diff --git a/android/app/build.gradle b/android/app/build.gradle index 59dc25bc..cac80b26 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -138,7 +138,7 @@ android { versionName userVer versionCode googleVer multiDexEnabled true - missingDimensionStrategy 'react-native-camera', 'general' + missingDimensionStrategy 'react-native-camera', 'general' ndk { abiFilters "armeabi-v7a", "x86" } @@ -201,10 +201,11 @@ dependencies { implementation "com.facebook.react:react-native:+" // From node_modules implementation "com.google.android.gms:play-services-base:16.0.1" implementation "com.google.firebase:firebase-core:16.0.8" - implementation "com.google.firebase:firebase-config:16.4.0" - implementation "com.google.firebase:firebase-auth:16.1.0" - implementation "com.google.firebase:firebase-messaging:17.4.0" - implementation "com.google.firebase:firebase-perf:16.2.4" + implementation "com.google.firebase:firebase-config:16.5.0" + implementation "com.google.firebase:firebase-auth:16.2.1" + implementation "com.google.firebase:firebase-messaging:17.6.0" + implementation "com.google.firebase:firebase-perf:16.2.5" + implementation "com.google.firebase:firebase-database:16.1.0" implementation 'me.leolin:ShortcutBadger:1.1.21@aar' implementation('com.crashlytics.sdk.android:crashlytics:2.9.9@aar') { transitive = true diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index f1341317..508ac3ee 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -5,6 +5,8 @@ + + + + + + + + + @@ -21,6 +30,7 @@ getPackages() { return Arrays.asList( new MainReactPackage(), - new CustomTabsPackage(), - new ReactNativeRestartPackage(), - new CameraRollPackage(), - new RNCViewPagerPackage(), - new ReactSliderPackage(), - new AsyncStoragePackage(), - new RNFirebasePackage(), + new CustomTabsPackage(), + new ReactNativeRestartPackage(), + new CameraRollPackage(), + new RNCViewPagerPackage(), + new ReactSliderPackage(), + new AsyncStoragePackage(), + new RNFirebasePackage(), new LottiePackage(), new RNGestureHandlerPackage(), new LinearGradientPackage(), @@ -62,6 +64,8 @@ protected List getPackages() { new RNFirebaseCrashlyticsPackage(), new RNFirebasePerformancePackage(), new RNFetchBlobPackage(), + new RNFirebaseDatabasePackage(), + new RNFirebaseNotificationsPackage(), new ExtraDimensionsPackage() ); } diff --git a/android/app/src/main/res/drawable/ic_icon.xml b/android/app/src/main/res/drawable/ic_icon.xml new file mode 100644 index 00000000..b2362cab --- /dev/null +++ b/android/app/src/main/res/drawable/ic_icon.xml @@ -0,0 +1,4 @@ + + + diff --git a/android/app/src/main/res/drawable/ic_notification.xml b/android/app/src/main/res/drawable/ic_notification.xml new file mode 100644 index 00000000..53bb83bc --- /dev/null +++ b/android/app/src/main/res/drawable/ic_notification.xml @@ -0,0 +1,5 @@ + + + diff --git a/index.js b/index.js index 61a752da..09ca3ccd 100644 --- a/index.js +++ b/index.js @@ -33,6 +33,19 @@ import CleanReducers from './src/components/screens/CleanReducers'; import CalendarPermission from './src/components/screens/CalendarPermission'; import { blue, dark_blue, white } from './src/styles.js'; import { getStrings } from './src/services/helper'; +import firebase from 'react-native-firebase'; +import bgMessaging from './src/background/bgMessaging'; +import bgActions from './src/background/bgActions'; +import SharingManagement from './src/components/screens/SharingManagement'; + +let config = { + databaseURL: 'https://kalend.firebaseio.com/', + projectId: 'AIzaSyAsHLSwnApIrFap-5kuCjB2sCsfaAi81f4', +}; + +if (!firebase.apps.length) { + firebase.initializeApp(config); +} const theme = { ...DefaultTheme, @@ -224,7 +237,8 @@ const DashboardOptionsNavigator = createStackNavigator( UnavailableHours: { screen: UnavailableHours, navigationOptions: DashboardOptionsNavigatorOptions }, UnavailableFixed: { screen: FixedEvent, navigationOptions: DashboardOptionsNavigatorOptions }, - CalendarPermission: { screen: CalendarPermission, navigationOptions: DashboardOptionsNavigatorOptions } + CalendarPermission: { screen: CalendarPermission, navigationOptions: DashboardOptionsNavigatorOptions }, + SharingManagement: { screen: SharingManagement, navigationOptions: DashboardOptionsNavigatorOptions} }, { initialRouteName: 'DashboardNavigator', @@ -278,4 +292,6 @@ export default function Main() { ); } -AppRegistry.registerComponent(appName, () => Main); \ No newline at end of file +AppRegistry.registerComponent(appName, () => Main); +AppRegistry.registerHeadlessTask('RNFirebaseBackgroundMessage', () => bgMessaging); +AppRegistry.registerHeadlessTask('RNFirebaseBackgroundNotificationAction', () => bgActions); \ No newline at end of file diff --git a/ios/Kalend.xcodeproj/project.pbxproj b/ios/Kalend.xcodeproj/project.pbxproj index c8260816..e27ea885 100644 --- a/ios/Kalend.xcodeproj/project.pbxproj +++ b/ios/Kalend.xcodeproj/project.pbxproj @@ -1658,4 +1658,4 @@ /* End XCConfigurationList section */ }; rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; -} +} \ No newline at end of file diff --git a/ios/Podfile b/ios/Podfile index 232c7435..53818a70 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -29,9 +29,11 @@ target 'Kalend' do pod 'react-native-camera', path: '../node_modules/react-native-camera' pod 'Firebase/Core', '~> 5.15.0' pod 'Firebase/RemoteConfig', '~> 5.15.0' + pod 'Firebase/Messaging', '~> 5.15.0' + pod 'Firebase/Performance', '~> 5.15.0' + pod 'Firebase/Database', '~> 5.15.0' pod 'Fabric', '~> 1.7.13' pod 'Crashlytics', '~> 3.10.7' - pod 'Firebase/Performance', '~> 5.15.0' pod 'lottie-ios', :path => '../node_modules/lottie-ios' pod 'react-native-slider', :path => '../node_modules/@react-native-community/slider' pod 'rn-fetch-blob', :path => '../node_modules/rn-fetch-blob' diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 6eded97b..14078ecf 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -11,6 +11,12 @@ PODS: - FirebaseAnalytics (= 5.4.0) - Firebase/CoreOnly (5.15.0): - FirebaseCore (= 5.1.10) + - Firebase/Database (5.15.0): + - Firebase/CoreOnly + - FirebaseDatabase (= 5.0.4) + - Firebase/Messaging (5.15.0): + - Firebase/CoreOnly + - FirebaseMessaging (= 3.2.2) - Firebase/Performance (5.15.0): - Firebase/Core - FirebasePerformance (= 2.2.2) @@ -29,12 +35,25 @@ PODS: - GoogleUtilities/Network (~> 5.2) - "GoogleUtilities/NSData+zlib (~> 5.2)" - nanopb (~> 0.3) + - FirebaseAnalyticsInterop (1.2.0) + - FirebaseAuthInterop (1.0.0) - FirebaseCore (5.1.10): - GoogleUtilities/Logger (~> 5.2) + - FirebaseDatabase (5.0.4): + - FirebaseAuthInterop (~> 1.0) + - FirebaseCore (~> 5.1) + - leveldb-library (~> 1.18) - FirebaseInstanceID (3.3.0): - FirebaseCore (~> 5.1) - GoogleUtilities/Environment (~> 5.3) - GoogleUtilities/UserDefaults (~> 5.3) + - FirebaseMessaging (3.2.2): + - FirebaseAnalyticsInterop (~> 1.1) + - FirebaseCore (~> 5.1) + - FirebaseInstanceID (~> 3.0) + - GoogleUtilities/Environment (~> 5.2) + - GoogleUtilities/Reachability (~> 5.2) + - Protobuf (~> 3.1) - FirebasePerformance (2.2.2): - FirebaseAnalytics (~> 5.4) - FirebaseInstanceID (~> 3.3) @@ -100,6 +119,7 @@ PODS: - GoogleUtilities/UserDefaults (5.5.0): - GoogleUtilities/Logger - GTMSessionFetcher/Core (1.2.1) + - leveldb-library (1.20) - lottie-ios (2.5.3) - lottie-react-native (2.6.0): - lottie-ios @@ -185,6 +205,8 @@ DEPENDENCIES: - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - Fabric (~> 1.7.13) - Firebase/Core (~> 5.15.0) + - Firebase/Database (~> 5.15.0) + - Firebase/Messaging (~> 5.15.0) - Firebase/Performance (~> 5.15.0) - Firebase/RemoteConfig (~> 5.15.0) - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`) @@ -218,8 +240,12 @@ SPEC REPOS: - Firebase - FirebaseABTesting - FirebaseAnalytics + - FirebaseAnalyticsInterop + - FirebaseAuthInterop - FirebaseCore + - FirebaseDatabase - FirebaseInstanceID + - FirebaseMessaging - FirebasePerformance - FirebaseRemoteConfig - GoogleAppMeasurement @@ -227,6 +253,7 @@ SPEC REPOS: - GoogleToolboxForMac - GoogleUtilities - GTMSessionFetcher + - leveldb-library - nanopb - Protobuf @@ -271,8 +298,12 @@ SPEC CHECKSUMS: Firebase: 8bb9268bff82374f2cbaaabb143e725743c316ae FirebaseABTesting: 1f50b8d50f5e3469eea54e7463a7b7fe221d1f5e FirebaseAnalytics: c06f9d70577d79074214700a71fd5d39de5550fb + FirebaseAnalyticsInterop: efbe45c8385ec626e29f9525e5ebd38520dfb6c1 + FirebaseAuthInterop: 0ffa57668be100582bb7643d4fcb7615496c41fc FirebaseCore: 35747502d9e8c6ee217385ad04446c7c2aaf9c5c + FirebaseDatabase: 0621689f77528d62b47e1c06ca737c4c19275d1a FirebaseInstanceID: e2fa4cb35ef5558c200f7f0ad8a53e212215f93e + FirebaseMessaging: b412996f6a09337d232bb3a6676ce4d1f353d024 FirebasePerformance: 6f77b930f982a54ad487d3de5523ce641db9dcc9 FirebaseRemoteConfig: 7e11c65f0769c09bff6947997c209515058c5318 Folly: de497beb10f102453a1afa9edbf8cf8a251890de @@ -282,6 +313,7 @@ SPEC CHECKSUMS: GoogleToolboxForMac: ff31605b7d66400dcec09bed5861689aebadda4d GoogleUtilities: 6481e6318c5fcabaaa8513ef8120f329055d7c10 GTMSessionFetcher: 32aeca0aa144acea523e1c8e053089dec2cb98ca + leveldb-library: 08cba283675b7ed2d99629a4bc5fd052cd2bb6a5 lottie-ios: a50d5c0160425cd4b01b852bb9578963e6d92d31 lottie-react-native: 05b6e2dd502d7a91ff128036c4f0984363e5eb4a nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 @@ -296,6 +328,6 @@ SPEC CHECKSUMS: RNVectorIcons: cb42a5653c046f12ca16c9480c571b52620559e8 yoga: 596e61c9b57751d08a22b07aba310dbd3e65ab75 -PODFILE CHECKSUM: 1bc1c28808f6ea34810ecf744d14fcab22288c99 +PODFILE CHECKSUM: 891466dbe9751910bb3eb1a5d6f7824de1c246e0 COCOAPODS: 1.6.1 diff --git a/ios/Pods/FirebaseAnalyticsInterop/Interop/Analytics/Public/FIRAnalyticsInterop.h b/ios/Pods/FirebaseAnalyticsInterop/Interop/Analytics/Public/FIRAnalyticsInterop.h new file mode 100644 index 00000000..a5143c5e --- /dev/null +++ b/ios/Pods/FirebaseAnalyticsInterop/Interop/Analytics/Public/FIRAnalyticsInterop.h @@ -0,0 +1,60 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class FIRAConditionalUserProperty; +@protocol FIRAnalyticsInteropListener; + +NS_ASSUME_NONNULL_BEGIN + +/// Connector for bridging communication between Firebase SDKs and FirebaseAnalytics API. +@protocol FIRAnalyticsInterop + +/// Sets user property when trigger event is logged. This API is only available in the SDK. +- (void)setConditionalUserProperty:(FIRAConditionalUserProperty *)conditionalUserProperty; + +/// Clears user property if set. +- (void)clearConditionalUserProperty:(NSString *)userPropertyName + clearEventName:(NSString *)clearEventName + clearEventParameters:(NSDictionary *)clearEventParameters; + +/// Returns currently set user properties. +- (NSArray *)conditionalUserProperties:(NSString *)origin + propertyNamePrefix: + (NSString *)propertyNamePrefix; + +/// Returns the maximum number of user properties. +- (NSInteger)maxUserProperties:(NSString *)origin; + +/// Logs events. +- (void)logEventWithOrigin:(NSString *)origin + name:(NSString *)name + parameters:(nullable NSDictionary *)parameters; + +/// Sets user property. +- (void)setUserPropertyWithOrigin:(NSString *)origin name:(NSString *)name value:(id)value; + +/// Registers an Analytics listener for the given origin. +- (void)registerAnalyticsListener:(id)listener + withOrigin:(NSString *)origin; + +/// Unregisters an Analytics listener for the given origin. +- (void)unregisterAnalyticsListenerWithOrigin:(NSString *)origin; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Pods/FirebaseAnalyticsInterop/Interop/Analytics/Public/FIRAnalyticsInteropListener.h b/ios/Pods/FirebaseAnalyticsInterop/Interop/Analytics/Public/FIRAnalyticsInteropListener.h new file mode 100644 index 00000000..45cde550 --- /dev/null +++ b/ios/Pods/FirebaseAnalyticsInterop/Interop/Analytics/Public/FIRAnalyticsInteropListener.h @@ -0,0 +1,24 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +/// Handles events and messages from Analytics. +@protocol FIRAnalyticsInteropListener + +/// Triggers when an Analytics event happens for the registered origin with +/// `FIRAnalyticsInterop`s `registerAnalyticsListener:withOrigin:`. +- (void)messageTriggered:(NSString *)name parameters:(NSDictionary *)parameters; + +@end \ No newline at end of file diff --git a/ios/Pods/FirebaseAnalyticsInterop/Interop/Analytics/Public/FIRInteropEventNames.h b/ios/Pods/FirebaseAnalyticsInterop/Interop/Analytics/Public/FIRInteropEventNames.h new file mode 100644 index 00000000..efc54ab2 --- /dev/null +++ b/ios/Pods/FirebaseAnalyticsInterop/Interop/Analytics/Public/FIRInteropEventNames.h @@ -0,0 +1,28 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/// @file FIRInteropEventNames.h + +#import + +/// Notification open event name. +static NSString *const kFIRIEventNotificationOpen = @"_no"; + +/// Notification foreground event name. +static NSString *const kFIRIEventNotificationForeground = @"_nf"; + +/// Campaign event name. +static NSString *const kFIRIEventFirebaseCampaign = @"_cmp"; diff --git a/ios/Pods/FirebaseAnalyticsInterop/Interop/Analytics/Public/FIRInteropParameterNames.h b/ios/Pods/FirebaseAnalyticsInterop/Interop/Analytics/Public/FIRInteropParameterNames.h new file mode 100644 index 00000000..ae440bec --- /dev/null +++ b/ios/Pods/FirebaseAnalyticsInterop/Interop/Analytics/Public/FIRInteropParameterNames.h @@ -0,0 +1,73 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +/// @file FIRInteropParameterNames.h +/// +/// Predefined event parameter names used by Firebase. This file is a subset of the +/// FirebaseAnalytics FIRParameterNames.h public header. +/// +/// The origin of your traffic, such as an Ad network (for example, google) or partner (urban +/// airship). Identify the advertiser, site, publication, etc. that is sending traffic to your +/// property. Highly recommended (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterSource : @"InMobi",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRIParameterSource NS_SWIFT_NAME(AnalyticsParameterSource) = @"source"; + +/// The advertising or marketing medium, for example: cpc, banner, email, push. Highly recommended +/// (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterMedium : @"email",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRIParameterMedium NS_SWIFT_NAME(AnalyticsParameterMedium) = @"medium"; + +/// The individual campaign name, slogan, promo code, etc. Some networks have pre-defined macro to +/// capture campaign information, otherwise can be populated by developer. Highly Recommended +/// (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterCampaign : @"winter_promotion",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRIParameterCampaign NS_SWIFT_NAME(AnalyticsParameterCampaign) = + @"campaign"; + +/// Message identifier. +static NSString *const kFIRIParameterMessageIdentifier = @"_nmid"; + +/// Message name. +static NSString *const kFIRIParameterMessageName = @"_nmn"; + +/// Message send time. +static NSString *const kFIRIParameterMessageTime = @"_nmt"; + +/// Message device time. +static NSString *const kFIRIParameterMessageDeviceTime = @"_ndt"; + +/// Topic message. +static NSString *const kFIRIParameterTopic = @"_nt"; + +/// Stores the message_id of the last notification opened by the app. +static NSString *const kFIRIUserPropertyLastNotification = @"_ln"; diff --git a/ios/Pods/FirebaseAnalyticsInterop/LICENSE b/ios/Pods/FirebaseAnalyticsInterop/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/ios/Pods/FirebaseAnalyticsInterop/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/ios/Pods/FirebaseAnalyticsInterop/README.md b/ios/Pods/FirebaseAnalyticsInterop/README.md new file mode 100644 index 00000000..bfaceebc --- /dev/null +++ b/ios/Pods/FirebaseAnalyticsInterop/README.md @@ -0,0 +1,193 @@ +# Firebase iOS Open Source Development [![Build Status](https://travis-ci.org/firebase/firebase-ios-sdk.svg?branch=master)](https://travis-ci.org/firebase/firebase-ios-sdk) + +This repository contains a subset of the Firebase iOS SDK source. It currently +includes FirebaseCore, FirebaseAuth, FirebaseDatabase, FirebaseFirestore, +FirebaseFunctions, FirebaseInAppMessagingDisplay, FirebaseMessaging and +FirebaseStorage. + +The repository also includes GoogleUtilities source. The +[GoogleUtilities](GoogleUtilities/README.md) pod is +a set of utilities used by Firebase and other Google products. + +Firebase is an app development platform with tools to help you build, grow and +monetize your app. More information about Firebase can be found at +[https://firebase.google.com](https://firebase.google.com). + +## Installation + +See the three subsections for details about three different installation methods. +1. [Standard pod install](README.md#standard-pod-install) +1. [Installing from the GitHub repo](README.md#installing-from-github) +1. [Experimental Carthage](README.md#carthage-ios-only) + +### Standard pod install + +Go to +[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup). + +### Installing from GitHub + +For releases starting with 5.0.0, the source for each release is also deployed +to CocoaPods master and available via standard +[CocoaPods Podfile syntax](https://guides.cocoapods.org/syntax/podfile.html#pod). + +These instructions can be used to access the Firebase repo at other branches, +tags, or commits. + +#### Background + +See +[the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod) +for instructions and options about overriding pod source locations. + +#### Accessing Firebase Source Snapshots + +All of the official releases are tagged in this repo and available via CocoaPods. To access a local +source snapshot or unreleased branch, use Podfile directives like the following: + +To access FirebaseFirestore via a branch: +``` +pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' +pod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' +``` + +To access FirebaseMessaging via a checked out version of the firebase-ios-sdk repo do: + +``` +pod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk' +pod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk' +``` + +### Carthage (iOS only) + +Instructions for the experimental Carthage distribution are at +[Carthage](Carthage.md). + +### Rome + +Instructions for installing binary frameworks via +[Rome](https://github.com/CocoaPods/Rome) are at [Rome](Rome.md). + +## Development + +Follow the subsequent instructions to develop, debug, unit test, run integration +tests, and try out reference samples: + +``` +$ git clone git@github.com:firebase/firebase-ios-sdk.git +$ cd firebase-ios-sdk/Example +$ pod update +$ open Firebase.xcworkspace +``` + +Firestore and Functions have self contained Xcode projects. See +[Firestore/README.md](Firestore/README.md) and +[Functions/README.md](Functions/README.md). + +### Code Formatting + +Travis will verify that any code changes are done in a style compliant way. Install +`clang-format` and `swiftformat`. +This command will get the right `clang-format` version: + +`brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/773cb75d360b58f32048f5964038d09825a507c8/Formula/clang-format.rb` + +### Running Unit Tests + +Select a scheme and press Command-u to build a component and run its unit tests. + +### Running Sample Apps +In order to run the sample apps and integration tests, you'll need valid +`GoogleService-Info.plist` files for those samples. The Firebase Xcode project contains dummy plist +files without real values, but can be replaced with real plist files. To get your own +`GoogleService-Info.plist` files: + +1. Go to the [Firebase Console](https://console.firebase.google.com/) +2. Create a new Firebase project, if you don't already have one +3. For each sample app you want to test, create a new Firebase app with the sample app's bundle +identifier (e.g. `com.google.Database-Example`) +4. Download the resulting `GoogleService-Info.plist` and replace the appropriate dummy plist file +(e.g. in [Example/Database/App/](Example/Database/App/)); + +Some sample apps like Firebase Messaging ([Example/Messaging/App](Example/Messaging/App)) require +special Apple capabilities, and you will have to change the sample app to use a unique bundle +identifier that you can control in your own Apple Developer account. + +## Specific Component Instructions +See the sections below for any special instructions for those components. + +### Firebase Auth + +If you're doing specific Firebase Auth development, see +[the Auth Sample README](Example/Auth/README.md) for instructions about +building and running the FirebaseAuth pod along with various samples and tests. + +### Firebase Database + +To run the Database Integration tests, make your database authentication rules +[public](https://firebase.google.com/docs/database/security/quickstart). + +### Firebase Storage + +To run the Storage Integration tests, follow the instructions in +[FIRStorageIntegrationTests.m](Example/Storage/Tests/Integration/FIRStorageIntegrationTests.m). + +#### Push Notifications + +Push notifications can only be delivered to specially provisioned App IDs in the developer portal. +In order to actually test receiving push notifications, you will need to: + +1. Change the bundle identifier of the sample app to something you own in your Apple Developer +account, and enable that App ID for push notifications. +2. You'll also need to +[upload your APNs Provider Authentication Key or certificate to the Firebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs) +at **Project Settings > Cloud Messaging > [Your Firebase App]**. +3. Ensure your iOS device is added to your Apple Developer portal as a test device. + +#### iOS Simulator + +The iOS Simulator cannot register for remote notifications, and will not receive push notifications. +In order to receive push notifications, you'll have to follow the steps above and run the app on a +physical device. + +## Community Supported Efforts + +We've seen an amazing amount of interest and contributions to improve the Firebase SDKs, and we are +very grateful! We'd like to empower as many developers as we can to be able to use Firebase and +participate in the Firebase community. + +### macOS and tvOS +FirebaseAuth, FirebaseCore, FirebaseDatabase and FirebaseStorage now compile, run unit tests, and +work on macOS and tvOS, thanks to contributions from the community. There are a few tweaks needed, +like ensuring iOS-only, macOS-only, or tvOS-only code is correctly guarded with checks for +`TARGET_OS_IOS`, `TARGET_OS_OSX` and `TARGET_OS_TV`. + +For tvOS, checkout the [Sample](Example/tvOSSample). + +Keep in mind that macOS and tvOS are not officially supported by Firebase, and this repository is +actively developed primarily for iOS. While we can catch basic unit test issues with Travis, there +may be some changes where the SDK no longer works as expected on macOS or tvOS. If you encounter +this, please [file an issue](https://github.com/firebase/firebase-ios-sdk/issues). + +For installation instructions, see [above](README.md#accessing-firebase-source-snapshots). + +Note that the Firebase pod is not available for macOS and tvOS. Install a selection of the +`FirebaseAuth`, `FirebaseCore`, `FirebaseDatabase` and `FirebaseStorage` CocoaPods. + +## Roadmap + +See [Roadmap](ROADMAP.md) for more about the Firebase iOS SDK Open Source +plans and directions. + +## Contributing + +See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase +iOS SDK. + +## License + +The contents of this repository is licensed under the +[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). + +Your use of Firebase is governed by the +[Terms of Service for Firebase Services](https://firebase.google.com/terms/). diff --git a/ios/Pods/FirebaseAuthInterop/Interop/Auth/Public/FIRAuthInterop.h b/ios/Pods/FirebaseAuthInterop/Interop/Auth/Public/FIRAuthInterop.h new file mode 100644 index 00000000..5c365a3c --- /dev/null +++ b/ios/Pods/FirebaseAuthInterop/Interop/Auth/Public/FIRAuthInterop.h @@ -0,0 +1,42 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRAuthInterop_h +#define FIRAuthInterop_h + +NS_ASSUME_NONNULL_BEGIN + +/** @typedef FIRTokenCallback + @brief The type of block which gets called when a token is ready. + */ +typedef void (^FIRTokenCallback)(NSString *_Nullable token, NSError *_Nullable error) + NS_SWIFT_NAME(TokenCallback); + +/// Common methods for Auth interoperability. +NS_SWIFT_NAME(AuthInterop) +@protocol FIRAuthInterop + +/// Retrieves the Firebase authentication token, possibly refreshing it if it has expired. +- (void)getTokenForcingRefresh:(BOOL)forceRefresh withCallback:(FIRTokenCallback)callback; + +/// Get the current Auth user's UID. Returns nil if there is no user signed in. +- (nullable NSString *)getUserID; + +@end + +NS_ASSUME_NONNULL_END + +#endif /* FIRAuthInterop_h */ diff --git a/ios/Pods/FirebaseAuthInterop/LICENSE b/ios/Pods/FirebaseAuthInterop/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/ios/Pods/FirebaseAuthInterop/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/ios/Pods/FirebaseAuthInterop/README.md b/ios/Pods/FirebaseAuthInterop/README.md new file mode 100644 index 00000000..4414b3e3 --- /dev/null +++ b/ios/Pods/FirebaseAuthInterop/README.md @@ -0,0 +1,179 @@ +# Firebase iOS Open Source Development [![Build Status](https://travis-ci.org/firebase/firebase-ios-sdk.svg?branch=master)](https://travis-ci.org/firebase/firebase-ios-sdk) + +This repository contains a subset of the Firebase iOS SDK source. It currently +includes FirebaseCore, FirebaseAuth, FirebaseDatabase, FirebaseFirestore, +FirebaseFunctions, FirebaseMessaging and FirebaseStorage. + +The repository also includes GoogleUtilities source. The +[GoogleUtilities](GoogleUtilities/README.md) pod is +a set of utilities used by Firebase and other Google products. + +Firebase is an app development platform with tools to help you build, grow and +monetize your app. More information about Firebase can be found at +[https://firebase.google.com](https://firebase.google.com). + +## Installation + +See the three subsections for details about three different installation methods. +1. [Standard pod install](README.md#standard-pod-install) +1. [Installing from the GitHub repo](README.md#installing-from-github) +1. [Experimental Carthage](README.md#carthage-ios-only) + +### Standard pod install + +Go to +[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup). + +### Installing from GitHub + +For releases starting with 5.0.0, the source for each release is also deployed +to CocoaPods master and available via standard +[CocoaPods Podfile syntax](https://guides.cocoapods.org/syntax/podfile.html#pod). + +These instructions can be used to access the Firebase repo at other branches, +tags, or commits. + +#### Background + +See +[the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod) +for instructions and options about overriding pod source locations. + +#### Accessing Firebase Source Snapshots + +All of the official releases are tagged in this repo and available via CocoaPods. To access a local +source snapshot or unreleased branch, use Podfile directives like the following: + +To access FirebaseFirestore via a branch: +``` +pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' +pod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' +``` + +To access FirebaseMessaging via a checked out version of the firebase-ios-sdk repo do: + +``` +pod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk' +pod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk' +``` + +### Carthage (iOS only) + +An experimental Carthage distribution is now available. See +[Carthage](Carthage.md). + +## Development + +Follow the subsequent instructions to develop, debug, unit test, run integration +tests, and try out reference samples: + +``` +$ git clone git@github.com:firebase/firebase-ios-sdk.git +$ cd firebase-ios-sdk/Example +$ pod update +$ open Firebase.xcworkspace +``` + +Firestore and Functions have self contained Xcode projects. See +[Firestore/README.md](Firestore/README.md) and +[Functions/README.md](Functions/README.md). + +### Running Unit Tests + +Select a scheme and press Command-u to build a component and run its unit tests. + +### Running Sample Apps +In order to run the sample apps and integration tests, you'll need valid +`GoogleService-Info.plist` files for those samples. The Firebase Xcode project contains dummy plist +files without real values, but can be replaced with real plist files. To get your own +`GoogleService-Info.plist` files: + +1. Go to the [Firebase Console](https://console.firebase.google.com/) +2. Create a new Firebase project, if you don't already have one +3. For each sample app you want to test, create a new Firebase app with the sample app's bundle +identifier (e.g. `com.google.Database-Example`) +4. Download the resulting `GoogleService-Info.plist` and replace the appropriate dummy plist file +(e.g. in [Example/Database/App/](Example/Database/App/)); + +Some sample apps like Firebase Messaging ([Example/Messaging/App](Example/Messaging/App)) require +special Apple capabilities, and you will have to change the sample app to use a unique bundle +identifier that you can control in your own Apple Developer account. + +## Specific Component Instructions +See the sections below for any special instructions for those components. + +### Firebase Auth + +If you're doing specific Firebase Auth development, see +[AuthSamples/README.md](AuthSamples/README.md) for instructions about +building and running the FirebaseAuth pod along with various samples and tests. + +### Firebase Database + +To run the Database Integration tests, make your database authentication rules +[public](https://firebase.google.com/docs/database/security/quickstart). + +### Firebase Storage + +To run the Storage Integration tests, follow the instructions in +[FIRStorageIntegrationTests.m](Example/Storage/Tests/Integration/FIRStorageIntegrationTests.m). + +#### Push Notifications + +Push notifications can only be delivered to specially provisioned App IDs in the developer portal. +In order to actually test receiving push notifications, you will need to: + +1. Change the bundle identifier of the sample app to something you own in your Apple Developer +account, and enable that App ID for push notifications. +2. You'll also need to +[upload your APNs Provider Authentication Key or certificate to the Firebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs) +at **Project Settings > Cloud Messaging > [Your Firebase App]**. +3. Ensure your iOS device is added to your Apple Developer portal as a test device. + +#### iOS Simulator + +The iOS Simulator cannot register for remote notifications, and will not receive push notifications. +In order to receive push notifications, you'll have to follow the steps above and run the app on a +physical device. + +## Community Supported Efforts + +We've seen an amazing amount of interest and contributions to improve the Firebase SDKs, and we are +very grateful! We'd like to empower as many developers as we can to be able to use Firebase and +participate in the Firebase community. + +### macOS and tvOS +FirebaseAuth, FirebaseCore, FirebaseDatabase and FirebaseStorage now compile, run unit tests, and +work on macOS and tvOS, thanks to contributions from the community. There are a few tweaks needed, +like ensuring iOS-only, macOS-only, or tvOS-only code is correctly guarded with checks for +`TARGET_OS_IOS`, `TARGET_OS_OSX` and `TARGET_OS_TV`. + +For tvOS, checkout the [Sample](Example/tvOSSample). + +Keep in mind that macOS and tvOS are not officially supported by Firebase, and this repository is +actively developed primarily for iOS. While we can catch basic unit test issues with Travis, there +may be some changes where the SDK no longer works as expected on macOS or tvOS. If you encounter +this, please [file an issue](https://github.com/firebase/firebase-ios-sdk/issues). + +For installation instructions, see [above](README.md#accessing-firebase-source-snapshots). + +Note that the Firebase pod is not available for macOS and tvOS. Install a selection of the +`FirebaseAuth`, `FirebaseCore`, `FirebaseDatabase` and `FirebaseStorage` CocoaPods. + +## Roadmap + +See [Roadmap](ROADMAP.md) for more about the Firebase iOS SDK Open Source +plans and directions. + +## Contributing + +See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase +iOS SDK. + +## License + +The contents of this repository is licensed under the +[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). + +Your use of Firebase is governed by the +[Terms of Service for Firebase Services](https://firebase.google.com/terms/). diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRDataSnapshot.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRDataSnapshot.m new file mode 100644 index 00000000..b7744939 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRDataSnapshot.m @@ -0,0 +1,101 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRDataSnapshot.h" +#import "FIRDataSnapshot_Private.h" +#import "FChildrenNode.h" +#import "FValidation.h" +#import "FTransformedEnumerator.h" +#import "FIRDatabaseReference.h" + +@interface FIRDataSnapshot () +@property (nonatomic, strong) FIRDatabaseReference *ref; +@end + +@implementation FIRDataSnapshot + +- (id)initWithRef:(FIRDatabaseReference *)ref indexedNode:(FIndexedNode *)node +{ + self = [super init]; + if (self != nil) { + self->_ref = ref; + self->_node = node; + } + return self; +} + +- (id) value { + return [self.node.node val]; +} + +- (id) valueInExportFormat { + return [self.node.node valForExport:YES]; +} + +- (FIRDataSnapshot *)childSnapshotForPath:(NSString *)childPathString { + [FValidation validateFrom:@"child:" validPathString:childPathString]; + FPath* childPath = [[FPath alloc] initWith:childPathString]; + FIRDatabaseReference * childRef = [self.ref child:childPathString]; + + id childNode = [self.node.node getChild:childPath]; + return [[FIRDataSnapshot alloc] initWithRef:childRef indexedNode:[FIndexedNode indexedNodeWithNode:childNode]]; +} + +- (BOOL) hasChild:(NSString *)childPathString { + [FValidation validateFrom:@"hasChild:" validPathString:childPathString]; + FPath* childPath = [[FPath alloc] initWith:childPathString]; + return ! [[self.node.node getChild:childPath] isEmpty]; +} + +- (id) priority { + id priority = [self.node.node getPriority]; + return priority.val; +} + + +- (BOOL) hasChildren { + if([self.node.node isLeafNode]) { + return false; + } + else { + return ![self.node.node isEmpty]; + } +} + +- (BOOL) exists { + return ![self.node.node isEmpty]; +} + +- (NSString *) key { + return [self.ref key]; +} + +- (NSUInteger) childrenCount { + return [self.node.node numChildren]; +} + +- (NSEnumerator *) children { + return [[FTransformedEnumerator alloc] initWithEnumerator:self.node.childEnumerator andTransform:^id(FNamedNode *node) { + FIRDatabaseReference *childRef = [self.ref child:node.name]; + return [[FIRDataSnapshot alloc] initWithRef:childRef indexedNode:[FIndexedNode indexedNodeWithNode:node.node]]; + }]; +} + +- (NSString *) description { + return [NSString stringWithFormat:@"Snap (%@) %@", self.key, self.node.node]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRDatabase.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRDatabase.m new file mode 100644 index 00000000..1a2ba888 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRDatabase.m @@ -0,0 +1,211 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import +#import +#import +#import +#import +#import +#import + +#import "FIRDatabase.h" +#import "FIRDatabaseComponent.h" +#import "FIRDatabaseConfig_Private.h" +#import "FIRDatabaseQuery_Private.h" +#import "FIRDatabaseReference_Private.h" +#import "FIRDatabase_Private.h" +#import "FRepoInfo.h" +#import "FValidation.h" + +@implementation FIRDatabase + +// The STR and STR_EXPAND macro allow a numeric version passed to he compiler driver +// with a -D to be treated as a string instead of an invalid floating point value. +#define STR(x) STR_EXPAND(x) +#define STR_EXPAND(x) #x +static const char *FIREBASE_SEMVER = (const char *)STR(FIRDatabase_VERSION); + ++ (FIRDatabase *)database { + if (![FIRApp isDefaultAppConfigured]) { + [NSException raise:@"FIRAppNotConfigured" + format:@"Failed to get default Firebase Database instance. Must call `[FIRApp " + @"configure]` (`FirebaseApp.configure()` in Swift) before using " + @"Firebase Database."]; + } + return [FIRDatabase databaseForApp:[FIRApp defaultApp]]; +} + ++ (FIRDatabase *)databaseWithURL:(NSString *)url { + FIRApp *app = [FIRApp defaultApp]; + if (app == nil) { + [NSException raise:@"FIRAppNotConfigured" + format:@"Failed to get default Firebase Database instance. " + @"Must call `[FIRApp configure]` (`FirebaseApp.configure()` in " + @"Swift) before using Firebase Database."]; + } + return [FIRDatabase databaseForApp:app URL:url]; +} + ++ (FIRDatabase *)databaseForApp:(FIRApp *)app { + if (app == nil) { + [NSException raise:@"InvalidFIRApp" format:@"nil FIRApp instance passed to databaseForApp."]; + } + return [FIRDatabase databaseForApp:app URL:app.options.databaseURL]; +} + ++ (FIRDatabase *)databaseForApp:(FIRApp *)app URL:(NSString *)url { + if (app == nil) { + [NSException raise:@"InvalidFIRApp" + format:@"nil FIRApp instance passed to databaseForApp."]; + } + if (url == nil) { + [NSException raise:@"MissingDatabaseURL" + format:@"Failed to get FirebaseDatabase instance: " + @"Specify DatabaseURL within FIRApp or from your databaseForApp:URL: call."]; + } + id provider = FIR_COMPONENT(FIRDatabaseProvider, app.container); + return [provider databaseForApp:app URL:url]; +} + ++ (NSString *) buildVersion { + // TODO: Restore git hash when build moves back to git + return [NSString stringWithFormat:@"%s_%s", FIREBASE_SEMVER, __DATE__]; +} + ++ (FIRDatabase *)createDatabaseForTests:(FRepoInfo *)repoInfo config:(FIRDatabaseConfig *)config { + FIRDatabase *db = [[FIRDatabase alloc] initWithApp:nil repoInfo:repoInfo config:config]; + [db ensureRepo]; + return db; +} + ++ (NSString *) sdkVersion { + return [NSString stringWithUTF8String:FIREBASE_SEMVER]; +} + ++ (void) setLoggingEnabled:(BOOL)enabled { + [FUtilities setLoggingEnabled:enabled]; + FFLog(@"I-RDB024001", @"BUILD Version: %@", [FIRDatabase buildVersion]); +} + + +- (id)initWithApp:(FIRApp *)app repoInfo:(FRepoInfo *)info config:(FIRDatabaseConfig *)config { + self = [super init]; + if (self != nil) { + self->_repoInfo = info; + self->_config = config; + self->_app = app; + } + return self; +} + +- (FIRDatabaseReference *)reference { + [self ensureRepo]; + + return [[FIRDatabaseReference alloc] initWithRepo:self.repo path:[FPath empty]]; +} + +- (FIRDatabaseReference *)referenceWithPath:(NSString *)path { + [self ensureRepo]; + + [FValidation validateFrom:@"referenceWithPath" validRootPathString:path]; + FPath *childPath = [[FPath alloc] initWith:path]; + return [[FIRDatabaseReference alloc] initWithRepo:self.repo path:childPath]; +} + +- (FIRDatabaseReference *)referenceFromURL:(NSString *)databaseUrl { + [self ensureRepo]; + + if (databaseUrl == nil) { + [NSException raise:@"InvalidDatabaseURL" format:@"Invalid nil url passed to referenceFromURL:"]; + } + FParsedUrl *parsedUrl = [FUtilities parseUrl:databaseUrl]; + [FValidation validateFrom:@"referenceFromURL:" validURL:parsedUrl]; + if (![parsedUrl.repoInfo.host isEqualToString:_repoInfo.host]) { + [NSException raise:@"InvalidDatabaseURL" format:@"Invalid URL (%@) passed to getReference(). URL was expected " + "to match configured Database URL: %@", databaseUrl, [self reference].URL]; + } + return [[FIRDatabaseReference alloc] initWithRepo:self.repo path:parsedUrl.path]; +} + + +- (void)purgeOutstandingWrites { + [self ensureRepo]; + + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + [self.repo purgeOutstandingWrites]; + }); +} + +- (void)goOnline { + [self ensureRepo]; + + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + [self.repo resume]; + }); +} + +- (void)goOffline { + [self ensureRepo]; + + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + [self.repo interrupt]; + }); +} + +- (void)setPersistenceEnabled:(BOOL)persistenceEnabled { + [self assertUnfrozen:@"setPersistenceEnabled"]; + self->_config.persistenceEnabled = persistenceEnabled; +} + +- (BOOL)persistenceEnabled { + return self->_config.persistenceEnabled; +} + +- (void)setPersistenceCacheSizeBytes:(NSUInteger)persistenceCacheSizeBytes { + [self assertUnfrozen:@"setPersistenceCacheSizeBytes"]; + self->_config.persistenceCacheSizeBytes = persistenceCacheSizeBytes; +} + +- (NSUInteger)persistenceCacheSizeBytes { + return self->_config.persistenceCacheSizeBytes; +} + +- (void)setCallbackQueue:(dispatch_queue_t)callbackQueue { + [self assertUnfrozen:@"setCallbackQueue"]; + self->_config.callbackQueue = callbackQueue; +} + +- (dispatch_queue_t)callbackQueue { + return self->_config.callbackQueue; +} + +- (void) assertUnfrozen:(NSString*)methodName { + if (self.repo != nil) { + [NSException raise:@"FIRDatabaseAlreadyInUse" format:@"Calls to %@ must be made before any other usage of " + "FIRDatabase instance.", methodName]; + } +} + +- (void) ensureRepo { + if (self.repo == nil) { + self.repo = [FRepoManager createRepo:self.repoInfo config:self.config database:self]; + } +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRDatabaseComponent.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRDatabaseComponent.h new file mode 100644 index 00000000..37840a1f --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRDatabaseComponent.h @@ -0,0 +1,44 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class FIRApp; +@class FIRDatabase; + +NS_ASSUME_NONNULL_BEGIN + +/// This protocol is used in the interop registration process to register an instance provider for +/// individual FIRApps. +@protocol FIRDatabaseProvider + +/// Gets a FirebaseDatabase instance for the specified URL, using the specified FirebaseApp. +- (FIRDatabase *)databaseForApp:(FIRApp *)app URL:(NSString *)url; + +@end + +/// A concrete implementation for FIRDatabaseProvider to create Database instances. +@interface FIRDatabaseComponent : NSObject + +/// The FIRApp that instances will be set up with. +@property(nonatomic, weak, readonly) FIRApp *app; + +/// Unavailable, use `databaseForApp:URL:` instead. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRDatabaseComponent.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRDatabaseComponent.m new file mode 100644 index 00000000..eee0b337 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRDatabaseComponent.m @@ -0,0 +1,156 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRDatabaseComponent.h" + +#import "FIRDatabase_Private.h" +#import "FIRDatabaseConfig_Private.h" +#import "FRepoManager.h" + +#import +#import +#import +#import +#import +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/** A NSMutableDictionary of FirebaseApp name and FRepoInfo to FirebaseDatabase instance. */ +typedef NSMutableDictionary FIRDatabaseDictionary; + +@interface FIRDatabaseComponent () +@property (nonatomic) FIRDatabaseDictionary *instances; +/// Internal intializer. +- (instancetype)initWithApp:(FIRApp *)app; +@end + +@implementation FIRDatabaseComponent + +#pragma mark - Initialization + +- (instancetype)initWithApp:(FIRApp *)app { + self = [super init]; + if (self) { + _app = app; + _instances = [NSMutableDictionary dictionary]; + } + return self; +} + +#pragma mark - Lifecycle + ++ (void)load { + [FIRComponentContainer registerAsComponentRegistrant:self]; +} + +#pragma mark - FIRComponentRegistrant + ++ (NSArray *)componentsToRegister { + FIRDependency *authDep = + [FIRDependency dependencyWithProtocol:@protocol(FIRAuthInterop) isRequired:NO]; + FIRComponentCreationBlock creationBlock = + ^id _Nullable(FIRComponentContainer *container, BOOL *isCacheable) { + *isCacheable = YES; + return [[FIRDatabaseComponent alloc] initWithApp:container.app]; + }; + FIRComponent *databaseProvider = + [FIRComponent componentWithProtocol:@protocol(FIRDatabaseProvider) + instantiationTiming:FIRInstantiationTimingLazy + dependencies:@[ authDep ] + creationBlock:creationBlock]; + return @[ databaseProvider ]; +} + +#pragma mark - Instance management. + +- (void)appWillBeDeleted:(FIRApp *)app { + NSString *appName = app.name; + if (appName == nil) { + return; + } + FIRDatabaseDictionary* instances = [self instances]; + @synchronized (instances) { + // Clean up the deleted instance in an effort to remove any resources still in use. + // Note: Any leftover instances of this exact database will be invalid. + for (FIRDatabase * database in [instances allValues]) { + [FRepoManager disposeRepos:database.config]; + } + [instances removeAllObjects]; + } +} + +#pragma mark - FIRDatabaseProvider Conformance + + +- (FIRDatabase *)databaseForApp:(FIRApp *)app URL:(NSString *)url { + if (app == nil) { + [NSException raise:@"InvalidFIRApp" + format:@"nil FIRApp instance passed to databaseForApp."]; + } + + if (url == nil) { + [NSException raise:@"MissingDatabaseURL" + format:@"Failed to get FirebaseDatabase instance: " + "Specify DatabaseURL within FIRApp or from your databaseForApp:URL: call."]; + } + + NSURL *databaseUrl = [NSURL URLWithString:url]; + + if (databaseUrl == nil) { + [NSException raise:@"InvalidDatabaseURL" format:@"The Database URL '%@' cannot be parsed. " + "Specify a valid DatabaseURL within FIRApp or from your databaseForApp:URL: call.", databaseUrl]; + } else if (![databaseUrl.path isEqualToString:@""] && ![databaseUrl.path isEqualToString:@"/"]) { + [NSException raise:@"InvalidDatabaseURL" format:@"Configured Database URL '%@' is invalid. It should point " + "to the root of a Firebase Database but it includes a path: %@",databaseUrl, databaseUrl.path]; + } + + FIRDatabaseDictionary *instances = [self instances]; + @synchronized (instances) { + FParsedUrl *parsedUrl = [FUtilities parseUrl:databaseUrl.absoluteString]; + NSString *urlIndex = + [NSString stringWithFormat:@"%@:%@", parsedUrl.repoInfo.host, [parsedUrl.path toString]]; + FIRDatabase *database = instances[urlIndex]; + if (!database) { + id authTokenProvider = + [FAuthTokenProvider authTokenProviderWithAuth: + FIR_COMPONENT(FIRAuthInterop, app.container)]; + + // If this is the default app, don't set the session persistence key so that we use our + // default ("default") instead of the FIRApp default ("[DEFAULT]") so that we + // preserve the default location used by the legacy Firebase SDK. + NSString *sessionIdentifier = @"default"; + if (![FIRApp isDefaultAppConfigured] || app != [FIRApp defaultApp]) { + sessionIdentifier = app.name; + } + + FIRDatabaseConfig *config = + [[FIRDatabaseConfig alloc] initWithSessionIdentifier:sessionIdentifier + authTokenProvider:authTokenProvider]; + database = [[FIRDatabase alloc] initWithApp:app + repoInfo:parsedUrl.repoInfo + config:config]; + instances[urlIndex] = database; + } + + return database; + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRDatabaseConfig.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRDatabaseConfig.h new file mode 100644 index 00000000..d41f3a81 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRDatabaseConfig.h @@ -0,0 +1,63 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@protocol FAuthTokenProvider; + +NS_ASSUME_NONNULL_BEGIN + +/** + * TODO: Merge FIRDatabaseConfig into FIRDatabase. + */ +@interface FIRDatabaseConfig : NSObject + +- (id)initWithSessionIdentifier:(NSString *)identifier authTokenProvider:(id)authTokenProvider; + +/** + * By default the Firebase Database client will keep data in memory while your application is running, but not + * when it is restarted. By setting this value to YES, the data will be persisted to on-device (disk) + * storage and will thus be available again when the app is restarted (even when there is no network + * connectivity at that time). Note that this property must be set before creating your first FIRDatabaseReference + * and only needs to be called once per application. + * + * If your app uses Firebase Authentication, the client will automatically persist the user's authentication + * token across restarts, even without persistence enabled. But if the auth token expired while offline and + * you've enabled persistence, the client will pause write operations until you successfully re-authenticate + * (or explicitly unauthenticate) to prevent your writes from being sent unauthenticated and failing due to + * security rules. + */ +@property (nonatomic) BOOL persistenceEnabled; + +/** + * By default the Firebase Database client will use up to 10MB of disk space to cache data. If the cache grows beyond this size, + * the client will start removing data that hasn't been recently used. If you find that your application caches too + * little or too much data, call this method to change the cache size. This property must be set before creating + * your first FIRDatabaseReference and only needs to be called once per application. + * + * Note that the specified cache size is only an approximation and the size on disk may temporarily exceed it + * at times. + */ +@property (nonatomic) NSUInteger persistenceCacheSizeBytes; + +/** + * Sets the dispatch queue on which all events are raised. The default queue is the main queue. + */ +@property (nonatomic, strong) dispatch_queue_t callbackQueue; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRDatabaseConfig.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRDatabaseConfig.m new file mode 100644 index 00000000..a49d4a0a --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRDatabaseConfig.m @@ -0,0 +1,84 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRDatabaseConfig.h" + +#import "FAuthTokenProvider.h" +#import "FIRDatabaseConfig_Private.h" +#import "FIRNoopAuthTokenProvider.h" + +@interface FIRDatabaseConfig (Private) + +@property (nonatomic, strong, readwrite) NSString *sessionIdentifier; + +@end + +@implementation FIRDatabaseConfig + +- (id)init { + [NSException raise:NSInvalidArgumentException format:@"Can't create config objects!"]; + return nil; +} + +- (id)initWithSessionIdentifier:(NSString *)identifier authTokenProvider:(id)authTokenProvider { + self = [super init]; + if (self != nil) { + self->_sessionIdentifier = identifier; + self->_callbackQueue = dispatch_get_main_queue(); + self->_persistenceCacheSizeBytes = 10*1024*1024; // Default cache size is 10MB + self->_authTokenProvider = authTokenProvider; + } + return self; +} + +- (void)assertUnfrozen { + if (self.isFrozen) { + [NSException raise:NSGenericException format:@"Can't modify config objects after they are in use for FIRDatabaseReferences."]; + } +} + +- (void)setAuthTokenProvider:(id)authTokenProvider { + [self assertUnfrozen]; + self->_authTokenProvider = authTokenProvider; +} + +- (void)setPersistenceEnabled:(BOOL)persistenceEnabled { + [self assertUnfrozen]; + self->_persistenceEnabled = persistenceEnabled; +} + +- (void)setPersistenceCacheSizeBytes:(NSUInteger)persistenceCacheSizeBytes { + [self assertUnfrozen]; + // Can't be less than 1MB + if (persistenceCacheSizeBytes < 1024*1024) { + [NSException raise:NSInvalidArgumentException format:@"The minimum cache size must be at least 1MB"]; + } + if (persistenceCacheSizeBytes > 100*1024*1024) { + [NSException raise:NSInvalidArgumentException format:@"Firebase Database currently doesn't support a cache size larger than 100MB"]; + } + self->_persistenceCacheSizeBytes = persistenceCacheSizeBytes; +} + +- (void)setCallbackQueue:(dispatch_queue_t)callbackQueue { + [self assertUnfrozen]; + self->_callbackQueue = callbackQueue; +} + +- (void)freeze { + self->_isFrozen = YES; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRDatabaseQuery.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRDatabaseQuery.m new file mode 100644 index 00000000..de18a7c0 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRDatabaseQuery.m @@ -0,0 +1,525 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRDatabaseQuery.h" +#import "FIRDatabaseQuery_Private.h" +#import "FValidation.h" +#import "FQueryParams.h" +#import "FQuerySpec.h" +#import "FValueEventRegistration.h" +#import "FChildEventRegistration.h" +#import "FPath.h" +#import "FKeyIndex.h" +#import "FPathIndex.h" +#import "FPriorityIndex.h" +#import "FValueIndex.h" +#import "FLeafNode.h" +#import "FSnapshotUtilities.h" +#import "FConstants.h" + +@implementation FIRDatabaseQuery + +@synthesize repo; +@synthesize path; +@synthesize queryParams; + +#define INVALID_QUERY_PARAM_ERROR @"InvalidQueryParameter" + + ++ (dispatch_queue_t)sharedQueue +{ + // We use this shared queue across all of the FQueries so things happen FIFO (as opposed to dispatch_get_global_queue(0, 0) which is concurrent) + static dispatch_once_t pred; + static dispatch_queue_t sharedDispatchQueue; + + dispatch_once(&pred, ^{ + sharedDispatchQueue = dispatch_queue_create("FirebaseWorker", NULL); + }); + + return sharedDispatchQueue; +} + +- (id) initWithRepo:(FRepo *)theRepo path:(FPath *)thePath { + return [self initWithRepo:theRepo path:thePath params:nil orderByCalled:NO priorityMethodCalled:NO]; +} + +- (id) initWithRepo:(FRepo *)theRepo + path:(FPath *)thePath + params:(FQueryParams *)theParams + orderByCalled:(BOOL)orderByCalled +priorityMethodCalled:(BOOL)priorityMethodCalled { + self = [super init]; + if (self) { + self.repo = theRepo; + self.path = thePath; + if (!theParams) { + theParams = [FQueryParams defaultInstance]; + } + if (![theParams isValid]) { + @throw [[NSException alloc] initWithName:@"InvalidArgumentError" reason:@"Queries are limited to two constraints" userInfo:nil]; + } + self.queryParams = theParams; + self.orderByCalled = orderByCalled; + self.priorityMethodCalled = priorityMethodCalled; + } + return self; +} + +- (FQuerySpec *)querySpec { + return [[FQuerySpec alloc] initWithPath:self.path params:self.queryParams]; +} + +- (void)validateQueryEndpointsForParams:(FQueryParams *)params { + if ([params.index isEqual:[FKeyIndex keyIndex]]) { + if ([params hasStart]) { + if (params.indexStartKey != [FUtilities minName]) { + [NSException raise:INVALID_QUERY_PARAM_ERROR format:@"Can't use queryStartingAtValue:childKey: or queryEqualTo:andChildKey: in combination with queryOrderedByKey"]; + } + if (![params.indexStartValue.val isKindOfClass:[NSString class]]) { + [NSException raise:INVALID_QUERY_PARAM_ERROR format:@"Can't use queryStartingAtValue: with other types than string in combination with queryOrderedByKey"]; + } + } + if ([params hasEnd]) { + if (params.indexEndKey != [FUtilities maxName]) { + [NSException raise:INVALID_QUERY_PARAM_ERROR format:@"Can't use queryEndingAtValue:childKey: or queryEqualToValue:childKey: in combination with queryOrderedByKey"]; + } + if (![params.indexEndValue.val isKindOfClass:[NSString class]]) { + [NSException raise:INVALID_QUERY_PARAM_ERROR format:@"Can't use queryEndingAtValue: with other types than string in combination with queryOrderedByKey"]; + } + } + } else if ([params.index isEqual:[FPriorityIndex priorityIndex]]) { + if (([params hasStart] && ![FValidation validatePriorityValue:params.indexStartValue.val]) || + ([params hasEnd] && ![FValidation validatePriorityValue:params.indexEndValue.val])) { + [NSException raise:INVALID_QUERY_PARAM_ERROR format:@"When using queryOrderedByPriority, values provided to queryStartingAtValue:, queryEndingAtValue:, or queryEqualToValue: must be valid priorities."]; + } + } +} + +- (void)validateEqualToCall { + if ([self.queryParams hasStart]) { + [NSException raise:INVALID_QUERY_PARAM_ERROR format:@"Cannot combine queryEqualToValue: and queryStartingAtValue:"]; + } + if ([self.queryParams hasEnd]) { + [NSException raise:INVALID_QUERY_PARAM_ERROR format:@"Cannot combine queryEqualToValue: and queryEndingAtValue:"]; + } +} + +- (void)validateNoPreviousOrderByCalled { + if (self.orderByCalled) { + [NSException raise:INVALID_QUERY_PARAM_ERROR format:@"Cannot use multiple queryOrderedBy calls!"]; + } +} + +- (void)validateIndexValueType:(id)type fromMethod:(NSString *)method { + if (type != nil && + ![type isKindOfClass:[NSNumber class]] && + ![type isKindOfClass:[NSString class]] && + ![type isKindOfClass:[NSNull class]]) { + [NSException raise:INVALID_QUERY_PARAM_ERROR format:@"You can only pass nil, NSString or NSNumber to %@", method]; + } +} + +- (FIRDatabaseQuery *)queryStartingAtValue:(id)startValue { + return [self queryStartingAtInternal:startValue childKey:nil from:@"queryStartingAtValue:" priorityMethod:NO]; +} + +- (FIRDatabaseQuery *)queryStartingAtValue:(id)startValue childKey:(NSString *)childKey { + if ([self.queryParams.index isEqual:[FKeyIndex keyIndex]]) { + @throw [[NSException alloc] initWithName:INVALID_QUERY_PARAM_ERROR + reason:@"You must use queryStartingAtValue: instead of queryStartingAtValue:childKey: when using queryOrderedByKey:" + userInfo:nil]; + } + return [self queryStartingAtInternal:startValue + childKey:childKey + from:@"queryStartingAtValue:childKey:" + priorityMethod:NO]; +} + +- (FIRDatabaseQuery *)queryStartingAtInternal:(id)startValue + childKey:(NSString *)childKey + from:(NSString *)methodName + priorityMethod:(BOOL)priorityMethod { + [self validateIndexValueType:startValue fromMethod:methodName]; + if (childKey != nil) { + [FValidation validateFrom:methodName validKey:childKey]; + } + if ([self.queryParams hasStart]) { + [NSException raise:INVALID_QUERY_PARAM_ERROR + format:@"Can't call %@ after queryStartingAtValue or queryEqualToValue was previously called", methodName]; + } + id startNode = [FSnapshotUtilities nodeFrom:startValue]; + FQueryParams* params = [self.queryParams startAt:startNode childKey:childKey]; + [self validateQueryEndpointsForParams:params]; + return [[FIRDatabaseQuery alloc] initWithRepo:self.repo + path:self.path + params:params + orderByCalled:self.orderByCalled + priorityMethodCalled:priorityMethod || self.priorityMethodCalled]; +} + +- (FIRDatabaseQuery *)queryEndingAtValue:(id)endValue { + return [self queryEndingAtInternal:endValue + childKey:nil + from:@"queryEndingAtValue:" + priorityMethod:NO]; +} + +- (FIRDatabaseQuery *)queryEndingAtValue:(id)endValue childKey:(NSString *)childKey { + if ([self.queryParams.index isEqual:[FKeyIndex keyIndex]]) { + @throw [[NSException alloc] initWithName:INVALID_QUERY_PARAM_ERROR + reason:@"You must use queryEndingAtValue: instead of queryEndingAtValue:childKey: when using queryOrderedByKey:" + userInfo:nil]; + } + + return [self queryEndingAtInternal:endValue + childKey:childKey + from:@"queryEndingAtValue:childKey:" + priorityMethod:NO]; +} + +- (FIRDatabaseQuery *)queryEndingAtInternal:(id)endValue + childKey:(NSString *)childKey + from:(NSString *)methodName + priorityMethod:(BOOL)priorityMethod { + [self validateIndexValueType:endValue fromMethod:methodName]; + if (childKey != nil) { + [FValidation validateFrom:methodName validKey:childKey]; + } + if ([self.queryParams hasEnd]) { + [NSException raise:INVALID_QUERY_PARAM_ERROR + format:@"Can't call %@ after queryEndingAtValue or queryEqualToValue was previously called", methodName]; + } + id endNode = [FSnapshotUtilities nodeFrom:endValue]; + FQueryParams* params = [self.queryParams endAt:endNode childKey:childKey]; + [self validateQueryEndpointsForParams:params]; + return [[FIRDatabaseQuery alloc] initWithRepo:self.repo + path:self.path + params:params + orderByCalled:self.orderByCalled + priorityMethodCalled:priorityMethod || self.priorityMethodCalled]; +} + +- (FIRDatabaseQuery *)queryEqualToValue:(id)value { + return [self queryEqualToInternal:value childKey:nil from:@"queryEqualToValue:" priorityMethod:NO]; +} + +- (FIRDatabaseQuery *)queryEqualToValue:(id)value childKey:(NSString *)childKey { + if ([self.queryParams.index isEqual:[FKeyIndex keyIndex]]) { + @throw [[NSException alloc] initWithName:INVALID_QUERY_PARAM_ERROR + reason:@"You must use queryEqualToValue: instead of queryEqualTo:childKey: when using queryOrderedByKey:" + userInfo:nil]; + } + return [self queryEqualToInternal:value childKey:childKey from:@"queryEqualToValue:childKey:" priorityMethod:NO]; +} + +- (FIRDatabaseQuery *)queryEqualToInternal:(id)value + childKey:(NSString *)childKey + from:(NSString *)methodName + priorityMethod:(BOOL)priorityMethod { + [self validateIndexValueType:value fromMethod:methodName]; + if (childKey != nil) { + [FValidation validateFrom:methodName validKey:childKey]; + } + if ([self.queryParams hasEnd] || [self.queryParams hasStart]) { + [NSException raise:INVALID_QUERY_PARAM_ERROR + format:@"Can't call %@ after queryStartingAtValue, queryEndingAtValue or queryEqualToValue was previously called", methodName]; + } + id node = [FSnapshotUtilities nodeFrom:value]; + FQueryParams* params = [[self.queryParams startAt:node childKey:childKey] endAt:node childKey:childKey]; + [self validateQueryEndpointsForParams:params]; + return [[FIRDatabaseQuery alloc] initWithRepo:self.repo + path:self.path + params:params + orderByCalled:self.orderByCalled + priorityMethodCalled:priorityMethod || self.priorityMethodCalled]; +} + +- (void)validateLimitRange:(NSUInteger)limit +{ + // No need to check for negative ranges, since limit is unsigned + if (limit == 0) { + [NSException raise:INVALID_QUERY_PARAM_ERROR format:@"Limit can't be zero"]; + } + if (limit >= 1ul<<31) { + [NSException raise:INVALID_QUERY_PARAM_ERROR format:@"Limit must be less than 2,147,483,648"]; + } +} + +- (FIRDatabaseQuery *)queryLimitedToFirst:(NSUInteger)limit { + if (self.queryParams.limitSet) { + [NSException raise:INVALID_QUERY_PARAM_ERROR format:@"Can't call queryLimitedToFirst: if a limit was previously set"]; + } + [self validateLimitRange:limit]; + FQueryParams* params = [self.queryParams limitToFirst:limit]; + return [[FIRDatabaseQuery alloc] initWithRepo:self.repo + path:self.path + params:params + orderByCalled:self.orderByCalled + priorityMethodCalled:self.priorityMethodCalled]; +} + +- (FIRDatabaseQuery *)queryLimitedToLast:(NSUInteger)limit { + if (self.queryParams.limitSet) { + [NSException raise:INVALID_QUERY_PARAM_ERROR format:@"Can't call queryLimitedToLast: if a limit was previously set"]; + } + [self validateLimitRange:limit]; + FQueryParams* params = [self.queryParams limitToLast:limit]; + return [[FIRDatabaseQuery alloc] initWithRepo:self.repo + path:self.path + params:params + orderByCalled:self.orderByCalled + priorityMethodCalled:self.priorityMethodCalled]; +} + +- (FIRDatabaseQuery *)queryOrderedByChild:(NSString *)indexPathString { + if ([indexPathString isEqualToString:@"$key"] || [indexPathString isEqualToString:@".key"]) { + @throw [[NSException alloc] initWithName:INVALID_QUERY_PARAM_ERROR + reason:[NSString stringWithFormat:@"(queryOrderedByChild:) %@ is invalid. Use queryOrderedByKey: instead.", indexPathString] + userInfo:nil]; + } else if ([indexPathString isEqualToString:@"$priority"] || [indexPathString isEqualToString:@".priority"]) { + @throw [[NSException alloc] initWithName:INVALID_QUERY_PARAM_ERROR + reason:[NSString stringWithFormat:@"(queryOrderedByChild:) %@ is invalid. Use queryOrderedByPriority: instead.", indexPathString] + userInfo:nil]; + } else if ([indexPathString isEqualToString:@"$value"] || [indexPathString isEqualToString:@".value"]) { + @throw [[NSException alloc] initWithName:INVALID_QUERY_PARAM_ERROR + reason:[NSString stringWithFormat:@"(queryOrderedByChild:) %@ is invalid. Use queryOrderedByValue: instead.", indexPathString] + userInfo:nil]; + } + [self validateNoPreviousOrderByCalled]; + + [FValidation validateFrom:@"queryOrderedByChild:" validPathString:indexPathString]; + FPath *indexPath = [FPath pathWithString:indexPathString]; + if (indexPath.isEmpty) { + @throw [[NSException alloc] initWithName:INVALID_QUERY_PARAM_ERROR + reason:[NSString stringWithFormat:@"(queryOrderedByChild:) with an empty path is invalid. Use queryOrderedByValue: instead."] + userInfo:nil]; + } + id index = [[FPathIndex alloc] initWithPath:indexPath]; + + FQueryParams *params = [self.queryParams orderBy:index]; + [self validateQueryEndpointsForParams:params]; + return [[FIRDatabaseQuery alloc] initWithRepo:self.repo + path:self.path + params:params + orderByCalled:YES + priorityMethodCalled:self.priorityMethodCalled]; +} + +- (FIRDatabaseQuery *) queryOrderedByKey { + [self validateNoPreviousOrderByCalled]; + FQueryParams *params = [self.queryParams orderBy:[FKeyIndex keyIndex]]; + [self validateQueryEndpointsForParams:params]; + return [[FIRDatabaseQuery alloc] initWithRepo:self.repo + path:self.path + params:params + orderByCalled:YES + priorityMethodCalled:self.priorityMethodCalled]; +} + +- (FIRDatabaseQuery *) queryOrderedByValue { + [self validateNoPreviousOrderByCalled]; + FQueryParams *params = [self.queryParams orderBy:[FValueIndex valueIndex]]; + return [[FIRDatabaseQuery alloc] initWithRepo:self.repo + path:self.path + params:params + orderByCalled:YES + priorityMethodCalled:self.priorityMethodCalled]; +} + +- (FIRDatabaseQuery *) queryOrderedByPriority { + [self validateNoPreviousOrderByCalled]; + FQueryParams *params = [self.queryParams orderBy:[FPriorityIndex priorityIndex]]; + return [[FIRDatabaseQuery alloc] initWithRepo:self.repo + path:self.path + params:params + orderByCalled:YES + priorityMethodCalled:self.priorityMethodCalled]; +} + +- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *))block { + [FValidation validateFrom:@"observeEventType:withBlock:" knownEventType:eventType]; + return [self observeEventType:eventType withBlock:block withCancelBlock:nil]; +} + + +- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(fbt_void_datasnapshot_nsstring)block { + [FValidation validateFrom:@"observeEventType:andPreviousSiblingKeyWithBlock:" knownEventType:eventType]; + return [self observeEventType:eventType andPreviousSiblingKeyWithBlock:block withCancelBlock:nil]; +} + + +- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType withBlock:(fbt_void_datasnapshot)block withCancelBlock:(fbt_void_nserror)cancelBlock { + [FValidation validateFrom:@"observeEventType:withBlock:withCancelBlock:" knownEventType:eventType]; + + if (eventType == FIRDataEventTypeValue) { + // Handle FIRDataEventTypeValue specially because they shouldn't have prevName callbacks + NSUInteger handle = [[FUtilities LUIDGenerator] integerValue]; + [self observeValueEventWithHandle:handle withBlock:block cancelCallback:cancelBlock]; + return handle; + } else { + // Wrap up the userCallback so we can treat everything as a callback that has a prevName + fbt_void_datasnapshot userCallback = [block copy]; + return [self observeEventType:eventType andPreviousSiblingKeyWithBlock:^(FIRDataSnapshot *snapshot, NSString *prevName) { + if (userCallback != nil) { + userCallback(snapshot); + } + } withCancelBlock:cancelBlock]; + } +} + +- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(fbt_void_datasnapshot_nsstring)block withCancelBlock:(fbt_void_nserror)cancelBlock { + [FValidation validateFrom:@"observeEventType:andPreviousSiblingKeyWithBlock:withCancelBlock:" knownEventType:eventType]; + + + if (eventType == FIRDataEventTypeValue) { + // TODO: This gets hit by observeSingleEventOfType. Need to fix. + /* + @throw [[NSException alloc] initWithName:@"InvalidEventTypeForObserver" + reason:@"(observeEventType:andPreviousSiblingKeyWithBlock:withCancelBlock:) Cannot use observeEventType:andPreviousSiblingKeyWithBlock:withCancelBlock: with FIRDataEventTypeValue. Use observeEventType:withBlock:withCancelBlock: instead." + userInfo:nil]; + */ + } + + NSUInteger handle = [[FUtilities LUIDGenerator] integerValue]; + NSDictionary *callbacks = @{[NSNumber numberWithInteger:eventType]: [block copy]}; + [self observeChildEventWithHandle:handle withCallbacks:callbacks cancelCallback:cancelBlock]; + + return handle; +} + +// If we want to distinguish between value event listeners and child event listeners, like in the Java client, we can +// consider exporting this. If we do, add argument validation. Otherwise, arguments are validated in the public-facing +// portions of the API. Also, move the FIRDatabaseHandle logic. +- (void)observeValueEventWithHandle:(FIRDatabaseHandle)handle withBlock:(fbt_void_datasnapshot)block cancelCallback:(fbt_void_nserror)cancelBlock { + // Note that we don't need to copy the callbacks here, FEventRegistration callback properties set to copy + FValueEventRegistration *registration = [[FValueEventRegistration alloc] initWithRepo:self.repo + handle:handle + callback:block + cancelCallback:cancelBlock]; + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + [self.repo addEventRegistration:registration forQuery:self.querySpec]; + }); +} + +// Note: as with the above method, we may wish to expose this at some point. +- (void)observeChildEventWithHandle:(FIRDatabaseHandle)handle withCallbacks:(NSDictionary *)callbacks cancelCallback:(fbt_void_nserror)cancelBlock { + // Note that we don't need to copy the callbacks here, FEventRegistration callback properties set to copy + FChildEventRegistration *registration = [[FChildEventRegistration alloc] initWithRepo:self.repo + handle:handle + callbacks:callbacks + cancelCallback:cancelBlock]; + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + [self.repo addEventRegistration:registration forQuery:self.querySpec]; + }); +} + + +- (void) removeObserverWithHandle:(FIRDatabaseHandle)handle { + FValueEventRegistration *event = [[FValueEventRegistration alloc] initWithRepo:self.repo + handle:handle + callback:nil + cancelCallback:nil]; + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + [self.repo removeEventRegistration:event forQuery:self.querySpec]; + }); +} + + +- (void) removeAllObservers { + [self removeObserverWithHandle:NSNotFound]; +} + +- (void)keepSynced:(BOOL)keepSynced { + if ([self.path.getFront isEqualToString:kDotInfoPrefix]) { + [NSException raise:NSInvalidArgumentException format:@"Can't keep query on .info tree synced (this already is the case)."]; + } + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + [self.repo keepQuery:self.querySpec synced:keepSynced]; + }); +} + +- (void)observeSingleEventOfType:(FIRDataEventType)eventType withBlock:(fbt_void_datasnapshot)block { + + [self observeSingleEventOfType:eventType withBlock:block withCancelBlock:nil]; +} + + +- (void)observeSingleEventOfType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(fbt_void_datasnapshot_nsstring)block { + + [self observeSingleEventOfType:eventType andPreviousSiblingKeyWithBlock:block withCancelBlock:nil]; +} + + +- (void)observeSingleEventOfType:(FIRDataEventType)eventType withBlock:(fbt_void_datasnapshot)block withCancelBlock:(fbt_void_nserror)cancelBlock { + + // XXX: user reported memory leak in method + + // "When you copy a block, any references to other blocks from within that block are copied if necessary—an entire tree may be copied (from the top). If you have block variables and you reference a block from within the block, that block will be copied." + // http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/bxVariables.html#//apple_ref/doc/uid/TP40007502-CH6-SW1 + // So... we don't need to do this since inside the on: we copy this block off the stack to the heap. + // __block fbt_void_datasnapshot userCallback = [callback copy]; + + [self observeSingleEventOfType:eventType andPreviousSiblingKeyWithBlock:^(FIRDataSnapshot *snapshot, NSString *prevName) { + if (block != nil) { + block(snapshot); + } + } withCancelBlock:cancelBlock]; +} + +/** +* Attaches a listener, waits for the first event, and then removes the listener +*/ +- (void)observeSingleEventOfType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(fbt_void_datasnapshot_nsstring)block withCancelBlock:(fbt_void_nserror)cancelBlock { + + // XXX: user reported memory leak in method + + // "When you copy a block, any references to other blocks from within that block are copied if necessary—an entire tree may be copied (from the top). If you have block variables and you reference a block from within the block, that block will be copied." + // http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/bxVariables.html#//apple_ref/doc/uid/TP40007502-CH6-SW1 + // So... we don't need to do this since inside the on: we copy this block off the stack to the heap. + // __block fbt_void_datasnapshot userCallback = [callback copy]; + + __block FIRDatabaseHandle handle; + __block BOOL firstCall = YES; + + fbt_void_datasnapshot_nsstring callback = [block copy]; + fbt_void_datasnapshot_nsstring wrappedCallback = ^(FIRDataSnapshot *snap, NSString* prevName) { + if (firstCall) { + firstCall = NO; + [self removeObserverWithHandle:handle]; + callback(snap, prevName); + } + }; + + fbt_void_nserror cancelCallback = [cancelBlock copy]; + handle = [self observeEventType:eventType andPreviousSiblingKeyWithBlock:wrappedCallback withCancelBlock:^(NSError* error){ + + [self removeObserverWithHandle:handle]; + + if (cancelCallback) { + cancelCallback(error); + } + }]; +} + +- (NSString *) description { + return [NSString stringWithFormat:@"(%@ %@)", self.path, self.queryParams.description]; +} + +- (FIRDatabaseReference *) ref { + return [[FIRDatabaseReference alloc] initWithRepo:self.repo path:self.path]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRMutableData.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRMutableData.m new file mode 100644 index 00000000..77a022ab --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRMutableData.m @@ -0,0 +1,134 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMutableData.h" +#import "FIRMutableData_Private.h" +#import "FSnapshotHolder.h" +#import "FSnapshotUtilities.h" +#import "FChildrenNode.h" +#import "FTransformedEnumerator.h" +#import "FNamedNode.h" +#import "FIndexedNode.h" + +@interface FIRMutableData () + +- (id) initWithPrefixPath:(FPath *)path andSnapshotHolder:(FSnapshotHolder *)snapshotHolder; + +@property (strong, nonatomic) FSnapshotHolder* data; +@property (strong, nonatomic) FPath* prefixPath; + +@end + +@implementation FIRMutableData + +@synthesize data; +@synthesize prefixPath; + +- (id) initWithNode:(id)node { + FSnapshotHolder* holder = [[FSnapshotHolder alloc] init]; + FPath* path = [FPath empty]; + [holder updateSnapshot:path withNewSnapshot:node]; + return [self initWithPrefixPath:path andSnapshotHolder:holder]; +} + +- (id) initWithPrefixPath:(FPath *)path andSnapshotHolder:(FSnapshotHolder *)snapshotHolder { + self = [super init]; + if (self) { + self.prefixPath = path; + self.data = snapshotHolder; + } + return self; +} + +- (FIRMutableData *)childDataByAppendingPath:(NSString *)path { + FPath* wholePath = [self.prefixPath childFromString:path]; + return [[FIRMutableData alloc] initWithPrefixPath:wholePath andSnapshotHolder:self.data]; +} + +- (FIRMutableData *) parent { + if ([self.prefixPath isEmpty]) { + return nil; + } else { + FPath* path = [self.prefixPath parent]; + return [[FIRMutableData alloc] initWithPrefixPath:path andSnapshotHolder:self.data]; + } +} + +- (void) setValue:(id)aValue { + id node = [FSnapshotUtilities nodeFrom:aValue withValidationFrom:@"setValue:"]; + [self.data updateSnapshot:self.prefixPath withNewSnapshot:node]; +} + +- (void) setPriority:(id)aPriority { + id node = [self.data getNode:self.prefixPath]; + id pri = [FSnapshotUtilities nodeFrom:aPriority]; + node = [node updatePriority:pri]; + [self.data updateSnapshot:self.prefixPath withNewSnapshot:node]; +} + +- (id) value { + return [[self.data getNode:self.prefixPath] val]; +} + +- (id) priority { + return [[[self.data getNode:self.prefixPath] getPriority] val]; +} + +- (BOOL) hasChildren { + id node = [self.data getNode:self.prefixPath]; + return ![node isLeafNode] && ![(FChildrenNode*)node isEmpty]; +} + +- (BOOL) hasChildAtPath:(NSString *)path { + id node = [self.data getNode:self.prefixPath]; + FPath* childPath = [[FPath alloc] initWith:path]; + return ![[node getChild:childPath] isEmpty]; +} + +- (NSUInteger) childrenCount { + return [[self.data getNode:self.prefixPath] numChildren]; +} + +- (NSString *) key { + return [self.prefixPath getBack]; +} + +- (id) nodeValue { + return [self.data getNode:self.prefixPath]; +} + +- (NSEnumerator *) children { + FIndexedNode *indexedNode = [FIndexedNode indexedNodeWithNode:self.nodeValue]; + return [[FTransformedEnumerator alloc] initWithEnumerator:[indexedNode childEnumerator] andTransform:^id(FNamedNode *node) { + FPath* childPath = [self.prefixPath childFromString:node.name]; + FIRMutableData * childData = [[FIRMutableData alloc] initWithPrefixPath:childPath andSnapshotHolder:self.data]; + return childData; + }]; +} + +- (BOOL) isEqualToData:(FIRMutableData *)other { + return self.data == other.data && [[self.prefixPath description] isEqualToString:[other.prefixPath description]]; +} + +- (NSString *) description { + if (self.key == nil) { + return [NSString stringWithFormat:@"FIRMutableData (top-most transaction) %@ %@", self.key, self.value]; + } else { + return [NSString stringWithFormat:@"FIRMutableData (%@) %@", self.key, self.value]; + } +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRServerValue.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRServerValue.m new file mode 100644 index 00000000..14bb745f --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRServerValue.m @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRDatabaseReference.h" +#import "FIRServerValue.h" + +@implementation FIRServerValue + ++ (NSDictionary *) timestamp { + static NSDictionary *timestamp = nil; + if (timestamp == nil) { + timestamp = @{ @".sv": @"timestamp" }; + } + return timestamp; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRTransactionResult.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRTransactionResult.m new file mode 100644 index 00000000..8afc5b7b --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/FIRTransactionResult.m @@ -0,0 +1,39 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRTransactionResult.h" +#import "FIRTransactionResult_Private.h" + +@implementation FIRTransactionResult + +@synthesize update; +@synthesize isSuccess; + ++ (FIRTransactionResult *)successWithValue:(FIRMutableData *)value { + FIRTransactionResult * result = [[FIRTransactionResult alloc] init]; + result.isSuccess = YES; + result.update = value; + return result; +} + ++ (FIRTransactionResult *) abort { + FIRTransactionResult * result = [[FIRTransactionResult alloc] init]; + result.isSuccess = NO; + result.update = nil; + return result; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Api/Private/FIRDataSnapshot_Private.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/Private/FIRDataSnapshot_Private.h new file mode 100644 index 00000000..c2d3871b --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/Private/FIRDataSnapshot_Private.h @@ -0,0 +1,28 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRDataSnapshot.h" +#import "FIndexedNode.h" +#import "FTypedefs_Private.h" + +@interface FIRDataSnapshot () + +// in _Private for testing purposes +@property (nonatomic, strong) FIndexedNode *node; + +- (id)initWithRef:(FIRDatabaseReference *)ref indexedNode:(FIndexedNode *)node; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Api/Private/FIRDatabaseQuery_Private.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/Private/FIRDatabaseQuery_Private.h new file mode 100644 index 00000000..3a10fe3e --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/Private/FIRDatabaseQuery_Private.h @@ -0,0 +1,43 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FRepo.h" +#import "FPath.h" +#import "FRepoManager.h" +#import "FTypedefs_Private.h" +#import "FQueryParams.h" +#import "FIRDatabaseQuery.h" + +@interface FIRDatabaseQuery () + ++ (dispatch_queue_t)sharedQueue; + +- (id) initWithRepo:(FRepo *)repo path:(FPath *)path; +- (id) initWithRepo:(FRepo *)repo + path:(FPath *)path + params:(FQueryParams *)params + orderByCalled:(BOOL)orderByCalled +priorityMethodCalled:(BOOL)priorityMethodCalled; + +@property (nonatomic, strong) FRepo* repo; +@property (nonatomic, strong) FPath* path; +@property (nonatomic, strong) FQueryParams *queryParams; +@property (nonatomic) BOOL orderByCalled; +@property (nonatomic) BOOL priorityMethodCalled; + +- (FQuerySpec *)querySpec; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Api/Private/FIRDatabaseReference_Private.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/Private/FIRDatabaseReference_Private.h new file mode 100644 index 00000000..6063cb83 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/Private/FIRDatabaseReference_Private.h @@ -0,0 +1,27 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRDatabaseReference.h" +#import "FTypedefs_Private.h" +#import "FIRDatabaseConfig.h" +#import "FRepo.h" + +@interface FIRDatabaseReference () + +- (id)initWithConfig:(FIRDatabaseConfig *)config; +- (id)initWithRepo:(FRepo *)repo path:(FPath *)path; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Api/Private/FIRDatabase_Private.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/Private/FIRDatabase_Private.h new file mode 100644 index 00000000..5e294519 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/Private/FIRDatabase_Private.h @@ -0,0 +1,34 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRDatabase.h" + +@class FRepo; +@class FRepoInfo; +@class FIRDatabaseConfig; + +@interface FIRDatabase () + +@property (nonatomic, strong) FRepoInfo *repoInfo; +@property (nonatomic, strong) FIRDatabaseConfig *config; +@property (nonatomic, strong) FRepo *repo; + +- (id)initWithApp:(FIRApp *)app repoInfo:(FRepoInfo *)info config:(FIRDatabaseConfig *)config; + ++ (NSString *) buildVersion; ++ (FIRDatabase *) createDatabaseForTests:(FRepoInfo *)repoInfo config:(FIRDatabaseConfig *)config; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Api/Private/FIRMutableData_Private.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/Private/FIRMutableData_Private.h new file mode 100644 index 00000000..ee3aa967 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/Private/FIRMutableData_Private.h @@ -0,0 +1,26 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMutableData.h" +#import "FNode.h" + +@interface FIRMutableData () + +- (id) initWithNode:(id)node; +- (id) nodeValue; +- (BOOL) isEqualToData:(FIRMutableData *)other; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Api/Private/FIRTransactionResult_Private.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/Private/FIRTransactionResult_Private.h new file mode 100644 index 00000000..82290f27 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/Private/FIRTransactionResult_Private.h @@ -0,0 +1,25 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRTransactionResult.h" +#import "FIRMutableData.h" + +@interface FIRTransactionResult () + +@property (nonatomic) BOOL isSuccess; +@property (nonatomic, strong) FIRMutableData * update; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Api/Private/FTypedefs_Private.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/Private/FTypedefs_Private.h new file mode 100644 index 00000000..73f4c9a3 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Api/Private/FTypedefs_Private.h @@ -0,0 +1,56 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#ifndef __FTYPEDEFS_PRIVATE__ +#define __FTYPEDEFS_PRIVATE__ + +#import + +typedef NS_ENUM(NSInteger, FTransactionStatus) { + FTransactionInitializing, // 0 + FTransactionRun, // 1 + FTransactionSent, // 2 + FTransactionCompleted, // 3 + FTransactionSentNeedsAbort, // 4 + FTransactionNeedsAbort // 5 +}; + +@protocol FNode; +@class FPath; +@class FIRTransactionResult; +@class FIRMutableData; +@class FIRDataSnapshot; +@class FCompoundHash; + +typedef void (^fbt_void_nserror_bool_datasnapshot) (NSError* error, BOOL committed, FIRDataSnapshot * snapshot); +typedef FIRTransactionResult * (^fbt_transactionresult_mutabledata) (FIRMutableData * currentData); +typedef void (^fbt_void_path_node) (FPath*, id); +typedef void (^fbt_void_nsstring) (NSString *); +typedef BOOL (^fbt_bool_nsstring_node) (NSString *, id); +typedef void (^fbt_void_path_node_marray) (FPath *, id, NSMutableArray *); +typedef BOOL (^fbt_bool_void) (void); +typedef void (^fbt_void_nsstring_nsstring)(NSString *str1, NSString* str2); +typedef void (^fbt_void_nsstring_nserror)(NSString *str, NSError* error); +typedef BOOL (^fbt_bool_path)(FPath *str); +typedef void (^fbt_void_id)(id data); +typedef NSString* (^fbt_nsstring_void) (void); +typedef FCompoundHash* (^fbt_compoundhash_void) (void); +typedef NSArray* (^fbt_nsarray_nsstring_id)(NSString *status, id Data); +typedef NSArray* (^fbt_nsarray_nsstring)(NSString *status); + +// WWDC 2012 session 712 starting in page 83 for saving blocks in properties (use @property (strong) type name). + +#endif diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Constants/FConstants.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Constants/FConstants.h new file mode 100644 index 00000000..e97a8a11 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Constants/FConstants.h @@ -0,0 +1,190 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#ifndef Firebase_FConstants_h +#define Firebase_FConstants_h + +#import + +#pragma mark - +#pragma mark Wire Protocol Envelope Constants + +FOUNDATION_EXPORT NSString *const kFWPRequestType; +FOUNDATION_EXPORT NSString *const kFWPRequestTypeData; +FOUNDATION_EXPORT NSString *const kFWPRequestDataPayload; +FOUNDATION_EXPORT NSString *const kFWPRequestNumber; +FOUNDATION_EXPORT NSString *const kFWPRequestPayloadBody; +FOUNDATION_EXPORT NSString *const kFWPRequestError; +FOUNDATION_EXPORT NSString *const kFWPRequestAction; +FOUNDATION_EXPORT NSString *const kFWPResponseForRNData; +FOUNDATION_EXPORT NSString *const kFWPResponseForActionStatus; +FOUNDATION_EXPORT NSString *const kFWPResponseForActionStatusOk; +FOUNDATION_EXPORT NSString *const kFWPResponseForActionStatusDataStale; +FOUNDATION_EXPORT NSString *const kFWPResponseForActionData; +FOUNDATION_EXPORT NSString *const kFWPResponseDataWarnings; + +FOUNDATION_EXPORT NSString *const kFWPAsyncServerAction; +FOUNDATION_EXPORT NSString *const kFWPAsyncServerPayloadBody; +FOUNDATION_EXPORT NSString *const kFWPAsyncServerDataUpdate; +FOUNDATION_EXPORT NSString *const kFWPAsyncServerDataMerge; +FOUNDATION_EXPORT NSString *const kFWPAsyncServerDataRangeMerge; +FOUNDATION_EXPORT NSString *const kFWPAsyncServerAuthRevoked; +FOUNDATION_EXPORT NSString *const kFWPASyncServerListenCancelled; +FOUNDATION_EXPORT NSString *const kFWPAsyncServerSecurityDebug; +FOUNDATION_EXPORT NSString *const kFWPAsyncServerDataUpdateBodyPath; // {“a”: “d”, “b”: {“p”: “/”, “d”: “”}} +FOUNDATION_EXPORT NSString *const kFWPAsyncServerDataUpdateBodyData; +FOUNDATION_EXPORT NSString *const kFWPAsyncServerDataUpdateStartPath; +FOUNDATION_EXPORT NSString *const kFWPAsyncServerDataUpdateEndPath; +FOUNDATION_EXPORT NSString *const kFWPAsyncServerDataUpdateRangeMerge; +FOUNDATION_EXPORT NSString *const kFWPAsyncServerDataUpdateBodyTag; +FOUNDATION_EXPORT NSString *const kFWPAsyncServerDataQueries; + +FOUNDATION_EXPORT NSString *const kFWPAsyncServerEnvelopeType; +FOUNDATION_EXPORT NSString *const kFWPAsyncServerEnvelopeData; +FOUNDATION_EXPORT NSString *const kFWPAsyncServerControlMessage; +FOUNDATION_EXPORT NSString *const kFWPAsyncServerControlMessageType; +FOUNDATION_EXPORT NSString *const kFWPAsyncServerControlMessageData; +FOUNDATION_EXPORT NSString *const kFWPAsyncServerDataMessage; + +FOUNDATION_EXPORT NSString *const kFWPAsyncServerHello; +FOUNDATION_EXPORT NSString *const kFWPAsyncServerHelloTimestamp; +FOUNDATION_EXPORT NSString *const kFWPAsyncServerHelloVersion; +FOUNDATION_EXPORT NSString *const kFWPAsyncServerHelloConnectedHost; +FOUNDATION_EXPORT NSString *const kFWPAsyncServerHelloSession; + +FOUNDATION_EXPORT NSString *const kFWPAsyncServerControlMessageShutdown; +FOUNDATION_EXPORT NSString *const kFWPAsyncServerControlMessageReset; + +#pragma mark - +#pragma mark Wire Protocol Payload Constants + +FOUNDATION_EXPORT NSString *const kFWPRequestActionPut; +FOUNDATION_EXPORT NSString *const kFWPRequestActionMerge; +FOUNDATION_EXPORT NSString *const kFWPRequestActionTaggedListen; +FOUNDATION_EXPORT NSString *const kFWPRequestActionTaggedUnlisten; +FOUNDATION_EXPORT NSString *const kFWPRequestActionListen; // {"t": "d", "d": {"r": 1, "a": "l", "b": { "p": "/" } } } +FOUNDATION_EXPORT NSString *const kFWPRequestActionUnlisten; +FOUNDATION_EXPORT NSString *const kFWPRequestActionStats; +FOUNDATION_EXPORT NSString *const kFWPRequestActionDisconnectPut; +FOUNDATION_EXPORT NSString *const kFWPRequestActionDisconnectMerge; +FOUNDATION_EXPORT NSString *const kFWPRequestActionDisconnectCancel; +FOUNDATION_EXPORT NSString *const kFWPRequestActionAuth; +FOUNDATION_EXPORT NSString *const kFWPRequestActionUnauth; +FOUNDATION_EXPORT NSString *const kFWPRequestCredential; +FOUNDATION_EXPORT NSString *const kFWPRequestPath; +FOUNDATION_EXPORT NSString *const kFWPRequestCounters; +FOUNDATION_EXPORT NSString *const kFWPRequestQueries; +FOUNDATION_EXPORT NSString *const kFWPRequestTag; +FOUNDATION_EXPORT NSString *const kFWPRequestData; +FOUNDATION_EXPORT NSString *const kFWPRequestHash; +FOUNDATION_EXPORT NSString *const kFWPRequestCompoundHash; +FOUNDATION_EXPORT NSString *const kFWPRequestCompoundHashPaths; +FOUNDATION_EXPORT NSString *const kFWPRequestCompoundHashHashes; +FOUNDATION_EXPORT NSString *const kFWPRequestStatus; + +#pragma mark - +#pragma mark Websock Transport Constants + +FOUNDATION_EXPORT NSString *const kWireProtocolVersionParam; +FOUNDATION_EXPORT NSString *const kWebsocketProtocolVersion; +FOUNDATION_EXPORT NSString *const kWebsocketServerKillPacket; +FOUNDATION_EXPORT const int kWebsocketMaxFrameSize; +FOUNDATION_EXPORT NSUInteger const kWebsocketKeepaliveInterval; +FOUNDATION_EXPORT NSUInteger const kWebsocketConnectTimeout; + +FOUNDATION_EXPORT float const kPersistentConnReconnectMinDelay; +FOUNDATION_EXPORT float const kPersistentConnReconnectMaxDelay; +FOUNDATION_EXPORT float const kPersistentConnReconnectMultiplier; +FOUNDATION_EXPORT float const kPersistentConnSuccessfulConnectionEstablishedDelay; + +#pragma mark - +#pragma mark Query / QueryParams constants + +FOUNDATION_EXPORT NSString *const kQueryDefault; +FOUNDATION_EXPORT NSString *const kQueryDefaultObject; +FOUNDATION_EXPORT NSString *const kViewManagerDictConstView; +FOUNDATION_EXPORT NSString *const kFQPIndexStartValue; +FOUNDATION_EXPORT NSString *const kFQPIndexStartName; +FOUNDATION_EXPORT NSString *const kFQPIndexEndValue; +FOUNDATION_EXPORT NSString *const kFQPIndexEndName; +FOUNDATION_EXPORT NSString *const kFQPLimit; +FOUNDATION_EXPORT NSString *const kFQPViewFrom; +FOUNDATION_EXPORT NSString *const kFQPViewFromLeft; +FOUNDATION_EXPORT NSString *const kFQPViewFromRight; +FOUNDATION_EXPORT NSString *const kFQPIndex; + +#pragma mark - +#pragma mark Interrupt Reasons + +FOUNDATION_EXPORT NSString *const kFInterruptReasonServerKill; +FOUNDATION_EXPORT NSString *const kFInterruptReasonWaitingForOpen; +FOUNDATION_EXPORT NSString *const kFInterruptReasonRepoInterrupt; +FOUNDATION_EXPORT NSString *const kFInterruptReasonAuthExpired; + +#pragma mark - +#pragma mark Payload constants + +FOUNDATION_EXPORT NSString *const kPayloadPriority; +FOUNDATION_EXPORT NSString *const kPayloadValue; +FOUNDATION_EXPORT NSString *const kPayloadMetadataPrefix; + +#pragma mark - +#pragma mark ServerValue constants + +FOUNDATION_EXPORT NSString *const kServerValueSubKey; +FOUNDATION_EXPORT NSString *const kServerValuePriority; + +#pragma mark - +#pragma mark .info/ constants + +FOUNDATION_EXPORT NSString *const kDotInfoPrefix; +FOUNDATION_EXPORT NSString *const kDotInfoConnected; +FOUNDATION_EXPORT NSString *const kDotInfoServerTimeOffset; + +#pragma mark - +#pragma mark ObjectiveC to JavaScript type constants + +FOUNDATION_EXPORT NSString *const kJavaScriptObject; +FOUNDATION_EXPORT NSString *const kJavaScriptString; +FOUNDATION_EXPORT NSString *const kJavaScriptBoolean; +FOUNDATION_EXPORT NSString *const kJavaScriptNumber; +FOUNDATION_EXPORT NSString *const kJavaScriptNull; +FOUNDATION_EXPORT NSString *const kJavaScriptTrue; +FOUNDATION_EXPORT NSString *const kJavaScriptFalse; + +#pragma mark - +#pragma mark Error handling constants + +FOUNDATION_EXPORT NSString *const kFErrorDomain; +FOUNDATION_EXPORT NSUInteger const kFAuthError; +FOUNDATION_EXPORT NSString *const kFErrorWriteCanceled; + +#pragma mark - +#pragma mark Validation Constants + +FOUNDATION_EXPORT NSUInteger const kFirebaseMaxObjectDepth; +FOUNDATION_EXPORT const unsigned int kFirebaseMaxLeafSize; + +#pragma mark - +#pragma mark Transaction Constants + +FOUNDATION_EXPORT NSUInteger const kFTransactionMaxRetries; +FOUNDATION_EXPORT NSString *const kFTransactionTooManyRetries; +FOUNDATION_EXPORT NSString *const kFTransactionNoData; +FOUNDATION_EXPORT NSString *const kFTransactionSet; +FOUNDATION_EXPORT NSString *const kFTransactionDisconnect; + +#endif diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Constants/FConstants.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Constants/FConstants.m new file mode 100644 index 00000000..e492ba1e --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Constants/FConstants.m @@ -0,0 +1,183 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FConstants.h" + +#pragma mark - +#pragma mark Wire Protocol Envelope Constants + +NSString *const kFWPRequestType = @"t"; +NSString *const kFWPRequestTypeData = @"d"; +NSString *const kFWPRequestDataPayload = @"d"; +NSString *const kFWPRequestNumber = @"r"; +NSString *const kFWPRequestPayloadBody = @"b"; +NSString *const kFWPRequestError = @"error"; +NSString *const kFWPRequestAction = @"a"; +NSString *const kFWPResponseForRNData = @"b"; +NSString *const kFWPResponseForActionStatus = @"s"; +NSString *const kFWPResponseForActionStatusOk = @"ok"; +NSString *const kFWPResponseForActionStatusDataStale = @"datastale"; +NSString *const kFWPResponseForActionData = @"d"; +NSString *const kFWPResponseDataWarnings = @"w"; +NSString *const kFWPAsyncServerAction = @"a"; +NSString *const kFWPAsyncServerPayloadBody = @"b"; +NSString *const kFWPAsyncServerDataUpdate = @"d"; +NSString *const kFWPAsyncServerDataMerge = @"m"; +NSString *const kFWPAsyncServerDataRangeMerge = @"rm"; +NSString *const kFWPAsyncServerAuthRevoked = @"ac"; +NSString *const kFWPASyncServerListenCancelled = @"c"; +NSString *const kFWPAsyncServerSecurityDebug = @"sd"; +NSString *const kFWPAsyncServerDataUpdateBodyPath = @"p"; // {“a”: “d”, “b”: {“p”: “/”, “d”: “”}} +NSString *const kFWPAsyncServerDataUpdateBodyData = @"d"; +NSString *const kFWPAsyncServerDataUpdateStartPath = @"s"; +NSString *const kFWPAsyncServerDataUpdateEndPath = @"e"; +NSString *const kFWPAsyncServerDataUpdateRangeMerge = @"m"; +NSString *const kFWPAsyncServerDataUpdateBodyTag = @"t"; +NSString *const kFWPAsyncServerDataQueries = @"q"; + +NSString *const kFWPAsyncServerEnvelopeType = @"t"; +NSString *const kFWPAsyncServerEnvelopeData = @"d"; +NSString *const kFWPAsyncServerControlMessage = @"c"; +NSString *const kFWPAsyncServerControlMessageType = @"t"; +NSString *const kFWPAsyncServerControlMessageData = @"d"; +NSString *const kFWPAsyncServerDataMessage = @"d"; + +NSString *const kFWPAsyncServerHello = @"h"; +NSString *const kFWPAsyncServerHelloTimestamp = @"ts"; +NSString *const kFWPAsyncServerHelloVersion = @"v"; +NSString *const kFWPAsyncServerHelloConnectedHost = @"h"; +NSString *const kFWPAsyncServerHelloSession = @"s"; + +NSString *const kFWPAsyncServerControlMessageShutdown = @"s"; +NSString *const kFWPAsyncServerControlMessageReset = @"r"; + +#pragma mark - +#pragma mark Wire Protocol Payload Constants + +NSString *const kFWPRequestActionPut = @"p"; +NSString *const kFWPRequestActionMerge = @"m"; +NSString *const kFWPRequestActionListen = @"l"; // {"t": "d", "d": {"r": 1, "a": "l", "b": { "p": "/" } } } +NSString *const kFWPRequestActionUnlisten = @"u"; +NSString *const kFWPRequestActionStats = @"s"; +NSString *const kFWPRequestActionTaggedListen = @"q"; +NSString *const kFWPRequestActionTaggedUnlisten = @"n"; +NSString *const kFWPRequestActionDisconnectPut = @"o"; +NSString *const kFWPRequestActionDisconnectMerge = @"om"; +NSString *const kFWPRequestActionDisconnectCancel = @"oc"; +NSString *const kFWPRequestActionAuth = @"auth"; +NSString *const kFWPRequestActionUnauth = @"unauth"; +NSString *const kFWPRequestCredential = @"cred"; +NSString *const kFWPRequestPath = @"p"; +NSString *const kFWPRequestCounters = @"c"; +NSString *const kFWPRequestQueries = @"q"; +NSString *const kFWPRequestTag = @"t"; +NSString *const kFWPRequestData = @"d"; +NSString *const kFWPRequestHash = @"h"; +NSString *const kFWPRequestCompoundHash = @"ch"; +NSString *const kFWPRequestCompoundHashPaths = @"ps"; +NSString *const kFWPRequestCompoundHashHashes = @"hs"; +NSString *const kFWPRequestStatus = @"s"; + +#pragma mark - +#pragma mark Websock Transport Constants + +NSString *const kWireProtocolVersionParam = @"v"; +NSString *const kWebsocketProtocolVersion = @"5"; +NSString *const kWebsocketServerKillPacket = @"kill"; +const int kWebsocketMaxFrameSize = 16384; +NSUInteger const kWebsocketKeepaliveInterval = 45; +NSUInteger const kWebsocketConnectTimeout = 30; + +float const kPersistentConnReconnectMinDelay = 1.0; +float const kPersistentConnReconnectMaxDelay = 30.0; +float const kPersistentConnReconnectMultiplier = 1.3f; +float const kPersistentConnSuccessfulConnectionEstablishedDelay = 30.0; + +#pragma mark - +#pragma mark Query constants + +NSString *const kQueryDefault = @"default"; +NSString *const kQueryDefaultObject = @"{}"; +NSString *const kViewManagerDictConstView = @"view"; +NSString *const kFQPIndexStartValue = @"sp"; +NSString *const kFQPIndexStartName = @"sn"; +NSString *const kFQPIndexEndValue = @"ep"; +NSString *const kFQPIndexEndName = @"en"; +NSString *const kFQPLimit = @"l"; +NSString *const kFQPViewFrom = @"vf"; +NSString *const kFQPViewFromLeft = @"l"; +NSString *const kFQPViewFromRight = @"r"; +NSString *const kFQPIndex = @"i"; + +#pragma mark - +#pragma mark Interrupt Reasons + +NSString *const kFInterruptReasonServerKill = @"server_kill"; +NSString *const kFInterruptReasonWaitingForOpen = @"waiting_for_open"; +NSString *const kFInterruptReasonRepoInterrupt = @"repo_interrupt"; + +#pragma mark - +#pragma mark Payload constants + +NSString *const kPayloadPriority = @".priority"; +NSString *const kPayloadValue = @".value"; +NSString *const kPayloadMetadataPrefix = @"."; + +#pragma mark - +#pragma mark ServerValue constants + +NSString *const kServerValueSubKey = @".sv"; +NSString *const kServerValuePriority = @"timestamp"; + +#pragma mark - +#pragma mark .info/ constants + +NSString *const kDotInfoPrefix = @".info"; +NSString *const kDotInfoConnected = @"connected"; +NSString *const kDotInfoServerTimeOffset = @"serverTimeOffset"; + +#pragma mark - +#pragma mark ObjectiveC to JavaScript type constants + +NSString *const kJavaScriptObject = @"object"; +NSString *const kJavaScriptString = @"string"; +NSString *const kJavaScriptBoolean = @"boolean"; +NSString *const kJavaScriptNumber = @"number"; +NSString *const kJavaScriptNull = @"null"; +NSString *const kJavaScriptTrue = @"true"; +NSString *const kJavaScriptFalse = @"false"; + +#pragma mark - +#pragma mark Error handling constants + +NSString *const kFErrorDomain = @"com.firebase"; +NSUInteger const kFAuthError = 1; +NSString *const kFErrorWriteCanceled = @"write_canceled"; + +#pragma mark - +#pragma mark Validation Constants + +NSUInteger const kFirebaseMaxObjectDepth = 1000; +const unsigned int kFirebaseMaxLeafSize = 1024 * 1024 * 10; // 10 MB + +#pragma mark - +#pragma mark Transaction Constants + +NSUInteger const kFTransactionMaxRetries = 25; +NSString *const kFTransactionTooManyRetries = @"maxretry"; +NSString *const kFTransactionNoData = @"nodata"; +NSString *const kFTransactionSet = @"set"; +NSString *const kFTransactionDisconnect = @"disconnect"; diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FCompoundHash.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FCompoundHash.h new file mode 100644 index 00000000..cd5240e9 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FCompoundHash.h @@ -0,0 +1,40 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import "FNode.h" + + +@interface FCompoundHashBuilder : NSObject + +- (FPath *)currentPath; + +@end + + +typedef BOOL (^FCompoundHashSplitStrategy) (FCompoundHashBuilder *builder); + + +@interface FCompoundHash : NSObject + +@property (nonatomic, strong, readonly) NSArray *posts; +@property (nonatomic, strong, readonly) NSArray *hashes; + ++ (FCompoundHash *)fromNode:(id)node; ++ (FCompoundHash *)fromNode:(id)node splitStrategy:(FCompoundHashSplitStrategy)strategy; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FCompoundHash.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FCompoundHash.m new file mode 100644 index 00000000..b4f72cd2 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FCompoundHash.m @@ -0,0 +1,236 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FCompoundHash.h" +#import "FLeafNode.h" +#import "FStringUtilities.h" +#import "FSnapshotUtilities.h" +#import "FChildrenNode.h" + +@interface FCompoundHashBuilder () + +@property (nonatomic, strong) FCompoundHashSplitStrategy splitStrategy; + +@property (nonatomic, strong) NSMutableArray *currentPaths; +@property (nonatomic, strong) NSMutableArray *currentHashes; + +@end + +@implementation FCompoundHashBuilder { + + // NOTE: We use the existence of this to know if we've started building a range (i.e. encountered a leaf node). + NSMutableString *optHashValueBuilder; + + // The current path as a stack. This is used in combination with currentPathDepth to simultaneously store the + // last leaf node path. The depth is changed when descending and ascending, at the same time the current key + // is set for the current depth. Because the keys are left unchanged for ascending the path will also contain + // the path of the last visited leaf node (using lastLeafDepth elements) + NSMutableArray *currentPath; + NSInteger lastLeafDepth; + NSInteger currentPathDepth; + + BOOL needsComma; +} + +- (instancetype)initWithSplitStrategy:(FCompoundHashSplitStrategy)strategy { + self = [super init]; + if (self != nil) { + self->_splitStrategy = strategy; + self->optHashValueBuilder = nil; + self->currentPath = [NSMutableArray array]; + self->lastLeafDepth = -1; + self->currentPathDepth = 0; + self->needsComma = YES; + self->_currentPaths = [NSMutableArray array]; + self->_currentHashes = [NSMutableArray array]; + } + return self; +} + +- (BOOL)isBuildingRange { + return self->optHashValueBuilder != nil; +} + +- (NSUInteger)currentHashLength { + return self->optHashValueBuilder.length; +} + +- (FPath *)currentPath { + return [self currentPathWithDepth:self->currentPathDepth]; +} + +- (FPath *)currentPathWithDepth:(NSInteger)depth { + NSArray *pieces = [self->currentPath subarrayWithRange:NSMakeRange(0, depth)]; + return [[FPath alloc] initWithPieces:pieces andPieceNum:0]; +} + +- (void)enumerateCurrentPathToDepth:(NSInteger)depth withBlock:(void (^) (NSString *key))block { + for (NSInteger i = 0; i < depth; i++) { + block(self->currentPath[i]); + } +} + +- (void)appendKey:(NSString *)key toString:(NSMutableString *)string { + [FSnapshotUtilities appendHashV2RepresentationForString:key toString:string]; +} + +- (void)ensureRange { + if (![self isBuildingRange]) { + optHashValueBuilder = [NSMutableString string]; + [optHashValueBuilder appendString:@"("]; + [self enumerateCurrentPathToDepth:self->currentPathDepth withBlock:^(NSString *key) { + [self appendKey:key toString:self->optHashValueBuilder]; + [self->optHashValueBuilder appendString:@":("]; + }]; + self->needsComma = NO; + } +} + +- (void)processLeaf:(FLeafNode *)leafNode { + [self ensureRange]; + + self->lastLeafDepth = self->currentPathDepth; + [FSnapshotUtilities appendHashRepresentationForLeafNode:leafNode + toString:self->optHashValueBuilder + hashVersion:FDataHashVersionV2]; + self->needsComma = YES; + if (self.splitStrategy(self)) { + [self endRange]; + } +} + +- (void)startChild:(NSString *)key { + [self ensureRange]; + + if (self->needsComma) { + [self->optHashValueBuilder appendString:@","]; + } + [self appendKey:key toString:self->optHashValueBuilder]; + [self->optHashValueBuilder appendString:@":("]; + if (self->currentPathDepth == currentPath.count) { + [self->currentPath addObject:key]; + } else { + self->currentPath[self->currentPathDepth] = key; + } + self->currentPathDepth++; + self->needsComma = NO; +} + +- (void)endChild { + self->currentPathDepth--; + if ([self isBuildingRange]) { + [self->optHashValueBuilder appendString:@")"]; + } + self->needsComma = YES; +} + +- (void)finishHashing { + NSAssert(self->currentPathDepth == 0, @"Can't finish hashing in the middle of processing a child"); + if ([self isBuildingRange] ) { + [self endRange]; + } + + // Always close with the empty hash for the remaining range to allow simple appending + [self.currentHashes addObject:@""]; +} + +- (void)endRange { + NSAssert([self isBuildingRange], @"Can't end range without starting a range!"); + // Add closing parenthesis for current depth + for (NSUInteger i = 0; i < currentPathDepth; i++) { + [self->optHashValueBuilder appendString:@")"]; + } + [self->optHashValueBuilder appendString:@")"]; + + FPath *lastLeafPath = [self currentPathWithDepth:self->lastLeafDepth]; + NSString *hash = [FStringUtilities base64EncodedSha1:self->optHashValueBuilder]; + [self.currentHashes addObject:hash]; + [self.currentPaths addObject:lastLeafPath]; + + self->optHashValueBuilder = nil; +} + +@end + + +@interface FCompoundHash () + +@property (nonatomic, strong, readwrite) NSArray *posts; +@property (nonatomic, strong, readwrite) NSArray *hashes; + +@end + +@implementation FCompoundHash + +- (id)initWithPosts:(NSArray *)posts hashes:(NSArray *)hashes { + self = [super init]; + if (self != nil) { + if (posts.count != hashes.count - 1) { + [NSException raise:NSInvalidArgumentException format:@"Number of posts need to be n-1 for n hashes in FCompoundHash"]; + } + self.posts = posts; + self.hashes = hashes; + } + return self; +} + ++ (FCompoundHashSplitStrategy)simpleSizeSplitStrategyForNode:(id)node { + NSUInteger estimatedSize = [FSnapshotUtilities estimateSerializedNodeSize:node]; + + // Splits for + // 1k -> 512 (2 parts) + // 5k -> 715 (7 parts) + // 100k -> 3.2k (32 parts) + // 500k -> 7k (71 parts) + // 5M -> 23k (228 parts) + NSUInteger splitThreshold = MAX(512, (NSUInteger)sqrt(estimatedSize * 100)); + + return ^BOOL(FCompoundHashBuilder *builder) { + // Never split on priorities + return [builder currentHashLength] > splitThreshold && ![[[builder currentPath] getBack] isEqualToString:@".priority"]; + }; +} + ++ (FCompoundHash *)fromNode:(id)node { + return [FCompoundHash fromNode:node splitStrategy:[FCompoundHash simpleSizeSplitStrategyForNode:node]]; +} + ++ (FCompoundHash *)fromNode:(id)node splitStrategy:(FCompoundHashSplitStrategy)strategy { + if ([node isEmpty]) { + return [[FCompoundHash alloc] initWithPosts:@[] hashes:@[@""]]; + } else { + FCompoundHashBuilder *builder = [[FCompoundHashBuilder alloc] initWithSplitStrategy:strategy]; + [FCompoundHash processNode:node builder:builder]; + [builder finishHashing]; + return [[FCompoundHash alloc] initWithPosts:builder.currentPaths hashes:builder.currentHashes]; + } +} + ++ (void)processNode:(id)node builder:(FCompoundHashBuilder *)builder { + if ([node isLeafNode]) { + [builder processLeaf:node]; + } else { + NSAssert(![node isEmpty], @"Can't calculate hash on empty node!"); + FChildrenNode *childrenNode = (FChildrenNode *)node; + [childrenNode enumerateChildrenAndPriorityUsingBlock:^(NSString *key, id node, BOOL *stop) { + [builder startChild:key]; + [self processNode:node builder:builder]; + [builder endChild]; + }]; + } +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FListenProvider.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FListenProvider.h new file mode 100644 index 00000000..7a41754c --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FListenProvider.h @@ -0,0 +1,33 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FTypedefs_Private.h" + +@class FQuerySpec; +@protocol FSyncTreeHash; + +typedef NSArray* (^fbt_startListeningBlock)(FQuerySpec *query, + NSNumber *tagId, + id hash, + fbt_nsarray_nsstring onComplete); +typedef void (^fbt_stopListeningBlock)(FQuerySpec *query, NSNumber *tagId); + +@interface FListenProvider : NSObject + +@property (nonatomic, copy) fbt_startListeningBlock startListening; +@property (nonatomic, copy) fbt_stopListeningBlock stopListening; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FListenProvider.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FListenProvider.m new file mode 100644 index 00000000..7a49609c --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FListenProvider.m @@ -0,0 +1,26 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FListenProvider.h" +#import "FIRDatabaseQuery.h" + + +@implementation FListenProvider + +@synthesize startListening; +@synthesize stopListening; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FPersistentConnection.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FPersistentConnection.h new file mode 100644 index 00000000..412c8747 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FPersistentConnection.h @@ -0,0 +1,78 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FConnection.h" +#import "FRepoInfo.h" +#import "FTypedefs.h" +#import "FTypedefs_Private.h" + +@protocol FPersistentConnectionDelegate; +@protocol FSyncTreeHash; +@class FQuerySpec; +@class FIRDatabaseConfig; + +@interface FPersistentConnection : NSObject + +@property (nonatomic, weak) id delegate; +@property (nonatomic) BOOL pauseWrites; + +- (id)initWithRepoInfo:(FRepoInfo *)repoInfo + dispatchQueue:(dispatch_queue_t)queue + config:(FIRDatabaseConfig *)config; + +- (void)open; + +- (void) putData:(id)data forPath:(NSString *)pathString withHash:(NSString *)hash withCallback:(fbt_void_nsstring_nsstring)onComplete; +- (void) mergeData:(id)data forPath:(NSString *)pathString withCallback:(fbt_void_nsstring_nsstring)onComplete; + +- (void) listen:(FQuerySpec *)query + tagId:(NSNumber *)tagId + hash:(id)hash + onComplete:(fbt_void_nsstring)onComplete; + +- (void) unlisten:(FQuerySpec *)query tagId:(NSNumber *)tagId; +- (void) refreshAuthToken:(NSString *)token; +- (void) onDisconnectPutData:(id)data forPath:(FPath *)path withCallback:(fbt_void_nsstring_nsstring)callback; +- (void) onDisconnectMergeData:(id)data forPath:(FPath *)path withCallback:(fbt_void_nsstring_nsstring)callback; +- (void) onDisconnectCancelPath:(FPath *)path withCallback:(fbt_void_nsstring_nsstring)callback; +- (void) ackPuts; +- (void) purgeOutstandingWrites; + +- (void) interruptForReason:(NSString *)reason; +- (void) resumeForReason:(NSString *)reason; +- (BOOL) isInterruptedForReason:(NSString *)reason; + +// FConnection delegate methods +- (void)onReady:(FConnection *)fconnection atTime:(NSNumber *)timestamp sessionID:(NSString *)sessionID; +- (void)onDataMessage:(FConnection *)fconnection withMessage:(NSDictionary *)message; +- (void)onDisconnect:(FConnection *)fconnection withReason:(FDisconnectReason)reason; +- (void)onKill:(FConnection *)fconnection withReason:(NSString *)reason; + +// Testing methods +- (NSDictionary *) dumpListens; + +@end + +@protocol FPersistentConnectionDelegate + +- (void)onDataUpdate:(FPersistentConnection *)fpconnection forPath:(NSString *)pathString message:(id)message isMerge:(BOOL)isMerge tagId:(NSNumber *)tagId; +- (void)onRangeMerge:(NSArray *)ranges forPath:(NSString *)path tagId:(NSNumber *)tag; +- (void)onConnect:(FPersistentConnection *)fpconnection; +- (void)onDisconnect:(FPersistentConnection *)fpconnection; +- (void)onServerInfoUpdate:(FPersistentConnection *)fpconnection updates:(NSDictionary *)updates; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FPersistentConnection.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FPersistentConnection.m new file mode 100644 index 00000000..f341bb10 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FPersistentConnection.m @@ -0,0 +1,952 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#import + +#import +#import +#import +#import +#import "FIRDatabaseReference.h" +#import "FPersistentConnection.h" +#import "FConstants.h" +#import "FAtomicNumber.h" +#import "FQueryParams.h" +#import "FTupleOnDisconnect.h" +#import "FTupleCallbackStatus.h" +#import "FQuerySpec.h" +#import "FIndex.h" +#import "FIRDatabaseConfig.h" +#import "FIRDatabaseConfig_Private.h" +#import "FSnapshotUtilities.h" +#import "FRangeMerge.h" +#import "FCompoundHash.h" +#import "FSyncTree.h" +#import "FIRRetryHelper.h" +#import "FAuthTokenProvider.h" +#import "FUtilities.h" + +@interface FOutstandingQuery : NSObject + +@property (nonatomic, strong) FQuerySpec* query; +@property (nonatomic, strong) NSNumber *tagId; +@property (nonatomic, strong) id syncTreeHash; +@property (nonatomic, copy) fbt_void_nsstring onComplete; + +@end + +@implementation FOutstandingQuery + +@end + + +@interface FOutstandingPut : NSObject + +@property (nonatomic, strong) NSString *action; +@property (nonatomic, strong) NSDictionary *request; +@property (nonatomic, copy) fbt_void_nsstring_nsstring onCompleteBlock; +@property (nonatomic) BOOL sent; + +@end + +@implementation FOutstandingPut + +@end + + +typedef enum { + ConnectionStateDisconnected, + ConnectionStateGettingToken, + ConnectionStateConnecting, + ConnectionStateAuthenticating, + ConnectionStateConnected +} ConnectionState; + +@interface FPersistentConnection () { + ConnectionState connectionState; + BOOL firstConnection; + NSTimeInterval reconnectDelay; + NSTimeInterval lastConnectionAttemptTime; + NSTimeInterval lastConnectionEstablishedTime; + SCNetworkReachabilityRef reachability; +} + +- (int) getNextRequestNumber; +- (void) onDataPushWithAction:(NSString *)action andBody:(NSDictionary *)body; +- (void) handleTimestamp:(NSNumber *)timestamp; +- (void) sendOnDisconnectAction:(NSString *)action forPath:(NSString *)pathString withData:(id)data andCallback:(fbt_void_nsstring_nsstring)callback; + +@property (nonatomic, strong) FConnection* realtime; +@property (nonatomic, strong) NSMutableDictionary* listens; +@property (nonatomic, strong) NSMutableDictionary* outstandingPuts; +@property (nonatomic, strong) NSMutableArray* onDisconnectQueue; +@property (nonatomic, strong) FRepoInfo* repoInfo; +@property (nonatomic, strong) FAtomicNumber* putCounter; +@property (nonatomic, strong) FAtomicNumber* requestNumber; +@property (nonatomic, strong) NSMutableDictionary* requestCBHash; +@property (nonatomic, strong) FIRDatabaseConfig *config; +@property (nonatomic) NSUInteger unackedListensCount; +@property (nonatomic, strong) NSMutableArray *putsToAck; +@property (nonatomic, strong) dispatch_queue_t dispatchQueue; +@property (nonatomic, strong) NSString* lastSessionID; +@property (nonatomic, strong) NSMutableSet *interruptReasons; +@property (nonatomic, strong) FIRRetryHelper *retryHelper; +@property (nonatomic, strong) id authTokenProvider; +@property (nonatomic, strong) NSString *authToken; +@property (nonatomic) BOOL forceAuthTokenRefresh; +@property (nonatomic) NSUInteger currentFetchTokenAttempt; + +@end + + +@implementation FPersistentConnection + +- (id)initWithRepoInfo:(FRepoInfo *)repoInfo dispatchQueue:(dispatch_queue_t)dispatchQueue config:(FIRDatabaseConfig *)config { + self = [super init]; + if (self) { + self->_config = config; + self->_repoInfo = repoInfo; + self->_dispatchQueue = dispatchQueue; + self->_authTokenProvider = config.authTokenProvider; + NSAssert(self->_authTokenProvider != nil, @"Expected auth token provider"); + self.interruptReasons = [NSMutableSet set]; + + self.listens = [[NSMutableDictionary alloc] init]; + self.outstandingPuts = [[NSMutableDictionary alloc] init]; + self.onDisconnectQueue = [[NSMutableArray alloc] init]; + self.putCounter = [[FAtomicNumber alloc] init]; + self.requestNumber = [[FAtomicNumber alloc] init]; + self.requestCBHash = [[NSMutableDictionary alloc] init]; + self.unackedListensCount = 0; + self.putsToAck = [NSMutableArray array]; + connectionState = ConnectionStateDisconnected; + firstConnection = YES; + reconnectDelay = kPersistentConnReconnectMinDelay; + + self->_retryHelper = [[FIRRetryHelper alloc] initWithDispatchQueue:dispatchQueue + minRetryDelayAfterFailure:kPersistentConnReconnectMinDelay + maxRetryDelay:kPersistentConnReconnectMaxDelay + retryExponent:kPersistentConnReconnectMultiplier + jitterFactor:0.7]; + + [self setupNotifications]; + // Make sure we don't actually connect until open is called + [self interruptForReason:kFInterruptReasonWaitingForOpen]; + } + // nb: The reason establishConnection isn't called here like the JS version is because + // callers need to set the delegate first. The ctor can be modified to accept the delegate + // but that deviates from normal ios conventions. After the delegate has been set, the caller + // is responsible for calling establishConnection: + return self; +} + +- (void) dealloc { + if (reachability) { + // Unschedule the notifications + SCNetworkReachabilitySetDispatchQueue(reachability, NULL); + CFRelease(reachability); + } +} + +#pragma mark - +#pragma mark Public methods + +- (void) open { + [self resumeForReason:kFInterruptReasonWaitingForOpen]; +} + +/** +* Note that the listens dictionary has a type of Map[String (pathString), Map[FQueryParams, FOutstandingQuery]] +* +* This means, for each path we care about, there are sets of queryParams that correspond to an FOutstandingQuery object. +* There can be multiple sets at a path since we overlap listens for a short time while adding or removing a query from a +* location in the tree. +*/ +- (void) listen:(FQuerySpec *)query + tagId:(NSNumber *)tagId + hash:(id)hash + onComplete:(fbt_void_nsstring)onComplete { + FFLog(@"I-RDB034001", @"Listen called for %@", query); + + NSAssert(self.listens[query] == nil, @"listen() called twice for the same query"); + NSAssert(query.isDefault || !query.loadsAllData, @"listen called for non-default but complete query"); + FOutstandingQuery* outstanding = [[FOutstandingQuery alloc] init]; + outstanding.query = query; + outstanding.tagId = tagId; + outstanding.syncTreeHash = hash; + outstanding.onComplete = onComplete; + [self.listens setObject:outstanding forKey:query]; + if ([self connected]) { + [self sendListen:outstanding]; + } +} + +- (void) putData:(id)data forPath:(NSString *)pathString withHash:(NSString *)hash withCallback:(fbt_void_nsstring_nsstring)onComplete { + [self putInternal:data forAction:kFWPRequestActionPut forPath:pathString withHash:hash withCallback:onComplete]; +} + +- (void) mergeData:(id)data forPath:(NSString *)pathString withCallback:(fbt_void_nsstring_nsstring)onComplete { + [self putInternal:data forAction:kFWPRequestActionMerge forPath:pathString withHash:nil withCallback:onComplete]; +} + +- (void) onDisconnectPutData:(id)data forPath:(FPath *)path withCallback:(fbt_void_nsstring_nsstring)callback { + if ([self canSendWrites]) { + [self sendOnDisconnectAction:kFWPRequestActionDisconnectPut forPath:[path description] withData:data andCallback:callback]; + } else { + FTupleOnDisconnect* tuple = [[FTupleOnDisconnect alloc] init]; + tuple.pathString = [path description]; + tuple.action = kFWPRequestActionDisconnectPut; + tuple.data = data; + tuple.onComplete = callback; + [self.onDisconnectQueue addObject:tuple]; + } +} + +- (void) onDisconnectMergeData:(id)data forPath:(FPath *)path withCallback:(fbt_void_nsstring_nsstring)callback { + if ([self canSendWrites]) { + [self sendOnDisconnectAction:kFWPRequestActionDisconnectMerge forPath:[path description] withData:data andCallback:callback]; + } else { + FTupleOnDisconnect* tuple = [[FTupleOnDisconnect alloc] init]; + tuple.pathString = [path description]; + tuple.action = kFWPRequestActionDisconnectMerge; + tuple.data = data; + tuple.onComplete = callback; + [self.onDisconnectQueue addObject:tuple]; + } +} + +- (void) onDisconnectCancelPath:(FPath *)path withCallback:(fbt_void_nsstring_nsstring)callback { + if ([self canSendWrites]) { + [self sendOnDisconnectAction:kFWPRequestActionDisconnectCancel forPath:[path description] withData:[NSNull null] andCallback:callback]; + } else { + FTupleOnDisconnect* tuple = [[FTupleOnDisconnect alloc] init]; + tuple.pathString = [path description]; + tuple.action = kFWPRequestActionDisconnectCancel; + tuple.data = [NSNull null]; + tuple.onComplete = callback; + [self.onDisconnectQueue addObject:tuple]; + } +} + +- (void) unlisten:(FQuerySpec *)query tagId:(NSNumber *)tagId { + FPath *path = query.path; + FFLog(@"I-RDB034002", @"Unlistening for %@", query); + + NSArray *outstanding = [self removeListen:query]; + if (outstanding.count > 0 && [self connected]) { + [self sendUnlisten:path queryParams:query.params tagId:tagId]; + } +} + +- (void) refreshAuthToken:(NSString *)token { + self.authToken = token; + if ([self connected]) { + if (token != nil) { + [self sendAuthAndRestoreStateAfterComplete:NO]; + } else { + [self sendUnauth]; + } + } +} + +#pragma mark - +#pragma mark Connection status + +- (BOOL)connected { + return self->connectionState == ConnectionStateAuthenticating || self->connectionState == ConnectionStateConnected; +} + +- (BOOL)canSendWrites { + return self->connectionState == ConnectionStateConnected; +} + +#pragma mark - +#pragma mark FConnection delegate methods + +- (void)onReady:(FConnection *)fconnection atTime:(NSNumber *)timestamp sessionID:(NSString *)sessionID { + FFLog(@"I-RDB034003", @"On ready"); + lastConnectionEstablishedTime = [[NSDate date] timeIntervalSince1970]; + [self handleTimestamp:timestamp]; + + if (firstConnection) { + [self sendConnectStats]; + } + + [self restoreAuth]; + firstConnection = NO; + self.lastSessionID = sessionID; + dispatch_async(self.dispatchQueue, ^{ + [self.delegate onConnect:self]; + }); +} + +- (void)onDataMessage:(FConnection *)fconnection withMessage:(NSDictionary *)message { + if (message[kFWPRequestNumber] != nil) { + // this is a response to a request we sent + NSNumber* rn = [NSNumber numberWithInt:[[message objectForKey:kFWPRequestNumber] intValue]]; + if ([self.requestCBHash objectForKey:rn]) { + void (^callback)(NSDictionary*) = [self.requestCBHash objectForKey:rn]; + [self.requestCBHash removeObjectForKey:rn]; + + if (callback) { + //dispatch_async(self.dispatchQueue, ^{ + callback([message objectForKey:kFWPResponseForRNData]); + //}); + } + } + } else if (message[kFWPRequestError] != nil) { + NSString* error = [message objectForKey:kFWPRequestError]; + @throw [[NSException alloc] initWithName:@"FirebaseDatabaseServerError" reason:error userInfo:nil]; + } else if (message[kFWPAsyncServerAction] != nil) { + // this is a server push of some sort + NSString* action = [message objectForKey:kFWPAsyncServerAction]; + NSDictionary* body = [message objectForKey:kFWPAsyncServerPayloadBody]; + [self onDataPushWithAction:action andBody:body]; + } +} + +- (void)onDisconnect:(FConnection *)fconnection withReason:(FDisconnectReason)reason { + FFLog(@"I-RDB034004", @"Got on disconnect due to %s", (reason == DISCONNECT_REASON_SERVER_RESET) ? "server_reset" : "other"); + connectionState = ConnectionStateDisconnected; + // Drop the realtime connection + self.realtime = nil; + [self cancelSentTransactions]; + [self.requestCBHash removeAllObjects]; + self.unackedListensCount = 0; + if ([self shouldReconnect]) { + NSTimeInterval timeSinceLastConnectSucceeded = [[NSDate date] timeIntervalSince1970] - lastConnectionEstablishedTime; + BOOL lastConnectionWasSuccessful; + if (lastConnectionEstablishedTime > 0) { + lastConnectionWasSuccessful = timeSinceLastConnectSucceeded > kPersistentConnSuccessfulConnectionEstablishedDelay; + } else { + lastConnectionWasSuccessful = NO; + } + + if (reason == DISCONNECT_REASON_SERVER_RESET || lastConnectionWasSuccessful) { + [self.retryHelper signalSuccess]; + } + [self tryScheduleReconnect]; + } + lastConnectionEstablishedTime = 0; + [self.delegate onDisconnect:self]; +} + +- (void)onKill:(FConnection *)fconnection withReason:(NSString *)reason { + FFWarn(@"I-RDB034005", @"Firebase Database connection was forcefully killed by the server. Will not attempt reconnect. Reason: %@", reason); + [self interruptForReason:kFInterruptReasonServerKill]; +} + +#pragma mark - +#pragma mark Connection handling methods + +- (void) interruptForReason:(NSString *)reason { + FFLog(@"I-RDB034006", @"Connection interrupted for: %@", reason); + + [self.interruptReasons addObject:reason]; + if (self.realtime) { + // Will call onDisconnect and set the connection state to Disconnected + [self.realtime close]; + self.realtime = nil; + } else { + [self.retryHelper cancel]; + self->connectionState = ConnectionStateDisconnected; + } + // Reset timeouts + [self.retryHelper signalSuccess]; +} + +- (void) resumeForReason:(NSString *)reason { + FFLog(@"I-RDB034007", @"Connection no longer interrupted for: %@", reason); + [self.interruptReasons removeObject:reason]; + + if ([self shouldReconnect] && connectionState == ConnectionStateDisconnected) { + [self tryScheduleReconnect]; + } +} + +- (BOOL) shouldReconnect { + return self.interruptReasons.count == 0; +} + +- (BOOL) isInterruptedForReason:(NSString *)reason { + return [self.interruptReasons containsObject:reason]; +} + +#pragma mark - +#pragma mark Private methods + +- (void) tryScheduleReconnect { + if ([self shouldReconnect]) { + NSAssert(self->connectionState == ConnectionStateDisconnected, + @"Not in disconnected state: %d", self->connectionState); + BOOL forceRefresh = self.forceAuthTokenRefresh; + self.forceAuthTokenRefresh = NO; + FFLog(@"I-RDB034008", @"Scheduling connection attempt"); + [self.retryHelper retry:^{ + FFLog(@"I-RDB034009", @"Trying to fetch auth token"); + NSAssert(self->connectionState == ConnectionStateDisconnected, + @"Not in disconnected state: %d", self->connectionState); + self->connectionState = ConnectionStateGettingToken; + self.currentFetchTokenAttempt++; + NSUInteger thisFetchTokenAttempt = self.currentFetchTokenAttempt; + [self.authTokenProvider fetchTokenForcingRefresh:forceRefresh withCallback:^(NSString *token, NSError *error) { + if (thisFetchTokenAttempt == self.currentFetchTokenAttempt) { + if (error != nil) { + self->connectionState = ConnectionStateDisconnected; + FFLog(@"I-RDB034010", @"Error fetching token: %@", error); + [self tryScheduleReconnect]; + } else { + // Someone could have interrupted us while fetching the token, + // marking the connection as Disconnected + if (self->connectionState == ConnectionStateGettingToken) { + FFLog(@"I-RDB034011", @"Successfully fetched token, opening connection"); + [self openNetworkConnectionWithToken:token]; + } else { + NSAssert(self->connectionState == ConnectionStateDisconnected, + @"Expected connection state disconnected, but got %d", self->connectionState); + FFLog(@"I-RDB034012", @"Not opening connection after token refresh, because connection was set to disconnected."); + } + } + } else { + FFLog(@"I-RDB034013", @"Ignoring fetch token result, because this was not the latest attempt."); + } + }]; + }]; + + } +} + +- (void) openNetworkConnectionWithToken:(NSString *)token { + NSAssert(self->connectionState == ConnectionStateGettingToken, + @"Trying to open network connection while in wrong state: %d", self->connectionState); + self.authToken = token; + self->connectionState = ConnectionStateConnecting; + self.realtime = [[FConnection alloc] initWith:self.repoInfo + andDispatchQueue:self.dispatchQueue + lastSessionID:self.lastSessionID]; + self.realtime.delegate = self; + [self.realtime open]; +} + +static void reachabilityCallback(SCNetworkReachabilityRef ref, SCNetworkReachabilityFlags flags, void* info) { + if (flags & kSCNetworkReachabilityFlagsReachable) { + FFLog(@"I-RDB034014", @"Network became reachable. Trigger a connection attempt"); + FPersistentConnection* self = (__bridge FPersistentConnection *)info; + // Reset reconnect delay + [self.retryHelper signalSuccess]; + if (self->connectionState == ConnectionStateDisconnected) { + [self tryScheduleReconnect]; + } + } else { + FFLog(@"I-RDB034015", @"Network is not reachable"); + } +} + +- (void) enteringForeground { + dispatch_async(self.dispatchQueue, ^{ + // Reset reconnect delay + [self.retryHelper signalSuccess]; + if (self->connectionState == ConnectionStateDisconnected) { + [self tryScheduleReconnect]; + } + }); +} + +- (void) setupNotifications { + + NSString * const* foregroundConstant = (NSString * const *) dlsym(RTLD_DEFAULT, "UIApplicationWillEnterForegroundNotification"); + if (foregroundConstant) { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(enteringForeground) + name:*foregroundConstant + object:nil]; + } + // An empty address is interpreted a generic internet access + struct sockaddr_in zeroAddress; + bzero(&zeroAddress, sizeof(zeroAddress)); + zeroAddress.sin_len = sizeof(zeroAddress); + zeroAddress.sin_family = AF_INET; + reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)&zeroAddress); + SCNetworkReachabilityContext ctx = {0, (__bridge void *)(self), NULL, NULL, NULL}; + if (SCNetworkReachabilitySetCallback(reachability, reachabilityCallback, &ctx)) { + SCNetworkReachabilitySetDispatchQueue(reachability, self.dispatchQueue); + } else { + FFLog(@"I-RDB034016", @"Failed to set up network reachability monitoring"); + CFRelease(reachability); + reachability = NULL; + } +} + +- (void) sendAuthAndRestoreStateAfterComplete:(BOOL)restoreStateAfterComplete { + NSAssert([self connected], @"Must be connected to send auth"); + NSAssert(self.authToken != nil, @"Can't send auth if there is no credential"); + + NSDictionary* requestData = @{kFWPRequestCredential: self.authToken}; + [self sendAction:kFWPRequestActionAuth body:requestData sensitive:YES callback:^(NSDictionary *data) { + self->connectionState = ConnectionStateConnected; + NSString* status = [data objectForKey:kFWPResponseForActionStatus]; + id responseData = [data objectForKey:kFWPResponseForActionData]; + if (responseData == nil) { + responseData = @"error"; + } + + BOOL statusOk = [status isEqualToString:kFWPResponseForActionStatusOk]; + if (statusOk) { + if (restoreStateAfterComplete) { + [self restoreState]; + } + } else { + self.authToken = nil; + self.forceAuthTokenRefresh = YES; + if ([status isEqualToString:@"expired_token"]) { + FFLog(@"I-RDB034017", @"Authentication failed: %@ (%@)", status, responseData); + } else { + FFWarn(@"I-RDB034018", @"Authentication failed: %@ (%@)", status, responseData); + } + [self.realtime close]; + } + }]; +} + +- (void) sendUnauth { + [self sendAction:kFWPRequestActionUnauth body:@{} sensitive:NO callback:nil]; +} + +- (void) onAuthRevokedWithStatus:(NSString *)status andReason:(NSString *)reason { + // This might be for an earlier token than we just recently sent. But since we need to close the connection anyways, + // we can set it to null here and we will refresh the token later on reconnect + if ([status isEqualToString:@"expired_token"]) { + FFLog(@"I-RDB034019", @"Auth token revoked: %@ (%@)", status, reason); + } else { + FFWarn(@"I-RDB034020", @"Auth token revoked: %@ (%@)", status, reason); + } + self.authToken = nil; + self.forceAuthTokenRefresh = YES; + // Try reconnecting on auth revocation + [self.realtime close]; +} + +- (void) onListenRevoked:(FPath *)path { + NSArray *queries = [self removeAllListensAtPath:path]; + for (FOutstandingQuery* query in queries) { + query.onComplete(@"permission_denied"); + } +} + +- (void) sendOnDisconnectAction:(NSString *)action forPath:(NSString *)pathString withData:(id)data andCallback:(fbt_void_nsstring_nsstring)callback { + + NSDictionary* request = @{kFWPRequestPath: pathString, kFWPRequestData: data}; + FFLog(@"I-RDB034021", @"onDisconnect %@: %@", action, request); + + [self sendAction:action + body:request + sensitive:NO + callback:^(NSDictionary *data) { + NSString* status = [data objectForKey:kFWPResponseForActionStatus]; + NSString* errorReason = [data objectForKey:kFWPResponseForActionData]; + callback(status, errorReason); + }]; +} + +- (void) sendPut:(NSNumber *) index { + NSAssert([self canSendWrites], @"sendPut called when not able to send writes"); + FOutstandingPut* put = self.outstandingPuts[index]; + assert(put != nil); + fbt_void_nsstring_nsstring onComplete = put.onCompleteBlock; + + // Do not async this block; copying the block insinde sendAction: doesn't happen in time (or something) so coredumps + put.sent = YES; + [self sendAction:put.action + body:put.request + sensitive:NO + callback:^(NSDictionary* data) { + + FOutstandingPut *currentPut = self.outstandingPuts[index]; + if (currentPut == put) { + [self.outstandingPuts removeObjectForKey:index]; + + if (onComplete != nil) { + NSString *status = [data objectForKey:kFWPResponseForActionStatus]; + NSString *errorReason = [data objectForKey:kFWPResponseForActionData]; + if (self.unackedListensCount == 0) { + onComplete(status, errorReason); + } else { + FTupleCallbackStatus *putToAck = [[FTupleCallbackStatus alloc] init]; + putToAck.block = onComplete; + putToAck.status = status; + putToAck.errorReason = errorReason; + [self.putsToAck addObject:putToAck]; + } + } + } else { + FFLog(@"I-RDB034022", @"Ignoring on complete for put %@ because it was already removed", index); + } + }]; +} + +- (void) sendUnlisten:(FPath *)path queryParams:(FQueryParams *)queryParams tagId:(NSNumber *)tagId { + FFLog(@"I-RDB034023", @"Unlisten on %@ for %@", path, queryParams); + + NSMutableDictionary* request = [NSMutableDictionary dictionaryWithObjectsAndKeys:[path toString], kFWPRequestPath, nil]; + if (tagId != nil) { + [request setObject:queryParams.wireProtocolParams forKey:kFWPRequestQueries]; + [request setObject:tagId forKey:kFWPRequestTag]; + } + + [self sendAction:kFWPRequestActionTaggedUnlisten + body:request + sensitive:NO + callback:nil]; +} + +- (void) putInternal:(id)data forAction:(NSString *)action forPath:(NSString *)pathString withHash:(NSString *)hash withCallback:(fbt_void_nsstring_nsstring)onComplete { + + NSMutableDictionary *request = [NSMutableDictionary dictionaryWithObjectsAndKeys: + pathString, kFWPRequestPath, + data, kFWPRequestData, nil]; + if(hash) { + [request setObject:hash forKey:kFWPRequestHash]; + } + + FOutstandingPut *put = [[FOutstandingPut alloc] init]; + put.action = action; + put.request = request; + put.onCompleteBlock = onComplete; + put.sent = NO; + + NSNumber* index = [self.putCounter getAndIncrement]; + self.outstandingPuts[index] = put; + + if ([self canSendWrites]) { + FFLog(@"I-RDB034024", @"Was connected, and added as index: %@", index); + [self sendPut:index]; + } + else { + FFLog(@"I-RDB034025", @"Wasn't connected or writes paused, so added to outstanding puts only. Path: %@", pathString); + } +} + +- (void) sendListen:(FOutstandingQuery *)listenSpec { + FQuerySpec *query = listenSpec.query; + FFLog(@"I-RDB034026", @"Listen for %@", query); + NSMutableDictionary *request = [NSMutableDictionary dictionaryWithObject:[query.path toString] forKey:kFWPRequestPath]; + + // Only bother to send query if it's non-default + if (listenSpec.tagId != nil) { + [request setObject:[query.params wireProtocolParams] forKey:kFWPRequestQueries]; + [request setObject:listenSpec.tagId forKey:kFWPRequestTag]; + } + + [request setObject:[listenSpec.syncTreeHash simpleHash] forKey:kFWPRequestHash]; + if ([listenSpec.syncTreeHash includeCompoundHash]) { + FCompoundHash *compoundHash = [listenSpec.syncTreeHash compoundHash]; + NSMutableArray *posts = [NSMutableArray array]; + for (FPath *path in compoundHash.posts) { + [posts addObject:path.wireFormat]; + } + request[kFWPRequestCompoundHash] = @{ kFWPRequestCompoundHashHashes: compoundHash.hashes, + kFWPRequestCompoundHashPaths: posts }; + } + + fbt_void_nsdictionary onResponse = ^(NSDictionary *response) { + FFLog(@"I-RDB034027", @"Listen response %@", response); + // warn in any case, even if the listener was removed + [self warnOnListenWarningsForQuery:query payload:response[kFWPResponseForActionData]]; + + FOutstandingQuery *currentListenSpec = self.listens[query]; + + // only trigger actions if the listen hasn't been removed (and maybe readded) + if (currentListenSpec == listenSpec) { + NSString *status = [response objectForKey:kFWPRequestStatus]; + if (![status isEqualToString:@"ok"]) { + [self removeListen:query]; + } + + if (listenSpec.onComplete) { + listenSpec.onComplete(status); + } + } + + self.unackedListensCount--; + NSAssert(self.unackedListensCount >= 0, @"unackedListensCount decremented to be negative."); + if (self.unackedListensCount == 0) { + [self ackPuts]; + } + }; + + [self sendAction:kFWPRequestActionTaggedListen + body:request + sensitive:NO + callback:onResponse]; + + self.unackedListensCount++; +} + +- (void) warnOnListenWarningsForQuery:(FQuerySpec *)query payload:(id)payload { + if (payload != nil && [payload isKindOfClass:[NSDictionary class]]) { + NSDictionary *payloadDict = payload; + id warnings = payloadDict[kFWPResponseDataWarnings]; + if (warnings != nil && [warnings isKindOfClass:[NSArray class]]) { + NSArray *warningsArr = warnings; + if ([warningsArr containsObject:@"no_index"]) { + NSString *indexSpec = [NSString stringWithFormat:@"\".indexOn\": \"%@\"", [query.params.index queryDefinition]]; + NSString *indexPath = [query.path description]; + FFWarn(@"I-RDB034028", @"Using an unspecified index. Your data will be downloaded and filtered on the client. " + "Consider adding %@ at %@ to your security rules for better performance", indexSpec, indexPath); + } + } + } +} + +- (int) getNextRequestNumber { + return [[self.requestNumber getAndIncrement] intValue]; +} + +- (void)sendAction:(NSString *)action + body:(NSDictionary *)message + sensitive:(BOOL)sensitive + callback:(void (^)(NSDictionary* data))onMessage { + // Hold onto the onMessage callback for this request before firing it off + NSNumber* rn = [NSNumber numberWithInt:[self getNextRequestNumber]]; + NSDictionary* msg = [NSDictionary dictionaryWithObjectsAndKeys: + rn, kFWPRequestNumber, + action, kFWPRequestAction, + message, kFWPRequestPayloadBody, + nil]; + + [self.realtime sendRequest:msg sensitive:sensitive]; + + if (onMessage) { + // Debug message without a callback; bump the rn, but don't hold onto the cb + [self.requestCBHash setObject:[onMessage copy] forKey:rn]; + } +} + +- (void) cancelSentTransactions { + NSMutableDictionary* cancelledOutstandingPuts = [[NSMutableDictionary alloc] init]; + + for (NSNumber* index in self.outstandingPuts) { + FOutstandingPut* put = self.outstandingPuts[index]; + if (put.request[kFWPRequestHash] && put.sent) { + // This is a sent transaction put. + cancelledOutstandingPuts[index] = put; + } + } + + [cancelledOutstandingPuts enumerateKeysAndObjectsUsingBlock:^(NSNumber *index, FOutstandingPut *outstandingPut, BOOL *stop) { + // `onCompleteBlock:` may invoke `rerunTransactionsForPath:` and enqueue new writes. We defer calling + // it until we have finished enumerating all existing writes. + outstandingPut.onCompleteBlock(kFTransactionDisconnect, @"Client was disconnected while running a transaction"); + [self.outstandingPuts removeObjectForKey:index]; + }]; +} + +- (void) onDataPushWithAction:(NSString *)action andBody:(NSDictionary *)body { + FFLog(@"I-RDB034029", @"handleServerMessage: %@, %@", action, body); + id delegate = self.delegate; + if ([action isEqualToString:kFWPAsyncServerDataUpdate] || [action isEqualToString:kFWPAsyncServerDataMerge]) { + BOOL isMerge = [action isEqualToString:kFWPAsyncServerDataMerge]; + + if ([body objectForKey:kFWPAsyncServerDataUpdateBodyPath] && [body objectForKey:kFWPAsyncServerDataUpdateBodyData]) { + NSString* path = [body objectForKey:kFWPAsyncServerDataUpdateBodyPath]; + id payloadData = [body objectForKey:kFWPAsyncServerDataUpdateBodyData]; + if (isMerge && [payloadData isKindOfClass:[NSDictionary class]] && [payloadData count] == 0) { + // ignore empty merge + } else { + [delegate onDataUpdate:self forPath:path message:payloadData isMerge:isMerge tagId:[body objectForKey:kFWPAsyncServerDataUpdateBodyTag]]; + } + } + else { + FFLog(@"I-RDB034030", @"Malformed data response from server missing path or data: %@", body); + } + } else if ([action isEqualToString:kFWPAsyncServerDataRangeMerge]) { + NSString *path = body[kFWPAsyncServerDataUpdateBodyPath]; + NSArray *ranges = body[kFWPAsyncServerDataUpdateBodyData]; + NSNumber *tag = body[kFWPAsyncServerDataUpdateBodyTag]; + NSMutableArray *rangeMerges = [NSMutableArray array]; + for (NSDictionary *range in ranges) { + NSString *startString = range[kFWPAsyncServerDataUpdateStartPath]; + NSString *endString = range[kFWPAsyncServerDataUpdateEndPath]; + id updateData = range[kFWPAsyncServerDataUpdateRangeMerge]; + id updates = [FSnapshotUtilities nodeFrom:updateData]; + FPath *start = (startString != nil) ? [[FPath alloc] initWith:startString] : nil; + FPath *end = (endString != nil) ? [[FPath alloc] initWith:endString] : nil; + FRangeMerge *merge = [[FRangeMerge alloc] initWithStart:start end:end updates:updates]; + [rangeMerges addObject:merge]; + } + [delegate onRangeMerge:rangeMerges forPath:path tagId:tag]; + } else if ([action isEqualToString:kFWPAsyncServerAuthRevoked]) { + NSString* status = [body objectForKey:kFWPResponseForActionStatus]; + NSString* reason = [body objectForKey:kFWPResponseForActionData]; + [self onAuthRevokedWithStatus:status andReason:reason]; + } else if ([action isEqualToString:kFWPASyncServerListenCancelled]) { + NSString* pathString = [body objectForKey:kFWPAsyncServerDataUpdateBodyPath]; + [self onListenRevoked:[[FPath alloc] initWith:pathString]]; + } else if ([action isEqualToString:kFWPAsyncServerSecurityDebug]) { + NSString* msg = [body objectForKey:@"msg"]; + if (msg != nil) { + NSArray *msgs = [msg componentsSeparatedByString:@"\n"]; + for (NSString* m in msgs) { + FFWarn(@"I-RDB034031", @"%@", m); + } + } + } else { + // TODO: revoke listens, auth, security debug + FFLog(@"I-RDB034032", @"Unsupported action from server: %@", action); + } +} + +- (void) restoreAuth { + FFLog(@"I-RDB034033", @"Calling restore state"); + + NSAssert(self->connectionState == ConnectionStateConnecting, + @"Wanted to restore auth, but was in wrong state: %d", self->connectionState); + if (self.authToken == nil) { + FFLog(@"I-RDB034034", @"Not restoring auth because token is nil"); + self->connectionState = ConnectionStateConnected; + [self restoreState]; + } else { + FFLog(@"I-RDB034035", @"Restoring auth"); + self->connectionState = ConnectionStateAuthenticating; + [self sendAuthAndRestoreStateAfterComplete:YES]; + } +} + +- (void) restoreState { + NSAssert(self->connectionState == ConnectionStateConnected, + @"Should be connected if we're restoring state, but we are: %d", self->connectionState); + + [self.listens enumerateKeysAndObjectsUsingBlock:^(FQuerySpec *query, FOutstandingQuery *outstandingListen, BOOL *stop) { + FFLog(@"I-RDB034036", @"Restoring listen for %@", query); + [self sendListen:outstandingListen]; + }]; + + NSArray* keys = [[self.outstandingPuts allKeys] sortedArrayUsingSelector:@selector(compare:)]; + for(int i = 0; i < [keys count]; i++) { + if([self.outstandingPuts objectForKey:[keys objectAtIndex:i]] != nil) { + FFLog(@"I-RDB034037", @"Restoring put: %d", i); + [self sendPut:[keys objectAtIndex:i]]; + } + else { + FFLog(@"I-RDB034038", @"Restoring put: skipped nil: %d", i); + } + } + + for (FTupleOnDisconnect* tuple in self.onDisconnectQueue) { + [self sendOnDisconnectAction:tuple.action forPath:tuple.pathString withData:tuple.data andCallback:tuple.onComplete]; + } + [self.onDisconnectQueue removeAllObjects]; +} + +- (NSArray *) removeListen:(FQuerySpec *)query { + NSAssert(query.isDefault || !query.loadsAllData, @"removeListen called for non-default but complete query"); + + FOutstandingQuery* outstanding = self.listens[query]; + if (!outstanding) { + FFLog(@"I-RDB034039", @"Trying to remove listener for query %@ but no listener exists", query); + return @[]; + } else { + [self.listens removeObjectForKey:query]; + return @[outstanding]; + } +} + +- (NSArray *) removeAllListensAtPath:(FPath *)path { + FFLog(@"I-RDB034040", @"Removing all listens at path %@", path); + NSMutableArray *removed = [NSMutableArray array]; + NSMutableArray *toRemove = [NSMutableArray array]; + [self.listens enumerateKeysAndObjectsUsingBlock:^(FQuerySpec *spec, FOutstandingQuery *outstanding, BOOL *stop) { + if ([spec.path isEqual:path]) { + [removed addObject:outstanding]; + [toRemove addObject:spec]; + } + }]; + [self.listens removeObjectsForKeys:toRemove]; + return removed; +} + +- (void) purgeOutstandingWrites { + // We might have unacked puts in our queue that we need to ack now before we send out any cancels... + [self ackPuts]; + // Cancel in order + NSArray* keys = [[self.outstandingPuts allKeys] sortedArrayUsingSelector:@selector(compare:)]; + for (NSNumber *key in keys) { + FOutstandingPut *put = self.outstandingPuts[key]; + if (put.onCompleteBlock != nil) { + put.onCompleteBlock(kFErrorWriteCanceled, nil); + } + } + for (FTupleOnDisconnect *onDisconnect in self.onDisconnectQueue) { + if (onDisconnect.onComplete != nil) { + onDisconnect.onComplete(kFErrorWriteCanceled, nil); + } + } + [self.outstandingPuts removeAllObjects]; + [self.onDisconnectQueue removeAllObjects]; +} + +- (void) ackPuts { + for (FTupleCallbackStatus *put in self.putsToAck) { + put.block(put.status, put.errorReason); + } + [self.putsToAck removeAllObjects]; +} + +- (void) handleTimestamp:(NSNumber *)timestamp { + FFLog(@"I-RDB034041", @"Handling timestamp: %@", timestamp); + double timestampDeltaMs = [timestamp doubleValue] - ([[NSDate date] timeIntervalSince1970] * 1000); + [self.delegate onServerInfoUpdate:self updates:@{kDotInfoServerTimeOffset: [NSNumber numberWithDouble:timestampDeltaMs]}]; +} + +- (void) sendStats:(NSDictionary *)stats { + if ([stats count] > 0) { + NSDictionary *request = @{ kFWPRequestCounters: stats }; + [self sendAction:kFWPRequestActionStats body:request sensitive:NO callback:^(NSDictionary *data) { + NSString* status = [data objectForKey:kFWPResponseForActionStatus]; + NSString* errorReason = [data objectForKey:kFWPResponseForActionData]; + BOOL statusOk = [status isEqualToString:kFWPResponseForActionStatusOk]; + if (!statusOk) { + FFLog(@"I-RDB034042", @"Failed to send stats: %@", errorReason); + } + }]; + } else { + FFLog(@"I-RDB034043", @"Not sending stats because stats are empty"); + } +} + +- (void) sendConnectStats { + NSMutableDictionary *stats = [NSMutableDictionary dictionary]; + + #if TARGET_OS_IOS || TARGET_OS_TV + if (self.config.persistenceEnabled) { + stats[@"persistence.ios.enabled"] = @1; + } + #elif TARGET_OS_OSX + if (self.config.persistenceEnabled) { + stats[@"persistence.osx.enabled"] = @1; + } + #endif + NSString *sdkVersion = [[FIRDatabase sdkVersion] stringByReplacingOccurrencesOfString:@"." withString:@"-"]; + NSString *sdkStatName = [NSString stringWithFormat:@"sdk.objc.%@", sdkVersion]; + stats[sdkStatName] = @1; + FFLog(@"I-RDB034044", @"Sending first connection stats"); + [self sendStats:stats]; +} + +- (NSDictionary *) dumpListens { + return self.listens; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FQueryParams.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FQueryParams.h new file mode 100644 index 00000000..e9728e7b --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FQueryParams.h @@ -0,0 +1,59 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@protocol FIndex, FNodeFilter, FNode; + +@interface FQueryParams : NSObject + +@property (nonatomic, readonly) BOOL limitSet; +@property (nonatomic, readonly) NSInteger limit; + +@property (nonatomic, strong, readonly) NSString *viewFrom; +@property (nonatomic, strong, readonly) id indexStartValue; +@property (nonatomic, strong, readonly) NSString *indexStartKey; +@property (nonatomic, strong, readonly) id indexEndValue; +@property (nonatomic, strong, readonly) NSString *indexEndKey; + +@property (nonatomic, strong, readonly) id index; + +- (BOOL)loadsAllData; +- (BOOL)isDefault; +- (BOOL)isValid; +- (BOOL)hasAnchoredLimit; + +- (FQueryParams *) limitTo:(NSInteger) limit; +- (FQueryParams *) limitToFirst:(NSInteger) newLimit; +- (FQueryParams *) limitToLast:(NSInteger) newLimit; + +- (FQueryParams *) startAt:(id)indexValue childKey:(NSString *)key; +- (FQueryParams *) startAt:(id)indexValue; +- (FQueryParams *) endAt:(id)indexValue childKey:(NSString *)key; +- (FQueryParams *) endAt:(id)indexValue; + +- (FQueryParams *) orderBy:(id) index; + ++ (FQueryParams *) defaultInstance; ++ (FQueryParams *) fromQueryObject:(NSDictionary *)dict; + +- (BOOL)hasStart; +- (BOOL)hasEnd; + +- (NSDictionary *) wireProtocolParams; +- (BOOL) isViewFromLeft; +- (id) nodeFilter; +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FQueryParams.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FQueryParams.m new file mode 100644 index 00000000..79203580 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FQueryParams.m @@ -0,0 +1,372 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FQueryParams.h" +#import "FValidation.h" +#import "FConstants.h" +#import "FIndex.h" +#import "FPriorityIndex.h" +#import "FUtilities.h" +#import "FNodeFilter.h" +#import "FIndexedFilter.h" +#import "FLimitedFilter.h" +#import "FRangedFilter.h" +#import "FNode.h" +#import "FSnapshotUtilities.h" + +@interface FQueryParams () + +@property (nonatomic, readwrite) BOOL limitSet; +@property (nonatomic, readwrite) NSInteger limit; + +@property (nonatomic, strong, readwrite) NSString *viewFrom; +/** +* indexStartValue is anything you can store as a priority / value. +*/ +@property (nonatomic, strong, readwrite) id indexStartValue; +@property (nonatomic, strong, readwrite) NSString *indexStartKey; +/** +* indexStartValue is anything you can store as a priority / value. +*/ +@property (nonatomic, strong, readwrite) id indexEndValue; +@property (nonatomic, strong, readwrite) NSString *indexEndKey; + +@property (nonatomic, strong, readwrite) id index; + +@end + +@implementation FQueryParams + ++ (FQueryParams *) defaultInstance { + static FQueryParams *defaultParams = nil; + static dispatch_once_t defaultParamsToken; + dispatch_once(&defaultParamsToken, ^{ + defaultParams = [[FQueryParams alloc] init]; + }); + return defaultParams; +} + + +- (id)init { + self = [super init]; + if (self) { + self->_limitSet = NO; + self->_limit = 0; + + self->_viewFrom = nil; + self->_indexStartValue = nil; + self->_indexStartKey = nil; + self->_indexEndValue = nil; + self->_indexEndKey = nil; + + self->_index = [FPriorityIndex priorityIndex]; + } + return self; +} + +/** +* Only valid if hasStart is true +*/ +- (id) indexStartValue { + NSAssert([self hasStart], @"Only valid if start has been set"); + return _indexStartValue; +} + +/** +* Only valid if hasStart is true. +* @return The starting key name for the range defined by these query parameters +*/ +- (NSString *) indexStartKey { + NSAssert([self hasStart], @"Only valid if start has been set"); + if (_indexStartKey == nil) { + return [FUtilities minName]; + } else { + return _indexStartKey; + } +} + +/** +* Only valid if hasEnd is true. +*/ +- (id) indexEndValue { + NSAssert([self hasEnd], @"Only valid if end has been set"); + return _indexEndValue; +} + +/** +* Only valid if hasEnd is true. +* @return The end key name for the range defined by these query parameters +*/ +- (NSString *) indexEndKey { + NSAssert([self hasEnd], @"Only valid if end has been set"); + if (_indexEndKey == nil) { + return [FUtilities maxName]; + } else { + return _indexEndKey; + } +} + +/** +* @return true if a limit has been set and has been explicitly anchored +*/ +- (BOOL) hasAnchoredLimit { + return self.limitSet && self.viewFrom != nil; +} + +/** +* Only valid to call if limitSet returns true +*/ +- (NSInteger) limit { + NSAssert(self.limitSet, @"Only valid if limit has been set"); + return _limit; +} + +- (BOOL)hasStart { + return self->_indexStartValue != nil; +} + +- (BOOL)hasEnd { + return self->_indexEndValue != nil; +} + +- (id) copyWithZone:(NSZone *)zone { + // Immutable + return self; +} + +- (id) mutableCopy { + FQueryParams* other = [[[self class] alloc] init]; + // Maybe need to do extra copying here + other->_limitSet = _limitSet; + other->_limit = _limit; + other->_indexStartValue = _indexStartValue; + other->_indexStartKey = _indexStartKey; + other->_indexEndValue = _indexEndValue; + other->_indexEndKey = _indexEndKey; + other->_viewFrom = _viewFrom; + other->_index = _index; + return other; +} + +- (FQueryParams *) limitTo:(NSInteger)newLimit { + FQueryParams *newParams = [self mutableCopy]; + newParams->_limitSet = YES; + newParams->_limit = newLimit; + newParams->_viewFrom = nil; + return newParams; +} + +- (FQueryParams *) limitToFirst:(NSInteger)newLimit { + FQueryParams *newParams = [self mutableCopy]; + newParams->_limitSet = YES; + newParams->_limit = newLimit; + newParams->_viewFrom = kFQPViewFromLeft; + return newParams; +} + +- (FQueryParams *) limitToLast:(NSInteger)newLimit { + FQueryParams *newParams = [self mutableCopy]; + newParams->_limitSet = YES; + newParams->_limit = newLimit; + newParams->_viewFrom = kFQPViewFromRight; + return newParams; +} + +- (FQueryParams *) startAt:(id)indexValue childKey:(NSString *)key { + NSAssert([indexValue isLeafNode] || [indexValue isEmpty], nil); + FQueryParams *newParams = [self mutableCopy]; + newParams->_indexStartValue = indexValue; + newParams->_indexStartKey = key; + return newParams; +} + +- (FQueryParams *) startAt:(id)indexValue { + return [self startAt:indexValue childKey:nil]; +} + +- (FQueryParams *) endAt:(id)indexValue childKey:(NSString *)key { + NSAssert([indexValue isLeafNode] || [indexValue isEmpty], nil); + FQueryParams *newParams = [self mutableCopy]; + newParams->_indexEndValue = indexValue; + newParams->_indexEndKey = key; + return newParams; +} + +- (FQueryParams *) endAt:(id)indexValue { + return [self endAt:indexValue childKey:nil]; +} + +- (FQueryParams *) orderBy:(id)newIndex { + FQueryParams *newParams = [self mutableCopy]; + newParams->_index = newIndex; + return newParams; +} + +- (NSDictionary *) wireProtocolParams { + NSMutableDictionary* dict = [[NSMutableDictionary alloc] init]; + if ([self hasStart]) { + [dict setObject:[self.indexStartValue valForExport:YES] forKey:kFQPIndexStartValue]; + + // Don't use property as it will be [MIN-NAME] + if (self->_indexStartKey != nil) { + [dict setObject:self->_indexStartKey forKey:kFQPIndexStartName]; + } + } + + if ([self hasEnd]) { + [dict setObject:[self.indexEndValue valForExport:YES] forKey:kFQPIndexEndValue]; + + // Don't use property as it will be [MAX-NAME] + if (self->_indexEndKey != nil) { + [dict setObject:self->_indexEndKey forKey:kFQPIndexEndName]; + } + } + + if (self.limitSet) { + [dict setObject:[NSNumber numberWithInteger:self.limit] forKey:kFQPLimit]; + NSString *vf = self.viewFrom; + if (vf == nil) { + // limit() rather than limitToFirst or limitToLast was called. + // This means that only one of startSet or endSet is true. Use them + // to calculate which side of the view to anchor to. If neither is set, + // Anchor to end + if ([self hasStart]) { + vf = kFQPViewFromLeft; + } else { + vf = kFQPViewFromRight; + } + } + [dict setObject:vf forKey:kFQPViewFrom]; + } + + // For now, priority index is the default, so we only specify if it's some other index. + if (![self.index isEqual:[FPriorityIndex priorityIndex]]) { + [dict setObject:[self.index queryDefinition] forKey:kFQPIndex]; + } + + return dict; +} + ++ (FQueryParams *)fromQueryObject:(NSDictionary *)dict { + if (dict.count == 0) { + return [FQueryParams defaultInstance]; + } + + FQueryParams *params = [[FQueryParams alloc] init]; + if (dict[kFQPLimit] != nil) { + params->_limitSet = YES; + params->_limit = [dict[kFQPLimit] integerValue]; + } + + if (dict[kFQPIndexStartValue] != nil) { + params->_indexStartValue = [FSnapshotUtilities nodeFrom:dict[kFQPIndexStartValue]]; + if (dict[kFQPIndexStartName] != nil) { + params->_indexStartKey = dict[kFQPIndexStartName]; + } + } + + if (dict[kFQPIndexEndValue] != nil) { + params->_indexEndValue = [FSnapshotUtilities nodeFrom:dict[kFQPIndexEndValue]]; + if (dict[kFQPIndexEndName] != nil) { + params->_indexEndKey = dict[kFQPIndexEndName]; + } + } + + if (dict[kFQPViewFrom] != nil) { + NSString *viewFrom = dict[kFQPViewFrom]; + if (![viewFrom isEqualToString:kFQPViewFromLeft] && ![viewFrom isEqualToString:kFQPViewFromRight]) { + [NSException raise:NSInvalidArgumentException format:@"Unknown view from paramter: %@", viewFrom]; + } + params->_viewFrom = viewFrom; + } + + NSString *index = dict[kFQPIndex]; + if (index != nil) { + params->_index = [FIndex indexFromQueryDefinition:index]; + } + + return params; +} + +- (BOOL) isViewFromLeft { + if (self.viewFrom != nil) { + // Not null, we can just check + return [self.viewFrom isEqualToString:kFQPViewFromLeft]; + } else { + // If start is set, it's view from left. Otherwise not. + return self.hasStart; + } +} + +- (id) nodeFilter { + if (self.loadsAllData) { + return [[FIndexedFilter alloc] initWithIndex:self.index]; + } else if (self.limitSet) { + return [[FLimitedFilter alloc] initWithQueryParams:self]; + } else { + return [[FRangedFilter alloc] initWithQueryParams:self]; + } +} + + +- (BOOL) isValid { + return !(self.hasStart && self.hasEnd && self.limitSet && !self.hasAnchoredLimit); +} + +- (BOOL) loadsAllData { + return !(self.hasStart || self.hasEnd || self.limitSet); +} + +- (BOOL) isDefault { + return [self loadsAllData] && [self.index isEqual:[FPriorityIndex priorityIndex]]; +} + +- (NSString *) description { + return [[self wireProtocolParams] description]; +} + +- (BOOL) isEqual:(id)obj { + if (self == obj) { + return YES; + } + if (![obj isKindOfClass:[self class]]) { + return NO; + } + FQueryParams *other = (FQueryParams *)obj; + if (self->_limitSet != other->_limitSet) return NO; + if (self->_limit != other->_limit) return NO; + if ((self->_index != other->_index) && ![self->_index isEqual:other->_index]) return NO; + if ((self->_indexStartKey != other->_indexStartKey) && ![self->_indexStartKey isEqualToString:other->_indexStartKey]) return NO; + if ((self->_indexStartValue != other->_indexStartValue) && ![self->_indexStartValue isEqual:other->_indexStartValue]) return NO; + if ((self->_indexEndKey != other->_indexEndKey) && ![self->_indexEndKey isEqualToString:other->_indexEndKey]) return NO; + if ((self->_indexEndValue != other->_indexEndValue) && ![self->_indexEndValue isEqual:other->_indexEndValue]) return NO; + if ([self isViewFromLeft] != [other isViewFromLeft]) return NO; + + return YES; +} + +- (NSUInteger) hash { + NSUInteger result = _limitSet ? _limit : 0; + result = 31 * result + ([self isViewFromLeft] ? 1231 : 1237); + result = 31 * result + [_indexStartKey hash]; + result = 31 * result + [_indexStartValue hash]; + result = 31 * result + [_indexEndKey hash]; + result = 31 * result + [_indexEndValue hash]; + result = 31 * result + [_index hash]; + return result; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FQuerySpec.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FQuerySpec.h new file mode 100644 index 00000000..49ed5367 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FQuerySpec.h @@ -0,0 +1,36 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import "FQueryParams.h" +#import "FPath.h" +#import "FIndex.h" + +@interface FQuerySpec : NSObject + +@property (nonatomic, strong, readonly) FPath* path; +@property (nonatomic, strong, readonly) FQueryParams *params; + +- (id)initWithPath:(FPath *)path params:(FQueryParams *)params; + ++ (FQuerySpec *)defaultQueryAtPath:(FPath *)path; + +- (id)index; +- (BOOL)isDefault; +- (BOOL)loadsAllData; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FQuerySpec.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FQuerySpec.m new file mode 100644 index 00000000..24be4338 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FQuerySpec.m @@ -0,0 +1,85 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FQuerySpec.h" + +@interface FQuerySpec () + +@property (nonatomic, strong, readwrite) FPath* path; +@property (nonatomic, strong, readwrite) FQueryParams *params; + + +@end + +@implementation FQuerySpec + +- (id)initWithPath:(FPath *)path params:(FQueryParams *)params { + self = [super init]; + if (self != nil) { + self->_path = path; + self->_params = params; + } + return self; +} + ++ (FQuerySpec *)defaultQueryAtPath:(FPath *)path { + return [[FQuerySpec alloc] initWithPath:path params:[FQueryParams defaultInstance]]; +} + +- (id)copyWithZone:(NSZone *)zone { + // Immutable + return self; +} + +- (id)index { + return self.params.index; +} + +- (BOOL)isDefault { + return self.params.isDefault; +} + +- (BOOL)loadsAllData { + return self.params.loadsAllData; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + + if (![object isKindOfClass:[FQuerySpec class]]) { + return NO; + } + + FQuerySpec *other = (FQuerySpec *)object; + + if (![self.path isEqual:other.path]) { + return NO; + } + + return [self.params isEqual:other.params]; +} + +- (NSUInteger)hash { + return self.path.hash * 31 + self.params.hash; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"FQuerySpec (path: %@, params: %@)", self.path, self.params]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRangeMerge.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRangeMerge.h new file mode 100644 index 00000000..8825e0e0 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRangeMerge.h @@ -0,0 +1,35 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import "FNode.h" + +/** + * Applies a merge of a snap for a given interval of paths. + * Each leaf in the current node which the relative path lies *after* (the optional) start and lies *before or at* + * (the optional) end will be deleted. Each leaf in snap that lies in the interval will be added to the resulting node. + * Nodes outside of the range are ignored. nil for start and end are sentinel values that represent -infinity and + * +infinity respectively (aka includes any path). + * Priorities of children nodes are treated as leaf children of that node. + */ +@interface FRangeMerge : NSObject + +- (instancetype)initWithStart:(FPath *)start end:(FPath *)end updates:(id)updates; + +- (id)applyToNode:(id)node; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRangeMerge.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRangeMerge.m new file mode 100644 index 00000000..8bc67bf3 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRangeMerge.m @@ -0,0 +1,107 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FRangeMerge.h" + +#import "FEmptyNode.h" + +@interface FRangeMerge () + +@property (nonatomic, strong) FPath *optExclusiveStart; +@property (nonatomic, strong) FPath *optInclusiveEnd; +@property (nonatomic, strong) id updates; + +@end + +@implementation FRangeMerge + +- (instancetype)initWithStart:(FPath *)start end:(FPath *)end updates:(id)updates { + self = [super init]; + if (self != nil) { + self->_optExclusiveStart = start; + self->_optInclusiveEnd = end; + self->_updates = updates; + } + return self; +} + +- (id)applyToNode:(id)node { + return [self updateRangeInNode:[FPath empty] node:node updates:self.updates]; +} + +- (id)updateRangeInNode:(FPath *)currentPath node:(id)node updates:(id)updates { + NSComparisonResult startComparison = (self.optExclusiveStart == nil) ? NSOrderedDescending : [currentPath compare:self.optExclusiveStart]; + NSComparisonResult endComparison = (self.optInclusiveEnd == nil) ? NSOrderedAscending : [currentPath compare:self.optInclusiveEnd]; + BOOL startInNode = self.optExclusiveStart != nil && [currentPath contains:self.optExclusiveStart]; + BOOL endInNode = self.optInclusiveEnd != nil && [currentPath contains:self.optInclusiveEnd]; + if (startComparison == NSOrderedDescending && endComparison == NSOrderedAscending && !endInNode) { + // child is completly contained + return updates; + } else if (startComparison == NSOrderedDescending && endInNode && [updates isLeafNode]) { + return updates; + } else if (startComparison == NSOrderedDescending && endComparison == NSOrderedSame) { + NSAssert(endInNode, @"End not in node"); + NSAssert(![updates isLeafNode], @"Found leaf node update, this case should have been handled above."); + if ([node isLeafNode]) { + // Update node was not a leaf node, so we can delete it + return [FEmptyNode emptyNode]; + } else { + // Unaffected by range, ignore + return node; + } + } else if (startInNode || endInNode) { + // There is a partial update we need to do, so collect all relevant children + NSMutableSet *allChildren = [NSMutableSet set]; + [node enumerateChildrenUsingBlock:^(NSString *key, id node, BOOL *stop) { + [allChildren addObject:key]; + }]; + [updates enumerateChildrenUsingBlock:^(NSString *key, id node, BOOL *stop) { + [allChildren addObject:key]; + }]; + + __block id newNode = node; + void (^action)(id, BOOL *) = ^void(NSString *key, BOOL *stop) { + id currentChild = [node getImmediateChild:key]; + id updatedChild = [self updateRangeInNode:[currentPath childFromString:key] + node:currentChild + updates:[updates getImmediateChild:key]]; + // Only need to update if the node changed + if (updatedChild != currentChild) { + newNode = [newNode updateImmediateChild:key withNewChild:updatedChild]; + } + }; + + [allChildren enumerateObjectsUsingBlock:action]; + + // Add priority last, so the node is not empty when applying + if (!updates.getPriority.isEmpty || !node.getPriority.isEmpty) { + BOOL stop = NO; + action(@".priority", &stop); + } + return newNode; + } else { + // Unaffected by this range + NSAssert(endComparison == NSOrderedDescending || startComparison <= NSOrderedSame, @"Invalid range for update"); + return node; + } +} + +- (NSString *)description { + return [NSString stringWithFormat:@"RangeMerge (optExclusiveStart = %@, optExclusiveEng = %@, updates = %@)", + self.optExclusiveStart, self.optInclusiveEnd, self.updates]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRepo.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRepo.h new file mode 100644 index 00000000..ab0b0745 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRepo.h @@ -0,0 +1,76 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FRepoInfo.h" +#import "FPersistentConnection.h" +#import "FIRDataEventType.h" +#import "FTupleUserCallback.h" + +@class FQuerySpec; +@class FPersistence; +@class FAuthenticationManager; +@class FIRDatabaseConfig; +@protocol FEventRegistration; +@class FCompoundWrite; +@protocol FClock; +@class FIRDatabase; + +@interface FRepo : NSObject + +@property (nonatomic, strong) FIRDatabaseConfig *config; + +- (id)initWithRepoInfo:(FRepoInfo *)info config:(FIRDatabaseConfig *)config database:(FIRDatabase *)database; + +- (void) set:(FPath *)path withNode:(id)node withCallback:(fbt_void_nserror_ref)onComplete; +- (void) update:(FPath *)path withNodes:(FCompoundWrite *)compoundWrite withCallback:(fbt_void_nserror_ref)callback; +- (void) purgeOutstandingWrites; + +- (void) addEventRegistration:(id)eventRegistration forQuery:(FQuerySpec *)query; +- (void) removeEventRegistration:(id)eventRegistration forQuery:(FQuerySpec *)query; +- (void) keepQuery:(FQuerySpec *)query synced:(BOOL)synced; + +- (NSString*)name; +- (NSTimeInterval)serverTime; + +- (void) onDataUpdate:(FPersistentConnection *)fpconnection forPath:(NSString *)pathString message:(id)message isMerge:(BOOL)isMerge tagId:(NSNumber *)tagId; +- (void) onConnect:(FPersistentConnection *)fpconnection; +- (void) onDisconnect:(FPersistentConnection *)fpconnection; + +// Disconnect methods +- (void) onDisconnectCancel:(FPath *)path withCallback:(fbt_void_nserror_ref)callback; +- (void) onDisconnectSet:(FPath *)path withNode:(id)node withCallback:(fbt_void_nserror_ref)callback; +- (void) onDisconnectUpdate:(FPath *)path withNodes:(FCompoundWrite *)compoundWrite withCallback:(fbt_void_nserror_ref)callback; + +// Connection Management. +- (void) interrupt; +- (void) resume; + +// Transactions +- (void) startTransactionOnPath:(FPath *)path + update:(fbt_transactionresult_mutabledata)update + onComplete:(fbt_void_nserror_bool_datasnapshot)onComplete + withLocalEvents:(BOOL)applyLocally; + +// Testing methods +- (NSDictionary *) dumpListens; +- (void) dispose; +- (void) setHijackHash:(BOOL)hijack; + +@property (nonatomic, strong, readonly) FAuthenticationManager *auth; +@property (nonatomic, strong, readonly) FIRDatabase *database; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRepo.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRepo.m new file mode 100644 index 00000000..ae1d8e81 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRepo.m @@ -0,0 +1,1119 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import +#import +#import "FRepo.h" +#import "FSnapshotUtilities.h" +#import "FConstants.h" +#import "FIRDatabaseQuery_Private.h" +#import "FQuerySpec.h" +#import "FTupleNodePath.h" +#import "FRepo_Private.h" +#import "FRepoManager.h" +#import "FServerValues.h" +#import "FTupleSetIdPath.h" +#import "FSyncTree.h" +#import "FEventRegistration.h" +#import "FAtomicNumber.h" +#import "FSyncTree.h" +#import "FListenProvider.h" +#import "FEventRaiser.h" +#import "FSnapshotHolder.h" +#import "FIRDatabaseConfig_Private.h" +#import "FLevelDBStorageEngine.h" +#import "FPersistenceManager.h" +#import "FWriteRecord.h" +#import "FCachePolicy.h" +#import "FClock.h" +#import "FIRDatabase_Private.h" +#import "FTree.h" +#import "FTupleTransaction.h" +#import "FIRTransactionResult.h" +#import "FIRTransactionResult_Private.h" +#import "FIRMutableData.h" +#import "FIRMutableData_Private.h" +#import "FIRDataSnapshot.h" +#import "FIRDataSnapshot_Private.h" +#import "FValueEventRegistration.h" +#import "FEmptyNode.h" + +#if TARGET_OS_IOS || TARGET_OS_TV +#import +#endif + +@interface FRepo() + +@property (nonatomic, strong) FOffsetClock *serverClock; +@property (nonatomic, strong) FPersistenceManager* persistenceManager; +@property (nonatomic, strong) FIRDatabase *database; +@property (nonatomic, strong, readwrite) FAuthenticationManager *auth; +@property (nonatomic, strong) FSyncTree *infoSyncTree; +@property (nonatomic) NSInteger writeIdCounter; +@property (nonatomic) BOOL hijackHash; +@property (nonatomic, strong) FTree *transactionQueueTree; +@property (nonatomic) BOOL loggedTransactionPersistenceWarning; + +/** +* Test only. For load testing the server. +*/ +@property (nonatomic, strong) id (^interceptServerDataCallback)(NSString *pathString, id data); +@end + + +@implementation FRepo + +- (id)initWithRepoInfo:(FRepoInfo*)info config:(FIRDatabaseConfig *)config database:(FIRDatabase *)database { + self = [super init]; + if (self) { + self.repoInfo = info; + self.config = config; + self.database = database; + + // Access can occur outside of shared queue, so the clock needs to be initialized here + self.serverClock = [[FOffsetClock alloc] initWithClock:[FSystemClock clock] offset:0]; + + self.connection = [[FPersistentConnection alloc] initWithRepoInfo:self.repoInfo dispatchQueue:[FIRDatabaseQuery sharedQueue] config:self.config]; + + // Needs to be called before authentication manager is instantiated + self.eventRaiser = [[FEventRaiser alloc] initWithQueue:self.config.callbackQueue]; + + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + [self deferredInit]; + }); + } + return self; +} + +- (void)deferredInit { + // TODO: cleanup on dealloc + __weak FRepo *weakSelf = self; + [self.config.authTokenProvider listenForTokenChanges:^(NSString *token) { + [weakSelf.connection refreshAuthToken:token]; + }]; + + // Open connection now so that by the time we are connected the deferred init has run + // This relies on the fact that all callbacks run on repos queue + self.connection.delegate = self; + [self.connection open]; + + self.dataUpdateCount = 0; + self.rangeMergeUpdateCount = 0; + self.interceptServerDataCallback = nil; + + if (self.config.persistenceEnabled) { + NSString* repoHashString = [NSString stringWithFormat:@"%@_%@", self.repoInfo.host, self.repoInfo.namespace]; + NSString* persistencePrefix = [NSString stringWithFormat:@"%@/%@", self.config.sessionIdentifier, repoHashString]; + + id cachePolicy = [[FLRUCachePolicy alloc] initWithMaxSize:self.config.persistenceCacheSizeBytes]; + + id engine; + if (self.config.forceStorageEngine != nil) { + engine = self.config.forceStorageEngine; + } else { + FLevelDBStorageEngine *levelDBEngine = [[FLevelDBStorageEngine alloc] initWithPath:persistencePrefix]; + // We need the repo info to run the legacy migration. Future migrations will be managed by the database itself + // Remove this once we are confident that no-one is using legacy migration anymore... + [levelDBEngine runLegacyMigration:self.repoInfo]; + engine = levelDBEngine; + } + + self.persistenceManager = [[FPersistenceManager alloc] initWithStorageEngine:engine cachePolicy:cachePolicy]; + } else { + self.persistenceManager = nil; + } + + [self initTransactions]; + + // A list of data pieces and paths to be set when this client disconnects + self.onDisconnect = [[FSparseSnapshotTree alloc] init]; + self.infoData = [[FSnapshotHolder alloc] init]; + + FListenProvider *infoListenProvider = [[FListenProvider alloc] init]; + infoListenProvider.startListening = ^(FQuerySpec *query, + NSNumber *tagId, + id hash, + fbt_nsarray_nsstring onComplete) { + NSArray *infoEvents = @[]; + FRepo *strongSelf = weakSelf; + id node = [strongSelf.infoData getNode:query.path]; + // This is possibly a hack, but we have different semantics for .info endpoints. We don't raise null events + // on initial data... + if (![node isEmpty]) { + infoEvents = [strongSelf.infoSyncTree applyServerOverwriteAtPath:query.path newData:node]; + [strongSelf.eventRaiser raiseCallback:^{ + onComplete(kFWPResponseForActionStatusOk); + }]; + } + return infoEvents; + }; + infoListenProvider.stopListening = ^(FQuerySpec *query, NSNumber *tagId) {}; + self.infoSyncTree = [[FSyncTree alloc] initWithListenProvider:infoListenProvider]; + + FListenProvider *serverListenProvider = [[FListenProvider alloc] init]; + serverListenProvider.startListening = ^(FQuerySpec *query, + NSNumber *tagId, + id hash, + fbt_nsarray_nsstring onComplete) { + [weakSelf.connection listen:query tagId:tagId hash:hash onComplete:^(NSString *status) { + NSArray *events = onComplete(status); + [weakSelf.eventRaiser raiseEvents:events]; + }]; + // No synchronous events for network-backed sync trees + return @[]; + }; + serverListenProvider.stopListening = ^(FQuerySpec *query, NSNumber *tag) { + [weakSelf.connection unlisten:query tagId:tag]; + }; + self.serverSyncTree = [[FSyncTree alloc] initWithPersistenceManager:self.persistenceManager + listenProvider:serverListenProvider]; + + [self restoreWrites]; + + [self updateInfo:kDotInfoConnected withValue:@NO]; + + [self setupNotifications]; +} + + +- (void) restoreWrites { + NSArray *writes = self.persistenceManager.userWrites; + + NSDictionary *serverValues = [FServerValues generateServerValues:self.serverClock]; + __block NSInteger lastWriteId = NSIntegerMin; + [writes enumerateObjectsUsingBlock:^(FWriteRecord *write, NSUInteger idx, BOOL *stop) { + NSInteger writeId = write.writeId; + fbt_void_nsstring_nsstring callback = ^(NSString *status, NSString *errorReason) { + [self warnIfWriteFailedAtPath:write.path status:status message:@"Persisted write"]; + [self ackWrite:writeId rerunTransactionsAtPath:write.path status:status]; + }; + if (lastWriteId >= writeId) { + [NSException raise:NSInternalInconsistencyException format:@"Restored writes were not in order!"]; + } + lastWriteId = writeId; + self.writeIdCounter = writeId + 1; + if ([write isOverwrite]) { + FFLog(@"I-RDB038001", @"Restoring overwrite with id %ld", (long)write.writeId); + [self.connection putData:[write.overwrite valForExport:YES] + forPath:[write.path toString] + withHash:nil + withCallback:callback]; + id resolved = [FServerValues resolveDeferredValueSnapshot:write.overwrite withServerValues:serverValues]; + [self.serverSyncTree applyUserOverwriteAtPath:write.path newData:resolved writeId:writeId isVisible:YES]; + } else { + FFLog(@"I-RDB038002", @"Restoring merge with id %ld", (long)write.writeId); + [self.connection mergeData:[write.merge valForExport:YES] + forPath:[write.path toString] + withCallback:callback]; + FCompoundWrite *resolved = [FServerValues resolveDeferredValueCompoundWrite:write.merge withServerValues:serverValues]; + [self.serverSyncTree applyUserMergeAtPath:write.path changedChildren:resolved writeId:writeId]; + } + }]; +} + +- (NSString*)name { + return self.repoInfo.namespace; +} + +- (NSString *) description { + return [self.repoInfo description]; +} + +- (void) interrupt { + [self.connection interruptForReason:kFInterruptReasonRepoInterrupt]; +} + +- (void) resume { + [self.connection resumeForReason:kFInterruptReasonRepoInterrupt]; +} + +// NOTE: Typically if you're calling this, you should be in an @autoreleasepool block to make sure that ARC kicks +// in and cleans up things no longer referenced (i.e. pendingPutsDB). +- (void) dispose { + [self.connection interruptForReason:kFInterruptReasonRepoInterrupt]; + + // We need to nil out any references to LevelDB, to make sure the + // LevelDB exclusive locks are released. + [self.persistenceManager close]; +} + +- (NSInteger) nextWriteId { + return self->_writeIdCounter++; +} + +- (NSTimeInterval) serverTime { + return [self.serverClock currentTime]; +} + +- (void) set:(FPath *)path withNode:(id)node withCallback:(fbt_void_nserror_ref)onComplete { + id value = [node valForExport:YES]; + FFLog(@"I-RDB038003", @"Setting: %@ with %@ pri: %@", [path toString], [value description], [[node getPriority] val]); + + // TODO: Optimize this behavior to either (a) store flag to skip resolving where possible and / or + // (b) store unresolved paths on JSON parse + NSDictionary* serverValues = [FServerValues generateServerValues:self.serverClock]; + id newNode = [FServerValues resolveDeferredValueSnapshot:node withServerValues:serverValues]; + + NSInteger writeId = [self nextWriteId]; + [self.persistenceManager saveUserOverwrite:node atPath:path writeId:writeId]; + NSArray *events = [self.serverSyncTree applyUserOverwriteAtPath:path newData:newNode writeId:writeId isVisible:YES]; + [self.eventRaiser raiseEvents:events]; + + [self.connection putData:value forPath:[path toString] withHash:nil withCallback:^(NSString *status, NSString *errorReason) { + [self warnIfWriteFailedAtPath:path status:status message:@"setValue: or removeValue:"]; + [self ackWrite:writeId rerunTransactionsAtPath:path status:status]; + [self callOnComplete:onComplete withStatus:status errorReason:errorReason andPath:path]; + }]; + + FPath* affectedPath = [self abortTransactionsAtPath:path error:kFTransactionSet]; + [self rerunTransactionsForPath:affectedPath]; +} + +- (void) update:(FPath *)path withNodes:(FCompoundWrite *)nodes withCallback:(fbt_void_nserror_ref)callback { + NSDictionary *values = [nodes valForExport:YES]; + + FFLog(@"I-RDB038004", @"Updating: %@ with %@", [path toString], [values description]); + NSDictionary* serverValues = [FServerValues generateServerValues:self.serverClock]; + FCompoundWrite *resolved = [FServerValues resolveDeferredValueCompoundWrite:nodes withServerValues:serverValues]; + + if (!resolved.isEmpty) { + NSInteger writeId = [self nextWriteId]; + [self.persistenceManager saveUserMerge:nodes atPath:path writeId:writeId]; + NSArray *events = [self.serverSyncTree applyUserMergeAtPath:path changedChildren:resolved writeId:writeId]; + [self.eventRaiser raiseEvents:events]; + + [self.connection mergeData:values forPath:[path description] withCallback:^(NSString *status, NSString *errorReason) { + [self warnIfWriteFailedAtPath:path status:status message:@"updateChildValues:"]; + [self ackWrite:writeId rerunTransactionsAtPath:path status:status]; + [self callOnComplete:callback withStatus:status errorReason:errorReason andPath:path]; + }]; + + [nodes enumerateWrites:^(FPath *childPath, id node, BOOL *stop) { + FPath* pathFromRoot = [path child:childPath]; + FFLog(@"I-RDB038005", @"Cancelling transactions at path: %@", pathFromRoot); + FPath *affectedPath = [self abortTransactionsAtPath:pathFromRoot error:kFTransactionSet]; + [self rerunTransactionsForPath:affectedPath]; + }]; + } else { + FFLog(@"I-RDB038006", @"update called with empty data. Doing nothing"); + // Do nothing, just call the callback + [self callOnComplete:callback withStatus:@"ok" errorReason:nil andPath:path]; + } +} + +- (void) onDisconnectCancel:(FPath *)path withCallback:(fbt_void_nserror_ref)callback { + [self.connection onDisconnectCancelPath:path withCallback:^(NSString *status, NSString *errorReason) { + BOOL success = [status isEqualToString:kFWPResponseForActionStatusOk]; + if (success) { + [self.onDisconnect forgetPath:path]; + } else { + FFLog(@"I-RDB038007", @"cancelDisconnectOperations: at %@ failed: %@", path, status); + } + + [self callOnComplete:callback withStatus:status errorReason:errorReason andPath:path]; + }]; +} + +- (void) onDisconnectSet:(FPath *)path withNode:(id)node withCallback:(fbt_void_nserror_ref)callback { + [self.connection onDisconnectPutData:[node valForExport:YES] forPath:path withCallback:^(NSString *status, NSString *errorReason) { + BOOL success = [status isEqualToString:kFWPResponseForActionStatusOk]; + if (success) { + [self.onDisconnect rememberData:node onPath:path]; + } else { + FFWarn(@"I-RDB038008", @"onDisconnectSetValue: or onDisconnectRemoveValue: at %@ failed: %@", path, status); + } + + [self callOnComplete:callback withStatus:status errorReason:errorReason andPath:path]; + }]; +} + +- (void) onDisconnectUpdate:(FPath *)path withNodes:(FCompoundWrite *)nodes withCallback:(fbt_void_nserror_ref)callback { + if (!nodes.isEmpty) { + NSDictionary *values = [nodes valForExport:YES]; + + [self.connection onDisconnectMergeData:values forPath:path withCallback:^(NSString *status, NSString *errorReason) { + BOOL success = [status isEqualToString:kFWPResponseForActionStatusOk]; + if (success) { + [nodes enumerateWrites:^(FPath *relativePath, id nodeUnresolved, BOOL *stop) { + FPath* childPath = [path child:relativePath]; + [self.onDisconnect rememberData:nodeUnresolved onPath:childPath]; + }]; + } else { + FFWarn(@"I-RDB038009", @"onDisconnectUpdateChildValues: at %@ failed %@", path, status); + } + + [self callOnComplete:callback withStatus:status errorReason:errorReason andPath:path]; + }]; + } else { + // Do nothing, just call the callback + [self callOnComplete:callback withStatus:@"ok" errorReason:nil andPath:path]; + } +} + +- (void) purgeOutstandingWrites { + FFLog(@"I-RDB038010", @"Purging outstanding writes"); + NSArray *events = [self.serverSyncTree removeAllWrites]; + [self.eventRaiser raiseEvents:events]; + // Abort any transactions + [self abortTransactionsAtPath:[FPath empty] error:kFErrorWriteCanceled]; + // Remove outstanding writes from connection + [self.connection purgeOutstandingWrites]; +} + +- (void) addEventRegistration:(id )eventRegistration forQuery:(FQuerySpec *)query { + NSArray *events = nil; + if ([[query.path getFront] isEqualToString:kDotInfoPrefix]) { + events = [self.infoSyncTree addEventRegistration:eventRegistration forQuery:query]; + } else { + events = [self.serverSyncTree addEventRegistration:eventRegistration forQuery:query]; + } + [self.eventRaiser raiseEvents:events]; +} + +- (void) removeEventRegistration:(id)eventRegistration forQuery:(FQuerySpec *)query { + // These are guaranteed not to raise events, since we're not passing in a cancelError. However we can future-proof + // a little bit by handling the return values anyways. + FFLog(@"I-RDB038011", @"Removing event registration with hande: %lu", (unsigned long)eventRegistration.handle); + NSArray *events = nil; + if ([[query.path getFront] isEqualToString:kDotInfoPrefix]) { + events = [self.infoSyncTree removeEventRegistration:eventRegistration forQuery:query cancelError:nil]; + } else { + events = [self.serverSyncTree removeEventRegistration:eventRegistration forQuery:query cancelError:nil]; + } + [self.eventRaiser raiseEvents:events]; +} + +- (void) keepQuery:(FQuerySpec *)query synced:(BOOL)synced { + NSAssert(![[query.path getFront] isEqualToString:kDotInfoPrefix], @"Can't keep .info tree synced!"); + [self.serverSyncTree keepQuery:query synced:synced]; +} + +- (void) updateInfo:(NSString *) pathString withValue:(id)value { + // hack to make serverTimeOffset available in a threadsafe way. Property is marked as atomic + if ([pathString isEqualToString:kDotInfoServerTimeOffset]) { + NSTimeInterval offset = [(NSNumber *)value doubleValue]/1000.0; + self.serverClock = [[FOffsetClock alloc] initWithClock:[FSystemClock clock] offset:offset]; + } + + FPath* path = [[FPath alloc] initWith:[NSString stringWithFormat:@"%@/%@", kDotInfoPrefix, pathString]]; + id newNode = [FSnapshotUtilities nodeFrom:value]; + [self.infoData updateSnapshot:path withNewSnapshot:newNode]; + NSArray *events = [self.infoSyncTree applyServerOverwriteAtPath:path newData:newNode]; + [self.eventRaiser raiseEvents:events]; +} + +- (void) callOnComplete:(fbt_void_nserror_ref)onComplete withStatus:(NSString *)status errorReason:(NSString *)errorReason andPath:(FPath *)path { + if (onComplete) { + FIRDatabaseReference * ref = [[FIRDatabaseReference alloc] initWithRepo:self path:path]; + BOOL statusOk = [status isEqualToString:kFWPResponseForActionStatusOk]; + NSError* err = nil; + if (!statusOk) { + err = [FUtilities errorForStatus:status andReason:errorReason]; + } + [self.eventRaiser raiseCallback:^{ + onComplete(err, ref); + }]; + } +} + +- (void)ackWrite:(NSInteger)writeId rerunTransactionsAtPath:(FPath *)path status:(NSString *)status { + if ([status isEqualToString:kFErrorWriteCanceled]) { + // This write was already removed, we just need to ignore it... + } else { + BOOL success = [status isEqualToString:kFWPResponseForActionStatusOk]; + NSArray *clearEvents = [self.serverSyncTree ackUserWriteWithWriteId:writeId revert:!success persist:YES clock:self.serverClock]; + if ([clearEvents count] > 0) { + [self rerunTransactionsForPath:path]; + } + [self.eventRaiser raiseEvents:clearEvents]; + } +} + +- (void) warnIfWriteFailedAtPath:(FPath *)path status:(NSString *)status message:(NSString *)message { + if (!([status isEqualToString:kFWPResponseForActionStatusOk] || [status isEqualToString:kFErrorWriteCanceled])) { + FFWarn(@"I-RDB038012", @"%@ at %@ failed: %@", message, path, status); + } +} + +#pragma mark - +#pragma mark FPersistentConnectionDelegate methods + +- (void) onDataUpdate:(FPersistentConnection *)fpconnection forPath:(NSString *)pathString message:(id)data isMerge:(BOOL)isMerge tagId:(NSNumber *)tagId { + FFLog(@"I-RDB038013", @"onDataUpdateForPath: %@ withMessage: %@", pathString, data); + + // For testing. + self.dataUpdateCount++; + + FPath* path = [[FPath alloc] initWith:pathString]; + data = self.interceptServerDataCallback ? self.interceptServerDataCallback(pathString, data) : data; + NSArray *events = nil; + + if (tagId != nil) { + if (isMerge) { + NSDictionary *message = data; + FCompoundWrite *taggedChildren = [FCompoundWrite compoundWriteWithValueDictionary:message]; + events = [self.serverSyncTree applyTaggedQueryMergeAtPath:path changedChildren:taggedChildren tagId:tagId]; + } else { + id taggedSnap = [FSnapshotUtilities nodeFrom:data]; + events = [self.serverSyncTree applyTaggedQueryOverwriteAtPath:path newData:taggedSnap tagId:tagId]; + } + } else if (isMerge) { + NSDictionary *message = data; + FCompoundWrite *changedChildren = [FCompoundWrite compoundWriteWithValueDictionary:message]; + events = [self.serverSyncTree applyServerMergeAtPath:path changedChildren:changedChildren]; + } else { + id snap = [FSnapshotUtilities nodeFrom:data]; + events = [self.serverSyncTree applyServerOverwriteAtPath:path newData:snap]; + } + + if ([events count] > 0) { + // Since we have a listener outstanding for each transaction, receiving any events + // is a proxy for some change having occurred. + [self rerunTransactionsForPath:path]; + } + + [self.eventRaiser raiseEvents:events]; +} + +- (void)onRangeMerge:(NSArray *)ranges forPath:(NSString *)pathString tagId:(NSNumber *)tag { + FFLog(@"I-RDB038014", @"onRangeMerge: %@ => %@", pathString, ranges); + + // For testing + self.rangeMergeUpdateCount++; + + FPath* path = [[FPath alloc] initWith:pathString]; + NSArray *events; + if (tag != nil) { + events = [self.serverSyncTree applyTaggedServerRangeMergeAtPath:path updates:ranges tagId:tag]; + } else { + events = [self.serverSyncTree applyServerRangeMergeAtPath:path updates:ranges]; + } + if (events.count > 0) { + // Since we have a listener outstanding for each transaction, receiving any events + // is a proxy for some change having occurred. + [self rerunTransactionsForPath:path]; + } + + [self.eventRaiser raiseEvents:events]; +} + +- (void)onConnect:(FPersistentConnection *)fpconnection { + [self updateInfo:kDotInfoConnected withValue:@YES]; +} + +- (void)onDisconnect:(FPersistentConnection *)fpconnection { + [self updateInfo:kDotInfoConnected withValue:@NO]; + [self runOnDisconnectEvents]; +} + +- (void)onServerInfoUpdate:(FPersistentConnection *)fpconnection updates:(NSDictionary *)updates { + for (NSString* key in updates) { + id val = [updates objectForKey:key]; + [self updateInfo:key withValue:val]; + } +} + +- (void) setupNotifications { + NSString * const *backgroundConstant = (NSString * const *) dlsym(RTLD_DEFAULT, "UIApplicationDidEnterBackgroundNotification"); + if (backgroundConstant) { + FFLog(@"I-RDB038015", @"Registering for background notification."); + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(didEnterBackground) + name:*backgroundConstant + object:nil]; + } else { + FFLog(@"I-RDB038016", @"Skipped registering for background notification."); + } +} + +- (void) didEnterBackground { + if (!self.config.persistenceEnabled) + return; + + // Targetted compilation is ONLY for testing. UIKit is weak-linked in actual release build. + #if TARGET_OS_IOS || TARGET_OS_TV + // The idea is to wait until any outstanding sets get written to disk. Since the sets might still be in our + // dispatch queue, we wait for the dispatch queue to catch up and for persistence to catch up. + // This may be undesirable though. The dispatch queue might just be processing a bunch of incoming data or + // something. We might want to keep track of whether there are any unpersisted sets or something. + FFLog(@"I-RDB038017", @"Entering background. Starting background task to finish work."); + Class uiApplicationClass = NSClassFromString(@"UIApplication"); + assert(uiApplicationClass); // If we are here, we should be on iOS and UIApplication should be available. + + UIApplication *application = [uiApplicationClass sharedApplication]; + __block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{ + [application endBackgroundTask:bgTask]; + }]; + + NSDate *start = [NSDate date]; + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + NSTimeInterval finishTime = [start timeIntervalSinceNow]*-1; + FFLog(@"I-RDB038018", @"Background task completed. Queue time: %f", finishTime); + [application endBackgroundTask:bgTask]; + }); + #endif +} + +#pragma mark - +#pragma mark Internal methods + +/** +* Applies all the changes stored up in the onDisconnect tree +*/ +- (void) runOnDisconnectEvents { + FFLog(@"I-RDB038019", @"Running onDisconnectEvents"); + NSDictionary* serverValues = [FServerValues generateServerValues:self.serverClock]; + FSparseSnapshotTree* resolvedTree = [FServerValues resolveDeferredValueTree:self.onDisconnect withServerValues:serverValues]; + NSMutableArray *events = [[NSMutableArray alloc] init]; + + [resolvedTree forEachTreeAtPath:[FPath empty] do:^(FPath *path, id node) { + [events addObjectsFromArray:[self.serverSyncTree applyServerOverwriteAtPath:path newData:node]]; + FPath* affectedPath = [self abortTransactionsAtPath:path error:kFTransactionSet]; + [self rerunTransactionsForPath:affectedPath]; + }]; + + self.onDisconnect = [[FSparseSnapshotTree alloc] init]; + [self.eventRaiser raiseEvents:events]; +} + +- (NSDictionary *) dumpListens { + return [self.connection dumpListens]; +} + +#pragma mark - +#pragma mark Transactions + +/** + * Setup the transaction data structures + */ +- (void) initTransactions { + self.transactionQueueTree = [[FTree alloc] init]; + self.hijackHash = NO; + self.loggedTransactionPersistenceWarning = NO; +} + +/** + * Creates a new transaction, add its to the transactions we're tracking, and sends it to the server if possible + */ +- (void) startTransactionOnPath:(FPath *)path update:(fbt_transactionresult_mutabledata)update onComplete:(fbt_void_nserror_bool_datasnapshot)onComplete withLocalEvents:(BOOL)applyLocally { + if (self.config.persistenceEnabled && !self.loggedTransactionPersistenceWarning) { + self.loggedTransactionPersistenceWarning = YES; + FFInfo(@"I-RDB038020", @"runTransactionBlock: usage detected while persistence is enabled. Please be aware that transactions " + @"*will not* be persisted across app restarts. " + @"See https://www.firebase.com/docs/ios/guide/offline-capabilities.html#section-handling-transactions-offline for more details."); + } + + FIRDatabaseReference * watchRef = [[FIRDatabaseReference alloc] initWithRepo:self path:path]; + // make sure we're listening on this node + // Note: we can't do this asynchronously. To preserve event ordering, it has to be done in this block. + // This is ok, this block is guaranteed to be our own event loop + NSUInteger handle = [[FUtilities LUIDGenerator] integerValue]; + fbt_void_datasnapshot cb = ^(FIRDataSnapshot *snapshot) {}; + FValueEventRegistration *registration = [[FValueEventRegistration alloc] initWithRepo:self + handle:handle + callback:cb + cancelCallback:nil]; + [watchRef.repo addEventRegistration:registration forQuery:watchRef.querySpec]; + fbt_void_void unwatcher = ^{ [watchRef removeObserverWithHandle:handle]; }; + + // Save all the data that represents this transaction + FTupleTransaction* transaction = [[FTupleTransaction alloc] init]; + transaction.path = path; + transaction.update = update; + transaction.onComplete = onComplete; + transaction.status = FTransactionInitializing; + transaction.order = [FUtilities LUIDGenerator]; + transaction.applyLocally = applyLocally; + transaction.retryCount = 0; + transaction.unwatcher = unwatcher; + transaction.currentWriteId = nil; + transaction.currentInputSnapshot = nil; + transaction.currentOutputSnapshotRaw = nil; + transaction.currentOutputSnapshotResolved = nil; + + // Run transaction initially + id currentState = [self latestStateAtPath:path excludeWriteIds:nil]; + transaction.currentInputSnapshot = currentState; + FIRMutableData * mutableCurrent = [[FIRMutableData alloc] initWithNode:currentState]; + FIRTransactionResult * result = transaction.update(mutableCurrent); + + if (!result.isSuccess) { + // Abort the transaction + transaction.unwatcher(); + transaction.currentOutputSnapshotRaw = nil; + transaction.currentOutputSnapshotResolved = nil; + if (transaction.onComplete) { + FIRDatabaseReference *ref = [[FIRDatabaseReference alloc] initWithRepo:self path:transaction.path]; + FIndexedNode *indexedNode = [FIndexedNode indexedNodeWithNode:transaction.currentInputSnapshot]; + FIRDataSnapshot *snap = [[FIRDataSnapshot alloc] initWithRef:ref indexedNode:indexedNode]; + [self.eventRaiser raiseCallback:^{ + transaction.onComplete(nil, NO, snap); + }]; + } + } else { + // Note: different from js. We don't need to validate, FIRMutableData does validation. + // We also don't have to worry about priorities. Just mark as run and add to queue. + transaction.status = FTransactionRun; + FTree* queueNode = [self.transactionQueueTree subTree:transaction.path]; + NSMutableArray* nodeQueue = [queueNode getValue]; + if (nodeQueue == nil) { + nodeQueue = [[NSMutableArray alloc] init]; + } + [nodeQueue addObject:transaction]; + [queueNode setValue:nodeQueue]; + + // Update visibleData and raise events + // Note: We intentionally raise events after updating all of our transaction state, since the user could + // start new transactions from the event callbacks + NSDictionary* serverValues = [FServerValues generateServerValues:self.serverClock]; + id newValUnresolved = [result.update nodeValue]; + id newVal = [FServerValues resolveDeferredValueSnapshot:newValUnresolved withServerValues:serverValues]; + transaction.currentOutputSnapshotRaw = newValUnresolved; + transaction.currentOutputSnapshotResolved = newVal; + transaction.currentWriteId = [NSNumber numberWithInteger:[self nextWriteId]]; + + NSArray *events = [self.serverSyncTree applyUserOverwriteAtPath:path newData:newVal + writeId:[transaction.currentWriteId integerValue] + isVisible:transaction.applyLocally]; + [self.eventRaiser raiseEvents:events]; + + [self sendAllReadyTransactions]; + } +} + +/** + * @param writeIdsToExclude A specific set to exclude + */ +- (id) latestStateAtPath:(FPath *)path excludeWriteIds:(NSArray *)writeIdsToExclude { + id latestState = [self.serverSyncTree calcCompleteEventCacheAtPath:path excludeWriteIds:writeIdsToExclude]; + return latestState ? latestState : [FEmptyNode emptyNode]; +} + +/** + * Sends any already-run transactions that aren't waiting for outstanding transactions to complete. + * + * Externally, call the version with no arguments. + * Internally, calls itself recursively with a particular transactionQueueTree node to recurse through the tree + */ +- (void) sendAllReadyTransactions { + FTree* node = self.transactionQueueTree; + + [self pruneCompletedTransactionsBelowNode:node]; + [self sendReadyTransactionsForTree:node]; +} + +- (void) sendReadyTransactionsForTree:(FTree *)node { + NSMutableArray* queue = [node getValue]; + if (queue != nil) { + queue = [self buildTransactionQueueAtNode:node]; + NSAssert([queue count] > 0, @"Sending zero length transaction queue"); + + NSUInteger notRunIndex = [queue indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { + return ((FTupleTransaction*)obj).status != FTransactionRun; + }]; + + // If they're all run (and not sent), we can send them. Else, we must wait. + if (notRunIndex == NSNotFound) { + [self sendTransactionQueue:queue atPath:node.path]; + } + } else if ([node hasChildren]) { + [node forEachChild:^(FTree *child) { + [self sendReadyTransactionsForTree:child]; + }]; + } +} + +/** + * Given a list of run transactions, send them to the server and then handle the result (success or failure). + */ +- (void) sendTransactionQueue:(NSMutableArray *)queue atPath:(FPath *)path { + // Mark transactions as sent and bump the retry count + NSMutableArray *writeIdsToExclude = [[NSMutableArray alloc] init]; + for (FTupleTransaction *transaction in queue) { + [writeIdsToExclude addObject:transaction.currentWriteId]; + } + id latestState = [self latestStateAtPath:path excludeWriteIds:writeIdsToExclude]; + id snapToSend = latestState; + NSString *latestHash = [latestState dataHash]; + for (FTupleTransaction* transaction in queue) { + NSAssert(transaction.status == FTransactionRun, @"[FRepo sendTransactionQueue:] items in queue should all be run."); + FFLog(@"I-RDB038021", @"Transaction at %@ set to SENT", transaction.path); + transaction.status = FTransactionSent; + transaction.retryCount++; + FPath *relativePath = [FPath relativePathFrom:path to:transaction.path]; + // If we've gotten to this point, the output snapshot must be defined. + snapToSend = [snapToSend updateChild:relativePath withNewChild:transaction.currentOutputSnapshotRaw]; + } + + id dataToSend = [snapToSend valForExport:YES]; + NSString *pathToSend = [path description]; + latestHash = self.hijackHash ? @"badhash" : latestHash; + + // Send the put + [self.connection putData:dataToSend forPath:pathToSend withHash:latestHash withCallback:^(NSString *status, NSString *errorReason) { + FFLog(@"I-RDB038022", @"Transaction put response: %@ : %@", pathToSend, status); + + NSMutableArray *events = [[NSMutableArray alloc] init]; + if ([status isEqualToString:kFWPResponseForActionStatusOk]) { + // Queue up the callbacks and fire them after cleaning up all of our transaction state, since + // the callback could trigger more transactions or sets. + NSMutableArray *callbacks = [[NSMutableArray alloc] init]; + for (FTupleTransaction *transaction in queue) { + transaction.status = FTransactionCompleted; + [events addObjectsFromArray:[self.serverSyncTree ackUserWriteWithWriteId:[transaction.currentWriteId integerValue] + revert:NO + persist:NO + clock:self.serverClock]]; + if (transaction.onComplete) { + // We never unset the output snapshot, and given that this transaction is complete, it should be set + id node = transaction.currentOutputSnapshotResolved; + FIndexedNode *indexedNode = [FIndexedNode indexedNodeWithNode:node]; + FIRDatabaseReference *ref = [[FIRDatabaseReference alloc] initWithRepo:self path:transaction.path]; + FIRDataSnapshot *snapshot = [[FIRDataSnapshot alloc] initWithRef:ref indexedNode:indexedNode]; + fbt_void_void cb = ^{ + transaction.onComplete(nil, YES, snapshot); + }; + [callbacks addObject:[cb copy]]; + } + transaction.unwatcher(); + } + + // Now remove the completed transactions. + [self pruneCompletedTransactionsBelowNode:[self.transactionQueueTree subTree:path]]; + // There may be pending transactions that we can now send. + [self sendAllReadyTransactions]; + + // Finally, trigger onComplete callbacks + [self.eventRaiser raiseCallbacks:callbacks]; + } else { + // transactions are no longer sent. Update their status appropriately. + if ([status isEqualToString:kFWPResponseForActionStatusDataStale]) { + for (FTupleTransaction *transaction in queue) { + if (transaction.status == FTransactionSentNeedsAbort) { + transaction.status = FTransactionNeedsAbort; + } else { + transaction.status = FTransactionRun; + } + } + } else { + FFWarn(@"I-RDB038023", @"runTransactionBlock: at %@ failed: %@", path, status); + for (FTupleTransaction *transaction in queue) { + transaction.status = FTransactionNeedsAbort; + [transaction setAbortStatus:status reason:errorReason]; + } + } + } + + [self rerunTransactionsForPath:path]; + [self.eventRaiser raiseEvents:events]; + }]; +} + +/** + * Finds all transactions dependent on the data at changed Path and reruns them. + * + * Should be called any time cached data changes. + * + * Return the highest path that was affected by rerunning transactions. This is the path at which events need to + * be raised for. + */ +- (FPath *) rerunTransactionsForPath:(FPath *)changedPath { + // For the common case that there are no transactions going on, skip all this! + if ([self.transactionQueueTree isEmpty]) { + return changedPath; + } else { + FTree* rootMostTransactionNode = [self getAncestorTransactionNodeForPath:changedPath]; + FPath* path = rootMostTransactionNode.path; + + NSArray* queue = [self buildTransactionQueueAtNode:rootMostTransactionNode]; + [self rerunTransactionQueue:queue atPath:path]; + + return path; + } +} + +/** + * Does all the work of rerunning transactions (as well as cleans up aborted transactions and whatnot). + */ +- (void) rerunTransactionQueue:(NSArray *)queue atPath:(FPath *)path { + if (queue.count == 0) { + return; // nothing to do + } + + // Queue up the callbacks and fire them after cleaning up all of our transaction state, since + // the callback could trigger more transactions or sets. + NSMutableArray *events = [[NSMutableArray alloc] init]; + NSMutableArray *callbacks = [[NSMutableArray alloc] init]; + + // Ignore, by default, all of the sets in this queue, since we're re-running all of them. However, we want to include + // the results of new sets triggered as part of this re-run, so we don't want to ignore a range, just these specific + // sets. + NSMutableArray *writeIdsToExclude = [[NSMutableArray alloc] init]; + for (FTupleTransaction *transaction in queue) { + [writeIdsToExclude addObject:transaction.currentWriteId]; + } + + for (FTupleTransaction* transaction in queue) { + FPath* relativePath __unused = [FPath relativePathFrom:path to:transaction.path]; + BOOL abortTransaction = NO; + NSAssert(relativePath != nil, @"[FRepo rerunTransactionsQueue:] relativePath should not be null."); + + if (transaction.status == FTransactionNeedsAbort) { + abortTransaction = YES; + if (![transaction.abortStatus isEqualToString:kFErrorWriteCanceled]) { + NSArray *ackEvents = [self.serverSyncTree ackUserWriteWithWriteId:[transaction.currentWriteId integerValue] + revert:YES + persist:NO + clock:self.serverClock]; + [events addObjectsFromArray:ackEvents]; + } + } else if (transaction.status == FTransactionRun) { + if (transaction.retryCount >= kFTransactionMaxRetries) { + abortTransaction = YES; + [transaction setAbortStatus:kFTransactionTooManyRetries reason:nil]; + [events addObjectsFromArray:[self.serverSyncTree ackUserWriteWithWriteId:[transaction.currentWriteId integerValue] + revert:YES + persist:NO + clock:self.serverClock]]; + } else { + // This code reruns a transaction + id currentNode = [self latestStateAtPath:transaction.path excludeWriteIds:writeIdsToExclude]; + transaction.currentInputSnapshot = currentNode; + FIRMutableData * mutableCurrent = [[FIRMutableData alloc] initWithNode:currentNode]; + FIRTransactionResult * result = transaction.update(mutableCurrent); + if (result.isSuccess) { + NSNumber *oldWriteId = transaction.currentWriteId; + NSDictionary* serverValues = [FServerValues generateServerValues:self.serverClock]; + + id newVal = [result.update nodeValue]; + id newValResolved = [FServerValues resolveDeferredValueSnapshot:newVal withServerValues:serverValues]; + + transaction.currentOutputSnapshotRaw = newVal; + transaction.currentOutputSnapshotResolved = newValResolved; + + transaction.currentWriteId = [NSNumber numberWithInteger:[self nextWriteId]]; + // Mutates writeIdsToExclude in place + [writeIdsToExclude removeObject:oldWriteId]; + [events addObjectsFromArray:[self.serverSyncTree applyUserOverwriteAtPath:transaction.path + newData:transaction.currentOutputSnapshotResolved + writeId:[transaction.currentWriteId integerValue] + isVisible:transaction.applyLocally]]; + [events addObjectsFromArray:[self.serverSyncTree ackUserWriteWithWriteId:[oldWriteId integerValue] + revert:YES + persist:NO + clock:self.serverClock]]; + } else { + abortTransaction = YES; + // The user aborted the transaction. JS treats ths as a "nodata" abort, but it's not an error, so we don't send them an error. + [transaction setAbortStatus:nil reason:nil]; + [events addObjectsFromArray:[self.serverSyncTree ackUserWriteWithWriteId:[transaction.currentWriteId integerValue] + revert:YES + persist:NO + clock:self.serverClock]]; + } + } + } + + [self.eventRaiser raiseEvents:events]; + events = nil; + + if (abortTransaction) { + // Abort + transaction.status = FTransactionCompleted; + transaction.unwatcher(); + if (transaction.onComplete) { + FIRDatabaseReference * ref = [[FIRDatabaseReference alloc] initWithRepo:self path:transaction.path]; + FIndexedNode *lastInput = [FIndexedNode indexedNodeWithNode:transaction.currentInputSnapshot]; + FIRDataSnapshot * snap = [[FIRDataSnapshot alloc] initWithRef:ref indexedNode:lastInput]; + fbt_void_void cb = ^{ + // Unlike JS, no need to check for "nodata" because ObjC has abortError = nil + transaction.onComplete(transaction.abortError, NO, snap); + }; + [callbacks addObject:[cb copy]]; + } + } + } + + // Note: unlike current js client, we don't need to preserve priority. Users can set priority via FIRMutableData + + // Clean up completed transactions. + [self pruneCompletedTransactionsBelowNode:self.transactionQueueTree]; + + // Now fire callbacks, now that we're in a good, known state. + [self.eventRaiser raiseCallbacks:callbacks]; + + // Try to send the transaction result to the server + [self sendAllReadyTransactions]; +} + +- (FTree *) getAncestorTransactionNodeForPath:(FPath *)path { + FTree* transactionNode = self.transactionQueueTree; + + while (![path isEmpty] && [transactionNode getValue] == nil) { + NSString* front = [path getFront]; + transactionNode = [transactionNode subTree:[[FPath alloc] initWith:front]]; + path = [path popFront]; + } + + return transactionNode; +} + +- (NSMutableArray *) buildTransactionQueueAtNode:(FTree *)node { + NSMutableArray* queue = [[NSMutableArray alloc] init]; + [self aggregateTransactionQueuesForNode:node andQueue:queue]; + + [queue sortUsingComparator:^NSComparisonResult(FTupleTransaction* obj1, FTupleTransaction* obj2) { + return [obj1.order compare:obj2.order]; + }]; + + return queue; +} + +- (void) aggregateTransactionQueuesForNode:(FTree *)node andQueue:(NSMutableArray *)queue { + NSArray* nodeQueue = [node getValue]; + [queue addObjectsFromArray:nodeQueue]; + + [node forEachChild:^(FTree *child) { + [self aggregateTransactionQueuesForNode:child andQueue:queue]; + }]; +} + +/** + * Remove COMPLETED transactions at or below this node in the transactionQueueTree + */ +- (void) pruneCompletedTransactionsBelowNode:(FTree *)node { + NSMutableArray* queue = [node getValue]; + if (queue != nil) { + int i = 0; + // remove all of the completed transactions from the queue + while (i < queue.count) { + FTupleTransaction* transaction = [queue objectAtIndex:i]; + if (transaction.status == FTransactionCompleted) { + [queue removeObjectAtIndex:i]; + } else { + i++; + } + } + if (queue.count > 0) { + [node setValue:queue]; + } else { + [node setValue:nil]; + } + } + + [node forEachChildMutationSafe:^(FTree *child) { + [self pruneCompletedTransactionsBelowNode:child]; + }]; +} + +/** + * Aborts all transactions on ancestors or descendants of the specified path. Called when doing a setValue: or + * updateChildValues: since we consider them incompatible with transactions + * + * @param path path for which we want to abort related transactions. + */ +- (FPath *) abortTransactionsAtPath:(FPath *)path error:(NSString *)error { + // For the common case that there are no transactions going on, skip all this! + if ([self.transactionQueueTree isEmpty]) { + return path; + } else { + FPath* affectedPath = [self getAncestorTransactionNodeForPath:path].path; + + FTree* transactionNode = [self.transactionQueueTree subTree:path]; + [transactionNode forEachAncestor:^BOOL(FTree *ancestor) { + [self abortTransactionsAtNode:ancestor error:error]; + return NO; + }]; + + [self abortTransactionsAtNode:transactionNode error:error]; + + [transactionNode forEachDescendant:^(FTree *child) { + [self abortTransactionsAtNode:child error:error]; + }]; + + return affectedPath; + } +} + +/** + * Abort transactions stored in this transactions queue node. + * + * @param node Node to abort transactions for. + */ +- (void) abortTransactionsAtNode:(FTree *)node error:(NSString *)error { + NSMutableArray* queue = [node getValue]; + if (queue != nil) { + + // Queue up the callbacks and fire them after cleaning up all of our transaction state, since + // can be immediately aborted and removed. + NSMutableArray* callbacks = [[NSMutableArray alloc] init]; + + // Go through queue. Any already-sent transactions must be marked for abort, while the unsent ones + // can be immediately aborted and removed + NSMutableArray *events = [[NSMutableArray alloc] init]; + int lastSent = -1; + // Note: all of the sent transactions will be at the front of the queue, so safe to increment lastSent + for (FTupleTransaction* transaction in queue) { + if (transaction.status == FTransactionSentNeedsAbort) { + // No-op. already marked. + } else if (transaction.status == FTransactionSent) { + // Mark this transaction for abort when it returns + lastSent++; + transaction.status = FTransactionSentNeedsAbort; + [transaction setAbortStatus:error reason:nil]; + } else { + // we can abort this immediately + transaction.unwatcher(); + if ([error isEqualToString:kFTransactionSet]) { + [events addObjectsFromArray:[self.serverSyncTree ackUserWriteWithWriteId:[transaction.currentWriteId integerValue] + revert:YES + persist:NO + clock:self.serverClock]]; + } else { + // If it was cancelled it was already removed from the sync tree, no need to ack + NSAssert([error isEqualToString:kFErrorWriteCanceled], nil); + } + + if (transaction.onComplete) { + NSError* abortReason = [FUtilities errorForStatus:error andReason:nil]; + FIRDataSnapshot * snapshot = nil; + fbt_void_void cb = ^{ + transaction.onComplete(abortReason, NO, snapshot); + }; + [callbacks addObject:[cb copy]]; + } + } + } + if (lastSent == -1) { + // We're not waiting for any sent transactions. We can clear the queue. + [node setValue:nil]; + } else { + // Remove the transactions we aborted + NSRange theRange; + theRange.location = lastSent + 1; + theRange.length = queue.count - theRange.location; + [queue removeObjectsInRange:theRange]; + } + + // Now fire the callbacks + [self.eventRaiser raiseEvents:events]; + [self.eventRaiser raiseCallbacks:callbacks]; + } +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRepoInfo.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRepoInfo.h new file mode 100644 index 00000000..433bf352 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRepoInfo.h @@ -0,0 +1,38 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@interface FRepoInfo : NSObject + +@property (nonatomic, readonly, strong) NSString* host; +@property (nonatomic, readonly, strong) NSString* namespace; +@property (nonatomic, strong) NSString* internalHost; +@property (nonatomic, readonly) bool secure; + +- (id) initWithHost:(NSString*)host isSecure:(bool)secure withNamespace:(NSString*)namespace; + +- (NSString *) connectionURLWithLastSessionID:(NSString*)lastSessionID; +- (NSString *) connectionURL; +- (void) clearInternalHostCache; +- (BOOL) isDemoHost; +- (BOOL) isCustomHost; + +- (id)copyWithZone:(NSZone *)zone; +- (NSUInteger)hash; +- (BOOL)isEqual:(id)anObject; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRepoInfo.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRepoInfo.m new file mode 100644 index 00000000..925163e8 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRepoInfo.m @@ -0,0 +1,134 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FRepoInfo.h" +#import "FConstants.h" + +@interface FRepoInfo () + +@property (nonatomic, strong) NSString *domain; + +@end + + +@implementation FRepoInfo + +@synthesize namespace; +@synthesize host; +@synthesize internalHost; +@synthesize secure; +@synthesize domain; + +- (id) initWithHost:(NSString*)aHost isSecure:(bool)isSecure withNamespace:(NSString*)aNamespace { + self = [super init]; + if (self) { + host = aHost; + domain = [host substringFromIndex:[host rangeOfString:@"."].location+1]; + secure = isSecure; + namespace = aNamespace; + + // Get cached internal host if it exists + NSString* internalHostKey = [NSString stringWithFormat:@"firebase:host:%@", self.host]; + NSString* cachedInternalHost = [[NSUserDefaults standardUserDefaults] stringForKey:internalHostKey]; + if (cachedInternalHost != nil) { + internalHost = cachedInternalHost; + } else { + internalHost = self.host; + } + } + return self; +} + +- (NSString *)description { + // The namespace is encoded in the hostname, so we can just return this. + return [NSString stringWithFormat:@"http%@://%@", (self.secure ? @"s" : @""), self.host]; +} + +- (void) setInternalHost:(NSString *)newHost { + if (![internalHost isEqualToString:newHost]) { + internalHost = newHost; + + // Cache the internal host so we don't need to redirect later on + NSString* internalHostKey = [NSString stringWithFormat:@"firebase:host:%@", self.host]; + NSUserDefaults* cache = [NSUserDefaults standardUserDefaults]; + [cache setObject:internalHost forKey:internalHostKey]; + [cache synchronize]; + } +} + +- (void) clearInternalHostCache { + internalHost = self.host; + + // Remove the cached entry + NSString* internalHostKey = [NSString stringWithFormat:@"firebase:host:%@", self.host]; + NSUserDefaults* cache = [NSUserDefaults standardUserDefaults]; + [cache removeObjectForKey:internalHostKey]; + [cache synchronize]; +} + +- (BOOL) isDemoHost { + return [self.domain isEqualToString:@"firebaseio-demo.com"]; +} + +- (BOOL) isCustomHost { + return ![self.domain isEqualToString:@"firebaseio-demo.com"] && ![self.domain isEqualToString:@"firebaseio.com"]; +} + + +- (NSString *) connectionURL { + return [self connectionURLWithLastSessionID:nil]; +} + +- (NSString *) connectionURLWithLastSessionID:(NSString*)lastSessionID { + NSString *scheme; + if (self.secure) { + scheme = @"wss"; + } else { + scheme = @"ws"; + } + NSString *url = [NSString stringWithFormat:@"%@://%@/.ws?%@=%@&ns=%@", + scheme, + self.internalHost, + kWireProtocolVersionParam, + kWebsocketProtocolVersion, + self.namespace]; + + if (lastSessionID != nil) { + url = [NSString stringWithFormat:@"%@&ls=%@", url, lastSessionID]; + } + return url; +} + +- (id)copyWithZone:(NSZone *)zone; { + return self; // Immutable +} + +- (NSUInteger)hash { + NSUInteger result = host.hash; + result = 31 * result + (secure ? 1 : 0); + result = 31 * result + namespace.hash; + result = 31 * result + host.hash; + return result; +} + +- (BOOL)isEqual:(id)anObject { + if (![anObject isKindOfClass:[FRepoInfo class]]) return NO; + FRepoInfo *other = (FRepoInfo *)anObject; + return secure == other.secure && [host isEqualToString:other.host] && + [namespace isEqualToString:other.namespace]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRepoManager.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRepoManager.h new file mode 100644 index 00000000..c492861c --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRepoManager.h @@ -0,0 +1,32 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FRepoInfo.h" +#import "FRepo.h" +#import "FIRDatabaseConfig.h" + +@interface FRepoManager : NSObject + ++ (FRepo *) getRepo:(FRepoInfo *)repoInfo config:(FIRDatabaseConfig *)config; ++ (FRepo *) createRepo:(FRepoInfo *)repoInfo config:(FIRDatabaseConfig *)config database:(FIRDatabase *)database; ++ (void) interruptAll; ++ (void) interrupt:(FIRDatabaseConfig *)config; ++ (void) resumeAll; ++ (void) resume:(FIRDatabaseConfig *)config; ++ (void) disposeRepos:(FIRDatabaseConfig *)config; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRepoManager.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRepoManager.m new file mode 100644 index 00000000..31c3efc5 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRepoManager.m @@ -0,0 +1,135 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FRepoManager.h" +#import "FRepo.h" +#import "FIRDatabaseQuery_Private.h" +#import "FAtomicNumber.h" +#import "FIRDatabaseConfig_Private.h" +#import "FIRDatabase_Private.h" + +@implementation FRepoManager + +typedef NSMutableDictionary *> + FRepoDictionary; + ++ (FRepoDictionary *)configs { + static dispatch_once_t pred = 0; + static FRepoDictionary *configs; + dispatch_once(&pred, ^{ + configs = [NSMutableDictionary dictionary]; + }); + return configs; +} + +/** + * Used for legacy unit tests. The public API should go through FirebaseDatabase which + * calls createRepo. + */ ++ (FRepo *) getRepo:(FRepoInfo *)repoInfo config:(FIRDatabaseConfig *)config { + [config freeze]; + FRepoDictionary *configs = [FRepoManager configs]; + @synchronized(configs) { + NSMutableDictionary *repos = configs[config.sessionIdentifier]; + if (!repos || repos[repoInfo] == nil) { + // Calling this should create the repo. + [FIRDatabase createDatabaseForTests:repoInfo config:config]; + } + + return configs[config.sessionIdentifier][repoInfo]; + } +} + ++ (FRepo *) createRepo:(FRepoInfo *)repoInfo config:(FIRDatabaseConfig *)config database:(FIRDatabase *)database { + [config freeze]; + FRepoDictionary *configs = [FRepoManager configs]; + @synchronized(configs) { + NSMutableDictionary *repos = + configs[config.sessionIdentifier]; + if (!repos) { + repos = [NSMutableDictionary dictionary]; + configs[config.sessionIdentifier] = repos; + } + FRepo *repo = repos[repoInfo]; + if (repo == nil) { + repo = [[FRepo alloc] initWithRepoInfo:repoInfo config:config database:database]; + repos[repoInfo] = repo; + return repo; + } else { + [NSException raise:@"RepoExists" format:@"createRepo called for Repo that already exists."]; + return nil; + } + } +} + ++ (void) interrupt:(FIRDatabaseConfig *)config { + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + FRepoDictionary *configs = [FRepoManager configs]; + NSMutableDictionary *repos = configs[config.sessionIdentifier]; + for (FRepo *repo in [repos allValues]) { + [repo interrupt]; + } + }); +} + ++ (void) interruptAll { + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + FRepoDictionary *configs = [FRepoManager configs]; + for (NSMutableDictionary *repos in [configs allValues]) { + for (FRepo *repo in [repos allValues]) { + [repo interrupt]; + } + } + }); +} + ++ (void) resume:(FIRDatabaseConfig *)config { + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + FRepoDictionary *configs = [FRepoManager configs]; + NSMutableDictionary *repos = configs[config.sessionIdentifier]; + for (FRepo *repo in [repos allValues]) { + [repo resume]; + } + }); +} + ++ (void) resumeAll { + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + FRepoDictionary *configs = [FRepoManager configs]; + for (NSMutableDictionary *repos in [configs allValues]) { + for (FRepo *repo in [repos allValues]) { + [repo resume]; + } + } + }); +} + ++ (void)disposeRepos:(FIRDatabaseConfig *)config { + // Do this synchronously to make sure we release our references to LevelDB before returning, allowing LevelDB + // to close and release its exclusive locks. + dispatch_sync([FIRDatabaseQuery sharedQueue], ^{ + FFLog(@"I-RDB040001", @"Disposing all repos for Config with name %@", config.sessionIdentifier); + NSMutableDictionary *configs = [FRepoManager configs]; + for (FRepo* repo in [configs[config.sessionIdentifier] allValues]) { + [repo dispose]; + } + [configs removeObjectForKey:config.sessionIdentifier]; + }); +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRepo_Private.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRepo_Private.h new file mode 100644 index 00000000..109edacc --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FRepo_Private.h @@ -0,0 +1,42 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FRepo.h" +#import "FSparseSnapshotTree.h" + +@class FSyncTree; +@class FAtomicNumber; +@class FEventRaiser; +@class FSnapshotHolder; + +@interface FRepo () + +- (void) runOnDisconnectEvents; + +@property (nonatomic, strong) FRepoInfo* repoInfo; +@property (nonatomic, strong) FPersistentConnection* connection; +@property (nonatomic, strong) FSnapshotHolder* infoData; +@property (nonatomic, strong) FSparseSnapshotTree* onDisconnect; +@property (nonatomic, strong) FEventRaiser *eventRaiser; +@property (nonatomic, strong) FSyncTree *serverSyncTree; + +// For testing. +@property (nonatomic) long dataUpdateCount; +@property (nonatomic) long rangeMergeUpdateCount; + +- (NSInteger)nextWriteId; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FServerValues.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FServerValues.h new file mode 100644 index 00000000..2540c12e --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FServerValues.h @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FSparseSnapshotTree.h" +#import "FNode.h" +#import "FCompoundWrite.h" +#import "FClock.h" + +@interface FServerValues : NSObject + ++ (NSDictionary*) generateServerValues:(id)clock; ++ (id) resolveDeferredValueCompoundWrite:(FCompoundWrite*)write withServerValues:(NSDictionary*)serverValues; ++ (id) resolveDeferredValueSnapshot:(id)node withServerValues:(NSDictionary*)serverValues; ++ (id) resolveDeferredValueTree:(FSparseSnapshotTree*)tree withServerValues:(NSDictionary*)serverValues; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FServerValues.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FServerValues.m new file mode 100644 index 00000000..89ee5d0f --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FServerValues.m @@ -0,0 +1,93 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FServerValues.h" +#import "FConstants.h" +#import "FLeafNode.h" +#import "FChildrenNode.h" +#import "FSnapshotUtilities.h" + +@implementation FServerValues + ++ (NSDictionary*) generateServerValues:(id)clock { + long long millis = (long long)([clock currentTime] * 1000); + return @{ @"timestamp": [NSNumber numberWithLongLong:millis] }; +} + ++ (id) resolveDeferredValue:(id)val withServerValues:(NSDictionary*)serverValues { + if ([val isKindOfClass:[NSDictionary class]]) { + NSDictionary* dict = val; + if (dict[kServerValueSubKey] != nil) { + NSString* serverValueType = [dict objectForKey:kServerValueSubKey]; + if (serverValues[serverValueType] != nil) { + return [serverValues objectForKey:serverValueType]; + } else { + // TODO: Throw unrecognizedServerValue error here + } + } + } + return val; +} + ++ (FCompoundWrite *) resolveDeferredValueCompoundWrite:(FCompoundWrite *)write withServerValues:(NSDictionary *)serverValues { + __block FCompoundWrite *resolved = write; + [write enumerateWrites:^(FPath *path, id node, BOOL *stop) { + id resolvedNode = [FServerValues resolveDeferredValueSnapshot:node withServerValues:serverValues]; + // Node actually changed, use pointer inequality here + if (resolvedNode != node) { + resolved = [resolved addWrite:resolvedNode atPath:path]; + } + }]; + return resolved; +} + ++ (id) resolveDeferredValueTree:(FSparseSnapshotTree*)tree withServerValues:(NSDictionary*)serverValues { + FSparseSnapshotTree* resolvedTree = [[FSparseSnapshotTree alloc] init]; + [tree forEachTreeAtPath:[FPath empty] do:^(FPath* path, id node) { + [resolvedTree rememberData:[FServerValues resolveDeferredValueSnapshot:node withServerValues:serverValues] onPath:path]; + }]; + return resolvedTree; +} + ++ (id) resolveDeferredValueSnapshot:(id)node withServerValues:(NSDictionary*)serverValues { + id priorityVal = [FServerValues resolveDeferredValue:[[node getPriority] val] withServerValues:serverValues]; + id priority = [FSnapshotUtilities nodeFrom:priorityVal]; + + if ([node isLeafNode]) { + id value = [self resolveDeferredValue:[node val] withServerValues:serverValues]; + if (![value isEqual:[node val]] || ![priority isEqual:[node getPriority]]) { + return [[FLeafNode alloc] initWithValue:value withPriority:priority]; + } else { + return node; + } + } else { + __block FChildrenNode* newNode = node; + if (![priority isEqual:[node getPriority]]) { + newNode = [newNode updatePriority:priority]; + } + + [node enumerateChildrenUsingBlock:^(NSString *childKey, id childNode, BOOL *stop) { + id newChildNode = [FServerValues resolveDeferredValueSnapshot:childNode withServerValues:serverValues]; + if (![newChildNode isEqual:childNode]) { + newNode = [newNode updateImmediateChild:childKey withNewChild:newChildNode]; + } + }]; + return newNode; + } +} + +@end + diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSnapshotHolder.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSnapshotHolder.h new file mode 100644 index 00000000..9a1d871a --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSnapshotHolder.h @@ -0,0 +1,27 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FNode.h" + +@interface FSnapshotHolder : NSObject + +- (id) getNode:(FPath *)path; +- (void) updateSnapshot:(FPath *)path withNewSnapshot:(id)newSnapshotNode; + +@property (nonatomic, strong) id rootNode; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSnapshotHolder.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSnapshotHolder.m new file mode 100644 index 00000000..25c46257 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSnapshotHolder.m @@ -0,0 +1,46 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FSnapshotHolder.h" +#import "FEmptyNode.h" + +@interface FSnapshotHolder() + + +@end + +@implementation FSnapshotHolder + +@synthesize rootNode; + +- (id)init +{ + self = [super init]; + if (self) { + self.rootNode = [FEmptyNode emptyNode]; + } + return self; +} + +- (id) getNode:(FPath *)path { + return [self.rootNode getChild:path]; +} + +- (void) updateSnapshot:(FPath *)path withNewSnapshot:(id)newSnapshotNode { + self.rootNode = [self.rootNode updateChild:path withNewChild:newSnapshotNode]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSparseSnapshotTree.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSparseSnapshotTree.h new file mode 100644 index 00000000..b860c9d0 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSparseSnapshotTree.h @@ -0,0 +1,34 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FNode.h" +#import "FPath.h" +#import "FTypedefs_Private.h" + +@class FSparseSnapshotTree; + +typedef void (^fbt_void_nsstring_sstree) (NSString*, FSparseSnapshotTree*); + +@interface FSparseSnapshotTree : NSObject + +- (id) findPath:(FPath *)path; +- (void) rememberData:(id)data onPath:(FPath *)path; +- (BOOL) forgetPath:(FPath *)path; +- (void) forEachTreeAtPath:(FPath *)prefixPath do:(fbt_void_path_node)func; +- (void) forEachChild:(fbt_void_nsstring_sstree)func; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSparseSnapshotTree.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSparseSnapshotTree.m new file mode 100644 index 00000000..1f16888c --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSparseSnapshotTree.m @@ -0,0 +1,144 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FSparseSnapshotTree.h" +#import "FChildrenNode.h" + +@interface FSparseSnapshotTree () { + id value; + NSMutableDictionary* children; +} + +@end + +@implementation FSparseSnapshotTree + +- (id) init { + self = [super init]; + if (self) { + value = nil; + children = nil; + } + return self; +} + +- (id) findPath:(FPath *)path { + if (value != nil) { + return [value getChild:path]; + } else if (![path isEmpty] && children != nil) { + NSString* childKey = [path getFront]; + path = [path popFront]; + FSparseSnapshotTree* childTree = children[childKey]; + if (childTree != nil) { + return [childTree findPath:path]; + } else { + return nil; + } + } else { + return nil; + } +} + +- (void) rememberData:(id)data onPath:(FPath *)path { + if ([path isEmpty]) { + value = data; + children = nil; + } else if (value != nil) { + value = [value updateChild:path withNewChild:data]; + } else { + if (children == nil) { + children = [[NSMutableDictionary alloc] init]; + } + + NSString* childKey = [path getFront]; + if (children[childKey] == nil) { + children[childKey] = [[FSparseSnapshotTree alloc] init]; + } + + FSparseSnapshotTree* child = children[childKey]; + path = [path popFront]; + [child rememberData:data onPath:path]; + } +} + +- (BOOL) forgetPath:(FPath *)path { + if ([path isEmpty]) { + value = nil; + children = nil; + return YES; + } else { + if (value != nil) { + if ([value isLeafNode]) { + // non-empty path at leaf. the path leads to nowhere + return NO; + } else { + id tmp = value; + value = nil; + + [tmp enumerateChildrenUsingBlock:^(NSString *key, id node, BOOL *stop) { + [self rememberData:node onPath:[[FPath alloc] initWith:key]]; + }]; + + // we've cleared out the value and set children. Call ourself again to hit the next case + return [self forgetPath:path]; + } + } else if (children != nil) { + NSString* childKey = [path getFront]; + path = [path popFront]; + + if (children[childKey] != nil) { + FSparseSnapshotTree* child = children[childKey]; + BOOL safeToRemove = [child forgetPath:path]; + if (safeToRemove) { + [children removeObjectForKey:childKey]; + } + } + + if ([children count] == 0) { + children = nil; + return YES; + } else { + return NO; + } + } else { + return YES; + } + } +} + +- (void) forEachTreeAtPath:(FPath *)prefixPath do:(fbt_void_path_node)func { + if (value != nil) { + func(prefixPath, value); + } else { + [self forEachChild:^(NSString* key, FSparseSnapshotTree* tree) { + FPath* path = [prefixPath childFromString:key]; + [tree forEachTreeAtPath:path do:func]; + }]; + } +} + + +- (void) forEachChild:(fbt_void_nsstring_sstree)func { + if (children != nil) { + for (NSString* key in children) { + FSparseSnapshotTree* tree = [children objectForKey:key]; + func(key, tree); + } + } +} + + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSyncPoint.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSyncPoint.h new file mode 100644 index 00000000..4e5a4e28 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSyncPoint.h @@ -0,0 +1,66 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@protocol FOperation; +@class FWriteTreeRef; +@protocol FNode; +@protocol FEventRegistration; +@class FQuerySpec; +@class FChildrenNode; +@class FTupleRemovedQueriesEvents; +@class FView; +@class FPath; +@class FCacheNode; +@class FPersistenceManager; + +@interface FSyncPoint : NSObject + +- (id)initWithPersistenceManager:(FPersistenceManager *)persistence; + +- (BOOL) isEmpty; + +/** +* Returns array of FEvent +*/ +- (NSArray *) applyOperation:(id)operation writesCache:(FWriteTreeRef *)writesCache serverCache:(id)optCompleteServerCache; + +/** +* Returns array of FEvent +*/ +- (NSArray *) addEventRegistration:(id )eventRegistration + forNonExistingViewForQuery:(FQuerySpec *)query + writesCache:(FWriteTreeRef *)writesCache + serverCache:(FCacheNode *)serverCache; + +- (NSArray *) addEventRegistration:(id )eventRegistration + forExistingViewForQuery:(FQuerySpec *)query; + +- (FTupleRemovedQueriesEvents *) removeEventRegistration:(id )eventRegistration + forQuery:(FQuerySpec *)query + cancelError:(NSError *)cancelError; +/** +* Returns array of FViews +*/ +- (NSArray *) queryViews; +- (id) completeServerCacheAtPath:(FPath *)path; +- (FView *) viewForQuery:(FQuerySpec *)query; +- (BOOL) viewExistsForQuery:(FQuerySpec *)query; +- (BOOL) hasCompleteView; +- (FView *) completeView; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSyncPoint.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSyncPoint.m new file mode 100644 index 00000000..cd429f18 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSyncPoint.m @@ -0,0 +1,257 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FSyncPoint.h" +#import "FOperation.h" +#import "FWriteTreeRef.h" +#import "FNode.h" +#import "FEventRegistration.h" +#import "FIRDatabaseQuery.h" +#import "FChildrenNode.h" +#import "FTupleRemovedQueriesEvents.h" +#import "FView.h" +#import "FOperationSource.h" +#import "FQuerySpec.h" +#import "FQueryParams.h" +#import "FPath.h" +#import "FEmptyNode.h" +#import "FViewCache.h" +#import "FCacheNode.h" +#import "FPersistenceManager.h" +#import "FDataEvent.h" + +/** +* SyncPoint represents a single location in a SyncTree with 1 or more event registrations, meaning we need to +* maintain 1 or more Views at this location to cache server data and raise appropriate events for server changes +* and user writes (set, transaction, update). +* +* It's responsible for: +* - Maintaining the set of 1 or more views necessary at this location (a SyncPoint with 0 views should be removed). +* - Proxying user / server operations to the views as appropriate (i.e. applyServerOverwrite, +* applyUserOverwrite, etc.) +*/ +@interface FSyncPoint () +/** +* The Views being tracked at this location in the tree, stored as a map where the key is a +* queryParams and the value is the View for that query. +* +* NOTE: This list will be quite small (usually 1, but perhaps 2 or 3; any more is an odd use case). +* +* Maps NSString -> FView +*/ +@property (nonatomic, strong) NSMutableDictionary *views; + +@property (nonatomic, strong) FPersistenceManager *persistenceManager; +@end + +@implementation FSyncPoint + +- (id) initWithPersistenceManager:(FPersistenceManager *)persistence { + self = [super init]; + if (self) { + self.persistenceManager = persistence; + self.views = [[NSMutableDictionary alloc] init]; + } + return self; +} + +- (BOOL) isEmpty { + return [self.views count] == 0; +} + +- (NSArray *) applyOperation:(id)operation + toView:(FView *)view + writesCache:(FWriteTreeRef *)writesCache + serverCache:(id)optCompleteServerCache { + FViewOperationResult *result = [view applyOperation:operation writesCache:writesCache serverCache:optCompleteServerCache]; + if (!view.query.loadsAllData) { + NSMutableSet *removed = [NSMutableSet set]; + NSMutableSet *added = [NSMutableSet set]; + [result.changes enumerateObjectsUsingBlock:^(FChange *change, NSUInteger idx, BOOL *stop) { + if (change.type == FIRDataEventTypeChildAdded) { + [added addObject:change.childKey]; + } else if (change.type == FIRDataEventTypeChildRemoved) { + [removed addObject:change.childKey]; + } + }]; + if ([removed count] > 0 || [added count] > 0) { + [self.persistenceManager updateTrackedQueryKeysWithAddedKeys:added removedKeys:removed forQuery:view.query]; + } + } + return result.events; +} + +- (NSArray *) applyOperation:(id )operation writesCache:(FWriteTreeRef *)writesCache serverCache:(id )optCompleteServerCache { + FQueryParams *queryParams = operation.source.queryParams; + if (queryParams != nil) { + FView *view = [self.views objectForKey:queryParams]; + NSAssert(view != nil, @"SyncTree gave us an op for an invalid query."); + return [self applyOperation:operation toView:view writesCache:writesCache serverCache:optCompleteServerCache]; + } else { + NSMutableArray *events = [[NSMutableArray alloc] init]; + [self.views enumerateKeysAndObjectsUsingBlock:^(FQueryParams *key, FView *view, BOOL *stop) { + NSArray *eventsForView = [self applyOperation:operation toView:view writesCache:writesCache serverCache:optCompleteServerCache]; + [events addObjectsFromArray:eventsForView]; + }]; + return events; + } +} + +/** +* Add an event callback for the specified query +* Returns Array of FEvent events to raise. +*/ +- (NSArray *) addEventRegistration:(id )eventRegistration + forNonExistingViewForQuery:(FQuerySpec *)query + writesCache:(FWriteTreeRef *)writesCache + serverCache:(FCacheNode *)serverCache { + NSAssert(self.views[query.params] == nil, @"Found view for query: %@", query.params); + // TODO: make writesCache take flag for complete server node + id eventCache = [writesCache calculateCompleteEventCacheWithCompleteServerCache:serverCache.isFullyInitialized ? serverCache.node : nil]; + BOOL eventCacheComplete; + if (eventCache != nil) { + eventCacheComplete = YES; + } else { + eventCache = [writesCache calculateCompleteEventChildrenWithCompleteServerChildren:serverCache.node]; + eventCacheComplete = NO; + } + + FIndexedNode *indexed = [FIndexedNode indexedNodeWithNode:eventCache index:query.index]; + FCacheNode *eventCacheNode = [[FCacheNode alloc] initWithIndexedNode:indexed + isFullyInitialized:eventCacheComplete + isFiltered:NO]; + FViewCache *viewCache = [[FViewCache alloc] initWithEventCache:eventCacheNode serverCache:serverCache]; + FView *view = [[FView alloc] initWithQuery:query initialViewCache:viewCache]; + // If this is a non-default query we need to tell persistence our current view of the data + if (!query.loadsAllData) { + NSMutableSet *allKeys = [NSMutableSet set]; + [view.eventCache enumerateChildrenUsingBlock:^(NSString *key, id node, BOOL *stop) { + [allKeys addObject:key]; + }]; + [self.persistenceManager setTrackedQueryKeys:allKeys forQuery:query]; + } + self.views[query.params] = view; + return [self addEventRegistration:eventRegistration forExistingViewForQuery:query]; +} + +- (NSArray *)addEventRegistration:(id)eventRegistration + forExistingViewForQuery:(FQuerySpec *)query { + FView *view = self.views[query.params]; + NSAssert(view != nil, @"No view for query: %@", query); + [view addEventRegistration:eventRegistration]; + return [view initialEvents:eventRegistration]; +} + +/** +* Remove event callback(s). Return cancelEvents if a cancelError is specified. +* +* If query is the default query, we'll check all views for the specified eventRegistration. +* If eventRegistration is nil, we'll remove all callbacks for the specified view(s). +* +* @return FTupleRemovedQueriesEvents removed queries and any cancel events +*/ +- (FTupleRemovedQueriesEvents *) removeEventRegistration:(id )eventRegistration + forQuery:(FQuerySpec *)query + cancelError:(NSError *)cancelError { + NSMutableArray *removedQueries = [[NSMutableArray alloc] init]; + __block NSMutableArray *cancelEvents = [[NSMutableArray alloc] init]; + BOOL hadCompleteView = [self hasCompleteView]; + if ([query isDefault]) { + // When you do [ref removeObserverWithHandle:], we search all views for the registration to remove. + [self.views enumerateKeysAndObjectsUsingBlock:^(FQueryParams *viewQueryParams, FView *view, BOOL *stop) { + [cancelEvents addObjectsFromArray:[view removeEventRegistration:eventRegistration cancelError:cancelError]]; + if ([view isEmpty]) { + [self.views removeObjectForKey:viewQueryParams]; + + // We'll deal with complete views later + if (![view.query loadsAllData]) { + [removedQueries addObject:view.query]; + } + } + }]; + } else { + // remove the callback from the specific view + FView *view = [self.views objectForKey:query.params]; + if (view != nil) { + [cancelEvents addObjectsFromArray:[view removeEventRegistration:eventRegistration cancelError:cancelError]]; + + if ([view isEmpty]) { + [self.views removeObjectForKey:query.params]; + + // We'll deal with complete views later + if (![view.query loadsAllData]) { + [removedQueries addObject:view.query]; + } + } + } + } + + if (hadCompleteView && ![self hasCompleteView]) { + // We removed our last complete view + [removedQueries addObject:[FQuerySpec defaultQueryAtPath:query.path]]; + } + + return [[FTupleRemovedQueriesEvents alloc] initWithRemovedQueries:removedQueries cancelEvents:cancelEvents]; +} + +- (NSArray *) queryViews { + __block NSMutableArray *filteredViews = [[NSMutableArray alloc] init]; + + [self.views enumerateKeysAndObjectsUsingBlock:^(FQueryParams *key, FView *view, BOOL *stop) { + if (![view.query loadsAllData]) { + [filteredViews addObject:view]; + } + }]; + + return filteredViews; +} + +- (id ) completeServerCacheAtPath:(FPath *)path { + __block id serverCache = nil; + [self.views enumerateKeysAndObjectsUsingBlock:^(FQueryParams *key, FView *view, BOOL *stop) { + serverCache = [view completeServerCacheFor:path]; + *stop = (serverCache != nil); + }]; + return serverCache; +} + +- (FView *) viewForQuery:(FQuerySpec *)query { + return [self.views objectForKey:query.params]; +} + +- (BOOL) viewExistsForQuery:(FQuerySpec *)query { + return [self viewForQuery:query] != nil; +} + +- (BOOL) hasCompleteView { + return [self completeView] != nil; +} + +- (FView *) completeView { + __block FView *completeView = nil; + + [self.views enumerateKeysAndObjectsUsingBlock:^(FQueryParams *key, FView *view, BOOL *stop) { + if ([view.query loadsAllData]) { + completeView = view; + *stop = YES; + } + }]; + + return completeView; +} + + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSyncTree.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSyncTree.h new file mode 100644 index 00000000..887f7219 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSyncTree.h @@ -0,0 +1,61 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class FListenProvider; +@protocol FNode; +@class FPath; +@protocol FEventRegistration; +@protocol FPersistedServerCache; +@class FQuerySpec; +@class FCompoundWrite; +@class FPersistenceManager; +@class FCompoundHash; +@protocol FClock; + +@protocol FSyncTreeHash + +- (NSString *)simpleHash; +- (FCompoundHash *)compoundHash; +- (BOOL)includeCompoundHash; + +@end + +@interface FSyncTree : NSObject + +- (id) initWithListenProvider:(FListenProvider *)provider; +- (id) initWithPersistenceManager:(FPersistenceManager *)persistenceManager + listenProvider:(FListenProvider *)provider; + +// These methods all return NSArray of FEvent +- (NSArray *) applyUserOverwriteAtPath:(FPath *)path newData:(id )newData writeId:(NSInteger)writeId isVisible:(BOOL)visible; +- (NSArray *) applyUserMergeAtPath:(FPath *)path changedChildren:(FCompoundWrite *)changedChildren writeId:(NSInteger)writeId; +- (NSArray *) ackUserWriteWithWriteId:(NSInteger)writeId revert:(BOOL)revert persist:(BOOL)persist clock:(id)clock; +- (NSArray *) applyServerOverwriteAtPath:(FPath *)path newData:(id)newData; +- (NSArray *) applyServerMergeAtPath:(FPath *)path changedChildren:(FCompoundWrite *)changedChildren; +- (NSArray *) applyServerRangeMergeAtPath:(FPath *)path updates:(NSArray *)ranges; +- (NSArray *) applyTaggedQueryOverwriteAtPath:(FPath *)path newData:(id )newData tagId:(NSNumber *)tagId; +- (NSArray *) applyTaggedQueryMergeAtPath:(FPath *)path changedChildren:(FCompoundWrite *)changedChildren tagId:(NSNumber *)tagId; +- (NSArray *) applyTaggedServerRangeMergeAtPath:(FPath *)path updates:(NSArray *)ranges tagId:(NSNumber *)tagId; +- (NSArray *) addEventRegistration:(id)eventRegistration forQuery:(FQuerySpec *)query; +- (NSArray *) removeEventRegistration:(id )eventRegistration forQuery:(FQuerySpec *)query cancelError:(NSError *)cancelError; +- (void)keepQuery:(FQuerySpec *)query synced:(BOOL)keepSynced; +- (NSArray *) removeAllWrites; + +- (id) calcCompleteEventCacheAtPath:(FPath *)path excludeWriteIds:(NSArray *)writeIdsToExclude; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSyncTree.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSyncTree.m new file mode 100644 index 00000000..688a43b2 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FSyncTree.m @@ -0,0 +1,818 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FSyncTree.h" +#import "FListenProvider.h" +#import "FWriteTree.h" +#import "FNode.h" +#import "FPath.h" +#import "FEventRegistration.h" +#import "FImmutableTree.h" +#import "FOperation.h" +#import "FWriteTreeRef.h" +#import "FOverwrite.h" +#import "FOperationSource.h" +#import "FMerge.h" +#import "FAckUserWrite.h" +#import "FView.h" +#import "FSyncPoint.h" +#import "FEmptyNode.h" +#import "FQueryParams.h" +#import "FQuerySpec.h" +#import "FSnapshotHolder.h" +#import "FChildrenNode.h" +#import "FTupleRemovedQueriesEvents.h" +#import "FAtomicNumber.h" +#import "FEventRaiser.h" +#import "FListenComplete.h" +#import "FSnapshotUtilities.h" +#import "FCacheNode.h" +#import "FUtilities.h" +#import "FCompoundWrite.h" +#import "FWriteRecord.h" +#import "FPersistenceManager.h" +#import "FKeepSyncedEventRegistration.h" +#import "FServerValues.h" +#import "FCompoundHash.h" +#import "FRangeMerge.h" + +// Size after which we start including the compound hash +static const NSUInteger kFSizeThresholdForCompoundHash = 1024; + +@interface FListenContainer : NSObject + +@property (nonatomic, strong) FView *view; +@property (nonatomic, copy) fbt_nsarray_nsstring onComplete; + +@end + +@implementation FListenContainer + +- (instancetype)initWithView:(FView *)view onComplete:(fbt_nsarray_nsstring)onComplete { + self = [super init]; + if (self != nil) { + self->_view = view; + self->_onComplete = onComplete; + } + return self; +} + +- (id)serverCache { + return self.view.serverCache; +} + +- (FCompoundHash *)compoundHash { + return [FCompoundHash fromNode:[self serverCache]]; +} + +- (NSString *)simpleHash { + return [[self serverCache] dataHash]; +} + +- (BOOL)includeCompoundHash { + return [FSnapshotUtilities estimateSerializedNodeSize:[self serverCache]] > kFSizeThresholdForCompoundHash; +} + +@end + +@interface FSyncTree () + +/** +* Tree of SyncPoints. There's a SyncPoint at any location that has 1 or more views. +*/ +@property (nonatomic, strong) FImmutableTree *syncPointTree; + +/** +* A tree of all pending user writes (user-initiated set, transactions, updates, etc) +*/ +@property (nonatomic, strong) FWriteTree *pendingWriteTree; + +/** +* Maps tagId -> FTuplePathQueryParams +*/ +@property (nonatomic, strong) NSMutableDictionary *tagToQueryMap; +@property (nonatomic, strong) NSMutableDictionary *queryToTagMap; +@property (nonatomic, strong) FListenProvider *listenProvider; +@property (nonatomic, strong) FPersistenceManager *persistenceManager; +@property (nonatomic, strong) FAtomicNumber *queryTagCounter; +@property (nonatomic, strong) NSMutableSet *keepSyncedQueries; + +@end + +/** +* SyncTree is the central class for managing event callback registration, data caching, views +* (query processing), and event generation. There are typically two SyncTree instances for +* each Repo, one for the normal Firebase data, and one for the .info data. +* +* It has a number of responsibilities, including: +* - Tracking all user event callbacks (registered via addEventRegistration: and removeEventRegistration:). +* - Applying and caching data changes for user setValue:, runTransactionBlock:, and updateChildValues: calls +* (applyUserOverwriteAtPath:, applyUserMergeAtPath:). +* - Applying and caching data changes for server data changes (applyServerOverwriteAtPath:, +* applyServerMergeAtPath:). +* - Generating user-facing events for server and user changes (all of the apply* methods +* return the set of events that need to be raised as a result). +* - Maintaining the appropriate set of server listens to ensure we are always subscribed +* to the correct set of paths and queries to satisfy the current set of user event +* callbacks (listens are started/stopped using the provided listenProvider). +* +* NOTE: Although SyncTree tracks event callbacks and calculates events to raise, the actual +* events are returned to the caller rather than raised synchronously. +*/ +@implementation FSyncTree + +- (id) initWithListenProvider:(FListenProvider *)provider { + return [self initWithPersistenceManager:nil listenProvider:provider]; +} + +- (id) initWithPersistenceManager:(FPersistenceManager *)persistenceManager listenProvider:(FListenProvider *)provider { + self = [super init]; + if (self) { + self.syncPointTree = [FImmutableTree empty]; + self.pendingWriteTree = [[FWriteTree alloc] init]; + self.tagToQueryMap = [[NSMutableDictionary alloc] init]; + self.queryToTagMap = [[NSMutableDictionary alloc] init]; + self.listenProvider = provider; + self.persistenceManager = persistenceManager; + self.queryTagCounter = [[FAtomicNumber alloc] init]; + self.keepSyncedQueries = [NSMutableSet set]; + } + return self; +} + +#pragma mark - +#pragma mark Apply Operations + +/** +* Apply data changes for a user-generated setValue: runTransactionBlock: updateChildValues:, etc. +* @return NSArray of FEvent to raise. +*/ +- (NSArray *) applyUserOverwriteAtPath:(FPath *)path newData:(id )newData writeId:(NSInteger)writeId isVisible:(BOOL)visible { + // Record pending write + [self.pendingWriteTree addOverwriteAtPath:path newData:newData writeId:writeId isVisible:visible]; + if (!visible) { + return @[]; + } else { + FOverwrite *operation = [[FOverwrite alloc] initWithSource:[FOperationSource userInstance] path:path snap:newData]; + return [self applyOperationToSyncPoints:operation]; + } +} + +/** +* Apply the data from a user-generated updateChildValues: call +* @return NSArray of FEvent to raise. +*/ +- (NSArray *) applyUserMergeAtPath:(FPath *)path changedChildren:(FCompoundWrite *)changedChildren writeId:(NSInteger)writeId { + // Record pending merge + [self.pendingWriteTree addMergeAtPath:path changedChildren:changedChildren writeId:writeId]; + + FMerge *operation = [[FMerge alloc] initWithSource:[FOperationSource userInstance] path:path children:changedChildren]; + return [self applyOperationToSyncPoints:operation]; +} + +/** + * Acknowledge a pending user write that was previously registered with applyUserOverwriteAtPath: or applyUserMergeAtPath: + * TODO[offline]: Taking a serverClock here is awkward, but server values are awkward. :-( + * @return NSArray of FEvent to raise. + */ +- (NSArray *) ackUserWriteWithWriteId:(NSInteger)writeId revert:(BOOL)revert persist:(BOOL)persist clock:(id)clock { + FWriteRecord *write = [self.pendingWriteTree writeForId:writeId]; + BOOL needToReevaluate = [self.pendingWriteTree removeWriteId:writeId]; + if (write.visible) { + if (persist) { + [self.persistenceManager removeUserWrite:writeId]; + } + if (!revert) { + NSDictionary *serverValues = [FServerValues generateServerValues:clock]; + if ([write isOverwrite]) { + id resolvedNode = [FServerValues resolveDeferredValueSnapshot:write.overwrite withServerValues:serverValues]; + [self.persistenceManager applyUserWrite:resolvedNode toServerCacheAtPath:write.path]; + } else { + FCompoundWrite *resolvedMerge = [FServerValues resolveDeferredValueCompoundWrite:write.merge withServerValues:serverValues]; + [self.persistenceManager applyUserMerge:resolvedMerge toServerCacheAtPath:write.path]; + } + } + } + if (!needToReevaluate) { + return @[]; + } else { + __block FImmutableTree *affectedTree = [FImmutableTree empty]; + if (write.isOverwrite) { + affectedTree = [affectedTree setValue:@YES atPath:[FPath empty]]; + } else { + [write.merge enumerateWrites:^(FPath *path, id node, BOOL *stop) { + affectedTree = [affectedTree setValue:@YES atPath:path]; + }]; + } + FAckUserWrite *operation = [[FAckUserWrite alloc] initWithPath:write.path affectedTree:affectedTree revert:revert]; + return [self applyOperationToSyncPoints:operation]; + } +} + +/** +* Apply new server data for the specified path +* @return NSArray of FEvent to raise. +*/ +- (NSArray *) applyServerOverwriteAtPath:(FPath *)path newData:(id )newData { + [self.persistenceManager updateServerCacheWithNode:newData forQuery:[FQuerySpec defaultQueryAtPath:path]]; + FOverwrite *operation = [[FOverwrite alloc] initWithSource:[FOperationSource serverInstance] path:path snap:newData]; + return [self applyOperationToSyncPoints:operation]; +} + +/** +* Applied new server data to be merged in at the specified path +* @return NSArray of FEvent to raise. +*/ +- (NSArray *) applyServerMergeAtPath:(FPath *)path changedChildren:(FCompoundWrite *)changedChildren { + [self.persistenceManager updateServerCacheWithMerge:changedChildren atPath:path]; + FMerge *operation = [[FMerge alloc] initWithSource:[FOperationSource serverInstance] path:path children:changedChildren]; + return [self applyOperationToSyncPoints:operation]; +} + +- (NSArray *) applyServerRangeMergeAtPath:(FPath *)path updates:(NSArray *)ranges { + FSyncPoint *syncPoint = [self.syncPointTree valueAtPath:path]; + if (syncPoint == nil) { + // Removed view, so it's safe to just ignore this update + return @[]; + } else { + // This could be for any "complete" (unfiltered) view, and if there is more than one complete view, they should + // each have the same cache so it doesn't matter which one we use. + FView *view = [syncPoint completeView]; + if (view != nil) { + id serverNode = [view serverCache]; + for (FRangeMerge *merge in ranges) { + serverNode = [merge applyToNode:serverNode]; + } + return [self applyServerOverwriteAtPath:path newData:serverNode]; + } else { + // There doesn't exist a view for this update, so it was removed and it's safe to just ignore this range + // merge + return @[]; + } + } +} + +/** +* Apply a listen complete to a path +* @return NSArray of FEvent to raise. +*/ +- (NSArray *) applyListenCompleteAtPath:(FPath *)path { + [self.persistenceManager setQueryComplete:[FQuerySpec defaultQueryAtPath:path]]; + id operation = [[FListenComplete alloc] initWithSource:[FOperationSource serverInstance] path:path]; + return [self applyOperationToSyncPoints:operation]; +} + +/** +* Apply a listen complete to a path +* @return NSArray of FEvent to raise. +*/ +- (NSArray *) applyTaggedListenCompleteAtPath:(FPath *)path tagId:(NSNumber *)tagId { + FQuerySpec *query = [self queryForTag:tagId]; + if (query != nil) { + [self.persistenceManager setQueryComplete:query]; + FPath *relativePath = [FPath relativePathFrom:query.path to:path]; + id op = [[FListenComplete alloc] initWithSource:[FOperationSource forServerTaggedQuery:query.params] + path:relativePath]; + return [self applyTaggedOperation:op atPath:query.path]; + } else { + // We've already removed the query. No big deal, ignore the update. + return @[]; + } +} + +/** +* Internal helper method to apply tagged operation +*/ +- (NSArray *) applyTaggedOperation:(id)operation atPath:(FPath *)path { + FSyncPoint *syncPoint = [self.syncPointTree valueAtPath:path]; + NSAssert(syncPoint != nil, @"Missing sync point for query tag that we're tracking."); + FWriteTreeRef *writesCache = [self.pendingWriteTree childWritesForPath:path]; + return [syncPoint applyOperation:operation writesCache:writesCache serverCache:nil]; +} + +/** +* Apply new server data for the specified tagged query +* @return NSArray of FEvent to raise. +*/ +- (NSArray *) applyTaggedQueryOverwriteAtPath:(FPath *)path newData:(id )newData tagId:(NSNumber *)tagId { + FQuerySpec *query = [self queryForTag:tagId]; + if (query != nil) { + FPath *relativePath = [FPath relativePathFrom:query.path to:path]; + FQuerySpec *queryToOverwrite = relativePath.isEmpty ? query : [FQuerySpec defaultQueryAtPath:path]; + [self.persistenceManager updateServerCacheWithNode:newData forQuery:queryToOverwrite]; + FOverwrite *operation = [[FOverwrite alloc] initWithSource:[FOperationSource forServerTaggedQuery:query.params] + path:relativePath snap:newData]; + return [self applyTaggedOperation:operation atPath:query.path]; + } else { + // Query must have been removed already + return @[]; + } +} + +/** +* Apply server data to be merged in for the specified tagged query +* @return NSArray of FEvent to raise. +*/ +- (NSArray *) applyTaggedQueryMergeAtPath:(FPath *)path changedChildren:(FCompoundWrite *)changedChildren tagId:(NSNumber *)tagId { + FQuerySpec *query = [self queryForTag:tagId]; + if (query != nil) { + FPath *relativePath = [FPath relativePathFrom:query.path to:path]; + [self.persistenceManager updateServerCacheWithMerge:changedChildren atPath:path]; + FMerge *operation = [[FMerge alloc] initWithSource:[FOperationSource forServerTaggedQuery:query.params] + path:relativePath + children:changedChildren]; + return [self applyTaggedOperation:operation atPath:query.path]; + } else { + // We've already removed the query. No big deal, ignore the update. + return @[]; + } +} + +- (NSArray *) applyTaggedServerRangeMergeAtPath:(FPath *)path updates:(NSArray *)ranges tagId:(NSNumber *)tagId { + FQuerySpec *query = [self queryForTag:tagId]; + if (query != nil) { + NSAssert([path isEqual:query.path], @"Tagged update path and query path must match"); + FSyncPoint *syncPoint = [self.syncPointTree valueAtPath:path]; + NSAssert(syncPoint != nil, @"Missing sync point for query tag that we're tracking."); + FView *view = [syncPoint viewForQuery:query]; + NSAssert(view != nil, @"Missing view for query tag that we're tracking"); + id serverNode = [view serverCache]; + for (FRangeMerge *merge in ranges) { + serverNode = [merge applyToNode:serverNode]; + } + return [self applyTaggedQueryOverwriteAtPath:path newData:serverNode tagId:tagId]; + } else { + // We've already removed the query. No big deal, ignore the update. + return @[]; + } +} + +/** +* Add an event callback for the specified query +* @return NSArray of FEvent to raise. +*/ +- (NSArray *) addEventRegistration:(id)eventRegistration forQuery:(FQuerySpec *)query { + FPath *path = query.path; + + __block BOOL foundAncestorDefaultView = NO; + [self.syncPointTree forEachOnPath:query.path whileBlock:^BOOL(FPath *pathToSyncPoint, FSyncPoint *syncPoint) { + foundAncestorDefaultView = foundAncestorDefaultView || [syncPoint hasCompleteView]; + return !foundAncestorDefaultView; + }]; + + [self.persistenceManager setQueryActive:query]; + + FSyncPoint *syncPoint = [self.syncPointTree valueAtPath:path]; + if (syncPoint == nil) { + syncPoint = [[FSyncPoint alloc] initWithPersistenceManager:self.persistenceManager]; + self.syncPointTree = [self.syncPointTree setValue:syncPoint atPath:path]; + } + + BOOL viewAlreadyExists = [syncPoint viewExistsForQuery:query]; + NSArray *events; + if (viewAlreadyExists) { + events = [syncPoint addEventRegistration:eventRegistration forExistingViewForQuery:query]; + } else { + if (![query loadsAllData]) { + // We need to track a tag for this query + NSAssert(self.queryToTagMap[query] == nil, @"View does not exist, but we have a tag"); + NSNumber *tagId = [self.queryTagCounter getAndIncrement]; + self.queryToTagMap[query] = tagId; + self.tagToQueryMap[tagId] = query; + } + + FWriteTreeRef *writesCache = [self.pendingWriteTree childWritesForPath:path]; + FCacheNode *serverCache = [self serverCacheForQuery:query]; + events = [syncPoint addEventRegistration:eventRegistration + forNonExistingViewForQuery:query + writesCache:writesCache + serverCache:serverCache]; + + // There was no view and no default listen + if (!foundAncestorDefaultView) { + FView *view = [syncPoint viewForQuery:query]; + NSMutableArray *mutableEvents = [events mutableCopy]; + [mutableEvents addObjectsFromArray:[self setupListenerOnQuery:query view:view]]; + events = mutableEvents; + } + } + + return events; +} + +- (FCacheNode *)serverCacheForQuery:(FQuerySpec *)query { + __block id serverCacheNode = nil; + + [self.syncPointTree forEachOnPath:query.path whileBlock:^BOOL(FPath *pathToSyncPoint, FSyncPoint *syncPoint) { + FPath *relativePath = [FPath relativePathFrom:pathToSyncPoint to:query.path]; + serverCacheNode = [syncPoint completeServerCacheAtPath:relativePath]; + return serverCacheNode == nil; + }]; + + FCacheNode *serverCache; + if (serverCacheNode != nil) { + FIndexedNode *indexed = [FIndexedNode indexedNodeWithNode:serverCacheNode index:query.index]; + serverCache = [[FCacheNode alloc] initWithIndexedNode:indexed isFullyInitialized:YES isFiltered:NO]; + } else { + FCacheNode *persistenceServerCache = [self.persistenceManager serverCacheForQuery:query]; + if (persistenceServerCache.isFullyInitialized) { + serverCache = persistenceServerCache; + } else { + serverCacheNode = [FEmptyNode emptyNode]; + + FImmutableTree *subtree = [self.syncPointTree subtreeAtPath:query.path]; + [subtree forEachChild:^(NSString *childKey, FSyncPoint *childSyncPoint) { + id completeCache = [childSyncPoint completeServerCacheAtPath:[FPath empty]]; + if (completeCache) { + serverCacheNode = [serverCacheNode updateImmediateChild:childKey withNewChild:completeCache]; + } + }]; + // Fill the node with any available children we have + [persistenceServerCache.node enumerateChildrenUsingBlock:^(NSString *key, id node, BOOL *stop) { + if (![serverCacheNode hasChild:key]) { + serverCacheNode = [serverCacheNode updateImmediateChild:key withNewChild:node]; + } + }]; + FIndexedNode *indexed = [FIndexedNode indexedNodeWithNode:serverCacheNode index:query.index]; + serverCache = [[FCacheNode alloc] initWithIndexedNode:indexed isFullyInitialized:NO isFiltered:NO]; + } + } + + return serverCache; +} + +/** +* Remove event callback(s). +* +* If query is the default query, we'll check all queries for the specified eventRegistration. +* If eventRegistration is null, we'll remove all callbacks for the specified query/queries. +* +* @param eventRegistration if nil, all callbacks are removed +* @param cancelError If provided, appropriate cancel events will be returned +* @return NSArray of FEvent to raise. +*/ +- (NSArray *) removeEventRegistration:(id )eventRegistration + forQuery:(FQuerySpec *)query + cancelError:(NSError *)cancelError { + // Find the syncPoint first. Then deal with whether or not it has matching listeners + FPath *path = query.path; + FSyncPoint *maybeSyncPoint = [self.syncPointTree valueAtPath:path]; + NSArray *cancelEvents = @[]; + + // A removal on a default query affects all queries at that location. A removal on an indexed query, even one without + // other query constraints, does *not* affect all queries at that location. So this check must be for 'default', and + // not loadsAllData: + if (maybeSyncPoint && ([query isDefault] || [maybeSyncPoint viewExistsForQuery:query])) { + FTupleRemovedQueriesEvents *removedAndEvents = [maybeSyncPoint removeEventRegistration:eventRegistration forQuery:query cancelError:cancelError]; + if ([maybeSyncPoint isEmpty]) { + self.syncPointTree = [self.syncPointTree removeValueAtPath:path]; + } + NSArray *removed = removedAndEvents.removedQueries; + cancelEvents = removedAndEvents.cancelEvents; + + // We may have just removed one of many listeners and can short-circuit this whole process + // We may also not have removed a default listener, in which case all of the descendant listeners should already + // be properly set up. + // + // Since indexed queries can shadow if they don't have other query constraints, check for loadsAllData: instead + // of isDefault: + NSUInteger defaultQueryIndex = [removed indexOfObjectPassingTest:^BOOL(FQuerySpec *q, NSUInteger idx, BOOL *stop) { + return [q loadsAllData]; + }]; + BOOL removingDefault = defaultQueryIndex != NSNotFound; + [removed enumerateObjectsUsingBlock:^(FQuerySpec *query, NSUInteger idx, BOOL *stop) { + [self.persistenceManager setQueryInactive:query]; + }]; + NSNumber *covered = [self.syncPointTree findOnPath:path andApplyBlock:^id(FPath *relativePath, FSyncPoint *parentSyncPoint) { + return [NSNumber numberWithBool:[parentSyncPoint hasCompleteView]]; + }]; + + if (removingDefault && ![covered boolValue]) { + FImmutableTree *subtree = [self.syncPointTree subtreeAtPath:path]; + // There are potentially child listeners. Determine what if any listens we need to send before executing + // the removal + if (![subtree isEmpty]) { + // We need to fold over our subtree and collect the listeners to send + NSArray *newViews = [self collectDistinctViewsForSubTree:subtree]; + + // Ok, we've collected all the listens we need. Set them up. + [newViews enumerateObjectsUsingBlock:^(FView *view, NSUInteger idx, BOOL *stop) { + FQuerySpec *newQuery = view.query; + FListenContainer *listenContainer = [self createListenerForView:view]; + self.listenProvider.startListening([self queryForListening:newQuery], [self tagForQuery:newQuery], + listenContainer, listenContainer.onComplete); + }]; + } else { + // There's nothing below us, so nothing we need to start listening on + } + } + + // If we removed anything and we're not covered by a higher up listen, we need to stop listening on this query. + // The above block has us covered in terms of making sure we're set up on listens lower in the tree. + // Also, note that if we have a cancelError, it's already been removed at the provider level. + if (![covered boolValue] && [removed count] > 0 && cancelError == nil) { + // If we removed a default, then we weren't listening on any of the other queries here. Just cancel the one + // default. Otherwise, we need to iterate through and cancel each individual query + if (removingDefault) { + // We don't tag default listeners + self.listenProvider.stopListening([self queryForListening:query], nil); + } else { + [removed enumerateObjectsUsingBlock:^(FQuerySpec *queryToRemove, NSUInteger idx, BOOL *stop) { + NSNumber *tagToRemove = [self.queryToTagMap objectForKey:queryToRemove]; + self.listenProvider.stopListening([self queryForListening:queryToRemove], tagToRemove); + }]; + } + } + // Now, clear all the tags we're tracking for the removed listens. + [self removeTags:removed]; + } else { + // No-op, this listener must've been already removed + } + return cancelEvents; +} + +- (void)keepQuery:(FQuerySpec *)query synced:(BOOL)keepSynced { + // Only do something if we actually need to add/remove an event registration + if (keepSynced && ![self.keepSyncedQueries containsObject:query]) { + [self addEventRegistration:[FKeepSyncedEventRegistration instance] forQuery:query]; + [self.keepSyncedQueries addObject:query]; + } else if (!keepSynced && [self.keepSyncedQueries containsObject:query]) { + [self removeEventRegistration:[FKeepSyncedEventRegistration instance] forQuery:query cancelError:nil]; + [self.keepSyncedQueries removeObject:query]; + } +} + +- (NSArray *) removeAllWrites { + [self.persistenceManager removeAllUserWrites]; + NSArray *removedWrites = [self.pendingWriteTree removeAllWrites]; + if (removedWrites.count > 0) { + FImmutableTree *affectedTree = [[FImmutableTree empty] setValue:@YES atPath:[FPath empty]]; + return [self applyOperationToSyncPoints:[[FAckUserWrite alloc] initWithPath:[FPath empty] + affectedTree:affectedTree revert:YES]]; + } else { + return @[]; + } +} + +/** +* Returns a complete cache, if we have one, of the data at a particular path. The location must have a listener above +* it, but as this is only used by transaction code, that should always be the case anyways. +* +* Note: this method will *include* hidden writes from transaction with applyLocally set to false. +* @param path The path to the data we want +* @param writeIdsToExclude A specific set to be excluded +*/ +- (id ) calcCompleteEventCacheAtPath:(FPath *)path excludeWriteIds:(NSArray *)writeIdsToExclude { + BOOL includeHiddenSets = YES; + FWriteTree *writeTree = self.pendingWriteTree; + id serverCache = [self.syncPointTree findOnPath:path andApplyBlock:^id(FPath *pathSoFar, FSyncPoint *syncPoint) { + FPath *relativePath = [FPath relativePathFrom:pathSoFar to:path]; + id serverCache = [syncPoint completeServerCacheAtPath:relativePath]; + if (serverCache) { + return serverCache; + } else { + return nil; + } + }]; + return [writeTree calculateCompleteEventCacheAtPath:path completeServerCache:serverCache excludeWriteIds:writeIdsToExclude includeHiddenWrites:includeHiddenSets]; +} + +#pragma mark - +#pragma mark Private Methods +/** +* This collapses multiple unfiltered views into a single view, since we only need a single +* listener for them. +* @return NSArray of FView +*/ +- (NSArray *) collectDistinctViewsForSubTree:(FImmutableTree *)subtree { + return [subtree foldWithBlock:^NSArray *(FPath *relativePath, FSyncPoint *maybeChildSyncPoint, NSDictionary *childMap) { + if (maybeChildSyncPoint && [maybeChildSyncPoint hasCompleteView]) { + FView *completeView = [maybeChildSyncPoint completeView]; + return @[completeView]; + } else { + // No complete view here, flatten any deeper listens into an array + NSMutableArray *views = [[NSMutableArray alloc] init]; + if (maybeChildSyncPoint) { + views = [[maybeChildSyncPoint queryViews] mutableCopy]; + } + [childMap enumerateKeysAndObjectsUsingBlock:^(NSString *childKey, NSArray *childViews, BOOL *stop) { + [views addObjectsFromArray:childViews]; + }]; + return views; + } + }]; +} + +/** +* @param queries NSArray of FQuerySpec +*/ +- (void) removeTags:(NSArray *)queries { + [queries enumerateObjectsUsingBlock:^(FQuerySpec *removedQuery, NSUInteger idx, BOOL *stop) { + if (![removedQuery loadsAllData]) { + // We should have a tag for this + NSNumber *removedQueryTag = self.queryToTagMap[removedQuery]; + [self.queryToTagMap removeObjectForKey:removedQuery]; + [self.tagToQueryMap removeObjectForKey:removedQueryTag]; + } + }]; +} + +- (FQuerySpec *) queryForListening:(FQuerySpec *)query { + if (query.loadsAllData && !query.isDefault) { + // We treat queries that load all data as default queries + return [FQuerySpec defaultQueryAtPath:query.path]; + } else { + return query; + } +} + +/** +* For a given new listen, manage the de-duplication of outstanding subscriptions. +* @return NSArray of FEvent events to support synchronous data sources +*/ +- (NSArray *) setupListenerOnQuery:(FQuerySpec *)query view:(FView *)view { + FPath *path = query.path; + NSNumber *tagId = [self tagForQuery:query]; + FListenContainer *listenContainer = [self createListenerForView:view]; + + NSArray *events = self.listenProvider.startListening([self queryForListening:query], tagId, listenContainer, + listenContainer.onComplete); + + FImmutableTree *subtree = [self.syncPointTree subtreeAtPath:path]; + // The root of this subtree has our query. We're here because we definitely need to send a listen for that, but we + // may need to shadow other listens as well. + if (tagId != nil) { + NSAssert(![subtree.value hasCompleteView], @"If we're adding a query, it shouldn't be shadowed"); + } else { + // Shadow everything at or below this location, this is a default listener. + NSArray *queriesToStop = [subtree foldWithBlock:^id(FPath *relativePath, FSyncPoint *maybeChildSyncPoint, NSDictionary *childMap) { + if (![relativePath isEmpty] && maybeChildSyncPoint != nil && [maybeChildSyncPoint hasCompleteView]) { + return @[[maybeChildSyncPoint completeView].query]; + } else { + // No default listener here, flatten any deeper queries into an array + NSMutableArray *queries = [[NSMutableArray alloc] init]; + if (maybeChildSyncPoint != nil) { + for (FView *view in [maybeChildSyncPoint queryViews]) { + [queries addObject:view.query]; + } + } + [childMap enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSArray *childQueries, BOOL *stop) { + [queries addObjectsFromArray:childQueries]; + }]; + return queries; + } + }]; + for (FQuerySpec *queryToStop in queriesToStop) { + self.listenProvider.stopListening([self queryForListening:queryToStop], [self tagForQuery:queryToStop]); + } + } + return events; +} + +- (FListenContainer *) createListenerForView:(FView *)view { + FQuerySpec *query = view.query; + NSNumber *tagId = [self tagForQuery:query]; + + FListenContainer *listenContainer = [[FListenContainer alloc] initWithView:view + onComplete:^(NSString *status) { + if ([status isEqualToString:@"ok"]) { + if (tagId != nil) { + return [self applyTaggedListenCompleteAtPath:query.path tagId:tagId]; + } else { + return [self applyListenCompleteAtPath:query.path]; + } + } else { + // If a listen failed, kill all of the listeners here, not just the one that triggered the error. + // Note that this may need to be scoped to just this listener if we change permissions on filtered children + NSError *error = [FUtilities errorForStatus:status andReason:nil]; + FFWarn(@"I-RDB038012", @"Listener at %@ failed: %@", query.path, status); + return [self removeEventRegistration:nil forQuery:query cancelError:error]; + } + }]; + + return listenContainer; +} + +/** +* @return The query associated with the given tag, if we have one +*/ +- (FQuerySpec *) queryForTag:(NSNumber *)tagId { + return self.tagToQueryMap[tagId]; +} + +/** +* @return The tag associated with the given query +*/ +- (NSNumber *) tagForQuery:(FQuerySpec *)query { + return self.queryToTagMap[query]; +} + +#pragma mark - +#pragma mark applyOperation Helpers + +/** +* A helper method that visits all descendant and ancestor SyncPoints, applying the operation. +* +* NOTES: +* - Descendant SyncPoints will be visited first (since we raise events depth-first). + +* - We call applyOperation: on each SyncPoint passing three things: +* 1. A version of the Operation that has been made relative to the SyncPoint location. +* 2. A WriteTreeRef of any writes we have cached at the SyncPoint location. +* 3. A snapshot Node with cached server data, if we have it. + +* - We concatenate all of the events returned by each SyncPoint and return the result. +* +* @return Array of FEvent +*/ +- (NSArray *) applyOperationToSyncPoints:(id)operation { + return [self applyOperationHelper:operation syncPointTree:self.syncPointTree serverCache:nil + writesCache:[self.pendingWriteTree childWritesForPath:[FPath empty]]]; +} + +/** +* Recursive helper for applyOperationToSyncPoints_ +*/ +- (NSArray *) applyOperationHelper:(id)operation syncPointTree:(FImmutableTree *)syncPointTree + serverCache:(id)serverCache writesCache:(FWriteTreeRef *)writesCache { + if ([operation.path isEmpty]) { + return [self applyOperationDescendantsHelper:operation syncPointTree:syncPointTree serverCache:serverCache writesCache:writesCache]; + } else { + FSyncPoint *syncPoint = syncPointTree.value; + + // If we don't have cached server data, see if we can get it from this SyncPoint + if (serverCache == nil && syncPoint != nil) { + serverCache = [syncPoint completeServerCacheAtPath:[FPath empty]]; + } + + NSMutableArray *events = [[NSMutableArray alloc] init]; + NSString *childKey = [operation.path getFront]; + id childOperation = [operation operationForChild:childKey]; + FImmutableTree *childTree = [syncPointTree.children get:childKey]; + if (childTree != nil && childOperation != nil) { + id childServerCache = serverCache ? [serverCache getImmediateChild:childKey] : nil; + FWriteTreeRef *childWritesCache = [writesCache childWriteTreeRef:childKey]; + [events addObjectsFromArray:[self applyOperationHelper:childOperation syncPointTree:childTree serverCache:childServerCache writesCache:childWritesCache]]; + } + + if (syncPoint) { + [events addObjectsFromArray:[syncPoint applyOperation:operation writesCache:writesCache serverCache:serverCache]]; + } + + return events; + } +} + +/** +* Recursive helper for applyOperationToSyncPoints: +*/ +- (NSArray *) applyOperationDescendantsHelper:(id)operation syncPointTree:(FImmutableTree *)syncPointTree + serverCache:(id)serverCache writesCache:(FWriteTreeRef *)writesCache { + FSyncPoint *syncPoint = syncPointTree.value; + + // If we don't have cached server data, see if we can get it from this SyncPoint + id resolvedServerCache; + if (serverCache == nil & syncPoint != nil) { + resolvedServerCache = [syncPoint completeServerCacheAtPath:[FPath empty]]; + } else { + resolvedServerCache = serverCache; + } + + NSMutableArray *events = [[NSMutableArray alloc] init]; + [syncPointTree.children enumerateKeysAndObjectsUsingBlock:^(NSString *childKey, FImmutableTree *childTree, BOOL *stop) { + id childServerCache = nil; + if (resolvedServerCache != nil) { + childServerCache = [resolvedServerCache getImmediateChild:childKey]; + } + FWriteTreeRef *childWritesCache = [writesCache childWriteTreeRef:childKey]; + id childOperation = [operation operationForChild:childKey]; + if (childOperation != nil) { + [events addObjectsFromArray:[self applyOperationDescendantsHelper:childOperation + syncPointTree:childTree + serverCache:childServerCache + writesCache:childWritesCache]]; + } + }]; + + if (syncPoint) { + [events addObjectsFromArray:[syncPoint applyOperation:operation writesCache:writesCache serverCache:resolvedServerCache]]; + } + + return events; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FWriteRecord.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FWriteRecord.h new file mode 100644 index 00000000..a9b53fe8 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FWriteRecord.h @@ -0,0 +1,40 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class FPath; +@class FCompoundWrite; +@protocol FNode; + +@interface FWriteRecord : NSObject + +- initWithPath:(FPath *)path overwrite:(id)overwrite writeId:(NSInteger)writeId visible:(BOOL)isVisible; +- initWithPath:(FPath *)path merge:(FCompoundWrite *)merge writeId:(NSInteger)writeId; + +@property (nonatomic, readonly) NSInteger writeId; +@property (nonatomic, strong, readonly) FPath *path; +@property (nonatomic, strong, readonly) id overwrite; +/** +* Maps NSString -> id +*/ +@property (nonatomic, strong, readonly) FCompoundWrite *merge; +@property (nonatomic, readonly) BOOL visible; + +- (BOOL)isMerge; +- (BOOL)isOverwrite; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FWriteRecord.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FWriteRecord.m new file mode 100644 index 00000000..47c952cd --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FWriteRecord.m @@ -0,0 +1,117 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FWriteRecord.h" +#import "FPath.h" +#import "FNode.h" +#import "FCompoundWrite.h" + +@interface FWriteRecord () +@property (nonatomic, readwrite) NSInteger writeId; +@property (nonatomic, strong, readwrite) FPath *path; +@property (nonatomic, strong, readwrite) id overwrite; +@property (nonatomic, strong, readwrite) FCompoundWrite *merge; +@property (nonatomic, readwrite) BOOL visible; +@end + +@implementation FWriteRecord + +- (id)initWithPath:(FPath *)path overwrite:(id)overwrite writeId:(NSInteger)writeId visible:(BOOL)isVisible { + self = [super init]; + if (self) { + self.path = path; + if (overwrite == nil) { + [NSException raise:NSInvalidArgumentException format:@"Can't pass nil as overwrite parameter to an overwrite write record"]; + } + self.overwrite = overwrite; + self.merge = nil; + self.writeId = writeId; + self.visible = isVisible; + } + return self; +} + +- (id)initWithPath:(FPath *)path merge:(FCompoundWrite *)merge writeId:(NSInteger)writeId { + self = [super init]; + if (self) { + self.path = path; + if (merge == nil) { + [NSException raise:NSInvalidArgumentException format:@"Can't pass nil as merge parameter to an merge write record"]; + } + self.overwrite = nil; + self.merge = merge; + self.writeId = writeId; + self.visible = YES; + } + return self; +} + +- (id)overwrite { + if (self->_overwrite == nil) { + [NSException raise:NSInvalidArgumentException format:@"Can't get overwrite for merge write record!"]; + } + return self->_overwrite; +} + +- (FCompoundWrite *)compoundWrite { + if (self->_merge == nil) { + [NSException raise:NSInvalidArgumentException format:@"Can't get merge for overwrite write record!"]; + } + return self->_merge; +} + +- (BOOL)isMerge { + return self->_merge != nil; +} + +- (BOOL)isOverwrite { + return self->_overwrite != nil; +} + +- (NSString *)description { + if (self.isOverwrite) { + return [NSString stringWithFormat:@"FWriteRecord { writeId = %lu, path = %@, overwrite = %@, visible = %d }", + (unsigned long)self.writeId, self.path, self.overwrite, self.visible]; + } else { + return [NSString stringWithFormat:@"FWriteRecord { writeId = %lu, path = %@, merge = %@ }", + (unsigned long)self.writeId, self.path, self.merge]; + } +} + +- (BOOL)isEqual:(id)object { + if (![object isKindOfClass:[self class]]) { + return NO; + } + FWriteRecord *other = (FWriteRecord *)object; + if (self->_writeId != other->_writeId) return NO; + if (self->_path != other->_path && ![self->_path isEqual:other->_path]) return NO; + if (self->_overwrite != other->_overwrite && ![self->_overwrite isEqual:other->_overwrite]) return NO; + if (self->_merge != other->_merge && ![self->_merge isEqual:other->_merge]) return NO; + if (self->_visible != other->_visible) return NO; + + return YES; +} + +- (NSUInteger)hash { + NSUInteger hash = self->_writeId * 17; + hash = hash * 31 + self->_path.hash; + hash = hash * 31 + self->_overwrite.hash; + hash = hash * 31 + self->_merge.hash; + hash = hash * 31 + ((self->_visible) ? 1 : 0); + return hash; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FWriteTree.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FWriteTree.h new file mode 100644 index 00000000..243bc9f3 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FWriteTree.h @@ -0,0 +1,63 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class FPath; +@protocol FNode; +@class FCompoundWrite; +@class FWriteTreeRef; +@class FChildrenNode; +@class FNamedNode; +@class FWriteRecord; +@protocol FIndex; +@class FCacheNode; + +@interface FWriteTree : NSObject + +- (FWriteTreeRef *) childWritesForPath:(FPath *)path; +- (void) addOverwriteAtPath:(FPath *)path newData:(id)newData writeId:(NSInteger)writeId isVisible:(BOOL)visible; +- (void) addMergeAtPath:(FPath *)path changedChildren:(FCompoundWrite *)changedChildren writeId:(NSInteger)writeId; +- (BOOL) removeWriteId:(NSInteger)writeId; +- (NSArray *) removeAllWrites; +- (FWriteRecord *)writeForId:(NSInteger)writeId; + +- (id) calculateCompleteEventCacheAtPath:(FPath *)treePath + completeServerCache:(id)completeServerCache + excludeWriteIds:(NSArray *)writeIdsToExclude + includeHiddenWrites:(BOOL)includeHiddenWrites; + +- (id) calculateCompleteEventChildrenAtPath:(FPath *)treePath + completeServerChildren:(id)completeServerChildren; + +- (id) calculateEventCacheAfterServerOverwriteAtPath:(FPath *)treePath + childPath:(FPath *)childPath + existingEventSnap:(id)existingEventSnap + existingServerSnap:(id)existingServerSnap; + +- (id) calculateCompleteChildAtPath:(FPath *)treePath + childKey:(NSString *)childKey + cache:(FCacheNode *)existingServerCache; + +- (id) shadowingWriteAtPath:(FPath *)path; + +- (FNamedNode *) calculateNextNodeAfterPost:(FNamedNode *)post + atPath:(FPath *)path + completeServerData:(id)completeServerData + reverse:(BOOL)reverse + index:(id)index; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FWriteTree.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FWriteTree.m new file mode 100644 index 00000000..c5b08ea5 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FWriteTree.m @@ -0,0 +1,458 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FWriteTree.h" +#import "FImmutableTree.h" +#import "FPath.h" +#import "FNode.h" +#import "FWriteTreeRef.h" +#import "FChildrenNode.h" +#import "FNamedNode.h" +#import "FWriteRecord.h" +#import "FEmptyNode.h" +#import "FIndex.h" +#import "FCompoundWrite.h" +#import "FCacheNode.h" + +@interface FWriteTree () +/** +* A tree tracking the results of applying all visible writes. This does not include transactions with +* applyLocally=false or writes that are completely shadowed by other writes. +* Contains id as values. +*/ +@property (nonatomic, strong) FCompoundWrite *visibleWrites; +/** +* A list of pending writes, regardless of visibility and shadowed-ness. Used to calcuate arbitrary +* sets of the changed data, such as hidden writes (from transactions) or changes with certain writes excluded (also +* used by transactions). +* Contains FWriteRecords. +*/ +@property (nonatomic, strong) NSMutableArray *allWrites; +@property (nonatomic) NSInteger lastWriteId; +@end + +/** +* FWriteTree tracks all pending user-initiated writes and has methods to calcuate the result of merging them with +* underlying server data (to create "event cache" data). Pending writes are added with addOverwriteAtPath: and +* addMergeAtPath: and removed with removeWriteId:. +*/ +@implementation FWriteTree + +@synthesize allWrites; +@synthesize lastWriteId; + +- (id) init { + self = [super init]; + if (self) { + self.visibleWrites = [FCompoundWrite emptyWrite]; + self.allWrites = [[NSMutableArray alloc] init]; + self.lastWriteId = -1; + } + return self; +} + +/** +* Create a new WriteTreeRef for the given path. For use with a new sync point at the given path. +*/ +- (FWriteTreeRef *) childWritesForPath:(FPath *)path { + return [[FWriteTreeRef alloc] initWithPath:path writeTree:self]; +} + +/** +* Record a new overwrite from user code. +* @param visible Is set to false by some transactions. It should be excluded from event caches. +*/ +- (void) addOverwriteAtPath:(FPath *)path newData:(id )newData writeId:(NSInteger)writeId isVisible:(BOOL)visible { + NSAssert(writeId > self.lastWriteId, @"Stacking an older write on top of a newer one"); + FWriteRecord *record = [[FWriteRecord alloc] initWithPath:path overwrite:newData writeId:writeId visible:visible]; + [self.allWrites addObject:record]; + + if (visible) { + self.visibleWrites = [self.visibleWrites addWrite:newData atPath:path]; + } + + self.lastWriteId = writeId; +} + +/** +* Record a new merge from user code. +* @param changedChildren maps NSString -> id +*/ +- (void) addMergeAtPath:(FPath *)path changedChildren:(FCompoundWrite *)changedChildren writeId:(NSInteger)writeId { + NSAssert(writeId > self.lastWriteId, @"Stacking an older merge on top of newer one"); + FWriteRecord *record = [[FWriteRecord alloc] initWithPath:path merge:changedChildren writeId:writeId]; + [self.allWrites addObject:record]; + + self.visibleWrites = [self.visibleWrites addCompoundWrite:changedChildren atPath:path]; + self.lastWriteId = writeId; +} + +- (FWriteRecord *)writeForId:(NSInteger)writeId { + NSUInteger index = [self.allWrites indexOfObjectPassingTest:^BOOL(FWriteRecord *write, NSUInteger idx, BOOL *stop) { + return write.writeId == writeId; + }]; + return (index == NSNotFound) ? nil : self.allWrites[index]; +} + +/** +* Remove a write (either an overwrite or merge) that has been successfully acknowledged by the server. Recalculates the +* tree if necessary. We return the path of the write and whether it may have been visible, meaning views need to +* reevaluate. +* +* @return YES if the write may have been visible (meaning we'll need to reevaluate / raise events as a result). +*/ +- (BOOL) removeWriteId:(NSInteger)writeId { + NSUInteger index = [self.allWrites indexOfObjectPassingTest:^BOOL(FWriteRecord *record, NSUInteger idx, BOOL *stop) { + if (record.writeId == writeId) { + return YES; + } else { + return NO; + } + }]; + NSAssert(index != NSNotFound, @"[FWriteTree removeWriteId:] called with nonexistent writeId."); + FWriteRecord *writeToRemove = self.allWrites[index]; + [self.allWrites removeObjectAtIndex:index]; + + BOOL removedWriteWasVisible = writeToRemove.visible; + BOOL removedWriteOverlapsWithOtherWrites = NO; + NSInteger i = [self.allWrites count] - 1; + + while (removedWriteWasVisible && i >= 0) { + FWriteRecord *currentWrite = [self.allWrites objectAtIndex:i]; + if (currentWrite.visible) { + if (i >= index && [self record:currentWrite containsPath:writeToRemove.path]) { + // The removed write was completely shadowed by a subsequent write. + removedWriteWasVisible = NO; + } else if ([writeToRemove.path contains:currentWrite.path]) { + // Either we're covering some writes or they're covering part of us (depending on which came first). + removedWriteOverlapsWithOtherWrites = YES; + } + } + i--; + } + + if (!removedWriteWasVisible) { + return NO; + } else if (removedWriteOverlapsWithOtherWrites) { + // There's some shadowing going on. Just rebuild the visible writes from scratch. + [self resetTree]; + return YES; + } else { + // There's no shadowing. We can safely just remove the write(s) from visibleWrites. + if ([writeToRemove isOverwrite]) { + self.visibleWrites = [self.visibleWrites removeWriteAtPath:writeToRemove.path]; + } else { + FCompoundWrite *merge = writeToRemove.merge; + [merge enumerateWrites:^(FPath *path, id node, BOOL *stop) { + self.visibleWrites = [self.visibleWrites removeWriteAtPath:[writeToRemove.path child:path]]; + }]; + } + return YES; + } +} + +- (NSArray *) removeAllWrites { + NSArray *writes = self.allWrites; + self.visibleWrites = [FCompoundWrite emptyWrite]; + self.allWrites = [NSMutableArray array]; + return writes; +} + +/** +* @return A complete snapshot for the given path if there's visible write data at that path, else nil. +* No server data is considered. +*/ +- (id ) completeWriteDataAtPath:(FPath *)path { + return [self.visibleWrites completeNodeAtPath:path]; +} + +/** +* Given optional, underlying server data, and an optional set of constraints (exclude some sets, include hidden +* writes), attempt to calculate a complete snapshot for the given path +* @param includeHiddenWrites Defaults to false, whether or not to layer on writes with visible set to false +*/ +- (id ) calculateCompleteEventCacheAtPath:(FPath *)treePath completeServerCache:(id )completeServerCache + excludeWriteIds:(NSArray *)writeIdsToExclude includeHiddenWrites:(BOOL)includeHiddenWrites { + if (writeIdsToExclude == nil && !includeHiddenWrites) { + id shadowingNode = [self.visibleWrites completeNodeAtPath:treePath]; + if (shadowingNode != nil) { + return shadowingNode; + } else { + // No cache here. Can't claim complete knowledge. + FCompoundWrite *subMerge = [self.visibleWrites childCompoundWriteAtPath:treePath]; + if (subMerge.isEmpty) { + return completeServerCache; + } else if (completeServerCache == nil && ![subMerge hasCompleteWriteAtPath:[FPath empty]]) { + // We wouldn't have a complete snapshot since there's no underlying data and no complete shadow + return nil; + } else { + id layeredCache = completeServerCache != nil ? completeServerCache : [FEmptyNode emptyNode]; + return [subMerge applyToNode:layeredCache]; + } + } + } else { + FCompoundWrite *merge = [self.visibleWrites childCompoundWriteAtPath:treePath]; + if (!includeHiddenWrites && merge.isEmpty) { + return completeServerCache; + } else { + // If the server cache is null and we don't have a complete cache, we need to return nil + if (!includeHiddenWrites && completeServerCache == nil && ![merge hasCompleteWriteAtPath:[FPath empty]]) { + return nil; + } else { + BOOL (^filter) (FWriteRecord *) = ^(FWriteRecord *record) { + return (BOOL) ((record.visible || includeHiddenWrites) && + (writeIdsToExclude == nil || ![writeIdsToExclude containsObject:[NSNumber numberWithInteger:record.writeId]]) && + ([record.path contains:treePath] || [treePath contains:record.path])); + }; + FCompoundWrite *mergeAtPath = [FWriteTree layerTreeFromWrites:self.allWrites filter:filter treeRoot:treePath]; + id layeredCache = completeServerCache ? completeServerCache : [FEmptyNode emptyNode]; + return [mergeAtPath applyToNode:layeredCache]; + } + } + } +} + +/** +* With optional, underlying server data, attempt to return a children node of children that we have complete data for. +* Used when creating new views, to pre-fill their complete event children snapshot. +*/ +- (FChildrenNode *) calculateCompleteEventChildrenAtPath:(FPath *)treePath + completeServerChildren:(id)completeServerChildren { + __block id completeChildren = [FEmptyNode emptyNode]; + id topLevelSet = [self.visibleWrites completeNodeAtPath:treePath]; + if (topLevelSet != nil) { + if (![topLevelSet isLeafNode]) { + // We're shadowing everything. Return the children. + FChildrenNode *topChildrenNode = topLevelSet; + [topChildrenNode enumerateChildrenUsingBlock:^(NSString *key, id node, BOOL *stop) { + completeChildren = [completeChildren updateImmediateChild:key withNewChild:node]; + }]; + } + return completeChildren; + } else { + // Layer any children we have on top of this + // We know we don't have a top-level set, so just enumerate existing children, and apply any updates + FCompoundWrite *merge = [self.visibleWrites childCompoundWriteAtPath:treePath]; + [completeServerChildren enumerateChildrenUsingBlock:^(NSString *key, id node, BOOL *stop) { + FCompoundWrite *childMerge = [merge childCompoundWriteAtPath:[[FPath alloc] initWith:key]]; + id newChildNode = [childMerge applyToNode:node]; + completeChildren = [completeChildren updateImmediateChild:key withNewChild:newChildNode]; + }]; + // Add any complete children we have from the set. + for (FNamedNode *node in merge.completeChildren) { + completeChildren = [completeChildren updateImmediateChild:node.name withNewChild:node.node]; + } + return completeChildren; + } +} + +/** +* Given that the underlying server data has updated, determine what, if anything, needs to be applied to the event cache. +* +* Possibilities +* +* 1. No write are shadowing. Events should be raised, the snap to be applied comes from the server data. +* +* 2. Some write is completely shadowing. No events to be raised. +* +* 3. Is partially shadowed. Events .. +* +* Either existingEventSnap or existingServerSnap must exist. +*/ +- (id ) calculateEventCacheAfterServerOverwriteAtPath:(FPath *)treePath childPath:(FPath *)childPath existingEventSnap:(id )existingEventSnap existingServerSnap:(id )existingServerSnap { + NSAssert(existingEventSnap != nil || existingServerSnap != nil, + @"Either existingEventSnap or existingServerSanp must exist."); + + FPath *path = [treePath child:childPath]; + if ([self.visibleWrites hasCompleteWriteAtPath:path]) { + // At this point we can probably guarantee that we're in case 2, meaning no events + // May need to check visibility while doing the findRootMostValueAndPath call + return nil; + } else { + // This could be more efficient if the serverNode + updates doesn't change the eventSnap + // However this is tricky to find out, since user updates don't necessary change the server + // snap, e.g. priority updates on empty nodes, or deep deletes. Another special case is if the server + // adds nodes, but doesn't change any existing writes. It is therefore not enough to + // only check if the updates change the serverNode. + // Maybe check if the merge tree contains these special cases and only do a full overwrite in that case? + FCompoundWrite *childMerge = [self.visibleWrites childCompoundWriteAtPath:path]; + if (childMerge.isEmpty) { + // We're not shadowing at all. Case 1 + return [existingServerSnap getChild:childPath]; + } else { + return [childMerge applyToNode:[existingServerSnap getChild:childPath]]; + } + } +} + +/** +* Returns a complete child for a given server snap after applying all user writes or nil if there is no complete child +* for this child key. +*/ +- (id) calculateCompleteChildAtPath:(FPath *)treePath childKey:(NSString *)childKey cache:(FCacheNode *)existingServerCache { + FPath *path = [treePath childFromString:childKey]; + id shadowingNode = [self.visibleWrites completeNodeAtPath:path]; + if (shadowingNode != nil) { + return shadowingNode; + } else { + if ([existingServerCache isCompleteForChild:childKey]) { + FCompoundWrite *childMerge = [self.visibleWrites childCompoundWriteAtPath:path]; + return [childMerge applyToNode:[existingServerCache.node getImmediateChild:childKey]]; + } else { + return nil; + } + } +} + +/** +* Returns a node if there is a complete overwrite for this path. More specifically, if there is a write at +* a higher path, this will return the child of that write relative to the write and this path. +* Returns null if there is no write at this path. +*/ +- (id) shadowingWriteAtPath:(FPath *)path { + return [self.visibleWrites completeNodeAtPath:path]; +} + +/** +* This method is used when processing child remove events on a query. If we can, we pull in children that were outside +* the window, but may now be in the window. +*/ +- (FNamedNode *)calculateNextNodeAfterPost:(FNamedNode *)post + atPath:(FPath *)treePath + completeServerData:(id)completeServerData + reverse:(BOOL)reverse + index:(id)index +{ + __block id toIterate; + FCompoundWrite *merge = [self.visibleWrites childCompoundWriteAtPath:treePath]; + id shadowingNode = [merge completeNodeAtPath:[FPath empty]]; + if (shadowingNode != nil) { + toIterate = shadowingNode; + } else if (completeServerData != nil) { + toIterate = [merge applyToNode:completeServerData]; + } else { + return nil; + } + + __block NSString *currentNextKey = nil; + __block id currentNextNode = nil; + [toIterate enumerateChildrenUsingBlock:^(NSString *key, id node, BOOL *stop) { + if ([index compareKey:key andNode:node toOtherKey:post.name andNode:post.node reverse:reverse] > NSOrderedSame && + (!currentNextKey || [index compareKey:key andNode:node toOtherKey:currentNextKey andNode:currentNextNode reverse:reverse] < NSOrderedSame)) { + currentNextKey = key; + currentNextNode = node; + } + }]; + + if (currentNextKey != nil) { + return [FNamedNode nodeWithName:currentNextKey node:currentNextNode]; + } else { + return nil; + } +} + +#pragma mark - +#pragma mark Private Methods + +- (BOOL) record:(FWriteRecord *)record containsPath:(FPath *)path { + if ([record isOverwrite]) { + return [record.path contains:path]; + } else { + __block BOOL contains = NO; + [record.merge enumerateWrites:^(FPath *childPath, id node, BOOL *stop) { + contains = [[record.path child:childPath] contains:path]; + *stop = contains; + }]; + return contains; + } +} + +/** +* Re-layer the writes and merges into a tree so we can efficiently calculate event snapshots +*/ +- (void) resetTree { + self.visibleWrites = [FWriteTree layerTreeFromWrites:self.allWrites filter:[FWriteTree defaultFilter] treeRoot:[FPath empty]]; + if ([self.allWrites count] > 0) { + FWriteRecord *lastRecord = self.allWrites[[self.allWrites count] - 1]; + self.lastWriteId = lastRecord.writeId; + } else { + self.lastWriteId = -1; + } +} + +/** +* The default filter used when constructing the tree. Keep everything that's visible. +*/ ++ (BOOL (^)(FWriteRecord *record)) defaultFilter { + static BOOL (^filter)(FWriteRecord *); + static dispatch_once_t filterToken; + dispatch_once(&filterToken, ^{ + filter = ^(FWriteRecord *record) { + return YES; + }; + }); + return filter; +} + +/** +* Static method. Given an array of WriteRecords, a filter for which ones to include, and a path, construct a merge +* at that path +* @return An FImmutableTree of ids. +*/ ++ (FCompoundWrite *) layerTreeFromWrites:(NSArray *)writes filter:(BOOL (^)(FWriteRecord *record))filter treeRoot:(FPath *)treeRoot { + __block FCompoundWrite *compoundWrite = [FCompoundWrite emptyWrite]; + [writes enumerateObjectsUsingBlock:^(FWriteRecord *record, NSUInteger idx, BOOL *stop) { + // Theory, a later set will either: + // a) abort a relevant transaction, so no need to worry about excluding it from calculating that transaction + // b) not be relevant to a transaction (separate branch), so again will not affect the data for that transaction + if (filter(record)) { + FPath *writePath = record.path; + if ([record isOverwrite]) { + if ([treeRoot contains:writePath]) { + FPath *relativePath = [FPath relativePathFrom:treeRoot to:writePath]; + compoundWrite = [compoundWrite addWrite:record.overwrite atPath:relativePath]; + } else if ([writePath contains:treeRoot]) { + id child = [record.overwrite getChild:[FPath relativePathFrom:writePath to:treeRoot]]; + compoundWrite = [compoundWrite addWrite:child atPath:[FPath empty]]; + } else { + // There is no overlap between root path and write path, ignore write + } + } else { + if ([treeRoot contains:writePath]) { + FPath *relativePath = [FPath relativePathFrom:treeRoot to:writePath]; + compoundWrite = [compoundWrite addCompoundWrite:record.merge atPath:relativePath]; + } else if ([writePath contains:treeRoot]) { + FPath *relativePath = [FPath relativePathFrom:writePath to:treeRoot]; + if (relativePath.isEmpty) { + compoundWrite = [compoundWrite addCompoundWrite:record.merge atPath:[FPath empty]]; + } else { + id child = [record.merge completeNodeAtPath:relativePath]; + if (child != nil) { + // There exists a child in this node that matches the root path + id deepNode = [child getChild:[relativePath popFront]]; + compoundWrite = [compoundWrite addWrite:deepNode atPath:[FPath empty]]; + } + } + } else { + // There is no overlap between root path and write path, ignore write + } + } + } + }]; + return compoundWrite; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FWriteTreeRef.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FWriteTreeRef.h new file mode 100644 index 00000000..791dd268 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FWriteTreeRef.h @@ -0,0 +1,51 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@protocol FNode; +@class FChildrenNode; +@class FPath; +@class FNamedNode; +@class FWriteRecord; +@class FWriteTree; +@protocol FIndex; +@class FCacheNode; + +@interface FWriteTreeRef : NSObject + +- (id) initWithPath:(FPath *)aPath writeTree:(FWriteTree *)tree; + +- (id ) calculateCompleteEventCacheWithCompleteServerCache:(id )completeServerCache; + +- (FChildrenNode *) calculateCompleteEventChildrenWithCompleteServerChildren:(FChildrenNode *)completeServerChildren; + +- (id) calculateEventCacheAfterServerOverwriteWithChildPath:(FPath *)childPath + existingEventSnap:(id)existingEventSnap + existingServerSnap:(id)existingServerSnap; + +- (id) shadowingWriteAtPath:(FPath *)path; + +- (FNamedNode *) calculateNextNodeAfterPost:(FNamedNode *)post + completeServerData:(id)completeServerData + reverse:(BOOL)reverse + index:(id)index; + +- (id) calculateCompleteChild:(NSString *)childKey cache:(FCacheNode *)existingServerCache; + +- (FWriteTreeRef *) childWriteTreeRef:(NSString *)childKey; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FWriteTreeRef.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FWriteTreeRef.m new file mode 100644 index 00000000..392369b5 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/FWriteTreeRef.m @@ -0,0 +1,133 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FWriteTreeRef.h" +#import "FPath.h" +#import "FNode.h" +#import "FWriteTree.h" +#import "FChildrenNode.h" +#import "FNamedNode.h" +#import "FWriteRecord.h" +#import "FIndex.h" +#import "FCacheNode.h" + +@interface FWriteTreeRef () +/** +* The path to this particular FWriteTreeRef. Used for calling methods on writeTree while exposing a simpler interface +* to callers. +*/ +@property (nonatomic, strong) FPath *path; +/** +* A reference to the actual tree of the write data. All methods are pass-through to the tree, but with the appropriate +* path prefixed. +* +* This lets us make cheap references to points in the tree for sync points without having to copy and maintain all of +* the data. +*/ +@property (nonatomic, strong) FWriteTree *writeTree; +@end + +/** +* A FWriteTreeRef wraps a FWriteTree and a FPath, for convenient access to a particular subtree. All the methods just +* proxy to the underlying FWriteTree. +*/ +@implementation FWriteTreeRef +- (id) initWithPath:(FPath *)aPath writeTree:(FWriteTree *)tree { + self = [super init]; + if (self) { + self.path = aPath; + self.writeTree = tree; + } + return self; +} + +/** +* @return If possible, returns a complete event cache, using the underlying server data if possible. In addition, can +* be used to get a cache that includes hidden writes, and excludes arbitrary writes. Note that customizing the returned +* node can lead to a more expensive calculation. +*/ +- (id ) calculateCompleteEventCacheWithCompleteServerCache:(id)completeServerCache { + return [self.writeTree calculateCompleteEventCacheAtPath:self.path completeServerCache:completeServerCache excludeWriteIds:nil includeHiddenWrites:NO]; +} + +/** +* @return If possible, returns a children node containing all of the complete children we have data for. The returned +* data is a mix of the given server data and write data. +*/ +- (FChildrenNode *) calculateCompleteEventChildrenWithCompleteServerChildren:(id)completeServerChildren { + return [self.writeTree calculateCompleteEventChildrenAtPath:self.path completeServerChildren:completeServerChildren]; +} + +/** +* Given that either the underlying server data has updated or the outstanding writes have been updating, determine what, +* if anything, needs to be applied to the event cache. +* +* Possibilities: +* +* 1. No writes are shadowing. Events should be raised, the snap to be applied comes from the server data. +* +* 2. Some writes are completly shadowing. No events to be raised. +* +* 3. Is partially shadowed. Events should be raised. +* +* Either existingEventSnap or existingServerSnap must exist, this is validated via an assert. +*/ +- (id) calculateEventCacheAfterServerOverwriteWithChildPath:(FPath *)childPath existingEventSnap:(id )existingEventSnap existingServerSnap:(id )existingServerSnap { + return [self.writeTree calculateEventCacheAfterServerOverwriteAtPath:self.path childPath:childPath existingEventSnap:existingEventSnap existingServerSnap:existingServerSnap]; +} + +/** +* Returns a node if there is a complete overwrite for this path. More specifically, if there is a write at a higher +* path, this will return the child of that write relative to the write and this path. +* Returns nil if there is no write at this path. +*/ +- (id) shadowingWriteAtPath:(FPath *)path { + return [self.writeTree shadowingWriteAtPath:[self.path child:path]]; +} + +/** +* This method is used when processing child remove events on a query. If we can, we pull in children that are outside +* the window, but may now be in the window. +*/ +- (FNamedNode *)calculateNextNodeAfterPost:(FNamedNode *)post + completeServerData:(id)completeServerData + reverse:(BOOL)reverse + index:(id)index +{ + return [self.writeTree calculateNextNodeAfterPost:post + atPath:self.path + completeServerData:completeServerData + reverse:reverse + index:index]; +} + +/** +* Returns a complete child for a given server snap after applying all user writes or nil if there is no complete child +* for this child key. +*/ +- (id) calculateCompleteChild:(NSString *)childKey cache:(FCacheNode *)existingServerCache { + return [self.writeTree calculateCompleteChildAtPath:self.path childKey:childKey cache:existingServerCache]; +} + +/** +* @return a WriteTreeref for a child. +*/ +- (FWriteTreeRef *) childWriteTreeRef:(NSString *)childKey { + return [[FWriteTreeRef alloc] initWithPath:[self.path childFromString:childKey] writeTree:self.writeTree]; +} + + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FAckUserWrite.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FAckUserWrite.h new file mode 100644 index 00000000..a3379963 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FAckUserWrite.h @@ -0,0 +1,35 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FOperation.h" + +@class FPath; +@class FOperationSource; +@class FImmutableTree; + + +@interface FAckUserWrite : NSObject + +- initWithPath:(FPath *)operationPath affectedTree:(FImmutableTree *)affectedTree revert:(BOOL)shouldRevert; + +@property (nonatomic, strong, readonly) FOperationSource *source; +@property (nonatomic, readonly) FOperationType type; +@property (nonatomic, strong, readonly) FPath *path; +// A FImmutableTree, containing @YES for each affected path. Affected paths can't overlap. +@property (nonatomic, strong, readonly) FImmutableTree *affectedTree; +@property (nonatomic, readonly) BOOL revert; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FAckUserWrite.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FAckUserWrite.m new file mode 100644 index 00000000..f81e7f5d --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FAckUserWrite.m @@ -0,0 +1,55 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FAckUserWrite.h" +#import "FPath.h" +#import "FOperationSource.h" +#import "FImmutableTree.h" + + +@implementation FAckUserWrite + +- (id) initWithPath:(FPath *)operationPath affectedTree:(FImmutableTree *)tree revert:(BOOL)shouldRevert { + self = [super init]; + if (self) { + self->_source = [FOperationSource userInstance]; + self->_type = FOperationTypeAckUserWrite; + self->_path = operationPath; + self->_affectedTree = tree; + self->_revert = shouldRevert; + } + return self; +} + +- (FAckUserWrite *) operationForChild:(NSString *)childKey { + if (![self.path isEmpty]) { + NSAssert([self.path.getFront isEqualToString:childKey], @"operationForChild called for unrelated child."); + return [[FAckUserWrite alloc] initWithPath:[self.path popFront] affectedTree:self.affectedTree revert:self.revert]; + } else if (self.affectedTree.value != nil) { + NSAssert(self.affectedTree.children.isEmpty, @"affectedTree should not have overlapping affected paths."); + // All child locations are affected as well; just return same operation. + return self; + } else { + FImmutableTree *childTree = [self.affectedTree subtreeAtPath:[[FPath alloc] initWith:childKey]]; + return [[FAckUserWrite alloc] initWithPath:[FPath empty] affectedTree:childTree revert:self.revert]; + } +} + +- (NSString *) description { + return [NSString stringWithFormat:@"FAckUserWrite { path=%@, revert=%d, affectedTree=%@ }", self.path, self.revert, self.affectedTree]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FMerge.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FMerge.h new file mode 100644 index 00000000..4cab6139 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FMerge.h @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FOperation.h" + +@class FCompoundWrite; + +@interface FMerge : NSObject + +- (id) initWithSource:(FOperationSource *)aSource path:(FPath *)aPath children:(FCompoundWrite *)children; + +@property (nonatomic, strong, readonly) FOperationSource *source; +@property (nonatomic, readonly) FOperationType type; +@property (nonatomic, strong, readonly) FPath *path; +@property (nonatomic, strong, readonly) FCompoundWrite *children; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FMerge.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FMerge.m new file mode 100644 index 00000000..8e6d9249 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FMerge.m @@ -0,0 +1,71 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FMerge.h" +#import "FOperationSource.h" +#import "FPath.h" +#import "FNode.h" +#import "FOverwrite.h" +#import "FCompoundWrite.h" + +@interface FMerge () +@property (nonatomic, strong, readwrite) FOperationSource *source; +@property (nonatomic, readwrite) FOperationType type; +@property (nonatomic, strong, readwrite) FPath *path; +@property (nonatomic, strong) FCompoundWrite *children; +@end + +@implementation FMerge + +@synthesize source; +@synthesize type; +@synthesize path; +@synthesize children; + +- (id) initWithSource:(FOperationSource *)aSource path:(FPath *)aPath children:(FCompoundWrite *)someChildren { + self = [super init]; + if (self) { + self.source = aSource; + self.type = FOperationTypeMerge; + self.path = aPath; + self.children = someChildren; + } + return self; +} + +- (id) operationForChild:(NSString *)childKey { + if ([self.path isEmpty]) { + FCompoundWrite *childTree = [self.children childCompoundWriteAtPath:[[FPath alloc] initWith:childKey]]; + if (childTree.isEmpty) { + return nil; + } else if (childTree.rootWrite != nil) { + // We have a snapshot for the child in question. This becomes an overwrite of the child. + return [[FOverwrite alloc] initWithSource:self.source path:[FPath empty] snap:childTree.rootWrite]; + } else { + // This is a merge at a deeper level + return [[FMerge alloc] initWithSource:self.source path:[FPath empty] children:childTree]; + } + } else { + NSAssert([self.path.getFront isEqualToString:childKey], @"Can't get a merge for a child not on the path of the operation"); + return [[FMerge alloc] initWithSource:self.source path:[self.path popFront] children:self.children]; + } +} + +- (NSString *) description { + return [NSString stringWithFormat:@"FMerge { path=%@, soruce=%@ children=%@}", self.path, self.source, self.children]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FOperation.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FOperation.h new file mode 100644 index 00000000..2bbbbd2e --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FOperation.h @@ -0,0 +1,34 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class FOperationSource; +@class FPath; + +typedef NS_ENUM(NSInteger, FOperationType) { + FOperationTypeOverwrite = 0, + FOperationTypeMerge = 1, + FOperationTypeAckUserWrite = 2, + FOperationTypeListenComplete = 3 +}; + +@protocol FOperation +@property (nonatomic, strong, readonly) FOperationSource *source; +@property (nonatomic, readonly) FOperationType type; +@property (nonatomic, strong, readonly) FPath *path; +- (id) operationForChild:(NSString *)childKey; +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FOperationSource.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FOperationSource.h new file mode 100644 index 00000000..a069c2f6 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FOperationSource.h @@ -0,0 +1,34 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class FQueryParams; + +@interface FOperationSource : NSObject + +@property (nonatomic, readonly) BOOL fromUser; +@property (nonatomic, readonly) BOOL fromServer; +@property (nonatomic, readonly) BOOL isTagged; +@property (nonatomic, strong, readonly) FQueryParams *queryParams; + +- initWithFromUser:(BOOL)isFromUser fromServer:(BOOL)isFromServer queryParams:(FQueryParams *)params tagged:(BOOL)isTagged; + ++ (FOperationSource *) userInstance; ++ (FOperationSource *) serverInstance; ++ (FOperationSource *) forServerTaggedQuery:(FQueryParams *)params; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FOperationSource.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FOperationSource.m new file mode 100644 index 00000000..9a34a2ee --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FOperationSource.m @@ -0,0 +1,73 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FOperationSource.h" +#import "FPath.h" +#import "FQueryParams.h" + +@interface FOperationSource () +@property (nonatomic, readwrite) BOOL fromUser; +@property (nonatomic, readwrite) BOOL fromServer; +@property (nonatomic, readwrite) BOOL isTagged; +@property (nonatomic, strong, readwrite) FQueryParams *queryParams; +@end + +@implementation FOperationSource + +@synthesize fromUser; +@synthesize fromServer; +@synthesize queryParams; + +- (id) initWithFromUser:(BOOL)isFromUser fromServer:(BOOL)isFromServer queryParams:(FQueryParams *)params tagged:(BOOL)tagged { + self = [super init]; + if (self) { + self.fromUser = isFromUser; + self.fromServer = isFromServer; + self.queryParams = params; + self.isTagged = tagged; + } + return self; +} + ++ (FOperationSource *) userInstance { + static FOperationSource *user = nil; + static dispatch_once_t userToken; + dispatch_once(&userToken, ^{ + user = [[FOperationSource alloc] initWithFromUser:YES fromServer:NO queryParams:nil tagged:NO]; + }); + return user; +} + ++ (FOperationSource *) serverInstance { + static FOperationSource *server = nil; + static dispatch_once_t serverToken; + dispatch_once(&serverToken, ^{ + server = [[FOperationSource alloc] initWithFromUser:NO fromServer:YES queryParams:nil tagged:NO]; + }); + return server; +} + ++ (FOperationSource *) forServerTaggedQuery:(FQueryParams *)params { + return [[FOperationSource alloc] initWithFromUser:NO fromServer:YES queryParams:params tagged:YES]; +} + +- (NSString *) description { + return [NSString stringWithFormat:@"FOperationSource { fromUser=%d, fromServer=%d, queryId=%@, tagged=%d }", + self.fromUser, self.fromServer, self.queryParams, self.isTagged]; +} + + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FOverwrite.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FOverwrite.h new file mode 100644 index 00000000..e950beda --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FOverwrite.h @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FOperation.h" + +@protocol FNode; + +@interface FOverwrite : NSObject + +- (id) initWithSource:(FOperationSource *)aSource path:(FPath *)aPath snap:(id)aSnap; + +@property (nonatomic, strong, readonly) FOperationSource *source; +@property (nonatomic, readonly) FOperationType type; +@property (nonatomic, strong, readonly) FPath *path; +@property (nonatomic, strong, readonly) id snap; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FOverwrite.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FOverwrite.m new file mode 100644 index 00000000..b72d31a6 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Operation/FOverwrite.m @@ -0,0 +1,62 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FOverwrite.h" +#import "FNode.h" +#import "FOperationSource.h" + +@interface FOverwrite () +@property (nonatomic, strong, readwrite) FOperationSource *source; +@property (nonatomic, readwrite) FOperationType type; +@property (nonatomic, strong, readwrite) FPath *path; +@property (nonatomic, strong) id snap; +@end + +@implementation FOverwrite + +@synthesize source; +@synthesize type; +@synthesize path; +@synthesize snap; + +- (id) initWithSource:(FOperationSource *)aSource path:(FPath *)aPath snap:(id )aSnap { + self = [super init]; + if (self) { + self.source = aSource; + self.type = FOperationTypeOverwrite; + self.path = aPath; + self.snap = aSnap; + } + return self; +} + +- (FOverwrite *) operationForChild:(NSString *)childKey { + if ([self.path isEmpty]) { + return [[FOverwrite alloc] initWithSource:self.source + path:[FPath empty] + snap:[self.snap getImmediateChild:childKey]]; + } else { + return [[FOverwrite alloc] initWithSource:self.source + path:[self.path popFront] + snap:self.snap]; + } +} + +- (NSString *) description { + return [NSString stringWithFormat:@"FOverwrite { path=%@, source=%@, snapshot=%@ }", self.path, self.source, self.snap]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FIRRetryHelper.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FIRRetryHelper.h new file mode 100644 index 00000000..f83aad98 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FIRRetryHelper.h @@ -0,0 +1,33 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@interface FIRRetryHelper : NSObject + +- (instancetype) initWithDispatchQueue:(dispatch_queue_t)dispatchQueue + minRetryDelayAfterFailure:(NSTimeInterval)minRetryDelayAfterFailure + maxRetryDelay:(NSTimeInterval)maxRetryDelay + retryExponent:(double)retryExponent + jitterFactor:(double)jitterFactor; + +- (void) retry:(void (^)(void))block; + +- (void) cancel; + +- (void) signalSuccess; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FIRRetryHelper.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FIRRetryHelper.m new file mode 100644 index 00000000..fca02f58 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FIRRetryHelper.m @@ -0,0 +1,140 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FIRRetryHelper.h" +#import "FUtilities.h" + +@interface FIRRetryHelperTask : NSObject + +@property (nonatomic, strong) void (^block)(void); + +@end + +@implementation FIRRetryHelperTask + +- (instancetype) initWithBlock:(void (^)(void))block { + self = [super init]; + if (self != nil) { + self->_block = [block copy]; + } + return self; +} + +- (BOOL) isCanceled { + return self.block == nil; +} + +- (void) cancel { + self.block = nil; +} + +- (void) execute { + if (self.block) { + self.block(); + } +} + +@end + + + +@interface FIRRetryHelper () + +@property (nonatomic, strong) dispatch_queue_t dispatchQueue; +@property (nonatomic) NSTimeInterval minRetryDelayAfterFailure; +@property (nonatomic) NSTimeInterval maxRetryDelay; +@property (nonatomic) double retryExponent; +@property (nonatomic) double jitterFactor; + +@property (nonatomic) BOOL lastWasSuccess; +@property (nonatomic) NSTimeInterval currentRetryDelay; + +@property (nonatomic, strong) FIRRetryHelperTask *scheduledRetry; + +@end + +@implementation FIRRetryHelper + +- (instancetype) initWithDispatchQueue:(dispatch_queue_t)dispatchQueue + minRetryDelayAfterFailure:(NSTimeInterval)minRetryDelayAfterFailure + maxRetryDelay:(NSTimeInterval)maxRetryDelay + retryExponent:(double)retryExponent + jitterFactor:(double)jitterFactor { + self = [super init]; + if (self != nil) { + self->_dispatchQueue = dispatchQueue; + self->_minRetryDelayAfterFailure = minRetryDelayAfterFailure; + self->_maxRetryDelay = maxRetryDelay; + self->_retryExponent = retryExponent; + self->_jitterFactor = jitterFactor; + self->_lastWasSuccess = YES; + } + return self; +} + +- (void) retry:(void (^)(void))block { + if (self.scheduledRetry != nil) { + FFLog(@"I-RDB054001", @"Canceling existing retry attempt"); + [self.scheduledRetry cancel]; + self.scheduledRetry = nil; + } + + NSTimeInterval delay; + if (self.lastWasSuccess) { + delay = 0; + } else { + if (self.currentRetryDelay == 0) { + self.currentRetryDelay = self.minRetryDelayAfterFailure; + } else { + NSTimeInterval newDelay = (self.currentRetryDelay * self.retryExponent); + self.currentRetryDelay = MIN(newDelay, self.maxRetryDelay); + } + + delay = ((1 - self.jitterFactor) * self.currentRetryDelay) + + (self.jitterFactor * self.currentRetryDelay * [FUtilities randomDouble]); + FFLog(@"I-RDB054002", @"Scheduling retry in %fs", delay); + + } + self.lastWasSuccess = NO; + FIRRetryHelperTask *task = [[FIRRetryHelperTask alloc] initWithBlock:block]; + self.scheduledRetry = task; + dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (long long)(delay * NSEC_PER_SEC)); + dispatch_after(popTime, self.dispatchQueue, ^{ + if (![task isCanceled]) { + self.scheduledRetry = nil; + [task execute]; + } + }); +} + +- (void) signalSuccess { + self.lastWasSuccess = YES; + self.currentRetryDelay = 0; +} + +- (void) cancel { + if (self.scheduledRetry != nil) { + FFLog(@"I-RDB054003", @"Canceling existing retry attempt"); + [self.scheduledRetry cancel]; + self.scheduledRetry = nil; + } else { + FFLog(@"I-RDB054004", @"No existing retry attempt to cancel"); + } + self.currentRetryDelay = 0; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FImmutableTree.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FImmutableTree.h new file mode 100644 index 00000000..005a9f20 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FImmutableTree.h @@ -0,0 +1,51 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FImmutableSortedDictionary.h" +#import "FPath.h" +#import "FTuplePathValue.h" + +@interface FImmutableTree : NSObject + +- (id) initWithValue:(id)aValue; +- (id) initWithValue:(id)aValue children:(FImmutableSortedDictionary *)childrenMap; + ++ (FImmutableTree *) empty; +- (BOOL) isEmpty; + +- (FTuplePathValue *) findRootMostMatchingPath:(FPath *)relativePath predicate:(BOOL (^)(id))predicate; +- (FTuplePathValue *) findRootMostValueAndPath:(FPath *)relativePath; +- (FImmutableTree *) subtreeAtPath:(FPath *)relativePath; +- (FImmutableTree *) setValue:(id)newValue atPath:(FPath *)relativePath; +- (FImmutableTree *) removeValueAtPath:(FPath *)relativePath; +- (id) valueAtPath:(FPath *)relativePath; +- (id) rootMostValueOnPath:(FPath *)path; +- (id) rootMostValueOnPath:(FPath *)path matching:(BOOL (^)(id))predicate; +- (id) leafMostValueOnPath:(FPath *)path; +- (id) leafMostValueOnPath:(FPath *)relativePath matching:(BOOL (^)(id))predicate; +- (BOOL) containsValueMatching:(BOOL (^)(id))predicate; +- (FImmutableTree *) setTree:(FImmutableTree *)newTree atPath:(FPath *)relativePath; +- (id) foldWithBlock:(id (^)(FPath *path, id value, NSDictionary *foldedChildren))block; +- (id) findOnPath:(FPath *)path andApplyBlock:(id (^)(FPath *path, id value))block; +- (FPath *) forEachOnPath:(FPath *)path whileBlock:(BOOL (^)(FPath *path, id value))block; +- (FImmutableTree *) forEachOnPath:(FPath *)path performBlock:(void (^)(FPath *path, id value))block; +- (void) forEach:(void (^)(FPath *path, id value))block; +- (void) forEachChild:(void (^)(NSString *childKey, id childValue))block; + +@property (nonatomic, strong, readonly) id value; +@property (nonatomic, strong, readonly) FImmutableSortedDictionary *children; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FImmutableTree.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FImmutableTree.m new file mode 100644 index 00000000..57bf74d5 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FImmutableTree.m @@ -0,0 +1,421 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FImmutableTree.h" +#import "FImmutableSortedDictionary.h" +#import "FPath.h" +#import "FUtilities.h" + +@interface FImmutableTree () +@property (nonatomic, strong, readwrite) id value; +/** +* Maps NSString -> FImmutableTree, where is type of value. +*/ +@property (nonatomic, strong, readwrite) FImmutableSortedDictionary *children; +@end + +@implementation FImmutableTree +@synthesize value; +@synthesize children; + +- (id) initWithValue:(id)aValue { + self = [super init]; + if (self) { + self.value = aValue; + self.children = [FImmutableTree emptyChildren]; + } + return self; +} + +- (id) initWithValue:(id)aValue children:(FImmutableSortedDictionary *)childrenMap { + self = [super init]; + if (self) { + self.value = aValue; + self.children = childrenMap; + } + return self; +} + ++ (FImmutableSortedDictionary *) emptyChildren { + static dispatch_once_t emptyChildrenToken; + static FImmutableSortedDictionary *emptyChildren; + dispatch_once(&emptyChildrenToken, ^{ + emptyChildren = [FImmutableSortedDictionary dictionaryWithComparator:[FUtilities stringComparator]]; + }); + return emptyChildren; +} + ++ (FImmutableTree *) empty { + static dispatch_once_t emptyImmutableTreeToken; + static FImmutableTree *emptyTree = nil; + dispatch_once(&emptyImmutableTreeToken, ^{ + emptyTree = [[FImmutableTree alloc] initWithValue:nil]; + }); + return emptyTree; +} + +- (BOOL) isEmpty { + return self.value == nil && [self.children isEmpty]; +} + +/** +* Given a path and a predicate, return the first node and the path to that node where the predicate returns true +* // TODO Do a perf test. If we're creating a bunch of FTuplePathValue objects on the way back out, it may be better to pass down a pathSoFar FPath +*/ +- (FTuplePathValue *) findRootMostMatchingPath:(FPath *)relativePath predicate:(BOOL (^)(id value))predicate { + if (self.value != nil && predicate(self.value)) { + return [[FTuplePathValue alloc] initWithPath:[FPath empty] value:self.value]; + } else { + if ([relativePath isEmpty]) { + return nil; + } else { + NSString *front = [relativePath getFront]; + FImmutableTree *child = [self.children get:front]; + if (child != nil) { + FTuplePathValue *childExistingPathAndValue = [child findRootMostMatchingPath:[relativePath popFront] predicate:predicate]; + if (childExistingPathAndValue != nil) { + FPath *fullPath = [[[FPath alloc] initWith:front] child:childExistingPathAndValue.path]; + return [[FTuplePathValue alloc] initWithPath:fullPath value:childExistingPathAndValue.value]; + } else { + return nil; + } + } else { + // No child matching path + return nil; + } + } + } +} + +/** +* Find, if it exists, the shortest subpath of the given path that points a defined value in the tree +*/ +- (FTuplePathValue *) findRootMostValueAndPath:(FPath *)relativePath { + return [self findRootMostMatchingPath:relativePath predicate:^BOOL(__unsafe_unretained id value){ + return YES; + }]; +} + +- (id) rootMostValueOnPath:(FPath *)path { + return [self rootMostValueOnPath:path matching:^BOOL(id value) { + return YES; + }]; +} + +- (id) rootMostValueOnPath:(FPath *)path matching:(BOOL (^)(id))predicate { + if (self.value != nil && predicate(self.value)) { + return self.value; + } else if (path.isEmpty) { + return nil; + } else { + return [[self.children get:path.getFront] rootMostValueOnPath:[path popFront] matching:predicate]; + } +} + +- (id) leafMostValueOnPath:(FPath *)path { + return [self leafMostValueOnPath:path matching:^BOOL(id value) { + return YES; + }]; +} + +- (id) leafMostValueOnPath:(FPath *)relativePath matching:(BOOL (^)(id))predicate { + __block id currentValue = self.value; + __block FImmutableTree *currentTree = self; + [relativePath enumerateComponentsUsingBlock:^(NSString *key, BOOL *stop) { + currentTree = [currentTree.children get:key]; + if (currentTree == nil) { + *stop = YES; + } else { + id treeValue = currentTree.value; + if (treeValue != nil && predicate(treeValue)) { + currentValue = treeValue; + } + } + }]; + return currentValue; +} + +- (BOOL) containsValueMatching:(BOOL (^)(id))predicate { + if (self.value != nil && predicate(self.value)) { + return YES; + } else { + __block BOOL found = NO; + [self.children enumerateKeysAndObjectsUsingBlock:^(NSString *key, FImmutableTree *subtree, BOOL *stop) { + found = [subtree containsValueMatching:predicate]; + if (found) *stop = YES; + }]; + return found; + } +} + +- (FImmutableTree *) subtreeAtPath:(FPath *)relativePath { + if ([relativePath isEmpty]) { + return self; + } else { + NSString *front = [relativePath getFront]; + FImmutableTree *childTree = [self.children get:front]; + if (childTree != nil) { + return [childTree subtreeAtPath:[relativePath popFront]]; + } else { + return [FImmutableTree empty]; + } + } +} + +/** +* Sets a value at the specified path +*/ +- (FImmutableTree *) setValue:(id)newValue atPath:(FPath *)relativePath { + if ([relativePath isEmpty]) { + return [[FImmutableTree alloc] initWithValue:newValue children:self.children]; + } else { + NSString *front = [relativePath getFront]; + FImmutableTree *child = [self.children get:front]; + if (child == nil) { + child = [FImmutableTree empty]; + } + FImmutableTree *newChild = [child setValue:newValue atPath:[relativePath popFront]]; + FImmutableSortedDictionary *newChildren = [self.children insertKey:front withValue:newChild]; + return [[FImmutableTree alloc] initWithValue:self.value children:newChildren]; + } +} + +/** +* Remove the value at the specified path +*/ +- (FImmutableTree *) removeValueAtPath:(FPath *)relativePath { + if ([relativePath isEmpty]) { + if ([self.children isEmpty]) { + return [FImmutableTree empty]; + } else { + return [[FImmutableTree alloc] initWithValue:nil children:self.children]; + } + } else { + NSString *front = [relativePath getFront]; + FImmutableTree *child = [self.children get:front]; + if (child) { + FImmutableTree *newChild = [child removeValueAtPath:[relativePath popFront]]; + FImmutableSortedDictionary *newChildren; + if ([newChild isEmpty]) { + newChildren = [self.children removeKey:front]; + } else { + newChildren = [self.children insertKey:front withValue:newChild]; + } + if (self.value == nil && [newChildren isEmpty]) { + return [FImmutableTree empty]; + } else { + return [[FImmutableTree alloc] initWithValue:self.value children:newChildren]; + } + } else { + return self; + } + } +} + +/** +* Gets a value from the tree +*/ +- (id) valueAtPath:(FPath *)relativePath { + if ([relativePath isEmpty]) { + return self.value; + } else { + NSString *front = [relativePath getFront]; + FImmutableTree *child = [self.children get:front]; + if (child) { + return [child valueAtPath:[relativePath popFront]]; + } else { + return nil; + } + } +} + +/** +* Replaces the subtree at the specified path with the given new tree +*/ +- (FImmutableTree *) setTree:(FImmutableTree *)newTree atPath:(FPath *)relativePath { + if ([relativePath isEmpty]) { + return newTree; + } else { + NSString *front = [relativePath getFront]; + FImmutableTree *child = [self.children get:front]; + if (child == nil) { + child = [FImmutableTree empty]; + } + FImmutableTree *newChild = [child setTree:newTree atPath:[relativePath popFront]]; + FImmutableSortedDictionary *newChildren; + if ([newChild isEmpty]) { + newChildren = [self.children removeKey:front]; + } else { + newChildren = [self.children insertKey:front withValue:newChild]; + } + return [[FImmutableTree alloc] initWithValue:self.value children:newChildren]; + } +} + +/** +* Performs a depth first fold on this tree. Transforms a tree into a single value, given a function that operates on +* the path to a node, an optional current value, and a map of the child names to folded subtrees +*/ +- (id) foldWithBlock:(id (^)(FPath *path, id value, NSDictionary *foldedChildren))block { + return [self foldWithPathSoFar:[FPath empty] withBlock:block]; +} + +/** +* Recursive helper for public facing foldWithBlock: method +*/ +- (id) foldWithPathSoFar:(FPath *)pathSoFar withBlock:(id (^)(FPath *path, id value, NSDictionary *foldedChildren))block { + __block NSMutableDictionary *accum = [[NSMutableDictionary alloc] init]; + [self.children enumerateKeysAndObjectsUsingBlock:^(NSString *childKey, FImmutableTree *childTree, BOOL *stop) { + accum[childKey] = [childTree foldWithPathSoFar:[pathSoFar childFromString:childKey] withBlock:block]; + }]; + return block(pathSoFar, self.value, accum); +} + +/** +* Find the first matching value on the given path. Return the result of applying block to it. +*/ +- (id) findOnPath:(FPath *)path andApplyBlock:(id (^)(FPath *path, id value))block { + return [self findOnPath:path pathSoFar:[FPath empty] andApplyBlock:block]; +} + +- (id) findOnPath:(FPath *)pathToFollow pathSoFar:(FPath *)pathSoFar andApplyBlock:(id (^)(FPath *path, id value))block { + id result = self.value ? block(pathSoFar, self.value) : nil; + if (result != nil) { + return result; + } else { + if ([pathToFollow isEmpty]) { + return nil; + } else { + NSString *front = [pathToFollow getFront]; + FImmutableTree *nextChild = [self.children get:front]; + if (nextChild != nil) { + return [nextChild findOnPath:[pathToFollow popFront] pathSoFar:[pathSoFar childFromString:front] andApplyBlock:block]; + } else { + return nil; + } + } + } +} +/** +* Call the block on each value along the path for as long as that function returns true +* @return The path to the deepest location inspected +*/ +- (FPath *) forEachOnPath:(FPath *)path whileBlock:(BOOL (^)(FPath *, id))block { + return [self forEachOnPath:path pathSoFar:[FPath empty] whileBlock:block]; +} + +- (FPath *) forEachOnPath:(FPath *)pathToFollow pathSoFar:(FPath *)pathSoFar whileBlock:(BOOL (^)(FPath *, id))block { + if ([pathToFollow isEmpty]) { + if (self.value) { + block(pathSoFar, self.value); + } + return pathSoFar; + } else { + BOOL shouldContinue = YES; + if (self.value) { + shouldContinue = block(pathSoFar, self.value); + } + if (shouldContinue) { + NSString *front = [pathToFollow getFront]; + FImmutableTree *nextChild = [self.children get:front]; + if (nextChild) { + return [nextChild forEachOnPath:[pathToFollow popFront] pathSoFar:[pathSoFar childFromString:front] whileBlock:block]; + } else { + return pathSoFar; + } + } else { + return pathSoFar; + } + } +} + +- (FImmutableTree *) forEachOnPath:(FPath *)path performBlock:(void (^)(FPath *path, id value))block { + return [self forEachOnPath:path pathSoFar:[FPath empty] performBlock:block]; +} + +- (FImmutableTree *) forEachOnPath:(FPath *)pathToFollow pathSoFar:(FPath *)pathSoFar performBlock:(void (^)(FPath *path, id value))block { + if ([pathToFollow isEmpty]) { + return self; + } else { + if (self.value) { + block(pathSoFar, self.value); + } + NSString *front = [pathToFollow getFront]; + FImmutableTree *nextChild = [self.children get:front]; + if (nextChild) { + return [nextChild forEachOnPath:[pathToFollow popFront] pathSoFar:[pathSoFar childFromString:front] performBlock:block]; + } else { + return [FImmutableTree empty]; + } + } +} +/** +* Calls the given block for each node in the tree that has a value. Called in depth-first order +*/ +- (void) forEach:(void (^)(FPath *path, id value))block { + [self forEachPathSoFar:[FPath empty] withBlock:block]; +} + +- (void) forEachPathSoFar:(FPath *)pathSoFar withBlock:(void (^)(FPath *path, id value))block { + [self.children enumerateKeysAndObjectsUsingBlock:^(NSString *childKey, FImmutableTree *childTree, BOOL *stop) { + [childTree forEachPathSoFar:[pathSoFar childFromString:childKey] withBlock:block]; + }]; + if (self.value) { + block(pathSoFar, self.value); + } +} + +- (void) forEachChild:(void (^)(NSString *childKey, id childValue))block { + [self.children enumerateKeysAndObjectsUsingBlock:^(NSString *childKey, FImmutableTree *childTree, BOOL *stop) { + if (childTree.value) { + block(childKey, childTree.value); + } + }]; +} + +- (BOOL)isEqual:(id)object { + if (![object isKindOfClass:[FImmutableTree class]]) { + return NO; + } + FImmutableTree *other = (FImmutableTree *)object; + return (self.value == other.value || [self.value isEqual:other.value]) && [self.children isEqual:other.children]; +} + +- (NSUInteger)hash { + return self.children.hash * 31 + [self.value hash]; +} + +- (NSString *) description { + NSMutableString *string = [[NSMutableString alloc] init]; + [string appendString:@"FImmutableTree { value="]; + [string appendString:(self.value ? [self.value description] : @"")]; + [string appendString:@", children={"]; + [self.children enumerateKeysAndObjectsUsingBlock:^(NSString *childKey, FImmutableTree *childTree, BOOL *stop) { + [string appendString:@" "]; + [string appendString:childKey]; + [string appendString:@"="]; + [string appendString:[childTree.value description]]; + }]; + [string appendString:@" } }"]; + return [NSString stringWithString:string]; +} + +- (NSString *) debugDescription { + return [self description]; +} + + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FPath.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FPath.h new file mode 100644 index 00000000..71a7167b --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FPath.h @@ -0,0 +1,45 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@interface FPath : NSObject + ++ (FPath *) relativePathFrom:(FPath *)outer to:(FPath *)inner; ++ (FPath *) empty; ++ (FPath *) pathWithString:(NSString *)string; + +- (id)initWith:(NSString *)path; +- (id)initWithPieces:(NSArray *)somePieces andPieceNum:(NSInteger)aPieceNum; + +- (id)copyWithZone:(NSZone *)zone; + +- (void)enumerateComponentsUsingBlock:(void (^)(NSString *key, BOOL *stop))block; +- (NSString *) getFront; +- (NSUInteger) length; +- (FPath *) popFront; +- (NSString *) getBack; +- (NSString *) toString; +- (NSString *) toStringWithTrailingSlash; +- (NSString *) wireFormat; +- (FPath *) parent; +- (FPath *) child:(FPath *)childPathObj; +- (FPath *) childFromString:(NSString *)childPath; +- (BOOL) isEmpty; +- (BOOL) contains:(FPath *)other; +- (NSComparisonResult) compare:(FPath *)other; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FPath.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FPath.m new file mode 100644 index 00000000..5215596e --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FPath.m @@ -0,0 +1,298 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FPath.h" + +#import "FUtilities.h" + +@interface FPath() + +@property (nonatomic, readwrite, assign) NSInteger pieceNum; +@property (nonatomic, strong) NSArray * pieces; + +@end + +@implementation FPath + +#pragma mark - +#pragma mark Initializers + ++ (FPath *) relativePathFrom:(FPath *)outer to:(FPath *)inner { + NSString* outerFront = [outer getFront]; + NSString* innerFront = [inner getFront]; + if (outerFront == nil) { + return inner; + } else if ([outerFront isEqualToString:innerFront]) { + return [self relativePathFrom:[outer popFront] to:[inner popFront]]; + } else { + @throw [[NSException alloc] initWithName:@"FirebaseDatabaseInternalError" reason:[NSString stringWithFormat:@"innerPath (%@) is not within outerPath (%@)", inner, outer] userInfo:nil]; + } +} + ++ (FPath *)pathWithString:(NSString *)string +{ + return [[FPath alloc] initWith:string]; +} + +- (id)initWith:(NSString *)path +{ + self = [super init]; + if (self) { + NSArray *pathPieces = [path componentsSeparatedByString:@"/"]; + NSMutableArray *newPieces = [[NSMutableArray alloc] init]; + for (NSInteger i = 0; i < pathPieces.count; i++) { + NSString *piece = [pathPieces objectAtIndex:i]; + if (piece.length > 0) { + [newPieces addObject:piece]; + } + } + + self.pieces = newPieces; + self.pieceNum = 0; + } + return self; +} + +- (id)initWithPieces:(NSArray *)somePieces andPieceNum:(NSInteger)aPieceNum { + self = [super init]; + if (self) { + self.pieceNum = aPieceNum; + self.pieces = somePieces; + } + return self; +} + +- (id)copyWithZone:(NSZone *)zone +{ + // Immutable, so it's safe to return self + return self; +} + +- (NSString *)description { + return [self toString]; +} + +#pragma mark - +#pragma mark Public methods + +- (NSString *) getFront { + if(self.pieceNum >= self.pieces.count) { + return nil; + } + return [self.pieces objectAtIndex:self.pieceNum]; +} + +/** +* @return The number of segments in this path +*/ +- (NSUInteger) length { + return self.pieces.count - self.pieceNum; +} + +- (FPath *) popFront { + NSInteger newPieceNum = self.pieceNum; + if (newPieceNum < self.pieces.count) { + newPieceNum++; + } + return [[FPath alloc] initWithPieces:self.pieces andPieceNum:newPieceNum]; +} + +- (NSString *) getBack { + if(self.pieceNum < self.pieces.count) { + return [self.pieces lastObject]; + } + else { + return nil; + } +} + +- (NSString *) toString { + return [self toStringWithTrailingSlash:NO]; +} + +- (NSString *) toStringWithTrailingSlash { + return [self toStringWithTrailingSlash:YES]; +} + +- (NSString *) toStringWithTrailingSlash:(BOOL)trailingSlash { + NSMutableString* pathString = [[NSMutableString alloc] init]; + for(NSInteger i = self.pieceNum; i < self.pieces.count; i++) { + [pathString appendString:@"/"]; + [pathString appendString:[self.pieces objectAtIndex:i]]; + } + if ([pathString length] == 0) { + return @"/"; + } else { + if (trailingSlash) { + [pathString appendString:@"/"]; + } + return pathString; + } +} + +- (NSString *)wireFormat { + if ([self isEmpty]) { + return @"/"; + } else { + NSMutableString* pathString = [[NSMutableString alloc] init]; + for (NSInteger i = self.pieceNum; i < self.pieces.count; i++) { + if (i > self.pieceNum) { + [pathString appendString:@"/"]; + } + [pathString appendString:[self.pieces objectAtIndex:i]]; + } + return pathString; + } +} + +- (FPath *) parent { + if(self.pieceNum >= self.pieces.count) { + return nil; + } else { + NSMutableArray* newPieces = [[NSMutableArray alloc] init]; + for (NSInteger i = self.pieceNum; i < self.pieces.count - 1; i++) { + [newPieces addObject:[self.pieces objectAtIndex:i]]; + } + return [[FPath alloc] initWithPieces:newPieces andPieceNum:0]; + } +} + +- (FPath *) child:(FPath *)childPathObj { + NSMutableArray* newPieces = [[NSMutableArray alloc] init]; + for (NSInteger i = self.pieceNum; i < self.pieces.count; i++) { + [newPieces addObject:[self.pieces objectAtIndex:i]]; + } + + for (NSInteger i = childPathObj.pieceNum; i < childPathObj.pieces.count; i++) { + [newPieces addObject:[childPathObj.pieces objectAtIndex:i]]; + } + + return [[FPath alloc] initWithPieces:newPieces andPieceNum:0]; +} + +- (FPath *)childFromString:(NSString *)childPath { + NSMutableArray* newPieces = [[NSMutableArray alloc] init]; + for (NSInteger i = self.pieceNum; i < self.pieces.count; i++) { + [newPieces addObject:[self.pieces objectAtIndex:i]]; + } + + NSArray *pathPieces = [childPath componentsSeparatedByString:@"/"]; + for (unsigned int i = 0; i < pathPieces.count; i++) { + NSString *piece = [pathPieces objectAtIndex:i]; + if (piece.length > 0) { + [newPieces addObject:piece]; + } + } + + return [[FPath alloc] initWithPieces:newPieces andPieceNum:0]; +} + +/** +* @return True if there are no segments in this path +*/ +- (BOOL) isEmpty { + return self.pieceNum >= self.pieces.count; +} + +/** +* @return Singleton to represent an empty path +*/ ++ (FPath *) empty { + static dispatch_once_t oneEmptyPath; + static FPath *emptyPath; + dispatch_once(&oneEmptyPath, ^{ + emptyPath = [[FPath alloc] initWith:@""]; + }); + return emptyPath; +} + +- (BOOL) contains:(FPath *)other { + if (self.length > other.length) { + return NO; + } + + NSInteger i = self.pieceNum; + NSInteger j = other.pieceNum; + while (i < self.pieces.count) { + NSString* thisSeg = [self.pieces objectAtIndex:i]; + NSString* otherSeg = [other.pieces objectAtIndex:j]; + if (![thisSeg isEqualToString:otherSeg]) { + return NO; + } + ++i; + ++j; + } + return YES; +} + +- (void) enumerateComponentsUsingBlock:(void (^)(NSString *, BOOL *))block { + BOOL stop = NO; + for (NSInteger i = self.pieceNum; !stop && i < self.pieces.count; i++) { + block(self.pieces[i], &stop); + } +} + +- (NSComparisonResult) compare:(FPath *)other { + NSInteger myCount = self.pieces.count; + NSInteger otherCount = other.pieces.count; + for (NSInteger i = self.pieceNum, j = other.pieceNum; i < myCount && j < otherCount; i++, j++) { + NSComparisonResult comparison = [FUtilities compareKey:self.pieces[i] toKey:other.pieces[j]]; + if (comparison != NSOrderedSame) { + return comparison; + } + } + if (self.length < other.length) { + return NSOrderedAscending; + } else if (other.length < self.length) { + return NSOrderedDescending; + } else { + NSAssert(self.length == other.length, @"Paths must be the same lengths"); + return NSOrderedSame; + } +} + +/** +* @return YES if paths are the same +*/ +- (BOOL)isEqual:(id)other +{ + if (other == self) { + return YES; + } + if (!other || ![other isKindOfClass:[self class]]) { + return NO; + } + FPath *otherPath = (FPath *)other; + if (self.length != otherPath.length) { + return NO; + } + for (NSUInteger i = self.pieceNum, j = otherPath.pieceNum; i < self.pieces.count; i++, j++) { + if (![self.pieces[i] isEqualToString:otherPath.pieces[j]]) { + return NO; + } + } + return YES; +} + +- (NSUInteger) hash { + NSUInteger hashCode = 0; + for (NSInteger i = self.pieceNum; i < self.pieces.count; i++) { + hashCode = hashCode * 37 + [self.pieces[i] hash]; + } + return hashCode; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FTree.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FTree.h new file mode 100644 index 00000000..85285268 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FTree.h @@ -0,0 +1,48 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FTreeNode.h" +#import "FPath.h" + +@interface FTree : NSObject + +- (id)init; +- (id)initWithName:(NSString*)aName withParent:(FTree *)aParent withNode:(FTreeNode *)aNode; + +- (FTree *) subTree:(FPath*)path; +- (id)getValue; +- (void)setValue:(id)value; +- (void) clear; +- (BOOL) hasChildren; +- (BOOL) isEmpty; +- (void) forEachChildMutationSafe:(void (^)(FTree *))action; +- (void) forEachChild:(void (^)(FTree *))action; +- (void) forEachDescendant:(void (^)(FTree *))action; +- (void) forEachDescendant:(void (^)(FTree *))action includeSelf:(BOOL)incSelf childrenFirst:(BOOL)childFirst; +- (BOOL) forEachAncestor:(BOOL (^)(FTree *))action; +- (BOOL) forEachAncestor:(BOOL (^)(FTree *))action includeSelf:(BOOL)incSelf; +- (void) forEachImmediateDescendantWithValue:(void (^)(FTree *))action; +- (BOOL) valueExistsAtOrAbove:(FPath *)path; +- (FPath *)path; +- (void) updateParents; +- (void) updateChild:(NSString*)childName withNode:(FTree *)child; + +@property (nonatomic, strong) NSString* name; +@property (nonatomic, strong) FTree* parent; +@property (nonatomic, strong) FTreeNode* node; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FTree.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FTree.m new file mode 100644 index 00000000..8e7a334a --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FTree.m @@ -0,0 +1,183 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FTree.h" +#import "FTreeNode.h" +#import "FPath.h" +#import "FUtilities.h" + +@implementation FTree + +@synthesize name; +@synthesize parent; +@synthesize node; + +- (id)init +{ + self = [super init]; + if (self) { + self.name = @""; + self.parent = nil; + self.node = [[FTreeNode alloc] init]; + } + return self; +} + + +- (id)initWithName:(NSString*)aName withParent:(FTree *)aParent withNode:(FTreeNode *)aNode +{ + self = [super init]; + if (self) { + self.name = aName != nil ? aName : @""; + self.parent = aParent != nil ? aParent : nil; + self.node = aNode != nil ? aNode : [[FTreeNode alloc] init]; + } + return self; +} + +- (FTree *) subTree:(FPath*)path { + FTree* child = self; + NSString* next = [path getFront]; + while(next != nil) { + FTreeNode* childNode = child.node.children[next]; + if (childNode == nil) { + childNode = [[FTreeNode alloc] init]; + } + child = [[FTree alloc] initWithName:next withParent:child withNode:childNode]; + path = [path popFront]; + next = [path getFront]; + } + return child; +} + +- (id)getValue { + return self.node.value; +} + +- (void)setValue:(id)value { + self.node.value = value; + [self updateParents]; +} + +- (void) clear { + self.node.value = nil; + [self.node.children removeAllObjects]; + self.node.childCount = 0; + [self updateParents]; +} + +- (BOOL) hasChildren { + return self.node.childCount > 0; +} + +- (BOOL) isEmpty { + return [self getValue] == nil && ![self hasChildren]; +} + +- (void) forEachChild:(void (^)(FTree *))action { + for(NSString* key in self.node.children) { + action([[FTree alloc] initWithName:key withParent:self withNode:[self.node.children objectForKey:key]]); + } +} + +- (void) forEachChildMutationSafe:(void (^)(FTree *))action { + for(NSString* key in [self.node.children copy]) { + action([[FTree alloc] initWithName:key withParent:self withNode:[self.node.children objectForKey:key]]); + } +} + +- (void) forEachDescendant:(void (^)(FTree *))action { + [self forEachDescendant:action includeSelf:NO childrenFirst:NO]; +} + +- (void) forEachDescendant:(void (^)(FTree *))action includeSelf:(BOOL)incSelf childrenFirst:(BOOL)childFirst { + if(incSelf && !childFirst) { + action(self); + } + + [self forEachChild:^(FTree* child) { + [child forEachDescendant:action includeSelf:YES childrenFirst:childFirst]; + }]; + + if(incSelf && childFirst) { + action(self); + } +} + +- (BOOL) forEachAncestor:(BOOL (^)(FTree *))action { + return [self forEachAncestor:action includeSelf:NO]; +} + +- (BOOL) forEachAncestor:(BOOL (^)(FTree *))action includeSelf:(BOOL)incSelf { + FTree* aNode = (incSelf) ? self : self.parent; + while(aNode != nil) { + if(action(aNode)) { + return YES; + } + aNode = aNode.parent; + } + return NO; +} + +- (void) forEachImmediateDescendantWithValue:(void (^)(FTree *))action { + [self forEachChild:^(FTree * child) { + if([child getValue] != nil) { + action(child); + } + else { + [child forEachImmediateDescendantWithValue:action]; + } + }]; +} + +- (BOOL) valueExistsAtOrAbove:(FPath *)path { + FTreeNode* aNode = self.node; + while(aNode != nil) { + if(aNode.value != nil) { + return YES; + } + aNode = [aNode.children objectForKey:path.getFront]; + path = [path popFront]; + } + // XXX Check with Michael if this is correct; deviates from JS. + return NO; +} + +- (FPath *)path { + return [[FPath alloc] initWith:(self.parent == nil) ? self.name : + [NSString stringWithFormat:@"%@/%@", [self.parent path], self.name ]]; +} + +- (void) updateParents { + [self.parent updateChild:self.name withNode:self]; +} + +- (void) updateChild:(NSString*)childName withNode:(FTree *)child { + BOOL childEmpty = [child isEmpty]; + BOOL childExists = self.node.children[childName] != nil; + if(childEmpty && childExists) { + [self.node.children removeObjectForKey:childName]; + self.node.childCount = self.node.childCount - 1; + [self updateParents]; + } + else if(!childEmpty && !childExists) { + [self.node.children setObject:child.node forKey:childName]; + self.node.childCount = self.node.childCount + 1; + [self updateParents]; + } +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FTreeNode.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FTreeNode.h new file mode 100644 index 00000000..7e3497ea --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FTreeNode.h @@ -0,0 +1,25 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@interface FTreeNode : NSObject + +@property (nonatomic, strong) NSMutableDictionary* children; +@property (nonatomic, readwrite, assign) int childCount; +@property (nonatomic, strong) id value; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FTreeNode.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FTreeNode.m new file mode 100644 index 00000000..9cba9c5a --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/Utilities/FTreeNode.m @@ -0,0 +1,36 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FTreeNode.h" + +@implementation FTreeNode + +@synthesize children; +@synthesize childCount; +@synthesize value; + +- (id)init +{ + self = [super init]; + if (self) { + self.children = [[NSMutableDictionary alloc] init]; + self.childCount = 0; + self.value = nil; + } + return self; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FCacheNode.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FCacheNode.h new file mode 100644 index 00000000..b23869cb --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FCacheNode.h @@ -0,0 +1,44 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@protocol FNode; +@class FIndexedNode; +@class FPath; + +/** +* A cache node only stores complete children. Additionally it holds a flag whether the node can be considered fully +* initialized in the sense that we know at one point in time, this represented a valid state of the world, e.g. +* initialized with data from the server, or a complete overwrite by the client. It is not necessarily complete because +* it may have been from a tagged query. The filtered flag also tracks whether a node potentially had children removed +* due to a filter. +*/ +@interface FCacheNode : NSObject + +- (id) initWithIndexedNode:(FIndexedNode *)indexedNode + isFullyInitialized:(BOOL)fullyInitialized + isFiltered:(BOOL)filtered; + +- (BOOL) isCompleteForPath:(FPath *)path; +- (BOOL) isCompleteForChild:(NSString *)childKey; + +@property (nonatomic, readonly) BOOL isFullyInitialized; +@property (nonatomic, readonly) BOOL isFiltered; +@property (nonatomic, strong, readonly) FIndexedNode *indexedNode; +@property (nonatomic, strong, readonly) id node; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FCacheNode.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FCacheNode.m new file mode 100644 index 00000000..4767a259 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FCacheNode.m @@ -0,0 +1,60 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FCacheNode.h" +#import "FNode.h" +#import "FPath.h" +#import "FEmptyNode.h" +#import "FIndexedNode.h" + +@interface FCacheNode () +@property (nonatomic, readwrite) BOOL isFullyInitialized; +@property (nonatomic, readwrite) BOOL isFiltered; +@property (nonatomic, strong, readwrite) FIndexedNode *indexedNode; +@end + +@implementation FCacheNode +- (id) initWithIndexedNode:(FIndexedNode *)indexedNode + isFullyInitialized:(BOOL)fullyInitialized + isFiltered:(BOOL)filtered +{ + self = [super init]; + if (self) { + self.indexedNode = indexedNode; + self.isFullyInitialized = fullyInitialized; + self.isFiltered = filtered; + } + return self; +} + +- (BOOL)isCompleteForPath:(FPath *)path { + if (path.isEmpty) { + return self.isFullyInitialized && !self.isFiltered; + } else { + NSString *childKey = [path getFront]; + return [self isCompleteForChild:childKey]; + } +} + +- (BOOL)isCompleteForChild:(NSString *)childKey { + return (self.isFullyInitialized && !self.isFiltered) || [self.node hasChild:childKey]; +} + +- (id)node { + return self.indexedNode.node; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FCancelEvent.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FCancelEvent.h new file mode 100644 index 00000000..38277f77 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FCancelEvent.h @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FEvent.h" + +@protocol FEventRegistration; + + +@interface FCancelEvent : NSObject + +- initWithEventRegistration:(id)eventRegistration error:(NSError *)error path:(FPath *)path; + +@property (nonatomic, strong, readonly) NSError *error; +@property (nonatomic, strong, readonly) FPath *path; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FCancelEvent.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FCancelEvent.m new file mode 100644 index 00000000..fb73f17a --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FCancelEvent.m @@ -0,0 +1,55 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FCancelEvent.h" +#import "FPath.h" +#import "FEventRegistration.h" + +@interface FCancelEvent () +@property (nonatomic, strong) id eventRegistration; +@property (nonatomic, strong, readwrite) NSError *error; +@property (nonatomic, strong, readwrite) FPath *path; +@end + +@implementation FCancelEvent + +@synthesize eventRegistration; +@synthesize error; +@synthesize path; + +- (id)initWithEventRegistration:(id )registration error:(NSError *)anError path:(FPath *)aPath { + self = [super init]; + if (self) { + self.eventRegistration = registration; + self.error = anError; + self.path = aPath; + } + return self; +} + +- (void) fireEventOnQueue:(dispatch_queue_t)queue { + [self.eventRegistration fireEvent:self queue:queue]; +} + +- (BOOL) isCancelEvent { + return YES; +} + +- (NSString *) description { + return [NSString stringWithFormat:@"%@: cancel", self.path]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FChange.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FChange.h new file mode 100644 index 00000000..d728fe0c --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FChange.h @@ -0,0 +1,38 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FIRDatabaseReference.h" +#import "FNode.h" +#import "FIndexedNode.h" + +@interface FChange : NSObject + +@property (nonatomic, readonly) FIRDataEventType type; +@property (nonatomic, strong, readonly) FIndexedNode *indexedNode; +@property (nonatomic, strong, readonly) NSString *childKey; +@property (nonatomic, strong, readonly) NSString *prevKey; +@property (nonatomic, strong, readonly) FIndexedNode *oldIndexedNode; + +- (id)initWithType:(FIRDataEventType)type indexedNode:(FIndexedNode *)indexedNode; +- (id)initWithType:(FIRDataEventType)type indexedNode:(FIndexedNode *)indexedNode childKey:(NSString *)childKey; +- (id)initWithType:(FIRDataEventType)type + indexedNode:(FIndexedNode *)indexedNode + childKey:(NSString *)childKey + oldIndexedNode:(FIndexedNode *)oldIndexedNode; + +- (FChange *) changeWithPrevKey:(NSString *)prevKey; +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FChange.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FChange.m new file mode 100644 index 00000000..893fce49 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FChange.m @@ -0,0 +1,65 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FChange.h" + +@interface FChange () + +@property (nonatomic, strong, readwrite) NSString *prevKey; + +@end + +@implementation FChange + +- (id)initWithType:(FIRDataEventType)type indexedNode:(FIndexedNode *)indexedNode +{ + return [self initWithType:type indexedNode:indexedNode childKey:nil oldIndexedNode:nil]; +} + +- (id)initWithType:(FIRDataEventType)type indexedNode:(FIndexedNode *)indexedNode childKey:(NSString *)childKey +{ + return [self initWithType:type indexedNode:indexedNode childKey:childKey oldIndexedNode:nil]; +} + +- (id)initWithType:(FIRDataEventType)type + indexedNode:(FIndexedNode *)indexedNode + childKey:(NSString *)childKey + oldIndexedNode:(FIndexedNode *)oldIndexedNode +{ + self = [super init]; + if (self != nil) { + self->_type = type; + self->_indexedNode = indexedNode; + self->_childKey = childKey; + self->_oldIndexedNode = oldIndexedNode; + } + return self; +} + +- (FChange *) changeWithPrevKey:(NSString *)prevKey { + FChange *newChange = [[FChange alloc] initWithType:self.type + indexedNode:self.indexedNode + childKey:self.childKey + oldIndexedNode:self.oldIndexedNode]; + newChange.prevKey = prevKey; + return newChange; +} + +- (NSString *) description { + return [NSString stringWithFormat:@"event: %d, data: %@", (int)self.type, [self.indexedNode.node val]]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FChildEventRegistration.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FChildEventRegistration.h new file mode 100644 index 00000000..8da0b8fb --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FChildEventRegistration.h @@ -0,0 +1,37 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FEventRegistration.h" +#import "FTypedefs.h" + +@class FRepo; + +@interface FChildEventRegistration : NSObject + +- (id) initWithRepo:(FRepo *)repo + handle:(FIRDatabaseHandle)fHandle + callbacks:(NSDictionary *)callbackBlocks + cancelCallback:(fbt_void_nserror)cancelCallbackBlock; + +/** +* Maps FIRDataEventType (as NSNumber) to fbt_void_datasnapshot_nsstring +*/ +@property (nonatomic, copy, readonly) NSDictionary *callbacks; +@property (nonatomic, copy, readonly) fbt_void_nserror cancelCallback; +@property (nonatomic, readonly) FIRDatabaseHandle handle; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FChildEventRegistration.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FChildEventRegistration.m new file mode 100644 index 00000000..a98ea477 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FChildEventRegistration.m @@ -0,0 +1,93 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FChildEventRegistration.h" +#import "FIRDatabaseQuery_Private.h" +#import "FQueryParams.h" +#import "FQuerySpec.h" +#import "FIRDataSnapshot_Private.h" +#import "FDataEvent.h" +#import "FCancelEvent.h" + +@interface FChildEventRegistration () +@property (nonatomic, strong) FRepo *repo; +@property (nonatomic, copy, readwrite) NSDictionary *callbacks; +@property (nonatomic, copy, readwrite) fbt_void_nserror cancelCallback; +@property (nonatomic, readwrite) FIRDatabaseHandle handle; +@end + +@implementation FChildEventRegistration + +- (id)initWithRepo:(id)repo handle:(FIRDatabaseHandle)fHandle callbacks:(NSDictionary *)callbackBlocks cancelCallback:(fbt_void_nserror)cancelCallbackBlock { + self = [super init]; + if (self) { + self.repo = repo; + self.handle = fHandle; + self.callbacks = callbackBlocks; + self.cancelCallback = cancelCallbackBlock; + } + return self; +} + +- (BOOL) responseTo:(FIRDataEventType)eventType { + return self.callbacks != nil && [self.callbacks objectForKey:[NSNumber numberWithInteger:eventType]] != nil; +} + +- (FDataEvent *) createEventFrom:(FChange *)change query:(FQuerySpec *)query { + FIRDatabaseReference *ref = [[FIRDatabaseReference alloc] initWithRepo:self.repo path:[query.path childFromString:change.childKey]]; + FIRDataSnapshot *snapshot = [[FIRDataSnapshot alloc] initWithRef:ref indexedNode:change.indexedNode]; + + FDataEvent *eventData = [[FDataEvent alloc] initWithEventType:change.type eventRegistration:self + dataSnapshot:snapshot prevName:change.prevKey]; + return eventData; +} + +- (void) fireEvent:(id )event queue:(dispatch_queue_t)queue { + if ([event isCancelEvent]) { + FCancelEvent *cancelEvent = event; + FFLog(@"I-RDB061001", @"Raising cancel value event on %@", event.path); + NSAssert(self.cancelCallback != nil, @"Raising a cancel event on a listener with no cancel callback"); + dispatch_async(queue, ^{ + self.cancelCallback(cancelEvent.error); + }); + } else if (self.callbacks != nil) { + FDataEvent *dataEvent = event; + FFLog(@"I-RDB061002", @"Raising event callback (%ld) on %@", (long)dataEvent.eventType, dataEvent.path); + fbt_void_datasnapshot_nsstring callback = [self.callbacks objectForKey:[NSNumber numberWithInteger:dataEvent.eventType]]; + + if (callback != nil) { + dispatch_async(queue, ^{ + callback(dataEvent.snapshot, dataEvent.prevName); + }); + } + } +} + +- (FCancelEvent *) createCancelEventFromError:(NSError *)error path:(FPath *)path { + if (self.cancelCallback != nil) { + return [[FCancelEvent alloc] initWithEventRegistration:self error:error path:path]; + } else { + return nil; + } +} + +- (BOOL) matches:(id)other { + return self.handle == NSNotFound || other.handle == NSNotFound || self.handle == other.handle; +} + + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FDataEvent.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FDataEvent.h new file mode 100644 index 00000000..da90b035 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FDataEvent.h @@ -0,0 +1,39 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FIRDataSnapshot.h" +#import "FIRDatabaseReference.h" +#import "FTupleUserCallback.h" +#import "FEvent.h" + +@protocol FEventRegistration; +@protocol FIndex; + +@interface FDataEvent : NSObject + +- initWithEventType:(FIRDataEventType)type eventRegistration:(id)eventRegistration + dataSnapshot:(FIRDataSnapshot *)dataSnapshot; +- initWithEventType:(FIRDataEventType)type eventRegistration:(id)eventRegistration + dataSnapshot:(FIRDataSnapshot *)snapshot prevName:(NSString *)prevName; + + +@property (nonatomic, strong, readonly) id eventRegistration; +@property (nonatomic, strong, readonly) FIRDataSnapshot * snapshot; +@property (nonatomic, strong, readonly) NSString* prevName; +@property (nonatomic, readonly) FIRDataEventType eventType; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FDataEvent.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FDataEvent.m new file mode 100644 index 00000000..6c97faf0 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FDataEvent.m @@ -0,0 +1,74 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FDataEvent.h" +#import "FEventRegistration.h" +#import "FIndex.h" +#import "FIRDatabaseQuery_Private.h" + +@interface FDataEvent () +@property (nonatomic, strong, readwrite) id eventRegistration; +@property (nonatomic, strong, readwrite) FIRDataSnapshot *snapshot; +@property (nonatomic, strong, readwrite) NSString *prevName; +@property (nonatomic, readwrite) FIRDataEventType eventType; +@end + +@implementation FDataEvent + +@synthesize eventRegistration; +@synthesize snapshot; +@synthesize prevName; +@synthesize eventType; + +- (id)initWithEventType:(FIRDataEventType)type eventRegistration:(id )registration dataSnapshot:(FIRDataSnapshot *)dataSnapshot { + return [self initWithEventType:type eventRegistration:registration dataSnapshot:dataSnapshot prevName:nil]; +} + +- (id)initWithEventType:(FIRDataEventType)type eventRegistration:(id )registration dataSnapshot:(FIRDataSnapshot *)dataSnapshot prevName:(NSString *)previousName { + self = [super init]; + if (self) { + self.eventRegistration = registration; + self.snapshot = dataSnapshot; + self.prevName = previousName; + self.eventType = type; + } + return self; +} + +- (FPath *) path { + // Used for logging, so delay calculation + FIRDatabaseReference *ref = self.snapshot.ref; + if (self.eventType == FIRDataEventTypeValue) { + return ref.path; + } else { + return ref.parent.path; + } +} + +- (void) fireEventOnQueue:(dispatch_queue_t)queue { + [self.eventRegistration fireEvent:self queue:queue]; +} + +- (BOOL) isCancelEvent { + return NO; +} + + +- (NSString *) description { + return [NSString stringWithFormat:@"event %d, data: %@", (int) eventType, [snapshot value]]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FEvent.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FEvent.h new file mode 100644 index 00000000..6b9e31a9 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FEvent.h @@ -0,0 +1,27 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FIRDataEventType.h" + +@class FPath; + +@protocol FEvent +- (FPath *) path; +- (void) fireEventOnQueue:(dispatch_queue_t)queue; +- (BOOL) isCancelEvent; +- (NSString *) description; +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FEventRaiser.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FEventRaiser.h new file mode 100644 index 00000000..01a0130c --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FEventRaiser.h @@ -0,0 +1,35 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FTypedefs.h" + +@class FPath; +@class FRepo; +@class FIRDatabaseConfig; + +/** +* Left as instance methods rather than class methods so that we could potentially callback on different queues for different repos. +* This is semi-parallel to JS's FEventQueue +*/ +@interface FEventRaiser : NSObject + +- (id)initWithQueue:(dispatch_queue_t)queue; + +- (void) raiseEvents:(NSArray *)eventDataList; +- (void) raiseCallback:(fbt_void_void)callback; +- (void) raiseCallbacks:(NSArray *)callbackList; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FEventRaiser.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FEventRaiser.m new file mode 100644 index 00000000..94a0907c --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FEventRaiser.m @@ -0,0 +1,72 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FEventRaiser.h" +#import "FDataEvent.h" +#import "FTypedefs.h" +#import "FUtilities.h" +#import "FTupleUserCallback.h" +#import "FRepo.h" +#import "FRepoManager.h" + +@interface FEventRaiser () + +@property (nonatomic, strong) dispatch_queue_t queue; + +@end + +/** +* This class exists for symmetry with other clients, but since events are async, we don't need to do the complicated +* stuff the JS client does to preserve event order. +*/ +@implementation FEventRaiser + +- (id)init { + [NSException raise:NSInternalInconsistencyException format:@"Can't use default constructor"]; + return nil; +} + +- (id)initWithQueue:(dispatch_queue_t)queue { + self = [super init]; + if (self != nil) { + self->_queue = queue; + } + return self; +} + +- (void) raiseEvents:(NSArray *)eventDataList { + for (id event in eventDataList) { + [event fireEventOnQueue:self.queue]; + } +} + +- (void) raiseCallback:(fbt_void_void)callback { + dispatch_async(self.queue, callback); +} + +- (void) raiseCallbacks:(NSArray *)callbackList { + for (fbt_void_void callback in callbackList) { + dispatch_async(self.queue, callback); + } +} + ++ (void) raiseCallbacks:(NSArray *)callbackList queue:(dispatch_queue_t)queue { + for (fbt_void_void callback in callbackList) { + dispatch_async(queue, callback); + } +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FEventRegistration.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FEventRegistration.h new file mode 100644 index 00000000..5b845acc --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FEventRegistration.h @@ -0,0 +1,36 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FChange.h" +#import "FIRDataEventType.h" + +@protocol FEvent; +@class FDataEvent; +@class FCancelEvent; +@class FQuerySpec; + +@protocol FEventRegistration +- (BOOL) responseTo:(FIRDataEventType)eventType; +- (FDataEvent *) createEventFrom:(FChange *)change query:(FQuerySpec *)query; +- (void) fireEvent:(id)event queue:(dispatch_queue_t)queue; +- (FCancelEvent *) createCancelEventFromError:(NSError *)error path:(FPath *)path; +/** +* Used to figure out what event registration match the event registration that needs to be removed. +*/ +- (BOOL) matches:(id)other; +@property (nonatomic, readonly) FIRDatabaseHandle handle; +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FKeepSyncedEventRegistration.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FKeepSyncedEventRegistration.h new file mode 100644 index 00000000..669e0126 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FKeepSyncedEventRegistration.h @@ -0,0 +1,28 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import "FEventRegistration.h" + +/** + * A singleton event registration to mark a query as keep synced + */ +@interface FKeepSyncedEventRegistration : NSObject + ++ (FKeepSyncedEventRegistration *)instance; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FKeepSyncedEventRegistration.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FKeepSyncedEventRegistration.m new file mode 100644 index 00000000..806d54fc --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FKeepSyncedEventRegistration.m @@ -0,0 +1,64 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FKeepSyncedEventRegistration.h" + +@interface FKeepSyncedEventRegistration () + +@end + +@implementation FKeepSyncedEventRegistration + ++ (FKeepSyncedEventRegistration *)instance { + static dispatch_once_t onceToken; + static FKeepSyncedEventRegistration *keepSynced; + dispatch_once(&onceToken, ^{ + keepSynced = [[FKeepSyncedEventRegistration alloc] init]; + }); + return keepSynced; +} + +- (BOOL) responseTo:(FIRDataEventType)eventType { + return NO; +} + +- (FDataEvent *) createEventFrom:(FChange *)change query:(FQuerySpec *)query { + [NSException raise:NSInternalInconsistencyException format:@"Should never create event for FKeepSyncedEventRegistration"]; + return nil; +} + +- (void) fireEvent:(id)event queue:(dispatch_queue_t)queue { + [NSException raise:NSInternalInconsistencyException format:@"Should never raise event for FKeepSyncedEventRegistration"]; +} + +- (FCancelEvent *) createCancelEventFromError:(NSError *)error path:(FPath *)path { + // Don't create cancel events.... + return nil; +} + +- (FIRDatabaseHandle) handle { + // TODO[offline]: returning arbitray, can't return NSNotFound since that is used to match other event registrations + // We should really redo this to match on different kind of events (single observer, all observers, cancelled) + // rather than on a NSNotFound handle... + return NSNotFound - 1; +} + +- (BOOL) matches:(id)other { + // Only matches singleton instance + return self == other; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FValueEventRegistration.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FValueEventRegistration.h new file mode 100644 index 00000000..1220c604 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FValueEventRegistration.h @@ -0,0 +1,34 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FEventRegistration.h" +#import "FTypedefs.h" + +@class FRepo; + +@interface FValueEventRegistration : NSObject + +- (id) initWithRepo:(FRepo *)repo + handle:(FIRDatabaseHandle)fHandle + callback:(fbt_void_datasnapshot)callbackBlock + cancelCallback:(fbt_void_nserror)cancelCallbackBlock; + +@property (nonatomic, copy, readonly) fbt_void_datasnapshot callback; +@property (nonatomic, copy, readonly) fbt_void_nserror cancelCallback; +@property (nonatomic, readonly) FIRDatabaseHandle handle; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FValueEventRegistration.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FValueEventRegistration.m new file mode 100644 index 00000000..6a986292 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FValueEventRegistration.m @@ -0,0 +1,90 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FValueEventRegistration.h" +#import "FIRDatabaseQuery_Private.h" +#import "FQueryParams.h" +#import "FQuerySpec.h" +#import "FIRDataSnapshot_Private.h" +#import "FCancelEvent.h" +#import "FDataEvent.h" + +@interface FValueEventRegistration () +@property (nonatomic, strong) FRepo* repo; +@property (nonatomic, copy, readwrite) fbt_void_datasnapshot callback; +@property (nonatomic, copy, readwrite) fbt_void_nserror cancelCallback; +@property (nonatomic, readwrite) FIRDatabaseHandle handle; +@end + +@implementation FValueEventRegistration + +- (id) initWithRepo:(FRepo *)repo + handle:(FIRDatabaseHandle)fHandle + callback:(fbt_void_datasnapshot)callbackBlock + cancelCallback:(fbt_void_nserror)cancelCallbackBlock { + self = [super init]; + if (self) { + self.repo = repo; + self.handle = fHandle; + self.callback = callbackBlock; + self.cancelCallback = cancelCallbackBlock; + } + return self; +} + +- (BOOL) responseTo:(FIRDataEventType)eventType { + return eventType == FIRDataEventTypeValue; +} + +- (FDataEvent *) createEventFrom:(FChange *)change query:(FQuerySpec *)query { + FIRDatabaseReference *ref = [[FIRDatabaseReference alloc] initWithRepo:self.repo path:query.path]; + FIRDataSnapshot *snapshot = [[FIRDataSnapshot alloc] initWithRef:ref indexedNode:change.indexedNode]; + FDataEvent *eventData = [[FDataEvent alloc] initWithEventType:FIRDataEventTypeValue eventRegistration:self + dataSnapshot:snapshot]; + return eventData; +} + +- (void) fireEvent:(id )event queue:(dispatch_queue_t)queue { + if ([event isCancelEvent]) { + FCancelEvent *cancelEvent = event; + FFLog(@"I-RDB065001", @"Raising cancel value event on %@", event.path); + NSAssert(self.cancelCallback != nil, @"Raising a cancel event on a listener with no cancel callback"); + dispatch_async(queue, ^{ + self.cancelCallback(cancelEvent.error); + }); + } else if (self.callback != nil) { + FDataEvent *dataEvent = event; + FFLog(@"I-RDB065002", @"Raising value event on %@", dataEvent.snapshot.key); + dispatch_async(queue, ^{ + self.callback(dataEvent.snapshot); + }); + } +} + +- (FCancelEvent *) createCancelEventFromError:(NSError *)error path:(FPath *)path { + if (self.cancelCallback != nil) { + return [[FCancelEvent alloc] initWithEventRegistration:self error:error path:path]; + } else { + return nil; + } +} + +- (BOOL) matches:(id)other { + return self.handle == NSNotFound || other.handle == NSNotFound || self.handle == other.handle; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FView.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FView.h new file mode 100644 index 00000000..2d0761a6 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FView.h @@ -0,0 +1,53 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@protocol FNode; +@protocol FOperation; +@protocol FEventRegistration; +@class FWriteTreeRef; +@class FQuerySpec; +@class FChange; +@class FPath; +@class FViewCache; + +@interface FViewOperationResult : NSObject + +@property (nonatomic, strong, readonly) NSArray* changes; +@property (nonatomic, strong, readonly) NSArray* events; + +@end + + +@interface FView : NSObject + +@property (nonatomic, strong, readonly) FQuerySpec *query; + +- (id) initWithQuery:(FQuerySpec *)query initialViewCache:(FViewCache *)initialViewCache; + +- (id) eventCache; +- (id) serverCache; +- (id) completeServerCacheFor:(FPath*)path; +- (BOOL) isEmpty; + +- (void) addEventRegistration:(id)eventRegistration; +- (NSArray *) removeEventRegistration:(id)eventRegistration cancelError:(NSError *)cancelError; + +- (FViewOperationResult *) applyOperation:(id )operation writesCache:(FWriteTreeRef *)writesCache serverCache:(id )optCompleteServerCache; +- (NSArray *) initialEvents:(id)registration; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FView.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FView.m new file mode 100644 index 00000000..1aea4d7e --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FView.m @@ -0,0 +1,223 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FView.h" +#import "FNode.h" +#import "FWriteTreeRef.h" +#import "FOperation.h" +#import "FIRDatabaseQuery.h" +#import "FIRDatabaseQuery_Private.h" +#import "FEventRegistration.h" +#import "FQueryParams.h" +#import "FQuerySpec.h" +#import "FViewCache.h" +#import "FPath.h" +#import "FEventGenerator.h" +#import "FOperationSource.h" +#import "FCancelEvent.h" +#import "FIndexedFilter.h" +#import "FCacheNode.h" +#import "FEmptyNode.h" +#import "FViewProcessor.h" +#import "FViewProcessorResult.h" +#import "FIndexedNode.h" + +@interface FViewOperationResult () + +@property (nonatomic, strong, readwrite) NSArray *changes; +@property (nonatomic, strong, readwrite) NSArray *events; + +@end + +@implementation FViewOperationResult + +- (id)initWithChanges:(NSArray *)changes events:(NSArray *)events { + self = [super init]; + if (self != nil) { + self->_changes = changes; + self->_events = events; + } + return self; +} + +@end + +/** +* A view represents a specific location and query that has 1 or more event registrations. +* +* It does several things: +* - Maintains the list of event registration for this location/query. +* - Maintains a cache of the data visible for this location/query. +* - Applies new operations (via applyOperation), updates the cache, and based on the event +* registrations returns the set of events to be raised. +*/ +@interface FView () + +@property (nonatomic, strong, readwrite) FQuerySpec *query; +@property (nonatomic, strong) FViewProcessor *processor; +@property (nonatomic, strong) FViewCache *viewCache; +@property (nonatomic, strong) NSMutableArray *eventRegistrations; +@property (nonatomic, strong) FEventGenerator *eventGenerator; + +@end + +@implementation FView +- (id) initWithQuery:(FQuerySpec *)query initialViewCache:(FViewCache *)initialViewCache { + self = [super init]; + if (self) { + self.query = query; + + FIndexedFilter *indexFilter = [[FIndexedFilter alloc] initWithIndex:query.index]; + id filter = query.params.nodeFilter; + self.processor = [[FViewProcessor alloc] initWithFilter:filter]; + FCacheNode *initialServerCache = initialViewCache.cachedServerSnap; + FCacheNode *initialEventCache = initialViewCache.cachedEventSnap; + + // Don't filter server node with other filter than index, wait for tagged listen + FIndexedNode *emptyIndexedNode = [FIndexedNode indexedNodeWithNode:[FEmptyNode emptyNode] index:query.index]; + FIndexedNode *serverSnap = [indexFilter updateFullNode:emptyIndexedNode + withNewNode:initialServerCache.indexedNode + accumulator:nil]; + FIndexedNode *eventSnap = [filter updateFullNode:emptyIndexedNode + withNewNode:initialEventCache.indexedNode + accumulator:nil]; + FCacheNode *newServerCache = [[FCacheNode alloc] initWithIndexedNode:serverSnap + isFullyInitialized:initialServerCache.isFullyInitialized + isFiltered:indexFilter.filtersNodes]; + FCacheNode *newEventCache = [[FCacheNode alloc] initWithIndexedNode:eventSnap + isFullyInitialized:initialEventCache.isFullyInitialized + isFiltered:filter.filtersNodes]; + + self.viewCache = [[FViewCache alloc] initWithEventCache:newEventCache serverCache:newServerCache]; + + self.eventRegistrations = [[NSMutableArray alloc] init]; + + self.eventGenerator = [[FEventGenerator alloc] initWithQuery:query]; + } + + return self; +} + +- (id ) serverCache { + return self.viewCache.cachedServerSnap.node; +} + +- (id ) eventCache { + return self.viewCache.cachedEventSnap.node; +} + +- (id ) completeServerCacheFor:(FPath*)path { + id cache = self.viewCache.completeServerSnap; + if (cache) { + // If this isn't a "loadsAllData" view, then cache isn't actually a complete cache and + // we need to see if it contains the child we're interested in. + if ([self.query loadsAllData] || + (!path.isEmpty && ![cache getImmediateChild:path.getFront].isEmpty)) { + return [cache getChild:path]; + } + } + return nil; +} + +- (BOOL) isEmpty { + return self.eventRegistrations.count == 0; +} + +- (void) addEventRegistration:(id )eventRegistration { + [self.eventRegistrations addObject:eventRegistration]; +} + +/** +* @param eventRegistration If null, remove all callbacks. +* @param cancelError If a cancelError is provided, appropriate cancel events will be returned. +* @return Cancel events, if cancelError was provided. +*/ +- (NSArray *) removeEventRegistration:(id )eventRegistration cancelError:(NSError *)cancelError { + NSMutableArray *cancelEvents = [[NSMutableArray alloc] init]; + if (cancelError != nil) { + NSAssert(eventRegistration == nil, @"A cancel should cancel all event registrations."); + FPath *path = self.query.path; + for (id registration in self.eventRegistrations) { + FCancelEvent *maybeEvent = [registration createCancelEventFromError:cancelError path:path]; + if (maybeEvent) { + [cancelEvents addObject:maybeEvent]; + } + } + } + + if (eventRegistration) { + NSUInteger i = 0; + while (i < self.eventRegistrations.count) { + id existing = self.eventRegistrations[i]; + if ([existing matches:eventRegistration]) { + [self.eventRegistrations removeObjectAtIndex:i]; + } else { + i++; + } + } + } else { + [self.eventRegistrations removeAllObjects]; + } + return cancelEvents; +} + +/** + * Applies the given Operation, updates our cache, and returns the appropriate events and changes + */ +- (FViewOperationResult *) applyOperation:(id )operation writesCache:(FWriteTreeRef *)writesCache serverCache:(id )optCompleteServerCache { + if (operation.type == FOperationTypeMerge && operation.source.queryParams != nil) { + NSAssert(self.viewCache.completeServerSnap != nil, @"We should always have a full cache before handling merges"); + NSAssert(self.viewCache.completeEventSnap != nil, @"Missing event cache, even though we have a server cache"); + } + FViewCache *oldViewCache = self.viewCache; + FViewProcessorResult *result = [self.processor applyOperationOn:oldViewCache operation:operation writesCache:writesCache completeCache:optCompleteServerCache]; + + NSAssert(result.viewCache.cachedServerSnap.isFullyInitialized || !oldViewCache.cachedServerSnap.isFullyInitialized, @"Once a server snap is complete, it should never go back."); + + self.viewCache = result.viewCache; + NSArray *events = [self generateEventsForChanges:result.changes eventCache:result.viewCache.cachedEventSnap.indexedNode registration:nil]; + return [[FViewOperationResult alloc] initWithChanges:result.changes events:events]; +} + +- (NSArray *) initialEvents:(id)registration { + FCacheNode *eventSnap = self.viewCache.cachedEventSnap; + NSMutableArray *initialChanges = [[NSMutableArray alloc] init]; + [eventSnap.indexedNode.node enumerateChildrenUsingBlock:^(NSString *key, id node, BOOL *stop) { + FIndexedNode *indexed = [FIndexedNode indexedNodeWithNode:node]; + FChange *change = [[FChange alloc] initWithType:FIRDataEventTypeChildAdded indexedNode:indexed childKey:key]; + [initialChanges addObject:change]; + }]; + if (eventSnap.isFullyInitialized) { + FChange *change = [[FChange alloc] initWithType:FIRDataEventTypeValue indexedNode:eventSnap.indexedNode]; + [initialChanges addObject:change]; + } + return [self generateEventsForChanges:initialChanges eventCache:eventSnap.indexedNode registration:registration]; +} + +- (NSArray *) generateEventsForChanges:(NSArray *)changes eventCache:(FIndexedNode *)eventCache registration:(id)registration { + NSArray *registrations; + if (registration == nil) { + registrations = [[NSArray alloc] initWithArray:self.eventRegistrations]; + } else { + registrations = [[NSArray alloc] initWithObjects:registration, nil]; + } + return [self.eventGenerator generateEventsForChanges:changes eventCache:eventCache eventRegistrations:registrations]; +} + +- (NSString *) description { + return [NSString stringWithFormat:@"FView (%@)", self.query]; +} +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FViewCache.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FViewCache.h new file mode 100644 index 00000000..4d018774 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FViewCache.h @@ -0,0 +1,35 @@ +#/* +* Copyright 2017 Google +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#import + +@protocol FNode; +@class FCacheNode; +@class FIndexedNode; + +@interface FViewCache : NSObject + +- (id) initWithEventCache:(FCacheNode *)eventCache serverCache:(FCacheNode *)serverCache; + +- (FViewCache *) updateEventSnap:(FIndexedNode *)eventSnap isComplete:(BOOL)complete isFiltered:(BOOL)filtered; +- (FViewCache *) updateServerSnap:(FIndexedNode *)serverSnap isComplete:(BOOL)complete isFiltered:(BOOL)filtered; + +@property (nonatomic, strong, readonly) FCacheNode *cachedEventSnap; +@property (nonatomic, strong, readonly) id completeEventSnap; +@property (nonatomic, strong, readonly) FCacheNode *cachedServerSnap; +@property (nonatomic, strong, readonly) id completeServerSnap; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FViewCache.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FViewCache.m new file mode 100644 index 00000000..c6ec8b16 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/FViewCache.m @@ -0,0 +1,61 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FViewCache.h" +#import "FCacheNode.h" +#import "FNode.h" +#import "FEmptyNode.h" + +@interface FViewCache () +@property (nonatomic, strong, readwrite) FCacheNode *cachedEventSnap; +@property (nonatomic, strong, readwrite) FCacheNode *cachedServerSnap; +@end + +@implementation FViewCache + +- (id) initWithEventCache:(FCacheNode *)eventCache serverCache:(FCacheNode *)serverCache { + self = [super init]; + if (self) { + self.cachedEventSnap = eventCache; + self.cachedServerSnap = serverCache; + } + return self; +} + +- (FViewCache *) updateEventSnap:(FIndexedNode *)eventSnap isComplete:(BOOL)complete isFiltered:(BOOL)filtered { + FCacheNode *updatedEventCache = [[FCacheNode alloc] initWithIndexedNode:eventSnap + isFullyInitialized:complete + isFiltered:filtered]; + return [[FViewCache alloc] initWithEventCache:updatedEventCache serverCache:self.cachedServerSnap]; +} + +- (FViewCache *) updateServerSnap:(FIndexedNode *)serverSnap isComplete:(BOOL)complete isFiltered:(BOOL)filtered { + FCacheNode *updatedServerCache = [[FCacheNode alloc] initWithIndexedNode:serverSnap + isFullyInitialized:complete + isFiltered:filtered]; + return [[FViewCache alloc] initWithEventCache:self.cachedEventSnap serverCache:updatedServerCache]; +} + +- (id) completeEventSnap { + return (self.cachedEventSnap.isFullyInitialized) ? self.cachedEventSnap.node : nil; +} + +- (id) completeServerSnap { + return (self.cachedServerSnap.isFullyInitialized) ? self.cachedServerSnap.node : nil; +} + + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FChildChangeAccumulator.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FChildChangeAccumulator.h new file mode 100644 index 00000000..59b0a85f --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FChildChangeAccumulator.h @@ -0,0 +1,28 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class FChange; + + +@interface FChildChangeAccumulator : NSObject + +- (id) init; +- (void) trackChildChange:(FChange *)change; +- (NSArray *) changes; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FChildChangeAccumulator.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FChildChangeAccumulator.m new file mode 100644 index 00000000..e43fd7c9 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FChildChangeAccumulator.m @@ -0,0 +1,80 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FChildChangeAccumulator.h" +#import "FChange.h" +#import "FIndex.h" + +@interface FChildChangeAccumulator () +@property (nonatomic, strong) NSMutableDictionary *changeMap; +@end + +@implementation FChildChangeAccumulator + +- (id) init { + self = [super init]; + if (self) { + self.changeMap = [[NSMutableDictionary alloc] init]; + } + return self; +} + +- (void) trackChildChange:(FChange *)change { + FIRDataEventType type = change.type; + NSString *childKey = change.childKey; + NSAssert(type == FIRDataEventTypeChildAdded || type == FIRDataEventTypeChildChanged || type == FIRDataEventTypeChildRemoved, @"Only child changes supported for tracking."); + NSAssert(![change.childKey isEqualToString:@".priority"], @"Changes not tracked on priority"); + if (self.changeMap[childKey] != nil) { + FChange *oldChange = [self.changeMap objectForKey:childKey]; + FIRDataEventType oldType = oldChange.type; + if (type == FIRDataEventTypeChildAdded && oldType == FIRDataEventTypeChildRemoved) { + FChange *newChange = [[FChange alloc] initWithType:FIRDataEventTypeChildChanged + indexedNode:change.indexedNode + childKey:childKey + oldIndexedNode:oldChange.indexedNode]; + [self.changeMap setObject:newChange forKey:childKey]; + } else if (type == FIRDataEventTypeChildRemoved && oldType == FIRDataEventTypeChildAdded) { + [self.changeMap removeObjectForKey:childKey]; + } else if (type == FIRDataEventTypeChildRemoved && oldType == FIRDataEventTypeChildChanged) { + FChange *newChange = [[FChange alloc] initWithType:FIRDataEventTypeChildRemoved + indexedNode:oldChange.oldIndexedNode + childKey:childKey]; + [self.changeMap setObject:newChange forKey:childKey]; + } else if (type == FIRDataEventTypeChildChanged && oldType == FIRDataEventTypeChildAdded) { + FChange *newChange = [[FChange alloc] initWithType:FIRDataEventTypeChildAdded + indexedNode:change.indexedNode + childKey:childKey]; + [self.changeMap setObject:newChange forKey:childKey]; + } else if (type == FIRDataEventTypeChildChanged && oldType == FIRDataEventTypeChildChanged) { + FChange *newChange = [[FChange alloc] initWithType:FIRDataEventTypeChildChanged + indexedNode:change.indexedNode + childKey:childKey + oldIndexedNode:oldChange.oldIndexedNode]; + [self.changeMap setObject:newChange forKey:childKey]; + } else { + NSString *reason = [NSString stringWithFormat:@"Illegal combination of changes: %@ occurred after %@", change, oldChange]; + @throw [[NSException alloc] initWithName:@"FirebaseDatabaseInternalError" reason:reason userInfo:nil]; + } + } else { + [self.changeMap setObject:change forKey:childKey]; + } +} + +- (NSArray *) changes { + return [self.changeMap allValues]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FCompleteChildSource.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FCompleteChildSource.h new file mode 100644 index 00000000..4e99045e --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FCompleteChildSource.h @@ -0,0 +1,28 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@protocol FNode; +@class FNamedNode; +@protocol FIndex; + +@protocol FCompleteChildSource + +- (id) completeChild:(NSString *)childKey; +- (FNamedNode *) childByIndex:(id)index afterChild:(FNamedNode *)child isReverse:(BOOL)reverse; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FIndexedFilter.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FIndexedFilter.h new file mode 100644 index 00000000..5081a77d --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FIndexedFilter.h @@ -0,0 +1,27 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FNodeFilter.h" + +@protocol FIndex; + + +@interface FIndexedFilter : NSObject + +- (id) initWithIndex:(id)theIndex; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FIndexedFilter.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FIndexedFilter.m new file mode 100644 index 00000000..44c411cf --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FIndexedFilter.m @@ -0,0 +1,147 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FNode.h" +#import "FIndexedFilter.h" +#import "FChildChangeAccumulator.h" +#import "FIndex.h" +#import "FChange.h" +#import "FChildrenNode.h" +#import "FKeyIndex.h" +#import "FEmptyNode.h" +#import "FIndexedNode.h" + +@interface FIndexedFilter () +@property (nonatomic, strong, readwrite) id index; +@end + +@implementation FIndexedFilter +- (id) initWithIndex:(id)theIndex { + self = [super init]; + if (self) { + self.index = theIndex; + } + return self; +} + +- (FIndexedNode *)updateChildIn:(FIndexedNode *)indexedNode + forChildKey:(NSString *)childKey + newChild:(id)newChildSnap + affectedPath:(FPath *)affectedPath + fromSource:(id)source + accumulator:(FChildChangeAccumulator *)optChangeAccumulator +{ + NSAssert([indexedNode hasIndex:self.index], @"The index in FIndexedNode must match the index of the filter"); + id node = indexedNode.node; + id oldChildSnap = [node getImmediateChild:childKey]; + + // Check if anything actually changed. + if ([[oldChildSnap getChild:affectedPath] isEqual:[newChildSnap getChild:affectedPath]]) { + // There's an edge case where a child can enter or leave the view because affectedPath was set to null. + // In this case, affectedPath will appear null in both the old and new snapshots. So we need + // to avoid treating these cases as "nothing changed." + if (oldChildSnap.isEmpty == newChildSnap.isEmpty) { + // Nothing changed. + #ifdef DEBUG + NSAssert([oldChildSnap isEqual:newChildSnap], @"Old and new snapshots should be equal."); + #endif + + return indexedNode; + } + } + if (optChangeAccumulator) { + if (newChildSnap.isEmpty) { + if ([node hasChild:childKey]) { + FChange *change = [[FChange alloc] initWithType:FIRDataEventTypeChildRemoved + indexedNode:[FIndexedNode indexedNodeWithNode:oldChildSnap] + childKey:childKey]; + [optChangeAccumulator trackChildChange:change]; + } else { + NSAssert(node.isLeafNode, @"A child remove without an old child only makes sense on a leaf node."); + } + } else if (oldChildSnap.isEmpty) { + FChange *change = [[FChange alloc] initWithType:FIRDataEventTypeChildAdded + indexedNode:[FIndexedNode indexedNodeWithNode:newChildSnap] + childKey:childKey]; + [optChangeAccumulator trackChildChange:change]; + } else { + FChange *change = [[FChange alloc] initWithType:FIRDataEventTypeChildChanged + indexedNode:[FIndexedNode indexedNodeWithNode:newChildSnap] + childKey:childKey + oldIndexedNode:[FIndexedNode indexedNodeWithNode:oldChildSnap]]; + [optChangeAccumulator trackChildChange:change]; + } + } + if (node.isLeafNode && newChildSnap.isEmpty) { + return indexedNode; + } else { + return [indexedNode updateChild:childKey withNewChild:newChildSnap]; + } +} + +- (FIndexedNode *)updateFullNode:(FIndexedNode *)oldSnap + withNewNode:(FIndexedNode *)newSnap + accumulator:(FChildChangeAccumulator *)optChangeAccumulator +{ + if (optChangeAccumulator) { + [oldSnap.node enumerateChildrenUsingBlock:^(NSString *childKey, id childNode, BOOL *stop) { + if (![newSnap.node hasChild:childKey]) { + FChange *change = [[FChange alloc] initWithType:FIRDataEventTypeChildRemoved + indexedNode:[FIndexedNode indexedNodeWithNode:childNode] + childKey:childKey]; + [optChangeAccumulator trackChildChange:change]; + } + }]; + + [newSnap.node enumerateChildrenUsingBlock:^(NSString *childKey, id childNode, BOOL *stop) { + if ([oldSnap.node hasChild:childKey]) { + id oldChildSnap = [oldSnap.node getImmediateChild:childKey]; + if (![oldChildSnap isEqual:childNode]) { + FChange *change = [[FChange alloc] initWithType:FIRDataEventTypeChildChanged + indexedNode:[FIndexedNode indexedNodeWithNode:childNode] + childKey:childKey + oldIndexedNode:[FIndexedNode indexedNodeWithNode:oldChildSnap]]; + [optChangeAccumulator trackChildChange:change]; + } + } else { + FChange *change = [[FChange alloc] initWithType:FIRDataEventTypeChildAdded + indexedNode:[FIndexedNode indexedNodeWithNode:childNode] + childKey:childKey]; + [optChangeAccumulator trackChildChange:change]; + } + }]; + } + return newSnap; +} + +- (FIndexedNode *)updatePriority:(id)priority forNode:(FIndexedNode *)oldSnap +{ + if ([oldSnap.node isEmpty]) { + return oldSnap; + } else { + return [oldSnap updatePriority:priority]; + } +} + +- (BOOL) filtersNodes { + return NO; +} + +- (id) indexedFilter { + return self; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FLimitedFilter.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FLimitedFilter.h new file mode 100644 index 00000000..16909806 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FLimitedFilter.h @@ -0,0 +1,26 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FNodeFilter.h" + +@class FQueryParams; + + +@interface FLimitedFilter : NSObject + +- (id) initWithQueryParams:(FQueryParams *)params; +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FLimitedFilter.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FLimitedFilter.m new file mode 100644 index 00000000..8bc6e87d --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FLimitedFilter.m @@ -0,0 +1,243 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FLimitedFilter.h" +#import "FChildChangeAccumulator.h" +#import "FIndex.h" +#import "FRangedFilter.h" +#import "FQueryParams.h" +#import "FQueryParams.h" +#import "FNamedNode.h" +#import "FEmptyNode.h" +#import "FChildrenNode.h" +#import "FCompleteChildSource.h" +#import "FChange.h" +#import "FTreeSortedDictionary.h" + +@interface FLimitedFilter () +@property (nonatomic, strong) FRangedFilter *rangedFilter; +@property (nonatomic, strong, readwrite) id index; +@property (nonatomic) NSInteger limit; +@property (nonatomic) BOOL reverse; + +@end + +@implementation FLimitedFilter +- (id) initWithQueryParams:(FQueryParams *)params { + self = [super init]; + if (self) { + self.rangedFilter = [[FRangedFilter alloc] initWithQueryParams:params]; + self.index = params.index; + self.limit = params.limit; + self.reverse = !params.isViewFromLeft; + } + return self; +} + + +- (FIndexedNode *)updateChildIn:(FIndexedNode *)oldSnap + forChildKey:(NSString *)childKey + newChild:(id)newChildSnap + affectedPath:(FPath *)affectedPath + fromSource:(id)source + accumulator:(FChildChangeAccumulator *)optChangeAccumulator +{ + if (![self.rangedFilter matchesKey:childKey andNode:newChildSnap]) { + newChildSnap = [FEmptyNode emptyNode]; + } + if ([[oldSnap.node getImmediateChild:childKey] isEqual:newChildSnap]) { + // No change + return oldSnap; + } else if (oldSnap.node.numChildren < self.limit) { + return [[self.rangedFilter indexedFilter] updateChildIn:oldSnap + forChildKey:childKey + newChild:newChildSnap + affectedPath:affectedPath + fromSource:source + accumulator:optChangeAccumulator]; + } else { + return [self fullLimitUpdateNode:oldSnap + forChildKey:childKey + newChild:newChildSnap + fromSource:source + accumulator:optChangeAccumulator]; + } +} + +- (FIndexedNode *)fullLimitUpdateNode:(FIndexedNode *)oldIndexed + forChildKey:(NSString *)childKey + newChild:(id)newChildSnap + fromSource:(id)source + accumulator:(FChildChangeAccumulator *)optChangeAccumulator +{ + NSAssert(oldIndexed.node.numChildren == self.limit, @"Should have number of children equal to limit."); + + FNamedNode *windowBoundary = self.reverse ? oldIndexed.firstChild : oldIndexed.lastChild; + + BOOL inRange = [self.rangedFilter matchesKey:childKey andNode:newChildSnap]; + if ([oldIndexed.node hasChild:childKey]) { + // `childKey` was already in `oldSnap`. Figure out if it remains in the window or needs to be replaced. + id oldChildSnap = [oldIndexed.node getImmediateChild:childKey]; + + // In case the `newChildSnap` falls outside the window, get the `nextChild` that might replace it. + FNamedNode *nextChild = [source childByIndex:self.index afterChild:windowBoundary isReverse:(BOOL)self.reverse]; + if (nextChild != nil && ([nextChild.name isEqualToString:childKey] || + [oldIndexed.node hasChild:nextChild.name])) { + // There is a weird edge case where a node is updated as part of a merge in the write tree, but hasn't + // been applied to the limited filter yet. Ignore this next child which will be updated later in + // the limited filter... + nextChild = [source childByIndex:self.index afterChild:nextChild isReverse:self.reverse]; + } + + + + // Figure out if `newChildSnap` is in range and ordered before `nextChild` + BOOL remainsInWindow = inRange && !newChildSnap.isEmpty; + remainsInWindow = remainsInWindow && (!nextChild || [self.index compareKey:nextChild.name + andNode:nextChild.node + toOtherKey:childKey + andNode:newChildSnap + reverse:self.reverse] >= NSOrderedSame); + if (remainsInWindow) { + // `newChildSnap` is ordered before `nextChild`, so it's a child changed event + if (optChangeAccumulator != nil) { + FChange *change = [[FChange alloc] initWithType:FIRDataEventTypeChildChanged + indexedNode:[FIndexedNode indexedNodeWithNode:newChildSnap] + childKey:childKey + oldIndexedNode:[FIndexedNode indexedNodeWithNode:oldChildSnap]]; + [optChangeAccumulator trackChildChange:change]; + } + return [oldIndexed updateChild:childKey withNewChild:newChildSnap]; + } else { + // `newChildSnap` is ordered after `nextChild`, so it's a child removed event + if (optChangeAccumulator != nil) { + FChange *change = [[FChange alloc] initWithType:FIRDataEventTypeChildRemoved + indexedNode:[FIndexedNode indexedNodeWithNode:oldChildSnap] + childKey:childKey]; + [optChangeAccumulator trackChildChange:change]; + } + FIndexedNode *newIndexed = [oldIndexed updateChild:childKey withNewChild:[FEmptyNode emptyNode]]; + + // We need to check if the `nextChild` is actually in range before adding it + BOOL nextChildInRange = (nextChild != nil) && [self.rangedFilter matchesKey:nextChild.name + andNode:nextChild.node]; + if (nextChildInRange) { + if (optChangeAccumulator != nil) { + FChange *change = [[FChange alloc] initWithType:FIRDataEventTypeChildAdded + indexedNode:[FIndexedNode indexedNodeWithNode:nextChild.node] + childKey:nextChild.name]; + [optChangeAccumulator trackChildChange:change]; + } + return [newIndexed updateChild:nextChild.name withNewChild:nextChild.node]; + } else { + return newIndexed; + } + } + } else if (newChildSnap.isEmpty) { + // We're deleting a node, but it was not in the window, so ignore it. + return oldIndexed; + } else if (inRange) { + // `newChildSnap` is in range, but was ordered after `windowBoundary`. If this has changed, we bump out the + // `windowBoundary` and add the `newChildSnap` + if ([self.index compareKey:windowBoundary.name + andNode:windowBoundary.node + toOtherKey:childKey + andNode:newChildSnap + reverse:self.reverse] >= NSOrderedSame) { + if (optChangeAccumulator != nil) { + FChange *removedChange = [[FChange alloc] initWithType:FIRDataEventTypeChildRemoved + indexedNode:[FIndexedNode indexedNodeWithNode:windowBoundary.node] + childKey:windowBoundary.name]; + FChange *addedChange = [[FChange alloc] initWithType:FIRDataEventTypeChildAdded + indexedNode:[FIndexedNode indexedNodeWithNode:newChildSnap] + childKey:childKey]; + [optChangeAccumulator trackChildChange:removedChange]; + [optChangeAccumulator trackChildChange:addedChange]; + } + return [[oldIndexed updateChild:childKey withNewChild:newChildSnap] updateChild:windowBoundary.name + withNewChild:[FEmptyNode emptyNode]]; + } else { + return oldIndexed; + } + } else { + // `newChildSnap` was not in range and remains not in range, so ignore it. + return oldIndexed; + } +} + +- (FIndexedNode *)updateFullNode:(FIndexedNode *)oldSnap + withNewNode:(FIndexedNode *)newSnap + accumulator:(FChildChangeAccumulator *)optChangeAccumulator +{ + __block FIndexedNode *filtered; + if (newSnap.node.isLeafNode || newSnap.node.isEmpty) { + // Make sure we have a children node with the correct index, not a leaf node + filtered = [FIndexedNode indexedNodeWithNode:[FEmptyNode emptyNode] index:self.index]; + } else { + filtered = newSnap; + // Don't support priorities on queries. + filtered = [filtered updatePriority:[FEmptyNode emptyNode]]; + FNamedNode *startPost = nil; + FNamedNode *endPost = nil; + if (self.reverse) { + startPost = self.rangedFilter.endPost; + endPost = self.rangedFilter.startPost; + } else { + startPost = self.rangedFilter.startPost; + endPost = self.rangedFilter.endPost; + } + __block BOOL foundStartPost = NO; + __block NSUInteger count = 0; + [newSnap enumerateChildrenReverse:self.reverse usingBlock:^(NSString *childKey, id childNode, BOOL *stop) { + if (!foundStartPost && [self.index compareKey:startPost.name + andNode:startPost.node + toOtherKey:childKey + andNode:childNode + reverse:self.reverse] <= NSOrderedSame) { + // Start adding + foundStartPost = YES; + } + BOOL inRange = foundStartPost && count < self.limit; + inRange = inRange && [self.index compareKey:childKey + andNode:childNode + toOtherKey:endPost.name + andNode:endPost.node + reverse:self.reverse] <= NSOrderedSame; + if (inRange) { + count++; + } else { + filtered = [filtered updateChild:childKey withNewChild:[FEmptyNode emptyNode]]; + } + }]; + } + return [self.indexedFilter updateFullNode:oldSnap withNewNode:filtered accumulator:optChangeAccumulator]; +} + +- (FIndexedNode *)updatePriority:(id)priority forNode:(FIndexedNode *)oldSnap +{ + // Don't support priorities on queries. + return oldSnap; +} + +- (BOOL) filtersNodes { + return YES; +} + +- (id) indexedFilter { + return self.rangedFilter.indexedFilter; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FNodeFilter.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FNodeFilter.h new file mode 100644 index 00000000..f29a85a0 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Core/View/Filter/FNodeFilter.h @@ -0,0 +1,71 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@protocol FNode; +@class FIndexedNode; +@protocol FCompleteChildSource; +@class FChildChangeAccumulator; +@protocol FIndex; +@class FPath; + +/** +* FNodeFilter is used to update nodes and complete children of nodes while applying queries on the fly and keeping +* track of any child changes. This class does not track value changes as value changes depend on more than just the +* node itself. Different kind of queries require different kind of implementations of this interface. +*/ +@protocol FNodeFilter + +/** +* Update a single complete child in the snap. If the child equals the old child in the snap, this is a no-op. +* The method expects an indexed snap. +*/ +- (FIndexedNode *) updateChildIn:(FIndexedNode *)oldSnap + forChildKey:(NSString *)childKey + newChild:(id)newChildSnap + affectedPath:(FPath *)affectedPath + fromSource:(id)source + accumulator:(FChildChangeAccumulator *)optChangeAccumulator; + +/** +* Update a node in full and output any resulting change from this complete update. +*/ +- (FIndexedNode *) updateFullNode:(FIndexedNode *)oldSnap + withNewNode:(FIndexedNode *)newSnap + accumulator:(FChildChangeAccumulator *)optChangeAccumulator; + +/** +* Update the priority of the root node +*/ +- (FIndexedNode *) updatePriority:(id)priority forNode:(FIndexedNode *)oldSnap; + +/** +* Returns true if children might be filtered due to query critiera +*/ +- (BOOL) filtersNodes; + +/** +* Returns the index filter that this filter uses to get a NodeFilter that doesn't filter any children. +*/ +@property (nonatomic, strong, readonly) id indexedFilter; + +/** +* Returns the index that this filter uses +*/ +@property (nonatomic, strong, readonly) id index; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FClock.h b/ios/Pods/FirebaseDatabase/Firebase/Database/FClock.h new file mode 100644 index 00000000..1924ad40 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FClock.h @@ -0,0 +1,35 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@protocol FClock + +- (NSTimeInterval)currentTime; + +@end + +@interface FSystemClock : NSObject + ++ (FSystemClock *)clock; + +@end + +@interface FOffsetClock : NSObject + +- (id)initWithClock:(id)clock offset:(NSTimeInterval)offset; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FClock.m b/ios/Pods/FirebaseDatabase/Firebase/Database/FClock.m new file mode 100644 index 00000000..2464056f --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FClock.m @@ -0,0 +1,58 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FClock.h" + +@implementation FSystemClock + +- (NSTimeInterval)currentTime { + return [[NSDate date] timeIntervalSince1970]; +} + ++ (FSystemClock *)clock { + static dispatch_once_t onceToken; + static FSystemClock *clock; + dispatch_once(&onceToken, ^{ + clock = [[FSystemClock alloc] init]; + }); + return clock; +} + +@end + +@interface FOffsetClock () + +@property (nonatomic, strong) id clock; +@property (nonatomic) NSTimeInterval offset; + +@end + +@implementation FOffsetClock + +- (NSTimeInterval)currentTime { + return [self.clock currentTime] + self.offset; +} + +- (id)initWithClock:(id)clock offset:(NSTimeInterval)offset { + self = [super init]; + if (self != nil) { + self->_clock = clock; + self->_offset = offset; + } + return self; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FEventGenerator.h b/ios/Pods/FirebaseDatabase/Firebase/Database/FEventGenerator.h new file mode 100644 index 00000000..1bc011b9 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FEventGenerator.h @@ -0,0 +1,27 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class FQuerySpec; +@class FIndexedNode; +@protocol FNode; + +@interface FEventGenerator : NSObject +- (id) initWithQuery:(FQuerySpec *)query; +- (NSArray*) generateEventsForChanges:(NSArray*)changes eventCache:(FIndexedNode *)eventCache + eventRegistrations:(NSArray*)registrations; +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FEventGenerator.m b/ios/Pods/FirebaseDatabase/Firebase/Database/FEventGenerator.m new file mode 100644 index 00000000..f6e8f477 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FEventGenerator.m @@ -0,0 +1,141 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FEventGenerator.h" +#import "FNode.h" +#import "FIRDatabaseQuery_Private.h" +#import "FQueryParams.h" +#import "FQuerySpec.h" +#import "FChange.h" +#import "FNamedNode.h" +#import "FEventRegistration.h" +#import "FEvent.h" +#import "FDataEvent.h" + +@interface FEventGenerator () +@property (nonatomic, strong) FQuerySpec *query; +@end + +/** +* An EventGenerator is used to convert "raw" changes (fb.core.view.Change) as computed by the +* CacheDiffer into actual events (fb.core.view.Event) that can be raised. See generateEventsForChanges() +* for details. +*/ +@implementation FEventGenerator + +- (id)initWithQuery:(FQuerySpec *)query { + self = [super init]; + if (self) { + self.query = query; + } + return self; +} + +/** +* Given a set of raw changes (no moved events, and prevName not specified yet), and a set of EventRegistrations that +* should be notified of these changes, generate the actual events to be raised. +* +* Notes: +* - child_moved events will be synthesized at this time for any child_changed events that affect our index +* - prevName will be calculated based on the index ordering +* +* @param changes NSArray of FChange, not necessarily in order. +* @param registrations is NSArray of FEventRegistration. +* @return NSArray of FEvent. +*/ +- (NSArray *) generateEventsForChanges:(NSArray *)changes + eventCache:(FIndexedNode *)eventCache + eventRegistrations:(NSArray *)registrations +{ + NSMutableArray *events = [[NSMutableArray alloc] init]; + + // child_moved is index-specific, so check all our child_changed events to see if we need to materialize + // child_moved events with this view's index + NSMutableArray *moves = [[NSMutableArray alloc] init]; + for (FChange *change in changes) { + if (change.type == FIRDataEventTypeChildChanged && [self.query.index indexedValueChangedBetween:change.oldIndexedNode.node + and:change.indexedNode.node]) { + FChange *moveChange = [[FChange alloc] initWithType:FIRDataEventTypeChildMoved + indexedNode:change.indexedNode + childKey:change.childKey + oldIndexedNode:nil]; + [moves addObject:moveChange]; + } + } + + [self generateEvents:events forType:FIRDataEventTypeChildRemoved changes:changes eventCache:eventCache eventRegistrations:registrations]; + [self generateEvents:events forType:FIRDataEventTypeChildAdded changes:changes eventCache:eventCache eventRegistrations:registrations]; + [self generateEvents:events forType:FIRDataEventTypeChildMoved changes:moves eventCache:eventCache eventRegistrations:registrations]; + [self generateEvents:events forType:FIRDataEventTypeChildChanged changes:changes eventCache:eventCache eventRegistrations:registrations]; + [self generateEvents:events forType:FIRDataEventTypeValue changes:changes eventCache:eventCache eventRegistrations:registrations]; + + return events; +} + +- (void) generateEvents:(NSMutableArray *)events + forType:(FIRDataEventType)eventType + changes:(NSArray *)changes + eventCache:(FIndexedNode *)eventCache + eventRegistrations:(NSArray *)registrations +{ + NSMutableArray *filteredChanges = [[NSMutableArray alloc] init]; + for (FChange *change in changes) { + if (change.type == eventType) { + [filteredChanges addObject:change]; + } + } + + id index = self.query.index; + + [filteredChanges sortUsingComparator:^NSComparisonResult(FChange *one, FChange *two) { + if (one.childKey == nil || two.childKey == nil) { + @throw [[NSException alloc] initWithName:@"InternalInconsistencyError" + reason:@"Should only compare child_ events" + userInfo:nil]; + } + return [index compareKey:one.childKey + andNode:one.indexedNode.node + toOtherKey:two.childKey + andNode:two.indexedNode.node]; + }]; + + for (FChange *change in filteredChanges) { + for (id registration in registrations) { + if ([registration responseTo:eventType]) { + id event = [self generateEventForChange:change registration:registration eventCache:eventCache]; + [events addObject:event]; + } + } + } +} + +- (id) generateEventForChange:(FChange *)change + registration:(id)registration + eventCache:(FIndexedNode *)eventCache +{ + FChange *materializedChange; + if (change.type == FIRDataEventTypeValue || change.type == FIRDataEventTypeChildRemoved) { + materializedChange = change; + } else { + NSString *prevChildKey = [eventCache predecessorForChildKey:change.childKey + childNode:change.indexedNode.node + index:self.query.index]; + materializedChange = [change changeWithPrevKey:prevChildKey]; + } + return [registration createEventFrom:materializedChange query:self.query]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FIRDatabaseConfig_Private.h b/ios/Pods/FirebaseDatabase/Firebase/Database/FIRDatabaseConfig_Private.h new file mode 100644 index 00000000..ac37f2e2 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FIRDatabaseConfig_Private.h @@ -0,0 +1,31 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRDatabaseConfig.h" +#import "FAuthTokenProvider.h" + +@protocol FStorageEngine; + +@interface FIRDatabaseConfig () + +@property (nonatomic, readonly) BOOL isFrozen; +@property (nonatomic, strong, readonly) NSString *sessionIdentifier; +@property (nonatomic, strong) id authTokenProvider; +@property (nonatomic, strong) id forceStorageEngine; + +- (void)freeze; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FIRDatabaseReference.m b/ios/Pods/FirebaseDatabase/Firebase/Database/FIRDatabaseReference.m new file mode 100644 index 00000000..3ea5992f --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FIRDatabaseReference.m @@ -0,0 +1,400 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FIRDatabaseReference.h" +#import +#import "FUtilities.h" +#import "FNextPushId.h" +#import "FIRDatabaseQuery_Private.h" +#import "FValidation.h" +#import "FIRDatabaseReference_Private.h" +#import "FStringUtilities.h" +#import "FSnapshotUtilities.h" +#import "FIRDatabaseConfig.h" +#import "FIRDatabaseConfig_Private.h" +#import "FQueryParams.h" +#import "FIRDatabase.h" + +@implementation FIRDatabaseReference + +#pragma mark - +#pragma mark Constructors + +- (id) initWithConfig:(FIRDatabaseConfig *)config { + FParsedUrl* parsedUrl = [FUtilities parseUrl:[[FIRApp defaultApp] options].databaseURL]; + [FValidation validateFrom:@"initWithUrl:" validURL:parsedUrl]; + return [self initWithRepo:[FRepoManager getRepo:parsedUrl.repoInfo config:config] path:parsedUrl.path]; +} + +- (id) initWithRepo:(FRepo *)repo path:(FPath *)path { + return [super initWithRepo:repo + path:path + params:[FQueryParams defaultInstance] + orderByCalled:NO + priorityMethodCalled:NO]; +} + + +#pragma mark - +#pragma mark Ancillary methods + +- (nullable NSString *) key { + if([self.path isEmpty]) { + return nil; + } + else { + return [self.path getBack]; + } +} + +- (FIRDatabase *) database { + return self.repo.database; +} + +- (FIRDatabaseReference *) parent { + FPath* parentPath = [self.path parent]; + FIRDatabaseReference * parent = nil; + if (parentPath != nil ) { + parent = [[FIRDatabaseReference alloc] initWithRepo:self.repo path:parentPath]; + } + return parent; +} + +- (NSString *) URL { + FIRDatabaseReference * parent = [self parent]; + return parent == nil ? [self.repo description] : [NSString stringWithFormat:@"%@/%@", [parent description], [FStringUtilities urlEncoded:self.key]]; +} + +- (NSString *) description { + return [self URL]; +} + +- (FIRDatabaseReference *) root { + return [[FIRDatabaseReference alloc] initWithRepo:self.repo path:[[FPath alloc] initWith:@""]]; +} + +#pragma mark - +#pragma mark Child methods + +- (FIRDatabaseReference *)childByAppendingPath:(NSString *)pathString { + return [self child:pathString]; +} + +- (FIRDatabaseReference *)child:(NSString *)pathString { + if ([self.path getFront] == nil) { + // we're at the root + [FValidation validateFrom:@"child:" validRootPathString:pathString]; + } else { + [FValidation validateFrom:@"child:" validPathString:pathString]; + } + FPath* path = [self.path childFromString:pathString]; + FIRDatabaseReference * firebaseRef = [[FIRDatabaseReference alloc] initWithRepo:self.repo path:path]; + return firebaseRef; +} + +- (FIRDatabaseReference *) childByAutoId { + [FValidation validateFrom:@"childByAutoId:" writablePath:self.path]; + + NSString* name = [FNextPushId get:self.repo.serverTime]; + return [self child:name]; +} + +#pragma mark - +#pragma mark Basic write methods + +- (void) setValue:(id)value { + [self setValueInternal:value andPriority:nil withCompletionBlock:nil from:@"setValue:"]; +} + +- (void) setValue:(id)value withCompletionBlock:(fbt_void_nserror_ref)block { + [self setValueInternal:value andPriority:nil withCompletionBlock:block from:@"setValue:withCompletionBlock:"]; +} + +- (void) setValue:(id)value andPriority:(id)priority { + [self setValueInternal:value andPriority:priority withCompletionBlock:nil from:@"setValue:andPriority:"]; +} + +- (void) setValue:(id)value andPriority:(id)priority withCompletionBlock:(fbt_void_nserror_ref)block { + [self setValueInternal:value andPriority:priority withCompletionBlock:block from:@"setValue:andPriority:withCompletionBlock:"]; +} + +- (void) setValueInternal:(id)value andPriority:(id)priority withCompletionBlock:(fbt_void_nserror_ref)block from:(NSString*)fn { + [FValidation validateFrom:fn writablePath:self.path]; + + fbt_void_nserror_ref userCallback = [block copy]; + id newNode = [FSnapshotUtilities nodeFrom:value priority:priority withValidationFrom:fn]; + + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + [self.repo set:self.path withNode:newNode withCallback:userCallback]; + }); +} + + +- (void) removeValue { + [self setValueInternal:nil andPriority:nil withCompletionBlock:nil from:@"removeValue:"]; +} + +- (void) removeValueWithCompletionBlock:(fbt_void_nserror_ref)block { + [self setValueInternal:nil andPriority:nil withCompletionBlock:block from:@"removeValueWithCompletionBlock:"]; +} + + +- (void) setPriority:(id)priority { + [self setPriorityInternal:priority withCompletionBlock:nil from:@"setPriority:"]; +} + +- (void) setPriority:(id)priority withCompletionBlock:(fbt_void_nserror_ref)block { + + [self setPriorityInternal:priority withCompletionBlock:block from:@"setPriority:withCompletionBlock:"]; +} + +- (void) setPriorityInternal:(id)priority withCompletionBlock:(fbt_void_nserror_ref)block from:(NSString*)fn { + [FValidation validateFrom:fn writablePath:self.path]; + + fbt_void_nserror_ref userCallback = [block copy]; + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + [self.repo set:[self.path childFromString:@".priority"] withNode:[FSnapshotUtilities nodeFrom:priority] withCallback:userCallback]; + }); +} + + +- (void) updateChildValues:(NSDictionary *)values { + [self updateChildValuesInternal:values withCompletionBlock:nil from:@"updateChildValues:"]; +} + +- (void) updateChildValues:(NSDictionary *)values withCompletionBlock:(fbt_void_nserror_ref)block { + [self updateChildValuesInternal:values withCompletionBlock:block from:@"updateChildValues:withCompletionBlock:"]; +} + +- (void) updateChildValuesInternal:(NSDictionary *)values withCompletionBlock:(fbt_void_nserror_ref)block from:(NSString*)fn { + [FValidation validateFrom:fn writablePath:self.path]; + + FCompoundWrite *merge = [FSnapshotUtilities compoundWriteFromDictionary:values withValidationFrom:fn]; + + fbt_void_nserror_ref userCallback = [block copy]; + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + [self.repo update:self.path withNodes:merge withCallback:userCallback]; + }); +} + +#pragma mark - +#pragma mark Disconnect Operations + +- (void) onDisconnectSetValue:(id)value { + [self onDisconnectSetValueInternal:value andPriority:nil withCompletionBlock:nil from:@"onDisconnectSetValue:"]; +} + +- (void) onDisconnectSetValue:(id)value withCompletionBlock:(fbt_void_nserror_ref)block { + [self onDisconnectSetValueInternal:value andPriority:nil withCompletionBlock:block from:@"onDisconnectSetValue:withCompletionBlock:"]; +} + +- (void) onDisconnectSetValue:(id)value andPriority:(id)priority { + [self onDisconnectSetValueInternal:value andPriority:priority withCompletionBlock:nil from:@"onDisconnectSetValue:andPriority:"]; +} + +- (void) onDisconnectSetValue:(id)value andPriority:(id)priority withCompletionBlock:(fbt_void_nserror_ref)block { + [self onDisconnectSetValueInternal:value andPriority:priority withCompletionBlock:block from:@"onDisconnectSetValue:andPriority:withCompletionBlock:"]; +} + +- (void) onDisconnectSetValueInternal:(id)value andPriority:(id)priority withCompletionBlock:(fbt_void_nserror_ref)block from:(NSString*)fn { + [FValidation validateFrom:fn writablePath:self.path]; + + id newNodeUnresolved = [FSnapshotUtilities nodeFrom:value priority:priority withValidationFrom:fn]; + + fbt_void_nserror_ref userCallback = [block copy]; + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + [self.repo onDisconnectSet:self.path withNode:newNodeUnresolved withCallback:userCallback]; + }); +} + + +- (void) onDisconnectRemoveValue { + [self onDisconnectSetValueInternal:nil andPriority:nil withCompletionBlock:nil from:@"onDisconnectRemoveValue:"]; +} + +- (void) onDisconnectRemoveValueWithCompletionBlock:(fbt_void_nserror_ref)block { + [self onDisconnectSetValueInternal:nil andPriority:nil withCompletionBlock:block from:@"onDisconnectRemoveValueWithCompletionBlock:"]; +} + + +- (void) onDisconnectUpdateChildValues:(NSDictionary *)values { + [self onDisconnectUpdateChildValuesInternal:values withCompletionBlock:nil from:@"onDisconnectUpdateChildValues:"]; +} + +- (void) onDisconnectUpdateChildValues:(NSDictionary *)values withCompletionBlock:(fbt_void_nserror_ref)block { + [self onDisconnectUpdateChildValuesInternal:values withCompletionBlock:block from:@"onDisconnectUpdateChildValues:withCompletionBlock:"]; +} + +- (void) onDisconnectUpdateChildValuesInternal:(NSDictionary *)values withCompletionBlock:(fbt_void_nserror_ref)block from:(NSString*)fn { + [FValidation validateFrom:fn writablePath:self.path]; + + FCompoundWrite *merge = [FSnapshotUtilities compoundWriteFromDictionary:values withValidationFrom:fn]; + + fbt_void_nserror_ref userCallback = [block copy]; + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + [self.repo onDisconnectUpdate:self.path withNodes:merge withCallback:userCallback]; + }); +} + + +- (void) cancelDisconnectOperations { + [self cancelDisconnectOperationsWithCompletionBlock:nil]; +} + +- (void) cancelDisconnectOperationsWithCompletionBlock:(fbt_void_nserror_ref)block { + fbt_void_nserror_ref callback = nil; + if (block != nil) { + callback = [block copy]; + } + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + [self.repo onDisconnectCancel:self.path withCallback:callback]; + }); +} + +#pragma mark - +#pragma mark Connection management methods + ++ (void) goOffline { + [FRepoManager interruptAll]; +} + ++ (void) goOnline { + [FRepoManager resumeAll]; +} + + +#pragma mark - +#pragma mark Data reading methods deferred to FQuery + +- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType withBlock:(fbt_void_datasnapshot)block { + return [self observeEventType:eventType withBlock:block withCancelBlock:nil]; +} + +- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(fbt_void_datasnapshot_nsstring)block { + return [self observeEventType:eventType andPreviousSiblingKeyWithBlock:block withCancelBlock:nil]; +} + +- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType withBlock:(fbt_void_datasnapshot)block withCancelBlock:(fbt_void_nserror)cancelBlock { + return [super observeEventType:eventType withBlock:block withCancelBlock:cancelBlock]; +} + +- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(fbt_void_datasnapshot_nsstring)block withCancelBlock:(fbt_void_nserror)cancelBlock { + return [super observeEventType:eventType andPreviousSiblingKeyWithBlock:block withCancelBlock:cancelBlock]; +} + + +- (void) removeObserverWithHandle:(FIRDatabaseHandle)handle { + [super removeObserverWithHandle:handle]; +} + + +- (void) removeAllObservers { + [super removeAllObservers]; +} + +- (void) keepSynced:(BOOL)keepSynced { + [super keepSynced:keepSynced]; +} + +- (void)observeSingleEventOfType:(FIRDataEventType)eventType withBlock:(fbt_void_datasnapshot)block { + [self observeSingleEventOfType:eventType withBlock:block withCancelBlock:nil]; +} + +- (void)observeSingleEventOfType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(fbt_void_datasnapshot_nsstring)block { + [self observeSingleEventOfType:eventType andPreviousSiblingKeyWithBlock:block withCancelBlock:nil]; +} + +- (void)observeSingleEventOfType:(FIRDataEventType)eventType withBlock:(fbt_void_datasnapshot)block withCancelBlock:(fbt_void_nserror)cancelBlock { + [super observeSingleEventOfType:eventType withBlock:block withCancelBlock:cancelBlock]; +} + +- (void)observeSingleEventOfType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(fbt_void_datasnapshot_nsstring)block withCancelBlock:(fbt_void_nserror)cancelBlock { + [super observeSingleEventOfType:eventType andPreviousSiblingKeyWithBlock:block withCancelBlock:cancelBlock]; +} + +#pragma mark - +#pragma mark Query methods +// These methods suppress warnings from having method definitions in FIRDatabaseReference.h for docs generation. + +- (FIRDatabaseQuery *)queryLimitedToFirst:(NSUInteger)limit { + return [super queryLimitedToFirst:limit]; +} + +- (FIRDatabaseQuery *)queryLimitedToLast:(NSUInteger)limit { + return [super queryLimitedToLast:limit]; +} + +- (FIRDatabaseQuery *)queryOrderedByChild:(NSString *)key { + return [super queryOrderedByChild:key]; +} + +- (FIRDatabaseQuery *) queryOrderedByKey { + return [super queryOrderedByKey]; +} + +- (FIRDatabaseQuery *) queryOrderedByPriority { + return [super queryOrderedByPriority]; +} + +- (FIRDatabaseQuery *)queryStartingAtValue:(id)startValue { + return [super queryStartingAtValue:startValue]; +} + +- (FIRDatabaseQuery *)queryStartingAtValue:(id)startValue childKey:(NSString *)childKey { + return [super queryStartingAtValue:startValue childKey:childKey]; +} + +- (FIRDatabaseQuery *)queryEndingAtValue:(id)endValue { + return [super queryEndingAtValue:endValue]; +} + +- (FIRDatabaseQuery *)queryEndingAtValue:(id)endValue childKey:(NSString *)childKey { + return [super queryEndingAtValue:endValue childKey:childKey]; +} + +- (FIRDatabaseQuery *)queryEqualToValue:(id)value { + return [super queryEqualToValue:value]; +} + +- (FIRDatabaseQuery *)queryEqualToValue:(id)value childKey:(NSString *)childKey { + return [super queryEqualToValue:value childKey:childKey]; +} + + +#pragma mark - +#pragma mark Transaction methods + +- (void) runTransactionBlock:(fbt_transactionresult_mutabledata)block { + [FValidation validateFrom:@"runTransactionBlock:" writablePath:self.path]; + [self runTransactionBlock:block andCompletionBlock:nil withLocalEvents:YES]; +} + +- (void) runTransactionBlock:(fbt_transactionresult_mutabledata)update andCompletionBlock:(fbt_void_nserror_bool_datasnapshot)completionBlock { + [FValidation validateFrom:@"runTransactionBlock:andCompletionBlock:" writablePath:self.path]; + [self runTransactionBlock:update andCompletionBlock:completionBlock withLocalEvents:YES]; +} + +- (void) runTransactionBlock:(fbt_transactionresult_mutabledata)block andCompletionBlock:(fbt_void_nserror_bool_datasnapshot)completionBlock withLocalEvents:(BOOL)localEvents { + [FValidation validateFrom:@"runTransactionBlock:andCompletionBlock:withLocalEvents:" writablePath:self.path]; + fbt_transactionresult_mutabledata updateCopy = [block copy]; + fbt_void_nserror_bool_datasnapshot onCompleteCopy = [completionBlock copy]; + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + [self.repo startTransactionOnPath:self.path update:updateCopy onComplete:onCompleteCopy withLocalEvents:localEvents]; + }); +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FIndex.h b/ios/Pods/FirebaseDatabase/Firebase/Database/FIndex.h new file mode 100644 index 00000000..8ab08c89 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FIndex.h @@ -0,0 +1,50 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class FImmutableSortedDictionary; +@class FNamedNode; +@protocol FNode; + +@protocol FIndex +- (NSComparisonResult) compareKey:(NSString *)key1 + andNode:(id)node1 + toOtherKey:(NSString *)key2 + andNode:(id)node2; + +- (NSComparisonResult) compareKey:(NSString *)key1 + andNode:(id)node1 + toOtherKey:(NSString *)key2 + andNode:(id)node2 + reverse:(BOOL)reverse; + +- (NSComparisonResult) compareNamedNode:(FNamedNode *)namedNode1 toNamedNode:(FNamedNode *)namedNode2; + +- (BOOL) isDefinedOn:(id)node; +- (BOOL) indexedValueChangedBetween:(id)oldNode and:(id)newNode; +- (FNamedNode*) minPost; +- (FNamedNode*) maxPost; +- (FNamedNode*) makePost:(id)indexValue name:(NSString*)name; +- (NSString*) queryDefinition; + +@end + +@interface FIndex : NSObject + ++ (id)indexFromQueryDefinition:(NSString *)string; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FIndex.m b/ios/Pods/FirebaseDatabase/Firebase/Database/FIndex.m new file mode 100644 index 00000000..61980c7b --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FIndex.m @@ -0,0 +1,38 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIndex.h" + +#import "FKeyIndex.h" +#import "FValueIndex.h" +#import "FPathIndex.h" +#import "FPriorityIndex.h" + +@implementation FIndex + ++ (id)indexFromQueryDefinition:(NSString *)string { + if ([string isEqualToString:@".key"]) { + return [FKeyIndex keyIndex]; + } else if ([string isEqualToString:@".value"]) { + return [FValueIndex valueIndex]; + } else if ([string isEqualToString:@".priority"]) { + return [FPriorityIndex priorityIndex]; + } else { + return [[FPathIndex alloc] initWithPath:[[FPath alloc] initWith:string]]; + } +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FKeyIndex.h b/ios/Pods/FirebaseDatabase/Firebase/Database/FKeyIndex.h new file mode 100644 index 00000000..a6bf787a --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FKeyIndex.h @@ -0,0 +1,23 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FIndex.h" + + +@interface FKeyIndex : NSObject ++ (id) keyIndex; +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FKeyIndex.m b/ios/Pods/FirebaseDatabase/Firebase/Database/FKeyIndex.m new file mode 100644 index 00000000..68ad461b --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FKeyIndex.m @@ -0,0 +1,115 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FKeyIndex.h" +#import "FNamedNode.h" +#import "FSnapshotUtilities.h" +#import "FUtilities.h" +#import "FEmptyNode.h" + +@interface FKeyIndex () + +@property (nonatomic, strong) FNamedNode *maxPost; + +@end + +@implementation FKeyIndex + +- (id)init { + self = [super init]; + if (self) { + self.maxPost = [[FNamedNode alloc] initWithName:[FUtilities maxName] andNode:[FEmptyNode emptyNode]]; + } + return self; + +} + +- (NSComparisonResult) compareKey:(NSString *)key1 + andNode:(id)node1 + toOtherKey:(NSString *)key2 + andNode:(id)node2 +{ + return [FUtilities compareKey:key1 toKey:key2]; +} + +- (NSComparisonResult) compareKey:(NSString *)key1 + andNode:(id)node1 + toOtherKey:(NSString *)key2 + andNode:(id)node2 + reverse:(BOOL)reverse +{ + if (reverse) { + return [self compareKey:key2 andNode:node2 toOtherKey:key1 andNode:node1]; + } else { + return [self compareKey:key1 andNode:node1 toOtherKey:key2 andNode:node2]; + } +} + +- (NSComparisonResult) compareNamedNode:(FNamedNode *)namedNode1 toNamedNode:(FNamedNode *)namedNode2 +{ + return [self compareKey:namedNode1.name andNode:namedNode1.node toOtherKey:namedNode2.name andNode:namedNode2.node]; +} + +- (BOOL)isDefinedOn:(id )node { + return YES; +} + +- (BOOL)indexedValueChangedBetween:(id )oldNode and:(id )newNode { + return NO; // The key for a node never changes. +} + +- (FNamedNode *)minPost { + return [FNamedNode min]; +} + +- (FNamedNode *)makePost:(id)indexValue name:(NSString*)name { + NSString *key = indexValue.val; + NSAssert([key isKindOfClass:[NSString class]], @"KeyIndex indexValue must always be a string."); + // We just use empty node, but it'll never be compared, since our comparator only looks at name. + return [[FNamedNode alloc] initWithName:key andNode:[FEmptyNode emptyNode]]; +} + +- (NSString *) queryDefinition { + return @".key"; +} + +- (NSString *) description { + return @"FKeyIndex"; +} + +- (id)copyWithZone:(NSZone *)zone { + return self; +} + +- (BOOL) isEqual:(id)other { + // since we're a singleton. + return (other == self); +} + +- (NSUInteger) hash { + return [@".key" hash]; +} + + ++ (id) keyIndex { + static id keyIndex; + static dispatch_once_t once; + dispatch_once(&once, ^{ + keyIndex = [[FKeyIndex alloc] init]; + }); + return keyIndex; +} +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FListenComplete.h b/ios/Pods/FirebaseDatabase/Firebase/Database/FListenComplete.h new file mode 100644 index 00000000..914a3e45 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FListenComplete.h @@ -0,0 +1,29 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FOperation.h" + + +@interface FListenComplete : NSObject + +- (id) initWithSource:(FOperationSource *)aSource path:(FPath *)aPath; + +@property (nonatomic, strong, readonly) FOperationSource *source; +@property (nonatomic, strong, readonly) FPath *path; +@property (nonatomic, readonly) FOperationType type; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FListenComplete.m b/ios/Pods/FirebaseDatabase/Firebase/Database/FListenComplete.m new file mode 100644 index 00000000..85730754 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FListenComplete.m @@ -0,0 +1,51 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FListenComplete.h" +#import "FOperationSource.h" +#import "FPath.h" + +@interface FListenComplete () +@property (nonatomic, strong, readwrite) FOperationSource *source; +@property (nonatomic, strong, readwrite) FPath *path; +@property (nonatomic, readwrite) FOperationType type; +@end + +@implementation FListenComplete +- (id) initWithSource:(FOperationSource *)aSource path:(FPath *)aPath { + NSAssert(!aSource.fromUser, @"Can't have a listen complete from a user source"); + self = [super init]; + if (self) { + self.source = aSource; + self.path = aPath; + self.type = FOperationTypeListenComplete; + } + return self; +} + +- (id ) operationForChild:(NSString *)childKey { + if ([self.path isEmpty]) { + return [[FListenComplete alloc] initWithSource:self.source path:[FPath empty]]; + } else { + return [[FListenComplete alloc] initWithSource:self.source path:[self.path popFront]]; + } +} + +- (NSString *) description { + return [NSString stringWithFormat:@"FListenComplete { path=%@, source=%@ }", self.path, self.source]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FMaxNode.h b/ios/Pods/FirebaseDatabase/Firebase/Database/FMaxNode.h new file mode 100644 index 00000000..6aff8c6f --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FMaxNode.h @@ -0,0 +1,23 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FChildrenNode.h" + + +@interface FMaxNode : FChildrenNode + + (id) maxNode; +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FMaxNode.m b/ios/Pods/FirebaseDatabase/Firebase/Database/FMaxNode.m new file mode 100644 index 00000000..3c93684b --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FMaxNode.m @@ -0,0 +1,61 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FMaxNode.h" +#import "FUtilities.h" +#import "FEmptyNode.h" + + +@implementation FMaxNode { + +} +- (id) init { + self = [super init]; + if (self) { + + } + return self; +} + ++ (id) maxNode { + static FMaxNode *maxNode = nil; + static dispatch_once_t once; + dispatch_once(&once, ^{ + maxNode = [[FMaxNode alloc] init]; + }); + return maxNode; +} + +- (NSComparisonResult) compare:(id)other { + if (other == self) { + return NSOrderedSame; + } else { + return NSOrderedDescending; + } +} + +- (BOOL)isEqual:(id)other { + return other == self; +} + +- (id) getImmediateChild:(NSString *) childName { + return [FEmptyNode emptyNode]; +} + +- (BOOL) isEmpty { + return NO; +} +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FNamedNode.h b/ios/Pods/FirebaseDatabase/Firebase/Database/FNamedNode.h new file mode 100644 index 00000000..ac9baa65 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FNamedNode.h @@ -0,0 +1,32 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FNode.h" + +@interface FNamedNode : NSObject + +@property (nonatomic, strong, readonly) NSString* name; +@property (nonatomic, strong, readonly) id node; + + +-(id)initWithName:(NSString*)name andNode:(id)node; + ++ (FNamedNode *)nodeWithName:(NSString *)name node:(id)node; + ++ (FNamedNode*) min; ++ (FNamedNode*) max; +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FNamedNode.m b/ios/Pods/FirebaseDatabase/Firebase/Database/FNamedNode.m new file mode 100644 index 00000000..d11787b2 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FNamedNode.m @@ -0,0 +1,94 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FNamedNode.h" +#import "FUtilities.h" +#import "FEmptyNode.h" +#import "FMaxNode.h" +#import "FIndex.h" + +@interface FNamedNode () +@property (nonatomic, strong, readwrite) NSString* name; +@property (nonatomic, strong, readwrite) id node; +@end + +@implementation FNamedNode + ++ (FNamedNode *)nodeWithName:(NSString *)name node:(id)node +{ + return [[FNamedNode alloc] initWithName:name andNode:node]; +} + +- (id)initWithName:(NSString *)name andNode:(id )node { + self = [super init]; + if (self) { + self.name = name; + self.node = node; + } + return self; +} + +- (id)copy +{ + return self; +} + +- (id)copyWithZone:(NSZone *)zone +{ + return self; +} + ++ (FNamedNode *)min { + static FNamedNode *min = nil; + static dispatch_once_t once; + dispatch_once(&once, ^{ + min = [[FNamedNode alloc] initWithName:[FUtilities minName] andNode:[FEmptyNode emptyNode]]; + }); + return min; +} + ++ (FNamedNode *)max { + static FNamedNode *max = nil; + static dispatch_once_t once; + dispatch_once(&once, ^{ + max = [[FNamedNode alloc] initWithName:[FUtilities maxName] andNode:[FMaxNode maxNode]]; + }); + return max; +} + +- (NSString *) description { + return [NSString stringWithFormat:@"NamedNode[%@] %@", self.name, self.node]; +} + +- (BOOL) isEqual:(id)object { + if (self == object) { return YES; } + if (object == nil || ![object isKindOfClass:[FNamedNode class]]) { return NO; } + + FNamedNode *namedNode = object; + if (![self.name isEqualToString:namedNode.name]) { return NO; } + if (![self.node isEqual:namedNode.node]) { return NO; } + + return YES; +} + +- (NSUInteger) hash { + NSUInteger nameHash = [self.name hash]; + NSUInteger nodeHash = [self.node hash]; + NSUInteger result = 31 * nameHash + nodeHash; + return result; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FPathIndex.h b/ios/Pods/FirebaseDatabase/Firebase/Database/FPathIndex.h new file mode 100644 index 00000000..cf92ad1b --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FPathIndex.h @@ -0,0 +1,23 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FIndex.h" +#import "FPath.h" + +@interface FPathIndex : NSObject +- (id) initWithPath:(FPath *)path; +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FPathIndex.m b/ios/Pods/FirebaseDatabase/Firebase/Database/FPathIndex.m new file mode 100644 index 00000000..39913aae --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FPathIndex.m @@ -0,0 +1,125 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FPathIndex.h" +#import "FUtilities.h" +#import "FMaxNode.h" +#import "FEmptyNode.h" +#import "FSnapshotUtilities.h" +#import "FNamedNode.h" +#import "FPath.h" + +@interface FPathIndex () + @property (nonatomic, strong) FPath *path; +@end + +@implementation FPathIndex + +- (id) initWithPath:(FPath *)path { + self = [super init]; + if (self) { + if (path.isEmpty || [path.getFront isEqualToString:@".priority"]) { + [NSException raise:NSInvalidArgumentException format:@"Invalid path for PathIndex: %@", path]; + } + _path = path; + } + return self; +} + +- (NSComparisonResult) compareKey:(NSString *)key1 + andNode:(id)node1 + toOtherKey:(NSString *)key2 + andNode:(id)node2 +{ + id child1 = [node1 getChild:self.path]; + id child2 = [node2 getChild:self.path]; + NSComparisonResult indexCmp = [child1 compare:child2]; + if (indexCmp == NSOrderedSame) { + return [FUtilities compareKey:key1 toKey:key2]; + } else { + return indexCmp; + } +} + +- (NSComparisonResult) compareKey:(NSString *)key1 + andNode:(id)node1 + toOtherKey:(NSString *)key2 + andNode:(id)node2 + reverse:(BOOL)reverse +{ + if (reverse) { + return [self compareKey:key2 andNode:node2 toOtherKey:key1 andNode:node1]; + } else { + return [self compareKey:key1 andNode:node1 toOtherKey:key2 andNode:node2]; + } +} + +- (NSComparisonResult) compareNamedNode:(FNamedNode *)namedNode1 toNamedNode:(FNamedNode *)namedNode2 +{ + return [self compareKey:namedNode1.name andNode:namedNode1.node toOtherKey:namedNode2.name andNode:namedNode2.node]; +} + +- (BOOL)isDefinedOn:(id )node { + return ![node getChild:self.path].isEmpty; +} + +- (BOOL)indexedValueChangedBetween:(id )oldNode and:(id )newNode { + id oldValue = [oldNode getChild:self.path]; + id newValue = [newNode getChild:self.path]; + return [oldValue compare:newValue] != NSOrderedSame; +} + +- (FNamedNode *)minPost { + return FNamedNode.min; +} + +- (FNamedNode *)maxPost { + id maxNode = [[FEmptyNode emptyNode] updateChild:self.path + withNewChild:[FMaxNode maxNode]]; + + return [[FNamedNode alloc] initWithName:[FUtilities maxName] andNode:maxNode]; +} + +- (FNamedNode*)makePost:(id)indexValue name:(NSString*)name { + id node = [[FEmptyNode emptyNode] updateChild:self.path withNewChild:indexValue]; + return [[FNamedNode alloc] initWithName:name andNode:node]; +} + +- (NSString *)queryDefinition { + return [self.path wireFormat]; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"FPathIndex(%@)", self.path]; +} + +- (id)copyWithZone:(NSZone *)zone { + // Safe since we're immutable. + return self; +} + +- (BOOL) isEqual:(id)other { + if (![other isKindOfClass:[FPathIndex class]]) { + return NO; + } + return ([self.path isEqual:((FPathIndex*)other).path]); +} + +- (NSUInteger) hash { + return [self.path hash]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FPriorityIndex.h b/ios/Pods/FirebaseDatabase/Firebase/Database/FPriorityIndex.h new file mode 100644 index 00000000..8b5904d2 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FPriorityIndex.h @@ -0,0 +1,23 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import "FIndex.h" + +@interface FPriorityIndex : NSObject ++ (id) priorityIndex; +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FPriorityIndex.m b/ios/Pods/FirebaseDatabase/Firebase/Database/FPriorityIndex.m new file mode 100644 index 00000000..2d06ffa1 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FPriorityIndex.m @@ -0,0 +1,118 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FPriorityIndex.h" + +#import "FNode.h" +#import "FUtilities.h" +#import "FNamedNode.h" +#import "FEmptyNode.h" +#import "FLeafNode.h" +#import "FMaxNode.h" + +// TODO: Abstract into some common base class? + +@implementation FPriorityIndex + +- (NSComparisonResult) compareKey:(NSString *)key1 + andNode:(id)node1 + toOtherKey:(NSString *)key2 + andNode:(id)node2 +{ + id child1 = [node1 getPriority]; + id child2 = [node2 getPriority]; + NSComparisonResult indexCmp = [child1 compare:child2]; + if (indexCmp == NSOrderedSame) { + return [FUtilities compareKey:key1 toKey:key2]; + } else { + return indexCmp; + } +} + +- (NSComparisonResult) compareKey:(NSString *)key1 + andNode:(id)node1 + toOtherKey:(NSString *)key2 + andNode:(id)node2 + reverse:(BOOL)reverse +{ + if (reverse) { + return [self compareKey:key2 andNode:node2 toOtherKey:key1 andNode:node1]; + } else { + return [self compareKey:key1 andNode:node1 toOtherKey:key2 andNode:node2]; + } +} + +- (NSComparisonResult) compareNamedNode:(FNamedNode *)namedNode1 toNamedNode:(FNamedNode *)namedNode2 +{ + return [self compareKey:namedNode1.name andNode:namedNode1.node toOtherKey:namedNode2.name andNode:namedNode2.node]; +} + +- (BOOL)isDefinedOn:(id )node { + return !node.getPriority.isEmpty; +} + +- (BOOL)indexedValueChangedBetween:(id )oldNode and:(id )newNode { + id oldValue = [oldNode getPriority]; + id newValue = [newNode getPriority]; + return ![oldValue isEqual:newValue]; +} + +- (FNamedNode *)minPost { + return FNamedNode.min; +} + +- (FNamedNode *)maxPost { + return [self makePost:[FMaxNode maxNode] name:[FUtilities maxName]]; +} + +- (FNamedNode*)makePost:(id)indexValue name:(NSString*)name { + id node = [[FLeafNode alloc] initWithValue:@"[PRIORITY-POST]" withPriority:indexValue]; + return [[FNamedNode alloc] initWithName:name andNode:node]; +} + +- (NSString *)queryDefinition { + return @".priority"; +} + +- (NSString *)description { + return @"FPriorityIndex"; +} + +- (id)copyWithZone:(NSZone *)zone { + // Safe since we're immutable. + return self; +} + +- (BOOL) isEqual:(id)other { + return [other isKindOfClass:[FPriorityIndex class]]; +} + +- (NSUInteger) hash { + // chosen by a fair dice roll. Guaranteed to be random + return 3155577; +} + ++ (id) priorityIndex { + static id index; + static dispatch_once_t once; + dispatch_once(&once, ^{ + index = [[FPriorityIndex alloc] init]; + }); + + return index; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FRangedFilter.h b/ios/Pods/FirebaseDatabase/Firebase/Database/FRangedFilter.h new file mode 100644 index 00000000..14577788 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FRangedFilter.h @@ -0,0 +1,32 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FNodeFilter.h" + +@class FQueryParams; +@class FNamedNode; + +@interface FRangedFilter : NSObject + +- (id) initWithQueryParams:(FQueryParams *)params; +- (BOOL) matchesKey:(NSString *)key andNode:(id)node; + + +@property (nonatomic, strong, readonly) FNamedNode *startPost; +@property (nonatomic, strong, readonly) FNamedNode *endPost; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FRangedFilter.m b/ios/Pods/FirebaseDatabase/Firebase/Database/FRangedFilter.m new file mode 100644 index 00000000..5c4bbeb9 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FRangedFilter.m @@ -0,0 +1,118 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FRangedFilter.h" +#import "FChildChangeAccumulator.h" +#import "FNamedNode.h" +#import "FQueryParams.h" +#import "FIndexedFilter.h" +#import "FQueryParams.h" +#import "FEmptyNode.h" +#import "FChildrenNode.h" +#import "FIndexedNode.h" + +@interface FRangedFilter () +@property (nonatomic, strong, readwrite) id indexedFilter; +@property (nonatomic, strong, readwrite) id index; +@property (nonatomic, strong, readwrite) FNamedNode *startPost; +@property (nonatomic, strong, readwrite) FNamedNode *endPost; +@end + +@implementation FRangedFilter +- (id) initWithQueryParams:(FQueryParams *)params { + self = [super init]; + if (self) { + self.indexedFilter = [[FIndexedFilter alloc] initWithIndex:params.index]; + self.index = params.index; + self.startPost = [FRangedFilter startPostFromQueryParams:params]; + self.endPost = [FRangedFilter endPostFromQueryParams:params]; + } + return self; +} + + ++ (FNamedNode *) startPostFromQueryParams:(FQueryParams *)params { + if ([params hasStart]) { + NSString *startKey = params.indexStartKey; + return [params.index makePost:params.indexStartValue name:startKey]; + } else { + return params.index.minPost; + } +} + ++ (FNamedNode *) endPostFromQueryParams:(FQueryParams *)params { + if ([params hasEnd]) { + NSString *endKey = params.indexEndKey; + return [params.index makePost:params.indexEndValue name:endKey]; + } else { + return params.index.maxPost; + } +} + +- (BOOL) matchesKey:(NSString *)key andNode:(id)node { + return ([self.index compareKey:self.startPost.name andNode:self.startPost.node toOtherKey:key andNode:node] <= NSOrderedSame && + [self.index compareKey:key andNode:node toOtherKey:self.endPost.name andNode:self.endPost.node] <= NSOrderedSame); +} + +- (FIndexedNode *)updateChildIn:(FIndexedNode *)oldSnap + forChildKey:(NSString *)childKey + newChild:(id)newChildSnap + affectedPath:(FPath *)affectedPath + fromSource:(id)source + accumulator:(FChildChangeAccumulator *)optChangeAccumulator +{ + if (![self matchesKey:childKey andNode:newChildSnap]) { + newChildSnap = [FEmptyNode emptyNode]; + } + return [self.indexedFilter updateChildIn:oldSnap + forChildKey:childKey + newChild:newChildSnap + affectedPath:affectedPath + fromSource:source + accumulator:optChangeAccumulator]; +} + +- (FIndexedNode *) updateFullNode:(FIndexedNode *)oldSnap + withNewNode:(FIndexedNode *)newSnap + accumulator:(FChildChangeAccumulator *)optChangeAccumulator +{ + __block FIndexedNode *filtered; + if (newSnap.node.isLeafNode) { + // Make sure we have a children node with the correct index, not a leaf node + filtered = [FIndexedNode indexedNodeWithNode:[FEmptyNode emptyNode] index:self.index]; + } else { + // Dont' support priorities on queries + filtered = [newSnap updatePriority:[FEmptyNode emptyNode]]; + [newSnap.node enumerateChildrenUsingBlock:^(NSString *key, id node, BOOL *stop) { + if (![self matchesKey:key andNode:node]) { + filtered = [filtered updateChild:key withNewChild:[FEmptyNode emptyNode]]; + } + }]; + } + return [self.indexedFilter updateFullNode:oldSnap withNewNode:filtered accumulator:optChangeAccumulator]; +} + +- (FIndexedNode *) updatePriority:(id)priority forNode:(FIndexedNode *)oldSnap +{ + // Don't support priorities on queries + return oldSnap; +} + +- (BOOL) filtersNodes { + return YES; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FTransformedEnumerator.h b/ios/Pods/FirebaseDatabase/Firebase/Database/FTransformedEnumerator.h new file mode 100644 index 00000000..75391a84 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FTransformedEnumerator.h @@ -0,0 +1,24 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + + +@interface FTransformedEnumerator : NSEnumerator +- (id)initWithEnumerator:(NSEnumerator*) enumerator andTransform:(id (^)(id))transform; +- (id)nextObject; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FTransformedEnumerator.m b/ios/Pods/FirebaseDatabase/Firebase/Database/FTransformedEnumerator.m new file mode 100644 index 00000000..bb36e948 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FTransformedEnumerator.m @@ -0,0 +1,43 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FTransformedEnumerator.h" + +@interface FTransformedEnumerator () +@property (nonatomic, strong) NSEnumerator *enumerator; +@property (nonatomic, copy) id (^transform)(id); +@end + +@implementation FTransformedEnumerator +- (id)initWithEnumerator:(NSEnumerator *)enumerator andTransform:(id (^)(id))transform { + self = [super init]; + if (self) { + self.enumerator = enumerator; + self.transform = transform; + } + return self; +} + +- (id)nextObject { + id next = self.enumerator.nextObject; + if (next != nil) { + return self.transform(next); + } else { + return nil; + } +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FValueIndex.h b/ios/Pods/FirebaseDatabase/Firebase/Database/FValueIndex.h new file mode 100644 index 00000000..0f1c7f79 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FValueIndex.h @@ -0,0 +1,23 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FIndex.h" + + +@interface FValueIndex : NSObject ++ (id) valueIndex; +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FValueIndex.m b/ios/Pods/FirebaseDatabase/Firebase/Database/FValueIndex.m new file mode 100644 index 00000000..7ef9bfff --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FValueIndex.m @@ -0,0 +1,106 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FValueIndex.h" +#import "FNamedNode.h" +#import "FSnapshotUtilities.h" +#import "FUtilities.h" +#import "FMaxNode.h" + +@implementation FValueIndex + +- (NSComparisonResult) compareKey:(NSString *)key1 + andNode:(id)node1 + toOtherKey:(NSString *)key2 + andNode:(id)node2 +{ + NSComparisonResult indexCmp = [node1 compare:node2]; + if (indexCmp == NSOrderedSame) { + return [FUtilities compareKey:key1 toKey:key2]; + } else { + return indexCmp; + } +} + +- (NSComparisonResult) compareKey:(NSString *)key1 + andNode:(id)node1 + toOtherKey:(NSString *)key2 + andNode:(id)node2 + reverse:(BOOL)reverse +{ + if (reverse) { + return [self compareKey:key2 andNode:node2 toOtherKey:key1 andNode:node1]; + } else { + return [self compareKey:key1 andNode:node1 toOtherKey:key2 andNode:node2]; + } +} + +- (NSComparisonResult) compareNamedNode:(FNamedNode *)namedNode1 toNamedNode:(FNamedNode *)namedNode2 +{ + return [self compareKey:namedNode1.name andNode:namedNode1.node toOtherKey:namedNode2.name andNode:namedNode2.node]; +} + +- (BOOL)isDefinedOn:(id)node { + return YES; +} + +- (BOOL)indexedValueChangedBetween:(id)oldNode and:(id)newNode { + return ![oldNode isEqual:newNode]; +} + +- (FNamedNode *)minPost { + return FNamedNode.min; +} + +- (FNamedNode *)maxPost { + return FNamedNode.max; +} + +- (FNamedNode *)makePost:(id)indexValue name:(NSString*)name { + return [[FNamedNode alloc] initWithName:name andNode:indexValue]; +} + +- (NSString *)queryDefinition { + return @".value"; +} + +- (NSString *) description { + return @"FValueIndex"; +} + +- (id)copyWithZone:(NSZone *)zone { + return self; +} + +- (BOOL) isEqual:(id)other { + // since we're a singleton. + return (other == self); +} + +- (NSUInteger) hash { + return [@".value" hash]; +} + + ++ (id) valueIndex { + static id valueIndex; + static dispatch_once_t once; + dispatch_once(&once, ^{ + valueIndex = [[FValueIndex alloc] init]; + }); + return valueIndex; +} +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FViewProcessor.h b/ios/Pods/FirebaseDatabase/Firebase/Database/FViewProcessor.h new file mode 100644 index 00000000..59bfd2dc --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FViewProcessor.h @@ -0,0 +1,41 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class FViewCache; +@class FViewProcessorResult; +@class FChildChangeAccumulator; +@protocol FNode; +@class FWriteTreeRef; +@class FPath; +@protocol FOperation; +@protocol FNodeFilter; + + +@interface FViewProcessor : NSObject + +- (id)initWithFilter:(id)nodeFilter; + +- (FViewProcessorResult *)applyOperationOn:(FViewCache *)oldViewCache operation:(id)operation writesCache:(FWriteTreeRef *)writesCache completeCache:(id )optCompleteCache; +- (FViewCache *) revertUserWriteOn:(FViewCache *)viewCache + path:(FPath *)path + writesCache:(FWriteTreeRef *)writesCache + completeCache:(id)optCompleteCache + accumulator:(FChildChangeAccumulator *)accumulator; + + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FViewProcessor.m b/ios/Pods/FirebaseDatabase/Firebase/Database/FViewProcessor.m new file mode 100644 index 00000000..50a3594a --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FViewProcessor.m @@ -0,0 +1,655 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FViewProcessor.h" +#import "FCompleteChildSource.h" +#import "FWriteTreeRef.h" +#import "FViewCache.h" +#import "FCacheNode.h" +#import "FNode.h" +#import "FOperation.h" +#import "FOperationSource.h" +#import "FChildChangeAccumulator.h" +#import "FNodeFilter.h" +#import "FOverwrite.h" +#import "FMerge.h" +#import "FAckUserWrite.h" +#import "FViewProcessorResult.h" +#import "FIRDataEventType.h" +#import "FChange.h" +#import "FEmptyNode.h" +#import "FChildrenNode.h" +#import "FPath.h" +#import "FKeyIndex.h" +#import "FCompoundWrite.h" +#import "FImmutableTree.h" + +/** +* An implementation of FCompleteChildSource that never returns any additional children +*/ +@interface FNoCompleteChildSource: NSObject +@end + +@implementation FNoCompleteChildSource ++ (FNoCompleteChildSource *) instance { + static FNoCompleteChildSource *source = nil; + static dispatch_once_t once; + dispatch_once(&once, ^{ + source = [[FNoCompleteChildSource alloc] init]; + }); + return source; +} + +- (id) completeChild:(NSString *)childKey { + return nil; +} + +- (FNamedNode *) childByIndex:(id)index afterChild:(FNamedNode *)child isReverse:(BOOL)reverse { + return nil; +} +@end + +/** +* An implementation of FCompleteChildSource that uses a FWriteTree in addition to any other server data or +* old event caches available to calculate complete children. +*/ +@interface FWriteTreeCompleteChildSource: NSObject +@property (nonatomic, strong) FWriteTreeRef *writes; +@property (nonatomic, strong) FViewCache *viewCache; +@property (nonatomic, strong) id optCompleteServerCache; +@end + +@implementation FWriteTreeCompleteChildSource +- (id) initWithWrites:(FWriteTreeRef *)writes viewCache:(FViewCache *)viewCache serverCache:(id)optCompleteServerCache { + self = [super init]; + if (self) { + self.writes = writes; + self.viewCache = viewCache; + self.optCompleteServerCache = optCompleteServerCache; + } + return self; +} + +- (id) completeChild:(NSString *)childKey { + FCacheNode *node = self.viewCache.cachedEventSnap; + if ([node isCompleteForChild:childKey]) { + return [node.node getImmediateChild:childKey]; + } else { + FCacheNode *serverNode; + if (self.optCompleteServerCache) { + // Since we're only ever getting child nodes, we can use the key index here + FIndexedNode *indexed = [FIndexedNode indexedNodeWithNode:self.optCompleteServerCache index:[FKeyIndex keyIndex]]; + serverNode = [[FCacheNode alloc] initWithIndexedNode:indexed isFullyInitialized:YES isFiltered:NO]; + } else { + serverNode = self.viewCache.cachedServerSnap; + } + return [self.writes calculateCompleteChild:childKey cache:serverNode]; + } +} + +- (FNamedNode *) childByIndex:(id)index afterChild:(FNamedNode *)child isReverse:(BOOL)reverse { + id completeServerData = self.optCompleteServerCache != nil + ? self.optCompleteServerCache + : self.viewCache.completeServerSnap; + return [self.writes calculateNextNodeAfterPost:child + completeServerData:completeServerData + reverse:reverse + index:index]; +} + +@end + +@interface FViewProcessor () +@property (nonatomic, strong) id filter; +@end + +@implementation FViewProcessor + +- (id)initWithFilter:(id)nodeFilter { + self = [super init]; + if (self) { + self.filter = nodeFilter; + } + return self; +} + +- (FViewProcessorResult *)applyOperationOn:(FViewCache *)oldViewCache operation:(id)operation writesCache:(FWriteTreeRef *)writesCache completeCache:(id )optCompleteCache { + FChildChangeAccumulator *accumulator = [[FChildChangeAccumulator alloc] init]; + FViewCache *newViewCache; + + if (operation.type == FOperationTypeOverwrite) { + FOverwrite *overwrite = (FOverwrite *) operation; + if (operation.source.fromUser) { + newViewCache = [self applyUserOverwriteTo:oldViewCache + changePath:overwrite.path + changedSnap:overwrite.snap + writesCache:writesCache + completeCache:optCompleteCache + accumulator:accumulator]; + } else { + NSAssert(operation.source.fromServer, @"Unknown source for overwrite."); + // We filter the node if it's a tagged update or the node has been previously filtered and the update is + // not at the root in which case it is ok (and necessary) to mark the node unfiltered again + BOOL filterServerNode = overwrite.source.isTagged || (oldViewCache.cachedServerSnap.isFiltered && + !overwrite.path.isEmpty); + newViewCache = [self applyServerOverwriteTo:oldViewCache + changePath:overwrite.path + snap:overwrite.snap + writesCache:writesCache + completeCache:optCompleteCache + filterServerNode:filterServerNode + accumulator:accumulator]; + } + } else if (operation.type == FOperationTypeMerge) { + FMerge *merge = (FMerge*)operation; + if (operation.source.fromUser) { + newViewCache = [self applyUserMergeTo:oldViewCache + path:merge.path + changedChildren:merge.children + writesCache:writesCache + completeCache:optCompleteCache + accumulator:accumulator]; + } else { + NSAssert(operation.source.fromServer, @"Unknown source for merge."); + // We filter the node if it's a tagged update or the node has been previously filtered + BOOL filterServerNode = merge.source.isTagged || oldViewCache.cachedServerSnap.isFiltered; + newViewCache = [self applyServerMergeTo:oldViewCache + path:merge.path + changedChildren:merge.children + writesCache:writesCache + completeCache:optCompleteCache + filterServerNode:filterServerNode + accumulator:accumulator]; + } + } else if (operation.type == FOperationTypeAckUserWrite) { + FAckUserWrite *ackWrite = (FAckUserWrite *) operation; + if (!ackWrite.revert) { + newViewCache = [self ackUserWriteOn:oldViewCache + ackPath:ackWrite.path + affectedTree:ackWrite.affectedTree + writesCache:writesCache + completeCache:optCompleteCache + accumulator:accumulator]; + } else { + newViewCache = [self revertUserWriteOn:oldViewCache + path:ackWrite.path + writesCache:writesCache + completeCache:optCompleteCache + accumulator:accumulator]; + } + } else if (operation.type == FOperationTypeListenComplete) { + newViewCache = [self listenCompleteOldCache:oldViewCache + path:operation.path + writesCache:writesCache + serverCache:optCompleteCache + accumulator:accumulator]; + } else { + [NSException raise:NSInternalInconsistencyException + format:@"Unknown operation encountered %ld.", (long)operation.type]; + return nil; + } + + NSArray *changes = [self maybeAddValueFromOldViewCache:oldViewCache newViewCache:newViewCache changes:accumulator.changes]; + FViewProcessorResult *results = [[FViewProcessorResult alloc] initWithViewCache:newViewCache changes:changes]; + return results; +} + +- (NSArray *) maybeAddValueFromOldViewCache:(FViewCache *)oldViewCache newViewCache:(FViewCache *)newViewCache changes:(NSArray *)changes { + NSArray *newChanges = changes; + FCacheNode *eventSnap = newViewCache.cachedEventSnap; + if (eventSnap.isFullyInitialized) { + BOOL isLeafOrEmpty = eventSnap.node.isLeafNode || eventSnap.node.isEmpty; + if ([changes count] > 0 || + !oldViewCache.cachedEventSnap.isFullyInitialized || + (isLeafOrEmpty && ![eventSnap.node isEqual:oldViewCache.completeEventSnap]) || + ![eventSnap.node.getPriority isEqual:oldViewCache.completeEventSnap.getPriority]) { + FChange *valueChange = [[FChange alloc] initWithType:FIRDataEventTypeValue indexedNode:eventSnap.indexedNode]; + NSMutableArray *mutableChanges = [changes mutableCopy]; + [mutableChanges addObject:valueChange]; + newChanges = mutableChanges; + } + } + return newChanges; +} + +- (FViewCache *) generateEventCacheAfterServerEvent:(FViewCache *)viewCache + path:(FPath *)changePath + writesCache:(FWriteTreeRef *)writesCache + source:(id)source + accumulator:(FChildChangeAccumulator *)accumulator { + FCacheNode *oldEventSnap = viewCache.cachedEventSnap; + if ([writesCache shadowingWriteAtPath:changePath] != nil) { + // we have a shadowing write, ignore changes. + return viewCache; + } else { + FIndexedNode *newEventCache; + if (changePath.isEmpty) { + // TODO: figure out how this plays with "sliding ack windows" + NSAssert(viewCache.cachedServerSnap.isFullyInitialized, @"If change path is empty, we must have complete server data"); + id nodeWithLocalWrites; + if (viewCache.cachedServerSnap.isFiltered) { + // We need to special case this, because we need to only apply writes to complete children, or + // we might end up raising events for incomplete children. If the server data is filtered deep + // writes cannot be guaranteed to be complete + id serverCache = viewCache.completeServerSnap; + FChildrenNode *completeChildren = ([serverCache isKindOfClass:[FChildrenNode class]]) ? serverCache : [FEmptyNode emptyNode]; + nodeWithLocalWrites = [writesCache calculateCompleteEventChildrenWithCompleteServerChildren:completeChildren]; + } else { + nodeWithLocalWrites = [writesCache calculateCompleteEventCacheWithCompleteServerCache:viewCache.completeServerSnap]; + } + FIndexedNode *indexedNode = [FIndexedNode indexedNodeWithNode:nodeWithLocalWrites index:self.filter.index]; + newEventCache = [self.filter updateFullNode:viewCache.cachedEventSnap.indexedNode + withNewNode:indexedNode + accumulator:accumulator]; + } else { + NSString *childKey = [changePath getFront]; + if ([childKey isEqualToString:@".priority"]) { + NSAssert(changePath.length == 1, @"Can't have a priority with additional path components"); + id oldEventNode = oldEventSnap.node; + id serverNode = viewCache.cachedServerSnap.node; + // we might have overwrites for this priority + id updatedPriority = [writesCache calculateEventCacheAfterServerOverwriteWithChildPath:changePath + existingEventSnap:oldEventNode + existingServerSnap:serverNode]; + if (updatedPriority != nil) { + newEventCache = [self.filter updatePriority:updatedPriority forNode:oldEventSnap.indexedNode]; + } else { + // priority didn't change, keep old node + newEventCache = oldEventSnap.indexedNode; + } + } else { + FPath *childChangePath = [changePath popFront]; + id newEventChild; + if ([oldEventSnap isCompleteForChild:childKey]) { + id serverNode = viewCache.cachedServerSnap.node; + id eventChildUpdate = [writesCache calculateEventCacheAfterServerOverwriteWithChildPath:changePath existingEventSnap:oldEventSnap.node existingServerSnap:serverNode]; + if (eventChildUpdate != nil) { + newEventChild = [[oldEventSnap.node getImmediateChild:childKey] updateChild:childChangePath withNewChild:eventChildUpdate]; + } else { + // Nothing changed, just keep the old child + newEventChild = [oldEventSnap.node getImmediateChild:childKey]; + } + } else { + newEventChild = [writesCache calculateCompleteChild:childKey cache:viewCache.cachedServerSnap]; + } + if (newEventChild != nil) { + newEventCache = [self.filter updateChildIn:oldEventSnap.indexedNode + forChildKey:childKey + newChild:newEventChild + affectedPath:childChangePath + fromSource:source + accumulator:accumulator]; + } else { + // No complete children available or no change + newEventCache = oldEventSnap.indexedNode; + } + } + } + return [viewCache updateEventSnap:newEventCache + isComplete:(oldEventSnap.isFullyInitialized || changePath.isEmpty) + isFiltered:self.filter.filtersNodes]; + } +} + +- (FViewCache *) applyServerOverwriteTo:(FViewCache *)oldViewCache changePath:(FPath *)changePath snap:(id)changedSnap + writesCache:(FWriteTreeRef *)writesCache completeCache:(id)optCompleteCache + filterServerNode:(BOOL)filterServerNode accumulator:(FChildChangeAccumulator *)accumulator { + FCacheNode *oldServerSnap = oldViewCache.cachedServerSnap; + FIndexedNode *newServerCache; + id serverFilter = filterServerNode ? self.filter : self.filter.indexedFilter; + + if (changePath.isEmpty) { + FIndexedNode *indexed = [FIndexedNode indexedNodeWithNode:changedSnap index:serverFilter.index]; + newServerCache = [serverFilter updateFullNode:oldServerSnap.indexedNode withNewNode:indexed accumulator:nil]; + } else if (serverFilter.filtersNodes && !oldServerSnap.isFiltered) { + // We want to filter the server node, but we didn't filter the server node yet, so simulate a full update + NSAssert(![changePath isEmpty], @"An empty path should been caught in the other branch"); + NSString *childKey = [changePath getFront]; + FPath *updatePath = [changePath popFront]; + id newChild = [[oldServerSnap.node getImmediateChild:childKey] updateChild:updatePath + withNewChild:changedSnap]; + FIndexedNode *indexed = [oldServerSnap.indexedNode updateChild:childKey withNewChild:newChild]; + newServerCache = [serverFilter updateFullNode:oldServerSnap.indexedNode withNewNode:indexed accumulator:nil]; + } else { + NSString *childKey = [changePath getFront]; + if (![oldServerSnap isCompleteForPath:changePath] && changePath.length > 1) { + // We don't update incomplete nodes with updates intended for other listeners. + return oldViewCache; + } + FPath *childChangePath = [changePath popFront]; + id childNode = [oldServerSnap.node getImmediateChild:childKey]; + id newChildNode = [childNode updateChild:childChangePath withNewChild:changedSnap]; + if ([childKey isEqualToString:@".priority"]) { + newServerCache = [serverFilter updatePriority:newChildNode forNode:oldServerSnap.indexedNode]; + } else { + newServerCache = [serverFilter updateChildIn:oldServerSnap.indexedNode + forChildKey:childKey + newChild:newChildNode + affectedPath:childChangePath + fromSource:[FNoCompleteChildSource instance] + accumulator:nil]; + } + } + FViewCache *newViewCache = [oldViewCache updateServerSnap:newServerCache + isComplete:(oldServerSnap.isFullyInitialized || changePath.isEmpty) + isFiltered:serverFilter.filtersNodes]; + id source = [[FWriteTreeCompleteChildSource alloc] initWithWrites:writesCache + viewCache:newViewCache + serverCache:optCompleteCache]; + return [self generateEventCacheAfterServerEvent:newViewCache + path:changePath + writesCache:writesCache + source:source + accumulator:accumulator]; +} + +- (FViewCache *) applyUserOverwriteTo:(FViewCache *)oldViewCache + changePath:(FPath *)changePath + changedSnap:(id)changedSnap + writesCache:(FWriteTreeRef *)writesCache + completeCache:(id)optCompleteCache + accumulator:(FChildChangeAccumulator *)accumulator { + FCacheNode *oldEventSnap = oldViewCache.cachedEventSnap; + FViewCache *newViewCache; + id source = [[FWriteTreeCompleteChildSource alloc] initWithWrites:writesCache + viewCache:oldViewCache + serverCache:optCompleteCache]; + if (changePath.isEmpty) { + FIndexedNode *newIndexed = [FIndexedNode indexedNodeWithNode:changedSnap index:self.filter.index]; + FIndexedNode *newEventCache = [self.filter updateFullNode:oldEventSnap.indexedNode + withNewNode:newIndexed + accumulator:accumulator]; + newViewCache = [oldViewCache updateEventSnap:newEventCache isComplete:YES isFiltered:self.filter.filtersNodes]; + } else { + NSString *childKey = [changePath getFront]; + if ([childKey isEqualToString:@".priority"]) { + FIndexedNode *newEventCache = [self.filter updatePriority:changedSnap + forNode:oldViewCache.cachedEventSnap.indexedNode]; + newViewCache = [oldViewCache updateEventSnap:newEventCache + isComplete:oldEventSnap.isFullyInitialized + isFiltered:oldEventSnap.isFiltered]; + } else { + FPath *childChangePath = [changePath popFront]; + id oldChild = [oldEventSnap.node getImmediateChild:childKey]; + id newChild; + if (childChangePath.isEmpty) { + // Child overwrite, we can replace the child + newChild = changedSnap; + } else { + id childNode = [source completeChild:childKey]; + if (childNode != nil) { + if ([[childChangePath getBack] isEqualToString:@".priority"] && [childNode getChild:[childChangePath parent]].isEmpty) { + // This is a priority update on an empty node. If this node exists on the server, the server + // will send down the priority in the update, so ignore for now + newChild = childNode; + } else { + newChild = [childNode updateChild:childChangePath withNewChild:changedSnap]; + } + } else { + newChild = [FEmptyNode emptyNode]; + } + } + if (![oldChild isEqual:newChild]) { + FIndexedNode *newEventSnap = [self.filter updateChildIn:oldEventSnap.indexedNode + forChildKey:childKey + newChild:newChild + affectedPath:childChangePath + fromSource:source + accumulator:accumulator]; + newViewCache = [oldViewCache updateEventSnap:newEventSnap isComplete:oldEventSnap.isFullyInitialized isFiltered:self.filter.filtersNodes]; + } else { + newViewCache = oldViewCache; + } + } + } + return newViewCache; +} + ++ (BOOL) cache:(FViewCache *)viewCache hasChild:(NSString *)childKey { + return [viewCache.cachedEventSnap isCompleteForChild:childKey]; +} + +/** +* @param changedChildren NSDictionary of child name (NSString*) to child value (id) +*/ +- (FViewCache *) applyUserMergeTo:(FViewCache *)viewCache + path:(FPath *)path + changedChildren:(FCompoundWrite *)changedChildren + writesCache:(FWriteTreeRef *)writesCache + completeCache:(id)serverCache + accumulator:(FChildChangeAccumulator *)accumulator { + // HACK: In the case of a limit query, there may be some changes that bump things out of the + // window leaving room for new items. It's important we process these changes first, so we + // iterate the changes twice, first processing any that affect items currently in view. + // TODO: I consider an item "in view" if cacheHasChild is true, which checks both the server + // and event snap. I'm not sure if this will result in edge cases when a child is in one but + // not the other. + __block FViewCache *curViewCache = viewCache; + + [changedChildren enumerateWrites:^(FPath *relativePath, id childNode, BOOL *stop) { + FPath *writePath = [path child:relativePath]; + if ([FViewProcessor cache:viewCache hasChild:[writePath getFront]]) { + curViewCache = [self applyUserOverwriteTo:curViewCache + changePath:writePath + changedSnap:childNode + writesCache:writesCache + completeCache:serverCache + accumulator:accumulator]; + } + }]; + + [changedChildren enumerateWrites:^(FPath *relativePath, id childNode, BOOL *stop) { + FPath *writePath = [path child:relativePath]; + if (![FViewProcessor cache:viewCache hasChild:[writePath getFront]]) { + curViewCache = [self applyUserOverwriteTo:curViewCache + changePath:writePath + changedSnap:childNode + writesCache:writesCache + completeCache:serverCache + accumulator:accumulator]; + } + }]; + + return curViewCache; +} + +- (FViewCache *) applyServerMergeTo:(FViewCache *)viewCache + path:(FPath *)path + changedChildren:(FCompoundWrite *)changedChildren + writesCache:(FWriteTreeRef *)writesCache + completeCache:(id)serverCache + filterServerNode:(BOOL)filterServerNode + accumulator:(FChildChangeAccumulator *)accumulator { + // If we don't have a cache yet, this merge was intended for a previously listen in the same location. Ignore it and + // wait for the complete data update coming soon. + if (viewCache.cachedServerSnap.node.isEmpty && !viewCache.cachedServerSnap.isFullyInitialized) { + return viewCache; + } + + // HACK: In the case of a limit query, there may be some changes that bump things out of the + // window leaving room for new items. It's important we process these changes first, so we + // iterate the changes twice, first processing any that affect items currently in view. + // TODO: I consider an item "in view" if cacheHasChild is true, which checks both the server + // and event snap. I'm not sure if this will result in edge cases when a child is in one but + // not the other. + __block FViewCache *curViewCache = viewCache; + FCompoundWrite *actualMerge; + if (path.isEmpty) { + actualMerge = changedChildren; + } else { + actualMerge = [[FCompoundWrite emptyWrite] addCompoundWrite:changedChildren atPath:path]; + } + id serverNode = viewCache.cachedServerSnap.node; + + NSDictionary *childCompoundWrites = actualMerge.childCompoundWrites; + [childCompoundWrites enumerateKeysAndObjectsUsingBlock:^(NSString *childKey, FCompoundWrite *childMerge, BOOL *stop) { + if ([serverNode hasChild:childKey]) { + id serverChild = [viewCache.cachedServerSnap.node getImmediateChild:childKey]; + id newChild = [childMerge applyToNode:serverChild]; + curViewCache = [self applyServerOverwriteTo:curViewCache + changePath:[[FPath alloc] initWith:childKey] + snap:newChild + writesCache:writesCache + completeCache:serverCache + filterServerNode:filterServerNode + accumulator:accumulator]; + } + }]; + + [childCompoundWrites enumerateKeysAndObjectsUsingBlock:^(NSString *childKey, FCompoundWrite *childMerge, BOOL *stop) { + bool isUnknownDeepMerge = ![viewCache.cachedServerSnap isCompleteForChild:childKey] && childMerge.rootWrite == nil; + if (![serverNode hasChild:childKey] && !isUnknownDeepMerge) { + id serverChild = [viewCache.cachedServerSnap.node getImmediateChild:childKey]; + id newChild = [childMerge applyToNode:serverChild]; + curViewCache = [self applyServerOverwriteTo:curViewCache + changePath:[[FPath alloc] initWith:childKey] + snap:newChild + writesCache:writesCache + completeCache:serverCache + filterServerNode:filterServerNode + accumulator:accumulator]; + } + }]; + + return curViewCache; +} + +- (FViewCache *) ackUserWriteOn:(FViewCache *)viewCache + ackPath:(FPath *)ackPath + affectedTree:(FImmutableTree *)affectedTree + writesCache:(FWriteTreeRef *)writesCache + completeCache:(id )optCompleteCache + accumulator:(FChildChangeAccumulator *)accumulator { + + if ([writesCache shadowingWriteAtPath:ackPath] != nil) { + return viewCache; + } + + // Only filter server node if it is currently filtered + BOOL filterServerNode = viewCache.cachedServerSnap.isFiltered; + + // Essentially we'll just get our existing server cache for the affected paths and re-apply it as a server update + // now that it won't be shadowed. + FCacheNode *serverCache = viewCache.cachedServerSnap; + if (affectedTree.value != nil) { + // This is an overwrite. + if ((ackPath.isEmpty && serverCache.isFullyInitialized) || [serverCache isCompleteForPath:ackPath]) { + return [self applyServerOverwriteTo:viewCache changePath:ackPath snap:[serverCache.node getChild:ackPath] + writesCache:writesCache completeCache:optCompleteCache + filterServerNode:filterServerNode accumulator:accumulator]; + } else if (ackPath.isEmpty) { + // This is a goofy edge case where we are acking data at this location but don't have full data. We + // should just re-apply whatever we have in our cache as a merge. + FCompoundWrite *changedChildren = [FCompoundWrite emptyWrite]; + for(FNamedNode *child in serverCache.node.childEnumerator) { + changedChildren = [changedChildren addWrite:child.node atKey:child.name]; + } + return [self applyServerMergeTo:viewCache path:ackPath changedChildren:changedChildren + writesCache:writesCache completeCache:optCompleteCache + filterServerNode:filterServerNode accumulator:accumulator]; + } else { + return viewCache; + } + } else { + // This is a merge. + __block FCompoundWrite *changedChildren = [FCompoundWrite emptyWrite]; + [affectedTree forEach:^(FPath *mergePath, id value) { + FPath *serverCachePath = [ackPath child:mergePath]; + if ([serverCache isCompleteForPath:serverCachePath]) { + changedChildren = [changedChildren addWrite:[serverCache.node getChild:serverCachePath] atPath:mergePath]; + } + }]; + return [self applyServerMergeTo:viewCache path:ackPath changedChildren:changedChildren + writesCache:writesCache completeCache:optCompleteCache + filterServerNode:filterServerNode accumulator:accumulator]; + } +} + +- (FViewCache *) revertUserWriteOn:(FViewCache *)viewCache + path:(FPath *)path + writesCache:(FWriteTreeRef *)writesCache + completeCache:(id)optCompleteCache + accumulator:(FChildChangeAccumulator *)accumulator { + if ([writesCache shadowingWriteAtPath:path] != nil) { + return viewCache; + } else { + id source = [[FWriteTreeCompleteChildSource alloc] initWithWrites:writesCache + viewCache:viewCache + serverCache:optCompleteCache]; + FIndexedNode *oldEventCache = viewCache.cachedEventSnap.indexedNode; + FIndexedNode *newEventCache; + if (path.isEmpty || [[path getFront] isEqualToString:@".priority"]) { + id newNode; + if (viewCache.cachedServerSnap.isFullyInitialized) { + newNode = [writesCache calculateCompleteEventCacheWithCompleteServerCache:viewCache.completeServerSnap]; + } else { + newNode = [writesCache calculateCompleteEventChildrenWithCompleteServerChildren:viewCache.cachedServerSnap.node]; + } + FIndexedNode *indexedNode = [FIndexedNode indexedNodeWithNode:newNode index:self.filter.index]; + newEventCache = [self.filter updateFullNode:oldEventCache withNewNode:indexedNode accumulator:accumulator]; + } else { + NSString *childKey = [path getFront]; + id newChild = [writesCache calculateCompleteChild:childKey cache:viewCache.cachedServerSnap]; + if (newChild == nil && [viewCache.cachedServerSnap isCompleteForChild:childKey]) { + newChild = [oldEventCache.node getImmediateChild:childKey]; + } + if (newChild != nil) { + newEventCache = [self.filter updateChildIn:oldEventCache + forChildKey:childKey + newChild:newChild + affectedPath:[path popFront] + fromSource:source + accumulator:accumulator]; + } else if (newChild == nil && [viewCache.cachedEventSnap.node hasChild:childKey]) { + // No complete child available, delete the existing one, if any + newEventCache = [self.filter updateChildIn:oldEventCache + forChildKey:childKey + newChild:[FEmptyNode emptyNode] + affectedPath:[path popFront] + fromSource:source + accumulator:accumulator]; + } else { + newEventCache = oldEventCache; + } + if (newEventCache.node.isEmpty && viewCache.cachedServerSnap.isFullyInitialized) { + // We might have reverted all child writes. Maybe the old event was a leaf node. + id complete = [writesCache calculateCompleteEventCacheWithCompleteServerCache:viewCache.completeServerSnap]; + if (complete.isLeafNode) { + FIndexedNode *indexed = [FIndexedNode indexedNodeWithNode:complete]; + newEventCache = [self.filter updateFullNode:newEventCache + withNewNode:indexed + accumulator:accumulator]; + } + } + } + BOOL complete = viewCache.cachedServerSnap.isFullyInitialized || [writesCache shadowingWriteAtPath:[FPath empty]] != nil; + return [viewCache updateEventSnap:newEventCache isComplete:complete isFiltered:self.filter.filtersNodes]; + } +} + +- (FViewCache *) listenCompleteOldCache:(FViewCache *)viewCache + path:(FPath *)path + writesCache:(FWriteTreeRef *)writesCache + serverCache:(id)servercache + accumulator:(FChildChangeAccumulator *)accumulator { + FCacheNode *oldServerNode = viewCache.cachedServerSnap; + FViewCache *newViewCache = [viewCache updateServerSnap:oldServerNode.indexedNode + isComplete:(oldServerNode.isFullyInitialized || path.isEmpty) + isFiltered:oldServerNode.isFiltered]; + return [self generateEventCacheAfterServerEvent:newViewCache path:path writesCache:writesCache source:[FNoCompleteChildSource instance] accumulator:accumulator]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FViewProcessorResult.h b/ios/Pods/FirebaseDatabase/Firebase/Database/FViewProcessorResult.h new file mode 100644 index 00000000..e211d196 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FViewProcessorResult.h @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class FViewCache; + + +@interface FViewProcessorResult : NSObject +@property (nonatomic, strong, readonly) FViewCache *viewCache; +/** +* List of FChanges. +*/ +@property (nonatomic, strong, readonly) NSArray *changes; + +- (id) initWithViewCache:(FViewCache *)viewCache changes:(NSArray *)changes; +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/FViewProcessorResult.m b/ios/Pods/FirebaseDatabase/Firebase/Database/FViewProcessorResult.m new file mode 100644 index 00000000..3327888a --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/FViewProcessorResult.m @@ -0,0 +1,35 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FViewProcessorResult.h" +#import "FViewCache.h" + +@interface FViewProcessorResult () +@property (nonatomic, strong, readwrite) FViewCache *viewCache; +@property (nonatomic, strong, readwrite) NSArray *changes; +@end + +@implementation FViewProcessorResult +- (id) initWithViewCache:(FViewCache *)viewCache changes:(NSArray *)changes { + self = [super init]; + if (self) { + self.viewCache = viewCache; + self.changes = changes; + } + return self; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Login/FAuthTokenProvider.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Login/FAuthTokenProvider.h new file mode 100644 index 00000000..a4f8b156 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Login/FAuthTokenProvider.h @@ -0,0 +1,39 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import "FTypedefs.h" +#import "FTypedefs_Private.h" + +@protocol FIRAuthInterop; + +@protocol FAuthTokenProvider + +- (void)fetchTokenForcingRefresh:(BOOL)forceRefresh + withCallback:(fbt_void_nsstring_nserror)callback; + +- (void)listenForTokenChanges:(fbt_void_nsstring)listener; + +@end + +@interface FAuthTokenProvider : NSObject + ++ (id)authTokenProviderWithAuth:(id)auth; + +- (instancetype)init NS_UNAVAILABLE; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Login/FAuthTokenProvider.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Login/FAuthTokenProvider.m new file mode 100644 index 00000000..50103602 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Login/FAuthTokenProvider.m @@ -0,0 +1,117 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FAuthTokenProvider.h" + +#import +#import +#import +#import + +#import "FUtilities.h" +#import "FIRDatabaseQuery_Private.h" +#import "FIRNoopAuthTokenProvider.h" + +@interface FAuthStateListenerWrapper : NSObject + +@property (nonatomic, copy) fbt_void_nsstring listener; +@property (nonatomic, weak) id auth; + +@end + +@implementation FAuthStateListenerWrapper + +- (instancetype)initWithListener:(fbt_void_nsstring)listener auth:(id)auth { + self = [super init]; + if (self != nil) { + self->_listener = listener; + self->_auth = auth; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(authStateDidChangeNotification:) + name:FIRAuthStateDidChangeInternalNotification + object:nil]; + } + return self; +} + +- (void)authStateDidChangeNotification:(NSNotification *)notification { + NSDictionary *userInfo = notification.userInfo; + if (notification.object == self.auth) { + NSString *token = userInfo[FIRAuthStateDidChangeInternalNotificationTokenKey]; + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + self.listener(token); + }); + } +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +@end + + +@interface FIRFirebaseAuthTokenProvider : NSObject + +@property (nonatomic, strong) id auth; +/** Strong references to the auth listeners as they are only weak in FIRFirebaseApp */ +@property (nonatomic, strong) NSMutableArray *authListeners; + +- (instancetype) initWithAuth:(id)auth; + +@end + +@implementation FIRFirebaseAuthTokenProvider + +- (instancetype)initWithAuth:(id)auth { + self = [super init]; + if (self != nil) { + self->_auth = auth; + self->_authListeners = [NSMutableArray array]; + } + return self; +} + +- (void)fetchTokenForcingRefresh:(BOOL)forceRefresh + withCallback:(fbt_void_nsstring_nserror)callback { + if (self.auth == nil) { + // Signal that Auth is not available by returning nil. + callback(nil, nil); + } else { + [self.auth getTokenForcingRefresh:forceRefresh + withCallback:^(NSString * _Nullable token, NSError * _Nullable error) { + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + callback(token, error); + }); + }]; + } +} + +- (void)listenForTokenChanges:(_Nonnull fbt_void_nsstring)listener { + FAuthStateListenerWrapper *wrapper = + [[FAuthStateListenerWrapper alloc] initWithListener:listener auth:self.auth]; + [self.authListeners addObject:wrapper]; +} + +@end + +@implementation FAuthTokenProvider + ++ (id)authTokenProviderWithAuth:(id)authInterop { + return [[FIRFirebaseAuthTokenProvider alloc] initWithAuth:authInterop]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Login/FIRNoopAuthTokenProvider.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Login/FIRNoopAuthTokenProvider.h new file mode 100644 index 00000000..e27ddb48 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Login/FIRNoopAuthTokenProvider.h @@ -0,0 +1,22 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FAuthTokenProvider.h" + +@interface FIRNoopAuthTokenProvider : NSObject + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Login/FIRNoopAuthTokenProvider.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Login/FIRNoopAuthTokenProvider.m new file mode 100644 index 00000000..8bf467bc --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Login/FIRNoopAuthTokenProvider.m @@ -0,0 +1,33 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRNoopAuthTokenProvider.h" +#import "FAuthTokenProvider.h" +#import "FIRDatabaseQuery_Private.h" + +@implementation FIRNoopAuthTokenProvider + +- (void) fetchTokenForcingRefresh:(BOOL)forceRefresh withCallback:(fbt_void_nsstring_nserror)callback { + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + callback(nil, nil); + }); +} + +- (void) listenForTokenChanges:(fbt_void_nsstring)listener { + // no-op, because token never changes +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FCachePolicy.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FCachePolicy.h new file mode 100644 index 00000000..16b49fbf --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FCachePolicy.h @@ -0,0 +1,41 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@protocol FCachePolicy + +- (BOOL)shouldPruneCacheWithSize:(NSUInteger)cacheSize numberOfTrackedQueries:(NSUInteger)numTrackedQueries; +- (BOOL)shouldCheckCacheSize:(NSUInteger)serverUpdatesSinceLastCheck; +- (float)percentOfQueriesToPruneAtOnce; +- (NSUInteger)maxNumberOfQueriesToKeep; + +@end + + +@interface FLRUCachePolicy : NSObject + +@property (nonatomic, readonly) NSUInteger maxSize; + +- (id)initWithMaxSize:(NSUInteger)maxSize; + +@end + +@interface FNoCachePolicy : NSObject + ++ (FNoCachePolicy *)noCachePolicy; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FCachePolicy.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FCachePolicy.m new file mode 100644 index 00000000..7da76ef2 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FCachePolicy.m @@ -0,0 +1,79 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FCachePolicy.h" + +@interface FLRUCachePolicy () + +@property (nonatomic, readwrite) NSUInteger maxSize; + +@end + +static const NSUInteger kFServerUpdatesBetweenCacheSizeChecks = 1000; +static const NSUInteger kFMaxNumberOfPrunableQueriesToKeep = 1000; +static const float kFPercentOfQueriesToPruneAtOnce = 0.2f; + +@implementation FLRUCachePolicy + +- (id)initWithMaxSize:(NSUInteger)maxSize { + self = [super init]; + if (self != nil) { + self->_maxSize = maxSize; + } + return self; +} + +- (BOOL)shouldPruneCacheWithSize:(NSUInteger)cacheSize numberOfTrackedQueries:(NSUInteger)numTrackedQueries { + return cacheSize > self.maxSize || numTrackedQueries > kFMaxNumberOfPrunableQueriesToKeep; +} + +- (BOOL)shouldCheckCacheSize:(NSUInteger)serverUpdatesSinceLastCheck { + return serverUpdatesSinceLastCheck > kFServerUpdatesBetweenCacheSizeChecks; +} + +- (float)percentOfQueriesToPruneAtOnce { + return kFPercentOfQueriesToPruneAtOnce; +} + +- (NSUInteger)maxNumberOfQueriesToKeep { + return kFMaxNumberOfPrunableQueriesToKeep; +} + +@end + +@implementation FNoCachePolicy + ++ (FNoCachePolicy *)noCachePolicy { + return [[FNoCachePolicy alloc] init]; +} + +- (BOOL)shouldPruneCacheWithSize:(NSUInteger)cacheSize numberOfTrackedQueries:(NSUInteger)numTrackedQueries { + return NO; +} + +- (BOOL)shouldCheckCacheSize:(NSUInteger)serverUpdatesSinceLastCheck { + return NO; +} + +- (float)percentOfQueriesToPruneAtOnce { + return 0; +} + +- (NSUInteger)maxNumberOfQueriesToKeep { + return NSUIntegerMax; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FLevelDBStorageEngine.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FLevelDBStorageEngine.h new file mode 100644 index 00000000..84f38641 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FLevelDBStorageEngine.h @@ -0,0 +1,39 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import "FStorageEngine.h" +#import "FNode.h" +#import "FPath.h" +#import "FCompoundWrite.h" +#import "FQuerySpec.h" + +@class FCacheNode; +@class FTrackedQuery; +@class FPruneForest; +@class FRepoInfo; + +@interface FLevelDBStorageEngine : NSObject + ++ (NSString *) firebaseDir; + +- (id)initWithPath:(NSString *)path; + +- (void)runLegacyMigration:(FRepoInfo *)info; +- (void)purgeEverything; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FLevelDBStorageEngine.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FLevelDBStorageEngine.m new file mode 100644 index 00000000..68254ad4 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FLevelDBStorageEngine.m @@ -0,0 +1,738 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import "FLevelDBStorageEngine.h" + +#import +#import "APLevelDB.h" +#import "FSnapshotUtilities.h" +#import "FWriteRecord.h" +#import "FTrackedQuery.h" +#import "FQueryParams.h" +#import "FEmptyNode.h" +#import "FPruneForest.h" +#import "FUtilities.h" +#import "FPendingPut.h" // For legacy migration + +@interface FLevelDBStorageEngine () + +@property (nonatomic, strong) NSString *basePath; +@property (nonatomic, strong) APLevelDB *writesDB; +@property (nonatomic, strong) APLevelDB *serverCacheDB; + +@end + +// WARNING: If you change this, you need to write a migration script +static NSString * const kFPersistenceVersion = @"1"; + +static NSString * const kFServerDBPath = @"server_data"; +static NSString * const kFWritesDBPath = @"writes"; + +static NSString * const kFUserWriteId = @"id"; +static NSString * const kFUserWritePath = @"path"; +static NSString * const kFUserWriteOverwrite = @"o"; +static NSString * const kFUserWriteMerge = @"m"; + +static NSString * const kFTrackedQueryId = @"id"; +static NSString * const kFTrackedQueryPath = @"path"; +static NSString * const kFTrackedQueryParams = @"p"; +static NSString * const kFTrackedQueryLastUse = @"lu"; +static NSString * const kFTrackedQueryIsComplete = @"c"; +static NSString * const kFTrackedQueryIsActive = @"a"; + +static NSString * const kFServerCachePrefix = @"/server_cache/"; +// '~' is the last non-control character in the ASCII table until 127 +// We wan't the entire range of thing stored in the DB +static NSString * const kFServerCacheRangeEnd = @"/server_cache~"; +static NSString * const kFTrackedQueriesPrefix = @"/tracked_queries/"; +static NSString * const kFTrackedQueryKeysPrefix = @"/tracked_query_keys/"; + +// Failed to load JSON because a valid JSON turns out to be NaN while deserializing +static const NSInteger kFNanFailureCode = 3840; + +static NSString* writeRecordKey(NSUInteger writeId) { + return [NSString stringWithFormat:@"%lu", (unsigned long)(writeId)]; +} + +static NSString* serverCacheKey(FPath *path) { + return [NSString stringWithFormat:@"%@%@", kFServerCachePrefix, ([path toStringWithTrailingSlash])]; +} + +static NSString* trackedQueryKey(NSUInteger trackedQueryId) { + return [NSString stringWithFormat:@"%@%lu", kFTrackedQueriesPrefix, (unsigned long)trackedQueryId]; +} + +static NSString* trackedQueryKeysKeyPrefix(NSUInteger trackedQueryId) { + return [NSString stringWithFormat:@"%@%lu/", kFTrackedQueryKeysPrefix, (unsigned long)trackedQueryId]; +} + +static NSString* trackedQueryKeysKey(NSUInteger trackedQueryId, NSString *key) { + return [NSString stringWithFormat:@"%@%lu/%@", kFTrackedQueryKeysPrefix, (unsigned long)trackedQueryId, key]; +} + +@implementation FLevelDBStorageEngine +#pragma mark - Constructors + +- (id)initWithPath:(NSString*)dbPath +{ + self = [super init]; + if (self) { + self.basePath = [[FLevelDBStorageEngine firebaseDir] stringByAppendingPathComponent:dbPath]; + /* For reference: + serverDataDB = [aPersistence createDbByName:@"server_data"]; + FPangolinDB *completenessDb = [aPersistence createDbByName:@"server_complete"]; + */ + [FLevelDBStorageEngine ensureDir:self.basePath markAsDoNotBackup:YES]; + [self runMigration]; + [self openDatabases]; + } + return self; +} + +- (void)runMigration { + // Currently we're at version 1, so all we need to do is write that to a file + NSString *versionFile = [self.basePath stringByAppendingPathComponent:@"version"]; + NSError *error; + NSString *oldVersion = [NSString stringWithContentsOfFile:versionFile encoding:NSUTF8StringEncoding error:&error]; + if (!oldVersion) { + // This is probably fine, we don't have a version file yet + BOOL success = [kFPersistenceVersion writeToFile:versionFile atomically:NO encoding:NSUTF8StringEncoding error:&error]; + if (!success) { + FFWarn(@"I-RDB076001", @"Failed to write version for database: %@", error); + } + } else if ([oldVersion isEqualToString:kFPersistenceVersion]) { + // Everythings fine no need for migration + } else { + // If we add more versions in the future, we need to run migration here + [NSException raise:NSInternalInconsistencyException format:@"Unrecognized database version: %@", oldVersion]; + } +} + +- (void)runLegacyMigration:(FRepoInfo *)info { + NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *documentsDir = [dirPaths objectAtIndex:0]; + NSString *firebaseDir = [documentsDir stringByAppendingPathComponent:@"firebase"]; + NSString* repoHashString = [NSString stringWithFormat:@"%@_%@", info.host, info.namespace]; + NSString *legacyBaseDir = [NSString stringWithFormat:@"%@/1/%@/v1", firebaseDir, repoHashString]; + if ([[NSFileManager defaultManager] fileExistsAtPath:legacyBaseDir]) { + FFWarn(@"I-RDB076002", @"Legacy database found, migrating..."); + // We only need to migrate writes + NSError *error = nil; + APLevelDB *writes = [APLevelDB levelDBWithPath:[legacyBaseDir stringByAppendingPathComponent:@"outstanding_puts"] error:&error]; + if (writes != nil) { + __block NSUInteger numberOfWritesRestored = 0; + // Maybe we could use write batches, but what the heck, I'm sure it'll go fine :P + [writes enumerateKeysAndValuesAsData:^(NSString *key, NSData *data, BOOL *stop) { + id pendingPut = [NSKeyedUnarchiver unarchiveObjectWithData:data]; + if ([pendingPut isKindOfClass:[FPendingPut class]]) { + FPendingPut *put = pendingPut; + id newNode = [FSnapshotUtilities nodeFrom:put.data priority:put.priority]; + [self saveUserOverwrite:newNode atPath:put.path writeId:[key integerValue]]; + numberOfWritesRestored++; + } else if ([pendingPut isKindOfClass:[FPendingPutPriority class]]) { + // This is for backwards compatibility. Older clients will save FPendingPutPriority. New ones will need to read it and translate. + FPendingPutPriority *putPriority = pendingPut; + FPath *priorityPath = [putPriority.path childFromString:@".priority"]; + id newNode = [FSnapshotUtilities nodeFrom:putPriority.priority priority:nil]; + [self saveUserOverwrite:newNode atPath:priorityPath writeId:[key integerValue]]; + numberOfWritesRestored++; + } else if ([pendingPut isKindOfClass:[FPendingUpdate class]]) { + FPendingUpdate *update = pendingPut; + FCompoundWrite *merge = [FCompoundWrite compoundWriteWithValueDictionary:update.data]; + [self saveUserMerge:merge atPath:update.path writeId:[key integerValue]]; + numberOfWritesRestored++; + } else { + FFWarn(@"I-RDB076003", @"Failed to migrate legacy write, meh!"); + } + }]; + FFWarn(@"I-RDB076004", @"Migrated %lu writes", (unsigned long)numberOfWritesRestored); + [writes close]; + FFWarn(@"I-RDB076005", @"Deleting legacy database..."); + BOOL success = [[NSFileManager defaultManager] removeItemAtPath:legacyBaseDir error:&error]; + if (!success) { + FFWarn(@"I-RDB076006", @"Failed to delete legacy database: %@", error); + } else { + FFWarn(@"I-RDB076007", @"Finished migrating legacy database."); + } + } else { + FFWarn(@"I-RDB076008", @"Failed to migrate old database: %@", error); + } + } +} + +- (void)openDatabases { + self.serverCacheDB = [self createDB:kFServerDBPath]; + self.writesDB = [self createDB:kFWritesDBPath]; +} + +- (void)purgeDatabase:(NSString*) dbPath { + NSString *path = [self.basePath stringByAppendingPathComponent:dbPath]; + NSError *error; + FFWarn(@"I-RDB076009", @"Deleting database at path %@", path); + BOOL success = [[NSFileManager defaultManager] removeItemAtPath:path error:&error]; + if (!success) { + [NSException raise:NSInternalInconsistencyException format:@"Failed to delete database files: %@", error]; + } +} + +- (void)purgeEverything { + [self close]; + [@[kFServerDBPath, kFWritesDBPath] + enumerateObjectsUsingBlock:^(NSString *dbPath, NSUInteger idx, BOOL *stop) { + [self purgeDatabase:dbPath]; + }]; + + [self openDatabases]; +} + +- (void)close { + // autoreleasepool will cause deallocation which will close the DB + @autoreleasepool { + [self.serverCacheDB close]; + self.serverCacheDB = nil; + [self.writesDB close]; + self.writesDB = nil; + } +} + ++ (NSString *) firebaseDir { + #if TARGET_OS_IOS || TARGET_OS_TV + NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *documentsDir = [dirPaths objectAtIndex:0]; + return [documentsDir stringByAppendingPathComponent:@"firebase"]; + #elif TARGET_OS_OSX + return [NSHomeDirectory() stringByAppendingPathComponent:@".firebase"]; + #endif +} + +- (APLevelDB *)createDB:(NSString *)dbName { + NSError *err = nil; + NSString *path = [self.basePath stringByAppendingPathComponent:dbName]; + APLevelDB *db = [APLevelDB levelDBWithPath:path error:&err]; + + if (err) { + FFWarn(@"I-RDB076036", @"Failed to read database persistence file '%@': %@", + dbName, [err localizedDescription]); + err = nil; + + // Delete the database and try again. + [self purgeDatabase:dbName]; + db = [APLevelDB levelDBWithPath:path error:&err]; + + if (err) { + NSString *reason = [NSString stringWithFormat:@"Error initializing persistence: %@", [err description]]; + @throw [NSException exceptionWithName:@"FirebaseDatabasePersistenceFailure" reason:reason userInfo:nil]; + } + } + + return db; +} + +- (void)saveUserOverwrite:(id)node atPath:(FPath *)path writeId:(NSUInteger)writeId { + NSDictionary *write = + @{ kFUserWriteId: @(writeId), + kFUserWritePath: [path toStringWithTrailingSlash], + kFUserWriteOverwrite: [node valForExport:YES] }; + NSError *error = nil; + NSData *data = [NSJSONSerialization dataWithJSONObject:write options:0 error:&error]; + NSAssert(data, @"Failed to serialize user overwrite: %@, (Error: %@)", write, error); + [self.writesDB setData:data forKey:writeRecordKey(writeId)]; +} + +- (void)saveUserMerge:(FCompoundWrite *)merge atPath:(FPath *)path writeId:(NSUInteger)writeId { + NSDictionary *write = + @{ kFUserWriteId: @(writeId), + kFUserWritePath: [path toStringWithTrailingSlash], + kFUserWriteMerge: [merge valForExport:YES] }; + NSError *error = nil; + NSData *data = [NSJSONSerialization dataWithJSONObject:write options:0 error:&error]; + NSAssert(data, @"Failed to serialize user merge: %@ (Error: %@)", write, error); + [self.writesDB setData:data forKey:writeRecordKey(writeId)]; +} + +- (void)removeUserWrite:(NSUInteger)writeId { + [self.writesDB removeKey:writeRecordKey(writeId)]; +} + +- (void)removeAllUserWrites { + __block NSUInteger count = 0; + NSDate *start = [NSDate date]; + id batch = [self.writesDB beginWriteBatch]; + [self.writesDB enumerateKeys:^(NSString *key, BOOL *stop) { + [batch removeKey:key]; + count++; + }]; + BOOL success = [batch commit]; + if (!success) { + FFWarn(@"I-RDB076010", @"Failed to remove all users writes on disk!"); + } else { + FFDebug(@"I-RDB076011", @"Removed %lu writes in %fms", (unsigned long)count, [start timeIntervalSinceNow]*-1000); + } +} + +- (NSArray *)userWrites { + NSDate *date = [NSDate date]; + NSMutableArray *writes = [NSMutableArray array]; + [self.writesDB enumerateKeysAndValuesAsData:^(NSString *key, NSData *data, BOOL *stop) { + NSError *error = nil; + NSDictionary *writeJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; + if (writeJSON == nil) { + if (error.code == kFNanFailureCode) { + FFWarn(@"I-RDB076012", @"Failed to deserialize write (%@), likely because of out of range doubles (Error: %@)", + [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding], + error); + FFWarn(@"I-RDB076013", @"Removing failed write with key %@", key); + [self.writesDB removeKey:key]; + } else { + [NSException raise:NSInternalInconsistencyException format:@"Failed to deserialize write: %@", error]; + } + } else { + NSInteger writeId = ((NSNumber *)writeJSON[kFUserWriteId]).integerValue; + FPath *path = [FPath pathWithString:writeJSON[kFUserWritePath]]; + FWriteRecord *writeRecord; + if (writeJSON[kFUserWriteMerge] != nil) { + // It's a merge + FCompoundWrite *merge = [FCompoundWrite compoundWriteWithValueDictionary:writeJSON[kFUserWriteMerge]]; + writeRecord = [[FWriteRecord alloc] initWithPath:path merge:merge writeId:writeId]; + } else { + // It's an overwrite + NSAssert(writeJSON[kFUserWriteOverwrite] != nil, @"Persisted write did not contain merge or overwrite!"); + id node = [FSnapshotUtilities nodeFrom:writeJSON[kFUserWriteOverwrite]]; + writeRecord = [[FWriteRecord alloc] initWithPath:path overwrite:node writeId:writeId visible:YES]; + } + [writes addObject:writeRecord]; + } + }]; + // Make sure writes are sorted + [writes sortUsingComparator:^NSComparisonResult(FWriteRecord *one, FWriteRecord *two) { + if (one.writeId < two.writeId) { + return NSOrderedAscending; + } else if (one.writeId > two.writeId) { + return NSOrderedDescending; + } else { + return NSOrderedSame; + } + }]; + FFDebug(@"I-RDB076014", @"Loaded %lu writes in %fms", (unsigned long)writes.count, [date timeIntervalSinceNow]*-1000); + return writes; +} + +- (id)serverCacheAtPath:(FPath *)path { + NSDate *start = [NSDate date]; + id data = [self internalNestedDataForPath:path]; + id node = [FSnapshotUtilities nodeFrom:data]; + FFDebug(@"I-RDB076015", @"Loaded node with %d children at %@ in %fms", [node numChildren], path, [start timeIntervalSinceNow]*-1000); + return node; +} + +- (id)serverCacheForKeys:(NSSet *)keys atPath:(FPath *)path { + NSDate *start = [NSDate date]; + __block id node = [FEmptyNode emptyNode]; + [keys enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) { + id data = [self internalNestedDataForPath:[path childFromString:key]]; + node = [node updateImmediateChild:key withNewChild:[FSnapshotUtilities nodeFrom:data]]; + }]; + FFDebug(@"I-RDB076016", @"Loaded node with %d children for %lu keys at %@ in %fms", [node numChildren], (unsigned long)keys.count, path, [start timeIntervalSinceNow]*-1000); + return node; +} + +- (void)updateServerCache:(id)node atPath:(FPath *)path merge:(BOOL)merge { + NSDate *start = [NSDate date]; + id batch = [self.serverCacheDB beginWriteBatch]; + // Remove any leaf nodes that might be higher up + [self removeAllLeafNodesOnPath:path batch:batch]; + __block NSUInteger counter = 0; + if (merge) { + // remove any children that exist + [node enumerateChildrenUsingBlock:^(NSString *childKey, id childNode, BOOL *stop) { + FPath *childPath = [path childFromString:childKey]; + [self removeAllWithPrefix:serverCacheKey(childPath) batch:batch database:self.serverCacheDB]; + [self saveNodeInternal:childNode atPath:childPath batch:batch counter:&counter]; + }]; + } else { + // remove everything + [self removeAllWithPrefix:serverCacheKey(path) batch:batch database:self.serverCacheDB]; + [self saveNodeInternal:node atPath:path batch:batch counter:&counter]; + } + BOOL success = [batch commit]; + if (!success) { + FFWarn(@"I-RDB076017", @"Failed to update server cache on disk!"); + } else { + FFDebug(@"I-RDB076018", @"Saved %lu leaf nodes for overwrite in %fms", (unsigned long)counter, [start timeIntervalSinceNow]*-1000); + } +} + +- (void)updateServerCacheWithMerge:(FCompoundWrite *)merge atPath:(FPath *)path { + NSDate *start = [NSDate date]; + __block NSUInteger counter = 0; + id batch = [self.serverCacheDB beginWriteBatch]; + // Remove any leaf nodes that might be higher up + [self removeAllLeafNodesOnPath:path batch:batch]; + [merge enumerateWrites:^(FPath *relativePath, id node, BOOL *stop) { + FPath *childPath = [path child:relativePath]; + [self removeAllWithPrefix:serverCacheKey(childPath) batch:batch database:self.serverCacheDB]; + [self saveNodeInternal:node atPath:childPath batch:batch counter:&counter]; + }]; + BOOL success = [batch commit]; + if (!success) { + FFWarn(@"I-RDB076019", @"Failed to update server cache on disk!"); + } else { + FFDebug(@"I-RDB076020", @"Saved %lu leaf nodes for merge in %fms", (unsigned long)counter, [start timeIntervalSinceNow]*-1000); + } +} + +- (void)saveNodeInternal:(id)node atPath:(FPath *)path batch:(id)batch counter:(NSUInteger *)counter { + id data = [node valForExport:YES]; + if(data != nil && ![data isKindOfClass:[NSNull class]]) { + [self internalSetNestedData:data forKey:serverCacheKey(path) withBatch:batch counter:counter]; + } +} + +- (NSUInteger)serverCacheEstimatedSizeInBytes { + // Use the exact size, because for pruning the approximate size can lead to weird situations where we prune everything + // because no compaction is ever run + return [self.serverCacheDB exactSizeFrom:kFServerCachePrefix to:kFServerCacheRangeEnd]; +} + +- (void)pruneCache:(FPruneForest *)pruneForest atPath:(FPath *)path { + // TODO: be more intelligent, don't scan entire database... + + __block NSUInteger pruned = 0; + __block NSUInteger kept = 0; + NSDate *start = [NSDate date]; + + NSString *prefix = serverCacheKey(path); + id batch = [self.serverCacheDB beginWriteBatch]; + + [self.serverCacheDB enumerateKeysWithPrefix:prefix usingBlock:^(NSString *dbKey, BOOL *stop) { + NSString *pathStr = [dbKey substringFromIndex:prefix.length]; + FPath *relativePath = [[FPath alloc] initWith:pathStr]; + if ([pruneForest shouldPruneUnkeptDescendantsAtPath:relativePath]) { + pruned++; + [batch removeKey:dbKey]; + } else { + kept++; + } + }]; + BOOL success = [batch commit]; + if (!success) { + FFWarn(@"I-RDB076021", @"Failed to prune cache on disk!"); + } else { + FFDebug(@"I-RDB076022", @"Pruned %lu paths, kept %lu paths in %fms", (unsigned long)pruned, (unsigned long)kept, [start timeIntervalSinceNow]*-1000); + } +} + +#pragma mark - Tracked Queries + +- (NSArray *)loadTrackedQueries { + NSDate *date = [NSDate date]; + NSMutableArray *trackedQueries = [NSMutableArray array]; + [self.serverCacheDB enumerateKeysWithPrefix:kFTrackedQueriesPrefix asData:^(NSString *key, NSData *data, BOOL *stop) { + NSError *error = nil; + NSDictionary *queryJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; + if (queryJSON == nil) { + if (error.code == kFNanFailureCode) { + FFWarn(@"I-RDB076023", @"Failed to deserialize tracked query (%@), likely because of out of range doubles (Error: %@)", + [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding], + error); + FFWarn(@"I-RDB076024", @"Removing failed tracked query with key %@", key); + [self.serverCacheDB removeKey:key]; + } else { + [NSException raise:NSInternalInconsistencyException format:@"Failed to deserialize tracked query: %@", error]; + } + } else { + NSUInteger queryId = ((NSNumber *)queryJSON[kFTrackedQueryId]).unsignedIntegerValue; + FPath *path = [FPath pathWithString:queryJSON[kFTrackedQueryPath]]; + FQueryParams *params = [FQueryParams fromQueryObject:queryJSON[kFTrackedQueryParams]]; + FQuerySpec *query = [[FQuerySpec alloc] initWithPath:path params:params]; + BOOL isComplete = [queryJSON[kFTrackedQueryIsComplete] boolValue]; + BOOL isActive = [queryJSON[kFTrackedQueryIsActive] boolValue]; + NSTimeInterval lastUse = [queryJSON[kFTrackedQueryLastUse] doubleValue]; + + FTrackedQuery *trackedQuery = [[FTrackedQuery alloc] initWithId:queryId + query:query + lastUse:lastUse + isActive:isActive + isComplete:isComplete]; + + [trackedQueries addObject:trackedQuery]; + } + }]; + FFDebug(@"I-RDB076025", @"Loaded %lu tracked queries in %fms", (unsigned long)trackedQueries.count, [date timeIntervalSinceNow]*-1000); + return trackedQueries; +} + +- (void)removeTrackedQuery:(NSUInteger)queryId { + NSDate *start = [NSDate date]; + id batch = [self.serverCacheDB beginWriteBatch]; + [batch removeKey:trackedQueryKey(queryId)]; + __block NSUInteger keyCount = 0; + [self.serverCacheDB enumerateKeysWithPrefix:trackedQueryKeysKeyPrefix(queryId) usingBlock:^(NSString *key, BOOL *stop) { + [batch removeKey:key]; + keyCount++; + }]; + + BOOL success = [batch commit]; + if (!success) { + FFWarn(@"I-RDB076026", @"Failed to remove tracked query on disk!"); + } else { + FFDebug(@"I-RDB076027", @"Removed query with id %lu (and removed %lu keys) in %fms", + (unsigned long)queryId, + (unsigned long)keyCount, + [start timeIntervalSinceNow]*-1000); + } +} + +- (void)saveTrackedQuery:(FTrackedQuery *)query { + NSDate *start = [NSDate date]; + NSDictionary *trackedQuery = + @{ + kFTrackedQueryId: @(query.queryId), + kFTrackedQueryPath: [query.query.path toStringWithTrailingSlash], + kFTrackedQueryParams: [query.query.params wireProtocolParams], + kFTrackedQueryLastUse: @(query.lastUse), + kFTrackedQueryIsComplete: @(query.isComplete), + kFTrackedQueryIsActive: @(query.isActive) + }; + NSError *error = nil; + NSData *data = [NSJSONSerialization dataWithJSONObject:trackedQuery options:0 error:&error]; + NSAssert(data, @"Failed to serialize tracked query (Error: %@)", error); + [self.serverCacheDB setData:data forKey:trackedQueryKey(query.queryId)]; + FFDebug(@"I-RDB076028", @"Saved tracked query %lu in %fms", (unsigned long)query.queryId, [start timeIntervalSinceNow]*-1000); +} + +- (void)setTrackedQueryKeys:(NSSet *)keys forQueryId:(NSUInteger)queryId { + NSDate *start = [NSDate date]; + __block NSUInteger removed = 0; + __block NSUInteger added = 0; + id batch = [self.serverCacheDB beginWriteBatch]; + NSMutableSet *seenKeys = [NSMutableSet set]; + // First, delete any keys that might be stored and are not part of the current keys + [self.serverCacheDB enumerateKeysWithPrefix:trackedQueryKeysKeyPrefix(queryId) asStrings:^(NSString *dbKey, NSString *actualKey, BOOL *stop) { + if ([keys containsObject:actualKey]) { + // Already in DB + [seenKeys addObject:actualKey]; + } else { + // Not part of set, delete key + [batch removeKey:dbKey]; + removed++; + } + }]; + + // Next add any keys that are missing in the database + [keys enumerateObjectsUsingBlock:^(NSString *childKey, BOOL *stop) { + if (![seenKeys containsObject:childKey]) { + [batch setString:childKey forKey:trackedQueryKeysKey(queryId, childKey)]; + added++; + } + }]; + BOOL success = [batch commit]; + if (!success) { + FFWarn(@"I-RDB076029", @"Failed to set tracked queries on disk!"); + } else { + FFDebug(@"I-RDB076030", @"Set %lu tracked keys (%lu added, %lu removed) for query %lu in %fms", + (unsigned long)keys.count, + (unsigned long)added, + (unsigned long)removed, + (unsigned long)queryId, + [start timeIntervalSinceNow]*-1000); + } +} + +- (void)updateTrackedQueryKeysWithAddedKeys:(NSSet *)added removedKeys:(NSSet *)removed forQueryId:(NSUInteger)queryId { + NSDate *start = [NSDate date]; + id batch = [self.serverCacheDB beginWriteBatch]; + [removed enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) { + [batch removeKey:trackedQueryKeysKey(queryId, key)]; + }]; + [added enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) { + [batch setString:key forKey:trackedQueryKeysKey(queryId, key)]; + }]; + BOOL success = [batch commit]; + if (!success) { + FFWarn(@"I-RDB076031", @"Failed to update tracked queries on disk!"); + } else { + FFDebug(@"I-RDB076032", @"Added %lu tracked keys, removed %lu for query %lu in %fms", (unsigned long)added.count, (unsigned long)removed.count, (unsigned long)queryId, [start timeIntervalSinceNow]*-1000); + } +} + +- (NSSet *)trackedQueryKeysForQuery:(NSUInteger)queryId { + NSDate *start = [NSDate date]; + NSMutableSet *set = [NSMutableSet set]; + [self.serverCacheDB enumerateKeysWithPrefix:trackedQueryKeysKeyPrefix(queryId) asStrings:^(NSString *dbKey, NSString *actualKey, BOOL *stop) { + [set addObject:actualKey]; + }]; + FFDebug(@"I-RDB076033", @"Loaded %lu tracked keys for query %lu in %fms", (unsigned long)set.count, (unsigned long)queryId, [start timeIntervalSinceNow]*-1000); + return set; +} + +#pragma mark - Internal methods + +- (void)removeAllLeafNodesOnPath:(FPath *)path batch:(id)batch { + while (!path.isEmpty) { + [batch removeKey:serverCacheKey(path)]; + path = [path parent]; + } + // Make sure to delete any nodes at the root + [batch removeKey:serverCacheKey([FPath empty])]; +} + +- (void)removeAllWithPrefix:(NSString *)prefix batch:(id)batch database:(APLevelDB *)database { + assert(prefix != nil); + + [database enumerateKeysWithPrefix:prefix usingBlock:^(NSString *key, BOOL *stop) { + [batch removeKey:key]; + }]; +} + +#pragma mark - Internal helper methods + +- (void)internalSetNestedData:(id)value forKey:(NSString *)key withBatch:(id)batch counter:(NSUInteger *)counter { + if([value isKindOfClass:[NSDictionary class]]) { + NSDictionary* dictionary = value; + [dictionary enumerateKeysAndObjectsUsingBlock:^(id childKey, id obj, BOOL *stop) { + assert(obj != nil); + NSString* childPath = [NSString stringWithFormat:@"%@%@/", key, childKey]; + [self internalSetNestedData:obj forKey:childPath withBatch:batch counter:counter]; + }]; + } + else { + NSData *data = [self serializePrimitive:value]; + [batch setData:data forKey:key]; + (*counter)++; + } +} + +- (id)internalNestedDataForPath:(FPath *)path { + NSAssert(path != nil, @"Path was nil!"); + + NSString *baseKey = serverCacheKey(path); + + // HACK to make sure iter is freed now to avoid race conditions (if self.db is deleted before iter, you get an access violation). + @autoreleasepool { + APLevelDBIterator* iter = [APLevelDBIterator iteratorWithLevelDB:self.serverCacheDB]; + + [iter seekToKey:baseKey]; + if (iter.key == nil || ![iter.key hasPrefix:baseKey]) { + // No data. + return nil; + } else { + return [self internalNestedDataFromIterator:iter andKeyPrefix:baseKey]; + } + } +} + +- (id) internalNestedDataFromIterator:(APLevelDBIterator*)iterator andKeyPrefix:(NSString*)prefix { + NSString* key = iterator.key; + + if ([key isEqualToString:prefix]) { + id result = [self deserializePrimitive:iterator.valueAsData]; + [iterator nextKey]; + return result; + } else { + NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; + while (key != nil && [key hasPrefix:prefix]) { + NSString *relativePath = [key substringFromIndex:prefix.length]; + NSArray* pathPieces = [relativePath componentsSeparatedByString:@"/"]; + assert(pathPieces.count > 0); + NSString *childName = pathPieces[0]; + NSString *childPath = [NSString stringWithFormat:@"%@%@/", prefix, childName]; + id childValue = [self internalNestedDataFromIterator:iterator andKeyPrefix:childPath]; + [dict setValue:childValue forKey:childName]; + + key = iterator.key; + } + return dict; + } +} + + +- (NSData*) serializePrimitive:(id)value { + // HACK: The built-in serialization only works on dicts and arrays. So we create an array and then strip off + // the leading / trailing byte (the [ and ]). + NSError *error = nil; + NSData *data = [NSJSONSerialization dataWithJSONObject:@[value] options:0 error:&error]; + NSAssert(data, @"Failed to serialize primitive: %@", error); + + return [data subdataWithRange:NSMakeRange(1, data.length - 2)]; +} + +- (id)fixDoubleParsing:(id)value __attribute__((no_sanitize("float-cast-overflow"))) { + // The parser for double values in JSONSerialization at the root takes some short-cuts and delivers wrong results + // (wrong rounding) for some double values, including 2.47. Because we use the exact bytes for hashing on the server + // this will lead to hash mismatches. The parser of NSNumber seems to be more in line with what the server expects, + // so we use that here + if ([value isKindOfClass:[NSNumber class]]) { + CFNumberType type = CFNumberGetType((CFNumberRef)value); + if (type == kCFNumberDoubleType || type == kCFNumberFloatType) { + // The NSJSON parser returns all numbers as double values, even those that contain no exponent. To + // make sure that the String conversion below doesn't unexpectedly reduce precision, we make sure that + // our number is indeed not an integer. + if ((double)(int64_t)[value doubleValue] != [value doubleValue]) { + NSString *doubleString = [value stringValue]; + return [NSNumber numberWithDouble:[doubleString doubleValue]]; + } else { + return [NSNumber numberWithLongLong:[value longLongValue]]; + } + } + } + return value; +} + +- (id) deserializePrimitive:(NSData*)data { + NSError *error = nil; + id result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error]; + if (result != nil) { + return [self fixDoubleParsing:result]; + } else { + if (error.code == kFNanFailureCode) { + FFWarn(@"I-RDB076034", @"Failed to load primitive %@, likely because doubles where out of range (Error: %@)", + [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding], error); + return [NSNull null]; + } else { + [NSException raise:NSInternalInconsistencyException format:@"Failed to deserialiaze primitive: %@", error]; + return nil; + } + } + +} + ++ (void)ensureDir:(NSString*)path markAsDoNotBackup:(BOOL)markAsDoNotBackup { + NSError* error; + BOOL success = [[NSFileManager defaultManager] createDirectoryAtPath:path + withIntermediateDirectories:YES + attributes:nil + error:&error]; + if (!success) { + @throw [NSException exceptionWithName:@"FailedToCreatePersistenceDir" reason:@"Failed to create persistence directory." userInfo:@{ @"path": path }]; + } + + if (markAsDoNotBackup) { + NSURL *firebaseDirURL = [NSURL fileURLWithPath:path]; + success = [firebaseDirURL setResourceValue:@YES + forKey:NSURLIsExcludedFromBackupKey + error:&error]; + if (!success) { + FFWarn(@"I-RDB076035", @"Failed to mark firebase database folder as do not backup: %@", error); + [NSException raise:@"Error marking as do not backup" format:@"Failed to mark folder %@ as do not backup", firebaseDirURL]; + } + } +} + + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FPendingPut.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FPendingPut.h new file mode 100644 index 00000000..0d8de553 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FPendingPut.h @@ -0,0 +1,55 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FPath.h" + +// These are all legacy classes and are used to migrate older persistence data base to newer ones +// These classes should not be used in newer code + +@interface FPendingPut : NSObject + +@property (nonatomic, strong) FPath* path; +@property (nonatomic, strong) id data; +@property (nonatomic, strong) id priority; + +- (id) initWithPath:(FPath*)aPath andData:(id)aData andPriority:aPriority; +- (void)encodeWithCoder:(NSCoder *)aCoder; +- (id)initWithCoder:(NSCoder *)aDecoder; +@end + + +@interface FPendingPutPriority : NSObject + +@property (nonatomic, strong) FPath* path; +@property (nonatomic, strong) id priority; + +- (id) initWithPath:(FPath*)aPath andPriority:(id)aPriority; +- (void)encodeWithCoder:(NSCoder *)aCoder; +- (id)initWithCoder:(NSCoder *)aDecoder; + +@end + + +@interface FPendingUpdate : NSObject + +@property (nonatomic, strong) FPath* path; +@property (nonatomic, strong) NSDictionary* data; + +- (id) initWithPath:(FPath*)aPath andData:(NSDictionary*)aData; +- (void)encodeWithCoder:(NSCoder *)aCoder; +- (id)initWithCoder:(NSCoder *)aDecoder; +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FPendingPut.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FPendingPut.m new file mode 100644 index 00000000..12be8255 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FPendingPut.m @@ -0,0 +1,112 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FPendingPut.h" + +@implementation FPendingPut + +@synthesize path; +@synthesize data; + +- (id) initWithPath:(FPath *)aPath andData:(id)aData andPriority:(id)aPriority { + self = [super init]; + if (self) { + self.path = aPath; + self.data = aData; + self.priority = aPriority; + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:[self.path description] forKey:@"path"]; + [aCoder encodeObject:self.data forKey:@"data"]; + [aCoder encodeObject:self.priority forKey:@"priority"]; +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + self = [super init]; + if(self) { + self.path = [[FPath alloc] initWith:[aDecoder decodeObjectForKey:@"path"]]; + self.data = [aDecoder decodeObjectForKey:@"data"]; + self.priority = [aDecoder decodeObjectForKey:@"priority"]; + } + return self; +} + +@end + + +@implementation FPendingPutPriority + +@synthesize path; +@synthesize priority; + +- (id) initWithPath:(FPath *)aPath andPriority:(id)aPriority { + self = [super init]; + if (self) { + self.path = aPath; + self.priority = aPriority; + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:[self.path description] forKey:@"path"]; + [aCoder encodeObject:self.priority forKey:@"priority"]; +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + self = [super init]; + if(self) { + self.path = [[FPath alloc] initWith:[aDecoder decodeObjectForKey:@"path"]]; + self.priority = [aDecoder decodeObjectForKey:@"priority"]; + } + return self; +} + +@end + + +@implementation FPendingUpdate + +@synthesize path; +@synthesize data; + +- (id) initWithPath:(FPath *)aPath andData:(id)aData { + self = [super init]; + if (self) { + self.path = aPath; + self.data = aData; + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:[self.path description] forKey:@"path"]; + [aCoder encodeObject:self.data forKey:@"data"]; +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + self = [super init]; + if(self) { + self.path = [[FPath alloc] initWith:[aDecoder decodeObjectForKey:@"path"]]; + self.data = [aDecoder decodeObjectForKey:@"data"]; + } + return self; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FPersistenceManager.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FPersistenceManager.h new file mode 100644 index 00000000..a3688b30 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FPersistenceManager.h @@ -0,0 +1,52 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import "FNode.h" +#import "FCompoundWrite.h" +#import "FQuerySpec.h" +#import "FRepoInfo.h" +#import "FStorageEngine.h" +#import "FCachePolicy.h" +#import "FCacheNode.h" + +@interface FPersistenceManager : NSObject + +- (id)initWithStorageEngine:(id)storageEngine cachePolicy:(id)cachePolicy; +- (void)close; + +- (void)saveUserOverwrite:(id)node atPath:(FPath *)path writeId:(NSUInteger)writeId; +- (void)saveUserMerge:(FCompoundWrite *)merge atPath:(FPath *)path writeId:(NSUInteger)writeId; +- (void)removeUserWrite:(NSUInteger)writeId; +- (void)removeAllUserWrites; +- (NSArray *)userWrites; + +- (FCacheNode *)serverCacheForQuery:(FQuerySpec *)spec; +- (void)updateServerCacheWithNode:(id)node forQuery:(FQuerySpec *)spec; +- (void)updateServerCacheWithMerge:(FCompoundWrite *)merge atPath:(FPath *)path; + +- (void)applyUserWrite:(id)write toServerCacheAtPath:(FPath *)path; +- (void)applyUserMerge:(FCompoundWrite *)merge toServerCacheAtPath:(FPath *)path; + +- (void)setQueryComplete:(FQuerySpec *)spec; +- (void)setQueryActive:(FQuerySpec *)spec; +- (void)setQueryInactive:(FQuerySpec *)spec; + +- (void)setTrackedQueryKeys:(NSSet *)keys forQuery:(FQuerySpec *)query; +- (void)updateTrackedQueryKeysWithAddedKeys:(NSSet *)added removedKeys:(NSSet *)removed forQuery:(FQuerySpec *)query; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FPersistenceManager.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FPersistenceManager.m new file mode 100644 index 00000000..b488f3ef --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FPersistenceManager.m @@ -0,0 +1,191 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FPersistenceManager.h" +#import "FLevelDBStorageEngine.h" +#import "FCacheNode.h" +#import "FIndexedNode.h" +#import "FTrackedQueryManager.h" +#import "FTrackedQuery.h" +#import "FUtilities.h" +#import "FPruneForest.h" +#import "FClock.h" + +@interface FPersistenceManager () + +@property (nonatomic, strong) id storageEngine; +@property (nonatomic, strong) id cachePolicy; +@property (nonatomic, strong) FTrackedQueryManager *trackedQueryManager; +@property (nonatomic) NSUInteger serverCacheUpdatesSinceLastPruneCheck; + +@end + +@implementation FPersistenceManager + +- (id)initWithStorageEngine:(id)storageEngine cachePolicy:(id)cachePolicy { + self = [super init]; + if (self != nil) { + self->_storageEngine = storageEngine; + self->_cachePolicy = cachePolicy; + self->_trackedQueryManager = [[FTrackedQueryManager alloc] initWithStorageEngine:self.storageEngine + clock:[FSystemClock clock]]; + } + return self; +} + +- (void)close { + [self.storageEngine close]; + self.storageEngine = nil; + self.trackedQueryManager = nil; +} + +- (void)saveUserOverwrite:(id)node atPath:(FPath *)path writeId:(NSUInteger)writeId { + [self.storageEngine saveUserOverwrite:node atPath:path writeId:writeId]; +} + +- (void)saveUserMerge:(FCompoundWrite *)merge atPath:(FPath *)path writeId:(NSUInteger)writeId { + [self.storageEngine saveUserMerge:merge atPath:path writeId:writeId]; +} + +- (void)removeUserWrite:(NSUInteger)writeId { + [self.storageEngine removeUserWrite:writeId]; +} + +- (void)removeAllUserWrites { + [self.storageEngine removeAllUserWrites]; +} + +- (NSArray *)userWrites { + return [self.storageEngine userWrites]; +} + +- (FCacheNode *)serverCacheForQuery:(FQuerySpec *)query { + NSSet *trackedKeys; + BOOL complete; + // TODO[offline]: Should we use trackedKeys to find out if this location is a child of a complete query? + if ([self.trackedQueryManager isQueryComplete:query]) { + complete = YES; + FTrackedQuery *trackedQuery = [self.trackedQueryManager findTrackedQuery:query]; + if (!query.loadsAllData && trackedQuery.isComplete) { + trackedKeys = [self.storageEngine trackedQueryKeysForQuery:trackedQuery.queryId]; + } else { + trackedKeys = nil; + } + } else { + complete = NO; + trackedKeys = [self.trackedQueryManager knownCompleteChildrenAtPath:query.path]; + } + + id node; + if (trackedKeys != nil) { + node = [self.storageEngine serverCacheForKeys:trackedKeys atPath:query.path]; + } else { + node = [self.storageEngine serverCacheAtPath:query.path]; + } + + FIndexedNode *indexedNode = [FIndexedNode indexedNodeWithNode:node index:query.index]; + return [[FCacheNode alloc] initWithIndexedNode:indexedNode isFullyInitialized:complete isFiltered:(trackedKeys != nil)]; +} + +- (void)updateServerCacheWithNode:(id)node forQuery:(FQuerySpec *)query { + BOOL merge = !query.loadsAllData; + [self.storageEngine updateServerCache:node atPath:query.path merge:merge]; + [self setQueryComplete:query]; + [self doPruneCheckAfterServerUpdate]; +} + +- (void)updateServerCacheWithMerge:(FCompoundWrite *)merge atPath:(FPath *)path { + [self.storageEngine updateServerCacheWithMerge:merge atPath:path]; + [self doPruneCheckAfterServerUpdate]; +} + +- (void)applyUserMerge:(FCompoundWrite *)merge toServerCacheAtPath:(FPath *)path { + // TODO[offline]: rework this to be more efficient + [merge enumerateWrites:^(FPath *relativePath, id node, BOOL *stop) { + [self applyUserWrite:node toServerCacheAtPath:[path child:relativePath]]; + }]; +} + +- (void)applyUserWrite:(id)write toServerCacheAtPath:(FPath *)path { + // This is a hack to guess whether we already cached this because we got a server data update for this + // write via an existing active default query. If we didn't, then we'll manually cache this and add a + // tracked query to mark it complete and keep it cached. + // Unfortunately this is just a guess and it's possible that we *did* get an update (e.g. via a filtered + // query) and by overwriting the cache here, we'll actually store an incorrect value (e.g. in the case + // that we wrote a ServerValue.TIMESTAMP and the server resolved it to a different value). + // TODO[offline]: Consider reworking. + if (![self.trackedQueryManager hasActiveDefaultQueryAtPath:path]) { + [self.storageEngine updateServerCache:write atPath:path merge:NO]; + [self.trackedQueryManager ensureCompleteTrackedQueryAtPath:path]; + } +} + +- (void)setQueryComplete:(FQuerySpec *)query { + if (query.loadsAllData) { + [self.trackedQueryManager setQueriesCompleteAtPath:query.path]; + } else { + [self.trackedQueryManager setQueryComplete:query]; + } +} + +- (void)setQueryActive:(FQuerySpec *)spec { + [self.trackedQueryManager setQueryActive:spec]; +} + +- (void)setQueryInactive:(FQuerySpec *)spec { + [self.trackedQueryManager setQueryInactive:spec]; +} + +- (void)doPruneCheckAfterServerUpdate { + self.serverCacheUpdatesSinceLastPruneCheck++; + if ([self.cachePolicy shouldCheckCacheSize:self.serverCacheUpdatesSinceLastPruneCheck]) { + FFDebug(@"I-RDB078001", @"Reached prune check threshold. Checking..."); + NSDate *date = [NSDate date]; + self.serverCacheUpdatesSinceLastPruneCheck = 0; + BOOL canPrune = YES; + NSUInteger cacheSize = [self.storageEngine serverCacheEstimatedSizeInBytes]; + FFDebug(@"I-RDB078002", @"Server cache size: %lu", (unsigned long)cacheSize); + while (canPrune && [self.cachePolicy shouldPruneCacheWithSize:cacheSize + numberOfTrackedQueries:self.trackedQueryManager.numberOfPrunableQueries]) { + FPruneForest *pruneForest = [self.trackedQueryManager pruneOldQueries:self.cachePolicy]; + if (pruneForest.prunesAnything) { + [self.storageEngine pruneCache:pruneForest atPath:[FPath empty]]; + } else { + canPrune = NO; + } + cacheSize = [self.storageEngine serverCacheEstimatedSizeInBytes]; + FFDebug(@"I-RDB078003", @"Cache size after pruning: %lu", (unsigned long)cacheSize); + } + FFDebug(@"I-RDB078004", @"Pruning round took %fms", [date timeIntervalSinceNow]*-1000); + } +} + +- (void)setTrackedQueryKeys:(NSSet *)keys forQuery:(FQuerySpec *)query { + NSAssert(!query.loadsAllData, @"We should only track keys for filtered queries"); + FTrackedQuery *trackedQuery = [self.trackedQueryManager findTrackedQuery:query]; + NSAssert(trackedQuery.isActive, @"We only expect tracked keys for currently-active queries."); + [self.storageEngine setTrackedQueryKeys:keys forQueryId:trackedQuery.queryId]; +} + +- (void)updateTrackedQueryKeysWithAddedKeys:(NSSet *)added removedKeys:(NSSet *)removed forQuery:(FQuerySpec *)query { + NSAssert(!query.loadsAllData, @"We should only track keys for filtered queries"); + FTrackedQuery *trackedQuery = [self.trackedQueryManager findTrackedQuery:query]; + NSAssert(trackedQuery.isActive, @"We only expect tracked keys for currently-active queries."); + [self.storageEngine updateTrackedQueryKeysWithAddedKeys:added removedKeys:removed forQueryId:trackedQuery.queryId]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FPruneForest.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FPruneForest.h new file mode 100644 index 00000000..9e77217a --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FPruneForest.h @@ -0,0 +1,38 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class FPath; + +@interface FPruneForest : NSObject + ++ (FPruneForest *)empty; + +- (BOOL)prunesAnything; +- (BOOL)shouldPruneUnkeptDescendantsAtPath:(FPath *)path; +- (BOOL)shouldKeepPath:(FPath *)path; +- (BOOL)affectsPath:(FPath *)path; +- (FPruneForest *)child:(NSString *)childKey; +- (FPruneForest *)childAtPath:(FPath *)childKey; +- (FPruneForest *)prunePath:(FPath *)path; +- (FPruneForest *)keepPath:(FPath *)path; +- (FPruneForest *)keepAll:(NSSet *)children atPath:(FPath *)path; +- (FPruneForest *)pruneAll:(NSSet *)children atPath:(FPath *)path; + +- (void)enumarateKeptNodesUsingBlock:(void (^)(FPath *path))block; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FPruneForest.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FPruneForest.m new file mode 100644 index 00000000..ae5ce91b --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FPruneForest.m @@ -0,0 +1,177 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FPruneForest.h" + +#import "FImmutableTree.h" + +@interface FPruneForest () + +@property (nonatomic, strong) FImmutableTree *pruneForest; + +@end + +@implementation FPruneForest + +static BOOL (^kFPrunePredicate)(id) = ^BOOL(NSNumber *pruneValue) { + return [pruneValue boolValue]; +}; + +static BOOL (^kFKeepPredicate)(id) = ^BOOL(NSNumber *pruneValue) { + return ![pruneValue boolValue]; +}; + + ++ (FImmutableTree *)pruneTree { + static dispatch_once_t onceToken; + static FImmutableTree *pruneTree; + dispatch_once(&onceToken, ^{ + pruneTree = [[FImmutableTree alloc] initWithValue:@YES]; + }); + return pruneTree; +} + ++ (FImmutableTree *)keepTree { + static dispatch_once_t onceToken; + static FImmutableTree *keepTree; + dispatch_once(&onceToken, ^{ + keepTree = [[FImmutableTree alloc] initWithValue:@NO]; + }); + return keepTree; +} + +- (id) initWithForest:(FImmutableTree *)tree { + self = [super init]; + if (self != nil) { + self->_pruneForest = tree; + } + return self; +} + ++ (FPruneForest *)empty { + static dispatch_once_t onceToken; + static FPruneForest *forest; + dispatch_once(&onceToken, ^{ + forest = [[FPruneForest alloc] initWithForest:[FImmutableTree empty]]; + }); + return forest; +} + +- (BOOL)prunesAnything { + return [self.pruneForest containsValueMatching:kFPrunePredicate]; +} + +- (BOOL)shouldPruneUnkeptDescendantsAtPath:(FPath *)path { + NSNumber *shouldPrune = [self.pruneForest leafMostValueOnPath:path]; + return shouldPrune != nil && [shouldPrune boolValue]; +} + +- (BOOL)shouldKeepPath:(FPath *)path { + NSNumber *shouldPrune = [self.pruneForest leafMostValueOnPath:path]; + return shouldPrune != nil && ![shouldPrune boolValue]; +} + +- (BOOL)affectsPath:(FPath *)path { + return [self.pruneForest rootMostValueOnPath:path] != nil || ![[self.pruneForest subtreeAtPath:path] isEmpty]; +} + +- (FPruneForest *)child:(NSString *)childKey { + FImmutableTree *childPruneForest = [self.pruneForest.children get:childKey]; + if (childPruneForest == nil) { + if (self.pruneForest.value != nil) { + childPruneForest = [self.pruneForest.value boolValue] ? [FPruneForest pruneTree] : [FPruneForest keepTree]; + } else { + childPruneForest = [FImmutableTree empty]; + } + } else { + if (childPruneForest.value == nil && self.pruneForest.value != nil) { + childPruneForest = [childPruneForest setValue:self.pruneForest.value atPath:[FPath empty]]; + } + } + return [[FPruneForest alloc] initWithForest:childPruneForest]; +} + +- (FPruneForest *)childAtPath:(FPath *)path { + if (path.isEmpty) { + return self; + } else { + return [[self child:path.getFront] childAtPath:[path popFront]]; + } +} + +- (FPruneForest *)prunePath:(FPath *)path { + if ([self.pruneForest rootMostValueOnPath:path matching:kFKeepPredicate]) { + [NSException raise:NSInvalidArgumentException format:@"Can't prune path that was kept previously!"]; + } + if ([self.pruneForest rootMostValueOnPath:path matching:kFPrunePredicate]) { + // This path will already be pruned + return self; + } else { + FImmutableTree *newPruneForest = [self.pruneForest setTree:[FPruneForest pruneTree] atPath:path]; + return [[FPruneForest alloc] initWithForest:newPruneForest]; + } +} + +- (FPruneForest *)keepPath:(FPath *)path { + if ([self.pruneForest rootMostValueOnPath:path matching:kFKeepPredicate]) { + // This path will already be kept + return self; + } else { + FImmutableTree *newPruneForest = [self.pruneForest setTree:[FPruneForest keepTree] atPath:path]; + return [[FPruneForest alloc] initWithForest:newPruneForest]; + } +} + +- (FPruneForest *)keepAll:(NSSet *)children atPath:(FPath *)path { + if ([self.pruneForest rootMostValueOnPath:path matching:kFKeepPredicate]) { + // This path will already be kept + return self; + } else { + return [self setPruneValue:[FPruneForest keepTree] forAll:children atPath:path]; + } +} + +- (FPruneForest *)pruneAll:(NSSet *)children atPath:(FPath *)path { + if ([self.pruneForest rootMostValueOnPath:path matching:kFKeepPredicate]) { + [NSException raise:NSInvalidArgumentException format:@"Can't prune path that was kept previously!"]; + } + if ([self.pruneForest rootMostValueOnPath:path matching:kFPrunePredicate]) { + // This path will already be pruned + return self; + } else { + return [self setPruneValue:[FPruneForest pruneTree] forAll:children atPath:path]; + } +} + +- (FPruneForest *)setPruneValue:(FImmutableTree *)pruneValue forAll:(NSSet *)children atPath:(FPath *)path { + FImmutableTree *subtree = [self.pruneForest subtreeAtPath:path]; + __block FImmutableSortedDictionary *childrenDictionary = subtree.children; + [children enumerateObjectsUsingBlock:^(NSString *childKey, BOOL *stop) { + childrenDictionary = [childrenDictionary insertKey:childKey withValue:pruneValue]; + }]; + FImmutableTree *newSubtree = [[FImmutableTree alloc] initWithValue:subtree.value children:childrenDictionary]; + return [[FPruneForest alloc] initWithForest:[self.pruneForest setTree:newSubtree atPath:path]]; +} + +- (void)enumarateKeptNodesUsingBlock:(void (^)(FPath *))block { + [self.pruneForest forEach:^(FPath *path, id value) { + if (value != nil && ![value boolValue]) { + block(path); + } + }]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FStorageEngine.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FStorageEngine.h new file mode 100644 index 00000000..4f168e77 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FStorageEngine.h @@ -0,0 +1,53 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@protocol FNode; +@class FPruneForest; +@class FPath; +@class FCompoundWrite; +@class FQuerySpec; +@class FTrackedQuery; + +@protocol FStorageEngine + +- (void)close; + +- (void)saveUserOverwrite:(id)node atPath:(FPath *)path writeId:(NSUInteger)writeId; +- (void)saveUserMerge:(FCompoundWrite *)merge atPath:(FPath *)path writeId:(NSUInteger)writeId; +- (void)removeUserWrite:(NSUInteger)writeId; +- (void)removeAllUserWrites; +- (NSArray *)userWrites; + +- (id)serverCacheAtPath:(FPath *)path; +- (id)serverCacheForKeys:(NSSet *)keys atPath:(FPath *)path; +- (void)updateServerCache:(id)node atPath:(FPath *)path merge:(BOOL)merge; +- (void)updateServerCacheWithMerge:(FCompoundWrite *)merge atPath:(FPath *)path; +- (NSUInteger)serverCacheEstimatedSizeInBytes; + +- (void)pruneCache:(FPruneForest *)pruneForest atPath:(FPath *)path; + +- (NSArray *)loadTrackedQueries; +- (void)removeTrackedQuery:(NSUInteger)queryId; +- (void)saveTrackedQuery:(FTrackedQuery *)query; + +- (void)setTrackedQueryKeys:(NSSet *)keys forQueryId:(NSUInteger)queryId; +- (void)updateTrackedQueryKeysWithAddedKeys:(NSSet *)added removedKeys:(NSSet *)removed forQueryId:(NSUInteger)queryId; +- (NSSet *)trackedQueryKeysForQuery:(NSUInteger)queryId; + + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FTrackedQuery.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FTrackedQuery.h new file mode 100644 index 00000000..7bc8ef14 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FTrackedQuery.h @@ -0,0 +1,40 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class FQuerySpec; + +@interface FTrackedQuery : NSObject + +@property (nonatomic, readonly) NSUInteger queryId; +@property (nonatomic, strong, readonly) FQuerySpec *query; +@property (nonatomic, readonly) NSTimeInterval lastUse; +@property (nonatomic, readonly) BOOL isComplete; +@property (nonatomic, readonly) BOOL isActive; + +- (id)initWithId:(NSUInteger)queryId query:(FQuerySpec *)query lastUse:(NSTimeInterval)lastUse isActive:(BOOL)isActive; +- (id)initWithId:(NSUInteger)queryId + query:(FQuerySpec *)query + lastUse:(NSTimeInterval)lastUse + isActive:(BOOL)isActive + isComplete:(BOOL)isComplete; + +- (FTrackedQuery *)updateLastUse:(NSTimeInterval)lastUse; +- (FTrackedQuery *)setComplete; +- (FTrackedQuery *)setActiveState:(BOOL)isActive; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FTrackedQuery.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FTrackedQuery.m new file mode 100644 index 00000000..17208058 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FTrackedQuery.m @@ -0,0 +1,102 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FTrackedQuery.h" + +#import "FQuerySpec.h" + +@interface FTrackedQuery () + +@property (nonatomic, readwrite) NSUInteger queryId; +@property (nonatomic, strong, readwrite) FQuerySpec *query; +@property (nonatomic, readwrite) NSTimeInterval lastUse; +@property (nonatomic, readwrite) BOOL isComplete; +@property (nonatomic, readwrite) BOOL isActive; + +@end + + +@implementation FTrackedQuery + +- (id)initWithId:(NSUInteger)queryId + query:(FQuerySpec *)query + lastUse:(NSTimeInterval)lastUse + isActive:(BOOL)isActive + isComplete:(BOOL)isComplete { + self = [super init]; + if (self != nil) { + self->_queryId = queryId; + self->_query = query; + self->_lastUse = lastUse; + self->_isComplete = isComplete; + self->_isActive = isActive; + } + return self; +} + +- (id)initWithId:(NSUInteger)queryId query:(FQuerySpec *)query lastUse:(NSTimeInterval)lastUse isActive:(BOOL)isActive { + return [self initWithId:queryId query:query lastUse:lastUse isActive:isActive isComplete:NO]; +} + +- (FTrackedQuery *)updateLastUse:(NSTimeInterval)lastUse { + return [[FTrackedQuery alloc] initWithId:self.queryId + query:self.query + lastUse:lastUse + isActive:self.isActive + isComplete:self.isComplete]; +} + +- (FTrackedQuery *)setComplete { + return [[FTrackedQuery alloc] initWithId:self.queryId + query:self.query + lastUse:self.lastUse + isActive:self.isActive + isComplete:YES]; +} + +- (FTrackedQuery *)setActiveState:(BOOL)isActive { + return [[FTrackedQuery alloc] initWithId:self.queryId + query:self.query + lastUse:self.lastUse + isActive:isActive + isComplete:self.isComplete]; +} + +- (BOOL)isEqual:(id)object { + if (![object isKindOfClass:[FTrackedQuery class]]) { + return NO; + } + FTrackedQuery *other = (FTrackedQuery *)object; + if (self.queryId != other.queryId) return NO; + if (self.query != other.query && ![self.query isEqual:other.query]) return NO; + if (self.lastUse != other.lastUse) return NO; + if (self.isComplete != other.isComplete) return NO; + if (self.isActive != other.isActive) return NO; + + return YES; +} + +- (NSUInteger)hash { + NSUInteger hash = self.queryId; + hash = hash * 31 + self.query.hash; + hash = hash * 31 + (self.isActive ? 1 : 0); + hash = hash * 31 + (NSUInteger)self.lastUse; + hash = hash * 31 + (self.isComplete ? 1 : 0); + hash = hash * 31 + (self.isActive ? 1 : 0); + return hash; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FTrackedQueryManager.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FTrackedQueryManager.h new file mode 100644 index 00000000..ba2631b9 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FTrackedQueryManager.h @@ -0,0 +1,51 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@protocol FStorageEngine; +@protocol FClock; +@protocol FCachePolicy; +@class FQuerySpec; +@class FPath; +@class FTrackedQuery; +@class FPruneForest; + +@interface FTrackedQueryManager : NSObject + +- (id)initWithStorageEngine:(id)storageEngine clock:(id)clock; + +- (FTrackedQuery *)findTrackedQuery:(FQuerySpec *)query; + +- (BOOL)isQueryComplete:(FQuerySpec *)query; + +- (void)removeTrackedQuery:(FQuerySpec *)query; +- (void)setQueryComplete:(FQuerySpec *)query; +- (void)setQueriesCompleteAtPath:(FPath *)path; +- (void)setQueryActive:(FQuerySpec *)query; +- (void)setQueryInactive:(FQuerySpec *)query; + +- (BOOL)hasActiveDefaultQueryAtPath:(FPath *)path; +- (void)ensureCompleteTrackedQueryAtPath:(FPath *)path; + +- (FPruneForest *)pruneOldQueries:(id)cachePolicy; +- (NSUInteger)numberOfPrunableQueries; +- (NSSet *)knownCompleteChildrenAtPath:(FPath *)path; + +// For testing +- (void)verifyCache; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FTrackedQueryManager.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FTrackedQueryManager.m new file mode 100644 index 00000000..9176f255 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Persistence/FTrackedQueryManager.m @@ -0,0 +1,322 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FTrackedQueryManager.h" +#import "FImmutableTree.h" +#import "FLevelDBStorageEngine.h" +#import "FUtilities.h" +#import "FTrackedQuery.h" +#import "FPruneForest.h" +#import "FClock.h" +#import "FUtilities.h" +#import "FCachePolicy.h" + +@interface FTrackedQueryManager () + +@property (nonatomic, strong) FImmutableTree *trackedQueryTree; +@property (nonatomic, strong) id storageEngine; +@property (nonatomic, strong) id clock; +@property (nonatomic) NSUInteger currentQueryId; + +@end + +@implementation FTrackedQueryManager + +- (id)initWithStorageEngine:(id)storageEngine clock:(id)clock { + self = [super init]; + if (self != nil) { + self->_storageEngine = storageEngine; + self->_clock = clock; + self->_trackedQueryTree = [FImmutableTree empty]; + + NSTimeInterval lastUse = [clock currentTime]; + + NSArray *trackedQueries = [self.storageEngine loadTrackedQueries]; + [trackedQueries enumerateObjectsUsingBlock:^(FTrackedQuery *trackedQuery, NSUInteger idx, BOOL *stop) { + self.currentQueryId = MAX(trackedQuery.queryId + 1, self.currentQueryId); + if (trackedQuery.isActive) { + trackedQuery = [[trackedQuery setActiveState:NO] updateLastUse:lastUse]; + FFDebug(@"I-RDB081001", @"Setting active query %lu from previous app start inactive", (unsigned long)trackedQuery.queryId); + [self.storageEngine saveTrackedQuery:trackedQuery]; + } + [self cacheTrackedQuery:trackedQuery]; + }]; + } + return self; +} + ++ (void)assertValidTrackedQuery:(FQuerySpec *)query { + NSAssert(!query.loadsAllData || query.isDefault, @"Can't have tracked non-default query that loads all data"); +} + ++ (FQuerySpec *)normalizeQuery:(FQuerySpec *)query { + return query.loadsAllData ? [FQuerySpec defaultQueryAtPath:query.path] : query; +} + +- (FTrackedQuery *)findTrackedQuery:(FQuerySpec *)query { + query = [FTrackedQueryManager normalizeQuery:query]; + NSDictionary *set = [self.trackedQueryTree valueAtPath:query.path]; + return set[query.params]; +} + +- (void)removeTrackedQuery:(FQuerySpec *)query { + query = [FTrackedQueryManager normalizeQuery:query]; + FTrackedQuery *trackedQuery = [self findTrackedQuery:query]; + NSAssert(trackedQuery, @"Tracked query must exist to be removed!"); + + [self.storageEngine removeTrackedQuery:trackedQuery.queryId]; + NSMutableDictionary *trackedQueries = [self.trackedQueryTree valueAtPath:query.path]; + [trackedQueries removeObjectForKey:query.params]; +} + +- (void)setQueryActive:(FQuerySpec *)query { + [self setQueryActive:YES forQuery:query]; +} + +- (void)setQueryInactive:(FQuerySpec *)query { + [self setQueryActive:NO forQuery:query]; +} + +- (void)setQueryActive:(BOOL)isActive forQuery:(FQuerySpec *)query { + query = [FTrackedQueryManager normalizeQuery:query]; + FTrackedQuery *trackedQuery = [self findTrackedQuery:query]; + + // Regardless of whether it's now active or no langer active, we update the lastUse time + NSTimeInterval lastUse = [self.clock currentTime]; + if (trackedQuery != nil) { + trackedQuery = [[trackedQuery updateLastUse:lastUse] setActiveState:isActive]; + [self.storageEngine saveTrackedQuery:trackedQuery]; + } else { + NSAssert(isActive, @"If we're setting the query to inactive, we should already be tracking it!"); + trackedQuery = [[FTrackedQuery alloc] initWithId:self.currentQueryId++ + query:query + lastUse:lastUse + isActive:isActive]; + [self.storageEngine saveTrackedQuery:trackedQuery]; + } + + [self cacheTrackedQuery:trackedQuery]; +} + +- (void)setQueryComplete:(FQuerySpec *)query { + query = [FTrackedQueryManager normalizeQuery:query]; + FTrackedQuery *trackedQuery = [self findTrackedQuery:query]; + if (!trackedQuery) { + // We might have removed a query and pruned it before we got the complete message from the server... + FFWarn(@"I-RDB081002", @"Trying to set a query complete that is not tracked!"); + } else if (!trackedQuery.isComplete) { + trackedQuery = [trackedQuery setComplete]; + [self.storageEngine saveTrackedQuery:trackedQuery]; + [self cacheTrackedQuery:trackedQuery]; + } else { + // Nothing to do, already marked complete + } +} + +- (void)setQueriesCompleteAtPath:(FPath *)path { + [[self.trackedQueryTree subtreeAtPath:path] forEach:^(FPath *childPath, NSDictionary *trackedQueries) { + [trackedQueries enumerateKeysAndObjectsUsingBlock:^(FQueryParams *parms, FTrackedQuery *trackedQuery, BOOL *stop) { + if (!trackedQuery.isComplete) { + FTrackedQuery *newTrackedQuery = [trackedQuery setComplete]; + [self.storageEngine saveTrackedQuery:newTrackedQuery]; + [self cacheTrackedQuery:newTrackedQuery]; + } + }]; + }]; +} + +- (BOOL)isQueryComplete:(FQuerySpec *)query { + if ([self isIncludedInDefaultCompleteQuery:query]) { + return YES; + } else if (query.loadsAllData) { + // We didn't find a default complete query, so must not be complete. + return NO; + } else { + NSDictionary *trackedQueries = [self.trackedQueryTree valueAtPath:query.path]; + return [trackedQueries[query.params] isComplete]; + } +} + +- (BOOL)hasActiveDefaultQueryAtPath:(FPath *)path { + return [self.trackedQueryTree rootMostValueOnPath:path matching:^BOOL(NSDictionary *trackedQueries) { + return [trackedQueries[[FQueryParams defaultInstance]] isActive]; + }] != nil; +} + +- (void)ensureCompleteTrackedQueryAtPath:(FPath *)path { + FQuerySpec *query = [FQuerySpec defaultQueryAtPath:path]; + if (![self isIncludedInDefaultCompleteQuery:query]) { + FTrackedQuery *trackedQuery = [self findTrackedQuery:query]; + if (trackedQuery == nil) { + trackedQuery = [[FTrackedQuery alloc] initWithId:self.currentQueryId++ + query:query + lastUse:[self.clock currentTime] + isActive:NO + isComplete:YES]; + } else { + NSAssert(!trackedQuery.isComplete, @"This should have been handled above!"); + trackedQuery = [trackedQuery setComplete]; + } + [self.storageEngine saveTrackedQuery:trackedQuery]; + [self cacheTrackedQuery:trackedQuery]; + } +} + +- (BOOL)isIncludedInDefaultCompleteQuery:(FQuerySpec *)query { + return [self.trackedQueryTree findRootMostMatchingPath:query.path predicate:^BOOL(NSDictionary *trackedQueries) { + return [trackedQueries[[FQueryParams defaultInstance]] isComplete]; + }] != nil; +} + +- (void)cacheTrackedQuery:(FTrackedQuery *)query { + [FTrackedQueryManager assertValidTrackedQuery:query.query]; + NSMutableDictionary *trackedDict = [self.trackedQueryTree valueAtPath:query.query.path]; + if (trackedDict == nil) { + trackedDict = [NSMutableDictionary dictionary]; + self.trackedQueryTree = [self.trackedQueryTree setValue:trackedDict atPath:query.query.path]; + } + trackedDict[query.query.params] = query; +} + +- (NSUInteger) numberOfQueriesToPrune:(id)cachePolicy prunableCount:(NSUInteger)numPrunable { + NSUInteger numPercent = (NSUInteger)ceilf(numPrunable * [cachePolicy percentOfQueriesToPruneAtOnce]); + NSUInteger maxToKeep = [cachePolicy maxNumberOfQueriesToKeep]; + NSUInteger numMax = (numPrunable > maxToKeep) ? numPrunable - maxToKeep : 0; + // Make sure we get below number of max queries to prune + return MAX(numMax, numPercent); +} + +- (FPruneForest *)pruneOldQueries:(id)cachePolicy { + NSMutableArray *pruneableQueries = [NSMutableArray array]; + NSMutableArray *unpruneableQueries = [NSMutableArray array]; + [self.trackedQueryTree forEach:^(FPath *path, NSDictionary *trackedQueries) { + [trackedQueries enumerateKeysAndObjectsUsingBlock:^(FQueryParams *params, FTrackedQuery *trackedQuery, BOOL *stop) { + if (!trackedQuery.isActive) { + [pruneableQueries addObject:trackedQuery]; + } else { + [unpruneableQueries addObject:trackedQuery]; + } + }]; + }]; + [pruneableQueries sortUsingComparator:^NSComparisonResult(FTrackedQuery *q1, FTrackedQuery *q2) { + if (q1.lastUse < q2.lastUse) { + return NSOrderedAscending; + } else if (q1.lastUse > q2.lastUse) { + return NSOrderedDescending; + } else { + return NSOrderedSame; + } + }]; + + + __block FPruneForest *pruneForest = [FPruneForest empty]; + NSUInteger numToPrune = [self numberOfQueriesToPrune:cachePolicy prunableCount:pruneableQueries.count]; + + // TODO: do in transaction + for (NSUInteger i = 0; i < numToPrune; i++) { + FTrackedQuery *toPrune = pruneableQueries[i]; + pruneForest = [pruneForest prunePath:toPrune.query.path]; + [self removeTrackedQuery:toPrune.query]; + } + + // Keep the rest of the prunable queries + for (NSUInteger i = numToPrune; i < pruneableQueries.count; i++) { + FTrackedQuery *toKeep = pruneableQueries[i]; + pruneForest = [pruneForest keepPath:toKeep.query.path]; + } + + // Also keep unprunable queries + [unpruneableQueries enumerateObjectsUsingBlock:^(FTrackedQuery *toKeep, NSUInteger idx, BOOL *stop) { + pruneForest = [pruneForest keepPath:toKeep.query.path]; + }]; + + return pruneForest; +} + +- (NSUInteger)numberOfPrunableQueries { + __block NSUInteger count = 0; + [self.trackedQueryTree forEach:^(FPath *path, NSDictionary *trackedQueries) { + [trackedQueries enumerateKeysAndObjectsUsingBlock:^(FQueryParams *params, FTrackedQuery *trackedQuery, BOOL *stop) { + if (!trackedQuery.isActive) { + count++; + } + }]; + }]; + return count; +} + +- (NSSet *)filteredQueryIdsAtPath:(FPath *)path { + NSDictionary *queries = [self.trackedQueryTree valueAtPath:path]; + if (queries) { + NSMutableSet *ids = [NSMutableSet set]; + [queries enumerateKeysAndObjectsUsingBlock:^(FQueryParams *params, FTrackedQuery *query, BOOL *stop) { + if (!query.query.loadsAllData) { + [ids addObject:@(query.queryId)]; + } + }]; + return ids; + } else { + return [NSSet set]; + } +} + +- (NSSet *)knownCompleteChildrenAtPath:(FPath *)path { + NSAssert(![self isQueryComplete:[FQuerySpec defaultQueryAtPath:path]], @"Path is fully complete"); + + NSMutableSet *completeChildren = [NSMutableSet set]; + // First, get complete children from any queries at this location. + NSSet *queryIds = [self filteredQueryIdsAtPath:path]; + [queryIds enumerateObjectsUsingBlock:^(NSNumber *queryId, BOOL *stop) { + NSSet *keys = [self.storageEngine trackedQueryKeysForQuery:[queryId unsignedIntegerValue]]; + [completeChildren unionSet:keys]; + }]; + + // Second, get any complete default queries immediately below us. + [[[self.trackedQueryTree subtreeAtPath:path] children] enumerateKeysAndObjectsUsingBlock:^(NSString *childKey, FImmutableTree *childTree, BOOL *stop) { + if ([childTree.value[[FQueryParams defaultInstance]] isComplete]) { + [completeChildren addObject:childKey]; + } + }]; + + return completeChildren; +} + +- (void)verifyCache { + NSArray *storedTrackedQueries = [self.storageEngine loadTrackedQueries]; + NSMutableArray *trackedQueries = [NSMutableArray array]; + + [self.trackedQueryTree forEach:^(FPath *path, NSDictionary *queryDict) { + [trackedQueries addObjectsFromArray:queryDict.allValues]; + }]; + NSComparator comparator = ^NSComparisonResult(FTrackedQuery *q1, FTrackedQuery *q2) { + if (q1.queryId < q2.queryId) { + return NSOrderedAscending; + } else if (q1.queryId > q2.queryId) { + return NSOrderedDescending; + } else { + return NSOrderedSame; + } + }; + [trackedQueries sortUsingComparator:comparator]; + storedTrackedQueries = [storedTrackedQueries sortedArrayUsingComparator:comparator]; + + if (![trackedQueries isEqualToArray:storedTrackedQueries]) { + [NSException raise:NSInternalInconsistencyException format:@"Tracked queries and queries stored on disk don't match"]; + } +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRDataEventType.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRDataEventType.h new file mode 100644 index 00000000..916ce32b --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRDataEventType.h @@ -0,0 +1,38 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#ifndef Firebase_FIRDataEventType_h +#define Firebase_FIRDataEventType_h + +#import + +/** + * This enum is the set of events that you can observe at a Firebase Database location. + */ +typedef NS_ENUM(NSInteger, FIRDataEventType) { + /// A new child node is added to a location. + FIRDataEventTypeChildAdded, + /// A child node is removed from a location. + FIRDataEventTypeChildRemoved, + /// A child node at a location changes. + FIRDataEventTypeChildChanged, + /// A child node moves relative to the other child nodes at a location. + FIRDataEventTypeChildMoved, + /// Any data changes at a location or, recursively, at any child node. + FIRDataEventTypeValue +} NS_SWIFT_NAME(DataEventType); + +#endif diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRDataSnapshot.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRDataSnapshot.h new file mode 100644 index 00000000..02a1e6a7 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRDataSnapshot.h @@ -0,0 +1,147 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@class FIRDatabaseReference; + +/** + * A FIRDataSnapshot contains data from a Firebase Database location. Any time you read + * Firebase data, you receive the data as a FIRDataSnapshot. + * + * FIRDataSnapshots are passed to the blocks you attach with observeEventType:withBlock: or observeSingleEvent:withBlock:. + * They are efficiently-generated immutable copies of the data at a Firebase Database location. + * They can't be modified and will never change. To modify data at a location, + * use a FIRDatabaseReference (e.g. with setValue:). + */ +NS_SWIFT_NAME(DataSnapshot) +@interface FIRDataSnapshot : NSObject + + +#pragma mark - Navigating and inspecting a snapshot + +/** + * Gets a FIRDataSnapshot for the location at the specified relative path. + * The relative path can either be a simple child key (e.g. 'fred') + * or a deeper slash-separated path (e.g. 'fred/name/first'). If the child + * location has no data, an empty FIRDataSnapshot is returned. + * + * @param childPathString A relative path to the location of child data. + * @return The FIRDataSnapshot for the child location. + */ +- (FIRDataSnapshot *)childSnapshotForPath:(NSString *)childPathString; + + +/** + * Return YES if the specified child exists. + * + * @param childPathString A relative path to the location of a potential child. + * @return YES if data exists at the specified childPathString, else NO. + */ +- (BOOL) hasChild:(NSString *)childPathString; + + +/** + * Return YES if the DataSnapshot has any children. + * + * @return YES if this snapshot has any children, else NO. + */ +- (BOOL) hasChildren; + + +/** + * Return YES if the DataSnapshot contains a non-null value. + * + * @return YES if this snapshot contains a non-null value, else NO. + */ +- (BOOL) exists; + + +#pragma mark - Data export + +/** + * Returns the raw value at this location, coupled with any metadata, such as priority. + * + * Priorities, where they exist, are accessible under the ".priority" key in instances of NSDictionary. + * For leaf locations with priorities, the value will be under the ".value" key. + */ +- (id __nullable) valueInExportFormat; + + +#pragma mark - Properties + +/** + * Returns the contents of this data snapshot as native types. + * + * Data types returned: + * + NSDictionary + * + NSArray + * + NSNumber (also includes booleans) + * + NSString + * + * @return The data as a native object. + */ +@property (strong, readonly, nonatomic, nullable) id value; + + +/** + * Gets the number of children for this DataSnapshot. + * + * @return An integer indicating the number of children. + */ +@property (readonly, nonatomic) NSUInteger childrenCount; + + +/** + * Gets a FIRDatabaseReference for the location that this data came from. + * + * @return A FIRDatabaseReference instance for the location of this data. + */ +@property (nonatomic, readonly, strong) FIRDatabaseReference * ref; + + +/** + * The key of the location that generated this FIRDataSnapshot. + * + * @return An NSString containing the key for the location of this FIRDataSnapshot. + */ +@property (strong, readonly, nonatomic) NSString* key; + + +/** + * An iterator for snapshots of the child nodes in this snapshot. + * You can use the native for..in syntax: + * + * for (FIRDataSnapshot* child in snapshot.children) { + * ... + * } + * + * @return An NSEnumerator of the children. + */ +@property (strong, readonly, nonatomic) NSEnumerator* children; + +/** + * The priority of the data in this FIRDataSnapshot. + * + * @return The priority as a string, or nil if no priority was set. + */ +@property (strong, readonly, nonatomic, nullable) id priority; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRDatabase.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRDatabase.h new file mode 100644 index 00000000..15c87007 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRDatabase.h @@ -0,0 +1,168 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FIRDatabaseReference.h" + +@class FIRApp; + +NS_ASSUME_NONNULL_BEGIN + +/** + * The entry point for accessing a Firebase Database. You can get an instance by calling + * [FIRDatabase database]. To access a location in the database and read or write data, + * use [FIRDatabase reference]. + */ +NS_SWIFT_NAME(Database) +@interface FIRDatabase : NSObject + +/** + * The NSObject initializer that has been marked as unavailable. Use the `database` + * method instead + * + * @return An instancetype instance +*/ +- (instancetype) init __attribute__((unavailable("use the database method instead"))); + +/** + * Gets the instance of FIRDatabase for the default FIRApp. + * + * @return A FIRDatabase instance. + */ ++ (FIRDatabase *) database NS_SWIFT_NAME(database()); + +/** + * Gets a FirebaseDatabase instance for the specified URL. + * + * @param url The URL to the Firebase Database instance you want to access. + * @return A FIRDatabase instance. + */ ++ (FIRDatabase *)databaseWithURL:(NSString *)url NS_SWIFT_NAME(database(url:)); + +/** + * Gets a FirebaseDatabase instance for the specified URL, using the specified + * FirebaseApp. + * + * @param app The FIRApp to get a FIRDatabase for. + * @param url The URL to the Firebase Database instance you want to access. + * @return A FIRDatabase instance. + */ +// clang-format off ++ (FIRDatabase *)databaseForApp:(FIRApp *)app + URL:(NSString *)url NS_SWIFT_NAME(database(app:url:)); +// clang-format on + +/** + * Gets an instance of FIRDatabase for a specific FIRApp. + * + * @param app The FIRApp to get a FIRDatabase for. + * @return A FIRDatabase instance. + */ ++ (FIRDatabase *) databaseForApp:(FIRApp *)app NS_SWIFT_NAME(database(app:)); + +/** The FIRApp instance to which this FIRDatabase belongs. */ +@property (weak, readonly, nonatomic) FIRApp *app; + +/** + * Gets a FIRDatabaseReference for the root of your Firebase Database. + */ +- (FIRDatabaseReference *) reference; + +/** + * Gets a FIRDatabaseReference for the provided path. + * + * @param path Path to a location in your Firebase Database. + * @return A FIRDatabaseReference pointing to the specified path. + */ +- (FIRDatabaseReference *) referenceWithPath:(NSString *)path; + +/** + * Gets a FIRDatabaseReference for the provided URL. The URL must be a URL to a path + * within this Firebase Database. To create a FIRDatabaseReference to a different database, + * create a FIRApp} with a FIROptions object configured with the appropriate database URL. + * + * @param databaseUrl A URL to a path within your database. + * @return A FIRDatabaseReference for the provided URL. +*/ +- (FIRDatabaseReference *) referenceFromURL:(NSString *)databaseUrl; + +/** + * The Firebase Database client automatically queues writes and sends them to the server at the earliest opportunity, + * depending on network connectivity. In some cases (e.g. offline usage) there may be a large number of writes + * waiting to be sent. Calling this method will purge all outstanding writes so they are abandoned. + * + * All writes will be purged, including transactions and onDisconnect writes. The writes will + * be rolled back locally, perhaps triggering events for affected event listeners, and the client will not + * (re-)send them to the Firebase Database backend. + */ +- (void)purgeOutstandingWrites; + +/** + * Shuts down our connection to the Firebase Database backend until goOnline is called. + */ +- (void)goOffline; + +/** + * Resumes our connection to the Firebase Database backend after a previous goOffline call. + */ +- (void)goOnline; + +/** + * The Firebase Database client will cache synchronized data and keep track of all writes you've + * initiated while your application is running. It seamlessly handles intermittent network + * connections and re-sends write operations when the network connection is restored. + * + * However by default your write operations and cached data are only stored in-memory and will + * be lost when your app restarts. By setting this value to `YES`, the data will be persisted + * to on-device (disk) storage and will thus be available again when the app is restarted + * (even when there is no network connectivity at that time). Note that this property must be + * set before creating your first Database reference and only needs to be called once per + * application. + * + */ +@property (nonatomic) BOOL persistenceEnabled NS_SWIFT_NAME(isPersistenceEnabled); + +/** + * By default the Firebase Database client will use up to 10MB of disk space to cache data. If the cache grows beyond + * this size, the client will start removing data that hasn't been recently used. If you find that your application + * caches too little or too much data, call this method to change the cache size. This property must be set before + * creating your first FIRDatabaseReference and only needs to be called once per application. + * + * Note that the specified cache size is only an approximation and the size on disk may temporarily exceed it + * at times. Cache sizes smaller than 1 MB or greater than 100 MB are not supported. + */ +@property (nonatomic) NSUInteger persistenceCacheSizeBytes; + +/** + * Sets the dispatch queue on which all events are raised. The default queue is the main queue. + * + * Note that this must be set before creating your first Database reference. + */ +@property (nonatomic, strong) dispatch_queue_t callbackQueue; + +/** + * Enables verbose diagnostic logging. + * + * @param enabled YES to enable logging, NO to disable. + */ ++ (void) setLoggingEnabled:(BOOL)enabled; + +/** Retrieve the Firebase Database SDK version. */ ++ (NSString *) sdkVersion; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRDatabaseQuery.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRDatabaseQuery.h new file mode 100644 index 00000000..ef566438 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRDatabaseQuery.h @@ -0,0 +1,314 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FIRDataEventType.h" +#import "FIRDataSnapshot.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * A FIRDatabaseHandle is used to identify listeners of Firebase Database events. These handles + * are returned by observeEventType: and and can later be passed to removeObserverWithHandle: to + * stop receiving updates. + */ +typedef NSUInteger FIRDatabaseHandle NS_SWIFT_NAME(DatabaseHandle); + +/** + * A FIRDatabaseQuery instance represents a query over the data at a particular location. + * + * You create one by calling one of the query methods (queryOrderedByChild:, queryStartingAtValue:, etc.) + * on a FIRDatabaseReference. The query methods can be chained to further specify the data you are interested in + * observing + */ +NS_SWIFT_NAME(DatabaseQuery) +@interface FIRDatabaseQuery : NSObject + + +#pragma mark - Attach observers to read data + +/** + * observeEventType:withBlock: is used to listen for data changes at a particular location. + * This is the primary way to read data from the Firebase Database. Your block will be triggered + * for the initial data and again whenever the data changes. + * + * Use removeObserverWithHandle: to stop receiving updates. + * + * @param eventType The type of event to listen for. + * @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot. + * @return A handle used to unregister this block later using removeObserverWithHandle: + */ +- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block; + + +/** + * observeEventType:andPreviousSiblingKeyWithBlock: is used to listen for data changes at a particular location. + * This is the primary way to read data from the Firebase Database. Your block will be triggered + * for the initial data and again whenever the data changes. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and + * FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order. + * + * Use removeObserverWithHandle: to stop receiving updates. + * + * @param eventType The type of event to listen for. + * @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot + * and the previous child's key. + * @return A handle used to unregister this block later using removeObserverWithHandle: + */ +- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block; + + +/** + * observeEventType:withBlock: is used to listen for data changes at a particular location. + * This is the primary way to read data from the Firebase Database. Your block will be triggered + * for the initial data and again whenever the data changes. + * + * The cancelBlock will be called if you will no longer receive new events due to no longer having permission. + * + * Use removeObserverWithHandle: to stop receiving updates. + * + * @param eventType The type of event to listen for. + * @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot. + * @param cancelBlock The block that should be called if this client no longer has permission to receive these events + * @return A handle used to unregister this block later using removeObserverWithHandle: + */ +- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock; + + +/** + * observeEventType:andPreviousSiblingKeyWithBlock: is used to listen for data changes at a particular location. + * This is the primary way to read data from the Firebase Database. Your block will be triggered + * for the initial data and again whenever the data changes. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and + * FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order. + * + * The cancelBlock will be called if you will no longer receive new events due to no longer having permission. + * + * Use removeObserverWithHandle: to stop receiving updates. + * + * @param eventType The type of event to listen for. + * @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot + * and the previous child's key. + * @param cancelBlock The block that should be called if this client no longer has permission to receive these events + * @return A handle used to unregister this block later using removeObserverWithHandle: + */ +- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock; + + +/** + * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. + * + * @param eventType The type of event to listen for. + * @param block The block that should be called. It is passed the data as a FIRDataSnapshot. + */ +- (void)observeSingleEventOfType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block; + + +/** + * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and + * FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order. + * + * @param eventType The type of event to listen for. + * @param block The block that should be called. It is passed the data as a FIRDataSnapshot and the previous child's key. + */ +- (void)observeSingleEventOfType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block; + + +/** + * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. + * + * The cancelBlock will be called if you do not have permission to read data at this location. + * + * @param eventType The type of event to listen for. + * @param block The block that should be called. It is passed the data as a FIRDataSnapshot. + * @param cancelBlock The block that will be called if you don't have permission to access this data + */ +- (void)observeSingleEventOfType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock; + + +/** + * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and + * FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order. + * + * The cancelBlock will be called if you do not have permission to read data at this location. + * + * @param eventType The type of event to listen for. + * @param block The block that should be called. It is passed the data as a FIRDataSnapshot and the previous child's key. + * @param cancelBlock The block that will be called if you don't have permission to access this data + */ +- (void)observeSingleEventOfType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock; + + +#pragma mark - Detaching observers + +/** + * Detach a block previously attached with observeEventType:withBlock:. + * + * @param handle The handle returned by the call to observeEventType:withBlock: which we are trying to remove. + */ +- (void) removeObserverWithHandle:(FIRDatabaseHandle)handle; + + +/** + * Detach all blocks previously attached to this Firebase Database location with observeEventType:withBlock: + */ +- (void) removeAllObservers; + +/** + * By calling `keepSynced:YES` on a location, the data for that location will automatically be downloaded and + * kept in sync, even when no listeners are attached for that location. Additionally, while a location is kept + * synced, it will not be evicted from the persistent disk cache. + * + * @param keepSynced Pass YES to keep this location synchronized, pass NO to stop synchronization. +*/ + - (void) keepSynced:(BOOL)keepSynced; + + +#pragma mark - Querying and limiting + +/** +* queryLimitedToFirst: is used to generate a reference to a limited view of the data at this location. +* The FIRDatabaseQuery instance returned by queryLimitedToFirst: will respond to at most the first limit child nodes. +* +* @param limit The upper bound, inclusive, for the number of child nodes to receive events for +* @return A FIRDatabaseQuery instance, limited to at most limit child nodes. +*/ +- (FIRDatabaseQuery *)queryLimitedToFirst:(NSUInteger)limit; + + +/** +* queryLimitedToLast: is used to generate a reference to a limited view of the data at this location. +* The FIRDatabaseQuery instance returned by queryLimitedToLast: will respond to at most the last limit child nodes. +* +* @param limit The upper bound, inclusive, for the number of child nodes to receive events for +* @return A FIRDatabaseQuery instance, limited to at most limit child nodes. +*/ +- (FIRDatabaseQuery *)queryLimitedToLast:(NSUInteger)limit; + +/** + * queryOrderBy: is used to generate a reference to a view of the data that's been sorted by the values of + * a particular child key. This method is intended to be used in combination with queryStartingAtValue:, + * queryEndingAtValue:, or queryEqualToValue:. + * + * @param key The child key to use in ordering data visible to the returned FIRDatabaseQuery + * @return A FIRDatabaseQuery instance, ordered by the values of the specified child key. +*/ +- (FIRDatabaseQuery *)queryOrderedByChild:(NSString *)key; + +/** + * queryOrderedByKey: is used to generate a reference to a view of the data that's been sorted by child key. + * This method is intended to be used in combination with queryStartingAtValue:, queryEndingAtValue:, + * or queryEqualToValue:. + * + * @return A FIRDatabaseQuery instance, ordered by child keys. + */ +- (FIRDatabaseQuery *) queryOrderedByKey; + +/** + * queryOrderedByValue: is used to generate a reference to a view of the data that's been sorted by child value. + * This method is intended to be used in combination with queryStartingAtValue:, queryEndingAtValue:, + * or queryEqualToValue:. + * + * @return A FIRDatabaseQuery instance, ordered by child value. + */ +- (FIRDatabaseQuery *) queryOrderedByValue; + +/** + * queryOrderedByPriority: is used to generate a reference to a view of the data that's been sorted by child + * priority. This method is intended to be used in combination with queryStartingAtValue:, queryEndingAtValue:, + * or queryEqualToValue:. + * + * @return A FIRDatabaseQuery instance, ordered by child priorities. + */ +- (FIRDatabaseQuery *) queryOrderedByPriority; + +/** + * queryStartingAtValue: is used to generate a reference to a limited view of the data at this location. + * The FIRDatabaseQuery instance returned by queryStartingAtValue: will respond to events at nodes with a value + * greater than or equal to startValue. + * + * @param startValue The lower bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery + * @return A FIRDatabaseQuery instance, limited to data with value greater than or equal to startValue + */ +- (FIRDatabaseQuery *)queryStartingAtValue:(nullable id)startValue; + +/** + * queryStartingAtValue:childKey: is used to generate a reference to a limited view of the data at this location. + * The FIRDatabaseQuery instance returned by queryStartingAtValue:childKey will respond to events at nodes with a value + * greater than startValue, or equal to startValue and with a key greater than or equal to childKey. This is most + * useful when implementing pagination in a case where multiple nodes can match the startValue. + * + * @param startValue The lower bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery + * @param childKey The lower bound, inclusive, for the key of nodes with value equal to startValue + * @return A FIRDatabaseQuery instance, limited to data with value greater than or equal to startValue + */ +- (FIRDatabaseQuery *)queryStartingAtValue:(nullable id)startValue childKey:(nullable NSString *)childKey; + +/** + * queryEndingAtValue: is used to generate a reference to a limited view of the data at this location. + * The FIRDatabaseQuery instance returned by queryEndingAtValue: will respond to events at nodes with a value + * less than or equal to endValue. + * + * @param endValue The upper bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery + * @return A FIRDatabaseQuery instance, limited to data with value less than or equal to endValue + */ +- (FIRDatabaseQuery *)queryEndingAtValue:(nullable id)endValue; + +/** + * queryEndingAtValue:childKey: is used to generate a reference to a limited view of the data at this location. + * The FIRDatabaseQuery instance returned by queryEndingAtValue:childKey will respond to events at nodes with a value + * less than endValue, or equal to endValue and with a key less than or equal to childKey. This is most useful when + * implementing pagination in a case where multiple nodes can match the endValue. + * + * @param endValue The upper bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery + * @param childKey The upper bound, inclusive, for the key of nodes with value equal to endValue + * @return A FIRDatabaseQuery instance, limited to data with value less than or equal to endValue + */ +- (FIRDatabaseQuery *)queryEndingAtValue:(nullable id)endValue childKey:(nullable NSString *)childKey; + +/** + * queryEqualToValue: is used to generate a reference to a limited view of the data at this location. + * The FIRDatabaseQuery instance returned by queryEqualToValue: will respond to events at nodes with a value equal + * to the supplied argument. + * + * @param value The value that the data returned by this FIRDatabaseQuery will have + * @return A FIRDatabaseQuery instance, limited to data with the supplied value. + */ +- (FIRDatabaseQuery *)queryEqualToValue:(nullable id)value; + +/** + * queryEqualToValue:childKey: is used to generate a reference to a limited view of the data at this location. + * The FIRDatabaseQuery instance returned by queryEqualToValue:childKey will respond to events at nodes with a value + * equal to the supplied argument and with their key equal to childKey. There will be at most one node that matches + * because child keys are unique. + * + * @param value The value that the data returned by this FIRDatabaseQuery will have + * @param childKey The name of nodes with the right value + * @return A FIRDatabaseQuery instance, limited to data with the supplied value and the key. + */ +- (FIRDatabaseQuery *)queryEqualToValue:(nullable id)value childKey:(nullable NSString *)childKey; + + +#pragma mark - Properties + +/** +* Gets a FIRDatabaseReference for the location of this query. +* +* @return A FIRDatabaseReference for the location of this query. +*/ +@property (nonatomic, readonly, strong) FIRDatabaseReference * ref; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRDatabaseReference.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRDatabaseReference.h new file mode 100644 index 00000000..b96585e6 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRDatabaseReference.h @@ -0,0 +1,718 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FIRDatabaseQuery.h" +#import "FIRDatabase.h" +#import "FIRDataSnapshot.h" +#import "FIRMutableData.h" +#import "FIRTransactionResult.h" +#import "FIRServerValue.h" + +NS_ASSUME_NONNULL_BEGIN + +@class FIRDatabase; + +/** + * A FIRDatabaseReference represents a particular location in your Firebase Database + * and can be used for reading or writing data to that Firebase Database location. + * + * This class is the starting point for all Firebase Database operations. After you've + * obtained your first FIRDatabaseReference via [FIRDatabase reference], you can use it + * to read data (ie. observeEventType:withBlock:), write data (ie. setValue:), and to + * create new FIRDatabaseReferences (ie. child:). + */ +NS_SWIFT_NAME(DatabaseReference) +@interface FIRDatabaseReference : FIRDatabaseQuery + + +#pragma mark - Getting references to children locations + +/** + * Gets a FIRDatabaseReference for the location at the specified relative path. + * The relative path can either be a simple child key (e.g. 'fred') or a + * deeper slash-separated path (e.g. 'fred/name/first'). + * + * @param pathString A relative path from this location to the desired child location. + * @return A FIRDatabaseReference for the specified relative path. + */ +- (FIRDatabaseReference *)child:(NSString *)pathString; + +/** + * childByAppendingPath: is deprecated, use child: instead. + */ +- (FIRDatabaseReference *)childByAppendingPath:(NSString *)pathString __deprecated_msg("use child: instead"); + +/** + * childByAutoId generates a new child location using a unique key and returns a + * FIRDatabaseReference to it. This is useful when the children of a Firebase Database + * location represent a list of items. + * + * The unique key generated by childByAutoId: is prefixed with a client-generated + * timestamp so that the resulting list will be chronologically-sorted. + * + * @return A FIRDatabaseReference for the generated location. + */ +- (FIRDatabaseReference *) childByAutoId; + + +#pragma mark - Writing data + +/** Write data to this Firebase Database location. + +This will overwrite any data at this location and all child locations. + +Data types that can be set are: + +- NSString -- @"Hello World" +- NSNumber (also includes boolean) -- @YES, @43, @4.333 +- NSDictionary -- @{@"key": @"value", @"nested": @{@"another": @"value"} } +- NSArray + +The effect of the write will be visible immediately and the corresponding +events will be triggered. Synchronization of the data to the Firebase Database +servers will also be started. + +Passing null for the new value is equivalent to calling remove:; +all data at this location or any child location will be deleted. + +Note that setValue: will remove any priority stored at this location, so if priority +is meant to be preserved, you should use setValue:andPriority: instead. + +@param value The value to be written. + */ +- (void) setValue:(nullable id)value; + + +/** + * The same as setValue: with a block that gets triggered after the write operation has + * been committed to the Firebase Database servers. + * + * @param value The value to be written. + * @param block The block to be called after the write has been committed to the Firebase Database servers. + */ +- (void) setValue:(nullable id)value withCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block; + + +/** + * The same as setValue: with an additional priority to be attached to the data being written. + * Priorities are used to order items. + * + * @param value The value to be written. + * @param priority The priority to be attached to that data. + */ +- (void) setValue:(nullable id)value andPriority:(nullable id)priority; + + +/** + * The same as setValue:andPriority: with a block that gets triggered after the write operation has + * been committed to the Firebase Database servers. + * + * @param value The value to be written. + * @param priority The priority to be attached to that data. + * @param block The block to be called after the write has been committed to the Firebase Database servers. + */ +- (void) setValue:(nullable id)value andPriority:(nullable id)priority withCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block; + + +/** + * Remove the data at this Firebase Database location. Any data at child locations will also be deleted. + * + * The effect of the delete will be visible immediately and the corresponding events + * will be triggered. Synchronization of the delete to the Firebase Database servers will + * also be started. + * + * remove: is equivalent to calling setValue:nil + */ +- (void) removeValue; + + +/** + * The same as remove: with a block that gets triggered after the remove operation has + * been committed to the Firebase Database servers. + * + * @param block The block to be called after the remove has been committed to the Firebase Database servers. + */ +- (void) removeValueWithCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block; + +/** + * Sets a priority for the data at this Firebase Database location. + * Priorities can be used to provide a custom ordering for the children at a location + * (if no priorities are specified, the children are ordered by key). + * + * You cannot set a priority on an empty location. For this reason + * setValue:andPriority: should be used when setting initial data with a specific priority + * and setPriority: should be used when updating the priority of existing data. + * + * Children are sorted based on this priority using the following rules: + * + * Children with no priority come first. + * Children with a number as their priority come next. They are sorted numerically by priority (small to large). + * Children with a string as their priority come last. They are sorted lexicographically by priority. + * Whenever two children have the same priority (including no priority), they are sorted by key. Numeric + * keys come first (sorted numerically), followed by the remaining keys (sorted lexicographically). + * + * Note that priorities are parsed and ordered as IEEE 754 double-precision floating-point numbers. + * Keys are always stored as strings and are treated as numbers only when they can be parsed as a + * 32-bit integer + * + * @param priority The priority to set at the specified location. + */ +- (void) setPriority:(nullable id)priority; + + +/** + * The same as setPriority: with a block that is called once the priority has + * been committed to the Firebase Database servers. + * + * @param priority The priority to set at the specified location. + * @param block The block that is triggered after the priority has been written on the servers. + */ +- (void) setPriority:(nullable id)priority withCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block; + +/** + * Updates the values at the specified paths in the dictionary without overwriting other + * keys at this location. + * + * @param values A dictionary of the keys to change and their new values + */ +- (void) updateChildValues:(NSDictionary *)values; + +/** + * The same as update: with a block that is called once the update has been committed to the + * Firebase Database servers + * + * @param values A dictionary of the keys to change and their new values + * @param block The block that is triggered after the update has been written on the Firebase Database servers + */ +- (void) updateChildValues:(NSDictionary *)values withCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block; + + +#pragma mark - Attaching observers to read data + +/** + * observeEventType:withBlock: is used to listen for data changes at a particular location. + * This is the primary way to read data from the Firebase Database. Your block will be triggered + * for the initial data and again whenever the data changes. + * + * Use removeObserverWithHandle: to stop receiving updates. + * @param eventType The type of event to listen for. + * @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot. + * @return A handle used to unregister this block later using removeObserverWithHandle: + */ +- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block; + + +/** + * observeEventType:andPreviousSiblingKeyWithBlock: is used to listen for data changes at a particular location. + * This is the primary way to read data from the Firebase Database. Your block will be triggered + * for the initial data and again whenever the data changes. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and + * FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order. + * + * Use removeObserverWithHandle: to stop receiving updates. + * + * @param eventType The type of event to listen for. + * @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot + * and the previous child's key. + * @return A handle used to unregister this block later using removeObserverWithHandle: + */ +- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block; + + +/** + * observeEventType:withBlock: is used to listen for data changes at a particular location. + * This is the primary way to read data from the Firebase Database. Your block will be triggered + * for the initial data and again whenever the data changes. + * + * The cancelBlock will be called if you will no longer receive new events due to no longer having permission. + * + * Use removeObserverWithHandle: to stop receiving updates. + * + * @param eventType The type of event to listen for. + * @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot. + * @param cancelBlock The block that should be called if this client no longer has permission to receive these events + * @return A handle used to unregister this block later using removeObserverWithHandle: + */ +- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock; + + +/** + * observeEventType:andPreviousSiblingKeyWithBlock: is used to listen for data changes at a particular location. + * This is the primary way to read data from the Firebase Database. Your block will be triggered + * for the initial data and again whenever the data changes. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and + * FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order. + * + * The cancelBlock will be called if you will no longer receive new events due to no longer having permission. + * + * Use removeObserverWithHandle: to stop receiving updates. + * + * @param eventType The type of event to listen for. + * @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot + * and the previous child's key. + * @param cancelBlock The block that should be called if this client no longer has permission to receive these events + * @return A handle used to unregister this block later using removeObserverWithHandle: + */ +- (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock; + + +/** + * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. + * + * @param eventType The type of event to listen for. + * @param block The block that should be called. It is passed the data as a FIRDataSnapshot. + */ +- (void)observeSingleEventOfType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block; + + +/** + * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and + * FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order. + * + * @param eventType The type of event to listen for. + * @param block The block that should be called. It is passed the data as a FIRDataSnapshot and the previous child's key. + */ +- (void)observeSingleEventOfType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block; + + +/** + * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. + * + * The cancelBlock will be called if you do not have permission to read data at this location. + * + * @param eventType The type of event to listen for. + * @param block The block that should be called. It is passed the data as a FIRDataSnapshot. + * @param cancelBlock The block that will be called if you don't have permission to access this data + */ +- (void)observeSingleEventOfType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock; + + +/** + * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and + * FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order. + * + * The cancelBlock will be called if you do not have permission to read data at this location. + * + * @param eventType The type of event to listen for. + * @param block The block that should be called. It is passed the data as a FIRDataSnapshot and the previous child's key. + * @param cancelBlock The block that will be called if you don't have permission to access this data + */ +- (void)observeSingleEventOfType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock; + +#pragma mark - Detaching observers + +/** + * Detach a block previously attached with observeEventType:withBlock:. + * + * @param handle The handle returned by the call to observeEventType:withBlock: which we are trying to remove. + */ +- (void) removeObserverWithHandle:(FIRDatabaseHandle)handle; + +/** + * By calling `keepSynced:YES` on a location, the data for that location will automatically be downloaded and + * kept in sync, even when no listeners are attached for that location. Additionally, while a location is kept + * synced, it will not be evicted from the persistent disk cache. + * + * @param keepSynced Pass YES to keep this location synchronized, pass NO to stop synchronization. + */ +- (void) keepSynced:(BOOL)keepSynced; + + +/** + * Removes all observers at the current reference, but does not remove any observers at child references. + * removeAllObservers must be called again for each child reference where a listener was established to remove the observers. + */ +- (void) removeAllObservers; + +#pragma mark - Querying and limiting + + +/** + * queryLimitedToFirst: is used to generate a reference to a limited view of the data at this location. + * The FIRDatabaseQuery instance returned by queryLimitedToFirst: will respond to at most the first limit child nodes. + * + * @param limit The upper bound, inclusive, for the number of child nodes to receive events for + * @return A FIRDatabaseQuery instance, limited to at most limit child nodes. + */ +- (FIRDatabaseQuery *)queryLimitedToFirst:(NSUInteger)limit; + + +/** + * queryLimitedToLast: is used to generate a reference to a limited view of the data at this location. + * The FIRDatabaseQuery instance returned by queryLimitedToLast: will respond to at most the last limit child nodes. + * + * @param limit The upper bound, inclusive, for the number of child nodes to receive events for + * @return A FIRDatabaseQuery instance, limited to at most limit child nodes. + */ +- (FIRDatabaseQuery *)queryLimitedToLast:(NSUInteger)limit; + +/** + * queryOrderBy: is used to generate a reference to a view of the data that's been sorted by the values of + * a particular child key. This method is intended to be used in combination with queryStartingAtValue:, + * queryEndingAtValue:, or queryEqualToValue:. + * + * @param key The child key to use in ordering data visible to the returned FIRDatabaseQuery + * @return A FIRDatabaseQuery instance, ordered by the values of the specified child key. + */ +- (FIRDatabaseQuery *)queryOrderedByChild:(NSString *)key; + +/** + * queryOrderedByKey: is used to generate a reference to a view of the data that's been sorted by child key. + * This method is intended to be used in combination with queryStartingAtValue:, queryEndingAtValue:, + * or queryEqualToValue:. + * + * @return A FIRDatabaseQuery instance, ordered by child keys. + */ +- (FIRDatabaseQuery *) queryOrderedByKey; + +/** + * queryOrderedByPriority: is used to generate a reference to a view of the data that's been sorted by child + * priority. This method is intended to be used in combination with queryStartingAtValue:, queryEndingAtValue:, + * or queryEqualToValue:. + * + * @return A FIRDatabaseQuery instance, ordered by child priorities. + */ +- (FIRDatabaseQuery *) queryOrderedByPriority; + +/** + * queryStartingAtValue: is used to generate a reference to a limited view of the data at this location. + * The FIRDatabaseQuery instance returned by queryStartingAtValue: will respond to events at nodes with a value + * greater than or equal to startValue. + * + * @param startValue The lower bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery + * @return A FIRDatabaseQuery instance, limited to data with value greater than or equal to startValue + */ +- (FIRDatabaseQuery *)queryStartingAtValue:(nullable id)startValue; + +/** + * queryStartingAtValue:childKey: is used to generate a reference to a limited view of the data at this location. + * The FIRDatabaseQuery instance returned by queryStartingAtValue:childKey will respond to events at nodes with a value + * greater than startValue, or equal to startValue and with a key greater than or equal to childKey. + * + * @param startValue The lower bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery + * @param childKey The lower bound, inclusive, for the key of nodes with value equal to startValue + * @return A FIRDatabaseQuery instance, limited to data with value greater than or equal to startValue + */ +- (FIRDatabaseQuery *)queryStartingAtValue:(nullable id)startValue childKey:(nullable NSString *)childKey; + +/** + * queryEndingAtValue: is used to generate a reference to a limited view of the data at this location. + * The FIRDatabaseQuery instance returned by queryEndingAtValue: will respond to events at nodes with a value + * less than or equal to endValue. + * + * @param endValue The upper bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery + * @return A FIRDatabaseQuery instance, limited to data with value less than or equal to endValue + */ +- (FIRDatabaseQuery *)queryEndingAtValue:(nullable id)endValue; + +/** + * queryEndingAtValue:childKey: is used to generate a reference to a limited view of the data at this location. + * The FIRDatabaseQuery instance returned by queryEndingAtValue:childKey will respond to events at nodes with a value + * less than endValue, or equal to endValue and with a key less than or equal to childKey. + * + * @param endValue The upper bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery + * @param childKey The upper bound, inclusive, for the key of nodes with value equal to endValue + * @return A FIRDatabaseQuery instance, limited to data with value less than or equal to endValue + */ +- (FIRDatabaseQuery *)queryEndingAtValue:(nullable id)endValue childKey:(nullable NSString *)childKey; + +/** + * queryEqualToValue: is used to generate a reference to a limited view of the data at this location. + * The FIRDatabaseQuery instance returned by queryEqualToValue: will respond to events at nodes with a value equal + * to the supplied argument. + * + * @param value The value that the data returned by this FIRDatabaseQuery will have + * @return A FIRDatabaseQuery instance, limited to data with the supplied value. + */ +- (FIRDatabaseQuery *)queryEqualToValue:(nullable id)value; + +/** + * queryEqualToValue:childKey: is used to generate a reference to a limited view of the data at this location. + * The FIRDatabaseQuery instance returned by queryEqualToValue:childKey will respond to events at nodes with a value + * equal to the supplied argument with a key equal to childKey. There will be at most one node that matches because + * child keys are unique. + * + * @param value The value that the data returned by this FIRDatabaseQuery will have + * @param childKey The key of nodes with the right value + * @return A FIRDatabaseQuery instance, limited to data with the supplied value and the key. + */ +- (FIRDatabaseQuery *)queryEqualToValue:(nullable id)value childKey:(nullable NSString *)childKey; + +#pragma mark - Managing presence + +/** + * Ensure the data at this location is set to the specified value when + * the client is disconnected (due to closing the browser, navigating + * to a new page, or network issues). + * + * onDisconnectSetValue: is especially useful for implementing "presence" systems, + * where a value should be changed or cleared when a user disconnects + * so that he appears "offline" to other users. + * + * @param value The value to be set after the connection is lost. + */ +- (void) onDisconnectSetValue:(nullable id)value; + + +/** + * Ensure the data at this location is set to the specified value when + * the client is disconnected (due to closing the browser, navigating + * to a new page, or network issues). + * + * The completion block will be triggered when the operation has been successfully queued up on the Firebase Database servers + * + * @param value The value to be set after the connection is lost. + * @param block Block to be triggered when the operation has been queued up on the Firebase Database servers + */ +- (void) onDisconnectSetValue:(nullable id)value withCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block; + + +/** + * Ensure the data at this location is set to the specified value and priority when + * the client is disconnected (due to closing the browser, navigating + * to a new page, or network issues). + * + * @param value The value to be set after the connection is lost. + * @param priority The priority to be set after the connection is lost. + */ +- (void) onDisconnectSetValue:(nullable id)value andPriority:(id)priority; + + +/** + * Ensure the data at this location is set to the specified value and priority when + * the client is disconnected (due to closing the browser, navigating + * to a new page, or network issues). + * + * The completion block will be triggered when the operation has been successfully queued up on the Firebase Database servers + * + * @param value The value to be set after the connection is lost. + * @param priority The priority to be set after the connection is lost. + * @param block Block to be triggered when the operation has been queued up on the Firebase Database servers + */ +- (void) onDisconnectSetValue:(nullable id)value andPriority:(nullable id)priority withCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block; + + +/** + * Ensure the data at this location is removed when + * the client is disconnected (due to closing the app, navigating + * to a new page, or network issues). + * + * onDisconnectRemoveValue is especially useful for implementing "presence" systems. + */ +- (void) onDisconnectRemoveValue; + + +/** + * Ensure the data at this location is removed when + * the client is disconnected (due to closing the app, navigating + * to a new page, or network issues). + * + * onDisconnectRemoveValueWithCompletionBlock: is especially useful for implementing "presence" systems. + * + * @param block Block to be triggered when the operation has been queued up on the Firebase Database servers + */ +- (void) onDisconnectRemoveValueWithCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block; + + + +/** + * Ensure the data has the specified child values updated when + * the client is disconnected (due to closing the browser, navigating + * to a new page, or network issues). + * + * + * @param values A dictionary of child node keys and the values to set them to after the connection is lost. + */ +- (void) onDisconnectUpdateChildValues:(NSDictionary *)values; + + +/** + * Ensure the data has the specified child values updated when + * the client is disconnected (due to closing the browser, navigating + * to a new page, or network issues). + * + * + * @param values A dictionary of child node keys and the values to set them to after the connection is lost. + * @param block A block that will be called once the operation has been queued up on the Firebase Database servers + */ +- (void) onDisconnectUpdateChildValues:(NSDictionary *)values withCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block; + + +/** + * Cancel any operations that are set to run on disconnect. If you previously called onDisconnectSetValue:, + * onDisconnectRemoveValue:, or onDisconnectUpdateChildValues:, and no longer want the values updated when the + * connection is lost, call cancelDisconnectOperations: + */ +- (void) cancelDisconnectOperations; + + +/** + * Cancel any operations that are set to run on disconnect. If you previously called onDisconnectSetValue:, + * onDisconnectRemoveValue:, or onDisconnectUpdateChildValues:, and no longer want the values updated when the + * connection is lost, call cancelDisconnectOperations: + * + * @param block A block that will be triggered once the Firebase Database servers have acknowledged the cancel request. + */ +- (void) cancelDisconnectOperationsWithCompletionBlock:(nullable void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block; + + +#pragma mark - Manual Connection Management + +/** + * Manually disconnect the Firebase Database client from the server and disable automatic reconnection. + * + * The Firebase Database client automatically maintains a persistent connection to the Firebase Database server, + * which will remain active indefinitely and reconnect when disconnected. However, the goOffline( ) + * and goOnline( ) methods may be used to manually control the client connection in cases where + * a persistent connection is undesirable. + * + * While offline, the Firebase Database client will no longer receive data updates from the server. However, + * all database operations performed locally will continue to immediately fire events, allowing + * your application to continue behaving normally. Additionally, each operation performed locally + * will automatically be queued and retried upon reconnection to the Firebase Database server. + * + * To reconnect to the Firebase Database server and begin receiving remote events, see goOnline( ). + * Once the connection is reestablished, the Firebase Database client will transmit the appropriate data + * and fire the appropriate events so that your client "catches up" automatically. + * + * Note: Invoking this method will impact all Firebase Database connections. + */ ++ (void) goOffline; + +/** + * Manually reestablish a connection to the Firebase Database server and enable automatic reconnection. + * + * The Firebase Database client automatically maintains a persistent connection to the Firebase Database server, + * which will remain active indefinitely and reconnect when disconnected. However, the goOffline( ) + * and goOnline( ) methods may be used to manually control the client connection in cases where + * a persistent connection is undesirable. + * + * This method should be used after invoking goOffline( ) to disable the active connection. + * Once reconnected, the Firebase Database client will automatically transmit the proper data and fire + * the appropriate events so that your client "catches up" automatically. + * + * To disconnect from the Firebase Database server, see goOffline( ). + * + * Note: Invoking this method will impact all Firebase Database connections. + */ ++ (void) goOnline; + + +#pragma mark - Transactions + +/** + * Performs an optimistic-concurrency transactional update to the data at this location. Your block will be called with a FIRMutableData + * instance that contains the current data at this location. Your block should update this data to the value you + * wish to write to this location, and then return an instance of FIRTransactionResult with the new data. + * + * If, when the operation reaches the server, it turns out that this client had stale data, your block will be run + * again with the latest data from the server. + * + * When your block is run, you may decide to abort the transaction by returning [FIRTransactionResult abort]. + * + * @param block This block receives the current data at this location and must return an instance of FIRTransactionResult + */ +- (void) runTransactionBlock:(FIRTransactionResult * (^) (FIRMutableData* currentData))block; + + +/** + * Performs an optimistic-concurrency transactional update to the data at this location. Your block will be called with a FIRMutableData + * instance that contains the current data at this location. Your block should update this data to the value you + * wish to write to this location, and then return an instance of FIRTransactionResult with the new data. + * + * If, when the operation reaches the server, it turns out that this client had stale data, your block will be run + * again with the latest data from the server. + * + * When your block is run, you may decide to abort the transaction by returning [FIRTransactionResult abort]. + * + * @param block This block receives the current data at this location and must return an instance of FIRTransactionResult + * @param completionBlock This block will be triggered once the transaction is complete, whether it was successful or not. It will indicate if there was an error, whether or not the data was committed, and what the current value of the data at this location is. + */ +- (void)runTransactionBlock:(FIRTransactionResult * (^) (FIRMutableData* currentData))block andCompletionBlock:(void (^) (NSError *__nullable error, BOOL committed, FIRDataSnapshot *__nullable snapshot))completionBlock; + + + +/** + * Performs an optimistic-concurrency transactional update to the data at this location. Your block will be called with a FIRMutableData + * instance that contains the current data at this location. Your block should update this data to the value you + * wish to write to this location, and then return an instance of FIRTransactionResult with the new data. + * + * If, when the operation reaches the server, it turns out that this client had stale data, your block will be run + * again with the latest data from the server. + * + * When your block is run, you may decide to abort the transaction by return [FIRTransactionResult abort]. + * + * Since your block may be run multiple times, this client could see several immediate states that don't exist on the server. You can suppress those immediate states until the server confirms the final state of the transaction. + * + * @param block This block receives the current data at this location and must return an instance of FIRTransactionResult + * @param completionBlock This block will be triggered once the transaction is complete, whether it was successful or not. It will indicate if there was an error, whether or not the data was committed, and what the current value of the data at this location is. + * @param localEvents Set this to NO to suppress events raised for intermediate states, and only get events based on the final state of the transaction. + */ +- (void)runTransactionBlock:(FIRTransactionResult * (^) (FIRMutableData* currentData))block andCompletionBlock:(nullable void (^) (NSError *__nullable error, BOOL committed, FIRDataSnapshot *__nullable snapshot))completionBlock withLocalEvents:(BOOL)localEvents; + + +#pragma mark - Retrieving String Representation + +/** + * Gets the absolute URL of this Firebase Database location. + * + * @return The absolute URL of the referenced Firebase Database location. + */ +- (NSString *) description; + +#pragma mark - Properties + +/** + * Gets a FIRDatabaseReference for the parent location. + * If this instance refers to the root of your Firebase Database, it has no parent, + * and therefore parent( ) will return null. + * + * @return A FIRDatabaseReference for the parent location. + */ +@property (strong, readonly, nonatomic, nullable) FIRDatabaseReference * parent; + + +/** + * Gets a FIRDatabaseReference for the root location + * + * @return A new FIRDatabaseReference to root location. + */ +@property (strong, readonly, nonatomic) FIRDatabaseReference * root; + + +/** + * Gets the last token in a Firebase Database location (e.g. 'fred' in https://SampleChat.firebaseIO-demo.com/users/fred) + * + * @return The key of the location this reference points to. + */ +@property (strong, readonly, nonatomic, nullable) NSString* key; + +/** + * Gets the URL for the Firebase Database location referenced by this FIRDatabaseReference. + * + * @return The url of the location this reference points to. + */ +@property (strong, readonly, nonatomic) NSString* URL; + +/** + * Gets the FIRDatabase instance associated with this reference. + * + * @return The FIRDatabase object for this reference. + */ +@property (strong, readonly, nonatomic) FIRDatabase *database; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRMutableData.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRMutableData.h new file mode 100644 index 00000000..7445d715 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRMutableData.h @@ -0,0 +1,129 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A FIRMutableData instance is populated with data from a Firebase Database location. + * When you are using runTransactionBlock:, you will be given an instance containing the current + * data at that location. Your block will be responsible for updating that instance to the data + * you wish to save at that location, and then returning using [FIRTransactionResult successWithValue:]. + * + * To modify the data, set its value property to any of the native types support by Firebase Database: + * + * + NSNumber (includes BOOL) + * + NSDictionary + * + NSArray + * + NSString + * + nil / NSNull to remove the data + * + * Note that changes made to a child FIRMutableData instance will be visible to the parent. + */ +NS_SWIFT_NAME(MutableData) +@interface FIRMutableData : NSObject + + +#pragma mark - Inspecting and navigating the data + + +/** + * Returns boolean indicating whether this mutable data has children. + * + * @return YES if this data contains child nodes. + */ +- (BOOL) hasChildren; + + +/** + * Indicates whether this mutable data has a child at the given path. + * + * @param path A path string, consisting either of a single segment, like 'child', or multiple segments, 'a/deeper/child' + * @return YES if this data contains a child at the specified relative path + */ +- (BOOL) hasChildAtPath:(NSString *)path; + + +/** + * Used to obtain a FIRMutableData instance that encapsulates the data at the given relative path. + * Note that changes made to the child will be visible to the parent. + * + * @param path A path string, consisting either of a single segment, like 'child', or multiple segments, 'a/deeper/child' + * @return A FIRMutableData instance containing the data at the given path + */ +- (FIRMutableData *)childDataByAppendingPath:(NSString *)path; + + +#pragma mark - Properties + + +/** + * To modify the data contained by this instance of FIRMutableData, set this to any of the native types supported by Firebase Database: + * + * + NSNumber (includes BOOL) + * + NSDictionary + * + NSArray + * + NSString + * + nil / NSNull to remove the data + * + * Note that setting this value will override the priority at this location. + * + * @return The current data at this location as a native object + */ +@property (strong, nonatomic, nullable) id value; + + +/** + * Set this property to update the priority of the data at this location. Can be set to the following types: + * + * + NSNumber + * + NSString + * + nil / NSNull to remove the priority + * + * @return The priority of the data at this location + */ +@property (strong, nonatomic, nullable) id priority; + + +/** + * @return The number of child nodes at this location + */ +@property (readonly, nonatomic) NSUInteger childrenCount; + + +/** + * Used to iterate over the children at this location. You can use the native for .. in syntax: + * + * for (FIRMutableData* child in data.children) { + * ... + * } + * + * Note that this enumerator operates on an immutable copy of the child list. So, you can modify the instance + * during iteration, but the new additions will not be visible until you get a new enumerator. + */ +@property (readonly, nonatomic, strong) NSEnumerator* children; + + +/** + * @return The key name of this node, or nil if it is the top-most location + */ +@property (readonly, nonatomic, strong, nullable) NSString* key; + + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRServerValue.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRServerValue.h new file mode 100644 index 00000000..365590c8 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRServerValue.h @@ -0,0 +1,33 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +NS_ASSUME_NONNULL_BEGIN + +/** + * Placeholder values you may write into Firebase Database as a value or priority + * that will automatically be populated by the Firebase Database server. + */ +NS_SWIFT_NAME(ServerValue) +@interface FIRServerValue : NSObject + +/** + * Placeholder value for the number of milliseconds since the Unix epoch + */ ++ (NSDictionary *) timestamp; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRTransactionResult.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRTransactionResult.h new file mode 100644 index 00000000..d356c5c5 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FIRTransactionResult.h @@ -0,0 +1,46 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FIRMutableData.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * Used for runTransactionBlock:. An FIRTransactionResult instance is a container for the results of the transaction. + */ +NS_SWIFT_NAME(TransactionResult) +@interface FIRTransactionResult : NSObject + +/** + * Used for runTransactionBlock:. Indicates that the new value should be saved at this location + * + * @param value A FIRMutableData instance containing the new value to be set + * @return An FIRTransactionResult instance that can be used as a return value from the block given to runTransactionBlock: + */ ++ (FIRTransactionResult *)successWithValue:(FIRMutableData *)value; + + +/** + * Used for runTransactionBlock:. Indicates that the current transaction should no longer proceed. + * + * @return An FIRTransactionResult instance that can be used as a return value from the block given to runTransactionBlock: + */ ++ (FIRTransactionResult *) abort; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FirebaseDatabase.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FirebaseDatabase.h new file mode 100644 index 00000000..e52f5d62 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Public/FirebaseDatabase.h @@ -0,0 +1,29 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#ifndef FirebaseDatabase_h +#define FirebaseDatabase_h + +#import "FIRDatabase.h" +#import "FIRDatabaseQuery.h" +#import "FIRDatabaseReference.h" +#import "FIRDataEventType.h" +#import "FIRDataSnapshot.h" +#import "FIRMutableData.h" +#import "FIRServerValue.h" +#import "FIRTransactionResult.h" + +#endif /* FirebaseDatabase_h */ diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Realtime/FConnection.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Realtime/FConnection.h new file mode 100644 index 00000000..ed4879a2 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Realtime/FConnection.h @@ -0,0 +1,52 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FWebSocketConnection.h" +#import "FTypedefs.h" + +@protocol FConnectionDelegate; + +@interface FConnection : NSObject + +@property (nonatomic, weak) id delegate; + +- (id)initWith:(FRepoInfo *)aRepoInfo andDispatchQueue:(dispatch_queue_t)queue lastSessionID:(NSString *)lastSessionID; + +- (void)open; +- (void)close; +- (void)sendRequest:(NSDictionary *)dataMsg sensitive:(BOOL)sensitive; + +// FWebSocketDelegate delegate methods +- (void)onMessage:(FWebSocketConnection *)fwebSocket withMessage:(NSDictionary *)message; +- (void)onDisconnect:(FWebSocketConnection *)fwebSocket wasEverConnected:(BOOL)everConnected; + +@end + +typedef enum { + DISCONNECT_REASON_SERVER_RESET = 0, + DISCONNECT_REASON_OTHER = 1 +} FDisconnectReason; + +@protocol FConnectionDelegate + +- (void)onReady:(FConnection *)fconnection atTime:(NSNumber *)timestamp sessionID:(NSString *)sessionID; +- (void)onDataMessage:(FConnection *)fconnection withMessage:(NSDictionary *)message; +- (void)onDisconnect:(FConnection *)fconnection withReason:(FDisconnectReason)reason; +- (void)onKill:(FConnection *)fconnection withReason:(NSString *)reason; + +@end + diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Realtime/FConnection.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Realtime/FConnection.m new file mode 100644 index 00000000..08014f6e --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Realtime/FConnection.m @@ -0,0 +1,212 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FConnection.h" +#import "FConstants.h" + +typedef enum { + REALTIME_STATE_CONNECTING = 0, + REALTIME_STATE_CONNECTED = 1, + REALTIME_STATE_DISCONNECTED = 2, +} FConnectionState; + +@interface FConnection () { + FConnectionState state; +} + +@property (nonatomic, strong) FWebSocketConnection* conn; +@property (nonatomic, strong) FRepoInfo* repoInfo; + +@end + +#pragma mark - +#pragma mark FConnection implementation + +@implementation FConnection + +@synthesize delegate; +@synthesize conn; +@synthesize repoInfo; + +#pragma mark - +#pragma mark Initializers + +- (id)initWith:(FRepoInfo *)aRepoInfo andDispatchQueue:(dispatch_queue_t)queue lastSessionID:(NSString *)lastSessionID{ + self = [super init]; + if (self) { + state = REALTIME_STATE_CONNECTING; + self.repoInfo = aRepoInfo; + self.conn = [[FWebSocketConnection alloc] initWith:self.repoInfo andQueue:queue lastSessionID:lastSessionID]; + self.conn.delegate = self; + } + return self; +} + +#pragma mark - +#pragma mark Public method implementation + +- (void)open { + FFLog(@"I-RDB082001", @"Calling open in FConnection"); + [self.conn open]; +} + +- (void) closeWithReason:(FDisconnectReason)reason { + if (state != REALTIME_STATE_DISCONNECTED) { + FFLog(@"I-RDB082002", @"Closing realtime connection."); + state = REALTIME_STATE_DISCONNECTED; + + if (self.conn) { + FFLog(@"I-RDB082003", @"Calling close again."); + [self.conn close]; + self.conn = nil; + } + + [self.delegate onDisconnect:self withReason:reason]; + } +} + +- (void) close { + [self closeWithReason:DISCONNECT_REASON_OTHER]; +} + +- (void) sendRequest:(NSDictionary *)dataMsg sensitive:(BOOL)sensitive { + // since this came from the persistent connection, wrap it in a data message envelope + NSDictionary* msg = @{ + kFWPRequestType: kFWPRequestTypeData, + kFWPRequestDataPayload: dataMsg + }; + [self sendData:msg sensitive:sensitive]; +} + +#pragma mark - +#pragma mark Helpers + + +- (void) sendData:(NSDictionary *)data sensitive:(BOOL)sensitive { + if (state != REALTIME_STATE_CONNECTED) { + @throw [[NSException alloc] initWithName:@"InvalidConnectionState" reason:@"Tried to send data on an unconnected FConnection" userInfo:nil]; + } else { + if (sensitive) { + FFLog(@"I-RDB082004", @"Sending data (contents hidden)"); + } else { + FFLog(@"I-RDB082005", @"Sending: %@", data); + } + [self.conn send:data]; + } +} + +#pragma mark - +#pragma mark FWebSocketConnectinDelegate implementation + +// Corresponds to onConnectionLost in JS +- (void)onDisconnect:(FWebSocketConnection *)fwebSocket wasEverConnected:(BOOL)everConnected { + + self.conn = nil; + if (!everConnected && state == REALTIME_STATE_CONNECTING) { + FFLog(@"I-RDB082006", @"Realtime connection failed."); + + // Since we failed to connect at all, clear any cached entry for this namespace in case the machine went away + [self.repoInfo clearInternalHostCache]; + } else if (state == REALTIME_STATE_CONNECTED) { + FFLog(@"I-RDB082007", @"Realtime connection lost."); + } + + [self close]; +} + +// Corresponds to onMessageReceived in JS +- (void)onMessage:(FWebSocketConnection *)fwebSocket withMessage:(NSDictionary *)message { + NSString* rawMessageType = [message objectForKey:kFWPAsyncServerEnvelopeType]; + if(rawMessageType != nil) { + if([rawMessageType isEqualToString:kFWPAsyncServerDataMessage]) { + [self onDataMessage:[message objectForKey:kFWPAsyncServerEnvelopeData]]; + } + else if ([rawMessageType isEqualToString:kFWPAsyncServerControlMessage]) { + [self onControl:[message objectForKey:kFWPAsyncServerEnvelopeData]]; + } + else { + FFLog(@"I-RDB082008", @"Unrecognized server packet type: %@", rawMessageType); + } + } + else { + FFLog(@"I-RDB082009", @"Unrecognized raw server packet received: %@", message); + } +} + +- (void) onDataMessage:(NSDictionary *)message { + // we don't do anything with data messages, just kick them up a level + FFLog(@"I-RDB082010", @"Got data message: %@", message); + [self.delegate onDataMessage:self withMessage:message]; +} + +- (void) onControl:(NSDictionary *)message { + FFLog(@"I-RDB082011", @"Got control message: %@", message); + NSString* type = [message objectForKey:kFWPAsyncServerControlMessageType]; + if([type isEqualToString:kFWPAsyncServerControlMessageShutdown]) { + NSString* reason = [message objectForKey:kFWPAsyncServerControlMessageData]; + [self onConnectionShutdownWithReason:reason]; + } + else if ([type isEqualToString:kFWPAsyncServerControlMessageReset]) { + NSString* host = [message objectForKey:kFWPAsyncServerControlMessageData]; + [self onReset:host]; + } + else if ([type isEqualToString:kFWPAsyncServerHello]) { + NSDictionary* handshakeData = [message objectForKey:kFWPAsyncServerControlMessageData]; + [self onHandshake:handshakeData]; + } + else { + FFLog(@"I-RDB082012", @"Unknown control message returned from server: %@", message); + } +} + +- (void) onConnectionShutdownWithReason:(NSString *)reason { + FFLog(@"I-RDB082013", @"Connection shutdown command received. Shutting down..."); + + [self.delegate onKill:self withReason:reason]; + [self close]; +} + +- (void) onHandshake:(NSDictionary *)handshake { + NSNumber* timestamp = [handshake objectForKey:kFWPAsyncServerHelloTimestamp]; +// NSString* version = [handshake objectForKey:kFWPAsyncServerHelloVersion]; + NSString* host = [handshake objectForKey:kFWPAsyncServerHelloConnectedHost]; + NSString* sessionID = [handshake objectForKey:kFWPAsyncServerHelloSession]; + + self.repoInfo.internalHost = host; + + if (state == REALTIME_STATE_CONNECTING) { + [self.conn start]; + [self onConnection:self.conn readyAtTime:timestamp sessionID:sessionID]; + } +} + +- (void) onConnection:(FWebSocketConnection *)conn readyAtTime:(NSNumber *)timestamp sessionID:(NSString *)sessionID { + FFLog(@"I-RDB082014", @"Realtime connection established"); + state = REALTIME_STATE_CONNECTED; + + [self.delegate onReady:self atTime:timestamp sessionID:sessionID]; +} + +- (void) onReset:(NSString *)host { + FFLog(@"I-RDB082015", @"Got a reset; killing connection to: %@; Updating internalHost to: %@", repoInfo.internalHost, host); + self.repoInfo.internalHost = host; + + // Explicitly close the connection with SERVER_RESET so calling code knows to reconnect immediately. + [self closeWithReason:DISCONNECT_REASON_SERVER_RESET]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Realtime/FWebSocketConnection.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Realtime/FWebSocketConnection.h new file mode 100644 index 00000000..6a14d471 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Realtime/FWebSocketConnection.h @@ -0,0 +1,46 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FSRWebSocket.h" +#import "FUtilities.h" + +@protocol FWebSocketDelegate; + +@interface FWebSocketConnection : NSObject + +@property (nonatomic, weak) id delegate; + +- (id)initWith:(FRepoInfo *)repoInfo andQueue:(dispatch_queue_t)queue lastSessionID:(NSString *)lastSessionID; + +- (void) open; +- (void) close; +- (void) start; +- (void) send:(NSDictionary *)dictionary; + +- (void)webSocket:(FSRWebSocket *)webSocket didReceiveMessage:(id)message; +- (void)webSocketDidOpen:(FSRWebSocket *)webSocket; +- (void)webSocket:(FSRWebSocket *)webSocket didFailWithError:(NSError *)error; +- (void)webSocket:(FSRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean; + +@end + +@protocol FWebSocketDelegate + +- (void)onMessage:(FWebSocketConnection *)fwebSocket withMessage:(NSDictionary *)message; +- (void)onDisconnect:(FWebSocketConnection *)fwebSocket wasEverConnected:(BOOL)everConnected; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Realtime/FWebSocketConnection.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Realtime/FWebSocketConnection.m new file mode 100644 index 00000000..49d6bd8f --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Realtime/FWebSocketConnection.m @@ -0,0 +1,308 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +// Targetted compilation is ONLY for testing. UIKit is weak-linked in actual release build. + +#import + +#import +#import "FWebSocketConnection.h" +#import "FConstants.h" +#import "FIRDatabaseReference.h" +#import "FStringUtilities.h" +#import "FIRDatabase_Private.h" + +#if TARGET_OS_IOS || TARGET_OS_TV +#import +#endif + +@interface FWebSocketConnection () { + NSMutableString* frame; + BOOL everConnected; + BOOL isClosed; + NSTimer* keepAlive; +} + +- (void) shutdown; +- (void) onClosed; +- (void) closeIfNeverConnected; + +@property (nonatomic, strong) FSRWebSocket* webSocket; +@property (nonatomic, strong) NSNumber* connectionId; +@property (nonatomic, readwrite) int totalFrames; +@property (nonatomic, readonly) BOOL buffering; +@property (nonatomic, readonly) NSString* userAgent; +@property (nonatomic) dispatch_queue_t dispatchQueue; + +- (void)nop:(NSTimer *)timer; + +@end + +@implementation FWebSocketConnection + +@synthesize delegate; +@synthesize webSocket; +@synthesize connectionId; + +- (id)initWith:(FRepoInfo *)repoInfo andQueue:(dispatch_queue_t)queue lastSessionID:(NSString *)lastSessionID { + self = [super init]; + if (self) { + everConnected = NO; + isClosed = NO; + self.connectionId = [FUtilities LUIDGenerator]; + self.totalFrames = 0; + self.dispatchQueue = queue; + frame = nil; + + NSString* connectionUrl = [repoInfo connectionURLWithLastSessionID:lastSessionID]; + NSString* ua = [self userAgent]; + FFLog(@"I-RDB083001", @"(wsc:%@) Connecting to: %@ as %@", self.connectionId, connectionUrl, ua); + + NSURLRequest* req = [[NSURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:connectionUrl]]; + self.webSocket = [[FSRWebSocket alloc] initWithURLRequest:req queue:queue andUserAgent:ua]; + [self.webSocket setDelegateDispatchQueue:queue]; + self.webSocket.delegate = self; + } + return self; +} + +- (NSString *) userAgent { + NSString* systemVersion; + NSString* deviceName; + BOOL hasUiDeviceClass = NO; + + // Targetted compilation is ONLY for testing. UIKit is weak-linked in actual release build. + #if TARGET_OS_IOS || TARGET_OS_TV + Class uiDeviceClass = NSClassFromString(@"UIDevice"); + if (uiDeviceClass) { + systemVersion = [uiDeviceClass currentDevice].systemVersion; + deviceName = [uiDeviceClass currentDevice].model; + hasUiDeviceClass = YES; + } + #endif + + if (!hasUiDeviceClass) { + NSDictionary *systemVersionDictionary = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"]; + systemVersion = [systemVersionDictionary objectForKey:@"ProductVersion"]; + deviceName = [systemVersionDictionary objectForKey:@"ProductName"]; + } + + NSString* bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier]; + + // Sanitize '/'s in deviceName and bundleIdentifier for stats + deviceName = [FStringUtilities sanitizedForUserAgent:deviceName]; + bundleIdentifier = [FStringUtilities sanitizedForUserAgent:bundleIdentifier]; + + // Firebase/5/__//{device model / os (Mac OS X, iPhone, etc.}_ + NSString* ua = [NSString stringWithFormat:@"Firebase/%@/%@/%@/%@_%@", kWebsocketProtocolVersion, [FIRDatabase buildVersion], systemVersion, deviceName, bundleIdentifier]; + return ua; +} + +- (BOOL) buffering { + return frame != nil; +} + +#pragma mark - +#pragma mark Public FWebSocketConnection methods + +- (void) open { + FFLog(@"I-RDB083002", @"(wsc:%@) FWebSocketConnection open.", self.connectionId); + assert(delegate); + everConnected = NO; + // TODO Assert url + [self.webSocket open]; + dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, kWebsocketConnectTimeout * NSEC_PER_SEC); + dispatch_after(when, self.dispatchQueue, ^{ + [self closeIfNeverConnected]; + }); +} + +- (void) close { + FFLog(@"I-RDB083003", @"(wsc:%@) FWebSocketConnection is being closed.", self.connectionId); + isClosed = YES; + [self.webSocket close]; +} + +- (void) start { + // Start is a no-op for websockets. +} + +- (void) send:(NSDictionary *)dictionary { + + [self resetKeepAlive]; + + NSData* jsonData = [NSJSONSerialization dataWithJSONObject:dictionary + options:kNilOptions error:nil]; + + NSString* data = [[NSString alloc] initWithData:jsonData + encoding:NSUTF8StringEncoding]; + + NSArray* dataSegs = [FUtilities splitString:data intoMaxSize:kWebsocketMaxFrameSize]; + + // First send the header so the server knows how many segments are forthcoming + if (dataSegs.count > 1) { + [self.webSocket send:[NSString stringWithFormat:@"%u", (unsigned int)dataSegs.count]]; + } + + // Then, actually send the segments. + for(NSString * segment in dataSegs) { + [self.webSocket send:segment]; + } +} + +- (void) nop:(NSTimer *)timer { + if (!isClosed) { + FFLog(@"I-RDB083004", @"(wsc:%@) nop", self.connectionId); + [self.webSocket send:@"0"]; + } + else { + FFLog(@"I-RDB083005", @"(wsc:%@) No more websocket; invalidating nop timer.", self.connectionId); + [timer invalidate]; + } +} + +- (void) handleNewFrameCount:(int) numFrames { + self.totalFrames = numFrames; + frame = [[NSMutableString alloc] initWithString:@""]; + FFLog(@"I-RDB083006", @"(wsc:%@) handleNewFrameCount: %d", self.connectionId, self.totalFrames); +} + +- (NSString *) extractFrameCount:(NSString *) message { + if ([message length] <= 4) { + int frameCount = [message intValue]; + if (frameCount > 0) { + [self handleNewFrameCount:frameCount]; + return nil; + } + } + [self handleNewFrameCount:1]; + return message; +} + +- (void) appendFrame:(NSString *) message { + [frame appendString:message]; + self.totalFrames = self.totalFrames - 1; + + if (self.totalFrames == 0) { + // Call delegate and pass an immutable version of the frame + NSDictionary* json = [NSJSONSerialization JSONObjectWithData:[frame dataUsingEncoding:NSUTF8StringEncoding] + options:kNilOptions + error:nil]; + frame = nil; + FFLog(@"I-RDB083007", @"(wsc:%@) handleIncomingFrame sending complete frame: %d", self.connectionId, self.totalFrames); + + @autoreleasepool { + [self.delegate onMessage:self withMessage:json]; + } + } +} + +- (void) handleIncomingFrame:(NSString *) message { + [self resetKeepAlive]; + if (self.buffering) { + [self appendFrame:message]; + } else { + NSString *remaining = [self extractFrameCount:message]; + if (remaining) { + [self appendFrame:remaining]; + } + } +} + +#pragma mark - +#pragma mark SRWebSocketDelegate implementation +- (void)webSocket:(FSRWebSocket *)webSocket didReceiveMessage:(id)message +{ + [self handleIncomingFrame:message]; +} + +- (void)webSocketDidOpen:(FSRWebSocket *)webSocket +{ + FFLog(@"I-RDB083008", @"(wsc:%@) webSocketDidOpen", self.connectionId); + + everConnected = YES; + + dispatch_async(dispatch_get_main_queue(), ^{ + self->keepAlive = [NSTimer scheduledTimerWithTimeInterval:kWebsocketKeepaliveInterval + target:self + selector:@selector(nop:) + userInfo:nil + repeats:YES]; + FFLog(@"I-RDB083009", @"(wsc:%@) nop timer kicked off", self.connectionId); + }); +} + +- (void)webSocket:(FSRWebSocket *)webSocket didFailWithError:(NSError *)error +{ + FFLog(@"I-RDB083010", @"(wsc:%@) didFailWithError didFailWithError: %@", self.connectionId, [error description]); + [self onClosed]; +} + +- (void)webSocket:(FSRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean +{ + FFLog(@"I-RDB083011", @"(wsc:%@) didCloseWithCode: %ld %@", self.connectionId, (long)code, reason); + [self onClosed]; +} + +#pragma mark - +#pragma mark Private methods + +/** + * Note that the close / onClosed / shutdown cycle here is a little different from the javascript client. + * In order to properly handle deallocation, no close-related action is taken at a higher level until we + * have received notification from the websocket itself that it is closed. Otherwise, we end up deallocating + * this class and the FConnection class before the websocket has a change to call some of its delegate methods. + * So, since close is the external close handler, we just set a flag saying not to call our own delegate method + * and close the websocket. That will trigger a callback into this class that can then do things like clean up + * the keepalive timer. + */ + +- (void) closeIfNeverConnected { + if (!everConnected) { + FFLog(@"I-RDB083012", @"(wsc:%@) Websocket timed out on connect", self.connectionId); + [self.webSocket close]; + } +} + +- (void) shutdown { + isClosed = YES; + + // Call delegate methods + [self.delegate onDisconnect:self wasEverConnected:everConnected]; + +} + +- (void) onClosed { + if (!isClosed) { + FFLog(@"I-RDB083013", @"Websocket is closing itself"); + [self shutdown]; + } + self.webSocket = nil; + if (keepAlive.isValid) { + [keepAlive invalidate]; + } +} + +- (void) resetKeepAlive { + NSDate* newTime = [NSDate dateWithTimeIntervalSinceNow:kWebsocketKeepaliveInterval]; + // Calling setFireDate is actually kinda' expensive, so wait at least 5 seconds before updating it. + if ([newTime timeIntervalSinceDate:keepAlive.fireDate] > 5) { + FFLog(@"I-RDB083014", @"(wsc:%@) resetting keepalive, to %@ ; old: %@", self.connectionId, newTime, [keepAlive fireDate]); + [keepAlive setFireDate:newTime]; + } +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FChildrenNode.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FChildrenNode.h new file mode 100644 index 00000000..9eebdae4 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FChildrenNode.h @@ -0,0 +1,40 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FNode.h" +#import "FTypedefs.h" +#import "FTypedefs_Private.h" +#import "FImmutableSortedDictionary.h" + +@class FNamedNode; + +@interface FChildrenNode : NSObject + +- (id)initWithChildren:(FImmutableSortedDictionary *)someChildren; +- (id)initWithPriority:(id)aPriority children:(FImmutableSortedDictionary *)someChildren; + +// FChildrenNode specific methods + +- (void) enumerateChildrenAndPriorityUsingBlock:(void (^)(NSString *, id, BOOL *))block; + +- (FNamedNode *) firstChild; +- (FNamedNode *) lastChild; + +@property (nonatomic, strong) FImmutableSortedDictionary* children; +@property (nonatomic, strong) id priorityNode; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FChildrenNode.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FChildrenNode.m new file mode 100644 index 00000000..d53ae806 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FChildrenNode.m @@ -0,0 +1,385 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FChildrenNode.h" +#import "FEmptyNode.h" +#import "FConstants.h" +#import "FStringUtilities.h" +#import "FUtilities.h" +#import "FNamedNode.h" +#import "FMaxNode.h" +#import "FTransformedEnumerator.h" +#import "FSnapshotUtilities.h" +#import "FTransformedEnumerator.h" +#import "FPriorityIndex.h" +#import "FUtilities.h" + +@interface FChildrenNode () +@property (nonatomic, strong) NSString *lazyHash; +@end + +@implementation FChildrenNode + +// Note: The only reason we allow nil priority is to for EmptyNode, since we can't use +// EmptyNode as the priority of EmptyNode. We might want to consider making EmptyNode its own +// class instead of an empty ChildrenNode. + +- (id)init { + return [self initWithPriority:nil children:[FImmutableSortedDictionary dictionaryWithComparator:[FUtilities keyComparator]]]; +} + +- (id)initWithChildren:(FImmutableSortedDictionary *)someChildren { + return [self initWithPriority:nil children:someChildren]; +} + +- (id)initWithPriority:(id)aPriority children:(FImmutableSortedDictionary *)someChildren { + if (someChildren.isEmpty && aPriority != nil && ![aPriority isEmpty]) { + [NSException raise:NSInvalidArgumentException format:@"Can't create empty node with priority!"]; + } + self = [super init]; + if(self) { + self.children = someChildren; + self.priorityNode = aPriority; + } + return self; +} + +- (NSString *) description { + return [[self valForExport:YES] description]; +} + +#pragma mark - +#pragma mark FNode methods + + +- (BOOL) isLeafNode { + return NO; +} + +- (id) getPriority { + if (self.priorityNode) { + return self.priorityNode; + } else { + return [FEmptyNode emptyNode]; + } + +} + +- (id) updatePriority:(id)aPriority { + if ([self.children isEmpty]) { + return [FEmptyNode emptyNode]; + } else { + return [[FChildrenNode alloc] initWithPriority:aPriority children:self.children]; + } +} + +- (id) getImmediateChild:(NSString *) childName { + if ([childName isEqualToString:@".priority"]) { + return [self getPriority]; + } else { + id child = [self.children objectForKey:childName]; + return (child == nil) ? [FEmptyNode emptyNode] : child; + } +} + +- (id) getChild:(FPath *)path { + NSString* front = [path getFront]; + if(front == nil) { + return self; + } + else { + return [[self getImmediateChild:front] getChild:[path popFront]]; + } +} + +- (BOOL)hasChild:(NSString *)childName { + return ![self getImmediateChild:childName].isEmpty; +} + + +- (id) updateImmediateChild:(NSString *)childName withNewChild:(id)newChildNode { + NSAssert(newChildNode != nil, @"Should always be passing nodes."); + + if ([childName isEqualToString:@".priority"]) { + return [self updatePriority:newChildNode]; + } else { + FImmutableSortedDictionary *newChildren; + if (newChildNode.isEmpty) { + newChildren = [self.children removeObjectForKey:childName]; + } else { + newChildren = [self.children setObject:newChildNode forKey:childName]; + } + if (newChildren.isEmpty) { + return [FEmptyNode emptyNode]; + } else { + return [[FChildrenNode alloc] initWithPriority:self.getPriority children:newChildren]; + } + } +} + +- (id) updateChild:(FPath *)path withNewChild:(id)newChildNode { + NSString* front = [path getFront]; + if(front == nil) { + return newChildNode; + } else { + NSAssert(![front isEqualToString:@".priority"] || path.length == 1, @".priority must be the last token in a path."); + id newImmediateChild = [[self getImmediateChild:front] updateChild:[path popFront] withNewChild:newChildNode]; + return [self updateImmediateChild:front withNewChild:newImmediateChild]; + } +} + +- (BOOL) isEmpty { + return [self.children isEmpty]; +} + +- (int) numChildren { + return [self.children count]; +} + +- (id) val { + return [self valForExport:NO]; +} + +- (id) valForExport:(BOOL)exp { + if([self isEmpty]) { + return [NSNull null]; + } + + __block int numKeys = 0; + __block NSInteger maxKey = 0; + __block BOOL allIntegerKeys = YES; + + NSMutableDictionary* obj = [[NSMutableDictionary alloc] initWithCapacity:[self.children count]]; + [self enumerateChildrenUsingBlock:^(NSString *key, id childNode, BOOL *stop) { + [obj setObject:[childNode valForExport:exp] forKey:key]; + + numKeys++; + + // If we already found a string key, don't bother with any of this + if (!allIntegerKeys) { + return; + } + + // Treat leading zeroes that are not exactly "0" as strings + NSString* firstChar = [key substringWithRange:NSMakeRange(0, 1)]; + if ([firstChar isEqualToString:@"0"] && [key length] > 1) { + allIntegerKeys = NO; + } else { + NSNumber *keyAsNum = [FUtilities intForString:key]; + if (keyAsNum != nil) { + NSInteger keyAsInt = [keyAsNum integerValue]; + if (keyAsInt > maxKey) { + maxKey = keyAsInt; + } + } else { + allIntegerKeys = NO; + } + } + }]; + + if (!exp && allIntegerKeys && maxKey < 2 * numKeys) { + // convert to an array + NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity:maxKey + 1]; + for (int i = 0; i <= maxKey; ++i) { + NSString* keyString = [NSString stringWithFormat:@"%i", i]; + id child = obj[keyString]; + if (child != nil) { + [array addObject:child]; + } else { + [array addObject:[NSNull null]]; + } + } + return array; + } else { + + if(exp && [self getPriority] != nil && !self.getPriority.isEmpty) { + obj[kPayloadPriority] = [self.getPriority val]; + } + + return obj; + } +} + +- (NSString *) dataHash { + if (self.lazyHash == nil) { + NSMutableString *toHash = [[NSMutableString alloc] init]; + + if (!self.getPriority.isEmpty) { + [toHash appendString:@"priority:"]; + [FSnapshotUtilities appendHashRepresentationForLeafNode:(FLeafNode *)self.getPriority + toString:toHash + hashVersion:FDataHashVersionV1]; + [toHash appendString:@":"]; + } + + __block BOOL sawPriority = NO; + [self enumerateChildrenUsingBlock:^(NSString *key, id node, BOOL *stop) { + sawPriority = sawPriority || [[node getPriority] isEmpty]; + *stop = sawPriority; + }]; + if (sawPriority) { + NSMutableArray *array = [NSMutableArray array]; + [self enumerateChildrenUsingBlock:^(NSString *key, id node, BOOL *stop) { + FNamedNode *namedNode = [[FNamedNode alloc] initWithName:key andNode:node]; + [array addObject:namedNode]; + }]; + [array sortUsingComparator:^NSComparisonResult(FNamedNode *namedNode1, FNamedNode *namedNode2) { + return [[FPriorityIndex priorityIndex] compareNamedNode:namedNode1 toNamedNode:namedNode2]; + }]; + [array enumerateObjectsUsingBlock:^(FNamedNode *namedNode, NSUInteger idx, BOOL *stop) { + NSString *childHash = [namedNode.node dataHash]; + if (![childHash isEqualToString:@""]) { + [toHash appendFormat:@":%@:%@", namedNode.name, childHash]; + } + }]; + } else { + [self enumerateChildrenUsingBlock:^(NSString *key, id node, BOOL *stop) { + NSString *childHash = [node dataHash]; + if (![childHash isEqualToString:@""]) { + [toHash appendFormat:@":%@:%@", key, childHash]; + } + }]; + } + self.lazyHash = [toHash isEqualToString:@""] ? @"" : [FStringUtilities base64EncodedSha1:toHash]; + } + return self.lazyHash; +} + +- (NSComparisonResult)compare:(id )other { + // children nodes come last, unless this is actually an empty node, then we come first. + if (self.isEmpty) { + if (other.isEmpty) { + return NSOrderedSame; + } else { + return NSOrderedAscending; + } + } else if (other.isLeafNode || other.isEmpty) { + return NSOrderedDescending; + } else if (other == [FMaxNode maxNode]) { + return NSOrderedAscending; + } else { + // Must be another node with children. + return NSOrderedSame; + } +} + +- (BOOL)isEqual:(id )other { + if (other == self) { + return YES; + } else if (other == nil) { + return NO; + } else if (other.isLeafNode) { + return NO; + } else if (self.isEmpty && [other isEmpty]) { + // Empty nodes do not have priority + return YES; + } else { + FChildrenNode *otherChildrenNode = other; + if (![self.getPriority isEqual:other.getPriority]) { + return NO; + } else if (self.children.count == otherChildrenNode.children.count) { + __block BOOL equal = YES; + [self enumerateChildrenUsingBlock:^(NSString *key, id node, BOOL *stop) { + id child = [otherChildrenNode getImmediateChild:key]; + if (![child isEqual:node]) { + equal = NO; + *stop = YES; + } + }]; + return equal; + } else { + return NO; + } + } +} + +- (NSUInteger)hash { + __block NSUInteger hashCode = 0; + [self enumerateChildrenUsingBlock:^(NSString *key, id node, BOOL *stop) { + hashCode = 31 * hashCode + key.hash; + hashCode = 17 * hashCode + node.hash; + }]; + return 17 * hashCode + self.priorityNode.hash; +} + +- (void) enumerateChildrenAndPriorityUsingBlock:(void (^)(NSString *, id, BOOL *))block +{ + if ([self.getPriority isEmpty]) { + [self enumerateChildrenUsingBlock:block]; + } else { + __block BOOL passedPriorityKey = NO; + [self enumerateChildrenUsingBlock:^(NSString *key, id node, BOOL *stop) { + if (!passedPriorityKey && [FUtilities compareKey:key toKey:@".priority"] == NSOrderedDescending) { + passedPriorityKey = YES; + BOOL stopAfterPriority = NO; + block(@".priority", [self getPriority], &stopAfterPriority); + if (stopAfterPriority) return; + } + block(key, node, stop); + }]; + } +} + +- (void) enumerateChildrenUsingBlock:(void (^)(NSString *, id, BOOL *))block +{ + [self.children enumerateKeysAndObjectsUsingBlock:block]; +} + +- (void) enumerateChildrenReverse:(BOOL)reverse usingBlock:(void (^)(NSString *, id, BOOL *))block +{ + [self.children enumerateKeysAndObjectsReverse:reverse usingBlock:block]; +} + +- (NSEnumerator *)childEnumerator +{ + return [[FTransformedEnumerator alloc] initWithEnumerator:self.children.keyEnumerator andTransform:^id(NSString *key) { + return [FNamedNode nodeWithName:key node:[self getImmediateChild:key]]; + }]; +} + +- (NSString *) predecessorChildKey:(NSString *)childKey +{ + return [self.children getPredecessorKey:childKey]; +} + +#pragma mark - +#pragma mark FChildrenNode specific methods + +- (id) childrenGetter:(id)key { + return [self.children objectForKey:key]; +} + +- (FNamedNode *)firstChild +{ + NSString *childKey = self.children.minKey; + if (childKey) { + return [[FNamedNode alloc] initWithName:childKey andNode:[self getImmediateChild:childKey]]; + } else { + return nil; + } +} + +- (FNamedNode *)lastChild +{ + NSString *childKey = self.children.maxKey; + if (childKey) { + return [[FNamedNode alloc] initWithName:childKey andNode:[self getImmediateChild:childKey]]; + } else { + return nil; + } +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FCompoundWrite.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FCompoundWrite.h new file mode 100644 index 00000000..c67cfc7b --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FCompoundWrite.h @@ -0,0 +1,61 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class FImmutableTree; +@protocol FNode; +@class FPath; + +/** +* This class holds a collection of writes that can be applied to nodes in unison. It abstracts away the logic with +* dealing with priority writes and multiple nested writes. At any given path, there is only allowed to be one write +* modifying that path. Any write to an existing path or shadowing an existing path will modify that existing write to +* reflect the write added. +*/ +@interface FCompoundWrite : NSObject + +- (id) initWithWriteTree:(FImmutableTree *)tree; + +/** + * Creates a compound write with NSDictionary from path string to object + */ ++ (FCompoundWrite *) compoundWriteWithValueDictionary:(NSDictionary *)dictionary; +/** + * Creates a compound write with NSDictionary from path string to node + */ ++ (FCompoundWrite *) compoundWriteWithNodeDictionary:(NSDictionary *)dictionary; + ++ (FCompoundWrite *) emptyWrite; + +- (FCompoundWrite *) addWrite:(id)node atPath:(FPath *)path; +- (FCompoundWrite *) addWrite:(id)node atKey:(NSString *)key; +- (FCompoundWrite *) addCompoundWrite:(FCompoundWrite *)node atPath:(FPath *)path; +- (FCompoundWrite *) removeWriteAtPath:(FPath *)path; +- (id)rootWrite; +- (BOOL) hasCompleteWriteAtPath:(FPath *)path; +- (id) completeNodeAtPath:(FPath *)path; +- (NSArray *) completeChildren; +- (NSDictionary *)childCompoundWrites; +- (FCompoundWrite *) childCompoundWriteAtPath:(FPath *)path; +- (id) applyToNode:(id)node; +- (void)enumerateWrites:(void (^)(FPath *path, idnode, BOOL *stop))block; + +- (NSDictionary *)valForExport:(BOOL)exportFormat; + +- (BOOL) isEmpty; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FCompoundWrite.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FCompoundWrite.m new file mode 100644 index 00000000..88870951 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FCompoundWrite.m @@ -0,0 +1,257 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FCompoundWrite.h" +#import "FImmutableTree.h" +#import "FNode.h" +#import "FPath.h" +#import "FNamedNode.h" +#import "FSnapshotUtilities.h" + +@interface FCompoundWrite () +@property (nonatomic, strong) FImmutableTree *writeTree; +@end + +@implementation FCompoundWrite + +- (id) initWithWriteTree:(FImmutableTree *)tree { + self = [super init]; + if (self) { + self.writeTree = tree; + } + return self; +} + ++ (FCompoundWrite *)compoundWriteWithValueDictionary:(NSDictionary *)dictionary { + __block FImmutableTree *writeTree = [FImmutableTree empty]; + [dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *pathString, id value, BOOL *stop) { + id node = [FSnapshotUtilities nodeFrom:value]; + FImmutableTree *tree = [[FImmutableTree alloc] initWithValue:node]; + writeTree = [writeTree setTree:tree atPath:[[FPath alloc] initWith:pathString]]; + }]; + return [[FCompoundWrite alloc] initWithWriteTree:writeTree]; +} + ++ (FCompoundWrite *)compoundWriteWithNodeDictionary:(NSDictionary *)dictionary { + __block FImmutableTree *writeTree = [FImmutableTree empty]; + [dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *pathString, id node, BOOL *stop) { + FImmutableTree *tree = [[FImmutableTree alloc] initWithValue:node]; + writeTree = [writeTree setTree:tree atPath:[[FPath alloc] initWith:pathString]]; + }]; + return [[FCompoundWrite alloc] initWithWriteTree:writeTree]; +} + ++ (FCompoundWrite *) emptyWrite { + static dispatch_once_t pred = 0; + static FCompoundWrite *empty = nil; + dispatch_once(&pred, ^{ + empty = [[FCompoundWrite alloc] initWithWriteTree:[[FImmutableTree alloc] initWithValue:nil]]; + }); + return empty; +} + +- (FCompoundWrite *) addWrite:(id)node atPath:(FPath *)path { + if (path.isEmpty) { + return [[FCompoundWrite alloc] initWithWriteTree:[[FImmutableTree alloc] initWithValue:node]]; + } else { + FTuplePathValue *rootMost = [self.writeTree findRootMostValueAndPath:path]; + if (rootMost != nil) { + FPath *relativePath = [FPath relativePathFrom:rootMost.path to:path]; + id value = [rootMost.value updateChild:relativePath withNewChild:node]; + return [[FCompoundWrite alloc] initWithWriteTree:[self.writeTree setValue:value atPath:rootMost.path]]; + } else { + FImmutableTree *subtree = [[FImmutableTree alloc] initWithValue:node]; + FImmutableTree *newWriteTree = [self.writeTree setTree:subtree atPath:path]; + return [[FCompoundWrite alloc] initWithWriteTree:newWriteTree]; + } + } +} + +- (FCompoundWrite *) addWrite:(id)node atKey:(NSString *)key { + return [self addWrite:node atPath:[[FPath alloc] initWith:key]]; +} + +- (FCompoundWrite *) addCompoundWrite:(FCompoundWrite *)compoundWrite atPath:(FPath *)path { + __block FCompoundWrite *newWrite = self; + [compoundWrite.writeTree forEach:^(FPath *childPath, id value) { + newWrite = [newWrite addWrite:value atPath:[path child:childPath]]; + }]; + return newWrite; +} + +/** +* Will remove a write at the given path and deeper paths. This will not modify a write at a higher location, +* which must be removed by calling this method with that path. +* @param path The path at which a write and all deeper writes should be removed. +* @return The new FWriteCompound with the removed path. +*/ +- (FCompoundWrite *) removeWriteAtPath:(FPath *)path { + if (path.isEmpty) { + return [FCompoundWrite emptyWrite]; + } else { + FImmutableTree *newWriteTree = [self.writeTree setTree:[FImmutableTree empty] atPath:path]; + return [[FCompoundWrite alloc] initWithWriteTree:newWriteTree]; + } +} + +/** +* Returns whether this FCompoundWrite will fully overwrite a node at a given location and can therefore be considered +* "complete". +* @param path The path to check for +* @return Whether there is a complete write at that path. +*/ +- (BOOL) hasCompleteWriteAtPath:(FPath *)path { + return [self completeNodeAtPath:path] != nil; +} + +/** +* Returns a node for a path if and only if the node is a "complete" overwrite at that path. This will not aggregate +* writes from depeer paths, but will return child nodes from a more shallow path. +* @param path The path to get a complete write +* @return The node if complete at that path, or nil otherwise. +*/ +- (id) completeNodeAtPath:(FPath *)path { + FTuplePathValue *rootMost = [self.writeTree findRootMostValueAndPath:path]; + if (rootMost != nil) { + FPath *relativePath = [FPath relativePathFrom:rootMost.path to:path]; + return [rootMost.value getChild:relativePath]; + } else { + return nil; + } +} + +// TODO: change into traversal method... +- (NSArray *) completeChildren { + NSMutableArray *children = [[NSMutableArray alloc] init]; + if (self.writeTree.value != nil) { + id node = self.writeTree.value; + [node enumerateChildrenUsingBlock:^(NSString *key, id node, BOOL *stop) { + [children addObject:[[FNamedNode alloc] initWithName:key andNode:node]]; + }]; + } else { + [self.writeTree.children enumerateKeysAndObjectsUsingBlock:^(NSString *childKey, FImmutableTree *childTree, BOOL *stop) { + if (childTree.value != nil) { + [children addObject:[[FNamedNode alloc] initWithName:childKey andNode:childTree.value]]; + } + }]; + } + return children; +} + + +// TODO: change into enumarate method +- (NSDictionary *)childCompoundWrites { + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + [self.writeTree.children enumerateKeysAndObjectsUsingBlock:^(NSString *key, FImmutableTree *childWrite, BOOL *stop) { + dict[key] = [[FCompoundWrite alloc] initWithWriteTree:childWrite]; + }]; + return dict; +} + +- (FCompoundWrite *) childCompoundWriteAtPath:(FPath *)path { + if (path.isEmpty) { + return self; + } else { + id shadowingNode = [self completeNodeAtPath:path]; + if (shadowingNode != nil) { + return [[FCompoundWrite alloc] initWithWriteTree:[[FImmutableTree alloc] initWithValue:shadowingNode]]; + } else { + return [[FCompoundWrite alloc] initWithWriteTree:[self.writeTree subtreeAtPath:path]]; + } + } +} + +- (id) applySubtreeWrite:(FImmutableTree *)subtreeWrite atPath:(FPath *)relativePath toNode:(id)node { + if (subtreeWrite.value != nil) { + // Since a write there is always a leaf, we're done here. + return [node updateChild:relativePath withNewChild:subtreeWrite.value]; + } else { + __block id priorityWrite = nil; + __block id blockNode = node; + [subtreeWrite.children enumerateKeysAndObjectsUsingBlock:^(NSString *childKey, FImmutableTree *childTree, BOOL *stop) { + if ([childKey isEqualToString:@".priority"]) { + // Apply priorities at the end so we don't update priorities for either empty nodes or forget to apply + // priorities to empty nodes that are later filled. + NSAssert(childTree.value != nil, @"Priority writes must always be leaf nodes"); + priorityWrite = childTree.value; + } else { + blockNode = [self applySubtreeWrite:childTree atPath:[relativePath childFromString:childKey] toNode:blockNode]; + } + }]; + // If there was a priority write, we only apply it if the node is not empty + if (![blockNode getChild:relativePath].isEmpty && priorityWrite != nil) { + blockNode = [blockNode updateChild:[relativePath childFromString:@".priority"] withNewChild:priorityWrite]; + } + return blockNode; + } +} + +- (void)enumerateWrites:(void (^)(FPath *, id, BOOL *))block { + __block BOOL stop = NO; + // TODO: add stop to tree iterator... + [self.writeTree forEach:^(FPath *path, id value) { + if (!stop) { + block(path, value, &stop); + } + }]; +} + +/** +* Applies this FCompoundWrite to a node. The node is returned with all writes from this FCompoundWrite applied to the node. +* @param node The node to apply this FCompoundWrite to +* @return The node with all writes applied +*/ +- (id) applyToNode:(id)node { + return [self applySubtreeWrite:self.writeTree atPath:[FPath empty] toNode:node]; +} + +/** +* Return true if this CompoundWrite is empty and therefore does not modify any nodes. +* @return Whether this CompoundWrite is empty +*/ +- (BOOL) isEmpty { + return self.writeTree.isEmpty; +} + +- (id) rootWrite { + return self.writeTree.value; +} + +- (BOOL)isEqual:(id)object { + if (![object isKindOfClass:[FCompoundWrite class]]) { + return NO; + } + FCompoundWrite *other = (FCompoundWrite *)object; + return [[self valForExport:YES] isEqualToDictionary:[other valForExport:YES]]; +} + +- (NSUInteger)hash { + return [[self valForExport:YES] hash]; +} + +- (NSDictionary *)valForExport:(BOOL)exportFormat { + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [self.writeTree forEach:^(FPath *path, id value) { + dictionary[path.wireFormat] = [value valForExport:exportFormat]; + }]; + return dictionary; +} + +- (NSString *)description { + return [[self valForExport:YES] description]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FEmptyNode.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FEmptyNode.h new file mode 100644 index 00000000..ab404c29 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FEmptyNode.h @@ -0,0 +1,24 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FNode.h" + +@interface FEmptyNode : NSObject + ++ (id) emptyNode; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FEmptyNode.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FEmptyNode.m new file mode 100644 index 00000000..f41e1182 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FEmptyNode.m @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FEmptyNode.h" +#import "FChildrenNode.h" + +@implementation FEmptyNode + ++ (id) emptyNode { + static FChildrenNode* empty = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + empty = [[FChildrenNode alloc] init]; + }); + return empty; +} +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FIndexedNode.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FIndexedNode.h new file mode 100644 index 00000000..fd2db37e --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FIndexedNode.h @@ -0,0 +1,49 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#import + +#import "FNode.h" +#import "FIndex.h" +#import "FNamedNode.h" + +/** + * Represents a node together with an index. The index and node are updated in unison. In the case where the index + * does not affect the ordering (i.e. the ordering is identical to the key ordering) this class uses a fallback index + * to save memory. Everything operating on the index must special case the fallback index. + */ +@interface FIndexedNode : NSObject + +@property (nonatomic, strong, readonly) id node; + ++ (FIndexedNode *)indexedNodeWithNode:(id)node; ++ (FIndexedNode *)indexedNodeWithNode:(id)node index:(id)index; + +- (BOOL)hasIndex:(id)index; +- (FIndexedNode *)updateChild:(NSString *)key withNewChild:(id)newChildNode; +- (FIndexedNode *)updatePriority:(id)priority; + +- (FNamedNode *)firstChild; +- (FNamedNode *)lastChild; + +- (NSString *)predecessorForChildKey:(NSString *)childKey childNode:(id)childNode index:(id)index; + +- (void)enumerateChildrenReverse:(BOOL)reverse usingBlock:(void (^)(NSString *key, id node, BOOL *stop))block; + +- (NSEnumerator *)childEnumerator; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FIndexedNode.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FIndexedNode.m new file mode 100644 index 00000000..9dc60e16 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FIndexedNode.m @@ -0,0 +1,202 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIndexedNode.h" + +#import "FImmutableSortedSet.h" +#import "FIndex.h" +#import "FPriorityIndex.h" +#import "FKeyIndex.h" +#import "FChildrenNode.h" + +static FImmutableSortedSet *FALLBACK_INDEX; + +@interface FIndexedNode () + +@property (nonatomic, strong) id node; +/** + * The indexed set is initialized lazily to prevent creation when it is not needed + */ +@property (nonatomic, strong) FImmutableSortedSet *indexed; +@property (nonatomic, strong) id index; + +@end + +@implementation FIndexedNode + ++ (FImmutableSortedSet *)fallbackIndex { + static FImmutableSortedSet *fallbackIndex; + static dispatch_once_t once; + dispatch_once(&once, ^{ + fallbackIndex = [[FImmutableSortedSet alloc] init]; + }); + return fallbackIndex; +} + ++ (FIndexedNode *)indexedNodeWithNode:(id)node +{ + return [[FIndexedNode alloc] initWithNode:node index:[FPriorityIndex priorityIndex]]; +} + ++ (FIndexedNode *)indexedNodeWithNode:(id)node index:(id)index +{ + return [[FIndexedNode alloc] initWithNode:node index:index]; +} + +- (id)initWithNode:(id)node index:(id)index +{ + // Initialize indexed lazily + return [self initWithNode:node index:index indexed:nil]; +} + +- (id)initWithNode:(id)node index:(id)index indexed:(FImmutableSortedSet *)indexed +{ + self = [super init]; + if (self != nil) { + self->_node = node; + self->_index = index; + self->_indexed = indexed; + } + return self; +} + +- (void)ensureIndexed +{ + if (!self.indexed) { + if ([self.index isEqual:[FKeyIndex keyIndex]]) { + self.indexed = [FIndexedNode fallbackIndex]; + } else { + __block BOOL sawChild = NO; + [self.node enumerateChildrenUsingBlock:^(NSString *key, id node, BOOL *stop) { + sawChild = sawChild || [self.index isDefinedOn:node]; + *stop = sawChild; + }]; + if (sawChild) { + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + [self.node enumerateChildrenUsingBlock:^(NSString *key, id node, BOOL *stop) { + FNamedNode *namedNode = [[FNamedNode alloc] initWithName:key andNode:node]; + dict[namedNode] = [NSNull null]; + }]; + // Make sure to assign index here, because the comparator will be retained and using self will cause a + // cycle + id index = self.index; + self.indexed = [FImmutableSortedSet setWithKeysFromDictionary:dict + comparator:^NSComparisonResult(FNamedNode *namedNode1, FNamedNode *namedNode2) { + return [index compareNamedNode:namedNode1 toNamedNode:namedNode2]; + }]; + } else { + self.indexed = [FIndexedNode fallbackIndex]; + } + } + } +} + +- (BOOL)hasIndex:(id)index +{ + return [self.index isEqual:index]; +} + +- (FIndexedNode *)updateChild:(NSString *)key withNewChild:(id)newChildNode +{ + id newNode = [self.node updateImmediateChild:key withNewChild:newChildNode]; + if (self.indexed == [FIndexedNode fallbackIndex] && ![self.index isDefinedOn:newChildNode]) { + // doesn't affect the index, no need to create an index + return [[FIndexedNode alloc] initWithNode:newNode index:self.index indexed:[FIndexedNode fallbackIndex]]; + } else if (!self.indexed || self.indexed == [FIndexedNode fallbackIndex]) { + // No need to index yet, index lazily + return [[FIndexedNode alloc] initWithNode:newNode index:self.index]; + } else { + id oldChild = [self.node getImmediateChild:key]; + FImmutableSortedSet *newIndexed = [self.indexed removeObject:[FNamedNode nodeWithName:key node:oldChild]]; + if (![newChildNode isEmpty]) { + newIndexed = [newIndexed addObject:[FNamedNode nodeWithName:key node:newChildNode]]; + } + return [[FIndexedNode alloc] initWithNode:newNode index:self.index indexed:newIndexed]; + } +} + +- (FIndexedNode *)updatePriority:(id)priority +{ + return [[FIndexedNode alloc] initWithNode:[self.node updatePriority:priority] + index:self.index + indexed:self.indexed]; +} + +- (FNamedNode *)firstChild +{ + if (![self.node isKindOfClass:[FChildrenNode class]]) { + return nil; + } else { + [self ensureIndexed]; + if (self.indexed == [FIndexedNode fallbackIndex]) { + return [((FChildrenNode *)self.node) firstChild]; + } else { + return self.indexed.firstObject; + } + } +} + +- (FNamedNode *)lastChild +{ + if (![self.node isKindOfClass:[FChildrenNode class]]) { + return nil; + } else { + [self ensureIndexed]; + if (self.indexed == [FIndexedNode fallbackIndex]) { + return [((FChildrenNode *)self.node) lastChild]; + } else { + return self.indexed.lastObject; + } + } +} + +- (NSString *)predecessorForChildKey:(NSString *)childKey childNode:(id)childNode index:(id)index +{ + if (![self.index isEqual:index]) { + [NSException raise:NSInvalidArgumentException format:@"Index not available in IndexedNode!"]; + } + [self ensureIndexed]; + if (self.indexed == [FIndexedNode fallbackIndex]) { + return [self.node predecessorChildKey:childKey]; + } else { + FNamedNode *node = [self.indexed predecessorEntry:[FNamedNode nodeWithName:childKey node:childNode]]; + return node.name; + } +} + +- (void)enumerateChildrenReverse:(BOOL)reverse usingBlock:(void (^)(NSString *, id, BOOL *))block +{ + [self ensureIndexed]; + if (self.indexed == [FIndexedNode fallbackIndex]) { + [self.node enumerateChildrenReverse:reverse usingBlock:block]; + } else { + [self.indexed enumerateObjectsReverse:reverse usingBlock:^(FNamedNode *namedNode, BOOL *stop) { + block(namedNode.name, namedNode.node, stop); + }]; + } +} + +- (NSEnumerator *)childEnumerator +{ + [self ensureIndexed]; + if (self.indexed == [FIndexedNode fallbackIndex]) { + return [self.node childEnumerator]; + } else { + return [self.indexed objectEnumerator]; + } +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FLeafNode.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FLeafNode.h new file mode 100644 index 00000000..15e0132d --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FLeafNode.h @@ -0,0 +1,28 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FNode.h" + + +@interface FLeafNode : NSObject + +- (id)initWithValue:(id)aValue; +- (id)initWithValue:(id)aValue withPriority:(id)aPriority; + +@property (nonatomic, strong) id value; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FLeafNode.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FLeafNode.m new file mode 100644 index 00000000..a26e057e --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FLeafNode.m @@ -0,0 +1,250 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FLeafNode.h" +#import "FEmptyNode.h" +#import "FChildrenNode.h" +#import "FConstants.h" +#import "FImmutableSortedDictionary.h" +#import "FUtilities.h" +#import "FStringUtilities.h" +#import "FSnapshotUtilities.h" + +@interface FLeafNode () +@property (nonatomic, strong) id priorityNode; +@property (nonatomic, strong) NSString *lazyHash; + +@end + +@implementation FLeafNode + +@synthesize value; +@synthesize priorityNode; + +- (id)initWithValue:(id)aValue { + self = [super init]; + if (self) { + self.value = aValue; + self.priorityNode = [FEmptyNode emptyNode]; + } + return self; +} + +- (id)initWithValue:(id)aValue withPriority:(id)aPriority { + self = [super init]; + if (self) { + self.value = aValue; + [FSnapshotUtilities validatePriorityNode:aPriority]; + self.priorityNode = aPriority; + } + return self; +} + +#pragma mark - +#pragma mark FNode methods + +- (BOOL) isLeafNode { + return YES; +} + +- (id) getPriority { + return self.priorityNode; +} + +- (id) updatePriority:(id)aPriority { + return [[FLeafNode alloc] initWithValue:self.value withPriority:aPriority]; +} + +- (id) getImmediateChild:(NSString *) childName { + if ([childName isEqualToString:@".priority"]) { + return self.priorityNode; + } else { + return [FEmptyNode emptyNode]; + } +} + +- (id) getChild:(FPath *)path { + if (path.getFront == nil) { + return self; + } else if ([[path getFront] isEqualToString:@".priority"]) { + return [self getPriority]; + } else { + return [FEmptyNode emptyNode]; + } +} + +- (BOOL)hasChild:(NSString *)childName { + return [childName isEqualToString:@".priority"] && ![self getPriority].isEmpty; +} + + +- (NSString *)predecessorChildKey:(NSString *)childKey +{ + return nil; +} + +- (id) updateImmediateChild:(NSString *)childName withNewChild:(id)newChildNode { + if ([childName isEqualToString:@".priority"]) { + return [self updatePriority:newChildNode]; + } else if (newChildNode.isEmpty) { + return self; + } else { + FChildrenNode* childrenNode = [[FChildrenNode alloc] init]; + childrenNode = [childrenNode updateImmediateChild:childName withNewChild:newChildNode]; + childrenNode = [childrenNode updatePriority:self.priorityNode]; + return childrenNode; + } +} + +- (id) updateChild:(FPath *)path withNewChild:(id)newChildNode { + NSString* front = [path getFront]; + if(front == nil) { + return newChildNode; + } else if (newChildNode.isEmpty && ![front isEqualToString:@".priority"]) { + return self; + } else { + NSAssert(![front isEqualToString:@".priority"] || path.length == 1, @".priority must be the last token in a path."); + return [self updateImmediateChild:front withNewChild: + [[FEmptyNode emptyNode] updateChild:[path popFront] withNewChild:newChildNode]]; + } +} + +- (id) val { + return [self valForExport:NO]; +} + +- (id) valForExport:(BOOL)exp { + if(exp && !self.getPriority.isEmpty) { + return @{kPayloadValue : self.value, + kPayloadPriority : [[self getPriority] val]}; + } + else { + return self.value; + } +} + +- (BOOL)isEqual:(id )other { + if(other == self) { + return YES; + } else if (other.isLeafNode) { + FLeafNode *otherLeaf = other; + if ([FUtilities getJavascriptType:self.value] != [FUtilities getJavascriptType:otherLeaf.value]) { + return NO; + } + return [otherLeaf.value isEqual:self.value] && [otherLeaf.priorityNode isEqual:self.priorityNode]; + } else { + return NO; + } +} + +- (NSUInteger)hash { + return [self.value hash] * 17 + self.priorityNode.hash; +} + +- (id )withIndex:(id )index { + return self; +} + +- (BOOL)isIndexed:(id )index { + return YES; +} + +- (BOOL) isEmpty { + return NO; +} + +- (int) numChildren { + return 0; +} + +- (void) enumerateChildrenUsingBlock:(void (^)(NSString *, id, BOOL *))block +{ + // Nothing to iterate over +} + +- (void) enumerateChildrenReverse:(BOOL)reverse usingBlock:(void (^)(NSString *, id, BOOL *))block +{ + // Nothing to iterate over +} + +- (NSEnumerator *)childEnumerator +{ + // Nothing to iterate over + return [@[] objectEnumerator]; +} + +- (NSString *) dataHash { + if (self.lazyHash == nil) { + NSMutableString *toHash = [[NSMutableString alloc] init]; + [FSnapshotUtilities appendHashRepresentationForLeafNode:self toString:toHash hashVersion:FDataHashVersionV1]; + + self.lazyHash = [FStringUtilities base64EncodedSha1:toHash]; + } + return self.lazyHash; +} + +- (NSComparisonResult)compare:(id )other { + if (other == [FEmptyNode emptyNode]) { + return NSOrderedDescending; + } else if ([other isKindOfClass:[FChildrenNode class]]) { + return NSOrderedAscending; + } else { + NSAssert(other.isLeafNode, @"Compared against unknown type of node."); + return [self compareToLeafNode:(FLeafNode*)other]; + } +} + ++ (NSArray*) valueTypeOrder { + static NSArray* valueOrder = nil; + static dispatch_once_t once; + dispatch_once(&once, ^{ + valueOrder = @[kJavaScriptObject, kJavaScriptBoolean, kJavaScriptNumber, kJavaScriptString]; + }); + return valueOrder; +} + +- (NSComparisonResult) compareToLeafNode:(FLeafNode*)other { + NSString* thisLeafType = [FUtilities getJavascriptType:self.value]; + NSString* otherLeafType = [FUtilities getJavascriptType:other.value]; + NSUInteger thisIndex = [[FLeafNode valueTypeOrder] indexOfObject:thisLeafType]; + NSUInteger otherIndex = [[FLeafNode valueTypeOrder] indexOfObject:otherLeafType]; + assert(thisIndex >= 0 && otherIndex >= 0); + if (otherIndex == thisIndex) { + // Same type. Compare values. + if (thisLeafType == kJavaScriptObject) { + // Deferred value nodes are all equal, but we should also never get to this point... + return NSOrderedSame; + } else if (thisLeafType == kJavaScriptString) { + return [self.value compare:other.value options:NSLiteralSearch]; + } else { + return [self.value compare:other.value]; + } + } else { + return thisIndex > otherIndex ? NSOrderedDescending : NSOrderedAscending; + } +} + +- (NSString *) description { + return [[self valForExport:YES] description]; +} + +- (void) forEachChildDo:(fbt_bool_nsstring_node)action { + // There are no children, so there is nothing to do. + return; +} + + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FNode.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FNode.h new file mode 100644 index 00000000..13167567 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FNode.h @@ -0,0 +1,46 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FPath.h" +#import "FTypedefs_Private.h" + +@protocol FIndex; + +@protocol FNode + +- (BOOL) isLeafNode; +- (id) getPriority; +- (id) updatePriority:(id)priority; +- (id) getImmediateChild:(NSString *)childKey; +- (id) getChild:(FPath *)path; +- (NSString *) predecessorChildKey:(NSString *)childKey; +- (id) updateImmediateChild:(NSString *)childKey withNewChild:(id)newChildNode; +- (id) updateChild:(FPath *)path withNewChild:(id)newChildNode; +- (BOOL) hasChild:(NSString*)childKey; +- (BOOL) isEmpty; +- (int) numChildren; +- (id) val; +- (id) valForExport:(BOOL)exp; +- (NSString *) dataHash; +- (NSComparisonResult) compare:(id)other; +- (BOOL) isEqual:(id)other; +- (void)enumerateChildrenUsingBlock:(void (^)(NSString *key, id node, BOOL *stop))block; +- (void)enumerateChildrenReverse:(BOOL)reverse usingBlock:(void (^)(NSString *key, id node, BOOL *stop))block; + +- (NSEnumerator *)childEnumerator; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FSnapshotUtilities.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FSnapshotUtilities.h new file mode 100644 index 00000000..2a287886 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FSnapshotUtilities.h @@ -0,0 +1,45 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FNode.h" + +@class FImmutableSortedDictionary; +@class FCompoundWrite; +@class FLeafNode; +@protocol FNode; + +typedef NS_ENUM(NSInteger, FDataHashVersion) { + FDataHashVersionV1, + FDataHashVersionV2, +}; + +@interface FSnapshotUtilities : NSObject + ++ (id) nodeFrom:(id)val; ++ (id) nodeFrom:(id)val priority:(id)priority; ++ (id) nodeFrom:(id)val withValidationFrom:(NSString *)fn; ++ (id) nodeFrom:(id)val priority:(id)priority withValidationFrom:(NSString *)fn; ++ (FCompoundWrite *) compoundWriteFromDictionary:(NSDictionary *)values withValidationFrom:(NSString *)fn; ++ (void) validatePriorityNode:(id)priorityNode; ++ (void)appendHashRepresentationForLeafNode:(FLeafNode *)val + toString:(NSMutableString *)string + hashVersion:(FDataHashVersion)hashVersion; ++ (void)appendHashV2RepresentationForString:(NSString *)string toString:(NSMutableString *)mutableString; + ++ (NSUInteger)estimateSerializedNodeSize:(id)node; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FSnapshotUtilities.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FSnapshotUtilities.m new file mode 100644 index 00000000..c6012d3e --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Snapshot/FSnapshotUtilities.m @@ -0,0 +1,301 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FSnapshotUtilities.h" +#import "FEmptyNode.h" +#import "FLeafNode.h" +#import "FConstants.h" +#import "FUtilities.h" +#import "FChildrenNode.h" +#import "FLLRBValueNode.h" +#import "FValidation.h" +#import "FMaxNode.h" +#import "FNamedNode.h" +#import "FCompoundWrite.h" + +@implementation FSnapshotUtilities + ++ (id) nodeFrom:(id)val { + return [FSnapshotUtilities nodeFrom:val priority:nil]; +} + ++ (id) nodeFrom:(id)val priority:(id)priority { + return [FSnapshotUtilities nodeFrom:val priority:priority withValidationFrom:@"nodeFrom:priority:"]; +} + ++ (id) nodeFrom:(id)val withValidationFrom:(NSString *)fn { + return [FSnapshotUtilities nodeFrom:val priority:nil withValidationFrom:fn]; +} + ++ (id) nodeFrom:(id)val priority:(id)priority withValidationFrom:(NSString *)fn { + return [FSnapshotUtilities nodeFrom:val priority:priority withValidationFrom:fn atDepth:0 path:[[NSMutableArray alloc] init]]; +} + ++ (id) nodeFrom:(id)val priority:(id)aPriority withValidationFrom:(NSString *)fn atDepth:(int)depth path:(NSMutableArray *)path { + @autoreleasepool { + return [FSnapshotUtilities internalNodeFrom:val priority:aPriority withValidationFrom:fn atDepth:depth path:path]; + } +} + ++ (id) internalNodeFrom:(id)val priority:(id)aPriority withValidationFrom:(NSString *)fn atDepth:(int)depth path:(NSMutableArray *)path { + + + if (depth > kFirebaseMaxObjectDepth) { + NSRange range; + range.location = 0; + range.length = 100; + NSString* pathString = [[path subarrayWithRange:range] componentsJoinedByString:@"."]; + @throw [[NSException alloc] initWithName:@"InvalidFirebaseData" reason:[NSString stringWithFormat:@"(%@) Max object depth exceeded: %@...", fn, pathString] userInfo:nil]; + } + + if (val == nil || val == [NSNull null]) { + // Null is a valid type to store + return [FEmptyNode emptyNode]; + } + + [FValidation validateFrom:fn isValidPriorityValue:aPriority withPath:path]; + id priority = [FSnapshotUtilities nodeFrom:aPriority]; + + id value = val; + BOOL isLeafNode = NO; + + if([value isKindOfClass:[NSDictionary class]]) { + NSDictionary* dict = val; + if(dict[kPayloadPriority] != nil) { + id rawPriority = [dict objectForKey:kPayloadPriority]; + [FValidation validateFrom:fn isValidPriorityValue:rawPriority withPath:path]; + priority = [FSnapshotUtilities nodeFrom:rawPriority]; + } + + if(dict[kPayloadValue] != nil) { + value = [dict objectForKey:kPayloadValue]; + if ([FValidation validateFrom:fn isValidLeafValue:value withPath:path]) { + isLeafNode = YES; + } else { + @throw [[NSException alloc] + initWithName:@"InvalidLeafValueType" + reason:[NSString stringWithFormat:@"(%@) Invalid data type used with .value. Can only use " + "NSString and NSNumber or be null. Found %@ instead.", + fn, [[value class] description]] userInfo:nil]; + } + } + } + + if([FValidation validateFrom:fn isValidLeafValue:value withPath:path]) { + isLeafNode = YES; + } + + if (isLeafNode) { + return [[FLeafNode alloc] initWithValue:value withPriority:priority]; + } + + // Unlike with JS, we have to handle the dictionary and array cases separately. + if ([value isKindOfClass:[NSDictionary class]]) { + NSDictionary* dval = (NSDictionary *)value; + NSMutableDictionary *children = [NSMutableDictionary dictionaryWithCapacity:dval.count]; + + // Avoid creating a million newPaths by appending to old one + for (id keyId in dval) { + [FValidation validateFrom:fn validDictionaryKey:keyId withPath:path]; + NSString* key = (NSString*)keyId; + + if (![key hasPrefix:kPayloadMetadataPrefix]) { + [path addObject:key]; + id childNode = [FSnapshotUtilities nodeFrom:dval[key] priority:nil withValidationFrom:fn atDepth:depth + 1 path:path]; + [path removeLastObject]; + + if (![childNode isEmpty]) { + children[key] = childNode; + } + } + } + + if ([children count] == 0) { + return [FEmptyNode emptyNode]; + } else { + FImmutableSortedDictionary *childrenDict = [FImmutableSortedDictionary fromDictionary:children + withComparator:[FUtilities keyComparator]]; + return [[FChildrenNode alloc] initWithPriority:priority children:childrenDict]; + } + } else if([value isKindOfClass:[NSArray class]]) { + NSArray* aval = (NSArray *)value; + NSMutableDictionary* children = [NSMutableDictionary dictionaryWithCapacity:aval.count]; + + for(int i = 0; i < [aval count]; i++) { + NSString* key = [NSString stringWithFormat:@"%i", i]; + [path addObject:key]; + id childNode = [FSnapshotUtilities nodeFrom:[aval objectAtIndex:i] priority:nil withValidationFrom:fn atDepth:depth + 1 path:path]; + [path removeLastObject]; + + if (![childNode isEmpty]) { + children[key] = childNode; + } + } + + if ([children count] == 0) { + return [FEmptyNode emptyNode]; + } else { + FImmutableSortedDictionary *childrenDict = [FImmutableSortedDictionary fromDictionary:children + withComparator:[FUtilities keyComparator]]; + return [[FChildrenNode alloc] initWithPriority:priority children:childrenDict]; + } + } else { + NSRange range; + range.location = 0; + range.length = MIN(path.count, 50); + NSString* pathString = [[path subarrayWithRange:range] componentsJoinedByString:@"."]; + + @throw [[NSException alloc] initWithName:@"InvalidFirebaseData" + reason:[NSString stringWithFormat:@"(%@) Cannot store object of type %@ at %@. " + "Can only store objects of type NSNumber, NSString, NSDictionary, and NSArray.", + fn, [[value class] description], pathString] userInfo:nil]; + } +} + ++ (FCompoundWrite *) compoundWriteFromDictionary:(NSDictionary *)values withValidationFrom:(NSString *)fn { + FCompoundWrite *compoundWrite = [FCompoundWrite emptyWrite]; + + NSMutableArray *updatePaths = [NSMutableArray arrayWithCapacity:values.count]; + for (NSString *keyId in values) { + id value = values[keyId]; + [FValidation validateFrom:fn validUpdateDictionaryKey:keyId withValue:value]; + + FPath* path = [FPath pathWithString:keyId]; + id node = [FSnapshotUtilities nodeFrom:value withValidationFrom:fn]; + + [updatePaths addObject:path]; + compoundWrite = [compoundWrite addWrite:node atPath:path]; + } + + // Check that the update paths are not descendants of each other. + [updatePaths sortUsingComparator:^NSComparisonResult(FPath* left, FPath* right) { + return [left compare:right]; + }]; + FPath *prevPath = nil; + for (FPath *path in updatePaths) { + if (prevPath != nil && [prevPath contains:path]) { + @throw [[NSException alloc] initWithName:@"InvalidFirebaseData" reason:[NSString stringWithFormat:@"(%@) Invalid path in object. Path (%@) is an ancestor of (%@).", fn, prevPath, path] userInfo:nil]; + } + prevPath = path; + } + + return compoundWrite; +} + ++ (void)validatePriorityNode:(id )priorityNode { + assert(priorityNode != nil); + if (priorityNode.isLeafNode) { + id val = priorityNode.val; + if ([val isKindOfClass:[NSDictionary class]]) { + NSDictionary* valDict __unused = (NSDictionary*)val; + NSAssert(valDict[kServerValueSubKey] != nil, @"Priority can't be object unless it's a deferred value"); + } else { + NSString *jsType __unused = [FUtilities getJavascriptType:val]; + NSAssert(jsType == kJavaScriptString || jsType == kJavaScriptNumber, @"Priority of unexpected type."); + } + } else { + NSAssert(priorityNode == [FMaxNode maxNode] || priorityNode.isEmpty, @"Priority of unexpected type."); + } + // Don't call getPriority() on MAX_NODE to avoid hitting assertion. + NSAssert(priorityNode == [FMaxNode maxNode] || priorityNode.getPriority.isEmpty, + @"Priority nodes can't have a priority of their own."); +} + ++ (void)appendHashRepresentationForLeafNode:(FLeafNode *)leafNode + toString:(NSMutableString *)string + hashVersion:(FDataHashVersion)hashVersion { + NSAssert(hashVersion == FDataHashVersionV1 || hashVersion == FDataHashVersionV2, + @"Unknown hash version: %lu", (unsigned long)hashVersion); + if (!leafNode.getPriority.isEmpty) { + [string appendString:@"priority:"]; + [FSnapshotUtilities appendHashRepresentationForLeafNode:leafNode.getPriority toString:string hashVersion:hashVersion]; + [string appendString:@":"]; + } + + NSString *jsType = [FUtilities getJavascriptType:leafNode.val]; + [string appendString:jsType]; + [string appendString:@":"]; + + + if (jsType == kJavaScriptBoolean) { + NSString *boolString = [leafNode.val boolValue] ? kJavaScriptTrue : kJavaScriptFalse; + [string appendString:boolString]; + } else if (jsType == kJavaScriptNumber) { + NSString *numberString = [FUtilities ieee754StringForNumber:leafNode.val]; + [string appendString:numberString]; + } else if (jsType == kJavaScriptString) { + if (hashVersion == FDataHashVersionV1) { + [string appendString:leafNode.val]; + } else { + NSAssert(hashVersion == FDataHashVersionV2, @"Invalid hash version found"); + [FSnapshotUtilities appendHashV2RepresentationForString:leafNode.val toString:string]; + } + } else { + [NSException raise:NSInvalidArgumentException format:@"Unknown value for hashing: %@", leafNode]; + } +} + ++ (void)appendHashV2RepresentationForString:(NSString *)string + toString:(NSMutableString *)mutableString { + string = [string stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"]; + string = [string stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; + [mutableString appendString:@"\""]; + [mutableString appendString:string]; + [mutableString appendString:@"\""]; +} + ++ (NSUInteger)estimateLeafNodeSize:(FLeafNode *)leafNode { + NSString *jsType = [FUtilities getJavascriptType:leafNode.val]; + // These values are somewhat arbitrary, but we don't need an exact value so prefer performance over exact value + NSUInteger valueSize; + if (jsType == kJavaScriptNumber) { + valueSize = 8; // estimate each float with 8 bytes + } else if (jsType == kJavaScriptBoolean) { + valueSize = 4; // true or false need roughly 4 bytes + } else if (jsType == kJavaScriptString) { + valueSize = 2 + [leafNode.val length]; // add 2 for quotes + } else { + [NSException raise:NSInvalidArgumentException format:@"Unknown leaf type: %@", leafNode]; + return 0; + } + + if (leafNode.getPriority.isEmpty) { + return valueSize; + } else { + // Account for extra overhead due to the extra JSON object and the ".value" and ".priority" keys, colons, comma + NSUInteger leafPriorityOverhead = 2 + 8 + 11 + 2 + 1; + return leafPriorityOverhead + valueSize + [FSnapshotUtilities estimateLeafNodeSize:leafNode.getPriority]; + } +} + ++ (NSUInteger)estimateSerializedNodeSize:(id)node { + if ([node isEmpty]) { + return 4; // null keyword + } else if ([node isLeafNode]) { + return [FSnapshotUtilities estimateLeafNodeSize:node]; + } else { + NSAssert([node isKindOfClass:[FChildrenNode class]], @"Unexpected node type: %@", [node class]); + __block NSUInteger sum = 1; // opening brackets + [((FChildrenNode *)node) enumerateChildrenAndPriorityUsingBlock:^(NSString *key, idchild, BOOL *stop) { + sum += key.length; + sum += 4; // quotes around key and colon and (comma or closing bracket) + sum += [FSnapshotUtilities estimateSerializedNodeSize:child]; + }]; + return sum; + } +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FAtomicNumber.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FAtomicNumber.h new file mode 100644 index 00000000..589dc257 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FAtomicNumber.h @@ -0,0 +1,23 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@interface FAtomicNumber : NSObject + +- (NSNumber *) getAndIncrement; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FAtomicNumber.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FAtomicNumber.m new file mode 100644 index 00000000..4a14caa8 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FAtomicNumber.m @@ -0,0 +1,54 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FAtomicNumber.h" + +@interface FAtomicNumber() { + unsigned long number; +} + +@property (nonatomic, strong) NSLock* lock; + +@end + +@implementation FAtomicNumber + +@synthesize lock; + +- (id)init +{ + self = [super init]; + if (self) { + number = 1; + self.lock = [[NSLock alloc] init]; + } + return self; +} + +- (NSNumber *) getAndIncrement { + NSNumber* result; + + // See: http://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html#//apple_ref/doc/uid/10000057i-CH8-SW14 to improve, etc. + + [self.lock lock]; + result = [NSNumber numberWithUnsignedLong:number]; + number = number + 1; + [self.lock unlock]; + + return result; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FEventEmitter.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FEventEmitter.h new file mode 100644 index 00000000..069e10f3 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FEventEmitter.h @@ -0,0 +1,33 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRDatabaseQuery.h" +#import "FIRDatabaseConfig.h" +#import "FTypedefs_Private.h" + +@interface FEventEmitter : NSObject + +- (id) initWithAllowedEvents:(NSArray *)theAllowedEvents queue:(dispatch_queue_t)queue; + +- (id) getInitialEventForType:(NSString *)eventType; +- (void) triggerEventType:(NSString *)eventType data:(id)data; + +- (FIRDatabaseHandle)observeEventType:(NSString *)eventType withBlock:(fbt_void_id)block; +- (void) removeObserverForEventType:(NSString *)eventType withHandle:(FIRDatabaseHandle)handle; + +- (void) validateEventType:(NSString *)eventType; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FEventEmitter.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FEventEmitter.m new file mode 100644 index 00000000..f7c569bf --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FEventEmitter.m @@ -0,0 +1,145 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#import "FEventEmitter.h" +#import "FUtilities.h" +#import "FRepoManager.h" +#import "FIRDatabaseQuery_Private.h" + +@interface FEventListener : NSObject + +@property (nonatomic, copy) fbt_void_id userCallback; +@property (nonatomic) FIRDatabaseHandle handle; + +@end + +@implementation FEventListener + +@synthesize userCallback; +@synthesize handle; + +@end + + +@interface FEventEmitter () + +@property (nonatomic, strong) NSArray *allowedEvents; +@property (nonatomic, strong) NSMutableDictionary *listeners; +@property (nonatomic, strong) dispatch_queue_t queue; + +@end + + +@implementation FEventEmitter + +@synthesize allowedEvents; +@synthesize listeners; + +- (id) initWithAllowedEvents:(NSArray *)theAllowedEvents queue:(dispatch_queue_t)queue { + if (theAllowedEvents == nil || [theAllowedEvents count] == 0) { + @throw [NSException exceptionWithName:@"AllowedEventsValidation" reason:@"FEventEmitters must be initialized with at least one valid event." userInfo:nil]; + } + + self = [super init]; + + if (self) { + self.allowedEvents = [theAllowedEvents copy]; + self.listeners = [[NSMutableDictionary alloc] init]; + self.queue = queue; + } + + return self; +} + +- (id) getInitialEventForType:(NSString *)eventType { + @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"You must override getInitialEvent: when subclassing FEventEmitter" userInfo:nil]; +} + +- (void) triggerEventType:(NSString *)eventType data:(id)data { + [self validateEventType:eventType]; + NSMutableDictionary *eventTypeListeners = [self.listeners objectForKey:eventType]; + for (FEventListener *listener in eventTypeListeners) { + [self triggerListener:listener withData:data]; + } +} + +- (void) triggerListener:(FEventListener *)listener withData:(id)data { + // TODO, should probably get this from FRepo or something although it ends up being the same. (Except maybe for testing) + if (listener.userCallback) { + dispatch_async(self.queue, ^{ + listener.userCallback(data); + }); + } +} + +- (FIRDatabaseHandle)observeEventType:(NSString *)eventType withBlock:(fbt_void_id)block { + [self validateEventType:eventType]; + + // Create listener + FEventListener *listener = [[FEventListener alloc] init]; + listener.handle = [[FUtilities LUIDGenerator] integerValue]; + listener.userCallback = block; // copies block automatically + + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + [self addEventListener:listener forEventType:eventType]; + }); + + return listener.handle; +} + +- (void) addEventListener:(FEventListener *)listener forEventType:(NSString *)eventType { + // Get or initializer listeners map [FIRDatabaseHandle -> callback block] for eventType + NSMutableArray *eventTypeListeners = [self.listeners objectForKey:eventType]; + if (eventTypeListeners == nil) { + eventTypeListeners = [[NSMutableArray alloc] init]; + [self.listeners setObject:eventTypeListeners forKey:eventType]; + } + + // Add listener and fire the current event for this listener + [eventTypeListeners addObject:listener]; + id initialData = [self getInitialEventForType:eventType]; + [self triggerListener:listener withData:initialData]; +} + +- (void) removeObserverForEventType:(NSString *)eventType withHandle:(FIRDatabaseHandle)handle { + [self validateEventType:eventType]; + + dispatch_async([FIRDatabaseQuery sharedQueue], ^{ + [self removeEventListenerWithHandle:handle forEventType:eventType]; + }); +} + +- (void)removeEventListenerWithHandle:(FIRDatabaseHandle)handle forEventType:(NSString *)eventType { + NSMutableArray *eventTypeListeners = [self.listeners objectForKey:eventType]; + for (FEventListener *listener in [eventTypeListeners copy]) { + if (handle == NSNotFound || handle == listener.handle) { + [eventTypeListeners removeObject:listener]; + } + } +} + + +- (void) validateEventType:(NSString *)eventType { + if ([self.allowedEvents indexOfObject:eventType] == NSNotFound) { + @throw [NSException exceptionWithName:@"InvalidEventType" + reason:[NSString stringWithFormat:@"%@ is not a valid event type. %@ is the list of valid events.", + eventType, self.allowedEvents] + userInfo:nil]; + } +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FNextPushId.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FNextPushId.h new file mode 100644 index 00000000..2da54f06 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FNextPushId.h @@ -0,0 +1,23 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@interface FNextPushId : NSObject + ++ (NSString *) get:(NSTimeInterval)now; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FNextPushId.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FNextPushId.m new file mode 100644 index 00000000..ee3ba131 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FNextPushId.m @@ -0,0 +1,63 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FNextPushId.h" +#import "FUtilities.h" + +static NSString *const PUSH_CHARS = @"-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"; + +@implementation FNextPushId + ++ (NSString *) get:(NSTimeInterval)currentTime { + static long long lastPushTime = 0; + static int lastRandChars[12]; + + long long now = (long long)(currentTime * 1000); + + BOOL duplicateTime = now == lastPushTime; + lastPushTime = now; + + unichar timeStampChars[8]; + for(int i = 7; i >= 0; i--) { + timeStampChars[i] = [PUSH_CHARS characterAtIndex:(now % 64)]; + now = (long long)floor(now / 64); + } + + NSMutableString* id = [[NSMutableString alloc] init]; + [id appendString:[NSString stringWithCharacters:timeStampChars length:8]]; + + + if(!duplicateTime) { + for(int i = 0; i < 12; i++) { + lastRandChars[i] = (int)floor(arc4random() % 64); + } + } + else { + int i = 0; + for(i = 11; i >= 0 && lastRandChars[i] == 63; i--) { + lastRandChars[i] = 0; + } + lastRandChars[i]++; + } + + for(int i = 0; i < 12; i++) { + [id appendFormat:@"%C", [PUSH_CHARS characterAtIndex:lastRandChars[i]]]; + } + + return [NSString stringWithString:id]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FParsedUrl.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FParsedUrl.h new file mode 100644 index 00000000..7145f86b --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FParsedUrl.h @@ -0,0 +1,25 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FRepoInfo.h" +#import "FPath.h" + +@interface FParsedUrl : NSObject + +@property (nonatomic, strong) FRepoInfo* repoInfo; +@property (nonatomic, strong) FPath* path; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FParsedUrl.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FParsedUrl.m new file mode 100644 index 00000000..eb833309 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FParsedUrl.m @@ -0,0 +1,24 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FParsedUrl.h" + +@implementation FParsedUrl + +@synthesize repoInfo; +@synthesize path; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FStringUtilities.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FStringUtilities.h new file mode 100644 index 00000000..34ac9af9 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FStringUtilities.h @@ -0,0 +1,26 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@interface FStringUtilities : NSObject + ++ (NSString *) base64EncodedSha1:(NSString *)str; ++ (NSString *) urlDecoded:(NSString *)url; ++ (NSString *) urlEncoded:(NSString *)url; ++ (NSString *) sanitizedForUserAgent:(NSString *)str; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FStringUtilities.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FStringUtilities.m new file mode 100644 index 00000000..dff58e04 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FStringUtilities.m @@ -0,0 +1,61 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FStringUtilities.h" +#import "NSData+SRB64Additions.h" + +@implementation FStringUtilities + +// http://stackoverflow.com/questions/3468268/objective-c-sha1 +// http://stackoverflow.com/questions/7310457/ios-objective-c-sha-1-and-base64-problem ++ (NSString *) base64EncodedSha1:(NSString *)str { + const char *cstr = [str cStringUsingEncoding:NSUTF8StringEncoding]; + // NSString reports length in characters, but we want it in bytes, which strlen will give us. + unsigned long dataLen = strlen(cstr); + NSData *data = [NSData dataWithBytes:cstr length:dataLen]; + uint8_t digest[CC_SHA1_DIGEST_LENGTH]; + CC_SHA1(data.bytes, (unsigned int)data.length, digest); + NSData* output = [[NSData alloc] initWithBytes:digest length:CC_SHA1_DIGEST_LENGTH]; + return [FSRUtilities base64EncodedStringFromData:output]; +} + ++ (NSString *) urlDecoded:(NSString *)url { + NSString* replaced = [url stringByReplacingOccurrencesOfString:@"+" withString:@" "]; + NSString* decoded = [replaced stringByRemovingPercentEncoding]; + // This is kind of a hack, but is generally how the js client works. We could run into trouble if + // some piece is a correctly escaped %-sequence, and another isn't. But, that's bad input anyways... + if (decoded) { + return decoded; + } else { + return replaced; + } +} + ++ (NSString *) urlEncoded:(NSString *)url { + // Didn't seem like there was an Apple NSCharacterSet that had our version of the encoding + // So I made my own, following RFC 2396 https://www.ietf.org/rfc/rfc2396.txt + // allowedCharacters = alphanum | "-" | "_" | "~" + NSCharacterSet *allowedCharacters = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_~"]; + return [url stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacters]; +} + ++ (NSString *) sanitizedForUserAgent:(NSString *)str { + return [str stringByReplacingOccurrencesOfString:@"/|_" withString:@"|" options:NSRegularExpressionSearch range:NSMakeRange(0, [str length])]; +} + + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FTypedefs.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FTypedefs.h new file mode 100644 index 00000000..4a24ca5d --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FTypedefs.h @@ -0,0 +1,45 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#ifndef Firebase_FTypedefs_h +#define Firebase_FTypedefs_h + +/** + * Stub... + */ +@class FIRDataSnapshot; +@class FIRDatabaseReference; +@class FAuthData; +@protocol FNode; + +// fbt = Firebase Block Typedef + +typedef void (^fbt_void_void)(void); +typedef void (^fbt_void_datasnapshot_nsstring) (FIRDataSnapshot *snapshot, NSString *prevName); +typedef void (^fbt_void_datasnapshot) (FIRDataSnapshot *snapshot); +typedef void (^fbt_void_user)(FAuthData *user); +typedef void (^fbt_void_nsstring_id)(NSString* status, id data); +typedef void (^fbt_void_nserror_id)(NSError* error, id data); +typedef void (^fbt_void_nserror)(NSError *error); +typedef void (^fbt_void_nserror_ref)(NSError* error, FIRDatabaseReference * ref); +typedef void (^fbt_void_nserror_user)(NSError* error, FAuthData * user); +typedef void (^fbt_void_nserror_json)(NSError* error, NSDictionary* json); +typedef void (^fbt_void_nsdictionary)(NSDictionary *data); +typedef id (^fbt_id_node_nsstring)(id node, NSString* childName); + +#endif diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FUtilities.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FUtilities.h new file mode 100644 index 00000000..f7fe7a54 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FUtilities.h @@ -0,0 +1,75 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FParsedUrl.h" + +@interface FUtilities : NSObject + ++ (NSArray *) splitString:(NSString *)str intoMaxSize:(const unsigned int)size; ++ (NSNumber *) LUIDGenerator; ++ (FParsedUrl *) parseUrl:(NSString *)url; ++ (NSString *) getJavascriptType:(id)obj; ++ (NSError *) errorForStatus:(NSString *)status andReason:(NSString *)reason; ++ (NSNumber *) intForString:(NSString *)string; ++ (NSString *) ieee754StringForNumber:(NSNumber *)val; ++ (void) setLoggingEnabled:(BOOL)enabled; ++ (BOOL) getLoggingEnabled; + ++ (NSString*) minName; ++ (NSString*) maxName; ++ (NSComparisonResult) compareKey:(NSString *)a toKey:(NSString *)b; ++ (NSComparator) stringComparator; ++ (NSComparator) keyComparator; + ++ (double)randomDouble; + +@end + +typedef enum { + FLogLevelDebug = 1, + FLogLevelInfo = 2, + FLogLevelWarn = 3, + FLogLevelError = 4, + FLogLevelNone = 5 +} FLogLevel; + +// Log tags +FOUNDATION_EXPORT NSString *const kFPersistenceLogTag; + +#define FFLog(code, format, ...) FFDebug((code), (format), ##__VA_ARGS__) + +#define FFDebug(code, format, ...) do { \ + if (FFIsLoggingEnabled(FLogLevelDebug)) { \ + FIRLogDebug(kFIRLoggerDatabase, (code), (format), ##__VA_ARGS__); \ + } \ +} while(0) + +#define FFInfo(code, format, ...) do { \ + if (FFIsLoggingEnabled(FLogLevelInfo)) { \ + FIRLogError(kFIRLoggerDatabase, (code), (format), ##__VA_ARGS__); \ + } \ +} while(0) + +#define FFWarn(code, format, ...) do { \ + if (FFIsLoggingEnabled(FLogLevelWarn)) { \ + FIRLogWarning(kFIRLoggerDatabase, (code), (format), ##__VA_ARGS__); \ + } \ +} while(0) + +BOOL FFIsLoggingEnabled(FLogLevel logLevel); +void firebaseUncaughtExceptionHandler(NSException *exception); +void firebaseJobsTroll(void); diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FUtilities.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FUtilities.m new file mode 100644 index 00000000..d0a9a437 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FUtilities.m @@ -0,0 +1,390 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FUtilities.h" +#import "FStringUtilities.h" +#import "FConstants.h" +#import "FAtomicNumber.h" + +#define ARC4RANDOM_MAX 0x100000000 +#define INTEGER_32_MIN (-2147483648) +#define INTEGER_32_MAX 2147483647 + +#pragma mark - +#pragma mark C functions + +static FLogLevel logLevel = FLogLevelInfo; // Default log level is info +static NSMutableDictionary* options = nil; + +BOOL FFIsLoggingEnabled(FLogLevel level) { + return level >= logLevel; +} + +void firebaseJobsTroll(void) { + FFLog(@"I-RDB095001", @"password super secret; JFK conspiracy; Hello there! Having fun digging through Firebase? We're always hiring! jobs@firebase.com"); +} + +#pragma mark - +#pragma mark Private property and singleton specification + +@interface FUtilities() { + +} + +@property (nonatomic, strong) FAtomicNumber* localUid; + ++ (FUtilities*)singleton; + +@end + +@implementation FUtilities + +@synthesize localUid; + +- (id)init +{ + self = [super init]; + if (self) { + self.localUid = [[FAtomicNumber alloc] init]; + } + return self; +} + +// TODO: We really want to be able to set the log level ++ (void) setLoggingEnabled:(BOOL)enabled { + logLevel = enabled ? FLogLevelDebug : FLogLevelInfo; +} + ++ (BOOL) getLoggingEnabled { + return logLevel == FLogLevelDebug; +} + ++ (FUtilities*) singleton +{ + static dispatch_once_t pred = 0; + __strong static id _sharedObject = nil; + dispatch_once(&pred, ^{ + _sharedObject = [[self alloc] init]; // or some other init method + }); + return _sharedObject; +} + +// Refactor as a category of NSString ++ (NSArray *) splitString:(NSString *) str intoMaxSize:(const unsigned int) size { + if(str.length <= size) { + return [NSArray arrayWithObject:str]; + } + + NSMutableArray* dataSegs = [[NSMutableArray alloc] init]; + for(int c = 0; c < str.length; c += size) { + if (c + size > str.length) { + int rangeStart = c; + unsigned long rangeLength = size - ((c + size) - str.length); + [dataSegs addObject:[str substringWithRange:NSMakeRange(rangeStart, rangeLength)]]; + } + else { + int rangeStart = c; + int rangeLength = size; + [dataSegs addObject:[str substringWithRange:NSMakeRange(rangeStart, rangeLength)]]; + } + } + return dataSegs; +} + ++ (NSNumber *) LUIDGenerator { + FUtilities* f = [FUtilities singleton]; + return [f.localUid getAndIncrement]; +} + ++ (NSString *) decodePath:(NSString *)pathString { + NSMutableArray* decodedPieces = [[NSMutableArray alloc] init]; + NSArray* pieces = [pathString componentsSeparatedByString:@"/"]; + for (NSString* piece in pieces) { + if (piece.length > 0) { + [decodedPieces addObject:[FStringUtilities urlDecoded:piece]]; + } + } + return [NSString stringWithFormat:@"/%@", [decodedPieces componentsJoinedByString:@"/"]]; +} + ++ (FParsedUrl *) parseUrl:(NSString *)url { + NSString* original = url; + //NSURL* n = [[NSURL alloc] initWithString:url] + + NSString* host; + NSString* namespace; + bool secure; + + NSString* scheme = nil; + FPath* path = nil; + NSRange colonIndex = [url rangeOfString:@"//"]; + if (colonIndex.location != NSNotFound) { + scheme = [url substringToIndex:colonIndex.location - 1]; + url = [url substringFromIndex:colonIndex.location + 2]; + } + NSInteger slashIndex = [url rangeOfString:@"/"].location; + if (slashIndex == NSNotFound) { + slashIndex = url.length; + } + + host = [[url substringToIndex:slashIndex] lowercaseString]; + if (slashIndex >= url.length) { + url = @""; + } else { + url = [url substringFromIndex:slashIndex + 1]; + } + + NSArray *parts = [host componentsSeparatedByString:@"."]; + if([parts count] == 3) { + NSInteger colonIndex = [[parts objectAtIndex:2] rangeOfString:@":"].location; + if (colonIndex != NSNotFound) { + // we have a port, use the provided scheme + secure = [scheme isEqualToString:@"https"]; + } else { + secure = YES; + } + + namespace = [[parts objectAtIndex:0] lowercaseString]; + NSString* pathString = [self decodePath:[NSString stringWithFormat:@"/%@", url]]; + path = [[FPath alloc] initWith:pathString]; + } + else { + [NSException raise:@"No Firebase database specified." format:@"No Firebase database found for input: %@", url]; + } + + FRepoInfo* repoInfo = [[FRepoInfo alloc] initWithHost:host isSecure:secure withNamespace:namespace]; + + FFLog(@"I-RDB095002", @"---> Parsed (%@) to: (%@,%@); ns=(%@); path=(%@)", original, [repoInfo description], [repoInfo connectionURL], repoInfo.namespace, [path description]); + + FParsedUrl* parsedUrl = [[FParsedUrl alloc] init]; + parsedUrl.repoInfo = repoInfo; + parsedUrl.path = path; + + return parsedUrl; +} + +/* + case str: JString => priString + "string:" + str.s; + case bool: JBool => priString + "boolean:" + bool.value; + case double: JDouble => priString + "number:" + double.num; + case int: JInt => priString + "number:" + int.num; + case _ => { + error("Leaf node has value '" + data.value + "' of invalid type '" + data.value.getClass.toString + "'"); + ""; + } + */ + ++ (NSString *) getJavascriptType:(id)obj { + if ([obj isKindOfClass:[NSDictionary class]]) { + return kJavaScriptObject; + } else if([obj isKindOfClass:[NSString class]]) { + return kJavaScriptString; + } + else if ([obj isKindOfClass:[NSNumber class]]) { + // We used to just compare to @encode(BOOL) as suggested at + // http://stackoverflow.com/questions/2518761/get-type-of-nsnumber, but on arm64, @encode(BOOL) returns "B" + // instead of "c" even though objCType still returns 'c' (signed char). So check both. + if(strcmp([obj objCType], @encode(BOOL)) == 0 || + strcmp([obj objCType], @encode(signed char)) == 0) { + return kJavaScriptBoolean; + } + else { + return kJavaScriptNumber; + } + } + else { + return kJavaScriptNull; + } +} + ++ (NSError *) errorForStatus:(NSString *)status andReason:(NSString *)reason { + static dispatch_once_t pred = 0; + __strong static NSDictionary* errorMap = nil; + __strong static NSDictionary* errorCodes = nil; + dispatch_once(&pred, ^{ + errorMap = @{ + @"permission_denied": @"Permission Denied", + @"unavailable": @"Service is unavailable", + kFErrorWriteCanceled: @"Write cancelled by user" + }; + errorCodes = @{ + @"permission_denied": @1, + @"unavailable": @2, + kFErrorWriteCanceled: @3 + }; + }); + + if ([status isEqualToString:kFWPResponseForActionStatusOk]) { + return nil; + } else { + NSInteger code; + NSString* desc = nil; + if (reason) { + desc = reason; + } else if ([errorMap objectForKey:status] != nil) { + desc = [errorMap objectForKey:status]; + } else { + desc = status; + } + + if ([errorCodes objectForKey:status] != nil) { + NSNumber* num = [errorCodes objectForKey:status]; + code = [num integerValue]; + } else { + // XXX what to do here? + code = 9999; + } + + return [[NSError alloc] initWithDomain:kFErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey: desc}]; + } +} + ++ (NSNumber *) intForString:(NSString *)string { + static NSCharacterSet *notDigits = nil; + if (!notDigits) { + notDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet]; + } + if ([string rangeOfCharacterFromSet:notDigits].length == 0) { + NSInteger num; + NSScanner* scanner = [NSScanner scannerWithString:string]; + if ([scanner scanInteger:&num]) { + return [NSNumber numberWithInteger:num]; + } + } + return nil; +} + ++ (NSString *) ieee754StringForNumber:(NSNumber *)val { + double d = [val doubleValue]; + NSData* data = [NSData dataWithBytes:&d length:sizeof(double)]; + NSMutableString* str = [[NSMutableString alloc] init]; + const unsigned char* buffer = (const unsigned char*)[data bytes]; + for (int i = 0; i < data.length; i++) { + unsigned char byte = buffer[7 - i]; + [str appendFormat:@"%02x", byte]; + } + return str; +} + +static inline BOOL tryParseStringToInt(__unsafe_unretained NSString* str, NSInteger* integer) { + // First do some cheap checks (NOTE: The below checks are significantly faster than an equivalent regex :-( ). + NSUInteger length = str.length; + if (length > 11 || length == 0) { + return NO; + } + long long value = 0; + BOOL negative = NO; + NSUInteger i = 0; + if ([str characterAtIndex:0] == '-') { + if (length == 1) { + return NO; + } + negative = YES; + i = 1; + } + for(; i < length; i++) { + unichar c = [str characterAtIndex:i]; + // Must be a digit, or '-' if it's the first char. + if (c < '0' || c > '9') { + return NO; + } else { + int charValue = c - '0'; + value = value*10 + charValue; + } + } + + value = (negative) ? -value : value; + + if (value < INTEGER_32_MIN || value > INTEGER_32_MAX) { + return NO; + } else { + *integer = (NSInteger)value; + return YES; + } +} + ++ (NSString *) maxName { + static dispatch_once_t once; + static NSString *maxName; + dispatch_once(&once, ^{ + maxName = [[NSString alloc] initWithFormat:@"[MAX_NAME]"]; + }); + return maxName; +} + ++ (NSString *) minName { + static dispatch_once_t once; + static NSString *minName; + dispatch_once(&once, ^{ + minName = [[NSString alloc] initWithFormat:@"[MIN_NAME]"]; + }); + return minName; +} + ++ (NSComparisonResult) compareKey:(NSString *)a toKey:(NSString *)b { + if (a == b) { + return NSOrderedSame; + } else if (a == [FUtilities minName] || b == [FUtilities maxName]) { + return NSOrderedAscending; + } else if (b == [FUtilities minName] || a == [FUtilities maxName]) { + return NSOrderedDescending; + } else { + NSInteger aAsInt, bAsInt; + if (tryParseStringToInt(a, &aAsInt)) { + if (tryParseStringToInt(b, &bAsInt)) { + if (aAsInt > bAsInt) { + return NSOrderedDescending; + } else if (aAsInt < bAsInt) { + return NSOrderedAscending; + } else if (a.length > b.length) { + return NSOrderedDescending; + } else if (a.length < b.length) { + return NSOrderedAscending; + } else { + return NSOrderedSame; + } + } else { + return (NSComparisonResult) NSOrderedAscending; + } + } else if (tryParseStringToInt(b, &bAsInt)) { + return (NSComparisonResult) NSOrderedDescending; + } else { + // Perform literal character by character search to prevent a > b && b > a issues. + // Note that calling -(NSString *)decomposedStringWithCanonicalMapping also works. + return [a compare:b options:NSLiteralSearch]; + } + } +} + ++ (NSComparator) keyComparator { + return ^NSComparisonResult(__unsafe_unretained NSString *a, __unsafe_unretained NSString *b) { + return [FUtilities compareKey:a toKey:b]; + }; +} + ++ (NSComparator) stringComparator { + return ^NSComparisonResult(__unsafe_unretained NSString *a, __unsafe_unretained NSString *b) { + return [a compare:b]; + }; +} + ++ (double) randomDouble { + return ((double) arc4random() / ARC4RANDOM_MAX); +} + +@end + diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FValidation.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FValidation.h new file mode 100644 index 00000000..faa8f76c --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FValidation.h @@ -0,0 +1,45 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FPath.h" +#import "FIRDataEventType.h" +#import "FParsedUrl.h" +#import "FTypedefs.h" + +@interface FValidation : NSObject + ++ (void) validateFrom:(NSString *)fn writablePath:(FPath *)path; ++ (void) validateFrom:(NSString *)fn knownEventType:(FIRDataEventType)event; ++ (void) validateFrom:(NSString *)fn validPathString:(NSString *)pathString; ++ (void) validateFrom:(NSString *)fn validRootPathString:(NSString *)pathString; ++ (void) validateFrom:(NSString *)fn validKey:(NSString *)key; ++ (void) validateFrom:(NSString *)fn validURL:(FParsedUrl *)parsedUrl; + ++ (void) validateToken:(NSString *)token; + +// Functions for handling passing errors back ++ (void) handleError:(NSError *)error withUserCallback:(fbt_void_nserror_id)userCallback; ++ (void) handleError:(NSError *)error withSuccessCallback:(fbt_void_nserror)userCallback; + +// Functions used for validating while creating snapshots in FSnapshotUtilities ++ (BOOL) validateFrom:(NSString*)fn isValidLeafValue:(id)value withPath:(NSArray*)path; ++ (void) validateFrom:(NSString*)fn validDictionaryKey:(id)keyId withPath:(NSArray*)path; ++ (void) validateFrom:(NSString*)fn validUpdateDictionaryKey:(id)keyId withValue:(id)value; ++ (void) validateFrom:(NSString*)fn isValidPriorityValue:(id)value withPath:(NSArray*)path; ++ (BOOL) validatePriorityValue:value; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FValidation.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FValidation.m new file mode 100644 index 00000000..f088da2b --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/FValidation.m @@ -0,0 +1,312 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FValidation.h" +#import "FConstants.h" +#import "FParsedUrl.h" +#import "FTypedefs.h" + + +// Have to escape: * ? + [ ( ) { } ^ $ | \ . / +// See: https://developer.apple.com/library/mac/#documentation/Foundation/Reference/NSRegularExpression_Class/Reference/Reference.html + +NSString *const kInvalidPathCharacters = @"[].#$"; +NSString *const kInvalidKeyCharacters = @"[].#$/"; + +@implementation FValidation + ++ (void) validateFrom:(NSString *)fn writablePath:(FPath *)path { + if([[path getFront] isEqualToString:kDotInfoPrefix]) { + @throw [[NSException alloc] initWithName:@"WritablePathValidation" reason:[NSString stringWithFormat:@"(%@) failed to path %@: Can't modify data under %@", fn, [path description], kDotInfoPrefix] userInfo:nil]; + } +} + ++ (void) validateFrom:(NSString*)fn knownEventType:(FIRDataEventType)event { + switch (event) { + case FIRDataEventTypeValue: + case FIRDataEventTypeChildAdded: + case FIRDataEventTypeChildChanged: + case FIRDataEventTypeChildMoved: + case FIRDataEventTypeChildRemoved: + return; + break; + default: + @throw [[NSException alloc] initWithName:@"KnownEventTypeValidation" reason:[NSString stringWithFormat:@"(%@) Unknown event type: %d", fn, (int) event] userInfo:nil]; + break; + } +} + ++ (BOOL) isValidPathString:(NSString *)pathString { + static dispatch_once_t token; + static NSCharacterSet *badPathChars = nil; + dispatch_once(&token, ^{ + badPathChars = [NSCharacterSet characterSetWithCharactersInString:kInvalidPathCharacters]; + }); + return pathString != nil && [pathString length] != 0 && + [pathString rangeOfCharacterFromSet:badPathChars].location == NSNotFound; +} + ++ (void) validateFrom:(NSString *)fn validPathString:(NSString *)pathString { + if(! [self isValidPathString:pathString]) { + @throw [[NSException alloc] initWithName:@"InvalidPathValidation" reason:[NSString stringWithFormat:@"(%@) Must be a non-empty string and not contain '.' '#' '$' '[' or ']'", fn] userInfo:nil]; + } +} + ++ (void) validateFrom:(NSString *)fn validRootPathString:(NSString *)pathString { + static dispatch_once_t token; + static NSRegularExpression *dotInfoRegex = nil; + dispatch_once(&token, ^{ + dotInfoRegex = [NSRegularExpression regularExpressionWithPattern:@"^\\/*\\.info(\\/|$)" options:0 error:nil]; + }); + + NSString *tempPath = pathString; + // HACK: Obj-C regex are kinda' slow. Do a plain string search first before bothering with the regex. + if ([pathString rangeOfString:@".info"].location != NSNotFound) { + tempPath = [dotInfoRegex stringByReplacingMatchesInString:pathString options:0 range:NSMakeRange(0, pathString.length) withTemplate:@"/"]; + } + [self validateFrom:fn validPathString:tempPath]; +} + ++ (BOOL) isValidKey:(NSString *)key { + static dispatch_once_t token; + static NSCharacterSet *badKeyChars = nil; + dispatch_once(&token, ^{ + badKeyChars = [NSCharacterSet characterSetWithCharactersInString:kInvalidKeyCharacters]; + }); + return key != nil && key.length > 0 && [key rangeOfCharacterFromSet:badKeyChars].location == NSNotFound; +} + ++ (void) validateFrom:(NSString *)fn validKey:(NSString *)key { + if (![self isValidKey:key]) { + @throw [[NSException alloc] initWithName:@"InvalidKeyValidation" reason:[NSString stringWithFormat:@"(%@) Must be a non-empty string and not contain '/' '.' '#' '$' '[' or ']'", fn] userInfo:nil]; + } +} + ++ (void) validateFrom:(NSString *)fn validURL:(FParsedUrl *)parsedUrl { + NSString* pathString = [parsedUrl.path description]; + [self validateFrom:fn validRootPathString:pathString]; +} + +#pragma mark - +#pragma mark Authentication validation + ++ (BOOL) stringNonempty:(NSString *)str { + return str != nil && ![str isKindOfClass:[NSNull class]] && str.length > 0; +} + ++ (void) validateToken:(NSString *)token { + if (![FValidation stringNonempty:token]) { + [NSException raise:NSInvalidArgumentException format:@"Can't have empty string or nil for custom token"]; + } +} + +#pragma mark - +#pragma mark Handling authentication errors + +/** +* This function immediately calls the callback. +* It assumes that it is not on FirebaseWorker thread. +* It assumes it's on a user-controlled thread. +*/ ++ (void) handleError:(NSError *)error withUserCallback:(fbt_void_nserror_id)userCallback { + if (userCallback) { + userCallback(error, nil); + } +} + +/** +* This function immediately calls the callback. +* It assumes that it is not on FirebaseWorker thread. +* It assumes it's on a user-controlled thread. +*/ ++ (void) handleError:(NSError *)error withSuccessCallback:(fbt_void_nserror)userCallback { + if (userCallback) { + userCallback(error); + } +} + +#pragma mark - +#pragma mark Snapshot validation + ++ (BOOL) validateFrom:(NSString*)fn isValidLeafValue:(id)value withPath:(NSArray*)path { + if ([value isKindOfClass:[NSString class]]) { + // Try to avoid conversion to bytes if possible + NSString* theString = value; + if ([theString maximumLengthOfBytesUsingEncoding:NSUTF8StringEncoding] > kFirebaseMaxLeafSize && + [theString lengthOfBytesUsingEncoding:NSUTF8StringEncoding] > kFirebaseMaxLeafSize) { + NSRange range; + range.location = 0; + range.length = MIN(path.count, 50); + NSString* pathString = [[path subarrayWithRange:range] componentsJoinedByString:@"."]; + @throw [[NSException alloc] initWithName:@"InvalidFirebaseData" reason:[NSString stringWithFormat:@"(%@) String exceeds max size of %u utf8 bytes: %@", fn, (int)kFirebaseMaxLeafSize, pathString] userInfo:nil]; + } + return YES; + } + + else if ([value isKindOfClass:[NSNumber class]]) { + // Cannot store NaN, but otherwise can store NSNumbers. + if ([[NSDecimalNumber notANumber] isEqualToNumber:value]) { + NSRange range; + range.location = 0; + range.length = MIN(path.count, 50); + NSString* pathString = [[path subarrayWithRange:range] componentsJoinedByString:@"."]; + @throw [[NSException alloc] initWithName:@"InvalidFirebaseData" reason:[NSString stringWithFormat:@"(%@) Cannot store NaN at path: %@.", fn, pathString] userInfo:nil]; + } + return YES; + } + + else if ([value isKindOfClass:[NSDictionary class]]) { + NSDictionary* dval = value; + if (dval[kServerValueSubKey] != nil) { + if ([dval count] > 1) { + NSRange range; + range.location = 0; + range.length = MIN(path.count, 50); + NSString* pathString = [[path subarrayWithRange:range] componentsJoinedByString:@"."]; + @throw [[NSException alloc] initWithName:@"InvalidFirebaseData" reason:[NSString stringWithFormat:@"(%@) Cannot store other keys with server value keys.%@.", fn, pathString] userInfo:nil]; + } + return YES; + } + return NO; + } + + else if (value == [NSNull null] || value == nil) { + // Null is valid type to store at leaf + return YES; + } + + return NO; +} + ++ (NSString*) parseAndValidateKey:(id)keyId fromFunction:(NSString*)fn path:(NSArray*)path { + if (![keyId isKindOfClass:[NSString class]]) { + NSRange range; + range.location = 0; + range.length = MIN(path.count, 50); + NSString* pathString = [[path subarrayWithRange:range] componentsJoinedByString:@"."]; + @throw [[NSException alloc] initWithName:@"InvalidFirebaseData" reason:[NSString stringWithFormat:@"(%@) Non-string keys are not allowed in object at path: %@", fn, pathString] userInfo:nil]; + } + return (NSString*)keyId; +} + ++ (void) validateFrom:(NSString*)fn validDictionaryKey:(id)keyId withPath:(NSArray*)path { + NSString *key = [self parseAndValidateKey:keyId fromFunction:fn path:path]; + if (![key isEqualToString:kPayloadPriority] && ![key isEqualToString:kPayloadValue] && ![key isEqualToString:kServerValueSubKey] && ![FValidation isValidKey:key]) { + NSRange range; + range.location = 0; + range.length = MIN(path.count, 50); + NSString *pathString = [[path subarrayWithRange:range] componentsJoinedByString:@"."]; + @throw [[NSException alloc] initWithName:@"InvalidFirebaseData" reason:[NSString stringWithFormat:@"(%@) Invalid key in object at path: %@. Keys must be non-empty and cannot contain '/' '.' '#' '$' '[' or ']'", fn, pathString] userInfo:nil]; + } +} + ++ (void) validateFrom:(NSString*)fn validUpdateDictionaryKey:(id)keyId withValue:(id)value { + FPath *path = [FPath pathWithString:[self parseAndValidateKey:keyId fromFunction:fn path:@[]]]; + __block NSInteger keyNum = 0; + [path enumerateComponentsUsingBlock:^void (NSString *key, BOOL *stop) { + if ([key isEqualToString:kPayloadPriority] && keyNum == [path length] - 1) { + [self validateFrom:fn isValidPriorityValue:value withPath:@[]]; + } else { + keyNum++; + + if (![FValidation isValidKey:key]) { + @throw [[NSException alloc] initWithName:@"InvalidFirebaseData" reason:[NSString stringWithFormat:@"(%@) Invalid key in object. Keys must be non-empty and cannot contain '.' '#' '$' '[' or ']'", fn] userInfo:nil]; + } + } + }]; +} + ++ (void) validateFrom:(NSString*)fn isValidPriorityValue:(id)value withPath:(NSArray*)path { + [self validateFrom:fn isValidPriorityValue:value withPath:path throwError:YES]; +} + +/** +* Returns YES if priority is valid. +*/ ++ (BOOL)validatePriorityValue:value { + return [self validateFrom:nil isValidPriorityValue:value withPath:nil throwError:NO]; +} + +/** +* Helper for validating priorities. If passed YES for throwError, it'll throw descriptive errors on validation +* problems. Else, it'll just return YES/NO. +*/ ++ (BOOL) validateFrom:(NSString*)fn isValidPriorityValue:(id)value withPath:(NSArray*)path throwError:(BOOL)throwError { + if ([value isKindOfClass:[NSNumber class]]) { + if ([[NSDecimalNumber notANumber] isEqualToNumber:value]) { + if (throwError) { + NSRange range; + range.location = 0; + range.length = MIN(path.count, 50); + NSString *pathString = [[path subarrayWithRange:range] componentsJoinedByString:@"."]; + @throw [[NSException alloc] initWithName:@"InvalidFirebaseData" reason:[NSString stringWithFormat:@"(%@) Cannot store NaN as priority at path: %@.", fn, pathString] userInfo:nil]; + } else { + return NO; + } + } else if (value == (id) kCFBooleanFalse || value == (id) kCFBooleanTrue) { + if (throwError) { + NSRange range; + range.location = 0; + range.length = MIN(path.count, 50); + NSString *pathString = [[path subarrayWithRange:range] componentsJoinedByString:@"."]; + @throw [[NSException alloc] initWithName:@"InvalidFirebaseData" reason:[NSString stringWithFormat:@"(%@) Cannot store true/false as priority at path: %@.", fn, pathString] userInfo:nil]; + } else { + return NO; + } + } + } + else if ([value isKindOfClass:[NSDictionary class]]) { + NSDictionary *dval = value; + if (dval[kServerValueSubKey] != nil) { + if ([dval count] > 1) { + if (throwError) { + NSRange range; + range.location = 0; + range.length = MIN(path.count, 50); + NSString *pathString = [[path subarrayWithRange:range] componentsJoinedByString:@"."]; + @throw [[NSException alloc] initWithName:@"InvalidFirebaseData" reason:[NSString stringWithFormat:@"(%@) Cannot store other keys with server value keys as priority at path: %@.", fn, pathString] userInfo:nil]; + } else { + return NO; + } + } + } else { + if (throwError) { + NSRange range; + range.location = 0; + range.length = MIN(path.count, 50); + NSString *pathString = [[path subarrayWithRange:range] componentsJoinedByString:@"."]; + @throw [[NSException alloc] initWithName:@"InvalidFirebaseData" reason:[NSString stringWithFormat:@"(%@) Cannot store an NSDictionary as priority at path: %@.", fn, pathString] userInfo:nil]; + } else { + return NO; + } + } + } + else if ([value isKindOfClass:[NSArray class]]) { + if (throwError) { + NSRange range; + range.location = 0; + range.length = MIN(path.count, 50); + NSString *pathString = [[path subarrayWithRange:range] componentsJoinedByString:@"."]; + @throw [[NSException alloc] initWithName:@"InvalidFirebaseData" reason:[NSString stringWithFormat:@"(%@) Cannot store an NSArray as priority at path: %@.", fn, pathString] userInfo:nil]; + } else { + return NO; + } + } + + // It's valid! + return YES; +} +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleBoolBlock.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleBoolBlock.h new file mode 100644 index 00000000..bceeed29 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleBoolBlock.h @@ -0,0 +1,25 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FTypedefs.h" + +@interface FTupleBoolBlock : NSObject + +@property (nonatomic, readwrite) BOOL boolean; +@property (nonatomic, copy) fbt_void_void block; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleBoolBlock.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleBoolBlock.m new file mode 100644 index 00000000..c4cd8bf2 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleBoolBlock.m @@ -0,0 +1,24 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FTupleBoolBlock.h" + +@implementation FTupleBoolBlock + +@synthesize boolean; +@synthesize block; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleCallbackStatus.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleCallbackStatus.h new file mode 100644 index 00000000..6ec2375e --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleCallbackStatus.h @@ -0,0 +1,24 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FTypedefs_Private.h" + +@interface FTupleCallbackStatus : NSObject +@property (nonatomic, copy) fbt_void_nsstring_nsstring block; +@property (nonatomic) NSString* status; +@property (nonatomic) NSString* errorReason; +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleCallbackStatus.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleCallbackStatus.m new file mode 100644 index 00000000..05914bfd --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleCallbackStatus.m @@ -0,0 +1,22 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FTupleCallbackStatus.h" + +@implementation FTupleCallbackStatus +@synthesize block; +@synthesize status; +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleFirebase.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleFirebase.h new file mode 100644 index 00000000..ff84bbb2 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleFirebase.h @@ -0,0 +1,26 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FIRDatabaseReference.h" + +@interface FTupleFirebase : NSObject + +@property (nonatomic, strong) FIRDatabaseReference * one; +@property (nonatomic, strong) FIRDatabaseReference * two; +@property (nonatomic, strong) FIRDatabaseReference * three; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleFirebase.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleFirebase.m new file mode 100644 index 00000000..3956f8be --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleFirebase.m @@ -0,0 +1,25 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FTupleFirebase.h" + +@implementation FTupleFirebase + +@synthesize one; +@synthesize two; +@synthesize three; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleNodePath.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleNodePath.h new file mode 100644 index 00000000..fbf62c7e --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleNodePath.h @@ -0,0 +1,28 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FPath.h" +#import "FNode.h" + +@interface FTupleNodePath : NSObject + +@property (nonatomic, strong) FPath* path; +@property (nonatomic, strong) id node; + +- (id) initWithNode:(id)aNode andPath:(FPath *)aPath; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleNodePath.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleNodePath.m new file mode 100644 index 00000000..eefc0c2b --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleNodePath.m @@ -0,0 +1,33 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FTupleNodePath.h" + +@implementation FTupleNodePath + +@synthesize path; +@synthesize node; + +- (id) initWithNode:(id)aNode andPath:(FPath *)aPath { + self = [super init]; + if (self) { + self.path = aPath; + self.node = aNode; + } + return self; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleObjectNode.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleObjectNode.h new file mode 100644 index 00000000..6fcb7462 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleObjectNode.h @@ -0,0 +1,27 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FNode.h" + +@interface FTupleObjectNode : NSObject + +- (id)initWithObject:(id)aObj andNode:(id)aNode; + +@property (nonatomic, strong) id node; +@property (nonatomic, strong) id obj; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleObjectNode.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleObjectNode.m new file mode 100644 index 00000000..4c533b02 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleObjectNode.m @@ -0,0 +1,32 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#import "FTupleObjectNode.h" + +@implementation FTupleObjectNode + +@synthesize obj; +@synthesize node; + +- (id)initWithObject:(id)aObj andNode:(id)aNode { + self = [super init]; + if (self) { + self.obj = aObj; + self.node = aNode; + } + return self; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleObjects.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleObjects.h new file mode 100644 index 00000000..4ff1fcff --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleObjects.h @@ -0,0 +1,24 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@interface FTupleObjects : NSObject + +@property (nonatomic, strong) id objA; +@property (nonatomic, strong) id objB; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleObjects.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleObjects.m new file mode 100644 index 00000000..a9e4c886 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleObjects.m @@ -0,0 +1,24 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FTupleObjects.h" + +@implementation FTupleObjects + +@synthesize objA; +@synthesize objB; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleOnDisconnect.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleOnDisconnect.h new file mode 100644 index 00000000..91ad5e41 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleOnDisconnect.h @@ -0,0 +1,27 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FTypedefs_Private.h" + +@interface FTupleOnDisconnect : NSObject + +@property (strong, nonatomic) NSString* pathString; +@property (strong, nonatomic) NSString* action; +@property (strong, nonatomic) id data; +@property (strong, nonatomic) fbt_void_nsstring_nsstring onComplete; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleOnDisconnect.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleOnDisconnect.m new file mode 100644 index 00000000..bd458220 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleOnDisconnect.m @@ -0,0 +1,26 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FTupleOnDisconnect.h" + +@implementation FTupleOnDisconnect + +@synthesize pathString; +@synthesize action; +@synthesize data; +@synthesize onComplete; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTuplePathValue.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTuplePathValue.h new file mode 100644 index 00000000..f7ed4231 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTuplePathValue.h @@ -0,0 +1,25 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class FPath; + +@interface FTuplePathValue : NSObject +@property (nonatomic, strong, readonly) FPath *path; +@property (nonatomic, strong, readonly) id value; +- (id) initWithPath:(FPath *)aPath value:(id)aValue; +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTuplePathValue.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTuplePathValue.m new file mode 100644 index 00000000..49240aa6 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTuplePathValue.m @@ -0,0 +1,38 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FTuplePathValue.h" +#import "FPath.h" + +@interface FTuplePathValue () +@property (nonatomic, strong, readwrite) id value; +@property (nonatomic, strong, readwrite) FPath *path; +@end + +@implementation FTuplePathValue +@synthesize path; +@synthesize value; + +- (id) initWithPath:(FPath *)aPath value:(id)aValue { + self = [super init]; + if (self) { + self.value = aValue; + self.path = aPath; + } + return self; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleRemovedQueriesEvents.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleRemovedQueriesEvents.h new file mode 100644 index 00000000..f986916e --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleRemovedQueriesEvents.h @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@interface FTupleRemovedQueriesEvents : NSObject +/** +* `FIRDatabaseQuery`s removed with [SyncPoint removeEventRegistration:] +*/ +@property (nonatomic, strong, readonly) NSArray *removedQueries; +/** +* cancel events as FEvent +*/ +@property (nonatomic, strong, readonly) NSArray *cancelEvents; + +- (id) initWithRemovedQueries:(NSArray *)removed cancelEvents:(NSArray *)events; +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleRemovedQueriesEvents.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleRemovedQueriesEvents.m new file mode 100644 index 00000000..818d16b2 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleRemovedQueriesEvents.m @@ -0,0 +1,37 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FTupleRemovedQueriesEvents.h" + +@interface FTupleRemovedQueriesEvents () +@property (nonatomic, strong, readwrite) NSArray *removedQueries; +@property (nonatomic, strong, readwrite) NSArray *cancelEvents; +@end + +@implementation FTupleRemovedQueriesEvents +@synthesize removedQueries; +@synthesize cancelEvents; + +- (id) initWithRemovedQueries:(NSArray *)removed cancelEvents:(NSArray *)events { + self = [super init]; + if (self) { + self.removedQueries = removed; + self.cancelEvents = events; + } + return self; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleSetIdPath.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleSetIdPath.h new file mode 100644 index 00000000..5133d6da --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleSetIdPath.h @@ -0,0 +1,27 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FPath.h" + +@interface FTupleSetIdPath : NSObject + +- (id) initWithSetId:(NSNumber *)aSetId andPath:(FPath *)aPath; + +@property (strong, nonatomic) NSNumber* setId; +@property (strong, nonatomic) FPath* path; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleSetIdPath.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleSetIdPath.m new file mode 100644 index 00000000..5d3312bb --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleSetIdPath.m @@ -0,0 +1,33 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FTupleSetIdPath.h" + +@implementation FTupleSetIdPath + +@synthesize path; +@synthesize setId; + +- (id) initWithSetId:(NSNumber *)aSetId andPath:(FPath *)aPath { + self = [super init]; + if (self) { + self.setId = aSetId; + self.path = aPath; + } + return self; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleStringNode.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleStringNode.h new file mode 100644 index 00000000..e3fec803 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleStringNode.h @@ -0,0 +1,27 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FNode.h" + +@interface FTupleStringNode : NSObject + +- (id)initWithString:(NSString *)aString andNode:(id)aNode; + +@property (nonatomic, strong) id node; +@property (nonatomic, strong) NSString* string; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleStringNode.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleStringNode.m new file mode 100644 index 00000000..f058a8e0 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleStringNode.m @@ -0,0 +1,34 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FTupleStringNode.h" + +@implementation FTupleStringNode + +@synthesize string; +@synthesize node; + +- (id)initWithString:(NSString *)aString andNode:(id)aNode { + self = [super init]; + if (self) { + self.string = aString; + self.node = aNode; + } + return self; +} + + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleTSN.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleTSN.h new file mode 100644 index 00000000..bc62b2df --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleTSN.h @@ -0,0 +1,25 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FTupleStringNode.h" + +@interface FTupleTSN : NSObject + +@property (nonatomic, strong) FTupleStringNode* from; +@property (nonatomic, strong) FTupleStringNode* to; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleTSN.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleTSN.m new file mode 100644 index 00000000..348c3197 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleTSN.m @@ -0,0 +1,24 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FTupleTSN.h" + +@implementation FTupleTSN + +@synthesize from; +@synthesize to; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleTransaction.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleTransaction.h new file mode 100644 index 00000000..c9dcf4b5 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleTransaction.h @@ -0,0 +1,74 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FPath.h" +#import "FTypedefs_Private.h" +#import "FTypedefs.h" + +@interface FTupleTransaction : NSObject + +@property (nonatomic, strong) FPath* path; +@property (nonatomic, copy) fbt_transactionresult_mutabledata update; +@property (nonatomic, copy) fbt_void_nserror_bool_datasnapshot onComplete; +@property (nonatomic) FTransactionStatus status; + +/** +* Used when combining transaction at different locations to figure out which one goes first. +*/ +@property (nonatomic, strong) NSNumber* order; +/** +* Whether to raise local events for this transaction +*/ +@property (nonatomic) BOOL applyLocally; + +/** +* Count how many times we've retried the transaction +*/ +@property (nonatomic) int retryCount; + +/** +* Function to call to clean up our listener +*/ +@property (nonatomic, copy) fbt_void_void unwatcher; + +/** +* Stores why a transaction was aborted +*/ +@property (nonatomic, strong, readonly) NSString* abortStatus; +@property (nonatomic, strong, readonly) NSString* abortReason; + +- (void)setAbortStatus:(NSString *)abortStatus reason:(NSString *)reason; +- (NSError *)abortError; + +@property (nonatomic, strong) NSNumber *currentWriteId; + +/** +* Stores the input snapshot, before the update +*/ +@property (nonatomic, strong) id currentInputSnapshot; + +/** +* Stores the unresolved (for server values) output snapshot, after the update +*/ +@property (nonatomic, strong) id currentOutputSnapshotRaw; + +/** + * Stores the resolved (for server values) output snapshot, after the update + */ +@property (nonatomic, strong) id currentOutputSnapshotResolved; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleTransaction.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleTransaction.m new file mode 100644 index 00000000..bcff54ef --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleTransaction.m @@ -0,0 +1,38 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FTupleTransaction.h" +#import "FUtilities.h" + +@interface FTupleTransaction () + +@property (nonatomic, strong) NSString *abortStatus; +@property (nonatomic, strong) NSString *abortReason; + +@end + +@implementation FTupleTransaction + +- (void)setAbortStatus:(NSString *)abortStatus reason:(NSString *)reason { + self.abortStatus = abortStatus; + self.abortReason = reason; +} + +- (NSError *)abortError { + return (self.abortStatus != nil) ? [FUtilities errorForStatus:self.abortStatus andReason:self.abortReason] : nil; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleUserCallback.h b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleUserCallback.h new file mode 100644 index 00000000..d598217f --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleUserCallback.h @@ -0,0 +1,31 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "FTypedefs.h" +#import "FQueryParams.h" + +@interface FTupleUserCallback : NSObject + +- (id) initWithHandle:(NSUInteger)handle; + +@property (nonatomic, copy) fbt_void_datasnapshot_nsstring datasnapshotPrevnameCallback; +@property (nonatomic, copy) fbt_void_datasnapshot datasnapshotCallback; +@property (nonatomic, copy) fbt_void_nserror cancelCallback; +@property (nonatomic, copy) FQueryParams* queryParams; +@property (nonatomic) NSUInteger handle; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleUserCallback.m b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleUserCallback.m new file mode 100644 index 00000000..dc33bbd4 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleUserCallback.m @@ -0,0 +1,35 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FTupleUserCallback.h" + +@implementation FTupleUserCallback + +@synthesize datasnapshotCallback; +@synthesize datasnapshotPrevnameCallback; +@synthesize cancelCallback; +@synthesize queryParams; +@synthesize handle; + +- (id) initWithHandle:(NSUInteger)theHandle { + self = [super init]; + if (self) { + self.handle = theHandle; + } + return self; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FArraySortedDictionary.h b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FArraySortedDictionary.h new file mode 100644 index 00000000..3ab74762 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FArraySortedDictionary.h @@ -0,0 +1,21 @@ +#import +#import "FImmutableSortedDictionary.h" + +/** + * This is an array backed implementation of FImmutableSortedDictionary. It uses arrays and linear lookups to achieve + * good memory efficiency while maintaining good performance for small collections. It also uses less allocations than + * a comparable red black tree. To avoid degrading performance with increasing collection size it will automatically + * convert to a FTreeSortedDictionary after an insert call above a certain threshold. + */ +@interface FArraySortedDictionary : FImmutableSortedDictionary + ++ (FArraySortedDictionary *)fromDictionary:(NSDictionary *)dictionary withComparator:(NSComparator)comparator; + +- (id)initWithComparator:(NSComparator)comparator; + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, copy, readonly) NSComparator comparator; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FArraySortedDictionary.m b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FArraySortedDictionary.m new file mode 100644 index 00000000..15d2d8bd --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FArraySortedDictionary.m @@ -0,0 +1,266 @@ +#import "FArraySortedDictionary.h" +#import "FTreeSortedDictionary.h" + +@interface FArraySortedDictionaryEnumerator : NSEnumerator + +- (id)initWithKeys:(NSArray *)keys startPos:(NSInteger)pos isReverse:(BOOL)reverse; +- (id)nextObject; + +@property (nonatomic) NSInteger pos; +@property (nonatomic) BOOL reverse; +@property (nonatomic, strong) NSArray *keys; + +@end + +@implementation FArraySortedDictionaryEnumerator + +- (id)initWithKeys:(NSArray *)keys startPos:(NSInteger)pos isReverse:(BOOL)reverse +{ + self = [super init]; + if (self != nil) { + self->_pos = pos; + self->_reverse = reverse; + self->_keys = keys; + } + return self; +} + +- (id)nextObject +{ + NSInteger pos = self->_pos; + if (pos >= 0 && pos < self.keys.count) { + if (self.reverse) { + self->_pos--; + } else { + self->_pos++; + } + return self.keys[pos]; + } else { + return nil; + } +} + +@end + +@interface FArraySortedDictionary () + +- (id)initWithComparator:(NSComparator)comparator; + +@property (nonatomic, copy, readwrite) NSComparator comparator; +@property (nonatomic, strong) NSArray *keys; +@property (nonatomic, strong) NSArray *values; + +@end + +@implementation FArraySortedDictionary + ++ (FArraySortedDictionary *)fromDictionary:(NSDictionary *)dictionary withComparator:(NSComparator)comparator +{ + NSMutableArray *keys = [NSMutableArray arrayWithCapacity:dictionary.count]; + [dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + [keys addObject:key]; + }]; + [keys sortUsingComparator:comparator]; + + [keys enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + if (idx > 0) { + if (comparator(keys[idx - 1], obj) != NSOrderedAscending) { + [NSException raise:NSInvalidArgumentException format:@"Can't create FImmutableSortedDictionary with keys with same ordering!"]; + } + } + }]; + + NSMutableArray *values = [NSMutableArray arrayWithCapacity:keys.count]; + NSInteger pos = 0; + for (id key in keys) { + values[pos++] = dictionary[key]; + } + NSAssert(values.count == keys.count, @"We added as many keys as values"); + return [[FArraySortedDictionary alloc] initWithComparator:comparator keys:keys values:values]; +} + +- (id)initWithComparator:(NSComparator)comparator +{ + self = [super init]; + if (self != nil) { + self->_comparator = comparator; + self->_keys = [NSArray array]; + self->_values = [NSArray array]; + } + return self; +} + +- (id)initWithComparator:(NSComparator)comparator keys:(NSArray *)keys values:(NSArray *)values +{ + self = [super init]; + if (self != nil) { + self->_comparator = comparator; + self->_keys = keys; + self->_values = values; + } + return self; +} + +- (NSInteger) findInsertPositionForKey:(id)key +{ + NSInteger newPos = 0; + while (newPos < self.keys.count && self.comparator(self.keys[newPos], key) < NSOrderedSame) { + newPos++; + } + return newPos; +} + +- (NSInteger) findKey:(id)key +{ + if (key == nil) { + return NSNotFound; + } + for (NSInteger pos = 0; pos < self.keys.count; pos++) { + NSComparisonResult result = self.comparator(key, self.keys[pos]); + if (result == NSOrderedSame) { + return pos; + } else if (result == NSOrderedAscending) { + return NSNotFound; + } + } + return NSNotFound; +} + +- (FImmutableSortedDictionary *) insertKey:(id)key withValue:(id)value +{ + NSInteger pos = [self findKey:key]; + + if (pos == NSNotFound) { + /* + * If we're above the threshold we want to convert it to a tree backed implementation to not have + * degrading performance + */ + if (self.count >= SORTED_DICTIONARY_ARRAY_TO_RB_TREE_SIZE_THRESHOLD) { + NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:self.count]; + for (NSInteger i = 0; i < self.keys.count; i++) { + dict[self.keys[i]] = self.values[i]; + } + dict[key] = value; + return [FTreeSortedDictionary fromDictionary:dict withComparator:self.comparator]; + } else { + NSMutableArray *newKeys = [NSMutableArray arrayWithArray:self.keys]; + NSMutableArray *newValues = [NSMutableArray arrayWithArray:self.values]; + NSInteger newPos = [self findInsertPositionForKey:key]; + [newKeys insertObject:key atIndex:newPos]; + [newValues insertObject:value atIndex:newPos]; + return [[FArraySortedDictionary alloc] initWithComparator:self.comparator keys:newKeys values:newValues]; + } + } else { + NSMutableArray *newKeys = [NSMutableArray arrayWithArray:self.keys]; + NSMutableArray *newValues = [NSMutableArray arrayWithArray:self.values]; + newKeys[pos] = key; + newValues[pos] = value; + return [[FArraySortedDictionary alloc] initWithComparator:self.comparator keys:newKeys values:newValues]; + } +} + +- (FImmutableSortedDictionary *) removeKey:(id)key +{ + NSInteger pos = [self findKey:key]; + if (pos == NSNotFound) { + return self; + } else { + NSMutableArray *newKeys = [NSMutableArray arrayWithArray:self.keys]; + NSMutableArray *newValues = [NSMutableArray arrayWithArray:self.values]; + [newKeys removeObjectAtIndex:pos]; + [newValues removeObjectAtIndex:pos]; + return [[FArraySortedDictionary alloc] initWithComparator:self.comparator keys:newKeys values:newValues]; + } +} + +- (id) get:(id)key +{ + NSInteger pos = [self findKey:key]; + if (pos == NSNotFound) { + return nil; + } else { + return self.values[pos]; + } +} + +- (id) getPredecessorKey:(id) key { + NSInteger pos = [self findKey:key]; + if (pos == NSNotFound) { + [NSException raise:NSInternalInconsistencyException format:@"Can't get predecessor key for non-existent key"]; + return nil; + } else if (pos == 0) { + return nil; + } else { + return self.keys[pos - 1]; + } +} + +- (BOOL) isEmpty { + return self.keys.count == 0; +} + +- (int) count +{ + return (int)self.keys.count; +} + +- (id) minKey +{ + return [self.keys firstObject]; +} + +- (id) maxKey +{ + return [self.keys lastObject]; +} + +- (void) enumerateKeysAndObjectsUsingBlock:(void (^)(id, id, BOOL *))block +{ + [self enumerateKeysAndObjectsReverse:NO usingBlock:block]; +} + +- (void) enumerateKeysAndObjectsReverse:(BOOL)reverse usingBlock:(void (^)(id, id, BOOL *))block +{ + if (reverse) { + BOOL stop = NO; + for (NSInteger i = self.keys.count - 1; i >= 0; i--) { + block(self.keys[i], self.values[i], &stop); + if (stop) return; + } + } else { + BOOL stop = NO; + for (NSInteger i = 0; i < self.keys.count; i++) { + block(self.keys[i], self.values[i], &stop); + if (stop) return; + } + } +} + +- (BOOL) contains:(id)key { + return [self findKey:key] != NSNotFound; +} + +- (NSEnumerator *) keyEnumerator { + return [self.keys objectEnumerator]; +} + +- (NSEnumerator *) keyEnumeratorFrom:(id)startKey { + NSInteger startPos = [self findInsertPositionForKey:startKey]; + return [[FArraySortedDictionaryEnumerator alloc] initWithKeys:self.keys startPos:startPos isReverse:NO]; +} + +- (NSEnumerator *) reverseKeyEnumerator { + return [self.keys reverseObjectEnumerator]; +} + +- (NSEnumerator *) reverseKeyEnumeratorFrom:(id)startKey { + NSInteger startPos = [self findInsertPositionForKey:startKey]; + // if there's no exact match, findKeyOrInsertPosition will return the index *after* the closest match, but + // since this is a reverse iterator, we want to start just *before* the closest match. + if (startPos >= self.keys.count || self.comparator(self.keys[startPos], startKey) != NSOrderedSame) { + startPos -= 1; + } + return [[FArraySortedDictionaryEnumerator alloc] initWithKeys:self.keys startPos:startPos isReverse:YES]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FImmutableSortedDictionary.h b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FImmutableSortedDictionary.h new file mode 100644 index 00000000..d6687d86 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FImmutableSortedDictionary.h @@ -0,0 +1,54 @@ +/** + * @fileoverview Implementation of an immutable SortedMap using a Left-leaning + * Red-Black Tree, adapted from the implementation in Mugs + * (http://mads379.github.com/mugs/) by Mads Hartmann Jensen + * (mads379@gmail.com). + * + * Original paper on Left-leaning Red-Black Trees: + * http://www.cs.princeton.edu/~rs/talks/LLRB/LLRB.pdf + * + * Invariant 1: No red node has a red child + * Invariant 2: Every leaf path has the same number of black nodes + * Invariant 3: Only the left child can be red (left leaning) + */ + +#import + +/** + * The size threshold where we use a tree backed sorted map instead of an array backed sorted map. + * This is a more or less arbitrary chosen value, that was chosen to be large enough to fit most of object kind + * of Firebase data, but small enough to not notice degradation in performance for inserting and lookups. + * Feel free to empirically determine this constant, but don't expect much gain in real world performance. + */ +#define SORTED_DICTIONARY_ARRAY_TO_RB_TREE_SIZE_THRESHOLD 25 + +@interface FImmutableSortedDictionary : NSObject + ++ (FImmutableSortedDictionary *)dictionaryWithComparator:(NSComparator)comparator; ++ (FImmutableSortedDictionary *)fromDictionary:(NSDictionary *)dictionary withComparator:(NSComparator)comparator; + +- (FImmutableSortedDictionary *) insertKey:(id)aKey withValue:(id)aValue; +- (FImmutableSortedDictionary *) removeKey:(id)aKey; +- (id) get:(id) key; +- (id) getPredecessorKey:(id) key; +- (BOOL) isEmpty; +- (int) count; +- (id) minKey; +- (id) maxKey; +- (void) enumerateKeysAndObjectsUsingBlock:(void(^)(id key, id value, BOOL *stop))block; +- (void) enumerateKeysAndObjectsReverse:(BOOL)reverse usingBlock:(void(^)(id key, id value, BOOL *stop))block; +- (BOOL) contains:(id)key; +- (NSEnumerator *) keyEnumerator; +- (NSEnumerator *) keyEnumeratorFrom:(id)startKey; +- (NSEnumerator *) reverseKeyEnumerator; +- (NSEnumerator *) reverseKeyEnumeratorFrom:(id)startKey; + +#pragma mark - +#pragma mark Methods similar to NSMutableDictionary + +- (FImmutableSortedDictionary *) setObject:(id)anObject forKey:(id)aKey; +- (id) objectForKey:(id)key; +- (FImmutableSortedDictionary *) removeObjectForKey:(id)aKey; + +@end + diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FImmutableSortedDictionary.m b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FImmutableSortedDictionary.m new file mode 100644 index 00000000..659c63b1 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FImmutableSortedDictionary.m @@ -0,0 +1,142 @@ +#import "FImmutableSortedDictionary.h" +#import "FArraySortedDictionary.h" +#import "FTreeSortedDictionary.h" + +#define THROW_ABSTRACT_METHOD_EXCEPTION(sel) do { \ + @throw [NSException exceptionWithName:NSInternalInconsistencyException \ + reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(sel)] \ + userInfo:nil]; \ +} while(0) + +@implementation FImmutableSortedDictionary + ++ (FImmutableSortedDictionary *)dictionaryWithComparator:(NSComparator)comparator +{ + return [[FArraySortedDictionary alloc] initWithComparator:comparator]; +} + ++ (FImmutableSortedDictionary *)fromDictionary:(NSDictionary *)dictionary withComparator:(NSComparator)comparator +{ + if (dictionary.count <= SORTED_DICTIONARY_ARRAY_TO_RB_TREE_SIZE_THRESHOLD) { + return [FArraySortedDictionary fromDictionary:dictionary withComparator:comparator]; + } else { + return [FTreeSortedDictionary fromDictionary:dictionary withComparator:comparator]; + } +} + +- (FImmutableSortedDictionary *) insertKey:(id)aKey withValue:(id)aValue { + THROW_ABSTRACT_METHOD_EXCEPTION(@selector(insertKey:withValue:)); +} + +- (FImmutableSortedDictionary *) removeKey:(id)aKey { + THROW_ABSTRACT_METHOD_EXCEPTION(@selector(removeKey:)); +} + +- (id) get:(id) key { + THROW_ABSTRACT_METHOD_EXCEPTION(@selector(get:)); +} + +- (id) getPredecessorKey:(id) key { + THROW_ABSTRACT_METHOD_EXCEPTION(@selector(getPredecessorKey:)); +} + +- (BOOL) isEmpty { + THROW_ABSTRACT_METHOD_EXCEPTION(@selector(isEmpty)); +} + +- (int) count { + THROW_ABSTRACT_METHOD_EXCEPTION(@selector((count))); +} + +- (id) minKey { + THROW_ABSTRACT_METHOD_EXCEPTION(@selector(minKey)); +} + +- (id) maxKey { + THROW_ABSTRACT_METHOD_EXCEPTION(@selector(maxKey)); +} + +- (void) enumerateKeysAndObjectsUsingBlock:(void (^)(id, id, BOOL *))block { + THROW_ABSTRACT_METHOD_EXCEPTION(@selector(enumerateKeysAndObjectsUsingBlock:)); +} + +- (void) enumerateKeysAndObjectsReverse:(BOOL)reverse usingBlock:(void (^)(id, id, BOOL *))block { + THROW_ABSTRACT_METHOD_EXCEPTION(@selector(enumerateKeysAndObjectsReverse:usingBlock:)); +} + +- (BOOL) contains:(id)key { + THROW_ABSTRACT_METHOD_EXCEPTION(@selector(contains:)); +} + +- (NSEnumerator *) keyEnumerator { + THROW_ABSTRACT_METHOD_EXCEPTION(@selector(keyEnumerator)); +} + +- (NSEnumerator *) keyEnumeratorFrom:(id)startKey { + THROW_ABSTRACT_METHOD_EXCEPTION(@selector(keyEnumeratorFrom:)); +} + +- (NSEnumerator *) reverseKeyEnumerator { + THROW_ABSTRACT_METHOD_EXCEPTION(@selector(reverseKeyEnumerator)); +} + +- (NSEnumerator *) reverseKeyEnumeratorFrom:(id)startKey { + THROW_ABSTRACT_METHOD_EXCEPTION(@selector(reverseKeyEnumeratorFrom:)); +} + +- (BOOL)isEqual:(id)object { + if (![object isKindOfClass:[FImmutableSortedDictionary class]]) { + return NO; + } + FImmutableSortedDictionary *other = (FImmutableSortedDictionary *)object; + if (self.count != other.count) { + return NO; + } + __block BOOL isEqual = YES; + [self enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { + id otherValue = [other objectForKey:key]; + isEqual = isEqual && (value == otherValue || [value isEqual:otherValue]); + *stop = !isEqual; + }]; + return isEqual; +} + +- (NSUInteger)hash { + __block NSUInteger hash = 0; + [self enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { + hash = (hash * 31 + [key hash]) * 17 + [value hash]; + }]; + return hash; +} + +- (NSString *)description { + NSMutableString *str = [[NSMutableString alloc] init]; + __block BOOL first = YES; + [str appendString:@"{ "]; + [self enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { + if (!first) { + [str appendString:@", "]; + } + first = NO; + [str appendString:[NSString stringWithFormat:@"%@: %@", key, value]]; + }]; + [str appendString:@" }"]; + return str; +} + +#pragma mark - +#pragma mark Methods similar to NSMutableDictionary + +- (FImmutableSortedDictionary *) setObject:(__unsafe_unretained id)anObject forKey:(__unsafe_unretained id)aKey { + return [self insertKey:aKey withValue:anObject]; +} + +- (FImmutableSortedDictionary *) removeObjectForKey:(__unsafe_unretained id)aKey { + return [self removeKey:aKey]; +} + +- (id) objectForKey:(__unsafe_unretained id)key { + return [self get:key]; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FImmutableSortedSet.h b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FImmutableSortedSet.h new file mode 100644 index 00000000..ac15c2f0 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FImmutableSortedSet.h @@ -0,0 +1,22 @@ +#import + +@interface FImmutableSortedSet : NSObject + ++ (FImmutableSortedSet *)setWithKeysFromDictionary:(NSDictionary *)array comparator:(NSComparator)comparator; + +- (BOOL)containsObject:(id)object; +- (FImmutableSortedSet *)addObject:(id)object; +- (FImmutableSortedSet *)removeObject:(id)object; +- (id)firstObject; +- (id)lastObject; +- (NSUInteger)count; +- (BOOL)isEmpty; + +- (id)predecessorEntry:(id)entry; + +- (void)enumerateObjectsUsingBlock:(void (^)(id obj, BOOL *stop))block; +- (void)enumerateObjectsReverse:(BOOL)reverse usingBlock:(void (^)(id obj, BOOL *stop))block; + +- (NSEnumerator *)objectEnumerator; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FImmutableSortedSet.m b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FImmutableSortedSet.m new file mode 100644 index 00000000..1953af1a --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FImmutableSortedSet.m @@ -0,0 +1,115 @@ +#import "FImmutableSortedSet.h" +#import "FImmutableSortedDictionary.h" + +@interface FImmutableSortedSet () + +@property (nonatomic, strong) FImmutableSortedDictionary *dictionary; + +@end + +@implementation FImmutableSortedSet + ++ (FImmutableSortedSet *)setWithKeysFromDictionary:(NSDictionary *)dictionary comparator:(NSComparator)comparator +{ + FImmutableSortedDictionary *setDict = [FImmutableSortedDictionary fromDictionary:dictionary withComparator:comparator]; + return [[FImmutableSortedSet alloc] initWithDictionary:setDict]; +} + +- (id)initWithDictionary:(FImmutableSortedDictionary *)dictionary +{ + self = [super init]; + if (self != nil) { + self->_dictionary = dictionary; + } + return self; +} + +- (BOOL)contains:(id)object +{ + return [self.dictionary contains:object]; +} + +- (FImmutableSortedSet *)addObject:(id)object +{ + FImmutableSortedDictionary *newDictionary = [self.dictionary insertKey:object withValue:[NSNull null]]; + if (newDictionary != self.dictionary) { + return [[FImmutableSortedSet alloc] initWithDictionary:newDictionary]; + } else { + return self; + } +} + +- (FImmutableSortedSet *)removeObject:(id)object +{ + FImmutableSortedDictionary *newDictionary = [self.dictionary removeObjectForKey:object]; + if (newDictionary != self.dictionary) { + return [[FImmutableSortedSet alloc] initWithDictionary:newDictionary]; + } else { + return self; + } +} + +- (BOOL)containsObject:(id)object +{ + return [self.dictionary contains:object]; +} + +- (id)firstObject +{ + return [self.dictionary minKey]; +} + +- (id)lastObject +{ + return [self.dictionary maxKey]; +} + +- (id)predecessorEntry:(id)entry +{ + return [self.dictionary getPredecessorKey:entry]; +} + +- (NSUInteger)count +{ + return [self.dictionary count]; +} + +- (BOOL)isEmpty +{ + return [self.dictionary isEmpty]; +} + +- (void)enumerateObjectsUsingBlock:(void (^)(id, BOOL *))block +{ + [self enumerateObjectsReverse:NO usingBlock:block]; +} + +- (void)enumerateObjectsReverse:(BOOL)reverse usingBlock:(void (^)(id, BOOL *))block +{ + [self.dictionary enumerateKeysAndObjectsReverse:reverse usingBlock:^(id key, id value, BOOL *stop) { + block(key, stop); + }]; +} + +- (NSEnumerator *)objectEnumerator +{ + return [self.dictionary keyEnumerator]; +} + +- (NSString *)description +{ + NSMutableString *str = [[NSMutableString alloc] init]; + __block BOOL first = YES; + [str appendString:@"FImmutableSortedSet ( "]; + [self enumerateObjectsUsingBlock:^(id obj, BOOL *stop) { + if (!first) { + [str appendString:@", "]; + } + first = NO; + [str appendString:[NSString stringWithFormat:@"%@", obj]]; + }]; + [str appendString:@" )"]; + return str; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBEmptyNode.h b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBEmptyNode.h new file mode 100644 index 00000000..833f2a55 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBEmptyNode.h @@ -0,0 +1,27 @@ +#import +#import "FLLRBNode.h" + +@interface FLLRBEmptyNode : NSObject + ++ (id)emptyNode; + +- (id)copyWith:(id) aKey withValue:(id) aValue withColor:(FLLRBColor*) aColor withLeft:(id)aLeft withRight:(id)aRight; +- (id) insertKey:(id) aKey forValue:(id)aValue withComparator:(NSComparator)aComparator; +- (id) remove:(id) aKey withComparator:(NSComparator)aComparator; +- (int) count; +- (BOOL) isEmpty; +- (BOOL) inorderTraversal:(BOOL (^)(id key, id value))action; +- (BOOL) reverseTraversal:(BOOL (^)(id key, id value))action; +- (id) min; +- (id) minKey; +- (id) maxKey; +- (BOOL) isRed; +- (int) check; + +@property (nonatomic, strong) id key; +@property (nonatomic, strong) id value; +@property (nonatomic, strong) FLLRBColor* color; +@property (nonatomic, strong) id left; +@property (nonatomic, strong) id right; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBEmptyNode.m b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBEmptyNode.m new file mode 100644 index 00000000..3ca6f062 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBEmptyNode.m @@ -0,0 +1,72 @@ +#import "FLLRBEmptyNode.h" +#import "FLLRBValueNode.h" + +@implementation FLLRBEmptyNode + +@synthesize key, value, color, left, right; + +- (NSString *) description { + return [NSString stringWithFormat:@"[key=%@ val=%@ color=%@]", key, value, + (color != nil ? @"true" : @"false")]; +} + ++ (id)emptyNode +{ + static dispatch_once_t pred = 0; + __strong static id _sharedObject = nil; + dispatch_once(&pred, ^{ + _sharedObject = [[self alloc] init]; // or some other init method + }); + return _sharedObject; +} + +- (id)copyWith:(id) aKey withValue:(id) aValue withColor:(FLLRBColor*) aColor withLeft:(id)aLeft withRight:(id)aRight { + return self; +} + +- (id) insertKey:(id) aKey forValue:(id)aValue withComparator:(NSComparator)aComparator { + FLLRBValueNode* result = [[FLLRBValueNode alloc] initWithKey:aKey withValue:aValue withColor:nil withLeft:nil withRight:nil]; + return result; +} + +- (id) remove:(id) key withComparator:(NSComparator)aComparator { + return self; +} + +- (int) count { + return 0; +} + +- (BOOL) isEmpty { + return YES; +} + +- (BOOL) inorderTraversal:(BOOL (^)(id key, id value))action { + return NO; +} + +- (BOOL) reverseTraversal:(BOOL (^)(id key, id value))action { + return NO; +} + +- (id) min { + return self; +} + +- (id) minKey { + return nil; +} + +- (id) maxKey { + return nil; +} + +- (BOOL) isRed { + return NO; +} + +- (int) check { + return 0; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBNode.h b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBNode.h new file mode 100644 index 00000000..09b234c6 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBNode.h @@ -0,0 +1,29 @@ +#import + +#define RED @true +#define BLACK @false + +typedef NSNumber FLLRBColor; + +@protocol FLLRBNode + +- (id)copyWith:(id) aKey withValue:(id) aValue withColor:(FLLRBColor*) aColor withLeft:(id)aLeft withRight:(id)aRight; +- (id) insertKey:(id) aKey forValue:(id)aValue withComparator:(NSComparator)aComparator; +- (id) remove:(id) key withComparator:(NSComparator)aComparator; +- (int) count; +- (BOOL) isEmpty; +- (BOOL) inorderTraversal:(BOOL (^)(id key, id value))action; +- (BOOL) reverseTraversal:(BOOL (^)(id key, id value))action; +- (id) min; +- (id) minKey; +- (id) maxKey; +- (BOOL) isRed; +- (int) check; + +@property (nonatomic, strong) id key; +@property (nonatomic, strong) id value; +@property (nonatomic, strong) FLLRBColor* color; +@property (nonatomic, strong) id left; +@property (nonatomic, strong) id right; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBValueNode.h b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBValueNode.h new file mode 100644 index 00000000..50438bb3 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBValueNode.h @@ -0,0 +1,29 @@ +#import +#import "FLLRBNode.h" + +@interface FLLRBValueNode : NSObject + + +- (id)initWithKey:(id) key withValue:(id) value withColor:(FLLRBColor*) color withLeft:(id)left withRight:(id)right; +- (id)copyWith:(id) aKey withValue:(id) aValue withColor:(FLLRBColor*) aColor withLeft:(id)aLeft withRight:(id)aRight; +- (id) insertKey:(id) aKey forValue:(id)aValue withComparator:(NSComparator)aComparator; +- (id) remove:(id) aKey withComparator:(NSComparator)aComparator; +- (int) count; +- (BOOL) isEmpty; +- (BOOL) inorderTraversal:(BOOL (^)(id key, id value))action; +- (BOOL) reverseTraversal:(BOOL (^)(id key, id value))action; +- (id) min; +- (id) minKey; +- (id) maxKey; +- (BOOL) isRed; +- (int) check; + +- (BOOL) checkMaxDepth; + +@property (nonatomic, strong) id key; +@property (nonatomic, strong) id value; +@property (nonatomic, strong) FLLRBColor* color; +@property (nonatomic, strong) id left; +@property (nonatomic, strong) id right; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBValueNode.m b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBValueNode.m new file mode 100644 index 00000000..831b97fc --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBValueNode.m @@ -0,0 +1,230 @@ +#import "FLLRBValueNode.h" +#import "FLLRBEmptyNode.h" + +@implementation FLLRBValueNode + +@synthesize key, value, color, left, right; + +- (NSString *) description { + return [NSString stringWithFormat:@"[key=%@ val=%@ color=%@]", key, value, + (color != nil ? @"true" : @"false")]; +} + +- (id)initWithKey:(__unsafe_unretained id) aKey withValue:(__unsafe_unretained id) aValue withColor:(__unsafe_unretained FLLRBColor*) aColor withLeft:(__unsafe_unretained id)aLeft withRight:(__unsafe_unretained id)aRight +{ + self = [super init]; + if (self) { + self.key = aKey; + self.value = aValue; + self.color = aColor != nil ? aColor : RED; + self.left = aLeft != nil ? aLeft : [FLLRBEmptyNode emptyNode]; + self.right = aRight != nil ? aRight : [FLLRBEmptyNode emptyNode]; + } + return self; +} + +- (id)copyWith:(__unsafe_unretained id) aKey withValue:(__unsafe_unretained id) aValue withColor:(__unsafe_unretained FLLRBColor*) aColor withLeft:(__unsafe_unretained id)aLeft withRight:(__unsafe_unretained id)aRight { + return [[FLLRBValueNode alloc] initWithKey:(aKey != nil) ? aKey : self.key + withValue:(aValue != nil) ? aValue : self.value + withColor:(aColor != nil) ? aColor : self.color + withLeft:(aLeft != nil) ? aLeft : self.left + withRight:(aRight != nil) ? aRight : self.right]; +} + +- (int) count { + return [self.left count] + 1 + [self.right count]; +} + +- (BOOL) isEmpty { + return NO; +} + +/** +* Early terminates if aciton returns YES. +* @return The first truthy value returned by action, or the last falsey value returned by action. +*/ +- (BOOL) inorderTraversal:(BOOL (^)(id key, id value))action { + return [self.left inorderTraversal:action] || + action(self.key, self.value) || + [self.right inorderTraversal:action]; +} + +- (BOOL) reverseTraversal:(BOOL (^)(id key, id value))action { + return [self.right reverseTraversal:action] || + action(self.key, self.value) || + [self.left reverseTraversal:action]; +} + +- (id) min { + if([self.left isEmpty]) { + return self; + } + else { + return [self.left min]; + } +} + +- (id) minKey { + return [[self min] key]; +} + +- (id) maxKey { + if([self.right isEmpty]) { + return self.key; + } + else { + return [self.right maxKey]; + } +} + +- (id) insertKey:(__unsafe_unretained id) aKey forValue:(__unsafe_unretained id)aValue withComparator:(NSComparator)aComparator { + NSComparisonResult cmp = aComparator(aKey, self.key); + FLLRBValueNode* n = self; + + if(cmp == NSOrderedAscending) { + n = [n copyWith:nil withValue:nil withColor:nil withLeft:[n.left insertKey:aKey forValue:aValue withComparator:aComparator] withRight:nil]; + } + else if(cmp == NSOrderedSame) { + n = [n copyWith:nil withValue:aValue withColor:nil withLeft:nil withRight:nil]; + } + else { + n = [n copyWith:nil withValue:nil withColor:nil withLeft:nil withRight:[n.right insertKey:aKey forValue:aValue withComparator:aComparator]]; + } + + return [n fixUp]; +} + +- (id) removeMin { + + if([self.left isEmpty]) { + return [FLLRBEmptyNode emptyNode]; + } + + FLLRBValueNode* n = self; + if(! [n.left isRed] && ! [n.left.left isRed]) { + n = [n moveRedLeft]; + } + + n = [n copyWith:nil withValue:nil withColor:nil withLeft:[(FLLRBValueNode*)n.left removeMin] withRight:nil]; + return [n fixUp]; +} + + +- (id) fixUp { + FLLRBValueNode* n = self; + if([n.right isRed] && ! [n.left isRed]) n = [n rotateLeft]; + if([n.left isRed] && [n.left.left isRed]) n = [n rotateRight]; + if([n.left isRed] && [n.right isRed]) n = [n colorFlip]; + return n; +} + +- (FLLRBValueNode*) moveRedLeft { + FLLRBValueNode* n = [self colorFlip]; + if([n.right.left isRed]) { + n = [n copyWith:nil withValue:nil withColor:nil withLeft:nil withRight:[(FLLRBValueNode*)n.right rotateRight]]; + n = [n rotateLeft]; + n = [n colorFlip]; + } + return n; +} + +- (FLLRBValueNode*) moveRedRight { + FLLRBValueNode* n = [self colorFlip]; + if([n.left.left isRed]) { + n = [n rotateRight]; + n = [n colorFlip]; + } + return n; +} + +- (id) rotateLeft { + id nl = [self copyWith:nil withValue:nil withColor:RED withLeft:nil withRight:self.right.left]; + return [self.right copyWith:nil withValue:nil withColor:self.color withLeft:nl withRight:nil];; +} + +- (id) rotateRight { + id nr = [self copyWith:nil withValue:nil withColor:RED withLeft:self.left.right withRight:nil]; + return [self.left copyWith:nil withValue:nil withColor:self.color withLeft:nil withRight:nr]; +} + +- (id) colorFlip { + id nleft = [self.left copyWith:nil withValue:nil withColor:[NSNumber numberWithBool:![self.left.color boolValue]] withLeft:nil withRight:nil]; + id nright = [self.right copyWith:nil withValue:nil withColor:[NSNumber numberWithBool:![self.right.color boolValue]] withLeft:nil withRight:nil]; + + return [self copyWith:nil withValue:nil withColor:[NSNumber numberWithBool:![self.color boolValue]] withLeft:nleft withRight:nright]; +} + +- (id) remove:(__unsafe_unretained id) aKey withComparator:(NSComparator)comparator { + id smallest; + FLLRBValueNode* n = self; + + if(comparator(aKey, n.key) == NSOrderedAscending) { + if(![n.left isEmpty] && ![n.left isRed] && ![n.left.left isRed]) { + n = [n moveRedLeft]; + } + n = [n copyWith:nil withValue:nil withColor:nil withLeft:[n.left remove:aKey withComparator:comparator] withRight:nil]; + } + else { + if([n.left isRed]) { + n = [n rotateRight]; + } + + if(![n.right isEmpty] && ![n.right isRed] && ![n.right.left isRed]) { + n = [n moveRedRight]; + } + + if(comparator(aKey, n.key) == NSOrderedSame) { + if([n.right isEmpty]) { + return [FLLRBEmptyNode emptyNode]; + } + else { + smallest = [n.right min]; + n = [n copyWith:smallest.key withValue:smallest.value withColor:nil withLeft:nil withRight:[(FLLRBValueNode*)n.right removeMin]]; + } + } + n = [n copyWith:nil withValue:nil withColor:nil withLeft:nil withRight:[n.right remove:aKey withComparator:comparator]]; + } + return [n fixUp]; +} + +- (BOOL) isRed { + return [self.color boolValue]; +} + +- (BOOL) checkMaxDepth { + int blackDepth = [self check]; + if(pow(2.0, blackDepth) <= ([self count] + 1)) { + return YES; + } + else { + return NO; + } +} + +- (int) check { + int blackDepth = 0; + + if([self isRed] && [self.left isRed]) { + @throw [[NSException alloc] initWithName:@"check" reason:@"Red node has a red child" userInfo:nil]; + } + + if([self.right isRed]) { + @throw [[NSException alloc] initWithName:@"check" reason:@"Right child is red" userInfo:nil]; + } + + blackDepth = [self.left check]; +// NSLog(err); + if(blackDepth != [self.right check]) { + NSString* err = [NSString stringWithFormat:@"(%@ -> %@)blackDepth: %d ; self.right check: %d", self.value, [self.color boolValue] ? @"red" : @"black", blackDepth, [self.right check]]; +// return 10; + @throw [[NSException alloc] initWithName:@"check" reason:err userInfo:nil]; + } + else { + int ret = blackDepth + ([self isRed] ? 0 : 1); +// NSLog(@"black depth is: %d; other is: %d, ret is: %d", blackDepth, ([self isRed] ? 0 : 1), ret); + return ret; + } +} + + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FTreeSortedDictionary.h b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FTreeSortedDictionary.h new file mode 100644 index 00000000..934ca8b1 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FTreeSortedDictionary.h @@ -0,0 +1,30 @@ +/** + * @fileoverview Implementation of an immutable SortedMap using a Left-leaning + * Red-Black Tree, adapted from the implementation in Mugs + * (http://mads379.github.com/mugs/) by Mads Hartmann Jensen + * (mads379@gmail.com). + * + * Original paper on Left-leaning Red-Black Trees: + * http://www.cs.princeton.edu/~rs/talks/LLRB/LLRB.pdf + * + * Invariant 1: No red node has a red child + * Invariant 2: Every leaf path has the same number of black nodes + * Invariant 3: Only the left child can be red (left leaning) + */ + +#import +#import "FImmutableSortedDictionary.h" +#import "FLLRBNode.h" + +@interface FTreeSortedDictionary : FImmutableSortedDictionary + +@property (nonatomic, copy, readonly) NSComparator comparator; +@property (nonatomic, strong, readonly) id root; + +- (id)initWithComparator:(NSComparator)aComparator; + +// Override methods to return subtype +- (FTreeSortedDictionary *) insertKey:(id)aKey withValue:(id)aValue; +- (FTreeSortedDictionary *) removeKey:(id)aKey; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FTreeSortedDictionary.m b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FTreeSortedDictionary.m new file mode 100644 index 00000000..e9f0683a --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FTreeSortedDictionary.m @@ -0,0 +1,326 @@ +#import "FTreeSortedDictionary.h" +#import "FLLRBEmptyNode.h" +#import "FLLRBValueNode.h" +#import "FTreeSortedDictionaryEnumerator.h" + +typedef void (^fbt_void_nsnumber_int)(NSNumber* color, NSUInteger chunkSize); + +@interface FTreeSortedDictionary () + +@property (nonatomic, strong) id root; +@property (nonatomic, copy, readwrite) NSComparator comparator; + +@end + +@implementation FTreeSortedDictionary + +- (id)initWithComparator:(NSComparator)aComparator { + self = [super init]; + if (self) { + self.root = [FLLRBEmptyNode emptyNode]; + self.comparator = aComparator; + } + return self; +} + +- (id)initWithComparator:(NSComparator)aComparator withRoot:(__unsafe_unretained id)aRoot { + self = [super init]; + if (self) { + self.root = aRoot; + self.comparator = aComparator; + } + return self; +} + +/** + * Returns a copy of the map, with the specified key/value added or replaced. + */ +- (FTreeSortedDictionary *) insertKey:(__unsafe_unretained id)aKey withValue:(__unsafe_unretained id)aValue { + return [[FTreeSortedDictionary alloc] initWithComparator:self.comparator + withRoot:[[self.root insertKey:aKey forValue:aValue withComparator:self.comparator] + copyWith:nil + withValue:nil + withColor:BLACK + withLeft:nil + withRight:nil]]; +} + + +- (FTreeSortedDictionary *) removeKey:(__unsafe_unretained id)aKey { + // Remove is somewhat expensive even if the key doesn't exist (the tree does rebalancing and stuff). So avoid it. + if (![self contains:aKey]) { + return self; + } else { + return [[FTreeSortedDictionary alloc] + initWithComparator:self.comparator + withRoot:[[self.root remove:aKey withComparator:self.comparator] + copyWith:nil + withValue:nil + withColor:BLACK + withLeft:nil + withRight:nil]]; + } +} + +- (id) get:(__unsafe_unretained id) key { + if (key == nil) { + return nil; + } + NSComparisonResult cmp; + id node = self.root; + while(![node isEmpty]) { + cmp = self.comparator(key, node.key); + if(cmp == NSOrderedSame) { + return node.value; + } + else if (cmp == NSOrderedAscending) { + node = node.left; + } + else { + node = node.right; + } + } + return nil; +} + +- (id) getPredecessorKey:(__unsafe_unretained id) key { + NSComparisonResult cmp; + id node = self.root; + id rightParent = nil; + while(![node isEmpty]) { + cmp = self.comparator(key, node.key); + if(cmp == NSOrderedSame) { + if(![node.left isEmpty]) { + node = node.left; + while(! [node.right isEmpty]) { + node = node.right; + } + return node.key; + } + else if (rightParent != nil) { + return rightParent.key; + } + else { + return nil; + } + } + else if (cmp == NSOrderedAscending) { + node = node.left; + } + else if (cmp == NSOrderedDescending) { + rightParent = node; + node = node.right; + } + } + @throw [NSException exceptionWithName:@"NonexistentKey" reason:@"getPredecessorKey called with nonexistent key." userInfo:@{@"key": [key description] }]; +} + +- (BOOL) isEmpty { + return [self.root isEmpty]; +} + +- (int) count { + return [self.root count]; +} + +- (id) minKey { + return [self.root minKey]; +} + +- (id) maxKey { + return [self.root maxKey]; +} + +- (void) enumerateKeysAndObjectsUsingBlock:(void (^)(id, id, BOOL *))block +{ + [self enumerateKeysAndObjectsReverse:NO usingBlock:block]; +} + +- (void) enumerateKeysAndObjectsReverse:(BOOL)reverse usingBlock:(void (^)(id, id, BOOL *))block +{ + if (reverse) { + __block BOOL stop = NO; + [self.root reverseTraversal:^BOOL(id key, id value) { + block(key, value, &stop); + return stop; + }]; + } else { + __block BOOL stop = NO; + [self.root inorderTraversal:^BOOL(id key, id value) { + block(key, value, &stop); + return stop; + }]; + } +} + +- (BOOL) contains:(__unsafe_unretained id)key { + return ([self objectForKey:key] != nil); +} + +- (NSEnumerator *) keyEnumerator { + return [[FTreeSortedDictionaryEnumerator alloc] + initWithImmutableSortedDictionary:self startKey:nil isReverse:NO]; +} + +- (NSEnumerator *) keyEnumeratorFrom:(id)startKey { + return [[FTreeSortedDictionaryEnumerator alloc] + initWithImmutableSortedDictionary:self startKey:startKey isReverse:NO]; +} + +- (NSEnumerator *) reverseKeyEnumerator { + return [[FTreeSortedDictionaryEnumerator alloc] + initWithImmutableSortedDictionary:self startKey:nil isReverse:YES]; +} + +- (NSEnumerator *) reverseKeyEnumeratorFrom:(id)startKey { + return [[FTreeSortedDictionaryEnumerator alloc] + initWithImmutableSortedDictionary:self startKey:startKey isReverse:YES]; +} + + +#pragma mark - +#pragma mark Tree Builder + +// Code to efficiently build a RB Tree +typedef struct _base1_2list { + unsigned int bits; + unsigned short count; + unsigned short current; +} Base1_2List; + +Base1_2List *base1_2List_new(unsigned int length); +void base1_2List_free(Base1_2List* list); +unsigned int log_base2(unsigned int num); +BOOL base1_2List_next(Base1_2List* list); + +unsigned int log_base2(unsigned int num) { + return (unsigned int)(log(num) / log(2)); +} + +/** + * Works like an iterator, so it moves to the next bit. Do not call more than list->count times. + * @return whether or not the next bit is a 1 in base {1,2}. + */ +BOOL base1_2List_next(Base1_2List* list) { + BOOL result = !(list->bits & (0x1 << list->current)); + list->current--; + return result; +} + +static inline unsigned bit_mask(int x) { + return (x >= sizeof(unsigned) * CHAR_BIT) ? (unsigned) -1 : (1U << x) - 1; +} + +/** + * We represent the base{1,2} number as the combination of a binary number and a number of bits that we care about + * We iterate backwards, from most significant bit to least, to build up the llrb nodes. 0 base 2 => 1 base {1,2}, 1 base 2 => 2 base {1,2} + */ +Base1_2List *base1_2List_new(unsigned int length) { + size_t sz = sizeof(Base1_2List); + Base1_2List* list = calloc(1, sz); + // Calculate the number of bits that we care about + list->count = (unsigned short)log_base2(length + 1); + unsigned int mask = bit_mask(list->count); + list->bits = (length + 1) & mask; + list->current = list->count - 1; + return list; +} + + +void base1_2List_free(Base1_2List* list) { + free(list); +} + ++ (id) buildBalancedTree:(NSArray *)keys dictionary:(NSDictionary *)dictionary subArrayStartIndex:(NSUInteger)startIndex length:(NSUInteger)length { + length = MIN(keys.count - startIndex, length); // Bound length by the actual length of the array + if (length == 0) { + return nil; + } else if (length == 1) { + id key = keys[startIndex]; + return [[FLLRBValueNode alloc] initWithKey:key withValue:dictionary[key] withColor:BLACK withLeft:nil withRight:nil]; + } else { + NSUInteger middle = length / 2; + id left = [FTreeSortedDictionary buildBalancedTree:keys dictionary:dictionary subArrayStartIndex:startIndex length:middle]; + id right = [FTreeSortedDictionary buildBalancedTree:keys dictionary:dictionary subArrayStartIndex:(startIndex+middle+1) length:middle]; + id key = keys[startIndex + middle]; + return [[FLLRBValueNode alloc] initWithKey:key withValue:dictionary[key] withColor:BLACK withLeft:left withRight:right]; + } +} + ++ (id) rootFrom12List:(Base1_2List *)base1_2List keyList:(NSArray *)keyList dictionary:(NSDictionary *)dictionary { + __block id root = nil; + __block id node = nil; + __block NSUInteger index = keyList.count; + + fbt_void_nsnumber_int buildPennant = ^(NSNumber* color, NSUInteger chunkSize) { + NSUInteger startIndex = index - chunkSize + 1; + index -= chunkSize; + id key = keyList[index]; + id childTree = [self buildBalancedTree:keyList dictionary:dictionary subArrayStartIndex:startIndex length:(chunkSize - 1)]; + id pennant = [[FLLRBValueNode alloc] initWithKey:key withValue:dictionary[key] withColor:color withLeft:nil withRight:childTree]; + //attachPennant(pennant); + if (node) { + node.left = pennant; + node = pennant; + } else { + root = pennant; + node = pennant; + } + }; + + for (int i = 0; i < base1_2List->count; ++i) { + BOOL isOne = base1_2List_next(base1_2List); + NSUInteger chunkSize = (NSUInteger)pow(2.0, base1_2List->count - (i + 1)); + if (isOne) { + buildPennant(BLACK, chunkSize); + } else { + buildPennant(BLACK, chunkSize); + buildPennant(RED, chunkSize); + } + } + return root; +} + +/** + * Uses the algorithm linked here: + * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.46.1458 + */ + ++ (FImmutableSortedDictionary *)fromDictionary:(NSDictionary *)dictionary withComparator:(NSComparator)comparator +{ + // Steps: + // 0. Sort the array + // 1. Calculate the 1-2 number + // 2. Build From 1-2 number + // 0. for each digit in 1-2 number + // 0. calculate chunk size + // 1. build 1 or 2 pennants of that size + // 2. attach pennants and update node pointer + // 1. return root + NSMutableArray *sortedKeyList = [NSMutableArray arrayWithCapacity:dictionary.count]; + [dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + [sortedKeyList addObject:key]; + }]; + [sortedKeyList sortUsingComparator:comparator]; + + [sortedKeyList enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + if (idx > 0) { + if (comparator(sortedKeyList[idx - 1], obj) != NSOrderedAscending) { + [NSException raise:NSInvalidArgumentException format:@"Can't create FImmutableSortedDictionary with keys with same ordering!"]; + } + } + }]; + + Base1_2List* list = base1_2List_new((unsigned int)sortedKeyList.count); + id root = [self rootFrom12List:list keyList:sortedKeyList dictionary:dictionary]; + base1_2List_free(list); + + if (root != nil) { + return [[FTreeSortedDictionary alloc] initWithComparator:comparator withRoot:root]; + } else { + return [[FTreeSortedDictionary alloc] initWithComparator:comparator]; + } +} + +@end + diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FTreeSortedDictionaryEnumerator.h b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FTreeSortedDictionaryEnumerator.h new file mode 100644 index 00000000..d79fe8e6 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FTreeSortedDictionaryEnumerator.h @@ -0,0 +1,9 @@ +#import +#import "FTreeSortedDictionary.h" + +@interface FTreeSortedDictionaryEnumerator : NSEnumerator + +- (id)initWithImmutableSortedDictionary:(FTreeSortedDictionary *)aDict startKey:(id)startKey isReverse:(BOOL)reverse; +- (id)nextObject; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FTreeSortedDictionaryEnumerator.m b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FTreeSortedDictionaryEnumerator.m new file mode 100644 index 00000000..2aca86e0 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FTreeSortedDictionaryEnumerator.m @@ -0,0 +1,83 @@ +#import "FTreeSortedDictionaryEnumerator.h" + +@interface FTreeSortedDictionaryEnumerator() +@property (nonatomic, strong) FTreeSortedDictionary* immutableSortedDictionary; +@property (nonatomic, strong) NSMutableArray* stack; +@property (nonatomic) BOOL isReverse; + +@end + +@implementation FTreeSortedDictionaryEnumerator + +- (id)initWithImmutableSortedDictionary:(FTreeSortedDictionary *)aDict + startKey:(id)startKey isReverse:(BOOL)reverse { + self = [super init]; + if (self) { + self.immutableSortedDictionary = aDict; + self.stack = [[NSMutableArray alloc] init]; + self.isReverse = reverse; + + NSComparator comparator = aDict.comparator; + id node = self.immutableSortedDictionary.root; + + NSInteger cmp; + while(![node isEmpty]) { + cmp = startKey ? comparator(node.key, startKey) : 1; + // flip the comparison if we're going in reverse + if (self.isReverse) cmp *= -1; + + if (cmp < 0) { + // This node is less than our start key. Ignore it. + if (self.isReverse) { + node = node.left; + } else { + node = node.right; + } + } else if (cmp == 0) { + // This node is exactly equal to our start key. Push it on the stack, but stop iterating: + [self.stack addObject:node]; + break; + } else { + // This node is greater than our start key, add it to the stack and move on to the next one. + [self.stack addObject:node]; + if (self.isReverse) { + node = node.right; + } else { + node = node.left; + } + } + } + } + return self; +} + +- (id)nextObject { + if([self.stack count] == 0) { + return nil; + } + + id node = nil; + @synchronized(self.stack) { + node = [self.stack lastObject]; + [self.stack removeLastObject]; + } + id result = node.key; + + if (self.isReverse) { + node = node.left; + while (![node isEmpty]) { + [self.stack addObject:node]; + node = node.right; + } + } else { + node = node.right; + while (![node isEmpty]) { + [self.stack addObject:node]; + node = node.left; + } + } + + return result; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/SocketRocket/FSRWebSocket.h b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/SocketRocket/FSRWebSocket.h new file mode 100644 index 00000000..1ca1815c --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/SocketRocket/FSRWebSocket.h @@ -0,0 +1,107 @@ +// +// Copyright 2012 Square Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +typedef enum { + SR_CONNECTING = 0, + SR_OPEN = 1, + SR_CLOSING = 2, + SR_CLOSED = 3, + +} FSRReadyState; + +@class FSRWebSocket; + +extern NSString *const FSRWebSocketErrorDomain; + +@protocol FSRWebSocketDelegate; + +@interface FSRWebSocket : NSObject + +@property (nonatomic, weak) id delegate; + +@property (nonatomic, readonly) FSRReadyState readyState; +@property (nonatomic, readonly, retain) NSURL *url; + +// This returns the negotiated protocol. +// It will be niluntil after the handshake completes. +@property (nonatomic, readonly, copy) NSString *protocol; + +// Protocols should be an array of strings that turn into Sec-WebSocket-Protocol +- (id)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray *)protocols queue:(dispatch_queue_t)queue andUserAgent:(NSString *)userAgent; +- (id)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray *)protocols; +- (id)initWithURLRequest:(NSURLRequest *)request queue:(dispatch_queue_t)queue andUserAgent:(NSString *)userAgent; +- (id)initWithURLRequest:(NSURLRequest *)request; + +// Some helper constructors +- (id)initWithURL:(NSURL *)url protocols:(NSArray *)protocols; +- (id)initWithURL:(NSURL *)url; + +// Delegate queue will be dispatch_main_queue by default. +// You cannot set both OperationQueue and dispatch_queue. +- (void)setDelegateOperationQueue:(NSOperationQueue*) queue; +- (void)setDelegateDispatchQueue:(dispatch_queue_t)queue; + +// By default, it will schedule itself on +[NSRunLoop SR_networkRunLoop] using defaultModes. +- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode; +- (void)unscheduleFromRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode; + +// SRWebSockets are intended one-time-use only. Open should be called once and only once +- (void)open; + +- (void)close; +- (void)closeWithCode:(NSInteger)code reason:(NSString *)reason; + +// Send a UTF8 String or Data +- (void)send:(id)data; + +@end + +@protocol FSRWebSocketDelegate + +// message will either be an NSString if the server is using text +// or NSData if the server is using binary +- (void)webSocket:(FSRWebSocket *)webSocket didReceiveMessage:(id)message; + +@optional + +- (void)webSocketDidOpen:(FSRWebSocket *)webSocket; +- (void)webSocket:(FSRWebSocket *)webSocket didFailWithError:(NSError *)error; +- (void)webSocket:(FSRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean; + +@end + + +@interface NSURLRequest (FCertificateAdditions) + +@property (nonatomic, retain, readonly) NSArray *FSR_SSLPinnedCertificates; + +@end + + +@interface NSMutableURLRequest (FCertificateAdditions) + +@property (nonatomic, retain) NSArray *FSR_SSLPinnedCertificates; + +@end + +@interface NSRunLoop (FSRWebSocket) + ++ (NSRunLoop *)FSR_networkRunLoop; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/SocketRocket/FSRWebSocket.m b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/SocketRocket/FSRWebSocket.m new file mode 100644 index 00000000..4cd481b4 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/SocketRocket/FSRWebSocket.m @@ -0,0 +1,1852 @@ +// +// Copyright 2012 Square Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import "FSRWebSocket.h" + +#if TARGET_OS_IOS || TARGET_OS_TV +#define HAS_ICU +#endif + +#import + +#ifdef HAS_ICU +#import +#endif + +#if TARGET_OS_IOS || TARGET_OS_TV +#import +#elif TARGET_OS_OSX +#import +#endif + +#import +#import +#import "fbase64.h" +#import "NSData+SRB64Additions.h" + +#if OS_OBJECT_USE_OBJC_RETAIN_RELEASE +#define sr_dispatch_retain(x) +#define sr_dispatch_release(x) +#define maybe_bridge(x) ((__bridge void *) x) +#else +#define sr_dispatch_retain(x) dispatch_retain(x) +#define sr_dispatch_release(x) dispatch_release(x) +#define maybe_bridge(x) (x) +#endif + +typedef enum { + SROpCodeTextFrame = 0x1, + SROpCodeBinaryFrame = 0x2, + //3-7Reserved + SROpCodeConnectionClose = 0x8, + SROpCodePing = 0x9, + SROpCodePong = 0xA, + //B-F reserved +} FSROpCode; + +typedef enum { + SRStatusCodeNormal = 1000, + SRStatusCodeGoingAway = 1001, + SRStatusCodeProtocolError = 1002, + SRStatusCodeUnhandledType = 1003, + // 1004 reserved + SRStatusNoStatusReceived = 1005, + // 1004-1006 reserved + SRStatusCodeInvalidUTF8 = 1007, + SRStatusCodePolicyViolated = 1008, + SRStatusCodeMessageTooBig = 1009, +} FSRStatusCode; + +typedef struct { + BOOL fin; +// BOOL rsv1; +// BOOL rsv2; +// BOOL rsv3; + uint8_t opcode; + BOOL masked; + uint64_t payload_length; +} frame_header; + +static NSString *const SRWebSocketAppendToSecKeyString = @"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; + +static inline int32_t validate_dispatch_data_partial_string(NSData *data); +static inline void SRFastLog(NSString *format, ...); + +@interface NSData (FSRWebSocket) + +- (NSString *)stringBySHA1ThenBase64Encoding; + +@end + + +@interface NSString (FSRWebSocket) + +- (NSString *)stringBySHA1ThenBase64Encoding; + +@end + + +@interface NSURL (FSRWebSocket) + +// The origin isn't really applicable for a native application +// So instead, just map ws -> http and wss -> https +- (NSString *)SR_origin; + +@end + +@interface _FSRRunLoopThread : NSThread + +@property (nonatomic, readonly) NSRunLoop *runLoop; + +@end + +static NSString *newSHA1String(const char *bytes, size_t length) { + uint8_t md[CC_SHA1_DIGEST_LENGTH]; + + CC_SHA1(bytes, (int)length, md); + + size_t buffer_size = ((sizeof(md) * 3 + 2) / 2); + + char *buffer = (char *)malloc(buffer_size); + + int len = f_b64_ntop(md, CC_SHA1_DIGEST_LENGTH, buffer, buffer_size); + if (len == -1) { + free(buffer); + return nil; + } else{ + return [[NSString alloc] initWithBytesNoCopy:buffer length:len encoding:NSASCIIStringEncoding freeWhenDone:YES]; + } +} + +@implementation NSData (FSRWebSocket) + +- (NSString *)stringBySHA1ThenBase64Encoding; +{ + return newSHA1String(self.bytes, self.length); +} + +@end + + +@implementation NSString (FSRWebSocket) + +- (NSString *)stringBySHA1ThenBase64Encoding; +{ + return newSHA1String(self.UTF8String, self.length); +} + +@end + +NSString *const FSRWebSocketErrorDomain = @"FSRWebSocketErrorDomain"; + +// Returns number of bytes consumed. returning 0 means you didn't match. +// Sends bytes to callback handler; +typedef size_t (^stream_scanner)(NSData *collected_data); + +typedef void (^data_callback)(FSRWebSocket *webSocket, NSData *data); + +@interface FSRIOConsumer : NSObject { + stream_scanner _scanner; + data_callback _handler; + size_t _bytesNeeded; + BOOL _readToCurrentFrame; + BOOL _unmaskBytes; +} +@property (nonatomic, copy, readonly) stream_scanner consumer; +@property (nonatomic, copy, readonly) data_callback handler; +@property (nonatomic, assign) size_t bytesNeeded; +@property (nonatomic, assign, readonly) BOOL readToCurrentFrame; +@property (nonatomic, assign, readonly) BOOL unmaskBytes; + +@end + +// This class is not thread-safe, and is expected to always be run on the same queue. +@interface FSRIOConsumerPool : NSObject + +- (id)initWithBufferCapacity:(NSUInteger)poolSize; + +- (FSRIOConsumer *)consumerWithScanner:(stream_scanner)scanner handler:(data_callback)handler bytesNeeded:(size_t)bytesNeeded readToCurrentFrame:(BOOL)readToCurrentFrame unmaskBytes:(BOOL)unmaskBytes; +- (void)returnConsumer:(FSRIOConsumer *)consumer; + +@end + +@interface FSRWebSocket () + +- (void)_writeData:(NSData *)data; +- (void)_closeWithProtocolError:(NSString *)message; +- (void)_failWithError:(NSError *)error; + +- (void)_disconnect; + +- (void)_readFrameNew; +- (void)_readFrameContinue; + +- (void)_pumpScanner; + +- (void)_pumpWriting; + +- (void)_addConsumerWithScanner:(stream_scanner)consumer callback:(data_callback)callback; +- (void)_addConsumerWithDataLength:(size_t)dataLength callback:(data_callback)callback readToCurrentFrame:(BOOL)readToCurrentFrame unmaskBytes:(BOOL)unmaskBytes; +- (void)_addConsumerWithScanner:(stream_scanner)consumer callback:(data_callback)callback dataLength:(size_t)dataLength; +- (void)_readUntilBytes:(const void *)bytes length:(size_t)length callback:(data_callback)dataHandler; +- (void)_readUntilHeaderCompleteWithCallback:(data_callback)dataHandler; + +- (void)_sendFrameWithOpcode:(FSROpCode)opcode data:(id)data; + +- (BOOL)_checkHandshake:(CFHTTPMessageRef)httpMessage; +- (void)_SR_commonInit; + +- (void)_initializeStreams; +- (void)_connect; + +@property (nonatomic) FSRReadyState readyState; + +@property (nonatomic) NSOperationQueue *delegateOperationQueue; +@property (nonatomic) dispatch_queue_t delegateDispatchQueue; + +@end + + +@implementation FSRWebSocket { + NSInteger _webSocketVersion; + + NSOperationQueue *_delegateOperationQueue; + dispatch_queue_t _delegateDispatchQueue; + dispatch_queue_t _workQueue; + NSMutableArray *_consumers; + + NSInputStream *_inputStream; + NSOutputStream *_outputStream; + + NSMutableData *_readBuffer; + NSInteger _readBufferOffset; + + NSMutableData *_outputBuffer; + NSInteger _outputBufferOffset; + + uint8_t _currentFrameOpcode; + size_t _currentFrameCount; + size_t _readOpCount; + uint32_t _currentStringScanPosition; + NSMutableData *_currentFrameData; + + NSString *_closeReason; + + NSString *_secKey; + + BOOL _pinnedCertFound; + + uint8_t _currentReadMaskKey[4]; + size_t _currentReadMaskOffset; + + BOOL _consumerStopped; + + BOOL _closeWhenFinishedWriting; + BOOL _failed; + + BOOL _secure; + NSURLRequest *_urlRequest; + NSString *_userAgent; + + CFHTTPMessageRef _receivedHTTPHeaders; + + BOOL _sentClose; + BOOL _didFail; + BOOL _cleanupScheduled; + int _closeCode; + + BOOL _isPumping; + + NSMutableSet *_scheduledRunloops; + + // We use this to retain ourselves. + __strong FSRWebSocket *_selfRetain; + + NSArray *_requestedProtocols; + FSRIOConsumerPool *_consumerPool; +} + +@synthesize delegate = _delegate; +@synthesize url = _url; +@synthesize readyState = _readyState; +@synthesize protocol = _protocol; + +static __strong NSData *CRLFCRLF; + ++ (void)initialize; +{ + CRLFCRLF = [[NSData alloc] initWithBytes:"\r\n\r\n" length:4]; +} + +- (id)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray *)protocols queue:(dispatch_queue_t)queue andUserAgent:(NSString *)userAgent; +{ + self = [super init]; + if (self) { + assert(request.URL); + _url = request.URL; + NSString *scheme = [_url scheme]; + + _requestedProtocols = [protocols copy]; + _userAgent = userAgent; + + assert([scheme isEqualToString:@"ws"] || [scheme isEqualToString:@"http"] || [scheme isEqualToString:@"wss"] || [scheme isEqualToString:@"https"]); + _urlRequest = request; + + if ([scheme isEqualToString:@"wss"] || [scheme isEqualToString:@"https"]) { + _secure = YES; + } + + if (!queue) { + _delegateDispatchQueue = dispatch_get_main_queue(); + } else { + _delegateDispatchQueue = queue; + } + + [self _SR_commonInit]; + } + + return self; +} + +- (id)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray *)protocols; +{ + return [self initWithURLRequest:request protocols:nil queue:nil andUserAgent:nil]; +} + +- (id)initWithURLRequest:(NSURLRequest *)request queue:(dispatch_queue_t)queue andUserAgent:(NSString *)userAgent; +{ + return [self initWithURLRequest:request protocols:nil queue:queue andUserAgent:userAgent]; +} + +- (id)initWithURLRequest:(NSURLRequest *)request; +{ + return [self initWithURLRequest:request protocols:nil]; +} + +- (id)initWithURL:(NSURL *)url; +{ + return [self initWithURL:url protocols:nil]; +} + +- (id)initWithURL:(NSURL *)url protocols:(NSArray *)protocols; +{ + NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url]; + return [self initWithURLRequest:request protocols:protocols]; +} + +- (void)_SR_commonInit; +{ + _readyState = SR_CONNECTING; + + _consumerStopped = YES; + + _webSocketVersion = 13; + + _workQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + + // Going to set a specific on the queue so we can validate we're on the work queue + dispatch_queue_set_specific(_workQueue, (__bridge void *)self, maybe_bridge(_workQueue), NULL); + + sr_dispatch_retain(_delegateDispatchQueue); + + _readBuffer = [[NSMutableData alloc] init]; + _outputBuffer = [[NSMutableData alloc] init]; + + _currentFrameData = [[NSMutableData alloc] init]; + + _consumers = [[NSMutableArray alloc] init]; + + _consumerPool = [[FSRIOConsumerPool alloc] init]; + + _scheduledRunloops = [[NSMutableSet alloc] init]; + + [self _initializeStreams]; + + // default handlers +} + +- (void)assertOnWorkQueue; +{ + assert(dispatch_get_specific((__bridge void *)self) == maybe_bridge(_workQueue)); +} + +- (void)dealloc +{ + _inputStream.delegate = nil; + _outputStream.delegate = nil; + + [_inputStream close]; + [_outputStream close]; + + sr_dispatch_release(_workQueue); + _workQueue = NULL; + + if (_receivedHTTPHeaders) { + CFRelease(_receivedHTTPHeaders); + _receivedHTTPHeaders = NULL; + } + + if (_delegateDispatchQueue) { + sr_dispatch_release(_delegateDispatchQueue); + _delegateDispatchQueue = NULL; + } +} + +#ifndef NDEBUG + +- (void)setReadyState:(FSRReadyState)aReadyState; +{ + [self willChangeValueForKey:@"readyState"]; + assert(aReadyState > _readyState); + _readyState = aReadyState; + [self didChangeValueForKey:@"readyState"]; +} + +#endif + +- (void)open; +{ + assert(_url); + NSAssert(_readyState == SR_CONNECTING, @"Cannot call -(void)open on SRWebSocket more than once"); + + _selfRetain = self; + + [self _connect]; +} + +// Calls block on delegate queue +- (void)_performDelegateBlock:(dispatch_block_t)block; +{ + if (_delegateOperationQueue) { + [_delegateOperationQueue addOperationWithBlock:block]; + } else { + assert(_delegateDispatchQueue); + dispatch_async(_delegateDispatchQueue, block); + } +} + +- (void)setDelegateDispatchQueue:(dispatch_queue_t)queue; +{ + if (queue) { + sr_dispatch_retain(queue); + } + + if (_delegateDispatchQueue) { + sr_dispatch_release(_delegateDispatchQueue); + } + + _delegateDispatchQueue = queue; +} + +- (BOOL)_checkHandshake:(CFHTTPMessageRef)httpMessage; +{ + NSString *acceptHeader = CFBridgingRelease(CFHTTPMessageCopyHeaderFieldValue(httpMessage, CFSTR("Sec-WebSocket-Accept"))); + + if (acceptHeader == nil) { + return NO; + } + + NSString *concattedString = [_secKey stringByAppendingString:SRWebSocketAppendToSecKeyString]; + NSString *expectedAccept = [concattedString stringBySHA1ThenBase64Encoding]; + + return [acceptHeader isEqualToString:expectedAccept]; +} + +- (void)_HTTPHeadersDidFinish; +{ + NSInteger responseCode = CFHTTPMessageGetResponseStatusCode(_receivedHTTPHeaders); + + if (responseCode >= 400) { + SRFastLog(@"Request failed with response code %d", responseCode); + [self _failWithError:[NSError errorWithDomain:@"org.lolrus.SocketRocket" code:2132 userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"received bad response code from server %u", (int)responseCode] forKey:NSLocalizedDescriptionKey]]]; + return; + + } + + if(![self _checkHandshake:_receivedHTTPHeaders]) { + [self _failWithError:[NSError errorWithDomain:FSRWebSocketErrorDomain code:2133 userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Invalid Sec-WebSocket-Accept response"] forKey:NSLocalizedDescriptionKey]]]; + return; + } + + NSString *negotiatedProtocol = CFBridgingRelease(CFHTTPMessageCopyHeaderFieldValue(_receivedHTTPHeaders, CFSTR("Sec-WebSocket-Protocol"))); + if (negotiatedProtocol) { + // Make sure we requested the protocol + if ([_requestedProtocols indexOfObject:negotiatedProtocol] == NSNotFound) { + [self _failWithError:[NSError errorWithDomain:FSRWebSocketErrorDomain code:2133 userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Server specified Sec-WebSocket-Protocol that wasn't requested"] forKey:NSLocalizedDescriptionKey]]]; + return; + } + + _protocol = negotiatedProtocol; + } + + self.readyState = SR_OPEN; + + if (!_didFail) { + [self _readFrameNew]; + } + + [self _performDelegateBlock:^{ + if ([self.delegate respondsToSelector:@selector(webSocketDidOpen:)]) { + [self.delegate webSocketDidOpen:self]; + }; + }]; +} + + +- (void)_readHTTPHeader; +{ + if (_receivedHTTPHeaders == NULL) { + _receivedHTTPHeaders = CFHTTPMessageCreateEmpty(NULL, NO); + } + + [self _readUntilHeaderCompleteWithCallback:^(FSRWebSocket *self, NSData *data) { + CFHTTPMessageAppendBytes(self->_receivedHTTPHeaders, (const UInt8 *)data.bytes, data.length); + + if (CFHTTPMessageIsHeaderComplete(self->_receivedHTTPHeaders)) { + SRFastLog(@"Finished reading headers %@", CFBridgingRelease(CFHTTPMessageCopyAllHeaderFields(self->_receivedHTTPHeaders))); + [self _HTTPHeadersDidFinish]; + } else { + [self _readHTTPHeader]; + } + }]; +} + +- (void)didConnect +{ + SRFastLog(@"Connected"); + CFHTTPMessageRef request = CFHTTPMessageCreateRequest(NULL, CFSTR("GET"), (__bridge CFURLRef)_url, kCFHTTPVersion1_1); + + // Set host first so it defaults + CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Host"), (__bridge CFStringRef) + (_url.port != nil ? [NSString stringWithFormat:@"%@:%@", + _url.host, _url.port] : _url.host)); + + NSMutableData *keyBytes = [[NSMutableData alloc] initWithLength:16]; + int result = SecRandomCopyBytes(kSecRandomDefault, keyBytes.length, keyBytes.mutableBytes); + assert(result == 0); + _secKey = [FSRUtilities base64EncodedStringFromData:keyBytes]; + assert([_secKey length] == 24); + + CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Upgrade"), CFSTR("websocket")); + CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Connection"), CFSTR("Upgrade")); + if (_userAgent) { + CFHTTPMessageSetHeaderFieldValue(request, CFSTR("User-Agent"), (__bridge CFStringRef)_userAgent); + } + + CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Sec-WebSocket-Key"), (__bridge CFStringRef)_secKey); + CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Sec-WebSocket-Version"), (__bridge CFStringRef)[NSString stringWithFormat:@"%u", (int)_webSocketVersion]); + + CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Origin"), (__bridge CFStringRef)_url.SR_origin); + + if (_requestedProtocols) { + CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Sec-WebSocket-Protocol"), (__bridge CFStringRef)[_requestedProtocols componentsJoinedByString:@", "]); + } + + [_urlRequest.allHTTPHeaderFields enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + CFHTTPMessageSetHeaderFieldValue(request, (__bridge CFStringRef)key, (__bridge CFStringRef)obj); + }]; + + NSData *message = CFBridgingRelease(CFHTTPMessageCopySerializedMessage(request)); + + CFRelease(request); + + [self _writeData:message]; + [self _readHTTPHeader]; +} + +//- (void)_connectToHost:(NSString *)host port:(NSInteger)port; +- (void)_initializeStreams; +{ + NSInteger port = _url.port.integerValue; + if (port == 0) { + if (!_secure) { + port = 80; + } else { + port = 443; + } + } + NSString *host = _url.host; + + CFReadStreamRef readStream = NULL; + CFWriteStreamRef writeStream = NULL; + + CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)host, (int)port, &readStream, &writeStream); + + // XXX + CFReadStreamSetProperty(readStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeBackground); + CFWriteStreamSetProperty(writeStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeBackground); + + _outputStream = CFBridgingRelease(writeStream); + _inputStream = CFBridgingRelease(readStream); + + + if (_secure) { + NSMutableDictionary *SSLOptions = [[NSMutableDictionary alloc] init]; + + [_outputStream setProperty:(__bridge id)kCFStreamSocketSecurityLevelNegotiatedSSL forKey:(__bridge id)kCFStreamPropertySocketSecurityLevel]; + + // If we're using pinned certs, don't validate the certificate chain + if ([_urlRequest FSR_SSLPinnedCertificates].count) { + [SSLOptions setValue:[NSNumber numberWithBool:NO] forKey:(__bridge id)kCFStreamSSLValidatesCertificateChain]; + } + + [_outputStream setProperty:SSLOptions + forKey:(__bridge id)kCFStreamPropertySSLSettings]; + } + + _inputStream.delegate = self; + _outputStream.delegate = self; + + [_outputStream open]; + [_inputStream open]; +} + +- (void)_connect; +{ + if (!_scheduledRunloops.count) { + [self scheduleInRunLoop:[NSRunLoop FSR_networkRunLoop] forMode:NSDefaultRunLoopMode]; + } + + + [_outputStream open]; + [_inputStream open]; +} + +- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode; +{ + [_outputStream scheduleInRunLoop:aRunLoop forMode:mode]; + [_inputStream scheduleInRunLoop:aRunLoop forMode:mode]; + + [_scheduledRunloops addObject:@[aRunLoop, mode]]; +} + +- (void)unscheduleFromRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode; +{ + [_outputStream removeFromRunLoop:aRunLoop forMode:mode]; + [_inputStream removeFromRunLoop:aRunLoop forMode:mode]; + + [_scheduledRunloops removeObject:@[aRunLoop, mode]]; +} + +- (void)close; +{ + [self closeWithCode:-1 reason:nil]; +} + +- (void)closeWithCode:(NSInteger)code reason:(NSString *)reason; +{ + assert(code); + dispatch_async(_workQueue, ^{ + if (self.readyState == SR_CLOSING || self.readyState == SR_CLOSED) { + return; + } + + BOOL wasConnecting = self.readyState == SR_CONNECTING; + + self.readyState = SR_CLOSING; + + SRFastLog(@"Closing with code %d reason %@", code, reason); + + if (wasConnecting) { + [self _disconnect]; + return; + } + + size_t maxMsgSize = [reason maximumLengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + NSMutableData *mutablePayload = [[NSMutableData alloc] initWithLength:sizeof(uint16_t) + maxMsgSize]; + NSData *payload = mutablePayload; + + ((uint16_t *)mutablePayload.mutableBytes)[0] = EndianU16_BtoN(code); + + if (reason) { + NSRange remainingRange = {0}; + + NSUInteger usedLength = 0; + + BOOL success = [reason getBytes:(char *)mutablePayload.mutableBytes + sizeof(uint16_t) maxLength:payload.length - sizeof(uint16_t) usedLength:&usedLength encoding:NSUTF8StringEncoding options:NSStringEncodingConversionExternalRepresentation range:NSMakeRange(0, reason.length) remainingRange:&remainingRange]; + + assert(success); + assert(remainingRange.length == 0); + + if (usedLength != maxMsgSize) { + payload = [payload subdataWithRange:NSMakeRange(0, usedLength + sizeof(uint16_t))]; + } + } + + + [self _sendFrameWithOpcode:SROpCodeConnectionClose data:payload]; + }); +} + +- (void)_closeWithProtocolError:(NSString *)message; +{ + // Need to shunt this on the _callbackQueue first to see if they received any messages + [self _performDelegateBlock:^{ + [self closeWithCode:SRStatusCodeProtocolError reason:message]; + dispatch_async(self->_workQueue, ^{ + [self _disconnect]; + }); + }]; +} + +- (void)_failWithError:(NSError *)error; +{ + dispatch_async(_workQueue, ^{ + if (self.readyState != SR_CLOSED) { + self->_failed = YES; + [self _performDelegateBlock:^{ + if ([self.delegate respondsToSelector:@selector(webSocket:didFailWithError:)]) { + [self.delegate webSocket:self didFailWithError:error]; + } + }]; + + self.readyState = SR_CLOSED; + + SRFastLog(@"Failing with error %@", error.localizedDescription); + + [self _disconnect]; + [self _scheduleCleanup]; + } + }); +} + +- (void)_writeData:(NSData *)data; +{ + [self assertOnWorkQueue]; + + if (_closeWhenFinishedWriting) { + return; + } + [_outputBuffer appendData:data]; + [self _pumpWriting]; +} +- (void)send:(id)data; +{ + SRFastLog(@"Sending data %@", data); + NSAssert(self.readyState != SR_CONNECTING, @"Invalid State: Cannot call send: until connection is open"); + // TODO: maybe not copy this for performance + data = [data copy]; + dispatch_async(_workQueue, ^{ + if ([data isKindOfClass:[NSString class]]) { + [self _sendFrameWithOpcode:SROpCodeTextFrame data:[(NSString *)data dataUsingEncoding:NSUTF8StringEncoding]]; + } else if ([data isKindOfClass:[NSData class]]) { + [self _sendFrameWithOpcode:SROpCodeBinaryFrame data:data]; + } else if (data == nil) { + [self _sendFrameWithOpcode:SROpCodeTextFrame data:data]; + } else { + assert(NO); + } + }); +} + +- (void)handlePing:(NSData *)pingData; +{ + // Need to pingpong this off _callbackQueue first to make sure messages happen in order + [self _performDelegateBlock:^{ + dispatch_async(self->_workQueue, ^{ + [self _sendFrameWithOpcode:SROpCodePong data:pingData]; + }); + }]; +} + +- (void)handlePong; +{ + // NOOP +} + +- (void)_handleMessage:(id)message +{ + SRFastLog(@"Received message"); + [self _performDelegateBlock:^{ + if ([self.delegate respondsToSelector:@selector(webSocket:didReceiveMessage:)]) { + [self.delegate webSocket:self didReceiveMessage:message]; + } + }]; +} + + +static inline BOOL closeCodeIsValid(int closeCode) { + if (closeCode < 1000) { + return NO; + } + + if (closeCode >= 1000 && closeCode <= 1011) { + if (closeCode == 1004 || + closeCode == 1005 || + closeCode == 1006) { + return NO; + } + return YES; + } + + if (closeCode >= 3000 && closeCode <= 3999) { + return YES; + } + + if (closeCode >= 4000 && closeCode <= 4999) { + return YES; + } + + return NO; +} + +// Note from RFC: +// +// If there is a body, the first two +// bytes of the body MUST be a 2-byte unsigned integer (in network byte +// order) representing a status code with value /code/ defined in +// Section 7.4. Following the 2-byte integer the body MAY contain UTF-8 +// encoded data with value /reason/, the interpretation of which is not +// defined by this specification. + +- (void)handleCloseWithData:(NSData *)data; +{ + size_t dataSize = data.length; + __block uint16_t closeCode = 0; + + SRFastLog(@"Received close frame"); + + if (dataSize == 1) { + // TODO handle error + [self _closeWithProtocolError:@"Payload for close must be larger than 2 bytes"]; + return; + } else if (dataSize >= 2) { + [data getBytes:&closeCode length:sizeof(closeCode)]; + _closeCode = EndianU16_BtoN(closeCode); + if (!closeCodeIsValid(_closeCode)) { + [self _closeWithProtocolError:[NSString stringWithFormat:@"Cannot have close code of %d", _closeCode]]; + return; + } + if (dataSize > 2) { + _closeReason = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(2, dataSize - 2)] encoding:NSUTF8StringEncoding]; + if (!_closeReason) { + [self _closeWithProtocolError:@"Close reason MUST be valid UTF-8"]; + return; + } + } + } else { + _closeCode = SRStatusNoStatusReceived; + } + + [self assertOnWorkQueue]; + + if (self.readyState == SR_OPEN) { + [self closeWithCode:1000 reason:nil]; + } + dispatch_async(_workQueue, ^{ + [self _disconnect]; + }); +} + +- (void)_disconnect; +{ + [self assertOnWorkQueue]; + SRFastLog(@"Trying to disconnect"); + _closeWhenFinishedWriting = YES; + [self _pumpWriting]; +} + +- (void)_handleFrameWithData:(NSData *)frameData opCode:(NSInteger)opcode; +{ + // Check that the current data is valid UTF8 + + BOOL isControlFrame = (opcode == SROpCodePing || opcode == SROpCodePong || opcode == SROpCodeConnectionClose); + if (!isControlFrame) { + [self _readFrameNew]; + } else { + dispatch_async(_workQueue, ^{ + [self _readFrameContinue]; + }); + } + + switch (opcode) { + case SROpCodeTextFrame: { + NSString *str = [[NSString alloc] initWithData:frameData encoding:NSUTF8StringEncoding]; + if (str == nil && frameData) { + [self closeWithCode:SRStatusCodeInvalidUTF8 reason:@"Text frames must be valid UTF-8"]; + dispatch_async(_workQueue, ^{ + [self _disconnect]; + }); + + return; + } + [self _handleMessage:str]; + break; + } + case SROpCodeBinaryFrame: + [self _handleMessage:[frameData copy]]; + break; + case SROpCodeConnectionClose: + [self handleCloseWithData:frameData]; + break; + case SROpCodePing: + [self handlePing:frameData]; + break; + case SROpCodePong: + [self handlePong]; + break; + default: + [self _closeWithProtocolError:[NSString stringWithFormat:@"Unknown opcode %u", (int)opcode]]; + // TODO: Handle invalid opcode + break; + } +} + +- (void)_handleFrameHeader:(frame_header)frame_header curData:(NSData *)curData; +{ + assert(frame_header.opcode != 0); + + if (self.readyState != SR_OPEN) { + return; + } + + + BOOL isControlFrame = (frame_header.opcode == SROpCodePing || frame_header.opcode == SROpCodePong || frame_header.opcode == SROpCodeConnectionClose); + + if (isControlFrame && !frame_header.fin) { + [self _closeWithProtocolError:@"Fragmented control frames not allowed"]; + return; + } + + if (isControlFrame && frame_header.payload_length >= 126) { + [self _closeWithProtocolError:@"Control frames cannot have payloads larger than 126 bytes"]; + return; + } + + if (!isControlFrame) { + _currentFrameOpcode = frame_header.opcode; + _currentFrameCount += 1; + } + + if (frame_header.payload_length == 0) { + if (isControlFrame) { + [self _handleFrameWithData:curData opCode:frame_header.opcode]; + } else { + if (frame_header.fin) { + [self _handleFrameWithData:_currentFrameData opCode:frame_header.opcode]; + } else { + // TODO add assert that opcode is not a control; + [self _readFrameContinue]; + } + } + } else { + [self _addConsumerWithDataLength:(size_t)frame_header.payload_length callback:^(FSRWebSocket *self, NSData *newData) { + if (isControlFrame) { + [self _handleFrameWithData:newData opCode:frame_header.opcode]; + } else { + if (frame_header.fin) { + [self _handleFrameWithData:self->_currentFrameData opCode:frame_header.opcode]; + } else { + // TODO add assert that opcode is not a control; + [self _readFrameContinue]; + } + + } + } readToCurrentFrame:!isControlFrame unmaskBytes:frame_header.masked]; + } +} + +/* From RFC: + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-------+-+-------------+-------------------------------+ + |F|R|R|R| opcode|M| Payload len | Extended payload length | + |I|S|S|S| (4) |A| (7) | (16/64) | + |N|V|V|V| |S| | (if payload len==126/127) | + | |1|2|3| |K| | | + +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + + | Extended payload length continued, if payload len == 127 | + + - - - - - - - - - - - - - - - +-------------------------------+ + | |Masking-key, if MASK set to 1 | + +-------------------------------+-------------------------------+ + | Masking-key (continued) | Payload Data | + +-------------------------------- - - - - - - - - - - - - - - - + + : Payload Data continued ... : + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + | Payload Data continued ... | + +---------------------------------------------------------------+ + */ + +static const uint8_t SRFinMask = 0x80; +static const uint8_t SROpCodeMask = 0x0F; +static const uint8_t SRRsvMask = 0x70; +static const uint8_t SRMaskMask = 0x80; +static const uint8_t SRPayloadLenMask = 0x7F; + + +- (void)_readFrameContinue; +{ + assert((_currentFrameCount == 0 && _currentFrameOpcode == 0) || (_currentFrameCount > 0 && _currentFrameOpcode > 0)); + + [self _addConsumerWithDataLength:2 callback:^(FSRWebSocket *self, NSData *data) { + __block frame_header header = {0}; + + const uint8_t *headerBuffer = data.bytes; + assert(data.length >= 2); + + if (headerBuffer[0] & SRRsvMask) { + [self _closeWithProtocolError:@"Server used RSV bits"]; + return; + } + + uint8_t receivedOpcode = (SROpCodeMask & headerBuffer[0]); + + BOOL isControlFrame = (receivedOpcode == SROpCodePing || receivedOpcode == SROpCodePong || receivedOpcode == SROpCodeConnectionClose); + + if (!isControlFrame && receivedOpcode != 0 && self->_currentFrameCount > 0) { + [self _closeWithProtocolError:@"all data frames after the initial data frame must have opcode 0"]; + return; + } + + if (receivedOpcode == 0 && self->_currentFrameCount == 0) { + [self _closeWithProtocolError:@"cannot continue a message"]; + return; + } + + header.opcode = receivedOpcode == 0 ? self->_currentFrameOpcode : receivedOpcode; + + header.fin = !!(SRFinMask & headerBuffer[0]); + + + header.masked = !!(SRMaskMask & headerBuffer[1]); + header.payload_length = SRPayloadLenMask & headerBuffer[1]; + + headerBuffer = NULL; + + if (header.masked) { + [self _closeWithProtocolError:@"Client must receive unmasked data"]; + } + + size_t extra_bytes_needed = header.masked ? sizeof(self->_currentReadMaskKey) : 0; + + if (header.payload_length == 126) { + extra_bytes_needed += sizeof(uint16_t); + } else if (header.payload_length == 127) { + extra_bytes_needed += sizeof(uint64_t); + } + + if (extra_bytes_needed == 0) { + [self _handleFrameHeader:header curData:self->_currentFrameData]; + } else { + [self _addConsumerWithDataLength:extra_bytes_needed callback:^(FSRWebSocket *self, NSData *data) { + size_t mapped_size = data.length; + const void *mapped_buffer = data.bytes; + size_t offset = 0; + + if (header.payload_length == 126) { + assert(mapped_size >= sizeof(uint16_t)); + uint16_t newLen = EndianU16_BtoN(*(uint16_t *)(mapped_buffer)); + header.payload_length = newLen; + offset += sizeof(uint16_t); + } else if (header.payload_length == 127) { + assert(mapped_size >= sizeof(uint64_t)); + header.payload_length = EndianU64_BtoN(*(uint64_t *)(mapped_buffer)); + offset += sizeof(uint64_t); + } else { + assert(header.payload_length < 126 && header.payload_length >= 0); + } + + + if (header.masked) { + assert(mapped_size >= sizeof(self->_currentReadMaskOffset) + offset); + memcpy(self->_currentReadMaskKey, ((uint8_t *)mapped_buffer) + offset, sizeof(self->_currentReadMaskKey)); + } + + [self _handleFrameHeader:header curData:self->_currentFrameData]; + } readToCurrentFrame:NO unmaskBytes:NO]; + } + } readToCurrentFrame:NO unmaskBytes:NO]; +} + +- (void)_readFrameNew; +{ + dispatch_async(_workQueue, ^{ + [self->_currentFrameData setLength:0]; + + self->_currentFrameOpcode = 0; + self->_currentFrameCount = 0; + self->_readOpCount = 0; + self->_currentStringScanPosition = 0; + + [self _readFrameContinue]; + }); +} + +- (void)_pumpWriting; +{ + [self assertOnWorkQueue]; + + NSUInteger dataLength = _outputBuffer.length; + if (dataLength - _outputBufferOffset > 0 && _outputStream.hasSpaceAvailable) { + NSUInteger bytesWritten = [_outputStream write:_outputBuffer.bytes + _outputBufferOffset maxLength:dataLength - _outputBufferOffset]; + if (bytesWritten == -1) { + [self _failWithError:[NSError errorWithDomain:@"org.lolrus.SocketRocket" code:2145 userInfo:[NSDictionary dictionaryWithObject:@"Error writing to stream" forKey:NSLocalizedDescriptionKey]]]; + return; + } + + _outputBufferOffset += bytesWritten; + + if (_outputBufferOffset > 4096 && _outputBufferOffset > (_outputBuffer.length >> 1)) { + _outputBuffer = [[NSMutableData alloc] initWithBytes:(char *)_outputBuffer.bytes + _outputBufferOffset length:_outputBuffer.length - _outputBufferOffset]; + _outputBufferOffset = 0; + } + } + + if (_closeWhenFinishedWriting && + _outputBuffer.length - _outputBufferOffset == 0 && + (_inputStream.streamStatus != NSStreamStatusNotOpen && + _inputStream.streamStatus != NSStreamStatusClosed) && + !_sentClose) { + _sentClose = YES; + + @synchronized (self) { + [_outputStream close]; + [_inputStream close]; + + // TODO: Why are we missing the SocketRocket code to call unscheduleFromRunLoop??? + } + + if (!_failed) { + [self _performDelegateBlock:^{ + if ([self.delegate respondsToSelector:@selector(webSocket:didCloseWithCode:reason:wasClean:)]) { + [self.delegate webSocket:self didCloseWithCode:self->_closeCode reason:self->_closeReason wasClean:YES]; + } + }]; + } + [self _scheduleCleanup]; + } +} + +- (void)_addConsumerWithScanner:(stream_scanner)consumer callback:(data_callback)callback; +{ + [self assertOnWorkQueue]; + [self _addConsumerWithScanner:consumer callback:callback dataLength:0]; +} + +- (void)_addConsumerWithDataLength:(size_t)dataLength callback:(data_callback)callback readToCurrentFrame:(BOOL)readToCurrentFrame unmaskBytes:(BOOL)unmaskBytes; +{ + [self assertOnWorkQueue]; + assert(dataLength); + + [_consumers addObject:[_consumerPool consumerWithScanner:nil handler:callback bytesNeeded:dataLength readToCurrentFrame:readToCurrentFrame unmaskBytes:unmaskBytes]]; + [self _pumpScanner]; +} + +- (void)_addConsumerWithScanner:(stream_scanner)consumer callback:(data_callback)callback dataLength:(size_t)dataLength; +{ + [self assertOnWorkQueue]; + [_consumers addObject:[_consumerPool consumerWithScanner:consumer handler:callback bytesNeeded:dataLength readToCurrentFrame:NO unmaskBytes:NO]]; + [self _pumpScanner]; +} + + +- (void)_scheduleCleanup +{ + @synchronized(self) { + if (_cleanupScheduled) { + return; + } + + _cleanupScheduled = YES; + + // Cleanup NSStream delegate's in the same RunLoop used by the streams themselves: + // This way we'll prevent race conditions between handleEvent and SRWebsocket's dealloc + NSTimer *timer = [NSTimer timerWithTimeInterval:(0.0f) target:self selector:@selector(_cleanupSelfReference:) userInfo:nil repeats:NO]; + [[NSRunLoop FSR_networkRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; + } +} + +- (void)_cleanupSelfReference:(NSTimer *)timer +{ + @synchronized(self) { + // Nuke NSStream delegate's + _inputStream.delegate = nil; + _outputStream.delegate = nil; + + // Remove the streams, right now, from the networkRunLoop + [_inputStream close]; + [_outputStream close]; + } + + // Cleanup selfRetain in the same GCD queue as usual + dispatch_async(_workQueue, ^{ + self->_selfRetain = nil; + }); +} + + +static const char CRLFCRLFBytes[] = {'\r', '\n', '\r', '\n'}; + +- (void)_readUntilHeaderCompleteWithCallback:(data_callback)dataHandler; +{ + [self _readUntilBytes:CRLFCRLFBytes length:sizeof(CRLFCRLFBytes) callback:dataHandler]; +} + +- (void)_readUntilBytes:(const void *)bytes length:(size_t)length callback:(data_callback)dataHandler; +{ + // TODO optimize so this can continue from where we last searched + stream_scanner consumer = ^size_t(NSData *data) { + __block size_t found_size = 0; + __block size_t match_count = 0; + + size_t size = data.length; + const unsigned char *buffer = data.bytes; + for (int i = 0; i < size; i++ ) { + if (((const unsigned char *)buffer)[i] == ((const unsigned char *)bytes)[match_count]) { + match_count += 1; + if (match_count == length) { + found_size = i + 1; + break; + } + } else { + match_count = 0; + } + } + return found_size; + }; + [self _addConsumerWithScanner:consumer callback:dataHandler]; +} + + +// Returns true if did work +- (BOOL)_innerPumpScanner { + + BOOL didWork = NO; + + if (self.readyState >= SR_CLOSING) { + return didWork; + } + + if (!_consumers.count) { + return didWork; + } + + size_t curSize = _readBuffer.length - _readBufferOffset; + if (!curSize) { + return didWork; + } + + FSRIOConsumer *consumer = [_consumers objectAtIndex:0]; + + size_t bytesNeeded = consumer.bytesNeeded; + + size_t foundSize = 0; + if (consumer.consumer) { + NSData *tempView = [NSData dataWithBytesNoCopy:(char *)_readBuffer.bytes + _readBufferOffset length:_readBuffer.length - _readBufferOffset freeWhenDone:NO]; + foundSize = consumer.consumer(tempView); + } else { + assert(consumer.bytesNeeded); + if (curSize >= bytesNeeded) { + foundSize = bytesNeeded; + } else if (consumer.readToCurrentFrame) { + foundSize = curSize; + } + } + + NSData *slice = nil; + if (consumer.readToCurrentFrame || foundSize) { + NSRange sliceRange = NSMakeRange(_readBufferOffset, foundSize); + slice = [_readBuffer subdataWithRange:sliceRange]; + + _readBufferOffset += foundSize; + + if (_readBufferOffset > 4096 && _readBufferOffset > (_readBuffer.length >> 1)) { + _readBuffer = [[NSMutableData alloc] initWithBytes:(char *)_readBuffer.bytes + _readBufferOffset length:_readBuffer.length - _readBufferOffset]; _readBufferOffset = 0; + } + + if (consumer.unmaskBytes) { + NSMutableData *mutableSlice = [slice mutableCopy]; + + NSUInteger len = mutableSlice.length; + uint8_t *bytes = mutableSlice.mutableBytes; + + for (int i = 0; i < len; i++) { + bytes[i] = bytes[i] ^ _currentReadMaskKey[_currentReadMaskOffset % sizeof(_currentReadMaskKey)]; + _currentReadMaskOffset += 1; + } + + slice = mutableSlice; + } + + if (consumer.readToCurrentFrame) { + [_currentFrameData appendData:slice]; + + _readOpCount += 1; + + if (_currentFrameOpcode == SROpCodeTextFrame) { + // Validate UTF8 stuff. + size_t currentDataSize = _currentFrameData.length; + if (_currentFrameOpcode == SROpCodeTextFrame && currentDataSize > 0) { + // TODO: Optimize the crap out of this. Don't really have to copy all the data each time + + size_t scanSize = currentDataSize - _currentStringScanPosition; + + NSData *scan_data = [_currentFrameData subdataWithRange:NSMakeRange(_currentStringScanPosition, scanSize)]; + int32_t valid_utf8_size = validate_dispatch_data_partial_string(scan_data); + + if (valid_utf8_size == -1) { + [self closeWithCode:SRStatusCodeInvalidUTF8 reason:@"Text frames must be valid UTF-8"]; + dispatch_async(_workQueue, ^{ + [self _disconnect]; + }); + return didWork; + } else { + _currentStringScanPosition += valid_utf8_size; + } + } + + } + + consumer.bytesNeeded -= foundSize; + + if (consumer.bytesNeeded == 0) { + [_consumers removeObjectAtIndex:0]; + consumer.handler(self, nil); + didWork = YES; + } + } else if (foundSize) { + [_consumers removeObjectAtIndex:0]; + consumer.handler(self, slice); + didWork = YES; + } + } + return didWork; +} + +-(void)_pumpScanner; +{ + [self assertOnWorkQueue]; + + if (!_isPumping) { + _isPumping = YES; + } else { + return; + } + + while ([self _innerPumpScanner]) { + + } + + _isPumping = NO; +} + +//#define NOMASK + +static const size_t SRFrameHeaderOverhead = 32; + +- (void)_sendFrameWithOpcode:(FSROpCode)opcode data:(id)data; +{ + [self assertOnWorkQueue]; + + NSAssert(data == nil || [data isKindOfClass:[NSData class]] || [data isKindOfClass:[NSString class]], @"Function expects nil, NSString or NSData"); + + size_t payloadLength = [data isKindOfClass:[NSString class]] ? [(NSString *)data lengthOfBytesUsingEncoding:NSUTF8StringEncoding] : [data length]; + + NSMutableData *frame = [[NSMutableData alloc] initWithLength:payloadLength + SRFrameHeaderOverhead]; + if (!frame) { + [self closeWithCode:SRStatusCodeMessageTooBig reason:@"Message too big"]; + return; + } + uint8_t *frame_buffer = (uint8_t *)[frame mutableBytes]; + + // set fin + frame_buffer[0] = SRFinMask | opcode; + + BOOL useMask = YES; +#ifdef NOMASK + useMask = NO; +#endif + + if (useMask) { + // set the mask and header + frame_buffer[1] |= SRMaskMask; + } + + size_t frame_buffer_size = 2; + + const uint8_t *unmasked_payload = NULL; + if ([data isKindOfClass:[NSData class]]) { + unmasked_payload = (uint8_t *)[data bytes]; + } else if ([data isKindOfClass:[NSString class]]) { + unmasked_payload = (const uint8_t *)[data UTF8String]; + } else { + assert(NO); + } + + if (payloadLength < 126) { + frame_buffer[1] |= payloadLength; + } else if (payloadLength <= UINT16_MAX) { + frame_buffer[1] |= 126; + *((uint16_t *)(frame_buffer + frame_buffer_size)) = EndianU16_BtoN((uint16_t)payloadLength); + frame_buffer_size += sizeof(uint16_t); + } else { + frame_buffer[1] |= 127; + *((uint64_t *)(frame_buffer + frame_buffer_size)) = EndianU64_BtoN((uint64_t)payloadLength); + frame_buffer_size += sizeof(uint64_t); + } + + if (!useMask) { + for (int i = 0; i < payloadLength; i++) { + frame_buffer[frame_buffer_size] = unmasked_payload[i]; + frame_buffer_size += 1; + } + } else { + uint8_t *mask_key = frame_buffer + frame_buffer_size; + int result = SecRandomCopyBytes(kSecRandomDefault, sizeof(uint32_t), (uint8_t *)mask_key); + assert(result == 0); + frame_buffer_size += sizeof(uint32_t); + + // TODO: could probably optimize this with SIMD + for (int i = 0; i < payloadLength; i++) { + frame_buffer[frame_buffer_size] = unmasked_payload[i] ^ mask_key[i % sizeof(uint32_t)]; + frame_buffer_size += 1; + } + } + + assert(frame_buffer_size <= [frame length]); + frame.length = frame_buffer_size; + + [self _writeData:frame]; +} + +- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode; +{ + __weak __typeof__(self) weakSelf = self; + + // turn on keep-alive for the output stream. + if (eventCode == NSStreamEventOpenCompleted && aStream == _outputStream) { + CFDataRef socketData = CFWriteStreamCopyProperty((CFWriteStreamRef)_outputStream, kCFStreamPropertySocketNativeHandle); + // In rare cases socketData might be nil (there are crash reports out there), in which case we'll have to just + // live without keep-alive :( + if (socketData != nil) { + CFSocketNativeHandle socket; + CFDataGetBytes(socketData, CFRangeMake(0, sizeof(CFSocketNativeHandle)), (UInt8 *)&socket); + CFRelease(socketData); + + int keepAliveOn = 1; + if (setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &keepAliveOn, sizeof(keepAliveOn)) == -1) { + SRFastLog(@"Failed to turn on TCP keepalive for websocket"); + } + } + } + + if (_secure && !_pinnedCertFound && (eventCode == NSStreamEventHasBytesAvailable || eventCode == NSStreamEventHasSpaceAvailable)) { + + NSArray *sslCerts = [_urlRequest FSR_SSLPinnedCertificates]; + if (sslCerts) { + SecTrustRef secTrust = (__bridge SecTrustRef)[aStream propertyForKey:(__bridge id)kCFStreamPropertySSLPeerTrust]; + if (secTrust) { + NSInteger numCerts = SecTrustGetCertificateCount(secTrust); + for (NSInteger i = 0; i < numCerts && !_pinnedCertFound; i++) { + SecCertificateRef cert = SecTrustGetCertificateAtIndex(secTrust, i); + NSData *certData = CFBridgingRelease(SecCertificateCopyData(cert)); + + for (id ref in sslCerts) { + SecCertificateRef trustedCert = (__bridge SecCertificateRef)ref; + NSData *trustedCertData = CFBridgingRelease(SecCertificateCopyData(trustedCert)); + + if ([trustedCertData isEqualToData:certData]) { + _pinnedCertFound = YES; + break; + } + } + } + } + + if (!_pinnedCertFound) { + dispatch_async(_workQueue, ^{ + NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : @"Invalid server cert" }; + [weakSelf _failWithError:[NSError errorWithDomain:@"org.lolrus.SocketRocket" code:23556 userInfo:userInfo]]; + }); + return; + } + } + } + + // SRFastLog(@"%@ Got stream event %d", aStream, eventCode); + dispatch_async(_workQueue, ^{ + [weakSelf safeHandleEvent:eventCode stream:aStream]; + }); +} + +- (void)safeHandleEvent:(NSStreamEvent)eventCode stream:(NSStream *)aStream +{ + switch (eventCode) { + case NSStreamEventOpenCompleted: { + SRFastLog(@"NSStreamEventOpenCompleted %@", aStream); + if (self.readyState >= SR_CLOSING) { + return; + } + + + assert(_readBuffer); + + if (self.readyState == SR_CONNECTING && aStream == _inputStream) { + [self didConnect]; + } + [self _pumpWriting]; + [self _pumpScanner]; + break; + } + + case NSStreamEventErrorOccurred: { + SRFastLog(@"NSStreamEventErrorOccurred %@ %@", aStream, [[aStream streamError] copy]); + /// TODO specify error better! + [self _failWithError:aStream.streamError]; + _readBufferOffset = 0; + [_readBuffer setLength:0]; + break; + + } + + case NSStreamEventEndEncountered: { + [self _pumpScanner]; + SRFastLog(@"NSStreamEventEndEncountered %@", aStream); + if (aStream.streamError) { + [self _failWithError:aStream.streamError]; + } else { + dispatch_async(_workQueue, ^{ + if (self.readyState != SR_CLOSED) { + self.readyState = SR_CLOSED; + [self _scheduleCleanup]; + } + + if (!self->_sentClose && !self->_failed) { + self->_sentClose = YES; + // If we get closed in this state it's probably not clean because we should be sending this when we send messages + [self _performDelegateBlock:^{ + if ([self.delegate respondsToSelector:@selector(webSocket:didCloseWithCode:reason:wasClean:)]) { + [self.delegate webSocket:self didCloseWithCode:0 reason:@"Stream end encountered" wasClean:NO]; + } + }]; + } + }); + } + + break; + } + + case NSStreamEventHasBytesAvailable: { + SRFastLog(@"NSStreamEventHasBytesAvailable %@", aStream); + const NSUInteger bufferSize = 2048; + uint8_t buffer[bufferSize]; + + while (_inputStream.hasBytesAvailable) { + NSInteger bytes_read = [_inputStream read:buffer maxLength:bufferSize]; + + if (bytes_read > 0) { + [_readBuffer appendBytes:buffer length:bytes_read]; + } else if (bytes_read < 0) { + [self _failWithError:_inputStream.streamError]; + } + + if (bytes_read != bufferSize) { + break; + } + }; + [self _pumpScanner]; + break; + } + + case NSStreamEventHasSpaceAvailable: { + SRFastLog(@"NSStreamEventHasSpaceAvailable %@", aStream); + [self _pumpWriting]; + break; + } + + default: + SRFastLog(@"(default) %@", aStream); + break; + } +} + +@end + + +@implementation FSRIOConsumer + +@synthesize bytesNeeded = _bytesNeeded; +@synthesize consumer = _scanner; +@synthesize handler = _handler; +@synthesize readToCurrentFrame = _readToCurrentFrame; +@synthesize unmaskBytes = _unmaskBytes; + +- (void)setupWithScanner:(stream_scanner)scanner handler:(data_callback)handler bytesNeeded:(size_t)bytesNeeded readToCurrentFrame:(BOOL)readToCurrentFrame unmaskBytes:(BOOL)unmaskBytes; +{ + _scanner = [scanner copy]; + _handler = [handler copy]; + _bytesNeeded = bytesNeeded; + _readToCurrentFrame = readToCurrentFrame; + _unmaskBytes = unmaskBytes; + assert(_scanner || _bytesNeeded); +} + +@end + +@implementation FSRIOConsumerPool { + NSUInteger _poolSize; + NSMutableArray *_bufferedConsumers; +} + +- (id)initWithBufferCapacity:(NSUInteger)poolSize; +{ + self = [super init]; + if (self) { + _poolSize = poolSize; + _bufferedConsumers = [[NSMutableArray alloc] initWithCapacity:poolSize]; + } + return self; +} + +- (id)init +{ + return [self initWithBufferCapacity:8]; +} + +- (FSRIOConsumer *)consumerWithScanner:(stream_scanner)scanner handler:(data_callback)handler bytesNeeded:(size_t)bytesNeeded readToCurrentFrame:(BOOL)readToCurrentFrame unmaskBytes:(BOOL)unmaskBytes; +{ + FSRIOConsumer *consumer = nil; + if (_bufferedConsumers.count) { + consumer = [_bufferedConsumers lastObject]; + [_bufferedConsumers removeLastObject]; + } else { + consumer = [[FSRIOConsumer alloc] init]; + } + + [consumer setupWithScanner:scanner handler:handler bytesNeeded:bytesNeeded readToCurrentFrame:readToCurrentFrame unmaskBytes:unmaskBytes]; + + return consumer; +} + +- (void)returnConsumer:(FSRIOConsumer *)consumer; +{ + if (_bufferedConsumers.count < _poolSize) { + [_bufferedConsumers addObject:consumer]; + } +} + +@end + +@implementation NSURLRequest (FCertificateAdditions) + +- (NSArray *)FSR_SSLPinnedCertificates; +{ + return [NSURLProtocol propertyForKey:@"FSR_SSLPinnedCertificates" inRequest:self]; +} + +@end + +@implementation NSMutableURLRequest (FCertificateAdditions) + +- (NSArray *)FSR_SSLPinnedCertificates; +{ + return [NSURLProtocol propertyForKey:@"FSR_SSLPinnedCertificates" inRequest:self]; +} + +- (void)setFSR_SSLPinnedCertificates:(NSArray *)FSR_SSLPinnedCertificates; +{ + [NSURLProtocol setProperty:FSR_SSLPinnedCertificates forKey:@"FSR_SSLPinnedCertificates" inRequest:self]; +} + +@end + +@implementation NSURL (FSRWebSocket) + +- (NSString *)SR_origin; +{ + NSString *scheme = [self.scheme lowercaseString]; + + if ([scheme isEqualToString:@"wss"]) { + scheme = @"https"; + } else if ([scheme isEqualToString:@"ws"]) { + scheme = @"http"; + } + + if (self.port != nil) { + return [NSString stringWithFormat:@"%@://%@:%@/", scheme, self.host, self.port]; + } else { + return [NSString stringWithFormat:@"%@://%@/", scheme, self.host]; + } +} + +@end + +// #define SR_ENABLE_LOG + +static inline void SRFastLog(NSString *format, ...) { +#ifdef SR_ENABLE_LOG + __block va_list arg_list; + va_start (arg_list, format); + + NSString *formattedString = [[NSString alloc] initWithFormat:format arguments:arg_list]; + + va_end(arg_list); + + NSLog(@"[SR] %@", formattedString); +#endif +} + + +#ifdef HAS_ICU + +static inline int32_t validate_dispatch_data_partial_string(NSData *data) { + + const void * contents = [data bytes]; + long size = [data length]; + + const uint8_t *str = (const uint8_t *)contents; + + + UChar32 codepoint = 1; + int32_t offset = 0; + int32_t lastOffset = 0; + while(offset < size && codepoint > 0) { + lastOffset = offset; + U8_NEXT(str, offset, size, codepoint); + } + + if (codepoint == -1) { + // Check to see if the last byte is valid or whether it was just continuing + if (!U8_IS_LEAD(str[lastOffset]) || U8_COUNT_TRAIL_BYTES(str[lastOffset]) + lastOffset < (int32_t)size) { + + size = -1; + } else { + uint8_t leadByte = str[lastOffset]; + U8_MASK_LEAD_BYTE(leadByte, U8_COUNT_TRAIL_BYTES(leadByte)); + + for (int i = lastOffset + 1; i < offset; i++) { + + if (U8_IS_SINGLE(str[i]) || U8_IS_LEAD(str[i]) || !U8_IS_TRAIL(str[i])) { + size = -1; + } + } + + if (size != -1) { + size = lastOffset; + } + } + } + + if (size != -1 && ![[NSString alloc] initWithBytesNoCopy:(char *)[data bytes] length:size encoding:NSUTF8StringEncoding freeWhenDone:NO]) { + size = -1; + } + + return (int32_t)size; +} + +#else + +// This is a hack, and probably not optimal +static inline int32_t validate_dispatch_data_partial_string(NSData *data) { + static const int maxCodepointSize = 3; + + for (int i = 0; i < maxCodepointSize; i++) { + NSString *str = [[NSString alloc] initWithBytesNoCopy:(char *)data.bytes length:data.length - i encoding:NSUTF8StringEncoding freeWhenDone:NO]; + if (str) { + return (int)(data.length - i); + } + } + + return -1; +} + +#endif + +static _FSRRunLoopThread *networkThread = nil; +static NSRunLoop *networkRunLoop = nil; + +@implementation NSRunLoop (FSRWebSocket) + ++ (NSRunLoop *)FSR_networkRunLoop { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + networkThread = [[_FSRRunLoopThread alloc] init]; + networkThread.name = @"com.squareup.SocketRocket.NetworkThread"; + [networkThread start]; + networkRunLoop = networkThread.runLoop; + }); + + return networkRunLoop; +} + +@end + + +@implementation _FSRRunLoopThread { + dispatch_group_t _waitGroup; +} + +@synthesize runLoop = _runLoop; + +- (void)dealloc +{ + sr_dispatch_release(_waitGroup); +} + +- (id)init +{ + self = [super init]; + if (self) { + _waitGroup = dispatch_group_create(); + dispatch_group_enter(_waitGroup); + } + return self; +} + + +/** + * This is the main method of the thread on which the socket events are scheduled in a run loop. + */ +- (void)main; +{ + @autoreleasepool { + _runLoop = [NSRunLoop currentRunLoop]; + dispatch_group_leave(_waitGroup); + + // Add an empty run loop source to prevent runloop from spinning. + CFRunLoopSourceContext sourceCtx = { + .version = 0, + .info = NULL, + .retain = NULL, + .release = NULL, + .copyDescription = NULL, + .equal = NULL, + .hash = NULL, + .schedule = NULL, + .cancel = NULL, + .perform = NULL + }; + CFRunLoopSourceRef source = CFRunLoopSourceCreate(NULL, 0, &sourceCtx); + CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode); + CFRelease(source); + + while ([_runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]) { + + } + assert(NO); + } +} + +- (NSRunLoop *)runLoop; +{ + dispatch_group_wait(_waitGroup, DISPATCH_TIME_FOREVER); + return _runLoop; +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/SocketRocket/NSData+SRB64Additions.h b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/SocketRocket/NSData+SRB64Additions.h new file mode 100644 index 00000000..bac393bc --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/SocketRocket/NSData+SRB64Additions.h @@ -0,0 +1,23 @@ +// +// Copyright 2012 Square Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +@interface FSRUtilities : NSObject + ++ (NSString *)base64EncodedStringFromData:(NSData *)data; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/SocketRocket/NSData+SRB64Additions.m b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/SocketRocket/NSData+SRB64Additions.m new file mode 100644 index 00000000..2be1d842 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/SocketRocket/NSData+SRB64Additions.m @@ -0,0 +1,37 @@ +// +// Copyright 2012 Square Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "NSData+SRB64Additions.h" +#import "fbase64.h" + +@implementation FSRUtilities + ++ (NSString *)base64EncodedStringFromData:(NSData *)data { + size_t buffer_size = ((data.length * 3 + 2) / 2); + + char *buffer = (char *)malloc(buffer_size); + + int len = f_b64_ntop(data.bytes, data.length, buffer, buffer_size); + + if (len == -1) { + free(buffer); + return nil; + } else{ + return [[NSString alloc] initWithBytesNoCopy:buffer length:len encoding:NSUTF8StringEncoding freeWhenDone:YES]; + } +} + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/SocketRocket/fbase64.c b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/SocketRocket/fbase64.c new file mode 100644 index 00000000..238c23cf --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/SocketRocket/fbase64.c @@ -0,0 +1,318 @@ +/* $OpenBSD: base64.c,v 1.5 2006/10/21 09:55:03 otto Exp $ */ + +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +/* OPENBSD ORIGINAL: lib/libc/net/base64.c */ + + +// +// Distributed with modifications by Firebase ( https://www.firebase.com ) +// + +#if (!defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP)) || (!defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON)) + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "fbase64.h" + +static const char Base64[] = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char Pad64 = '='; + +/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) + The following encoding technique is taken from RFC 1521 by Borenstein + and Freed. It is reproduced here in a slightly edited form for + convenience. + + A 65-character subset of US-ASCII is used, enabling 6 bits to be + represented per printable character. (The extra 65th character, "=", + is used to signify a special processing function.) + + The encoding process represents 24-bit groups of input bits as output + strings of 4 encoded characters. Proceeding from left to right, a + 24-bit input group is formed by concatenating 3 8-bit input groups. + These 24 bits are then treated as 4 concatenated 6-bit groups, each + of which is translated into a single digit in the base64 alphabet. + + Each 6-bit group is used as an index into an array of 64 printable + characters. The character referenced by the index is placed in the + output string. + + Table 1: The Base64 Alphabet + + Value Encoding Value Encoding Value Encoding Value Encoding + 0 A 17 R 34 i 51 z + 1 B 18 S 35 j 52 0 + 2 C 19 T 36 k 53 1 + 3 D 20 U 37 l 54 2 + 4 E 21 V 38 m 55 3 + 5 F 22 W 39 n 56 4 + 6 G 23 X 40 o 57 5 + 7 H 24 Y 41 p 58 6 + 8 I 25 Z 42 q 59 7 + 9 J 26 a 43 r 60 8 + 10 K 27 b 44 s 61 9 + 11 L 28 c 45 t 62 + + 12 M 29 d 46 u 63 / + 13 N 30 e 47 v + 14 O 31 f 48 w (pad) = + 15 P 32 g 49 x + 16 Q 33 h 50 y + + Special processing is performed if fewer than 24 bits are available + at the end of the data being encoded. A full encoding quantum is + always completed at the end of a quantity. When fewer than 24 input + bits are available in an input group, zero bits are added (on the + right) to form an integral number of 6-bit groups. Padding at the + end of the data is performed using the '=' character. + + Since all base64 input is an integral number of octets, only the + ------------------------------------------------- + following cases can arise: + + (1) the final quantum of encoding input is an integral + multiple of 24 bits; here, the final unit of encoded + output will be an integral multiple of 4 characters + with no "=" padding, + (2) the final quantum of encoding input is exactly 8 bits; + here, the final unit of encoded output will be two + characters followed by two "=" padding characters, or + (3) the final quantum of encoding input is exactly 16 bits; + here, the final unit of encoded output will be three + characters followed by one "=" padding character. + */ + +#if !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) +int +f_b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) +{ + size_t datalength = 0; + u_char input[3]; + u_char output[4]; + u_int i; + + while (2 < srclength) { + input[0] = *src++; + input[1] = *src++; + input[2] = *src++; + srclength -= 3; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + output[3] = input[2] & 0x3f; + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + target[datalength++] = Base64[output[2]]; + target[datalength++] = Base64[output[3]]; + } + + /* Now we worry about padding. */ + if (0 != srclength) { + /* Get what's left. */ + input[0] = input[1] = input[2] = '\0'; + for (i = 0; i < srclength; i++) + input[i] = *src++; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + if (srclength == 1) + target[datalength++] = Pad64; + else + target[datalength++] = Base64[output[2]]; + target[datalength++] = Pad64; + } + if (datalength >= targsize) + return (-1); + target[datalength] = '\0'; /* Returned value doesn't count \0. */ + return (int)(datalength); +} +#endif /* !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) */ + +#if !defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON) + +/* skips all whitespace anywhere. + converts characters, four at a time, starting at (or after) + src from base - 64 numbers into three 8 bit bytes in the target area. + it returns the number of data bytes stored at the target, or -1 on error. + */ + +int +f_b64_pton(char const *src, u_char *target, size_t targsize) +{ + u_int tarindex, state; + int ch; + char *pos; + + state = 0; + tarindex = 0; + + while ((ch = *src++) != '\0') { + if (isspace(ch)) /* Skip whitespace anywhere. */ + continue; + + if (ch == Pad64) + break; + + pos = strchr(Base64, ch); + if (pos == 0) /* A non-base64 character. */ + return (-1); + + switch (state) { + case 0: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] = (pos - Base64) << 2; + } + state = 1; + break; + case 1: + if (target) { + if (tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 4; + target[tarindex+1] = ((pos - Base64) & 0x0f) + << 4 ; + } + tarindex++; + state = 2; + break; + case 2: + if (target) { + if (tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 2; + target[tarindex+1] = ((pos - Base64) & 0x03) + << 6; + } + tarindex++; + state = 3; + break; + case 3: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64); + } + tarindex++; + state = 0; + break; + } + } + + /* + * We are done decoding Base-64 chars. Let's see if we ended + * on a byte boundary, and/or with erroneous trailing characters. + */ + + if (ch == Pad64) { /* We got a pad char. */ + ch = *src++; /* Skip it, get next. */ + switch (state) { + case 0: /* Invalid = in first position */ + case 1: /* Invalid = in second position */ + return (-1); + + case 2: /* Valid, means one byte of info */ + /* Skip any number of spaces. */ + for (; ch != '\0'; ch = *src++) + if (!isspace(ch)) + break; + /* Make sure there is another trailing = sign. */ + if (ch != Pad64) + return (-1); + ch = *src++; /* Skip the = */ + /* Fall through to "single trailing =" case. */ + /* FALLTHROUGH */ + + case 3: /* Valid, means two bytes of info */ + /* + * We know this char is an =. Is there anything but + * whitespace after it? + */ + for (; ch != '\0'; ch = *src++) + if (!isspace(ch)) + return (-1); + + /* + * Now make sure for cases 2 and 3 that the "extra" + * bits that slopped past the last full byte were + * zeros. If we don't check them, they become a + * subliminal channel. + */ + if (target && target[tarindex] != 0) + return (-1); + } + } else { + /* + * We ended by seeing the end of the string. Make sure we + * have no partial bytes lying around. + */ + if (state != 0) + return (-1); + } + + return (tarindex); +} + +#endif /* !defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON) */ +#endif diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/SocketRocket/fbase64.h b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/SocketRocket/fbase64.h new file mode 100644 index 00000000..a9bf1427 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/SocketRocket/fbase64.h @@ -0,0 +1,33 @@ +// Copyright 2012 Square Inc. +// +// 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. +// + +#ifndef FSocketRocket_base64_h +#define FSocketRocket_base64_h + +#include + +extern int +f_b64_ntop(u_char const *src, + size_t srclength, + char *target, + size_t targsize); + +extern int +f_b64_pton(char const *src, + u_char *target, + size_t targsize); + + +#endif diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/Wrap-leveldb/APLevelDB.h b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/Wrap-leveldb/APLevelDB.h new file mode 100644 index 00000000..c0baa224 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/Wrap-leveldb/APLevelDB.h @@ -0,0 +1,105 @@ +// +// APLevelDB.h +// +// Created by Adam Preble on 1/23/12. +// Copyright (c) 2012 Adam Preble. All rights reserved. +// +// 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. + +#import + +extern NSString * const APLevelDBErrorDomain; + +@class APLevelDBIterator; +@protocol APLevelDBWriteBatch; + +@interface APLevelDB : NSObject + +@property (nonatomic, readonly, strong) NSString *path; + ++ (APLevelDB *)levelDBWithPath:(NSString *)path error:(NSError *__autoreleasing*)errorOut; +- (void)close; + +- (BOOL)setData:(NSData *)data forKey:(NSString *)key; +- (BOOL)setString:(NSString *)str forKey:(NSString *)key; + +- (NSData *)dataForKey:(NSString *)key; +- (NSString *)stringForKey:(NSString *)key; + +- (BOOL)removeKey:(NSString *)key; + +- (NSArray *)allKeys; + +- (void)enumerateKeys:(void (^)(NSString *key, BOOL *stop))block; +- (void)enumerateKeysWithPrefix:(NSString *)prefix usingBlock:(void (^)(NSString *key, BOOL *stop))block; + +- (void)enumerateKeysAndValuesAsStrings:(void (^)(NSString *key, NSString *value, BOOL *stop))block; +- (void)enumerateKeysWithPrefix:(NSString *)prefix asStrings:(void (^)(NSString *key, NSString *value, BOOL *stop))block; + +- (void)enumerateKeysAndValuesAsData:(void (^)(NSString *key, NSData *value, BOOL *stop))block; +- (void)enumerateKeysWithPrefix:(NSString *)prefix asData:(void (^)(NSString *key, NSData *value, BOOL *stop))block; + +- (NSUInteger)approximateSizeFrom:(NSString *)from to:(NSString *)to; +- (NSUInteger)exactSizeFrom:(NSString *)from to:(NSString *)to; + +// Objective-C Subscripting Support: +// The database object supports subscripting for string-string and string-data key-value access and assignment. +// Examples: +// db[@"key"] = @"value"; +// db[@"key"] = [NSData data]; +// NSString *s = db[@"key"]; +// An NSInvalidArgumentException is raised if the key is not an NSString, or if the assigned object is not an +// instance of NSString or NSData. +- (id)objectForKeyedSubscript:(id)key; +- (void)setObject:(id)object forKeyedSubscript:(id)key; + +// Batch write/atomic update support: +- (id)beginWriteBatch; + +@end + + +@interface APLevelDBIterator : NSObject + ++ (id)iteratorWithLevelDB:(APLevelDB *)db; + +// Designated initializer: +- (id)initWithLevelDB:(APLevelDB *)db; + +- (BOOL)seekToKey:(NSString *)key; +- (NSString *)nextKey; +- (NSString *)key; +- (NSString *)valueAsString; +- (NSData *)valueAsData; + +@end + + +@protocol APLevelDBWriteBatch + +- (void)setData:(NSData *)data forKey:(NSString *)key; +- (void)setString:(NSString *)str forKey:(NSString *)key; + +- (void)removeKey:(NSString *)key; + +// Remove all of the buffered sets and removes: +- (void)clear; +- (BOOL)commit; + +@end diff --git a/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/Wrap-leveldb/APLevelDB.mm b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/Wrap-leveldb/APLevelDB.mm new file mode 100644 index 00000000..cdecce68 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/Firebase/Database/third_party/Wrap-leveldb/APLevelDB.mm @@ -0,0 +1,500 @@ +// +// APLevelDB.m +// +// Created by Adam Preble on 1/23/12. +// Copyright (c) 2012 Adam Preble. All rights reserved. +// +// 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. + +// +// Portions of APLevelDB are based on LevelDB-ObjC: +// https://github.com/hoisie/LevelDB-ObjC +// Specifically the SliceFromString/StringFromSlice macros, and the structure of +// the enumeration methods. License for those potions follows: +// +// Copyright (c) 2011 Pave Labs +// +// 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. +// + +#import "APLevelDB.h" + +#import "leveldb/db.h" +#import "leveldb/options.h" +#import "leveldb/write_batch.h" + +NSString * const APLevelDBErrorDomain = @"APLevelDBErrorDomain"; + +#define SliceFromString(_string_) (leveldb::Slice((char *)[_string_ UTF8String], [_string_ lengthOfBytesUsingEncoding:NSUTF8StringEncoding])) +#define StringFromSlice(_slice_) ([[NSString alloc] initWithBytes:_slice_.data() length:_slice_.size() encoding:NSUTF8StringEncoding]) + + +@interface APLevelDBWriteBatch : NSObject { + @package + leveldb::WriteBatch _batch; +} + +@property (nonatomic, strong) APLevelDB *levelDB; + +- (id)initWithLevelDB:(APLevelDB *)levelDB; +@end + + +#pragma mark - APLevelDB + +@interface APLevelDB () { + leveldb::DB *_db; + leveldb::ReadOptions _readOptions; + leveldb::WriteOptions _writeOptions; +} +- (id)initWithPath:(NSString *)path error:(NSError **)errorOut; ++ (leveldb::Options)defaultCreateOptions; +@property (nonatomic, readonly) leveldb::DB *db; +@end + + +@implementation APLevelDB + +@synthesize path = _path; +@synthesize db = _db; + ++ (APLevelDB *)levelDBWithPath:(NSString *)path error:(NSError *__autoreleasing *)errorOut +{ + return [[APLevelDB alloc] initWithPath:path error:errorOut]; +} + +- (id)initWithPath:(NSString *)path error:(NSError *__autoreleasing *)errorOut +{ + if ((self = [super init])) + { + _path = path; + + leveldb::Options options = [[self class] defaultCreateOptions]; + + leveldb::Status status = leveldb::DB::Open(options, [_path UTF8String], &_db); + + if (!status.ok()) + { + if (errorOut) + { + NSString *statusString = [[NSString alloc] initWithCString:status.ToString().c_str() encoding:NSUTF8StringEncoding]; + *errorOut = [NSError errorWithDomain:APLevelDBErrorDomain + code:0 + userInfo:[NSDictionary dictionaryWithObjectsAndKeys:statusString, NSLocalizedDescriptionKey, nil]]; + } + return nil; + } + + _writeOptions.sync = false; + } + return self; +} + +- (void)close { + if (_db != NULL) { + delete _db; + _db = NULL; + } +} + +- (void)dealloc +{ + if (_db != NULL) { + delete _db; + _db = NULL; + } +} + ++ (leveldb::Options)defaultCreateOptions +{ + leveldb::Options options; + options.create_if_missing = true; + return options; +} + +- (BOOL)setData:(NSData *)data forKey:(NSString *)key +{ + leveldb::Slice keySlice = SliceFromString(key); + leveldb::Slice valueSlice = leveldb::Slice((const char *)[data bytes], (size_t)[data length]); + leveldb::Status status = _db->Put(_writeOptions, keySlice, valueSlice); + return (status.ok() == true); +} + +- (BOOL)setString:(NSString *)str forKey:(NSString *)key +{ + // This could have been based on + leveldb::Slice keySlice = SliceFromString(key); + leveldb::Slice valueSlice = SliceFromString(str); + leveldb::Status status = _db->Put(_writeOptions, keySlice, valueSlice); + return (status.ok() == true); +} + +- (NSData *)dataForKey:(NSString *)key +{ + leveldb::Slice keySlice = SliceFromString(key); + std::string valueCPPString; + leveldb::Status status = _db->Get(_readOptions, keySlice, &valueCPPString); + + if (!status.ok()) + return nil; + else + return [NSData dataWithBytes:valueCPPString.data() length:valueCPPString.size()]; +} + +- (NSString *)stringForKey:(NSString *)key +{ + leveldb::Slice keySlice = SliceFromString(key); + std::string valueCPPString; + leveldb::Status status = _db->Get(_readOptions, keySlice, &valueCPPString); + + // We assume (dangerously?) UTF-8 string encoding: + if (!status.ok()) + return nil; + else + return [[NSString alloc] initWithBytes:valueCPPString.data() length:valueCPPString.size() encoding:NSUTF8StringEncoding]; +} + +- (BOOL)removeKey:(NSString *)key +{ + leveldb::Slice keySlice = SliceFromString(key); + leveldb::Status status = _db->Delete(_writeOptions, keySlice); + return (status.ok() == true); +} + +- (NSArray *)allKeys +{ + NSMutableArray *keys = [NSMutableArray array]; + [self enumerateKeys:^(NSString *key, BOOL *stop) { + [keys addObject:key]; + }]; + return keys; +} + +- (void)enumerateKeysAndValuesAsStrings:(void (^)(NSString *key, NSString *value, BOOL *stop))block +{ + [self enumerateKeysWithPrefix:@"" asStrings:block]; +} + +- (void)enumerateKeysWithPrefix:(NSString *)prefixString asStrings:(void (^)(NSString *, NSString *, BOOL *))block +{ + @autoreleasepool { + BOOL stop = NO; + leveldb::Iterator* iter = _db->NewIterator(leveldb::ReadOptions()); + leveldb::Slice prefix = SliceFromString(prefixString); + for (iter->Seek(prefix); iter->Valid(); iter->Next()) { + leveldb::Slice key = iter->key(), value = iter->value(); + if (key.starts_with(prefix)) { + NSString *k = StringFromSlice(key); + NSString *v = [[NSString alloc] initWithBytes:value.data() length:value.size() encoding:NSUTF8StringEncoding]; + block(k, v, &stop); + if (stop) + break; + } else { + break; + } + } + + delete iter; + } +} + +- (void)enumerateKeys:(void (^)(NSString *key, BOOL *stop))block +{ + [self enumerateKeysWithPrefix:@"" usingBlock:block]; +} + +- (void)enumerateKeysWithPrefix:(NSString *)prefixString usingBlock:(void (^)(NSString *key, BOOL *stop))block; +{ + @autoreleasepool { + BOOL stop = NO; + leveldb::Slice prefix = SliceFromString(prefixString); + leveldb::Iterator* iter = _db->NewIterator(leveldb::ReadOptions()); + for (iter->Seek(prefix); iter->Valid(); iter->Next()) { + leveldb::Slice key = iter->key(); + if (key.starts_with(prefix)) { + NSString *k = StringFromSlice(key); + block(k, &stop); + if (stop) + break; + } else { + break; + } + } + + delete iter; + } +} + +- (void)enumerateKeysAndValuesAsData:(void (^)(NSString *key, NSData *data, BOOL *stop))block +{ + [self enumerateKeysWithPrefix:@"" asData:block]; +} + +- (void)enumerateKeysWithPrefix:(NSString *)prefixString asData:(void (^)(NSString *, NSData *, BOOL *))block +{ + @autoreleasepool { + BOOL stop = NO; + leveldb::Iterator* iter = _db->NewIterator(leveldb::ReadOptions()); + leveldb::Slice prefix = SliceFromString(prefixString); + for (iter->Seek(prefix); iter->Valid(); iter->Next()) { + leveldb::Slice key = iter->key(), value = iter->value(); + if (key.starts_with(prefix)) { + NSString *k = StringFromSlice(key); + NSData *data = [NSData dataWithBytes:value.data() length:value.size()]; + block(k, data, &stop); + if (stop) + break; + } else { + break; + } + } + + delete iter; + } +} + +- (NSUInteger)exactSizeFrom:(NSString *)from to:(NSString *)to { + NSUInteger size = 0; + leveldb::Iterator* iter = _db->NewIterator(leveldb::ReadOptions()); + leveldb::Slice fromSlice = SliceFromString(from); + leveldb::Slice toSlice = SliceFromString(to); + iter->Seek(fromSlice); + while (iter->Valid() && iter->key().compare(toSlice) <= 0) { + size += iter->value().size(); + iter->Next(); + } + delete iter; + return size; +} + + +- (NSUInteger)approximateSizeFrom:(NSString *)from to:(NSString *)to { + leveldb::Range ranges[1]; + leveldb::Slice fromSlice = SliceFromString(from); + leveldb::Slice toSlice = SliceFromString(to); + ranges[0] = leveldb::Range(fromSlice, toSlice); + uint64_t sizes[1]; + _db->GetApproximateSizes(ranges, 1, sizes); + return (NSUInteger)sizes[0]; +} + +#pragma mark - Subscripting Support + +- (id)objectForKeyedSubscript:(id)key +{ + if (![key respondsToSelector: @selector(componentsSeparatedByString:)]) + { + [NSException raise:NSInvalidArgumentException format:@"key must be an NSString"]; + } + return [self stringForKey:key]; +} +- (void)setObject:(id)thing forKeyedSubscript:(id)key +{ + id idKey = (id) key; + if (![idKey respondsToSelector: @selector(componentsSeparatedByString:)]) + { + [NSException raise:NSInvalidArgumentException format:@"key must be NSString or NSData"]; + } + + if ([thing respondsToSelector:@selector(componentsSeparatedByString:)]) + [self setString:thing forKey:(NSString *)key]; + else if ([thing respondsToSelector:@selector(subdataWithRange:)]) + [self setData:thing forKey:(NSString *)key]; + else + [NSException raise:NSInvalidArgumentException format:@"object must be NSString or NSData"]; +} + +#pragma mark - Atomic Updates + +- (id)beginWriteBatch +{ + APLevelDBWriteBatch *batch = [[APLevelDBWriteBatch alloc] initWithLevelDB:self]; + return batch; +} + +- (BOOL)commitWriteBatch:(id)theBatch +{ + if (!theBatch) + return NO; + + APLevelDBWriteBatch *batch = theBatch; + + leveldb::Status status; + status = _db->Write(_writeOptions, &batch->_batch); + return (status.ok() == true); +} + +@end + + +#pragma mark - APLevelDBIterator + +@interface APLevelDBIterator () { + leveldb::Iterator *_iter; +} + +@property (nonatomic, strong) APLevelDB *levelDB; +@end + + + +@implementation APLevelDBIterator + ++ (id)iteratorWithLevelDB:(APLevelDB *)db +{ + APLevelDBIterator *iter = [[[self class] alloc] initWithLevelDB:db]; + return iter; +} + +- (id)initWithLevelDB:(APLevelDB *)db +{ + if ((self = [super init])) + { + // Hold on to the database so it doesn't get deallocated before the iterator is deallocated + self->_levelDB = db; + _iter = db.db->NewIterator(leveldb::ReadOptions()); + _iter->SeekToFirst(); + if (!_iter->Valid()) + return nil; + } + return self; +} + +- (id)init +{ + [NSException raise:@"BadInitializer" format:@"Use the designated initializer, -initWithLevelDB:, instead."]; + return nil; +} + +- (void)dealloc +{ + self->_levelDB = nil; + delete _iter; + _iter = NULL; +} + +- (BOOL)seekToKey:(NSString *)key +{ + leveldb::Slice target = SliceFromString(key); + _iter->Seek(target); + return _iter->Valid() == true; +} + +- (void)seekToFirst +{ + _iter->SeekToFirst(); +} + +- (void)seekToLast +{ + _iter->SeekToLast(); +} + +- (NSString *)nextKey +{ + _iter->Next(); + return [self key]; +} + +- (NSString *)key +{ + if (_iter->Valid() == false) + return nil; + leveldb::Slice value = _iter->key(); + return StringFromSlice(value); +} + +- (NSString *)valueAsString +{ + if (_iter->Valid() == false) + return nil; + leveldb::Slice value = _iter->value(); + return StringFromSlice(value); +} + +- (NSData *)valueAsData +{ + if (_iter->Valid() == false) + return nil; + leveldb::Slice value = _iter->value(); + return [NSData dataWithBytes:value.data() length:value.size()]; +} + +@end + + + +#pragma mark - APLevelDBWriteBatch + +@implementation APLevelDBWriteBatch + +- (id)initWithLevelDB:(APLevelDB *)levelDB { + self = [super init]; + if (self != nil) { + self->_levelDB = levelDB; + } + return self; +} + +- (void)setData:(NSData *)data forKey:(NSString *)key +{ + leveldb::Slice keySlice = SliceFromString(key); + leveldb::Slice valueSlice = leveldb::Slice((const char *)[data bytes], (size_t)[data length]); + _batch.Put(keySlice, valueSlice); +} +- (void)setString:(NSString *)str forKey:(NSString *)key +{ + leveldb::Slice keySlice = SliceFromString(key); + leveldb::Slice valueSlice = SliceFromString(str); + _batch.Put(keySlice, valueSlice); +} + +- (void)removeKey:(NSString *)key +{ + leveldb::Slice keySlice = SliceFromString(key); + _batch.Delete(keySlice); +} + +- (void)clear +{ + _batch.Clear(); +} + +- (BOOL)commit { + return [self.levelDB commitWriteBatch:self]; +} + +@end + diff --git a/ios/Pods/FirebaseDatabase/LICENSE b/ios/Pods/FirebaseDatabase/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/ios/Pods/FirebaseDatabase/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/ios/Pods/FirebaseDatabase/README.md b/ios/Pods/FirebaseDatabase/README.md new file mode 100644 index 00000000..d414a4cd --- /dev/null +++ b/ios/Pods/FirebaseDatabase/README.md @@ -0,0 +1,193 @@ +# Firebase iOS Open Source Development [![Build Status](https://travis-ci.org/firebase/firebase-ios-sdk.svg?branch=master)](https://travis-ci.org/firebase/firebase-ios-sdk) + +This repository contains a subset of the Firebase iOS SDK source. It currently +includes FirebaseCore, FirebaseAuth, FirebaseDatabase, FirebaseFirestore, +FirebaseFunctions, FirebaseInAppMessagingDisplay, FirebaseMessaging and +FirebaseStorage. + +The repository also includes GoogleUtilities source. The +[GoogleUtilities](GoogleUtilities/README.md) pod is +a set of utilities used by Firebase and other Google products. + +Firebase is an app development platform with tools to help you build, grow and +monetize your app. More information about Firebase can be found at +[https://firebase.google.com](https://firebase.google.com). + +## Installation + +See the three subsections for details about three different installation methods. +1. [Standard pod install](README.md#standard-pod-install) +1. [Installing from the GitHub repo](README.md#installing-from-github) +1. [Experimental Carthage](README.md#carthage-ios-only) + +### Standard pod install + +Go to +[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup). + +### Installing from GitHub + +For releases starting with 5.0.0, the source for each release is also deployed +to CocoaPods master and available via standard +[CocoaPods Podfile syntax](https://guides.cocoapods.org/syntax/podfile.html#pod). + +These instructions can be used to access the Firebase repo at other branches, +tags, or commits. + +#### Background + +See +[the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod) +for instructions and options about overriding pod source locations. + +#### Accessing Firebase Source Snapshots + +All of the official releases are tagged in this repo and available via CocoaPods. To access a local +source snapshot or unreleased branch, use Podfile directives like the following: + +To access FirebaseFirestore via a branch: +``` +pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' +pod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' +``` + +To access FirebaseMessaging via a checked out version of the firebase-ios-sdk repo do: + +``` +pod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk' +pod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk' +``` + +### Carthage (iOS only) + +Instructions for the experimental Carthage distribution are at +[Carthage](Carthage.md). + +### Rome + +Instructions for installing binary frameworks via +[Rome](https://github.com/CocoaPods/Rome) are at [Rome](Rome.md). + +## Development + +Follow the subsequent instructions to develop, debug, unit test, run integration +tests, and try out reference samples: + +``` +$ git clone git@github.com:firebase/firebase-ios-sdk.git +$ cd firebase-ios-sdk/Example +$ pod update +$ open Firebase.xcworkspace +``` + +Firestore and Functions have self contained Xcode projects. See +[Firestore/README.md](Firestore/README.md) and +[Functions/README.md](Functions/README.md). + +### Code Formatting + +Travis will verify that any code changes are done in a style compliant way. Install +`clang-format` and `swiftformat`. +This command will get the right `clang-format` version: + +`brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/0743d748ba8b41eec074a0a787dc80219142c525/Formula/clang-format.rb` + +### Running Unit Tests + +Select a scheme and press Command-u to build a component and run its unit tests. + +### Running Sample Apps +In order to run the sample apps and integration tests, you'll need valid +`GoogleService-Info.plist` files for those samples. The Firebase Xcode project contains dummy plist +files without real values, but can be replaced with real plist files. To get your own +`GoogleService-Info.plist` files: + +1. Go to the [Firebase Console](https://console.firebase.google.com/) +2. Create a new Firebase project, if you don't already have one +3. For each sample app you want to test, create a new Firebase app with the sample app's bundle +identifier (e.g. `com.google.Database-Example`) +4. Download the resulting `GoogleService-Info.plist` and replace the appropriate dummy plist file +(e.g. in [Example/Database/App/](Example/Database/App/)); + +Some sample apps like Firebase Messaging ([Example/Messaging/App](Example/Messaging/App)) require +special Apple capabilities, and you will have to change the sample app to use a unique bundle +identifier that you can control in your own Apple Developer account. + +## Specific Component Instructions +See the sections below for any special instructions for those components. + +### Firebase Auth + +If you're doing specific Firebase Auth development, see +[the Auth Sample README](Example/Auth/README.md) for instructions about +building and running the FirebaseAuth pod along with various samples and tests. + +### Firebase Database + +To run the Database Integration tests, make your database authentication rules +[public](https://firebase.google.com/docs/database/security/quickstart). + +### Firebase Storage + +To run the Storage Integration tests, follow the instructions in +[FIRStorageIntegrationTests.m](Example/Storage/Tests/Integration/FIRStorageIntegrationTests.m). + +#### Push Notifications + +Push notifications can only be delivered to specially provisioned App IDs in the developer portal. +In order to actually test receiving push notifications, you will need to: + +1. Change the bundle identifier of the sample app to something you own in your Apple Developer +account, and enable that App ID for push notifications. +2. You'll also need to +[upload your APNs Provider Authentication Key or certificate to the Firebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs) +at **Project Settings > Cloud Messaging > [Your Firebase App]**. +3. Ensure your iOS device is added to your Apple Developer portal as a test device. + +#### iOS Simulator + +The iOS Simulator cannot register for remote notifications, and will not receive push notifications. +In order to receive push notifications, you'll have to follow the steps above and run the app on a +physical device. + +## Community Supported Efforts + +We've seen an amazing amount of interest and contributions to improve the Firebase SDKs, and we are +very grateful! We'd like to empower as many developers as we can to be able to use Firebase and +participate in the Firebase community. + +### macOS and tvOS +FirebaseAuth, FirebaseCore, FirebaseDatabase and FirebaseStorage now compile, run unit tests, and +work on macOS and tvOS, thanks to contributions from the community. There are a few tweaks needed, +like ensuring iOS-only, macOS-only, or tvOS-only code is correctly guarded with checks for +`TARGET_OS_IOS`, `TARGET_OS_OSX` and `TARGET_OS_TV`. + +For tvOS, checkout the [Sample](Example/tvOSSample). + +Keep in mind that macOS and tvOS are not officially supported by Firebase, and this repository is +actively developed primarily for iOS. While we can catch basic unit test issues with Travis, there +may be some changes where the SDK no longer works as expected on macOS or tvOS. If you encounter +this, please [file an issue](https://github.com/firebase/firebase-ios-sdk/issues). + +For installation instructions, see [above](README.md#accessing-firebase-source-snapshots). + +Note that the Firebase pod is not available for macOS and tvOS. Install a selection of the +`FirebaseAuth`, `FirebaseCore`, `FirebaseDatabase` and `FirebaseStorage` CocoaPods. + +## Roadmap + +See [Roadmap](ROADMAP.md) for more about the Firebase iOS SDK Open Source +plans and directions. + +## Contributing + +See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase +iOS SDK. + +## License + +The contents of this repository is licensed under the +[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). + +Your use of Firebase is governed by the +[Terms of Service for Firebase Services](https://firebase.google.com/terms/). diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMMessageCode.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMMessageCode.h new file mode 100644 index 00000000..4b16189a --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMMessageCode.h @@ -0,0 +1,191 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +typedef NS_ENUM(NSInteger, FIRMessagingMessageCode) { + // FIRMessaging+FIRApp.m + kFIRMessagingMessageCodeFIRApp000 = 1000, // I-FCM001000 + kFIRMessagingMessageCodeFIRApp001 = 1001, // I-FCM001001 + // FIRMessaging.m + kFIRMessagingMessageCodeMessagingPrintLibraryVersion = 2000, // I-FCM002000 + kFIRMessagingMessageCodeMessaging001 = 2001, // I-FCM002001 + kFIRMessagingMessageCodeMessaging002 = 2002, // I-FCM002002 - no longer used + kFIRMessagingMessageCodeMessaging003 = 2003, // I-FCM002003 + kFIRMessagingMessageCodeMessaging004 = 2004, // I-FCM002004 + kFIRMessagingMessageCodeMessaging005 = 2005, // I-FCM002005 + kFIRMessagingMessageCodeMessaging006 = 2006, // I-FCM002006 - no longer used + kFIRMessagingMessageCodeMessaging007 = 2007, // I-FCM002007 - no longer used + kFIRMessagingMessageCodeMessaging008 = 2008, // I-FCM002008 - no longer used + kFIRMessagingMessageCodeMessaging009 = 2009, // I-FCM002009 + kFIRMessagingMessageCodeMessaging010 = 2010, // I-FCM002010 + kFIRMessagingMessageCodeMessaging011 = 2011, // I-FCM002011 + kFIRMessagingMessageCodeMessaging012 = 2012, // I-FCM002012 + kFIRMessagingMessageCodeMessaging013 = 2013, // I-FCM002013 + kFIRMessagingMessageCodeMessaging014 = 2014, // I-FCM002014 + kFIRMessagingMessageCodeMessaging015 = 2015, // I-FCM002015 + kFIRMessagingMessageCodeMessaging016 = 2016, // I-FCM002016 - no longer used + kFIRMessagingMessageCodeMessaging017 = 2017, // I-FCM002017 + kFIRMessagingMessageCodeMessaging018 = 2018, // I-FCM002018 + kFIRMessagingMessageCodeRemoteMessageDelegateMethodNotImplemented = 2019, // I-FCM002019 + kFIRMessagingMessageCodeSenderIDNotSuppliedForTokenFetch = 2020, // I-FCM002020 + kFIRMessagingMessageCodeSenderIDNotSuppliedForTokenDelete = 2021, // I-FCM002021 + kFIRMessagingMessageCodeAPNSTokenNotAvailableDuringTokenFetch = 2022, // I-FCM002022 + kFIRMessagingMessageCodeTokenDelegateMethodsNotImplemented = 2023, // I-FCM002023 + kFIRMessagingMessageCodeTopicFormatIsDeprecated = 2024, + // FIRMessagingClient.m + kFIRMessagingMessageCodeClient000 = 4000, // I-FCM004000 + kFIRMessagingMessageCodeClient001 = 4001, // I-FCM004001 + kFIRMessagingMessageCodeClient002 = 4002, // I-FCM004002 + kFIRMessagingMessageCodeClient003 = 4003, // I-FCM004003 + kFIRMessagingMessageCodeClient004 = 4004, // I-FCM004004 + kFIRMessagingMessageCodeClient005 = 4005, // I-FCM004005 + kFIRMessagingMessageCodeClient006 = 4006, // I-FCM004006 + kFIRMessagingMessageCodeClient007 = 4007, // I-FCM004007 + kFIRMessagingMessageCodeClient008 = 4008, // I-FCM004008 + kFIRMessagingMessageCodeClient009 = 4009, // I-FCM004009 + kFIRMessagingMessageCodeClient010 = 4010, // I-FCM004010 + kFIRMessagingMessageCodeClient011 = 4011, // I-FCM004011 + // FIRMessagingConnection.m + kFIRMessagingMessageCodeConnection000 = 5000, // I-FCM005000 + kFIRMessagingMessageCodeConnection001 = 5001, // I-FCM005001 + kFIRMessagingMessageCodeConnection002 = 5002, // I-FCM005002 + kFIRMessagingMessageCodeConnection003 = 5003, // I-FCM005003 + kFIRMessagingMessageCodeConnection004 = 5004, // I-FCM005004 + kFIRMessagingMessageCodeConnection005 = 5005, // I-FCM005005 + kFIRMessagingMessageCodeConnection006 = 5006, // I-FCM005006 + kFIRMessagingMessageCodeConnection007 = 5007, // I-FCM005007 + kFIRMessagingMessageCodeConnection008 = 5008, // I-FCM005008 + kFIRMessagingMessageCodeConnection009 = 5009, // I-FCM005009 + kFIRMessagingMessageCodeConnection010 = 5010, // I-FCM005010 + kFIRMessagingMessageCodeConnection011 = 5011, // I-FCM005011 + kFIRMessagingMessageCodeConnection012 = 5012, // I-FCM005012 + kFIRMessagingMessageCodeConnection013 = 5013, // I-FCM005013 + kFIRMessagingMessageCodeConnection014 = 5014, // I-FCM005014 + kFIRMessagingMessageCodeConnection015 = 5015, // I-FCM005015 + kFIRMessagingMessageCodeConnection016 = 5016, // I-FCM005016 + kFIRMessagingMessageCodeConnection017 = 5017, // I-FCM005017 + kFIRMessagingMessageCodeConnection018 = 5018, // I-FCM005018 + kFIRMessagingMessageCodeConnection019 = 5019, // I-FCM005019 + kFIRMessagingMessageCodeConnection020 = 5020, // I-FCM005020 + kFIRMessagingMessageCodeConnection021 = 5021, // I-FCM005021 + kFIRMessagingMessageCodeConnection022 = 5022, // I-FCM005022 + kFIRMessagingMessageCodeConnection023 = 5023, // I-FCM005023 + // FIRMessagingContextManagerService.m + kFIRMessagingMessageCodeContextManagerService000 = 6000, // I-FCM006000 + kFIRMessagingMessageCodeContextManagerService001 = 6001, // I-FCM006001 + kFIRMessagingMessageCodeContextManagerService002 = 6002, // I-FCM006002 + kFIRMessagingMessageCodeContextManagerService003 = 6003, // I-FCM006003 + kFIRMessagingMessageCodeContextManagerService004 = 6004, // I-FCM006004 + kFIRMessagingMessageCodeContextManagerService005 = 6005, // I-FCM006005 + // FIRMessagingDataMessageManager.m + kFIRMessagingMessageCodeDataMessageManager000 = 7000, // I-FCM007000 + kFIRMessagingMessageCodeDataMessageManager001 = 7001, // I-FCM007001 + kFIRMessagingMessageCodeDataMessageManager002 = 7002, // I-FCM007002 + kFIRMessagingMessageCodeDataMessageManager003 = 7003, // I-FCM007003 + kFIRMessagingMessageCodeDataMessageManager004 = 7004, // I-FCM007004 + kFIRMessagingMessageCodeDataMessageManager005 = 7005, // I-FCM007005 + kFIRMessagingMessageCodeDataMessageManager006 = 7006, // I-FCM007006 + kFIRMessagingMessageCodeDataMessageManager007 = 7007, // I-FCM007007 + kFIRMessagingMessageCodeDataMessageManager008 = 7008, // I-FCM007008 + kFIRMessagingMessageCodeDataMessageManager009 = 7009, // I-FCM007009 + kFIRMessagingMessageCodeDataMessageManager010 = 7010, // I-FCM007010 + kFIRMessagingMessageCodeDataMessageManager011 = 7011, // I-FCM007011 + kFIRMessagingMessageCodeDataMessageManager012 = 7012, // I-FCM007012 + // FIRMessagingPendingTopicsList.m + kFIRMessagingMessageCodePendingTopicsList000 = 8000, // I-FCM008000 + // FIRMessagingPubSub.m + kFIRMessagingMessageCodePubSub000 = 9000, // I-FCM009000 + kFIRMessagingMessageCodePubSub001 = 9001, // I-FCM009001 + kFIRMessagingMessageCodePubSub002 = 9002, // I-FCM009002 + kFIRMessagingMessageCodePubSub003 = 9003, // I-FCM009003 + // FIRMessagingReceiver.m + kFIRMessagingMessageCodeReceiver000 = 10000, // I-FCM010000 + kFIRMessagingMessageCodeReceiver001 = 10001, // I-FCM010001 + kFIRMessagingMessageCodeReceiver002 = 10002, // I-FCM010002 + kFIRMessagingMessageCodeReceiver003 = 10003, // I-FCM010003 + kFIRMessagingMessageCodeReceiver004 = 10004, // I-FCM010004 - no longer used + kFIRMessagingMessageCodeReceiver005 = 10005, // I-FCM010005 + // FIRMessagingRegistrar.m + kFIRMessagingMessageCodeRegistrar000 = 11000, // I-FCM011000 + // FIRMessagingRemoteNotificationsProxy.m + kFIRMessagingMessageCodeRemoteNotificationsProxy000 = 12000, // I-FCM012000 + kFIRMessagingMessageCodeRemoteNotificationsProxy001 = 12001, // I-FCM012001 + kFIRMessagingMessageCodeRemoteNotificationsProxyAPNSFailed = 12002, // I-FCM012002 + kFIRMessagingMessageCodeRemoteNotificationsProxyMethodNotAdded = 12003, // I-FCM012003 + // FIRMessagingRmq2PersistentStore.m + kFIRMessagingMessageCodeRmq2PersistentStore000 = 13000, // I-FCM013000 + kFIRMessagingMessageCodeRmq2PersistentStore001 = 13001, // I-FCM013001 + kFIRMessagingMessageCodeRmq2PersistentStore002 = 13002, // I-FCM013002 + kFIRMessagingMessageCodeRmq2PersistentStore003 = 13003, // I-FCM013003 + kFIRMessagingMessageCodeRmq2PersistentStore004 = 13004, // I-FCM013004 + kFIRMessagingMessageCodeRmq2PersistentStore005 = 13005, // I-FCM013005 + kFIRMessagingMessageCodeRmq2PersistentStore006 = 13006, // I-FCM013006 + kFIRMessagingMessageCodeRmq2PersistentStoreErrorCreatingDatabase = 13007, // I-FCM013007 + kFIRMessagingMessageCodeRmq2PersistentStoreErrorOpeningDatabase = 13008, // I-FCM013008 + kFIRMessagingMessageCodeRmq2PersistentStoreInvalidRmqDirectory = 13009, // I-FCM013009 + kFIRMessagingMessageCodeRmq2PersistentStoreErrorCreatingTable = 13010, // I-FCM013010 + // FIRMessagingRmqManager.m + kFIRMessagingMessageCodeRmqManager000 = 14000, // I-FCM014000 + // FIRMessagingSecureSocket.m + kFIRMessagingMessageCodeSecureSocket000 = 15000, // I-FCM015000 + kFIRMessagingMessageCodeSecureSocket001 = 15001, // I-FCM015001 + kFIRMessagingMessageCodeSecureSocket002 = 15002, // I-FCM015002 + kFIRMessagingMessageCodeSecureSocket003 = 15003, // I-FCM015003 + kFIRMessagingMessageCodeSecureSocket004 = 15004, // I-FCM015004 + kFIRMessagingMessageCodeSecureSocket005 = 15005, // I-FCM015005 + kFIRMessagingMessageCodeSecureSocket006 = 15006, // I-FCM015006 + kFIRMessagingMessageCodeSecureSocket007 = 15007, // I-FCM015007 + kFIRMessagingMessageCodeSecureSocket008 = 15008, // I-FCM015008 + kFIRMessagingMessageCodeSecureSocket009 = 15009, // I-FCM015009 + kFIRMessagingMessageCodeSecureSocket010 = 15010, // I-FCM015010 + kFIRMessagingMessageCodeSecureSocket011 = 15011, // I-FCM015011 + kFIRMessagingMessageCodeSecureSocket012 = 15012, // I-FCM015012 + kFIRMessagingMessageCodeSecureSocket013 = 15013, // I-FCM015013 + kFIRMessagingMessageCodeSecureSocket014 = 15014, // I-FCM015014 + kFIRMessagingMessageCodeSecureSocket015 = 15015, // I-FCM015015 + kFIRMessagingMessageCodeSecureSocket016 = 15016, // I-FCM015016 + // FIRMessagingSyncMessageManager.m + kFIRMessagingMessageCodeSyncMessageManager000 = 16000, // I-FCM016000 + kFIRMessagingMessageCodeSyncMessageManager001 = 16001, // I-FCM016001 + kFIRMessagingMessageCodeSyncMessageManager002 = 16002, // I-FCM016002 + kFIRMessagingMessageCodeSyncMessageManager003 = 16003, // I-FCM016003 + kFIRMessagingMessageCodeSyncMessageManager004 = 16004, // I-FCM016004 + kFIRMessagingMessageCodeSyncMessageManager005 = 16005, // I-FCM016005 + kFIRMessagingMessageCodeSyncMessageManager006 = 16006, // I-FCM016006 + kFIRMessagingMessageCodeSyncMessageManager007 = 16007, // I-FCM016007 + kFIRMessagingMessageCodeSyncMessageManager008 = 16008, // I-FCM016008 + // FIRMessagingTopicOperation.m + kFIRMessagingMessageCodeTopicOption000 = 17000, // I-FCM017000 + kFIRMessagingMessageCodeTopicOption001 = 17001, // I-FCM017001 + kFIRMessagingMessageCodeTopicOption002 = 17002, // I-FCM017002 + kFIRMessagingMessageCodeTopicOptionTopicEncodingFailed = 17003, // I-FCM017003 + kFIRMessagingMessageCodeTopicOperationEmptyResponse = 17004, // I-FCM017004 + // FIRMessagingUtilities.m + kFIRMessagingMessageCodeUtilities000 = 18000, // I-FCM018000 + kFIRMessagingMessageCodeUtilities001 = 18001, // I-FCM018001 + kFIRMessagingMessageCodeUtilities002 = 18002, // I-FCM018002 + // FIRMessagingAnalytics.m + kFIRMessagingMessageCodeAnalytics000 = 19000, // I-FCM019000 + kFIRMessagingMessageCodeAnalytics001 = 19001, // I-FCM019001 + kFIRMessagingMessageCodeAnalytics002 = 19002, // I-FCM019002 + kFIRMessagingMessageCodeAnalytics003 = 19003, // I-FCM019003 + kFIRMessagingMessageCodeAnalytics004 = 19004, // I-FCM019004 + kFIRMessagingMessageCodeAnalytics005 = 19005, // I-FCM019005 + kFIRMessagingMessageCodeAnalyticsInvalidEvent = 19006, // I-FCM019006 + kFIRMessagingMessageCodeAnalytics007 = 19007, // I-FCM019007 + kFIRMessagingMessageCodeAnalyticsCouldNotInvokeAnalyticsLog = 19008, // I-FCM019008 +}; diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessaging.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessaging.m new file mode 100644 index 00000000..eb6f71b1 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessaging.m @@ -0,0 +1,1233 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#if !__has_feature(objc_arc) +#error FIRMessagingLib should be compiled with ARC. +#endif + +#import "FIRMessaging.h" +#import "FIRMessaging_Private.h" + +#import + +#import "FIRMessagingAnalytics.h" +#import "FIRMessagingClient.h" +#import "FIRMessagingConstants.h" +#import "FIRMessagingContextManagerService.h" +#import "FIRMessagingDataMessageManager.h" +#import "FIRMessagingDefines.h" +#import "FIRMessagingLogger.h" +#import "FIRMessagingPubSub.h" +#import "FIRMessagingReceiver.h" +#import "FIRMessagingRemoteNotificationsProxy.h" +#import "FIRMessagingRmqManager.h" +#import "FIRMessagingSyncMessageManager.h" +#import "FIRMessagingUtilities.h" +#import "FIRMessagingVersionUtilities.h" +#import "FIRMessaging_Private.h" + +#import +#import +#import +#import +#import +#import +#import +#import +#import + +#import "NSError+FIRMessaging.h" + +static NSString *const kFIRMessagingMessageViaAPNSRootKey = @"aps"; +static NSString *const kFIRMessagingReachabilityHostname = @"www.google.com"; +static NSString *const kFIRMessagingDefaultTokenScope = @"*"; +static NSString *const kFIRMessagingFCMTokenFetchAPNSOption = @"apns_token"; + +#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 +const NSNotificationName FIRMessagingSendSuccessNotification = + @"com.firebase.messaging.notif.send-success"; +const NSNotificationName FIRMessagingSendErrorNotification = + @"com.firebase.messaging.notif.send-error"; +const NSNotificationName FIRMessagingMessagesDeletedNotification = + @"com.firebase.messaging.notif.messages-deleted"; +const NSNotificationName FIRMessagingConnectionStateChangedNotification = + @"com.firebase.messaging.notif.connection-state-changed"; +const NSNotificationName FIRMessagingRegistrationTokenRefreshedNotification = + @"com.firebase.messaging.notif.fcm-token-refreshed"; +#else +NSString *const FIRMessagingSendSuccessNotification = + @"com.firebase.messaging.notif.send-success"; +NSString *const FIRMessagingSendErrorNotification = + @"com.firebase.messaging.notif.send-error"; +NSString * const FIRMessagingMessagesDeletedNotification = + @"com.firebase.messaging.notif.messages-deleted"; +NSString * const FIRMessagingConnectionStateChangedNotification = + @"com.firebase.messaging.notif.connection-state-changed"; +NSString * const FIRMessagingRegistrationTokenRefreshedNotification = + @"com.firebase.messaging.notif.fcm-token-refreshed"; +#endif // defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 + +NSString *const kFIRMessagingUserDefaultsKeyAutoInitEnabled = + @"com.firebase.messaging.auto-init.enabled"; // Auto Init Enabled key stored in NSUserDefaults + +NSString *const kFIRMessagingAPNSTokenType = @"APNSTokenType"; // APNS Token type key stored in user info. + +NSString *const kFIRMessagingPlistAutoInitEnabled = + @"FirebaseMessagingAutoInitEnabled"; // Auto Init Enabled key stored in Info.plist + +@interface FIRMessagingMessageInfo () + +@property(nonatomic, readwrite, assign) FIRMessagingMessageStatus status; + +@end + +@implementation FIRMessagingMessageInfo + +- (instancetype)init { + FIRMessagingInvalidateInitializer(); +} + +- (instancetype)initWithStatus:(FIRMessagingMessageStatus)status { + self = [super init]; + if (self) { + _status = status; + } + return self; +} + +@end + +#pragma mark - for iOS 10 compatibility +@implementation FIRMessagingRemoteMessage + +- (instancetype)init { + self = [super init]; + if (self) { + _appData = [[NSMutableDictionary alloc] init]; + } + + return self; +} + +@end + +@interface FIRMessaging () + +// FIRApp properties +@property(nonatomic, readwrite, strong) NSData *apnsTokenData; +@property(nonatomic, readwrite, strong) NSString *defaultFcmToken; + +@property(nonatomic, readwrite, strong) FIRInstanceID *instanceID; + +@property(nonatomic, readwrite, assign) BOOL isClientSetup; + +@property(nonatomic, readwrite, strong) FIRMessagingClient *client; +@property(nonatomic, readwrite, strong) GULReachabilityChecker *reachability; +@property(nonatomic, readwrite, strong) FIRMessagingDataMessageManager *dataMessageManager; +@property(nonatomic, readwrite, strong) FIRMessagingPubSub *pubsub; +@property(nonatomic, readwrite, strong) FIRMessagingRmqManager *rmq2Manager; +@property(nonatomic, readwrite, strong) FIRMessagingReceiver *receiver; +@property(nonatomic, readwrite, strong) FIRMessagingSyncMessageManager *syncMessageManager; +@property(nonatomic, readwrite, strong) NSUserDefaults *messagingUserDefaults; + +/// Message ID's logged for analytics. This prevents us from logging the same message twice +/// which can happen if the user inadvertently calls `appDidReceiveMessage` along with us +/// calling it implicitly during swizzling. +@property(nonatomic, readwrite, strong) NSMutableSet *loggedMessageIDs; +@property(nonatomic, readwrite, strong) id _Nullable analytics; + +@end + +// Messaging doesn't provide any functionality to other components, +// so it provides a private, empty protocol that it conforms to and use it for registration. + +@protocol FIRMessagingInstanceProvider +@end + +@interface FIRMessaging () +@end + +@implementation FIRMessaging + +// File static to support InstanceID tests that call [FIRMessaging messaging] after +// [FIRMessaging messagingForTests]. +static FIRMessaging *sMessaging; + ++ (FIRMessaging *)messaging { + if (sMessaging != nil) { + return sMessaging; + } + FIRApp *defaultApp = [FIRApp defaultApp]; // Missing configure will be logged here. + id messaging = + FIR_COMPONENT(FIRMessagingInstanceProvider, defaultApp.container); + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + [(FIRMessaging *)messaging start]; + }); + sMessaging = (FIRMessaging *)messaging; + return sMessaging; +} + ++ (FIRMessaging *)messagingForTests { + sMessaging = [[FIRMessaging alloc] initWithAnalytics:nil + withInstanceID:[FIRInstanceID instanceID] + withUserDefaults:[NSUserDefaults standardUserDefaults]]; + [sMessaging start]; + return sMessaging; +} + +- (instancetype)initWithAnalytics:(nullable id)analytics + withInstanceID:(FIRInstanceID *)instanceID + withUserDefaults:(NSUserDefaults *)defaults { + self = [super init]; + if (self != nil) { + _loggedMessageIDs = [NSMutableSet set]; + _instanceID = instanceID; + _messagingUserDefaults = defaults; + _analytics = analytics; + } + return self; +} + +- (void)dealloc { + [self.reachability stop]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [self teardown]; +} + +#pragma mark - Config + ++ (void)load { + [FIRApp registerAsConfigurable:self]; + [FIRComponentContainer registerAsComponentRegistrant:self]; +} + ++ (nonnull NSArray *)componentsToRegister { + FIRDependency *analyticsDep = + [FIRDependency dependencyWithProtocol:@protocol(FIRAnalyticsInterop) isRequired:NO]; + FIRComponentCreationBlock creationBlock = + ^id _Nullable(FIRComponentContainer *container, BOOL *isCacheable) { + // Ensure it's cached so it returns the same instance every time messaging is called. + *isCacheable = YES; + id analytics = FIR_COMPONENT(FIRAnalyticsInterop, container); + return [[FIRMessaging alloc] initWithAnalytics:analytics + withInstanceID:[FIRInstanceID instanceID] + withUserDefaults:[NSUserDefaults standardUserDefaults]]; + }; + FIRComponent *messagingProvider = + [FIRComponent componentWithProtocol:@protocol(FIRMessagingInstanceProvider) + instantiationTiming:FIRInstantiationTimingLazy + dependencies:@[ analyticsDep ] + creationBlock:creationBlock]; + + return @[ messagingProvider ]; +} + ++ (void)configureWithApp:(FIRApp *)app { + if (!app.isDefaultApp) { + // Only configure for the default FIRApp. + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeFIRApp001, + @"Firebase Messaging only works with the default app."); + return; + } + [[FIRMessaging messaging] configureMessaging:app]; +} + +- (void)configureMessaging:(FIRApp *)app { + // Swizzle remote-notification-related methods (app delegate and UNUserNotificationCenter) + if ([FIRMessagingRemoteNotificationsProxy canSwizzleMethods]) { + NSString *docsURLString = @"https://firebase.google.com/docs/cloud-messaging/ios/client" + @"#method_swizzling_in_firebase_messaging"; + FIRMessagingLoggerNotice(kFIRMessagingMessageCodeFIRApp000, + @"FIRMessaging Remote Notifications proxy enabled, will swizzle " + @"remote notification receiver handlers. If you'd prefer to manually " + @"integrate Firebase Messaging, add \"%@\" to your Info.plist, " + @"and set it to NO. Follow the instructions at:\n%@\nto ensure " + @"proper integration.", + kFIRMessagingRemoteNotificationsProxyEnabledInfoPlistKey, + docsURLString); + [FIRMessagingRemoteNotificationsProxy swizzleMethods]; + } +} + +- (void)start { + // Print the library version for logging. + NSString *currentLibraryVersion = FIRMessagingCurrentLibraryVersion(); + FIRMessagingLoggerInfo(kFIRMessagingMessageCodeMessagingPrintLibraryVersion, + @"FIRMessaging library version %@", + currentLibraryVersion); + + [self setupReceiver]; + + NSString *hostname = kFIRMessagingReachabilityHostname; + self.reachability = [[GULReachabilityChecker alloc] initWithReachabilityDelegate:self + withHost:hostname]; + [self.reachability start]; + + [self setupApplicationSupportSubDirectory]; + // setup FIRMessaging objects + [self setupRmqManager]; + [self setupClient]; + [self setupSyncMessageManager]; + [self setupDataMessageManager]; + [self setupTopics]; + + self.isClientSetup = YES; + [self setupNotificationListeners]; +} + +- (void)setupApplicationSupportSubDirectory { + NSString *messagingSubDirectory = kFIRMessagingApplicationSupportSubDirectory; + if (![[self class] hasApplicationSupportSubDirectory:messagingSubDirectory]) { + [[self class] createApplicationSupportSubDirectory:messagingSubDirectory]; + } +} + +- (void)setupNotificationListeners { + // To prevent multiple notifications remove self as observer for all events. + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center removeObserver:self]; + + [center addObserver:self + selector:@selector(didReceiveDefaultInstanceIDToken:) + name:kFIRMessagingFCMTokenNotification + object:nil]; + [center addObserver:self + selector:@selector(defaultInstanceIDTokenWasRefreshed:) + name:kFIRMessagingRegistrationTokenRefreshNotification + object:nil]; + [center addObserver:self + selector:@selector(applicationStateChanged) + name:UIApplicationDidBecomeActiveNotification + object:nil]; + [center addObserver:self + selector:@selector(applicationStateChanged) + name:UIApplicationDidEnterBackgroundNotification + object:nil]; +} + +- (void)setupReceiver { + self.receiver = [[FIRMessagingReceiver alloc] init]; + self.receiver.delegate = self; +} + +- (void)setupClient { + self.client = [[FIRMessagingClient alloc] initWithDelegate:self + reachability:self.reachability + rmq2Manager:self.rmq2Manager]; +} + +- (void)setupDataMessageManager { + self.dataMessageManager = + [[FIRMessagingDataMessageManager alloc] initWithDelegate:self.receiver + client:self.client + rmq2Manager:self.rmq2Manager + syncMessageManager:self.syncMessageManager]; + + [self.dataMessageManager refreshDelayedMessages]; + [self.client setDataMessageManager:self.dataMessageManager]; +} + +- (void)setupRmqManager { + self.rmq2Manager = [[FIRMessagingRmqManager alloc] initWithDatabaseName:@"rmq2"]; + [self.rmq2Manager loadRmqId]; +} + +- (void)setupTopics { + _FIRMessagingDevAssert(self.client, @"Invalid nil client before init pubsub."); + self.pubsub = [[FIRMessagingPubSub alloc] initWithClient:self.client]; +} + +- (void)setupSyncMessageManager { + self.syncMessageManager = + [[FIRMessagingSyncMessageManager alloc] initWithRmqManager:self.rmq2Manager]; + + // Delete the expired messages with a delay. We don't want to block startup with a somewhat + // expensive db call. + FIRMessaging_WEAKIFY(self); + dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)); + dispatch_after(time, dispatch_get_main_queue(), ^{ + FIRMessaging_STRONGIFY(self); + [self.syncMessageManager removeExpiredSyncMessages]; + }); +} + +- (void)teardown { + _FIRMessagingDevAssert([NSThread isMainThread], + @"FIRMessaging should be called from main thread only."); + [self.client teardown]; + self.pubsub = nil; + self.syncMessageManager = nil; + self.rmq2Manager = nil; + self.dataMessageManager = nil; + self.client = nil; + self.isClientSetup = NO; + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeMessaging001, @"Did successfully teardown"); +} + +#pragma mark - Messages + +- (FIRMessagingMessageInfo *)appDidReceiveMessage:(NSDictionary *)message { + if (!message.count) { + return [[FIRMessagingMessageInfo alloc] initWithStatus:FIRMessagingMessageStatusUnknown]; + } + + // For downstream messages that go via MCS we should strip out this key before sending + // the message to the device. + BOOL isOldMessage = NO; + NSString *messageID = message[kFIRMessagingMessageIDKey]; + if ([messageID length]) { + [self.rmq2Manager saveS2dMessageWithRmqId:messageID]; + + BOOL isSyncMessage = [[self class] isAPNSSyncMessage:message]; + if (isSyncMessage) { + isOldMessage = [self.syncMessageManager didReceiveAPNSSyncMessage:message]; + } + } + // Prevent duplicates by keeping a cache of all the logged messages during each session. + // The duplicates only happen when the 3P app calls `appDidReceiveMessage:` along with + // us swizzling their implementation to call the same method implicitly. + if (!isOldMessage && messageID.length) { + isOldMessage = [self.loggedMessageIDs containsObject:messageID]; + if (!isOldMessage) { + [self.loggedMessageIDs addObject:messageID]; + } + } + + if (!isOldMessage) { + [FIRMessagingAnalytics logMessage:message toAnalytics:_analytics]; + [self handleContextManagerMessage:message]; + [self handleIncomingLinkIfNeededFromMessage:message]; + } + return [[FIRMessagingMessageInfo alloc] initWithStatus:FIRMessagingMessageStatusNew]; +} + +- (BOOL)handleContextManagerMessage:(NSDictionary *)message { + if ([FIRMessagingContextManagerService isContextManagerMessage:message]) { + return [FIRMessagingContextManagerService handleContextManagerMessage:message]; + } + return NO; +} + ++ (BOOL)isAPNSSyncMessage:(NSDictionary *)message { + if ([message[kFIRMessagingMessageViaAPNSRootKey] isKindOfClass:[NSDictionary class]]) { + NSDictionary *aps = message[kFIRMessagingMessageViaAPNSRootKey]; + return [aps[kFIRMessagingMessageAPNSContentAvailableKey] boolValue]; + } + return NO; +} + +- (void)handleIncomingLinkIfNeededFromMessage:(NSDictionary *)message { + NSURL *url = [self linkURLFromMessage:message]; + if (url == nil) { + return; + } + if (![NSThread isMainThread]) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self handleIncomingLinkIfNeededFromMessage:message]; + + }); + return; + } + UIApplication *application = FIRMessagingUIApplication(); + if (!application) { + return; + } + id appDelegate = application.delegate; + SEL continueUserActivitySelector = + @selector(application:continueUserActivity:restorationHandler:); + SEL openURLWithOptionsSelector = @selector(application:openURL:options:); + SEL openURLWithSourceApplicationSelector = + @selector(application:openURL:sourceApplication:annotation:); + SEL handleOpenURLSelector = @selector(application:handleOpenURL:); + // Due to FIRAAppDelegateProxy swizzling, this selector will most likely get chosen, whether or + // not the actual application has implemented + // |application:continueUserActivity:restorationHandler:|. A warning will be displayed to the user + // if they haven't implemented it. + if ([NSUserActivity class] != nil && + [appDelegate respondsToSelector:continueUserActivitySelector]) { + NSUserActivity *userActivity = + [[NSUserActivity alloc] initWithActivityType:NSUserActivityTypeBrowsingWeb]; + userActivity.webpageURL = url; + [appDelegate application:application + continueUserActivity:userActivity + restorationHandler:^(NSArray * _Nullable restorableObjects) { + // Do nothing, as we don't support the app calling this block + }]; + + } else if ([appDelegate respondsToSelector:openURLWithOptionsSelector]) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability" + [appDelegate application:application openURL:url options:@{}]; +#pragma clang diagnostic pop + + // Similarly, |application:openURL:sourceApplication:annotation:| will also always be called, due + // to the default swizzling done by FIRAAppDelegateProxy in Firebase Analytics + } else if ([appDelegate respondsToSelector:openURLWithSourceApplicationSelector]) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [appDelegate application:application + openURL:url + sourceApplication:FIRMessagingAppIdentifier() + annotation:@{}]; + } else if ([appDelegate respondsToSelector:handleOpenURLSelector]) { + [appDelegate application:application handleOpenURL:url]; +#pragma clang diagnostic pop + } +} + +- (NSURL *)linkURLFromMessage:(NSDictionary *)message { + NSString *urlString = message[kFIRMessagingMessageLinkKey]; + if (urlString == nil || ![urlString isKindOfClass:[NSString class]] || urlString.length == 0) { + return nil; + } + NSURL *url = [NSURL URLWithString:urlString]; + return url; +} + +#pragma mark - APNS + +- (NSData *)APNSToken { + return self.apnsTokenData; +} + +- (void)setAPNSToken:(NSData *)APNSToken { + [self setAPNSToken:APNSToken type:FIRMessagingAPNSTokenTypeUnknown]; +} + +- (void)setAPNSToken:(NSData *)apnsToken type:(FIRMessagingAPNSTokenType)type { + if ([apnsToken isEqual:self.apnsTokenData]) { + return; + } + self.apnsTokenData = apnsToken; + + // Notify InstanceID that APNS Token has been set. + NSDictionary *userInfo = @{kFIRMessagingAPNSTokenType : @(type)}; + NSNotification *notification = + [NSNotification notificationWithName:kFIRMessagingAPNSTokenNotification + object:[apnsToken copy] + userInfo:userInfo]; + [[NSNotificationQueue defaultQueue] enqueueNotification:notification postingStyle:NSPostASAP]; +} + +#pragma mark - FCM + +- (BOOL)isAutoInitEnabled { + // Check storage + id isAutoInitEnabledObject = + [_messagingUserDefaults objectForKey:kFIRMessagingUserDefaultsKeyAutoInitEnabled]; + if (isAutoInitEnabledObject) { + return [isAutoInitEnabledObject boolValue]; + } + + // Check Info.plist + isAutoInitEnabledObject = + [[NSBundle mainBundle] objectForInfoDictionaryKey:kFIRMessagingPlistAutoInitEnabled]; + if (isAutoInitEnabledObject) { + return [isAutoInitEnabledObject boolValue]; + } + + // If none of above exists, we default to the global switch that comes from FIRApp. + return [[FIRApp defaultApp] isDataCollectionDefaultEnabled]; +} + +- (void)setAutoInitEnabled:(BOOL)autoInitEnabled { + BOOL isFCMAutoInitEnabled = [self isAutoInitEnabled]; + [_messagingUserDefaults setBool:autoInitEnabled + forKey:kFIRMessagingUserDefaultsKeyAutoInitEnabled]; + [_messagingUserDefaults synchronize]; + if (!isFCMAutoInitEnabled && autoInitEnabled) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + self.defaultFcmToken = self.instanceID.token; +#pragma clang diagnostic pop + } +} + +- (NSString *)FCMToken { + NSString *token = self.defaultFcmToken; + if (!token) { + // We may not have received it from Instance ID yet (via NSNotification), so extract it directly +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + token = self.instanceID.token; +#pragma clang diagnostic pop + } + return token; +} + +- (void)retrieveFCMTokenForSenderID:(nonnull NSString *)senderID + completion:(nonnull FIRMessagingFCMTokenFetchCompletion)completion { + if (!senderID.length) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeSenderIDNotSuppliedForTokenFetch, + @"Sender ID not supplied. It is required for a token fetch, " + @"to identify the sender."); + if (completion) { + NSString *description = @"Couldn't fetch token because a Sender ID was not supplied. A valid " + @"Sender ID is required to fetch an FCM token"; + NSError *error = [NSError fcm_errorWithCode:FIRMessagingErrorInvalidRequest + userInfo:@{NSLocalizedDescriptionKey : description}]; + completion(nil, error); + } + return; + } + NSDictionary *options = nil; + if (self.APNSToken) { + options = @{kFIRMessagingFCMTokenFetchAPNSOption : self.APNSToken}; + } else { + FIRMessagingLoggerWarn(kFIRMessagingMessageCodeAPNSTokenNotAvailableDuringTokenFetch, + @"APNS device token not set before retrieving FCM Token for Sender ID " + @"'%@'. Notifications to this FCM Token will not be delivered over APNS." + @"Be sure to re-retrieve the FCM token once the APNS device token is " + @"set.", senderID); + } + [self.instanceID tokenWithAuthorizedEntity:senderID + scope:kFIRMessagingDefaultTokenScope + options:options + handler:completion]; +} + +- (void)deleteFCMTokenForSenderID:(nonnull NSString *)senderID + completion:(nonnull FIRMessagingDeleteFCMTokenCompletion)completion { + if (!senderID.length) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeSenderIDNotSuppliedForTokenDelete, + @"Sender ID not supplied. It is required to delete an FCM token."); + if (completion) { + NSString *description = @"Couldn't delete token because a Sender ID was not supplied. A " + @"valid Sender ID is required to delete an FCM token"; + NSError *error = [NSError fcm_errorWithCode:FIRMessagingErrorInvalidRequest + userInfo:@{NSLocalizedDescriptionKey : description}]; + completion(error); + } + return; + } + [self.instanceID deleteTokenWithAuthorizedEntity:senderID + scope:kFIRMessagingDefaultTokenScope + handler:completion]; +} + +#pragma mark - FIRMessagingDelegate helper methods +- (void)setDelegate:(id)delegate { + _delegate = delegate; + [self validateDelegateConformsToTokenAvailabilityMethods]; +} + +// Check if the delegate conforms to |didReceiveRegistrationToken:| +// and display a warning to the developer if not. +// NOTE: Once |didReceiveRegistrationToken:| can be made a required method, this +// check can be removed. +- (void)validateDelegateConformsToTokenAvailabilityMethods { + if (self.delegate && + ![self.delegate respondsToSelector:@selector(messaging:didReceiveRegistrationToken:)]) { + FIRMessagingLoggerWarn(kFIRMessagingMessageCodeTokenDelegateMethodsNotImplemented, + @"The object %@ does not respond to " + @"-messaging:didReceiveRegistrationToken:. Please implement " + @"-messaging:didReceiveRegistrationToken: to be provided with an FCM " + @"token.", self.delegate.description); + } +} + +- (void)notifyDelegateOfFCMTokenAvailability { + __weak FIRMessaging *weakSelf = self; + if (![NSThread isMainThread]) { + dispatch_async(dispatch_get_main_queue(), ^{ + [weakSelf notifyDelegateOfFCMTokenAvailability]; + }); + return; + } + if ([self.delegate respondsToSelector:@selector(messaging:didReceiveRegistrationToken:)]) { + [self.delegate messaging:self didReceiveRegistrationToken:self.defaultFcmToken]; + } +} + + +- (void)setUseMessagingDelegateForDirectChannel:(BOOL)useMessagingDelegateForDirectChannel { + self.receiver.useDirectChannel = useMessagingDelegateForDirectChannel; +} + +- (BOOL)useMessagingDelegateForDirectChannel { + return self.receiver.useDirectChannel; +} + +#pragma mark - Application State Changes + +- (void)applicationStateChanged { + if (self.shouldEstablishDirectChannel) { + [self updateAutomaticClientConnection]; + } +} + +#pragma mark - Direct Channel + +- (void)setShouldEstablishDirectChannel:(BOOL)shouldEstablishDirectChannel { + if (_shouldEstablishDirectChannel == shouldEstablishDirectChannel) { + return; + } + _shouldEstablishDirectChannel = shouldEstablishDirectChannel; + [self updateAutomaticClientConnection]; +} + +- (BOOL)isDirectChannelEstablished { + return self.client.isConnectionActive; +} + +- (BOOL)shouldBeConnectedAutomatically { + // We require a token from Instance ID + NSString *token = self.defaultFcmToken; + // Only on foreground connections + UIApplication *application = FIRMessagingUIApplication(); + if (!application) { + return NO; + } + UIApplicationState applicationState = application.applicationState; + BOOL shouldBeConnected = _shouldEstablishDirectChannel && + (token.length > 0) && + applicationState == UIApplicationStateActive; + return shouldBeConnected; +} + +- (void)updateAutomaticClientConnection { + if (![NSThread isMainThread]) { + // Call this method from the main thread + dispatch_async(dispatch_get_main_queue(), ^{ + [self updateAutomaticClientConnection]; + }); + return; + } + BOOL shouldBeConnected = [self shouldBeConnectedAutomatically]; + if (shouldBeConnected && !self.client.isConnected) { + [self.client connectWithHandler:^(NSError *error) { + if (!error) { + // It means we connected. Fire connection change notification + [self notifyOfDirectChannelConnectionChange]; + } + }]; + } else if (!shouldBeConnected && self.client.isConnected) { + [self.client disconnect]; + [self notifyOfDirectChannelConnectionChange]; + } +} + +- (void)notifyOfDirectChannelConnectionChange { + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center postNotificationName:FIRMessagingConnectionStateChangedNotification object:self]; +} + +#pragma mark - Connect + +- (void)connectWithCompletion:(FIRMessagingConnectCompletion)handler { + _FIRMessagingDevAssert([NSThread isMainThread], + @"FIRMessaging connect should be called from main thread only."); + _FIRMessagingDevAssert(self.isClientSetup, @"FIRMessaging client not setup."); + [self.client connectWithHandler:^(NSError *error) { + if (handler) { + handler(error); + } + if (!error) { + // It means we connected. Fire connection change notification + [self notifyOfDirectChannelConnectionChange]; + } + }]; + +} + +- (void)disconnect { + _FIRMessagingDevAssert([NSThread isMainThread], + @"FIRMessaging should be called from main thread only."); + if ([self.client isConnected]) { + [self.client disconnect]; + [self notifyOfDirectChannelConnectionChange]; + } +} + +#pragma mark - Topics + ++ (NSString *)normalizeTopic:(NSString *)topic { + if (!topic.length) { + return nil; + } + if (![FIRMessagingPubSub hasTopicsPrefix:topic]) { + topic = [FIRMessagingPubSub addPrefixToTopic:topic]; + } + if ([FIRMessagingPubSub isValidTopicWithPrefix:topic]) { + return [topic copy]; + } + return nil; +} + +- (void)subscribeToTopic:(NSString *)topic { + [self subscribeToTopic:topic completion:nil]; +} + +- (void)subscribeToTopic:(NSString *)topic + completion:(nullable FIRMessagingTopicOperationCompletion)completion { + if ([FIRMessagingPubSub hasTopicsPrefix:topic]) { + FIRMessagingLoggerWarn(kFIRMessagingMessageCodeTopicFormatIsDeprecated, + @"Format '%@' is deprecated. Only '%@' should be used in " + @"subscribeToTopic.", + topic, [FIRMessagingPubSub removePrefixFromTopic:topic]); + } + if (!self.defaultFcmToken.length) { + FIRMessagingLoggerWarn(kFIRMessagingMessageCodeMessaging010, + @"The subscription operation is suspended because you don't have a " + @"token. The operation will resume once you get an FCM token."); + } + NSString *normalizeTopic = [[self class] normalizeTopic:topic]; + if (normalizeTopic.length) { + [self.pubsub subscribeToTopic:normalizeTopic handler:completion]; + return; + } + FIRMessagingLoggerError(kFIRMessagingMessageCodeMessaging009, + @"Cannot parse topic name %@. Will not subscribe.", topic); + if (completion) { + completion([NSError fcm_errorWithCode:FIRMessagingErrorInvalidTopicName userInfo:nil]); + } +} + +- (void)unsubscribeFromTopic:(NSString *)topic { + [self unsubscribeFromTopic:topic completion:nil]; +} + +- (void)unsubscribeFromTopic:(NSString *)topic + completion:(nullable FIRMessagingTopicOperationCompletion)completion { + if ([FIRMessagingPubSub hasTopicsPrefix:topic]) { + FIRMessagingLoggerWarn(kFIRMessagingMessageCodeTopicFormatIsDeprecated, + @"Format '%@' is deprecated. Only '%@' should be used in " + @"unsubscribeFromTopic.", + topic, [FIRMessagingPubSub removePrefixFromTopic:topic]); + } + if (!self.defaultFcmToken.length) { + FIRMessagingLoggerWarn(kFIRMessagingMessageCodeMessaging012, + @"The unsubscription operation is suspended because you don't have a " + @"token. The operation will resume once you get an FCM token."); + } + NSString *normalizeTopic = [[self class] normalizeTopic:topic]; + if (normalizeTopic.length) { + [self.pubsub unsubscribeFromTopic:normalizeTopic handler:completion]; + return; + } + FIRMessagingLoggerError(kFIRMessagingMessageCodeMessaging011, + @"Cannot parse topic name %@. Will not unsubscribe.", topic); + if (completion) { + completion([NSError fcm_errorWithCode:FIRMessagingErrorInvalidTopicName userInfo:nil]); + } +} + +#pragma mark - Send + +- (void)sendMessage:(NSDictionary *)message + to:(NSString *)to + withMessageID:(NSString *)messageID + timeToLive:(int64_t)ttl { + _FIRMessagingDevAssert([to length] != 0, @"Invalid receiver id for FIRMessaging-message"); + + NSMutableDictionary *fcmMessage = [[self class] createFIRMessagingMessageWithMessage:message + to:to + withID:messageID + timeToLive:ttl + delay:0]; + FIRMessagingLoggerInfo(kFIRMessagingMessageCodeMessaging013, @"Sending message: %@ with id: %@", + message, messageID); + [self.dataMessageManager sendDataMessageStanza:fcmMessage]; +} + ++ (NSMutableDictionary *)createFIRMessagingMessageWithMessage:(NSDictionary *)message + to:(NSString *)to + withID:(NSString *)msgID + timeToLive:(int64_t)ttl + delay:(int)delay { + NSMutableDictionary *fcmMessage = [NSMutableDictionary dictionary]; + fcmMessage[kFIRMessagingSendTo] = [to copy]; + fcmMessage[kFIRMessagingSendMessageID] = msgID ? [msgID copy] : @""; + fcmMessage[kFIRMessagingSendTTL] = @(ttl); + fcmMessage[kFIRMessagingSendDelay] = @(delay); + fcmMessage[KFIRMessagingSendMessageAppData] = + [NSMutableDictionary dictionaryWithDictionary:message]; + return fcmMessage; +} + +#pragma mark - IID dependencies + ++ (NSString *)FIRMessagingSDKVersion { + return FIRMessagingCurrentLibraryVersion(); +} + ++ (NSString *)FIRMessagingSDKCurrentLocale { + return [self currentLocale]; +} + +#pragma mark - FIRMessagingReceiverDelegate + +- (void)receiver:(FIRMessagingReceiver *)receiver + receivedRemoteMessage:(FIRMessagingRemoteMessage *)remoteMessage { + if ([self.delegate respondsToSelector:@selector(messaging:didReceiveMessage:)]) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability" + [self.delegate messaging:self didReceiveMessage:remoteMessage]; +#pragma pop + } else { + // Delegate methods weren't implemented, so messages are being dropped, log a warning + FIRMessagingLoggerWarn(kFIRMessagingMessageCodeRemoteMessageDelegateMethodNotImplemented, + @"FIRMessaging received data-message, but FIRMessagingDelegate's" + @"-messaging:didReceiveMessage: not implemented"); + } +} + +#pragma mark - GULReachabilityDelegate + +- (void)reachability:(GULReachabilityChecker *)reachability + statusChanged:(GULReachabilityStatus)status { + [self onNetworkStatusChanged]; +} + +#pragma mark - Network + +- (void)onNetworkStatusChanged { + if (![self.client isConnected] && [self isNetworkAvailable]) { + if (self.client.shouldStayConnected) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeMessaging014, + @"Attempting to establish direct channel."); + [self.client retryConnectionImmediately:YES]; + } + [self.pubsub scheduleSync:YES]; + } +} + +- (BOOL)isNetworkAvailable { + GULReachabilityStatus status = self.reachability.reachabilityStatus; + return (status == kGULReachabilityViaCellular || status == kGULReachabilityViaWifi); +} + +- (FIRMessagingNetworkStatus)networkType { + GULReachabilityStatus status = self.reachability.reachabilityStatus; + if (![self isNetworkAvailable]) { + return kFIRMessagingReachabilityNotReachable; + } else if (status == kGULReachabilityViaCellular) { + return kFIRMessagingReachabilityReachableViaWWAN; + } else { + return kFIRMessagingReachabilityReachableViaWiFi; + } +} + +#pragma mark - Notifications + +- (void)didReceiveDefaultInstanceIDToken:(NSNotification *)notification { + if (notification.object && ![notification.object isKindOfClass:[NSString class]]) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeMessaging015, + @"Invalid default FCM token type %@", + NSStringFromClass([notification.object class])); + return; + } + NSString *oldToken = self.defaultFcmToken; + self.defaultFcmToken = [(NSString *)notification.object copy]; + if (self.defaultFcmToken && ![self.defaultFcmToken isEqualToString:oldToken]) { + [self notifyDelegateOfFCMTokenAvailability]; + } + [self.pubsub scheduleSync:YES]; + if (self.shouldEstablishDirectChannel) { + [self updateAutomaticClientConnection]; + } +} + +- (void)defaultInstanceIDTokenWasRefreshed:(NSNotification *)notification { + // Retrieve the Instance ID default token, and if it is non-nil, post it +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + NSString *token = self.instanceID.token; +#pragma clang diagnostic pop + // Sometimes Instance ID doesn't yet have a token, so wait until the default + // token is fetched, and then notify. This ensures that this token should not + // be nil when the developer accesses it. + if (token != nil) { + NSString *oldToken = self.defaultFcmToken; + self.defaultFcmToken = [token copy]; + if (self.defaultFcmToken && ![self.defaultFcmToken isEqualToString:oldToken]) { + [self notifyDelegateOfFCMTokenAvailability]; + } + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center postNotificationName:FIRMessagingRegistrationTokenRefreshedNotification object:nil]; + } +} + +#pragma mark - Application Support Directory + ++ (BOOL)hasApplicationSupportSubDirectory:(NSString *)subDirectoryName { + NSString *subDirectoryPath = [self pathForApplicationSupportSubDirectory:subDirectoryName]; + BOOL isDirectory; + if (![[NSFileManager defaultManager] fileExistsAtPath:subDirectoryPath + isDirectory:&isDirectory]) { + return NO; + } else if (!isDirectory) { + return NO; + } + return YES; +} + ++ (NSString *)pathForApplicationSupportSubDirectory:(NSString *)subDirectoryName { + NSArray *directoryPaths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, + NSUserDomainMask, YES); + NSString *applicationSupportDirPath = directoryPaths.lastObject; + NSArray *components = @[applicationSupportDirPath, subDirectoryName]; + return [NSString pathWithComponents:components]; +} + ++ (BOOL)createApplicationSupportSubDirectory:(NSString *)subDirectoryName { + NSString *subDirectoryPath = [self pathForApplicationSupportSubDirectory:subDirectoryName]; + BOOL hasSubDirectory; + + if (![[NSFileManager defaultManager] fileExistsAtPath:subDirectoryPath + isDirectory:&hasSubDirectory]) { + NSError *error; + [[NSFileManager defaultManager] createDirectoryAtPath:subDirectoryPath + withIntermediateDirectories:YES + attributes:nil + error:&error]; + if (error) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeMessaging017, + @"Cannot create directory %@, error: %@", subDirectoryPath, error); + return NO; + } + } else { + if (!hasSubDirectory) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeMessaging018, + @"Found file instead of directory at %@", subDirectoryPath); + return NO; + } + } + return YES; +} + +#pragma mark - Locales + ++ (NSString *)currentLocale { + NSArray *locales = [self firebaseLocales]; + NSArray *preferredLocalizations = + [NSBundle preferredLocalizationsFromArray:locales + forPreferences:[NSLocale preferredLanguages]]; + NSString *legalDocsLanguage = [preferredLocalizations firstObject]; + // Use en as the default language + return legalDocsLanguage ? legalDocsLanguage : @"en"; +} + ++ (NSArray *)firebaseLocales { + NSMutableArray *locales = [NSMutableArray array]; + NSDictionary *localesMap = [self firebaselocalesMap]; + for (NSString *key in localesMap) { + [locales addObjectsFromArray:localesMap[key]]; + } + return locales; +} + ++ (NSDictionary *)firebaselocalesMap { + return @{ + // Albanian + @"sq" : @[ @"sq_AL" ], + // Belarusian + @"be" : @[ @"be_BY" ], + // Bulgarian + @"bg" : @[ @"bg_BG" ], + // Catalan + @"ca" : @[ @"ca", @"ca_ES" ], + // Croatian + @"hr" : @[ @"hr", @"hr_HR" ], + // Czech + @"cs" : @[ @"cs", @"cs_CZ" ], + // Danish + @"da" : @[ @"da", @"da_DK" ], + // Estonian + @"et" : @[ @"et_EE" ], + // Finnish + @"fi" : @[ @"fi", @"fi_FI" ], + // Hebrew + @"he" : @[ @"he", @"iw_IL" ], + // Hindi + @"hi" : @[ @"hi_IN" ], + // Hungarian + @"hu" : @[ @"hu", @"hu_HU" ], + // Icelandic + @"is" : @[ @"is_IS" ], + // Indonesian + @"id" : @[ @"id", @"in_ID", @"id_ID" ], + // Irish + @"ga" : @[ @"ga_IE" ], + // Korean + @"ko" : @[ @"ko", @"ko_KR", @"ko-KR" ], + // Latvian + @"lv" : @[ @"lv_LV" ], + // Lithuanian + @"lt" : @[ @"lt_LT" ], + // Macedonian + @"mk" : @[ @"mk_MK" ], + // Malay + @"ms" : @[ @"ms_MY" ], + // Maltese + @"ms" : @[ @"mt_MT" ], + // Polish + @"pl" : @[ @"pl", @"pl_PL", @"pl-PL" ], + // Romanian + @"ro" : @[ @"ro", @"ro_RO" ], + // Russian + @"ru" : @[ @"ru_RU", @"ru", @"ru_BY", @"ru_KZ", @"ru-RU" ], + // Slovak + @"sk" : @[ @"sk", @"sk_SK" ], + // Slovenian + @"sl" : @[ @"sl_SI" ], + // Swedish + @"sv" : @[ @"sv", @"sv_SE", @"sv-SE" ], + // Turkish + @"tr" : @[ @"tr", @"tr-TR", @"tr_TR" ], + // Ukrainian + @"uk" : @[ @"uk", @"uk_UA" ], + // Vietnamese + @"vi" : @[ @"vi", @"vi_VN" ], + // The following are groups of locales or locales that sub-divide a + // language). + // Arabic + @"ar" : @[ + @"ar", + @"ar_DZ", + @"ar_BH", + @"ar_EG", + @"ar_IQ", + @"ar_JO", + @"ar_KW", + @"ar_LB", + @"ar_LY", + @"ar_MA", + @"ar_OM", + @"ar_QA", + @"ar_SA", + @"ar_SD", + @"ar_SY", + @"ar_TN", + @"ar_AE", + @"ar_YE", + @"ar_GB", + @"ar-IQ", + @"ar_US" + ], + // Simplified Chinese + @"zh_Hans" : @[ @"zh_CN", @"zh_SG", @"zh-Hans" ], + // Traditional Chinese + @"zh_Hant" : @[ @"zh_HK", @"zh_TW", @"zh-Hant", @"zh-HK", @"zh-TW" ], + // Dutch + @"nl" : @[ @"nl", @"nl_BE", @"nl_NL", @"nl-NL" ], + // English + @"en" : @[ + @"en", + @"en_AU", + @"en_CA", + @"en_IN", + @"en_IE", + @"en_MT", + @"en_NZ", + @"en_PH", + @"en_SG", + @"en_ZA", + @"en_GB", + @"en_US", + @"en_AE", + @"en-AE", + @"en_AS", + @"en-AU", + @"en_BD", + @"en-CA", + @"en_EG", + @"en_ES", + @"en_GB", + @"en-GB", + @"en_HK", + @"en_ID", + @"en-IN", + @"en_NG", + @"en-PH", + @"en_PK", + @"en-SG", + @"en-US" + ], + // French + + @"fr" : @[ + @"fr", + @"fr_BE", + @"fr_CA", + @"fr_FR", + @"fr_LU", + @"fr_CH", + @"fr-CA", + @"fr-FR", + @"fr_MA" + ], + // German + @"de" : @[ @"de", @"de_AT", @"de_DE", @"de_LU", @"de_CH", @"de-DE" ], + // Greek + @"el" : @[ @"el", @"el_CY", @"el_GR" ], + // Italian + @"it" : @[ @"it", @"it_IT", @"it_CH", @"it-IT" ], + // Japanese + @"ja" : @[ @"ja", @"ja_JP", @"ja_JP_JP", @"ja-JP" ], + // Norwegian + @"no" : @[ @"nb", @"no_NO", @"no_NO_NY", @"nb_NO" ], + // Brazilian Portuguese + @"pt_BR" : @[ @"pt_BR", @"pt-BR" ], + // European Portuguese + @"pt_PT" : @[ @"pt", @"pt_PT", @"pt-PT" ], + // Serbian + @"sr" : @[ + @"sr_BA", + @"sr_ME", + @"sr_RS", + @"sr_Latn_BA", + @"sr_Latn_ME", + @"sr_Latn_RS" + ], + // European Spanish + @"es_ES" : @[ @"es", @"es_ES", @"es-ES" ], + // Mexican Spanish + @"es_MX" : @[ @"es-MX", @"es_MX", @"es_US", @"es-US" ], + // Latin American Spanish + @"es_419" : @[ + @"es_AR", + @"es_BO", + @"es_CL", + @"es_CO", + @"es_CR", + @"es_DO", + @"es_EC", + @"es_SV", + @"es_GT", + @"es_HN", + @"es_NI", + @"es_PA", + @"es_PY", + @"es_PE", + @"es_PR", + @"es_UY", + @"es_VE", + @"es-AR", + @"es-CL", + @"es-CO" + ], + // Thai + @"th" : @[ @"th", @"th_TH", @"th_TH_TH" ], + }; +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingAnalytics.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingAnalytics.h new file mode 100644 index 00000000..13bfab5b --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingAnalytics.h @@ -0,0 +1,44 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Provides integration between FIRMessaging and Analytics. + * + * All Analytics dependencies should be kept in this class, and missing dependencies should be + * handled gracefully. + * + */ +@interface FIRMessagingAnalytics : NSObject + +/** + * Determine whether a notification has the properties to be loggable to Analytics. + * If so, send the notification. + * @param notification The notification payload from APNs + * @param analytics The class to be used as the receiver of the logging method + */ + ++ (void)logMessage:(NSDictionary *)notification + toAnalytics:(id _Nullable)analytics; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingAnalytics.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingAnalytics.m new file mode 100644 index 00000000..42124be7 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingAnalytics.m @@ -0,0 +1,225 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import "FIRMessagingAnalytics.h" +#import "FIRMessagingLogger.h" + +#import +#import +#import + +static NSString *const kLogTag = @"FIRMessagingAnalytics"; + +// aps Key +static NSString *const kApsKey = @"aps"; +static NSString *const kApsAlertKey = @"alert"; +static NSString *const kApsSoundKey = @"sound"; +static NSString *const kApsBadgeKey = @"badge"; +static NSString *const kApsContentAvailableKey = @"badge"; + +// Data Key +static NSString *const kDataKey = @"data"; + +// Messaging From Key +static NSString *const kFIRMessagingFromKey = @"from"; + +static NSString *const kFIRParameterLabel = @"label"; + +static NSString *const kReengagementSource = @"Firebase"; +static NSString *const kReengagementMedium = @"notification"; + +// Analytics +static NSString *const kAnalyticsEnabled = @"google.c.a." @"e"; +static NSString *const kAnalyticsComposerIdentifier = @"google.c.a." @"c_id"; +static NSString *const kAnalyticsComposerLabel = @"google.c.a." @"c_l"; +static NSString *const kAnalyticsMessageLabel = @"google.c.a." @"m_l"; +static NSString *const kAnalyticsMessageTimestamp = @"google.c.a." @"ts"; +static NSString *const kAnalyticsMessageUseDeviceTime = @"google.c.a." @"udt"; +static NSString *const kAnalyticsTrackConversions = @"google.c.a." @"tc"; + +@implementation FIRMessagingAnalytics + ++ (BOOL)canLogNotification:(NSDictionary *)notification { + if (!notification.count) { + // Payload is empty + return NO; + } + NSString *isAnalyticsLoggingEnabled = notification[kAnalyticsEnabled]; + if (![isAnalyticsLoggingEnabled isKindOfClass:[NSString class]] || + ![isAnalyticsLoggingEnabled isEqualToString:@"1"]) { + // Analytics logging is not enabled + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeAnalytics001, + @"Analytics logging is disabled. Do not log event."); + return NO; + } + return YES; +} + ++ (void)logOpenNotification:(NSDictionary *)notification + toAnalytics:(id _Nullable)analytics { + [self logUserPropertyForConversionTracking:notification toAnalytics:analytics]; + [self logEvent:kFIRIEventNotificationOpen +withNotification:notification + toAnalytics:analytics]; +} + ++ (void)logForegroundNotification:(NSDictionary *)notification + toAnalytics:(id _Nullable)analytics { + [self logEvent:kFIRIEventNotificationForeground +withNotification:notification + toAnalytics:analytics]; +} + ++ (void)logEvent:(NSString *)event +withNotification:(NSDictionary *)notification + toAnalytics:(id _Nullable)analytics { + if (!event.length) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeAnalyticsInvalidEvent, + @"Can't log analytics with empty event."); + return; + } + NSMutableDictionary *params = [self paramsForEvent:event withNotification:notification]; + + [analytics logEventWithOrigin:@"fcm" name:event parameters:params]; + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeAnalytics005, + @"%@: Sending event: %@ params: %@", kLogTag, event, params); +} + ++ (NSMutableDictionary *)paramsForEvent:(NSString *)event + withNotification:(NSDictionary *)notification { + NSDictionary *analyticsDataMap = notification; + if (!analyticsDataMap.count) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeAnalytics000, + @"No data found in notification. Will not log any analytics events."); + return nil; + } + + if (![self canLogNotification:analyticsDataMap]) { + return nil; + } + + NSMutableDictionary *params = [NSMutableDictionary dictionary]; + NSString *composerIdentifier = analyticsDataMap[kAnalyticsComposerIdentifier]; + if ([composerIdentifier isKindOfClass:[NSString class]] && composerIdentifier.length) { + params[kFIRIParameterMessageIdentifier] = [composerIdentifier copy]; + } + + NSString *composerLabel = analyticsDataMap[kAnalyticsComposerLabel]; + if ([composerLabel isKindOfClass:[NSString class]] && composerLabel.length) { + params[kFIRIParameterMessageName] = [composerLabel copy]; + } + + NSString *messageLabel = analyticsDataMap[kAnalyticsMessageLabel]; + if ([messageLabel isKindOfClass:[NSString class]] && messageLabel.length) { + params[kFIRParameterLabel] = [messageLabel copy]; + } + + NSString *from = analyticsDataMap[kFIRMessagingFromKey]; + if ([from isKindOfClass:[NSString class]] && [from containsString:@"/topics/"]) { + params[kFIRIParameterTopic] = [from copy]; + } + + id timestamp = analyticsDataMap[kAnalyticsMessageTimestamp]; + if ([timestamp respondsToSelector:@selector(longLongValue)]) { + int64_t timestampValue = [timestamp longLongValue]; + if (timestampValue != 0) { + params[kFIRIParameterMessageTime] = @(timestampValue); + } + } + + if (analyticsDataMap[kAnalyticsMessageUseDeviceTime]) { + params[kFIRIParameterMessageDeviceTime] = analyticsDataMap[kAnalyticsMessageUseDeviceTime]; + } + + return params; +} + ++ (void)logUserPropertyForConversionTracking:(NSDictionary *)notification + toAnalytics:(id _Nullable)analytics { + NSInteger shouldTrackConversions = [notification[kAnalyticsTrackConversions] integerValue]; + if (shouldTrackConversions != 1) { + return; + } + + NSString *composerIdentifier = notification[kAnalyticsComposerIdentifier]; + if ([composerIdentifier isKindOfClass:[NSString class]] && composerIdentifier.length) { + // Set user property for event. + [analytics setUserPropertyWithOrigin:@"fcm" + name:kFIRIUserPropertyLastNotification + value:composerIdentifier]; + + // Set the re-engagement attribution properties. + NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:3]; + params[kFIRIParameterSource] = kReengagementSource; + params[kFIRIParameterMedium] = kReengagementMedium; + params[kFIRIParameterCampaign] = composerIdentifier; + [analytics logEventWithOrigin:@"fcm" name:kFIRIEventFirebaseCampaign parameters:params]; + + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeAnalytics003, + @"%@: Sending event: %@ params: %@", kLogTag, + kFIRIEventFirebaseCampaign, params); + + } else { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeAnalytics004, + @"%@: Failed to set user property: %@ value: %@", kLogTag, + kFIRIUserPropertyLastNotification, composerIdentifier); + } +} + ++ (void)logMessage:(NSDictionary *)notification + toAnalytics:(id _Nullable)analytics { + if (![self canLogNotification:notification]) { + return; + } + + UIApplication *application = [self currentUIApplication]; + if (!application) { + return; + } + UIApplicationState applicationState = application.applicationState; + switch (applicationState) { + case UIApplicationStateInactive: + // App was either in background(suspended) or inactive and user tapped on a display + // notification. + [self logOpenNotification:notification toAnalytics:analytics]; + break; + + case UIApplicationStateActive: + // App was in foreground when it received the notification. + [self logForegroundNotification:notification toAnalytics:analytics]; + break; + + default: + // Only a silent notification (i.e. 'content-available' is true) can be received while the app + // is in the background. These messages aren't loggable anyway. + break; + } +} + ++ (UIApplication *)currentUIApplication { + Class applicationClass = nil; + if (![GULAppEnvironmentUtil isAppExtension]) { + Class cls = NSClassFromString(@"UIApplication"); + if (cls && [cls respondsToSelector:NSSelectorFromString(@"sharedApplication")]) { + applicationClass = cls; + } + } + return [applicationClass sharedApplication]; +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingCheckinService.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingCheckinService.h new file mode 100644 index 00000000..155143a5 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingCheckinService.h @@ -0,0 +1,53 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +/** + * Register the device with Checkin Service and get back the `authID`, `secret token` etc. for the + * client. Checkin results are cached in the `FIRMessagingDefaultsManager` and periodically refreshed to + * prevent them from being stale. Each client needs to register with checkin before registering + * with FIRMessaging. + */ +@interface FIRMessagingCheckinService : NSObject + +@property(nonatomic, readonly, strong) NSString *deviceAuthID; +@property(nonatomic, readonly, strong) NSString *secretToken; +@property(nonatomic, readonly, strong) NSString *versionInfo; +@property(nonatomic, readonly, assign) BOOL hasValidCheckinInfo; + +/** + * Verify if valid checkin preferences have been loaded in memory. + * + * @return YES if valid checkin preferences exist in memory else NO. + */ +- (BOOL)hasValidCheckinInfo; + +/** + * Try to load prefetched checkin preferences from the cache. This supports the use case where + * InstanceID library has already obtained a valid checkin and we should be using that. + * + * This should be used as a last gasp effort to retreive any cached checkin preferences before + * hitting the FIRMessaging backend to retrieve new preferences. + * + * Note this is only required because InstanceID and FIRMessaging both require checkin preferences which + * need to be synced with each other. + * + * @return YES if successfully loaded cached checkin preferences into memory else NO. + */ +- (BOOL)tryToLoadPrefetchedCheckinPreferences; + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingCheckinService.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingCheckinService.m new file mode 100644 index 00000000..9dad847c --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingCheckinService.m @@ -0,0 +1,132 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingCheckinService.h" + +#import "FIRMessagingUtilities.h" +#import "NSError+FIRMessaging.h" + +@interface FIRMessagingCheckinService () + +// This property is of type FIRInstanceIDCheckinPreferences, if InstanceID was directly linkable +@property(nonatomic, readwrite, strong) id checkinPreferences; + +@end + +@implementation FIRMessagingCheckinService; + +#pragma mark - Reflection-Based Getter Functions + +// Encapsulates the -hasValidCheckinInfo method of FIRInstanceIDCheckinPreferences +BOOL FIRMessagingCheckinService_hasValidCheckinInfo(id checkinPreferences) { + SEL hasValidCheckinInfoSelector = NSSelectorFromString(@"hasValidCheckinInfo"); + if (![checkinPreferences respondsToSelector:hasValidCheckinInfoSelector]) { + // Can't check hasValidCheckinInfo + return NO; + } + + // Since hasValidCheckinInfo returns a BOOL, use NSInvocation + NSMethodSignature *methodSignature = + [[checkinPreferences class] instanceMethodSignatureForSelector:hasValidCheckinInfoSelector]; + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; + invocation.selector = hasValidCheckinInfoSelector; + invocation.target = checkinPreferences; + [invocation invoke]; + BOOL returnValue; + [invocation getReturnValue:&returnValue]; + return returnValue; +} + +// Returns a non-scalar (id) object based on the property name +id FIRMessagingCheckinService_propertyNamed(id checkinPreferences, NSString *propertyName) { + SEL propertyGetterSelector = NSSelectorFromString(propertyName); + if ([checkinPreferences respondsToSelector:propertyGetterSelector]) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + return [checkinPreferences performSelector:propertyGetterSelector]; +#pragma clang diagnostic pop + } + return nil; +} + +#pragma mark - Methods + +- (BOOL)tryToLoadPrefetchedCheckinPreferences { + Class instanceIDClass = NSClassFromString(@"FIRInstanceID"); + if (!instanceIDClass) { + // InstanceID is not linked + return NO; + } + + // [FIRInstanceID instanceID] + SEL instanceIDSelector = NSSelectorFromString(@"instanceID"); + if (![instanceIDClass respondsToSelector:instanceIDSelector]) { + return NO; + } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + id instanceID = [instanceIDClass performSelector:instanceIDSelector]; +#pragma clang diagnostic pop + if (!instanceID) { + // Instance ID singleton not available + return NO; + } + + // [[FIRInstanceID instanceID] cachedCheckinPreferences] + SEL cachedCheckinPrefsSelector = NSSelectorFromString(@"cachedCheckinPreferences"); + if (![instanceID respondsToSelector:cachedCheckinPrefsSelector]) { + // cachedCheckinPreferences is not accessible + return NO; + } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + id checkinPreferences = [instanceID performSelector:cachedCheckinPrefsSelector]; +#pragma clang diagnostic pop + if (!checkinPreferences) { + // No cached checkin prefs + return NO; + } + + BOOL hasValidInfo = FIRMessagingCheckinService_hasValidCheckinInfo(checkinPreferences); + if (hasValidInfo) { + self.checkinPreferences = checkinPreferences; + } + return hasValidInfo; +} + +#pragma mark - API + +- (NSString *)deviceAuthID { + return FIRMessagingCheckinService_propertyNamed(self.checkinPreferences, @"deviceID"); +} + +- (NSString *)secretToken { + return FIRMessagingCheckinService_propertyNamed(self.checkinPreferences, @"secretToken"); +} + +- (NSString *)versionInfo { + return FIRMessagingCheckinService_propertyNamed(self.checkinPreferences, @"versionInfo"); +} + +- (NSString *)digest { + return FIRMessagingCheckinService_propertyNamed(self.checkinPreferences, @"digest"); +} + +- (BOOL)hasValidCheckinInfo { + return FIRMessagingCheckinService_hasValidCheckinInfo(self.checkinPreferences); +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingClient.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingClient.h new file mode 100644 index 00000000..98337a30 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingClient.h @@ -0,0 +1,156 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessaging.h" + +@class GULReachabilityChecker; +@class GPBMessage; + +@class FIRMessagingConnection; +@class FIRMessagingDataMessageManager; +@class FIRMessagingRmqManager; + +/** + * Callback to handle MCS connection requests. + * + * @param error The error object if any while trying to connect with MCS else nil. + */ +typedef void(^FIRMessagingConnectCompletionHandler)(NSError *error); + +@protocol FIRMessagingClientDelegate + +@end + +/** + * The client handles the subscribe/unsubscribe for an unregistered senderID + * and device. It also manages the FIRMessaging data connection, the exponential backoff + * algorithm in case of registration failures, sign in failures and unregister + * failures. It also handles the reconnect logic if the FIRMessaging connection is + * broken off by some error during an active session. + */ +@interface FIRMessagingClient : NSObject + +@property(nonatomic, readonly, strong) FIRMessagingConnection *connection; +@property(nonatomic, readwrite, weak) FIRMessagingDataMessageManager *dataMessageManager; + +// Designated initializer +- (instancetype)initWithDelegate:(id)delegate + reachability:(GULReachabilityChecker *)reachability + rmq2Manager:(FIRMessagingRmqManager *)rmq2Manager; + +- (void)teardown; + +- (void)cancelAllRequests; + +#pragma mark - FIRMessaging subscribe + +/** + * Update the subscription associated with the given token and topic. + * + * For a to-be-created subscription we check if the client is already + * subscribed to the topic or not. If subscribed we should have the + * subscriptionID in the cache and we return from there itself, else we call + * the FIRMessaging backend to create a new subscription for the topic for this client. + * + * For delete subscription requests we delete the stored subscription in the + * client and then invoke the FIRMessaging backend to delete the existing subscription + * completely. + * + * @param token The token associated with the device. + * @param topic The topic for which the subscription should be updated. + * @param options The options to be passed in to the subscription request. + * @param shouldDelete If YES this would delete the subscription from the cache + * and also let the FIRMessaging backend know that we need to delete + * the subscriptionID associated with this topic. + * If NO we try to create a new subscription for the given + * token and topic. + * @param handler The handler to invoke once the subscription request + * finishes. + */ +- (void)updateSubscriptionWithToken:(NSString *)token + topic:(NSString *)topic + options:(NSDictionary *)options + shouldDelete:(BOOL)shouldDelete + handler:(FIRMessagingTopicOperationCompletion)handler; + +#pragma mark - MCS Connection + +/** + * Create a MCS connection. + * + * @param handler The handler to be invokend once the connection is setup. If + * setting up the connection fails we invoke the handler with + * an appropriate error object. + */ +- (void)connectWithHandler:(FIRMessagingConnectCompletionHandler)handler; + +/** + * Disconnect the current MCS connection. If there is no valid connection this + * should be a NO-OP. + */ +- (void)disconnect; + +#pragma mark - MCS Connection State + +/** + * If we are connected to MCS or not. This doesn't take into account the fact if + * the client has been signed in(verified) by MCS. + * + * @return YES if we are signed in or connecting and trying to sign-in else NO. + */ +@property(nonatomic, readonly) BOOL isConnected; + +/** + * If we have an active MCS connection + * + * @return YES if we have an active MCS connection else NO. + */ +@property(nonatomic, readonly) BOOL isConnectionActive; + +/** + * If we should be connected to MCS + * + * @return YES if we have attempted a connection and not requested to disconect. + */ +@property(nonatomic, readonly) BOOL shouldStayConnected; + +/** + * Schedule a retry to connect to MCS. If `immediately` is `YES` try to + * schedule a retry now else retry with some delay. + * + * @param immediately Should retry right now. + */ +- (void)retryConnectionImmediately:(BOOL)immediately; + +#pragma mark - Messages + +/** + * Send a message over the MCS connection. + * + * @param message Message to be sent. + */ +- (void)sendMessage:(GPBMessage *)message; + +/** + * Send message if we have an active MCS connection. If not cache the message + * for this session and in case we are able to re-establish the connection try + * again else drop it. This should only be used for TTL=0 messages for now. + * + * @param message Message to be sent. + */ +- (void)sendOnConnectOrDrop:(GPBMessage *)message; + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingClient.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingClient.m new file mode 100644 index 00000000..9d8c5589 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingClient.m @@ -0,0 +1,506 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingClient.h" + +#import + +#import "FIRMessaging.h" +#import "FIRMessagingConnection.h" +#import "FIRMessagingConstants.h" +#import "FIRMessagingDataMessageManager.h" +#import "FIRMessagingDefines.h" +#import "FIRMessagingLogger.h" +#import "FIRMessagingRegistrar.h" +#import "FIRMessagingRmqManager.h" +#import "FIRMessagingTopicsCommon.h" +#import "FIRMessagingUtilities.h" +#import "NSError+FIRMessaging.h" + +static const NSTimeInterval kConnectTimeoutInterval = 40.0; +static const NSTimeInterval kReconnectDelayInSeconds = 2 * 60; // 2 minutes + +static const NSUInteger kMaxRetryExponent = 10; // 2^10 = 1024 seconds ~= 17 minutes + +static NSString *const kFIRMessagingMCSServerHost = @"mtalk.google.com"; +static NSUInteger const kFIRMessagingMCSServerPort = 5228; + +// register device with checkin +typedef void(^FIRMessagingRegisterDeviceHandler)(NSError *error); + +static NSString *FIRMessagingServerHost() { + static NSString *serverHost = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSDictionary *environment = [[NSProcessInfo processInfo] environment]; + NSString *customServerHostAndPort = environment[@"FCM_MCS_HOST"]; + NSString *host = [customServerHostAndPort componentsSeparatedByString:@":"].firstObject; + if (host) { + serverHost = host; + } else { + serverHost = kFIRMessagingMCSServerHost; + } + }); + return serverHost; +} + +static NSUInteger FIRMessagingServerPort() { + static NSUInteger serverPort = kFIRMessagingMCSServerPort; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSDictionary *environment = [[NSProcessInfo processInfo] environment]; + NSString *customServerHostAndPort = environment[@"FCM_MCS_HOST"]; + NSArray *components = [customServerHostAndPort componentsSeparatedByString:@":"]; + NSUInteger port = (NSUInteger)[components.lastObject integerValue]; + if (port != 0) { + serverPort = port; + } + }); + return serverPort; +} + +@interface FIRMessagingClient () + +@property(nonatomic, readwrite, weak) id clientDelegate; +@property(nonatomic, readwrite, strong) FIRMessagingConnection *connection; +@property(nonatomic, readwrite, strong) FIRMessagingRegistrar *registrar; + +@property(nonatomic, readwrite, strong) NSString *senderId; + +// FIRMessagingService owns these instances +@property(nonatomic, readwrite, weak) FIRMessagingRmqManager *rmq2Manager; +@property(nonatomic, readwrite, weak) GULReachabilityChecker *reachability; + +@property(nonatomic, readwrite, assign) int64_t lastConnectedTimestamp; +@property(nonatomic, readwrite, assign) int64_t lastDisconnectedTimestamp; +@property(nonatomic, readwrite, assign) NSUInteger connectRetryCount; + +// Should we stay connected to MCS or not. Should be YES throughout the lifetime +// of a MCS connection. If set to NO it signifies that an existing MCS connection +// should be disconnected. +@property(nonatomic, readwrite, assign) BOOL stayConnected; +@property(nonatomic, readwrite, assign) NSTimeInterval connectionTimeoutInterval; + +// Used if the MCS connection suddenly breaksdown in the middle and we want to reconnect +// with some permissible delay we schedule a reconnect and set it to YES and when it's +// scheduled this will be set back to NO. +@property(nonatomic, readwrite, assign) BOOL didScheduleReconnect; + +// handlers +@property(nonatomic, readwrite, copy) FIRMessagingConnectCompletionHandler connectHandler; + +@end + +@implementation FIRMessagingClient + +- (instancetype)init { + FIRMessagingInvalidateInitializer(); +} + +- (instancetype)initWithDelegate:(id)delegate + reachability:(GULReachabilityChecker *)reachability + rmq2Manager:(FIRMessagingRmqManager *)rmq2Manager { + self = [super init]; + if (self) { + _reachability = reachability; + _clientDelegate = delegate; + _rmq2Manager = rmq2Manager; + _registrar = [[FIRMessagingRegistrar alloc] init]; + _connectionTimeoutInterval = kConnectTimeoutInterval; + // Listen for checkin fetch notifications, as connecting to MCS may have failed due to + // missing checkin info (while it was being fetched). + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(checkinFetched:) + name:kFIRMessagingCheckinFetchedNotification + object:nil]; + } + return self; +} + +- (void)teardown { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeClient000, @""); + self.stayConnected = NO; + + // Clear all the handlers + self.connectHandler = nil; + + [self.connection teardown]; + + // Stop all subscription requests + [self.registrar cancelAllRequests]; + + _FIRMessagingDevAssert(self.connection.state == kFIRMessagingConnectionNotConnected, @"Did not disconnect"); + [NSObject cancelPreviousPerformRequestsWithTarget:self]; + + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)cancelAllRequests { + // Stop any checkin requests or any subscription requests + [self.registrar cancelAllRequests]; + + // Stop any future connection requests to MCS + if (self.stayConnected && self.isConnected && !self.isConnectionActive) { + self.stayConnected = NO; + [NSObject cancelPreviousPerformRequestsWithTarget:self]; + } +} + +#pragma mark - FIRMessaging subscribe + +- (void)updateSubscriptionWithToken:(NSString *)token + topic:(NSString *)topic + options:(NSDictionary *)options + shouldDelete:(BOOL)shouldDelete + handler:(FIRMessagingTopicOperationCompletion)handler { + + _FIRMessagingDevAssert(handler != nil, @"Invalid handler to FIRMessaging subscribe"); + + FIRMessagingTopicOperationCompletion completion = ^void(NSError *error) { + if (error) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeClient001, @"Failed to subscribe to topic %@", + error); + } else { + if (shouldDelete) { + FIRMessagingLoggerInfo(kFIRMessagingMessageCodeClient002, + @"Successfully unsubscribed from topic %@", topic); + } else { + FIRMessagingLoggerInfo(kFIRMessagingMessageCodeClient003, + @"Successfully subscribed to topic %@", topic); + } + } + handler(error); + }; + + [self.registrar updateSubscriptionToTopic:topic + withToken:token + options:options + shouldDelete:shouldDelete + handler:completion]; +} + +#pragma mark - MCS Connection + +- (BOOL)isConnected { + return self.stayConnected && self.connection.state != kFIRMessagingConnectionNotConnected; +} + +- (BOOL)isConnectionActive { + return self.stayConnected && self.connection.state == kFIRMessagingConnectionSignedIn; +} + +- (BOOL)shouldStayConnected { + return self.stayConnected; +} + +- (void)retryConnectionImmediately:(BOOL)immediately { + // Do not connect to an invalid host or an invalid port + if (!self.stayConnected || !self.connection.host || self.connection.port == 0) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeClient004, + @"FIRMessaging connection will not reconnect to MCS. " + @"Stay connected: %d", + self.stayConnected); + return; + } + if (self.isConnectionActive) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeClient005, + @"FIRMessaging Connection skip retry, active"); + // already connected and logged in. + // Heartbeat alarm is set and will force close the connection + return; + } + if (self.isConnected) { + // already connected and logged in. + // Heartbeat alarm is set and will force close the connection + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeClient006, + @"FIRMessaging Connection skip retry, connected"); + return; + } + + if (immediately) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeClient007, + @"Try to connect to MCS immediately"); + [self tryToConnect]; + } else { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeClient008, @"Try to connect to MCS lazily"); + // Avoid all the other logic that we have in other clients, since this would always happen + // when the app is in the foreground and since the FIRMessaging connection isn't shared with any other + // app we can be more aggressive in reconnections + if (!self.didScheduleReconnect) { + FIRMessaging_WEAKIFY(self); + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, + (int64_t)(kReconnectDelayInSeconds * NSEC_PER_SEC)), + dispatch_get_main_queue(), ^{ + FIRMessaging_STRONGIFY(self); + self.didScheduleReconnect = NO; + [self tryToConnect]; + }); + + self.didScheduleReconnect = YES; + } + } +} + +- (void)connectWithHandler:(FIRMessagingConnectCompletionHandler)handler { + if (self.isConnected) { + NSError *error = [NSError fcm_errorWithCode:kFIRMessagingErrorCodeAlreadyConnected + userInfo:@{ + NSLocalizedFailureReasonErrorKey: @"FIRMessaging is already connected", + }]; + handler(error); + return; + } + self.lastDisconnectedTimestamp = FIRMessagingCurrentTimestampInMilliseconds(); + self.connectHandler = handler; + [self connect]; +} + +- (void)connect { + // reset retry counts + self.connectRetryCount = 0; + + if (self.isConnected) { + return; + } + + self.stayConnected = YES; + if (![self.registrar tryToLoadValidCheckinInfo]) { + // Checkin info is not available. This may be due to the checkin still being fetched. + if (self.connectHandler) { + NSError *error = [NSError errorWithFCMErrorCode:kFIRMessagingErrorCodeMissingDeviceID]; + self.connectHandler(error); + } + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeClient009, + @"Failed to connect to MCS. No deviceID and secret found."); + // Return for now. If checkin is, in fact, retrieved, the + // |kFIRMessagingCheckinFetchedNotification| will be fired. + return; + } + [self setupConnectionAndConnect]; +} + +- (void)disconnect { + // user called disconnect + // We don't want to connect later even if no network is available. + [self disconnectWithTryToConnectLater:NO]; +} + +/** + * Disconnect the current client connection. Also explicitly stop and connction retries. + * + * @param tryToConnectLater If YES will try to connect later when sending upstream messages + * else if NO do not connect again until user explicitly calls + * connect. + */ +- (void)disconnectWithTryToConnectLater:(BOOL)tryToConnectLater { + + self.stayConnected = tryToConnectLater; + [self.connection signOut]; + _FIRMessagingDevAssert(self.connection.state == kFIRMessagingConnectionNotConnected, + @"FIRMessaging connection did not disconnect"); + + // since we can disconnect while still trying to establish the connection it's required to + // cancel all performSelectors else the object might be retained + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(tryToConnect) + object:nil]; + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(didConnectTimeout) + object:nil]; + self.connectHandler = nil; +} + +#pragma mark - Checkin Notification +- (void)checkinFetched:(NSNotification *)notification { + // A failed checkin may have been the reason for the connection failure. Attempt a connection + // if the checkin fetched notification is fired. + if (self.stayConnected && !self.isConnected) { + [self connect]; + } +} + +#pragma mark - Messages + +- (void)sendMessage:(GPBMessage *)message { + [self.connection sendProto:message]; +} + +- (void)sendOnConnectOrDrop:(GPBMessage *)message { + [self.connection sendOnConnectOrDrop:message]; +} + +#pragma mark - FIRMessagingConnectionDelegate + +- (void)connection:(FIRMessagingConnection *)fcmConnection + didCloseForReason:(FIRMessagingConnectionCloseReason)reason { + + self.lastDisconnectedTimestamp = FIRMessagingCurrentTimestampInMilliseconds(); + + if (reason == kFIRMessagingConnectionCloseReasonSocketDisconnected) { + // Cancel the not-yet-triggered timeout task before rescheduling, in case the previous sign in + // failed, due to a connection error caused by bad network. + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(didConnectTimeout) + object:nil]; + } + if (self.stayConnected) { + [self scheduleConnectRetry]; + } +} + +- (void)didLoginWithConnection:(FIRMessagingConnection *)fcmConnection { + // Cancel the not-yet-triggered timeout task. + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(didConnectTimeout) + object:nil]; + self.connectRetryCount = 0; + self.lastConnectedTimestamp = FIRMessagingCurrentTimestampInMilliseconds(); + + + [self.dataMessageManager setDeviceAuthID:self.registrar.deviceAuthID + secretToken:self.registrar.secretToken]; + if (self.connectHandler) { + self.connectHandler(nil); + // notified the third party app with the registrationId. + // we don't want them to know about the connection status and how it changes + // so remove this handler + self.connectHandler = nil; + } +} + +- (void)connectionDidRecieveMessage:(GtalkDataMessageStanza *)message { + NSDictionary *parsedMessage = [self.dataMessageManager processPacket:message]; + if ([parsedMessage count]) { + [self.dataMessageManager didReceiveParsedMessage:parsedMessage]; + } +} + +- (int)connectionDidReceiveAckForRmqIds:(NSArray *)rmqIds { + NSSet *rmqIDSet = [NSSet setWithArray:rmqIds]; + NSMutableArray *messagesSent = [NSMutableArray arrayWithCapacity:rmqIds.count]; + [self.rmq2Manager scanWithRmqMessageHandler:nil + dataMessageHandler:^(int64_t rmqId, GtalkDataMessageStanza *stanza) { + NSString *rmqIdString = [NSString stringWithFormat:@"%lld", rmqId]; + if ([rmqIDSet containsObject:rmqIdString]) { + [messagesSent addObject:stanza]; + } + }]; + for (GtalkDataMessageStanza *message in messagesSent) { + [self.dataMessageManager didSendDataMessageStanza:message]; + } + return [self.rmq2Manager removeRmqMessagesWithRmqIds:rmqIds]; +} + +#pragma mark - Private + +- (void)setupConnectionAndConnect { + [self setupConnection]; + [self tryToConnect]; +} + +- (void)setupConnection { + NSString *host = FIRMessagingServerHost(); + NSUInteger port = FIRMessagingServerPort(); + _FIRMessagingDevAssert([host length] > 0 && port != 0, @"Invalid port or host"); + + if (self.connection != nil) { + // if there is an old connection, explicitly sign it off. + [self.connection signOut]; + self.connection.delegate = nil; + } + self.connection = [[FIRMessagingConnection alloc] initWithAuthID:self.registrar.deviceAuthID + token:self.registrar.secretToken + host:host + port:port + runLoop:[NSRunLoop mainRunLoop] + rmq2Manager:self.rmq2Manager + fcmManager:self.dataMessageManager]; + self.connection.delegate = self; +} + +- (void)tryToConnect { + if (!self.stayConnected) { + return; + } + + // Cancel any other pending signin requests. + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(tryToConnect) + object:nil]; + + // Do not re-sign in if there is already a connection in progress. + if (self.connection.state != kFIRMessagingConnectionNotConnected) { + return; + } + + _FIRMessagingDevAssert(self.registrar.deviceAuthID.length > 0 && + self.registrar.secretToken.length > 0 && + self.connection != nil, + @"Invalid state cannot connect"); + + self.connectRetryCount = MIN(kMaxRetryExponent, self.connectRetryCount + 1); + [self performSelector:@selector(didConnectTimeout) + withObject:nil + afterDelay:self.connectionTimeoutInterval]; + [self.connection signIn]; +} + +- (void)didConnectTimeout { + _FIRMessagingDevAssert(self.connection.state != kFIRMessagingConnectionSignedIn, + @"Invalid state for MCS connection"); + + if (self.stayConnected) { + [self.connection signOut]; + [self scheduleConnectRetry]; + } +} + +#pragma mark - Schedulers + +- (void)scheduleConnectRetry { + GULReachabilityStatus status = self.reachability.reachabilityStatus; + BOOL isReachable = (status == kGULReachabilityViaWifi || status == kGULReachabilityViaCellular); + if (!isReachable) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeClient010, + @"Internet not reachable when signing into MCS during a retry"); + + FIRMessagingConnectCompletionHandler handler = [self.connectHandler copy]; + // disconnect before issuing a callback + [self disconnectWithTryToConnectLater:YES]; + NSError *error = + [NSError errorWithDomain:@"No internet available, cannot connect to FIRMessaging" + code:kFIRMessagingErrorCodeNetwork + userInfo:nil]; + if (handler) { + handler(error); + self.connectHandler = nil; + } + return; + } + + NSUInteger retryInterval = [self nextRetryInterval]; + + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeClient011, + @"Failed to sign in to MCS, retry in %lu seconds", + _FIRMessaging_UL(retryInterval)); + [self performSelector:@selector(tryToConnect) withObject:nil afterDelay:retryInterval]; +} + +- (NSUInteger)nextRetryInterval { + return 1u << self.connectRetryCount; +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingCodedInputStream.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingCodedInputStream.h new file mode 100644 index 00000000..8f22290c --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingCodedInputStream.h @@ -0,0 +1,28 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@interface FIRMessagingCodedInputStream : NSObject + +@property(nonatomic, readonly, assign) size_t offset; + +- (instancetype)initWithData:(NSData *)data; +- (BOOL)readTag:(int8_t *)tag; +- (BOOL)readLength:(int32_t *)length; +- (NSData *)readDataWithLength:(uint32_t)length; + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingCodedInputStream.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingCodedInputStream.m new file mode 100644 index 00000000..82c0677c --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingCodedInputStream.m @@ -0,0 +1,142 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingCodedInputStream.h" +#import "FIRMessagingDefines.h" + +typedef struct { + const void *bytes; + size_t bufferSize; + size_t bufferPos; +} BufferState; + +static BOOL CheckSize(BufferState *state, size_t size) { + size_t newSize = state->bufferPos + size; + if (newSize > state->bufferSize) { + return NO; + } + return YES; +} + +static BOOL ReadRawByte(BufferState *state, int8_t *output) { + _FIRMessagingDevAssert(output != NULL && state != NULL, @"Invalid parameters"); + + if (CheckSize(state, sizeof(int8_t))) { + *output = ((int8_t *)state->bytes)[state->bufferPos++]; + return YES; + } + return NO; +} + +static BOOL ReadRawVarInt32(BufferState *state, int32_t *output) { + _FIRMessagingDevAssert(output != NULL && state != NULL, @"Invalid parameters"); + + int8_t tmp = 0; + if (!ReadRawByte(state, &tmp)) { + return NO; + } + if (tmp >= 0) { + *output = tmp; + return YES; + } + int32_t result = tmp & 0x7f; + if (!ReadRawByte(state, &tmp)) { + return NO; + } + if (tmp >= 0) { + result |= tmp << 7; + } else { + result |= (tmp & 0x7f) << 7; + if (!ReadRawByte(state, &tmp)) { + return NO; + } + if (tmp >= 0) { + result |= tmp << 14; + } else { + result |= (tmp & 0x7f) << 14; + if (!ReadRawByte(state, &tmp)) { + return NO; + } + if (tmp >= 0) { + result |= tmp << 21; + } else { + result |= (tmp & 0x7f) << 21; + if (!ReadRawByte(state, &tmp)) { + return NO; + } + result |= tmp << 28; + if (tmp < 0) { + // Discard upper 32 bits. + for (int i = 0; i < 5; ++i) { + if (!ReadRawByte(state, &tmp)) { + return NO; + } + if (tmp >= 0) { + *output = result; + return YES; + } + } + return NO; + } + } + } + } + *output = result; + return YES; +} + +@interface FIRMessagingCodedInputStream() + +@property(nonatomic, readwrite, strong) NSData *buffer; +@property(nonatomic, readwrite, assign) BufferState state; + +@end + +@implementation FIRMessagingCodedInputStream; + +- (instancetype)initWithData:(NSData *)data { + self = [super init]; + if (self) { + _buffer = data; + _state.bytes = _buffer.bytes; + _state.bufferSize = _buffer.length; + } + return self; +} + +- (size_t)offset { + return _state.bufferPos; +} + +- (BOOL)readTag:(int8_t *)tag { + return ReadRawByte(&_state, tag); +} + +- (BOOL)readLength:(int32_t *)length { + return ReadRawVarInt32(&_state, length); +} + +- (NSData *)readDataWithLength:(uint32_t)length { + if (!CheckSize(&_state, length)) { + return nil; + } + const void *bytesToRead = _state.bytes + _state.bufferPos; + NSData *result = [NSData dataWithBytes:bytesToRead length:length]; + _state.bufferPos += length; + return result; +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingConnection.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingConnection.h new file mode 100644 index 00000000..25a018c6 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingConnection.h @@ -0,0 +1,106 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class FIRMessagingConnection; +@class FIRMessagingDataMessageManager; +@class FIRMessagingRmqManager; + +@class GtalkDataMessageStanza; +@class GPBMessage; + +typedef void (^FIRMessagingMessageHandler)(NSDictionary *); + +typedef NS_ENUM(NSUInteger, FIRMessagingConnectionState) { + kFIRMessagingConnectionNotConnected = 0, + kFIRMessagingConnectionConnecting, + kFIRMessagingConnectionConnected, + kFIRMessagingConnectionSignedIn, +}; + +typedef NS_ENUM(NSUInteger, FIRMessagingConnectionCloseReason) { + kFIRMessagingConnectionCloseReasonSocketDisconnected = 0, + kFIRMessagingConnectionCloseReasonTimeout, + kFIRMessagingConnectionCloseReasonUserDisconnect, +}; + +@protocol FIRMessagingConnectionDelegate + +- (void)connection:(FIRMessagingConnection *)fcmConnection + didCloseForReason:(FIRMessagingConnectionCloseReason)reason; +- (void)didLoginWithConnection:(FIRMessagingConnection *)fcmConnection; +- (void)connectionDidRecieveMessage:(GtalkDataMessageStanza *)message; +/** + * Called when a stream ACK or a selective ACK are received - this indicates the + * message has been received by MCS. + * @return The count of rmqIds deleted from the client RMQ store. + */ +- (int)connectionDidReceiveAckForRmqIds:(NSArray *)rmqIds; + +@end + + +/** + * This class maintains the actual FIRMessaging connection that we use to receive and send messages + * while the app is in foreground. Once we have a registrationID from the FIRMessaging backend we + * are able to set up this connection which is used for any further communication with FIRMessaging + * backend. In case the connection breaks off while the app is still being used we try to rebuild + * the connection with an exponential backoff. + * + * This class also notifies the delegate about the main events happening in the lifcycle of the + * FIRMessaging connection (read FIRMessagingConnectionDelegate). All of the `on-the-wire` + * interactions with FIRMessaging are channelled through here. + */ +@interface FIRMessagingConnection : NSObject + +@property(nonatomic, readonly, assign) FIRMessagingConnectionState state; +@property(nonatomic, readonly, copy) NSString *host; +@property(nonatomic, readonly, assign) NSUInteger port; +@property(nonatomic, readwrite, weak) id delegate; + +- (instancetype)initWithAuthID:(NSString *)authId + token:(NSString *)token + host:(NSString *)host + port:(NSUInteger)port + runLoop:(NSRunLoop *)runLoop + rmq2Manager:(FIRMessagingRmqManager *)rmq2Manager + fcmManager:(FIRMessagingDataMessageManager *)dataMessageManager; + +- (void)signIn; // connect +- (void)signOut; // disconnect + +/** + * Teardown the FIRMessaging connection and deallocate the resources being held up by the + * connection. + */ +- (void)teardown; + +/** + * Send proto to the wire. The message will be cached before we try to send so that in case of + * failure we can send it again later on when we have connection. + */ +- (void)sendProto:(GPBMessage *)proto; + +/** + * Send a message after the currently in progress connection succeeds, otherwise drop it. + * + * This should be used for TTL=0 messages that force a reconnect. They shouldn't be persisted + * in the RMQ, but they should be sent if the reconnect is successful. + */ +- (void)sendOnConnectOrDrop:(GPBMessage *)message; + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingConnection.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingConnection.m new file mode 100644 index 00000000..8694326b --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingConnection.m @@ -0,0 +1,708 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingConnection.h" + +#import "Protos/GtalkCore.pbobjc.h" +#import "Protos/GtalkExtensions.pbobjc.h" + +#import "FIRMessaging.h" +#import "FIRMessagingDataMessageManager.h" +#import "FIRMessagingDefines.h" +#import "FIRMessagingLogger.h" +#import "FIRMessagingRmqManager.h" +#import "FIRMessagingSecureSocket.h" +#import "FIRMessagingUtilities.h" +#import "FIRMessagingVersionUtilities.h" +#import "FIRMessaging_Private.h" + +static NSInteger const kIqSelectiveAck = 12; +static NSInteger const kIqStreamAck = 13; +static int const kInvalidStreamId = -1; +// Threshold for number of messages removed that we will ack, for short lived connections +static int const kMessageRemoveAckThresholdCount = 5; + +static NSTimeInterval const kHeartbeatInterval = 30.0; +static NSTimeInterval const kConnectionTimeout = 20.0; +static int32_t const kAckingInterval = 10; + +static NSString *const kUnackedS2dIdKey = @"FIRMessagingUnackedS2dIdKey"; +static NSString *const kAckedS2dIdMapKey = @"FIRMessagingAckedS2dIdMapKey"; + +static NSString *const kRemoteFromAddress = @"from"; + +@interface FIRMessagingD2SInfo : NSObject + +@property(nonatomic, readwrite, assign) int streamId; +@property(nonatomic, readwrite, strong) NSString *d2sID; +- (instancetype)initWithStreamId:(int)streamId d2sId:(NSString *)d2sID; + +@end + +@implementation FIRMessagingD2SInfo + +- (instancetype)initWithStreamId:(int)streamId d2sId:(NSString *)d2sID { + self = [super init]; + if (self) { + _streamId = streamId; + _d2sID = [d2sID copy]; + } + return self; +} + +- (BOOL)isEqual:(id)object { + if ([object isKindOfClass:[self class]]) { + FIRMessagingD2SInfo *other = (FIRMessagingD2SInfo *)object; + return self.streamId == other.streamId && [self.d2sID isEqualToString:other.d2sID]; + } + return NO; +} + +- (NSUInteger)hash { + return [self.d2sID hash]; +} + +@end + +@interface FIRMessagingConnection () + +@property(nonatomic, readwrite, weak) FIRMessagingRmqManager *rmq2Manager; +@property(nonatomic, readwrite, weak) FIRMessagingDataMessageManager *dataMessageManager; + +@property(nonatomic, readwrite, assign) FIRMessagingConnectionState state; +@property(nonatomic, readwrite, copy) NSString *host; +@property(nonatomic, readwrite, assign) NSUInteger port; + +@property(nonatomic, readwrite, strong) NSString *authId; +@property(nonatomic, readwrite, strong) NSString *token; + +@property(nonatomic, readwrite, strong) FIRMessagingSecureSocket *socket; + +@property(nonatomic, readwrite, assign) int64_t lastLoginServerTimestamp; +@property(nonatomic, readwrite, assign) int lastStreamIdAcked; +@property(nonatomic, readwrite, assign) int inStreamId; +@property(nonatomic, readwrite, assign) int outStreamId; + +@property(nonatomic, readwrite, strong) NSMutableArray *unackedS2dIds; +@property(nonatomic, readwrite, strong) NSMutableDictionary *ackedS2dMap; +@property(nonatomic, readwrite, strong) NSMutableArray *d2sInfos; +// ttl=0 messages that need to be sent as soon as we establish a connection +@property(nonatomic, readwrite, strong) NSMutableArray *sendOnConnectMessages; + +@property(nonatomic, readwrite, strong) NSRunLoop *runLoop; + +@end + + +@implementation FIRMessagingConnection; + +- (instancetype)initWithAuthID:(NSString *)authId + token:(NSString *)token + host:(NSString *)host + port:(NSUInteger)port + runLoop:(NSRunLoop *)runLoop + rmq2Manager:(FIRMessagingRmqManager *)rmq2Manager + fcmManager:(FIRMessagingDataMessageManager *)dataMessageManager { + self = [super init]; + if (self) { + _authId = [authId copy]; + _token = [token copy]; + _host = [host copy]; + _port = port; + _runLoop = runLoop; + _rmq2Manager = rmq2Manager; + _dataMessageManager = dataMessageManager; + + _d2sInfos = [NSMutableArray array]; + + _unackedS2dIds = [NSMutableArray arrayWithArray:[_rmq2Manager unackedS2dRmqIds]]; + _ackedS2dMap = [NSMutableDictionary dictionary]; + _sendOnConnectMessages = [NSMutableArray array]; + } + return self; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"host: %@, port: %lu, stream id in: %d, stream id out: %d", + self.host, + _FIRMessaging_UL(self.port), + self.inStreamId, + self.outStreamId]; +} + +- (void)signIn { + _FIRMessagingDevAssert(self.state == kFIRMessagingConnectionNotConnected, @"Invalid connection state."); + if (self.state != kFIRMessagingConnectionNotConnected) { + return; + } + + // break it up for testing + [self setupConnectionSocket]; + [self connectToSocket:self.socket]; +} + +- (void)setupConnectionSocket { + self.socket = [[FIRMessagingSecureSocket alloc] init]; + self.socket.delegate = self; +} + +- (void)connectToSocket:(FIRMessagingSecureSocket *)socket { + self.state = kFIRMessagingConnectionConnecting; + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection000, + @"Start connecting to FIRMessaging service."); + [socket connectToHost:self.host port:self.port onRunLoop:self.runLoop]; +} + +- (void)signOut { + // Clear the list of messages to be sent on connect. This will only + // have messages in it if an error happened before receiving the LoginResponse. + [self.sendOnConnectMessages removeAllObjects]; + + if (self.state == kFIRMessagingConnectionSignedIn) { + [self sendClose]; + } + if (self.state != kFIRMessagingConnectionNotConnected) { + [self disconnect]; + } +} + +- (void)teardown { + if (self.state != kFIRMessagingConnectionNotConnected) { + [self disconnect]; + } +} + +#pragma mark - FIRMessagingSecureSocketDelegate + +- (void)secureSocketDidConnect:(FIRMessagingSecureSocket *)socket { + self.state = kFIRMessagingConnectionConnected; + self.lastStreamIdAcked = 0; + self.inStreamId = 0; + self.outStreamId = 0; + + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection001, + @"Connected to FIRMessaging service."); + [self resetUnconfirmedAcks]; + [self sendLoginRequest:self.authId token:self.token]; +} + +- (void)didDisconnectWithSecureSocket:(FIRMessagingSecureSocket *)socket { + _FIRMessagingDevAssert(self.socket == socket, @"Invalid socket"); + _FIRMessagingDevAssert(self.socket.state == kFIRMessagingSecureSocketClosed, @"Socket already closed"); + + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection002, + @"Secure socket disconnected from FIRMessaging service."); + [self disconnect]; + [self.delegate connection:self didCloseForReason:kFIRMessagingConnectionCloseReasonSocketDisconnected]; +} + +- (void)secureSocket:(FIRMessagingSecureSocket *)socket + didReceiveData:(NSData *)data + withTag:(int8_t)tag { + if (tag < 0) { + // Invalid proto tag + return; + } + + Class klassForTag = FIRMessagingGetClassForTag((FIRMessagingProtoTag)tag); + if ([klassForTag isSubclassOfClass:[NSNull class]]) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeConnection003, @"Invalid tag %d for proto", + tag); + return; + } + + GPBMessage *proto = [klassForTag parseFromData:data error:NULL]; + if (tag == kFIRMessagingProtoTagLoginResponse && self.state != kFIRMessagingConnectionConnected) { + FIRMessagingLoggerDebug( + kFIRMessagingMessageCodeConnection004, + @"Should not receive generated message when the connection is not connected."); + return; + } else if (tag != kFIRMessagingProtoTagLoginResponse && self.state != kFIRMessagingConnectionSignedIn) { + FIRMessagingLoggerDebug( + kFIRMessagingMessageCodeConnection005, + @"Should not receive generated message when the connection is not signed in."); + return; + } + + // If traffic is received after a heartbeat it is safe to assume the connection is healthy. + [self cancelConnectionTimeoutTask]; + [self performSelector:@selector(sendHeartbeatPing) + withObject:nil + afterDelay:kHeartbeatInterval]; + + [self willProcessProto:proto]; + switch (tag) { + case kFIRMessagingProtoTagLoginResponse: + [self didReceiveLoginResponse:(GtalkLoginResponse *)proto]; + break; + case kFIRMessagingProtoTagDataMessageStanza: + [self didReceiveDataMessageStanza:(GtalkDataMessageStanza *)proto]; + break; + case kFIRMessagingProtoTagHeartbeatPing: + [self didReceiveHeartbeatPing:(GtalkHeartbeatPing *)proto]; + break; + case kFIRMessagingProtoTagHeartbeatAck: + [self didReceiveHeartbeatAck:(GtalkHeartbeatAck *)proto]; + break; + case kFIRMessagingProtoTagClose: + [self didReceiveClose:(GtalkClose *)proto]; + break; + case kFIRMessagingProtoTagIqStanza: + [self handleIqStanza:(GtalkIqStanza *)proto]; + break; + default: + [self didReceiveUnhandledProto:proto]; + break; + } +} + +// Called from secure socket once we have send the proto with given rmqId over the wire +// since we are mostly concerned with user facing messages which certainly have a rmqId +// we can retrieve them from the Rmq if necessary to look at stuff but for now we just +// log it. +- (void)secureSocket:(FIRMessagingSecureSocket *)socket + didSendProtoWithTag:(int8_t)tag + rmqId:(NSString *)rmqId { + // log the message + [self logMessage:rmqId messageType:tag isOut:YES]; +} + +#pragma mark - FIRMessagingTestConnection + +- (void)sendProto:(GPBMessage *)proto { + FIRMessagingProtoTag tag = FIRMessagingGetTagForProto(proto); + if (tag == kFIRMessagingProtoTagLoginRequest && self.state != kFIRMessagingConnectionConnected) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection006, + @"Cannot send generated message when the connection is not connected."); + return; + } else if (tag != kFIRMessagingProtoTagLoginRequest && self.state != kFIRMessagingConnectionSignedIn) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection007, + @"Cannot send generated message when the connection is not signed in."); + return; + } + + _FIRMessagingDevAssert(self.socket != nil, @"Socket shouldn't be nil"); + if (self.socket == nil) { + return; + } + + [self willSendProto:proto]; + + [self.socket sendData:proto.data withTag:tag rmqId:FIRMessagingGetRmq2Id(proto)]; +} + +- (void)sendOnConnectOrDrop:(GPBMessage *)message { + if (self.state == kFIRMessagingConnectionSignedIn) { + // If a connection has already been established, send normally + [self sendProto:message]; + } else { + // Otherwise add them to the list of messages to send after login + [self.sendOnConnectMessages addObject:message]; + } +} + ++ (GtalkLoginRequest *)loginRequestWithToken:(NSString *)token authID:(NSString *)authID { + GtalkLoginRequest *login = [[GtalkLoginRequest alloc] init]; + login.accountId = 1000000; + login.authService = GtalkLoginRequest_AuthService_AndroidId; + login.authToken = token; + login.id_p = [NSString stringWithFormat:@"%@-%@", @"ios", FIRMessagingCurrentLibraryVersion()]; + login.domain = @"mcs.android.com"; + login.deviceId = [NSString stringWithFormat:@"android-%llx", authID.longLongValue]; + login.networkType = [self currentNetworkType]; + login.resource = authID; + login.user = authID; + login.useRmq2 = YES; + login.lastRmqId = 1; // Sending not enabled yet so this stays as 1. + return login; +} + ++ (int32_t)currentNetworkType { + // http://developer.android.com/reference/android/net/ConnectivityManager.html + int32_t fcmNetworkType; + FIRMessagingNetworkStatus type = [[FIRMessaging messaging] networkType]; + switch (type) { + case kFIRMessagingReachabilityReachableViaWiFi: + fcmNetworkType = 1; + break; + + case kFIRMessagingReachabilityReachableViaWWAN: + fcmNetworkType = 0; + break; + + default: + fcmNetworkType = -1; + break; + } + return fcmNetworkType; +} + +- (void)sendLoginRequest:(NSString *)authId + token:(NSString *)token { + GtalkLoginRequest *login = [[self class] loginRequestWithToken:token authID:authId]; + + // clear the messages sent during last connection + if ([self.d2sInfos count]) { + [self.d2sInfos removeAllObjects]; + } + + if (self.unackedS2dIds.count > 0) { + FIRMessagingLoggerDebug( + kFIRMessagingMessageCodeConnection008, + @"There are unacked persistent Ids in the login request: %@", + [self.unackedS2dIds.description stringByReplacingOccurrencesOfString:@"%" + withString:@"%%"]); + } + // Send out acks. + for (NSString *unackedPersistentS2dId in self.unackedS2dIds) { + [login.receivedPersistentIdArray addObject:unackedPersistentS2dId]; + } + + GtalkSetting *setting = [[GtalkSetting alloc] init]; + setting.name = @"new_vc"; + setting.value = @"1"; + [login.settingArray addObject:setting]; + + [self sendProto:login]; +} + +- (void)sendHeartbeatAck { + [self sendProto:[[GtalkHeartbeatAck alloc] init]]; +} + +- (void)sendHeartbeatPing { + // cancel the previous heartbeat request. + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(sendHeartbeatPing) + object:nil]; + [self scheduleConnectionTimeoutTask]; + [self sendProto:[[GtalkHeartbeatPing alloc] init]]; +} + ++ (GtalkIqStanza *)createStreamAck { + GtalkIqStanza *iq = [[GtalkIqStanza alloc] init]; + iq.type = GtalkIqStanza_IqType_Set; + iq.id_p = @""; + GtalkExtension *ext = [[GtalkExtension alloc] init]; + ext.id_p = kIqStreamAck; + ext.data_p = @""; + iq.extension = ext; + return iq; +} + +- (void)sendStreamAck { + GtalkIqStanza *iq = [[self class] createStreamAck]; + [self sendProto:iq]; +} + +- (void)sendClose { + [self sendProto:[[GtalkClose alloc] init]]; +} + +- (void)handleIqStanza:(GtalkIqStanza *)iq { + if (iq.hasExtension) { + if (iq.extension.id_p == kIqStreamAck) { + [self didReceiveStreamAck:iq]; + return; + } + if (iq.extension.id_p == kIqSelectiveAck) { + [self didReceiveSelectiveAck:iq]; + return; + } + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection009, @"Unknown ack extension id %d.", + iq.extension.id_p); + } else { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection010, @"Ip stanza without extension."); + } + [self didReceiveUnhandledProto:iq]; +} + +- (void)didReceiveLoginResponse:(GtalkLoginResponse *)loginResponse { + if (loginResponse.hasError) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection011, + @"Login error with type: %@, message: %@.", loginResponse.error.type, + loginResponse.error.message); + return; + } + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection012, @"Logged onto MCS service."); + // We sent the persisted list of unack'd messages with login so we can assume they have been ack'd + // by the server. + _FIRMessagingDevAssert(self.unackedS2dIds.count == 0, @"No ids present"); + _FIRMessagingDevAssert(self.outStreamId == 1, @"Login should be the first stream id"); + + self.state = kFIRMessagingConnectionSignedIn; + self.lastLoginServerTimestamp = loginResponse.serverTimestamp; + [self.delegate didLoginWithConnection:self]; + [self sendHeartbeatPing]; + + // Add all the TTL=0 messages on connect + for (GPBMessage *message in self.sendOnConnectMessages) { + [self sendProto:message]; + } + [self.sendOnConnectMessages removeAllObjects]; +} + +- (void)didReceiveHeartbeatPing:(GtalkHeartbeatPing *)heartbeatPing { + [self sendHeartbeatAck]; +} + +- (void)didReceiveHeartbeatAck:(GtalkHeartbeatAck *)heartbeatAck { +} + +- (void)didReceiveDataMessageStanza:(GtalkDataMessageStanza *)dataMessageStanza { + // TODO: Maybe add support raw data later + [self.delegate connectionDidRecieveMessage:dataMessageStanza]; +} + +- (void)didReceiveUnhandledProto:(GPBMessage *)proto { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection013, @"Received unhandled proto"); +} + +- (void)didReceiveStreamAck:(GtalkIqStanza *)iq { + // Server received some stuff from us we don't really need to do anything special +} + +- (void)didReceiveSelectiveAck:(GtalkIqStanza *)iq { + GtalkExtension *extension = iq.extension; + if (extension) { + int extensionId = extension.id_p; + if (extensionId == kIqSelectiveAck) { + + NSString *dataString = extension.data_p; + GtalkSelectiveAck *selectiveAck = [[GtalkSelectiveAck alloc] init]; + [selectiveAck mergeFromData:[dataString dataUsingEncoding:NSUTF8StringEncoding] + extensionRegistry:nil]; + + NSArray *acks = [selectiveAck idArray]; + + // we've received ACK's + [self.delegate connectionDidReceiveAckForRmqIds:acks]; + + // resend unacked messages + [self.dataMessageManager resendMessagesWithConnection:self]; + } + } +} + +- (void)didReceiveClose:(GtalkClose *)close { + [self disconnect]; +} + +- (void)willProcessProto:(GPBMessage *)proto { + self.inStreamId++; + + if ([proto isKindOfClass:GtalkDataMessageStanza.class]) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection014, + @"RMQ: Receiving %@ with rmq_id: %@ incoming stream Id: %d", + proto.class, FIRMessagingGetRmq2Id(proto), self.inStreamId); + } else { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection015, + @"RMQ: Receiving %@ with incoming stream Id: %d.", proto.class, + self.inStreamId); + } + int streamId = FIRMessagingGetLastStreamId(proto); + if (streamId != kInvalidStreamId) { + // confirm the D2S messages that were sent by us + [self confirmAckedD2sIdsWithStreamId:streamId]; + + // We can now confirm that our ack was received by the server and start our unack'd list fresh + // with the proto we just received. + [self confirmAckedS2dIdsWithStreamId:streamId]; + } + NSString *rmq2Id = FIRMessagingGetRmq2Id(proto); + if (rmq2Id != nil) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection016, + @"RMQ: Add unacked persistent Id: %@.", + [rmq2Id stringByReplacingOccurrencesOfString:@"%" withString:@"%%"]); + [self.unackedS2dIds addObject:rmq2Id]; + [self.rmq2Manager saveS2dMessageWithRmqId:rmq2Id]; // RMQ save + } + BOOL explicitAck = ([proto isKindOfClass:[GtalkDataMessageStanza class]] && + [(GtalkDataMessageStanza *)proto immediateAck]); + // If we have not sent anything and the ack threshold has been reached then explicitly send one + // to notify the server that we have received messages. + if (self.inStreamId - self.lastStreamIdAcked >= kAckingInterval || explicitAck) { + [self sendStreamAck]; + } +} + +- (void)willSendProto:(GPBMessage *)proto { + self.outStreamId++; + + NSString *rmq2Id = FIRMessagingGetRmq2Id(proto); + if ([rmq2Id length]) { + FIRMessagingD2SInfo *d2sInfo = [[FIRMessagingD2SInfo alloc] initWithStreamId:self.outStreamId d2sId:rmq2Id]; + [self.d2sInfos addObject:d2sInfo]; + } + + // each time we send a d2s message, it acks previously received + // s2d messages via the last (s2d) stream id received. + + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection017, + @"RMQ: Sending %@ with outgoing stream Id: %d.", proto.class, + self.outStreamId); + // We have received messages since last time we sent something - send ack info to server. + if (self.inStreamId > self.lastStreamIdAcked) { + FIRMessagingSetLastStreamId(proto, self.inStreamId); + self.lastStreamIdAcked = self.inStreamId; + } + + if (self.unackedS2dIds.count > 0) { + // Move all 'unack'd' messages to the ack'd map so they can be removed once the + // ack is confirmed. + NSArray *ackedS2dIds = [NSArray arrayWithArray:self.unackedS2dIds]; + FIRMessagingLoggerDebug( + kFIRMessagingMessageCodeConnection018, @"RMQ: Mark persistent Ids as acked: %@.", + [ackedS2dIds.description stringByReplacingOccurrencesOfString:@"%" withString:@"%%"]); + [self.unackedS2dIds removeAllObjects]; + self.ackedS2dMap[[@(self.outStreamId) stringValue]] = ackedS2dIds; + } +} + +#pragma mark - Private + +/** + * This processes the s2d message received in reference to the d2s messages + * that we have sent before. + */ +- (void)confirmAckedD2sIdsWithStreamId:(int)lastReceivedStreamId { + NSMutableArray *d2sIdsAcked = [NSMutableArray array]; + for (FIRMessagingD2SInfo *d2sInfo in self.d2sInfos) { + if (lastReceivedStreamId < d2sInfo.streamId) { + break; + } + [d2sIdsAcked addObject:d2sInfo]; + } + + NSMutableArray *rmqIds = [NSMutableArray arrayWithCapacity:[d2sIdsAcked count]]; + // remove ACK'ed messages + for (FIRMessagingD2SInfo *d2sInfo in d2sIdsAcked) { + if ([d2sInfo.d2sID length]) { + [rmqIds addObject:d2sInfo.d2sID]; + } + [self.d2sInfos removeObject:d2sInfo]; + } + [self.delegate connectionDidReceiveAckForRmqIds:rmqIds]; + int count = [self.delegate connectionDidReceiveAckForRmqIds:rmqIds]; + if (kMessageRemoveAckThresholdCount > 0 && count >= kMessageRemoveAckThresholdCount) { + // For short lived connections, if a large number of messages are removed, send an + // ack straight away so the server knows that this message was received. + [self sendStreamAck]; + } +} + +/** + * Called when a stream ACK or a selective ACK are received - this indicates the message has + * been received by MCS. + */ +- (void)didReceiveAckForRmqIds:(NSArray *)rmqIds { + // TODO: let the user know that the following messages were received by the server +} + +- (void)confirmAckedS2dIdsWithStreamId:(int)lastReceivedStreamId { + // If the server hasn't received the streamId yet. + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection019, + @"RMQ: Server last received stream Id: %d.", lastReceivedStreamId); + if (lastReceivedStreamId < self.outStreamId) { + // TODO: This could be a good indicator that we need to re-send something (acks)? + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection020, + @"RMQ: There are unsent messages that should be send...\n" + "server received: %d\nlast stream id sent: %d", + lastReceivedStreamId, self.outStreamId); + } + + NSSet *ackedStreamIds = + [self.ackedS2dMap keysOfEntriesPassingTest:^BOOL(id key, id obj, BOOL *stop) { + NSString *streamId = key; + return streamId.intValue <= lastReceivedStreamId; + }]; + NSMutableArray *s2dIdsToDelete = [NSMutableArray array]; + + for (NSString *streamId in ackedStreamIds) { + NSArray *ackedS2dIds = self.ackedS2dMap[streamId]; + if (ackedS2dIds.count > 0) { + FIRMessagingLoggerDebug( + kFIRMessagingMessageCodeConnection021, + @"RMQ: Mark persistent Ids as confirmed by stream id %@: %@.", streamId, + [ackedS2dIds.description stringByReplacingOccurrencesOfString:@"%" withString:@"%%"]); + [self.ackedS2dMap removeObjectForKey:streamId]; + } + + [s2dIdsToDelete addObjectsFromArray:ackedS2dIds]; + } + + // clean up s2d ids that the server knows we've received. + // we let the server know via a s2d last stream id received in a + // d2s message. the server lets us know it has received our d2s + // message via a d2s last stream id received in a s2d message. + [self.rmq2Manager removeS2dIds:s2dIdsToDelete]; +} + +- (void)resetUnconfirmedAcks { + [self.ackedS2dMap enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + [self.unackedS2dIds addObjectsFromArray:obj]; + }]; + [self.ackedS2dMap removeAllObjects]; +} + +- (void)disconnect { + _FIRMessagingDevAssert(self.state != kFIRMessagingConnectionNotConnected, @"Connection already not connected"); + // cancel pending timeout tasks. + [self cancelConnectionTimeoutTask]; + // cancel pending heartbeat. + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(sendHeartbeatPing) + object:nil]; + // Unset the delegate. FIRMessagingConnection will not receive further events from the socket from now on. + self.socket.delegate = nil; + [self.socket disconnect]; + self.state = kFIRMessagingConnectionNotConnected; +} + +- (void)connectionTimedOut { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection022, + @"Connection to FIRMessaging service timed out."); + [self disconnect]; + [self.delegate connection:self didCloseForReason:kFIRMessagingConnectionCloseReasonTimeout]; +} + +- (void)scheduleConnectionTimeoutTask { + // cancel the previous heartbeat timeout event and schedule a new one. + [self cancelConnectionTimeoutTask]; + [self performSelector:@selector(connectionTimedOut) + withObject:nil + afterDelay:[self connectionTimeoutInterval]]; +} + +- (void)cancelConnectionTimeoutTask { + // cancel pending timeout tasks. + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(connectionTimedOut) + object:nil]; +} + +- (void)logMessage:(NSString *)description messageType:(int)messageType isOut:(BOOL)isOut { + messageType = isOut ? -messageType : messageType; + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection023, + @"Send msg: %@ type: %d inStreamId: %d outStreamId: %d", description, + messageType, self.inStreamId, self.outStreamId); +} + +- (NSTimeInterval)connectionTimeoutInterval { + return kConnectionTimeout; +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingConstants.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingConstants.h new file mode 100644 index 00000000..ad0d6c90 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingConstants.h @@ -0,0 +1,58 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +/** + * Global constants to be put here. + * + */ +#import + +#ifndef _FIRMessaging_CONSTANTS_H +#define _FIRMessaging_CONSTANTS_H + +FOUNDATION_EXPORT NSString *const kFIRMessagingRawDataKey; +FOUNDATION_EXPORT NSString *const kFIRMessagingCollapseKey; +FOUNDATION_EXPORT NSString *const kFIRMessagingFromKey; + +FOUNDATION_EXPORT NSString *const kFIRMessagingSendTo; +FOUNDATION_EXPORT NSString *const kFIRMessagingSendTTL; +FOUNDATION_EXPORT NSString *const kFIRMessagingSendDelay; +FOUNDATION_EXPORT NSString *const kFIRMessagingSendMessageID; +FOUNDATION_EXPORT NSString *const KFIRMessagingSendMessageAppData; + +FOUNDATION_EXPORT NSString *const kFIRMessagingMessageInternalReservedKeyword; +FOUNDATION_EXPORT NSString *const kFIRMessagingMessagePersistentIDKey; + +FOUNDATION_EXPORT NSString *const kFIRMessagingMessageIDKey; +FOUNDATION_EXPORT NSString *const kFIRMessagingMessageAPNSContentAvailableKey; +FOUNDATION_EXPORT NSString *const kFIRMessagingMessageSyncViaMCSKey; +FOUNDATION_EXPORT NSString *const kFIRMessagingMessageSyncMessageTTLKey; +FOUNDATION_EXPORT NSString *const kFIRMessagingMessageLinkKey; + +FOUNDATION_EXPORT NSString *const kFIRMessagingRemoteNotificationsProxyEnabledInfoPlistKey; + +FOUNDATION_EXPORT NSString *const kFIRMessagingApplicationSupportSubDirectory; + +// Notifications +FOUNDATION_EXPORT NSString *const kFIRMessagingCheckinFetchedNotification; +FOUNDATION_EXPORT NSString *const kFIRMessagingAPNSTokenNotification; +FOUNDATION_EXPORT NSString *const kFIRMessagingFCMTokenNotification; +FOUNDATION_EXPORT NSString *const kFIRMessagingInstanceIDTokenRefreshNotification __deprecated_msg("Use kFIRMessagingRegistrationTokenRefreshNotification instead"); +FOUNDATION_EXPORT NSString *const kFIRMessagingRegistrationTokenRefreshNotification; + +FOUNDATION_EXPORT const int kFIRMessagingSendTtlDefault; // 24 hours + +#endif diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingConstants.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingConstants.m new file mode 100644 index 00000000..8904cc59 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingConstants.m @@ -0,0 +1,52 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingConstants.h" + +NSString *const kFIRMessagingRawDataKey = @"rawData"; +NSString *const kFIRMessagingCollapseKey = @"collapse_key"; +NSString *const kFIRMessagingFromKey = @"from"; + +NSString *const kFIRMessagingSendTo = @"google." @"to"; +NSString *const kFIRMessagingSendTTL = @"google." @"ttl"; +NSString *const kFIRMessagingSendDelay = @"google." @"delay"; +NSString *const kFIRMessagingSendMessageID = @"google." @"msg_id"; +NSString *const KFIRMessagingSendMessageAppData = @"google." @"data"; + +NSString *const kFIRMessagingMessageInternalReservedKeyword = @"gcm."; +NSString *const kFIRMessagingMessagePersistentIDKey = @"persistent_id"; + +NSString *const kFIRMessagingMessageIDKey = @"gcm." @"message_id"; +NSString *const kFIRMessagingMessageAPNSContentAvailableKey = @"content-available"; +NSString *const kFIRMessagingMessageSyncViaMCSKey = @"gcm." @"duplex"; +NSString *const kFIRMessagingMessageSyncMessageTTLKey = @"gcm." @"ttl"; +NSString *const kFIRMessagingMessageLinkKey = @"gcm." @"app_link"; + +NSString *const kFIRMessagingRemoteNotificationsProxyEnabledInfoPlistKey = + @"FirebaseAppDelegateProxyEnabled"; + +NSString *const kFIRMessagingApplicationSupportSubDirectory = @"Google/FirebaseMessaging"; + +// Notifications +NSString *const kFIRMessagingCheckinFetchedNotification = @"com.google.gcm.notif-checkin-fetched"; +NSString *const kFIRMessagingAPNSTokenNotification = @"com.firebase.iid.notif.apns-token"; +NSString *const kFIRMessagingFCMTokenNotification = @"com.firebase.iid.notif.fcm-token"; +NSString *const kFIRMessagingInstanceIDTokenRefreshNotification = + @"com.firebase.iid.notif.refresh-token"; +NSString *const kFIRMessagingRegistrationTokenRefreshNotification = + @"com.firebase.iid.notif.refresh-token"; + +const int kFIRMessagingSendTtlDefault = 24 * 60 * 60; // 24 hours diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingContextManagerService.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingContextManagerService.h new file mode 100644 index 00000000..83e64442 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingContextManagerService.h @@ -0,0 +1,44 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +FOUNDATION_EXPORT NSString *const kFIRMessagingContextManagerCategory; +FOUNDATION_EXPORT NSString *const kFIRMessagingContextManagerLocalTimeStart; +FOUNDATION_EXPORT NSString *const kFIRMessagingContextManagerLocalTimeEnd; +FOUNDATION_EXPORT NSString *const kFIRMessagingContextManagerBodyKey; + +@interface FIRMessagingContextManagerService : NSObject + +/** + * Check if the message is a context manager message or not. + * + * @param message The message to verify. + * + * @return YES if the message is a context manager message else NO. + */ ++ (BOOL)isContextManagerMessage:(NSDictionary *)message; + +/** + * Handle context manager message. + * + * @param message The message to handle. + * + * @return YES if the message was handled successfully else NO. + */ ++ (BOOL)handleContextManagerMessage:(NSDictionary *)message; + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingContextManagerService.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingContextManagerService.m new file mode 100644 index 00000000..8527db1f --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingContextManagerService.m @@ -0,0 +1,203 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingContextManagerService.h" + +#import + +#import "FIRMessagingDefines.h" +#import "FIRMessagingLogger.h" +#import "FIRMessagingUtilities.h" + +#define kFIRMessagingContextManagerPrefixKey @"google.c.cm." +#define kFIRMessagingContextManagerNotificationKeyPrefix @"gcm.notification." + +static NSString *const kLogTag = @"FIRMessagingAnalytics"; + +static NSString *const kLocalTimeFormatString = @"yyyy-MM-dd HH:mm:ss"; + +static NSString *const kContextManagerPrefixKey = kFIRMessagingContextManagerPrefixKey; + +// Local timed messages (format yyyy-mm-dd HH:mm:ss) +NSString *const kFIRMessagingContextManagerLocalTimeStart = kFIRMessagingContextManagerPrefixKey @"lt_start"; +NSString *const kFIRMessagingContextManagerLocalTimeEnd = kFIRMessagingContextManagerPrefixKey @"lt_end"; + +// Local Notification Params +NSString *const kFIRMessagingContextManagerBodyKey = kFIRMessagingContextManagerNotificationKeyPrefix @"body"; +NSString *const kFIRMessagingContextManagerTitleKey = kFIRMessagingContextManagerNotificationKeyPrefix @"title"; +NSString *const kFIRMessagingContextManagerBadgeKey = kFIRMessagingContextManagerNotificationKeyPrefix @"badge"; +NSString *const kFIRMessagingContextManagerCategoryKey = + kFIRMessagingContextManagerNotificationKeyPrefix @"click_action"; +NSString *const kFIRMessagingContextManagerSoundKey = kFIRMessagingContextManagerNotificationKeyPrefix @"sound"; +NSString *const kFIRMessagingContextManagerContentAvailableKey = + kFIRMessagingContextManagerNotificationKeyPrefix @"content-available"; + +typedef NS_ENUM(NSUInteger, FIRMessagingContextManagerMessageType) { + FIRMessagingContextManagerMessageTypeNone, + FIRMessagingContextManagerMessageTypeLocalTime, +}; + +@implementation FIRMessagingContextManagerService + ++ (BOOL)isContextManagerMessage:(NSDictionary *)message { + // For now we only support local time in ContextManager. + if (![message[kFIRMessagingContextManagerLocalTimeStart] length]) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeContextManagerService000, + @"Received message missing local start time, dropped."); + return NO; + } + + return YES; +} + ++ (BOOL)handleContextManagerMessage:(NSDictionary *)message { + NSString *startTimeString = message[kFIRMessagingContextManagerLocalTimeStart]; + if (startTimeString.length) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeContextManagerService001, + @"%@ Received context manager message with local time %@", kLogTag, + startTimeString); + return [self handleContextManagerLocalTimeMessage:message]; + } + + return NO; +} + ++ (BOOL)handleContextManagerLocalTimeMessage:(NSDictionary *)message { + NSString *startTimeString = message[kFIRMessagingContextManagerLocalTimeStart]; + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]; + [dateFormatter setDateFormat:kLocalTimeFormatString]; + NSDate *startDate = [dateFormatter dateFromString:startTimeString]; + + _FIRMessagingDevAssert(startDate, @"Invalid local start date format %@", startTimeString); + if (!startTimeString) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeContextManagerService002, + @"Invalid local start date format %@. Message dropped", + startTimeString); + return NO; + } + + NSDate *currentDate = [NSDate date]; + + if ([currentDate compare:startDate] == NSOrderedAscending) { + [self scheduleLocalNotificationForMessage:message + atDate:startDate]; + } else { + // check end time has not passed + NSString *endTimeString = message[kFIRMessagingContextManagerLocalTimeEnd]; + if (!endTimeString) { + FIRMessagingLoggerInfo( + kFIRMessagingMessageCodeContextManagerService003, + @"No end date specified for message, start date elapsed. Message dropped."); + return YES; + } + + NSDate *endDate = [dateFormatter dateFromString:endTimeString]; + + _FIRMessagingDevAssert(endDate, @"Invalid local end date format %@", endTimeString); + if (!endTimeString) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeContextManagerService004, + @"Invalid local end date format %@. Message dropped", endTimeString); + return NO; + } + + if ([endDate compare:currentDate] == NSOrderedAscending) { + // end date has already passed drop the message + FIRMessagingLoggerInfo(kFIRMessagingMessageCodeContextManagerService005, + @"End date %@ has already passed. Message dropped.", endTimeString); + return YES; + } + + // schedule message right now (buffer 10s) + [self scheduleLocalNotificationForMessage:message + atDate:[currentDate dateByAddingTimeInterval:10]]; + } + return YES; +} + ++ (void)scheduleLocalNotificationForMessage:(NSDictionary *)message + atDate:(NSDate *)date { + NSDictionary *apsDictionary = message; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + UILocalNotification *notification = [[UILocalNotification alloc] init]; +#pragma clang diagnostic pop + + // A great way to understand timezones and UILocalNotifications + // http://stackoverflow.com/questions/18424569/understanding-uilocalnotification-timezone + notification.timeZone = [NSTimeZone defaultTimeZone]; + notification.fireDate = date; + + // In the current solution all of the display stuff goes into a special "aps" dictionary + // being sent in the message. + if ([apsDictionary[kFIRMessagingContextManagerBodyKey] length]) { + notification.alertBody = apsDictionary[kFIRMessagingContextManagerBodyKey]; + } + if ([apsDictionary[kFIRMessagingContextManagerTitleKey] length]) { + // |alertTitle| is iOS 8.2+, so check if we can set it + if ([notification respondsToSelector:@selector(setAlertTitle:)]) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability" + notification.alertTitle = apsDictionary[kFIRMessagingContextManagerTitleKey]; +#pragma pop + } + } + + if (apsDictionary[kFIRMessagingContextManagerSoundKey]) { + notification.soundName = apsDictionary[kFIRMessagingContextManagerSoundKey]; + } + if (apsDictionary[kFIRMessagingContextManagerBadgeKey]) { + notification.applicationIconBadgeNumber = + [apsDictionary[kFIRMessagingContextManagerBadgeKey] integerValue]; + } + if (apsDictionary[kFIRMessagingContextManagerCategoryKey]) { + // |category| is iOS 8.0+, so check if we can set it + if ([notification respondsToSelector:@selector(setCategory:)]) { + notification.category = apsDictionary[kFIRMessagingContextManagerCategoryKey]; + } + } + + NSDictionary *userInfo = [self parseDataFromMessage:message]; + if (userInfo.count) { + notification.userInfo = userInfo; + } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + UIApplication *application = FIRMessagingUIApplication(); + if (!application) { + return; + } + [application scheduleLocalNotification:notification]; +#pragma clang diagnostic pop +} + ++ (NSDictionary *)parseDataFromMessage:(NSDictionary *)message { + NSMutableDictionary *data = [NSMutableDictionary dictionary]; + for (NSObject *key in message) { + if ([key isKindOfClass:[NSString class]]) { + NSString *keyString = (NSString *)key; + if ([keyString isEqualToString:kFIRMessagingContextManagerContentAvailableKey]) { + continue; + } else if ([keyString hasPrefix:kContextManagerPrefixKey]) { + continue; + } + } + data[[key copy]] = message[key]; + } + return [data copy]; +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingDataMessageManager.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingDataMessageManager.h new file mode 100644 index 00000000..cf8df74e --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingDataMessageManager.h @@ -0,0 +1,101 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class GtalkDataMessageStanza; + +@class FIRMessagingClient; +@class FIRMessagingConnection; +@class FIRMessagingReceiver; +@class FIRMessagingRmqManager; +@class FIRMessagingSyncMessageManager; + +@protocol FIRMessagingDataMessageManagerDelegate + +#pragma mark - Downstream Callbacks + +/** + * Invoked when FIRMessaging receives a downstream message via the MCS connection. + * Let's the user know that they have received a new message by invoking the + * App's remoteNotification callback. + * + * @param message The downstream message received by the MCS connection. + */ +- (void)didReceiveMessage:(nonnull NSDictionary *)message + withIdentifier:(nullable NSString *)messageID; + +#pragma mark - Upstream Callbacks + +/** + * Notify the app that FIRMessaging will soon be sending the upstream message requested by the app. + * + * @param messageID The messageId passed in by the app to track this particular message. + * @param error The error in case FIRMessaging cannot send the message upstream. + */ +- (void)willSendDataMessageWithID:(nullable NSString *)messageID error:(nullable NSError *)error; + +/** + * Notify the app that FIRMessaging did successfully send it's message via the MCS + * connection and the message was successfully delivered. + * + * @param messageId The messageId passed in by the app to track this particular + * message. + */ +- (void)didSendDataMessageWithID:(nonnull NSString *)messageId; + +#pragma mark - Server Callbacks + +/** + * Notify the app that FIRMessaging server deleted some messages which exceeded storage limits. This + * indicates the "deleted_messages" message type we received from the server. + */ +- (void)didDeleteMessagesOnServer; + +@end + +/** + * This manages all of the data messages being sent by the client and also the messages that + * were received from the server. + */ +@interface FIRMessagingDataMessageManager : NSObject + +NS_ASSUME_NONNULL_BEGIN + +- (instancetype)initWithDelegate:(id)delegate + client:(FIRMessagingClient *)client + rmq2Manager:(FIRMessagingRmqManager *)rmq2Manager + syncMessageManager:(FIRMessagingSyncMessageManager *)syncMessageManager; + +- (void)setDeviceAuthID:(NSString *)deviceAuthID secretToken:(NSString *)secretToken; + +- (void)refreshDelayedMessages; + +#pragma mark - Receive + +- (nullable NSDictionary *)processPacket:(GtalkDataMessageStanza *)packet; +- (void)didReceiveParsedMessage:(NSDictionary *)message; + +#pragma mark - Send + +- (void)sendDataMessageStanza:(NSMutableDictionary *)dataMessage; +- (void)didSendDataMessageStanza:(GtalkDataMessageStanza *)message; + +- (void)resendMessagesWithConnection:(FIRMessagingConnection *)connection; + +NS_ASSUME_NONNULL_END + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingDataMessageManager.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingDataMessageManager.m new file mode 100644 index 00000000..b62763a1 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingDataMessageManager.m @@ -0,0 +1,528 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingDataMessageManager.h" + +#import "Protos/GtalkCore.pbobjc.h" + +#import "FIRMessagingClient.h" +#import "FIRMessagingConnection.h" +#import "FIRMessagingConstants.h" +#import "FIRMessagingDefines.h" +#import "FIRMessagingDelayedMessageQueue.h" +#import "FIRMessagingLogger.h" +#import "FIRMessagingReceiver.h" +#import "FIRMessagingRmqManager.h" +#import "FIRMessaging_Private.h" +#import "FIRMessagingSyncMessageManager.h" +#import "FIRMessagingUtilities.h" +#import "NSError+FIRMessaging.h" + +static const int kMaxAppDataSizeDefault = 4 * 1024; // 4k +static const int kMinDelaySeconds = 1; // 1 second +static const int kMaxDelaySeconds = 60 * 60; // 1 hour + +static NSString *const kFromForFIRMessagingMessages = @"mcs.android.com"; +static NSString *const kGSFMessageCategory = @"com.google.android.gsf.gtalkservice"; +// TODO: Update Gcm to FIRMessaging in the constants below +static NSString *const kFCMMessageCategory = @"com.google.gcm"; +static NSString *const kMessageReservedPrefix = @"google."; + +static NSString *const kFCMMessageSpecialMessage = @"message_type"; + +// special messages sent by the server +static NSString *const kFCMMessageTypeDeletedMessages = @"deleted_messages"; + +static NSString *const kMCSNotificationPrefix = @"gcm.notification."; +static NSString *const kDataMessageNotificationKey = @"notification"; + + +typedef NS_ENUM(int8_t, UpstreamForceReconnect) { + // Never force reconnect on upstream messages + kUpstreamForceReconnectOff = 0, + // Force reconnect for TTL=0 upstream messages + kUpstreamForceReconnectTTL0 = 1, + // Force reconnect for all upstream messages + kUpstreamForceReconnectAll = 2, +}; + +@interface FIRMessagingDataMessageManager () + +@property(nonatomic, readwrite, weak) FIRMessagingClient *client; +@property(nonatomic, readwrite, weak) FIRMessagingRmqManager *rmq2Manager; +@property(nonatomic, readwrite, weak) FIRMessagingSyncMessageManager *syncMessageManager; +@property(nonatomic, readwrite, weak) id delegate; +@property(nonatomic, readwrite, strong) FIRMessagingDelayedMessageQueue *delayedMessagesQueue; + +@property(nonatomic, readwrite, assign) int ttl; +@property(nonatomic, readwrite, copy) NSString *deviceAuthID; +@property(nonatomic, readwrite, copy) NSString *secretToken; +@property(nonatomic, readwrite, assign) int maxAppDataSize; +@property(nonatomic, readwrite, assign) UpstreamForceReconnect upstreamForceReconnect; + +@end + +@implementation FIRMessagingDataMessageManager + +- (instancetype)initWithDelegate:(id)delegate + client:(FIRMessagingClient *)client + rmq2Manager:(FIRMessagingRmqManager *)rmq2Manager + syncMessageManager:(FIRMessagingSyncMessageManager *)syncMessageManager { + self = [super init]; + if (self) { + _delegate = delegate; + _client = client; + _rmq2Manager = rmq2Manager; + _syncMessageManager = syncMessageManager; + _ttl = kFIRMessagingSendTtlDefault; + _maxAppDataSize = kMaxAppDataSizeDefault; + // on by default + _upstreamForceReconnect = kUpstreamForceReconnectAll; + } + return self; +} + +- (void)setDeviceAuthID:(NSString *)deviceAuthID secretToken:(NSString *)secretToken { + _FIRMessagingDevAssert([deviceAuthID length] && [secretToken length], + @"Invalid credentials for FIRMessaging"); + self.deviceAuthID = deviceAuthID; + self.secretToken = secretToken; +} + +- (void)refreshDelayedMessages { + FIRMessaging_WEAKIFY(self); + self.delayedMessagesQueue = + [[FIRMessagingDelayedMessageQueue alloc] initWithRmqScanner:self.rmq2Manager + sendDelayedMessagesHandler:^(NSArray *messages) { + FIRMessaging_STRONGIFY(self); + [self sendDelayedMessages:messages]; + }]; +} + +- (nullable NSDictionary *)processPacket:(GtalkDataMessageStanza *)dataMessage { + NSString *category = dataMessage.category; + NSString *from = dataMessage.from; + if ([kFCMMessageCategory isEqualToString:category] || + [kGSFMessageCategory isEqualToString:category]) { + [self handleMCSDataMessage:dataMessage]; + return nil; + } else if ([kFromForFIRMessagingMessages isEqualToString:from]) { + [self handleMCSDataMessage:dataMessage]; + return nil; + } + + return [self parseDataMessage:dataMessage]; +} + +- (void)handleMCSDataMessage:(GtalkDataMessageStanza *)dataMessage { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeDataMessageManager000, + @"Received message for FIRMessaging from downstream %@", dataMessage); +} + +- (NSDictionary *)parseDataMessage:(GtalkDataMessageStanza *)dataMessage { + NSMutableDictionary *message = [NSMutableDictionary dictionary]; + NSString *from = [dataMessage from]; + if ([from length]) { + message[kFIRMessagingFromKey] = from; + } + + // raw data + NSData *rawData = [dataMessage rawData]; + if ([rawData length]) { + message[kFIRMessagingRawDataKey] = rawData; + } + + NSString *token = [dataMessage token]; + if ([token length]) { + message[kFIRMessagingCollapseKey] = token; + } + + // Add the persistent_id. This would be removed later before sending the message to the device. + NSString *persistentID = [dataMessage persistentId]; + _FIRMessagingDevAssert([persistentID length], @"Invalid MCS message without persistentID"); + if ([persistentID length]) { + message[kFIRMessagingMessageIDKey] = persistentID; + } + + // third-party data + for (GtalkAppData *item in dataMessage.appDataArray) { + _FIRMessagingDevAssert(item.hasKey && item.hasValue, @"Invalid AppData"); + + // do not process the "from" key -- is not useful + if ([kFIRMessagingFromKey isEqualToString:item.key]) { + continue; + } + + // Filter the "gcm.notification." keys in the message + if ([item.key hasPrefix:kMCSNotificationPrefix]) { + NSString *key = [item.key substringFromIndex:[kMCSNotificationPrefix length]]; + if ([key length]) { + if (!message[kDataMessageNotificationKey]) { + message[kDataMessageNotificationKey] = [NSMutableDictionary dictionary]; + } + message[kDataMessageNotificationKey][key] = item.value; + } else { + _FIRMessagingDevAssert([key length], @"Invalid key in MCS message: %@", key); + FIRMessagingLoggerError(kFIRMessagingMessageCodeDataMessageManager001, + @"Invalid key in MCS message: %@", key); + } + continue; + } + + // Filter the "gcm.duplex" key + if ([item.key isEqualToString:kFIRMessagingMessageSyncViaMCSKey]) { + BOOL value = [item.value boolValue]; + message[kFIRMessagingMessageSyncViaMCSKey] = @(value); + continue; + } + + // do not allow keys with "reserved" keyword + if ([[item.key lowercaseString] hasPrefix:kMessageReservedPrefix]) { + continue; + } + + [message setObject:item.value forKey:item.key]; + } + // TODO: Add support for encrypting raw data later + return [NSDictionary dictionaryWithDictionary:message]; +} + +- (void)didReceiveParsedMessage:(NSDictionary *)message { + if ([message[kFCMMessageSpecialMessage] length]) { + NSString *messageType = message[kFCMMessageSpecialMessage]; + if ([kFCMMessageTypeDeletedMessages isEqualToString:messageType]) { + // TODO: Maybe trim down message to remove some unnecessary fields. + // tell the FCM receiver of deleted messages + [self.delegate didDeleteMessagesOnServer]; + return; + } + FIRMessagingLoggerError(kFIRMessagingMessageCodeDataMessageManager002, + @"Invalid message type received: %@", messageType); + } else if (message[kFIRMessagingMessageSyncViaMCSKey]) { + // Update SYNC_RMQ with the message + BOOL isDuplicate = [self.syncMessageManager didReceiveMCSSyncMessage:message]; + if (isDuplicate) { + return; + } + } + NSString *messageId = message[kFIRMessagingMessageIDKey]; + NSDictionary *filteredMessage = [self filterInternalFIRMessagingKeysFromMessage:message]; + [self.delegate didReceiveMessage:filteredMessage withIdentifier:messageId]; +} + +- (NSDictionary *)filterInternalFIRMessagingKeysFromMessage:(NSDictionary *)message { + NSMutableDictionary *newMessage = [NSMutableDictionary dictionaryWithDictionary:message]; + for (NSString *key in message) { + if ([key hasPrefix:kFIRMessagingMessageInternalReservedKeyword]) { + [newMessage removeObjectForKey:key]; + } + } + return [newMessage copy]; +} + +- (void)sendDataMessageStanza:(NSMutableDictionary *)dataMessage { + NSNumber *ttlNumber = dataMessage[kFIRMessagingSendTTL]; + NSString *to = dataMessage[kFIRMessagingSendTo]; + NSString *msgId = dataMessage[kFIRMessagingSendMessageID]; + NSString *appPackage = [self categoryForUpstreamMessages]; + GtalkDataMessageStanza *stanza = [[GtalkDataMessageStanza alloc] init]; + + // TODO: enforce TTL (right now only ttl=0 is special, means no storage) + int ttl = [ttlNumber intValue]; + if (ttl < 0 || ttl > self.ttl) { + ttl = self.ttl; + } + [stanza setTtl:ttl]; + [stanza setSent:FIRMessagingCurrentTimestampInSeconds()]; + + int delay = [self delayForMessage:dataMessage]; + if (delay > 0) { + [stanza setMaxDelay:delay]; + } + + if (msgId) { + [stanza setId_p:msgId]; + } + + // collapse key as given by the sender + NSString *token = dataMessage[KFIRMessagingSendMessageAppData][kFIRMessagingCollapseKey]; + if ([token length]) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeDataMessageManager003, + @"FIRMessaging using %@ as collapse key", token); + [stanza setToken:token]; + } + + if (!self.secretToken) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeDataMessageManager004, + @"Trying to send data message without a secret token. " + @"Authentication failed."); + [self willSendDataMessageFail:stanza + withMessageId:msgId + error:kFIRMessagingErrorCodeMissingDeviceID]; + return; + } + + if (![to length]) { + [self willSendDataMessageFail:stanza withMessageId:msgId error:kFIRMessagingErrorMissingTo]; + return; + } + [stanza setTo:to]; + [stanza setCategory:appPackage]; + // required field in the proto this is set by the server + // set it to a sentinel so the runtime doesn't throw an exception + [stanza setFrom:@""]; + + // MCS itself would set the registration ID + // [stanza setRegId:nil]; + + int size = [self addData:dataMessage[KFIRMessagingSendMessageAppData] toStanza:stanza]; + if (size > kMaxAppDataSizeDefault) { + [self willSendDataMessageFail:stanza withMessageId:msgId error:kFIRMessagingErrorSizeExceeded]; + return; + } + + BOOL useRmq = (ttl != 0) && (msgId != nil); + if (useRmq) { + if (!self.client.isConnected) { + // do nothing assuming rmq save is enabled + } + + NSError *error; + if (![self.rmq2Manager saveRmqMessage:stanza error:&error]) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeDataMessageManager005, @"%@", error); + [self willSendDataMessageFail:stanza withMessageId:msgId error:kFIRMessagingErrorSave]; + return; + } + + [self willSendDataMessageSuccess:stanza withMessageId:msgId]; + } + + // if delay > 0 we don't really care about sending the message right now + // so we piggy-back on any other urgent(delay = 0) message that we are sending + if (delay > 0 && [self delayMessage:stanza]) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeDataMessageManager006, @"Delaying Message %@", + dataMessage); + return; + } + // send delayed messages + [self sendDelayedMessages:[self.delayedMessagesQueue removeDelayedMessages]]; + + BOOL sending = [self tryToSendDataMessageStanza:stanza]; + if (!sending) { + if (useRmq) { + NSString *event __unused = [NSString stringWithFormat:@"Queued message: %@", [stanza id_p]]; + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeDataMessageManager007, @"%@", event); + } else { + [self willSendDataMessageFail:stanza + withMessageId:msgId + error:kFIRMessagingErrorCodeNetwork]; + return; + } + } +} + +- (void)sendDelayedMessages:(NSArray *)delayedMessages { + for (GtalkDataMessageStanza *message in delayedMessages) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeDataMessageManager008, + @"%@ Sending delayed message %@", @"DMM", message); + [message setActualDelay:(int)(FIRMessagingCurrentTimestampInSeconds() - message.sent)]; + [self tryToSendDataMessageStanza:message]; + } +} + +- (void)didSendDataMessageStanza:(GtalkDataMessageStanza *)message { + NSString *msgId = [message id_p] ?: @""; + [self.delegate didSendDataMessageWithID:msgId]; +} + +- (void)addParamWithKey:(NSString *)key + value:(NSString *)val + toStanza:(GtalkDataMessageStanza *)stanza { + if (!key || !val) { + return; + } + GtalkAppData *appData = [[GtalkAppData alloc] init]; + [appData setKey:key]; + [appData setValue:val]; + [[stanza appDataArray] addObject:appData]; +} + +/** + @return The size of the data being added to stanza. + */ +- (int)addData:(NSDictionary *)data toStanza:(GtalkDataMessageStanza *)stanza { + int size = 0; + for (NSString *key in data) { + NSObject *val = data[key]; + if ([val isKindOfClass:[NSString class]]) { + NSString *strVal = (NSString *)val; + [self addParamWithKey:key value:strVal toStanza:stanza]; + size += [key length] + [strVal length]; + } else if ([val isKindOfClass:[NSNumber class]]) { + NSString *strVal = [(NSNumber *)val stringValue]; + [self addParamWithKey:key value:strVal toStanza:stanza]; + size += [key length] + [strVal length]; + } else if ([kFIRMessagingRawDataKey isEqualToString:key] && + [val isKindOfClass:[NSData class]]) { + NSData *rawData = (NSData *)val; + [stanza setRawData:[rawData copy]]; + size += [rawData length]; + } else { + FIRMessagingLoggerError(kFIRMessagingMessageCodeDataMessageManager009, @"Ignoring key: %@", + key); + } + } + return size; +} + +/** + * Notify the messenger that send data message completed with success. This is called for + * TTL=0, after the message has been sent, or when message is saved, to unlock the send() + * method. + */ +- (void)willSendDataMessageSuccess:(GtalkDataMessageStanza *)stanza + withMessageId:(NSString *)messageId { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeDataMessageManager010, + @"send message success: %@", messageId); + [self.delegate willSendDataMessageWithID:messageId error:nil]; +} + +/** + * We send 'send failures' from server as normal FIRMessaging messages, with a 'message_type' + * extra - same as 'message deleted'. + * + * For TTL=0 or errors that can be detected during send ( too many messages, invalid, etc) + * we throw IOExceptions + */ +- (void)willSendDataMessageFail:(GtalkDataMessageStanza *)stanza + withMessageId:(NSString *)messageId + error:(FIRMessagingInternalErrorCode)errorCode { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeDataMessageManager011, + @"Send message fail: %@ error: %lu", messageId, (unsigned long)errorCode); + + NSError *error = [NSError errorWithFCMErrorCode:errorCode]; + if ([self.delegate respondsToSelector:@selector(willSendDataMessageWithID:error:)]) { + [self.delegate willSendDataMessageWithID:messageId error:error]; + } +} + +- (void)resendMessagesWithConnection:(FIRMessagingConnection *)connection { + NSMutableString *rmqIdsResent = [NSMutableString string]; + NSMutableArray *toRemoveRmqIds = [NSMutableArray array]; + FIRMessaging_WEAKIFY(self); + FIRMessaging_WEAKIFY(connection); + FIRMessagingRmqMessageHandler messageHandler = ^(int64_t rmqId, int8_t tag, NSData *data) { + FIRMessaging_STRONGIFY(self); + FIRMessaging_STRONGIFY(connection); + GPBMessage *proto = + [FIRMessagingGetClassForTag((FIRMessagingProtoTag)tag) parseFromData:data error:NULL]; + if ([proto isKindOfClass:GtalkDataMessageStanza.class]) { + GtalkDataMessageStanza *stanza = (GtalkDataMessageStanza *)proto; + + if (![self handleExpirationForDataMessage:stanza]) { + // time expired let's delete from RMQ + [toRemoveRmqIds addObject:stanza.persistentId]; + return; + } + [rmqIdsResent appendString:[NSString stringWithFormat:@"%@,", stanza.id_p]]; + } + + [connection sendProto:proto]; + }; + [self.rmq2Manager scanWithRmqMessageHandler:messageHandler + dataMessageHandler:nil]; + + if ([rmqIdsResent length]) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeDataMessageManager012, @"Resent: %@", + rmqIdsResent); + } + + if ([toRemoveRmqIds count]) { + [self.rmq2Manager removeRmqMessagesWithRmqIds:toRemoveRmqIds]; + } +} + +/** + * Check the TTL and generate an error if needed. + * + * @return false if the message needs to be deleted + */ +- (BOOL)handleExpirationForDataMessage:(GtalkDataMessageStanza *)message { + if (message.ttl == 0) { + return NO; + } + + int64_t now = FIRMessagingCurrentTimestampInSeconds(); + if (now > message.sent + message.ttl) { + [self willSendDataMessageFail:message + withMessageId:message.id_p + error:kFIRMessagingErrorServiceNotAvailable]; + return NO; + } + return YES; +} + +#pragma mark - Private + +- (int)delayForMessage:(NSMutableDictionary *)message { + int delay = 0; // default + if (message[kFIRMessagingSendDelay]) { + delay = [message[kFIRMessagingSendDelay] intValue]; + [message removeObjectForKey:kFIRMessagingSendDelay]; + if (delay < kMinDelaySeconds) { + delay = 0; + } else if (delay > kMaxDelaySeconds) { + delay = kMaxDelaySeconds; + } + } + return delay; +} + +// return True if successfully delayed else False +- (BOOL)delayMessage:(GtalkDataMessageStanza *)message { + return [self.delayedMessagesQueue queueMessage:message]; +} + +- (BOOL)tryToSendDataMessageStanza:(GtalkDataMessageStanza *)stanza { + if (self.client.isConnectionActive) { + [self.client sendMessage:stanza]; + return YES; + } + + // if we only reconnect for TTL = 0 messages check if we ttl = 0 or + // if we reconnect for all messages try to reconnect + if ((self.upstreamForceReconnect == kUpstreamForceReconnectTTL0 && stanza.ttl == 0) || + self.upstreamForceReconnect == kUpstreamForceReconnectAll) { + BOOL isNetworkAvailable = [[FIRMessaging messaging] isNetworkAvailable]; + if (isNetworkAvailable) { + if (stanza.ttl == 0) { + // Add TTL = 0 messages to be sent on next connect. TTL != 0 messages are + // persisted, and will be sent from the RMQ. + [self.client sendOnConnectOrDrop:stanza]; + } + + [self.client retryConnectionImmediately:YES]; + return YES; + } + } + return NO; +} + +- (NSString *)categoryForUpstreamMessages { + return FIRMessagingAppIdentifier(); +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingDefines.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingDefines.h new file mode 100644 index 00000000..abf79a57 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingDefines.h @@ -0,0 +1,84 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#ifndef FIRMessaging_xcodeproj_FIRMessagingDefines_h +#define FIRMessaging_xcodeproj_FIRMessagingDefines_h + +#define _FIRMessaging_VERBOSE_LOGGING 1 + +// Verbose Logging +#if (_FIRMessaging_VERBOSE_LOGGING) +#define FIRMessaging_DEV_VERBOSE_LOG(...) NSLog(__VA_ARGS__) +#else +#define FIRMessaging_DEV_VERBOSE_LOG(...) do { } while (0) +#endif // FIRMessaging_VERBOSE_LOGGING + + +// WEAKIFY & STRONGIFY +// Helper macro. +#define _FIRMessaging_WEAKNAME(VAR) VAR ## _weak_ + +#define FIRMessaging_WEAKIFY(VAR) __weak __typeof__(VAR) _FIRMessaging_WEAKNAME(VAR) = (VAR); + +#define FIRMessaging_STRONGIFY(VAR) \ +_Pragma("clang diagnostic push") \ +_Pragma("clang diagnostic ignored \"-Wshadow\"") \ +__strong __typeof__(VAR) VAR = _FIRMessaging_WEAKNAME(VAR); \ +_Pragma("clang diagnostic pop") + + +// Type Conversions (used for NSInteger etc) +#ifndef _FIRMessaging_L +#define _FIRMessaging_L(v) (long)(v) +#endif + +#ifndef _FIRMessaging_UL +#define _FIRMessaging_UL(v) (unsigned long)(v) +#endif + +#endif + +// Debug Assert +#ifndef _FIRMessagingDevAssert +// we directly invoke the NSAssert handler so we can pass on the varargs +// (NSAssert doesn't have a macro we can use that takes varargs) +#ifdef DEBUG +#define _FIRMessagingDevAssert(condition, ...) \ + do { \ + if (!(condition)) { \ + [[NSAssertionHandler currentHandler] \ + handleFailureInFunction:(NSString *) \ + [NSString stringWithUTF8String:__PRETTY_FUNCTION__] \ + file:(NSString *)[NSString stringWithUTF8String:__FILE__] \ + lineNumber:__LINE__ \ + description:__VA_ARGS__]; \ + } \ + } while(0) +#else // !defined(DEBUG) +#define _FIRMessagingDevAssert(condition, ...) do { } while (0) +#endif // !defined(DEBUG) + +#endif // _FIRMessagingDevAssert + +// Invalidates the initializer from which it's called. +#ifndef FIRMessagingInvalidateInitializer +#define FIRMessagingInvalidateInitializer() \ + do { \ + [self class]; /* Avoid warning of dead store to |self|. */ \ + _FIRMessagingDevAssert(NO, @"Invalid initializer."); \ + return nil; \ + } while (0) +#endif diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingDelayedMessageQueue.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingDelayedMessageQueue.h new file mode 100644 index 00000000..d20ec916 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingDelayedMessageQueue.h @@ -0,0 +1,35 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class GtalkDataMessageStanza; +@class FIRMessagingRmqManager; + +@protocol FIRMessagingRmqScanner; + +typedef void(^FIRMessagingSendDelayedMessagesHandler)(NSArray *messages); + +@interface FIRMessagingDelayedMessageQueue : NSObject + +- (instancetype)initWithRmqScanner:(id)rmqScanner + sendDelayedMessagesHandler:(FIRMessagingSendDelayedMessagesHandler)sendDelayedMessagesHandler; + +- (BOOL)queueMessage:(GtalkDataMessageStanza *)message; + +- (NSArray *)removeDelayedMessages; + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingDelayedMessageQueue.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingDelayedMessageQueue.m new file mode 100644 index 00000000..0371c020 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingDelayedMessageQueue.m @@ -0,0 +1,146 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingDelayedMessageQueue.h" + +#import "Protos/GtalkCore.pbobjc.h" + +#import "FIRMessagingDefines.h" +#import "FIRMessagingRmqManager.h" +#import "FIRMessagingUtilities.h" + +static const int kMaxQueuedMessageCount = 10; + +@interface FIRMessagingDelayedMessageQueue () + +@property(nonatomic, readonly, weak) id rmqScanner; +@property(nonatomic, readonly, copy) FIRMessagingSendDelayedMessagesHandler sendDelayedMessagesHandler; + +@property(nonatomic, readwrite, assign) int persistedMessageCount; +// the scheduled timeout or -1 if not set +@property(nonatomic, readwrite, assign) int64_t scheduledTimeoutMilliseconds; +// The time of the last scan of the message DB, +// used to avoid retrieving messages more than once. +@property(nonatomic, readwrite, assign) int64_t lastDBScanTimestampSeconds; + +@property(nonatomic, readwrite, strong) NSMutableArray *messages; +@property(nonatomic, readwrite, strong) NSTimer *sendTimer; + +@end + +@implementation FIRMessagingDelayedMessageQueue + +- (instancetype)init { + FIRMessagingInvalidateInitializer(); +} + +- (instancetype)initWithRmqScanner:(id)rmqScanner + sendDelayedMessagesHandler:(FIRMessagingSendDelayedMessagesHandler)sendDelayedMessagesHandler { + _FIRMessagingDevAssert(sendDelayedMessagesHandler, @"Invalid nil callback for delayed messages"); + self = [super init]; + if (self) { + _rmqScanner = rmqScanner; + _sendDelayedMessagesHandler = sendDelayedMessagesHandler; + _messages = [NSMutableArray arrayWithCapacity:10]; + _scheduledTimeoutMilliseconds = -1; + } + return self; +} + +- (BOOL)queueMessage:(GtalkDataMessageStanza *)message { + if (self.messages.count >= kMaxQueuedMessageCount) { + return NO; + } + if (message.ttl == 0) { + // ttl=0 messages aren't persisted, add it to memory + [self.messages addObject:message]; + } else { + self.persistedMessageCount++; + } + int64_t timeoutMillis = [self calculateTimeoutInMillisWithDelayInSeconds:message.maxDelay]; + if (![self isTimeoutScheduled] || timeoutMillis < self.scheduledTimeoutMilliseconds) { + [self scheduleTimeoutInMillis:timeoutMillis]; + } + return YES; +} + +- (NSArray *)removeDelayedMessages { + [self cancelTimeout]; + if ([self messageCount] == 0) { + return @[]; + } + + NSMutableArray *delayedMessages = [NSMutableArray array]; + // add the ttl=0 messages + if (self.messages.count) { + [delayedMessages addObjectsFromArray:delayedMessages]; + [self.messages removeAllObjects]; + } + + // add persistent messages + if (self.persistedMessageCount > 0) { + FIRMessaging_WEAKIFY(self); + [self.rmqScanner scanWithRmqMessageHandler:nil + dataMessageHandler:^(int64_t rmqId, GtalkDataMessageStanza *stanza) { + FIRMessaging_STRONGIFY(self); + if ([stanza hasMaxDelay] && + [stanza sent] >= self.lastDBScanTimestampSeconds) { + [delayedMessages addObject:stanza]; + } + }]; + self.lastDBScanTimestampSeconds = FIRMessagingCurrentTimestampInSeconds(); + self.persistedMessageCount = 0; + } + return delayedMessages; +} + +- (void)sendMessages { + if (self.sendDelayedMessagesHandler) { + self.sendDelayedMessagesHandler([self removeDelayedMessages]); + } +} + +#pragma mark - Private + +- (NSInteger)messageCount { + return self.messages.count + self.persistedMessageCount; +} + +- (BOOL)isTimeoutScheduled { + return self.scheduledTimeoutMilliseconds > 0; +} + +- (int64_t)calculateTimeoutInMillisWithDelayInSeconds:(int)delay { + return FIRMessagingCurrentTimestampInMilliseconds() + delay * 1000.0; +} + +- (void)scheduleTimeoutInMillis:(int64_t)time { + [self cancelTimeout]; + self.scheduledTimeoutMilliseconds = time; + double delay = (time - FIRMessagingCurrentTimestampInMilliseconds()) / 1000.0; + [self performSelector:@selector(sendMessages) withObject:self afterDelay:delay]; +} + +- (void)cancelTimeout { + if ([self isTimeoutScheduled]) { + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(sendMessages) + object:nil]; + self.scheduledTimeoutMilliseconds = -1; + } +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingLogger.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingLogger.h new file mode 100644 index 00000000..223ac9c5 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingLogger.h @@ -0,0 +1,67 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMMessageCode.h" + +// The convenience macros are only defined if they haven't already been defined. +#ifndef FIRMessagingLoggerInfo + +// Convenience macros that log to the shared FIRMessagingLogger instance. These macros +// are how users should typically log to FIRMessagingLogger. +#define FIRMessagingLoggerDebug(code, ...) \ + [FIRMessagingSharedLogger() logFuncDebug:__func__ messageCode:code msg:__VA_ARGS__] +#define FIRMessagingLoggerInfo(code, ...) \ + [FIRMessagingSharedLogger() logFuncInfo:__func__ messageCode:code msg:__VA_ARGS__] +#define FIRMessagingLoggerNotice(code, ...) \ + [FIRMessagingSharedLogger() logFuncNotice:__func__ messageCode:code msg:__VA_ARGS__] +#define FIRMessagingLoggerWarn(code, ...) \ + [FIRMessagingSharedLogger() logFuncWarning:__func__ messageCode:code msg:__VA_ARGS__] +#define FIRMessagingLoggerError(code, ...) \ + [FIRMessagingSharedLogger() logFuncError:__func__ messageCode:code msg:__VA_ARGS__] + +#endif // !defined(FIRMessagingLoggerInfo) + +@interface FIRMessagingLogger : NSObject + +- (void)logFuncDebug:(const char *)func + messageCode:(FIRMessagingMessageCode)messageCode + msg:(NSString *)fmt, ... NS_FORMAT_FUNCTION(3, 4); + +- (void)logFuncInfo:(const char *)func + messageCode:(FIRMessagingMessageCode)messageCode + msg:(NSString *)fmt, ... NS_FORMAT_FUNCTION(3, 4); + +- (void)logFuncNotice:(const char *)func + messageCode:(FIRMessagingMessageCode)messageCode + msg:(NSString *)fmt, ... NS_FORMAT_FUNCTION(3, 4); + +- (void)logFuncWarning:(const char *)func + messageCode:(FIRMessagingMessageCode)messageCode + msg:(NSString *)fmt, ... NS_FORMAT_FUNCTION(3, 4); + +- (void)logFuncError:(const char *)func + messageCode:(FIRMessagingMessageCode)messageCode + msg:(NSString *)fmt, ... NS_FORMAT_FUNCTION(3, 4); + +@end + +/** + * Instantiates and/or returns a shared FIRMessagingLogger used exclusively + * for FIRMessaging log messages. + * + * @return the shared FIRMessagingLogger instance + */ +FIRMessagingLogger *FIRMessagingSharedLogger(void); diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingLogger.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingLogger.m new file mode 100644 index 00000000..62eb8dae --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingLogger.m @@ -0,0 +1,93 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingLogger.h" + +#import + +@implementation FIRMessagingLogger + ++ (instancetype)standardLogger { + return [[FIRMessagingLogger alloc] init]; +} + +#pragma mark - Log Helpers + ++ (NSString *)formatMessageCode:(FIRMessagingMessageCode)messageCode { + return [NSString stringWithFormat:@"I-FCM%06ld", (long)messageCode]; +} + +- (void)logFuncDebug:(const char *)func + messageCode:(FIRMessagingMessageCode)messageCode + msg:(NSString *)fmt, ... { + va_list args; + va_start(args, fmt); + FIRLogBasic(FIRLoggerLevelDebug, kFIRLoggerMessaging, + [FIRMessagingLogger formatMessageCode:messageCode], fmt, args); + va_end(args); +} + +- (void)logFuncInfo:(const char *)func + messageCode:(FIRMessagingMessageCode)messageCode + msg:(NSString *)fmt, ... { + va_list args; + va_start(args, fmt); + FIRLogBasic(FIRLoggerLevelInfo, kFIRLoggerMessaging, + [FIRMessagingLogger formatMessageCode:messageCode], fmt, args); + va_end(args); +} + +- (void)logFuncNotice:(const char *)func + messageCode:(FIRMessagingMessageCode)messageCode + msg:(NSString *)fmt, ... { + va_list args; + va_start(args, fmt); + FIRLogBasic(FIRLoggerLevelNotice, kFIRLoggerMessaging, + [FIRMessagingLogger formatMessageCode:messageCode], fmt, args); + va_end(args); +} + +- (void)logFuncWarning:(const char *)func + messageCode:(FIRMessagingMessageCode)messageCode + msg:(NSString *)fmt, ... { + va_list args; + va_start(args, fmt); + FIRLogBasic(FIRLoggerLevelWarning, kFIRLoggerMessaging, + [FIRMessagingLogger formatMessageCode:messageCode], fmt, args); + va_end(args); +} + +- (void)logFuncError:(const char *)func + messageCode:(FIRMessagingMessageCode)messageCode + msg:(NSString *)fmt, ... { + va_list args; + va_start(args, fmt); + FIRLogBasic(FIRLoggerLevelError, kFIRLoggerMessaging, + [FIRMessagingLogger formatMessageCode:messageCode], fmt, args); + va_end(args); +} + +@end + +FIRMessagingLogger *FIRMessagingSharedLogger(void) { + static dispatch_once_t onceToken; + static FIRMessagingLogger *logger; + dispatch_once(&onceToken, ^{ + logger = [FIRMessagingLogger standardLogger]; + }); + + return logger; +} diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPacketQueue.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPacketQueue.h new file mode 100644 index 00000000..1f528abb --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPacketQueue.h @@ -0,0 +1,43 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@interface FIRMessagingPacket : NSObject + ++ (FIRMessagingPacket *)packetWithTag:(int8_t)tag rmqId:(NSString *)rmqId data:(NSData *)data; + +@property(nonatomic, readonly, strong) NSData *data; +@property(nonatomic, readonly, assign) int8_t tag; +// not sent over the wire required for bookkeeping +@property(nonatomic, readonly, assign) NSString *rmqId; + +@end + + +/** + * A queue of the packets(protos) that need to be send over the wire. + */ +@interface FIRMessagingPacketQueue : NSObject + +@property(nonatomic, readonly, assign) NSUInteger count; +@property(nonatomic, readonly, assign) BOOL isEmpty; + +- (void)push:(FIRMessagingPacket *)packet; +- (void)pushHead:(FIRMessagingPacket *)packet; +- (FIRMessagingPacket *)pop; + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPacketQueue.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPacketQueue.m new file mode 100644 index 00000000..2b3410a3 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPacketQueue.m @@ -0,0 +1,103 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingPacketQueue.h" + +#import "FIRMessagingDefines.h" + +@interface FIRMessagingPacket () + +@property(nonatomic, readwrite, strong) NSData *data; +@property(nonatomic, readwrite, assign) int8_t tag; +@property(nonatomic, readwrite, assign) NSString *rmqId; + +@end + +@implementation FIRMessagingPacket + ++ (FIRMessagingPacket *)packetWithTag:(int8_t)tag rmqId:(NSString *)rmqId data:(NSData *)data { + return [[self alloc] initWithTag:tag rmqId:rmqId data:data]; +} + +- (instancetype)init { + FIRMessagingInvalidateInitializer(); +} + +- (instancetype)initWithTag:(int8_t)tag rmqId:(NSString *)rmqId data:(NSData *)data { + self = [super init]; + if (self != nil) { + _data = data; + _tag = tag; + _rmqId = rmqId; + } + return self; +} + +- (NSString *)description { + if ([self.rmqId length]) { + return [NSString stringWithFormat:@", RmqId - %@", + self.tag, _FIRMessaging_UL(self.data.length), self.rmqId]; + } else { + return [NSString stringWithFormat:@"", + self.tag, _FIRMessaging_UL(self.data.length)]; + } +} + +@end + +@interface FIRMessagingPacketQueue () + +@property(nonatomic, readwrite, strong) NSMutableArray *packetsContainer; + +@end + + +@implementation FIRMessagingPacketQueue; + +- (id)init { + self = [super init]; + if (self) { + _packetsContainer = [[NSMutableArray alloc] init]; + } + return self; +} + +- (BOOL)isEmpty { + return self.packetsContainer.count == 0; +} + +- (NSUInteger)count { + return self.packetsContainer.count; +} + +- (void)push:(FIRMessagingPacket *)packet { + [self.packetsContainer addObject:packet]; +} + +- (void)pushHead:(FIRMessagingPacket *)packet { + [self.packetsContainer insertObject:packet atIndex:0]; +} + +- (FIRMessagingPacket *)pop { + if (!self.isEmpty) { + FIRMessagingPacket *packet = self.packetsContainer[0]; + [self.packetsContainer removeObjectAtIndex:0]; + return packet; + } + return nil; +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPendingTopicsList.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPendingTopicsList.h new file mode 100644 index 00000000..a8108bf9 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPendingTopicsList.h @@ -0,0 +1,119 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import "FIRMessaging.h" +#import "FIRMessagingTopicsCommon.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * Represents a single batch of topics, with the same action. + * + * Topic operations which have the same action (subscribe or unsubscribe) can be executed + * simultaneously, as the order of operations do not matter with the same action. The set of + * topics is unique, as it doesn't make sense to apply the same action to the same topic + * repeatedly; the result would be the same as the first time. + */ +@interface FIRMessagingTopicBatch : NSObject + +@property(nonatomic, readonly, assign) FIRMessagingTopicAction action; +@property(nonatomic, readonly, copy) NSMutableSet *topics; + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithAction:(FIRMessagingTopicAction)action NS_DESIGNATED_INITIALIZER; + +@end + +@class FIRMessagingPendingTopicsList; +/** + * This delegate must be supplied to the instance of FIRMessagingPendingTopicsList, via the + * @cdelegate property. It lets the + * pending topics list know whether or not it can begin making requests via + * @c-pendingTopicsListCanRequestTopicUpdates:, and handles the request to actually + * perform the topic operation. The delegate also handles when the pending topics list is updated, + * so that it can be archived or persisted. + * + * @see FIRMessagingPendingTopicsList + */ +@protocol FIRMessagingPendingTopicsListDelegate + +- (void)pendingTopicsList:(FIRMessagingPendingTopicsList *)list + requestedUpdateForTopic:(NSString *)topic + action:(FIRMessagingTopicAction)action + completion:(FIRMessagingTopicOperationCompletion)completion; +- (void)pendingTopicsListDidUpdate:(FIRMessagingPendingTopicsList *)list; +- (BOOL)pendingTopicsListCanRequestTopicUpdates:(FIRMessagingPendingTopicsList *)list; + +@end + +/** + * FIRMessagingPendingTopicsList manages a list of topic subscription updates, batched by the same + * action (subscribe or unsubscribe). The list roughly maintains the order of the topic operations, + * batched together whenever the topic action (subscribe or unsubscribe) changes. + * + * Topics operations are batched by action because it is safe to perform the same topic action + * (subscribe or unsubscribe) on many topics simultaneously. After each batch is successfully + * completed, the next batch operations can begin. + * + * When asked to resume its operations, FIRMessagingPendingTopicsList will begin performing updates + * of its current batch of topics. For example, it may begin subscription operations for topics + * [A, B, C] simultaneously. + * + * When the current batch is completed, the next batch of operations will be started. For example + * the list may begin unsubscribe operations for [D, A, E]. Note that because A is in both batches, + * A will be correctly subscribed in the first batch, then unsubscribed as part of the second batch + * of operations. Without batching, it would be ambiguous whether A's subscription operation or the + * unsubscription operation would be completed first. + * + * An app can subscribe and unsubscribe from many topics, and this class helps persist the pending + * topics and perform the operation safely and correctly. + * + * When a topic fails to subscribe or unsubscribe due to a network error, it is considered a + * recoverable error, and so it remains in the current batch until it is succesfully completed. + * Topic updates are completed when they either (a) succeed, (b) are cancelled, or (c) result in an + * unrecoverable error. Any error outside of `NSURLErrorDomain` is considered an unrecoverable + * error. + * + * In addition to maintaining the list of pending topic updates, FIRMessagingPendingTopicsList also + * can track completion handlers for topic operations. + * + * @discussion Completion handlers for topic updates are not maintained if it was restored from a + * keyed archive. They are only called if the topic operation finished within the same app session. + * + * You must supply an object conforming to FIRMessagingPendingTopicsListDelegate in order for the + * topic operations to execute. + * + * @see FIRMessagingPendingTopicsListDelegate + */ +@interface FIRMessagingPendingTopicsList : NSObject + +@property(nonatomic, weak) NSObject *delegate; + +@property(nonatomic, readonly, strong, nullable) NSDate *archiveDate; +@property(nonatomic, readonly) NSUInteger numberOfBatches; + + +- (instancetype)init NS_DESIGNATED_INITIALIZER; +- (void)addOperationForTopic:(NSString *)topic + withAction:(FIRMessagingTopicAction)action + completion:(nullable FIRMessagingTopicOperationCompletion)completion; +- (void)resumeOperationsIfNeeded; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPendingTopicsList.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPendingTopicsList.m new file mode 100644 index 00000000..b10b5522 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPendingTopicsList.m @@ -0,0 +1,265 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingPendingTopicsList.h" + +#import "FIRMessaging_Private.h" +#import "FIRMessagingLogger.h" +#import "FIRMessagingPubSub.h" + +#import "FIRMessagingDefines.h" + +NSString *const kPendingTopicBatchActionKey = @"action"; +NSString *const kPendingTopicBatchTopicsKey = @"topics"; + +NSString *const kPendingBatchesEncodingKey = @"batches"; +NSString *const kPendingTopicsTimestampEncodingKey = @"ts"; + +#pragma mark - FIRMessagingTopicBatch + +@interface FIRMessagingTopicBatch () + +@property(nonatomic, strong, nonnull) NSMutableDictionary + *> *topicHandlers; + +@end + +@implementation FIRMessagingTopicBatch + +- (instancetype)initWithAction:(FIRMessagingTopicAction)action { + if (self = [super init]) { + _action = action; + _topics = [NSMutableSet set]; + _topicHandlers = [NSMutableDictionary dictionary]; + } + return self; +} + +#pragma mark NSCoding + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeInteger:self.action forKey:kPendingTopicBatchActionKey]; + [aCoder encodeObject:self.topics forKey:kPendingTopicBatchTopicsKey]; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + + // Ensure that our integer -> enum casting is safe + NSInteger actionRawValue = [aDecoder decodeIntegerForKey:kPendingTopicBatchActionKey]; + FIRMessagingTopicAction action = FIRMessagingTopicActionSubscribe; + if (actionRawValue == FIRMessagingTopicActionUnsubscribe) { + action = FIRMessagingTopicActionUnsubscribe; + } + + if (self = [self initWithAction:action]) { + NSSet *topics = [aDecoder decodeObjectForKey:kPendingTopicBatchTopicsKey]; + if ([topics isKindOfClass:[NSSet class]]) { + _topics = [topics mutableCopy]; + } + _topicHandlers = [NSMutableDictionary dictionary]; + } + return self; +} + +@end + +#pragma mark - FIRMessagingPendingTopicsList + +@interface FIRMessagingPendingTopicsList () + +@property(nonatomic, readwrite, strong) NSDate *archiveDate; +@property(nonatomic, strong) NSMutableArray *topicBatches; + +@property(nonatomic, strong) FIRMessagingTopicBatch *currentBatch; +@property(nonatomic, strong) NSMutableSet *topicsInFlight; + +@end + +@implementation FIRMessagingPendingTopicsList + +- (instancetype)init { + if (self = [super init]) { + _topicBatches = [NSMutableArray array]; + _topicsInFlight = [NSMutableSet set]; + } + return self; +} + ++ (void)pruneTopicBatches:(NSMutableArray *)topicBatches { + // For now, just remove empty batches. In the future we can use this to make the subscriptions + // more efficient, by actually pruning topic actions that cancel each other out, for example. + for (NSInteger i = topicBatches.count-1; i >= 0; i--) { + FIRMessagingTopicBatch *batch = topicBatches[i]; + if (batch.topics.count == 0) { + [topicBatches removeObjectAtIndex:i]; + } + } +} + +#pragma mark NSCoding + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:[NSDate date] forKey:kPendingTopicsTimestampEncodingKey]; + [aCoder encodeObject:self.topicBatches forKey:kPendingBatchesEncodingKey]; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { + + if (self = [self init]) { + _archiveDate = [aDecoder decodeObjectForKey:kPendingTopicsTimestampEncodingKey]; + NSArray *archivedBatches = [aDecoder decodeObjectForKey:kPendingBatchesEncodingKey]; + if (archivedBatches) { + _topicBatches = [archivedBatches mutableCopy]; + [FIRMessagingPendingTopicsList pruneTopicBatches:_topicBatches]; + } + _topicsInFlight = [NSMutableSet set]; + } + return self; +} + +#pragma mark Getters + +- (NSUInteger)numberOfBatches { + return self.topicBatches.count; +} + +#pragma mark Adding/Removing topics + +- (void)addOperationForTopic:(NSString *)topic + withAction:(FIRMessagingTopicAction)action + completion:(nullable FIRMessagingTopicOperationCompletion)completion { + + FIRMessagingTopicBatch *lastBatch = nil; + @synchronized (self) { + lastBatch = self.topicBatches.lastObject; + if (!lastBatch || lastBatch.action != action) { + // There either was no last batch, or our last batch's action was not the same, so we have to + // create a new batch + lastBatch = [[FIRMessagingTopicBatch alloc] initWithAction:action]; + [self.topicBatches addObject:lastBatch]; + } + BOOL topicExistedBefore = ([lastBatch.topics member:topic] != nil); + if (!topicExistedBefore) { + [lastBatch.topics addObject:topic]; + [self.delegate pendingTopicsListDidUpdate:self]; + } + // Add the completion handler to the batch + if (completion) { + NSMutableArray *handlers = lastBatch.topicHandlers[topic]; + if (!handlers) { + handlers = [[NSMutableArray alloc] init]; + } + [handlers addObject:completion]; + lastBatch.topicHandlers[topic] = handlers; + } + if (!self.currentBatch) { + self.currentBatch = lastBatch; + } + // This may have been the first topic added, or was added to an ongoing batch + if (self.currentBatch == lastBatch && !topicExistedBefore) { + // Add this topic to our ongoing operations + FIRMessaging_WEAKIFY(self); + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ + FIRMessaging_STRONGIFY(self); + [self resumeOperationsIfNeeded]; + }); + } + } +} + +- (void)resumeOperationsIfNeeded { + @synchronized (self) { + // If current batch is not set, set it now + if (!self.currentBatch) { + self.currentBatch = self.topicBatches.firstObject; + } + if (self.currentBatch.topics.count == 0) { + return; + } + if (!self.delegate) { + FIRMessagingLoggerError(kFIRMessagingMessageCodePendingTopicsList000, + @"Attempted to update pending topics without a delegate"); + return; + } + if (![self.delegate pendingTopicsListCanRequestTopicUpdates:self]) { + return; + } + for (NSString *topic in self.currentBatch.topics) { + if ([self.topicsInFlight member:topic]) { + // This topic is already active, so skip + continue; + } + [self beginUpdateForCurrentBatchTopic:topic]; + } + } +} + +- (BOOL)subscriptionErrorIsRecoverable:(NSError *)error { + return [error.domain isEqualToString:NSURLErrorDomain]; +} + +- (void)beginUpdateForCurrentBatchTopic:(NSString *)topic { + + @synchronized (self) { + [self.topicsInFlight addObject:topic]; + } + FIRMessaging_WEAKIFY(self); + [self.delegate + pendingTopicsList:self + requestedUpdateForTopic:topic + action:self.currentBatch.action + completion:^(NSError *error) { + dispatch_async( + dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ + FIRMessaging_STRONGIFY(self); + @synchronized(self) { + [self.topicsInFlight removeObject:topic]; + + BOOL recoverableError = [self subscriptionErrorIsRecoverable:error]; + if (!error || !recoverableError) { + // Notify our handlers and remove the topic from our batch + NSMutableArray *handlers = self.currentBatch.topicHandlers[topic]; + if (handlers.count) { + dispatch_async(dispatch_get_main_queue(), ^{ + for (FIRMessagingTopicOperationCompletion handler in handlers) { + handler(error); + } + [handlers removeAllObjects]; + }); + } + [self.currentBatch.topics removeObject:topic]; + [self.currentBatch.topicHandlers removeObjectForKey:topic]; + if (self.currentBatch.topics.count == 0) { + // All topic updates successfully finished in this batch, move on + // to the next batch + [self.topicBatches removeObject:self.currentBatch]; + self.currentBatch = nil; + } + [self.delegate pendingTopicsListDidUpdate:self]; + FIRMessaging_WEAKIFY(self); + dispatch_async( + dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), + ^{ + FIRMessaging_STRONGIFY(self); + [self resumeOperationsIfNeeded]; + }); + } + } + }); + }]; +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPersistentSyncMessage.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPersistentSyncMessage.h new file mode 100644 index 00000000..5a48e998 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPersistentSyncMessage.h @@ -0,0 +1,28 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@interface FIRMessagingPersistentSyncMessage : NSObject + +@property(nonatomic, readonly, strong) NSString *rmqID; +@property(nonatomic, readwrite, assign) BOOL apnsReceived; +@property(nonatomic, readwrite, assign) BOOL mcsReceived; +@property(nonatomic, readonly, assign) int64_t expirationTime; + +- (instancetype)initWithRMQID:(NSString *)rmqID expirationTime:(int64_t)expirationTime; + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPersistentSyncMessage.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPersistentSyncMessage.m new file mode 100644 index 00000000..bf7d05b4 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPersistentSyncMessage.m @@ -0,0 +1,54 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingPersistentSyncMessage.h" + +#import "FIRMessagingDefines.h" + +@interface FIRMessagingPersistentSyncMessage () + +@property(nonatomic, readwrite, strong) NSString *rmqID; +@property(nonatomic, readwrite, assign) int64_t expirationTime; + +@end + +@implementation FIRMessagingPersistentSyncMessage + +- (instancetype)init { + FIRMessagingInvalidateInitializer(); +} + +- (instancetype)initWithRMQID:(NSString *)rmqID expirationTime:(int64_t)expirationTime { + self = [super init]; + if (self) { + _rmqID = [rmqID copy]; + _expirationTime = expirationTime; + } + return self; +} + +- (NSString *)description { + NSString *classDescription = NSStringFromClass([self class]); + NSDate *date = [NSDate dateWithTimeIntervalSince1970:self.expirationTime]; + return [NSString stringWithFormat:@"%@: (rmqID: %@, apns: %d, mcs: %d, expiry: %@", + classDescription, self.rmqID, self.mcsReceived, self.apnsReceived, date]; +} + +- (NSString *)debugDescription { + return [self description]; +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPubSub.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPubSub.h new file mode 100644 index 00000000..2c2fbe62 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPubSub.h @@ -0,0 +1,171 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessaging.h" + +NS_ASSUME_NONNULL_BEGIN + +@class FIRMessagingClient; +@class FIRMessagingPubSubCache; + +/** + * FIRMessagingPubSub provides a publish-subscribe model for sending FIRMessaging topic messages. + * + * An app can subscribe to different topics defined by the + * developer. The app server can then send messages to the subscribed devices + * without having to maintain topic-subscribers mapping. Topics do not + * need to be explicitly created before subscribing or publishing—they + * are automatically created when publishing or subscribing. + * + * Messages published to the topic will be received as regular FIRMessaging messages + * with `"from"` set to `"/topics/myTopic"`. + * + * Only topic names that match the pattern `"/topics/[a-zA-Z0-9-_.~%]{1,900}"` + * are allowed for subscribing and publishing. + */ +@interface FIRMessagingPubSub : NSObject + +@property(nonatomic, readonly, strong) FIRMessagingPubSubCache *cache; +@property(nonatomic, readonly, strong) FIRMessagingClient *client; + +/** + * Initializes an instance of FIRMessagingPubSub. + * + * @return An instance of FIRMessagingPubSub. + */ +- (instancetype)initWithClient:(FIRMessagingClient *)client NS_DESIGNATED_INITIALIZER; + +/** + * Subscribes an app instance to a topic, enabling it to receive messages + * sent to that topic. + * + * This is an asynchronous call. If subscription fails, FIRMessaging + * invokes the completion callback with the appropriate error. + * + * @see FIRMessagingPubSub unsubscribeWithToken:topic:handler: + * + * @param token The registration token as received from the InstanceID + * library for a given `authorizedEntity` and "gcm" scope. + * @param topic The topic to subscribe to. Should be of the form + * `"/topics/"`. + * @param options Unused parameter, please pass nil or empty dictionary. + * @param handler The callback handler invoked when the subscribe call + * ends. In case of success, a nil error is returned. Otherwise, + * an appropriate error object is returned. + * @discussion This method is thread-safe. However, it is not guaranteed to + * return on the main thread. + */ +- (void)subscribeWithToken:(NSString *)token + topic:(NSString *)topic + options:(nullable NSDictionary *)options + handler:(FIRMessagingTopicOperationCompletion)handler; + +/** + * Unsubscribes an app instance from a topic, stopping it from receiving + * any further messages sent to that topic. + * + * This is an asynchronous call. If the attempt to unsubscribe fails, + * we invoke the `completion` callback passed in with an appropriate error. + * + * @param token The token used to subscribe to this topic. + * @param topic The topic to unsubscribe from. Should be of the form + * `"/topics/"`. + * @param options Unused parameter, please pass nil or empty dictionary. + * @param handler The handler that is invoked once the unsubscribe call ends. + * In case of success, nil error is returned. Otherwise, an + * appropriate error object is returned. + * @discussion This method is thread-safe. However, it is not guaranteed to + * return on the main thread. + */ +- (void)unsubscribeWithToken:(NSString *)token + topic:(NSString *)topic + options:(nullable NSDictionary *)options + handler:(FIRMessagingTopicOperationCompletion)handler; + +/** + * Asynchronously subscribe to the topic. Adds to the pending list of topic operations. + * Retry in case of failures. This makes a repeated attempt to subscribe to the topic + * as compared to the `subscribe` method above which tries once. + * + * @param topic The topic name to subscribe to. Should be of the form `"/topics/"`. + * @param handler The handler that is invoked once the unsubscribe call ends. + * In case of success, nil error is returned. Otherwise, an + * appropriate error object is returned. + */ +- (void)subscribeToTopic:(NSString *)topic + handler:(nullable FIRMessagingTopicOperationCompletion)handler; + +/** + * Asynchronously unsubscribe from the topic. Adds to the pending list of topic operations. + * Retry in case of failures. This makes a repeated attempt to unsubscribe from the topic + * as compared to the `unsubscribe` method above which tries once. + * + * @param topic The topic name to unsubscribe from. Should be of the form `"/topics/"`. + * @param handler The handler that is invoked once the unsubscribe call ends. + * In case of success, nil error is returned. Otherwise, an + * appropriate error object is returned. + */ +- (void)unsubscribeFromTopic:(NSString *)topic + handler:(nullable FIRMessagingTopicOperationCompletion)handler; + +/** + * Schedule subscriptions sync. + * + * @param immediately YES if the sync should be scheduled immediately else NO if we can delay + * the sync. + */ +- (void)scheduleSync:(BOOL)immediately; + +/** + * Adds the "/topics/" prefix to the topic. + * + * @param topic The topic to add the prefix to. + * + * @return The new topic name with the "/topics/" prefix added. + */ ++ (NSString *)addPrefixToTopic:(NSString *)topic; + +/** + * Removes the "/topics/" prefix from the topic. + * + * @param topic The topic to remove the prefix from. + * + * @return The new topic name with the "/topics/" prefix removed. + */ + ++ (NSString *)removePrefixFromTopic:(NSString *)topic; + +/** + * Check if the topic name has "/topics/" prefix. + * + * @param topic The topic name to verify. + * + * @return YES if the topic name has "/topics/" prefix else NO. + */ ++ (BOOL)hasTopicsPrefix:(NSString *)topic; + +/** + * Check if it's a valid topic name. This includes "/topics/" prefix in the topic name. + * + * @param topic The topic name to verify. + * + * @return YES if the topic name satisfies the regex "/topics/[a-zA-Z0-9-_.~%]{1,900}". + */ ++ (BOOL)isValidTopicWithPrefix:(NSString *)topic; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPubSub.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPubSub.m new file mode 100644 index 00000000..3f954e8a --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPubSub.m @@ -0,0 +1,280 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingPubSub.h" + +#import "FIRMessaging.h" +#import "FIRMessagingClient.h" +#import "FIRMessagingDefines.h" +#import "FIRMessagingLogger.h" +#import "FIRMessagingPendingTopicsList.h" +#import "FIRMessagingUtilities.h" +#import "FIRMessaging_Private.h" +#import "NSDictionary+FIRMessaging.h" +#import "NSError+FIRMessaging.h" + +static NSString *const kPendingSubscriptionsListKey = + @"com.firebase.messaging.pending-subscriptions"; + +@interface FIRMessagingPubSub () + +@property(nonatomic, readwrite, strong) FIRMessagingPendingTopicsList *pendingTopicUpdates; +@property(nonatomic, readwrite, strong) FIRMessagingClient *client; + +@end + +@implementation FIRMessagingPubSub + +- (instancetype)init { + FIRMessagingInvalidateInitializer(); + // Need this to disable an Xcode warning. + return [self initWithClient:nil]; +} + +- (instancetype)initWithClient:(FIRMessagingClient *)client { + self = [super init]; + if (self) { + _client = client; + [self restorePendingTopicsList]; + } + return self; +} + +- (void)subscribeWithToken:(NSString *)token + topic:(NSString *)topic + options:(NSDictionary *)options + handler:(FIRMessagingTopicOperationCompletion)handler { + _FIRMessagingDevAssert([token length], @"FIRMessaging error no token specified"); + _FIRMessagingDevAssert([topic length], @"FIRMessaging error Invalid empty topic specified"); + if (!self.client) { + handler([NSError errorWithFCMErrorCode:kFIRMessagingErrorCodePubSubFIRMessagingNotSetup]); + return; + } + + token = [token copy]; + topic = [topic copy]; + + if (![options count]) { + options = @{}; + } + + if (![[self class] isValidTopicWithPrefix:topic]) { + FIRMessagingLoggerError(kFIRMessagingMessageCodePubSub000, + @"Invalid FIRMessaging Pubsub topic %@", topic); + handler([NSError errorWithFCMErrorCode:kFIRMessagingErrorCodePubSubInvalidTopic]); + return; + } + + if (![self verifyPubSubOptions:options]) { + // we do not want to quit even if options have some invalid values. + FIRMessagingLoggerError(kFIRMessagingMessageCodePubSub001, + @"Invalid options passed to FIRMessagingPubSub with non-string keys or " + "values."); + } + // copy the dictionary would trim non-string keys or values if any. + options = [options fcm_trimNonStringValues]; + + [self.client updateSubscriptionWithToken:token + topic:topic + options:options + shouldDelete:NO + handler:^void(NSError *error) { + handler(error); + }]; +} + +- (void)unsubscribeWithToken:(NSString *)token + topic:(NSString *)topic + options:(NSDictionary *)options + handler:(FIRMessagingTopicOperationCompletion)handler { + _FIRMessagingDevAssert([token length], @"FIRMessaging error no token specified"); + _FIRMessagingDevAssert([topic length], @"FIRMessaging error Invalid empty topic specified"); + + if (!self.client) { + handler([NSError errorWithFCMErrorCode:kFIRMessagingErrorCodePubSubFIRMessagingNotSetup]); + return; + } + + token = [token copy]; + topic = [topic copy]; + if (![options count]) { + options = @{}; + } + + if (![[self class] isValidTopicWithPrefix:topic]) { + FIRMessagingLoggerError(kFIRMessagingMessageCodePubSub002, + @"Invalid FIRMessaging Pubsub topic %@", topic); + handler([NSError errorWithFCMErrorCode:kFIRMessagingErrorCodePubSubInvalidTopic]); + return; + } + if (![self verifyPubSubOptions:options]) { + // we do not want to quit even if options have some invalid values. + FIRMessagingLoggerError( + kFIRMessagingMessageCodePubSub003, + @"Invalid options passed to FIRMessagingPubSub with non-string keys or values."); + } + // copy the dictionary would trim non-string keys or values if any. + options = [options fcm_trimNonStringValues]; + + [self.client updateSubscriptionWithToken:token + topic:topic + options:options + shouldDelete:YES + handler:^void(NSError *error) { + handler(error); + }]; +} + +- (void)subscribeToTopic:(NSString *)topic + handler:(nullable FIRMessagingTopicOperationCompletion)handler { + [self.pendingTopicUpdates addOperationForTopic:topic + withAction:FIRMessagingTopicActionSubscribe + completion:handler]; +} + +- (void)unsubscribeFromTopic:(NSString *)topic + handler:(nullable FIRMessagingTopicOperationCompletion)handler { + [self.pendingTopicUpdates addOperationForTopic:topic + withAction:FIRMessagingTopicActionUnsubscribe + completion:handler]; +} + +- (void)scheduleSync:(BOOL)immediately { + NSString *fcmToken = [[FIRMessaging messaging] defaultFcmToken]; + if (fcmToken.length) { + [self.pendingTopicUpdates resumeOperationsIfNeeded]; + } +} + +#pragma mark - FIRMessagingPendingTopicsListDelegate + +- (void)pendingTopicsList:(FIRMessagingPendingTopicsList *)list + requestedUpdateForTopic:(NSString *)topic + action:(FIRMessagingTopicAction)action + completion:(FIRMessagingTopicOperationCompletion)completion { + + NSString *fcmToken = [[FIRMessaging messaging] defaultFcmToken]; + if (action == FIRMessagingTopicActionSubscribe) { + [self subscribeWithToken:fcmToken topic:topic options:nil handler:completion]; + } else { + [self unsubscribeWithToken:fcmToken topic:topic options:nil handler:completion]; + } +} + +- (void)pendingTopicsListDidUpdate:(FIRMessagingPendingTopicsList *)list { + [self archivePendingTopicsList:list]; +} + +- (BOOL)pendingTopicsListCanRequestTopicUpdates:(FIRMessagingPendingTopicsList *)list { + NSString *fcmToken = [[FIRMessaging messaging] defaultFcmToken]; + return (fcmToken.length > 0); +} + +#pragma mark - Storing Pending Topics + +- (void)archivePendingTopicsList:(FIRMessagingPendingTopicsList *)topicsList { + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + NSData *pendingData = [NSKeyedArchiver archivedDataWithRootObject:topicsList]; + [defaults setObject:pendingData forKey:kPendingSubscriptionsListKey]; + [defaults synchronize]; +} + +- (void)restorePendingTopicsList { + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + NSData *pendingData = [defaults objectForKey:kPendingSubscriptionsListKey]; + FIRMessagingPendingTopicsList *subscriptions; + @try { + if (pendingData) { + subscriptions = [NSKeyedUnarchiver unarchiveObjectWithData:pendingData]; + } + } @catch (NSException *exception) { + // Nothing we can do, just continue as if we don't have pending subscriptions + } @finally { + if (subscriptions) { + self.pendingTopicUpdates = subscriptions; + } else { + self.pendingTopicUpdates = [[FIRMessagingPendingTopicsList alloc] init]; + } + self.pendingTopicUpdates.delegate = self; + } +} + +#pragma mark - Private Helpers + +- (BOOL)verifyPubSubOptions:(NSDictionary *)options { + return ![options fcm_hasNonStringKeysOrValues]; +} + +#pragma mark - Topic Name Helpers + +static NSString *const kTopicsPrefix = @"/topics/"; +static NSString *const kTopicRegexPattern = @"/topics/([a-zA-Z0-9-_.~%]+)"; + ++ (NSString *)addPrefixToTopic:(NSString *)topic { + if (![self hasTopicsPrefix:topic]) { + return [NSString stringWithFormat:@"%@%@", kTopicsPrefix, topic]; + } else { + return [topic copy]; + } +} + ++ (NSString *)removePrefixFromTopic:(NSString *)topic { + if ([self hasTopicsPrefix:topic]) { + return [topic substringFromIndex:kTopicsPrefix.length]; + } else { + return [topic copy]; + } +} + ++ (BOOL)hasTopicsPrefix:(NSString *)topic { + return [topic hasPrefix:kTopicsPrefix]; +} + +/** + * Returns a regular expression for matching a topic sender. + * + * @return The topic matching regular expression + */ ++ (NSRegularExpression *)topicRegex { + // Since this is a static regex pattern, we only only need to declare it once. + static NSRegularExpression *topicRegex; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSError *error; + topicRegex = + [NSRegularExpression regularExpressionWithPattern:kTopicRegexPattern + options:NSRegularExpressionAnchorsMatchLines + error:&error]; + }); + return topicRegex; +} + +/** + * Gets the class describing occurences of topic names and sender IDs in the sender. + * + * @param expression The topic expression used to generate a pubsub topic + * + * @return Representation of captured subexpressions in topic regular expression + */ ++ (BOOL)isValidTopicWithPrefix:(NSString *)topic { + NSRange topicRange = NSMakeRange(0, topic.length); + NSRange regexMatchRange = [[self topicRegex] rangeOfFirstMatchInString:topic + options:NSMatchingAnchored + range:topicRange]; + return NSEqualRanges(topicRange, regexMatchRange); +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPubSubRegistrar.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPubSubRegistrar.h new file mode 100644 index 00000000..b51813f0 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPubSubRegistrar.h @@ -0,0 +1,56 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingTopicOperation.h" + +@class FIRMessagingCheckinService; + +@interface FIRMessagingPubSubRegistrar : NSObject + +/** + * Designated Initializer. + * + * @param checkinService The checkin service used to register with Checkin + * server. + * + * @return A new FIRMessagingPubSubRegistrar instance used to subscribe/unsubscribe. + */ +- (instancetype)initWithCheckinService:(FIRMessagingCheckinService *)checkinService; + +/** + * Stops all the subscription requests going on in parallel. This would + * invalidate all the handlers associated with the subscription requests. + */ +- (void)stopAllSubscriptionRequests; + +/** + * Update subscription status for a given topic with FIRMessaging's backend. + * + * @param topic The topic to subscribe to. + * @param token The registration token to be used. + * @param options The options to be passed in during subscription request. + * @param shouldDelete NO if the subscription is being added else YES if being + * removed. + * @param handler The handler invoked once the update subscription request + * finishes. + */ +- (void)updateSubscriptionToTopic:(NSString *)topic + withToken:(NSString *)token + options:(NSDictionary *)options + shouldDelete:(BOOL)shouldDelete + handler:(FIRMessagingTopicOperationCompletion)handler; + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPubSubRegistrar.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPubSubRegistrar.m new file mode 100644 index 00000000..6268302e --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingPubSubRegistrar.m @@ -0,0 +1,78 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingPubSubRegistrar.h" + +#import "FIRMessagingCheckinService.h" +#import "FIRMessagingDefines.h" +#import "FIRMessagingPubSubRegistrar.h" +#import "FIRMessagingTopicsCommon.h" +#import "NSError+FIRMessaging.h" + +@interface FIRMessagingPubSubRegistrar () + +@property(nonatomic, readwrite, strong) FIRMessagingCheckinService *checkinService; + +@property(nonatomic, readonly, strong) NSOperationQueue *topicOperations; +// Common errors, instantiated, to avoid generating multiple copies +@property(nonatomic, readwrite, strong) NSError *operationInProgressError; + +@end + +@implementation FIRMessagingPubSubRegistrar + +- (instancetype)init { + FIRMessagingInvalidateInitializer(); +} + +- (instancetype)initWithCheckinService:(FIRMessagingCheckinService *)checkinService { + self = [super init]; + if (self) { + _checkinService = checkinService; + _topicOperations = [[NSOperationQueue alloc] init]; + // Do 10 topic operations at a time; it's enough to keep the TCP connection to the host alive, + // saving hundreds of milliseconds on each request (compared to a serial queue). + _topicOperations.maxConcurrentOperationCount = 10; + } + return self; +} + +- (void)stopAllSubscriptionRequests { + [self.topicOperations cancelAllOperations]; +} + +- (void)updateSubscriptionToTopic:(NSString *)topic + withToken:(NSString *)token + options:(NSDictionary *)options + shouldDelete:(BOOL)shouldDelete + handler:(FIRMessagingTopicOperationCompletion)handler { + + FIRMessagingTopicAction action = FIRMessagingTopicActionSubscribe; + if (shouldDelete) { + action = FIRMessagingTopicActionUnsubscribe; + } + FIRMessagingTopicOperation *operation = + [[FIRMessagingTopicOperation alloc] initWithTopic:topic + action:action + token:token + options:options + checkinService:self.checkinService + completion:handler]; + [self.topicOperations addOperation:operation]; + +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingReceiver.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingReceiver.h new file mode 100644 index 00000000..e3124204 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingReceiver.h @@ -0,0 +1,34 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingDataMessageManager.h" +#import "FIRMessaging.h" + +@class FIRMessagingReceiver; +@protocol FIRMessagingReceiverDelegate + +- (void)receiver:(nonnull FIRMessagingReceiver *)receiver + receivedRemoteMessage:(nonnull FIRMessagingRemoteMessage *)remoteMessage; + +@end + +@interface FIRMessagingReceiver : NSObject + +@property(nonatomic, weak, nullable) id delegate; +/// Whether to use direct channel for direct channel message callback handler in all iOS versions. +@property(nonatomic, assign) BOOL useDirectChannel; + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingReceiver.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingReceiver.m new file mode 100644 index 00000000..ac8a6837 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingReceiver.m @@ -0,0 +1,182 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingReceiver.h" + +#import + +#import + +#import "FIRMessaging.h" +#import "FIRMessagingLogger.h" +#import "FIRMessagingUtilities.h" +#import "FIRMessaging_Private.h" + +static NSString *const kUpstreamMessageIDUserInfoKey = @"messageID"; +static NSString *const kUpstreamErrorUserInfoKey = @"error"; +/// "Should use Messaging delegate" key stored in NSUserDefaults +NSString *const kFIRMessagingUserDefaultsKeyUseMessagingDelegate = + @"com.firebase.messaging.useMessagingDelegate"; +/// "Should use Messaging Delegate" key stored in Info.plist +NSString *const kFIRMessagingPlistUseMessagingDelegate = + @"FirebaseMessagingUseMessagingDelegateForDirectChannel"; + +static int downstreamMessageID = 0; + +@implementation FIRMessagingReceiver + +#pragma mark - FIRMessagingDataMessageManager protocol + +- (void)didReceiveMessage:(NSDictionary *)message withIdentifier:(nullable NSString *)messageID { + if (![messageID length]) { + messageID = [[self class] nextMessageID]; + } + + NSInteger majorOSVersion = [[GULAppEnvironmentUtil systemVersion] integerValue]; + if (majorOSVersion >= 10 || self.useDirectChannel) { + // iOS 10 and above or use direct channel is enabled. + [self scheduleIos10NotificationForMessage:message withIdentifier:messageID]; + } else { + // Post notification directly to AppDelegate handlers. This is valid pre-iOS 10. + [self scheduleNotificationForMessage:message]; + } +} + +- (void)willSendDataMessageWithID:(NSString *)messageID error:(NSError *)error { + NSNotification *notification; + if (error) { + NSDictionary *userInfo = @{ + kUpstreamMessageIDUserInfoKey : [messageID copy], + kUpstreamErrorUserInfoKey : error + }; + notification = [NSNotification notificationWithName:FIRMessagingSendErrorNotification + object:nil + userInfo:userInfo]; + [[NSNotificationQueue defaultQueue] enqueueNotification:notification postingStyle:NSPostASAP]; + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeReceiver000, + @"Fail to send upstream message: %@ error: %@", messageID, error); + } else { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeReceiver001, @"Will send upstream message: %@", + messageID); + } +} + +- (void)didSendDataMessageWithID:(NSString *)messageID { + // invoke the callbacks asynchronously + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeReceiver002, @"Did send upstream message: %@", + messageID); + NSNotification * notification = + [NSNotification notificationWithName:FIRMessagingSendSuccessNotification + object:nil + userInfo:@{ kUpstreamMessageIDUserInfoKey : [messageID copy] }]; + + [[NSNotificationQueue defaultQueue] enqueueNotification:notification postingStyle:NSPostASAP]; +} + +- (void)didDeleteMessagesOnServer { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeReceiver003, + @"Will send deleted messages notification"); + NSNotification * notification = + [NSNotification notificationWithName:FIRMessagingMessagesDeletedNotification + object:nil]; + + [[NSNotificationQueue defaultQueue] enqueueNotification:notification postingStyle:NSPostASAP]; +} + +#pragma mark - Private Helpers +// As the new UserNotifications framework in iOS 10 doesn't support constructor/mutation for +// UNNotification object, FCM can't inject the message to the app with UserNotifications framework. +// Define our own protocol, which means app developers need to implement two interfaces to receive +// display notifications and data messages respectively for devices running iOS 10 or above. Devices +// running iOS 9 or below are not affected. +- (void)scheduleIos10NotificationForMessage:(NSDictionary *)message + withIdentifier:(NSString *)messageID { + FIRMessagingRemoteMessage *wrappedMessage = [[FIRMessagingRemoteMessage alloc] init]; + // TODO: wrap title, body, badge and other fields + wrappedMessage.appData = [message copy]; + wrappedMessage.messageID = messageID; + [self.delegate receiver:self receivedRemoteMessage:wrappedMessage]; +} + +- (void)scheduleNotificationForMessage:(NSDictionary *)message { + SEL newNotificationSelector = + @selector(application:didReceiveRemoteNotification:fetchCompletionHandler:); + SEL oldNotificationSelector = @selector(application:didReceiveRemoteNotification:); + + dispatch_async(dispatch_get_main_queue(), ^{ + UIApplication *application = FIRMessagingUIApplication(); + if (!application) { + return; + } + id appDelegate = [application delegate]; + if ([appDelegate respondsToSelector:newNotificationSelector]) { + // Try the new remote notification callback + [appDelegate application:application + didReceiveRemoteNotification:message + fetchCompletionHandler:^(UIBackgroundFetchResult result) { + }]; + + } else if ([appDelegate respondsToSelector:oldNotificationSelector]) { + // Try the old remote notification callback +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [appDelegate application:application didReceiveRemoteNotification:message]; +#pragma clang diagnostic pop + } else { + FIRMessagingLoggerError(kFIRMessagingMessageCodeReceiver005, + @"None of the remote notification callbacks implemented by " + @"UIApplicationDelegate"); + } + }); +} + ++ (NSString *)nextMessageID { + @synchronized (self) { + ++downstreamMessageID; + return [NSString stringWithFormat:@"gcm-%d", downstreamMessageID]; + } +} + +- (BOOL)useDirectChannel { + // Check storage + NSUserDefaults *messagingDefaults = [NSUserDefaults standardUserDefaults]; + id shouldUseMessagingDelegate = + [messagingDefaults objectForKey:kFIRMessagingUserDefaultsKeyUseMessagingDelegate]; + if (shouldUseMessagingDelegate) { + return [shouldUseMessagingDelegate boolValue]; + } + + // Check Info.plist + shouldUseMessagingDelegate = + [[NSBundle mainBundle] objectForInfoDictionaryKey:kFIRMessagingPlistUseMessagingDelegate]; + if (shouldUseMessagingDelegate) { + return [shouldUseMessagingDelegate boolValue]; + } + // If none of above exists, we go back to default behavior which is NO. + return NO; +} + +- (void)setUseDirectChannel:(BOOL)useDirectChannel { + NSUserDefaults *messagingDefaults = [NSUserDefaults standardUserDefaults]; + BOOL shouldUseMessagingDelegate = [self useDirectChannel]; + if (useDirectChannel != shouldUseMessagingDelegate) { + [messagingDefaults setBool:useDirectChannel + forKey:kFIRMessagingUserDefaultsKeyUseMessagingDelegate]; + [messagingDefaults synchronize]; + } +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRegistrar.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRegistrar.h new file mode 100644 index 00000000..065479cb --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRegistrar.h @@ -0,0 +1,80 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessaging.h" +#import "FIRMessagingCheckinService.h" + +@class FIRMessagingCheckinStore; +@class FIRMessagingPubSubRegistrar; + +/** + * Handle the registration process for the client. Fetch checkin information from the Checkin + * service if not cached on the device and then try to register the client with FIRMessaging backend. + */ +@interface FIRMessagingRegistrar : NSObject + +@property(nonatomic, readonly, strong) FIRMessagingPubSubRegistrar *pubsubRegistrar; +@property(nonatomic, readonly, strong) NSString *deviceAuthID; +@property(nonatomic, readonly, strong) NSString *secretToken; + +/** + * Initialize a FIRMessaging Registrar. + * + * @return A FIRMessaging Registrar object. + */ +- (instancetype)init NS_DESIGNATED_INITIALIZER; + +#pragma mark - Checkin + +/** + * Try to load checkin info from the disk if not currently loaded into memory. + * + * @return YES if successfully loaded valid checkin info to memory else NO. + */ +- (BOOL)tryToLoadValidCheckinInfo; + +#pragma mark - Subscribe/Unsubscribe + +/** + * Update the subscription for a given topic for the client. + * + * @param topic The topic for which the subscription should be updated. + * @param token The registration token to be used by the client. + * @param options The extra options if any being passed as part of + * subscription request. + * @param shouldDelete YES if we want to delete an existing subscription else NO + * if we want to create a new subscription. + * @param handler The handler to invoke once the subscription request is + * complete. + */ +- (void)updateSubscriptionToTopic:(NSString *)topic + withToken:(NSString *)token + options:(NSDictionary *)options + shouldDelete:(BOOL)shouldDelete + handler:(FIRMessagingTopicOperationCompletion)handler; + +/** + * Cancel all subscription requests as well as any requests to checkin. Note if + * there are subscription requests waiting on checkin to complete those requests + * would be marked as stale and be NO-OP's if they happen in the future. + * + * Also note this is a one time operation, you should only call this if you want + * to immediately stop all requests and deallocate the registrar. After calling + * this once you would no longer be able to use this registrar object. + */ +- (void)cancelAllRequests; + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRegistrar.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRegistrar.m new file mode 100644 index 00000000..47a22ecc --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRegistrar.m @@ -0,0 +1,108 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingRegistrar.h" + +#import "FIRMessagingDefines.h" +#import "FIRMessagingLogger.h" +#import "FIRMessagingPubSubRegistrar.h" +#import "FIRMessagingUtilities.h" +#import "NSError+FIRMessaging.h" + +@interface FIRMessagingRegistrar () + +@property(nonatomic, readwrite, assign) BOOL stopAllSubscriptions; + +@property(nonatomic, readwrite, strong) FIRMessagingCheckinService *checkinService; +@property(nonatomic, readwrite, strong) FIRMessagingPubSubRegistrar *pubsubRegistrar; + +@end + +@implementation FIRMessagingRegistrar + +- (NSString *)deviceAuthID { + return self.checkinService.deviceAuthID; +} + +- (NSString *)secretToken { + return self.checkinService.secretToken; +} + +- (instancetype)init { + self = [super init]; + if (self) { + _checkinService = [[FIRMessagingCheckinService alloc] init]; + // TODO(chliangGoogle): Merge pubsubRegistrar with Registrar as it is hard to track how many + // checkinService instances by separating classes too often. + _pubsubRegistrar = [[FIRMessagingPubSubRegistrar alloc] initWithCheckinService:_checkinService]; + } + return self; +} + +#pragma mark - Checkin + +- (BOOL)tryToLoadValidCheckinInfo { + [self.checkinService tryToLoadPrefetchedCheckinPreferences]; + return [self.checkinService hasValidCheckinInfo]; +} + +#pragma mark - Subscribe/Unsubscribe + +- (void)updateSubscriptionToTopic:(NSString *)topic + withToken:(NSString *)token + options:(NSDictionary *)options + shouldDelete:(BOOL)shouldDelete + handler:(FIRMessagingTopicOperationCompletion)handler { + _FIRMessagingDevAssert(handler, @"Invalid nil handler"); + + if ([self tryToLoadValidCheckinInfo]) { + [self doUpdateSubscriptionForTopic:topic + token:token + options:options + shouldDelete:shouldDelete + completion:handler]; + + } else { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeRegistrar000, + @"Device check in error, no auth credentials found"); + NSError *error = [NSError errorWithFCMErrorCode:kFIRMessagingErrorCodeMissingDeviceID]; + handler(error); + } +} + +- (void)cancelAllRequests { + self.stopAllSubscriptions = YES; + [self.pubsubRegistrar stopAllSubscriptionRequests]; +} + +#pragma mark - Private + +- (void)doUpdateSubscriptionForTopic:(NSString *)topic + token:(NSString *)token + options:(NSDictionary *)options + shouldDelete:(BOOL)shouldDelete + completion:(FIRMessagingTopicOperationCompletion)completion { + _FIRMessagingDevAssert([self.checkinService hasValidCheckinInfo], + @"No valid checkin info found before subscribe"); + + [self.pubsubRegistrar updateSubscriptionToTopic:topic + withToken:token + options:options + shouldDelete:shouldDelete + handler:completion]; +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRemoteNotificationsProxy.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRemoteNotificationsProxy.h new file mode 100644 index 00000000..59c3c15d --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRemoteNotificationsProxy.h @@ -0,0 +1,40 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +/** + * Swizzle remote-notification callbacks to invoke FIRMessaging methods + * before calling original implementations. + */ +@interface FIRMessagingRemoteNotificationsProxy : NSObject + +/** + * Checks the `FirebaseAppDelegateProxyEnabled` key in the App's Info.plist. If the key is + * missing or incorrectly formatted, returns `YES`. + * + * @return YES if the Application Delegate and User Notification Center methods can be swizzled. + * Otherwise, returns NO. + */ ++ (BOOL)canSwizzleMethods; + +/** + * Swizzles Application Delegate's remote-notification callbacks and User Notification Center + * delegate callback, and invokes the original selectors once done. + */ ++ (void)swizzleMethods; + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRemoteNotificationsProxy.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRemoteNotificationsProxy.m new file mode 100644 index 00000000..7cea178e --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRemoteNotificationsProxy.m @@ -0,0 +1,723 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingRemoteNotificationsProxy.h" + +#import +#import + +#import "FIRMessagingConstants.h" +#import "FIRMessagingLogger.h" +#import "FIRMessagingUtilities.h" +#import "FIRMessaging_Private.h" + +static const BOOL kDefaultAutoRegisterEnabledValue = YES; +static void * UserNotificationObserverContext = &UserNotificationObserverContext; + +static NSString *kUserNotificationWillPresentSelectorString = + @"userNotificationCenter:willPresentNotification:withCompletionHandler:"; +static NSString *kUserNotificationDidReceiveResponseSelectorString = + @"userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:"; +static NSString *kReceiveDataMessageSelectorString = @"messaging:didReceiveMessage:"; + +@interface FIRMessagingRemoteNotificationsProxy () + +@property(strong, nonatomic) NSMutableDictionary *originalAppDelegateImps; +@property(strong, nonatomic) NSMutableDictionary *swizzledSelectorsByClass; + +@property(nonatomic) BOOL didSwizzleMethods; +@property(nonatomic) BOOL didSwizzleAppDelegateMethods; + +@property(nonatomic) BOOL hasSwizzledUserNotificationDelegate; +@property(nonatomic) BOOL isObservingUserNotificationDelegateChanges; + +@property(strong, nonatomic) id userNotificationCenter; +@property(strong, nonatomic) id currentUserNotificationCenterDelegate; + +@end + +@implementation FIRMessagingRemoteNotificationsProxy + ++ (BOOL)canSwizzleMethods { + id canSwizzleValue = + [[NSBundle mainBundle] + objectForInfoDictionaryKey: kFIRMessagingRemoteNotificationsProxyEnabledInfoPlistKey]; + if (canSwizzleValue && [canSwizzleValue isKindOfClass:[NSNumber class]]) { + NSNumber *canSwizzleNumberValue = (NSNumber *)canSwizzleValue; + return canSwizzleNumberValue.boolValue; + } else { + return kDefaultAutoRegisterEnabledValue; + } +} + ++ (void)swizzleMethods { + [[FIRMessagingRemoteNotificationsProxy sharedProxy] swizzleMethodsIfPossible]; +} + ++ (instancetype)sharedProxy { + static FIRMessagingRemoteNotificationsProxy *proxy; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + proxy = [[FIRMessagingRemoteNotificationsProxy alloc] init]; + }); + return proxy; +} + +- (instancetype)init { + self = [super init]; + if (self) { + _originalAppDelegateImps = [[NSMutableDictionary alloc] init]; + _swizzledSelectorsByClass = [[NSMutableDictionary alloc] init]; + } + return self; +} + +- (void)dealloc { + [self unswizzleAllMethods]; + self.swizzledSelectorsByClass = nil; + [self.originalAppDelegateImps removeAllObjects]; + self.originalAppDelegateImps = nil; + [self removeUserNotificationCenterDelegateObserver]; +} + +- (void)swizzleMethodsIfPossible { + // Already swizzled. + if (self.didSwizzleMethods) { + return; + } + + UIApplication *application = FIRMessagingUIApplication(); + if (!application) { + return; + } + NSObject *appDelegate = [application delegate]; + [self swizzleAppDelegateMethods:appDelegate]; + + // Add KVO listener on [UNUserNotificationCenter currentNotificationCenter]'s delegate property + Class notificationCenterClass = NSClassFromString(@"UNUserNotificationCenter"); + if (notificationCenterClass) { + // We are linked against iOS 10 SDK or above + id notificationCenter = getNamedPropertyFromObject(notificationCenterClass, + @"currentNotificationCenter", + notificationCenterClass); + if (notificationCenter) { + [self listenForDelegateChangesInUserNotificationCenter:notificationCenter]; + } + } + + self.didSwizzleMethods = YES; +} + +- (void)unswizzleAllMethods { + for (NSString *className in self.swizzledSelectorsByClass) { + Class klass = NSClassFromString(className); + NSArray *selectorStrings = self.swizzledSelectorsByClass[className]; + for (NSString *selectorString in selectorStrings) { + SEL selector = NSSelectorFromString(selectorString); + [self unswizzleSelector:selector inClass:klass]; + } + } + [self.swizzledSelectorsByClass removeAllObjects]; +} + +- (void)swizzleAppDelegateMethods:(id)appDelegate { + if (![appDelegate conformsToProtocol:@protocol(UIApplicationDelegate)]) { + return; + } + Class appDelegateClass = [appDelegate class]; + + BOOL didSwizzleAppDelegate = NO; + // Message receiving handler for iOS 9, 8, 7 devices (both display notification and data message). + SEL remoteNotificationSelector = + @selector(application:didReceiveRemoteNotification:); + + SEL remoteNotificationWithFetchHandlerSelector = + @selector(application:didReceiveRemoteNotification:fetchCompletionHandler:); + + // For recording when APNS tokens are registered (or fail to register) + SEL registerForAPNSFailSelector = + @selector(application:didFailToRegisterForRemoteNotificationsWithError:); + + SEL registerForAPNSSuccessSelector = + @selector(application:didRegisterForRemoteNotificationsWithDeviceToken:); + + + // Receive Remote Notifications. + BOOL selectorWithFetchHandlerImplemented = NO; + if ([appDelegate respondsToSelector:remoteNotificationWithFetchHandlerSelector]) { + selectorWithFetchHandlerImplemented = YES; + [self swizzleSelector:remoteNotificationWithFetchHandlerSelector + inClass:appDelegateClass + withImplementation:(IMP)FCM_swizzle_appDidReceiveRemoteNotificationWithHandler + inProtocol:@protocol(UIApplicationDelegate)]; + didSwizzleAppDelegate = YES; + } + + if ([appDelegate respondsToSelector:remoteNotificationSelector] || + !selectorWithFetchHandlerImplemented) { + [self swizzleSelector:remoteNotificationSelector + inClass:appDelegateClass + withImplementation:(IMP)FCM_swizzle_appDidReceiveRemoteNotification + inProtocol:@protocol(UIApplicationDelegate)]; + didSwizzleAppDelegate = YES; + } + + // For data message from MCS. + SEL receiveDataMessageSelector = NSSelectorFromString(kReceiveDataMessageSelectorString); + if ([appDelegate respondsToSelector:receiveDataMessageSelector]) { + [self swizzleSelector:receiveDataMessageSelector + inClass:appDelegateClass + withImplementation:(IMP)FCM_swizzle_messagingDidReceiveMessage + inProtocol:@protocol(UIApplicationDelegate)]; + didSwizzleAppDelegate = YES; + } + + // Receive APNS token + [self swizzleSelector:registerForAPNSSuccessSelector + inClass:appDelegateClass + withImplementation:(IMP)FCM_swizzle_appDidRegisterForRemoteNotifications + inProtocol:@protocol(UIApplicationDelegate)]; + + [self swizzleSelector:registerForAPNSFailSelector + inClass:appDelegateClass + withImplementation:(IMP)FCM_swizzle_appDidFailToRegisterForRemoteNotifications + inProtocol:@protocol(UIApplicationDelegate)]; + + self.didSwizzleAppDelegateMethods = didSwizzleAppDelegate; +} + +- (void)listenForDelegateChangesInUserNotificationCenter:(id)notificationCenter { + Class notificationCenterClass = NSClassFromString(@"UNUserNotificationCenter"); + if (![notificationCenter isKindOfClass:notificationCenterClass]) { + return; + } + id delegate = getNamedPropertyFromObject(notificationCenter, @"delegate", nil); + Protocol *delegateProtocol = NSProtocolFromString(@"UNUserNotificationCenterDelegate"); + if ([delegate conformsToProtocol:delegateProtocol]) { + // Swizzle this object now, if available + [self swizzleUserNotificationCenterDelegate:delegate]; + } + // Add KVO observer for "delegate" keyPath for future changes + [self addDelegateObserverToUserNotificationCenter:notificationCenter]; +} + +#pragma mark - UNNotificationCenter Swizzling + +- (void)swizzleUserNotificationCenterDelegate:(id _Nonnull)delegate { + if (self.currentUserNotificationCenterDelegate == delegate) { + // Via pointer-check, compare if we have already swizzled this item. + return; + } + Protocol *userNotificationCenterProtocol = + NSProtocolFromString(@"UNUserNotificationCenterDelegate"); + if ([delegate conformsToProtocol:userNotificationCenterProtocol]) { + SEL willPresentNotificationSelector = + NSSelectorFromString(kUserNotificationWillPresentSelectorString); + // Swizzle the optional method + // "userNotificationCenter:willPresentNotification:withCompletionHandler:", if it is + // implemented. Do not swizzle otherwise, as an implementation *will* be created, which will + // fool iOS into thinking that this method is implemented, and therefore not send notifications + // to the fallback method in the app delegate + // "application:didReceiveRemoteNotification:fetchCompletionHandler:". + if ([delegate respondsToSelector:willPresentNotificationSelector]) { + [self swizzleSelector:willPresentNotificationSelector + inClass:[delegate class] + withImplementation:(IMP)FCM_swizzle_willPresentNotificationWithHandler + inProtocol:userNotificationCenterProtocol]; + } + SEL didReceiveNotificationResponseSelector = + NSSelectorFromString(kUserNotificationDidReceiveResponseSelectorString); + if ([delegate respondsToSelector:didReceiveNotificationResponseSelector]) { + [self swizzleSelector:didReceiveNotificationResponseSelector + inClass:[delegate class] + withImplementation:(IMP)FCM_swizzle_didReceiveNotificationResponseWithHandler + inProtocol:userNotificationCenterProtocol]; + } + self.currentUserNotificationCenterDelegate = delegate; + self.hasSwizzledUserNotificationDelegate = YES; + } +} + +- (void)unswizzleUserNotificationCenterDelegate:(id _Nonnull)delegate { + if (self.currentUserNotificationCenterDelegate != delegate) { + // We aren't swizzling this delegate, so don't do anything. + return; + } + SEL willPresentNotificationSelector = + NSSelectorFromString(kUserNotificationWillPresentSelectorString); + // Call unswizzle methods, even if the method was not implemented (it will fail gracefully). + [self unswizzleSelector:willPresentNotificationSelector + inClass:[self.currentUserNotificationCenterDelegate class]]; + SEL didReceiveNotificationResponseSelector = + NSSelectorFromString(kUserNotificationDidReceiveResponseSelectorString); + [self unswizzleSelector:didReceiveNotificationResponseSelector + inClass:[self.currentUserNotificationCenterDelegate class]]; + self.currentUserNotificationCenterDelegate = nil; + self.hasSwizzledUserNotificationDelegate = NO; +} + +#pragma mark - KVO for UNUserNotificationCenter + +- (void)addDelegateObserverToUserNotificationCenter:(id)userNotificationCenter { + [self removeUserNotificationCenterDelegateObserver]; + @try { + [userNotificationCenter addObserver:self + forKeyPath:NSStringFromSelector(@selector(delegate)) + options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld + context:UserNotificationObserverContext]; + self.userNotificationCenter = userNotificationCenter; + self.isObservingUserNotificationDelegateChanges = YES; + } @catch (NSException *exception) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeRemoteNotificationsProxy000, + @"Encountered exception trying to add a KVO observer for " + @"UNUserNotificationCenter's 'delegate' property: %@", + exception); + } @finally { + + } +} + +- (void)removeUserNotificationCenterDelegateObserver { + if (!self.userNotificationCenter) { + return; + } + @try { + [self.userNotificationCenter removeObserver:self + forKeyPath:NSStringFromSelector(@selector(delegate)) + context:UserNotificationObserverContext]; + self.userNotificationCenter = nil; + self.isObservingUserNotificationDelegateChanges = NO; + } @catch (NSException *exception) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeRemoteNotificationsProxy001, + @"Encountered exception trying to remove a KVO observer for " + @"UNUserNotificationCenter's 'delegate' property: %@", + exception); + } @finally { + + } +} + +- (void)observeValueForKeyPath:(NSString *)keyPath + ofObject:(id)object + change:(NSDictionary *)change + context:(void *)context { + if (context == UserNotificationObserverContext) { + if ([keyPath isEqualToString:NSStringFromSelector(@selector(delegate))]) { + id oldDelegate = change[NSKeyValueChangeOldKey]; + if (oldDelegate && oldDelegate != [NSNull null]) { + [self unswizzleUserNotificationCenterDelegate:oldDelegate]; + } + id newDelegate = change[NSKeyValueChangeNewKey]; + if (newDelegate && newDelegate != [NSNull null]) { + [self swizzleUserNotificationCenterDelegate:newDelegate]; + } + } + } else { + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; + } +} + +#pragma mark - NSProxy methods + +- (void)saveOriginalImplementation:(IMP)imp forSelector:(SEL)selector { + if (imp && selector) { + NSValue *IMPValue = [NSValue valueWithPointer:imp]; + NSString *selectorString = NSStringFromSelector(selector); + self.originalAppDelegateImps[selectorString] = IMPValue; + } +} + +- (IMP)originalImplementationForSelector:(SEL)selector { + NSString *selectorString = NSStringFromSelector(selector); + NSValue *implementation_value = self.originalAppDelegateImps[selectorString]; + if (!implementation_value) { + return nil; + } + + IMP imp; + [implementation_value getValue:&imp]; + return imp; +} + +- (void)trackSwizzledSelector:(SEL)selector ofClass:(Class)klass { + NSString *className = NSStringFromClass(klass); + NSString *selectorString = NSStringFromSelector(selector); + NSArray *selectors = self.swizzledSelectorsByClass[selectorString]; + if (selectors) { + selectors = [selectors arrayByAddingObject:selectorString]; + } else { + selectors = @[selectorString]; + } + self.swizzledSelectorsByClass[className] = selectors; +} + +- (void)removeImplementationForSelector:(SEL)selector { + NSString *selectorString = NSStringFromSelector(selector); + [self.originalAppDelegateImps removeObjectForKey:selectorString]; +} + +- (void)swizzleSelector:(SEL)originalSelector + inClass:(Class)klass + withImplementation:(IMP)swizzledImplementation + inProtocol:(Protocol *)protocol { + Method originalMethod = class_getInstanceMethod(klass, originalSelector); + + if (originalMethod) { + // This class implements this method, so replace the original implementation + // with our new implementation and save the old implementation. + + IMP __original_method_implementation = + method_setImplementation(originalMethod, swizzledImplementation); + + IMP __nonexistant_method_implementation = [self nonExistantMethodImplementationForClass:klass]; + + if (__original_method_implementation && + __original_method_implementation != __nonexistant_method_implementation && + __original_method_implementation != swizzledImplementation) { + [self saveOriginalImplementation:__original_method_implementation + forSelector:originalSelector]; + } + } else { + // The class doesn't have this method, so add our swizzled implementation as the + // original implementation of the original method. + struct objc_method_description method_description = + protocol_getMethodDescription(protocol, originalSelector, NO, YES); + + BOOL methodAdded = class_addMethod(klass, + originalSelector, + swizzledImplementation, + method_description.types); + if (!methodAdded) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeRemoteNotificationsProxyMethodNotAdded, + @"Could not add method for %@ to class %@", + NSStringFromSelector(originalSelector), + NSStringFromClass(klass)); + } + } + [self trackSwizzledSelector:originalSelector ofClass:klass]; +} + +- (void)unswizzleSelector:(SEL)selector inClass:(Class)klass { + + Method swizzledMethod = class_getInstanceMethod(klass, selector); + if (!swizzledMethod) { + // This class doesn't seem to have this selector as an instance method? Bail out. + return; + } + + IMP original_imp = [self originalImplementationForSelector:selector]; + if (original_imp) { + // Restore the original implementation as the current implementation + method_setImplementation(swizzledMethod, original_imp); + [self removeImplementationForSelector:selector]; + } else { + // This class originally did not have an implementation for this selector. + + // We can't actually remove methods in Objective C 2.0, but we could set + // its method to something non-existent. This should give us the same + // behavior as if the method was not implemented. + // See: http://stackoverflow.com/a/8276527/9849 + + IMP nonExistantMethodImplementation = [self nonExistantMethodImplementationForClass:klass]; + method_setImplementation(swizzledMethod, nonExistantMethodImplementation); + } +} + +#pragma mark - Reflection Helpers + +// This is useful to generate from a stable, "known missing" selector, as the IMP can be compared +// in case we are setting an implementation for a class that was previously "unswizzled" into a +// non-existant implementation. +- (IMP)nonExistantMethodImplementationForClass:(Class)klass { + SEL nonExistantSelector = NSSelectorFromString(@"aNonExistantMethod"); + IMP nonExistantMethodImplementation = class_getMethodImplementation(klass, nonExistantSelector); + return nonExistantMethodImplementation; +} + +// A safe, non-leaky way return a property object by its name +id getNamedPropertyFromObject(id object, NSString *propertyName, Class klass) { + SEL selector = NSSelectorFromString(propertyName); + if (![object respondsToSelector:selector]) { + return nil; + } + if (!klass) { + klass = [NSObject class]; + } + // Suppress clang warning about leaks in performSelector + // The alternative way to perform this is to invoke + // the method as a block (see http://stackoverflow.com/a/20058585), + // but this approach sometimes returns incomplete objects. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + id property = [object performSelector:selector]; +#pragma clang diagnostic pop + if (![property isKindOfClass:klass]) { + return nil; + } + return property; +} + +#pragma mark - Swizzled Methods + +void FCM_swizzle_appDidReceiveRemoteNotification(id self, + SEL _cmd, + UIApplication *app, + NSDictionary *userInfo) { + [[FIRMessaging messaging] appDidReceiveMessage:userInfo]; + + IMP original_imp = + [[FIRMessagingRemoteNotificationsProxy sharedProxy] originalImplementationForSelector:_cmd]; + if (original_imp) { + ((void (*)(id, SEL, UIApplication *, NSDictionary *))original_imp)(self, + _cmd, + app, + userInfo); + } +} + +void FCM_swizzle_appDidReceiveRemoteNotificationWithHandler( + id self, SEL _cmd, UIApplication *app, NSDictionary *userInfo, + void (^handler)(UIBackgroundFetchResult)) { + + [[FIRMessaging messaging] appDidReceiveMessage:userInfo]; + + IMP original_imp = + [[FIRMessagingRemoteNotificationsProxy sharedProxy] originalImplementationForSelector:_cmd]; + if (original_imp) { + ((void (*)(id, SEL, UIApplication *, NSDictionary *, + void (^)(UIBackgroundFetchResult)))original_imp)( + self, _cmd, app, userInfo, handler); + } +} + +/** + * Swizzle the notification handler for iOS 10+ devices. + * Signature of original handler is as below: + * - (void)userNotificationCenter:(UNUserNotificationCenter *)center + * willPresentNotification:(UNNotification *)notification + * withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler + * In order to make FCM SDK compile and compatible with iOS SDKs before iOS 10, hide the + * parameter types from the swizzling implementation. + */ +void FCM_swizzle_willPresentNotificationWithHandler( + id self, SEL _cmd, id center, id notification, void (^handler)(NSUInteger)) { + + FIRMessagingRemoteNotificationsProxy *proxy = [FIRMessagingRemoteNotificationsProxy sharedProxy]; + IMP original_imp = [proxy originalImplementationForSelector:_cmd]; + + void (^callOriginalMethodIfAvailable)(void) = ^{ + if (original_imp) { + ((void (*)(id, SEL, id, id, void (^)(NSUInteger)))original_imp)( + self, _cmd, center, notification, handler); + } + return; + }; + + Class notificationCenterClass = NSClassFromString(@"UNUserNotificationCenter"); + Class notificationClass = NSClassFromString(@"UNNotification"); + if (!notificationCenterClass || !notificationClass) { + // Can't find UserNotifications framework. Do not swizzle, just execute the original method. + callOriginalMethodIfAvailable(); + } + + if (!center || ![center isKindOfClass:[notificationCenterClass class]]) { + // Invalid parameter type from the original method. + // Do not swizzle, just execute the original method. + callOriginalMethodIfAvailable(); + return; + } + + if (!notification || ![notification isKindOfClass:[notificationClass class]]) { + // Invalid parameter type from the original method. + // Do not swizzle, just execute the original method. + callOriginalMethodIfAvailable(); + return; + } + + if (!handler) { + // Invalid parameter type from the original method. + // Do not swizzle, just execute the original method. + callOriginalMethodIfAvailable(); + return; + } + + // Attempt to access the user info + id notificationUserInfo = userInfoFromNotification(notification); + + if (!notificationUserInfo) { + // Could not access notification.request.content.userInfo. + callOriginalMethodIfAvailable(); + return; + } + + [[FIRMessaging messaging] appDidReceiveMessage:notificationUserInfo]; + // Execute the original implementation. + callOriginalMethodIfAvailable(); +} + +/** + * Swizzle the notification handler for iOS 10+ devices. + * Signature of original handler is as below: + * - (void)userNotificationCenter:(UNUserNotificationCenter *)center + * didReceiveNotificationResponse:(UNNotificationResponse *)response + * withCompletionHandler:(void (^)(void))completionHandler + * In order to make FCM SDK compile and compatible with iOS SDKs before iOS 10, hide the + * parameter types from the swizzling implementation. + */ +void FCM_swizzle_didReceiveNotificationResponseWithHandler( + id self, SEL _cmd, id center, id response, void (^handler)(void)) { + + FIRMessagingRemoteNotificationsProxy *proxy = [FIRMessagingRemoteNotificationsProxy sharedProxy]; + IMP original_imp = [proxy originalImplementationForSelector:_cmd]; + + void (^callOriginalMethodIfAvailable)(void) = ^{ + if (original_imp) { + ((void (*)(id, SEL, id, id, void (^)(void)))original_imp)( + self, _cmd, center, response, handler); + } + return; + }; + + Class notificationCenterClass = NSClassFromString(@"UNUserNotificationCenter"); + Class responseClass = NSClassFromString(@"UNNotificationResponse"); + if (!center || ![center isKindOfClass:[notificationCenterClass class]]) { + // Invalid parameter type from the original method. + // Do not swizzle, just execute the original method. + callOriginalMethodIfAvailable(); + return; + } + + if (!response || ![response isKindOfClass:[responseClass class]]) { + // Invalid parameter type from the original method. + // Do not swizzle, just execute the original method. + callOriginalMethodIfAvailable(); + return; + } + + if (!handler) { + // Invalid parameter type from the original method. + // Do not swizzle, just execute the original method. + callOriginalMethodIfAvailable(); + return; + } + + // Try to access the response.notification property + SEL notificationSelector = NSSelectorFromString(@"notification"); + if (![response respondsToSelector:notificationSelector]) { + // Cannot access the .notification property. + callOriginalMethodIfAvailable(); + return; + } + id notificationClass = NSClassFromString(@"UNNotification"); + id notification = getNamedPropertyFromObject(response, @"notification", notificationClass); + + // With a notification object, use the common code to reach deep into notification + // (notification.request.content.userInfo) + id notificationUserInfo = userInfoFromNotification(notification); + if (!notificationUserInfo) { + // Could not access notification.request.content.userInfo. + callOriginalMethodIfAvailable(); + return; + } + + [[FIRMessaging messaging] appDidReceiveMessage:notificationUserInfo]; + // Execute the original implementation. + callOriginalMethodIfAvailable(); +} + +id userInfoFromNotification(id notification) { + + // Select the userInfo field from UNNotification.request.content.userInfo. + SEL requestSelector = NSSelectorFromString(@"request"); + if (![notification respondsToSelector:requestSelector]) { + // Cannot access the request property. + return nil; + } + Class requestClass = NSClassFromString(@"UNNotificationRequest"); + id notificationRequest = getNamedPropertyFromObject(notification, @"request", requestClass); + + SEL notificationContentSelector = NSSelectorFromString(@"content"); + if (!notificationRequest + || ![notificationRequest respondsToSelector:notificationContentSelector]) { + // Cannot access the content property. + return nil; + } + Class contentClass = NSClassFromString(@"UNNotificationContent"); + id notificationContent = getNamedPropertyFromObject(notificationRequest, + @"content", + contentClass); + + SEL notificationUserInfoSelector = NSSelectorFromString(@"userInfo"); + if (!notificationContent + || ![notificationContent respondsToSelector:notificationUserInfoSelector]) { + // Cannot access the userInfo property. + return nil; + } + id notificationUserInfo = getNamedPropertyFromObject(notificationContent, + @"userInfo", + [NSDictionary class]); + + if (!notificationUserInfo) { + // This is not the expected notification handler. + return nil; + } + + return notificationUserInfo; +} + +void FCM_swizzle_messagingDidReceiveMessage(id self, SEL _cmd, FIRMessaging *message, + FIRMessagingRemoteMessage *remoteMessage) { + [[FIRMessaging messaging] appDidReceiveMessage:remoteMessage.appData]; + + IMP original_imp = + [[FIRMessagingRemoteNotificationsProxy sharedProxy] originalImplementationForSelector:_cmd]; + if (original_imp) { + ((void (*)(id, SEL, FIRMessaging *, FIRMessagingRemoteMessage *))original_imp)( + self, _cmd, message, remoteMessage); + } +} + +void FCM_swizzle_appDidFailToRegisterForRemoteNotifications(id self, + SEL _cmd, + UIApplication *app, + NSError *error) { + // Log the fact that we failed to register for remote notifications + FIRMessagingLoggerError(kFIRMessagingMessageCodeRemoteNotificationsProxyAPNSFailed, + @"Error in " + @"application:didFailToRegisterForRemoteNotificationsWithError: %@", + error.localizedDescription); + IMP original_imp = + [[FIRMessagingRemoteNotificationsProxy sharedProxy] originalImplementationForSelector:_cmd]; + if (original_imp) { + ((void (*)(id, SEL, UIApplication *, NSError *))original_imp)(self, _cmd, app, error); + } +} + +void FCM_swizzle_appDidRegisterForRemoteNotifications(id self, + SEL _cmd, + UIApplication *app, + NSData *deviceToken) { + // Pass the APNSToken along to FIRMessaging (and auto-detect the token type) + [FIRMessaging messaging].APNSToken = deviceToken; + + IMP original_imp = + [[FIRMessagingRemoteNotificationsProxy sharedProxy] originalImplementationForSelector:_cmd]; + if (original_imp) { + ((void (*)(id, SEL, UIApplication *, NSData *))original_imp)(self, _cmd, app, deviceToken); + } +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRmq2PersistentStore.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRmq2PersistentStore.h new file mode 100644 index 00000000..09f1d446 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRmq2PersistentStore.h @@ -0,0 +1,201 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class FIRMessagingPersistentSyncMessage; + +// table data handlers +/** + * Handle message stored in the outgoing RMQ messages table. + * + * @param rmqId The rmqID of the message. + * @param tag The message tag. + * @param data The data stored in the message. + */ +typedef void(^FCMOutgoingRmqMessagesTableHandler)(int64_t rmqId, int8_t tag, NSData *data); + +/// Outgoing messages RMQ table +extern NSString *const kTableOutgoingRmqMessages; +/// Server to device RMQ table +extern NSString *const kTableS2DRmqIds; + +@interface FIRMessagingRmq2PersistentStore : NSObject + +/** + * Initialize and open the RMQ database on the client. + * + * @param databaseName The name for RMQ database. + * + * @return A store used to persist messages on the client. + */ +- (instancetype)initWithDatabaseName:(NSString *)databaseName; + +/** + * Save outgoing message in RMQ. + * + * @param rmqId The rmqID for the message. + * @param tag The tag of the message proto. + * @param data The data being sent in the message. + * @param error The error if any while saving the message to the persistent store. + * + * @return YES if the message was successfully saved to the persistent store else NO. + */ +- (BOOL)saveMessageWithRmqId:(int64_t)rmqId + tag:(int8_t)tag + data:(NSData *)data + error:(NSError **)error; + +/** + * Add unacked server to device message with a given rmqID to the persistent store. + * + * @param rmqId The rmqID of the message that was not acked by the cient. + * + * @return YES if the save was successful else NO. + */ +- (BOOL)saveUnackedS2dMessageWithRmqId:(NSString *)rmqId; + +/** + * Update the last RMQ ID that was sent by the client. + * + * @param rmqID The latest rmqID sent by the device. + * + * @return YES if the last rmqID was successfully saved else NO. + */ +- (BOOL)updateLastOutgoingRmqId:(int64_t)rmqID; + +#pragma mark - Query + +/** + * Query the highest rmqID saved in the Outgoing messages table. + * + * @return The highest rmqID amongst all the messages in the Outgoing RMQ table. If no message + * was ever persisted return 0. + */ +- (int64_t)queryHighestRmqId; + +/** + * The last rmqID that was saved on the client. + * + * @return The last rmqID that was saved. If no rmqID was ever persisted return 0. + */ +- (int64_t)queryLastRmqId; + +/** + * Get a list of all unacked server to device messages stored on the client. + * + * @return List of all unacked s2d messages in the persistent store. + */ +- (NSArray *)unackedS2dRmqIds; + +/** + * Iterate over all outgoing messages in the RMQ table. + * + * @param handler The handler invoked with each message in the outgoing RMQ table. + */ +- (void)scanOutgoingRmqMessagesWithHandler:(FCMOutgoingRmqMessagesTableHandler)handler; + +#pragma mark - Delete + +/** + * Delete messages with given rmqID's from a table. + * + * @param tableName The table name from which to delete the rmq messages. + * @param rmqIds The rmqID's of the messages to be deleted. + * + * @return The number of messages that were successfully deleted. + */ +- (int)deleteMessagesFromTable:(NSString *)tableName + withRmqIds:(NSArray *)rmqIds; + +/** + * Remove database from the device. + * + * @param dbName The database name to be deleted. + */ ++ (void)removeDatabase:(NSString *)dbName; + +#pragma mark - Sync Messages + +/** + * Save sync message to persistent store to check for duplicates. + * + * @param rmqID The rmqID of the message to save. + * @param expirationTime The expiration time of the message to save. + * @param apnsReceived YES if the message was received via APNS else NO. + * @param mcsReceived YES if the message was received via MCS else NO. + * @param error The error if any while saving the message to store. + * + * @return YES if the message was saved successfully else NO. + */ +- (BOOL)saveSyncMessageWithRmqID:(NSString *)rmqID + expirationTime:(int64_t)expirationTime + apnsReceived:(BOOL)apnsReceived + mcsReceived:(BOOL)mcsReceived + error:(NSError **)error; + +/** + * Update sync message received via APNS. + * + * @param rmqID The rmqID of the sync message. + * @param error The error if any while updating the sync message in persistence. + * + * @return YES if the update was successful else NO. + */ +- (BOOL)updateSyncMessageViaAPNSWithRmqID:(NSString *)rmqID + error:(NSError **)error; + +/** + * Update sync message received via MCS. + * + * @param rmqID The rmqID of the sync message. + * @param error The error if any while updating the sync message in persistence. + * + * @return YES if the update was successful else NO. + */ +- (BOOL)updateSyncMessageViaMCSWithRmqID:(NSString *)rmqID + error:(NSError **)error; + +/** + * Query sync message table for a given rmqID. + * + * @param rmqID The rmqID to search for in SYNC_RMQ. + * + * @return The sync message that was persisted with `rmqID`. If no such message was persisted + * return nil. + */ +- (FIRMessagingPersistentSyncMessage *)querySyncMessageWithRmqID:(NSString *)rmqID; + +/** + * Delete sync message with rmqID. + * + * @param rmqID The rmqID of the message to delete. + * + * @return YES if a sync message with rmqID was found and deleted successfully else NO. + */ +- (BOOL)deleteSyncMessageWithRmqID:(NSString *)rmqID; + +/** + * Delete the expired sync messages from persisten store. Also deletes messages that have been + * delivered both via APNS and MCS. + * + * @param error The error if any while deleting the messages. + * + * @return The total number of messages that were deleted from the persistent store. + */ +- (int)deleteExpiredOrFinishedSyncMessages:(NSError **)error; + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRmq2PersistentStore.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRmq2PersistentStore.m new file mode 100644 index 00000000..dc6e6c9c --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRmq2PersistentStore.m @@ -0,0 +1,807 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingRmq2PersistentStore.h" + +#import + +#import "FIRMessagingConstants.h" +#import "FIRMessagingDefines.h" +#import "FIRMessagingLogger.h" +#import "FIRMessagingPersistentSyncMessage.h" +#import "FIRMessagingUtilities.h" +#import "NSError+FIRMessaging.h" +#import "Protos/GtalkCore.pbobjc.h" + +#ifndef _FIRMessagingRmqLogAndExit +#define _FIRMessagingRmqLogAndExit(stmt, return_value) \ +do { \ +[self logErrorAndFinalizeStatement:stmt]; \ +return return_value; \ +} while(0) +#endif + +typedef enum : NSUInteger { + FIRMessagingRmqDirectoryUnknown, + FIRMessagingRmqDirectoryDocuments, + FIRMessagingRmqDirectoryApplicationSupport, +} FIRMessagingRmqDirectory; + +static NSString *const kFCMRmqStoreTag = @"FIRMessagingRmqStore:"; + +// table names +NSString *const kTableOutgoingRmqMessages = @"outgoingRmqMessages"; +NSString *const kTableLastRmqId = @"lastrmqid"; +NSString *const kOldTableS2DRmqIds = @"s2dRmqIds"; +NSString *const kTableS2DRmqIds = @"s2dRmqIds_1"; + +// Used to prevent de-duping of sync messages received both via APNS and MCS. +NSString *const kTableSyncMessages = @"incomingSyncMessages"; + +static NSString *const kTablePrefix = @""; + +// create tables +static NSString *const kCreateTableOutgoingRmqMessages = + @"create TABLE IF NOT EXISTS %@%@ " + @"(_id INTEGER PRIMARY KEY, " + @"rmq_id INTEGER, " + @"type INTEGER, " + @"ts INTEGER, " + @"data BLOB)"; + +static NSString *const kCreateTableLastRmqId = + @"create TABLE IF NOT EXISTS %@%@ " + @"(_id INTEGER PRIMARY KEY, " + @"rmq_id INTEGER)"; + +static NSString *const kCreateTableS2DRmqIds = + @"create TABLE IF NOT EXISTS %@%@ " + @"(_id INTEGER PRIMARY KEY, " + @"rmq_id TEXT)"; + +static NSString *const kCreateTableSyncMessages = + @"create TABLE IF NOT EXISTS %@%@ " + @"(_id INTEGER PRIMARY KEY, " + @"rmq_id TEXT, " + @"expiration_ts INTEGER, " + @"apns_recv INTEGER, " + @"mcs_recv INTEGER)"; + +static NSString *const kDropTableCommand = + @"drop TABLE if exists %@%@"; + +// table infos +static NSString *const kRmqIdColumn = @"rmq_id"; +static NSString *const kDataColumn = @"data"; +static NSString *const kProtobufTagColumn = @"type"; +static NSString *const kIdColumn = @"_id"; + +static NSString *const kOutgoingRmqMessagesColumns = @"rmq_id, type, data"; + +// Sync message columns +static NSString *const kSyncMessagesColumns = @"rmq_id, expiration_ts, apns_recv, mcs_recv"; +// Message time expiration in seconds since 1970 +static NSString *const kSyncMessageExpirationTimestampColumn = @"expiration_ts"; +static NSString *const kSyncMessageAPNSReceivedColumn = @"apns_recv"; +static NSString *const kSyncMessageMCSReceivedColumn = @"mcs_recv"; + +// table data handlers +typedef void(^FCMOutgoingRmqMessagesTableHandler)(int64_t rmqId, int8_t tag, NSData *data); + +// Utility to create an NSString from a sqlite3 result code +NSString * _Nonnull FIRMessagingStringFromSQLiteResult(int result) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability" + const char *errorStr = sqlite3_errstr(result); +#pragma pop + NSString *errorString = [NSString stringWithFormat:@"%d - %s", result, errorStr]; + return errorString; +} + +@interface FIRMessagingRmq2PersistentStore () { + sqlite3 *_database; +} + +@property(nonatomic, readwrite, strong) NSString *databaseName; +@property(nonatomic, readwrite, assign) FIRMessagingRmqDirectory currentDirectory; + +@end + +@implementation FIRMessagingRmq2PersistentStore + +- (instancetype)initWithDatabaseName:(NSString *)databaseName { + self = [super init]; + if (self) { + _databaseName = [databaseName copy]; + BOOL didMoveToApplicationSupport = + [self moveToApplicationSupportSubDirectory:kFIRMessagingApplicationSupportSubDirectory]; + + _currentDirectory = didMoveToApplicationSupport + ? FIRMessagingRmqDirectoryApplicationSupport + : FIRMessagingRmqDirectoryDocuments; + + [self openDatabase:_databaseName]; + } + return self; +} + +- (void)dealloc { + sqlite3_close(_database); +} + +- (BOOL)moveToApplicationSupportSubDirectory:(NSString *)subDirectoryName { + NSArray *directoryPaths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, + NSUserDomainMask, YES); + NSString *applicationSupportDirPath = directoryPaths.lastObject; + NSArray *components = @[applicationSupportDirPath, subDirectoryName]; + NSString *subDirectoryPath = [NSString pathWithComponents:components]; + BOOL hasSubDirectory; + + if (![[NSFileManager defaultManager] fileExistsAtPath:subDirectoryPath + isDirectory:&hasSubDirectory]) { + // Cannot move to non-existent directory + return NO; + } + + if ([self doesFileExistInDirectory:FIRMessagingRmqDirectoryDocuments]) { + NSString *oldPlistPath = [[self class] pathForDatabase:self.databaseName + inDirectory:FIRMessagingRmqDirectoryDocuments]; + NSString *newPlistPath = [[self class] + pathForDatabase:self.databaseName + inDirectory:FIRMessagingRmqDirectoryApplicationSupport]; + + if ([self doesFileExistInDirectory:FIRMessagingRmqDirectoryApplicationSupport]) { + // File exists in both Documents and ApplicationSupport, delete the one in Documents + NSError *deleteError; + if (![[NSFileManager defaultManager] removeItemAtPath:oldPlistPath error:&deleteError]) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeRmq2PersistentStore000, + @"Failed to delete old copy of %@.sqlite in Documents %@", + self.databaseName, deleteError); + } + return NO; + } + NSError *moveError; + if (![[NSFileManager defaultManager] moveItemAtPath:oldPlistPath + toPath:newPlistPath + error:&moveError]) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeRmq2PersistentStore001, + @"Failed to move file %@ from %@ to %@. Error: %@", self.databaseName, + oldPlistPath, newPlistPath, moveError); + return NO; + } + } + // We moved the file if it existed, otherwise we didn't need to do anything + return YES; +} + +- (BOOL)doesFileExistInDirectory:(FIRMessagingRmqDirectory)directory { + NSString *path = [[self class] pathForDatabase:self.databaseName inDirectory:directory]; + return [[NSFileManager defaultManager] fileExistsAtPath:path]; +} + ++ (NSString *)pathForDatabase:(NSString *)dbName inDirectory:(FIRMessagingRmqDirectory)directory { + NSArray *paths; + NSArray *components; + NSString *dbNameWithExtension = [NSString stringWithFormat:@"%@.sqlite", dbName]; + NSString *errorMessage; + + switch (directory) { + case FIRMessagingRmqDirectoryDocuments: + paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + components = @[paths.lastObject, dbNameWithExtension]; + break; + + case FIRMessagingRmqDirectoryApplicationSupport: + paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, + NSUserDomainMask, + YES); + components = @[ + paths.lastObject, + kFIRMessagingApplicationSupportSubDirectory, + dbNameWithExtension + ]; + break; + + default: + errorMessage = [NSString stringWithFormat:@"Invalid directory type %lu", + (unsigned long)directory]; + FIRMessagingLoggerError(kFIRMessagingMessageCodeRmq2PersistentStoreInvalidRmqDirectory, + @"%@", + errorMessage); + NSAssert(NO, errorMessage); + break; + } + + return [NSString pathWithComponents:components]; +} + +- (void)createTableWithName:(NSString *)tableName command:(NSString *)command { + char *error; + NSString *createDatabase = [NSString stringWithFormat:command, kTablePrefix, tableName]; + if (sqlite3_exec(_database, [createDatabase UTF8String], NULL, NULL, &error) != SQLITE_OK) { + // remove db before failing + [self removeDatabase]; + NSString *errorMessage = [NSString stringWithFormat:@"Couldn't create table: %@ %@", + kCreateTableOutgoingRmqMessages, + [NSString stringWithCString:error encoding:NSUTF8StringEncoding]]; + FIRMessagingLoggerError(kFIRMessagingMessageCodeRmq2PersistentStoreErrorCreatingTable, + @"%@", + errorMessage); + NSAssert(NO, errorMessage); + } +} + +- (void)dropTableWithName:(NSString *)tableName { + char *error; + NSString *dropTableSQL = [NSString stringWithFormat:kDropTableCommand, kTablePrefix, tableName]; + if (sqlite3_exec(_database, [dropTableSQL UTF8String], NULL, NULL, &error) != SQLITE_OK) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeRmq2PersistentStore002, + @"Failed to remove table %@", tableName); + } +} + +- (void)removeDatabase { + NSString *path = [[self class] pathForDatabase:self.databaseName + inDirectory:self.currentDirectory]; + [[NSFileManager defaultManager] removeItemAtPath:path error:nil]; +} + ++ (void)removeDatabase:(NSString *)dbName { + NSString *documentsDirPath = [self pathForDatabase:dbName + inDirectory:FIRMessagingRmqDirectoryDocuments]; + NSString *applicationSupportDirPath = + [self pathForDatabase:dbName inDirectory:FIRMessagingRmqDirectoryApplicationSupport]; + [[NSFileManager defaultManager] removeItemAtPath:documentsDirPath error:nil]; + [[NSFileManager defaultManager] removeItemAtPath:applicationSupportDirPath error:nil]; +} + +- (void)openDatabase:(NSString *)dbName { + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSString *path = [[self class] pathForDatabase:dbName inDirectory:self.currentDirectory]; + + BOOL didOpenDatabase = YES; + if (![fileManager fileExistsAtPath:path]) { + // We've to separate between different versions here because of backwards compatbility issues. + int result = sqlite3_open([path UTF8String], &_database); + if (result != SQLITE_OK) { + NSString *errorString = FIRMessagingStringFromSQLiteResult(result); + NSString *errorMessage = + [NSString stringWithFormat:@"Could not open existing RMQ database at path %@, error: %@", + path, + errorString]; + FIRMessagingLoggerError(kFIRMessagingMessageCodeRmq2PersistentStoreErrorOpeningDatabase, + @"%@", + errorMessage); + NSAssert(NO, errorMessage); + return; + } + [self createTableWithName:kTableOutgoingRmqMessages + command:kCreateTableOutgoingRmqMessages]; + + [self createTableWithName:kTableLastRmqId command:kCreateTableLastRmqId]; + [self createTableWithName:kTableS2DRmqIds command:kCreateTableS2DRmqIds]; + } else { + // Calling sqlite3_open should create the database, since the file doesn't exist. + int result = sqlite3_open([path UTF8String], &_database); + if (result != SQLITE_OK) { + NSString *errorString = FIRMessagingStringFromSQLiteResult(result); + NSString *errorMessage = + [NSString stringWithFormat:@"Could not create RMQ database at path %@, error: %@", + path, + errorString]; + FIRMessagingLoggerError(kFIRMessagingMessageCodeRmq2PersistentStoreErrorCreatingDatabase, + @"%@", + errorMessage); + NSAssert(NO, errorMessage); + didOpenDatabase = NO; + } else { + [self updateDbWithStringRmqID]; + } + } + + if (didOpenDatabase) { + [self createTableWithName:kTableSyncMessages command:kCreateTableSyncMessages]; + } +} + +- (void)updateDbWithStringRmqID { + [self createTableWithName:kTableS2DRmqIds command:kCreateTableS2DRmqIds]; + [self dropTableWithName:kOldTableS2DRmqIds]; +} + +#pragma mark - Insert + +- (BOOL)saveUnackedS2dMessageWithRmqId:(NSString *)rmqId { + NSString *insertFormat = @"INSERT INTO %@ (%@) VALUES (?)"; + NSString *insertSQL = [NSString stringWithFormat:insertFormat, + kTableS2DRmqIds, + kRmqIdColumn]; + sqlite3_stmt *insert_statement; + if (sqlite3_prepare_v2(_database, [insertSQL UTF8String], -1, &insert_statement, NULL) + != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(insert_statement, NO); + } + if (sqlite3_bind_text(insert_statement, + 1, + [rmqId UTF8String], + (int)[rmqId length], + SQLITE_STATIC) != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(insert_statement, NO); + } + if (sqlite3_step(insert_statement) != SQLITE_DONE) { + _FIRMessagingRmqLogAndExit(insert_statement, NO); + } + sqlite3_finalize(insert_statement); + return YES; +} + +- (BOOL)saveMessageWithRmqId:(int64_t)rmqId + tag:(int8_t)tag + data:(NSData *)data + error:(NSError **)error { + NSString *insertFormat = @"INSERT INTO %@ (%@, %@, %@) VALUES (?, ?, ?)"; + NSString *insertSQL = [NSString stringWithFormat:insertFormat, + kTableOutgoingRmqMessages, // table + kRmqIdColumn, kProtobufTagColumn, kDataColumn /* columns */]; + sqlite3_stmt *insert_statement; + if (sqlite3_prepare_v2(_database, [insertSQL UTF8String], -1, &insert_statement, NULL) + != SQLITE_OK) { + if (error) { + *error = [NSError errorWithDomain:[NSString stringWithFormat:@"%s", sqlite3_errmsg(_database)] + code:sqlite3_errcode(_database) + userInfo:nil]; + } + _FIRMessagingRmqLogAndExit(insert_statement, NO); + } + if (sqlite3_bind_int64(insert_statement, 1, rmqId) != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(insert_statement, NO); + } + if (sqlite3_bind_int(insert_statement, 2, tag) != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(insert_statement, NO); + } + if (sqlite3_bind_blob(insert_statement, 3, [data bytes], (int)[data length], NULL) != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(insert_statement, NO); + } + if (sqlite3_step(insert_statement) != SQLITE_DONE) { + _FIRMessagingRmqLogAndExit(insert_statement, NO); + } + + sqlite3_finalize(insert_statement); + return YES; +} + +- (int)deleteMessagesFromTable:(NSString *)tableName + withRmqIds:(NSArray *)rmqIds { + _FIRMessagingDevAssert([tableName isEqualToString:kTableOutgoingRmqMessages] || + [tableName isEqualToString:kTableLastRmqId] || + [tableName isEqualToString:kTableS2DRmqIds] || + [tableName isEqualToString:kTableSyncMessages], + @"%@: Invalid Table Name %@", kFCMRmqStoreTag, tableName); + + BOOL isRmqIDString = NO; + // RmqID is a string only for outgoing messages + if ([tableName isEqualToString:kTableS2DRmqIds] || + [tableName isEqualToString:kTableSyncMessages]) { + isRmqIDString = YES; + } + + NSMutableString *delete = [NSMutableString stringWithFormat:@"DELETE FROM %@ WHERE ", tableName]; + + NSString *toDeleteArgument = [NSString stringWithFormat:@"%@ = ? OR ", kRmqIdColumn]; + + int toDelete = (int)[rmqIds count]; + if (toDelete == 0) { + return 0; + } + int maxBatchSize = 100; + int start = 0; + int deleteCount = 0; + while (start < toDelete) { + + // construct the WHERE argument + int end = MIN(start + maxBatchSize, toDelete); + NSMutableString *whereArgument = [NSMutableString string]; + for (int i = start; i < end; i++) { + [whereArgument appendString:toDeleteArgument]; + } + // remove the last * OR * from argument + NSRange range = NSMakeRange([whereArgument length] -4, 4); + [whereArgument deleteCharactersInRange:range]; + NSString *deleteQuery = [NSString stringWithFormat:@"%@ %@", delete, whereArgument]; + + + // sqlite update + sqlite3_stmt *delete_statement; + if (sqlite3_prepare_v2(_database, [deleteQuery UTF8String], + -1, &delete_statement, NULL) != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(delete_statement, 0); + } + + // bind values + int rmqIndex = 0; + int placeholderIndex = 1; // placeholders in sqlite3 start with 1 + for (NSString *rmqId in rmqIds) { // objectAtIndex: is O(n) -- would make it slow + if (rmqIndex < start) { + rmqIndex++; + continue; + } else if (rmqIndex >= end) { + break; + } else { + if (isRmqIDString) { + if (sqlite3_bind_text(delete_statement, + placeholderIndex, + [rmqId UTF8String], + (int)[rmqId length], + SQLITE_STATIC) != SQLITE_OK) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeRmq2PersistentStore003, + @"Failed to bind rmqID %@", rmqId); + continue; + } + } else { + int64_t rmqIdValue = [rmqId longLongValue]; + sqlite3_bind_int64(delete_statement, placeholderIndex, rmqIdValue); + } + placeholderIndex++; + } + rmqIndex++; + } + if (sqlite3_step(delete_statement) != SQLITE_DONE) { + _FIRMessagingRmqLogAndExit(delete_statement, deleteCount); + } + sqlite3_finalize(delete_statement); + deleteCount += sqlite3_changes(_database); + start = end; + } + + // if we are here all of our sqlite queries should have succeeded + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeRmq2PersistentStore004, + @"%@ Trying to delete %d s2D ID's, successfully deleted %d", + kFCMRmqStoreTag, toDelete, deleteCount); + return deleteCount; +} + +#pragma mark - Query + +- (int64_t)queryHighestRmqId { + NSString *queryFormat = @"SELECT %@ FROM %@ ORDER BY %@ DESC LIMIT %d"; + NSString *query = [NSString stringWithFormat:queryFormat, + kRmqIdColumn, // column + kTableOutgoingRmqMessages, // table + kRmqIdColumn, // order by column + 1]; // limit + + sqlite3_stmt *statement; + int64_t highestRmqId = 0; + if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &statement, NULL) != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(statement, highestRmqId); + } + if (sqlite3_step(statement) == SQLITE_ROW) { + highestRmqId = sqlite3_column_int64(statement, 0); + } + sqlite3_finalize(statement); + return highestRmqId; +} + +- (int64_t)queryLastRmqId { + NSString *queryFormat = @"SELECT %@ FROM %@ ORDER BY %@ DESC LIMIT %d"; + NSString *query = [NSString stringWithFormat:queryFormat, + kRmqIdColumn, // column + kTableLastRmqId, // table + kRmqIdColumn, // order by column + 1]; // limit + + sqlite3_stmt *statement; + int64_t lastRmqId = 0; + if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &statement, NULL) != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(statement, lastRmqId); + } + if (sqlite3_step(statement) == SQLITE_ROW) { + lastRmqId = sqlite3_column_int64(statement, 0); + } + sqlite3_finalize(statement); + return lastRmqId; +} + +- (BOOL)updateLastOutgoingRmqId:(int64_t)rmqID { + NSString *queryFormat = @"INSERT OR REPLACE INTO %@ (%@, %@) VALUES (?, ?)"; + NSString *query = [NSString stringWithFormat:queryFormat, + kTableLastRmqId, // table + kIdColumn, kRmqIdColumn]; // columns + sqlite3_stmt *statement; + if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &statement, NULL) != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(statement, NO); + } + if (sqlite3_bind_int(statement, 1, 1) != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(statement, NO); + } + if (sqlite3_bind_int64(statement, 2, rmqID) != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(statement, NO); + } + if (sqlite3_step(statement) != SQLITE_DONE) { + _FIRMessagingRmqLogAndExit(statement, NO); + } + sqlite3_finalize(statement); + return YES; +} + +- (NSArray *)unackedS2dRmqIds { + NSString *queryFormat = @"SELECT %@ FROM %@ ORDER BY %@ ASC"; + NSString *query = [NSString stringWithFormat:queryFormat, + kRmqIdColumn, + kTableS2DRmqIds, + kRmqIdColumn]; + sqlite3_stmt *statement; + if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &statement, NULL) != SQLITE_OK) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeRmq2PersistentStore005, + @"%@: Could not find s2d ids", kFCMRmqStoreTag); + _FIRMessagingRmqLogAndExit(statement, @[]); + } + NSMutableArray *rmqIDArray = [NSMutableArray array]; + while (sqlite3_step(statement) == SQLITE_ROW) { + const char *rmqID = (char *)sqlite3_column_text(statement, 0); + [rmqIDArray addObject:[NSString stringWithUTF8String:rmqID]]; + } + sqlite3_finalize(statement); + return rmqIDArray; +} + +#pragma mark - Scan + +- (void)scanOutgoingRmqMessagesWithHandler:(FCMOutgoingRmqMessagesTableHandler)handler { + static NSString *queryFormat = @"SELECT %@ FROM %@ WHERE %@ != 0 ORDER BY %@ ASC"; + NSString *query = [NSString stringWithFormat:queryFormat, + kOutgoingRmqMessagesColumns, // select (rmq_id, type, data) + kTableOutgoingRmqMessages, // from table + kRmqIdColumn, // where + kRmqIdColumn]; // order by + sqlite3_stmt *statement; + if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &statement, NULL) != SQLITE_OK) { + [self logError]; + sqlite3_finalize(statement); + return; + } + // can query sqlite3 for this but this is fine + const int rmqIdColumnNumber = 0; + const int typeColumnNumber = 1; + const int dataColumnNumber = 2; + while (sqlite3_step(statement) == SQLITE_ROW) { + int64_t rmqId = sqlite3_column_int64(statement, rmqIdColumnNumber); + int8_t type = sqlite3_column_int(statement, typeColumnNumber); + const void *bytes = sqlite3_column_blob(statement, dataColumnNumber); + int length = sqlite3_column_bytes(statement, dataColumnNumber); + _FIRMessagingDevAssert(bytes != NULL, + @"%@ Message with no data being stored in Rmq", + kFCMRmqStoreTag); + NSData *data = [NSData dataWithBytes:bytes length:length]; + handler(rmqId, type, data); + } + sqlite3_finalize(statement); +} + +#pragma mark - Sync Messages + +- (FIRMessagingPersistentSyncMessage *)querySyncMessageWithRmqID:(NSString *)rmqID { + _FIRMessagingDevAssert([rmqID length], @"Invalid rmqID key %@ to search in SYNC_RMQ", rmqID); + + NSString *queryFormat = @"SELECT %@ FROM %@ WHERE %@ = '%@'"; + NSString *query = [NSString stringWithFormat:queryFormat, + kSyncMessagesColumns, // SELECT (rmq_id, expiration_ts, apns_recv, mcs_recv) + kTableSyncMessages, // FROM sync_rmq + kRmqIdColumn, // WHERE rmq_id + rmqID]; + + sqlite3_stmt *stmt; + if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &stmt, NULL) != SQLITE_OK) { + [self logError]; + sqlite3_finalize(stmt); + return nil; + } + + const int rmqIDColumn = 0; + const int expirationTimestampColumn = 1; + const int apnsReceivedColumn = 2; + const int mcsReceivedColumn = 3; + + int count = 0; + FIRMessagingPersistentSyncMessage *persistentMessage; + + while (sqlite3_step(stmt) == SQLITE_ROW) { + NSString *rmqID = + [NSString stringWithUTF8String:(char *)sqlite3_column_text(stmt, rmqIDColumn)]; + int64_t expirationTimestamp = sqlite3_column_int64(stmt, expirationTimestampColumn); + BOOL apnsReceived = sqlite3_column_int(stmt, apnsReceivedColumn); + BOOL mcsReceived = sqlite3_column_int(stmt, mcsReceivedColumn); + + // create a new persistent message + persistentMessage = + [[FIRMessagingPersistentSyncMessage alloc] initWithRMQID:rmqID expirationTime:expirationTimestamp]; + persistentMessage.apnsReceived = apnsReceived; + persistentMessage.mcsReceived = mcsReceived; + + count++; + } + sqlite3_finalize(stmt); + + _FIRMessagingDevAssert(count <= 1, @"Found multiple messages in %@ with same RMQ ID", kTableSyncMessages); + return persistentMessage; +} + +- (BOOL)deleteSyncMessageWithRmqID:(NSString *)rmqID { + _FIRMessagingDevAssert([rmqID length], @"Invalid rmqID key %@ to delete in SYNC_RMQ", rmqID); + return [self deleteMessagesFromTable:kTableSyncMessages withRmqIds:@[rmqID]] > 0; +} + +- (int)deleteExpiredOrFinishedSyncMessages:(NSError *__autoreleasing *)error { + int64_t now = FIRMessagingCurrentTimestampInSeconds(); + NSString *deleteSQL = @"DELETE FROM %@ " + @"WHERE %@ < %lld OR " // expirationTime < now + @"(%@ = 1 AND %@ = 1)"; // apns_received = 1 AND mcs_received = 1 + NSString *query = [NSString stringWithFormat:deleteSQL, + kTableSyncMessages, + kSyncMessageExpirationTimestampColumn, + now, + kSyncMessageAPNSReceivedColumn, + kSyncMessageMCSReceivedColumn]; + + NSString *errorReason = @"Failed to save delete expired sync messages from store."; + + sqlite3_stmt *stmt; + if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &stmt, NULL) != SQLITE_OK) { + if (error) { + *error = [NSError fcm_errorWithCode:sqlite3_errcode(_database) + userInfo:@{ @"error" : errorReason }]; + } + _FIRMessagingRmqLogAndExit(stmt, 0); + } + + if (sqlite3_step(stmt) != SQLITE_DONE) { + if (error) { + *error = [NSError fcm_errorWithCode:sqlite3_errcode(_database) + userInfo:@{ @"error" : errorReason }]; + } + _FIRMessagingRmqLogAndExit(stmt, 0); + } + + sqlite3_finalize(stmt); + int deleteCount = sqlite3_changes(_database); + return deleteCount; +} + +- (BOOL)saveSyncMessageWithRmqID:(NSString *)rmqID + expirationTime:(int64_t)expirationTime + apnsReceived:(BOOL)apnsReceived + mcsReceived:(BOOL)mcsReceived + error:(NSError **)error { + _FIRMessagingDevAssert([rmqID length], @"Invalid nil message to persist to SYNC_RMQ"); + + NSString *insertFormat = @"INSERT INTO %@ (%@, %@, %@, %@) VALUES (?, ?, ?, ?)"; + NSString *insertSQL = [NSString stringWithFormat:insertFormat, + kTableSyncMessages, // Table name + kRmqIdColumn, // rmq_id + kSyncMessageExpirationTimestampColumn, // expiration_ts + kSyncMessageAPNSReceivedColumn, // apns_recv + kSyncMessageMCSReceivedColumn /* mcs_recv */]; + + sqlite3_stmt *stmt; + + if (sqlite3_prepare_v2(_database, [insertSQL UTF8String], -1, &stmt, NULL) != SQLITE_OK) { + if (error) { + *error = [NSError fcm_errorWithCode:sqlite3_errcode(_database) + userInfo:@{ @"error" : @"Failed to save sync message to store." }]; + } + _FIRMessagingRmqLogAndExit(stmt, NO); + } + + if (sqlite3_bind_text(stmt, 1, [rmqID UTF8String], (int)[rmqID length], NULL) != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(stmt, NO); + } + + if (sqlite3_bind_int64(stmt, 2, expirationTime) != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(stmt, NO); + } + + if (sqlite3_bind_int(stmt, 3, apnsReceived ? 1 : 0) != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(stmt, NO); + } + + if (sqlite3_bind_int(stmt, 4, mcsReceived ? 1 : 0) != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(stmt, NO); + } + + if (sqlite3_step(stmt) != SQLITE_DONE) { + _FIRMessagingRmqLogAndExit(stmt, NO); + } + + sqlite3_finalize(stmt); + return YES; +} + +- (BOOL)updateSyncMessageViaAPNSWithRmqID:(NSString *)rmqID + error:(NSError **)error { + return [self updateSyncMessageWithRmqID:rmqID + column:kSyncMessageAPNSReceivedColumn + value:YES + error:error]; +} + +- (BOOL)updateSyncMessageViaMCSWithRmqID:(NSString *)rmqID + error:(NSError *__autoreleasing *)error { + return [self updateSyncMessageWithRmqID:rmqID + column:kSyncMessageMCSReceivedColumn + value:YES + error:error]; +} + +- (BOOL)updateSyncMessageWithRmqID:(NSString *)rmqID + column:(NSString *)column + value:(BOOL)value + error:(NSError **)error { + _FIRMessagingDevAssert([column isEqualToString:kSyncMessageAPNSReceivedColumn] || + [column isEqualToString:kSyncMessageMCSReceivedColumn], + @"Invalid column name %@ for SYNC_RMQ", column); + NSString *queryFormat = @"UPDATE %@ " // Table name + @"SET %@ = %d " // column=value + @"WHERE %@ = ?"; // condition + NSString *query = [NSString stringWithFormat:queryFormat, + kTableSyncMessages, + column, + value ? 1 : 0, + kRmqIdColumn]; + sqlite3_stmt *stmt; + + if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &stmt, NULL) != SQLITE_OK) { + if (error) { + *error = [NSError fcm_errorWithCode:sqlite3_errcode(_database) + userInfo:@{ @"error" : @"Failed to update sync message"}]; + } + _FIRMessagingRmqLogAndExit(stmt, NO); + } + + if (sqlite3_bind_text(stmt, 1, [rmqID UTF8String], (int)[rmqID length], NULL) != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(stmt, NO); + } + + if (sqlite3_step(stmt) != SQLITE_DONE) { + _FIRMessagingRmqLogAndExit(stmt, NO); + } + + sqlite3_finalize(stmt); + return YES; + +} + +#pragma mark - Private + +- (NSString *)lastErrorMessage { + return [NSString stringWithFormat:@"%s", sqlite3_errmsg(_database)]; +} + +- (int)lastErrorCode { + return sqlite3_errcode(_database); +} + +- (void)logError { + FIRMessagingLoggerError(kFIRMessagingMessageCodeRmq2PersistentStore006, + @"%@ error: code (%d) message: %@", kFCMRmqStoreTag, [self lastErrorCode], + [self lastErrorMessage]); +} + +- (void)logErrorAndFinalizeStatement:(sqlite3_stmt *)stmt { + [self logError]; + sqlite3_finalize(stmt); +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRmqManager.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRmqManager.h new file mode 100644 index 00000000..ba48b983 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRmqManager.h @@ -0,0 +1,190 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class GtalkDataMessageStanza; +@class GPBMessage; + +@class FIRMessagingPersistentSyncMessage; + +/** + * Called on each raw message. + */ +typedef void(^FIRMessagingRmqMessageHandler)(int64_t rmqId, int8_t tag, NSData *data); + +/** + * Called on each DataMessageStanza. + */ +typedef void(^FIRMessagingDataMessageHandler)(int64_t rmqId, GtalkDataMessageStanza *stanza); + +/** + * Used to scan through the rmq and perform actions on messages as required. + */ +@protocol FIRMessagingRmqScanner + +/** + * Scan the RMQ for outgoing messages and process them as required. + */ +- (void)scanWithRmqMessageHandler:(FIRMessagingRmqMessageHandler)rmqMessageHandler + dataMessageHandler:(FIRMessagingDataMessageHandler)dataMessageHandler; + +@end + +/** + * This manages the RMQ persistent store. + * + * The store is used to store all the S2D id's that were received by the client and were ACK'ed + * by us but the server hasn't confirmed the ACK. We don't delete these id's until the server + * ACK's us that they have received them. + * + * We also store the upstream messages(d2s) that were sent by the client. + * + * Also store the lastRMQId that was sent by us so that for a new connection being setup we don't + * duplicate RMQ Id's for the new messages. + */ +@interface FIRMessagingRmqManager : NSObject + +// designated initializer +- (instancetype)initWithDatabaseName:(NSString *)databaseName; + +- (void)loadRmqId; + +/** + * Save an upstream message to RMQ. If the message send fails for some reason we would not + * lose the message since it would be saved in the RMQ. + * + * @param message The upstream message to be saved. + * @param error The error if any while saving the message else nil. + * + * @return YES if the message was successfully saved to RMQ else NO. + */ +- (BOOL)saveRmqMessage:(GPBMessage *)message error:(NSError **)error; + +/** + * Save Server to device message with the given RMQ-ID. + * + * @param rmqID The rmqID of the s2d message to save. + * + * @return YES if the save was successfull else NO. + */ +- (BOOL)saveS2dMessageWithRmqId:(NSString *)rmqID; + +/** + * A list of all unacked Server to device RMQ IDs. + * + * @return A list of unacked Server to Device RMQ ID's. All values are Strings. + */ +- (NSArray *)unackedS2dRmqIds; + +/** + * Removes the outgoing message from RMQ store. + * + * @param rmqId The rmqID to remove from the store. + * + * @return The number of messages deleted successfully. + */ +- (int)removeRmqMessagesWithRmqId:(NSString *)rmqId; + +/** + * Removes the messages with the given rmqIDs from RMQ store. + * + * @param rmqIds The lsit of rmqID's to remove from the store. + * + * @return The number of messages deleted successfully. + */ +- (int)removeRmqMessagesWithRmqIds:(NSArray *)rmqIds; + +/** + * Removes a list of downstream messages from the RMQ. + * + * @param s2dIds The list of messages ACK'ed by the server that we should remove + * from the RMQ store. + */ +- (void)removeS2dIds:(NSArray *)s2dIds; + +#pragma mark - Sync Messages + +/** + * Get persisted sync message with rmqID. + * + * @param rmqID The rmqID of the persisted sync message. + * + * @return A valid persistent sync message with the given rmqID if found in the RMQ else nil. + */ +- (FIRMessagingPersistentSyncMessage *)querySyncMessageWithRmqID:(NSString *)rmqID; + +/** + * Delete sync message with rmqID. + * + * @param rmqID The rmqID of the persisted sync message. + * + * @return YES if the message was successfully deleted else NO. + */ +- (BOOL)deleteSyncMessageWithRmqID:(NSString *)rmqID; + +/** + * Delete the expired sync messages from persisten store. Also deletes messages that have been + * delivered both via APNS and MCS. + * + * @param error The error if any while deleting the messages. + * + * @return The total number of messages that were deleted from the persistent store. + */ +- (int)deleteExpiredOrFinishedSyncMessages:(NSError **)error; + +/** + * Save sync message received by the device. + * + * @param rmqID The rmqID of the message received. + * @param expirationTime The expiration time of the sync message received. + * @param apnsReceived YES if the message was received via APNS else NO. + * @param mcsReceived YES if the message was received via MCS else NO. + * @param error The error if any while saving the sync message to persistent store. + * + * @return YES if the message save was successful else NO. + */ +- (BOOL)saveSyncMessageWithRmqID:(NSString *)rmqID + expirationTime:(int64_t)expirationTime + apnsReceived:(BOOL)apnsReceived + mcsReceived:(BOOL)mcsReceived + error:(NSError **)error; + +/** + * Update sync message received via APNS. + * + * @param rmqID The rmqID of the received message. + * @param error The error if any while updating the sync message. + * + * @return YES if the persistent sync message was successfully updated else NO. + */ +- (BOOL)updateSyncMessageViaAPNSWithRmqID:(NSString *)rmqID error:(NSError **)error; + +/** + * Update sync message received via MCS. + * + * @param rmqID The rmqID of the received message. + * @param error The error if any while updating the sync message. + * + * @return YES if the persistent sync message was successfully updated else NO. + */ +- (BOOL)updateSyncMessageViaMCSWithRmqID:(NSString *)rmqID error:(NSError **)error; + +#pragma mark - Testing + ++ (void)removeDatabaseWithName:(NSString *)dbName; + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRmqManager.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRmqManager.m new file mode 100644 index 00000000..449e3d6d --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingRmqManager.m @@ -0,0 +1,264 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingRmqManager.h" + +#import + +#import "FIRMessagingDefines.h" +#import "FIRMessagingLogger.h" +#import "FIRMessagingRmq2PersistentStore.h" +#import "FIRMessagingUtilities.h" +#import "Protos/GtalkCore.pbobjc.h" + +#ifndef _FIRMessagingRmqLogAndExit +#define _FIRMessagingRmqLogAndExit(stmt, return_value) \ +do { \ + [self logErrorAndFinalizeStatement:stmt]; \ + return return_value; \ +} while(0) +#endif + +static NSString *const kFCMRmqTag = @"FIRMessagingRmq:"; + +@interface FIRMessagingRmqManager () + +@property(nonatomic, readwrite, strong) FIRMessagingRmq2PersistentStore *rmq2Store; +// map the category of an outgoing message with the number of messages for that category +// should always have two keys -- the app, gcm +@property(nonatomic, readwrite, strong) NSMutableDictionary *outstandingMessages; + +// Outgoing RMQ persistent id +@property(nonatomic, readwrite, assign) int64_t rmqId; + +@end + +@implementation FIRMessagingRmqManager + +- (instancetype)initWithDatabaseName:(NSString *)databaseName { + self = [super init]; + if (self) { + _FIRMessagingDevAssert([databaseName length] > 0, @"RMQ: Invalid rmq db name"); + _rmq2Store = [[FIRMessagingRmq2PersistentStore alloc] initWithDatabaseName:databaseName]; + _outstandingMessages = [NSMutableDictionary dictionaryWithCapacity:2]; + _rmqId = -1; + } + return self; +} + +- (void)loadRmqId { + if (self.rmqId >= 0) { + return; // already done + } + + [self loadInitialOutgoingPersistentId]; + if (self.outstandingMessages.count) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeRmqManager000, + @"%@: outstanding categories %ld", kFCMRmqTag, + _FIRMessaging_UL(self.outstandingMessages.count)); + } +} + +/** + * Initialize the 'initial RMQ': + * - max ID of any message in the queue + * - if the queue is empty, stored value in separate DB. + * + * Stream acks will remove from RMQ, when we remove the highest message we keep track + * of its ID. + */ +- (void)loadInitialOutgoingPersistentId { + + // we shouldn't always trust the lastRmqId stored in the LastRmqId table, because + // we only save to the LastRmqId table once in a while (after getting the lastRmqId sent + // by the server after reconnect, and after getting a rmq ack from the server). The + // rmq message with the highest rmq id tells the real story, so check against that first. + + int64_t rmqId = [self queryHighestRmqId]; + if (rmqId == 0) { + rmqId = [self querylastRmqId]; + } + self.rmqId = rmqId + 1; +} + +#pragma mark - Save + +/** + * Save a message to RMQ2. Will populate the rmq2 persistent ID. + */ +- (BOOL)saveRmqMessage:(GPBMessage *)message + error:(NSError **)error { + // send using rmq2manager + // the wire format of rmq2 id is a string. However, we keep it as a long internally + // in the database. So only convert the id to string when preparing for sending over + // the wire. + NSString *rmq2Id = FIRMessagingGetRmq2Id(message); + if (![rmq2Id length]) { + int64_t rmqId = [self nextRmqId]; + rmq2Id = [NSString stringWithFormat:@"%lld", rmqId]; + FIRMessagingSetRmq2Id(message, rmq2Id); + } + FIRMessagingProtoTag tag = FIRMessagingGetTagForProto(message); + return [self saveMessage:message withRmqId:[rmq2Id integerValue] tag:tag error:error]; +} + +- (BOOL)saveMessage:(GPBMessage *)message + withRmqId:(int64_t)rmqId + tag:(int8_t)tag + error:(NSError **)error { + NSData *data = [message data]; + return [self.rmq2Store saveMessageWithRmqId:rmqId tag:tag data:data error:error]; +} + +/** + * This is called when we delete the largest outgoing message from queue. + */ +- (void)saveLastOutgoingRmqId:(int64_t)rmqID { + [self.rmq2Store updateLastOutgoingRmqId:rmqID]; +} + +- (BOOL)saveS2dMessageWithRmqId:(NSString *)rmqID { + return [self.rmq2Store saveUnackedS2dMessageWithRmqId:rmqID]; +} + +#pragma mark - Query + +- (int64_t)queryHighestRmqId { + return [self.rmq2Store queryHighestRmqId]; +} + +- (int64_t)querylastRmqId { + return [self.rmq2Store queryLastRmqId]; +} + +- (NSArray *)unackedS2dRmqIds { + return [self.rmq2Store unackedS2dRmqIds]; +} + +#pragma mark - FIRMessagingRMQScanner protocol + +/** + * We don't have a 'getMessages' method - it would require loading in memory + * the entire content body of all messages. + * + * Instead we iterate and call 'resend' for each message. + * + * This is called: + * - on connect MCS, to resend any outstanding messages + * - init + */ +- (void)scanWithRmqMessageHandler:(FIRMessagingRmqMessageHandler)rmqMessageHandler + dataMessageHandler:(FIRMessagingDataMessageHandler)dataMessageHandler { + // no need to scan database with no callbacks + if (rmqMessageHandler || dataMessageHandler) { + [self.rmq2Store scanOutgoingRmqMessagesWithHandler:^(int64_t rmqId, int8_t tag, NSData *data) { + if (rmqMessageHandler != nil) { + rmqMessageHandler(rmqId, tag, data); + } + if (dataMessageHandler != nil && kFIRMessagingProtoTagDataMessageStanza == tag) { + GPBMessage *proto = + [FIRMessagingGetClassForTag((FIRMessagingProtoTag)tag) parseFromData:data error:NULL]; + GtalkDataMessageStanza *stanza = (GtalkDataMessageStanza *)proto; + dataMessageHandler(rmqId, stanza); + } + }]; + } +} + +#pragma mark - Remove + +- (void)ackReceivedForRmqId:(NSString *)rmqId { + // TODO: Optional book-keeping +} + +- (int)removeRmqMessagesWithRmqId:(NSString *)rmqId { + return [self removeRmqMessagesWithRmqIds:@[rmqId]]; +} + +- (int)removeRmqMessagesWithRmqIds:(NSArray *)rmqIds { + if (![rmqIds count]) { + return 0; + } + for (NSString *rmqId in rmqIds) { + [self ackReceivedForRmqId:rmqId]; + } + int64_t maxRmqId = -1; + for (NSString *rmqId in rmqIds) { + int64_t rmqIdValue = [rmqId longLongValue]; + if (rmqIdValue > maxRmqId) { + maxRmqId = rmqIdValue; + } + } + maxRmqId++; + if (maxRmqId >= self.rmqId) { + [self saveLastOutgoingRmqId:maxRmqId]; + } + return [self.rmq2Store deleteMessagesFromTable:kTableOutgoingRmqMessages withRmqIds:rmqIds]; +} + +- (void)removeS2dIds:(NSArray *)s2dIds { + [self.rmq2Store deleteMessagesFromTable:kTableS2DRmqIds withRmqIds:s2dIds]; +} + +#pragma mark - Sync Messages + +// TODO: RMQManager should also have a cache for all the sync messages +// so we don't hit the DB each time. +- (FIRMessagingPersistentSyncMessage *)querySyncMessageWithRmqID:(NSString *)rmqID { + return [self.rmq2Store querySyncMessageWithRmqID:rmqID]; +} + +- (BOOL)deleteSyncMessageWithRmqID:(NSString *)rmqID { + return [self.rmq2Store deleteSyncMessageWithRmqID:rmqID]; +} + +- (int)deleteExpiredOrFinishedSyncMessages:(NSError **)error { + return [self.rmq2Store deleteExpiredOrFinishedSyncMessages:error]; +} + +- (BOOL)saveSyncMessageWithRmqID:(NSString *)rmqID + expirationTime:(int64_t)expirationTime + apnsReceived:(BOOL)apnsReceived + mcsReceived:(BOOL)mcsReceived + error:(NSError *__autoreleasing *)error { + return [self.rmq2Store saveSyncMessageWithRmqID:rmqID + expirationTime:expirationTime + apnsReceived:apnsReceived + mcsReceived:mcsReceived + error:error]; +} + +- (BOOL)updateSyncMessageViaAPNSWithRmqID:(NSString *)rmqID error:(NSError **)error { + return [self.rmq2Store updateSyncMessageViaAPNSWithRmqID:rmqID error:error]; +} + +- (BOOL)updateSyncMessageViaMCSWithRmqID:(NSString *)rmqID error:(NSError **)error { + return [self.rmq2Store updateSyncMessageViaMCSWithRmqID:rmqID error:error]; +} + +#pragma mark - Testing + ++ (void)removeDatabaseWithName:(NSString *)dbName { + [FIRMessagingRmq2PersistentStore removeDatabase:dbName]; +} + +#pragma mark - Private + +- (int64_t)nextRmqId { + return ++self.rmqId; +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingSecureSocket.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingSecureSocket.h new file mode 100644 index 00000000..169f60e6 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingSecureSocket.h @@ -0,0 +1,56 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +typedef NS_ENUM(NSUInteger, FIRMessagingSecureSocketState){ + kFIRMessagingSecureSocketNotOpen = 0, + kFIRMessagingSecureSocketOpening, + kFIRMessagingSecureSocketOpen, + kFIRMessagingSecureSocketClosing, + kFIRMessagingSecureSocketClosed, + kFIRMessagingSecureSocketError +}; + +@class FIRMessagingSecureSocket; + +@protocol FIRMessagingSecureSocketDelegate + +- (void)secureSocket:(FIRMessagingSecureSocket *)socket + didReceiveData:(NSData *)data + withTag:(int8_t)tag; +- (void)secureSocket:(FIRMessagingSecureSocket *)socket + didSendProtoWithTag:(int8_t)tag + rmqId:(NSString *)rmqId; +- (void)secureSocketDidConnect:(FIRMessagingSecureSocket *)socket; +- (void)didDisconnectWithSecureSocket:(FIRMessagingSecureSocket *)socket; + +@end + +/** + * This manages the input/output streams connected to the MCS server. Used to receive data from + * the server and send to it over the wire. + */ +@interface FIRMessagingSecureSocket : NSObject + +@property(nonatomic, readwrite, weak) id delegate; +@property(nonatomic, readonly, assign) FIRMessagingSecureSocketState state; + +- (void)connectToHost:(NSString *)host port:(NSUInteger)port onRunLoop:(NSRunLoop *)runLoop; +- (void)disconnect; +- (void)sendData:(NSData *)data withTag:(int8_t)tag rmqId:(NSString *)rmqId; + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingSecureSocket.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingSecureSocket.m new file mode 100644 index 00000000..46d4a70b --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingSecureSocket.m @@ -0,0 +1,444 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingSecureSocket.h" + +#import "GPBMessage.h" +#import "GPBCodedOutputStream.h" +#import "GPBUtilities.h" + +#import "FIRMessagingCodedInputStream.h" +#import "FIRMessagingDefines.h" +#import "FIRMessagingLogger.h" +#import "FIRMessagingPacketQueue.h" + +static const NSUInteger kMaxBufferLength = 1024 * 1024; // 1M +static const NSUInteger kBufferLengthIncrement = 16 * 1024; // 16k +static const uint8_t kVersion = 40; +static const uint8_t kInvalidTag = -1; + +typedef NS_ENUM(NSUInteger, FIRMessagingSecureSocketReadResult) { + kFIRMessagingSecureSocketReadResultNone, + kFIRMessagingSecureSocketReadResultIncomplete, + kFIRMessagingSecureSocketReadResultCorrupt, + kFIRMessagingSecureSocketReadResultSuccess +}; + +static int32_t LogicalRightShift32(int32_t value, int32_t spaces) { + return (int32_t)((uint32_t)(value) >> spaces); +} + +static NSUInteger SerializedSize(int32_t value) { + NSUInteger bytes = 0; + while (YES) { + if ((value & ~0x7F) == 0) { + bytes += sizeof(uint8_t); + return bytes; + } else { + bytes += sizeof(uint8_t); + value = LogicalRightShift32(value, 7); + } + } +} + +@interface FIRMessagingSecureSocket() + +@property(nonatomic, readwrite, assign) FIRMessagingSecureSocketState state; +@property(nonatomic, readwrite, strong) NSInputStream *inStream; +@property(nonatomic, readwrite, strong) NSOutputStream *outStream; + +@property(nonatomic, readwrite, strong) NSMutableData *inputBuffer; +@property(nonatomic, readwrite, assign) NSUInteger inputBufferLength; +@property(nonatomic, readwrite, strong) NSMutableData *outputBuffer; +@property(nonatomic, readwrite, assign) NSUInteger outputBufferLength; + +@property(nonatomic, readwrite, strong) FIRMessagingPacketQueue *packetQueue; +@property(nonatomic, readwrite, assign) BOOL isVersionSent; +@property(nonatomic, readwrite, assign) BOOL isVersionReceived; +@property(nonatomic, readwrite, assign) BOOL isInStreamOpen; +@property(nonatomic, readwrite, assign) BOOL isOutStreamOpen; + +@property(nonatomic, readwrite, strong) NSRunLoop *runLoop; +@property(nonatomic, readwrite, strong) NSString *currentRmqIdBeingSent; +@property(nonatomic, readwrite, assign) int8_t currentProtoTypeBeingSent; + +@end + +@implementation FIRMessagingSecureSocket + +- (instancetype)init { + self = [super init]; + if (self) { + _state = kFIRMessagingSecureSocketNotOpen; + _inputBuffer = [NSMutableData dataWithLength:kBufferLengthIncrement]; + _packetQueue = [[FIRMessagingPacketQueue alloc] init]; + _currentProtoTypeBeingSent = kInvalidTag; + } + return self; +} + +- (void)dealloc { + [self disconnect]; +} + +- (void)connectToHost:(NSString *)host + port:(NSUInteger)port + onRunLoop:(NSRunLoop *)runLoop { + _FIRMessagingDevAssert(host != nil, @"Invalid host"); + _FIRMessagingDevAssert(runLoop != nil, @"Invalid runloop"); + _FIRMessagingDevAssert(self.state == kFIRMessagingSecureSocketNotOpen, @"Socket is already connected"); + + if (!host || self.state != kFIRMessagingSecureSocketNotOpen) { + return; + } + + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket000, + @"Opening secure socket to FIRMessaging service"); + self.state = kFIRMessagingSecureSocketOpening; + self.runLoop = runLoop; + CFReadStreamRef inputStreamRef; + CFWriteStreamRef outputStreamRef; + CFStreamCreatePairWithSocketToHost(NULL, + (__bridge CFStringRef)host, + (int)port, + &inputStreamRef, + &outputStreamRef); + self.inStream = CFBridgingRelease(inputStreamRef); + self.outStream = CFBridgingRelease(outputStreamRef); + if (!self.inStream || !self.outStream) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket001, + @"Failed to initialize socket."); + return; + } + + self.isInStreamOpen = NO; + self.isOutStreamOpen = NO; + + BOOL isVOIPSocket = NO; + + [self openStream:self.outStream isVOIPStream:isVOIPSocket]; + [self openStream:self.inStream isVOIPStream:isVOIPSocket]; +} + +- (void)disconnect { + if (self.state == kFIRMessagingSecureSocketClosing) { + return; + } + if (!self.inStream && !self.outStream) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket002, + @"The socket is not open or already closed."); + _FIRMessagingDevAssert(self.state == kFIRMessagingSecureSocketClosed || self.state == kFIRMessagingSecureSocketNotOpen, + @"Socket is already disconnected."); + return; + } + + self.state = kFIRMessagingSecureSocketClosing; + if (self.inStream) { + [self closeStream:self.inStream]; + self.inStream = nil; + } + if (self.outStream) { + [self closeStream:self.outStream]; + self.outStream = nil; + } + self.state = kFIRMessagingSecureSocketClosed; + [self.delegate didDisconnectWithSecureSocket:self]; +} + +- (void)sendData:(NSData *)data withTag:(int8_t)tag rmqId:(NSString *)rmqId { + [self.packetQueue push:[FIRMessagingPacket packetWithTag:tag rmqId:rmqId data:data]]; + if ([self.outStream hasSpaceAvailable]) { + [self performWrite]; + } +} + +#pragma mark - NSStreamDelegate + +- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode { + switch (eventCode) { + case NSStreamEventHasBytesAvailable: + if (self.state != kFIRMessagingSecureSocketOpen) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket003, + @"Try to read from socket that is not opened"); + return; + } + _FIRMessagingDevAssert(stream == self.inStream, @"Incorrect stream"); + if (![self performRead]) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket004, + @"Error occurred when reading incoming stream"); + [self disconnect]; + } + break; + case NSStreamEventEndEncountered: + FIRMessagingLoggerDebug( + kFIRMessagingMessageCodeSecureSocket005, @"%@ end encountered", + stream == self.inStream + ? @"Input stream" + : (stream == self.outStream ? @"Output stream" : @"Unknown stream")); + [self disconnect]; + break; + case NSStreamEventOpenCompleted: + if (stream == self.inStream) { + self.isInStreamOpen = YES; + } else if (stream == self.outStream) { + self.isOutStreamOpen = YES; + } + if (self.isInStreamOpen && self.isOutStreamOpen) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket006, + @"Secure socket to FIRMessaging service opened"); + self.state = kFIRMessagingSecureSocketOpen; + [self.delegate secureSocketDidConnect:self]; + } + break; + case NSStreamEventErrorOccurred: { + FIRMessagingLoggerDebug( + kFIRMessagingMessageCodeSecureSocket007, @"%@ error occurred", + stream == self.inStream + ? @"Input stream" + : (stream == self.outStream ? @"Output stream" : @"Unknown stream")); + [self disconnect]; + break; + } + case NSStreamEventHasSpaceAvailable: + if (self.state != kFIRMessagingSecureSocketOpen) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket008, + @"Try to write to socket that is not opened"); + return; + } + _FIRMessagingDevAssert(stream == self.outStream, @"Incorrect stream"); + [self performWrite]; + break; + default: + break; + } +} + +#pragma mark - Private + +- (void)openStream:(NSStream *)stream isVOIPStream:(BOOL)isVOIPStream { + _FIRMessagingDevAssert(stream != nil, @"Invalid stream"); + _FIRMessagingDevAssert(self.runLoop != nil, @"Invalid runloop"); + + if (stream) { + _FIRMessagingDevAssert([stream streamStatus] == NSStreamStatusNotOpen, @"Stream already open"); + if ([stream streamStatus] != NSStreamStatusNotOpen) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket009, + @"stream should not be open."); + return; + } + [stream setProperty:NSStreamSocketSecurityLevelNegotiatedSSL + forKey:NSStreamSocketSecurityLevelKey]; + if (isVOIPStream) { + [stream setProperty:NSStreamNetworkServiceTypeVoIP + forKey:NSStreamNetworkServiceType]; + } + stream.delegate = self; + [stream scheduleInRunLoop:self.runLoop forMode:NSDefaultRunLoopMode]; + [stream open]; + } +} + +- (void)closeStream:(NSStream *)stream { + _FIRMessagingDevAssert(stream != nil, @"Invalid stream"); + _FIRMessagingDevAssert(self.runLoop != nil, @"Invalid runloop"); + + if (stream) { + [stream close]; + [stream removeFromRunLoop:self.runLoop forMode:NSDefaultRunLoopMode]; + stream.delegate = nil; + } +} + +- (BOOL)performRead { + _FIRMessagingDevAssert(self.state == kFIRMessagingSecureSocketOpen, @"Socket should be open"); + + if (!self.isVersionReceived) { + self.isVersionReceived = YES; + uint8_t versionByte = 0; + NSInteger bytesRead = [self.inStream read:&versionByte maxLength:sizeof(uint8_t)]; + if (bytesRead != sizeof(uint8_t) || kVersion != versionByte) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket010, + @"Version do not match. Received %d, Expecting %d", versionByte, + kVersion); + return NO; + } + } + + while (YES) { + BOOL isInputBufferValid = [self.inputBuffer length] > 0; + _FIRMessagingDevAssert(isInputBufferValid, + @"Invalid input buffer size %lu. Used bytes length %lu, buffer content: %@", + _FIRMessaging_UL([self.inputBuffer length]), + _FIRMessaging_UL(self.inputBufferLength), + self.inputBuffer); + if (!isInputBufferValid) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket011, + @"Input buffer is not valid."); + return NO; + } + + if (![self.inStream hasBytesAvailable]) { + break; + } + + // try to read more data + uint8_t *unusedBufferPtr = (uint8_t *)self.inputBuffer.mutableBytes + self.inputBufferLength; + NSUInteger unusedBufferLength = [self.inputBuffer length] - self.inputBufferLength; + NSInteger bytesRead = [self.inStream read:unusedBufferPtr maxLength:unusedBufferLength]; + if (bytesRead <= 0) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket012, + @"Failed to read input stream. Bytes read %ld, Used buffer size %lu, " + @"Unused buffer size %lu", + _FIRMessaging_UL(bytesRead), _FIRMessaging_UL(self.inputBufferLength), + _FIRMessaging_UL(unusedBufferLength)); + break; + } + // did successfully read some more data + self.inputBufferLength += (NSUInteger)bytesRead; + + if ([self.inputBuffer length] <= self.inputBufferLength) { + // shouldn't be reading more than 1MB of data in one go + if ([self.inputBuffer length] + kBufferLengthIncrement > kMaxBufferLength) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket013, + @"Input buffer exceed 1M, disconnect socket"); + return NO; + } + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket014, + @"Input buffer limit exceeded. Used input buffer size %lu, " + @"Total input buffer size %lu. No unused buffer left. " + @"Increase buffer size.", + _FIRMessaging_UL(self.inputBufferLength), + _FIRMessaging_UL([self.inputBuffer length])); + [self.inputBuffer increaseLengthBy:kBufferLengthIncrement]; + _FIRMessagingDevAssert([self.inputBuffer length] > self.inputBufferLength, @"Invalid buffer size"); + } + + while (self.inputBufferLength > 0 && [self.inputBuffer length] > 0) { + _FIRMessagingDevAssert([self.inputBuffer length] >= self.inputBufferLength, + @"Buffer longer than length"); + NSRange inputRange = NSMakeRange(0, self.inputBufferLength); + size_t protoBytes = 0; + // read the actual proto data coming in + FIRMessagingSecureSocketReadResult readResult = + [self processCurrentInputBuffer:[self.inputBuffer subdataWithRange:inputRange] + outOffset:&protoBytes]; + // Corrupt data encountered, stop processing. + if (readResult == kFIRMessagingSecureSocketReadResultCorrupt) { + return NO; + // Incomplete data, keep trying to read by loading more from the stream. + } else if (readResult == kFIRMessagingSecureSocketReadResultIncomplete) { + break; + } + _FIRMessagingDevAssert(self.inputBufferLength >= protoBytes, @"More bytes than buffer can handle"); + // we have read (0, protoBytes) of data in the inputBuffer + if (protoBytes == self.inputBufferLength) { + // did completely read the buffer data can be reset for further processing + self.inputBufferLength = 0; + } else { + // delete processed bytes while maintaining the buffer size. + NSUInteger prevLength __unused = [self.inputBuffer length]; + // delete the processed bytes + [self.inputBuffer replaceBytesInRange:NSMakeRange(0, protoBytes) withBytes:NULL length:0]; + // reallocate more data + [self.inputBuffer increaseLengthBy:protoBytes]; + _FIRMessagingDevAssert([self.inputBuffer length] == prevLength, + @"Invalid input buffer size %lu. Used bytes length %lu, " + @"buffer content: %@", + _FIRMessaging_UL([self.inputBuffer length]), + _FIRMessaging_UL(self.inputBufferLength), + self.inputBuffer); + self.inputBufferLength -= protoBytes; + } + } + } + return YES; +} + +- (FIRMessagingSecureSocketReadResult)processCurrentInputBuffer:(NSData *)readData + outOffset:(size_t *)outOffset { + *outOffset = 0; + + FIRMessagingCodedInputStream *input = [[FIRMessagingCodedInputStream alloc] initWithData:readData]; + int8_t rawTag; + if (![input readTag:&rawTag]) { + return kFIRMessagingSecureSocketReadResultIncomplete; + } + int32_t length; + if (![input readLength:&length]) { + return kFIRMessagingSecureSocketReadResultIncomplete; + } + // NOTE tag can be zero for |HeartbeatPing|, and length can be zero for |Close| proto + _FIRMessagingDevAssert(rawTag >= 0 && length >= 0, @"Invalid tag or length"); + if (rawTag < 0 || length < 0) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket015, @"Buffer data corrupted."); + return kFIRMessagingSecureSocketReadResultCorrupt; + } + NSData *data = [input readDataWithLength:(uint32_t)length]; + if (data == nil) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket016, + @"Incomplete data, buffered data length %ld, expected length %d", + _FIRMessaging_UL(self.inputBufferLength), length); + return kFIRMessagingSecureSocketReadResultIncomplete; + } + [self.delegate secureSocket:self didReceiveData:data withTag:rawTag]; + *outOffset = input.offset; + return kFIRMessagingSecureSocketReadResultSuccess; +} + +- (void)performWrite { + _FIRMessagingDevAssert(self.state == kFIRMessagingSecureSocketOpen, @"Invalid socket state"); + + if (!self.isVersionSent) { + self.isVersionSent = YES; + uint8_t versionByte = kVersion; + [self.outStream write:&versionByte maxLength:sizeof(uint8_t)]; + } + + while (!self.packetQueue.isEmpty && self.outStream.hasSpaceAvailable) { + if (self.outputBuffer.length == 0) { + // serialize new packets only when the output buffer is flushed. + FIRMessagingPacket *packet = [self.packetQueue pop]; + self.currentRmqIdBeingSent = packet.rmqId; + self.currentProtoTypeBeingSent = packet.tag; + NSUInteger length = SerializedSize(packet.tag) + + SerializedSize((int)packet.data.length) + packet.data.length; + self.outputBuffer = [NSMutableData dataWithLength:length]; + GPBCodedOutputStream *output = [GPBCodedOutputStream streamWithData:self.outputBuffer]; + [output writeRawVarint32:packet.tag]; + [output writeBytesNoTag:packet.data]; + self.outputBufferLength = 0; + } + + // flush the output buffer. + NSInteger written = [self.outStream write:self.outputBuffer.bytes + self.outputBufferLength + maxLength:self.outputBuffer.length - self.outputBufferLength]; + if (written <= 0) { + continue; + } + self.outputBufferLength += (NSUInteger)written; + if (self.outputBufferLength >= self.outputBuffer.length) { + self.outputBufferLength = 0; + self.outputBuffer = nil; + [self.delegate secureSocket:self + didSendProtoWithTag:self.currentProtoTypeBeingSent + rmqId:self.currentRmqIdBeingSent]; + self.currentRmqIdBeingSent = nil; + self.currentProtoTypeBeingSent = kInvalidTag; + } + } +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingSyncMessageManager.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingSyncMessageManager.h new file mode 100644 index 00000000..3d30bdb5 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingSyncMessageManager.h @@ -0,0 +1,59 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@class FIRMessagingRmqManager; + +/** + * Handle sync messages being received both via MCS and APNS. + */ +@interface FIRMessagingSyncMessageManager : NSObject + +/** + * Initialize sync message manager. + * + * @param rmqManager The RMQ manager on the client. + * + * @return Sync message manager. + */ +- (instancetype)initWithRmqManager:(FIRMessagingRmqManager *)rmqManager; + +/** + * Remove expired sync message from persistent store. Also removes messages that have + * been received both via APNS and MCS. + */ +- (void)removeExpiredSyncMessages; + +/** + * App did recive a sync message via APNS. + * + * @param message The sync message received. + * + * @return YES if the message is a duplicate of an already received sync message else NO. + */ +- (BOOL)didReceiveAPNSSyncMessage:(NSDictionary *)message; + +/** + * App did receive a sync message via MCS. + * + * @param message The sync message received. + * + * @return YES if the message is a duplicate of an already received sync message else NO. + */ +- (BOOL)didReceiveMCSSyncMessage:(NSDictionary *)message; + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingSyncMessageManager.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingSyncMessageManager.m new file mode 100644 index 00000000..1257b02f --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingSyncMessageManager.m @@ -0,0 +1,147 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingSyncMessageManager.h" + +#import "FIRMessagingConstants.h" +#import "FIRMessagingDefines.h" +#import "FIRMessagingLogger.h" +#import "FIRMessagingPersistentSyncMessage.h" +#import "FIRMessagingRmqManager.h" +#import "FIRMessagingUtilities.h" + +static const int64_t kDefaultSyncMessageTTL = 4 * 7 * 24 * 60 * 60; // 4 weeks +// 4 MB of free space is required to persist Sync messages +static const uint64_t kMinFreeDiskSpaceInMB = 1; + +@interface FIRMessagingSyncMessageManager() + +@property(nonatomic, readwrite, strong) FIRMessagingRmqManager *rmqManager; + +@end + +@implementation FIRMessagingSyncMessageManager + +- (instancetype)init { + FIRMessagingInvalidateInitializer(); +} + +- (instancetype)initWithRmqManager:(FIRMessagingRmqManager *)rmqManager { + _FIRMessagingDevAssert(rmqManager, @"Invalid nil rmq manager while initalizing sync message manager"); + self = [super init]; + if (self) { + _rmqManager = rmqManager; + } + return self; +} + +- (void)removeExpiredSyncMessages { + NSError *error; + int deleteCount = [self.rmqManager deleteExpiredOrFinishedSyncMessages:&error]; + if (error) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeSyncMessageManager000, + @"Error while deleting expired sync messages %@", error); + } else if (deleteCount > 0) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSyncMessageManager001, + @"Successfully deleted %d sync messages from store", deleteCount); + } +} + +- (BOOL)didReceiveAPNSSyncMessage:(NSDictionary *)message { + return [self didReceiveSyncMessage:message viaAPNS:YES viaMCS:NO]; +} + +- (BOOL)didReceiveMCSSyncMessage:(NSDictionary *)message { + return [self didReceiveSyncMessage:message viaAPNS:NO viaMCS:YES]; +} + +- (BOOL)didReceiveSyncMessage:(NSDictionary *)message + viaAPNS:(BOOL)viaAPNS + viaMCS:(BOOL)viaMCS { + NSString *rmqID = message[kFIRMessagingMessageIDKey]; + _FIRMessagingDevAssert([rmqID length], @"Invalid nil rmqID for message"); + if (![rmqID length]) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeSyncMessageManager002, + @"Invalid nil rmqID for sync message."); + return NO; + } + + FIRMessagingPersistentSyncMessage *persistentMessage = + [self.rmqManager querySyncMessageWithRmqID:rmqID]; + + NSError *error; + if (!persistentMessage) { + + // Do not persist the new message if we don't have enough disk space + uint64_t freeDiskSpace = FIRMessagingGetFreeDiskSpaceInMB(); + if (freeDiskSpace < kMinFreeDiskSpaceInMB) { + return NO; + } + + int64_t expirationTime = [[self class] expirationTimeForSyncMessage:message]; + if (![self.rmqManager saveSyncMessageWithRmqID:rmqID + expirationTime:expirationTime + apnsReceived:viaAPNS + mcsReceived:viaMCS + error:&error]) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeSyncMessageManager003, + @"Failed to save sync message with rmqID %@", rmqID); + } else { + FIRMessagingLoggerInfo(kFIRMessagingMessageCodeSyncMessageManager004, + @"Added sync message to cache: %@", rmqID); + } + return NO; + } + + if (viaAPNS && !persistentMessage.apnsReceived) { + persistentMessage.apnsReceived = YES; + if (![self.rmqManager updateSyncMessageViaAPNSWithRmqID:rmqID error:&error]) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeSyncMessageManager005, + @"Failed to update APNS state for sync message %@", rmqID); + } + } else if (viaMCS && !persistentMessage.mcsReceived) { + persistentMessage.mcsReceived = YES; + if (![self.rmqManager updateSyncMessageViaMCSWithRmqID:rmqID error:&error]) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeSyncMessageManager006, + @"Failed to update MCS state for sync message %@", rmqID); + } + } + + // Received message via both ways we can safely delete it. + if (persistentMessage.apnsReceived && persistentMessage.mcsReceived) { + if (![self.rmqManager deleteSyncMessageWithRmqID:rmqID]) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeSyncMessageManager007, + @"Failed to delete sync message %@", rmqID); + } else { + FIRMessagingLoggerInfo(kFIRMessagingMessageCodeSyncMessageManager008, + @"Successfully deleted sync message from cache %@", rmqID); + } + } + + // Already received this message either via MCS or APNS. + return YES; +} + ++ (int64_t)expirationTimeForSyncMessage:(NSDictionary *)message { + int64_t ttl = kDefaultSyncMessageTTL; + if (message[kFIRMessagingMessageSyncMessageTTLKey]) { + ttl = [message[kFIRMessagingMessageSyncMessageTTLKey] longLongValue]; + } + int64_t currentTime = FIRMessagingCurrentTimestampInSeconds(); + return currentTime + ttl; +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingTopicOperation.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingTopicOperation.h new file mode 100644 index 00000000..ea98e6d2 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingTopicOperation.h @@ -0,0 +1,46 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import "FIRMessaging.h" +#import "FIRMessagingCheckinService.h" +#import "FIRMessagingTopicsCommon.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * An asynchronous NSOperation subclass which performs a single network request for a topic + * subscription operation. Once completed, it calls its provided completion handler. + */ +@interface FIRMessagingTopicOperation : NSOperation + +@property(nonatomic, readonly, copy) NSString *topic; +@property(nonatomic, readonly, assign) FIRMessagingTopicAction action; +@property(nonatomic, readonly, copy) NSString *token; +@property(nonatomic, readonly, copy, nullable) NSDictionary *options; +@property(nonatomic, readonly, strong) FIRMessagingCheckinService *checkinService; + +- (instancetype)initWithTopic:(NSString *)topic + action:(FIRMessagingTopicAction)action + token:(NSString *)token + options:(nullable NSDictionary *)options + checkinService:(FIRMessagingCheckinService *)checkinService + completion:(FIRMessagingTopicOperationCompletion)completion; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingTopicOperation.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingTopicOperation.m new file mode 100644 index 00000000..6703178b --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingTopicOperation.m @@ -0,0 +1,263 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingTopicOperation.h" + +#import "FIRMessagingCheckinService.h" +#import "FIRMessagingDefines.h" +#import "FIRMessagingLogger.h" +#import "FIRMessagingUtilities.h" +#import "NSError+FIRMessaging.h" + +#define DEBUG_LOG_SUBSCRIPTION_OPERATION_DURATIONS 0 + +static NSString *const kFIRMessagingSubscribeServerHost = + @"https://iid.googleapis.com/iid/register"; + +NSString *FIRMessagingSubscriptionsServer() { + static NSString *serverHost = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSDictionary *environment = [[NSProcessInfo processInfo] environment]; + NSString *customServerHost = environment[@"FCM_SERVER_ENDPOINT"]; + if (customServerHost.length) { + serverHost = customServerHost; + } else { + serverHost = kFIRMessagingSubscribeServerHost; + } + }); + return serverHost; +} + +@interface FIRMessagingTopicOperation () { + BOOL _isFinished; + BOOL _isExecuting; +} + +@property(nonatomic, readwrite, copy) NSString *topic; +@property(nonatomic, readwrite, assign) FIRMessagingTopicAction action; +@property(nonatomic, readwrite, copy) NSString *token; +@property(nonatomic, readwrite, copy) NSDictionary *options; +@property(nonatomic, readwrite, strong) FIRMessagingCheckinService *checkinService; +@property(nonatomic, readwrite, copy) FIRMessagingTopicOperationCompletion completion; + +@property(atomic, strong) NSURLSessionDataTask *dataTask; + +@end + +@implementation FIRMessagingTopicOperation + ++ (NSURLSession *)sharedSession { + static NSURLSession *subscriptionOperationSharedSession; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; + config.timeoutIntervalForResource = 60.0f; // 1 minute + subscriptionOperationSharedSession = [NSURLSession sessionWithConfiguration:config]; + subscriptionOperationSharedSession.sessionDescription = @"com.google.fcm.topics.session"; + }); + return subscriptionOperationSharedSession; +} + +- (instancetype)initWithTopic:(NSString *)topic + action:(FIRMessagingTopicAction)action + token:(NSString *)token + options:(NSDictionary *)options + checkinService:(FIRMessagingCheckinService *)checkinService + completion:(FIRMessagingTopicOperationCompletion)completion { + if (self = [super init]) { + _topic = topic; + _action = action; + _token = token; + _options = options; + _checkinService = checkinService; + _completion = completion; + + _isExecuting = NO; + _isFinished = NO; + } + return self; +} + +- (void)dealloc { + _topic = nil; + _token = nil; + _checkinService = nil; + _completion = nil; +} + +- (BOOL)isAsynchronous { + return YES; +} + +- (BOOL)isExecuting { + return _isExecuting; +} + +- (void)setExecuting:(BOOL)executing { + [self willChangeValueForKey:@"isExecuting"]; + _isExecuting = executing; + [self didChangeValueForKey:@"isExecuting"]; +} + +- (BOOL)isFinished { + return _isFinished; +} + +- (void)setFinished:(BOOL)finished { + [self willChangeValueForKey:@"isFinished"]; + _isFinished = finished; + [self didChangeValueForKey:@"isFinished"]; +} + +- (void)start { + if (self.isCancelled) { + NSError *error = + [NSError errorWithFCMErrorCode:kFIRMessagingErrorCodePubSubOperationIsCancelled]; + [self finishWithError:error]; + return; + } + + [self setExecuting:YES]; + + [self performSubscriptionChange]; +} + +- (void)finishWithError:(NSError *)error { + // Add a check to prevent this finish from being called more than once. + if (self.isFinished) { + return; + } + self.dataTask = nil; + if (self.completion) { + self.completion(error); + } + + [self setExecuting:NO]; + [self setFinished:YES]; +} + +- (void)cancel { + [super cancel]; + [self.dataTask cancel]; + NSError *error = [NSError errorWithFCMErrorCode:kFIRMessagingErrorCodePubSubOperationIsCancelled]; + [self finishWithError:error]; +} + +- (void)performSubscriptionChange { + + NSURL *url = [NSURL URLWithString:FIRMessagingSubscriptionsServer()]; + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; + NSString *appIdentifier = FIRMessagingAppIdentifier(); + NSString *deviceAuthID = self.checkinService.deviceAuthID; + NSString *secretToken = self.checkinService.secretToken; + NSString *authString = [NSString stringWithFormat:@"AidLogin %@:%@", deviceAuthID, secretToken]; + [request setValue:authString forHTTPHeaderField:@"Authorization"]; + [request setValue:appIdentifier forHTTPHeaderField:@"app"]; + [request setValue:self.checkinService.versionInfo forHTTPHeaderField:@"info"]; + + // Topic can contain special characters (like `%`) so encode the value. + NSCharacterSet *characterSet = [NSCharacterSet URLQueryAllowedCharacterSet]; + NSString *encodedTopic = + [self.topic stringByAddingPercentEncodingWithAllowedCharacters:characterSet]; + if (encodedTopic == nil) { + // The transformation was somehow not possible, so use the original topic. + FIRMessagingLoggerWarn(kFIRMessagingMessageCodeTopicOptionTopicEncodingFailed, + @"Unable to encode the topic '%@' during topic subscription change. " + @"Please ensure that the topic name contains only valid characters.", + self.topic); + encodedTopic = self.topic; + } + + NSMutableString *content = [NSMutableString stringWithFormat: + @"sender=%@&app=%@&device=%@&" + @"app_ver=%@&X-gcm.topic=%@&X-scope=%@", + self.token, + appIdentifier, + deviceAuthID, + FIRMessagingCurrentAppVersion(), + encodedTopic, + encodedTopic]; + + if (self.action == FIRMessagingTopicActionUnsubscribe) { + [content appendString:@"&delete=true"]; + } + + FIRMessagingLoggerInfo(kFIRMessagingMessageCodeTopicOption000, @"Topic subscription request: %@", + content); + + request.HTTPBody = [content dataUsingEncoding:NSUTF8StringEncoding]; + [request setHTTPMethod:@"POST"]; + +#if DEBUG_LOG_SUBSCRIPTION_OPERATION_DURATIONS + NSDate *start = [NSDate date]; +#endif + + FIRMessaging_WEAKIFY(self) + void(^requestHandler)(NSData *, NSURLResponse *, NSError *) = + ^(NSData *data, NSURLResponse *URLResponse, NSError *error) { + FIRMessaging_STRONGIFY(self) + if (error) { + // Our operation could have been cancelled, which would result in our data task's error being + // NSURLErrorCancelled + if (error.code == NSURLErrorCancelled) { + // We would only have been cancelled in the -cancel method, which will call finish for us + // so just return and do nothing. + return; + } + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTopicOption001, + @"Device registration HTTP fetch error. Error Code: %ld", + _FIRMessaging_L(error.code)); + [self finishWithError:error]; + return; + } + NSString *response = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + if (response.length == 0) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTopicOperationEmptyResponse, + @"Invalid registration response - zero length."); + [self finishWithError:[NSError errorWithFCMErrorCode:kFIRMessagingErrorCodeUnknown]]; + return; + } + NSArray *parts = [response componentsSeparatedByString:@"="]; + _FIRMessagingDevAssert(parts.count, @"Invalid registration response"); + if (![parts[0] isEqualToString:@"token"] || parts.count <= 1) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTopicOption002, + @"Invalid registration response %@", response); + [self finishWithError:[NSError errorWithFCMErrorCode:kFIRMessagingErrorCodeUnknown]]; + return; + } +#if DEBUG_LOG_SUBSCRIPTION_OPERATION_DURATIONS + NSTimeInterval duration = -[start timeIntervalSinceNow]; + FIRMessagingLoggerDebug(@"%@ change took %.2fs", self.topic, duration); +#endif + [self finishWithError:nil]; + + }; + + NSURLSession *urlSession = [FIRMessagingTopicOperation sharedSession]; + + self.dataTask = [urlSession dataTaskWithRequest:request completionHandler:requestHandler]; + NSString *description; + if (_action == FIRMessagingTopicActionSubscribe) { + description = [NSString stringWithFormat:@"com.google.fcm.topics.subscribe: %@", _topic]; + } else { + description = [NSString stringWithFormat:@"com.google.fcm.topics.unsubscribe: %@", _topic]; + } + self.dataTask.taskDescription = description; + [self.dataTask resume]; +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingTopicsCommon.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingTopicsCommon.h new file mode 100644 index 00000000..030b3fff --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingTopicsCommon.h @@ -0,0 +1,29 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Represents the action taken on a subscription topic. + */ +typedef NS_ENUM(NSInteger, FIRMessagingTopicAction) { + FIRMessagingTopicActionSubscribe, + FIRMessagingTopicActionUnsubscribe +}; + +NS_ASSUME_NONNULL_END diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingUtilities.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingUtilities.h new file mode 100644 index 00000000..206ff073 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingUtilities.h @@ -0,0 +1,58 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +typedef NS_ENUM(int8_t, FIRMessagingProtoTag) { + kFIRMessagingProtoTagInvalid = -1, + kFIRMessagingProtoTagHeartbeatPing = 0, + kFIRMessagingProtoTagHeartbeatAck = 1, + kFIRMessagingProtoTagLoginRequest = 2, + kFIRMessagingProtoTagLoginResponse = 3, + kFIRMessagingProtoTagClose = 4, + kFIRMessagingProtoTagIqStanza = 7, + kFIRMessagingProtoTagDataMessageStanza = 8, +}; + +@class GPBMessage; + +#pragma mark - Protocol Buffers + +FOUNDATION_EXPORT FIRMessagingProtoTag FIRMessagingGetTagForProto(GPBMessage *protoClass); +FOUNDATION_EXPORT Class FIRMessagingGetClassForTag(FIRMessagingProtoTag tag); + +#pragma mark - MCS + +FOUNDATION_EXPORT NSString *FIRMessagingGetRmq2Id(GPBMessage *proto); +FOUNDATION_EXPORT void FIRMessagingSetRmq2Id(GPBMessage *proto, NSString *pID); +FOUNDATION_EXPORT int FIRMessagingGetLastStreamId(GPBMessage *proto); +FOUNDATION_EXPORT void FIRMessagingSetLastStreamId(GPBMessage *proto, int sid); + +#pragma mark - Time + +FOUNDATION_EXPORT int64_t FIRMessagingCurrentTimestampInSeconds(void); +FOUNDATION_EXPORT int64_t FIRMessagingCurrentTimestampInMilliseconds(void); + +#pragma mark - App Info + +FOUNDATION_EXPORT NSString *FIRMessagingCurrentAppVersion(void); +FOUNDATION_EXPORT NSString *FIRMessagingAppIdentifier(void); + +#pragma mark - Others + +FOUNDATION_EXPORT uint64_t FIRMessagingGetFreeDiskSpaceInMB(void); +FOUNDATION_EXPORT UIApplication *FIRMessagingUIApplication(void); + diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingUtilities.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingUtilities.m new file mode 100644 index 00000000..fa3a2334 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingUtilities.m @@ -0,0 +1,188 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingUtilities.h" + +#import "Protos/GtalkCore.pbobjc.h" + +#import "FIRMessagingLogger.h" + +#import + +// Convert the macro to a string +#define STR_EXPAND(x) #x +#define STR(x) STR_EXPAND(x) + +static const uint64_t kBytesToMegabytesDivisor = 1024 * 1024LL; + +#pragma mark - Protocol Buffers + +FIRMessagingProtoTag FIRMessagingGetTagForProto(GPBMessage *proto) { + if ([proto isKindOfClass:[GtalkHeartbeatPing class]]) { + return kFIRMessagingProtoTagHeartbeatPing; + } else if ([proto isKindOfClass:[GtalkHeartbeatAck class]]) { + return kFIRMessagingProtoTagHeartbeatAck; + } else if ([proto isKindOfClass:[GtalkLoginRequest class]]) { + return kFIRMessagingProtoTagLoginRequest; + } else if ([proto isKindOfClass:[GtalkLoginResponse class]]) { + return kFIRMessagingProtoTagLoginResponse; + } else if ([proto isKindOfClass:[GtalkClose class]]) { + return kFIRMessagingProtoTagClose; + } else if ([proto isKindOfClass:[GtalkIqStanza class]]) { + return kFIRMessagingProtoTagIqStanza; + } else if ([proto isKindOfClass:[GtalkDataMessageStanza class]]) { + return kFIRMessagingProtoTagDataMessageStanza; + } + return kFIRMessagingProtoTagInvalid; +} + +Class FIRMessagingGetClassForTag(FIRMessagingProtoTag tag) { + switch (tag) { + case kFIRMessagingProtoTagHeartbeatPing: + return GtalkHeartbeatPing.class; + case kFIRMessagingProtoTagHeartbeatAck: + return GtalkHeartbeatAck.class; + case kFIRMessagingProtoTagLoginRequest: + return GtalkLoginRequest.class; + case kFIRMessagingProtoTagLoginResponse: + return GtalkLoginResponse.class; + case kFIRMessagingProtoTagClose: + return GtalkClose.class; + case kFIRMessagingProtoTagIqStanza: + return GtalkIqStanza.class; + case kFIRMessagingProtoTagDataMessageStanza: + return GtalkDataMessageStanza.class; + case kFIRMessagingProtoTagInvalid: + return NSNull.class; + } + return NSNull.class; +} + +#pragma mark - MCS + +NSString *FIRMessagingGetRmq2Id(GPBMessage *proto) { + if ([proto isKindOfClass:[GtalkIqStanza class]]) { + if (((GtalkIqStanza *)proto).hasPersistentId) { + return ((GtalkIqStanza *)proto).persistentId; + } + } else if ([proto isKindOfClass:[GtalkDataMessageStanza class]]) { + if (((GtalkDataMessageStanza *)proto).hasPersistentId) { + return ((GtalkDataMessageStanza *)proto).persistentId; + } + } + return nil; +} + +void FIRMessagingSetRmq2Id(GPBMessage *proto, NSString *pID) { + if ([proto isKindOfClass:[GtalkIqStanza class]]) { + ((GtalkIqStanza *)proto).persistentId = pID; + } else if ([proto isKindOfClass:[GtalkDataMessageStanza class]]) { + ((GtalkDataMessageStanza *)proto).persistentId = pID; + } +} + +int FIRMessagingGetLastStreamId(GPBMessage *proto) { + if ([proto isKindOfClass:[GtalkIqStanza class]]) { + if (((GtalkIqStanza *)proto).hasLastStreamIdReceived) { + return ((GtalkIqStanza *)proto).lastStreamIdReceived; + } + } else if ([proto isKindOfClass:[GtalkDataMessageStanza class]]) { + if (((GtalkDataMessageStanza *)proto).hasLastStreamIdReceived) { + return ((GtalkDataMessageStanza *)proto).lastStreamIdReceived; + } + } else if ([proto isKindOfClass:[GtalkHeartbeatPing class]]) { + if (((GtalkHeartbeatPing *)proto).hasLastStreamIdReceived) { + return ((GtalkHeartbeatPing *)proto).lastStreamIdReceived; + } + } else if ([proto isKindOfClass:[GtalkHeartbeatAck class]]) { + if (((GtalkHeartbeatAck *)proto).hasLastStreamIdReceived) { + return ((GtalkHeartbeatAck *)proto).lastStreamIdReceived; + } + } + return -1; +} + +void FIRMessagingSetLastStreamId(GPBMessage *proto, int sid) { + if ([proto isKindOfClass:[GtalkIqStanza class]]) { + ((GtalkIqStanza *)proto).lastStreamIdReceived = sid; + } else if ([proto isKindOfClass:[GtalkDataMessageStanza class]]) { + ((GtalkDataMessageStanza *)proto).lastStreamIdReceived = sid; + } else if ([proto isKindOfClass:[GtalkHeartbeatPing class]]) { + ((GtalkHeartbeatPing *)proto).lastStreamIdReceived = sid; + } else if ([proto isKindOfClass:[GtalkHeartbeatAck class]]) { + ((GtalkHeartbeatAck *)proto).lastStreamIdReceived = sid; + } +} + +#pragma mark - Time + +int64_t FIRMessagingCurrentTimestampInSeconds(void) { + return (int64_t)[[NSDate date] timeIntervalSince1970]; +} + +int64_t FIRMessagingCurrentTimestampInMilliseconds(void) { + return (int64_t)(FIRMessagingCurrentTimestampInSeconds() * 1000.0); +} + +#pragma mark - App Info + +NSString *FIRMessagingCurrentAppVersion(void) { + NSString *version = [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"]; + if (![version length]) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeUtilities000, + @"Could not find current app version"); + return @""; + } + return version; +} + +NSString *FIRMessagingAppIdentifier(void) { + return [[NSBundle mainBundle] bundleIdentifier]; +} + +uint64_t FIRMessagingGetFreeDiskSpaceInMB(void) { + NSError *error; + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + + NSDictionary *attributesMap = + [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] + error:&error]; + if (attributesMap) { + uint64_t totalSizeInBytes __unused = [attributesMap[NSFileSystemSize] longLongValue]; + uint64_t freeSizeInBytes = [attributesMap[NSFileSystemFreeSize] longLongValue]; + FIRMessagingLoggerDebug( + kFIRMessagingMessageCodeUtilities001, @"Device has capacity %llu MB with %llu MB free.", + totalSizeInBytes / kBytesToMegabytesDivisor, freeSizeInBytes / kBytesToMegabytesDivisor); + return ((double)freeSizeInBytes) / kBytesToMegabytesDivisor; + } else { + FIRMessagingLoggerError(kFIRMessagingMessageCodeUtilities002, + @"Error in retreiving device's free memory %@", error); + return 0; + } +} + +UIApplication *FIRMessagingUIApplication(void) { + static Class applicationClass = nil; + // iOS App extensions should not call [UIApplication sharedApplication], even if UIApplication + // responds to it. + if (![GULAppEnvironmentUtil isAppExtension]) { + Class cls = NSClassFromString(@"UIApplication"); + if (cls && [cls respondsToSelector:NSSelectorFromString(@"sharedApplication")]) { + applicationClass = cls; + } + } + return [applicationClass sharedApplication]; +} diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingVersionUtilities.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingVersionUtilities.h new file mode 100644 index 00000000..cd292afa --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingVersionUtilities.h @@ -0,0 +1,35 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +/** + * Parsing utility for FIRMessaging Library versions. FIRMessaging Library follows semantic versioning. + * This provides utilities to parse the library versions to enable features and do + * updates based on appropriate library versions. + * + * Some example semantic versions are 1.0.1, 2.1.0, 2.1.1, 2.2.0-alpha1, 2.2.1-beta1 + */ + +FOUNDATION_EXPORT NSString *FIRMessagingCurrentLibraryVersion(void); +/// Returns the current Major version of FIRMessaging library. +FOUNDATION_EXPORT int FIRMessagingCurrentLibraryVersionMajor(void); +/// Returns the current Minor version of FIRMessaging library. +FOUNDATION_EXPORT int FIRMessagingCurrentLibraryVersionMinor(void); +/// Returns the current Patch version of FIRMessaging library. +FOUNDATION_EXPORT int FIRMessagingCurrentLibraryVersionPatch(void); +/// Returns YES if current library version is `beta` else NO. +FOUNDATION_EXPORT BOOL FIRMessagingCurrentLibraryVersionIsBeta(void); diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingVersionUtilities.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingVersionUtilities.m new file mode 100644 index 00000000..1a3333ce --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessagingVersionUtilities.m @@ -0,0 +1,87 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingVersionUtilities.h" + +#import "FIRMessagingDefines.h" + +// Convert the macro to a string +#define STR_EXPAND(x) #x +#define STR(x) STR_EXPAND(x) + +static NSString *const kSemanticVersioningSeparator = @"."; +static NSString *const kBetaVersionPrefix = @"-beta"; + +static NSString *libraryVersion; +static int majorVersion; +static int minorVersion; +static int patchVersion; +static int betaVersion; + +void FIRMessagingParseCurrentLibraryVersion(void) { + static NSArray *allVersions; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSMutableString *daylightVersion = [NSMutableString stringWithUTF8String:STR(FIRMessaging_LIB_VERSION)]; + // Parse versions + // major, minor, patch[-beta#] + allVersions = [daylightVersion componentsSeparatedByString:kSemanticVersioningSeparator]; + _FIRMessagingDevAssert(allVersions.count == 3, @"Invalid versioning of FIRMessaging library"); + if (allVersions.count == 3) { + majorVersion = [allVersions[0] intValue]; + minorVersion = [allVersions[1] intValue]; + + // Parse patch and beta versions + NSArray *patchAndBetaVersion = + [allVersions[2] componentsSeparatedByString:kBetaVersionPrefix]; + _FIRMessagingDevAssert(patchAndBetaVersion.count <= 2, @"Invalid versioning of FIRMessaging library"); + if (patchAndBetaVersion.count == 2) { + patchVersion = [patchAndBetaVersion[0] intValue]; + betaVersion = [patchAndBetaVersion[1] intValue]; + } else if (patchAndBetaVersion.count == 1) { + patchVersion = [patchAndBetaVersion[0] intValue]; + } + } + + // Copy library version + libraryVersion = [daylightVersion copy]; + }); +} + +NSString *FIRMessagingCurrentLibraryVersion(void) { + FIRMessagingParseCurrentLibraryVersion(); + return libraryVersion; +} + +int FIRMessagingCurrentLibraryVersionMajor(void) { + FIRMessagingParseCurrentLibraryVersion(); + return majorVersion; +} + +int FIRMessagingCurrentLibraryVersionMinor(void) { + FIRMessagingParseCurrentLibraryVersion(); + return minorVersion; +} + +int FIRMessagingCurrentLibraryVersionPatch(void) { + FIRMessagingParseCurrentLibraryVersion(); + return patchVersion; +} + +BOOL FIRMessagingCurrentLibraryVersionIsBeta(void) { + FIRMessagingParseCurrentLibraryVersion(); + return betaVersion > 0; +} diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessaging_Private.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessaging_Private.h new file mode 100644 index 00000000..0a95a500 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FIRMessaging_Private.h @@ -0,0 +1,59 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessaging.h" + +@class FIRMessagingClient; +@class FIRMessagingPubSub; + +typedef NS_ENUM(int8_t, FIRMessagingNetworkStatus) { + kFIRMessagingReachabilityNotReachable = 0, + kFIRMessagingReachabilityReachableViaWiFi, + kFIRMessagingReachabilityReachableViaWWAN, +}; + +FOUNDATION_EXPORT NSString *const kFIRMessagingPlistAutoInitEnabled; +FOUNDATION_EXPORT NSString *const kFIRMessagingUserDefaultsKeyAutoInitEnabled; +FOUNDATION_EXPORT NSString *const kFIRMessagingUserDefaultsKeyUseMessagingDelegate; +FOUNDATION_EXPORT NSString *const kFIRMessagingPlistUseMessagingDelegate; + +@interface FIRMessagingRemoteMessage () + +@property(nonatomic, copy) NSString *messageID; +@property(nonatomic, strong) NSDictionary *appData; + +@end + +@interface FIRMessaging () + +#pragma mark - Private API + +- (NSString *)defaultFcmToken; +- (FIRMessagingClient *)client; +- (FIRMessagingPubSub *)pubsub; + +// Create a sample message to be sent over the wire using FIRMessaging. Look at +// FIRMessagingService.h to see what each param signifies. ++ (NSMutableDictionary *)createFIRMessagingMessageWithMessage:(NSDictionary *)message + to:(NSString *)to + withID:(NSString *)msgID + timeToLive:(int64_t)ttl + delay:(int)delay; + +- (BOOL)isNetworkAvailable; +- (FIRMessagingNetworkStatus)networkType; + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/FirebaseMessaging.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FirebaseMessaging.h new file mode 100644 index 00000000..ef081c90 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/FirebaseMessaging.h @@ -0,0 +1,17 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessaging.h" diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/InternalHeaders/FIRMessagingInternalUtilities.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/InternalHeaders/FIRMessagingInternalUtilities.h new file mode 100644 index 00000000..d6a16393 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/InternalHeaders/FIRMessagingInternalUtilities.h @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +/// @file FIRMessagingInternalUtilities.h +/// +/// Internal Class Names and Methods that other libs can query at runtime. + +/// FIRMessaging Class that responds to the FIRMessaging SDK version selector. +/// Verify at runtime if the class exists and implements the +/// required method. +static NSString *const kFIRMessagingSDKClassString = @"FIRMessaging"; + +/// FIRMessaging selector that returns the current FIRMessaging library version. +static NSString *const kFIRMessagingSDKVersionSelectorString = @"FIRMessagingSDKVersion"; + +/// FIRMessaging selector that returns the current device locale. +static NSString *const kFIRMessagingSDKLocaleSelectorString = @"FIRMessagingSDKCurrentLocale"; diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/NSDictionary+FIRMessaging.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/NSDictionary+FIRMessaging.h new file mode 100644 index 00000000..fe14451b --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/NSDictionary+FIRMessaging.h @@ -0,0 +1,45 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@interface NSDictionary (FIRMessaging) + +/** + * Returns a string representation for the given dictionary. Assumes that all + * keys and values are strings. + * + * @return A string representation of all keys and values in the dictionary. + * The returned string is not pretty-printed. + */ +- (NSString *)fcm_string; + +/** + * Check if the dictionary has any non-string keys or values. + * + * @return YES if the dictionary has any non-string keys or values else NO. + */ +- (BOOL)fcm_hasNonStringKeysOrValues; + +/** + * Trims all (key, value) pair in a dictionary that are not strings. + * + * @return A new copied dictionary with all the non-string keys or values + * removed from the original dictionary. + */ +- (NSDictionary *)fcm_trimNonStringValues; + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/NSDictionary+FIRMessaging.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/NSDictionary+FIRMessaging.m new file mode 100644 index 00000000..8df22ab0 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/NSDictionary+FIRMessaging.m @@ -0,0 +1,59 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "NSDictionary+FIRMessaging.h" + +@implementation NSDictionary (FIRMessaging) + +- (NSString *)fcm_string { + NSMutableString *dictAsString = [NSMutableString string]; + NSString *separator = @"|"; + for (id key in self) { + id value = self[key]; + if ([key isKindOfClass:[NSString class]] && [value isKindOfClass:[NSString class]]) { + [dictAsString appendFormat:@"%@:%@%@", key, value, separator]; + } + } + // remove the last separator + if ([dictAsString length]) { + [dictAsString deleteCharactersInRange:NSMakeRange(dictAsString.length - 1, 1)]; + } + return [dictAsString copy]; +} + +- (BOOL)fcm_hasNonStringKeysOrValues { + for (id key in self) { + id value = self[key]; + if (![key isKindOfClass:[NSString class]] || ![value isKindOfClass:[NSString class]]) { + return YES; + } + } + return NO; +} + +- (NSDictionary *)fcm_trimNonStringValues { + NSMutableDictionary *trimDictionary = + [NSMutableDictionary dictionaryWithCapacity:self.count]; + for (id key in self) { + id value = self[key]; + if ([key isKindOfClass:[NSString class]] && [value isKindOfClass:[NSString class]]) { + trimDictionary[(NSString *)key] = value; + } + } + return trimDictionary; +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/NSError+FIRMessaging.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/NSError+FIRMessaging.h new file mode 100644 index 00000000..ae25b5b5 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/NSError+FIRMessaging.h @@ -0,0 +1,69 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +FOUNDATION_EXPORT NSString *const kFIRMessagingDomain; + +typedef NS_ENUM(NSUInteger, FIRMessagingInternalErrorCode) { + // Unknown error. + kFIRMessagingErrorCodeUnknown = 0, + + // HTTP related errors. + kFIRMessagingErrorCodeAuthentication = 1, + kFIRMessagingErrorCodeNoAccess = 2, + kFIRMessagingErrorCodeTimeout = 3, + kFIRMessagingErrorCodeNetwork = 4, + + // Another operation is in progress. + kFIRMessagingErrorCodeOperationInProgress = 5, + + // Failed to perform device check in. + kFIRMessagingErrorCodeRegistrarFailedToCheckIn = 6, + + kFIRMessagingErrorCodeInvalidRequest = 7, + + // FIRMessaging generic errors + kFIRMessagingErrorCodeMissingDeviceID = 501, + + // upstream send errors + kFIRMessagingErrorServiceNotAvailable = 1001, + kFIRMessagingErrorInvalidParameters = 1002, + kFIRMessagingErrorMissingTo = 1003, + kFIRMessagingErrorSave = 1004, + kFIRMessagingErrorSizeExceeded = 1005, + // Future Send Errors + + // MCS errors + // Already connected with MCS + kFIRMessagingErrorCodeAlreadyConnected = 2001, + + // PubSub errors + kFIRMessagingErrorCodePubSubAlreadySubscribed = 3001, + kFIRMessagingErrorCodePubSubAlreadyUnsubscribed = 3002, + kFIRMessagingErrorCodePubSubInvalidTopic = 3003, + kFIRMessagingErrorCodePubSubFIRMessagingNotSetup = 3004, + kFIRMessagingErrorCodePubSubOperationIsCancelled = 3005, +}; + +@interface NSError (FIRMessaging) + +@property(nonatomic, readonly) FIRMessagingInternalErrorCode fcmErrorCode; + ++ (NSError *)errorWithFCMErrorCode:(FIRMessagingInternalErrorCode)fcmErrorCode; ++ (NSError *)fcm_errorWithCode:(NSInteger)code userInfo:(NSDictionary *)userInfo; + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/NSError+FIRMessaging.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/NSError+FIRMessaging.m new file mode 100644 index 00000000..e4b8736c --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/NSError+FIRMessaging.m @@ -0,0 +1,35 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "NSError+FIRMessaging.h" + +NSString *const kFIRMessagingDomain = @"com.google.fcm"; + +@implementation NSError (FIRMessaging) + +- (FIRMessagingInternalErrorCode)fcmErrorCode { + return (FIRMessagingInternalErrorCode)self.code; +} + ++ (NSError *)errorWithFCMErrorCode:(FIRMessagingInternalErrorCode)fcmErrorCode { + return [NSError errorWithDomain:kFIRMessagingDomain code:fcmErrorCode userInfo:nil]; +} + ++ (NSError *)fcm_errorWithCode:(NSInteger)code userInfo:(NSDictionary *)userInfo { + return [NSError errorWithDomain:kFIRMessagingDomain code:code userInfo:userInfo]; +} + +@end diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/Protos/GtalkCore.pbobjc.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/Protos/GtalkCore.pbobjc.h new file mode 100644 index 00000000..46d2d9ce --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/Protos/GtalkCore.pbobjc.h @@ -0,0 +1,1374 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: buzz/mobile/proto/gtalk_core.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30002 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30002 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +@class GtalkAppData; +@class GtalkCellTower; +@class GtalkClientEvent; +@class GtalkErrorInfo; +@class GtalkExtension; +@class GtalkHeartbeatConfig; +@class GtalkHeartbeatStat; +@class GtalkPresenceStanza; +@class GtalkSetting; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - Enum GtalkLoginRequest_AuthService + +typedef GPB_ENUM(GtalkLoginRequest_AuthService) { + GtalkLoginRequest_AuthService_Mail = 0, + GtalkLoginRequest_AuthService_AndroidCloudToDeviceMessage = 1, + GtalkLoginRequest_AuthService_AndroidId = 2, +}; + +GPBEnumDescriptor *GtalkLoginRequest_AuthService_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkLoginRequest_AuthService_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkMessageStanza_MessageType + +typedef GPB_ENUM(GtalkMessageStanza_MessageType) { + GtalkMessageStanza_MessageType_Normal = 0, + GtalkMessageStanza_MessageType_Chat = 1, + GtalkMessageStanza_MessageType_Groupchat = 2, + GtalkMessageStanza_MessageType_Headline = 3, + GtalkMessageStanza_MessageType_Error = 4, +}; + +GPBEnumDescriptor *GtalkMessageStanza_MessageType_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkMessageStanza_MessageType_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkPresenceStanza_PresenceType + +typedef GPB_ENUM(GtalkPresenceStanza_PresenceType) { + GtalkPresenceStanza_PresenceType_Unavailable = 0, + GtalkPresenceStanza_PresenceType_Subscribe = 1, + GtalkPresenceStanza_PresenceType_Subscribed = 2, + GtalkPresenceStanza_PresenceType_Unsubscribe = 3, + GtalkPresenceStanza_PresenceType_Unsubscribed = 4, + GtalkPresenceStanza_PresenceType_Probe = 5, + GtalkPresenceStanza_PresenceType_Error = 6, +}; + +GPBEnumDescriptor *GtalkPresenceStanza_PresenceType_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkPresenceStanza_PresenceType_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkPresenceStanza_ShowType + +typedef GPB_ENUM(GtalkPresenceStanza_ShowType) { + GtalkPresenceStanza_ShowType_Away = 0, + GtalkPresenceStanza_ShowType_Chat = 1, + GtalkPresenceStanza_ShowType_Dnd = 2, + GtalkPresenceStanza_ShowType_Xa = 3, +}; + +GPBEnumDescriptor *GtalkPresenceStanza_ShowType_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkPresenceStanza_ShowType_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkPresenceStanza_ClientType + +typedef GPB_ENUM(GtalkPresenceStanza_ClientType) { + GtalkPresenceStanza_ClientType_Mobile = 0, + GtalkPresenceStanza_ClientType_Android = 1, +}; + +GPBEnumDescriptor *GtalkPresenceStanza_ClientType_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkPresenceStanza_ClientType_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkPresenceStanza_CapabilitiesFlags + +typedef GPB_ENUM(GtalkPresenceStanza_CapabilitiesFlags) { + GtalkPresenceStanza_CapabilitiesFlags_HasVoiceV1 = 1, + GtalkPresenceStanza_CapabilitiesFlags_HasVideoV1 = 2, + GtalkPresenceStanza_CapabilitiesFlags_HasCameraV1 = 4, + GtalkPresenceStanza_CapabilitiesFlags_HasPmucV1 = 8, +}; + +GPBEnumDescriptor *GtalkPresenceStanza_CapabilitiesFlags_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkPresenceStanza_CapabilitiesFlags_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkBatchPresenceStanza_Type + +typedef GPB_ENUM(GtalkBatchPresenceStanza_Type) { + GtalkBatchPresenceStanza_Type_Get = 0, + GtalkBatchPresenceStanza_Type_Set = 1, +}; + +GPBEnumDescriptor *GtalkBatchPresenceStanza_Type_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkBatchPresenceStanza_Type_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkIqStanza_IqType + +typedef GPB_ENUM(GtalkIqStanza_IqType) { + GtalkIqStanza_IqType_Get = 0, + GtalkIqStanza_IqType_Set = 1, + GtalkIqStanza_IqType_Result = 2, + GtalkIqStanza_IqType_Error = 3, +}; + +GPBEnumDescriptor *GtalkIqStanza_IqType_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkIqStanza_IqType_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkClientEvent_Type + +typedef GPB_ENUM(GtalkClientEvent_Type) { + GtalkClientEvent_Type_Unknown = 0, + GtalkClientEvent_Type_DiscardedEvents = 1, + GtalkClientEvent_Type_FailedConnection = 2, + GtalkClientEvent_Type_SuccessfulConnection = 3, + GtalkClientEvent_Type_McsReconnectRequest = 4, + GtalkClientEvent_Type_FailedSocketCreationMcsReconnect = 5, + GtalkClientEvent_Type_McsReconnectLimited = 6, +}; + +GPBEnumDescriptor *GtalkClientEvent_Type_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkClientEvent_Type_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkClientEvent_McsReconnectAction + +typedef GPB_ENUM(GtalkClientEvent_McsReconnectAction) { + GtalkClientEvent_McsReconnectAction_None = 0, + GtalkClientEvent_McsReconnectAction_NotConnected = 1, + GtalkClientEvent_McsReconnectAction_TooSoon = 2, +}; + +GPBEnumDescriptor *GtalkClientEvent_McsReconnectAction_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkClientEvent_McsReconnectAction_IsValidValue(int32_t value); + +#pragma mark - GtalkGtalkCoreRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +@interface GtalkGtalkCoreRoot : GPBRootObject +@end + +#pragma mark - GtalkHeartbeatPing + +typedef GPB_ENUM(GtalkHeartbeatPing_FieldNumber) { + GtalkHeartbeatPing_FieldNumber_StreamId = 1, + GtalkHeartbeatPing_FieldNumber_LastStreamIdReceived = 2, + GtalkHeartbeatPing_FieldNumber_Status = 3, + GtalkHeartbeatPing_FieldNumber_CellTower = 4, + GtalkHeartbeatPing_FieldNumber_IntervalMs = 5, +}; + +@interface GtalkHeartbeatPing : GPBMessage + + +@property(nonatomic, readwrite) int32_t streamId; + +@property(nonatomic, readwrite) BOOL hasStreamId; + +@property(nonatomic, readwrite) int32_t lastStreamIdReceived; + +@property(nonatomic, readwrite) BOOL hasLastStreamIdReceived; + +@property(nonatomic, readwrite) int64_t status; + +@property(nonatomic, readwrite) BOOL hasStatus; + +@property(nonatomic, readwrite, strong, null_resettable) GtalkCellTower *cellTower DEPRECATED_ATTRIBUTE; +/** Test to see if @c cellTower has been set. */ +@property(nonatomic, readwrite) BOOL hasCellTower DEPRECATED_ATTRIBUTE; + + +@property(nonatomic, readwrite) int32_t intervalMs; + +@property(nonatomic, readwrite) BOOL hasIntervalMs; +@end + +#pragma mark - GtalkHeartbeatAck + +typedef GPB_ENUM(GtalkHeartbeatAck_FieldNumber) { + GtalkHeartbeatAck_FieldNumber_StreamId = 1, + GtalkHeartbeatAck_FieldNumber_LastStreamIdReceived = 2, + GtalkHeartbeatAck_FieldNumber_Status = 3, + GtalkHeartbeatAck_FieldNumber_CellTower = 4, + GtalkHeartbeatAck_FieldNumber_IntervalMs = 5, +}; + +@interface GtalkHeartbeatAck : GPBMessage + + +@property(nonatomic, readwrite) int32_t streamId; + +@property(nonatomic, readwrite) BOOL hasStreamId; + +@property(nonatomic, readwrite) int32_t lastStreamIdReceived; + +@property(nonatomic, readwrite) BOOL hasLastStreamIdReceived; + +@property(nonatomic, readwrite) int64_t status; + +@property(nonatomic, readwrite) BOOL hasStatus; + +@property(nonatomic, readwrite, strong, null_resettable) GtalkCellTower *cellTower DEPRECATED_ATTRIBUTE; +/** Test to see if @c cellTower has been set. */ +@property(nonatomic, readwrite) BOOL hasCellTower DEPRECATED_ATTRIBUTE; + + +@property(nonatomic, readwrite) int32_t intervalMs; + +@property(nonatomic, readwrite) BOOL hasIntervalMs; +@end + +#pragma mark - GtalkErrorInfo + +typedef GPB_ENUM(GtalkErrorInfo_FieldNumber) { + GtalkErrorInfo_FieldNumber_Code = 1, + GtalkErrorInfo_FieldNumber_Message = 2, + GtalkErrorInfo_FieldNumber_Type = 3, + GtalkErrorInfo_FieldNumber_Extension = 4, +}; + +@interface GtalkErrorInfo : GPBMessage + + +@property(nonatomic, readwrite) int32_t code; + +@property(nonatomic, readwrite) BOOL hasCode; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *message; +/** Test to see if @c message has been set. */ +@property(nonatomic, readwrite) BOOL hasMessage; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *type; +/** Test to see if @c type has been set. */ +@property(nonatomic, readwrite) BOOL hasType; + + +@property(nonatomic, readwrite, strong, null_resettable) GtalkExtension *extension; +/** Test to see if @c extension has been set. */ +@property(nonatomic, readwrite) BOOL hasExtension; + +@end + +#pragma mark - GtalkSetting + +typedef GPB_ENUM(GtalkSetting_FieldNumber) { + GtalkSetting_FieldNumber_Name = 1, + GtalkSetting_FieldNumber_Value = 2, +}; + +@interface GtalkSetting : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *name; +/** Test to see if @c name has been set. */ +@property(nonatomic, readwrite) BOOL hasName; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *value; +/** Test to see if @c value has been set. */ +@property(nonatomic, readwrite) BOOL hasValue; + +@end + +#pragma mark - GtalkHeartbeatStat + +typedef GPB_ENUM(GtalkHeartbeatStat_FieldNumber) { + GtalkHeartbeatStat_FieldNumber_Ip = 1, + GtalkHeartbeatStat_FieldNumber_Timeout = 2, + GtalkHeartbeatStat_FieldNumber_IntervalMs = 3, +}; + +@interface GtalkHeartbeatStat : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *ip; +/** Test to see if @c ip has been set. */ +@property(nonatomic, readwrite) BOOL hasIp; + + +@property(nonatomic, readwrite) BOOL timeout; + +@property(nonatomic, readwrite) BOOL hasTimeout; + +@property(nonatomic, readwrite) int32_t intervalMs; + +@property(nonatomic, readwrite) BOOL hasIntervalMs; +@end + +#pragma mark - GtalkHeartbeatConfig + +typedef GPB_ENUM(GtalkHeartbeatConfig_FieldNumber) { + GtalkHeartbeatConfig_FieldNumber_UploadStat = 1, + GtalkHeartbeatConfig_FieldNumber_Ip = 2, + GtalkHeartbeatConfig_FieldNumber_IntervalMs = 3, +}; + +@interface GtalkHeartbeatConfig : GPBMessage + + +@property(nonatomic, readwrite) BOOL uploadStat; + +@property(nonatomic, readwrite) BOOL hasUploadStat; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *ip; +/** Test to see if @c ip has been set. */ +@property(nonatomic, readwrite) BOOL hasIp; + + +@property(nonatomic, readwrite) int32_t intervalMs; + +@property(nonatomic, readwrite) BOOL hasIntervalMs; +@end + +#pragma mark - GtalkLoginRequest + +typedef GPB_ENUM(GtalkLoginRequest_FieldNumber) { + GtalkLoginRequest_FieldNumber_Id_p = 1, + GtalkLoginRequest_FieldNumber_Domain = 2, + GtalkLoginRequest_FieldNumber_User = 3, + GtalkLoginRequest_FieldNumber_Resource = 4, + GtalkLoginRequest_FieldNumber_AuthToken = 5, + GtalkLoginRequest_FieldNumber_DeviceId = 6, + GtalkLoginRequest_FieldNumber_LastRmqId = 7, + GtalkLoginRequest_FieldNumber_SettingArray = 8, + GtalkLoginRequest_FieldNumber_ReceivedPersistentIdArray = 10, + GtalkLoginRequest_FieldNumber_IncludeStreamIds = 11, + GtalkLoginRequest_FieldNumber_HeartbeatStat = 13, + GtalkLoginRequest_FieldNumber_UseRmq2 = 14, + GtalkLoginRequest_FieldNumber_AccountId = 15, + GtalkLoginRequest_FieldNumber_AuthService = 16, + GtalkLoginRequest_FieldNumber_NetworkType = 17, + GtalkLoginRequest_FieldNumber_Status = 18, + GtalkLoginRequest_FieldNumber_TokenVersionInfo = 19, + GtalkLoginRequest_FieldNumber_CellTower = 20, + GtalkLoginRequest_FieldNumber_GcmStartTimeMs = 21, + GtalkLoginRequest_FieldNumber_ClientEventArray = 22, + GtalkLoginRequest_FieldNumber_OnFallback = 23, + GtalkLoginRequest_FieldNumber_NoPendingUpstream = 24, + GtalkLoginRequest_FieldNumber_ReconnectRequestId = 25, +}; + +@interface GtalkLoginRequest : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *id_p; +/** Test to see if @c id_p has been set. */ +@property(nonatomic, readwrite) BOOL hasId_p; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *domain; +/** Test to see if @c domain has been set. */ +@property(nonatomic, readwrite) BOOL hasDomain; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *user; +/** Test to see if @c user has been set. */ +@property(nonatomic, readwrite) BOOL hasUser; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *resource; +/** Test to see if @c resource has been set. */ +@property(nonatomic, readwrite) BOOL hasResource; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *authToken; +/** Test to see if @c authToken has been set. */ +@property(nonatomic, readwrite) BOOL hasAuthToken; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *deviceId; +/** Test to see if @c deviceId has been set. */ +@property(nonatomic, readwrite) BOOL hasDeviceId; + + +@property(nonatomic, readwrite) int64_t lastRmqId; + +@property(nonatomic, readwrite) BOOL hasLastRmqId; + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *settingArray; +/** The number of items in @c settingArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger settingArray_Count; + + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *receivedPersistentIdArray; +/** The number of items in @c receivedPersistentIdArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger receivedPersistentIdArray_Count; + + +@property(nonatomic, readwrite) BOOL includeStreamIds; + +@property(nonatomic, readwrite) BOOL hasIncludeStreamIds; + +@property(nonatomic, readwrite, strong, null_resettable) GtalkHeartbeatStat *heartbeatStat; +/** Test to see if @c heartbeatStat has been set. */ +@property(nonatomic, readwrite) BOOL hasHeartbeatStat; + + +@property(nonatomic, readwrite) BOOL useRmq2; + +@property(nonatomic, readwrite) BOOL hasUseRmq2; + +@property(nonatomic, readwrite) int64_t accountId; + +@property(nonatomic, readwrite) BOOL hasAccountId; + +@property(nonatomic, readwrite) GtalkLoginRequest_AuthService authService; + +@property(nonatomic, readwrite) BOOL hasAuthService; + +@property(nonatomic, readwrite) int32_t networkType; + +@property(nonatomic, readwrite) BOOL hasNetworkType; + +@property(nonatomic, readwrite) int64_t status; + +@property(nonatomic, readwrite) BOOL hasStatus; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *tokenVersionInfo; +/** Test to see if @c tokenVersionInfo has been set. */ +@property(nonatomic, readwrite) BOOL hasTokenVersionInfo; + + +@property(nonatomic, readwrite, strong, null_resettable) GtalkCellTower *cellTower DEPRECATED_ATTRIBUTE; +/** Test to see if @c cellTower has been set. */ +@property(nonatomic, readwrite) BOOL hasCellTower DEPRECATED_ATTRIBUTE; + + +@property(nonatomic, readwrite) uint64_t gcmStartTimeMs; + +@property(nonatomic, readwrite) BOOL hasGcmStartTimeMs; + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *clientEventArray; +/** The number of items in @c clientEventArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger clientEventArray_Count; + + +@property(nonatomic, readwrite) BOOL onFallback; + +@property(nonatomic, readwrite) BOOL hasOnFallback; + +@property(nonatomic, readwrite) BOOL noPendingUpstream; + +@property(nonatomic, readwrite) BOOL hasNoPendingUpstream; + +@property(nonatomic, readwrite) int32_t reconnectRequestId; + +@property(nonatomic, readwrite) BOOL hasReconnectRequestId; +@end + +#pragma mark - GtalkLoginResponse + +typedef GPB_ENUM(GtalkLoginResponse_FieldNumber) { + GtalkLoginResponse_FieldNumber_Id_p = 1, + GtalkLoginResponse_FieldNumber_Jid = 2, + GtalkLoginResponse_FieldNumber_Error = 3, + GtalkLoginResponse_FieldNumber_SettingArray = 4, + GtalkLoginResponse_FieldNumber_StreamId = 5, + GtalkLoginResponse_FieldNumber_LastStreamIdReceived = 6, + GtalkLoginResponse_FieldNumber_HeartbeatConfig = 7, + GtalkLoginResponse_FieldNumber_ServerTimestamp = 8, +}; + +@interface GtalkLoginResponse : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *id_p; +/** Test to see if @c id_p has been set. */ +@property(nonatomic, readwrite) BOOL hasId_p; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *jid; +/** Test to see if @c jid has been set. */ +@property(nonatomic, readwrite) BOOL hasJid; + + +@property(nonatomic, readwrite, strong, null_resettable) GtalkErrorInfo *error; +/** Test to see if @c error has been set. */ +@property(nonatomic, readwrite) BOOL hasError; + + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *settingArray; +/** The number of items in @c settingArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger settingArray_Count; + + +@property(nonatomic, readwrite) int32_t streamId; + +@property(nonatomic, readwrite) BOOL hasStreamId; + +@property(nonatomic, readwrite) int32_t lastStreamIdReceived; + +@property(nonatomic, readwrite) BOOL hasLastStreamIdReceived; + +@property(nonatomic, readwrite, strong, null_resettable) GtalkHeartbeatConfig *heartbeatConfig; +/** Test to see if @c heartbeatConfig has been set. */ +@property(nonatomic, readwrite) BOOL hasHeartbeatConfig; + + +@property(nonatomic, readwrite) int64_t serverTimestamp; + +@property(nonatomic, readwrite) BOOL hasServerTimestamp; +@end + +#pragma mark - GtalkBindAccountRequest + +typedef GPB_ENUM(GtalkBindAccountRequest_FieldNumber) { + GtalkBindAccountRequest_FieldNumber_Id_p = 1, + GtalkBindAccountRequest_FieldNumber_Domain = 2, + GtalkBindAccountRequest_FieldNumber_User = 3, + GtalkBindAccountRequest_FieldNumber_Resource = 4, + GtalkBindAccountRequest_FieldNumber_AuthToken = 5, + GtalkBindAccountRequest_FieldNumber_PersistentId = 6, + GtalkBindAccountRequest_FieldNumber_StreamId = 7, + GtalkBindAccountRequest_FieldNumber_LastStreamIdReceived = 8, + GtalkBindAccountRequest_FieldNumber_AccountId = 9, +}; + +@interface GtalkBindAccountRequest : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *id_p; +/** Test to see if @c id_p has been set. */ +@property(nonatomic, readwrite) BOOL hasId_p; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *domain; +/** Test to see if @c domain has been set. */ +@property(nonatomic, readwrite) BOOL hasDomain; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *user; +/** Test to see if @c user has been set. */ +@property(nonatomic, readwrite) BOOL hasUser; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *resource; +/** Test to see if @c resource has been set. */ +@property(nonatomic, readwrite) BOOL hasResource; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *authToken; +/** Test to see if @c authToken has been set. */ +@property(nonatomic, readwrite) BOOL hasAuthToken; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *persistentId; +/** Test to see if @c persistentId has been set. */ +@property(nonatomic, readwrite) BOOL hasPersistentId; + + +@property(nonatomic, readwrite) int32_t streamId; + +@property(nonatomic, readwrite) BOOL hasStreamId; + +@property(nonatomic, readwrite) int32_t lastStreamIdReceived; + +@property(nonatomic, readwrite) BOOL hasLastStreamIdReceived; + +@property(nonatomic, readwrite) int64_t accountId; + +@property(nonatomic, readwrite) BOOL hasAccountId; +@end + +#pragma mark - GtalkBindAccountResponse + +typedef GPB_ENUM(GtalkBindAccountResponse_FieldNumber) { + GtalkBindAccountResponse_FieldNumber_Id_p = 1, + GtalkBindAccountResponse_FieldNumber_Jid = 2, + GtalkBindAccountResponse_FieldNumber_Error = 3, + GtalkBindAccountResponse_FieldNumber_StreamId = 4, + GtalkBindAccountResponse_FieldNumber_LastStreamIdReceived = 5, +}; + +@interface GtalkBindAccountResponse : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *id_p; +/** Test to see if @c id_p has been set. */ +@property(nonatomic, readwrite) BOOL hasId_p; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *jid; +/** Test to see if @c jid has been set. */ +@property(nonatomic, readwrite) BOOL hasJid; + + +@property(nonatomic, readwrite, strong, null_resettable) GtalkErrorInfo *error; +/** Test to see if @c error has been set. */ +@property(nonatomic, readwrite) BOOL hasError; + + +@property(nonatomic, readwrite) int32_t streamId; + +@property(nonatomic, readwrite) BOOL hasStreamId; + +@property(nonatomic, readwrite) int32_t lastStreamIdReceived; + +@property(nonatomic, readwrite) BOOL hasLastStreamIdReceived; +@end + +#pragma mark - GtalkStreamErrorStanza + +typedef GPB_ENUM(GtalkStreamErrorStanza_FieldNumber) { + GtalkStreamErrorStanza_FieldNumber_Type = 1, + GtalkStreamErrorStanza_FieldNumber_Text = 2, +}; + +@interface GtalkStreamErrorStanza : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *type; +/** Test to see if @c type has been set. */ +@property(nonatomic, readwrite) BOOL hasType; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *text; +/** Test to see if @c text has been set. */ +@property(nonatomic, readwrite) BOOL hasText; + +@end + +#pragma mark - GtalkClose + +@interface GtalkClose : GPBMessage + +@end + +#pragma mark - GtalkExtension + +typedef GPB_ENUM(GtalkExtension_FieldNumber) { + GtalkExtension_FieldNumber_Id_p = 1, + GtalkExtension_FieldNumber_Data_p = 2, +}; + +@interface GtalkExtension : GPBMessage + + +@property(nonatomic, readwrite) int32_t id_p; + +@property(nonatomic, readwrite) BOOL hasId_p; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *data_p; +/** Test to see if @c data_p has been set. */ +@property(nonatomic, readwrite) BOOL hasData_p; + +@end + +#pragma mark - GtalkMessageStanza + +typedef GPB_ENUM(GtalkMessageStanza_FieldNumber) { + GtalkMessageStanza_FieldNumber_RmqId = 1, + GtalkMessageStanza_FieldNumber_Type = 2, + GtalkMessageStanza_FieldNumber_Id_p = 3, + GtalkMessageStanza_FieldNumber_From = 4, + GtalkMessageStanza_FieldNumber_To = 5, + GtalkMessageStanza_FieldNumber_Subject = 6, + GtalkMessageStanza_FieldNumber_Body = 7, + GtalkMessageStanza_FieldNumber_Thread = 8, + GtalkMessageStanza_FieldNumber_Error = 9, + GtalkMessageStanza_FieldNumber_ExtensionArray = 10, + GtalkMessageStanza_FieldNumber_Nosave = 11, + GtalkMessageStanza_FieldNumber_Timestamp = 12, + GtalkMessageStanza_FieldNumber_PersistentId = 13, + GtalkMessageStanza_FieldNumber_StreamId = 14, + GtalkMessageStanza_FieldNumber_LastStreamIdReceived = 15, + GtalkMessageStanza_FieldNumber_Read = 16, + GtalkMessageStanza_FieldNumber_AccountId = 17, +}; + +@interface GtalkMessageStanza : GPBMessage + + +@property(nonatomic, readwrite) int64_t rmqId; + +@property(nonatomic, readwrite) BOOL hasRmqId; + +@property(nonatomic, readwrite) GtalkMessageStanza_MessageType type; + +@property(nonatomic, readwrite) BOOL hasType; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *id_p; +/** Test to see if @c id_p has been set. */ +@property(nonatomic, readwrite) BOOL hasId_p; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *from; +/** Test to see if @c from has been set. */ +@property(nonatomic, readwrite) BOOL hasFrom; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *to; +/** Test to see if @c to has been set. */ +@property(nonatomic, readwrite) BOOL hasTo; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *subject; +/** Test to see if @c subject has been set. */ +@property(nonatomic, readwrite) BOOL hasSubject; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *body; +/** Test to see if @c body has been set. */ +@property(nonatomic, readwrite) BOOL hasBody; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *thread; +/** Test to see if @c thread has been set. */ +@property(nonatomic, readwrite) BOOL hasThread; + + +@property(nonatomic, readwrite, strong, null_resettable) GtalkErrorInfo *error; +/** Test to see if @c error has been set. */ +@property(nonatomic, readwrite) BOOL hasError; + + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *extensionArray; +/** The number of items in @c extensionArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger extensionArray_Count; + + +@property(nonatomic, readwrite) BOOL nosave; + +@property(nonatomic, readwrite) BOOL hasNosave; + +@property(nonatomic, readwrite) int64_t timestamp; + +@property(nonatomic, readwrite) BOOL hasTimestamp; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *persistentId; +/** Test to see if @c persistentId has been set. */ +@property(nonatomic, readwrite) BOOL hasPersistentId; + + +@property(nonatomic, readwrite) int32_t streamId; + +@property(nonatomic, readwrite) BOOL hasStreamId; + +@property(nonatomic, readwrite) int32_t lastStreamIdReceived; + +@property(nonatomic, readwrite) BOOL hasLastStreamIdReceived; + +@property(nonatomic, readwrite) BOOL read; + +@property(nonatomic, readwrite) BOOL hasRead; + +@property(nonatomic, readwrite) int64_t accountId; + +@property(nonatomic, readwrite) BOOL hasAccountId; +@end + +#pragma mark - GtalkPresenceStanza + +typedef GPB_ENUM(GtalkPresenceStanza_FieldNumber) { + GtalkPresenceStanza_FieldNumber_RmqId = 1, + GtalkPresenceStanza_FieldNumber_Type = 2, + GtalkPresenceStanza_FieldNumber_Id_p = 3, + GtalkPresenceStanza_FieldNumber_From = 4, + GtalkPresenceStanza_FieldNumber_To = 5, + GtalkPresenceStanza_FieldNumber_Show = 6, + GtalkPresenceStanza_FieldNumber_Status = 7, + GtalkPresenceStanza_FieldNumber_Priority = 8, + GtalkPresenceStanza_FieldNumber_Error = 9, + GtalkPresenceStanza_FieldNumber_ExtensionArray = 10, + GtalkPresenceStanza_FieldNumber_Client = 11, + GtalkPresenceStanza_FieldNumber_AvatarHash = 12, + GtalkPresenceStanza_FieldNumber_PersistentId = 13, + GtalkPresenceStanza_FieldNumber_StreamId = 14, + GtalkPresenceStanza_FieldNumber_LastStreamIdReceived = 15, + GtalkPresenceStanza_FieldNumber_CapabilitiesFlags = 16, + GtalkPresenceStanza_FieldNumber_AccountId = 17, +}; + +@interface GtalkPresenceStanza : GPBMessage + + +@property(nonatomic, readwrite) int64_t rmqId; + +@property(nonatomic, readwrite) BOOL hasRmqId; + +@property(nonatomic, readwrite) GtalkPresenceStanza_PresenceType type; + +@property(nonatomic, readwrite) BOOL hasType; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *id_p; +/** Test to see if @c id_p has been set. */ +@property(nonatomic, readwrite) BOOL hasId_p; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *from; +/** Test to see if @c from has been set. */ +@property(nonatomic, readwrite) BOOL hasFrom; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *to; +/** Test to see if @c to has been set. */ +@property(nonatomic, readwrite) BOOL hasTo; + + +@property(nonatomic, readwrite) GtalkPresenceStanza_ShowType show; + +@property(nonatomic, readwrite) BOOL hasShow; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *status; +/** Test to see if @c status has been set. */ +@property(nonatomic, readwrite) BOOL hasStatus; + + +@property(nonatomic, readwrite) int32_t priority; + +@property(nonatomic, readwrite) BOOL hasPriority; + +@property(nonatomic, readwrite, strong, null_resettable) GtalkErrorInfo *error; +/** Test to see if @c error has been set. */ +@property(nonatomic, readwrite) BOOL hasError; + + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *extensionArray; +/** The number of items in @c extensionArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger extensionArray_Count; + + +@property(nonatomic, readwrite) GtalkPresenceStanza_ClientType client; + +@property(nonatomic, readwrite) BOOL hasClient; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *avatarHash; +/** Test to see if @c avatarHash has been set. */ +@property(nonatomic, readwrite) BOOL hasAvatarHash; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *persistentId; +/** Test to see if @c persistentId has been set. */ +@property(nonatomic, readwrite) BOOL hasPersistentId; + + +@property(nonatomic, readwrite) int32_t streamId; + +@property(nonatomic, readwrite) BOOL hasStreamId; + +@property(nonatomic, readwrite) int32_t lastStreamIdReceived; + +@property(nonatomic, readwrite) BOOL hasLastStreamIdReceived; + +@property(nonatomic, readwrite) int32_t capabilitiesFlags; + +@property(nonatomic, readwrite) BOOL hasCapabilitiesFlags; + +@property(nonatomic, readwrite) int64_t accountId; + +@property(nonatomic, readwrite) BOOL hasAccountId; +@end + +#pragma mark - GtalkBatchPresenceStanza + +typedef GPB_ENUM(GtalkBatchPresenceStanza_FieldNumber) { + GtalkBatchPresenceStanza_FieldNumber_Id_p = 1, + GtalkBatchPresenceStanza_FieldNumber_To = 2, + GtalkBatchPresenceStanza_FieldNumber_PresenceArray = 3, + GtalkBatchPresenceStanza_FieldNumber_PersistentId = 4, + GtalkBatchPresenceStanza_FieldNumber_StreamId = 5, + GtalkBatchPresenceStanza_FieldNumber_LastStreamIdReceived = 6, + GtalkBatchPresenceStanza_FieldNumber_AccountId = 7, + GtalkBatchPresenceStanza_FieldNumber_Type = 8, + GtalkBatchPresenceStanza_FieldNumber_Error = 9, +}; + +@interface GtalkBatchPresenceStanza : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *id_p; +/** Test to see if @c id_p has been set. */ +@property(nonatomic, readwrite) BOOL hasId_p; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *to; +/** Test to see if @c to has been set. */ +@property(nonatomic, readwrite) BOOL hasTo; + + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *presenceArray; +/** The number of items in @c presenceArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger presenceArray_Count; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *persistentId; +/** Test to see if @c persistentId has been set. */ +@property(nonatomic, readwrite) BOOL hasPersistentId; + + +@property(nonatomic, readwrite) int32_t streamId; + +@property(nonatomic, readwrite) BOOL hasStreamId; + +@property(nonatomic, readwrite) int32_t lastStreamIdReceived; + +@property(nonatomic, readwrite) BOOL hasLastStreamIdReceived; + +@property(nonatomic, readwrite) int64_t accountId; + +@property(nonatomic, readwrite) BOOL hasAccountId; + +@property(nonatomic, readwrite) GtalkBatchPresenceStanza_Type type; + +@property(nonatomic, readwrite) BOOL hasType; + +@property(nonatomic, readwrite, strong, null_resettable) GtalkErrorInfo *error; +/** Test to see if @c error has been set. */ +@property(nonatomic, readwrite) BOOL hasError; + +@end + +#pragma mark - GtalkIqStanza + +typedef GPB_ENUM(GtalkIqStanza_FieldNumber) { + GtalkIqStanza_FieldNumber_RmqId = 1, + GtalkIqStanza_FieldNumber_Type = 2, + GtalkIqStanza_FieldNumber_Id_p = 3, + GtalkIqStanza_FieldNumber_From = 4, + GtalkIqStanza_FieldNumber_To = 5, + GtalkIqStanza_FieldNumber_Error = 6, + GtalkIqStanza_FieldNumber_Extension = 7, + GtalkIqStanza_FieldNumber_PersistentId = 8, + GtalkIqStanza_FieldNumber_StreamId = 9, + GtalkIqStanza_FieldNumber_LastStreamIdReceived = 10, + GtalkIqStanza_FieldNumber_AccountId = 11, + GtalkIqStanza_FieldNumber_Status = 12, +}; + +@interface GtalkIqStanza : GPBMessage + + +@property(nonatomic, readwrite) int64_t rmqId; + +@property(nonatomic, readwrite) BOOL hasRmqId; + +@property(nonatomic, readwrite) GtalkIqStanza_IqType type; + +@property(nonatomic, readwrite) BOOL hasType; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *id_p; +/** Test to see if @c id_p has been set. */ +@property(nonatomic, readwrite) BOOL hasId_p; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *from; +/** Test to see if @c from has been set. */ +@property(nonatomic, readwrite) BOOL hasFrom; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *to; +/** Test to see if @c to has been set. */ +@property(nonatomic, readwrite) BOOL hasTo; + + +@property(nonatomic, readwrite, strong, null_resettable) GtalkErrorInfo *error; +/** Test to see if @c error has been set. */ +@property(nonatomic, readwrite) BOOL hasError; + + +@property(nonatomic, readwrite, strong, null_resettable) GtalkExtension *extension; +/** Test to see if @c extension has been set. */ +@property(nonatomic, readwrite) BOOL hasExtension; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *persistentId; +/** Test to see if @c persistentId has been set. */ +@property(nonatomic, readwrite) BOOL hasPersistentId; + + +@property(nonatomic, readwrite) int32_t streamId; + +@property(nonatomic, readwrite) BOOL hasStreamId; + +@property(nonatomic, readwrite) int32_t lastStreamIdReceived; + +@property(nonatomic, readwrite) BOOL hasLastStreamIdReceived; + +@property(nonatomic, readwrite) int64_t accountId; + +@property(nonatomic, readwrite) BOOL hasAccountId; + +@property(nonatomic, readwrite) int64_t status; + +@property(nonatomic, readwrite) BOOL hasStatus; +@end + +#pragma mark - GtalkAppData + +typedef GPB_ENUM(GtalkAppData_FieldNumber) { + GtalkAppData_FieldNumber_Key = 1, + GtalkAppData_FieldNumber_Value = 2, +}; + +@interface GtalkAppData : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *key; +/** Test to see if @c key has been set. */ +@property(nonatomic, readwrite) BOOL hasKey; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *value; +/** Test to see if @c value has been set. */ +@property(nonatomic, readwrite) BOOL hasValue; + +@end + +#pragma mark - GtalkDataMessageStanza + +typedef GPB_ENUM(GtalkDataMessageStanza_FieldNumber) { + GtalkDataMessageStanza_FieldNumber_RmqId = 1, + GtalkDataMessageStanza_FieldNumber_Id_p = 2, + GtalkDataMessageStanza_FieldNumber_From = 3, + GtalkDataMessageStanza_FieldNumber_To = 4, + GtalkDataMessageStanza_FieldNumber_Category = 5, + GtalkDataMessageStanza_FieldNumber_Token = 6, + GtalkDataMessageStanza_FieldNumber_AppDataArray = 7, + GtalkDataMessageStanza_FieldNumber_FromTrustedServer = 8, + GtalkDataMessageStanza_FieldNumber_PersistentId = 9, + GtalkDataMessageStanza_FieldNumber_StreamId = 10, + GtalkDataMessageStanza_FieldNumber_LastStreamIdReceived = 11, + GtalkDataMessageStanza_FieldNumber_Permission = 12, + GtalkDataMessageStanza_FieldNumber_RegId = 13, + GtalkDataMessageStanza_FieldNumber_PkgSignature = 14, + GtalkDataMessageStanza_FieldNumber_ClientId = 15, + GtalkDataMessageStanza_FieldNumber_DeviceUserId = 16, + GtalkDataMessageStanza_FieldNumber_Ttl = 17, + GtalkDataMessageStanza_FieldNumber_Sent = 18, + GtalkDataMessageStanza_FieldNumber_Queued = 19, + GtalkDataMessageStanza_FieldNumber_Status = 20, + GtalkDataMessageStanza_FieldNumber_RawData = 21, + GtalkDataMessageStanza_FieldNumber_MaxDelay = 22, + GtalkDataMessageStanza_FieldNumber_ActualDelay = 23, + GtalkDataMessageStanza_FieldNumber_ImmediateAck = 24, + GtalkDataMessageStanza_FieldNumber_DeliveryReceiptRequested = 25, + GtalkDataMessageStanza_FieldNumber_ExternalMessageId = 26, + GtalkDataMessageStanza_FieldNumber_Flags = 27, + GtalkDataMessageStanza_FieldNumber_CellTower = 28, + GtalkDataMessageStanza_FieldNumber_Priority = 29, +}; + +@interface GtalkDataMessageStanza : GPBMessage + + +@property(nonatomic, readwrite) int64_t rmqId; + +@property(nonatomic, readwrite) BOOL hasRmqId; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *id_p; +/** Test to see if @c id_p has been set. */ +@property(nonatomic, readwrite) BOOL hasId_p; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *from; +/** Test to see if @c from has been set. */ +@property(nonatomic, readwrite) BOOL hasFrom; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *to; +/** Test to see if @c to has been set. */ +@property(nonatomic, readwrite) BOOL hasTo; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *category; +/** Test to see if @c category has been set. */ +@property(nonatomic, readwrite) BOOL hasCategory; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *token; +/** Test to see if @c token has been set. */ +@property(nonatomic, readwrite) BOOL hasToken; + + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *appDataArray; +/** The number of items in @c appDataArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger appDataArray_Count; + + +@property(nonatomic, readwrite) BOOL fromTrustedServer; + +@property(nonatomic, readwrite) BOOL hasFromTrustedServer; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *persistentId; +/** Test to see if @c persistentId has been set. */ +@property(nonatomic, readwrite) BOOL hasPersistentId; + + +@property(nonatomic, readwrite) int32_t streamId; + +@property(nonatomic, readwrite) BOOL hasStreamId; + +@property(nonatomic, readwrite) int32_t lastStreamIdReceived; + +@property(nonatomic, readwrite) BOOL hasLastStreamIdReceived; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *permission; +/** Test to see if @c permission has been set. */ +@property(nonatomic, readwrite) BOOL hasPermission; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *regId; +/** Test to see if @c regId has been set. */ +@property(nonatomic, readwrite) BOOL hasRegId; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *pkgSignature; +/** Test to see if @c pkgSignature has been set. */ +@property(nonatomic, readwrite) BOOL hasPkgSignature; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *clientId; +/** Test to see if @c clientId has been set. */ +@property(nonatomic, readwrite) BOOL hasClientId; + + +@property(nonatomic, readwrite) int64_t deviceUserId; + +@property(nonatomic, readwrite) BOOL hasDeviceUserId; + +@property(nonatomic, readwrite) int32_t ttl; + +@property(nonatomic, readwrite) BOOL hasTtl; + +@property(nonatomic, readwrite) int64_t sent; + +@property(nonatomic, readwrite) BOOL hasSent; + +@property(nonatomic, readwrite) int32_t queued; + +@property(nonatomic, readwrite) BOOL hasQueued; + +@property(nonatomic, readwrite) int64_t status; + +@property(nonatomic, readwrite) BOOL hasStatus; + +@property(nonatomic, readwrite, copy, null_resettable) NSData *rawData; +/** Test to see if @c rawData has been set. */ +@property(nonatomic, readwrite) BOOL hasRawData; + + +@property(nonatomic, readwrite) int32_t maxDelay; + +@property(nonatomic, readwrite) BOOL hasMaxDelay; + +@property(nonatomic, readwrite) int32_t actualDelay; + +@property(nonatomic, readwrite) BOOL hasActualDelay; + +@property(nonatomic, readwrite) BOOL immediateAck; + +@property(nonatomic, readwrite) BOOL hasImmediateAck; + +@property(nonatomic, readwrite) BOOL deliveryReceiptRequested; + +@property(nonatomic, readwrite) BOOL hasDeliveryReceiptRequested; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *externalMessageId; +/** Test to see if @c externalMessageId has been set. */ +@property(nonatomic, readwrite) BOOL hasExternalMessageId; + + +@property(nonatomic, readwrite) int64_t flags; + +@property(nonatomic, readwrite) BOOL hasFlags; + +@property(nonatomic, readwrite, strong, null_resettable) GtalkCellTower *cellTower DEPRECATED_ATTRIBUTE; +/** Test to see if @c cellTower has been set. */ +@property(nonatomic, readwrite) BOOL hasCellTower DEPRECATED_ATTRIBUTE; + + +@property(nonatomic, readwrite) int32_t priority; + +@property(nonatomic, readwrite) BOOL hasPriority; +@end + +#pragma mark - GtalkTalkMetadata + +typedef GPB_ENUM(GtalkTalkMetadata_FieldNumber) { + GtalkTalkMetadata_FieldNumber_Foreground = 1, +}; + +@interface GtalkTalkMetadata : GPBMessage + + +@property(nonatomic, readwrite) BOOL foreground; + +@property(nonatomic, readwrite) BOOL hasForeground; +@end + +#pragma mark - GtalkCellTower + +typedef GPB_ENUM(GtalkCellTower_FieldNumber) { + GtalkCellTower_FieldNumber_Id_p = 1, + GtalkCellTower_FieldNumber_KnownCongestionStatus = 2, +}; + +DEPRECATED_ATTRIBUTE +@interface GtalkCellTower : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *id_p; +/** Test to see if @c id_p has been set. */ +@property(nonatomic, readwrite) BOOL hasId_p; + + +@property(nonatomic, readwrite) int32_t knownCongestionStatus; + +@property(nonatomic, readwrite) BOOL hasKnownCongestionStatus; +@end + +#pragma mark - GtalkClientEvent + +typedef GPB_ENUM(GtalkClientEvent_FieldNumber) { + GtalkClientEvent_FieldNumber_Type = 1, + GtalkClientEvent_FieldNumber_NumberDiscardedEvents = 100, + GtalkClientEvent_FieldNumber_NetworkType = 200, + GtalkClientEvent_FieldNumber_NetworkPort = 201, + GtalkClientEvent_FieldNumber_TimeConnectionStartedMs = 202, + GtalkClientEvent_FieldNumber_TimeConnectionEndedMs = 203, + GtalkClientEvent_FieldNumber_ErrorCode = 204, + GtalkClientEvent_FieldNumber_TimeConnectionEstablishedMs = 300, + GtalkClientEvent_FieldNumber_McsReconnectAction = 400, +}; + +@interface GtalkClientEvent : GPBMessage + + +@property(nonatomic, readwrite) GtalkClientEvent_Type type; + +@property(nonatomic, readwrite) BOOL hasType; + +@property(nonatomic, readwrite) uint32_t numberDiscardedEvents; + +@property(nonatomic, readwrite) BOOL hasNumberDiscardedEvents; + +@property(nonatomic, readwrite) int32_t networkType; + +@property(nonatomic, readwrite) BOOL hasNetworkType; + +@property(nonatomic, readwrite) int32_t networkPort; + +@property(nonatomic, readwrite) BOOL hasNetworkPort; + +@property(nonatomic, readwrite) uint64_t timeConnectionStartedMs; + +@property(nonatomic, readwrite) BOOL hasTimeConnectionStartedMs; + +@property(nonatomic, readwrite) uint64_t timeConnectionEndedMs; + +@property(nonatomic, readwrite) BOOL hasTimeConnectionEndedMs; + +@property(nonatomic, readwrite) int32_t errorCode; + +@property(nonatomic, readwrite) BOOL hasErrorCode; + +@property(nonatomic, readwrite) uint64_t timeConnectionEstablishedMs; + +@property(nonatomic, readwrite) BOOL hasTimeConnectionEstablishedMs; + +@property(nonatomic, readwrite) GtalkClientEvent_McsReconnectAction mcsReconnectAction; + +@property(nonatomic, readwrite) BOOL hasMcsReconnectAction; +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/Protos/GtalkCore.pbobjc.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/Protos/GtalkCore.pbobjc.m new file mode 100644 index 00000000..06c91346 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/Protos/GtalkCore.pbobjc.m @@ -0,0 +1,3017 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: buzz/mobile/proto/gtalk_core.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + + #import "GtalkCore.pbobjc.h" +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +#pragma mark - GtalkGtalkCoreRoot + +@implementation GtalkGtalkCoreRoot + +// No extensions in the file and no imports, so no need to generate +// +extensionRegistry. + +@end + +#pragma mark - GtalkGtalkCoreRoot_FileDescriptor + +static GPBFileDescriptor *GtalkGtalkCoreRoot_FileDescriptor(void) { + // This is called by +initialize so there is no need to worry + // about thread safety of the singleton. + static GPBFileDescriptor *descriptor = NULL; + if (!descriptor) { + GPB_DEBUG_CHECK_RUNTIME_VERSIONS(); + descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"mobilegtalk" + objcPrefix:@"Gtalk" + syntax:GPBFileSyntaxProto2]; + } + return descriptor; +} + +#pragma mark - GtalkHeartbeatPing + +@implementation GtalkHeartbeatPing + +@dynamic hasStreamId, streamId; +@dynamic hasLastStreamIdReceived, lastStreamIdReceived; +@dynamic hasStatus, status; +@dynamic hasCellTower, cellTower; +@dynamic hasIntervalMs, intervalMs; + +typedef struct GtalkHeartbeatPing__storage_ { + uint32_t _has_storage_[1]; + int32_t streamId; + int32_t lastStreamIdReceived; + int32_t intervalMs; + GtalkCellTower *cellTower; + int64_t status; +} GtalkHeartbeatPing__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "streamId", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatPing_FieldNumber_StreamId, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkHeartbeatPing__storage_, streamId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "lastStreamIdReceived", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatPing_FieldNumber_LastStreamIdReceived, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkHeartbeatPing__storage_, lastStreamIdReceived), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "status", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatPing_FieldNumber_Status, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkHeartbeatPing__storage_, status), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "cellTower", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkCellTower), + .number = GtalkHeartbeatPing_FieldNumber_CellTower, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkHeartbeatPing__storage_, cellTower), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "intervalMs", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatPing_FieldNumber_IntervalMs, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkHeartbeatPing__storage_, intervalMs), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkHeartbeatPing class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkHeartbeatPing__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkHeartbeatAck + +@implementation GtalkHeartbeatAck + +@dynamic hasStreamId, streamId; +@dynamic hasLastStreamIdReceived, lastStreamIdReceived; +@dynamic hasStatus, status; +@dynamic hasCellTower, cellTower; +@dynamic hasIntervalMs, intervalMs; + +typedef struct GtalkHeartbeatAck__storage_ { + uint32_t _has_storage_[1]; + int32_t streamId; + int32_t lastStreamIdReceived; + int32_t intervalMs; + GtalkCellTower *cellTower; + int64_t status; +} GtalkHeartbeatAck__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "streamId", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatAck_FieldNumber_StreamId, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkHeartbeatAck__storage_, streamId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "lastStreamIdReceived", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatAck_FieldNumber_LastStreamIdReceived, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkHeartbeatAck__storage_, lastStreamIdReceived), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "status", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatAck_FieldNumber_Status, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkHeartbeatAck__storage_, status), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "cellTower", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkCellTower), + .number = GtalkHeartbeatAck_FieldNumber_CellTower, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkHeartbeatAck__storage_, cellTower), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "intervalMs", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatAck_FieldNumber_IntervalMs, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkHeartbeatAck__storage_, intervalMs), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkHeartbeatAck class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkHeartbeatAck__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkErrorInfo + +@implementation GtalkErrorInfo + +@dynamic hasCode, code; +@dynamic hasMessage, message; +@dynamic hasType, type; +@dynamic hasExtension, extension; + +typedef struct GtalkErrorInfo__storage_ { + uint32_t _has_storage_[1]; + int32_t code; + NSString *message; + NSString *type; + GtalkExtension *extension; +} GtalkErrorInfo__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "code", + .dataTypeSpecific.className = NULL, + .number = GtalkErrorInfo_FieldNumber_Code, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkErrorInfo__storage_, code), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeInt32, + }, + { + .name = "message", + .dataTypeSpecific.className = NULL, + .number = GtalkErrorInfo_FieldNumber_Message, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkErrorInfo__storage_, message), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "type", + .dataTypeSpecific.className = NULL, + .number = GtalkErrorInfo_FieldNumber_Type, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkErrorInfo__storage_, type), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "extension", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkExtension), + .number = GtalkErrorInfo_FieldNumber_Extension, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkErrorInfo__storage_, extension), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkErrorInfo class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkErrorInfo__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkSetting + +@implementation GtalkSetting + +@dynamic hasName, name; +@dynamic hasValue, value; + +typedef struct GtalkSetting__storage_ { + uint32_t _has_storage_[1]; + NSString *name; + NSString *value; +} GtalkSetting__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "name", + .dataTypeSpecific.className = NULL, + .number = GtalkSetting_FieldNumber_Name, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkSetting__storage_, name), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "value", + .dataTypeSpecific.className = NULL, + .number = GtalkSetting_FieldNumber_Value, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkSetting__storage_, value), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkSetting class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkSetting__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkHeartbeatStat + +@implementation GtalkHeartbeatStat + +@dynamic hasIp, ip; +@dynamic hasTimeout, timeout; +@dynamic hasIntervalMs, intervalMs; + +typedef struct GtalkHeartbeatStat__storage_ { + uint32_t _has_storage_[1]; + int32_t intervalMs; + NSString *ip; +} GtalkHeartbeatStat__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "ip", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatStat_FieldNumber_Ip, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkHeartbeatStat__storage_, ip), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "timeout", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatStat_FieldNumber_Timeout, + .hasIndex = 1, + .offset = 2, // Stored in _has_storage_ to save space. + .flags = GPBFieldRequired, + .dataType = GPBDataTypeBool, + }, + { + .name = "intervalMs", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatStat_FieldNumber_IntervalMs, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkHeartbeatStat__storage_, intervalMs), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkHeartbeatStat class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkHeartbeatStat__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkHeartbeatConfig + +@implementation GtalkHeartbeatConfig + +@dynamic hasUploadStat, uploadStat; +@dynamic hasIp, ip; +@dynamic hasIntervalMs, intervalMs; + +typedef struct GtalkHeartbeatConfig__storage_ { + uint32_t _has_storage_[1]; + int32_t intervalMs; + NSString *ip; +} GtalkHeartbeatConfig__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "uploadStat", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatConfig_FieldNumber_UploadStat, + .hasIndex = 0, + .offset = 1, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "ip", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatConfig_FieldNumber_Ip, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkHeartbeatConfig__storage_, ip), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "intervalMs", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatConfig_FieldNumber_IntervalMs, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkHeartbeatConfig__storage_, intervalMs), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkHeartbeatConfig class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkHeartbeatConfig__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkLoginRequest + +@implementation GtalkLoginRequest + +@dynamic hasId_p, id_p; +@dynamic hasDomain, domain; +@dynamic hasUser, user; +@dynamic hasResource, resource; +@dynamic hasAuthToken, authToken; +@dynamic hasDeviceId, deviceId; +@dynamic hasLastRmqId, lastRmqId; +@dynamic settingArray, settingArray_Count; +@dynamic receivedPersistentIdArray, receivedPersistentIdArray_Count; +@dynamic hasIncludeStreamIds, includeStreamIds; +@dynamic hasHeartbeatStat, heartbeatStat; +@dynamic hasUseRmq2, useRmq2; +@dynamic hasAccountId, accountId; +@dynamic hasAuthService, authService; +@dynamic hasNetworkType, networkType; +@dynamic hasStatus, status; +@dynamic hasTokenVersionInfo, tokenVersionInfo; +@dynamic hasCellTower, cellTower; +@dynamic hasGcmStartTimeMs, gcmStartTimeMs; +@dynamic clientEventArray, clientEventArray_Count; +@dynamic hasOnFallback, onFallback; +@dynamic hasNoPendingUpstream, noPendingUpstream; +@dynamic hasReconnectRequestId, reconnectRequestId; + +typedef struct GtalkLoginRequest__storage_ { + uint32_t _has_storage_[1]; + GtalkLoginRequest_AuthService authService; + int32_t networkType; + int32_t reconnectRequestId; + NSString *id_p; + NSString *domain; + NSString *user; + NSString *resource; + NSString *authToken; + NSString *deviceId; + NSMutableArray *settingArray; + NSMutableArray *receivedPersistentIdArray; + GtalkHeartbeatStat *heartbeatStat; + NSString *tokenVersionInfo; + GtalkCellTower *cellTower; + NSMutableArray *clientEventArray; + int64_t lastRmqId; + int64_t accountId; + int64_t status; + uint64_t gcmStartTimeMs; +} GtalkLoginRequest__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_Id_p, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, id_p), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "domain", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_Domain, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, domain), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "user", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_User, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, user), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "resource", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_Resource, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, resource), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "authToken", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_AuthToken, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, authToken), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "deviceId", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_DeviceId, + .hasIndex = 5, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, deviceId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "lastRmqId", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_LastRmqId, + .hasIndex = 6, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, lastRmqId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "settingArray", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkSetting), + .number = GtalkLoginRequest_FieldNumber_SettingArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, settingArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "receivedPersistentIdArray", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_ReceivedPersistentIdArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, receivedPersistentIdArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeString, + }, + { + .name = "includeStreamIds", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_IncludeStreamIds, + .hasIndex = 7, + .offset = 8, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "heartbeatStat", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkHeartbeatStat), + .number = GtalkLoginRequest_FieldNumber_HeartbeatStat, + .hasIndex = 9, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, heartbeatStat), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "useRmq2", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_UseRmq2, + .hasIndex = 10, + .offset = 11, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "accountId", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_AccountId, + .hasIndex = 12, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, accountId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "authService", + .dataTypeSpecific.enumDescFunc = GtalkLoginRequest_AuthService_EnumDescriptor, + .number = GtalkLoginRequest_FieldNumber_AuthService, + .hasIndex = 13, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, authService), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "networkType", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_NetworkType, + .hasIndex = 14, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, networkType), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "status", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_Status, + .hasIndex = 15, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, status), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "tokenVersionInfo", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_TokenVersionInfo, + .hasIndex = 16, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, tokenVersionInfo), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "cellTower", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkCellTower), + .number = GtalkLoginRequest_FieldNumber_CellTower, + .hasIndex = 17, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, cellTower), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "gcmStartTimeMs", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_GcmStartTimeMs, + .hasIndex = 18, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, gcmStartTimeMs), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeUInt64, + }, + { + .name = "clientEventArray", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkClientEvent), + .number = GtalkLoginRequest_FieldNumber_ClientEventArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, clientEventArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "onFallback", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_OnFallback, + .hasIndex = 19, + .offset = 20, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "noPendingUpstream", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_NoPendingUpstream, + .hasIndex = 21, + .offset = 22, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "reconnectRequestId", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_ReconnectRequestId, + .hasIndex = 23, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, reconnectRequestId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkLoginRequest class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkLoginRequest__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - Enum GtalkLoginRequest_AuthService + +GPBEnumDescriptor *GtalkLoginRequest_AuthService_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "Mail\000AndroidCloudToDeviceMessage\000Android" + "Id\000"; + static const int32_t values[] = { + GtalkLoginRequest_AuthService_Mail, + GtalkLoginRequest_AuthService_AndroidCloudToDeviceMessage, + GtalkLoginRequest_AuthService_AndroidId, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkLoginRequest_AuthService) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkLoginRequest_AuthService_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkLoginRequest_AuthService_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkLoginRequest_AuthService_Mail: + case GtalkLoginRequest_AuthService_AndroidCloudToDeviceMessage: + case GtalkLoginRequest_AuthService_AndroidId: + return YES; + default: + return NO; + } +} + +#pragma mark - GtalkLoginResponse + +@implementation GtalkLoginResponse + +@dynamic hasId_p, id_p; +@dynamic hasJid, jid; +@dynamic hasError, error; +@dynamic settingArray, settingArray_Count; +@dynamic hasStreamId, streamId; +@dynamic hasLastStreamIdReceived, lastStreamIdReceived; +@dynamic hasHeartbeatConfig, heartbeatConfig; +@dynamic hasServerTimestamp, serverTimestamp; + +typedef struct GtalkLoginResponse__storage_ { + uint32_t _has_storage_[1]; + int32_t streamId; + int32_t lastStreamIdReceived; + NSString *id_p; + NSString *jid; + GtalkErrorInfo *error; + NSMutableArray *settingArray; + GtalkHeartbeatConfig *heartbeatConfig; + int64_t serverTimestamp; +} GtalkLoginResponse__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginResponse_FieldNumber_Id_p, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkLoginResponse__storage_, id_p), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "jid", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginResponse_FieldNumber_Jid, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkLoginResponse__storage_, jid), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "error", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkErrorInfo), + .number = GtalkLoginResponse_FieldNumber_Error, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkLoginResponse__storage_, error), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "settingArray", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkSetting), + .number = GtalkLoginResponse_FieldNumber_SettingArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkLoginResponse__storage_, settingArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "streamId", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginResponse_FieldNumber_StreamId, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkLoginResponse__storage_, streamId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "lastStreamIdReceived", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginResponse_FieldNumber_LastStreamIdReceived, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkLoginResponse__storage_, lastStreamIdReceived), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "heartbeatConfig", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkHeartbeatConfig), + .number = GtalkLoginResponse_FieldNumber_HeartbeatConfig, + .hasIndex = 5, + .offset = (uint32_t)offsetof(GtalkLoginResponse__storage_, heartbeatConfig), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "serverTimestamp", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginResponse_FieldNumber_ServerTimestamp, + .hasIndex = 6, + .offset = (uint32_t)offsetof(GtalkLoginResponse__storage_, serverTimestamp), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkLoginResponse class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkLoginResponse__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkBindAccountRequest + +@implementation GtalkBindAccountRequest + +@dynamic hasId_p, id_p; +@dynamic hasDomain, domain; +@dynamic hasUser, user; +@dynamic hasResource, resource; +@dynamic hasAuthToken, authToken; +@dynamic hasPersistentId, persistentId; +@dynamic hasStreamId, streamId; +@dynamic hasLastStreamIdReceived, lastStreamIdReceived; +@dynamic hasAccountId, accountId; + +typedef struct GtalkBindAccountRequest__storage_ { + uint32_t _has_storage_[1]; + int32_t streamId; + int32_t lastStreamIdReceived; + NSString *id_p; + NSString *domain; + NSString *user; + NSString *resource; + NSString *authToken; + NSString *persistentId; + int64_t accountId; +} GtalkBindAccountRequest__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountRequest_FieldNumber_Id_p, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkBindAccountRequest__storage_, id_p), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "domain", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountRequest_FieldNumber_Domain, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkBindAccountRequest__storage_, domain), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "user", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountRequest_FieldNumber_User, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkBindAccountRequest__storage_, user), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "resource", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountRequest_FieldNumber_Resource, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkBindAccountRequest__storage_, resource), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "authToken", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountRequest_FieldNumber_AuthToken, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkBindAccountRequest__storage_, authToken), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "persistentId", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountRequest_FieldNumber_PersistentId, + .hasIndex = 5, + .offset = (uint32_t)offsetof(GtalkBindAccountRequest__storage_, persistentId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "streamId", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountRequest_FieldNumber_StreamId, + .hasIndex = 6, + .offset = (uint32_t)offsetof(GtalkBindAccountRequest__storage_, streamId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "lastStreamIdReceived", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountRequest_FieldNumber_LastStreamIdReceived, + .hasIndex = 7, + .offset = (uint32_t)offsetof(GtalkBindAccountRequest__storage_, lastStreamIdReceived), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "accountId", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountRequest_FieldNumber_AccountId, + .hasIndex = 8, + .offset = (uint32_t)offsetof(GtalkBindAccountRequest__storage_, accountId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkBindAccountRequest class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkBindAccountRequest__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkBindAccountResponse + +@implementation GtalkBindAccountResponse + +@dynamic hasId_p, id_p; +@dynamic hasJid, jid; +@dynamic hasError, error; +@dynamic hasStreamId, streamId; +@dynamic hasLastStreamIdReceived, lastStreamIdReceived; + +typedef struct GtalkBindAccountResponse__storage_ { + uint32_t _has_storage_[1]; + int32_t streamId; + int32_t lastStreamIdReceived; + NSString *id_p; + NSString *jid; + GtalkErrorInfo *error; +} GtalkBindAccountResponse__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountResponse_FieldNumber_Id_p, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkBindAccountResponse__storage_, id_p), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "jid", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountResponse_FieldNumber_Jid, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkBindAccountResponse__storage_, jid), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "error", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkErrorInfo), + .number = GtalkBindAccountResponse_FieldNumber_Error, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkBindAccountResponse__storage_, error), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "streamId", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountResponse_FieldNumber_StreamId, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkBindAccountResponse__storage_, streamId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "lastStreamIdReceived", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountResponse_FieldNumber_LastStreamIdReceived, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkBindAccountResponse__storage_, lastStreamIdReceived), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkBindAccountResponse class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkBindAccountResponse__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkStreamErrorStanza + +@implementation GtalkStreamErrorStanza + +@dynamic hasType, type; +@dynamic hasText, text; + +typedef struct GtalkStreamErrorStanza__storage_ { + uint32_t _has_storage_[1]; + NSString *type; + NSString *text; +} GtalkStreamErrorStanza__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "type", + .dataTypeSpecific.className = NULL, + .number = GtalkStreamErrorStanza_FieldNumber_Type, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkStreamErrorStanza__storage_, type), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "text", + .dataTypeSpecific.className = NULL, + .number = GtalkStreamErrorStanza_FieldNumber_Text, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkStreamErrorStanza__storage_, text), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkStreamErrorStanza class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkStreamErrorStanza__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkClose + +@implementation GtalkClose + + +typedef struct GtalkClose__storage_ { + uint32_t _has_storage_[1]; +} GtalkClose__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkClose class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:NULL + fieldCount:0 + storageSize:sizeof(GtalkClose__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkExtension + +@implementation GtalkExtension + +@dynamic hasId_p, id_p; +@dynamic hasData_p, data_p; + +typedef struct GtalkExtension__storage_ { + uint32_t _has_storage_[1]; + int32_t id_p; + NSString *data_p; +} GtalkExtension__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkExtension_FieldNumber_Id_p, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkExtension__storage_, id_p), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeInt32, + }, + { + .name = "data_p", + .dataTypeSpecific.className = NULL, + .number = GtalkExtension_FieldNumber_Data_p, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkExtension__storage_, data_p), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkExtension class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkExtension__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkMessageStanza + +@implementation GtalkMessageStanza + +@dynamic hasRmqId, rmqId; +@dynamic hasType, type; +@dynamic hasId_p, id_p; +@dynamic hasFrom, from; +@dynamic hasTo, to; +@dynamic hasSubject, subject; +@dynamic hasBody, body; +@dynamic hasThread, thread; +@dynamic hasError, error; +@dynamic extensionArray, extensionArray_Count; +@dynamic hasNosave, nosave; +@dynamic hasTimestamp, timestamp; +@dynamic hasPersistentId, persistentId; +@dynamic hasStreamId, streamId; +@dynamic hasLastStreamIdReceived, lastStreamIdReceived; +@dynamic hasRead, read; +@dynamic hasAccountId, accountId; + +typedef struct GtalkMessageStanza__storage_ { + uint32_t _has_storage_[1]; + GtalkMessageStanza_MessageType type; + int32_t streamId; + int32_t lastStreamIdReceived; + NSString *id_p; + NSString *from; + NSString *to; + NSString *subject; + NSString *body; + NSString *thread; + GtalkErrorInfo *error; + NSMutableArray *extensionArray; + NSString *persistentId; + int64_t rmqId; + int64_t timestamp; + int64_t accountId; +} GtalkMessageStanza__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "rmqId", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_RmqId, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, rmqId), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldTextFormatNameCustom), + .dataType = GPBDataTypeInt64, + }, + { + .name = "type", + .dataTypeSpecific.enumDescFunc = GtalkMessageStanza_MessageType_EnumDescriptor, + .number = GtalkMessageStanza_FieldNumber_Type, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, type), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_Id_p, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, id_p), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "from", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_From, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, from), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "to", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_To, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, to), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "subject", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_Subject, + .hasIndex = 5, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, subject), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "body", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_Body, + .hasIndex = 6, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, body), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "thread", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_Thread, + .hasIndex = 7, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, thread), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "error", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkErrorInfo), + .number = GtalkMessageStanza_FieldNumber_Error, + .hasIndex = 8, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, error), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "extensionArray", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkExtension), + .number = GtalkMessageStanza_FieldNumber_ExtensionArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, extensionArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "nosave", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_Nosave, + .hasIndex = 9, + .offset = 10, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "timestamp", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_Timestamp, + .hasIndex = 11, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, timestamp), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "persistentId", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_PersistentId, + .hasIndex = 12, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, persistentId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "streamId", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_StreamId, + .hasIndex = 13, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, streamId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "lastStreamIdReceived", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_LastStreamIdReceived, + .hasIndex = 14, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, lastStreamIdReceived), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "read", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_Read, + .hasIndex = 15, + .offset = 16, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "accountId", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_AccountId, + .hasIndex = 17, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, accountId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkMessageStanza class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkMessageStanza__storage_) + flags:GPBDescriptorInitializationFlag_None]; +#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS + static const char *extraTextFormatInfo = + "\001\001\005\000"; + [localDescriptor setupExtraTextInfo:extraTextFormatInfo]; +#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - Enum GtalkMessageStanza_MessageType + +GPBEnumDescriptor *GtalkMessageStanza_MessageType_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "Normal\000Chat\000Groupchat\000Headline\000Error\000"; + static const int32_t values[] = { + GtalkMessageStanza_MessageType_Normal, + GtalkMessageStanza_MessageType_Chat, + GtalkMessageStanza_MessageType_Groupchat, + GtalkMessageStanza_MessageType_Headline, + GtalkMessageStanza_MessageType_Error, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkMessageStanza_MessageType) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkMessageStanza_MessageType_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkMessageStanza_MessageType_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkMessageStanza_MessageType_Normal: + case GtalkMessageStanza_MessageType_Chat: + case GtalkMessageStanza_MessageType_Groupchat: + case GtalkMessageStanza_MessageType_Headline: + case GtalkMessageStanza_MessageType_Error: + return YES; + default: + return NO; + } +} + +#pragma mark - GtalkPresenceStanza + +@implementation GtalkPresenceStanza + +@dynamic hasRmqId, rmqId; +@dynamic hasType, type; +@dynamic hasId_p, id_p; +@dynamic hasFrom, from; +@dynamic hasTo, to; +@dynamic hasShow, show; +@dynamic hasStatus, status; +@dynamic hasPriority, priority; +@dynamic hasError, error; +@dynamic extensionArray, extensionArray_Count; +@dynamic hasClient, client; +@dynamic hasAvatarHash, avatarHash; +@dynamic hasPersistentId, persistentId; +@dynamic hasStreamId, streamId; +@dynamic hasLastStreamIdReceived, lastStreamIdReceived; +@dynamic hasCapabilitiesFlags, capabilitiesFlags; +@dynamic hasAccountId, accountId; + +typedef struct GtalkPresenceStanza__storage_ { + uint32_t _has_storage_[1]; + GtalkPresenceStanza_PresenceType type; + GtalkPresenceStanza_ShowType show; + int32_t priority; + GtalkPresenceStanza_ClientType client; + int32_t streamId; + int32_t lastStreamIdReceived; + int32_t capabilitiesFlags; + NSString *id_p; + NSString *from; + NSString *to; + NSString *status; + GtalkErrorInfo *error; + NSMutableArray *extensionArray; + NSString *avatarHash; + NSString *persistentId; + int64_t rmqId; + int64_t accountId; +} GtalkPresenceStanza__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "rmqId", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_RmqId, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, rmqId), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldTextFormatNameCustom), + .dataType = GPBDataTypeInt64, + }, + { + .name = "type", + .dataTypeSpecific.enumDescFunc = GtalkPresenceStanza_PresenceType_EnumDescriptor, + .number = GtalkPresenceStanza_FieldNumber_Type, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, type), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_Id_p, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, id_p), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "from", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_From, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, from), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "to", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_To, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, to), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "show", + .dataTypeSpecific.enumDescFunc = GtalkPresenceStanza_ShowType_EnumDescriptor, + .number = GtalkPresenceStanza_FieldNumber_Show, + .hasIndex = 5, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, show), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "status", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_Status, + .hasIndex = 6, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, status), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "priority", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_Priority, + .hasIndex = 7, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, priority), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "error", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkErrorInfo), + .number = GtalkPresenceStanza_FieldNumber_Error, + .hasIndex = 8, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, error), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "extensionArray", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkExtension), + .number = GtalkPresenceStanza_FieldNumber_ExtensionArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, extensionArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "client", + .dataTypeSpecific.enumDescFunc = GtalkPresenceStanza_ClientType_EnumDescriptor, + .number = GtalkPresenceStanza_FieldNumber_Client, + .hasIndex = 9, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, client), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "avatarHash", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_AvatarHash, + .hasIndex = 10, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, avatarHash), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "persistentId", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_PersistentId, + .hasIndex = 11, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, persistentId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "streamId", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_StreamId, + .hasIndex = 12, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, streamId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "lastStreamIdReceived", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_LastStreamIdReceived, + .hasIndex = 13, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, lastStreamIdReceived), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "capabilitiesFlags", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_CapabilitiesFlags, + .hasIndex = 14, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, capabilitiesFlags), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "accountId", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_AccountId, + .hasIndex = 15, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, accountId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkPresenceStanza class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkPresenceStanza__storage_) + flags:GPBDescriptorInitializationFlag_None]; +#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS + static const char *extraTextFormatInfo = + "\001\001\005\000"; + [localDescriptor setupExtraTextInfo:extraTextFormatInfo]; +#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - Enum GtalkPresenceStanza_PresenceType + +GPBEnumDescriptor *GtalkPresenceStanza_PresenceType_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "Unavailable\000Subscribe\000Subscribed\000Unsubsc" + "ribe\000Unsubscribed\000Probe\000Error\000"; + static const int32_t values[] = { + GtalkPresenceStanza_PresenceType_Unavailable, + GtalkPresenceStanza_PresenceType_Subscribe, + GtalkPresenceStanza_PresenceType_Subscribed, + GtalkPresenceStanza_PresenceType_Unsubscribe, + GtalkPresenceStanza_PresenceType_Unsubscribed, + GtalkPresenceStanza_PresenceType_Probe, + GtalkPresenceStanza_PresenceType_Error, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkPresenceStanza_PresenceType) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkPresenceStanza_PresenceType_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkPresenceStanza_PresenceType_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkPresenceStanza_PresenceType_Unavailable: + case GtalkPresenceStanza_PresenceType_Subscribe: + case GtalkPresenceStanza_PresenceType_Subscribed: + case GtalkPresenceStanza_PresenceType_Unsubscribe: + case GtalkPresenceStanza_PresenceType_Unsubscribed: + case GtalkPresenceStanza_PresenceType_Probe: + case GtalkPresenceStanza_PresenceType_Error: + return YES; + default: + return NO; + } +} + +#pragma mark - Enum GtalkPresenceStanza_ShowType + +GPBEnumDescriptor *GtalkPresenceStanza_ShowType_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "Away\000Chat\000Dnd\000Xa\000"; + static const int32_t values[] = { + GtalkPresenceStanza_ShowType_Away, + GtalkPresenceStanza_ShowType_Chat, + GtalkPresenceStanza_ShowType_Dnd, + GtalkPresenceStanza_ShowType_Xa, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkPresenceStanza_ShowType) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkPresenceStanza_ShowType_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkPresenceStanza_ShowType_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkPresenceStanza_ShowType_Away: + case GtalkPresenceStanza_ShowType_Chat: + case GtalkPresenceStanza_ShowType_Dnd: + case GtalkPresenceStanza_ShowType_Xa: + return YES; + default: + return NO; + } +} + +#pragma mark - Enum GtalkPresenceStanza_ClientType + +GPBEnumDescriptor *GtalkPresenceStanza_ClientType_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "Mobile\000Android\000"; + static const int32_t values[] = { + GtalkPresenceStanza_ClientType_Mobile, + GtalkPresenceStanza_ClientType_Android, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkPresenceStanza_ClientType) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkPresenceStanza_ClientType_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkPresenceStanza_ClientType_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkPresenceStanza_ClientType_Mobile: + case GtalkPresenceStanza_ClientType_Android: + return YES; + default: + return NO; + } +} + +#pragma mark - Enum GtalkPresenceStanza_CapabilitiesFlags + +GPBEnumDescriptor *GtalkPresenceStanza_CapabilitiesFlags_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "HasVoiceV1\000HasVideoV1\000HasCameraV1\000HasPmu" + "cV1\000"; + static const int32_t values[] = { + GtalkPresenceStanza_CapabilitiesFlags_HasVoiceV1, + GtalkPresenceStanza_CapabilitiesFlags_HasVideoV1, + GtalkPresenceStanza_CapabilitiesFlags_HasCameraV1, + GtalkPresenceStanza_CapabilitiesFlags_HasPmucV1, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkPresenceStanza_CapabilitiesFlags) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkPresenceStanza_CapabilitiesFlags_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkPresenceStanza_CapabilitiesFlags_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkPresenceStanza_CapabilitiesFlags_HasVoiceV1: + case GtalkPresenceStanza_CapabilitiesFlags_HasVideoV1: + case GtalkPresenceStanza_CapabilitiesFlags_HasCameraV1: + case GtalkPresenceStanza_CapabilitiesFlags_HasPmucV1: + return YES; + default: + return NO; + } +} + +#pragma mark - GtalkBatchPresenceStanza + +@implementation GtalkBatchPresenceStanza + +@dynamic hasId_p, id_p; +@dynamic hasTo, to; +@dynamic presenceArray, presenceArray_Count; +@dynamic hasPersistentId, persistentId; +@dynamic hasStreamId, streamId; +@dynamic hasLastStreamIdReceived, lastStreamIdReceived; +@dynamic hasAccountId, accountId; +@dynamic hasType, type; +@dynamic hasError, error; + +typedef struct GtalkBatchPresenceStanza__storage_ { + uint32_t _has_storage_[1]; + int32_t streamId; + int32_t lastStreamIdReceived; + GtalkBatchPresenceStanza_Type type; + NSString *id_p; + NSString *to; + NSMutableArray *presenceArray; + NSString *persistentId; + GtalkErrorInfo *error; + int64_t accountId; +} GtalkBatchPresenceStanza__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkBatchPresenceStanza_FieldNumber_Id_p, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkBatchPresenceStanza__storage_, id_p), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "to", + .dataTypeSpecific.className = NULL, + .number = GtalkBatchPresenceStanza_FieldNumber_To, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkBatchPresenceStanza__storage_, to), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "presenceArray", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkPresenceStanza), + .number = GtalkBatchPresenceStanza_FieldNumber_PresenceArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkBatchPresenceStanza__storage_, presenceArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "persistentId", + .dataTypeSpecific.className = NULL, + .number = GtalkBatchPresenceStanza_FieldNumber_PersistentId, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkBatchPresenceStanza__storage_, persistentId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "streamId", + .dataTypeSpecific.className = NULL, + .number = GtalkBatchPresenceStanza_FieldNumber_StreamId, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkBatchPresenceStanza__storage_, streamId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "lastStreamIdReceived", + .dataTypeSpecific.className = NULL, + .number = GtalkBatchPresenceStanza_FieldNumber_LastStreamIdReceived, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkBatchPresenceStanza__storage_, lastStreamIdReceived), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "accountId", + .dataTypeSpecific.className = NULL, + .number = GtalkBatchPresenceStanza_FieldNumber_AccountId, + .hasIndex = 5, + .offset = (uint32_t)offsetof(GtalkBatchPresenceStanza__storage_, accountId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "type", + .dataTypeSpecific.enumDescFunc = GtalkBatchPresenceStanza_Type_EnumDescriptor, + .number = GtalkBatchPresenceStanza_FieldNumber_Type, + .hasIndex = 6, + .offset = (uint32_t)offsetof(GtalkBatchPresenceStanza__storage_, type), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "error", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkErrorInfo), + .number = GtalkBatchPresenceStanza_FieldNumber_Error, + .hasIndex = 7, + .offset = (uint32_t)offsetof(GtalkBatchPresenceStanza__storage_, error), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkBatchPresenceStanza class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkBatchPresenceStanza__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - Enum GtalkBatchPresenceStanza_Type + +GPBEnumDescriptor *GtalkBatchPresenceStanza_Type_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "Get\000Set\000"; + static const int32_t values[] = { + GtalkBatchPresenceStanza_Type_Get, + GtalkBatchPresenceStanza_Type_Set, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkBatchPresenceStanza_Type) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkBatchPresenceStanza_Type_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkBatchPresenceStanza_Type_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkBatchPresenceStanza_Type_Get: + case GtalkBatchPresenceStanza_Type_Set: + return YES; + default: + return NO; + } +} + +#pragma mark - GtalkIqStanza + +@implementation GtalkIqStanza + +@dynamic hasRmqId, rmqId; +@dynamic hasType, type; +@dynamic hasId_p, id_p; +@dynamic hasFrom, from; +@dynamic hasTo, to; +@dynamic hasError, error; +@dynamic hasExtension, extension; +@dynamic hasPersistentId, persistentId; +@dynamic hasStreamId, streamId; +@dynamic hasLastStreamIdReceived, lastStreamIdReceived; +@dynamic hasAccountId, accountId; +@dynamic hasStatus, status; + +typedef struct GtalkIqStanza__storage_ { + uint32_t _has_storage_[1]; + GtalkIqStanza_IqType type; + int32_t streamId; + int32_t lastStreamIdReceived; + NSString *id_p; + NSString *from; + NSString *to; + GtalkErrorInfo *error; + GtalkExtension *extension; + NSString *persistentId; + int64_t rmqId; + int64_t accountId; + int64_t status; +} GtalkIqStanza__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "rmqId", + .dataTypeSpecific.className = NULL, + .number = GtalkIqStanza_FieldNumber_RmqId, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, rmqId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "type", + .dataTypeSpecific.enumDescFunc = GtalkIqStanza_IqType_EnumDescriptor, + .number = GtalkIqStanza_FieldNumber_Type, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, type), + .flags = (GPBFieldFlags)(GPBFieldRequired | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkIqStanza_FieldNumber_Id_p, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, id_p), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "from", + .dataTypeSpecific.className = NULL, + .number = GtalkIqStanza_FieldNumber_From, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, from), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "to", + .dataTypeSpecific.className = NULL, + .number = GtalkIqStanza_FieldNumber_To, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, to), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "error", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkErrorInfo), + .number = GtalkIqStanza_FieldNumber_Error, + .hasIndex = 5, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, error), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "extension", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkExtension), + .number = GtalkIqStanza_FieldNumber_Extension, + .hasIndex = 6, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, extension), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "persistentId", + .dataTypeSpecific.className = NULL, + .number = GtalkIqStanza_FieldNumber_PersistentId, + .hasIndex = 7, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, persistentId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "streamId", + .dataTypeSpecific.className = NULL, + .number = GtalkIqStanza_FieldNumber_StreamId, + .hasIndex = 8, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, streamId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "lastStreamIdReceived", + .dataTypeSpecific.className = NULL, + .number = GtalkIqStanza_FieldNumber_LastStreamIdReceived, + .hasIndex = 9, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, lastStreamIdReceived), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "accountId", + .dataTypeSpecific.className = NULL, + .number = GtalkIqStanza_FieldNumber_AccountId, + .hasIndex = 10, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, accountId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "status", + .dataTypeSpecific.className = NULL, + .number = GtalkIqStanza_FieldNumber_Status, + .hasIndex = 11, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, status), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkIqStanza class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkIqStanza__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - Enum GtalkIqStanza_IqType + +GPBEnumDescriptor *GtalkIqStanza_IqType_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "Get\000Set\000Result\000Error\000"; + static const int32_t values[] = { + GtalkIqStanza_IqType_Get, + GtalkIqStanza_IqType_Set, + GtalkIqStanza_IqType_Result, + GtalkIqStanza_IqType_Error, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkIqStanza_IqType) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkIqStanza_IqType_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkIqStanza_IqType_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkIqStanza_IqType_Get: + case GtalkIqStanza_IqType_Set: + case GtalkIqStanza_IqType_Result: + case GtalkIqStanza_IqType_Error: + return YES; + default: + return NO; + } +} + +#pragma mark - GtalkAppData + +@implementation GtalkAppData + +@dynamic hasKey, key; +@dynamic hasValue, value; + +typedef struct GtalkAppData__storage_ { + uint32_t _has_storage_[1]; + NSString *key; + NSString *value; +} GtalkAppData__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "key", + .dataTypeSpecific.className = NULL, + .number = GtalkAppData_FieldNumber_Key, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkAppData__storage_, key), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "value", + .dataTypeSpecific.className = NULL, + .number = GtalkAppData_FieldNumber_Value, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkAppData__storage_, value), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkAppData class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkAppData__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkDataMessageStanza + +@implementation GtalkDataMessageStanza + +@dynamic hasRmqId, rmqId; +@dynamic hasId_p, id_p; +@dynamic hasFrom, from; +@dynamic hasTo, to; +@dynamic hasCategory, category; +@dynamic hasToken, token; +@dynamic appDataArray, appDataArray_Count; +@dynamic hasFromTrustedServer, fromTrustedServer; +@dynamic hasPersistentId, persistentId; +@dynamic hasStreamId, streamId; +@dynamic hasLastStreamIdReceived, lastStreamIdReceived; +@dynamic hasPermission, permission; +@dynamic hasRegId, regId; +@dynamic hasPkgSignature, pkgSignature; +@dynamic hasClientId, clientId; +@dynamic hasDeviceUserId, deviceUserId; +@dynamic hasTtl, ttl; +@dynamic hasSent, sent; +@dynamic hasQueued, queued; +@dynamic hasStatus, status; +@dynamic hasRawData, rawData; +@dynamic hasMaxDelay, maxDelay; +@dynamic hasActualDelay, actualDelay; +@dynamic hasImmediateAck, immediateAck; +@dynamic hasDeliveryReceiptRequested, deliveryReceiptRequested; +@dynamic hasExternalMessageId, externalMessageId; +@dynamic hasFlags, flags; +@dynamic hasCellTower, cellTower; +@dynamic hasPriority, priority; + +typedef struct GtalkDataMessageStanza__storage_ { + uint32_t _has_storage_[1]; + int32_t streamId; + int32_t lastStreamIdReceived; + int32_t ttl; + int32_t queued; + int32_t maxDelay; + int32_t actualDelay; + int32_t priority; + NSString *id_p; + NSString *from; + NSString *to; + NSString *category; + NSString *token; + NSMutableArray *appDataArray; + NSString *persistentId; + NSString *permission; + NSString *regId; + NSString *pkgSignature; + NSString *clientId; + NSData *rawData; + NSString *externalMessageId; + GtalkCellTower *cellTower; + int64_t rmqId; + int64_t deviceUserId; + int64_t sent; + int64_t status; + int64_t flags; +} GtalkDataMessageStanza__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "rmqId", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_RmqId, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, rmqId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_Id_p, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, id_p), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "from", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_From, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, from), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "to", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_To, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, to), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "category", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_Category, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, category), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "token", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_Token, + .hasIndex = 5, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, token), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "appDataArray", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkAppData), + .number = GtalkDataMessageStanza_FieldNumber_AppDataArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, appDataArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "fromTrustedServer", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_FromTrustedServer, + .hasIndex = 6, + .offset = 7, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "persistentId", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_PersistentId, + .hasIndex = 8, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, persistentId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "streamId", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_StreamId, + .hasIndex = 9, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, streamId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "lastStreamIdReceived", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_LastStreamIdReceived, + .hasIndex = 10, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, lastStreamIdReceived), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "permission", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_Permission, + .hasIndex = 11, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, permission), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "regId", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_RegId, + .hasIndex = 12, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, regId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "pkgSignature", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_PkgSignature, + .hasIndex = 13, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, pkgSignature), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "clientId", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_ClientId, + .hasIndex = 14, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, clientId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "deviceUserId", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_DeviceUserId, + .hasIndex = 15, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, deviceUserId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "ttl", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_Ttl, + .hasIndex = 16, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, ttl), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "sent", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_Sent, + .hasIndex = 17, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, sent), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "queued", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_Queued, + .hasIndex = 18, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, queued), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "status", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_Status, + .hasIndex = 19, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, status), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "rawData", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_RawData, + .hasIndex = 20, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, rawData), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBytes, + }, + { + .name = "maxDelay", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_MaxDelay, + .hasIndex = 21, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, maxDelay), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "actualDelay", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_ActualDelay, + .hasIndex = 22, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, actualDelay), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "immediateAck", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_ImmediateAck, + .hasIndex = 23, + .offset = 24, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "deliveryReceiptRequested", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_DeliveryReceiptRequested, + .hasIndex = 25, + .offset = 26, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "externalMessageId", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_ExternalMessageId, + .hasIndex = 27, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, externalMessageId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "flags", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_Flags, + .hasIndex = 28, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, flags), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "cellTower", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkCellTower), + .number = GtalkDataMessageStanza_FieldNumber_CellTower, + .hasIndex = 29, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, cellTower), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "priority", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_Priority, + .hasIndex = 30, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, priority), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkDataMessageStanza class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkDataMessageStanza__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkTalkMetadata + +@implementation GtalkTalkMetadata + +@dynamic hasForeground, foreground; + +typedef struct GtalkTalkMetadata__storage_ { + uint32_t _has_storage_[1]; +} GtalkTalkMetadata__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "foreground", + .dataTypeSpecific.className = NULL, + .number = GtalkTalkMetadata_FieldNumber_Foreground, + .hasIndex = 0, + .offset = 1, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkTalkMetadata class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkTalkMetadata__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkCellTower + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" + +@implementation GtalkCellTower + +@dynamic hasId_p, id_p; +@dynamic hasKnownCongestionStatus, knownCongestionStatus; + +typedef struct GtalkCellTower__storage_ { + uint32_t _has_storage_[1]; + int32_t knownCongestionStatus; + NSString *id_p; +} GtalkCellTower__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkCellTower_FieldNumber_Id_p, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkCellTower__storage_, id_p), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "knownCongestionStatus", + .dataTypeSpecific.className = NULL, + .number = GtalkCellTower_FieldNumber_KnownCongestionStatus, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkCellTower__storage_, knownCongestionStatus), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkCellTower class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkCellTower__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma clang diagnostic pop + +#pragma mark - GtalkClientEvent + +@implementation GtalkClientEvent + +@dynamic hasType, type; +@dynamic hasNumberDiscardedEvents, numberDiscardedEvents; +@dynamic hasNetworkType, networkType; +@dynamic hasNetworkPort, networkPort; +@dynamic hasTimeConnectionStartedMs, timeConnectionStartedMs; +@dynamic hasTimeConnectionEndedMs, timeConnectionEndedMs; +@dynamic hasErrorCode, errorCode; +@dynamic hasTimeConnectionEstablishedMs, timeConnectionEstablishedMs; +@dynamic hasMcsReconnectAction, mcsReconnectAction; + +typedef struct GtalkClientEvent__storage_ { + uint32_t _has_storage_[1]; + GtalkClientEvent_Type type; + uint32_t numberDiscardedEvents; + int32_t networkType; + int32_t networkPort; + int32_t errorCode; + GtalkClientEvent_McsReconnectAction mcsReconnectAction; + uint64_t timeConnectionStartedMs; + uint64_t timeConnectionEndedMs; + uint64_t timeConnectionEstablishedMs; +} GtalkClientEvent__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "type", + .dataTypeSpecific.enumDescFunc = GtalkClientEvent_Type_EnumDescriptor, + .number = GtalkClientEvent_FieldNumber_Type, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkClientEvent__storage_, type), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "numberDiscardedEvents", + .dataTypeSpecific.className = NULL, + .number = GtalkClientEvent_FieldNumber_NumberDiscardedEvents, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkClientEvent__storage_, numberDiscardedEvents), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeUInt32, + }, + { + .name = "networkType", + .dataTypeSpecific.className = NULL, + .number = GtalkClientEvent_FieldNumber_NetworkType, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkClientEvent__storage_, networkType), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "networkPort", + .dataTypeSpecific.className = NULL, + .number = GtalkClientEvent_FieldNumber_NetworkPort, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkClientEvent__storage_, networkPort), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "timeConnectionStartedMs", + .dataTypeSpecific.className = NULL, + .number = GtalkClientEvent_FieldNumber_TimeConnectionStartedMs, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkClientEvent__storage_, timeConnectionStartedMs), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeUInt64, + }, + { + .name = "timeConnectionEndedMs", + .dataTypeSpecific.className = NULL, + .number = GtalkClientEvent_FieldNumber_TimeConnectionEndedMs, + .hasIndex = 5, + .offset = (uint32_t)offsetof(GtalkClientEvent__storage_, timeConnectionEndedMs), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeUInt64, + }, + { + .name = "errorCode", + .dataTypeSpecific.className = NULL, + .number = GtalkClientEvent_FieldNumber_ErrorCode, + .hasIndex = 6, + .offset = (uint32_t)offsetof(GtalkClientEvent__storage_, errorCode), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "timeConnectionEstablishedMs", + .dataTypeSpecific.className = NULL, + .number = GtalkClientEvent_FieldNumber_TimeConnectionEstablishedMs, + .hasIndex = 7, + .offset = (uint32_t)offsetof(GtalkClientEvent__storage_, timeConnectionEstablishedMs), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeUInt64, + }, + { + .name = "mcsReconnectAction", + .dataTypeSpecific.enumDescFunc = GtalkClientEvent_McsReconnectAction_EnumDescriptor, + .number = GtalkClientEvent_FieldNumber_McsReconnectAction, + .hasIndex = 8, + .offset = (uint32_t)offsetof(GtalkClientEvent__storage_, mcsReconnectAction), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkClientEvent class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkClientEvent__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - Enum GtalkClientEvent_Type + +GPBEnumDescriptor *GtalkClientEvent_Type_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "Unknown\000DiscardedEvents\000FailedConnection" + "\000SuccessfulConnection\000McsReconnectReques" + "t\000FailedSocketCreationMcsReconnect\000McsRe" + "connectLimited\000"; + static const int32_t values[] = { + GtalkClientEvent_Type_Unknown, + GtalkClientEvent_Type_DiscardedEvents, + GtalkClientEvent_Type_FailedConnection, + GtalkClientEvent_Type_SuccessfulConnection, + GtalkClientEvent_Type_McsReconnectRequest, + GtalkClientEvent_Type_FailedSocketCreationMcsReconnect, + GtalkClientEvent_Type_McsReconnectLimited, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkClientEvent_Type) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkClientEvent_Type_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkClientEvent_Type_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkClientEvent_Type_Unknown: + case GtalkClientEvent_Type_DiscardedEvents: + case GtalkClientEvent_Type_FailedConnection: + case GtalkClientEvent_Type_SuccessfulConnection: + case GtalkClientEvent_Type_McsReconnectRequest: + case GtalkClientEvent_Type_FailedSocketCreationMcsReconnect: + case GtalkClientEvent_Type_McsReconnectLimited: + return YES; + default: + return NO; + } +} + +#pragma mark - Enum GtalkClientEvent_McsReconnectAction + +GPBEnumDescriptor *GtalkClientEvent_McsReconnectAction_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "None\000NotConnected\000TooSoon\000"; + static const int32_t values[] = { + GtalkClientEvent_McsReconnectAction_None, + GtalkClientEvent_McsReconnectAction_NotConnected, + GtalkClientEvent_McsReconnectAction_TooSoon, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkClientEvent_McsReconnectAction) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkClientEvent_McsReconnectAction_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkClientEvent_McsReconnectAction_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkClientEvent_McsReconnectAction_None: + case GtalkClientEvent_McsReconnectAction_NotConnected: + case GtalkClientEvent_McsReconnectAction_TooSoon: + return YES; + default: + return NO; + } +} + + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/Protos/GtalkExtensions.pbobjc.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/Protos/GtalkExtensions.pbobjc.h new file mode 100644 index 00000000..f461884a --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/Protos/GtalkExtensions.pbobjc.h @@ -0,0 +1,617 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: buzz/mobile/proto/gtalk_extensions.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30002 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30002 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +@class GtalkOtrItem; +@class GtalkPhoto; +@class GtalkRosterItem; +@class GtalkSharedStatus_StatusList; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - Enum GtalkRosterItem_SubscriptionType + +typedef GPB_ENUM(GtalkRosterItem_SubscriptionType) { + GtalkRosterItem_SubscriptionType_None = 0, + GtalkRosterItem_SubscriptionType_To = 1, + GtalkRosterItem_SubscriptionType_From = 2, + GtalkRosterItem_SubscriptionType_Both = 3, + GtalkRosterItem_SubscriptionType_Remove = 4, +}; + +GPBEnumDescriptor *GtalkRosterItem_SubscriptionType_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkRosterItem_SubscriptionType_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkRosterItem_AskType + +typedef GPB_ENUM(GtalkRosterItem_AskType) { + GtalkRosterItem_AskType_Subscribe = 0, +}; + +GPBEnumDescriptor *GtalkRosterItem_AskType_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkRosterItem_AskType_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkRosterItem_DisplayType + +typedef GPB_ENUM(GtalkRosterItem_DisplayType) { + GtalkRosterItem_DisplayType_Blocked = 0, + GtalkRosterItem_DisplayType_Hidden = 1, + GtalkRosterItem_DisplayType_Pinned = 2, +}; + +GPBEnumDescriptor *GtalkRosterItem_DisplayType_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkRosterItem_DisplayType_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkSharedStatus_ShowType + +typedef GPB_ENUM(GtalkSharedStatus_ShowType) { + GtalkSharedStatus_ShowType_Default = 0, + GtalkSharedStatus_ShowType_Dnd = 1, +}; + +GPBEnumDescriptor *GtalkSharedStatus_ShowType_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkSharedStatus_ShowType_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkPostAuthBatchQuery_CapabilitiesExtFlags + +typedef GPB_ENUM(GtalkPostAuthBatchQuery_CapabilitiesExtFlags) { + GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasVoiceV1 = 1, + GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasVideoV1 = 2, + GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasCameraV1 = 4, + GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasPmucV1 = 8, +}; + +GPBEnumDescriptor *GtalkPostAuthBatchQuery_CapabilitiesExtFlags_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkPostAuthBatchQuery_CapabilitiesExtFlags_IsValidValue(int32_t value); + +#pragma mark - GtalkGtalkExtensionsRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +@interface GtalkGtalkExtensionsRoot : GPBRootObject +@end + +#pragma mark - GtalkRosterQuery + +typedef GPB_ENUM(GtalkRosterQuery_FieldNumber) { + GtalkRosterQuery_FieldNumber_Etag = 1, + GtalkRosterQuery_FieldNumber_NotModified = 2, + GtalkRosterQuery_FieldNumber_ItemArray = 3, + GtalkRosterQuery_FieldNumber_AvatarWidth = 4, + GtalkRosterQuery_FieldNumber_AvatarHeight = 5, +}; + +@interface GtalkRosterQuery : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *etag; +/** Test to see if @c etag has been set. */ +@property(nonatomic, readwrite) BOOL hasEtag; + + +@property(nonatomic, readwrite) BOOL notModified; + +@property(nonatomic, readwrite) BOOL hasNotModified; + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *itemArray; +/** The number of items in @c itemArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger itemArray_Count; + + +@property(nonatomic, readwrite) int32_t avatarWidth; + +@property(nonatomic, readwrite) BOOL hasAvatarWidth; + +@property(nonatomic, readwrite) int32_t avatarHeight; + +@property(nonatomic, readwrite) BOOL hasAvatarHeight; +@end + +#pragma mark - GtalkRosterItem + +typedef GPB_ENUM(GtalkRosterItem_FieldNumber) { + GtalkRosterItem_FieldNumber_Jid = 1, + GtalkRosterItem_FieldNumber_Name = 2, + GtalkRosterItem_FieldNumber_Subscription = 3, + GtalkRosterItem_FieldNumber_Ask = 4, + GtalkRosterItem_FieldNumber_GroupArray = 5, + GtalkRosterItem_FieldNumber_QuickContact = 6, + GtalkRosterItem_FieldNumber_Display = 7, + GtalkRosterItem_FieldNumber_Rejected = 8, +}; + +@interface GtalkRosterItem : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *jid; +/** Test to see if @c jid has been set. */ +@property(nonatomic, readwrite) BOOL hasJid; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *name; +/** Test to see if @c name has been set. */ +@property(nonatomic, readwrite) BOOL hasName; + + +@property(nonatomic, readwrite) GtalkRosterItem_SubscriptionType subscription; + +@property(nonatomic, readwrite) BOOL hasSubscription; + +@property(nonatomic, readwrite) GtalkRosterItem_AskType ask; + +@property(nonatomic, readwrite) BOOL hasAsk; + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *groupArray; +/** The number of items in @c groupArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger groupArray_Count; + + +@property(nonatomic, readwrite) BOOL quickContact; + +@property(nonatomic, readwrite) BOOL hasQuickContact; + +@property(nonatomic, readwrite) GtalkRosterItem_DisplayType display; + +@property(nonatomic, readwrite) BOOL hasDisplay; + +@property(nonatomic, readwrite) BOOL rejected; + +@property(nonatomic, readwrite) BOOL hasRejected; +@end + +#pragma mark - GtalkRmqLastId + +typedef GPB_ENUM(GtalkRmqLastId_FieldNumber) { + GtalkRmqLastId_FieldNumber_Id_p = 1, +}; + +@interface GtalkRmqLastId : GPBMessage + + +@property(nonatomic, readwrite) int64_t id_p; + +@property(nonatomic, readwrite) BOOL hasId_p; +@end + +#pragma mark - GtalkRmqAck + +typedef GPB_ENUM(GtalkRmqAck_FieldNumber) { + GtalkRmqAck_FieldNumber_Id_p = 1, +}; + +@interface GtalkRmqAck : GPBMessage + + +@property(nonatomic, readwrite) int64_t id_p; + +@property(nonatomic, readwrite) BOOL hasId_p; +@end + +#pragma mark - GtalkVCard + +typedef GPB_ENUM(GtalkVCard_FieldNumber) { + GtalkVCard_FieldNumber_Version = 1, + GtalkVCard_FieldNumber_FullName = 2, + GtalkVCard_FieldNumber_Photo = 3, + GtalkVCard_FieldNumber_AvatarHash = 4, + GtalkVCard_FieldNumber_Modified = 5, +}; + +@interface GtalkVCard : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *version; +/** Test to see if @c version has been set. */ +@property(nonatomic, readwrite) BOOL hasVersion; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *fullName; +/** Test to see if @c fullName has been set. */ +@property(nonatomic, readwrite) BOOL hasFullName; + + +@property(nonatomic, readwrite, strong, null_resettable) GtalkPhoto *photo; +/** Test to see if @c photo has been set. */ +@property(nonatomic, readwrite) BOOL hasPhoto; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *avatarHash; +/** Test to see if @c avatarHash has been set. */ +@property(nonatomic, readwrite) BOOL hasAvatarHash; + + +@property(nonatomic, readwrite) BOOL modified; + +@property(nonatomic, readwrite) BOOL hasModified; +@end + +#pragma mark - GtalkPhoto + +typedef GPB_ENUM(GtalkPhoto_FieldNumber) { + GtalkPhoto_FieldNumber_Type = 1, + GtalkPhoto_FieldNumber_Data_p = 2, +}; + +@interface GtalkPhoto : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *type; +/** Test to see if @c type has been set. */ +@property(nonatomic, readwrite) BOOL hasType; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *data_p; +/** Test to see if @c data_p has been set. */ +@property(nonatomic, readwrite) BOOL hasData_p; + +@end + +#pragma mark - GtalkChatRead + +typedef GPB_ENUM(GtalkChatRead_FieldNumber) { + GtalkChatRead_FieldNumber_User = 1, +}; + +@interface GtalkChatRead : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *user; +/** Test to see if @c user has been set. */ +@property(nonatomic, readwrite) BOOL hasUser; + +@end + +#pragma mark - GtalkChatClosed + +typedef GPB_ENUM(GtalkChatClosed_FieldNumber) { + GtalkChatClosed_FieldNumber_User = 1, +}; + +@interface GtalkChatClosed : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *user; +/** Test to see if @c user has been set. */ +@property(nonatomic, readwrite) BOOL hasUser; + +@end + +#pragma mark - GtalkCapabilities + +typedef GPB_ENUM(GtalkCapabilities_FieldNumber) { + GtalkCapabilities_FieldNumber_Node = 1, + GtalkCapabilities_FieldNumber_Ver = 2, + GtalkCapabilities_FieldNumber_Ext = 3, + GtalkCapabilities_FieldNumber_Hash_p = 4, +}; + +@interface GtalkCapabilities : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *node; +/** Test to see if @c node has been set. */ +@property(nonatomic, readwrite) BOOL hasNode; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *ver; +/** Test to see if @c ver has been set. */ +@property(nonatomic, readwrite) BOOL hasVer; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *ext; +/** Test to see if @c ext has been set. */ +@property(nonatomic, readwrite) BOOL hasExt; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *hash_p; +/** Test to see if @c hash_p has been set. */ +@property(nonatomic, readwrite) BOOL hasHash_p; + +@end + +#pragma mark - GtalkSharedStatus + +typedef GPB_ENUM(GtalkSharedStatus_FieldNumber) { + GtalkSharedStatus_FieldNumber_StatusMax = 1, + GtalkSharedStatus_FieldNumber_StatusListMax = 2, + GtalkSharedStatus_FieldNumber_StatusListContentsMax = 3, + GtalkSharedStatus_FieldNumber_Status = 4, + GtalkSharedStatus_FieldNumber_Show = 5, + GtalkSharedStatus_FieldNumber_StatusListArray = 6, + GtalkSharedStatus_FieldNumber_Invisible = 9, + GtalkSharedStatus_FieldNumber_StatusMinVersion = 10, +}; + +@interface GtalkSharedStatus : GPBMessage + + +@property(nonatomic, readwrite) int32_t statusMax; + +@property(nonatomic, readwrite) BOOL hasStatusMax; + +@property(nonatomic, readwrite) int32_t statusListMax; + +@property(nonatomic, readwrite) BOOL hasStatusListMax; + +@property(nonatomic, readwrite) int32_t statusListContentsMax; + +@property(nonatomic, readwrite) BOOL hasStatusListContentsMax; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *status; +/** Test to see if @c status has been set. */ +@property(nonatomic, readwrite) BOOL hasStatus; + + +@property(nonatomic, readwrite) GtalkSharedStatus_ShowType show; + +@property(nonatomic, readwrite) BOOL hasShow; + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *statusListArray; +/** The number of items in @c statusListArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger statusListArray_Count; + + +@property(nonatomic, readwrite) BOOL invisible; + +@property(nonatomic, readwrite) BOOL hasInvisible; + +@property(nonatomic, readwrite) int32_t statusMinVersion; + +@property(nonatomic, readwrite) BOOL hasStatusMinVersion; +@end + +#pragma mark - GtalkSharedStatus_StatusList + +typedef GPB_ENUM(GtalkSharedStatus_StatusList_FieldNumber) { + GtalkSharedStatus_StatusList_FieldNumber_Show = 7, + GtalkSharedStatus_StatusList_FieldNumber_StatusArray = 8, +}; + +@interface GtalkSharedStatus_StatusList : GPBMessage + + +@property(nonatomic, readwrite) GtalkSharedStatus_ShowType show; + +@property(nonatomic, readwrite) BOOL hasShow; + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *statusArray; +/** The number of items in @c statusArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger statusArray_Count; + +@end + +#pragma mark - GtalkOtrQuery + +typedef GPB_ENUM(GtalkOtrQuery_FieldNumber) { + GtalkOtrQuery_FieldNumber_NosaveDefault = 1, + GtalkOtrQuery_FieldNumber_ItemArray = 2, + GtalkOtrQuery_FieldNumber_Etag = 3, + GtalkOtrQuery_FieldNumber_NotModified = 4, +}; + +@interface GtalkOtrQuery : GPBMessage + + +@property(nonatomic, readwrite) BOOL nosaveDefault; + +@property(nonatomic, readwrite) BOOL hasNosaveDefault; + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *itemArray; +/** The number of items in @c itemArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger itemArray_Count; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *etag; +/** Test to see if @c etag has been set. */ +@property(nonatomic, readwrite) BOOL hasEtag; + + +@property(nonatomic, readwrite) BOOL notModified; + +@property(nonatomic, readwrite) BOOL hasNotModified; +@end + +#pragma mark - GtalkOtrItem + +typedef GPB_ENUM(GtalkOtrItem_FieldNumber) { + GtalkOtrItem_FieldNumber_Jid = 1, + GtalkOtrItem_FieldNumber_Nosave = 2, + GtalkOtrItem_FieldNumber_ChangedByBuddy = 3, +}; + +@interface GtalkOtrItem : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *jid; +/** Test to see if @c jid has been set. */ +@property(nonatomic, readwrite) BOOL hasJid; + + +@property(nonatomic, readwrite) BOOL nosave; + +@property(nonatomic, readwrite) BOOL hasNosave; + +@property(nonatomic, readwrite) BOOL changedByBuddy; + +@property(nonatomic, readwrite) BOOL hasChangedByBuddy; +@end + +#pragma mark - GtalkIdle + +typedef GPB_ENUM(GtalkIdle_FieldNumber) { + GtalkIdle_FieldNumber_Idle = 1, + GtalkIdle_FieldNumber_Away = 2, +}; + +@interface GtalkIdle : GPBMessage + + +@property(nonatomic, readwrite) BOOL idle; + +@property(nonatomic, readwrite) BOOL hasIdle; + +@property(nonatomic, readwrite) BOOL away; + +@property(nonatomic, readwrite) BOOL hasAway; +@end + +#pragma mark - GtalkPostAuthBatchQuery + +typedef GPB_ENUM(GtalkPostAuthBatchQuery_FieldNumber) { + GtalkPostAuthBatchQuery_FieldNumber_Available = 1, + GtalkPostAuthBatchQuery_FieldNumber_DeviceIdle = 2, + GtalkPostAuthBatchQuery_FieldNumber_MobileIndicator = 3, + GtalkPostAuthBatchQuery_FieldNumber_SharedStatusVersion = 4, + GtalkPostAuthBatchQuery_FieldNumber_RosterEtag = 5, + GtalkPostAuthBatchQuery_FieldNumber_OtrEtag = 6, + GtalkPostAuthBatchQuery_FieldNumber_AvatarHash = 7, + GtalkPostAuthBatchQuery_FieldNumber_VcardQueryStanzaId = 8, + GtalkPostAuthBatchQuery_FieldNumber_CapabilitiesExtFlags = 9, +}; + +@interface GtalkPostAuthBatchQuery : GPBMessage + + +@property(nonatomic, readwrite) BOOL available; + +@property(nonatomic, readwrite) BOOL hasAvailable; + +@property(nonatomic, readwrite) BOOL deviceIdle; + +@property(nonatomic, readwrite) BOOL hasDeviceIdle; + +@property(nonatomic, readwrite) BOOL mobileIndicator; + +@property(nonatomic, readwrite) BOOL hasMobileIndicator; + +@property(nonatomic, readwrite) int32_t sharedStatusVersion; + +@property(nonatomic, readwrite) BOOL hasSharedStatusVersion; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *rosterEtag; +/** Test to see if @c rosterEtag has been set. */ +@property(nonatomic, readwrite) BOOL hasRosterEtag; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *otrEtag; +/** Test to see if @c otrEtag has been set. */ +@property(nonatomic, readwrite) BOOL hasOtrEtag; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *avatarHash; +/** Test to see if @c avatarHash has been set. */ +@property(nonatomic, readwrite) BOOL hasAvatarHash; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *vcardQueryStanzaId; +/** Test to see if @c vcardQueryStanzaId has been set. */ +@property(nonatomic, readwrite) BOOL hasVcardQueryStanzaId; + + +@property(nonatomic, readwrite) int32_t capabilitiesExtFlags; + +@property(nonatomic, readwrite) BOOL hasCapabilitiesExtFlags; +@end + +#pragma mark - GtalkStreamAck + +@interface GtalkStreamAck : GPBMessage + +@end + +#pragma mark - GtalkSelectiveAck + +typedef GPB_ENUM(GtalkSelectiveAck_FieldNumber) { + GtalkSelectiveAck_FieldNumber_IdArray = 1, +}; + +@interface GtalkSelectiveAck : GPBMessage + + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *idArray; +/** The number of items in @c idArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger idArray_Count; + +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/Protos/GtalkExtensions.pbobjc.m b/ios/Pods/FirebaseMessaging/Firebase/Messaging/Protos/GtalkExtensions.pbobjc.m new file mode 100644 index 00000000..e41d4163 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/Protos/GtalkExtensions.pbobjc.m @@ -0,0 +1,1407 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: buzz/mobile/proto/gtalk_extensions.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + + #import "GtalkExtensions.pbobjc.h" +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +#pragma mark - GtalkGtalkExtensionsRoot + +@implementation GtalkGtalkExtensionsRoot + +// No extensions in the file and no imports, so no need to generate +// +extensionRegistry. + +@end + +#pragma mark - GtalkGtalkExtensionsRoot_FileDescriptor + +static GPBFileDescriptor *GtalkGtalkExtensionsRoot_FileDescriptor(void) { + // This is called by +initialize so there is no need to worry + // about thread safety of the singleton. + static GPBFileDescriptor *descriptor = NULL; + if (!descriptor) { + GPB_DEBUG_CHECK_RUNTIME_VERSIONS(); + descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"mobilegtalk" + objcPrefix:@"Gtalk" + syntax:GPBFileSyntaxProto2]; + } + return descriptor; +} + +#pragma mark - GtalkRosterQuery + +@implementation GtalkRosterQuery + +@dynamic hasEtag, etag; +@dynamic hasNotModified, notModified; +@dynamic itemArray, itemArray_Count; +@dynamic hasAvatarWidth, avatarWidth; +@dynamic hasAvatarHeight, avatarHeight; + +typedef struct GtalkRosterQuery__storage_ { + uint32_t _has_storage_[1]; + int32_t avatarWidth; + int32_t avatarHeight; + NSString *etag; + NSMutableArray *itemArray; +} GtalkRosterQuery__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "etag", + .dataTypeSpecific.className = NULL, + .number = GtalkRosterQuery_FieldNumber_Etag, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkRosterQuery__storage_, etag), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "notModified", + .dataTypeSpecific.className = NULL, + .number = GtalkRosterQuery_FieldNumber_NotModified, + .hasIndex = 1, + .offset = 2, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "itemArray", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkRosterItem), + .number = GtalkRosterQuery_FieldNumber_ItemArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkRosterQuery__storage_, itemArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "avatarWidth", + .dataTypeSpecific.className = NULL, + .number = GtalkRosterQuery_FieldNumber_AvatarWidth, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkRosterQuery__storage_, avatarWidth), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldTextFormatNameCustom), + .dataType = GPBDataTypeInt32, + }, + { + .name = "avatarHeight", + .dataTypeSpecific.className = NULL, + .number = GtalkRosterQuery_FieldNumber_AvatarHeight, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkRosterQuery__storage_, avatarHeight), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldTextFormatNameCustom), + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkRosterQuery class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkRosterQuery__storage_) + flags:GPBDescriptorInitializationFlag_None]; +#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS + static const char *extraTextFormatInfo = + "\002\004\013\000\005\014\000"; + [localDescriptor setupExtraTextInfo:extraTextFormatInfo]; +#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkRosterItem + +@implementation GtalkRosterItem + +@dynamic hasJid, jid; +@dynamic hasName, name; +@dynamic hasSubscription, subscription; +@dynamic hasAsk, ask; +@dynamic groupArray, groupArray_Count; +@dynamic hasQuickContact, quickContact; +@dynamic hasDisplay, display; +@dynamic hasRejected, rejected; + +typedef struct GtalkRosterItem__storage_ { + uint32_t _has_storage_[1]; + GtalkRosterItem_SubscriptionType subscription; + GtalkRosterItem_AskType ask; + GtalkRosterItem_DisplayType display; + NSString *jid; + NSString *name; + NSMutableArray *groupArray; +} GtalkRosterItem__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "jid", + .dataTypeSpecific.className = NULL, + .number = GtalkRosterItem_FieldNumber_Jid, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkRosterItem__storage_, jid), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "name", + .dataTypeSpecific.className = NULL, + .number = GtalkRosterItem_FieldNumber_Name, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkRosterItem__storage_, name), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "subscription", + .dataTypeSpecific.enumDescFunc = GtalkRosterItem_SubscriptionType_EnumDescriptor, + .number = GtalkRosterItem_FieldNumber_Subscription, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkRosterItem__storage_, subscription), + .flags = (GPBFieldFlags)(GPBFieldRequired | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "ask", + .dataTypeSpecific.enumDescFunc = GtalkRosterItem_AskType_EnumDescriptor, + .number = GtalkRosterItem_FieldNumber_Ask, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkRosterItem__storage_, ask), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "groupArray", + .dataTypeSpecific.className = NULL, + .number = GtalkRosterItem_FieldNumber_GroupArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkRosterItem__storage_, groupArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeString, + }, + { + .name = "quickContact", + .dataTypeSpecific.className = NULL, + .number = GtalkRosterItem_FieldNumber_QuickContact, + .hasIndex = 4, + .offset = 5, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "display", + .dataTypeSpecific.enumDescFunc = GtalkRosterItem_DisplayType_EnumDescriptor, + .number = GtalkRosterItem_FieldNumber_Display, + .hasIndex = 6, + .offset = (uint32_t)offsetof(GtalkRosterItem__storage_, display), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "rejected", + .dataTypeSpecific.className = NULL, + .number = GtalkRosterItem_FieldNumber_Rejected, + .hasIndex = 7, + .offset = 8, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkRosterItem class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkRosterItem__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - Enum GtalkRosterItem_SubscriptionType + +GPBEnumDescriptor *GtalkRosterItem_SubscriptionType_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "None\000To\000From\000Both\000Remove\000"; + static const int32_t values[] = { + GtalkRosterItem_SubscriptionType_None, + GtalkRosterItem_SubscriptionType_To, + GtalkRosterItem_SubscriptionType_From, + GtalkRosterItem_SubscriptionType_Both, + GtalkRosterItem_SubscriptionType_Remove, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkRosterItem_SubscriptionType) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkRosterItem_SubscriptionType_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkRosterItem_SubscriptionType_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkRosterItem_SubscriptionType_None: + case GtalkRosterItem_SubscriptionType_To: + case GtalkRosterItem_SubscriptionType_From: + case GtalkRosterItem_SubscriptionType_Both: + case GtalkRosterItem_SubscriptionType_Remove: + return YES; + default: + return NO; + } +} + +#pragma mark - Enum GtalkRosterItem_AskType + +GPBEnumDescriptor *GtalkRosterItem_AskType_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "Subscribe\000"; + static const int32_t values[] = { + GtalkRosterItem_AskType_Subscribe, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkRosterItem_AskType) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkRosterItem_AskType_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkRosterItem_AskType_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkRosterItem_AskType_Subscribe: + return YES; + default: + return NO; + } +} + +#pragma mark - Enum GtalkRosterItem_DisplayType + +GPBEnumDescriptor *GtalkRosterItem_DisplayType_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "Blocked\000Hidden\000Pinned\000"; + static const int32_t values[] = { + GtalkRosterItem_DisplayType_Blocked, + GtalkRosterItem_DisplayType_Hidden, + GtalkRosterItem_DisplayType_Pinned, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkRosterItem_DisplayType) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkRosterItem_DisplayType_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkRosterItem_DisplayType_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkRosterItem_DisplayType_Blocked: + case GtalkRosterItem_DisplayType_Hidden: + case GtalkRosterItem_DisplayType_Pinned: + return YES; + default: + return NO; + } +} + +#pragma mark - GtalkRmqLastId + +@implementation GtalkRmqLastId + +@dynamic hasId_p, id_p; + +typedef struct GtalkRmqLastId__storage_ { + uint32_t _has_storage_[1]; + int64_t id_p; +} GtalkRmqLastId__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkRmqLastId_FieldNumber_Id_p, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkRmqLastId__storage_, id_p), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeInt64, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkRmqLastId class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkRmqLastId__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkRmqAck + +@implementation GtalkRmqAck + +@dynamic hasId_p, id_p; + +typedef struct GtalkRmqAck__storage_ { + uint32_t _has_storage_[1]; + int64_t id_p; +} GtalkRmqAck__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkRmqAck_FieldNumber_Id_p, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkRmqAck__storage_, id_p), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeInt64, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkRmqAck class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkRmqAck__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkVCard + +@implementation GtalkVCard + +@dynamic hasVersion, version; +@dynamic hasFullName, fullName; +@dynamic hasPhoto, photo; +@dynamic hasAvatarHash, avatarHash; +@dynamic hasModified, modified; + +typedef struct GtalkVCard__storage_ { + uint32_t _has_storage_[1]; + NSString *version; + NSString *fullName; + GtalkPhoto *photo; + NSString *avatarHash; +} GtalkVCard__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "version", + .dataTypeSpecific.className = NULL, + .number = GtalkVCard_FieldNumber_Version, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkVCard__storage_, version), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "fullName", + .dataTypeSpecific.className = NULL, + .number = GtalkVCard_FieldNumber_FullName, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkVCard__storage_, fullName), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "photo", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkPhoto), + .number = GtalkVCard_FieldNumber_Photo, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkVCard__storage_, photo), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "avatarHash", + .dataTypeSpecific.className = NULL, + .number = GtalkVCard_FieldNumber_AvatarHash, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkVCard__storage_, avatarHash), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "modified", + .dataTypeSpecific.className = NULL, + .number = GtalkVCard_FieldNumber_Modified, + .hasIndex = 4, + .offset = 5, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkVCard class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkVCard__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkPhoto + +@implementation GtalkPhoto + +@dynamic hasType, type; +@dynamic hasData_p, data_p; + +typedef struct GtalkPhoto__storage_ { + uint32_t _has_storage_[1]; + NSString *type; + NSString *data_p; +} GtalkPhoto__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "type", + .dataTypeSpecific.className = NULL, + .number = GtalkPhoto_FieldNumber_Type, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkPhoto__storage_, type), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "data_p", + .dataTypeSpecific.className = NULL, + .number = GtalkPhoto_FieldNumber_Data_p, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkPhoto__storage_, data_p), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkPhoto class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkPhoto__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkChatRead + +@implementation GtalkChatRead + +@dynamic hasUser, user; + +typedef struct GtalkChatRead__storage_ { + uint32_t _has_storage_[1]; + NSString *user; +} GtalkChatRead__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "user", + .dataTypeSpecific.className = NULL, + .number = GtalkChatRead_FieldNumber_User, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkChatRead__storage_, user), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkChatRead class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkChatRead__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkChatClosed + +@implementation GtalkChatClosed + +@dynamic hasUser, user; + +typedef struct GtalkChatClosed__storage_ { + uint32_t _has_storage_[1]; + NSString *user; +} GtalkChatClosed__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "user", + .dataTypeSpecific.className = NULL, + .number = GtalkChatClosed_FieldNumber_User, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkChatClosed__storage_, user), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkChatClosed class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkChatClosed__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkCapabilities + +@implementation GtalkCapabilities + +@dynamic hasNode, node; +@dynamic hasVer, ver; +@dynamic hasExt, ext; +@dynamic hasHash_p, hash_p; + +typedef struct GtalkCapabilities__storage_ { + uint32_t _has_storage_[1]; + NSString *node; + NSString *ver; + NSString *ext; + NSString *hash_p; +} GtalkCapabilities__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "node", + .dataTypeSpecific.className = NULL, + .number = GtalkCapabilities_FieldNumber_Node, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkCapabilities__storage_, node), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "ver", + .dataTypeSpecific.className = NULL, + .number = GtalkCapabilities_FieldNumber_Ver, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkCapabilities__storage_, ver), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "ext", + .dataTypeSpecific.className = NULL, + .number = GtalkCapabilities_FieldNumber_Ext, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkCapabilities__storage_, ext), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "hash_p", + .dataTypeSpecific.className = NULL, + .number = GtalkCapabilities_FieldNumber_Hash_p, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkCapabilities__storage_, hash_p), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkCapabilities class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkCapabilities__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkSharedStatus + +@implementation GtalkSharedStatus + +@dynamic hasStatusMax, statusMax; +@dynamic hasStatusListMax, statusListMax; +@dynamic hasStatusListContentsMax, statusListContentsMax; +@dynamic hasStatus, status; +@dynamic hasShow, show; +@dynamic statusListArray, statusListArray_Count; +@dynamic hasInvisible, invisible; +@dynamic hasStatusMinVersion, statusMinVersion; + +typedef struct GtalkSharedStatus__storage_ { + uint32_t _has_storage_[1]; + int32_t statusMax; + int32_t statusListMax; + int32_t statusListContentsMax; + GtalkSharedStatus_ShowType show; + int32_t statusMinVersion; + NSString *status; + NSMutableArray *statusListArray; +} GtalkSharedStatus__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "statusMax", + .dataTypeSpecific.className = NULL, + .number = GtalkSharedStatus_FieldNumber_StatusMax, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkSharedStatus__storage_, statusMax), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "statusListMax", + .dataTypeSpecific.className = NULL, + .number = GtalkSharedStatus_FieldNumber_StatusListMax, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkSharedStatus__storage_, statusListMax), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "statusListContentsMax", + .dataTypeSpecific.className = NULL, + .number = GtalkSharedStatus_FieldNumber_StatusListContentsMax, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkSharedStatus__storage_, statusListContentsMax), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "status", + .dataTypeSpecific.className = NULL, + .number = GtalkSharedStatus_FieldNumber_Status, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkSharedStatus__storage_, status), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "show", + .dataTypeSpecific.enumDescFunc = GtalkSharedStatus_ShowType_EnumDescriptor, + .number = GtalkSharedStatus_FieldNumber_Show, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkSharedStatus__storage_, show), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "statusListArray", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkSharedStatus_StatusList), + .number = GtalkSharedStatus_FieldNumber_StatusListArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkSharedStatus__storage_, statusListArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeGroup, + }, + { + .name = "invisible", + .dataTypeSpecific.className = NULL, + .number = GtalkSharedStatus_FieldNumber_Invisible, + .hasIndex = 5, + .offset = 6, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "statusMinVersion", + .dataTypeSpecific.className = NULL, + .number = GtalkSharedStatus_FieldNumber_StatusMinVersion, + .hasIndex = 7, + .offset = (uint32_t)offsetof(GtalkSharedStatus__storage_, statusMinVersion), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkSharedStatus class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkSharedStatus__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - Enum GtalkSharedStatus_ShowType + +GPBEnumDescriptor *GtalkSharedStatus_ShowType_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "Default\000Dnd\000"; + static const int32_t values[] = { + GtalkSharedStatus_ShowType_Default, + GtalkSharedStatus_ShowType_Dnd, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkSharedStatus_ShowType) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkSharedStatus_ShowType_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkSharedStatus_ShowType_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkSharedStatus_ShowType_Default: + case GtalkSharedStatus_ShowType_Dnd: + return YES; + default: + return NO; + } +} + +#pragma mark - GtalkSharedStatus_StatusList + +@implementation GtalkSharedStatus_StatusList + +@dynamic hasShow, show; +@dynamic statusArray, statusArray_Count; + +typedef struct GtalkSharedStatus_StatusList__storage_ { + uint32_t _has_storage_[1]; + GtalkSharedStatus_ShowType show; + NSMutableArray *statusArray; +} GtalkSharedStatus_StatusList__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "show", + .dataTypeSpecific.enumDescFunc = GtalkSharedStatus_ShowType_EnumDescriptor, + .number = GtalkSharedStatus_StatusList_FieldNumber_Show, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkSharedStatus_StatusList__storage_, show), + .flags = (GPBFieldFlags)(GPBFieldRequired | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "statusArray", + .dataTypeSpecific.className = NULL, + .number = GtalkSharedStatus_StatusList_FieldNumber_StatusArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkSharedStatus_StatusList__storage_, statusArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkSharedStatus_StatusList class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkSharedStatus_StatusList__storage_) + flags:GPBDescriptorInitializationFlag_None]; + [localDescriptor setupContainingMessageClassName:GPBStringifySymbol(GtalkSharedStatus)]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkOtrQuery + +@implementation GtalkOtrQuery + +@dynamic hasNosaveDefault, nosaveDefault; +@dynamic itemArray, itemArray_Count; +@dynamic hasEtag, etag; +@dynamic hasNotModified, notModified; + +typedef struct GtalkOtrQuery__storage_ { + uint32_t _has_storage_[1]; + NSMutableArray *itemArray; + NSString *etag; +} GtalkOtrQuery__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "nosaveDefault", + .dataTypeSpecific.className = NULL, + .number = GtalkOtrQuery_FieldNumber_NosaveDefault, + .hasIndex = 0, + .offset = 1, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "itemArray", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkOtrItem), + .number = GtalkOtrQuery_FieldNumber_ItemArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkOtrQuery__storage_, itemArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "etag", + .dataTypeSpecific.className = NULL, + .number = GtalkOtrQuery_FieldNumber_Etag, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkOtrQuery__storage_, etag), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "notModified", + .dataTypeSpecific.className = NULL, + .number = GtalkOtrQuery_FieldNumber_NotModified, + .hasIndex = 3, + .offset = 4, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkOtrQuery class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkOtrQuery__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkOtrItem + +@implementation GtalkOtrItem + +@dynamic hasJid, jid; +@dynamic hasNosave, nosave; +@dynamic hasChangedByBuddy, changedByBuddy; + +typedef struct GtalkOtrItem__storage_ { + uint32_t _has_storage_[1]; + NSString *jid; +} GtalkOtrItem__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "jid", + .dataTypeSpecific.className = NULL, + .number = GtalkOtrItem_FieldNumber_Jid, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkOtrItem__storage_, jid), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "nosave", + .dataTypeSpecific.className = NULL, + .number = GtalkOtrItem_FieldNumber_Nosave, + .hasIndex = 1, + .offset = 2, // Stored in _has_storage_ to save space. + .flags = GPBFieldRequired, + .dataType = GPBDataTypeBool, + }, + { + .name = "changedByBuddy", + .dataTypeSpecific.className = NULL, + .number = GtalkOtrItem_FieldNumber_ChangedByBuddy, + .hasIndex = 3, + .offset = 4, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkOtrItem class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkOtrItem__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkIdle + +@implementation GtalkIdle + +@dynamic hasIdle, idle; +@dynamic hasAway, away; + +typedef struct GtalkIdle__storage_ { + uint32_t _has_storage_[1]; +} GtalkIdle__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "idle", + .dataTypeSpecific.className = NULL, + .number = GtalkIdle_FieldNumber_Idle, + .hasIndex = 0, + .offset = 1, // Stored in _has_storage_ to save space. + .flags = GPBFieldRequired, + .dataType = GPBDataTypeBool, + }, + { + .name = "away", + .dataTypeSpecific.className = NULL, + .number = GtalkIdle_FieldNumber_Away, + .hasIndex = 2, + .offset = 3, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkIdle class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkIdle__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkPostAuthBatchQuery + +@implementation GtalkPostAuthBatchQuery + +@dynamic hasAvailable, available; +@dynamic hasDeviceIdle, deviceIdle; +@dynamic hasMobileIndicator, mobileIndicator; +@dynamic hasSharedStatusVersion, sharedStatusVersion; +@dynamic hasRosterEtag, rosterEtag; +@dynamic hasOtrEtag, otrEtag; +@dynamic hasAvatarHash, avatarHash; +@dynamic hasVcardQueryStanzaId, vcardQueryStanzaId; +@dynamic hasCapabilitiesExtFlags, capabilitiesExtFlags; + +typedef struct GtalkPostAuthBatchQuery__storage_ { + uint32_t _has_storage_[1]; + int32_t sharedStatusVersion; + int32_t capabilitiesExtFlags; + NSString *rosterEtag; + NSString *otrEtag; + NSString *avatarHash; + NSString *vcardQueryStanzaId; +} GtalkPostAuthBatchQuery__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "available", + .dataTypeSpecific.className = NULL, + .number = GtalkPostAuthBatchQuery_FieldNumber_Available, + .hasIndex = 0, + .offset = 1, // Stored in _has_storage_ to save space. + .flags = GPBFieldRequired, + .dataType = GPBDataTypeBool, + }, + { + .name = "deviceIdle", + .dataTypeSpecific.className = NULL, + .number = GtalkPostAuthBatchQuery_FieldNumber_DeviceIdle, + .hasIndex = 2, + .offset = 3, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "mobileIndicator", + .dataTypeSpecific.className = NULL, + .number = GtalkPostAuthBatchQuery_FieldNumber_MobileIndicator, + .hasIndex = 4, + .offset = 5, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "sharedStatusVersion", + .dataTypeSpecific.className = NULL, + .number = GtalkPostAuthBatchQuery_FieldNumber_SharedStatusVersion, + .hasIndex = 6, + .offset = (uint32_t)offsetof(GtalkPostAuthBatchQuery__storage_, sharedStatusVersion), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "rosterEtag", + .dataTypeSpecific.className = NULL, + .number = GtalkPostAuthBatchQuery_FieldNumber_RosterEtag, + .hasIndex = 7, + .offset = (uint32_t)offsetof(GtalkPostAuthBatchQuery__storage_, rosterEtag), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "otrEtag", + .dataTypeSpecific.className = NULL, + .number = GtalkPostAuthBatchQuery_FieldNumber_OtrEtag, + .hasIndex = 8, + .offset = (uint32_t)offsetof(GtalkPostAuthBatchQuery__storage_, otrEtag), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "avatarHash", + .dataTypeSpecific.className = NULL, + .number = GtalkPostAuthBatchQuery_FieldNumber_AvatarHash, + .hasIndex = 9, + .offset = (uint32_t)offsetof(GtalkPostAuthBatchQuery__storage_, avatarHash), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "vcardQueryStanzaId", + .dataTypeSpecific.className = NULL, + .number = GtalkPostAuthBatchQuery_FieldNumber_VcardQueryStanzaId, + .hasIndex = 10, + .offset = (uint32_t)offsetof(GtalkPostAuthBatchQuery__storage_, vcardQueryStanzaId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "capabilitiesExtFlags", + .dataTypeSpecific.className = NULL, + .number = GtalkPostAuthBatchQuery_FieldNumber_CapabilitiesExtFlags, + .hasIndex = 11, + .offset = (uint32_t)offsetof(GtalkPostAuthBatchQuery__storage_, capabilitiesExtFlags), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkPostAuthBatchQuery class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkPostAuthBatchQuery__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - Enum GtalkPostAuthBatchQuery_CapabilitiesExtFlags + +GPBEnumDescriptor *GtalkPostAuthBatchQuery_CapabilitiesExtFlags_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "HasVoiceV1\000HasVideoV1\000HasCameraV1\000HasPmu" + "cV1\000"; + static const int32_t values[] = { + GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasVoiceV1, + GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasVideoV1, + GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasCameraV1, + GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasPmucV1, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkPostAuthBatchQuery_CapabilitiesExtFlags) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkPostAuthBatchQuery_CapabilitiesExtFlags_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkPostAuthBatchQuery_CapabilitiesExtFlags_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasVoiceV1: + case GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasVideoV1: + case GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasCameraV1: + case GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasPmucV1: + return YES; + default: + return NO; + } +} + +#pragma mark - GtalkStreamAck + +@implementation GtalkStreamAck + + +typedef struct GtalkStreamAck__storage_ { + uint32_t _has_storage_[1]; +} GtalkStreamAck__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkStreamAck class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:NULL + fieldCount:0 + storageSize:sizeof(GtalkStreamAck__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkSelectiveAck + +@implementation GtalkSelectiveAck + +@dynamic idArray, idArray_Count; + +typedef struct GtalkSelectiveAck__storage_ { + uint32_t _has_storage_[1]; + NSMutableArray *idArray; +} GtalkSelectiveAck__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "idArray", + .dataTypeSpecific.className = NULL, + .number = GtalkSelectiveAck_FieldNumber_IdArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkSelectiveAck__storage_, idArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkSelectiveAck class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkSelectiveAck__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/Public/FIRMessaging.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/Public/FIRMessaging.h new file mode 100644 index 00000000..d0ccfacf --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/Public/FIRMessaging.h @@ -0,0 +1,552 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * @related FIRMessaging + * + * The completion handler invoked when the registration token returns. + * If the call fails we return the appropriate `error code`, described by + * `FIRMessagingError`. + * + * @param FCMToken The valid registration token returned by FCM. + * @param error The error describing why a token request failed. The error code + * will match a value from the FIRMessagingError enumeration. + */ +typedef void(^FIRMessagingFCMTokenFetchCompletion)(NSString * _Nullable FCMToken, + NSError * _Nullable error) + NS_SWIFT_NAME(MessagingFCMTokenFetchCompletion); + + +/** + * @related FIRMessaging + * + * The completion handler invoked when the registration token deletion request is + * completed. If the call fails we return the appropriate `error code`, described + * by `FIRMessagingError`. + * + * @param error The error describing why a token deletion failed. The error code + * will match a value from the FIRMessagingError enumeration. + */ +typedef void(^FIRMessagingDeleteFCMTokenCompletion)(NSError * _Nullable error) + NS_SWIFT_NAME(MessagingDeleteFCMTokenCompletion); + +/** + * Callback to invoke once the HTTP call to FIRMessaging backend for updating + * subscription finishes. + * + * @param error The error which occurred while updating the subscription topic + * on the FIRMessaging server. This will be nil in case the operation + * was successful, or if the operation was cancelled. + */ +typedef void (^FIRMessagingTopicOperationCompletion)(NSError *_Nullable error); + +/** + * The completion handler invoked once the data connection with FIRMessaging is + * established. The data connection is used to send a continuous stream of + * data and all the FIRMessaging data notifications arrive through this connection. + * Once the connection is established we invoke the callback with `nil` error. + * Correspondingly if we get an error while trying to establish a connection + * we invoke the handler with an appropriate error object and do an + * exponential backoff to try and connect again unless successful. + * + * @param error The error object if any describing why the data connection + * to FIRMessaging failed. + */ +typedef void(^FIRMessagingConnectCompletion)(NSError * __nullable error) + NS_SWIFT_NAME(MessagingConnectCompletion) + __deprecated_msg("Please listen for the FIRMessagingConnectionStateChangedNotification " + "NSNotification instead."); + +#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 +/** + * Notification sent when the upstream message has been delivered + * successfully to the server. The notification object will be the messageID + * of the successfully delivered message. + */ +FOUNDATION_EXPORT const NSNotificationName FIRMessagingSendSuccessNotification + NS_SWIFT_NAME(MessagingSendSuccess); + +/** + * Notification sent when the upstream message was failed to be sent to the + * server. The notification object will be the messageID of the failed + * message. The userInfo dictionary will contain the relevant error + * information for the failure. + */ +FOUNDATION_EXPORT const NSNotificationName FIRMessagingSendErrorNotification + NS_SWIFT_NAME(MessagingSendError); + +/** + * Notification sent when the Firebase messaging server deletes pending + * messages due to exceeded storage limits. This may occur, for example, when + * the device cannot be reached for an extended period of time. + * + * It is recommended to retrieve any missing messages directly from the + * server. + */ +FOUNDATION_EXPORT const NSNotificationName FIRMessagingMessagesDeletedNotification + NS_SWIFT_NAME(MessagingMessagesDeleted); + +/** + * Notification sent when Firebase Messaging establishes or disconnects from + * an FCM socket connection. You can query the connection state in this + * notification by checking the `isDirectChannelEstablished` property of FIRMessaging. + */ +FOUNDATION_EXPORT const NSNotificationName FIRMessagingConnectionStateChangedNotification + NS_SWIFT_NAME(MessagingConnectionStateChanged); + +/** + * Notification sent when the FCM registration token has been refreshed. Please use the + * FIRMessaging delegate method `messaging:didReceiveRegistrationToken:` to receive current and + * updated tokens. + */ +FOUNDATION_EXPORT const NSNotificationName + FIRMessagingRegistrationTokenRefreshedNotification + NS_SWIFT_NAME(MessagingRegistrationTokenRefreshed); +#else +/** + * Notification sent when the upstream message has been delivered + * successfully to the server. The notification object will be the messageID + * of the successfully delivered message. + */ +FOUNDATION_EXPORT NSString *const FIRMessagingSendSuccessNotification + NS_SWIFT_NAME(MessagingSendSuccessNotification); + +/** + * Notification sent when the upstream message was failed to be sent to the + * server. The notification object will be the messageID of the failed + * message. The userInfo dictionary will contain the relevant error + * information for the failure. + */ +FOUNDATION_EXPORT NSString *const FIRMessagingSendErrorNotification + NS_SWIFT_NAME(MessagingSendErrorNotification); + +/** + * Notification sent when the Firebase messaging server deletes pending + * messages due to exceeded storage limits. This may occur, for example, when + * the device cannot be reached for an extended period of time. + * + * It is recommended to retrieve any missing messages directly from the + * server. + */ +FOUNDATION_EXPORT NSString *const FIRMessagingMessagesDeletedNotification + NS_SWIFT_NAME(MessagingMessagesDeletedNotification); + +/** + * Notification sent when Firebase Messaging establishes or disconnects from + * an FCM socket connection. You can query the connection state in this + * notification by checking the `isDirectChannelEstablished` property of FIRMessaging. + */ +FOUNDATION_EXPORT NSString *const FIRMessagingConnectionStateChangedNotification + NS_SWIFT_NAME(MessagingConnectionStateChangedNotification); + +/** + * Notification sent when the FCM registration token has been refreshed. Please use the + * FIRMessaging delegate method `messaging:didReceiveRegistrationToken:` to receive current and + * updated tokens. + */ +FOUNDATION_EXPORT NSString *const FIRMessagingRegistrationTokenRefreshedNotification + NS_SWIFT_NAME(MessagingRegistrationTokenRefreshedNotification); +#endif // defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 + +/** + * @enum FIRMessagingError + */ +typedef NS_ENUM(NSUInteger, FIRMessagingError) { + /// Unknown error. + FIRMessagingErrorUnknown = 0, + + /// FIRMessaging couldn't validate request from this client. + FIRMessagingErrorAuthentication = 1, + + /// InstanceID service cannot be accessed. + FIRMessagingErrorNoAccess = 2, + + /// Request to InstanceID backend timed out. + FIRMessagingErrorTimeout = 3, + + /// No network available to reach the servers. + FIRMessagingErrorNetwork = 4, + + /// Another similar operation in progress, bailing this one. + FIRMessagingErrorOperationInProgress = 5, + + /// Some parameters of the request were invalid. + FIRMessagingErrorInvalidRequest = 7, + + /// Topic name is invalid for subscription/unsubscription. + FIRMessagingErrorInvalidTopicName = 8, + +} NS_SWIFT_NAME(MessagingError); + +/// Status for the downstream message received by the app. +typedef NS_ENUM(NSInteger, FIRMessagingMessageStatus) { + /// Unknown status. + FIRMessagingMessageStatusUnknown, + /// New downstream message received by the app. + FIRMessagingMessageStatusNew, +} NS_SWIFT_NAME(MessagingMessageStatus); + +/** + * The APNS token type for the app. If the token type is set to `UNKNOWN` + * Firebase Messaging will implicitly try to figure out what the actual token type + * is from the provisioning profile. + * Unless you really need to specify the type, you should use the `APNSToken` + * property instead. + */ +typedef NS_ENUM(NSInteger, FIRMessagingAPNSTokenType) { + /// Unknown token type. + FIRMessagingAPNSTokenTypeUnknown, + /// Sandbox token type. + FIRMessagingAPNSTokenTypeSandbox, + /// Production token type. + FIRMessagingAPNSTokenTypeProd, +} NS_SWIFT_NAME(MessagingAPNSTokenType); + +/// Information about a downstream message received by the app. +NS_SWIFT_NAME(MessagingMessageInfo) +@interface FIRMessagingMessageInfo : NSObject + +/// The status of the downstream message +@property(nonatomic, readonly, assign) FIRMessagingMessageStatus status; + +@end + +/** + * A remote data message received by the app via FCM (not just the APNs interface). + * + * This is only for devices running iOS 10 or above. To support devices running iOS 9 or below, use + * the local and remote notifications handlers defined in UIApplicationDelegate protocol. + */ +NS_SWIFT_NAME(MessagingRemoteMessage) +@interface FIRMessagingRemoteMessage : NSObject + +/// The message ID of downstream message. +@property(nonatomic, readonly, copy) NSString *messageID; +/// The downstream message received by the application. +@property(nonatomic, readonly, strong) NSDictionary *appData; + +@end + +@class FIRMessaging; +/** + * A protocol to handle token update or data message delivery from FCM. + * + */ +NS_SWIFT_NAME(MessagingDelegate) +@protocol FIRMessagingDelegate + +@optional +/// This method will be called once a token is available, or has been refreshed. Typically it +/// will be called once per app start, but may be called more often, if token is invalidated or +/// updated. In this method, you should perform operations such as: +/// +/// * Uploading the FCM token to your application server, so targeted notifications can be sent. +/// +/// * Subscribing to any topics. +- (void)messaging:(FIRMessaging *)messaging + didReceiveRegistrationToken:(NSString *)fcmToken + NS_SWIFT_NAME(messaging(_:didReceiveRegistrationToken:)); + +/// This method is called on iOS 10+ devices to handle data messages received via FCM +/// direct channel (not via APNS). For iOS 9 and below, the direct channel data message +/// is handled by the UIApplicationDelegate's -application:didReceiveRemoteNotification: method. +/// You can enable all direct channel data messages to be delivered in FIRMessagingDelegate +/// by setting the flag `useMessagingDelegateForDirectMessages` to true. +- (void)messaging:(FIRMessaging *)messaging + didReceiveMessage:(FIRMessagingRemoteMessage *)remoteMessage + NS_SWIFT_NAME(messaging(_:didReceive:)) + __IOS_AVAILABLE(10.0); + +@end + +/** + * Firebase Messaging lets you reliably deliver messages at no cost. + * + * To send or receive messages, the app must get a + * registration token from FIRInstanceID. This token authorizes an + * app server to send messages to an app instance. + * + * In order to receive FIRMessaging messages, declare + * `application:didReceiveRemoteNotification::fetchCompletionHandler:`. + */ +NS_SWIFT_NAME(Messaging) +@interface FIRMessaging : NSObject + +/** + * Delegate to handle FCM token refreshes, and remote data messages received via FCM direct channel. + */ +@property(nonatomic, weak, nullable) id delegate; + +/** + * When set to `YES`, Firebase Messaging will automatically establish a socket-based, direct + * channel to the FCM server. Enable this only if you are sending upstream messages or + * receiving non-APNS, data-only messages in foregrounded apps. + * Default is `NO`. + */ +@property(nonatomic) BOOL shouldEstablishDirectChannel; + +/** + * Returns `YES` if the direct channel to the FCM server is active, and `NO` otherwise. + */ +@property(nonatomic, readonly) BOOL isDirectChannelEstablished; + +/* + * Whether direct channel message should only use FIRMessagingDelegate messaging(_:didReceive:) + * for message delivery callback. The default value is false. If you need to change + * the default, set FirebaseMessagingUseMessagingDelegateForDirectChannel to true in + * your application’s Info.plist. + * + * If false, the message via direct channel for iOS 9 and below is still delivered in + * `-UIApplicationDelegate application(_:didReceiveRemoteNotification:fetchCompletionHandler:)`, + * and the FIRMessagingRemoteMessage object and its associated data will be unavailable. + * For iOS 10 and above, it is still delivered in `FIRMessagingDelegate messaging(_:didReceive:)`. + * + * If true, the data message sent by direct channel will be delivered via + * `FIRMessagingDelegate messaging(_:didReceive:)` and across all iOS versions. + */ +@property(nonatomic, assign) BOOL useMessagingDelegateForDirectChannel; + +/** + * FIRMessaging + * + * @return An instance of FIRMessaging. + */ ++ (instancetype)messaging NS_SWIFT_NAME(messaging()); + +/** + * Unavailable. Use +messaging instead. + */ +- (instancetype)init __attribute__((unavailable("Use +messaging instead."))); + +#pragma mark - APNS + +/** + * This property is used to set the APNS Token received by the application delegate. + * + * FIRMessaging uses method swizzling to ensure that the APNS token is set + * automatically. However, if you have disabled swizzling by setting + * `FirebaseAppDelegateProxyEnabled` to `NO` in your app's + * Info.plist, you should manually set the APNS token in your application + * delegate's `-application:didRegisterForRemoteNotificationsWithDeviceToken:` + * method. + * + * If you would like to set the type of the APNS token, rather than relying on + * automatic detection, see: `-setAPNSToken:type:`. + */ +@property(nonatomic, copy, nullable) NSData *APNSToken NS_SWIFT_NAME(apnsToken); + +/** + * Set APNS token for the application. This APNS token will be used to register + * with Firebase Messaging using `FCMToken` or + * `tokenWithAuthorizedEntity:scope:options:handler`. + * + * @param apnsToken The APNS token for the application. + * @param type The type of APNS token. Debug builds should use + * FIRMessagingAPNSTokenTypeSandbox. Alternatively, you can supply + * FIRMessagingAPNSTokenTypeUnknown to have the type automatically + * detected based on your provisioning profile. + */ +- (void)setAPNSToken:(NSData *)apnsToken type:(FIRMessagingAPNSTokenType)type; + +#pragma mark - FCM Tokens + +/** + * Is Firebase Messaging token auto generation enabled? If this flag is disabled, + * Firebase Messaging will not generate token automatically for message delivery. + * + * If this flag is disabled, Firebase Messaging does not generate new tokens automatically for + * message delivery. If this flag is enabled, FCM generates a registration token on application + * start when there is no existing valid token. FCM also generates a new token when an existing + * token is deleted. + * + * This setting is persisted, and is applied on future + * invocations of your application. Once explicitly set, it overrides any + * settings in your Info.plist. + * + * By default, FCM automatic initialization is enabled. If you need to change the + * default (for example, because you want to prompt the user before getting token) + * set FirebaseMessagingAutoInitEnabled to false in your application's Info.plist. + */ +@property(nonatomic, assign, getter=isAutoInitEnabled) BOOL autoInitEnabled; + +/** + * The FCM token is used to identify this device so that FCM can send notifications to it. + * It is associated with your APNS token when the APNS token is supplied, so that sending + * messages to the FCM token will be delivered over APNS. + * + * The FCM token is sometimes refreshed automatically. In your FIRMessaging delegate, the + * delegate method `messaging:didReceiveRegistrationToken:` will be called once a token is + * available, or has been refreshed. Typically it should be called once per app start, but + * may be called more often, if token is invalidated or updated. + * + * Once you have an FCM token, you should send it to your application server, so it can use + * the FCM token to send notifications to your device. + */ +@property(nonatomic, readonly, nullable) NSString *FCMToken NS_SWIFT_NAME(fcmToken); + + +/** + * Retrieves an FCM registration token for a particular Sender ID. This can be used to allow + * multiple senders to send notifications to the same device. By providing a different Sender + * ID than your default when fetching a token, you can create a new FCM token which you can + * give to a different sender. Both tokens will deliver notifications to your device, and you + * can revoke a token when you need to. + * + * This registration token is not cached by FIRMessaging. FIRMessaging should have an APNS + * token set before calling this to ensure that notifications can be delivered via APNS using + * this FCM token. You may re-retrieve the FCM token once you have the APNS token set, to + * associate it with the FCM token. The default FCM token is automatically associated with + * the APNS token, if the APNS token data is available. + * + * @param senderID The Sender ID for a particular Firebase project. + * @param completion The completion handler to handle the token request. + */ +- (void)retrieveFCMTokenForSenderID:(NSString *)senderID + completion:(FIRMessagingFCMTokenFetchCompletion)completion + NS_SWIFT_NAME(retrieveFCMToken(forSenderID:completion:)); + + +/** + * Invalidates an FCM token for a particular Sender ID. That Sender ID cannot no longer send + * notifications to that FCM token. + * + * @param senderID The senderID for a particular Firebase project. + * @param completion The completion handler to handle the token deletion. + */ +- (void)deleteFCMTokenForSenderID:(NSString *)senderID + completion:(FIRMessagingDeleteFCMTokenCompletion)completion + NS_SWIFT_NAME(deleteFCMToken(forSenderID:completion:)); + + +#pragma mark - FCM Direct Channel + +/** + * Create a FIRMessaging data connection which will be used to send the data notifications + * sent by your server. It will also be used to send ACKS and other messages based + * on the FIRMessaging ACKS and other messages based on the FIRMessaging protocol. + * + * + * @param handler The handler to be invoked once the connection is established. + * If the connection fails we invoke the handler with an + * appropriate error code letting you know why it failed. At + * the same time, FIRMessaging performs exponential backoff to retry + * establishing a connection and invoke the handler when successful. + */ +- (void)connectWithCompletion:(FIRMessagingConnectCompletion)handler + NS_SWIFT_NAME(connect(handler:)) + __deprecated_msg("Please use the shouldEstablishDirectChannel property instead."); + +/** + * Disconnect the current FIRMessaging data connection. This stops any attempts to + * connect to FIRMessaging. Calling this on an already disconnected client is a no-op. + * + * Call this before `teardown` when your app is going to the background. + * Since the FIRMessaging connection won't be allowed to live when in the background, it is + * prudent to close the connection. + */ +- (void)disconnect + __deprecated_msg("Please use the shouldEstablishDirectChannel property instead."); + +#pragma mark - Topics + +/** + * Asynchronously subscribes to a topic. + * + * @param topic The name of the topic, for example, @"sports". + */ +- (void)subscribeToTopic:(NSString *)topic NS_SWIFT_NAME(subscribe(toTopic:)); + +/** + * Asynchronously subscribe to the provided topic, retrying on failure. + * + * @param topic The topic name to subscribe to, for example, @"sports". + * @param completion The completion that is invoked once the subscribe call ends. + * In case of success, nil error is returned. Otherwise, an + * appropriate error object is returned. + */ +- (void)subscribeToTopic:(nonnull NSString *)topic + completion:(nullable FIRMessagingTopicOperationCompletion)completion; + +/** + * Asynchronously unsubscribe from a topic. + * + * @param topic The name of the topic, for example @"sports". + */ +- (void)unsubscribeFromTopic:(NSString *)topic NS_SWIFT_NAME(unsubscribe(fromTopic:)); + +/** + * Asynchronously unsubscribe from the provided topic, retrying on failure. + * + * @param topic The topic name to unsubscribe from, for example @"sports". + * @param completion The completion that is invoked once the unsubscribe call ends. + * In case of success, nil error is returned. Otherwise, an + * appropriate error object is returned. + */ +- (void)unsubscribeFromTopic:(nonnull NSString *)topic + completion:(nullable FIRMessagingTopicOperationCompletion)completion; + +#pragma mark - Upstream + +/** + * Sends an upstream ("device to cloud") message. + * + * The message is queued if we don't have an active connection. + * You can only use the upstream feature if your FCM implementation + * uses the XMPP server protocol. + * + * @param message Key/Value pairs to be sent. Values must be String, any + * other type will be ignored. + * @param receiver A string identifying the receiver of the message. For FCM + * project IDs the value is `SENDER_ID@gcm.googleapis.com`. + * @param messageID The ID of the message. This is generated by the application. It + * must be unique for each message generated by this application. + * It allows error callbacks and debugging, to uniquely identify + * each message. + * @param ttl The time to live for the message. In case we aren't able to + * send the message before the TTL expires we will send you a + * callback. If 0, we'll attempt to send immediately and return + * an error if we're not connected. Otherwise, the message will + * be queued. As for server-side messages, we don't return an error + * if the message has been dropped because of TTL; this can happen + * on the server side, and it would require extra communication. + */ +- (void)sendMessage:(NSDictionary *)message + to:(NSString *)receiver + withMessageID:(NSString *)messageID + timeToLive:(int64_t)ttl; + +#pragma mark - Analytics + +/** + * Use this to track message delivery and analytics for messages, typically + * when you receive a notification in `application:didReceiveRemoteNotification:`. + * However, you only need to call this if you set the `FirebaseAppDelegateProxyEnabled` + * flag to `NO` in your Info.plist. If `FirebaseAppDelegateProxyEnabled` is either missing + * or set to `YES` in your Info.plist, the library will call this automatically. + * + * @param message The downstream message received by the application. + * + * @return Information about the downstream message. + */ +- (FIRMessagingMessageInfo *)appDidReceiveMessage:(NSDictionary *)message; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Pods/FirebaseMessaging/Firebase/Messaging/Public/FirebaseMessaging.h b/ios/Pods/FirebaseMessaging/Firebase/Messaging/Public/FirebaseMessaging.h new file mode 100755 index 00000000..ef081c90 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/Firebase/Messaging/Public/FirebaseMessaging.h @@ -0,0 +1,17 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessaging.h" diff --git a/ios/Pods/FirebaseMessaging/LICENSE b/ios/Pods/FirebaseMessaging/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/ios/Pods/FirebaseMessaging/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/ios/Pods/FirebaseMessaging/README.md b/ios/Pods/FirebaseMessaging/README.md new file mode 100644 index 00000000..d414a4cd --- /dev/null +++ b/ios/Pods/FirebaseMessaging/README.md @@ -0,0 +1,193 @@ +# Firebase iOS Open Source Development [![Build Status](https://travis-ci.org/firebase/firebase-ios-sdk.svg?branch=master)](https://travis-ci.org/firebase/firebase-ios-sdk) + +This repository contains a subset of the Firebase iOS SDK source. It currently +includes FirebaseCore, FirebaseAuth, FirebaseDatabase, FirebaseFirestore, +FirebaseFunctions, FirebaseInAppMessagingDisplay, FirebaseMessaging and +FirebaseStorage. + +The repository also includes GoogleUtilities source. The +[GoogleUtilities](GoogleUtilities/README.md) pod is +a set of utilities used by Firebase and other Google products. + +Firebase is an app development platform with tools to help you build, grow and +monetize your app. More information about Firebase can be found at +[https://firebase.google.com](https://firebase.google.com). + +## Installation + +See the three subsections for details about three different installation methods. +1. [Standard pod install](README.md#standard-pod-install) +1. [Installing from the GitHub repo](README.md#installing-from-github) +1. [Experimental Carthage](README.md#carthage-ios-only) + +### Standard pod install + +Go to +[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup). + +### Installing from GitHub + +For releases starting with 5.0.0, the source for each release is also deployed +to CocoaPods master and available via standard +[CocoaPods Podfile syntax](https://guides.cocoapods.org/syntax/podfile.html#pod). + +These instructions can be used to access the Firebase repo at other branches, +tags, or commits. + +#### Background + +See +[the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod) +for instructions and options about overriding pod source locations. + +#### Accessing Firebase Source Snapshots + +All of the official releases are tagged in this repo and available via CocoaPods. To access a local +source snapshot or unreleased branch, use Podfile directives like the following: + +To access FirebaseFirestore via a branch: +``` +pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' +pod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' +``` + +To access FirebaseMessaging via a checked out version of the firebase-ios-sdk repo do: + +``` +pod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk' +pod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk' +``` + +### Carthage (iOS only) + +Instructions for the experimental Carthage distribution are at +[Carthage](Carthage.md). + +### Rome + +Instructions for installing binary frameworks via +[Rome](https://github.com/CocoaPods/Rome) are at [Rome](Rome.md). + +## Development + +Follow the subsequent instructions to develop, debug, unit test, run integration +tests, and try out reference samples: + +``` +$ git clone git@github.com:firebase/firebase-ios-sdk.git +$ cd firebase-ios-sdk/Example +$ pod update +$ open Firebase.xcworkspace +``` + +Firestore and Functions have self contained Xcode projects. See +[Firestore/README.md](Firestore/README.md) and +[Functions/README.md](Functions/README.md). + +### Code Formatting + +Travis will verify that any code changes are done in a style compliant way. Install +`clang-format` and `swiftformat`. +This command will get the right `clang-format` version: + +`brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/0743d748ba8b41eec074a0a787dc80219142c525/Formula/clang-format.rb` + +### Running Unit Tests + +Select a scheme and press Command-u to build a component and run its unit tests. + +### Running Sample Apps +In order to run the sample apps and integration tests, you'll need valid +`GoogleService-Info.plist` files for those samples. The Firebase Xcode project contains dummy plist +files without real values, but can be replaced with real plist files. To get your own +`GoogleService-Info.plist` files: + +1. Go to the [Firebase Console](https://console.firebase.google.com/) +2. Create a new Firebase project, if you don't already have one +3. For each sample app you want to test, create a new Firebase app with the sample app's bundle +identifier (e.g. `com.google.Database-Example`) +4. Download the resulting `GoogleService-Info.plist` and replace the appropriate dummy plist file +(e.g. in [Example/Database/App/](Example/Database/App/)); + +Some sample apps like Firebase Messaging ([Example/Messaging/App](Example/Messaging/App)) require +special Apple capabilities, and you will have to change the sample app to use a unique bundle +identifier that you can control in your own Apple Developer account. + +## Specific Component Instructions +See the sections below for any special instructions for those components. + +### Firebase Auth + +If you're doing specific Firebase Auth development, see +[the Auth Sample README](Example/Auth/README.md) for instructions about +building and running the FirebaseAuth pod along with various samples and tests. + +### Firebase Database + +To run the Database Integration tests, make your database authentication rules +[public](https://firebase.google.com/docs/database/security/quickstart). + +### Firebase Storage + +To run the Storage Integration tests, follow the instructions in +[FIRStorageIntegrationTests.m](Example/Storage/Tests/Integration/FIRStorageIntegrationTests.m). + +#### Push Notifications + +Push notifications can only be delivered to specially provisioned App IDs in the developer portal. +In order to actually test receiving push notifications, you will need to: + +1. Change the bundle identifier of the sample app to something you own in your Apple Developer +account, and enable that App ID for push notifications. +2. You'll also need to +[upload your APNs Provider Authentication Key or certificate to the Firebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs) +at **Project Settings > Cloud Messaging > [Your Firebase App]**. +3. Ensure your iOS device is added to your Apple Developer portal as a test device. + +#### iOS Simulator + +The iOS Simulator cannot register for remote notifications, and will not receive push notifications. +In order to receive push notifications, you'll have to follow the steps above and run the app on a +physical device. + +## Community Supported Efforts + +We've seen an amazing amount of interest and contributions to improve the Firebase SDKs, and we are +very grateful! We'd like to empower as many developers as we can to be able to use Firebase and +participate in the Firebase community. + +### macOS and tvOS +FirebaseAuth, FirebaseCore, FirebaseDatabase and FirebaseStorage now compile, run unit tests, and +work on macOS and tvOS, thanks to contributions from the community. There are a few tweaks needed, +like ensuring iOS-only, macOS-only, or tvOS-only code is correctly guarded with checks for +`TARGET_OS_IOS`, `TARGET_OS_OSX` and `TARGET_OS_TV`. + +For tvOS, checkout the [Sample](Example/tvOSSample). + +Keep in mind that macOS and tvOS are not officially supported by Firebase, and this repository is +actively developed primarily for iOS. While we can catch basic unit test issues with Travis, there +may be some changes where the SDK no longer works as expected on macOS or tvOS. If you encounter +this, please [file an issue](https://github.com/firebase/firebase-ios-sdk/issues). + +For installation instructions, see [above](README.md#accessing-firebase-source-snapshots). + +Note that the Firebase pod is not available for macOS and tvOS. Install a selection of the +`FirebaseAuth`, `FirebaseCore`, `FirebaseDatabase` and `FirebaseStorage` CocoaPods. + +## Roadmap + +See [Roadmap](ROADMAP.md) for more about the Firebase iOS SDK Open Source +plans and directions. + +## Contributing + +See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase +iOS SDK. + +## License + +The contents of this repository is licensed under the +[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). + +Your use of Firebase is governed by the +[Terms of Service for Firebase Services](https://firebase.google.com/terms/). diff --git a/ios/Pods/Headers/Private/FirebaseAnalyticsInterop/FIRAnalyticsInterop.h b/ios/Pods/Headers/Private/FirebaseAnalyticsInterop/FIRAnalyticsInterop.h new file mode 120000 index 00000000..e01a43ad --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseAnalyticsInterop/FIRAnalyticsInterop.h @@ -0,0 +1 @@ +../../../FirebaseAnalyticsInterop/Interop/Analytics/Public/FIRAnalyticsInterop.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseAnalyticsInterop/FIRAnalyticsInteropListener.h b/ios/Pods/Headers/Private/FirebaseAnalyticsInterop/FIRAnalyticsInteropListener.h new file mode 120000 index 00000000..d3cd0976 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseAnalyticsInterop/FIRAnalyticsInteropListener.h @@ -0,0 +1 @@ +../../../FirebaseAnalyticsInterop/Interop/Analytics/Public/FIRAnalyticsInteropListener.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseAnalyticsInterop/FIRInteropEventNames.h b/ios/Pods/Headers/Private/FirebaseAnalyticsInterop/FIRInteropEventNames.h new file mode 120000 index 00000000..dbda3ecc --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseAnalyticsInterop/FIRInteropEventNames.h @@ -0,0 +1 @@ +../../../FirebaseAnalyticsInterop/Interop/Analytics/Public/FIRInteropEventNames.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseAnalyticsInterop/FIRInteropParameterNames.h b/ios/Pods/Headers/Private/FirebaseAnalyticsInterop/FIRInteropParameterNames.h new file mode 120000 index 00000000..51458430 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseAnalyticsInterop/FIRInteropParameterNames.h @@ -0,0 +1 @@ +../../../FirebaseAnalyticsInterop/Interop/Analytics/Public/FIRInteropParameterNames.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseAuthInterop/FIRAuthInterop.h b/ios/Pods/Headers/Private/FirebaseAuthInterop/FIRAuthInterop.h new file mode 120000 index 00000000..0253e257 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseAuthInterop/FIRAuthInterop.h @@ -0,0 +1 @@ +../../../FirebaseAuthInterop/Interop/Auth/Public/FIRAuthInterop.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/APLevelDB.h b/ios/Pods/Headers/Private/FirebaseDatabase/APLevelDB.h new file mode 120000 index 00000000..63c17e76 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/APLevelDB.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/third_party/Wrap-leveldb/APLevelDB.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FAckUserWrite.h b/ios/Pods/Headers/Private/FirebaseDatabase/FAckUserWrite.h new file mode 120000 index 00000000..ea472c65 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FAckUserWrite.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/Operation/FAckUserWrite.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FArraySortedDictionary.h b/ios/Pods/Headers/Private/FirebaseDatabase/FArraySortedDictionary.h new file mode 120000 index 00000000..9f51f185 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FArraySortedDictionary.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FArraySortedDictionary.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FAtomicNumber.h b/ios/Pods/Headers/Private/FirebaseDatabase/FAtomicNumber.h new file mode 120000 index 00000000..3f612f9f --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FAtomicNumber.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Utilities/FAtomicNumber.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FAuthTokenProvider.h b/ios/Pods/Headers/Private/FirebaseDatabase/FAuthTokenProvider.h new file mode 120000 index 00000000..9aacbd3f --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FAuthTokenProvider.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Login/FAuthTokenProvider.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FCacheNode.h b/ios/Pods/Headers/Private/FirebaseDatabase/FCacheNode.h new file mode 120000 index 00000000..29839d24 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FCacheNode.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/View/FCacheNode.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FCachePolicy.h b/ios/Pods/Headers/Private/FirebaseDatabase/FCachePolicy.h new file mode 120000 index 00000000..021d4bb3 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FCachePolicy.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Persistence/FCachePolicy.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FCancelEvent.h b/ios/Pods/Headers/Private/FirebaseDatabase/FCancelEvent.h new file mode 120000 index 00000000..1fed2ec1 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FCancelEvent.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/View/FCancelEvent.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FChange.h b/ios/Pods/Headers/Private/FirebaseDatabase/FChange.h new file mode 120000 index 00000000..d54e22bd --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FChange.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/View/FChange.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FChildChangeAccumulator.h b/ios/Pods/Headers/Private/FirebaseDatabase/FChildChangeAccumulator.h new file mode 120000 index 00000000..13b2812e --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FChildChangeAccumulator.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/View/Filter/FChildChangeAccumulator.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FChildEventRegistration.h b/ios/Pods/Headers/Private/FirebaseDatabase/FChildEventRegistration.h new file mode 120000 index 00000000..fc5949e5 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FChildEventRegistration.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/View/FChildEventRegistration.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FChildrenNode.h b/ios/Pods/Headers/Private/FirebaseDatabase/FChildrenNode.h new file mode 120000 index 00000000..5df57154 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FChildrenNode.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Snapshot/FChildrenNode.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FClock.h b/ios/Pods/Headers/Private/FirebaseDatabase/FClock.h new file mode 120000 index 00000000..ce565400 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FClock.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/FClock.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FCompleteChildSource.h b/ios/Pods/Headers/Private/FirebaseDatabase/FCompleteChildSource.h new file mode 120000 index 00000000..a6e42e38 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FCompleteChildSource.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/View/Filter/FCompleteChildSource.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FCompoundHash.h b/ios/Pods/Headers/Private/FirebaseDatabase/FCompoundHash.h new file mode 120000 index 00000000..bcc950e7 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FCompoundHash.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/FCompoundHash.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FCompoundWrite.h b/ios/Pods/Headers/Private/FirebaseDatabase/FCompoundWrite.h new file mode 120000 index 00000000..731587d8 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FCompoundWrite.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Snapshot/FCompoundWrite.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FConnection.h b/ios/Pods/Headers/Private/FirebaseDatabase/FConnection.h new file mode 120000 index 00000000..1dcbf010 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FConnection.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Realtime/FConnection.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FConstants.h b/ios/Pods/Headers/Private/FirebaseDatabase/FConstants.h new file mode 120000 index 00000000..17e1daf4 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FConstants.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Constants/FConstants.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FDataEvent.h b/ios/Pods/Headers/Private/FirebaseDatabase/FDataEvent.h new file mode 120000 index 00000000..ccc4aba0 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FDataEvent.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/View/FDataEvent.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FEmptyNode.h b/ios/Pods/Headers/Private/FirebaseDatabase/FEmptyNode.h new file mode 120000 index 00000000..ffabcd7d --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FEmptyNode.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Snapshot/FEmptyNode.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FEvent.h b/ios/Pods/Headers/Private/FirebaseDatabase/FEvent.h new file mode 120000 index 00000000..d14d86df --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FEvent.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/View/FEvent.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FEventEmitter.h b/ios/Pods/Headers/Private/FirebaseDatabase/FEventEmitter.h new file mode 120000 index 00000000..6574e477 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FEventEmitter.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Utilities/FEventEmitter.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FEventGenerator.h b/ios/Pods/Headers/Private/FirebaseDatabase/FEventGenerator.h new file mode 120000 index 00000000..7d48375e --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FEventGenerator.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/FEventGenerator.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FEventRaiser.h b/ios/Pods/Headers/Private/FirebaseDatabase/FEventRaiser.h new file mode 120000 index 00000000..30bf11a9 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FEventRaiser.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/View/FEventRaiser.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FEventRegistration.h b/ios/Pods/Headers/Private/FirebaseDatabase/FEventRegistration.h new file mode 120000 index 00000000..945a1587 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FEventRegistration.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/View/FEventRegistration.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FIRDataEventType.h b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDataEventType.h new file mode 120000 index 00000000..0a5c1089 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDataEventType.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Public/FIRDataEventType.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FIRDataSnapshot.h b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDataSnapshot.h new file mode 120000 index 00000000..1ca4513b --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDataSnapshot.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Public/FIRDataSnapshot.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FIRDataSnapshot_Private.h b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDataSnapshot_Private.h new file mode 120000 index 00000000..1be8b9ef --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDataSnapshot_Private.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Api/Private/FIRDataSnapshot_Private.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabase.h b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabase.h new file mode 120000 index 00000000..36c8659c --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabase.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Public/FIRDatabase.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabaseComponent.h b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabaseComponent.h new file mode 120000 index 00000000..46ba6e98 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabaseComponent.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Api/FIRDatabaseComponent.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabaseConfig.h b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabaseConfig.h new file mode 120000 index 00000000..0b2c1cd5 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabaseConfig.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Api/FIRDatabaseConfig.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabaseConfig_Private.h b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabaseConfig_Private.h new file mode 120000 index 00000000..1de5e749 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabaseConfig_Private.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/FIRDatabaseConfig_Private.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabaseQuery.h b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabaseQuery.h new file mode 120000 index 00000000..1c08fe6e --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabaseQuery.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Public/FIRDatabaseQuery.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabaseQuery_Private.h b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabaseQuery_Private.h new file mode 120000 index 00000000..dc408d6e --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabaseQuery_Private.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Api/Private/FIRDatabaseQuery_Private.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabaseReference.h b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabaseReference.h new file mode 120000 index 00000000..d2ef3453 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabaseReference.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Public/FIRDatabaseReference.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabaseReference_Private.h b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabaseReference_Private.h new file mode 120000 index 00000000..13aff15c --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabaseReference_Private.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Api/Private/FIRDatabaseReference_Private.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabase_Private.h b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabase_Private.h new file mode 120000 index 00000000..499d1978 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FIRDatabase_Private.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Api/Private/FIRDatabase_Private.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FIRMutableData.h b/ios/Pods/Headers/Private/FirebaseDatabase/FIRMutableData.h new file mode 120000 index 00000000..19b69a8c --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FIRMutableData.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Public/FIRMutableData.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FIRMutableData_Private.h b/ios/Pods/Headers/Private/FirebaseDatabase/FIRMutableData_Private.h new file mode 120000 index 00000000..5ed98863 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FIRMutableData_Private.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Api/Private/FIRMutableData_Private.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FIRNoopAuthTokenProvider.h b/ios/Pods/Headers/Private/FirebaseDatabase/FIRNoopAuthTokenProvider.h new file mode 120000 index 00000000..969976b9 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FIRNoopAuthTokenProvider.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Login/FIRNoopAuthTokenProvider.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FIRRetryHelper.h b/ios/Pods/Headers/Private/FirebaseDatabase/FIRRetryHelper.h new file mode 120000 index 00000000..bd3ef146 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FIRRetryHelper.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/Utilities/FIRRetryHelper.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FIRServerValue.h b/ios/Pods/Headers/Private/FirebaseDatabase/FIRServerValue.h new file mode 120000 index 00000000..9bf59844 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FIRServerValue.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Public/FIRServerValue.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FIRTransactionResult.h b/ios/Pods/Headers/Private/FirebaseDatabase/FIRTransactionResult.h new file mode 120000 index 00000000..24b6abb0 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FIRTransactionResult.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Public/FIRTransactionResult.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FIRTransactionResult_Private.h b/ios/Pods/Headers/Private/FirebaseDatabase/FIRTransactionResult_Private.h new file mode 120000 index 00000000..43642272 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FIRTransactionResult_Private.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Api/Private/FIRTransactionResult_Private.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FImmutableSortedDictionary.h b/ios/Pods/Headers/Private/FirebaseDatabase/FImmutableSortedDictionary.h new file mode 120000 index 00000000..36a36b0f --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FImmutableSortedDictionary.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FImmutableSortedDictionary.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FImmutableSortedSet.h b/ios/Pods/Headers/Private/FirebaseDatabase/FImmutableSortedSet.h new file mode 120000 index 00000000..33d00874 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FImmutableSortedSet.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FImmutableSortedSet.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FImmutableTree.h b/ios/Pods/Headers/Private/FirebaseDatabase/FImmutableTree.h new file mode 120000 index 00000000..824e0e1f --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FImmutableTree.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/Utilities/FImmutableTree.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FIndex.h b/ios/Pods/Headers/Private/FirebaseDatabase/FIndex.h new file mode 120000 index 00000000..8ea104f1 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FIndex.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/FIndex.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FIndexedFilter.h b/ios/Pods/Headers/Private/FirebaseDatabase/FIndexedFilter.h new file mode 120000 index 00000000..63669e68 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FIndexedFilter.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/View/Filter/FIndexedFilter.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FIndexedNode.h b/ios/Pods/Headers/Private/FirebaseDatabase/FIndexedNode.h new file mode 120000 index 00000000..b24ab0ba --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FIndexedNode.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Snapshot/FIndexedNode.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FKeepSyncedEventRegistration.h b/ios/Pods/Headers/Private/FirebaseDatabase/FKeepSyncedEventRegistration.h new file mode 120000 index 00000000..24c5e5d4 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FKeepSyncedEventRegistration.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/View/FKeepSyncedEventRegistration.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FKeyIndex.h b/ios/Pods/Headers/Private/FirebaseDatabase/FKeyIndex.h new file mode 120000 index 00000000..dbf3f755 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FKeyIndex.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/FKeyIndex.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FLLRBEmptyNode.h b/ios/Pods/Headers/Private/FirebaseDatabase/FLLRBEmptyNode.h new file mode 120000 index 00000000..8ae3b52d --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FLLRBEmptyNode.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBEmptyNode.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FLLRBNode.h b/ios/Pods/Headers/Private/FirebaseDatabase/FLLRBNode.h new file mode 120000 index 00000000..a2135de5 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FLLRBNode.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBNode.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FLLRBValueNode.h b/ios/Pods/Headers/Private/FirebaseDatabase/FLLRBValueNode.h new file mode 120000 index 00000000..0d981d88 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FLLRBValueNode.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBValueNode.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FLeafNode.h b/ios/Pods/Headers/Private/FirebaseDatabase/FLeafNode.h new file mode 120000 index 00000000..dbfb3848 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FLeafNode.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Snapshot/FLeafNode.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FLevelDBStorageEngine.h b/ios/Pods/Headers/Private/FirebaseDatabase/FLevelDBStorageEngine.h new file mode 120000 index 00000000..67845142 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FLevelDBStorageEngine.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Persistence/FLevelDBStorageEngine.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FLimitedFilter.h b/ios/Pods/Headers/Private/FirebaseDatabase/FLimitedFilter.h new file mode 120000 index 00000000..dfab6b66 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FLimitedFilter.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/View/Filter/FLimitedFilter.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FListenComplete.h b/ios/Pods/Headers/Private/FirebaseDatabase/FListenComplete.h new file mode 120000 index 00000000..1c472d24 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FListenComplete.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/FListenComplete.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FListenProvider.h b/ios/Pods/Headers/Private/FirebaseDatabase/FListenProvider.h new file mode 120000 index 00000000..bb61d1ab --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FListenProvider.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/FListenProvider.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FMaxNode.h b/ios/Pods/Headers/Private/FirebaseDatabase/FMaxNode.h new file mode 120000 index 00000000..ae4eb7d4 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FMaxNode.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/FMaxNode.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FMerge.h b/ios/Pods/Headers/Private/FirebaseDatabase/FMerge.h new file mode 120000 index 00000000..733d9eca --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FMerge.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/Operation/FMerge.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FNamedNode.h b/ios/Pods/Headers/Private/FirebaseDatabase/FNamedNode.h new file mode 120000 index 00000000..328e8376 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FNamedNode.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/FNamedNode.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FNextPushId.h b/ios/Pods/Headers/Private/FirebaseDatabase/FNextPushId.h new file mode 120000 index 00000000..d54ecdf3 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FNextPushId.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Utilities/FNextPushId.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FNode.h b/ios/Pods/Headers/Private/FirebaseDatabase/FNode.h new file mode 120000 index 00000000..4ec31f69 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FNode.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Snapshot/FNode.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FNodeFilter.h b/ios/Pods/Headers/Private/FirebaseDatabase/FNodeFilter.h new file mode 120000 index 00000000..d167862d --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FNodeFilter.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/View/Filter/FNodeFilter.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FOperation.h b/ios/Pods/Headers/Private/FirebaseDatabase/FOperation.h new file mode 120000 index 00000000..f15d781a --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FOperation.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/Operation/FOperation.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FOperationSource.h b/ios/Pods/Headers/Private/FirebaseDatabase/FOperationSource.h new file mode 120000 index 00000000..b660c41d --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FOperationSource.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/Operation/FOperationSource.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FOverwrite.h b/ios/Pods/Headers/Private/FirebaseDatabase/FOverwrite.h new file mode 120000 index 00000000..05ed11f0 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FOverwrite.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/Operation/FOverwrite.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FParsedUrl.h b/ios/Pods/Headers/Private/FirebaseDatabase/FParsedUrl.h new file mode 120000 index 00000000..5f42ab8f --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FParsedUrl.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Utilities/FParsedUrl.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FPath.h b/ios/Pods/Headers/Private/FirebaseDatabase/FPath.h new file mode 120000 index 00000000..06299230 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FPath.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/Utilities/FPath.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FPathIndex.h b/ios/Pods/Headers/Private/FirebaseDatabase/FPathIndex.h new file mode 120000 index 00000000..3ca9da30 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FPathIndex.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/FPathIndex.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FPendingPut.h b/ios/Pods/Headers/Private/FirebaseDatabase/FPendingPut.h new file mode 120000 index 00000000..5df83c70 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FPendingPut.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Persistence/FPendingPut.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FPersistenceManager.h b/ios/Pods/Headers/Private/FirebaseDatabase/FPersistenceManager.h new file mode 120000 index 00000000..9ac7453d --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FPersistenceManager.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Persistence/FPersistenceManager.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FPersistentConnection.h b/ios/Pods/Headers/Private/FirebaseDatabase/FPersistentConnection.h new file mode 120000 index 00000000..d3f96c7e --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FPersistentConnection.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/FPersistentConnection.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FPriorityIndex.h b/ios/Pods/Headers/Private/FirebaseDatabase/FPriorityIndex.h new file mode 120000 index 00000000..a5775491 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FPriorityIndex.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/FPriorityIndex.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FPruneForest.h b/ios/Pods/Headers/Private/FirebaseDatabase/FPruneForest.h new file mode 120000 index 00000000..67efbacf --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FPruneForest.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Persistence/FPruneForest.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FQueryParams.h b/ios/Pods/Headers/Private/FirebaseDatabase/FQueryParams.h new file mode 120000 index 00000000..8c91e962 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FQueryParams.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/FQueryParams.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FQuerySpec.h b/ios/Pods/Headers/Private/FirebaseDatabase/FQuerySpec.h new file mode 120000 index 00000000..025b79fd --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FQuerySpec.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/FQuerySpec.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FRangeMerge.h b/ios/Pods/Headers/Private/FirebaseDatabase/FRangeMerge.h new file mode 120000 index 00000000..c0c01a61 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FRangeMerge.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/FRangeMerge.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FRangedFilter.h b/ios/Pods/Headers/Private/FirebaseDatabase/FRangedFilter.h new file mode 120000 index 00000000..4dc73c6d --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FRangedFilter.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/FRangedFilter.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FRepo.h b/ios/Pods/Headers/Private/FirebaseDatabase/FRepo.h new file mode 120000 index 00000000..806da756 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FRepo.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/FRepo.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FRepoInfo.h b/ios/Pods/Headers/Private/FirebaseDatabase/FRepoInfo.h new file mode 120000 index 00000000..f3db337a --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FRepoInfo.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/FRepoInfo.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FRepoManager.h b/ios/Pods/Headers/Private/FirebaseDatabase/FRepoManager.h new file mode 120000 index 00000000..2f4d0d7c --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FRepoManager.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/FRepoManager.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FRepo_Private.h b/ios/Pods/Headers/Private/FirebaseDatabase/FRepo_Private.h new file mode 120000 index 00000000..2c99aae7 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FRepo_Private.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/FRepo_Private.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FSRWebSocket.h b/ios/Pods/Headers/Private/FirebaseDatabase/FSRWebSocket.h new file mode 120000 index 00000000..fc96baef --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FSRWebSocket.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/third_party/SocketRocket/FSRWebSocket.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FServerValues.h b/ios/Pods/Headers/Private/FirebaseDatabase/FServerValues.h new file mode 120000 index 00000000..b60672b2 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FServerValues.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/FServerValues.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FSnapshotHolder.h b/ios/Pods/Headers/Private/FirebaseDatabase/FSnapshotHolder.h new file mode 120000 index 00000000..38e865cc --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FSnapshotHolder.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/FSnapshotHolder.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FSnapshotUtilities.h b/ios/Pods/Headers/Private/FirebaseDatabase/FSnapshotUtilities.h new file mode 120000 index 00000000..74d6ca9e --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FSnapshotUtilities.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Snapshot/FSnapshotUtilities.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FSparseSnapshotTree.h b/ios/Pods/Headers/Private/FirebaseDatabase/FSparseSnapshotTree.h new file mode 120000 index 00000000..f6c6986f --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FSparseSnapshotTree.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/FSparseSnapshotTree.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FStorageEngine.h b/ios/Pods/Headers/Private/FirebaseDatabase/FStorageEngine.h new file mode 120000 index 00000000..fbec63ca --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FStorageEngine.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Persistence/FStorageEngine.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FStringUtilities.h b/ios/Pods/Headers/Private/FirebaseDatabase/FStringUtilities.h new file mode 120000 index 00000000..0c7b7cd1 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FStringUtilities.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Utilities/FStringUtilities.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FSyncPoint.h b/ios/Pods/Headers/Private/FirebaseDatabase/FSyncPoint.h new file mode 120000 index 00000000..6fc81d37 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FSyncPoint.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/FSyncPoint.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FSyncTree.h b/ios/Pods/Headers/Private/FirebaseDatabase/FSyncTree.h new file mode 120000 index 00000000..df5bff53 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FSyncTree.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/FSyncTree.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTrackedQuery.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTrackedQuery.h new file mode 120000 index 00000000..ef5c43cf --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTrackedQuery.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Persistence/FTrackedQuery.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTrackedQueryManager.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTrackedQueryManager.h new file mode 120000 index 00000000..fd637a53 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTrackedQueryManager.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Persistence/FTrackedQueryManager.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTransformedEnumerator.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTransformedEnumerator.h new file mode 120000 index 00000000..0b97aafa --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTransformedEnumerator.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/FTransformedEnumerator.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTree.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTree.h new file mode 120000 index 00000000..3b74da50 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTree.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/Utilities/FTree.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTreeNode.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTreeNode.h new file mode 120000 index 00000000..592b5509 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTreeNode.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/Utilities/FTreeNode.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTreeSortedDictionary.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTreeSortedDictionary.h new file mode 120000 index 00000000..9ac1db78 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTreeSortedDictionary.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FTreeSortedDictionary.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTreeSortedDictionaryEnumerator.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTreeSortedDictionaryEnumerator.h new file mode 120000 index 00000000..2302bacf --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTreeSortedDictionaryEnumerator.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FTreeSortedDictionaryEnumerator.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTupleBoolBlock.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleBoolBlock.h new file mode 120000 index 00000000..4556d5b1 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleBoolBlock.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleBoolBlock.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTupleCallbackStatus.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleCallbackStatus.h new file mode 120000 index 00000000..9fe40c80 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleCallbackStatus.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleCallbackStatus.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTupleFirebase.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleFirebase.h new file mode 120000 index 00000000..b6075729 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleFirebase.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleFirebase.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTupleNodePath.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleNodePath.h new file mode 120000 index 00000000..e8bbcb47 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleNodePath.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleNodePath.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTupleObjectNode.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleObjectNode.h new file mode 120000 index 00000000..acf0b468 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleObjectNode.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleObjectNode.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTupleObjects.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleObjects.h new file mode 120000 index 00000000..fcb5e6b7 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleObjects.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleObjects.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTupleOnDisconnect.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleOnDisconnect.h new file mode 120000 index 00000000..828a9ba3 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleOnDisconnect.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleOnDisconnect.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTuplePathValue.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTuplePathValue.h new file mode 120000 index 00000000..b562144c --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTuplePathValue.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTuplePathValue.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTupleRemovedQueriesEvents.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleRemovedQueriesEvents.h new file mode 120000 index 00000000..755025b5 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleRemovedQueriesEvents.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleRemovedQueriesEvents.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTupleSetIdPath.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleSetIdPath.h new file mode 120000 index 00000000..2d562863 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleSetIdPath.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleSetIdPath.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTupleStringNode.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleStringNode.h new file mode 120000 index 00000000..bbfef797 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleStringNode.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleStringNode.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTupleTSN.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleTSN.h new file mode 120000 index 00000000..6a2b49c7 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleTSN.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleTSN.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTupleTransaction.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleTransaction.h new file mode 120000 index 00000000..78ddacd6 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleTransaction.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleTransaction.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTupleUserCallback.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleUserCallback.h new file mode 120000 index 00000000..75a0b4b7 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTupleUserCallback.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Utilities/Tuples/FTupleUserCallback.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTypedefs.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTypedefs.h new file mode 120000 index 00000000..a4a2b833 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTypedefs.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Utilities/FTypedefs.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FTypedefs_Private.h b/ios/Pods/Headers/Private/FirebaseDatabase/FTypedefs_Private.h new file mode 120000 index 00000000..b2ccd832 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FTypedefs_Private.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Api/Private/FTypedefs_Private.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FUtilities.h b/ios/Pods/Headers/Private/FirebaseDatabase/FUtilities.h new file mode 120000 index 00000000..9a98677e --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FUtilities.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Utilities/FUtilities.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FValidation.h b/ios/Pods/Headers/Private/FirebaseDatabase/FValidation.h new file mode 120000 index 00000000..3aa11e28 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FValidation.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Utilities/FValidation.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FValueEventRegistration.h b/ios/Pods/Headers/Private/FirebaseDatabase/FValueEventRegistration.h new file mode 120000 index 00000000..66b211c9 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FValueEventRegistration.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/View/FValueEventRegistration.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FValueIndex.h b/ios/Pods/Headers/Private/FirebaseDatabase/FValueIndex.h new file mode 120000 index 00000000..bee65a99 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FValueIndex.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/FValueIndex.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FView.h b/ios/Pods/Headers/Private/FirebaseDatabase/FView.h new file mode 120000 index 00000000..f54d1906 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FView.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/View/FView.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FViewCache.h b/ios/Pods/Headers/Private/FirebaseDatabase/FViewCache.h new file mode 120000 index 00000000..6a0278e4 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FViewCache.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/View/FViewCache.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FViewProcessor.h b/ios/Pods/Headers/Private/FirebaseDatabase/FViewProcessor.h new file mode 120000 index 00000000..a9658556 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FViewProcessor.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/FViewProcessor.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FViewProcessorResult.h b/ios/Pods/Headers/Private/FirebaseDatabase/FViewProcessorResult.h new file mode 120000 index 00000000..88ddd3a7 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FViewProcessorResult.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/FViewProcessorResult.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FWebSocketConnection.h b/ios/Pods/Headers/Private/FirebaseDatabase/FWebSocketConnection.h new file mode 120000 index 00000000..a6ce12db --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FWebSocketConnection.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Realtime/FWebSocketConnection.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FWriteRecord.h b/ios/Pods/Headers/Private/FirebaseDatabase/FWriteRecord.h new file mode 120000 index 00000000..a3637d6d --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FWriteRecord.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/FWriteRecord.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FWriteTree.h b/ios/Pods/Headers/Private/FirebaseDatabase/FWriteTree.h new file mode 120000 index 00000000..ac116507 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FWriteTree.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/FWriteTree.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FWriteTreeRef.h b/ios/Pods/Headers/Private/FirebaseDatabase/FWriteTreeRef.h new file mode 120000 index 00000000..795b8b75 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FWriteTreeRef.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Core/FWriteTreeRef.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/FirebaseDatabase.h b/ios/Pods/Headers/Private/FirebaseDatabase/FirebaseDatabase.h new file mode 120000 index 00000000..95354d23 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/FirebaseDatabase.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Public/FirebaseDatabase.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/NSData+SRB64Additions.h b/ios/Pods/Headers/Private/FirebaseDatabase/NSData+SRB64Additions.h new file mode 120000 index 00000000..9a783bc9 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/NSData+SRB64Additions.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/third_party/SocketRocket/NSData+SRB64Additions.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseDatabase/fbase64.h b/ios/Pods/Headers/Private/FirebaseDatabase/fbase64.h new file mode 120000 index 00000000..5591a92b --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseDatabase/fbase64.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/third_party/SocketRocket/fbase64.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMMessageCode.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMMessageCode.h new file mode 120000 index 00000000..83e560dd --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMMessageCode.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMMessageCode.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessaging.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessaging.h new file mode 120000 index 00000000..febf8ca1 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessaging.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/Public/FIRMessaging.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingAnalytics.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingAnalytics.h new file mode 120000 index 00000000..e74b9015 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingAnalytics.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingAnalytics.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingCheckinService.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingCheckinService.h new file mode 120000 index 00000000..754397a4 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingCheckinService.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingCheckinService.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingClient.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingClient.h new file mode 120000 index 00000000..4a1033cb --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingClient.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingClient.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingCodedInputStream.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingCodedInputStream.h new file mode 120000 index 00000000..61e8e9bc --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingCodedInputStream.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingCodedInputStream.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingConnection.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingConnection.h new file mode 120000 index 00000000..7f2bffae --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingConnection.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingConnection.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingConstants.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingConstants.h new file mode 120000 index 00000000..1a74de01 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingConstants.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingConstants.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingContextManagerService.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingContextManagerService.h new file mode 120000 index 00000000..2540b8fc --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingContextManagerService.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingContextManagerService.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingDataMessageManager.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingDataMessageManager.h new file mode 120000 index 00000000..ece586ac --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingDataMessageManager.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingDataMessageManager.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingDefines.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingDefines.h new file mode 120000 index 00000000..75cf7d2f --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingDefines.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingDefines.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingDelayedMessageQueue.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingDelayedMessageQueue.h new file mode 120000 index 00000000..a0121f56 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingDelayedMessageQueue.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingDelayedMessageQueue.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingInternalUtilities.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingInternalUtilities.h new file mode 120000 index 00000000..714f0656 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingInternalUtilities.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/InternalHeaders/FIRMessagingInternalUtilities.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingLogger.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingLogger.h new file mode 120000 index 00000000..bab72575 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingLogger.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingLogger.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingPacketQueue.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingPacketQueue.h new file mode 120000 index 00000000..788dc85f --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingPacketQueue.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingPacketQueue.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingPendingTopicsList.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingPendingTopicsList.h new file mode 120000 index 00000000..c934c86c --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingPendingTopicsList.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingPendingTopicsList.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingPersistentSyncMessage.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingPersistentSyncMessage.h new file mode 120000 index 00000000..8d58c5ac --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingPersistentSyncMessage.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingPersistentSyncMessage.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingPubSub.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingPubSub.h new file mode 120000 index 00000000..1a7b18e4 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingPubSub.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingPubSub.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingPubSubRegistrar.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingPubSubRegistrar.h new file mode 120000 index 00000000..c7cfb5b6 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingPubSubRegistrar.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingPubSubRegistrar.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingReceiver.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingReceiver.h new file mode 120000 index 00000000..2390c12a --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingReceiver.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingReceiver.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingRegistrar.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingRegistrar.h new file mode 120000 index 00000000..ad864604 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingRegistrar.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingRegistrar.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingRemoteNotificationsProxy.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingRemoteNotificationsProxy.h new file mode 120000 index 00000000..527482bf --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingRemoteNotificationsProxy.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingRemoteNotificationsProxy.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingRmq2PersistentStore.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingRmq2PersistentStore.h new file mode 120000 index 00000000..8253ca7e --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingRmq2PersistentStore.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingRmq2PersistentStore.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingRmqManager.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingRmqManager.h new file mode 120000 index 00000000..d98c4036 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingRmqManager.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingRmqManager.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingSecureSocket.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingSecureSocket.h new file mode 120000 index 00000000..69bc0817 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingSecureSocket.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingSecureSocket.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingSyncMessageManager.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingSyncMessageManager.h new file mode 120000 index 00000000..5130e940 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingSyncMessageManager.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingSyncMessageManager.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingTopicOperation.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingTopicOperation.h new file mode 120000 index 00000000..effc84d3 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingTopicOperation.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingTopicOperation.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingTopicsCommon.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingTopicsCommon.h new file mode 120000 index 00000000..d86a6ea3 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingTopicsCommon.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingTopicsCommon.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingUtilities.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingUtilities.h new file mode 120000 index 00000000..bd4f44b5 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingUtilities.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingUtilities.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingVersionUtilities.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingVersionUtilities.h new file mode 120000 index 00000000..224998fb --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessagingVersionUtilities.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessagingVersionUtilities.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessaging_Private.h b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessaging_Private.h new file mode 120000 index 00000000..196e1b27 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FIRMessaging_Private.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/FIRMessaging_Private.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/FirebaseMessaging.h b/ios/Pods/Headers/Private/FirebaseMessaging/FirebaseMessaging.h new file mode 120000 index 00000000..cd1c5db2 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/FirebaseMessaging.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/Public/FirebaseMessaging.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/GtalkCore.pbobjc.h b/ios/Pods/Headers/Private/FirebaseMessaging/GtalkCore.pbobjc.h new file mode 120000 index 00000000..0a079bda --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/GtalkCore.pbobjc.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/Protos/GtalkCore.pbobjc.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/GtalkExtensions.pbobjc.h b/ios/Pods/Headers/Private/FirebaseMessaging/GtalkExtensions.pbobjc.h new file mode 120000 index 00000000..e74a93bd --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/GtalkExtensions.pbobjc.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/Protos/GtalkExtensions.pbobjc.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/NSDictionary+FIRMessaging.h b/ios/Pods/Headers/Private/FirebaseMessaging/NSDictionary+FIRMessaging.h new file mode 120000 index 00000000..e8e4ffd2 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/NSDictionary+FIRMessaging.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/NSDictionary+FIRMessaging.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/FirebaseMessaging/NSError+FIRMessaging.h b/ios/Pods/Headers/Private/FirebaseMessaging/NSError+FIRMessaging.h new file mode 120000 index 00000000..eb284740 --- /dev/null +++ b/ios/Pods/Headers/Private/FirebaseMessaging/NSError+FIRMessaging.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/NSError+FIRMessaging.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/arena.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/arena.h new file mode 120000 index 00000000..4b854106 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/arena.h @@ -0,0 +1 @@ +../../../../leveldb-library/util/arena.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/atomic_pointer.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/atomic_pointer.h new file mode 120000 index 00000000..28feddb9 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/atomic_pointer.h @@ -0,0 +1 @@ +../../../../leveldb-library/port/atomic_pointer.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/block.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/block.h new file mode 120000 index 00000000..ef272e55 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/block.h @@ -0,0 +1 @@ +../../../../leveldb-library/table/block.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/block_builder.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/block_builder.h new file mode 120000 index 00000000..7da5fbde --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/block_builder.h @@ -0,0 +1 @@ +../../../../leveldb-library/table/block_builder.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/builder.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/builder.h new file mode 120000 index 00000000..d3263268 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/builder.h @@ -0,0 +1 @@ +../../../../leveldb-library/db/builder.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/c.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/c.h new file mode 120000 index 00000000..684bb4bc --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/c.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/c.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/cache.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/cache.h new file mode 120000 index 00000000..f71b3791 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/cache.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/cache.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/coding.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/coding.h new file mode 120000 index 00000000..c7d012f2 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/coding.h @@ -0,0 +1 @@ +../../../../leveldb-library/util/coding.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/comparator.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/comparator.h new file mode 120000 index 00000000..d092f975 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/comparator.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/comparator.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/crc32c.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/crc32c.h new file mode 120000 index 00000000..eae0a38a --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/crc32c.h @@ -0,0 +1 @@ +../../../../leveldb-library/util/crc32c.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/db.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/db.h new file mode 120000 index 00000000..e68182ac --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/db.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/db.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/db_impl.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/db_impl.h new file mode 120000 index 00000000..cb83ba94 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/db_impl.h @@ -0,0 +1 @@ +../../../../leveldb-library/db/db_impl.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/db_iter.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/db_iter.h new file mode 120000 index 00000000..c363d8a1 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/db_iter.h @@ -0,0 +1 @@ +../../../../leveldb-library/db/db_iter.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/dbformat.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/dbformat.h new file mode 120000 index 00000000..8b0c7103 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/dbformat.h @@ -0,0 +1 @@ +../../../../leveldb-library/db/dbformat.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/dumpfile.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/dumpfile.h new file mode 120000 index 00000000..53b92ee1 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/dumpfile.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/dumpfile.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/env.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/env.h new file mode 120000 index 00000000..655aee31 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/env.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/env.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/env_posix_test_helper.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/env_posix_test_helper.h new file mode 120000 index 00000000..d71ff534 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/env_posix_test_helper.h @@ -0,0 +1 @@ +../../../../leveldb-library/util/env_posix_test_helper.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/filename.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/filename.h new file mode 120000 index 00000000..933f9bdd --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/filename.h @@ -0,0 +1 @@ +../../../../leveldb-library/db/filename.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/filter_block.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/filter_block.h new file mode 120000 index 00000000..10b51125 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/filter_block.h @@ -0,0 +1 @@ +../../../../leveldb-library/table/filter_block.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/filter_policy.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/filter_policy.h new file mode 120000 index 00000000..24bd90c5 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/filter_policy.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/filter_policy.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/format.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/format.h new file mode 120000 index 00000000..205ab1f1 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/format.h @@ -0,0 +1 @@ +../../../../leveldb-library/table/format.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/hash.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/hash.h new file mode 120000 index 00000000..35f623bf --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/hash.h @@ -0,0 +1 @@ +../../../../leveldb-library/util/hash.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/histogram.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/histogram.h new file mode 120000 index 00000000..1a9fe41f --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/histogram.h @@ -0,0 +1 @@ +../../../../leveldb-library/util/histogram.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/iterator.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/iterator.h new file mode 120000 index 00000000..0b79d163 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/iterator.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/iterator.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/iterator_wrapper.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/iterator_wrapper.h new file mode 120000 index 00000000..b2989ced --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/iterator_wrapper.h @@ -0,0 +1 @@ +../../../../leveldb-library/table/iterator_wrapper.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/log_format.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/log_format.h new file mode 120000 index 00000000..fddd431b --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/log_format.h @@ -0,0 +1 @@ +../../../../leveldb-library/db/log_format.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/log_reader.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/log_reader.h new file mode 120000 index 00000000..2bb355c2 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/log_reader.h @@ -0,0 +1 @@ +../../../../leveldb-library/db/log_reader.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/log_writer.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/log_writer.h new file mode 120000 index 00000000..7e4ba4ea --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/log_writer.h @@ -0,0 +1 @@ +../../../../leveldb-library/db/log_writer.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/logging.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/logging.h new file mode 120000 index 00000000..ea1775e2 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/logging.h @@ -0,0 +1 @@ +../../../../leveldb-library/util/logging.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/memtable.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/memtable.h new file mode 120000 index 00000000..15b28fad --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/memtable.h @@ -0,0 +1 @@ +../../../../leveldb-library/db/memtable.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/merger.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/merger.h new file mode 120000 index 00000000..8f50b6bd --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/merger.h @@ -0,0 +1 @@ +../../../../leveldb-library/table/merger.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/mutexlock.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/mutexlock.h new file mode 120000 index 00000000..39084ed4 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/mutexlock.h @@ -0,0 +1 @@ +../../../../leveldb-library/util/mutexlock.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/options.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/options.h new file mode 120000 index 00000000..df730a3c --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/options.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/options.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/port.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/port.h new file mode 120000 index 00000000..4b512ec3 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/port.h @@ -0,0 +1 @@ +../../../../leveldb-library/port/port.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/port_example.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/port_example.h new file mode 120000 index 00000000..af959a2f --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/port_example.h @@ -0,0 +1 @@ +../../../../leveldb-library/port/port_example.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/port_posix.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/port_posix.h new file mode 120000 index 00000000..196cebc8 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/port_posix.h @@ -0,0 +1 @@ +../../../../leveldb-library/port/port_posix.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/posix_logger.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/posix_logger.h new file mode 120000 index 00000000..dbdd71ed --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/posix_logger.h @@ -0,0 +1 @@ +../../../../leveldb-library/util/posix_logger.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/random.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/random.h new file mode 120000 index 00000000..0d5de05b --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/random.h @@ -0,0 +1 @@ +../../../../leveldb-library/util/random.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/skiplist.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/skiplist.h new file mode 120000 index 00000000..d6f87153 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/skiplist.h @@ -0,0 +1 @@ +../../../../leveldb-library/db/skiplist.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/slice.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/slice.h new file mode 120000 index 00000000..1198d033 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/slice.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/slice.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/snapshot.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/snapshot.h new file mode 120000 index 00000000..d2dc0e06 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/snapshot.h @@ -0,0 +1 @@ +../../../../leveldb-library/db/snapshot.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/status.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/status.h new file mode 120000 index 00000000..f0a87b2f --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/status.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/status.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/table.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/table.h new file mode 120000 index 00000000..6951d31c --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/table.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/table.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/table_builder.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/table_builder.h new file mode 120000 index 00000000..e396af91 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/table_builder.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/table_builder.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/table_cache.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/table_cache.h new file mode 120000 index 00000000..1631e7a2 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/table_cache.h @@ -0,0 +1 @@ +../../../../leveldb-library/db/table_cache.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/testharness.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/testharness.h new file mode 120000 index 00000000..faca4c39 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/testharness.h @@ -0,0 +1 @@ +../../../../leveldb-library/util/testharness.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/testutil.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/testutil.h new file mode 120000 index 00000000..bf9b40d1 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/testutil.h @@ -0,0 +1 @@ +../../../../leveldb-library/util/testutil.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/thread_annotations.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/thread_annotations.h new file mode 120000 index 00000000..75e4e079 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/thread_annotations.h @@ -0,0 +1 @@ +../../../../leveldb-library/port/thread_annotations.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/two_level_iterator.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/two_level_iterator.h new file mode 120000 index 00000000..e7f86877 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/two_level_iterator.h @@ -0,0 +1 @@ +../../../../leveldb-library/table/two_level_iterator.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/version_edit.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/version_edit.h new file mode 120000 index 00000000..e1afe515 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/version_edit.h @@ -0,0 +1 @@ +../../../../leveldb-library/db/version_edit.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/version_set.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/version_set.h new file mode 120000 index 00000000..4cb5e227 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/version_set.h @@ -0,0 +1 @@ +../../../../leveldb-library/db/version_set.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/write_batch.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/write_batch.h new file mode 120000 index 00000000..fdc08d62 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/write_batch.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/write_batch.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/leveldb-library/leveldb/write_batch_internal.h b/ios/Pods/Headers/Private/leveldb-library/leveldb/write_batch_internal.h new file mode 120000 index 00000000..fe989628 --- /dev/null +++ b/ios/Pods/Headers/Private/leveldb-library/leveldb/write_batch_internal.h @@ -0,0 +1 @@ +../../../../leveldb-library/db/write_batch_internal.h \ No newline at end of file diff --git a/ios/Pods/Headers/Private/react-native-camera/BarcodeDetectorManagerMlkit.h b/ios/Pods/Headers/Private/react-native-camera/BarcodeDetectorManagerMlkit.h new file mode 120000 index 00000000..cf36f9c7 --- /dev/null +++ b/ios/Pods/Headers/Private/react-native-camera/BarcodeDetectorManagerMlkit.h @@ -0,0 +1 @@ +../../../../../node_modules/react-native-camera/ios/RN/BarcodeDetectorManagerMlkit.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/FirebaseAnalyticsInterop/FIRAnalyticsInterop.h b/ios/Pods/Headers/Public/FirebaseAnalyticsInterop/FIRAnalyticsInterop.h new file mode 120000 index 00000000..e01a43ad --- /dev/null +++ b/ios/Pods/Headers/Public/FirebaseAnalyticsInterop/FIRAnalyticsInterop.h @@ -0,0 +1 @@ +../../../FirebaseAnalyticsInterop/Interop/Analytics/Public/FIRAnalyticsInterop.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/FirebaseAnalyticsInterop/FIRAnalyticsInteropListener.h b/ios/Pods/Headers/Public/FirebaseAnalyticsInterop/FIRAnalyticsInteropListener.h new file mode 120000 index 00000000..d3cd0976 --- /dev/null +++ b/ios/Pods/Headers/Public/FirebaseAnalyticsInterop/FIRAnalyticsInteropListener.h @@ -0,0 +1 @@ +../../../FirebaseAnalyticsInterop/Interop/Analytics/Public/FIRAnalyticsInteropListener.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/FirebaseAnalyticsInterop/FIRInteropEventNames.h b/ios/Pods/Headers/Public/FirebaseAnalyticsInterop/FIRInteropEventNames.h new file mode 120000 index 00000000..dbda3ecc --- /dev/null +++ b/ios/Pods/Headers/Public/FirebaseAnalyticsInterop/FIRInteropEventNames.h @@ -0,0 +1 @@ +../../../FirebaseAnalyticsInterop/Interop/Analytics/Public/FIRInteropEventNames.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/FirebaseAnalyticsInterop/FIRInteropParameterNames.h b/ios/Pods/Headers/Public/FirebaseAnalyticsInterop/FIRInteropParameterNames.h new file mode 120000 index 00000000..51458430 --- /dev/null +++ b/ios/Pods/Headers/Public/FirebaseAnalyticsInterop/FIRInteropParameterNames.h @@ -0,0 +1 @@ +../../../FirebaseAnalyticsInterop/Interop/Analytics/Public/FIRInteropParameterNames.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/FirebaseAuthInterop/FIRAuthInterop.h b/ios/Pods/Headers/Public/FirebaseAuthInterop/FIRAuthInterop.h new file mode 120000 index 00000000..0253e257 --- /dev/null +++ b/ios/Pods/Headers/Public/FirebaseAuthInterop/FIRAuthInterop.h @@ -0,0 +1 @@ +../../../FirebaseAuthInterop/Interop/Auth/Public/FIRAuthInterop.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/FirebaseDatabase/FIRDataEventType.h b/ios/Pods/Headers/Public/FirebaseDatabase/FIRDataEventType.h new file mode 120000 index 00000000..0a5c1089 --- /dev/null +++ b/ios/Pods/Headers/Public/FirebaseDatabase/FIRDataEventType.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Public/FIRDataEventType.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/FirebaseDatabase/FIRDataSnapshot.h b/ios/Pods/Headers/Public/FirebaseDatabase/FIRDataSnapshot.h new file mode 120000 index 00000000..1ca4513b --- /dev/null +++ b/ios/Pods/Headers/Public/FirebaseDatabase/FIRDataSnapshot.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Public/FIRDataSnapshot.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/FirebaseDatabase/FIRDatabase.h b/ios/Pods/Headers/Public/FirebaseDatabase/FIRDatabase.h new file mode 120000 index 00000000..36c8659c --- /dev/null +++ b/ios/Pods/Headers/Public/FirebaseDatabase/FIRDatabase.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Public/FIRDatabase.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/FirebaseDatabase/FIRDatabaseQuery.h b/ios/Pods/Headers/Public/FirebaseDatabase/FIRDatabaseQuery.h new file mode 120000 index 00000000..1c08fe6e --- /dev/null +++ b/ios/Pods/Headers/Public/FirebaseDatabase/FIRDatabaseQuery.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Public/FIRDatabaseQuery.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/FirebaseDatabase/FIRDatabaseReference.h b/ios/Pods/Headers/Public/FirebaseDatabase/FIRDatabaseReference.h new file mode 120000 index 00000000..d2ef3453 --- /dev/null +++ b/ios/Pods/Headers/Public/FirebaseDatabase/FIRDatabaseReference.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Public/FIRDatabaseReference.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/FirebaseDatabase/FIRMutableData.h b/ios/Pods/Headers/Public/FirebaseDatabase/FIRMutableData.h new file mode 120000 index 00000000..19b69a8c --- /dev/null +++ b/ios/Pods/Headers/Public/FirebaseDatabase/FIRMutableData.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Public/FIRMutableData.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/FirebaseDatabase/FIRServerValue.h b/ios/Pods/Headers/Public/FirebaseDatabase/FIRServerValue.h new file mode 120000 index 00000000..9bf59844 --- /dev/null +++ b/ios/Pods/Headers/Public/FirebaseDatabase/FIRServerValue.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Public/FIRServerValue.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/FirebaseDatabase/FIRTransactionResult.h b/ios/Pods/Headers/Public/FirebaseDatabase/FIRTransactionResult.h new file mode 120000 index 00000000..24b6abb0 --- /dev/null +++ b/ios/Pods/Headers/Public/FirebaseDatabase/FIRTransactionResult.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Public/FIRTransactionResult.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/FirebaseDatabase/FirebaseDatabase.h b/ios/Pods/Headers/Public/FirebaseDatabase/FirebaseDatabase.h new file mode 120000 index 00000000..95354d23 --- /dev/null +++ b/ios/Pods/Headers/Public/FirebaseDatabase/FirebaseDatabase.h @@ -0,0 +1 @@ +../../../FirebaseDatabase/Firebase/Database/Public/FirebaseDatabase.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/FirebaseMessaging/FIRMessaging.h b/ios/Pods/Headers/Public/FirebaseMessaging/FIRMessaging.h new file mode 120000 index 00000000..febf8ca1 --- /dev/null +++ b/ios/Pods/Headers/Public/FirebaseMessaging/FIRMessaging.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/Public/FIRMessaging.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/FirebaseMessaging/FirebaseMessaging.h b/ios/Pods/Headers/Public/FirebaseMessaging/FirebaseMessaging.h new file mode 120000 index 00000000..cd1c5db2 --- /dev/null +++ b/ios/Pods/Headers/Public/FirebaseMessaging/FirebaseMessaging.h @@ -0,0 +1 @@ +../../../FirebaseMessaging/Firebase/Messaging/Public/FirebaseMessaging.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/leveldb-library/leveldb/c.h b/ios/Pods/Headers/Public/leveldb-library/leveldb/c.h new file mode 120000 index 00000000..684bb4bc --- /dev/null +++ b/ios/Pods/Headers/Public/leveldb-library/leveldb/c.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/c.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/leveldb-library/leveldb/cache.h b/ios/Pods/Headers/Public/leveldb-library/leveldb/cache.h new file mode 120000 index 00000000..f71b3791 --- /dev/null +++ b/ios/Pods/Headers/Public/leveldb-library/leveldb/cache.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/cache.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/leveldb-library/leveldb/comparator.h b/ios/Pods/Headers/Public/leveldb-library/leveldb/comparator.h new file mode 120000 index 00000000..d092f975 --- /dev/null +++ b/ios/Pods/Headers/Public/leveldb-library/leveldb/comparator.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/comparator.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/leveldb-library/leveldb/db.h b/ios/Pods/Headers/Public/leveldb-library/leveldb/db.h new file mode 120000 index 00000000..e68182ac --- /dev/null +++ b/ios/Pods/Headers/Public/leveldb-library/leveldb/db.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/db.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/leveldb-library/leveldb/dumpfile.h b/ios/Pods/Headers/Public/leveldb-library/leveldb/dumpfile.h new file mode 120000 index 00000000..53b92ee1 --- /dev/null +++ b/ios/Pods/Headers/Public/leveldb-library/leveldb/dumpfile.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/dumpfile.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/leveldb-library/leveldb/env.h b/ios/Pods/Headers/Public/leveldb-library/leveldb/env.h new file mode 120000 index 00000000..655aee31 --- /dev/null +++ b/ios/Pods/Headers/Public/leveldb-library/leveldb/env.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/env.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/leveldb-library/leveldb/filter_policy.h b/ios/Pods/Headers/Public/leveldb-library/leveldb/filter_policy.h new file mode 120000 index 00000000..24bd90c5 --- /dev/null +++ b/ios/Pods/Headers/Public/leveldb-library/leveldb/filter_policy.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/filter_policy.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/leveldb-library/leveldb/iterator.h b/ios/Pods/Headers/Public/leveldb-library/leveldb/iterator.h new file mode 120000 index 00000000..0b79d163 --- /dev/null +++ b/ios/Pods/Headers/Public/leveldb-library/leveldb/iterator.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/iterator.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/leveldb-library/leveldb/options.h b/ios/Pods/Headers/Public/leveldb-library/leveldb/options.h new file mode 120000 index 00000000..df730a3c --- /dev/null +++ b/ios/Pods/Headers/Public/leveldb-library/leveldb/options.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/options.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/leveldb-library/leveldb/slice.h b/ios/Pods/Headers/Public/leveldb-library/leveldb/slice.h new file mode 120000 index 00000000..1198d033 --- /dev/null +++ b/ios/Pods/Headers/Public/leveldb-library/leveldb/slice.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/slice.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/leveldb-library/leveldb/status.h b/ios/Pods/Headers/Public/leveldb-library/leveldb/status.h new file mode 120000 index 00000000..f0a87b2f --- /dev/null +++ b/ios/Pods/Headers/Public/leveldb-library/leveldb/status.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/status.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/leveldb-library/leveldb/table.h b/ios/Pods/Headers/Public/leveldb-library/leveldb/table.h new file mode 120000 index 00000000..6951d31c --- /dev/null +++ b/ios/Pods/Headers/Public/leveldb-library/leveldb/table.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/table.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/leveldb-library/leveldb/table_builder.h b/ios/Pods/Headers/Public/leveldb-library/leveldb/table_builder.h new file mode 120000 index 00000000..e396af91 --- /dev/null +++ b/ios/Pods/Headers/Public/leveldb-library/leveldb/table_builder.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/table_builder.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/leveldb-library/leveldb/write_batch.h b/ios/Pods/Headers/Public/leveldb-library/leveldb/write_batch.h new file mode 120000 index 00000000..fdc08d62 --- /dev/null +++ b/ios/Pods/Headers/Public/leveldb-library/leveldb/write_batch.h @@ -0,0 +1 @@ +../../../../leveldb-library/include/leveldb/write_batch.h \ No newline at end of file diff --git a/ios/Pods/Headers/Public/react-native-camera/BarcodeDetectorManagerMlkit.h b/ios/Pods/Headers/Public/react-native-camera/BarcodeDetectorManagerMlkit.h new file mode 120000 index 00000000..cf36f9c7 --- /dev/null +++ b/ios/Pods/Headers/Public/react-native-camera/BarcodeDetectorManagerMlkit.h @@ -0,0 +1 @@ +../../../../../node_modules/react-native-camera/ios/RN/BarcodeDetectorManagerMlkit.h \ No newline at end of file diff --git a/ios/Pods/Manifest.lock b/ios/Pods/Manifest.lock index 6eded97b..14078ecf 100644 --- a/ios/Pods/Manifest.lock +++ b/ios/Pods/Manifest.lock @@ -11,6 +11,12 @@ PODS: - FirebaseAnalytics (= 5.4.0) - Firebase/CoreOnly (5.15.0): - FirebaseCore (= 5.1.10) + - Firebase/Database (5.15.0): + - Firebase/CoreOnly + - FirebaseDatabase (= 5.0.4) + - Firebase/Messaging (5.15.0): + - Firebase/CoreOnly + - FirebaseMessaging (= 3.2.2) - Firebase/Performance (5.15.0): - Firebase/Core - FirebasePerformance (= 2.2.2) @@ -29,12 +35,25 @@ PODS: - GoogleUtilities/Network (~> 5.2) - "GoogleUtilities/NSData+zlib (~> 5.2)" - nanopb (~> 0.3) + - FirebaseAnalyticsInterop (1.2.0) + - FirebaseAuthInterop (1.0.0) - FirebaseCore (5.1.10): - GoogleUtilities/Logger (~> 5.2) + - FirebaseDatabase (5.0.4): + - FirebaseAuthInterop (~> 1.0) + - FirebaseCore (~> 5.1) + - leveldb-library (~> 1.18) - FirebaseInstanceID (3.3.0): - FirebaseCore (~> 5.1) - GoogleUtilities/Environment (~> 5.3) - GoogleUtilities/UserDefaults (~> 5.3) + - FirebaseMessaging (3.2.2): + - FirebaseAnalyticsInterop (~> 1.1) + - FirebaseCore (~> 5.1) + - FirebaseInstanceID (~> 3.0) + - GoogleUtilities/Environment (~> 5.2) + - GoogleUtilities/Reachability (~> 5.2) + - Protobuf (~> 3.1) - FirebasePerformance (2.2.2): - FirebaseAnalytics (~> 5.4) - FirebaseInstanceID (~> 3.3) @@ -100,6 +119,7 @@ PODS: - GoogleUtilities/UserDefaults (5.5.0): - GoogleUtilities/Logger - GTMSessionFetcher/Core (1.2.1) + - leveldb-library (1.20) - lottie-ios (2.5.3) - lottie-react-native (2.6.0): - lottie-ios @@ -185,6 +205,8 @@ DEPENDENCIES: - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - Fabric (~> 1.7.13) - Firebase/Core (~> 5.15.0) + - Firebase/Database (~> 5.15.0) + - Firebase/Messaging (~> 5.15.0) - Firebase/Performance (~> 5.15.0) - Firebase/RemoteConfig (~> 5.15.0) - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`) @@ -218,8 +240,12 @@ SPEC REPOS: - Firebase - FirebaseABTesting - FirebaseAnalytics + - FirebaseAnalyticsInterop + - FirebaseAuthInterop - FirebaseCore + - FirebaseDatabase - FirebaseInstanceID + - FirebaseMessaging - FirebasePerformance - FirebaseRemoteConfig - GoogleAppMeasurement @@ -227,6 +253,7 @@ SPEC REPOS: - GoogleToolboxForMac - GoogleUtilities - GTMSessionFetcher + - leveldb-library - nanopb - Protobuf @@ -271,8 +298,12 @@ SPEC CHECKSUMS: Firebase: 8bb9268bff82374f2cbaaabb143e725743c316ae FirebaseABTesting: 1f50b8d50f5e3469eea54e7463a7b7fe221d1f5e FirebaseAnalytics: c06f9d70577d79074214700a71fd5d39de5550fb + FirebaseAnalyticsInterop: efbe45c8385ec626e29f9525e5ebd38520dfb6c1 + FirebaseAuthInterop: 0ffa57668be100582bb7643d4fcb7615496c41fc FirebaseCore: 35747502d9e8c6ee217385ad04446c7c2aaf9c5c + FirebaseDatabase: 0621689f77528d62b47e1c06ca737c4c19275d1a FirebaseInstanceID: e2fa4cb35ef5558c200f7f0ad8a53e212215f93e + FirebaseMessaging: b412996f6a09337d232bb3a6676ce4d1f353d024 FirebasePerformance: 6f77b930f982a54ad487d3de5523ce641db9dcc9 FirebaseRemoteConfig: 7e11c65f0769c09bff6947997c209515058c5318 Folly: de497beb10f102453a1afa9edbf8cf8a251890de @@ -282,6 +313,7 @@ SPEC CHECKSUMS: GoogleToolboxForMac: ff31605b7d66400dcec09bed5861689aebadda4d GoogleUtilities: 6481e6318c5fcabaaa8513ef8120f329055d7c10 GTMSessionFetcher: 32aeca0aa144acea523e1c8e053089dec2cb98ca + leveldb-library: 08cba283675b7ed2d99629a4bc5fd052cd2bb6a5 lottie-ios: a50d5c0160425cd4b01b852bb9578963e6d92d31 lottie-react-native: 05b6e2dd502d7a91ff128036c4f0984363e5eb4a nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 @@ -296,6 +328,6 @@ SPEC CHECKSUMS: RNVectorIcons: cb42a5653c046f12ca16c9480c571b52620559e8 yoga: 596e61c9b57751d08a22b07aba310dbd3e65ab75 -PODFILE CHECKSUM: 1bc1c28808f6ea34810ecf744d14fcab22288c99 +PODFILE CHECKSUM: 891466dbe9751910bb3eb1a5d6f7824de1c246e0 COCOAPODS: 1.6.1 diff --git a/ios/Pods/Pods.xcodeproj/project.pbxproj b/ios/Pods/Pods.xcodeproj/project.pbxproj index caacf698..a7809fa6 100644 --- a/ios/Pods/Pods.xcodeproj/project.pbxproj +++ b/ios/Pods/Pods.xcodeproj/project.pbxproj @@ -7,20 +7,54 @@ objects = { /* Begin PBXAggregateTarget section */ - 26ECD05F13D8FDDE98B912F8EAD399E8 /* FirebaseRemoteConfig */ = { + 0AC15EA33F402FC6A1A48C990993D7D8 /* FirebaseAnalytics */ = { isa = PBXAggregateTarget; - buildConfigurationList = 37A37499B53208B363CD87E69D4972FA /* Build configuration list for PBXAggregateTarget "FirebaseRemoteConfig" */; + buildConfigurationList = 839880EBB960216C533B0E7600D3FC94 /* Build configuration list for PBXAggregateTarget "FirebaseAnalytics" */; buildPhases = ( ); dependencies = ( - 8D93D4017D17D15BB6FD52DB84294B1A /* PBXTargetDependency */, - C77D7259D618E484E103939A6001F252 /* PBXTargetDependency */, - 5D5B1FDFFB65E1286288F88B4B96208E /* PBXTargetDependency */, - 9D19122B5E4DE3B9F0DD533BFEAF970B /* PBXTargetDependency */, - 59EAA373AEED2AD2AC1542044F8CA2F9 /* PBXTargetDependency */, - E168D8486AE08C301CC2AD371E592D2F /* PBXTargetDependency */, + 86D889B041F7E595FBAE046CC787D662 /* PBXTargetDependency */, + 41B77CD58647CE1ED96510F606339EE1 /* PBXTargetDependency */, + 4635A0D399850C0AB327AD8AE46ECF55 /* PBXTargetDependency */, + B3CB0C6F9F7940166124069220E93FEB /* PBXTargetDependency */, + 58CE038D1B4AF8508553ABD0DAD6A173 /* PBXTargetDependency */, ); - name = FirebaseRemoteConfig; + name = FirebaseAnalytics; + }; + 148A5443E43AD92241F7EC3C3A5FAF3B /* Firebase */ = { + isa = PBXAggregateTarget; + buildConfigurationList = F8FC7BD0FE07FA52B5E14327BAE47812 /* Build configuration list for PBXAggregateTarget "Firebase" */; + buildPhases = ( + ); + dependencies = ( + DC932B830E97F05F5174FAF92BD025A8 /* PBXTargetDependency */, + 83E92575B51FADF07C66CD5D39E2FFDB /* PBXTargetDependency */, + 2594DD1AAC8CB8733951CEEA880E5855 /* PBXTargetDependency */, + 3F5EB2DB81CDED37B3361BB99E8B7D25 /* PBXTargetDependency */, + 7EE34238BC1AB0CBD9493246BDDDA6EA /* PBXTargetDependency */, + 999CF551F4C68D6E905C34D7F5717F1C /* PBXTargetDependency */, + ); + name = Firebase; + }; + 2BA894431E6D4EC9D0D3602E2A926A36 /* GoogleAppMeasurement */ = { + isa = PBXAggregateTarget; + buildConfigurationList = A6CF3A8813B185C3B8CE38F87E453EF2 /* Build configuration list for PBXAggregateTarget "GoogleAppMeasurement" */; + buildPhases = ( + ); + dependencies = ( + E687E0812D6D93EC05FB13580CC7F7C7 /* PBXTargetDependency */, + 05D410252F22C0FAE3B2D90D3EA3AE19 /* PBXTargetDependency */, + ); + name = GoogleAppMeasurement; + }; + 2BE50E63279FC4B03758C99275E399D2 /* FirebaseAnalyticsInterop */ = { + isa = PBXAggregateTarget; + buildConfigurationList = BD73662F427EC5A0345DF66F2EA85402 /* Build configuration list for PBXAggregateTarget "FirebaseAnalyticsInterop" */; + buildPhases = ( + ); + dependencies = ( + ); + name = FirebaseAnalyticsInterop; }; 2CA9E9CBD6D1591F4833D0AC9A6DE30D /* GoogleSignIn */ = { isa = PBXAggregateTarget; @@ -42,349 +76,445 @@ ); name = "boost-for-react-native"; }; - A3197AFE21F0131BE3A6A49782BC6F1D /* FirebasePerformance */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 70AD7205E7FB4607A09DDA1B7EE7EC24 /* Build configuration list for PBXAggregateTarget "FirebasePerformance" */; - buildPhases = ( - ); - dependencies = ( - 7316EF72C63327D7391753E2FCDB3F10 /* PBXTargetDependency */, - 09F29D433D76449E1E460E4D969BC8FF /* PBXTargetDependency */, - FAB1F60F9F90648DB593BC942CEE0761 /* PBXTargetDependency */, - 535A4AA3D01EC95C3ABB9B71CCD691FD /* PBXTargetDependency */, - 9A91D8F7CA5F7302D8B122AB074DFB5A /* PBXTargetDependency */, - 48C2E7E88B267941E71C0F6F69A30C35 /* PBXTargetDependency */, - 89D37B9A59BA82AF5F8595D46AC525CD /* PBXTargetDependency */, - ); - name = FirebasePerformance; - }; - A341D07F993BE980A2F73FF26D003F2F /* Firebase */ = { + 78D21D148001007DE3F837778E7D27F5 /* FirebaseRemoteConfig */ = { isa = PBXAggregateTarget; - buildConfigurationList = C45A018D550E880DF4572355220CD3D2 /* Build configuration list for PBXAggregateTarget "Firebase" */; + buildConfigurationList = 29DB0BBAA2ADA23C15D8CB495A377BFC /* Build configuration list for PBXAggregateTarget "FirebaseRemoteConfig" */; buildPhases = ( ); dependencies = ( - 1BCB118B4796DF2D048EEFA5CE034DC8 /* PBXTargetDependency */, - EDFD3E09C90F689E147A813155808075 /* PBXTargetDependency */, - 2E6CB9C9BEE70CEE324B4631A17B4E95 /* PBXTargetDependency */, - 018AD128DF54B9AB4618CB18CE2AD2B6 /* PBXTargetDependency */, + D3097443ACB3BCA6B6016D72A9DD1235 /* PBXTargetDependency */, + 645DCB7BB6F21EE93BE79D5CF7FC3798 /* PBXTargetDependency */, + 1C21237929C94F977985F3424B64116F /* PBXTargetDependency */, + 6AC712D73A2EDCD9F14E0AA6CA5C45EE /* PBXTargetDependency */, + CF03569B8CBC70386653392793320C5A /* PBXTargetDependency */, + 9B31EAC729458EF7767C1C47EEDCBED5 /* PBXTargetDependency */, ); - name = Firebase; + name = FirebaseRemoteConfig; }; - A4AC528160CC8177E6EB809461379FF8 /* FirebaseAnalytics */ = { + 7DB3B0B9490B6AF4860CC9317D5F5C54 /* FirebaseInstanceID */ = { isa = PBXAggregateTarget; - buildConfigurationList = E96D4243FCC681D3FA071B6D5798F263 /* Build configuration list for PBXAggregateTarget "FirebaseAnalytics" */; + buildConfigurationList = 830CCE9C964DF67D0354BB888C9803E0 /* Build configuration list for PBXAggregateTarget "FirebaseInstanceID" */; buildPhases = ( ); dependencies = ( - 67C5620B74BC7A70371C9B446ADEE2D6 /* PBXTargetDependency */, - 4B85A8FC745F31ADA349C4A208A245B8 /* PBXTargetDependency */, - D7898D208CB707C9DBF4DA7ACA916832 /* PBXTargetDependency */, - AC7472FB1F5606F13227D95744D8FA35 /* PBXTargetDependency */, - A8505B2488F52D479B8AFA5166E7CA44 /* PBXTargetDependency */, + 97DC854ECC23AE53EED18F23F9EADC75 /* PBXTargetDependency */, + A612A44EE60B08352A5CEE87DB2E224F /* PBXTargetDependency */, ); - name = FirebaseAnalytics; + name = FirebaseInstanceID; }; - ABA9A411BB5A359862E5F1AA6238278E /* Crashlytics */ = { + 9164D8092E2D2FC2BAD1ABCC34521490 /* FirebaseAuthInterop */ = { isa = PBXAggregateTarget; - buildConfigurationList = A084C0089544D8EEE7DA4C6D8EEEF9ED /* Build configuration list for PBXAggregateTarget "Crashlytics" */; + buildConfigurationList = EAB88B5FC09CEDAE7954651F4F6CFEB0 /* Build configuration list for PBXAggregateTarget "FirebaseAuthInterop" */; buildPhases = ( ); dependencies = ( - C9CEFEFAAAEDB8CD947737FA56C849D4 /* PBXTargetDependency */, ); - name = Crashlytics; + name = FirebaseAuthInterop; }; - D35E9EC86D36A4C8BC1704199FDB3552 /* Fabric */ = { + 9E599700D610A70CDFA8E9AFF3FB9AE2 /* FirebasePerformance */ = { isa = PBXAggregateTarget; - buildConfigurationList = 13B185864087F75D556AC109B2D70BF7 /* Build configuration list for PBXAggregateTarget "Fabric" */; + buildConfigurationList = AAE4ACE12E61BAE48883E2516DD8E5B3 /* Build configuration list for PBXAggregateTarget "FirebasePerformance" */; buildPhases = ( ); dependencies = ( + CFAE725E695BE546790E870F8B3C9269 /* PBXTargetDependency */, + F3D771E70B32FE032A491D6EC42853EE /* PBXTargetDependency */, + 63232F8D0E3FD13799CEB0727E503AAE /* PBXTargetDependency */, + EFF89EC6601A5E356A2E6D13D35448D2 /* PBXTargetDependency */, + A23DDF850D4F67A06FFF5AC9BF8180ED /* PBXTargetDependency */, + 7A0059DE399DDF95A59D26EA0E537ADC /* PBXTargetDependency */, + 6050B2D9BA0734929EDD8F226A6BD721 /* PBXTargetDependency */, ); - name = Fabric; + name = FirebasePerformance; }; - F26DF4F6ADD5881D668DF81C6B3F05EF /* FirebaseInstanceID */ = { + ABA9A411BB5A359862E5F1AA6238278E /* Crashlytics */ = { isa = PBXAggregateTarget; - buildConfigurationList = 88FBA1418FAD76E151DAD088BE9DC5E8 /* Build configuration list for PBXAggregateTarget "FirebaseInstanceID" */; + buildConfigurationList = A084C0089544D8EEE7DA4C6D8EEEF9ED /* Build configuration list for PBXAggregateTarget "Crashlytics" */; buildPhases = ( ); dependencies = ( - B53DA27B35439C041D12AB993ED511C0 /* PBXTargetDependency */, - 1198565C7BC08D42BF953DC18F61741A /* PBXTargetDependency */, + C9CEFEFAAAEDB8CD947737FA56C849D4 /* PBXTargetDependency */, ); - name = FirebaseInstanceID; + name = Crashlytics; }; - F5E7779227CE35F03C5E86041DEC7C74 /* FirebaseABTesting */ = { + BCE30BBC689F944FE7A82C1512D6FFA1 /* FirebaseABTesting */ = { isa = PBXAggregateTarget; - buildConfigurationList = A98CB1647FE9647D98BDE52E34408CB7 /* Build configuration list for PBXAggregateTarget "FirebaseABTesting" */; + buildConfigurationList = E2734AACD9F862F58B9602F555C1DDE4 /* Build configuration list for PBXAggregateTarget "FirebaseABTesting" */; buildPhases = ( ); dependencies = ( - 287DE2DFE7610CCAA46FB3E8A3607A06 /* PBXTargetDependency */, - 07161E9C9601B867C9C6C2DAECB48860 /* PBXTargetDependency */, + 99133877B3B0C9462BE1707FEDB62F84 /* PBXTargetDependency */, + 696D3DF9C0C4EFD982048B9F2D49214B /* PBXTargetDependency */, ); name = FirebaseABTesting; }; - F63F26AAC9E12A1E6BDEECB1B662C7E6 /* GoogleAppMeasurement */ = { + D35E9EC86D36A4C8BC1704199FDB3552 /* Fabric */ = { isa = PBXAggregateTarget; - buildConfigurationList = DDD6A75A0001E7B5E52D6A3846D2F551 /* Build configuration list for PBXAggregateTarget "GoogleAppMeasurement" */; + buildConfigurationList = 13B185864087F75D556AC109B2D70BF7 /* Build configuration list for PBXAggregateTarget "Fabric" */; buildPhases = ( ); dependencies = ( - 35375E2BE56388EAD9941BBC63363378 /* PBXTargetDependency */, - 9388F1F23BFADE712C75F5BDEAA06EA0 /* PBXTargetDependency */, ); - name = GoogleAppMeasurement; + name = Fabric; }; /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ 000C62887AA8EC21F26A486AD8B15D09 /* RCTImageSource.h in Headers */ = {isa = PBXBuildFile; fileRef = BFD26887E45894A817B4BC60D0CB1E3B /* RCTImageSource.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 004857B8EDE18599545AEBE6219B39F8 /* FIRComponentType.h in Headers */ = {isa = PBXBuildFile; fileRef = 65996BB673A0A753370E3D489BA11ACE /* FIRComponentType.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 001188D0BA836471873566ACF7DD2C7C /* FImmutableSortedDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = C366C5C59C0D200C6D44A91E9A49FDB2 /* FImmutableSortedDictionary.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0011CF32452744A08A01D5E4095FE13C /* GULNSData+zlib.h in Headers */ = {isa = PBXBuildFile; fileRef = B061BDF4E0105DD15FEB9AB6612DF344 /* GULNSData+zlib.h */; settings = {ATTRIBUTES = (Project, ); }; }; 0049EEEC21CC6351ACF18383A2C9B8C4 /* lottie-ios-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = DF82CE493122706F14660EDC8CDF9C84 /* lottie-ios-dummy.m */; }; - 007E118C317B905A43396B0323494587 /* SafariViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C6BFB18CCE8A1FBE4A3B8FD6C5663A0D /* SafariViewManager.m */; }; - 00FE16F593D07181A9A4934A6ED5DB78 /* Wrappers.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = B9774DBEB2D9E947C193E108F5037DA0 /* Wrappers.pbobjc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 00524A4BD73D6CD43BDF8BF499EE8F56 /* FIRMessagingPacketQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AEDA64FA1B2A882628B31137FD427BB /* FIRMessagingPacketQueue.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 00995FE26D9777744B2D4EAAE882FC2F /* GPBWellKnownTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FFDB73167B848BBBD3E423FFEB9183B /* GPBWellKnownTypes.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 009C4724256981C1B3CB1EFF5A272A2F /* FView.h in Headers */ = {isa = PBXBuildFile; fileRef = BA438D914FD85D28EB649CD0E6157459 /* FView.h */; settings = {ATTRIBUTES = (Project, ); }; }; 012F242E967DD1F0BDC65464302632A9 /* LOTBlockCallback.m in Sources */ = {isa = PBXBuildFile; fileRef = 9593A2908BC72E3DDB3C560BE71A949C /* LOTBlockCallback.m */; }; + 0159458829D14CFA3B1A8EA433536214 /* FirebaseDatabase-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4589D5B88D4AE0FE6E7B2DB709F25865 /* FirebaseDatabase-dummy.m */; }; 01871217D2B992C5540941347CAB52F5 /* RCTBaseTextInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1694A41CC9BF288DDAB1E7DD6BC008F4 /* RCTBaseTextInputView.m */; }; 01992C3F7AD31127EBCD9058C8A4E65D /* LOTNumberInterpolator.m in Sources */ = {isa = PBXBuildFile; fileRef = AE6B99406B524DEF7EEE3CC82DFA539B /* LOTNumberInterpolator.m */; }; 01B61AF5FB0EDF1D5E93E55654DB7986 /* RCTSwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = C0C4B0C05706B38ABFB58518D1AED74E /* RCTSwitch.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 01D1BFCC44E7599E8B23FFA74B47D5DB /* RCTMaskedViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 235BAD3F402C7F6980AB0B120D5F5749 /* RCTMaskedViewManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 01FDBC86ACD349EFE9DF650AD1D7A3B4 /* react-native-camera-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = F8915607A789FA16613C44076588D5A6 /* react-native-camera-dummy.m */; }; 020C96CE2D9A3E23538C87029B88F8F9 /* RCTStyleAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = DDE9BC0483E47986E2389E525E3BC58F /* RCTStyleAnimatedNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; 025F3E374342A4BD20D7BE946D6C3331 /* RCTConvert+ART.h in Headers */ = {isa = PBXBuildFile; fileRef = 902942DCAA5BF1F1B2C9420A980D2C12 /* RCTConvert+ART.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 029D8DB67C00749B223CDAA8A09EB537 /* GtalkExtensions.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = C53BD08965BE33BBC6529816FF16507E /* GtalkExtensions.pbobjc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 02AEAD403501B28009B7828A43103647 /* RCTConvert+Transform.h in Headers */ = {isa = PBXBuildFile; fileRef = 4388312B78481D9F9DDBAF8615F67F6B /* RCTConvert+Transform.h */; settings = {ATTRIBUTES = (Project, ); }; }; 02CB725082BFBF6035AA0C6A4B1C38CF /* RCTLocalAssetImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 49FC27F61E472DA6AA264A341768C1CA /* RCTLocalAssetImageLoader.m */; }; + 02E9B5F5339416091F82BFE526EA3F45 /* GULReachabilityChecker+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 7D639F9D72183C354888805CCE9DD613 /* GULReachabilityChecker+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; 02FAF8E2E62557BB9BE10CCEB5D3E0C5 /* RCTSafeAreaViewLocalData.m in Sources */ = {isa = PBXBuildFile; fileRef = 8474BD3FE2CD0DCBA3CCD8128793F50C /* RCTSafeAreaViewLocalData.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 030F8076C81CA14B3DB825893059A846 /* FQuerySpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C0ECC2192D65619167B3FBDB43CA813 /* FQuerySpec.m */; }; 034CB905165C5579CF8A918D2F7DC16C /* LOTShapeTransform.m in Sources */ = {isa = PBXBuildFile; fileRef = 91538E3BC1356D7766925388D5888A8E /* LOTShapeTransform.m */; }; 03548212866ECEE10321E2B537D26590 /* RCTURLRequestHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 035893E648E8D4E1390D074DE46E9DF5 /* RCTURLRequestHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; 03EE3EAE75088C2A0335332FDA32FBB1 /* RCTActivityIndicatorView.h in Headers */ = {isa = PBXBuildFile; fileRef = D8AC307AEBEBD57D6EE106DF852FD1B3 /* RCTActivityIndicatorView.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0409334A6926A0577CC18E548FEB1CA9 /* RNSensorOrientationChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = FA13E84FE4F3D80FECEA316FDEFBD8E0 /* RNSensorOrientationChecker.m */; }; + 04AAF793E6858B1980475708D9FE5575 /* RNFetchBlobFS.m in Sources */ = {isa = PBXBuildFile; fileRef = F1C3036847AE6AE790A9289D590D4B71 /* RNFetchBlobFS.m */; }; 04E73580F363C580B2CCD02AB33F6559 /* RCTDatePickerManager.h in Headers */ = {isa = PBXBuildFile; fileRef = A06D48ED73D4F7A71C9AF366A8615444 /* RCTDatePickerManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 04E8A137D31C8444BCAB64CF930254E9 /* FIRDatabase.m in Sources */ = {isa = PBXBuildFile; fileRef = BE0D558DC88FD688F6668DFDAF4F95EA /* FIRDatabase.m */; }; 0540DCDC28F676DD70C350803E16152C /* RCTUIManagerObserverCoordinator.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D4E8486775DA51CF4544EDDA527A9FB /* RCTUIManagerObserverCoordinator.h */; settings = {ATTRIBUTES = (Project, ); }; }; 0575F8AF14052169F32EEEC73C908A61 /* RCTDeviceInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0238219549B56954B2991D3B7FC8B44F /* RCTDeviceInfo.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 05ABB5DB0EE4C0DC0ADDAAE49552A11D /* FNamedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 4137D29173DFD982B0C4FBA1F5733874 /* FNamedNode.m */; }; 05B4049347BC6CF3A9DA662F37437B41 /* RCTBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = F67A6E04237958154C561FFB40E4403C /* RCTBridge.h */; settings = {ATTRIBUTES = (Project, ); }; }; 05C24D66BD2BF420BA98972123156172 /* RCTRefreshControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 7172CC433F0674E5B263694B9CA6DD7E /* RCTRefreshControl.h */; settings = {ATTRIBUTES = (Project, ); }; }; 0656ABC70A234ADB25C2EA67BBCBE95E /* LOTCacheProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F6867BAF6A6626200CA74B50E84F1C /* LOTCacheProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 068CDE574D7E1A287ACCAD7BA8842B19 /* GTMSessionUploadFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = B3BB7130EFA148C5F3F281D62152FE76 /* GTMSessionUploadFetcher.m */; }; + 0696C527F29E507C0CFC9F803B3C4842 /* GPBUnknownField.h in Headers */ = {isa = PBXBuildFile; fileRef = C3F1E244988886410F5077DF2A9E5800 /* GPBUnknownField.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 069FA2E77E2E0D5E23854E8CFD038EC1 /* GTMSessionUploadFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = B92D1B13AFFAD16CE0CDDF43FE71D1C0 /* GTMSessionUploadFetcher.m */; }; + 06A7EF5B3E9331AF1E79003C86A960D0 /* GULLoggerLevel.h in Headers */ = {isa = PBXBuildFile; fileRef = BFE57F24EAB84A4526072597675704F6 /* GULLoggerLevel.h */; settings = {ATTRIBUTES = (Project, ); }; }; 073785AC6851B0230680EA893BF251B4 /* RCTImageUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 35495CD4CFD0E68DE646E26EB6FC2197 /* RCTImageUtils.h */; settings = {ATTRIBUTES = (Project, ); }; }; 073E8C9F928BC33EEC2DE664A5392CA6 /* LOTValueInterpolator.m in Sources */ = {isa = PBXBuildFile; fileRef = 746C38297B3157941E3CB81D2061B7B8 /* LOTValueInterpolator.m */; }; + 075B823640D097D7CE649285B25C6FC3 /* crc32c.h in Headers */ = {isa = PBXBuildFile; fileRef = B5B93839F37E7D38E19CAD266E896292 /* crc32c.h */; settings = {ATTRIBUTES = (Project, ); }; }; 076B2FC9318C46B575196423DC33767F /* RCTImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = A3151CCFC8AEC370D96A9FF5E99AE30A /* RCTImageView.m */; }; 0782A68E5863665F63BD56F6F89ACAC1 /* RCTInputAccessoryViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DD1DEBE830AB1AC562BD6CDC1D1BAB3D /* RCTInputAccessoryViewManager.m */; }; + 08107661132F919A5783A9BF4F5A21A7 /* db_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B9028452AA9A0B051DDEE4F315AE9DF /* db_impl.h */; settings = {ATTRIBUTES = (Project, ); }; }; 081731BC41600AE6558759B9AE1DA400 /* RCTImageShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = 11EF6D49F2864C7736EFB76F13566DD6 /* RCTImageShadowView.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 0867C3ADB477C60268F010BC4D231213 /* GULNetworkConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 63BB3BF433240BBBB17DF7E23D9EB8A8 /* GULNetworkConstants.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 086D3C772C96B5C95FCF942E1C180B2B /* FirebaseDatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = CBDB298C041272AF9FAC15943C63BA8E /* FirebaseDatabase.h */; settings = {ATTRIBUTES = (Project, ); }; }; 088D6D4B2655C754BD784C8939778CB6 /* RCTEventEmitter.m in Sources */ = {isa = PBXBuildFile; fileRef = ABD6CA6A8368CF9FD7A49E916DF975EB /* RCTEventEmitter.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 0898F632F058F1EFE747AAE5ABCE184F /* GTMSessionFetcherLogging.m in Sources */ = {isa = PBXBuildFile; fileRef = 02D4C7FEC7F4BD8E48C873E644DC9D4A /* GTMSessionFetcherLogging.m */; }; + 08B33987168B3086891B82A7664AAEE0 /* GTMMethodCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = 2C4CFD22020485822A4E873A26E08CB6 /* GTMMethodCheck.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 08C855353B1708C6A8407A4338406385 /* GULNetworkConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 1129AD0DCBBB3C878FD6D355C2C224A3 /* GULNetworkConstants.h */; settings = {ATTRIBUTES = (Project, ); }; }; 08D415BB8B106D36A1B7DF107B496655 /* JSExecutor.h in Headers */ = {isa = PBXBuildFile; fileRef = 172D5EB5619CDF0C2D83A30BB7941F8B /* JSExecutor.h */; settings = {ATTRIBUTES = (Project, ); }; }; 09425F6801B05067195D4DE2376AEAAE /* RCTWebView.m in Sources */ = {isa = PBXBuildFile; fileRef = E7FE8B992027B999D46A014B9FDEEA03 /* RCTWebView.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 095EBDCAEB6C94C96AEE7913022C8ABB /* pb_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 71A375F95732A94E9172EF330D55C0CA /* pb_common.c */; settings = {COMPILER_FLAGS = "-fno-objc-arc -fno-objc-arc -fno-objc-arc"; }; }; + 095BF194C673E77F513C06B66353E944 /* GULAppDelegateSwizzler_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 1B16B1592C78D9E8DDA420A908C6954A /* GULAppDelegateSwizzler_Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; 0991E1B366DB5A5FB844D91A3C578849 /* RCTNativeAnimatedModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 011B470F82E83CFB2344AE6FD57FA8C8 /* RCTNativeAnimatedModule.m */; }; 099C7B086C736521D230406EF7813100 /* RCTScrollContentViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F63C4E9A272851F08359BC3300FCAAE /* RCTScrollContentViewManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 09AC03ECDABC095638CB230648C7547F /* RNCamera.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F612EEFB18D2E5295A47F69A2FC4A84 /* RNCamera.m */; }; + 09F887B8A75EFA836CF0A7345E593DBE /* GPBProtocolBuffers.h in Headers */ = {isa = PBXBuildFile; fileRef = 76D48846AA16EE2F697709EC13A7DF6D /* GPBProtocolBuffers.h */; settings = {ATTRIBUTES = (Project, ); }; }; 0A79C40A0E87D89AD0E14DFA3367E896 /* RCTSafeAreaView.m in Sources */ = {isa = PBXBuildFile; fileRef = 0AAB35A6F112A270D9EB1C645F5B00E4 /* RCTSafeAreaView.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 0A7B045E48E9CF3D0A0CA567C9B9F30C /* FSnapshotHolder.m in Sources */ = {isa = PBXBuildFile; fileRef = 144C1C9FF805BE562AFDB9A01A69D574 /* FSnapshotHolder.m */; }; + 0A89757B0FBF76C413A8E3538999FADB /* FIRMessagingPubSubRegistrar.m in Sources */ = {isa = PBXBuildFile; fileRef = CAF1EDD6912136DCE34276BEE6DFEB30 /* FIRMessagingPubSubRegistrar.m */; }; + 0A91AE132171522E28AA7D237E11A4F4 /* slice.h in Headers */ = {isa = PBXBuildFile; fileRef = EACA4E5CB47C448ECE5F4211305C3437 /* slice.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0AAA7D1CA7B6EF52251986D3A44E6537 /* FViewCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 2C9BDBDC57900F889A1652635E54DE7B /* FViewCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; 0ACD149CBF7C411F34F4CB1CF7E14F73 /* RCTJavaScriptLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 38495E8EE2C723FE63F1EB3050A903D4 /* RCTJavaScriptLoader.h */; settings = {ATTRIBUTES = (Project, ); }; }; 0AD7AD5391EFF4D26017245AD5DB965F /* RCTMultiplicationAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = E93DDED1E5883AE48D3357AAF653B7C0 /* RCTMultiplicationAnimatedNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; 0ADEBCBACE799739531A7BE194E6C188 /* ARTRadialGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F6F507BDCE092203FD8A96184842EC7 /* ARTRadialGradient.m */; }; 0B06103C4C9B68A5E7537CF60C728099 /* RCTScrollableProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D8ADFD81FE169F7DCB3E6DB3A6B74D4 /* RCTScrollableProtocol.h */; settings = {ATTRIBUTES = (Project, ); }; }; 0B0F8DC8BE6327941FE37E72D0281C98 /* RCTTrackingAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = D689C2A9C4F50181069CCF244E2EB1F1 /* RCTTrackingAnimatedNode.m */; }; 0B2188140FD89ED122BDD7918E52DB89 /* RCTClipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = DC14EB28C512FB412CCFBEF043B47376 /* RCTClipboard.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0B4455F7885D68F6579856B6958FF623 /* FEventRaiser.h in Headers */ = {isa = PBXBuildFile; fileRef = 730C83CA84F8C07C83D086E1EAE7BC63 /* FEventRaiser.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0B45B5BFEF42A5BCAA45EAD37D64BDFD /* FIRTransactionResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 6ADFCB7CEFE52C2088C8DCC32BFE3902 /* FIRTransactionResult.m */; }; 0B89A3DCC42C6A4FF7E176A2D1543154 /* RCTValueAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 2456C921F0E0E039A5DAECBE2F092642 /* RCTValueAnimatedNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0B91DC9A47EE31399E4BD0A8D42002A2 /* RNLongPressHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = ADDD300F9C23E80F3E6FA0782C1F0C57 /* RNLongPressHandler.m */; }; + 0C01793A18AB12735F7F17FE7DB3F6F3 /* mutexlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F86652BE1E34EC9D11383F04A98C4FD /* mutexlock.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0C69A2DA368B7E073F93242C1B3A125C /* GPBCodedInputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B030D409ECDB4FBAC60A0939F910375 /* GPBCodedInputStream.h */; settings = {ATTRIBUTES = (Project, ); }; }; 0CA81DFB09FA5FE6C5962B6FBF572A04 /* LOTShapePath.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D18F7C88E716FB8C7586DF8840E8BB8 /* LOTShapePath.m */; }; 0CBD69CC757676C01860AB363E37DF78 /* RCTView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ABED5AE524DC2C875206C90BEB95684 /* RCTView.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 0CC3E50F57403230BB65498732A2753F /* RCTImageViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 53C6CE5DDBE02AAD3C756D217145641B /* RCTImageViewManager.m */; }; 0CCB24E088279F4CB97DC16D51F15245 /* LOTRoundedRectAnimator.m in Sources */ = {isa = PBXBuildFile; fileRef = 48E42E5379BC970766D176AA774BFDF8 /* LOTRoundedRectAnimator.m */; }; 0CDAA696F34FBF56440FA4F54E94B56A /* LOTPolygonAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = ECA4372C1B73E7D2DEB673F27E1AD867 /* LOTPolygonAnimator.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0D0552E9454F72CAAC4909DB11D66FAB /* RNFlingHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = E3D5A9D903C12622C9CFCDEF85AC1D32 /* RNFlingHandler.m */; }; 0D2EFC238972A3381AF75E141BB36507 /* RCTDevSettings.mm in Sources */ = {isa = PBXBuildFile; fileRef = EEE2B8341F386A304E1D877D53429953 /* RCTDevSettings.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 0DE9224FB0065B4509C6FA2B110C8660 /* Struct.pbobjc.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CF91E718BB25941178A5127B828D618 /* Struct.pbobjc.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0D346DEE3F2D9E165178E52003603F8F /* pb_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = A942DB8E6AD6323C241EC1569B908905 /* pb_decode.c */; settings = {COMPILER_FLAGS = "-fno-objc-arc -fno-objc-arc"; }; }; + 0D4563105FA05EAA82C5AE9CE75184D1 /* GPBDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F285B33466F8251D8487BB461AB15F3 /* GPBDictionary.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 0D88059BBAE92AB7E5AB70AB318CAA18 /* FirebaseMessaging.h in Headers */ = {isa = PBXBuildFile; fileRef = D80263157FFBEC750D3C4CBC0AA270E9 /* FirebaseMessaging.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0D9617148957D504733A57A44D3E019C /* FTupleCallbackStatus.m in Sources */ = {isa = PBXBuildFile; fileRef = B5D74D035F6118E5350D969D8DD10787 /* FTupleCallbackStatus.m */; }; + 0DE2F2D90178477FF721B7B4E4E0DAC4 /* FTupleOnDisconnect.h in Headers */ = {isa = PBXBuildFile; fileRef = 3953E080065D0ACBDC5447B414FF10C2 /* FTupleOnDisconnect.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0E051C49EE13199602B2B1B98DFAE133 /* RNFaceDetectorModuleMLKit.m in Sources */ = {isa = PBXBuildFile; fileRef = A96DF853EEF2E09A81C89D05EAAD8DB3 /* RNFaceDetectorModuleMLKit.m */; }; 0E08BD5279D63FA4D500A19DBE05CA3A /* RCTStyleAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = E151C4A87A591916C85752DA200BAC8A /* RCTStyleAnimatedNode.m */; }; + 0E718ADDB309A4D725F1F0BA572CBE25 /* table_builder.cc in Sources */ = {isa = PBXBuildFile; fileRef = 0ACE077C74B38A36472A73C30A541918 /* table_builder.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; 0E7733FDA4A998BBB37F0D77EBA946BF /* RCTWebSocketModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E7C51EC374729EE211BBA611F49F336 /* RCTWebSocketModule.m */; }; - 0E8D1C8FA1FEDB2271AA08A9B6D25315 /* GULAppDelegateSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = 81D34BCF7098CC66628D279837360686 /* GULAppDelegateSwizzler.m */; }; + 0E8934A02077C627F15C1B729DC97875 /* FaceDetectorManagerMlkit.m in Sources */ = {isa = PBXBuildFile; fileRef = E359D5293ABB8AD5A47B80B900B8A49D /* FaceDetectorManagerMlkit.m */; }; 0EDBC02495B64B4C5277E71DA011241C /* RCTI18nUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = B6FB979B8E4C2388378AB967B13FFFAC /* RCTI18nUtil.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 0EE792D067B7B13B06BE0B12D8CDB0A8 /* FIRConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E9C5CEDA8D77EA5BEE7FD692986F180 /* FIRConfiguration.m */; }; + 0F296A8EC38AC89695FEF3CA94A40740 /* FTupleFirebase.h in Headers */ = {isa = PBXBuildFile; fileRef = C617F0D38F777ED4CD1074CC93AC327F /* FTupleFirebase.h */; settings = {ATTRIBUTES = (Project, ); }; }; 0F2C10850AB93B4DA8BA498F1FA500C3 /* RCTInputAccessoryViewContent.m in Sources */ = {isa = PBXBuildFile; fileRef = 49CC0613AA6BD518F8981EF0D7DAED34 /* RCTInputAccessoryViewContent.m */; }; + 0F5074B1FF0192FA923D054896E77DC5 /* FIRVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = FAD876CD7B0231BB382CA6A4D0C971CD /* FIRVersion.m */; }; 0FAB4B533A196089E15665AA6516C02B /* RCTNetworkTask.h in Headers */ = {isa = PBXBuildFile; fileRef = A16C9C5E95A7854C71E34B8CC45BDFF8 /* RCTNetworkTask.h */; settings = {ATTRIBUTES = (Project, ); }; }; 0FABE115E1FAA012EB1A0E6869B42618 /* RCTLog.mm in Sources */ = {isa = PBXBuildFile; fileRef = C145BBEC6B510D44E5BF73963BC1DB2C /* RCTLog.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 0FEBE9A14339DBE846CFC3D98A9A4199 /* RCTModalHostViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 95A88BC6BAA8776332E800F6D8721343 /* RCTModalHostViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 10460236D60311486446A80694169AF2 /* SafariViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E34E8B54127EF1453E32E98C6B4B7AC /* SafariViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1004C59ED1BCAF2EBD0CB48E6964B4CC /* GULObjectSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = 935E381EBEF80577BC49C958FCE8C692 /* GULObjectSwizzler.m */; }; + 1021C3D91117F52FF297BC2AC3DE6302 /* FServerValues.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC945B959C11D5210263BD057197540 /* FServerValues.h */; settings = {ATTRIBUTES = (Project, ); }; }; 108384B15FA518D5A87256A799349019 /* UIView+React.m in Sources */ = {isa = PBXBuildFile; fileRef = 6DE1B9AFB3278317A61AC8A3D1318116 /* UIView+React.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 108E4098DEE3991E30A2DBBBBEF882B5 /* GPBDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = E7A74FC9AFF395322FB8D818AE4F9D48 /* GPBDictionary.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 10DFED34F69F7B4A2F58B3E3163A8C03 /* RNFetchBlobNetwork.m in Sources */ = {isa = PBXBuildFile; fileRef = 591CF78596852D81B2F664FA10F1DE9A /* RNFetchBlobNetwork.m */; }; + 10A4C4727FF43B561E26E7D56F08258D /* GPBExtensionRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 82FA54919C73D72F5F91E7FCEE74C2C0 /* GPBExtensionRegistry.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 10FCB3538633CFC2D1500D3C8FC76704 /* histogram.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9AAC04F3C3C444DC723AADB405F3C67C /* histogram.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; 111CCF27F416FA0178A8F3DD88586AAF /* JSBigString.h in Headers */ = {isa = PBXBuildFile; fileRef = 9FB8CC10DA53B32F313CDFA6046DDD7C /* JSBigString.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 113C0EDD61CA125B8B7FE574D5B67090 /* Api.pbobjc.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F686A439382FEEAB83044D57C61F0BB /* Api.pbobjc.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 114F9980661E4556B75B3388E0AD3F99 /* RNGestureHandlerRegistry.m in Sources */ = {isa = PBXBuildFile; fileRef = AF28386D4445A464FEEEC4A5F0DCEA17 /* RNGestureHandlerRegistry.m */; }; + 114204960494253B286F8D20B70266B6 /* hash.cc in Sources */ = {isa = PBXBuildFile; fileRef = 6B79CE92D4AF98478243B547ADFD51D0 /* hash.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; 1179F2E4CD4EE773F874EE8186FAEF64 /* RCTSurfaceRootShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = E0EE6767A427B04C976BDF008A52966B /* RCTSurfaceRootShadowView.h */; settings = {ATTRIBUTES = (Project, ); }; }; 11B7C18CC67E4C8BF2E1849474E97240 /* JSCExecutorFactory.mm in Sources */ = {isa = PBXBuildFile; fileRef = BFA9B121FEB246D503568A770F36E532 /* JSCExecutorFactory.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 12B204418A4F449FDE8B0F5D89895058 /* RCTActivityIndicatorViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4682CCFAFBB7EE666C6D02FE68F65401 /* RCTActivityIndicatorViewManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 12CFF38B5448CF452A6BEC3F88BD3AEE /* RNFetchBlobConst.h in Headers */ = {isa = PBXBuildFile; fileRef = 43250E80F4D3221A309BBA5C8E20BDB1 /* RNFetchBlobConst.h */; settings = {ATTRIBUTES = (Project, ); }; }; 12DD2FB4BCE938C1333055D9F1972688 /* RCTPerfMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E8C5436E24B27D30B420D1BA26753F1 /* RCTPerfMonitor.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 12EC7DAF67FC0E786517D5AD0B5E3510 /* RCTSurfaceView.h in Headers */ = {isa = PBXBuildFile; fileRef = 42664DE328C63EC3EDAE283C7D004071 /* RCTSurfaceView.h */; settings = {ATTRIBUTES = (Project, ); }; }; 13AE41EAB0AB31ABE357C9323C4E070C /* RCTCxxConvert.h in Headers */ = {isa = PBXBuildFile; fileRef = B90C4CD68F9CF6F0AE47AF3FBBDCB56C /* RCTCxxConvert.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 13AF2917A2AB285530C898D19FD5FBE1 /* Api.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 028C667A4E60B8920C74DACF0139CC88 /* Api.pbobjc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 13AF5AD842F58512B398A9B8414D0A32 /* RCTRootViewDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CD4338A67811F27EBC676D4033AF8B3 /* RCTRootViewDelegate.h */; settings = {ATTRIBUTES = (Project, ); }; }; 13C030BA54375AB043A7EA473777F139 /* LOTValueInterpolator.h in Headers */ = {isa = PBXBuildFile; fileRef = 7F1ADA74AFB453A777F528BA5F7F7468 /* LOTValueInterpolator.h */; settings = {ATTRIBUTES = (Project, ); }; }; 142974ABAAB485B660E033015A9D7139 /* RCTSurfaceHostingProxyRootView.mm in Sources */ = {isa = PBXBuildFile; fileRef = B14617709A54F5147344A857FBB2E9D6 /* RCTSurfaceHostingProxyRootView.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 1440BA308E9797088BBF23DFC408DE4A /* FListenProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = C1333FF3A02E8CA49BE65FB8FF1428E5 /* FListenProvider.m */; }; 146F2EA433CBD055F13DFF9F0CE40D74 /* RCTNativeModule.h in Headers */ = {isa = PBXBuildFile; fileRef = F8B1315482E2B07E77A91A0B03CB097D /* RCTNativeModule.h */; settings = {ATTRIBUTES = (Project, ); }; }; 14888A069834DA229753C62EAD438B3A /* RCTTextShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = DA7D0824629AFA21266D58546B4060DD /* RCTTextShadowView.m */; }; - 14977F123A5E35A34F257F2D3E24C824 /* GPBCodedOutputStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 704B5D61B511B65AB42B8159854ECBDE /* GPBCodedOutputStream.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 148F2F17B90BD20BB3214D2015A932F9 /* pb_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 4598E8CE21EEF42BE2584DBA6FCC11F1 /* pb_common.c */; settings = {COMPILER_FLAGS = "-fno-objc-arc -fno-objc-arc -fno-objc-arc"; }; }; + 14BF6ABD26C32F3D61A2707A47AA6B7F /* FTreeSortedDictionaryEnumerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 88DA4130826C456894E35ED6F53A4D9A /* FTreeSortedDictionaryEnumerator.m */; }; + 151C3271555C04869065F339810D3BED /* FIRMessagingConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = A665F0DDA5C86811B182E51C100CDCF7 /* FIRMessagingConnection.m */; }; 15349F5B49093ADF744C94257F241A41 /* RCTWebView.h in Headers */ = {isa = PBXBuildFile; fileRef = 73DE396839B80A6D9E338FA2F4AA80EC /* RCTWebView.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1547A4F603CBDB19B6918781F981CE8A /* FKeyIndex.m in Sources */ = {isa = PBXBuildFile; fileRef = 93B301CFF46AAB8D6D41C82A86DE1A2A /* FKeyIndex.m */; }; 154E5B258616F7A4ADF9FEC168C28B37 /* LOTLayerGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C3A734717549F61A45D9CAEAC709831 /* LOTLayerGroup.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 15A8AE0D52B3F5431BE47EF807164724 /* GPBArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 399AC2DD582FFA867EB3094A2FEC06A8 /* GPBArray.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 164EE20DD3472D199CA907077EFC3B4E /* RNNativeViewHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = AA89CDE0FD215108668B065F3BED453C /* RNNativeViewHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 16C2EC1C79E63B085BAD83B784154F89 /* GULOriginalIMPConvenienceMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = CE3D896360348ACE18C7BE4C77761091 /* GULOriginalIMPConvenienceMacros.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 171A1852B622F0A4CF7B26D389A3B375 /* GTMDebugSelectorValidation.h in Headers */ = {isa = PBXBuildFile; fileRef = 8C5D15A4DAED2F19F5A7B895AB07A872 /* GTMDebugSelectorValidation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 15FAC076EB77082E0006FEA13452D038 /* FTupleSetIdPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 9FD16AF9100342B1DCBB284920DDBEF5 /* FTupleSetIdPath.m */; }; + 17040698C0915D3AC6CBF28AE5C4C954 /* FSyncTree.h in Headers */ = {isa = PBXBuildFile; fileRef = 32739C50B1DCE959A410D8A13BD08B65 /* FSyncTree.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1727F9AB5EF9BFBBF0BB453CAC47C9E1 /* FPruneForest.m in Sources */ = {isa = PBXBuildFile; fileRef = A6CAB22B865E3D2DEA28B76B1E77BCFF /* FPruneForest.m */; }; 17D1480B362AB88DF5D9FF8FFB3B5E02 /* RCTI18nManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CCEEAB6761BA5986ADBE5CE1BBAD587D /* RCTI18nManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 17D94CD958531668B5323D9914BF061A /* repair.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7C72A21DB02B0FE24C7B1C441D3578B3 /* repair.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; 17FF5BA329F0A6241A77D52515DA6C51 /* RCTModuloAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 043F58F0BC6657E6FFD848D846718A8D /* RCTModuloAnimatedNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; 18057778B3ADE6CD9CC66C8F40F46292 /* Lottie.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DB8E3BD18F14DBDD15023DD16FC07C2 /* Lottie.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1812C91DC3F6586CAA95E92062597183 /* Type.pbobjc.h in Headers */ = {isa = PBXBuildFile; fileRef = 72E8E663A36070B6BA67A8E45D47C26F /* Type.pbobjc.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 186B094077809BB3D792926C9C16D775 /* FAtomicNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DEED99E085D1569EA7AF45E36DD03C1 /* FAtomicNumber.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 188243E3312D6924AF123B4D341BB5C0 /* FIndexedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 75A798E6C1AE8376F578BA0C0673F141 /* FIndexedNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 18882D0352FCC080F7927A00273D3BE0 /* GPBRuntimeTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 475AF4973905C1161DF33535253E26E6 /* GPBRuntimeTypes.h */; settings = {ATTRIBUTES = (Project, ); }; }; 188FEA26D0678B20138FE519D03B28FC /* LOTFillRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 662601B35F66B249DD7CB800FEFE040B /* LOTFillRenderer.m */; }; + 18A85D77D01E2916D9DC8E1A31B3B248 /* FStringUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = DE87533E945892A7B9EAA2C43279E3BF /* FStringUtilities.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 18DE3C2DFCB0573F8FC35223B2B6FBB0 /* FTransformedEnumerator.m in Sources */ = {isa = PBXBuildFile; fileRef = C57306D422BD4BF9E19EED1B89FD40C9 /* FTransformedEnumerator.m */; }; + 18F2FD00D44717B5A30D767A9B256C54 /* FIRBundleUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 7701718429F3F21BDCC1DD3131B9B39F /* FIRBundleUtil.m */; }; + 191D5454A6E5D2656B0505996BC20951 /* Duration.pbobjc.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BAA5361695A82FAF3A98A1C9DC2CD8B /* Duration.pbobjc.h */; settings = {ATTRIBUTES = (Project, ); }; }; 192CACB7DADBA06A838ABC77A5BC362B /* RCTSinglelineTextInputViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 78D2D129E82ACFC0468F93DD0C5D49E3 /* RCTSinglelineTextInputViewManager.m */; }; + 193BE72EBD47A2564D35213C6CD52C4D /* Any.pbobjc.h in Headers */ = {isa = PBXBuildFile; fileRef = A77A71A83A721E62043AB541BFEBF0BD /* Any.pbobjc.h */; settings = {ATTRIBUTES = (Project, ); }; }; 1984DCC1774647A41EC687DB0C8ECC19 /* RCTBlobManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 52DD891097E8BA881AA45ECCD08088A6 /* RCTBlobManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 199AEA2471224188FFFA9F144985A735 /* FIRMessagingRegistrar.m in Sources */ = {isa = PBXBuildFile; fileRef = A39D995E238A995FA07E6668EF4C51AB /* FIRMessagingRegistrar.m */; }; 19CF097544503430406C6252E42CF389 /* ARTShape.m in Sources */ = {isa = PBXBuildFile; fileRef = 35FFD27CEADB92D4B72AE5754CF4E05C /* ARTShape.m */; }; 19DBB50D9EE13BCC5645BC28452BC0C9 /* ARTGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 45EF49A6E479AD5B1B6C64EB4DDBF874 /* ARTGroup.h */; settings = {ATTRIBUTES = (Project, ); }; }; 1A0C37762EC2A040A04E1111A059350A /* RCTAutoInsetsProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 371AA013D82181933B52A942BBEC2174 /* RCTAutoInsetsProtocol.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 1B4299D321967434C09434EAFA59E8E1 /* GPBArray_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B60BC65335FEDFB242BAED10AA3B0BC /* GPBArray_PackagePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1B14A0F2C1FBF67F2F46A65BD2579B27 /* FChange.m in Sources */ = {isa = PBXBuildFile; fileRef = C123255B885108F4B59D313E39CD20E4 /* FChange.m */; }; + 1B5743AF9FB72E6F0FB5E3C5D5F9F870 /* FTupleSetIdPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 1476F8352701355D37CB650E82139B98 /* FTupleSetIdPath.h */; settings = {ATTRIBUTES = (Project, ); }; }; 1B75E125CE6A960748E87E64E130C82F /* ARTSurfaceView.m in Sources */ = {isa = PBXBuildFile; fileRef = B1CC0A71DEA435BB7C60D76EFBF14248 /* ARTSurfaceView.m */; }; + 1B833AE3DC0C944C3EA54E9E892DA95E /* FView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7C3BEB5634C1BC4486799C71640690D6 /* FView.m */; }; 1BA550DAFF918ABA887829107F51296A /* RCTModuleData.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2BC8CC3B0192881ADDEAC70313F213FA /* RCTModuleData.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 1BB162F77EF07D456CA73F81879435C9 /* GTMSessionFetcherService.m in Sources */ = {isa = PBXBuildFile; fileRef = 261886C1CC9C635DF4D09F766A9EBBE3 /* GTMSessionFetcherService.m */; }; + 1BF3DE02228F77902B5CA540EF143AD0 /* RNFetchBlobProgress.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D0B242D922F068B949ED9BC7E5AF629 /* RNFetchBlobProgress.m */; }; 1C35A730F11E1F1343E6359C349B62E0 /* RCTExceptionsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 17412BADE8F69566EF2B3D7BD9D21787 /* RCTExceptionsManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 1CB3549EC6011B45D5E83E7168669E5B /* pb_encode.c in Sources */ = {isa = PBXBuildFile; fileRef = F60E4721AAEABB1566B683C2D1B0A722 /* pb_encode.c */; settings = {COMPILER_FLAGS = "-fno-objc-arc -fno-objc-arc"; }; }; 1CDD8ECC52295F506B6D9A3C6E4FFF4F /* RCTAppState.m in Sources */ = {isa = PBXBuildFile; fileRef = D9C5641A4035540750DE5ECE63ED0CB1 /* RCTAppState.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 1CFAD9AF0B74C36771BF9BF93E7C7620 /* RCTInterpolationAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D18619374F6081A171C233D549F9D25 /* RCTInterpolationAnimatedNode.m */; }; 1CFC2371290B8BD5E4566758CC7DA106 /* JSDeltaBundleClient.h in Headers */ = {isa = PBXBuildFile; fileRef = ADEA670AC3587B44335EF35185F3C745 /* JSDeltaBundleClient.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 1D240A1529A2347A227BE4E7F552A355 /* Wrappers.pbobjc.h in Headers */ = {isa = PBXBuildFile; fileRef = BEFB98ED37598B87DC7616F39F161E8A /* Wrappers.pbobjc.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1D3AB4D4C2FA8CA7CCD0A08F4605CCB8 /* GULNetworkMessageCode.h in Headers */ = {isa = PBXBuildFile; fileRef = F03D781B2B4396C3C5745B1E5FEE04F5 /* GULNetworkMessageCode.h */; settings = {ATTRIBUTES = (Project, ); }; }; 1D3B9071939F00C79C9D88EAF268CC6D /* RCTShadowView+Internal.m in Sources */ = {isa = PBXBuildFile; fileRef = 3029D9FF7387BF6ABDE35AF4DD5469E4 /* RCTShadowView+Internal.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 1D7867B6EEB1DA95D0B6FA8FA1DFA384 /* RNFetchBlob.m in Sources */ = {isa = PBXBuildFile; fileRef = 03134ABA53AC736F9AC253EEC0A88AAB /* RNFetchBlob.m */; }; - 1D906B4694503ED48E3C565168422D39 /* GPBExtensionRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E1AA42D2B4DF27E096A2A733289CC42 /* GPBExtensionRegistry.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 1D9E84720F3503DDC25EB251006D50D6 /* Duration.pbobjc.h in Headers */ = {isa = PBXBuildFile; fileRef = 03652FC81BBDDC08F924DD4287DCFEC6 /* Duration.pbobjc.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1E0B2798AE38AA61EBC4FB25B6E01E01 /* RNFetchBlobConst.h in Headers */ = {isa = PBXBuildFile; fileRef = 43250E80F4D3221A309BBA5C8E20BDB1 /* RNFetchBlobConst.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1E384510921E92BE4AE5D961C7CCD7B3 /* FEventEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 853A62F813D5F154B1F1D222597065EB /* FEventEmitter.h */; settings = {ATTRIBUTES = (Project, ); }; }; 1E7EBABB0CE2EF6A57ECC8425A7DB327 /* LOTAnimationView.h in Headers */ = {isa = PBXBuildFile; fileRef = A571698B140D2045C589CBDEC0B09070 /* LOTAnimationView.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 1EA23D98EF3033B9D92C6A049FB43B6E /* GULLoggerLevel.h in Headers */ = {isa = PBXBuildFile; fileRef = BF207081B235EAF25864BC44066D2241 /* GULLoggerLevel.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1EA43B701259453AF35BF6528CBB82EE /* GPBCodedOutputStream.m in Sources */ = {isa = PBXBuildFile; fileRef = C22E4B37DB39B1245A7FF8D0A8222744 /* GPBCodedOutputStream.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 1F12ABB2EF706FB82D6B828AA46C5200 /* dumpfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 96B9292A43AC1761995175652F0BC87F /* dumpfile.h */; settings = {ATTRIBUTES = (Project, ); }; }; 1F425E9EA8ACAE79BDA1374DB7B8317B /* RCTI18nManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF454C04DA1216A56083477BA983262 /* RCTI18nManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1F47120BCD4D42AD10B01FEA3746F6EC /* coding.cc in Sources */ = {isa = PBXBuildFile; fileRef = 0F85A824A43BC24616CE7831CCFD7D77 /* coding.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; 1F5768D24B6A9A4C9EA0EEDA2620F6E1 /* RCTEventAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 850283C157E5D032508633B279DA10CD /* RCTEventAnimation.m */; }; - 1F80AB1E53B51BF7375739FF445BABBB /* RNGestureHandlerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D1E099506200348C65A2B01768F6FD4 /* RNGestureHandlerManager.m */; }; - 207672B473D80D3BB473D689023943B1 /* GPBExtensionInternals.h in Headers */ = {isa = PBXBuildFile; fileRef = 164E6AF71FDF857751A56340FCE1685E /* GPBExtensionInternals.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 207E0800765ECFFD3065835C90326C25 /* TextDetectorManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 0ECBC79B539E0CBD03F0D17495CA692C /* TextDetectorManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 208FCE8574FEB129B0C7A3D98B64C6DF /* GPBWireFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = F871A85C400F1341FCAE2E2DA33F26A3 /* GPBWireFormat.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 20B58413A50E7A7BE8872A76559ED5C2 /* GULNetwork.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4FC0A27C51B191972D727F7307D153 /* GULNetwork.m */; }; 20C4A616D70D24D993F35FD856B1B451 /* RCTLayoutAnimationGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A7B4C8C1C211CB2B2CCF8D70D9F7657 /* RCTLayoutAnimationGroup.h */; settings = {ATTRIBUTES = (Project, ); }; }; 20F6B2226C5625241B2B72FF964FDC59 /* RCTEventDispatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EE3AE0D79C2E0FE35D0BBAC95FB44F6 /* RCTEventDispatcher.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 2101ADD4BE9BB8463CADE84D4DB0D43F /* skiplist.h in Headers */ = {isa = PBXBuildFile; fileRef = 61795D140D90B3C7C2D348BBCC2A1DCF /* skiplist.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2145EC543EEACB3896B9867CEDB67CF9 /* FirebaseCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 818CA10F0216169E08402403FE90A012 /* FirebaseCore.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 218EC1E5AF8FC694688B4CEC4DCEFF6C /* RNCSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BD8A8817272444480B1B5B3B82FCC0D /* RNCSlider.m */; }; 21919254E4CEF377126FE2978020495F /* RCTBaseTextInputView.h in Headers */ = {isa = PBXBuildFile; fileRef = 2810B05EDC88C0ECB243160CD785B8A2 /* RCTBaseTextInputView.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 21C3FE327FEC922CDCF4B5B18EA09616 /* GPBWellKnownTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D82596297034CEA5B5479350D457747 /* GPBWellKnownTypes.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 221B644D1156D99799E72B8C958FE0FE /* FIRDatabaseConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 069F69FA97FDBC1655FD5690EA59DD94 /* FIRDatabaseConfig.m */; }; 22501093CA1F341F0C89D0F01A6387E1 /* ModuleRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3132C81E876E07E8E9B087ED105368CB /* ModuleRegistry.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 227CD4B18468A8431BC8F1830803C24D /* FIRAppAssociationRegistration.h in Headers */ = {isa = PBXBuildFile; fileRef = 6781CB7C70AB4EDC507A148480C7AD47 /* FIRAppAssociationRegistration.h */; settings = {ATTRIBUTES = (Project, ); }; }; 22DF5A408BEAB16CCFEEE7486A30A446 /* RCTConvert.m in Sources */ = {isa = PBXBuildFile; fileRef = 770284D939D902153C769176860C45DB /* RCTConvert.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 232CF4EF020A06B3A59A76684729C5FF /* FTupleCallbackStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = F63A293B954058E9A1379E8390D0C7B6 /* FTupleCallbackStatus.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 232E6518F7E1415E4A10289578423A39 /* Empty.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 55DD4835B21EDEF4C6BE39AE65FCA9A1 /* Empty.pbobjc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 233DA7B060879665428FACCA0BBA4ED9 /* RCTScrollContentViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = DA77C554B6351B86284E6A920E22FE4D /* RCTScrollContentViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2369FD32F05C8B6E8E7A38E7A3C5E8C1 /* FQueryParams.m in Sources */ = {isa = PBXBuildFile; fileRef = 51997ADB54C73F1CCA356B77B57555FA /* FQueryParams.m */; }; 237E16F0B814CD337B55CFDEB7CE8F8E /* RCTCxxBridgeDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 7D87E2A23446FFBC78001A489DEE8F70 /* RCTCxxBridgeDelegate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 239CF33B941EEB056E5C79A6FF11C5D0 /* FieldMask.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 3CF3157877D482C5AE976CC59518658E /* FieldMask.pbobjc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 23A4E683032333EE32F946DDA76A996D /* RCTInputAccessoryShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3666410D49626387A684F88995E542A4 /* RCTInputAccessoryShadowView.m */; }; 23BAAE809A846DF40D3CD90CE11A8611 /* RCTAccessibilityManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 051B8725AFBE993F63BF537AF698E39C /* RCTAccessibilityManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 23E05F69FA6772C85935F67EC707A13C /* RNLongPressHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = ADDD300F9C23E80F3E6FA0782C1F0C57 /* RNLongPressHandler.m */; }; + 23CAFDB472EC21390E69FD9F4DF5A7D6 /* FTree.h in Headers */ = {isa = PBXBuildFile; fileRef = CD98D934A6013CA6873D3813A714C304 /* FTree.h */; settings = {ATTRIBUTES = (Project, ); }; }; 23F59032B4616DF2E864576A1D562B28 /* RCTModalHostView.h in Headers */ = {isa = PBXBuildFile; fileRef = 36FA96CCD99684D69DA24C66A94FAE26 /* RCTModalHostView.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 23FB3862929BD283B99647F9D6E17D2F /* FIRApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 76D068BBF9B8EF1509782F606D5D2EF4 /* FIRApp.m */; }; + 241CC3B9355E06FA8C2752303C0D4E63 /* Api.pbobjc.h in Headers */ = {isa = PBXBuildFile; fileRef = F0858362C8895095E93E26625A443E27 /* Api.pbobjc.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 241ED6AA650FA0791AB94707CAF01F85 /* RCTSensorOrientationChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = 19FA7CC6598EE44D9CB7C787C69C4DBA /* RCTSensorOrientationChecker.m */; }; 2456EB3E2BF5464837CFA58B018C3EDD /* RCTObjcExecutor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C07FEF5E885A590D9947B8369748384 /* RCTObjcExecutor.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 2464DAABE8CCF40279CD91607BD7987E /* RCTInspector.mm in Sources */ = {isa = PBXBuildFile; fileRef = EBC50A3EF1A294BC9614C7451E2C961C /* RCTInspector.mm */; }; - 24B768F9FFB3410C9DFD4C97980FD3C6 /* Type.pbobjc.h in Headers */ = {isa = PBXBuildFile; fileRef = E56AB81FDD4BA5BC1152795983E34F3A /* Type.pbobjc.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 246B3D05A4326EF92EE37093A856CEFF /* block.h in Headers */ = {isa = PBXBuildFile; fileRef = 8AB83D79B3A65995AB528E4FB67F4DD8 /* block.h */; settings = {ATTRIBUTES = (Project, ); }; }; 24E69B01ED4721CD7DF024995C8B471B /* LRNAnimationViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = F9D719AD374E2180C209CC012653A45E /* LRNAnimationViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 2538CED3FB87DD98C18AD8344919F830 /* logging.cc in Sources */ = {isa = PBXBuildFile; fileRef = 46B7B4C6643F5C8189C5AA84D4591DA3 /* logging.cc */; }; + 251FCDD9F6CA1898D30BBB128BE7F5A7 /* pb_encode.c in Sources */ = {isa = PBXBuildFile; fileRef = 9FCAC1368EA1D0FB6A21074E4FFC222B /* pb_encode.c */; settings = {COMPILER_FLAGS = "-fno-objc-arc -fno-objc-arc"; }; }; + 2538CED3FB87DD98C18AD8344919F830 /* logging.cc in Sources */ = {isa = PBXBuildFile; fileRef = 601F5DDAD74761C1B8AA0BC62A59E2A0 /* logging.cc */; }; 254454344EC131C400B89F0B4EF89CAD /* LOTAsset.m in Sources */ = {isa = PBXBuildFile; fileRef = 48BE908F97E50EA448532A3A42C775D2 /* LOTAsset.m */; }; 258082F11B57F8DB01E65F44FB5B5E61 /* LOTShapeRepeater.m in Sources */ = {isa = PBXBuildFile; fileRef = 20C7D73E95CAB00F07FE116FFFD90D9A /* LOTShapeRepeater.m */; }; + 25AF7086425AC0343EA8F2D9EFF017C5 /* FIRMessagingUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E900875CB45B56E0BAE6568D0A5B66C /* FIRMessagingUtilities.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 25CF94A936991B3B5AA0F8279597737C /* FPathIndex.h in Headers */ = {isa = PBXBuildFile; fileRef = 89B9B60415B01CC3F624C6526B96677F /* FPathIndex.h */; settings = {ATTRIBUTES = (Project, ); }; }; 25E86EB8D2EC7133313632982EB3D07A /* RCTBorderDrawing.h in Headers */ = {isa = PBXBuildFile; fileRef = 94C9A54F15F62482D7C2F32220C15EFA /* RCTBorderDrawing.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 2659574A75E1EE6FFB6DC653DADE782C /* TextDetectorManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 0ECBC79B539E0CBD03F0D17495CA692C /* TextDetectorManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 25F9965077A811A694FC91D9DD09A6CC /* FIRMutableData.m in Sources */ = {isa = PBXBuildFile; fileRef = A5B1383C5CFB90D1E20E9E29C80E511F /* FIRMutableData.m */; }; + 26811A6DC72238AE718CFFC9444C136C /* FIRMessagingRegistrar.h in Headers */ = {isa = PBXBuildFile; fileRef = 80F654ED8096D8AD505DCFEDE99BA1E1 /* FIRMessagingRegistrar.h */; settings = {ATTRIBUTES = (Project, ); }; }; 26A7CC5815439685C49C4A0035425EC8 /* RCTScrollContentShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = E6E7317A7357055148E89C58A8192CE6 /* RCTScrollContentShadowView.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 26ADD4EBFF1CF170D6746F8B618CD048 /* ieee.h in Headers */ = {isa = PBXBuildFile; fileRef = FC71BAE9376FD74FA6A63D5734A674EE /* ieee.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 26B047ACB81197765A84D35A1198CD44 /* utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = B1681002ADBD3BB27EBF6CCCBB750356 /* utilities.cc */; }; + 26ADD4EBFF1CF170D6746F8B618CD048 /* ieee.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CBD2C6F54A33026F16AD69A95A2FB37 /* ieee.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 26B047ACB81197765A84D35A1198CD44 /* utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 0A53EF276FBFF04D58AA684821959964 /* utilities.cc */; }; 26F8870C3138A14FAF1C80329FF593E3 /* RCTSinglelineTextInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = E23706952480CA0B42056D4023ABC152 /* RCTSinglelineTextInputView.m */; }; + 270E0EF9748250FCD58DECBDD5C6905C /* FIRMessagingReceiver.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D94706E0AD7230685EFD7FAC0869FDF /* FIRMessagingReceiver.m */; }; 2722482669EF63C64EEFC6663324C30D /* Yoga-internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 55E881E02479E741E5834F96FABD6491 /* Yoga-internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 277036B0E193297222AE3A6E9B117D03 /* GPBExtensionInternals.m in Sources */ = {isa = PBXBuildFile; fileRef = 94F478DC9FFEB03F60B3A9D8CAB4F8E6 /* GPBExtensionInternals.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 272899E3496F2E6562AFE9D6C392E24F /* FIRComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = 69934098D004769DEF801CB253392E29 /* FIRComponent.m */; }; + 274312D3351FD48B5CD8882E96BCF66E /* GULSwizzledObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 582EC301F15AA66B4997BA389F1C7B4A /* GULSwizzledObject.m */; }; + 275FA198743DEFD6FFBA6784AF8C31E3 /* FTuplePathValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 356D1F2C7C8203EA4BA904A0766E18B5 /* FTuplePathValue.h */; settings = {ATTRIBUTES = (Project, ); }; }; 2773828271A50EF6353B7C06AA7F412A /* RCTKeyCommands.h in Headers */ = {isa = PBXBuildFile; fileRef = B6B07643917C9FF00A76C2B091742CF4 /* RCTKeyCommands.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 279C92D7F5977844581A912C3A82D7C8 /* FWriteRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = A8CFE27B14FB420A8984CD394175B732 /* FWriteRecord.m */; }; + 27CD829C76EE93608A0A1F2040C37F03 /* hash.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DB773AEC4E2516504AB580F796DF2E2 /* hash.h */; settings = {ATTRIBUTES = (Project, ); }; }; 2838CF04D301E7CF4C7CC49C573F7083 /* RCTAppState.h in Headers */ = {isa = PBXBuildFile; fileRef = 67115196505F73C72E5AF2C379B60B6C /* RCTAppState.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 28A4B31405FE402DEED1CC0A9FF0B97E /* Api.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = A2FC2BDCA6C193274FC35FEFE7B968A3 /* Api.pbobjc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 284CCD4E7E54160A6FD950F88F7347C9 /* FIRMessagingConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 42DA9DA5A3D5DB14678F48C2A1FDC942 /* FIRMessagingConstants.m */; }; + 28A8990B7D5AB27B1CB0E0AFF738911B /* FPruneForest.h in Headers */ = {isa = PBXBuildFile; fileRef = 7D9EF1FEC57661FEDFEEE115CE240A13 /* FPruneForest.h */; settings = {ATTRIBUTES = (Project, ); }; }; 28CCB282F9B6FF62E49915D59208A0B4 /* LOTAnimationTransitionController.h in Headers */ = {isa = PBXBuildFile; fileRef = 79063DC172B9F714478327954C1A07E3 /* LOTAnimationTransitionController.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 28CCEA986134061B7478F0FD6F5D7FE6 /* GPBCodedInputStream.m in Sources */ = {isa = PBXBuildFile; fileRef = B6EF56F996D239DC5D0F14C3E7E83114 /* GPBCodedInputStream.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 28FF9EC018218B5FD951CCA81E31463E /* RCTTouchHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = EEDEA875DCFFD65E21FAE42E0B036184 /* RCTTouchHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 29B53D72A2C474743F36D0C986CAF507 /* FIRBundleUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = F8CF17E734F32CD73EEC467FCE9A45B5 /* FIRBundleUtil.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2901BD41C8E6A6945C6C665E0A2D1011 /* GTMSessionFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 9677C666B33082D8B27E6DCD72A275C6 /* GTMSessionFetcher.m */; }; + 293BB08CC9F5E499DF00A4C55F84853A /* FTupleRemovedQueriesEvents.m in Sources */ = {isa = PBXBuildFile; fileRef = F9968FB8B37B6F7C4652AFC5FE159D74 /* FTupleRemovedQueriesEvents.m */; }; 29D22ABD2452CDCDE9E7D3A8D4D9CD07 /* LOTHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 4504FA11559835ADFAB0362A2D32DCA2 /* LOTHelpers.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 29DD921BB3B17D7968BE6C8BD2E5683D /* GPBMessage_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A6DF6B5FABFF927C45202CE34C54F6A /* GPBMessage_PackagePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 2A1D2B93CB186F017A34FCBE34D42678 /* FIRAppAssociationRegistration.m in Sources */ = {isa = PBXBuildFile; fileRef = ECB0BC7C084D6EF921C6A0DDFE303A52 /* FIRAppAssociationRegistration.m */; }; - 2AA1ACD56287D3AFC270EB76B734A008 /* Any.pbobjc.h in Headers */ = {isa = PBXBuildFile; fileRef = A7528D347E330AA90943C4E0F75EFF1B /* Any.pbobjc.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 2AA8F4AA0CB1F2038BE6D15B1877D1D1 /* RNTapHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 56F9D4CFBB73958CA564E272FA0824BF /* RNTapHandler.m */; }; + 2A162E30FA787CADB18AAD34F8B634C3 /* RNGestureHandlerModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 49FD4AA449D624ED888B9D3357AE7BEB /* RNGestureHandlerModule.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2A1ADB3FDC4BA6F24D817AC296FB0C10 /* FImmutableSortedSet.m in Sources */ = {isa = PBXBuildFile; fileRef = 09624EE7B259BADAF0F1FAD4F0A753D3 /* FImmutableSortedSet.m */; }; + 2A2736C2800E5A5B4E4D155DCF489D37 /* FParsedUrl.m in Sources */ = {isa = PBXBuildFile; fileRef = FED414C1C4109A5CE0652D6F306AE7DE /* FParsedUrl.m */; }; + 2A2E881958263C4D97B8CEBDE00C551A /* FArraySortedDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C7270A700555CE0EA21EFB5C5B0554F /* FArraySortedDictionary.h */; settings = {ATTRIBUTES = (Project, ); }; }; 2AD6B37B259C3F4D7253892F6E140332 /* RCTLayoutAnimationGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 340145309578C08B4F2AE4B56488E2C8 /* RCTLayoutAnimationGroup.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 2AF2E394BA7A6C2AD7D2D45E5638F52B /* RNFetchBlobProgress.h in Headers */ = {isa = PBXBuildFile; fileRef = B2526A953CFDECE87D286CB079F7960B /* RNFetchBlobProgress.h */; settings = {ATTRIBUTES = (Project, ); }; }; 2B003C99EB6E9C56F866F6088B3737D8 /* RCTLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 61665E98CEAAF6108E6E006F554A0FEF /* RCTLog.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2B209181F6867B90173C48D8DA4738A1 /* FTree.m in Sources */ = {isa = PBXBuildFile; fileRef = 02282D73DD284911333138BCA9E63E33 /* FTree.m */; }; 2B2992782B552E41F8777D273A1B4ED4 /* RCTFileRequestHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA88A1A5C7F06D89072A77D1A214D236 /* RCTFileRequestHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; 2B3418BC45F4179F6CDCBF5571A3B213 /* RCTModuleData.h in Headers */ = {isa = PBXBuildFile; fileRef = BF82EF2FF5E8C12B2AA4472A4D67D160 /* RCTModuleData.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2BA2DCDA1319BDE4AD47C6E68DBCA2EE /* FIRDatabaseQuery_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8ABD9D96C5ED0354122B80F70AB70E3F /* FIRDatabaseQuery_Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; 2BB97E0FEBA7C1E70D7158C4A178BA9C /* RCTAlertManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 7273E0B4CC9DF12BD919BFFEF50247D1 /* RCTAlertManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 2BEF55E6297B28DD21909106260A2093 /* ARTLinearGradient.h in Headers */ = {isa = PBXBuildFile; fileRef = 9454F36934883700BC69C2C908D8BD2F /* ARTLinearGradient.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2C10884E9CB2D15FB8D82FD6212124EC /* table.cc in Sources */ = {isa = PBXBuildFile; fileRef = D05298160C882B143B7DDF778A6A6B75 /* table.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; 2C11D4CFAFF1516BB74EF8EA2AD51759 /* RCTReloadCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 53F8B831111D7B588BA378D2308369F8 /* RCTReloadCommand.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 2C29E7D93E37272F07A3F6F9C941B37E /* GULAppDelegateSwizzler.h in Headers */ = {isa = PBXBuildFile; fileRef = 856D59AAC88A0EAB2C54480479C7B899 /* GULAppDelegateSwizzler.h */; settings = {ATTRIBUTES = (Project, ); }; }; 2C417AF90947662455F656050A111306 /* RCTRawTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FC2012E3882666B87D01CA152D8CBC14 /* RCTRawTextViewManager.m */; }; 2C4244D9C23123499C6B1741F8DAC497 /* YGLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 922BB5774C0CF4980FF7F28D6021F078 /* YGLayout.cpp */; settings = {COMPILER_FLAGS = "-fno-omit-frame-pointer -fexceptions -Wall -Werror -std=c++1y -fPIC -fno-objc-arc"; }; }; - 2C5B58A5F6F1224217140FD062483195 /* Type.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = EC02BD47C323C6CDD736A555CCC513D3 /* Type.pbobjc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 2C6E5916078A6BDA81B1C36219AD96F6 /* LOTColorInterpolator.h in Headers */ = {isa = PBXBuildFile; fileRef = E1EC351B241B1D7BB7F5979FFD3C290B /* LOTColorInterpolator.h */; settings = {ATTRIBUTES = (Project, ); }; }; 2C7C7F150A9AD57760A89AA6C2ED31B6 /* RCTConvert+Text.m in Sources */ = {isa = PBXBuildFile; fileRef = 00F5A6FE3E4851D6A2E58851F7E0A1F2 /* RCTConvert+Text.m */; }; 2C8BD8D5D6731E167FB801C409B735D2 /* JSDeltaBundleClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DBDF8CC32DA3BACA4FFD1D938B0FFDDB /* JSDeltaBundleClient.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 2CB7DA6A77C07E2F009CA3F6D092B0F4 /* FIRMessagingDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 986EF17779F9AA5EA7576D1E5564003F /* FIRMessagingDefines.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2CBD8BE0A15525C01B09F025049A7754 /* pb.h in Headers */ = {isa = PBXBuildFile; fileRef = 53CAB80B48147C3FF98B40A65850F078 /* pb.h */; settings = {ATTRIBUTES = (Project, ); }; }; 2CFD559486A0D2962A8D2064D09B7203 /* RCTTextSelection.h in Headers */ = {isa = PBXBuildFile; fileRef = E03F85C41E15C8E7D8436A1BF14EDE22 /* RCTTextSelection.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 2D663B3BD9E834E0CEE84C0B27E7B2EB /* GULAppDelegateSwizzler_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 2504EFA7DAA884BEBB3493C7C31EFF2B /* GULAppDelegateSwizzler_Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 2DCAF7457114793D0E53E38156244CA0 /* RNNativeViewHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 885E29EDFA78D83E21A10B4B902FB800 /* RNNativeViewHandler.m */; }; + 2D0D9D1833FF1CD8204BA750B7E7FDA6 /* FWriteTreeRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 4026413238A48D0FEA34D02E3F2C199C /* FWriteTreeRef.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2D9DA1F064A6F9183E41D386ECFA2CF9 /* FLLRBNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 799504110AB087904080B91819637656 /* FLLRBNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; 2DF56CAE7005EC14AA9694A7FD176738 /* RAMBundleRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = EAADC4D064CA1481CB53F01353DB5B93 /* RAMBundleRegistry.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 2ECC13E56257E81D9694C2BA2E7FF665 /* bignum.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CEB3711F4BDB27DF244600A105B2363 /* bignum.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 2ED0AF5ED5618ECAC7B02F71D3ABEE76 /* RCTFont+FA5.h in Headers */ = {isa = PBXBuildFile; fileRef = 43023DF2386FBE3F4BBBCB542912D016 /* RCTFont+FA5.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 2EF1508AA88B71C7D1A6A5489D329A2E /* FieldMask.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 045BD9EED41E317E0FD863E5D64EA5B7 /* FieldMask.pbobjc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 2E08983E01CEBC7DA9BD2F2DB38118C6 /* two_level_iterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 838388E76F01CCA24EB0680BAA345E6A /* two_level_iterator.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2E8C8CE8EF6685EC0DDE0CC252C74B5C /* GPBMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 886DE47956E22373CFBD2E91672FDC4B /* GPBMessage.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 2EB78E8A354A22EB6E0423B6D3289D4A /* builder.h in Headers */ = {isa = PBXBuildFile; fileRef = 295F4B225E8825FB9DDBD005632C9CCF /* builder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2ECC13E56257E81D9694C2BA2E7FF665 /* bignum.h in Headers */ = {isa = PBXBuildFile; fileRef = 0903408DDF7F8C3AD3752EB1503C160E /* bignum.h */; settings = {ATTRIBUTES = (Project, ); }; }; 2F4FE9618A1A4536ED9494982E93A1FA /* RCTI18nUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = BBE863A5A18F7C2BAFE03967B327F6B9 /* RCTI18nUtil.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 301C0484261C3C6F06E70FCADA7B4522 /* ARTSolidColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 63BC6BDA2D77D8120D508A54DC9A0E93 /* ARTSolidColor.m */; }; 3021356B0A818260790A527E849BE261 /* RCTShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = D02AC7026BFA6B0D78EA32C56D5DC6AD /* RCTShadowView.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 30BF73B5445EC0CDD63F7B5B17367C90 /* FIRVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = 359ED3EAF36B84F77497C0D3990E3302 /* FIRVersion.m */; }; + 303EA23E33C62D6F6714E4C5AC18D089 /* GULMutableDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = E8B6F15CA218EE2C13727952245B8088 /* GULMutableDictionary.h */; settings = {ATTRIBUTES = (Project, ); }; }; 31023FD01E760995058EA7DE892C9E45 /* RCTSliderManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F1E6835B8412BDC741BEB45C61EE2115 /* RCTSliderManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 31067DBA182F6CE40FD002EC9BBE520B /* fixed-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8790B8A241F3149E10155D2A2A1BDA12 /* fixed-dtoa.cc */; }; + 31067DBA182F6CE40FD002EC9BBE520B /* fixed-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = 6A8046567CE04F8DFE9CEEE8A4C16012 /* fixed-dtoa.cc */; }; + 314459A22255D1631C8B25518409552C /* FTupleNodePath.h in Headers */ = {isa = PBXBuildFile; fileRef = 1B4644B43D841F176E86CB3561348D33 /* FTupleNodePath.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 315254F10E03F63817A00CB588025963 /* FIRTransactionResult_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 79A7987DF3C0A779E751CAF23BB69165 /* FIRTransactionResult_Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; 3155811A4EEF7CB014614B8CE0588B10 /* LOTAsset.h in Headers */ = {isa = PBXBuildFile; fileRef = BAA66F78FD1BB2023BC7506B6B680E6E /* LOTAsset.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 31587B819DFDFA7BD0272A791452C77E /* testutil.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2FF32C8A293A79D640DB5B9A70792DA8 /* testutil.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; 3159CBD4BC51A915E03F2A60E54EE5CB /* RCTMultiplicationAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 28158453CB780AD8FF755BDB8FDDA7D3 /* RCTMultiplicationAnimatedNode.m */; }; 31919089CB00B4385E498BF79FE4517C /* RCTAssert.h in Headers */ = {isa = PBXBuildFile; fileRef = A2B6C34F2F2C31419BA7F710BAD6948F /* RCTAssert.h */; settings = {ATTRIBUTES = (Project, ); }; }; 31A50940E6E2E6CE5353AEBA8C440B23 /* JSIDynamic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8C80E4172C72EF5A2E25B2F4B0056D3 /* JSIDynamic.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 31E3581D6EDB39E36F2A6DF5BE18E188 /* RCTNetworking.h in Headers */ = {isa = PBXBuildFile; fileRef = 877F832D478F7EE34256387B7ADC18DD /* RCTNetworking.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 31EF41C0572F951A5F47BE1C9BF51C93 /* FIROptions.m in Sources */ = {isa = PBXBuildFile; fileRef = E8016487FDE2099DD54389EA7B3BCEFB /* FIROptions.m */; }; 320BFA51D49E76D8605F5C96DC16460C /* LOTShapeGradientFill.m in Sources */ = {isa = PBXBuildFile; fileRef = 9AAFA074082E4A3256D5E78B820DCE71 /* LOTShapeGradientFill.m */; }; 3211607B69D451A15DC7DD7501DB8BB7 /* RCTSafeAreaViewLocalData.h in Headers */ = {isa = PBXBuildFile; fileRef = 684B1E3E8888CA9F33E3E278102D9069 /* RCTSafeAreaViewLocalData.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 324D272F5FBD1A1506DB7F33CF64785E /* FIRMessagingLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 459829D2EDDEE906B8986B8464589100 /* FIRMessagingLogger.m */; }; + 326B23F4C1E82E9D0D97C4FE2A7E1FC8 /* port_example.h in Headers */ = {isa = PBXBuildFile; fileRef = 829DE110A8990FA98FC7334454C7D389 /* port_example.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 326D51784FA6FC7A8CC96AABE8E6B1BB /* RNCAsyncStorageDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = E9F98E76BEE8F0638C877D1134193645 /* RNCAsyncStorageDelegate.h */; settings = {ATTRIBUTES = (Project, ); }; }; 32B241562DA2A98F902528ACC1014D47 /* YGStyle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF60CAE211EC3F73A3B88CD598800AD4 /* YGStyle.cpp */; settings = {COMPILER_FLAGS = "-fno-omit-frame-pointer -fexceptions -Wall -Werror -std=c++1y -fPIC -fno-objc-arc"; }; }; 32C7AF7CC08C9461F9965D74BE5AE455 /* JSINativeModules.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8814F242551E04EFE362687AD2EAE8E6 /* JSINativeModules.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 33EC8769B51683B6F95C78985880D5A8 /* IOS7Polyfill.h in Headers */ = {isa = PBXBuildFile; fileRef = 6097374DA5B371540FA9C83AFB1A3A25 /* IOS7Polyfill.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 341CEC20DEC87BE5AE1E6317E9A56461 /* GPBUnknownField.m in Sources */ = {isa = PBXBuildFile; fileRef = CC009AD3A6FC5280653B1AFEFB598776 /* GPBUnknownField.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 3422558EA4A5C9764EAB85B0BDD36FFF /* FIRComponentContainerInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 81728A50D2944B4CA77790DAB5A0AC3D /* FIRComponentContainerInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 338CBB9B5FFE6FD9D15FA7D3EBA194B8 /* FPendingPut.h in Headers */ = {isa = PBXBuildFile; fileRef = 86DF92D9A6B37877E72691BB0096A0D6 /* FPendingPut.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 33FC737D99CB664F8469C2EF22AB6401 /* FIRMessagingUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = CAAB05F190C3DDA01DBEB8EA8DF57C01 /* FIRMessagingUtilities.m */; }; 342A1A326F103F1F55BBE21E00690F1D /* RCTEventAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = FD5B10A2640382AB59C65D8DADBB5AAC /* RCTEventAnimation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3453BF0E9C9C70124FE45009C2C1251F /* env.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3CCD6F717B705096084DE94D831AD5DC /* env.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; 34B246EA112307242F81A8F7B1DA123F /* RCTShadowView+Layout.h in Headers */ = {isa = PBXBuildFile; fileRef = 95F6C360D03CD57ADA63299BC3F41F0F /* RCTShadowView+Layout.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 3532F3DAB77B7B0B94415EBEF72D586D /* GULLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 2233E91FFBE6CBACEFCB81BD57B1B34D /* GULLogger.m */; }; + 34CE447F524A02F5FCF1B0093165D006 /* FConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 712659E6D3CA9427726A4CF0C0A5A952 /* FConnection.m */; }; + 351F5D91B1D126A2ADFC663C4E8E53EC /* FClock.m in Sources */ = {isa = PBXBuildFile; fileRef = AA83A1F88B9D90E1ECE2A9C296AF07B5 /* FClock.m */; }; + 352EF04332383EFC0A46A4B84DE11FAD /* FIRDataSnapshot.h in Headers */ = {isa = PBXBuildFile; fileRef = DDDC4F8A35BB39296300F5DE8F18F98C /* FIRDataSnapshot.h */; settings = {ATTRIBUTES = (Project, ); }; }; 353B4FD77CCE8651AEB03486F382D67D /* LOTShapeTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = F452B1DDF4232583FAF44BE85A7E9017 /* LOTShapeTransform.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 35587A5C06858B72C0737165795394A0 /* FIRMessagingLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 065D8744D7CD01032E24ABBA1ACAFC3E /* FIRMessagingLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; 35665AFC6EEB2978CB21B2D736201F22 /* RCTBridgeModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 6134C8480EA154992E8DD8FD4A7ABFB3 /* RCTBridgeModule.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 358DE74C846604DA87BB2A091C689BB5 /* RNFlingHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = E3D5A9D903C12622C9CFCDEF85AC1D32 /* RNFlingHandler.m */; }; - 35A691609E2C8E3C7CAEF04062D4E7D5 /* rn-fetch-blob-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = C3277A54607788C1F851C3A4076FCA8A /* rn-fetch-blob-dummy.m */; }; 35B74329CD18C93833A14F99702C2DA2 /* RCTMaskedView.m in Sources */ = {isa = PBXBuildFile; fileRef = 0581DF1C5E0B29F30F31EC180A7D9249 /* RCTMaskedView.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 35C1670ED33D110EE7F218369F07625D /* GPBExtensionRegistry.m in Sources */ = {isa = PBXBuildFile; fileRef = 018DA0CED90F3227330B1E4C36E30D39 /* GPBExtensionRegistry.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 35C98A64FF0B4F956CEF46F98CCE751F /* RCTCxxModule.h in Headers */ = {isa = PBXBuildFile; fileRef = C8BE936BA747B4B181EF4159DBE88139 /* RCTCxxModule.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 35EBF55A31D996B787D3297BC9C4253A /* FIRMessagingClient.h in Headers */ = {isa = PBXBuildFile; fileRef = F295E06C7C436FFF623A07299B5151E3 /* FIRMessagingClient.h */; settings = {ATTRIBUTES = (Project, ); }; }; 36096FD7A627E3494710367C7CD03385 /* RCTImageViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = C173864C3DD0334F76FFDBDF7A4866F1 /* RCTImageViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 368678FD447F1882A39DDBBB1A6BBF32 /* FIRMessagingRemoteNotificationsProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 19BF7714D6B5F3817830119EEC74D6FE /* FIRMessagingRemoteNotificationsProxy.m */; }; 36BB99017F8305F3BCE373E755660C3F /* LOTAnimatedControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 57230F2F16D2613F6BCDC05F71AC3A8D /* LOTAnimatedControl.h */; settings = {ATTRIBUTES = (Project, ); }; }; 36FFD47E0D59CED0667D1AE6582240B2 /* RCTDecayAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D270D704787AD78F293EB611F1E668A /* RCTDecayAnimation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3715C0A8D76DCB4EC6910477FD17F032 /* RNFlingHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8B3BDD59AA2F1354B33FA9F9FB787 /* RNFlingHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 37254E9DDE214B4FCDABF39261827074 /* FIRErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = 03168B5FD0FDF3BC03988D170627C222 /* FIRErrors.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 372F9F22EB10D5348DD753FACF1FB309 /* FEventEmitter.m in Sources */ = {isa = PBXBuildFile; fileRef = BC151BD4C4B5CFCE88605416C591816B /* FEventEmitter.m */; }; 3772C429552C70A0FB3030E0CCA92A67 /* RCTSafeAreaShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = B65830077D8C098B52B977E4E16CAB6B /* RCTSafeAreaShadowView.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 38549FF2BFA84F64582389CC9B659207 /* RNCAsyncStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E74862BA95FE8275A4D8B3DCB813A9E /* RNCAsyncStorage.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 38775AA4A27AF2969C7BEB5021C5AC03 /* FirebaseCore-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D561A3F24666C785CEFA0514E9FB9F3 /* FirebaseCore-dummy.m */; }; - 38AB8943C5A222E0AD60090C6E8DE89A /* RNCameraManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E7BCDE68E4FC2A47B90EDF9E20BF4EB /* RNCameraManager.m */; }; - 392B78F24DE2327FDB07904F055ED372 /* RNRootViewGestureRecognizer.h in Headers */ = {isa = PBXBuildFile; fileRef = D6A066C924E3B5578BF58A340D1BCAA3 /* RNRootViewGestureRecognizer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 39E0F8505E13055AF532F52A6AF6E72B /* FIRErrorCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 8562F0DDAF1B176288A98162E9134DD1 /* FIRErrorCode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 37C9843EAA8C7A92FAABEA945B91AD52 /* log_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1D8034D5DC09757CBF6C88BCE84C81B3 /* log_reader.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; + 381533F2AAEEDFC510A538FF9F2A6C70 /* RNFaceDetectorModuleMLKit.h in Headers */ = {isa = PBXBuildFile; fileRef = EC11AE71F07F98FFB4F2C741FE3A108D /* RNFaceDetectorModuleMLKit.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 38EA8D7832A3A7C66E0FD15B22D21893 /* FTreeSortedDictionaryEnumerator.h in Headers */ = {isa = PBXBuildFile; fileRef = AFE4F3AA1A28BE43D9287AFBB26703D0 /* FTreeSortedDictionaryEnumerator.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 393E3145FDCB078EAFCCBBF827220547 /* FIRMessagingRmqManager.h in Headers */ = {isa = PBXBuildFile; fileRef = C7C7AC57C4C8E75A6C614918C18F943A /* FIRMessagingRmqManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 39580F89BFDCEF3B4F7F32BE6CC07C50 /* RNCAsyncStorage-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = F9BB0530FA2B7ABB88C9492E14A34A62 /* RNCAsyncStorage-dummy.m */; }; + 39BD4B821A6DF71CEE30F3124FC8CB83 /* FTupleStringNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 5EBECD9E9DD343F563D6765E57EFC7F5 /* FTupleStringNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3A3023A6A893126A1B8D609CBC06006A /* RNGestureHandlerEvents.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C0872A90B2BA40CEF9E18D168D08A48 /* RNGestureHandlerEvents.m */; }; 3A39871FBFF02AB2FC84C1B3F197DF76 /* RCTTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9375C7CBEBFF6AB1E5BDFD18BC069BB7 /* RCTTextViewManager.m */; }; 3A48BF316FDA6DB57E67567BB16944A2 /* RCTSurfaceHostingView.mm in Sources */ = {isa = PBXBuildFile; fileRef = AAA8FD0DB1334F6D0E1A77D3797040A5 /* RCTSurfaceHostingView.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 3AC98700186BF1FB0FEF8CFC48D97A0D /* GULAppDelegateSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = F121AD95A2079F5A12FCCFABC3DF1CF8 /* GULAppDelegateSwizzler.m */; }; + 3ACC4F8F206003A5BDCDB524C31F914F /* iterator_wrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 3F40208B1F0DC24CAF70925FE733EE42 /* iterator_wrapper.h */; settings = {ATTRIBUTES = (Project, ); }; }; 3AD3408BD5816D0DDC6A5816A1BC0827 /* RCTBaseTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = EB84D8D5AE446239B764F329A8B3A681 /* RCTBaseTextViewManager.m */; }; - 3B1DD336C634B2398D03A33060C1B9E1 /* GULAppEnvironmentUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 335250B47DC62B5D209ED0E7B499E7D5 /* GULAppEnvironmentUtil.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3B208C191EA69C914E2BECEC92EBF410 /* FSRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 1501D5CE22977171369A89A58320F0E7 /* FSRWebSocket.m */; }; 3B4DF4CEA4AAEDFB456AE08EAD29F299 /* RCTManagedPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = F1C0DD3D15AE6327FDE72155DDA4B4BE /* RCTManagedPointer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 3B7BD9357A83991C66149CC90A9FE92B /* ScopeGuard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB089FC3285722B2E922DC1AE785160A /* ScopeGuard.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 3B95CC2D21DF541398FA41E427DF6A9F /* raw_logging.cc in Sources */ = {isa = PBXBuildFile; fileRef = AD5955431A3FCFA7048680B4C25EF64C /* raw_logging.cc */; }; - 3BE0669EF90361F0650A127523B23E96 /* RNGestureHandlerRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = B86F6404D1245E652DEBCF670CA27A4B /* RNGestureHandlerRegistry.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 3C3AD732486F0C2D11031307DBC8A9A8 /* Format.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9899A22E44EAB1314C1B352F982A23FF /* Format.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 3C4FED8981790131C3EBD1B7C8E09896 /* RNForceTouchHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B11BF4BE90DD52473A3ECCD891DA90A9 /* RNForceTouchHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3B7BD9357A83991C66149CC90A9FE92B /* ScopeGuard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BF8B947CBDBE7B454CED67A04F0CC23 /* ScopeGuard.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 3B95CC2D21DF541398FA41E427DF6A9F /* raw_logging.cc in Sources */ = {isa = PBXBuildFile; fileRef = FA951E29A39E4CF2BE2834740CF4F5C7 /* raw_logging.cc */; }; + 3BB3CA8031EF8878556D57B628CD5AAA /* FUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = CE7FD3CFEE2A2A5C9E216149A1A17A0E /* FUtilities.m */; }; + 3BCADF720D85DFCFC1FB6162BB587B12 /* FIRLoggerLevel.h in Headers */ = {isa = PBXBuildFile; fileRef = EA02DB62870C585628FD8725D3277A54 /* FIRLoggerLevel.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3C3AD732486F0C2D11031307DBC8A9A8 /* Format.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B41F99C2DD0AA870E1DEAC36E815B58D /* Format.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 3C6A07B36306511C1651E54EA2E2290F /* testharness.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1EF8A973FA536E2E222B0BDFA64DF17E /* testharness.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; + 3C85E7A495858915F3BCFC3610A8250E /* FAuthTokenProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 944176C892C7E452B815BCEBCBCC07B2 /* FAuthTokenProvider.m */; }; 3C93881AA7DCEDB491A7480C31A0D130 /* RCTComponentData.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B2570E8AAE0D3B21DC7ECEE32C397C5 /* RCTComponentData.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 3CB8DC7F8D90272D3063BD44C82F98B1 /* FIRMessagingVersionUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 389E3FCACF1C1E456B1E409DB7E730BF /* FIRMessagingVersionUtilities.m */; }; + 3CD7060DB1BCCB81C1ECDB3F966E83EC /* FIRMessagingConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 70BAF82D1EE14FACDC272E1C4B56C5E9 /* FIRMessagingConnection.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3CEE7FB3BD2CFC7B0F4F042AE528ED0E /* FChildrenNode.h in Headers */ = {isa = PBXBuildFile; fileRef = CEABB06453C94255BB0FE4056E94C510 /* FChildrenNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; 3CF4B898906CA84F3E8E9BE605009D69 /* RCTModalHostViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 911F56CC688E70E6D4A634EA21017F9D /* RCTModalHostViewManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 3D19AF38C81F44DC071A53EC1425B920 /* GPBRootObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 80F61CFD731064B4566AC59E8B1DDC68 /* GPBRootObject.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 3DAB5A42B6624B6A1EDF6354774553DE /* TextDetectorManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5219A5D3B1D612138A0F260A22820610 /* TextDetectorManager.m */; }; 3DAF9D5A82A2833FD6DFD9ABFBFE4FF0 /* YGEnums.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CF9FA1CC7CD8464B462CAD48AFB1D1A7 /* YGEnums.cpp */; settings = {COMPILER_FLAGS = "-fno-omit-frame-pointer -fexceptions -Wall -Werror -std=c++1y -fPIC -fno-objc-arc"; }; }; + 3DB2BB65E216C7AB2ED6E7775D92F3C1 /* FPersistentConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E56962CF36D9AC7FC58707C2D4DCF6C /* FPersistentConnection.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3DE031256D0F33B9E7FC1421A8720CC0 /* FTrackedQueryManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 894D53FA3FFD70DFE5301E4E508B2DFF /* FTrackedQueryManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; 3DED86DB013A3575987D5E1F4193843C /* RCTMultipartStreamReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 058F2D320849C5E354F3AA1679C66E11 /* RCTMultipartStreamReader.h */; settings = {ATTRIBUTES = (Project, ); }; }; 3E0D5BD3C28E2B59A384F12F400F7012 /* RCTAnimationDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 7FC9B3EA0A07AE52AA1D18C1F8F8CF1F /* RCTAnimationDriver.h */; settings = {ATTRIBUTES = (Project, ); }; }; 3E7ED25AF8FA7543A98EB195849D03D9 /* RCTConvert+Transform.m in Sources */ = {isa = PBXBuildFile; fileRef = 7C7738F40E683A127FF4C2FE7DC76056 /* RCTConvert+Transform.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 3E9183B650E1AB20EEF1809ABA7B31E9 /* RNImageUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 73FB83B5567B867C643ABD764A2CC524 /* RNImageUtils.m */; }; 3EA0EAC988E3480897CAF64BA94B9E03 /* LOTRepeaterRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 748B5E72654314BF99FE3E495ABF000E /* LOTRepeaterRenderer.h */; settings = {ATTRIBUTES = (Project, ); }; }; 3EED13928F319CBD82F9CDE264338B0B /* RCTProfileTrampoline-x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = BAE3AC60F51B43A3E006A2BFB91E3CE5 /* RCTProfileTrampoline-x86_64.S */; }; 3EF0E77EF4873AC375F2E50D4E2ADB2C /* UIColor+Expanded.m in Sources */ = {isa = PBXBuildFile; fileRef = 255FBD0F7442584058A993EA565B5598 /* UIColor+Expanded.m */; }; 3EF2C64A967000D1B8433A69D8B830F9 /* RCTURLRequestDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 41928F9CEA164E82386F4C2DBA176D24 /* RCTURLRequestDelegate.h */; settings = {ATTRIBUTES = (Project, ); }; }; 3F17CA3C0A8E29BE019ED0B3D46CE74C /* YGMarker.h in Headers */ = {isa = PBXBuildFile; fileRef = 432B068DE5FB4AAE0865A421A5F3009C /* YGMarker.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 3F396C524AC312BF7499E4DEC9F7DB4F /* pb_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 212FB97DDEAF6BEAFED5E4B7EFBDBA01 /* pb_decode.c */; settings = {COMPILER_FLAGS = "-fno-objc-arc -fno-objc-arc"; }; }; - 3F505D52F2775E5B56A45D604B9809E4 /* Empty.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B1D4D3C0E4191DF1485194B68CEB7AD /* Empty.pbobjc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 3F73A96B09445BEAA8AF36A3883285FB /* RCTClipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = 6942AC0BB436F0E4B768FE87E5A8019D /* RCTClipboard.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 3F98B8875E41D625A3489AC61714ADF9 /* FImmutableTree.m in Sources */ = {isa = PBXBuildFile; fileRef = 00BE88F25DC58F3A5C0BCEB71B025B97 /* FImmutableTree.m */; }; + 3FE904A17592EB69B2AB78D5545E58B0 /* FWebSocketConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 32D626A4D1610ABDE8CEF2647EB63976 /* FWebSocketConnection.h */; settings = {ATTRIBUTES = (Project, ); }; }; 3FEE8BBF9AD962C0443269393F461E95 /* YGLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FAD745BB610D527200334238FC49013 /* YGLayout.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 400811EACC5D204617DAA35B7257A5AE /* FTreeNode.m in Sources */ = {isa = PBXBuildFile; fileRef = A21E69899E4D49D3B37623017C91600C /* FTreeNode.m */; }; 40097E4791E74789A834AFCD7DA38DCD /* ARTGroupManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F864B053F8A153CD44481E267EFD35F /* ARTGroupManager.m */; }; - 4058877C728619A86988C0ABEB8810A5 /* GPBProtocolBuffers.h in Headers */ = {isa = PBXBuildFile; fileRef = 43497B573E91EF51113E2EEBC8C1EC96 /* GPBProtocolBuffers.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4016801FF6E76F859B9D3FA2D99A068F /* FCompoundWrite.m in Sources */ = {isa = PBXBuildFile; fileRef = 516F35E8FDF2F4BFF18B895917E368F1 /* FCompoundWrite.m */; }; 407F8F4F662C1B2765B63B0EFD7770A8 /* RCTAdditionAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 66D7FB3F304C0694F361D185C2B5284E /* RCTAdditionAnimatedNode.m */; }; + 407FB5F780BDAAFECE8167C302B3209C /* FStorageEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 70CD617F541028461ADEB6E9EECBE23B /* FStorageEngine.h */; settings = {ATTRIBUTES = (Project, ); }; }; 40B38FCEAE98FA7E22E80A478382390D /* LRNContainerView.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A555741AC2B507F159D654AD368AB7 /* LRNContainerView.h */; settings = {ATTRIBUTES = (Project, ); }; }; 41503DF61D9C93E995C6D2A596C250DA /* LOTPathInterpolator.h in Headers */ = {isa = PBXBuildFile; fileRef = F7466C1AF40FB2AFB6AA506B04693370 /* LOTPathInterpolator.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 418A72CD642151047F5312E3C13DDF2A /* FIRMessagingRemoteNotificationsProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 010593F7E979CEFE100326A954A7ADA3 /* FIRMessagingRemoteNotificationsProxy.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 41B98E539FC994EA91307583A755702F /* NSData+SRB64Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = E972B990B021624DF8F843EB6A72994F /* NSData+SRB64Additions.m */; }; + 41ECA52F5717B6A4BB87E08098621E7B /* FIRMessaging.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C573707E62D8A5DD5ED310288347C87 /* FIRMessaging.m */; }; 42452E04F747B0DC4C75310AB2E5EC24 /* LOTShapeFill.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D203CA071CD6707C1DB1730354C047 /* LOTShapeFill.m */; }; - 42631F04F1FB85FEEDE8F4908A7FA4D3 /* GULNSData+zlib.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B136F18AEA180219FBA5D7410D58846 /* GULNSData+zlib.h */; settings = {ATTRIBUTES = (Project, ); }; }; 4267C97488146FE894945A8BB1DB363F /* RCTWKWebViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 883B6143152CCA96E0CF4594C47DF773 /* RCTWKWebViewManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 426E915A234B465920E6627F48DD3E48 /* LRNContainerView.m in Sources */ = {isa = PBXBuildFile; fileRef = AC70AA5633E0D9EE05B6E8C3E39A690E /* LRNContainerView.m */; }; 42839B7D6607D5637BAA48C826663182 /* JSBigString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36F0B66E287C6ADDC28307A83785D71D /* JSBigString.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; @@ -394,260 +524,355 @@ 43554FBBE6553CE2A90B87B06DAE0F90 /* RCTDiffClampAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4609362358BBBF1E75601DD484FE07A8 /* RCTDiffClampAnimatedNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; 437C101938A216A38028385EF871B479 /* RCTTransformAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 32DEF137DA3C62D37ABC663B89E7A21F /* RCTTransformAnimatedNode.m */; }; 437E0835B7ED33D93D6F5AAE5BB7D363 /* LOTShapeRectangle.h in Headers */ = {isa = PBXBuildFile; fileRef = 681732CD2C5F6E22898FFAF9F43DFCB1 /* LOTShapeRectangle.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 43CF58B7907116E2FE0DEDA144E2E7A8 /* FValueIndex.h in Headers */ = {isa = PBXBuildFile; fileRef = 58504D264295A60569A9BACA31B854E4 /* FValueIndex.h */; settings = {ATTRIBUTES = (Project, ); }; }; 444323334685E7B1E92C3FD1C58620C7 /* RCTEventEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1D3F307D076FF78FE39D6E5E0F462FAB /* RCTEventEmitter.h */; settings = {ATTRIBUTES = (Project, ); }; }; 44C399B15392FF9AB79DF73C3832DB2C /* RCTSurfaceStage.h in Headers */ = {isa = PBXBuildFile; fileRef = B17DCFD337394DD83E0C87CCBE659BE1 /* RCTSurfaceStage.h */; settings = {ATTRIBUTES = (Project, ); }; }; 44DA4821BE796A8A4923B3EC61C3ED58 /* InspectorInterfaces.h in Headers */ = {isa = PBXBuildFile; fileRef = AA47B680DDAD19C7E18F4F7A21F31D34 /* InspectorInterfaces.h */; settings = {ATTRIBUTES = (Project, ); }; }; 455277BE2864AAE9DD5A33122ADCB81B /* ARTSurfaceView.h in Headers */ = {isa = PBXBuildFile; fileRef = CCD157FC35CFB41CB2073E6FC1FB159D /* ARTSurfaceView.h */; settings = {ATTRIBUTES = (Project, ); }; }; 45733948231EDC3A391BDC7F27F1A7E8 /* RCTBridgeMethod.h in Headers */ = {isa = PBXBuildFile; fileRef = 524343A6FDD6067649ABED74830C92FB /* RCTBridgeMethod.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 459910DE0C8B132CEC7F35791180406F /* GPBUtilities_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 21661A7F663A0C93FA1F45E12ED66480 /* GPBUtilities_PackagePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; 45A1F060D620E2C1D294C13438EF7B06 /* LOTAnimationCache.h in Headers */ = {isa = PBXBuildFile; fileRef = ECCA970817C13BA5DC777519F6C31589 /* LOTAnimationCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; 45F4990F2A1C03F3904F0164CB042206 /* YGNode.h in Headers */ = {isa = PBXBuildFile; fileRef = CDD27395DE604FBBB6D789AD3757EB10 /* YGNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; 462378F11FD925046E301796CF5864D6 /* LOTMaskContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = F013E4C7BC7F453FACF687F6A0FC744F /* LOTMaskContainer.m */; }; - 466C9C104A7DB79159EE0AFBE1E6A270 /* RNCAsyncStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F73F441EFFB57B67671EC1D71949757 /* RNCAsyncStorage.m */; }; - 46C7C184C89B5DE19E1E7757BF18B7CA /* fast-dtoa.h in Headers */ = {isa = PBXBuildFile; fileRef = B71607B0576176404F452DD809E993D0 /* fast-dtoa.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 467047FA544BC876EE820B6C23383963 /* APLevelDB.h in Headers */ = {isa = PBXBuildFile; fileRef = 419AD5D765BE6240880B0DED4704566F /* APLevelDB.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46C7C184C89B5DE19E1E7757BF18B7CA /* fast-dtoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 007D6D8738E909C6CF0320FF9CE52D28 /* fast-dtoa.h */; settings = {ATTRIBUTES = (Project, ); }; }; 46E2C9C379B304BCD8777685945E6E5A /* RCTSurfaceSizeMeasureMode.mm in Sources */ = {isa = PBXBuildFile; fileRef = F9E4AE645639D4F1E42C5230CAA3293C /* RCTSurfaceSizeMeasureMode.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 47457EE291003D4606CA4AD6ADEEC530 /* RNRootViewGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0A8083D1F6D61E7CADFCFEC6B487C4 /* RNRootViewGestureRecognizer.m */; }; + 47045A571995E8144D9CD11E5BB937AF /* FChildEventRegistration.h in Headers */ = {isa = PBXBuildFile; fileRef = FB77A383C92DDA7CEBB334739002ADE6 /* FChildEventRegistration.h */; settings = {ATTRIBUTES = (Project, ); }; }; 47547EA527975D10848E8B1BE50A60D0 /* RCTDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B8F76C35798A39530DF4CAADCF9DA65 /* RCTDefines.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 47A53913D0B382C0D80B469FFBF660CF /* react-native-camera-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = F8915607A789FA16613C44076588D5A6 /* react-native-camera-dummy.m */; }; + 476EED1FBFB3E7267634CA0D0218AFB9 /* FIRMessagingPubSub.h in Headers */ = {isa = PBXBuildFile; fileRef = C91204B4B8E6BFE92D6270595B0E41B8 /* FIRMessagingPubSub.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4796FD6316E274E201F895A87E29A2FD /* FIRVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = CAE5C63FB4B0E24853ECEC763B56541B /* FIRVersion.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 47EAF3F8F2BE25A3B1F941F5C4C7408B /* logging.cc in Sources */ = {isa = PBXBuildFile; fileRef = D6BD0DC337189DAD217C1ECB7620C8AD /* logging.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; 47FA2AA2C9C673A1C114DD42AD0387E9 /* LOTPolystarAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = 250135120E1268B9E37A19B1BA773892 /* LOTPolystarAnimator.h */; settings = {ATTRIBUTES = (Project, ); }; }; 4805E7DF14B36C7078E9186D8F2E8FB9 /* LOTAssetGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA1E553086B47B4F5976B6207520336 /* LOTAssetGroup.m */; }; + 48AE61EAD2027714189B82B0A54105F4 /* RNCSliderManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E4AA426D9F768455A13E32CB81CF537D /* RNCSliderManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; 48D4AAF6AD59399A9C96A6E0E57811F0 /* NSValue+Compat.m in Sources */ = {isa = PBXBuildFile; fileRef = 877FBFA30FD9C5E7350352BA6E7D8903 /* NSValue+Compat.m */; }; 494F4726012CD730EB47203573378FB1 /* fishhook.c in Sources */ = {isa = PBXBuildFile; fileRef = 295B9A1EE8E0456AD85C309CF752BCDE /* fishhook.c */; }; - 4960BA7C223DB21A38DEABFA1572EC41 /* GTMDebugThreadValidation.h in Headers */ = {isa = PBXBuildFile; fileRef = 520AAB5C69DF55FB372E2356B9E73273 /* GTMDebugThreadValidation.h */; settings = {ATTRIBUTES = (Project, ); }; }; 49CE340D9FA18297843D77433681F59D /* RCTBorderStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 30F867DF6C4A1BFC4127CE2948C92A03 /* RCTBorderStyle.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 49CF2504036F1053DE3A3EFACB16878B /* FIRDatabase_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 01B3017DFB14AAC889D13223520F8A82 /* FIRDatabase_Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; 49D77CA06AAC754230A34417431A8484 /* RCTUIManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 3AC9869F42735E2629B487533BB101C8 /* RCTUIManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; 49F13C522FA2BCCA834FA3D888F84152 /* RCTComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A0CE655EB439D100B22AB226928A06A /* RCTComponent.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 4A4AC5A022F94AFD6FF930EBCDC87F8D /* FieldMask.pbobjc.h in Headers */ = {isa = PBXBuildFile; fileRef = 75ADAB93DC535E6DF3AAC46DAA07D9DC /* FieldMask.pbobjc.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 4A78E99F1B0E53E2632BED6A6943ADD7 /* FIRBundleUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 228E1FDFF261DF8EB10848297D3AB291 /* FIRBundleUtil.m */; }; + 49F6082A7056E1162EDADF9F9ABD9080 /* FIRServerValue.h in Headers */ = {isa = PBXBuildFile; fileRef = BDB3F378ED3191C4E52C52675F76AB45 /* FIRServerValue.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4A79307E67AA69448A4629069F0D7947 /* FViewCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 562F8CB0D3313A7C1376DB26779FD16F /* FViewCache.m */; }; + 4A7CB69CFCC95FFAEEC248D414EA1C56 /* FLLRBValueNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 29D2B5D41D48199784CDB89A40F06B5C /* FLLRBValueNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; 4A9D3D2F1BA8C4364FC5137BD6D6FF3A /* RCTUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 8D29E26FA2AE080F5BB7190E07F01DF0 /* RCTUtils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4ADE2317465B57AE998D2EEBA726D665 /* FIRCoreConfigurable.h in Headers */ = {isa = PBXBuildFile; fileRef = B3B50DE72F5CD916F93A5496C7473931 /* FIRCoreConfigurable.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4AEC1CCFE197D520A824CDB6ED734160 /* GULReachabilityChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = 660E8F4A387A81130A3B64FDA0DC2C2F /* GULReachabilityChecker.m */; }; 4B056DF581094239996F764C4073EECA /* ARTPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DD0798D0E11306CF7CB526214125B12 /* ARTPattern.m */; }; + 4B524E786CEFA12D08176EAC89D948DB /* memtable.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3F2F365D934F6305BB1F840BA46B96D5 /* memtable.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; 4B6DD60D3F5B14D459D097E6E731D84B /* JSBundleType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86065096B5CB88A98E055E5988FB4AFB /* JSBundleType.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 4B90C3C897CF67577A7437789F658B8B /* two_level_iterator.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3236036995BCE087A642F3AEB2328A4B /* two_level_iterator.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; 4B9E3034FCFCA4176694010C92118922 /* RCTSurfaceHostingView.h in Headers */ = {isa = PBXBuildFile; fileRef = 442A4479A2D25B5166A4FAAB6638FD4F /* RCTSurfaceHostingView.h */; settings = {ATTRIBUTES = (Project, ); }; }; 4BA5E4E95CBF0CB433044140A2A52C19 /* ReactMarker.h in Headers */ = {isa = PBXBuildFile; fileRef = CBF89793120841C4D18A6D4C3B9EC656 /* ReactMarker.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 4BF3F058D3837F4A3358A70733C4F688 /* RCTCameraManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FE0D685632B5D653CAD70F3ADE15857D /* RCTCameraManager.m */; }; - 4BF62E25C86EC98CB67CABF4D7871AA7 /* Pods-Kalend-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F9BB4CBCB450B127736E624E673744A /* Pods-Kalend-dummy.m */; }; - 4C1BD17233DF15565B66AC1002B822B3 /* GULSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = 58536835EFA959CC6FD5CF5218FDFC75 /* GULSwizzler.m */; }; - 4C3B755D2C32658C1D18B6E8E3031103 /* RNCSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BD8A8817272444480B1B5B3B82FCC0D /* RNCSlider.m */; }; + 4C21D8E9839706D96121600EAB64899D /* FRangedFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 43C31F092679C01E2C9CE96EBAA48663 /* FRangedFilter.m */; }; + 4C2EDA8799BA0432093C8C788F71B27A /* RNGestureHandlerModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CD95F8D31BA3304FCA6F0E43A9A1281 /* RNGestureHandlerModule.m */; }; + 4C406BA0486D04ACCCFBFA73F4D79ADD /* RNLongPressHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 5990E7950D75F0AEEEBEB9D5F4FD915A /* RNLongPressHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; 4C42BA352F242820EB182D0A164D7BB5 /* RCTDatePickerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = BC6ED2451D7533FC61CD6E8DEDC4623F /* RCTDatePickerManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 4C511D9751B1CEBE03694E5D8FB621D1 /* RCTScrollContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = D0781A402BF5C76FBD4E60EB5C9DC250 /* RCTScrollContentView.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 4CC2989A38F3B7AAFEA9DBDD31880224 /* FIRLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = DB61590A1D3C3125938F217F5E14ED9D /* FIRLogger.m */; }; + 4CDF13B90C45B12C5F8323C13C65D2E5 /* comparator.h in Headers */ = {isa = PBXBuildFile; fileRef = C6F941B784ADFAD4519A40D1636044D9 /* comparator.h */; settings = {ATTRIBUTES = (Project, ); }; }; 4D12038330C7E30625CE62B0BBC31DA7 /* Yoga.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 568E1E2F9C4686E3749464F2F212933C /* Yoga.cpp */; settings = {COMPILER_FLAGS = "-fno-omit-frame-pointer -fexceptions -Wall -Werror -std=c++1y -fPIC -fno-objc-arc"; }; }; 4D128DCA996FAB117AE2CDAC2AA61AE7 /* UIBezierPath.m in Sources */ = {isa = PBXBuildFile; fileRef = A7B22B44D0055B4FEBC93443C5396239 /* UIBezierPath.m */; }; - 4D3C83598788529994A8420061B066AE /* MallocImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 672B4F31CF65337F8111AAFD4FE52315 /* MallocImpl.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 4D3B9204EEEB72B24B2836C82C888ED9 /* FIRMessagingDelayedMessageQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = E65F21F9ABB67CCC10B8DA68A6597A33 /* FIRMessagingDelayedMessageQueue.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4D3C83598788529994A8420061B066AE /* MallocImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 71F17B940ED7E61E4B3F0479A436376E /* MallocImpl.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 4D69D43025D290FEC049F8FAF7616759 /* FIRMessagingRmqManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FCE4AE69FB42F974D532A536DAC73C2B /* FIRMessagingRmqManager.m */; }; 4DB83155AA9BB2EB44CD1BF181939137 /* RCTActivityIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5AF65FF35F0E3DA312885756C885EA1D /* RCTActivityIndicatorView.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 4DDE0D8EC451F169D91D5CA0CDBB574B /* LOTShapeTrimPath.m in Sources */ = {isa = PBXBuildFile; fileRef = B7A399176373C8AA1A6610E3132E23B1 /* LOTShapeTrimPath.m */; }; - 4E2AAF2951FE1485BD0028EB1F8C1694 /* GTMLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = EC84E3599BBB7DD06B11323C1785FE23 /* GTMLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4E04F4461634D567642EA6962129DF56 /* FIRMessagingCheckinService.h in Headers */ = {isa = PBXBuildFile; fileRef = A635DF48E01E89FDD6731F6327F620EA /* FIRMessagingCheckinService.h */; settings = {ATTRIBUTES = (Project, ); }; }; 4E3C4383B3ED40FAF71AAF158A097056 /* LOTSizeInterpolator.h in Headers */ = {isa = PBXBuildFile; fileRef = 774F4E51B70BC28A607E08C929DC4D87 /* LOTSizeInterpolator.h */; settings = {ATTRIBUTES = (Project, ); }; }; 4EE79274A9A39DC223B7D10593C50DCA /* RCTFrameUpdate.m in Sources */ = {isa = PBXBuildFile; fileRef = 15A9011D85860FA918D538B04E4F0E1F /* RCTFrameUpdate.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 4EF22C94AA677E8535C72254E6BC2260 /* JSModulesUnbundle.h in Headers */ = {isa = PBXBuildFile; fileRef = 05826DCEE0F36471E684F1684BD2951A /* JSModulesUnbundle.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4F0B93FF899904A5711D574AF8E3A134 /* SourceContext.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 233CC9D72A4769298201DCE6A22219B4 /* SourceContext.pbobjc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 4F34898B9B92AE758FF52EE3B57C3EAF /* RCTImageBlurUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 3591100D83359EA796A9E1D182A9825B /* RCTImageBlurUtils.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 4F481BF28F5D485193696E17B5782F6C /* signalhandler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 013E70C5F49F92AA2533BE9D5B83A65D /* signalhandler.cc */; }; - 4F84615D788E2303F4AF889D9E500584 /* RNFileSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = CD00DCE93642C11C81C8B55D2512DC9E /* RNFileSystem.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4F481BF28F5D485193696E17B5782F6C /* signalhandler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 552E2C917A1918F04F22AA02556B8562 /* signalhandler.cc */; }; + 4F5FC8A554259A02834F92645D114887 /* FIRAnalyticsConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 8C595054FE1F0AB55132320069F45FD0 /* FIRAnalyticsConfiguration.h */; settings = {ATTRIBUTES = (Project, ); }; }; 4FE26A0728F5B5BF6C27016C49634930 /* RCTDisplayLink.h in Headers */ = {isa = PBXBuildFile; fileRef = FA10F3C5F810847BACD34E4D8A2D1CE9 /* RCTDisplayLink.h */; settings = {ATTRIBUTES = (Project, ); }; }; 5015DAB6FBDB0AB79C493C1AC64FBC62 /* RCTMultilineTextInputViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B957823DE0B2159383BA55754DD618C7 /* RCTMultilineTextInputViewManager.m */; }; + 501FD58A6631FDBEF9B574E5BA57324A /* FIROptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 3704EE2DB67187CDD6B387F348CB41D0 /* FIROptions.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 502C8A78D9714A90147D9131BE4E1CDD /* RNForceTouchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 350C32D80852C78B7284508AF930D643 /* RNForceTouchHandler.m */; }; 50510C9867B2B7B67259EE6C7190D1AA /* LOTBezierPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 92645298A7A3705DF33AF08F6C912988 /* LOTBezierPath.h */; settings = {ATTRIBUTES = (Project, ); }; }; 505C65D96958E41AA60A05A0D0149271 /* RCTTextAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = CA5C01AFB4BD1A05F686B418F6709EE7 /* RCTTextAttributes.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 508E11B11F29BC7BD17A49FEB13A7C1C /* RNGestureHandlerModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CD95F8D31BA3304FCA6F0E43A9A1281 /* RNGestureHandlerModule.m */; }; 50947B6975B6C4E44C81B353CCD7DBDC /* LOTPathInterpolator.m in Sources */ = {isa = PBXBuildFile; fileRef = D1B2DE63C0645FDA9E54CF342CC451A3 /* LOTPathInterpolator.m */; }; 50A823E31F21E359FD2905962B07F227 /* RCTRedBoxExtraDataViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91E27A3160ABCFED1B02335AB8E5570B /* RCTRedBoxExtraDataViewController.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 5112566D095E6BAF3A58A7DA261D41DA /* db_iter.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E009D4735C805CED8A49BDC00DA9679 /* db_iter.h */; settings = {ATTRIBUTES = (Project, ); }; }; 514BB94BCFE48D98ADEFC4E07659152B /* RCTSubtractionAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7D3A05841540D10AB818F37AB3C8FC3D /* RCTSubtractionAnimatedNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; 516BEF436EEB6E6712CD3D1A65596BA1 /* LOTKeyframe.m in Sources */ = {isa = PBXBuildFile; fileRef = 28A58FD07042B910D401A97FE2112FAD /* LOTKeyframe.m */; }; - 518A21F5438049FA77B03B1387C0BB67 /* FIRAnalyticsConfiguration+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E987BD8711908B25633630076E4D31C /* FIRAnalyticsConfiguration+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 51A9173A7BBDA8AADDAEC4471E349EB3 /* FIRMessagingPendingTopicsList.h in Headers */ = {isa = PBXBuildFile; fileRef = 75290A71FA8F79E812D3DB2C1321AF9E /* FIRMessagingPendingTopicsList.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 52337EECC6A00580652F91DA24A414F6 /* GTMDebugSelectorValidation.h in Headers */ = {isa = PBXBuildFile; fileRef = CD5404E787B4589BCC278F9ED7665639 /* GTMDebugSelectorValidation.h */; settings = {ATTRIBUTES = (Project, ); }; }; 52422F2D921C64898CD0720F6C6AB304 /* LOTLayerContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = D07B46AEB7D2CE6A8C3D3D25EF50A8D0 /* LOTLayerContainer.m */; }; + 524791447807C9424BCA2ADA65EB0643 /* FImmutableSortedDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = A80DF0C102E3EA656E87DBE7A9FF4F08 /* FImmutableSortedDictionary.m */; }; + 52780D4B9C56D52EE4CBF8FF03CCCFF9 /* GULObjectSwizzler.h in Headers */ = {isa = PBXBuildFile; fileRef = FB474C1F8E857DCA0F160460EFC9017D /* GULObjectSwizzler.h */; settings = {ATTRIBUTES = (Project, ); }; }; 528722A0B5C81410F8689F0C7BA53C31 /* RCTViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E62425D7BD0B62BEFBE4C7D9C3FF88A6 /* RCTViewManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 5288F7C05FD65ACC5A382CF7A1B8D705 /* RCTFollyConvert.h in Headers */ = {isa = PBXBuildFile; fileRef = BDD4FD7DCCE03AA492F5C7E9434723F1 /* RCTFollyConvert.h */; settings = {ATTRIBUTES = (Project, ); }; }; 528A8D4A74E07A86BDDB1E1528CDE06C /* RCTSafeAreaViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 01492C4D83A3EE634C07FEE211CF13D0 /* RCTSafeAreaViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 52933337314D1D5F12D382FE35230BA3 /* FIRNoopAuthTokenProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 15A9D734E57E7B82657B9C03A83BDAD6 /* FIRNoopAuthTokenProvider.m */; }; + 52A277F85AD4B99DB661878D45796BBA /* RNFetchBlobNetwork.m in Sources */ = {isa = PBXBuildFile; fileRef = 591CF78596852D81B2F664FA10F1DE9A /* RNFetchBlobNetwork.m */; }; + 52DD9F7F357CA8043AE0FA675899C60D /* FNextPushId.h in Headers */ = {isa = PBXBuildFile; fileRef = 1930D643E55F4366DCFB1B34FB799D5A /* FNextPushId.h */; settings = {ATTRIBUTES = (Project, ); }; }; 530B29BFF687B1B6CDAE606A16A7C828 /* RCTSafeAreaShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = B80195DC6DFD29FEE0CCAF6EF891B51A /* RCTSafeAreaShadowView.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 532BD0393673759BF1C0C40B01EE2D5F /* RNCameraUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 35CC5C005C98B39B79281E11E9E4BB01 /* RNCameraUtils.h */; settings = {ATTRIBUTES = (Project, ); }; }; 533666E84056DD7AF98099341CAA588B /* LOTTransformInterpolator.m in Sources */ = {isa = PBXBuildFile; fileRef = A6BD5267B696C1517DEB35E481886AB1 /* LOTTransformInterpolator.m */; }; - 535DAAA72BC855F5514686AAB426399F /* GTMSessionFetcherLogging.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D41F04E9445A45F2AC4B9B3E9E09BFF /* GTMSessionFetcherLogging.h */; settings = {ATTRIBUTES = (Project, ); }; }; 537826093BC5A5B1E0B8D101DAB24AB4 /* RCTPointerEvents.h in Headers */ = {isa = PBXBuildFile; fileRef = E703B49FCFBE69F94379558A82645F3C /* RCTPointerEvents.h */; settings = {ATTRIBUTES = (Project, ); }; }; 5397C4FFDE661A0214AE0294BE101EC6 /* ARTLinearGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 1895D859CA9767D810F6C3510ABCA351 /* ARTLinearGradient.m */; }; - 53BE8F23C13B6ABB20739BB2BCB86717 /* GULLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 42CE6557E4770B5F0D1F2C2B81F80F97 /* GULLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 53BF5793D93E75B8DD978A801BD918BD /* RNPanHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = CEF7599963D907DFA7840EE2120C743C /* RNPanHandler.m */; }; + 53DA9B914C3FD19605996A4ABDE66C2D /* FImmutableTree.h in Headers */ = {isa = PBXBuildFile; fileRef = 4432B5DE12A0775BABA5B5E3B961116C /* FImmutableTree.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 53DB5CF00DADBFC3CD7829A781D08F40 /* FKeepSyncedEventRegistration.m in Sources */ = {isa = PBXBuildFile; fileRef = F830A41CD61BA702D980C5F7FCE20253 /* FKeepSyncedEventRegistration.m */; }; 542302EF51E917C6FDDF6FFF651AF37D /* RCTDataRequestHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AB7FDBDFC2DA39E68B035C391BDCA6B /* RCTDataRequestHandler.m */; }; - 5453AE886AA5A4606F93E83332084F4E /* SourceContext.pbobjc.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B457FAC86A7D2B564DEC7B9230B1745 /* SourceContext.pbobjc.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 54322F729D2AFCC889938351E1499A39 /* GPBDescriptor_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 36F3D1B3B7B29DDC9BAB3591E2F2A9DC /* GPBDescriptor_PackagePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; 547381AAFD88D483450CC41BD00558E0 /* RCTSRWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AEEA1671928288C86857036B1C49A40 /* RCTSRWebSocket.h */; settings = {ATTRIBUTES = (Project, ); }; }; 54B2C16352D018790453E251CAB0B4DA /* LOTShapeGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 096E4DC08D065EFAD71B1714E6EB5395 /* LOTShapeGroup.m */; }; + 54DD45180299C11D2BEF50D813586E9E /* GPBMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 02A7AC7B71A07E26F7AC8D4CBF4EC17F /* GPBMessage.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 54F0AC4BFB6B3D650E4EC225819AEBFA /* log_writer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9A5D125A926C9A0A1A3FB1982E721273 /* log_writer.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; 55215048B08EA84054042EAF1DCAE6B1 /* jsi-inl.h in Headers */ = {isa = PBXBuildFile; fileRef = BC887ADD7DE12B30A345C72686EC603A /* jsi-inl.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 55978B6781237651DB5C726C990C9CA0 /* FConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C3A3E65CB073D3D976CBD3F68542942 /* FConstants.m */; }; 55A183546D816239EFA6D38900190AC3 /* RCTCxxUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = BDB62C96CE74FA6EEB5A0576D2402A2B /* RCTCxxUtils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 55AFE71F07AFEE984593CA7090B804E4 /* GULNetworkURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FB6DE326DCEDAD8854CB441D76ADA23 /* GULNetworkURLSession.h */; settings = {ATTRIBUTES = (Project, ); }; }; 55BC36B45570696ADDAEF7B05D131D68 /* LOTNumberInterpolator.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D2E72C270DF02D693F6A3D82EA4C798 /* LOTNumberInterpolator.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 55E7C95CEB9CB8E9D24D79E768E5C4FE /* F14Table.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27B324A94122FB21CAF9924D9DE60D16 /* F14Table.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 55E7C95CEB9CB8E9D24D79E768E5C4FE /* F14Table.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CC1DD9770508DA94C742ED0638E76E5F /* F14Table.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 55EE2682867ED04715047C532E0FE5A9 /* RCTInterpolationAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 00C8F011D8EFC7ADAC8D4F7DCFA6C67B /* RCTInterpolationAnimatedNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 562D4A7195CC8F23EE349F87BFD87417 /* RNGestureHandlerButton.m in Sources */ = {isa = PBXBuildFile; fileRef = CD7120334CF748AE6786EAC9476FE961 /* RNGestureHandlerButton.m */; }; + 56079FAB8E21B3AAC652DC6ED9D08FEA /* FAckUserWrite.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F42437F1F72018693E866EC0BDA1BB7 /* FAckUserWrite.m */; }; 564979325AD9936D971373102020F4A1 /* RCTProgressViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 671D388C9298241343E84F91FA03F927 /* RCTProgressViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 56AD8769C79F40FBECB1B581095ACF62 /* FirebaseCore.h in Headers */ = {isa = PBXBuildFile; fileRef = F3B8ED4FC03D2D28F01CB56C2C5F8B84 /* FirebaseCore.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 56619F38A7BC40AADA3F656FB2E5A2D3 /* RCTFont+FA5.m in Sources */ = {isa = PBXBuildFile; fileRef = B3D9AA395B8A6E438AEB2F16D98D26EB /* RCTFont+FA5.m */; }; + 56A2971E105D6D2CDF42FA9A033096B9 /* FOverwrite.h in Headers */ = {isa = PBXBuildFile; fileRef = 445CCC9B3DDFCC1034CA6BC4F856C306 /* FOverwrite.h */; settings = {ATTRIBUTES = (Project, ); }; }; 56B8CEB9F19F560AFD49F6C46B18CC79 /* ARTShapeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B8BF1A988BE76405BD305A08EB0484A9 /* ARTShapeManager.m */; }; + 56BEA8C64962C18023116E3314D84A8F /* FIRComponentType.m in Sources */ = {isa = PBXBuildFile; fileRef = 0356BDAEC5808155DFE77028C5997175 /* FIRComponentType.m */; }; + 56D74B4DA37EAC08EEB4CD707B0EF55D /* testutil.h in Headers */ = {isa = PBXBuildFile; fileRef = F60D66CC797623BFF95E4681FBA0CA3B /* testutil.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5746004E5CEDAE3B19A2444FA37A4573 /* FIRAnalyticsConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 08491B7F2816397E75081103B09AACA0 /* FIRAnalyticsConfiguration.m */; }; 57BBA389D630E27ABB88DEFFFDAEE245 /* RCTInvalidating.h in Headers */ = {isa = PBXBuildFile; fileRef = 87B199563AB49A7E7D90A26E4E537620 /* RCTInvalidating.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 57EEBEECEB49A560BAFB750DB90ADF5C /* strtod.h in Headers */ = {isa = PBXBuildFile; fileRef = AB062FB5FE3CA4C8C4BA1594452B88EA /* strtod.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 588DAA4232F7A3F806BF582E894B427A /* RNFileSystem.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BA903F2624EB644E66875057A6B8EB4 /* RNFileSystem.m */; }; + 57EEBEECEB49A560BAFB750DB90ADF5C /* strtod.h in Headers */ = {isa = PBXBuildFile; fileRef = E28F9CFD4A5F59337955F5E5E29D7D00 /* strtod.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 58824627FAEA9EB0208A37401340CC43 /* NSDictionary+FIRMessaging.m in Sources */ = {isa = PBXBuildFile; fileRef = 317F07FF03994881B20CF2F7178180EA /* NSDictionary+FIRMessaging.m */; }; + 588A9F60E27020FE274AFC471CFBE26E /* FAtomicNumber.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BE6185E47D64690D26AA8C43019350E /* FAtomicNumber.m */; }; 58A27AD1101FBFEC569C4581F4621066 /* LOTAnimatedSwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = 015548AD477FAF4C212214E3B96D7A3C /* LOTAnimatedSwitch.m */; }; - 58BD9D02F092420900C9A91F1FEE94DF /* utils.h in Headers */ = {isa = PBXBuildFile; fileRef = AFD44EF8E63D08F65BFAC2B9A64F48C7 /* utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 58E45E924CF947D43546B0BC561552E4 /* json_pointer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B08791541E4426FA32DDA9485ED88B0A /* json_pointer.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 58BD9D02F092420900C9A91F1FEE94DF /* utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 94E0F561370BA98565BFE8AB2C1009E0 /* utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 58E45E924CF947D43546B0BC561552E4 /* json_pointer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59A6ED2700886866121E44BBA8816C68 /* json_pointer.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 58FCFE9AA04828E2B937CD8857C49656 /* FViewProcessorResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 42174118D83E777F4DC7503F4BADCDDF /* FViewProcessorResult.m */; }; 5913CADEB9E1AF0E6BD0C4F928F2FB04 /* RecoverableError.h in Headers */ = {isa = PBXBuildFile; fileRef = A1B11C8E6A6B0CF082119A417B2238A6 /* RecoverableError.h */; settings = {ATTRIBUTES = (Project, ); }; }; 5919A40C16C1305A1741579B7A91EBC2 /* LOTKeypath.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C2B7801CC73D3FD710970C5A7C482D8 /* LOTKeypath.h */; settings = {ATTRIBUTES = (Project, ); }; }; 5927F590412EE2EEB3AE256625881BA0 /* RCTModalHostView.m in Sources */ = {isa = PBXBuildFile; fileRef = BE49BF6A5B015C7C7A205AC35FBF1525 /* RCTModalHostView.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 5964EBF5F7CC7918DB0FCC45C571CF45 /* fast-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = 17D71D051405FFD0A9EC92F14F4AE0F0 /* fast-dtoa.cc */; }; + 592D03551BFA5B934AFAEAD09CB5FD29 /* FNode.h in Headers */ = {isa = PBXBuildFile; fileRef = B991E2493BC8E88470D17EF78E3D3A3C /* FNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5964EBF5F7CC7918DB0FCC45C571CF45 /* fast-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = E4F17079DA08EE5B499986B263AA74E1 /* fast-dtoa.cc */; }; 59B041A33035721C0921FEA242038F26 /* RCTRootShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AF188074BA189C66E4E1A65F5CDF624 /* RCTRootShadowView.h */; settings = {ATTRIBUTES = (Project, ); }; }; 59BAD2EA4C402FB2AB2FD62F09FB79E5 /* LOTShapeGradientFill.h in Headers */ = {isa = PBXBuildFile; fileRef = E4541339B70BD38568F4086EFBDF27F8 /* LOTShapeGradientFill.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 59D1C8039C0715353C070B15A246E60F /* GULNetworkURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 82A67AD1F41497CDE05BE0D941580CEF /* GULNetworkURLSession.m */; }; 59E36DF4FF3C27944DB88A38AD284A94 /* Utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F88B7517C24189335EE9DBE58ABE0C93 /* Utils.cpp */; settings = {COMPILER_FLAGS = "-fno-omit-frame-pointer -fexceptions -Wall -Werror -std=c++1y -fPIC -fno-objc-arc"; }; }; 59E952F0FFC47B0F6B535660A78CA743 /* RCTAsyncLocalStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 0955504CC40828288DE3ACD2B86BDC98 /* RCTAsyncLocalStorage.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 5A1E4E71C134D34A5A9435F54C6CAE86 /* Timestamp.pbobjc.h in Headers */ = {isa = PBXBuildFile; fileRef = 965A11AA7991DDB3973C8D73A71FA994 /* Timestamp.pbobjc.h */; settings = {ATTRIBUTES = (Project, ); }; }; 5A349334DB410375E63CF4EF8D450640 /* Utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 5883E68EDE439141E868243B72A3E48B /* Utils.h */; settings = {ATTRIBUTES = (Project, ); }; }; 5A4A9D53AB4F27BF47B16D6FEF5DD453 /* RCTStatusBarManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E507AF1A669A51075286F3DF0C16F451 /* RCTStatusBarManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 5A5BD9B87A4C74452B6C0FCDBBAAA9B5 /* GULReachabilityChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D65282280EFE00FDF44F5A44A8134F1 /* GULReachabilityChecker.h */; settings = {ATTRIBUTES = (Project, ); }; }; 5A5BF0CF46C3141609DB76C5EF06A3D7 /* RCTInputAccessoryViewContent.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B378C8781F4CC8F505149DA1C8ADA2D /* RCTInputAccessoryViewContent.h */; settings = {ATTRIBUTES = (Project, ); }; }; 5A6FA379B53F40CDF7AB89C71AFC7A30 /* RCTNullability.h in Headers */ = {isa = PBXBuildFile; fileRef = E16C2A4C6133D17287DD7C76EC852FC1 /* RCTNullability.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 5AFE13968D9DAEB7BB20884538B107B9 /* RNFetchBlobFS.h in Headers */ = {isa = PBXBuildFile; fileRef = 0416AA6600923BDD6D86D764FF7245BD /* RNFetchBlobFS.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 5B11245B0B3D367D144172E1A32363A6 /* GTMSessionUploadFetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 50AD35B3BB2CAE00789A8EEB035CDE08 /* GTMSessionUploadFetcher.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 5B119B24B1D6E01777FE7FCC1D54698F /* GULNetworkURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = DB968FBE67FB3F234237A2BBB1574133 /* GULNetworkURLSession.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5A9B64DE9ACE2179EF597CB050C4027E /* FirebaseMessaging.h in Headers */ = {isa = PBXBuildFile; fileRef = D891B248FC73F84B37DA8C9BCEE57D8E /* FirebaseMessaging.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5AEAA2770B94FA077E506696F5EC45A1 /* GTMNSString+URLArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = E78736EF22E1BD2BBBA9FC6AA32A8EA0 /* GTMNSString+URLArguments.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5B4781A080ADFC278CCEA27F494DBF5C /* FIRMessagingDelayedMessageQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 5177F3CD579B574CBC9F2649190E4693 /* FIRMessagingDelayedMessageQueue.m */; }; 5B9F14A619ED8D990D717D9C9A7466D6 /* SystraceSection.h in Headers */ = {isa = PBXBuildFile; fileRef = A2788A21B377EE2915E672FBD225D3DA /* SystraceSection.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5BA4ACD6BF65A8541083FA1CFA590555 /* db.h in Headers */ = {isa = PBXBuildFile; fileRef = 712333C1507824756FE2CF1F681ACB7E /* db.h */; settings = {ATTRIBUTES = (Project, ); }; }; 5BC7F6EB6E91D78C560C8FA507E117A7 /* RCTBundleURLProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 863BBD064846E7D63EE919F9B1A7E593 /* RCTBundleURLProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; 5C0A16AD069F8DBEA8EE0CFFB3FD0F12 /* ARTRenderableManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 72F4DE19A8FA046681F301783248F5FC /* ARTRenderableManager.m */; }; + 5C536868F97347DAFE85E5F1A9D7E703 /* FIRMessagingCodedInputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 845976E40CFA65B0DEBDDFB5EE10EF94 /* FIRMessagingCodedInputStream.h */; settings = {ATTRIBUTES = (Project, ); }; }; 5C9DE72892745A40A2082AFEF145336D /* RCTRedBoxExtraDataViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A89542AE5AA5DE9542FE4B8387D671F /* RCTRedBoxExtraDataViewController.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5CD529C806CFA1E7537EE273DA852501 /* RNRootViewGestureRecognizer.h in Headers */ = {isa = PBXBuildFile; fileRef = D6A066C924E3B5578BF58A340D1BCAA3 /* RNRootViewGestureRecognizer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5CE87E371FB6152A3EE39064A8480030 /* FTrackedQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = 972D70808FEDD70C15F55B7E8015CC79 /* FTrackedQuery.m */; }; + 5D02A5078E708729C3F9D749D4CEC628 /* GULSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = 0AAB4A3659EDD277935020E5576C79ED /* GULSwizzler.m */; }; 5D2928D6E7D4F9E300E26CB2EF585455 /* RCTObjcExecutor.h in Headers */ = {isa = PBXBuildFile; fileRef = 0479ECCB459541332FD74AE6FF8170CD /* RCTObjcExecutor.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5D471E97EDDB85894A1188803D7DE67C /* FCachePolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = 8C67F76BA60F26BD2E805CB7688786F3 /* FCachePolicy.h */; settings = {ATTRIBUTES = (Project, ); }; }; 5D4DC3A2E5D3087288C2995679B53AA9 /* LOTRenderGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = CFB316B0BA41A32B18B88ACA1666EEC0 /* LOTRenderGroup.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5D82FEA63F7DB79FC729411E92D89003 /* FIRDependency.m in Sources */ = {isa = PBXBuildFile; fileRef = 87BF0D472913B05794F194F52D37FBE3 /* FIRDependency.m */; }; 5D9FA40B48291754DF51D6C4D67BC0C7 /* RCTInputAccessoryView.h in Headers */ = {isa = PBXBuildFile; fileRef = 260F9C12700347670BE4AB984A2C3EDF /* RCTInputAccessoryView.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5DB35591B9D81A7B4DC4517FA43733FE /* status.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B2C069F9D6B52B8EB4CD32898783208 /* status.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; 5DB9D2D55BEC5F962CEFBCCC9D7B802A /* YGFloatOptional.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A3A7C992B818A68729BDA2C5F9F693A /* YGFloatOptional.h */; settings = {ATTRIBUTES = (Project, ); }; }; 5DCC964E2C749703950AED8F35F7F6DE /* RCTTextAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = 2FA53F3F29CD7D55AFAFD70D621F2BFF /* RCTTextAttributes.m */; }; 5DDAF4DD2A242DBF9E319F39B6B1FB0E /* RCTDeviceInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 673E0523607CC30F0D3C0B43797DF375 /* RCTDeviceInfo.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 5E30825D0D6A418223D99C5A39E86068 /* FIRMessagingPersistentSyncMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 56E2A60C3BF0245E931C0022D13A3EFC /* FIRMessagingPersistentSyncMessage.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5E37D63A65F2665B8D444C5FD1FE0A70 /* FIRErrors.m in Sources */ = {isa = PBXBuildFile; fileRef = F7454AAA8611460E40072A8242598B1B /* FIRErrors.m */; }; 5E5243A3ED955430BCCFAA396CB7C7B3 /* LRNAnimationViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EEDC241C41A1D77AB05E9263C629A53 /* LRNAnimationViewManager.m */; }; 5E529BDF20F4ECC43279D056FEADCA99 /* RCTNetInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = B8438D27F7F395EBCA298C48C6D2D2FF /* RCTNetInfo.m */; }; - 5E6DF8B8EC31FC15983978492CC7F857 /* GPBUnknownFieldSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A4E6E17CDE7E172CD43CCC6944BD67A /* GPBUnknownFieldSet.h */; settings = {ATTRIBUTES = (Project, ); }; }; 5E8CD77081728E05D2CACF16C6FD7808 /* RCTConvert+CoreLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = EE4762BA1F671BEDC7AE5E7D8F885A29 /* RCTConvert+CoreLocation.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 5EC6BCE473AC1E5689014FE96BCC7E4F /* RCTCameraManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B37984E6B75620169C999C514D4145A2 /* RCTCameraManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; 5EC7A6137370D89638B9D46D137E0355 /* RCTAnimationType.h in Headers */ = {isa = PBXBuildFile; fileRef = 8DE4FCE791E34E4C3BA04A067B420E49 /* RCTAnimationType.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5EFFDD6C81BE995B2B349B431A51EF9F /* FIRMessagingPendingTopicsList.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E5BD7D7208DA0C99017C1E9935E47D0 /* FIRMessagingPendingTopicsList.m */; }; 5F0206429E2E4B5C0D1AA6A014D9D04C /* RCTInspectorPackagerConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 717FE23B07E8513D81BBB492914623C4 /* RCTInspectorPackagerConnection.m */; }; + 5F44773753D3041C24DFC20E0F678BCC /* FieldMask.pbobjc.h in Headers */ = {isa = PBXBuildFile; fileRef = DAAA36549110648BA6C2F58F29780FED /* FieldMask.pbobjc.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5F48331C117925B91F2946F3989A9026 /* FDataEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 297D93EF3C8789F0A1EC74DD2721C0B3 /* FDataEvent.m */; }; + 5F56D23C49524428EC03E62D2A6B108D /* FIRConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = D4C24610BD75A9F8F6DA40D2196CD758 /* FIRConfiguration.h */; settings = {ATTRIBUTES = (Project, ); }; }; 5F75F3E44E3979F24060B029A449A341 /* RCTTextView.h in Headers */ = {isa = PBXBuildFile; fileRef = 204F2399882F7EAA57373166A055F8A1 /* RCTTextView.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 60028AF82A0190939D7D440FA2890635 /* RNFetchBlobReqBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = EA6B4E3FFE92057716DC762718518A3D /* RNFetchBlobReqBuilder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6030828805A49C92E7A0218F0754AAE6 /* FTupleObjects.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A9D1C75BADE6BF64AAA760F711269D2 /* FTupleObjects.h */; settings = {ATTRIBUTES = (Project, ); }; }; 604EA8D47EA4DF5919009682858D940A /* RCTProgressViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 803BFBC6CDDDE19EF8A63FA2D4B924FF /* RCTProgressViewManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 605F02D912F1E87876CB61CEF41AC3ED /* RCTPickerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 471256E31D0FB00CD281E6DE5E334F0C /* RCTPickerManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 6082B5DD8B4043912B10804597948102 /* RCTRefreshControlManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AE3425C16A423035FDA69B385FB469A /* RCTRefreshControlManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; 60B482866B922ECF6C8F9B45F8C98025 /* LOTAnimationView_Compat.h in Headers */ = {isa = PBXBuildFile; fileRef = 5683B5FB1C42A4A9787FB8F57D839142 /* LOTAnimationView_Compat.h */; settings = {ATTRIBUTES = (Project, ); }; }; 60F95D6CFDBAEFA8985675D2C0BAC35C /* RCTSourceCode.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A4D7E1040FFE7B7D05950F04D10D4D5 /* RCTSourceCode.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 60FF57BCE46DFA609230E4EF1E0454A3 /* SafariViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C6BFB18CCE8A1FBE4A3B8FD6C5663A0D /* SafariViewManager.m */; }; 610BBF25B7B7B0755497C9CCDB6D16B4 /* JSCRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A890C30E0C5AE2973D5A95747EAFFCD4 /* JSCRuntime.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 61548808FA1EE156F49E02086A23918C /* RCTTiming.m in Sources */ = {isa = PBXBuildFile; fileRef = 9AE6ABFDF7D0132D465F1710C4E9801C /* RCTTiming.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 6165C64977254E20FF5B5A9CCE5BD21F /* FTransformedEnumerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A7BA2DCF1D8BC5B1D2E1B940D8066D1 /* FTransformedEnumerator.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 617D495AFE507A66662D7EC64E37A6D8 /* GPBExtensionInternals.m in Sources */ = {isa = PBXBuildFile; fileRef = EDF5582CA0E76148091A5524FB1D31A1 /* GPBExtensionInternals.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 61A404F36C8BE86C5AA52A84020E8DBA /* lottie-react-native-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = CF98877DBA38E5D54AD5B9E4133C9EA1 /* lottie-react-native-dummy.m */; }; 61A7B2691B64C76674782B069C056262 /* RCTConvert.h in Headers */ = {isa = PBXBuildFile; fileRef = CBE050C384520225DAACA622107F16D7 /* RCTConvert.h */; settings = {ATTRIBUTES = (Project, ); }; }; 6227BC3E6B6300D2BAECFCE48BF05DB0 /* RCTPlatform.h in Headers */ = {isa = PBXBuildFile; fileRef = E0C50295F44644AD62228433168B8E42 /* RCTPlatform.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 62728BD7C32DBD3DACB67117AB9F8DB3 /* RNRotationHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B2F7643BC09CB61D842C17C7F3CD8B1 /* RNRotationHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6240D6CDB62655F6E6191ADED2DD268A /* FTreeSortedDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 8A49009D41FCF7B380C203917270C643 /* FTreeSortedDictionary.m */; }; + 6246130E1D89FFA2908B2455BFDF26B1 /* FEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = ABC865F02D8659D4C60C31F9E9C3A82D /* FEvent.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6293202483EED5142D5399921298F132 /* version_set.cc in Sources */ = {isa = PBXBuildFile; fileRef = A382B5DEBE7AB4A099F71363217CE031 /* version_set.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; + 63092FF5A06D72EDA9082BBEE3C51AA6 /* GPBExtensionInternals.h in Headers */ = {isa = PBXBuildFile; fileRef = 8627BB978197F51EFF396E4327FA065B /* GPBExtensionInternals.h */; settings = {ATTRIBUTES = (Project, ); }; }; 6352C47A29A22A11C145A99C47396A4A /* NSTextStorage+FontScaling.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D69450C3EF6D0FDE2FC78B917EDB6E7 /* NSTextStorage+FontScaling.m */; }; - 639C07DD67D426C054C6236414C91B70 /* fixed-dtoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 50F4AE7E1F3A99FA789591FE4516D16F /* fixed-dtoa.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 639C07DD67D426C054C6236414C91B70 /* fixed-dtoa.h in Headers */ = {isa = PBXBuildFile; fileRef = F10372658AF8256C69BF8332554C2705 /* fixed-dtoa.h */; settings = {ATTRIBUTES = (Project, ); }; }; 63A3ED94E3B821EE85636DB45AF14BFF /* CALayer+Compat.h in Headers */ = {isa = PBXBuildFile; fileRef = 7057CADF90B4D8695FEC8649999BAB3D /* CALayer+Compat.h */; settings = {ATTRIBUTES = (Project, ); }; }; 63BB0E04D41EE84D3B9FDEC72B1D4C7E /* RCTDatePicker.h in Headers */ = {isa = PBXBuildFile; fileRef = B8CAE2B67E055AAE161B2AFEC59A9566 /* RCTDatePicker.h */; settings = {ATTRIBUTES = (Project, ); }; }; 64021DFDE1E8FBD933581992C589016D /* RCTTiming.h in Headers */ = {isa = PBXBuildFile; fileRef = 56670206FA21065D6B0B080224D66A7D /* RCTTiming.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 6487691A1771BB2427E6188D91B93BCB /* react-native-safari-view-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A10DDC391DD1168DCD24BD98A2F09C8 /* react-native-safari-view-dummy.m */; }; + 647E7F9E51FA44165F698391BEE948D9 /* RNCameraManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E7BCDE68E4FC2A47B90EDF9E20BF4EB /* RNCameraManager.m */; }; + 6496C58ECA79C3DF13DEF88E3CD63CDA /* FMerge.h in Headers */ = {isa = PBXBuildFile; fileRef = B4AD0B7F0736B586F077CD29A43498C0 /* FMerge.h */; settings = {ATTRIBUTES = (Project, ); }; }; 64A7F1EBF967BAA809965F3079A84CD9 /* LOTKeyframe.h in Headers */ = {isa = PBXBuildFile; fileRef = 9837195654E0E5D0866423166511174F /* LOTKeyframe.h */; settings = {ATTRIBUTES = (Project, ); }; }; 64B33694FD99F9FB7A3E761CD7B3A606 /* LOTRoundedRectAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = 902FD3FE90F56C6A627A9362273086AF /* LOTRoundedRectAnimator.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 64C38D840CA38F2FEB8EFB3F62BF5EE6 /* GPBMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = D67703327E542502AE07DAA13C45E9D4 /* GPBMessage.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 64FBF91E9C36209D66272B6473D930B6 /* GULNSData+zlib.m in Sources */ = {isa = PBXBuildFile; fileRef = 82B76D98D30AA6642A0C7940342E89EA /* GULNSData+zlib.m */; }; 651B8A47AAAE9FC86EEE090FD812FB0A /* LOTShapeRepeater.h in Headers */ = {isa = PBXBuildFile; fileRef = A6B4F7B695D7FFDC077B98D08BFCE260 /* LOTShapeRepeater.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 651E5E714107123EFB21B8E85C677EFD /* RNPinchHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = CDA13C7FD544550D5933B17CF8D31051 /* RNPinchHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; 6525A5B2A4A69411AC94CF89A84396D0 /* RCTRedBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 9313714DA10D502647A5804C554C9E9C /* RCTRedBox.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 6538ABA053492B6165992DEF46E9113B /* FIRComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = BD9521758003CF81234DC8B5C4D59376 /* FIRComponent.m */; }; 656BD8A74D3E8CDA69480ACA0AB8E4AD /* LOTInterpolatorCallback.m in Sources */ = {isa = PBXBuildFile; fileRef = D29BC019266EA41E8FF8A9E9283737A6 /* LOTInterpolatorCallback.m */; }; 65757357DF21C2ECBBBC877678843980 /* ARTTextFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 71B20CCB72E6B6F7B565BB42E1FC512B /* ARTTextFrame.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 658D4AC1D34CED7BB2D3E081E4AE245A /* raw_logging.h in Headers */ = {isa = PBXBuildFile; fileRef = CCABEE37C670ACA6EC2203CB15D5088B /* raw_logging.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 658D4AC1D34CED7BB2D3E081E4AE245A /* raw_logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 33E3B98582281B282D18F8BC608009B3 /* raw_logging.h */; settings = {ATTRIBUTES = (Project, ); }; }; 65D016C104E79F527B95DCE0D658D1B3 /* RCTTransformAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 53AFE876BC5E44B03DD8FCE520321A7E /* RCTTransformAnimatedNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; 6669EC0E97498D9EB1819C7B6F14A42F /* RCTSpringAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EC39FF75C03F8EF4C12F41C0D574F19 /* RCTSpringAnimation.h */; settings = {ATTRIBUTES = (Project, ); }; }; 666B4C38D5A8C72250B031B52E66FCAA /* RCTTrackingAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = A912E2564D55F3C9C4C2676D6973C880 /* RCTTrackingAnimatedNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 667E8435DCC183B4743FF5656F97D468 /* RNForceTouchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 350C32D80852C78B7284508AF930D643 /* RNForceTouchHandler.m */; }; + 6699843C7D1A90DDBA6780F27C89955F /* GtalkExtensions.pbobjc.h in Headers */ = {isa = PBXBuildFile; fileRef = C03D805F3E975FCDCB26979447EF0A9C /* GtalkExtensions.pbobjc.h */; settings = {ATTRIBUTES = (Project, ); }; }; 66A9A87C67F780297CEEFBCAFB0D3716 /* RCTDevLoadingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 056951F1895AF99BBEB7DDE69213EBE9 /* RCTDevLoadingView.m */; }; + 66BF62C47DFACA717140724C6C2B7AD9 /* GtalkCore.pbobjc.h in Headers */ = {isa = PBXBuildFile; fileRef = C0F481DA187D9340471FBE612D71CD33 /* GtalkCore.pbobjc.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 66C94119E594089494A7319ECDC01E25 /* pb_common.h in Headers */ = {isa = PBXBuildFile; fileRef = F3C5C06ABF35C5C02A270D606DED2B88 /* pb_common.h */; settings = {ATTRIBUTES = (Project, ); }; }; 6703241DAD821B9AC74350A3AFCCFB9E /* RCTImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = F2111F6588DAFD858FEF540938E7E7B3 /* RCTImageView.h */; settings = {ATTRIBUTES = (Project, ); }; }; 67596E80B41F85F26983D84E69AF0ED0 /* MethodCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5091BE2A2FA317E87D81E7342544DC81 /* MethodCall.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 6771967EC2A3AE180866F1C1FF765323 /* diy-fp.cc in Sources */ = {isa = PBXBuildFile; fileRef = AF63990D5314AA2FE6B12AB99651E4D4 /* diy-fp.cc */; }; + 6761238C0810E18431677C55ABA8E015 /* block.cc in Sources */ = {isa = PBXBuildFile; fileRef = 6FB03253561D95AC814D0898B86FC6C8 /* block.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; + 6771967EC2A3AE180866F1C1FF765323 /* diy-fp.cc in Sources */ = {isa = PBXBuildFile; fileRef = FD226B9F64B84B90460570210B738B55 /* diy-fp.cc */; }; + 67996068CB093C6261229BF195E9C68E /* GPBDictionary_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 90B601B427F3F79EA0C870FACB123D08 /* GPBDictionary_PackagePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 67D82F41B93EC9583720DF80CB07030D /* FRepoManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B5CAF3C5A56B499167AC157F5AA1E79C /* FRepoManager.m */; }; 680F1BCF38E9224BFFABCAB25541CC56 /* RCTMultilineTextInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 78BC1C212B2CC12CC24696810D33B02D /* RCTMultilineTextInputView.m */; }; + 6856CED8F184BF34509C004C56600435 /* FIRDataEventType.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CC836083D4A964D223ED91DB13EAB5F /* FIRDataEventType.h */; settings = {ATTRIBUTES = (Project, ); }; }; 6858082014CCF6B7330527E533DBE437 /* RCTBorderDrawing.m in Sources */ = {isa = PBXBuildFile; fileRef = 7CF05035E70E34884130DF4C99791EF8 /* RCTBorderDrawing.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 68B17303F5B146360C757DE82C887581 /* RCTPackagerConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 12C85F0B8E6D79F3D6F9DD7B523A18CD /* RCTPackagerConnection.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 68CCD068CED1BAADD51D5D47A63D1D16 /* FIRComponentContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B5C38E88269258D4425BB6B3CEC1A39 /* FIRComponentContainer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 68F9564EEBF668B418191E282E8B0661 /* RNGestureHandlerButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 85E6E56A33A36BEB34C1AF48CC77EB02 /* RNGestureHandlerButton.h */; settings = {ATTRIBUTES = (Project, ); }; }; 6922ED532F7753969C1616CD211F2815 /* RCTImageEditingManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 99AC6FD61CC9CE5CFDD66C16EDCB1862 /* RCTImageEditingManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 69274AB05B6E38B4AA3EF4BAD1CC47BA /* RNNativeViewHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = AA89CDE0FD215108668B065F3BED453C /* RNNativeViewHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; 696167EA4531EF62C4BD07F1EB2C2082 /* ARTTextManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 057E16118AB23A0C841533BF0C3463B2 /* ARTTextManager.m */; }; + 698989DB531ABBE31DF0EE7FCC06B5EC /* FIRMessagingContextManagerService.h in Headers */ = {isa = PBXBuildFile; fileRef = E14F98E6F5EE4D75A64409BE058C39FD /* FIRMessagingContextManagerService.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6A2E01FF96B5E0C3553A9664F7E6DB9F /* FIRMessagingDataMessageManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 8FFF38C9E3F7CB5F4C45EC6F0C89C59D /* FIRMessagingDataMessageManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6A30FBDF51B3F81C00A7245E1FA6C99A /* GTMNSDictionary+URLArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = 32A0B6720F9A5E7B16DF805BAC9B4BE5 /* GTMNSDictionary+URLArguments.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6A36779AE89A2D8C580CB5B277AAE91A /* FPersistenceManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 33616753739FB63382C4F65ECE442123 /* FPersistenceManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6A65E6F53C547156F610BD9F11B682E7 /* filter_policy.h in Headers */ = {isa = PBXBuildFile; fileRef = 551F72DF002E8D67C63ED1DE0140ACC9 /* filter_policy.h */; settings = {ATTRIBUTES = (Project, ); }; }; 6A66E9C03B93C7A39A976C5F93412718 /* RCTImageShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9EC17D24BD4FD110021C6321BAB74C63 /* RCTImageShadowView.m */; }; + 6A692343B8F323E574DD2E870F9AEEBC /* FValueEventRegistration.m in Sources */ = {isa = PBXBuildFile; fileRef = D31E2D7BB58C00689E3BFF3B7399343B /* FValueEventRegistration.m */; }; 6A709FA966C9D9E6A5B33DCF8951D3C8 /* RCTPropsAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 90454C7B94BE46303481BA504D5DB04E /* RCTPropsAnimatedNode.m */; }; 6A73A6834B3C0142512FDCD1EF35DECE /* RCTSurfaceRootShadowViewDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 67DE87427E74AE70A903BC6AC4BC6EC7 /* RCTSurfaceRootShadowViewDelegate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6B1412BA1ACDECA1D4484BDC76461A38 /* FIRDatabaseReference_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 9FC8A2A184DB31E6141FB571B418F177 /* FIRDatabaseReference_Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; 6B22E212A5A8B59AF2562E887A88CA1A /* LOTBlockCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 1313984235EF5F0640B20BC58ECCE6FC /* LOTBlockCallback.h */; settings = {ATTRIBUTES = (Project, ); }; }; 6B301139792E3943834176F9AFB0AC1C /* RCTTouchEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 354F3741B3D98EF94AEFE9A3A72118C5 /* RCTTouchEvent.h */; settings = {ATTRIBUTES = (Project, ); }; }; 6B347BDECF811BDB6E6C228CA3CCDC08 /* LOTArrayInterpolator.m in Sources */ = {isa = PBXBuildFile; fileRef = 68B7BFBD5F19AA93B5F6A8AA6F9BC091 /* LOTArrayInterpolator.m */; }; 6B827278A553EAB3D6F191456EA56D11 /* ARTBrush.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F2AF4334192AED4630043ECF25E747B /* ARTBrush.m */; }; - 6C041CA0E482DC0EBA10AC8B07115688 /* bignum-dtoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 562EFD18A443FC75D1F2A7C9E1BFBEED /* bignum-dtoa.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6BCB0DBB1B39D69EF7310F76AB5DC2CB /* FLeafNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 59E80B5F2FA215DB1789FF68C3AB8EBE /* FLeafNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6BE50A02CB9BEB605A0015BE8D395676 /* FOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 97038520199DADF5850A500588C4A880 /* FOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6C041CA0E482DC0EBA10AC8B07115688 /* bignum-dtoa.h in Headers */ = {isa = PBXBuildFile; fileRef = E4EA040473FF29F9FB33D19CA9E5D77C /* bignum-dtoa.h */; settings = {ATTRIBUTES = (Project, ); }; }; 6C15FCF56333CE6D760988844D640C16 /* RCTDevLoadingView.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B65BEDF98A9DC36BAE9E390414D143A /* RCTDevLoadingView.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 6C304831B984511F20CE8F70C6DBFAA4 /* RNImageUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 73FB83B5567B867C643ABD764A2CC524 /* RNImageUtils.m */; }; - 6C6718E9960F07F3D248FE984E5EFC84 /* GTMDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B166C99A5BAB626C5AE7A6B572EA8F1 /* GTMDefines.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6C174498316C14889CFD89E79E1C21A0 /* logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AD9246D1D4092E3286681D4F885BC9D /* logging.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6CBF0F9FC4DC93223523EE17B60407C6 /* FPriorityIndex.m in Sources */ = {isa = PBXBuildFile; fileRef = F2B6BA82BA68EC9759243F03F20A4E92 /* FPriorityIndex.m */; }; 6CD9CD5B5BA2E1B2E78F2A70D7D7F8BA /* CompactValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A7FD36CD8B0DDBD2D2B211B252A8F93 /* CompactValue.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6CE0B8E7937DFDDA4F7711C870EB8018 /* RCTCamera.h in Headers */ = {isa = PBXBuildFile; fileRef = 610EC1E202A0352FCB800B241B92D083 /* RCTCamera.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6CE81693D166A4B948D52F6637C6DAF4 /* GULUserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = EFA1763DB7C1831455E270524CADA3B2 /* GULUserDefaults.m */; }; + 6D08E404B5A52E32A85FB9057FDF9579 /* FIRTransactionResult.h in Headers */ = {isa = PBXBuildFile; fileRef = BFAA8B4261AA8616E6962307CE1E10B6 /* FIRTransactionResult.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6D3E3C6D6921ED5FA3228507212B9CBE /* react-native-safari-view-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A10DDC391DD1168DCD24BD98A2F09C8 /* react-native-safari-view-dummy.m */; }; 6D8C744925DF6A4192C08872B59A4484 /* RCTDevSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AEB7903B8C74355D0296B3B43D50927 /* RCTDevSettings.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6D8E93AC07AEE6B6E8B0755086BD301E /* GPBCodedOutputStream_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = F185A3E96AB8074C9B448A3A346AFCC8 /* GPBCodedOutputStream_PackagePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6D91DF9734AB514E0E29715FA89FF878 /* FCompoundWrite.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FE8D8BD4DB7927197E7B596371BCEC6 /* FCompoundWrite.h */; settings = {ATTRIBUTES = (Project, ); }; }; 6D9F9B35D4087C4623D7C6DF4356EF1A /* RCTAccessibilityManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 501A740F38D382633F06137DB932BED5 /* RCTAccessibilityManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 6E26435DC619D6F307CB0CEEE2C62E06 /* react-native-slider-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = CBBC3D6FF5DD9F28B52AC5769D2DCA85 /* react-native-slider-dummy.m */; }; + 6DAF8B615791129D99F654AE376BDD68 /* Pods-Kalend-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F9BB4CBCB450B127736E624E673744A /* Pods-Kalend-dummy.m */; }; + 6E18158E049EBF824FA9AFAEE97A5357 /* RCTCameraManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FE0D685632B5D653CAD70F3ADE15857D /* RCTCameraManager.m */; }; 6E304461B9D7BCAB7A6B5ABC9CFF8A16 /* RCTSegmentedControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 404C190CC8198E5D961D90022D883B23 /* RCTSegmentedControl.h */; settings = {ATTRIBUTES = (Project, ); }; }; 6EA1F127D76804FFF2A4107B67CB11F9 /* RCTNativeModule.mm in Sources */ = {isa = PBXBuildFile; fileRef = B9E0C3F7D941425B2461E5751C15ADF1 /* RCTNativeModule.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 6ECFB2695D23D31F39CFC6152888131A /* LOTTrimPathNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 164F9C8C1B9350383134F306BDFF8D13 /* LOTTrimPathNode.m */; }; + 6F1B9ACBE8AD95E9BDDDE9BBFAF9574E /* Duration.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 37ABB67EB8FC12697EBA5E61AB7D193D /* Duration.pbobjc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 6F249E16421FF3CD50ED7AB52C4E7C56 /* FIRMessagingPubSubRegistrar.h in Headers */ = {isa = PBXBuildFile; fileRef = 2EBBCAE335DBBFEA14BA90A678C4A32B /* FIRMessagingPubSubRegistrar.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6F6C30FE3ED4302E998E217F6E9967D8 /* FOverwrite.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FF006F9B14B4A5F20A8D153F088C1DB /* FOverwrite.m */; }; 6F749407C4D27D3489D1010C62A098E8 /* InspectorInterfaces.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42664F57FEAC8CCF1ED5C28F6D5ABE90 /* InspectorInterfaces.cpp */; }; + 6F91922DB8040D6B61FD0C95F2A551A3 /* FIRMessagingPacketQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = E206E0CCE0AAB0D92428779769DF2674 /* FIRMessagingPacketQueue.m */; }; + 6FA156517C0BD710286599F90D810C02 /* FUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 073FA4385301B0EDD8CBBE54E0A85814 /* FUtilities.h */; settings = {ATTRIBUTES = (Project, ); }; }; 6FA1FC6CF545650B46888A781171709C /* BVLinearGradientManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FDB57154FD20A94DEBC19617F121F6D /* BVLinearGradientManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; 6FA5D6EAAD9D6DA9FC39D75A17371EE2 /* LOTCacheProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F7ABF393796AFC79A50CCB443FD285D1 /* LOTCacheProvider.m */; }; 6FD15D8D6A57FAAF8DC316637697A586 /* RCTFileReaderModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EF9CF21CA97F3E245FF3C7C05FCC207 /* RCTFileReaderModule.m */; }; 6FEE825BC3D863BFB7ACC669C6BD0319 /* RCTRawTextShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = F5F89201B26BC1E9C24CB18A3D18A712 /* RCTRawTextShadowView.h */; settings = {ATTRIBUTES = (Project, ); }; }; 6FEE8EC9FEF0593B4F912B097E33044B /* RCTSurface.h in Headers */ = {isa = PBXBuildFile; fileRef = A15ACEF5251CA6929F77B10C034BAB29 /* RCTSurface.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 705968212B3112EB4E8E3ED0C1534B49 /* FIRAnalyticsConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = DAD798862C9706CF2AD96981528491E6 /* FIRAnalyticsConfiguration.m */; }; - 706BE2D559547C6B3D97103F4E10064D /* GULNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = 350524E76529714B8516ED0B3AB7635C /* GULNetwork.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 715D4D977A023888E81E503AF1C27763 /* GULUserDefaults.h in Headers */ = {isa = PBXBuildFile; fileRef = F16040E0616BC0C5392F632DE49C3BEA /* GULUserDefaults.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6FF88CB95D0349D384DAF1346B5A6409 /* FIRDatabaseQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = 14CCBBBF8B62D60B9B16C63F39BDBDA1 /* FIRDatabaseQuery.m */; }; + 70C446632296926808151BF809059293 /* FIRServerValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A6CD0729441F2880CBA9BBEEE9104CE /* FIRServerValue.m */; }; + 710FDBA24280D878AC65B1E38B136324 /* filter_block.cc in Sources */ = {isa = PBXBuildFile; fileRef = 40799FECEBD3623D6C8B1C70ED1823BA /* filter_block.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; + 7151734535AE1DDC2F81A35828AFC079 /* FViewProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DAF410F81561E974F2E4070A0334FF2 /* FViewProcessor.m */; }; 716291F94033C915EB52BF6F2F6E9B88 /* BVLinearGradientLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 29B293C5E2E1A65C90676AD7F889DA73 /* BVLinearGradientLayer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 717C7B1F58028417564B42BD580F2FD3 /* FTrackedQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = D7A0F65DB920061ABF199FC50A40FA72 /* FTrackedQuery.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 71C3353E24B694C0A9EBBBBE47F475A7 /* FIRMessagingVersionUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = FDD801BB217E720037A5DACA23733155 /* FIRMessagingVersionUtilities.h */; settings = {ATTRIBUTES = (Project, ); }; }; 71CF4A638A18DD1EE95E2D4CB708A6E5 /* RCTUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 58D4FA35EFFE4B135722B03355E0F720 /* RCTUtils.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 71EEE5F718C3CA64CCC5E8E3E2EAF816 /* vlog_is_on.h in Headers */ = {isa = PBXBuildFile; fileRef = D9878295E9DBE9E1A357C2B8CE1C958F /* vlog_is_on.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 72614C46EA50ED4C0C6D0F22EA08CEE5 /* RNCameraManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FF470BC01770DA20B58E1154277FBA /* RNCameraManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 72CBCEF20BCC9BFA8F7B2E1F72004B2A /* RCTCamera.h in Headers */ = {isa = PBXBuildFile; fileRef = 610EC1E202A0352FCB800B241B92D083 /* RCTCamera.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 731C4D68A06F7E56EBF410363D58BCD2 /* GULObjectSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = 226E382223F53A8210A8E202F67338BA /* GULObjectSwizzler.m */; }; - 73EEB566925EC53FF283E67030464FF0 /* RNFetchBlobFS.m in Sources */ = {isa = PBXBuildFile; fileRef = F1C3036847AE6AE790A9289D590D4B71 /* RNFetchBlobFS.m */; }; - 742281C7D04AC6B80894EF222BDE7D20 /* FIRComponentRegistrant.h in Headers */ = {isa = PBXBuildFile; fileRef = DE06D8A8706390B6234D827E9B397F5D /* FIRComponentRegistrant.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 71E25D9FB28C8A20DA17C354E3A0A241 /* FPendingPut.m in Sources */ = {isa = PBXBuildFile; fileRef = 229EC03EE7326CEE9A1F6C1C8EB26333 /* FPendingPut.m */; }; + 71EEE5F718C3CA64CCC5E8E3E2EAF816 /* vlog_is_on.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CC3EF116CEB4E86A61C700DAF2FAF03 /* vlog_is_on.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7213586F7FB0AAF53BAB97C78810A3FC /* port.h in Headers */ = {isa = PBXBuildFile; fileRef = 11F954B9E1906E4B03C7590C9A888D93 /* port.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 733DAD9AE09EB1C0A875ACB80204D671 /* RNCameraUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 35CC5C005C98B39B79281E11E9E4BB01 /* RNCameraUtils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7387D76DE0A83A036759D86297D71E45 /* merger.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9C76269F60F7AC52CC5655F057186C7F /* merger.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; + 73A409A3B2F017BC99B3A8FCE2187821 /* GULLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 0FA1DA480D16C4A256F4422152880539 /* GULLogger.m */; }; 742463EA68672DFC495FDA3B3180DE50 /* RCTLocalAssetImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = D4CFC1ABBDCCAC32FE76345B5F1609D6 /* RCTLocalAssetImageLoader.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 742CC4D1F703A9BE1EB80152F102B99C /* log_severity.h in Headers */ = {isa = PBXBuildFile; fileRef = 907520142BCBA284CCB871DD47D9B4CB /* log_severity.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 742CC4D1F703A9BE1EB80152F102B99C /* log_severity.h in Headers */ = {isa = PBXBuildFile; fileRef = FEA943D1799FC73FC42813F1177AD37D /* log_severity.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 74401E5F3B22BF07478C2F13F23E2F72 /* GPBCodedOutputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F235E8C436E14FF6556F77D0ADA49DC /* GPBCodedOutputStream.h */; settings = {ATTRIBUTES = (Project, ); }; }; 74EDC2B1CF8B01B5E082143FBAAEE3EA /* RCTSinglelineTextInputViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E75454AA3F8D20AF2398992A93616888 /* RCTSinglelineTextInputViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 74F45499FDE9D20C016793B721D09C56 /* FIRMessagingPubSub.m in Sources */ = {isa = PBXBuildFile; fileRef = 91DB18116E45682289F6BAD1CED9DC6D /* FIRMessagingPubSub.m */; }; 7504AFEA66D7B598DB394102ACA4E444 /* RCTMessageThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 66CB5BB34B82627B60C1FC2096B4E725 /* RCTMessageThread.h */; settings = {ATTRIBUTES = (Project, ); }; }; 755A29C8A43B3AA4F834570266E6B464 /* RCTRootViewInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C6116C0F9BD4A3F5B51A63F2ED47FE0 /* RCTRootViewInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; 7577AC5AD725C9FE7FA641645A4EFB64 /* BVLinearGradientManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 01C890CACD06B7B63E14638617083B9C /* BVLinearGradientManager.m */; }; + 75923621F395B10BCEC3D9787219CDBD /* FRepoInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 224C97647A67A921AFF5BEF517FB27C9 /* FRepoInfo.m */; }; 7592C4C12315D4EE17D3F8D55A837A22 /* RCTBaseTextShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 62503FE6E7B7B5BD8F82C236CCBA3D06 /* RCTBaseTextShadowView.m */; }; 75A7C6DFFB9755EF1AA50DCD7A82C241 /* RCTWebViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F7CA64D8BA17A077DCF9F3D6559D84E1 /* RCTWebViewManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 75C9A545D28C8E2BD52C5F8E95B1F2EB /* RNTapHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 56F9D4CFBB73958CA564E272FA0824BF /* RNTapHandler.m */; }; 75CD40FB9B06ED1225080138343B1ED8 /* RCTLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = B7AE9A9D4A1B61B6EB9705A39931B56B /* RCTLayout.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 75EEBD44FE7B165241FD8E1FFB708768 /* FIRApp.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E6228157D6E72B153CDEF9FD2F04E8D /* FIRApp.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 7655B6BEAF1A60083C6DC06F90E9E663 /* GTMMethodCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CE3268860304C5F99F52C2E4444CCB1 /* GTMMethodCheck.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 767122C90F0670EB48E34494F33F1FF8 /* GPBArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 59A526190F6146A759532A4C61F5E776 /* GPBArray.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7634E5D555C8491F5632E9522034FDA6 /* FLevelDBStorageEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = 8780294E8D554541F2E815BCB528F0EE /* FLevelDBStorageEngine.m */; }; + 76503D48114EE373C53D1327D8CAE1F6 /* format.cc in Sources */ = {isa = PBXBuildFile; fileRef = A0AE80D03F26B3B90DB417809B76E098 /* format.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; 76818A273D234E1FA8EC5A8F5B40A320 /* YGConfig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08927525A90C0C9011727E3727DAE263 /* YGConfig.cpp */; settings = {COMPILER_FLAGS = "-fno-omit-frame-pointer -fexceptions -Wall -Werror -std=c++1y -fPIC -fno-objc-arc"; }; }; 7715F7025F00877B253E723E54AF0FAB /* RCTErrorInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 3E26A16EB9930837A5C4EBA6D2ACA06D /* RCTErrorInfo.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 771A92C7B9BCD5DCF7774F1471414504 /* JSExecutor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D2FB1FCF0A9BAC4F44D99ECFF16F1 /* JSExecutor.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 772F573E42C06F8FF78FF34EF22FE6A0 /* RCTMultipartDataTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 70AE67D41FC83E3674ED1D13700B576D /* RCTMultipartDataTask.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 7738ED46BFCE6891BB77C6B5D70BD938 /* GPBDictionary_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 67A6DC4F6F9CD4DE1E36CD36DD25E40E /* GPBDictionary_PackagePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; 7756FE7DBA3A0A5E08E31B3252E419A6 /* DispatchMessageQueueThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A874F9D8CA0329C9D492D46CEB3C103 /* DispatchMessageQueueThread.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 77989694A92E2CDB79C0D659E4B46B0D /* GTMSessionFetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = C5653F8D546A15A5F37363138529A92F /* GTMSessionFetcher.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 776EF5349F68D7B7F4545C2A147C9733 /* FClock.h in Headers */ = {isa = PBXBuildFile; fileRef = F1021C8F2B1FBF8AA49943F46258A907 /* FClock.h */; settings = {ATTRIBUTES = (Project, ); }; }; 77B9EF325D2112116F70977858891E40 /* RCTParserUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 7270F87015782FFE32E13F93F3D2503E /* RCTParserUtils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 77CE0D11D86FE5D5EBAC5195D4EA6055 /* RNFetchBlobReqBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 02164749E0FF8E59CB81D19A4E8F959A /* RNFetchBlobReqBuilder.m */; }; 77EF6F8659385B884B113D8981EBAD46 /* RCTLayoutAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 64025A2EC934909B86A3753FE5288DB3 /* RCTLayoutAnimation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 78017A8BE60C6A30F93751BFE9CCFE91 /* RNGestureHandlerRegistry.m in Sources */ = {isa = PBXBuildFile; fileRef = AF28386D4445A464FEEEC4A5F0DCEA17 /* RNGestureHandlerRegistry.m */; }; + 78543A920E1C1359F4E4DBF4772CD8C9 /* FChildChangeAccumulator.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C8C47ABA550DEE7AF6DB7793BD0F4B3 /* FChildChangeAccumulator.h */; settings = {ATTRIBUTES = (Project, ); }; }; 78560DD625F69296D355E9741F99F0AD /* LOTShapeCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = 2476CC9205C2943764C45EC9C1C2F26E /* LOTShapeCircle.m */; }; + 7860F7080050EF7E1CAEC963D6BB9626 /* GTMDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 43FAF91300BB0C423267A829E54A3897 /* GTMDefines.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 78808235156CED3A97287975E76C6248 /* GPBWireFormat.m in Sources */ = {isa = PBXBuildFile; fileRef = 76F353CA912399FEFC2D3D20C67AF7D4 /* GPBWireFormat.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 7891267E2488C0A9B31DFC513A2FF0E9 /* FChildrenNode.m in Sources */ = {isa = PBXBuildFile; fileRef = BD84C78C51CE9A9263693F3444B7571E /* FChildrenNode.m */; }; 78ACBE3B477E94C68DDEDB35E78C0DA5 /* ARTRadialGradient.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D7D7EB41053A679EA4EBD3418B75328 /* ARTRadialGradient.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 78B7CF9EFFAF48F6185834936FD96B7C /* FIRLoggerLevel.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F6860C06A97C95A108D783D81E2163D /* FIRLoggerLevel.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 78B924599AF584FFF2AA76F3267985C6 /* GPBCodedInputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B7B0F102C88F6DAF4C3966658C3C929 /* GPBCodedInputStream.h */; settings = {ATTRIBUTES = (Project, ); }; }; 78C471C40D3FC8414FB7EB63666F53B3 /* Pods-KalendTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4FBB5B3E944E4FBD37FA4466A28D61A1 /* Pods-KalendTests-dummy.m */; }; 790C42A3B3F0B9B5C4DD6D50CBAB50CA /* ARTCGFloatArray.h in Headers */ = {isa = PBXBuildFile; fileRef = F7DF0FEC55276C99C5115F3C88AF9D64 /* ARTCGFloatArray.h */; settings = {ATTRIBUTES = (Project, ); }; }; 794B8C19632AABBC581325AE6024E658 /* LOTTransformInterpolator.h in Headers */ = {isa = PBXBuildFile; fileRef = C2B8B3C008A656FAB91900CE428C9FCD /* LOTTransformInterpolator.h */; settings = {ATTRIBUTES = (Project, ); }; }; 7952680E112F855D6029EE1875A81932 /* LOTLayerContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 36608B3AA94AA71EC4319C20BB1DD3EB /* LOTLayerContainer.h */; settings = {ATTRIBUTES = (Project, ); }; }; 79790C9B724024A760FDEF57D704F11F /* ARTText.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A85634DF2B189D121BEA48B11F23B82 /* ARTText.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 79857180ED795BB5CB039C7A5BF8B2EC /* GTMSessionFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = B5DDE4132759E6E19918282C11B5F81A /* GTMSessionFetcher.m */; }; + 799C2589A30E062414DF38B8F5056D16 /* FEmptyNode.h in Headers */ = {isa = PBXBuildFile; fileRef = FF608C446C6174A7DC7F119C8A65AB96 /* FEmptyNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 799F320DAC6CD7D929CE0AD9C26F8931 /* GTMNSString+URLArguments.m in Sources */ = {isa = PBXBuildFile; fileRef = 3580EB0D6BC1342D553F04112A5AED34 /* GTMNSString+URLArguments.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 79F6F07B31F874240EAA809A98BCC896 /* RCTCxxMethod.mm in Sources */ = {isa = PBXBuildFile; fileRef = 631AB4B67AAEC51F6B69632AD9442693 /* RCTCxxMethod.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 79FB8AF3EB23406E5613BA5B673EEC9C /* FMaxNode.m in Sources */ = {isa = PBXBuildFile; fileRef = AE7A6AB9927CAC8E535EFB9EA04B6211 /* FMaxNode.m */; }; 7A0AAE58EE4786BCD4AD8AD1E2089BBF /* RCTImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = FD26EB05CA7B4C0DAE5C62273ADB52CA /* RCTImageLoader.h */; settings = {ATTRIBUTES = (Project, ); }; }; 7A1757F926F6AF6D96F9BB0A3DFBCC6D /* RCTSurfaceStage.m in Sources */ = {isa = PBXBuildFile; fileRef = 9AE23F4F482B346105F1E47522631516 /* RCTSurfaceStage.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 7A87B89DE54C46CEA06F91E990307977 /* GPBDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F9BB1D579C19AC9E2483A5F07973D6A /* GPBDescriptor.h */; settings = {ATTRIBUTES = (Project, ); }; }; 7ADAA3CD25072E9A76252803992B7C95 /* RCTBaseTextInputShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = DC2E2A6F9EEF1601DF370E61F6100CD4 /* RCTBaseTextInputShadowView.m */; }; + 7AF99B9C61C2B3E2092007A851A669A0 /* GPBBootstrap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E356741FE3B30C036009C1197254FF3 /* GPBBootstrap.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7B0A2D0C93F0AB344981881B2A495462 /* options.h in Headers */ = {isa = PBXBuildFile; fileRef = 42A113B02397B96427B9C3AFE74CB9BD /* options.h */; settings = {ATTRIBUTES = (Project, ); }; }; 7B3B154A3E1B5C16793F1B843103367E /* RCTFPSGraph.m in Sources */ = {isa = PBXBuildFile; fileRef = 01AE5F9E13FECB830F19C1C5CF8C3568 /* RCTFPSGraph.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 7B5598FBF3B26C9029C358D2DC7C3819 /* FIRMessagingRmq2PersistentStore.h in Headers */ = {isa = PBXBuildFile; fileRef = A06E21DE99BB96DBF43EA033D82CFCDD /* FIRMessagingRmq2PersistentStore.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7B59C5D0DCC19C961D37B0CB98C46782 /* RNGestureHandlerRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = B86F6404D1245E652DEBCF670CA27A4B /* RNGestureHandlerRegistry.h */; settings = {ATTRIBUTES = (Project, ); }; }; 7BA92A7CF6C0CC29583472B6051A0EA1 /* RCTDatePicker.m in Sources */ = {isa = PBXBuildFile; fileRef = C5B684709AC0CB3811821BE69E5E3A5D /* RCTDatePicker.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 7BE23A0E9F3B65F69CAC388F67F52CC1 /* RNFetchBlob.h in Headers */ = {isa = PBXBuildFile; fileRef = C630CAE6E614C60BBC8F4EB1C693F8E2 /* RNFetchBlob.h */; settings = {ATTRIBUTES = (Project, ); }; }; 7BE43F5B4686A5BE28035389D50B5D51 /* RCTExceptionsManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 79294B443523F14967C8D519B26477F9 /* RCTExceptionsManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7BF0B37C33B2B53D2281C11319271108 /* RNFileSystem.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BA903F2624EB644E66875057A6B8EB4 /* RNFileSystem.m */; }; 7BFE1AE975B65AC5D3C215256C7376A0 /* RCTConvert+CoreLocation.m in Sources */ = {isa = PBXBuildFile; fileRef = F32B512239740712D8C9850175735B91 /* RCTConvert+CoreLocation.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 7C0F462132BC8E3E0357371FC3F1FE8A /* JSIndexedRAMBundle.h in Headers */ = {isa = PBXBuildFile; fileRef = 85569D29BAAB1D11B5A8BECB44CB753D /* JSIndexedRAMBundle.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 7C106A1C989429BEED21855A31655120 /* GULNetworkConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 81E6CEE364947BFEFBB66A11AEEEC135 /* GULNetworkConstants.m */; }; 7CF14E6C90AEC8B350DD7CF612B1973C /* RCTFrameUpdate.h in Headers */ = {isa = PBXBuildFile; fileRef = CF8879FFDCEF10F7A3919F84FC294174 /* RCTFrameUpdate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7D8F8F119064991E7675A6AF1B761CEC /* FIRMessaging.h in Headers */ = {isa = PBXBuildFile; fileRef = CECB2E52A4D61E5EEC7F654E4D1E971B /* FIRMessaging.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7DD7FBF9D8507B1433ADDDC6840322C0 /* FRangeMerge.h in Headers */ = {isa = PBXBuildFile; fileRef = 050407348E20AAECDC9692CA87B3CD6C /* FRangeMerge.h */; settings = {ATTRIBUTES = (Project, ); }; }; 7DD9988B9240BAFF8A13BCFAFB849777 /* LOTCircleAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E22FDD307ACA7FA3FC8B70EA8A0EB0F /* LOTCircleAnimator.h */; settings = {ATTRIBUTES = (Project, ); }; }; 7DF6C1F94EC37E7B83E9005D432A1852 /* RCTWebSocketExecutor.h in Headers */ = {isa = PBXBuildFile; fileRef = 49A575D5C16F64CF2CE30FDB249FA60D /* RCTWebSocketExecutor.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7DFF9E849F894AE3A958272EF9336CA6 /* FChildChangeAccumulator.m in Sources */ = {isa = PBXBuildFile; fileRef = C392121EEC6B53EB2F5D7CCC636CE7E8 /* FChildChangeAccumulator.m */; }; 7E09C5B616F6E6C7981CC2C3132017CA /* RCTAdditionAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = BBF2272B1A787903B2FB330832E0A312 /* RCTAdditionAnimatedNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; 7E1015A773EDDBAA1A4A74D78CB1E2D0 /* LOTKeypath.m in Sources */ = {isa = PBXBuildFile; fileRef = 172872FF42AA7C8C52C78E317B897288 /* LOTKeypath.m */; }; 7E2581DAB864C0532BC7254DDCE81DAF /* RCTRawTextShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 40B36309908A3A11AA696B9A29C11A29 /* RCTRawTextShadowView.m */; }; 7E33E2A700CFE0C9D5C0F10A2FB3624A /* JsArgumentHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 9907C6D5C2C4CEC06370BFBC97558BBA /* JsArgumentHelpers.h */; settings = {ATTRIBUTES = (Project, ); }; }; 7E345DA1249D7583A60D84A83A471069 /* RCTPerformanceLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 91D9F2460233AE7E6D83D9731F784F10 /* RCTPerformanceLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 7E9F92CA976CAE831CD1DEA5602FCB5A /* RNFetchBlobProgress.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D0B242D922F068B949ED9BC7E5AF629 /* RNFetchBlobProgress.m */; }; 7EA309ED7833E6370777EFAF2727C493 /* RCTPackagerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = B079E7551271DB9993BC2E10B6003DFA /* RCTPackagerClient.h */; settings = {ATTRIBUTES = (Project, ); }; }; 7EB9AA29F39254AE6E070F20D2093AC1 /* RCTMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 55378F358C28BCA52E825CAF1B22759E /* RCTMacros.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7EC72EBAD6CF9A4EACD0E23075B3D44E /* GPBUtilities_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 535A732EEE2C5782F0E8756BE795DCDF /* GPBUtilities_PackagePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7F09CCC4EFA3B2DDDBB58B54DF0EB7DC /* FIRConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 8225C2C04620F9942D7441424A5CBBDB /* FIRConfiguration.m */; }; + 7F5CBB4DCB39A4973CC0E4C2A07DCDCB /* merger.h in Headers */ = {isa = PBXBuildFile; fileRef = 53DDAA6BA233D4B91F3EB8FD9014366D /* merger.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7F79F065477E8E91BA4CCFE22A311ED9 /* FIRDatabaseComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 304BBCFDADDF0EDDFD3A6000BC94FE7D /* FIRDatabaseComponent.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7F905C3328959B10CD5E3DDCC8279D97 /* FIRErrorCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D5A958ACB4439FA215BE021AE20B0D3 /* FIRErrorCode.h */; settings = {ATTRIBUTES = (Project, ); }; }; 7FD86058726995678BC0EFB41EEECD5C /* RCTUIManagerUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 8D7CC37D2809D0E76FAAE7E7CF45D5EF /* RCTUIManagerUtils.h */; settings = {ATTRIBUTES = (Project, ); }; }; 7FDBA52E55D5297D4E5F895E0AD355CF /* RCTFPSGraph.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C14CD2BC9A541C7E7BFB144938A0B60 /* RCTFPSGraph.h */; settings = {ATTRIBUTES = (Project, ); }; }; 7FDE8B5EC93F0F07876AF1B297F63009 /* RCTAsyncLocalStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = EC9761A203C14C2643FBDA81D466FE97 /* RCTAsyncLocalStorage.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; @@ -657,288 +882,432 @@ 80ACA974A8FA793CED01D6B8C7D7AA59 /* RCTAlertManager.h in Headers */ = {isa = PBXBuildFile; fileRef = ACDC49CC344315810A5B1ABC3B8A9E94 /* RCTAlertManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; 80CCA566116F548CC346777E870F5C95 /* LOTCompositionContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = DC3EAC6D58AE790C3E7FE90BC74D8871 /* LOTCompositionContainer.h */; settings = {ATTRIBUTES = (Project, ); }; }; 80CE063F93F6AEC5C9D0B91F3DC7484F /* RCTPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 507DAB37F96FF3E6A7084936E4E0599E /* RCTPicker.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 8102C51589B9D022052C49DAFF731DA9 /* RNGestureHandler-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 0458D0A7DAA406B4565D450B7D6B7545 /* RNGestureHandler-dummy.m */; }; - 81B7947A7E981BBD9FAFC8924255A3AF /* FIRAppInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DEA959471C355E2B056B18A9D36B924 /* FIRAppInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8138C2654E2DA8D84EA0AFEEF91CFE24 /* arena.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B0C51FA037711B40BF921BC4F2075A4 /* arena.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8141FE90E4E672569BCFD55D85EDEF13 /* FIRAppAssociationRegistration.m in Sources */ = {isa = PBXBuildFile; fileRef = B8117D0312D0C6A5E6D959942D8477AB /* FIRAppAssociationRegistration.m */; }; + 8158AC36DB53550096B9D2DD5703D5B8 /* FIRComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = F0C80DE6854B8FBEA2554B18BE095780 /* FIRComponent.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 817250CF85CC2E456BBD802C713FAAD2 /* Empty.pbobjc.h in Headers */ = {isa = PBXBuildFile; fileRef = 3822BBD2EAF04D86C912BA9D549D6B34 /* Empty.pbobjc.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8186BE010DB761EB637830C2A44F1B7D /* FCompoundHash.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B073494BCE05F22ECA7AAAD5ECC6F1F /* FCompoundHash.m */; }; + 81ADD00A0DC1A56565A2E80AC1104FB7 /* RCTCamera.m in Sources */ = {isa = PBXBuildFile; fileRef = 8A50D282DCFFDC13A41E028712B304E8 /* RCTCamera.m */; }; + 81DEFFD2AFF1DD97B3E57CAF3B4F8AEA /* GULSwizzler.h in Headers */ = {isa = PBXBuildFile; fileRef = 91CE28EB044818CC40BB467E58167F54 /* GULSwizzler.h */; settings = {ATTRIBUTES = (Project, ); }; }; 81E5C68B6EDF8BBD736B61A38B4A331A /* RCTKeyboardObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 44E2AF7684191EFD1A9D338205C5E64A /* RCTKeyboardObserver.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 81F9AF4E91592C358A88FE96209B7378 /* log_writer.h in Headers */ = {isa = PBXBuildFile; fileRef = F83F0FC48D1A44FFA4748EF0FB17C65F /* log_writer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 827B607DD0AF27A93FB4AA179DA09827 /* FTreeSortedDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 8D81569D4FB78A79815500605F8D4D1E /* FTreeSortedDictionary.h */; settings = {ATTRIBUTES = (Project, ); }; }; 83101D156861CD18904DD81EBF3138E0 /* YGNodePrint.h in Headers */ = {isa = PBXBuildFile; fileRef = D32405BBE0C577DA07F6E785FC7AEC81 /* YGNodePrint.h */; settings = {ATTRIBUTES = (Project, ); }; }; 835C745AB17FA03F9D91F2471079F7E7 /* ARTRenderableManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 222A1B2E02B1DA97A41401CD7B3315AA /* ARTRenderableManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; 83A0167B938EAE4712E769F9D6951BDD /* RCTFollyConvert.mm in Sources */ = {isa = PBXBuildFile; fileRef = 736B20E9BE1D6FD444F2B1BFE6DD3F21 /* RCTFollyConvert.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 842F7AEDC26D4C513F77B346CD86F72E /* FIRLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 4153397B595713F36B71DB3D53A7F8B9 /* FIRLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8448F725BFA533F2D3B517AD3E9FF2E6 /* RNFetchBlob.m in Sources */ = {isa = PBXBuildFile; fileRef = 03134ABA53AC736F9AC253EEC0A88AAB /* RNFetchBlob.m */; }; + 84BBEE716AA163C45A238F76AB0876AA /* GPBUnknownFieldSet_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 65850DA53C24DA8CA8584275DC5C7E41 /* GPBUnknownFieldSet_PackagePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 84CF740A031E631EE8CEF4F18B132F37 /* FLimitedFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F4CE8B42235E53F5BD9721CD57244D9 /* FLimitedFilter.m */; }; 850D56CB5F2640606827DA9A08F1B914 /* RCTAssert.m in Sources */ = {isa = PBXBuildFile; fileRef = D352A8B6C4B73D889DDC0EAB7F698163 /* RCTAssert.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 851581D982C384766E587884970388A7 /* iterator.h in Headers */ = {isa = PBXBuildFile; fileRef = D73F4F4A7162578699829D8BFEDACF6B /* iterator.h */; settings = {ATTRIBUTES = (Project, ); }; }; 85531E411E3812BD0DD0B5E576B2C3BA /* RCTUIManagerUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = BAC680A655CEE3D1226D0DF6DACB29D5 /* RCTUIManagerUtils.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 858220C8AF394C6F2CDDBAB67F55B88D /* diy-fp.h in Headers */ = {isa = PBXBuildFile; fileRef = F67BC7772FAF16CB5D795D8DF00C46DE /* diy-fp.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 857F14CBFA0F726866C9CBD1172A597E /* Wrappers.pbobjc.h in Headers */ = {isa = PBXBuildFile; fileRef = 55AF778DC11874FA59DADD2E7AB1ACD9 /* Wrappers.pbobjc.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 858220C8AF394C6F2CDDBAB67F55B88D /* diy-fp.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D1EDBB41D682CA19504C5D902951F7F /* diy-fp.h */; settings = {ATTRIBUTES = (Project, ); }; }; 859F10253FF7A8C268321265C3A781D6 /* LOTTrimPathNode.h in Headers */ = {isa = PBXBuildFile; fileRef = D8CCFAC19E7D657962E9E82D9CEEADDF /* LOTTrimPathNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; 85AFA931B1497B6831E737C133512466 /* RCTBaseTextInputShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = F11C17182C527BDE80AA800CCAAD1B99 /* RCTBaseTextInputShadowView.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 85C941090086B362BF94C4274EEAC2CC /* Demangle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90925193CFC8654619BC7A42DF98C8EE /* Demangle.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 85C941090086B362BF94C4274EEAC2CC /* Demangle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C74E5ED86914ACF3E7DFB35010DE2D5 /* Demangle.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 85CB7014145B1047A73137CAB121A224 /* CGGeometry+LOTAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 39C651A996DC0FA83F18E9A22B4CD303 /* CGGeometry+LOTAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 85EC7669A4ED0B18EE6C6A233C05BD8D /* RNFileSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = CD00DCE93642C11C81C8B55D2512DC9E /* RNFileSystem.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 85FC10DA6CCDEF9EA132AD221D5D5282 /* FTupleFirebase.m in Sources */ = {isa = PBXBuildFile; fileRef = 26E73ED066200F04541BEBB190059366 /* FTupleFirebase.m */; }; 864F24F053C73EA379CEB3AF1CF135E0 /* RCTTextShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A330D8AB6658D47D7439D2CBB8A05C3 /* RCTTextShadowView.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 866ACB952AB4073CCB35404BF9AA2F1E /* RNFaceDetectorModuleMLKit.m in Sources */ = {isa = PBXBuildFile; fileRef = A96DF853EEF2E09A81C89D05EAAD8DB3 /* RNFaceDetectorModuleMLKit.m */; }; 8681C7843C1A930C0C557709ED3BCE20 /* RCTFont.mm in Sources */ = {isa = PBXBuildFile; fileRef = BDAF4D00242A8AA51DB03DCB87800F6E /* RCTFont.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 869AF668891FC81F96210126E66E866A /* RCTBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 9EAED3F23E1A902278FD103C4314106D /* RCTBridge.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 8761E7B3DE15DDBEA0D14884181DD61A /* FIRComponentType.m in Sources */ = {isa = PBXBuildFile; fileRef = DF2213EE14498C8830860C206AA10A17 /* FIRComponentType.m */; }; + 86EEAAF7922FB1C7EA5400E9EBD762E2 /* FWriteTree.h in Headers */ = {isa = PBXBuildFile; fileRef = B647F3C3F6873E7E8E7E77C89EE80A03 /* FWriteTree.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 87110F690A602435E1CCDEB54A9F76E2 /* coding.h in Headers */ = {isa = PBXBuildFile; fileRef = 75C2BF4E24C1C4A8516CD1D3AE267D4B /* coding.h */; settings = {ATTRIBUTES = (Project, ); }; }; 876D2BCA060AEBAF3F089852471BE2CB /* MessageQueueThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 80407E3F969E6595C77DFCAC08CC985B /* MessageQueueThread.h */; settings = {ATTRIBUTES = (Project, ); }; }; 87710F4BD6B486C26D62ED4CA2F2B1E6 /* YGNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7943ABFECCB8CEB221228123155B36D /* YGNode.cpp */; settings = {COMPILER_FLAGS = "-fno-omit-frame-pointer -fexceptions -Wall -Werror -std=c++1y -fPIC -fno-objc-arc"; }; }; 87D2DB3AAE13B4550B3574DB358703C0 /* RCTSurfaceView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 32F5E016D93E5F7ACE3242CC25AE3BAD /* RCTSurfaceView.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 87D5755C40DD5FAEDD6F66888711B2EF /* RCTFrameAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = ED3E60F7ECD984F725643E49A4E75477 /* RCTFrameAnimation.m */; }; 87D80A8B3AD144BD2BFABBA1AE228AE0 /* RCTCxxBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 163707F9FE0CCEA43E6C380C04E6AC7F /* RCTCxxBridge.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 8853CDCC00C5A51CBC41612B9216829B /* FCompleteChildSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 35FC9E3E1747E42F7199467986DEEFE3 /* FCompleteChildSource.h */; settings = {ATTRIBUTES = (Project, ); }; }; 88D821CFCA8555D2A66193C3AED782E9 /* RCTFrameAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = FC78FC13F0EAB89D84791470CBF5CBF9 /* RCTFrameAnimation.h */; settings = {ATTRIBUTES = (Project, ); }; }; 88E48110CE45B302B1B6CCB70F2D977F /* CxxNativeModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AEE02FAFB329C410ADF0DEC592C517CF /* CxxNativeModule.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 88FFBB0FF9540A7C26BACE525BD74AC5 /* RCTBaseTextShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = 769615763CCB0E89898526841FDAC335 /* RCTBaseTextShadowView.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8906B1509CF40730BF06DF9AC6597F50 /* RNSensorOrientationChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = C12E589CC6B6291AE80132D0C18F34BD /* RNSensorOrientationChecker.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8907CC037F680B2A55E2CF257278A2B1 /* GPBMessage_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = B401B96BDEDB3229635D97BF950291A2 /* GPBMessage_PackagePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 89332FF66F6EC16A560B3B9970050FB8 /* FSyncPoint.m in Sources */ = {isa = PBXBuildFile; fileRef = B1AE50A8879222641AC18419CDDD872B /* FSyncPoint.m */; }; 89B9AE46EA638CF24978954C1A5BAF24 /* RCTSegmentedControlManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 355E84A45297B185E85080801ED38C24 /* RCTSegmentedControlManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 8A8B29120AC7C8F71729C0DCFB252FE6 /* FIRMMessageCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 50AA96879422B9860DF58C1C5F54ACB9 /* FIRMMessageCode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8A9F6D812AE8B6A23E4FB6155B76F304 /* FPathIndex.m in Sources */ = {isa = PBXBuildFile; fileRef = 6AB7F22E3C7682C14E733A9ECE01325A /* FPathIndex.m */; }; 8AA4BFD3BC3EF578F075DE4B4F06B856 /* RCTSurfaceView+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A5686B574C0F54F3F451488BC5747CDF /* RCTSurfaceView+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 8ACC27CC9FCE781F5F2E6E2461794D63 /* GTMNSDictionary+URLArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = D30915124033725D9B5D8D4201D28BA1 /* GTMNSDictionary+URLArguments.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8AD5227F67EE14DDD28699B584155B36 /* RNFetchBlobRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A858624BA6720E250FB69F3157BB5B2 /* RNFetchBlobRequest.h */; settings = {ATTRIBUTES = (Project, ); }; }; 8AD809C09E853B2EFBED535EC84E2DEB /* LOTAnimatorNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C4CE2EB080A0EC0E32273B5FBC17F82 /* LOTAnimatorNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; 8B01E80929B540A4DE0C26B137250E07 /* RCTDevMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = 84B7FFB90CB09D325C1290A677505E48 /* RCTDevMenu.h */; settings = {ATTRIBUTES = (Project, ); }; }; 8B1CF81442D39989E3BCC18341DB0E0F /* NSDataBigString.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2BDF846CF1664AC23BC15C5315AA9FE7 /* NSDataBigString.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 8B4698D4C15DD2E12F0ADA0446F3C3E6 /* RCTValueAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = F8430DEE28745D0D292FDB484995DE43 /* RCTValueAnimatedNode.m */; }; - 8BC33834645F99E5E5E9AE8130A909CE /* logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 74CEE568726ABC9EC073632676A4C3BF /* logging.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8BC33834645F99E5E5E9AE8130A909CE /* logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 55086ABF2F5769B99BC491AABF543073 /* logging.h */; settings = {ATTRIBUTES = (Project, ); }; }; 8BCA7AAE9A78BA3E4802370C855C28FA /* YGValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F998E92F8BC66D5A786DB4ACEAA93B5 /* YGValue.cpp */; settings = {COMPILER_FLAGS = "-fno-omit-frame-pointer -fexceptions -Wall -Werror -std=c++1y -fPIC -fno-objc-arc"; }; }; 8BD5ADE12AD807B199EC3E06BB0D3B14 /* LOTModels.h in Headers */ = {isa = PBXBuildFile; fileRef = E68CE192F943371CEEB4E2242D78068D /* LOTModels.h */; settings = {ATTRIBUTES = (Project, ); }; }; 8C06592EF76781AC5282FCA49C51AE11 /* RCTModalHostViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 734E1D0168D67B0851932A9E07A5265E /* RCTModalHostViewController.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 8C1EC8DD42562F3EA6D45C7D69FFA2A7 /* Assume.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A73AEA93339D92B2C110B4FFDE82B8 /* Assume.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 8C531E68DE1BF4F0D03E2C3F692ACFCE /* FIRAnalyticsConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = A066CEC53E71610DC720C640B5F947AC /* FIRAnalyticsConfiguration.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8C1EC8DD42562F3EA6D45C7D69FFA2A7 /* Assume.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C8C4EDEA0E251A3310090AF3E18556FC /* Assume.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 8C544E3B299547CAA3841C9E9E23EFDE /* RCTVirtualTextViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 10C464D5F1CF9BE605ADAFD754E5B607 /* RCTVirtualTextViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; 8C5B732A7AEA99B628A19CED96196E6A /* LOTArrayInterpolator.h in Headers */ = {isa = PBXBuildFile; fileRef = CAAA360C270F6154A4092B600351F423 /* LOTArrayInterpolator.h */; settings = {ATTRIBUTES = (Project, ); }; }; 8C5CFD3E338FD3698102E3EC2F3EA525 /* RCTRootContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = C1AC47ABA6BE0B3D265D386E69438D8A /* RCTRootContentView.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 8C808B338A2D5B045C899783338A148D /* GPBRootObject.h in Headers */ = {isa = PBXBuildFile; fileRef = BBB105BF3615DD99C8BDB51065E1D6F3 /* GPBRootObject.h */; settings = {ATTRIBUTES = (Project, ); }; }; 8D330BF671E352F7DD93CA2AA2747908 /* RCTUITextField.h in Headers */ = {isa = PBXBuildFile; fileRef = 192764F7F9F5627D9C7C178EBAF30A6E /* RCTUITextField.h */; settings = {ATTRIBUTES = (Project, ); }; }; 8D3BEDAB65D95F54B6E2A5FF0D504A5B /* RCTPicker.m in Sources */ = {isa = PBXBuildFile; fileRef = BC73B0FC9B3AC70C2CB7F58F34CDFB0B /* RCTPicker.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 8D4279D8D9E4FC6B8F0310F14ECC9D90 /* RCTInputAccessoryView.m in Sources */ = {isa = PBXBuildFile; fileRef = 962A34E023EEF408A4C1FBBEE8EF5956 /* RCTInputAccessoryView.m */; }; 8D59882D893E80BF211AE74359BBBE1C /* RCTGIFImageDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D6CF16F061EB2946CEAF00F8D5909B6A /* RCTGIFImageDecoder.h */; settings = {ATTRIBUTES = (Project, ); }; }; 8D875686983DA681E4B0461FA47AAE8D /* LOTShapeRectangle.m in Sources */ = {isa = PBXBuildFile; fileRef = 88D8A6966CF11F39006D3B576E26FCA6 /* LOTShapeRectangle.m */; }; + 8D9F03CDF6A4835EB7987327D421F621 /* FIRMessagingContextManagerService.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A27F2FAACB3CE33F2F156508EE98F6D /* FIRMessagingContextManagerService.m */; }; 8DB43E948553A2960C8E03DB2CF27C9A /* LOTStrokeRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 43F50708D562369FD044BAD3C270F45E /* LOTStrokeRenderer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 8DC4C9575113197C5BB1E7D3C33DF7EF /* GULLoggerCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 69DAFD5D0157639AA62C9A5B0260F34C /* GULLoggerCodes.h */; settings = {ATTRIBUTES = (Project, ); }; }; 8DD579D0CEAB95EEF816B185FD050A48 /* RCTShadowView+Layout.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D2689C07131170A9DC79F71ED14AB91 /* RCTShadowView+Layout.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 8DDEB41D6176F58B173AE37206CDCCF4 /* FWebSocketConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = C4FEF857D99B721AC9FA93B793FE4332 /* FWebSocketConnection.m */; }; + 8DE4F72442143404C46DEDCC929614C2 /* GTMNSData+zlib.m in Sources */ = {isa = PBXBuildFile; fileRef = FEF896D60E19DB40D4F2856F9A57C70D /* GTMNSData+zlib.m */; }; 8DE7179659E9300AF522BF2B9AAA42E8 /* RCTNativeAnimatedNodesManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B8E39E05CEDE3BAB149A097CF036769 /* RCTNativeAnimatedNodesManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; 8E07B68A25E1B860F05F7D57B98000FE /* RAMBundleRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 05DABF2A23A0CE9A83FA72582193EAF6 /* RAMBundleRegistry.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 8E46EE220B47CC65FA468AD09D94B6D2 /* vlog_is_on.cc in Sources */ = {isa = PBXBuildFile; fileRef = A52DFF00A66DC596AE662E6482F17420 /* vlog_is_on.cc */; }; + 8E17D99396C7FF3DE15E4D8D0280A704 /* FWriteRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = 48C04CC3873113348843DA33D0D9C28F /* FWriteRecord.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8E46EE220B47CC65FA468AD09D94B6D2 /* vlog_is_on.cc in Sources */ = {isa = PBXBuildFile; fileRef = FC87325B7FE134E2BA0D1F307D81C10A /* vlog_is_on.cc */; }; 8E854B1FD8E210BBD44004A8414C6D11 /* LOTShapeStroke.h in Headers */ = {isa = PBXBuildFile; fileRef = F503BAE598985D376AD676FCA2722218 /* LOTShapeStroke.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 8EB92E8192ADF4B246C62B91283C3D36 /* GPBProtocolBuffers_RuntimeSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = B43C5CAB0FF24DA68A1B4B097044C880 /* GPBProtocolBuffers_RuntimeSupport.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 8EBCA300E25FAF6D92D8E7ABC1A35B27 /* cached-powers.cc in Sources */ = {isa = PBXBuildFile; fileRef = 166091403FC4A8777527BE2435C87455 /* cached-powers.cc */; }; + 8E9CD32F54B2CDECF607C9C963CB7A2F /* FPriorityIndex.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FCB6D1827727575781B732B26E6B151 /* FPriorityIndex.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8EBCA300E25FAF6D92D8E7ABC1A35B27 /* cached-powers.cc in Sources */ = {isa = PBXBuildFile; fileRef = E51A57E86D7E23F9AF304C34332DD319 /* cached-powers.cc */; }; 8EE5E247EC087CE978F4D2701499B7AC /* RCTErrorInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = F276AC2354381D0874D7EF427D68BA36 /* RCTErrorInfo.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 8F0F3E85B60E20C6F28A34288631A908 /* GPBCodedOutputStream_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 251B3A4D5C73A6D5545A5C5D38F4E596 /* GPBCodedOutputStream_PackagePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 8FC021BA68F82BB8C1CE92621BADE1B3 /* GULNetworkMessageCode.h in Headers */ = {isa = PBXBuildFile; fileRef = FE918890A9495185DB1DF01F4612855C /* GULNetworkMessageCode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8F464C2DBA97E83917780375986EF33F /* FIRMessagingReceiver.h in Headers */ = {isa = PBXBuildFile; fileRef = D73650FB53553AA024FEED450D81D6D9 /* FIRMessagingReceiver.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8F9ACF806352B2AB444C4F6D70443F05 /* APLevelDB.mm in Sources */ = {isa = PBXBuildFile; fileRef = FBC96DFA9FE254B5A90E3FB1E0E87C05 /* APLevelDB.mm */; }; + 8FD4C98211BDAD30D9AF6B1DDAF062EE /* histogram.h in Headers */ = {isa = PBXBuildFile; fileRef = 0933D47EBA37DBA669BB91D37332294A /* histogram.h */; settings = {ATTRIBUTES = (Project, ); }; }; 9016542243DA41EE352308EB74FE4187 /* LOTPolygonAnimator.m in Sources */ = {isa = PBXBuildFile; fileRef = E7E3920695342A9DC9737F825BB5B785 /* LOTPolygonAnimator.m */; }; - 901690D2038CFADBCC94FDD88A405157 /* RNCAsyncStorageDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = E9F98E76BEE8F0638C877D1134193645 /* RNCAsyncStorageDelegate.h */; settings = {ATTRIBUTES = (Project, ); }; }; 9064D40652D1DA7BB4B75E8FA02A65E9 /* jsi.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CD8ABFCB5425BAB402EA483FD5E29D9 /* jsi.h */; settings = {ATTRIBUTES = (Project, ); }; }; 906BD060B53BE9C0CBE99D0ADDF7A09D /* RCTImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 931DC9AD1E113DBEC5E592853085D6BD /* RCTImageLoader.m */; }; 907D6E29AC2E68AC01E0794445FA2129 /* RCTSurfaceHostingProxyRootView.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DD1AB9F0A805291588A2A63A92AD283 /* RCTSurfaceHostingProxyRootView.h */; settings = {ATTRIBUTES = (Project, ); }; }; 907FA67FDC02049B978BFB79F5E0CA68 /* yoga-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 44C9DD523C62CEE9C68EE24148B935A2 /* yoga-dummy.m */; }; 90A7A3A444BF2ED85618B1C3CF8CC06D /* CALayer+Compat.m in Sources */ = {isa = PBXBuildFile; fileRef = 531481565D59FA89B019BAAFDEE12F70 /* CALayer+Compat.m */; }; - 90D94A80C8990BBBA0B1C0B21FA894C1 /* RNFetchBlobNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = 346ED9A09FF573F0481536CEDE22A26F /* RNFetchBlobNetwork.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 90ACBE3264A6FD02CEA37414106B9073 /* Struct.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F2541E8FA48C590154DE81E96C53239F /* Struct.pbobjc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 90D9A5727C4E73AC6D30F7C6224DD851 /* LOTMask.m in Sources */ = {isa = PBXBuildFile; fileRef = 93B2BA1259B01297817D30E62781994F /* LOTMask.m */; }; - 913BDC332A99FC637B1B6909E821A416 /* GTMNSData+zlib.m in Sources */ = {isa = PBXBuildFile; fileRef = 13049D05C3EA29CBF24A9BAD6E4B6DF6 /* GTMNSData+zlib.m */; }; + 90E728F7016943691BBCB3A450D8C437 /* react-native-slider-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = CBBC3D6FF5DD9F28B52AC5769D2DCA85 /* react-native-slider-dummy.m */; }; + 91329F83B642C7B66561408EEFC27CCE /* filename.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1D0FE567498F874EDCA9397BB8942691 /* filename.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; + 91545C780A082E4E6B1794C84DAAFF89 /* FTupleNodePath.m in Sources */ = {isa = PBXBuildFile; fileRef = 2582A15A70285331E519CBBEAEF231CD /* FTupleNodePath.m */; }; 915AD92CA5182253D0014DFCD0197AE7 /* LOTRenderNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 8EC44748D83175173382714006908D92 /* LOTRenderNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; 915CD3DDCA9F195C83C5ED9790657D6F /* RCTSRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 69FCDC7812C211776AF778267B3AB5EA /* RCTSRWebSocket.m */; }; - 91B2F2C709B82E146808C5CF710B3DE8 /* FIRComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EB3BB905ECB39DB9D7D567060436721 /* FIRComponent.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 91B6E9B150C998D2A5DE3D4B7D3F8EA4 /* GPBRuntimeTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FF78D17720D1DF41C6200A4DAA3A4BB /* GPBRuntimeTypes.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 917F64334A3A896FAAA29A86A142D815 /* env.h in Headers */ = {isa = PBXBuildFile; fileRef = CAF9F96F1F05C6595393D5C96BCEAC85 /* env.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9192638012FD251F4D774E5A10FA08FE /* Struct.pbobjc.h in Headers */ = {isa = PBXBuildFile; fileRef = 8648BC64286D754073CACC328B7BB68F /* Struct.pbobjc.h */; settings = {ATTRIBUTES = (Project, ); }; }; 91EFCC21973326F9538C657A25F0485C /* LOTRenderNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 72DE8883E97BF12D74E72919B77F3443 /* LOTRenderNode.m */; }; 91F577291EA17CF09B2B4A51B83E660A /* RCTBaseTextViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = A415059A03A7CB62357072B5157F8F3B /* RCTBaseTextViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 92F770D40FBED9F855E5C8820C317BD9 /* pb.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A003652CC3D84C54C2C705D53E16081 /* pb.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 92FD956D21F164CAD096A04461BFC0F9 /* GPBDescriptor_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 3F53BFB4A05790B07429F81FDFC82E28 /* GPBDescriptor_PackagePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 931A0D3EC2819746125A38C2CAE44BA2 /* GULReachabilityChecker+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 832D30811692600A1C71322C43578D87 /* GULReachabilityChecker+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; 931B8BB25C432ED0828182379FAC3FD9 /* LOTFillRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = BD7C6997D0323588A4202F3D69FF9640 /* LOTFillRenderer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 932376213FB869732DBE6FD1C053C4C1 /* GULAppEnvironmentUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 37F2C52AF05B020D5CD6CC5800BF1E2D /* GULAppEnvironmentUtil.m */; }; + 933A7C2D9883C6DDFCB8AAE58C2EB11A /* FIRMessagingTopicOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 65047FECD45DEE085062BEEF54A90E1D /* FIRMessagingTopicOperation.m */; }; 937807B849EDE6DC90EF3FC6FB02B9CF /* RCTAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C28B39638447DA22BA1B9F4E2DCE167 /* RCTAnimatedNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 93AC140E83211FFE7D73691EAA322208 /* FSparseSnapshotTree.h in Headers */ = {isa = PBXBuildFile; fileRef = 72A95C2BB95FD8729CF4444BE5B0899B /* FSparseSnapshotTree.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 93D28B57FAE0077A30CA494B9B88DFED /* GoogleToolboxForMac-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = F5529B22BE63AF18AE6DB17C4A3157CD /* GoogleToolboxForMac-dummy.m */; }; + 93D7E5FD58F8B01B1D245928683C42A4 /* write_batch.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E28567DA629BA3B509E5A6F78CFA386 /* write_batch.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 93DB9ECC1508D87CF429CB9FB9EF8014 /* GPBDescriptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 7C33485C8E12BB74635C0EB707C20FFD /* GPBDescriptor.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 93ECE632753E5506BA436EC46F562964 /* RCTDiffClampAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 03E6E83A0ACA743E9FB4084F3B63F9B0 /* RCTDiffClampAnimatedNode.m */; }; - 9437BF247A919FA627BDA660AB6CDA05 /* RNCSlider.h in Headers */ = {isa = PBXBuildFile; fileRef = 34BDF9CC5F54E3FC924C3B13CEF34797 /* RNCSlider.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9408BFD5A1622FF536810A93BE097BE4 /* FIRComponentContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E764F449658692454D522EA90DEDB37 /* FIRComponentContainer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 940BB98CCD896AE13E549A90A2963928 /* RNGestureHandlerManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 97539D7F20648B8EB3502B6C2D03DBA1 /* RNGestureHandlerManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 94133703D188AD0DB8CF45DD53C193AD /* fbase64.c in Sources */ = {isa = PBXBuildFile; fileRef = A996778AA6C82C606288542E389E64D1 /* fbase64.c */; }; + 9414CE4D67E3EEC035AEB00664A845F7 /* FCancelEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4894517F5081C83018D0B703F6F85A /* FCancelEvent.m */; }; 943FD4480DCB7CDC685FB76235BAE420 /* ARTSurfaceViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A48B66A95DC6A35C618F128B61FE14B /* ARTSurfaceViewManager.m */; }; 94A0A35664CCE03D8B4918046C34FABB /* RCTModuleMethod.h in Headers */ = {isa = PBXBuildFile; fileRef = F81374B32921869AADB0EBA11B8B8C2B /* RCTModuleMethod.h */; settings = {ATTRIBUTES = (Project, ); }; }; 94BA3A98C46FDC75F02D9FEB43B713FF /* LOTPathAnimator.m in Sources */ = {isa = PBXBuildFile; fileRef = 45D26EA1C9F75EEE7866827C957EAA21 /* LOTPathAnimator.m */; }; 94BB2F85DE3F02E97380122787144ADE /* RCTSurfaceRootView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BFC487AA2EAC55B0D6AF7F9C00AB156 /* RCTSurfaceRootView.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 94DCBF40A4F479EA9020829BB72B2E45 /* GoogleToolboxForMac-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F9F37A7C4E4098D92D5CC0D7020DAA2 /* GoogleToolboxForMac-dummy.m */; }; - 94F2D189EF991CF2B35A2EC1DA53CB46 /* GULSwizzledObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BFC25B49C86C3D89C95B316576FA83E /* GULSwizzledObject.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 94BF783D54086ABB0C8E2EBA25BDEA0A /* FOperationSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 96BB8CB87E982251038E03C2CC280BCC /* FOperationSource.m */; }; + 94D5ED4AB46F6CC15E37A8F6FF4097F2 /* FRepo.m in Sources */ = {isa = PBXBuildFile; fileRef = 247163A6FF856A371E4B0C15E8AC85EE /* FRepo.m */; }; 951F6A8805CDED9F8619049292BAE0B2 /* BVLinearGradient.h in Headers */ = {isa = PBXBuildFile; fileRef = 852EFC4CF9C218A75E2E16D7DADF6825 /* BVLinearGradient.h */; settings = {ATTRIBUTES = (Project, ); }; }; 95C472D55ACA6CE82DF80781F7F08F71 /* RCTImageSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 8A3A62DD2A1CE7440ADD19C9EFD77263 /* RCTImageSource.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 960446E73866EBE556C8AC9F7E528777 /* GULSwizzledObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B30F2E8DF13C2CA1CEE032F3305159D /* GULSwizzledObject.m */; }; + 95C672D21C6375399DC69352491F5794 /* FTypedefs_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = C595E476B33E9109CFF379EC8ACA664F /* FTypedefs_Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 95F7FD337EB8D0981F782A055F93602A /* FIRMessagingSecureSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CB2ECC205A62B1B815F9B9BC95FD7DE /* FIRMessagingSecureSocket.h */; settings = {ATTRIBUTES = (Project, ); }; }; 9605199D852065DCBC79FEF1FE9426AF /* LOTGradientFillRender.m in Sources */ = {isa = PBXBuildFile; fileRef = 0FB9D920B7BCDEF86B4C02E227A8C6E7 /* LOTGradientFillRender.m */; }; - 96EEB954DF701EC4D5BC03686FCA72BA /* strtod.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5D0C84E15BAC64269568163FD126444C /* strtod.cc */; }; + 96EEB954DF701EC4D5BC03686FCA72BA /* strtod.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2B7B63FEF8ACB55544B78B64DCE68B0 /* strtod.cc */; }; + 9732B0DE5EA3561BFD43A8368A85DF13 /* GULAppEnvironmentUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 7778BE85B353DF2729DA7024BA6B45DD /* GULAppEnvironmentUtil.h */; settings = {ATTRIBUTES = (Project, ); }; }; 973840E55D8085F889AE37476AFE8AB0 /* RCTScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = EF77CDFC4A198113ED34C217FD6AFD4F /* RCTScrollView.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - 97461377B2F7C42B59F5522C0A0B34AB /* RNCSliderManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B57FCF76A2AE22EE4A5C389401781F /* RNCSliderManager.m */; }; - 975EBA7C61C19031E2A7F37D60B5FFA7 /* GPBBootstrap.h in Headers */ = {isa = PBXBuildFile; fileRef = 55BFCCA16E8D02EB0E1E34DC2BAEAFD2 /* GPBBootstrap.h */; settings = {ATTRIBUTES = (Project, ); }; }; 978F1AB185BF3615BD03F2A0FA7E6DA7 /* RCTBridgeDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 2061B9760AF4D28D3E2250A8BEBF4933 /* RCTBridgeDelegate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 97F016CD00542791C12D2A096ED7B08F /* GPBUnknownField.h in Headers */ = {isa = PBXBuildFile; fileRef = C535944E602B816C57B438C995D97885 /* GPBUnknownField.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 97A2E00FB6CEA0718637CCA80D98D022 /* GULNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B691314C201B650B478BF0309DE70A5 /* GULNetwork.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 97E38F297DB2F4A542F8A999C8FCAEE1 /* FSnapshotUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DC3113D655890D1C34171C729A45C4F /* FSnapshotUtilities.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 97EBFD8B77ABC06936241133776D694E /* RNPinchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 87D53996554AD7FFB9B3579A9CE55BA3 /* RNPinchHandler.m */; }; 982DE5CC6EBA2931D1D8D274D85F3206 /* RCTPickerManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E676A27CDFC9BA5FABF19A413E8D2EDA /* RCTPickerManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 986EA1E27A22C6960C4473999CC92936 /* RNGestureHandlerState.h in Headers */ = {isa = PBXBuildFile; fileRef = B00ADF8372DC0454091CF0BB4BBAB371 /* RNGestureHandlerState.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9870BB0DD90BE40016CD8694A1971483 /* db_iter.cc in Sources */ = {isa = PBXBuildFile; fileRef = D26ED6213ECE3731B5B8B7236F7FE8FF /* db_iter.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; 98DC0ED7E329774C738F2F5BC6E083A2 /* JSIExecutor.h in Headers */ = {isa = PBXBuildFile; fileRef = A4952194B682E2C59C8BEBE5B06C6BA7 /* JSIExecutor.h */; settings = {ATTRIBUTES = (Project, ); }; }; 98EF1241417226E9B1CBA8CEEAD16277 /* JSIDynamic.h in Headers */ = {isa = PBXBuildFile; fileRef = 2509BBA42464F8BC22F3C80C68F657A8 /* JSIDynamic.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 98FB94D3BBBFE648A4E8F20B020D56EE /* Any.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 0F621743FB68D849DBB1B3AB4FBF0F50 /* Any.pbobjc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 99080CF5D9820F96377779DCFCCB5F26 /* RNCamera.h in Headers */ = {isa = PBXBuildFile; fileRef = 911D510658586F54B72EDCA08D6C57BD /* RNCamera.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 98FDDB55A7ECD8396691F2010D86D578 /* GTMSessionFetcherLogging.h in Headers */ = {isa = PBXBuildFile; fileRef = BFF0522100C085C847D645AB1139E93C /* GTMSessionFetcherLogging.h */; settings = {ATTRIBUTES = (Project, ); }; }; 990E9A51E12247BA6AA15703EFABEE80 /* RCTVirtualTextShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = FF7A94C1A592820091032D15BDC731AA /* RCTVirtualTextShadowView.h */; settings = {ATTRIBUTES = (Project, ); }; }; 99112AD5E52A37D81CE8CEA321679A0B /* RCTImageStoreManager.h in Headers */ = {isa = PBXBuildFile; fileRef = BC13A64008F9C0F3B569239F2C565486 /* RCTImageStoreManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; 993D051AFED68166F2FF173A8DA8F86D /* LOTPathAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = 64F26A68A2EABD264BBFEF73861FE8B5 /* LOTPathAnimator.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9990D56BB52EC952476CCBC17F7EC774 /* RCTSensorOrientationChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = A9DCDCA15045807E09FAAF6884D391A1 /* RCTSensorOrientationChecker.h */; settings = {ATTRIBUTES = (Project, ); }; }; 9996B6878D412956342AAAD0CACA8642 /* RCTTouchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 07F58E8644069B5C6B981E95AEEA2043 /* RCTTouchHandler.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 99B54AEEDAEBDEF0394B2D715E87C7FD /* YGValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 19728967E0FA09F1220A1E84FBAA2D9C /* YGValue.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 9A867F6A0F5EF259794ED3ECE522B5EC /* String.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2441A0494B64BA30472F9C2D55D56C83 /* String.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + 99CC6B7AEE677D3A7913B17C6BD2F631 /* FTupleObjects.m in Sources */ = {isa = PBXBuildFile; fileRef = 7472FF197F11A3E87702DD9487C989EF /* FTupleObjects.m */; }; + 99E736CB491CB2C0B7EA28F0836917C7 /* RNVectorIconsManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DB314FFC84DE55C304FC8E3DC14BDC3 /* RNVectorIconsManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9A14841BA574F2ED53F5FDA20CAA6C38 /* write_batch.cc in Sources */ = {isa = PBXBuildFile; fileRef = 444573A933F954E270941208E387DEAE /* write_batch.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; + 9A62E8C1118A1CF929FD957AC63596EE /* FaceDetectorManagerMlkit.h in Headers */ = {isa = PBXBuildFile; fileRef = B932271FB81CB35C7C0424FE0293122B /* FaceDetectorManagerMlkit.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9A867F6A0F5EF259794ED3ECE522B5EC /* String.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1825D2BACAE0467CA2F215722962EBA2 /* String.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; 9B35F2A1EFB4E946BCAD29184F3D5B77 /* RCTImageUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B6FA38CD2611CB45471BC7BDE102410 /* RCTImageUtils.m */; }; + 9B50F719832219D70DC88A8857EB0D97 /* c.cc in Sources */ = {isa = PBXBuildFile; fileRef = E59970476AE1C8FA38C8E3A183F30980 /* c.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; 9BC595AE91F40EC95750BAE5AE7D9129 /* RCTSinglelineTextInputView.h in Headers */ = {isa = PBXBuildFile; fileRef = DBA2643C609EA568FAB82AE5D1862E67 /* RCTSinglelineTextInputView.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9BEFB6CBE2741A44637A81C16553EBA0 /* Wrappers.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 493D4839B109B1EF43AA9A203C9EAF78 /* Wrappers.pbobjc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 9C2E1B211F058DABB9605EB2FA87285F /* FIRComponentRegistrant.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E8E3FA6B7209E08AAFA8F100C00089D /* FIRComponentRegistrant.h */; settings = {ATTRIBUTES = (Project, ); }; }; 9C2F514CA1ACDBB5CE2E5685F1C01A2D /* RCTErrorCustomizer.h in Headers */ = {isa = PBXBuildFile; fileRef = F8F798D9A42CCDA5B665CF0965DE364F /* RCTErrorCustomizer.h */; settings = {ATTRIBUTES = (Project, ); }; }; 9C3B153DB0958B2AE7C3A73565E1D71B /* UIColor.m in Sources */ = {isa = PBXBuildFile; fileRef = AC3939EFE51775126A54F9E9F4B5B29B /* UIColor.m */; }; 9C57A10FC867EAEBC3B48F0C439F4353 /* RCTFileReaderModule.h in Headers */ = {isa = PBXBuildFile; fileRef = E7D6FF54DB702FEF68CC23A8E0C134FE /* RCTFileReaderModule.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 9CF4C63AFFC68BE0E7A686959E83A81F /* CameraFocusSquare.h in Headers */ = {isa = PBXBuildFile; fileRef = AE05C0B725F26A95F95934A61F017ECE /* CameraFocusSquare.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9C8FF27343E4C0B629FDAD0089E8F418 /* FEventGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E295112032A733DEDF268666E7090D2 /* FEventGenerator.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9C98568D4383E52533A36CF5AA80E99E /* FAuthTokenProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F571C5DB444B31B17A40742A190C5BF /* FAuthTokenProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; 9D01853FCF031F3978A3F8F655F272C3 /* LOTAnimatedSwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = 088258D36D72F94F87F2700988424F4E /* LOTAnimatedSwitch.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9D550FD62CB625A1ED710ABC7D71996F /* FTupleTransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = 954AA7FCA35AB21D4C75C8AB916981FF /* FTupleTransaction.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9D7EA014500608934A4963922F753B05 /* nanopb-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 77EEBDAE0C2EFBC7F5A8C4AD1CD162FE /* nanopb-dummy.m */; }; + 9D970E7F14AD5354C6B34125CC56EDA9 /* RNGestureHandlerButton.m in Sources */ = {isa = PBXBuildFile; fileRef = CD7120334CF748AE6786EAC9476FE961 /* RNGestureHandlerButton.m */; }; + 9DC31FF4D1BCB49D0496C43620E7A25B /* FCacheNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F22203D7EEA6D4715E45F6FE625DAF /* FCacheNode.m */; }; 9DE41B66D07CAB21E33AB056878BC1EE /* RCTBackedTextInputDelegateAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = FEF9C3498B2429744E8F6ACE1C55E552 /* RCTBackedTextInputDelegateAdapter.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 9E5E70C76DDC2E8EC3C8A47D03DAF14C /* GULAppEnvironmentUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D8D7BB881323B238CADCF721026C5B7 /* GULAppEnvironmentUtil.m */; }; - 9EA3342F9E7DC0CCB63BC931429BD2FA /* FIRErrors.m in Sources */ = {isa = PBXBuildFile; fileRef = F1EB83C041B24EB45510D09F3E799544 /* FIRErrors.m */; }; + 9E07548305B71E5475F7381603F9EF4A /* FKeepSyncedEventRegistration.h in Headers */ = {isa = PBXBuildFile; fileRef = B3E04C62ED98682FE35D19F1871D4B6F /* FKeepSyncedEventRegistration.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9E14D078614463EB6800EBF7A22743B6 /* version_set.h in Headers */ = {isa = PBXBuildFile; fileRef = 468E1DA4FDB85768910BD3669FBB8A51 /* version_set.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9E61001E55CCE2F0217924CA239BFC38 /* RNCameraUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = DBE424B6EA62565C72A271120F6BD303 /* RNCameraUtils.m */; }; + 9E8BCE3C2F8101B8D9491C04458420B4 /* FCacheNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 76D9C9E44997FE825633287D7D5FF42F /* FCacheNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9E90684572D41461D288FE51A1C693C0 /* GTMSessionFetcherLogging.m in Sources */ = {isa = PBXBuildFile; fileRef = 421A08E7B9F97963B5D038C345894614 /* GTMSessionFetcherLogging.m */; }; + 9EA77067ABECD283E785F61F7B0D5ECE /* FSnapshotUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 26FBF5FA8071E77A53B62F51FB74DE70 /* FSnapshotUtilities.m */; }; + 9F054D9D250782B625DE731E3F73E135 /* GULNetworkConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = C7ABB2E00759610511896A78CB4637B6 /* GULNetworkConstants.m */; }; + 9F71E8D921990D444592A9FAF02E6985 /* GPBUnknownFieldSet.m in Sources */ = {isa = PBXBuildFile; fileRef = 0ACB229E2B3A2738DFDC60451CE1EF18 /* GPBUnknownFieldSet.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 9F93FEF3C52CA600E42BFB36EB6BF517 /* Yoga.h in Headers */ = {isa = PBXBuildFile; fileRef = 9066231FC462CE25D64E6E23A25E4C03 /* Yoga.h */; settings = {ATTRIBUTES = (Project, ); }; }; - A07F95E203275CBE3C2653D7C7E1E4D3 /* FIRErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DAA4CF4117F164B6489B04E99B3DDC8 /* FIRErrors.h */; settings = {ATTRIBUTES = (Project, ); }; }; - A0BA660DCDAE5C7950ECB61DDC4F09B7 /* RNFlingHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C8B3BDD59AA2F1354B33FA9F9FB787 /* RNFlingHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; - A11AE932FB89688512C2E4CAF2E9406E /* RNFetchBlobRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A858624BA6720E250FB69F3157BB5B2 /* RNFetchBlobRequest.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9FB3548BEAD5A95E08EC38F8B32BEDBF /* GPBUnknownField_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C22EE39B6204C1DD87F7F1352D610E3 /* GPBUnknownField_PackagePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9FCA82BA4CF3AFEC24C3C31AD3633FDF /* crc32c.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2EA3F99C1D3B4AF30B88B8BD22D2D7C3 /* crc32c.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; + A033121C8191D179389CD98E057EE495 /* status.h in Headers */ = {isa = PBXBuildFile; fileRef = B5E89629B0CB240B5BA5202F26C219A7 /* status.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A0897AC1AC83BB160EFC7BB2A785F5B2 /* bloom.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8C1B90E0F2D381FFF1B123D4F5376D25 /* bloom.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; + A097BF70F5016F732449B7763C60264F /* GTMLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = B5FA10934409CED2B3FD4C266168AD26 /* GTMLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A11FF41512E77716BED7150F30BA7CEC /* FPath.h in Headers */ = {isa = PBXBuildFile; fileRef = FF7D0CD093F4582E925A76C8ADBAE17F /* FPath.h */; settings = {ATTRIBUTES = (Project, ); }; }; A1379540EF76BC23735BE5983637ECF2 /* jsi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6B8E3862D41450B31D85FD534DFE2100 /* jsi.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + A158F39E402E377E64E38A81C6C1270B /* FTuplePathValue.m in Sources */ = {isa = PBXBuildFile; fileRef = D823ACADD98348643E4C77C77F7342C8 /* FTuplePathValue.m */; }; + A16C4B4FB9FF63A9CF1C4E77E42056D8 /* version_edit.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1C374ECE8D62BB7FABF1AF2C15A3663D /* version_edit.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; A18C8D75F78E475A3062CECF47369EEF /* RCTPackagerConnection.mm in Sources */ = {isa = PBXBuildFile; fileRef = F8122DCC36F7D8D6C8275A04F9CFBD22 /* RCTPackagerConnection.mm */; }; A1E26AC50944FE1084AA47ECB72D9AAC /* LOTShapeStar.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAE737D0A15E9855F3B9BC0D20AAE0C /* LOTShapeStar.h */; settings = {ATTRIBUTES = (Project, ); }; }; - A222B43688E53EBA4EF0088EC1033EE0 /* FaceDetectorManagerMlkit.m in Sources */ = {isa = PBXBuildFile; fileRef = E359D5293ABB8AD5A47B80B900B8A49D /* FaceDetectorManagerMlkit.m */; }; + A2F67B7957E1AE1B9A75F001BD746C99 /* RNFetchBlobReqBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = EA6B4E3FFE92057716DC762718518A3D /* RNFetchBlobReqBuilder.h */; settings = {ATTRIBUTES = (Project, ); }; }; A3249E68DA675287BA56EDD5E5EF1088 /* LOTLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 929D04716358D6AA8CA0936574C71023 /* LOTLayer.h */; settings = {ATTRIBUTES = (Project, ); }; }; A39C5BF966F2DA1783FEA7A410C546F4 /* ReactMarker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 38ABD9EF28C0E496F8D7B970A40253E8 /* ReactMarker.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + A3FA34C0EBF2B0B11F1B96B99650BBF2 /* FIRDatabaseReference.m in Sources */ = {isa = PBXBuildFile; fileRef = 797D0736CD646C1C5C7C068633067BB9 /* FIRDatabaseReference.m */; }; + A3FE696837871054FA7EC60E1855635B /* FIRMessagingRmq2PersistentStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A71E9CEC1419826CB35B97C1AA689F8 /* FIRMessagingRmq2PersistentStore.m */; }; A42ABC15F4E13A89FD9B893662E32519 /* RCTView.h in Headers */ = {isa = PBXBuildFile; fileRef = 3DC54162C7D5787B5F594D8311012868 /* RCTView.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A42BBB11A5C8997E64C8BF3D1356F5B5 /* FIndex.m in Sources */ = {isa = PBXBuildFile; fileRef = 6DD759A337B2E093C7B598AF79F47FF0 /* FIndex.m */; }; + A43BA8363FE521EB75D09B3DDA60B300 /* RNRotationHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C1B758110482496963A1857EB4703E8 /* RNRotationHandler.m */; }; A442F75660C29E9F7E57186BA91ED45B /* RCTSegmentedControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B2395B1A24C8256313CFCB26A28628F /* RCTSegmentedControl.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; A44EE4BB2BC2B641D77883761D03969C /* CxxModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F8A41FE97F9E25D4B9F0EFA66FC8981 /* CxxModule.h */; settings = {ATTRIBUTES = (Project, ); }; }; - A4893101111408974D02EBD975429AB5 /* FIRCoreConfigurable.h in Headers */ = {isa = PBXBuildFile; fileRef = 91AA353441322E37B9D6F28C0BEC52BA /* FIRCoreConfigurable.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A50CA0C7A4D385131AAEDC1A8A7C24DB /* GULLoggerCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 9EC86C9577627EF1AE803B92047DB36A /* GULLoggerCodes.h */; settings = {ATTRIBUTES = (Project, ); }; }; A53D03AB0832F3D69CF191FC860CF8A2 /* BVLinearGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = FCC2557C4CFE085AB85934CAC35B5F3A /* BVLinearGradient.m */; }; + A55467E5636325B2331155A28AF952C5 /* FRepo_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 121210F3B063DF666F39A8CCFA329536 /* FRepo_Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; A56F81842DC30502F311261DB2040BB2 /* BVLinearGradient-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 23E7FCA5301B09CE97AB809DDCC55C97 /* BVLinearGradient-dummy.m */; }; A604962D96AEDFF98B688BFBA6006233 /* JSIndexedRAMBundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 96035D8119680BA9B467D0C29C63E0AB /* JSIndexedRAMBundle.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + A636ADD62E996BCB1B95D66C9C5F571D /* FIndexedFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 3FE9EFF9530C76BC0428F708BDEF0D16 /* FIndexedFilter.m */; }; A64B61DBD3D57C57A346A60BB5163525 /* RCTAnimationUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 7ABD27F1E7EDFA071116E8B05CC55EC7 /* RCTAnimationUtils.m */; }; + A662C3DA32720E5D5C32BAB10ED7AFE8 /* GTMDebugThreadValidation.h in Headers */ = {isa = PBXBuildFile; fileRef = F8078A0EC20DF2D77210B1B085D2884E /* GTMDebugThreadValidation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A6A4E7FF9C2387781A5296926566911A /* FIRDatabaseReference.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CF36179E7398673F38A1B46BDDE8565 /* FIRDatabaseReference.h */; settings = {ATTRIBUTES = (Project, ); }; }; A6A7E8E92BA1845B28222C1A38333C81 /* RCTNetworkTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F141EDCB9073F1D7A8E981D94DB34CC9 /* RCTNetworkTask.m */; }; A6C9C50F2A5BF5DD3787710AB6B8E6BF /* RCTProfileTrampoline-i386.S in Sources */ = {isa = PBXBuildFile; fileRef = D42044BF99DF4BAD9F403E6983617148 /* RCTProfileTrampoline-i386.S */; }; A7000FCC030EDC3F88B8C8CCC83C24CD /* LOTAnimationCache.m in Sources */ = {isa = PBXBuildFile; fileRef = EF23E37ADBAFF0E153F90721DCC052D5 /* LOTAnimationCache.m */; }; - A737C661E9E38EF1FF35322713CC1828 /* cached-powers.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C95E73D25734090CEB4C2607EC3804F /* cached-powers.h */; settings = {ATTRIBUTES = (Project, ); }; }; - A760783CFAC0CC516FFBEA0512CFA9A0 /* nanopb-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 179D68FDFC3CDCDF06A4BA700012BB6A /* nanopb-dummy.m */; }; + A7306BD94CD26B98E26779B134BDE19D /* FTypedefs.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FA052929FA7D379DAE94EC06B51D6EE /* FTypedefs.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A737C661E9E38EF1FF35322713CC1828 /* cached-powers.h in Headers */ = {isa = PBXBuildFile; fileRef = 6377CCAE0CE909B359DACF7BE9A33CA0 /* cached-powers.h */; settings = {ATTRIBUTES = (Project, ); }; }; A7A17EEF808876134D4E61A5CBB2139E /* RCTUIManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 43E60D5D989B41E99312ECC278204378 /* RCTUIManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + A7AACA4AD8D93A99E7E043409100FBA1 /* FIRMessagingCodedInputStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 708507DA28CE846DF9AEFA83BFB58787 /* FIRMessagingCodedInputStream.m */; }; + A7EB9C99ADE1F63274C86DA87DD90717 /* GoogleUtilities-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 2905FC763BAE2E62DB4A4F12CCD07622 /* GoogleUtilities-dummy.m */; }; + A7F107EF618B19B159FBFDEE3C3F0FBA /* RNFetchBlobFS.h in Headers */ = {isa = PBXBuildFile; fileRef = 0416AA6600923BDD6D86D764FF7245BD /* RNFetchBlobFS.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A7F64E577028CDA807DEB1C4A2B2027A /* FIRMutableData.h in Headers */ = {isa = PBXBuildFile; fileRef = AF8C098D4570B1F9F98B038CCEF57632 /* FIRMutableData.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A803147A9E4FC0F26784D426675A38C0 /* posix_logger.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3BD5ABF14EA65C9DCE54CAD425A6F6 /* posix_logger.h */; settings = {ATTRIBUTES = (Project, ); }; }; A8154D58981758D98053610C3E9CAA91 /* RCTImageCache.h in Headers */ = {isa = PBXBuildFile; fileRef = FF2D67CA22841D33C41ED8C7CA55DD6D /* RCTImageCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A823349579B07D9AE576E097151B004E /* random.h in Headers */ = {isa = PBXBuildFile; fileRef = E39C79A0D5A0D5FF88250F805F77CB8E /* random.h */; settings = {ATTRIBUTES = (Project, ); }; }; A828E282526AC8D3FB1A449069D57B37 /* RCTDisplayLink.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EA6CB24CBB62BF24D50D1E98999F6C9 /* RCTDisplayLink.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; A8317F6D877746218165B00B48DC7537 /* MethodCall.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D68CB009F69DAC3C0B3B0139FE88276 /* MethodCall.h */; settings = {ATTRIBUTES = (Project, ); }; }; A844A6C033C835F88E4BAE0194ACB27B /* RCTFont.h in Headers */ = {isa = PBXBuildFile; fileRef = FC8CF3BB210F100AAB7CB2626963B656 /* RCTFont.h */; settings = {ATTRIBUTES = (Project, ); }; }; A865E3BCE43865755ADB411632B043B9 /* RCTHTTPRequestHandler.mm in Sources */ = {isa = PBXBuildFile; fileRef = E12385130E862EAF2CB1B2497F6EB0B3 /* RCTHTTPRequestHandler.mm */; }; - A88CE2EE2DB0CB5B02AD33A28198B549 /* GPBDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = 693E671BE3C1553C44C0A6CDF5D15765 /* GPBDescriptor.h */; settings = {ATTRIBUTES = (Project, ); }; }; - A93342B5FFECB35D60472961D8838F74 /* RNPinchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 87D53996554AD7FFB9B3579A9CE55BA3 /* RNPinchHandler.m */; }; + A86909B8D1589A118D5FAE0CC3AF6909 /* Any.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 46D34415B6A31D4D3C4CFE3135387179 /* Any.pbobjc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + A873DABF82824216B5CA0A5C387825E0 /* filter_policy.cc in Sources */ = {isa = PBXBuildFile; fileRef = 27B78908479033CE1848EB5E0A3FCB7E /* filter_policy.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; + A8A2110B4FB69088131EA1ADD93D9C3B /* RNForceTouchHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B11BF4BE90DD52473A3ECCD891DA90A9 /* RNForceTouchHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A8BED7DDB2B23624B3C8105FC8C68AE2 /* FIRDatabaseComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = DD63A7FD3C1EAFFA38928D1C845684E9 /* FIRDatabaseComponent.m */; }; A95F7FAD60E87C80116FBA3A4D93CF14 /* RCTModuloAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 88EB025A6AEDBF2035F1F1E6A32D51F5 /* RCTModuloAnimatedNode.m */; }; + A98833727BA1BA414BF17A794EBF3B2C /* GPBArray_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0996F2843C29C1944530ABEEFC68EFD6 /* GPBArray_PackagePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A99EFEF5545FB42DD9637E847A24CB3C /* FChange.h in Headers */ = {isa = PBXBuildFile; fileRef = 500D2122A635658F32FE739A31FC4AC2 /* FChange.h */; settings = {ATTRIBUTES = (Project, ); }; }; A9A18E4E1A70F62A396B35B4FAF8FD34 /* UIView+React.h in Headers */ = {isa = PBXBuildFile; fileRef = 70031E439E3AA606F52BF4E0AEC37B4C /* UIView+React.h */; settings = {ATTRIBUTES = (Project, ); }; }; - A9B5E1D410D9042BF45B47DD7139432F /* RNGestureHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = CAF134372BC2E71A7EAE7B74A63B1675 /* RNGestureHandler.m */; }; + A9A1D02A49F519BC127ABD3445C3E7DB /* FIRMessagingSyncMessageManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 77B8A48D919AA42DBDD52D2941231A93 /* FIRMessagingSyncMessageManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A9A7AE3F60384440A5C3C38988E7A685 /* FIRMessagingSyncMessageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3CB5D828593D472D95DB8470B5489622 /* FIRMessagingSyncMessageManager.m */; }; + A9D85E933B968789EC736ED00120ADDF /* RCTFont+FA5.h in Headers */ = {isa = PBXBuildFile; fileRef = 43023DF2386FBE3F4BBBCB542912D016 /* RCTFont+FA5.h */; settings = {ATTRIBUTES = (Project, ); }; }; A9D8788D3A743CAE8AB9143A4E6EBD6B /* LOTCircleAnimator.m in Sources */ = {isa = PBXBuildFile; fileRef = 1166E3CFD29896EA74A58F6D90258905 /* LOTCircleAnimator.m */; }; A9EC603E6C3535E31D63EF322AE85238 /* LOTPointInterpolator.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F89EC8366AC31149B4E36BE52546A35 /* LOTPointInterpolator.m */; }; - AA3807717214518966CD92E89334D3C9 /* GTMNSString+URLArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C51BCC2C2047CF29CEE5B7144FE4CDD /* GTMNSString+URLArguments.h */; settings = {ATTRIBUTES = (Project, ); }; }; - AA4F8B6207CCDC02E4B1B3CEBC116CEF /* NSMutableDictionary+ImageMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = A72C619251A9096ADB9C7E0C7C73069B /* NSMutableDictionary+ImageMetadata.m */; }; + AA31B4B5897EFBA3F5E657592F73D6BA /* SourceContext.pbobjc.h in Headers */ = {isa = PBXBuildFile; fileRef = 9536222AC312336E96C37ACA5AB4A33F /* SourceContext.pbobjc.h */; settings = {ATTRIBUTES = (Project, ); }; }; + AA43729C187714D515D7FE3C1B11354A /* FIROptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 33EE705BF112EC3B7C1E67E9E0B858F2 /* FIROptions.m */; }; + AA9DEA6E2D3B3BA20156D53AD5326703 /* IOS7Polyfill.h in Headers */ = {isa = PBXBuildFile; fileRef = 6097374DA5B371540FA9C83AFB1A3A25 /* IOS7Polyfill.h */; settings = {ATTRIBUTES = (Project, ); }; }; AADB0F1087C6021616CF16960E32812B /* LOTAnimatedControl.m in Sources */ = {isa = PBXBuildFile; fileRef = AF07C7326B260A90BBB39545CE1A42B9 /* LOTAnimatedControl.m */; }; - AAE1DE760605E8EF78EA34F40338E874 /* Empty.pbobjc.h in Headers */ = {isa = PBXBuildFile; fileRef = 843C108D6749BB75281B7551D4057AAD /* Empty.pbobjc.h */; settings = {ATTRIBUTES = (Project, ); }; }; AAF168770641057E6FFC3B37217A2CEF /* RCTCxxUtils.mm in Sources */ = {isa = PBXBuildFile; fileRef = F444846636210A1404151D580D5E80B3 /* RCTCxxUtils.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - AB434CB381A5F892D7380FC9AE31F5D2 /* RNSensorOrientationChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = C12E589CC6B6291AE80132D0C18F34BD /* RNSensorOrientationChecker.h */; settings = {ATTRIBUTES = (Project, ); }; }; ABE42A3DF39C994E82EFB522486D9C8D /* RCTRootView.m in Sources */ = {isa = PBXBuildFile; fileRef = E3CDBBF3E29018AD51DCF6C4AF91524B /* RCTRootView.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + ABEF3258E2372D38510F0D9BF5104071 /* FCancelEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 317A7F3B0FB2B5E365D3120C3A197A7D /* FCancelEvent.h */; settings = {ATTRIBUTES = (Project, ); }; }; AC0AF9F62FC0EB3EC8DECAA743D65046 /* RCTRedBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A2A8E4C4ADF680027DD478B19EAF61D /* RCTRedBox.h */; settings = {ATTRIBUTES = (Project, ); }; }; AC8D925AE68CD70FBE67ECCF80D868AF /* LOTPointInterpolator.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D6216AD162DCFD8C33260AACCEA984C /* LOTPointInterpolator.h */; settings = {ATTRIBUTES = (Project, ); }; }; + AC8FDA0BA3363CF90B991B71CEB41539 /* FChildEventRegistration.m in Sources */ = {isa = PBXBuildFile; fileRef = D9F0881486A7B6AAD1B970DB71EFF3E7 /* FChildEventRegistration.m */; }; + ACB516F98412E6486ACD413DCA253CA4 /* RNNativeViewHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 885E29EDFA78D83E21A10B4B902FB800 /* RNNativeViewHandler.m */; }; + ACCBC2D9DDB7F075D2871FEDDAE8E61A /* GPBArray.m in Sources */ = {isa = PBXBuildFile; fileRef = C1A52144BC0B6CCEC97272ACD77685E9 /* GPBArray.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + ACD06A14952B6F92B0B17A1E2ABCBCE1 /* RNImageUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 8496380D74A861E38030178BC919B55D /* RNImageUtils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + ACD35CF9147445F5259E930CFA538AC7 /* RNPinchHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = CDA13C7FD544550D5933B17CF8D31051 /* RNPinchHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; ACF5DE1CE499BD41F63A766074C9EA67 /* RCTSwitchManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5947FF2E57DE03614761CB690335A9C4 /* RCTSwitchManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; AD263BA06EAB3A5A74748C107488CE6E /* ARTNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 8903F0F9A7539997003CB4FFF0FD056A /* ARTNode.m */; }; - ADA0E8F85491D2D5A7A3DE800A354504 /* bignum.cc in Sources */ = {isa = PBXBuildFile; fileRef = F4D55EE988849BADA37D15F73DFD03A4 /* bignum.cc */; }; + AD283DEA3744706AE0BCA1A4BAADA26C /* FIndex.h in Headers */ = {isa = PBXBuildFile; fileRef = B1F3079B96D41B5A86AA71A071EC3373 /* FIndex.h */; settings = {ATTRIBUTES = (Project, ); }; }; + AD5FF55E1C183325F9D913C8E7DABAF9 /* SafariViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E34E8B54127EF1453E32E98C6B4B7AC /* SafariViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + AD621C470BDA406C2E495990553F5483 /* iterator.cc in Sources */ = {isa = PBXBuildFile; fileRef = BBE854992F5608033BEF94135B5A8FC2 /* iterator.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; + ADA0E8F85491D2D5A7A3DE800A354504 /* bignum.cc in Sources */ = {isa = PBXBuildFile; fileRef = C8DE78C4F95B9EBFE477962A8FFD4D8F /* bignum.cc */; }; + ADB3A996A3F39F7FB86B6C64BD1BF820 /* FEventRegistration.h in Headers */ = {isa = PBXBuildFile; fileRef = 759C34A1ED749325D1487BE17458AD5D /* FEventRegistration.h */; settings = {ATTRIBUTES = (Project, ); }; }; + ADC87054F534DBD851BA5E7435EC41F8 /* FRepoManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E6EF280F867455DDB14113B604BA304 /* FRepoManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + ADEDC4DF2D4E4035B2C947DD10BA2979 /* env_posix.cc in Sources */ = {isa = PBXBuildFile; fileRef = 01EFAC98986CB6F1033BA70216B2A359 /* env_posix.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; AE01F2388C8697090952D0FDD37BA521 /* React-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = A35EF7FE5291708829E1F95972034ED8 /* React-dummy.m */; }; + AE1F99DBE0CBEC8B2278E1F515C3A4B9 /* FValueIndex.m in Sources */ = {isa = PBXBuildFile; fileRef = 79CCFA5EFC38FED164C8F415BC49DF1E /* FValueIndex.m */; }; AE4D2B320B1FFA2D393EB782254B8BEF /* RCTWKWebView.h in Headers */ = {isa = PBXBuildFile; fileRef = B65142D3B750A2DAA58F5BDBBECACD56 /* RCTWKWebView.h */; settings = {ATTRIBUTES = (Project, ); }; }; - AE4FBA813AE92A84F89687F8E466B20C /* GULNSData+zlib.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D8239D1C7ED7D0E5013E1D00ABCC4EE /* GULNSData+zlib.m */; }; - AE76DBAE36EC283665C7E3B64C26770E /* TextDetectorManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5219A5D3B1D612138A0F260A22820610 /* TextDetectorManager.m */; }; - AEE19FFBA1A052352E5A4ED4A425B096 /* RNFaceDetectorModuleMLKit.h in Headers */ = {isa = PBXBuildFile; fileRef = EC11AE71F07F98FFB4F2C741FE3A108D /* RNFaceDetectorModuleMLKit.h */; settings = {ATTRIBUTES = (Project, ); }; }; + AEA17548CCF3D43C0D4E69ACD6F9B16C /* GPBUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A94C572AA48C7A9AAD37504C253D08E /* GPBUtilities.h */; settings = {ATTRIBUTES = (Project, ); }; }; AF095B328040BBB31E6F928A89791D21 /* RCTMultilineTextInputView.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E2F3D8B34EFA5FBE9D146313A09C54F /* RCTMultilineTextInputView.h */; settings = {ATTRIBUTES = (Project, ); }; }; + AF3426D61AC45AB336FD0D37064808AB /* FNamedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 469B99E535C3387F64B9842052BCDCC5 /* FNamedNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + AF857D89FF02AEC18A34E303CC849AD7 /* FIRDataSnapshot_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 53EA97F0D01736B84E48D58715BA4290 /* FIRDataSnapshot_Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; AF88E5799666D44A3EF6FB2F6136A32E /* RCTTextDecorationLineType.h in Headers */ = {isa = PBXBuildFile; fileRef = A02DF5A47E9FD63836FBCC6770451CBF /* RCTTextDecorationLineType.h */; settings = {ATTRIBUTES = (Project, ); }; }; + AFBACBCC096F84B09BD69AE023A938FE /* RNCSliderManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B57FCF76A2AE22EE4A5C389401781F /* RNCSliderManager.m */; }; AFBC84B47B1F9F9492BD4779CCA57142 /* LOTRepeaterRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A4155C7E08C2F42EF1B2E7C21605878 /* LOTRepeaterRenderer.m */; }; + AFF8E7FF6283BA4EEC101DEAE626F0F4 /* FViewProcessorResult.h in Headers */ = {isa = PBXBuildFile; fileRef = C9301A96DC9D610653E5C327A7CC6D68 /* FViewProcessorResult.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B0289F339E768CBBDB08CD2B8479A711 /* filename.h in Headers */ = {isa = PBXBuildFile; fileRef = 1EC0957443FA3D8BFC4DA9600F70F905 /* filename.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B0384A9C10668031EDC4512205B58835 /* FIRMessagingInternalUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = CA6F39AF275D541906673CA4ED08BD50 /* FIRMessagingInternalUtilities.h */; settings = {ATTRIBUTES = (Project, ); }; }; B04685989A95E9607D9756D60A74AA9D /* RCTModuleMethod.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37EFDEDDEC049394460B8F0E470BF41D /* RCTModuleMethod.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + B0C300B9DD43F4E6B9349D47E27F1B61 /* FViewProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = B03BC145252CE9439EBA6193ED4FD670 /* FViewProcessor.h */; settings = {ATTRIBUTES = (Project, ); }; }; B0D3F7AF7BA893EE4D23888B1D1A3587 /* RCTScrollContentShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3ECBFC304C0A4E3357B5D2DF819C26FE /* RCTScrollContentShadowView.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - B188BBD7B22F0F4FE470D9E8DF8DA1F6 /* RNGestureHandlerModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 49FD4AA449D624ED888B9D3357AE7BEB /* RNGestureHandlerModule.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B108968F37EE82CA50D5F94F7A21009F /* FQuerySpec.h in Headers */ = {isa = PBXBuildFile; fileRef = D9AC6948A267A80CDA2B6FA35397F5B9 /* FQuerySpec.h */; settings = {ATTRIBUTES = (Project, ); }; }; B1966EC811D9DE89FBEBED551A9BBE73 /* RCTInputAccessoryViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDF7AB3951A3C99FB086DC3CAFC91A5 /* RCTInputAccessoryViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; B1BD0D3622D2F35C5BC1C72E33EF97AB /* RCTScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = E20AAECFB7B513223A62954055D1A210 /* RCTScrollView.h */; settings = {ATTRIBUTES = (Project, ); }; }; - B1E8E0F6BB25F362479378657177F4AE /* Struct.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F94A26A5BD1EFE7C445E6E39296D4C9C /* Struct.pbobjc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - B239DA8126DA1736556BA1F1E996017E /* RNTapHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = A370A8D76A77EC077A9966F91063910A /* RNTapHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B20D3518D5B524017760849F71DC2959 /* filter_block.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C8C8EAA66B9A8936B5CB402688314A6 /* filter_block.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B22BF834D5A7FCFCA5C0065E64767595 /* version_edit.h in Headers */ = {isa = PBXBuildFile; fileRef = DBD8498E7A02847611B117CB1EE855C6 /* version_edit.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B2751DECD00EF750F346B9B94D4DCE0D /* Protobuf-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 10C619156E9298615BA8F6EFD90E2786 /* Protobuf-dummy.m */; }; B2E3F6064330140012485F0A813FD1D8 /* RCTCxxConvert.m in Sources */ = {isa = PBXBuildFile; fileRef = 33C20E6ACD6DEF8A107EAF74125A0A78 /* RCTCxxConvert.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - B3407DB7C19CA83CA63E5AE22F944EAC /* GULUserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 566DAFF42528D1D6FCEBD3246015F7CE /* GULUserDefaults.m */; }; + B33C11A8033AB8F2D3140437A0009492 /* FNodeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 908D456544B582A2941A79B982FA9D86 /* FNodeFilter.h */; settings = {ATTRIBUTES = (Project, ); }; }; B35606A531080F4CE07E0C33DA3BA427 /* LOTBezierData.h in Headers */ = {isa = PBXBuildFile; fileRef = 29A4B1AA6BD798B95E0BCD406CBD5D21 /* LOTBezierData.h */; settings = {ATTRIBUTES = (Project, ); }; }; B390C5F30FA7385D3849639F95D7BB33 /* LOTStrokeRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 49194903D29AA4A078E54FE287F5D24C /* LOTStrokeRenderer.m */; }; - B44F9943ACE5593D77A872BB114C61A5 /* GPBCodedInputStream.m in Sources */ = {isa = PBXBuildFile; fileRef = C155DB55D12C657623843D2DE1B723C0 /* GPBCodedInputStream.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - B46849FCC0BDF3343785C4018D2B2854 /* GoogleUtilities-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 1C3262CA3724AF3763EAB28F74C4341B /* GoogleUtilities-dummy.m */; }; + B4F179008CC73909CF82598A99C28B18 /* FTupleStringNode.m in Sources */ = {isa = PBXBuildFile; fileRef = C498401C32F8C28FA82FC4A342F00E57 /* FTupleStringNode.m */; }; + B50C56FF4273C882E5A3F13F00CF6B1B /* FRepo.h in Headers */ = {isa = PBXBuildFile; fileRef = FFA7A89F9DC8DAC084A978A4F9B99A5D /* FRepo.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B5271569774F9D2426B39569D9D940E6 /* arena.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5E69820A04F974F3CFFCCB3091ACA698 /* arena.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; + B587BAEF82D4C9FF23CD50F21FC27F64 /* table.h in Headers */ = {isa = PBXBuildFile; fileRef = 3CBE8B32C08136207C1ED4E64F1E7C30 /* table.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B637C6DEC346BA280846FB413466A59A /* RNGestureHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = CAF134372BC2E71A7EAE7B74A63B1675 /* RNGestureHandler.m */; }; B63AB8CF1C0CE6992430AB1F01591668 /* RCTDivisionAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 9FDA07E5331D72D53F6CDFE0B6343817 /* RCTDivisionAnimatedNode.m */; }; B63E3FF91D0E501A942503AEF81A5DD3 /* RCTInspectorDevServerHelper.mm in Sources */ = {isa = PBXBuildFile; fileRef = F8C0C7600A97270ED1EF9B07A6692F0F /* RCTInspectorDevServerHelper.mm */; }; - B64BC18DE636C8C27F5B68FBE6E3C708 /* pb_decode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C03D23A538969ECF4FE84795F3C2BB5 /* pb_decode.h */; settings = {ATTRIBUTES = (Project, ); }; }; - B6A02AAE01AF684E41919E284D2362F6 /* GPBUnknownFieldSet_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0AF5AE5037BF6C75F311B1B382B1BD12 /* GPBUnknownFieldSet_PackagePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - B6FAC731A96CD66859136BC0FB274884 /* Unicode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2F78EC927E123ED2AD0206235BCC08BB /* Unicode.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + B6BBC4425071324F694CB0187A4B2927 /* FImmutableSortedSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F4530CAB03AC6F4D0F2979F7FC111EC /* FImmutableSortedSet.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B6D32B09B41A82E88508959E99AC6FE9 /* write_batch_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F7A091B8C6E441AB1BFD5CC75E281F9 /* write_batch_internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B6F4CE2FE44E2AB13AE4AFA9FF29E330 /* FIRMessaging_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 640485D56F169D7F85A9148D7262296D /* FIRMessaging_Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B6FAC731A96CD66859136BC0FB274884 /* Unicode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F47C369C57996A13FC6CD8458BBE8B3E /* Unicode.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; B74AA0FB78BC93317313E0756F085334 /* RCTBaseTextInputViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 874716F29B6F762B15369BE564CE2A27 /* RCTBaseTextInputViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; B76C4289BD039FA2E6ADC26208CE12CB /* RCTSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = D245972CB81A651E4CE20662BA7AE117 /* RCTSlider.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - B7991E98563076878AA5B035407A864F /* RNGestureHandlerEvents.h in Headers */ = {isa = PBXBuildFile; fileRef = F794D9A735E46A11E4EE3F1E77A9753C /* RNGestureHandlerEvents.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B79C3B6226C6B20FECB963ADA18CEDFA /* FTupleTransaction.m in Sources */ = {isa = PBXBuildFile; fileRef = C6B6E040B15704408AD50B573EF3DC97 /* FTupleTransaction.m */; }; + B7CB772B6A77D5B2F1F6D384C6B08F9A /* FIRComponentType.h in Headers */ = {isa = PBXBuildFile; fileRef = C18794FB4491915FA833B66DE05948DF /* FIRComponentType.h */; settings = {ATTRIBUTES = (Project, ); }; }; B82A8C938A37FDE70E048A422FF3F8C5 /* LOTColorInterpolator.m in Sources */ = {isa = PBXBuildFile; fileRef = 66C03B50B7BC7446C0D7BF05DF9D23FB /* LOTColorInterpolator.m */; }; + B83139D9AA479A08013B8EAC827F325D /* FWriteTree.m in Sources */ = {isa = PBXBuildFile; fileRef = 497DC3EC24F8F871BE484C8E6E675FB9 /* FWriteTree.m */; }; + B8328AE0BD33C3D50767C20A1D425F39 /* GPBUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BF47581753EE9991293514DAE4C7293 /* GPBUtilities.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; B852D48ACEF8A752033EBCEFD85A5996 /* NSValue+Compat.h in Headers */ = {isa = PBXBuildFile; fileRef = 1BA065A58BF7952929FEBD9BE6E833C2 /* NSValue+Compat.h */; settings = {ATTRIBUTES = (Project, ); }; }; - B85C0204B7080879BD116C0BC5B70A56 /* RNLongPressHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 5990E7950D75F0AEEEBEB9D5F4FD915A /* RNLongPressHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; B8BBA13AFAE2D82607954F6ADEE20C6F /* SharedProxyCxxModule.h in Headers */ = {isa = PBXBuildFile; fileRef = F3A37968E25A732F4F61687A41E97F87 /* SharedProxyCxxModule.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B8DB12793BA68F37CDDA65A4BF2CF2F6 /* FIRMessagingSecureSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = A87E72714A0CB0D74D50BA450CCF834B /* FIRMessagingSecureSocket.m */; }; B8E18988F352BEDCF55A5392CDBD55C5 /* RCTJavaScriptLoader.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5FE73A5FFA76C4B66DB344C966268AF4 /* RCTJavaScriptLoader.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; B8F0C27E4AAC5DD159DF5AC40E047EB2 /* RCTHTTPRequestHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A1444E21F24A9054384677B8D892F9E /* RCTHTTPRequestHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; B9209481F4BF90451FEB33C5378C210C /* RCTKeyboardObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = CF275BE4FEB45E4E34879C52AD867F7E /* RCTKeyboardObserver.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + B9494EDF343453F963503C4CDE946666 /* FConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D7D22BFC36156A34EAAA455C211B9D3 /* FConnection.h */; settings = {ATTRIBUTES = (Project, ); }; }; B97622BE5F062DA3AA84143C90887655 /* LOTAnimationView_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 7DDBD0701B6073C2040902224B2A6ADB /* LOTAnimationView_Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; - B98529C7D66A995B21D58F994EC2FA6B /* GTMSessionFetcher-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = CC2547E3827FA29B4BE7F24C6C7129CF /* GTMSessionFetcher-dummy.m */; }; B9ABD330AA3964CF2583A974FE6B2C6C /* ARTNodeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A351EFA847FB7BE145FE4372C864DD0 /* ARTNodeManager.m */; }; B9C00B6001A229AA8D3BEA2AC2C2CDB4 /* LOTBezierPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 636599CBD5F1D9FC19C882804FF3D16C /* LOTBezierPath.m */; }; - B9D5635A6CB3317489A433AD8F3E5A55 /* FIROptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DFA54C268300CACAB672429F27F4893 /* FIROptions.h */; settings = {ATTRIBUTES = (Project, ); }; }; - B9F5F9810CF60170D928F580F3135E65 /* GULObjectSwizzler.h in Headers */ = {isa = PBXBuildFile; fileRef = DB5F9A456823497815130E9E530D85D3 /* GULObjectSwizzler.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BA02231F41A2ED9DF20D5C93DB7EB650 /* FIRDatabaseQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = 64ECD487E0F940E52FAE9C1561AE435F /* FIRDatabaseQuery.h */; settings = {ATTRIBUTES = (Project, ); }; }; BA10151AD766D9252B0AB2E2B1A3E9A4 /* NativeModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 06E3D243EFDC5A86565B61EA296DC97A /* NativeModule.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BA20BD3928AD86CF78E62BC1F0ECFE09 /* port_posix_sse.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B0E712AC4E399D821909DFA5AC02342 /* port_posix_sse.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; + BA280545E1DB13C13C5B5E420B1A2F20 /* GTMSessionFetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = DAFE21A309048749918F40D0AEEF651B /* GTMSessionFetcher.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BA7974E36A0E189D0F1F1F68A77859C6 /* env_posix_test_helper.h in Headers */ = {isa = PBXBuildFile; fileRef = 30D6BEA3A2C59F3B59B748B9C5DA5AF1 /* env_posix_test_helper.h */; settings = {ATTRIBUTES = (Project, ); }; }; BA9306F7D34A86DE523B8F7F9E7500F4 /* RCTReloadCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = B70B5703A021E8A82E96B815A562911C /* RCTReloadCommand.h */; settings = {ATTRIBUTES = (Project, ); }; }; BAAA9EF814FB93B67A31CCCDA299A00C /* LOTValueCallback.m in Sources */ = {isa = PBXBuildFile; fileRef = D720CBE9F4ABD0088F7C8430C804E0F2 /* LOTValueCallback.m */; }; BB4DA369A68A9CED098D1D2714B7039A /* CxxNativeModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 06AC11EE41F74F48DFBC6AC0E324CFAC /* CxxNativeModule.h */; settings = {ATTRIBUTES = (Project, ); }; }; - BBC47AA70B4D9D828CECC02F073ECD57 /* GPBCodedOutputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = CB581520BBAE84BDC670F94F64B3FE2C /* GPBCodedOutputStream.h */; settings = {ATTRIBUTES = (Project, ); }; }; - BC3B14DAC4C329A5AE98396144F98D68 /* GPBRootObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 40E19694FE31A1B80E73A68B32E53D48 /* GPBRootObject.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + BB8D5849C5EB26EB4B819DD4E8F04E4A /* GTMSessionFetcherService.m in Sources */ = {isa = PBXBuildFile; fileRef = C11F09F5D7BFF243861A75935726732E /* GTMSessionFetcherService.m */; }; + BBA105DF3C4E10C539D00DB3AAA939E8 /* FLevelDBStorageEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D8FD7EDF6E543DB4D9DA88021A5417B /* FLevelDBStorageEngine.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BBA7E64A68AC870C231D1B21432779F4 /* FIRMessagingAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = CCD510EA205821B5537E61E565622B87 /* FIRMessagingAnalytics.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BBCA38B91FC76D5D9547779BF983F2B7 /* FLLRBEmptyNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 948383FCA22475A89A577753033C97D7 /* FLLRBEmptyNode.m */; }; + BBD4025AC8BA9F696C307FBE20EE565E /* FIRMessagingDataMessageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = BF0053A92A3441539945F1004FF4F28A /* FIRMessagingDataMessageManager.m */; }; + BC02656B3A666758410BF05D2F560315 /* NSData+SRB64Additions.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BDB0946FE4427D7EE3CC47737533840 /* NSData+SRB64Additions.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BC393C4DDE70D3C35865A7AD04981F25 /* FIndexedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = F1289BC33AE993214A1322EE8396AF70 /* FIndexedNode.m */; }; + BC46E2E7DEADFF1E8F759FAFD9559A7A /* RNGestureHandlerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D1E099506200348C65A2B01768F6FD4 /* RNGestureHandlerManager.m */; }; + BC7EE54BE2D20E72CDC05BAED6398B6F /* FIndexedFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = B52E090772086382345A487E8AF24146 /* FIndexedFilter.h */; settings = {ATTRIBUTES = (Project, ); }; }; BCB125DD261CA9948A7378E0FD62EE50 /* JSCRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = AA134FE3E7902FD59B5DFAE116D13DF1 /* JSCRuntime.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BCD3B81055C2DC578F9DADB0A5D48265 /* GPBCodedInputStream_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 4785EB3ACEC0E8CCA1161262C30079BD /* GPBCodedInputStream_PackagePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; BD073B2EDD184B73785AECBA0E87496E /* RCTGIFImageDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 2FBE3558F43FAEAEC0EA0D1C52013233 /* RCTGIFImageDecoder.m */; }; - BD2FD845D5F8BE8221303C32BA1E2BCA /* RNGestureHandlerEvents.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C0872A90B2BA40CEF9E18D168D08A48 /* RNGestureHandlerEvents.m */; }; - BDF0004BF692F52CE420A0C207E5FB4D /* GPBCodedInputStream_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 52A4AE6DDD3EA030E3CAC170B3C190AD /* GPBCodedInputStream_PackagePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BD26F56BB67619862948EFB07852B5F2 /* comparator.cc in Sources */ = {isa = PBXBuildFile; fileRef = ACDA9668469FE07E1CDC60A09A2E0022 /* comparator.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; + BD2A817F718848F261F55EFA6B60C1EF /* FValidation.m in Sources */ = {isa = PBXBuildFile; fileRef = 9197527BF54C7861B6DA0625FED4EE24 /* FValidation.m */; }; + BDA23269C2018E00F347379F7264D054 /* FLLRBEmptyNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 329BD46423F50005F2F603C45F8A03CE /* FLLRBEmptyNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BDCED52C7A3F2F1279671112C21E3096 /* FIRMessagingAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 03C7DC736195B2F84AB92FD41F745685 /* FIRMessagingAnalytics.m */; }; BDF7BBD643073E3046699942CEC021A6 /* RCTImageEditingManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9647215CEFAEF77A6720B470AA9CCDB7 /* RCTImageEditingManager.m */; }; BDFBC9A0D0C87E961A3A0486BBE67D47 /* RCTAnimationUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 590EA11D60BDC44FB2AB5C6A91572E01 /* RCTAnimationUtils.h */; settings = {ATTRIBUTES = (Project, ); }; }; - BE64F3C6F12C659DF505C9076F9BFBA1 /* GTMNSString+URLArguments.m in Sources */ = {isa = PBXBuildFile; fileRef = 18B460E4AEBC71D4F729A44EA5FDDB3C /* GTMNSString+URLArguments.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + BE111BBD1063B7BCED4706B1835BA8B8 /* FSyncPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 25BEA17231DD2405EAF009FDD93C48D7 /* FSyncPoint.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BE4022CA4636A3D36C0EC34AC88F0DFB /* FIRDatabaseConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 119233EEDFEBB78EFF551ACE3BA29826 /* FIRDatabaseConfig.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BE8C849C929EAD47BE26881A32C245FB /* GULReachabilityChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = B23331D08F0FB92619826BCF638468EC /* GULReachabilityChecker.h */; settings = {ATTRIBUTES = (Project, ); }; }; BE93EC042756D89D6C87649624E68F52 /* RCTVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = 153D64AD7A461EE90C2D7D3D7D6C90D5 /* RCTVersion.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; BEE901C6F3D9E874E79AC34B14C6A4BD /* RCTCxxModule.mm in Sources */ = {isa = PBXBuildFile; fileRef = 137B1E68E59720F269B6488A0EA8132F /* RCTCxxModule.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; BEE95688594E64F0F7D5D0AA8AEFD940 /* RCTPerformanceLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A9461FDC3EFC18F84B16A4506A01FD /* RCTPerformanceLogger.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + BEF2FA3DA4D477B34FF9A9E4F12D3DE0 /* FIRMessagingTopicsCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = B234D6101F861EA4DDA1FAF741BCDDDC /* FIRMessagingTopicsCommon.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BEFD6EFBE7043B3B33684FFE6C646033 /* GULNetworkURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E6957BFB3FCF960F7BB3C06E83AFCE8 /* GULNetworkURLSession.m */; }; BF06C5961F9F30C0BD482DA7F69E498D /* LOTValueCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = A87059FF49429D002A86F2E59B178E5D /* LOTValueCallback.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BF2EC45C2815ED477BE718178A199707 /* pb_decode.h in Headers */ = {isa = PBXBuildFile; fileRef = C57A0D2CF0F382E8C20382DCFAFD1221 /* pb_decode.h */; settings = {ATTRIBUTES = (Project, ); }; }; BF508943C95654A5FE5711C8EABE35C7 /* JSCExecutorFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B836199A12F73E910B7A5628A0108F1 /* JSCExecutorFactory.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BF74BDFBA7BE313E3D85C3B23B606A3A /* FPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 7CAACBD84B0FF26AABBC2C0E6051CECE /* FPath.m */; }; + BF91E4224980166C1FD43C1B2C042A4A /* FEventRaiser.m in Sources */ = {isa = PBXBuildFile; fileRef = A031910DEC6962FD8A88B9BB9215E807 /* FEventRaiser.m */; }; BFA69CFF6A9A8E7F85A6EDBCFC236E4F /* Instance.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A62A5F6AD64B8BF4A5390E182176CB1 /* Instance.h */; settings = {ATTRIBUTES = (Project, ); }; }; - C04B6F056C6373D30BD408B524112AA0 /* FIRVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = FEE80C65BE332B5B353A346DB6BA667C /* FIRVersion.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BFB6B29630E840DE00D213262622636B /* RNPanHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = CEF7599963D907DFA7840EE2120C743C /* RNPanHandler.m */; }; + BFF393EB0908DD98477CE11C1F5FB2E8 /* FWriteTreeRef.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E00DB364E41712CD057A8C1BF44424D /* FWriteTreeRef.m */; }; C04B7E9A408401DAB7AD8F5288D15DCF /* LOTRadialGradientLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DCEDC5350B60E81693F454A83EE906C /* LOTRadialGradientLayer.m */; }; - C0691FE7A0B64FB402F3EF6D3D0ABD0A /* RNSensorOrientationChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = FA13E84FE4F3D80FECEA316FDEFBD8E0 /* RNSensorOrientationChecker.m */; }; + C08F3E2A8A4D57C656663A87C27D2734 /* FCachePolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = 9FD42A1D1EFDAD7F398B68B135BC9F5F /* FCachePolicy.m */; }; C0940A04823AA9443ED5A43A4D5DD7F0 /* JSIExecutor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C82AAF34F6F689688447C1940B73104 /* JSIExecutor.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + C0AFF5303BEB481F6BD89042FBF2B9B1 /* FTupleTSN.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CACFD271582042A2D81EC4C6B15DACD /* FTupleTSN.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C1DAABE4FA5E557B2B5D9AEB21097220 /* FSyncTree.m in Sources */ = {isa = PBXBuildFile; fileRef = D5C19AB0924F2D0B33D5F9D3E93B6C02 /* FSyncTree.m */; }; C1EAB815F27ECAF028A4F944BE6AB9F9 /* RCTTextSelection.m in Sources */ = {isa = PBXBuildFile; fileRef = 83137E3B69277B70F3379CD498869329 /* RCTTextSelection.m */; }; C1FCD1B343FE1327C6DB63ACB4512453 /* RCTUITextView.h in Headers */ = {isa = PBXBuildFile; fileRef = 99BF4EF72AC68820FF7468DE3C48BF43 /* RCTUITextView.h */; settings = {ATTRIBUTES = (Project, ); }; }; C2032A1F36C55FDDA6E678A030525ACB /* LOTComposition.m in Sources */ = {isa = PBXBuildFile; fileRef = B1D11BB4203DEDE80F5C0B6C81F252D2 /* LOTComposition.m */; }; - C21A98E93501CC570AE58686F99BCF08 /* FIRDependency.h in Headers */ = {isa = PBXBuildFile; fileRef = 87FD80787842E07D922056CD49FC2EE1 /* FIRDependency.h */; settings = {ATTRIBUTES = (Project, ); }; }; - C2221EF953B6A275A90AE1054178F11F /* RNFetchBlobReqBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 02164749E0FF8E59CB81D19A4E8F959A /* RNFetchBlobReqBuilder.m */; }; + C2082E35A195D1D20F2152704BAA78F7 /* FServerValues.m in Sources */ = {isa = PBXBuildFile; fileRef = 3FEFA415177BF93D444343263FB71D2B /* FServerValues.m */; }; C2468B5E22F6C0A4C24AEB2AA10ACF5E /* LOTMask.h in Headers */ = {isa = PBXBuildFile; fileRef = AB1869756BBD1A29757ED8E2F3E40795 /* LOTMask.h */; settings = {ATTRIBUTES = (Project, ); }; }; C24CB0D3EC79ABA72AE64D886B97CD5C /* RCTReconnectingWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 57E3F9077165C17BFC3CF8A0CFD58014 /* RCTReconnectingWebSocket.m */; }; C25142332C6A42E3FB85D7250752E46A /* RCTTextViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B30FE6DDEEA9589B8F905714BD2B70A /* RCTTextViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - C25197631119CCA0A326BBCFD7D808EC /* GPBUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = CFECFEAE9C6ACBAC47AEDE6533BE668B /* GPBUtilities.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C29E6656B2F76A622C5A9D56F181AB97 /* FTupleObjectNode.h in Headers */ = {isa = PBXBuildFile; fileRef = C8EBE838EB55E2BC9441464B7B06BFA5 /* FTupleObjectNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; C2BBECED9D8C1F6A594C0EBF57FCE489 /* RCTSegmentedControlManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 76E05F699787D35369E6FDFDD7E00546 /* RCTSegmentedControlManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - C369C72BAB144C122AA4BA9BECA20BB5 /* GPBUnknownField_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = FAAFA9FE05ABD9EC9E489698BB896A55 /* GPBUnknownField_PackagePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - C3B3709DDBEB552F8063D0B1A7DE5302 /* GTMNSDictionary+URLArguments.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B33B41158BDBB4A9D00FCAE71EBD99 /* GTMNSDictionary+URLArguments.m */; }; + C2D1046A7C8F5C0A960F6412582EBC3F /* GTMNSData+zlib.h in Headers */ = {isa = PBXBuildFile; fileRef = 6FDF8C105D1CD0639854ED193B0B62C8 /* GTMNSData+zlib.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C317CD39213DD8F534ACCA5354A39B6A /* FTrackedQueryManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 22DAF0E1D71C0A9951000AABEE74F317 /* FTrackedQueryManager.m */; }; + C32A478BF8B93A4DDEB48D4507D845EE /* GULSwizzledObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 27938245D9F59E1D8028A667866781E4 /* GULSwizzledObject.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C3430C146960EDCEC4B4FCFFF7F0E45F /* thread_annotations.h in Headers */ = {isa = PBXBuildFile; fileRef = 19330FC8B77327DE6F4BBF84783EB457 /* thread_annotations.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C3F6AE1330A7FD090F4D91793AD9B67E /* RNFetchBlobNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = 346ED9A09FF573F0481536CEDE22A26F /* RNFetchBlobNetwork.h */; settings = {ATTRIBUTES = (Project, ); }; }; C42BEE42685E036B5A97AF4A2A5863A0 /* RCTDataRequestHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FC851087BC17D35AF6D400CB9199999E /* RCTDataRequestHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; - C4392EE09C5AE00193DAC33B632B561C /* GTMNSData+zlib.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E2631576F7A1002CC3B12FA44368A76 /* GTMNSData+zlib.h */; settings = {ATTRIBUTES = (Project, ); }; }; C447A68240D5325E73E80E7FAD0A2334 /* RCTNetInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 458BF14601CB10A44C586D9DB33A9A7B /* RCTNetInfo.h */; settings = {ATTRIBUTES = (Project, ); }; }; - C481511BBF4AD67C105ACB503EE4E993 /* double-conversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 37967DC16FAFA16E418FAA5795D66DB3 /* double-conversion.h */; settings = {ATTRIBUTES = (Project, ); }; }; - C4A566ECED53CAECFC9919361DFDCA5B /* GULReachabilityChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = 887F7DBD5091038F3A40E4095823B0FF /* GULReachabilityChecker.m */; }; + C447ECC61AB7D83C68A6C9BB778717B5 /* GTMSessionUploadFetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = C490B04338D5B6C8B578768799D868C2 /* GTMSessionUploadFetcher.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C459FB55EAB68F8CA9C0288D233454E5 /* atomic_pointer.h in Headers */ = {isa = PBXBuildFile; fileRef = D1DA3DDBB6E2F5BA2A56638520AD91BF /* atomic_pointer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C45FA57D0A067A2691D9E80552DB44F3 /* RNGestureHandler-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 0458D0A7DAA406B4565D450B7D6B7545 /* RNGestureHandler-dummy.m */; }; + C481511BBF4AD67C105ACB503EE4E993 /* double-conversion.h in Headers */ = {isa = PBXBuildFile; fileRef = A32E5E0F146D5D98346795AB2202609C /* double-conversion.h */; settings = {ATTRIBUTES = (Project, ); }; }; C4AE9EF04ECCC4928BB2924AA332DE47 /* NSDataBigString.h in Headers */ = {isa = PBXBuildFile; fileRef = FEDC05B78A74ED521879E1C95BD2D6E8 /* NSDataBigString.h */; settings = {ATTRIBUTES = (Project, ); }; }; - C4C9B17ADFBD94BC209E01AD28FEBD7D /* RNVectorIconsManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DB314FFC84DE55C304FC8E3DC14BDC3 /* RNVectorIconsManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C4DB20AE36B355A73E1DBA1455952577 /* RNGestureHandlerDirection.h in Headers */ = {isa = PBXBuildFile; fileRef = D76D5D51CD891E00FB602A22F703D79A /* RNGestureHandlerDirection.h */; settings = {ATTRIBUTES = (Project, ); }; }; C4DC32785D59ECF3F12328707F9056EC /* RCTSurfaceRootView.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E3ACA9687A5C84260C13F858BFB2DF /* RCTSurfaceRootView.h */; settings = {ATTRIBUTES = (Project, ); }; }; - C5803C5384E0A0C7C21D6C1217497444 /* Duration.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 7545ED3CF47CD833D50D1BECB7E25191 /* Duration.pbobjc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + C571DF5ECF1978804DFD1E14E61D0833 /* table_builder.h in Headers */ = {isa = PBXBuildFile; fileRef = 18351BEBA491DA6D9CADDDC581F9CE07 /* table_builder.h */; settings = {ATTRIBUTES = (Project, ); }; }; C5B6811F849E08DBC0C23E3A03DD0D9C /* ARTText.m in Sources */ = {isa = PBXBuildFile; fileRef = 015C8546B0320ACF5B29CD7BE84521F3 /* ARTText.m */; }; C636253DD9A602C9DD77D0B1460C234F /* ARTShape.h in Headers */ = {isa = PBXBuildFile; fileRef = 3283ED2A78CAF4FC9ADFA07A66E235CD /* ARTShape.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C677530755C932F08F3857D54781B19A /* FIROptionsInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = F36D0E45637DB5DDE415A88AB9F81B2F /* FIROptionsInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; C67E28F5292540614F6CF6833D211785 /* RCTBundleURLProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 633CF5FA3E4291F940F1B8D40D1B097B /* RCTBundleURLProvider.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - C684F5F6B06D3C1C8F428F6C1E08B836 /* RNImageUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 8496380D74A861E38030178BC919B55D /* RNImageUtils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C69CC5FCDB3AA6D5EA18C8DD6C86C8ED /* NSError+FIRMessaging.h in Headers */ = {isa = PBXBuildFile; fileRef = 6EDCC0DCEBE6963DC7DF76AD7231B96C /* NSError+FIRMessaging.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C70172F0F275CCDB6A3C6C7B12557EDD /* FDataEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 23D54FAEECFDD570E95E39A465F7CDA4 /* FDataEvent.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C7108FB8364507227C6CA793A340470B /* block_builder.cc in Sources */ = {isa = PBXBuildFile; fileRef = EC7538EECB1B622475352EA2C29CE32D /* block_builder.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; + C71B1CE38FC2925A8E5FE0B06A126146 /* GPBDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = BF0EB3589EDFE0B529D244E5F911C9F0 /* GPBDictionary.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C742832691B37699A04569E62272CC86 /* FListenComplete.m in Sources */ = {isa = PBXBuildFile; fileRef = D53E177D9DAED78A04E5F1872DEFFCF0 /* FListenComplete.m */; }; + C750788F72143D5167D7505E7A1ED8B9 /* cache.h in Headers */ = {isa = PBXBuildFile; fileRef = F39C03C8E9840CA54648E59EB7400EFF /* cache.h */; settings = {ATTRIBUTES = (Project, ); }; }; C7564C7008593B7655FB80265A15346E /* RCTComponentData.h in Headers */ = {isa = PBXBuildFile; fileRef = E92A551E816233B89581BF7B40822187 /* RCTComponentData.h */; settings = {ATTRIBUTES = (Project, ); }; }; C7A78D9C36CB211B58FDFEEB339FD016 /* LOTShapeCircle.h in Headers */ = {isa = PBXBuildFile; fileRef = F80767D7A8BE8E1D3A575E3ACD94E24D /* LOTShapeCircle.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C7ED253056C86FE2E96603845574D529 /* FIRDependency.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A8A1B99D1D6D8DE0C6ADD1FF71CB5FA /* FIRDependency.h */; settings = {ATTRIBUTES = (Project, ); }; }; C8158359C9E68974B3AC174372EB8AAE /* RCTSurfaceRootShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 65B11D7F2569B53319B988E9A0CE1F15 /* RCTSurfaceRootShadowView.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + C84D6AB476E626EC66D86928DC232C73 /* GPBExtensionRegistry.m in Sources */ = {isa = PBXBuildFile; fileRef = 66071353779F44989D907BF1A8344AAE /* GPBExtensionRegistry.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + C85CF22D871D5449F865A23FAD3041EF /* FIRRetryHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = C1115D0ED1326D53E4F18C7A3B7395FD /* FIRRetryHelper.m */; }; + C866203D8E0177BE15C7E00F31299627 /* FIRComponentContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1447EEC6E44D953BB79924C9D18D6ADA /* FIRComponentContainer.m */; }; C88DF6FCB1EFEEE9F3B13471C491700C /* LOTShapeGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 672C2783B15E32F205E5BE67AA0CDED5 /* LOTShapeGroup.h */; settings = {ATTRIBUTES = (Project, ); }; }; - C90689F01BAD94E908B25CF2DCE0E257 /* GPBUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 56C71E142AC9AF135CF8FFABF92C82DA /* GPBUtilities.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + C8EE6BCCF7E6B440F37A8660F6F6016E /* FTupleUserCallback.m in Sources */ = {isa = PBXBuildFile; fileRef = ED1405255E18F31D45F86A8C53FFCCCB /* FTupleUserCallback.m */; }; C944C7B904F28FB5059968B6F37F4EE3 /* YGEnums.h in Headers */ = {isa = PBXBuildFile; fileRef = F20BE9489B143302BF0DA9538538E07E /* YGEnums.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C958B93EF63BDE2DA0736877037DFDAC /* RNFetchBlobRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = C503F2038314A9628108B22C4993AD58 /* RNFetchBlobRequest.m */; }; C995CBF8AA688A2B2097CF2D63B01ADC /* RCTLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 776E21EDFEB7038444892C624EF4A321 /* RCTLayout.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + C9A12D4F3300948B69DA3C3EF153830D /* GTMSessionFetcherService.h in Headers */ = {isa = PBXBuildFile; fileRef = 3CD58A35D4D5CEA9C36AE6EEB064AC42 /* GTMSessionFetcherService.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C9A49FC4C19A996CB95D8E94EF645DF3 /* table_cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = A844DA2D4F3B499538E16BED3E72F98C /* table_cache.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; C9AE12E7754918FAEA45639EFE0D245F /* instrumentation.h in Headers */ = {isa = PBXBuildFile; fileRef = D629396A8F0E2869D8380E13C5A5C29E /* instrumentation.h */; settings = {ATTRIBUTES = (Project, ); }; }; - C9CD52BAC20DB985D0F13F4E30CF3C3B /* RCTSensorOrientationChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = 19FA7CC6598EE44D9CB7C787C69C4DBA /* RCTSensorOrientationChecker.m */; }; + C9CE381840E6E9AC3795A7C184F137AA /* FListenProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 8EA3039B8276E66EFA1E055C5273D6E5 /* FListenProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C9F84383BFD15ADB125B9A4B1E70E9E5 /* FStringUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 6DCA35EF795480806D8EEBF75738F78F /* FStringUtilities.m */; }; + CA2AAE32804043D222C64ABE8112A84E /* table_cache.h in Headers */ = {isa = PBXBuildFile; fileRef = C194B9D7F5D0883EEE60232E87973E59 /* table_cache.h */; settings = {ATTRIBUTES = (Project, ); }; }; CA3D141EE14C81EF23DD9653A758EF70 /* CGGeometry+LOTAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 5974F1EB6EB6CB8C449E83A3E40CED96 /* CGGeometry+LOTAdditions.m */; }; - CA4ACB8C42B724665EF049E6F7F0EDA7 /* json.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CA0AE83BD8B4AF3F29E505170295D7C4 /* json.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + CA4ACB8C42B724665EF049E6F7F0EDA7 /* json.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2637FDEA1D9A58931B3F5B9C8B06F0F /* json.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + CA93635F6353B0E0055DB4092575ED96 /* FEventGenerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 433A22FA442B112CC55C0E2F3A3BD38D /* FEventGenerator.m */; }; CABCAE64240C665168D8D4F87089E10D /* RCTSlider.h in Headers */ = {isa = PBXBuildFile; fileRef = C3253FB72A2C4AA4187AC5F9D41A311F /* RCTSlider.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CB045B37225229F11C968518BD501053 /* FNextPushId.m in Sources */ = {isa = PBXBuildFile; fileRef = F19E6A2E633381302ECD1857A558CBA4 /* FNextPushId.m */; }; CB0D3CDA34E8B34CD914060F823DF6DC /* LOTShapeTrimPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 22570DB31327C71F2C7ED350AF9A924A /* LOTShapeTrimPath.h */; settings = {ATTRIBUTES = (Project, ); }; }; CB282A5528E98F7E8ED12D9587AC5063 /* RCTPlatform.m in Sources */ = {isa = PBXBuildFile; fileRef = FBC71BA32DD33275E6BD072F11CCC515 /* RCTPlatform.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - CB91BC6A614FEA1761D3DF29C7AC3FF8 /* RNCameraUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = DBE424B6EA62565C72A271120F6BD303 /* RNCameraUtils.m */; }; CB938A6498186B4A085F3AD448E4050E /* RCTScrollViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E8822CA2EA5A654CB52D16B5DB5A15E2 /* RCTScrollViewManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; CB99261931C5CD92C9300440B8D363F7 /* RCTJSStackFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = CB829089F49F46CE31DE0B2148003406 /* RCTJSStackFrame.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - CBACB4C01B29DE7F8AB7B848BD5FE094 /* GPBUnknownFieldSet.m in Sources */ = {isa = PBXBuildFile; fileRef = 7A49385C1B5229EEBF1131781952DF75 /* GPBUnknownFieldSet.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + CBBCB3FBC75D4172F2EE54FDA4EE229A /* GTMLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = E26BCDA9139114A005F6E1B64F0322EE /* GTMLogger.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + CBF9FE3FDB7CF9F12151C303FD32D972 /* memtable.h in Headers */ = {isa = PBXBuildFile; fileRef = 2581AA780F218D5AAF0D6EA495651CA5 /* memtable.h */; settings = {ATTRIBUTES = (Project, ); }; }; CC307EB96B5EE65AEA776D210D9F1104 /* RCTInspectorDevServerHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = E62EB5FA27F6828BF00DC2FAF8C801F3 /* RCTInspectorDevServerHelper.h */; settings = {ATTRIBUTES = (Project, ); }; }; CC55B4859757D16D04340023F6218C1A /* LOTComposition.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FC7E18D44F599E0A2115E29EAFB55B1 /* LOTComposition.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CCAC15E902228F355342E658C1AD8F70 /* RNPanHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = AB1EAD16533C88F11FC3DD170FC841E1 /* RNPanHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; CCC3665B0D8F29CA4692D567D580B4A0 /* JSINativeModules.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B4D47D9E7EC3DB220CC86EC3BC65AD3 /* JSINativeModules.h */; settings = {ATTRIBUTES = (Project, ); }; }; CCF2D3B3613631BE873F2E4238C86255 /* RCTTextTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 650B57D7A404F369CB237E61EF0EA9D8 /* RCTTextTransform.h */; settings = {ATTRIBUTES = (Project, ); }; }; - CD5C2BA165DB596F4723A49E23E150BA /* pb_common.h in Headers */ = {isa = PBXBuildFile; fileRef = 3AD64AEC8F88EDF0FBA67499A8E1BAC3 /* pb_common.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CD21F2D35D090736AA8650A31A3400A3 /* Timestamp.pbobjc.h in Headers */ = {isa = PBXBuildFile; fileRef = D0A50AC65A954663824B0368232AA1F0 /* Timestamp.pbobjc.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CD65FFA81F39C2D6D955FDD9FE7E0131 /* FIRLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 524DC92E428590D64BD35B69FAE4E32B /* FIRLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; CDC37BF44F5072ADF0A3E9E15C9DA0BD /* RCTSafeAreaViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 03F7F96614223367ED6CAB4C3E8DC736 /* RCTSafeAreaViewManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; CDD0D3ED73297A22917534A2A164AFEC /* RCTSwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = 670D9CBD24A68989F39AC9EA92A043CE /* RCTSwitch.h */; settings = {ATTRIBUTES = (Project, ); }; }; CDFCCF999458238031C324D7A9C3A3D6 /* RCTImageBlurUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E65C73D2BC04DDFF78DC170CE2C9EC9 /* RCTImageBlurUtils.m */; }; @@ -946,226 +1315,286 @@ CE0900BA772EFDFCF45A77E4807D742A /* RCTBridge+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 817530E6C928CADC2BB77B42E29DC002 /* RCTBridge+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; CE156A0959F934AF0B580179E6E220D2 /* RCTConvert+Text.h in Headers */ = {isa = PBXBuildFile; fileRef = 310762F9BD551FCE1265F8B7AEA14FA9 /* RCTConvert+Text.h */; settings = {ATTRIBUTES = (Project, ); }; }; CE5407F1BC5E010FCE36B3CA47E34D03 /* RCTMaskedViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 202CEFF02AB6C39FA334A9B51F1D8870 /* RCTMaskedViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - CE57855893FD21B83E44BDAD4B90E618 /* GPBWireFormat.m in Sources */ = {isa = PBXBuildFile; fileRef = 88DF437691E927D8BF17D5DEDA4F65EA /* GPBWireFormat.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; CE7CAC22EEE67E0C6A76E39B7DF9E157 /* RCTWrapperViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B00149D139B98EBDFEDADD6B0EC3ABDF /* RCTWrapperViewController.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; CE8519ABB004F881DC300B71D145C0A3 /* LOTBezierData.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BB195552DB736B00A2DDC46ED5F7F22 /* LOTBezierData.m */; }; - CEBA933E0875C2F373DA252D59C1F158 /* demangle.cc in Sources */ = {isa = PBXBuildFile; fileRef = 52532E69A2044DDD180BABF354EE7E65 /* demangle.cc */; }; + CEA99928D4EA2DEDA9B6575870AF20CB /* FIRDatabaseConfig_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = E239DC18249A7979EAB77B82565AC428 /* FIRDatabaseConfig_Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CEBA933E0875C2F373DA252D59C1F158 /* demangle.cc in Sources */ = {isa = PBXBuildFile; fileRef = 0091745266BB0CA502AFA0EEE4BC1F65 /* demangle.cc */; }; CEE496E9BF30D5C1A5631A235BA90A47 /* RCTViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4095214014C09337822E347037EE75D0 /* RCTViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; CFAB1DA51EE3844654BA62BE9361D26E /* LOTAnimatorNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 671FF1235A314976A563716029B5F4EA /* LOTAnimatorNode.m */; }; - CFD1D48B88C942CEC0DEF42980FE59F2 /* RNVectorIconsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = A63A7845D5D8252F25F776BCD60DB0B8 /* RNVectorIconsManager.m */; }; - D005AC08259585CEF587FE2B122F6CB3 /* RNGestureHandlerState.h in Headers */ = {isa = PBXBuildFile; fileRef = B00ADF8372DC0454091CF0BB4BBAB371 /* RNGestureHandlerState.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CFB61C168BC344927165EB13CAB19648 /* FArraySortedDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F68366A11B377715E042AE44705C84B /* FArraySortedDictionary.m */; }; + CFB69C39DF772B3A3F42193E41CF8221 /* GULReachabilityMessageCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 23AFDC3FD68BD01B454A06682CE3ACD8 /* GULReachabilityMessageCode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CFC67BC60F185B7EA7F5AD04542FF2BA /* FOperationSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 17EA5C6CF12F09B8E6CB1128E1F997E7 /* FOperationSource.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CFDCBE473B99BB78E3F984DDE446790B /* FTupleUserCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 84A5D23ED0B9FFA009FFA35EB291AB1A /* FTupleUserCallback.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CFE1D62AF406FD038F9BBBBE643D84F5 /* RNFetchBlobConst.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D1DC0DAA27875096DEE4ADBD2161459 /* RNFetchBlobConst.m */; }; D00C9229B70C5AAA868DBF6AACBF3177 /* RCTBlobManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = C7355975BE16954A289895CFB03F6130 /* RCTBlobManager.mm */; }; - D067BBB335AAC3CE608E89CFC26FD7FC /* GULMutableDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = C164FB1950C97D321BAD71E7B09EFAE2 /* GULMutableDictionary.h */; settings = {ATTRIBUTES = (Project, ); }; }; - D08E5B14CEA0BD64B060AF27FBC6EFE5 /* RCTCamera.m in Sources */ = {isa = PBXBuildFile; fileRef = 8A50D282DCFFDC13A41E028712B304E8 /* RCTCamera.m */; }; - D0F3166D09790783F929A4DDADA37714 /* DoubleConversion-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 08283566C09AC0491587696FA9DBD268 /* DoubleConversion-dummy.m */; }; - D13FB891E0B40056CA513244647EB941 /* GTMSessionFetcherService.h in Headers */ = {isa = PBXBuildFile; fileRef = D217F05EA07BA1756CB1ED1DB1B1297A /* GTMSessionFetcherService.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D0777D0D19D44A48AA9CCA523BE9D85F /* testharness.h in Headers */ = {isa = PBXBuildFile; fileRef = 208205C1978010CC4D1CA1B7BD5F07C8 /* testharness.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D0F0DA45E564DFEDAD5067A2F2968AC2 /* rn-fetch-blob-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = C3277A54607788C1F851C3A4076FCA8A /* rn-fetch-blob-dummy.m */; }; + D0F3166D09790783F929A4DDADA37714 /* DoubleConversion-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 059085B56857C3A23B738477A8506199 /* DoubleConversion-dummy.m */; }; + D12D3AC0B2A4D2E429E6E9F06B669015 /* FSparseSnapshotTree.m in Sources */ = {isa = PBXBuildFile; fileRef = 473169B7B5260E7DB0EF41FC5FE82E1F /* FSparseSnapshotTree.m */; }; + D12F33493208D3073B51BB4BFB4D215C /* FSnapshotHolder.h in Headers */ = {isa = PBXBuildFile; fileRef = 60C94E3663E9FEEEE52C5735B40D1878 /* FSnapshotHolder.h */; settings = {ATTRIBUTES = (Project, ); }; }; D17725D2357B9C15FA03E0F58BC4C824 /* RCTInputAccessoryShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C7D8A5F115A4003517A46E722C87A64 /* RCTInputAccessoryShadowView.h */; settings = {ATTRIBUTES = (Project, ); }; }; D1DD78E9739F8A7A9FC31A816401737D /* UIBezierPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A04BF50BC8EDFBD7D470C4A6A57C154 /* UIBezierPath.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D20B16A522B1AEAFB045EFED4638D291 /* FRepoInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = C18E7A2F44E3CA8C7C511D941F510972 /* FRepoInfo.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D215AD6BDEEF2A4C513B105F2B9A666F /* NSError+FIRMessaging.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EEC2E179EE88ADA68266CD2DEC1F4A1 /* NSError+FIRMessaging.m */; }; D2D1B2B31D0E32CD1FAAAB47A1054BA4 /* ARTSolidColor.h in Headers */ = {isa = PBXBuildFile; fileRef = 094D117A5256ACECDD26613C69C201DF /* ARTSolidColor.h */; settings = {ATTRIBUTES = (Project, ); }; }; - D2DC4E0ADFCD5EC47BB16F230C44668D /* GPBMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = CE2BE289D98F170C42BD48505D636DED /* GPBMessage.h */; settings = {ATTRIBUTES = (Project, ); }; }; - D2DFE3D6DE3F2D53905A0F6B6BEFBAA0 /* RNFetchBlobConst.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D1DC0DAA27875096DEE4ADBD2161459 /* RNFetchBlobConst.m */; }; D36C4FB806018801D882B1C48AB5F160 /* RCTSafeAreaView.h in Headers */ = {isa = PBXBuildFile; fileRef = DAED88F71117DC4A32D6894F1FB96FF0 /* RCTSafeAreaView.h */; settings = {ATTRIBUTES = (Project, ); }; }; D37982D1BB0B5135BF146066C037A87D /* RCTParserUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B75D776FA7AF1AC6DDEE7E22134D344 /* RCTParserUtils.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + D39C93159FF257FB6F49AD432238264D /* FIRDatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = DCBA4B6D5B8B1D7BEA57870E0AFF5FAA /* FIRDatabase.h */; settings = {ATTRIBUTES = (Project, ); }; }; D3EB8C04EFC6B2A7380C33C53669CC4F /* UIColor+Expanded.h in Headers */ = {isa = PBXBuildFile; fileRef = 01929951D5F7706DB8E73E00B1CA5F37 /* UIColor+Expanded.h */; settings = {ATTRIBUTES = (Project, ); }; }; - D42C1B204922084F4FEDCA451C14AA2E /* RNVectorIcons-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AD64A7145A593F426EA57467D5625F3 /* RNVectorIcons-dummy.m */; }; + D3EEF94F7EA9E8C801E7D0C34FF48364 /* FTreeNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4457F2FAE5F4B126775B3F4783243322 /* FTreeNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D3FB43A0B478FE43C47E4BDFADD4E4E0 /* GPBArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 78AA68D19B1F685D88867FD4E892FEDA /* GPBArray.h */; settings = {ATTRIBUTES = (Project, ); }; }; D4337E42FDF5E6DD77FBF3A56679FA92 /* ARTGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 2453345CD7397B82DF0FA2E4EB28F3BA /* ARTGroup.m */; }; + D4398146DDC2CD89858D5B0923A015F4 /* FListenComplete.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A957ABA5B2C2265A3AD0EE1B4A29FC8 /* FListenComplete.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D483F932471FE02FD203E158268CF117 /* RNRootViewGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0A8083D1F6D61E7CADFCFEC6B487C4 /* RNRootViewGestureRecognizer.m */; }; + D4C69CA73ED5DB5D3B6CA9340AA893DD /* FIRApp.h in Headers */ = {isa = PBXBuildFile; fileRef = 7DC2D23C296C50404F997788F0820D30 /* FIRApp.h */; settings = {ATTRIBUTES = (Project, ); }; }; D4C7D2525F7897CC01DF826839E3E216 /* LOTRadialGradientLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 582E4A6A2B2641A0BA4423E00A100423 /* LOTRadialGradientLayer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - D4DA1F113B5DE5E746CF35894C01ED9C /* RNGestureHandlerDirection.h in Headers */ = {isa = PBXBuildFile; fileRef = D76D5D51CD891E00FB602A22F703D79A /* RNGestureHandlerDirection.h */; settings = {ATTRIBUTES = (Project, ); }; }; D4F52944B13F24ABBCE935ABDD03CC04 /* RCTSurface.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33677BAA7A4403589F38035004F76073 /* RCTSurface.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - D558F66FD6ED01B2E74511EB48A9FE47 /* FIRApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A8327FC8E434A4FD8AD318FD9CCF1DF /* FIRApp.m */; }; D55C1ECBC9847DACADEA08563FDE490E /* RCTScrollContentView.h in Headers */ = {isa = PBXBuildFile; fileRef = E221A524F918A64DA7B7204158DFD9AC /* RCTScrollContentView.h */; settings = {ATTRIBUTES = (Project, ); }; }; D59C635DF424743BE566CA367A3CF9C1 /* ARTNodeManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 08C3AE369601BB599B605DEA3A811741 /* ARTNodeManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - D59D8F2920198040224CE8178CDC525A /* GULAppDelegateSwizzler.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E822D3712B9F2508695B633714B57B3 /* GULAppDelegateSwizzler.h */; settings = {ATTRIBUTES = (Project, ); }; }; - D5DF8DA8032627AF2C452567022217FF /* RNGestureHandlerManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 97539D7F20648B8EB3502B6C2D03DBA1 /* RNGestureHandlerManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - D5FCCBC6FC17EF4AE9A47A846E86635A /* symbolize.cc in Sources */ = {isa = PBXBuildFile; fileRef = F434B45DD59F2A9E58327AF6CD3196C2 /* symbolize.cc */; }; + D5FCCBC6FC17EF4AE9A47A846E86635A /* symbolize.cc in Sources */ = {isa = PBXBuildFile; fileRef = C17BCCDDD4B9DE20CDD862DB25AE65EE /* symbolize.cc */; }; D622FE267FF6987F3E6BA9B866FDBF4D /* RCTSpringAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 506D06BA5D3CCECBB07CB08C9000987F /* RCTSpringAnimation.m */; }; D64CB98B52AFE4991FED10E9353237F1 /* instrumentation.h in Headers */ = {isa = PBXBuildFile; fileRef = FC82D6BF01B2A16F37302C3EEC6E8727 /* instrumentation.h */; settings = {ATTRIBUTES = (Project, ); }; }; - D6C7269D8A0D8F472B91F5905B877DB8 /* RNCAsyncStorage-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = F9BB0530FA2B7ABB88C9492E14A34A62 /* RNCAsyncStorage-dummy.m */; }; + D65D11EF73E40819E2E5028A1D2732D3 /* FTupleTSN.m in Sources */ = {isa = PBXBuildFile; fileRef = 0443112F2C0662B91042E0AEBB57DC06 /* FTupleTSN.m */; }; + D6DD6E870187C3F6FDDFA71AABC2D3A2 /* GULNetworkLoggerProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 92A08879A6771EC77258B679ADC924C5 /* GULNetworkLoggerProtocol.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D6FD46E2815B593AD2ABEB59AF4E4C94 /* c.h in Headers */ = {isa = PBXBuildFile; fileRef = B091C318F79526158445BD1BEA70EE1D /* c.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D706F00399FEFE632CFE106C61F1D233 /* FRangeMerge.m in Sources */ = {isa = PBXBuildFile; fileRef = BE9CA43AFEEF958245EE8ACFBEE39DDE /* FRangeMerge.m */; }; D71BC274854C97E329A4521F64320F4D /* RCTModalManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 63C3B40B412C1338FDB1C37A27251328 /* RCTModalManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - D72CC7409F3C3C1B0E8AD96F026CA241 /* FIRAppAssociationRegistration.h in Headers */ = {isa = PBXBuildFile; fileRef = 956092396D8711436F8FD00E422519E4 /* FIRAppAssociationRegistration.h */; settings = {ATTRIBUTES = (Project, ); }; }; - D78B51B22EE74B1B777D0F0D1ACDEBDE /* FIRDependency.m in Sources */ = {isa = PBXBuildFile; fileRef = 9871279D3275A57A5741B76A1FA0C70C /* FIRDependency.m */; }; + D7E24A2389B49642273A6B595252C0FC /* GULMutableDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = D19E3BE45818BDD32978B54B12A699D5 /* GULMutableDictionary.m */; }; D835AFDD69F404FA50E2E4BEF7EED614 /* NSTextStorage+FontScaling.h in Headers */ = {isa = PBXBuildFile; fileRef = 092C1DBA998516C3FD1BA9BC820F1557 /* NSTextStorage+FontScaling.h */; settings = {ATTRIBUTES = (Project, ); }; }; - D891A8BD4011E9F81950945388D37E2D /* RNRotationHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C1B758110482496963A1857EB4703E8 /* RNRotationHandler.m */; }; + D852DCAF8B012B21EF9288350A4E3F76 /* FIRComponentContainerInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 56DBBA3497A012C8AB33055D5DA559A8 /* FIRComponentContainerInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D863BFB7CE4E154ECAD4996BDABE2CDD /* FTupleOnDisconnect.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BC0964039A18391158C331D4DB21FD4 /* FTupleOnDisconnect.m */; }; D8B0FD1AE4B6A0F8D25E8B2B21751B5C /* RCTWebSocketModule.h in Headers */ = {isa = PBXBuildFile; fileRef = D293C55B6E9EA0811D18F194C74DEC29 /* RCTWebSocketModule.h */; settings = {ATTRIBUTES = (Project, ); }; }; D8D713A0AEDDE5977DE2A541CF1748BE /* LOTCompositionContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CAC838DD88D2D4FFB88840897FBC28F /* LOTCompositionContainer.m */; }; D8F310508E41964FAB5B15215DA2D197 /* RCTWebSocketExecutor.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B2C2794E9BD66CD459106E6836ECE13 /* RCTWebSocketExecutor.m */; }; + D940B3E1BE2A8C583EABC60E7E29BE2F /* builder.cc in Sources */ = {isa = PBXBuildFile; fileRef = 622CE1787B15B5BF9B8E6D7C32EE1F60 /* builder.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; D94341121A627A8DF168184E70BC7166 /* LOTShapeStar.m in Sources */ = {isa = PBXBuildFile; fileRef = B725E4A7DA69A23B0480624F11C61823 /* LOTShapeStar.m */; }; D946B1978BEB85F2B08983863444AAE9 /* RCTTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = F967CE02BF608E45E02D579CD9F45449 /* RCTTextView.m */; }; + D95CA95E195C4DE64DB8A869EEA301F1 /* GPBRootObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B690A9359A398B343537A429DBDF0F9 /* GPBRootObject.h */; settings = {ATTRIBUTES = (Project, ); }; }; D975F0B14063924B9FC41A6AB1E180AC /* RCTRawTextViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 2EAEECA81B7EBF096C19D14F97514F13 /* RCTRawTextViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - D9D0A0B908A6C31A8983D5D1DB9B5DBD /* GULSwizzler.h in Headers */ = {isa = PBXBuildFile; fileRef = 8C02673A3977C4B70F2FFE4CFE80D989 /* GULSwizzler.h */; settings = {ATTRIBUTES = (Project, ); }; }; - DA7E6FB5A40BD2E067CB80AE0FB029B7 /* RNGestureHandlerButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 85E6E56A33A36BEB34C1AF48CC77EB02 /* RNGestureHandlerButton.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D9B00ED55275DB056D716D099687E078 /* FLLRBValueNode.m in Sources */ = {isa = PBXBuildFile; fileRef = E0FB88CDA2B66EEF55DF26B852C8C7DF /* FLLRBValueNode.m */; }; + D9FE98956BE308F549E125550899F6B5 /* RNGestureHandlerEvents.h in Headers */ = {isa = PBXBuildFile; fileRef = F794D9A735E46A11E4EE3F1E77A9753C /* RNGestureHandlerEvents.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DA6BC229F531E52A212D19DDA1D7AF58 /* RNCamera.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F612EEFB18D2E5295A47F69A2FC4A84 /* RNCamera.m */; }; DAF3A2DF5B73D4B41AF405338F37CC13 /* RCTMultipartDataTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 2ACD8C020C859A4C2BDFAE9204E09AC6 /* RCTMultipartDataTask.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - DB17CE3D79A3C58558BD653382F29510 /* stl_logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 855A4A4D0254750282F9818524C8A400 /* stl_logging.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DB17CE3D79A3C58558BD653382F29510 /* stl_logging.h in Headers */ = {isa = PBXBuildFile; fileRef = E93A0049997B4AF4882B81A770C7A357 /* stl_logging.h */; settings = {ATTRIBUTES = (Project, ); }; }; DB1B6BD29EB113DA93EA5DC940D56F42 /* RCTPackagerClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 45A392302A405B0BF159FBEDA479AC2B /* RCTPackagerClient.m */; }; DB30E34B4746B1801F185B2262D4B924 /* LOTLayerGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 31B9876795C497C2401DBC409B70C41D /* LOTLayerGroup.m */; }; + DB5BB7ACF9E7B95476CA44906F412E08 /* FIRMessagingCheckinService.m in Sources */ = {isa = PBXBuildFile; fileRef = 317A540B41EBF84D2B70A726EE91CD5F /* FIRMessagingCheckinService.m */; }; DB75E5467B76B0612B84683F2046533F /* LOTShapeFill.h in Headers */ = {isa = PBXBuildFile; fileRef = 86721F4035FCFF4C51729F4D220E8D93 /* LOTShapeFill.h */; settings = {ATTRIBUTES = (Project, ); }; }; DBE56981219CC54B6C2FB69E7536EB18 /* RCTBaseTextInputViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1C14C35A19AF78E3297F99ECB885B3A1 /* RCTBaseTextInputViewManager.m */; }; DBED8431C5428E3708992E00AABA4937 /* UIView+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF753F1A291F75A7AE6B56DD2E388A0 /* UIView+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DC1A393DB2798F10C1A8D6FAC9F1BD5A /* RNCAsyncStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F73F441EFFB57B67671EC1D71949757 /* RNCAsyncStorage.m */; }; DC44D73D47E57A326B4DC65894A70957 /* LOTSizeInterpolator.m in Sources */ = {isa = PBXBuildFile; fileRef = 56D39D45B18459AA455BFBFF4FAD257A /* LOTSizeInterpolator.m */; }; - DC5CD1FFC1DF7B1B99CEAC11E107C17F /* glog-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = E4D149BAE01097E99370276CD05701C2 /* glog-dummy.m */; }; + DC4F7559F6C5F2120786E2AE2A121444 /* Timestamp.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D97F98E914FF8F367D4172A6ADFCA5A /* Timestamp.pbobjc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + DC5CD1FFC1DF7B1B99CEAC11E107C17F /* glog-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 8731D3E9DDAC0B89CDD6F6EC2D655B24 /* glog-dummy.m */; }; DC607037B07CB098F6D2178002996C19 /* RCTNetworking.mm in Sources */ = {isa = PBXBuildFile; fileRef = E080E68F9FC380CF31ED3FF9D3C684B1 /* RCTNetworking.mm */; }; DC62FCEC70B64CB94A180C5A8A64B09C /* RCTEventDispatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = D0AE4BED71888F3A5354D7A7B0C35F3B /* RCTEventDispatcher.h */; settings = {ATTRIBUTES = (Project, ); }; }; DCB4BE7AE1C85DB0C7F1FDC42EBEE7B3 /* RCTVirtualTextShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = FEF78209E27EA271441A7BCE73F837A8 /* RCTVirtualTextShadowView.m */; }; - DDAA33220CD6AF40659A21F76FA95C4B /* FaceDetectorManagerMlkit.h in Headers */ = {isa = PBXBuildFile; fileRef = B932271FB81CB35C7C0424FE0293122B /* FaceDetectorManagerMlkit.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DCF15F95FAE2BEA35F039BAA607DCAA7 /* FValidation.h in Headers */ = {isa = PBXBuildFile; fileRef = 61ACF260B4EF5D451280A6D877073D43 /* FValidation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DD96D9527958D87E78C92E117A9E26E3 /* CameraFocusSquare.m in Sources */ = {isa = PBXBuildFile; fileRef = 92B09EFD510A481A35910A0357C904D5 /* CameraFocusSquare.m */; }; + DD9A08C5B56E232AD3A85E04A8BE7476 /* dbformat.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3F5F074174924D93C197546B8037001E /* dbformat.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; DDC73A36C06CDCD26C927948B490E067 /* RCTResizeMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 9385A8EAF9C13A19B70C1E945A795A7A /* RCTResizeMode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DE0B7E6F588668F2888D407F60A1D62F /* log_reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 6442B918CC9418758CF784503DBAB162 /* log_reader.h */; settings = {ATTRIBUTES = (Project, ); }; }; DE16B27EE60D7D189F6B21BCE9AE16F9 /* RCTProfile.m in Sources */ = {isa = PBXBuildFile; fileRef = 99E8ADB319D634EF68B91446363EBB28 /* RCTProfile.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; DE181A136E8510940CC487D0BF8D83DC /* RCTConvert+ART.m in Sources */ = {isa = PBXBuildFile; fileRef = CBE5B10943CD147795ADCB05AFB5EF1F /* RCTConvert+ART.m */; }; - DE66DA857A4E0DD7EEDE0D58F4E8A5F2 /* FIRComponentContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 98FC40A3FE46790AAADF0F447DBD2475 /* FIRComponentContainer.m */; }; DEF40C0B830BDDDB8AB547588967F6F2 /* RCTSliderManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 588BEB890092B4F1677B0E9EB2911C77 /* RCTSliderManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; DF375C905A333B79B37E39F3559981D5 /* RCTRefreshControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 5ACF6CBFCA3AC47C540C3C7419FE53AA /* RCTRefreshControl.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + DF6680AC21D5775E07D44E12C71BF279 /* FTupleRemovedQueriesEvents.h in Headers */ = {isa = PBXBuildFile; fileRef = F7ACDEDE0588E8BFED42E158BF74D1A1 /* FTupleRemovedQueriesEvents.h */; settings = {ATTRIBUTES = (Project, ); }; }; DF926A6B03E82B1545762B9CF5EB6CD6 /* RCTWKWebView.m in Sources */ = {isa = PBXBuildFile; fileRef = CD7F87C359E0FE18DC0D5E9CA48C10B0 /* RCTWKWebView.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + DFB3B78A02C98D0E56889301764B5F2E /* port_posix.cc in Sources */ = {isa = PBXBuildFile; fileRef = 961544B462C97D32FB08BBB712F6753C /* port_posix.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; DFD6E8E489141F36DEFD964573F5B1FD /* ModuleRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 460D0B7487E6617FA7B85B894612A8DF /* ModuleRegistry.h */; settings = {ATTRIBUTES = (Project, ); }; }; - E014D5970B9ED5F2E48A3C434D48DD34 /* RNFetchBlobRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = C503F2038314A9628108B22C4993AD58 /* RNFetchBlobRequest.m */; }; - E047BEBE605021439F4E01B0A92ED6F1 /* bignum-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = 576CCA63035FF40021B2C4893AD22C70 /* bignum-dtoa.cc */; }; - E0E28EBD3C58CBA48A5E6350B8B8DBB9 /* GPBDescriptor.m in Sources */ = {isa = PBXBuildFile; fileRef = F33CF734EB75D645B6F559246B91C0EE /* GPBDescriptor.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + DFEF7F5580CD6D24A03E9A899B8400E0 /* Type.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F40FF9A2C28A675DBD9CAF66C26FF0D3 /* Type.pbobjc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + DFF23735A94D669FDF9E6B52F36EEF20 /* FTupleBoolBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = BF22DB6374FFB9A50C6A86CFB0C76AA5 /* FTupleBoolBlock.m */; }; + E047BEBE605021439F4E01B0A92ED6F1 /* bignum-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2D38CC89FE381ABEE58778A8430EC558 /* bignum-dtoa.cc */; }; + E06BA97EBAC98AE3DDE30EC133FA4BFA /* FQueryParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 279A3550CD2D5DDEC0DCCEB54A44A4C4 /* FQueryParams.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E0A6A324E0CD7F7F28506331798E4C55 /* GtalkCore.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 0522DE22463906DA220EC22B9CDB8B94 /* GtalkCore.pbobjc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; E144AE0B56AAAD7978DA63303AFE45F4 /* ARTBrush.h in Headers */ = {isa = PBXBuildFile; fileRef = A9B0F1B7B070C44944D560B5882D048E /* ARTBrush.h */; settings = {ATTRIBUTES = (Project, ); }; }; E1C393092A3D7966DE890DEFF6711F6C /* RCTProfileTrampoline-arm64.S in Sources */ = {isa = PBXBuildFile; fileRef = 725E5C8C5289CC330632F4343FBF8BAF /* RCTProfileTrampoline-arm64.S */; }; - E1D7CA508B6E16AA7151AE0C7BEFA777 /* GTMLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = CFBAB1A595B912E748E740EA7F52B3DA /* GTMLogger.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + E1EC2AE00609612EE09CE76F4A8B6A17 /* RNVectorIconsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = A63A7845D5D8252F25F776BCD60DB0B8 /* RNVectorIconsManager.m */; }; E1F048E786E6C9DF7B87EC2C55D1B004 /* RCTDivisionAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4316C0A63F69747996783CF7CE0283B1 /* RCTDivisionAnimatedNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E20D8615C67AF849C9C656E220B5EEF6 /* format.h in Headers */ = {isa = PBXBuildFile; fileRef = 3535EA46EDD3D96558DC4A1026C4DE0F /* format.h */; settings = {ATTRIBUTES = (Project, ); }; }; E21FBDC48E71B6ABDEC6F3F39F018E87 /* RCTMessageThread.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6DC9A94A09A4624AB1124AC0D2C15309 /* RCTMessageThread.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; E22FD268E4CA8345A60DF19473C3F3F1 /* LOTInterpolatorCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 284CE73BA93AF2DBCC13D60F939D8AAA /* LOTInterpolatorCallback.h */; settings = {ATTRIBUTES = (Project, ); }; }; E2328CDEEDB6E48DFC56866D5E4F2AFF /* RCTLayoutAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 26CE83BC330B28EB74B16605040003BC /* RCTLayoutAnimation.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; E2B55CF3FD0D27BCE42A632CF51B10FD /* NativeToJsBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = B180FDEA9837D85FA70FC4346B89A0F7 /* NativeToJsBridge.h */; settings = {ATTRIBUTES = (Project, ); }; }; E2B9C22954B63E343398C6B05FF59647 /* RCTAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 96995B796E3EB652FC1CF2BE54246301 /* RCTAnimatedNode.m */; }; - E3185C87D5A50228FA0CCC843A3DD0B0 /* pb_encode.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B08F7E25D12EB4A87A9121CACBA86AD /* pb_encode.h */; settings = {ATTRIBUTES = (Project, ); }; }; - E3324DDB69FD906AC89A71F5732A1823 /* SourceContext.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = ABE121B8F8204830E2DDDB9E6E0B724E /* SourceContext.pbobjc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - E355084E8391D9A71CF0DE9BE2355FF4 /* double-conversion.cc in Sources */ = {isa = PBXBuildFile; fileRef = D6370AE595DEA29F6BFBF7A1FE241694 /* double-conversion.cc */; }; + E2C4CEF466CD0D6E6E2BEFBEE257197E /* RNCamera.h in Headers */ = {isa = PBXBuildFile; fileRef = 911D510658586F54B72EDCA08D6C57BD /* RNCamera.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E343EF2D0EEAB2FCF3FA5F1C262D68CD /* FIRMutableData_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B42FCEC34634448FD698A9E455C74B8 /* FIRMutableData_Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E355084E8391D9A71CF0DE9BE2355FF4 /* double-conversion.cc in Sources */ = {isa = PBXBuildFile; fileRef = 0079273BFA178FC1D3EB5A83E2E021CE /* double-conversion.cc */; }; + E36A3301796EDD8B74AF5AF15EE97879 /* FTupleObjectNode.m in Sources */ = {isa = PBXBuildFile; fileRef = D4EA5D48358A64B6E278A7F281758C47 /* FTupleObjectNode.m */; }; E373543FD5ECAA70A589E559B8026527 /* YGConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 7356F174C3C879B33E39DE8286361D19 /* YGConfig.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E3C3983950941BAF636880BAAAF9332F /* db_impl.cc in Sources */ = {isa = PBXBuildFile; fileRef = F35A0211C71E14D30E9960DD0297256D /* db_impl.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; E3CBC4B87C7F791C49154D8EE06F190F /* RCTUIUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 1B11C9CEB955F2A8B352F3BD3AC30DE3 /* RCTUIUtils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E3E45784C42349DC19CDEBA6F2723512 /* FLeafNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 529DD218B7FEAB0FD9D59EFC98F24DF4 /* FLeafNode.m */; }; E472991D2D35A56BE3AAF4DF57BE1420 /* ARTGroupManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B29FC6C848393BBCD0A6F9EA4A954B73 /* ARTGroupManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; E474CD6B45A604A8A99BE69D9CDF762A /* YGMarker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D8B2472D47EE2975E0761212822EA32 /* YGMarker.cpp */; settings = {COMPILER_FLAGS = "-fno-omit-frame-pointer -fexceptions -Wall -Werror -std=c++1y -fPIC -fno-objc-arc"; }; }; + E492FD1D0F950C9915C580EB89F76804 /* FIRRetryHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 981A7005F97321DE167E0284DA26CA96 /* FIRRetryHelper.h */; settings = {ATTRIBUTES = (Project, ); }; }; E4AA4D83718D2AB48013D2801302A5D2 /* UIColor.h in Headers */ = {isa = PBXBuildFile; fileRef = 5116AAB3AA934A9D25C58991F46D2A8D /* UIColor.h */; settings = {ATTRIBUTES = (Project, ); }; }; E4B88EA62FF27B7ED348000528685124 /* RCTVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FEBD5C9C01BC81616CF51782FE941B2 /* RCTVersion.h */; settings = {ATTRIBUTES = (Project, ); }; }; E4BBC379EC1741BF0B2349318F86C401 /* LOTMaskContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 00DD70332EF9B678EB55555BD8E5EC43 /* LOTMaskContainer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E4DFEC4486874317EB58F04764F922C8 /* FIRNoopAuthTokenProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = A2FD731CDB94C61CDE98166ABD6071E7 /* FIRNoopAuthTokenProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E4E725D3F41BEA19B1A1F36D61C8D49F /* FIRMessagingTopicOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E8D7E53496B4BF7E29AB957ABC2565B /* FIRMessagingTopicOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; E527EC3B53E332FF5C6E989E60194F33 /* LOTValueDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = E7197EFE05484AB6A667F1D481C3E22E /* LOTValueDelegate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E53C2294CA635D2BF10A0702DD11C0A9 /* GULOriginalIMPConvenienceMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D0545CF38D0D7BDE8CADA67D790B465 /* GULOriginalIMPConvenienceMacros.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E568519D546B77B516F43ADCC70BDD6C /* FEmptyNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 9693C764585DF4F21DC261BAC46C1B91 /* FEmptyNode.m */; }; + E573719D08940140F2D661C384C105EE /* RNRotationHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B2F7643BC09CB61D842C17C7F3CD8B1 /* RNRotationHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; E5CC1D27E8190436886EBA44B5C8D697 /* LOTShapePath.h in Headers */ = {isa = PBXBuildFile; fileRef = 17AE8534092346597F0F30C4088C4090 /* LOTShapePath.h */; settings = {ATTRIBUTES = (Project, ); }; }; - E5D727851E73258ECB305EE470A4E462 /* GPBRootObject_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = E09978CEA186ADB6111AD2F9C5948BD6 /* GPBRootObject_PackagePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E5DE5D31EE76423F9F3422BB832C788F /* RNVectorIcons-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AD64A7145A593F426EA57467D5625F3 /* RNVectorIcons-dummy.m */; }; + E5DEAF7B16E65CA66325F83AE1A58B9C /* FSRWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 7326097D94A70A24EB9F31AED2BC8EAB /* FSRWebSocket.h */; settings = {ATTRIBUTES = (Project, ); }; }; E5F1BCDF10B22DEF3BFD4252F27F2C19 /* ARTRenderable.h in Headers */ = {isa = PBXBuildFile; fileRef = A12B66C8CE4E84C8F2B950757C6954F4 /* ARTRenderable.h */; settings = {ATTRIBUTES = (Project, ); }; }; E61EA0E9C78986D23F128D85B5164879 /* RCTBackedTextInputViewProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = F0FDDBD244E9955CCA1AEF1AFA36DC6A /* RCTBackedTextInputViewProtocol.h */; settings = {ATTRIBUTES = (Project, ); }; }; - E63EF5F9C04C2AFECC4C081027B8099D /* dynamic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D8A7F3EB14D892AF47730840C714CCEC /* dynamic.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + E63EF5F9C04C2AFECC4C081027B8099D /* dynamic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DF01DAD811E57DC0E104624FC8E3958 /* dynamic.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; E671919C91A7539A0ECD4F650799FDA9 /* RCTDevMenu.m in Sources */ = {isa = PBXBuildFile; fileRef = CAC45BF87ED4C888307835A1B7F52C69 /* RCTDevMenu.m */; }; E6A30AB03934A2DAF83CE620766072EA /* RCTModalHostViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 358580AC267FE5D8CBD704501611FDC4 /* RCTModalHostViewController.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - E6D375741B826C594B5D56A754E2BD2D /* GULNetwork.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C17428E231BAEA6AA8DA7844DA8C227 /* GULNetwork.m */; }; + E71C91CB347F4BE5624A42E56E9FE60A /* FIRMessagingPersistentSyncMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 63130479CCFC34C4090DEA0EC26DDEFF /* FIRMessagingPersistentSyncMessage.m */; }; + E71DD15B7354B729F08D756042F1A4DA /* FLimitedFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 267864CCA87DB796A799D1C8EF7D05F7 /* FLimitedFilter.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E75478BD710626804EFA990841477F38 /* FRangedFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BE36269AD6FB60A9259105E262E4081E /* FRangedFilter.h */; settings = {ATTRIBUTES = (Project, ); }; }; E79686D3D85B39D45B6D9194D5E98906 /* LOTShapeStroke.m in Sources */ = {isa = PBXBuildFile; fileRef = FD73FD41476FC068A2D103BA58F1EB3F /* LOTShapeStroke.m */; }; - E824A6440CE987F1EE710A0881AD1AC6 /* RNGestureHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 39B32BB5D0A26142E513079EBA428BCA /* RNGestureHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E7A3644332D3B6AED0EE5F0F91E9B6ED /* FirebaseCore-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 9274C252BFD539E5FDC69265C7A79A67 /* FirebaseCore-dummy.m */; }; + E7C2708DD5E9AB26B2AA63509D978C30 /* CameraFocusSquare.h in Headers */ = {isa = PBXBuildFile; fileRef = AE05C0B725F26A95F95934A61F017ECE /* CameraFocusSquare.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E81B9C5922C86CADE4C0BB4A0E144ED3 /* GULLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 75B640AB094C5A3B26E85EC575DAF7F8 /* GULLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E845993DC1F557382488296682338F79 /* GPBUnknownFieldSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F2D533EDC352B7D0DE415441637CD41 /* GPBUnknownFieldSet.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E84B072BFC2DF6C35D4142110976F6A4 /* dumpfile.cc in Sources */ = {isa = PBXBuildFile; fileRef = 791909236376A7AC032230DCDD821695 /* dumpfile.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; E88A835466E17CD5BF3A62089ECB15D9 /* ARTRenderable.m in Sources */ = {isa = PBXBuildFile; fileRef = 656279E8CE2F3F651EB039E74CE3200A /* ARTRenderable.m */; }; E8945E3BFCB9A53DD4F7A2D727A7FC92 /* RCTRootShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 73E291DAE7396986D57AEAFCB1C1F3B8 /* RCTRootShadowView.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + E8A3641867D06699DC99DA213ED25CCF /* log_format.h in Headers */ = {isa = PBXBuildFile; fileRef = 39F99C7DB7E3135595E3B4FA528D8CCF /* log_format.h */; settings = {ATTRIBUTES = (Project, ); }; }; E8C40E722B05BFC4D72F8FB3E770D70A /* RCTTouchEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 50D55837BAC6B4441EEF54A3B348C056 /* RCTTouchEvent.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; E8F28B07256E275F478A4F7044C82169 /* RCTStatusBarManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C5B6B7BEE23E439D405CAE39C32BAEFF /* RCTStatusBarManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; E9767B2DE27ABD25330D6CFF3EE2B986 /* LOTPolystarAnimator.m in Sources */ = {isa = PBXBuildFile; fileRef = 228B7F62F484C92E3822F08535BF48A5 /* LOTPolystarAnimator.m */; }; - E9CA94D7F3110CBD58BF6523AC8298FF /* GPBDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = C38431EA2F1BFEA2C3D23BC917886E86 /* GPBDictionary.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E98E7937A05647042CD23228F50E1687 /* block_builder.h in Headers */ = {isa = PBXBuildFile; fileRef = 7D55D1B1A1EEFE3C9DA51ADCBC1D2B96 /* block_builder.h */; settings = {ATTRIBUTES = (Project, ); }; }; EA1DD73FF6E144831EC0E20E2A63FE4B /* YGMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D95ADA61F5850D55FFE5C051C6EB34B /* YGMacros.h */; settings = {ATTRIBUTES = (Project, ); }; }; EA3EF58F773343A29C910383DE7B8B4B /* RCTCxxMethod.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B28AE00B98C9CE22A983E63EFA72434 /* RCTCxxMethod.h */; settings = {ATTRIBUTES = (Project, ); }; }; EA543BF13963FFE00B3617282BFF8410 /* RCTWrapperViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = FA766D6EA1284DBB1B057023FAA39AFB /* RCTWrapperViewController.h */; settings = {ATTRIBUTES = (Project, ); }; }; + EAC3DB095EA4352E9E12CA7C586ADF6B /* FirebaseMessaging-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 85AB9F4C2E8E73E002AE9713A5F0578C /* FirebaseMessaging-dummy.m */; }; EADA9C54A8BC6852A2418576C14A68EA /* BVLinearGradientLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 86E41579D642772BEEFB933E211EDDEC /* BVLinearGradientLayer.m */; }; + EAE97385DCFDEF4B727F3AEA9A98E0B2 /* FTupleBoolBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = B19B6B724947A15AD078508AEDEC16E9 /* FTupleBoolBlock.h */; settings = {ATTRIBUTES = (Project, ); }; }; + EAECFCB1CAE1B441CABDC4E6522CD0DC /* GPBProtocolBuffers_RuntimeSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E9EAABCF1ACD513834E19042D2F3C11 /* GPBProtocolBuffers_RuntimeSupport.h */; settings = {ATTRIBUTES = (Project, ); }; }; EBB68E4EA08D7CF8C2B244A452AC2D65 /* LOTRenderGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = E79754D1939CADD9A2BD8B93C18F881F /* LOTRenderGroup.m */; }; - EBED03B859831B804A17EC10FC9F0B53 /* RNFetchBlobProgress.h in Headers */ = {isa = PBXBuildFile; fileRef = B2526A953CFDECE87D286CB079F7960B /* RNFetchBlobProgress.h */; settings = {ATTRIBUTES = (Project, ); }; }; - EBF38B83E921765F6B3480F8510900DA /* Conv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C279CC817F4988EC6BC12D1FC7BD4C47 /* Conv.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - EC274E90B4E60A63A204BA23D4EAF952 /* ColdClass.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D39703CF179678BEC4A69B8694A01080 /* ColdClass.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + EBF38B83E921765F6B3480F8510900DA /* Conv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C1D869DCB8998E09EDF65B9054CD933B /* Conv.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + EC274E90B4E60A63A204BA23D4EAF952 /* ColdClass.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7D686991C1E7EE358016B312E9B964B7 /* ColdClass.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + EC6CE93A7FE2FF239CD63F63857648FF /* FMerge.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C745941C2E59521A729ABA0D06C4A96 /* FMerge.m */; }; ECAABF1D88C6DDC0E90327E8648EA376 /* JsArgumentHelpers-inl.h in Headers */ = {isa = PBXBuildFile; fileRef = 40F3AB45973140BD4CA31F022691E763 /* JsArgumentHelpers-inl.h */; settings = {ATTRIBUTES = (Project, ); }; }; ECE61374C4A1849537BA55E8FD5D71DB /* RCTInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BCEBA993ACB66EC3B4F9FC0746B1C39 /* RCTInspector.h */; settings = {ATTRIBUTES = (Project, ); }; }; - ED4D78E64525ADE4BF615623DBA76706 /* GPBWellKnownTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 8526A6E0B4983EEBE27458896D71AE80 /* GPBWellKnownTypes.h */; settings = {ATTRIBUTES = (Project, ); }; }; + ECEC1E12ED5267924603D9B2B6FC1409 /* RNTapHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = A370A8D76A77EC077A9966F91063910A /* RNTapHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; + ED7E5B87EE62D787243B4BB6970EAD08 /* GTMNSDictionary+URLArguments.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D5E2C8453763AD280CD8070711E7F32 /* GTMNSDictionary+URLArguments.m */; }; + ED7F989F9C32A7EFDE4C7D7B6FAA604A /* GTMSessionFetcher-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = EB2E9C6FCA433DEE6A1FE505D7BCD974 /* GTMSessionFetcher-dummy.m */; }; ED8B9BEFB9EDCB5BB189EA4763B93045 /* RCTMultilineTextInputViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = C845E4CA4E78627DC882F52E50BE94C6 /* RCTMultilineTextInputViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - ED8D12AB8A57D24F990EBFF4C64581D5 /* Folly-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 2410678D9F5CB5DC22FE50D7F0379F3A /* Folly-dummy.m */; }; - ED9D29AEC736F9155E6ADA0B73544963 /* RCTSensorOrientationChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = A9DCDCA15045807E09FAAF6884D391A1 /* RCTSensorOrientationChecker.h */; settings = {ATTRIBUTES = (Project, ); }; }; + ED8D12AB8A57D24F990EBFF4C64581D5 /* Folly-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 49074C2E5E4EA6ED6EB392FB200135AE /* Folly-dummy.m */; }; ED9D43DA8CDF1B4981373B4030F0490F /* RCTFileRequestHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = C7D44258BCBCF27347A517637671E8E4 /* RCTFileRequestHandler.m */; }; EDA15F5AEBE97CEF0AABC6A4EDF6417D /* RCTDecayAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C2D37E893D34B25904C1AE819B80A0A /* RCTDecayAnimation.m */; }; EDABF88C4060897CBA0B32C1101CE05A /* RCTReconnectingWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B6A85AD405BD0E5173260D69711368E /* RCTReconnectingWebSocket.h */; settings = {ATTRIBUTES = (Project, ); }; }; EDCB14D12700A73355924AAA70429F43 /* RCTUITextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 164D64521EB94AA2D7A7EFC5759F5949 /* RCTUITextView.m */; }; EDE2AB48A4DB8CA2C3DFB8E1716E3017 /* RCTPropsAnimatedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = AE2F6E3DD9D915040FECF56B5EBB7AA7 /* RCTPropsAnimatedNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + EDE6A9180C6F8B3334909515AD2DEE61 /* fbase64.h in Headers */ = {isa = PBXBuildFile; fileRef = ADE2305F8ACE4C5E55537E2552D21731 /* fbase64.h */; settings = {ATTRIBUTES = (Project, ); }; }; EDFC007FD30BFF1E14D83ABA34A44A76 /* RCTImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D90E38C531117D96E97CFE156AF7F2F /* RCTImageCache.m */; }; - EE71604A10EB3AC1C5393ADAFB01F291 /* FIRLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 06B7A465837535A2CB308829DF834B8B /* FIRLogger.m */; }; EE72232FE182227D793D8B0C059B84B3 /* RCTRootView.h in Headers */ = {isa = PBXBuildFile; fileRef = 07002D48EB6136F683151A9B409335A7 /* RCTRootView.h */; settings = {ATTRIBUTES = (Project, ); }; }; EE9BFAE22B12380EF92C4B7F06D6BED4 /* ARTNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 10546C57184BA5840555353F51FCBB30 /* ARTNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + EF0E84C41367B8F89ACB192170FCF738 /* FIRAnalyticsConfiguration+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E316121E6C0066D9EEAC18DDB94300C /* FIRAnalyticsConfiguration+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; EF111024CDF81AE372963FCF080F644D /* RCTResizeMode.m in Sources */ = {isa = PBXBuildFile; fileRef = BCFE35AC82A2303C93F12BC734B0D9A4 /* RCTResizeMode.m */; }; - EF2D4358A9E3D015C6CFAF79FB274E9C /* GULReachabilityMessageCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 2792075F8CDA8BFF18CBE95BD0DD1596 /* GULReachabilityMessageCode.h */; settings = {ATTRIBUTES = (Project, ); }; }; EF30D6BBC3D0D641BDC58C7D4BA7A2A1 /* ARTShapeManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A4F2C73ACD927B9486FBCFFE9A06ECD /* ARTShapeManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; EF61000B7C5E50E087BD5BD7496583F9 /* RCTShadowView+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 3967DC89715ACB7F63847339AA56D3A1 /* RCTShadowView+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; - F030B2233B200230A94C9EC48E0A3BA0 /* RCTFont+FA5.m in Sources */ = {isa = PBXBuildFile; fileRef = B3D9AA395B8A6E438AEB2F16D98D26EB /* RCTFont+FA5.m */; }; F0610F5CF05B6947572863D805C449FF /* LOTGradientFillRender.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D8844423291FD86C6B95F535C6E9F55 /* LOTGradientFillRender.h */; settings = {ATTRIBUTES = (Project, ); }; }; - F0954726872BA5624DFF3CBAFAFAB78D /* RNPanHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = AB1EAD16533C88F11FC3DD170FC841E1 /* RNPanHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; - F0B72793022B3003F6AB60A8CE0919E2 /* Protobuf-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = BECFE46C4D035B9D9F991722AA0B59BC /* Protobuf-dummy.m */; }; F0CFC901A410ADD6E2395540E76F2EF0 /* RCTMaskedView.h in Headers */ = {isa = PBXBuildFile; fileRef = 96FFAB43B46C406A48BE65C22ACF11A8 /* RCTMaskedView.h */; settings = {ATTRIBUTES = (Project, ); }; }; F0F27655B2C7738C4285F770C4850FFE /* RCTScrollViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B578FBFE085DFB2F39B4CCF42957029 /* RCTScrollViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; F0F68067BDC781870C2E958802F79C21 /* RCTJavaScriptExecutor.h in Headers */ = {isa = PBXBuildFile; fileRef = 2EFA34689F30A01DA5092DD58DB934B6 /* RCTJavaScriptExecutor.h */; settings = {ATTRIBUTES = (Project, ); }; }; F17BB3511D116B6BC277B6CBBFD64A1C /* RCTRefreshControlManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F255EECA7833B5B5574BC504489CE8F /* RCTRefreshControlManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - F2575DC1F39CB66ADC9013434AF377A6 /* GPBWireFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = B9081F23DE9B5CE80A9F7E36382251BD /* GPBWireFormat.h */; settings = {ATTRIBUTES = (Project, ); }; }; F276BDBF4A94B8492E8AB290B316FBE7 /* RCTActivityIndicatorViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = BC4084335C8BB1D294748F7006D98878 /* RCTActivityIndicatorViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F2B4D2D68DB0EB08EF03C5F10FC71CC3 /* FConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EF52EC3FC7F93B8DA1F7CB9F131FF8E /* FConstants.h */; settings = {ATTRIBUTES = (Project, ); }; }; F2BC94082B411E6AABA36677B2066A5A /* LOTAssetGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 335D303B610AA3BF2E75EC830AF46A91 /* LOTAssetGroup.h */; settings = {ATTRIBUTES = (Project, ); }; }; F2CD1165DD5C71D25086BB15CBDCA26E /* RCTUIUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EC752003B705106CAC2EE5F0FB7F0F4 /* RCTUIUtils.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + F2D6FBEA9787957B00DC15CCF4CF03D0 /* RCTCameraManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B37984E6B75620169C999C514D4145A2 /* RCTCameraManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; F2D77FA401A4CBCC9D32E95FBEE88ABB /* RCTShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = AA2CB2DBE166F9507D94091F7015431F /* RCTShadowView.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F347A71DDBB51EB0DB3E4E05268B6329 /* options.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3CB542AB89073932BBB2EABF4DFD6836 /* options.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; F366B863016FC5FA9B113DE0186993F3 /* LOTAnimationTransitionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 90616E226A6B4606DB5249F30AAD58CF /* LOTAnimationTransitionController.m */; }; F37A9FA800977D1112BEB4A0B034D048 /* ARTContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = A720011F7BD486F3A952633092E5AE78 /* ARTContainer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - F407300AF6C7F53CBB1869EC36A54DAD /* RNCSliderManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E4AA426D9F768455A13E32CB81CF537D /* RNCSliderManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F3F8F8769841AD3DDC9C7AEE42EF2EDF /* FIRMessagingClient.m in Sources */ = {isa = PBXBuildFile; fileRef = CED6E5B78AF9299C7515CA609B49FA2A /* FIRMessagingClient.m */; }; + F3FB9033D2F5EFC3A2B2399F46DCDF07 /* GPBUnknownField.m in Sources */ = {isa = PBXBuildFile; fileRef = 4229147F5CEA195DD7119238617BA3A1 /* GPBUnknownField.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; F407321178F5AA0FD9D1F3EA90055005 /* YGStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = E1DB6641CD9DDECD715A74348312634E /* YGStyle.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F416848DC50BB98C8D95E9847547132E /* FIRMessagingConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 79743169E22CF9AF19816EDD74E1AFE0 /* FIRMessagingConstants.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F42B49049E4BB0940AA0271967DF2765 /* leveldb-library-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = AB9F058E8DFCEF13A69CAD294274BF95 /* leveldb-library-dummy.m */; }; + F42D6CCF705596381849593895540261 /* dbformat.h in Headers */ = {isa = PBXBuildFile; fileRef = 3324B1E18650F1EA8A0408F7CE1B3B04 /* dbformat.h */; settings = {ATTRIBUTES = (Project, ); }; }; F46FD4A925EFB311BF0DBEE6B6F3BDD1 /* RCTProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = AEAB205567BE19020EB024CF512C8832 /* RCTProfile.h */; settings = {ATTRIBUTES = (Project, ); }; }; F4DAB60A31898BEBD3A45C506A719AAF /* RCTKeyCommands.m in Sources */ = {isa = PBXBuildFile; fileRef = 963C60031331362932971E446AD1B316 /* RCTKeyCommands.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + F4DBBB88B5049150B427A3E39CC21412 /* cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = 783DA6DADA45F2B359DE949E9CF607F0 /* cache.cc */; settings = {COMPILER_FLAGS = "-DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -fno-objc-arc"; }; }; F525901DCA224FF4065B494B22F0B1E3 /* RCTVirtualTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13D96F3F28855DA932B7DC774EF9B8B4 /* RCTVirtualTextViewManager.m */; }; - F5DA11E860A51716DE1972B23AC3D9CA /* FIROptionsInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 30BC39D87A2A7DB8BA697925454B1880 /* FIROptionsInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F5C8A375A5EA4F3DB076E3347DFBCB38 /* pb_encode.h in Headers */ = {isa = PBXBuildFile; fileRef = 06CB84FA5566D0EDA5C8331F13B8C392 /* pb_encode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F5EA4D5809407F18546801504152DD04 /* RNGestureHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 39B32BB5D0A26142E513079EBA428BCA /* RNGestureHandler.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F653F5E6B85800F4A5DA2D0E4C6644A2 /* FPersistentConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CF7B73F4DA5EDEF5C6A440C5FCC53DE /* FPersistentConnection.m */; }; F654A5CC4F73DFAA418D488E6B4EF7A3 /* ARTTextManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A31C1733EF0C9BB884EBE2E396FFEAF /* ARTTextManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F6667591D04F15BA939CBC05ED9361D6 /* GULUserDefaults.h in Headers */ = {isa = PBXBuildFile; fileRef = F2E40AA55A9ECB3776EB7ADA99968947 /* GULUserDefaults.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F68C38DCB827D5E869CCC4FD13FF5AD4 /* FPersistenceManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A4536262CC31CAB068E3FACD297A952 /* FPersistenceManager.m */; }; F6DE4ADCCC5ACFE73633C7E2E9E6655B /* RCTBackedTextInputDelegateAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = FE8598D360D11D081817DB736D6AD2FB /* RCTBackedTextInputDelegateAdapter.m */; }; F71ED389E46EA53386302540889C11AF /* RCTUITextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 9876A397A877B549A95586B145C9EE7D /* RCTUITextField.m */; }; - F768EB69B38FFCE90EAB313B61FF5887 /* GULMutableDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C9444A5C15DCECB1B9B6C8CCE7F58A9 /* GULMutableDictionary.m */; }; + F737EE04FE891A8FD3583A39D22EA782 /* RNCameraManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FF470BC01770DA20B58E1154277FBA /* RNCameraManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F780EB7564A8C9A8E210EFC903BBE40D /* RNCAsyncStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E74862BA95FE8275A4D8B3DCB813A9E /* RNCAsyncStorage.h */; settings = {ATTRIBUTES = (Project, ); }; }; F7933D8AF44839F0B81138EE40FAD0F7 /* RCTSurfaceSizeMeasureMode.h in Headers */ = {isa = PBXBuildFile; fileRef = A99DABEC949DF08F3FBCD984E1AB7A97 /* RCTSurfaceSizeMeasureMode.h */; settings = {ATTRIBUTES = (Project, ); }; }; F7A159610DA69D5DC091D7300A6C1F6C /* RCTMultipartStreamReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 153B1B91C237664EC2E39EE3A492FA3D /* RCTMultipartStreamReader.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + F7F7E3B897D2C6DD31D4B8034148FDFF /* FMaxNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E4789119E50F090D03CF025000A12B1 /* FMaxNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F841D05C6B81E12385B0CA91684F708A /* NSMutableDictionary+ImageMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = A72C619251A9096ADB9C7E0C7C73069B /* NSMutableDictionary+ImageMetadata.m */; }; + F847BC099683E3AB68CF0A982E2FD9BD /* port_posix.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D63F49AFC33302B0D509F2B6AC99EFD /* port_posix.h */; settings = {ATTRIBUTES = (Project, ); }; }; F86AE3E0F10057AE82ABDCBFC3268F40 /* LOTLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = BB59F911BFDED0926E861FB7D6D313D4 /* LOTLayer.m */; }; + F8863E1C92E7C0A0F25997D2B5235472 /* FValueEventRegistration.h in Headers */ = {isa = PBXBuildFile; fileRef = D90AC7BDF0B4BFB4AA7E3274289B83E7 /* FValueEventRegistration.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F88B9A9B52466333E3C24059A3C7F794 /* FAckUserWrite.h in Headers */ = {isa = PBXBuildFile; fileRef = 97386F1F30CB7CCC02F608D5C9331B09 /* FAckUserWrite.h */; settings = {ATTRIBUTES = (Project, ); }; }; F8A30EBC89CBD3EE536C2D41E1EDCFF6 /* RCTWebViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 71054E1F5B576519521100CD4493714D /* RCTWebViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; F8BE178731063C2D6B33137C34E799BD /* RCTNativeAnimatedModule.h in Headers */ = {isa = PBXBuildFile; fileRef = AE9AB4AB24FCE91AC2DB08BE8B6E5D19 /* RCTNativeAnimatedModule.h */; settings = {ATTRIBUTES = (Project, ); }; }; - F8C4219A1075AE56CFAFDA69BBAE5744 /* Demangle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B27A960FDD399A1F54CDD8A1001C653A /* Demangle.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - F92B5AD1E7A0563B3CD18C4F07C3792E /* CameraFocusSquare.m in Sources */ = {isa = PBXBuildFile; fileRef = 92B09EFD510A481A35910A0357C904D5 /* CameraFocusSquare.m */; }; + F8C4219A1075AE56CFAFDA69BBAE5744 /* Demangle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3139F2E895812FCE53080ADF53B3B0D0 /* Demangle.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; F94C59F5F54397091AF5E16CA7D12C74 /* RCTWKWebViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B480D2E46B16594B22AA5F276C772BE /* RCTWKWebViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F9CDB9DF65083CD68DD46CBD686D3AB9 /* FKeyIndex.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C5A241F21BA1B05DA1E29393CF0055D /* FKeyIndex.h */; settings = {ATTRIBUTES = (Project, ); }; }; F9E3CEDF8E80DD1C31F89FABD93D24F6 /* RCTInspectorPackagerConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 437CBC6F45F9C301B9440D883975E358 /* RCTInspectorPackagerConnection.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F9FE0A585EA917DD4387982B9DBB54FC /* snapshot.h in Headers */ = {isa = PBXBuildFile; fileRef = 47F15902BABCC392AE6231BBABBFE856 /* snapshot.h */; settings = {ATTRIBUTES = (Project, ); }; }; + FA44603A21F375502C05745A1B80D532 /* NSDictionary+FIRMessaging.h in Headers */ = {isa = PBXBuildFile; fileRef = 5154260B8F510C7AC74F8D2465CB6BC4 /* NSDictionary+FIRMessaging.h */; settings = {ATTRIBUTES = (Project, ); }; }; FA696CE0F4B39C88DD715011988FE96B /* YGNodePrint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F0A5E0C579BCF0C0D6F86FFBEE81A59B /* YGNodePrint.cpp */; settings = {COMPILER_FLAGS = "-fno-omit-frame-pointer -fexceptions -Wall -Werror -std=c++1y -fPIC -fno-objc-arc"; }; }; + FB320909B47389A2B2594129D4986015 /* FCompoundHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 12C406E967EB43474042DAEFDE88B37A /* FCompoundHash.h */; settings = {ATTRIBUTES = (Project, ); }; }; + FB655992E1C3B47CFD6FD478552CEDBC /* FParsedUrl.h in Headers */ = {isa = PBXBuildFile; fileRef = DB33FB1032597062017CC74BCA181FBC /* FParsedUrl.h */; settings = {ATTRIBUTES = (Project, ); }; }; FBC794A6E36A7E0DCF859ABFA3AF08F3 /* RCTManagedPointer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3E110645A6A25907F1D5F71BCFACD145 /* RCTManagedPointer.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - FBD357A04F657E0592174A70345E05F0 /* GPBWellKnownTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = AFF5C24E7B1C59368C5150DB1C38082E /* GPBWellKnownTypes.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; FBDDD9EFFAD56328FD70992FF59632FB /* RCTJSStackFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 16815D82AA76AD2A7707B986C1D06F78 /* RCTJSStackFrame.h */; settings = {ATTRIBUTES = (Project, ); }; }; FC1B529BCAA9CAB4C5A90756278C540A /* RCTSwitchManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 460ADA466C1DDA3792167EFC6B825121 /* RCTSwitchManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; - FC261BB17EB7C8FDBF98AB8283C8DE25 /* SpookyHashV2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4576960A63CAA9F4F93A4A177389016E /* SpookyHashV2.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + FC261BB17EB7C8FDBF98AB8283C8DE25 /* SpookyHashV2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E192A7C87BD0F2CD1AABD4BF326F5AB2 /* SpookyHashV2.cpp */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; FC6988AF69CDF4B1CBEEEB9503141855 /* RCTModalManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 7CE41CACAC85EB71E7CC555C66765840 /* RCTModalManager.m */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; FC6D2C6288D814AE17DA176DDBA8093F /* RCTProfileTrampoline-arm.S in Sources */ = {isa = PBXBuildFile; fileRef = 1ED4EF54422909B082349BEB896EAE52 /* RCTProfileTrampoline-arm.S */; }; FCBA396ACB3495482AD1EB0F7A80E818 /* RCTBackedTextInputDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = B6802A885D9F93CD0A522ED9ED5E718F /* RCTBackedTextInputDelegate.h */; settings = {ATTRIBUTES = (Project, ); }; }; FCBBF37964E5FFF8903651BF471BCD13 /* ARTSurfaceViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A64DEA330BCD99E949F44D3BDB93C2 /* ARTSurfaceViewManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; FCBFAF1C0B410E5B16FAB4484BB109A0 /* JSBundleType.h in Headers */ = {isa = PBXBuildFile; fileRef = DC4A85EB5EFD2092B7B661BADC546896 /* JSBundleType.h */; settings = {ATTRIBUTES = (Project, ); }; }; - FD12628ECD997FE99C2D5FE5EAE33D27 /* GULNetworkLoggerProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = F8E794EB8B9462A8721D684AECC475EF /* GULNetworkLoggerProtocol.h */; settings = {ATTRIBUTES = (Project, ); }; }; - FD1A3036A1977EE372FE0E6C8C5E9BB2 /* RNFetchBlob.h in Headers */ = {isa = PBXBuildFile; fileRef = C630CAE6E614C60BBC8F4EB1C693F8E2 /* RNFetchBlob.h */; settings = {ATTRIBUTES = (Project, ); }; }; + FCCA640086B52AB7992BEFCD487BC352 /* FIRDataSnapshot.m in Sources */ = {isa = PBXBuildFile; fileRef = 15EB2B211850BEB00F748CE3C6ABEDBB /* FIRDataSnapshot.m */; }; + FD01A794D75B254E830836CBEFE881B5 /* GPBRootObject_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = C416C95441AF1526F177BE7DD0EA46A1 /* GPBRootObject_PackagePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; FD29F7CC109537E8F1A37E96A0D40B09 /* RCTRootContentView.h in Headers */ = {isa = PBXBuildFile; fileRef = 53BA1C2FD0843B20B712655FA70159C5 /* RCTRootContentView.h */; settings = {ATTRIBUTES = (Project, ); }; }; FDACD8E355CBDE8EDBBB53CD940A03BC /* RCTSurfaceDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0143894FA6872B7CEDFFA128F0588D84 /* RCTSurfaceDelegate.h */; settings = {ATTRIBUTES = (Project, ); }; }; FE3B7E3B3567E8D650CE6B66D4BE2C9C /* RCTUIManagerObserverCoordinator.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0530DF33D70DCF527E71FFD8BF870CCF /* RCTUIManagerObserverCoordinator.mm */; settings = {COMPILER_FLAGS = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"; }; }; + FE7B5A18D11C99290251F9514576807C /* FIRBundleUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = B9ADE36B8790FDCE7F8382ADFE37F0AD /* FIRBundleUtil.h */; settings = {ATTRIBUTES = (Project, ); }; }; + FEE9EAEF1085DD988BEE8F4FA613E546 /* RNCSlider.h in Headers */ = {isa = PBXBuildFile; fileRef = 34BDF9CC5F54E3FC924C3B13CEF34797 /* RNCSlider.h */; settings = {ATTRIBUTES = (Project, ); }; }; FF20269A0283CE0B8BDBA6D3ED794AF4 /* RCTNativeAnimatedNodesManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB5D178A64571DC2782E0EE7028B96C /* RCTNativeAnimatedNodesManager.m */; }; - FF5EA79B055FA1C2946482473F16B254 /* FIRConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 41C13D3D29D39FB608EB5F98BEACAB05 /* FIRConfiguration.h */; settings = {ATTRIBUTES = (Project, ); }; }; FF94FB0330AA4CA3457C8F738A844BF2 /* LOTPlatformCompat.h in Headers */ = {isa = PBXBuildFile; fileRef = FA35F6CF8EAF8187EA202935419DE86C /* LOTPlatformCompat.h */; settings = {ATTRIBUTES = (Project, ); }; }; - FFEF1EF11C557EBE2D344D601B29A947 /* Timestamp.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = D3BD408FFBCEBE1D2EDAED208F372A46 /* Timestamp.pbobjc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + FFC393A865498C8967E0E42308B36FFF /* FIRAppInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = A0E18AA5B74FEBF3197D4099EE1AEA6E /* FIRAppInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; FFF659C941BD7D6BE17BD469BB7D6F9E /* ARTPattern.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD2A0A3BFD5409478E32051818235BC /* ARTPattern.h */; settings = {ATTRIBUTES = (Project, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 03178BFEA997093EF6683A1F0B4489E0 /* PBXContainerItemProxy */ = { + 044602550C428E012CD1102E24540735 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; remoteGlobalIDString = E1D8FCCB52D6F4883463C99656914BB4; remoteInfo = React; }; - 03D5E3CB146BD621410E10452AC660A3 /* PBXContainerItemProxy */ = { + 055C1FB26957C70CA930C097B9D41EE3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = A4AC528160CC8177E6EB809461379FF8; - remoteInfo = FirebaseAnalytics; + remoteGlobalIDString = 2BA894431E6D4EC9D0D3602E2A926A36; + remoteInfo = GoogleAppMeasurement; }; - 044602550C428E012CD1102E24540735 /* PBXContainerItemProxy */ = { + 0585E951434FFC03181E338F67E1BB27 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; remoteGlobalIDString = E1D8FCCB52D6F4883463C99656914BB4; remoteInfo = React; }; - 083ACD6CDB44A8A0BB6995D9477E04A3 /* PBXContainerItemProxy */ = { + 07017F15BEF5287A64F0220DB1D08954 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = F26DF4F6ADD5881D668DF81C6B3F05EF; - remoteInfo = FirebaseInstanceID; + remoteGlobalIDString = 0F9B2847C94286E2198E137459CF5903; + remoteInfo = nanopb; }; 08D7D438CB5FE26AF1B363114EF78C45 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -1174,75 +1603,75 @@ remoteGlobalIDString = 66641B93FAF80FF325B2D7B4AD85056F; remoteInfo = "boost-for-react-native"; }; - 0C19C30A67341726FDC8A88AECF61870 /* PBXContainerItemProxy */ = { + 0AE93191873C131FCFDECCFB24C30E0A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = D35E9EC86D36A4C8BC1704199FDB3552; - remoteInfo = Fabric; + remoteGlobalIDString = 8DB803987D7643D2F74BB781FE7E2C01; + remoteInfo = "react-native-slider"; }; - 0FFD040E4348A9367B8C41C80C4140A1 /* PBXContainerItemProxy */ = { + 0C988D4B370B9D18F996A66B59E257C8 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 9D25FE822A25731CE0F3D6AAA7E16E67; - remoteInfo = RNCAsyncStorage; + remoteGlobalIDString = 4C183470A0DE712E37357833C539A41C; + remoteInfo = FirebaseCore; }; - 130037C83D82796FEC7B502209D3AD18 /* PBXContainerItemProxy */ = { + 0EA6186454DFA5E5027B8AF8BF1F9158 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = F5E7779227CE35F03C5E86041DEC7C74; - remoteInfo = FirebaseABTesting; + remoteGlobalIDString = 4C183470A0DE712E37357833C539A41C; + remoteInfo = FirebaseCore; }; - 17C73FE4E8B6BD6E5847E7A65959424E /* PBXContainerItemProxy */ = { + 105672866F4BE2C08E743ABF0B2EA2FF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = F5E7779227CE35F03C5E86041DEC7C74; - remoteInfo = FirebaseABTesting; + remoteGlobalIDString = 0AC15EA33F402FC6A1A48C990993D7D8; + remoteInfo = FirebaseAnalytics; }; - 17E8F56727399A92144C65A800AA5A71 /* PBXContainerItemProxy */ = { + 13948C3EB8AC60908FC67251349170B5 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = E1CAF37843DB75E7886034596F9D9B56; - remoteInfo = glog; + remoteGlobalIDString = B449DAF8AE800FB85E1F497B65EF9956; + remoteInfo = GoogleUtilities; }; - 1B0732705F2612B6C43B690D903E86F3 /* PBXContainerItemProxy */ = { + 165A25EF313B69CF952BA037C7D1C9E7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 448819EB6C064114FE58EBAA295670B1; - remoteInfo = FirebaseCore; + remoteGlobalIDString = 2BE50E63279FC4B03758C99275E399D2; + remoteInfo = FirebaseAnalyticsInterop; }; - 1CF6CA83FC898D6768010D18C0A8B185 /* PBXContainerItemProxy */ = { + 1745ABEB8B749DCCE705B1911DD93BBA /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 66641B93FAF80FF325B2D7B4AD85056F; - remoteInfo = "boost-for-react-native"; + remoteGlobalIDString = 9E599700D610A70CDFA8E9AFF3FB9AE2; + remoteInfo = FirebasePerformance; }; - 1D160AF43C977841AA22C4ECA775CD4B /* PBXContainerItemProxy */ = { + 1CF6CA83FC898D6768010D18C0A8B185 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 5E317F794B07662C390113F089191B83; - remoteInfo = "lottie-react-native"; + remoteGlobalIDString = 66641B93FAF80FF325B2D7B4AD85056F; + remoteInfo = "boost-for-react-native"; }; - 1E668B13ED97F5CA52280B48B5E94354 /* PBXContainerItemProxy */ = { + 20C21CB204BC6F34F59DEA695BA4FDD3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 1656132E72FE6E162694B82A10950197; - remoteInfo = RNVectorIcons; + remoteGlobalIDString = 9164D8092E2D2FC2BAD1ABCC34521490; + remoteInfo = FirebaseAuthInterop; }; - 1EA7D88F1824DFB2E1C778747C76AB39 /* PBXContainerItemProxy */ = { + 25350512A99EBD12FAAD0B86950275DD /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 2CA9E9CBD6D1591F4833D0AC9A6DE30D; - remoteInfo = GoogleSignIn; + remoteGlobalIDString = 0B288C19EF7E9BFFBF358F352E60AA3D; + remoteInfo = GoogleToolboxForMac; }; 264DBD7ADF27047E9845798B1FC67AF5 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -1251,26 +1680,40 @@ remoteGlobalIDString = A6EE5F943783158E6136A310CB61F189; remoteInfo = DoubleConversion; }; - 2A6C25E5EC6A66217F4B8F9380C6FF5A /* PBXContainerItemProxy */ = { + 277B32B0B18E28E771FFC53F22F940B6 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 448819EB6C064114FE58EBAA295670B1; - remoteInfo = FirebaseCore; + remoteGlobalIDString = E1D8FCCB52D6F4883463C99656914BB4; + remoteInfo = React; }; - 2D67EFBDD17B1FADDB737E05E9F08137 /* PBXContainerItemProxy */ = { + 2BDA79177A79D620F28693878E51BCEC /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = A341D07F993BE980A2F73FF26D003F2F; - remoteInfo = Firebase; + remoteGlobalIDString = 16BE0913B925E13F023F8ACADD6AEDAC; + remoteInfo = BVLinearGradient; }; - 33C2E9A5FD7CA642BCDC3B7E5B5B2C05 /* PBXContainerItemProxy */ = { + 2C7A6F7FA845FF36E2D4F09878002334 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 0281128B8C9A5F3BC2777ABCC1353408; - remoteInfo = "react-native-camera"; + remoteGlobalIDString = 7DB3B0B9490B6AF4860CC9317D5F5C54; + remoteInfo = FirebaseInstanceID; + }; + 2CB55291D9E244FAC3981CDE051836A7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4C183470A0DE712E37357833C539A41C; + remoteInfo = FirebaseCore; + }; + 2DFA37430FA4B98814AAE23106AB9BEA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B449DAF8AE800FB85E1F497B65EF9956; + remoteInfo = GoogleUtilities; }; 347F2576FE3031D88315EF798753AC13 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -1279,110 +1722,110 @@ remoteGlobalIDString = 899724123EE938F93E535EDDF3D69EDA; remoteInfo = Folly; }; - 36EB2D50CB8FC52A4D7016F523619A3B /* PBXContainerItemProxy */ = { + 34BDF333136B127463B035B6266E61B1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = E1D8FCCB52D6F4883463C99656914BB4; - remoteInfo = React; + remoteGlobalIDString = DF4F838E6093604EE864818A37DBF3E2; + remoteInfo = "leveldb-library"; }; - 37FE4FF1FB3FB531FD2536A2321755CE /* PBXContainerItemProxy */ = { + 353531F726EAB4EFB434186CC08E61A5 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = A6EE5F943783158E6136A310CB61F189; - remoteInfo = DoubleConversion; + remoteGlobalIDString = 4C183470A0DE712E37357833C539A41C; + remoteInfo = FirebaseCore; }; - 3933BD09AE3A3D8E4918A22DBE146167 /* PBXContainerItemProxy */ = { + 37FE4FF1FB3FB531FD2536A2321755CE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 26ECD05F13D8FDDE98B912F8EAD399E8; - remoteInfo = FirebaseRemoteConfig; + remoteGlobalIDString = A6EE5F943783158E6136A310CB61F189; + remoteInfo = DoubleConversion; }; - 3A9C14C65AC309186E3E9FB96ED3BFA1 /* PBXContainerItemProxy */ = { + 3D52552F79E8F53183A7115F981A71C2 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 448819EB6C064114FE58EBAA295670B1; - remoteInfo = FirebaseCore; + remoteGlobalIDString = 2BE50E63279FC4B03758C99275E399D2; + remoteInfo = FirebaseAnalyticsInterop; }; - 406AC04BFBFE5DC8409426C754DF411F /* PBXContainerItemProxy */ = { + 41456A458556CEFE7530210D328851EE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = F26DF4F6ADD5881D668DF81C6B3F05EF; - remoteInfo = FirebaseInstanceID; + remoteGlobalIDString = E1D8FCCB52D6F4883463C99656914BB4; + remoteInfo = React; }; - 433ED0A60CD58BAE5D57832B60665C9A /* PBXContainerItemProxy */ = { + 41BAAE91BE6D177A15C1545315E52B33 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = F26DF4F6ADD5881D668DF81C6B3F05EF; + remoteGlobalIDString = 7DB3B0B9490B6AF4860CC9317D5F5C54; remoteInfo = FirebaseInstanceID; }; - 466B6C3BD3C763937C115EE92E0E9DED /* PBXContainerItemProxy */ = { + 4C7FE07ECC19AC40C456FAD1306F59EA /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = F63F26AAC9E12A1E6BDEECB1B662C7E6; - remoteInfo = GoogleAppMeasurement; + remoteGlobalIDString = B449DAF8AE800FB85E1F497B65EF9956; + remoteInfo = GoogleUtilities; }; - 468A9E61876A12241830676FABE908E1 /* PBXContainerItemProxy */ = { + 4D7F7F984C1BCFF55C72425264358F9B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = E1D8FCCB52D6F4883463C99656914BB4; - remoteInfo = React; + remoteGlobalIDString = ABA9A411BB5A359862E5F1AA6238278E; + remoteInfo = Crashlytics; }; - 491B427B0E9462E6841599CDDE61CE71 /* PBXContainerItemProxy */ = { + 5154F08CEE977135381277107A14A431 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 899724123EE938F93E535EDDF3D69EDA; - remoteInfo = Folly; + remoteGlobalIDString = 78D21D148001007DE3F837778E7D27F5; + remoteInfo = FirebaseRemoteConfig; }; - 4B1162F8422C723A2AB51B19650CC967 /* PBXContainerItemProxy */ = { + 53275EEEA94F3F2DEABA5FEE4B8FF2F8 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 11C54F681447111DE53C634CEDA6439B; - remoteInfo = "react-native-slider"; + remoteGlobalIDString = 4C183470A0DE712E37357833C539A41C; + remoteInfo = FirebaseCore; }; - 53E90F5BF12E0D9B1CD507CD4C8AA991 /* PBXContainerItemProxy */ = { + 568AC389DEC1796DEC8D21794CE0B6A2 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = E1D8FCCB52D6F4883463C99656914BB4; - remoteInfo = React; + remoteGlobalIDString = 5E317F794B07662C390113F089191B83; + remoteInfo = "lottie-react-native"; }; - 5DF7529822BF64C712E80096320C508A /* PBXContainerItemProxy */ = { + 5C054B6E63DB8C7406BB0DC63B2A0FF9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 35B0CD518EC8B839AD44597B2B183B62; - remoteInfo = nanopb; + remoteGlobalIDString = 572A5F97CA1814DB67594FEEAA9160A1; + remoteInfo = RNVectorIcons; }; - 605B9F86A653094A9E5C304397430D79 /* PBXContainerItemProxy */ = { + 5EF202B03DCCB385135B63BBD81BBE12 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = AA035077852F44007A1367BB990F195D; - remoteInfo = GoogleToolboxForMac; + remoteGlobalIDString = 7DB3B0B9490B6AF4860CC9317D5F5C54; + remoteInfo = FirebaseInstanceID; }; - 660BBEBA587B135B30F122350115F0DF /* PBXContainerItemProxy */ = { + 6641473F1758E11ECBE1EFDA32BF7355 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = A6EE5F943783158E6136A310CB61F189; - remoteInfo = DoubleConversion; + remoteGlobalIDString = 9164D8092E2D2FC2BAD1ABCC34521490; + remoteInfo = FirebaseAuthInterop; }; - 66296FA0C38BDDDA7FD308D9DCAA11E6 /* PBXContainerItemProxy */ = { + 691F71A405EE1F7527D0A12641C94F14 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = E1D8FCCB52D6F4883463C99656914BB4; - remoteInfo = React; + remoteGlobalIDString = 9EAC38454747EC28EBFCFAA0097CC2F5; + remoteInfo = RNCAsyncStorage; }; 6AF073F59FA5E3F83B9934D0E8BDE172 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -1391,12 +1834,19 @@ remoteGlobalIDString = E1CAF37843DB75E7886034596F9D9B56; remoteInfo = glog; }; - 6D2DAC509EA697FC7FC081C1CDCE5241 /* PBXContainerItemProxy */ = { + 6D38434C8B9B43CA8CF820D4829DD161 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 072080E8F57A5E595567C4EA8DA532F2; - remoteInfo = RNGestureHandler; + remoteGlobalIDString = 23DF0A63500D3BD8E8BA84CFC260F48A; + remoteInfo = FirebaseDatabase; + }; + 6D851FE011D10C8DC13C23DCA712B3CE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B449DAF8AE800FB85E1F497B65EF9956; + remoteInfo = GoogleUtilities; }; 6DB229A00820B6D3849F4BD0B789EE4C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -1405,19 +1855,26 @@ remoteGlobalIDString = E1D8FCCB52D6F4883463C99656914BB4; remoteInfo = React; }; - 6DC6454253B7115CB20E3B067A06A7DF /* PBXContainerItemProxy */ = { + 6E0044A1C82B1DAEDAB14444DC3748A1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = A3197AFE21F0131BE3A6A49782BC6F1D; - remoteInfo = FirebasePerformance; + remoteGlobalIDString = DF4F838E6093604EE864818A37DBF3E2; + remoteInfo = "leveldb-library"; }; - 6DE73E05262B43D4DCF9ACE46B77089F /* PBXContainerItemProxy */ = { + 7394770E6EC356D91E8F2550BE99D7A4 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 9E5688F66E67822336D226F99E7A6588; - remoteInfo = Protobuf; + remoteGlobalIDString = 0F9B2847C94286E2198E137459CF5903; + remoteInfo = nanopb; + }; + 74F344B729185361C75D88CBF1E5070A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 34D4E730D4CC6DE5A7BD20268CD434E5; + remoteInfo = RNGestureHandler; }; 76490FC12387367CEE6489B60FD95F73 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -1426,403 +1883,524 @@ remoteGlobalIDString = 33E77AA8166EA35F2575BF105C979D6A; remoteInfo = "lottie-ios"; }; - 78355AC4ACD19F1D8F358A906EC4A269 /* PBXContainerItemProxy */ = { + 76BB597CC859CD009E81DCA8DA6A4912 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = A4AC528160CC8177E6EB809461379FF8; - remoteInfo = FirebaseAnalytics; + remoteGlobalIDString = E1D8FCCB52D6F4883463C99656914BB4; + remoteInfo = React; }; - 7AB389380B6FD143D6DCA47C8D4464E3 /* PBXContainerItemProxy */ = { + 76BEF71A2C91FF8730DC067162C9463D /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 2A9CA5658E5FDBBD07A7FFEA95C4ECFA; - remoteInfo = GTMSessionFetcher; + remoteGlobalIDString = E1D8FCCB52D6F4883463C99656914BB4; + remoteInfo = React; }; - 816C88F7B2DBB1FBDE117DB14A78222A /* PBXContainerItemProxy */ = { + 76D0E1B98484EEC5D1E736A8E39720AB /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 35B0CD518EC8B839AD44597B2B183B62; - remoteInfo = nanopb; + remoteGlobalIDString = BCE30BBC689F944FE7A82C1512D6FFA1; + remoteInfo = FirebaseABTesting; }; - 818964BAD6E300D1928522854B05E2BA /* PBXContainerItemProxy */ = { + 790ADA83043201CD8786361319432367 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = BEFDC8279895EA5EC1BF281D21F9B15D; - remoteInfo = GoogleUtilities; + remoteGlobalIDString = A835F24A9AD839C08095DBDAC0B40225; + remoteInfo = GTMSessionFetcher; }; - 826DA3990E71645209FE690B16191537 /* PBXContainerItemProxy */ = { + 7EA62A5A8126CBAA21D5D9897108B454 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 33E77AA8166EA35F2575BF105C979D6A; - remoteInfo = "lottie-ios"; + remoteGlobalIDString = 22BEF3F4E553CFCB4173F8D80CE8E88C; + remoteInfo = Protobuf; }; - 88159EC956417A114FD2E5C69A232CD3 /* PBXContainerItemProxy */ = { + 81B2C1B5643D1AF65DDF39A9C4644527 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = BEFDC8279895EA5EC1BF281D21F9B15D; - remoteInfo = GoogleUtilities; + remoteGlobalIDString = BBA2DD90CC21A6145F49BEF817D76438; + remoteInfo = yoga; }; - 8ACD8D635C06DACAAF5B5BBA0DDFC7DE /* PBXContainerItemProxy */ = { + 8241BAF8CFAD0F9034A2316EB7F1D844 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = BEFDC8279895EA5EC1BF281D21F9B15D; - remoteInfo = GoogleUtilities; + remoteGlobalIDString = 22BEF3F4E553CFCB4173F8D80CE8E88C; + remoteInfo = Protobuf; }; - 99A703C5BD2B30D15952CE937D2B7C0D /* PBXContainerItemProxy */ = { + 827204C17F33E1EA71E4F9C489B27CF1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = BEFDC8279895EA5EC1BF281D21F9B15D; - remoteInfo = GoogleUtilities; + remoteGlobalIDString = 7DB3B0B9490B6AF4860CC9317D5F5C54; + remoteInfo = FirebaseInstanceID; }; - 9C46503EC73E87E9773BBD6B7ACB19C0 /* PBXContainerItemProxy */ = { + 844D5C03EA44D954C33C790B98425EB9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 47492BF4D2C397E56EAAD1B6A3C49548; - remoteInfo = "Pods-Kalend"; + remoteGlobalIDString = 78D21D148001007DE3F837778E7D27F5; + remoteInfo = FirebaseRemoteConfig; }; - A052B7AAA361846460EF3396A294ED49 /* PBXContainerItemProxy */ = { + 8713547E4836EADCC4C633085992190E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = A4AC528160CC8177E6EB809461379FF8; - remoteInfo = FirebaseAnalytics; + remoteGlobalIDString = 2CA9E9CBD6D1591F4833D0AC9A6DE30D; + remoteInfo = GoogleSignIn; }; - A15B8D564CE1D122E7F75F5CF79C3184 /* PBXContainerItemProxy */ = { + 8765D467BAD6C49485EA8D888D4E9C08 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = ABA9A411BB5A359862E5F1AA6238278E; - remoteInfo = Crashlytics; + remoteGlobalIDString = 0AC15EA33F402FC6A1A48C990993D7D8; + remoteInfo = FirebaseAnalytics; }; - A39860F8EFD4538E4290A8E9DA7C63B2 /* PBXContainerItemProxy */ = { + 88AA8DDE8001850D5953E8EF71ABBBC3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = AA035077852F44007A1367BB990F195D; - remoteInfo = GoogleToolboxForMac; + remoteGlobalIDString = 0F9B2847C94286E2198E137459CF5903; + remoteInfo = nanopb; }; - A3A95A9578626A027F5662EFCC2E486F /* PBXContainerItemProxy */ = { + 8BA048E635A439A19CB234A359078FCD /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 26ECD05F13D8FDDE98B912F8EAD399E8; + remoteGlobalIDString = 78D21D148001007DE3F837778E7D27F5; remoteInfo = FirebaseRemoteConfig; }; - A4900E29090911B6944C226B269ADDF8 /* PBXContainerItemProxy */ = { + 8D10AFDEC6EA21B8990577A1870F8861 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 6946D4B5CA576A1782B086978B485908; - remoteInfo = "react-native-safari-view"; + remoteGlobalIDString = B449DAF8AE800FB85E1F497B65EF9956; + remoteInfo = GoogleUtilities; }; - A772DB2DEF1D9E4FEBAC83250262F500 /* PBXContainerItemProxy */ = { + 8EE00F482AD1A928EF29121006965526 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 2A9CA5658E5FDBBD07A7FFEA95C4ECFA; - remoteInfo = GTMSessionFetcher; + remoteGlobalIDString = 9E599700D610A70CDFA8E9AFF3FB9AE2; + remoteInfo = FirebasePerformance; }; - A9D6DC9CB40E4423C1BA75D2D9087468 /* PBXContainerItemProxy */ = { + 9599F034C4508616A585749184CDF334 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 66641B93FAF80FF325B2D7B4AD85056F; - remoteInfo = "boost-for-react-native"; + remoteGlobalIDString = 4348A814F8FBD3A06D1844F43CF5619D; + remoteInfo = FirebaseMessaging; }; - AA327200248DBFB36D2BBAC897CD5EB7 /* PBXContainerItemProxy */ = { + 9C46503EC73E87E9773BBD6B7ACB19C0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = BEFDC8279895EA5EC1BF281D21F9B15D; - remoteInfo = GoogleUtilities; + remoteGlobalIDString = D8CB9CF69BB52ED6D1A37B51EA54DD5F; + remoteInfo = "Pods-Kalend"; }; - AC5C963A5150C27B599306AA6F50DE00 /* PBXContainerItemProxy */ = { + 9D2A92143EC3DE18CEA858F2334A0DB3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = E1CAF37843DB75E7886034596F9D9B56; - remoteInfo = glog; + remoteGlobalIDString = 22BEF3F4E553CFCB4173F8D80CE8E88C; + remoteInfo = Protobuf; }; - AC7ACBEA5D5B57764908B4BD9B0B3180 /* PBXContainerItemProxy */ = { + A103EDE456171AC421F0ADC6CBFB1A82 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = BBA0C24EDB3A4C12E5E9947993A25BDD; - remoteInfo = "rn-fetch-blob"; + remoteGlobalIDString = 23DF0A63500D3BD8E8BA84CFC260F48A; + remoteInfo = FirebaseDatabase; }; - B1CB420F6321BE59C47DA8AE0AEC62E4 /* PBXContainerItemProxy */ = { + A280861F2EB31AC1BD60B7F1814EEB08 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = E1D8FCCB52D6F4883463C99656914BB4; - remoteInfo = React; + remoteGlobalIDString = 4C183470A0DE712E37357833C539A41C; + remoteInfo = FirebaseCore; }; - B4170BF0300D596478CC9CAF274B7460 /* PBXContainerItemProxy */ = { + A35F81AB62A9B0B51D7771047A5A9363 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = AA035077852F44007A1367BB990F195D; - remoteInfo = GoogleToolboxForMac; + remoteGlobalIDString = 2BA894431E6D4EC9D0D3602E2A926A36; + remoteInfo = GoogleAppMeasurement; }; - B6AF5AC3E4EE099766D01F858F53CC89 /* PBXContainerItemProxy */ = { + A39860F8EFD4538E4290A8E9DA7C63B2 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 2A9CA5658E5FDBBD07A7FFEA95C4ECFA; - remoteInfo = GTMSessionFetcher; + remoteGlobalIDString = 0B288C19EF7E9BFFBF358F352E60AA3D; + remoteInfo = GoogleToolboxForMac; }; - B6FDA52C375C94B67C0F2A61AA2B1C1B /* PBXContainerItemProxy */ = { + A772DB2DEF1D9E4FEBAC83250262F500 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 448819EB6C064114FE58EBAA295670B1; - remoteInfo = FirebaseCore; + remoteGlobalIDString = A835F24A9AD839C08095DBDAC0B40225; + remoteInfo = GTMSessionFetcher; }; - B9435ED0F4941F85D0F89E9FA70F0E56 /* PBXContainerItemProxy */ = { + A8DD62FFD9EC22FD928DAF7B7E4AA3CF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 35B0CD518EC8B839AD44597B2B183B62; - remoteInfo = nanopb; + remoteGlobalIDString = B449DAF8AE800FB85E1F497B65EF9956; + remoteInfo = GoogleUtilities; }; - C79749E337C3DB9C667C1BB8C74B0C9D /* PBXContainerItemProxy */ = { + A9F12D1969C28AE3BB2CED3522E7BF3E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 26ECD05F13D8FDDE98B912F8EAD399E8; - remoteInfo = FirebaseRemoteConfig; + remoteGlobalIDString = 0E35C59D1F9DC4D53C36F02E9F5228F4; + remoteInfo = "react-native-safari-view"; }; - CBEAC6A9CFAD96974D677995381B9461 /* PBXContainerItemProxy */ = { + AC5C963A5150C27B599306AA6F50DE00 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 448819EB6C064114FE58EBAA295670B1; - remoteInfo = FirebaseCore; + remoteGlobalIDString = E1CAF37843DB75E7886034596F9D9B56; + remoteInfo = glog; }; - CCA6A46CB98EDCA8F0A484DEE349AA32 /* PBXContainerItemProxy */ = { + B20F5FB559C22D0844CF50F8428FD90B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = BBA2DD90CC21A6145F49BEF817D76438; - remoteInfo = yoga; + remoteGlobalIDString = 7DB3B0B9490B6AF4860CC9317D5F5C54; + remoteInfo = FirebaseInstanceID; }; - D465047540D12FD9D95291AE82A76DB9 /* PBXContainerItemProxy */ = { + BE4B618EA1C87B7407F38EB80CF67CCF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = D35E9EC86D36A4C8BC1704199FDB3552; - remoteInfo = Fabric; + remoteGlobalIDString = 0AC15EA33F402FC6A1A48C990993D7D8; + remoteInfo = FirebaseAnalytics; }; - DBDB4F15B5722CEE3B0183B8A512781C /* PBXContainerItemProxy */ = { + C317B92D6552153355138B8AF7A0DF82 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 9E5688F66E67822336D226F99E7A6588; - remoteInfo = Protobuf; + remoteGlobalIDString = 899724123EE938F93E535EDDF3D69EDA; + remoteInfo = Folly; }; - DD71FE4534A57A8FE6BD5CA10318595A /* PBXContainerItemProxy */ = { + C331DDFF297305849D76D8DBBC13947B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = F26DF4F6ADD5881D668DF81C6B3F05EF; - remoteInfo = FirebaseInstanceID; + remoteGlobalIDString = E1D8FCCB52D6F4883463C99656914BB4; + remoteInfo = React; }; - DE54543D5D61745702021E54EBEFA04F /* PBXContainerItemProxy */ = { + C800E1037DCCBF7A279FB4F5FEC0C584 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = BEFDC8279895EA5EC1BF281D21F9B15D; - remoteInfo = GoogleUtilities; + remoteGlobalIDString = 0B288C19EF7E9BFFBF358F352E60AA3D; + remoteInfo = GoogleToolboxForMac; }; - E46901E90592D634469CE4DCE7EA38BE /* PBXContainerItemProxy */ = { + D0F255E8A4D8412D21C13E4DCF0DFC96 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = A3197AFE21F0131BE3A6A49782BC6F1D; - remoteInfo = FirebasePerformance; + remoteGlobalIDString = 22BEF3F4E553CFCB4173F8D80CE8E88C; + remoteInfo = Protobuf; }; - E6F2C90842B0E24138D6E9E4F212A067 /* PBXContainerItemProxy */ = { + D3C9E32A012D1584F9F28FEF5D925D82 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 448819EB6C064114FE58EBAA295670B1; + remoteGlobalIDString = 4C183470A0DE712E37357833C539A41C; remoteInfo = FirebaseCore; }; - E7FE9CA07606EEEC87598BAAC48A9DCA /* PBXContainerItemProxy */ = { + D460425A16079DEA23274B84CC308912 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = BEFDC8279895EA5EC1BF281D21F9B15D; - remoteInfo = GoogleUtilities; + remoteGlobalIDString = 38E5CE2978C5F628FBD76567E1CC36FC; + remoteInfo = "react-native-camera"; }; - EBE5C2359D0F5353B72AAA258DABC84E /* PBXContainerItemProxy */ = { + D465047540D12FD9D95291AE82A76DB9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = F63F26AAC9E12A1E6BDEECB1B662C7E6; - remoteInfo = GoogleAppMeasurement; + remoteGlobalIDString = D35E9EC86D36A4C8BC1704199FDB3552; + remoteInfo = Fabric; }; - EDD184E7F5C5EB03336DC93FFFC07E97 /* PBXContainerItemProxy */ = { + DF97121A39547E4458BA4B8E63916D6E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = BBA2DD90CC21A6145F49BEF817D76438; - remoteInfo = yoga; + remoteGlobalIDString = 22BEF3F4E553CFCB4173F8D80CE8E88C; + remoteInfo = Protobuf; }; - EE139BB473D40617D332ADD9FFC051B9 /* PBXContainerItemProxy */ = { + DFC815EDB5C8E218FBD16DFFF5AB10BE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 9E5688F66E67822336D226F99E7A6588; - remoteInfo = Protobuf; + remoteGlobalIDString = E1D8FCCB52D6F4883463C99656914BB4; + remoteInfo = React; }; - EFAEDD1B332C752B8B578E55C9FF95BC /* PBXContainerItemProxy */ = { + E3D44E4B82DCD0F3C07363AA86CB4571 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = A4AC528160CC8177E6EB809461379FF8; - remoteInfo = FirebaseAnalytics; + remoteGlobalIDString = D35E9EC86D36A4C8BC1704199FDB3552; + remoteInfo = Fabric; }; - F188D5B9F9F22193AB2864E950B50A71 /* PBXContainerItemProxy */ = { + E42A1937BD55510C716F6E73DE9F135F /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; remoteGlobalIDString = E1D8FCCB52D6F4883463C99656914BB4; remoteInfo = React; }; - F56F3FB2D25DD598B6ABCA66B20A7D10 /* PBXContainerItemProxy */ = { + E717E1A20DBCA413E36929D674F5448B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 16BE0913B925E13F023F8ACADD6AEDAC; - remoteInfo = BVLinearGradient; + remoteGlobalIDString = E6A6F5DA5057B74455DEBDE8988C3E7D; + remoteInfo = "rn-fetch-blob"; }; - FB757F113AD3C74F087AD99F4E48C760 /* PBXContainerItemProxy */ = { + ECB9F2E200E36C504BA8C8ADD7A94736 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 9E5688F66E67822336D226F99E7A6588; - remoteInfo = Protobuf; + remoteGlobalIDString = 148A5443E43AD92241F7EC3C3A5FAF3B; + remoteInfo = Firebase; }; - FC8F0DABC455CC75718B2F6C5E985CAA /* PBXContainerItemProxy */ = { + EDD184E7F5C5EB03336DC93FFFC07E97 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = E1D8FCCB52D6F4883463C99656914BB4; - remoteInfo = React; + remoteGlobalIDString = BBA2DD90CC21A6145F49BEF817D76438; + remoteInfo = yoga; + }; + EDD7B4B2478984DB8F9E2FF46E86B9CD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4348A814F8FBD3A06D1844F43CF5619D; + remoteInfo = FirebaseMessaging; + }; + F16DA88CE2793B109BD5C1BD9F588A80 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = A835F24A9AD839C08095DBDAC0B40225; + remoteInfo = GTMSessionFetcher; + }; + F194DACC558D5F8744F6392FD9AEB0C6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 0AC15EA33F402FC6A1A48C990993D7D8; + remoteInfo = FirebaseAnalytics; + }; + F3B12138923C78DD9F126326957A4D7B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = BCE30BBC689F944FE7A82C1512D6FFA1; + remoteInfo = FirebaseABTesting; + }; + F49E7C9600A0E0D36A5F24FF3912CE94 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B449DAF8AE800FB85E1F497B65EF9956; + remoteInfo = GoogleUtilities; + }; + FB47DA304027652B64AE4ED424B9B971 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33E77AA8166EA35F2575BF105C979D6A; + remoteInfo = "lottie-ios"; + }; + FC7EB13854E58E008EA61CDA1D853AE6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B449DAF8AE800FB85E1F497B65EF9956; + remoteInfo = GoogleUtilities; + }; + FCADA1C246D524281444B9BAE6836669 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4C183470A0DE712E37357833C539A41C; + remoteInfo = FirebaseCore; + }; + FD09B23FE363D8D94566CE666E63A6F7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E1CAF37843DB75E7886034596F9D9B56; + remoteInfo = glog; + }; + FD8BC0BFAAA43ED5D4F3408AE35CD20F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 66641B93FAF80FF325B2D7B4AD85056F; + remoteInfo = "boost-for-react-native"; + }; + FEA94A49C8485B2CD96D45C08DA6EA81 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = A6EE5F943783158E6136A310CB61F189; + remoteInfo = DoubleConversion; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ 00066D035794B7A884D691A75B2B3916 /* React.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = React.xcconfig; sourceTree = ""; }; + 0079273BFA178FC1D3EB5A83E2E021CE /* double-conversion.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = "double-conversion.cc"; path = "double-conversion/double-conversion.cc"; sourceTree = ""; }; + 007D6D8738E909C6CF0320FF9CE52D28 /* fast-dtoa.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "fast-dtoa.h"; path = "double-conversion/fast-dtoa.h"; sourceTree = ""; }; + 0091745266BB0CA502AFA0EEE4BC1F65 /* demangle.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = demangle.cc; path = src/demangle.cc; sourceTree = ""; }; + 00BE88F25DC58F3A5C0BCEB71B025B97 /* FImmutableTree.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FImmutableTree.m; path = Firebase/Database/Core/Utilities/FImmutableTree.m; sourceTree = ""; }; 00C8F011D8EFC7ADAC8D4F7DCFA6C67B /* RCTInterpolationAnimatedNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTInterpolationAnimatedNode.h; sourceTree = ""; }; 00DD70332EF9B678EB55555BD8E5EC43 /* LOTMaskContainer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTMaskContainer.h; sourceTree = ""; }; 00F5A6FE3E4851D6A2E58851F7E0A1F2 /* RCTConvert+Text.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "RCTConvert+Text.m"; path = "Libraries/Text/RCTConvert+Text.m"; sourceTree = ""; }; + 010593F7E979CEFE100326A954A7ADA3 /* FIRMessagingRemoteNotificationsProxy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingRemoteNotificationsProxy.h; path = Firebase/Messaging/FIRMessagingRemoteNotificationsProxy.h; sourceTree = ""; }; 011B470F82E83CFB2344AE6FD57FA8C8 /* RCTNativeAnimatedModule.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTNativeAnimatedModule.m; path = Libraries/NativeAnimation/RCTNativeAnimatedModule.m; sourceTree = ""; }; - 013E70C5F49F92AA2533BE9D5B83A65D /* signalhandler.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = signalhandler.cc; path = src/signalhandler.cc; sourceTree = ""; }; 0143894FA6872B7CEDFFA128F0588D84 /* RCTSurfaceDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSurfaceDelegate.h; sourceTree = ""; }; 01492C4D83A3EE634C07FEE211CF13D0 /* RCTSafeAreaViewManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSafeAreaViewManager.h; sourceTree = ""; }; 015548AD477FAF4C212214E3B96D7A3C /* LOTAnimatedSwitch.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTAnimatedSwitch.m; sourceTree = ""; }; 015C8546B0320ACF5B29CD7BE84521F3 /* ARTText.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = ARTText.m; path = Libraries/ART/ARTText.m; sourceTree = ""; }; - 018DA0CED90F3227330B1E4C36E30D39 /* GPBExtensionRegistry.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBExtensionRegistry.m; path = objectivec/GPBExtensionRegistry.m; sourceTree = ""; }; 01929951D5F7706DB8E73E00B1CA5F37 /* UIColor+Expanded.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "UIColor+Expanded.h"; sourceTree = ""; }; 01AE5F9E13FECB830F19C1C5CF8C3568 /* RCTFPSGraph.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTFPSGraph.m; sourceTree = ""; }; + 01B3017DFB14AAC889D13223520F8A82 /* FIRDatabase_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDatabase_Private.h; path = Firebase/Database/Api/Private/FIRDatabase_Private.h; sourceTree = ""; }; 01C890CACD06B7B63E14638617083B9C /* BVLinearGradientManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = BVLinearGradientManager.m; path = BVLinearGradient/BVLinearGradientManager.m; sourceTree = ""; }; + 01EFAC98986CB6F1033BA70216B2A359 /* env_posix.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = env_posix.cc; path = util/env_posix.cc; sourceTree = ""; }; 02164749E0FF8E59CB81D19A4E8F959A /* RNFetchBlobReqBuilder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNFetchBlobReqBuilder.m; path = ios/RNFetchBlobReqBuilder.m; sourceTree = ""; }; + 02282D73DD284911333138BCA9E63E33 /* FTree.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FTree.m; path = Firebase/Database/Core/Utilities/FTree.m; sourceTree = ""; }; 0238219549B56954B2991D3B7FC8B44F /* RCTDeviceInfo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTDeviceInfo.h; sourceTree = ""; }; - 02D4C7FEC7F4BD8E48C873E644DC9D4A /* GTMSessionFetcherLogging.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTMSessionFetcherLogging.m; path = Source/GTMSessionFetcherLogging.m; sourceTree = ""; }; + 028C667A4E60B8920C74DACF0139CC88 /* Api.pbobjc.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = Api.pbobjc.m; path = objectivec/google/protobuf/Api.pbobjc.m; sourceTree = ""; }; + 02A7AC7B71A07E26F7AC8D4CBF4EC17F /* GPBMessage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBMessage.h; path = objectivec/GPBMessage.h; sourceTree = ""; }; 03134ABA53AC736F9AC253EEC0A88AAB /* RNFetchBlob.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RNFetchBlob.m; sourceTree = ""; }; + 03168B5FD0FDF3BC03988D170627C222 /* FIRErrors.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRErrors.h; path = Firebase/Core/Private/FIRErrors.h; sourceTree = ""; }; 03229B7D127C72D69A776B71BFA2B094 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; }; + 0356BDAEC5808155DFE77028C5997175 /* FIRComponentType.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRComponentType.m; path = Firebase/Core/FIRComponentType.m; sourceTree = ""; }; 035893E648E8D4E1390D074DE46E9DF5 /* RCTURLRequestHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTURLRequestHandler.h; sourceTree = ""; }; - 03652FC81BBDDC08F924DD4287DCFEC6 /* Duration.pbobjc.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Duration.pbobjc.h; path = objectivec/google/protobuf/Duration.pbobjc.h; sourceTree = ""; }; + 03C7DC736195B2F84AB92FD41F745685 /* FIRMessagingAnalytics.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingAnalytics.m; path = Firebase/Messaging/FIRMessagingAnalytics.m; sourceTree = ""; }; 03E6E83A0ACA743E9FB4084F3B63F9B0 /* RCTDiffClampAnimatedNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTDiffClampAnimatedNode.m; sourceTree = ""; }; 03F7F96614223367ED6CAB4C3E8DC736 /* RCTSafeAreaViewManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTSafeAreaViewManager.m; sourceTree = ""; }; + 04050B383E0D612ACABF04B122699C1B /* libPods-KalendTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libPods-KalendTests.a"; path = "libPods-KalendTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 0416AA6600923BDD6D86D764FF7245BD /* RNFetchBlobFS.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNFetchBlobFS.h; path = ios/RNFetchBlobFS.h; sourceTree = ""; }; 043F58F0BC6657E6FFD848D846718A8D /* RCTModuloAnimatedNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTModuloAnimatedNode.h; sourceTree = ""; }; + 0443112F2C0662B91042E0AEBB57DC06 /* FTupleTSN.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FTupleTSN.m; path = Firebase/Database/Utilities/Tuples/FTupleTSN.m; sourceTree = ""; }; 0458D0A7DAA406B4565D450B7D6B7545 /* RNGestureHandler-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "RNGestureHandler-dummy.m"; sourceTree = ""; }; - 045BD9EED41E317E0FD863E5D64EA5B7 /* FieldMask.pbobjc.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FieldMask.pbobjc.m; path = objectivec/google/protobuf/FieldMask.pbobjc.m; sourceTree = ""; }; 0479ECCB459541332FD74AE6FF8170CD /* RCTObjcExecutor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTObjcExecutor.h; sourceTree = ""; }; 04F2354933A13E2ECDA8A2D23E6528BA /* GLOSSARY.md */ = {isa = PBXFileReference; includeInIndex = 1; name = GLOSSARY.md; path = docs/GLOSSARY.md; sourceTree = ""; }; + 050407348E20AAECDC9692CA87B3CD6C /* FRangeMerge.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FRangeMerge.h; path = Firebase/Database/Core/FRangeMerge.h; sourceTree = ""; }; 051B8725AFBE993F63BF537AF698E39C /* RCTAccessibilityManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTAccessibilityManager.m; sourceTree = ""; }; + 0522DE22463906DA220EC22B9CDB8B94 /* GtalkCore.pbobjc.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GtalkCore.pbobjc.m; path = Firebase/Messaging/Protos/GtalkCore.pbobjc.m; sourceTree = ""; }; + 05287BC664B5445346A8EF5DCADB1246 /* boost-for-react-native.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "boost-for-react-native.xcconfig"; sourceTree = ""; }; 0530DF33D70DCF527E71FFD8BF870CCF /* RCTUIManagerObserverCoordinator.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTUIManagerObserverCoordinator.mm; sourceTree = ""; }; + 053F5C4B01F3F55AF0D991966A9AFB40 /* Protobuf.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Protobuf.xcconfig; sourceTree = ""; }; 056951F1895AF99BBEB7DDE69213EBE9 /* RCTDevLoadingView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTDevLoadingView.m; sourceTree = ""; }; 057E16118AB23A0C841533BF0C3463B2 /* ARTTextManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = ARTTextManager.m; sourceTree = ""; }; 0581DF1C5E0B29F30F31EC180A7D9249 /* RCTMaskedView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTMaskedView.m; sourceTree = ""; }; 05826DCEE0F36471E684F1684BD2951A /* JSModulesUnbundle.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = JSModulesUnbundle.h; path = ReactCommon/cxxreact/JSModulesUnbundle.h; sourceTree = ""; }; 058F2D320849C5E354F3AA1679C66E11 /* RCTMultipartStreamReader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTMultipartStreamReader.h; sourceTree = ""; }; - 05BDA139C28772B6669FAA49F8C210EC /* libRNCAsyncStorage.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libRNCAsyncStorage.a; path = libRNCAsyncStorage.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 059085B56857C3A23B738477A8506199 /* DoubleConversion-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "DoubleConversion-dummy.m"; sourceTree = ""; }; 05DABF2A23A0CE9A83FA72582193EAF6 /* RAMBundleRegistry.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = RAMBundleRegistry.cpp; path = ReactCommon/cxxreact/RAMBundleRegistry.cpp; sourceTree = ""; }; + 065D8744D7CD01032E24ABBA1ACAFC3E /* FIRMessagingLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingLogger.h; path = Firebase/Messaging/FIRMessagingLogger.h; sourceTree = ""; }; + 069F69FA97FDBC1655FD5690EA59DD94 /* FIRDatabaseConfig.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRDatabaseConfig.m; path = Firebase/Database/Api/FIRDatabaseConfig.m; sourceTree = ""; }; 06AC11EE41F74F48DFBC6AC0E324CFAC /* CxxNativeModule.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CxxNativeModule.h; path = ReactCommon/cxxreact/CxxNativeModule.h; sourceTree = ""; }; - 06B7A465837535A2CB308829DF834B8B /* FIRLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRLogger.m; path = Firebase/Core/FIRLogger.m; sourceTree = ""; }; + 06CB84FA5566D0EDA5C8331F13B8C392 /* pb_encode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = pb_encode.h; sourceTree = ""; }; 06E3D243EFDC5A86565B61EA296DC97A /* NativeModule.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = NativeModule.h; path = ReactCommon/cxxreact/NativeModule.h; sourceTree = ""; }; 07002D48EB6136F683151A9B409335A7 /* RCTRootView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTRootView.h; sourceTree = ""; }; + 073FA4385301B0EDD8CBBE54E0A85814 /* FUtilities.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FUtilities.h; path = Firebase/Database/Utilities/FUtilities.h; sourceTree = ""; }; 076B30A0A3EB7C519D58B6326E54C155 /* LottieLogo1.gif */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.gif; name = LottieLogo1.gif; path = docs/gifs/LottieLogo1.gif; sourceTree = ""; }; - 07A73AEA93339D92B2C110B4FFDE82B8 /* Assume.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = Assume.cpp; path = folly/lang/Assume.cpp; sourceTree = ""; }; 07F58E8644069B5C6B981E95AEEA2043 /* RCTTouchHandler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTTouchHandler.m; sourceTree = ""; }; - 08283566C09AC0491587696FA9DBD268 /* DoubleConversion-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "DoubleConversion-dummy.m"; sourceTree = ""; }; + 08491B7F2816397E75081103B09AACA0 /* FIRAnalyticsConfiguration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRAnalyticsConfiguration.m; path = Firebase/Core/FIRAnalyticsConfiguration.m; sourceTree = ""; }; 088258D36D72F94F87F2700988424F4E /* LOTAnimatedSwitch.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTAnimatedSwitch.h; sourceTree = ""; }; 08927525A90C0C9011727E3727DAE263 /* YGConfig.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = YGConfig.cpp; path = yoga/YGConfig.cpp; sourceTree = ""; }; 08C3AE369601BB599B605DEA3A811741 /* ARTNodeManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = ARTNodeManager.h; sourceTree = ""; }; + 0903408DDF7F8C3AD3752EB1503C160E /* bignum.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = bignum.h; path = "double-conversion/bignum.h"; sourceTree = ""; }; 092C1DBA998516C3FD1BA9BC820F1557 /* NSTextStorage+FontScaling.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "NSTextStorage+FontScaling.h"; sourceTree = ""; }; + 0933D47EBA37DBA669BB91D37332294A /* histogram.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = histogram.h; path = util/histogram.h; sourceTree = ""; }; 094D117A5256ACECDD26613C69C201DF /* ARTSolidColor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = ARTSolidColor.h; sourceTree = ""; }; 0955504CC40828288DE3ACD2B86BDC98 /* RCTAsyncLocalStorage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTAsyncLocalStorage.h; sourceTree = ""; }; 095C3DBF1C00F57162F83E279588357C /* MaterialCommunityIcons.ttf */ = {isa = PBXFileReference; includeInIndex = 1; name = MaterialCommunityIcons.ttf; path = Fonts/MaterialCommunityIcons.ttf; sourceTree = ""; }; + 09624EE7B259BADAF0F1FAD4F0A753D3 /* FImmutableSortedSet.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FImmutableSortedSet.m; path = Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FImmutableSortedSet.m; sourceTree = ""; }; 096E4DC08D065EFAD71B1714E6EB5395 /* LOTShapeGroup.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTShapeGroup.m; sourceTree = ""; }; - 09701DDB31B473B0CDAF79AE545802F4 /* libGTMSessionFetcher.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libGTMSessionFetcher.a; path = libGTMSessionFetcher.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 0996F2843C29C1944530ABEEFC68EFD6 /* GPBArray_PackagePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBArray_PackagePrivate.h; path = objectivec/GPBArray_PackagePrivate.h; sourceTree = ""; }; 09A9461FDC3EFC18F84B16A4506A01FD /* RCTPerformanceLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTPerformanceLogger.m; sourceTree = ""; }; 0A330D8AB6658D47D7439D2CBB8A05C3 /* RCTTextShadowView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTTextShadowView.h; sourceTree = ""; }; 0A4289BCEB56700A05AA24316CD6E2BB /* BVLinearGradient-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "BVLinearGradient-prefix.pch"; sourceTree = ""; }; + 0A53EF276FBFF04D58AA684821959964 /* utilities.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = utilities.cc; path = src/utilities.cc; sourceTree = ""; }; 0A62A5F6AD64B8BF4A5390E182176CB1 /* Instance.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Instance.h; path = ReactCommon/cxxreact/Instance.h; sourceTree = ""; }; 0AAB35A6F112A270D9EB1C645F5B00E4 /* RCTSafeAreaView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTSafeAreaView.m; sourceTree = ""; }; - 0AF5AE5037BF6C75F311B1B382B1BD12 /* GPBUnknownFieldSet_PackagePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBUnknownFieldSet_PackagePrivate.h; path = objectivec/GPBUnknownFieldSet_PackagePrivate.h; sourceTree = ""; }; + 0AAB4A3659EDD277935020E5576C79ED /* GULSwizzler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULSwizzler.m; path = GoogleUtilities/MethodSwizzler/GULSwizzler.m; sourceTree = ""; }; + 0ACB229E2B3A2738DFDC60451CE1EF18 /* GPBUnknownFieldSet.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBUnknownFieldSet.m; path = objectivec/GPBUnknownFieldSet.m; sourceTree = ""; }; + 0ACE077C74B38A36472A73C30A541918 /* table_builder.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = table_builder.cc; path = table/table_builder.cc; sourceTree = ""; }; + 0B030D409ECDB4FBAC60A0939F910375 /* GPBCodedInputStream.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBCodedInputStream.h; path = objectivec/GPBCodedInputStream.h; sourceTree = ""; }; + 0B0C51FA037711B40BF921BC4F2075A4 /* arena.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = arena.h; path = util/arena.h; sourceTree = ""; }; 0B378C8781F4CC8F505149DA1C8ADA2D /* RCTInputAccessoryViewContent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTInputAccessoryViewContent.h; sourceTree = ""; }; 0B4D47D9E7EC3DB220CC86EC3BC65AD3 /* JSINativeModules.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = JSINativeModules.h; path = ReactCommon/jsiexecutor/jsireact/JSINativeModules.h; sourceTree = ""; }; 0BA903F2624EB644E66875057A6B8EB4 /* RNFileSystem.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNFileSystem.m; path = ios/RN/RNFileSystem.m; sourceTree = ""; }; + 0BAA5361695A82FAF3A98A1C9DC2CD8B /* Duration.pbobjc.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Duration.pbobjc.h; path = objectivec/google/protobuf/Duration.pbobjc.h; sourceTree = ""; }; + 0C0ECC2192D65619167B3FBDB43CA813 /* FQuerySpec.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FQuerySpec.m; path = Firebase/Database/Core/FQuerySpec.m; sourceTree = ""; }; + 0C5A241F21BA1B05DA1E29393CF0055D /* FKeyIndex.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FKeyIndex.h; path = Firebase/Database/FKeyIndex.h; sourceTree = ""; }; 0C7D8A5F115A4003517A46E722C87A64 /* RCTInputAccessoryShadowView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTInputAccessoryShadowView.h; sourceTree = ""; }; 0CAC838DD88D2D4FFB88840897FBC28F /* LOTCompositionContainer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTCompositionContainer.m; sourceTree = ""; }; + 0CACFD271582042A2D81EC4C6B15DACD /* FTupleTSN.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTupleTSN.h; path = Firebase/Database/Utilities/Tuples/FTupleTSN.h; sourceTree = ""; }; 0CD8ABFCB5425BAB402EA483FD5E29D9 /* jsi.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = jsi.h; path = ReactCommon/jsi/jsi.h; sourceTree = ""; }; - 0CEB3711F4BDB27DF244600A105B2363 /* bignum.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = bignum.h; path = "double-conversion/bignum.h"; sourceTree = ""; }; + 0CED65E4831C1A74A2F05C919CF3A6FA /* GoogleSignIn.bundle */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "wrapper.plug-in"; name = GoogleSignIn.bundle; path = Resources/GoogleSignIn.bundle; sourceTree = ""; }; + 0CF36179E7398673F38A1B46BDDE8565 /* FIRDatabaseReference.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDatabaseReference.h; path = Firebase/Database/Public/FIRDatabaseReference.h; sourceTree = ""; }; + 0E356741FE3B30C036009C1197254FF3 /* GPBBootstrap.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBBootstrap.h; path = objectivec/GPBBootstrap.h; sourceTree = ""; }; + 0E40F0916CDD2AD6370BED49A5AD407E /* FIRAnalyticsInteropListener.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAnalyticsInteropListener.h; path = Interop/Analytics/Public/FIRAnalyticsInteropListener.h; sourceTree = ""; }; 0E7C51EC374729EE211BBA611F49F336 /* RCTWebSocketModule.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTWebSocketModule.m; path = Libraries/WebSocket/RCTWebSocketModule.m; sourceTree = ""; }; + 0E900875CB45B56E0BAE6568D0A5B66C /* FIRMessagingUtilities.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingUtilities.h; path = Firebase/Messaging/FIRMessagingUtilities.h; sourceTree = ""; }; + 0E9EAABCF1ACD513834E19042D2F3C11 /* GPBProtocolBuffers_RuntimeSupport.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBProtocolBuffers_RuntimeSupport.h; path = objectivec/GPBProtocolBuffers_RuntimeSupport.h; sourceTree = ""; }; 0EA6CB24CBB62BF24D50D1E98999F6C9 /* RCTDisplayLink.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTDisplayLink.m; sourceTree = ""; }; 0ECBC79B539E0CBD03F0D17495CA692C /* TextDetectorManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = TextDetectorManager.h; path = ios/RN/TextDetectorManager.h; sourceTree = ""; }; - 0F621743FB68D849DBB1B3AB4FBF0F50 /* Any.pbobjc.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = Any.pbobjc.m; path = objectivec/google/protobuf/Any.pbobjc.m; sourceTree = ""; }; + 0EEC2E179EE88ADA68266CD2DEC1F4A1 /* NSError+FIRMessaging.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSError+FIRMessaging.m"; path = "Firebase/Messaging/NSError+FIRMessaging.m"; sourceTree = ""; }; + 0F678C71FCC584F339C700EF781734C9 /* libFirebaseMessaging.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libFirebaseMessaging.a; path = libFirebaseMessaging.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 0F85A824A43BC24616CE7831CCFD7D77 /* coding.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = coding.cc; path = util/coding.cc; sourceTree = ""; }; + 0FA1DA480D16C4A256F4422152880539 /* GULLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULLogger.m; path = GoogleUtilities/Logger/GULLogger.m; sourceTree = ""; }; 0FB9D920B7BCDEF86B4C02E227A8C6E7 /* LOTGradientFillRender.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTGradientFillRender.m; sourceTree = ""; }; + 0FC945B959C11D5210263BD057197540 /* FServerValues.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FServerValues.h; path = Firebase/Database/Core/FServerValues.h; sourceTree = ""; }; 0FDF7AB3951A3C99FB086DC3CAFC91A5 /* RCTInputAccessoryViewManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTInputAccessoryViewManager.h; sourceTree = ""; }; - 0FDF8816221E690C3EF750B7BC3B3CCB /* Answers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Answers.h; path = iOS/Crashlytics.framework/Headers/Answers.h; sourceTree = ""; }; 0FF454C04DA1216A56083477BA983262 /* RCTI18nManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTI18nManager.h; sourceTree = ""; }; 10546C57184BA5840555353F51FCBB30 /* ARTNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ARTNode.h; path = Libraries/ART/ARTNode.h; sourceTree = ""; }; 105B4263F5E7E4F1E9CBC0AA40450BA6 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; }; 10C464D5F1CF9BE605ADAFD754E5B607 /* RCTVirtualTextViewManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTVirtualTextViewManager.h; sourceTree = ""; }; + 10C619156E9298615BA8F6EFD90E2786 /* Protobuf-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Protobuf-dummy.m"; sourceTree = ""; }; + 1129AD0DCBBB3C878FD6D355C2C224A3 /* GULNetworkConstants.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkConstants.h; path = GoogleUtilities/Network/Private/GULNetworkConstants.h; sourceTree = ""; }; 1166E3CFD29896EA74A58F6D90258905 /* LOTCircleAnimator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTCircleAnimator.m; sourceTree = ""; }; + 119233EEDFEBB78EFF551ACE3BA29826 /* FIRDatabaseConfig.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDatabaseConfig.h; path = Firebase/Database/Api/FIRDatabaseConfig.h; sourceTree = ""; }; 11EF6D49F2864C7736EFB76F13566DD6 /* RCTImageShadowView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTImageShadowView.h; path = Libraries/Image/RCTImageShadowView.h; sourceTree = ""; }; + 11F954B9E1906E4B03C7590C9A888D93 /* port.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = port.h; path = port/port.h; sourceTree = ""; }; + 121210F3B063DF666F39A8CCFA329536 /* FRepo_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FRepo_Private.h; path = Firebase/Database/Core/FRepo_Private.h; sourceTree = ""; }; + 122B6326C706977426CCFAC9070682FC /* CLSStackFrame.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CLSStackFrame.h; path = iOS/Crashlytics.framework/Headers/CLSStackFrame.h; sourceTree = ""; }; + 12C406E967EB43474042DAEFDE88B37A /* FCompoundHash.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FCompoundHash.h; path = Firebase/Database/Core/FCompoundHash.h; sourceTree = ""; }; 12C85F0B8E6D79F3D6F9DD7B523A18CD /* RCTPackagerConnection.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTPackagerConnection.h; sourceTree = ""; }; - 13049D05C3EA29CBF24A9BAD6E4B6DF6 /* GTMNSData+zlib.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "GTMNSData+zlib.m"; path = "Foundation/GTMNSData+zlib.m"; sourceTree = ""; }; 1313984235EF5F0640B20BC58ECCE6FC /* LOTBlockCallback.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTBlockCallback.h; sourceTree = ""; }; 137B1E68E59720F269B6488A0EA8132F /* RCTCxxModule.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTCxxModule.mm; sourceTree = ""; }; 13C8D6B0E0A96DB5C57B65AEECEFBCDA /* RCTCamera.md */ = {isa = PBXFileReference; includeInIndex = 1; name = RCTCamera.md; path = docs/RCTCamera.md; sourceTree = ""; }; 13D96F3F28855DA932B7DC774EF9B8B4 /* RCTVirtualTextViewManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTVirtualTextViewManager.m; sourceTree = ""; }; + 1447EEC6E44D953BB79924C9D18D6ADA /* FIRComponentContainer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRComponentContainer.m; path = Firebase/Core/FIRComponentContainer.m; sourceTree = ""; }; + 144C1C9FF805BE562AFDB9A01A69D574 /* FSnapshotHolder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FSnapshotHolder.m; path = Firebase/Database/Core/FSnapshotHolder.m; sourceTree = ""; }; + 1476F8352701355D37CB650E82139B98 /* FTupleSetIdPath.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTupleSetIdPath.h; path = Firebase/Database/Utilities/Tuples/FTupleSetIdPath.h; sourceTree = ""; }; 14A64DEA330BCD99E949F44D3BDB93C2 /* ARTSurfaceViewManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = ARTSurfaceViewManager.h; sourceTree = ""; }; + 14CCBBBF8B62D60B9B16C63F39BDBDA1 /* FIRDatabaseQuery.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRDatabaseQuery.m; path = Firebase/Database/Api/FIRDatabaseQuery.m; sourceTree = ""; }; + 1501D5CE22977171369A89A58320F0E7 /* FSRWebSocket.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FSRWebSocket.m; path = Firebase/Database/third_party/SocketRocket/FSRWebSocket.m; sourceTree = ""; }; 152ACA559E31CB2EEE9562BF0E60149E /* Example4.gif */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.gif; name = Example4.gif; path = docs/gifs/Example4.gif; sourceTree = ""; }; 153B1B91C237664EC2E39EE3A492FA3D /* RCTMultipartStreamReader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTMultipartStreamReader.m; sourceTree = ""; }; 153D64AD7A461EE90C2D7D3D7D6C90D5 /* RCTVersion.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTVersion.m; sourceTree = ""; }; - 156121052651E68677BF8522AC28928C /* DoubleConversion.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = DoubleConversion.xcconfig; sourceTree = ""; }; - 157706EDD3606099FD3DFF40939F0F07 /* Fabric.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Fabric.h; path = iOS/Fabric.framework/Headers/Fabric.h; sourceTree = ""; }; 15A9011D85860FA918D538B04E4F0E1F /* RCTFrameUpdate.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTFrameUpdate.m; sourceTree = ""; }; - 15B2B5FFFEFF905A2E8F5CAD7D6E83D9 /* FirebaseRemoteConfig.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseRemoteConfig.xcconfig; sourceTree = ""; }; + 15A9D734E57E7B82657B9C03A83BDAD6 /* FIRNoopAuthTokenProvider.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRNoopAuthTokenProvider.m; path = Firebase/Database/Login/FIRNoopAuthTokenProvider.m; sourceTree = ""; }; + 15EB2B211850BEB00F748CE3C6ABEDBB /* FIRDataSnapshot.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRDataSnapshot.m; path = Firebase/Database/Api/FIRDataSnapshot.m; sourceTree = ""; }; 163707F9FE0CCEA43E6C380C04E6AC7F /* RCTCxxBridge.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTCxxBridge.mm; sourceTree = ""; }; 164D64521EB94AA2D7A7EFC5759F5949 /* RCTUITextView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTUITextView.m; sourceTree = ""; }; - 164E6AF71FDF857751A56340FCE1685E /* GPBExtensionInternals.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBExtensionInternals.h; path = objectivec/GPBExtensionInternals.h; sourceTree = ""; }; 164F9C8C1B9350383134F306BDFF8D13 /* LOTTrimPathNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTTrimPathNode.m; sourceTree = ""; }; - 166091403FC4A8777527BE2435C87455 /* cached-powers.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = "cached-powers.cc"; path = "double-conversion/cached-powers.cc"; sourceTree = ""; }; 16815D82AA76AD2A7707B986C1D06F78 /* RCTJSStackFrame.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTJSStackFrame.h; sourceTree = ""; }; 1694A41CC9BF288DDAB1E7DD6BC008F4 /* RCTBaseTextInputView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTBaseTextInputView.m; sourceTree = ""; }; 17258D135D9BB7E83C8F2D02315DFB22 /* lottie-react-native.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "lottie-react-native.xcconfig"; sourceTree = ""; }; @@ -1830,222 +2408,308 @@ 172D5EB5619CDF0C2D83A30BB7941F8B /* JSExecutor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = JSExecutor.h; path = ReactCommon/cxxreact/JSExecutor.h; sourceTree = ""; }; 173866B6E1CB900B921139211799E3A5 /* Pods-Kalend-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Kalend-resources.sh"; sourceTree = ""; }; 17412BADE8F69566EF2B3D7BD9D21787 /* RCTExceptionsManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTExceptionsManager.m; sourceTree = ""; }; - 179D68FDFC3CDCDF06A4BA700012BB6A /* nanopb-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "nanopb-dummy.m"; sourceTree = ""; }; 17AE8534092346597F0F30C4088C4090 /* LOTShapePath.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTShapePath.h; sourceTree = ""; }; - 17D71D051405FFD0A9EC92F14F4AE0F0 /* fast-dtoa.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = "fast-dtoa.cc"; path = "double-conversion/fast-dtoa.cc"; sourceTree = ""; }; - 188115FBADC84AD94022FC7497ADA47A /* Crashlytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Crashlytics.framework; path = iOS/Crashlytics.framework; sourceTree = ""; }; + 17EA5C6CF12F09B8E6CB1128E1F997E7 /* FOperationSource.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FOperationSource.h; path = Firebase/Database/Core/Operation/FOperationSource.h; sourceTree = ""; }; + 1825D2BACAE0467CA2F215722962EBA2 /* String.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = String.cpp; path = folly/String.cpp; sourceTree = ""; }; + 18351BEBA491DA6D9CADDDC581F9CE07 /* table_builder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = table_builder.h; path = include/leveldb/table_builder.h; sourceTree = ""; }; 188CD2DDBDAAEEAF4AA4BD6C44D93F14 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE; sourceTree = ""; }; 1895D859CA9767D810F6C3510ABCA351 /* ARTLinearGradient.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = ARTLinearGradient.m; sourceTree = ""; }; - 18B460E4AEBC71D4F729A44EA5FDDB3C /* GTMNSString+URLArguments.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "GTMNSString+URLArguments.m"; path = "Foundation/GTMNSString+URLArguments.m"; sourceTree = ""; }; - 18BD70EBB27C2C225F7C9265B7A5AFBC /* CLSLogging.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CLSLogging.h; path = iOS/Crashlytics.framework/Headers/CLSLogging.h; sourceTree = ""; }; 192764F7F9F5627D9C7C178EBAF30A6E /* RCTUITextField.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTUITextField.h; sourceTree = ""; }; + 1930D643E55F4366DCFB1B34FB799D5A /* FNextPushId.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FNextPushId.h; path = Firebase/Database/Utilities/FNextPushId.h; sourceTree = ""; }; + 19330FC8B77327DE6F4BBF84783EB457 /* thread_annotations.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = thread_annotations.h; path = port/thread_annotations.h; sourceTree = ""; }; 19728967E0FA09F1220A1E84FBAA2D9C /* YGValue.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = YGValue.h; path = yoga/YGValue.h; sourceTree = ""; }; + 19BF7714D6B5F3817830119EEC74D6FE /* FIRMessagingRemoteNotificationsProxy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingRemoteNotificationsProxy.m; path = Firebase/Messaging/FIRMessagingRemoteNotificationsProxy.m; sourceTree = ""; }; 19FA7CC6598EE44D9CB7C787C69C4DBA /* RCTSensorOrientationChecker.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTSensorOrientationChecker.m; path = ios/RCT/RCTSensorOrientationChecker.m; sourceTree = ""; }; 1A0CE655EB439D100B22AB226928A06A /* RCTComponent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTComponent.h; sourceTree = ""; }; 1A3A7C992B818A68729BDA2C5F9F693A /* YGFloatOptional.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = YGFloatOptional.h; path = yoga/YGFloatOptional.h; sourceTree = ""; }; + 1A4536262CC31CAB068E3FACD297A952 /* FPersistenceManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FPersistenceManager.m; path = Firebase/Database/Persistence/FPersistenceManager.m; sourceTree = ""; }; 1A48B66A95DC6A35C618F128B61FE14B /* ARTSurfaceViewManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = ARTSurfaceViewManager.m; sourceTree = ""; }; - 1A8327FC8E434A4FD8AD318FD9CCF1DF /* FIRApp.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRApp.m; path = Firebase/Core/FIRApp.m; sourceTree = ""; }; 1A89542AE5AA5DE9542FE4B8387D671F /* RCTRedBoxExtraDataViewController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTRedBoxExtraDataViewController.h; sourceTree = ""; }; 1B11C9CEB955F2A8B352F3BD3AC30DE3 /* RCTUIUtils.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTUIUtils.h; sourceTree = ""; }; - 1B4BEF4027A9C2211C97B5F2A75601C7 /* CLSAttributes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CLSAttributes.h; path = iOS/Crashlytics.framework/Headers/CLSAttributes.h; sourceTree = ""; }; + 1B16B1592C78D9E8DDA420A908C6954A /* GULAppDelegateSwizzler_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULAppDelegateSwizzler_Private.h; path = GoogleUtilities/AppDelegateSwizzler/Internal/GULAppDelegateSwizzler_Private.h; sourceTree = ""; }; + 1B4644B43D841F176E86CB3561348D33 /* FTupleNodePath.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTupleNodePath.h; path = Firebase/Database/Utilities/Tuples/FTupleNodePath.h; sourceTree = ""; }; 1BA065A58BF7952929FEBD9BE6E833C2 /* NSValue+Compat.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "NSValue+Compat.h"; sourceTree = ""; }; 1BB195552DB736B00A2DDC46ED5F7F22 /* LOTBezierData.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTBezierData.m; sourceTree = ""; }; 1C14C35A19AF78E3297F99ECB885B3A1 /* RCTBaseTextInputViewManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTBaseTextInputViewManager.m; sourceTree = ""; }; 1C28B39638447DA22BA1B9F4E2DCE167 /* RCTAnimatedNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTAnimatedNode.h; sourceTree = ""; }; - 1C3262CA3724AF3763EAB28F74C4341B /* GoogleUtilities-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "GoogleUtilities-dummy.m"; sourceTree = ""; }; + 1C374ECE8D62BB7FABF1AF2C15A3663D /* version_edit.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = version_edit.cc; path = db/version_edit.cc; sourceTree = ""; }; 1C6116C0F9BD4A3F5B51A63F2ED47FE0 /* RCTRootViewInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTRootViewInternal.h; sourceTree = ""; }; + 1C8C47ABA550DEE7AF6DB7793BD0F4B3 /* FChildChangeAccumulator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FChildChangeAccumulator.h; path = Firebase/Database/Core/View/Filter/FChildChangeAccumulator.h; sourceTree = ""; }; + 1CBD2C6F54A33026F16AD69A95A2FB37 /* ieee.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ieee.h; path = "double-conversion/ieee.h"; sourceTree = ""; }; 1D0B242D922F068B949ED9BC7E5AF629 /* RNFetchBlobProgress.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNFetchBlobProgress.m; path = ios/RNFetchBlobProgress.m; sourceTree = ""; }; + 1D0FE567498F874EDCA9397BB8942691 /* filename.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = filename.cc; path = db/filename.cc; sourceTree = ""; }; 1D3F307D076FF78FE39D6E5E0F462FAB /* RCTEventEmitter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTEventEmitter.h; sourceTree = ""; }; - 1D71AD1DB4527B0E722DBF9C232C497E /* Crashlytics.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Crashlytics.h; path = iOS/Crashlytics.framework/Headers/Crashlytics.h; sourceTree = ""; }; + 1D8034D5DC09757CBF6C88BCE84C81B3 /* log_reader.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = log_reader.cc; path = db/log_reader.cc; sourceTree = ""; }; + 1DB773AEC4E2516504AB580F796DF2E2 /* hash.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = hash.h; path = util/hash.h; sourceTree = ""; }; 1DD1AB9F0A805291588A2A63A92AD283 /* RCTSurfaceHostingProxyRootView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSurfaceHostingProxyRootView.h; sourceTree = ""; }; - 1DEA959471C355E2B056B18A9D36B924 /* FIRAppInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAppInternal.h; path = Firebase/Core/Private/FIRAppInternal.h; sourceTree = ""; }; + 1DF01DAD811E57DC0E104624FC8E3958 /* dynamic.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = dynamic.cpp; path = folly/dynamic.cpp; sourceTree = ""; }; + 1E28567DA629BA3B509E5A6F78CFA386 /* write_batch.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = write_batch.h; path = include/leveldb/write_batch.h; sourceTree = ""; }; 1E2F3D8B34EFA5FBE9D146313A09C54F /* RCTMultilineTextInputView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTMultilineTextInputView.h; sourceTree = ""; }; 1E59AA57BB1577CB3DA41C09BA59D66A /* Watermelon.gif */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.gif; name = Watermelon.gif; path = docs/gifs/Watermelon.gif; sourceTree = ""; }; 1E74862BA95FE8275A4D8B3DCB813A9E /* RNCAsyncStorage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNCAsyncStorage.h; path = ios/RNCAsyncStorage.h; sourceTree = ""; }; + 1EC0957443FA3D8BFC4DA9600F70F905 /* filename.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = filename.h; path = db/filename.h; sourceTree = ""; }; 1EC752003B705106CAC2EE5F0FB7F0F4 /* RCTUIUtils.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTUIUtils.m; sourceTree = ""; }; 1ED4EF54422909B082349BEB896EAE52 /* RCTProfileTrampoline-arm.S */ = {isa = PBXFileReference; includeInIndex = 1; path = "RCTProfileTrampoline-arm.S"; sourceTree = ""; }; 1EEDC241C41A1D77AB05E9263C629A53 /* LRNAnimationViewManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = LRNAnimationViewManager.m; path = src/ios/LottieReactNative/LRNAnimationViewManager.m; sourceTree = ""; }; + 1EF8A973FA536E2E222B0BDFA64DF17E /* testharness.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = testharness.cc; path = util/testharness.cc; sourceTree = ""; }; + 1F235E8C436E14FF6556F77D0ADA49DC /* GPBCodedOutputStream.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBCodedOutputStream.h; path = objectivec/GPBCodedOutputStream.h; sourceTree = ""; }; + 1F2D533EDC352B7D0DE415441637CD41 /* GPBUnknownFieldSet.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBUnknownFieldSet.h; path = objectivec/GPBUnknownFieldSet.h; sourceTree = ""; }; + 1F4FC0A27C51B191972D727F7307D153 /* GULNetwork.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULNetwork.m; path = GoogleUtilities/Network/GULNetwork.m; sourceTree = ""; }; 1F612EEFB18D2E5295A47F69A2FC4A84 /* RNCamera.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNCamera.m; path = ios/RN/RNCamera.m; sourceTree = ""; }; - 1F6860C06A97C95A108D783D81E2163D /* FIRLoggerLevel.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLoggerLevel.h; path = Firebase/Core/Public/FIRLoggerLevel.h; sourceTree = ""; }; 1F73F441EFFB57B67671EC1D71949757 /* RNCAsyncStorage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNCAsyncStorage.m; path = ios/RNCAsyncStorage.m; sourceTree = ""; }; 1FAD745BB610D527200334238FC49013 /* YGLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = YGLayout.h; path = yoga/YGLayout.h; sourceTree = ""; }; 1FDB57154FD20A94DEBC19617F121F6D /* BVLinearGradientManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BVLinearGradientManager.h; path = BVLinearGradient/BVLinearGradientManager.h; sourceTree = ""; }; + 1FF006F9B14B4A5F20A8D153F088C1DB /* FOverwrite.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FOverwrite.m; path = Firebase/Database/Core/Operation/FOverwrite.m; sourceTree = ""; }; 202CEFF02AB6C39FA334A9B51F1D8870 /* RCTMaskedViewManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTMaskedViewManager.h; sourceTree = ""; }; 204F2399882F7EAA57373166A055F8A1 /* RCTTextView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTTextView.h; sourceTree = ""; }; 2061B9760AF4D28D3E2250A8BEBF4933 /* RCTBridgeDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTBridgeDelegate.h; sourceTree = ""; }; + 208205C1978010CC4D1CA1B7BD5F07C8 /* testharness.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = testharness.h; path = util/testharness.h; sourceTree = ""; }; 20C7D73E95CAB00F07FE116FFFD90D9A /* LOTShapeRepeater.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTShapeRepeater.m; sourceTree = ""; }; 210A1CF925368F7822E0CDAC951C268D /* Recipes.md */ = {isa = PBXFileReference; includeInIndex = 1; name = Recipes.md; path = docs/Recipes.md; sourceTree = ""; }; - 212FB97DDEAF6BEAFED5E4B7EFBDBA01 /* pb_decode.c */ = {isa = PBXFileReference; includeInIndex = 1; path = pb_decode.c; sourceTree = ""; }; - 21661A7F663A0C93FA1F45E12ED66480 /* GPBUtilities_PackagePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBUtilities_PackagePrivate.h; path = objectivec/GPBUtilities_PackagePrivate.h; sourceTree = ""; }; - 21D92EBF9C5C9D2E24D5EDC4ECD86EB3 /* libGoogleUtilities.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libGoogleUtilities.a; path = libGoogleUtilities.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 2156A0B7B819CB97B539B49BE9C60221 /* libProtobuf.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libProtobuf.a; path = libProtobuf.a; sourceTree = BUILT_PRODUCTS_DIR; }; 222A1B2E02B1DA97A41401CD7B3315AA /* ARTRenderableManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = ARTRenderableManager.h; sourceTree = ""; }; - 2233E91FFBE6CBACEFCB81BD57B1B34D /* GULLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULLogger.m; path = GoogleUtilities/Logger/GULLogger.m; sourceTree = ""; }; + 224C97647A67A921AFF5BEF517FB27C9 /* FRepoInfo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FRepoInfo.m; path = Firebase/Database/Core/FRepoInfo.m; sourceTree = ""; }; 22570DB31327C71F2C7ED350AF9A924A /* LOTShapeTrimPath.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTShapeTrimPath.h; sourceTree = ""; }; - 226E382223F53A8210A8E202F67338BA /* GULObjectSwizzler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULObjectSwizzler.m; path = GoogleUtilities/ISASwizzler/GULObjectSwizzler.m; sourceTree = ""; }; 228B7F62F484C92E3822F08535BF48A5 /* LOTPolystarAnimator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTPolystarAnimator.m; sourceTree = ""; }; - 228E1FDFF261DF8EB10848297D3AB291 /* FIRBundleUtil.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRBundleUtil.m; path = Firebase/Core/FIRBundleUtil.m; sourceTree = ""; }; + 229EC03EE7326CEE9A1F6C1C8EB26333 /* FPendingPut.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FPendingPut.m; path = Firebase/Database/Persistence/FPendingPut.m; sourceTree = ""; }; + 22C6EE7C568060C47D4DD01B6A1DAA41 /* libRNVectorIcons.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libRNVectorIcons.a; path = libRNVectorIcons.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 22DAF0E1D71C0A9951000AABEE74F317 /* FTrackedQueryManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FTrackedQueryManager.m; path = Firebase/Database/Persistence/FTrackedQueryManager.m; sourceTree = ""; }; 22E0623C0304B30B2AA1436750E2C8A0 /* RNCAsyncStorage.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RNCAsyncStorage.xcconfig; sourceTree = ""; }; 231C1D17E3BAB791F3407E34ACD5FC05 /* QA.md */ = {isa = PBXFileReference; includeInIndex = 1; name = QA.md; path = docs/QA.md; sourceTree = ""; }; + 233CC9D72A4769298201DCE6A22219B4 /* SourceContext.pbobjc.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SourceContext.pbobjc.m; path = objectivec/google/protobuf/SourceContext.pbobjc.m; sourceTree = ""; }; 235BAD3F402C7F6980AB0B120D5F5749 /* RCTMaskedViewManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTMaskedViewManager.m; sourceTree = ""; }; - 23B37EAAEEE6C1F0DE71D561FB401651 /* liblottie-ios.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "liblottie-ios.a"; path = "liblottie-ios.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 23AFDC3FD68BD01B454A06682CE3ACD8 /* GULReachabilityMessageCode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULReachabilityMessageCode.h; path = GoogleUtilities/Reachability/Private/GULReachabilityMessageCode.h; sourceTree = ""; }; + 23D54FAEECFDD570E95E39A465F7CDA4 /* FDataEvent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FDataEvent.h; path = Firebase/Database/Core/View/FDataEvent.h; sourceTree = ""; }; 23E7FCA5301B09CE97AB809DDCC55C97 /* BVLinearGradient-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "BVLinearGradient-dummy.m"; sourceTree = ""; }; 23F0CE51550D2CCFBABCB411CECFB191 /* AntDesign.ttf */ = {isa = PBXFileReference; includeInIndex = 1; name = AntDesign.ttf; path = Fonts/AntDesign.ttf; sourceTree = ""; }; 2402A9540C188DF09C54925D6A8D7927 /* React-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "React-prefix.pch"; sourceTree = ""; }; - 2410678D9F5CB5DC22FE50D7F0379F3A /* Folly-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Folly-dummy.m"; sourceTree = ""; }; - 2441A0494B64BA30472F9C2D55D56C83 /* String.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = String.cpp; path = folly/String.cpp; sourceTree = ""; }; 2453345CD7397B82DF0FA2E4EB28F3BA /* ARTGroup.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = ARTGroup.m; path = Libraries/ART/ARTGroup.m; sourceTree = ""; }; 2456C921F0E0E039A5DAECBE2F092642 /* RCTValueAnimatedNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTValueAnimatedNode.h; sourceTree = ""; }; + 247163A6FF856A371E4B0C15E8AC85EE /* FRepo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FRepo.m; path = Firebase/Database/Core/FRepo.m; sourceTree = ""; }; 2476CC9205C2943764C45EC9C1C2F26E /* LOTShapeCircle.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTShapeCircle.m; sourceTree = ""; }; 250135120E1268B9E37A19B1BA773892 /* LOTPolystarAnimator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTPolystarAnimator.h; sourceTree = ""; }; - 2504EFA7DAA884BEBB3493C7C31EFF2B /* GULAppDelegateSwizzler_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULAppDelegateSwizzler_Private.h; path = GoogleUtilities/AppDelegateSwizzler/Internal/GULAppDelegateSwizzler_Private.h; sourceTree = ""; }; 2509BBA42464F8BC22F3C80C68F657A8 /* JSIDynamic.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = JSIDynamic.h; path = ReactCommon/jsi/JSIDynamic.h; sourceTree = ""; }; - 251B3A4D5C73A6D5545A5C5D38F4E596 /* GPBCodedOutputStream_PackagePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBCodedOutputStream_PackagePrivate.h; path = objectivec/GPBCodedOutputStream_PackagePrivate.h; sourceTree = ""; }; 255FBD0F7442584058A993EA565B5598 /* UIColor+Expanded.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "UIColor+Expanded.m"; sourceTree = ""; }; + 2581AA780F218D5AAF0D6EA495651CA5 /* memtable.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = memtable.h; path = db/memtable.h; sourceTree = ""; }; + 2582A15A70285331E519CBBEAEF231CD /* FTupleNodePath.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FTupleNodePath.m; path = Firebase/Database/Utilities/Tuples/FTupleNodePath.m; sourceTree = ""; }; + 25BEA17231DD2405EAF009FDD93C48D7 /* FSyncPoint.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FSyncPoint.h; path = Firebase/Database/Core/FSyncPoint.h; sourceTree = ""; }; 25F30DBB7217E0EB6D38CC70931AA72F /* BVLinearGradient.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = BVLinearGradient.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 260F9C12700347670BE4AB984A2C3EDF /* RCTInputAccessoryView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTInputAccessoryView.h; sourceTree = ""; }; - 261886C1CC9C635DF4D09F766A9EBBE3 /* GTMSessionFetcherService.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTMSessionFetcherService.m; path = Source/GTMSessionFetcherService.m; sourceTree = ""; }; + 267864CCA87DB796A799D1C8EF7D05F7 /* FLimitedFilter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FLimitedFilter.h; path = Firebase/Database/Core/View/Filter/FLimitedFilter.h; sourceTree = ""; }; 26CE83BC330B28EB74B16605040003BC /* RCTLayoutAnimation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTLayoutAnimation.m; sourceTree = ""; }; - 2792075F8CDA8BFF18CBE95BD0DD1596 /* GULReachabilityMessageCode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULReachabilityMessageCode.h; path = GoogleUtilities/Reachability/Private/GULReachabilityMessageCode.h; sourceTree = ""; }; - 27B324A94122FB21CAF9924D9DE60D16 /* F14Table.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = F14Table.cpp; path = folly/container/detail/F14Table.cpp; sourceTree = ""; }; + 26E73ED066200F04541BEBB190059366 /* FTupleFirebase.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FTupleFirebase.m; path = Firebase/Database/Utilities/Tuples/FTupleFirebase.m; sourceTree = ""; }; + 26FBF5FA8071E77A53B62F51FB74DE70 /* FSnapshotUtilities.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FSnapshotUtilities.m; path = Firebase/Database/Snapshot/FSnapshotUtilities.m; sourceTree = ""; }; + 27938245D9F59E1D8028A667866781E4 /* GULSwizzledObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULSwizzledObject.h; path = GoogleUtilities/ISASwizzler/Private/GULSwizzledObject.h; sourceTree = ""; }; + 279A3550CD2D5DDEC0DCCEB54A44A4C4 /* FQueryParams.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FQueryParams.h; path = Firebase/Database/Core/FQueryParams.h; sourceTree = ""; }; + 27B78908479033CE1848EB5E0A3FCB7E /* filter_policy.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = filter_policy.cc; path = util/filter_policy.cc; sourceTree = ""; }; 2810B05EDC88C0ECB243160CD785B8A2 /* RCTBaseTextInputView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTBaseTextInputView.h; sourceTree = ""; }; 28158453CB780AD8FF755BDB8FDDA7D3 /* RCTMultiplicationAnimatedNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTMultiplicationAnimatedNode.m; sourceTree = ""; }; - 2831E881A4F91126F443F35CD9C43A29 /* Protobuf-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Protobuf-prefix.pch"; sourceTree = ""; }; 284CE73BA93AF2DBCC13D60F939D8AAA /* LOTInterpolatorCallback.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTInterpolatorCallback.h; sourceTree = ""; }; 28A58FD07042B910D401A97FE2112FAD /* LOTKeyframe.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTKeyframe.m; sourceTree = ""; }; 28D203CA071CD6707C1DB1730354C047 /* LOTShapeFill.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTShapeFill.m; sourceTree = ""; }; - 28D497C6002C97A230F3D31493013279 /* FirebaseInstanceID.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseInstanceID.framework; path = Frameworks/FirebaseInstanceID.framework; sourceTree = ""; }; + 2905FC763BAE2E62DB4A4F12CCD07622 /* GoogleUtilities-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "GoogleUtilities-dummy.m"; sourceTree = ""; }; 295B9A1EE8E0456AD85C309CF752BCDE /* fishhook.c */ = {isa = PBXFileReference; includeInIndex = 1; name = fishhook.c; path = Libraries/fishhook/fishhook.c; sourceTree = ""; }; + 295F4B225E8825FB9DDBD005632C9CCF /* builder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = builder.h; path = db/builder.h; sourceTree = ""; }; + 297D93EF3C8789F0A1EC74DD2721C0B3 /* FDataEvent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FDataEvent.m; path = Firebase/Database/Core/View/FDataEvent.m; sourceTree = ""; }; 29A4B1AA6BD798B95E0BCD406CBD5D21 /* LOTBezierData.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTBezierData.h; sourceTree = ""; }; 29B293C5E2E1A65C90676AD7F889DA73 /* BVLinearGradientLayer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BVLinearGradientLayer.h; path = BVLinearGradient/BVLinearGradientLayer.h; sourceTree = ""; }; + 29D2B5D41D48199784CDB89A40F06B5C /* FLLRBValueNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FLLRBValueNode.h; path = Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBValueNode.h; sourceTree = ""; }; 2A351EFA847FB7BE145FE4372C864DD0 /* ARTNodeManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = ARTNodeManager.m; sourceTree = ""; }; 2A4155C7E08C2F42EF1B2E7C21605878 /* LOTRepeaterRenderer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTRepeaterRenderer.m; sourceTree = ""; }; - 2A6DF6B5FABFF927C45202CE34C54F6A /* GPBMessage_PackagePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBMessage_PackagePrivate.h; path = objectivec/GPBMessage_PackagePrivate.h; sourceTree = ""; }; + 2A6CD0729441F2880CBA9BBEEE9104CE /* FIRServerValue.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRServerValue.m; path = Firebase/Database/Api/FIRServerValue.m; sourceTree = ""; }; + 2A957ABA5B2C2265A3AD0EE1B4A29FC8 /* FListenComplete.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FListenComplete.h; path = Firebase/Database/FListenComplete.h; sourceTree = ""; }; 2ACD8C020C859A4C2BDFAE9204E09AC6 /* RCTMultipartDataTask.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTMultipartDataTask.m; sourceTree = ""; }; + 2AD9246D1D4092E3286681D4F885BC9D /* logging.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = logging.h; path = util/logging.h; sourceTree = ""; }; 2AEB7903B8C74355D0296B3B43D50927 /* RCTDevSettings.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTDevSettings.h; sourceTree = ""; }; - 2B08F7E25D12EB4A87A9121CACBA86AD /* pb_encode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = pb_encode.h; sourceTree = ""; }; 2B2570E8AAE0D3B21DC7ECEE32C397C5 /* RCTComponentData.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTComponentData.m; sourceTree = ""; }; 2B28AE00B98C9CE22A983E63EFA72434 /* RCTCxxMethod.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTCxxMethod.h; sourceTree = ""; }; 2B2C2794E9BD66CD459106E6836ECE13 /* RCTWebSocketExecutor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTWebSocketExecutor.m; path = Libraries/WebSocket/RCTWebSocketExecutor.m; sourceTree = ""; }; + 2B9028452AA9A0B051DDEE4F315AE9DF /* db_impl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = db_impl.h; path = db/db_impl.h; sourceTree = ""; }; 2BC8CC3B0192881ADDEAC70313F213FA /* RCTModuleData.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTModuleData.mm; sourceTree = ""; }; 2BD8A8817272444480B1B5B3B82FCC0D /* RNCSlider.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNCSlider.m; path = ios/RNCSlider.m; sourceTree = ""; }; 2BDF846CF1664AC23BC15C5315AA9FE7 /* NSDataBigString.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = NSDataBigString.mm; sourceTree = ""; }; - 2BFC25B49C86C3D89C95B316576FA83E /* GULSwizzledObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULSwizzledObject.h; path = GoogleUtilities/ISASwizzler/Private/GULSwizzledObject.h; sourceTree = ""; }; + 2BF47581753EE9991293514DAE4C7293 /* GPBUtilities.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBUtilities.m; path = objectivec/GPBUtilities.m; sourceTree = ""; }; 2C0E9614BB5103F441C0E525709EAB49 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; }; + 2C4CFD22020485822A4E873A26E08CB6 /* GTMMethodCheck.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMMethodCheck.h; path = DebugUtils/GTMMethodCheck.h; sourceTree = ""; }; + 2C9BDBDC57900F889A1652635E54DE7B /* FViewCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FViewCache.h; path = Firebase/Database/Core/View/FViewCache.h; sourceTree = ""; }; 2CA1E553086B47B4F5976B6207520336 /* LOTAssetGroup.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTAssetGroup.m; sourceTree = ""; }; + 2CB2ECC205A62B1B815F9B9BC95FD7DE /* FIRMessagingSecureSocket.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingSecureSocket.h; path = Firebase/Messaging/FIRMessagingSecureSocket.h; sourceTree = ""; }; + 2CC836083D4A964D223ED91DB13EAB5F /* FIRDataEventType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDataEventType.h; path = Firebase/Database/Public/FIRDataEventType.h; sourceTree = ""; }; 2CD4338A67811F27EBC676D4033AF8B3 /* RCTRootViewDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTRootViewDelegate.h; sourceTree = ""; }; - 2CF91E718BB25941178A5127B828D618 /* Struct.pbobjc.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Struct.pbobjc.h; path = objectivec/google/protobuf/Struct.pbobjc.h; sourceTree = ""; }; + 2D1EDBB41D682CA19504C5D902951F7F /* diy-fp.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "diy-fp.h"; path = "double-conversion/diy-fp.h"; sourceTree = ""; }; + 2D38CC89FE381ABEE58778A8430EC558 /* bignum-dtoa.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = "bignum-dtoa.cc"; path = "double-conversion/bignum-dtoa.cc"; sourceTree = ""; }; + 2D82596297034CEA5B5479350D457747 /* GPBWellKnownTypes.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBWellKnownTypes.m; path = objectivec/GPBWellKnownTypes.m; sourceTree = ""; }; + 2D94706E0AD7230685EFD7FAC0869FDF /* FIRMessagingReceiver.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingReceiver.m; path = Firebase/Messaging/FIRMessagingReceiver.m; sourceTree = ""; }; + 2D97F98E914FF8F367D4172A6ADFCA5A /* Timestamp.pbobjc.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = Timestamp.pbobjc.m; path = objectivec/google/protobuf/Timestamp.pbobjc.m; sourceTree = ""; }; 2DB8E3BD18F14DBDD15023DD16FC07C2 /* Lottie.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = Lottie.h; sourceTree = ""; }; - 2E1AA42D2B4DF27E096A2A733289CC42 /* GPBExtensionRegistry.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBExtensionRegistry.h; path = objectivec/GPBExtensionRegistry.h; sourceTree = ""; }; + 2DEED99E085D1569EA7AF45E36DD03C1 /* FAtomicNumber.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FAtomicNumber.h; path = Firebase/Database/Utilities/FAtomicNumber.h; sourceTree = ""; }; + 2E14A2E0B973C1B11918E2E0DF10B31A /* GTMSessionFetcher-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "GTMSessionFetcher-prefix.pch"; sourceTree = ""; }; + 2E295112032A733DEDF268666E7090D2 /* FEventGenerator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FEventGenerator.h; path = Firebase/Database/FEventGenerator.h; sourceTree = ""; }; + 2E5BD7D7208DA0C99017C1E9935E47D0 /* FIRMessagingPendingTopicsList.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingPendingTopicsList.m; path = Firebase/Messaging/FIRMessagingPendingTopicsList.m; sourceTree = ""; }; + 2E6957BFB3FCF960F7BB3C06E83AFCE8 /* GULNetworkURLSession.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULNetworkURLSession.m; path = GoogleUtilities/Network/GULNetworkURLSession.m; sourceTree = ""; }; + 2EA3F99C1D3B4AF30B88B8BD22D2D7C3 /* crc32c.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = crc32c.cc; path = util/crc32c.cc; sourceTree = ""; }; 2EAEECA81B7EBF096C19D14F97514F13 /* RCTRawTextViewManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTRawTextViewManager.h; sourceTree = ""; }; + 2EBBCAE335DBBFEA14BA90A678C4A32B /* FIRMessagingPubSubRegistrar.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingPubSubRegistrar.h; path = Firebase/Messaging/FIRMessagingPubSubRegistrar.h; sourceTree = ""; }; 2EFA34689F30A01DA5092DD58DB934B6 /* RCTJavaScriptExecutor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTJavaScriptExecutor.h; sourceTree = ""; }; 2F2AF4334192AED4630043ECF25E747B /* ARTBrush.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = ARTBrush.m; sourceTree = ""; }; - 2F78EC927E123ED2AD0206235BCC08BB /* Unicode.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = Unicode.cpp; path = folly/Unicode.cpp; sourceTree = ""; }; + 2F4CE8B42235E53F5BD9721CD57244D9 /* FLimitedFilter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FLimitedFilter.m; path = Firebase/Database/Core/View/Filter/FLimitedFilter.m; sourceTree = ""; }; 2F9BB4CBCB450B127736E624E673744A /* Pods-Kalend-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Kalend-dummy.m"; sourceTree = ""; }; 2FA53F3F29CD7D55AFAFD70D621F2BFF /* RCTTextAttributes.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTTextAttributes.m; path = Libraries/Text/RCTTextAttributes.m; sourceTree = ""; }; 2FBE3558F43FAEAEC0EA0D1C52013233 /* RCTGIFImageDecoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTGIFImageDecoder.m; path = Libraries/Image/RCTGIFImageDecoder.m; sourceTree = ""; }; - 2FC12CDDA3884BD1F1A3DFCF56CFD70C /* GoogleToolboxForMac-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "GoogleToolboxForMac-prefix.pch"; sourceTree = ""; }; + 2FF32C8A293A79D640DB5B9A70792DA8 /* testutil.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = testutil.cc; path = util/testutil.cc; sourceTree = ""; }; 3029D9FF7387BF6ABDE35AF4DD5469E4 /* RCTShadowView+Internal.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "RCTShadowView+Internal.m"; sourceTree = ""; }; - 30BC39D87A2A7DB8BA697925454B1880 /* FIROptionsInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIROptionsInternal.h; path = Firebase/Core/Private/FIROptionsInternal.h; sourceTree = ""; }; - 30EC85B249403A7FDD744964E3B64C8D /* libPods-KalendTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libPods-KalendTests.a"; path = "libPods-KalendTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 304BBCFDADDF0EDDFD3A6000BC94FE7D /* FIRDatabaseComponent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDatabaseComponent.h; path = Firebase/Database/Api/FIRDatabaseComponent.h; sourceTree = ""; }; + 30D6BEA3A2C59F3B59B748B9C5DA5AF1 /* env_posix_test_helper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = env_posix_test_helper.h; path = util/env_posix_test_helper.h; sourceTree = ""; }; 30F867DF6C4A1BFC4127CE2948C92A03 /* RCTBorderStyle.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTBorderStyle.h; sourceTree = ""; }; 310762F9BD551FCE1265F8B7AEA14FA9 /* RCTConvert+Text.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "RCTConvert+Text.h"; path = "Libraries/Text/RCTConvert+Text.h"; sourceTree = ""; }; 3132C81E876E07E8E9B087ED105368CB /* ModuleRegistry.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = ModuleRegistry.cpp; path = ReactCommon/cxxreact/ModuleRegistry.cpp; sourceTree = ""; }; - 317D105DF47B8D3BA7ED9A9D6EFBC466 /* libGoogleToolboxForMac.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libGoogleToolboxForMac.a; path = libGoogleToolboxForMac.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 3139F2E895812FCE53080ADF53B3B0D0 /* Demangle.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = Demangle.cpp; path = folly/Demangle.cpp; sourceTree = ""; }; + 317A540B41EBF84D2B70A726EE91CD5F /* FIRMessagingCheckinService.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingCheckinService.m; path = Firebase/Messaging/FIRMessagingCheckinService.m; sourceTree = ""; }; + 317A7F3B0FB2B5E365D3120C3A197A7D /* FCancelEvent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FCancelEvent.h; path = Firebase/Database/Core/View/FCancelEvent.h; sourceTree = ""; }; + 317F07FF03994881B20CF2F7178180EA /* NSDictionary+FIRMessaging.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSDictionary+FIRMessaging.m"; path = "Firebase/Messaging/NSDictionary+FIRMessaging.m"; sourceTree = ""; }; 31B9876795C497C2401DBC409B70C41D /* LOTLayerGroup.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTLayerGroup.m; sourceTree = ""; }; + 3236036995BCE087A642F3AEB2328A4B /* two_level_iterator.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = two_level_iterator.cc; path = table/two_level_iterator.cc; sourceTree = ""; }; + 32739C50B1DCE959A410D8A13BD08B65 /* FSyncTree.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FSyncTree.h; path = Firebase/Database/Core/FSyncTree.h; sourceTree = ""; }; 3283ED2A78CAF4FC9ADFA07A66E235CD /* ARTShape.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ARTShape.h; path = Libraries/ART/ARTShape.h; sourceTree = ""; }; + 329BD46423F50005F2F603C45F8A03CE /* FLLRBEmptyNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FLLRBEmptyNode.h; path = Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBEmptyNode.h; sourceTree = ""; }; + 32A0B6720F9A5E7B16DF805BAC9B4BE5 /* GTMNSDictionary+URLArguments.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "GTMNSDictionary+URLArguments.h"; path = "Foundation/GTMNSDictionary+URLArguments.h"; sourceTree = ""; }; + 32D626A4D1610ABDE8CEF2647EB63976 /* FWebSocketConnection.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FWebSocketConnection.h; path = Firebase/Database/Realtime/FWebSocketConnection.h; sourceTree = ""; }; 32DEF137DA3C62D37ABC663B89E7A21F /* RCTTransformAnimatedNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTTransformAnimatedNode.m; sourceTree = ""; }; 32F5E016D93E5F7ACE3242CC25AE3BAD /* RCTSurfaceView.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTSurfaceView.mm; sourceTree = ""; }; - 335250B47DC62B5D209ED0E7B499E7D5 /* GULAppEnvironmentUtil.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULAppEnvironmentUtil.h; path = GoogleUtilities/Environment/third_party/GULAppEnvironmentUtil.h; sourceTree = ""; }; + 3324B1E18650F1EA8A0408F7CE1B3B04 /* dbformat.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = dbformat.h; path = db/dbformat.h; sourceTree = ""; }; 335D303B610AA3BF2E75EC830AF46A91 /* LOTAssetGroup.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTAssetGroup.h; sourceTree = ""; }; + 33616753739FB63382C4F65ECE442123 /* FPersistenceManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FPersistenceManager.h; path = Firebase/Database/Persistence/FPersistenceManager.h; sourceTree = ""; }; 33677BAA7A4403589F38035004F76073 /* RCTSurface.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTSurface.mm; sourceTree = ""; }; 33C20E6ACD6DEF8A107EAF74125A0A78 /* RCTCxxConvert.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTCxxConvert.m; sourceTree = ""; }; + 33E3B98582281B282D18F8BC608009B3 /* raw_logging.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = raw_logging.h; path = src/glog/raw_logging.h; sourceTree = ""; }; + 33EE705BF112EC3B7C1E67E9E0B858F2 /* FIROptions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIROptions.m; path = Firebase/Core/FIROptions.m; sourceTree = ""; }; 340145309578C08B4F2AE4B56488E2C8 /* RCTLayoutAnimationGroup.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTLayoutAnimationGroup.m; sourceTree = ""; }; 346ED9A09FF573F0481536CEDE22A26F /* RNFetchBlobNetwork.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNFetchBlobNetwork.h; path = ios/RNFetchBlobNetwork.h; sourceTree = ""; }; 34BDF9CC5F54E3FC924C3B13CEF34797 /* RNCSlider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNCSlider.h; path = ios/RNCSlider.h; sourceTree = ""; }; - 350524E76529714B8516ED0B3AB7635C /* GULNetwork.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetwork.h; path = GoogleUtilities/Network/Private/GULNetwork.h; sourceTree = ""; }; + 34F22203D7EEA6D4715E45F6FE625DAF /* FCacheNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FCacheNode.m; path = Firebase/Database/Core/View/FCacheNode.m; sourceTree = ""; }; 350C32D80852C78B7284508AF930D643 /* RNForceTouchHandler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RNForceTouchHandler.m; sourceTree = ""; }; + 3535EA46EDD3D96558DC4A1026C4DE0F /* format.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = format.h; path = table/format.h; sourceTree = ""; }; 35495CD4CFD0E68DE646E26EB6FC2197 /* RCTImageUtils.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTImageUtils.h; path = Libraries/Image/RCTImageUtils.h; sourceTree = ""; }; 354F3741B3D98EF94AEFE9A3A72118C5 /* RCTTouchEvent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTTouchEvent.h; sourceTree = ""; }; 355E84A45297B185E85080801ED38C24 /* RCTSegmentedControlManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTSegmentedControlManager.m; sourceTree = ""; }; + 356D1F2C7C8203EA4BA904A0766E18B5 /* FTuplePathValue.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTuplePathValue.h; path = Firebase/Database/Utilities/Tuples/FTuplePathValue.h; sourceTree = ""; }; + 3580EB0D6BC1342D553F04112A5AED34 /* GTMNSString+URLArguments.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "GTMNSString+URLArguments.m"; path = "Foundation/GTMNSString+URLArguments.m"; sourceTree = ""; }; 358580AC267FE5D8CBD704501611FDC4 /* RCTModalHostViewController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTModalHostViewController.m; sourceTree = ""; }; 358E1AF673F7E4D22349DC10E2CEB46F /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE; sourceTree = ""; }; 3591100D83359EA796A9E1D182A9825B /* RCTImageBlurUtils.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTImageBlurUtils.h; path = Libraries/Image/RCTImageBlurUtils.h; sourceTree = ""; }; - 359ED3EAF36B84F77497C0D3990E3302 /* FIRVersion.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRVersion.m; path = Firebase/Core/FIRVersion.m; sourceTree = ""; }; 35CC5C005C98B39B79281E11E9E4BB01 /* RNCameraUtils.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNCameraUtils.h; path = ios/RN/RNCameraUtils.h; sourceTree = ""; }; + 35FC9E3E1747E42F7199467986DEEFE3 /* FCompleteChildSource.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FCompleteChildSource.h; path = Firebase/Database/Core/View/Filter/FCompleteChildSource.h; sourceTree = ""; }; 35FFD27CEADB92D4B72AE5754CF4E05C /* ARTShape.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = ARTShape.m; path = Libraries/ART/ARTShape.m; sourceTree = ""; }; 36608B3AA94AA71EC4319C20BB1DD3EB /* LOTLayerContainer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTLayerContainer.h; sourceTree = ""; }; 3666410D49626387A684F88995E542A4 /* RCTInputAccessoryShadowView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTInputAccessoryShadowView.m; sourceTree = ""; }; 36F0B66E287C6ADDC28307A83785D71D /* JSBigString.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = JSBigString.cpp; path = ReactCommon/cxxreact/JSBigString.cpp; sourceTree = ""; }; + 36F3D1B3B7B29DDC9BAB3591E2F2A9DC /* GPBDescriptor_PackagePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBDescriptor_PackagePrivate.h; path = objectivec/GPBDescriptor_PackagePrivate.h; sourceTree = ""; }; 36FA96CCD99684D69DA24C66A94FAE26 /* RCTModalHostView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTModalHostView.h; sourceTree = ""; }; + 3704EE2DB67187CDD6B387F348CB41D0 /* FIROptions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIROptions.h; path = Firebase/Core/Public/FIROptions.h; sourceTree = ""; }; 371AA013D82181933B52A942BBEC2174 /* RCTAutoInsetsProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTAutoInsetsProtocol.h; sourceTree = ""; }; - 37967DC16FAFA16E418FAA5795D66DB3 /* double-conversion.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "double-conversion.h"; path = "double-conversion/double-conversion.h"; sourceTree = ""; }; + 37ABB67EB8FC12697EBA5E61AB7D193D /* Duration.pbobjc.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = Duration.pbobjc.m; path = objectivec/google/protobuf/Duration.pbobjc.m; sourceTree = ""; }; 37EFDEDDEC049394460B8F0E470BF41D /* RCTModuleMethod.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTModuleMethod.mm; sourceTree = ""; }; + 37F2C52AF05B020D5CD6CC5800BF1E2D /* GULAppEnvironmentUtil.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULAppEnvironmentUtil.m; path = GoogleUtilities/Environment/third_party/GULAppEnvironmentUtil.m; sourceTree = ""; }; + 3822BBD2EAF04D86C912BA9D549D6B34 /* Empty.pbobjc.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Empty.pbobjc.h; path = objectivec/google/protobuf/Empty.pbobjc.h; sourceTree = ""; }; 38495E8EE2C723FE63F1EB3050A903D4 /* RCTJavaScriptLoader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTJavaScriptLoader.h; sourceTree = ""; }; + 389E3FCACF1C1E456B1E409DB7E730BF /* FIRMessagingVersionUtilities.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingVersionUtilities.m; path = Firebase/Messaging/FIRMessagingVersionUtilities.m; sourceTree = ""; }; 38ABD9EF28C0E496F8D7B970A40253E8 /* ReactMarker.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = ReactMarker.cpp; path = ReactCommon/cxxreact/ReactMarker.cpp; sourceTree = ""; }; + 3953E080065D0ACBDC5447B414FF10C2 /* FTupleOnDisconnect.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTupleOnDisconnect.h; path = Firebase/Database/Utilities/Tuples/FTupleOnDisconnect.h; sourceTree = ""; }; 3967DC89715ACB7F63847339AA56D3A1 /* RCTShadowView+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RCTShadowView+Internal.h"; sourceTree = ""; }; - 399AC2DD582FFA867EB3094A2FEC06A8 /* GPBArray.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBArray.m; path = objectivec/GPBArray.m; sourceTree = ""; }; 39B32BB5D0A26142E513079EBA428BCA /* RNGestureHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNGestureHandler.h; path = ios/RNGestureHandler.h; sourceTree = ""; }; 39C651A996DC0FA83F18E9A22B4CD303 /* CGGeometry+LOTAdditions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CGGeometry+LOTAdditions.h"; sourceTree = ""; }; - 39F9AFCFBFF9F81F427E737A4D3DFAE2 /* glog.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = glog.xcconfig; sourceTree = ""; }; + 39F99C7DB7E3135595E3B4FA528D8CCF /* log_format.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = log_format.h; path = db/log_format.h; sourceTree = ""; }; + 3A71E9CEC1419826CB35B97C1AA689F8 /* FIRMessagingRmq2PersistentStore.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingRmq2PersistentStore.m; path = Firebase/Messaging/FIRMessagingRmq2PersistentStore.m; sourceTree = ""; }; + 3A7BA2DCF1D8BC5B1D2E1B940D8066D1 /* FTransformedEnumerator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTransformedEnumerator.h; path = Firebase/Database/FTransformedEnumerator.h; sourceTree = ""; }; 3A7FD36CD8B0DDBD2D2B211B252A8F93 /* CompactValue.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CompactValue.h; path = yoga/CompactValue.h; sourceTree = ""; }; 3A858624BA6720E250FB69F3157BB5B2 /* RNFetchBlobRequest.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNFetchBlobRequest.h; path = ios/RNFetchBlobRequest.h; sourceTree = ""; }; 3A874F9D8CA0329C9D492D46CEB3C103 /* DispatchMessageQueueThread.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = DispatchMessageQueueThread.h; sourceTree = ""; }; + 3AC89BACB5F8AA89ED44F24D013259E2 /* Fabric.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Fabric.xcconfig; sourceTree = ""; }; 3AC9869F42735E2629B487533BB101C8 /* RCTUIManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTUIManager.h; sourceTree = ""; }; - 3AD64AEC8F88EDF0FBA67499A8E1BAC3 /* pb_common.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = pb_common.h; sourceTree = ""; }; - 3B457FAC86A7D2B564DEC7B9230B1745 /* SourceContext.pbobjc.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SourceContext.pbobjc.h; path = objectivec/google/protobuf/SourceContext.pbobjc.h; sourceTree = ""; }; + 3B0E712AC4E399D821909DFA5AC02342 /* port_posix_sse.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = port_posix_sse.cc; path = port/port_posix_sse.cc; sourceTree = ""; }; + 3B2C069F9D6B52B8EB4CD32898783208 /* status.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = status.cc; path = util/status.cc; sourceTree = ""; }; 3B65BEDF98A9DC36BAE9E390414D143A /* RCTDevLoadingView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTDevLoadingView.h; sourceTree = ""; }; + 3B690A9359A398B343537A429DBDF0F9 /* GPBRootObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBRootObject.h; path = objectivec/GPBRootObject.h; sourceTree = ""; }; + 3B691314C201B650B478BF0309DE70A5 /* GULNetwork.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetwork.h; path = GoogleUtilities/Network/Private/GULNetwork.h; sourceTree = ""; }; 3B836199A12F73E910B7A5628A0108F1 /* JSCExecutorFactory.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = JSCExecutorFactory.h; sourceTree = ""; }; + 3BD51FC68A9B78174E2EDEB72D9BE395 /* DoubleConversion-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "DoubleConversion-prefix.pch"; sourceTree = ""; }; 3BD674B4A2113D3D42D1ABC50E8FDDE1 /* RCTSourceCode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSourceCode.h; sourceTree = ""; }; 3C0872A90B2BA40CEF9E18D168D08A48 /* RNGestureHandlerEvents.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNGestureHandlerEvents.m; path = ios/RNGestureHandlerEvents.m; sourceTree = ""; }; 3C0899B8F85D0B2E2676EBE3FFE12351 /* fishhook.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = fishhook.h; path = Libraries/fishhook/fishhook.h; sourceTree = ""; }; - 3C95E73D25734090CEB4C2607EC3804F /* cached-powers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "cached-powers.h"; path = "double-conversion/cached-powers.h"; sourceTree = ""; }; + 3CB542AB89073932BBB2EABF4DFD6836 /* options.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = options.cc; path = util/options.cc; sourceTree = ""; }; + 3CB5D828593D472D95DB8470B5489622 /* FIRMessagingSyncMessageManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingSyncMessageManager.m; path = Firebase/Messaging/FIRMessagingSyncMessageManager.m; sourceTree = ""; }; + 3CBE8B32C08136207C1ED4E64F1E7C30 /* table.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = table.h; path = include/leveldb/table.h; sourceTree = ""; }; + 3CCD6F717B705096084DE94D831AD5DC /* env.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = env.cc; path = util/env.cc; sourceTree = ""; }; + 3CD58A35D4D5CEA9C36AE6EEB064AC42 /* GTMSessionFetcherService.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMSessionFetcherService.h; path = Source/GTMSessionFetcherService.h; sourceTree = ""; }; + 3CF3157877D482C5AE976CC59518658E /* FieldMask.pbobjc.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FieldMask.pbobjc.m; path = objectivec/google/protobuf/FieldMask.pbobjc.m; sourceTree = ""; }; 3D1E099506200348C65A2B01768F6FD4 /* RNGestureHandlerManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNGestureHandlerManager.m; path = ios/RNGestureHandlerManager.m; sourceTree = ""; }; - 3D481A2FEFDEC6C0F85F9CF98283BE9A /* FABAttributes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FABAttributes.h; path = iOS/Fabric.framework/Headers/FABAttributes.h; sourceTree = ""; }; 3D68CB009F69DAC3C0B3B0139FE88276 /* MethodCall.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MethodCall.h; path = ReactCommon/cxxreact/MethodCall.h; sourceTree = ""; }; 3D8B2472D47EE2975E0761212822EA32 /* YGMarker.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = YGMarker.cpp; path = yoga/YGMarker.cpp; sourceTree = ""; }; 3D95ADA61F5850D55FFE5C051C6EB34B /* YGMacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = YGMacros.h; path = yoga/YGMacros.h; sourceTree = ""; }; 3DB5D178A64571DC2782E0EE7028B96C /* RCTNativeAnimatedNodesManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTNativeAnimatedNodesManager.m; path = Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.m; sourceTree = ""; }; 3DC54162C7D5787B5F594D8311012868 /* RCTView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTView.h; sourceTree = ""; }; 3DE8F1C0381736C414E36B5246102866 /* Entypo.ttf */ = {isa = PBXFileReference; includeInIndex = 1; name = Entypo.ttf; path = Fonts/Entypo.ttf; sourceTree = ""; }; + 3E009D4735C805CED8A49BDC00DA9679 /* db_iter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = db_iter.h; path = db/db_iter.h; sourceTree = ""; }; 3E110645A6A25907F1D5F71BCFACD145 /* RCTManagedPointer.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTManagedPointer.mm; sourceTree = ""; }; - 3E2631576F7A1002CC3B12FA44368A76 /* GTMNSData+zlib.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "GTMNSData+zlib.h"; path = "Foundation/GTMNSData+zlib.h"; sourceTree = ""; }; 3E26A16EB9930837A5C4EBA6D2ACA06D /* RCTErrorInfo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTErrorInfo.m; sourceTree = ""; }; 3E7846B3067043205EAB371A4A7DFC21 /* Pods-Kalend.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Kalend.debug.xcconfig"; sourceTree = ""; }; - 3E822D3712B9F2508695B633714B57B3 /* GULAppDelegateSwizzler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULAppDelegateSwizzler.h; path = GoogleUtilities/AppDelegateSwizzler/Private/GULAppDelegateSwizzler.h; sourceTree = ""; }; 3ECBFC304C0A4E3357B5D2DF819C26FE /* RCTScrollContentShadowView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTScrollContentShadowView.m; sourceTree = ""; }; - 3F53BFB4A05790B07429F81FDFC82E28 /* GPBDescriptor_PackagePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBDescriptor_PackagePrivate.h; path = objectivec/GPBDescriptor_PackagePrivate.h; sourceTree = ""; }; + 3EF52EC3FC7F93B8DA1F7CB9F131FF8E /* FConstants.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FConstants.h; path = Firebase/Database/Constants/FConstants.h; sourceTree = ""; }; + 3F21A75ECC7FA892F2FDD35E53B8B217 /* FirebaseInstanceID.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseInstanceID.framework; path = Frameworks/FirebaseInstanceID.framework; sourceTree = ""; }; + 3F285B33466F8251D8487BB461AB15F3 /* GPBDictionary.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBDictionary.m; path = objectivec/GPBDictionary.m; sourceTree = ""; }; + 3F2F365D934F6305BB1F840BA46B96D5 /* memtable.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = memtable.cc; path = db/memtable.cc; sourceTree = ""; }; + 3F40208B1F0DC24CAF70925FE733EE42 /* iterator_wrapper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = iterator_wrapper.h; path = table/iterator_wrapper.h; sourceTree = ""; }; + 3F5F074174924D93C197546B8037001E /* dbformat.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = dbformat.cc; path = db/dbformat.cc; sourceTree = ""; }; 3F6F507BDCE092203FD8A96184842EC7 /* ARTRadialGradient.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = ARTRadialGradient.m; sourceTree = ""; }; + 3FB6DE326DCEDAD8854CB441D76ADA23 /* GULNetworkURLSession.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkURLSession.h; path = GoogleUtilities/Network/Private/GULNetworkURLSession.h; sourceTree = ""; }; 3FC7E18D44F599E0A2115E29EAFB55B1 /* LOTComposition.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTComposition.h; sourceTree = ""; }; + 3FE8D8BD4DB7927197E7B596371BCEC6 /* FCompoundWrite.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FCompoundWrite.h; path = Firebase/Database/Snapshot/FCompoundWrite.h; sourceTree = ""; }; + 3FE9EFF9530C76BC0428F708BDEF0D16 /* FIndexedFilter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIndexedFilter.m; path = Firebase/Database/Core/View/Filter/FIndexedFilter.m; sourceTree = ""; }; 3FEBD5C9C01BC81616CF51782FE941B2 /* RCTVersion.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTVersion.h; sourceTree = ""; }; + 3FEFA415177BF93D444343263FB71D2B /* FServerValues.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FServerValues.m; path = Firebase/Database/Core/FServerValues.m; sourceTree = ""; }; + 4026413238A48D0FEA34D02E3F2C199C /* FWriteTreeRef.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FWriteTreeRef.h; path = Firebase/Database/Core/FWriteTreeRef.h; sourceTree = ""; }; 404C190CC8198E5D961D90022D883B23 /* RCTSegmentedControl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSegmentedControl.h; sourceTree = ""; }; + 40799FECEBD3623D6C8B1C70ED1823BA /* filter_block.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = filter_block.cc; path = table/filter_block.cc; sourceTree = ""; }; 4095214014C09337822E347037EE75D0 /* RCTViewManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTViewManager.h; sourceTree = ""; }; 40B36309908A3A11AA696B9A29C11A29 /* RCTRawTextShadowView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTRawTextShadowView.m; sourceTree = ""; }; - 40E19694FE31A1B80E73A68B32E53D48 /* GPBRootObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBRootObject.m; path = objectivec/GPBRootObject.m; sourceTree = ""; }; 40F3AB45973140BD4CA31F022691E763 /* JsArgumentHelpers-inl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "JsArgumentHelpers-inl.h"; path = "ReactCommon/cxxreact/JsArgumentHelpers-inl.h"; sourceTree = ""; }; - 4153397B595713F36B71DB3D53A7F8B9 /* FIRLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLogger.h; path = Firebase/Core/Private/FIRLogger.h; sourceTree = ""; }; + 412FAA9B45D3BC5F377824D97A606828 /* GoogleUtilities-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "GoogleUtilities-prefix.pch"; sourceTree = ""; }; + 4137D29173DFD982B0C4FBA1F5733874 /* FNamedNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FNamedNode.m; path = Firebase/Database/FNamedNode.m; sourceTree = ""; }; 41928F9CEA164E82386F4C2DBA176D24 /* RCTURLRequestDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTURLRequestDelegate.h; sourceTree = ""; }; - 41C13D3D29D39FB608EB5F98BEACAB05 /* FIRConfiguration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRConfiguration.h; path = Firebase/Core/Public/FIRConfiguration.h; sourceTree = ""; }; + 419AD5D765BE6240880B0DED4704566F /* APLevelDB.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = APLevelDB.h; path = "Firebase/Database/third_party/Wrap-leveldb/APLevelDB.h"; sourceTree = ""; }; 41F6867BAF6A6626200CA74B50E84F1C /* LOTCacheProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTCacheProvider.h; sourceTree = ""; }; + 42174118D83E777F4DC7503F4BADCDDF /* FViewProcessorResult.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FViewProcessorResult.m; path = Firebase/Database/FViewProcessorResult.m; sourceTree = ""; }; + 421A08E7B9F97963B5D038C345894614 /* GTMSessionFetcherLogging.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTMSessionFetcherLogging.m; path = Source/GTMSessionFetcherLogging.m; sourceTree = ""; }; + 4229147F5CEA195DD7119238617BA3A1 /* GPBUnknownField.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBUnknownField.m; path = objectivec/GPBUnknownField.m; sourceTree = ""; }; 42664DE328C63EC3EDAE283C7D004071 /* RCTSurfaceView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSurfaceView.h; sourceTree = ""; }; 42664F57FEAC8CCF1ED5C28F6D5ABE90 /* InspectorInterfaces.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = InspectorInterfaces.cpp; path = ReactCommon/jsinspector/InspectorInterfaces.cpp; sourceTree = ""; }; - 42CE6557E4770B5F0D1F2C2B81F80F97 /* GULLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULLogger.h; path = GoogleUtilities/Logger/Private/GULLogger.h; sourceTree = ""; }; + 42A113B02397B96427B9C3AFE74CB9BD /* options.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = options.h; path = include/leveldb/options.h; sourceTree = ""; }; + 42DA9DA5A3D5DB14678F48C2A1FDC942 /* FIRMessagingConstants.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingConstants.m; path = Firebase/Messaging/FIRMessagingConstants.m; sourceTree = ""; }; 43023DF2386FBE3F4BBBCB542912D016 /* RCTFont+FA5.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "RCTFont+FA5.h"; path = "RNVectorIconsManager/RCTFont+FA5.h"; sourceTree = ""; }; 4316C0A63F69747996783CF7CE0283B1 /* RCTDivisionAnimatedNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTDivisionAnimatedNode.h; sourceTree = ""; }; 43250E80F4D3221A309BBA5C8E20BDB1 /* RNFetchBlobConst.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNFetchBlobConst.h; path = ios/RNFetchBlobConst.h; sourceTree = ""; }; 432B068DE5FB4AAE0865A421A5F3009C /* YGMarker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = YGMarker.h; path = yoga/YGMarker.h; sourceTree = ""; }; 43381773DD19FA49B450440B73C47B38 /* Community 2_3.gif */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.gif; name = "Community 2_3.gif"; path = "docs/gifs/Community 2_3.gif"; sourceTree = ""; }; - 43497B573E91EF51113E2EEBC8C1EC96 /* GPBProtocolBuffers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBProtocolBuffers.h; path = objectivec/GPBProtocolBuffers.h; sourceTree = ""; }; + 433A22FA442B112CC55C0E2F3A3BD38D /* FEventGenerator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FEventGenerator.m; path = Firebase/Database/FEventGenerator.m; sourceTree = ""; }; 437CBC6F45F9C301B9440D883975E358 /* RCTInspectorPackagerConnection.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTInspectorPackagerConnection.h; sourceTree = ""; }; 4388312B78481D9F9DDBAF8615F67F6B /* RCTConvert+Transform.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+Transform.h"; sourceTree = ""; }; + 43C31F092679C01E2C9CE96EBAA48663 /* FRangedFilter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FRangedFilter.m; path = Firebase/Database/FRangedFilter.m; sourceTree = ""; }; 43E60D5D989B41E99312ECC278204378 /* RCTUIManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTUIManager.m; sourceTree = ""; }; 43F50708D562369FD044BAD3C270F45E /* LOTStrokeRenderer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTStrokeRenderer.h; sourceTree = ""; }; + 43FAF91300BB0C423267A829E54A3897 /* GTMDefines.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = GTMDefines.h; sourceTree = ""; }; 442A4479A2D25B5166A4FAAB6638FD4F /* RCTSurfaceHostingView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSurfaceHostingView.h; sourceTree = ""; }; + 4432B5DE12A0775BABA5B5E3B961116C /* FImmutableTree.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FImmutableTree.h; path = Firebase/Database/Core/Utilities/FImmutableTree.h; sourceTree = ""; }; 44442BC6515E65477B31119F35936B14 /* HamburgerArrow.gif */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.gif; name = HamburgerArrow.gif; path = docs/gifs/HamburgerArrow.gif; sourceTree = ""; }; + 444573A933F954E270941208E387DEAE /* write_batch.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = write_batch.cc; path = db/write_batch.cc; sourceTree = ""; }; + 4457F2FAE5F4B126775B3F4783243322 /* FTreeNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTreeNode.h; path = Firebase/Database/Core/Utilities/FTreeNode.h; sourceTree = ""; }; + 445CCC9B3DDFCC1034CA6BC4F856C306 /* FOverwrite.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FOverwrite.h; path = Firebase/Database/Core/Operation/FOverwrite.h; sourceTree = ""; }; 44C9DD523C62CEE9C68EE24148B935A2 /* yoga-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "yoga-dummy.m"; sourceTree = ""; }; 44E2AF7684191EFD1A9D338205C5E64A /* RCTKeyboardObserver.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTKeyboardObserver.h; sourceTree = ""; }; 4504FA11559835ADFAB0362A2D32DCA2 /* LOTHelpers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTHelpers.h; sourceTree = ""; }; - 4576960A63CAA9F4F93A4A177389016E /* SpookyHashV2.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = SpookyHashV2.cpp; path = folly/hash/SpookyHashV2.cpp; sourceTree = ""; }; + 4589D5B88D4AE0FE6E7B2DB709F25865 /* FirebaseDatabase-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FirebaseDatabase-dummy.m"; sourceTree = ""; }; 458BF14601CB10A44C586D9DB33A9A7B /* RCTNetInfo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTNetInfo.h; path = Libraries/Network/RCTNetInfo.h; sourceTree = ""; }; + 459829D2EDDEE906B8986B8464589100 /* FIRMessagingLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingLogger.m; path = Firebase/Messaging/FIRMessagingLogger.m; sourceTree = ""; }; + 4598E8CE21EEF42BE2584DBA6FCC11F1 /* pb_common.c */ = {isa = PBXFileReference; includeInIndex = 1; path = pb_common.c; sourceTree = ""; }; 459AD113A1D87FD52F8568A2DD75DB85 /* RCTSubtractionAnimatedNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTSubtractionAnimatedNode.m; sourceTree = ""; }; 45A392302A405B0BF159FBEDA479AC2B /* RCTPackagerClient.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTPackagerClient.m; sourceTree = ""; }; 45A44884388E4BB5947F6777276394DF /* LottieLogo2.gif */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.gif; name = LottieLogo2.gif; path = docs/gifs/LottieLogo2.gif; sourceTree = ""; }; @@ -2055,94 +2719,126 @@ 460ADA466C1DDA3792167EFC6B825121 /* RCTSwitchManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTSwitchManager.m; sourceTree = ""; }; 460D0B7487E6617FA7B85B894612A8DF /* ModuleRegistry.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ModuleRegistry.h; path = ReactCommon/cxxreact/ModuleRegistry.h; sourceTree = ""; }; 4682CCFAFBB7EE666C6D02FE68F65401 /* RCTActivityIndicatorViewManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTActivityIndicatorViewManager.m; sourceTree = ""; }; + 468E1DA4FDB85768910BD3669FBB8A51 /* version_set.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = version_set.h; path = db/version_set.h; sourceTree = ""; }; + 469B99E535C3387F64B9842052BCDCC5 /* FNamedNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FNamedNode.h; path = Firebase/Database/FNamedNode.h; sourceTree = ""; }; 46A555741AC2B507F159D654AD368AB7 /* LRNContainerView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = LRNContainerView.h; path = src/ios/LottieReactNative/LRNContainerView.h; sourceTree = ""; }; - 46B7B4C6643F5C8189C5AA84D4591DA3 /* logging.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = logging.cc; path = src/logging.cc; sourceTree = ""; }; + 46A977D12AD3E74855601EDFF339278D /* libReact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libReact.a; path = libReact.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 46D34415B6A31D4D3C4CFE3135387179 /* Any.pbobjc.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = Any.pbobjc.m; path = objectivec/google/protobuf/Any.pbobjc.m; sourceTree = ""; }; + 46E4423D5D97E60BC8EB6AE0F8F7BBAE /* FirebaseCoreDiagnostics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseCoreDiagnostics.framework; path = Frameworks/FirebaseCoreDiagnostics.framework; sourceTree = ""; }; 471256E31D0FB00CD281E6DE5E334F0C /* RCTPickerManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTPickerManager.m; sourceTree = ""; }; - 476BF08F77E75BD5FA8165A67387DFF1 /* libPods-Kalend.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libPods-Kalend.a"; path = "libPods-Kalend.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 473169B7B5260E7DB0EF41FC5FE82E1F /* FSparseSnapshotTree.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FSparseSnapshotTree.m; path = Firebase/Database/Core/FSparseSnapshotTree.m; sourceTree = ""; }; + 473DDD131AFF23C0382BA90B4DF19C03 /* libGoogleToolboxForMac.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libGoogleToolboxForMac.a; path = libGoogleToolboxForMac.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 475AF4973905C1161DF33535253E26E6 /* GPBRuntimeTypes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBRuntimeTypes.h; path = objectivec/GPBRuntimeTypes.h; sourceTree = ""; }; + 4785EB3ACEC0E8CCA1161262C30079BD /* GPBCodedInputStream_PackagePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBCodedInputStream_PackagePrivate.h; path = objectivec/GPBCodedInputStream_PackagePrivate.h; sourceTree = ""; }; 47B394892FA45C8D28A7A57E8CB2814A /* GradleUpgradeGuide.md */ = {isa = PBXFileReference; includeInIndex = 1; name = GradleUpgradeGuide.md; path = docs/GradleUpgradeGuide.md; sourceTree = ""; }; - 48659E513214C479B4B888D3B8350612 /* FIRAnalyticsConnector.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FIRAnalyticsConnector.framework; path = Frameworks/FIRAnalyticsConnector.framework; sourceTree = ""; }; + 47F15902BABCC392AE6231BBABBFE856 /* snapshot.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = snapshot.h; path = db/snapshot.h; sourceTree = ""; }; 48BE908F97E50EA448532A3A42C775D2 /* LOTAsset.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTAsset.m; sourceTree = ""; }; + 48C04CC3873113348843DA33D0D9C28F /* FWriteRecord.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FWriteRecord.h; path = Firebase/Database/Core/FWriteRecord.h; sourceTree = ""; }; 48E42E5379BC970766D176AA774BFDF8 /* LOTRoundedRectAnimator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTRoundedRectAnimator.m; sourceTree = ""; }; + 49074C2E5E4EA6ED6EB392FB200135AE /* Folly-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Folly-dummy.m"; sourceTree = ""; }; 4915E4B99108F26BABCE6B35F1A5D46A /* RNCamera.md */ = {isa = PBXFileReference; includeInIndex = 1; name = RNCamera.md; path = docs/RNCamera.md; sourceTree = ""; }; 49194903D29AA4A078E54FE287F5D24C /* LOTStrokeRenderer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTStrokeRenderer.m; sourceTree = ""; }; + 493D4839B109B1EF43AA9A203C9EAF78 /* Wrappers.pbobjc.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = Wrappers.pbobjc.m; path = objectivec/google/protobuf/Wrappers.pbobjc.m; sourceTree = ""; }; + 497DC3EC24F8F871BE484C8E6E675FB9 /* FWriteTree.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FWriteTree.m; path = Firebase/Database/Core/FWriteTree.m; sourceTree = ""; }; 49A575D5C16F64CF2CE30FDB249FA60D /* RCTWebSocketExecutor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTWebSocketExecutor.h; path = Libraries/WebSocket/RCTWebSocketExecutor.h; sourceTree = ""; }; - 49CA8FF288BF1DD519D78B70E988EC17 /* GoogleSignIn.bundle */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "wrapper.plug-in"; name = GoogleSignIn.bundle; path = Resources/GoogleSignIn.bundle; sourceTree = ""; }; 49CC0613AA6BD518F8981EF0D7DAED34 /* RCTInputAccessoryViewContent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTInputAccessoryViewContent.m; sourceTree = ""; }; 49FC27F61E472DA6AA264A341768C1CA /* RCTLocalAssetImageLoader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTLocalAssetImageLoader.m; path = Libraries/Image/RCTLocalAssetImageLoader.m; sourceTree = ""; }; 49FD4AA449D624ED888B9D3357AE7BEB /* RNGestureHandlerModule.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNGestureHandlerModule.h; path = ios/RNGestureHandlerModule.h; sourceTree = ""; }; - 4A1D2BA8A36579D7C6ACF5802A9A4F87 /* FirebaseCore.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseCore.xcconfig; sourceTree = ""; }; - 4A4E6E17CDE7E172CD43CCC6944BD67A /* GPBUnknownFieldSet.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBUnknownFieldSet.h; path = objectivec/GPBUnknownFieldSet.h; sourceTree = ""; }; 4ABED5AE524DC2C875206C90BEB95684 /* RCTView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTView.m; sourceTree = ""; }; - 4B166C99A5BAB626C5AE7A6B572EA8F1 /* GTMDefines.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = GTMDefines.h; sourceTree = ""; }; - 4B7B0F102C88F6DAF4C3966658C3C929 /* GPBCodedInputStream.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBCodedInputStream.h; path = objectivec/GPBCodedInputStream.h; sourceTree = ""; }; + 4B073494BCE05F22ECA7AAAD5ECC6F1F /* FCompoundHash.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FCompoundHash.m; path = Firebase/Database/Core/FCompoundHash.m; sourceTree = ""; }; + 4B3BD5ABF14EA65C9DCE54CAD425A6F6 /* posix_logger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = posix_logger.h; path = util/posix_logger.h; sourceTree = ""; }; 4B8E39E05CEDE3BAB149A097CF036769 /* RCTNativeAnimatedNodesManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTNativeAnimatedNodesManager.h; path = Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.h; sourceTree = ""; }; + 4BC0964039A18391158C331D4DB21FD4 /* FTupleOnDisconnect.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FTupleOnDisconnect.m; path = Firebase/Database/Utilities/Tuples/FTupleOnDisconnect.m; sourceTree = ""; }; 4BCEBA993ACB66EC3B4F9FC0746B1C39 /* RCTInspector.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTInspector.h; sourceTree = ""; }; 4BF753F1A291F75A7AE6B56DD2E388A0 /* UIView+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "UIView+Private.h"; sourceTree = ""; }; 4BFC487AA2EAC55B0D6AF7F9C00AB156 /* RCTSurfaceRootView.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTSurfaceRootView.mm; sourceTree = ""; }; + 4C3A3E65CB073D3D976CBD3F68542942 /* FConstants.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FConstants.m; path = Firebase/Database/Constants/FConstants.m; sourceTree = ""; }; + 4C573707E62D8A5DD5ED310288347C87 /* FIRMessaging.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessaging.m; path = Firebase/Messaging/FIRMessaging.m; sourceTree = ""; }; + 4C745941C2E59521A729ABA0D06C4A96 /* FMerge.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FMerge.m; path = Firebase/Database/Core/Operation/FMerge.m; sourceTree = ""; }; + 4C74E5ED86914ACF3E7DFB35010DE2D5 /* Demangle.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = Demangle.cpp; path = folly/detail/Demangle.cpp; sourceTree = ""; }; 4CAE737D0A15E9855F3B9BC0D20AAE0C /* LOTShapeStar.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTShapeStar.h; sourceTree = ""; }; - 4D058D7A841DF70FCA740AC480BBF35F /* librn-fetch-blob.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "librn-fetch-blob.a"; path = "librn-fetch-blob.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CF512EAEBEB1E1AB12A8A573BEFBA68 /* CLSLogging.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CLSLogging.h; path = iOS/Crashlytics.framework/Headers/CLSLogging.h; sourceTree = ""; }; + 4D161E1BA70F18F152790A436071D295 /* FirebaseCore.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseCore.xcconfig; sourceTree = ""; }; 4D2689C07131170A9DC79F71ED14AB91 /* RCTShadowView+Layout.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "RCTShadowView+Layout.m"; sourceTree = ""; }; - 4D5CAF3D45E732FD8A39342B97FA8FDA /* FirebaseABTesting.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseABTesting.xcconfig; sourceTree = ""; }; - 4D837984DF861DEEF7EB13DB66895A8D /* Protobuf.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Protobuf.xcconfig; sourceTree = ""; }; + 4D5A958ACB4439FA215BE021AE20B0D3 /* FIRErrorCode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRErrorCode.h; path = Firebase/Core/Private/FIRErrorCode.h; sourceTree = ""; }; + 4D63F49AFC33302B0D509F2B6AC99EFD /* port_posix.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = port_posix.h; path = port/port_posix.h; sourceTree = ""; }; + 4D8FD7EDF6E543DB4D9DA88021A5417B /* FLevelDBStorageEngine.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FLevelDBStorageEngine.h; path = Firebase/Database/Persistence/FLevelDBStorageEngine.h; sourceTree = ""; }; + 4DEBEA10243186DD60C9FF25CE3B0850 /* CLSReport.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CLSReport.h; path = iOS/Crashlytics.framework/Headers/CLSReport.h; sourceTree = ""; }; 4E0A8083D1F6D61E7CADFCFEC6B487C4 /* RNRootViewGestureRecognizer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNRootViewGestureRecognizer.m; path = ios/RNRootViewGestureRecognizer.m; sourceTree = ""; }; - 4E464D9BB99F9154986CD67B87B39582 /* GoogleAppMeasurement.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleAppMeasurement.xcconfig; sourceTree = ""; }; - 4EB3BB905ECB39DB9D7D567060436721 /* FIRComponent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponent.h; path = Firebase/Core/Private/FIRComponent.h; sourceTree = ""; }; + 4E6EF280F867455DDB14113B604BA304 /* FRepoManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FRepoManager.h; path = Firebase/Database/Core/FRepoManager.h; sourceTree = ""; }; + 4E8E3FA6B7209E08AAFA8F100C00089D /* FIRComponentRegistrant.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentRegistrant.h; path = Firebase/Core/Private/FIRComponentRegistrant.h; sourceTree = ""; }; 4EC39FF75C03F8EF4C12F41C0D574F19 /* RCTSpringAnimation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSpringAnimation.h; sourceTree = ""; }; + 4EC7FACEF78343F1D452E765198F75FB /* librn-fetch-blob.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "librn-fetch-blob.a"; path = "librn-fetch-blob.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 4EE3AE0D79C2E0FE35D0BBAC95FB44F6 /* RCTEventDispatcher.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTEventDispatcher.m; sourceTree = ""; }; 4F255EECA7833B5B5574BC504489CE8F /* RCTRefreshControlManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTRefreshControlManager.m; sourceTree = ""; }; - 4F29AA4C2EEA95F56F02DA16BB7DC936 /* GoogleAppMeasurement.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GoogleAppMeasurement.framework; path = Frameworks/GoogleAppMeasurement.framework; sourceTree = ""; }; 4F2C481C3BA60E548147700786B22991 /* Pods-KalendTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-KalendTests.debug.xcconfig"; sourceTree = ""; }; + 4F3B40DFBA149C119799DFD182066F9C /* FABAttributes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FABAttributes.h; path = iOS/Fabric.framework/Headers/FABAttributes.h; sourceTree = ""; }; 4F998E92F8BC66D5A786DB4ACEAA93B5 /* YGValue.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = YGValue.cpp; path = yoga/YGValue.cpp; sourceTree = ""; }; + 4F9BB1D579C19AC9E2483A5F07973D6A /* GPBDescriptor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBDescriptor.h; path = objectivec/GPBDescriptor.h; sourceTree = ""; }; 4FBB5B3E944E4FBD37FA4466A28D61A1 /* Pods-KalendTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-KalendTests-dummy.m"; sourceTree = ""; }; - 4FF78D17720D1DF41C6200A4DAA3A4BB /* GPBRuntimeTypes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBRuntimeTypes.h; path = objectivec/GPBRuntimeTypes.h; sourceTree = ""; }; - 5016614A2295D4A10CD95448B0578C11 /* liblottie-react-native.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "liblottie-react-native.a"; path = "liblottie-react-native.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4FCB6D1827727575781B732B26E6B151 /* FPriorityIndex.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FPriorityIndex.h; path = Firebase/Database/FPriorityIndex.h; sourceTree = ""; }; + 4FFDB73167B848BBBD3E423FFEB9183B /* GPBWellKnownTypes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBWellKnownTypes.h; path = objectivec/GPBWellKnownTypes.h; sourceTree = ""; }; + 500D2122A635658F32FE739A31FC4AC2 /* FChange.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FChange.h; path = Firebase/Database/Core/View/FChange.h; sourceTree = ""; }; 501A740F38D382633F06137DB932BED5 /* RCTAccessibilityManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTAccessibilityManager.h; sourceTree = ""; }; 50621C4AB28A88EB35E93245917A8BBB /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE; sourceTree = ""; }; 506D06BA5D3CCECBB07CB08C9000987F /* RCTSpringAnimation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTSpringAnimation.m; sourceTree = ""; }; 507DAB37F96FF3E6A7084936E4E0599E /* RCTPicker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTPicker.h; sourceTree = ""; }; 5091BE2A2FA317E87D81E7342544DC81 /* MethodCall.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = MethodCall.cpp; path = ReactCommon/cxxreact/MethodCall.cpp; sourceTree = ""; }; - 50AD35B3BB2CAE00789A8EEB035CDE08 /* GTMSessionUploadFetcher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMSessionUploadFetcher.h; path = Source/GTMSessionUploadFetcher.h; sourceTree = ""; }; + 50AA96879422B9860DF58C1C5F54ACB9 /* FIRMMessageCode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMMessageCode.h; path = Firebase/Messaging/FIRMMessageCode.h; sourceTree = ""; }; + 50AC883EF355F48FFDB198F26BF0DEB5 /* libPods-Kalend.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libPods-Kalend.a"; path = "libPods-Kalend.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 50D55837BAC6B4441EEF54A3B348C056 /* RCTTouchEvent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTTouchEvent.m; sourceTree = ""; }; 50E3ACA9687A5C84260C13F858BFB2DF /* RCTSurfaceRootView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSurfaceRootView.h; sourceTree = ""; }; - 50F4AE7E1F3A99FA789591FE4516D16F /* fixed-dtoa.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "fixed-dtoa.h"; path = "double-conversion/fixed-dtoa.h"; sourceTree = ""; }; 50FF470BC01770DA20B58E1154277FBA /* RNCameraManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNCameraManager.h; path = ios/RN/RNCameraManager.h; sourceTree = ""; }; 5116AAB3AA934A9D25C58991F46D2A8D /* UIColor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = UIColor.h; sourceTree = ""; }; + 5147DF55EFD9DDF7091D87DF9F9E8D37 /* FirebaseAnalyticsInterop.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseAnalyticsInterop.xcconfig; sourceTree = ""; }; + 5154260B8F510C7AC74F8D2465CB6BC4 /* NSDictionary+FIRMessaging.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+FIRMessaging.h"; path = "Firebase/Messaging/NSDictionary+FIRMessaging.h"; sourceTree = ""; }; + 516F35E8FDF2F4BFF18B895917E368F1 /* FCompoundWrite.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FCompoundWrite.m; path = Firebase/Database/Snapshot/FCompoundWrite.m; sourceTree = ""; }; + 5177F3CD579B574CBC9F2649190E4693 /* FIRMessagingDelayedMessageQueue.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingDelayedMessageQueue.m; path = Firebase/Messaging/FIRMessagingDelayedMessageQueue.m; sourceTree = ""; }; + 51997ADB54C73F1CCA356B77B57555FA /* FQueryParams.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FQueryParams.m; path = Firebase/Database/Core/FQueryParams.m; sourceTree = ""; }; 51F96FE990AF57BDF75513496DEE28A4 /* api.md */ = {isa = PBXFileReference; includeInIndex = 1; name = api.md; path = docs/api.md; sourceTree = ""; }; - 520AAB5C69DF55FB372E2356B9E73273 /* GTMDebugThreadValidation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMDebugThreadValidation.h; path = DebugUtils/GTMDebugThreadValidation.h; sourceTree = ""; }; 5219A5D3B1D612138A0F260A22820610 /* TextDetectorManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = TextDetectorManager.m; path = ios/RN/TextDetectorManager.m; sourceTree = ""; }; 524343A6FDD6067649ABED74830C92FB /* RCTBridgeMethod.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTBridgeMethod.h; sourceTree = ""; }; - 52532E69A2044DDD180BABF354EE7E65 /* demangle.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = demangle.cc; path = src/demangle.cc; sourceTree = ""; }; - 52A4AE6DDD3EA030E3CAC170B3C190AD /* GPBCodedInputStream_PackagePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBCodedInputStream_PackagePrivate.h; path = objectivec/GPBCodedInputStream_PackagePrivate.h; sourceTree = ""; }; + 524DC92E428590D64BD35B69FAE4E32B /* FIRLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLogger.h; path = Firebase/Core/Private/FIRLogger.h; sourceTree = ""; }; + 529DD218B7FEAB0FD9D59EFC98F24DF4 /* FLeafNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FLeafNode.m; path = Firebase/Database/Snapshot/FLeafNode.m; sourceTree = ""; }; 52DD891097E8BA881AA45ECCD08088A6 /* RCTBlobManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTBlobManager.h; path = Libraries/Blob/RCTBlobManager.h; sourceTree = ""; }; 531481565D59FA89B019BAAFDEE12F70 /* CALayer+Compat.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "CALayer+Compat.m"; sourceTree = ""; }; 532BFE3E6004DD157D026786F06A2F28 /* RNGestureHandler.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RNGestureHandler.xcconfig; sourceTree = ""; }; 535A574FCBC85245364587C81687767D /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; }; - 535DE5CEB6FC286766550112D04D82EC /* FirebasePerformance.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebasePerformance.framework; path = Frameworks/FirebasePerformance.framework; sourceTree = ""; }; + 535A732EEE2C5782F0E8756BE795DCDF /* GPBUtilities_PackagePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBUtilities_PackagePrivate.h; path = objectivec/GPBUtilities_PackagePrivate.h; sourceTree = ""; }; 53AFE876BC5E44B03DD8FCE520321A7E /* RCTTransformAnimatedNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTTransformAnimatedNode.h; sourceTree = ""; }; 53BA1C2FD0843B20B712655FA70159C5 /* RCTRootContentView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTRootContentView.h; sourceTree = ""; }; 53C6CE5DDBE02AAD3C756D217145641B /* RCTImageViewManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTImageViewManager.m; path = Libraries/Image/RCTImageViewManager.m; sourceTree = ""; }; + 53CAB80B48147C3FF98B40A65850F078 /* pb.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = pb.h; sourceTree = ""; }; + 53D3D878BD14E11D645D0C2EBBDEABCD /* libGTMSessionFetcher.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libGTMSessionFetcher.a; path = libGTMSessionFetcher.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 53DDAA6BA233D4B91F3EB8FD9014366D /* merger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = merger.h; path = table/merger.h; sourceTree = ""; }; + 53EA97F0D01736B84E48D58715BA4290 /* FIRDataSnapshot_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDataSnapshot_Private.h; path = Firebase/Database/Api/Private/FIRDataSnapshot_Private.h; sourceTree = ""; }; 53F8B831111D7B588BA378D2308369F8 /* RCTReloadCommand.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTReloadCommand.m; sourceTree = ""; }; 5458382A8B89DCFF60A1CF5A89242675 /* RNVectorIcons.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RNVectorIcons.xcconfig; sourceTree = ""; }; + 55086ABF2F5769B99BC491AABF543073 /* logging.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = logging.h; path = src/glog/logging.h; sourceTree = ""; }; + 551F72DF002E8D67C63ED1DE0140ACC9 /* filter_policy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = filter_policy.h; path = include/leveldb/filter_policy.h; sourceTree = ""; }; + 552E2C917A1918F04F22AA02556B8562 /* signalhandler.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = signalhandler.cc; path = src/signalhandler.cc; sourceTree = ""; }; 55378F358C28BCA52E825CAF1B22759E /* RCTMacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTMacros.h; sourceTree = ""; }; - 55BFCCA16E8D02EB0E1E34DC2BAEAFD2 /* GPBBootstrap.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBBootstrap.h; path = objectivec/GPBBootstrap.h; sourceTree = ""; }; + 55AF778DC11874FA59DADD2E7AB1ACD9 /* Wrappers.pbobjc.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Wrappers.pbobjc.h; path = objectivec/google/protobuf/Wrappers.pbobjc.h; sourceTree = ""; }; + 55DD4835B21EDEF4C6BE39AE65FCA9A1 /* Empty.pbobjc.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = Empty.pbobjc.m; path = objectivec/google/protobuf/Empty.pbobjc.m; sourceTree = ""; }; 55E881E02479E741E5834F96FABD6491 /* Yoga-internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "Yoga-internal.h"; path = "yoga/Yoga-internal.h"; sourceTree = ""; }; - 562EFD18A443FC75D1F2A7C9E1BFBEED /* bignum-dtoa.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "bignum-dtoa.h"; path = "double-conversion/bignum-dtoa.h"; sourceTree = ""; }; + 562F8CB0D3313A7C1376DB26779FD16F /* FViewCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FViewCache.m; path = Firebase/Database/Core/View/FViewCache.m; sourceTree = ""; }; 56670206FA21065D6B0B080224D66A7D /* RCTTiming.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTTiming.h; sourceTree = ""; }; - 566DAFF42528D1D6FCEBD3246015F7CE /* GULUserDefaults.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULUserDefaults.m; path = GoogleUtilities/UserDefaults/GULUserDefaults.m; sourceTree = ""; }; 5683B5FB1C42A4A9787FB8F57D839142 /* LOTAnimationView_Compat.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTAnimationView_Compat.h; sourceTree = ""; }; 568E1E2F9C4686E3749464F2F212933C /* Yoga.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = Yoga.cpp; path = yoga/Yoga.cpp; sourceTree = ""; }; - 56C71E142AC9AF135CF8FFABF92C82DA /* GPBUtilities.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBUtilities.m; path = objectivec/GPBUtilities.m; sourceTree = ""; }; 56D39D45B18459AA455BFBFF4FAD257A /* LOTSizeInterpolator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTSizeInterpolator.m; sourceTree = ""; }; + 56DBBA3497A012C8AB33055D5DA559A8 /* FIRComponentContainerInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentContainerInternal.h; path = Firebase/Core/Private/FIRComponentContainerInternal.h; sourceTree = ""; }; + 56E2A60C3BF0245E931C0022D13A3EFC /* FIRMessagingPersistentSyncMessage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingPersistentSyncMessage.h; path = Firebase/Messaging/FIRMessagingPersistentSyncMessage.h; sourceTree = ""; }; + 56E453AAAE1E2456E2004FDD594E41AA /* libFirebaseDatabase.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libFirebaseDatabase.a; path = libFirebaseDatabase.a; sourceTree = BUILT_PRODUCTS_DIR; }; 56F9D4CFBB73958CA564E272FA0824BF /* RNTapHandler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RNTapHandler.m; sourceTree = ""; }; 57230F2F16D2613F6BCDC05F71AC3A8D /* LOTAnimatedControl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTAnimatedControl.h; sourceTree = ""; }; - 576CCA63035FF40021B2C4893AD22C70 /* bignum-dtoa.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = "bignum-dtoa.cc"; path = "double-conversion/bignum-dtoa.cc"; sourceTree = ""; }; + 57BD04B505CC2C942D300E2F298F08D4 /* libnanopb.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libnanopb.a; path = libnanopb.a; sourceTree = BUILT_PRODUCTS_DIR; }; 57E3F9077165C17BFC3CF8A0CFD58014 /* RCTReconnectingWebSocket.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTReconnectingWebSocket.m; path = Libraries/WebSocket/RCTReconnectingWebSocket.m; sourceTree = ""; }; 582E4A6A2B2641A0BA4423E00A100423 /* LOTRadialGradientLayer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTRadialGradientLayer.h; sourceTree = ""; }; - 58536835EFA959CC6FD5CF5218FDFC75 /* GULSwizzler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULSwizzler.m; path = GoogleUtilities/MethodSwizzler/GULSwizzler.m; sourceTree = ""; }; + 582EC301F15AA66B4997BA389F1C7B4A /* GULSwizzledObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULSwizzledObject.m; path = GoogleUtilities/ISASwizzler/GULSwizzledObject.m; sourceTree = ""; }; + 58504D264295A60569A9BACA31B854E4 /* FValueIndex.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FValueIndex.h; path = Firebase/Database/FValueIndex.h; sourceTree = ""; }; + 5882233FCBBC4D6397255B41D78352EF /* FirebasePerformance.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebasePerformance.framework; path = Frameworks/FirebasePerformance.framework; sourceTree = ""; }; 5883E68EDE439141E868243B72A3E48B /* Utils.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Utils.h; path = yoga/Utils.h; sourceTree = ""; }; 588BEB890092B4F1677B0E9EB2911C77 /* RCTSliderManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSliderManager.h; sourceTree = ""; }; - 58B33B41158BDBB4A9D00FCAE71EBD99 /* GTMNSDictionary+URLArguments.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "GTMNSDictionary+URLArguments.m"; path = "Foundation/GTMNSDictionary+URLArguments.m"; sourceTree = ""; }; - 58CF185EA5EBF3C2DE3574AB8DFE2489 /* FirebaseABTesting.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseABTesting.framework; path = Frameworks/FirebaseABTesting.framework; sourceTree = ""; }; 58D4FA35EFFE4B135722B03355E0F720 /* RCTUtils.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTUtils.m; sourceTree = ""; }; 590EA11D60BDC44FB2AB5C6A91572E01 /* RCTAnimationUtils.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTAnimationUtils.h; path = Libraries/NativeAnimation/RCTAnimationUtils.h; sourceTree = ""; }; 591CF78596852D81B2F664FA10F1DE9A /* RNFetchBlobNetwork.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNFetchBlobNetwork.m; path = ios/RNFetchBlobNetwork.m; sourceTree = ""; }; @@ -2150,60 +2846,78 @@ 5974F1EB6EB6CB8C449E83A3E40CED96 /* CGGeometry+LOTAdditions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "CGGeometry+LOTAdditions.m"; sourceTree = ""; }; 5984D0698E05710B32529A5873997FFD /* react-native-slider-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "react-native-slider-prefix.pch"; sourceTree = ""; }; 5990E7950D75F0AEEEBEB9D5F4FD915A /* RNLongPressHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RNLongPressHandler.h; sourceTree = ""; }; - 59A526190F6146A759532A4C61F5E776 /* GPBArray.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBArray.h; path = objectivec/GPBArray.h; sourceTree = ""; }; + 59A6ED2700886866121E44BBA8816C68 /* json_pointer.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = json_pointer.cpp; path = folly/json_pointer.cpp; sourceTree = ""; }; + 59DC9639CA4DCBB82ACE73BDE97C8FE1 /* nanopb.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = nanopb.xcconfig; sourceTree = ""; }; + 59E80B5F2FA215DB1789FF68C3AB8EBE /* FLeafNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FLeafNode.h; path = Firebase/Database/Snapshot/FLeafNode.h; sourceTree = ""; }; 5A1444E21F24A9054384677B8D892F9E /* RCTHTTPRequestHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTHTTPRequestHandler.h; path = Libraries/Network/RCTHTTPRequestHandler.h; sourceTree = ""; }; 5A2A8E4C4ADF680027DD478B19EAF61D /* RCTRedBox.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTRedBox.h; sourceTree = ""; }; 5A85634DF2B189D121BEA48B11F23B82 /* ARTText.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ARTText.h; path = Libraries/ART/ARTText.h; sourceTree = ""; }; 5ACF6CBFCA3AC47C540C3C7419FE53AA /* RCTRefreshControl.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTRefreshControl.m; sourceTree = ""; }; 5AE3425C16A423035FDA69B385FB469A /* RCTRefreshControlManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTRefreshControlManager.h; sourceTree = ""; }; + 5AEDA64FA1B2A882628B31137FD427BB /* FIRMessagingPacketQueue.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingPacketQueue.h; path = Firebase/Messaging/FIRMessagingPacketQueue.h; sourceTree = ""; }; 5AF65FF35F0E3DA312885756C885EA1D /* RCTActivityIndicatorView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTActivityIndicatorView.m; sourceTree = ""; }; - 5B30F2E8DF13C2CA1CEE032F3305159D /* GULSwizzledObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULSwizzledObject.m; path = GoogleUtilities/ISASwizzler/GULSwizzledObject.m; sourceTree = ""; }; 5B480D2E46B16594B22AA5F276C772BE /* RCTWKWebViewManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTWKWebViewManager.h; sourceTree = ""; }; 5B6FA38CD2611CB45471BC7BDE102410 /* RCTImageUtils.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTImageUtils.m; path = Libraries/Image/RCTImageUtils.m; sourceTree = ""; }; 5B75D776FA7AF1AC6DDEE7E22134D344 /* RCTParserUtils.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTParserUtils.m; sourceTree = ""; }; 5B8F76C35798A39530DF4CAADCF9DA65 /* RCTDefines.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTDefines.h; sourceTree = ""; }; - 5C17428E231BAEA6AA8DA7844DA8C227 /* GULNetwork.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULNetwork.m; path = GoogleUtilities/Network/GULNetwork.m; sourceTree = ""; }; + 5BD9EEEB632240CE8400657E09078FAA /* FirebaseAuthInterop.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseAuthInterop.xcconfig; sourceTree = ""; }; + 5BF8B947CBDBE7B454CED67A04F0CC23 /* ScopeGuard.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = ScopeGuard.cpp; path = folly/ScopeGuard.cpp; sourceTree = ""; }; 5C1B758110482496963A1857EB4703E8 /* RNRotationHandler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RNRotationHandler.m; sourceTree = ""; }; 5C2647862355572B747ECDBE58C58D4B /* LottieWalkthrough.gif */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.gif; name = LottieWalkthrough.gif; path = docs/gifs/LottieWalkthrough.gif; sourceTree = ""; }; 5C2D37E893D34B25904C1AE819B80A0A /* RCTDecayAnimation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTDecayAnimation.m; sourceTree = ""; }; 5C4CE2EB080A0EC0E32273B5FBC17F82 /* LOTAnimatorNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTAnimatorNode.h; sourceTree = ""; }; - 5D0C84E15BAC64269568163FD126444C /* strtod.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = strtod.cc; path = "double-conversion/strtod.cc"; sourceTree = ""; }; + 5C8C8EAA66B9A8936B5CB402688314A6 /* filter_block.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = filter_block.h; path = table/filter_block.h; sourceTree = ""; }; + 5CC1DE1429BDC8EF516F540CE704AE69 /* CLSAttributes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CLSAttributes.h; path = iOS/Crashlytics.framework/Headers/CLSAttributes.h; sourceTree = ""; }; + 5CC3EF116CEB4E86A61C700DAF2FAF03 /* vlog_is_on.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = vlog_is_on.h; path = src/glog/vlog_is_on.h; sourceTree = ""; }; 5D18619374F6081A171C233D549F9D25 /* RCTInterpolationAnimatedNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTInterpolationAnimatedNode.m; sourceTree = ""; }; 5D1DC0DAA27875096DEE4ADBD2161459 /* RNFetchBlobConst.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNFetchBlobConst.m; path = ios/RNFetchBlobConst.m; sourceTree = ""; }; 5D6216AD162DCFD8C33260AACCEA984C /* LOTPointInterpolator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTPointInterpolator.h; sourceTree = ""; }; - 5D8239D1C7ED7D0E5013E1D00ABCC4EE /* GULNSData+zlib.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "GULNSData+zlib.m"; path = "GoogleUtilities/NSData+zlib/GULNSData+zlib.m"; sourceTree = ""; }; 5D8844423291FD86C6B95F535C6E9F55 /* LOTGradientFillRender.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTGradientFillRender.h; sourceTree = ""; }; 5DB314FFC84DE55C304FC8E3DC14BDC3 /* RNVectorIconsManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNVectorIconsManager.h; path = RNVectorIconsManager/RNVectorIconsManager.h; sourceTree = ""; }; + 5DC3113D655890D1C34171C729A45C4F /* FSnapshotUtilities.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FSnapshotUtilities.h; path = Firebase/Database/Snapshot/FSnapshotUtilities.h; sourceTree = ""; }; 5E22FDD307ACA7FA3FC8B70EA8A0EB0F /* LOTCircleAnimator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTCircleAnimator.h; sourceTree = ""; }; 5E34E8B54127EF1453E32E98C6B4B7AC /* SafariViewManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = SafariViewManager.h; sourceTree = ""; }; - 5E987BD8711908B25633630076E4D31C /* FIRAnalyticsConfiguration+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FIRAnalyticsConfiguration+Internal.h"; path = "Firebase/Core/Private/FIRAnalyticsConfiguration+Internal.h"; sourceTree = ""; }; - 5E9C5CEDA8D77EA5BEE7FD692986F180 /* FIRConfiguration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRConfiguration.m; path = Firebase/Core/FIRConfiguration.m; sourceTree = ""; }; + 5E56962CF36D9AC7FC58707C2D4DCF6C /* FPersistentConnection.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FPersistentConnection.h; path = Firebase/Database/Core/FPersistentConnection.h; sourceTree = ""; }; + 5E69820A04F974F3CFFCCB3091ACA698 /* arena.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = arena.cc; path = util/arena.cc; sourceTree = ""; }; + 5EBECD9E9DD343F563D6765E57EFC7F5 /* FTupleStringNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTupleStringNode.h; path = Firebase/Database/Utilities/Tuples/FTupleStringNode.h; sourceTree = ""; }; 5F1F2819810285F3505FF1164FA26F4D /* Zocial.ttf */ = {isa = PBXFileReference; includeInIndex = 1; name = Zocial.ttf; path = Fonts/Zocial.ttf; sourceTree = ""; }; - 5F5F4DDD9BFE4308D4946C6C56152D8D /* libreact-native-camera.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libreact-native-camera.a"; path = "libreact-native-camera.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 5F8A41FE97F9E25D4B9F0EFA66FC8981 /* CxxModule.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CxxModule.h; path = ReactCommon/cxxreact/CxxModule.h; sourceTree = ""; }; - 5F9F37A7C4E4098D92D5CC0D7020DAA2 /* GoogleToolboxForMac-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "GoogleToolboxForMac-dummy.m"; sourceTree = ""; }; + 5FA052929FA7D379DAE94EC06B51D6EE /* FTypedefs.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTypedefs.h; path = Firebase/Database/Utilities/FTypedefs.h; sourceTree = ""; }; 5FE73A5FFA76C4B66DB344C966268AF4 /* RCTJavaScriptLoader.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTJavaScriptLoader.mm; sourceTree = ""; }; - 606DF439F68F15C4F56B9B3A5C083A7E /* libnanopb.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libnanopb.a; path = libnanopb.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 601F5DDAD74761C1B8AA0BC62A59E2A0 /* logging.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = logging.cc; path = src/logging.cc; sourceTree = ""; }; 6097374DA5B371540FA9C83AFB1A3A25 /* IOS7Polyfill.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = IOS7Polyfill.h; path = ios/IOS7Polyfill.h; sourceTree = ""; }; + 60C94E3663E9FEEEE52C5735B40D1878 /* FSnapshotHolder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FSnapshotHolder.h; path = Firebase/Database/Core/FSnapshotHolder.h; sourceTree = ""; }; 610EC1E202A0352FCB800B241B92D083 /* RCTCamera.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTCamera.h; path = ios/RCT/RCTCamera.h; sourceTree = ""; }; 61122C8054846D29678272FD83A4D887 /* rn-fetch-blob.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = "rn-fetch-blob.podspec"; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 6134C8480EA154992E8DD8FD4A7ABFB3 /* RCTBridgeModule.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTBridgeModule.h; sourceTree = ""; }; 61665E98CEAAF6108E6E006F554A0FEF /* RCTLog.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTLog.h; sourceTree = ""; }; + 61795D140D90B3C7C2D348BBCC2A1DCF /* skiplist.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = skiplist.h; path = db/skiplist.h; sourceTree = ""; }; + 61882694087119C9EACDCA7808A7CEAE /* Fabric.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Fabric.framework; path = iOS/Fabric.framework; sourceTree = ""; }; 618F73C667D4F19D67F0AAAD4ACA299D /* react-native-camera.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "react-native-camera.xcconfig"; sourceTree = ""; }; + 61ACF260B4EF5D451280A6D877073D43 /* FValidation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FValidation.h; path = Firebase/Database/Utilities/FValidation.h; sourceTree = ""; }; + 622CE1787B15B5BF9B8E6D7C32EE1F60 /* builder.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = builder.cc; path = db/builder.cc; sourceTree = ""; }; 62503FE6E7B7B5BD8F82C236CCBA3D06 /* RCTBaseTextShadowView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTBaseTextShadowView.m; sourceTree = ""; }; + 63130479CCFC34C4090DEA0EC26DDEFF /* FIRMessagingPersistentSyncMessage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingPersistentSyncMessage.m; path = Firebase/Messaging/FIRMessagingPersistentSyncMessage.m; sourceTree = ""; }; 631AB4B67AAEC51F6B69632AD9442693 /* RCTCxxMethod.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTCxxMethod.mm; sourceTree = ""; }; 633CF5FA3E4291F940F1B8D40D1B097B /* RCTBundleURLProvider.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTBundleURLProvider.m; sourceTree = ""; }; 636599CBD5F1D9FC19C882804FF3D16C /* LOTBezierPath.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTBezierPath.m; sourceTree = ""; }; - 63BB3BF433240BBBB17DF7E23D9EB8A8 /* GULNetworkConstants.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkConstants.h; path = GoogleUtilities/Network/Private/GULNetworkConstants.h; sourceTree = ""; }; + 6377CCAE0CE909B359DACF7BE9A33CA0 /* cached-powers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "cached-powers.h"; path = "double-conversion/cached-powers.h"; sourceTree = ""; }; 63BC6BDA2D77D8120D508A54DC9A0E93 /* ARTSolidColor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = ARTSolidColor.m; sourceTree = ""; }; 63C3B40B412C1338FDB1C37A27251328 /* RCTModalManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTModalManager.h; sourceTree = ""; }; 64025A2EC934909B86A3753FE5288DB3 /* RCTLayoutAnimation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTLayoutAnimation.h; sourceTree = ""; }; + 640485D56F169D7F85A9148D7262296D /* FIRMessaging_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessaging_Private.h; path = Firebase/Messaging/FIRMessaging_Private.h; sourceTree = ""; }; + 6442B918CC9418758CF784503DBAB162 /* log_reader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = log_reader.h; path = db/log_reader.h; sourceTree = ""; }; + 64ECD487E0F940E52FAE9C1561AE435F /* FIRDatabaseQuery.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDatabaseQuery.h; path = Firebase/Database/Public/FIRDatabaseQuery.h; sourceTree = ""; }; 64F26A68A2EABD264BBFEF73861FE8B5 /* LOTPathAnimator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTPathAnimator.h; sourceTree = ""; }; + 65047FECD45DEE085062BEEF54A90E1D /* FIRMessagingTopicOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingTopicOperation.m; path = Firebase/Messaging/FIRMessagingTopicOperation.m; sourceTree = ""; }; 650B57D7A404F369CB237E61EF0EA9D8 /* RCTTextTransform.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTTextTransform.h; path = Libraries/Text/RCTTextTransform.h; sourceTree = ""; }; 656279E8CE2F3F651EB039E74CE3200A /* ARTRenderable.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = ARTRenderable.m; path = Libraries/ART/ARTRenderable.m; sourceTree = ""; }; - 65996BB673A0A753370E3D489BA11ACE /* FIRComponentType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentType.h; path = Firebase/Core/Private/FIRComponentType.h; sourceTree = ""; }; + 65850DA53C24DA8CA8584275DC5C7E41 /* GPBUnknownFieldSet_PackagePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBUnknownFieldSet_PackagePrivate.h; path = objectivec/GPBUnknownFieldSet_PackagePrivate.h; sourceTree = ""; }; 65B11D7F2569B53319B988E9A0CE1F15 /* RCTSurfaceRootShadowView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTSurfaceRootShadowView.m; sourceTree = ""; }; + 66071353779F44989D907BF1A8344AAE /* GPBExtensionRegistry.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBExtensionRegistry.m; path = objectivec/GPBExtensionRegistry.m; sourceTree = ""; }; + 660E8F4A387A81130A3B64FDA0DC2C2F /* GULReachabilityChecker.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULReachabilityChecker.m; path = GoogleUtilities/Reachability/GULReachabilityChecker.m; sourceTree = ""; }; 662601B35F66B249DD7CB800FEFE040B /* LOTFillRenderer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTFillRenderer.m; sourceTree = ""; }; + 66A32C509A3E748E0848AB62683135DB /* liblottie-react-native.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "liblottie-react-native.a"; path = "liblottie-react-native.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 66C03B50B7BC7446C0D7BF05DF9D23FB /* LOTColorInterpolator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTColorInterpolator.m; sourceTree = ""; }; 66CB5BB34B82627B60C1FC2096B4E725 /* RCTMessageThread.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTMessageThread.h; sourceTree = ""; }; 66D7FB3F304C0694F361D185C2B5284E /* RCTAdditionAnimatedNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTAdditionAnimatedNode.m; sourceTree = ""; }; @@ -2211,52 +2925,66 @@ 67115196505F73C72E5AF2C379B60B6C /* RCTAppState.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTAppState.h; sourceTree = ""; }; 671D388C9298241343E84F91FA03F927 /* RCTProgressViewManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTProgressViewManager.h; sourceTree = ""; }; 671FF1235A314976A563716029B5F4EA /* LOTAnimatorNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTAnimatorNode.m; sourceTree = ""; }; - 672B4F31CF65337F8111AAFD4FE52315 /* MallocImpl.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = MallocImpl.cpp; path = folly/memory/detail/MallocImpl.cpp; sourceTree = ""; }; 672C2783B15E32F205E5BE67AA0CDED5 /* LOTShapeGroup.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTShapeGroup.h; sourceTree = ""; }; 673E0523607CC30F0D3C0B43797DF375 /* RCTDeviceInfo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTDeviceInfo.m; sourceTree = ""; }; - 674074D8450092A34E1538055F096B0D /* GoogleUtilities-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "GoogleUtilities-prefix.pch"; sourceTree = ""; }; - 67A6DC4F6F9CD4DE1E36CD36DD25E40E /* GPBDictionary_PackagePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBDictionary_PackagePrivate.h; path = objectivec/GPBDictionary_PackagePrivate.h; sourceTree = ""; }; + 6781CB7C70AB4EDC507A148480C7AD47 /* FIRAppAssociationRegistration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAppAssociationRegistration.h; path = Firebase/Core/Private/FIRAppAssociationRegistration.h; sourceTree = ""; }; 67DE87427E74AE70A903BC6AC4BC6EC7 /* RCTSurfaceRootShadowViewDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSurfaceRootShadowViewDelegate.h; sourceTree = ""; }; 681732CD2C5F6E22898FFAF9F43DFCB1 /* LOTShapeRectangle.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTShapeRectangle.h; sourceTree = ""; }; 684B1E3E8888CA9F33E3E278102D9069 /* RCTSafeAreaViewLocalData.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSafeAreaViewLocalData.h; sourceTree = ""; }; 68B7BFBD5F19AA93B5F6A8AA6F9BC091 /* LOTArrayInterpolator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTArrayInterpolator.m; sourceTree = ""; }; 68C531654C6DC8ECCB691CAA6C9FF7DC /* RNGestureHandler-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RNGestureHandler-prefix.pch"; sourceTree = ""; }; - 693E671BE3C1553C44C0A6CDF5D15765 /* GPBDescriptor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBDescriptor.h; path = objectivec/GPBDescriptor.h; sourceTree = ""; }; 6942AC0BB436F0E4B768FE87E5A8019D /* RCTClipboard.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTClipboard.m; sourceTree = ""; }; - 69DAFD5D0157639AA62C9A5B0260F34C /* GULLoggerCodes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULLoggerCodes.h; path = GoogleUtilities/Common/GULLoggerCodes.h; sourceTree = ""; }; + 69934098D004769DEF801CB253392E29 /* FIRComponent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRComponent.m; path = Firebase/Core/FIRComponent.m; sourceTree = ""; }; 69FCDC7812C211776AF778267B3AB5EA /* RCTSRWebSocket.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTSRWebSocket.m; path = Libraries/WebSocket/RCTSRWebSocket.m; sourceTree = ""; }; - 6A4D82D6621A33F2E46CCD53AADF6195 /* libRNGestureHandler.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libRNGestureHandler.a; path = libRNGestureHandler.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 6A27F2FAACB3CE33F2F156508EE98F6D /* FIRMessagingContextManagerService.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingContextManagerService.m; path = Firebase/Messaging/FIRMessagingContextManagerService.m; sourceTree = ""; }; 6A4F2C73ACD927B9486FBCFFE9A06ECD /* ARTShapeManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = ARTShapeManager.h; sourceTree = ""; }; + 6A8046567CE04F8DFE9CEEE8A4C16012 /* fixed-dtoa.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = "fixed-dtoa.cc"; path = "double-conversion/fixed-dtoa.cc"; sourceTree = ""; }; + 6AB7F22E3C7682C14E733A9ECE01325A /* FPathIndex.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FPathIndex.m; path = Firebase/Database/FPathIndex.m; sourceTree = ""; }; 6ABC30AA2971247A0B65DE455BBFDACD /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE; sourceTree = ""; }; - 6B136F18AEA180219FBA5D7410D58846 /* GULNSData+zlib.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "GULNSData+zlib.h"; path = "GoogleUtilities/NSData+zlib/GULNSData+zlib.h"; sourceTree = ""; }; + 6ADFCB7CEFE52C2088C8DCC32BFE3902 /* FIRTransactionResult.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRTransactionResult.m; path = Firebase/Database/Api/FIRTransactionResult.m; sourceTree = ""; }; + 6B79CE92D4AF98478243B547ADFD51D0 /* hash.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = hash.cc; path = util/hash.cc; sourceTree = ""; }; 6B8E3862D41450B31D85FD534DFE2100 /* jsi.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = jsi.cpp; path = ReactCommon/jsi/jsi.cpp; sourceTree = ""; }; - 6C28D2538D83FB8724D1397DF54FAEB9 /* FirebaseInstanceID.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseInstanceID.xcconfig; sourceTree = ""; }; + 6C22EE39B6204C1DD87F7F1352D610E3 /* GPBUnknownField_PackagePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBUnknownField_PackagePrivate.h; path = objectivec/GPBUnknownField_PackagePrivate.h; sourceTree = ""; }; 6D2E72C270DF02D693F6A3D82EA4C798 /* LOTNumberInterpolator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTNumberInterpolator.h; sourceTree = ""; }; - 6D41F04E9445A45F2AC4B9B3E9E09BFF /* GTMSessionFetcherLogging.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMSessionFetcherLogging.h; path = Source/GTMSessionFetcherLogging.h; sourceTree = ""; }; - 6D65282280EFE00FDF44F5A44A8134F1 /* GULReachabilityChecker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULReachabilityChecker.h; path = GoogleUtilities/Reachability/Private/GULReachabilityChecker.h; sourceTree = ""; }; 6D7D7EB41053A679EA4EBD3418B75328 /* ARTRadialGradient.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = ARTRadialGradient.h; sourceTree = ""; }; 6D8ADFD81FE169F7DCB3E6DB3A6B74D4 /* RCTScrollableProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTScrollableProtocol.h; sourceTree = ""; }; 6D90E38C531117D96E97CFE156AF7F2F /* RCTImageCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTImageCache.m; path = Libraries/Image/RCTImageCache.m; sourceTree = ""; }; 6DC9A94A09A4624AB1124AC0D2C15309 /* RCTMessageThread.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTMessageThread.mm; sourceTree = ""; }; + 6DCA35EF795480806D8EEBF75738F78F /* FStringUtilities.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FStringUtilities.m; path = Firebase/Database/Utilities/FStringUtilities.m; sourceTree = ""; }; + 6DD759A337B2E093C7B598AF79F47FF0 /* FIndex.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIndex.m; path = Firebase/Database/FIndex.m; sourceTree = ""; }; 6DE1B9AFB3278317A61AC8A3D1318116 /* UIView+React.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "UIView+React.m"; sourceTree = ""; }; - 6ECB293043438D7AA669ACD4DA0AA4C5 /* FirebaseRemoteConfig.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseRemoteConfig.framework; path = Frameworks/FirebaseRemoteConfig.framework; sourceTree = ""; }; + 6EDCC0DCEBE6963DC7DF76AD7231B96C /* NSError+FIRMessaging.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSError+FIRMessaging.h"; path = "Firebase/Messaging/NSError+FIRMessaging.h"; sourceTree = ""; }; + 6EF580D9928337F521B007EC45FC1F8C /* libRNGestureHandler.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libRNGestureHandler.a; path = libRNGestureHandler.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 6F42437F1F72018693E866EC0BDA1BB7 /* FAckUserWrite.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FAckUserWrite.m; path = Firebase/Database/Core/Operation/FAckUserWrite.m; sourceTree = ""; }; + 6F4530CAB03AC6F4D0F2979F7FC111EC /* FImmutableSortedSet.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FImmutableSortedSet.h; path = Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FImmutableSortedSet.h; sourceTree = ""; }; 6F864B053F8A153CD44481E267EFD35F /* ARTGroupManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = ARTGroupManager.m; sourceTree = ""; }; + 6F86652BE1E34EC9D11383F04A98C4FD /* mutexlock.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = mutexlock.h; path = util/mutexlock.h; sourceTree = ""; }; + 6FB03253561D95AC814D0898B86FC6C8 /* block.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = block.cc; path = table/block.cc; sourceTree = ""; }; + 6FDF8C105D1CD0639854ED193B0B62C8 /* GTMNSData+zlib.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "GTMNSData+zlib.h"; path = "Foundation/GTMNSData+zlib.h"; sourceTree = ""; }; 70031E439E3AA606F52BF4E0AEC37B4C /* UIView+React.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "UIView+React.h"; sourceTree = ""; }; - 704B5D61B511B65AB42B8159854ECBDE /* GPBCodedOutputStream.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBCodedOutputStream.m; path = objectivec/GPBCodedOutputStream.m; sourceTree = ""; }; 7057CADF90B4D8695FEC8649999BAB3D /* CALayer+Compat.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CALayer+Compat.h"; sourceTree = ""; }; + 708507DA28CE846DF9AEFA83BFB58787 /* FIRMessagingCodedInputStream.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingCodedInputStream.m; path = Firebase/Messaging/FIRMessagingCodedInputStream.m; sourceTree = ""; }; 70AE67D41FC83E3674ED1D13700B576D /* RCTMultipartDataTask.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTMultipartDataTask.h; sourceTree = ""; }; + 70BAF82D1EE14FACDC272E1C4B56C5E9 /* FIRMessagingConnection.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingConnection.h; path = Firebase/Messaging/FIRMessagingConnection.h; sourceTree = ""; }; + 70CD617F541028461ADEB6E9EECBE23B /* FStorageEngine.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FStorageEngine.h; path = Firebase/Database/Persistence/FStorageEngine.h; sourceTree = ""; }; 71054E1F5B576519521100CD4493714D /* RCTWebViewManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTWebViewManager.h; sourceTree = ""; }; + 712333C1507824756FE2CF1F681ACB7E /* db.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = db.h; path = include/leveldb/db.h; sourceTree = ""; }; + 712659E6D3CA9427726A4CF0C0A5A952 /* FConnection.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FConnection.m; path = Firebase/Database/Realtime/FConnection.m; sourceTree = ""; }; 7172CC433F0674E5B263694B9CA6DD7E /* RCTRefreshControl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTRefreshControl.h; sourceTree = ""; }; 717FE23B07E8513D81BBB492914623C4 /* RCTInspectorPackagerConnection.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTInspectorPackagerConnection.m; sourceTree = ""; }; - 71A375F95732A94E9172EF330D55C0CA /* pb_common.c */ = {isa = PBXFileReference; includeInIndex = 1; path = pb_common.c; sourceTree = ""; }; 71B20CCB72E6B6F7B565BB42E1FC512B /* ARTTextFrame.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ARTTextFrame.h; path = Libraries/ART/ARTTextFrame.h; sourceTree = ""; }; + 71F17B940ED7E61E4B3F0479A436376E /* MallocImpl.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = MallocImpl.cpp; path = folly/memory/detail/MallocImpl.cpp; sourceTree = ""; }; 725E5C8C5289CC330632F4343FBF8BAF /* RCTProfileTrampoline-arm64.S */ = {isa = PBXFileReference; includeInIndex = 1; path = "RCTProfileTrampoline-arm64.S"; sourceTree = ""; }; 7270F87015782FFE32E13F93F3D2503E /* RCTParserUtils.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTParserUtils.h; sourceTree = ""; }; 7273E0B4CC9DF12BD919BFFEF50247D1 /* RCTAlertManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTAlertManager.m; sourceTree = ""; }; 728B75239BFFFF7F1132EE851038388B /* LOTAnimationView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTAnimationView.m; sourceTree = ""; }; 72A6E50CC1D3D99B182C95CB014AF3D0 /* NativeToJsBridge.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = NativeToJsBridge.cpp; path = ReactCommon/cxxreact/NativeToJsBridge.cpp; sourceTree = ""; }; + 72A95C2BB95FD8729CF4444BE5B0899B /* FSparseSnapshotTree.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FSparseSnapshotTree.h; path = Firebase/Database/Core/FSparseSnapshotTree.h; sourceTree = ""; }; 72DE8883E97BF12D74E72919B77F3443 /* LOTRenderNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTRenderNode.m; sourceTree = ""; }; + 72E8E663A36070B6BA67A8E45D47C26F /* Type.pbobjc.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Type.pbobjc.h; path = objectivec/google/protobuf/Type.pbobjc.h; sourceTree = ""; }; 72F4DE19A8FA046681F301783248F5FC /* ARTRenderableManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = ARTRenderableManager.m; sourceTree = ""; }; + 730C83CA84F8C07C83D086E1EAE7BC63 /* FEventRaiser.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FEventRaiser.h; path = Firebase/Database/Core/View/FEventRaiser.h; sourceTree = ""; }; + 7326097D94A70A24EB9F31AED2BC8EAB /* FSRWebSocket.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FSRWebSocket.h; path = Firebase/Database/third_party/SocketRocket/FSRWebSocket.h; sourceTree = ""; }; 734E1D0168D67B0851932A9E07A5265E /* RCTModalHostViewController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTModalHostViewController.h; sourceTree = ""; }; 7356F174C3C879B33E39DE8286361D19 /* YGConfig.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = YGConfig.h; path = yoga/YGConfig.h; sourceTree = ""; }; 736B20E9BE1D6FD444F2B1BFE6DD3F21 /* RCTFollyConvert.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTFollyConvert.mm; sourceTree = ""; }; @@ -2264,550 +2992,747 @@ 73E291DAE7396986D57AEAFCB1C1F3B8 /* RCTRootShadowView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTRootShadowView.m; sourceTree = ""; }; 73FB83B5567B867C643ABD764A2CC524 /* RNImageUtils.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNImageUtils.m; path = ios/RN/RNImageUtils.m; sourceTree = ""; }; 746C38297B3157941E3CB81D2061B7B8 /* LOTValueInterpolator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTValueInterpolator.m; sourceTree = ""; }; + 7472FF197F11A3E87702DD9487C989EF /* FTupleObjects.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FTupleObjects.m; path = Firebase/Database/Utilities/Tuples/FTupleObjects.m; sourceTree = ""; }; 748B5E72654314BF99FE3E495ABF000E /* LOTRepeaterRenderer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTRepeaterRenderer.h; sourceTree = ""; }; - 74CEE568726ABC9EC073632676A4C3BF /* logging.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = logging.h; path = src/glog/logging.h; sourceTree = ""; }; + 75290A71FA8F79E812D3DB2C1321AF9E /* FIRMessagingPendingTopicsList.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingPendingTopicsList.h; path = Firebase/Messaging/FIRMessagingPendingTopicsList.h; sourceTree = ""; }; 7542AAC5A1596B18344251F049739855 /* Pods-Kalend.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Kalend.release.xcconfig"; sourceTree = ""; }; - 7545ED3CF47CD833D50D1BECB7E25191 /* Duration.pbobjc.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = Duration.pbobjc.m; path = objectivec/google/protobuf/Duration.pbobjc.m; sourceTree = ""; }; - 75ACB369AE23EB126585E20EF8618DD7 /* Folly-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Folly-prefix.pch"; sourceTree = ""; }; - 75ADAB93DC535E6DF3AAC46DAA07D9DC /* FieldMask.pbobjc.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FieldMask.pbobjc.h; path = objectivec/google/protobuf/FieldMask.pbobjc.h; sourceTree = ""; }; + 759C34A1ED749325D1487BE17458AD5D /* FEventRegistration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FEventRegistration.h; path = Firebase/Database/Core/View/FEventRegistration.h; sourceTree = ""; }; + 75A798E6C1AE8376F578BA0C0673F141 /* FIndexedNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIndexedNode.h; path = Firebase/Database/Snapshot/FIndexedNode.h; sourceTree = ""; }; + 75B640AB094C5A3B26E85EC575DAF7F8 /* GULLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULLogger.h; path = GoogleUtilities/Logger/Private/GULLogger.h; sourceTree = ""; }; + 75C2BF4E24C1C4A8516CD1D3AE267D4B /* coding.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = coding.h; path = util/coding.h; sourceTree = ""; }; 769615763CCB0E89898526841FDAC335 /* RCTBaseTextShadowView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTBaseTextShadowView.h; sourceTree = ""; }; + 76D068BBF9B8EF1509782F606D5D2EF4 /* FIRApp.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRApp.m; path = Firebase/Core/FIRApp.m; sourceTree = ""; }; + 76D48846AA16EE2F697709EC13A7DF6D /* GPBProtocolBuffers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBProtocolBuffers.h; path = objectivec/GPBProtocolBuffers.h; sourceTree = ""; }; + 76D9C9E44997FE825633287D7D5FF42F /* FCacheNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FCacheNode.h; path = Firebase/Database/Core/View/FCacheNode.h; sourceTree = ""; }; 76E05F699787D35369E6FDFDD7E00546 /* RCTSegmentedControlManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSegmentedControlManager.h; sourceTree = ""; }; + 76F353CA912399FEFC2D3D20C67AF7D4 /* GPBWireFormat.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBWireFormat.m; path = objectivec/GPBWireFormat.m; sourceTree = ""; }; + 7701718429F3F21BDCC1DD3131B9B39F /* FIRBundleUtil.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRBundleUtil.m; path = Firebase/Core/FIRBundleUtil.m; sourceTree = ""; }; 770284D939D902153C769176860C45DB /* RCTConvert.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTConvert.m; sourceTree = ""; }; 774F4E51B70BC28A607E08C929DC4D87 /* LOTSizeInterpolator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTSizeInterpolator.h; sourceTree = ""; }; 776E21EDFEB7038444892C624EF4A321 /* RCTLayout.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTLayout.m; sourceTree = ""; }; + 7778BE85B353DF2729DA7024BA6B45DD /* GULAppEnvironmentUtil.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULAppEnvironmentUtil.h; path = GoogleUtilities/Environment/third_party/GULAppEnvironmentUtil.h; sourceTree = ""; }; + 77B8A48D919AA42DBDD52D2941231A93 /* FIRMessagingSyncMessageManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingSyncMessageManager.h; path = Firebase/Messaging/FIRMessagingSyncMessageManager.h; sourceTree = ""; }; + 77EEBDAE0C2EFBC7F5A8C4AD1CD162FE /* nanopb-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "nanopb-dummy.m"; sourceTree = ""; }; 782A79361DF9C6B0D66F11F762775989 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; }; 7838F382547FF2E54C947E5A36FD32AA /* react-native-slider.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = "react-native-slider.podspec"; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; - 788D5F1524FB50C541D8C669AA9336EF /* Firebase.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Firebase.xcconfig; sourceTree = ""; }; + 783DA6DADA45F2B359DE949E9CF607F0 /* cache.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = cache.cc; path = util/cache.cc; sourceTree = ""; }; + 78AA68D19B1F685D88867FD4E892FEDA /* GPBArray.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBArray.h; path = objectivec/GPBArray.h; sourceTree = ""; }; 78BC1C212B2CC12CC24696810D33B02D /* RCTMultilineTextInputView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTMultilineTextInputView.m; sourceTree = ""; }; 78D2D129E82ACFC0468F93DD0C5D49E3 /* RCTSinglelineTextInputViewManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTSinglelineTextInputViewManager.m; sourceTree = ""; }; 78F0294CE68009EDB243EB923DAEEDA8 /* migrationV2.md */ = {isa = PBXFileReference; includeInIndex = 1; name = migrationV2.md; path = docs/migrationV2.md; sourceTree = ""; }; 79063DC172B9F714478327954C1A07E3 /* LOTAnimationTransitionController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTAnimationTransitionController.h; sourceTree = ""; }; + 791909236376A7AC032230DCDD821695 /* dumpfile.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = dumpfile.cc; path = db/dumpfile.cc; sourceTree = ""; }; 79294B443523F14967C8D519B26477F9 /* RCTExceptionsManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTExceptionsManager.h; sourceTree = ""; }; + 79743169E22CF9AF19816EDD74E1AFE0 /* FIRMessagingConstants.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingConstants.h; path = Firebase/Messaging/FIRMessagingConstants.h; sourceTree = ""; }; + 797D0736CD646C1C5C7C068633067BB9 /* FIRDatabaseReference.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRDatabaseReference.m; path = Firebase/Database/FIRDatabaseReference.m; sourceTree = ""; }; + 799504110AB087904080B91819637656 /* FLLRBNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FLLRBNode.h; path = Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBNode.h; sourceTree = ""; }; + 79A7987DF3C0A779E751CAF23BB69165 /* FIRTransactionResult_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRTransactionResult_Private.h; path = Firebase/Database/Api/Private/FIRTransactionResult_Private.h; sourceTree = ""; }; + 79CCFA5EFC38FED164C8F415BC49DF1E /* FValueIndex.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FValueIndex.m; path = Firebase/Database/FValueIndex.m; sourceTree = ""; }; 7A04BF50BC8EDFBD7D470C4A6A57C154 /* UIBezierPath.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = UIBezierPath.h; sourceTree = ""; }; - 7A49385C1B5229EEBF1131781952DF75 /* GPBUnknownFieldSet.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBUnknownFieldSet.m; path = objectivec/GPBUnknownFieldSet.m; sourceTree = ""; }; 7A7EEA9F3DF5F35E148C1B93FDAB8737 /* RNVectorIcons.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = RNVectorIcons.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 7A9D1C75BADE6BF64AAA760F711269D2 /* FTupleObjects.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTupleObjects.h; path = Firebase/Database/Utilities/Tuples/FTupleObjects.h; sourceTree = ""; }; 7ABD27F1E7EDFA071116E8B05CC55EC7 /* RCTAnimationUtils.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTAnimationUtils.m; path = Libraries/NativeAnimation/RCTAnimationUtils.m; sourceTree = ""; }; 7AD64A7145A593F426EA57467D5625F3 /* RNVectorIcons-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "RNVectorIcons-dummy.m"; sourceTree = ""; }; 7AEEA1671928288C86857036B1C49A40 /* RCTSRWebSocket.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTSRWebSocket.h; path = Libraries/WebSocket/RCTSRWebSocket.h; sourceTree = ""; }; - 7B1D4D3C0E4191DF1485194B68CEB7AD /* Empty.pbobjc.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = Empty.pbobjc.m; path = objectivec/google/protobuf/Empty.pbobjc.m; sourceTree = ""; }; 7B1E90D7919ACCA063D2E90BEE8C5DED /* RNCAsyncStorage.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = RNCAsyncStorage.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 7B2F7643BC09CB61D842C17C7F3CD8B1 /* RNRotationHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RNRotationHandler.h; sourceTree = ""; }; 7B578FBFE085DFB2F39B4CCF42957029 /* RCTScrollViewManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTScrollViewManager.h; sourceTree = ""; }; - 7B5C38E88269258D4425BB6B3CEC1A39 /* FIRComponentContainer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentContainer.h; path = Firebase/Core/Private/FIRComponentContainer.h; sourceTree = ""; }; 7BBE5A3C44D34E1372F5F0E1D0B8DB00 /* lottie-react-native-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "lottie-react-native-prefix.pch"; sourceTree = ""; }; - 7C03D23A538969ECF4FE84795F3C2BB5 /* pb_decode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = pb_decode.h; sourceTree = ""; }; + 7BE6185E47D64690D26AA8C43019350E /* FAtomicNumber.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FAtomicNumber.m; path = Firebase/Database/Utilities/FAtomicNumber.m; sourceTree = ""; }; 7C14CD2BC9A541C7E7BFB144938A0B60 /* RCTFPSGraph.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTFPSGraph.h; sourceTree = ""; }; + 7C33485C8E12BB74635C0EB707C20FFD /* GPBDescriptor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBDescriptor.m; path = objectivec/GPBDescriptor.m; sourceTree = ""; }; 7C3A734717549F61A45D9CAEAC709831 /* LOTLayerGroup.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTLayerGroup.h; sourceTree = ""; }; + 7C3BEB5634C1BC4486799C71640690D6 /* FView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FView.m; path = Firebase/Database/Core/View/FView.m; sourceTree = ""; }; + 7C72A21DB02B0FE24C7B1C441D3578B3 /* repair.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = repair.cc; path = db/repair.cc; sourceTree = ""; }; 7C7738F40E683A127FF4C2FE7DC76056 /* RCTConvert+Transform.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+Transform.m"; sourceTree = ""; }; - 7CE3268860304C5F99F52C2E4444CCB1 /* GTMMethodCheck.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMMethodCheck.h; path = DebugUtils/GTMMethodCheck.h; sourceTree = ""; }; + 7CAACBD84B0FF26AABBC2C0E6051CECE /* FPath.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FPath.m; path = Firebase/Database/Core/Utilities/FPath.m; sourceTree = ""; }; 7CE41CACAC85EB71E7CC555C66765840 /* RCTModalManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTModalManager.m; sourceTree = ""; }; 7CF05035E70E34884130DF4C99791EF8 /* RCTBorderDrawing.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTBorderDrawing.m; sourceTree = ""; }; 7D18F7C88E716FB8C7586DF8840E8BB8 /* LOTShapePath.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTShapePath.m; sourceTree = ""; }; 7D3A05841540D10AB818F37AB3C8FC3D /* RCTSubtractionAnimatedNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSubtractionAnimatedNode.h; sourceTree = ""; }; 7D3A39EF56EC9CBCAFD8D3AFDCB7F42E /* FontAwesome5_Solid.ttf */ = {isa = PBXFileReference; includeInIndex = 1; name = FontAwesome5_Solid.ttf; path = Fonts/FontAwesome5_Solid.ttf; sourceTree = ""; }; + 7D55D1B1A1EEFE3C9DA51ADCBC1D2B96 /* block_builder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = block_builder.h; path = table/block_builder.h; sourceTree = ""; }; + 7D5E2C8453763AD280CD8070711E7F32 /* GTMNSDictionary+URLArguments.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "GTMNSDictionary+URLArguments.m"; path = "Foundation/GTMNSDictionary+URLArguments.m"; sourceTree = ""; }; + 7D639F9D72183C354888805CCE9DD613 /* GULReachabilityChecker+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "GULReachabilityChecker+Internal.h"; path = "GoogleUtilities/Reachability/GULReachabilityChecker+Internal.h"; sourceTree = ""; }; + 7D686991C1E7EE358016B312E9B964B7 /* ColdClass.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = ColdClass.cpp; path = folly/lang/ColdClass.cpp; sourceTree = ""; }; 7D87E2A23446FFBC78001A489DEE8F70 /* RCTCxxBridgeDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTCxxBridgeDelegate.h; sourceTree = ""; }; + 7D9EF1FEC57661FEDFEEE115CE240A13 /* FPruneForest.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FPruneForest.h; path = Firebase/Database/Persistence/FPruneForest.h; sourceTree = ""; }; + 7DC2D23C296C50404F997788F0820D30 /* FIRApp.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRApp.h; path = Firebase/Core/Public/FIRApp.h; sourceTree = ""; }; 7DCEDC5350B60E81693F454A83EE906C /* LOTRadialGradientLayer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTRadialGradientLayer.m; sourceTree = ""; }; 7DDBD0701B6073C2040902224B2A6ADB /* LOTAnimationView_Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTAnimationView_Internal.h; sourceTree = ""; }; - 7E17028DBAA1E01FA284E0D1304048A7 /* libreact-native-slider.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libreact-native-slider.a"; path = "libreact-native-slider.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 7E4789119E50F090D03CF025000A12B1 /* FMaxNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FMaxNode.h; path = Firebase/Database/FMaxNode.h; sourceTree = ""; }; 7EF9CF21CA97F3E245FF3C7C05FCC207 /* RCTFileReaderModule.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTFileReaderModule.m; path = Libraries/Blob/RCTFileReaderModule.m; sourceTree = ""; }; 7F1ADA74AFB453A777F528BA5F7F7468 /* LOTValueInterpolator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTValueInterpolator.h; sourceTree = ""; }; 7FC8F281D113ACCE0F9CFC8D4F602BC9 /* SimpleLineIcons.ttf */ = {isa = PBXFileReference; includeInIndex = 1; name = SimpleLineIcons.ttf; path = Fonts/SimpleLineIcons.ttf; sourceTree = ""; }; 7FC9B3EA0A07AE52AA1D18C1F8F8CF1F /* RCTAnimationDriver.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTAnimationDriver.h; sourceTree = ""; }; 7FFDD4CDD40AC409B0985E74BF5A2442 /* react-native-slider.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "react-native-slider.xcconfig"; sourceTree = ""; }; - 8025EF7DC44740DD0CC6704D3A07623E /* libBVLinearGradient.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libBVLinearGradient.a; path = libBVLinearGradient.a; sourceTree = BUILT_PRODUCTS_DIR; }; 803BFBC6CDDDE19EF8A63FA2D4B924FF /* RCTProgressViewManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTProgressViewManager.m; sourceTree = ""; }; 80407E3F969E6595C77DFCAC08CC985B /* MessageQueueThread.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MessageQueueThread.h; path = ReactCommon/cxxreact/MessageQueueThread.h; sourceTree = ""; }; - 805FCB3E481C727E14A57BDD02367CFD /* FirebasePerformance.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebasePerformance.xcconfig; sourceTree = ""; }; - 81728A50D2944B4CA77790DAB5A0AC3D /* FIRComponentContainerInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentContainerInternal.h; path = Firebase/Core/Private/FIRComponentContainerInternal.h; sourceTree = ""; }; + 806638551525BD116E464D867CA63D1B /* libFirebaseCore.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libFirebaseCore.a; path = libFirebaseCore.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 80F61CFD731064B4566AC59E8B1DDC68 /* GPBRootObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBRootObject.m; path = objectivec/GPBRootObject.m; sourceTree = ""; }; + 80F654ED8096D8AD505DCFEDE99BA1E1 /* FIRMessagingRegistrar.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingRegistrar.h; path = Firebase/Messaging/FIRMessagingRegistrar.h; sourceTree = ""; }; 817530E6C928CADC2BB77B42E29DC002 /* RCTBridge+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RCTBridge+Private.h"; sourceTree = ""; }; 817A1060B032A903F45E7BBD656AB035 /* rn-fetch-blob-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "rn-fetch-blob-prefix.pch"; sourceTree = ""; }; + 818CA10F0216169E08402403FE90A012 /* FirebaseCore.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseCore.h; path = Firebase/Core/Public/FirebaseCore.h; sourceTree = ""; }; 81B57FCF76A2AE22EE4A5C389401781F /* RNCSliderManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNCSliderManager.m; path = ios/RNCSliderManager.m; sourceTree = ""; }; 81C8B3BDD59AA2F1354B33FA9F9FB787 /* RNFlingHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RNFlingHandler.h; sourceTree = ""; }; - 81D34BCF7098CC66628D279837360686 /* GULAppDelegateSwizzler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULAppDelegateSwizzler.m; path = GoogleUtilities/AppDelegateSwizzler/GULAppDelegateSwizzler.m; sourceTree = ""; }; - 81E6CEE364947BFEFBB66A11AEEEC135 /* GULNetworkConstants.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULNetworkConstants.m; path = GoogleUtilities/Network/GULNetworkConstants.m; sourceTree = ""; }; 820EB3F7CD1ADA909475E8D4CAF5315A /* yoga-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "yoga-prefix.pch"; sourceTree = ""; }; - 82A67AD1F41497CDE05BE0D941580CEF /* GULNetworkURLSession.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULNetworkURLSession.m; path = GoogleUtilities/Network/GULNetworkURLSession.m; sourceTree = ""; }; + 82119C686FAE08B6354EDEA9F39962B0 /* Answers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Answers.h; path = iOS/Crashlytics.framework/Headers/Answers.h; sourceTree = ""; }; + 8225C2C04620F9942D7441424A5CBBDB /* FIRConfiguration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRConfiguration.m; path = Firebase/Core/FIRConfiguration.m; sourceTree = ""; }; + 829DE110A8990FA98FC7334454C7D389 /* port_example.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = port_example.h; path = port/port_example.h; sourceTree = ""; }; + 82B76D98D30AA6642A0C7940342E89EA /* GULNSData+zlib.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "GULNSData+zlib.m"; path = "GoogleUtilities/NSData+zlib/GULNSData+zlib.m"; sourceTree = ""; }; + 82FA54919C73D72F5F91E7FCEE74C2C0 /* GPBExtensionRegistry.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBExtensionRegistry.h; path = objectivec/GPBExtensionRegistry.h; sourceTree = ""; }; 83137E3B69277B70F3379CD498869329 /* RCTTextSelection.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTTextSelection.m; sourceTree = ""; }; - 832D30811692600A1C71322C43578D87 /* GULReachabilityChecker+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "GULReachabilityChecker+Internal.h"; path = "GoogleUtilities/Reachability/GULReachabilityChecker+Internal.h"; sourceTree = ""; }; - 843C108D6749BB75281B7551D4057AAD /* Empty.pbobjc.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Empty.pbobjc.h; path = objectivec/google/protobuf/Empty.pbobjc.h; sourceTree = ""; }; + 838388E76F01CCA24EB0680BAA345E6A /* two_level_iterator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = two_level_iterator.h; path = table/two_level_iterator.h; sourceTree = ""; }; + 845976E40CFA65B0DEBDDFB5EE10EF94 /* FIRMessagingCodedInputStream.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingCodedInputStream.h; path = Firebase/Messaging/FIRMessagingCodedInputStream.h; sourceTree = ""; }; 8474BD3FE2CD0DCBA3CCD8128793F50C /* RCTSafeAreaViewLocalData.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTSafeAreaViewLocalData.m; sourceTree = ""; }; 8496380D74A861E38030178BC919B55D /* RNImageUtils.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNImageUtils.h; path = ios/RN/RNImageUtils.h; sourceTree = ""; }; + 84A5D23ED0B9FFA009FFA35EB291AB1A /* FTupleUserCallback.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTupleUserCallback.h; path = Firebase/Database/Utilities/Tuples/FTupleUserCallback.h; sourceTree = ""; }; 84B7FFB90CB09D325C1290A677505E48 /* RCTDevMenu.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTDevMenu.h; sourceTree = ""; }; 850283C157E5D032508633B279DA10CD /* RCTEventAnimation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTEventAnimation.m; sourceTree = ""; }; - 850627136AB58C8DA3E77E69C7A41DF4 /* Folly.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Folly.xcconfig; sourceTree = ""; }; - 8526A6E0B4983EEBE27458896D71AE80 /* GPBWellKnownTypes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBWellKnownTypes.h; path = objectivec/GPBWellKnownTypes.h; sourceTree = ""; }; 852EFC4CF9C218A75E2E16D7DADF6825 /* BVLinearGradient.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BVLinearGradient.h; path = BVLinearGradient/BVLinearGradient.h; sourceTree = ""; }; + 853A62F813D5F154B1F1D222597065EB /* FEventEmitter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FEventEmitter.h; path = Firebase/Database/Utilities/FEventEmitter.h; sourceTree = ""; }; 85569D29BAAB1D11B5A8BECB44CB753D /* JSIndexedRAMBundle.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = JSIndexedRAMBundle.h; path = ReactCommon/cxxreact/JSIndexedRAMBundle.h; sourceTree = ""; }; - 855A4A4D0254750282F9818524C8A400 /* stl_logging.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = stl_logging.h; path = src/glog/stl_logging.h; sourceTree = ""; }; - 8562F0DDAF1B176288A98162E9134DD1 /* FIRErrorCode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRErrorCode.h; path = Firebase/Core/Private/FIRErrorCode.h; sourceTree = ""; }; + 856D59AAC88A0EAB2C54480479C7B899 /* GULAppDelegateSwizzler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULAppDelegateSwizzler.h; path = GoogleUtilities/AppDelegateSwizzler/Private/GULAppDelegateSwizzler.h; sourceTree = ""; }; + 85AB9F4C2E8E73E002AE9713A5F0578C /* FirebaseMessaging-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FirebaseMessaging-dummy.m"; sourceTree = ""; }; 85E6E56A33A36BEB34C1AF48CC77EB02 /* RNGestureHandlerButton.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNGestureHandlerButton.h; path = ios/RNGestureHandlerButton.h; sourceTree = ""; }; 86065096B5CB88A98E055E5988FB4AFB /* JSBundleType.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = JSBundleType.cpp; path = ReactCommon/cxxreact/JSBundleType.cpp; sourceTree = ""; }; + 8627BB978197F51EFF396E4327FA065B /* GPBExtensionInternals.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBExtensionInternals.h; path = objectivec/GPBExtensionInternals.h; sourceTree = ""; }; 863BBD064846E7D63EE919F9B1A7E593 /* RCTBundleURLProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTBundleURLProvider.h; sourceTree = ""; }; + 8648BC64286D754073CACC328B7BB68F /* Struct.pbobjc.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Struct.pbobjc.h; path = objectivec/google/protobuf/Struct.pbobjc.h; sourceTree = ""; }; 86581280F99A19C65FF9188F6CF1400D /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; name = README.md; path = docs/README.md; sourceTree = ""; }; 86721F4035FCFF4C51729F4D220E8D93 /* LOTShapeFill.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTShapeFill.h; sourceTree = ""; }; + 8685293563920AD67BBFD02921A36356 /* FIRAnalyticsInterop.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAnalyticsInterop.h; path = Interop/Analytics/Public/FIRAnalyticsInterop.h; sourceTree = ""; }; + 86DF92D9A6B37877E72691BB0096A0D6 /* FPendingPut.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FPendingPut.h; path = Firebase/Database/Persistence/FPendingPut.h; sourceTree = ""; }; 86E41579D642772BEEFB933E211EDDEC /* BVLinearGradientLayer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = BVLinearGradientLayer.m; path = BVLinearGradient/BVLinearGradientLayer.m; sourceTree = ""; }; + 8731D3E9DDAC0B89CDD6F6EC2D655B24 /* glog-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "glog-dummy.m"; sourceTree = ""; }; 874716F29B6F762B15369BE564CE2A27 /* RCTBaseTextInputViewManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTBaseTextInputViewManager.h; sourceTree = ""; }; 874DD3640EAAC04E53B072960D73F89F /* Feather.ttf */ = {isa = PBXFileReference; includeInIndex = 1; name = Feather.ttf; path = Fonts/Feather.ttf; sourceTree = ""; }; + 8759E85F683CBD7D8313AD3920BD8B57 /* FirebaseAnalytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseAnalytics.framework; path = Frameworks/FirebaseAnalytics.framework; sourceTree = ""; }; 877F832D478F7EE34256387B7ADC18DD /* RCTNetworking.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTNetworking.h; path = Libraries/Network/RCTNetworking.h; sourceTree = ""; }; 877FBFA30FD9C5E7350352BA6E7D8903 /* NSValue+Compat.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "NSValue+Compat.m"; sourceTree = ""; }; - 8790B8A241F3149E10155D2A2A1BDA12 /* fixed-dtoa.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = "fixed-dtoa.cc"; path = "double-conversion/fixed-dtoa.cc"; sourceTree = ""; }; + 8780294E8D554541F2E815BCB528F0EE /* FLevelDBStorageEngine.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FLevelDBStorageEngine.m; path = Firebase/Database/Persistence/FLevelDBStorageEngine.m; sourceTree = ""; }; 87B199563AB49A7E7D90A26E4E537620 /* RCTInvalidating.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTInvalidating.h; sourceTree = ""; }; + 87BF0D472913B05794F194F52D37FBE3 /* FIRDependency.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRDependency.m; path = Firebase/Core/FIRDependency.m; sourceTree = ""; }; 87D53996554AD7FFB9B3579A9CE55BA3 /* RNPinchHandler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RNPinchHandler.m; sourceTree = ""; }; 87F6253D399519CB0A5C05E20C1F299C /* Ionicons.ttf */ = {isa = PBXFileReference; includeInIndex = 1; name = Ionicons.ttf; path = Fonts/Ionicons.ttf; sourceTree = ""; }; - 87FD80787842E07D922056CD49FC2EE1 /* FIRDependency.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDependency.h; path = Firebase/Core/Private/FIRDependency.h; sourceTree = ""; }; 8814F242551E04EFE362687AD2EAE8E6 /* JSINativeModules.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = JSINativeModules.cpp; path = ReactCommon/jsiexecutor/jsireact/JSINativeModules.cpp; sourceTree = ""; }; - 882D20CF3E4020747627A3A5FE26F042 /* GoogleSignIn.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleSignIn.xcconfig; sourceTree = ""; }; - 88364B23619E73D4CD113CC0E8460578 /* libProtobuf.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libProtobuf.a; path = libProtobuf.a; sourceTree = BUILT_PRODUCTS_DIR; }; 883B6143152CCA96E0CF4594C47DF773 /* RCTWKWebViewManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTWKWebViewManager.m; sourceTree = ""; }; 885E29EDFA78D83E21A10B4B902FB800 /* RNNativeViewHandler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RNNativeViewHandler.m; sourceTree = ""; }; - 887F7DBD5091038F3A40E4095823B0FF /* GULReachabilityChecker.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULReachabilityChecker.m; path = GoogleUtilities/Reachability/GULReachabilityChecker.m; sourceTree = ""; }; + 886DE47956E22373CFBD2E91672FDC4B /* GPBMessage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBMessage.m; path = objectivec/GPBMessage.m; sourceTree = ""; }; 88D8A6966CF11F39006D3B576E26FCA6 /* LOTShapeRectangle.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTShapeRectangle.m; sourceTree = ""; }; - 88DF437691E927D8BF17D5DEDA4F65EA /* GPBWireFormat.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBWireFormat.m; path = objectivec/GPBWireFormat.m; sourceTree = ""; }; + 88DA4130826C456894E35ED6F53A4D9A /* FTreeSortedDictionaryEnumerator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FTreeSortedDictionaryEnumerator.m; path = Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FTreeSortedDictionaryEnumerator.m; sourceTree = ""; }; 88EB025A6AEDBF2035F1F1E6A32D51F5 /* RCTModuloAnimatedNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTModuloAnimatedNode.m; sourceTree = ""; }; 8903F0F9A7539997003CB4FFF0FD056A /* ARTNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = ARTNode.m; path = Libraries/ART/ARTNode.m; sourceTree = ""; }; - 89AB621D96C9B51FB13A8A4BC09FF9E3 /* DoubleConversion-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "DoubleConversion-prefix.pch"; sourceTree = ""; }; + 89130677F74BC1967BBAD867534292CA /* FIRInteropEventNames.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInteropEventNames.h; path = Interop/Analytics/Public/FIRInteropEventNames.h; sourceTree = ""; }; + 894D53FA3FFD70DFE5301E4E508B2DFF /* FTrackedQueryManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTrackedQueryManager.h; path = Firebase/Database/Persistence/FTrackedQueryManager.h; sourceTree = ""; }; + 89B9B60415B01CC3F624C6526B96677F /* FPathIndex.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FPathIndex.h; path = Firebase/Database/FPathIndex.h; sourceTree = ""; }; 89CA7A146CB927B9201F74F37A2D20FE /* BVLinearGradient.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = BVLinearGradient.xcconfig; sourceTree = ""; }; - 8A003652CC3D84C54C2C705D53E16081 /* pb.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = pb.h; sourceTree = ""; }; 8A31C1733EF0C9BB884EBE2E396FFEAF /* ARTTextManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = ARTTextManager.h; sourceTree = ""; }; 8A3A62DD2A1CE7440ADD19C9EFD77263 /* RCTImageSource.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTImageSource.m; sourceTree = ""; }; + 8A49009D41FCF7B380C203917270C643 /* FTreeSortedDictionary.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FTreeSortedDictionary.m; path = Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FTreeSortedDictionary.m; sourceTree = ""; }; 8A50D282DCFFDC13A41E028712B304E8 /* RCTCamera.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTCamera.m; path = ios/RCT/RCTCamera.m; sourceTree = ""; }; 8A7B4C8C1C211CB2B2CCF8D70D9F7657 /* RCTLayoutAnimationGroup.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTLayoutAnimationGroup.h; sourceTree = ""; }; + 8A8A1B99D1D6D8DE0C6ADD1FF71CB5FA /* FIRDependency.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDependency.h; path = Firebase/Core/Private/FIRDependency.h; sourceTree = ""; }; 8AB7FDBDFC2DA39E68B035C391BDCA6B /* RCTDataRequestHandler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTDataRequestHandler.m; path = Libraries/Network/RCTDataRequestHandler.m; sourceTree = ""; }; + 8AB83D79B3A65995AB528E4FB67F4DD8 /* block.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = block.h; path = table/block.h; sourceTree = ""; }; + 8ABD9D96C5ED0354122B80F70AB70E3F /* FIRDatabaseQuery_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDatabaseQuery_Private.h; path = Firebase/Database/Api/Private/FIRDatabaseQuery_Private.h; sourceTree = ""; }; 8B30FE6DDEEA9589B8F905714BD2B70A /* RCTTextViewManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTTextViewManager.h; sourceTree = ""; }; - 8C02673A3977C4B70F2FFE4CFE80D989 /* GULSwizzler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULSwizzler.h; path = GoogleUtilities/MethodSwizzler/Private/GULSwizzler.h; sourceTree = ""; }; - 8C5D15A4DAED2F19F5A7B895AB07A872 /* GTMDebugSelectorValidation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMDebugSelectorValidation.h; path = DebugUtils/GTMDebugSelectorValidation.h; sourceTree = ""; }; + 8B42FCEC34634448FD698A9E455C74B8 /* FIRMutableData_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMutableData_Private.h; path = Firebase/Database/Api/Private/FIRMutableData_Private.h; sourceTree = ""; }; + 8C1B90E0F2D381FFF1B123D4F5376D25 /* bloom.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = bloom.cc; path = util/bloom.cc; sourceTree = ""; }; + 8C4A852050AF22C0F63D82C6E289AC36 /* Folly.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Folly.xcconfig; sourceTree = ""; }; + 8C595054FE1F0AB55132320069F45FD0 /* FIRAnalyticsConfiguration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAnalyticsConfiguration.h; path = Firebase/Core/Public/FIRAnalyticsConfiguration.h; sourceTree = ""; }; + 8C67F76BA60F26BD2E805CB7688786F3 /* FCachePolicy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FCachePolicy.h; path = Firebase/Database/Persistence/FCachePolicy.h; sourceTree = ""; }; 8C82AAF34F6F689688447C1940B73104 /* JSIExecutor.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = JSIExecutor.cpp; path = ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp; sourceTree = ""; }; - 8C9444A5C15DCECB1B9B6C8CCE7F58A9 /* GULMutableDictionary.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULMutableDictionary.m; path = GoogleUtilities/Network/GULMutableDictionary.m; sourceTree = ""; }; 8CD95F8D31BA3304FCA6F0E43A9A1281 /* RNGestureHandlerModule.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNGestureHandlerModule.m; path = ios/RNGestureHandlerModule.m; sourceTree = ""; }; + 8CF7B73F4DA5EDEF5C6A440C5FCC53DE /* FPersistentConnection.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FPersistentConnection.m; path = Firebase/Database/Core/FPersistentConnection.m; sourceTree = ""; }; 8D29E26FA2AE080F5BB7190E07F01DF0 /* RCTUtils.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTUtils.h; sourceTree = ""; }; 8D7CC37D2809D0E76FAAE7E7CF45D5EF /* RCTUIManagerUtils.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTUIManagerUtils.h; sourceTree = ""; }; + 8D81569D4FB78A79815500605F8D4D1E /* FTreeSortedDictionary.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTreeSortedDictionary.h; path = Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FTreeSortedDictionary.h; sourceTree = ""; }; + 8DAF410F81561E974F2E4070A0334FF2 /* FViewProcessor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FViewProcessor.m; path = Firebase/Database/FViewProcessor.m; sourceTree = ""; }; 8DE4FCE791E34E4C3BA04A067B420E49 /* RCTAnimationType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTAnimationType.h; sourceTree = ""; }; + 8E316121E6C0066D9EEAC18DDB94300C /* FIRAnalyticsConfiguration+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FIRAnalyticsConfiguration+Internal.h"; path = "Firebase/Core/Private/FIRAnalyticsConfiguration+Internal.h"; sourceTree = ""; }; 8E5ED2D9192FAF41FB60F68E10D04347 /* tests.md */ = {isa = PBXFileReference; includeInIndex = 1; name = tests.md; path = docs/tests.md; sourceTree = ""; }; - 8E6228157D6E72B153CDEF9FD2F04E8D /* FIRApp.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRApp.h; path = Firebase/Core/Public/FIRApp.h; sourceTree = ""; }; 8E65C73D2BC04DDFF78DC170CE2C9EC9 /* RCTImageBlurUtils.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTImageBlurUtils.m; path = Libraries/Image/RCTImageBlurUtils.m; sourceTree = ""; }; + 8E702FAD5F5F374D2FC13FE47219A91C /* libreact-native-camera.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libreact-native-camera.a"; path = "libreact-native-camera.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 8E764F449658692454D522EA90DEDB37 /* FIRComponentContainer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentContainer.h; path = Firebase/Core/Private/FIRComponentContainer.h; sourceTree = ""; }; 8E7BCDE68E4FC2A47B90EDF9E20BF4EB /* RNCameraManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNCameraManager.m; path = ios/RN/RNCameraManager.m; sourceTree = ""; }; 8E7E7140D1D2690EF22C542A366CFA63 /* yoga.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = yoga.xcconfig; sourceTree = ""; }; + 8E8D7E53496B4BF7E29AB957ABC2565B /* FIRMessagingTopicOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingTopicOperation.h; path = Firebase/Messaging/FIRMessagingTopicOperation.h; sourceTree = ""; }; + 8EA3039B8276E66EFA1E055C5273D6E5 /* FListenProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FListenProvider.h; path = Firebase/Database/Core/FListenProvider.h; sourceTree = ""; }; 8EC44748D83175173382714006908D92 /* LOTRenderNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTRenderNode.h; sourceTree = ""; }; - 8F686A439382FEEAB83044D57C61F0BB /* Api.pbobjc.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Api.pbobjc.h; path = objectivec/google/protobuf/Api.pbobjc.h; sourceTree = ""; }; + 8F3AC0B3CF021ABD39D948CB83367A32 /* FirebaseMessaging.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseMessaging.xcconfig; sourceTree = ""; }; + 8F46D2A286B809B9242F0DBE0D362017 /* GoogleAppMeasurement.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GoogleAppMeasurement.framework; path = Frameworks/GoogleAppMeasurement.framework; sourceTree = ""; }; + 8F51B0E5493C1021B8F13C0DBE689DBA /* Firebase.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Firebase.xcconfig; sourceTree = ""; }; + 8F571C5DB444B31B17A40742A190C5BF /* FAuthTokenProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FAuthTokenProvider.h; path = Firebase/Database/Login/FAuthTokenProvider.h; sourceTree = ""; }; + 8F68366A11B377715E042AE44705C84B /* FArraySortedDictionary.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FArraySortedDictionary.m; path = Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FArraySortedDictionary.m; sourceTree = ""; }; 8F695D32CED7970993F4B0BC6EBD4525 /* RNCAsyncStorage-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RNCAsyncStorage-prefix.pch"; sourceTree = ""; }; + 8F7A091B8C6E441AB1BFD5CC75E281F9 /* write_batch_internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = write_batch_internal.h; path = db/write_batch_internal.h; sourceTree = ""; }; 8F89EC8366AC31149B4E36BE52546A35 /* LOTPointInterpolator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTPointInterpolator.m; sourceTree = ""; }; + 8FFF38C9E3F7CB5F4C45EC6F0C89C59D /* FIRMessagingDataMessageManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingDataMessageManager.h; path = Firebase/Messaging/FIRMessagingDataMessageManager.h; sourceTree = ""; }; 902942DCAA5BF1F1B2C9420A980D2C12 /* RCTConvert+ART.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "RCTConvert+ART.h"; path = "Libraries/ART/RCTConvert+ART.h"; sourceTree = ""; }; 902FD3FE90F56C6A627A9362273086AF /* LOTRoundedRectAnimator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTRoundedRectAnimator.h; sourceTree = ""; }; 90454C7B94BE46303481BA504D5DB04E /* RCTPropsAnimatedNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTPropsAnimatedNode.m; sourceTree = ""; }; 90616E226A6B4606DB5249F30AAD58CF /* LOTAnimationTransitionController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTAnimationTransitionController.m; sourceTree = ""; }; 9066231FC462CE25D64E6E23A25E4C03 /* Yoga.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Yoga.h; path = yoga/Yoga.h; sourceTree = ""; }; - 907520142BCBA284CCB871DD47D9B4CB /* log_severity.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = log_severity.h; path = src/glog/log_severity.h; sourceTree = ""; }; - 90925193CFC8654619BC7A42DF98C8EE /* Demangle.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = Demangle.cpp; path = folly/detail/Demangle.cpp; sourceTree = ""; }; + 908D456544B582A2941A79B982FA9D86 /* FNodeFilter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FNodeFilter.h; path = Firebase/Database/Core/View/Filter/FNodeFilter.h; sourceTree = ""; }; + 90B601B427F3F79EA0C870FACB123D08 /* GPBDictionary_PackagePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBDictionary_PackagePrivate.h; path = objectivec/GPBDictionary_PackagePrivate.h; sourceTree = ""; }; 911D510658586F54B72EDCA08D6C57BD /* RNCamera.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNCamera.h; path = ios/RN/RNCamera.h; sourceTree = ""; }; 911F56CC688E70E6D4A634EA21017F9D /* RCTModalHostViewManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTModalHostViewManager.m; sourceTree = ""; }; 91538E3BC1356D7766925388D5888A8E /* LOTShapeTransform.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTShapeTransform.m; sourceTree = ""; }; - 91AA353441322E37B9D6F28C0BEC52BA /* FIRCoreConfigurable.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRCoreConfigurable.h; path = Firebase/Core/Private/FIRCoreConfigurable.h; sourceTree = ""; }; + 9197527BF54C7861B6DA0625FED4EE24 /* FValidation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FValidation.m; path = Firebase/Database/Utilities/FValidation.m; sourceTree = ""; }; + 91CE28EB044818CC40BB467E58167F54 /* GULSwizzler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULSwizzler.h; path = GoogleUtilities/MethodSwizzler/Private/GULSwizzler.h; sourceTree = ""; }; 91D9F2460233AE7E6D83D9731F784F10 /* RCTPerformanceLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTPerformanceLogger.h; sourceTree = ""; }; + 91DB18116E45682289F6BAD1CED9DC6D /* FIRMessagingPubSub.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingPubSub.m; path = Firebase/Messaging/FIRMessagingPubSub.m; sourceTree = ""; }; 91E27A3160ABCFED1B02335AB8E5570B /* RCTRedBoxExtraDataViewController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTRedBoxExtraDataViewController.m; sourceTree = ""; }; + 91F21C81538226CD9A5DE14ECF25EBEE /* DoubleConversion.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = DoubleConversion.xcconfig; sourceTree = ""; }; + 9229E08D02A82F7A9C3D6ECA5DAE6D63 /* FirebaseRemoteConfig.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseRemoteConfig.xcconfig; sourceTree = ""; }; 922BB5774C0CF4980FF7F28D6021F078 /* YGLayout.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = YGLayout.cpp; path = yoga/YGLayout.cpp; sourceTree = ""; }; 92645298A7A3705DF33AF08F6C912988 /* LOTBezierPath.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTBezierPath.h; sourceTree = ""; }; + 9274C252BFD539E5FDC69265C7A79A67 /* FirebaseCore-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FirebaseCore-dummy.m"; sourceTree = ""; }; 929D04716358D6AA8CA0936574C71023 /* LOTLayer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTLayer.h; sourceTree = ""; }; + 92A08879A6771EC77258B679ADC924C5 /* GULNetworkLoggerProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkLoggerProtocol.h; path = GoogleUtilities/Network/Private/GULNetworkLoggerProtocol.h; sourceTree = ""; }; 92B09EFD510A481A35910A0357C904D5 /* CameraFocusSquare.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = CameraFocusSquare.m; path = ios/RCT/CameraFocusSquare.m; sourceTree = ""; }; 9313714DA10D502647A5804C554C9E9C /* RCTRedBox.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTRedBox.m; sourceTree = ""; }; 931DC9AD1E113DBEC5E592853085D6BD /* RCTImageLoader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTImageLoader.m; path = Libraries/Image/RCTImageLoader.m; sourceTree = ""; }; + 935E381EBEF80577BC49C958FCE8C692 /* GULObjectSwizzler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULObjectSwizzler.m; path = GoogleUtilities/ISASwizzler/GULObjectSwizzler.m; sourceTree = ""; }; 9375C7CBEBFF6AB1E5BDFD18BC069BB7 /* RCTTextViewManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTTextViewManager.m; sourceTree = ""; }; 9385A8EAF9C13A19B70C1E945A795A7A /* RCTResizeMode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTResizeMode.h; path = Libraries/Image/RCTResizeMode.h; sourceTree = ""; }; 93B2BA1259B01297817D30E62781994F /* LOTMask.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTMask.m; sourceTree = ""; }; + 93B301CFF46AAB8D6D41C82A86DE1A2A /* FKeyIndex.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FKeyIndex.m; path = Firebase/Database/FKeyIndex.m; sourceTree = ""; }; + 944176C892C7E452B815BCEBCBCC07B2 /* FAuthTokenProvider.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FAuthTokenProvider.m; path = Firebase/Database/Login/FAuthTokenProvider.m; sourceTree = ""; }; 9454F36934883700BC69C2C908D8BD2F /* ARTLinearGradient.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = ARTLinearGradient.h; sourceTree = ""; }; - 94A5A82BB6865C83B8A112721EB86BB8 /* FirebaseAnalytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseAnalytics.framework; path = Frameworks/FirebaseAnalytics.framework; sourceTree = ""; }; + 948383FCA22475A89A577753033C97D7 /* FLLRBEmptyNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FLLRBEmptyNode.m; path = Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBEmptyNode.m; sourceTree = ""; }; 94C9A54F15F62482D7C2F32220C15EFA /* RCTBorderDrawing.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTBorderDrawing.h; sourceTree = ""; }; - 94F478DC9FFEB03F60B3A9D8CAB4F8E6 /* GPBExtensionInternals.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBExtensionInternals.m; path = objectivec/GPBExtensionInternals.m; sourceTree = ""; }; - 9548E2A3E0F414AB329F84C569C84767 /* libRNVectorIcons.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libRNVectorIcons.a; path = libRNVectorIcons.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 956092396D8711436F8FD00E422519E4 /* FIRAppAssociationRegistration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAppAssociationRegistration.h; path = Firebase/Core/Private/FIRAppAssociationRegistration.h; sourceTree = ""; }; + 94E0F561370BA98565BFE8AB2C1009E0 /* utils.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = utils.h; path = "double-conversion/utils.h"; sourceTree = ""; }; + 9536222AC312336E96C37ACA5AB4A33F /* SourceContext.pbobjc.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SourceContext.pbobjc.h; path = objectivec/google/protobuf/SourceContext.pbobjc.h; sourceTree = ""; }; + 954AA7FCA35AB21D4C75C8AB916981FF /* FTupleTransaction.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTupleTransaction.h; path = Firebase/Database/Utilities/Tuples/FTupleTransaction.h; sourceTree = ""; }; 9593A2908BC72E3DDB3C560BE71A949C /* LOTBlockCallback.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTBlockCallback.m; sourceTree = ""; }; 95A88BC6BAA8776332E800F6D8721343 /* RCTModalHostViewManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTModalHostViewManager.h; sourceTree = ""; }; 95F6C360D03CD57ADA63299BC3F41F0F /* RCTShadowView+Layout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RCTShadowView+Layout.h"; sourceTree = ""; }; 96035D8119680BA9B467D0C29C63E0AB /* JSIndexedRAMBundle.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = JSIndexedRAMBundle.cpp; path = ReactCommon/cxxreact/JSIndexedRAMBundle.cpp; sourceTree = ""; }; + 961544B462C97D32FB08BBB712F6753C /* port_posix.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = port_posix.cc; path = port/port_posix.cc; sourceTree = ""; }; 962A34E023EEF408A4C1FBBEE8EF5956 /* RCTInputAccessoryView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTInputAccessoryView.m; sourceTree = ""; }; 963C60031331362932971E446AD1B316 /* RCTKeyCommands.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTKeyCommands.m; sourceTree = ""; }; 9647215CEFAEF77A6720B470AA9CCDB7 /* RCTImageEditingManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTImageEditingManager.m; path = Libraries/Image/RCTImageEditingManager.m; sourceTree = ""; }; - 965A11AA7991DDB3973C8D73A71FA994 /* Timestamp.pbobjc.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Timestamp.pbobjc.h; path = objectivec/google/protobuf/Timestamp.pbobjc.h; sourceTree = ""; }; + 9677C666B33082D8B27E6DCD72A275C6 /* GTMSessionFetcher.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTMSessionFetcher.m; path = Source/GTMSessionFetcher.m; sourceTree = ""; }; + 9693C764585DF4F21DC261BAC46C1B91 /* FEmptyNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FEmptyNode.m; path = Firebase/Database/Snapshot/FEmptyNode.m; sourceTree = ""; }; 96995B796E3EB652FC1CF2BE54246301 /* RCTAnimatedNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTAnimatedNode.m; sourceTree = ""; }; + 96B9292A43AC1761995175652F0BC87F /* dumpfile.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = dumpfile.h; path = include/leveldb/dumpfile.h; sourceTree = ""; }; + 96BB8CB87E982251038E03C2CC280BCC /* FOperationSource.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FOperationSource.m; path = Firebase/Database/Core/Operation/FOperationSource.m; sourceTree = ""; }; 96FFAB43B46C406A48BE65C22ACF11A8 /* RCTMaskedView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTMaskedView.h; sourceTree = ""; }; + 97038520199DADF5850A500588C4A880 /* FOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FOperation.h; path = Firebase/Database/Core/Operation/FOperation.h; sourceTree = ""; }; + 972D70808FEDD70C15F55B7E8015CC79 /* FTrackedQuery.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FTrackedQuery.m; path = Firebase/Database/Persistence/FTrackedQuery.m; sourceTree = ""; }; + 97386F1F30CB7CCC02F608D5C9331B09 /* FAckUserWrite.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FAckUserWrite.h; path = Firebase/Database/Core/Operation/FAckUserWrite.h; sourceTree = ""; }; 97539D7F20648B8EB3502B6C2D03DBA1 /* RNGestureHandlerManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNGestureHandlerManager.h; path = ios/RNGestureHandlerManager.h; sourceTree = ""; }; + 977D66020EA6D24E36A88FCB18A6AAE7 /* GTMSessionFetcher.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GTMSessionFetcher.xcconfig; sourceTree = ""; }; + 97CD5C8C1C395381AE311D463DC443A0 /* glog-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "glog-prefix.pch"; sourceTree = ""; }; + 981A7005F97321DE167E0284DA26CA96 /* FIRRetryHelper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRRetryHelper.h; path = Firebase/Database/Core/Utilities/FIRRetryHelper.h; sourceTree = ""; }; 9837195654E0E5D0866423166511174F /* LOTKeyframe.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTKeyframe.h; sourceTree = ""; }; - 9871279D3275A57A5741B76A1FA0C70C /* FIRDependency.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRDependency.m; path = Firebase/Core/FIRDependency.m; sourceTree = ""; }; + 986EF17779F9AA5EA7576D1E5564003F /* FIRMessagingDefines.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingDefines.h; path = Firebase/Messaging/FIRMessagingDefines.h; sourceTree = ""; }; 9876A397A877B549A95586B145C9EE7D /* RCTUITextField.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTUITextField.m; sourceTree = ""; }; - 9899A22E44EAB1314C1B352F982A23FF /* Format.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = Format.cpp; path = folly/Format.cpp; sourceTree = ""; }; - 98B477F61D2BA25FC56F9919E3D0F0A9 /* glog-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "glog-prefix.pch"; sourceTree = ""; }; - 98E6F329E8D9AF00DCF3E33E60A44F60 /* GoogleToolboxForMac.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleToolboxForMac.xcconfig; sourceTree = ""; }; - 98FC40A3FE46790AAADF0F447DBD2475 /* FIRComponentContainer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRComponentContainer.m; path = Firebase/Core/FIRComponentContainer.m; sourceTree = ""; }; + 98914BC1DAECE76E6A8DAEEE16262925 /* libleveldb-library.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libleveldb-library.a"; path = "libleveldb-library.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 9907C6D5C2C4CEC06370BFBC97558BBA /* JsArgumentHelpers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = JsArgumentHelpers.h; path = ReactCommon/cxxreact/JsArgumentHelpers.h; sourceTree = ""; }; 99AC6FD61CC9CE5CFDD66C16EDCB1862 /* RCTImageEditingManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTImageEditingManager.h; path = Libraries/Image/RCTImageEditingManager.h; sourceTree = ""; }; 99BF4EF72AC68820FF7468DE3C48BF43 /* RCTUITextView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTUITextView.h; sourceTree = ""; }; 99E8ADB319D634EF68B91446363EBB28 /* RCTProfile.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTProfile.m; sourceTree = ""; }; 9A10DDC391DD1168DCD24BD98A2F09C8 /* react-native-safari-view-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "react-native-safari-view-dummy.m"; sourceTree = ""; }; 9A4D7E1040FFE7B7D05950F04D10D4D5 /* RCTSourceCode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTSourceCode.m; sourceTree = ""; }; - 9A776103D69455946E4E465A746DF256 /* Fabric.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Fabric.xcconfig; sourceTree = ""; }; + 9A5D125A926C9A0A1A3FB1982E721273 /* log_writer.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = log_writer.cc; path = db/log_writer.cc; sourceTree = ""; }; + 9A94C572AA48C7A9AAD37504C253D08E /* GPBUtilities.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBUtilities.h; path = objectivec/GPBUtilities.h; sourceTree = ""; }; + 9AAC04F3C3C444DC723AADB405F3C67C /* histogram.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = histogram.cc; path = util/histogram.cc; sourceTree = ""; }; 9AAFA074082E4A3256D5E78B820DCE71 /* LOTShapeGradientFill.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTShapeGradientFill.m; sourceTree = ""; }; 9AE23F4F482B346105F1E47522631516 /* RCTSurfaceStage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTSurfaceStage.m; sourceTree = ""; }; 9AE6ABFDF7D0132D465F1710C4E9801C /* RCTTiming.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTTiming.m; sourceTree = ""; }; 9AF188074BA189C66E4E1A65F5CDF624 /* RCTRootShadowView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTRootShadowView.h; sourceTree = ""; }; + 9AF40F6C4A43F07E9A10444CB0C59005 /* Firebase.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Firebase.h; path = CoreOnly/Sources/Firebase.h; sourceTree = ""; }; 9B2395B1A24C8256313CFCB26A28628F /* RCTSegmentedControl.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTSegmentedControl.m; sourceTree = ""; }; - 9B60BC65335FEDFB242BAED10AA3B0BC /* GPBArray_PackagePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBArray_PackagePrivate.h; path = objectivec/GPBArray_PackagePrivate.h; sourceTree = ""; }; 9B6A85AD405BD0E5173260D69711368E /* RCTReconnectingWebSocket.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTReconnectingWebSocket.h; path = Libraries/WebSocket/RCTReconnectingWebSocket.h; sourceTree = ""; }; - 9B94044BB8213CE214598799507CBFEC /* nanopb.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = nanopb.xcconfig; sourceTree = ""; }; + 9BCD00A0A096989061C773F8C8DFD83E /* FirebaseABTesting.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseABTesting.xcconfig; sourceTree = ""; }; + 9BDB0946FE4427D7EE3CC47737533840 /* NSData+SRB64Additions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSData+SRB64Additions.h"; path = "Firebase/Database/third_party/SocketRocket/NSData+SRB64Additions.h"; sourceTree = ""; }; 9C07FEF5E885A590D9947B8369748384 /* RCTObjcExecutor.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTObjcExecutor.mm; sourceTree = ""; }; 9C2B7801CC73D3FD710970C5A7C482D8 /* LOTKeypath.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTKeypath.h; sourceTree = ""; }; - 9C51BCC2C2047CF29CEE5B7144FE4CDD /* GTMNSString+URLArguments.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "GTMNSString+URLArguments.h"; path = "Foundation/GTMNSString+URLArguments.h"; sourceTree = ""; }; + 9C7270A700555CE0EA21EFB5C5B0554F /* FArraySortedDictionary.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FArraySortedDictionary.h; path = Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FArraySortedDictionary.h; sourceTree = ""; }; + 9C76269F60F7AC52CC5655F057186C7F /* merger.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = merger.cc; path = table/merger.cc; sourceTree = ""; }; + 9CEF7B062307C23ED1E338D00919BA99 /* FirebaseInstanceID.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseInstanceID.xcconfig; sourceTree = ""; }; + 9D0545CF38D0D7BDE8CADA67D790B465 /* GULOriginalIMPConvenienceMacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULOriginalIMPConvenienceMacros.h; path = GoogleUtilities/MethodSwizzler/Private/GULOriginalIMPConvenienceMacros.h; sourceTree = ""; }; 9D1A6F8BDD2DAB53D53DD8EA9D835715 /* react-native-safari-view.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "react-native-safari-view.xcconfig"; sourceTree = ""; }; 9D270D704787AD78F293EB611F1E668A /* RCTDecayAnimation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTDecayAnimation.h; sourceTree = ""; }; 9D4E8486775DA51CF4544EDDA527A9FB /* RCTUIManagerObserverCoordinator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTUIManagerObserverCoordinator.h; sourceTree = ""; }; - 9D561A3F24666C785CEFA0514E9FB9F3 /* FirebaseCore-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FirebaseCore-dummy.m"; sourceTree = ""; }; 9D5AEC3E92139A5A8079F18E934BD643 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE; sourceTree = ""; }; 9D69450C3EF6D0FDE2FC78B917EDB6E7 /* NSTextStorage+FontScaling.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "NSTextStorage+FontScaling.m"; sourceTree = ""; }; - 9D8D7BB881323B238CADCF721026C5B7 /* GULAppEnvironmentUtil.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULAppEnvironmentUtil.m; path = GoogleUtilities/Environment/third_party/GULAppEnvironmentUtil.m; sourceTree = ""; }; + 9D7D22BFC36156A34EAAA455C211B9D3 /* FConnection.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FConnection.h; path = Firebase/Database/Realtime/FConnection.h; sourceTree = ""; }; 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; - 9DAA4CF4117F164B6489B04E99B3DDC8 /* FIRErrors.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRErrors.h; path = Firebase/Core/Private/FIRErrors.h; sourceTree = ""; }; 9DD0798D0E11306CF7CB526214125B12 /* ARTPattern.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = ARTPattern.m; sourceTree = ""; }; - 9DD45A1FEE98B97FA742D24D7BFFB9F7 /* libglog.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libglog.a; path = libglog.a; sourceTree = BUILT_PRODUCTS_DIR; }; 9DE6426BF193356B3A80DDBA62AC121C /* Pods-KalendTests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-KalendTests-acknowledgements.plist"; sourceTree = ""; }; - 9DFA54C268300CACAB672429F27F4893 /* FIROptions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIROptions.h; path = Firebase/Core/Public/FIROptions.h; sourceTree = ""; }; + 9E00DB364E41712CD057A8C1BF44424D /* FWriteTreeRef.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FWriteTreeRef.m; path = Firebase/Database/Core/FWriteTreeRef.m; sourceTree = ""; }; + 9E5F13FAEEFB31F2BE8766AFA672C020 /* FirebaseABTesting.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseABTesting.framework; path = Frameworks/FirebaseABTesting.framework; sourceTree = ""; }; 9E8C5436E24B27D30B420D1BA26753F1 /* RCTPerfMonitor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTPerfMonitor.m; sourceTree = ""; }; 9EAED3F23E1A902278FD103C4314106D /* RCTBridge.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTBridge.m; sourceTree = ""; }; 9EC17D24BD4FD110021C6321BAB74C63 /* RCTImageShadowView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTImageShadowView.m; path = Libraries/Image/RCTImageShadowView.m; sourceTree = ""; }; + 9EC86C9577627EF1AE803B92047DB36A /* GULLoggerCodes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULLoggerCodes.h; path = GoogleUtilities/Common/GULLoggerCodes.h; sourceTree = ""; }; 9EE1D050271A02AA3216858AAC75D93B /* FontAwesome5_Regular.ttf */ = {isa = PBXFileReference; includeInIndex = 1; name = FontAwesome5_Regular.ttf; path = Fonts/FontAwesome5_Regular.ttf; sourceTree = ""; }; 9F63C4E9A272851F08359BC3300FCAAE /* RCTScrollContentViewManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTScrollContentViewManager.m; sourceTree = ""; }; 9FB8CC10DA53B32F313CDFA6046DDD7C /* JSBigString.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = JSBigString.h; path = ReactCommon/cxxreact/JSBigString.h; sourceTree = ""; }; + 9FC8A2A184DB31E6141FB571B418F177 /* FIRDatabaseReference_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDatabaseReference_Private.h; path = Firebase/Database/Api/Private/FIRDatabaseReference_Private.h; sourceTree = ""; }; + 9FCAC1368EA1D0FB6A21074E4FFC222B /* pb_encode.c */ = {isa = PBXFileReference; includeInIndex = 1; path = pb_encode.c; sourceTree = ""; }; + 9FD16AF9100342B1DCBB284920DDBEF5 /* FTupleSetIdPath.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FTupleSetIdPath.m; path = Firebase/Database/Utilities/Tuples/FTupleSetIdPath.m; sourceTree = ""; }; + 9FD42A1D1EFDAD7F398B68B135BC9F5F /* FCachePolicy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FCachePolicy.m; path = Firebase/Database/Persistence/FCachePolicy.m; sourceTree = ""; }; 9FDA07E5331D72D53F6CDFE0B6343817 /* RCTDivisionAnimatedNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTDivisionAnimatedNode.m; sourceTree = ""; }; A02DF5A47E9FD63836FBCC6770451CBF /* RCTTextDecorationLineType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTTextDecorationLineType.h; sourceTree = ""; }; - A066CEC53E71610DC720C640B5F947AC /* FIRAnalyticsConfiguration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAnalyticsConfiguration.h; path = Firebase/Core/Public/FIRAnalyticsConfiguration.h; sourceTree = ""; }; + A031910DEC6962FD8A88B9BB9215E807 /* FEventRaiser.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FEventRaiser.m; path = Firebase/Database/Core/View/FEventRaiser.m; sourceTree = ""; }; A06D48ED73D4F7A71C9AF366A8615444 /* RCTDatePickerManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTDatePickerManager.h; sourceTree = ""; }; + A06E21DE99BB96DBF43EA033D82CFCDD /* FIRMessagingRmq2PersistentStore.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingRmq2PersistentStore.h; path = Firebase/Messaging/FIRMessagingRmq2PersistentStore.h; sourceTree = ""; }; + A0AE80D03F26B3B90DB417809B76E098 /* format.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = format.cc; path = table/format.cc; sourceTree = ""; }; + A0E18AA5B74FEBF3197D4099EE1AEA6E /* FIRAppInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAppInternal.h; path = Firebase/Core/Private/FIRAppInternal.h; sourceTree = ""; }; A12B66C8CE4E84C8F2B950757C6954F4 /* ARTRenderable.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ARTRenderable.h; path = Libraries/ART/ARTRenderable.h; sourceTree = ""; }; A15ACEF5251CA6929F77B10C034BAB29 /* RCTSurface.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSurface.h; sourceTree = ""; }; A16C9C5E95A7854C71E34B8CC45BDFF8 /* RCTNetworkTask.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTNetworkTask.h; path = Libraries/Network/RCTNetworkTask.h; sourceTree = ""; }; A1B11C8E6A6B0CF082119A417B2238A6 /* RecoverableError.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RecoverableError.h; path = ReactCommon/cxxreact/RecoverableError.h; sourceTree = ""; }; - A20E3A94B5CFE14A6601DBF6817B625A /* GoogleSignIn.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GoogleSignIn.framework; path = Frameworks/GoogleSignIn.framework; sourceTree = ""; }; + A1EC205FD86D69A4FA55F7CCCB1DBE80 /* libRNCAsyncStorage.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libRNCAsyncStorage.a; path = libRNCAsyncStorage.a; sourceTree = BUILT_PRODUCTS_DIR; }; + A21E69899E4D49D3B37623017C91600C /* FTreeNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FTreeNode.m; path = Firebase/Database/Core/Utilities/FTreeNode.m; sourceTree = ""; }; A2788A21B377EE2915E672FBD225D3DA /* SystraceSection.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SystraceSection.h; path = ReactCommon/cxxreact/SystraceSection.h; sourceTree = ""; }; A2B6C34F2F2C31419BA7F710BAD6948F /* RCTAssert.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTAssert.h; sourceTree = ""; }; - A2BE11A3B339E51FA7A12775C1F8C727 /* boost-for-react-native.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "boost-for-react-native.xcconfig"; sourceTree = ""; }; - A2FC2BDCA6C193274FC35FEFE7B968A3 /* Api.pbobjc.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = Api.pbobjc.m; path = objectivec/google/protobuf/Api.pbobjc.m; sourceTree = ""; }; + A2FD731CDB94C61CDE98166ABD6071E7 /* FIRNoopAuthTokenProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRNoopAuthTokenProvider.h; path = Firebase/Database/Login/FIRNoopAuthTokenProvider.h; sourceTree = ""; }; A3151CCFC8AEC370D96A9FF5E99AE30A /* RCTImageView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTImageView.m; path = Libraries/Image/RCTImageView.m; sourceTree = ""; }; + A32E5E0F146D5D98346795AB2202609C /* double-conversion.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "double-conversion.h"; path = "double-conversion/double-conversion.h"; sourceTree = ""; }; A35EF7FE5291708829E1F95972034ED8 /* React-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "React-dummy.m"; sourceTree = ""; }; A370A8D76A77EC077A9966F91063910A /* RNTapHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RNTapHandler.h; sourceTree = ""; }; + A382B5DEBE7AB4A099F71363217CE031 /* version_set.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = version_set.cc; path = db/version_set.cc; sourceTree = ""; }; + A39D995E238A995FA07E6668EF4C51AB /* FIRMessagingRegistrar.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingRegistrar.m; path = Firebase/Messaging/FIRMessagingRegistrar.m; sourceTree = ""; }; A415059A03A7CB62357072B5157F8F3B /* RCTBaseTextViewManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTBaseTextViewManager.h; sourceTree = ""; }; + A440D20566AE68C23C77B6587694AFA4 /* liblottie-ios.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "liblottie-ios.a"; path = "liblottie-ios.a"; sourceTree = BUILT_PRODUCTS_DIR; }; A4952194B682E2C59C8BEBE5B06C6BA7 /* JSIExecutor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = JSIExecutor.h; path = ReactCommon/jsiexecutor/jsireact/JSIExecutor.h; sourceTree = ""; }; - A52DFF00A66DC596AE662E6482F17420 /* vlog_is_on.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = vlog_is_on.cc; path = src/vlog_is_on.cc; sourceTree = ""; }; A5686B574C0F54F3F451488BC5747CDF /* RCTSurfaceView+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RCTSurfaceView+Internal.h"; sourceTree = ""; }; A571698B140D2045C589CBDEC0B09070 /* LOTAnimationView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTAnimationView.h; sourceTree = ""; }; - A58EC44B09EEA53BA369716C9DF9497F /* libFolly.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libFolly.a; path = libFolly.a; sourceTree = BUILT_PRODUCTS_DIR; }; + A5B1383C5CFB90D1E20E9E29C80E511F /* FIRMutableData.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMutableData.m; path = Firebase/Database/Api/FIRMutableData.m; sourceTree = ""; }; A62C6C913A3397E1FCC9116A412166B4 /* lottie-ios.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = "lottie-ios.podspec"; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + A635DF48E01E89FDD6731F6327F620EA /* FIRMessagingCheckinService.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingCheckinService.h; path = Firebase/Messaging/FIRMessagingCheckinService.h; sourceTree = ""; }; A63A7845D5D8252F25F776BCD60DB0B8 /* RNVectorIconsManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNVectorIconsManager.m; path = RNVectorIconsManager/RNVectorIconsManager.m; sourceTree = ""; }; + A665F0DDA5C86811B182E51C100CDCF7 /* FIRMessagingConnection.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingConnection.m; path = Firebase/Messaging/FIRMessagingConnection.m; sourceTree = ""; }; A6B4F7B695D7FFDC077B98D08BFCE260 /* LOTShapeRepeater.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTShapeRepeater.h; sourceTree = ""; }; A6BD5267B696C1517DEB35E481886AB1 /* LOTTransformInterpolator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTTransformInterpolator.m; sourceTree = ""; }; + A6CAB22B865E3D2DEA28B76B1E77BCFF /* FPruneForest.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FPruneForest.m; path = Firebase/Database/Persistence/FPruneForest.m; sourceTree = ""; }; A720011F7BD486F3A952633092E5AE78 /* ARTContainer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ARTContainer.h; path = Libraries/ART/ARTContainer.h; sourceTree = ""; }; A72C619251A9096ADB9C7E0C7C73069B /* NSMutableDictionary+ImageMetadata.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSMutableDictionary+ImageMetadata.m"; path = "ios/RCT/NSMutableDictionary+ImageMetadata.m"; sourceTree = ""; }; - A7528D347E330AA90943C4E0F75EFF1B /* Any.pbobjc.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Any.pbobjc.h; path = objectivec/google/protobuf/Any.pbobjc.h; sourceTree = ""; }; + A77A71A83A721E62043AB541BFEBF0BD /* Any.pbobjc.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Any.pbobjc.h; path = objectivec/google/protobuf/Any.pbobjc.h; sourceTree = ""; }; A7943ABFECCB8CEB221228123155B36D /* YGNode.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = YGNode.cpp; path = yoga/YGNode.cpp; sourceTree = ""; }; A7B22B44D0055B4FEBC93443C5396239 /* UIBezierPath.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = UIBezierPath.m; sourceTree = ""; }; + A80DF0C102E3EA656E87DBE7A9FF4F08 /* FImmutableSortedDictionary.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FImmutableSortedDictionary.m; path = Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FImmutableSortedDictionary.m; sourceTree = ""; }; + A844DA2D4F3B499538E16BED3E72F98C /* table_cache.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = table_cache.cc; path = db/table_cache.cc; sourceTree = ""; }; A87059FF49429D002A86F2E59B178E5D /* LOTValueCallback.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTValueCallback.h; sourceTree = ""; }; + A87E72714A0CB0D74D50BA450CCF834B /* FIRMessagingSecureSocket.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingSecureSocket.m; path = Firebase/Messaging/FIRMessagingSecureSocket.m; sourceTree = ""; }; A890C30E0C5AE2973D5A95747EAFFCD4 /* JSCRuntime.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = JSCRuntime.cpp; path = ReactCommon/jsi/JSCRuntime.cpp; sourceTree = ""; }; A8C80E4172C72EF5A2E25B2F4B0056D3 /* JSIDynamic.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = JSIDynamic.cpp; path = ReactCommon/jsi/JSIDynamic.cpp; sourceTree = ""; }; + A8CFE27B14FB420A8984CD394175B732 /* FWriteRecord.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FWriteRecord.m; path = Firebase/Database/Core/FWriteRecord.m; sourceTree = ""; }; A912E2564D55F3C9C4C2676D6973C880 /* RCTTrackingAnimatedNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTTrackingAnimatedNode.h; sourceTree = ""; }; + A942DB8E6AD6323C241EC1569B908905 /* pb_decode.c */ = {isa = PBXFileReference; includeInIndex = 1; path = pb_decode.c; sourceTree = ""; }; A96DF853EEF2E09A81C89D05EAAD8DB3 /* RNFaceDetectorModuleMLKit.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNFaceDetectorModuleMLKit.m; path = ios/RN/RNFaceDetectorModuleMLKit.m; sourceTree = ""; }; + A996778AA6C82C606288542E389E64D1 /* fbase64.c */ = {isa = PBXFileReference; includeInIndex = 1; name = fbase64.c; path = Firebase/Database/third_party/SocketRocket/fbase64.c; sourceTree = ""; }; A99DABEC949DF08F3FBCD984E1AB7A97 /* RCTSurfaceSizeMeasureMode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSurfaceSizeMeasureMode.h; sourceTree = ""; }; + A9A13C7FD650007FE0BC0CE9DAC2D0FE /* libyoga.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libyoga.a; path = libyoga.a; sourceTree = BUILT_PRODUCTS_DIR; }; A9B0F1B7B070C44944D560B5882D048E /* ARTBrush.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = ARTBrush.h; sourceTree = ""; }; A9DCDCA15045807E09FAAF6884D391A1 /* RCTSensorOrientationChecker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTSensorOrientationChecker.h; path = ios/RCT/RCTSensorOrientationChecker.h; sourceTree = ""; }; AA134FE3E7902FD59B5DFAE116D13DF1 /* JSCRuntime.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = JSCRuntime.h; path = ReactCommon/jsi/JSCRuntime.h; sourceTree = ""; }; AA2CB2DBE166F9507D94091F7015431F /* RCTShadowView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTShadowView.h; sourceTree = ""; }; AA47157636374C230D1A4A9509BAD018 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; }; AA47B680DDAD19C7E18F4F7A21F31D34 /* InspectorInterfaces.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = InspectorInterfaces.h; path = ReactCommon/jsinspector/InspectorInterfaces.h; sourceTree = ""; }; + AA83A1F88B9D90E1ECE2A9C296AF07B5 /* FClock.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FClock.m; path = Firebase/Database/FClock.m; sourceTree = ""; }; AA89CDE0FD215108668B065F3BED453C /* RNNativeViewHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RNNativeViewHandler.h; sourceTree = ""; }; AAA8FD0DB1334F6D0E1A77D3797040A5 /* RCTSurfaceHostingView.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTSurfaceHostingView.mm; sourceTree = ""; }; - AB062FB5FE3CA4C8C4BA1594452B88EA /* strtod.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = strtod.h; path = "double-conversion/strtod.h"; sourceTree = ""; }; AB1869756BBD1A29757ED8E2F3E40795 /* LOTMask.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTMask.h; sourceTree = ""; }; AB1EAD16533C88F11FC3DD170FC841E1 /* RNPanHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RNPanHandler.h; sourceTree = ""; }; + AB8A9CADCFA27F2AF11A9FF2DDEEE4F9 /* GoogleAppMeasurement.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleAppMeasurement.xcconfig; sourceTree = ""; }; + AB9F058E8DFCEF13A69CAD294274BF95 /* leveldb-library-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "leveldb-library-dummy.m"; sourceTree = ""; }; + ABC865F02D8659D4C60C31F9E9C3A82D /* FEvent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FEvent.h; path = Firebase/Database/Core/View/FEvent.h; sourceTree = ""; }; ABD6CA6A8368CF9FD7A49E916DF975EB /* RCTEventEmitter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTEventEmitter.m; sourceTree = ""; }; - ABE121B8F8204830E2DDDB9E6E0B724E /* SourceContext.pbobjc.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SourceContext.pbobjc.m; path = objectivec/google/protobuf/SourceContext.pbobjc.m; sourceTree = ""; }; - ABED08F5DBD737384350543B1E1BBA36 /* CLSStackFrame.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CLSStackFrame.h; path = iOS/Crashlytics.framework/Headers/CLSStackFrame.h; sourceTree = ""; }; AC3939EFE51775126A54F9E9F4B5B29B /* UIColor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = UIColor.m; sourceTree = ""; }; + AC6D6A725BC22F15370F6E9C5FACFD65 /* GoogleSignIn.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GoogleSignIn.framework; path = Frameworks/GoogleSignIn.framework; sourceTree = ""; }; AC70AA5633E0D9EE05B6E8C3E39A690E /* LRNContainerView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = LRNContainerView.m; path = src/ios/LottieReactNative/LRNContainerView.m; sourceTree = ""; }; + AC776B24502D3481FED95A67A2A42097 /* FirebaseRemoteConfig.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseRemoteConfig.framework; path = Frameworks/FirebaseRemoteConfig.framework; sourceTree = ""; }; + ACDA9668469FE07E1CDC60A09A2E0022 /* comparator.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = comparator.cc; path = util/comparator.cc; sourceTree = ""; }; ACDC49CC344315810A5B1ABC3B8A9E94 /* RCTAlertManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTAlertManager.h; sourceTree = ""; }; + ACF4AA6F7523E7457E2508CB97A2AE10 /* GoogleSignIn.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleSignIn.xcconfig; sourceTree = ""; }; AD53BF71BFBF5866E9D8F71D2BD1EC27 /* Example3.gif */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.gif; name = Example3.gif; path = docs/gifs/Example3.gif; sourceTree = ""; }; - AD5955431A3FCFA7048680B4C25EF64C /* raw_logging.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = raw_logging.cc; path = src/raw_logging.cc; sourceTree = ""; }; ADDD300F9C23E80F3E6FA0782C1F0C57 /* RNLongPressHandler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RNLongPressHandler.m; sourceTree = ""; }; + ADE2305F8ACE4C5E55537E2552D21731 /* fbase64.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = fbase64.h; path = Firebase/Database/third_party/SocketRocket/fbase64.h; sourceTree = ""; }; ADEA670AC3587B44335EF35185F3C745 /* JSDeltaBundleClient.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = JSDeltaBundleClient.h; path = ReactCommon/cxxreact/JSDeltaBundleClient.h; sourceTree = ""; }; AE05C0B725F26A95F95934A61F017ECE /* CameraFocusSquare.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CameraFocusSquare.h; path = ios/RCT/CameraFocusSquare.h; sourceTree = ""; }; AE2F6E3DD9D915040FECF56B5EBB7AA7 /* RCTPropsAnimatedNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTPropsAnimatedNode.h; sourceTree = ""; }; AE67D79860AECE78E639E63EC2E5029E /* Pods-Kalend-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Kalend-acknowledgements.markdown"; sourceTree = ""; }; AE6B99406B524DEF7EEE3CC82DFA539B /* LOTNumberInterpolator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTNumberInterpolator.m; sourceTree = ""; }; + AE7A6AB9927CAC8E535EFB9EA04B6211 /* FMaxNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FMaxNode.m; path = Firebase/Database/FMaxNode.m; sourceTree = ""; }; AE9AB4AB24FCE91AC2DB08BE8B6E5D19 /* RCTNativeAnimatedModule.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTNativeAnimatedModule.h; path = Libraries/NativeAnimation/RCTNativeAnimatedModule.h; sourceTree = ""; }; AEAB205567BE19020EB024CF512C8832 /* RCTProfile.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTProfile.h; sourceTree = ""; }; AEE02FAFB329C410ADF0DEC592C517CF /* CxxNativeModule.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = CxxNativeModule.cpp; path = ReactCommon/cxxreact/CxxNativeModule.cpp; sourceTree = ""; }; AF07C7326B260A90BBB39545CE1A42B9 /* LOTAnimatedControl.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTAnimatedControl.m; sourceTree = ""; }; AF28386D4445A464FEEEC4A5F0DCEA17 /* RNGestureHandlerRegistry.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNGestureHandlerRegistry.m; path = ios/RNGestureHandlerRegistry.m; sourceTree = ""; }; AF60CAE211EC3F73A3B88CD598800AD4 /* YGStyle.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = YGStyle.cpp; path = yoga/YGStyle.cpp; sourceTree = ""; }; - AF63990D5314AA2FE6B12AB99651E4D4 /* diy-fp.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = "diy-fp.cc"; path = "double-conversion/diy-fp.cc"; sourceTree = ""; }; AF8360F204358EC43CD59AA05AC1D09F /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE; sourceTree = ""; }; - AFD44EF8E63D08F65BFAC2B9A64F48C7 /* utils.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = utils.h; path = "double-conversion/utils.h"; sourceTree = ""; }; - AFF5C24E7B1C59368C5150DB1C38082E /* GPBWellKnownTypes.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBWellKnownTypes.m; path = objectivec/GPBWellKnownTypes.m; sourceTree = ""; }; - AFFFC489744C1B215B7F1528408797BA /* libFirebaseCore.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libFirebaseCore.a; path = libFirebaseCore.a; sourceTree = BUILT_PRODUCTS_DIR; }; + AF8C098D4570B1F9F98B038CCEF57632 /* FIRMutableData.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMutableData.h; path = Firebase/Database/Public/FIRMutableData.h; sourceTree = ""; }; + AFE4F3AA1A28BE43D9287AFBB26703D0 /* FTreeSortedDictionaryEnumerator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTreeSortedDictionaryEnumerator.h; path = Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FTreeSortedDictionaryEnumerator.h; sourceTree = ""; }; B00149D139B98EBDFEDADD6B0EC3ABDF /* RCTWrapperViewController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTWrapperViewController.m; sourceTree = ""; }; B00ADF8372DC0454091CF0BB4BBAB371 /* RNGestureHandlerState.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNGestureHandlerState.h; path = ios/RNGestureHandlerState.h; sourceTree = ""; }; + B03BC145252CE9439EBA6193ED4FD670 /* FViewProcessor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FViewProcessor.h; path = Firebase/Database/FViewProcessor.h; sourceTree = ""; }; + B061BDF4E0105DD15FEB9AB6612DF344 /* GULNSData+zlib.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "GULNSData+zlib.h"; path = "GoogleUtilities/NSData+zlib/GULNSData+zlib.h"; sourceTree = ""; }; B07170B241B133AB5FC213C44A441840 /* Pods-Kalend-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Kalend-acknowledgements.plist"; sourceTree = ""; }; B079E7551271DB9993BC2E10B6003DFA /* RCTPackagerClient.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTPackagerClient.h; sourceTree = ""; }; - B08791541E4426FA32DDA9485ED88B0A /* json_pointer.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = json_pointer.cpp; path = folly/json_pointer.cpp; sourceTree = ""; }; + B091C318F79526158445BD1BEA70EE1D /* c.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = c.h; path = include/leveldb/c.h; sourceTree = ""; }; B11BF4BE90DD52473A3ECCD891DA90A9 /* RNForceTouchHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RNForceTouchHandler.h; sourceTree = ""; }; B14617709A54F5147344A857FBB2E9D6 /* RCTSurfaceHostingProxyRootView.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTSurfaceHostingProxyRootView.mm; sourceTree = ""; }; - B1681002ADBD3BB27EBF6CCCBB750356 /* utilities.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = utilities.cc; path = src/utilities.cc; sourceTree = ""; }; B17DCFD337394DD83E0C87CCBE659BE1 /* RCTSurfaceStage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSurfaceStage.h; sourceTree = ""; }; B180FDEA9837D85FA70FC4346B89A0F7 /* NativeToJsBridge.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = NativeToJsBridge.h; path = ReactCommon/cxxreact/NativeToJsBridge.h; sourceTree = ""; }; + B19B6B724947A15AD078508AEDEC16E9 /* FTupleBoolBlock.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTupleBoolBlock.h; path = Firebase/Database/Utilities/Tuples/FTupleBoolBlock.h; sourceTree = ""; }; + B1AE50A8879222641AC18419CDDD872B /* FSyncPoint.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FSyncPoint.m; path = Firebase/Database/Core/FSyncPoint.m; sourceTree = ""; }; + B1C82826976D3CFD04CA34287A43BC42 /* Folly-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Folly-prefix.pch"; sourceTree = ""; }; B1CC0A71DEA435BB7C60D76EFBF14248 /* ARTSurfaceView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = ARTSurfaceView.m; path = Libraries/ART/ARTSurfaceView.m; sourceTree = ""; }; B1D11BB4203DEDE80F5C0B6C81F252D2 /* LOTComposition.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTComposition.m; sourceTree = ""; }; + B1F3079B96D41B5A86AA71A071EC3373 /* FIndex.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIndex.h; path = Firebase/Database/FIndex.h; sourceTree = ""; }; B20196913BE8DF3AE3B8CA0D4BA820B3 /* RCTImageStoreManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTImageStoreManager.m; path = Libraries/Image/RCTImageStoreManager.m; sourceTree = ""; }; + B23331D08F0FB92619826BCF638468EC /* GULReachabilityChecker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULReachabilityChecker.h; path = GoogleUtilities/Reachability/Private/GULReachabilityChecker.h; sourceTree = ""; }; + B234D6101F861EA4DDA1FAF741BCDDDC /* FIRMessagingTopicsCommon.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingTopicsCommon.h; path = Firebase/Messaging/FIRMessagingTopicsCommon.h; sourceTree = ""; }; B2526A953CFDECE87D286CB079F7960B /* RNFetchBlobProgress.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNFetchBlobProgress.h; path = ios/RNFetchBlobProgress.h; sourceTree = ""; }; - B27A960FDD399A1F54CDD8A1001C653A /* Demangle.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = Demangle.cpp; path = folly/Demangle.cpp; sourceTree = ""; }; + B2633AA729012C8F9A895D11943A5963 /* ANSCompatibility.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ANSCompatibility.h; path = iOS/Crashlytics.framework/Headers/ANSCompatibility.h; sourceTree = ""; }; + B2637FDEA1D9A58931B3F5B9C8B06F0F /* json.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = json.cpp; path = folly/json.cpp; sourceTree = ""; }; B29FC6C848393BBCD0A6F9EA4A954B73 /* ARTGroupManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = ARTGroupManager.h; sourceTree = ""; }; + B2D2639C87FF020213A738A3AB5154DA /* libreact-native-slider.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libreact-native-slider.a"; path = "libreact-native-slider.a"; sourceTree = BUILT_PRODUCTS_DIR; }; B37984E6B75620169C999C514D4145A2 /* RCTCameraManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTCameraManager.h; path = ios/RCT/RCTCameraManager.h; sourceTree = ""; }; - B3BB7130EFA148C5F3F281D62152FE76 /* GTMSessionUploadFetcher.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTMSessionUploadFetcher.m; path = Source/GTMSessionUploadFetcher.m; sourceTree = ""; }; + B3B50DE72F5CD916F93A5496C7473931 /* FIRCoreConfigurable.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRCoreConfigurable.h; path = Firebase/Core/Private/FIRCoreConfigurable.h; sourceTree = ""; }; B3D9AA395B8A6E438AEB2F16D98D26EB /* RCTFont+FA5.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "RCTFont+FA5.m"; path = "RNVectorIconsManager/RCTFont+FA5.m"; sourceTree = ""; }; - B43C5CAB0FF24DA68A1B4B097044C880 /* GPBProtocolBuffers_RuntimeSupport.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBProtocolBuffers_RuntimeSupport.h; path = objectivec/GPBProtocolBuffers_RuntimeSupport.h; sourceTree = ""; }; - B5DDE4132759E6E19918282C11B5F81A /* GTMSessionFetcher.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTMSessionFetcher.m; path = Source/GTMSessionFetcher.m; sourceTree = ""; }; + B3E04C62ED98682FE35D19F1871D4B6F /* FKeepSyncedEventRegistration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FKeepSyncedEventRegistration.h; path = Firebase/Database/Core/View/FKeepSyncedEventRegistration.h; sourceTree = ""; }; + B401B96BDEDB3229635D97BF950291A2 /* GPBMessage_PackagePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBMessage_PackagePrivate.h; path = objectivec/GPBMessage_PackagePrivate.h; sourceTree = ""; }; + B41F99C2DD0AA870E1DEAC36E815B58D /* Format.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = Format.cpp; path = folly/Format.cpp; sourceTree = ""; }; + B48DB19E655254729291192628C71D52 /* Crashlytics.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Crashlytics.xcconfig; sourceTree = ""; }; + B4AD0B7F0736B586F077CD29A43498C0 /* FMerge.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FMerge.h; path = Firebase/Database/Core/Operation/FMerge.h; sourceTree = ""; }; + B52E090772086382345A487E8AF24146 /* FIndexedFilter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIndexedFilter.h; path = Firebase/Database/Core/View/Filter/FIndexedFilter.h; sourceTree = ""; }; + B5B93839F37E7D38E19CAD266E896292 /* crc32c.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = crc32c.h; path = util/crc32c.h; sourceTree = ""; }; + B5C7AABDAD319DCAA5D16BB307B85F74 /* Protobuf-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Protobuf-prefix.pch"; sourceTree = ""; }; + B5CAF3C5A56B499167AC157F5AA1E79C /* FRepoManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FRepoManager.m; path = Firebase/Database/Core/FRepoManager.m; sourceTree = ""; }; + B5D74D035F6118E5350D969D8DD10787 /* FTupleCallbackStatus.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FTupleCallbackStatus.m; path = Firebase/Database/Utilities/Tuples/FTupleCallbackStatus.m; sourceTree = ""; }; + B5E89629B0CB240B5BA5202F26C219A7 /* status.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = status.h; path = include/leveldb/status.h; sourceTree = ""; }; + B5FA10934409CED2B3FD4C266168AD26 /* GTMLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMLogger.h; path = Foundation/GTMLogger.h; sourceTree = ""; }; + B647F3C3F6873E7E8E7E77C89EE80A03 /* FWriteTree.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FWriteTree.h; path = Firebase/Database/Core/FWriteTree.h; sourceTree = ""; }; B65142D3B750A2DAA58F5BDBBECACD56 /* RCTWKWebView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTWKWebView.h; sourceTree = ""; }; B65830077D8C098B52B977E4E16CAB6B /* RCTSafeAreaShadowView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTSafeAreaShadowView.m; sourceTree = ""; }; B6605BA749FD76B2032CD81CFB54D3B3 /* PinJump.gif */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.gif; name = PinJump.gif; path = docs/gifs/PinJump.gif; sourceTree = ""; }; B6802A885D9F93CD0A522ED9ED5E718F /* RCTBackedTextInputDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTBackedTextInputDelegate.h; sourceTree = ""; }; B68DFCB9A0593F93495976476EAA6DEA /* Example2.gif */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.gif; name = Example2.gif; path = docs/gifs/Example2.gif; sourceTree = ""; }; B6B07643917C9FF00A76C2B091742CF4 /* RCTKeyCommands.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTKeyCommands.h; sourceTree = ""; }; + B6EF56F996D239DC5D0F14C3E7E83114 /* GPBCodedInputStream.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBCodedInputStream.m; path = objectivec/GPBCodedInputStream.m; sourceTree = ""; }; B6FB979B8E4C2388378AB967B13FFFAC /* RCTI18nUtil.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTI18nUtil.h; sourceTree = ""; }; B6FDE9433C6656CAEB210366F1BD4DC8 /* MaterialIcons.ttf */ = {isa = PBXFileReference; includeInIndex = 1; name = MaterialIcons.ttf; path = Fonts/MaterialIcons.ttf; sourceTree = ""; }; B70B5703A021E8A82E96B815A562911C /* RCTReloadCommand.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTReloadCommand.h; sourceTree = ""; }; - B71607B0576176404F452DD809E993D0 /* fast-dtoa.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "fast-dtoa.h"; path = "double-conversion/fast-dtoa.h"; sourceTree = ""; }; B725E4A7DA69A23B0480624F11C61823 /* LOTShapeStar.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTShapeStar.m; sourceTree = ""; }; B7A399176373C8AA1A6610E3132E23B1 /* LOTShapeTrimPath.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTShapeTrimPath.m; sourceTree = ""; }; B7AE9A9D4A1B61B6EB9705A39931B56B /* RCTLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTLayout.h; sourceTree = ""; }; B80195DC6DFD29FEE0CCAF6EF891B51A /* RCTSafeAreaShadowView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSafeAreaShadowView.h; sourceTree = ""; }; + B8117D0312D0C6A5E6D959942D8477AB /* FIRAppAssociationRegistration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRAppAssociationRegistration.m; path = Firebase/Core/FIRAppAssociationRegistration.m; sourceTree = ""; }; B8438D27F7F395EBCA298C48C6D2D2FF /* RCTNetInfo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTNetInfo.m; path = Libraries/Network/RCTNetInfo.m; sourceTree = ""; }; B86F6404D1245E652DEBCF670CA27A4B /* RNGestureHandlerRegistry.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNGestureHandlerRegistry.h; path = ios/RNGestureHandlerRegistry.h; sourceTree = ""; }; B8BF1A988BE76405BD305A08EB0484A9 /* ARTShapeManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = ARTShapeManager.m; sourceTree = ""; }; B8CAE2B67E055AAE161B2AFEC59A9566 /* RCTDatePicker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTDatePicker.h; sourceTree = ""; }; - B9081F23DE9B5CE80A9F7E36382251BD /* GPBWireFormat.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBWireFormat.h; path = objectivec/GPBWireFormat.h; sourceTree = ""; }; B90C4CD68F9CF6F0AE47AF3FBBDCB56C /* RCTCxxConvert.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTCxxConvert.h; sourceTree = ""; }; + B92D1B13AFFAD16CE0CDDF43FE71D1C0 /* GTMSessionUploadFetcher.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTMSessionUploadFetcher.m; path = Source/GTMSessionUploadFetcher.m; sourceTree = ""; }; B932271FB81CB35C7C0424FE0293122B /* FaceDetectorManagerMlkit.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FaceDetectorManagerMlkit.h; path = ios/RN/FaceDetectorManagerMlkit.h; sourceTree = ""; }; - B940312F1597EF5B430898726144532D /* GTMSessionFetcher.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GTMSessionFetcher.xcconfig; sourceTree = ""; }; B957823DE0B2159383BA55754DD618C7 /* RCTMultilineTextInputViewManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTMultilineTextInputViewManager.m; sourceTree = ""; }; - B9774DBEB2D9E947C193E108F5037DA0 /* Wrappers.pbobjc.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = Wrappers.pbobjc.m; path = objectivec/google/protobuf/Wrappers.pbobjc.m; sourceTree = ""; }; + B991E2493BC8E88470D17EF78E3D3A3C /* FNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FNode.h; path = Firebase/Database/Snapshot/FNode.h; sourceTree = ""; }; + B9ADE36B8790FDCE7F8382ADFE37F0AD /* FIRBundleUtil.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRBundleUtil.h; path = Firebase/Core/Private/FIRBundleUtil.h; sourceTree = ""; }; B9E0C3F7D941425B2461E5751C15ADF1 /* RCTNativeModule.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTNativeModule.mm; sourceTree = ""; }; BA0DB2822EBD8DA710A39C21BC6F6B7C /* react-navigation.md */ = {isa = PBXFileReference; includeInIndex = 1; name = "react-navigation.md"; path = "docs/react-navigation.md"; sourceTree = ""; }; + BA20E7E90F36B7CFF0BDC2A7B376EED9 /* FirebaseDatabase.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseDatabase.xcconfig; sourceTree = ""; }; + BA438D914FD85D28EB649CD0E6157459 /* FView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FView.h; path = Firebase/Database/Core/View/FView.h; sourceTree = ""; }; + BA58397C32C68A5294911C70B2608DD8 /* GoogleToolboxForMac.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleToolboxForMac.xcconfig; sourceTree = ""; }; BAA66F78FD1BB2023BC7506B6B680E6E /* LOTAsset.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTAsset.h; sourceTree = ""; }; BAC680A655CEE3D1226D0DF6DACB29D5 /* RCTUIManagerUtils.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTUIManagerUtils.m; sourceTree = ""; }; BAE3AC60F51B43A3E006A2BFB91E3CE5 /* RCTProfileTrampoline-x86_64.S */ = {isa = PBXFileReference; includeInIndex = 1; path = "RCTProfileTrampoline-x86_64.S"; sourceTree = ""; }; - BB089FC3285722B2E922DC1AE785160A /* ScopeGuard.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = ScopeGuard.cpp; path = folly/ScopeGuard.cpp; sourceTree = ""; }; BB59F911BFDED0926E861FB7D6D313D4 /* LOTLayer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTLayer.m; sourceTree = ""; }; - BBB105BF3615DD99C8BDB51065E1D6F3 /* GPBRootObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBRootObject.h; path = objectivec/GPBRootObject.h; sourceTree = ""; }; + BBE854992F5608033BEF94135B5A8FC2 /* iterator.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = iterator.cc; path = table/iterator.cc; sourceTree = ""; }; BBE863A5A18F7C2BAFE03967B327F6B9 /* RCTI18nUtil.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTI18nUtil.m; sourceTree = ""; }; BBF2272B1A787903B2FB330832E0A312 /* RCTAdditionAnimatedNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTAdditionAnimatedNode.h; sourceTree = ""; }; BC13A64008F9C0F3B569239F2C565486 /* RCTImageStoreManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTImageStoreManager.h; path = Libraries/Image/RCTImageStoreManager.h; sourceTree = ""; }; - BC243429357134BED3601064EB41CDC2 /* libyoga.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libyoga.a; path = libyoga.a; sourceTree = BUILT_PRODUCTS_DIR; }; + BC151BD4C4B5CFCE88605416C591816B /* FEventEmitter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FEventEmitter.m; path = Firebase/Database/Utilities/FEventEmitter.m; sourceTree = ""; }; BC4084335C8BB1D294748F7006D98878 /* RCTActivityIndicatorViewManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTActivityIndicatorViewManager.h; sourceTree = ""; }; + BC487B47C2B96C67BEA917671F02DB85 /* FirebaseAnalytics.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseAnalytics.xcconfig; sourceTree = ""; }; BC6ED2451D7533FC61CD6E8DEDC4623F /* RCTDatePickerManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTDatePickerManager.m; sourceTree = ""; }; BC73B0FC9B3AC70C2CB7F58F34CDFB0B /* RCTPicker.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTPicker.m; sourceTree = ""; }; BC887ADD7DE12B30A345C72686EC603A /* jsi-inl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "jsi-inl.h"; path = "ReactCommon/jsi/jsi-inl.h"; sourceTree = ""; }; + BC8B62A2E1B21D7D1EF6B9EDCDC01935 /* Crashlytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Crashlytics.framework; path = iOS/Crashlytics.framework; sourceTree = ""; }; BCFE35AC82A2303C93F12BC734B0D9A4 /* RCTResizeMode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTResizeMode.m; path = Libraries/Image/RCTResizeMode.m; sourceTree = ""; }; BD43401BDCCF005FE929D4B0B6F32221 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; }; BD5638C504C69F0A7738C3C135478BFB /* react-native-camera-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "react-native-camera-prefix.pch"; sourceTree = ""; }; BD7C6997D0323588A4202F3D69FF9640 /* LOTFillRenderer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTFillRenderer.h; sourceTree = ""; }; - BD9521758003CF81234DC8B5C4D59376 /* FIRComponent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRComponent.m; path = Firebase/Core/FIRComponent.m; sourceTree = ""; }; + BD84C78C51CE9A9263693F3444B7571E /* FChildrenNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FChildrenNode.m; path = Firebase/Database/Snapshot/FChildrenNode.m; sourceTree = ""; }; BDAF4D00242A8AA51DB03DCB87800F6E /* RCTFont.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTFont.mm; sourceTree = ""; }; + BDB3F378ED3191C4E52C52675F76AB45 /* FIRServerValue.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRServerValue.h; path = Firebase/Database/Public/FIRServerValue.h; sourceTree = ""; }; BDB62C96CE74FA6EEB5A0576D2402A2B /* RCTCxxUtils.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTCxxUtils.h; sourceTree = ""; }; BDD4FD7DCCE03AA492F5C7E9434723F1 /* RCTFollyConvert.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTFollyConvert.h; sourceTree = ""; }; + BE0D558DC88FD688F6668DFDAF4F95EA /* FIRDatabase.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRDatabase.m; path = Firebase/Database/Api/FIRDatabase.m; sourceTree = ""; }; + BE36269AD6FB60A9259105E262E4081E /* FRangedFilter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FRangedFilter.h; path = Firebase/Database/FRangedFilter.h; sourceTree = ""; }; BE49BF6A5B015C7C7A205AC35FBF1525 /* RCTModalHostView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTModalHostView.m; sourceTree = ""; }; - BECFE46C4D035B9D9F991722AA0B59BC /* Protobuf-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Protobuf-dummy.m"; sourceTree = ""; }; + BE9CA43AFEEF958245EE8ACFBEE39DDE /* FRangeMerge.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FRangeMerge.m; path = Firebase/Database/Core/FRangeMerge.m; sourceTree = ""; }; BED260FE5E6E1A5CE4B4C23893EC330C /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; }; - BEFB98ED37598B87DC7616F39F161E8A /* Wrappers.pbobjc.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Wrappers.pbobjc.h; path = objectivec/google/protobuf/Wrappers.pbobjc.h; sourceTree = ""; }; - BF207081B235EAF25864BC44066D2241 /* GULLoggerLevel.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULLoggerLevel.h; path = GoogleUtilities/Logger/Public/GULLoggerLevel.h; sourceTree = ""; }; + BF0053A92A3441539945F1004FF4F28A /* FIRMessagingDataMessageManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingDataMessageManager.m; path = Firebase/Messaging/FIRMessagingDataMessageManager.m; sourceTree = ""; }; + BF0EB3589EDFE0B529D244E5F911C9F0 /* GPBDictionary.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBDictionary.h; path = objectivec/GPBDictionary.h; sourceTree = ""; }; + BF22DB6374FFB9A50C6A86CFB0C76AA5 /* FTupleBoolBlock.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FTupleBoolBlock.m; path = Firebase/Database/Utilities/Tuples/FTupleBoolBlock.m; sourceTree = ""; }; BF82EF2FF5E8C12B2AA4472A4D67D160 /* RCTModuleData.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTModuleData.h; sourceTree = ""; }; BFA9B121FEB246D503568A770F36E532 /* JSCExecutorFactory.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = JSCExecutorFactory.mm; sourceTree = ""; }; + BFAA8B4261AA8616E6962307CE1E10B6 /* FIRTransactionResult.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRTransactionResult.h; path = Firebase/Database/Public/FIRTransactionResult.h; sourceTree = ""; }; BFD26887E45894A817B4BC60D0CB1E3B /* RCTImageSource.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTImageSource.h; sourceTree = ""; }; + BFE57F24EAB84A4526072597675704F6 /* GULLoggerLevel.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULLoggerLevel.h; path = GoogleUtilities/Logger/Public/GULLoggerLevel.h; sourceTree = ""; }; + BFF0522100C085C847D645AB1139E93C /* GTMSessionFetcherLogging.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMSessionFetcherLogging.h; path = Source/GTMSessionFetcherLogging.h; sourceTree = ""; }; + C03D805F3E975FCDCB26979447EF0A9C /* GtalkExtensions.pbobjc.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GtalkExtensions.pbobjc.h; path = Firebase/Messaging/Protos/GtalkExtensions.pbobjc.h; sourceTree = ""; }; C03FC127E321BD5B589C03F6CB5D15C7 /* FontAwesome5_Brands.ttf */ = {isa = PBXFileReference; includeInIndex = 1; name = FontAwesome5_Brands.ttf; path = Fonts/FontAwesome5_Brands.ttf; sourceTree = ""; }; C0C4B0C05706B38ABFB58518D1AED74E /* RCTSwitch.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTSwitch.m; sourceTree = ""; }; + C0F481DA187D9340471FBE612D71CD33 /* GtalkCore.pbobjc.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GtalkCore.pbobjc.h; path = Firebase/Messaging/Protos/GtalkCore.pbobjc.h; sourceTree = ""; }; + C1115D0ED1326D53E4F18C7A3B7395FD /* FIRRetryHelper.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRRetryHelper.m; path = Firebase/Database/Core/Utilities/FIRRetryHelper.m; sourceTree = ""; }; + C11F09F5D7BFF243861A75935726732E /* GTMSessionFetcherService.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTMSessionFetcherService.m; path = Source/GTMSessionFetcherService.m; sourceTree = ""; }; + C123255B885108F4B59D313E39CD20E4 /* FChange.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FChange.m; path = Firebase/Database/Core/View/FChange.m; sourceTree = ""; }; C12E589CC6B6291AE80132D0C18F34BD /* RNSensorOrientationChecker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNSensorOrientationChecker.h; path = ios/RN/RNSensorOrientationChecker.h; sourceTree = ""; }; + C1333FF3A02E8CA49BE65FB8FF1428E5 /* FListenProvider.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FListenProvider.m; path = Firebase/Database/Core/FListenProvider.m; sourceTree = ""; }; C145BBEC6B510D44E5BF73963BC1DB2C /* RCTLog.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTLog.mm; sourceTree = ""; }; - C155DB55D12C657623843D2DE1B723C0 /* GPBCodedInputStream.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBCodedInputStream.m; path = objectivec/GPBCodedInputStream.m; sourceTree = ""; }; - C164FB1950C97D321BAD71E7B09EFAE2 /* GULMutableDictionary.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULMutableDictionary.h; path = GoogleUtilities/Network/Private/GULMutableDictionary.h; sourceTree = ""; }; C173864C3DD0334F76FFDBDF7A4866F1 /* RCTImageViewManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTImageViewManager.h; path = Libraries/Image/RCTImageViewManager.h; sourceTree = ""; }; + C17BCCDDD4B9DE20CDD862DB25AE65EE /* symbolize.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = symbolize.cc; path = src/symbolize.cc; sourceTree = ""; }; + C18794FB4491915FA833B66DE05948DF /* FIRComponentType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentType.h; path = Firebase/Core/Private/FIRComponentType.h; sourceTree = ""; }; + C18E7A2F44E3CA8C7C511D941F510972 /* FRepoInfo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FRepoInfo.h; path = Firebase/Database/Core/FRepoInfo.h; sourceTree = ""; }; + C194B9D7F5D0883EEE60232E87973E59 /* table_cache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = table_cache.h; path = db/table_cache.h; sourceTree = ""; }; + C1A52144BC0B6CCEC97272ACD77685E9 /* GPBArray.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBArray.m; path = objectivec/GPBArray.m; sourceTree = ""; }; C1AC47ABA6BE0B3D265D386E69438D8A /* RCTRootContentView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTRootContentView.m; sourceTree = ""; }; - C279CC817F4988EC6BC12D1FC7BD4C47 /* Conv.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = Conv.cpp; path = folly/Conv.cpp; sourceTree = ""; }; + C1D869DCB8998E09EDF65B9054CD933B /* Conv.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = Conv.cpp; path = folly/Conv.cpp; sourceTree = ""; }; + C22E4B37DB39B1245A7FF8D0A8222744 /* GPBCodedOutputStream.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBCodedOutputStream.m; path = objectivec/GPBCodedOutputStream.m; sourceTree = ""; }; C2B8B3C008A656FAB91900CE428C9FCD /* LOTTransformInterpolator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTTransformInterpolator.h; sourceTree = ""; }; C3253FB72A2C4AA4187AC5F9D41A311F /* RCTSlider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSlider.h; sourceTree = ""; }; C3277A54607788C1F851C3A4076FCA8A /* rn-fetch-blob-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "rn-fetch-blob-dummy.m"; sourceTree = ""; }; - C38431EA2F1BFEA2C3D23BC917886E86 /* GPBDictionary.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBDictionary.h; path = objectivec/GPBDictionary.h; sourceTree = ""; }; - C48F82AED30534365C1AFE10BA57DDD7 /* libreact-native-safari-view.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libreact-native-safari-view.a"; path = "libreact-native-safari-view.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + C366C5C59C0D200C6D44A91E9A49FDB2 /* FImmutableSortedDictionary.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FImmutableSortedDictionary.h; path = Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FImmutableSortedDictionary.h; sourceTree = ""; }; + C38E4C6C9CCA165F1A58CB3B9280E33F /* FIRInteropParameterNames.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInteropParameterNames.h; path = Interop/Analytics/Public/FIRInteropParameterNames.h; sourceTree = ""; }; + C392121EEC6B53EB2F5D7CCC636CE7E8 /* FChildChangeAccumulator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FChildChangeAccumulator.m; path = Firebase/Database/Core/View/Filter/FChildChangeAccumulator.m; sourceTree = ""; }; + C3F1E244988886410F5077DF2A9E5800 /* GPBUnknownField.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBUnknownField.h; path = objectivec/GPBUnknownField.h; sourceTree = ""; }; + C416C95441AF1526F177BE7DD0EA46A1 /* GPBRootObject_PackagePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBRootObject_PackagePrivate.h; path = objectivec/GPBRootObject_PackagePrivate.h; sourceTree = ""; }; + C490B04338D5B6C8B578768799D868C2 /* GTMSessionUploadFetcher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMSessionUploadFetcher.h; path = Source/GTMSessionUploadFetcher.h; sourceTree = ""; }; + C498401C32F8C28FA82FC4A342F00E57 /* FTupleStringNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FTupleStringNode.m; path = Firebase/Database/Utilities/Tuples/FTupleStringNode.m; sourceTree = ""; }; + C4FEF857D99B721AC9FA93B793FE4332 /* FWebSocketConnection.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FWebSocketConnection.m; path = Firebase/Database/Realtime/FWebSocketConnection.m; sourceTree = ""; }; C503F2038314A9628108B22C4993AD58 /* RNFetchBlobRequest.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNFetchBlobRequest.m; path = ios/RNFetchBlobRequest.m; sourceTree = ""; }; - C535944E602B816C57B438C995D97885 /* GPBUnknownField.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBUnknownField.h; path = objectivec/GPBUnknownField.h; sourceTree = ""; }; - C5653F8D546A15A5F37363138529A92F /* GTMSessionFetcher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMSessionFetcher.h; path = Source/GTMSessionFetcher.h; sourceTree = ""; }; + C53BD08965BE33BBC6529816FF16507E /* GtalkExtensions.pbobjc.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GtalkExtensions.pbobjc.m; path = Firebase/Messaging/Protos/GtalkExtensions.pbobjc.m; sourceTree = ""; }; + C57306D422BD4BF9E19EED1B89FD40C9 /* FTransformedEnumerator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FTransformedEnumerator.m; path = Firebase/Database/FTransformedEnumerator.m; sourceTree = ""; }; + C57A0D2CF0F382E8C20382DCFAFD1221 /* pb_decode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = pb_decode.h; sourceTree = ""; }; + C595E476B33E9109CFF379EC8ACA664F /* FTypedefs_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTypedefs_Private.h; path = Firebase/Database/Api/Private/FTypedefs_Private.h; sourceTree = ""; }; C5B684709AC0CB3811821BE69E5E3A5D /* RCTDatePicker.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTDatePicker.m; sourceTree = ""; }; C5B6B7BEE23E439D405CAE39C32BAEFF /* RCTStatusBarManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTStatusBarManager.m; sourceTree = ""; }; + C617F0D38F777ED4CD1074CC93AC327F /* FTupleFirebase.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTupleFirebase.h; path = Firebase/Database/Utilities/Tuples/FTupleFirebase.h; sourceTree = ""; }; C630CAE6E614C60BBC8F4EB1C693F8E2 /* RNFetchBlob.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RNFetchBlob.h; sourceTree = ""; }; + C6B6E040B15704408AD50B573EF3DC97 /* FTupleTransaction.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FTupleTransaction.m; path = Firebase/Database/Utilities/Tuples/FTupleTransaction.m; sourceTree = ""; }; C6BFB18CCE8A1FBE4A3B8FD6C5663A0D /* SafariViewManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = SafariViewManager.m; sourceTree = ""; }; + C6F941B784ADFAD4519A40D1636044D9 /* comparator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = comparator.h; path = include/leveldb/comparator.h; sourceTree = ""; }; C7355975BE16954A289895CFB03F6130 /* RCTBlobManager.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = RCTBlobManager.mm; path = Libraries/Blob/RCTBlobManager.mm; sourceTree = ""; }; - C773304DB418B220023CBE9A87606274 /* CLSReport.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CLSReport.h; path = iOS/Crashlytics.framework/Headers/CLSReport.h; sourceTree = ""; }; + C7ABB2E00759610511896A78CB4637B6 /* GULNetworkConstants.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULNetworkConstants.m; path = GoogleUtilities/Network/GULNetworkConstants.m; sourceTree = ""; }; + C7C7AC57C4C8E75A6C614918C18F943A /* FIRMessagingRmqManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingRmqManager.h; path = Firebase/Messaging/FIRMessagingRmqManager.h; sourceTree = ""; }; + C7D3A3C62ABB5D05A88CE06DEBC05EC1 /* GoogleToolboxForMac-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "GoogleToolboxForMac-prefix.pch"; sourceTree = ""; }; C7D44258BCBCF27347A517637671E8E4 /* RCTFileRequestHandler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTFileRequestHandler.m; path = Libraries/Network/RCTFileRequestHandler.m; sourceTree = ""; }; C801D0A6DFD8D87133EBC3899D042C69 /* Pods-KalendTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-KalendTests.release.xcconfig"; sourceTree = ""; }; C845E4CA4E78627DC882F52E50BE94C6 /* RCTMultilineTextInputViewManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTMultilineTextInputViewManager.h; sourceTree = ""; }; C89A3061854BAD9A1BD38FEA633921AD /* FontAwesome.ttf */ = {isa = PBXFileReference; includeInIndex = 1; name = FontAwesome.ttf; path = Fonts/FontAwesome.ttf; sourceTree = ""; }; C8BE936BA747B4B181EF4159DBE88139 /* RCTCxxModule.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTCxxModule.h; sourceTree = ""; }; - CA0AE83BD8B4AF3F29E505170295D7C4 /* json.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = json.cpp; path = folly/json.cpp; sourceTree = ""; }; + C8C4EDEA0E251A3310090AF3E18556FC /* Assume.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = Assume.cpp; path = folly/lang/Assume.cpp; sourceTree = ""; }; + C8DE78C4F95B9EBFE477962A8FFD4D8F /* bignum.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = bignum.cc; path = "double-conversion/bignum.cc"; sourceTree = ""; }; + C8EBE838EB55E2BC9441464B7B06BFA5 /* FTupleObjectNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTupleObjectNode.h; path = Firebase/Database/Utilities/Tuples/FTupleObjectNode.h; sourceTree = ""; }; + C91204B4B8E6BFE92D6270595B0E41B8 /* FIRMessagingPubSub.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingPubSub.h; path = Firebase/Messaging/FIRMessagingPubSub.h; sourceTree = ""; }; + C9301A96DC9D610653E5C327A7CC6D68 /* FViewProcessorResult.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FViewProcessorResult.h; path = Firebase/Database/FViewProcessorResult.h; sourceTree = ""; }; CA5C01AFB4BD1A05F686B418F6709EE7 /* RCTTextAttributes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTTextAttributes.h; path = Libraries/Text/RCTTextAttributes.h; sourceTree = ""; }; + CA6F39AF275D541906673CA4ED08BD50 /* FIRMessagingInternalUtilities.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingInternalUtilities.h; path = Firebase/Messaging/InternalHeaders/FIRMessagingInternalUtilities.h; sourceTree = ""; }; CAAA360C270F6154A4092B600351F423 /* LOTArrayInterpolator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTArrayInterpolator.h; sourceTree = ""; }; + CAAB05F190C3DDA01DBEB8EA8DF57C01 /* FIRMessagingUtilities.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingUtilities.m; path = Firebase/Messaging/FIRMessagingUtilities.m; sourceTree = ""; }; CAC45BF87ED4C888307835A1B7F52C69 /* RCTDevMenu.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTDevMenu.m; sourceTree = ""; }; + CAE5C63FB4B0E24853ECEC763B56541B /* FIRVersion.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRVersion.h; path = Firebase/Core/Private/FIRVersion.h; sourceTree = ""; }; CAF134372BC2E71A7EAE7B74A63B1675 /* RNGestureHandler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNGestureHandler.m; path = ios/RNGestureHandler.m; sourceTree = ""; }; + CAF1EDD6912136DCE34276BEE6DFEB30 /* FIRMessagingPubSubRegistrar.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingPubSubRegistrar.m; path = Firebase/Messaging/FIRMessagingPubSubRegistrar.m; sourceTree = ""; }; + CAF9F96F1F05C6595393D5C96BCEAC85 /* env.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = env.h; path = include/leveldb/env.h; sourceTree = ""; }; CB1633A96B8B195CE9A5A942CDD221FC /* Expo_Usage.md */ = {isa = PBXFileReference; includeInIndex = 1; name = Expo_Usage.md; path = docs/Expo_Usage.md; sourceTree = ""; }; - CB581520BBAE84BDC670F94F64B3FE2C /* GPBCodedOutputStream.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBCodedOutputStream.h; path = objectivec/GPBCodedOutputStream.h; sourceTree = ""; }; CB829089F49F46CE31DE0B2148003406 /* RCTJSStackFrame.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTJSStackFrame.m; sourceTree = ""; }; CBBC3D6FF5DD9F28B52AC5769D2DCA85 /* react-native-slider-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "react-native-slider-dummy.m"; sourceTree = ""; }; + CBDB298C041272AF9FAC15943C63BA8E /* FirebaseDatabase.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseDatabase.h; path = Firebase/Database/Public/FirebaseDatabase.h; sourceTree = ""; }; CBE050C384520225DAACA622107F16D7 /* RCTConvert.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTConvert.h; sourceTree = ""; }; CBE5B10943CD147795ADCB05AFB5EF1F /* RCTConvert+ART.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "RCTConvert+ART.m"; path = "Libraries/ART/RCTConvert+ART.m"; sourceTree = ""; }; CBF89793120841C4D18A6D4C3B9EC656 /* ReactMarker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ReactMarker.h; path = ReactCommon/cxxreact/ReactMarker.h; sourceTree = ""; }; - CC009AD3A6FC5280653B1AFEFB598776 /* GPBUnknownField.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBUnknownField.m; path = objectivec/GPBUnknownField.m; sourceTree = ""; }; - CC2547E3827FA29B4BE7F24C6C7129CF /* GTMSessionFetcher-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "GTMSessionFetcher-dummy.m"; sourceTree = ""; }; + CC1DD9770508DA94C742ED0638E76E5F /* F14Table.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = F14Table.cpp; path = folly/container/detail/F14Table.cpp; sourceTree = ""; }; CC85BB00022112BB6718E5AA79DB45CF /* TwitterHeart.gif */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.gif; name = TwitterHeart.gif; path = docs/gifs/TwitterHeart.gif; sourceTree = ""; }; - CCABEE37C670ACA6EC2203CB15D5088B /* raw_logging.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = raw_logging.h; path = src/glog/raw_logging.h; sourceTree = ""; }; CCD157FC35CFB41CB2073E6FC1FB159D /* ARTSurfaceView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ARTSurfaceView.h; path = Libraries/ART/ARTSurfaceView.h; sourceTree = ""; }; + CCD510EA205821B5537E61E565622B87 /* FIRMessagingAnalytics.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingAnalytics.h; path = Firebase/Messaging/FIRMessagingAnalytics.h; sourceTree = ""; }; CCEEAB6761BA5986ADBE5CE1BBAD587D /* RCTI18nManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTI18nManager.m; sourceTree = ""; }; CD00DCE93642C11C81C8B55D2512DC9E /* RNFileSystem.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNFileSystem.h; path = ios/RN/RNFileSystem.h; sourceTree = ""; }; + CD5404E787B4589BCC278F9ED7665639 /* GTMDebugSelectorValidation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMDebugSelectorValidation.h; path = DebugUtils/GTMDebugSelectorValidation.h; sourceTree = ""; }; CD7120334CF748AE6786EAC9476FE961 /* RNGestureHandlerButton.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNGestureHandlerButton.m; path = ios/RNGestureHandlerButton.m; sourceTree = ""; }; CD76B527FA702FB7CC049AAFF874EE4E /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; }; CD7F87C359E0FE18DC0D5E9CA48C10B0 /* RCTWKWebView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTWKWebView.m; sourceTree = ""; }; + CD98D934A6013CA6873D3813A714C304 /* FTree.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTree.h; path = Firebase/Database/Core/Utilities/FTree.h; sourceTree = ""; }; CDA13C7FD544550D5933B17CF8D31051 /* RNPinchHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RNPinchHandler.h; sourceTree = ""; }; CDD27395DE604FBBB6D789AD3757EB10 /* YGNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = YGNode.h; path = yoga/YGNode.h; sourceTree = ""; }; - CE2BE289D98F170C42BD48505D636DED /* GPBMessage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBMessage.h; path = objectivec/GPBMessage.h; sourceTree = ""; }; - CE3D896360348ACE18C7BE4C77761091 /* GULOriginalIMPConvenienceMacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULOriginalIMPConvenienceMacros.h; path = GoogleUtilities/MethodSwizzler/Private/GULOriginalIMPConvenienceMacros.h; sourceTree = ""; }; - CE79F1692CCD852490873D21A8A1F5E4 /* nanopb-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "nanopb-prefix.pch"; sourceTree = ""; }; + CE7FD3CFEE2A2A5C9E216149A1A17A0E /* FUtilities.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FUtilities.m; path = Firebase/Database/Utilities/FUtilities.m; sourceTree = ""; }; + CEABB06453C94255BB0FE4056E94C510 /* FChildrenNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FChildrenNode.h; path = Firebase/Database/Snapshot/FChildrenNode.h; sourceTree = ""; }; + CECB2E52A4D61E5EEC7F654E4D1E971B /* FIRMessaging.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessaging.h; path = Firebase/Messaging/Public/FIRMessaging.h; sourceTree = ""; }; + CED6E5B78AF9299C7515CA609B49FA2A /* FIRMessagingClient.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingClient.m; path = Firebase/Messaging/FIRMessagingClient.m; sourceTree = ""; }; CEF7599963D907DFA7840EE2120C743C /* RNPanHandler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RNPanHandler.m; sourceTree = ""; }; CF275BE4FEB45E4E34879C52AD867F7E /* RCTKeyboardObserver.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTKeyboardObserver.m; sourceTree = ""; }; CF8879FFDCEF10F7A3919F84FC294174 /* RCTFrameUpdate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTFrameUpdate.h; sourceTree = ""; }; CF98877DBA38E5D54AD5B9E4133C9EA1 /* lottie-react-native-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "lottie-react-native-dummy.m"; sourceTree = ""; }; CF9FA1CC7CD8464B462CAD48AFB1D1A7 /* YGEnums.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = YGEnums.cpp; path = yoga/YGEnums.cpp; sourceTree = ""; }; + CFA246E02267A79CF043A0C5D335BDFD /* libDoubleConversion.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libDoubleConversion.a; path = libDoubleConversion.a; sourceTree = BUILT_PRODUCTS_DIR; }; CFB316B0BA41A32B18B88ACA1666EEC0 /* LOTRenderGroup.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTRenderGroup.h; sourceTree = ""; }; - CFBAB1A595B912E748E740EA7F52B3DA /* GTMLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTMLogger.m; path = Foundation/GTMLogger.m; sourceTree = ""; }; - CFECFEAE9C6ACBAC47AEDE6533BE668B /* GPBUtilities.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBUtilities.h; path = objectivec/GPBUtilities.h; sourceTree = ""; }; - D01034046F54D95FB3954D9BCB09728F /* Firebase.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Firebase.h; path = CoreOnly/Sources/Firebase.h; sourceTree = ""; }; + CFE63D481FB99B0508A809E105EAD9F3 /* libglog.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libglog.a; path = libglog.a; sourceTree = BUILT_PRODUCTS_DIR; }; D02AC7026BFA6B0D78EA32C56D5DC6AD /* RCTShadowView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTShadowView.m; sourceTree = ""; }; + D05298160C882B143B7DDF778A6A6B75 /* table.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = table.cc; path = table/table.cc; sourceTree = ""; }; D0781A402BF5C76FBD4E60EB5C9DC250 /* RCTScrollContentView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTScrollContentView.m; sourceTree = ""; }; D07B46AEB7D2CE6A8C3D3D25EF50A8D0 /* LOTLayerContainer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTLayerContainer.m; sourceTree = ""; }; + D0A50AC65A954663824B0368232AA1F0 /* Timestamp.pbobjc.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Timestamp.pbobjc.h; path = objectivec/google/protobuf/Timestamp.pbobjc.h; sourceTree = ""; }; D0AE4BED71888F3A5354D7A7B0C35F3B /* RCTEventDispatcher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTEventDispatcher.h; sourceTree = ""; }; + D196BAC67D73FBE47B196FFF4809A496 /* nanopb-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "nanopb-prefix.pch"; sourceTree = ""; }; + D19E3BE45818BDD32978B54B12A699D5 /* GULMutableDictionary.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULMutableDictionary.m; path = GoogleUtilities/Network/GULMutableDictionary.m; sourceTree = ""; }; D1B2DE63C0645FDA9E54CF342CC451A3 /* LOTPathInterpolator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTPathInterpolator.m; sourceTree = ""; }; - D217F05EA07BA1756CB1ED1DB1B1297A /* GTMSessionFetcherService.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMSessionFetcherService.h; path = Source/GTMSessionFetcherService.h; sourceTree = ""; }; + D1DA3DDBB6E2F5BA2A56638520AD91BF /* atomic_pointer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = atomic_pointer.h; path = port/atomic_pointer.h; sourceTree = ""; }; + D229CC4B4E3B58BD5DC90E01A82CFD88 /* leveldb-library.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "leveldb-library.xcconfig"; sourceTree = ""; }; D245972CB81A651E4CE20662BA7AE117 /* RCTSlider.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTSlider.m; sourceTree = ""; }; + D26ED6213ECE3731B5B8B7236F7FE8FF /* db_iter.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = db_iter.cc; path = db/db_iter.cc; sourceTree = ""; }; D293C55B6E9EA0811D18F194C74DEC29 /* RCTWebSocketModule.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTWebSocketModule.h; path = Libraries/WebSocket/RCTWebSocketModule.h; sourceTree = ""; }; + D299AD82DC20B38AB6F91E9CFB0B288E /* FirebasePerformance.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebasePerformance.xcconfig; sourceTree = ""; }; D29BC019266EA41E8FF8A9E9283737A6 /* LOTInterpolatorCallback.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTInterpolatorCallback.m; sourceTree = ""; }; + D2B7B63FEF8ACB55544B78B64DCE68B0 /* strtod.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = strtod.cc; path = "double-conversion/strtod.cc"; sourceTree = ""; }; D2C2F8D8A12555F08DDCFA09123D48F5 /* react-native-camera.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = "react-native-camera.podspec"; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; D2EF937B653B0A032947E23C74F4800B /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE; sourceTree = ""; }; - D30915124033725D9B5D8D4201D28BA1 /* GTMNSDictionary+URLArguments.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "GTMNSDictionary+URLArguments.h"; path = "Foundation/GTMNSDictionary+URLArguments.h"; sourceTree = ""; }; + D31E2D7BB58C00689E3BFF3B7399343B /* FValueEventRegistration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FValueEventRegistration.m; path = Firebase/Database/Core/View/FValueEventRegistration.m; sourceTree = ""; }; D32405BBE0C577DA07F6E785FC7AEC81 /* YGNodePrint.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = YGNodePrint.h; path = yoga/YGNodePrint.h; sourceTree = ""; }; D352A8B6C4B73D889DDC0EAB7F698163 /* RCTAssert.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTAssert.m; sourceTree = ""; }; - D39703CF179678BEC4A69B8694A01080 /* ColdClass.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = ColdClass.cpp; path = folly/lang/ColdClass.cpp; sourceTree = ""; }; - D3BD408FFBCEBE1D2EDAED208F372A46 /* Timestamp.pbobjc.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = Timestamp.pbobjc.m; path = objectivec/google/protobuf/Timestamp.pbobjc.m; sourceTree = ""; }; D42044BF99DF4BAD9F403E6983617148 /* RCTProfileTrampoline-i386.S */ = {isa = PBXFileReference; includeInIndex = 1; path = "RCTProfileTrampoline-i386.S"; sourceTree = ""; }; + D4C24610BD75A9F8F6DA40D2196CD758 /* FIRConfiguration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRConfiguration.h; path = Firebase/Core/Public/FIRConfiguration.h; sourceTree = ""; }; D4CFC1ABBDCCAC32FE76345B5F1609D6 /* RCTLocalAssetImageLoader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTLocalAssetImageLoader.h; path = Libraries/Image/RCTLocalAssetImageLoader.h; sourceTree = ""; }; + D4EA5D48358A64B6E278A7F281758C47 /* FTupleObjectNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FTupleObjectNode.m; path = Firebase/Database/Utilities/Tuples/FTupleObjectNode.m; sourceTree = ""; }; D4F8050DC830D3958BBE1A8328D4511F /* Instance.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = Instance.cpp; path = ReactCommon/cxxreact/Instance.cpp; sourceTree = ""; }; - D58D2936FA8A367615DAB1A583B88323 /* GTMSessionFetcher-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "GTMSessionFetcher-prefix.pch"; sourceTree = ""; }; + D53B439011DAD099853AF3889D7B9E54 /* leveldb-library-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "leveldb-library-prefix.pch"; sourceTree = ""; }; + D53E177D9DAED78A04E5F1872DEFFCF0 /* FListenComplete.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FListenComplete.m; path = Firebase/Database/FListenComplete.m; sourceTree = ""; }; + D5C19AB0924F2D0B33D5F9D3E93B6C02 /* FSyncTree.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FSyncTree.m; path = Firebase/Database/Core/FSyncTree.m; sourceTree = ""; }; D629396A8F0E2869D8380E13C5A5C29E /* instrumentation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = instrumentation.h; path = ReactCommon/jsi/instrumentation.h; sourceTree = ""; }; - D6370AE595DEA29F6BFBF7A1FE241694 /* double-conversion.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = "double-conversion.cc"; path = "double-conversion/double-conversion.cc"; sourceTree = ""; }; - D67703327E542502AE07DAA13C45E9D4 /* GPBMessage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBMessage.m; path = objectivec/GPBMessage.m; sourceTree = ""; }; D689C2A9C4F50181069CCF244E2EB1F1 /* RCTTrackingAnimatedNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTTrackingAnimatedNode.m; sourceTree = ""; }; D6A066C924E3B5578BF58A340D1BCAA3 /* RNRootViewGestureRecognizer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNRootViewGestureRecognizer.h; path = ios/RNRootViewGestureRecognizer.h; sourceTree = ""; }; + D6BD0DC337189DAD217C1ECB7620C8AD /* logging.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = logging.cc; path = util/logging.cc; sourceTree = ""; }; D6CF16F061EB2946CEAF00F8D5909B6A /* RCTGIFImageDecoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTGIFImageDecoder.h; path = Libraries/Image/RCTGIFImageDecoder.h; sourceTree = ""; }; D6ED821B1013D9D5D2C4E161E1FE3479 /* migration.md */ = {isa = PBXFileReference; includeInIndex = 1; name = migration.md; path = docs/migration.md; sourceTree = ""; }; D720CBE9F4ABD0088F7C8430C804E0F2 /* LOTValueCallback.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTValueCallback.m; sourceTree = ""; }; + D73650FB53553AA024FEED450D81D6D9 /* FIRMessagingReceiver.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingReceiver.h; path = Firebase/Messaging/FIRMessagingReceiver.h; sourceTree = ""; }; + D73F4F4A7162578699829D8BFEDACF6B /* iterator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = iterator.h; path = include/leveldb/iterator.h; sourceTree = ""; }; D76D5D51CD891E00FB602A22F703D79A /* RNGestureHandlerDirection.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNGestureHandlerDirection.h; path = ios/RNGestureHandlerDirection.h; sourceTree = ""; }; D77FF794A92CED7479B7414F4980FDCA /* lottie-ios.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "lottie-ios.xcconfig"; sourceTree = ""; }; - D8A7F3EB14D892AF47730840C714CCEC /* dynamic.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = dynamic.cpp; path = folly/dynamic.cpp; sourceTree = ""; }; + D7A0F65DB920061ABF199FC50A40FA72 /* FTrackedQuery.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTrackedQuery.h; path = Firebase/Database/Persistence/FTrackedQuery.h; sourceTree = ""; }; + D7A43A98FD75E98C4018D87ED67EA41E /* FIRAnalyticsConnector.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FIRAnalyticsConnector.framework; path = Frameworks/FIRAnalyticsConnector.framework; sourceTree = ""; }; + D7B5F2F53B922C2DA16A59C5A8B63185 /* GoogleUtilities.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleUtilities.xcconfig; sourceTree = ""; }; + D80263157FFBEC750D3C4CBC0AA270E9 /* FirebaseMessaging.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseMessaging.h; path = Firebase/Messaging/FirebaseMessaging.h; sourceTree = ""; }; + D823ACADD98348643E4C77C77F7342C8 /* FTuplePathValue.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FTuplePathValue.m; path = Firebase/Database/Utilities/Tuples/FTuplePathValue.m; sourceTree = ""; }; + D86222299A69AD5898E1DD96FD18847F /* libGoogleUtilities.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libGoogleUtilities.a; path = libGoogleUtilities.a; sourceTree = BUILT_PRODUCTS_DIR; }; + D891B248FC73F84B37DA8C9BCEE57D8E /* FirebaseMessaging.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseMessaging.h; path = Firebase/Messaging/Public/FirebaseMessaging.h; sourceTree = ""; }; D8AC307AEBEBD57D6EE106DF852FD1B3 /* RCTActivityIndicatorView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTActivityIndicatorView.h; sourceTree = ""; }; D8CCFAC19E7D657962E9E82D9CEEADDF /* LOTTrimPathNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTTrimPathNode.h; sourceTree = ""; }; - D9688E70781B95F50FAD1F88E039C2BF /* FirebaseAnalytics.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseAnalytics.xcconfig; sourceTree = ""; }; - D9878295E9DBE9E1A357C2B8CE1C958F /* vlog_is_on.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = vlog_is_on.h; path = src/glog/vlog_is_on.h; sourceTree = ""; }; + D90AC7BDF0B4BFB4AA7E3274289B83E7 /* FValueEventRegistration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FValueEventRegistration.h; path = Firebase/Database/Core/View/FValueEventRegistration.h; sourceTree = ""; }; + D9AC6948A267A80CDA2B6FA35397F5B9 /* FQuerySpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FQuerySpec.h; path = Firebase/Database/Core/FQuerySpec.h; sourceTree = ""; }; D9C5641A4035540750DE5ECE63ED0CB1 /* RCTAppState.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTAppState.m; sourceTree = ""; }; + D9F0881486A7B6AAD1B970DB71EFF3E7 /* FChildEventRegistration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FChildEventRegistration.m; path = Firebase/Database/Core/View/FChildEventRegistration.m; sourceTree = ""; }; DA77C554B6351B86284E6A920E22FE4D /* RCTScrollContentViewManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTScrollContentViewManager.h; sourceTree = ""; }; DA7D0824629AFA21266D58546B4060DD /* RCTTextShadowView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTTextShadowView.m; sourceTree = ""; }; - DAD798862C9706CF2AD96981528491E6 /* FIRAnalyticsConfiguration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRAnalyticsConfiguration.m; path = Firebase/Core/FIRAnalyticsConfiguration.m; sourceTree = ""; }; + DAAA36549110648BA6C2F58F29780FED /* FieldMask.pbobjc.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FieldMask.pbobjc.h; path = objectivec/google/protobuf/FieldMask.pbobjc.h; sourceTree = ""; }; DAED88F71117DC4A32D6894F1FB96FF0 /* RCTSafeAreaView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSafeAreaView.h; sourceTree = ""; }; - DB5B9375AA63B4948C38D7EFC02A0727 /* libReact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libReact.a; path = libReact.a; sourceTree = BUILT_PRODUCTS_DIR; }; - DB5F9A456823497815130E9E530D85D3 /* GULObjectSwizzler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULObjectSwizzler.h; path = GoogleUtilities/ISASwizzler/Private/GULObjectSwizzler.h; sourceTree = ""; }; - DB968FBE67FB3F234237A2BBB1574133 /* GULNetworkURLSession.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkURLSession.h; path = GoogleUtilities/Network/Private/GULNetworkURLSession.h; sourceTree = ""; }; + DAFE21A309048749918F40D0AEEF651B /* GTMSessionFetcher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMSessionFetcher.h; path = Source/GTMSessionFetcher.h; sourceTree = ""; }; + DB33FB1032597062017CC74BCA181FBC /* FParsedUrl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FParsedUrl.h; path = Firebase/Database/Utilities/FParsedUrl.h; sourceTree = ""; }; + DB61590A1D3C3125938F217F5E14ED9D /* FIRLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRLogger.m; path = Firebase/Core/FIRLogger.m; sourceTree = ""; }; DBA2643C609EA568FAB82AE5D1862E67 /* RCTSinglelineTextInputView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSinglelineTextInputView.h; sourceTree = ""; }; + DBD8498E7A02847611B117CB1EE855C6 /* version_edit.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = version_edit.h; path = db/version_edit.h; sourceTree = ""; }; DBDF8CC32DA3BACA4FFD1D938B0FFDDB /* JSDeltaBundleClient.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = JSDeltaBundleClient.cpp; path = ReactCommon/cxxreact/JSDeltaBundleClient.cpp; sourceTree = ""; }; DBE424B6EA62565C72A271120F6BD303 /* RNCameraUtils.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNCameraUtils.m; path = ios/RN/RNCameraUtils.m; sourceTree = ""; }; DC14EB28C512FB412CCFBEF043B47376 /* RCTClipboard.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTClipboard.h; sourceTree = ""; }; DC2E2A6F9EEF1601DF370E61F6100CD4 /* RCTBaseTextInputShadowView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTBaseTextInputShadowView.m; sourceTree = ""; }; DC3EAC6D58AE790C3E7FE90BC74D8871 /* LOTCompositionContainer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTCompositionContainer.h; sourceTree = ""; }; + DC4894517F5081C83018D0B703F6F85A /* FCancelEvent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FCancelEvent.m; path = Firebase/Database/Core/View/FCancelEvent.m; sourceTree = ""; }; DC4A85EB5EFD2092B7B661BADC546896 /* JSBundleType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = JSBundleType.h; path = ReactCommon/cxxreact/JSBundleType.h; sourceTree = ""; }; + DCBA4B6D5B8B1D7BEA57870E0AFF5FAA /* FIRDatabase.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDatabase.h; path = Firebase/Database/Public/FIRDatabase.h; sourceTree = ""; }; DCD2A0A3BFD5409478E32051818235BC /* ARTPattern.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = ARTPattern.h; sourceTree = ""; }; DD1DEBE830AB1AC562BD6CDC1D1BAB3D /* RCTInputAccessoryViewManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTInputAccessoryViewManager.m; sourceTree = ""; }; + DD63A7FD3C1EAFFA38928D1C845684E9 /* FIRDatabaseComponent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRDatabaseComponent.m; path = Firebase/Database/Api/FIRDatabaseComponent.m; sourceTree = ""; }; + DDDC4F8A35BB39296300F5DE8F18F98C /* FIRDataSnapshot.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDataSnapshot.h; path = Firebase/Database/Public/FIRDataSnapshot.h; sourceTree = ""; }; DDE9BC0483E47986E2389E525E3BC58F /* RCTStyleAnimatedNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTStyleAnimatedNode.h; sourceTree = ""; }; - DE06D8A8706390B6234D827E9B397F5D /* FIRComponentRegistrant.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentRegistrant.h; path = Firebase/Core/Private/FIRComponentRegistrant.h; sourceTree = ""; }; - DE76DB9FA2EBA46167E0E55714379F0E /* GoogleUtilities.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleUtilities.xcconfig; sourceTree = ""; }; - DF2213EE14498C8830860C206AA10A17 /* FIRComponentType.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRComponentType.m; path = Firebase/Core/FIRComponentType.m; sourceTree = ""; }; + DE87533E945892A7B9EAA2C43279E3BF /* FStringUtilities.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FStringUtilities.h; path = Firebase/Database/Utilities/FStringUtilities.h; sourceTree = ""; }; + DEC2277CFF299DC146C91D2C77A9481C /* Crashlytics.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Crashlytics.h; path = iOS/Crashlytics.framework/Headers/Crashlytics.h; sourceTree = ""; }; DF82CE493122706F14660EDC8CDF9C84 /* lottie-ios-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "lottie-ios-dummy.m"; sourceTree = ""; }; E03F85C41E15C8E7D8436A1BF14EDE22 /* RCTTextSelection.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTTextSelection.h; sourceTree = ""; }; E066FA80048DF982D01D2D1E5C4EAD84 /* LineAnimation.gif */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.gif; name = LineAnimation.gif; path = docs/gifs/LineAnimation.gif; sourceTree = ""; }; E080E68F9FC380CF31ED3FF9D3C684B1 /* RCTNetworking.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = RCTNetworking.mm; path = Libraries/Network/RCTNetworking.mm; sourceTree = ""; }; - E09978CEA186ADB6111AD2F9C5948BD6 /* GPBRootObject_PackagePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBRootObject_PackagePrivate.h; path = objectivec/GPBRootObject_PackagePrivate.h; sourceTree = ""; }; E0C50295F44644AD62228433168B8E42 /* RCTPlatform.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTPlatform.h; sourceTree = ""; }; E0EE6767A427B04C976BDF008A52966B /* RCTSurfaceRootShadowView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSurfaceRootShadowView.h; sourceTree = ""; }; + E0FB88CDA2B66EEF55DF26B852C8C7DF /* FLLRBValueNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FLLRBValueNode.m; path = Firebase/Database/third_party/FImmutableSortedDictionary/FImmutableSortedDictionary/FLLRBValueNode.m; sourceTree = ""; }; E12385130E862EAF2CB1B2497F6EB0B3 /* RCTHTTPRequestHandler.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = RCTHTTPRequestHandler.mm; path = Libraries/Network/RCTHTTPRequestHandler.mm; sourceTree = ""; }; E1368B9C7C8BEA106730E06B20F5975F /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE; sourceTree = ""; }; + E14F98E6F5EE4D75A64409BE058C39FD /* FIRMessagingContextManagerService.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingContextManagerService.h; path = Firebase/Messaging/FIRMessagingContextManagerService.h; sourceTree = ""; }; E151C4A87A591916C85752DA200BAC8A /* RCTStyleAnimatedNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTStyleAnimatedNode.m; sourceTree = ""; }; E16C2A4C6133D17287DD7C76EC852FC1 /* RCTNullability.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTNullability.h; sourceTree = ""; }; + E192A7C87BD0F2CD1AABD4BF326F5AB2 /* SpookyHashV2.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = SpookyHashV2.cpp; path = folly/hash/SpookyHashV2.cpp; sourceTree = ""; }; E1DB6641CD9DDECD715A74348312634E /* YGStyle.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = YGStyle.h; path = yoga/YGStyle.h; sourceTree = ""; }; E1EC351B241B1D7BB7F5979FFD3C290B /* LOTColorInterpolator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTColorInterpolator.h; sourceTree = ""; }; + E206E0CCE0AAB0D92428779769DF2674 /* FIRMessagingPacketQueue.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingPacketQueue.m; path = Firebase/Messaging/FIRMessagingPacketQueue.m; sourceTree = ""; }; E20AAECFB7B513223A62954055D1A210 /* RCTScrollView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTScrollView.h; sourceTree = ""; }; E221A524F918A64DA7B7204158DFD9AC /* RCTScrollContentView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTScrollContentView.h; sourceTree = ""; }; E23706952480CA0B42056D4023ABC152 /* RCTSinglelineTextInputView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTSinglelineTextInputView.m; sourceTree = ""; }; + E239DC18249A7979EAB77B82565AC428 /* FIRDatabaseConfig_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDatabaseConfig_Private.h; path = Firebase/Database/FIRDatabaseConfig_Private.h; sourceTree = ""; }; + E26BCDA9139114A005F6E1B64F0322EE /* GTMLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTMLogger.m; path = Foundation/GTMLogger.m; sourceTree = ""; }; E28756335C70656E94E1ACD304BF3758 /* react-native-safari-view.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = "react-native-safari-view.podspec"; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + E28F9CFD4A5F59337955F5E5E29D7D00 /* strtod.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = strtod.h; path = "double-conversion/strtod.h"; sourceTree = ""; }; E359D5293ABB8AD5A47B80B900B8A49D /* FaceDetectorManagerMlkit.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FaceDetectorManagerMlkit.m; path = ios/RN/FaceDetectorManagerMlkit.m; sourceTree = ""; }; + E39C79A0D5A0D5FF88250F805F77CB8E /* random.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = random.h; path = util/random.h; sourceTree = ""; }; E3CDBBF3E29018AD51DCF6C4AF91524B /* RCTRootView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTRootView.m; sourceTree = ""; }; E3D5A9D903C12622C9CFCDEF85AC1D32 /* RNFlingHandler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RNFlingHandler.m; sourceTree = ""; }; E41D2FB1FCF0A9BAC4F44D99ECFF16F1 /* JSExecutor.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = JSExecutor.cpp; path = ReactCommon/cxxreact/JSExecutor.cpp; sourceTree = ""; }; E4541339B70BD38568F4086EFBDF27F8 /* LOTShapeGradientFill.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTShapeGradientFill.h; sourceTree = ""; }; E48EC980E941EBAE62F524312BA9CAE0 /* typescript.md */ = {isa = PBXFileReference; includeInIndex = 1; name = typescript.md; path = docs/typescript.md; sourceTree = ""; }; E4AA426D9F768455A13E32CB81CF537D /* RNCSliderManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNCSliderManager.h; path = ios/RNCSliderManager.h; sourceTree = ""; }; - E4D149BAE01097E99370276CD05701C2 /* glog-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "glog-dummy.m"; sourceTree = ""; }; + E4EA040473FF29F9FB33D19CA9E5D77C /* bignum-dtoa.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "bignum-dtoa.h"; path = "double-conversion/bignum-dtoa.h"; sourceTree = ""; }; + E4F17079DA08EE5B499986B263AA74E1 /* fast-dtoa.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = "fast-dtoa.cc"; path = "double-conversion/fast-dtoa.cc"; sourceTree = ""; }; E4F4B0B011F317A90D0BFF29A355160A /* Pods-KalendTests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-KalendTests-acknowledgements.markdown"; sourceTree = ""; }; E507AF1A669A51075286F3DF0C16F451 /* RCTStatusBarManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTStatusBarManager.h; sourceTree = ""; }; - E56AB81FDD4BA5BC1152795983E34F3A /* Type.pbobjc.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Type.pbobjc.h; path = objectivec/google/protobuf/Type.pbobjc.h; sourceTree = ""; }; - E61A6F3D99F028A4319041B8E296FAF3 /* ANSCompatibility.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ANSCompatibility.h; path = iOS/Crashlytics.framework/Headers/ANSCompatibility.h; sourceTree = ""; }; + E51A57E86D7E23F9AF304C34332DD319 /* cached-powers.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = "cached-powers.cc"; path = "double-conversion/cached-powers.cc"; sourceTree = ""; }; + E59970476AE1C8FA38C8E3A183F30980 /* c.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = c.cc; path = db/c.cc; sourceTree = ""; }; E62425D7BD0B62BEFBE4C7D9C3FF88A6 /* RCTViewManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTViewManager.m; sourceTree = ""; }; E62EB5FA27F6828BF00DC2FAF8C801F3 /* RCTInspectorDevServerHelper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTInspectorDevServerHelper.h; sourceTree = ""; }; + E65F21F9ABB67CCC10B8DA68A6597A33 /* FIRMessagingDelayedMessageQueue.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingDelayedMessageQueue.h; path = Firebase/Messaging/FIRMessagingDelayedMessageQueue.h; sourceTree = ""; }; E676A27CDFC9BA5FABF19A413E8D2EDA /* RCTPickerManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTPickerManager.h; sourceTree = ""; }; E68CE192F943371CEEB4E2242D78068D /* LOTModels.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTModels.h; sourceTree = ""; }; E6D7D25E175DC983D3143400EC87BDF7 /* lottie-react-native.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = "lottie-react-native.podspec"; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; - E6D8D2B589B7505E5F8303C187DD0871 /* Crashlytics.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Crashlytics.xcconfig; sourceTree = ""; }; E6E7317A7357055148E89C58A8192CE6 /* RCTScrollContentShadowView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTScrollContentShadowView.h; sourceTree = ""; }; E703B49FCFBE69F94379558A82645F3C /* RCTPointerEvents.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTPointerEvents.h; sourceTree = ""; }; E7197EFE05484AB6A667F1D481C3E22E /* LOTValueDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTValueDelegate.h; sourceTree = ""; }; E75454AA3F8D20AF2398992A93616888 /* RCTSinglelineTextInputViewManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTSinglelineTextInputViewManager.h; sourceTree = ""; }; + E78736EF22E1BD2BBBA9FC6AA32A8EA0 /* GTMNSString+URLArguments.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "GTMNSString+URLArguments.h"; path = "Foundation/GTMNSString+URLArguments.h"; sourceTree = ""; }; E79754D1939CADD9A2BD8B93C18F881F /* LOTRenderGroup.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTRenderGroup.m; sourceTree = ""; }; - E7A74FC9AFF395322FB8D818AE4F9D48 /* GPBDictionary.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBDictionary.m; path = objectivec/GPBDictionary.m; sourceTree = ""; }; E7D6FF54DB702FEF68CC23A8E0C134FE /* RCTFileReaderModule.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTFileReaderModule.h; path = Libraries/Blob/RCTFileReaderModule.h; sourceTree = ""; }; E7E3920695342A9DC9737F825BB5B785 /* LOTPolygonAnimator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTPolygonAnimator.m; sourceTree = ""; }; E7FE8B992027B999D46A014B9FDEEA03 /* RCTWebView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTWebView.m; sourceTree = ""; }; - E8016487FDE2099DD54389EA7B3BCEFB /* FIROptions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIROptions.m; path = Firebase/Core/FIROptions.m; sourceTree = ""; }; E8822CA2EA5A654CB52D16B5DB5A15E2 /* RCTScrollViewManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTScrollViewManager.m; sourceTree = ""; }; + E8B6F15CA218EE2C13727952245B8088 /* GULMutableDictionary.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULMutableDictionary.h; path = GoogleUtilities/Network/Private/GULMutableDictionary.h; sourceTree = ""; }; E92A551E816233B89581BF7B40822187 /* RCTComponentData.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTComponentData.h; sourceTree = ""; }; + E93A0049997B4AF4882B81A770C7A357 /* stl_logging.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = stl_logging.h; path = src/glog/stl_logging.h; sourceTree = ""; }; E93DDED1E5883AE48D3357AAF653B7C0 /* RCTMultiplicationAnimatedNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTMultiplicationAnimatedNode.h; sourceTree = ""; }; + E972B990B021624DF8F843EB6A72994F /* NSData+SRB64Additions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSData+SRB64Additions.m"; path = "Firebase/Database/third_party/SocketRocket/NSData+SRB64Additions.m"; sourceTree = ""; }; E9F98E76BEE8F0638C877D1134193645 /* RNCAsyncStorageDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNCAsyncStorageDelegate.h; path = ios/RNCAsyncStorageDelegate.h; sourceTree = ""; }; + EA02DB62870C585628FD8725D3277A54 /* FIRLoggerLevel.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLoggerLevel.h; path = Firebase/Core/Public/FIRLoggerLevel.h; sourceTree = ""; }; EA6B4E3FFE92057716DC762718518A3D /* RNFetchBlobReqBuilder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNFetchBlobReqBuilder.h; path = ios/RNFetchBlobReqBuilder.h; sourceTree = ""; }; EAADC4D064CA1481CB53F01353DB5B93 /* RAMBundleRegistry.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RAMBundleRegistry.h; path = ReactCommon/cxxreact/RAMBundleRegistry.h; sourceTree = ""; }; + EACA4E5CB47C448ECE5F4211305C3437 /* slice.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = slice.h; path = include/leveldb/slice.h; sourceTree = ""; }; + EAF0CF08241A3BDE4435A323BE22EE7A /* libFolly.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libFolly.a; path = libFolly.a; sourceTree = BUILT_PRODUCTS_DIR; }; EB1A2E1F3DA2A353B5B14523CF4EA839 /* RNVectorIcons-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RNVectorIcons-prefix.pch"; sourceTree = ""; }; + EB2E9C6FCA433DEE6A1FE505D7BCD974 /* GTMSessionFetcher-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "GTMSessionFetcher-dummy.m"; sourceTree = ""; }; EB84D8D5AE446239B764F329A8B3A681 /* RCTBaseTextViewManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTBaseTextViewManager.m; sourceTree = ""; }; EBC50A3EF1A294BC9614C7451E2C961C /* RCTInspector.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTInspector.mm; sourceTree = ""; }; - EC02BD47C323C6CDD736A555CCC513D3 /* Type.pbobjc.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = Type.pbobjc.m; path = objectivec/google/protobuf/Type.pbobjc.m; sourceTree = ""; }; EC11AE71F07F98FFB4F2C741FE3A108D /* RNFaceDetectorModuleMLKit.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNFaceDetectorModuleMLKit.h; path = ios/RN/RNFaceDetectorModuleMLKit.h; sourceTree = ""; }; - EC84E3599BBB7DD06B11323C1785FE23 /* GTMLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMLogger.h; path = Foundation/GTMLogger.h; sourceTree = ""; }; + EC7538EECB1B622475352EA2C29CE32D /* block_builder.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = block_builder.cc; path = table/block_builder.cc; sourceTree = ""; }; EC871643B2DFCE7EAE3C9A7925AE04A9 /* react-native-safari-view-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "react-native-safari-view-prefix.pch"; sourceTree = ""; }; EC9761A203C14C2643FBDA81D466FE97 /* RCTAsyncLocalStorage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTAsyncLocalStorage.m; sourceTree = ""; }; ECA4372C1B73E7D2DEB673F27E1AD867 /* LOTPolygonAnimator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTPolygonAnimator.h; sourceTree = ""; }; - ECB0BC7C084D6EF921C6A0DDFE303A52 /* FIRAppAssociationRegistration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRAppAssociationRegistration.m; path = Firebase/Core/FIRAppAssociationRegistration.m; sourceTree = ""; }; ECCA970817C13BA5DC777519F6C31589 /* LOTAnimationCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTAnimationCache.h; sourceTree = ""; }; + ED1405255E18F31D45F86A8C53FFCCCB /* FTupleUserCallback.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FTupleUserCallback.m; path = Firebase/Database/Utilities/Tuples/FTupleUserCallback.m; sourceTree = ""; }; ED3E60F7ECD984F725643E49A4E75477 /* RCTFrameAnimation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTFrameAnimation.m; sourceTree = ""; }; EDAE74714FD283435319781E10D99C18 /* yoga.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = yoga.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + EDF5582CA0E76148091A5524FB1D31A1 /* GPBExtensionInternals.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBExtensionInternals.m; path = objectivec/GPBExtensionInternals.m; sourceTree = ""; }; EE4762BA1F671BEDC7AE5E7D8F885A29 /* RCTConvert+CoreLocation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+CoreLocation.h"; sourceTree = ""; }; EEDEA875DCFFD65E21FAE42E0B036184 /* RCTTouchHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTTouchHandler.h; sourceTree = ""; }; EEE2B8341F386A304E1D877D53429953 /* RCTDevSettings.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTDevSettings.mm; sourceTree = ""; }; @@ -2815,57 +3740,80 @@ EF37E2604A3658AB4E0EF5A34A3EDB03 /* React.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = React.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; EF4F36543A72816751F130CB28C4ABE5 /* rn-fetch-blob.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "rn-fetch-blob.xcconfig"; sourceTree = ""; }; EF77CDFC4A198113ED34C217FD6AFD4F /* RCTScrollView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTScrollView.m; sourceTree = ""; }; + EFA1763DB7C1831455E270524CADA3B2 /* GULUserDefaults.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULUserDefaults.m; path = GoogleUtilities/UserDefaults/GULUserDefaults.m; sourceTree = ""; }; F013E4C7BC7F453FACF687F6A0FC744F /* LOTMaskContainer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTMaskContainer.m; sourceTree = ""; }; - F08376C309E3A7B855BEF7D386E55ACC /* Fabric.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Fabric.framework; path = iOS/Fabric.framework; sourceTree = ""; }; + F03D781B2B4396C3C5745B1E5FEE04F5 /* GULNetworkMessageCode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkMessageCode.h; path = GoogleUtilities/Network/Private/GULNetworkMessageCode.h; sourceTree = ""; }; + F0858362C8895095E93E26625A443E27 /* Api.pbobjc.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Api.pbobjc.h; path = objectivec/google/protobuf/Api.pbobjc.h; sourceTree = ""; }; + F08847E07FB985EEA88834452E00AE45 /* glog.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = glog.xcconfig; sourceTree = ""; }; F0A5E0C579BCF0C0D6F86FFBEE81A59B /* YGNodePrint.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = YGNodePrint.cpp; path = yoga/YGNodePrint.cpp; sourceTree = ""; }; + F0C80DE6854B8FBEA2554B18BE095780 /* FIRComponent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponent.h; path = Firebase/Core/Private/FIRComponent.h; sourceTree = ""; }; + F0CBB45A9EF73E2FA4E38AE32898F09A /* libBVLinearGradient.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libBVLinearGradient.a; path = libBVLinearGradient.a; sourceTree = BUILT_PRODUCTS_DIR; }; + F0CCAEDCD7986152DEEA9EF1049C9034 /* FIRAuthInterop.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAuthInterop.h; path = Interop/Auth/Public/FIRAuthInterop.h; sourceTree = ""; }; F0FDDBD244E9955CCA1AEF1AFA36DC6A /* RCTBackedTextInputViewProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTBackedTextInputViewProtocol.h; sourceTree = ""; }; + F1021C8F2B1FBF8AA49943F46258A907 /* FClock.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FClock.h; path = Firebase/Database/FClock.h; sourceTree = ""; }; + F10372658AF8256C69BF8332554C2705 /* fixed-dtoa.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "fixed-dtoa.h"; path = "double-conversion/fixed-dtoa.h"; sourceTree = ""; }; F11C17182C527BDE80AA800CCAAD1B99 /* RCTBaseTextInputShadowView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTBaseTextInputShadowView.h; sourceTree = ""; }; + F121AD95A2079F5A12FCCFABC3DF1CF8 /* GULAppDelegateSwizzler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULAppDelegateSwizzler.m; path = GoogleUtilities/AppDelegateSwizzler/GULAppDelegateSwizzler.m; sourceTree = ""; }; + F1289BC33AE993214A1322EE8396AF70 /* FIndexedNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIndexedNode.m; path = Firebase/Database/Snapshot/FIndexedNode.m; sourceTree = ""; }; F141EDCB9073F1D7A8E981D94DB34CC9 /* RCTNetworkTask.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTNetworkTask.m; path = Libraries/Network/RCTNetworkTask.m; sourceTree = ""; }; - F16040E0616BC0C5392F632DE49C3BEA /* GULUserDefaults.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULUserDefaults.h; path = GoogleUtilities/UserDefaults/Private/GULUserDefaults.h; sourceTree = ""; }; + F185A3E96AB8074C9B448A3A346AFCC8 /* GPBCodedOutputStream_PackagePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBCodedOutputStream_PackagePrivate.h; path = objectivec/GPBCodedOutputStream_PackagePrivate.h; sourceTree = ""; }; + F19E6A2E633381302ECD1857A558CBA4 /* FNextPushId.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FNextPushId.m; path = Firebase/Database/Utilities/FNextPushId.m; sourceTree = ""; }; F1C0DD3D15AE6327FDE72155DDA4B4BE /* RCTManagedPointer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTManagedPointer.h; sourceTree = ""; }; F1C3036847AE6AE790A9289D590D4B71 /* RNFetchBlobFS.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RNFetchBlobFS.m; path = ios/RNFetchBlobFS.m; sourceTree = ""; }; F1E6835B8412BDC741BEB45C61EE2115 /* RCTSliderManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTSliderManager.m; sourceTree = ""; }; - F1EB83C041B24EB45510D09F3E799544 /* FIRErrors.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRErrors.m; path = Firebase/Core/FIRErrors.m; sourceTree = ""; }; F20BE9489B143302BF0DA9538538E07E /* YGEnums.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = YGEnums.h; path = yoga/YGEnums.h; sourceTree = ""; }; F2111F6588DAFD858FEF540938E7E7B3 /* RCTImageView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTImageView.h; path = Libraries/Image/RCTImageView.h; sourceTree = ""; }; + F2541E8FA48C590154DE81E96C53239F /* Struct.pbobjc.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = Struct.pbobjc.m; path = objectivec/google/protobuf/Struct.pbobjc.m; sourceTree = ""; }; F276AC2354381D0874D7EF427D68BA36 /* RCTErrorInfo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTErrorInfo.h; sourceTree = ""; }; + F295E06C7C436FFF623A07299B5151E3 /* FIRMessagingClient.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingClient.h; path = Firebase/Messaging/FIRMessagingClient.h; sourceTree = ""; }; + F2B6BA82BA68EC9759243F03F20A4E92 /* FPriorityIndex.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FPriorityIndex.m; path = Firebase/Database/FPriorityIndex.m; sourceTree = ""; }; + F2E40AA55A9ECB3776EB7ADA99968947 /* GULUserDefaults.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULUserDefaults.h; path = GoogleUtilities/UserDefaults/Private/GULUserDefaults.h; sourceTree = ""; }; F32B512239740712D8C9850175735B91 /* RCTConvert+CoreLocation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+CoreLocation.m"; sourceTree = ""; }; - F33CF734EB75D645B6F559246B91C0EE /* GPBDescriptor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GPBDescriptor.m; path = objectivec/GPBDescriptor.m; sourceTree = ""; }; + F35A0211C71E14D30E9960DD0297256D /* db_impl.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = db_impl.cc; path = db/db_impl.cc; sourceTree = ""; }; + F36D0E45637DB5DDE415A88AB9F81B2F /* FIROptionsInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIROptionsInternal.h; path = Firebase/Core/Private/FIROptionsInternal.h; sourceTree = ""; }; + F39C03C8E9840CA54648E59EB7400EFF /* cache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = cache.h; path = include/leveldb/cache.h; sourceTree = ""; }; F3A37968E25A732F4F61687A41E97F87 /* SharedProxyCxxModule.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SharedProxyCxxModule.h; path = ReactCommon/cxxreact/SharedProxyCxxModule.h; sourceTree = ""; }; - F3B8ED4FC03D2D28F01CB56C2C5F8B84 /* FirebaseCore.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseCore.h; path = Firebase/Core/Public/FirebaseCore.h; sourceTree = ""; }; - F434B45DD59F2A9E58327AF6CD3196C2 /* symbolize.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = symbolize.cc; path = src/symbolize.cc; sourceTree = ""; }; + F3A4CCB65F606F18AF787E7DAB77CEFE /* Fabric.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Fabric.h; path = iOS/Fabric.framework/Headers/Fabric.h; sourceTree = ""; }; + F3C5C06ABF35C5C02A270D606DED2B88 /* pb_common.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = pb_common.h; sourceTree = ""; }; + F40FF9A2C28A675DBD9CAF66C26FF0D3 /* Type.pbobjc.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = Type.pbobjc.m; path = objectivec/google/protobuf/Type.pbobjc.m; sourceTree = ""; }; F43FDBB00FEA0CA48F29C3A6FEB8D79E /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE; sourceTree = ""; }; F444846636210A1404151D580D5E80B3 /* RCTCxxUtils.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTCxxUtils.mm; sourceTree = ""; }; F452B1DDF4232583FAF44BE85A7E9017 /* LOTShapeTransform.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTShapeTransform.h; sourceTree = ""; }; + F47C369C57996A13FC6CD8458BBE8B3E /* Unicode.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = Unicode.cpp; path = folly/Unicode.cpp; sourceTree = ""; }; F49915C070E7D298BA8E86D24E95FA3C /* Octicons.ttf */ = {isa = PBXFileReference; includeInIndex = 1; name = Octicons.ttf; path = Fonts/Octicons.ttf; sourceTree = ""; }; - F4D55EE988849BADA37D15F73DFD03A4 /* bignum.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = bignum.cc; path = "double-conversion/bignum.cc"; sourceTree = ""; }; F503BAE598985D376AD676FCA2722218 /* LOTShapeStroke.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTShapeStroke.h; sourceTree = ""; }; + F5529B22BE63AF18AE6DB17C4A3157CD /* GoogleToolboxForMac-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "GoogleToolboxForMac-dummy.m"; sourceTree = ""; }; F56F8E2E9D0A6A89130FF41DBCAA9E4B /* Example1.gif */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.gif; name = Example1.gif; path = docs/gifs/Example1.gif; sourceTree = ""; }; F5EBBC529E31FBDDFC7E664B7059DBC9 /* EvilIcons.ttf */ = {isa = PBXFileReference; includeInIndex = 1; name = EvilIcons.ttf; path = Fonts/EvilIcons.ttf; sourceTree = ""; }; F5F89201B26BC1E9C24CB18A3D18A712 /* RCTRawTextShadowView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTRawTextShadowView.h; sourceTree = ""; }; - F60E4721AAEABB1566B683C2D1B0A722 /* pb_encode.c */ = {isa = PBXFileReference; includeInIndex = 1; path = pb_encode.c; sourceTree = ""; }; + F60D66CC797623BFF95E4681FBA0CA3B /* testutil.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = testutil.h; path = util/testutil.h; sourceTree = ""; }; F62D7944813A14B0202B13BC285570A6 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; }; + F63A293B954058E9A1379E8390D0C7B6 /* FTupleCallbackStatus.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTupleCallbackStatus.h; path = Firebase/Database/Utilities/Tuples/FTupleCallbackStatus.h; sourceTree = ""; }; F67A6E04237958154C561FFB40E4403C /* RCTBridge.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTBridge.h; sourceTree = ""; }; - F67BC7772FAF16CB5D795D8DF00C46DE /* diy-fp.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "diy-fp.h"; path = "double-conversion/diy-fp.h"; sourceTree = ""; }; + F7454AAA8611460E40072A8242598B1B /* FIRErrors.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRErrors.m; path = Firebase/Core/FIRErrors.m; sourceTree = ""; }; F7466C1AF40FB2AFB6AA506B04693370 /* LOTPathInterpolator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTPathInterpolator.h; sourceTree = ""; }; F794D9A735E46A11E4EE3F1E77A9753C /* RNGestureHandlerEvents.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RNGestureHandlerEvents.h; path = ios/RNGestureHandlerEvents.h; sourceTree = ""; }; F7ABF393796AFC79A50CCB443FD285D1 /* LOTCacheProvider.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTCacheProvider.m; sourceTree = ""; }; + F7ACDEDE0588E8BFED42E158BF74D1A1 /* FTupleRemovedQueriesEvents.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FTupleRemovedQueriesEvents.h; path = Firebase/Database/Utilities/Tuples/FTupleRemovedQueriesEvents.h; sourceTree = ""; }; F7CA64D8BA17A077DCF9F3D6559D84E1 /* RCTWebViewManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTWebViewManager.m; sourceTree = ""; }; F7DF0FEC55276C99C5115F3C88AF9D64 /* ARTCGFloatArray.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ARTCGFloatArray.h; path = Libraries/ART/ARTCGFloatArray.h; sourceTree = ""; }; F80767D7A8BE8E1D3A575E3ACD94E24D /* LOTShapeCircle.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTShapeCircle.h; sourceTree = ""; }; + F8078A0EC20DF2D77210B1B085D2884E /* GTMDebugThreadValidation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMDebugThreadValidation.h; path = DebugUtils/GTMDebugThreadValidation.h; sourceTree = ""; }; F8122DCC36F7D8D6C8275A04F9CFBD22 /* RCTPackagerConnection.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTPackagerConnection.mm; sourceTree = ""; }; F81374B32921869AADB0EBA11B8B8C2B /* RCTModuleMethod.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTModuleMethod.h; sourceTree = ""; }; + F830A41CD61BA702D980C5F7FCE20253 /* FKeepSyncedEventRegistration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FKeepSyncedEventRegistration.m; path = Firebase/Database/Core/View/FKeepSyncedEventRegistration.m; sourceTree = ""; }; + F83F0FC48D1A44FFA4748EF0FB17C65F /* log_writer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = log_writer.h; path = db/log_writer.h; sourceTree = ""; }; F8430DEE28745D0D292FDB484995DE43 /* RCTValueAnimatedNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTValueAnimatedNode.m; sourceTree = ""; }; + F871A85C400F1341FCAE2E2DA33F26A3 /* GPBWireFormat.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBWireFormat.h; path = objectivec/GPBWireFormat.h; sourceTree = ""; }; F88B7517C24189335EE9DBE58ABE0C93 /* Utils.cpp */ = {isa = PBXFileReference; includeInIndex = 1; name = Utils.cpp; path = yoga/Utils.cpp; sourceTree = ""; }; F8915607A789FA16613C44076588D5A6 /* react-native-camera-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "react-native-camera-dummy.m"; sourceTree = ""; }; F8B1315482E2B07E77A91A0B03CB097D /* RCTNativeModule.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTNativeModule.h; sourceTree = ""; }; F8C0C7600A97270ED1EF9B07A6692F0F /* RCTInspectorDevServerHelper.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = RCTInspectorDevServerHelper.mm; sourceTree = ""; }; - F8CF17E734F32CD73EEC467FCE9A45B5 /* FIRBundleUtil.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRBundleUtil.h; path = Firebase/Core/Private/FIRBundleUtil.h; sourceTree = ""; }; - F8E794EB8B9462A8721D684AECC475EF /* GULNetworkLoggerProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkLoggerProtocol.h; path = GoogleUtilities/Network/Private/GULNetworkLoggerProtocol.h; sourceTree = ""; }; + F8D489213322E442845543761017E348 /* libreact-native-safari-view.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libreact-native-safari-view.a"; path = "libreact-native-safari-view.a"; sourceTree = BUILT_PRODUCTS_DIR; }; F8F798D9A42CCDA5B665CF0965DE364F /* RCTErrorCustomizer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTErrorCustomizer.h; sourceTree = ""; }; - F94A26A5BD1EFE7C445E6E39296D4C9C /* Struct.pbobjc.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = Struct.pbobjc.m; path = objectivec/google/protobuf/Struct.pbobjc.m; sourceTree = ""; }; F967CE02BF608E45E02D579CD9F45449 /* RCTTextView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTTextView.m; sourceTree = ""; }; F9709200A0A585A420FE5633E11333D5 /* lottie-ios-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "lottie-ios-prefix.pch"; sourceTree = ""; }; + F9968FB8B37B6F7C4652AFC5FE159D74 /* FTupleRemovedQueriesEvents.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FTupleRemovedQueriesEvents.m; path = Firebase/Database/Utilities/Tuples/FTupleRemovedQueriesEvents.m; sourceTree = ""; }; F9BB0530FA2B7ABB88C9492E14A34A62 /* RNCAsyncStorage-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "RNCAsyncStorage-dummy.m"; sourceTree = ""; }; F9CEE4AE7ED35D9AF5FA0BC8CE6F8AC2 /* RNGestureHandler.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = RNGestureHandler.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; F9D719AD374E2180C209CC012653A45E /* LRNAnimationViewManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = LRNAnimationViewManager.h; path = src/ios/LottieReactNative/LRNAnimationViewManager.h; sourceTree = ""; }; @@ -2876,30 +3824,39 @@ FA35F6CF8EAF8187EA202935419DE86C /* LOTPlatformCompat.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LOTPlatformCompat.h; sourceTree = ""; }; FA766D6EA1284DBB1B057023FAA39AFB /* RCTWrapperViewController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTWrapperViewController.h; sourceTree = ""; }; FA88A1A5C7F06D89072A77D1A214D236 /* RCTFileRequestHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTFileRequestHandler.h; path = Libraries/Network/RCTFileRequestHandler.h; sourceTree = ""; }; - FAAFA9FE05ABD9EC9E489698BB896A55 /* GPBUnknownField_PackagePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GPBUnknownField_PackagePrivate.h; path = objectivec/GPBUnknownField_PackagePrivate.h; sourceTree = ""; }; + FA951E29A39E4CF2BE2834740CF4F5C7 /* raw_logging.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = raw_logging.cc; path = src/raw_logging.cc; sourceTree = ""; }; + FAD876CD7B0231BB382CA6A4D0C971CD /* FIRVersion.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRVersion.m; path = Firebase/Core/FIRVersion.m; sourceTree = ""; }; + FB474C1F8E857DCA0F160460EFC9017D /* GULObjectSwizzler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULObjectSwizzler.h; path = GoogleUtilities/ISASwizzler/Private/GULObjectSwizzler.h; sourceTree = ""; }; + FB77A383C92DDA7CEBB334739002ADE6 /* FChildEventRegistration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FChildEventRegistration.h; path = Firebase/Database/Core/View/FChildEventRegistration.h; sourceTree = ""; }; FBC71BA32DD33275E6BD072F11CCC515 /* RCTPlatform.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTPlatform.m; sourceTree = ""; }; + FBC96DFA9FE254B5A90E3FB1E0E87C05 /* APLevelDB.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = APLevelDB.mm; path = "Firebase/Database/third_party/Wrap-leveldb/APLevelDB.mm"; sourceTree = ""; }; FC2012E3882666B87D01CA152D8CBC14 /* RCTRawTextViewManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTRawTextViewManager.m; sourceTree = ""; }; - FC71BAE9376FD74FA6A63D5734A674EE /* ieee.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ieee.h; path = "double-conversion/ieee.h"; sourceTree = ""; }; FC78FC13F0EAB89D84791470CBF5CBF9 /* RCTFrameAnimation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTFrameAnimation.h; sourceTree = ""; }; - FC7E6370ED8E8ECEE0DFC1F1FEF95096 /* FirebaseCoreDiagnostics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseCoreDiagnostics.framework; path = Frameworks/FirebaseCoreDiagnostics.framework; sourceTree = ""; }; FC82D6BF01B2A16F37302C3EEC6E8727 /* instrumentation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = instrumentation.h; path = yoga/instrumentation.h; sourceTree = ""; }; FC851087BC17D35AF6D400CB9199999E /* RCTDataRequestHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTDataRequestHandler.h; path = Libraries/Network/RCTDataRequestHandler.h; sourceTree = ""; }; + FC87325B7FE134E2BA0D1F307D81C10A /* vlog_is_on.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = vlog_is_on.cc; path = src/vlog_is_on.cc; sourceTree = ""; }; FC8CF3BB210F100AAB7CB2626963B656 /* RCTFont.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTFont.h; sourceTree = ""; }; FCC2557C4CFE085AB85934CAC35B5F3A /* BVLinearGradient.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = BVLinearGradient.m; path = BVLinearGradient/BVLinearGradient.m; sourceTree = ""; }; + FCE4AE69FB42F974D532A536DAC73C2B /* FIRMessagingRmqManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRMessagingRmqManager.m; path = Firebase/Messaging/FIRMessagingRmqManager.m; sourceTree = ""; }; + FD226B9F64B84B90460570210B738B55 /* diy-fp.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = "diy-fp.cc"; path = "double-conversion/diy-fp.cc"; sourceTree = ""; }; FD26EB05CA7B4C0DAE5C62273ADB52CA /* RCTImageLoader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTImageLoader.h; path = Libraries/Image/RCTImageLoader.h; sourceTree = ""; }; FD4522BF3B816C2348DAD1222C03F3E2 /* LICENSE.md */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE.md; sourceTree = ""; }; FD5B10A2640382AB59C65D8DADBB5AAC /* RCTEventAnimation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTEventAnimation.h; sourceTree = ""; }; FD73FD41476FC068A2D103BA58F1EB3F /* LOTShapeStroke.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LOTShapeStroke.m; sourceTree = ""; }; - FDDB7A507E51D22F70C1917483F1FF71 /* libDoubleConversion.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libDoubleConversion.a; path = libDoubleConversion.a; sourceTree = BUILT_PRODUCTS_DIR; }; + FDD801BB217E720037A5DACA23733155 /* FIRMessagingVersionUtilities.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRMessagingVersionUtilities.h; path = Firebase/Messaging/FIRMessagingVersionUtilities.h; sourceTree = ""; }; FE0D685632B5D653CAD70F3ADE15857D /* RCTCameraManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCTCameraManager.m; path = ios/RCT/RCTCameraManager.m; sourceTree = ""; }; FE8598D360D11D081817DB736D6AD2FB /* RCTBackedTextInputDelegateAdapter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTBackedTextInputDelegateAdapter.m; sourceTree = ""; }; - FE918890A9495185DB1DF01F4612855C /* GULNetworkMessageCode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkMessageCode.h; path = GoogleUtilities/Network/Private/GULNetworkMessageCode.h; sourceTree = ""; }; + FEA943D1799FC73FC42813F1177AD37D /* log_severity.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = log_severity.h; path = src/glog/log_severity.h; sourceTree = ""; }; + FED414C1C4109A5CE0652D6F306AE7DE /* FParsedUrl.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FParsedUrl.m; path = Firebase/Database/Utilities/FParsedUrl.m; sourceTree = ""; }; FEDC05B78A74ED521879E1C95BD2D6E8 /* NSDataBigString.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = NSDataBigString.h; sourceTree = ""; }; - FEE80C65BE332B5B353A346DB6BA667C /* FIRVersion.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRVersion.h; path = Firebase/Core/Private/FIRVersion.h; sourceTree = ""; }; FEF78209E27EA271441A7BCE73F837A8 /* RCTVirtualTextShadowView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = RCTVirtualTextShadowView.m; sourceTree = ""; }; + FEF896D60E19DB40D4F2856F9A57C70D /* GTMNSData+zlib.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "GTMNSData+zlib.m"; path = "Foundation/GTMNSData+zlib.m"; sourceTree = ""; }; FEF9C3498B2429744E8F6ACE1C55E552 /* RCTBackedTextInputDelegateAdapter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTBackedTextInputDelegateAdapter.h; sourceTree = ""; }; FF2D67CA22841D33C41ED8C7CA55DD6D /* RCTImageCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCTImageCache.h; path = Libraries/Image/RCTImageCache.h; sourceTree = ""; }; + FF608C446C6174A7DC7F119C8A65AB96 /* FEmptyNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FEmptyNode.h; path = Firebase/Database/Snapshot/FEmptyNode.h; sourceTree = ""; }; FF7A94C1A592820091032D15BDC731AA /* RCTVirtualTextShadowView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = RCTVirtualTextShadowView.h; sourceTree = ""; }; + FF7D0CD093F4582E925A76C8ADBAE17F /* FPath.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FPath.h; path = Firebase/Database/Core/Utilities/FPath.h; sourceTree = ""; }; + FFA7A89F9DC8DAC084A978A4F9B99A5D /* FRepo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FRepo.h; path = Firebase/Database/Core/FRepo.h; sourceTree = ""; }; FFE5CD541617B7012FB1BC1EA206604E /* Foundation.ttf */ = {isa = PBXFileReference; includeInIndex = 1; name = Foundation.ttf; path = Fonts/Foundation.ttf; sourceTree = ""; }; /* End PBXFileReference section */ @@ -2911,49 +3868,56 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 104222A4D84B286D6E9920E82D8F0389 /* Frameworks */ = { + 07E7A941F20E6C684896D27D143E92BE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 152A76E04F6AC53412E56CEB51064439 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 1D381A28CB62C6CA220B58A3310B3574 /* Frameworks */ = { + 30C5DFF2267426CEC40ECE5C02B32343 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 31EC555F8F1BD6AB0C1006609DE3E1B7 /* Frameworks */ = { + 4092503050BEFB74223828528389FF3B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 47438DD2D0487D45BE909332AD8E354B /* Frameworks */ = { + 4A91B5D8F0D608B69209E4D72BE0E5E6 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 5B2CEB7E56EE8932114E71616A7DBF8B /* Frameworks */ = { + 4AC3BE407B80D2D10F0CF78DAD07FCBC /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 625BA5F353DFA668EBF6CC7762ECBF5F /* Frameworks */ = { + 55D6665E90D1201A33ADA0479D046B90 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 647C8AE6E369AD2546B6E141A4DE3C5A /* Frameworks */ = { + 69FE1319C8BB95D6C049E26D83951D46 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( @@ -2967,7 +3931,7 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 71C938CCDAEB531F0F9E7B75AA3DF4C3 /* Frameworks */ = { + 7D40F8656597D2EFC3CE6019B1A8500B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( @@ -2981,14 +3945,21 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 85B4FCA8D1A7F8286FA288F6EEE98188 /* Frameworks */ = { + 7D8EDA6A26030D045F4C9E0F088E92D7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7EC51503EE0E00565D6033FC23B964C9 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 90F4EBD254EBCE9D4A448ABBBBB99572 /* Frameworks */ = { + 85B4FCA8D1A7F8286FA288F6EEE98188 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( @@ -3009,56 +3980,63 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - AD5905A0024A647FE5870184F282AD59 /* Frameworks */ = { + AF0973AE7A78C92E0EDADEE1A28F8AF4 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - AF0973AE7A78C92E0EDADEE1A28F8AF4 /* Frameworks */ = { + B6D2CB6123695E2FE94D47773B390E0F /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - BBA59D1B2924626AF2F602604B2AF6CC /* Frameworks */ = { + BC25A11AFF5BF8A53FC9CCC527A31525 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - DAE49414134E8E971BE1B8E346EC396A /* Frameworks */ = { + C1AEBAACD973D83F474032A098AD4C40 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - E961A44EE560B97B80914051D0F98703 /* Frameworks */ = { + C86A89D38DE5A49A00199686A5394DBF /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - FD09386DF33818CC62C305A2D8C9353E /* Frameworks */ = { + DAE49414134E8E971BE1B8E346EC396A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - FE784280FBF07E6392C7AA0680D14151 /* Frameworks */ = { + DE6A2CB668338A9531A84CDEA79EF211 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FD9C228956CE8EC9A4212BC42B38485E /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - FE7852698FF29A79F0DD5BF99FE727B0 /* Frameworks */ = { + FE784280FBF07E6392C7AA0680D14151 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( @@ -3117,19 +4095,30 @@ path = "../../node_modules/react-native/ReactCommon/yoga"; sourceTree = ""; }; - 06477A6CFAB5EF07B6CC8DBFB685D798 /* GoogleToolboxForMac */ = { + 049487709C127577B245F6815F39F962 /* NSData+zlib */ = { isa = PBXGroup; children = ( - 98E4CB163CB27B892D511558099E86E2 /* DebugUtils */, - 49D3B787269FAF211F88ACD90427AD8D /* Defines */, - EA6EBAFC1136A5A6493EBC015E14644E /* Logger */, - F76187C15D9726671993DEC769576483 /* NSData+zlib */, - F18DC7FBE29F14CB34ED9520F77E7973 /* NSDictionary+URLArguments */, - 8FE979E90FCC24872818DEBFAAF163A9 /* NSString+URLArguments */, - E6430C32A0C02CE2C10634E4D8B0FF64 /* Support Files */, + 6FDF8C105D1CD0639854ED193B0B62C8 /* GTMNSData+zlib.h */, + FEF896D60E19DB40D4F2856F9A57C70D /* GTMNSData+zlib.m */, ); - name = GoogleToolboxForMac; - path = GoogleToolboxForMac; + name = "NSData+zlib"; + sourceTree = ""; + }; + 04F378073F79D730A9DC573CF72D4C7D /* Network */ = { + isa = PBXGroup; + children = ( + E8B6F15CA218EE2C13727952245B8088 /* GULMutableDictionary.h */, + D19E3BE45818BDD32978B54B12A699D5 /* GULMutableDictionary.m */, + 3B691314C201B650B478BF0309DE70A5 /* GULNetwork.h */, + 1F4FC0A27C51B191972D727F7307D153 /* GULNetwork.m */, + 1129AD0DCBBB3C878FD6D355C2C224A3 /* GULNetworkConstants.h */, + C7ABB2E00759610511896A78CB4637B6 /* GULNetworkConstants.m */, + 92A08879A6771EC77258B679ADC924C5 /* GULNetworkLoggerProtocol.h */, + F03D781B2B4396C3C5745B1E5FEE04F5 /* GULNetworkMessageCode.h */, + 3FB6DE326DCEDAD8854CB441D76ADA23 /* GULNetworkURLSession.h */, + 2E6957BFB3FCF960F7BB3C06E83AFCE8 /* GULNetworkURLSession.m */, + ); + name = Network; sourceTree = ""; }; 069A2928EFCEDC33E57E644E2E64D217 /* RenderSystem */ = { @@ -3178,26 +4167,6 @@ path = React/CxxUtils; sourceTree = ""; }; - 07BD9D3E16EA7A5E7552EFBCA41F7B0F /* Support Files */ = { - isa = PBXGroup; - children = ( - 805FCB3E481C727E14A57BDD02367CFD /* FirebasePerformance.xcconfig */, - ); - name = "Support Files"; - path = "../Target Support Files/FirebasePerformance"; - sourceTree = ""; - }; - 09A41CE5363CD27F533B9DC58F244A4A /* GoogleSignIn */ = { - isa = PBXGroup; - children = ( - 6DE890B392FDA6F9938881601240DB49 /* Frameworks */, - D0D9E26D144F941EBB8CB2B40E0C9935 /* Resources */, - 7C4C752F0F9A6C73582A57AAB49F9628 /* Support Files */, - ); - name = GoogleSignIn; - path = GoogleSignIn; - sourceTree = ""; - }; 0CB97A4B7995B6ED248F278D81A8CCBC /* Handlers */ = { isa = PBXGroup; children = ( @@ -3233,6 +4202,13 @@ name = jsiexecutor; sourceTree = ""; }; + 0D7DE7BFDBB8C2F90FF5DAA99E683C1A /* decode */ = { + isa = PBXGroup; + children = ( + ); + name = decode; + sourceTree = ""; + }; 0E09F86951302D1EA1E5A637CD33392A /* RCTAnimation */ = { isa = PBXGroup; children = ( @@ -3248,21 +4224,22 @@ name = RCTAnimation; sourceTree = ""; }; - 10B58B83C820EF9BFB7342BF63AA1161 /* NSData+zlib */ = { + 0E7C8E1098EE4C173158E15B01B3E00C /* Support Files */ = { isa = PBXGroup; children = ( - 6B136F18AEA180219FBA5D7410D58846 /* GULNSData+zlib.h */, - 5D8239D1C7ED7D0E5013E1D00ABCC4EE /* GULNSData+zlib.m */, + ACF4AA6F7523E7457E2508CB97A2AE10 /* GoogleSignIn.xcconfig */, ); - name = "NSData+zlib"; + name = "Support Files"; + path = "../Target Support Files/GoogleSignIn"; sourceTree = ""; }; - 122625E3B7A2EC379C5005686C02784F /* Frameworks */ = { + 1270936F7B8B1E1E97B2972DB4DDE891 /* NSData+zlib */ = { isa = PBXGroup; children = ( - 4F29AA4C2EEA95F56F02DA16BB7DC936 /* GoogleAppMeasurement.framework */, + B061BDF4E0105DD15FEB9AB6612DF344 /* GULNSData+zlib.h */, + 82B76D98D30AA6642A0C7940342E89EA /* GULNSData+zlib.m */, ); - name = Frameworks; + name = "NSData+zlib"; sourceTree = ""; }; 12AC9601AC1D24A0817A48EAD5DA8F7D /* RNCAsyncStorage */ = { @@ -3278,6 +4255,77 @@ path = "../../node_modules/@react-native-community/async-storage"; sourceTree = ""; }; + 14BC085A5F27FE5700E6348158AF34B3 /* Protobuf */ = { + isa = PBXGroup; + children = ( + A77A71A83A721E62043AB541BFEBF0BD /* Any.pbobjc.h */, + 46D34415B6A31D4D3C4CFE3135387179 /* Any.pbobjc.m */, + F0858362C8895095E93E26625A443E27 /* Api.pbobjc.h */, + 028C667A4E60B8920C74DACF0139CC88 /* Api.pbobjc.m */, + 0BAA5361695A82FAF3A98A1C9DC2CD8B /* Duration.pbobjc.h */, + 37ABB67EB8FC12697EBA5E61AB7D193D /* Duration.pbobjc.m */, + 3822BBD2EAF04D86C912BA9D549D6B34 /* Empty.pbobjc.h */, + 55DD4835B21EDEF4C6BE39AE65FCA9A1 /* Empty.pbobjc.m */, + DAAA36549110648BA6C2F58F29780FED /* FieldMask.pbobjc.h */, + 3CF3157877D482C5AE976CC59518658E /* FieldMask.pbobjc.m */, + 78AA68D19B1F685D88867FD4E892FEDA /* GPBArray.h */, + C1A52144BC0B6CCEC97272ACD77685E9 /* GPBArray.m */, + 0996F2843C29C1944530ABEEFC68EFD6 /* GPBArray_PackagePrivate.h */, + 0E356741FE3B30C036009C1197254FF3 /* GPBBootstrap.h */, + 0B030D409ECDB4FBAC60A0939F910375 /* GPBCodedInputStream.h */, + B6EF56F996D239DC5D0F14C3E7E83114 /* GPBCodedInputStream.m */, + 4785EB3ACEC0E8CCA1161262C30079BD /* GPBCodedInputStream_PackagePrivate.h */, + 1F235E8C436E14FF6556F77D0ADA49DC /* GPBCodedOutputStream.h */, + C22E4B37DB39B1245A7FF8D0A8222744 /* GPBCodedOutputStream.m */, + F185A3E96AB8074C9B448A3A346AFCC8 /* GPBCodedOutputStream_PackagePrivate.h */, + 4F9BB1D579C19AC9E2483A5F07973D6A /* GPBDescriptor.h */, + 7C33485C8E12BB74635C0EB707C20FFD /* GPBDescriptor.m */, + 36F3D1B3B7B29DDC9BAB3591E2F2A9DC /* GPBDescriptor_PackagePrivate.h */, + BF0EB3589EDFE0B529D244E5F911C9F0 /* GPBDictionary.h */, + 3F285B33466F8251D8487BB461AB15F3 /* GPBDictionary.m */, + 90B601B427F3F79EA0C870FACB123D08 /* GPBDictionary_PackagePrivate.h */, + 8627BB978197F51EFF396E4327FA065B /* GPBExtensionInternals.h */, + EDF5582CA0E76148091A5524FB1D31A1 /* GPBExtensionInternals.m */, + 82FA54919C73D72F5F91E7FCEE74C2C0 /* GPBExtensionRegistry.h */, + 66071353779F44989D907BF1A8344AAE /* GPBExtensionRegistry.m */, + 02A7AC7B71A07E26F7AC8D4CBF4EC17F /* GPBMessage.h */, + 886DE47956E22373CFBD2E91672FDC4B /* GPBMessage.m */, + B401B96BDEDB3229635D97BF950291A2 /* GPBMessage_PackagePrivate.h */, + 76D48846AA16EE2F697709EC13A7DF6D /* GPBProtocolBuffers.h */, + 0E9EAABCF1ACD513834E19042D2F3C11 /* GPBProtocolBuffers_RuntimeSupport.h */, + 3B690A9359A398B343537A429DBDF0F9 /* GPBRootObject.h */, + 80F61CFD731064B4566AC59E8B1DDC68 /* GPBRootObject.m */, + C416C95441AF1526F177BE7DD0EA46A1 /* GPBRootObject_PackagePrivate.h */, + 475AF4973905C1161DF33535253E26E6 /* GPBRuntimeTypes.h */, + C3F1E244988886410F5077DF2A9E5800 /* GPBUnknownField.h */, + 4229147F5CEA195DD7119238617BA3A1 /* GPBUnknownField.m */, + 6C22EE39B6204C1DD87F7F1352D610E3 /* GPBUnknownField_PackagePrivate.h */, + 1F2D533EDC352B7D0DE415441637CD41 /* GPBUnknownFieldSet.h */, + 0ACB229E2B3A2738DFDC60451CE1EF18 /* GPBUnknownFieldSet.m */, + 65850DA53C24DA8CA8584275DC5C7E41 /* GPBUnknownFieldSet_PackagePrivate.h */, + 9A94C572AA48C7A9AAD37504C253D08E /* GPBUtilities.h */, + 2BF47581753EE9991293514DAE4C7293 /* GPBUtilities.m */, + 535A732EEE2C5782F0E8756BE795DCDF /* GPBUtilities_PackagePrivate.h */, + 4FFDB73167B848BBBD3E423FFEB9183B /* GPBWellKnownTypes.h */, + 2D82596297034CEA5B5479350D457747 /* GPBWellKnownTypes.m */, + F871A85C400F1341FCAE2E2DA33F26A3 /* GPBWireFormat.h */, + 76F353CA912399FEFC2D3D20C67AF7D4 /* GPBWireFormat.m */, + 9536222AC312336E96C37ACA5AB4A33F /* SourceContext.pbobjc.h */, + 233CC9D72A4769298201DCE6A22219B4 /* SourceContext.pbobjc.m */, + 8648BC64286D754073CACC328B7BB68F /* Struct.pbobjc.h */, + F2541E8FA48C590154DE81E96C53239F /* Struct.pbobjc.m */, + D0A50AC65A954663824B0368232AA1F0 /* Timestamp.pbobjc.h */, + 2D97F98E914FF8F367D4172A6ADFCA5A /* Timestamp.pbobjc.m */, + 72E8E663A36070B6BA67A8E45D47C26F /* Type.pbobjc.h */, + F40FF9A2C28A675DBD9CAF66C26FF0D3 /* Type.pbobjc.m */, + 55AF778DC11874FA59DADD2E7AB1ACD9 /* Wrappers.pbobjc.h */, + 493D4839B109B1EF43AA9A203C9EAF78 /* Wrappers.pbobjc.m */, + 3DDFD0720066C466C26195030D6A3066 /* Support Files */, + ); + name = Protobuf; + path = Protobuf; + sourceTree = ""; + }; 1575D66B3DA4B53512A6FFAAF430A88A /* DevSupport */ = { isa = PBXGroup; children = ( @@ -3308,36 +4356,6 @@ path = "../../node_modules/react-native-camera"; sourceTree = ""; }; - 1A347C92C3B4E5038AD6FCB73A777617 /* ISASwizzler */ = { - isa = PBXGroup; - children = ( - DB5F9A456823497815130E9E530D85D3 /* GULObjectSwizzler.h */, - 226E382223F53A8210A8E202F67338BA /* GULObjectSwizzler.m */, - 2BFC25B49C86C3D89C95B316576FA83E /* GULSwizzledObject.h */, - 5B30F2E8DF13C2CA1CEE032F3305159D /* GULSwizzledObject.m */, - ); - name = ISASwizzler; - sourceTree = ""; - }; - 1A36BBB7E70230CCE89FF04B18A6D304 /* FirebaseRemoteConfig */ = { - isa = PBXGroup; - children = ( - 2BD36F57CFC5380F2FDF54CDA032AAC7 /* Frameworks */, - 5E8AC9F6532F71EE58C4AACD3D6FB86C /* Support Files */, - ); - name = FirebaseRemoteConfig; - path = FirebaseRemoteConfig; - sourceTree = ""; - }; - 1A75F25B796D7CB10819692CD5467EF9 /* Environment */ = { - isa = PBXGroup; - children = ( - 335250B47DC62B5D209ED0E7B499E7D5 /* GULAppEnvironmentUtil.h */, - 9D8D7BB881323B238CADCF721026C5B7 /* GULAppEnvironmentUtil.m */, - ); - name = Environment; - sourceTree = ""; - }; 1CB2D43ABB05D6819C7AB2DDCC0DAFA2 /* RNFetchBlob */ = { isa = PBXGroup; children = ( @@ -3363,33 +4381,6 @@ name = RCTWebSocket; sourceTree = ""; }; - 1E43D88086FB5F49EBAB5BAD779E8351 /* DoubleConversion */ = { - isa = PBXGroup; - children = ( - F4D55EE988849BADA37D15F73DFD03A4 /* bignum.cc */, - 0CEB3711F4BDB27DF244600A105B2363 /* bignum.h */, - 576CCA63035FF40021B2C4893AD22C70 /* bignum-dtoa.cc */, - 562EFD18A443FC75D1F2A7C9E1BFBEED /* bignum-dtoa.h */, - 166091403FC4A8777527BE2435C87455 /* cached-powers.cc */, - 3C95E73D25734090CEB4C2607EC3804F /* cached-powers.h */, - AF63990D5314AA2FE6B12AB99651E4D4 /* diy-fp.cc */, - F67BC7772FAF16CB5D795D8DF00C46DE /* diy-fp.h */, - D6370AE595DEA29F6BFBF7A1FE241694 /* double-conversion.cc */, - 37967DC16FAFA16E418FAA5795D66DB3 /* double-conversion.h */, - 17D71D051405FFD0A9EC92F14F4AE0F0 /* fast-dtoa.cc */, - B71607B0576176404F452DD809E993D0 /* fast-dtoa.h */, - 8790B8A241F3149E10155D2A2A1BDA12 /* fixed-dtoa.cc */, - 50F4AE7E1F3A99FA789591FE4516D16F /* fixed-dtoa.h */, - FC71BAE9376FD74FA6A63D5734A674EE /* ieee.h */, - 5D0C84E15BAC64269568163FD126444C /* strtod.cc */, - AB062FB5FE3CA4C8C4BA1594452B88EA /* strtod.h */, - AFD44EF8E63D08F65BFAC2B9A64F48C7 /* utils.h */, - E9562410DE4A48FCA85F99BB011CC4D9 /* Support Files */, - ); - name = DoubleConversion; - path = DoubleConversion; - sourceTree = ""; - }; 1E75BA895137526B8089025DA07D5F8C /* Nodes */ = { isa = PBXGroup; children = ( @@ -3453,30 +4444,6 @@ path = RenderNodes; sourceTree = ""; }; - 21C6B6341BE38C47292B78BC6D116D13 /* Folly */ = { - isa = PBXGroup; - children = ( - 07A73AEA93339D92B2C110B4FFDE82B8 /* Assume.cpp */, - D39703CF179678BEC4A69B8694A01080 /* ColdClass.cpp */, - C279CC817F4988EC6BC12D1FC7BD4C47 /* Conv.cpp */, - B27A960FDD399A1F54CDD8A1001C653A /* Demangle.cpp */, - 90925193CFC8654619BC7A42DF98C8EE /* Demangle.cpp */, - D8A7F3EB14D892AF47730840C714CCEC /* dynamic.cpp */, - 27B324A94122FB21CAF9924D9DE60D16 /* F14Table.cpp */, - 9899A22E44EAB1314C1B352F982A23FF /* Format.cpp */, - CA0AE83BD8B4AF3F29E505170295D7C4 /* json.cpp */, - B08791541E4426FA32DDA9485ED88B0A /* json_pointer.cpp */, - 672B4F31CF65337F8111AAFD4FE52315 /* MallocImpl.cpp */, - BB089FC3285722B2E922DC1AE785160A /* ScopeGuard.cpp */, - 4576960A63CAA9F4F93A4A177389016E /* SpookyHashV2.cpp */, - 2441A0494B64BA30472F9C2D55D56C83 /* String.cpp */, - 2F78EC927E123ED2AD0206235BCC08BB /* Unicode.cpp */, - E8B7BC35E6CDE0AF0B43923A66D90C81 /* Support Files */, - ); - name = Folly; - path = Folly; - sourceTree = ""; - }; 253F23E0AEF9F2FF63650951602428EF /* Support Files */ = { isa = PBXGroup; children = ( @@ -3488,6 +4455,16 @@ path = "../../ios/Pods/Target Support Files/react-native-safari-view"; sourceTree = ""; }; + 2558A8BB01481BD8C27B876045E13494 /* Frameworks */ = { + isa = PBXGroup; + children = ( + D7A43A98FD75E98C4018D87ED67EA41E /* FIRAnalyticsConnector.framework */, + 8759E85F683CBD7D8313AD3920BD8B57 /* FirebaseAnalytics.framework */, + 46E4423D5D97E60BC8EB6AE0F8F7BBAE /* FirebaseCoreDiagnostics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; 276A7FAD6A8DA879F47766E76F7FD755 /* Pod */ = { isa = PBXGroup; children = ( @@ -3561,13 +4538,257 @@ path = "../../node_modules/react-native"; sourceTree = ""; }; - 29433304B61FDDFA392CBB2982CD30A5 /* Support Files */ = { - isa = PBXGroup; - children = ( - 788D5F1524FB50C541D8C669AA9336EF /* Firebase.xcconfig */, - ); - name = "Support Files"; - path = "../Target Support Files/Firebase"; + 2939FC1C4D0A41A594EFA485570583B1 /* FirebaseDatabase */ = { + isa = PBXGroup; + children = ( + 419AD5D765BE6240880B0DED4704566F /* APLevelDB.h */, + FBC96DFA9FE254B5A90E3FB1E0E87C05 /* APLevelDB.mm */, + 97386F1F30CB7CCC02F608D5C9331B09 /* FAckUserWrite.h */, + 6F42437F1F72018693E866EC0BDA1BB7 /* FAckUserWrite.m */, + 9C7270A700555CE0EA21EFB5C5B0554F /* FArraySortedDictionary.h */, + 8F68366A11B377715E042AE44705C84B /* FArraySortedDictionary.m */, + 2DEED99E085D1569EA7AF45E36DD03C1 /* FAtomicNumber.h */, + 7BE6185E47D64690D26AA8C43019350E /* FAtomicNumber.m */, + 8F571C5DB444B31B17A40742A190C5BF /* FAuthTokenProvider.h */, + 944176C892C7E452B815BCEBCBCC07B2 /* FAuthTokenProvider.m */, + A996778AA6C82C606288542E389E64D1 /* fbase64.c */, + ADE2305F8ACE4C5E55537E2552D21731 /* fbase64.h */, + 76D9C9E44997FE825633287D7D5FF42F /* FCacheNode.h */, + 34F22203D7EEA6D4715E45F6FE625DAF /* FCacheNode.m */, + 8C67F76BA60F26BD2E805CB7688786F3 /* FCachePolicy.h */, + 9FD42A1D1EFDAD7F398B68B135BC9F5F /* FCachePolicy.m */, + 317A7F3B0FB2B5E365D3120C3A197A7D /* FCancelEvent.h */, + DC4894517F5081C83018D0B703F6F85A /* FCancelEvent.m */, + 500D2122A635658F32FE739A31FC4AC2 /* FChange.h */, + C123255B885108F4B59D313E39CD20E4 /* FChange.m */, + 1C8C47ABA550DEE7AF6DB7793BD0F4B3 /* FChildChangeAccumulator.h */, + C392121EEC6B53EB2F5D7CCC636CE7E8 /* FChildChangeAccumulator.m */, + FB77A383C92DDA7CEBB334739002ADE6 /* FChildEventRegistration.h */, + D9F0881486A7B6AAD1B970DB71EFF3E7 /* FChildEventRegistration.m */, + CEABB06453C94255BB0FE4056E94C510 /* FChildrenNode.h */, + BD84C78C51CE9A9263693F3444B7571E /* FChildrenNode.m */, + F1021C8F2B1FBF8AA49943F46258A907 /* FClock.h */, + AA83A1F88B9D90E1ECE2A9C296AF07B5 /* FClock.m */, + 35FC9E3E1747E42F7199467986DEEFE3 /* FCompleteChildSource.h */, + 12C406E967EB43474042DAEFDE88B37A /* FCompoundHash.h */, + 4B073494BCE05F22ECA7AAAD5ECC6F1F /* FCompoundHash.m */, + 3FE8D8BD4DB7927197E7B596371BCEC6 /* FCompoundWrite.h */, + 516F35E8FDF2F4BFF18B895917E368F1 /* FCompoundWrite.m */, + 9D7D22BFC36156A34EAAA455C211B9D3 /* FConnection.h */, + 712659E6D3CA9427726A4CF0C0A5A952 /* FConnection.m */, + 3EF52EC3FC7F93B8DA1F7CB9F131FF8E /* FConstants.h */, + 4C3A3E65CB073D3D976CBD3F68542942 /* FConstants.m */, + 23D54FAEECFDD570E95E39A465F7CDA4 /* FDataEvent.h */, + 297D93EF3C8789F0A1EC74DD2721C0B3 /* FDataEvent.m */, + FF608C446C6174A7DC7F119C8A65AB96 /* FEmptyNode.h */, + 9693C764585DF4F21DC261BAC46C1B91 /* FEmptyNode.m */, + ABC865F02D8659D4C60C31F9E9C3A82D /* FEvent.h */, + 853A62F813D5F154B1F1D222597065EB /* FEventEmitter.h */, + BC151BD4C4B5CFCE88605416C591816B /* FEventEmitter.m */, + 2E295112032A733DEDF268666E7090D2 /* FEventGenerator.h */, + 433A22FA442B112CC55C0E2F3A3BD38D /* FEventGenerator.m */, + 730C83CA84F8C07C83D086E1EAE7BC63 /* FEventRaiser.h */, + A031910DEC6962FD8A88B9BB9215E807 /* FEventRaiser.m */, + 759C34A1ED749325D1487BE17458AD5D /* FEventRegistration.h */, + C366C5C59C0D200C6D44A91E9A49FDB2 /* FImmutableSortedDictionary.h */, + A80DF0C102E3EA656E87DBE7A9FF4F08 /* FImmutableSortedDictionary.m */, + 6F4530CAB03AC6F4D0F2979F7FC111EC /* FImmutableSortedSet.h */, + 09624EE7B259BADAF0F1FAD4F0A753D3 /* FImmutableSortedSet.m */, + 4432B5DE12A0775BABA5B5E3B961116C /* FImmutableTree.h */, + 00BE88F25DC58F3A5C0BCEB71B025B97 /* FImmutableTree.m */, + B1F3079B96D41B5A86AA71A071EC3373 /* FIndex.h */, + 6DD759A337B2E093C7B598AF79F47FF0 /* FIndex.m */, + B52E090772086382345A487E8AF24146 /* FIndexedFilter.h */, + 3FE9EFF9530C76BC0428F708BDEF0D16 /* FIndexedFilter.m */, + 75A798E6C1AE8376F578BA0C0673F141 /* FIndexedNode.h */, + F1289BC33AE993214A1322EE8396AF70 /* FIndexedNode.m */, + DCBA4B6D5B8B1D7BEA57870E0AFF5FAA /* FIRDatabase.h */, + BE0D558DC88FD688F6668DFDAF4F95EA /* FIRDatabase.m */, + 01B3017DFB14AAC889D13223520F8A82 /* FIRDatabase_Private.h */, + 304BBCFDADDF0EDDFD3A6000BC94FE7D /* FIRDatabaseComponent.h */, + DD63A7FD3C1EAFFA38928D1C845684E9 /* FIRDatabaseComponent.m */, + 119233EEDFEBB78EFF551ACE3BA29826 /* FIRDatabaseConfig.h */, + 069F69FA97FDBC1655FD5690EA59DD94 /* FIRDatabaseConfig.m */, + E239DC18249A7979EAB77B82565AC428 /* FIRDatabaseConfig_Private.h */, + 64ECD487E0F940E52FAE9C1561AE435F /* FIRDatabaseQuery.h */, + 14CCBBBF8B62D60B9B16C63F39BDBDA1 /* FIRDatabaseQuery.m */, + 8ABD9D96C5ED0354122B80F70AB70E3F /* FIRDatabaseQuery_Private.h */, + 0CF36179E7398673F38A1B46BDDE8565 /* FIRDatabaseReference.h */, + 797D0736CD646C1C5C7C068633067BB9 /* FIRDatabaseReference.m */, + 9FC8A2A184DB31E6141FB571B418F177 /* FIRDatabaseReference_Private.h */, + 2CC836083D4A964D223ED91DB13EAB5F /* FIRDataEventType.h */, + DDDC4F8A35BB39296300F5DE8F18F98C /* FIRDataSnapshot.h */, + 15EB2B211850BEB00F748CE3C6ABEDBB /* FIRDataSnapshot.m */, + 53EA97F0D01736B84E48D58715BA4290 /* FIRDataSnapshot_Private.h */, + CBDB298C041272AF9FAC15943C63BA8E /* FirebaseDatabase.h */, + AF8C098D4570B1F9F98B038CCEF57632 /* FIRMutableData.h */, + A5B1383C5CFB90D1E20E9E29C80E511F /* FIRMutableData.m */, + 8B42FCEC34634448FD698A9E455C74B8 /* FIRMutableData_Private.h */, + A2FD731CDB94C61CDE98166ABD6071E7 /* FIRNoopAuthTokenProvider.h */, + 15A9D734E57E7B82657B9C03A83BDAD6 /* FIRNoopAuthTokenProvider.m */, + 981A7005F97321DE167E0284DA26CA96 /* FIRRetryHelper.h */, + C1115D0ED1326D53E4F18C7A3B7395FD /* FIRRetryHelper.m */, + BDB3F378ED3191C4E52C52675F76AB45 /* FIRServerValue.h */, + 2A6CD0729441F2880CBA9BBEEE9104CE /* FIRServerValue.m */, + BFAA8B4261AA8616E6962307CE1E10B6 /* FIRTransactionResult.h */, + 6ADFCB7CEFE52C2088C8DCC32BFE3902 /* FIRTransactionResult.m */, + 79A7987DF3C0A779E751CAF23BB69165 /* FIRTransactionResult_Private.h */, + B3E04C62ED98682FE35D19F1871D4B6F /* FKeepSyncedEventRegistration.h */, + F830A41CD61BA702D980C5F7FCE20253 /* FKeepSyncedEventRegistration.m */, + 0C5A241F21BA1B05DA1E29393CF0055D /* FKeyIndex.h */, + 93B301CFF46AAB8D6D41C82A86DE1A2A /* FKeyIndex.m */, + 59E80B5F2FA215DB1789FF68C3AB8EBE /* FLeafNode.h */, + 529DD218B7FEAB0FD9D59EFC98F24DF4 /* FLeafNode.m */, + 4D8FD7EDF6E543DB4D9DA88021A5417B /* FLevelDBStorageEngine.h */, + 8780294E8D554541F2E815BCB528F0EE /* FLevelDBStorageEngine.m */, + 267864CCA87DB796A799D1C8EF7D05F7 /* FLimitedFilter.h */, + 2F4CE8B42235E53F5BD9721CD57244D9 /* FLimitedFilter.m */, + 2A957ABA5B2C2265A3AD0EE1B4A29FC8 /* FListenComplete.h */, + D53E177D9DAED78A04E5F1872DEFFCF0 /* FListenComplete.m */, + 8EA3039B8276E66EFA1E055C5273D6E5 /* FListenProvider.h */, + C1333FF3A02E8CA49BE65FB8FF1428E5 /* FListenProvider.m */, + 329BD46423F50005F2F603C45F8A03CE /* FLLRBEmptyNode.h */, + 948383FCA22475A89A577753033C97D7 /* FLLRBEmptyNode.m */, + 799504110AB087904080B91819637656 /* FLLRBNode.h */, + 29D2B5D41D48199784CDB89A40F06B5C /* FLLRBValueNode.h */, + E0FB88CDA2B66EEF55DF26B852C8C7DF /* FLLRBValueNode.m */, + 7E4789119E50F090D03CF025000A12B1 /* FMaxNode.h */, + AE7A6AB9927CAC8E535EFB9EA04B6211 /* FMaxNode.m */, + B4AD0B7F0736B586F077CD29A43498C0 /* FMerge.h */, + 4C745941C2E59521A729ABA0D06C4A96 /* FMerge.m */, + 469B99E535C3387F64B9842052BCDCC5 /* FNamedNode.h */, + 4137D29173DFD982B0C4FBA1F5733874 /* FNamedNode.m */, + 1930D643E55F4366DCFB1B34FB799D5A /* FNextPushId.h */, + F19E6A2E633381302ECD1857A558CBA4 /* FNextPushId.m */, + B991E2493BC8E88470D17EF78E3D3A3C /* FNode.h */, + 908D456544B582A2941A79B982FA9D86 /* FNodeFilter.h */, + 97038520199DADF5850A500588C4A880 /* FOperation.h */, + 17EA5C6CF12F09B8E6CB1128E1F997E7 /* FOperationSource.h */, + 96BB8CB87E982251038E03C2CC280BCC /* FOperationSource.m */, + 445CCC9B3DDFCC1034CA6BC4F856C306 /* FOverwrite.h */, + 1FF006F9B14B4A5F20A8D153F088C1DB /* FOverwrite.m */, + DB33FB1032597062017CC74BCA181FBC /* FParsedUrl.h */, + FED414C1C4109A5CE0652D6F306AE7DE /* FParsedUrl.m */, + FF7D0CD093F4582E925A76C8ADBAE17F /* FPath.h */, + 7CAACBD84B0FF26AABBC2C0E6051CECE /* FPath.m */, + 89B9B60415B01CC3F624C6526B96677F /* FPathIndex.h */, + 6AB7F22E3C7682C14E733A9ECE01325A /* FPathIndex.m */, + 86DF92D9A6B37877E72691BB0096A0D6 /* FPendingPut.h */, + 229EC03EE7326CEE9A1F6C1C8EB26333 /* FPendingPut.m */, + 33616753739FB63382C4F65ECE442123 /* FPersistenceManager.h */, + 1A4536262CC31CAB068E3FACD297A952 /* FPersistenceManager.m */, + 5E56962CF36D9AC7FC58707C2D4DCF6C /* FPersistentConnection.h */, + 8CF7B73F4DA5EDEF5C6A440C5FCC53DE /* FPersistentConnection.m */, + 4FCB6D1827727575781B732B26E6B151 /* FPriorityIndex.h */, + F2B6BA82BA68EC9759243F03F20A4E92 /* FPriorityIndex.m */, + 7D9EF1FEC57661FEDFEEE115CE240A13 /* FPruneForest.h */, + A6CAB22B865E3D2DEA28B76B1E77BCFF /* FPruneForest.m */, + 279A3550CD2D5DDEC0DCCEB54A44A4C4 /* FQueryParams.h */, + 51997ADB54C73F1CCA356B77B57555FA /* FQueryParams.m */, + D9AC6948A267A80CDA2B6FA35397F5B9 /* FQuerySpec.h */, + 0C0ECC2192D65619167B3FBDB43CA813 /* FQuerySpec.m */, + BE36269AD6FB60A9259105E262E4081E /* FRangedFilter.h */, + 43C31F092679C01E2C9CE96EBAA48663 /* FRangedFilter.m */, + 050407348E20AAECDC9692CA87B3CD6C /* FRangeMerge.h */, + BE9CA43AFEEF958245EE8ACFBEE39DDE /* FRangeMerge.m */, + FFA7A89F9DC8DAC084A978A4F9B99A5D /* FRepo.h */, + 247163A6FF856A371E4B0C15E8AC85EE /* FRepo.m */, + 121210F3B063DF666F39A8CCFA329536 /* FRepo_Private.h */, + C18E7A2F44E3CA8C7C511D941F510972 /* FRepoInfo.h */, + 224C97647A67A921AFF5BEF517FB27C9 /* FRepoInfo.m */, + 4E6EF280F867455DDB14113B604BA304 /* FRepoManager.h */, + B5CAF3C5A56B499167AC157F5AA1E79C /* FRepoManager.m */, + 0FC945B959C11D5210263BD057197540 /* FServerValues.h */, + 3FEFA415177BF93D444343263FB71D2B /* FServerValues.m */, + 60C94E3663E9FEEEE52C5735B40D1878 /* FSnapshotHolder.h */, + 144C1C9FF805BE562AFDB9A01A69D574 /* FSnapshotHolder.m */, + 5DC3113D655890D1C34171C729A45C4F /* FSnapshotUtilities.h */, + 26FBF5FA8071E77A53B62F51FB74DE70 /* FSnapshotUtilities.m */, + 72A95C2BB95FD8729CF4444BE5B0899B /* FSparseSnapshotTree.h */, + 473169B7B5260E7DB0EF41FC5FE82E1F /* FSparseSnapshotTree.m */, + 7326097D94A70A24EB9F31AED2BC8EAB /* FSRWebSocket.h */, + 1501D5CE22977171369A89A58320F0E7 /* FSRWebSocket.m */, + 70CD617F541028461ADEB6E9EECBE23B /* FStorageEngine.h */, + DE87533E945892A7B9EAA2C43279E3BF /* FStringUtilities.h */, + 6DCA35EF795480806D8EEBF75738F78F /* FStringUtilities.m */, + 25BEA17231DD2405EAF009FDD93C48D7 /* FSyncPoint.h */, + B1AE50A8879222641AC18419CDDD872B /* FSyncPoint.m */, + 32739C50B1DCE959A410D8A13BD08B65 /* FSyncTree.h */, + D5C19AB0924F2D0B33D5F9D3E93B6C02 /* FSyncTree.m */, + D7A0F65DB920061ABF199FC50A40FA72 /* FTrackedQuery.h */, + 972D70808FEDD70C15F55B7E8015CC79 /* FTrackedQuery.m */, + 894D53FA3FFD70DFE5301E4E508B2DFF /* FTrackedQueryManager.h */, + 22DAF0E1D71C0A9951000AABEE74F317 /* FTrackedQueryManager.m */, + 3A7BA2DCF1D8BC5B1D2E1B940D8066D1 /* FTransformedEnumerator.h */, + C57306D422BD4BF9E19EED1B89FD40C9 /* FTransformedEnumerator.m */, + CD98D934A6013CA6873D3813A714C304 /* FTree.h */, + 02282D73DD284911333138BCA9E63E33 /* FTree.m */, + 4457F2FAE5F4B126775B3F4783243322 /* FTreeNode.h */, + A21E69899E4D49D3B37623017C91600C /* FTreeNode.m */, + 8D81569D4FB78A79815500605F8D4D1E /* FTreeSortedDictionary.h */, + 8A49009D41FCF7B380C203917270C643 /* FTreeSortedDictionary.m */, + AFE4F3AA1A28BE43D9287AFBB26703D0 /* FTreeSortedDictionaryEnumerator.h */, + 88DA4130826C456894E35ED6F53A4D9A /* FTreeSortedDictionaryEnumerator.m */, + B19B6B724947A15AD078508AEDEC16E9 /* FTupleBoolBlock.h */, + BF22DB6374FFB9A50C6A86CFB0C76AA5 /* FTupleBoolBlock.m */, + F63A293B954058E9A1379E8390D0C7B6 /* FTupleCallbackStatus.h */, + B5D74D035F6118E5350D969D8DD10787 /* FTupleCallbackStatus.m */, + C617F0D38F777ED4CD1074CC93AC327F /* FTupleFirebase.h */, + 26E73ED066200F04541BEBB190059366 /* FTupleFirebase.m */, + 1B4644B43D841F176E86CB3561348D33 /* FTupleNodePath.h */, + 2582A15A70285331E519CBBEAEF231CD /* FTupleNodePath.m */, + C8EBE838EB55E2BC9441464B7B06BFA5 /* FTupleObjectNode.h */, + D4EA5D48358A64B6E278A7F281758C47 /* FTupleObjectNode.m */, + 7A9D1C75BADE6BF64AAA760F711269D2 /* FTupleObjects.h */, + 7472FF197F11A3E87702DD9487C989EF /* FTupleObjects.m */, + 3953E080065D0ACBDC5447B414FF10C2 /* FTupleOnDisconnect.h */, + 4BC0964039A18391158C331D4DB21FD4 /* FTupleOnDisconnect.m */, + 356D1F2C7C8203EA4BA904A0766E18B5 /* FTuplePathValue.h */, + D823ACADD98348643E4C77C77F7342C8 /* FTuplePathValue.m */, + F7ACDEDE0588E8BFED42E158BF74D1A1 /* FTupleRemovedQueriesEvents.h */, + F9968FB8B37B6F7C4652AFC5FE159D74 /* FTupleRemovedQueriesEvents.m */, + 1476F8352701355D37CB650E82139B98 /* FTupleSetIdPath.h */, + 9FD16AF9100342B1DCBB284920DDBEF5 /* FTupleSetIdPath.m */, + 5EBECD9E9DD343F563D6765E57EFC7F5 /* FTupleStringNode.h */, + C498401C32F8C28FA82FC4A342F00E57 /* FTupleStringNode.m */, + 954AA7FCA35AB21D4C75C8AB916981FF /* FTupleTransaction.h */, + C6B6E040B15704408AD50B573EF3DC97 /* FTupleTransaction.m */, + 0CACFD271582042A2D81EC4C6B15DACD /* FTupleTSN.h */, + 0443112F2C0662B91042E0AEBB57DC06 /* FTupleTSN.m */, + 84A5D23ED0B9FFA009FFA35EB291AB1A /* FTupleUserCallback.h */, + ED1405255E18F31D45F86A8C53FFCCCB /* FTupleUserCallback.m */, + 5FA052929FA7D379DAE94EC06B51D6EE /* FTypedefs.h */, + C595E476B33E9109CFF379EC8ACA664F /* FTypedefs_Private.h */, + 073FA4385301B0EDD8CBBE54E0A85814 /* FUtilities.h */, + CE7FD3CFEE2A2A5C9E216149A1A17A0E /* FUtilities.m */, + 61ACF260B4EF5D451280A6D877073D43 /* FValidation.h */, + 9197527BF54C7861B6DA0625FED4EE24 /* FValidation.m */, + D90AC7BDF0B4BFB4AA7E3274289B83E7 /* FValueEventRegistration.h */, + D31E2D7BB58C00689E3BFF3B7399343B /* FValueEventRegistration.m */, + 58504D264295A60569A9BACA31B854E4 /* FValueIndex.h */, + 79CCFA5EFC38FED164C8F415BC49DF1E /* FValueIndex.m */, + BA438D914FD85D28EB649CD0E6157459 /* FView.h */, + 7C3BEB5634C1BC4486799C71640690D6 /* FView.m */, + 2C9BDBDC57900F889A1652635E54DE7B /* FViewCache.h */, + 562F8CB0D3313A7C1376DB26779FD16F /* FViewCache.m */, + B03BC145252CE9439EBA6193ED4FD670 /* FViewProcessor.h */, + 8DAF410F81561E974F2E4070A0334FF2 /* FViewProcessor.m */, + C9301A96DC9D610653E5C327A7CC6D68 /* FViewProcessorResult.h */, + 42174118D83E777F4DC7503F4BADCDDF /* FViewProcessorResult.m */, + 32D626A4D1610ABDE8CEF2647EB63976 /* FWebSocketConnection.h */, + C4FEF857D99B721AC9FA93B793FE4332 /* FWebSocketConnection.m */, + 48C04CC3873113348843DA33D0D9C28F /* FWriteRecord.h */, + A8CFE27B14FB420A8984CD394175B732 /* FWriteRecord.m */, + B647F3C3F6873E7E8E7E77C89EE80A03 /* FWriteTree.h */, + 497DC3EC24F8F871BE484C8E6E675FB9 /* FWriteTree.m */, + 4026413238A48D0FEA34D02E3F2C199C /* FWriteTreeRef.h */, + 9E00DB364E41712CD057A8C1BF44424D /* FWriteTreeRef.m */, + 9BDB0946FE4427D7EE3CC47737533840 /* NSData+SRB64Additions.h */, + E972B990B021624DF8F843EB6A72994F /* NSData+SRB64Additions.m */, + C133CA569680BBE9A31833EB690CD1A6 /* Support Files */, + ); + name = FirebaseDatabase; + path = FirebaseDatabase; sourceTree = ""; }; 2BCEA554400F3D5EBC30412D941711B0 /* AnimatableProperties */ = { @@ -3582,40 +4803,45 @@ path = "lottie-ios/Classes/AnimatableProperties"; sourceTree = ""; }; - 2BD36F57CFC5380F2FDF54CDA032AAC7 /* Frameworks */ = { + 2D7C1931165E91D50259F37EC8299E52 /* NSDictionary+URLArguments */ = { isa = PBXGroup; children = ( - 6ECB293043438D7AA669ACD4DA0AA4C5 /* FirebaseRemoteConfig.framework */, + 32A0B6720F9A5E7B16DF805BAC9B4BE5 /* GTMNSDictionary+URLArguments.h */, + 7D5E2C8453763AD280CD8070711E7F32 /* GTMNSDictionary+URLArguments.m */, ); - name = Frameworks; + name = "NSDictionary+URLArguments"; sourceTree = ""; }; - 2D3DE2E31F2D872157EF8F212CC1F859 /* Frameworks */ = { + 2D7F07D099FB37E7C40DCE511B316E2B /* FirebaseInstanceID */ = { isa = PBXGroup; children = ( - 48659E513214C479B4B888D3B8350612 /* FIRAnalyticsConnector.framework */, - 94A5A82BB6865C83B8A112721EB86BB8 /* FirebaseAnalytics.framework */, - FC7E6370ED8E8ECEE0DFC1F1FEF95096 /* FirebaseCoreDiagnostics.framework */, + A2112E575AE2EE3E14261FF8A02CF2CB /* Frameworks */, + FAC4991A72205D7859F70DD53B02792A /* Support Files */, ); - name = Frameworks; + name = FirebaseInstanceID; + path = FirebaseInstanceID; sourceTree = ""; }; - 2EAC24B63631910A23E52DA8FAC9C9E5 /* Frameworks */ = { + 2EDBDA4D92612A3DC2D3462CACE641FF /* Reachability */ = { isa = PBXGroup; children = ( - F08376C309E3A7B855BEF7D386E55ACC /* Fabric.framework */, + B23331D08F0FB92619826BCF638468EC /* GULReachabilityChecker.h */, + 660E8F4A387A81130A3B64FDA0DC2C2F /* GULReachabilityChecker.m */, + 7D639F9D72183C354888805CCE9DD613 /* GULReachabilityChecker+Internal.h */, + 23AFDC3FD68BD01B454A06682CE3ACD8 /* GULReachabilityMessageCode.h */, ); - name = Frameworks; + name = Reachability; sourceTree = ""; }; - 2FF2B9103B5FF92F6CF5340AC1EB2D3A /* GTMSessionFetcher */ = { + 2FBBA01BCEE7BF9E18C782F8CF95F2CE /* Support Files */ = { isa = PBXGroup; children = ( - 5452125F43CB215096948BCA9936BF30 /* Core */, - D79E835CDA9B31B584D471309760C1F4 /* Support Files */, + D229CC4B4E3B58BD5DC90E01A82CFD88 /* leveldb-library.xcconfig */, + AB9F058E8DFCEF13A69CAD294274BF95 /* leveldb-library-dummy.m */, + D53B439011DAD099853AF3889D7B9E54 /* leveldb-library-prefix.pch */, ); - name = GTMSessionFetcher; - path = GTMSessionFetcher; + name = "Support Files"; + path = "../Target Support Files/leveldb-library"; sourceTree = ""; }; 30D1FF08E84DF4F40651C487191AD92D /* Resources */ = { @@ -3651,15 +4877,6 @@ path = "../../ios/Pods/Target Support Files/RNGestureHandler"; sourceTree = ""; }; - 32839E364152CEE1450A53BE2AC57572 /* Support Files */ = { - isa = PBXGroup; - children = ( - E6D8D2B589B7505E5F8303C187DD0871 /* Crashlytics.xcconfig */, - ); - name = "Support Files"; - path = "../Target Support Files/Crashlytics"; - sourceTree = ""; - }; 32EC7D8967951D2F34D5B65AFC8D6F53 /* ManipulatorNodes */ = { isa = PBXGroup; children = ( @@ -3688,12 +4905,13 @@ path = "../../node_modules/lottie-ios"; sourceTree = ""; }; - 353980B67A83A15D8C226855106DE7AF /* CoreOnly */ = { + 3560D9B3FD533A2E87854E1D49278FC8 /* Support Files */ = { isa = PBXGroup; children = ( - D01034046F54D95FB3954D9BCB09728F /* Firebase.h */, + AB8A9CADCFA27F2AF11A9FF2DDEEE4F9 /* GoogleAppMeasurement.xcconfig */, ); - name = CoreOnly; + name = "Support Files"; + path = "../Target Support Files/GoogleAppMeasurement"; sourceTree = ""; }; 38710A60ECB545373FEFD0786BB3B547 /* cxxreact */ = { @@ -3736,6 +4954,35 @@ name = cxxreact; sourceTree = ""; }; + 39D32C7C9A2B5456974A42AEEBD9F440 /* Logger */ = { + isa = PBXGroup; + children = ( + B5FA10934409CED2B3FD4C266168AD26 /* GTMLogger.h */, + E26BCDA9139114A005F6E1B64F0322EE /* GTMLogger.m */, + ); + name = Logger; + sourceTree = ""; + }; + 39D99F8E69EA7B3FAA8F989AECF383EB /* Support Files */ = { + isa = PBXGroup; + children = ( + 8F51B0E5493C1021B8F13C0DBE689DBA /* Firebase.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/Firebase"; + sourceTree = ""; + }; + 3DDFD0720066C466C26195030D6A3066 /* Support Files */ = { + isa = PBXGroup; + children = ( + 053F5C4B01F3F55AF0D991966A9AFB40 /* Protobuf.xcconfig */, + 10C619156E9298615BA8F6EFD90E2786 /* Protobuf-dummy.m */, + B5C7AABDAD319DCAA5D16BB307B85F74 /* Protobuf-prefix.pch */, + ); + name = "Support Files"; + path = "../Target Support Files/Protobuf"; + sourceTree = ""; + }; 4338A79750C0C02CCCF4D50EF12BE163 /* Extensions */ = { isa = PBXGroup; children = ( @@ -3753,29 +5000,53 @@ path = "lottie-ios/Classes/Extensions"; sourceTree = ""; }; - 44DE2F80960376614C6B1B6F9745696E /* Crashlytics */ = { + 43F667A8F8489C369E9847D584CEE39B /* Support Files */ = { isa = PBXGroup; children = ( - E61A6F3D99F028A4319041B8E296FAF3 /* ANSCompatibility.h */, - 0FDF8816221E690C3EF750B7BC3B3CCB /* Answers.h */, - 1B4BEF4027A9C2211C97B5F2A75601C7 /* CLSAttributes.h */, - 18BD70EBB27C2C225F7C9265B7A5AFBC /* CLSLogging.h */, - C773304DB418B220023CBE9A87606274 /* CLSReport.h */, - ABED08F5DBD737384350543B1E1BBA36 /* CLSStackFrame.h */, - 1D71AD1DB4527B0E722DBF9C232C497E /* Crashlytics.h */, - 5DDE9F30AA12E28E2E555882AEF4A8CB /* Frameworks */, - 32839E364152CEE1450A53BE2AC57572 /* Support Files */, + D299AD82DC20B38AB6F91E9CFB0B288E /* FirebasePerformance.xcconfig */, ); - name = Crashlytics; - path = Crashlytics; + name = "Support Files"; + path = "../Target Support Files/FirebasePerformance"; sourceTree = ""; }; - 49D3B787269FAF211F88ACD90427AD8D /* Defines */ = { + 44ECEE4E8F295D1DE795BD66C1E67E15 /* Resources */ = { isa = PBXGroup; children = ( - 4B166C99A5BAB626C5AE7A6B572EA8F1 /* GTMDefines.h */, + 0CED65E4831C1A74A2F05C919CF3A6FA /* GoogleSignIn.bundle */, ); - name = Defines; + name = Resources; + sourceTree = ""; + }; + 470DAC2834F86DFE321D8E93672ACE17 /* glog */ = { + isa = PBXGroup; + children = ( + 0091745266BB0CA502AFA0EEE4BC1F65 /* demangle.cc */, + FEA943D1799FC73FC42813F1177AD37D /* log_severity.h */, + 601F5DDAD74761C1B8AA0BC62A59E2A0 /* logging.cc */, + 55086ABF2F5769B99BC491AABF543073 /* logging.h */, + FA951E29A39E4CF2BE2834740CF4F5C7 /* raw_logging.cc */, + 33E3B98582281B282D18F8BC608009B3 /* raw_logging.h */, + 552E2C917A1918F04F22AA02556B8562 /* signalhandler.cc */, + E93A0049997B4AF4882B81A770C7A357 /* stl_logging.h */, + C17BCCDDD4B9DE20CDD862DB25AE65EE /* symbolize.cc */, + 0A53EF276FBFF04D58AA684821959964 /* utilities.cc */, + FC87325B7FE134E2BA0D1F307D81C10A /* vlog_is_on.cc */, + 5CC3EF116CEB4E86A61C700DAF2FAF03 /* vlog_is_on.h */, + 623BCD1C8FE30CF815205613C0BC5AE5 /* Support Files */, + ); + name = glog; + path = glog; + sourceTree = ""; + }; + 489350B79281D0614F64042EE9C61B0A /* AppDelegateSwizzler */ = { + isa = PBXGroup; + children = ( + 856D59AAC88A0EAB2C54480479C7B899 /* GULAppDelegateSwizzler.h */, + F121AD95A2079F5A12FCCFABC3DF1CF8 /* GULAppDelegateSwizzler.m */, + 1B16B1592C78D9E8DDA420A908C6954A /* GULAppDelegateSwizzler_Private.h */, + 9EC86C9577627EF1AE803B92047DB36A /* GULLoggerCodes.h */, + ); + name = AppDelegateSwizzler; sourceTree = ""; }; 49DEC8DF676344C64F8E8BEA426F7B67 /* Pods-KalendTests */ = { @@ -3803,86 +5074,41 @@ path = Libraries/Text/BaseText; sourceTree = ""; }; - 4BB29917B6D82CF0463A51C548211AB3 /* Protobuf */ = { - isa = PBXGroup; - children = ( - A7528D347E330AA90943C4E0F75EFF1B /* Any.pbobjc.h */, - 0F621743FB68D849DBB1B3AB4FBF0F50 /* Any.pbobjc.m */, - 8F686A439382FEEAB83044D57C61F0BB /* Api.pbobjc.h */, - A2FC2BDCA6C193274FC35FEFE7B968A3 /* Api.pbobjc.m */, - 03652FC81BBDDC08F924DD4287DCFEC6 /* Duration.pbobjc.h */, - 7545ED3CF47CD833D50D1BECB7E25191 /* Duration.pbobjc.m */, - 843C108D6749BB75281B7551D4057AAD /* Empty.pbobjc.h */, - 7B1D4D3C0E4191DF1485194B68CEB7AD /* Empty.pbobjc.m */, - 75ADAB93DC535E6DF3AAC46DAA07D9DC /* FieldMask.pbobjc.h */, - 045BD9EED41E317E0FD863E5D64EA5B7 /* FieldMask.pbobjc.m */, - 59A526190F6146A759532A4C61F5E776 /* GPBArray.h */, - 399AC2DD582FFA867EB3094A2FEC06A8 /* GPBArray.m */, - 9B60BC65335FEDFB242BAED10AA3B0BC /* GPBArray_PackagePrivate.h */, - 55BFCCA16E8D02EB0E1E34DC2BAEAFD2 /* GPBBootstrap.h */, - 4B7B0F102C88F6DAF4C3966658C3C929 /* GPBCodedInputStream.h */, - C155DB55D12C657623843D2DE1B723C0 /* GPBCodedInputStream.m */, - 52A4AE6DDD3EA030E3CAC170B3C190AD /* GPBCodedInputStream_PackagePrivate.h */, - CB581520BBAE84BDC670F94F64B3FE2C /* GPBCodedOutputStream.h */, - 704B5D61B511B65AB42B8159854ECBDE /* GPBCodedOutputStream.m */, - 251B3A4D5C73A6D5545A5C5D38F4E596 /* GPBCodedOutputStream_PackagePrivate.h */, - 693E671BE3C1553C44C0A6CDF5D15765 /* GPBDescriptor.h */, - F33CF734EB75D645B6F559246B91C0EE /* GPBDescriptor.m */, - 3F53BFB4A05790B07429F81FDFC82E28 /* GPBDescriptor_PackagePrivate.h */, - C38431EA2F1BFEA2C3D23BC917886E86 /* GPBDictionary.h */, - E7A74FC9AFF395322FB8D818AE4F9D48 /* GPBDictionary.m */, - 67A6DC4F6F9CD4DE1E36CD36DD25E40E /* GPBDictionary_PackagePrivate.h */, - 164E6AF71FDF857751A56340FCE1685E /* GPBExtensionInternals.h */, - 94F478DC9FFEB03F60B3A9D8CAB4F8E6 /* GPBExtensionInternals.m */, - 2E1AA42D2B4DF27E096A2A733289CC42 /* GPBExtensionRegistry.h */, - 018DA0CED90F3227330B1E4C36E30D39 /* GPBExtensionRegistry.m */, - CE2BE289D98F170C42BD48505D636DED /* GPBMessage.h */, - D67703327E542502AE07DAA13C45E9D4 /* GPBMessage.m */, - 2A6DF6B5FABFF927C45202CE34C54F6A /* GPBMessage_PackagePrivate.h */, - 43497B573E91EF51113E2EEBC8C1EC96 /* GPBProtocolBuffers.h */, - B43C5CAB0FF24DA68A1B4B097044C880 /* GPBProtocolBuffers_RuntimeSupport.h */, - BBB105BF3615DD99C8BDB51065E1D6F3 /* GPBRootObject.h */, - 40E19694FE31A1B80E73A68B32E53D48 /* GPBRootObject.m */, - E09978CEA186ADB6111AD2F9C5948BD6 /* GPBRootObject_PackagePrivate.h */, - 4FF78D17720D1DF41C6200A4DAA3A4BB /* GPBRuntimeTypes.h */, - C535944E602B816C57B438C995D97885 /* GPBUnknownField.h */, - CC009AD3A6FC5280653B1AFEFB598776 /* GPBUnknownField.m */, - FAAFA9FE05ABD9EC9E489698BB896A55 /* GPBUnknownField_PackagePrivate.h */, - 4A4E6E17CDE7E172CD43CCC6944BD67A /* GPBUnknownFieldSet.h */, - 7A49385C1B5229EEBF1131781952DF75 /* GPBUnknownFieldSet.m */, - 0AF5AE5037BF6C75F311B1B382B1BD12 /* GPBUnknownFieldSet_PackagePrivate.h */, - CFECFEAE9C6ACBAC47AEDE6533BE668B /* GPBUtilities.h */, - 56C71E142AC9AF135CF8FFABF92C82DA /* GPBUtilities.m */, - 21661A7F663A0C93FA1F45E12ED66480 /* GPBUtilities_PackagePrivate.h */, - 8526A6E0B4983EEBE27458896D71AE80 /* GPBWellKnownTypes.h */, - AFF5C24E7B1C59368C5150DB1C38082E /* GPBWellKnownTypes.m */, - B9081F23DE9B5CE80A9F7E36382251BD /* GPBWireFormat.h */, - 88DF437691E927D8BF17D5DEDA4F65EA /* GPBWireFormat.m */, - 3B457FAC86A7D2B564DEC7B9230B1745 /* SourceContext.pbobjc.h */, - ABE121B8F8204830E2DDDB9E6E0B724E /* SourceContext.pbobjc.m */, - 2CF91E718BB25941178A5127B828D618 /* Struct.pbobjc.h */, - F94A26A5BD1EFE7C445E6E39296D4C9C /* Struct.pbobjc.m */, - 965A11AA7991DDB3973C8D73A71FA994 /* Timestamp.pbobjc.h */, - D3BD408FFBCEBE1D2EDAED208F372A46 /* Timestamp.pbobjc.m */, - E56AB81FDD4BA5BC1152795983E34F3A /* Type.pbobjc.h */, - EC02BD47C323C6CDD736A555CCC513D3 /* Type.pbobjc.m */, - BEFB98ED37598B87DC7616F39F161E8A /* Wrappers.pbobjc.h */, - B9774DBEB2D9E947C193E108F5037DA0 /* Wrappers.pbobjc.m */, - 4E37141F36B64383D54DFE84F449F238 /* Support Files */, + 4CCB825F5AC68CCDB43D1063715601C4 /* FirebaseRemoteConfig */ = { + isa = PBXGroup; + children = ( + E91BD7196B0C9A3F1F9449C1C678E57D /* Frameworks */, + E4FC724836DC1C7CAD1DA6AD582E5C8A /* Support Files */, ); - name = Protobuf; - path = Protobuf; + name = FirebaseRemoteConfig; + path = FirebaseRemoteConfig; sourceTree = ""; }; - 4E37141F36B64383D54DFE84F449F238 /* Support Files */ = { - isa = PBXGroup; - children = ( - 4D837984DF861DEEF7EB13DB66895A8D /* Protobuf.xcconfig */, - BECFE46C4D035B9D9F991722AA0B59BC /* Protobuf-dummy.m */, - 2831E881A4F91126F443F35CD9C43A29 /* Protobuf-prefix.pch */, + 4E8CD56C55A5B44742EFAD311C8936F8 /* DoubleConversion */ = { + isa = PBXGroup; + children = ( + C8DE78C4F95B9EBFE477962A8FFD4D8F /* bignum.cc */, + 0903408DDF7F8C3AD3752EB1503C160E /* bignum.h */, + 2D38CC89FE381ABEE58778A8430EC558 /* bignum-dtoa.cc */, + E4EA040473FF29F9FB33D19CA9E5D77C /* bignum-dtoa.h */, + E51A57E86D7E23F9AF304C34332DD319 /* cached-powers.cc */, + 6377CCAE0CE909B359DACF7BE9A33CA0 /* cached-powers.h */, + FD226B9F64B84B90460570210B738B55 /* diy-fp.cc */, + 2D1EDBB41D682CA19504C5D902951F7F /* diy-fp.h */, + 0079273BFA178FC1D3EB5A83E2E021CE /* double-conversion.cc */, + A32E5E0F146D5D98346795AB2202609C /* double-conversion.h */, + E4F17079DA08EE5B499986B263AA74E1 /* fast-dtoa.cc */, + 007D6D8738E909C6CF0320FF9CE52D28 /* fast-dtoa.h */, + 6A8046567CE04F8DFE9CEEE8A4C16012 /* fixed-dtoa.cc */, + F10372658AF8256C69BF8332554C2705 /* fixed-dtoa.h */, + 1CBD2C6F54A33026F16AD69A95A2FB37 /* ieee.h */, + D2B7B63FEF8ACB55544B78B64DCE68B0 /* strtod.cc */, + E28F9CFD4A5F59337955F5E5E29D7D00 /* strtod.h */, + 94E0F561370BA98565BFE8AB2C1009E0 /* utils.h */, + E874305A386E4B2B1AEE71217B571425 /* Support Files */, ); - name = "Support Files"; - path = "../Target Support Files/Protobuf"; + name = DoubleConversion; + path = DoubleConversion; sourceTree = ""; }; 52D56CBACDD52E79F5D7507B705F3701 /* Support Files */ = { @@ -3896,19 +5122,13 @@ path = "../../ios/Pods/Target Support Files/BVLinearGradient"; sourceTree = ""; }; - 5452125F43CB215096948BCA9936BF30 /* Core */ = { + 536AAB4CB04B9AE19CC283D9EA172604 /* boost-for-react-native */ = { isa = PBXGroup; children = ( - C5653F8D546A15A5F37363138529A92F /* GTMSessionFetcher.h */, - B5DDE4132759E6E19918282C11B5F81A /* GTMSessionFetcher.m */, - 6D41F04E9445A45F2AC4B9B3E9E09BFF /* GTMSessionFetcherLogging.h */, - 02D4C7FEC7F4BD8E48C873E644DC9D4A /* GTMSessionFetcherLogging.m */, - D217F05EA07BA1756CB1ED1DB1B1297A /* GTMSessionFetcherService.h */, - 261886C1CC9C635DF4D09F766A9EBBE3 /* GTMSessionFetcherService.m */, - 50AD35B3BB2CAE00789A8EEB035CDE08 /* GTMSessionUploadFetcher.h */, - B3BB7130EFA148C5F3F281D62152FE76 /* GTMSessionUploadFetcher.m */, + 6E445C96D1557E8CED57A42B0EA50D2B /* Support Files */, ); - name = Core; + name = "boost-for-react-native"; + path = "boost-for-react-native"; sourceTree = ""; }; 56338E322F47B9635E1B684F22520B84 /* Inspector */ = { @@ -3923,42 +5143,44 @@ path = React/Inspector; sourceTree = ""; }; - 5D747C7DE3B308F734522E9F4995E831 /* RCTBlob */ = { + 5B6B068E147BC4A7DF40B1416E5BFDF9 /* Support Files */ = { isa = PBXGroup; children = ( - 52DD891097E8BA881AA45ECCD08088A6 /* RCTBlobManager.h */, - C7355975BE16954A289895CFB03F6130 /* RCTBlobManager.mm */, - E7D6FF54DB702FEF68CC23A8E0C134FE /* RCTFileReaderModule.h */, - 7EF9CF21CA97F3E245FF3C7C05FCC207 /* RCTFileReaderModule.m */, + D7B5F2F53B922C2DA16A59C5A8B63185 /* GoogleUtilities.xcconfig */, + 2905FC763BAE2E62DB4A4F12CCD07622 /* GoogleUtilities-dummy.m */, + 412FAA9B45D3BC5F377824D97A606828 /* GoogleUtilities-prefix.pch */, ); - name = RCTBlob; + name = "Support Files"; + path = "../Target Support Files/GoogleUtilities"; sourceTree = ""; }; - 5D97952CF8C95D245D9E9585BC41C023 /* Pod */ = { + 5C55488882496282E2E858C013C9D13A /* Frameworks */ = { isa = PBXGroup; children = ( - 6ABC30AA2971247A0B65DE455BBFDACD /* LICENSE */, - BD43401BDCCF005FE929D4B0B6F32221 /* README.md */, - 7A7EEA9F3DF5F35E148C1B93FDAB8737 /* RNVectorIcons.podspec */, + BC8B62A2E1B21D7D1EF6B9EDCDC01935 /* Crashlytics.framework */, ); - name = Pod; + name = Frameworks; sourceTree = ""; }; - 5DDE9F30AA12E28E2E555882AEF4A8CB /* Frameworks */ = { + 5D747C7DE3B308F734522E9F4995E831 /* RCTBlob */ = { isa = PBXGroup; children = ( - 188115FBADC84AD94022FC7497ADA47A /* Crashlytics.framework */, + 52DD891097E8BA881AA45ECCD08088A6 /* RCTBlobManager.h */, + C7355975BE16954A289895CFB03F6130 /* RCTBlobManager.mm */, + E7D6FF54DB702FEF68CC23A8E0C134FE /* RCTFileReaderModule.h */, + 7EF9CF21CA97F3E245FF3C7C05FCC207 /* RCTFileReaderModule.m */, ); - name = Frameworks; + name = RCTBlob; sourceTree = ""; }; - 5E8AC9F6532F71EE58C4AACD3D6FB86C /* Support Files */ = { + 5D97952CF8C95D245D9E9585BC41C023 /* Pod */ = { isa = PBXGroup; children = ( - 15B2B5FFFEFF905A2E8F5CAD7D6E83D9 /* FirebaseRemoteConfig.xcconfig */, + 6ABC30AA2971247A0B65DE455BBFDACD /* LICENSE */, + BD43401BDCCF005FE929D4B0B6F32221 /* README.md */, + 7A7EEA9F3DF5F35E148C1B93FDAB8737 /* RNVectorIcons.podspec */, ); - name = "Support Files"; - path = "../Target Support Files/FirebaseRemoteConfig"; + name = Pod; sourceTree = ""; }; 5EA481DDE52B8B4BE52F89CD7EA04BDB /* Private */ = { @@ -3981,6 +5203,21 @@ path = "lottie-ios/Classes/Private"; sourceTree = ""; }; + 5F57C61A2A2CB384063FB4F4B3D71891 /* Core */ = { + isa = PBXGroup; + children = ( + DAFE21A309048749918F40D0AEEF651B /* GTMSessionFetcher.h */, + 9677C666B33082D8B27E6DCD72A275C6 /* GTMSessionFetcher.m */, + BFF0522100C085C847D645AB1139E93C /* GTMSessionFetcherLogging.h */, + 421A08E7B9F97963B5D038C345894614 /* GTMSessionFetcherLogging.m */, + 3CD58A35D4D5CEA9C36AE6EEB064AC42 /* GTMSessionFetcherService.h */, + C11F09F5D7BFF243861A75935726732E /* GTMSessionFetcherService.m */, + C490B04338D5B6C8B578768799D868C2 /* GTMSessionUploadFetcher.h */, + B92D1B13AFFAD16CE0CDDF43FE71D1C0 /* GTMSessionUploadFetcher.m */, + ); + name = Core; + sourceTree = ""; + }; 5FD6EDADBDE171A6B1327EF1BA73AD7A /* Pod */ = { isa = PBXGroup; children = ( @@ -4051,14 +5288,15 @@ path = "../../node_modules/rn-fetch-blob"; sourceTree = ""; }; - 62D76B19092EB46004120C788C319DE6 /* FirebaseABTesting */ = { + 623BCD1C8FE30CF815205613C0BC5AE5 /* Support Files */ = { isa = PBXGroup; children = ( - FB9EB62AF0A182D7747320D0C0A7690D /* Frameworks */, - 916359A2A9AD7C6AFD962450AD7BF665 /* Support Files */, + F08847E07FB985EEA88834452E00AE45 /* glog.xcconfig */, + 8731D3E9DDAC0B89CDD6F6EC2D655B24 /* glog-dummy.m */, + 97CD5C8C1C395381AE311D463DC443A0 /* glog-prefix.pch */, ); - name = FirebaseABTesting; - path = FirebaseABTesting; + name = "Support Files"; + path = "../Target Support Files/glog"; sourceTree = ""; }; 64BA94FD3D382FE54360F36D0E06CC73 /* RCTImage */ = { @@ -4101,15 +5339,12 @@ name = fishhook; sourceTree = ""; }; - 6967585AF965AC0D039D4D00C910310B /* Support Files */ = { + 68E3989753DD74275266668F5F6574DD /* CoreOnly */ = { isa = PBXGroup; children = ( - 9B94044BB8213CE214598799507CBFEC /* nanopb.xcconfig */, - 179D68FDFC3CDCDF06A4BA700012BB6A /* nanopb-dummy.m */, - CE79F1692CCD852490873D21A8A1F5E4 /* nanopb-prefix.pch */, + 9AF40F6C4A43F07E9A10444CB0C59005 /* Firebase.h */, ); - name = "Support Files"; - path = "../Target Support Files/nanopb"; + name = CoreOnly; sourceTree = ""; }; 696F4AFB0BDB982FA0A597E3B329E576 /* SafeAreaView */ = { @@ -4128,12 +5363,13 @@ path = SafeAreaView; sourceTree = ""; }; - 6DE890B392FDA6F9938881601240DB49 /* Frameworks */ = { + 6C369285569DAC5A13A7E6B9D065E1CB /* Support Files */ = { isa = PBXGroup; children = ( - A20E3A94B5CFE14A6601DBF6817B625A /* GoogleSignIn.framework */, + 9BCD00A0A096989061C773F8C8DFD83E /* FirebaseABTesting.xcconfig */, ); - name = Frameworks; + name = "Support Files"; + path = "../Target Support Files/FirebaseABTesting"; sourceTree = ""; }; 6DED9FD67F1177CE1802F34A31AF480C /* Pod */ = { @@ -4146,24 +5382,52 @@ name = Pod; sourceTree = ""; }; - 70B78359C6EBC8DC20608D1CEF7C233B /* Support Files */ = { + 6E445C96D1557E8CED57A42B0EA50D2B /* Support Files */ = { isa = PBXGroup; children = ( - 4A1D2BA8A36579D7C6ACF5802A9A4F87 /* FirebaseCore.xcconfig */, - 9D561A3F24666C785CEFA0514E9FB9F3 /* FirebaseCore-dummy.m */, + 05287BC664B5445346A8EF5DCADB1246 /* boost-for-react-native.xcconfig */, ); name = "Support Files"; - path = "../Target Support Files/FirebaseCore"; + path = "../Target Support Files/boost-for-react-native"; sourceTree = ""; }; - 73404971D1F0F5EDF17D39DFBFDA918C /* MethodSwizzler */ = { + 6EE5C0A93377A8B527B3CFFCD22E42EB /* Support Files */ = { isa = PBXGroup; children = ( - CE3D896360348ACE18C7BE4C77761091 /* GULOriginalIMPConvenienceMacros.h */, - 8C02673A3977C4B70F2FFE4CFE80D989 /* GULSwizzler.h */, - 58536835EFA959CC6FD5CF5218FDFC75 /* GULSwizzler.m */, + 977D66020EA6D24E36A88FCB18A6AAE7 /* GTMSessionFetcher.xcconfig */, + EB2E9C6FCA433DEE6A1FE505D7BCD974 /* GTMSessionFetcher-dummy.m */, + 2E14A2E0B973C1B11918E2E0DF10B31A /* GTMSessionFetcher-prefix.pch */, ); - name = MethodSwizzler; + name = "Support Files"; + path = "../Target Support Files/GTMSessionFetcher"; + sourceTree = ""; + }; + 700D93D1B73A10C5E879FF5F567D1FC9 /* GoogleUtilities */ = { + isa = PBXGroup; + children = ( + 489350B79281D0614F64042EE9C61B0A /* AppDelegateSwizzler */, + A529596F46E2C5060BDFB8C54D8059F9 /* Environment */, + E7B78806BEDFD695D811E9D3DCC09DBF /* ISASwizzler */, + 9D2E1F39AEDE51176E26215F3F1F0D42 /* Logger */, + 7CB4D831915008DB291E05C839D5BFC8 /* MethodSwizzler */, + 04F378073F79D730A9DC573CF72D4C7D /* Network */, + 1270936F7B8B1E1E97B2972DB4DDE891 /* NSData+zlib */, + 2EDBDA4D92612A3DC2D3462CACE641FF /* Reachability */, + 5B6B068E147BC4A7DF40B1416E5BFDF9 /* Support Files */, + AA134835A3CB89CDD516D648F8B43478 /* UserDefaults */, + ); + name = GoogleUtilities; + path = GoogleUtilities; + sourceTree = ""; + }; + 70950A081D7170EDF494AE7378F31F34 /* DebugUtils */ = { + isa = PBXGroup; + children = ( + CD5404E787B4589BCC278F9ED7665639 /* GTMDebugSelectorValidation.h */, + F8078A0EC20DF2D77210B1B085D2884E /* GTMDebugThreadValidation.h */, + 2C4CFD22020485822A4E873A26E08CB6 /* GTMMethodCheck.h */, + ); + name = DebugUtils; sourceTree = ""; }; 746CF49156554564506F5ADFA53482E5 /* Profiler */ = { @@ -4184,6 +5448,17 @@ path = React/Profiler; sourceTree = ""; }; + 749DA3BAB7B54AB06C9E76DBAA96A3B0 /* GoogleSignIn */ = { + isa = PBXGroup; + children = ( + 96A98A38817F55D79ECD2E3A66821D5E /* Frameworks */, + 44ECEE4E8F295D1DE795BD66C1E67E15 /* Resources */, + 0E7C8E1098EE4C173158E15B01B3E00C /* Support Files */, + ); + name = GoogleSignIn; + path = GoogleSignIn; + sourceTree = ""; + }; 75B074F6B7DAF020089753C2050A5B89 /* Support Files */ = { isa = PBXGroup; children = ( @@ -4195,17 +5470,6 @@ path = "../../ios/Pods/Target Support Files/lottie-react-native"; sourceTree = ""; }; - 77A2A0A58F95DAB36C7AECC7574CE50A /* Reachability */ = { - isa = PBXGroup; - children = ( - 6D65282280EFE00FDF44F5A44A8134F1 /* GULReachabilityChecker.h */, - 887F7DBD5091038F3A40E4095823B0FF /* GULReachabilityChecker.m */, - 832D30811692600A1C71322C43578D87 /* GULReachabilityChecker+Internal.h */, - 2792075F8CDA8BFF18CBE95BD0DD1596 /* GULReachabilityMessageCode.h */, - ); - name = Reachability; - sourceTree = ""; - }; 780160D53D38A4FB2ACD9028DA22E14E /* RNVectorIcons */ = { isa = PBXGroup; children = ( @@ -4221,25 +5485,26 @@ path = "../../node_modules/react-native-vector-icons"; sourceTree = ""; }; - 7A0BCBCC68920681E4558ED2EBF0D456 /* Fabric */ = { + 7CB4D831915008DB291E05C839D5BFC8 /* MethodSwizzler */ = { isa = PBXGroup; children = ( - 3D481A2FEFDEC6C0F85F9CF98283BE9A /* FABAttributes.h */, - 157706EDD3606099FD3DFF40939F0F07 /* Fabric.h */, - 2EAC24B63631910A23E52DA8FAC9C9E5 /* Frameworks */, - E9C95A53B1C11199DC74A894EC27CCF6 /* Support Files */, + 9D0545CF38D0D7BDE8CADA67D790B465 /* GULOriginalIMPConvenienceMacros.h */, + 91CE28EB044818CC40BB467E58167F54 /* GULSwizzler.h */, + 0AAB4A3659EDD277935020E5576C79ED /* GULSwizzler.m */, ); - name = Fabric; - path = Fabric; + name = MethodSwizzler; sourceTree = ""; }; - 7C4C752F0F9A6C73582A57AAB49F9628 /* Support Files */ = { + 7E0B7EBF09C4B3A6E4F89A7FC53E0669 /* Fabric */ = { isa = PBXGroup; children = ( - 882D20CF3E4020747627A3A5FE26F042 /* GoogleSignIn.xcconfig */, + 4F3B40DFBA149C119799DFD182066F9C /* FABAttributes.h */, + F3A4CCB65F606F18AF787E7DAB77CEFE /* Fabric.h */, + 834611A3197D7DD3C353314E7AA13F87 /* Frameworks */, + 87E9B8536C3B2D2A23CF602AE6056038 /* Support Files */, ); - name = "Support Files"; - path = "../Target Support Files/GoogleSignIn"; + name = Fabric; + path = Fabric; sourceTree = ""; }; 7FFB85C1582BFA792479DDD65A3FF023 /* jsi */ = { @@ -4304,48 +5569,12 @@ path = Libraries/NativeAnimation/Drivers; sourceTree = ""; }; - 83CBFE6ACCCFE16D36E9DAD78813CAB5 /* FirebaseCore */ = { - isa = PBXGroup; - children = ( - A066CEC53E71610DC720C640B5F947AC /* FIRAnalyticsConfiguration.h */, - DAD798862C9706CF2AD96981528491E6 /* FIRAnalyticsConfiguration.m */, - 5E987BD8711908B25633630076E4D31C /* FIRAnalyticsConfiguration+Internal.h */, - 8E6228157D6E72B153CDEF9FD2F04E8D /* FIRApp.h */, - 1A8327FC8E434A4FD8AD318FD9CCF1DF /* FIRApp.m */, - 956092396D8711436F8FD00E422519E4 /* FIRAppAssociationRegistration.h */, - ECB0BC7C084D6EF921C6A0DDFE303A52 /* FIRAppAssociationRegistration.m */, - 1DEA959471C355E2B056B18A9D36B924 /* FIRAppInternal.h */, - F8CF17E734F32CD73EEC467FCE9A45B5 /* FIRBundleUtil.h */, - 228E1FDFF261DF8EB10848297D3AB291 /* FIRBundleUtil.m */, - 4EB3BB905ECB39DB9D7D567060436721 /* FIRComponent.h */, - BD9521758003CF81234DC8B5C4D59376 /* FIRComponent.m */, - 7B5C38E88269258D4425BB6B3CEC1A39 /* FIRComponentContainer.h */, - 98FC40A3FE46790AAADF0F447DBD2475 /* FIRComponentContainer.m */, - 81728A50D2944B4CA77790DAB5A0AC3D /* FIRComponentContainerInternal.h */, - DE06D8A8706390B6234D827E9B397F5D /* FIRComponentRegistrant.h */, - 65996BB673A0A753370E3D489BA11ACE /* FIRComponentType.h */, - DF2213EE14498C8830860C206AA10A17 /* FIRComponentType.m */, - 41C13D3D29D39FB608EB5F98BEACAB05 /* FIRConfiguration.h */, - 5E9C5CEDA8D77EA5BEE7FD692986F180 /* FIRConfiguration.m */, - 91AA353441322E37B9D6F28C0BEC52BA /* FIRCoreConfigurable.h */, - 87FD80787842E07D922056CD49FC2EE1 /* FIRDependency.h */, - 9871279D3275A57A5741B76A1FA0C70C /* FIRDependency.m */, - F3B8ED4FC03D2D28F01CB56C2C5F8B84 /* FirebaseCore.h */, - 8562F0DDAF1B176288A98162E9134DD1 /* FIRErrorCode.h */, - 9DAA4CF4117F164B6489B04E99B3DDC8 /* FIRErrors.h */, - F1EB83C041B24EB45510D09F3E799544 /* FIRErrors.m */, - 4153397B595713F36B71DB3D53A7F8B9 /* FIRLogger.h */, - 06B7A465837535A2CB308829DF834B8B /* FIRLogger.m */, - 1F6860C06A97C95A108D783D81E2163D /* FIRLoggerLevel.h */, - 9DFA54C268300CACAB672429F27F4893 /* FIROptions.h */, - E8016487FDE2099DD54389EA7B3BCEFB /* FIROptions.m */, - 30BC39D87A2A7DB8BA697925454B1880 /* FIROptionsInternal.h */, - FEE80C65BE332B5B353A346DB6BA667C /* FIRVersion.h */, - 359ED3EAF36B84F77497C0D3990E3302 /* FIRVersion.m */, - 70B78359C6EBC8DC20608D1CEF7C233B /* Support Files */, + 834611A3197D7DD3C353314E7AA13F87 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 61882694087119C9EACDCA7808A7CEAE /* Fabric.framework */, ); - name = FirebaseCore; - path = FirebaseCore; + name = Frameworks; sourceTree = ""; }; 842D8DA8AF6F02070A882D8AE737B4AD /* RawText */ = { @@ -4378,14 +5607,13 @@ path = Libraries/ART/Brushes; sourceTree = ""; }; - 88B8BABCF300520C62698EC1DF73CFAC /* Logger */ = { + 87E9B8536C3B2D2A23CF602AE6056038 /* Support Files */ = { isa = PBXGroup; children = ( - 42CE6557E4770B5F0D1F2C2B81F80F97 /* GULLogger.h */, - 2233E91FFBE6CBACEFCB81BD57B1B34D /* GULLogger.m */, - BF207081B235EAF25864BC44066D2241 /* GULLoggerLevel.h */, + 3AC89BACB5F8AA89ED44F24D013259E2 /* Fabric.xcconfig */, ); - name = Logger; + name = "Support Files"; + path = "../Target Support Files/Fabric"; sourceTree = ""; }; 89B1FA7E1B7F0AB243EDD68331DA32E6 /* ViewManagers */ = { @@ -4424,6 +5652,23 @@ path = Libraries/Text/Text; sourceTree = ""; }; + 8DE3D15655EBE8968E6616A8B3E8819E /* Crashlytics */ = { + isa = PBXGroup; + children = ( + B2633AA729012C8F9A895D11943A5963 /* ANSCompatibility.h */, + 82119C686FAE08B6354EDEA9F39962B0 /* Answers.h */, + 5CC1DE1429BDC8EF516F540CE704AE69 /* CLSAttributes.h */, + 4CF512EAEBEB1E1AB12A8A573BEFBA68 /* CLSLogging.h */, + 4DEBEA10243186DD60C9FF25CE3B0850 /* CLSReport.h */, + 122B6326C706977426CCFAC9070682FC /* CLSStackFrame.h */, + DEC2277CFF299DC146C91D2C77A9481C /* Crashlytics.h */, + 5C55488882496282E2E858C013C9D13A /* Frameworks */, + DE5BC9EA66EB10A2040F267FC1F5B036 /* Support Files */, + ); + name = Crashlytics; + path = Crashlytics; + sourceTree = ""; + }; 8EA2B36BEF7BC6FC009FAF9A1E2BA015 /* Base */ = { isa = PBXGroup; children = ( @@ -4504,22 +5749,14 @@ path = React/Base; sourceTree = ""; }; - 8F4FDAD3251F42F325985D437EDC5146 /* Support Files */ = { - isa = PBXGroup; - children = ( - A2BE11A3B339E51FA7A12775C1F8C727 /* boost-for-react-native.xcconfig */, - ); - name = "Support Files"; - path = "../Target Support Files/boost-for-react-native"; - sourceTree = ""; - }; - 8FE979E90FCC24872818DEBFAAF163A9 /* NSString+URLArguments */ = { + 9108661FC1BE030C92DEA31ECF196A4E /* FirebasePerformance */ = { isa = PBXGroup; children = ( - 9C51BCC2C2047CF29CEE5B7144FE4CDD /* GTMNSString+URLArguments.h */, - 18B460E4AEBC71D4F729A44EA5FDDB3C /* GTMNSString+URLArguments.m */, + 9852C04837898D0D75E990E9251A1486 /* Frameworks */, + 43F667A8F8489C369E9847D584CEE39B /* Support Files */, ); - name = "NSString+URLArguments"; + name = FirebasePerformance; + path = FirebasePerformance; sourceTree = ""; }; 91450A5BB998C806EF6B6D875AB07068 /* Pod */ = { @@ -4531,23 +5768,22 @@ name = Pod; sourceTree = ""; }; - 916359A2A9AD7C6AFD962450AD7BF665 /* Support Files */ = { + 956AECC74E2AD54E6735BBE7638E9D0F /* FirebaseABTesting */ = { isa = PBXGroup; children = ( - 4D5CAF3D45E732FD8A39342B97FA8FDA /* FirebaseABTesting.xcconfig */, + BFF1E29957527A1293FE8C73FDDD9CA6 /* Frameworks */, + 6C369285569DAC5A13A7E6B9D065E1CB /* Support Files */, ); - name = "Support Files"; - path = "../Target Support Files/FirebaseABTesting"; + name = FirebaseABTesting; + path = FirebaseABTesting; sourceTree = ""; }; - 977A093AF726B4BF833EE50F08475894 /* FirebaseAnalytics */ = { + 96A98A38817F55D79ECD2E3A66821D5E /* Frameworks */ = { isa = PBXGroup; children = ( - 2D3DE2E31F2D872157EF8F212CC1F859 /* Frameworks */, - D6F9F0A033F70BF7194FED50E176BC5E /* Support Files */, + AC6D6A725BC22F15370F6E9C5FACFD65 /* GoogleSignIn.framework */, ); - name = FirebaseAnalytics; - path = FirebaseAnalytics; + name = Frameworks; sourceTree = ""; }; 978A77403A618F05BC9F837A4E912CBC /* UIUtils */ = { @@ -4560,23 +5796,33 @@ path = React/UIUtils; sourceTree = ""; }; - 98E4CB163CB27B892D511558099E86E2 /* DebugUtils */ = { + 9852C04837898D0D75E990E9251A1486 /* Frameworks */ = { isa = PBXGroup; children = ( - 8C5D15A4DAED2F19F5A7B895AB07A872 /* GTMDebugSelectorValidation.h */, - 520AAB5C69DF55FB372E2356B9E73273 /* GTMDebugThreadValidation.h */, - 7CE3268860304C5F99F52C2E4444CCB1 /* GTMMethodCheck.h */, + 5882233FCBBC4D6397255B41D78352EF /* FirebasePerformance.framework */, ); - name = DebugUtils; + name = Frameworks; sourceTree = ""; }; - A05337A0E503B47839C670498D29ED20 /* Support Files */ = { + 9D2E1F39AEDE51176E26215F3F1F0D42 /* Logger */ = { isa = PBXGroup; children = ( - 4E464D9BB99F9154986CD67B87B39582 /* GoogleAppMeasurement.xcconfig */, + 75B640AB094C5A3B26E85EC575DAF7F8 /* GULLogger.h */, + 0FA1DA480D16C4A256F4422152880539 /* GULLogger.m */, + BFE57F24EAB84A4526072597675704F6 /* GULLoggerLevel.h */, + ); + name = Logger; + sourceTree = ""; + }; + 9EE8BCFE7DC9D8F2601585EA9605806B /* Support Files */ = { + isa = PBXGroup; + children = ( + BA58397C32C68A5294911C70B2608DD8 /* GoogleToolboxForMac.xcconfig */, + F5529B22BE63AF18AE6DB17C4A3157CD /* GoogleToolboxForMac-dummy.m */, + C7D3A3C62ABB5D05A88CE06DEBC05EC1 /* GoogleToolboxForMac-prefix.pch */, ); name = "Support Files"; - path = "../Target Support Files/GoogleAppMeasurement"; + path = "../Target Support Files/GoogleToolboxForMac"; sourceTree = ""; }; A0BA08FDA71A4AED6148FBCDADA15B85 /* Pod */ = { @@ -4658,6 +5904,14 @@ path = React/Modules; sourceTree = ""; }; + A2112E575AE2EE3E14261FF8A02CF2CB /* Frameworks */ = { + isa = PBXGroup; + children = ( + 3F21A75ECC7FA892F2FDD35E53B8B217 /* FirebaseInstanceID.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; A484AF3FB52120EAA636694823965B0E /* Support Files */ = { isa = PBXGroup; children = ( @@ -4669,6 +5923,15 @@ path = "../../../../ios/Pods/Target Support Files/yoga"; sourceTree = ""; }; + A529596F46E2C5060BDFB8C54D8059F9 /* Environment */ = { + isa = PBXGroup; + children = ( + 7778BE85B353DF2729DA7024BA6B45DD /* GULAppEnvironmentUtil.h */, + 37F2C52AF05B020D5CD6CC5800BF1E2D /* GULAppEnvironmentUtil.m */, + ); + name = Environment; + sourceTree = ""; + }; A55C423E4B6E038BB8987A45480C1234 /* Support Files */ = { isa = PBXGroup; children = ( @@ -4680,22 +5943,14 @@ path = "../../ios/Pods/Target Support Files/React"; sourceTree = ""; }; - A8B796D722873477DD99C9B694941CC3 /* nanopb */ = { + A6853D8398FDDC5721606E3C13616ACE /* Support Files */ = { isa = PBXGroup; children = ( - 8A003652CC3D84C54C2C705D53E16081 /* pb.h */, - 71A375F95732A94E9172EF330D55C0CA /* pb_common.c */, - 3AD64AEC8F88EDF0FBA67499A8E1BAC3 /* pb_common.h */, - 212FB97DDEAF6BEAFED5E4B7EFBDBA01 /* pb_decode.c */, - 7C03D23A538969ECF4FE84795F3C2BB5 /* pb_decode.h */, - F60E4721AAEABB1566B683C2D1B0A722 /* pb_encode.c */, - 2B08F7E25D12EB4A87A9121CACBA86AD /* pb_encode.h */, - D02058706DA406760A76EAE5C4DA6D47 /* decode */, - E600215E3DED18A62A7195781C893997 /* encode */, - 6967585AF965AC0D039D4D00C910310B /* Support Files */, + 8F3AC0B3CF021ABD39D948CB83367A32 /* FirebaseMessaging.xcconfig */, + 85AB9F4C2E8E73E002AE9713A5F0578C /* FirebaseMessaging-dummy.m */, ); - name = nanopb; - path = nanopb; + name = "Support Files"; + path = "../Target Support Files/FirebaseMessaging"; sourceTree = ""; }; A8F07435ABB5731FC4E56D0B1E8752BA /* Pod */ = { @@ -4736,31 +5991,13 @@ path = "lottie-ios/Classes/MacCompatibility"; sourceTree = ""; }; - AA04F4062275680DE44996B22057B6AC /* FirebasePerformance */ = { - isa = PBXGroup; - children = ( - BB68F3758CC8BCFBB9709F21E9602A22 /* Frameworks */, - 07BD9D3E16EA7A5E7552EFBCA41F7B0F /* Support Files */, - ); - name = FirebasePerformance; - path = FirebasePerformance; - sourceTree = ""; - }; - AA9A5653B28BBDBEC49C9A95DD06A896 /* Network */ = { + AA134835A3CB89CDD516D648F8B43478 /* UserDefaults */ = { isa = PBXGroup; children = ( - C164FB1950C97D321BAD71E7B09EFAE2 /* GULMutableDictionary.h */, - 8C9444A5C15DCECB1B9B6C8CCE7F58A9 /* GULMutableDictionary.m */, - 350524E76529714B8516ED0B3AB7635C /* GULNetwork.h */, - 5C17428E231BAEA6AA8DA7844DA8C227 /* GULNetwork.m */, - 63BB3BF433240BBBB17DF7E23D9EB8A8 /* GULNetworkConstants.h */, - 81E6CEE364947BFEFBB66A11AEEEC135 /* GULNetworkConstants.m */, - F8E794EB8B9462A8721D684AECC475EF /* GULNetworkLoggerProtocol.h */, - FE918890A9495185DB1DF01F4612855C /* GULNetworkMessageCode.h */, - DB968FBE67FB3F234237A2BBB1574133 /* GULNetworkURLSession.h */, - 82A67AD1F41497CDE05BE0D941580CEF /* GULNetworkURLSession.m */, + F2E40AA55A9ECB3776EB7ADA99968947 /* GULUserDefaults.h */, + EFA1763DB7C1831455E270524CADA3B2 /* GULUserDefaults.m */, ); - name = Network; + name = UserDefaults; sourceTree = ""; }; AB1B5380CAC8EF28AD8B143607FD2625 /* Views */ = { @@ -4876,15 +6113,6 @@ path = AnimatorNodes; sourceTree = ""; }; - ACB3E082093C5068E1B83456E26F3837 /* Support Files */ = { - isa = PBXGroup; - children = ( - 6C28D2538D83FB8724D1397DF54FAEB9 /* FirebaseInstanceID.xcconfig */, - ); - name = "Support Files"; - path = "../Target Support Files/FirebaseInstanceID"; - sourceTree = ""; - }; ADFF89B81531CC930D56832F6971B603 /* Support Files */ = { isa = PBXGroup; children = ( @@ -4896,31 +6124,37 @@ path = "../../../ios/Pods/Target Support Files/RNCAsyncStorage"; sourceTree = ""; }; - AE6A1CCB7482B50F0449825C17E1517C /* Pods */ = { - isa = PBXGroup; - children = ( - EA6CFAF7BB7BD19090F8C5995E11C8A2 /* boost-for-react-native */, - 44DE2F80960376614C6B1B6F9745696E /* Crashlytics */, - 1E43D88086FB5F49EBAB5BAD779E8351 /* DoubleConversion */, - 7A0BCBCC68920681E4558ED2EBF0D456 /* Fabric */, - FF2DE9067FA7667E745C623BFCC2B4B8 /* Firebase */, - 62D76B19092EB46004120C788C319DE6 /* FirebaseABTesting */, - 977A093AF726B4BF833EE50F08475894 /* FirebaseAnalytics */, - 83CBFE6ACCCFE16D36E9DAD78813CAB5 /* FirebaseCore */, - B31EA5935E38806A74EB4A4EADAE9477 /* FirebaseInstanceID */, - AA04F4062275680DE44996B22057B6AC /* FirebasePerformance */, - 1A36BBB7E70230CCE89FF04B18A6D304 /* FirebaseRemoteConfig */, - 21C6B6341BE38C47292B78BC6D116D13 /* Folly */, - E2C5771D3EBDEACB55A02FE132B64678 /* glog */, - DB180DE5DD5A98F9AB54E5DEC48C817D /* GoogleAppMeasurement */, - 09A41CE5363CD27F533B9DC58F244A4A /* GoogleSignIn */, - 06477A6CFAB5EF07B6CC8DBFB685D798 /* GoogleToolboxForMac */, - BB5F6C1A5B619570B6AE47474A780401 /* GoogleUtilities */, - 2FF2B9103B5FF92F6CF5340AC1EB2D3A /* GTMSessionFetcher */, - A8B796D722873477DD99C9B694941CC3 /* nanopb */, - 4BB29917B6D82CF0463A51C548211AB3 /* Protobuf */, + AE32582820779A4ECAD915FC40AE90B1 /* Products */ = { + isa = PBXGroup; + children = ( + F0CBB45A9EF73E2FA4E38AE32898F09A /* libBVLinearGradient.a */, + CFA246E02267A79CF043A0C5D335BDFD /* libDoubleConversion.a */, + 806638551525BD116E464D867CA63D1B /* libFirebaseCore.a */, + 56E453AAAE1E2456E2004FDD594E41AA /* libFirebaseDatabase.a */, + 0F678C71FCC584F339C700EF781734C9 /* libFirebaseMessaging.a */, + EAF0CF08241A3BDE4435A323BE22EE7A /* libFolly.a */, + CFE63D481FB99B0508A809E105EAD9F3 /* libglog.a */, + 473DDD131AFF23C0382BA90B4DF19C03 /* libGoogleToolboxForMac.a */, + D86222299A69AD5898E1DD96FD18847F /* libGoogleUtilities.a */, + 53D3D878BD14E11D645D0C2EBBDEABCD /* libGTMSessionFetcher.a */, + 98914BC1DAECE76E6A8DAEEE16262925 /* libleveldb-library.a */, + A440D20566AE68C23C77B6587694AFA4 /* liblottie-ios.a */, + 66A32C509A3E748E0848AB62683135DB /* liblottie-react-native.a */, + 57BD04B505CC2C942D300E2F298F08D4 /* libnanopb.a */, + 50AC883EF355F48FFDB198F26BF0DEB5 /* libPods-Kalend.a */, + 04050B383E0D612ACABF04B122699C1B /* libPods-KalendTests.a */, + 2156A0B7B819CB97B539B49BE9C60221 /* libProtobuf.a */, + 46A977D12AD3E74855601EDFF339278D /* libReact.a */, + 8E702FAD5F5F374D2FC13FE47219A91C /* libreact-native-camera.a */, + F8D489213322E442845543761017E348 /* libreact-native-safari-view.a */, + B2D2639C87FF020213A738A3AB5154DA /* libreact-native-slider.a */, + 4EC7FACEF78343F1D452E765198F75FB /* librn-fetch-blob.a */, + A1EC205FD86D69A4FA55F7CCCB1DBE80 /* libRNCAsyncStorage.a */, + 6EF580D9928337F521B007EC45FC1F8C /* libRNGestureHandler.a */, + 22C6EE7C568060C47D4DD01B6A1DAA41 /* libRNVectorIcons.a */, + A9A13C7FD650007FE0BC0CE9DAC2D0FE /* libyoga.a */, ); - name = Pods; + name = Products; sourceTree = ""; }; AEBE3C8681F8B5063EEFC2A5B9F21485 /* Core */ = { @@ -4935,6 +6169,15 @@ name = Core; sourceTree = ""; }; + AEF92C9E3385219E8914EA323CA5AD3B /* Support Files */ = { + isa = PBXGroup; + children = ( + 5147DF55EFD9DDF7091D87DF9F9E8D37 /* FirebaseAnalyticsInterop.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/FirebaseAnalyticsInterop"; + sourceTree = ""; + }; B064C172ED1610DE453507D4A4177E33 /* RCT */ = { isa = PBXGroup; children = ( @@ -4951,6 +6194,16 @@ name = RCT; sourceTree = ""; }; + B26EAB57A6DD4DA953AD4CB9D5BEC734 /* GTMSessionFetcher */ = { + isa = PBXGroup; + children = ( + 5F57C61A2A2CB384063FB4F4B3D71891 /* Core */, + 6EE5C0A93377A8B527B3CFFCD22E42EB /* Support Files */, + ); + name = GTMSessionFetcher; + path = GTMSessionFetcher; + sourceTree = ""; + }; B2D1083223B073F75C5074C5E5B2B7BE /* Development Pods */ = { isa = PBXGroup; children = ( @@ -4970,50 +6223,33 @@ name = "Development Pods"; sourceTree = ""; }; - B31EA5935E38806A74EB4A4EADAE9477 /* FirebaseInstanceID */ = { - isa = PBXGroup; - children = ( - C7582B1F4334FC97C083BD63E4B08BED /* Frameworks */, - ACB3E082093C5068E1B83456E26F3837 /* Support Files */, - ); - name = FirebaseInstanceID; - path = FirebaseInstanceID; - sourceTree = ""; - }; - B9F41E9C5A41E232604491FD44BE5F45 /* Pod */ = { + B2FD2B8ACAB3FB395E4FE078D8EBBE69 /* Support Files */ = { isa = PBXGroup; children = ( - 188CD2DDBDAAEEAF4AA4BD6C44D93F14 /* LICENSE */, - 2C0E9614BB5103F441C0E525709EAB49 /* README.md */, - 7B1E90D7919ACCA063D2E90BEE8C5DED /* RNCAsyncStorage.podspec */, + 5BD9EEEB632240CE8400657E09078FAA /* FirebaseAuthInterop.xcconfig */, ); - name = Pod; + name = "Support Files"; + path = "../Target Support Files/FirebaseAuthInterop"; sourceTree = ""; }; - BB5F6C1A5B619570B6AE47474A780401 /* GoogleUtilities */ = { + B49542B498A06DB2EDF8EE88BC589009 /* Support Files */ = { isa = PBXGroup; children = ( - F6B50A93D030BD0496B509C8E3586FDA /* AppDelegateSwizzler */, - 1A75F25B796D7CB10819692CD5467EF9 /* Environment */, - 1A347C92C3B4E5038AD6FCB73A777617 /* ISASwizzler */, - 88B8BABCF300520C62698EC1DF73CFAC /* Logger */, - 73404971D1F0F5EDF17D39DFBFDA918C /* MethodSwizzler */, - AA9A5653B28BBDBEC49C9A95DD06A896 /* Network */, - 10B58B83C820EF9BFB7342BF63AA1161 /* NSData+zlib */, - 77A2A0A58F95DAB36C7AECC7574CE50A /* Reachability */, - CA0C386B816D91869DCB58ACB91E3C03 /* Support Files */, - CA741C53F444718340DFAC56D5739B78 /* UserDefaults */, + 4D161E1BA70F18F152790A436071D295 /* FirebaseCore.xcconfig */, + 9274C252BFD539E5FDC69265C7A79A67 /* FirebaseCore-dummy.m */, ); - name = GoogleUtilities; - path = GoogleUtilities; + name = "Support Files"; + path = "../Target Support Files/FirebaseCore"; sourceTree = ""; }; - BB68F3758CC8BCFBB9709F21E9602A22 /* Frameworks */ = { + B9F41E9C5A41E232604491FD44BE5F45 /* Pod */ = { isa = PBXGroup; children = ( - 535DE5CEB6FC286766550112D04D82EC /* FirebasePerformance.framework */, + 188CD2DDBDAAEEAF4AA4BD6C44D93F14 /* LICENSE */, + 2C0E9614BB5103F441C0E525709EAB49 /* README.md */, + 7B1E90D7919ACCA063D2E90BEE8C5DED /* RNCAsyncStorage.podspec */, ); - name = Frameworks; + name = Pod; sourceTree = ""; }; BD3F36B9F4554E80A95FAF8227ABB6BA /* Targets Support Files */ = { @@ -5039,6 +6275,25 @@ path = Multiline; sourceTree = ""; }; + BE6837C16C835DE5A245DC1C5F808C26 /* Support Files */ = { + isa = PBXGroup; + children = ( + 8C4A852050AF22C0F63D82C6E289AC36 /* Folly.xcconfig */, + 49074C2E5E4EA6ED6EB392FB200135AE /* Folly-dummy.m */, + B1C82826976D3CFD04CA34287A43BC42 /* Folly-prefix.pch */, + ); + name = "Support Files"; + path = "../Target Support Files/Folly"; + sourceTree = ""; + }; + BFF1E29957527A1293FE8C73FDDD9CA6 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 9E5F13FAEEFB31F2BE8766AFA672C020 /* FirebaseABTesting.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; C002E8C9449BD4511C2F9FDC4CF2D96D /* react-native-safari-view */ = { isa = PBXGroup; children = ( @@ -5051,6 +6306,40 @@ path = "../../node_modules/react-native-safari-view"; sourceTree = ""; }; + C10C30EEA6929E33052D5D091F30489A /* GoogleToolboxForMac */ = { + isa = PBXGroup; + children = ( + 70950A081D7170EDF494AE7378F31F34 /* DebugUtils */, + C4F20AEEF0A98442CFF21496ADF8390A /* Defines */, + 39D32C7C9A2B5456974A42AEEBD9F440 /* Logger */, + 049487709C127577B245F6815F39F962 /* NSData+zlib */, + 2D7C1931165E91D50259F37EC8299E52 /* NSDictionary+URLArguments */, + C1BFDAC4EA6D29456B02D58E2C431B0B /* NSString+URLArguments */, + 9EE8BCFE7DC9D8F2601585EA9605806B /* Support Files */, + ); + name = GoogleToolboxForMac; + path = GoogleToolboxForMac; + sourceTree = ""; + }; + C133CA569680BBE9A31833EB690CD1A6 /* Support Files */ = { + isa = PBXGroup; + children = ( + BA20E7E90F36B7CFF0BDC2A7B376EED9 /* FirebaseDatabase.xcconfig */, + 4589D5B88D4AE0FE6E7B2DB709F25865 /* FirebaseDatabase-dummy.m */, + ); + name = "Support Files"; + path = "../Target Support Files/FirebaseDatabase"; + sourceTree = ""; + }; + C1BFDAC4EA6D29456B02D58E2C431B0B /* NSString+URLArguments */ = { + isa = PBXGroup; + children = ( + E78736EF22E1BD2BBBA9FC6AA32A8EA0 /* GTMNSString+URLArguments.h */, + 3580EB0D6BC1342D553F04112A5AED34 /* GTMNSString+URLArguments.m */, + ); + name = "NSString+URLArguments"; + sourceTree = ""; + }; C32128EB3DF58940954B2143FAC3EFF6 /* ART */ = { isa = PBXGroup; children = ( @@ -5077,17 +6366,6 @@ name = ART; sourceTree = ""; }; - C3B286438F3E4ECA3F7F6F6EA828678C /* Support Files */ = { - isa = PBXGroup; - children = ( - 39F9AFCFBFF9F81F427E737A4D3DFAE2 /* glog.xcconfig */, - E4D149BAE01097E99370276CD05701C2 /* glog-dummy.m */, - 98B477F61D2BA25FC56F9919E3D0F0A9 /* glog-prefix.pch */, - ); - name = "Support Files"; - path = "../Target Support Files/glog"; - sourceTree = ""; - }; C41DAD329116851BF003D5CB3D7C0ABD /* VirtualText */ = { isa = PBXGroup; children = ( @@ -5100,6 +6378,32 @@ path = Libraries/Text/VirtualText; sourceTree = ""; }; + C4615624561F4E4A6BFE018C37521F58 /* GoogleAppMeasurement */ = { + isa = PBXGroup; + children = ( + C5C83617C3BD671A3F130BFF7871CD5E /* Frameworks */, + 3560D9B3FD533A2E87854E1D49278FC8 /* Support Files */, + ); + name = GoogleAppMeasurement; + path = GoogleAppMeasurement; + sourceTree = ""; + }; + C4F20AEEF0A98442CFF21496ADF8390A /* Defines */ = { + isa = PBXGroup; + children = ( + 43FAF91300BB0C423267A829E54A3897 /* GTMDefines.h */, + ); + name = Defines; + sourceTree = ""; + }; + C5C83617C3BD671A3F130BFF7871CD5E /* Frameworks */ = { + isa = PBXGroup; + children = ( + 8F46D2A286B809B9242F0DBE0D362017 /* GoogleAppMeasurement.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; C626C28754E353ABC7402D162B200580 /* CxxModule */ = { isa = PBXGroup; children = ( @@ -5127,14 +6431,6 @@ name = Pod; sourceTree = ""; }; - C7582B1F4334FC97C083BD63E4B08BED /* Frameworks */ = { - isa = PBXGroup; - children = ( - 28D497C6002C97A230F3D31493013279 /* FirebaseInstanceID.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; C97D7D18E6FA9C716D1E7D7E4D6C2E62 /* Support Files */ = { isa = PBXGroup; children = ( @@ -5146,54 +6442,32 @@ path = "../../ios/Pods/Target Support Files/RNVectorIcons"; sourceTree = ""; }; - CA0C386B816D91869DCB58ACB91E3C03 /* Support Files */ = { + CF1408CF629C7361332E53B88F7BD30C = { isa = PBXGroup; children = ( - DE76DB9FA2EBA46167E0E55714379F0E /* GoogleUtilities.xcconfig */, - 1C3262CA3724AF3763EAB28F74C4341B /* GoogleUtilities-dummy.m */, - 674074D8450092A34E1538055F096B0D /* GoogleUtilities-prefix.pch */, + 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, + B2D1083223B073F75C5074C5E5B2B7BE /* Development Pods */, + D89477F20FB1DE18A04690586D7808C4 /* Frameworks */, + DB8367266C1ACC8C7CAC16C5395D9C35 /* Pods */, + AE32582820779A4ECAD915FC40AE90B1 /* Products */, + BD3F36B9F4554E80A95FAF8227ABB6BA /* Targets Support Files */, ); - name = "Support Files"; - path = "../Target Support Files/GoogleUtilities"; sourceTree = ""; }; - CA741C53F444718340DFAC56D5739B78 /* UserDefaults */ = { + CFB503A6ECDC80B24E7BB9C8CCDAE2DD /* FirebaseAnalyticsInterop */ = { isa = PBXGroup; children = ( - F16040E0616BC0C5392F632DE49C3BEA /* GULUserDefaults.h */, - 566DAFF42528D1D6FCEBD3246015F7CE /* GULUserDefaults.m */, + 8685293563920AD67BBFD02921A36356 /* FIRAnalyticsInterop.h */, + 0E40F0916CDD2AD6370BED49A5AD407E /* FIRAnalyticsInteropListener.h */, + 89130677F74BC1967BBAD867534292CA /* FIRInteropEventNames.h */, + C38E4C6C9CCA165F1A58CB3B9280E33F /* FIRInteropParameterNames.h */, + AEF92C9E3385219E8914EA323CA5AD3B /* Support Files */, ); - name = UserDefaults; + name = FirebaseAnalyticsInterop; + path = FirebaseAnalyticsInterop; sourceTree = ""; }; - CF1408CF629C7361332E53B88F7BD30C = { - isa = PBXGroup; - children = ( - 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, - B2D1083223B073F75C5074C5E5B2B7BE /* Development Pods */, - D89477F20FB1DE18A04690586D7808C4 /* Frameworks */, - AE6A1CCB7482B50F0449825C17E1517C /* Pods */, - E8911370D22C3BCD0D9ECD83A1475C8E /* Products */, - BD3F36B9F4554E80A95FAF8227ABB6BA /* Targets Support Files */, - ); - sourceTree = ""; - }; - D02058706DA406760A76EAE5C4DA6D47 /* decode */ = { - isa = PBXGroup; - children = ( - ); - name = decode; - sourceTree = ""; - }; - D0D9E26D144F941EBB8CB2B40E0C9935 /* Resources */ = { - isa = PBXGroup; - children = ( - 49CA8FF288BF1DD519D78B70E988EC17 /* GoogleSignIn.bundle */, - ); - name = Resources; - sourceTree = ""; - }; - D22EED22C3DCFBD2CA824BDED56BE57F /* Models */ = { + D22EED22C3DCFBD2CA824BDED56BE57F /* Models */ = { isa = PBXGroup; children = ( BAA66F78FD1BB2023BC7506B6B680E6E /* LOTAsset.h */, @@ -5266,15 +6540,6 @@ name = CxxBridge; sourceTree = ""; }; - D6F9F0A033F70BF7194FED50E176BC5E /* Support Files */ = { - isa = PBXGroup; - children = ( - D9688E70781B95F50FAD1F88E039C2BF /* FirebaseAnalytics.xcconfig */, - ); - name = "Support Files"; - path = "../Target Support Files/FirebaseAnalytics"; - sourceTree = ""; - }; D7377B1BA14F1579EB4DD6BA872D1E75 /* react-native-slider */ = { isa = PBXGroup; children = ( @@ -5289,17 +6554,6 @@ path = "../../node_modules/@react-native-community/slider"; sourceTree = ""; }; - D79E835CDA9B31B584D471309760C1F4 /* Support Files */ = { - isa = PBXGroup; - children = ( - B940312F1597EF5B430898726144532D /* GTMSessionFetcher.xcconfig */, - CC2547E3827FA29B4BE7F24C6C7129CF /* GTMSessionFetcher-dummy.m */, - D58D2936FA8A367615DAB1A583B88323 /* GTMSessionFetcher-prefix.pch */, - ); - name = "Support Files"; - path = "../Target Support Files/GTMSessionFetcher"; - sourceTree = ""; - }; D89477F20FB1DE18A04690586D7808C4 /* Frameworks */ = { isa = PBXGroup; children = ( @@ -5337,14 +6591,45 @@ path = Libraries/Text/TextInput; sourceTree = ""; }; - DB180DE5DD5A98F9AB54E5DEC48C817D /* GoogleAppMeasurement */ = { + DB8367266C1ACC8C7CAC16C5395D9C35 /* Pods */ = { + isa = PBXGroup; + children = ( + 536AAB4CB04B9AE19CC283D9EA172604 /* boost-for-react-native */, + 8DE3D15655EBE8968E6616A8B3E8819E /* Crashlytics */, + 4E8CD56C55A5B44742EFAD311C8936F8 /* DoubleConversion */, + 7E0B7EBF09C4B3A6E4F89A7FC53E0669 /* Fabric */, + EDDB50A9AAA22A25725BEC4E90182385 /* Firebase */, + 956AECC74E2AD54E6735BBE7638E9D0F /* FirebaseABTesting */, + FDE871B07A3312C1BF928F52F909D44B /* FirebaseAnalytics */, + CFB503A6ECDC80B24E7BB9C8CCDAE2DD /* FirebaseAnalyticsInterop */, + E523B201D46380C2CCA40C8BBFF02617 /* FirebaseAuthInterop */, + F1832899B1ADCACE1A18F44B7FBB6612 /* FirebaseCore */, + 2939FC1C4D0A41A594EFA485570583B1 /* FirebaseDatabase */, + 2D7F07D099FB37E7C40DCE511B316E2B /* FirebaseInstanceID */, + FE5AED7E48653E61726C73D710DA810F /* FirebaseMessaging */, + 9108661FC1BE030C92DEA31ECF196A4E /* FirebasePerformance */, + 4CCB825F5AC68CCDB43D1063715601C4 /* FirebaseRemoteConfig */, + EE0D4E7EBEF1CBF0AF3143FD9AAE3C8D /* Folly */, + 470DAC2834F86DFE321D8E93672ACE17 /* glog */, + C4615624561F4E4A6BFE018C37521F58 /* GoogleAppMeasurement */, + 749DA3BAB7B54AB06C9E76DBAA96A3B0 /* GoogleSignIn */, + C10C30EEA6929E33052D5D091F30489A /* GoogleToolboxForMac */, + 700D93D1B73A10C5E879FF5F567D1FC9 /* GoogleUtilities */, + B26EAB57A6DD4DA953AD4CB9D5BEC734 /* GTMSessionFetcher */, + E46CD62C18406671C4FD80DCCA203599 /* leveldb-library */, + F38B2603D3F5222AD09EAC578D251E04 /* nanopb */, + 14BC085A5F27FE5700E6348158AF34B3 /* Protobuf */, + ); + name = Pods; + sourceTree = ""; + }; + DE5BC9EA66EB10A2040F267FC1F5B036 /* Support Files */ = { isa = PBXGroup; children = ( - 122625E3B7A2EC379C5005686C02784F /* Frameworks */, - A05337A0E503B47839C670498D29ED20 /* Support Files */, + B48DB19E655254729291192628C71D52 /* Crashlytics.xcconfig */, ); - name = GoogleAppMeasurement; - path = GoogleAppMeasurement; + name = "Support Files"; + path = "../Target Support Files/Crashlytics"; sourceTree = ""; }; DF3EC367E06407ED1CAF961834325783 /* CxxBridge */ = { @@ -5365,27 +6650,6 @@ path = React/CxxBridge; sourceTree = ""; }; - E2C5771D3EBDEACB55A02FE132B64678 /* glog */ = { - isa = PBXGroup; - children = ( - 52532E69A2044DDD180BABF354EE7E65 /* demangle.cc */, - 907520142BCBA284CCB871DD47D9B4CB /* log_severity.h */, - 46B7B4C6643F5C8189C5AA84D4591DA3 /* logging.cc */, - 74CEE568726ABC9EC073632676A4C3BF /* logging.h */, - AD5955431A3FCFA7048680B4C25EF64C /* raw_logging.cc */, - CCABEE37C670ACA6EC2203CB15D5088B /* raw_logging.h */, - 013E70C5F49F92AA2533BE9D5B83A65D /* signalhandler.cc */, - 855A4A4D0254750282F9818524C8A400 /* stl_logging.h */, - F434B45DD59F2A9E58327AF6CD3196C2 /* symbolize.cc */, - B1681002ADBD3BB27EBF6CCCBB750356 /* utilities.cc */, - A52DFF00A66DC596AE662E6482F17420 /* vlog_is_on.cc */, - D9878295E9DBE9E1A357C2B8CE1C958F /* vlog_is_on.h */, - C3B286438F3E4ECA3F7F6F6EA828678C /* Support Files */, - ); - name = glog; - path = glog; - sourceTree = ""; - }; E42609A0D4D69F9FD60B1E73E82CF0EA /* Pod */ = { isa = PBXGroup; children = ( @@ -5396,22 +6660,134 @@ name = Pod; sourceTree = ""; }; - E600215E3DED18A62A7195781C893997 /* encode */ = { + E46CD62C18406671C4FD80DCCA203599 /* leveldb-library */ = { + isa = PBXGroup; + children = ( + 5E69820A04F974F3CFFCCB3091ACA698 /* arena.cc */, + 0B0C51FA037711B40BF921BC4F2075A4 /* arena.h */, + D1DA3DDBB6E2F5BA2A56638520AD91BF /* atomic_pointer.h */, + 6FB03253561D95AC814D0898B86FC6C8 /* block.cc */, + 8AB83D79B3A65995AB528E4FB67F4DD8 /* block.h */, + EC7538EECB1B622475352EA2C29CE32D /* block_builder.cc */, + 7D55D1B1A1EEFE3C9DA51ADCBC1D2B96 /* block_builder.h */, + 8C1B90E0F2D381FFF1B123D4F5376D25 /* bloom.cc */, + 622CE1787B15B5BF9B8E6D7C32EE1F60 /* builder.cc */, + 295F4B225E8825FB9DDBD005632C9CCF /* builder.h */, + E59970476AE1C8FA38C8E3A183F30980 /* c.cc */, + B091C318F79526158445BD1BEA70EE1D /* c.h */, + 783DA6DADA45F2B359DE949E9CF607F0 /* cache.cc */, + F39C03C8E9840CA54648E59EB7400EFF /* cache.h */, + 0F85A824A43BC24616CE7831CCFD7D77 /* coding.cc */, + 75C2BF4E24C1C4A8516CD1D3AE267D4B /* coding.h */, + ACDA9668469FE07E1CDC60A09A2E0022 /* comparator.cc */, + C6F941B784ADFAD4519A40D1636044D9 /* comparator.h */, + 2EA3F99C1D3B4AF30B88B8BD22D2D7C3 /* crc32c.cc */, + B5B93839F37E7D38E19CAD266E896292 /* crc32c.h */, + 712333C1507824756FE2CF1F681ACB7E /* db.h */, + F35A0211C71E14D30E9960DD0297256D /* db_impl.cc */, + 2B9028452AA9A0B051DDEE4F315AE9DF /* db_impl.h */, + D26ED6213ECE3731B5B8B7236F7FE8FF /* db_iter.cc */, + 3E009D4735C805CED8A49BDC00DA9679 /* db_iter.h */, + 3F5F074174924D93C197546B8037001E /* dbformat.cc */, + 3324B1E18650F1EA8A0408F7CE1B3B04 /* dbformat.h */, + 791909236376A7AC032230DCDD821695 /* dumpfile.cc */, + 96B9292A43AC1761995175652F0BC87F /* dumpfile.h */, + 3CCD6F717B705096084DE94D831AD5DC /* env.cc */, + CAF9F96F1F05C6595393D5C96BCEAC85 /* env.h */, + 01EFAC98986CB6F1033BA70216B2A359 /* env_posix.cc */, + 30D6BEA3A2C59F3B59B748B9C5DA5AF1 /* env_posix_test_helper.h */, + 1D0FE567498F874EDCA9397BB8942691 /* filename.cc */, + 1EC0957443FA3D8BFC4DA9600F70F905 /* filename.h */, + 40799FECEBD3623D6C8B1C70ED1823BA /* filter_block.cc */, + 5C8C8EAA66B9A8936B5CB402688314A6 /* filter_block.h */, + 27B78908479033CE1848EB5E0A3FCB7E /* filter_policy.cc */, + 551F72DF002E8D67C63ED1DE0140ACC9 /* filter_policy.h */, + A0AE80D03F26B3B90DB417809B76E098 /* format.cc */, + 3535EA46EDD3D96558DC4A1026C4DE0F /* format.h */, + 6B79CE92D4AF98478243B547ADFD51D0 /* hash.cc */, + 1DB773AEC4E2516504AB580F796DF2E2 /* hash.h */, + 9AAC04F3C3C444DC723AADB405F3C67C /* histogram.cc */, + 0933D47EBA37DBA669BB91D37332294A /* histogram.h */, + BBE854992F5608033BEF94135B5A8FC2 /* iterator.cc */, + D73F4F4A7162578699829D8BFEDACF6B /* iterator.h */, + 3F40208B1F0DC24CAF70925FE733EE42 /* iterator_wrapper.h */, + 39F99C7DB7E3135595E3B4FA528D8CCF /* log_format.h */, + 1D8034D5DC09757CBF6C88BCE84C81B3 /* log_reader.cc */, + 6442B918CC9418758CF784503DBAB162 /* log_reader.h */, + 9A5D125A926C9A0A1A3FB1982E721273 /* log_writer.cc */, + F83F0FC48D1A44FFA4748EF0FB17C65F /* log_writer.h */, + D6BD0DC337189DAD217C1ECB7620C8AD /* logging.cc */, + 2AD9246D1D4092E3286681D4F885BC9D /* logging.h */, + 3F2F365D934F6305BB1F840BA46B96D5 /* memtable.cc */, + 2581AA780F218D5AAF0D6EA495651CA5 /* memtable.h */, + 9C76269F60F7AC52CC5655F057186C7F /* merger.cc */, + 53DDAA6BA233D4B91F3EB8FD9014366D /* merger.h */, + 6F86652BE1E34EC9D11383F04A98C4FD /* mutexlock.h */, + 3CB542AB89073932BBB2EABF4DFD6836 /* options.cc */, + 42A113B02397B96427B9C3AFE74CB9BD /* options.h */, + 11F954B9E1906E4B03C7590C9A888D93 /* port.h */, + 829DE110A8990FA98FC7334454C7D389 /* port_example.h */, + 961544B462C97D32FB08BBB712F6753C /* port_posix.cc */, + 4D63F49AFC33302B0D509F2B6AC99EFD /* port_posix.h */, + 3B0E712AC4E399D821909DFA5AC02342 /* port_posix_sse.cc */, + 4B3BD5ABF14EA65C9DCE54CAD425A6F6 /* posix_logger.h */, + E39C79A0D5A0D5FF88250F805F77CB8E /* random.h */, + 7C72A21DB02B0FE24C7B1C441D3578B3 /* repair.cc */, + 61795D140D90B3C7C2D348BBCC2A1DCF /* skiplist.h */, + EACA4E5CB47C448ECE5F4211305C3437 /* slice.h */, + 47F15902BABCC392AE6231BBABBFE856 /* snapshot.h */, + 3B2C069F9D6B52B8EB4CD32898783208 /* status.cc */, + B5E89629B0CB240B5BA5202F26C219A7 /* status.h */, + D05298160C882B143B7DDF778A6A6B75 /* table.cc */, + 3CBE8B32C08136207C1ED4E64F1E7C30 /* table.h */, + 0ACE077C74B38A36472A73C30A541918 /* table_builder.cc */, + 18351BEBA491DA6D9CADDDC581F9CE07 /* table_builder.h */, + A844DA2D4F3B499538E16BED3E72F98C /* table_cache.cc */, + C194B9D7F5D0883EEE60232E87973E59 /* table_cache.h */, + 1EF8A973FA536E2E222B0BDFA64DF17E /* testharness.cc */, + 208205C1978010CC4D1CA1B7BD5F07C8 /* testharness.h */, + 2FF32C8A293A79D640DB5B9A70792DA8 /* testutil.cc */, + F60D66CC797623BFF95E4681FBA0CA3B /* testutil.h */, + 19330FC8B77327DE6F4BBF84783EB457 /* thread_annotations.h */, + 3236036995BCE087A642F3AEB2328A4B /* two_level_iterator.cc */, + 838388E76F01CCA24EB0680BAA345E6A /* two_level_iterator.h */, + 1C374ECE8D62BB7FABF1AF2C15A3663D /* version_edit.cc */, + DBD8498E7A02847611B117CB1EE855C6 /* version_edit.h */, + A382B5DEBE7AB4A099F71363217CE031 /* version_set.cc */, + 468E1DA4FDB85768910BD3669FBB8A51 /* version_set.h */, + 444573A933F954E270941208E387DEAE /* write_batch.cc */, + 1E28567DA629BA3B509E5A6F78CFA386 /* write_batch.h */, + 8F7A091B8C6E441AB1BFD5CC75E281F9 /* write_batch_internal.h */, + 2FBBA01BCEE7BF9E18C782F8CF95F2CE /* Support Files */, + ); + name = "leveldb-library"; + path = "leveldb-library"; + sourceTree = ""; + }; + E4EAFFF6828995E3D2AA50BFC3F54B5D /* encode */ = { isa = PBXGroup; children = ( ); name = encode; sourceTree = ""; }; - E6430C32A0C02CE2C10634E4D8B0FF64 /* Support Files */ = { + E4FC724836DC1C7CAD1DA6AD582E5C8A /* Support Files */ = { isa = PBXGroup; children = ( - 98E6F329E8D9AF00DCF3E33E60A44F60 /* GoogleToolboxForMac.xcconfig */, - 5F9F37A7C4E4098D92D5CC0D7020DAA2 /* GoogleToolboxForMac-dummy.m */, - 2FC12CDDA3884BD1F1A3DFCF56CFD70C /* GoogleToolboxForMac-prefix.pch */, + 9229E08D02A82F7A9C3D6ECA5DAE6D63 /* FirebaseRemoteConfig.xcconfig */, ); name = "Support Files"; - path = "../Target Support Files/GoogleToolboxForMac"; + path = "../Target Support Files/FirebaseRemoteConfig"; + sourceTree = ""; + }; + E523B201D46380C2CCA40C8BBFF02617 /* FirebaseAuthInterop */ = { + isa = PBXGroup; + children = ( + F0CCAEDCD7986152DEEA9EF1049C9034 /* FIRAuthInterop.h */, + B2FD2B8ACAB3FB395E4FE078D8EBBE69 /* Support Files */, + ); + name = FirebaseAuthInterop; + path = FirebaseAuthInterop; sourceTree = ""; }; E72B36A0F2FCA5568E286DE4F1270448 /* RN */ = { @@ -5439,45 +6815,34 @@ name = RN; sourceTree = ""; }; - E8911370D22C3BCD0D9ECD83A1475C8E /* Products */ = { - isa = PBXGroup; - children = ( - 8025EF7DC44740DD0CC6704D3A07623E /* libBVLinearGradient.a */, - FDDB7A507E51D22F70C1917483F1FF71 /* libDoubleConversion.a */, - AFFFC489744C1B215B7F1528408797BA /* libFirebaseCore.a */, - A58EC44B09EEA53BA369716C9DF9497F /* libFolly.a */, - 9DD45A1FEE98B97FA742D24D7BFFB9F7 /* libglog.a */, - 317D105DF47B8D3BA7ED9A9D6EFBC466 /* libGoogleToolboxForMac.a */, - 21D92EBF9C5C9D2E24D5EDC4ECD86EB3 /* libGoogleUtilities.a */, - 09701DDB31B473B0CDAF79AE545802F4 /* libGTMSessionFetcher.a */, - 23B37EAAEEE6C1F0DE71D561FB401651 /* liblottie-ios.a */, - 5016614A2295D4A10CD95448B0578C11 /* liblottie-react-native.a */, - 606DF439F68F15C4F56B9B3A5C083A7E /* libnanopb.a */, - 476BF08F77E75BD5FA8165A67387DFF1 /* libPods-Kalend.a */, - 30EC85B249403A7FDD744964E3B64C8D /* libPods-KalendTests.a */, - 88364B23619E73D4CD113CC0E8460578 /* libProtobuf.a */, - DB5B9375AA63B4948C38D7EFC02A0727 /* libReact.a */, - 5F5F4DDD9BFE4308D4946C6C56152D8D /* libreact-native-camera.a */, - C48F82AED30534365C1AFE10BA57DDD7 /* libreact-native-safari-view.a */, - 7E17028DBAA1E01FA284E0D1304048A7 /* libreact-native-slider.a */, - 4D058D7A841DF70FCA740AC480BBF35F /* librn-fetch-blob.a */, - 05BDA139C28772B6669FAA49F8C210EC /* libRNCAsyncStorage.a */, - 6A4D82D6621A33F2E46CCD53AADF6195 /* libRNGestureHandler.a */, - 9548E2A3E0F414AB329F84C569C84767 /* libRNVectorIcons.a */, - BC243429357134BED3601064EB41CDC2 /* libyoga.a */, + E7B78806BEDFD695D811E9D3DCC09DBF /* ISASwizzler */ = { + isa = PBXGroup; + children = ( + FB474C1F8E857DCA0F160460EFC9017D /* GULObjectSwizzler.h */, + 935E381EBEF80577BC49C958FCE8C692 /* GULObjectSwizzler.m */, + 27938245D9F59E1D8028A667866781E4 /* GULSwizzledObject.h */, + 582EC301F15AA66B4997BA389F1C7B4A /* GULSwizzledObject.m */, ); - name = Products; + name = ISASwizzler; sourceTree = ""; }; - E8B7BC35E6CDE0AF0B43923A66D90C81 /* Support Files */ = { + E874305A386E4B2B1AEE71217B571425 /* Support Files */ = { isa = PBXGroup; children = ( - 850627136AB58C8DA3E77E69C7A41DF4 /* Folly.xcconfig */, - 2410678D9F5CB5DC22FE50D7F0379F3A /* Folly-dummy.m */, - 75ACB369AE23EB126585E20EF8618DD7 /* Folly-prefix.pch */, + 91F21C81538226CD9A5DE14ECF25EBEE /* DoubleConversion.xcconfig */, + 059085B56857C3A23B738477A8506199 /* DoubleConversion-dummy.m */, + 3BD51FC68A9B78174E2EDEB72D9BE395 /* DoubleConversion-prefix.pch */, ); name = "Support Files"; - path = "../Target Support Files/Folly"; + path = "../Target Support Files/DoubleConversion"; + sourceTree = ""; + }; + E91BD7196B0C9A3F1F9449C1C678E57D /* Frameworks */ = { + isa = PBXGroup; + children = ( + AC776B24502D3481FED95A67A2A42097 /* FirebaseRemoteConfig.framework */, + ); + name = Frameworks; sourceTree = ""; }; E925D7C0D41BCC9739107D63697BEC29 /* lottie-react-native */ = { @@ -5494,24 +6859,13 @@ path = "../../node_modules/lottie-react-native"; sourceTree = ""; }; - E9562410DE4A48FCA85F99BB011CC4D9 /* Support Files */ = { - isa = PBXGroup; - children = ( - 156121052651E68677BF8522AC28928C /* DoubleConversion.xcconfig */, - 08283566C09AC0491587696FA9DBD268 /* DoubleConversion-dummy.m */, - 89AB621D96C9B51FB13A8A4BC09FF9E3 /* DoubleConversion-prefix.pch */, - ); - name = "Support Files"; - path = "../Target Support Files/DoubleConversion"; - sourceTree = ""; - }; - E9C95A53B1C11199DC74A894EC27CCF6 /* Support Files */ = { + E9A559B395422BBC798356F1B1D59538 /* Support Files */ = { isa = PBXGroup; children = ( - 9A776103D69455946E4E465A746DF256 /* Fabric.xcconfig */, + BC487B47C2B96C67BEA917671F02DB85 /* FirebaseAnalytics.xcconfig */, ); name = "Support Files"; - path = "../Target Support Files/Fabric"; + path = "../Target Support Files/FirebaseAnalytics"; sourceTree = ""; }; EA451829A225676B4CC82912CBE063F5 /* InterpolatorNodes */ = { @@ -5538,22 +6892,38 @@ path = InterpolatorNodes; sourceTree = ""; }; - EA6CFAF7BB7BD19090F8C5995E11C8A2 /* boost-for-react-native */ = { + EDDB50A9AAA22A25725BEC4E90182385 /* Firebase */ = { isa = PBXGroup; children = ( - 8F4FDAD3251F42F325985D437EDC5146 /* Support Files */, + 68E3989753DD74275266668F5F6574DD /* CoreOnly */, + 39D99F8E69EA7B3FAA8F989AECF383EB /* Support Files */, ); - name = "boost-for-react-native"; - path = "boost-for-react-native"; + name = Firebase; + path = Firebase; sourceTree = ""; }; - EA6EBAFC1136A5A6493EBC015E14644E /* Logger */ = { + EE0D4E7EBEF1CBF0AF3143FD9AAE3C8D /* Folly */ = { isa = PBXGroup; children = ( - EC84E3599BBB7DD06B11323C1785FE23 /* GTMLogger.h */, - CFBAB1A595B912E748E740EA7F52B3DA /* GTMLogger.m */, + C8C4EDEA0E251A3310090AF3E18556FC /* Assume.cpp */, + 7D686991C1E7EE358016B312E9B964B7 /* ColdClass.cpp */, + C1D869DCB8998E09EDF65B9054CD933B /* Conv.cpp */, + 3139F2E895812FCE53080ADF53B3B0D0 /* Demangle.cpp */, + 4C74E5ED86914ACF3E7DFB35010DE2D5 /* Demangle.cpp */, + 1DF01DAD811E57DC0E104624FC8E3958 /* dynamic.cpp */, + CC1DD9770508DA94C742ED0638E76E5F /* F14Table.cpp */, + B41F99C2DD0AA870E1DEAC36E815B58D /* Format.cpp */, + B2637FDEA1D9A58931B3F5B9C8B06F0F /* json.cpp */, + 59A6ED2700886866121E44BBA8816C68 /* json_pointer.cpp */, + 71F17B940ED7E61E4B3F0479A436376E /* MallocImpl.cpp */, + 5BF8B947CBDBE7B454CED67A04F0CC23 /* ScopeGuard.cpp */, + E192A7C87BD0F2CD1AABD4BF326F5AB2 /* SpookyHashV2.cpp */, + 1825D2BACAE0467CA2F215722962EBA2 /* String.cpp */, + F47C369C57996A13FC6CD8458BBE8B3E /* Unicode.cpp */, + BE6837C16C835DE5A245DC1C5F808C26 /* Support Files */, ); - name = Logger; + name = Folly; + path = Folly; sourceTree = ""; }; F11888B9AD2579C6C81D7A044E62CB9E /* RNGestureHandler */ = { @@ -5583,24 +6953,77 @@ path = "../../node_modules/react-native-gesture-handler"; sourceTree = ""; }; - F18DC7FBE29F14CB34ED9520F77E7973 /* NSDictionary+URLArguments */ = { + F1832899B1ADCACE1A18F44B7FBB6612 /* FirebaseCore */ = { + isa = PBXGroup; + children = ( + 8C595054FE1F0AB55132320069F45FD0 /* FIRAnalyticsConfiguration.h */, + 08491B7F2816397E75081103B09AACA0 /* FIRAnalyticsConfiguration.m */, + 8E316121E6C0066D9EEAC18DDB94300C /* FIRAnalyticsConfiguration+Internal.h */, + 7DC2D23C296C50404F997788F0820D30 /* FIRApp.h */, + 76D068BBF9B8EF1509782F606D5D2EF4 /* FIRApp.m */, + 6781CB7C70AB4EDC507A148480C7AD47 /* FIRAppAssociationRegistration.h */, + B8117D0312D0C6A5E6D959942D8477AB /* FIRAppAssociationRegistration.m */, + A0E18AA5B74FEBF3197D4099EE1AEA6E /* FIRAppInternal.h */, + B9ADE36B8790FDCE7F8382ADFE37F0AD /* FIRBundleUtil.h */, + 7701718429F3F21BDCC1DD3131B9B39F /* FIRBundleUtil.m */, + F0C80DE6854B8FBEA2554B18BE095780 /* FIRComponent.h */, + 69934098D004769DEF801CB253392E29 /* FIRComponent.m */, + 8E764F449658692454D522EA90DEDB37 /* FIRComponentContainer.h */, + 1447EEC6E44D953BB79924C9D18D6ADA /* FIRComponentContainer.m */, + 56DBBA3497A012C8AB33055D5DA559A8 /* FIRComponentContainerInternal.h */, + 4E8E3FA6B7209E08AAFA8F100C00089D /* FIRComponentRegistrant.h */, + C18794FB4491915FA833B66DE05948DF /* FIRComponentType.h */, + 0356BDAEC5808155DFE77028C5997175 /* FIRComponentType.m */, + D4C24610BD75A9F8F6DA40D2196CD758 /* FIRConfiguration.h */, + 8225C2C04620F9942D7441424A5CBBDB /* FIRConfiguration.m */, + B3B50DE72F5CD916F93A5496C7473931 /* FIRCoreConfigurable.h */, + 8A8A1B99D1D6D8DE0C6ADD1FF71CB5FA /* FIRDependency.h */, + 87BF0D472913B05794F194F52D37FBE3 /* FIRDependency.m */, + 818CA10F0216169E08402403FE90A012 /* FirebaseCore.h */, + 4D5A958ACB4439FA215BE021AE20B0D3 /* FIRErrorCode.h */, + 03168B5FD0FDF3BC03988D170627C222 /* FIRErrors.h */, + F7454AAA8611460E40072A8242598B1B /* FIRErrors.m */, + 524DC92E428590D64BD35B69FAE4E32B /* FIRLogger.h */, + DB61590A1D3C3125938F217F5E14ED9D /* FIRLogger.m */, + EA02DB62870C585628FD8725D3277A54 /* FIRLoggerLevel.h */, + 3704EE2DB67187CDD6B387F348CB41D0 /* FIROptions.h */, + 33EE705BF112EC3B7C1E67E9E0B858F2 /* FIROptions.m */, + F36D0E45637DB5DDE415A88AB9F81B2F /* FIROptionsInternal.h */, + CAE5C63FB4B0E24853ECEC763B56541B /* FIRVersion.h */, + FAD876CD7B0231BB382CA6A4D0C971CD /* FIRVersion.m */, + B49542B498A06DB2EDF8EE88BC589009 /* Support Files */, + ); + name = FirebaseCore; + path = FirebaseCore; + sourceTree = ""; + }; + F292F824B8339AA09747E0559CBFDD3D /* Support Files */ = { isa = PBXGroup; children = ( - D30915124033725D9B5D8D4201D28BA1 /* GTMNSDictionary+URLArguments.h */, - 58B33B41158BDBB4A9D00FCAE71EBD99 /* GTMNSDictionary+URLArguments.m */, + 59DC9639CA4DCBB82ACE73BDE97C8FE1 /* nanopb.xcconfig */, + 77EEBDAE0C2EFBC7F5A8C4AD1CD162FE /* nanopb-dummy.m */, + D196BAC67D73FBE47B196FFF4809A496 /* nanopb-prefix.pch */, ); - name = "NSDictionary+URLArguments"; + name = "Support Files"; + path = "../Target Support Files/nanopb"; sourceTree = ""; }; - F6B50A93D030BD0496B509C8E3586FDA /* AppDelegateSwizzler */ = { + F38B2603D3F5222AD09EAC578D251E04 /* nanopb */ = { isa = PBXGroup; children = ( - 3E822D3712B9F2508695B633714B57B3 /* GULAppDelegateSwizzler.h */, - 81D34BCF7098CC66628D279837360686 /* GULAppDelegateSwizzler.m */, - 2504EFA7DAA884BEBB3493C7C31EFF2B /* GULAppDelegateSwizzler_Private.h */, - 69DAFD5D0157639AA62C9A5B0260F34C /* GULLoggerCodes.h */, + 53CAB80B48147C3FF98B40A65850F078 /* pb.h */, + 4598E8CE21EEF42BE2584DBA6FCC11F1 /* pb_common.c */, + F3C5C06ABF35C5C02A270D606DED2B88 /* pb_common.h */, + A942DB8E6AD6323C241EC1569B908905 /* pb_decode.c */, + C57A0D2CF0F382E8C20382DCFAFD1221 /* pb_decode.h */, + 9FCAC1368EA1D0FB6A21074E4FFC222B /* pb_encode.c */, + 06CB84FA5566D0EDA5C8331F13B8C392 /* pb_encode.h */, + 0D7DE7BFDBB8C2F90FF5DAA99E683C1A /* decode */, + E4EAFFF6828995E3D2AA50BFC3F54B5D /* encode */, + F292F824B8339AA09747E0559CBFDD3D /* Support Files */, ); - name = AppDelegateSwizzler; + name = nanopb; + path = nanopb; sourceTree = ""; }; F75B605D33DDD3AEEEC60FB9B87C1BB2 /* jsinspector */ = { @@ -5612,15 +7035,6 @@ name = jsinspector; sourceTree = ""; }; - F76187C15D9726671993DEC769576483 /* NSData+zlib */ = { - isa = PBXGroup; - children = ( - 3E2631576F7A1002CC3B12FA44368A76 /* GTMNSData+zlib.h */, - 13049D05C3EA29CBF24A9BAD6E4B6DF6 /* GTMNSData+zlib.m */, - ); - name = "NSData+zlib"; - sourceTree = ""; - }; F7954DF88F703886EB9B1CD728F52CE4 /* SurfaceHostingView */ = { isa = PBXGroup; children = ( @@ -5635,12 +7049,13 @@ path = SurfaceHostingView; sourceTree = ""; }; - FB9EB62AF0A182D7747320D0C0A7690D /* Frameworks */ = { + FAC4991A72205D7859F70DD53B02792A /* Support Files */ = { isa = PBXGroup; children = ( - 58CF185EA5EBF3C2DE3574AB8DFE2489 /* FirebaseABTesting.framework */, + 9CEF7B062307C23ED1E338D00919BA99 /* FirebaseInstanceID.xcconfig */, ); - name = Frameworks; + name = "Support Files"; + path = "../Target Support Files/FirebaseInstanceID"; sourceTree = ""; }; FBCDE41871628BCC4185126F81A8BC69 /* Surface */ = { @@ -5676,23 +7091,99 @@ path = "../../ios/Pods/Target Support Files/rn-fetch-blob"; sourceTree = ""; }; - FED8D34B951824194CF2C6FFC64D0EC5 /* DevSupport */ = { + FDE871B07A3312C1BF928F52F909D44B /* FirebaseAnalytics */ = { isa = PBXGroup; children = ( - 1575D66B3DA4B53512A6FFAAF430A88A /* DevSupport */, - 56338E322F47B9635E1B684F22520B84 /* Inspector */, + 2558A8BB01481BD8C27B876045E13494 /* Frameworks */, + E9A559B395422BBC798356F1B1D59538 /* Support Files */, ); - name = DevSupport; + name = FirebaseAnalytics; + path = FirebaseAnalytics; + sourceTree = ""; + }; + FE5AED7E48653E61726C73D710DA810F /* FirebaseMessaging */ = { + isa = PBXGroup; + children = ( + D891B248FC73F84B37DA8C9BCEE57D8E /* FirebaseMessaging.h */, + D80263157FFBEC750D3C4CBC0AA270E9 /* FirebaseMessaging.h */, + CECB2E52A4D61E5EEC7F654E4D1E971B /* FIRMessaging.h */, + 4C573707E62D8A5DD5ED310288347C87 /* FIRMessaging.m */, + 640485D56F169D7F85A9148D7262296D /* FIRMessaging_Private.h */, + CCD510EA205821B5537E61E565622B87 /* FIRMessagingAnalytics.h */, + 03C7DC736195B2F84AB92FD41F745685 /* FIRMessagingAnalytics.m */, + A635DF48E01E89FDD6731F6327F620EA /* FIRMessagingCheckinService.h */, + 317A540B41EBF84D2B70A726EE91CD5F /* FIRMessagingCheckinService.m */, + F295E06C7C436FFF623A07299B5151E3 /* FIRMessagingClient.h */, + CED6E5B78AF9299C7515CA609B49FA2A /* FIRMessagingClient.m */, + 845976E40CFA65B0DEBDDFB5EE10EF94 /* FIRMessagingCodedInputStream.h */, + 708507DA28CE846DF9AEFA83BFB58787 /* FIRMessagingCodedInputStream.m */, + 70BAF82D1EE14FACDC272E1C4B56C5E9 /* FIRMessagingConnection.h */, + A665F0DDA5C86811B182E51C100CDCF7 /* FIRMessagingConnection.m */, + 79743169E22CF9AF19816EDD74E1AFE0 /* FIRMessagingConstants.h */, + 42DA9DA5A3D5DB14678F48C2A1FDC942 /* FIRMessagingConstants.m */, + E14F98E6F5EE4D75A64409BE058C39FD /* FIRMessagingContextManagerService.h */, + 6A27F2FAACB3CE33F2F156508EE98F6D /* FIRMessagingContextManagerService.m */, + 8FFF38C9E3F7CB5F4C45EC6F0C89C59D /* FIRMessagingDataMessageManager.h */, + BF0053A92A3441539945F1004FF4F28A /* FIRMessagingDataMessageManager.m */, + 986EF17779F9AA5EA7576D1E5564003F /* FIRMessagingDefines.h */, + E65F21F9ABB67CCC10B8DA68A6597A33 /* FIRMessagingDelayedMessageQueue.h */, + 5177F3CD579B574CBC9F2649190E4693 /* FIRMessagingDelayedMessageQueue.m */, + CA6F39AF275D541906673CA4ED08BD50 /* FIRMessagingInternalUtilities.h */, + 065D8744D7CD01032E24ABBA1ACAFC3E /* FIRMessagingLogger.h */, + 459829D2EDDEE906B8986B8464589100 /* FIRMessagingLogger.m */, + 5AEDA64FA1B2A882628B31137FD427BB /* FIRMessagingPacketQueue.h */, + E206E0CCE0AAB0D92428779769DF2674 /* FIRMessagingPacketQueue.m */, + 75290A71FA8F79E812D3DB2C1321AF9E /* FIRMessagingPendingTopicsList.h */, + 2E5BD7D7208DA0C99017C1E9935E47D0 /* FIRMessagingPendingTopicsList.m */, + 56E2A60C3BF0245E931C0022D13A3EFC /* FIRMessagingPersistentSyncMessage.h */, + 63130479CCFC34C4090DEA0EC26DDEFF /* FIRMessagingPersistentSyncMessage.m */, + C91204B4B8E6BFE92D6270595B0E41B8 /* FIRMessagingPubSub.h */, + 91DB18116E45682289F6BAD1CED9DC6D /* FIRMessagingPubSub.m */, + 2EBBCAE335DBBFEA14BA90A678C4A32B /* FIRMessagingPubSubRegistrar.h */, + CAF1EDD6912136DCE34276BEE6DFEB30 /* FIRMessagingPubSubRegistrar.m */, + D73650FB53553AA024FEED450D81D6D9 /* FIRMessagingReceiver.h */, + 2D94706E0AD7230685EFD7FAC0869FDF /* FIRMessagingReceiver.m */, + 80F654ED8096D8AD505DCFEDE99BA1E1 /* FIRMessagingRegistrar.h */, + A39D995E238A995FA07E6668EF4C51AB /* FIRMessagingRegistrar.m */, + 010593F7E979CEFE100326A954A7ADA3 /* FIRMessagingRemoteNotificationsProxy.h */, + 19BF7714D6B5F3817830119EEC74D6FE /* FIRMessagingRemoteNotificationsProxy.m */, + A06E21DE99BB96DBF43EA033D82CFCDD /* FIRMessagingRmq2PersistentStore.h */, + 3A71E9CEC1419826CB35B97C1AA689F8 /* FIRMessagingRmq2PersistentStore.m */, + C7C7AC57C4C8E75A6C614918C18F943A /* FIRMessagingRmqManager.h */, + FCE4AE69FB42F974D532A536DAC73C2B /* FIRMessagingRmqManager.m */, + 2CB2ECC205A62B1B815F9B9BC95FD7DE /* FIRMessagingSecureSocket.h */, + A87E72714A0CB0D74D50BA450CCF834B /* FIRMessagingSecureSocket.m */, + 77B8A48D919AA42DBDD52D2941231A93 /* FIRMessagingSyncMessageManager.h */, + 3CB5D828593D472D95DB8470B5489622 /* FIRMessagingSyncMessageManager.m */, + 8E8D7E53496B4BF7E29AB957ABC2565B /* FIRMessagingTopicOperation.h */, + 65047FECD45DEE085062BEEF54A90E1D /* FIRMessagingTopicOperation.m */, + B234D6101F861EA4DDA1FAF741BCDDDC /* FIRMessagingTopicsCommon.h */, + 0E900875CB45B56E0BAE6568D0A5B66C /* FIRMessagingUtilities.h */, + CAAB05F190C3DDA01DBEB8EA8DF57C01 /* FIRMessagingUtilities.m */, + FDD801BB217E720037A5DACA23733155 /* FIRMessagingVersionUtilities.h */, + 389E3FCACF1C1E456B1E409DB7E730BF /* FIRMessagingVersionUtilities.m */, + 50AA96879422B9860DF58C1C5F54ACB9 /* FIRMMessageCode.h */, + C0F481DA187D9340471FBE612D71CD33 /* GtalkCore.pbobjc.h */, + 0522DE22463906DA220EC22B9CDB8B94 /* GtalkCore.pbobjc.m */, + C03D805F3E975FCDCB26979447EF0A9C /* GtalkExtensions.pbobjc.h */, + C53BD08965BE33BBC6529816FF16507E /* GtalkExtensions.pbobjc.m */, + 5154260B8F510C7AC74F8D2465CB6BC4 /* NSDictionary+FIRMessaging.h */, + 317F07FF03994881B20CF2F7178180EA /* NSDictionary+FIRMessaging.m */, + 6EDCC0DCEBE6963DC7DF76AD7231B96C /* NSError+FIRMessaging.h */, + 0EEC2E179EE88ADA68266CD2DEC1F4A1 /* NSError+FIRMessaging.m */, + A6853D8398FDDC5721606E3C13616ACE /* Support Files */, + ); + name = FirebaseMessaging; + path = FirebaseMessaging; sourceTree = ""; }; - FF2DE9067FA7667E745C623BFCC2B4B8 /* Firebase */ = { + FED8D34B951824194CF2C6FFC64D0EC5 /* DevSupport */ = { isa = PBXGroup; children = ( - 353980B67A83A15D8C226855106DE7AF /* CoreOnly */, - 29433304B61FDDFA392CBB2982CD30A5 /* Support Files */, + 1575D66B3DA4B53512A6FFAAF430A88A /* DevSupport */, + 56338E322F47B9635E1B684F22520B84 /* Inspector */, ); - name = Firebase; - path = Firebase; + name = DevSupport; sourceTree = ""; }; FF487A4EB6BB847F92338EF7471A5E88 /* Pods-Kalend */ = { @@ -5712,6 +7203,145 @@ /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ + 0288EF814D00879C90F07254681BC4AF /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 467047FA544BC876EE820B6C23383963 /* APLevelDB.h in Headers */, + F88B9A9B52466333E3C24059A3C7F794 /* FAckUserWrite.h in Headers */, + 2A2E881958263C4D97B8CEBDE00C551A /* FArraySortedDictionary.h in Headers */, + 186B094077809BB3D792926C9C16D775 /* FAtomicNumber.h in Headers */, + 9C98568D4383E52533A36CF5AA80E99E /* FAuthTokenProvider.h in Headers */, + EDE6A9180C6F8B3334909515AD2DEE61 /* fbase64.h in Headers */, + 9E8BCE3C2F8101B8D9491C04458420B4 /* FCacheNode.h in Headers */, + 5D471E97EDDB85894A1188803D7DE67C /* FCachePolicy.h in Headers */, + ABEF3258E2372D38510F0D9BF5104071 /* FCancelEvent.h in Headers */, + A99EFEF5545FB42DD9637E847A24CB3C /* FChange.h in Headers */, + 78543A920E1C1359F4E4DBF4772CD8C9 /* FChildChangeAccumulator.h in Headers */, + 47045A571995E8144D9CD11E5BB937AF /* FChildEventRegistration.h in Headers */, + 3CEE7FB3BD2CFC7B0F4F042AE528ED0E /* FChildrenNode.h in Headers */, + 776EF5349F68D7B7F4545C2A147C9733 /* FClock.h in Headers */, + 8853CDCC00C5A51CBC41612B9216829B /* FCompleteChildSource.h in Headers */, + FB320909B47389A2B2594129D4986015 /* FCompoundHash.h in Headers */, + 6D91DF9734AB514E0E29715FA89FF878 /* FCompoundWrite.h in Headers */, + B9494EDF343453F963503C4CDE946666 /* FConnection.h in Headers */, + F2B4D2D68DB0EB08EF03C5F10FC71CC3 /* FConstants.h in Headers */, + C70172F0F275CCDB6A3C6C7B12557EDD /* FDataEvent.h in Headers */, + 799C2589A30E062414DF38B8F5056D16 /* FEmptyNode.h in Headers */, + 6246130E1D89FFA2908B2455BFDF26B1 /* FEvent.h in Headers */, + 1E384510921E92BE4AE5D961C7CCD7B3 /* FEventEmitter.h in Headers */, + 9C8FF27343E4C0B629FDAD0089E8F418 /* FEventGenerator.h in Headers */, + 0B4455F7885D68F6579856B6958FF623 /* FEventRaiser.h in Headers */, + ADB3A996A3F39F7FB86B6C64BD1BF820 /* FEventRegistration.h in Headers */, + 001188D0BA836471873566ACF7DD2C7C /* FImmutableSortedDictionary.h in Headers */, + B6BBC4425071324F694CB0187A4B2927 /* FImmutableSortedSet.h in Headers */, + 53DA9B914C3FD19605996A4ABDE66C2D /* FImmutableTree.h in Headers */, + AD283DEA3744706AE0BCA1A4BAADA26C /* FIndex.h in Headers */, + BC7EE54BE2D20E72CDC05BAED6398B6F /* FIndexedFilter.h in Headers */, + 188243E3312D6924AF123B4D341BB5C0 /* FIndexedNode.h in Headers */, + D39C93159FF257FB6F49AD432238264D /* FIRDatabase.h in Headers */, + 49CF2504036F1053DE3A3EFACB16878B /* FIRDatabase_Private.h in Headers */, + 7F79F065477E8E91BA4CCFE22A311ED9 /* FIRDatabaseComponent.h in Headers */, + BE4022CA4636A3D36C0EC34AC88F0DFB /* FIRDatabaseConfig.h in Headers */, + CEA99928D4EA2DEDA9B6575870AF20CB /* FIRDatabaseConfig_Private.h in Headers */, + BA02231F41A2ED9DF20D5C93DB7EB650 /* FIRDatabaseQuery.h in Headers */, + 2BA2DCDA1319BDE4AD47C6E68DBCA2EE /* FIRDatabaseQuery_Private.h in Headers */, + A6A4E7FF9C2387781A5296926566911A /* FIRDatabaseReference.h in Headers */, + 6B1412BA1ACDECA1D4484BDC76461A38 /* FIRDatabaseReference_Private.h in Headers */, + 6856CED8F184BF34509C004C56600435 /* FIRDataEventType.h in Headers */, + 352EF04332383EFC0A46A4B84DE11FAD /* FIRDataSnapshot.h in Headers */, + AF857D89FF02AEC18A34E303CC849AD7 /* FIRDataSnapshot_Private.h in Headers */, + 086D3C772C96B5C95FCF942E1C180B2B /* FirebaseDatabase.h in Headers */, + A7F64E577028CDA807DEB1C4A2B2027A /* FIRMutableData.h in Headers */, + E343EF2D0EEAB2FCF3FA5F1C262D68CD /* FIRMutableData_Private.h in Headers */, + E4DFEC4486874317EB58F04764F922C8 /* FIRNoopAuthTokenProvider.h in Headers */, + E492FD1D0F950C9915C580EB89F76804 /* FIRRetryHelper.h in Headers */, + 49F6082A7056E1162EDADF9F9ABD9080 /* FIRServerValue.h in Headers */, + 6D08E404B5A52E32A85FB9057FDF9579 /* FIRTransactionResult.h in Headers */, + 315254F10E03F63817A00CB588025963 /* FIRTransactionResult_Private.h in Headers */, + 9E07548305B71E5475F7381603F9EF4A /* FKeepSyncedEventRegistration.h in Headers */, + F9CDB9DF65083CD68DD46CBD686D3AB9 /* FKeyIndex.h in Headers */, + 6BCB0DBB1B39D69EF7310F76AB5DC2CB /* FLeafNode.h in Headers */, + BBA105DF3C4E10C539D00DB3AAA939E8 /* FLevelDBStorageEngine.h in Headers */, + E71DD15B7354B729F08D756042F1A4DA /* FLimitedFilter.h in Headers */, + D4398146DDC2CD89858D5B0923A015F4 /* FListenComplete.h in Headers */, + C9CE381840E6E9AC3795A7C184F137AA /* FListenProvider.h in Headers */, + BDA23269C2018E00F347379F7264D054 /* FLLRBEmptyNode.h in Headers */, + 2D9DA1F064A6F9183E41D386ECFA2CF9 /* FLLRBNode.h in Headers */, + 4A7CB69CFCC95FFAEEC248D414EA1C56 /* FLLRBValueNode.h in Headers */, + F7F7E3B897D2C6DD31D4B8034148FDFF /* FMaxNode.h in Headers */, + 6496C58ECA79C3DF13DEF88E3CD63CDA /* FMerge.h in Headers */, + AF3426D61AC45AB336FD0D37064808AB /* FNamedNode.h in Headers */, + 52DD9F7F357CA8043AE0FA675899C60D /* FNextPushId.h in Headers */, + 592D03551BFA5B934AFAEAD09CB5FD29 /* FNode.h in Headers */, + B33C11A8033AB8F2D3140437A0009492 /* FNodeFilter.h in Headers */, + 6BE50A02CB9BEB605A0015BE8D395676 /* FOperation.h in Headers */, + CFC67BC60F185B7EA7F5AD04542FF2BA /* FOperationSource.h in Headers */, + 56A2971E105D6D2CDF42FA9A033096B9 /* FOverwrite.h in Headers */, + FB655992E1C3B47CFD6FD478552CEDBC /* FParsedUrl.h in Headers */, + A11FF41512E77716BED7150F30BA7CEC /* FPath.h in Headers */, + 25CF94A936991B3B5AA0F8279597737C /* FPathIndex.h in Headers */, + 338CBB9B5FFE6FD9D15FA7D3EBA194B8 /* FPendingPut.h in Headers */, + 6A36779AE89A2D8C580CB5B277AAE91A /* FPersistenceManager.h in Headers */, + 3DB2BB65E216C7AB2ED6E7775D92F3C1 /* FPersistentConnection.h in Headers */, + 8E9CD32F54B2CDECF607C9C963CB7A2F /* FPriorityIndex.h in Headers */, + 28A8990B7D5AB27B1CB0E0AFF738911B /* FPruneForest.h in Headers */, + E06BA97EBAC98AE3DDE30EC133FA4BFA /* FQueryParams.h in Headers */, + B108968F37EE82CA50D5F94F7A21009F /* FQuerySpec.h in Headers */, + E75478BD710626804EFA990841477F38 /* FRangedFilter.h in Headers */, + 7DD7FBF9D8507B1433ADDDC6840322C0 /* FRangeMerge.h in Headers */, + B50C56FF4273C882E5A3F13F00CF6B1B /* FRepo.h in Headers */, + A55467E5636325B2331155A28AF952C5 /* FRepo_Private.h in Headers */, + D20B16A522B1AEAFB045EFED4638D291 /* FRepoInfo.h in Headers */, + ADC87054F534DBD851BA5E7435EC41F8 /* FRepoManager.h in Headers */, + 1021C3D91117F52FF297BC2AC3DE6302 /* FServerValues.h in Headers */, + D12F33493208D3073B51BB4BFB4D215C /* FSnapshotHolder.h in Headers */, + 97E38F297DB2F4A542F8A999C8FCAEE1 /* FSnapshotUtilities.h in Headers */, + 93AC140E83211FFE7D73691EAA322208 /* FSparseSnapshotTree.h in Headers */, + E5DEAF7B16E65CA66325F83AE1A58B9C /* FSRWebSocket.h in Headers */, + 407FB5F780BDAAFECE8167C302B3209C /* FStorageEngine.h in Headers */, + 18A85D77D01E2916D9DC8E1A31B3B248 /* FStringUtilities.h in Headers */, + BE111BBD1063B7BCED4706B1835BA8B8 /* FSyncPoint.h in Headers */, + 17040698C0915D3AC6CBF28AE5C4C954 /* FSyncTree.h in Headers */, + 717C7B1F58028417564B42BD580F2FD3 /* FTrackedQuery.h in Headers */, + 3DE031256D0F33B9E7FC1421A8720CC0 /* FTrackedQueryManager.h in Headers */, + 6165C64977254E20FF5B5A9CCE5BD21F /* FTransformedEnumerator.h in Headers */, + 23CAFDB472EC21390E69FD9F4DF5A7D6 /* FTree.h in Headers */, + D3EEF94F7EA9E8C801E7D0C34FF48364 /* FTreeNode.h in Headers */, + 827B607DD0AF27A93FB4AA179DA09827 /* FTreeSortedDictionary.h in Headers */, + 38EA8D7832A3A7C66E0FD15B22D21893 /* FTreeSortedDictionaryEnumerator.h in Headers */, + EAE97385DCFDEF4B727F3AEA9A98E0B2 /* FTupleBoolBlock.h in Headers */, + 232CF4EF020A06B3A59A76684729C5FF /* FTupleCallbackStatus.h in Headers */, + 0F296A8EC38AC89695FEF3CA94A40740 /* FTupleFirebase.h in Headers */, + 314459A22255D1631C8B25518409552C /* FTupleNodePath.h in Headers */, + C29E6656B2F76A622C5A9D56F181AB97 /* FTupleObjectNode.h in Headers */, + 6030828805A49C92E7A0218F0754AAE6 /* FTupleObjects.h in Headers */, + 0DE2F2D90178477FF721B7B4E4E0DAC4 /* FTupleOnDisconnect.h in Headers */, + 275FA198743DEFD6FFBA6784AF8C31E3 /* FTuplePathValue.h in Headers */, + DF6680AC21D5775E07D44E12C71BF279 /* FTupleRemovedQueriesEvents.h in Headers */, + 1B5743AF9FB72E6F0FB5E3C5D5F9F870 /* FTupleSetIdPath.h in Headers */, + 39BD4B821A6DF71CEE30F3124FC8CB83 /* FTupleStringNode.h in Headers */, + 9D550FD62CB625A1ED710ABC7D71996F /* FTupleTransaction.h in Headers */, + C0AFF5303BEB481F6BD89042FBF2B9B1 /* FTupleTSN.h in Headers */, + CFDCBE473B99BB78E3F984DDE446790B /* FTupleUserCallback.h in Headers */, + A7306BD94CD26B98E26779B134BDE19D /* FTypedefs.h in Headers */, + 95C672D21C6375399DC69352491F5794 /* FTypedefs_Private.h in Headers */, + 6FA156517C0BD710286599F90D810C02 /* FUtilities.h in Headers */, + DCF15F95FAE2BEA35F039BAA607DCAA7 /* FValidation.h in Headers */, + F8863E1C92E7C0A0F25997D2B5235472 /* FValueEventRegistration.h in Headers */, + 43CF58B7907116E2FE0DEDA144E2E7A8 /* FValueIndex.h in Headers */, + 009C4724256981C1B3CB1EFF5A272A2F /* FView.h in Headers */, + 0AAA7D1CA7B6EF52251986D3A44E6537 /* FViewCache.h in Headers */, + B0C300B9DD43F4E6B9349D47E27F1B61 /* FViewProcessor.h in Headers */, + AFF8E7FF6283BA4EEC101DEAE626F0F4 /* FViewProcessorResult.h in Headers */, + 3FE904A17592EB69B2AB78D5545E58B0 /* FWebSocketConnection.h in Headers */, + 8E17D99396C7FF3DE15E4D8D0280A704 /* FWriteRecord.h in Headers */, + 86EEAAF7922FB1C7EA5400E9EBD762E2 /* FWriteTree.h in Headers */, + 2D0D9D1833FF1CD8204BA750B7E7FDA6 /* FWriteTreeRef.h in Headers */, + BC02656B3A666758410BF05D2F560315 /* NSData+SRB64Additions.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 0B6BCC22253475E320F1ADF71BF2A715 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -5734,45 +7364,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 1AEA4100B603D4A9A933E2A9FCEA7404 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 10460236D60311486446A80694169AF2 /* SafariViewManager.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 2188B3CE2A139A8ADDEF81C16463989B /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 22FAE8EC55151AB82B53D9B0ADB2BA4D /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - A0BA660DCDAE5C7950ECB61DDC4F09B7 /* RNFlingHandler.h in Headers */, - 3C4FED8981790131C3EBD1B7C8E09896 /* RNForceTouchHandler.h in Headers */, - E824A6440CE987F1EE710A0881AD1AC6 /* RNGestureHandler.h in Headers */, - DA7E6FB5A40BD2E067CB80AE0FB029B7 /* RNGestureHandlerButton.h in Headers */, - D4DA1F113B5DE5E746CF35894C01ED9C /* RNGestureHandlerDirection.h in Headers */, - B7991E98563076878AA5B035407A864F /* RNGestureHandlerEvents.h in Headers */, - D5DF8DA8032627AF2C452567022217FF /* RNGestureHandlerManager.h in Headers */, - B188BBD7B22F0F4FE470D9E8DF8DA1F6 /* RNGestureHandlerModule.h in Headers */, - 3BE0669EF90361F0650A127523B23E96 /* RNGestureHandlerRegistry.h in Headers */, - D005AC08259585CEF587FE2B122F6CB3 /* RNGestureHandlerState.h in Headers */, - B85C0204B7080879BD116C0BC5B70A56 /* RNLongPressHandler.h in Headers */, - 164EE20DD3472D199CA907077EFC3B4E /* RNNativeViewHandler.h in Headers */, - F0954726872BA5624DFF3CBAFAFAB78D /* RNPanHandler.h in Headers */, - 651E5E714107123EFB21B8E85C677EFD /* RNPinchHandler.h in Headers */, - 392B78F24DE2327FDB07904F055ED372 /* RNRootViewGestureRecognizer.h in Headers */, - 62728BD7C32DBD3DACB67117AB9F8DB3 /* RNRotationHandler.h in Headers */, - B239DA8126DA1736556BA1F1E996017E /* RNTapHandler.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 23FF026BC9F063E68BACBA237585D727 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -5865,18 +7456,27 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 4354827B6BB689FE680ACA302CC544C1 /* Headers */ = { + 44EC45CBBE74A7C706D0980BF5716777 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 171A1852B622F0A4CF7B26D389A3B375 /* GTMDebugSelectorValidation.h in Headers */, - 4960BA7C223DB21A38DEABFA1572EC41 /* GTMDebugThreadValidation.h in Headers */, - 6C6718E9960F07F3D248FE984E5EFC84 /* GTMDefines.h in Headers */, - 4E2AAF2951FE1485BD0028EB1F8C1694 /* GTMLogger.h in Headers */, - 7655B6BEAF1A60083C6DC06F90E9E663 /* GTMMethodCheck.h in Headers */, - C4392EE09C5AE00193DAC33B632B561C /* GTMNSData+zlib.h in Headers */, - 8ACC27CC9FCE781F5F2E6E2461794D63 /* GTMNSDictionary+URLArguments.h in Headers */, - AA3807717214518966CD92E89334D3C9 /* GTMNSString+URLArguments.h in Headers */, + 3715C0A8D76DCB4EC6910477FD17F032 /* RNFlingHandler.h in Headers */, + A8A2110B4FB69088131EA1ADD93D9C3B /* RNForceTouchHandler.h in Headers */, + F5EA4D5809407F18546801504152DD04 /* RNGestureHandler.h in Headers */, + 68F9564EEBF668B418191E282E8B0661 /* RNGestureHandlerButton.h in Headers */, + C4DB20AE36B355A73E1DBA1455952577 /* RNGestureHandlerDirection.h in Headers */, + D9FE98956BE308F549E125550899F6B5 /* RNGestureHandlerEvents.h in Headers */, + 940BB98CCD896AE13E549A90A2963928 /* RNGestureHandlerManager.h in Headers */, + 2A162E30FA787CADB18AAD34F8B634C3 /* RNGestureHandlerModule.h in Headers */, + 7B59C5D0DCC19C961D37B0CB98C46782 /* RNGestureHandlerRegistry.h in Headers */, + 986EA1E27A22C6960C4473999CC92936 /* RNGestureHandlerState.h in Headers */, + 4C406BA0486D04ACCCFBFA73F4D79ADD /* RNLongPressHandler.h in Headers */, + 69274AB05B6E38B4AA3EF4BAD1CC47BA /* RNNativeViewHandler.h in Headers */, + CCAC15E902228F355342E658C1AD8F70 /* RNPanHandler.h in Headers */, + ACD35CF9147445F5259E930CFA538AC7 /* RNPinchHandler.h in Headers */, + 5CD529C806CFA1E7537EE273DA852501 /* RNRootViewGestureRecognizer.h in Headers */, + E573719D08940140F2D661C384C105EE /* RNRotationHandler.h in Headers */, + ECEC1E12ED5267924603D9B2B6FC1409 /* RNTapHandler.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -5892,23 +7492,52 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 6385787502E866C0C8D3C81C3DD5D7C7 /* Headers */ = { + 53D7CBB750FDF9A7443B765461A6B4A0 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + BA280545E1DB13C13C5B5E420B1A2F20 /* GTMSessionFetcher.h in Headers */, + 98FDDB55A7ECD8396691F2010D86D578 /* GTMSessionFetcherLogging.h in Headers */, + C9A12D4F3300948B69DA3C3EF153830D /* GTMSessionFetcherService.h in Headers */, + C447ECC61AB7D83C68A6C9BB778717B5 /* GTMSessionUploadFetcher.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5EECE20A051CDE842E85832655A8769A /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + FEE9EAEF1085DD988BEE8F4FA613E546 /* RNCSlider.h in Headers */, + 48AE61EAD2027714189B82B0A54105F4 /* RNCSliderManager.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 617E2AC705F0B2406BD1DBE1CB18C6A0 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 9CF4C63AFFC68BE0E7A686959E83A81F /* CameraFocusSquare.h in Headers */, - DDAA33220CD6AF40659A21F76FA95C4B /* FaceDetectorManagerMlkit.h in Headers */, - 72CBCEF20BCC9BFA8F7B2E1F72004B2A /* RCTCamera.h in Headers */, - 5EC6BCE473AC1E5689014FE96BCC7E4F /* RCTCameraManager.h in Headers */, - ED9D29AEC736F9155E6ADA0B73544963 /* RCTSensorOrientationChecker.h in Headers */, - 99080CF5D9820F96377779DCFCCB5F26 /* RNCamera.h in Headers */, - 72614C46EA50ED4C0C6D0F22EA08CEE5 /* RNCameraManager.h in Headers */, - 532BD0393673759BF1C0C40B01EE2D5F /* RNCameraUtils.h in Headers */, - AEE19FFBA1A052352E5A4ED4A425B096 /* RNFaceDetectorModuleMLKit.h in Headers */, - 4F84615D788E2303F4AF889D9E500584 /* RNFileSystem.h in Headers */, - C684F5F6B06D3C1C8F428F6C1E08B836 /* RNImageUtils.h in Headers */, - AB434CB381A5F892D7380FC9AE31F5D2 /* RNSensorOrientationChecker.h in Headers */, - 2659574A75E1EE6FFB6DC653DADE782C /* TextDetectorManager.h in Headers */, + EF0E84C41367B8F89ACB192170FCF738 /* FIRAnalyticsConfiguration+Internal.h in Headers */, + 4F5FC8A554259A02834F92645D114887 /* FIRAnalyticsConfiguration.h in Headers */, + D4C69CA73ED5DB5D3B6CA9340AA893DD /* FIRApp.h in Headers */, + 227CD4B18468A8431BC8F1830803C24D /* FIRAppAssociationRegistration.h in Headers */, + FFC393A865498C8967E0E42308B36FFF /* FIRAppInternal.h in Headers */, + FE7B5A18D11C99290251F9514576807C /* FIRBundleUtil.h in Headers */, + 8158AC36DB53550096B9D2DD5703D5B8 /* FIRComponent.h in Headers */, + 9408BFD5A1622FF536810A93BE097BE4 /* FIRComponentContainer.h in Headers */, + D852DCAF8B012B21EF9288350A4E3F76 /* FIRComponentContainerInternal.h in Headers */, + 9C2E1B211F058DABB9605EB2FA87285F /* FIRComponentRegistrant.h in Headers */, + B7CB772B6A77D5B2F1F6D384C6B08F9A /* FIRComponentType.h in Headers */, + 5F56D23C49524428EC03E62D2A6B108D /* FIRConfiguration.h in Headers */, + 4ADE2317465B57AE998D2EEBA726D665 /* FIRCoreConfigurable.h in Headers */, + C7ED253056C86FE2E96603845574D529 /* FIRDependency.h in Headers */, + 2145EC543EEACB3896B9867CEDB67CF9 /* FirebaseCore.h in Headers */, + 7F905C3328959B10CD5E3DDCC8279D97 /* FIRErrorCode.h in Headers */, + 37254E9DDE214B4FCDABF39261827074 /* FIRErrors.h in Headers */, + CD65FFA81F39C2D6D955FDD9FE7E0131 /* FIRLogger.h in Headers */, + 3BCADF720D85DFCFC1FB6162BB587B12 /* FIRLoggerLevel.h in Headers */, + 501FD58A6631FDBEF9B574E5BA57324A /* FIROptions.h in Headers */, + C677530755C932F08F3857D54781B19A /* FIROptionsInternal.h in Headers */, + 4796FD6316E274E201F895A87E29A2FD /* FIRVersion.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -5929,14 +7558,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 75401077A077A36DC576AE055CF6A41E /* Headers */ = { + 7DD324ACDFF9DA24A6D40D0E375B293B /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 92F770D40FBED9F855E5C8820C317BD9 /* pb.h in Headers */, - CD5C2BA165DB596F4723A49E23E150BA /* pb_common.h in Headers */, - B64BC18DE636C8C27F5B68FBE6E3C708 /* pb_decode.h in Headers */, - E3185C87D5A50228FA0CCC843A3DD0B0 /* pb_encode.h in Headers */, + 2CBD8BE0A15525C01B09F025049A7754 /* pb.h in Headers */, + 66C94119E594089494A7319ECDC01E25 /* pb_common.h in Headers */, + BF2EC45C2815ED477BE718178A199707 /* pb_decode.h in Headers */, + F5C8A375A5EA4F3DB076E3347DFBCB38 /* pb_encode.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6233,243 +7862,328 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - A691B34223825AC2405C7D2742BD9731 /* Headers */ = { + 919FD11BA85060F8EC39A4287B2DF2D1 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 33EC8769B51683B6F95C78985880D5A8 /* IOS7Polyfill.h in Headers */, - FD1A3036A1977EE372FE0E6C8C5E9BB2 /* RNFetchBlob.h in Headers */, - 12CFF38B5448CF452A6BEC3F88BD3AEE /* RNFetchBlobConst.h in Headers */, - 5AFE13968D9DAEB7BB20884538B107B9 /* RNFetchBlobFS.h in Headers */, - 90D94A80C8990BBBA0B1C0B21FA894C1 /* RNFetchBlobNetwork.h in Headers */, - EBED03B859831B804A17EC10FC9F0B53 /* RNFetchBlobProgress.h in Headers */, - 60028AF82A0190939D7D440FA2890635 /* RNFetchBlobReqBuilder.h in Headers */, - A11AE932FB89688512C2E4CAF2E9406E /* RNFetchBlobRequest.h in Headers */, + F780EB7564A8C9A8E210EFC903BBE40D /* RNCAsyncStorage.h in Headers */, + 326D51784FA6FC7A8CC96AABE8E6B1BB /* RNCAsyncStorageDelegate.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - ADBE7AE7BE9C029CD1FCDA1A4A003205 /* Headers */ = { + 9C64F0FFE7F69861E6F341F624554C28 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - D59D8F2920198040224CE8178CDC525A /* GULAppDelegateSwizzler.h in Headers */, - 2D663B3BD9E834E0CEE84C0B27E7B2EB /* GULAppDelegateSwizzler_Private.h in Headers */, - 3B1DD336C634B2398D03A33060C1B9E1 /* GULAppEnvironmentUtil.h in Headers */, - 53BE8F23C13B6ABB20739BB2BCB86717 /* GULLogger.h in Headers */, - 8DC4C9575113197C5BB1E7D3C33DF7EF /* GULLoggerCodes.h in Headers */, - 1EA23D98EF3033B9D92C6A049FB43B6E /* GULLoggerLevel.h in Headers */, - D067BBB335AAC3CE608E89CFC26FD7FC /* GULMutableDictionary.h in Headers */, - 706BE2D559547C6B3D97103F4E10064D /* GULNetwork.h in Headers */, - 0867C3ADB477C60268F010BC4D231213 /* GULNetworkConstants.h in Headers */, - FD12628ECD997FE99C2D5FE5EAE33D27 /* GULNetworkLoggerProtocol.h in Headers */, - 8FC021BA68F82BB8C1CE92621BADE1B3 /* GULNetworkMessageCode.h in Headers */, - 5B119B24B1D6E01777FE7FCC1D54698F /* GULNetworkURLSession.h in Headers */, - 42631F04F1FB85FEEDE8F4908A7FA4D3 /* GULNSData+zlib.h in Headers */, - B9F5F9810CF60170D928F580F3135E65 /* GULObjectSwizzler.h in Headers */, - 16C2EC1C79E63B085BAD83B784154F89 /* GULOriginalIMPConvenienceMacros.h in Headers */, - 931A0D3EC2819746125A38C2CAE44BA2 /* GULReachabilityChecker+Internal.h in Headers */, - 5A5BD9B87A4C74452B6C0FCDBBAAA9B5 /* GULReachabilityChecker.h in Headers */, - EF2D4358A9E3D015C6CFAF79FB274E9C /* GULReachabilityMessageCode.h in Headers */, - 94F2D189EF991CF2B35A2EC1DA53CB46 /* GULSwizzledObject.h in Headers */, - D9D0A0B908A6C31A8983D5D1DB9B5DBD /* GULSwizzler.h in Headers */, - 715D4D977A023888E81E503AF1C27763 /* GULUserDefaults.h in Headers */, + 8138C2654E2DA8D84EA0AFEEF91CFE24 /* arena.h in Headers */, + C459FB55EAB68F8CA9C0288D233454E5 /* atomic_pointer.h in Headers */, + 246B3D05A4326EF92EE37093A856CEFF /* block.h in Headers */, + E98E7937A05647042CD23228F50E1687 /* block_builder.h in Headers */, + 2EB78E8A354A22EB6E0423B6D3289D4A /* builder.h in Headers */, + D6FD46E2815B593AD2ABEB59AF4E4C94 /* c.h in Headers */, + C750788F72143D5167D7505E7A1ED8B9 /* cache.h in Headers */, + 87110F690A602435E1CCDEB54A9F76E2 /* coding.h in Headers */, + 4CDF13B90C45B12C5F8323C13C65D2E5 /* comparator.h in Headers */, + 075B823640D097D7CE649285B25C6FC3 /* crc32c.h in Headers */, + 5BA4ACD6BF65A8541083FA1CFA590555 /* db.h in Headers */, + 08107661132F919A5783A9BF4F5A21A7 /* db_impl.h in Headers */, + 5112566D095E6BAF3A58A7DA261D41DA /* db_iter.h in Headers */, + F42D6CCF705596381849593895540261 /* dbformat.h in Headers */, + 1F12ABB2EF706FB82D6B828AA46C5200 /* dumpfile.h in Headers */, + 917F64334A3A896FAAA29A86A142D815 /* env.h in Headers */, + BA7974E36A0E189D0F1F1F68A77859C6 /* env_posix_test_helper.h in Headers */, + B0289F339E768CBBDB08CD2B8479A711 /* filename.h in Headers */, + B20D3518D5B524017760849F71DC2959 /* filter_block.h in Headers */, + 6A65E6F53C547156F610BD9F11B682E7 /* filter_policy.h in Headers */, + E20D8615C67AF849C9C656E220B5EEF6 /* format.h in Headers */, + 27CD829C76EE93608A0A1F2040C37F03 /* hash.h in Headers */, + 8FD4C98211BDAD30D9AF6B1DDAF062EE /* histogram.h in Headers */, + 851581D982C384766E587884970388A7 /* iterator.h in Headers */, + 3ACC4F8F206003A5BDCDB524C31F914F /* iterator_wrapper.h in Headers */, + E8A3641867D06699DC99DA213ED25CCF /* log_format.h in Headers */, + DE0B7E6F588668F2888D407F60A1D62F /* log_reader.h in Headers */, + 81F9AF4E91592C358A88FE96209B7378 /* log_writer.h in Headers */, + 6C174498316C14889CFD89E79E1C21A0 /* logging.h in Headers */, + CBF9FE3FDB7CF9F12151C303FD32D972 /* memtable.h in Headers */, + 7F5CBB4DCB39A4973CC0E4C2A07DCDCB /* merger.h in Headers */, + 0C01793A18AB12735F7F17FE7DB3F6F3 /* mutexlock.h in Headers */, + 7B0A2D0C93F0AB344981881B2A495462 /* options.h in Headers */, + 7213586F7FB0AAF53BAB97C78810A3FC /* port.h in Headers */, + 326B23F4C1E82E9D0D97C4FE2A7E1FC8 /* port_example.h in Headers */, + F847BC099683E3AB68CF0A982E2FD9BD /* port_posix.h in Headers */, + A803147A9E4FC0F26784D426675A38C0 /* posix_logger.h in Headers */, + A823349579B07D9AE576E097151B004E /* random.h in Headers */, + 2101ADD4BE9BB8463CADE84D4DB0D43F /* skiplist.h in Headers */, + 0A91AE132171522E28AA7D237E11A4F4 /* slice.h in Headers */, + F9FE0A585EA917DD4387982B9DBB54FC /* snapshot.h in Headers */, + A033121C8191D179389CD98E057EE495 /* status.h in Headers */, + B587BAEF82D4C9FF23CD50F21FC27F64 /* table.h in Headers */, + C571DF5ECF1978804DFD1E14E61D0833 /* table_builder.h in Headers */, + CA2AAE32804043D222C64ABE8112A84E /* table_cache.h in Headers */, + D0777D0D19D44A48AA9CCA523BE9D85F /* testharness.h in Headers */, + 56D74B4DA37EAC08EEB4CD707B0EF55D /* testutil.h in Headers */, + C3430C146960EDCEC4B4FCFFF7F0E45F /* thread_annotations.h in Headers */, + 2E08983E01CEBC7DA9BD2F2DB38118C6 /* two_level_iterator.h in Headers */, + B22BF834D5A7FCFCA5C0065E64767595 /* version_edit.h in Headers */, + 9E14D078614463EB6800EBF7A22743B6 /* version_set.h in Headers */, + 93D7E5FD58F8B01B1D245928683C42A4 /* write_batch.h in Headers */, + B6D32B09B41A82E88508959E99AC6FE9 /* write_batch_internal.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - B054694A7E9DC149D1F2A4DD1888AD0D /* Headers */ = { + A33B0F7F030D87D607530D83AB0BBD95 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 9437BF247A919FA627BDA660AB6CDA05 /* RNCSlider.h in Headers */, - F407300AF6C7F53CBB1869EC36A54DAD /* RNCSliderManager.h in Headers */, + 193BE72EBD47A2564D35213C6CD52C4D /* Any.pbobjc.h in Headers */, + 241CC3B9355E06FA8C2752303C0D4E63 /* Api.pbobjc.h in Headers */, + 191D5454A6E5D2656B0505996BC20951 /* Duration.pbobjc.h in Headers */, + 817250CF85CC2E456BBD802C713FAAD2 /* Empty.pbobjc.h in Headers */, + 5F44773753D3041C24DFC20E0F678BCC /* FieldMask.pbobjc.h in Headers */, + D3FB43A0B478FE43C47E4BDFADD4E4E0 /* GPBArray.h in Headers */, + A98833727BA1BA414BF17A794EBF3B2C /* GPBArray_PackagePrivate.h in Headers */, + 7AF99B9C61C2B3E2092007A851A669A0 /* GPBBootstrap.h in Headers */, + 0C69A2DA368B7E073F93242C1B3A125C /* GPBCodedInputStream.h in Headers */, + BCD3B81055C2DC578F9DADB0A5D48265 /* GPBCodedInputStream_PackagePrivate.h in Headers */, + 74401E5F3B22BF07478C2F13F23E2F72 /* GPBCodedOutputStream.h in Headers */, + 6D8E93AC07AEE6B6E8B0755086BD301E /* GPBCodedOutputStream_PackagePrivate.h in Headers */, + 7A87B89DE54C46CEA06F91E990307977 /* GPBDescriptor.h in Headers */, + 54322F729D2AFCC889938351E1499A39 /* GPBDescriptor_PackagePrivate.h in Headers */, + C71B1CE38FC2925A8E5FE0B06A126146 /* GPBDictionary.h in Headers */, + 67996068CB093C6261229BF195E9C68E /* GPBDictionary_PackagePrivate.h in Headers */, + 63092FF5A06D72EDA9082BBEE3C51AA6 /* GPBExtensionInternals.h in Headers */, + 10A4C4727FF43B561E26E7D56F08258D /* GPBExtensionRegistry.h in Headers */, + 54DD45180299C11D2BEF50D813586E9E /* GPBMessage.h in Headers */, + 8907CC037F680B2A55E2CF257278A2B1 /* GPBMessage_PackagePrivate.h in Headers */, + 09F887B8A75EFA836CF0A7345E593DBE /* GPBProtocolBuffers.h in Headers */, + EAECFCB1CAE1B441CABDC4E6522CD0DC /* GPBProtocolBuffers_RuntimeSupport.h in Headers */, + D95CA95E195C4DE64DB8A869EEA301F1 /* GPBRootObject.h in Headers */, + FD01A794D75B254E830836CBEFE881B5 /* GPBRootObject_PackagePrivate.h in Headers */, + 18882D0352FCC080F7927A00273D3BE0 /* GPBRuntimeTypes.h in Headers */, + 0696C527F29E507C0CFC9F803B3C4842 /* GPBUnknownField.h in Headers */, + 9FB3548BEAD5A95E08EC38F8B32BEDBF /* GPBUnknownField_PackagePrivate.h in Headers */, + E845993DC1F557382488296682338F79 /* GPBUnknownFieldSet.h in Headers */, + 84BBEE716AA163C45A238F76AB0876AA /* GPBUnknownFieldSet_PackagePrivate.h in Headers */, + AEA17548CCF3D43C0D4E69ACD6F9B16C /* GPBUtilities.h in Headers */, + 7EC72EBAD6CF9A4EACD0E23075B3D44E /* GPBUtilities_PackagePrivate.h in Headers */, + 00995FE26D9777744B2D4EAAE882FC2F /* GPBWellKnownTypes.h in Headers */, + 208FCE8574FEB129B0C7A3D98B64C6DF /* GPBWireFormat.h in Headers */, + AA31B4B5897EFBA3F5E657592F73D6BA /* SourceContext.pbobjc.h in Headers */, + 9192638012FD251F4D774E5A10FA08FE /* Struct.pbobjc.h in Headers */, + CD21F2D35D090736AA8650A31A3400A3 /* Timestamp.pbobjc.h in Headers */, + 1812C91DC3F6586CAA95E92062597183 /* Type.pbobjc.h in Headers */, + 857F14CBFA0F726866C9CBD1172A597E /* Wrappers.pbobjc.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - CE0260DE795B445A60AF5B3E8FCDA0E5 /* Headers */ = { + A4C26DBA32B795E9B40BD059C28ADCC7 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 24E69B01ED4721CD7DF024995C8B471B /* LRNAnimationViewManager.h in Headers */, - 40B38FCEAE98FA7E22E80A478382390D /* LRNContainerView.h in Headers */, + E7C2708DD5E9AB26B2AA63509D978C30 /* CameraFocusSquare.h in Headers */, + 9A62E8C1118A1CF929FD957AC63596EE /* FaceDetectorManagerMlkit.h in Headers */, + 6CE0B8E7937DFDDA4F7711C870EB8018 /* RCTCamera.h in Headers */, + F2D6FBEA9787957B00DC15CCF4CF03D0 /* RCTCameraManager.h in Headers */, + 9990D56BB52EC952476CCBC17F7EC774 /* RCTSensorOrientationChecker.h in Headers */, + E2C4CEF466CD0D6E6E2BEFBEE257197E /* RNCamera.h in Headers */, + F737EE04FE891A8FD3583A39D22EA782 /* RNCameraManager.h in Headers */, + 733DAD9AE09EB1C0A875ACB80204D671 /* RNCameraUtils.h in Headers */, + 381533F2AAEEDFC510A538FF9F2A6C70 /* RNFaceDetectorModuleMLKit.h in Headers */, + 85EC7669A4ED0B18EE6C6A233C05BD8D /* RNFileSystem.h in Headers */, + ACD06A14952B6F92B0B17A1E2ABCBCE1 /* RNImageUtils.h in Headers */, + 8906B1509CF40730BF06DF9AC6597F50 /* RNSensorOrientationChecker.h in Headers */, + 207E0800765ECFFD3065835C90326C25 /* TextDetectorManager.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - D42681AD85C4F54C92CE17F19AAB41A2 /* Headers */ = { + ABDEFD0AD75D94C787EAD2DB58DCB99B /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 77989694A92E2CDB79C0D659E4B46B0D /* GTMSessionFetcher.h in Headers */, - 535DAAA72BC855F5514686AAB426399F /* GTMSessionFetcherLogging.h in Headers */, - D13FB891E0B40056CA513244647EB941 /* GTMSessionFetcherService.h in Headers */, - 5B11245B0B3D367D144172E1A32363A6 /* GTMSessionUploadFetcher.h in Headers */, + 5A9B64DE9ACE2179EF597CB050C4027E /* FirebaseMessaging.h in Headers */, + 0D88059BBAE92AB7E5AB70AB318CAA18 /* FirebaseMessaging.h in Headers */, + 7D8F8F119064991E7675A6AF1B761CEC /* FIRMessaging.h in Headers */, + B6F4CE2FE44E2AB13AE4AFA9FF29E330 /* FIRMessaging_Private.h in Headers */, + BBA7E64A68AC870C231D1B21432779F4 /* FIRMessagingAnalytics.h in Headers */, + 4E04F4461634D567642EA6962129DF56 /* FIRMessagingCheckinService.h in Headers */, + 35EBF55A31D996B787D3297BC9C4253A /* FIRMessagingClient.h in Headers */, + 5C536868F97347DAFE85E5F1A9D7E703 /* FIRMessagingCodedInputStream.h in Headers */, + 3CD7060DB1BCCB81C1ECDB3F966E83EC /* FIRMessagingConnection.h in Headers */, + F416848DC50BB98C8D95E9847547132E /* FIRMessagingConstants.h in Headers */, + 698989DB531ABBE31DF0EE7FCC06B5EC /* FIRMessagingContextManagerService.h in Headers */, + 6A2E01FF96B5E0C3553A9664F7E6DB9F /* FIRMessagingDataMessageManager.h in Headers */, + 2CB7DA6A77C07E2F009CA3F6D092B0F4 /* FIRMessagingDefines.h in Headers */, + 4D3B9204EEEB72B24B2836C82C888ED9 /* FIRMessagingDelayedMessageQueue.h in Headers */, + B0384A9C10668031EDC4512205B58835 /* FIRMessagingInternalUtilities.h in Headers */, + 35587A5C06858B72C0737165795394A0 /* FIRMessagingLogger.h in Headers */, + 00524A4BD73D6CD43BDF8BF499EE8F56 /* FIRMessagingPacketQueue.h in Headers */, + 51A9173A7BBDA8AADDAEC4471E349EB3 /* FIRMessagingPendingTopicsList.h in Headers */, + 5E30825D0D6A418223D99C5A39E86068 /* FIRMessagingPersistentSyncMessage.h in Headers */, + 476EED1FBFB3E7267634CA0D0218AFB9 /* FIRMessagingPubSub.h in Headers */, + 6F249E16421FF3CD50ED7AB52C4E7C56 /* FIRMessagingPubSubRegistrar.h in Headers */, + 8F464C2DBA97E83917780375986EF33F /* FIRMessagingReceiver.h in Headers */, + 26811A6DC72238AE718CFFC9444C136C /* FIRMessagingRegistrar.h in Headers */, + 418A72CD642151047F5312E3C13DDF2A /* FIRMessagingRemoteNotificationsProxy.h in Headers */, + 7B5598FBF3B26C9029C358D2DC7C3819 /* FIRMessagingRmq2PersistentStore.h in Headers */, + 393E3145FDCB078EAFCCBBF827220547 /* FIRMessagingRmqManager.h in Headers */, + 95F7FD337EB8D0981F782A055F93602A /* FIRMessagingSecureSocket.h in Headers */, + A9A1D02A49F519BC127ABD3445C3E7DB /* FIRMessagingSyncMessageManager.h in Headers */, + E4E725D3F41BEA19B1A1F36D61C8D49F /* FIRMessagingTopicOperation.h in Headers */, + BEF2FA3DA4D477B34FF9A9E4F12D3DE0 /* FIRMessagingTopicsCommon.h in Headers */, + 25AF7086425AC0343EA8F2D9EFF017C5 /* FIRMessagingUtilities.h in Headers */, + 71C3353E24B694C0A9EBBBBE47F475A7 /* FIRMessagingVersionUtilities.h in Headers */, + 8A8B29120AC7C8F71729C0DCFB252FE6 /* FIRMMessageCode.h in Headers */, + 66BF62C47DFACA717140724C6C2B7AD9 /* GtalkCore.pbobjc.h in Headers */, + 6699843C7D1A90DDBA6780F27C89955F /* GtalkExtensions.pbobjc.h in Headers */, + FA44603A21F375502C05745A1B80D532 /* NSDictionary+FIRMessaging.h in Headers */, + C69CC5FCDB3AA6D5EA18C8DD6C86C8ED /* NSError+FIRMessaging.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - D9753F2975670BE0679F70306B16A1AC /* Headers */ = { + B2FB164423CA890A3D464D8A557AE8CE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 2AA1ACD56287D3AFC270EB76B734A008 /* Any.pbobjc.h in Headers */, - 113C0EDD61CA125B8B7FE574D5B67090 /* Api.pbobjc.h in Headers */, - 1D9E84720F3503DDC25EB251006D50D6 /* Duration.pbobjc.h in Headers */, - AAE1DE760605E8EF78EA34F40338E874 /* Empty.pbobjc.h in Headers */, - 4A4AC5A022F94AFD6FF930EBCDC87F8D /* FieldMask.pbobjc.h in Headers */, - 767122C90F0670EB48E34494F33F1FF8 /* GPBArray.h in Headers */, - 1B4299D321967434C09434EAFA59E8E1 /* GPBArray_PackagePrivate.h in Headers */, - 975EBA7C61C19031E2A7F37D60B5FFA7 /* GPBBootstrap.h in Headers */, - 78B924599AF584FFF2AA76F3267985C6 /* GPBCodedInputStream.h in Headers */, - BDF0004BF692F52CE420A0C207E5FB4D /* GPBCodedInputStream_PackagePrivate.h in Headers */, - BBC47AA70B4D9D828CECC02F073ECD57 /* GPBCodedOutputStream.h in Headers */, - 8F0F3E85B60E20C6F28A34288631A908 /* GPBCodedOutputStream_PackagePrivate.h in Headers */, - A88CE2EE2DB0CB5B02AD33A28198B549 /* GPBDescriptor.h in Headers */, - 92FD956D21F164CAD096A04461BFC0F9 /* GPBDescriptor_PackagePrivate.h in Headers */, - E9CA94D7F3110CBD58BF6523AC8298FF /* GPBDictionary.h in Headers */, - 7738ED46BFCE6891BB77C6B5D70BD938 /* GPBDictionary_PackagePrivate.h in Headers */, - 207672B473D80D3BB473D689023943B1 /* GPBExtensionInternals.h in Headers */, - 1D906B4694503ED48E3C565168422D39 /* GPBExtensionRegistry.h in Headers */, - D2DC4E0ADFCD5EC47BB16F230C44668D /* GPBMessage.h in Headers */, - 29DD921BB3B17D7968BE6C8BD2E5683D /* GPBMessage_PackagePrivate.h in Headers */, - 4058877C728619A86988C0ABEB8810A5 /* GPBProtocolBuffers.h in Headers */, - 8EB92E8192ADF4B246C62B91283C3D36 /* GPBProtocolBuffers_RuntimeSupport.h in Headers */, - 8C808B338A2D5B045C899783338A148D /* GPBRootObject.h in Headers */, - E5D727851E73258ECB305EE470A4E462 /* GPBRootObject_PackagePrivate.h in Headers */, - 91B6E9B150C998D2A5DE3D4B7D3F8EA4 /* GPBRuntimeTypes.h in Headers */, - 97F016CD00542791C12D2A096ED7B08F /* GPBUnknownField.h in Headers */, - C369C72BAB144C122AA4BA9BECA20BB5 /* GPBUnknownField_PackagePrivate.h in Headers */, - 5E6DF8B8EC31FC15983978492CC7F857 /* GPBUnknownFieldSet.h in Headers */, - B6A02AAE01AF684E41919E284D2362F6 /* GPBUnknownFieldSet_PackagePrivate.h in Headers */, - C25197631119CCA0A326BBCFD7D808EC /* GPBUtilities.h in Headers */, - 459910DE0C8B132CEC7F35791180406F /* GPBUtilities_PackagePrivate.h in Headers */, - ED4D78E64525ADE4BF615623DBA76706 /* GPBWellKnownTypes.h in Headers */, - F2575DC1F39CB66ADC9013434AF377A6 /* GPBWireFormat.h in Headers */, - 5453AE886AA5A4606F93E83332084F4E /* SourceContext.pbobjc.h in Headers */, - 0DE9224FB0065B4509C6FA2B110C8660 /* Struct.pbobjc.h in Headers */, - 5A1E4E71C134D34A5A9435F54C6CAE86 /* Timestamp.pbobjc.h in Headers */, - 24B768F9FFB3410C9DFD4C97980FD3C6 /* Type.pbobjc.h in Headers */, - 1D240A1529A2347A227BE4E7F552A355 /* Wrappers.pbobjc.h in Headers */, + AD5FF55E1C183325F9D913C8E7DABAF9 /* SafariViewManager.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - DA974BA6F22F6C7311402B6ADC442E3E /* Headers */ = { + CBED29C375B8C6361BD85E4C78593D79 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 38549FF2BFA84F64582389CC9B659207 /* RNCAsyncStorage.h in Headers */, - 901690D2038CFADBCC94FDD88A405157 /* RNCAsyncStorageDelegate.h in Headers */, + 52337EECC6A00580652F91DA24A414F6 /* GTMDebugSelectorValidation.h in Headers */, + A662C3DA32720E5D5C32BAB10ED7AFE8 /* GTMDebugThreadValidation.h in Headers */, + 7860F7080050EF7E1CAEC963D6BB9626 /* GTMDefines.h in Headers */, + A097BF70F5016F732449B7763C60264F /* GTMLogger.h in Headers */, + 08B33987168B3086891B82A7664AAEE0 /* GTMMethodCheck.h in Headers */, + C2D1046A7C8F5C0A960F6412582EBC3F /* GTMNSData+zlib.h in Headers */, + 6A30FBDF51B3F81C00A7245E1FA6C99A /* GTMNSDictionary+URLArguments.h in Headers */, + 5AEAA2770B94FA077E506696F5EC45A1 /* GTMNSString+URLArguments.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - F43958A8AEB6C4029CC5131E55015722 /* Headers */ = { + CC4349147AB73ECB69A1019721B909B3 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 2ED0AF5ED5618ECAC7B02F71D3ABEE76 /* RCTFont+FA5.h in Headers */, - C4C9B17ADFBD94BC209E01AD28FEBD7D /* RNVectorIconsManager.h in Headers */, + A9D85E933B968789EC736ED00120ADDF /* RCTFont+FA5.h in Headers */, + 99E736CB491CB2C0B7EA28F0836917C7 /* RNVectorIconsManager.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - FA3ABE91CB7BC3E80480536379B7AFAD /* Headers */ = { + CE0260DE795B445A60AF5B3E8FCDA0E5 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 518A21F5438049FA77B03B1387C0BB67 /* FIRAnalyticsConfiguration+Internal.h in Headers */, - 8C531E68DE1BF4F0D03E2C3F692ACFCE /* FIRAnalyticsConfiguration.h in Headers */, - 75EEBD44FE7B165241FD8E1FFB708768 /* FIRApp.h in Headers */, - D72CC7409F3C3C1B0E8AD96F026CA241 /* FIRAppAssociationRegistration.h in Headers */, - 81B7947A7E981BBD9FAFC8924255A3AF /* FIRAppInternal.h in Headers */, - 29B53D72A2C474743F36D0C986CAF507 /* FIRBundleUtil.h in Headers */, - 91B2F2C709B82E146808C5CF710B3DE8 /* FIRComponent.h in Headers */, - 68CCD068CED1BAADD51D5D47A63D1D16 /* FIRComponentContainer.h in Headers */, - 3422558EA4A5C9764EAB85B0BDD36FFF /* FIRComponentContainerInternal.h in Headers */, - 742281C7D04AC6B80894EF222BDE7D20 /* FIRComponentRegistrant.h in Headers */, - 004857B8EDE18599545AEBE6219B39F8 /* FIRComponentType.h in Headers */, - FF5EA79B055FA1C2946482473F16B254 /* FIRConfiguration.h in Headers */, - A4893101111408974D02EBD975429AB5 /* FIRCoreConfigurable.h in Headers */, - C21A98E93501CC570AE58686F99BCF08 /* FIRDependency.h in Headers */, - 56AD8769C79F40FBECB1B581095ACF62 /* FirebaseCore.h in Headers */, - 39E0F8505E13055AF532F52A6AF6E72B /* FIRErrorCode.h in Headers */, - A07F95E203275CBE3C2653D7C7E1E4D3 /* FIRErrors.h in Headers */, - 842F7AEDC26D4C513F77B346CD86F72E /* FIRLogger.h in Headers */, - 78B7CF9EFFAF48F6185834936FD96B7C /* FIRLoggerLevel.h in Headers */, - B9D5635A6CB3317489A433AD8F3E5A55 /* FIROptions.h in Headers */, - F5DA11E860A51716DE1972B23AC3D9CA /* FIROptionsInternal.h in Headers */, - C04B6F056C6373D30BD408B524112AA0 /* FIRVersion.h in Headers */, + 24E69B01ED4721CD7DF024995C8B471B /* LRNAnimationViewManager.h in Headers */, + 40B38FCEAE98FA7E22E80A478382390D /* LRNContainerView.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 0281128B8C9A5F3BC2777ABCC1353408 /* react-native-camera */ = { - isa = PBXNativeTarget; - buildConfigurationList = 17905515BD2398AC7775CB1C636ED24F /* Build configuration list for PBXNativeTarget "react-native-camera" */; - buildPhases = ( - 6385787502E866C0C8D3C81C3DD5D7C7 /* Headers */, - 6154ECAF16B902A28A60A7AEAF1132A9 /* Sources */, - E961A44EE560B97B80914051D0F98703 /* Frameworks */, + EA9DF2F829B381E714401EE26CACC722 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( ); - buildRules = ( + runOnlyForDeploymentPostprocessing = 0; + }; + EC30658B916752E267B1F22BDFBDACC9 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 2C29E7D93E37272F07A3F6F9C941B37E /* GULAppDelegateSwizzler.h in Headers */, + 095BF194C673E77F513C06B66353E944 /* GULAppDelegateSwizzler_Private.h in Headers */, + 9732B0DE5EA3561BFD43A8368A85DF13 /* GULAppEnvironmentUtil.h in Headers */, + E81B9C5922C86CADE4C0BB4A0E144ED3 /* GULLogger.h in Headers */, + A50CA0C7A4D385131AAEDC1A8A7C24DB /* GULLoggerCodes.h in Headers */, + 06A7EF5B3E9331AF1E79003C86A960D0 /* GULLoggerLevel.h in Headers */, + 303EA23E33C62D6F6714E4C5AC18D089 /* GULMutableDictionary.h in Headers */, + 97A2E00FB6CEA0718637CCA80D98D022 /* GULNetwork.h in Headers */, + 08C855353B1708C6A8407A4338406385 /* GULNetworkConstants.h in Headers */, + D6DD6E870187C3F6FDDFA71AABC2D3A2 /* GULNetworkLoggerProtocol.h in Headers */, + 1D3AB4D4C2FA8CA7CCD0A08F4605CCB8 /* GULNetworkMessageCode.h in Headers */, + 55AFE71F07AFEE984593CA7090B804E4 /* GULNetworkURLSession.h in Headers */, + 0011CF32452744A08A01D5E4095FE13C /* GULNSData+zlib.h in Headers */, + 52780D4B9C56D52EE4CBF8FF03CCCFF9 /* GULObjectSwizzler.h in Headers */, + E53C2294CA635D2BF10A0702DD11C0A9 /* GULOriginalIMPConvenienceMacros.h in Headers */, + 02E9B5F5339416091F82BFE526EA3F45 /* GULReachabilityChecker+Internal.h in Headers */, + BE8C849C929EAD47BE26881A32C245FB /* GULReachabilityChecker.h in Headers */, + CFB69C39DF772B3A3F42193E41CF8221 /* GULReachabilityMessageCode.h in Headers */, + C32A478BF8B93A4DDEB48D4507D845EE /* GULSwizzledObject.h in Headers */, + 81DEFFD2AFF1DD97B3E57CAF3B4F8AEA /* GULSwizzler.h in Headers */, + F6667591D04F15BA939CBC05ED9361D6 /* GULUserDefaults.h in Headers */, ); - dependencies = ( - 98908516E81F29A2119F4BEEF96D31DD /* PBXTargetDependency */, + runOnlyForDeploymentPostprocessing = 0; + }; + FEDC15AB5E7113204FF85A93AB1D3166 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + AA9DEA6E2D3B3BA20156D53AD5326703 /* IOS7Polyfill.h in Headers */, + 7BE23A0E9F3B65F69CAC388F67F52CC1 /* RNFetchBlob.h in Headers */, + 1E0B2798AE38AA61EBC4FB25B6E01E01 /* RNFetchBlobConst.h in Headers */, + A7F107EF618B19B159FBFDEE3C3F0FBA /* RNFetchBlobFS.h in Headers */, + C3F6AE1330A7FD090F4D91793AD9B67E /* RNFetchBlobNetwork.h in Headers */, + 2AF2E394BA7A6C2AD7D2D45E5638F52B /* RNFetchBlobProgress.h in Headers */, + A2F67B7957E1AE1B9A75F001BD746C99 /* RNFetchBlobReqBuilder.h in Headers */, + 8AD5227F67EE14DDD28699B584155B36 /* RNFetchBlobRequest.h in Headers */, ); - name = "react-native-camera"; - productName = "react-native-camera"; - productReference = 5F5F4DDD9BFE4308D4946C6C56152D8D /* libreact-native-camera.a */; - productType = "com.apple.product-type.library.static"; + runOnlyForDeploymentPostprocessing = 0; }; - 072080E8F57A5E595567C4EA8DA532F2 /* RNGestureHandler */ = { +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 0B288C19EF7E9BFFBF358F352E60AA3D /* GoogleToolboxForMac */ = { isa = PBXNativeTarget; - buildConfigurationList = 07EC1F6B9BEE2082CBD9BE5C5079D3C0 /* Build configuration list for PBXNativeTarget "RNGestureHandler" */; + buildConfigurationList = 4471AEED27AEDEAF3C943CB699E1C52F /* Build configuration list for PBXNativeTarget "GoogleToolboxForMac" */; buildPhases = ( - 22FAE8EC55151AB82B53D9B0ADB2BA4D /* Headers */, - F52D434AE8559F9A0EBAF56828EEEFAF /* Sources */, - 1D381A28CB62C6CA220B58A3310B3574 /* Frameworks */, + CBED29C375B8C6361BD85E4C78593D79 /* Headers */, + 2D3D8677E3FF68A38B6DB76A4D1F42A9 /* Sources */, + 7D40F8656597D2EFC3CE6019B1A8500B /* Frameworks */, ); buildRules = ( ); dependencies = ( - 0BD4D238BC6B4C4802C6E0DAD1E764F9 /* PBXTargetDependency */, ); - name = RNGestureHandler; - productName = RNGestureHandler; - productReference = 6A4D82D6621A33F2E46CCD53AADF6195 /* libRNGestureHandler.a */; + name = GoogleToolboxForMac; + productName = GoogleToolboxForMac; + productReference = 473DDD131AFF23C0382BA90B4DF19C03 /* libGoogleToolboxForMac.a */; productType = "com.apple.product-type.library.static"; }; - 11C54F681447111DE53C634CEDA6439B /* react-native-slider */ = { + 0E35C59D1F9DC4D53C36F02E9F5228F4 /* react-native-safari-view */ = { isa = PBXNativeTarget; - buildConfigurationList = 5CC475E75ACB3EA054E4190AEA9682D2 /* Build configuration list for PBXNativeTarget "react-native-slider" */; + buildConfigurationList = 84A6918C46136E15CD69044DD756F14B /* Build configuration list for PBXNativeTarget "react-native-safari-view" */; buildPhases = ( - B054694A7E9DC149D1F2A4DD1888AD0D /* Headers */, - 5DA76F166B46841FA166040566AB0DCC /* Sources */, - 47438DD2D0487D45BE909332AD8E354B /* Frameworks */, + B2FB164423CA890A3D464D8A557AE8CE /* Headers */, + B71A7E9A2808075FDF1D62248617A645 /* Sources */, + 152A76E04F6AC53412E56CEB51064439 /* Frameworks */, ); buildRules = ( ); dependencies = ( - 82DC79EE462BB2E75E63F79B8C101168 /* PBXTargetDependency */, + 31FD7B021E855574AD9D2B81C1F0D524 /* PBXTargetDependency */, ); - name = "react-native-slider"; - productName = "react-native-slider"; - productReference = 7E17028DBAA1E01FA284E0D1304048A7 /* libreact-native-slider.a */; + name = "react-native-safari-view"; + productName = "react-native-safari-view"; + productReference = F8D489213322E442845543761017E348 /* libreact-native-safari-view.a */; productType = "com.apple.product-type.library.static"; }; - 1656132E72FE6E162694B82A10950197 /* RNVectorIcons */ = { + 0F9B2847C94286E2198E137459CF5903 /* nanopb */ = { isa = PBXNativeTarget; - buildConfigurationList = 1B852014228F9600E7B980D35203ED8C /* Build configuration list for PBXNativeTarget "RNVectorIcons" */; + buildConfigurationList = A58F84E3BEDDCC54778F118917EEBD24 /* Build configuration list for PBXNativeTarget "nanopb" */; buildPhases = ( - F43958A8AEB6C4029CC5131E55015722 /* Headers */, - EA753332BC3963C26CF9538287ECBF7B /* Sources */, - 31EC555F8F1BD6AB0C1006609DE3E1B7 /* Frameworks */, + 7DD324ACDFF9DA24A6D40D0E375B293B /* Headers */, + E723948C206E2763F7AED71B2C8CFD4A /* Sources */, + 69FE1319C8BB95D6C049E26D83951D46 /* Frameworks */, ); buildRules = ( ); dependencies = ( - 032FB2B418CE844E3D61467DE7E0F56D /* PBXTargetDependency */, ); - name = RNVectorIcons; - productName = RNVectorIcons; - productReference = 9548E2A3E0F414AB329F84C569C84767 /* libRNVectorIcons.a */; + name = nanopb; + productName = nanopb; + productReference = 57BD04B505CC2C942D300E2F298F08D4 /* libnanopb.a */; productType = "com.apple.product-type.library.static"; }; 16BE0913B925E13F023F8ACADD6AEDAC /* BVLinearGradient */ = { @@ -6487,24 +8201,44 @@ ); name = BVLinearGradient; productName = BVLinearGradient; - productReference = 8025EF7DC44740DD0CC6704D3A07623E /* libBVLinearGradient.a */; + productReference = F0CBB45A9EF73E2FA4E38AE32898F09A /* libBVLinearGradient.a */; productType = "com.apple.product-type.library.static"; }; - 2A9CA5658E5FDBBD07A7FFEA95C4ECFA /* GTMSessionFetcher */ = { + 22BEF3F4E553CFCB4173F8D80CE8E88C /* Protobuf */ = { isa = PBXNativeTarget; - buildConfigurationList = 075A99C1769C88FC29ACCECA70C86FB7 /* Build configuration list for PBXNativeTarget "GTMSessionFetcher" */; + buildConfigurationList = FEDAE663F5DB1ACECF4FE1CA0CD3CC73 /* Build configuration list for PBXNativeTarget "Protobuf" */; buildPhases = ( - D42681AD85C4F54C92CE17F19AAB41A2 /* Headers */, - 29F50BDAC507C989A26C0D37A3DCC5C9 /* Sources */, - BBA59D1B2924626AF2F602604B2AF6CC /* Frameworks */, + A33B0F7F030D87D607530D83AB0BBD95 /* Headers */, + A17BF487543A8899347025F543457443 /* Sources */, + 7D8EDA6A26030D045F4C9E0F088E92D7 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); - name = GTMSessionFetcher; - productName = GTMSessionFetcher; - productReference = 09701DDB31B473B0CDAF79AE545802F4 /* libGTMSessionFetcher.a */; + name = Protobuf; + productName = Protobuf; + productReference = 2156A0B7B819CB97B539B49BE9C60221 /* libProtobuf.a */; + productType = "com.apple.product-type.library.static"; + }; + 23DF0A63500D3BD8E8BA84CFC260F48A /* FirebaseDatabase */ = { + isa = PBXNativeTarget; + buildConfigurationList = 319D7BE581977605775091B621A07C22 /* Build configuration list for PBXNativeTarget "FirebaseDatabase" */; + buildPhases = ( + 0288EF814D00879C90F07254681BC4AF /* Headers */, + 1703155358F77914CB84D074232327FE /* Sources */, + DE6A2CB668338A9531A84CDEA79EF211 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + CE9EB39FDB58090BDE9FDCCD4594C327 /* PBXTargetDependency */, + 9CE24EA7959487FFC2176F75076660E9 /* PBXTargetDependency */, + C0A00069CBF88BB652A94EC9AF1F23AD /* PBXTargetDependency */, + ); + name = FirebaseDatabase; + productName = FirebaseDatabase; + productReference = 56E453AAAE1E2456E2004FDD594E41AA /* libFirebaseDatabase.a */; productType = "com.apple.product-type.library.static"; }; 33E77AA8166EA35F2575BF105C979D6A /* lottie-ios */ = { @@ -6521,24 +8255,43 @@ ); name = "lottie-ios"; productName = "lottie-ios"; - productReference = 23B37EAAEEE6C1F0DE71D561FB401651 /* liblottie-ios.a */; + productReference = A440D20566AE68C23C77B6587694AFA4 /* liblottie-ios.a */; productType = "com.apple.product-type.library.static"; }; - 35B0CD518EC8B839AD44597B2B183B62 /* nanopb */ = { + 34D4E730D4CC6DE5A7BD20268CD434E5 /* RNGestureHandler */ = { isa = PBXNativeTarget; - buildConfigurationList = 41928B8F7CAF78A8CA3DC06AA919798E /* Build configuration list for PBXNativeTarget "nanopb" */; + buildConfigurationList = C84F7A20AE7F5D08CC5DD8D81F12E906 /* Build configuration list for PBXNativeTarget "RNGestureHandler" */; buildPhases = ( - 75401077A077A36DC576AE055CF6A41E /* Headers */, - 331E5AF7E79BF7913658E70A59E5AC6C /* Sources */, - 90F4EBD254EBCE9D4A448ABBBBB99572 /* Frameworks */, + 44EC45CBBE74A7C706D0980BF5716777 /* Headers */, + 51FB5160D6BFBEBCFB6014C936129B09 /* Sources */, + FD9C228956CE8EC9A4212BC42B38485E /* Frameworks */, ); buildRules = ( ); dependencies = ( + 0F825B85C73D5400B863AB048F2B8039 /* PBXTargetDependency */, ); - name = nanopb; - productName = nanopb; - productReference = 606DF439F68F15C4F56B9B3A5C083A7E /* libnanopb.a */; + name = RNGestureHandler; + productName = RNGestureHandler; + productReference = 6EF580D9928337F521B007EC45FC1F8C /* libRNGestureHandler.a */; + productType = "com.apple.product-type.library.static"; + }; + 38E5CE2978C5F628FBD76567E1CC36FC /* react-native-camera */ = { + isa = PBXNativeTarget; + buildConfigurationList = 15E25BD050E906581AC7356BD2DD942C /* Build configuration list for PBXNativeTarget "react-native-camera" */; + buildPhases = ( + A4C26DBA32B795E9B40BD059C28ADCC7 /* Headers */, + B4EFF81C8A2EC8CDC4915541B5B56C60 /* Sources */, + 4092503050BEFB74223828528389FF3B /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 6448F8A3E7B51E79B3350DCC2B4194A6 /* PBXTargetDependency */, + ); + name = "react-native-camera"; + productName = "react-native-camera"; + productReference = 8E702FAD5F5F374D2FC13FE47219A91C /* libreact-native-camera.a */; productType = "com.apple.product-type.library.static"; }; 3B5AC1FADCE6BE3D1139AD02B6901FD1 /* Pods-KalendTests */ = { @@ -6556,74 +8309,65 @@ ); name = "Pods-KalendTests"; productName = "Pods-KalendTests"; - productReference = 30EC85B249403A7FDD744964E3B64C8D /* libPods-KalendTests.a */; + productReference = 04050B383E0D612ACABF04B122699C1B /* libPods-KalendTests.a */; + productType = "com.apple.product-type.library.static"; + }; + 4348A814F8FBD3A06D1844F43CF5619D /* FirebaseMessaging */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4F9CCB851C9A390E108AF1336F7577A7 /* Build configuration list for PBXNativeTarget "FirebaseMessaging" */; + buildPhases = ( + ABDEFD0AD75D94C787EAD2DB58DCB99B /* Headers */, + 8B475820218ADE4DE68B145580BB9EE4 /* Sources */, + 4A91B5D8F0D608B69209E4D72BE0E5E6 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 6D647615C5D5E0534709B6166B22052D /* PBXTargetDependency */, + 39750D9A86FDEB43206A3F916A7FC632 /* PBXTargetDependency */, + 30BD86B131373002CCE71244FD15D268 /* PBXTargetDependency */, + 9C9C4FC7B288398AB97CA1D3BB505C38 /* PBXTargetDependency */, + F3E2A73B6DB5AE2478BAE71F9CA2A3A6 /* PBXTargetDependency */, + ); + name = FirebaseMessaging; + productName = FirebaseMessaging; + productReference = 0F678C71FCC584F339C700EF781734C9 /* libFirebaseMessaging.a */; productType = "com.apple.product-type.library.static"; }; - 448819EB6C064114FE58EBAA295670B1 /* FirebaseCore */ = { + 4C183470A0DE712E37357833C539A41C /* FirebaseCore */ = { isa = PBXNativeTarget; - buildConfigurationList = F6943DB6F35007357E4317601AD206CD /* Build configuration list for PBXNativeTarget "FirebaseCore" */; + buildConfigurationList = 96C0DBAE598FF9D41101845EB8FE801D /* Build configuration list for PBXNativeTarget "FirebaseCore" */; buildPhases = ( - FA3ABE91CB7BC3E80480536379B7AFAD /* Headers */, - FE432BD04A5268E4FA09199166298A97 /* Sources */, - FD09386DF33818CC62C305A2D8C9353E /* Frameworks */, + 617E2AC705F0B2406BD1DBE1CB18C6A0 /* Headers */, + 75B3340E4C797AF65561BE46AC2CFC39 /* Sources */, + B6D2CB6123695E2FE94D47773B390E0F /* Frameworks */, ); buildRules = ( ); dependencies = ( - 27A6DF758467632B070DEB8AC82A09BF /* PBXTargetDependency */, + 4E9BC44AA1D81985745181F6202027EE /* PBXTargetDependency */, ); name = FirebaseCore; productName = FirebaseCore; - productReference = AFFFC489744C1B215B7F1528408797BA /* libFirebaseCore.a */; + productReference = 806638551525BD116E464D867CA63D1B /* libFirebaseCore.a */; productType = "com.apple.product-type.library.static"; }; - 47492BF4D2C397E56EAAD1B6A3C49548 /* Pods-Kalend */ = { + 572A5F97CA1814DB67594FEEAA9160A1 /* RNVectorIcons */ = { isa = PBXNativeTarget; - buildConfigurationList = 25EBC5051EE154F1FCE20A19E60BC96B /* Build configuration list for PBXNativeTarget "Pods-Kalend" */; + buildConfigurationList = 4BC6C2898B88E8258014DB0CCFC4203A /* Build configuration list for PBXNativeTarget "RNVectorIcons" */; buildPhases = ( - 2188B3CE2A139A8ADDEF81C16463989B /* Headers */, - 71D0D4293F7FDE832B55C46D6BEB823D /* Sources */, - 71C938CCDAEB531F0F9E7B75AA3DF4C3 /* Frameworks */, + CC4349147AB73ECB69A1019721B909B3 /* Headers */, + DD4D1D79A068B9883C9FD5DBDB48F203 /* Sources */, + 30C5DFF2267426CEC40ECE5C02B32343 /* Frameworks */, ); buildRules = ( ); dependencies = ( - D8CC601D778EF44BFE3144C6A22FF660 /* PBXTargetDependency */, - F6DFEE56C188CC386E1F02C58AA786EC /* PBXTargetDependency */, - 7D2A42AFB1A1F796D13CC03E76697A15 /* PBXTargetDependency */, - C922F8F03220621A12710B46BB7BDFEF /* PBXTargetDependency */, - 87AF80D80305EE015C8D6A9FFF9FEA46 /* PBXTargetDependency */, - 3713E8112868440B7F93E3C7ABCDAEF4 /* PBXTargetDependency */, - E60AD53130EA91C6F253099805119F6A /* PBXTargetDependency */, - B9CC9A6FF2D4A8D3714D01CA9710F814 /* PBXTargetDependency */, - D97FB6648C4E6277CCA631197803C884 /* PBXTargetDependency */, - 9CA7B9283B639B40A6C2819B629270B6 /* PBXTargetDependency */, - E22F388532F96C2222C3D0FE5D6FB0C1 /* PBXTargetDependency */, - C8EE50750AECE9A7AAF226566994B22C /* PBXTargetDependency */, - 01BBB82997B50AE27316EC1572F0EFA7 /* PBXTargetDependency */, - DAD37E5B55D180545DABFA5687497C01 /* PBXTargetDependency */, - DC5DAE49351E0342EDE5EE284F43F519 /* PBXTargetDependency */, - 69577D3AED610A696F0ACC7794B84501 /* PBXTargetDependency */, - D8EF861CC600251048254834481C0822 /* PBXTargetDependency */, - FE4253924CD04C42F4A83DE23A5B56CA /* PBXTargetDependency */, - AA63200AE6CC68A1AD06622BDFC5E9C8 /* PBXTargetDependency */, - 5023D15380AEB4C0821C363AE203303C /* PBXTargetDependency */, - DBE6A1D4D327B59945C95F174E8FFEDD /* PBXTargetDependency */, - 97881C8E69BB3BBB18B70D8B61AA4F9E /* PBXTargetDependency */, - CAAA120969FA2C3F747FB5C80D9DCA4B /* PBXTargetDependency */, - 031CA24B8FEA4EB085FFA2176E39C302 /* PBXTargetDependency */, - 21AD593FC2D659E30497E5B58668E826 /* PBXTargetDependency */, - EFF6C4AC6232E9ADB4682C7C18966A13 /* PBXTargetDependency */, - D34BD7F383FE74DD86CFD364E7A649B7 /* PBXTargetDependency */, - 189E9CB0851D49EAE09837A9F90A7053 /* PBXTargetDependency */, - 4863ACE07182999839B947908C8D7A67 /* PBXTargetDependency */, - 6B3E65A8BDF77BC0F5045E53A4CDCDE7 /* PBXTargetDependency */, - 7BE41D2725FEBAD293C3F067A1B9F5D1 /* PBXTargetDependency */, - 83FE5DD92285CEB0E03327232E2E9160 /* PBXTargetDependency */, + C47C8D58971DFE236D090CA826CEDA99 /* PBXTargetDependency */, ); - name = "Pods-Kalend"; - productName = "Pods-Kalend"; - productReference = 476BF08F77E75BD5FA8165A67387DFF1 /* libPods-Kalend.a */; + name = RNVectorIcons; + productName = RNVectorIcons; + productReference = 22C6EE7C568060C47D4DD01B6A1DAA41 /* libRNVectorIcons.a */; productType = "com.apple.product-type.library.static"; }; 5E317F794B07662C390113F089191B83 /* lottie-react-native */ = { @@ -6642,25 +8386,7 @@ ); name = "lottie-react-native"; productName = "lottie-react-native"; - productReference = 5016614A2295D4A10CD95448B0578C11 /* liblottie-react-native.a */; - productType = "com.apple.product-type.library.static"; - }; - 6946D4B5CA576A1782B086978B485908 /* react-native-safari-view */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6A4DA9F8817669E27CB5A7C8FA7D2A26 /* Build configuration list for PBXNativeTarget "react-native-safari-view" */; - buildPhases = ( - 1AEA4100B603D4A9A933E2A9FCEA7404 /* Headers */, - C7C9FDC5490FB9246F9AFD670E1BCEC1 /* Sources */, - 647C8AE6E369AD2546B6E141A4DE3C5A /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 047A51CB8BB8B8BA79C857C15E7765DE /* PBXTargetDependency */, - ); - name = "react-native-safari-view"; - productName = "react-native-safari-view"; - productReference = C48F82AED30534365C1AFE10BA57DDD7 /* libreact-native-safari-view.a */; + productReference = 66A32C509A3E748E0848AB62683135DB /* liblottie-react-native.a */; productType = "com.apple.product-type.library.static"; }; 899724123EE938F93E535EDDF3D69EDA /* Folly */ = { @@ -6680,42 +8406,43 @@ ); name = Folly; productName = Folly; - productReference = A58EC44B09EEA53BA369716C9DF9497F /* libFolly.a */; + productReference = EAF0CF08241A3BDE4435A323BE22EE7A /* libFolly.a */; productType = "com.apple.product-type.library.static"; }; - 9D25FE822A25731CE0F3D6AAA7E16E67 /* RNCAsyncStorage */ = { + 8DB803987D7643D2F74BB781FE7E2C01 /* react-native-slider */ = { isa = PBXNativeTarget; - buildConfigurationList = A7FAF6F6747EDB5167ECD60B6741E25E /* Build configuration list for PBXNativeTarget "RNCAsyncStorage" */; + buildConfigurationList = B4FA9B94B441BA05D587CB38046BD183 /* Build configuration list for PBXNativeTarget "react-native-slider" */; buildPhases = ( - DA974BA6F22F6C7311402B6ADC442E3E /* Headers */, - C47BFF3863E0D5A9F0BF9321EE0FC129 /* Sources */, - 625BA5F353DFA668EBF6CC7762ECBF5F /* Frameworks */, + 5EECE20A051CDE842E85832655A8769A /* Headers */, + B5BBAA5CA99DA20DFED0BD3770D1654C /* Sources */, + 4AC3BE407B80D2D10F0CF78DAD07FCBC /* Frameworks */, ); buildRules = ( ); dependencies = ( - 6BDDD5E7EBA6C06086DC579313EE91C0 /* PBXTargetDependency */, + D112DE49FA7B07167DFD9C42ED7710EE /* PBXTargetDependency */, ); - name = RNCAsyncStorage; - productName = RNCAsyncStorage; - productReference = 05BDA139C28772B6669FAA49F8C210EC /* libRNCAsyncStorage.a */; + name = "react-native-slider"; + productName = "react-native-slider"; + productReference = B2D2639C87FF020213A738A3AB5154DA /* libreact-native-slider.a */; productType = "com.apple.product-type.library.static"; }; - 9E5688F66E67822336D226F99E7A6588 /* Protobuf */ = { + 9EAC38454747EC28EBFCFAA0097CC2F5 /* RNCAsyncStorage */ = { isa = PBXNativeTarget; - buildConfigurationList = 93F96ACEEE5FCD20472D40784A808CFD /* Build configuration list for PBXNativeTarget "Protobuf" */; + buildConfigurationList = 6360D91DFA01A8052B366CEEA7A26019 /* Build configuration list for PBXNativeTarget "RNCAsyncStorage" */; buildPhases = ( - D9753F2975670BE0679F70306B16A1AC /* Headers */, - AADF4DE744414D9508D99F2D5BAD2340 /* Sources */, - AD5905A0024A647FE5870184F282AD59 /* Frameworks */, + 919FD11BA85060F8EC39A4287B2DF2D1 /* Headers */, + 6E3698FCAEDCEF89E95CCCD0529EC8A4 /* Sources */, + BC25A11AFF5BF8A53FC9CCC527A31525 /* Frameworks */, ); buildRules = ( ); dependencies = ( + B224E3770BEF28F52BA0D94D9A95DBFD /* PBXTargetDependency */, ); - name = Protobuf; - productName = Protobuf; - productReference = 88364B23619E73D4CD113CC0E8460578 /* libProtobuf.a */; + name = RNCAsyncStorage; + productName = RNCAsyncStorage; + productReference = A1EC205FD86D69A4FA55F7CCCB1DBE80 /* libRNCAsyncStorage.a */; productType = "com.apple.product-type.library.static"; }; A6EE5F943783158E6136A310CB61F189 /* DoubleConversion */ = { @@ -6732,42 +8459,41 @@ ); name = DoubleConversion; productName = DoubleConversion; - productReference = FDDB7A507E51D22F70C1917483F1FF71 /* libDoubleConversion.a */; + productReference = CFA246E02267A79CF043A0C5D335BDFD /* libDoubleConversion.a */; productType = "com.apple.product-type.library.static"; }; - AA035077852F44007A1367BB990F195D /* GoogleToolboxForMac */ = { + A835F24A9AD839C08095DBDAC0B40225 /* GTMSessionFetcher */ = { isa = PBXNativeTarget; - buildConfigurationList = E87B8987703715DA718A87A20D959F0B /* Build configuration list for PBXNativeTarget "GoogleToolboxForMac" */; + buildConfigurationList = EF580C074815DB2948B6B0916525EDB8 /* Build configuration list for PBXNativeTarget "GTMSessionFetcher" */; buildPhases = ( - 4354827B6BB689FE680ACA302CC544C1 /* Headers */, - 772A8DDB2F70CD8A6DCE9D6977A8FE6F /* Sources */, - FE7852698FF29A79F0DD5BF99FE727B0 /* Frameworks */, + 53D7CBB750FDF9A7443B765461A6B4A0 /* Headers */, + E9668837795B7EF0D0D7D53C6594AE81 /* Sources */, + C1AEBAACD973D83F474032A098AD4C40 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); - name = GoogleToolboxForMac; - productName = GoogleToolboxForMac; - productReference = 317D105DF47B8D3BA7ED9A9D6EFBC466 /* libGoogleToolboxForMac.a */; + name = GTMSessionFetcher; + productName = GTMSessionFetcher; + productReference = 53D3D878BD14E11D645D0C2EBBDEABCD /* libGTMSessionFetcher.a */; productType = "com.apple.product-type.library.static"; }; - BBA0C24EDB3A4C12E5E9947993A25BDD /* rn-fetch-blob */ = { + B449DAF8AE800FB85E1F497B65EF9956 /* GoogleUtilities */ = { isa = PBXNativeTarget; - buildConfigurationList = C910F120266A0E277B7CBFFCD33C51C5 /* Build configuration list for PBXNativeTarget "rn-fetch-blob" */; + buildConfigurationList = D6212F3679BF9E059A9D82C8DF6EF03A /* Build configuration list for PBXNativeTarget "GoogleUtilities" */; buildPhases = ( - A691B34223825AC2405C7D2742BD9731 /* Headers */, - 404760AFB0E0FDE4EF177094CAF55271 /* Sources */, - 5B2CEB7E56EE8932114E71616A7DBF8B /* Frameworks */, + EC30658B916752E267B1F22BDFBDACC9 /* Headers */, + B3E4EBAAA4FF8C58DD94D33624A2D586 /* Sources */, + C86A89D38DE5A49A00199686A5394DBF /* Frameworks */, ); buildRules = ( ); dependencies = ( - 4D6FB8B919EE7D569F8E4F15CEB9412F /* PBXTargetDependency */, ); - name = "rn-fetch-blob"; - productName = "rn-fetch-blob"; - productReference = 4D058D7A841DF70FCA740AC480BBF35F /* librn-fetch-blob.a */; + name = GoogleUtilities; + productName = GoogleUtilities; + productReference = D86222299A69AD5898E1DD96FD18847F /* libGoogleUtilities.a */; productType = "com.apple.product-type.library.static"; }; BBA2DD90CC21A6145F49BEF817D76438 /* yoga */ = { @@ -6784,24 +8510,78 @@ ); name = yoga; productName = yoga; - productReference = BC243429357134BED3601064EB41CDC2 /* libyoga.a */; + productReference = A9A13C7FD650007FE0BC0CE9DAC2D0FE /* libyoga.a */; productType = "com.apple.product-type.library.static"; }; - BEFDC8279895EA5EC1BF281D21F9B15D /* GoogleUtilities */ = { + D8CB9CF69BB52ED6D1A37B51EA54DD5F /* Pods-Kalend */ = { isa = PBXNativeTarget; - buildConfigurationList = C7DB024E1DC497BCAC9996B471F53C97 /* Build configuration list for PBXNativeTarget "GoogleUtilities" */; + buildConfigurationList = 19FFB503DC56D25D481C6314DB9562C7 /* Build configuration list for PBXNativeTarget "Pods-Kalend" */; buildPhases = ( - ADBE7AE7BE9C029CD1FCDA1A4A003205 /* Headers */, - 94867334EE650756B2B2D11AC91503E8 /* Sources */, - 104222A4D84B286D6E9920E82D8F0389 /* Frameworks */, + EA9DF2F829B381E714401EE26CACC722 /* Headers */, + C1D7665F7DCB6E0F7874C556E7A1ED10 /* Sources */, + 55D6665E90D1201A33ADA0479D046B90 /* Frameworks */, ); buildRules = ( ); dependencies = ( + C7B77D7B01A09DE62FAC4D1F4945DAF3 /* PBXTargetDependency */, + 5C22BEEC38F30698F2F91D10A0E23538 /* PBXTargetDependency */, + 687724E8C5289161DABD0F9ABE44D724 /* PBXTargetDependency */, + 00C6B4CEFDB97FE4325D1D8F584357BD /* PBXTargetDependency */, + 38FBF4E6F588A532D17C29C40B38625F /* PBXTargetDependency */, + 6A3BFD31AAD4508378C8D3458F78441C /* PBXTargetDependency */, + 33EBFEBA79CFD1DCCE8F3FB2B2C8ABA1 /* PBXTargetDependency */, + 307FC17504F2FCE6239A4AEC078AB0DF /* PBXTargetDependency */, + 34EC5AD30A409B443EA34F8568AAAD28 /* PBXTargetDependency */, + 82083C0313AD4BE27A5BA8E848D9BC3D /* PBXTargetDependency */, + 3DE50CC468F8C6F8203E7C6366EBFB6E /* PBXTargetDependency */, + E88DBD10343207782F2569F3701BB0FD /* PBXTargetDependency */, + 495E243745B5A976E9D3A2A10EC60E73 /* PBXTargetDependency */, + 8130CB1AC041CD1542FB7BCC25A7CD79 /* PBXTargetDependency */, + 7A4643BF24BA4EAB3B3655607BBD97D0 /* PBXTargetDependency */, + BE2297E8900638C17120C3BB406FCEB5 /* PBXTargetDependency */, + A6F4873A20F124C29AD361B45DB20BA4 /* PBXTargetDependency */, + DE7316A58E7292DBB9A5E1762716DF87 /* PBXTargetDependency */, + E45EFBE90A195AE81F39BA17AD99472E /* PBXTargetDependency */, + 3ABC88942AAAC39AF75A630C23CB09D7 /* PBXTargetDependency */, + 0839F2DBA902F00225699940AB7B98F7 /* PBXTargetDependency */, + D1BB0E1B32DB70370BBD9EEA7BE763C4 /* PBXTargetDependency */, + EB21FC7055D75EAFF0B81C88279C5D38 /* PBXTargetDependency */, + 7CD9D8BF4AA1119BB0C7BD9FF31D99B4 /* PBXTargetDependency */, + 3DFC3493939C08E221A8B939F8FA68BF /* PBXTargetDependency */, + FC6D73F3A1883F01557E5A6A8396CADA /* PBXTargetDependency */, + 446617D452A04EFE3190081B25107263 /* PBXTargetDependency */, + 35AEE714B6DEB5C5B6A23C0E139D7694 /* PBXTargetDependency */, + 6E5D83430B6AD4A4DEC7B1D3D8EF237B /* PBXTargetDependency */, + 7B41BD946B2A87FA36B17E1DF3745278 /* PBXTargetDependency */, + 857A118DD2605C7C64A85AD51F715C56 /* PBXTargetDependency */, + 2DDB366C32704FDC4B03BFC14C894897 /* PBXTargetDependency */, + 2AD0BED2694826826E6842794E7A0CA2 /* PBXTargetDependency */, + 399734DCD139FD0BA892CAAD7EDAEFE8 /* PBXTargetDependency */, + C5181A0F5A2FA29177F19C8E651444A5 /* PBXTargetDependency */, + 2281E465EA28D5280F8DD473C6F2A71D /* PBXTargetDependency */, + 94D18AD9FFCA0C741D1B10A349B1800E /* PBXTargetDependency */, ); - name = GoogleUtilities; - productName = GoogleUtilities; - productReference = 21D92EBF9C5C9D2E24D5EDC4ECD86EB3 /* libGoogleUtilities.a */; + name = "Pods-Kalend"; + productName = "Pods-Kalend"; + productReference = 50AC883EF355F48FFDB198F26BF0DEB5 /* libPods-Kalend.a */; + productType = "com.apple.product-type.library.static"; + }; + DF4F838E6093604EE864818A37DBF3E2 /* leveldb-library */ = { + isa = PBXNativeTarget; + buildConfigurationList = D6DEDA99A356C9DD777ED7C1B5B71712 /* Build configuration list for PBXNativeTarget "leveldb-library" */; + buildPhases = ( + 9C64F0FFE7F69861E6F341F624554C28 /* Headers */, + 31542B70939D2D9610B6243647524DB6 /* Sources */, + 07E7A941F20E6C684896D27D143E92BE /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "leveldb-library"; + productName = "leveldb-library"; + productReference = 98914BC1DAECE76E6A8DAEEE16262925 /* libleveldb-library.a */; productType = "com.apple.product-type.library.static"; }; E1CAF37843DB75E7886034596F9D9B56 /* glog */ = { @@ -6818,7 +8598,7 @@ ); name = glog; productName = glog; - productReference = 9DD45A1FEE98B97FA742D24D7BFFB9F7 /* libglog.a */; + productReference = CFE63D481FB99B0508A809E105EAD9F3 /* libglog.a */; productType = "com.apple.product-type.library.static"; }; E1D8FCCB52D6F4883463C99656914BB4 /* React */ = { @@ -6840,7 +8620,25 @@ ); name = React; productName = React; - productReference = DB5B9375AA63B4948C38D7EFC02A0727 /* libReact.a */; + productReference = 46A977D12AD3E74855601EDFF339278D /* libReact.a */; + productType = "com.apple.product-type.library.static"; + }; + E6A6F5DA5057B74455DEBDE8988C3E7D /* rn-fetch-blob */ = { + isa = PBXNativeTarget; + buildConfigurationList = 39E104F50FCB816E256B211B5C63770F /* Build configuration list for PBXNativeTarget "rn-fetch-blob" */; + buildPhases = ( + FEDC15AB5E7113204FF85A93AB1D3166 /* Headers */, + D553A7CA11542A2888DD7D0D0667E926 /* Sources */, + 7EC51503EE0E00565D6033FC23B964C9 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + DF3C05EEF2C8BFBE8DA3BBB0F654799B /* PBXTargetDependency */, + ); + name = "rn-fetch-blob"; + productName = "rn-fetch-blob"; + productReference = 4EC7FACEF78343F1D452E765198F75FB /* librn-fetch-blob.a */; productType = "com.apple.product-type.library.static"; }; /* End PBXNativeTarget section */ @@ -6860,7 +8658,7 @@ en, ); mainGroup = CF1408CF629C7361332E53B88F7BD30C; - productRefGroup = E8911370D22C3BCD0D9ECD83A1475C8E /* Products */; + productRefGroup = AE32582820779A4ECAD915FC40AE90B1 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( @@ -6869,34 +8667,39 @@ ABA9A411BB5A359862E5F1AA6238278E /* Crashlytics */, A6EE5F943783158E6136A310CB61F189 /* DoubleConversion */, D35E9EC86D36A4C8BC1704199FDB3552 /* Fabric */, - A341D07F993BE980A2F73FF26D003F2F /* Firebase */, - F5E7779227CE35F03C5E86041DEC7C74 /* FirebaseABTesting */, - A4AC528160CC8177E6EB809461379FF8 /* FirebaseAnalytics */, - 448819EB6C064114FE58EBAA295670B1 /* FirebaseCore */, - F26DF4F6ADD5881D668DF81C6B3F05EF /* FirebaseInstanceID */, - A3197AFE21F0131BE3A6A49782BC6F1D /* FirebasePerformance */, - 26ECD05F13D8FDDE98B912F8EAD399E8 /* FirebaseRemoteConfig */, + 148A5443E43AD92241F7EC3C3A5FAF3B /* Firebase */, + BCE30BBC689F944FE7A82C1512D6FFA1 /* FirebaseABTesting */, + 0AC15EA33F402FC6A1A48C990993D7D8 /* FirebaseAnalytics */, + 2BE50E63279FC4B03758C99275E399D2 /* FirebaseAnalyticsInterop */, + 9164D8092E2D2FC2BAD1ABCC34521490 /* FirebaseAuthInterop */, + 4C183470A0DE712E37357833C539A41C /* FirebaseCore */, + 23DF0A63500D3BD8E8BA84CFC260F48A /* FirebaseDatabase */, + 7DB3B0B9490B6AF4860CC9317D5F5C54 /* FirebaseInstanceID */, + 4348A814F8FBD3A06D1844F43CF5619D /* FirebaseMessaging */, + 9E599700D610A70CDFA8E9AFF3FB9AE2 /* FirebasePerformance */, + 78D21D148001007DE3F837778E7D27F5 /* FirebaseRemoteConfig */, 899724123EE938F93E535EDDF3D69EDA /* Folly */, E1CAF37843DB75E7886034596F9D9B56 /* glog */, - F63F26AAC9E12A1E6BDEECB1B662C7E6 /* GoogleAppMeasurement */, + 2BA894431E6D4EC9D0D3602E2A926A36 /* GoogleAppMeasurement */, 2CA9E9CBD6D1591F4833D0AC9A6DE30D /* GoogleSignIn */, - AA035077852F44007A1367BB990F195D /* GoogleToolboxForMac */, - BEFDC8279895EA5EC1BF281D21F9B15D /* GoogleUtilities */, - 2A9CA5658E5FDBBD07A7FFEA95C4ECFA /* GTMSessionFetcher */, + 0B288C19EF7E9BFFBF358F352E60AA3D /* GoogleToolboxForMac */, + B449DAF8AE800FB85E1F497B65EF9956 /* GoogleUtilities */, + A835F24A9AD839C08095DBDAC0B40225 /* GTMSessionFetcher */, + DF4F838E6093604EE864818A37DBF3E2 /* leveldb-library */, 33E77AA8166EA35F2575BF105C979D6A /* lottie-ios */, 5E317F794B07662C390113F089191B83 /* lottie-react-native */, - 35B0CD518EC8B839AD44597B2B183B62 /* nanopb */, - 47492BF4D2C397E56EAAD1B6A3C49548 /* Pods-Kalend */, + 0F9B2847C94286E2198E137459CF5903 /* nanopb */, + D8CB9CF69BB52ED6D1A37B51EA54DD5F /* Pods-Kalend */, 3B5AC1FADCE6BE3D1139AD02B6901FD1 /* Pods-KalendTests */, - 9E5688F66E67822336D226F99E7A6588 /* Protobuf */, + 22BEF3F4E553CFCB4173F8D80CE8E88C /* Protobuf */, E1D8FCCB52D6F4883463C99656914BB4 /* React */, - 0281128B8C9A5F3BC2777ABCC1353408 /* react-native-camera */, - 6946D4B5CA576A1782B086978B485908 /* react-native-safari-view */, - 11C54F681447111DE53C634CEDA6439B /* react-native-slider */, - BBA0C24EDB3A4C12E5E9947993A25BDD /* rn-fetch-blob */, - 9D25FE822A25731CE0F3D6AAA7E16E67 /* RNCAsyncStorage */, - 072080E8F57A5E595567C4EA8DA532F2 /* RNGestureHandler */, - 1656132E72FE6E162694B82A10950197 /* RNVectorIcons */, + 38E5CE2978C5F628FBD76567E1CC36FC /* react-native-camera */, + 0E35C59D1F9DC4D53C36F02E9F5228F4 /* react-native-safari-view */, + 8DB803987D7643D2F74BB781FE7E2C01 /* react-native-slider */, + E6A6F5DA5057B74455DEBDE8988C3E7D /* rn-fetch-blob */, + 9EAC38454747EC28EBFCFAA0097CC2F5 /* RNCAsyncStorage */, + 34D4E730D4CC6DE5A7BD20268CD434E5 /* RNGestureHandler */, + 572A5F97CA1814DB67594FEEAA9160A1 /* RNVectorIcons */, BBA2DD90CC21A6145F49BEF817D76438 /* yoga */, ); }; @@ -7220,41 +9023,185 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 29F50BDAC507C989A26C0D37A3DCC5C9 /* Sources */ = { + 1703155358F77914CB84D074232327FE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - B98529C7D66A995B21D58F994EC2FA6B /* GTMSessionFetcher-dummy.m in Sources */, - 79857180ED795BB5CB039C7A5BF8B2EC /* GTMSessionFetcher.m in Sources */, - 0898F632F058F1EFE747AAE5ABCE184F /* GTMSessionFetcherLogging.m in Sources */, - 1BB162F77EF07D456CA73F81879435C9 /* GTMSessionFetcherService.m in Sources */, - 068CDE574D7E1A287ACCAD7BA8842B19 /* GTMSessionUploadFetcher.m in Sources */, + 8F9ACF806352B2AB444C4F6D70443F05 /* APLevelDB.mm in Sources */, + 56079FAB8E21B3AAC652DC6ED9D08FEA /* FAckUserWrite.m in Sources */, + CFB61C168BC344927165EB13CAB19648 /* FArraySortedDictionary.m in Sources */, + 588A9F60E27020FE274AFC471CFBE26E /* FAtomicNumber.m in Sources */, + 3C85E7A495858915F3BCFC3610A8250E /* FAuthTokenProvider.m in Sources */, + 94133703D188AD0DB8CF45DD53C193AD /* fbase64.c in Sources */, + 9DC31FF4D1BCB49D0496C43620E7A25B /* FCacheNode.m in Sources */, + C08F3E2A8A4D57C656663A87C27D2734 /* FCachePolicy.m in Sources */, + 9414CE4D67E3EEC035AEB00664A845F7 /* FCancelEvent.m in Sources */, + 1B14A0F2C1FBF67F2F46A65BD2579B27 /* FChange.m in Sources */, + 7DFF9E849F894AE3A958272EF9336CA6 /* FChildChangeAccumulator.m in Sources */, + AC8FDA0BA3363CF90B991B71CEB41539 /* FChildEventRegistration.m in Sources */, + 7891267E2488C0A9B31DFC513A2FF0E9 /* FChildrenNode.m in Sources */, + 351F5D91B1D126A2ADFC663C4E8E53EC /* FClock.m in Sources */, + 8186BE010DB761EB637830C2A44F1B7D /* FCompoundHash.m in Sources */, + 4016801FF6E76F859B9D3FA2D99A068F /* FCompoundWrite.m in Sources */, + 34CE447F524A02F5FCF1B0093165D006 /* FConnection.m in Sources */, + 55978B6781237651DB5C726C990C9CA0 /* FConstants.m in Sources */, + 5F48331C117925B91F2946F3989A9026 /* FDataEvent.m in Sources */, + E568519D546B77B516F43ADCC70BDD6C /* FEmptyNode.m in Sources */, + 372F9F22EB10D5348DD753FACF1FB309 /* FEventEmitter.m in Sources */, + CA93635F6353B0E0055DB4092575ED96 /* FEventGenerator.m in Sources */, + BF91E4224980166C1FD43C1B2C042A4A /* FEventRaiser.m in Sources */, + 524791447807C9424BCA2ADA65EB0643 /* FImmutableSortedDictionary.m in Sources */, + 2A1ADB3FDC4BA6F24D817AC296FB0C10 /* FImmutableSortedSet.m in Sources */, + 3F98B8875E41D625A3489AC61714ADF9 /* FImmutableTree.m in Sources */, + A42BBB11A5C8997E64C8BF3D1356F5B5 /* FIndex.m in Sources */, + A636ADD62E996BCB1B95D66C9C5F571D /* FIndexedFilter.m in Sources */, + BC393C4DDE70D3C35865A7AD04981F25 /* FIndexedNode.m in Sources */, + 04E8A137D31C8444BCAB64CF930254E9 /* FIRDatabase.m in Sources */, + A8BED7DDB2B23624B3C8105FC8C68AE2 /* FIRDatabaseComponent.m in Sources */, + 221B644D1156D99799E72B8C958FE0FE /* FIRDatabaseConfig.m in Sources */, + 6FF88CB95D0349D384DAF1346B5A6409 /* FIRDatabaseQuery.m in Sources */, + A3FA34C0EBF2B0B11F1B96B99650BBF2 /* FIRDatabaseReference.m in Sources */, + FCCA640086B52AB7992BEFCD487BC352 /* FIRDataSnapshot.m in Sources */, + 0159458829D14CFA3B1A8EA433536214 /* FirebaseDatabase-dummy.m in Sources */, + 25F9965077A811A694FC91D9DD09A6CC /* FIRMutableData.m in Sources */, + 52933337314D1D5F12D382FE35230BA3 /* FIRNoopAuthTokenProvider.m in Sources */, + C85CF22D871D5449F865A23FAD3041EF /* FIRRetryHelper.m in Sources */, + 70C446632296926808151BF809059293 /* FIRServerValue.m in Sources */, + 0B45B5BFEF42A5BCAA45EAD37D64BDFD /* FIRTransactionResult.m in Sources */, + 53DB5CF00DADBFC3CD7829A781D08F40 /* FKeepSyncedEventRegistration.m in Sources */, + 1547A4F603CBDB19B6918781F981CE8A /* FKeyIndex.m in Sources */, + E3E45784C42349DC19CDEBA6F2723512 /* FLeafNode.m in Sources */, + 7634E5D555C8491F5632E9522034FDA6 /* FLevelDBStorageEngine.m in Sources */, + 84CF740A031E631EE8CEF4F18B132F37 /* FLimitedFilter.m in Sources */, + C742832691B37699A04569E62272CC86 /* FListenComplete.m in Sources */, + 1440BA308E9797088BBF23DFC408DE4A /* FListenProvider.m in Sources */, + BBCA38B91FC76D5D9547779BF983F2B7 /* FLLRBEmptyNode.m in Sources */, + D9B00ED55275DB056D716D099687E078 /* FLLRBValueNode.m in Sources */, + 79FB8AF3EB23406E5613BA5B673EEC9C /* FMaxNode.m in Sources */, + EC6CE93A7FE2FF239CD63F63857648FF /* FMerge.m in Sources */, + 05ABB5DB0EE4C0DC0ADDAAE49552A11D /* FNamedNode.m in Sources */, + CB045B37225229F11C968518BD501053 /* FNextPushId.m in Sources */, + 94BF783D54086ABB0C8E2EBA25BDEA0A /* FOperationSource.m in Sources */, + 6F6C30FE3ED4302E998E217F6E9967D8 /* FOverwrite.m in Sources */, + 2A2736C2800E5A5B4E4D155DCF489D37 /* FParsedUrl.m in Sources */, + BF74BDFBA7BE313E3D85C3B23B606A3A /* FPath.m in Sources */, + 8A9F6D812AE8B6A23E4FB6155B76F304 /* FPathIndex.m in Sources */, + 71E25D9FB28C8A20DA17C354E3A0A241 /* FPendingPut.m in Sources */, + F68C38DCB827D5E869CCC4FD13FF5AD4 /* FPersistenceManager.m in Sources */, + F653F5E6B85800F4A5DA2D0E4C6644A2 /* FPersistentConnection.m in Sources */, + 6CBF0F9FC4DC93223523EE17B60407C6 /* FPriorityIndex.m in Sources */, + 1727F9AB5EF9BFBBF0BB453CAC47C9E1 /* FPruneForest.m in Sources */, + 2369FD32F05C8B6E8E7A38E7A3C5E8C1 /* FQueryParams.m in Sources */, + 030F8076C81CA14B3DB825893059A846 /* FQuerySpec.m in Sources */, + 4C21D8E9839706D96121600EAB64899D /* FRangedFilter.m in Sources */, + D706F00399FEFE632CFE106C61F1D233 /* FRangeMerge.m in Sources */, + 94D5ED4AB46F6CC15E37A8F6FF4097F2 /* FRepo.m in Sources */, + 75923621F395B10BCEC3D9787219CDBD /* FRepoInfo.m in Sources */, + 67D82F41B93EC9583720DF80CB07030D /* FRepoManager.m in Sources */, + C2082E35A195D1D20F2152704BAA78F7 /* FServerValues.m in Sources */, + 0A7B045E48E9CF3D0A0CA567C9B9F30C /* FSnapshotHolder.m in Sources */, + 9EA77067ABECD283E785F61F7B0D5ECE /* FSnapshotUtilities.m in Sources */, + D12D3AC0B2A4D2E429E6E9F06B669015 /* FSparseSnapshotTree.m in Sources */, + 3B208C191EA69C914E2BECEC92EBF410 /* FSRWebSocket.m in Sources */, + C9F84383BFD15ADB125B9A4B1E70E9E5 /* FStringUtilities.m in Sources */, + 89332FF66F6EC16A560B3B9970050FB8 /* FSyncPoint.m in Sources */, + C1DAABE4FA5E557B2B5D9AEB21097220 /* FSyncTree.m in Sources */, + 5CE87E371FB6152A3EE39064A8480030 /* FTrackedQuery.m in Sources */, + C317CD39213DD8F534ACCA5354A39B6A /* FTrackedQueryManager.m in Sources */, + 18DE3C2DFCB0573F8FC35223B2B6FBB0 /* FTransformedEnumerator.m in Sources */, + 2B209181F6867B90173C48D8DA4738A1 /* FTree.m in Sources */, + 400811EACC5D204617DAA35B7257A5AE /* FTreeNode.m in Sources */, + 6240D6CDB62655F6E6191ADED2DD268A /* FTreeSortedDictionary.m in Sources */, + 14BF6ABD26C32F3D61A2707A47AA6B7F /* FTreeSortedDictionaryEnumerator.m in Sources */, + DFF23735A94D669FDF9E6B52F36EEF20 /* FTupleBoolBlock.m in Sources */, + 0D9617148957D504733A57A44D3E019C /* FTupleCallbackStatus.m in Sources */, + 85FC10DA6CCDEF9EA132AD221D5D5282 /* FTupleFirebase.m in Sources */, + 91545C780A082E4E6B1794C84DAAFF89 /* FTupleNodePath.m in Sources */, + E36A3301796EDD8B74AF5AF15EE97879 /* FTupleObjectNode.m in Sources */, + 99CC6B7AEE677D3A7913B17C6BD2F631 /* FTupleObjects.m in Sources */, + D863BFB7CE4E154ECAD4996BDABE2CDD /* FTupleOnDisconnect.m in Sources */, + A158F39E402E377E64E38A81C6C1270B /* FTuplePathValue.m in Sources */, + 293BB08CC9F5E499DF00A4C55F84853A /* FTupleRemovedQueriesEvents.m in Sources */, + 15FAC076EB77082E0006FEA13452D038 /* FTupleSetIdPath.m in Sources */, + B4F179008CC73909CF82598A99C28B18 /* FTupleStringNode.m in Sources */, + B79C3B6226C6B20FECB963ADA18CEDFA /* FTupleTransaction.m in Sources */, + D65D11EF73E40819E2E5028A1D2732D3 /* FTupleTSN.m in Sources */, + C8EE6BCCF7E6B440F37A8660F6F6016E /* FTupleUserCallback.m in Sources */, + 3BB3CA8031EF8878556D57B628CD5AAA /* FUtilities.m in Sources */, + BD2A817F718848F261F55EFA6B60C1EF /* FValidation.m in Sources */, + 6A692343B8F323E574DD2E870F9AEEBC /* FValueEventRegistration.m in Sources */, + AE1F99DBE0CBEC8B2278E1F515C3A4B9 /* FValueIndex.m in Sources */, + 1B833AE3DC0C944C3EA54E9E892DA95E /* FView.m in Sources */, + 4A79307E67AA69448A4629069F0D7947 /* FViewCache.m in Sources */, + 7151734535AE1DDC2F81A35828AFC079 /* FViewProcessor.m in Sources */, + 58FCFE9AA04828E2B937CD8857C49656 /* FViewProcessorResult.m in Sources */, + 8DDEB41D6176F58B173AE37206CDCCF4 /* FWebSocketConnection.m in Sources */, + 279C92D7F5977844581A912C3A82D7C8 /* FWriteRecord.m in Sources */, + B83139D9AA479A08013B8EAC827F325D /* FWriteTree.m in Sources */, + BFF393EB0908DD98477CE11C1F5FB2E8 /* FWriteTreeRef.m in Sources */, + 41B98E539FC994EA91307583A755702F /* NSData+SRB64Additions.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 331E5AF7E79BF7913658E70A59E5AC6C /* Sources */ = { + 2D3D8677E3FF68A38B6DB76A4D1F42A9 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - A760783CFAC0CC516FFBEA0512CFA9A0 /* nanopb-dummy.m in Sources */, - 095EBDCAEB6C94C96AEE7913022C8ABB /* pb_common.c in Sources */, - 3F396C524AC312BF7499E4DEC9F7DB4F /* pb_decode.c in Sources */, - 1CB3549EC6011B45D5E83E7168669E5B /* pb_encode.c in Sources */, + 93D28B57FAE0077A30CA494B9B88DFED /* GoogleToolboxForMac-dummy.m in Sources */, + CBBCB3FBC75D4172F2EE54FDA4EE229A /* GTMLogger.m in Sources */, + 8DE4F72442143404C46DEDCC929614C2 /* GTMNSData+zlib.m in Sources */, + ED7E5B87EE62D787243B4BB6970EAD08 /* GTMNSDictionary+URLArguments.m in Sources */, + 799F320DAC6CD7D929CE0AD9C26F8931 /* GTMNSString+URLArguments.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 404760AFB0E0FDE4EF177094CAF55271 /* Sources */ = { + 31542B70939D2D9610B6243647524DB6 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 35A691609E2C8E3C7CAEF04062D4E7D5 /* rn-fetch-blob-dummy.m in Sources */, - 1D7867B6EEB1DA95D0B6FA8FA1DFA384 /* RNFetchBlob.m in Sources */, - D2DFE3D6DE3F2D53905A0F6B6BEFBAA0 /* RNFetchBlobConst.m in Sources */, - 73EEB566925EC53FF283E67030464FF0 /* RNFetchBlobFS.m in Sources */, - 10DFED34F69F7B4A2F58B3E3163A8C03 /* RNFetchBlobNetwork.m in Sources */, - 7E9F92CA976CAE831CD1DEA5602FCB5A /* RNFetchBlobProgress.m in Sources */, - C2221EF953B6A275A90AE1054178F11F /* RNFetchBlobReqBuilder.m in Sources */, - E014D5970B9ED5F2E48A3C434D48DD34 /* RNFetchBlobRequest.m in Sources */, + B5271569774F9D2426B39569D9D940E6 /* arena.cc in Sources */, + 6761238C0810E18431677C55ABA8E015 /* block.cc in Sources */, + C7108FB8364507227C6CA793A340470B /* block_builder.cc in Sources */, + A0897AC1AC83BB160EFC7BB2A785F5B2 /* bloom.cc in Sources */, + D940B3E1BE2A8C583EABC60E7E29BE2F /* builder.cc in Sources */, + 9B50F719832219D70DC88A8857EB0D97 /* c.cc in Sources */, + F4DBBB88B5049150B427A3E39CC21412 /* cache.cc in Sources */, + 1F47120BCD4D42AD10B01FEA3746F6EC /* coding.cc in Sources */, + BD26F56BB67619862948EFB07852B5F2 /* comparator.cc in Sources */, + 9FCA82BA4CF3AFEC24C3C31AD3633FDF /* crc32c.cc in Sources */, + E3C3983950941BAF636880BAAAF9332F /* db_impl.cc in Sources */, + 9870BB0DD90BE40016CD8694A1971483 /* db_iter.cc in Sources */, + DD9A08C5B56E232AD3A85E04A8BE7476 /* dbformat.cc in Sources */, + E84B072BFC2DF6C35D4142110976F6A4 /* dumpfile.cc in Sources */, + 3453BF0E9C9C70124FE45009C2C1251F /* env.cc in Sources */, + ADEDC4DF2D4E4035B2C947DD10BA2979 /* env_posix.cc in Sources */, + 91329F83B642C7B66561408EEFC27CCE /* filename.cc in Sources */, + 710FDBA24280D878AC65B1E38B136324 /* filter_block.cc in Sources */, + A873DABF82824216B5CA0A5C387825E0 /* filter_policy.cc in Sources */, + 76503D48114EE373C53D1327D8CAE1F6 /* format.cc in Sources */, + 114204960494253B286F8D20B70266B6 /* hash.cc in Sources */, + 10FCB3538633CFC2D1500D3C8FC76704 /* histogram.cc in Sources */, + AD621C470BDA406C2E495990553F5483 /* iterator.cc in Sources */, + F42B49049E4BB0940AA0271967DF2765 /* leveldb-library-dummy.m in Sources */, + 37C9843EAA8C7A92FAABEA945B91AD52 /* log_reader.cc in Sources */, + 54F0AC4BFB6B3D650E4EC225819AEBFA /* log_writer.cc in Sources */, + 47EAF3F8F2BE25A3B1F941F5C4C7408B /* logging.cc in Sources */, + 4B524E786CEFA12D08176EAC89D948DB /* memtable.cc in Sources */, + 7387D76DE0A83A036759D86297D71E45 /* merger.cc in Sources */, + F347A71DDBB51EB0DB3E4E05268B6329 /* options.cc in Sources */, + DFB3B78A02C98D0E56889301764B5F2E /* port_posix.cc in Sources */, + BA20BD3928AD86CF78E62BC1F0ECFE09 /* port_posix_sse.cc in Sources */, + 17D94CD958531668B5323D9914BF061A /* repair.cc in Sources */, + 5DB35591B9D81A7B4DC4517FA43733FE /* status.cc in Sources */, + 2C10884E9CB2D15FB8D82FD6212124EC /* table.cc in Sources */, + 0E718ADDB309A4D725F1F0BA572CBE25 /* table_builder.cc in Sources */, + C9A49FC4C19A996CB95D8E94EF645DF3 /* table_cache.cc in Sources */, + 3C6A07B36306511C1651E54EA2E2290F /* testharness.cc in Sources */, + 31587B819DFDFA7BD0272A791452C77E /* testutil.cc in Sources */, + 4B90C3C897CF67577A7437789F658B8B /* two_level_iterator.cc in Sources */, + A16C4B4FB9FF63A9CF1C4E77E42056D8 /* version_edit.cc in Sources */, + 6293202483EED5142D5399921298F132 /* version_set.cc in Sources */, + 9A14841BA574F2ED53F5FDA20CAA6C38 /* write_batch.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7287,55 +9234,56 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 5DA76F166B46841FA166040566AB0DCC /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6E26435DC619D6F307CB0CEEE2C62E06 /* react-native-slider-dummy.m in Sources */, - 4C3B755D2C32658C1D18B6E8E3031103 /* RNCSlider.m in Sources */, - 97461377B2F7C42B59F5522C0A0B34AB /* RNCSliderManager.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 6154ECAF16B902A28A60A7AEAF1132A9 /* Sources */ = { + 51FB5160D6BFBEBCFB6014C936129B09 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - F92B5AD1E7A0563B3CD18C4F07C3792E /* CameraFocusSquare.m in Sources */, - A222B43688E53EBA4EF0088EC1033EE0 /* FaceDetectorManagerMlkit.m in Sources */, - AA4F8B6207CCDC02E4B1B3CEBC116CEF /* NSMutableDictionary+ImageMetadata.m in Sources */, - D08E5B14CEA0BD64B060AF27FBC6EFE5 /* RCTCamera.m in Sources */, - 4BF3F058D3837F4A3358A70733C4F688 /* RCTCameraManager.m in Sources */, - C9CD52BAC20DB985D0F13F4E30CF3C3B /* RCTSensorOrientationChecker.m in Sources */, - 47A53913D0B382C0D80B469FFBF660CF /* react-native-camera-dummy.m in Sources */, - 09AC03ECDABC095638CB230648C7547F /* RNCamera.m in Sources */, - 38AB8943C5A222E0AD60090C6E8DE89A /* RNCameraManager.m in Sources */, - CB91BC6A614FEA1761D3DF29C7AC3FF8 /* RNCameraUtils.m in Sources */, - 866ACB952AB4073CCB35404BF9AA2F1E /* RNFaceDetectorModuleMLKit.m in Sources */, - 588DAA4232F7A3F806BF582E894B427A /* RNFileSystem.m in Sources */, - 6C304831B984511F20CE8F70C6DBFAA4 /* RNImageUtils.m in Sources */, - C0691FE7A0B64FB402F3EF6D3D0ABD0A /* RNSensorOrientationChecker.m in Sources */, - AE76DBAE36EC283665C7E3B64C26770E /* TextDetectorManager.m in Sources */, + 0D0552E9454F72CAAC4909DB11D66FAB /* RNFlingHandler.m in Sources */, + 502C8A78D9714A90147D9131BE4E1CDD /* RNForceTouchHandler.m in Sources */, + C45FA57D0A067A2691D9E80552DB44F3 /* RNGestureHandler-dummy.m in Sources */, + B637C6DEC346BA280846FB413466A59A /* RNGestureHandler.m in Sources */, + 9D970E7F14AD5354C6B34125CC56EDA9 /* RNGestureHandlerButton.m in Sources */, + 3A3023A6A893126A1B8D609CBC06006A /* RNGestureHandlerEvents.m in Sources */, + BC46E2E7DEADFF1E8F759FAFD9559A7A /* RNGestureHandlerManager.m in Sources */, + 4C2EDA8799BA0432093C8C788F71B27A /* RNGestureHandlerModule.m in Sources */, + 78017A8BE60C6A30F93751BFE9CCFE91 /* RNGestureHandlerRegistry.m in Sources */, + 0B91DC9A47EE31399E4BD0A8D42002A2 /* RNLongPressHandler.m in Sources */, + ACB516F98412E6486ACD413DCA253CA4 /* RNNativeViewHandler.m in Sources */, + BFB6B29630E840DE00D213262622636B /* RNPanHandler.m in Sources */, + 97EBFD8B77ABC06936241133776D694E /* RNPinchHandler.m in Sources */, + D483F932471FE02FD203E158268CF117 /* RNRootViewGestureRecognizer.m in Sources */, + A43BA8363FE521EB75D09B3DDA60B300 /* RNRotationHandler.m in Sources */, + 75C9A545D28C8E2BD52C5F8E95B1F2EB /* RNTapHandler.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 71D0D4293F7FDE832B55C46D6BEB823D /* Sources */ = { + 6E3698FCAEDCEF89E95CCCD0529EC8A4 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4BF62E25C86EC98CB67CABF4D7871AA7 /* Pods-Kalend-dummy.m in Sources */, + 39580F89BFDCEF3B4F7F32BE6CC07C50 /* RNCAsyncStorage-dummy.m in Sources */, + DC1A393DB2798F10C1A8D6FAC9F1BD5A /* RNCAsyncStorage.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 772A8DDB2F70CD8A6DCE9D6977A8FE6F /* Sources */ = { + 75B3340E4C797AF65561BE46AC2CFC39 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 94DCBF40A4F479EA9020829BB72B2E45 /* GoogleToolboxForMac-dummy.m in Sources */, - E1D7CA508B6E16AA7151AE0C7BEFA777 /* GTMLogger.m in Sources */, - 913BDC332A99FC637B1B6909E821A416 /* GTMNSData+zlib.m in Sources */, - C3B3709DDBEB552F8063D0B1A7DE5302 /* GTMNSDictionary+URLArguments.m in Sources */, - BE64F3C6F12C659DF505C9076F9BFBA1 /* GTMNSString+URLArguments.m in Sources */, + 5746004E5CEDAE3B19A2444FA37A4573 /* FIRAnalyticsConfiguration.m in Sources */, + 23FB3862929BD283B99647F9D6E17D2F /* FIRApp.m in Sources */, + 8141FE90E4E672569BCFD55D85EDEF13 /* FIRAppAssociationRegistration.m in Sources */, + 18F2FD00D44717B5A30D767A9B256C54 /* FIRBundleUtil.m in Sources */, + 272899E3496F2E6562AFE9D6C392E24F /* FIRComponent.m in Sources */, + C866203D8E0177BE15C7E00F31299627 /* FIRComponentContainer.m in Sources */, + 56BEA8C64962C18023116E3314D84A8F /* FIRComponentType.m in Sources */, + 7F09CCC4EFA3B2DDDBB58B54DF0EB7DC /* FIRConfiguration.m in Sources */, + 5D82FEA63F7DB79FC729411E92D89003 /* FIRDependency.m in Sources */, + E7A3644332D3B6AED0EE5F0F91E9B6ED /* FirebaseCore-dummy.m in Sources */, + 5E37D63A65F2665B8D444C5FD1FE0A70 /* FIRErrors.m in Sources */, + 4CC2989A38F3B7AAFEA9DBDD31880224 /* FIRLogger.m in Sources */, + AA43729C187714D515D7FE3C1B11354A /* FIROptions.m in Sources */, + 0F5074B1FF0192FA923D054896E77DC5 /* FIRVersion.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7355,56 +9303,135 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 94867334EE650756B2B2D11AC91503E8 /* Sources */ = { + 8B475820218ADE4DE68B145580BB9EE4 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EAC3DB095EA4352E9E12CA7C586ADF6B /* FirebaseMessaging-dummy.m in Sources */, + 41ECA52F5717B6A4BB87E08098621E7B /* FIRMessaging.m in Sources */, + BDCED52C7A3F2F1279671112C21E3096 /* FIRMessagingAnalytics.m in Sources */, + DB5BB7ACF9E7B95476CA44906F412E08 /* FIRMessagingCheckinService.m in Sources */, + F3F8F8769841AD3DDC9C7AEE42EF2EDF /* FIRMessagingClient.m in Sources */, + A7AACA4AD8D93A99E7E043409100FBA1 /* FIRMessagingCodedInputStream.m in Sources */, + 151C3271555C04869065F339810D3BED /* FIRMessagingConnection.m in Sources */, + 284CCD4E7E54160A6FD950F88F7347C9 /* FIRMessagingConstants.m in Sources */, + 8D9F03CDF6A4835EB7987327D421F621 /* FIRMessagingContextManagerService.m in Sources */, + BBD4025AC8BA9F696C307FBE20EE565E /* FIRMessagingDataMessageManager.m in Sources */, + 5B4781A080ADFC278CCEA27F494DBF5C /* FIRMessagingDelayedMessageQueue.m in Sources */, + 324D272F5FBD1A1506DB7F33CF64785E /* FIRMessagingLogger.m in Sources */, + 6F91922DB8040D6B61FD0C95F2A551A3 /* FIRMessagingPacketQueue.m in Sources */, + 5EFFDD6C81BE995B2B349B431A51EF9F /* FIRMessagingPendingTopicsList.m in Sources */, + E71C91CB347F4BE5624A42E56E9FE60A /* FIRMessagingPersistentSyncMessage.m in Sources */, + 74F45499FDE9D20C016793B721D09C56 /* FIRMessagingPubSub.m in Sources */, + 0A89757B0FBF76C413A8E3538999FADB /* FIRMessagingPubSubRegistrar.m in Sources */, + 270E0EF9748250FCD58DECBDD5C6905C /* FIRMessagingReceiver.m in Sources */, + 199AEA2471224188FFFA9F144985A735 /* FIRMessagingRegistrar.m in Sources */, + 368678FD447F1882A39DDBBB1A6BBF32 /* FIRMessagingRemoteNotificationsProxy.m in Sources */, + A3FE696837871054FA7EC60E1855635B /* FIRMessagingRmq2PersistentStore.m in Sources */, + 4D69D43025D290FEC049F8FAF7616759 /* FIRMessagingRmqManager.m in Sources */, + B8DB12793BA68F37CDDA65A4BF2CF2F6 /* FIRMessagingSecureSocket.m in Sources */, + A9A7AE3F60384440A5C3C38988E7A685 /* FIRMessagingSyncMessageManager.m in Sources */, + 933A7C2D9883C6DDFCB8AAE58C2EB11A /* FIRMessagingTopicOperation.m in Sources */, + 33FC737D99CB664F8469C2EF22AB6401 /* FIRMessagingUtilities.m in Sources */, + 3CB8DC7F8D90272D3063BD44C82F98B1 /* FIRMessagingVersionUtilities.m in Sources */, + E0A6A324E0CD7F7F28506331798E4C55 /* GtalkCore.pbobjc.m in Sources */, + 029D8DB67C00749B223CDAA8A09EB537 /* GtalkExtensions.pbobjc.m in Sources */, + 58824627FAEA9EB0208A37401340CC43 /* NSDictionary+FIRMessaging.m in Sources */, + D215AD6BDEEF2A4C513B105F2B9A666F /* NSError+FIRMessaging.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A17BF487543A8899347025F543457443 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A86909B8D1589A118D5FAE0CC3AF6909 /* Any.pbobjc.m in Sources */, + 13AF2917A2AB285530C898D19FD5FBE1 /* Api.pbobjc.m in Sources */, + 6F1B9ACBE8AD95E9BDDDE9BBFAF9574E /* Duration.pbobjc.m in Sources */, + 232E6518F7E1415E4A10289578423A39 /* Empty.pbobjc.m in Sources */, + 239CF33B941EEB056E5C79A6FF11C5D0 /* FieldMask.pbobjc.m in Sources */, + ACCBC2D9DDB7F075D2871FEDDAE8E61A /* GPBArray.m in Sources */, + 28CCEA986134061B7478F0FD6F5D7FE6 /* GPBCodedInputStream.m in Sources */, + 1EA43B701259453AF35BF6528CBB82EE /* GPBCodedOutputStream.m in Sources */, + 93DB9ECC1508D87CF429CB9FB9EF8014 /* GPBDescriptor.m in Sources */, + 0D4563105FA05EAA82C5AE9CE75184D1 /* GPBDictionary.m in Sources */, + 617D495AFE507A66662D7EC64E37A6D8 /* GPBExtensionInternals.m in Sources */, + C84D6AB476E626EC66D86928DC232C73 /* GPBExtensionRegistry.m in Sources */, + 2E8C8CE8EF6685EC0DDE0CC252C74B5C /* GPBMessage.m in Sources */, + 3D19AF38C81F44DC071A53EC1425B920 /* GPBRootObject.m in Sources */, + F3FB9033D2F5EFC3A2B2399F46DCDF07 /* GPBUnknownField.m in Sources */, + 9F71E8D921990D444592A9FAF02E6985 /* GPBUnknownFieldSet.m in Sources */, + B8328AE0BD33C3D50767C20A1D425F39 /* GPBUtilities.m in Sources */, + 21C3FE327FEC922CDCF4B5B18EA09616 /* GPBWellKnownTypes.m in Sources */, + 78808235156CED3A97287975E76C6248 /* GPBWireFormat.m in Sources */, + B2751DECD00EF750F346B9B94D4DCE0D /* Protobuf-dummy.m in Sources */, + 4F0B93FF899904A5711D574AF8E3A134 /* SourceContext.pbobjc.m in Sources */, + 90ACBE3264A6FD02CEA37414106B9073 /* Struct.pbobjc.m in Sources */, + DC4F7559F6C5F2120786E2AE2A121444 /* Timestamp.pbobjc.m in Sources */, + DFEF7F5580CD6D24A03E9A899B8400E0 /* Type.pbobjc.m in Sources */, + 9BEFB6CBE2741A44637A81C16553EBA0 /* Wrappers.pbobjc.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B3E4EBAAA4FF8C58DD94D33624A2D586 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A7EB9C99ADE1F63274C86DA87DD90717 /* GoogleUtilities-dummy.m in Sources */, + 3AC98700186BF1FB0FEF8CFC48D97A0D /* GULAppDelegateSwizzler.m in Sources */, + 932376213FB869732DBE6FD1C053C4C1 /* GULAppEnvironmentUtil.m in Sources */, + 73A409A3B2F017BC99B3A8FCE2187821 /* GULLogger.m in Sources */, + D7E24A2389B49642273A6B595252C0FC /* GULMutableDictionary.m in Sources */, + 20B58413A50E7A7BE8872A76559ED5C2 /* GULNetwork.m in Sources */, + 9F054D9D250782B625DE731E3F73E135 /* GULNetworkConstants.m in Sources */, + BEFD6EFBE7043B3B33684FFE6C646033 /* GULNetworkURLSession.m in Sources */, + 64FBF91E9C36209D66272B6473D930B6 /* GULNSData+zlib.m in Sources */, + 1004C59ED1BCAF2EBD0CB48E6964B4CC /* GULObjectSwizzler.m in Sources */, + 4AEC1CCFE197D520A824CDB6ED734160 /* GULReachabilityChecker.m in Sources */, + 274312D3351FD48B5CD8882E96BCF66E /* GULSwizzledObject.m in Sources */, + 5D02A5078E708729C3F9D749D4CEC628 /* GULSwizzler.m in Sources */, + 6CE81693D166A4B948D52F6637C6DAF4 /* GULUserDefaults.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B4EFF81C8A2EC8CDC4915541B5B56C60 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DD96D9527958D87E78C92E117A9E26E3 /* CameraFocusSquare.m in Sources */, + 0E8934A02077C627F15C1B729DC97875 /* FaceDetectorManagerMlkit.m in Sources */, + F841D05C6B81E12385B0CA91684F708A /* NSMutableDictionary+ImageMetadata.m in Sources */, + 81ADD00A0DC1A56565A2E80AC1104FB7 /* RCTCamera.m in Sources */, + 6E18158E049EBF824FA9AFAEE97A5357 /* RCTCameraManager.m in Sources */, + 241ED6AA650FA0791AB94707CAF01F85 /* RCTSensorOrientationChecker.m in Sources */, + 01FDBC86ACD349EFE9DF650AD1D7A3B4 /* react-native-camera-dummy.m in Sources */, + DA6BC229F531E52A212D19DDA1D7AF58 /* RNCamera.m in Sources */, + 647E7F9E51FA44165F698391BEE948D9 /* RNCameraManager.m in Sources */, + 9E61001E55CCE2F0217924CA239BFC38 /* RNCameraUtils.m in Sources */, + 0E051C49EE13199602B2B1B98DFAE133 /* RNFaceDetectorModuleMLKit.m in Sources */, + 7BF0B37C33B2B53D2281C11319271108 /* RNFileSystem.m in Sources */, + 3E9183B650E1AB20EEF1809ABA7B31E9 /* RNImageUtils.m in Sources */, + 0409334A6926A0577CC18E548FEB1CA9 /* RNSensorOrientationChecker.m in Sources */, + 3DAB5A42B6624B6A1EDF6354774553DE /* TextDetectorManager.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B5BBAA5CA99DA20DFED0BD3770D1654C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - B46849FCC0BDF3343785C4018D2B2854 /* GoogleUtilities-dummy.m in Sources */, - 0E8D1C8FA1FEDB2271AA08A9B6D25315 /* GULAppDelegateSwizzler.m in Sources */, - 9E5E70C76DDC2E8EC3C8A47D03DAF14C /* GULAppEnvironmentUtil.m in Sources */, - 3532F3DAB77B7B0B94415EBEF72D586D /* GULLogger.m in Sources */, - F768EB69B38FFCE90EAB313B61FF5887 /* GULMutableDictionary.m in Sources */, - E6D375741B826C594B5D56A754E2BD2D /* GULNetwork.m in Sources */, - 7C106A1C989429BEED21855A31655120 /* GULNetworkConstants.m in Sources */, - 59D1C8039C0715353C070B15A246E60F /* GULNetworkURLSession.m in Sources */, - AE4FBA813AE92A84F89687F8E466B20C /* GULNSData+zlib.m in Sources */, - 731C4D68A06F7E56EBF410363D58BCD2 /* GULObjectSwizzler.m in Sources */, - C4A566ECED53CAECFC9919361DFDCA5B /* GULReachabilityChecker.m in Sources */, - 960446E73866EBE556C8AC9F7E528777 /* GULSwizzledObject.m in Sources */, - 4C1BD17233DF15565B66AC1002B822B3 /* GULSwizzler.m in Sources */, - B3407DB7C19CA83CA63E5AE22F944EAC /* GULUserDefaults.m in Sources */, + 90E728F7016943691BBCB3A450D8C437 /* react-native-slider-dummy.m in Sources */, + 218EC1E5AF8FC694688B4CEC4DCEFF6C /* RNCSlider.m in Sources */, + AFBACBCC096F84B09BD69AE023A938FE /* RNCSliderManager.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - AADF4DE744414D9508D99F2D5BAD2340 /* Sources */ = { + B71A7E9A2808075FDF1D62248617A645 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 98FB94D3BBBFE648A4E8F20B020D56EE /* Any.pbobjc.m in Sources */, - 28A4B31405FE402DEED1CC0A9FF0B97E /* Api.pbobjc.m in Sources */, - C5803C5384E0A0C7C21D6C1217497444 /* Duration.pbobjc.m in Sources */, - 3F505D52F2775E5B56A45D604B9809E4 /* Empty.pbobjc.m in Sources */, - 2EF1508AA88B71C7D1A6A5489D329A2E /* FieldMask.pbobjc.m in Sources */, - 15A8AE0D52B3F5431BE47EF807164724 /* GPBArray.m in Sources */, - B44F9943ACE5593D77A872BB114C61A5 /* GPBCodedInputStream.m in Sources */, - 14977F123A5E35A34F257F2D3E24C824 /* GPBCodedOutputStream.m in Sources */, - E0E28EBD3C58CBA48A5E6350B8B8DBB9 /* GPBDescriptor.m in Sources */, - 108E4098DEE3991E30A2DBBBBEF882B5 /* GPBDictionary.m in Sources */, - 277036B0E193297222AE3A6E9B117D03 /* GPBExtensionInternals.m in Sources */, - 35C1670ED33D110EE7F218369F07625D /* GPBExtensionRegistry.m in Sources */, - 64C38D840CA38F2FEB8EFB3F62BF5EE6 /* GPBMessage.m in Sources */, - BC3B14DAC4C329A5AE98396144F98D68 /* GPBRootObject.m in Sources */, - 341CEC20DEC87BE5AE1E6317E9A56461 /* GPBUnknownField.m in Sources */, - CBACB4C01B29DE7F8AB7B848BD5FE094 /* GPBUnknownFieldSet.m in Sources */, - C90689F01BAD94E908B25CF2DCE0E257 /* GPBUtilities.m in Sources */, - FBD357A04F657E0592174A70345E05F0 /* GPBWellKnownTypes.m in Sources */, - CE57855893FD21B83E44BDAD4B90E618 /* GPBWireFormat.m in Sources */, - F0B72793022B3003F6AB60A8CE0919E2 /* Protobuf-dummy.m in Sources */, - E3324DDB69FD906AC89A71F5732A1823 /* SourceContext.pbobjc.m in Sources */, - B1E8E0F6BB25F362479378657177F4AE /* Struct.pbobjc.m in Sources */, - FFEF1EF11C557EBE2D344D601B29A947 /* Timestamp.pbobjc.m in Sources */, - 2C5B58A5F6F1224217140FD062483195 /* Type.pbobjc.m in Sources */, - 00FE16F593D07181A9A4934A6ED5DB78 /* Wrappers.pbobjc.m in Sources */, + 6D3E3C6D6921ED5FA3228507212B9CBE /* react-native-safari-view-dummy.m in Sources */, + 60FF57BCE46DFA609230E4EF1E0454A3 /* SafariViewManager.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7416,21 +9443,36 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - C47BFF3863E0D5A9F0BF9321EE0FC129 /* Sources */ = { + C1D7665F7DCB6E0F7874C556E7A1ED10 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6DAF8B615791129D99F654AE376BDD68 /* Pods-Kalend-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D553A7CA11542A2888DD7D0D0667E926 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - D6C7269D8A0D8F472B91F5905B877DB8 /* RNCAsyncStorage-dummy.m in Sources */, - 466C9C104A7DB79159EE0AFBE1E6A270 /* RNCAsyncStorage.m in Sources */, + D0F0DA45E564DFEDAD5067A2F2968AC2 /* rn-fetch-blob-dummy.m in Sources */, + 8448F725BFA533F2D3B517AD3E9FF2E6 /* RNFetchBlob.m in Sources */, + CFE1D62AF406FD038F9BBBBE643D84F5 /* RNFetchBlobConst.m in Sources */, + 04AAF793E6858B1980475708D9FE5575 /* RNFetchBlobFS.m in Sources */, + 52A277F85AD4B99DB661878D45796BBA /* RNFetchBlobNetwork.m in Sources */, + 1BF3DE02228F77902B5CA540EF143AD0 /* RNFetchBlobProgress.m in Sources */, + 77CE0D11D86FE5D5EBAC5195D4EA6055 /* RNFetchBlobReqBuilder.m in Sources */, + C958B93EF63BDE2DA0736877037DFDAC /* RNFetchBlobRequest.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - C7C9FDC5490FB9246F9AFD670E1BCEC1 /* Sources */ = { + DD4D1D79A068B9883C9FD5DBDB48F203 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6487691A1771BB2427E6188D91B93BCB /* react-native-safari-view-dummy.m in Sources */, - 007E118C317B905A43396B0323494587 /* SafariViewManager.m in Sources */, + 56619F38A7BC40AADA3F656FB2E5A2D3 /* RCTFont+FA5.m in Sources */, + E5DE5D31EE76423F9F3422BB832C788F /* RNVectorIcons-dummy.m in Sources */, + E1EC2AE00609612EE09CE76F4A8B6A17 /* RNVectorIconsManager.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7457,13 +9499,26 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - EA753332BC3963C26CF9538287ECBF7B /* Sources */ = { + E723948C206E2763F7AED71B2C8CFD4A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9D7EA014500608934A4963922F753B05 /* nanopb-dummy.m in Sources */, + 148F2F17B90BD20BB3214D2015A932F9 /* pb_common.c in Sources */, + 0D346DEE3F2D9E165178E52003603F8F /* pb_decode.c in Sources */, + 251FCDD9F6CA1898D30BBB128BE7F5A7 /* pb_encode.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E9668837795B7EF0D0D7D53C6594AE81 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - F030B2233B200230A94C9EC48E0A3BA0 /* RCTFont+FA5.m in Sources */, - D42C1B204922084F4FEDCA451C14AA2E /* RNVectorIcons-dummy.m in Sources */, - CFD1D48B88C942CEC0DEF42980FE59F2 /* RNVectorIconsManager.m in Sources */, + ED7F989F9C32A7EFDE4C7D7B6FAA604A /* GTMSessionFetcher-dummy.m in Sources */, + 2901BD41C8E6A6945C6C665E0A2D1011 /* GTMSessionFetcher.m in Sources */, + 9E90684572D41461D288FE51A1C693C0 /* GTMSessionFetcherLogging.m in Sources */, + BB8D5849C5EB26EB4B819DD4E8F04E4A /* GTMSessionFetcherService.m in Sources */, + 069FA2E77E2E0D5E23854E8CFD038EC1 /* GTMSessionUploadFetcher.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7492,214 +9547,200 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - F52D434AE8559F9A0EBAF56828EEEFAF /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 358DE74C846604DA87BB2A091C689BB5 /* RNFlingHandler.m in Sources */, - 667E8435DCC183B4743FF5656F97D468 /* RNForceTouchHandler.m in Sources */, - 8102C51589B9D022052C49DAFF731DA9 /* RNGestureHandler-dummy.m in Sources */, - A9B5E1D410D9042BF45B47DD7139432F /* RNGestureHandler.m in Sources */, - 562D4A7195CC8F23EE349F87BFD87417 /* RNGestureHandlerButton.m in Sources */, - BD2FD845D5F8BE8221303C32BA1E2BCA /* RNGestureHandlerEvents.m in Sources */, - 1F80AB1E53B51BF7375739FF445BABBB /* RNGestureHandlerManager.m in Sources */, - 508E11B11F29BC7BD17A49FEB13A7C1C /* RNGestureHandlerModule.m in Sources */, - 114F9980661E4556B75B3388E0AD3F99 /* RNGestureHandlerRegistry.m in Sources */, - 23E05F69FA6772C85935F67EC707A13C /* RNLongPressHandler.m in Sources */, - 2DCAF7457114793D0E53E38156244CA0 /* RNNativeViewHandler.m in Sources */, - 53BF5793D93E75B8DD978A801BD918BD /* RNPanHandler.m in Sources */, - A93342B5FFECB35D60472961D8838F74 /* RNPinchHandler.m in Sources */, - 47457EE291003D4606CA4AD6ADEEC530 /* RNRootViewGestureRecognizer.m in Sources */, - D891A8BD4011E9F81950945388D37E2D /* RNRotationHandler.m in Sources */, - 2AA8F4AA0CB1F2038BE6D15B1877D1D1 /* RNTapHandler.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - FE432BD04A5268E4FA09199166298A97 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 705968212B3112EB4E8E3ED0C1534B49 /* FIRAnalyticsConfiguration.m in Sources */, - D558F66FD6ED01B2E74511EB48A9FE47 /* FIRApp.m in Sources */, - 2A1D2B93CB186F017A34FCBE34D42678 /* FIRAppAssociationRegistration.m in Sources */, - 4A78E99F1B0E53E2632BED6A6943ADD7 /* FIRBundleUtil.m in Sources */, - 6538ABA053492B6165992DEF46E9113B /* FIRComponent.m in Sources */, - DE66DA857A4E0DD7EEDE0D58F4E8A5F2 /* FIRComponentContainer.m in Sources */, - 8761E7B3DE15DDBEA0D14884181DD61A /* FIRComponentType.m in Sources */, - 0EE792D067B7B13B06BE0B12D8CDB0A8 /* FIRConfiguration.m in Sources */, - D78B51B22EE74B1B777D0F0D1ACDEBDE /* FIRDependency.m in Sources */, - 38775AA4A27AF2969C7BEB5021C5AC03 /* FirebaseCore-dummy.m in Sources */, - 9EA3342F9E7DC0CCB63BC931429BD2FA /* FIRErrors.m in Sources */, - EE71604A10EB3AC1C5393ADAFB01F291 /* FIRLogger.m in Sources */, - 31EF41C0572F951A5F47BE1C9BF51C93 /* FIROptions.m in Sources */, - 30BF73B5445EC0CDD63F7B5B17367C90 /* FIRVersion.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 018AD128DF54B9AB4618CB18CE2AD2B6 /* PBXTargetDependency */ = { + 00C6B4CEFDB97FE4325D1D8F584357BD /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = FirebaseRemoteConfig; - target = 26ECD05F13D8FDDE98B912F8EAD399E8 /* FirebaseRemoteConfig */; - targetProxy = C79749E337C3DB9C667C1BB8C74B0C9D /* PBXContainerItemProxy */; + name = Fabric; + target = D35E9EC86D36A4C8BC1704199FDB3552 /* Fabric */; + targetProxy = E3D44E4B82DCD0F3C07363AA86CB4571 /* PBXContainerItemProxy */; }; - 01BBB82997B50AE27316EC1572F0EFA7 /* PBXTargetDependency */ = { + 03F9511F6A531EA3AEA953D4410ABD72 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = GTMSessionFetcher; - target = 2A9CA5658E5FDBBD07A7FFEA95C4ECFA /* GTMSessionFetcher */; - targetProxy = B6AF5AC3E4EE099766D01F858F53CC89 /* PBXContainerItemProxy */; + name = React; + target = E1D8FCCB52D6F4883463C99656914BB4 /* React */; + targetProxy = 044602550C428E012CD1102E24540735 /* PBXContainerItemProxy */; }; - 031CA24B8FEA4EB085FFA2176E39C302 /* PBXTargetDependency */ = { + 05D410252F22C0FAE3B2D90D3EA3AE19 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = glog; - target = E1CAF37843DB75E7886034596F9D9B56 /* glog */; - targetProxy = 17E8F56727399A92144C65A800AA5A71 /* PBXContainerItemProxy */; + name = nanopb; + target = 0F9B2847C94286E2198E137459CF5903 /* nanopb */; + targetProxy = 7394770E6EC356D91E8F2550BE99D7A4 /* PBXContainerItemProxy */; }; - 032FB2B418CE844E3D61467DE7E0F56D /* PBXTargetDependency */ = { + 0839F2DBA902F00225699940AB7B98F7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = React; - target = E1D8FCCB52D6F4883463C99656914BB4 /* React */; - targetProxy = B1CB420F6321BE59C47DA8AE0AEC62E4 /* PBXContainerItemProxy */; + name = GoogleUtilities; + target = B449DAF8AE800FB85E1F497B65EF9956 /* GoogleUtilities */; + targetProxy = 2DFA37430FA4B98814AAE23106AB9BEA /* PBXContainerItemProxy */; }; - 03F9511F6A531EA3AEA953D4410ABD72 /* PBXTargetDependency */ = { + 0F825B85C73D5400B863AB048F2B8039 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = React; target = E1D8FCCB52D6F4883463C99656914BB4 /* React */; - targetProxy = 044602550C428E012CD1102E24540735 /* PBXContainerItemProxy */; + targetProxy = E42A1937BD55510C716F6E73DE9F135F /* PBXContainerItemProxy */; }; - 047A51CB8BB8B8BA79C857C15E7765DE /* PBXTargetDependency */ = { + 1C21237929C94F977985F3424B64116F /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = React; - target = E1D8FCCB52D6F4883463C99656914BB4 /* React */; - targetProxy = 36EB2D50CB8FC52A4D7016F523619A3B /* PBXContainerItemProxy */; + name = FirebaseCore; + target = 4C183470A0DE712E37357833C539A41C /* FirebaseCore */; + targetProxy = D3C9E32A012D1584F9F28FEF5D925D82 /* PBXContainerItemProxy */; }; - 07161E9C9601B867C9C6C2DAECB48860 /* PBXTargetDependency */ = { + 2281E465EA28D5280F8DD473C6F2A71D /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = Protobuf; - target = 9E5688F66E67822336D226F99E7A6588 /* Protobuf */; - targetProxy = DBDB4F15B5722CEE3B0183B8A512781C /* PBXContainerItemProxy */; + name = "rn-fetch-blob"; + target = E6A6F5DA5057B74455DEBDE8988C3E7D /* rn-fetch-blob */; + targetProxy = E717E1A20DBCA413E36929D674F5448B /* PBXContainerItemProxy */; }; - 09F29D433D76449E1E460E4D969BC8FF /* PBXTargetDependency */ = { + 241F3D50EC328E8CF63ECDB338E60067 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = FirebaseInstanceID; - target = F26DF4F6ADD5881D668DF81C6B3F05EF /* FirebaseInstanceID */; - targetProxy = 433ED0A60CD58BAE5D57832B60665C9A /* PBXContainerItemProxy */; + name = GoogleToolboxForMac; + target = 0B288C19EF7E9BFFBF358F352E60AA3D /* GoogleToolboxForMac */; + targetProxy = A39860F8EFD4538E4290A8E9DA7C63B2 /* PBXContainerItemProxy */; }; - 0BD4D238BC6B4C4802C6E0DAD1E764F9 /* PBXTargetDependency */ = { + 2594DD1AAC8CB8733951CEEA880E5855 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = React; - target = E1D8FCCB52D6F4883463C99656914BB4 /* React */; - targetProxy = 53E90F5BF12E0D9B1CD507CD4C8AA991 /* PBXContainerItemProxy */; + name = FirebaseDatabase; + target = 23DF0A63500D3BD8E8BA84CFC260F48A /* FirebaseDatabase */; + targetProxy = 6D38434C8B9B43CA8CF820D4829DD161 /* PBXContainerItemProxy */; }; - 1198565C7BC08D42BF953DC18F61741A /* PBXTargetDependency */ = { + 2AD0BED2694826826E6842794E7A0CA2 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = GoogleUtilities; - target = BEFDC8279895EA5EC1BF281D21F9B15D /* GoogleUtilities */; - targetProxy = 99A703C5BD2B30D15952CE937D2B7C0D /* PBXContainerItemProxy */; + name = "react-native-camera"; + target = 38E5CE2978C5F628FBD76567E1CC36FC /* react-native-camera */; + targetProxy = D460425A16079DEA23274B84CC308912 /* PBXContainerItemProxy */; }; - 189E9CB0851D49EAE09837A9F90A7053 /* PBXTargetDependency */ = { + 2DDB366C32704FDC4B03BFC14C894897 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = "react-native-camera"; - target = 0281128B8C9A5F3BC2777ABCC1353408 /* react-native-camera */; - targetProxy = 33C2E9A5FD7CA642BCDC3B7E5B5B2C05 /* PBXContainerItemProxy */; + name = nanopb; + target = 0F9B2847C94286E2198E137459CF5903 /* nanopb */; + targetProxy = 07017F15BEF5287A64F0220DB1D08954 /* PBXContainerItemProxy */; + }; + 307FC17504F2FCE6239A4AEC078AB0DF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseAnalyticsInterop; + target = 2BE50E63279FC4B03758C99275E399D2 /* FirebaseAnalyticsInterop */; + targetProxy = 165A25EF313B69CF952BA037C7D1C9E7 /* PBXContainerItemProxy */; + }; + 30BD86B131373002CCE71244FD15D268 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseInstanceID; + target = 7DB3B0B9490B6AF4860CC9317D5F5C54 /* FirebaseInstanceID */; + targetProxy = B20F5FB559C22D0844CF50F8428FD90B /* PBXContainerItemProxy */; + }; + 31FD7B021E855574AD9D2B81C1F0D524 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = React; + target = E1D8FCCB52D6F4883463C99656914BB4 /* React */; + targetProxy = 76BEF71A2C91FF8730DC067162C9463D /* PBXContainerItemProxy */; }; - 1BCB118B4796DF2D048EEFA5CE034DC8 /* PBXTargetDependency */ = { + 33EBFEBA79CFD1DCCE8F3FB2B2C8ABA1 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = FirebaseAnalytics; - target = A4AC528160CC8177E6EB809461379FF8 /* FirebaseAnalytics */; - targetProxy = EFAEDD1B332C752B8B578E55C9FF95BC /* PBXContainerItemProxy */; + target = 0AC15EA33F402FC6A1A48C990993D7D8 /* FirebaseAnalytics */; + targetProxy = 8765D467BAD6C49485EA8D888D4E9C08 /* PBXContainerItemProxy */; }; - 21AD593FC2D659E30497E5B58668E826 /* PBXTargetDependency */ = { + 34EC5AD30A409B443EA34F8568AAAD28 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = "lottie-ios"; - target = 33E77AA8166EA35F2575BF105C979D6A /* lottie-ios */; - targetProxy = 826DA3990E71645209FE690B16191537 /* PBXContainerItemProxy */; + name = FirebaseAuthInterop; + target = 9164D8092E2D2FC2BAD1ABCC34521490 /* FirebaseAuthInterop */; + targetProxy = 6641473F1758E11ECBE1EFDA32BF7355 /* PBXContainerItemProxy */; }; - 241F3D50EC328E8CF63ECDB338E60067 /* PBXTargetDependency */ = { + 35AEE714B6DEB5C5B6A23C0E139D7694 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = GoogleToolboxForMac; - target = AA035077852F44007A1367BB990F195D /* GoogleToolboxForMac */; - targetProxy = A39860F8EFD4538E4290A8E9DA7C63B2 /* PBXContainerItemProxy */; + name = glog; + target = E1CAF37843DB75E7886034596F9D9B56 /* glog */; + targetProxy = FD09B23FE363D8D94566CE666E63A6F7 /* PBXContainerItemProxy */; }; - 27A6DF758467632B070DEB8AC82A09BF /* PBXTargetDependency */ = { + 38FBF4E6F588A532D17C29C40B38625F /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = GoogleUtilities; - target = BEFDC8279895EA5EC1BF281D21F9B15D /* GoogleUtilities */; - targetProxy = 818964BAD6E300D1928522854B05E2BA /* PBXContainerItemProxy */; + name = Firebase; + target = 148A5443E43AD92241F7EC3C3A5FAF3B /* Firebase */; + targetProxy = ECB9F2E200E36C504BA8C8ADD7A94736 /* PBXContainerItemProxy */; }; - 287DE2DFE7610CCAA46FB3E8A3607A06 /* PBXTargetDependency */ = { + 39750D9A86FDEB43206A3F916A7FC632 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = FirebaseCore; - target = 448819EB6C064114FE58EBAA295670B1 /* FirebaseCore */; - targetProxy = 2A6C25E5EC6A66217F4B8F9380C6FF5A /* PBXContainerItemProxy */; + target = 4C183470A0DE712E37357833C539A41C /* FirebaseCore */; + targetProxy = A280861F2EB31AC1BD60B7F1814EEB08 /* PBXContainerItemProxy */; }; - 2E6CB9C9BEE70CEE324B4631A17B4E95 /* PBXTargetDependency */ = { + 399734DCD139FD0BA892CAAD7EDAEFE8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = FirebasePerformance; - target = A3197AFE21F0131BE3A6A49782BC6F1D /* FirebasePerformance */; - targetProxy = 6DC6454253B7115CB20E3B067A06A7DF /* PBXContainerItemProxy */; + name = "react-native-safari-view"; + target = 0E35C59D1F9DC4D53C36F02E9F5228F4 /* react-native-safari-view */; + targetProxy = A9F12D1969C28AE3BB2CED3522E7BF3E /* PBXContainerItemProxy */; }; - 35375E2BE56388EAD9941BBC63363378 /* PBXTargetDependency */ = { + 3ABC88942AAAC39AF75A630C23CB09D7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = GoogleUtilities; - target = BEFDC8279895EA5EC1BF281D21F9B15D /* GoogleUtilities */; - targetProxy = 8ACD8D635C06DACAAF5B5BBA0DDFC7DE /* PBXContainerItemProxy */; + name = GoogleToolboxForMac; + target = 0B288C19EF7E9BFFBF358F352E60AA3D /* GoogleToolboxForMac */; + targetProxy = 25350512A99EBD12FAAD0B86950275DD /* PBXContainerItemProxy */; }; - 3713E8112868440B7F93E3C7ABCDAEF4 /* PBXTargetDependency */ = { + 3DE50CC468F8C6F8203E7C6366EBFB6E /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = FirebaseABTesting; - target = F5E7779227CE35F03C5E86041DEC7C74 /* FirebaseABTesting */; - targetProxy = 130037C83D82796FEC7B502209D3AD18 /* PBXContainerItemProxy */; + name = FirebaseDatabase; + target = 23DF0A63500D3BD8E8BA84CFC260F48A /* FirebaseDatabase */; + targetProxy = A103EDE456171AC421F0ADC6CBFB1A82 /* PBXContainerItemProxy */; }; - 4863ACE07182999839B947908C8D7A67 /* PBXTargetDependency */ = { + 3DFC3493939C08E221A8B939F8FA68BF /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = "react-native-safari-view"; - target = 6946D4B5CA576A1782B086978B485908 /* react-native-safari-view */; - targetProxy = A4900E29090911B6944C226B269ADDF8 /* PBXContainerItemProxy */; + name = RNVectorIcons; + target = 572A5F97CA1814DB67594FEEAA9160A1 /* RNVectorIcons */; + targetProxy = 5C054B6E63DB8C7406BB0DC63B2A0FF9 /* PBXContainerItemProxy */; }; - 48C2E7E88B267941E71C0F6F69A30C35 /* PBXTargetDependency */ = { + 3F5EB2DB81CDED37B3361BB99E8B7D25 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = GTMSessionFetcher; - target = 2A9CA5658E5FDBBD07A7FFEA95C4ECFA /* GTMSessionFetcher */; - targetProxy = 7AB389380B6FD143D6DCA47C8D4464E3 /* PBXContainerItemProxy */; + name = FirebaseMessaging; + target = 4348A814F8FBD3A06D1844F43CF5619D /* FirebaseMessaging */; + targetProxy = EDD7B4B2478984DB8F9E2FF46E86B9CD /* PBXContainerItemProxy */; }; - 4B85A8FC745F31ADA349C4A208A245B8 /* PBXTargetDependency */ = { + 41B77CD58647CE1ED96510F606339EE1 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = FirebaseInstanceID; - target = F26DF4F6ADD5881D668DF81C6B3F05EF /* FirebaseInstanceID */; - targetProxy = DD71FE4534A57A8FE6BD5CA10318595A /* PBXContainerItemProxy */; + target = 7DB3B0B9490B6AF4860CC9317D5F5C54 /* FirebaseInstanceID */; + targetProxy = 827204C17F33E1EA71E4F9C489B27CF1 /* PBXContainerItemProxy */; }; - 4D6FB8B919EE7D569F8E4F15CEB9412F /* PBXTargetDependency */ = { + 446617D452A04EFE3190081B25107263 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = React; - target = E1D8FCCB52D6F4883463C99656914BB4 /* React */; - targetProxy = 468A9E61876A12241830676FABE908E1 /* PBXContainerItemProxy */; + name = "boost-for-react-native"; + target = 66641B93FAF80FF325B2D7B4AD85056F /* boost-for-react-native */; + targetProxy = FD8BC0BFAAA43ED5D4F3408AE35CD20F /* PBXContainerItemProxy */; }; - 5023D15380AEB4C0821C363AE203303C /* PBXTargetDependency */ = { + 4635A0D399850C0AB327AD8AE46ECF55 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = RNGestureHandler; - target = 072080E8F57A5E595567C4EA8DA532F2 /* RNGestureHandler */; - targetProxy = 6D2DAC509EA697FC7FC081C1CDCE5241 /* PBXContainerItemProxy */; + name = GoogleAppMeasurement; + target = 2BA894431E6D4EC9D0D3602E2A926A36 /* GoogleAppMeasurement */; + targetProxy = 055C1FB26957C70CA930C097B9D41EE3 /* PBXContainerItemProxy */; }; - 535A4AA3D01EC95C3ABB9B71CCD691FD /* PBXTargetDependency */ = { + 495E243745B5A976E9D3A2A10EC60E73 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = GoogleToolboxForMac; - target = AA035077852F44007A1367BB990F195D /* GoogleToolboxForMac */; - targetProxy = B4170BF0300D596478CC9CAF274B7460 /* PBXContainerItemProxy */; + name = FirebaseMessaging; + target = 4348A814F8FBD3A06D1844F43CF5619D /* FirebaseMessaging */; + targetProxy = 9599F034C4508616A585749184CDF334 /* PBXContainerItemProxy */; }; - 59EAA373AEED2AD2AC1542044F8CA2F9 /* PBXTargetDependency */ = { + 4E9BC44AA1D81985745181F6202027EE /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = GoogleUtilities; - target = BEFDC8279895EA5EC1BF281D21F9B15D /* GoogleUtilities */; - targetProxy = 88159EC956417A114FD2E5C69A232CD3 /* PBXContainerItemProxy */; + target = B449DAF8AE800FB85E1F497B65EF9956 /* GoogleUtilities */; + targetProxy = F49E7C9600A0E0D36A5F24FF3912CE94 /* PBXContainerItemProxy */; }; - 5D5B1FDFFB65E1286288F88B4B96208E /* PBXTargetDependency */ = { + 58CE038D1B4AF8508553ABD0DAD6A173 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = FirebaseCore; - target = 448819EB6C064114FE58EBAA295670B1 /* FirebaseCore */; - targetProxy = CBEAC6A9CFAD96974D677995381B9461 /* PBXContainerItemProxy */; + name = nanopb; + target = 0F9B2847C94286E2198E137459CF5903 /* nanopb */; + targetProxy = 88AA8DDE8001850D5953E8EF71ABBBC3 /* PBXContainerItemProxy */; + }; + 5C22BEEC38F30698F2F91D10A0E23538 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Crashlytics; + target = ABA9A411BB5A359862E5F1AA6238278E /* Crashlytics */; + targetProxy = 4D7F7F984C1BCFF55C72425264358F9B /* PBXContainerItemProxy */; + }; + 6050B2D9BA0734929EDD8F226A6BD721 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Protobuf; + target = 22BEF3F4E553CFCB4173F8D80CE8E88C /* Protobuf */; + targetProxy = DF97121A39547E4458BA4B8E63916D6E /* PBXContainerItemProxy */; }; 6164A9E2008751442209AD2E87CF8C1D /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -7707,35 +9748,59 @@ target = 66641B93FAF80FF325B2D7B4AD85056F /* boost-for-react-native */; targetProxy = 08D7D438CB5FE26AF1B363114EF78C45 /* PBXContainerItemProxy */; }; - 67C5620B74BC7A70371C9B446ADEE2D6 /* PBXTargetDependency */ = { + 63232F8D0E3FD13799CEB0727E503AAE /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = FirebaseCore; - target = 448819EB6C064114FE58EBAA295670B1 /* FirebaseCore */; - targetProxy = B6FDA52C375C94B67C0F2A61AA2B1C1B /* PBXContainerItemProxy */; + name = FirebaseRemoteConfig; + target = 78D21D148001007DE3F837778E7D27F5 /* FirebaseRemoteConfig */; + targetProxy = 8BA048E635A439A19CB234A359078FCD /* PBXContainerItemProxy */; }; - 69577D3AED610A696F0ACC7794B84501 /* PBXTargetDependency */ = { + 6448F8A3E7B51E79B3350DCC2B4194A6 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = GoogleToolboxForMac; - target = AA035077852F44007A1367BB990F195D /* GoogleToolboxForMac */; - targetProxy = 605B9F86A653094A9E5C304397430D79 /* PBXContainerItemProxy */; + name = React; + target = E1D8FCCB52D6F4883463C99656914BB4 /* React */; + targetProxy = 0585E951434FFC03181E338F67E1BB27 /* PBXContainerItemProxy */; }; - 6B3E65A8BDF77BC0F5045E53A4CDCDE7 /* PBXTargetDependency */ = { + 645DCB7BB6F21EE93BE79D5CF7FC3798 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = "react-native-slider"; - target = 11C54F681447111DE53C634CEDA6439B /* react-native-slider */; - targetProxy = 4B1162F8422C723A2AB51B19650CC967 /* PBXContainerItemProxy */; + name = FirebaseAnalytics; + target = 0AC15EA33F402FC6A1A48C990993D7D8 /* FirebaseAnalytics */; + targetProxy = BE4B618EA1C87B7407F38EB80CF67CCF /* PBXContainerItemProxy */; }; - 6BDDD5E7EBA6C06086DC579313EE91C0 /* PBXTargetDependency */ = { + 687724E8C5289161DABD0F9ABE44D724 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = React; - target = E1D8FCCB52D6F4883463C99656914BB4 /* React */; - targetProxy = 66296FA0C38BDDDA7FD308D9DCAA11E6 /* PBXContainerItemProxy */; + name = DoubleConversion; + target = A6EE5F943783158E6136A310CB61F189 /* DoubleConversion */; + targetProxy = FEA94A49C8485B2CD96D45C08DA6EA81 /* PBXContainerItemProxy */; }; - 7316EF72C63327D7391753E2FCDB3F10 /* PBXTargetDependency */ = { + 696D3DF9C0C4EFD982048B9F2D49214B /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = FirebaseAnalytics; - target = A4AC528160CC8177E6EB809461379FF8 /* FirebaseAnalytics */; - targetProxy = 03D5E3CB146BD621410E10452AC660A3 /* PBXContainerItemProxy */; + name = Protobuf; + target = 22BEF3F4E553CFCB4173F8D80CE8E88C /* Protobuf */; + targetProxy = D0F255E8A4D8412D21C13E4DCF0DFC96 /* PBXContainerItemProxy */; + }; + 6A3BFD31AAD4508378C8D3458F78441C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseABTesting; + target = BCE30BBC689F944FE7A82C1512D6FFA1 /* FirebaseABTesting */; + targetProxy = F3B12138923C78DD9F126326957A4D7B /* PBXContainerItemProxy */; + }; + 6AC712D73A2EDCD9F14E0AA6CA5C45EE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseInstanceID; + target = 7DB3B0B9490B6AF4860CC9317D5F5C54 /* FirebaseInstanceID */; + targetProxy = 5EF202B03DCCB385135B63BBD81BBE12 /* PBXContainerItemProxy */; + }; + 6D647615C5D5E0534709B6166B22052D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseAnalyticsInterop; + target = 2BE50E63279FC4B03758C99275E399D2 /* FirebaseAnalyticsInterop */; + targetProxy = 3D52552F79E8F53183A7115F981A71C2 /* PBXContainerItemProxy */; + }; + 6E5D83430B6AD4A4DEC7B1D3D8EF237B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "leveldb-library"; + target = DF4F838E6093604EE864818A37DBF3E2 /* leveldb-library */; + targetProxy = 34BDF333136B127463B035B6266E61B1 /* PBXContainerItemProxy */; }; 737E0389685E65E3B1A7CFCDA799797D /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -7749,17 +9814,29 @@ target = 66641B93FAF80FF325B2D7B4AD85056F /* boost-for-react-native */; targetProxy = 1CF6CA83FC898D6768010D18C0A8B185 /* PBXContainerItemProxy */; }; - 7BE41D2725FEBAD293C3F067A1B9F5D1 /* PBXTargetDependency */ = { + 7A0059DE399DDF95A59D26EA0E537ADC /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = "rn-fetch-blob"; - target = BBA0C24EDB3A4C12E5E9947993A25BDD /* rn-fetch-blob */; - targetProxy = AC7ACBEA5D5B57764908B4BD9B0B3180 /* PBXContainerItemProxy */; + name = GTMSessionFetcher; + target = A835F24A9AD839C08095DBDAC0B40225 /* GTMSessionFetcher */; + targetProxy = 790ADA83043201CD8786361319432367 /* PBXContainerItemProxy */; }; - 7D2A42AFB1A1F796D13CC03E76697A15 /* PBXTargetDependency */ = { + 7A4643BF24BA4EAB3B3655607BBD97D0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = DoubleConversion; - target = A6EE5F943783158E6136A310CB61F189 /* DoubleConversion */; - targetProxy = 660BBEBA587B135B30F122350115F0DF /* PBXContainerItemProxy */; + name = FirebaseRemoteConfig; + target = 78D21D148001007DE3F837778E7D27F5 /* FirebaseRemoteConfig */; + targetProxy = 5154F08CEE977135381277107A14A431 /* PBXContainerItemProxy */; + }; + 7B41BD946B2A87FA36B17E1DF3745278 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "lottie-ios"; + target = 33E77AA8166EA35F2575BF105C979D6A /* lottie-ios */; + targetProxy = FB47DA304027652B64AE4ED424B9B971 /* PBXContainerItemProxy */; + }; + 7CD9D8BF4AA1119BB0C7BD9FF31D99B4 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = RNGestureHandler; + target = 34D4E730D4CC6DE5A7BD20268CD434E5 /* RNGestureHandler */; + targetProxy = 74F344B729185361C75D88CBF1E5070A /* PBXContainerItemProxy */; }; 7DB167386435EDF08C5492D5556152D7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -7770,74 +9847,86 @@ 7E82EB579E39965ED6179AC31DF1A8A5 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = GTMSessionFetcher; - target = 2A9CA5658E5FDBBD07A7FFEA95C4ECFA /* GTMSessionFetcher */; + target = A835F24A9AD839C08095DBDAC0B40225 /* GTMSessionFetcher */; targetProxy = A772DB2DEF1D9E4FEBAC83250262F500 /* PBXContainerItemProxy */; }; - 82DC79EE462BB2E75E63F79B8C101168 /* PBXTargetDependency */ = { + 7EE34238BC1AB0CBD9493246BDDDA6EA /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = React; - target = E1D8FCCB52D6F4883463C99656914BB4 /* React */; - targetProxy = F188D5B9F9F22193AB2864E950B50A71 /* PBXContainerItemProxy */; + name = FirebasePerformance; + target = 9E599700D610A70CDFA8E9AFF3FB9AE2 /* FirebasePerformance */; + targetProxy = 1745ABEB8B749DCCE705B1911DD93BBA /* PBXContainerItemProxy */; }; - 83FE5DD92285CEB0E03327232E2E9160 /* PBXTargetDependency */ = { + 8130CB1AC041CD1542FB7BCC25A7CD79 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = yoga; - target = BBA2DD90CC21A6145F49BEF817D76438 /* yoga */; - targetProxy = CCA6A46CB98EDCA8F0A484DEE349AA32 /* PBXContainerItemProxy */; + name = FirebasePerformance; + target = 9E599700D610A70CDFA8E9AFF3FB9AE2 /* FirebasePerformance */; + targetProxy = 8EE00F482AD1A928EF29121006965526 /* PBXContainerItemProxy */; }; - 87AF80D80305EE015C8D6A9FFF9FEA46 /* PBXTargetDependency */ = { + 82083C0313AD4BE27A5BA8E848D9BC3D /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = Firebase; - target = A341D07F993BE980A2F73FF26D003F2F /* Firebase */; - targetProxy = 2D67EFBDD17B1FADDB737E05E9F08137 /* PBXContainerItemProxy */; + name = FirebaseCore; + target = 4C183470A0DE712E37357833C539A41C /* FirebaseCore */; + targetProxy = 353531F726EAB4EFB434186CC08E61A5 /* PBXContainerItemProxy */; }; - 89D37B9A59BA82AF5F8595D46AC525CD /* PBXTargetDependency */ = { + 83E92575B51FADF07C66CD5D39E2FFDB /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = Protobuf; - target = 9E5688F66E67822336D226F99E7A6588 /* Protobuf */; - targetProxy = 6DE73E05262B43D4DCF9ACE46B77089F /* PBXContainerItemProxy */; + name = FirebaseCore; + target = 4C183470A0DE712E37357833C539A41C /* FirebaseCore */; + targetProxy = 0C988D4B370B9D18F996A66B59E257C8 /* PBXContainerItemProxy */; }; - 8D93D4017D17D15BB6FD52DB84294B1A /* PBXTargetDependency */ = { + 857A118DD2605C7C64A85AD51F715C56 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = FirebaseABTesting; - target = F5E7779227CE35F03C5E86041DEC7C74 /* FirebaseABTesting */; - targetProxy = 17C73FE4E8B6BD6E5847E7A65959424E /* PBXContainerItemProxy */; + name = "lottie-react-native"; + target = 5E317F794B07662C390113F089191B83 /* lottie-react-native */; + targetProxy = 568AC389DEC1796DEC8D21794CE0B6A2 /* PBXContainerItemProxy */; }; - 9388F1F23BFADE712C75F5BDEAA06EA0 /* PBXTargetDependency */ = { + 86D889B041F7E595FBAE046CC787D662 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = nanopb; - target = 35B0CD518EC8B839AD44597B2B183B62 /* nanopb */; - targetProxy = B9435ED0F4941F85D0F89E9FA70F0E56 /* PBXContainerItemProxy */; + name = FirebaseCore; + target = 4C183470A0DE712E37357833C539A41C /* FirebaseCore */; + targetProxy = 0EA6186454DFA5E5027B8AF8BF1F9158 /* PBXContainerItemProxy */; }; - 97881C8E69BB3BBB18B70D8B61AA4F9E /* PBXTargetDependency */ = { + 94D18AD9FFCA0C741D1B10A349B1800E /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = React; - target = E1D8FCCB52D6F4883463C99656914BB4 /* React */; - targetProxy = 03178BFEA997093EF6683A1F0B4489E0 /* PBXContainerItemProxy */; + name = yoga; + target = BBA2DD90CC21A6145F49BEF817D76438 /* yoga */; + targetProxy = 81B2C1B5643D1AF65DDF39A9C4644527 /* PBXContainerItemProxy */; }; - 98908516E81F29A2119F4BEEF96D31DD /* PBXTargetDependency */ = { + 97DC854ECC23AE53EED18F23F9EADC75 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = React; - target = E1D8FCCB52D6F4883463C99656914BB4 /* React */; - targetProxy = FC8F0DABC455CC75718B2F6C5E985CAA /* PBXContainerItemProxy */; + name = FirebaseCore; + target = 4C183470A0DE712E37357833C539A41C /* FirebaseCore */; + targetProxy = FCADA1C246D524281444B9BAE6836669 /* PBXContainerItemProxy */; }; - 9A91D8F7CA5F7302D8B122AB074DFB5A /* PBXTargetDependency */ = { + 99133877B3B0C9462BE1707FEDB62F84 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = GoogleUtilities; - target = BEFDC8279895EA5EC1BF281D21F9B15D /* GoogleUtilities */; - targetProxy = AA327200248DBFB36D2BBAC897CD5EB7 /* PBXContainerItemProxy */; + name = FirebaseCore; + target = 4C183470A0DE712E37357833C539A41C /* FirebaseCore */; + targetProxy = 53275EEEA94F3F2DEABA5FEE4B8FF2F8 /* PBXContainerItemProxy */; }; - 9CA7B9283B639B40A6C2819B629270B6 /* PBXTargetDependency */ = { + 999CF551F4C68D6E905C34D7F5717F1C /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = FirebasePerformance; - target = A3197AFE21F0131BE3A6A49782BC6F1D /* FirebasePerformance */; - targetProxy = E46901E90592D634469CE4DCE7EA38BE /* PBXContainerItemProxy */; + name = FirebaseRemoteConfig; + target = 78D21D148001007DE3F837778E7D27F5 /* FirebaseRemoteConfig */; + targetProxy = 844D5C03EA44D954C33C790B98425EB9 /* PBXContainerItemProxy */; }; - 9D19122B5E4DE3B9F0DD533BFEAF970B /* PBXTargetDependency */ = { + 9B31EAC729458EF7767C1C47EEDCBED5 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = FirebaseInstanceID; - target = F26DF4F6ADD5881D668DF81C6B3F05EF /* FirebaseInstanceID */; - targetProxy = 406AC04BFBFE5DC8409426C754DF411F /* PBXContainerItemProxy */; + name = Protobuf; + target = 22BEF3F4E553CFCB4173F8D80CE8E88C /* Protobuf */; + targetProxy = 8241BAF8CFAD0F9034A2316EB7F1D844 /* PBXContainerItemProxy */; + }; + 9C9C4FC7B288398AB97CA1D3BB505C38 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = GoogleUtilities; + target = B449DAF8AE800FB85E1F497B65EF9956 /* GoogleUtilities */; + targetProxy = 4C7FE07ECC19AC40C456FAD1306F59EA /* PBXContainerItemProxy */; + }; + 9CE24EA7959487FFC2176F75076660E9 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseCore; + target = 4C183470A0DE712E37357833C539A41C /* FirebaseCore */; + targetProxy = 2CB55291D9E244FAC3981CDE051836A7 /* PBXContainerItemProxy */; }; A07AB94691667633BE76F54090FBCCE7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -7845,35 +9934,41 @@ target = BBA2DD90CC21A6145F49BEF817D76438 /* yoga */; targetProxy = EDD184E7F5C5EB03336DC93FFFC07E97 /* PBXContainerItemProxy */; }; + A23DDF850D4F67A06FFF5AC9BF8180ED /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = GoogleUtilities; + target = B449DAF8AE800FB85E1F497B65EF9956 /* GoogleUtilities */; + targetProxy = A8DD62FFD9EC22FD928DAF7B7E4AA3CF /* PBXContainerItemProxy */; + }; A587477D4690AB5C25ED6E7110EF1434 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = "lottie-ios"; target = 33E77AA8166EA35F2575BF105C979D6A /* lottie-ios */; targetProxy = 76490FC12387367CEE6489B60FD95F73 /* PBXContainerItemProxy */; }; - A8505B2488F52D479B8AFA5166E7CA44 /* PBXTargetDependency */ = { + A612A44EE60B08352A5CEE87DB2E224F /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = nanopb; - target = 35B0CD518EC8B839AD44597B2B183B62 /* nanopb */; - targetProxy = 5DF7529822BF64C712E80096320C508A /* PBXContainerItemProxy */; + name = GoogleUtilities; + target = B449DAF8AE800FB85E1F497B65EF9956 /* GoogleUtilities */; + targetProxy = 6D851FE011D10C8DC13C23DCA712B3CE /* PBXContainerItemProxy */; }; - AA63200AE6CC68A1AD06622BDFC5E9C8 /* PBXTargetDependency */ = { + A6F4873A20F124C29AD361B45DB20BA4 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = RNCAsyncStorage; - target = 9D25FE822A25731CE0F3D6AAA7E16E67 /* RNCAsyncStorage */; - targetProxy = 0FFD040E4348A9367B8C41C80C4140A1 /* PBXContainerItemProxy */; + name = GTMSessionFetcher; + target = A835F24A9AD839C08095DBDAC0B40225 /* GTMSessionFetcher */; + targetProxy = F16DA88CE2793B109BD5C1BD9F588A80 /* PBXContainerItemProxy */; }; - AC7472FB1F5606F13227D95744D8FA35 /* PBXTargetDependency */ = { + B224E3770BEF28F52BA0D94D9A95DBFD /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = GoogleUtilities; - target = BEFDC8279895EA5EC1BF281D21F9B15D /* GoogleUtilities */; - targetProxy = E7FE9CA07606EEEC87598BAAC48A9DCA /* PBXContainerItemProxy */; + name = React; + target = E1D8FCCB52D6F4883463C99656914BB4 /* React */; + targetProxy = DFC815EDB5C8E218FBD16DFFF5AB10BE /* PBXContainerItemProxy */; }; - B53DA27B35439C041D12AB993ED511C0 /* PBXTargetDependency */ = { + B3CB0C6F9F7940166124069220E93FEB /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = FirebaseCore; - target = 448819EB6C064114FE58EBAA295670B1 /* FirebaseCore */; - targetProxy = 1B0732705F2612B6C43B690D903E86F3 /* PBXContainerItemProxy */; + name = GoogleUtilities; + target = B449DAF8AE800FB85E1F497B65EF9956 /* GoogleUtilities */; + targetProxy = 13948C3EB8AC60908FC67251349170B5 /* PBXContainerItemProxy */; }; B8635BBD81EC5C604EDEEC0EB50FD38A /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -7881,113 +9976,113 @@ target = A6EE5F943783158E6136A310CB61F189 /* DoubleConversion */; targetProxy = 37FE4FF1FB3FB531FD2536A2321755CE /* PBXContainerItemProxy */; }; - B9CC9A6FF2D4A8D3714D01CA9710F814 /* PBXTargetDependency */ = { + BE2297E8900638C17120C3BB406FCEB5 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = FirebaseCore; - target = 448819EB6C064114FE58EBAA295670B1 /* FirebaseCore */; - targetProxy = E6F2C90842B0E24138D6E9E4F212A067 /* PBXContainerItemProxy */; + name = Folly; + target = 899724123EE938F93E535EDDF3D69EDA /* Folly */; + targetProxy = C317B92D6552153355138B8AF7A0DF82 /* PBXContainerItemProxy */; }; - C77D7259D618E484E103939A6001F252 /* PBXTargetDependency */ = { + C0A00069CBF88BB652A94EC9AF1F23AD /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = FirebaseAnalytics; - target = A4AC528160CC8177E6EB809461379FF8 /* FirebaseAnalytics */; - targetProxy = 78355AC4ACD19F1D8F358A906EC4A269 /* PBXContainerItemProxy */; + name = "leveldb-library"; + target = DF4F838E6093604EE864818A37DBF3E2 /* leveldb-library */; + targetProxy = 6E0044A1C82B1DAEDAB14444DC3748A1 /* PBXContainerItemProxy */; }; - C8EE50750AECE9A7AAF226566994B22C /* PBXTargetDependency */ = { + C47C8D58971DFE236D090CA826CEDA99 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = Folly; - target = 899724123EE938F93E535EDDF3D69EDA /* Folly */; - targetProxy = 491B427B0E9462E6841599CDDE61CE71 /* PBXContainerItemProxy */; + name = React; + target = E1D8FCCB52D6F4883463C99656914BB4 /* React */; + targetProxy = 76BB597CC859CD009E81DCA8DA6A4912 /* PBXContainerItemProxy */; }; - C922F8F03220621A12710B46BB7BDFEF /* PBXTargetDependency */ = { + C5181A0F5A2FA29177F19C8E651444A5 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = Fabric; - target = D35E9EC86D36A4C8BC1704199FDB3552 /* Fabric */; - targetProxy = 0C19C30A67341726FDC8A88AECF61870 /* PBXContainerItemProxy */; + name = "react-native-slider"; + target = 8DB803987D7643D2F74BB781FE7E2C01 /* react-native-slider */; + targetProxy = 0AE93191873C131FCFDECCFB24C30E0A /* PBXContainerItemProxy */; }; - C9CEFEFAAAEDB8CD947737FA56C849D4 /* PBXTargetDependency */ = { + C7B77D7B01A09DE62FAC4D1F4945DAF3 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = Fabric; - target = D35E9EC86D36A4C8BC1704199FDB3552 /* Fabric */; - targetProxy = D465047540D12FD9D95291AE82A76DB9 /* PBXContainerItemProxy */; + name = BVLinearGradient; + target = 16BE0913B925E13F023F8ACADD6AEDAC /* BVLinearGradient */; + targetProxy = 2BDA79177A79D620F28693878E51BCEC /* PBXContainerItemProxy */; }; - CAAA120969FA2C3F747FB5C80D9DCA4B /* PBXTargetDependency */ = { + C9CEFEFAAAEDB8CD947737FA56C849D4 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = "boost-for-react-native"; - target = 66641B93FAF80FF325B2D7B4AD85056F /* boost-for-react-native */; - targetProxy = A9D6DC9CB40E4423C1BA75D2D9087468 /* PBXContainerItemProxy */; + name = Fabric; + target = D35E9EC86D36A4C8BC1704199FDB3552 /* Fabric */; + targetProxy = D465047540D12FD9D95291AE82A76DB9 /* PBXContainerItemProxy */; }; CB47107FBB6AF81EC17C0BCFEB820E21 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = "Pods-Kalend"; - target = 47492BF4D2C397E56EAAD1B6A3C49548 /* Pods-Kalend */; + target = D8CB9CF69BB52ED6D1A37B51EA54DD5F /* Pods-Kalend */; targetProxy = 9C46503EC73E87E9773BBD6B7ACB19C0 /* PBXContainerItemProxy */; }; + CE9EB39FDB58090BDE9FDCCD4594C327 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseAuthInterop; + target = 9164D8092E2D2FC2BAD1ABCC34521490 /* FirebaseAuthInterop */; + targetProxy = 20C21CB204BC6F34F59DEA695BA4FDD3 /* PBXContainerItemProxy */; + }; + CF03569B8CBC70386653392793320C5A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = GoogleUtilities; + target = B449DAF8AE800FB85E1F497B65EF9956 /* GoogleUtilities */; + targetProxy = 8D10AFDEC6EA21B8990577A1870F8861 /* PBXContainerItemProxy */; + }; + CFAE725E695BE546790E870F8B3C9269 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseAnalytics; + target = 0AC15EA33F402FC6A1A48C990993D7D8 /* FirebaseAnalytics */; + targetProxy = F194DACC558D5F8744F6392FD9AEB0C6 /* PBXContainerItemProxy */; + }; D028C27980CD4DB3790C0DA56B7FF93D /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = glog; target = E1CAF37843DB75E7886034596F9D9B56 /* glog */; targetProxy = 6AF073F59FA5E3F83B9934D0E8BDE172 /* PBXContainerItemProxy */; }; - D34BD7F383FE74DD86CFD364E7A649B7 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = nanopb; - target = 35B0CD518EC8B839AD44597B2B183B62 /* nanopb */; - targetProxy = 816C88F7B2DBB1FBDE117DB14A78222A /* PBXContainerItemProxy */; - }; - D7898D208CB707C9DBF4DA7ACA916832 /* PBXTargetDependency */ = { + D112DE49FA7B07167DFD9C42ED7710EE /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = GoogleAppMeasurement; - target = F63F26AAC9E12A1E6BDEECB1B662C7E6 /* GoogleAppMeasurement */; - targetProxy = 466B6C3BD3C763937C115EE92E0E9DED /* PBXContainerItemProxy */; + name = React; + target = E1D8FCCB52D6F4883463C99656914BB4 /* React */; + targetProxy = 277B32B0B18E28E771FFC53F22F940B6 /* PBXContainerItemProxy */; }; - D8CC601D778EF44BFE3144C6A22FF660 /* PBXTargetDependency */ = { + D1BB0E1B32DB70370BBD9EEA7BE763C4 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = BVLinearGradient; - target = 16BE0913B925E13F023F8ACADD6AEDAC /* BVLinearGradient */; - targetProxy = F56F3FB2D25DD598B6ABCA66B20A7D10 /* PBXContainerItemProxy */; + name = Protobuf; + target = 22BEF3F4E553CFCB4173F8D80CE8E88C /* Protobuf */; + targetProxy = 7EA62A5A8126CBAA21D5D9897108B454 /* PBXContainerItemProxy */; }; - D8EF861CC600251048254834481C0822 /* PBXTargetDependency */ = { + D3097443ACB3BCA6B6016D72A9DD1235 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = GoogleUtilities; - target = BEFDC8279895EA5EC1BF281D21F9B15D /* GoogleUtilities */; - targetProxy = DE54543D5D61745702021E54EBEFA04F /* PBXContainerItemProxy */; + name = FirebaseABTesting; + target = BCE30BBC689F944FE7A82C1512D6FFA1 /* FirebaseABTesting */; + targetProxy = 76D0E1B98484EEC5D1E736A8E39720AB /* PBXContainerItemProxy */; }; - D97FB6648C4E6277CCA631197803C884 /* PBXTargetDependency */ = { + DC932B830E97F05F5174FAF92BD025A8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = FirebaseInstanceID; - target = F26DF4F6ADD5881D668DF81C6B3F05EF /* FirebaseInstanceID */; - targetProxy = 083ACD6CDB44A8A0BB6995D9477E04A3 /* PBXContainerItemProxy */; + name = FirebaseAnalytics; + target = 0AC15EA33F402FC6A1A48C990993D7D8 /* FirebaseAnalytics */; + targetProxy = 105672866F4BE2C08E743ABF0B2EA2FF /* PBXContainerItemProxy */; }; - DAD37E5B55D180545DABFA5687497C01 /* PBXTargetDependency */ = { + DE7316A58E7292DBB9A5E1762716DF87 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = GoogleAppMeasurement; - target = F63F26AAC9E12A1E6BDEECB1B662C7E6 /* GoogleAppMeasurement */; - targetProxy = EBE5C2359D0F5353B72AAA258DABC84E /* PBXContainerItemProxy */; + target = 2BA894431E6D4EC9D0D3602E2A926A36 /* GoogleAppMeasurement */; + targetProxy = A35F81AB62A9B0B51D7771047A5A9363 /* PBXContainerItemProxy */; }; - DBE6A1D4D327B59945C95F174E8FFEDD /* PBXTargetDependency */ = { + DF3C05EEF2C8BFBE8DA3BBB0F654799B /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = RNVectorIcons; - target = 1656132E72FE6E162694B82A10950197 /* RNVectorIcons */; - targetProxy = 1E668B13ED97F5CA52280B48B5E94354 /* PBXContainerItemProxy */; + name = React; + target = E1D8FCCB52D6F4883463C99656914BB4 /* React */; + targetProxy = C331DDFF297305849D76D8DBBC13947B /* PBXContainerItemProxy */; }; - DC5DAE49351E0342EDE5EE284F43F519 /* PBXTargetDependency */ = { + E45EFBE90A195AE81F39BA17AD99472E /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = GoogleSignIn; target = 2CA9E9CBD6D1591F4833D0AC9A6DE30D /* GoogleSignIn */; - targetProxy = 1EA7D88F1824DFB2E1C778747C76AB39 /* PBXContainerItemProxy */; - }; - E168D8486AE08C301CC2AD371E592D2F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = Protobuf; - target = 9E5688F66E67822336D226F99E7A6588 /* Protobuf */; - targetProxy = EE139BB473D40617D332ADD9FFC051B9 /* PBXContainerItemProxy */; - }; - E22F388532F96C2222C3D0FE5D6FB0C1 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = FirebaseRemoteConfig; - target = 26ECD05F13D8FDDE98B912F8EAD399E8 /* FirebaseRemoteConfig */; - targetProxy = 3933BD09AE3A3D8E4918A22DBE146167 /* PBXContainerItemProxy */; + targetProxy = 8713547E4836EADCC4C633085992190E /* PBXContainerItemProxy */; }; E555CC66E213F001BFCAFA1F83CABBE1 /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -7995,29 +10090,41 @@ target = 899724123EE938F93E535EDDF3D69EDA /* Folly */; targetProxy = 347F2576FE3031D88315EF798753AC13 /* PBXContainerItemProxy */; }; - E60AD53130EA91C6F253099805119F6A /* PBXTargetDependency */ = { + E687E0812D6D93EC05FB13580CC7F7C7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = FirebaseAnalytics; - target = A4AC528160CC8177E6EB809461379FF8 /* FirebaseAnalytics */; - targetProxy = A052B7AAA361846460EF3396A294ED49 /* PBXContainerItemProxy */; + name = GoogleUtilities; + target = B449DAF8AE800FB85E1F497B65EF9956 /* GoogleUtilities */; + targetProxy = FC7EB13854E58E008EA61CDA1D853AE6 /* PBXContainerItemProxy */; }; - EDFD3E09C90F689E147A813155808075 /* PBXTargetDependency */ = { + E88DBD10343207782F2569F3701BB0FD /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = FirebaseCore; - target = 448819EB6C064114FE58EBAA295670B1 /* FirebaseCore */; - targetProxy = 3A9C14C65AC309186E3E9FB96ED3BFA1 /* PBXContainerItemProxy */; + name = FirebaseInstanceID; + target = 7DB3B0B9490B6AF4860CC9317D5F5C54 /* FirebaseInstanceID */; + targetProxy = 41BAAE91BE6D177A15C1545315E52B33 /* PBXContainerItemProxy */; }; - EFF6C4AC6232E9ADB4682C7C18966A13 /* PBXTargetDependency */ = { + EB21FC7055D75EAFF0B81C88279C5D38 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = "lottie-react-native"; - target = 5E317F794B07662C390113F089191B83 /* lottie-react-native */; - targetProxy = 1D160AF43C977841AA22C4ECA775CD4B /* PBXContainerItemProxy */; + name = RNCAsyncStorage; + target = 9EAC38454747EC28EBFCFAA0097CC2F5 /* RNCAsyncStorage */; + targetProxy = 691F71A405EE1F7527D0A12641C94F14 /* PBXContainerItemProxy */; }; - F6DFEE56C188CC386E1F02C58AA786EC /* PBXTargetDependency */ = { + EFF89EC6601A5E356A2E6D13D35448D2 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = Crashlytics; - target = ABA9A411BB5A359862E5F1AA6238278E /* Crashlytics */; - targetProxy = A15B8D564CE1D122E7F75F5CF79C3184 /* PBXContainerItemProxy */; + name = GoogleToolboxForMac; + target = 0B288C19EF7E9BFFBF358F352E60AA3D /* GoogleToolboxForMac */; + targetProxy = C800E1037DCCBF7A279FB4F5FEC0C584 /* PBXContainerItemProxy */; + }; + F3D771E70B32FE032A491D6EC42853EE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseInstanceID; + target = 7DB3B0B9490B6AF4860CC9317D5F5C54 /* FirebaseInstanceID */; + targetProxy = 2C7A6F7FA845FF36E2D4F09878002334 /* PBXContainerItemProxy */; + }; + F3E2A73B6DB5AE2478BAE71F9CA2A3A6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Protobuf; + target = 22BEF3F4E553CFCB4173F8D80CE8E88C /* Protobuf */; + targetProxy = 9D2A92143EC3DE18CEA858F2334A0DB3 /* PBXContainerItemProxy */; }; FA6B451C8769EA08A2620741EA6C92E5 /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -8025,67 +10132,61 @@ target = E1CAF37843DB75E7886034596F9D9B56 /* glog */; targetProxy = AC5C963A5150C27B599306AA6F50DE00 /* PBXContainerItemProxy */; }; - FAB1F60F9F90648DB593BC942CEE0761 /* PBXTargetDependency */ = { + FC6D73F3A1883F01557E5A6A8396CADA /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = FirebaseRemoteConfig; - target = 26ECD05F13D8FDDE98B912F8EAD399E8 /* FirebaseRemoteConfig */; - targetProxy = A3A95A9578626A027F5662EFCC2E486F /* PBXContainerItemProxy */; - }; - FE4253924CD04C42F4A83DE23A5B56CA /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = Protobuf; - target = 9E5688F66E67822336D226F99E7A6588 /* Protobuf */; - targetProxy = FB757F113AD3C74F087AD99F4E48C760 /* PBXContainerItemProxy */; + name = React; + target = E1D8FCCB52D6F4883463C99656914BB4 /* React */; + targetProxy = 41456A458556CEFE7530210D328851EE /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - 021053F77C53B48586B71FB95A8B8EF6 /* Release */ = { + 011C22328D257A94A5D148996FC7803E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7FFDD4CDD40AC409B0985E74BF5A2442 /* react-native-slider.xcconfig */; + baseConfigurationReference = BC487B47C2B96C67BEA917671F02DB85 /* FirebaseAnalytics.xcconfig */; buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/react-native-slider/react-native-slider-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = react_native_slider; - PRODUCT_NAME = "react-native-slider"; - PUBLIC_HEADERS_FOLDER_PATH = ""; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; - 025EB4EB3563FD2AFC6C228A4FF87E64 /* Debug */ = { + 056C009C442A698606C063320C8BF25A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D9688E70781B95F50FAD1F88E039C2BF /* FirebaseAnalytics.xcconfig */; + baseConfigurationReference = 3AC89BACB5F8AA89ED44F24D013259E2 /* Fabric.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; }; - name = Debug; + name = Release; }; - 056C009C442A698606C063320C8BF25A /* Release */ = { + 06350C4E1E957F3AE675A68E687EEB5D /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9A776103D69455946E4E465A746DF256 /* Fabric.xcconfig */; + baseConfigurationReference = BA20E7E90F36B7CFF0BDC2A7B376EED9 /* FirebaseDatabase.xcconfig */; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = FirebaseDatabase; + PRODUCT_NAME = FirebaseDatabase; + PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -8155,41 +10256,53 @@ }; name = Debug; }; - 0BB159FA65D3DCE2AF8C7F262097CC06 /* Debug */ = { + 08163C690DA6989C71E85D5791798C68 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 5458382A8B89DCFF60A1CF5A89242675 /* RNVectorIcons.xcconfig */; + baseConfigurationReference = D229CC4B4E3B58BD5DC90E01A82CFD88 /* leveldb-library.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/RNVectorIcons/RNVectorIcons-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + GCC_PREFIX_HEADER = "Target Support Files/leveldb-library/leveldb-library-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 5.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = RNVectorIcons; - PRODUCT_NAME = RNVectorIcons; + PRODUCT_MODULE_NAME = leveldb; + PRODUCT_NAME = "leveldb-library"; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; }; - name = Debug; + name = Release; }; - 0E5EC1898A346B4D5F37396DDBB94FA1 /* Debug */ = { + 0F25794B9E36C5D263B8CE88E8D3CB77 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15B2B5FFFEFF905A2E8F5CAD7D6E83D9 /* FirebaseRemoteConfig.xcconfig */; + baseConfigurationReference = EF4F36543A72816751F130CB28C4ABE5 /* rn-fetch-blob.xcconfig */; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + GCC_PREFIX_HEADER = "Target Support Files/rn-fetch-blob/rn-fetch-blob-prefix.pch"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = rn_fetch_blob; + PRODUCT_NAME = "rn-fetch-blob"; + PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; }; - name = Debug; + name = Release; }; 15A38C94A5F32EB67C19861FAA476D3E /* Release */ = { isa = XCBuildConfiguration; @@ -8213,21 +10326,21 @@ }; name = Release; }; - 17283E7AEF36256C2BBE12B2C88366E7 /* Release */ = { + 1857DE5D08152FFAE3D98A04A1B1338A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = DE76DB9FA2EBA46167E0E55714379F0E /* GoogleUtilities.xcconfig */; + baseConfigurationReference = 7FFDD4CDD40AC409B0985E74BF5A2442 /* react-native-slider.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/GoogleUtilities/GoogleUtilities-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; + GCC_PREFIX_HEADER = "Target Support Files/react-native-slider/react-native-slider-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = GoogleUtilities; - PRODUCT_NAME = GoogleUtilities; + PRODUCT_MODULE_NAME = react_native_slider; + PRODUCT_NAME = "react-native-slider"; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; @@ -8237,21 +10350,21 @@ }; name = Release; }; - 18AC59E6C6265D0A077BD120976A9822 /* Debug */ = { + 1D1FB60FB0764025877626850D7F90A1 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = B940312F1597EF5B430898726144532D /* GTMSessionFetcher.xcconfig */; + baseConfigurationReference = 22E0623C0304B30B2AA1436750E2C8A0 /* RNCAsyncStorage.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/GTMSessionFetcher/GTMSessionFetcher-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + GCC_PREFIX_HEADER = "Target Support Files/RNCAsyncStorage/RNCAsyncStorage-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = GTMSessionFetcher; - PRODUCT_NAME = GTMSessionFetcher; + PRODUCT_MODULE_NAME = RNCAsyncStorage; + PRODUCT_NAME = RNCAsyncStorage; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; @@ -8260,9 +10373,33 @@ }; name = Debug; }; + 1E6D9F5E37291B3F187C1F41FCC53127 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9D1A6F8BDD2DAB53D53DD8EA9D835715 /* react-native-safari-view.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + GCC_PREFIX_HEADER = "Target Support Files/react-native-safari-view/react-native-safari-view-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = react_native_safari_view; + PRODUCT_NAME = "react-native-safari-view"; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; 200CD2396E713A87F09DF2D0477FFC0C /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = E6D8D2B589B7505E5F8303C187DD0871 /* Crashlytics.xcconfig */; + baseConfigurationReference = B48DB19E655254729291192628C71D52 /* Crashlytics.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; @@ -8276,7 +10413,7 @@ }; 23D5BEBA41EB0C45D1EE5EB2F36ECBE2 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = E6D8D2B589B7505E5F8303C187DD0871 /* Crashlytics.xcconfig */; + baseConfigurationReference = B48DB19E655254729291192628C71D52 /* Crashlytics.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; @@ -8287,65 +10424,58 @@ }; name = Debug; }; - 23F8FECF56BF3C34C8DAC168305E4BAE /* Debug */ = { + 274950BCE8527216008931FDEA20722C /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3E7846B3067043205EAB371A4A7DFC21 /* Pods-Kalend.debug.xcconfig */; + baseConfigurationReference = F08847E07FB985EEA88834452E00AE45 /* glog.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + GCC_PREFIX_HEADER = "Target Support Files/glog/glog-prefix.pch"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MACH_O_TYPE = staticlib; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = glog; + PRODUCT_NAME = glog; + PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; }; - name = Debug; + name = Release; }; - 2558FEC0DCAFDCB97A67334CDEE90740 /* Debug */ = { + 278DE9AE524D8988B0677B0A44BA9C1E /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4D837984DF861DEEF7EB13DB66895A8D /* Protobuf.xcconfig */; + baseConfigurationReference = BC487B47C2B96C67BEA917671F02DB85 /* FirebaseAnalytics.xcconfig */; buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/Protobuf/Protobuf-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = Protobuf; - PRODUCT_NAME = Protobuf; - PUBLIC_HEADERS_FOLDER_PATH = ""; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 274950BCE8527216008931FDEA20722C /* Release */ = { + 2BB597298D98AD9B97700875CA2E6270 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 39F9AFCFBFF9F81F427E737A4D3DFAE2 /* glog.xcconfig */; + baseConfigurationReference = 5458382A8B89DCFF60A1CF5A89242675 /* RNVectorIcons.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/glog/glog-prefix.pch"; + GCC_PREFIX_HEADER = "Target Support Files/RNVectorIcons/RNVectorIcons-prefix.pch"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = glog; - PRODUCT_NAME = glog; + PRODUCT_MODULE_NAME = RNVectorIcons; + PRODUCT_NAME = RNVectorIcons; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; @@ -8355,33 +10485,32 @@ }; name = Release; }; - 2A790A8AF0ABFF31504CA4D7272E9D9B /* Debug */ = { + 2E237688B9A0ED3348030E835F70FCDF /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9B94044BB8213CE214598799507CBFEC /* nanopb.xcconfig */; + baseConfigurationReference = 4D161E1BA70F18F152790A436071D295 /* FirebaseCore.xcconfig */; buildSettings = { - CLANG_ENABLE_OBJC_WEAK = NO; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/nanopb/nanopb-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 4.3; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = nanopb; - PRODUCT_NAME = nanopb; + PRODUCT_MODULE_NAME = FirebaseCore; + PRODUCT_NAME = FirebaseCore; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; }; - name = Debug; + name = Release; }; - 2F9825D621B27E42F9318AF2D8BB8E2D /* Release */ = { + 314A74716DF512FCDB5CC1199DAD3582 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6C28D2538D83FB8724D1397DF54FAEB9 /* FirebaseInstanceID.xcconfig */; + baseConfigurationReference = 5BD9EEEB632240CE8400657E09078FAA /* FirebaseAuthInterop.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; @@ -8393,32 +10522,9 @@ }; name = Release; }; - 3B6B4AF6B02251772803DB3FC6D5ACC9 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 532BFE3E6004DD157D026786F06A2F28 /* RNGestureHandler.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/RNGestureHandler/RNGestureHandler-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = RNGestureHandler; - PRODUCT_NAME = RNGestureHandler; - PUBLIC_HEADERS_FOLDER_PATH = ""; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; 3D943A14FDF2486526E9F735BCDF6DDC /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 850627136AB58C8DA3E77E69C7A41DF4 /* Folly.xcconfig */; + baseConfigurationReference = 8C4A852050AF22C0F63D82C6E289AC36 /* Folly.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -8463,7 +10569,7 @@ }; 40E4B5C9E39D2A84C21FE63191BC69DD /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A2BE11A3B339E51FA7A12775C1F8C727 /* boost-for-react-native.xcconfig */; + baseConfigurationReference = 05287BC664B5445346A8EF5DCADB1246 /* boost-for-react-native.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; @@ -8498,69 +10604,88 @@ }; name = Debug; }; - 46C2B5FFF7BC9951E366C5764BEA5CBA /* Release */ = { + 478982238AB5F75BBA5A4D96D5AF4971 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 618F73C667D4F19D67F0AAAD4ACA299D /* react-native-camera.xcconfig */; + baseConfigurationReference = 7542AAC5A1596B18344251F049739855 /* Pods-Kalend.release.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/react-native-camera/react-native-camera-prefix.pch"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MACH_O_TYPE = staticlib; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; - PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = react_native_camera; - PRODUCT_NAME = "react-native-camera"; - PUBLIC_HEADERS_FOLDER_PATH = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; SDKROOT = iphoneos; SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; - 4D92C1C486E1DDAF3820FF4E338DBD26 /* Release */ = { + 4A983D9BD3B57236ECA7F3F7E1AAC892 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 8E7E7140D1D2690EF22C542A366CFA63 /* yoga.xcconfig */; + baseConfigurationReference = D229CC4B4E3B58BD5DC90E01A82CFD88 /* leveldb-library.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/yoga/yoga-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + GCC_PREFIX_HEADER = "Target Support Files/leveldb-library/leveldb-library-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 5.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = yoga; - PRODUCT_NAME = yoga; + PRODUCT_MODULE_NAME = leveldb; + PRODUCT_NAME = "leveldb-library"; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; }; - name = Release; + name = Debug; }; - 5058AB53ACE0322AE48D62B1C0B478F9 /* Release */ = { + 4CDD633C1C1873D0475DB0E4803894DD /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4D837984DF861DEEF7EB13DB66895A8D /* Protobuf.xcconfig */; + baseConfigurationReference = BA20E7E90F36B7CFF0BDC2A7B376EED9 /* FirebaseDatabase.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/Protobuf/Protobuf-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = Protobuf; - PRODUCT_NAME = Protobuf; + PRODUCT_MODULE_NAME = FirebaseDatabase; + PRODUCT_NAME = FirebaseDatabase; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 4D92C1C486E1DDAF3820FF4E338DBD26 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8E7E7140D1D2690EF22C542A366CFA63 /* yoga.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + GCC_PREFIX_HEADER = "Target Support Files/yoga/yoga-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = yoga; + PRODUCT_NAME = yoga; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; @@ -8570,46 +10695,53 @@ }; name = Release; }; - 555AD0F125D44244757E620C4E5FBA00 /* Release */ = { + 4F4672CF647956A6D544ACBD07C10C82 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = B940312F1597EF5B430898726144532D /* GTMSessionFetcher.xcconfig */; + baseConfigurationReference = 053F5C4B01F3F55AF0D991966A9AFB40 /* Protobuf.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/GTMSessionFetcher/GTMSessionFetcher-prefix.pch"; + GCC_PREFIX_HEADER = "Target Support Files/Protobuf/Protobuf-prefix.pch"; IPHONEOS_DEPLOYMENT_TARGET = 7.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = GTMSessionFetcher; - PRODUCT_NAME = GTMSessionFetcher; + PRODUCT_MODULE_NAME = Protobuf; + PRODUCT_NAME = Protobuf; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; }; - name = Release; + name = Debug; }; - 62987C7379916D85CFA73770BC6213E6 /* Debug */ = { + 522CA3A2962AE5714897D2857E7AE783 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4E464D9BB99F9154986CD67B87B39582 /* GoogleAppMeasurement.xcconfig */; + baseConfigurationReference = 3E7846B3067043205EAB371A4A7DFC21 /* Pods-Kalend.debug.xcconfig */; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CODE_SIGN_IDENTITY = "iPhone Developer"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MACH_O_TYPE = staticlib; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; SDKROOT = iphoneos; + SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 64F223B552257F54DFE6C75EEA56905D /* Debug */ = { + 53D34499943F6E6D6A6A14CF89CE1046 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4D5CAF3D45E732FD8A39342B97FA8FDA /* FirebaseABTesting.xcconfig */; + baseConfigurationReference = 9CEF7B062307C23ED1E338D00919BA99 /* FirebaseInstanceID.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; @@ -8622,7 +10754,7 @@ }; 6626058B9EBEB879949BCEDACCEBFC22 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 156121052651E68677BF8522AC28928C /* DoubleConversion.xcconfig */; + baseConfigurationReference = 91F21C81538226CD9A5DE14ECF25EBEE /* DoubleConversion.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -8644,36 +10776,61 @@ }; name = Release; }; - 67A30CF0CA1E0EF7B16B360C50CEF663 /* Debug */ = { + 67593C093ECA5182F075F31A6D4DEC3E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = DE76DB9FA2EBA46167E0E55714379F0E /* GoogleUtilities.xcconfig */; + baseConfigurationReference = BA58397C32C68A5294911C70B2608DD8 /* GoogleToolboxForMac.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/GoogleUtilities/GoogleUtilities-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; + GCC_PREFIX_HEADER = "Target Support Files/GoogleToolboxForMac/GoogleToolboxForMac-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = GoogleUtilities; - PRODUCT_NAME = GoogleUtilities; + PRODUCT_MODULE_NAME = GoogleToolboxForMac; + PRODUCT_NAME = GoogleToolboxForMac; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; }; - name = Debug; + name = Release; + }; + 67DFD8AAEBA5D73A45A84E83497F473A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 618F73C667D4F19D67F0AAAD4ACA299D /* react-native-camera.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + GCC_PREFIX_HEADER = "Target Support Files/react-native-camera/react-native-camera-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = react_native_camera; + PRODUCT_NAME = "react-native-camera"; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; }; - 6925038D3EF3F351F11E5014E01780D7 /* Release */ = { + 699050F7CFF73408396D638A1C8E01A0 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4E464D9BB99F9154986CD67B87B39582 /* GoogleAppMeasurement.xcconfig */; + baseConfigurationReference = 5147DF55EFD9DDF7091D87DF9F9E8D37 /* FirebaseAnalyticsInterop.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; @@ -8681,6 +10838,29 @@ }; name = Release; }; + 6DADD7739C4DEAC4138FA5418F465FB5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = EF4F36543A72816751F130CB28C4ABE5 /* rn-fetch-blob.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + GCC_PREFIX_HEADER = "Target Support Files/rn-fetch-blob/rn-fetch-blob-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = rn_fetch_blob; + PRODUCT_NAME = "rn-fetch-blob"; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; 7046CFD653D4D0BF36981EE1182BDC7C /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = D77FF794A92CED7479B7414F4980FDCA /* lottie-ios.xcconfig */; @@ -8706,7 +10886,7 @@ }; 727319A53A7E92DB4C57AAD030AEDFE6 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 882D20CF3E4020747627A3A5FE26F042 /* GoogleSignIn.xcconfig */; + baseConfigurationReference = ACF4AA6F7523E7457E2508CB97A2AE10 /* GoogleSignIn.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; @@ -8718,49 +10898,81 @@ }; name = Release; }; - 7908EBC4DCF19A6CD1A139947C92A14F /* Release */ = { + 79FEF173B97C6440B7E74C4A8B652165 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4D5CAF3D45E732FD8A39342B97FA8FDA /* FirebaseABTesting.xcconfig */; + baseConfigurationReference = 8E7E7140D1D2690EF22C542A366CFA63 /* yoga.xcconfig */; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + GCC_PREFIX_HEADER = "Target Support Files/yoga/yoga-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = yoga; + PRODUCT_NAME = yoga; + PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; }; - name = Release; + name = Debug; }; - 79606CEC260A5A66A8411880EE645E90 /* Release */ = { + 7A6877FA14288C56F05D8D6BC0A45AFE /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 805FCB3E481C727E14A57BDD02367CFD /* FirebasePerformance.xcconfig */; + baseConfigurationReference = 59DC9639CA4DCBB82ACE73BDE97C8FE1 /* nanopb.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + GCC_PREFIX_HEADER = "Target Support Files/nanopb/nanopb-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 4.3; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = nanopb; + PRODUCT_NAME = nanopb; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 7B7E9D7FAB7E45B9F4ADF8DC4822703B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3AC89BACB5F8AA89ED44F24D013259E2 /* Fabric.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; }; - name = Release; + name = Debug; }; - 79FEF173B97C6440B7E74C4A8B652165 /* Debug */ = { + 7B9C05907FAD013210E8634F9CE8464E /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 8E7E7140D1D2690EF22C542A366CFA63 /* yoga.xcconfig */; + baseConfigurationReference = 9D1A6F8BDD2DAB53D53DD8EA9D835715 /* react-native-safari-view.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/yoga/yoga-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + GCC_PREFIX_HEADER = "Target Support Files/react-native-safari-view/react-native-safari-view-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = yoga; - PRODUCT_NAME = yoga; + PRODUCT_MODULE_NAME = react_native_safari_view; + PRODUCT_NAME = "react-native-safari-view"; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; @@ -8769,41 +10981,42 @@ }; name = Debug; }; - 7B7E9D7FAB7E45B9F4ADF8DC4822703B /* Debug */ = { + 7C0771BCB86EE6DD75B1AAD83412A4B0 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9A776103D69455946E4E465A746DF256 /* Fabric.xcconfig */; + baseConfigurationReference = 9BCD00A0A096989061C773F8C8DFD83E /* FirebaseABTesting.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 7BB92A44F2C42234E78C648F1A7A2DB8 /* Debug */ = { + 7C092A21D594FD9F5EDC300089A17EC2 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 618F73C667D4F19D67F0AAAD4ACA299D /* react-native-camera.xcconfig */; + baseConfigurationReference = 22E0623C0304B30B2AA1436750E2C8A0 /* RNCAsyncStorage.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/react-native-camera/react-native-camera-prefix.pch"; + GCC_PREFIX_HEADER = "Target Support Files/RNCAsyncStorage/RNCAsyncStorage-prefix.pch"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = react_native_camera; - PRODUCT_NAME = "react-native-camera"; + PRODUCT_MODULE_NAME = RNCAsyncStorage; + PRODUCT_NAME = RNCAsyncStorage; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; }; - name = Debug; + name = Release; }; 7C2F2E49C903EBB1F0EDC977A594B72E /* Release */ = { isa = XCBuildConfiguration; @@ -8829,35 +11042,44 @@ }; name = Release; }; - 91C0BCE09212352FD038F65BFE474638 /* Release */ = { + 813A4B1F49B563AE75BE56C75CCC8794 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D9688E70781B95F50FAD1F88E039C2BF /* FirebaseAnalytics.xcconfig */; + baseConfigurationReference = 8F3AC0B3CF021ABD39D948CB83367A32 /* FirebaseMessaging.xcconfig */; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = FirebaseMessaging; + PRODUCT_NAME = FirebaseMessaging; + PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; - 92DF31CA19962116CE2088DBCEA2EFB3 /* Release */ = { + 814797926CB4C322D638447BD9ACED01 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 98E6F329E8D9AF00DCF3E33E60A44F60 /* GoogleToolboxForMac.xcconfig */; + baseConfigurationReference = D7B5F2F53B922C2DA16A59C5A8B63185 /* GoogleUtilities.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/GoogleToolboxForMac/GoogleToolboxForMac-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + GCC_PREFIX_HEADER = "Target Support Files/GoogleUtilities/GoogleUtilities-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = GoogleToolboxForMac; - PRODUCT_NAME = GoogleToolboxForMac; + PRODUCT_MODULE_NAME = GoogleUtilities; + PRODUCT_NAME = GoogleUtilities; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; @@ -8867,21 +11089,35 @@ }; name = Release; }; - 935A1287DA4D48B4E041C0F29E3A282C /* Release */ = { + 81815494C2631FD82C9B880DAF265773 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 5458382A8B89DCFF60A1CF5A89242675 /* RNVectorIcons.xcconfig */; + baseConfigurationReference = 9BCD00A0A096989061C773F8C8DFD83E /* FirebaseABTesting.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 8B517E703A87906FC7B143745A8C76D8 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 532BFE3E6004DD157D026786F06A2F28 /* RNGestureHandler.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/RNVectorIcons/RNVectorIcons-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + GCC_PREFIX_HEADER = "Target Support Files/RNGestureHandler/RNGestureHandler-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = RNVectorIcons; - PRODUCT_NAME = RNVectorIcons; + PRODUCT_MODULE_NAME = RNGestureHandler; + PRODUCT_NAME = RNGestureHandler; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; @@ -8891,20 +11127,35 @@ }; name = Release; }; - 95853F1151F0E4AF7E4039129B3F6226 /* Debug */ = { + 8BF7AE0B5CA7D27342FAB65BF518FA6F /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9CEF7B062307C23ED1E338D00919BA99 /* FirebaseInstanceID.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 8DD2528AFEC550C4B8B0E17873B55A2C /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4A1D2BA8A36579D7C6ACF5802A9A4F87 /* FirebaseCore.xcconfig */; + baseConfigurationReference = 7FFDD4CDD40AC409B0985E74BF5A2442 /* react-native-slider.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + GCC_PREFIX_HEADER = "Target Support Files/react-native-slider/react-native-slider-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = FirebaseCore; - PRODUCT_NAME = FirebaseCore; + PRODUCT_MODULE_NAME = react_native_slider; + PRODUCT_NAME = "react-native-slider"; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; @@ -8913,29 +11164,27 @@ }; name = Debug; }; - 9DCB6DC806E76EC8AB2A45BEEDD77062 /* Release */ = { + 958B91BCEC57E56079E426C5F7E74B8B /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9D1A6F8BDD2DAB53D53DD8EA9D835715 /* react-native-safari-view.xcconfig */; + baseConfigurationReference = 8F3AC0B3CF021ABD39D948CB83367A32 /* FirebaseMessaging.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/react-native-safari-view/react-native-safari-view-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = react_native_safari_view; - PRODUCT_NAME = "react-native-safari-view"; + PRODUCT_MODULE_NAME = FirebaseMessaging; + PRODUCT_NAME = FirebaseMessaging; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; }; - name = Release; + name = Debug; }; A1962E6FF39BBAC201A2E5DDF99557DF /* Release */ = { isa = XCBuildConfiguration; @@ -8997,34 +11246,43 @@ }; name = Release; }; - A4FB8BDECA7F69556D53CA0712EBD71E /* Debug */ = { + A1FA9208750767CA0D6987075FD2AFC2 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 882D20CF3E4020747627A3A5FE26F042 /* GoogleSignIn.xcconfig */; + baseConfigurationReference = 4D161E1BA70F18F152790A436071D295 /* FirebaseCore.xcconfig */; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = FirebaseCore; + PRODUCT_NAME = FirebaseCore; + PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - A95241966B8B4F5A5ACA030FAFFD9B76 /* Debug */ = { + A3AB0D6A36B7A904F9261A033B41F685 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = EF4F36543A72816751F130CB28C4ABE5 /* rn-fetch-blob.xcconfig */; + baseConfigurationReference = 618F73C667D4F19D67F0AAAD4ACA299D /* react-native-camera.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/rn-fetch-blob/rn-fetch-blob-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + GCC_PREFIX_HEADER = "Target Support Files/react-native-camera/react-native-camera-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = rn_fetch_blob; - PRODUCT_NAME = "rn-fetch-blob"; + PRODUCT_MODULE_NAME = react_native_camera; + PRODUCT_NAME = "react-native-camera"; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; @@ -9033,6 +11291,33 @@ }; name = Debug; }; + A4FB8BDECA7F69556D53CA0712EBD71E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = ACF4AA6F7523E7457E2508CB97A2AE10 /* GoogleSignIn.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + AAA73D73FB5DAD1A2E0202BDAD0019F5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D299AD82DC20B38AB6F91E9CFB0B288E /* FirebasePerformance.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; AC3712EC6370E639361D208F23BC22B5 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 00066D035794B7A884D691A75B2B3916 /* React.xcconfig */; @@ -9057,62 +11342,59 @@ }; name = Release; }; - AECC040413B12169C1AC8985A05BCDF3 /* Release */ = { + ADB5CDCE5C9956230034BC7437683CD2 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9B94044BB8213CE214598799507CBFEC /* nanopb.xcconfig */; + baseConfigurationReference = 5458382A8B89DCFF60A1CF5A89242675 /* RNVectorIcons.xcconfig */; buildSettings = { - CLANG_ENABLE_OBJC_WEAK = NO; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/nanopb/nanopb-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 4.3; + GCC_PREFIX_HEADER = "Target Support Files/RNVectorIcons/RNVectorIcons-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = nanopb; - PRODUCT_NAME = nanopb; + PRODUCT_MODULE_NAME = RNVectorIcons; + PRODUCT_NAME = RNVectorIcons; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; }; - name = Release; + name = Debug; }; - B1040F821EADE4A088EDB9B96A678B62 /* Release */ = { + AFFC2A7A4A0E7332ED8CAF63A6475B47 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 532BFE3E6004DD157D026786F06A2F28 /* RNGestureHandler.xcconfig */; + baseConfigurationReference = D7B5F2F53B922C2DA16A59C5A8B63185 /* GoogleUtilities.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/RNGestureHandler/RNGestureHandler-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + GCC_PREFIX_HEADER = "Target Support Files/GoogleUtilities/GoogleUtilities-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = RNGestureHandler; - PRODUCT_NAME = RNGestureHandler; + PRODUCT_MODULE_NAME = GoogleUtilities; + PRODUCT_NAME = GoogleUtilities; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; }; - name = Release; + name = Debug; }; - BA5CC1E38B7356564003B0B3A8A91EF5 /* Debug */ = { + B998DED4A4A9EE2042BCEABA54457032 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 788D5F1524FB50C541D8C669AA9336EF /* Firebase.xcconfig */; + baseConfigurationReference = AB8A9CADCFA27F2AF11A9FF2DDEEE4F9 /* GoogleAppMeasurement.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; @@ -9145,7 +11427,7 @@ }; BCED374361B9387A457B9F7B3685F9FE /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A2BE11A3B339E51FA7A12775C1F8C727 /* boost-for-react-native.xcconfig */; + baseConfigurationReference = 05287BC664B5445346A8EF5DCADB1246 /* boost-for-react-native.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; @@ -9156,9 +11438,23 @@ }; name = Debug; }; - BD7043922182A73390B8E1CED846534E /* Debug */ = { + BDEA490FF0FFB23453CEA9C707DCBCCB /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = AB8A9CADCFA27F2AF11A9FF2DDEEE4F9 /* GoogleAppMeasurement.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + BEA8029F65BE16100C5ACB4B8DA663D8 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6C28D2538D83FB8724D1397DF54FAEB9 /* FirebaseInstanceID.xcconfig */; + baseConfigurationReference = 8F51B0E5493C1021B8F13C0DBE689DBA /* Firebase.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; @@ -9169,21 +11465,21 @@ }; name = Debug; }; - BF4C5D26A36614BB5D9933EDAAF6D276 /* Debug */ = { + BFEEC82BF383728CC4BD0B37EE091B32 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 22E0623C0304B30B2AA1436750E2C8A0 /* RNCAsyncStorage.xcconfig */; + baseConfigurationReference = 532BFE3E6004DD157D026786F06A2F28 /* RNGestureHandler.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/RNCAsyncStorage/RNCAsyncStorage-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + GCC_PREFIX_HEADER = "Target Support Files/RNGestureHandler/RNGestureHandler-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = RNCAsyncStorage; - PRODUCT_NAME = RNCAsyncStorage; + PRODUCT_MODULE_NAME = RNGestureHandler; + PRODUCT_NAME = RNGestureHandler; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; @@ -9192,32 +11488,33 @@ }; name = Debug; }; - BF951464F01457F70680799C77B2E58F /* Debug */ = { + C463E94A7547081E44FA250DA2F56AB4 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9D1A6F8BDD2DAB53D53DD8EA9D835715 /* react-native-safari-view.xcconfig */; + baseConfigurationReference = 053F5C4B01F3F55AF0D991966A9AFB40 /* Protobuf.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/react-native-safari-view/react-native-safari-view-prefix.pch"; + GCC_PREFIX_HEADER = "Target Support Files/Protobuf/Protobuf-prefix.pch"; IPHONEOS_DEPLOYMENT_TARGET = 7.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = react_native_safari_view; - PRODUCT_NAME = "react-native-safari-view"; + PRODUCT_MODULE_NAME = Protobuf; + PRODUCT_NAME = Protobuf; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; }; - name = Debug; + name = Release; }; C72E49257C5D7B8DCC9EDC34F2BF070D /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 156121052651E68677BF8522AC28928C /* DoubleConversion.xcconfig */; + baseConfigurationReference = 91F21C81538226CD9A5DE14ECF25EBEE /* DoubleConversion.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -9238,91 +11535,81 @@ }; name = Debug; }; - D5D7360A5D05BD17CF18E9D128191FB4 /* Debug */ = { + CAF066F302A6DD5A279004ACE16D40DC /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 850627136AB58C8DA3E77E69C7A41DF4 /* Folly.xcconfig */; + baseConfigurationReference = 9229E08D02A82F7A9C3D6ECA5DAE6D63 /* FirebaseRemoteConfig.xcconfig */; buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/Folly/Folly-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = folly; - PRODUCT_NAME = Folly; - PUBLIC_HEADERS_FOLDER_PATH = ""; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - D61230EB624785EC667E43CEFC15F6A1 /* Debug */ = { + CB88221214307172A2307CF0A243A2FD /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 39F9AFCFBFF9F81F427E737A4D3DFAE2 /* glog.xcconfig */; + baseConfigurationReference = 977D66020EA6D24E36A88FCB18A6AAE7 /* GTMSessionFetcher.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/glog/glog-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + GCC_PREFIX_HEADER = "Target Support Files/GTMSessionFetcher/GTMSessionFetcher-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = glog; - PRODUCT_NAME = glog; + PRODUCT_MODULE_NAME = GTMSessionFetcher; + PRODUCT_NAME = GTMSessionFetcher; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; }; - name = Debug; + name = Release; }; - D7F089D0EC34D9969C4CAE70B0188AEE /* Release */ = { + CF93B159A5E6A7829467AB4CC951AAC2 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = EF4F36543A72816751F130CB28C4ABE5 /* rn-fetch-blob.xcconfig */; + baseConfigurationReference = 977D66020EA6D24E36A88FCB18A6AAE7 /* GTMSessionFetcher.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/rn-fetch-blob/rn-fetch-blob-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + GCC_PREFIX_HEADER = "Target Support Files/GTMSessionFetcher/GTMSessionFetcher-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = rn_fetch_blob; - PRODUCT_NAME = "rn-fetch-blob"; + PRODUCT_MODULE_NAME = GTMSessionFetcher; + PRODUCT_NAME = GTMSessionFetcher; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; }; - name = Release; + name = Debug; }; - D89CACC6052737D1973E19614F285E8C /* Debug */ = { + D5D7360A5D05BD17CF18E9D128191FB4 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 00066D035794B7A884D691A75B2B3916 /* React.xcconfig */; + baseConfigurationReference = 8C4A852050AF22C0F63D82C6E289AC36 /* Folly.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/React/React-prefix.pch"; + GCC_PREFIX_HEADER = "Target Support Files/Folly/Folly-prefix.pch"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = React; - PRODUCT_NAME = React; + PRODUCT_MODULE_NAME = folly; + PRODUCT_NAME = Folly; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; @@ -9331,34 +11618,21 @@ }; name = Debug; }; - D908F51EE1B50ADB8A45E5835CC354C9 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 805FCB3E481C727E14A57BDD02367CFD /* FirebasePerformance.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "iPhone Developer"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - D95E116F0C443AE9EC82C85B35E42658 /* Debug */ = { + D61230EB624785EC667E43CEFC15F6A1 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7FFDD4CDD40AC409B0985E74BF5A2442 /* react-native-slider.xcconfig */; + baseConfigurationReference = F08847E07FB985EEA88834452E00AE45 /* glog.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/react-native-slider/react-native-slider-prefix.pch"; + GCC_PREFIX_HEADER = "Target Support Files/glog/glog-prefix.pch"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = react_native_slider; - PRODUCT_NAME = "react-native-slider"; + PRODUCT_MODULE_NAME = glog; + PRODUCT_NAME = glog; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; @@ -9367,21 +11641,21 @@ }; name = Debug; }; - DEF30F26FCA452FC4A38E47086DFBE6C /* Debug */ = { + D6A0A247332FE6142BB3B809872DB8C1 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 89CA7A146CB927B9201F74F37A2D20FE /* BVLinearGradient.xcconfig */; + baseConfigurationReference = BA58397C32C68A5294911C70B2608DD8 /* GoogleToolboxForMac.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/BVLinearGradient/BVLinearGradient-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + GCC_PREFIX_HEADER = "Target Support Files/GoogleToolboxForMac/GoogleToolboxForMac-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = BVLinearGradient; - PRODUCT_NAME = BVLinearGradient; + PRODUCT_MODULE_NAME = GoogleToolboxForMac; + PRODUCT_NAME = GoogleToolboxForMac; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; @@ -9390,21 +11664,21 @@ }; name = Debug; }; - E146E40C8AC0E1E664B28E37D07B4CC2 /* Debug */ = { + D89CACC6052737D1973E19614F285E8C /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 98E6F329E8D9AF00DCF3E33E60A44F60 /* GoogleToolboxForMac.xcconfig */; + baseConfigurationReference = 00066D035794B7A884D691A75B2B3916 /* React.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/GoogleToolboxForMac/GoogleToolboxForMac-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + GCC_PREFIX_HEADER = "Target Support Files/React/React-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = GoogleToolboxForMac; - PRODUCT_NAME = GoogleToolboxForMac; + PRODUCT_MODULE_NAME = React; + PRODUCT_NAME = React; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; @@ -9413,21 +11687,22 @@ }; name = Debug; }; - E656F1D1E15EC86FC932DF411987FED3 /* Release */ = { + DA24C324C3B0CF9A66955909043F0C92 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 22E0623C0304B30B2AA1436750E2C8A0 /* RNCAsyncStorage.xcconfig */; + baseConfigurationReference = 59DC9639CA4DCBB82ACE73BDE97C8FE1 /* nanopb.xcconfig */; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - GCC_PREFIX_HEADER = "Target Support Files/RNCAsyncStorage/RNCAsyncStorage-prefix.pch"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + GCC_PREFIX_HEADER = "Target Support Files/nanopb/nanopb-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 4.3; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = RNCAsyncStorage; - PRODUCT_NAME = RNCAsyncStorage; + PRODUCT_MODULE_NAME = nanopb; + PRODUCT_NAME = nanopb; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; @@ -9437,9 +11712,9 @@ }; name = Release; }; - EA471850DCCAFB8B17919159FAF430B0 /* Release */ = { + DDC76ABD89D80B9278F7A22F8D998387 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15B2B5FFFEFF905A2E8F5CAD7D6E83D9 /* FirebaseRemoteConfig.xcconfig */; + baseConfigurationReference = 5BD9EEEB632240CE8400657E09078FAA /* FirebaseAuthInterop.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; @@ -9447,36 +11722,35 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; }; - name = Release; + name = Debug; }; - EB4212A9F5DD2EA44D5203FC53D652FD /* Release */ = { + DEF30F26FCA452FC4A38E47086DFBE6C /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4A1D2BA8A36579D7C6ACF5802A9A4F87 /* FirebaseCore.xcconfig */; + baseConfigurationReference = 89CA7A146CB927B9201F74F37A2D20FE /* BVLinearGradient.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + GCC_PREFIX_HEADER = "Target Support Files/BVLinearGradient/BVLinearGradient-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = FirebaseCore; - PRODUCT_NAME = FirebaseCore; + PRODUCT_MODULE_NAME = BVLinearGradient; + PRODUCT_NAME = BVLinearGradient; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; }; - name = Release; + name = Debug; }; - F4E69001EC995870652AC5F173944FFE /* Release */ = { + E0EF6E2D06E7FC89859314E0290E3894 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 788D5F1524FB50C541D8C669AA9336EF /* Firebase.xcconfig */; + baseConfigurationReference = 8F51B0E5493C1021B8F13C0DBE689DBA /* Firebase.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; @@ -9488,6 +11762,19 @@ }; name = Release; }; + EEE9FE6251516C3D72501047AE522736 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D299AD82DC20B38AB6F91E9CFB0B288E /* FirebasePerformance.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; F505CC942D1F8AA6D8B77A1F8ACA66C4 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 17258D135D9BB7E83C8F2D02315DFB22 /* lottie-react-native.xcconfig */; @@ -9512,23 +11799,28 @@ }; name = Release; }; - FA270730A0C8149F369858977EC459EA /* Release */ = { + FE314E53C5E7E85614DE52E0A70565C6 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7542AAC5A1596B18344251F049739855 /* Pods-Kalend.release.xcconfig */; + baseConfigurationReference = 5147DF55EFD9DDF7091D87DF9F9E8D37 /* FirebaseAnalyticsInterop.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MACH_O_TYPE = staticlib; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + FFE8183A249DA8EAE148894042273A7C /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9229E08D02A82F7A9C3D6ECA5DAE6D63 /* FirebaseRemoteConfig.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; SDKROOT = iphoneos; - SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -9537,24 +11829,6 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 075A99C1769C88FC29ACCECA70C86FB7 /* Build configuration list for PBXNativeTarget "GTMSessionFetcher" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 18AC59E6C6265D0A077BD120976A9822 /* Debug */, - 555AD0F125D44244757E620C4E5FBA00 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 07EC1F6B9BEE2082CBD9BE5C5079D3C0 /* Build configuration list for PBXNativeTarget "RNGestureHandler" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B6B4AF6B02251772803DB3FC6D5ACC9 /* Debug */, - B1040F821EADE4A088EDB9B96A678B62 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 0EDD87012FB6F789D068F8F0EA12CF40 /* Build configuration list for PBXNativeTarget "glog" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -9573,20 +11847,20 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 17905515BD2398AC7775CB1C636ED24F /* Build configuration list for PBXNativeTarget "react-native-camera" */ = { + 15E25BD050E906581AC7356BD2DD942C /* Build configuration list for PBXNativeTarget "react-native-camera" */ = { isa = XCConfigurationList; buildConfigurations = ( - 7BB92A44F2C42234E78C648F1A7A2DB8 /* Debug */, - 46C2B5FFF7BC9951E366C5764BEA5CBA /* Release */, + A3AB0D6A36B7A904F9261A033B41F685 /* Debug */, + 67DFD8AAEBA5D73A45A84E83497F473A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 1B852014228F9600E7B980D35203ED8C /* Build configuration list for PBXNativeTarget "RNVectorIcons" */ = { + 19FFB503DC56D25D481C6314DB9562C7 /* Build configuration list for PBXNativeTarget "Pods-Kalend" */ = { isa = XCConfigurationList; buildConfigurations = ( - 0BB159FA65D3DCE2AF8C7F262097CC06 /* Debug */, - 935A1287DA4D48B4E041C0F29E3A282C /* Release */, + 522CA3A2962AE5714897D2857E7AE783 /* Debug */, + 478982238AB5F75BBA5A4D96D5AF4971 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -9600,20 +11874,20 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 25EBC5051EE154F1FCE20A19E60BC96B /* Build configuration list for PBXNativeTarget "Pods-Kalend" */ = { + 267EAC32215E1AA475B8B9C873D882D6 /* Build configuration list for PBXNativeTarget "BVLinearGradient" */ = { isa = XCConfigurationList; buildConfigurations = ( - 23F8FECF56BF3C34C8DAC168305E4BAE /* Debug */, - FA270730A0C8149F369858977EC459EA /* Release */, + DEF30F26FCA452FC4A38E47086DFBE6C /* Debug */, + BBBD493A83F16EFB10455111396765C0 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 267EAC32215E1AA475B8B9C873D882D6 /* Build configuration list for PBXNativeTarget "BVLinearGradient" */ = { + 29DB0BBAA2ADA23C15D8CB495A377BFC /* Build configuration list for PBXAggregateTarget "FirebaseRemoteConfig" */ = { isa = XCConfigurationList; buildConfigurations = ( - DEF30F26FCA452FC4A38E47086DFBE6C /* Debug */, - BBBD493A83F16EFB10455111396765C0 /* Release */, + CAF066F302A6DD5A279004ACE16D40DC /* Debug */, + FFE8183A249DA8EAE148894042273A7C /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -9636,20 +11910,29 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 37A37499B53208B363CD87E69D4972FA /* Build configuration list for PBXAggregateTarget "FirebaseRemoteConfig" */ = { + 319D7BE581977605775091B621A07C22 /* Build configuration list for PBXNativeTarget "FirebaseDatabase" */ = { isa = XCConfigurationList; buildConfigurations = ( - 0E5EC1898A346B4D5F37396DDBB94FA1 /* Debug */, - EA471850DCCAFB8B17919159FAF430B0 /* Release */, + 4CDD633C1C1873D0475DB0E4803894DD /* Debug */, + 06350C4E1E957F3AE675A68E687EEB5D /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 41928B8F7CAF78A8CA3DC06AA919798E /* Build configuration list for PBXNativeTarget "nanopb" */ = { + 39E104F50FCB816E256B211B5C63770F /* Build configuration list for PBXNativeTarget "rn-fetch-blob" */ = { isa = XCConfigurationList; buildConfigurations = ( - 2A790A8AF0ABFF31504CA4D7272E9D9B /* Debug */, - AECC040413B12169C1AC8985A05BCDF3 /* Release */, + 6DADD7739C4DEAC4138FA5418F465FB5 /* Debug */, + 0F25794B9E36C5D263B8CE88E8D3CB77 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4471AEED27AEDEAF3C943CB699E1C52F /* Build configuration list for PBXNativeTarget "GoogleToolboxForMac" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D6A0A247332FE6142BB3B809872DB8C1 /* Debug */, + 67593C093ECA5182F075F31A6D4DEC3E /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -9672,38 +11955,38 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 5AE3722DD39C3B2C37D89B1AC2A0A4C0 /* Build configuration list for PBXAggregateTarget "boost-for-react-native" */ = { + 4BC6C2898B88E8258014DB0CCFC4203A /* Build configuration list for PBXNativeTarget "RNVectorIcons" */ = { isa = XCConfigurationList; buildConfigurations = ( - BCED374361B9387A457B9F7B3685F9FE /* Debug */, - 40E4B5C9E39D2A84C21FE63191BC69DD /* Release */, + ADB5CDCE5C9956230034BC7437683CD2 /* Debug */, + 2BB597298D98AD9B97700875CA2E6270 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 5CC475E75ACB3EA054E4190AEA9682D2 /* Build configuration list for PBXNativeTarget "react-native-slider" */ = { + 4F9CCB851C9A390E108AF1336F7577A7 /* Build configuration list for PBXNativeTarget "FirebaseMessaging" */ = { isa = XCConfigurationList; buildConfigurations = ( - D95E116F0C443AE9EC82C85B35E42658 /* Debug */, - 021053F77C53B48586B71FB95A8B8EF6 /* Release */, + 958B91BCEC57E56079E426C5F7E74B8B /* Debug */, + 813A4B1F49B563AE75BE56C75CCC8794 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 6A4DA9F8817669E27CB5A7C8FA7D2A26 /* Build configuration list for PBXNativeTarget "react-native-safari-view" */ = { + 5AE3722DD39C3B2C37D89B1AC2A0A4C0 /* Build configuration list for PBXAggregateTarget "boost-for-react-native" */ = { isa = XCConfigurationList; buildConfigurations = ( - BF951464F01457F70680799C77B2E58F /* Debug */, - 9DCB6DC806E76EC8AB2A45BEEDD77062 /* Release */, + BCED374361B9387A457B9F7B3685F9FE /* Debug */, + 40E4B5C9E39D2A84C21FE63191BC69DD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 70AD7205E7FB4607A09DDA1B7EE7EC24 /* Build configuration list for PBXAggregateTarget "FirebasePerformance" */ = { + 6360D91DFA01A8052B366CEEA7A26019 /* Build configuration list for PBXNativeTarget "RNCAsyncStorage" */ = { isa = XCConfigurationList; buildConfigurations = ( - D908F51EE1B50ADB8A45E5835CC354C9 /* Debug */, - 79606CEC260A5A66A8411880EE645E90 /* Release */, + 1D1FB60FB0764025877626850D7F90A1 /* Debug */, + 7C092A21D594FD9F5EDC300089A17EC2 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -9717,20 +12000,38 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 88FBA1418FAD76E151DAD088BE9DC5E8 /* Build configuration list for PBXAggregateTarget "FirebaseInstanceID" */ = { + 830CCE9C964DF67D0354BB888C9803E0 /* Build configuration list for PBXAggregateTarget "FirebaseInstanceID" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53D34499943F6E6D6A6A14CF89CE1046 /* Debug */, + 8BF7AE0B5CA7D27342FAB65BF518FA6F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 839880EBB960216C533B0E7600D3FC94 /* Build configuration list for PBXAggregateTarget "FirebaseAnalytics" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 278DE9AE524D8988B0677B0A44BA9C1E /* Debug */, + 011C22328D257A94A5D148996FC7803E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 84A6918C46136E15CD69044DD756F14B /* Build configuration list for PBXNativeTarget "react-native-safari-view" */ = { isa = XCConfigurationList; buildConfigurations = ( - BD7043922182A73390B8E1CED846534E /* Debug */, - 2F9825D621B27E42F9318AF2D8BB8E2D /* Release */, + 7B9C05907FAD013210E8634F9CE8464E /* Debug */, + 1E6D9F5E37291B3F187C1F41FCC53127 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 93F96ACEEE5FCD20472D40784A808CFD /* Build configuration list for PBXNativeTarget "Protobuf" */ = { + 96C0DBAE598FF9D41101845EB8FE801D /* Build configuration list for PBXNativeTarget "FirebaseCore" */ = { isa = XCConfigurationList; buildConfigurations = ( - 2558FEC0DCAFDCB97A67334CDEE90740 /* Debug */, - 5058AB53ACE0322AE48D62B1C0B478F9 /* Release */, + A1FA9208750767CA0D6987075FD2AFC2 /* Debug */, + 2E237688B9A0ED3348030E835F70FCDF /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -9744,20 +12045,38 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - A7FAF6F6747EDB5167ECD60B6741E25E /* Build configuration list for PBXNativeTarget "RNCAsyncStorage" */ = { + A58F84E3BEDDCC54778F118917EEBD24 /* Build configuration list for PBXNativeTarget "nanopb" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7A6877FA14288C56F05D8D6BC0A45AFE /* Debug */, + DA24C324C3B0CF9A66955909043F0C92 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A6CF3A8813B185C3B8CE38F87E453EF2 /* Build configuration list for PBXAggregateTarget "GoogleAppMeasurement" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B998DED4A4A9EE2042BCEABA54457032 /* Debug */, + BDEA490FF0FFB23453CEA9C707DCBCCB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + AAE4ACE12E61BAE48883E2516DD8E5B3 /* Build configuration list for PBXAggregateTarget "FirebasePerformance" */ = { isa = XCConfigurationList; buildConfigurations = ( - BF4C5D26A36614BB5D9933EDAAF6D276 /* Debug */, - E656F1D1E15EC86FC932DF411987FED3 /* Release */, + EEE9FE6251516C3D72501047AE522736 /* Debug */, + AAA73D73FB5DAD1A2E0202BDAD0019F5 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - A98CB1647FE9647D98BDE52E34408CB7 /* Build configuration list for PBXAggregateTarget "FirebaseABTesting" */ = { + B4FA9B94B441BA05D587CB38046BD183 /* Build configuration list for PBXNativeTarget "react-native-slider" */ = { isa = XCConfigurationList; buildConfigurations = ( - 64F223B552257F54DFE6C75EEA56905D /* Debug */, - 7908EBC4DCF19A6CD1A139947C92A14F /* Release */, + 8DD2528AFEC550C4B8B0E17873B55A2C /* Debug */, + 1857DE5D08152FFAE3D98A04A1B1338A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -9771,11 +12090,11 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - C45A018D550E880DF4572355220CD3D2 /* Build configuration list for PBXAggregateTarget "Firebase" */ = { + BD73662F427EC5A0345DF66F2EA85402 /* Build configuration list for PBXAggregateTarget "FirebaseAnalyticsInterop" */ = { isa = XCConfigurationList; buildConfigurations = ( - BA5CC1E38B7356564003B0B3A8A91EF5 /* Debug */, - F4E69001EC995870652AC5F173944FFE /* Release */, + FE314E53C5E7E85614DE52E0A70565C6 /* Debug */, + 699050F7CFF73408396D638A1C8E01A0 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -9789,47 +12108,56 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - C7DB024E1DC497BCAC9996B471F53C97 /* Build configuration list for PBXNativeTarget "GoogleUtilities" */ = { + C84F7A20AE7F5D08CC5DD8D81F12E906 /* Build configuration list for PBXNativeTarget "RNGestureHandler" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BFEEC82BF383728CC4BD0B37EE091B32 /* Debug */, + 8B517E703A87906FC7B143745A8C76D8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D6212F3679BF9E059A9D82C8DF6EF03A /* Build configuration list for PBXNativeTarget "GoogleUtilities" */ = { isa = XCConfigurationList; buildConfigurations = ( - 67A30CF0CA1E0EF7B16B360C50CEF663 /* Debug */, - 17283E7AEF36256C2BBE12B2C88366E7 /* Release */, + AFFC2A7A4A0E7332ED8CAF63A6475B47 /* Debug */, + 814797926CB4C322D638447BD9ACED01 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - C910F120266A0E277B7CBFFCD33C51C5 /* Build configuration list for PBXNativeTarget "rn-fetch-blob" */ = { + D6DEDA99A356C9DD777ED7C1B5B71712 /* Build configuration list for PBXNativeTarget "leveldb-library" */ = { isa = XCConfigurationList; buildConfigurations = ( - A95241966B8B4F5A5ACA030FAFFD9B76 /* Debug */, - D7F089D0EC34D9969C4CAE70B0188AEE /* Release */, + 4A983D9BD3B57236ECA7F3F7E1AAC892 /* Debug */, + 08163C690DA6989C71E85D5791798C68 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - DDD6A75A0001E7B5E52D6A3846D2F551 /* Build configuration list for PBXAggregateTarget "GoogleAppMeasurement" */ = { + E2734AACD9F862F58B9602F555C1DDE4 /* Build configuration list for PBXAggregateTarget "FirebaseABTesting" */ = { isa = XCConfigurationList; buildConfigurations = ( - 62987C7379916D85CFA73770BC6213E6 /* Debug */, - 6925038D3EF3F351F11E5014E01780D7 /* Release */, + 7C0771BCB86EE6DD75B1AAD83412A4B0 /* Debug */, + 81815494C2631FD82C9B880DAF265773 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - E87B8987703715DA718A87A20D959F0B /* Build configuration list for PBXNativeTarget "GoogleToolboxForMac" */ = { + EAB88B5FC09CEDAE7954651F4F6CFEB0 /* Build configuration list for PBXAggregateTarget "FirebaseAuthInterop" */ = { isa = XCConfigurationList; buildConfigurations = ( - E146E40C8AC0E1E664B28E37D07B4CC2 /* Debug */, - 92DF31CA19962116CE2088DBCEA2EFB3 /* Release */, + DDC76ABD89D80B9278F7A22F8D998387 /* Debug */, + 314A74716DF512FCDB5CC1199DAD3582 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - E96D4243FCC681D3FA071B6D5798F263 /* Build configuration list for PBXAggregateTarget "FirebaseAnalytics" */ = { + EF580C074815DB2948B6B0916525EDB8 /* Build configuration list for PBXNativeTarget "GTMSessionFetcher" */ = { isa = XCConfigurationList; buildConfigurations = ( - 025EB4EB3563FD2AFC6C228A4FF87E64 /* Debug */, - 91C0BCE09212352FD038F65BFE474638 /* Release */, + CF93B159A5E6A7829467AB4CC951AAC2 /* Debug */, + CB88221214307172A2307CF0A243A2FD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -9843,11 +12171,20 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - F6943DB6F35007357E4317601AD206CD /* Build configuration list for PBXNativeTarget "FirebaseCore" */ = { + F8FC7BD0FE07FA52B5E14327BAE47812 /* Build configuration list for PBXAggregateTarget "Firebase" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BEA8029F65BE16100C5ACB4B8DA663D8 /* Debug */, + E0EF6E2D06E7FC89859314E0290E3894 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + FEDAE663F5DB1ACECF4FE1CA0CD3CC73 /* Build configuration list for PBXNativeTarget "Protobuf" */ = { isa = XCConfigurationList; buildConfigurations = ( - 95853F1151F0E4AF7E4039129B3F6226 /* Debug */, - EB4212A9F5DD2EA44D5203FC53D652FD /* Release */, + 4F4672CF647956A6D544ACBD07C10C82 /* Debug */, + C463E94A7547081E44FA250DA2F56AB4 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/ios/Pods/Target Support Files/Firebase/Firebase.xcconfig b/ios/Pods/Target Support Files/Firebase/Firebase.xcconfig index 6f0e00ef..900d0e1a 100644 --- a/ios/Pods/Target Support Files/Firebase/Firebase.xcconfig +++ b/ios/Pods/Target Support Files/Firebase/Firebase.xcconfig @@ -1,7 +1,7 @@ CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Firebase FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/FirebaseABTesting/Frameworks" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/FirebaseInstanceID/Frameworks" "${PODS_ROOT}/FirebasePerformance/Frameworks" "${PODS_ROOT}/FirebaseRemoteConfig/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Firebase" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/GTMSessionFetcher" "${PODS_ROOT}/Headers/Public/GoogleToolboxForMac" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/Protobuf" "${PODS_ROOT}/Headers/Public/nanopb" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Firebase" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseAnalyticsInterop" "${PODS_ROOT}/Headers/Public/FirebaseAuthInterop" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseDatabase" "${PODS_ROOT}/Headers/Public/FirebaseMessaging" "${PODS_ROOT}/Headers/Public/GTMSessionFetcher" "${PODS_ROOT}/Headers/Public/GoogleToolboxForMac" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/Protobuf" "${PODS_ROOT}/Headers/Public/leveldb-library" "${PODS_ROOT}/Headers/Public/nanopb" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} diff --git a/ios/Pods/Target Support Files/FirebaseAnalyticsInterop/FirebaseAnalyticsInterop.xcconfig b/ios/Pods/Target Support Files/FirebaseAnalyticsInterop/FirebaseAnalyticsInterop.xcconfig new file mode 100644 index 00000000..8e152fe1 --- /dev/null +++ b/ios/Pods/Target Support Files/FirebaseAnalyticsInterop/FirebaseAnalyticsInterop.xcconfig @@ -0,0 +1,9 @@ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseAnalyticsInterop +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/FirebaseAnalyticsInterop" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/FirebaseAnalyticsInterop" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseAnalyticsInterop +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES diff --git a/ios/Pods/Target Support Files/FirebaseAuthInterop/FirebaseAuthInterop.xcconfig b/ios/Pods/Target Support Files/FirebaseAuthInterop/FirebaseAuthInterop.xcconfig new file mode 100644 index 00000000..41a70529 --- /dev/null +++ b/ios/Pods/Target Support Files/FirebaseAuthInterop/FirebaseAuthInterop.xcconfig @@ -0,0 +1,9 @@ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseAuthInterop +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/FirebaseAuthInterop" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/FirebaseAuthInterop" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseAuthInterop +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES diff --git a/ios/Pods/Target Support Files/FirebaseDatabase/FirebaseDatabase-dummy.m b/ios/Pods/Target Support Files/FirebaseDatabase/FirebaseDatabase-dummy.m new file mode 100644 index 00000000..40813e77 --- /dev/null +++ b/ios/Pods/Target Support Files/FirebaseDatabase/FirebaseDatabase-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_FirebaseDatabase : NSObject +@end +@implementation PodsDummy_FirebaseDatabase +@end diff --git a/ios/Pods/Target Support Files/FirebaseDatabase/FirebaseDatabase.xcconfig b/ios/Pods/Target Support Files/FirebaseDatabase/FirebaseDatabase.xcconfig new file mode 100644 index 00000000..74f1e695 --- /dev/null +++ b/ios/Pods/Target Support Files/FirebaseDatabase/FirebaseDatabase.xcconfig @@ -0,0 +1,10 @@ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseDatabase +GCC_C_LANGUAGE_STANDARD = c99 +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 FIRDatabase_VERSION=5.0.4 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/FirebaseDatabase" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/FirebaseAuthInterop" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseDatabase" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/leveldb-library" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseDatabase +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES diff --git a/ios/Pods/Target Support Files/FirebaseMessaging/FirebaseMessaging-dummy.m b/ios/Pods/Target Support Files/FirebaseMessaging/FirebaseMessaging-dummy.m new file mode 100644 index 00000000..ec945492 --- /dev/null +++ b/ios/Pods/Target Support Files/FirebaseMessaging/FirebaseMessaging-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_FirebaseMessaging : NSObject +@end +@implementation PodsDummy_FirebaseMessaging +@end diff --git a/ios/Pods/Target Support Files/FirebaseMessaging/FirebaseMessaging.xcconfig b/ios/Pods/Target Support Files/FirebaseMessaging/FirebaseMessaging.xcconfig new file mode 100644 index 00000000..8c93e903 --- /dev/null +++ b/ios/Pods/Target Support Files/FirebaseMessaging/FirebaseMessaging.xcconfig @@ -0,0 +1,11 @@ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseMessaging +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/FirebaseInstanceID/Frameworks" +GCC_C_LANGUAGE_STANDARD = c99 +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1 FIRMessaging_LIB_VERSION=3.2.2 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/FirebaseMessaging" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/FirebaseAnalyticsInterop" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseMessaging" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/Protobuf" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseMessaging +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES diff --git a/ios/Pods/Target Support Files/Pods-Kalend/Pods-Kalend-acknowledgements.markdown b/ios/Pods/Target Support Files/Pods-Kalend/Pods-Kalend-acknowledgements.markdown index f1d96e87..7a3d0099 100644 --- a/ios/Pods/Target Support Files/Pods-Kalend/Pods-Kalend-acknowledgements.markdown +++ b/ios/Pods/Target Support Files/Pods-Kalend/Pods-Kalend-acknowledgements.markdown @@ -76,6 +76,418 @@ Copyright 2018 Google Copyright 2018 Google +## FirebaseAnalyticsInterop + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + + +## FirebaseAuthInterop + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + + ## FirebaseCore @@ -282,10 +694,422 @@ Copyright 2018 Google limitations under the License. +## FirebaseDatabase + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + + ## FirebaseInstanceID Copyright 2018 Google +## FirebaseMessaging + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + + ## FirebasePerformance Copyright 2018 Google @@ -1333,6 +2157,37 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## leveldb-library + +Copyright (c) 2011 The LevelDB Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ## lottie-ios Apache License diff --git a/ios/Pods/Target Support Files/Pods-Kalend/Pods-Kalend-acknowledgements.plist b/ios/Pods/Target Support Files/Pods-Kalend/Pods-Kalend-acknowledgements.plist index 4053db7a..de8a73cc 100644 --- a/ios/Pods/Target Support Files/Pods-Kalend/Pods-Kalend-acknowledgements.plist +++ b/ios/Pods/Target Support Files/Pods-Kalend/Pods-Kalend-acknowledgements.plist @@ -322,6 +322,430 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Copyright [yyyy] [name of copyright owner] + 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. + + License + Apache + Title + FirebaseAnalyticsInterop + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + + License + Apache + Title + FirebaseAuthInterop + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + 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 @@ -341,6 +765,218 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Type PSGroupSpecifier + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + + License + Apache + Title + FirebaseDatabase + Type + PSGroupSpecifier + FooterText Copyright 2018 Google @@ -351,6 +987,218 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Type PSGroupSpecifier + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + + License + Apache + Title + FirebaseMessaging + Type + PSGroupSpecifier + FooterText Copyright 2018 Google @@ -1488,6 +2336,43 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Type PSGroupSpecifier + + FooterText + Copyright (c) 2011 The LevelDB Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + License + New BSD + Title + leveldb-library + Type + PSGroupSpecifier + FooterText Apache License diff --git a/ios/Pods/Target Support Files/Pods-Kalend/Pods-Kalend.debug.xcconfig b/ios/Pods/Target Support Files/Pods-Kalend/Pods-Kalend.debug.xcconfig index 0028749e..71d8d743 100644 --- a/ios/Pods/Target Support Files/Pods-Kalend/Pods-Kalend.debug.xcconfig +++ b/ios/Pods/Target Support Files/Pods-Kalend/Pods-Kalend.debug.xcconfig @@ -1,8 +1,8 @@ FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Crashlytics/iOS" "${PODS_ROOT}/Fabric/iOS" "${PODS_ROOT}/FirebaseABTesting/Frameworks" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/FirebaseInstanceID/Frameworks" "${PODS_ROOT}/FirebasePerformance/Frameworks" "${PODS_ROOT}/FirebaseRemoteConfig/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" "${PODS_ROOT}/GoogleSignIn/Frameworks" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/BVLinearGradient" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/GTMSessionFetcher" "${PODS_ROOT}/Headers/Public/GoogleToolboxForMac" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/Protobuf" "${PODS_ROOT}/Headers/Public/RNCAsyncStorage" "${PODS_ROOT}/Headers/Public/RNGestureHandler" "${PODS_ROOT}/Headers/Public/RNVectorIcons" "${PODS_ROOT}/Headers/Public/React" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/lottie-ios" "${PODS_ROOT}/Headers/Public/lottie-react-native" "${PODS_ROOT}/Headers/Public/nanopb" "${PODS_ROOT}/Headers/Public/react-native-camera" "${PODS_ROOT}/Headers/Public/react-native-safari-view" "${PODS_ROOT}/Headers/Public/react-native-slider" "${PODS_ROOT}/Headers/Public/rn-fetch-blob" "${PODS_ROOT}/Headers/Public/yoga" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources -LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BVLinearGradient" "${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/Folly" "${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleToolboxForMac" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "${PODS_CONFIGURATION_BUILD_DIR}/RNCAsyncStorage" "${PODS_CONFIGURATION_BUILD_DIR}/RNGestureHandler" "${PODS_CONFIGURATION_BUILD_DIR}/RNVectorIcons" "${PODS_CONFIGURATION_BUILD_DIR}/React" "${PODS_CONFIGURATION_BUILD_DIR}/glog" "${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios" "${PODS_CONFIGURATION_BUILD_DIR}/lottie-react-native" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-camera" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-safari-view" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-slider" "${PODS_CONFIGURATION_BUILD_DIR}/rn-fetch-blob" "${PODS_CONFIGURATION_BUILD_DIR}/yoga" -OTHER_LDFLAGS = $(inherited) -ObjC -l"BVLinearGradient" -l"DoubleConversion" -l"FirebaseCore" -l"Folly" -l"GTMSessionFetcher" -l"GoogleToolboxForMac" -l"GoogleUtilities" -l"Protobuf" -l"RNCAsyncStorage" -l"RNGestureHandler" -l"RNVectorIcons" -l"React" -l"c++" -l"glog" -l"lottie-ios" -l"lottie-react-native" -l"nanopb" -l"react-native-camera" -l"react-native-safari-view" -l"react-native-slider" -l"rn-fetch-blob" -l"sqlite3" -l"stdc++" -l"yoga" -l"z" -framework "CoreGraphics" -framework "CoreTelephony" -framework "CoreText" -framework "Crashlytics" -framework "FIRAnalyticsConnector" -framework "Fabric" -framework "FirebaseABTesting" -framework "FirebaseAnalytics" -framework "FirebaseCoreDiagnostics" -framework "FirebaseInstanceID" -framework "FirebasePerformance" -framework "FirebaseRemoteConfig" -framework "Foundation" -framework "GoogleAppMeasurement" -framework "GoogleSignIn" -framework "JavaScriptCore" -framework "LocalAuthentication" -framework "QuartzCore" -framework "SafariServices" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/BVLinearGradient" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseAnalyticsInterop" "${PODS_ROOT}/Headers/Public/FirebaseAuthInterop" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseDatabase" "${PODS_ROOT}/Headers/Public/FirebaseMessaging" "${PODS_ROOT}/Headers/Public/GTMSessionFetcher" "${PODS_ROOT}/Headers/Public/GoogleToolboxForMac" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/Protobuf" "${PODS_ROOT}/Headers/Public/RNCAsyncStorage" "${PODS_ROOT}/Headers/Public/RNGestureHandler" "${PODS_ROOT}/Headers/Public/RNVectorIcons" "${PODS_ROOT}/Headers/Public/React" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/leveldb-library" "${PODS_ROOT}/Headers/Public/lottie-ios" "${PODS_ROOT}/Headers/Public/lottie-react-native" "${PODS_ROOT}/Headers/Public/nanopb" "${PODS_ROOT}/Headers/Public/react-native-camera" "${PODS_ROOT}/Headers/Public/react-native-safari-view" "${PODS_ROOT}/Headers/Public/react-native-slider" "${PODS_ROOT}/Headers/Public/rn-fetch-blob" "${PODS_ROOT}/Headers/Public/yoga" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources +LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BVLinearGradient" "${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseDatabase" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseMessaging" "${PODS_CONFIGURATION_BUILD_DIR}/Folly" "${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleToolboxForMac" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "${PODS_CONFIGURATION_BUILD_DIR}/RNCAsyncStorage" "${PODS_CONFIGURATION_BUILD_DIR}/RNGestureHandler" "${PODS_CONFIGURATION_BUILD_DIR}/RNVectorIcons" "${PODS_CONFIGURATION_BUILD_DIR}/React" "${PODS_CONFIGURATION_BUILD_DIR}/glog" "${PODS_CONFIGURATION_BUILD_DIR}/leveldb-library" "${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios" "${PODS_CONFIGURATION_BUILD_DIR}/lottie-react-native" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-camera" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-safari-view" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-slider" "${PODS_CONFIGURATION_BUILD_DIR}/rn-fetch-blob" "${PODS_CONFIGURATION_BUILD_DIR}/yoga" +OTHER_LDFLAGS = $(inherited) -ObjC -l"BVLinearGradient" -l"DoubleConversion" -l"FirebaseCore" -l"FirebaseDatabase" -l"FirebaseMessaging" -l"Folly" -l"GTMSessionFetcher" -l"GoogleToolboxForMac" -l"GoogleUtilities" -l"Protobuf" -l"RNCAsyncStorage" -l"RNGestureHandler" -l"RNVectorIcons" -l"React" -l"c++" -l"glog" -l"icucore" -l"leveldb-library" -l"lottie-ios" -l"lottie-react-native" -l"nanopb" -l"react-native-camera" -l"react-native-safari-view" -l"react-native-slider" -l"rn-fetch-blob" -l"sqlite3" -l"stdc++" -l"yoga" -l"z" -framework "CFNetwork" -framework "CoreGraphics" -framework "CoreTelephony" -framework "CoreText" -framework "Crashlytics" -framework "FIRAnalyticsConnector" -framework "Fabric" -framework "FirebaseABTesting" -framework "FirebaseAnalytics" -framework "FirebaseCoreDiagnostics" -framework "FirebaseInstanceID" -framework "FirebasePerformance" -framework "FirebaseRemoteConfig" -framework "Foundation" -framework "GoogleAppMeasurement" -framework "GoogleSignIn" -framework "JavaScriptCore" -framework "LocalAuthentication" -framework "QuartzCore" -framework "SafariServices" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. diff --git a/ios/Pods/Target Support Files/Pods-Kalend/Pods-Kalend.release.xcconfig b/ios/Pods/Target Support Files/Pods-Kalend/Pods-Kalend.release.xcconfig index 0028749e..71d8d743 100644 --- a/ios/Pods/Target Support Files/Pods-Kalend/Pods-Kalend.release.xcconfig +++ b/ios/Pods/Target Support Files/Pods-Kalend/Pods-Kalend.release.xcconfig @@ -1,8 +1,8 @@ FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Crashlytics/iOS" "${PODS_ROOT}/Fabric/iOS" "${PODS_ROOT}/FirebaseABTesting/Frameworks" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/FirebaseInstanceID/Frameworks" "${PODS_ROOT}/FirebasePerformance/Frameworks" "${PODS_ROOT}/FirebaseRemoteConfig/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" "${PODS_ROOT}/GoogleSignIn/Frameworks" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/BVLinearGradient" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/GTMSessionFetcher" "${PODS_ROOT}/Headers/Public/GoogleToolboxForMac" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/Protobuf" "${PODS_ROOT}/Headers/Public/RNCAsyncStorage" "${PODS_ROOT}/Headers/Public/RNGestureHandler" "${PODS_ROOT}/Headers/Public/RNVectorIcons" "${PODS_ROOT}/Headers/Public/React" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/lottie-ios" "${PODS_ROOT}/Headers/Public/lottie-react-native" "${PODS_ROOT}/Headers/Public/nanopb" "${PODS_ROOT}/Headers/Public/react-native-camera" "${PODS_ROOT}/Headers/Public/react-native-safari-view" "${PODS_ROOT}/Headers/Public/react-native-slider" "${PODS_ROOT}/Headers/Public/rn-fetch-blob" "${PODS_ROOT}/Headers/Public/yoga" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources -LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BVLinearGradient" "${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/Folly" "${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleToolboxForMac" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "${PODS_CONFIGURATION_BUILD_DIR}/RNCAsyncStorage" "${PODS_CONFIGURATION_BUILD_DIR}/RNGestureHandler" "${PODS_CONFIGURATION_BUILD_DIR}/RNVectorIcons" "${PODS_CONFIGURATION_BUILD_DIR}/React" "${PODS_CONFIGURATION_BUILD_DIR}/glog" "${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios" "${PODS_CONFIGURATION_BUILD_DIR}/lottie-react-native" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-camera" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-safari-view" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-slider" "${PODS_CONFIGURATION_BUILD_DIR}/rn-fetch-blob" "${PODS_CONFIGURATION_BUILD_DIR}/yoga" -OTHER_LDFLAGS = $(inherited) -ObjC -l"BVLinearGradient" -l"DoubleConversion" -l"FirebaseCore" -l"Folly" -l"GTMSessionFetcher" -l"GoogleToolboxForMac" -l"GoogleUtilities" -l"Protobuf" -l"RNCAsyncStorage" -l"RNGestureHandler" -l"RNVectorIcons" -l"React" -l"c++" -l"glog" -l"lottie-ios" -l"lottie-react-native" -l"nanopb" -l"react-native-camera" -l"react-native-safari-view" -l"react-native-slider" -l"rn-fetch-blob" -l"sqlite3" -l"stdc++" -l"yoga" -l"z" -framework "CoreGraphics" -framework "CoreTelephony" -framework "CoreText" -framework "Crashlytics" -framework "FIRAnalyticsConnector" -framework "Fabric" -framework "FirebaseABTesting" -framework "FirebaseAnalytics" -framework "FirebaseCoreDiagnostics" -framework "FirebaseInstanceID" -framework "FirebasePerformance" -framework "FirebaseRemoteConfig" -framework "Foundation" -framework "GoogleAppMeasurement" -framework "GoogleSignIn" -framework "JavaScriptCore" -framework "LocalAuthentication" -framework "QuartzCore" -framework "SafariServices" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/BVLinearGradient" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseAnalyticsInterop" "${PODS_ROOT}/Headers/Public/FirebaseAuthInterop" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseDatabase" "${PODS_ROOT}/Headers/Public/FirebaseMessaging" "${PODS_ROOT}/Headers/Public/GTMSessionFetcher" "${PODS_ROOT}/Headers/Public/GoogleToolboxForMac" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/Protobuf" "${PODS_ROOT}/Headers/Public/RNCAsyncStorage" "${PODS_ROOT}/Headers/Public/RNGestureHandler" "${PODS_ROOT}/Headers/Public/RNVectorIcons" "${PODS_ROOT}/Headers/Public/React" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/leveldb-library" "${PODS_ROOT}/Headers/Public/lottie-ios" "${PODS_ROOT}/Headers/Public/lottie-react-native" "${PODS_ROOT}/Headers/Public/nanopb" "${PODS_ROOT}/Headers/Public/react-native-camera" "${PODS_ROOT}/Headers/Public/react-native-safari-view" "${PODS_ROOT}/Headers/Public/react-native-slider" "${PODS_ROOT}/Headers/Public/rn-fetch-blob" "${PODS_ROOT}/Headers/Public/yoga" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources +LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BVLinearGradient" "${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseDatabase" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseMessaging" "${PODS_CONFIGURATION_BUILD_DIR}/Folly" "${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleToolboxForMac" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/Protobuf" "${PODS_CONFIGURATION_BUILD_DIR}/RNCAsyncStorage" "${PODS_CONFIGURATION_BUILD_DIR}/RNGestureHandler" "${PODS_CONFIGURATION_BUILD_DIR}/RNVectorIcons" "${PODS_CONFIGURATION_BUILD_DIR}/React" "${PODS_CONFIGURATION_BUILD_DIR}/glog" "${PODS_CONFIGURATION_BUILD_DIR}/leveldb-library" "${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios" "${PODS_CONFIGURATION_BUILD_DIR}/lottie-react-native" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-camera" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-safari-view" "${PODS_CONFIGURATION_BUILD_DIR}/react-native-slider" "${PODS_CONFIGURATION_BUILD_DIR}/rn-fetch-blob" "${PODS_CONFIGURATION_BUILD_DIR}/yoga" +OTHER_LDFLAGS = $(inherited) -ObjC -l"BVLinearGradient" -l"DoubleConversion" -l"FirebaseCore" -l"FirebaseDatabase" -l"FirebaseMessaging" -l"Folly" -l"GTMSessionFetcher" -l"GoogleToolboxForMac" -l"GoogleUtilities" -l"Protobuf" -l"RNCAsyncStorage" -l"RNGestureHandler" -l"RNVectorIcons" -l"React" -l"c++" -l"glog" -l"icucore" -l"leveldb-library" -l"lottie-ios" -l"lottie-react-native" -l"nanopb" -l"react-native-camera" -l"react-native-safari-view" -l"react-native-slider" -l"rn-fetch-blob" -l"sqlite3" -l"stdc++" -l"yoga" -l"z" -framework "CFNetwork" -framework "CoreGraphics" -framework "CoreTelephony" -framework "CoreText" -framework "Crashlytics" -framework "FIRAnalyticsConnector" -framework "Fabric" -framework "FirebaseABTesting" -framework "FirebaseAnalytics" -framework "FirebaseCoreDiagnostics" -framework "FirebaseInstanceID" -framework "FirebasePerformance" -framework "FirebaseRemoteConfig" -framework "Foundation" -framework "GoogleAppMeasurement" -framework "GoogleSignIn" -framework "JavaScriptCore" -framework "LocalAuthentication" -framework "QuartzCore" -framework "SafariServices" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. diff --git a/ios/Pods/Target Support Files/Pods-KalendTests/Pods-KalendTests.debug.xcconfig b/ios/Pods/Target Support Files/Pods-KalendTests/Pods-KalendTests.debug.xcconfig index 6fdc2ea4..205a3732 100644 --- a/ios/Pods/Target Support Files/Pods-KalendTests/Pods-KalendTests.debug.xcconfig +++ b/ios/Pods/Target Support Files/Pods-KalendTests/Pods-KalendTests.debug.xcconfig @@ -1,7 +1,7 @@ FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Crashlytics/iOS" "${PODS_ROOT}/Fabric/iOS" "${PODS_ROOT}/FirebaseABTesting/Frameworks" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/FirebaseInstanceID/Frameworks" "${PODS_ROOT}/FirebasePerformance/Frameworks" "${PODS_ROOT}/FirebaseRemoteConfig/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" "${PODS_ROOT}/GoogleSignIn/Frameworks" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/BVLinearGradient" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/GTMSessionFetcher" "${PODS_ROOT}/Headers/Public/GoogleToolboxForMac" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/Protobuf" "${PODS_ROOT}/Headers/Public/RNCAsyncStorage" "${PODS_ROOT}/Headers/Public/RNGestureHandler" "${PODS_ROOT}/Headers/Public/RNVectorIcons" "${PODS_ROOT}/Headers/Public/React" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/lottie-ios" "${PODS_ROOT}/Headers/Public/lottie-react-native" "${PODS_ROOT}/Headers/Public/nanopb" "${PODS_ROOT}/Headers/Public/react-native-camera" "${PODS_ROOT}/Headers/Public/react-native-safari-view" "${PODS_ROOT}/Headers/Public/react-native-slider" "${PODS_ROOT}/Headers/Public/rn-fetch-blob" "${PODS_ROOT}/Headers/Public/yoga" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources -OTHER_LDFLAGS = $(inherited) -ObjC -l"c++" -l"sqlite3" -l"stdc++" -l"z" -framework "CoreGraphics" -framework "CoreTelephony" -framework "CoreText" -framework "Foundation" -framework "JavaScriptCore" -framework "LocalAuthentication" -framework "QuartzCore" -framework "SafariServices" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/BVLinearGradient" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseAnalyticsInterop" "${PODS_ROOT}/Headers/Public/FirebaseAuthInterop" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseDatabase" "${PODS_ROOT}/Headers/Public/FirebaseMessaging" "${PODS_ROOT}/Headers/Public/GTMSessionFetcher" "${PODS_ROOT}/Headers/Public/GoogleToolboxForMac" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/Protobuf" "${PODS_ROOT}/Headers/Public/RNCAsyncStorage" "${PODS_ROOT}/Headers/Public/RNGestureHandler" "${PODS_ROOT}/Headers/Public/RNVectorIcons" "${PODS_ROOT}/Headers/Public/React" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/leveldb-library" "${PODS_ROOT}/Headers/Public/lottie-ios" "${PODS_ROOT}/Headers/Public/lottie-react-native" "${PODS_ROOT}/Headers/Public/nanopb" "${PODS_ROOT}/Headers/Public/react-native-camera" "${PODS_ROOT}/Headers/Public/react-native-safari-view" "${PODS_ROOT}/Headers/Public/react-native-slider" "${PODS_ROOT}/Headers/Public/rn-fetch-blob" "${PODS_ROOT}/Headers/Public/yoga" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources +OTHER_LDFLAGS = $(inherited) -ObjC -l"c++" -l"icucore" -l"sqlite3" -l"stdc++" -l"z" -framework "CFNetwork" -framework "CoreGraphics" -framework "CoreTelephony" -framework "CoreText" -framework "Foundation" -framework "JavaScriptCore" -framework "LocalAuthentication" -framework "QuartzCore" -framework "SafariServices" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. diff --git a/ios/Pods/Target Support Files/Pods-KalendTests/Pods-KalendTests.release.xcconfig b/ios/Pods/Target Support Files/Pods-KalendTests/Pods-KalendTests.release.xcconfig index 6fdc2ea4..205a3732 100644 --- a/ios/Pods/Target Support Files/Pods-KalendTests/Pods-KalendTests.release.xcconfig +++ b/ios/Pods/Target Support Files/Pods-KalendTests/Pods-KalendTests.release.xcconfig @@ -1,7 +1,7 @@ FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Crashlytics/iOS" "${PODS_ROOT}/Fabric/iOS" "${PODS_ROOT}/FirebaseABTesting/Frameworks" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/FirebaseInstanceID/Frameworks" "${PODS_ROOT}/FirebasePerformance/Frameworks" "${PODS_ROOT}/FirebaseRemoteConfig/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" "${PODS_ROOT}/GoogleSignIn/Frameworks" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/BVLinearGradient" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/GTMSessionFetcher" "${PODS_ROOT}/Headers/Public/GoogleToolboxForMac" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/Protobuf" "${PODS_ROOT}/Headers/Public/RNCAsyncStorage" "${PODS_ROOT}/Headers/Public/RNGestureHandler" "${PODS_ROOT}/Headers/Public/RNVectorIcons" "${PODS_ROOT}/Headers/Public/React" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/lottie-ios" "${PODS_ROOT}/Headers/Public/lottie-react-native" "${PODS_ROOT}/Headers/Public/nanopb" "${PODS_ROOT}/Headers/Public/react-native-camera" "${PODS_ROOT}/Headers/Public/react-native-safari-view" "${PODS_ROOT}/Headers/Public/react-native-slider" "${PODS_ROOT}/Headers/Public/rn-fetch-blob" "${PODS_ROOT}/Headers/Public/yoga" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources -OTHER_LDFLAGS = $(inherited) -ObjC -l"c++" -l"sqlite3" -l"stdc++" -l"z" -framework "CoreGraphics" -framework "CoreTelephony" -framework "CoreText" -framework "Foundation" -framework "JavaScriptCore" -framework "LocalAuthentication" -framework "QuartzCore" -framework "SafariServices" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/BVLinearGradient" "${PODS_ROOT}/Headers/Public/DoubleConversion" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseAnalyticsInterop" "${PODS_ROOT}/Headers/Public/FirebaseAuthInterop" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseDatabase" "${PODS_ROOT}/Headers/Public/FirebaseMessaging" "${PODS_ROOT}/Headers/Public/GTMSessionFetcher" "${PODS_ROOT}/Headers/Public/GoogleToolboxForMac" "${PODS_ROOT}/Headers/Public/GoogleUtilities" "${PODS_ROOT}/Headers/Public/Protobuf" "${PODS_ROOT}/Headers/Public/RNCAsyncStorage" "${PODS_ROOT}/Headers/Public/RNGestureHandler" "${PODS_ROOT}/Headers/Public/RNVectorIcons" "${PODS_ROOT}/Headers/Public/React" "${PODS_ROOT}/Headers/Public/glog" "${PODS_ROOT}/Headers/Public/leveldb-library" "${PODS_ROOT}/Headers/Public/lottie-ios" "${PODS_ROOT}/Headers/Public/lottie-react-native" "${PODS_ROOT}/Headers/Public/nanopb" "${PODS_ROOT}/Headers/Public/react-native-camera" "${PODS_ROOT}/Headers/Public/react-native-safari-view" "${PODS_ROOT}/Headers/Public/react-native-slider" "${PODS_ROOT}/Headers/Public/rn-fetch-blob" "${PODS_ROOT}/Headers/Public/yoga" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources +OTHER_LDFLAGS = $(inherited) -ObjC -l"c++" -l"icucore" -l"sqlite3" -l"stdc++" -l"z" -framework "CFNetwork" -framework "CoreGraphics" -framework "CoreTelephony" -framework "CoreText" -framework "Foundation" -framework "JavaScriptCore" -framework "LocalAuthentication" -framework "QuartzCore" -framework "SafariServices" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. diff --git a/ios/Pods/Target Support Files/leveldb-library/leveldb-library-dummy.m b/ios/Pods/Target Support Files/leveldb-library/leveldb-library-dummy.m new file mode 100644 index 00000000..dba14922 --- /dev/null +++ b/ios/Pods/Target Support Files/leveldb-library/leveldb-library-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_leveldb_library : NSObject +@end +@implementation PodsDummy_leveldb_library +@end diff --git a/ios/Pods/Target Support Files/leveldb-library/leveldb-library-prefix.pch b/ios/Pods/Target Support Files/leveldb-library/leveldb-library-prefix.pch new file mode 100644 index 00000000..beb2a244 --- /dev/null +++ b/ios/Pods/Target Support Files/leveldb-library/leveldb-library-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/ios/Pods/Target Support Files/leveldb-library/leveldb-library.xcconfig b/ios/Pods/Target Support Files/leveldb-library/leveldb-library.xcconfig new file mode 100644 index 00000000..f6247200 --- /dev/null +++ b/ios/Pods/Target Support Files/leveldb-library/leveldb-library.xcconfig @@ -0,0 +1,11 @@ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/leveldb-library +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/leveldb-library" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/leveldb-library" "${PODS_ROOT}/leveldb-library" "${PODS_ROOT}/leveldb-library/include" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/leveldb-library +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_HEADERMAP = No +WARNING_CFLAGS = -Wno-shorten-64-to-32 -Wno-comma -Wno-unreachable-code -Wno-conditional-uninitialized -Wno-deprecated-declarations diff --git a/ios/Pods/leveldb-library/LICENSE b/ios/Pods/leveldb-library/LICENSE new file mode 100644 index 00000000..8e80208c --- /dev/null +++ b/ios/Pods/leveldb-library/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2011 The LevelDB Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ios/Pods/leveldb-library/README.md b/ios/Pods/leveldb-library/README.md new file mode 100644 index 00000000..a010c508 --- /dev/null +++ b/ios/Pods/leveldb-library/README.md @@ -0,0 +1,174 @@ +**LevelDB is a fast key-value storage library written at Google that provides an ordered mapping from string keys to string values.** + +[![Build Status](https://travis-ci.org/google/leveldb.svg?branch=master)](https://travis-ci.org/google/leveldb) + +Authors: Sanjay Ghemawat (sanjay@google.com) and Jeff Dean (jeff@google.com) + +# Features + * Keys and values are arbitrary byte arrays. + * Data is stored sorted by key. + * Callers can provide a custom comparison function to override the sort order. + * The basic operations are `Put(key,value)`, `Get(key)`, `Delete(key)`. + * Multiple changes can be made in one atomic batch. + * Users can create a transient snapshot to get a consistent view of data. + * Forward and backward iteration is supported over the data. + * Data is automatically compressed using the [Snappy compression library](http://google.github.io/snappy/). + * External activity (file system operations etc.) is relayed through a virtual interface so users can customize the operating system interactions. + +# Documentation + [LevelDB library documentation](https://github.com/google/leveldb/blob/master/doc/index.md) is online and bundled with the source code. + + +# Limitations + * This is not a SQL database. It does not have a relational data model, it does not support SQL queries, and it has no support for indexes. + * Only a single process (possibly multi-threaded) can access a particular database at a time. + * There is no client-server support builtin to the library. An application that needs such support will have to wrap their own server around the library. + +# Contributing to the leveldb Project +The leveldb project welcomes contributions. leveldb's primary goal is to be +a reliable and fast key/value store. Changes that are in line with the +features/limitations outlined above, and meet the requirements below, +will be considered. + +Contribution requirements: + +1. **POSIX only**. We _generally_ will only accept changes that are both + compiled, and tested on a POSIX platform - usually Linux. Very small + changes will sometimes be accepted, but consider that more of an + exception than the rule. + +2. **Stable API**. We strive very hard to maintain a stable API. Changes that + require changes for projects using leveldb _might_ be rejected without + sufficient benefit to the project. + +3. **Tests**: All changes must be accompanied by a new (or changed) test, or + a sufficient explanation as to why a new (or changed) test is not required. + +## Submitting a Pull Request +Before any pull request will be accepted the author must first sign a +Contributor License Agreement (CLA) at https://cla.developers.google.com/. + +In order to keep the commit timeline linear +[squash](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Squashing-Commits) +your changes down to a single commit and [rebase](https://git-scm.com/docs/git-rebase) +on google/leveldb/master. This keeps the commit timeline linear and more easily sync'ed +with the internal repository at Google. More information at GitHub's +[About Git rebase](https://help.github.com/articles/about-git-rebase/) page. + +# Performance + +Here is a performance report (with explanations) from the run of the +included db_bench program. The results are somewhat noisy, but should +be enough to get a ballpark performance estimate. + +## Setup + +We use a database with a million entries. Each entry has a 16 byte +key, and a 100 byte value. Values used by the benchmark compress to +about half their original size. + + LevelDB: version 1.1 + Date: Sun May 1 12:11:26 2011 + CPU: 4 x Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz + CPUCache: 4096 KB + Keys: 16 bytes each + Values: 100 bytes each (50 bytes after compression) + Entries: 1000000 + Raw Size: 110.6 MB (estimated) + File Size: 62.9 MB (estimated) + +## Write performance + +The "fill" benchmarks create a brand new database, in either +sequential, or random order. The "fillsync" benchmark flushes data +from the operating system to the disk after every operation; the other +write operations leave the data sitting in the operating system buffer +cache for a while. The "overwrite" benchmark does random writes that +update existing keys in the database. + + fillseq : 1.765 micros/op; 62.7 MB/s + fillsync : 268.409 micros/op; 0.4 MB/s (10000 ops) + fillrandom : 2.460 micros/op; 45.0 MB/s + overwrite : 2.380 micros/op; 46.5 MB/s + +Each "op" above corresponds to a write of a single key/value pair. +I.e., a random write benchmark goes at approximately 400,000 writes per second. + +Each "fillsync" operation costs much less (0.3 millisecond) +than a disk seek (typically 10 milliseconds). We suspect that this is +because the hard disk itself is buffering the update in its memory and +responding before the data has been written to the platter. This may +or may not be safe based on whether or not the hard disk has enough +power to save its memory in the event of a power failure. + +## Read performance + +We list the performance of reading sequentially in both the forward +and reverse direction, and also the performance of a random lookup. +Note that the database created by the benchmark is quite small. +Therefore the report characterizes the performance of leveldb when the +working set fits in memory. The cost of reading a piece of data that +is not present in the operating system buffer cache will be dominated +by the one or two disk seeks needed to fetch the data from disk. +Write performance will be mostly unaffected by whether or not the +working set fits in memory. + + readrandom : 16.677 micros/op; (approximately 60,000 reads per second) + readseq : 0.476 micros/op; 232.3 MB/s + readreverse : 0.724 micros/op; 152.9 MB/s + +LevelDB compacts its underlying storage data in the background to +improve read performance. The results listed above were done +immediately after a lot of random writes. The results after +compactions (which are usually triggered automatically) are better. + + readrandom : 11.602 micros/op; (approximately 85,000 reads per second) + readseq : 0.423 micros/op; 261.8 MB/s + readreverse : 0.663 micros/op; 166.9 MB/s + +Some of the high cost of reads comes from repeated decompression of blocks +read from disk. If we supply enough cache to the leveldb so it can hold the +uncompressed blocks in memory, the read performance improves again: + + readrandom : 9.775 micros/op; (approximately 100,000 reads per second before compaction) + readrandom : 5.215 micros/op; (approximately 190,000 reads per second after compaction) + +## Repository contents + +See [doc/index.md](doc/index.md) for more explanation. See +[doc/impl.md](doc/impl.md) for a brief overview of the implementation. + +The public interface is in include/*.h. Callers should not include or +rely on the details of any other header files in this package. Those +internal APIs may be changed without warning. + +Guide to header files: + +* **include/db.h**: Main interface to the DB: Start here + +* **include/options.h**: Control over the behavior of an entire database, +and also control over the behavior of individual reads and writes. + +* **include/comparator.h**: Abstraction for user-specified comparison function. +If you want just bytewise comparison of keys, you can use the default +comparator, but clients can write their own comparator implementations if they +want custom ordering (e.g. to handle different character encodings, etc.) + +* **include/iterator.h**: Interface for iterating over data. You can get +an iterator from a DB object. + +* **include/write_batch.h**: Interface for atomically applying multiple +updates to a database. + +* **include/slice.h**: A simple module for maintaining a pointer and a +length into some other byte array. + +* **include/status.h**: Status is returned from many of the public interfaces +and is used to report success and various kinds of errors. + +* **include/env.h**: +Abstraction of the OS environment. A posix implementation of this interface is +in util/env_posix.cc + +* **include/table.h, include/table_builder.h**: Lower-level modules that most +clients probably won't use directly diff --git a/ios/Pods/leveldb-library/db/builder.cc b/ios/Pods/leveldb-library/db/builder.cc new file mode 100644 index 00000000..f4198821 --- /dev/null +++ b/ios/Pods/leveldb-library/db/builder.cc @@ -0,0 +1,88 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "db/builder.h" + +#include "db/filename.h" +#include "db/dbformat.h" +#include "db/table_cache.h" +#include "db/version_edit.h" +#include "leveldb/db.h" +#include "leveldb/env.h" +#include "leveldb/iterator.h" + +namespace leveldb { + +Status BuildTable(const std::string& dbname, + Env* env, + const Options& options, + TableCache* table_cache, + Iterator* iter, + FileMetaData* meta) { + Status s; + meta->file_size = 0; + iter->SeekToFirst(); + + std::string fname = TableFileName(dbname, meta->number); + if (iter->Valid()) { + WritableFile* file; + s = env->NewWritableFile(fname, &file); + if (!s.ok()) { + return s; + } + + TableBuilder* builder = new TableBuilder(options, file); + meta->smallest.DecodeFrom(iter->key()); + for (; iter->Valid(); iter->Next()) { + Slice key = iter->key(); + meta->largest.DecodeFrom(key); + builder->Add(key, iter->value()); + } + + // Finish and check for builder errors + if (s.ok()) { + s = builder->Finish(); + if (s.ok()) { + meta->file_size = builder->FileSize(); + assert(meta->file_size > 0); + } + } else { + builder->Abandon(); + } + delete builder; + + // Finish and check for file errors + if (s.ok()) { + s = file->Sync(); + } + if (s.ok()) { + s = file->Close(); + } + delete file; + file = NULL; + + if (s.ok()) { + // Verify that the table is usable + Iterator* it = table_cache->NewIterator(ReadOptions(), + meta->number, + meta->file_size); + s = it->status(); + delete it; + } + } + + // Check for input iterator errors + if (!iter->status().ok()) { + s = iter->status(); + } + + if (s.ok() && meta->file_size > 0) { + // Keep it + } else { + env->DeleteFile(fname); + } + return s; +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/db/builder.h b/ios/Pods/leveldb-library/db/builder.h new file mode 100644 index 00000000..62431fcf --- /dev/null +++ b/ios/Pods/leveldb-library/db/builder.h @@ -0,0 +1,34 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_DB_BUILDER_H_ +#define STORAGE_LEVELDB_DB_BUILDER_H_ + +#include "leveldb/status.h" + +namespace leveldb { + +struct Options; +struct FileMetaData; + +class Env; +class Iterator; +class TableCache; +class VersionEdit; + +// Build a Table file from the contents of *iter. The generated file +// will be named according to meta->number. On success, the rest of +// *meta will be filled with metadata about the generated table. +// If no data is present in *iter, meta->file_size will be set to +// zero, and no Table file will be produced. +extern Status BuildTable(const std::string& dbname, + Env* env, + const Options& options, + TableCache* table_cache, + Iterator* iter, + FileMetaData* meta); + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_DB_BUILDER_H_ diff --git a/ios/Pods/leveldb-library/db/c.cc b/ios/Pods/leveldb-library/db/c.cc new file mode 100644 index 00000000..08ff0ad9 --- /dev/null +++ b/ios/Pods/leveldb-library/db/c.cc @@ -0,0 +1,595 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "leveldb/c.h" + +#include +#include +#include "leveldb/cache.h" +#include "leveldb/comparator.h" +#include "leveldb/db.h" +#include "leveldb/env.h" +#include "leveldb/filter_policy.h" +#include "leveldb/iterator.h" +#include "leveldb/options.h" +#include "leveldb/status.h" +#include "leveldb/write_batch.h" + +using leveldb::Cache; +using leveldb::Comparator; +using leveldb::CompressionType; +using leveldb::DB; +using leveldb::Env; +using leveldb::FileLock; +using leveldb::FilterPolicy; +using leveldb::Iterator; +using leveldb::kMajorVersion; +using leveldb::kMinorVersion; +using leveldb::Logger; +using leveldb::NewBloomFilterPolicy; +using leveldb::NewLRUCache; +using leveldb::Options; +using leveldb::RandomAccessFile; +using leveldb::Range; +using leveldb::ReadOptions; +using leveldb::SequentialFile; +using leveldb::Slice; +using leveldb::Snapshot; +using leveldb::Status; +using leveldb::WritableFile; +using leveldb::WriteBatch; +using leveldb::WriteOptions; + +extern "C" { + +struct leveldb_t { DB* rep; }; +struct leveldb_iterator_t { Iterator* rep; }; +struct leveldb_writebatch_t { WriteBatch rep; }; +struct leveldb_snapshot_t { const Snapshot* rep; }; +struct leveldb_readoptions_t { ReadOptions rep; }; +struct leveldb_writeoptions_t { WriteOptions rep; }; +struct leveldb_options_t { Options rep; }; +struct leveldb_cache_t { Cache* rep; }; +struct leveldb_seqfile_t { SequentialFile* rep; }; +struct leveldb_randomfile_t { RandomAccessFile* rep; }; +struct leveldb_writablefile_t { WritableFile* rep; }; +struct leveldb_logger_t { Logger* rep; }; +struct leveldb_filelock_t { FileLock* rep; }; + +struct leveldb_comparator_t : public Comparator { + void* state_; + void (*destructor_)(void*); + int (*compare_)( + void*, + const char* a, size_t alen, + const char* b, size_t blen); + const char* (*name_)(void*); + + virtual ~leveldb_comparator_t() { + (*destructor_)(state_); + } + + virtual int Compare(const Slice& a, const Slice& b) const { + return (*compare_)(state_, a.data(), a.size(), b.data(), b.size()); + } + + virtual const char* Name() const { + return (*name_)(state_); + } + + // No-ops since the C binding does not support key shortening methods. + virtual void FindShortestSeparator(std::string*, const Slice&) const { } + virtual void FindShortSuccessor(std::string* key) const { } +}; + +struct leveldb_filterpolicy_t : public FilterPolicy { + void* state_; + void (*destructor_)(void*); + const char* (*name_)(void*); + char* (*create_)( + void*, + const char* const* key_array, const size_t* key_length_array, + int num_keys, + size_t* filter_length); + unsigned char (*key_match_)( + void*, + const char* key, size_t length, + const char* filter, size_t filter_length); + + virtual ~leveldb_filterpolicy_t() { + (*destructor_)(state_); + } + + virtual const char* Name() const { + return (*name_)(state_); + } + + virtual void CreateFilter(const Slice* keys, int n, std::string* dst) const { + std::vector key_pointers(n); + std::vector key_sizes(n); + for (int i = 0; i < n; i++) { + key_pointers[i] = keys[i].data(); + key_sizes[i] = keys[i].size(); + } + size_t len; + char* filter = (*create_)(state_, &key_pointers[0], &key_sizes[0], n, &len); + dst->append(filter, len); + free(filter); + } + + virtual bool KeyMayMatch(const Slice& key, const Slice& filter) const { + return (*key_match_)(state_, key.data(), key.size(), + filter.data(), filter.size()); + } +}; + +struct leveldb_env_t { + Env* rep; + bool is_default; +}; + +static bool SaveError(char** errptr, const Status& s) { + assert(errptr != NULL); + if (s.ok()) { + return false; + } else if (*errptr == NULL) { + *errptr = strdup(s.ToString().c_str()); + } else { + // TODO(sanjay): Merge with existing error? + free(*errptr); + *errptr = strdup(s.ToString().c_str()); + } + return true; +} + +static char* CopyString(const std::string& str) { + char* result = reinterpret_cast(malloc(sizeof(char) * str.size())); + memcpy(result, str.data(), sizeof(char) * str.size()); + return result; +} + +leveldb_t* leveldb_open( + const leveldb_options_t* options, + const char* name, + char** errptr) { + DB* db; + if (SaveError(errptr, DB::Open(options->rep, std::string(name), &db))) { + return NULL; + } + leveldb_t* result = new leveldb_t; + result->rep = db; + return result; +} + +void leveldb_close(leveldb_t* db) { + delete db->rep; + delete db; +} + +void leveldb_put( + leveldb_t* db, + const leveldb_writeoptions_t* options, + const char* key, size_t keylen, + const char* val, size_t vallen, + char** errptr) { + SaveError(errptr, + db->rep->Put(options->rep, Slice(key, keylen), Slice(val, vallen))); +} + +void leveldb_delete( + leveldb_t* db, + const leveldb_writeoptions_t* options, + const char* key, size_t keylen, + char** errptr) { + SaveError(errptr, db->rep->Delete(options->rep, Slice(key, keylen))); +} + + +void leveldb_write( + leveldb_t* db, + const leveldb_writeoptions_t* options, + leveldb_writebatch_t* batch, + char** errptr) { + SaveError(errptr, db->rep->Write(options->rep, &batch->rep)); +} + +char* leveldb_get( + leveldb_t* db, + const leveldb_readoptions_t* options, + const char* key, size_t keylen, + size_t* vallen, + char** errptr) { + char* result = NULL; + std::string tmp; + Status s = db->rep->Get(options->rep, Slice(key, keylen), &tmp); + if (s.ok()) { + *vallen = tmp.size(); + result = CopyString(tmp); + } else { + *vallen = 0; + if (!s.IsNotFound()) { + SaveError(errptr, s); + } + } + return result; +} + +leveldb_iterator_t* leveldb_create_iterator( + leveldb_t* db, + const leveldb_readoptions_t* options) { + leveldb_iterator_t* result = new leveldb_iterator_t; + result->rep = db->rep->NewIterator(options->rep); + return result; +} + +const leveldb_snapshot_t* leveldb_create_snapshot( + leveldb_t* db) { + leveldb_snapshot_t* result = new leveldb_snapshot_t; + result->rep = db->rep->GetSnapshot(); + return result; +} + +void leveldb_release_snapshot( + leveldb_t* db, + const leveldb_snapshot_t* snapshot) { + db->rep->ReleaseSnapshot(snapshot->rep); + delete snapshot; +} + +char* leveldb_property_value( + leveldb_t* db, + const char* propname) { + std::string tmp; + if (db->rep->GetProperty(Slice(propname), &tmp)) { + // We use strdup() since we expect human readable output. + return strdup(tmp.c_str()); + } else { + return NULL; + } +} + +void leveldb_approximate_sizes( + leveldb_t* db, + int num_ranges, + const char* const* range_start_key, const size_t* range_start_key_len, + const char* const* range_limit_key, const size_t* range_limit_key_len, + uint64_t* sizes) { + Range* ranges = new Range[num_ranges]; + for (int i = 0; i < num_ranges; i++) { + ranges[i].start = Slice(range_start_key[i], range_start_key_len[i]); + ranges[i].limit = Slice(range_limit_key[i], range_limit_key_len[i]); + } + db->rep->GetApproximateSizes(ranges, num_ranges, sizes); + delete[] ranges; +} + +void leveldb_compact_range( + leveldb_t* db, + const char* start_key, size_t start_key_len, + const char* limit_key, size_t limit_key_len) { + Slice a, b; + db->rep->CompactRange( + // Pass NULL Slice if corresponding "const char*" is NULL + (start_key ? (a = Slice(start_key, start_key_len), &a) : NULL), + (limit_key ? (b = Slice(limit_key, limit_key_len), &b) : NULL)); +} + +void leveldb_destroy_db( + const leveldb_options_t* options, + const char* name, + char** errptr) { + SaveError(errptr, DestroyDB(name, options->rep)); +} + +void leveldb_repair_db( + const leveldb_options_t* options, + const char* name, + char** errptr) { + SaveError(errptr, RepairDB(name, options->rep)); +} + +void leveldb_iter_destroy(leveldb_iterator_t* iter) { + delete iter->rep; + delete iter; +} + +unsigned char leveldb_iter_valid(const leveldb_iterator_t* iter) { + return iter->rep->Valid(); +} + +void leveldb_iter_seek_to_first(leveldb_iterator_t* iter) { + iter->rep->SeekToFirst(); +} + +void leveldb_iter_seek_to_last(leveldb_iterator_t* iter) { + iter->rep->SeekToLast(); +} + +void leveldb_iter_seek(leveldb_iterator_t* iter, const char* k, size_t klen) { + iter->rep->Seek(Slice(k, klen)); +} + +void leveldb_iter_next(leveldb_iterator_t* iter) { + iter->rep->Next(); +} + +void leveldb_iter_prev(leveldb_iterator_t* iter) { + iter->rep->Prev(); +} + +const char* leveldb_iter_key(const leveldb_iterator_t* iter, size_t* klen) { + Slice s = iter->rep->key(); + *klen = s.size(); + return s.data(); +} + +const char* leveldb_iter_value(const leveldb_iterator_t* iter, size_t* vlen) { + Slice s = iter->rep->value(); + *vlen = s.size(); + return s.data(); +} + +void leveldb_iter_get_error(const leveldb_iterator_t* iter, char** errptr) { + SaveError(errptr, iter->rep->status()); +} + +leveldb_writebatch_t* leveldb_writebatch_create() { + return new leveldb_writebatch_t; +} + +void leveldb_writebatch_destroy(leveldb_writebatch_t* b) { + delete b; +} + +void leveldb_writebatch_clear(leveldb_writebatch_t* b) { + b->rep.Clear(); +} + +void leveldb_writebatch_put( + leveldb_writebatch_t* b, + const char* key, size_t klen, + const char* val, size_t vlen) { + b->rep.Put(Slice(key, klen), Slice(val, vlen)); +} + +void leveldb_writebatch_delete( + leveldb_writebatch_t* b, + const char* key, size_t klen) { + b->rep.Delete(Slice(key, klen)); +} + +void leveldb_writebatch_iterate( + leveldb_writebatch_t* b, + void* state, + void (*put)(void*, const char* k, size_t klen, const char* v, size_t vlen), + void (*deleted)(void*, const char* k, size_t klen)) { + class H : public WriteBatch::Handler { + public: + void* state_; + void (*put_)(void*, const char* k, size_t klen, const char* v, size_t vlen); + void (*deleted_)(void*, const char* k, size_t klen); + virtual void Put(const Slice& key, const Slice& value) { + (*put_)(state_, key.data(), key.size(), value.data(), value.size()); + } + virtual void Delete(const Slice& key) { + (*deleted_)(state_, key.data(), key.size()); + } + }; + H handler; + handler.state_ = state; + handler.put_ = put; + handler.deleted_ = deleted; + b->rep.Iterate(&handler); +} + +leveldb_options_t* leveldb_options_create() { + return new leveldb_options_t; +} + +void leveldb_options_destroy(leveldb_options_t* options) { + delete options; +} + +void leveldb_options_set_comparator( + leveldb_options_t* opt, + leveldb_comparator_t* cmp) { + opt->rep.comparator = cmp; +} + +void leveldb_options_set_filter_policy( + leveldb_options_t* opt, + leveldb_filterpolicy_t* policy) { + opt->rep.filter_policy = policy; +} + +void leveldb_options_set_create_if_missing( + leveldb_options_t* opt, unsigned char v) { + opt->rep.create_if_missing = v; +} + +void leveldb_options_set_error_if_exists( + leveldb_options_t* opt, unsigned char v) { + opt->rep.error_if_exists = v; +} + +void leveldb_options_set_paranoid_checks( + leveldb_options_t* opt, unsigned char v) { + opt->rep.paranoid_checks = v; +} + +void leveldb_options_set_env(leveldb_options_t* opt, leveldb_env_t* env) { + opt->rep.env = (env ? env->rep : NULL); +} + +void leveldb_options_set_info_log(leveldb_options_t* opt, leveldb_logger_t* l) { + opt->rep.info_log = (l ? l->rep : NULL); +} + +void leveldb_options_set_write_buffer_size(leveldb_options_t* opt, size_t s) { + opt->rep.write_buffer_size = s; +} + +void leveldb_options_set_max_open_files(leveldb_options_t* opt, int n) { + opt->rep.max_open_files = n; +} + +void leveldb_options_set_cache(leveldb_options_t* opt, leveldb_cache_t* c) { + opt->rep.block_cache = c->rep; +} + +void leveldb_options_set_block_size(leveldb_options_t* opt, size_t s) { + opt->rep.block_size = s; +} + +void leveldb_options_set_block_restart_interval(leveldb_options_t* opt, int n) { + opt->rep.block_restart_interval = n; +} + +void leveldb_options_set_compression(leveldb_options_t* opt, int t) { + opt->rep.compression = static_cast(t); +} + +leveldb_comparator_t* leveldb_comparator_create( + void* state, + void (*destructor)(void*), + int (*compare)( + void*, + const char* a, size_t alen, + const char* b, size_t blen), + const char* (*name)(void*)) { + leveldb_comparator_t* result = new leveldb_comparator_t; + result->state_ = state; + result->destructor_ = destructor; + result->compare_ = compare; + result->name_ = name; + return result; +} + +void leveldb_comparator_destroy(leveldb_comparator_t* cmp) { + delete cmp; +} + +leveldb_filterpolicy_t* leveldb_filterpolicy_create( + void* state, + void (*destructor)(void*), + char* (*create_filter)( + void*, + const char* const* key_array, const size_t* key_length_array, + int num_keys, + size_t* filter_length), + unsigned char (*key_may_match)( + void*, + const char* key, size_t length, + const char* filter, size_t filter_length), + const char* (*name)(void*)) { + leveldb_filterpolicy_t* result = new leveldb_filterpolicy_t; + result->state_ = state; + result->destructor_ = destructor; + result->create_ = create_filter; + result->key_match_ = key_may_match; + result->name_ = name; + return result; +} + +void leveldb_filterpolicy_destroy(leveldb_filterpolicy_t* filter) { + delete filter; +} + +leveldb_filterpolicy_t* leveldb_filterpolicy_create_bloom(int bits_per_key) { + // Make a leveldb_filterpolicy_t, but override all of its methods so + // they delegate to a NewBloomFilterPolicy() instead of user + // supplied C functions. + struct Wrapper : public leveldb_filterpolicy_t { + const FilterPolicy* rep_; + ~Wrapper() { delete rep_; } + const char* Name() const { return rep_->Name(); } + void CreateFilter(const Slice* keys, int n, std::string* dst) const { + return rep_->CreateFilter(keys, n, dst); + } + bool KeyMayMatch(const Slice& key, const Slice& filter) const { + return rep_->KeyMayMatch(key, filter); + } + static void DoNothing(void*) { } + }; + Wrapper* wrapper = new Wrapper; + wrapper->rep_ = NewBloomFilterPolicy(bits_per_key); + wrapper->state_ = NULL; + wrapper->destructor_ = &Wrapper::DoNothing; + return wrapper; +} + +leveldb_readoptions_t* leveldb_readoptions_create() { + return new leveldb_readoptions_t; +} + +void leveldb_readoptions_destroy(leveldb_readoptions_t* opt) { + delete opt; +} + +void leveldb_readoptions_set_verify_checksums( + leveldb_readoptions_t* opt, + unsigned char v) { + opt->rep.verify_checksums = v; +} + +void leveldb_readoptions_set_fill_cache( + leveldb_readoptions_t* opt, unsigned char v) { + opt->rep.fill_cache = v; +} + +void leveldb_readoptions_set_snapshot( + leveldb_readoptions_t* opt, + const leveldb_snapshot_t* snap) { + opt->rep.snapshot = (snap ? snap->rep : NULL); +} + +leveldb_writeoptions_t* leveldb_writeoptions_create() { + return new leveldb_writeoptions_t; +} + +void leveldb_writeoptions_destroy(leveldb_writeoptions_t* opt) { + delete opt; +} + +void leveldb_writeoptions_set_sync( + leveldb_writeoptions_t* opt, unsigned char v) { + opt->rep.sync = v; +} + +leveldb_cache_t* leveldb_cache_create_lru(size_t capacity) { + leveldb_cache_t* c = new leveldb_cache_t; + c->rep = NewLRUCache(capacity); + return c; +} + +void leveldb_cache_destroy(leveldb_cache_t* cache) { + delete cache->rep; + delete cache; +} + +leveldb_env_t* leveldb_create_default_env() { + leveldb_env_t* result = new leveldb_env_t; + result->rep = Env::Default(); + result->is_default = true; + return result; +} + +void leveldb_env_destroy(leveldb_env_t* env) { + if (!env->is_default) delete env->rep; + delete env; +} + +void leveldb_free(void* ptr) { + free(ptr); +} + +int leveldb_major_version() { + return kMajorVersion; +} + +int leveldb_minor_version() { + return kMinorVersion; +} + +} // end extern "C" diff --git a/ios/Pods/leveldb-library/db/db_impl.cc b/ios/Pods/leveldb-library/db/db_impl.cc new file mode 100644 index 00000000..f43ad767 --- /dev/null +++ b/ios/Pods/leveldb-library/db/db_impl.cc @@ -0,0 +1,1568 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "db/db_impl.h" + +#include +#include +#include +#include +#include +#include +#include "db/builder.h" +#include "db/db_iter.h" +#include "db/dbformat.h" +#include "db/filename.h" +#include "db/log_reader.h" +#include "db/log_writer.h" +#include "db/memtable.h" +#include "db/table_cache.h" +#include "db/version_set.h" +#include "db/write_batch_internal.h" +#include "leveldb/db.h" +#include "leveldb/env.h" +#include "leveldb/status.h" +#include "leveldb/table.h" +#include "leveldb/table_builder.h" +#include "port/port.h" +#include "table/block.h" +#include "table/merger.h" +#include "table/two_level_iterator.h" +#include "util/coding.h" +#include "util/logging.h" +#include "util/mutexlock.h" + +namespace leveldb { + +const int kNumNonTableCacheFiles = 10; + +// Information kept for every waiting writer +struct DBImpl::Writer { + Status status; + WriteBatch* batch; + bool sync; + bool done; + port::CondVar cv; + + explicit Writer(port::Mutex* mu) : cv(mu) { } +}; + +struct DBImpl::CompactionState { + Compaction* const compaction; + + // Sequence numbers < smallest_snapshot are not significant since we + // will never have to service a snapshot below smallest_snapshot. + // Therefore if we have seen a sequence number S <= smallest_snapshot, + // we can drop all entries for the same key with sequence numbers < S. + SequenceNumber smallest_snapshot; + + // Files produced by compaction + struct Output { + uint64_t number; + uint64_t file_size; + InternalKey smallest, largest; + }; + std::vector outputs; + + // State kept for output being generated + WritableFile* outfile; + TableBuilder* builder; + + uint64_t total_bytes; + + Output* current_output() { return &outputs[outputs.size()-1]; } + + explicit CompactionState(Compaction* c) + : compaction(c), + outfile(NULL), + builder(NULL), + total_bytes(0) { + } +}; + +// Fix user-supplied options to be reasonable +template +static void ClipToRange(T* ptr, V minvalue, V maxvalue) { + if (static_cast(*ptr) > maxvalue) *ptr = maxvalue; + if (static_cast(*ptr) < minvalue) *ptr = minvalue; +} +Options SanitizeOptions(const std::string& dbname, + const InternalKeyComparator* icmp, + const InternalFilterPolicy* ipolicy, + const Options& src) { + Options result = src; + result.comparator = icmp; + result.filter_policy = (src.filter_policy != NULL) ? ipolicy : NULL; + ClipToRange(&result.max_open_files, 64 + kNumNonTableCacheFiles, 50000); + ClipToRange(&result.write_buffer_size, 64<<10, 1<<30); + ClipToRange(&result.max_file_size, 1<<20, 1<<30); + ClipToRange(&result.block_size, 1<<10, 4<<20); + if (result.info_log == NULL) { + // Open a log file in the same directory as the db + src.env->CreateDir(dbname); // In case it does not exist + src.env->RenameFile(InfoLogFileName(dbname), OldInfoLogFileName(dbname)); + Status s = src.env->NewLogger(InfoLogFileName(dbname), &result.info_log); + if (!s.ok()) { + // No place suitable for logging + result.info_log = NULL; + } + } + if (result.block_cache == NULL) { + result.block_cache = NewLRUCache(8 << 20); + } + return result; +} + +DBImpl::DBImpl(const Options& raw_options, const std::string& dbname) + : env_(raw_options.env), + internal_comparator_(raw_options.comparator), + internal_filter_policy_(raw_options.filter_policy), + options_(SanitizeOptions(dbname, &internal_comparator_, + &internal_filter_policy_, raw_options)), + owns_info_log_(options_.info_log != raw_options.info_log), + owns_cache_(options_.block_cache != raw_options.block_cache), + dbname_(dbname), + db_lock_(NULL), + shutting_down_(NULL), + bg_cv_(&mutex_), + mem_(NULL), + imm_(NULL), + logfile_(NULL), + logfile_number_(0), + log_(NULL), + seed_(0), + tmp_batch_(new WriteBatch), + bg_compaction_scheduled_(false), + manual_compaction_(NULL) { + has_imm_.Release_Store(NULL); + + // Reserve ten files or so for other uses and give the rest to TableCache. + const int table_cache_size = options_.max_open_files - kNumNonTableCacheFiles; + table_cache_ = new TableCache(dbname_, &options_, table_cache_size); + + versions_ = new VersionSet(dbname_, &options_, table_cache_, + &internal_comparator_); +} + +DBImpl::~DBImpl() { + // Wait for background work to finish + mutex_.Lock(); + shutting_down_.Release_Store(this); // Any non-NULL value is ok + while (bg_compaction_scheduled_) { + bg_cv_.Wait(); + } + mutex_.Unlock(); + + if (db_lock_ != NULL) { + env_->UnlockFile(db_lock_); + } + + delete versions_; + if (mem_ != NULL) mem_->Unref(); + if (imm_ != NULL) imm_->Unref(); + delete tmp_batch_; + delete log_; + delete logfile_; + delete table_cache_; + + if (owns_info_log_) { + delete options_.info_log; + } + if (owns_cache_) { + delete options_.block_cache; + } +} + +Status DBImpl::NewDB() { + VersionEdit new_db; + new_db.SetComparatorName(user_comparator()->Name()); + new_db.SetLogNumber(0); + new_db.SetNextFile(2); + new_db.SetLastSequence(0); + + const std::string manifest = DescriptorFileName(dbname_, 1); + WritableFile* file; + Status s = env_->NewWritableFile(manifest, &file); + if (!s.ok()) { + return s; + } + { + log::Writer log(file); + std::string record; + new_db.EncodeTo(&record); + s = log.AddRecord(record); + if (s.ok()) { + s = file->Close(); + } + } + delete file; + if (s.ok()) { + // Make "CURRENT" file that points to the new manifest file. + s = SetCurrentFile(env_, dbname_, 1); + } else { + env_->DeleteFile(manifest); + } + return s; +} + +void DBImpl::MaybeIgnoreError(Status* s) const { + if (s->ok() || options_.paranoid_checks) { + // No change needed + } else { + Log(options_.info_log, "Ignoring error %s", s->ToString().c_str()); + *s = Status::OK(); + } +} + +void DBImpl::DeleteObsoleteFiles() { + if (!bg_error_.ok()) { + // After a background error, we don't know whether a new version may + // or may not have been committed, so we cannot safely garbage collect. + return; + } + + // Make a set of all of the live files + std::set live = pending_outputs_; + versions_->AddLiveFiles(&live); + + std::vector filenames; + env_->GetChildren(dbname_, &filenames); // Ignoring errors on purpose + uint64_t number; + FileType type; + for (size_t i = 0; i < filenames.size(); i++) { + if (ParseFileName(filenames[i], &number, &type)) { + bool keep = true; + switch (type) { + case kLogFile: + keep = ((number >= versions_->LogNumber()) || + (number == versions_->PrevLogNumber())); + break; + case kDescriptorFile: + // Keep my manifest file, and any newer incarnations' + // (in case there is a race that allows other incarnations) + keep = (number >= versions_->ManifestFileNumber()); + break; + case kTableFile: + keep = (live.find(number) != live.end()); + break; + case kTempFile: + // Any temp files that are currently being written to must + // be recorded in pending_outputs_, which is inserted into "live" + keep = (live.find(number) != live.end()); + break; + case kCurrentFile: + case kDBLockFile: + case kInfoLogFile: + keep = true; + break; + } + + if (!keep) { + if (type == kTableFile) { + table_cache_->Evict(number); + } + Log(options_.info_log, "Delete type=%d #%lld\n", + int(type), + static_cast(number)); + env_->DeleteFile(dbname_ + "/" + filenames[i]); + } + } + } +} + +Status DBImpl::Recover(VersionEdit* edit, bool *save_manifest) { + mutex_.AssertHeld(); + + // Ignore error from CreateDir since the creation of the DB is + // committed only when the descriptor is created, and this directory + // may already exist from a previous failed creation attempt. + env_->CreateDir(dbname_); + assert(db_lock_ == NULL); + Status s = env_->LockFile(LockFileName(dbname_), &db_lock_); + if (!s.ok()) { + return s; + } + + if (!env_->FileExists(CurrentFileName(dbname_))) { + if (options_.create_if_missing) { + s = NewDB(); + if (!s.ok()) { + return s; + } + } else { + return Status::InvalidArgument( + dbname_, "does not exist (create_if_missing is false)"); + } + } else { + if (options_.error_if_exists) { + return Status::InvalidArgument( + dbname_, "exists (error_if_exists is true)"); + } + } + + s = versions_->Recover(save_manifest); + if (!s.ok()) { + return s; + } + SequenceNumber max_sequence(0); + + // Recover from all newer log files than the ones named in the + // descriptor (new log files may have been added by the previous + // incarnation without registering them in the descriptor). + // + // Note that PrevLogNumber() is no longer used, but we pay + // attention to it in case we are recovering a database + // produced by an older version of leveldb. + const uint64_t min_log = versions_->LogNumber(); + const uint64_t prev_log = versions_->PrevLogNumber(); + std::vector filenames; + s = env_->GetChildren(dbname_, &filenames); + if (!s.ok()) { + return s; + } + std::set expected; + versions_->AddLiveFiles(&expected); + uint64_t number; + FileType type; + std::vector logs; + for (size_t i = 0; i < filenames.size(); i++) { + if (ParseFileName(filenames[i], &number, &type)) { + expected.erase(number); + if (type == kLogFile && ((number >= min_log) || (number == prev_log))) + logs.push_back(number); + } + } + if (!expected.empty()) { + char buf[50]; + snprintf(buf, sizeof(buf), "%d missing files; e.g.", + static_cast(expected.size())); + return Status::Corruption(buf, TableFileName(dbname_, *(expected.begin()))); + } + + // Recover in the order in which the logs were generated + std::sort(logs.begin(), logs.end()); + for (size_t i = 0; i < logs.size(); i++) { + s = RecoverLogFile(logs[i], (i == logs.size() - 1), save_manifest, edit, + &max_sequence); + if (!s.ok()) { + return s; + } + + // The previous incarnation may not have written any MANIFEST + // records after allocating this log number. So we manually + // update the file number allocation counter in VersionSet. + versions_->MarkFileNumberUsed(logs[i]); + } + + if (versions_->LastSequence() < max_sequence) { + versions_->SetLastSequence(max_sequence); + } + + return Status::OK(); +} + +Status DBImpl::RecoverLogFile(uint64_t log_number, bool last_log, + bool* save_manifest, VersionEdit* edit, + SequenceNumber* max_sequence) { + struct LogReporter : public log::Reader::Reporter { + Env* env; + Logger* info_log; + const char* fname; + Status* status; // NULL if options_.paranoid_checks==false + virtual void Corruption(size_t bytes, const Status& s) { + Log(info_log, "%s%s: dropping %d bytes; %s", + (this->status == NULL ? "(ignoring error) " : ""), + fname, static_cast(bytes), s.ToString().c_str()); + if (this->status != NULL && this->status->ok()) *this->status = s; + } + }; + + mutex_.AssertHeld(); + + // Open the log file + std::string fname = LogFileName(dbname_, log_number); + SequentialFile* file; + Status status = env_->NewSequentialFile(fname, &file); + if (!status.ok()) { + MaybeIgnoreError(&status); + return status; + } + + // Create the log reader. + LogReporter reporter; + reporter.env = env_; + reporter.info_log = options_.info_log; + reporter.fname = fname.c_str(); + reporter.status = (options_.paranoid_checks ? &status : NULL); + // We intentionally make log::Reader do checksumming even if + // paranoid_checks==false so that corruptions cause entire commits + // to be skipped instead of propagating bad information (like overly + // large sequence numbers). + log::Reader reader(file, &reporter, true/*checksum*/, + 0/*initial_offset*/); + Log(options_.info_log, "Recovering log #%llu", + (unsigned long long) log_number); + + // Read all the records and add to a memtable + std::string scratch; + Slice record; + WriteBatch batch; + int compactions = 0; + MemTable* mem = NULL; + while (reader.ReadRecord(&record, &scratch) && + status.ok()) { + if (record.size() < 12) { + reporter.Corruption( + record.size(), Status::Corruption("log record too small")); + continue; + } + WriteBatchInternal::SetContents(&batch, record); + + if (mem == NULL) { + mem = new MemTable(internal_comparator_); + mem->Ref(); + } + status = WriteBatchInternal::InsertInto(&batch, mem); + MaybeIgnoreError(&status); + if (!status.ok()) { + break; + } + const SequenceNumber last_seq = + WriteBatchInternal::Sequence(&batch) + + WriteBatchInternal::Count(&batch) - 1; + if (last_seq > *max_sequence) { + *max_sequence = last_seq; + } + + if (mem->ApproximateMemoryUsage() > options_.write_buffer_size) { + compactions++; + *save_manifest = true; + status = WriteLevel0Table(mem, edit, NULL); + mem->Unref(); + mem = NULL; + if (!status.ok()) { + // Reflect errors immediately so that conditions like full + // file-systems cause the DB::Open() to fail. + break; + } + } + } + + delete file; + + // See if we should keep reusing the last log file. + if (status.ok() && options_.reuse_logs && last_log && compactions == 0) { + assert(logfile_ == NULL); + assert(log_ == NULL); + assert(mem_ == NULL); + uint64_t lfile_size; + if (env_->GetFileSize(fname, &lfile_size).ok() && + env_->NewAppendableFile(fname, &logfile_).ok()) { + Log(options_.info_log, "Reusing old log %s \n", fname.c_str()); + log_ = new log::Writer(logfile_, lfile_size); + logfile_number_ = log_number; + if (mem != NULL) { + mem_ = mem; + mem = NULL; + } else { + // mem can be NULL if lognum exists but was empty. + mem_ = new MemTable(internal_comparator_); + mem_->Ref(); + } + } + } + + if (mem != NULL) { + // mem did not get reused; compact it. + if (status.ok()) { + *save_manifest = true; + status = WriteLevel0Table(mem, edit, NULL); + } + mem->Unref(); + } + + return status; +} + +Status DBImpl::WriteLevel0Table(MemTable* mem, VersionEdit* edit, + Version* base) { + mutex_.AssertHeld(); + const uint64_t start_micros = env_->NowMicros(); + FileMetaData meta; + meta.number = versions_->NewFileNumber(); + pending_outputs_.insert(meta.number); + Iterator* iter = mem->NewIterator(); + Log(options_.info_log, "Level-0 table #%llu: started", + (unsigned long long) meta.number); + + Status s; + { + mutex_.Unlock(); + s = BuildTable(dbname_, env_, options_, table_cache_, iter, &meta); + mutex_.Lock(); + } + + Log(options_.info_log, "Level-0 table #%llu: %lld bytes %s", + (unsigned long long) meta.number, + (unsigned long long) meta.file_size, + s.ToString().c_str()); + delete iter; + pending_outputs_.erase(meta.number); + + + // Note that if file_size is zero, the file has been deleted and + // should not be added to the manifest. + int level = 0; + if (s.ok() && meta.file_size > 0) { + const Slice min_user_key = meta.smallest.user_key(); + const Slice max_user_key = meta.largest.user_key(); + if (base != NULL) { + level = base->PickLevelForMemTableOutput(min_user_key, max_user_key); + } + edit->AddFile(level, meta.number, meta.file_size, + meta.smallest, meta.largest); + } + + CompactionStats stats; + stats.micros = env_->NowMicros() - start_micros; + stats.bytes_written = meta.file_size; + stats_[level].Add(stats); + return s; +} + +void DBImpl::CompactMemTable() { + mutex_.AssertHeld(); + assert(imm_ != NULL); + + // Save the contents of the memtable as a new Table + VersionEdit edit; + Version* base = versions_->current(); + base->Ref(); + Status s = WriteLevel0Table(imm_, &edit, base); + base->Unref(); + + if (s.ok() && shutting_down_.Acquire_Load()) { + s = Status::IOError("Deleting DB during memtable compaction"); + } + + // Replace immutable memtable with the generated Table + if (s.ok()) { + edit.SetPrevLogNumber(0); + edit.SetLogNumber(logfile_number_); // Earlier logs no longer needed + s = versions_->LogAndApply(&edit, &mutex_); + } + + if (s.ok()) { + // Commit to the new state + imm_->Unref(); + imm_ = NULL; + has_imm_.Release_Store(NULL); + DeleteObsoleteFiles(); + } else { + RecordBackgroundError(s); + } +} + +void DBImpl::CompactRange(const Slice* begin, const Slice* end) { + int max_level_with_files = 1; + { + MutexLock l(&mutex_); + Version* base = versions_->current(); + for (int level = 1; level < config::kNumLevels; level++) { + if (base->OverlapInLevel(level, begin, end)) { + max_level_with_files = level; + } + } + } + TEST_CompactMemTable(); // TODO(sanjay): Skip if memtable does not overlap + for (int level = 0; level < max_level_with_files; level++) { + TEST_CompactRange(level, begin, end); + } +} + +void DBImpl::TEST_CompactRange(int level, const Slice* begin,const Slice* end) { + assert(level >= 0); + assert(level + 1 < config::kNumLevels); + + InternalKey begin_storage, end_storage; + + ManualCompaction manual; + manual.level = level; + manual.done = false; + if (begin == NULL) { + manual.begin = NULL; + } else { + begin_storage = InternalKey(*begin, kMaxSequenceNumber, kValueTypeForSeek); + manual.begin = &begin_storage; + } + if (end == NULL) { + manual.end = NULL; + } else { + end_storage = InternalKey(*end, 0, static_cast(0)); + manual.end = &end_storage; + } + + MutexLock l(&mutex_); + while (!manual.done && !shutting_down_.Acquire_Load() && bg_error_.ok()) { + if (manual_compaction_ == NULL) { // Idle + manual_compaction_ = &manual; + MaybeScheduleCompaction(); + } else { // Running either my compaction or another compaction. + bg_cv_.Wait(); + } + } + if (manual_compaction_ == &manual) { + // Cancel my manual compaction since we aborted early for some reason. + manual_compaction_ = NULL; + } +} + +Status DBImpl::TEST_CompactMemTable() { + // NULL batch means just wait for earlier writes to be done + Status s = Write(WriteOptions(), NULL); + if (s.ok()) { + // Wait until the compaction completes + MutexLock l(&mutex_); + while (imm_ != NULL && bg_error_.ok()) { + bg_cv_.Wait(); + } + if (imm_ != NULL) { + s = bg_error_; + } + } + return s; +} + +void DBImpl::RecordBackgroundError(const Status& s) { + mutex_.AssertHeld(); + if (bg_error_.ok()) { + bg_error_ = s; + bg_cv_.SignalAll(); + } +} + +void DBImpl::MaybeScheduleCompaction() { + mutex_.AssertHeld(); + if (bg_compaction_scheduled_) { + // Already scheduled + } else if (shutting_down_.Acquire_Load()) { + // DB is being deleted; no more background compactions + } else if (!bg_error_.ok()) { + // Already got an error; no more changes + } else if (imm_ == NULL && + manual_compaction_ == NULL && + !versions_->NeedsCompaction()) { + // No work to be done + } else { + bg_compaction_scheduled_ = true; + env_->Schedule(&DBImpl::BGWork, this); + } +} + +void DBImpl::BGWork(void* db) { + reinterpret_cast(db)->BackgroundCall(); +} + +void DBImpl::BackgroundCall() { + MutexLock l(&mutex_); + assert(bg_compaction_scheduled_); + if (shutting_down_.Acquire_Load()) { + // No more background work when shutting down. + } else if (!bg_error_.ok()) { + // No more background work after a background error. + } else { + BackgroundCompaction(); + } + + bg_compaction_scheduled_ = false; + + // Previous compaction may have produced too many files in a level, + // so reschedule another compaction if needed. + MaybeScheduleCompaction(); + bg_cv_.SignalAll(); +} + +void DBImpl::BackgroundCompaction() { + mutex_.AssertHeld(); + + if (imm_ != NULL) { + CompactMemTable(); + return; + } + + Compaction* c; + bool is_manual = (manual_compaction_ != NULL); + InternalKey manual_end; + if (is_manual) { + ManualCompaction* m = manual_compaction_; + c = versions_->CompactRange(m->level, m->begin, m->end); + m->done = (c == NULL); + if (c != NULL) { + manual_end = c->input(0, c->num_input_files(0) - 1)->largest; + } + Log(options_.info_log, + "Manual compaction at level-%d from %s .. %s; will stop at %s\n", + m->level, + (m->begin ? m->begin->DebugString().c_str() : "(begin)"), + (m->end ? m->end->DebugString().c_str() : "(end)"), + (m->done ? "(end)" : manual_end.DebugString().c_str())); + } else { + c = versions_->PickCompaction(); + } + + Status status; + if (c == NULL) { + // Nothing to do + } else if (!is_manual && c->IsTrivialMove()) { + // Move file to next level + assert(c->num_input_files(0) == 1); + FileMetaData* f = c->input(0, 0); + c->edit()->DeleteFile(c->level(), f->number); + c->edit()->AddFile(c->level() + 1, f->number, f->file_size, + f->smallest, f->largest); + status = versions_->LogAndApply(c->edit(), &mutex_); + if (!status.ok()) { + RecordBackgroundError(status); + } + VersionSet::LevelSummaryStorage tmp; + Log(options_.info_log, "Moved #%lld to level-%d %lld bytes %s: %s\n", + static_cast(f->number), + c->level() + 1, + static_cast(f->file_size), + status.ToString().c_str(), + versions_->LevelSummary(&tmp)); + } else { + CompactionState* compact = new CompactionState(c); + status = DoCompactionWork(compact); + if (!status.ok()) { + RecordBackgroundError(status); + } + CleanupCompaction(compact); + c->ReleaseInputs(); + DeleteObsoleteFiles(); + } + delete c; + + if (status.ok()) { + // Done + } else if (shutting_down_.Acquire_Load()) { + // Ignore compaction errors found during shutting down + } else { + Log(options_.info_log, + "Compaction error: %s", status.ToString().c_str()); + } + + if (is_manual) { + ManualCompaction* m = manual_compaction_; + if (!status.ok()) { + m->done = true; + } + if (!m->done) { + // We only compacted part of the requested range. Update *m + // to the range that is left to be compacted. + m->tmp_storage = manual_end; + m->begin = &m->tmp_storage; + } + manual_compaction_ = NULL; + } +} + +void DBImpl::CleanupCompaction(CompactionState* compact) { + mutex_.AssertHeld(); + if (compact->builder != NULL) { + // May happen if we get a shutdown call in the middle of compaction + compact->builder->Abandon(); + delete compact->builder; + } else { + assert(compact->outfile == NULL); + } + delete compact->outfile; + for (size_t i = 0; i < compact->outputs.size(); i++) { + const CompactionState::Output& out = compact->outputs[i]; + pending_outputs_.erase(out.number); + } + delete compact; +} + +Status DBImpl::OpenCompactionOutputFile(CompactionState* compact) { + assert(compact != NULL); + assert(compact->builder == NULL); + uint64_t file_number; + { + mutex_.Lock(); + file_number = versions_->NewFileNumber(); + pending_outputs_.insert(file_number); + CompactionState::Output out; + out.number = file_number; + out.smallest.Clear(); + out.largest.Clear(); + compact->outputs.push_back(out); + mutex_.Unlock(); + } + + // Make the output file + std::string fname = TableFileName(dbname_, file_number); + Status s = env_->NewWritableFile(fname, &compact->outfile); + if (s.ok()) { + compact->builder = new TableBuilder(options_, compact->outfile); + } + return s; +} + +Status DBImpl::FinishCompactionOutputFile(CompactionState* compact, + Iterator* input) { + assert(compact != NULL); + assert(compact->outfile != NULL); + assert(compact->builder != NULL); + + const uint64_t output_number = compact->current_output()->number; + assert(output_number != 0); + + // Check for iterator errors + Status s = input->status(); + const uint64_t current_entries = compact->builder->NumEntries(); + if (s.ok()) { + s = compact->builder->Finish(); + } else { + compact->builder->Abandon(); + } + const uint64_t current_bytes = compact->builder->FileSize(); + compact->current_output()->file_size = current_bytes; + compact->total_bytes += current_bytes; + delete compact->builder; + compact->builder = NULL; + + // Finish and check for file errors + if (s.ok()) { + s = compact->outfile->Sync(); + } + if (s.ok()) { + s = compact->outfile->Close(); + } + delete compact->outfile; + compact->outfile = NULL; + + if (s.ok() && current_entries > 0) { + // Verify that the table is usable + Iterator* iter = table_cache_->NewIterator(ReadOptions(), + output_number, + current_bytes); + s = iter->status(); + delete iter; + if (s.ok()) { + Log(options_.info_log, + "Generated table #%llu@%d: %lld keys, %lld bytes", + (unsigned long long) output_number, + compact->compaction->level(), + (unsigned long long) current_entries, + (unsigned long long) current_bytes); + } + } + return s; +} + + +Status DBImpl::InstallCompactionResults(CompactionState* compact) { + mutex_.AssertHeld(); + Log(options_.info_log, "Compacted %d@%d + %d@%d files => %lld bytes", + compact->compaction->num_input_files(0), + compact->compaction->level(), + compact->compaction->num_input_files(1), + compact->compaction->level() + 1, + static_cast(compact->total_bytes)); + + // Add compaction outputs + compact->compaction->AddInputDeletions(compact->compaction->edit()); + const int level = compact->compaction->level(); + for (size_t i = 0; i < compact->outputs.size(); i++) { + const CompactionState::Output& out = compact->outputs[i]; + compact->compaction->edit()->AddFile( + level + 1, + out.number, out.file_size, out.smallest, out.largest); + } + return versions_->LogAndApply(compact->compaction->edit(), &mutex_); +} + +Status DBImpl::DoCompactionWork(CompactionState* compact) { + const uint64_t start_micros = env_->NowMicros(); + int64_t imm_micros = 0; // Micros spent doing imm_ compactions + + Log(options_.info_log, "Compacting %d@%d + %d@%d files", + compact->compaction->num_input_files(0), + compact->compaction->level(), + compact->compaction->num_input_files(1), + compact->compaction->level() + 1); + + assert(versions_->NumLevelFiles(compact->compaction->level()) > 0); + assert(compact->builder == NULL); + assert(compact->outfile == NULL); + if (snapshots_.empty()) { + compact->smallest_snapshot = versions_->LastSequence(); + } else { + compact->smallest_snapshot = snapshots_.oldest()->number_; + } + + // Release mutex while we're actually doing the compaction work + mutex_.Unlock(); + + Iterator* input = versions_->MakeInputIterator(compact->compaction); + input->SeekToFirst(); + Status status; + ParsedInternalKey ikey; + std::string current_user_key; + bool has_current_user_key = false; + SequenceNumber last_sequence_for_key = kMaxSequenceNumber; + for (; input->Valid() && !shutting_down_.Acquire_Load(); ) { + // Prioritize immutable compaction work + if (has_imm_.NoBarrier_Load() != NULL) { + const uint64_t imm_start = env_->NowMicros(); + mutex_.Lock(); + if (imm_ != NULL) { + CompactMemTable(); + bg_cv_.SignalAll(); // Wakeup MakeRoomForWrite() if necessary + } + mutex_.Unlock(); + imm_micros += (env_->NowMicros() - imm_start); + } + + Slice key = input->key(); + if (compact->compaction->ShouldStopBefore(key) && + compact->builder != NULL) { + status = FinishCompactionOutputFile(compact, input); + if (!status.ok()) { + break; + } + } + + // Handle key/value, add to state, etc. + bool drop = false; + if (!ParseInternalKey(key, &ikey)) { + // Do not hide error keys + current_user_key.clear(); + has_current_user_key = false; + last_sequence_for_key = kMaxSequenceNumber; + } else { + if (!has_current_user_key || + user_comparator()->Compare(ikey.user_key, + Slice(current_user_key)) != 0) { + // First occurrence of this user key + current_user_key.assign(ikey.user_key.data(), ikey.user_key.size()); + has_current_user_key = true; + last_sequence_for_key = kMaxSequenceNumber; + } + + if (last_sequence_for_key <= compact->smallest_snapshot) { + // Hidden by an newer entry for same user key + drop = true; // (A) + } else if (ikey.type == kTypeDeletion && + ikey.sequence <= compact->smallest_snapshot && + compact->compaction->IsBaseLevelForKey(ikey.user_key)) { + // For this user key: + // (1) there is no data in higher levels + // (2) data in lower levels will have larger sequence numbers + // (3) data in layers that are being compacted here and have + // smaller sequence numbers will be dropped in the next + // few iterations of this loop (by rule (A) above). + // Therefore this deletion marker is obsolete and can be dropped. + drop = true; + } + + last_sequence_for_key = ikey.sequence; + } +#if 0 + Log(options_.info_log, + " Compact: %s, seq %d, type: %d %d, drop: %d, is_base: %d, " + "%d smallest_snapshot: %d", + ikey.user_key.ToString().c_str(), + (int)ikey.sequence, ikey.type, kTypeValue, drop, + compact->compaction->IsBaseLevelForKey(ikey.user_key), + (int)last_sequence_for_key, (int)compact->smallest_snapshot); +#endif + + if (!drop) { + // Open output file if necessary + if (compact->builder == NULL) { + status = OpenCompactionOutputFile(compact); + if (!status.ok()) { + break; + } + } + if (compact->builder->NumEntries() == 0) { + compact->current_output()->smallest.DecodeFrom(key); + } + compact->current_output()->largest.DecodeFrom(key); + compact->builder->Add(key, input->value()); + + // Close output file if it is big enough + if (compact->builder->FileSize() >= + compact->compaction->MaxOutputFileSize()) { + status = FinishCompactionOutputFile(compact, input); + if (!status.ok()) { + break; + } + } + } + + input->Next(); + } + + if (status.ok() && shutting_down_.Acquire_Load()) { + status = Status::IOError("Deleting DB during compaction"); + } + if (status.ok() && compact->builder != NULL) { + status = FinishCompactionOutputFile(compact, input); + } + if (status.ok()) { + status = input->status(); + } + delete input; + input = NULL; + + CompactionStats stats; + stats.micros = env_->NowMicros() - start_micros - imm_micros; + for (int which = 0; which < 2; which++) { + for (int i = 0; i < compact->compaction->num_input_files(which); i++) { + stats.bytes_read += compact->compaction->input(which, i)->file_size; + } + } + for (size_t i = 0; i < compact->outputs.size(); i++) { + stats.bytes_written += compact->outputs[i].file_size; + } + + mutex_.Lock(); + stats_[compact->compaction->level() + 1].Add(stats); + + if (status.ok()) { + status = InstallCompactionResults(compact); + } + if (!status.ok()) { + RecordBackgroundError(status); + } + VersionSet::LevelSummaryStorage tmp; + Log(options_.info_log, + "compacted to: %s", versions_->LevelSummary(&tmp)); + return status; +} + +namespace { +struct IterState { + port::Mutex* mu; + Version* version; + MemTable* mem; + MemTable* imm; +}; + +static void CleanupIteratorState(void* arg1, void* arg2) { + IterState* state = reinterpret_cast(arg1); + state->mu->Lock(); + state->mem->Unref(); + if (state->imm != NULL) state->imm->Unref(); + state->version->Unref(); + state->mu->Unlock(); + delete state; +} +} // namespace + +Iterator* DBImpl::NewInternalIterator(const ReadOptions& options, + SequenceNumber* latest_snapshot, + uint32_t* seed) { + IterState* cleanup = new IterState; + mutex_.Lock(); + *latest_snapshot = versions_->LastSequence(); + + // Collect together all needed child iterators + std::vector list; + list.push_back(mem_->NewIterator()); + mem_->Ref(); + if (imm_ != NULL) { + list.push_back(imm_->NewIterator()); + imm_->Ref(); + } + versions_->current()->AddIterators(options, &list); + Iterator* internal_iter = + NewMergingIterator(&internal_comparator_, &list[0], list.size()); + versions_->current()->Ref(); + + cleanup->mu = &mutex_; + cleanup->mem = mem_; + cleanup->imm = imm_; + cleanup->version = versions_->current(); + internal_iter->RegisterCleanup(CleanupIteratorState, cleanup, NULL); + + *seed = ++seed_; + mutex_.Unlock(); + return internal_iter; +} + +Iterator* DBImpl::TEST_NewInternalIterator() { + SequenceNumber ignored; + uint32_t ignored_seed; + return NewInternalIterator(ReadOptions(), &ignored, &ignored_seed); +} + +int64_t DBImpl::TEST_MaxNextLevelOverlappingBytes() { + MutexLock l(&mutex_); + return versions_->MaxNextLevelOverlappingBytes(); +} + +Status DBImpl::Get(const ReadOptions& options, + const Slice& key, + std::string* value) { + Status s; + MutexLock l(&mutex_); + SequenceNumber snapshot; + if (options.snapshot != NULL) { + snapshot = reinterpret_cast(options.snapshot)->number_; + } else { + snapshot = versions_->LastSequence(); + } + + MemTable* mem = mem_; + MemTable* imm = imm_; + Version* current = versions_->current(); + mem->Ref(); + if (imm != NULL) imm->Ref(); + current->Ref(); + + bool have_stat_update = false; + Version::GetStats stats; + + // Unlock while reading from files and memtables + { + mutex_.Unlock(); + // First look in the memtable, then in the immutable memtable (if any). + LookupKey lkey(key, snapshot); + if (mem->Get(lkey, value, &s)) { + // Done + } else if (imm != NULL && imm->Get(lkey, value, &s)) { + // Done + } else { + s = current->Get(options, lkey, value, &stats); + have_stat_update = true; + } + mutex_.Lock(); + } + + if (have_stat_update && current->UpdateStats(stats)) { + MaybeScheduleCompaction(); + } + mem->Unref(); + if (imm != NULL) imm->Unref(); + current->Unref(); + return s; +} + +Iterator* DBImpl::NewIterator(const ReadOptions& options) { + SequenceNumber latest_snapshot; + uint32_t seed; + Iterator* iter = NewInternalIterator(options, &latest_snapshot, &seed); + return NewDBIterator( + this, user_comparator(), iter, + (options.snapshot != NULL + ? reinterpret_cast(options.snapshot)->number_ + : latest_snapshot), + seed); +} + +void DBImpl::RecordReadSample(Slice key) { + MutexLock l(&mutex_); + if (versions_->current()->RecordReadSample(key)) { + MaybeScheduleCompaction(); + } +} + +const Snapshot* DBImpl::GetSnapshot() { + MutexLock l(&mutex_); + return snapshots_.New(versions_->LastSequence()); +} + +void DBImpl::ReleaseSnapshot(const Snapshot* s) { + MutexLock l(&mutex_); + snapshots_.Delete(reinterpret_cast(s)); +} + +// Convenience methods +Status DBImpl::Put(const WriteOptions& o, const Slice& key, const Slice& val) { + return DB::Put(o, key, val); +} + +Status DBImpl::Delete(const WriteOptions& options, const Slice& key) { + return DB::Delete(options, key); +} + +Status DBImpl::Write(const WriteOptions& options, WriteBatch* my_batch) { + Writer w(&mutex_); + w.batch = my_batch; + w.sync = options.sync; + w.done = false; + + MutexLock l(&mutex_); + writers_.push_back(&w); + while (!w.done && &w != writers_.front()) { + w.cv.Wait(); + } + if (w.done) { + return w.status; + } + + // May temporarily unlock and wait. + Status status = MakeRoomForWrite(my_batch == NULL); + uint64_t last_sequence = versions_->LastSequence(); + Writer* last_writer = &w; + if (status.ok() && my_batch != NULL) { // NULL batch is for compactions + WriteBatch* updates = BuildBatchGroup(&last_writer); + WriteBatchInternal::SetSequence(updates, last_sequence + 1); + last_sequence += WriteBatchInternal::Count(updates); + + // Add to log and apply to memtable. We can release the lock + // during this phase since &w is currently responsible for logging + // and protects against concurrent loggers and concurrent writes + // into mem_. + { + mutex_.Unlock(); + status = log_->AddRecord(WriteBatchInternal::Contents(updates)); + bool sync_error = false; + if (status.ok() && options.sync) { + status = logfile_->Sync(); + if (!status.ok()) { + sync_error = true; + } + } + if (status.ok()) { + status = WriteBatchInternal::InsertInto(updates, mem_); + } + mutex_.Lock(); + if (sync_error) { + // The state of the log file is indeterminate: the log record we + // just added may or may not show up when the DB is re-opened. + // So we force the DB into a mode where all future writes fail. + RecordBackgroundError(status); + } + } + if (updates == tmp_batch_) tmp_batch_->Clear(); + + versions_->SetLastSequence(last_sequence); + } + + while (true) { + Writer* ready = writers_.front(); + writers_.pop_front(); + if (ready != &w) { + ready->status = status; + ready->done = true; + ready->cv.Signal(); + } + if (ready == last_writer) break; + } + + // Notify new head of write queue + if (!writers_.empty()) { + writers_.front()->cv.Signal(); + } + + return status; +} + +// REQUIRES: Writer list must be non-empty +// REQUIRES: First writer must have a non-NULL batch +WriteBatch* DBImpl::BuildBatchGroup(Writer** last_writer) { + assert(!writers_.empty()); + Writer* first = writers_.front(); + WriteBatch* result = first->batch; + assert(result != NULL); + + size_t size = WriteBatchInternal::ByteSize(first->batch); + + // Allow the group to grow up to a maximum size, but if the + // original write is small, limit the growth so we do not slow + // down the small write too much. + size_t max_size = 1 << 20; + if (size <= (128<<10)) { + max_size = size + (128<<10); + } + + *last_writer = first; + std::deque::iterator iter = writers_.begin(); + ++iter; // Advance past "first" + for (; iter != writers_.end(); ++iter) { + Writer* w = *iter; + if (w->sync && !first->sync) { + // Do not include a sync write into a batch handled by a non-sync write. + break; + } + + if (w->batch != NULL) { + size += WriteBatchInternal::ByteSize(w->batch); + if (size > max_size) { + // Do not make batch too big + break; + } + + // Append to *result + if (result == first->batch) { + // Switch to temporary batch instead of disturbing caller's batch + result = tmp_batch_; + assert(WriteBatchInternal::Count(result) == 0); + WriteBatchInternal::Append(result, first->batch); + } + WriteBatchInternal::Append(result, w->batch); + } + *last_writer = w; + } + return result; +} + +// REQUIRES: mutex_ is held +// REQUIRES: this thread is currently at the front of the writer queue +Status DBImpl::MakeRoomForWrite(bool force) { + mutex_.AssertHeld(); + assert(!writers_.empty()); + bool allow_delay = !force; + Status s; + while (true) { + if (!bg_error_.ok()) { + // Yield previous error + s = bg_error_; + break; + } else if ( + allow_delay && + versions_->NumLevelFiles(0) >= config::kL0_SlowdownWritesTrigger) { + // We are getting close to hitting a hard limit on the number of + // L0 files. Rather than delaying a single write by several + // seconds when we hit the hard limit, start delaying each + // individual write by 1ms to reduce latency variance. Also, + // this delay hands over some CPU to the compaction thread in + // case it is sharing the same core as the writer. + mutex_.Unlock(); + env_->SleepForMicroseconds(1000); + allow_delay = false; // Do not delay a single write more than once + mutex_.Lock(); + } else if (!force && + (mem_->ApproximateMemoryUsage() <= options_.write_buffer_size)) { + // There is room in current memtable + break; + } else if (imm_ != NULL) { + // We have filled up the current memtable, but the previous + // one is still being compacted, so we wait. + Log(options_.info_log, "Current memtable full; waiting...\n"); + bg_cv_.Wait(); + } else if (versions_->NumLevelFiles(0) >= config::kL0_StopWritesTrigger) { + // There are too many level-0 files. + Log(options_.info_log, "Too many L0 files; waiting...\n"); + bg_cv_.Wait(); + } else { + // Attempt to switch to a new memtable and trigger compaction of old + assert(versions_->PrevLogNumber() == 0); + uint64_t new_log_number = versions_->NewFileNumber(); + WritableFile* lfile = NULL; + s = env_->NewWritableFile(LogFileName(dbname_, new_log_number), &lfile); + if (!s.ok()) { + // Avoid chewing through file number space in a tight loop. + versions_->ReuseFileNumber(new_log_number); + break; + } + delete log_; + delete logfile_; + logfile_ = lfile; + logfile_number_ = new_log_number; + log_ = new log::Writer(lfile); + imm_ = mem_; + has_imm_.Release_Store(imm_); + mem_ = new MemTable(internal_comparator_); + mem_->Ref(); + force = false; // Do not force another compaction if have room + MaybeScheduleCompaction(); + } + } + return s; +} + +bool DBImpl::GetProperty(const Slice& property, std::string* value) { + value->clear(); + + MutexLock l(&mutex_); + Slice in = property; + Slice prefix("leveldb."); + if (!in.starts_with(prefix)) return false; + in.remove_prefix(prefix.size()); + + if (in.starts_with("num-files-at-level")) { + in.remove_prefix(strlen("num-files-at-level")); + uint64_t level; + bool ok = ConsumeDecimalNumber(&in, &level) && in.empty(); + if (!ok || level >= config::kNumLevels) { + return false; + } else { + char buf[100]; + snprintf(buf, sizeof(buf), "%d", + versions_->NumLevelFiles(static_cast(level))); + *value = buf; + return true; + } + } else if (in == "stats") { + char buf[200]; + snprintf(buf, sizeof(buf), + " Compactions\n" + "Level Files Size(MB) Time(sec) Read(MB) Write(MB)\n" + "--------------------------------------------------\n" + ); + value->append(buf); + for (int level = 0; level < config::kNumLevels; level++) { + int files = versions_->NumLevelFiles(level); + if (stats_[level].micros > 0 || files > 0) { + snprintf( + buf, sizeof(buf), + "%3d %8d %8.0f %9.0f %8.0f %9.0f\n", + level, + files, + versions_->NumLevelBytes(level) / 1048576.0, + stats_[level].micros / 1e6, + stats_[level].bytes_read / 1048576.0, + stats_[level].bytes_written / 1048576.0); + value->append(buf); + } + } + return true; + } else if (in == "sstables") { + *value = versions_->current()->DebugString(); + return true; + } else if (in == "approximate-memory-usage") { + size_t total_usage = options_.block_cache->TotalCharge(); + if (mem_) { + total_usage += mem_->ApproximateMemoryUsage(); + } + if (imm_) { + total_usage += imm_->ApproximateMemoryUsage(); + } + char buf[50]; + snprintf(buf, sizeof(buf), "%llu", + static_cast(total_usage)); + value->append(buf); + return true; + } + + return false; +} + +void DBImpl::GetApproximateSizes( + const Range* range, int n, + uint64_t* sizes) { + // TODO(opt): better implementation + Version* v; + { + MutexLock l(&mutex_); + versions_->current()->Ref(); + v = versions_->current(); + } + + for (int i = 0; i < n; i++) { + // Convert user_key into a corresponding internal key. + InternalKey k1(range[i].start, kMaxSequenceNumber, kValueTypeForSeek); + InternalKey k2(range[i].limit, kMaxSequenceNumber, kValueTypeForSeek); + uint64_t start = versions_->ApproximateOffsetOf(v, k1); + uint64_t limit = versions_->ApproximateOffsetOf(v, k2); + sizes[i] = (limit >= start ? limit - start : 0); + } + + { + MutexLock l(&mutex_); + v->Unref(); + } +} + +// Default implementations of convenience methods that subclasses of DB +// can call if they wish +Status DB::Put(const WriteOptions& opt, const Slice& key, const Slice& value) { + WriteBatch batch; + batch.Put(key, value); + return Write(opt, &batch); +} + +Status DB::Delete(const WriteOptions& opt, const Slice& key) { + WriteBatch batch; + batch.Delete(key); + return Write(opt, &batch); +} + +DB::~DB() { } + +Status DB::Open(const Options& options, const std::string& dbname, + DB** dbptr) { + *dbptr = NULL; + + DBImpl* impl = new DBImpl(options, dbname); + impl->mutex_.Lock(); + VersionEdit edit; + // Recover handles create_if_missing, error_if_exists + bool save_manifest = false; + Status s = impl->Recover(&edit, &save_manifest); + if (s.ok() && impl->mem_ == NULL) { + // Create new log and a corresponding memtable. + uint64_t new_log_number = impl->versions_->NewFileNumber(); + WritableFile* lfile; + s = options.env->NewWritableFile(LogFileName(dbname, new_log_number), + &lfile); + if (s.ok()) { + edit.SetLogNumber(new_log_number); + impl->logfile_ = lfile; + impl->logfile_number_ = new_log_number; + impl->log_ = new log::Writer(lfile); + impl->mem_ = new MemTable(impl->internal_comparator_); + impl->mem_->Ref(); + } + } + if (s.ok() && save_manifest) { + edit.SetPrevLogNumber(0); // No older logs needed after recovery. + edit.SetLogNumber(impl->logfile_number_); + s = impl->versions_->LogAndApply(&edit, &impl->mutex_); + } + if (s.ok()) { + impl->DeleteObsoleteFiles(); + impl->MaybeScheduleCompaction(); + } + impl->mutex_.Unlock(); + if (s.ok()) { + assert(impl->mem_ != NULL); + *dbptr = impl; + } else { + delete impl; + } + return s; +} + +Snapshot::~Snapshot() { +} + +Status DestroyDB(const std::string& dbname, const Options& options) { + Env* env = options.env; + std::vector filenames; + // Ignore error in case directory does not exist + env->GetChildren(dbname, &filenames); + if (filenames.empty()) { + return Status::OK(); + } + + FileLock* lock; + const std::string lockname = LockFileName(dbname); + Status result = env->LockFile(lockname, &lock); + if (result.ok()) { + uint64_t number; + FileType type; + for (size_t i = 0; i < filenames.size(); i++) { + if (ParseFileName(filenames[i], &number, &type) && + type != kDBLockFile) { // Lock file will be deleted at end + Status del = env->DeleteFile(dbname + "/" + filenames[i]); + if (result.ok() && !del.ok()) { + result = del; + } + } + } + env->UnlockFile(lock); // Ignore error since state is already gone + env->DeleteFile(lockname); + env->DeleteDir(dbname); // Ignore error in case dir contains other files + } + return result; +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/db/db_impl.h b/ios/Pods/leveldb-library/db/db_impl.h new file mode 100644 index 00000000..8ff323e7 --- /dev/null +++ b/ios/Pods/leveldb-library/db/db_impl.h @@ -0,0 +1,211 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_DB_DB_IMPL_H_ +#define STORAGE_LEVELDB_DB_DB_IMPL_H_ + +#include +#include +#include "db/dbformat.h" +#include "db/log_writer.h" +#include "db/snapshot.h" +#include "leveldb/db.h" +#include "leveldb/env.h" +#include "port/port.h" +#include "port/thread_annotations.h" + +namespace leveldb { + +class MemTable; +class TableCache; +class Version; +class VersionEdit; +class VersionSet; + +class DBImpl : public DB { + public: + DBImpl(const Options& options, const std::string& dbname); + virtual ~DBImpl(); + + // Implementations of the DB interface + virtual Status Put(const WriteOptions&, const Slice& key, const Slice& value); + virtual Status Delete(const WriteOptions&, const Slice& key); + virtual Status Write(const WriteOptions& options, WriteBatch* updates); + virtual Status Get(const ReadOptions& options, + const Slice& key, + std::string* value); + virtual Iterator* NewIterator(const ReadOptions&); + virtual const Snapshot* GetSnapshot(); + virtual void ReleaseSnapshot(const Snapshot* snapshot); + virtual bool GetProperty(const Slice& property, std::string* value); + virtual void GetApproximateSizes(const Range* range, int n, uint64_t* sizes); + virtual void CompactRange(const Slice* begin, const Slice* end); + + // Extra methods (for testing) that are not in the public DB interface + + // Compact any files in the named level that overlap [*begin,*end] + void TEST_CompactRange(int level, const Slice* begin, const Slice* end); + + // Force current memtable contents to be compacted. + Status TEST_CompactMemTable(); + + // Return an internal iterator over the current state of the database. + // The keys of this iterator are internal keys (see format.h). + // The returned iterator should be deleted when no longer needed. + Iterator* TEST_NewInternalIterator(); + + // Return the maximum overlapping data (in bytes) at next level for any + // file at a level >= 1. + int64_t TEST_MaxNextLevelOverlappingBytes(); + + // Record a sample of bytes read at the specified internal key. + // Samples are taken approximately once every config::kReadBytesPeriod + // bytes. + void RecordReadSample(Slice key); + + private: + friend class DB; + struct CompactionState; + struct Writer; + + Iterator* NewInternalIterator(const ReadOptions&, + SequenceNumber* latest_snapshot, + uint32_t* seed); + + Status NewDB(); + + // Recover the descriptor from persistent storage. May do a significant + // amount of work to recover recently logged updates. Any changes to + // be made to the descriptor are added to *edit. + Status Recover(VersionEdit* edit, bool* save_manifest) + EXCLUSIVE_LOCKS_REQUIRED(mutex_); + + void MaybeIgnoreError(Status* s) const; + + // Delete any unneeded files and stale in-memory entries. + void DeleteObsoleteFiles(); + + // Compact the in-memory write buffer to disk. Switches to a new + // log-file/memtable and writes a new descriptor iff successful. + // Errors are recorded in bg_error_. + void CompactMemTable() EXCLUSIVE_LOCKS_REQUIRED(mutex_); + + Status RecoverLogFile(uint64_t log_number, bool last_log, bool* save_manifest, + VersionEdit* edit, SequenceNumber* max_sequence) + EXCLUSIVE_LOCKS_REQUIRED(mutex_); + + Status WriteLevel0Table(MemTable* mem, VersionEdit* edit, Version* base) + EXCLUSIVE_LOCKS_REQUIRED(mutex_); + + Status MakeRoomForWrite(bool force /* compact even if there is room? */) + EXCLUSIVE_LOCKS_REQUIRED(mutex_); + WriteBatch* BuildBatchGroup(Writer** last_writer); + + void RecordBackgroundError(const Status& s); + + void MaybeScheduleCompaction() EXCLUSIVE_LOCKS_REQUIRED(mutex_); + static void BGWork(void* db); + void BackgroundCall(); + void BackgroundCompaction() EXCLUSIVE_LOCKS_REQUIRED(mutex_); + void CleanupCompaction(CompactionState* compact) + EXCLUSIVE_LOCKS_REQUIRED(mutex_); + Status DoCompactionWork(CompactionState* compact) + EXCLUSIVE_LOCKS_REQUIRED(mutex_); + + Status OpenCompactionOutputFile(CompactionState* compact); + Status FinishCompactionOutputFile(CompactionState* compact, Iterator* input); + Status InstallCompactionResults(CompactionState* compact) + EXCLUSIVE_LOCKS_REQUIRED(mutex_); + + // Constant after construction + Env* const env_; + const InternalKeyComparator internal_comparator_; + const InternalFilterPolicy internal_filter_policy_; + const Options options_; // options_.comparator == &internal_comparator_ + bool owns_info_log_; + bool owns_cache_; + const std::string dbname_; + + // table_cache_ provides its own synchronization + TableCache* table_cache_; + + // Lock over the persistent DB state. Non-NULL iff successfully acquired. + FileLock* db_lock_; + + // State below is protected by mutex_ + port::Mutex mutex_; + port::AtomicPointer shutting_down_; + port::CondVar bg_cv_; // Signalled when background work finishes + MemTable* mem_; + MemTable* imm_; // Memtable being compacted + port::AtomicPointer has_imm_; // So bg thread can detect non-NULL imm_ + WritableFile* logfile_; + uint64_t logfile_number_; + log::Writer* log_; + uint32_t seed_; // For sampling. + + // Queue of writers. + std::deque writers_; + WriteBatch* tmp_batch_; + + SnapshotList snapshots_; + + // Set of table files to protect from deletion because they are + // part of ongoing compactions. + std::set pending_outputs_; + + // Has a background compaction been scheduled or is running? + bool bg_compaction_scheduled_; + + // Information for a manual compaction + struct ManualCompaction { + int level; + bool done; + const InternalKey* begin; // NULL means beginning of key range + const InternalKey* end; // NULL means end of key range + InternalKey tmp_storage; // Used to keep track of compaction progress + }; + ManualCompaction* manual_compaction_; + + VersionSet* versions_; + + // Have we encountered a background error in paranoid mode? + Status bg_error_; + + // Per level compaction stats. stats_[level] stores the stats for + // compactions that produced data for the specified "level". + struct CompactionStats { + int64_t micros; + int64_t bytes_read; + int64_t bytes_written; + + CompactionStats() : micros(0), bytes_read(0), bytes_written(0) { } + + void Add(const CompactionStats& c) { + this->micros += c.micros; + this->bytes_read += c.bytes_read; + this->bytes_written += c.bytes_written; + } + }; + CompactionStats stats_[config::kNumLevels]; + + // No copying allowed + DBImpl(const DBImpl&); + void operator=(const DBImpl&); + + const Comparator* user_comparator() const { + return internal_comparator_.user_comparator(); + } +}; + +// Sanitize db options. The caller should delete result.info_log if +// it is not equal to src.info_log. +extern Options SanitizeOptions(const std::string& db, + const InternalKeyComparator* icmp, + const InternalFilterPolicy* ipolicy, + const Options& src); + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_DB_DB_IMPL_H_ diff --git a/ios/Pods/leveldb-library/db/db_iter.cc b/ios/Pods/leveldb-library/db/db_iter.cc new file mode 100644 index 00000000..3b2035e9 --- /dev/null +++ b/ios/Pods/leveldb-library/db/db_iter.cc @@ -0,0 +1,317 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "db/db_iter.h" + +#include "db/filename.h" +#include "db/db_impl.h" +#include "db/dbformat.h" +#include "leveldb/env.h" +#include "leveldb/iterator.h" +#include "port/port.h" +#include "util/logging.h" +#include "util/mutexlock.h" +#include "util/random.h" + +namespace leveldb { + +#if 0 +static void DumpInternalIter(Iterator* iter) { + for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { + ParsedInternalKey k; + if (!ParseInternalKey(iter->key(), &k)) { + fprintf(stderr, "Corrupt '%s'\n", EscapeString(iter->key()).c_str()); + } else { + fprintf(stderr, "@ '%s'\n", k.DebugString().c_str()); + } + } +} +#endif + +namespace { + +// Memtables and sstables that make the DB representation contain +// (userkey,seq,type) => uservalue entries. DBIter +// combines multiple entries for the same userkey found in the DB +// representation into a single entry while accounting for sequence +// numbers, deletion markers, overwrites, etc. +class DBIter: public Iterator { + public: + // Which direction is the iterator currently moving? + // (1) When moving forward, the internal iterator is positioned at + // the exact entry that yields this->key(), this->value() + // (2) When moving backwards, the internal iterator is positioned + // just before all entries whose user key == this->key(). + enum Direction { + kForward, + kReverse + }; + + DBIter(DBImpl* db, const Comparator* cmp, Iterator* iter, SequenceNumber s, + uint32_t seed) + : db_(db), + user_comparator_(cmp), + iter_(iter), + sequence_(s), + direction_(kForward), + valid_(false), + rnd_(seed), + bytes_counter_(RandomPeriod()) { + } + virtual ~DBIter() { + delete iter_; + } + virtual bool Valid() const { return valid_; } + virtual Slice key() const { + assert(valid_); + return (direction_ == kForward) ? ExtractUserKey(iter_->key()) : saved_key_; + } + virtual Slice value() const { + assert(valid_); + return (direction_ == kForward) ? iter_->value() : saved_value_; + } + virtual Status status() const { + if (status_.ok()) { + return iter_->status(); + } else { + return status_; + } + } + + virtual void Next(); + virtual void Prev(); + virtual void Seek(const Slice& target); + virtual void SeekToFirst(); + virtual void SeekToLast(); + + private: + void FindNextUserEntry(bool skipping, std::string* skip); + void FindPrevUserEntry(); + bool ParseKey(ParsedInternalKey* key); + + inline void SaveKey(const Slice& k, std::string* dst) { + dst->assign(k.data(), k.size()); + } + + inline void ClearSavedValue() { + if (saved_value_.capacity() > 1048576) { + std::string empty; + swap(empty, saved_value_); + } else { + saved_value_.clear(); + } + } + + // Pick next gap with average value of config::kReadBytesPeriod. + ssize_t RandomPeriod() { + return rnd_.Uniform(2*config::kReadBytesPeriod); + } + + DBImpl* db_; + const Comparator* const user_comparator_; + Iterator* const iter_; + SequenceNumber const sequence_; + + Status status_; + std::string saved_key_; // == current key when direction_==kReverse + std::string saved_value_; // == current raw value when direction_==kReverse + Direction direction_; + bool valid_; + + Random rnd_; + ssize_t bytes_counter_; + + // No copying allowed + DBIter(const DBIter&); + void operator=(const DBIter&); +}; + +inline bool DBIter::ParseKey(ParsedInternalKey* ikey) { + Slice k = iter_->key(); + ssize_t n = k.size() + iter_->value().size(); + bytes_counter_ -= n; + while (bytes_counter_ < 0) { + bytes_counter_ += RandomPeriod(); + db_->RecordReadSample(k); + } + if (!ParseInternalKey(k, ikey)) { + status_ = Status::Corruption("corrupted internal key in DBIter"); + return false; + } else { + return true; + } +} + +void DBIter::Next() { + assert(valid_); + + if (direction_ == kReverse) { // Switch directions? + direction_ = kForward; + // iter_ is pointing just before the entries for this->key(), + // so advance into the range of entries for this->key() and then + // use the normal skipping code below. + if (!iter_->Valid()) { + iter_->SeekToFirst(); + } else { + iter_->Next(); + } + if (!iter_->Valid()) { + valid_ = false; + saved_key_.clear(); + return; + } + // saved_key_ already contains the key to skip past. + } else { + // Store in saved_key_ the current key so we skip it below. + SaveKey(ExtractUserKey(iter_->key()), &saved_key_); + } + + FindNextUserEntry(true, &saved_key_); +} + +void DBIter::FindNextUserEntry(bool skipping, std::string* skip) { + // Loop until we hit an acceptable entry to yield + assert(iter_->Valid()); + assert(direction_ == kForward); + do { + ParsedInternalKey ikey; + if (ParseKey(&ikey) && ikey.sequence <= sequence_) { + switch (ikey.type) { + case kTypeDeletion: + // Arrange to skip all upcoming entries for this key since + // they are hidden by this deletion. + SaveKey(ikey.user_key, skip); + skipping = true; + break; + case kTypeValue: + if (skipping && + user_comparator_->Compare(ikey.user_key, *skip) <= 0) { + // Entry hidden + } else { + valid_ = true; + saved_key_.clear(); + return; + } + break; + } + } + iter_->Next(); + } while (iter_->Valid()); + saved_key_.clear(); + valid_ = false; +} + +void DBIter::Prev() { + assert(valid_); + + if (direction_ == kForward) { // Switch directions? + // iter_ is pointing at the current entry. Scan backwards until + // the key changes so we can use the normal reverse scanning code. + assert(iter_->Valid()); // Otherwise valid_ would have been false + SaveKey(ExtractUserKey(iter_->key()), &saved_key_); + while (true) { + iter_->Prev(); + if (!iter_->Valid()) { + valid_ = false; + saved_key_.clear(); + ClearSavedValue(); + return; + } + if (user_comparator_->Compare(ExtractUserKey(iter_->key()), + saved_key_) < 0) { + break; + } + } + direction_ = kReverse; + } + + FindPrevUserEntry(); +} + +void DBIter::FindPrevUserEntry() { + assert(direction_ == kReverse); + + ValueType value_type = kTypeDeletion; + if (iter_->Valid()) { + do { + ParsedInternalKey ikey; + if (ParseKey(&ikey) && ikey.sequence <= sequence_) { + if ((value_type != kTypeDeletion) && + user_comparator_->Compare(ikey.user_key, saved_key_) < 0) { + // We encountered a non-deleted value in entries for previous keys, + break; + } + value_type = ikey.type; + if (value_type == kTypeDeletion) { + saved_key_.clear(); + ClearSavedValue(); + } else { + Slice raw_value = iter_->value(); + if (saved_value_.capacity() > raw_value.size() + 1048576) { + std::string empty; + swap(empty, saved_value_); + } + SaveKey(ExtractUserKey(iter_->key()), &saved_key_); + saved_value_.assign(raw_value.data(), raw_value.size()); + } + } + iter_->Prev(); + } while (iter_->Valid()); + } + + if (value_type == kTypeDeletion) { + // End + valid_ = false; + saved_key_.clear(); + ClearSavedValue(); + direction_ = kForward; + } else { + valid_ = true; + } +} + +void DBIter::Seek(const Slice& target) { + direction_ = kForward; + ClearSavedValue(); + saved_key_.clear(); + AppendInternalKey( + &saved_key_, ParsedInternalKey(target, sequence_, kValueTypeForSeek)); + iter_->Seek(saved_key_); + if (iter_->Valid()) { + FindNextUserEntry(false, &saved_key_ /* temporary storage */); + } else { + valid_ = false; + } +} + +void DBIter::SeekToFirst() { + direction_ = kForward; + ClearSavedValue(); + iter_->SeekToFirst(); + if (iter_->Valid()) { + FindNextUserEntry(false, &saved_key_ /* temporary storage */); + } else { + valid_ = false; + } +} + +void DBIter::SeekToLast() { + direction_ = kReverse; + ClearSavedValue(); + iter_->SeekToLast(); + FindPrevUserEntry(); +} + +} // anonymous namespace + +Iterator* NewDBIterator( + DBImpl* db, + const Comparator* user_key_comparator, + Iterator* internal_iter, + SequenceNumber sequence, + uint32_t seed) { + return new DBIter(db, user_key_comparator, internal_iter, sequence, seed); +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/db/db_iter.h b/ios/Pods/leveldb-library/db/db_iter.h new file mode 100644 index 00000000..04927e93 --- /dev/null +++ b/ios/Pods/leveldb-library/db/db_iter.h @@ -0,0 +1,28 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_DB_DB_ITER_H_ +#define STORAGE_LEVELDB_DB_DB_ITER_H_ + +#include +#include "leveldb/db.h" +#include "db/dbformat.h" + +namespace leveldb { + +class DBImpl; + +// Return a new iterator that converts internal keys (yielded by +// "*internal_iter") that were live at the specified "sequence" number +// into appropriate user keys. +extern Iterator* NewDBIterator( + DBImpl* db, + const Comparator* user_key_comparator, + Iterator* internal_iter, + SequenceNumber sequence, + uint32_t seed); + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_DB_DB_ITER_H_ diff --git a/ios/Pods/leveldb-library/db/dbformat.cc b/ios/Pods/leveldb-library/db/dbformat.cc new file mode 100644 index 00000000..20a7ca44 --- /dev/null +++ b/ios/Pods/leveldb-library/db/dbformat.cc @@ -0,0 +1,140 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include +#include "db/dbformat.h" +#include "port/port.h" +#include "util/coding.h" + +namespace leveldb { + +static uint64_t PackSequenceAndType(uint64_t seq, ValueType t) { + assert(seq <= kMaxSequenceNumber); + assert(t <= kValueTypeForSeek); + return (seq << 8) | t; +} + +void AppendInternalKey(std::string* result, const ParsedInternalKey& key) { + result->append(key.user_key.data(), key.user_key.size()); + PutFixed64(result, PackSequenceAndType(key.sequence, key.type)); +} + +std::string ParsedInternalKey::DebugString() const { + char buf[50]; + snprintf(buf, sizeof(buf), "' @ %llu : %d", + (unsigned long long) sequence, + int(type)); + std::string result = "'"; + result += EscapeString(user_key.ToString()); + result += buf; + return result; +} + +std::string InternalKey::DebugString() const { + std::string result; + ParsedInternalKey parsed; + if (ParseInternalKey(rep_, &parsed)) { + result = parsed.DebugString(); + } else { + result = "(bad)"; + result.append(EscapeString(rep_)); + } + return result; +} + +const char* InternalKeyComparator::Name() const { + return "leveldb.InternalKeyComparator"; +} + +int InternalKeyComparator::Compare(const Slice& akey, const Slice& bkey) const { + // Order by: + // increasing user key (according to user-supplied comparator) + // decreasing sequence number + // decreasing type (though sequence# should be enough to disambiguate) + int r = user_comparator_->Compare(ExtractUserKey(akey), ExtractUserKey(bkey)); + if (r == 0) { + const uint64_t anum = DecodeFixed64(akey.data() + akey.size() - 8); + const uint64_t bnum = DecodeFixed64(bkey.data() + bkey.size() - 8); + if (anum > bnum) { + r = -1; + } else if (anum < bnum) { + r = +1; + } + } + return r; +} + +void InternalKeyComparator::FindShortestSeparator( + std::string* start, + const Slice& limit) const { + // Attempt to shorten the user portion of the key + Slice user_start = ExtractUserKey(*start); + Slice user_limit = ExtractUserKey(limit); + std::string tmp(user_start.data(), user_start.size()); + user_comparator_->FindShortestSeparator(&tmp, user_limit); + if (tmp.size() < user_start.size() && + user_comparator_->Compare(user_start, tmp) < 0) { + // User key has become shorter physically, but larger logically. + // Tack on the earliest possible number to the shortened user key. + PutFixed64(&tmp, PackSequenceAndType(kMaxSequenceNumber,kValueTypeForSeek)); + assert(this->Compare(*start, tmp) < 0); + assert(this->Compare(tmp, limit) < 0); + start->swap(tmp); + } +} + +void InternalKeyComparator::FindShortSuccessor(std::string* key) const { + Slice user_key = ExtractUserKey(*key); + std::string tmp(user_key.data(), user_key.size()); + user_comparator_->FindShortSuccessor(&tmp); + if (tmp.size() < user_key.size() && + user_comparator_->Compare(user_key, tmp) < 0) { + // User key has become shorter physically, but larger logically. + // Tack on the earliest possible number to the shortened user key. + PutFixed64(&tmp, PackSequenceAndType(kMaxSequenceNumber,kValueTypeForSeek)); + assert(this->Compare(*key, tmp) < 0); + key->swap(tmp); + } +} + +const char* InternalFilterPolicy::Name() const { + return user_policy_->Name(); +} + +void InternalFilterPolicy::CreateFilter(const Slice* keys, int n, + std::string* dst) const { + // We rely on the fact that the code in table.cc does not mind us + // adjusting keys[]. + Slice* mkey = const_cast(keys); + for (int i = 0; i < n; i++) { + mkey[i] = ExtractUserKey(keys[i]); + // TODO(sanjay): Suppress dups? + } + user_policy_->CreateFilter(keys, n, dst); +} + +bool InternalFilterPolicy::KeyMayMatch(const Slice& key, const Slice& f) const { + return user_policy_->KeyMayMatch(ExtractUserKey(key), f); +} + +LookupKey::LookupKey(const Slice& user_key, SequenceNumber s) { + size_t usize = user_key.size(); + size_t needed = usize + 13; // A conservative estimate + char* dst; + if (needed <= sizeof(space_)) { + dst = space_; + } else { + dst = new char[needed]; + } + start_ = dst; + dst = EncodeVarint32(dst, usize + 8); + kstart_ = dst; + memcpy(dst, user_key.data(), usize); + dst += usize; + EncodeFixed64(dst, PackSequenceAndType(s, kValueTypeForSeek)); + dst += 8; + end_ = dst; +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/db/dbformat.h b/ios/Pods/leveldb-library/db/dbformat.h new file mode 100644 index 00000000..ea897b13 --- /dev/null +++ b/ios/Pods/leveldb-library/db/dbformat.h @@ -0,0 +1,230 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_DB_DBFORMAT_H_ +#define STORAGE_LEVELDB_DB_DBFORMAT_H_ + +#include +#include "leveldb/comparator.h" +#include "leveldb/db.h" +#include "leveldb/filter_policy.h" +#include "leveldb/slice.h" +#include "leveldb/table_builder.h" +#include "util/coding.h" +#include "util/logging.h" + +namespace leveldb { + +// Grouping of constants. We may want to make some of these +// parameters set via options. +namespace config { +static const int kNumLevels = 7; + +// Level-0 compaction is started when we hit this many files. +static const int kL0_CompactionTrigger = 4; + +// Soft limit on number of level-0 files. We slow down writes at this point. +static const int kL0_SlowdownWritesTrigger = 8; + +// Maximum number of level-0 files. We stop writes at this point. +static const int kL0_StopWritesTrigger = 12; + +// Maximum level to which a new compacted memtable is pushed if it +// does not create overlap. We try to push to level 2 to avoid the +// relatively expensive level 0=>1 compactions and to avoid some +// expensive manifest file operations. We do not push all the way to +// the largest level since that can generate a lot of wasted disk +// space if the same key space is being repeatedly overwritten. +static const int kMaxMemCompactLevel = 2; + +// Approximate gap in bytes between samples of data read during iteration. +static const int kReadBytesPeriod = 1048576; + +} // namespace config + +class InternalKey; + +// Value types encoded as the last component of internal keys. +// DO NOT CHANGE THESE ENUM VALUES: they are embedded in the on-disk +// data structures. +enum ValueType { + kTypeDeletion = 0x0, + kTypeValue = 0x1 +}; +// kValueTypeForSeek defines the ValueType that should be passed when +// constructing a ParsedInternalKey object for seeking to a particular +// sequence number (since we sort sequence numbers in decreasing order +// and the value type is embedded as the low 8 bits in the sequence +// number in internal keys, we need to use the highest-numbered +// ValueType, not the lowest). +static const ValueType kValueTypeForSeek = kTypeValue; + +typedef uint64_t SequenceNumber; + +// We leave eight bits empty at the bottom so a type and sequence# +// can be packed together into 64-bits. +static const SequenceNumber kMaxSequenceNumber = + ((0x1ull << 56) - 1); + +struct ParsedInternalKey { + Slice user_key; + SequenceNumber sequence; + ValueType type; + + ParsedInternalKey() { } // Intentionally left uninitialized (for speed) + ParsedInternalKey(const Slice& u, const SequenceNumber& seq, ValueType t) + : user_key(u), sequence(seq), type(t) { } + std::string DebugString() const; +}; + +// Return the length of the encoding of "key". +inline size_t InternalKeyEncodingLength(const ParsedInternalKey& key) { + return key.user_key.size() + 8; +} + +// Append the serialization of "key" to *result. +extern void AppendInternalKey(std::string* result, + const ParsedInternalKey& key); + +// Attempt to parse an internal key from "internal_key". On success, +// stores the parsed data in "*result", and returns true. +// +// On error, returns false, leaves "*result" in an undefined state. +extern bool ParseInternalKey(const Slice& internal_key, + ParsedInternalKey* result); + +// Returns the user key portion of an internal key. +inline Slice ExtractUserKey(const Slice& internal_key) { + assert(internal_key.size() >= 8); + return Slice(internal_key.data(), internal_key.size() - 8); +} + +inline ValueType ExtractValueType(const Slice& internal_key) { + assert(internal_key.size() >= 8); + const size_t n = internal_key.size(); + uint64_t num = DecodeFixed64(internal_key.data() + n - 8); + unsigned char c = num & 0xff; + return static_cast(c); +} + +// A comparator for internal keys that uses a specified comparator for +// the user key portion and breaks ties by decreasing sequence number. +class InternalKeyComparator : public Comparator { + private: + const Comparator* user_comparator_; + public: + explicit InternalKeyComparator(const Comparator* c) : user_comparator_(c) { } + virtual const char* Name() const; + virtual int Compare(const Slice& a, const Slice& b) const; + virtual void FindShortestSeparator( + std::string* start, + const Slice& limit) const; + virtual void FindShortSuccessor(std::string* key) const; + + const Comparator* user_comparator() const { return user_comparator_; } + + int Compare(const InternalKey& a, const InternalKey& b) const; +}; + +// Filter policy wrapper that converts from internal keys to user keys +class InternalFilterPolicy : public FilterPolicy { + private: + const FilterPolicy* const user_policy_; + public: + explicit InternalFilterPolicy(const FilterPolicy* p) : user_policy_(p) { } + virtual const char* Name() const; + virtual void CreateFilter(const Slice* keys, int n, std::string* dst) const; + virtual bool KeyMayMatch(const Slice& key, const Slice& filter) const; +}; + +// Modules in this directory should keep internal keys wrapped inside +// the following class instead of plain strings so that we do not +// incorrectly use string comparisons instead of an InternalKeyComparator. +class InternalKey { + private: + std::string rep_; + public: + InternalKey() { } // Leave rep_ as empty to indicate it is invalid + InternalKey(const Slice& user_key, SequenceNumber s, ValueType t) { + AppendInternalKey(&rep_, ParsedInternalKey(user_key, s, t)); + } + + void DecodeFrom(const Slice& s) { rep_.assign(s.data(), s.size()); } + Slice Encode() const { + assert(!rep_.empty()); + return rep_; + } + + Slice user_key() const { return ExtractUserKey(rep_); } + + void SetFrom(const ParsedInternalKey& p) { + rep_.clear(); + AppendInternalKey(&rep_, p); + } + + void Clear() { rep_.clear(); } + + std::string DebugString() const; +}; + +inline int InternalKeyComparator::Compare( + const InternalKey& a, const InternalKey& b) const { + return Compare(a.Encode(), b.Encode()); +} + +inline bool ParseInternalKey(const Slice& internal_key, + ParsedInternalKey* result) { + const size_t n = internal_key.size(); + if (n < 8) return false; + uint64_t num = DecodeFixed64(internal_key.data() + n - 8); + unsigned char c = num & 0xff; + result->sequence = num >> 8; + result->type = static_cast(c); + result->user_key = Slice(internal_key.data(), n - 8); + return (c <= static_cast(kTypeValue)); +} + +// A helper class useful for DBImpl::Get() +class LookupKey { + public: + // Initialize *this for looking up user_key at a snapshot with + // the specified sequence number. + LookupKey(const Slice& user_key, SequenceNumber sequence); + + ~LookupKey(); + + // Return a key suitable for lookup in a MemTable. + Slice memtable_key() const { return Slice(start_, end_ - start_); } + + // Return an internal key (suitable for passing to an internal iterator) + Slice internal_key() const { return Slice(kstart_, end_ - kstart_); } + + // Return the user key + Slice user_key() const { return Slice(kstart_, end_ - kstart_ - 8); } + + private: + // We construct a char array of the form: + // klength varint32 <-- start_ + // userkey char[klength] <-- kstart_ + // tag uint64 + // <-- end_ + // The array is a suitable MemTable key. + // The suffix starting with "userkey" can be used as an InternalKey. + const char* start_; + const char* kstart_; + const char* end_; + char space_[200]; // Avoid allocation for short keys + + // No copying allowed + LookupKey(const LookupKey&); + void operator=(const LookupKey&); +}; + +inline LookupKey::~LookupKey() { + if (start_ != space_) delete[] start_; +} + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_DB_DBFORMAT_H_ diff --git a/ios/Pods/leveldb-library/db/dumpfile.cc b/ios/Pods/leveldb-library/db/dumpfile.cc new file mode 100644 index 00000000..61c47c2f --- /dev/null +++ b/ios/Pods/leveldb-library/db/dumpfile.cc @@ -0,0 +1,225 @@ +// Copyright (c) 2012 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include +#include "db/dbformat.h" +#include "db/filename.h" +#include "db/log_reader.h" +#include "db/version_edit.h" +#include "db/write_batch_internal.h" +#include "leveldb/env.h" +#include "leveldb/iterator.h" +#include "leveldb/options.h" +#include "leveldb/status.h" +#include "leveldb/table.h" +#include "leveldb/write_batch.h" +#include "util/logging.h" + +namespace leveldb { + +namespace { + +bool GuessType(const std::string& fname, FileType* type) { + size_t pos = fname.rfind('/'); + std::string basename; + if (pos == std::string::npos) { + basename = fname; + } else { + basename = std::string(fname.data() + pos + 1, fname.size() - pos - 1); + } + uint64_t ignored; + return ParseFileName(basename, &ignored, type); +} + +// Notified when log reader encounters corruption. +class CorruptionReporter : public log::Reader::Reporter { + public: + WritableFile* dst_; + virtual void Corruption(size_t bytes, const Status& status) { + std::string r = "corruption: "; + AppendNumberTo(&r, bytes); + r += " bytes; "; + r += status.ToString(); + r.push_back('\n'); + dst_->Append(r); + } +}; + +// Print contents of a log file. (*func)() is called on every record. +Status PrintLogContents(Env* env, const std::string& fname, + void (*func)(uint64_t, Slice, WritableFile*), + WritableFile* dst) { + SequentialFile* file; + Status s = env->NewSequentialFile(fname, &file); + if (!s.ok()) { + return s; + } + CorruptionReporter reporter; + reporter.dst_ = dst; + log::Reader reader(file, &reporter, true, 0); + Slice record; + std::string scratch; + while (reader.ReadRecord(&record, &scratch)) { + (*func)(reader.LastRecordOffset(), record, dst); + } + delete file; + return Status::OK(); +} + +// Called on every item found in a WriteBatch. +class WriteBatchItemPrinter : public WriteBatch::Handler { + public: + WritableFile* dst_; + virtual void Put(const Slice& key, const Slice& value) { + std::string r = " put '"; + AppendEscapedStringTo(&r, key); + r += "' '"; + AppendEscapedStringTo(&r, value); + r += "'\n"; + dst_->Append(r); + } + virtual void Delete(const Slice& key) { + std::string r = " del '"; + AppendEscapedStringTo(&r, key); + r += "'\n"; + dst_->Append(r); + } +}; + + +// Called on every log record (each one of which is a WriteBatch) +// found in a kLogFile. +static void WriteBatchPrinter(uint64_t pos, Slice record, WritableFile* dst) { + std::string r = "--- offset "; + AppendNumberTo(&r, pos); + r += "; "; + if (record.size() < 12) { + r += "log record length "; + AppendNumberTo(&r, record.size()); + r += " is too small\n"; + dst->Append(r); + return; + } + WriteBatch batch; + WriteBatchInternal::SetContents(&batch, record); + r += "sequence "; + AppendNumberTo(&r, WriteBatchInternal::Sequence(&batch)); + r.push_back('\n'); + dst->Append(r); + WriteBatchItemPrinter batch_item_printer; + batch_item_printer.dst_ = dst; + Status s = batch.Iterate(&batch_item_printer); + if (!s.ok()) { + dst->Append(" error: " + s.ToString() + "\n"); + } +} + +Status DumpLog(Env* env, const std::string& fname, WritableFile* dst) { + return PrintLogContents(env, fname, WriteBatchPrinter, dst); +} + +// Called on every log record (each one of which is a WriteBatch) +// found in a kDescriptorFile. +static void VersionEditPrinter(uint64_t pos, Slice record, WritableFile* dst) { + std::string r = "--- offset "; + AppendNumberTo(&r, pos); + r += "; "; + VersionEdit edit; + Status s = edit.DecodeFrom(record); + if (!s.ok()) { + r += s.ToString(); + r.push_back('\n'); + } else { + r += edit.DebugString(); + } + dst->Append(r); +} + +Status DumpDescriptor(Env* env, const std::string& fname, WritableFile* dst) { + return PrintLogContents(env, fname, VersionEditPrinter, dst); +} + +Status DumpTable(Env* env, const std::string& fname, WritableFile* dst) { + uint64_t file_size; + RandomAccessFile* file = NULL; + Table* table = NULL; + Status s = env->GetFileSize(fname, &file_size); + if (s.ok()) { + s = env->NewRandomAccessFile(fname, &file); + } + if (s.ok()) { + // We use the default comparator, which may or may not match the + // comparator used in this database. However this should not cause + // problems since we only use Table operations that do not require + // any comparisons. In particular, we do not call Seek or Prev. + s = Table::Open(Options(), file, file_size, &table); + } + if (!s.ok()) { + delete table; + delete file; + return s; + } + + ReadOptions ro; + ro.fill_cache = false; + Iterator* iter = table->NewIterator(ro); + std::string r; + for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { + r.clear(); + ParsedInternalKey key; + if (!ParseInternalKey(iter->key(), &key)) { + r = "badkey '"; + AppendEscapedStringTo(&r, iter->key()); + r += "' => '"; + AppendEscapedStringTo(&r, iter->value()); + r += "'\n"; + dst->Append(r); + } else { + r = "'"; + AppendEscapedStringTo(&r, key.user_key); + r += "' @ "; + AppendNumberTo(&r, key.sequence); + r += " : "; + if (key.type == kTypeDeletion) { + r += "del"; + } else if (key.type == kTypeValue) { + r += "val"; + } else { + AppendNumberTo(&r, key.type); + } + r += " => '"; + AppendEscapedStringTo(&r, iter->value()); + r += "'\n"; + dst->Append(r); + } + } + s = iter->status(); + if (!s.ok()) { + dst->Append("iterator error: " + s.ToString() + "\n"); + } + + delete iter; + delete table; + delete file; + return Status::OK(); +} + +} // namespace + +Status DumpFile(Env* env, const std::string& fname, WritableFile* dst) { + FileType ftype; + if (!GuessType(fname, &ftype)) { + return Status::InvalidArgument(fname + ": unknown file type"); + } + switch (ftype) { + case kLogFile: return DumpLog(env, fname, dst); + case kDescriptorFile: return DumpDescriptor(env, fname, dst); + case kTableFile: return DumpTable(env, fname, dst); + default: + break; + } + return Status::InvalidArgument(fname + ": not a dump-able file type"); +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/db/filename.cc b/ios/Pods/leveldb-library/db/filename.cc new file mode 100644 index 00000000..da32946d --- /dev/null +++ b/ios/Pods/leveldb-library/db/filename.cc @@ -0,0 +1,144 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include +#include +#include "db/filename.h" +#include "db/dbformat.h" +#include "leveldb/env.h" +#include "util/logging.h" + +namespace leveldb { + +// A utility routine: write "data" to the named file and Sync() it. +extern Status WriteStringToFileSync(Env* env, const Slice& data, + const std::string& fname); + +static std::string MakeFileName(const std::string& name, uint64_t number, + const char* suffix) { + char buf[100]; + snprintf(buf, sizeof(buf), "/%06llu.%s", + static_cast(number), + suffix); + return name + buf; +} + +std::string LogFileName(const std::string& name, uint64_t number) { + assert(number > 0); + return MakeFileName(name, number, "log"); +} + +std::string TableFileName(const std::string& name, uint64_t number) { + assert(number > 0); + return MakeFileName(name, number, "ldb"); +} + +std::string SSTTableFileName(const std::string& name, uint64_t number) { + assert(number > 0); + return MakeFileName(name, number, "sst"); +} + +std::string DescriptorFileName(const std::string& dbname, uint64_t number) { + assert(number > 0); + char buf[100]; + snprintf(buf, sizeof(buf), "/MANIFEST-%06llu", + static_cast(number)); + return dbname + buf; +} + +std::string CurrentFileName(const std::string& dbname) { + return dbname + "/CURRENT"; +} + +std::string LockFileName(const std::string& dbname) { + return dbname + "/LOCK"; +} + +std::string TempFileName(const std::string& dbname, uint64_t number) { + assert(number > 0); + return MakeFileName(dbname, number, "dbtmp"); +} + +std::string InfoLogFileName(const std::string& dbname) { + return dbname + "/LOG"; +} + +// Return the name of the old info log file for "dbname". +std::string OldInfoLogFileName(const std::string& dbname) { + return dbname + "/LOG.old"; +} + + +// Owned filenames have the form: +// dbname/CURRENT +// dbname/LOCK +// dbname/LOG +// dbname/LOG.old +// dbname/MANIFEST-[0-9]+ +// dbname/[0-9]+.(log|sst|ldb) +bool ParseFileName(const std::string& fname, + uint64_t* number, + FileType* type) { + Slice rest(fname); + if (rest == "CURRENT") { + *number = 0; + *type = kCurrentFile; + } else if (rest == "LOCK") { + *number = 0; + *type = kDBLockFile; + } else if (rest == "LOG" || rest == "LOG.old") { + *number = 0; + *type = kInfoLogFile; + } else if (rest.starts_with("MANIFEST-")) { + rest.remove_prefix(strlen("MANIFEST-")); + uint64_t num; + if (!ConsumeDecimalNumber(&rest, &num)) { + return false; + } + if (!rest.empty()) { + return false; + } + *type = kDescriptorFile; + *number = num; + } else { + // Avoid strtoull() to keep filename format independent of the + // current locale + uint64_t num; + if (!ConsumeDecimalNumber(&rest, &num)) { + return false; + } + Slice suffix = rest; + if (suffix == Slice(".log")) { + *type = kLogFile; + } else if (suffix == Slice(".sst") || suffix == Slice(".ldb")) { + *type = kTableFile; + } else if (suffix == Slice(".dbtmp")) { + *type = kTempFile; + } else { + return false; + } + *number = num; + } + return true; +} + +Status SetCurrentFile(Env* env, const std::string& dbname, + uint64_t descriptor_number) { + // Remove leading "dbname/" and add newline to manifest file name + std::string manifest = DescriptorFileName(dbname, descriptor_number); + Slice contents = manifest; + assert(contents.starts_with(dbname + "/")); + contents.remove_prefix(dbname.size() + 1); + std::string tmp = TempFileName(dbname, descriptor_number); + Status s = WriteStringToFileSync(env, contents.ToString() + "\n", tmp); + if (s.ok()) { + s = env->RenameFile(tmp, CurrentFileName(dbname)); + } + if (!s.ok()) { + env->DeleteFile(tmp); + } + return s; +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/db/filename.h b/ios/Pods/leveldb-library/db/filename.h new file mode 100644 index 00000000..87a75260 --- /dev/null +++ b/ios/Pods/leveldb-library/db/filename.h @@ -0,0 +1,85 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// File names used by DB code + +#ifndef STORAGE_LEVELDB_DB_FILENAME_H_ +#define STORAGE_LEVELDB_DB_FILENAME_H_ + +#include +#include +#include "leveldb/slice.h" +#include "leveldb/status.h" +#include "port/port.h" + +namespace leveldb { + +class Env; + +enum FileType { + kLogFile, + kDBLockFile, + kTableFile, + kDescriptorFile, + kCurrentFile, + kTempFile, + kInfoLogFile // Either the current one, or an old one +}; + +// Return the name of the log file with the specified number +// in the db named by "dbname". The result will be prefixed with +// "dbname". +extern std::string LogFileName(const std::string& dbname, uint64_t number); + +// Return the name of the sstable with the specified number +// in the db named by "dbname". The result will be prefixed with +// "dbname". +extern std::string TableFileName(const std::string& dbname, uint64_t number); + +// Return the legacy file name for an sstable with the specified number +// in the db named by "dbname". The result will be prefixed with +// "dbname". +extern std::string SSTTableFileName(const std::string& dbname, uint64_t number); + +// Return the name of the descriptor file for the db named by +// "dbname" and the specified incarnation number. The result will be +// prefixed with "dbname". +extern std::string DescriptorFileName(const std::string& dbname, + uint64_t number); + +// Return the name of the current file. This file contains the name +// of the current manifest file. The result will be prefixed with +// "dbname". +extern std::string CurrentFileName(const std::string& dbname); + +// Return the name of the lock file for the db named by +// "dbname". The result will be prefixed with "dbname". +extern std::string LockFileName(const std::string& dbname); + +// Return the name of a temporary file owned by the db named "dbname". +// The result will be prefixed with "dbname". +extern std::string TempFileName(const std::string& dbname, uint64_t number); + +// Return the name of the info log file for "dbname". +extern std::string InfoLogFileName(const std::string& dbname); + +// Return the name of the old info log file for "dbname". +extern std::string OldInfoLogFileName(const std::string& dbname); + +// If filename is a leveldb file, store the type of the file in *type. +// The number encoded in the filename is stored in *number. If the +// filename was successfully parsed, returns true. Else return false. +extern bool ParseFileName(const std::string& filename, + uint64_t* number, + FileType* type); + +// Make the CURRENT file point to the descriptor file with the +// specified number. +extern Status SetCurrentFile(Env* env, const std::string& dbname, + uint64_t descriptor_number); + + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_DB_FILENAME_H_ diff --git a/ios/Pods/leveldb-library/db/log_format.h b/ios/Pods/leveldb-library/db/log_format.h new file mode 100644 index 00000000..356e69fc --- /dev/null +++ b/ios/Pods/leveldb-library/db/log_format.h @@ -0,0 +1,35 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// Log format information shared by reader and writer. +// See ../doc/log_format.md for more detail. + +#ifndef STORAGE_LEVELDB_DB_LOG_FORMAT_H_ +#define STORAGE_LEVELDB_DB_LOG_FORMAT_H_ + +namespace leveldb { +namespace log { + +enum RecordType { + // Zero is reserved for preallocated files + kZeroType = 0, + + kFullType = 1, + + // For fragments + kFirstType = 2, + kMiddleType = 3, + kLastType = 4 +}; +static const int kMaxRecordType = kLastType; + +static const int kBlockSize = 32768; + +// Header is checksum (4 bytes), length (2 bytes), type (1 byte). +static const int kHeaderSize = 4 + 2 + 1; + +} // namespace log +} // namespace leveldb + +#endif // STORAGE_LEVELDB_DB_LOG_FORMAT_H_ diff --git a/ios/Pods/leveldb-library/db/log_reader.cc b/ios/Pods/leveldb-library/db/log_reader.cc new file mode 100644 index 00000000..a6d30454 --- /dev/null +++ b/ios/Pods/leveldb-library/db/log_reader.cc @@ -0,0 +1,284 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "db/log_reader.h" + +#include +#include "leveldb/env.h" +#include "util/coding.h" +#include "util/crc32c.h" + +namespace leveldb { +namespace log { + +Reader::Reporter::~Reporter() { +} + +Reader::Reader(SequentialFile* file, Reporter* reporter, bool checksum, + uint64_t initial_offset) + : file_(file), + reporter_(reporter), + checksum_(checksum), + backing_store_(new char[kBlockSize]), + buffer_(), + eof_(false), + last_record_offset_(0), + end_of_buffer_offset_(0), + initial_offset_(initial_offset), + resyncing_(initial_offset > 0) { +} + +Reader::~Reader() { + delete[] backing_store_; +} + +bool Reader::SkipToInitialBlock() { + size_t offset_in_block = initial_offset_ % kBlockSize; + uint64_t block_start_location = initial_offset_ - offset_in_block; + + // Don't search a block if we'd be in the trailer + if (offset_in_block > kBlockSize - 6) { + offset_in_block = 0; + block_start_location += kBlockSize; + } + + end_of_buffer_offset_ = block_start_location; + + // Skip to start of first block that can contain the initial record + if (block_start_location > 0) { + Status skip_status = file_->Skip(block_start_location); + if (!skip_status.ok()) { + ReportDrop(block_start_location, skip_status); + return false; + } + } + + return true; +} + +bool Reader::ReadRecord(Slice* record, std::string* scratch) { + if (last_record_offset_ < initial_offset_) { + if (!SkipToInitialBlock()) { + return false; + } + } + + scratch->clear(); + record->clear(); + bool in_fragmented_record = false; + // Record offset of the logical record that we're reading + // 0 is a dummy value to make compilers happy + uint64_t prospective_record_offset = 0; + + Slice fragment; + while (true) { + const unsigned int record_type = ReadPhysicalRecord(&fragment); + + // ReadPhysicalRecord may have only had an empty trailer remaining in its + // internal buffer. Calculate the offset of the next physical record now + // that it has returned, properly accounting for its header size. + uint64_t physical_record_offset = + end_of_buffer_offset_ - buffer_.size() - kHeaderSize - fragment.size(); + + if (resyncing_) { + if (record_type == kMiddleType) { + continue; + } else if (record_type == kLastType) { + resyncing_ = false; + continue; + } else { + resyncing_ = false; + } + } + + switch (record_type) { + case kFullType: + if (in_fragmented_record) { + // Handle bug in earlier versions of log::Writer where + // it could emit an empty kFirstType record at the tail end + // of a block followed by a kFullType or kFirstType record + // at the beginning of the next block. + if (scratch->empty()) { + in_fragmented_record = false; + } else { + ReportCorruption(scratch->size(), "partial record without end(1)"); + } + } + prospective_record_offset = physical_record_offset; + scratch->clear(); + *record = fragment; + last_record_offset_ = prospective_record_offset; + return true; + + case kFirstType: + if (in_fragmented_record) { + // Handle bug in earlier versions of log::Writer where + // it could emit an empty kFirstType record at the tail end + // of a block followed by a kFullType or kFirstType record + // at the beginning of the next block. + if (scratch->empty()) { + in_fragmented_record = false; + } else { + ReportCorruption(scratch->size(), "partial record without end(2)"); + } + } + prospective_record_offset = physical_record_offset; + scratch->assign(fragment.data(), fragment.size()); + in_fragmented_record = true; + break; + + case kMiddleType: + if (!in_fragmented_record) { + ReportCorruption(fragment.size(), + "missing start of fragmented record(1)"); + } else { + scratch->append(fragment.data(), fragment.size()); + } + break; + + case kLastType: + if (!in_fragmented_record) { + ReportCorruption(fragment.size(), + "missing start of fragmented record(2)"); + } else { + scratch->append(fragment.data(), fragment.size()); + *record = Slice(*scratch); + last_record_offset_ = prospective_record_offset; + return true; + } + break; + + case kEof: + if (in_fragmented_record) { + // This can be caused by the writer dying immediately after + // writing a physical record but before completing the next; don't + // treat it as a corruption, just ignore the entire logical record. + scratch->clear(); + } + return false; + + case kBadRecord: + if (in_fragmented_record) { + ReportCorruption(scratch->size(), "error in middle of record"); + in_fragmented_record = false; + scratch->clear(); + } + break; + + default: { + char buf[40]; + snprintf(buf, sizeof(buf), "unknown record type %u", record_type); + ReportCorruption( + (fragment.size() + (in_fragmented_record ? scratch->size() : 0)), + buf); + in_fragmented_record = false; + scratch->clear(); + break; + } + } + } + return false; +} + +uint64_t Reader::LastRecordOffset() { + return last_record_offset_; +} + +void Reader::ReportCorruption(uint64_t bytes, const char* reason) { + ReportDrop(bytes, Status::Corruption(reason)); +} + +void Reader::ReportDrop(uint64_t bytes, const Status& reason) { + if (reporter_ != NULL && + end_of_buffer_offset_ - buffer_.size() - bytes >= initial_offset_) { + reporter_->Corruption(static_cast(bytes), reason); + } +} + +unsigned int Reader::ReadPhysicalRecord(Slice* result) { + while (true) { + if (buffer_.size() < kHeaderSize) { + if (!eof_) { + // Last read was a full read, so this is a trailer to skip + buffer_.clear(); + Status status = file_->Read(kBlockSize, &buffer_, backing_store_); + end_of_buffer_offset_ += buffer_.size(); + if (!status.ok()) { + buffer_.clear(); + ReportDrop(kBlockSize, status); + eof_ = true; + return kEof; + } else if (buffer_.size() < kBlockSize) { + eof_ = true; + } + continue; + } else { + // Note that if buffer_ is non-empty, we have a truncated header at the + // end of the file, which can be caused by the writer crashing in the + // middle of writing the header. Instead of considering this an error, + // just report EOF. + buffer_.clear(); + return kEof; + } + } + + // Parse the header + const char* header = buffer_.data(); + const uint32_t a = static_cast(header[4]) & 0xff; + const uint32_t b = static_cast(header[5]) & 0xff; + const unsigned int type = header[6]; + const uint32_t length = a | (b << 8); + if (kHeaderSize + length > buffer_.size()) { + size_t drop_size = buffer_.size(); + buffer_.clear(); + if (!eof_) { + ReportCorruption(drop_size, "bad record length"); + return kBadRecord; + } + // If the end of the file has been reached without reading |length| bytes + // of payload, assume the writer died in the middle of writing the record. + // Don't report a corruption. + return kEof; + } + + if (type == kZeroType && length == 0) { + // Skip zero length record without reporting any drops since + // such records are produced by the mmap based writing code in + // env_posix.cc that preallocates file regions. + buffer_.clear(); + return kBadRecord; + } + + // Check crc + if (checksum_) { + uint32_t expected_crc = crc32c::Unmask(DecodeFixed32(header)); + uint32_t actual_crc = crc32c::Value(header + 6, 1 + length); + if (actual_crc != expected_crc) { + // Drop the rest of the buffer since "length" itself may have + // been corrupted and if we trust it, we could find some + // fragment of a real log record that just happens to look + // like a valid log record. + size_t drop_size = buffer_.size(); + buffer_.clear(); + ReportCorruption(drop_size, "checksum mismatch"); + return kBadRecord; + } + } + + buffer_.remove_prefix(kHeaderSize + length); + + // Skip physical record that started before initial_offset_ + if (end_of_buffer_offset_ - buffer_.size() - kHeaderSize - length < + initial_offset_) { + result->clear(); + return kBadRecord; + } + + *result = Slice(header + kHeaderSize, length); + return type; + } +} + +} // namespace log +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/db/log_reader.h b/ios/Pods/leveldb-library/db/log_reader.h new file mode 100644 index 00000000..8389d61f --- /dev/null +++ b/ios/Pods/leveldb-library/db/log_reader.h @@ -0,0 +1,113 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_DB_LOG_READER_H_ +#define STORAGE_LEVELDB_DB_LOG_READER_H_ + +#include + +#include "db/log_format.h" +#include "leveldb/slice.h" +#include "leveldb/status.h" + +namespace leveldb { + +class SequentialFile; + +namespace log { + +class Reader { + public: + // Interface for reporting errors. + class Reporter { + public: + virtual ~Reporter(); + + // Some corruption was detected. "size" is the approximate number + // of bytes dropped due to the corruption. + virtual void Corruption(size_t bytes, const Status& status) = 0; + }; + + // Create a reader that will return log records from "*file". + // "*file" must remain live while this Reader is in use. + // + // If "reporter" is non-NULL, it is notified whenever some data is + // dropped due to a detected corruption. "*reporter" must remain + // live while this Reader is in use. + // + // If "checksum" is true, verify checksums if available. + // + // The Reader will start reading at the first record located at physical + // position >= initial_offset within the file. + Reader(SequentialFile* file, Reporter* reporter, bool checksum, + uint64_t initial_offset); + + ~Reader(); + + // Read the next record into *record. Returns true if read + // successfully, false if we hit end of the input. May use + // "*scratch" as temporary storage. The contents filled in *record + // will only be valid until the next mutating operation on this + // reader or the next mutation to *scratch. + bool ReadRecord(Slice* record, std::string* scratch); + + // Returns the physical offset of the last record returned by ReadRecord. + // + // Undefined before the first call to ReadRecord. + uint64_t LastRecordOffset(); + + private: + SequentialFile* const file_; + Reporter* const reporter_; + bool const checksum_; + char* const backing_store_; + Slice buffer_; + bool eof_; // Last Read() indicated EOF by returning < kBlockSize + + // Offset of the last record returned by ReadRecord. + uint64_t last_record_offset_; + // Offset of the first location past the end of buffer_. + uint64_t end_of_buffer_offset_; + + // Offset at which to start looking for the first record to return + uint64_t const initial_offset_; + + // True if we are resynchronizing after a seek (initial_offset_ > 0). In + // particular, a run of kMiddleType and kLastType records can be silently + // skipped in this mode + bool resyncing_; + + // Extend record types with the following special values + enum { + kEof = kMaxRecordType + 1, + // Returned whenever we find an invalid physical record. + // Currently there are three situations in which this happens: + // * The record has an invalid CRC (ReadPhysicalRecord reports a drop) + // * The record is a 0-length record (No drop is reported) + // * The record is below constructor's initial_offset (No drop is reported) + kBadRecord = kMaxRecordType + 2 + }; + + // Skips all blocks that are completely before "initial_offset_". + // + // Returns true on success. Handles reporting. + bool SkipToInitialBlock(); + + // Return type, or one of the preceding special values + unsigned int ReadPhysicalRecord(Slice* result); + + // Reports dropped bytes to the reporter. + // buffer_ must be updated to remove the dropped bytes prior to invocation. + void ReportCorruption(uint64_t bytes, const char* reason); + void ReportDrop(uint64_t bytes, const Status& reason); + + // No copying allowed + Reader(const Reader&); + void operator=(const Reader&); +}; + +} // namespace log +} // namespace leveldb + +#endif // STORAGE_LEVELDB_DB_LOG_READER_H_ diff --git a/ios/Pods/leveldb-library/db/log_writer.cc b/ios/Pods/leveldb-library/db/log_writer.cc new file mode 100644 index 00000000..74a03270 --- /dev/null +++ b/ios/Pods/leveldb-library/db/log_writer.cc @@ -0,0 +1,112 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "db/log_writer.h" + +#include +#include "leveldb/env.h" +#include "util/coding.h" +#include "util/crc32c.h" + +namespace leveldb { +namespace log { + +static void InitTypeCrc(uint32_t* type_crc) { + for (int i = 0; i <= kMaxRecordType; i++) { + char t = static_cast(i); + type_crc[i] = crc32c::Value(&t, 1); + } +} + +Writer::Writer(WritableFile* dest) + : dest_(dest), + block_offset_(0) { + InitTypeCrc(type_crc_); +} + +Writer::Writer(WritableFile* dest, uint64_t dest_length) + : dest_(dest), block_offset_(dest_length % kBlockSize) { + InitTypeCrc(type_crc_); +} + +Writer::~Writer() { +} + +Status Writer::AddRecord(const Slice& slice) { + const char* ptr = slice.data(); + size_t left = slice.size(); + + // Fragment the record if necessary and emit it. Note that if slice + // is empty, we still want to iterate once to emit a single + // zero-length record + Status s; + bool begin = true; + do { + const int leftover = kBlockSize - block_offset_; + assert(leftover >= 0); + if (leftover < kHeaderSize) { + // Switch to a new block + if (leftover > 0) { + // Fill the trailer (literal below relies on kHeaderSize being 7) + assert(kHeaderSize == 7); + dest_->Append(Slice("\x00\x00\x00\x00\x00\x00", leftover)); + } + block_offset_ = 0; + } + + // Invariant: we never leave < kHeaderSize bytes in a block. + assert(kBlockSize - block_offset_ - kHeaderSize >= 0); + + const size_t avail = kBlockSize - block_offset_ - kHeaderSize; + const size_t fragment_length = (left < avail) ? left : avail; + + RecordType type; + const bool end = (left == fragment_length); + if (begin && end) { + type = kFullType; + } else if (begin) { + type = kFirstType; + } else if (end) { + type = kLastType; + } else { + type = kMiddleType; + } + + s = EmitPhysicalRecord(type, ptr, fragment_length); + ptr += fragment_length; + left -= fragment_length; + begin = false; + } while (s.ok() && left > 0); + return s; +} + +Status Writer::EmitPhysicalRecord(RecordType t, const char* ptr, size_t n) { + assert(n <= 0xffff); // Must fit in two bytes + assert(block_offset_ + kHeaderSize + n <= kBlockSize); + + // Format the header + char buf[kHeaderSize]; + buf[4] = static_cast(n & 0xff); + buf[5] = static_cast(n >> 8); + buf[6] = static_cast(t); + + // Compute the crc of the record type and the payload. + uint32_t crc = crc32c::Extend(type_crc_[t], ptr, n); + crc = crc32c::Mask(crc); // Adjust for storage + EncodeFixed32(buf, crc); + + // Write the header and the payload + Status s = dest_->Append(Slice(buf, kHeaderSize)); + if (s.ok()) { + s = dest_->Append(Slice(ptr, n)); + if (s.ok()) { + s = dest_->Flush(); + } + } + block_offset_ += kHeaderSize + n; + return s; +} + +} // namespace log +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/db/log_writer.h b/ios/Pods/leveldb-library/db/log_writer.h new file mode 100644 index 00000000..9e7cc470 --- /dev/null +++ b/ios/Pods/leveldb-library/db/log_writer.h @@ -0,0 +1,54 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_DB_LOG_WRITER_H_ +#define STORAGE_LEVELDB_DB_LOG_WRITER_H_ + +#include +#include "db/log_format.h" +#include "leveldb/slice.h" +#include "leveldb/status.h" + +namespace leveldb { + +class WritableFile; + +namespace log { + +class Writer { + public: + // Create a writer that will append data to "*dest". + // "*dest" must be initially empty. + // "*dest" must remain live while this Writer is in use. + explicit Writer(WritableFile* dest); + + // Create a writer that will append data to "*dest". + // "*dest" must have initial length "dest_length". + // "*dest" must remain live while this Writer is in use. + Writer(WritableFile* dest, uint64_t dest_length); + + ~Writer(); + + Status AddRecord(const Slice& slice); + + private: + WritableFile* dest_; + int block_offset_; // Current offset in block + + // crc32c values for all supported record types. These are + // pre-computed to reduce the overhead of computing the crc of the + // record type stored in the header. + uint32_t type_crc_[kMaxRecordType + 1]; + + Status EmitPhysicalRecord(RecordType type, const char* ptr, size_t length); + + // No copying allowed + Writer(const Writer&); + void operator=(const Writer&); +}; + +} // namespace log +} // namespace leveldb + +#endif // STORAGE_LEVELDB_DB_LOG_WRITER_H_ diff --git a/ios/Pods/leveldb-library/db/memtable.cc b/ios/Pods/leveldb-library/db/memtable.cc new file mode 100644 index 00000000..bfec0a7e --- /dev/null +++ b/ios/Pods/leveldb-library/db/memtable.cc @@ -0,0 +1,145 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "db/memtable.h" +#include "db/dbformat.h" +#include "leveldb/comparator.h" +#include "leveldb/env.h" +#include "leveldb/iterator.h" +#include "util/coding.h" + +namespace leveldb { + +static Slice GetLengthPrefixedSlice(const char* data) { + uint32_t len; + const char* p = data; + p = GetVarint32Ptr(p, p + 5, &len); // +5: we assume "p" is not corrupted + return Slice(p, len); +} + +MemTable::MemTable(const InternalKeyComparator& cmp) + : comparator_(cmp), + refs_(0), + table_(comparator_, &arena_) { +} + +MemTable::~MemTable() { + assert(refs_ == 0); +} + +size_t MemTable::ApproximateMemoryUsage() { return arena_.MemoryUsage(); } + +int MemTable::KeyComparator::operator()(const char* aptr, const char* bptr) + const { + // Internal keys are encoded as length-prefixed strings. + Slice a = GetLengthPrefixedSlice(aptr); + Slice b = GetLengthPrefixedSlice(bptr); + return comparator.Compare(a, b); +} + +// Encode a suitable internal key target for "target" and return it. +// Uses *scratch as scratch space, and the returned pointer will point +// into this scratch space. +static const char* EncodeKey(std::string* scratch, const Slice& target) { + scratch->clear(); + PutVarint32(scratch, target.size()); + scratch->append(target.data(), target.size()); + return scratch->data(); +} + +class MemTableIterator: public Iterator { + public: + explicit MemTableIterator(MemTable::Table* table) : iter_(table) { } + + virtual bool Valid() const { return iter_.Valid(); } + virtual void Seek(const Slice& k) { iter_.Seek(EncodeKey(&tmp_, k)); } + virtual void SeekToFirst() { iter_.SeekToFirst(); } + virtual void SeekToLast() { iter_.SeekToLast(); } + virtual void Next() { iter_.Next(); } + virtual void Prev() { iter_.Prev(); } + virtual Slice key() const { return GetLengthPrefixedSlice(iter_.key()); } + virtual Slice value() const { + Slice key_slice = GetLengthPrefixedSlice(iter_.key()); + return GetLengthPrefixedSlice(key_slice.data() + key_slice.size()); + } + + virtual Status status() const { return Status::OK(); } + + private: + MemTable::Table::Iterator iter_; + std::string tmp_; // For passing to EncodeKey + + // No copying allowed + MemTableIterator(const MemTableIterator&); + void operator=(const MemTableIterator&); +}; + +Iterator* MemTable::NewIterator() { + return new MemTableIterator(&table_); +} + +void MemTable::Add(SequenceNumber s, ValueType type, + const Slice& key, + const Slice& value) { + // Format of an entry is concatenation of: + // key_size : varint32 of internal_key.size() + // key bytes : char[internal_key.size()] + // value_size : varint32 of value.size() + // value bytes : char[value.size()] + size_t key_size = key.size(); + size_t val_size = value.size(); + size_t internal_key_size = key_size + 8; + const size_t encoded_len = + VarintLength(internal_key_size) + internal_key_size + + VarintLength(val_size) + val_size; + char* buf = arena_.Allocate(encoded_len); + char* p = EncodeVarint32(buf, internal_key_size); + memcpy(p, key.data(), key_size); + p += key_size; + EncodeFixed64(p, (s << 8) | type); + p += 8; + p = EncodeVarint32(p, val_size); + memcpy(p, value.data(), val_size); + assert((p + val_size) - buf == encoded_len); + table_.Insert(buf); +} + +bool MemTable::Get(const LookupKey& key, std::string* value, Status* s) { + Slice memkey = key.memtable_key(); + Table::Iterator iter(&table_); + iter.Seek(memkey.data()); + if (iter.Valid()) { + // entry format is: + // klength varint32 + // userkey char[klength] + // tag uint64 + // vlength varint32 + // value char[vlength] + // Check that it belongs to same user key. We do not check the + // sequence number since the Seek() call above should have skipped + // all entries with overly large sequence numbers. + const char* entry = iter.key(); + uint32_t key_length; + const char* key_ptr = GetVarint32Ptr(entry, entry+5, &key_length); + if (comparator_.comparator.user_comparator()->Compare( + Slice(key_ptr, key_length - 8), + key.user_key()) == 0) { + // Correct user key + const uint64_t tag = DecodeFixed64(key_ptr + key_length - 8); + switch (static_cast(tag & 0xff)) { + case kTypeValue: { + Slice v = GetLengthPrefixedSlice(key_ptr + key_length); + value->assign(v.data(), v.size()); + return true; + } + case kTypeDeletion: + *s = Status::NotFound(Slice()); + return true; + } + } + } + return false; +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/db/memtable.h b/ios/Pods/leveldb-library/db/memtable.h new file mode 100644 index 00000000..9f41567c --- /dev/null +++ b/ios/Pods/leveldb-library/db/memtable.h @@ -0,0 +1,88 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_DB_MEMTABLE_H_ +#define STORAGE_LEVELDB_DB_MEMTABLE_H_ + +#include +#include "leveldb/db.h" +#include "db/dbformat.h" +#include "db/skiplist.h" +#include "util/arena.h" + +namespace leveldb { + +class InternalKeyComparator; +class Mutex; +class MemTableIterator; + +class MemTable { + public: + // MemTables are reference counted. The initial reference count + // is zero and the caller must call Ref() at least once. + explicit MemTable(const InternalKeyComparator& comparator); + + // Increase reference count. + void Ref() { ++refs_; } + + // Drop reference count. Delete if no more references exist. + void Unref() { + --refs_; + assert(refs_ >= 0); + if (refs_ <= 0) { + delete this; + } + } + + // Returns an estimate of the number of bytes of data in use by this + // data structure. It is safe to call when MemTable is being modified. + size_t ApproximateMemoryUsage(); + + // Return an iterator that yields the contents of the memtable. + // + // The caller must ensure that the underlying MemTable remains live + // while the returned iterator is live. The keys returned by this + // iterator are internal keys encoded by AppendInternalKey in the + // db/format.{h,cc} module. + Iterator* NewIterator(); + + // Add an entry into memtable that maps key to value at the + // specified sequence number and with the specified type. + // Typically value will be empty if type==kTypeDeletion. + void Add(SequenceNumber seq, ValueType type, + const Slice& key, + const Slice& value); + + // If memtable contains a value for key, store it in *value and return true. + // If memtable contains a deletion for key, store a NotFound() error + // in *status and return true. + // Else, return false. + bool Get(const LookupKey& key, std::string* value, Status* s); + + private: + ~MemTable(); // Private since only Unref() should be used to delete it + + struct KeyComparator { + const InternalKeyComparator comparator; + explicit KeyComparator(const InternalKeyComparator& c) : comparator(c) { } + int operator()(const char* a, const char* b) const; + }; + friend class MemTableIterator; + friend class MemTableBackwardIterator; + + typedef SkipList Table; + + KeyComparator comparator_; + int refs_; + Arena arena_; + Table table_; + + // No copying allowed + MemTable(const MemTable&); + void operator=(const MemTable&); +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_DB_MEMTABLE_H_ diff --git a/ios/Pods/leveldb-library/db/repair.cc b/ios/Pods/leveldb-library/db/repair.cc new file mode 100644 index 00000000..4cd4bb04 --- /dev/null +++ b/ios/Pods/leveldb-library/db/repair.cc @@ -0,0 +1,461 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// We recover the contents of the descriptor from the other files we find. +// (1) Any log files are first converted to tables +// (2) We scan every table to compute +// (a) smallest/largest for the table +// (b) largest sequence number in the table +// (3) We generate descriptor contents: +// - log number is set to zero +// - next-file-number is set to 1 + largest file number we found +// - last-sequence-number is set to largest sequence# found across +// all tables (see 2c) +// - compaction pointers are cleared +// - every table file is added at level 0 +// +// Possible optimization 1: +// (a) Compute total size and use to pick appropriate max-level M +// (b) Sort tables by largest sequence# in the table +// (c) For each table: if it overlaps earlier table, place in level-0, +// else place in level-M. +// Possible optimization 2: +// Store per-table metadata (smallest, largest, largest-seq#, ...) +// in the table's meta section to speed up ScanTable. + +#include "db/builder.h" +#include "db/db_impl.h" +#include "db/dbformat.h" +#include "db/filename.h" +#include "db/log_reader.h" +#include "db/log_writer.h" +#include "db/memtable.h" +#include "db/table_cache.h" +#include "db/version_edit.h" +#include "db/write_batch_internal.h" +#include "leveldb/comparator.h" +#include "leveldb/db.h" +#include "leveldb/env.h" + +namespace leveldb { + +namespace { + +class Repairer { + public: + Repairer(const std::string& dbname, const Options& options) + : dbname_(dbname), + env_(options.env), + icmp_(options.comparator), + ipolicy_(options.filter_policy), + options_(SanitizeOptions(dbname, &icmp_, &ipolicy_, options)), + owns_info_log_(options_.info_log != options.info_log), + owns_cache_(options_.block_cache != options.block_cache), + next_file_number_(1) { + // TableCache can be small since we expect each table to be opened once. + table_cache_ = new TableCache(dbname_, &options_, 10); + } + + ~Repairer() { + delete table_cache_; + if (owns_info_log_) { + delete options_.info_log; + } + if (owns_cache_) { + delete options_.block_cache; + } + } + + Status Run() { + Status status = FindFiles(); + if (status.ok()) { + ConvertLogFilesToTables(); + ExtractMetaData(); + status = WriteDescriptor(); + } + if (status.ok()) { + unsigned long long bytes = 0; + for (size_t i = 0; i < tables_.size(); i++) { + bytes += tables_[i].meta.file_size; + } + Log(options_.info_log, + "**** Repaired leveldb %s; " + "recovered %d files; %llu bytes. " + "Some data may have been lost. " + "****", + dbname_.c_str(), + static_cast(tables_.size()), + bytes); + } + return status; + } + + private: + struct TableInfo { + FileMetaData meta; + SequenceNumber max_sequence; + }; + + std::string const dbname_; + Env* const env_; + InternalKeyComparator const icmp_; + InternalFilterPolicy const ipolicy_; + Options const options_; + bool owns_info_log_; + bool owns_cache_; + TableCache* table_cache_; + VersionEdit edit_; + + std::vector manifests_; + std::vector table_numbers_; + std::vector logs_; + std::vector tables_; + uint64_t next_file_number_; + + Status FindFiles() { + std::vector filenames; + Status status = env_->GetChildren(dbname_, &filenames); + if (!status.ok()) { + return status; + } + if (filenames.empty()) { + return Status::IOError(dbname_, "repair found no files"); + } + + uint64_t number; + FileType type; + for (size_t i = 0; i < filenames.size(); i++) { + if (ParseFileName(filenames[i], &number, &type)) { + if (type == kDescriptorFile) { + manifests_.push_back(filenames[i]); + } else { + if (number + 1 > next_file_number_) { + next_file_number_ = number + 1; + } + if (type == kLogFile) { + logs_.push_back(number); + } else if (type == kTableFile) { + table_numbers_.push_back(number); + } else { + // Ignore other files + } + } + } + } + return status; + } + + void ConvertLogFilesToTables() { + for (size_t i = 0; i < logs_.size(); i++) { + std::string logname = LogFileName(dbname_, logs_[i]); + Status status = ConvertLogToTable(logs_[i]); + if (!status.ok()) { + Log(options_.info_log, "Log #%llu: ignoring conversion error: %s", + (unsigned long long) logs_[i], + status.ToString().c_str()); + } + ArchiveFile(logname); + } + } + + Status ConvertLogToTable(uint64_t log) { + struct LogReporter : public log::Reader::Reporter { + Env* env; + Logger* info_log; + uint64_t lognum; + virtual void Corruption(size_t bytes, const Status& s) { + // We print error messages for corruption, but continue repairing. + Log(info_log, "Log #%llu: dropping %d bytes; %s", + (unsigned long long) lognum, + static_cast(bytes), + s.ToString().c_str()); + } + }; + + // Open the log file + std::string logname = LogFileName(dbname_, log); + SequentialFile* lfile; + Status status = env_->NewSequentialFile(logname, &lfile); + if (!status.ok()) { + return status; + } + + // Create the log reader. + LogReporter reporter; + reporter.env = env_; + reporter.info_log = options_.info_log; + reporter.lognum = log; + // We intentionally make log::Reader do checksumming so that + // corruptions cause entire commits to be skipped instead of + // propagating bad information (like overly large sequence + // numbers). + log::Reader reader(lfile, &reporter, false/*do not checksum*/, + 0/*initial_offset*/); + + // Read all the records and add to a memtable + std::string scratch; + Slice record; + WriteBatch batch; + MemTable* mem = new MemTable(icmp_); + mem->Ref(); + int counter = 0; + while (reader.ReadRecord(&record, &scratch)) { + if (record.size() < 12) { + reporter.Corruption( + record.size(), Status::Corruption("log record too small")); + continue; + } + WriteBatchInternal::SetContents(&batch, record); + status = WriteBatchInternal::InsertInto(&batch, mem); + if (status.ok()) { + counter += WriteBatchInternal::Count(&batch); + } else { + Log(options_.info_log, "Log #%llu: ignoring %s", + (unsigned long long) log, + status.ToString().c_str()); + status = Status::OK(); // Keep going with rest of file + } + } + delete lfile; + + // Do not record a version edit for this conversion to a Table + // since ExtractMetaData() will also generate edits. + FileMetaData meta; + meta.number = next_file_number_++; + Iterator* iter = mem->NewIterator(); + status = BuildTable(dbname_, env_, options_, table_cache_, iter, &meta); + delete iter; + mem->Unref(); + mem = NULL; + if (status.ok()) { + if (meta.file_size > 0) { + table_numbers_.push_back(meta.number); + } + } + Log(options_.info_log, "Log #%llu: %d ops saved to Table #%llu %s", + (unsigned long long) log, + counter, + (unsigned long long) meta.number, + status.ToString().c_str()); + return status; + } + + void ExtractMetaData() { + for (size_t i = 0; i < table_numbers_.size(); i++) { + ScanTable(table_numbers_[i]); + } + } + + Iterator* NewTableIterator(const FileMetaData& meta) { + // Same as compaction iterators: if paranoid_checks are on, turn + // on checksum verification. + ReadOptions r; + r.verify_checksums = options_.paranoid_checks; + return table_cache_->NewIterator(r, meta.number, meta.file_size); + } + + void ScanTable(uint64_t number) { + TableInfo t; + t.meta.number = number; + std::string fname = TableFileName(dbname_, number); + Status status = env_->GetFileSize(fname, &t.meta.file_size); + if (!status.ok()) { + // Try alternate file name. + fname = SSTTableFileName(dbname_, number); + Status s2 = env_->GetFileSize(fname, &t.meta.file_size); + if (s2.ok()) { + status = Status::OK(); + } + } + if (!status.ok()) { + ArchiveFile(TableFileName(dbname_, number)); + ArchiveFile(SSTTableFileName(dbname_, number)); + Log(options_.info_log, "Table #%llu: dropped: %s", + (unsigned long long) t.meta.number, + status.ToString().c_str()); + return; + } + + // Extract metadata by scanning through table. + int counter = 0; + Iterator* iter = NewTableIterator(t.meta); + bool empty = true; + ParsedInternalKey parsed; + t.max_sequence = 0; + for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { + Slice key = iter->key(); + if (!ParseInternalKey(key, &parsed)) { + Log(options_.info_log, "Table #%llu: unparsable key %s", + (unsigned long long) t.meta.number, + EscapeString(key).c_str()); + continue; + } + + counter++; + if (empty) { + empty = false; + t.meta.smallest.DecodeFrom(key); + } + t.meta.largest.DecodeFrom(key); + if (parsed.sequence > t.max_sequence) { + t.max_sequence = parsed.sequence; + } + } + if (!iter->status().ok()) { + status = iter->status(); + } + delete iter; + Log(options_.info_log, "Table #%llu: %d entries %s", + (unsigned long long) t.meta.number, + counter, + status.ToString().c_str()); + + if (status.ok()) { + tables_.push_back(t); + } else { + RepairTable(fname, t); // RepairTable archives input file. + } + } + + void RepairTable(const std::string& src, TableInfo t) { + // We will copy src contents to a new table and then rename the + // new table over the source. + + // Create builder. + std::string copy = TableFileName(dbname_, next_file_number_++); + WritableFile* file; + Status s = env_->NewWritableFile(copy, &file); + if (!s.ok()) { + return; + } + TableBuilder* builder = new TableBuilder(options_, file); + + // Copy data. + Iterator* iter = NewTableIterator(t.meta); + int counter = 0; + for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { + builder->Add(iter->key(), iter->value()); + counter++; + } + delete iter; + + ArchiveFile(src); + if (counter == 0) { + builder->Abandon(); // Nothing to save + } else { + s = builder->Finish(); + if (s.ok()) { + t.meta.file_size = builder->FileSize(); + } + } + delete builder; + builder = NULL; + + if (s.ok()) { + s = file->Close(); + } + delete file; + file = NULL; + + if (counter > 0 && s.ok()) { + std::string orig = TableFileName(dbname_, t.meta.number); + s = env_->RenameFile(copy, orig); + if (s.ok()) { + Log(options_.info_log, "Table #%llu: %d entries repaired", + (unsigned long long) t.meta.number, counter); + tables_.push_back(t); + } + } + if (!s.ok()) { + env_->DeleteFile(copy); + } + } + + Status WriteDescriptor() { + std::string tmp = TempFileName(dbname_, 1); + WritableFile* file; + Status status = env_->NewWritableFile(tmp, &file); + if (!status.ok()) { + return status; + } + + SequenceNumber max_sequence = 0; + for (size_t i = 0; i < tables_.size(); i++) { + if (max_sequence < tables_[i].max_sequence) { + max_sequence = tables_[i].max_sequence; + } + } + + edit_.SetComparatorName(icmp_.user_comparator()->Name()); + edit_.SetLogNumber(0); + edit_.SetNextFile(next_file_number_); + edit_.SetLastSequence(max_sequence); + + for (size_t i = 0; i < tables_.size(); i++) { + // TODO(opt): separate out into multiple levels + const TableInfo& t = tables_[i]; + edit_.AddFile(0, t.meta.number, t.meta.file_size, + t.meta.smallest, t.meta.largest); + } + + //fprintf(stderr, "NewDescriptor:\n%s\n", edit_.DebugString().c_str()); + { + log::Writer log(file); + std::string record; + edit_.EncodeTo(&record); + status = log.AddRecord(record); + } + if (status.ok()) { + status = file->Close(); + } + delete file; + file = NULL; + + if (!status.ok()) { + env_->DeleteFile(tmp); + } else { + // Discard older manifests + for (size_t i = 0; i < manifests_.size(); i++) { + ArchiveFile(dbname_ + "/" + manifests_[i]); + } + + // Install new manifest + status = env_->RenameFile(tmp, DescriptorFileName(dbname_, 1)); + if (status.ok()) { + status = SetCurrentFile(env_, dbname_, 1); + } else { + env_->DeleteFile(tmp); + } + } + return status; + } + + void ArchiveFile(const std::string& fname) { + // Move into another directory. E.g., for + // dir/foo + // rename to + // dir/lost/foo + const char* slash = strrchr(fname.c_str(), '/'); + std::string new_dir; + if (slash != NULL) { + new_dir.assign(fname.data(), slash - fname.data()); + } + new_dir.append("/lost"); + env_->CreateDir(new_dir); // Ignore error + std::string new_file = new_dir; + new_file.append("/"); + new_file.append((slash == NULL) ? fname.c_str() : slash + 1); + Status s = env_->RenameFile(fname, new_file); + Log(options_.info_log, "Archiving %s: %s\n", + fname.c_str(), s.ToString().c_str()); + } +}; +} // namespace + +Status RepairDB(const std::string& dbname, const Options& options) { + Repairer repairer(dbname, options); + return repairer.Run(); +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/db/skiplist.h b/ios/Pods/leveldb-library/db/skiplist.h new file mode 100644 index 00000000..8bd77764 --- /dev/null +++ b/ios/Pods/leveldb-library/db/skiplist.h @@ -0,0 +1,384 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_DB_SKIPLIST_H_ +#define STORAGE_LEVELDB_DB_SKIPLIST_H_ + +// Thread safety +// ------------- +// +// Writes require external synchronization, most likely a mutex. +// Reads require a guarantee that the SkipList will not be destroyed +// while the read is in progress. Apart from that, reads progress +// without any internal locking or synchronization. +// +// Invariants: +// +// (1) Allocated nodes are never deleted until the SkipList is +// destroyed. This is trivially guaranteed by the code since we +// never delete any skip list nodes. +// +// (2) The contents of a Node except for the next/prev pointers are +// immutable after the Node has been linked into the SkipList. +// Only Insert() modifies the list, and it is careful to initialize +// a node and use release-stores to publish the nodes in one or +// more lists. +// +// ... prev vs. next pointer ordering ... + +#include +#include +#include "port/port.h" +#include "util/arena.h" +#include "util/random.h" + +namespace leveldb { + +class Arena; + +template +class SkipList { + private: + struct Node; + + public: + // Create a new SkipList object that will use "cmp" for comparing keys, + // and will allocate memory using "*arena". Objects allocated in the arena + // must remain allocated for the lifetime of the skiplist object. + explicit SkipList(Comparator cmp, Arena* arena); + + // Insert key into the list. + // REQUIRES: nothing that compares equal to key is currently in the list. + void Insert(const Key& key); + + // Returns true iff an entry that compares equal to key is in the list. + bool Contains(const Key& key) const; + + // Iteration over the contents of a skip list + class Iterator { + public: + // Initialize an iterator over the specified list. + // The returned iterator is not valid. + explicit Iterator(const SkipList* list); + + // Returns true iff the iterator is positioned at a valid node. + bool Valid() const; + + // Returns the key at the current position. + // REQUIRES: Valid() + const Key& key() const; + + // Advances to the next position. + // REQUIRES: Valid() + void Next(); + + // Advances to the previous position. + // REQUIRES: Valid() + void Prev(); + + // Advance to the first entry with a key >= target + void Seek(const Key& target); + + // Position at the first entry in list. + // Final state of iterator is Valid() iff list is not empty. + void SeekToFirst(); + + // Position at the last entry in list. + // Final state of iterator is Valid() iff list is not empty. + void SeekToLast(); + + private: + const SkipList* list_; + Node* node_; + // Intentionally copyable + }; + + private: + enum { kMaxHeight = 12 }; + + // Immutable after construction + Comparator const compare_; + Arena* const arena_; // Arena used for allocations of nodes + + Node* const head_; + + // Modified only by Insert(). Read racily by readers, but stale + // values are ok. + port::AtomicPointer max_height_; // Height of the entire list + + inline int GetMaxHeight() const { + return static_cast( + reinterpret_cast(max_height_.NoBarrier_Load())); + } + + // Read/written only by Insert(). + Random rnd_; + + Node* NewNode(const Key& key, int height); + int RandomHeight(); + bool Equal(const Key& a, const Key& b) const { return (compare_(a, b) == 0); } + + // Return true if key is greater than the data stored in "n" + bool KeyIsAfterNode(const Key& key, Node* n) const; + + // Return the earliest node that comes at or after key. + // Return NULL if there is no such node. + // + // If prev is non-NULL, fills prev[level] with pointer to previous + // node at "level" for every level in [0..max_height_-1]. + Node* FindGreaterOrEqual(const Key& key, Node** prev) const; + + // Return the latest node with a key < key. + // Return head_ if there is no such node. + Node* FindLessThan(const Key& key) const; + + // Return the last node in the list. + // Return head_ if list is empty. + Node* FindLast() const; + + // No copying allowed + SkipList(const SkipList&); + void operator=(const SkipList&); +}; + +// Implementation details follow +template +struct SkipList::Node { + explicit Node(const Key& k) : key(k) { } + + Key const key; + + // Accessors/mutators for links. Wrapped in methods so we can + // add the appropriate barriers as necessary. + Node* Next(int n) { + assert(n >= 0); + // Use an 'acquire load' so that we observe a fully initialized + // version of the returned Node. + return reinterpret_cast(next_[n].Acquire_Load()); + } + void SetNext(int n, Node* x) { + assert(n >= 0); + // Use a 'release store' so that anybody who reads through this + // pointer observes a fully initialized version of the inserted node. + next_[n].Release_Store(x); + } + + // No-barrier variants that can be safely used in a few locations. + Node* NoBarrier_Next(int n) { + assert(n >= 0); + return reinterpret_cast(next_[n].NoBarrier_Load()); + } + void NoBarrier_SetNext(int n, Node* x) { + assert(n >= 0); + next_[n].NoBarrier_Store(x); + } + + private: + // Array of length equal to the node height. next_[0] is lowest level link. + port::AtomicPointer next_[1]; +}; + +template +typename SkipList::Node* +SkipList::NewNode(const Key& key, int height) { + char* mem = arena_->AllocateAligned( + sizeof(Node) + sizeof(port::AtomicPointer) * (height - 1)); + return new (mem) Node(key); +} + +template +inline SkipList::Iterator::Iterator(const SkipList* list) { + list_ = list; + node_ = NULL; +} + +template +inline bool SkipList::Iterator::Valid() const { + return node_ != NULL; +} + +template +inline const Key& SkipList::Iterator::key() const { + assert(Valid()); + return node_->key; +} + +template +inline void SkipList::Iterator::Next() { + assert(Valid()); + node_ = node_->Next(0); +} + +template +inline void SkipList::Iterator::Prev() { + // Instead of using explicit "prev" links, we just search for the + // last node that falls before key. + assert(Valid()); + node_ = list_->FindLessThan(node_->key); + if (node_ == list_->head_) { + node_ = NULL; + } +} + +template +inline void SkipList::Iterator::Seek(const Key& target) { + node_ = list_->FindGreaterOrEqual(target, NULL); +} + +template +inline void SkipList::Iterator::SeekToFirst() { + node_ = list_->head_->Next(0); +} + +template +inline void SkipList::Iterator::SeekToLast() { + node_ = list_->FindLast(); + if (node_ == list_->head_) { + node_ = NULL; + } +} + +template +int SkipList::RandomHeight() { + // Increase height with probability 1 in kBranching + static const unsigned int kBranching = 4; + int height = 1; + while (height < kMaxHeight && ((rnd_.Next() % kBranching) == 0)) { + height++; + } + assert(height > 0); + assert(height <= kMaxHeight); + return height; +} + +template +bool SkipList::KeyIsAfterNode(const Key& key, Node* n) const { + // NULL n is considered infinite + return (n != NULL) && (compare_(n->key, key) < 0); +} + +template +typename SkipList::Node* SkipList::FindGreaterOrEqual(const Key& key, Node** prev) + const { + Node* x = head_; + int level = GetMaxHeight() - 1; + while (true) { + Node* next = x->Next(level); + if (KeyIsAfterNode(key, next)) { + // Keep searching in this list + x = next; + } else { + if (prev != NULL) prev[level] = x; + if (level == 0) { + return next; + } else { + // Switch to next list + level--; + } + } + } +} + +template +typename SkipList::Node* +SkipList::FindLessThan(const Key& key) const { + Node* x = head_; + int level = GetMaxHeight() - 1; + while (true) { + assert(x == head_ || compare_(x->key, key) < 0); + Node* next = x->Next(level); + if (next == NULL || compare_(next->key, key) >= 0) { + if (level == 0) { + return x; + } else { + // Switch to next list + level--; + } + } else { + x = next; + } + } +} + +template +typename SkipList::Node* SkipList::FindLast() + const { + Node* x = head_; + int level = GetMaxHeight() - 1; + while (true) { + Node* next = x->Next(level); + if (next == NULL) { + if (level == 0) { + return x; + } else { + // Switch to next list + level--; + } + } else { + x = next; + } + } +} + +template +SkipList::SkipList(Comparator cmp, Arena* arena) + : compare_(cmp), + arena_(arena), + head_(NewNode(0 /* any key will do */, kMaxHeight)), + max_height_(reinterpret_cast(1)), + rnd_(0xdeadbeef) { + for (int i = 0; i < kMaxHeight; i++) { + head_->SetNext(i, NULL); + } +} + +template +void SkipList::Insert(const Key& key) { + // TODO(opt): We can use a barrier-free variant of FindGreaterOrEqual() + // here since Insert() is externally synchronized. + Node* prev[kMaxHeight]; + Node* x = FindGreaterOrEqual(key, prev); + + // Our data structure does not allow duplicate insertion + assert(x == NULL || !Equal(key, x->key)); + + int height = RandomHeight(); + if (height > GetMaxHeight()) { + for (int i = GetMaxHeight(); i < height; i++) { + prev[i] = head_; + } + //fprintf(stderr, "Change height from %d to %d\n", max_height_, height); + + // It is ok to mutate max_height_ without any synchronization + // with concurrent readers. A concurrent reader that observes + // the new value of max_height_ will see either the old value of + // new level pointers from head_ (NULL), or a new value set in + // the loop below. In the former case the reader will + // immediately drop to the next level since NULL sorts after all + // keys. In the latter case the reader will use the new node. + max_height_.NoBarrier_Store(reinterpret_cast(height)); + } + + x = NewNode(key, height); + for (int i = 0; i < height; i++) { + // NoBarrier_SetNext() suffices since we will add a barrier when + // we publish a pointer to "x" in prev[i]. + x->NoBarrier_SetNext(i, prev[i]->NoBarrier_Next(i)); + prev[i]->SetNext(i, x); + } +} + +template +bool SkipList::Contains(const Key& key) const { + Node* x = FindGreaterOrEqual(key, NULL); + if (x != NULL && Equal(key, x->key)) { + return true; + } else { + return false; + } +} + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_DB_SKIPLIST_H_ diff --git a/ios/Pods/leveldb-library/db/snapshot.h b/ios/Pods/leveldb-library/db/snapshot.h new file mode 100644 index 00000000..6ed413c4 --- /dev/null +++ b/ios/Pods/leveldb-library/db/snapshot.h @@ -0,0 +1,67 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_DB_SNAPSHOT_H_ +#define STORAGE_LEVELDB_DB_SNAPSHOT_H_ + +#include "db/dbformat.h" +#include "leveldb/db.h" + +namespace leveldb { + +class SnapshotList; + +// Snapshots are kept in a doubly-linked list in the DB. +// Each SnapshotImpl corresponds to a particular sequence number. +class SnapshotImpl : public Snapshot { + public: + SequenceNumber number_; // const after creation + + private: + friend class SnapshotList; + + // SnapshotImpl is kept in a doubly-linked circular list + SnapshotImpl* prev_; + SnapshotImpl* next_; + + SnapshotList* list_; // just for sanity checks +}; + +class SnapshotList { + public: + SnapshotList() { + list_.prev_ = &list_; + list_.next_ = &list_; + } + + bool empty() const { return list_.next_ == &list_; } + SnapshotImpl* oldest() const { assert(!empty()); return list_.next_; } + SnapshotImpl* newest() const { assert(!empty()); return list_.prev_; } + + const SnapshotImpl* New(SequenceNumber seq) { + SnapshotImpl* s = new SnapshotImpl; + s->number_ = seq; + s->list_ = this; + s->next_ = &list_; + s->prev_ = list_.prev_; + s->prev_->next_ = s; + s->next_->prev_ = s; + return s; + } + + void Delete(const SnapshotImpl* s) { + assert(s->list_ == this); + s->prev_->next_ = s->next_; + s->next_->prev_ = s->prev_; + delete s; + } + + private: + // Dummy head of doubly-linked list of snapshots + SnapshotImpl list_; +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_DB_SNAPSHOT_H_ diff --git a/ios/Pods/leveldb-library/db/table_cache.cc b/ios/Pods/leveldb-library/db/table_cache.cc new file mode 100644 index 00000000..e3d82cd3 --- /dev/null +++ b/ios/Pods/leveldb-library/db/table_cache.cc @@ -0,0 +1,127 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "db/table_cache.h" + +#include "db/filename.h" +#include "leveldb/env.h" +#include "leveldb/table.h" +#include "util/coding.h" + +namespace leveldb { + +struct TableAndFile { + RandomAccessFile* file; + Table* table; +}; + +static void DeleteEntry(const Slice& key, void* value) { + TableAndFile* tf = reinterpret_cast(value); + delete tf->table; + delete tf->file; + delete tf; +} + +static void UnrefEntry(void* arg1, void* arg2) { + Cache* cache = reinterpret_cast(arg1); + Cache::Handle* h = reinterpret_cast(arg2); + cache->Release(h); +} + +TableCache::TableCache(const std::string& dbname, + const Options* options, + int entries) + : env_(options->env), + dbname_(dbname), + options_(options), + cache_(NewLRUCache(entries)) { +} + +TableCache::~TableCache() { + delete cache_; +} + +Status TableCache::FindTable(uint64_t file_number, uint64_t file_size, + Cache::Handle** handle) { + Status s; + char buf[sizeof(file_number)]; + EncodeFixed64(buf, file_number); + Slice key(buf, sizeof(buf)); + *handle = cache_->Lookup(key); + if (*handle == NULL) { + std::string fname = TableFileName(dbname_, file_number); + RandomAccessFile* file = NULL; + Table* table = NULL; + s = env_->NewRandomAccessFile(fname, &file); + if (!s.ok()) { + std::string old_fname = SSTTableFileName(dbname_, file_number); + if (env_->NewRandomAccessFile(old_fname, &file).ok()) { + s = Status::OK(); + } + } + if (s.ok()) { + s = Table::Open(*options_, file, file_size, &table); + } + + if (!s.ok()) { + assert(table == NULL); + delete file; + // We do not cache error results so that if the error is transient, + // or somebody repairs the file, we recover automatically. + } else { + TableAndFile* tf = new TableAndFile; + tf->file = file; + tf->table = table; + *handle = cache_->Insert(key, tf, 1, &DeleteEntry); + } + } + return s; +} + +Iterator* TableCache::NewIterator(const ReadOptions& options, + uint64_t file_number, + uint64_t file_size, + Table** tableptr) { + if (tableptr != NULL) { + *tableptr = NULL; + } + + Cache::Handle* handle = NULL; + Status s = FindTable(file_number, file_size, &handle); + if (!s.ok()) { + return NewErrorIterator(s); + } + + Table* table = reinterpret_cast(cache_->Value(handle))->table; + Iterator* result = table->NewIterator(options); + result->RegisterCleanup(&UnrefEntry, cache_, handle); + if (tableptr != NULL) { + *tableptr = table; + } + return result; +} + +Status TableCache::Get(const ReadOptions& options, + uint64_t file_number, + uint64_t file_size, + const Slice& k, + void* arg, + void (*saver)(void*, const Slice&, const Slice&)) { + Cache::Handle* handle = NULL; + Status s = FindTable(file_number, file_size, &handle); + if (s.ok()) { + Table* t = reinterpret_cast(cache_->Value(handle))->table; + s = t->InternalGet(options, k, arg, saver); + cache_->Release(handle); + } + return s; +} + +void TableCache::Evict(uint64_t file_number) { + char buf[sizeof(file_number)]; + EncodeFixed64(buf, file_number); + cache_->Erase(Slice(buf, sizeof(buf))); +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/db/table_cache.h b/ios/Pods/leveldb-library/db/table_cache.h new file mode 100644 index 00000000..8cf4aaf1 --- /dev/null +++ b/ios/Pods/leveldb-library/db/table_cache.h @@ -0,0 +1,61 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// Thread-safe (provides internal synchronization) + +#ifndef STORAGE_LEVELDB_DB_TABLE_CACHE_H_ +#define STORAGE_LEVELDB_DB_TABLE_CACHE_H_ + +#include +#include +#include "db/dbformat.h" +#include "leveldb/cache.h" +#include "leveldb/table.h" +#include "port/port.h" + +namespace leveldb { + +class Env; + +class TableCache { + public: + TableCache(const std::string& dbname, const Options* options, int entries); + ~TableCache(); + + // Return an iterator for the specified file number (the corresponding + // file length must be exactly "file_size" bytes). If "tableptr" is + // non-NULL, also sets "*tableptr" to point to the Table object + // underlying the returned iterator, or NULL if no Table object underlies + // the returned iterator. The returned "*tableptr" object is owned by + // the cache and should not be deleted, and is valid for as long as the + // returned iterator is live. + Iterator* NewIterator(const ReadOptions& options, + uint64_t file_number, + uint64_t file_size, + Table** tableptr = NULL); + + // If a seek to internal key "k" in specified file finds an entry, + // call (*handle_result)(arg, found_key, found_value). + Status Get(const ReadOptions& options, + uint64_t file_number, + uint64_t file_size, + const Slice& k, + void* arg, + void (*handle_result)(void*, const Slice&, const Slice&)); + + // Evict any entry for the specified file number + void Evict(uint64_t file_number); + + private: + Env* const env_; + const std::string dbname_; + const Options* options_; + Cache* cache_; + + Status FindTable(uint64_t file_number, uint64_t file_size, Cache::Handle**); +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_DB_TABLE_CACHE_H_ diff --git a/ios/Pods/leveldb-library/db/version_edit.cc b/ios/Pods/leveldb-library/db/version_edit.cc new file mode 100644 index 00000000..f10a2d58 --- /dev/null +++ b/ios/Pods/leveldb-library/db/version_edit.cc @@ -0,0 +1,266 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "db/version_edit.h" + +#include "db/version_set.h" +#include "util/coding.h" + +namespace leveldb { + +// Tag numbers for serialized VersionEdit. These numbers are written to +// disk and should not be changed. +enum Tag { + kComparator = 1, + kLogNumber = 2, + kNextFileNumber = 3, + kLastSequence = 4, + kCompactPointer = 5, + kDeletedFile = 6, + kNewFile = 7, + // 8 was used for large value refs + kPrevLogNumber = 9 +}; + +void VersionEdit::Clear() { + comparator_.clear(); + log_number_ = 0; + prev_log_number_ = 0; + last_sequence_ = 0; + next_file_number_ = 0; + has_comparator_ = false; + has_log_number_ = false; + has_prev_log_number_ = false; + has_next_file_number_ = false; + has_last_sequence_ = false; + deleted_files_.clear(); + new_files_.clear(); +} + +void VersionEdit::EncodeTo(std::string* dst) const { + if (has_comparator_) { + PutVarint32(dst, kComparator); + PutLengthPrefixedSlice(dst, comparator_); + } + if (has_log_number_) { + PutVarint32(dst, kLogNumber); + PutVarint64(dst, log_number_); + } + if (has_prev_log_number_) { + PutVarint32(dst, kPrevLogNumber); + PutVarint64(dst, prev_log_number_); + } + if (has_next_file_number_) { + PutVarint32(dst, kNextFileNumber); + PutVarint64(dst, next_file_number_); + } + if (has_last_sequence_) { + PutVarint32(dst, kLastSequence); + PutVarint64(dst, last_sequence_); + } + + for (size_t i = 0; i < compact_pointers_.size(); i++) { + PutVarint32(dst, kCompactPointer); + PutVarint32(dst, compact_pointers_[i].first); // level + PutLengthPrefixedSlice(dst, compact_pointers_[i].second.Encode()); + } + + for (DeletedFileSet::const_iterator iter = deleted_files_.begin(); + iter != deleted_files_.end(); + ++iter) { + PutVarint32(dst, kDeletedFile); + PutVarint32(dst, iter->first); // level + PutVarint64(dst, iter->second); // file number + } + + for (size_t i = 0; i < new_files_.size(); i++) { + const FileMetaData& f = new_files_[i].second; + PutVarint32(dst, kNewFile); + PutVarint32(dst, new_files_[i].first); // level + PutVarint64(dst, f.number); + PutVarint64(dst, f.file_size); + PutLengthPrefixedSlice(dst, f.smallest.Encode()); + PutLengthPrefixedSlice(dst, f.largest.Encode()); + } +} + +static bool GetInternalKey(Slice* input, InternalKey* dst) { + Slice str; + if (GetLengthPrefixedSlice(input, &str)) { + dst->DecodeFrom(str); + return true; + } else { + return false; + } +} + +static bool GetLevel(Slice* input, int* level) { + uint32_t v; + if (GetVarint32(input, &v) && + v < config::kNumLevels) { + *level = v; + return true; + } else { + return false; + } +} + +Status VersionEdit::DecodeFrom(const Slice& src) { + Clear(); + Slice input = src; + const char* msg = NULL; + uint32_t tag; + + // Temporary storage for parsing + int level; + uint64_t number; + FileMetaData f; + Slice str; + InternalKey key; + + while (msg == NULL && GetVarint32(&input, &tag)) { + switch (tag) { + case kComparator: + if (GetLengthPrefixedSlice(&input, &str)) { + comparator_ = str.ToString(); + has_comparator_ = true; + } else { + msg = "comparator name"; + } + break; + + case kLogNumber: + if (GetVarint64(&input, &log_number_)) { + has_log_number_ = true; + } else { + msg = "log number"; + } + break; + + case kPrevLogNumber: + if (GetVarint64(&input, &prev_log_number_)) { + has_prev_log_number_ = true; + } else { + msg = "previous log number"; + } + break; + + case kNextFileNumber: + if (GetVarint64(&input, &next_file_number_)) { + has_next_file_number_ = true; + } else { + msg = "next file number"; + } + break; + + case kLastSequence: + if (GetVarint64(&input, &last_sequence_)) { + has_last_sequence_ = true; + } else { + msg = "last sequence number"; + } + break; + + case kCompactPointer: + if (GetLevel(&input, &level) && + GetInternalKey(&input, &key)) { + compact_pointers_.push_back(std::make_pair(level, key)); + } else { + msg = "compaction pointer"; + } + break; + + case kDeletedFile: + if (GetLevel(&input, &level) && + GetVarint64(&input, &number)) { + deleted_files_.insert(std::make_pair(level, number)); + } else { + msg = "deleted file"; + } + break; + + case kNewFile: + if (GetLevel(&input, &level) && + GetVarint64(&input, &f.number) && + GetVarint64(&input, &f.file_size) && + GetInternalKey(&input, &f.smallest) && + GetInternalKey(&input, &f.largest)) { + new_files_.push_back(std::make_pair(level, f)); + } else { + msg = "new-file entry"; + } + break; + + default: + msg = "unknown tag"; + break; + } + } + + if (msg == NULL && !input.empty()) { + msg = "invalid tag"; + } + + Status result; + if (msg != NULL) { + result = Status::Corruption("VersionEdit", msg); + } + return result; +} + +std::string VersionEdit::DebugString() const { + std::string r; + r.append("VersionEdit {"); + if (has_comparator_) { + r.append("\n Comparator: "); + r.append(comparator_); + } + if (has_log_number_) { + r.append("\n LogNumber: "); + AppendNumberTo(&r, log_number_); + } + if (has_prev_log_number_) { + r.append("\n PrevLogNumber: "); + AppendNumberTo(&r, prev_log_number_); + } + if (has_next_file_number_) { + r.append("\n NextFile: "); + AppendNumberTo(&r, next_file_number_); + } + if (has_last_sequence_) { + r.append("\n LastSeq: "); + AppendNumberTo(&r, last_sequence_); + } + for (size_t i = 0; i < compact_pointers_.size(); i++) { + r.append("\n CompactPointer: "); + AppendNumberTo(&r, compact_pointers_[i].first); + r.append(" "); + r.append(compact_pointers_[i].second.DebugString()); + } + for (DeletedFileSet::const_iterator iter = deleted_files_.begin(); + iter != deleted_files_.end(); + ++iter) { + r.append("\n DeleteFile: "); + AppendNumberTo(&r, iter->first); + r.append(" "); + AppendNumberTo(&r, iter->second); + } + for (size_t i = 0; i < new_files_.size(); i++) { + const FileMetaData& f = new_files_[i].second; + r.append("\n AddFile: "); + AppendNumberTo(&r, new_files_[i].first); + r.append(" "); + AppendNumberTo(&r, f.number); + r.append(" "); + AppendNumberTo(&r, f.file_size); + r.append(" "); + r.append(f.smallest.DebugString()); + r.append(" .. "); + r.append(f.largest.DebugString()); + } + r.append("\n}\n"); + return r; +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/db/version_edit.h b/ios/Pods/leveldb-library/db/version_edit.h new file mode 100644 index 00000000..eaef77b3 --- /dev/null +++ b/ios/Pods/leveldb-library/db/version_edit.h @@ -0,0 +1,107 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_DB_VERSION_EDIT_H_ +#define STORAGE_LEVELDB_DB_VERSION_EDIT_H_ + +#include +#include +#include +#include "db/dbformat.h" + +namespace leveldb { + +class VersionSet; + +struct FileMetaData { + int refs; + int allowed_seeks; // Seeks allowed until compaction + uint64_t number; + uint64_t file_size; // File size in bytes + InternalKey smallest; // Smallest internal key served by table + InternalKey largest; // Largest internal key served by table + + FileMetaData() : refs(0), allowed_seeks(1 << 30), file_size(0) { } +}; + +class VersionEdit { + public: + VersionEdit() { Clear(); } + ~VersionEdit() { } + + void Clear(); + + void SetComparatorName(const Slice& name) { + has_comparator_ = true; + comparator_ = name.ToString(); + } + void SetLogNumber(uint64_t num) { + has_log_number_ = true; + log_number_ = num; + } + void SetPrevLogNumber(uint64_t num) { + has_prev_log_number_ = true; + prev_log_number_ = num; + } + void SetNextFile(uint64_t num) { + has_next_file_number_ = true; + next_file_number_ = num; + } + void SetLastSequence(SequenceNumber seq) { + has_last_sequence_ = true; + last_sequence_ = seq; + } + void SetCompactPointer(int level, const InternalKey& key) { + compact_pointers_.push_back(std::make_pair(level, key)); + } + + // Add the specified file at the specified number. + // REQUIRES: This version has not been saved (see VersionSet::SaveTo) + // REQUIRES: "smallest" and "largest" are smallest and largest keys in file + void AddFile(int level, uint64_t file, + uint64_t file_size, + const InternalKey& smallest, + const InternalKey& largest) { + FileMetaData f; + f.number = file; + f.file_size = file_size; + f.smallest = smallest; + f.largest = largest; + new_files_.push_back(std::make_pair(level, f)); + } + + // Delete the specified "file" from the specified "level". + void DeleteFile(int level, uint64_t file) { + deleted_files_.insert(std::make_pair(level, file)); + } + + void EncodeTo(std::string* dst) const; + Status DecodeFrom(const Slice& src); + + std::string DebugString() const; + + private: + friend class VersionSet; + + typedef std::set< std::pair > DeletedFileSet; + + std::string comparator_; + uint64_t log_number_; + uint64_t prev_log_number_; + uint64_t next_file_number_; + SequenceNumber last_sequence_; + bool has_comparator_; + bool has_log_number_; + bool has_prev_log_number_; + bool has_next_file_number_; + bool has_last_sequence_; + + std::vector< std::pair > compact_pointers_; + DeletedFileSet deleted_files_; + std::vector< std::pair > new_files_; +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_DB_VERSION_EDIT_H_ diff --git a/ios/Pods/leveldb-library/db/version_set.cc b/ios/Pods/leveldb-library/db/version_set.cc new file mode 100644 index 00000000..b1256f90 --- /dev/null +++ b/ios/Pods/leveldb-library/db/version_set.cc @@ -0,0 +1,1535 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "db/version_set.h" + +#include +#include +#include "db/filename.h" +#include "db/log_reader.h" +#include "db/log_writer.h" +#include "db/memtable.h" +#include "db/table_cache.h" +#include "leveldb/env.h" +#include "leveldb/table_builder.h" +#include "table/merger.h" +#include "table/two_level_iterator.h" +#include "util/coding.h" +#include "util/logging.h" + +namespace leveldb { + +static int TargetFileSize(const Options* options) { + return options->max_file_size; +} + +// Maximum bytes of overlaps in grandparent (i.e., level+2) before we +// stop building a single file in a level->level+1 compaction. +static int64_t MaxGrandParentOverlapBytes(const Options* options) { + return 10 * TargetFileSize(options); +} + +// Maximum number of bytes in all compacted files. We avoid expanding +// the lower level file set of a compaction if it would make the +// total compaction cover more than this many bytes. +static int64_t ExpandedCompactionByteSizeLimit(const Options* options) { + return 25 * TargetFileSize(options); +} + +static double MaxBytesForLevel(const Options* options, int level) { + // Note: the result for level zero is not really used since we set + // the level-0 compaction threshold based on number of files. + + // Result for both level-0 and level-1 + double result = 10. * 1048576.0; + while (level > 1) { + result *= 10; + level--; + } + return result; +} + +static uint64_t MaxFileSizeForLevel(const Options* options, int level) { + // We could vary per level to reduce number of files? + return TargetFileSize(options); +} + +static int64_t TotalFileSize(const std::vector& files) { + int64_t sum = 0; + for (size_t i = 0; i < files.size(); i++) { + sum += files[i]->file_size; + } + return sum; +} + +Version::~Version() { + assert(refs_ == 0); + + // Remove from linked list + prev_->next_ = next_; + next_->prev_ = prev_; + + // Drop references to files + for (int level = 0; level < config::kNumLevels; level++) { + for (size_t i = 0; i < files_[level].size(); i++) { + FileMetaData* f = files_[level][i]; + assert(f->refs > 0); + f->refs--; + if (f->refs <= 0) { + delete f; + } + } + } +} + +int FindFile(const InternalKeyComparator& icmp, + const std::vector& files, + const Slice& key) { + uint32_t left = 0; + uint32_t right = files.size(); + while (left < right) { + uint32_t mid = (left + right) / 2; + const FileMetaData* f = files[mid]; + if (icmp.InternalKeyComparator::Compare(f->largest.Encode(), key) < 0) { + // Key at "mid.largest" is < "target". Therefore all + // files at or before "mid" are uninteresting. + left = mid + 1; + } else { + // Key at "mid.largest" is >= "target". Therefore all files + // after "mid" are uninteresting. + right = mid; + } + } + return right; +} + +static bool AfterFile(const Comparator* ucmp, + const Slice* user_key, const FileMetaData* f) { + // NULL user_key occurs before all keys and is therefore never after *f + return (user_key != NULL && + ucmp->Compare(*user_key, f->largest.user_key()) > 0); +} + +static bool BeforeFile(const Comparator* ucmp, + const Slice* user_key, const FileMetaData* f) { + // NULL user_key occurs after all keys and is therefore never before *f + return (user_key != NULL && + ucmp->Compare(*user_key, f->smallest.user_key()) < 0); +} + +bool SomeFileOverlapsRange( + const InternalKeyComparator& icmp, + bool disjoint_sorted_files, + const std::vector& files, + const Slice* smallest_user_key, + const Slice* largest_user_key) { + const Comparator* ucmp = icmp.user_comparator(); + if (!disjoint_sorted_files) { + // Need to check against all files + for (size_t i = 0; i < files.size(); i++) { + const FileMetaData* f = files[i]; + if (AfterFile(ucmp, smallest_user_key, f) || + BeforeFile(ucmp, largest_user_key, f)) { + // No overlap + } else { + return true; // Overlap + } + } + return false; + } + + // Binary search over file list + uint32_t index = 0; + if (smallest_user_key != NULL) { + // Find the earliest possible internal key for smallest_user_key + InternalKey small(*smallest_user_key, kMaxSequenceNumber,kValueTypeForSeek); + index = FindFile(icmp, files, small.Encode()); + } + + if (index >= files.size()) { + // beginning of range is after all files, so no overlap. + return false; + } + + return !BeforeFile(ucmp, largest_user_key, files[index]); +} + +// An internal iterator. For a given version/level pair, yields +// information about the files in the level. For a given entry, key() +// is the largest key that occurs in the file, and value() is an +// 16-byte value containing the file number and file size, both +// encoded using EncodeFixed64. +class Version::LevelFileNumIterator : public Iterator { + public: + LevelFileNumIterator(const InternalKeyComparator& icmp, + const std::vector* flist) + : icmp_(icmp), + flist_(flist), + index_(flist->size()) { // Marks as invalid + } + virtual bool Valid() const { + return index_ < flist_->size(); + } + virtual void Seek(const Slice& target) { + index_ = FindFile(icmp_, *flist_, target); + } + virtual void SeekToFirst() { index_ = 0; } + virtual void SeekToLast() { + index_ = flist_->empty() ? 0 : flist_->size() - 1; + } + virtual void Next() { + assert(Valid()); + index_++; + } + virtual void Prev() { + assert(Valid()); + if (index_ == 0) { + index_ = flist_->size(); // Marks as invalid + } else { + index_--; + } + } + Slice key() const { + assert(Valid()); + return (*flist_)[index_]->largest.Encode(); + } + Slice value() const { + assert(Valid()); + EncodeFixed64(value_buf_, (*flist_)[index_]->number); + EncodeFixed64(value_buf_+8, (*flist_)[index_]->file_size); + return Slice(value_buf_, sizeof(value_buf_)); + } + virtual Status status() const { return Status::OK(); } + private: + const InternalKeyComparator icmp_; + const std::vector* const flist_; + uint32_t index_; + + // Backing store for value(). Holds the file number and size. + mutable char value_buf_[16]; +}; + +static Iterator* GetFileIterator(void* arg, + const ReadOptions& options, + const Slice& file_value) { + TableCache* cache = reinterpret_cast(arg); + if (file_value.size() != 16) { + return NewErrorIterator( + Status::Corruption("FileReader invoked with unexpected value")); + } else { + return cache->NewIterator(options, + DecodeFixed64(file_value.data()), + DecodeFixed64(file_value.data() + 8)); + } +} + +Iterator* Version::NewConcatenatingIterator(const ReadOptions& options, + int level) const { + return NewTwoLevelIterator( + new LevelFileNumIterator(vset_->icmp_, &files_[level]), + &GetFileIterator, vset_->table_cache_, options); +} + +void Version::AddIterators(const ReadOptions& options, + std::vector* iters) { + // Merge all level zero files together since they may overlap + for (size_t i = 0; i < files_[0].size(); i++) { + iters->push_back( + vset_->table_cache_->NewIterator( + options, files_[0][i]->number, files_[0][i]->file_size)); + } + + // For levels > 0, we can use a concatenating iterator that sequentially + // walks through the non-overlapping files in the level, opening them + // lazily. + for (int level = 1; level < config::kNumLevels; level++) { + if (!files_[level].empty()) { + iters->push_back(NewConcatenatingIterator(options, level)); + } + } +} + +// Callback from TableCache::Get() +namespace { +enum SaverState { + kNotFound, + kFound, + kDeleted, + kCorrupt, +}; +struct Saver { + SaverState state; + const Comparator* ucmp; + Slice user_key; + std::string* value; +}; +} +static void SaveValue(void* arg, const Slice& ikey, const Slice& v) { + Saver* s = reinterpret_cast(arg); + ParsedInternalKey parsed_key; + if (!ParseInternalKey(ikey, &parsed_key)) { + s->state = kCorrupt; + } else { + if (s->ucmp->Compare(parsed_key.user_key, s->user_key) == 0) { + s->state = (parsed_key.type == kTypeValue) ? kFound : kDeleted; + if (s->state == kFound) { + s->value->assign(v.data(), v.size()); + } + } + } +} + +static bool NewestFirst(FileMetaData* a, FileMetaData* b) { + return a->number > b->number; +} + +void Version::ForEachOverlapping(Slice user_key, Slice internal_key, + void* arg, + bool (*func)(void*, int, FileMetaData*)) { + // TODO(sanjay): Change Version::Get() to use this function. + const Comparator* ucmp = vset_->icmp_.user_comparator(); + + // Search level-0 in order from newest to oldest. + std::vector tmp; + tmp.reserve(files_[0].size()); + for (uint32_t i = 0; i < files_[0].size(); i++) { + FileMetaData* f = files_[0][i]; + if (ucmp->Compare(user_key, f->smallest.user_key()) >= 0 && + ucmp->Compare(user_key, f->largest.user_key()) <= 0) { + tmp.push_back(f); + } + } + if (!tmp.empty()) { + std::sort(tmp.begin(), tmp.end(), NewestFirst); + for (uint32_t i = 0; i < tmp.size(); i++) { + if (!(*func)(arg, 0, tmp[i])) { + return; + } + } + } + + // Search other levels. + for (int level = 1; level < config::kNumLevels; level++) { + size_t num_files = files_[level].size(); + if (num_files == 0) continue; + + // Binary search to find earliest index whose largest key >= internal_key. + uint32_t index = FindFile(vset_->icmp_, files_[level], internal_key); + if (index < num_files) { + FileMetaData* f = files_[level][index]; + if (ucmp->Compare(user_key, f->smallest.user_key()) < 0) { + // All of "f" is past any data for user_key + } else { + if (!(*func)(arg, level, f)) { + return; + } + } + } + } +} + +Status Version::Get(const ReadOptions& options, + const LookupKey& k, + std::string* value, + GetStats* stats) { + Slice ikey = k.internal_key(); + Slice user_key = k.user_key(); + const Comparator* ucmp = vset_->icmp_.user_comparator(); + Status s; + + stats->seek_file = NULL; + stats->seek_file_level = -1; + FileMetaData* last_file_read = NULL; + int last_file_read_level = -1; + + // We can search level-by-level since entries never hop across + // levels. Therefore we are guaranteed that if we find data + // in an smaller level, later levels are irrelevant. + std::vector tmp; + FileMetaData* tmp2; + for (int level = 0; level < config::kNumLevels; level++) { + size_t num_files = files_[level].size(); + if (num_files == 0) continue; + + // Get the list of files to search in this level + FileMetaData* const* files = &files_[level][0]; + if (level == 0) { + // Level-0 files may overlap each other. Find all files that + // overlap user_key and process them in order from newest to oldest. + tmp.reserve(num_files); + for (uint32_t i = 0; i < num_files; i++) { + FileMetaData* f = files[i]; + if (ucmp->Compare(user_key, f->smallest.user_key()) >= 0 && + ucmp->Compare(user_key, f->largest.user_key()) <= 0) { + tmp.push_back(f); + } + } + if (tmp.empty()) continue; + + std::sort(tmp.begin(), tmp.end(), NewestFirst); + files = &tmp[0]; + num_files = tmp.size(); + } else { + // Binary search to find earliest index whose largest key >= ikey. + uint32_t index = FindFile(vset_->icmp_, files_[level], ikey); + if (index >= num_files) { + files = NULL; + num_files = 0; + } else { + tmp2 = files[index]; + if (ucmp->Compare(user_key, tmp2->smallest.user_key()) < 0) { + // All of "tmp2" is past any data for user_key + files = NULL; + num_files = 0; + } else { + files = &tmp2; + num_files = 1; + } + } + } + + for (uint32_t i = 0; i < num_files; ++i) { + if (last_file_read != NULL && stats->seek_file == NULL) { + // We have had more than one seek for this read. Charge the 1st file. + stats->seek_file = last_file_read; + stats->seek_file_level = last_file_read_level; + } + + FileMetaData* f = files[i]; + last_file_read = f; + last_file_read_level = level; + + Saver saver; + saver.state = kNotFound; + saver.ucmp = ucmp; + saver.user_key = user_key; + saver.value = value; + s = vset_->table_cache_->Get(options, f->number, f->file_size, + ikey, &saver, SaveValue); + if (!s.ok()) { + return s; + } + switch (saver.state) { + case kNotFound: + break; // Keep searching in other files + case kFound: + return s; + case kDeleted: + s = Status::NotFound(Slice()); // Use empty error message for speed + return s; + case kCorrupt: + s = Status::Corruption("corrupted key for ", user_key); + return s; + } + } + } + + return Status::NotFound(Slice()); // Use an empty error message for speed +} + +bool Version::UpdateStats(const GetStats& stats) { + FileMetaData* f = stats.seek_file; + if (f != NULL) { + f->allowed_seeks--; + if (f->allowed_seeks <= 0 && file_to_compact_ == NULL) { + file_to_compact_ = f; + file_to_compact_level_ = stats.seek_file_level; + return true; + } + } + return false; +} + +bool Version::RecordReadSample(Slice internal_key) { + ParsedInternalKey ikey; + if (!ParseInternalKey(internal_key, &ikey)) { + return false; + } + + struct State { + GetStats stats; // Holds first matching file + int matches; + + static bool Match(void* arg, int level, FileMetaData* f) { + State* state = reinterpret_cast(arg); + state->matches++; + if (state->matches == 1) { + // Remember first match. + state->stats.seek_file = f; + state->stats.seek_file_level = level; + } + // We can stop iterating once we have a second match. + return state->matches < 2; + } + }; + + State state; + state.matches = 0; + ForEachOverlapping(ikey.user_key, internal_key, &state, &State::Match); + + // Must have at least two matches since we want to merge across + // files. But what if we have a single file that contains many + // overwrites and deletions? Should we have another mechanism for + // finding such files? + if (state.matches >= 2) { + // 1MB cost is about 1 seek (see comment in Builder::Apply). + return UpdateStats(state.stats); + } + return false; +} + +void Version::Ref() { + ++refs_; +} + +void Version::Unref() { + assert(this != &vset_->dummy_versions_); + assert(refs_ >= 1); + --refs_; + if (refs_ == 0) { + delete this; + } +} + +bool Version::OverlapInLevel(int level, + const Slice* smallest_user_key, + const Slice* largest_user_key) { + return SomeFileOverlapsRange(vset_->icmp_, (level > 0), files_[level], + smallest_user_key, largest_user_key); +} + +int Version::PickLevelForMemTableOutput( + const Slice& smallest_user_key, + const Slice& largest_user_key) { + int level = 0; + if (!OverlapInLevel(0, &smallest_user_key, &largest_user_key)) { + // Push to next level if there is no overlap in next level, + // and the #bytes overlapping in the level after that are limited. + InternalKey start(smallest_user_key, kMaxSequenceNumber, kValueTypeForSeek); + InternalKey limit(largest_user_key, 0, static_cast(0)); + std::vector overlaps; + while (level < config::kMaxMemCompactLevel) { + if (OverlapInLevel(level + 1, &smallest_user_key, &largest_user_key)) { + break; + } + if (level + 2 < config::kNumLevels) { + // Check that file does not overlap too many grandparent bytes. + GetOverlappingInputs(level + 2, &start, &limit, &overlaps); + const int64_t sum = TotalFileSize(overlaps); + if (sum > MaxGrandParentOverlapBytes(vset_->options_)) { + break; + } + } + level++; + } + } + return level; +} + +// Store in "*inputs" all files in "level" that overlap [begin,end] +void Version::GetOverlappingInputs( + int level, + const InternalKey* begin, + const InternalKey* end, + std::vector* inputs) { + assert(level >= 0); + assert(level < config::kNumLevels); + inputs->clear(); + Slice user_begin, user_end; + if (begin != NULL) { + user_begin = begin->user_key(); + } + if (end != NULL) { + user_end = end->user_key(); + } + const Comparator* user_cmp = vset_->icmp_.user_comparator(); + for (size_t i = 0; i < files_[level].size(); ) { + FileMetaData* f = files_[level][i++]; + const Slice file_start = f->smallest.user_key(); + const Slice file_limit = f->largest.user_key(); + if (begin != NULL && user_cmp->Compare(file_limit, user_begin) < 0) { + // "f" is completely before specified range; skip it + } else if (end != NULL && user_cmp->Compare(file_start, user_end) > 0) { + // "f" is completely after specified range; skip it + } else { + inputs->push_back(f); + if (level == 0) { + // Level-0 files may overlap each other. So check if the newly + // added file has expanded the range. If so, restart search. + if (begin != NULL && user_cmp->Compare(file_start, user_begin) < 0) { + user_begin = file_start; + inputs->clear(); + i = 0; + } else if (end != NULL && user_cmp->Compare(file_limit, user_end) > 0) { + user_end = file_limit; + inputs->clear(); + i = 0; + } + } + } + } +} + +std::string Version::DebugString() const { + std::string r; + for (int level = 0; level < config::kNumLevels; level++) { + // E.g., + // --- level 1 --- + // 17:123['a' .. 'd'] + // 20:43['e' .. 'g'] + r.append("--- level "); + AppendNumberTo(&r, level); + r.append(" ---\n"); + const std::vector& files = files_[level]; + for (size_t i = 0; i < files.size(); i++) { + r.push_back(' '); + AppendNumberTo(&r, files[i]->number); + r.push_back(':'); + AppendNumberTo(&r, files[i]->file_size); + r.append("["); + r.append(files[i]->smallest.DebugString()); + r.append(" .. "); + r.append(files[i]->largest.DebugString()); + r.append("]\n"); + } + } + return r; +} + +// A helper class so we can efficiently apply a whole sequence +// of edits to a particular state without creating intermediate +// Versions that contain full copies of the intermediate state. +class VersionSet::Builder { + private: + // Helper to sort by v->files_[file_number].smallest + struct BySmallestKey { + const InternalKeyComparator* internal_comparator; + + bool operator()(FileMetaData* f1, FileMetaData* f2) const { + int r = internal_comparator->Compare(f1->smallest, f2->smallest); + if (r != 0) { + return (r < 0); + } else { + // Break ties by file number + return (f1->number < f2->number); + } + } + }; + + typedef std::set FileSet; + struct LevelState { + std::set deleted_files; + FileSet* added_files; + }; + + VersionSet* vset_; + Version* base_; + LevelState levels_[config::kNumLevels]; + + public: + // Initialize a builder with the files from *base and other info from *vset + Builder(VersionSet* vset, Version* base) + : vset_(vset), + base_(base) { + base_->Ref(); + BySmallestKey cmp; + cmp.internal_comparator = &vset_->icmp_; + for (int level = 0; level < config::kNumLevels; level++) { + levels_[level].added_files = new FileSet(cmp); + } + } + + ~Builder() { + for (int level = 0; level < config::kNumLevels; level++) { + const FileSet* added = levels_[level].added_files; + std::vector to_unref; + to_unref.reserve(added->size()); + for (FileSet::const_iterator it = added->begin(); + it != added->end(); ++it) { + to_unref.push_back(*it); + } + delete added; + for (uint32_t i = 0; i < to_unref.size(); i++) { + FileMetaData* f = to_unref[i]; + f->refs--; + if (f->refs <= 0) { + delete f; + } + } + } + base_->Unref(); + } + + // Apply all of the edits in *edit to the current state. + void Apply(VersionEdit* edit) { + // Update compaction pointers + for (size_t i = 0; i < edit->compact_pointers_.size(); i++) { + const int level = edit->compact_pointers_[i].first; + vset_->compact_pointer_[level] = + edit->compact_pointers_[i].second.Encode().ToString(); + } + + // Delete files + const VersionEdit::DeletedFileSet& del = edit->deleted_files_; + for (VersionEdit::DeletedFileSet::const_iterator iter = del.begin(); + iter != del.end(); + ++iter) { + const int level = iter->first; + const uint64_t number = iter->second; + levels_[level].deleted_files.insert(number); + } + + // Add new files + for (size_t i = 0; i < edit->new_files_.size(); i++) { + const int level = edit->new_files_[i].first; + FileMetaData* f = new FileMetaData(edit->new_files_[i].second); + f->refs = 1; + + // We arrange to automatically compact this file after + // a certain number of seeks. Let's assume: + // (1) One seek costs 10ms + // (2) Writing or reading 1MB costs 10ms (100MB/s) + // (3) A compaction of 1MB does 25MB of IO: + // 1MB read from this level + // 10-12MB read from next level (boundaries may be misaligned) + // 10-12MB written to next level + // This implies that 25 seeks cost the same as the compaction + // of 1MB of data. I.e., one seek costs approximately the + // same as the compaction of 40KB of data. We are a little + // conservative and allow approximately one seek for every 16KB + // of data before triggering a compaction. + f->allowed_seeks = (f->file_size / 16384); + if (f->allowed_seeks < 100) f->allowed_seeks = 100; + + levels_[level].deleted_files.erase(f->number); + levels_[level].added_files->insert(f); + } + } + + // Save the current state in *v. + void SaveTo(Version* v) { + BySmallestKey cmp; + cmp.internal_comparator = &vset_->icmp_; + for (int level = 0; level < config::kNumLevels; level++) { + // Merge the set of added files with the set of pre-existing files. + // Drop any deleted files. Store the result in *v. + const std::vector& base_files = base_->files_[level]; + std::vector::const_iterator base_iter = base_files.begin(); + std::vector::const_iterator base_end = base_files.end(); + const FileSet* added = levels_[level].added_files; + v->files_[level].reserve(base_files.size() + added->size()); + for (FileSet::const_iterator added_iter = added->begin(); + added_iter != added->end(); + ++added_iter) { + // Add all smaller files listed in base_ + for (std::vector::const_iterator bpos + = std::upper_bound(base_iter, base_end, *added_iter, cmp); + base_iter != bpos; + ++base_iter) { + MaybeAddFile(v, level, *base_iter); + } + + MaybeAddFile(v, level, *added_iter); + } + + // Add remaining base files + for (; base_iter != base_end; ++base_iter) { + MaybeAddFile(v, level, *base_iter); + } + +#ifndef NDEBUG + // Make sure there is no overlap in levels > 0 + if (level > 0) { + for (uint32_t i = 1; i < v->files_[level].size(); i++) { + const InternalKey& prev_end = v->files_[level][i-1]->largest; + const InternalKey& this_begin = v->files_[level][i]->smallest; + if (vset_->icmp_.Compare(prev_end, this_begin) >= 0) { + fprintf(stderr, "overlapping ranges in same level %s vs. %s\n", + prev_end.DebugString().c_str(), + this_begin.DebugString().c_str()); + abort(); + } + } + } +#endif + } + } + + void MaybeAddFile(Version* v, int level, FileMetaData* f) { + if (levels_[level].deleted_files.count(f->number) > 0) { + // File is deleted: do nothing + } else { + std::vector* files = &v->files_[level]; + if (level > 0 && !files->empty()) { + // Must not overlap + assert(vset_->icmp_.Compare((*files)[files->size()-1]->largest, + f->smallest) < 0); + } + f->refs++; + files->push_back(f); + } + } +}; + +VersionSet::VersionSet(const std::string& dbname, + const Options* options, + TableCache* table_cache, + const InternalKeyComparator* cmp) + : env_(options->env), + dbname_(dbname), + options_(options), + table_cache_(table_cache), + icmp_(*cmp), + next_file_number_(2), + manifest_file_number_(0), // Filled by Recover() + last_sequence_(0), + log_number_(0), + prev_log_number_(0), + descriptor_file_(NULL), + descriptor_log_(NULL), + dummy_versions_(this), + current_(NULL) { + AppendVersion(new Version(this)); +} + +VersionSet::~VersionSet() { + current_->Unref(); + assert(dummy_versions_.next_ == &dummy_versions_); // List must be empty + delete descriptor_log_; + delete descriptor_file_; +} + +void VersionSet::AppendVersion(Version* v) { + // Make "v" current + assert(v->refs_ == 0); + assert(v != current_); + if (current_ != NULL) { + current_->Unref(); + } + current_ = v; + v->Ref(); + + // Append to linked list + v->prev_ = dummy_versions_.prev_; + v->next_ = &dummy_versions_; + v->prev_->next_ = v; + v->next_->prev_ = v; +} + +Status VersionSet::LogAndApply(VersionEdit* edit, port::Mutex* mu) { + if (edit->has_log_number_) { + assert(edit->log_number_ >= log_number_); + assert(edit->log_number_ < next_file_number_); + } else { + edit->SetLogNumber(log_number_); + } + + if (!edit->has_prev_log_number_) { + edit->SetPrevLogNumber(prev_log_number_); + } + + edit->SetNextFile(next_file_number_); + edit->SetLastSequence(last_sequence_); + + Version* v = new Version(this); + { + Builder builder(this, current_); + builder.Apply(edit); + builder.SaveTo(v); + } + Finalize(v); + + // Initialize new descriptor log file if necessary by creating + // a temporary file that contains a snapshot of the current version. + std::string new_manifest_file; + Status s; + if (descriptor_log_ == NULL) { + // No reason to unlock *mu here since we only hit this path in the + // first call to LogAndApply (when opening the database). + assert(descriptor_file_ == NULL); + new_manifest_file = DescriptorFileName(dbname_, manifest_file_number_); + edit->SetNextFile(next_file_number_); + s = env_->NewWritableFile(new_manifest_file, &descriptor_file_); + if (s.ok()) { + descriptor_log_ = new log::Writer(descriptor_file_); + s = WriteSnapshot(descriptor_log_); + } + } + + // Unlock during expensive MANIFEST log write + { + mu->Unlock(); + + // Write new record to MANIFEST log + if (s.ok()) { + std::string record; + edit->EncodeTo(&record); + s = descriptor_log_->AddRecord(record); + if (s.ok()) { + s = descriptor_file_->Sync(); + } + if (!s.ok()) { + Log(options_->info_log, "MANIFEST write: %s\n", s.ToString().c_str()); + } + } + + // If we just created a new descriptor file, install it by writing a + // new CURRENT file that points to it. + if (s.ok() && !new_manifest_file.empty()) { + s = SetCurrentFile(env_, dbname_, manifest_file_number_); + } + + mu->Lock(); + } + + // Install the new version + if (s.ok()) { + AppendVersion(v); + log_number_ = edit->log_number_; + prev_log_number_ = edit->prev_log_number_; + } else { + delete v; + if (!new_manifest_file.empty()) { + delete descriptor_log_; + delete descriptor_file_; + descriptor_log_ = NULL; + descriptor_file_ = NULL; + env_->DeleteFile(new_manifest_file); + } + } + + return s; +} + +Status VersionSet::Recover(bool *save_manifest) { + struct LogReporter : public log::Reader::Reporter { + Status* status; + virtual void Corruption(size_t bytes, const Status& s) { + if (this->status->ok()) *this->status = s; + } + }; + + // Read "CURRENT" file, which contains a pointer to the current manifest file + std::string current; + Status s = ReadFileToString(env_, CurrentFileName(dbname_), ¤t); + if (!s.ok()) { + return s; + } + if (current.empty() || current[current.size()-1] != '\n') { + return Status::Corruption("CURRENT file does not end with newline"); + } + current.resize(current.size() - 1); + + std::string dscname = dbname_ + "/" + current; + SequentialFile* file; + s = env_->NewSequentialFile(dscname, &file); + if (!s.ok()) { + return s; + } + + bool have_log_number = false; + bool have_prev_log_number = false; + bool have_next_file = false; + bool have_last_sequence = false; + uint64_t next_file = 0; + uint64_t last_sequence = 0; + uint64_t log_number = 0; + uint64_t prev_log_number = 0; + Builder builder(this, current_); + + { + LogReporter reporter; + reporter.status = &s; + log::Reader reader(file, &reporter, true/*checksum*/, 0/*initial_offset*/); + Slice record; + std::string scratch; + while (reader.ReadRecord(&record, &scratch) && s.ok()) { + VersionEdit edit; + s = edit.DecodeFrom(record); + if (s.ok()) { + if (edit.has_comparator_ && + edit.comparator_ != icmp_.user_comparator()->Name()) { + s = Status::InvalidArgument( + edit.comparator_ + " does not match existing comparator ", + icmp_.user_comparator()->Name()); + } + } + + if (s.ok()) { + builder.Apply(&edit); + } + + if (edit.has_log_number_) { + log_number = edit.log_number_; + have_log_number = true; + } + + if (edit.has_prev_log_number_) { + prev_log_number = edit.prev_log_number_; + have_prev_log_number = true; + } + + if (edit.has_next_file_number_) { + next_file = edit.next_file_number_; + have_next_file = true; + } + + if (edit.has_last_sequence_) { + last_sequence = edit.last_sequence_; + have_last_sequence = true; + } + } + } + delete file; + file = NULL; + + if (s.ok()) { + if (!have_next_file) { + s = Status::Corruption("no meta-nextfile entry in descriptor"); + } else if (!have_log_number) { + s = Status::Corruption("no meta-lognumber entry in descriptor"); + } else if (!have_last_sequence) { + s = Status::Corruption("no last-sequence-number entry in descriptor"); + } + + if (!have_prev_log_number) { + prev_log_number = 0; + } + + MarkFileNumberUsed(prev_log_number); + MarkFileNumberUsed(log_number); + } + + if (s.ok()) { + Version* v = new Version(this); + builder.SaveTo(v); + // Install recovered version + Finalize(v); + AppendVersion(v); + manifest_file_number_ = next_file; + next_file_number_ = next_file + 1; + last_sequence_ = last_sequence; + log_number_ = log_number; + prev_log_number_ = prev_log_number; + + // See if we can reuse the existing MANIFEST file. + if (ReuseManifest(dscname, current)) { + // No need to save new manifest + } else { + *save_manifest = true; + } + } + + return s; +} + +bool VersionSet::ReuseManifest(const std::string& dscname, + const std::string& dscbase) { + if (!options_->reuse_logs) { + return false; + } + FileType manifest_type; + uint64_t manifest_number; + uint64_t manifest_size; + if (!ParseFileName(dscbase, &manifest_number, &manifest_type) || + manifest_type != kDescriptorFile || + !env_->GetFileSize(dscname, &manifest_size).ok() || + // Make new compacted MANIFEST if old one is too big + manifest_size >= TargetFileSize(options_)) { + return false; + } + + assert(descriptor_file_ == NULL); + assert(descriptor_log_ == NULL); + Status r = env_->NewAppendableFile(dscname, &descriptor_file_); + if (!r.ok()) { + Log(options_->info_log, "Reuse MANIFEST: %s\n", r.ToString().c_str()); + assert(descriptor_file_ == NULL); + return false; + } + + Log(options_->info_log, "Reusing MANIFEST %s\n", dscname.c_str()); + descriptor_log_ = new log::Writer(descriptor_file_, manifest_size); + manifest_file_number_ = manifest_number; + return true; +} + +void VersionSet::MarkFileNumberUsed(uint64_t number) { + if (next_file_number_ <= number) { + next_file_number_ = number + 1; + } +} + +void VersionSet::Finalize(Version* v) { + // Precomputed best level for next compaction + int best_level = -1; + double best_score = -1; + + for (int level = 0; level < config::kNumLevels-1; level++) { + double score; + if (level == 0) { + // We treat level-0 specially by bounding the number of files + // instead of number of bytes for two reasons: + // + // (1) With larger write-buffer sizes, it is nice not to do too + // many level-0 compactions. + // + // (2) The files in level-0 are merged on every read and + // therefore we wish to avoid too many files when the individual + // file size is small (perhaps because of a small write-buffer + // setting, or very high compression ratios, or lots of + // overwrites/deletions). + score = v->files_[level].size() / + static_cast(config::kL0_CompactionTrigger); + } else { + // Compute the ratio of current size to size limit. + const uint64_t level_bytes = TotalFileSize(v->files_[level]); + score = + static_cast(level_bytes) / MaxBytesForLevel(options_, level); + } + + if (score > best_score) { + best_level = level; + best_score = score; + } + } + + v->compaction_level_ = best_level; + v->compaction_score_ = best_score; +} + +Status VersionSet::WriteSnapshot(log::Writer* log) { + // TODO: Break up into multiple records to reduce memory usage on recovery? + + // Save metadata + VersionEdit edit; + edit.SetComparatorName(icmp_.user_comparator()->Name()); + + // Save compaction pointers + for (int level = 0; level < config::kNumLevels; level++) { + if (!compact_pointer_[level].empty()) { + InternalKey key; + key.DecodeFrom(compact_pointer_[level]); + edit.SetCompactPointer(level, key); + } + } + + // Save files + for (int level = 0; level < config::kNumLevels; level++) { + const std::vector& files = current_->files_[level]; + for (size_t i = 0; i < files.size(); i++) { + const FileMetaData* f = files[i]; + edit.AddFile(level, f->number, f->file_size, f->smallest, f->largest); + } + } + + std::string record; + edit.EncodeTo(&record); + return log->AddRecord(record); +} + +int VersionSet::NumLevelFiles(int level) const { + assert(level >= 0); + assert(level < config::kNumLevels); + return current_->files_[level].size(); +} + +const char* VersionSet::LevelSummary(LevelSummaryStorage* scratch) const { + // Update code if kNumLevels changes + assert(config::kNumLevels == 7); + snprintf(scratch->buffer, sizeof(scratch->buffer), + "files[ %d %d %d %d %d %d %d ]", + int(current_->files_[0].size()), + int(current_->files_[1].size()), + int(current_->files_[2].size()), + int(current_->files_[3].size()), + int(current_->files_[4].size()), + int(current_->files_[5].size()), + int(current_->files_[6].size())); + return scratch->buffer; +} + +uint64_t VersionSet::ApproximateOffsetOf(Version* v, const InternalKey& ikey) { + uint64_t result = 0; + for (int level = 0; level < config::kNumLevels; level++) { + const std::vector& files = v->files_[level]; + for (size_t i = 0; i < files.size(); i++) { + if (icmp_.Compare(files[i]->largest, ikey) <= 0) { + // Entire file is before "ikey", so just add the file size + result += files[i]->file_size; + } else if (icmp_.Compare(files[i]->smallest, ikey) > 0) { + // Entire file is after "ikey", so ignore + if (level > 0) { + // Files other than level 0 are sorted by meta->smallest, so + // no further files in this level will contain data for + // "ikey". + break; + } + } else { + // "ikey" falls in the range for this table. Add the + // approximate offset of "ikey" within the table. + Table* tableptr; + Iterator* iter = table_cache_->NewIterator( + ReadOptions(), files[i]->number, files[i]->file_size, &tableptr); + if (tableptr != NULL) { + result += tableptr->ApproximateOffsetOf(ikey.Encode()); + } + delete iter; + } + } + } + return result; +} + +void VersionSet::AddLiveFiles(std::set* live) { + for (Version* v = dummy_versions_.next_; + v != &dummy_versions_; + v = v->next_) { + for (int level = 0; level < config::kNumLevels; level++) { + const std::vector& files = v->files_[level]; + for (size_t i = 0; i < files.size(); i++) { + live->insert(files[i]->number); + } + } + } +} + +int64_t VersionSet::NumLevelBytes(int level) const { + assert(level >= 0); + assert(level < config::kNumLevels); + return TotalFileSize(current_->files_[level]); +} + +int64_t VersionSet::MaxNextLevelOverlappingBytes() { + int64_t result = 0; + std::vector overlaps; + for (int level = 1; level < config::kNumLevels - 1; level++) { + for (size_t i = 0; i < current_->files_[level].size(); i++) { + const FileMetaData* f = current_->files_[level][i]; + current_->GetOverlappingInputs(level+1, &f->smallest, &f->largest, + &overlaps); + const int64_t sum = TotalFileSize(overlaps); + if (sum > result) { + result = sum; + } + } + } + return result; +} + +// Stores the minimal range that covers all entries in inputs in +// *smallest, *largest. +// REQUIRES: inputs is not empty +void VersionSet::GetRange(const std::vector& inputs, + InternalKey* smallest, + InternalKey* largest) { + assert(!inputs.empty()); + smallest->Clear(); + largest->Clear(); + for (size_t i = 0; i < inputs.size(); i++) { + FileMetaData* f = inputs[i]; + if (i == 0) { + *smallest = f->smallest; + *largest = f->largest; + } else { + if (icmp_.Compare(f->smallest, *smallest) < 0) { + *smallest = f->smallest; + } + if (icmp_.Compare(f->largest, *largest) > 0) { + *largest = f->largest; + } + } + } +} + +// Stores the minimal range that covers all entries in inputs1 and inputs2 +// in *smallest, *largest. +// REQUIRES: inputs is not empty +void VersionSet::GetRange2(const std::vector& inputs1, + const std::vector& inputs2, + InternalKey* smallest, + InternalKey* largest) { + std::vector all = inputs1; + all.insert(all.end(), inputs2.begin(), inputs2.end()); + GetRange(all, smallest, largest); +} + +Iterator* VersionSet::MakeInputIterator(Compaction* c) { + ReadOptions options; + options.verify_checksums = options_->paranoid_checks; + options.fill_cache = false; + + // Level-0 files have to be merged together. For other levels, + // we will make a concatenating iterator per level. + // TODO(opt): use concatenating iterator for level-0 if there is no overlap + const int space = (c->level() == 0 ? c->inputs_[0].size() + 1 : 2); + Iterator** list = new Iterator*[space]; + int num = 0; + for (int which = 0; which < 2; which++) { + if (!c->inputs_[which].empty()) { + if (c->level() + which == 0) { + const std::vector& files = c->inputs_[which]; + for (size_t i = 0; i < files.size(); i++) { + list[num++] = table_cache_->NewIterator( + options, files[i]->number, files[i]->file_size); + } + } else { + // Create concatenating iterator for the files from this level + list[num++] = NewTwoLevelIterator( + new Version::LevelFileNumIterator(icmp_, &c->inputs_[which]), + &GetFileIterator, table_cache_, options); + } + } + } + assert(num <= space); + Iterator* result = NewMergingIterator(&icmp_, list, num); + delete[] list; + return result; +} + +Compaction* VersionSet::PickCompaction() { + Compaction* c; + int level; + + // We prefer compactions triggered by too much data in a level over + // the compactions triggered by seeks. + const bool size_compaction = (current_->compaction_score_ >= 1); + const bool seek_compaction = (current_->file_to_compact_ != NULL); + if (size_compaction) { + level = current_->compaction_level_; + assert(level >= 0); + assert(level+1 < config::kNumLevels); + c = new Compaction(options_, level); + + // Pick the first file that comes after compact_pointer_[level] + for (size_t i = 0; i < current_->files_[level].size(); i++) { + FileMetaData* f = current_->files_[level][i]; + if (compact_pointer_[level].empty() || + icmp_.Compare(f->largest.Encode(), compact_pointer_[level]) > 0) { + c->inputs_[0].push_back(f); + break; + } + } + if (c->inputs_[0].empty()) { + // Wrap-around to the beginning of the key space + c->inputs_[0].push_back(current_->files_[level][0]); + } + } else if (seek_compaction) { + level = current_->file_to_compact_level_; + c = new Compaction(options_, level); + c->inputs_[0].push_back(current_->file_to_compact_); + } else { + return NULL; + } + + c->input_version_ = current_; + c->input_version_->Ref(); + + // Files in level 0 may overlap each other, so pick up all overlapping ones + if (level == 0) { + InternalKey smallest, largest; + GetRange(c->inputs_[0], &smallest, &largest); + // Note that the next call will discard the file we placed in + // c->inputs_[0] earlier and replace it with an overlapping set + // which will include the picked file. + current_->GetOverlappingInputs(0, &smallest, &largest, &c->inputs_[0]); + assert(!c->inputs_[0].empty()); + } + + SetupOtherInputs(c); + + return c; +} + +void VersionSet::SetupOtherInputs(Compaction* c) { + const int level = c->level(); + InternalKey smallest, largest; + GetRange(c->inputs_[0], &smallest, &largest); + + current_->GetOverlappingInputs(level+1, &smallest, &largest, &c->inputs_[1]); + + // Get entire range covered by compaction + InternalKey all_start, all_limit; + GetRange2(c->inputs_[0], c->inputs_[1], &all_start, &all_limit); + + // See if we can grow the number of inputs in "level" without + // changing the number of "level+1" files we pick up. + if (!c->inputs_[1].empty()) { + std::vector expanded0; + current_->GetOverlappingInputs(level, &all_start, &all_limit, &expanded0); + const int64_t inputs0_size = TotalFileSize(c->inputs_[0]); + const int64_t inputs1_size = TotalFileSize(c->inputs_[1]); + const int64_t expanded0_size = TotalFileSize(expanded0); + if (expanded0.size() > c->inputs_[0].size() && + inputs1_size + expanded0_size < + ExpandedCompactionByteSizeLimit(options_)) { + InternalKey new_start, new_limit; + GetRange(expanded0, &new_start, &new_limit); + std::vector expanded1; + current_->GetOverlappingInputs(level+1, &new_start, &new_limit, + &expanded1); + if (expanded1.size() == c->inputs_[1].size()) { + Log(options_->info_log, + "Expanding@%d %d+%d (%ld+%ld bytes) to %d+%d (%ld+%ld bytes)\n", + level, + int(c->inputs_[0].size()), + int(c->inputs_[1].size()), + long(inputs0_size), long(inputs1_size), + int(expanded0.size()), + int(expanded1.size()), + long(expanded0_size), long(inputs1_size)); + smallest = new_start; + largest = new_limit; + c->inputs_[0] = expanded0; + c->inputs_[1] = expanded1; + GetRange2(c->inputs_[0], c->inputs_[1], &all_start, &all_limit); + } + } + } + + // Compute the set of grandparent files that overlap this compaction + // (parent == level+1; grandparent == level+2) + if (level + 2 < config::kNumLevels) { + current_->GetOverlappingInputs(level + 2, &all_start, &all_limit, + &c->grandparents_); + } + + if (false) { + Log(options_->info_log, "Compacting %d '%s' .. '%s'", + level, + smallest.DebugString().c_str(), + largest.DebugString().c_str()); + } + + // Update the place where we will do the next compaction for this level. + // We update this immediately instead of waiting for the VersionEdit + // to be applied so that if the compaction fails, we will try a different + // key range next time. + compact_pointer_[level] = largest.Encode().ToString(); + c->edit_.SetCompactPointer(level, largest); +} + +Compaction* VersionSet::CompactRange( + int level, + const InternalKey* begin, + const InternalKey* end) { + std::vector inputs; + current_->GetOverlappingInputs(level, begin, end, &inputs); + if (inputs.empty()) { + return NULL; + } + + // Avoid compacting too much in one shot in case the range is large. + // But we cannot do this for level-0 since level-0 files can overlap + // and we must not pick one file and drop another older file if the + // two files overlap. + if (level > 0) { + const uint64_t limit = MaxFileSizeForLevel(options_, level); + uint64_t total = 0; + for (size_t i = 0; i < inputs.size(); i++) { + uint64_t s = inputs[i]->file_size; + total += s; + if (total >= limit) { + inputs.resize(i + 1); + break; + } + } + } + + Compaction* c = new Compaction(options_, level); + c->input_version_ = current_; + c->input_version_->Ref(); + c->inputs_[0] = inputs; + SetupOtherInputs(c); + return c; +} + +Compaction::Compaction(const Options* options, int level) + : level_(level), + max_output_file_size_(MaxFileSizeForLevel(options, level)), + input_version_(NULL), + grandparent_index_(0), + seen_key_(false), + overlapped_bytes_(0) { + for (int i = 0; i < config::kNumLevels; i++) { + level_ptrs_[i] = 0; + } +} + +Compaction::~Compaction() { + if (input_version_ != NULL) { + input_version_->Unref(); + } +} + +bool Compaction::IsTrivialMove() const { + const VersionSet* vset = input_version_->vset_; + // Avoid a move if there is lots of overlapping grandparent data. + // Otherwise, the move could create a parent file that will require + // a very expensive merge later on. + return (num_input_files(0) == 1 && num_input_files(1) == 0 && + TotalFileSize(grandparents_) <= + MaxGrandParentOverlapBytes(vset->options_)); +} + +void Compaction::AddInputDeletions(VersionEdit* edit) { + for (int which = 0; which < 2; which++) { + for (size_t i = 0; i < inputs_[which].size(); i++) { + edit->DeleteFile(level_ + which, inputs_[which][i]->number); + } + } +} + +bool Compaction::IsBaseLevelForKey(const Slice& user_key) { + // Maybe use binary search to find right entry instead of linear search? + const Comparator* user_cmp = input_version_->vset_->icmp_.user_comparator(); + for (int lvl = level_ + 2; lvl < config::kNumLevels; lvl++) { + const std::vector& files = input_version_->files_[lvl]; + for (; level_ptrs_[lvl] < files.size(); ) { + FileMetaData* f = files[level_ptrs_[lvl]]; + if (user_cmp->Compare(user_key, f->largest.user_key()) <= 0) { + // We've advanced far enough + if (user_cmp->Compare(user_key, f->smallest.user_key()) >= 0) { + // Key falls in this file's range, so definitely not base level + return false; + } + break; + } + level_ptrs_[lvl]++; + } + } + return true; +} + +bool Compaction::ShouldStopBefore(const Slice& internal_key) { + const VersionSet* vset = input_version_->vset_; + // Scan to find earliest grandparent file that contains key. + const InternalKeyComparator* icmp = &vset->icmp_; + while (grandparent_index_ < grandparents_.size() && + icmp->Compare(internal_key, + grandparents_[grandparent_index_]->largest.Encode()) > 0) { + if (seen_key_) { + overlapped_bytes_ += grandparents_[grandparent_index_]->file_size; + } + grandparent_index_++; + } + seen_key_ = true; + + if (overlapped_bytes_ > MaxGrandParentOverlapBytes(vset->options_)) { + // Too much overlap for current output; start new output + overlapped_bytes_ = 0; + return true; + } else { + return false; + } +} + +void Compaction::ReleaseInputs() { + if (input_version_ != NULL) { + input_version_->Unref(); + input_version_ = NULL; + } +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/db/version_set.h b/ios/Pods/leveldb-library/db/version_set.h new file mode 100644 index 00000000..c4e7ac36 --- /dev/null +++ b/ios/Pods/leveldb-library/db/version_set.h @@ -0,0 +1,398 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// The representation of a DBImpl consists of a set of Versions. The +// newest version is called "current". Older versions may be kept +// around to provide a consistent view to live iterators. +// +// Each Version keeps track of a set of Table files per level. The +// entire set of versions is maintained in a VersionSet. +// +// Version,VersionSet are thread-compatible, but require external +// synchronization on all accesses. + +#ifndef STORAGE_LEVELDB_DB_VERSION_SET_H_ +#define STORAGE_LEVELDB_DB_VERSION_SET_H_ + +#include +#include +#include +#include "db/dbformat.h" +#include "db/version_edit.h" +#include "port/port.h" +#include "port/thread_annotations.h" + +namespace leveldb { + +namespace log { class Writer; } + +class Compaction; +class Iterator; +class MemTable; +class TableBuilder; +class TableCache; +class Version; +class VersionSet; +class WritableFile; + +// Return the smallest index i such that files[i]->largest >= key. +// Return files.size() if there is no such file. +// REQUIRES: "files" contains a sorted list of non-overlapping files. +extern int FindFile(const InternalKeyComparator& icmp, + const std::vector& files, + const Slice& key); + +// Returns true iff some file in "files" overlaps the user key range +// [*smallest,*largest]. +// smallest==NULL represents a key smaller than all keys in the DB. +// largest==NULL represents a key largest than all keys in the DB. +// REQUIRES: If disjoint_sorted_files, files[] contains disjoint ranges +// in sorted order. +extern bool SomeFileOverlapsRange( + const InternalKeyComparator& icmp, + bool disjoint_sorted_files, + const std::vector& files, + const Slice* smallest_user_key, + const Slice* largest_user_key); + +class Version { + public: + // Append to *iters a sequence of iterators that will + // yield the contents of this Version when merged together. + // REQUIRES: This version has been saved (see VersionSet::SaveTo) + void AddIterators(const ReadOptions&, std::vector* iters); + + // Lookup the value for key. If found, store it in *val and + // return OK. Else return a non-OK status. Fills *stats. + // REQUIRES: lock is not held + struct GetStats { + FileMetaData* seek_file; + int seek_file_level; + }; + Status Get(const ReadOptions&, const LookupKey& key, std::string* val, + GetStats* stats); + + // Adds "stats" into the current state. Returns true if a new + // compaction may need to be triggered, false otherwise. + // REQUIRES: lock is held + bool UpdateStats(const GetStats& stats); + + // Record a sample of bytes read at the specified internal key. + // Samples are taken approximately once every config::kReadBytesPeriod + // bytes. Returns true if a new compaction may need to be triggered. + // REQUIRES: lock is held + bool RecordReadSample(Slice key); + + // Reference count management (so Versions do not disappear out from + // under live iterators) + void Ref(); + void Unref(); + + void GetOverlappingInputs( + int level, + const InternalKey* begin, // NULL means before all keys + const InternalKey* end, // NULL means after all keys + std::vector* inputs); + + // Returns true iff some file in the specified level overlaps + // some part of [*smallest_user_key,*largest_user_key]. + // smallest_user_key==NULL represents a key smaller than all keys in the DB. + // largest_user_key==NULL represents a key largest than all keys in the DB. + bool OverlapInLevel(int level, + const Slice* smallest_user_key, + const Slice* largest_user_key); + + // Return the level at which we should place a new memtable compaction + // result that covers the range [smallest_user_key,largest_user_key]. + int PickLevelForMemTableOutput(const Slice& smallest_user_key, + const Slice& largest_user_key); + + int NumFiles(int level) const { return files_[level].size(); } + + // Return a human readable string that describes this version's contents. + std::string DebugString() const; + + private: + friend class Compaction; + friend class VersionSet; + + class LevelFileNumIterator; + Iterator* NewConcatenatingIterator(const ReadOptions&, int level) const; + + // Call func(arg, level, f) for every file that overlaps user_key in + // order from newest to oldest. If an invocation of func returns + // false, makes no more calls. + // + // REQUIRES: user portion of internal_key == user_key. + void ForEachOverlapping(Slice user_key, Slice internal_key, + void* arg, + bool (*func)(void*, int, FileMetaData*)); + + VersionSet* vset_; // VersionSet to which this Version belongs + Version* next_; // Next version in linked list + Version* prev_; // Previous version in linked list + int refs_; // Number of live refs to this version + + // List of files per level + std::vector files_[config::kNumLevels]; + + // Next file to compact based on seek stats. + FileMetaData* file_to_compact_; + int file_to_compact_level_; + + // Level that should be compacted next and its compaction score. + // Score < 1 means compaction is not strictly needed. These fields + // are initialized by Finalize(). + double compaction_score_; + int compaction_level_; + + explicit Version(VersionSet* vset) + : vset_(vset), next_(this), prev_(this), refs_(0), + file_to_compact_(NULL), + file_to_compact_level_(-1), + compaction_score_(-1), + compaction_level_(-1) { + } + + ~Version(); + + // No copying allowed + Version(const Version&); + void operator=(const Version&); +}; + +class VersionSet { + public: + VersionSet(const std::string& dbname, + const Options* options, + TableCache* table_cache, + const InternalKeyComparator*); + ~VersionSet(); + + // Apply *edit to the current version to form a new descriptor that + // is both saved to persistent state and installed as the new + // current version. Will release *mu while actually writing to the file. + // REQUIRES: *mu is held on entry. + // REQUIRES: no other thread concurrently calls LogAndApply() + Status LogAndApply(VersionEdit* edit, port::Mutex* mu) + EXCLUSIVE_LOCKS_REQUIRED(mu); + + // Recover the last saved descriptor from persistent storage. + Status Recover(bool *save_manifest); + + // Return the current version. + Version* current() const { return current_; } + + // Return the current manifest file number + uint64_t ManifestFileNumber() const { return manifest_file_number_; } + + // Allocate and return a new file number + uint64_t NewFileNumber() { return next_file_number_++; } + + // Arrange to reuse "file_number" unless a newer file number has + // already been allocated. + // REQUIRES: "file_number" was returned by a call to NewFileNumber(). + void ReuseFileNumber(uint64_t file_number) { + if (next_file_number_ == file_number + 1) { + next_file_number_ = file_number; + } + } + + // Return the number of Table files at the specified level. + int NumLevelFiles(int level) const; + + // Return the combined file size of all files at the specified level. + int64_t NumLevelBytes(int level) const; + + // Return the last sequence number. + uint64_t LastSequence() const { return last_sequence_; } + + // Set the last sequence number to s. + void SetLastSequence(uint64_t s) { + assert(s >= last_sequence_); + last_sequence_ = s; + } + + // Mark the specified file number as used. + void MarkFileNumberUsed(uint64_t number); + + // Return the current log file number. + uint64_t LogNumber() const { return log_number_; } + + // Return the log file number for the log file that is currently + // being compacted, or zero if there is no such log file. + uint64_t PrevLogNumber() const { return prev_log_number_; } + + // Pick level and inputs for a new compaction. + // Returns NULL if there is no compaction to be done. + // Otherwise returns a pointer to a heap-allocated object that + // describes the compaction. Caller should delete the result. + Compaction* PickCompaction(); + + // Return a compaction object for compacting the range [begin,end] in + // the specified level. Returns NULL if there is nothing in that + // level that overlaps the specified range. Caller should delete + // the result. + Compaction* CompactRange( + int level, + const InternalKey* begin, + const InternalKey* end); + + // Return the maximum overlapping data (in bytes) at next level for any + // file at a level >= 1. + int64_t MaxNextLevelOverlappingBytes(); + + // Create an iterator that reads over the compaction inputs for "*c". + // The caller should delete the iterator when no longer needed. + Iterator* MakeInputIterator(Compaction* c); + + // Returns true iff some level needs a compaction. + bool NeedsCompaction() const { + Version* v = current_; + return (v->compaction_score_ >= 1) || (v->file_to_compact_ != NULL); + } + + // Add all files listed in any live version to *live. + // May also mutate some internal state. + void AddLiveFiles(std::set* live); + + // Return the approximate offset in the database of the data for + // "key" as of version "v". + uint64_t ApproximateOffsetOf(Version* v, const InternalKey& key); + + // Return a human-readable short (single-line) summary of the number + // of files per level. Uses *scratch as backing store. + struct LevelSummaryStorage { + char buffer[100]; + }; + const char* LevelSummary(LevelSummaryStorage* scratch) const; + + private: + class Builder; + + friend class Compaction; + friend class Version; + + bool ReuseManifest(const std::string& dscname, const std::string& dscbase); + + void Finalize(Version* v); + + void GetRange(const std::vector& inputs, + InternalKey* smallest, + InternalKey* largest); + + void GetRange2(const std::vector& inputs1, + const std::vector& inputs2, + InternalKey* smallest, + InternalKey* largest); + + void SetupOtherInputs(Compaction* c); + + // Save current contents to *log + Status WriteSnapshot(log::Writer* log); + + void AppendVersion(Version* v); + + Env* const env_; + const std::string dbname_; + const Options* const options_; + TableCache* const table_cache_; + const InternalKeyComparator icmp_; + uint64_t next_file_number_; + uint64_t manifest_file_number_; + uint64_t last_sequence_; + uint64_t log_number_; + uint64_t prev_log_number_; // 0 or backing store for memtable being compacted + + // Opened lazily + WritableFile* descriptor_file_; + log::Writer* descriptor_log_; + Version dummy_versions_; // Head of circular doubly-linked list of versions. + Version* current_; // == dummy_versions_.prev_ + + // Per-level key at which the next compaction at that level should start. + // Either an empty string, or a valid InternalKey. + std::string compact_pointer_[config::kNumLevels]; + + // No copying allowed + VersionSet(const VersionSet&); + void operator=(const VersionSet&); +}; + +// A Compaction encapsulates information about a compaction. +class Compaction { + public: + ~Compaction(); + + // Return the level that is being compacted. Inputs from "level" + // and "level+1" will be merged to produce a set of "level+1" files. + int level() const { return level_; } + + // Return the object that holds the edits to the descriptor done + // by this compaction. + VersionEdit* edit() { return &edit_; } + + // "which" must be either 0 or 1 + int num_input_files(int which) const { return inputs_[which].size(); } + + // Return the ith input file at "level()+which" ("which" must be 0 or 1). + FileMetaData* input(int which, int i) const { return inputs_[which][i]; } + + // Maximum size of files to build during this compaction. + uint64_t MaxOutputFileSize() const { return max_output_file_size_; } + + // Is this a trivial compaction that can be implemented by just + // moving a single input file to the next level (no merging or splitting) + bool IsTrivialMove() const; + + // Add all inputs to this compaction as delete operations to *edit. + void AddInputDeletions(VersionEdit* edit); + + // Returns true if the information we have available guarantees that + // the compaction is producing data in "level+1" for which no data exists + // in levels greater than "level+1". + bool IsBaseLevelForKey(const Slice& user_key); + + // Returns true iff we should stop building the current output + // before processing "internal_key". + bool ShouldStopBefore(const Slice& internal_key); + + // Release the input version for the compaction, once the compaction + // is successful. + void ReleaseInputs(); + + private: + friend class Version; + friend class VersionSet; + + Compaction(const Options* options, int level); + + int level_; + uint64_t max_output_file_size_; + Version* input_version_; + VersionEdit edit_; + + // Each compaction reads inputs from "level_" and "level_+1" + std::vector inputs_[2]; // The two sets of inputs + + // State used to check for number of of overlapping grandparent files + // (parent == level_ + 1, grandparent == level_ + 2) + std::vector grandparents_; + size_t grandparent_index_; // Index in grandparent_starts_ + bool seen_key_; // Some output key has been seen + int64_t overlapped_bytes_; // Bytes of overlap between current output + // and grandparent files + + // State for implementing IsBaseLevelForKey + + // level_ptrs_ holds indices into input_version_->levels_: our state + // is that we are positioned at one of the file ranges for each + // higher level than the ones involved in this compaction (i.e. for + // all L >= level_ + 2). + size_t level_ptrs_[config::kNumLevels]; +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_DB_VERSION_SET_H_ diff --git a/ios/Pods/leveldb-library/db/write_batch.cc b/ios/Pods/leveldb-library/db/write_batch.cc new file mode 100644 index 00000000..33f4a425 --- /dev/null +++ b/ios/Pods/leveldb-library/db/write_batch.cc @@ -0,0 +1,147 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// WriteBatch::rep_ := +// sequence: fixed64 +// count: fixed32 +// data: record[count] +// record := +// kTypeValue varstring varstring | +// kTypeDeletion varstring +// varstring := +// len: varint32 +// data: uint8[len] + +#include "leveldb/write_batch.h" + +#include "leveldb/db.h" +#include "db/dbformat.h" +#include "db/memtable.h" +#include "db/write_batch_internal.h" +#include "util/coding.h" + +namespace leveldb { + +// WriteBatch header has an 8-byte sequence number followed by a 4-byte count. +static const size_t kHeader = 12; + +WriteBatch::WriteBatch() { + Clear(); +} + +WriteBatch::~WriteBatch() { } + +WriteBatch::Handler::~Handler() { } + +void WriteBatch::Clear() { + rep_.clear(); + rep_.resize(kHeader); +} + +Status WriteBatch::Iterate(Handler* handler) const { + Slice input(rep_); + if (input.size() < kHeader) { + return Status::Corruption("malformed WriteBatch (too small)"); + } + + input.remove_prefix(kHeader); + Slice key, value; + int found = 0; + while (!input.empty()) { + found++; + char tag = input[0]; + input.remove_prefix(1); + switch (tag) { + case kTypeValue: + if (GetLengthPrefixedSlice(&input, &key) && + GetLengthPrefixedSlice(&input, &value)) { + handler->Put(key, value); + } else { + return Status::Corruption("bad WriteBatch Put"); + } + break; + case kTypeDeletion: + if (GetLengthPrefixedSlice(&input, &key)) { + handler->Delete(key); + } else { + return Status::Corruption("bad WriteBatch Delete"); + } + break; + default: + return Status::Corruption("unknown WriteBatch tag"); + } + } + if (found != WriteBatchInternal::Count(this)) { + return Status::Corruption("WriteBatch has wrong count"); + } else { + return Status::OK(); + } +} + +int WriteBatchInternal::Count(const WriteBatch* b) { + return DecodeFixed32(b->rep_.data() + 8); +} + +void WriteBatchInternal::SetCount(WriteBatch* b, int n) { + EncodeFixed32(&b->rep_[8], n); +} + +SequenceNumber WriteBatchInternal::Sequence(const WriteBatch* b) { + return SequenceNumber(DecodeFixed64(b->rep_.data())); +} + +void WriteBatchInternal::SetSequence(WriteBatch* b, SequenceNumber seq) { + EncodeFixed64(&b->rep_[0], seq); +} + +void WriteBatch::Put(const Slice& key, const Slice& value) { + WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1); + rep_.push_back(static_cast(kTypeValue)); + PutLengthPrefixedSlice(&rep_, key); + PutLengthPrefixedSlice(&rep_, value); +} + +void WriteBatch::Delete(const Slice& key) { + WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1); + rep_.push_back(static_cast(kTypeDeletion)); + PutLengthPrefixedSlice(&rep_, key); +} + +namespace { +class MemTableInserter : public WriteBatch::Handler { + public: + SequenceNumber sequence_; + MemTable* mem_; + + virtual void Put(const Slice& key, const Slice& value) { + mem_->Add(sequence_, kTypeValue, key, value); + sequence_++; + } + virtual void Delete(const Slice& key) { + mem_->Add(sequence_, kTypeDeletion, key, Slice()); + sequence_++; + } +}; +} // namespace + +Status WriteBatchInternal::InsertInto(const WriteBatch* b, + MemTable* memtable) { + MemTableInserter inserter; + inserter.sequence_ = WriteBatchInternal::Sequence(b); + inserter.mem_ = memtable; + return b->Iterate(&inserter); +} + +void WriteBatchInternal::SetContents(WriteBatch* b, const Slice& contents) { + assert(contents.size() >= kHeader); + b->rep_.assign(contents.data(), contents.size()); +} + +void WriteBatchInternal::Append(WriteBatch* dst, const WriteBatch* src) { + SetCount(dst, Count(dst) + Count(src)); + assert(src->rep_.size() >= kHeader); + dst->rep_.append(src->rep_.data() + kHeader, src->rep_.size() - kHeader); +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/db/write_batch_internal.h b/ios/Pods/leveldb-library/db/write_batch_internal.h new file mode 100644 index 00000000..9448ef7b --- /dev/null +++ b/ios/Pods/leveldb-library/db/write_batch_internal.h @@ -0,0 +1,50 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_DB_WRITE_BATCH_INTERNAL_H_ +#define STORAGE_LEVELDB_DB_WRITE_BATCH_INTERNAL_H_ + +#include "db/dbformat.h" +#include "leveldb/write_batch.h" + +namespace leveldb { + +class MemTable; + +// WriteBatchInternal provides static methods for manipulating a +// WriteBatch that we don't want in the public WriteBatch interface. +class WriteBatchInternal { + public: + // Return the number of entries in the batch. + static int Count(const WriteBatch* batch); + + // Set the count for the number of entries in the batch. + static void SetCount(WriteBatch* batch, int n); + + // Return the sequence number for the start of this batch. + static SequenceNumber Sequence(const WriteBatch* batch); + + // Store the specified number as the sequence number for the start of + // this batch. + static void SetSequence(WriteBatch* batch, SequenceNumber seq); + + static Slice Contents(const WriteBatch* batch) { + return Slice(batch->rep_); + } + + static size_t ByteSize(const WriteBatch* batch) { + return batch->rep_.size(); + } + + static void SetContents(WriteBatch* batch, const Slice& contents); + + static Status InsertInto(const WriteBatch* batch, MemTable* memtable); + + static void Append(WriteBatch* dst, const WriteBatch* src); +}; + +} // namespace leveldb + + +#endif // STORAGE_LEVELDB_DB_WRITE_BATCH_INTERNAL_H_ diff --git a/ios/Pods/leveldb-library/include/leveldb/c.h b/ios/Pods/leveldb-library/include/leveldb/c.h new file mode 100644 index 00000000..1048fe3b --- /dev/null +++ b/ios/Pods/leveldb-library/include/leveldb/c.h @@ -0,0 +1,290 @@ +/* Copyright (c) 2011 The LevelDB Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. See the AUTHORS file for names of contributors. + + C bindings for leveldb. May be useful as a stable ABI that can be + used by programs that keep leveldb in a shared library, or for + a JNI api. + + Does not support: + . getters for the option types + . custom comparators that implement key shortening + . custom iter, db, env, cache implementations using just the C bindings + + Some conventions: + + (1) We expose just opaque struct pointers and functions to clients. + This allows us to change internal representations without having to + recompile clients. + + (2) For simplicity, there is no equivalent to the Slice type. Instead, + the caller has to pass the pointer and length as separate + arguments. + + (3) Errors are represented by a null-terminated c string. NULL + means no error. All operations that can raise an error are passed + a "char** errptr" as the last argument. One of the following must + be true on entry: + *errptr == NULL + *errptr points to a malloc()ed null-terminated error message + (On Windows, *errptr must have been malloc()-ed by this library.) + On success, a leveldb routine leaves *errptr unchanged. + On failure, leveldb frees the old value of *errptr and + set *errptr to a malloc()ed error message. + + (4) Bools have the type unsigned char (0 == false; rest == true) + + (5) All of the pointer arguments must be non-NULL. +*/ + +#ifndef STORAGE_LEVELDB_INCLUDE_C_H_ +#define STORAGE_LEVELDB_INCLUDE_C_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* Exported types */ + +typedef struct leveldb_t leveldb_t; +typedef struct leveldb_cache_t leveldb_cache_t; +typedef struct leveldb_comparator_t leveldb_comparator_t; +typedef struct leveldb_env_t leveldb_env_t; +typedef struct leveldb_filelock_t leveldb_filelock_t; +typedef struct leveldb_filterpolicy_t leveldb_filterpolicy_t; +typedef struct leveldb_iterator_t leveldb_iterator_t; +typedef struct leveldb_logger_t leveldb_logger_t; +typedef struct leveldb_options_t leveldb_options_t; +typedef struct leveldb_randomfile_t leveldb_randomfile_t; +typedef struct leveldb_readoptions_t leveldb_readoptions_t; +typedef struct leveldb_seqfile_t leveldb_seqfile_t; +typedef struct leveldb_snapshot_t leveldb_snapshot_t; +typedef struct leveldb_writablefile_t leveldb_writablefile_t; +typedef struct leveldb_writebatch_t leveldb_writebatch_t; +typedef struct leveldb_writeoptions_t leveldb_writeoptions_t; + +/* DB operations */ + +extern leveldb_t* leveldb_open( + const leveldb_options_t* options, + const char* name, + char** errptr); + +extern void leveldb_close(leveldb_t* db); + +extern void leveldb_put( + leveldb_t* db, + const leveldb_writeoptions_t* options, + const char* key, size_t keylen, + const char* val, size_t vallen, + char** errptr); + +extern void leveldb_delete( + leveldb_t* db, + const leveldb_writeoptions_t* options, + const char* key, size_t keylen, + char** errptr); + +extern void leveldb_write( + leveldb_t* db, + const leveldb_writeoptions_t* options, + leveldb_writebatch_t* batch, + char** errptr); + +/* Returns NULL if not found. A malloc()ed array otherwise. + Stores the length of the array in *vallen. */ +extern char* leveldb_get( + leveldb_t* db, + const leveldb_readoptions_t* options, + const char* key, size_t keylen, + size_t* vallen, + char** errptr); + +extern leveldb_iterator_t* leveldb_create_iterator( + leveldb_t* db, + const leveldb_readoptions_t* options); + +extern const leveldb_snapshot_t* leveldb_create_snapshot( + leveldb_t* db); + +extern void leveldb_release_snapshot( + leveldb_t* db, + const leveldb_snapshot_t* snapshot); + +/* Returns NULL if property name is unknown. + Else returns a pointer to a malloc()-ed null-terminated value. */ +extern char* leveldb_property_value( + leveldb_t* db, + const char* propname); + +extern void leveldb_approximate_sizes( + leveldb_t* db, + int num_ranges, + const char* const* range_start_key, const size_t* range_start_key_len, + const char* const* range_limit_key, const size_t* range_limit_key_len, + uint64_t* sizes); + +extern void leveldb_compact_range( + leveldb_t* db, + const char* start_key, size_t start_key_len, + const char* limit_key, size_t limit_key_len); + +/* Management operations */ + +extern void leveldb_destroy_db( + const leveldb_options_t* options, + const char* name, + char** errptr); + +extern void leveldb_repair_db( + const leveldb_options_t* options, + const char* name, + char** errptr); + +/* Iterator */ + +extern void leveldb_iter_destroy(leveldb_iterator_t*); +extern unsigned char leveldb_iter_valid(const leveldb_iterator_t*); +extern void leveldb_iter_seek_to_first(leveldb_iterator_t*); +extern void leveldb_iter_seek_to_last(leveldb_iterator_t*); +extern void leveldb_iter_seek(leveldb_iterator_t*, const char* k, size_t klen); +extern void leveldb_iter_next(leveldb_iterator_t*); +extern void leveldb_iter_prev(leveldb_iterator_t*); +extern const char* leveldb_iter_key(const leveldb_iterator_t*, size_t* klen); +extern const char* leveldb_iter_value(const leveldb_iterator_t*, size_t* vlen); +extern void leveldb_iter_get_error(const leveldb_iterator_t*, char** errptr); + +/* Write batch */ + +extern leveldb_writebatch_t* leveldb_writebatch_create(); +extern void leveldb_writebatch_destroy(leveldb_writebatch_t*); +extern void leveldb_writebatch_clear(leveldb_writebatch_t*); +extern void leveldb_writebatch_put( + leveldb_writebatch_t*, + const char* key, size_t klen, + const char* val, size_t vlen); +extern void leveldb_writebatch_delete( + leveldb_writebatch_t*, + const char* key, size_t klen); +extern void leveldb_writebatch_iterate( + leveldb_writebatch_t*, + void* state, + void (*put)(void*, const char* k, size_t klen, const char* v, size_t vlen), + void (*deleted)(void*, const char* k, size_t klen)); + +/* Options */ + +extern leveldb_options_t* leveldb_options_create(); +extern void leveldb_options_destroy(leveldb_options_t*); +extern void leveldb_options_set_comparator( + leveldb_options_t*, + leveldb_comparator_t*); +extern void leveldb_options_set_filter_policy( + leveldb_options_t*, + leveldb_filterpolicy_t*); +extern void leveldb_options_set_create_if_missing( + leveldb_options_t*, unsigned char); +extern void leveldb_options_set_error_if_exists( + leveldb_options_t*, unsigned char); +extern void leveldb_options_set_paranoid_checks( + leveldb_options_t*, unsigned char); +extern void leveldb_options_set_env(leveldb_options_t*, leveldb_env_t*); +extern void leveldb_options_set_info_log(leveldb_options_t*, leveldb_logger_t*); +extern void leveldb_options_set_write_buffer_size(leveldb_options_t*, size_t); +extern void leveldb_options_set_max_open_files(leveldb_options_t*, int); +extern void leveldb_options_set_cache(leveldb_options_t*, leveldb_cache_t*); +extern void leveldb_options_set_block_size(leveldb_options_t*, size_t); +extern void leveldb_options_set_block_restart_interval(leveldb_options_t*, int); + +enum { + leveldb_no_compression = 0, + leveldb_snappy_compression = 1 +}; +extern void leveldb_options_set_compression(leveldb_options_t*, int); + +/* Comparator */ + +extern leveldb_comparator_t* leveldb_comparator_create( + void* state, + void (*destructor)(void*), + int (*compare)( + void*, + const char* a, size_t alen, + const char* b, size_t blen), + const char* (*name)(void*)); +extern void leveldb_comparator_destroy(leveldb_comparator_t*); + +/* Filter policy */ + +extern leveldb_filterpolicy_t* leveldb_filterpolicy_create( + void* state, + void (*destructor)(void*), + char* (*create_filter)( + void*, + const char* const* key_array, const size_t* key_length_array, + int num_keys, + size_t* filter_length), + unsigned char (*key_may_match)( + void*, + const char* key, size_t length, + const char* filter, size_t filter_length), + const char* (*name)(void*)); +extern void leveldb_filterpolicy_destroy(leveldb_filterpolicy_t*); + +extern leveldb_filterpolicy_t* leveldb_filterpolicy_create_bloom( + int bits_per_key); + +/* Read options */ + +extern leveldb_readoptions_t* leveldb_readoptions_create(); +extern void leveldb_readoptions_destroy(leveldb_readoptions_t*); +extern void leveldb_readoptions_set_verify_checksums( + leveldb_readoptions_t*, + unsigned char); +extern void leveldb_readoptions_set_fill_cache( + leveldb_readoptions_t*, unsigned char); +extern void leveldb_readoptions_set_snapshot( + leveldb_readoptions_t*, + const leveldb_snapshot_t*); + +/* Write options */ + +extern leveldb_writeoptions_t* leveldb_writeoptions_create(); +extern void leveldb_writeoptions_destroy(leveldb_writeoptions_t*); +extern void leveldb_writeoptions_set_sync( + leveldb_writeoptions_t*, unsigned char); + +/* Cache */ + +extern leveldb_cache_t* leveldb_cache_create_lru(size_t capacity); +extern void leveldb_cache_destroy(leveldb_cache_t* cache); + +/* Env */ + +extern leveldb_env_t* leveldb_create_default_env(); +extern void leveldb_env_destroy(leveldb_env_t*); + +/* Utility */ + +/* Calls free(ptr). + REQUIRES: ptr was malloc()-ed and returned by one of the routines + in this file. Note that in certain cases (typically on Windows), you + may need to call this routine instead of free(ptr) to dispose of + malloc()-ed memory returned by this library. */ +extern void leveldb_free(void* ptr); + +/* Return the major version number for this release. */ +extern int leveldb_major_version(); + +/* Return the minor version number for this release. */ +extern int leveldb_minor_version(); + +#ifdef __cplusplus +} /* end extern "C" */ +#endif + +#endif /* STORAGE_LEVELDB_INCLUDE_C_H_ */ diff --git a/ios/Pods/leveldb-library/include/leveldb/cache.h b/ios/Pods/leveldb-library/include/leveldb/cache.h new file mode 100644 index 00000000..6819d5bc --- /dev/null +++ b/ios/Pods/leveldb-library/include/leveldb/cache.h @@ -0,0 +1,110 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// A Cache is an interface that maps keys to values. It has internal +// synchronization and may be safely accessed concurrently from +// multiple threads. It may automatically evict entries to make room +// for new entries. Values have a specified charge against the cache +// capacity. For example, a cache where the values are variable +// length strings, may use the length of the string as the charge for +// the string. +// +// A builtin cache implementation with a least-recently-used eviction +// policy is provided. Clients may use their own implementations if +// they want something more sophisticated (like scan-resistance, a +// custom eviction policy, variable cache sizing, etc.) + +#ifndef STORAGE_LEVELDB_INCLUDE_CACHE_H_ +#define STORAGE_LEVELDB_INCLUDE_CACHE_H_ + +#include +#include "leveldb/slice.h" + +namespace leveldb { + +class Cache; + +// Create a new cache with a fixed size capacity. This implementation +// of Cache uses a least-recently-used eviction policy. +extern Cache* NewLRUCache(size_t capacity); + +class Cache { + public: + Cache() { } + + // Destroys all existing entries by calling the "deleter" + // function that was passed to the constructor. + virtual ~Cache(); + + // Opaque handle to an entry stored in the cache. + struct Handle { }; + + // Insert a mapping from key->value into the cache and assign it + // the specified charge against the total cache capacity. + // + // Returns a handle that corresponds to the mapping. The caller + // must call this->Release(handle) when the returned mapping is no + // longer needed. + // + // When the inserted entry is no longer needed, the key and + // value will be passed to "deleter". + virtual Handle* Insert(const Slice& key, void* value, size_t charge, + void (*deleter)(const Slice& key, void* value)) = 0; + + // If the cache has no mapping for "key", returns NULL. + // + // Else return a handle that corresponds to the mapping. The caller + // must call this->Release(handle) when the returned mapping is no + // longer needed. + virtual Handle* Lookup(const Slice& key) = 0; + + // Release a mapping returned by a previous Lookup(). + // REQUIRES: handle must not have been released yet. + // REQUIRES: handle must have been returned by a method on *this. + virtual void Release(Handle* handle) = 0; + + // Return the value encapsulated in a handle returned by a + // successful Lookup(). + // REQUIRES: handle must not have been released yet. + // REQUIRES: handle must have been returned by a method on *this. + virtual void* Value(Handle* handle) = 0; + + // If the cache contains entry for key, erase it. Note that the + // underlying entry will be kept around until all existing handles + // to it have been released. + virtual void Erase(const Slice& key) = 0; + + // Return a new numeric id. May be used by multiple clients who are + // sharing the same cache to partition the key space. Typically the + // client will allocate a new id at startup and prepend the id to + // its cache keys. + virtual uint64_t NewId() = 0; + + // Remove all cache entries that are not actively in use. Memory-constrained + // applications may wish to call this method to reduce memory usage. + // Default implementation of Prune() does nothing. Subclasses are strongly + // encouraged to override the default implementation. A future release of + // leveldb may change Prune() to a pure abstract method. + virtual void Prune() {} + + // Return an estimate of the combined charges of all elements stored in the + // cache. + virtual size_t TotalCharge() const = 0; + + private: + void LRU_Remove(Handle* e); + void LRU_Append(Handle* e); + void Unref(Handle* e); + + struct Rep; + Rep* rep_; + + // No copying allowed + Cache(const Cache&); + void operator=(const Cache&); +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_CACHE_H_ diff --git a/ios/Pods/leveldb-library/include/leveldb/comparator.h b/ios/Pods/leveldb-library/include/leveldb/comparator.h new file mode 100644 index 00000000..556b984c --- /dev/null +++ b/ios/Pods/leveldb-library/include/leveldb/comparator.h @@ -0,0 +1,63 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_INCLUDE_COMPARATOR_H_ +#define STORAGE_LEVELDB_INCLUDE_COMPARATOR_H_ + +#include + +namespace leveldb { + +class Slice; + +// A Comparator object provides a total order across slices that are +// used as keys in an sstable or a database. A Comparator implementation +// must be thread-safe since leveldb may invoke its methods concurrently +// from multiple threads. +class Comparator { + public: + virtual ~Comparator(); + + // Three-way comparison. Returns value: + // < 0 iff "a" < "b", + // == 0 iff "a" == "b", + // > 0 iff "a" > "b" + virtual int Compare(const Slice& a, const Slice& b) const = 0; + + // The name of the comparator. Used to check for comparator + // mismatches (i.e., a DB created with one comparator is + // accessed using a different comparator. + // + // The client of this package should switch to a new name whenever + // the comparator implementation changes in a way that will cause + // the relative ordering of any two keys to change. + // + // Names starting with "leveldb." are reserved and should not be used + // by any clients of this package. + virtual const char* Name() const = 0; + + // Advanced functions: these are used to reduce the space requirements + // for internal data structures like index blocks. + + // If *start < limit, changes *start to a short string in [start,limit). + // Simple comparator implementations may return with *start unchanged, + // i.e., an implementation of this method that does nothing is correct. + virtual void FindShortestSeparator( + std::string* start, + const Slice& limit) const = 0; + + // Changes *key to a short string >= *key. + // Simple comparator implementations may return with *key unchanged, + // i.e., an implementation of this method that does nothing is correct. + virtual void FindShortSuccessor(std::string* key) const = 0; +}; + +// Return a builtin comparator that uses lexicographic byte-wise +// ordering. The result remains the property of this module and +// must not be deleted. +extern const Comparator* BytewiseComparator(); + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_COMPARATOR_H_ diff --git a/ios/Pods/leveldb-library/include/leveldb/db.h b/ios/Pods/leveldb-library/include/leveldb/db.h new file mode 100644 index 00000000..bfab10a0 --- /dev/null +++ b/ios/Pods/leveldb-library/include/leveldb/db.h @@ -0,0 +1,163 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_INCLUDE_DB_H_ +#define STORAGE_LEVELDB_INCLUDE_DB_H_ + +#include +#include +#include "leveldb/iterator.h" +#include "leveldb/options.h" + +namespace leveldb { + +// Update Makefile if you change these +static const int kMajorVersion = 1; +static const int kMinorVersion = 20; + +struct Options; +struct ReadOptions; +struct WriteOptions; +class WriteBatch; + +// Abstract handle to particular state of a DB. +// A Snapshot is an immutable object and can therefore be safely +// accessed from multiple threads without any external synchronization. +class Snapshot { + protected: + virtual ~Snapshot(); +}; + +// A range of keys +struct Range { + Slice start; // Included in the range + Slice limit; // Not included in the range + + Range() { } + Range(const Slice& s, const Slice& l) : start(s), limit(l) { } +}; + +// A DB is a persistent ordered map from keys to values. +// A DB is safe for concurrent access from multiple threads without +// any external synchronization. +class DB { + public: + // Open the database with the specified "name". + // Stores a pointer to a heap-allocated database in *dbptr and returns + // OK on success. + // Stores NULL in *dbptr and returns a non-OK status on error. + // Caller should delete *dbptr when it is no longer needed. + static Status Open(const Options& options, + const std::string& name, + DB** dbptr); + + DB() { } + virtual ~DB(); + + // Set the database entry for "key" to "value". Returns OK on success, + // and a non-OK status on error. + // Note: consider setting options.sync = true. + virtual Status Put(const WriteOptions& options, + const Slice& key, + const Slice& value) = 0; + + // Remove the database entry (if any) for "key". Returns OK on + // success, and a non-OK status on error. It is not an error if "key" + // did not exist in the database. + // Note: consider setting options.sync = true. + virtual Status Delete(const WriteOptions& options, const Slice& key) = 0; + + // Apply the specified updates to the database. + // Returns OK on success, non-OK on failure. + // Note: consider setting options.sync = true. + virtual Status Write(const WriteOptions& options, WriteBatch* updates) = 0; + + // If the database contains an entry for "key" store the + // corresponding value in *value and return OK. + // + // If there is no entry for "key" leave *value unchanged and return + // a status for which Status::IsNotFound() returns true. + // + // May return some other Status on an error. + virtual Status Get(const ReadOptions& options, + const Slice& key, std::string* value) = 0; + + // Return a heap-allocated iterator over the contents of the database. + // The result of NewIterator() is initially invalid (caller must + // call one of the Seek methods on the iterator before using it). + // + // Caller should delete the iterator when it is no longer needed. + // The returned iterator should be deleted before this db is deleted. + virtual Iterator* NewIterator(const ReadOptions& options) = 0; + + // Return a handle to the current DB state. Iterators created with + // this handle will all observe a stable snapshot of the current DB + // state. The caller must call ReleaseSnapshot(result) when the + // snapshot is no longer needed. + virtual const Snapshot* GetSnapshot() = 0; + + // Release a previously acquired snapshot. The caller must not + // use "snapshot" after this call. + virtual void ReleaseSnapshot(const Snapshot* snapshot) = 0; + + // DB implementations can export properties about their state + // via this method. If "property" is a valid property understood by this + // DB implementation, fills "*value" with its current value and returns + // true. Otherwise returns false. + // + // + // Valid property names include: + // + // "leveldb.num-files-at-level" - return the number of files at level , + // where is an ASCII representation of a level number (e.g. "0"). + // "leveldb.stats" - returns a multi-line string that describes statistics + // about the internal operation of the DB. + // "leveldb.sstables" - returns a multi-line string that describes all + // of the sstables that make up the db contents. + // "leveldb.approximate-memory-usage" - returns the approximate number of + // bytes of memory in use by the DB. + virtual bool GetProperty(const Slice& property, std::string* value) = 0; + + // For each i in [0,n-1], store in "sizes[i]", the approximate + // file system space used by keys in "[range[i].start .. range[i].limit)". + // + // Note that the returned sizes measure file system space usage, so + // if the user data compresses by a factor of ten, the returned + // sizes will be one-tenth the size of the corresponding user data size. + // + // The results may not include the sizes of recently written data. + virtual void GetApproximateSizes(const Range* range, int n, + uint64_t* sizes) = 0; + + // Compact the underlying storage for the key range [*begin,*end]. + // In particular, deleted and overwritten versions are discarded, + // and the data is rearranged to reduce the cost of operations + // needed to access the data. This operation should typically only + // be invoked by users who understand the underlying implementation. + // + // begin==NULL is treated as a key before all keys in the database. + // end==NULL is treated as a key after all keys in the database. + // Therefore the following call will compact the entire database: + // db->CompactRange(NULL, NULL); + virtual void CompactRange(const Slice* begin, const Slice* end) = 0; + + private: + // No copying allowed + DB(const DB&); + void operator=(const DB&); +}; + +// Destroy the contents of the specified database. +// Be very careful using this method. +Status DestroyDB(const std::string& name, const Options& options); + +// If a DB cannot be opened, you may attempt to call this method to +// resurrect as much of the contents of the database as possible. +// Some data may be lost, so be careful when calling this function +// on a database that contains important information. +Status RepairDB(const std::string& dbname, const Options& options); + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_DB_H_ diff --git a/ios/Pods/leveldb-library/include/leveldb/dumpfile.h b/ios/Pods/leveldb-library/include/leveldb/dumpfile.h new file mode 100644 index 00000000..3f97fda1 --- /dev/null +++ b/ios/Pods/leveldb-library/include/leveldb/dumpfile.h @@ -0,0 +1,25 @@ +// Copyright (c) 2014 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_INCLUDE_DUMPFILE_H_ +#define STORAGE_LEVELDB_INCLUDE_DUMPFILE_H_ + +#include +#include "leveldb/env.h" +#include "leveldb/status.h" + +namespace leveldb { + +// Dump the contents of the file named by fname in text format to +// *dst. Makes a sequence of dst->Append() calls; each call is passed +// the newline-terminated text corresponding to a single item found +// in the file. +// +// Returns a non-OK result if fname does not name a leveldb storage +// file, or if the file cannot be read. +Status DumpFile(Env* env, const std::string& fname, WritableFile* dst); + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_DUMPFILE_H_ diff --git a/ios/Pods/leveldb-library/include/leveldb/env.h b/ios/Pods/leveldb-library/include/leveldb/env.h new file mode 100644 index 00000000..99b6c214 --- /dev/null +++ b/ios/Pods/leveldb-library/include/leveldb/env.h @@ -0,0 +1,351 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// An Env is an interface used by the leveldb implementation to access +// operating system functionality like the filesystem etc. Callers +// may wish to provide a custom Env object when opening a database to +// get fine gain control; e.g., to rate limit file system operations. +// +// All Env implementations are safe for concurrent access from +// multiple threads without any external synchronization. + +#ifndef STORAGE_LEVELDB_INCLUDE_ENV_H_ +#define STORAGE_LEVELDB_INCLUDE_ENV_H_ + +#include +#include +#include +#include +#include "leveldb/status.h" + +namespace leveldb { + +class FileLock; +class Logger; +class RandomAccessFile; +class SequentialFile; +class Slice; +class WritableFile; + +class Env { + public: + Env() { } + virtual ~Env(); + + // Return a default environment suitable for the current operating + // system. Sophisticated users may wish to provide their own Env + // implementation instead of relying on this default environment. + // + // The result of Default() belongs to leveldb and must never be deleted. + static Env* Default(); + + // Create a brand new sequentially-readable file with the specified name. + // On success, stores a pointer to the new file in *result and returns OK. + // On failure stores NULL in *result and returns non-OK. If the file does + // not exist, returns a non-OK status. + // + // The returned file will only be accessed by one thread at a time. + virtual Status NewSequentialFile(const std::string& fname, + SequentialFile** result) = 0; + + // Create a brand new random access read-only file with the + // specified name. On success, stores a pointer to the new file in + // *result and returns OK. On failure stores NULL in *result and + // returns non-OK. If the file does not exist, returns a non-OK + // status. + // + // The returned file may be concurrently accessed by multiple threads. + virtual Status NewRandomAccessFile(const std::string& fname, + RandomAccessFile** result) = 0; + + // Create an object that writes to a new file with the specified + // name. Deletes any existing file with the same name and creates a + // new file. On success, stores a pointer to the new file in + // *result and returns OK. On failure stores NULL in *result and + // returns non-OK. + // + // The returned file will only be accessed by one thread at a time. + virtual Status NewWritableFile(const std::string& fname, + WritableFile** result) = 0; + + // Create an object that either appends to an existing file, or + // writes to a new file (if the file does not exist to begin with). + // On success, stores a pointer to the new file in *result and + // returns OK. On failure stores NULL in *result and returns + // non-OK. + // + // The returned file will only be accessed by one thread at a time. + // + // May return an IsNotSupportedError error if this Env does + // not allow appending to an existing file. Users of Env (including + // the leveldb implementation) must be prepared to deal with + // an Env that does not support appending. + virtual Status NewAppendableFile(const std::string& fname, + WritableFile** result); + + // Returns true iff the named file exists. + virtual bool FileExists(const std::string& fname) = 0; + + // Store in *result the names of the children of the specified directory. + // The names are relative to "dir". + // Original contents of *results are dropped. + virtual Status GetChildren(const std::string& dir, + std::vector* result) = 0; + + // Delete the named file. + virtual Status DeleteFile(const std::string& fname) = 0; + + // Create the specified directory. + virtual Status CreateDir(const std::string& dirname) = 0; + + // Delete the specified directory. + virtual Status DeleteDir(const std::string& dirname) = 0; + + // Store the size of fname in *file_size. + virtual Status GetFileSize(const std::string& fname, uint64_t* file_size) = 0; + + // Rename file src to target. + virtual Status RenameFile(const std::string& src, + const std::string& target) = 0; + + // Lock the specified file. Used to prevent concurrent access to + // the same db by multiple processes. On failure, stores NULL in + // *lock and returns non-OK. + // + // On success, stores a pointer to the object that represents the + // acquired lock in *lock and returns OK. The caller should call + // UnlockFile(*lock) to release the lock. If the process exits, + // the lock will be automatically released. + // + // If somebody else already holds the lock, finishes immediately + // with a failure. I.e., this call does not wait for existing locks + // to go away. + // + // May create the named file if it does not already exist. + virtual Status LockFile(const std::string& fname, FileLock** lock) = 0; + + // Release the lock acquired by a previous successful call to LockFile. + // REQUIRES: lock was returned by a successful LockFile() call + // REQUIRES: lock has not already been unlocked. + virtual Status UnlockFile(FileLock* lock) = 0; + + // Arrange to run "(*function)(arg)" once in a background thread. + // + // "function" may run in an unspecified thread. Multiple functions + // added to the same Env may run concurrently in different threads. + // I.e., the caller may not assume that background work items are + // serialized. + virtual void Schedule( + void (*function)(void* arg), + void* arg) = 0; + + // Start a new thread, invoking "function(arg)" within the new thread. + // When "function(arg)" returns, the thread will be destroyed. + virtual void StartThread(void (*function)(void* arg), void* arg) = 0; + + // *path is set to a temporary directory that can be used for testing. It may + // or many not have just been created. The directory may or may not differ + // between runs of the same process, but subsequent calls will return the + // same directory. + virtual Status GetTestDirectory(std::string* path) = 0; + + // Create and return a log file for storing informational messages. + virtual Status NewLogger(const std::string& fname, Logger** result) = 0; + + // Returns the number of micro-seconds since some fixed point in time. Only + // useful for computing deltas of time. + virtual uint64_t NowMicros() = 0; + + // Sleep/delay the thread for the prescribed number of micro-seconds. + virtual void SleepForMicroseconds(int micros) = 0; + + private: + // No copying allowed + Env(const Env&); + void operator=(const Env&); +}; + +// A file abstraction for reading sequentially through a file +class SequentialFile { + public: + SequentialFile() { } + virtual ~SequentialFile(); + + // Read up to "n" bytes from the file. "scratch[0..n-1]" may be + // written by this routine. Sets "*result" to the data that was + // read (including if fewer than "n" bytes were successfully read). + // May set "*result" to point at data in "scratch[0..n-1]", so + // "scratch[0..n-1]" must be live when "*result" is used. + // If an error was encountered, returns a non-OK status. + // + // REQUIRES: External synchronization + virtual Status Read(size_t n, Slice* result, char* scratch) = 0; + + // Skip "n" bytes from the file. This is guaranteed to be no + // slower that reading the same data, but may be faster. + // + // If end of file is reached, skipping will stop at the end of the + // file, and Skip will return OK. + // + // REQUIRES: External synchronization + virtual Status Skip(uint64_t n) = 0; + + private: + // No copying allowed + SequentialFile(const SequentialFile&); + void operator=(const SequentialFile&); +}; + +// A file abstraction for randomly reading the contents of a file. +class RandomAccessFile { + public: + RandomAccessFile() { } + virtual ~RandomAccessFile(); + + // Read up to "n" bytes from the file starting at "offset". + // "scratch[0..n-1]" may be written by this routine. Sets "*result" + // to the data that was read (including if fewer than "n" bytes were + // successfully read). May set "*result" to point at data in + // "scratch[0..n-1]", so "scratch[0..n-1]" must be live when + // "*result" is used. If an error was encountered, returns a non-OK + // status. + // + // Safe for concurrent use by multiple threads. + virtual Status Read(uint64_t offset, size_t n, Slice* result, + char* scratch) const = 0; + + private: + // No copying allowed + RandomAccessFile(const RandomAccessFile&); + void operator=(const RandomAccessFile&); +}; + +// A file abstraction for sequential writing. The implementation +// must provide buffering since callers may append small fragments +// at a time to the file. +class WritableFile { + public: + WritableFile() { } + virtual ~WritableFile(); + + virtual Status Append(const Slice& data) = 0; + virtual Status Close() = 0; + virtual Status Flush() = 0; + virtual Status Sync() = 0; + + private: + // No copying allowed + WritableFile(const WritableFile&); + void operator=(const WritableFile&); +}; + +// An interface for writing log messages. +class Logger { + public: + Logger() { } + virtual ~Logger(); + + // Write an entry to the log file with the specified format. + virtual void Logv(const char* format, va_list ap) = 0; + + private: + // No copying allowed + Logger(const Logger&); + void operator=(const Logger&); +}; + + +// Identifies a locked file. +class FileLock { + public: + FileLock() { } + virtual ~FileLock(); + private: + // No copying allowed + FileLock(const FileLock&); + void operator=(const FileLock&); +}; + +// Log the specified data to *info_log if info_log is non-NULL. +extern void Log(Logger* info_log, const char* format, ...) +# if defined(__GNUC__) || defined(__clang__) + __attribute__((__format__ (__printf__, 2, 3))) +# endif + ; + +// A utility routine: write "data" to the named file. +extern Status WriteStringToFile(Env* env, const Slice& data, + const std::string& fname); + +// A utility routine: read contents of named file into *data +extern Status ReadFileToString(Env* env, const std::string& fname, + std::string* data); + +// An implementation of Env that forwards all calls to another Env. +// May be useful to clients who wish to override just part of the +// functionality of another Env. +class EnvWrapper : public Env { + public: + // Initialize an EnvWrapper that delegates all calls to *t + explicit EnvWrapper(Env* t) : target_(t) { } + virtual ~EnvWrapper(); + + // Return the target to which this Env forwards all calls + Env* target() const { return target_; } + + // The following text is boilerplate that forwards all methods to target() + Status NewSequentialFile(const std::string& f, SequentialFile** r) { + return target_->NewSequentialFile(f, r); + } + Status NewRandomAccessFile(const std::string& f, RandomAccessFile** r) { + return target_->NewRandomAccessFile(f, r); + } + Status NewWritableFile(const std::string& f, WritableFile** r) { + return target_->NewWritableFile(f, r); + } + Status NewAppendableFile(const std::string& f, WritableFile** r) { + return target_->NewAppendableFile(f, r); + } + bool FileExists(const std::string& f) { return target_->FileExists(f); } + Status GetChildren(const std::string& dir, std::vector* r) { + return target_->GetChildren(dir, r); + } + Status DeleteFile(const std::string& f) { return target_->DeleteFile(f); } + Status CreateDir(const std::string& d) { return target_->CreateDir(d); } + Status DeleteDir(const std::string& d) { return target_->DeleteDir(d); } + Status GetFileSize(const std::string& f, uint64_t* s) { + return target_->GetFileSize(f, s); + } + Status RenameFile(const std::string& s, const std::string& t) { + return target_->RenameFile(s, t); + } + Status LockFile(const std::string& f, FileLock** l) { + return target_->LockFile(f, l); + } + Status UnlockFile(FileLock* l) { return target_->UnlockFile(l); } + void Schedule(void (*f)(void*), void* a) { + return target_->Schedule(f, a); + } + void StartThread(void (*f)(void*), void* a) { + return target_->StartThread(f, a); + } + virtual Status GetTestDirectory(std::string* path) { + return target_->GetTestDirectory(path); + } + virtual Status NewLogger(const std::string& fname, Logger** result) { + return target_->NewLogger(fname, result); + } + uint64_t NowMicros() { + return target_->NowMicros(); + } + void SleepForMicroseconds(int micros) { + target_->SleepForMicroseconds(micros); + } + private: + Env* target_; +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_ENV_H_ diff --git a/ios/Pods/leveldb-library/include/leveldb/filter_policy.h b/ios/Pods/leveldb-library/include/leveldb/filter_policy.h new file mode 100644 index 00000000..1fba0800 --- /dev/null +++ b/ios/Pods/leveldb-library/include/leveldb/filter_policy.h @@ -0,0 +1,70 @@ +// Copyright (c) 2012 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// A database can be configured with a custom FilterPolicy object. +// This object is responsible for creating a small filter from a set +// of keys. These filters are stored in leveldb and are consulted +// automatically by leveldb to decide whether or not to read some +// information from disk. In many cases, a filter can cut down the +// number of disk seeks form a handful to a single disk seek per +// DB::Get() call. +// +// Most people will want to use the builtin bloom filter support (see +// NewBloomFilterPolicy() below). + +#ifndef STORAGE_LEVELDB_INCLUDE_FILTER_POLICY_H_ +#define STORAGE_LEVELDB_INCLUDE_FILTER_POLICY_H_ + +#include + +namespace leveldb { + +class Slice; + +class FilterPolicy { + public: + virtual ~FilterPolicy(); + + // Return the name of this policy. Note that if the filter encoding + // changes in an incompatible way, the name returned by this method + // must be changed. Otherwise, old incompatible filters may be + // passed to methods of this type. + virtual const char* Name() const = 0; + + // keys[0,n-1] contains a list of keys (potentially with duplicates) + // that are ordered according to the user supplied comparator. + // Append a filter that summarizes keys[0,n-1] to *dst. + // + // Warning: do not change the initial contents of *dst. Instead, + // append the newly constructed filter to *dst. + virtual void CreateFilter(const Slice* keys, int n, std::string* dst) + const = 0; + + // "filter" contains the data appended by a preceding call to + // CreateFilter() on this class. This method must return true if + // the key was in the list of keys passed to CreateFilter(). + // This method may return true or false if the key was not on the + // list, but it should aim to return false with a high probability. + virtual bool KeyMayMatch(const Slice& key, const Slice& filter) const = 0; +}; + +// Return a new filter policy that uses a bloom filter with approximately +// the specified number of bits per key. A good value for bits_per_key +// is 10, which yields a filter with ~ 1% false positive rate. +// +// Callers must delete the result after any database that is using the +// result has been closed. +// +// Note: if you are using a custom comparator that ignores some parts +// of the keys being compared, you must not use NewBloomFilterPolicy() +// and must provide your own FilterPolicy that also ignores the +// corresponding parts of the keys. For example, if the comparator +// ignores trailing spaces, it would be incorrect to use a +// FilterPolicy (like NewBloomFilterPolicy) that does not ignore +// trailing spaces in keys. +extern const FilterPolicy* NewBloomFilterPolicy(int bits_per_key); + +} + +#endif // STORAGE_LEVELDB_INCLUDE_FILTER_POLICY_H_ diff --git a/ios/Pods/leveldb-library/include/leveldb/iterator.h b/ios/Pods/leveldb-library/include/leveldb/iterator.h new file mode 100644 index 00000000..da631ed9 --- /dev/null +++ b/ios/Pods/leveldb-library/include/leveldb/iterator.h @@ -0,0 +1,100 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// An iterator yields a sequence of key/value pairs from a source. +// The following class defines the interface. Multiple implementations +// are provided by this library. In particular, iterators are provided +// to access the contents of a Table or a DB. +// +// Multiple threads can invoke const methods on an Iterator without +// external synchronization, but if any of the threads may call a +// non-const method, all threads accessing the same Iterator must use +// external synchronization. + +#ifndef STORAGE_LEVELDB_INCLUDE_ITERATOR_H_ +#define STORAGE_LEVELDB_INCLUDE_ITERATOR_H_ + +#include "leveldb/slice.h" +#include "leveldb/status.h" + +namespace leveldb { + +class Iterator { + public: + Iterator(); + virtual ~Iterator(); + + // An iterator is either positioned at a key/value pair, or + // not valid. This method returns true iff the iterator is valid. + virtual bool Valid() const = 0; + + // Position at the first key in the source. The iterator is Valid() + // after this call iff the source is not empty. + virtual void SeekToFirst() = 0; + + // Position at the last key in the source. The iterator is + // Valid() after this call iff the source is not empty. + virtual void SeekToLast() = 0; + + // Position at the first key in the source that is at or past target. + // The iterator is Valid() after this call iff the source contains + // an entry that comes at or past target. + virtual void Seek(const Slice& target) = 0; + + // Moves to the next entry in the source. After this call, Valid() is + // true iff the iterator was not positioned at the last entry in the source. + // REQUIRES: Valid() + virtual void Next() = 0; + + // Moves to the previous entry in the source. After this call, Valid() is + // true iff the iterator was not positioned at the first entry in source. + // REQUIRES: Valid() + virtual void Prev() = 0; + + // Return the key for the current entry. The underlying storage for + // the returned slice is valid only until the next modification of + // the iterator. + // REQUIRES: Valid() + virtual Slice key() const = 0; + + // Return the value for the current entry. The underlying storage for + // the returned slice is valid only until the next modification of + // the iterator. + // REQUIRES: Valid() + virtual Slice value() const = 0; + + // If an error has occurred, return it. Else return an ok status. + virtual Status status() const = 0; + + // Clients are allowed to register function/arg1/arg2 triples that + // will be invoked when this iterator is destroyed. + // + // Note that unlike all of the preceding methods, this method is + // not abstract and therefore clients should not override it. + typedef void (*CleanupFunction)(void* arg1, void* arg2); + void RegisterCleanup(CleanupFunction function, void* arg1, void* arg2); + + private: + struct Cleanup { + CleanupFunction function; + void* arg1; + void* arg2; + Cleanup* next; + }; + Cleanup cleanup_; + + // No copying allowed + Iterator(const Iterator&); + void operator=(const Iterator&); +}; + +// Return an empty iterator (yields nothing). +extern Iterator* NewEmptyIterator(); + +// Return an empty iterator with the specified status. +extern Iterator* NewErrorIterator(const Status& status); + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_ITERATOR_H_ diff --git a/ios/Pods/leveldb-library/include/leveldb/options.h b/ios/Pods/leveldb-library/include/leveldb/options.h new file mode 100644 index 00000000..976e3812 --- /dev/null +++ b/ios/Pods/leveldb-library/include/leveldb/options.h @@ -0,0 +1,213 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_INCLUDE_OPTIONS_H_ +#define STORAGE_LEVELDB_INCLUDE_OPTIONS_H_ + +#include + +namespace leveldb { + +class Cache; +class Comparator; +class Env; +class FilterPolicy; +class Logger; +class Snapshot; + +// DB contents are stored in a set of blocks, each of which holds a +// sequence of key,value pairs. Each block may be compressed before +// being stored in a file. The following enum describes which +// compression method (if any) is used to compress a block. +enum CompressionType { + // NOTE: do not change the values of existing entries, as these are + // part of the persistent format on disk. + kNoCompression = 0x0, + kSnappyCompression = 0x1 +}; + +// Options to control the behavior of a database (passed to DB::Open) +struct Options { + // ------------------- + // Parameters that affect behavior + + // Comparator used to define the order of keys in the table. + // Default: a comparator that uses lexicographic byte-wise ordering + // + // REQUIRES: The client must ensure that the comparator supplied + // here has the same name and orders keys *exactly* the same as the + // comparator provided to previous open calls on the same DB. + const Comparator* comparator; + + // If true, the database will be created if it is missing. + // Default: false + bool create_if_missing; + + // If true, an error is raised if the database already exists. + // Default: false + bool error_if_exists; + + // If true, the implementation will do aggressive checking of the + // data it is processing and will stop early if it detects any + // errors. This may have unforeseen ramifications: for example, a + // corruption of one DB entry may cause a large number of entries to + // become unreadable or for the entire DB to become unopenable. + // Default: false + bool paranoid_checks; + + // Use the specified object to interact with the environment, + // e.g. to read/write files, schedule background work, etc. + // Default: Env::Default() + Env* env; + + // Any internal progress/error information generated by the db will + // be written to info_log if it is non-NULL, or to a file stored + // in the same directory as the DB contents if info_log is NULL. + // Default: NULL + Logger* info_log; + + // ------------------- + // Parameters that affect performance + + // Amount of data to build up in memory (backed by an unsorted log + // on disk) before converting to a sorted on-disk file. + // + // Larger values increase performance, especially during bulk loads. + // Up to two write buffers may be held in memory at the same time, + // so you may wish to adjust this parameter to control memory usage. + // Also, a larger write buffer will result in a longer recovery time + // the next time the database is opened. + // + // Default: 4MB + size_t write_buffer_size; + + // Number of open files that can be used by the DB. You may need to + // increase this if your database has a large working set (budget + // one open file per 2MB of working set). + // + // Default: 1000 + int max_open_files; + + // Control over blocks (user data is stored in a set of blocks, and + // a block is the unit of reading from disk). + + // If non-NULL, use the specified cache for blocks. + // If NULL, leveldb will automatically create and use an 8MB internal cache. + // Default: NULL + Cache* block_cache; + + // Approximate size of user data packed per block. Note that the + // block size specified here corresponds to uncompressed data. The + // actual size of the unit read from disk may be smaller if + // compression is enabled. This parameter can be changed dynamically. + // + // Default: 4K + size_t block_size; + + // Number of keys between restart points for delta encoding of keys. + // This parameter can be changed dynamically. Most clients should + // leave this parameter alone. + // + // Default: 16 + int block_restart_interval; + + // Leveldb will write up to this amount of bytes to a file before + // switching to a new one. + // Most clients should leave this parameter alone. However if your + // filesystem is more efficient with larger files, you could + // consider increasing the value. The downside will be longer + // compactions and hence longer latency/performance hiccups. + // Another reason to increase this parameter might be when you are + // initially populating a large database. + // + // Default: 2MB + size_t max_file_size; + + // Compress blocks using the specified compression algorithm. This + // parameter can be changed dynamically. + // + // Default: kSnappyCompression, which gives lightweight but fast + // compression. + // + // Typical speeds of kSnappyCompression on an Intel(R) Core(TM)2 2.4GHz: + // ~200-500MB/s compression + // ~400-800MB/s decompression + // Note that these speeds are significantly faster than most + // persistent storage speeds, and therefore it is typically never + // worth switching to kNoCompression. Even if the input data is + // incompressible, the kSnappyCompression implementation will + // efficiently detect that and will switch to uncompressed mode. + CompressionType compression; + + // EXPERIMENTAL: If true, append to existing MANIFEST and log files + // when a database is opened. This can significantly speed up open. + // + // Default: currently false, but may become true later. + bool reuse_logs; + + // If non-NULL, use the specified filter policy to reduce disk reads. + // Many applications will benefit from passing the result of + // NewBloomFilterPolicy() here. + // + // Default: NULL + const FilterPolicy* filter_policy; + + // Create an Options object with default values for all fields. + Options(); +}; + +// Options that control read operations +struct ReadOptions { + // If true, all data read from underlying storage will be + // verified against corresponding checksums. + // Default: false + bool verify_checksums; + + // Should the data read for this iteration be cached in memory? + // Callers may wish to set this field to false for bulk scans. + // Default: true + bool fill_cache; + + // If "snapshot" is non-NULL, read as of the supplied snapshot + // (which must belong to the DB that is being read and which must + // not have been released). If "snapshot" is NULL, use an implicit + // snapshot of the state at the beginning of this read operation. + // Default: NULL + const Snapshot* snapshot; + + ReadOptions() + : verify_checksums(false), + fill_cache(true), + snapshot(NULL) { + } +}; + +// Options that control write operations +struct WriteOptions { + // If true, the write will be flushed from the operating system + // buffer cache (by calling WritableFile::Sync()) before the write + // is considered complete. If this flag is true, writes will be + // slower. + // + // If this flag is false, and the machine crashes, some recent + // writes may be lost. Note that if it is just the process that + // crashes (i.e., the machine does not reboot), no writes will be + // lost even if sync==false. + // + // In other words, a DB write with sync==false has similar + // crash semantics as the "write()" system call. A DB write + // with sync==true has similar crash semantics to a "write()" + // system call followed by "fsync()". + // + // Default: false + bool sync; + + WriteOptions() + : sync(false) { + } +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_OPTIONS_H_ diff --git a/ios/Pods/leveldb-library/include/leveldb/slice.h b/ios/Pods/leveldb-library/include/leveldb/slice.h new file mode 100644 index 00000000..bc367986 --- /dev/null +++ b/ios/Pods/leveldb-library/include/leveldb/slice.h @@ -0,0 +1,109 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// Slice is a simple structure containing a pointer into some external +// storage and a size. The user of a Slice must ensure that the slice +// is not used after the corresponding external storage has been +// deallocated. +// +// Multiple threads can invoke const methods on a Slice without +// external synchronization, but if any of the threads may call a +// non-const method, all threads accessing the same Slice must use +// external synchronization. + +#ifndef STORAGE_LEVELDB_INCLUDE_SLICE_H_ +#define STORAGE_LEVELDB_INCLUDE_SLICE_H_ + +#include +#include +#include +#include + +namespace leveldb { + +class Slice { + public: + // Create an empty slice. + Slice() : data_(""), size_(0) { } + + // Create a slice that refers to d[0,n-1]. + Slice(const char* d, size_t n) : data_(d), size_(n) { } + + // Create a slice that refers to the contents of "s" + Slice(const std::string& s) : data_(s.data()), size_(s.size()) { } + + // Create a slice that refers to s[0,strlen(s)-1] + Slice(const char* s) : data_(s), size_(strlen(s)) { } + + // Return a pointer to the beginning of the referenced data + const char* data() const { return data_; } + + // Return the length (in bytes) of the referenced data + size_t size() const { return size_; } + + // Return true iff the length of the referenced data is zero + bool empty() const { return size_ == 0; } + + // Return the ith byte in the referenced data. + // REQUIRES: n < size() + char operator[](size_t n) const { + assert(n < size()); + return data_[n]; + } + + // Change this slice to refer to an empty array + void clear() { data_ = ""; size_ = 0; } + + // Drop the first "n" bytes from this slice. + void remove_prefix(size_t n) { + assert(n <= size()); + data_ += n; + size_ -= n; + } + + // Return a string that contains the copy of the referenced data. + std::string ToString() const { return std::string(data_, size_); } + + // Three-way comparison. Returns value: + // < 0 iff "*this" < "b", + // == 0 iff "*this" == "b", + // > 0 iff "*this" > "b" + int compare(const Slice& b) const; + + // Return true iff "x" is a prefix of "*this" + bool starts_with(const Slice& x) const { + return ((size_ >= x.size_) && + (memcmp(data_, x.data_, x.size_) == 0)); + } + + private: + const char* data_; + size_t size_; + + // Intentionally copyable +}; + +inline bool operator==(const Slice& x, const Slice& y) { + return ((x.size() == y.size()) && + (memcmp(x.data(), y.data(), x.size()) == 0)); +} + +inline bool operator!=(const Slice& x, const Slice& y) { + return !(x == y); +} + +inline int Slice::compare(const Slice& b) const { + const size_t min_len = (size_ < b.size_) ? size_ : b.size_; + int r = memcmp(data_, b.data_, min_len); + if (r == 0) { + if (size_ < b.size_) r = -1; + else if (size_ > b.size_) r = +1; + } + return r; +} + +} // namespace leveldb + + +#endif // STORAGE_LEVELDB_INCLUDE_SLICE_H_ diff --git a/ios/Pods/leveldb-library/include/leveldb/status.h b/ios/Pods/leveldb-library/include/leveldb/status.h new file mode 100644 index 00000000..d9575f97 --- /dev/null +++ b/ios/Pods/leveldb-library/include/leveldb/status.h @@ -0,0 +1,112 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// A Status encapsulates the result of an operation. It may indicate success, +// or it may indicate an error with an associated error message. +// +// Multiple threads can invoke const methods on a Status without +// external synchronization, but if any of the threads may call a +// non-const method, all threads accessing the same Status must use +// external synchronization. + +#ifndef STORAGE_LEVELDB_INCLUDE_STATUS_H_ +#define STORAGE_LEVELDB_INCLUDE_STATUS_H_ + +#include +#include "leveldb/slice.h" + +namespace leveldb { + +class Status { + public: + // Create a success status. + Status() : state_(NULL) { } + ~Status() { delete[] state_; } + + // Copy the specified status. + Status(const Status& s); + void operator=(const Status& s); + + // Return a success status. + static Status OK() { return Status(); } + + // Return error status of an appropriate type. + static Status NotFound(const Slice& msg, const Slice& msg2 = Slice()) { + return Status(kNotFound, msg, msg2); + } + static Status Corruption(const Slice& msg, const Slice& msg2 = Slice()) { + return Status(kCorruption, msg, msg2); + } + static Status NotSupported(const Slice& msg, const Slice& msg2 = Slice()) { + return Status(kNotSupported, msg, msg2); + } + static Status InvalidArgument(const Slice& msg, const Slice& msg2 = Slice()) { + return Status(kInvalidArgument, msg, msg2); + } + static Status IOError(const Slice& msg, const Slice& msg2 = Slice()) { + return Status(kIOError, msg, msg2); + } + + // Returns true iff the status indicates success. + bool ok() const { return (state_ == NULL); } + + // Returns true iff the status indicates a NotFound error. + bool IsNotFound() const { return code() == kNotFound; } + + // Returns true iff the status indicates a Corruption error. + bool IsCorruption() const { return code() == kCorruption; } + + // Returns true iff the status indicates an IOError. + bool IsIOError() const { return code() == kIOError; } + + // Returns true iff the status indicates a NotSupportedError. + bool IsNotSupportedError() const { return code() == kNotSupported; } + + // Returns true iff the status indicates an InvalidArgument. + bool IsInvalidArgument() const { return code() == kInvalidArgument; } + + // Return a string representation of this status suitable for printing. + // Returns the string "OK" for success. + std::string ToString() const; + + private: + // OK status has a NULL state_. Otherwise, state_ is a new[] array + // of the following form: + // state_[0..3] == length of message + // state_[4] == code + // state_[5..] == message + const char* state_; + + enum Code { + kOk = 0, + kNotFound = 1, + kCorruption = 2, + kNotSupported = 3, + kInvalidArgument = 4, + kIOError = 5 + }; + + Code code() const { + return (state_ == NULL) ? kOk : static_cast(state_[4]); + } + + Status(Code code, const Slice& msg, const Slice& msg2); + static const char* CopyState(const char* s); +}; + +inline Status::Status(const Status& s) { + state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_); +} +inline void Status::operator=(const Status& s) { + // The following condition catches both aliasing (when this == &s), + // and the common case where both s and *this are ok. + if (state_ != s.state_) { + delete[] state_; + state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_); + } +} + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_STATUS_H_ diff --git a/ios/Pods/leveldb-library/include/leveldb/table.h b/ios/Pods/leveldb-library/include/leveldb/table.h new file mode 100644 index 00000000..a9746c3f --- /dev/null +++ b/ios/Pods/leveldb-library/include/leveldb/table.h @@ -0,0 +1,85 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_INCLUDE_TABLE_H_ +#define STORAGE_LEVELDB_INCLUDE_TABLE_H_ + +#include +#include "leveldb/iterator.h" + +namespace leveldb { + +class Block; +class BlockHandle; +class Footer; +struct Options; +class RandomAccessFile; +struct ReadOptions; +class TableCache; + +// A Table is a sorted map from strings to strings. Tables are +// immutable and persistent. A Table may be safely accessed from +// multiple threads without external synchronization. +class Table { + public: + // Attempt to open the table that is stored in bytes [0..file_size) + // of "file", and read the metadata entries necessary to allow + // retrieving data from the table. + // + // If successful, returns ok and sets "*table" to the newly opened + // table. The client should delete "*table" when no longer needed. + // If there was an error while initializing the table, sets "*table" + // to NULL and returns a non-ok status. Does not take ownership of + // "*source", but the client must ensure that "source" remains live + // for the duration of the returned table's lifetime. + // + // *file must remain live while this Table is in use. + static Status Open(const Options& options, + RandomAccessFile* file, + uint64_t file_size, + Table** table); + + ~Table(); + + // Returns a new iterator over the table contents. + // The result of NewIterator() is initially invalid (caller must + // call one of the Seek methods on the iterator before using it). + Iterator* NewIterator(const ReadOptions&) const; + + // Given a key, return an approximate byte offset in the file where + // the data for that key begins (or would begin if the key were + // present in the file). The returned value is in terms of file + // bytes, and so includes effects like compression of the underlying data. + // E.g., the approximate offset of the last key in the table will + // be close to the file length. + uint64_t ApproximateOffsetOf(const Slice& key) const; + + private: + struct Rep; + Rep* rep_; + + explicit Table(Rep* rep) { rep_ = rep; } + static Iterator* BlockReader(void*, const ReadOptions&, const Slice&); + + // Calls (*handle_result)(arg, ...) with the entry found after a call + // to Seek(key). May not make such a call if filter policy says + // that key is not present. + friend class TableCache; + Status InternalGet( + const ReadOptions&, const Slice& key, + void* arg, + void (*handle_result)(void* arg, const Slice& k, const Slice& v)); + + + void ReadMeta(const Footer& footer); + void ReadFilter(const Slice& filter_handle_value); + + // No copying allowed + Table(const Table&); + void operator=(const Table&); +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_TABLE_H_ diff --git a/ios/Pods/leveldb-library/include/leveldb/table_builder.h b/ios/Pods/leveldb-library/include/leveldb/table_builder.h new file mode 100644 index 00000000..5fd1dc71 --- /dev/null +++ b/ios/Pods/leveldb-library/include/leveldb/table_builder.h @@ -0,0 +1,92 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// TableBuilder provides the interface used to build a Table +// (an immutable and sorted map from keys to values). +// +// Multiple threads can invoke const methods on a TableBuilder without +// external synchronization, but if any of the threads may call a +// non-const method, all threads accessing the same TableBuilder must use +// external synchronization. + +#ifndef STORAGE_LEVELDB_INCLUDE_TABLE_BUILDER_H_ +#define STORAGE_LEVELDB_INCLUDE_TABLE_BUILDER_H_ + +#include +#include "leveldb/options.h" +#include "leveldb/status.h" + +namespace leveldb { + +class BlockBuilder; +class BlockHandle; +class WritableFile; + +class TableBuilder { + public: + // Create a builder that will store the contents of the table it is + // building in *file. Does not close the file. It is up to the + // caller to close the file after calling Finish(). + TableBuilder(const Options& options, WritableFile* file); + + // REQUIRES: Either Finish() or Abandon() has been called. + ~TableBuilder(); + + // Change the options used by this builder. Note: only some of the + // option fields can be changed after construction. If a field is + // not allowed to change dynamically and its value in the structure + // passed to the constructor is different from its value in the + // structure passed to this method, this method will return an error + // without changing any fields. + Status ChangeOptions(const Options& options); + + // Add key,value to the table being constructed. + // REQUIRES: key is after any previously added key according to comparator. + // REQUIRES: Finish(), Abandon() have not been called + void Add(const Slice& key, const Slice& value); + + // Advanced operation: flush any buffered key/value pairs to file. + // Can be used to ensure that two adjacent entries never live in + // the same data block. Most clients should not need to use this method. + // REQUIRES: Finish(), Abandon() have not been called + void Flush(); + + // Return non-ok iff some error has been detected. + Status status() const; + + // Finish building the table. Stops using the file passed to the + // constructor after this function returns. + // REQUIRES: Finish(), Abandon() have not been called + Status Finish(); + + // Indicate that the contents of this builder should be abandoned. Stops + // using the file passed to the constructor after this function returns. + // If the caller is not going to call Finish(), it must call Abandon() + // before destroying this builder. + // REQUIRES: Finish(), Abandon() have not been called + void Abandon(); + + // Number of calls to Add() so far. + uint64_t NumEntries() const; + + // Size of the file generated so far. If invoked after a successful + // Finish() call, returns the size of the final generated file. + uint64_t FileSize() const; + + private: + bool ok() const { return status().ok(); } + void WriteBlock(BlockBuilder* block, BlockHandle* handle); + void WriteRawBlock(const Slice& data, CompressionType, BlockHandle* handle); + + struct Rep; + Rep* rep_; + + // No copying allowed + TableBuilder(const TableBuilder&); + void operator=(const TableBuilder&); +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_TABLE_BUILDER_H_ diff --git a/ios/Pods/leveldb-library/include/leveldb/write_batch.h b/ios/Pods/leveldb-library/include/leveldb/write_batch.h new file mode 100644 index 00000000..ee9aab68 --- /dev/null +++ b/ios/Pods/leveldb-library/include/leveldb/write_batch.h @@ -0,0 +1,64 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// WriteBatch holds a collection of updates to apply atomically to a DB. +// +// The updates are applied in the order in which they are added +// to the WriteBatch. For example, the value of "key" will be "v3" +// after the following batch is written: +// +// batch.Put("key", "v1"); +// batch.Delete("key"); +// batch.Put("key", "v2"); +// batch.Put("key", "v3"); +// +// Multiple threads can invoke const methods on a WriteBatch without +// external synchronization, but if any of the threads may call a +// non-const method, all threads accessing the same WriteBatch must use +// external synchronization. + +#ifndef STORAGE_LEVELDB_INCLUDE_WRITE_BATCH_H_ +#define STORAGE_LEVELDB_INCLUDE_WRITE_BATCH_H_ + +#include +#include "leveldb/status.h" + +namespace leveldb { + +class Slice; + +class WriteBatch { + public: + WriteBatch(); + ~WriteBatch(); + + // Store the mapping "key->value" in the database. + void Put(const Slice& key, const Slice& value); + + // If the database contains a mapping for "key", erase it. Else do nothing. + void Delete(const Slice& key); + + // Clear all updates buffered in this batch. + void Clear(); + + // Support for iterating over the contents of a batch. + class Handler { + public: + virtual ~Handler(); + virtual void Put(const Slice& key, const Slice& value) = 0; + virtual void Delete(const Slice& key) = 0; + }; + Status Iterate(Handler* handler) const; + + private: + friend class WriteBatchInternal; + + std::string rep_; // See comment in write_batch.cc for the format of rep_ + + // Intentionally copyable +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_WRITE_BATCH_H_ diff --git a/ios/Pods/leveldb-library/port/atomic_pointer.h b/ios/Pods/leveldb-library/port/atomic_pointer.h new file mode 100644 index 00000000..1c4c7aaf --- /dev/null +++ b/ios/Pods/leveldb-library/port/atomic_pointer.h @@ -0,0 +1,242 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +// AtomicPointer provides storage for a lock-free pointer. +// Platform-dependent implementation of AtomicPointer: +// - If the platform provides a cheap barrier, we use it with raw pointers +// - If is present (on newer versions of gcc, it is), we use +// a -based AtomicPointer. However we prefer the memory +// barrier based version, because at least on a gcc 4.4 32-bit build +// on linux, we have encountered a buggy implementation. +// Also, some implementations are much slower than a memory-barrier +// based implementation (~16ns for based acquire-load vs. ~1ns for +// a barrier based acquire-load). +// This code is based on atomicops-internals-* in Google's perftools: +// http://code.google.com/p/google-perftools/source/browse/#svn%2Ftrunk%2Fsrc%2Fbase + +#ifndef PORT_ATOMIC_POINTER_H_ +#define PORT_ATOMIC_POINTER_H_ + +#include +#ifdef LEVELDB_ATOMIC_PRESENT +#include +#endif +#ifdef OS_WIN +#include +#endif +#ifdef OS_MACOSX +#include +#endif + +#if defined(_M_X64) || defined(__x86_64__) +#define ARCH_CPU_X86_FAMILY 1 +#elif defined(_M_IX86) || defined(__i386__) || defined(__i386) +#define ARCH_CPU_X86_FAMILY 1 +#elif defined(__ARMEL__) +#define ARCH_CPU_ARM_FAMILY 1 +#elif defined(__aarch64__) +#define ARCH_CPU_ARM64_FAMILY 1 +#elif defined(__ppc__) || defined(__powerpc__) || defined(__powerpc64__) +#define ARCH_CPU_PPC_FAMILY 1 +#elif defined(__mips__) +#define ARCH_CPU_MIPS_FAMILY 1 +#endif + +namespace leveldb { +namespace port { + +// Define MemoryBarrier() if available +// Windows on x86 +#if defined(OS_WIN) && defined(COMPILER_MSVC) && defined(ARCH_CPU_X86_FAMILY) +// windows.h already provides a MemoryBarrier(void) macro +// http://msdn.microsoft.com/en-us/library/ms684208(v=vs.85).aspx +#define LEVELDB_HAVE_MEMORY_BARRIER + +// Mac OS +#elif defined(OS_MACOSX) +inline void MemoryBarrier() { + OSMemoryBarrier(); +} +#define LEVELDB_HAVE_MEMORY_BARRIER + +// Gcc on x86 +#elif defined(ARCH_CPU_X86_FAMILY) && defined(__GNUC__) +inline void MemoryBarrier() { + // See http://gcc.gnu.org/ml/gcc/2003-04/msg01180.html for a discussion on + // this idiom. Also see http://en.wikipedia.org/wiki/Memory_ordering. + __asm__ __volatile__("" : : : "memory"); +} +#define LEVELDB_HAVE_MEMORY_BARRIER + +// Sun Studio +#elif defined(ARCH_CPU_X86_FAMILY) && defined(__SUNPRO_CC) +inline void MemoryBarrier() { + // See http://gcc.gnu.org/ml/gcc/2003-04/msg01180.html for a discussion on + // this idiom. Also see http://en.wikipedia.org/wiki/Memory_ordering. + asm volatile("" : : : "memory"); +} +#define LEVELDB_HAVE_MEMORY_BARRIER + +// ARM Linux +#elif defined(ARCH_CPU_ARM_FAMILY) && defined(__linux__) +typedef void (*LinuxKernelMemoryBarrierFunc)(void); +// The Linux ARM kernel provides a highly optimized device-specific memory +// barrier function at a fixed memory address that is mapped in every +// user-level process. +// +// This beats using CPU-specific instructions which are, on single-core +// devices, un-necessary and very costly (e.g. ARMv7-A "dmb" takes more +// than 180ns on a Cortex-A8 like the one on a Nexus One). Benchmarking +// shows that the extra function call cost is completely negligible on +// multi-core devices. +// +inline void MemoryBarrier() { + (*(LinuxKernelMemoryBarrierFunc)0xffff0fa0)(); +} +#define LEVELDB_HAVE_MEMORY_BARRIER + +// ARM64 +#elif defined(ARCH_CPU_ARM64_FAMILY) +inline void MemoryBarrier() { + asm volatile("dmb sy" : : : "memory"); +} +#define LEVELDB_HAVE_MEMORY_BARRIER + +// PPC +#elif defined(ARCH_CPU_PPC_FAMILY) && defined(__GNUC__) +inline void MemoryBarrier() { + // TODO for some powerpc expert: is there a cheaper suitable variant? + // Perhaps by having separate barriers for acquire and release ops. + asm volatile("sync" : : : "memory"); +} +#define LEVELDB_HAVE_MEMORY_BARRIER + +// MIPS +#elif defined(ARCH_CPU_MIPS_FAMILY) && defined(__GNUC__) +inline void MemoryBarrier() { + __asm__ __volatile__("sync" : : : "memory"); +} +#define LEVELDB_HAVE_MEMORY_BARRIER + +#endif + +// AtomicPointer built using platform-specific MemoryBarrier() +#if defined(LEVELDB_HAVE_MEMORY_BARRIER) +class AtomicPointer { + private: + void* rep_; + public: + AtomicPointer() { } + explicit AtomicPointer(void* p) : rep_(p) {} + inline void* NoBarrier_Load() const { return rep_; } + inline void NoBarrier_Store(void* v) { rep_ = v; } + inline void* Acquire_Load() const { + void* result = rep_; + MemoryBarrier(); + return result; + } + inline void Release_Store(void* v) { + MemoryBarrier(); + rep_ = v; + } +}; + +// AtomicPointer based on +#elif defined(LEVELDB_ATOMIC_PRESENT) +class AtomicPointer { + private: + std::atomic rep_; + public: + AtomicPointer() { } + explicit AtomicPointer(void* v) : rep_(v) { } + inline void* Acquire_Load() const { + return rep_.load(std::memory_order_acquire); + } + inline void Release_Store(void* v) { + rep_.store(v, std::memory_order_release); + } + inline void* NoBarrier_Load() const { + return rep_.load(std::memory_order_relaxed); + } + inline void NoBarrier_Store(void* v) { + rep_.store(v, std::memory_order_relaxed); + } +}; + +// Atomic pointer based on sparc memory barriers +#elif defined(__sparcv9) && defined(__GNUC__) +class AtomicPointer { + private: + void* rep_; + public: + AtomicPointer() { } + explicit AtomicPointer(void* v) : rep_(v) { } + inline void* Acquire_Load() const { + void* val; + __asm__ __volatile__ ( + "ldx [%[rep_]], %[val] \n\t" + "membar #LoadLoad|#LoadStore \n\t" + : [val] "=r" (val) + : [rep_] "r" (&rep_) + : "memory"); + return val; + } + inline void Release_Store(void* v) { + __asm__ __volatile__ ( + "membar #LoadStore|#StoreStore \n\t" + "stx %[v], [%[rep_]] \n\t" + : + : [rep_] "r" (&rep_), [v] "r" (v) + : "memory"); + } + inline void* NoBarrier_Load() const { return rep_; } + inline void NoBarrier_Store(void* v) { rep_ = v; } +}; + +// Atomic pointer based on ia64 acq/rel +#elif defined(__ia64) && defined(__GNUC__) +class AtomicPointer { + private: + void* rep_; + public: + AtomicPointer() { } + explicit AtomicPointer(void* v) : rep_(v) { } + inline void* Acquire_Load() const { + void* val ; + __asm__ __volatile__ ( + "ld8.acq %[val] = [%[rep_]] \n\t" + : [val] "=r" (val) + : [rep_] "r" (&rep_) + : "memory" + ); + return val; + } + inline void Release_Store(void* v) { + __asm__ __volatile__ ( + "st8.rel [%[rep_]] = %[v] \n\t" + : + : [rep_] "r" (&rep_), [v] "r" (v) + : "memory" + ); + } + inline void* NoBarrier_Load() const { return rep_; } + inline void NoBarrier_Store(void* v) { rep_ = v; } +}; + +// We have neither MemoryBarrier(), nor +#else +#error Please implement AtomicPointer for this platform. + +#endif + +#undef LEVELDB_HAVE_MEMORY_BARRIER +#undef ARCH_CPU_X86_FAMILY +#undef ARCH_CPU_ARM_FAMILY +#undef ARCH_CPU_ARM64_FAMILY +#undef ARCH_CPU_PPC_FAMILY + +} // namespace port +} // namespace leveldb + +#endif // PORT_ATOMIC_POINTER_H_ diff --git a/ios/Pods/leveldb-library/port/port.h b/ios/Pods/leveldb-library/port/port.h new file mode 100644 index 00000000..e667db40 --- /dev/null +++ b/ios/Pods/leveldb-library/port/port.h @@ -0,0 +1,19 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_PORT_PORT_H_ +#define STORAGE_LEVELDB_PORT_PORT_H_ + +#include + +// Include the appropriate platform specific file below. If you are +// porting to a new platform, see "port_example.h" for documentation +// of what the new port_.h file must provide. +#if defined(LEVELDB_PLATFORM_POSIX) +# include "port/port_posix.h" +#elif defined(LEVELDB_PLATFORM_CHROMIUM) +# include "port/port_chromium.h" +#endif + +#endif // STORAGE_LEVELDB_PORT_PORT_H_ diff --git a/ios/Pods/leveldb-library/port/port_example.h b/ios/Pods/leveldb-library/port/port_example.h new file mode 100644 index 00000000..97bd669a --- /dev/null +++ b/ios/Pods/leveldb-library/port/port_example.h @@ -0,0 +1,141 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// This file contains the specification, but not the implementations, +// of the types/operations/etc. that should be defined by a platform +// specific port_.h file. Use this file as a reference for +// how to port this package to a new platform. + +#ifndef STORAGE_LEVELDB_PORT_PORT_EXAMPLE_H_ +#define STORAGE_LEVELDB_PORT_PORT_EXAMPLE_H_ + +namespace leveldb { +namespace port { + +// TODO(jorlow): Many of these belong more in the environment class rather than +// here. We should try moving them and see if it affects perf. + +// The following boolean constant must be true on a little-endian machine +// and false otherwise. +static const bool kLittleEndian = true /* or some other expression */; + +// ------------------ Threading ------------------- + +// A Mutex represents an exclusive lock. +class Mutex { + public: + Mutex(); + ~Mutex(); + + // Lock the mutex. Waits until other lockers have exited. + // Will deadlock if the mutex is already locked by this thread. + void Lock(); + + // Unlock the mutex. + // REQUIRES: This mutex was locked by this thread. + void Unlock(); + + // Optionally crash if this thread does not hold this mutex. + // The implementation must be fast, especially if NDEBUG is + // defined. The implementation is allowed to skip all checks. + void AssertHeld(); +}; + +class CondVar { + public: + explicit CondVar(Mutex* mu); + ~CondVar(); + + // Atomically release *mu and block on this condition variable until + // either a call to SignalAll(), or a call to Signal() that picks + // this thread to wakeup. + // REQUIRES: this thread holds *mu + void Wait(); + + // If there are some threads waiting, wake up at least one of them. + void Signal(); + + // Wake up all waiting threads. + void SignallAll(); +}; + +// Thread-safe initialization. +// Used as follows: +// static port::OnceType init_control = LEVELDB_ONCE_INIT; +// static void Initializer() { ... do something ...; } +// ... +// port::InitOnce(&init_control, &Initializer); +typedef intptr_t OnceType; +#define LEVELDB_ONCE_INIT 0 +extern void InitOnce(port::OnceType*, void (*initializer)()); + +// A type that holds a pointer that can be read or written atomically +// (i.e., without word-tearing.) +class AtomicPointer { + private: + intptr_t rep_; + public: + // Initialize to arbitrary value + AtomicPointer(); + + // Initialize to hold v + explicit AtomicPointer(void* v) : rep_(v) { } + + // Read and return the stored pointer with the guarantee that no + // later memory access (read or write) by this thread can be + // reordered ahead of this read. + void* Acquire_Load() const; + + // Set v as the stored pointer with the guarantee that no earlier + // memory access (read or write) by this thread can be reordered + // after this store. + void Release_Store(void* v); + + // Read the stored pointer with no ordering guarantees. + void* NoBarrier_Load() const; + + // Set va as the stored pointer with no ordering guarantees. + void NoBarrier_Store(void* v); +}; + +// ------------------ Compression ------------------- + +// Store the snappy compression of "input[0,input_length-1]" in *output. +// Returns false if snappy is not supported by this port. +extern bool Snappy_Compress(const char* input, size_t input_length, + std::string* output); + +// If input[0,input_length-1] looks like a valid snappy compressed +// buffer, store the size of the uncompressed data in *result and +// return true. Else return false. +extern bool Snappy_GetUncompressedLength(const char* input, size_t length, + size_t* result); + +// Attempt to snappy uncompress input[0,input_length-1] into *output. +// Returns true if successful, false if the input is invalid lightweight +// compressed data. +// +// REQUIRES: at least the first "n" bytes of output[] must be writable +// where "n" is the result of a successful call to +// Snappy_GetUncompressedLength. +extern bool Snappy_Uncompress(const char* input_data, size_t input_length, + char* output); + +// ------------------ Miscellaneous ------------------- + +// If heap profiling is not supported, returns false. +// Else repeatedly calls (*func)(arg, data, n) and then returns true. +// The concatenation of all "data[0,n-1]" fragments is the heap profile. +extern bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg); + +// Extend the CRC to include the first n bytes of buf. +// +// Returns zero if the CRC cannot be extended using acceleration, else returns +// the newly extended CRC value (which may also be zero). +uint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size); + +} // namespace port +} // namespace leveldb + +#endif // STORAGE_LEVELDB_PORT_PORT_EXAMPLE_H_ diff --git a/ios/Pods/leveldb-library/port/port_posix.cc b/ios/Pods/leveldb-library/port/port_posix.cc new file mode 100644 index 00000000..30e8007a --- /dev/null +++ b/ios/Pods/leveldb-library/port/port_posix.cc @@ -0,0 +1,53 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "port/port_posix.h" + +#include +#include +#include + +namespace leveldb { +namespace port { + +static void PthreadCall(const char* label, int result) { + if (result != 0) { + fprintf(stderr, "pthread %s: %s\n", label, strerror(result)); + abort(); + } +} + +Mutex::Mutex() { PthreadCall("init mutex", pthread_mutex_init(&mu_, NULL)); } + +Mutex::~Mutex() { PthreadCall("destroy mutex", pthread_mutex_destroy(&mu_)); } + +void Mutex::Lock() { PthreadCall("lock", pthread_mutex_lock(&mu_)); } + +void Mutex::Unlock() { PthreadCall("unlock", pthread_mutex_unlock(&mu_)); } + +CondVar::CondVar(Mutex* mu) + : mu_(mu) { + PthreadCall("init cv", pthread_cond_init(&cv_, NULL)); +} + +CondVar::~CondVar() { PthreadCall("destroy cv", pthread_cond_destroy(&cv_)); } + +void CondVar::Wait() { + PthreadCall("wait", pthread_cond_wait(&cv_, &mu_->mu_)); +} + +void CondVar::Signal() { + PthreadCall("signal", pthread_cond_signal(&cv_)); +} + +void CondVar::SignalAll() { + PthreadCall("broadcast", pthread_cond_broadcast(&cv_)); +} + +void InitOnce(OnceType* once, void (*initializer)()) { + PthreadCall("once", pthread_once(once, initializer)); +} + +} // namespace port +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/port/port_posix.h b/ios/Pods/leveldb-library/port/port_posix.h new file mode 100644 index 00000000..d67ab68c --- /dev/null +++ b/ios/Pods/leveldb-library/port/port_posix.h @@ -0,0 +1,156 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// See port_example.h for documentation for the following types/functions. + +#ifndef STORAGE_LEVELDB_PORT_PORT_POSIX_H_ +#define STORAGE_LEVELDB_PORT_PORT_POSIX_H_ + +#undef PLATFORM_IS_LITTLE_ENDIAN +#if defined(OS_MACOSX) + #include + #if defined(__DARWIN_LITTLE_ENDIAN) && defined(__DARWIN_BYTE_ORDER) + #define PLATFORM_IS_LITTLE_ENDIAN \ + (__DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN) + #endif +#elif defined(OS_SOLARIS) + #include + #ifdef _LITTLE_ENDIAN + #define PLATFORM_IS_LITTLE_ENDIAN true + #else + #define PLATFORM_IS_LITTLE_ENDIAN false + #endif +#elif defined(OS_FREEBSD) || defined(OS_OPENBSD) ||\ + defined(OS_NETBSD) || defined(OS_DRAGONFLYBSD) + #include + #include + #define PLATFORM_IS_LITTLE_ENDIAN (_BYTE_ORDER == _LITTLE_ENDIAN) +#elif defined(OS_HPUX) + #define PLATFORM_IS_LITTLE_ENDIAN false +#elif defined(OS_ANDROID) + // Due to a bug in the NDK x86 definition, + // _BYTE_ORDER must be used instead of __BYTE_ORDER on Android. + // See http://code.google.com/p/android/issues/detail?id=39824 + #include + #define PLATFORM_IS_LITTLE_ENDIAN (_BYTE_ORDER == _LITTLE_ENDIAN) +#else + #include +#endif + +#include +#ifdef SNAPPY +#include +#endif +#include +#include +#include "port/atomic_pointer.h" + +#ifndef PLATFORM_IS_LITTLE_ENDIAN +#define PLATFORM_IS_LITTLE_ENDIAN (__BYTE_ORDER == __LITTLE_ENDIAN) +#endif + +#if defined(OS_MACOSX) || defined(OS_SOLARIS) || defined(OS_FREEBSD) ||\ + defined(OS_NETBSD) || defined(OS_OPENBSD) || defined(OS_DRAGONFLYBSD) ||\ + defined(OS_ANDROID) || defined(OS_HPUX) || defined(CYGWIN) +// Use fread/fwrite/fflush on platforms without _unlocked variants +#define fread_unlocked fread +#define fwrite_unlocked fwrite +#define fflush_unlocked fflush +#endif + +#if defined(OS_MACOSX) || defined(OS_FREEBSD) ||\ + defined(OS_OPENBSD) || defined(OS_DRAGONFLYBSD) +// Use fsync() on platforms without fdatasync() +#define fdatasync fsync +#endif + +#if defined(OS_ANDROID) && __ANDROID_API__ < 9 +// fdatasync() was only introduced in API level 9 on Android. Use fsync() +// when targetting older platforms. +#define fdatasync fsync +#endif + +namespace leveldb { +namespace port { + +static const bool kLittleEndian = PLATFORM_IS_LITTLE_ENDIAN; +#undef PLATFORM_IS_LITTLE_ENDIAN + +class CondVar; + +class Mutex { + public: + Mutex(); + ~Mutex(); + + void Lock(); + void Unlock(); + void AssertHeld() { } + + private: + friend class CondVar; + pthread_mutex_t mu_; + + // No copying + Mutex(const Mutex&); + void operator=(const Mutex&); +}; + +class CondVar { + public: + explicit CondVar(Mutex* mu); + ~CondVar(); + void Wait(); + void Signal(); + void SignalAll(); + private: + pthread_cond_t cv_; + Mutex* mu_; +}; + +typedef pthread_once_t OnceType; +#define LEVELDB_ONCE_INIT PTHREAD_ONCE_INIT +extern void InitOnce(OnceType* once, void (*initializer)()); + +inline bool Snappy_Compress(const char* input, size_t length, + ::std::string* output) { +#ifdef SNAPPY + output->resize(snappy::MaxCompressedLength(length)); + size_t outlen; + snappy::RawCompress(input, length, &(*output)[0], &outlen); + output->resize(outlen); + return true; +#endif + + return false; +} + +inline bool Snappy_GetUncompressedLength(const char* input, size_t length, + size_t* result) { +#ifdef SNAPPY + return snappy::GetUncompressedLength(input, length, result); +#else + return false; +#endif +} + +inline bool Snappy_Uncompress(const char* input, size_t length, + char* output) { +#ifdef SNAPPY + return snappy::RawUncompress(input, length, output); +#else + return false; +#endif +} + +inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) { + return false; +} + +uint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size); + +} // namespace port +} // namespace leveldb + +#endif // STORAGE_LEVELDB_PORT_PORT_POSIX_H_ diff --git a/ios/Pods/leveldb-library/port/port_posix_sse.cc b/ios/Pods/leveldb-library/port/port_posix_sse.cc new file mode 100644 index 00000000..1e519ba0 --- /dev/null +++ b/ios/Pods/leveldb-library/port/port_posix_sse.cc @@ -0,0 +1,129 @@ +// Copyright 2016 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// A portable implementation of crc32c, optimized to handle +// four bytes at a time. +// +// In a separate source file to allow this accelerated CRC32C function to be +// compiled with the appropriate compiler flags to enable x86 SSE 4.2 +// instructions. + +#include +#include +#include "port/port.h" + +#if defined(LEVELDB_PLATFORM_POSIX_SSE) + +#if defined(_MSC_VER) +#include +#elif defined(__GNUC__) && defined(__SSE4_2__) +#include +#include +#endif + +#endif // defined(LEVELDB_PLATFORM_POSIX_SSE) + +namespace leveldb { +namespace port { + +#if defined(LEVELDB_PLATFORM_POSIX_SSE) + +// Used to fetch a naturally-aligned 32-bit word in little endian byte-order +static inline uint32_t LE_LOAD32(const uint8_t *p) { + // SSE is x86 only, so ensured that |p| is always little-endian. + uint32_t word; + memcpy(&word, p, sizeof(word)); + return word; +} + +#if defined(_M_X64) || defined(__x86_64__) // LE_LOAD64 is only used on x64. + +// Used to fetch a naturally-aligned 64-bit word in little endian byte-order +static inline uint64_t LE_LOAD64(const uint8_t *p) { + uint64_t dword; + memcpy(&dword, p, sizeof(dword)); + return dword; +} + +#endif // defined(_M_X64) || defined(__x86_64__) + +static inline bool HaveSSE42() { +#if defined(_MSC_VER) + int cpu_info[4]; + __cpuid(cpu_info, 1); + return (cpu_info[2] & (1 << 20)) != 0; +#elif defined(__GNUC__) + unsigned int eax, ebx, ecx, edx; + __get_cpuid(1, &eax, &ebx, &ecx, &edx); + return (ecx & (1 << 20)) != 0; +#else + return false; +#endif +} + +#endif // defined(LEVELDB_PLATFORM_POSIX_SSE) + +// For further improvements see Intel publication at: +// http://download.intel.com/design/intarch/papers/323405.pdf +uint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size) { +#if !defined(LEVELDB_PLATFORM_POSIX_SSE) + return 0; +#else + static bool have = HaveSSE42(); + if (!have) { + return 0; + } + + const uint8_t *p = reinterpret_cast(buf); + const uint8_t *e = p + size; + uint32_t l = crc ^ 0xffffffffu; + +#define STEP1 do { \ + l = _mm_crc32_u8(l, *p++); \ +} while (0) +#define STEP4 do { \ + l = _mm_crc32_u32(l, LE_LOAD32(p)); \ + p += 4; \ +} while (0) +#define STEP8 do { \ + l = _mm_crc32_u64(l, LE_LOAD64(p)); \ + p += 8; \ +} while (0) + + if (size > 16) { + // Process unaligned bytes + for (unsigned int i = reinterpret_cast(p) % 8; i; --i) { + STEP1; + } + + // _mm_crc32_u64 is only available on x64. +#if defined(_M_X64) || defined(__x86_64__) + // Process 8 bytes at a time + while ((e-p) >= 8) { + STEP8; + } + // Process 4 bytes at a time + if ((e-p) >= 4) { + STEP4; + } +#else // !(defined(_M_X64) || defined(__x86_64__)) + // Process 4 bytes at a time + while ((e-p) >= 4) { + STEP4; + } +#endif // defined(_M_X64) || defined(__x86_64__) + } + // Process the last few bytes + while (p != e) { + STEP1; + } +#undef STEP8 +#undef STEP4 +#undef STEP1 + return l ^ 0xffffffffu; +#endif // defined(LEVELDB_PLATFORM_POSIX_SSE) +} + +} // namespace port +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/port/thread_annotations.h b/ios/Pods/leveldb-library/port/thread_annotations.h new file mode 100644 index 00000000..9470ef58 --- /dev/null +++ b/ios/Pods/leveldb-library/port/thread_annotations.h @@ -0,0 +1,60 @@ +// Copyright (c) 2012 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_ +#define STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_ + +// Some environments provide custom macros to aid in static thread-safety +// analysis. Provide empty definitions of such macros unless they are already +// defined. + +#ifndef EXCLUSIVE_LOCKS_REQUIRED +#define EXCLUSIVE_LOCKS_REQUIRED(...) +#endif + +#ifndef SHARED_LOCKS_REQUIRED +#define SHARED_LOCKS_REQUIRED(...) +#endif + +#ifndef LOCKS_EXCLUDED +#define LOCKS_EXCLUDED(...) +#endif + +#ifndef LOCK_RETURNED +#define LOCK_RETURNED(x) +#endif + +#ifndef LOCKABLE +#define LOCKABLE +#endif + +#ifndef SCOPED_LOCKABLE +#define SCOPED_LOCKABLE +#endif + +#ifndef EXCLUSIVE_LOCK_FUNCTION +#define EXCLUSIVE_LOCK_FUNCTION(...) +#endif + +#ifndef SHARED_LOCK_FUNCTION +#define SHARED_LOCK_FUNCTION(...) +#endif + +#ifndef EXCLUSIVE_TRYLOCK_FUNCTION +#define EXCLUSIVE_TRYLOCK_FUNCTION(...) +#endif + +#ifndef SHARED_TRYLOCK_FUNCTION +#define SHARED_TRYLOCK_FUNCTION(...) +#endif + +#ifndef UNLOCK_FUNCTION +#define UNLOCK_FUNCTION(...) +#endif + +#ifndef NO_THREAD_SAFETY_ANALYSIS +#define NO_THREAD_SAFETY_ANALYSIS +#endif + +#endif // STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_ diff --git a/ios/Pods/leveldb-library/table/block.cc b/ios/Pods/leveldb-library/table/block.cc new file mode 100644 index 00000000..43e402c9 --- /dev/null +++ b/ios/Pods/leveldb-library/table/block.cc @@ -0,0 +1,268 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// Decodes the blocks generated by block_builder.cc. + +#include "table/block.h" + +#include +#include +#include "leveldb/comparator.h" +#include "table/format.h" +#include "util/coding.h" +#include "util/logging.h" + +namespace leveldb { + +inline uint32_t Block::NumRestarts() const { + assert(size_ >= sizeof(uint32_t)); + return DecodeFixed32(data_ + size_ - sizeof(uint32_t)); +} + +Block::Block(const BlockContents& contents) + : data_(contents.data.data()), + size_(contents.data.size()), + owned_(contents.heap_allocated) { + if (size_ < sizeof(uint32_t)) { + size_ = 0; // Error marker + } else { + size_t max_restarts_allowed = (size_-sizeof(uint32_t)) / sizeof(uint32_t); + if (NumRestarts() > max_restarts_allowed) { + // The size is too small for NumRestarts() + size_ = 0; + } else { + restart_offset_ = size_ - (1 + NumRestarts()) * sizeof(uint32_t); + } + } +} + +Block::~Block() { + if (owned_) { + delete[] data_; + } +} + +// Helper routine: decode the next block entry starting at "p", +// storing the number of shared key bytes, non_shared key bytes, +// and the length of the value in "*shared", "*non_shared", and +// "*value_length", respectively. Will not dereference past "limit". +// +// If any errors are detected, returns NULL. Otherwise, returns a +// pointer to the key delta (just past the three decoded values). +static inline const char* DecodeEntry(const char* p, const char* limit, + uint32_t* shared, + uint32_t* non_shared, + uint32_t* value_length) { + if (limit - p < 3) return NULL; + *shared = reinterpret_cast(p)[0]; + *non_shared = reinterpret_cast(p)[1]; + *value_length = reinterpret_cast(p)[2]; + if ((*shared | *non_shared | *value_length) < 128) { + // Fast path: all three values are encoded in one byte each + p += 3; + } else { + if ((p = GetVarint32Ptr(p, limit, shared)) == NULL) return NULL; + if ((p = GetVarint32Ptr(p, limit, non_shared)) == NULL) return NULL; + if ((p = GetVarint32Ptr(p, limit, value_length)) == NULL) return NULL; + } + + if (static_cast(limit - p) < (*non_shared + *value_length)) { + return NULL; + } + return p; +} + +class Block::Iter : public Iterator { + private: + const Comparator* const comparator_; + const char* const data_; // underlying block contents + uint32_t const restarts_; // Offset of restart array (list of fixed32) + uint32_t const num_restarts_; // Number of uint32_t entries in restart array + + // current_ is offset in data_ of current entry. >= restarts_ if !Valid + uint32_t current_; + uint32_t restart_index_; // Index of restart block in which current_ falls + std::string key_; + Slice value_; + Status status_; + + inline int Compare(const Slice& a, const Slice& b) const { + return comparator_->Compare(a, b); + } + + // Return the offset in data_ just past the end of the current entry. + inline uint32_t NextEntryOffset() const { + return (value_.data() + value_.size()) - data_; + } + + uint32_t GetRestartPoint(uint32_t index) { + assert(index < num_restarts_); + return DecodeFixed32(data_ + restarts_ + index * sizeof(uint32_t)); + } + + void SeekToRestartPoint(uint32_t index) { + key_.clear(); + restart_index_ = index; + // current_ will be fixed by ParseNextKey(); + + // ParseNextKey() starts at the end of value_, so set value_ accordingly + uint32_t offset = GetRestartPoint(index); + value_ = Slice(data_ + offset, 0); + } + + public: + Iter(const Comparator* comparator, + const char* data, + uint32_t restarts, + uint32_t num_restarts) + : comparator_(comparator), + data_(data), + restarts_(restarts), + num_restarts_(num_restarts), + current_(restarts_), + restart_index_(num_restarts_) { + assert(num_restarts_ > 0); + } + + virtual bool Valid() const { return current_ < restarts_; } + virtual Status status() const { return status_; } + virtual Slice key() const { + assert(Valid()); + return key_; + } + virtual Slice value() const { + assert(Valid()); + return value_; + } + + virtual void Next() { + assert(Valid()); + ParseNextKey(); + } + + virtual void Prev() { + assert(Valid()); + + // Scan backwards to a restart point before current_ + const uint32_t original = current_; + while (GetRestartPoint(restart_index_) >= original) { + if (restart_index_ == 0) { + // No more entries + current_ = restarts_; + restart_index_ = num_restarts_; + return; + } + restart_index_--; + } + + SeekToRestartPoint(restart_index_); + do { + // Loop until end of current entry hits the start of original entry + } while (ParseNextKey() && NextEntryOffset() < original); + } + + virtual void Seek(const Slice& target) { + // Binary search in restart array to find the last restart point + // with a key < target + uint32_t left = 0; + uint32_t right = num_restarts_ - 1; + while (left < right) { + uint32_t mid = (left + right + 1) / 2; + uint32_t region_offset = GetRestartPoint(mid); + uint32_t shared, non_shared, value_length; + const char* key_ptr = DecodeEntry(data_ + region_offset, + data_ + restarts_, + &shared, &non_shared, &value_length); + if (key_ptr == NULL || (shared != 0)) { + CorruptionError(); + return; + } + Slice mid_key(key_ptr, non_shared); + if (Compare(mid_key, target) < 0) { + // Key at "mid" is smaller than "target". Therefore all + // blocks before "mid" are uninteresting. + left = mid; + } else { + // Key at "mid" is >= "target". Therefore all blocks at or + // after "mid" are uninteresting. + right = mid - 1; + } + } + + // Linear search (within restart block) for first key >= target + SeekToRestartPoint(left); + while (true) { + if (!ParseNextKey()) { + return; + } + if (Compare(key_, target) >= 0) { + return; + } + } + } + + virtual void SeekToFirst() { + SeekToRestartPoint(0); + ParseNextKey(); + } + + virtual void SeekToLast() { + SeekToRestartPoint(num_restarts_ - 1); + while (ParseNextKey() && NextEntryOffset() < restarts_) { + // Keep skipping + } + } + + private: + void CorruptionError() { + current_ = restarts_; + restart_index_ = num_restarts_; + status_ = Status::Corruption("bad entry in block"); + key_.clear(); + value_.clear(); + } + + bool ParseNextKey() { + current_ = NextEntryOffset(); + const char* p = data_ + current_; + const char* limit = data_ + restarts_; // Restarts come right after data + if (p >= limit) { + // No more entries to return. Mark as invalid. + current_ = restarts_; + restart_index_ = num_restarts_; + return false; + } + + // Decode next entry + uint32_t shared, non_shared, value_length; + p = DecodeEntry(p, limit, &shared, &non_shared, &value_length); + if (p == NULL || key_.size() < shared) { + CorruptionError(); + return false; + } else { + key_.resize(shared); + key_.append(p, non_shared); + value_ = Slice(p + non_shared, value_length); + while (restart_index_ + 1 < num_restarts_ && + GetRestartPoint(restart_index_ + 1) < current_) { + ++restart_index_; + } + return true; + } + } +}; + +Iterator* Block::NewIterator(const Comparator* cmp) { + if (size_ < sizeof(uint32_t)) { + return NewErrorIterator(Status::Corruption("bad block contents")); + } + const uint32_t num_restarts = NumRestarts(); + if (num_restarts == 0) { + return NewEmptyIterator(); + } else { + return new Iter(cmp, data_, restart_offset_, num_restarts); + } +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/table/block.h b/ios/Pods/leveldb-library/table/block.h new file mode 100644 index 00000000..2493eb9f --- /dev/null +++ b/ios/Pods/leveldb-library/table/block.h @@ -0,0 +1,44 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_TABLE_BLOCK_H_ +#define STORAGE_LEVELDB_TABLE_BLOCK_H_ + +#include +#include +#include "leveldb/iterator.h" + +namespace leveldb { + +struct BlockContents; +class Comparator; + +class Block { + public: + // Initialize the block with the specified contents. + explicit Block(const BlockContents& contents); + + ~Block(); + + size_t size() const { return size_; } + Iterator* NewIterator(const Comparator* comparator); + + private: + uint32_t NumRestarts() const; + + const char* data_; + size_t size_; + uint32_t restart_offset_; // Offset in data_ of restart array + bool owned_; // Block owns data_[] + + // No copying allowed + Block(const Block&); + void operator=(const Block&); + + class Iter; +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_TABLE_BLOCK_H_ diff --git a/ios/Pods/leveldb-library/table/block_builder.cc b/ios/Pods/leveldb-library/table/block_builder.cc new file mode 100644 index 00000000..db660cd0 --- /dev/null +++ b/ios/Pods/leveldb-library/table/block_builder.cc @@ -0,0 +1,109 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// BlockBuilder generates blocks where keys are prefix-compressed: +// +// When we store a key, we drop the prefix shared with the previous +// string. This helps reduce the space requirement significantly. +// Furthermore, once every K keys, we do not apply the prefix +// compression and store the entire key. We call this a "restart +// point". The tail end of the block stores the offsets of all of the +// restart points, and can be used to do a binary search when looking +// for a particular key. Values are stored as-is (without compression) +// immediately following the corresponding key. +// +// An entry for a particular key-value pair has the form: +// shared_bytes: varint32 +// unshared_bytes: varint32 +// value_length: varint32 +// key_delta: char[unshared_bytes] +// value: char[value_length] +// shared_bytes == 0 for restart points. +// +// The trailer of the block has the form: +// restarts: uint32[num_restarts] +// num_restarts: uint32 +// restarts[i] contains the offset within the block of the ith restart point. + +#include "table/block_builder.h" + +#include +#include +#include "leveldb/comparator.h" +#include "leveldb/table_builder.h" +#include "util/coding.h" + +namespace leveldb { + +BlockBuilder::BlockBuilder(const Options* options) + : options_(options), + restarts_(), + counter_(0), + finished_(false) { + assert(options->block_restart_interval >= 1); + restarts_.push_back(0); // First restart point is at offset 0 +} + +void BlockBuilder::Reset() { + buffer_.clear(); + restarts_.clear(); + restarts_.push_back(0); // First restart point is at offset 0 + counter_ = 0; + finished_ = false; + last_key_.clear(); +} + +size_t BlockBuilder::CurrentSizeEstimate() const { + return (buffer_.size() + // Raw data buffer + restarts_.size() * sizeof(uint32_t) + // Restart array + sizeof(uint32_t)); // Restart array length +} + +Slice BlockBuilder::Finish() { + // Append restart array + for (size_t i = 0; i < restarts_.size(); i++) { + PutFixed32(&buffer_, restarts_[i]); + } + PutFixed32(&buffer_, restarts_.size()); + finished_ = true; + return Slice(buffer_); +} + +void BlockBuilder::Add(const Slice& key, const Slice& value) { + Slice last_key_piece(last_key_); + assert(!finished_); + assert(counter_ <= options_->block_restart_interval); + assert(buffer_.empty() // No values yet? + || options_->comparator->Compare(key, last_key_piece) > 0); + size_t shared = 0; + if (counter_ < options_->block_restart_interval) { + // See how much sharing to do with previous string + const size_t min_length = std::min(last_key_piece.size(), key.size()); + while ((shared < min_length) && (last_key_piece[shared] == key[shared])) { + shared++; + } + } else { + // Restart compression + restarts_.push_back(buffer_.size()); + counter_ = 0; + } + const size_t non_shared = key.size() - shared; + + // Add "" to buffer_ + PutVarint32(&buffer_, shared); + PutVarint32(&buffer_, non_shared); + PutVarint32(&buffer_, value.size()); + + // Add string delta to buffer_ followed by value + buffer_.append(key.data() + shared, non_shared); + buffer_.append(value.data(), value.size()); + + // Update state + last_key_.resize(shared); + last_key_.append(key.data() + shared, non_shared); + assert(Slice(last_key_) == key); + counter_++; +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/table/block_builder.h b/ios/Pods/leveldb-library/table/block_builder.h new file mode 100644 index 00000000..4fbcb339 --- /dev/null +++ b/ios/Pods/leveldb-library/table/block_builder.h @@ -0,0 +1,57 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_TABLE_BLOCK_BUILDER_H_ +#define STORAGE_LEVELDB_TABLE_BLOCK_BUILDER_H_ + +#include + +#include +#include "leveldb/slice.h" + +namespace leveldb { + +struct Options; + +class BlockBuilder { + public: + explicit BlockBuilder(const Options* options); + + // Reset the contents as if the BlockBuilder was just constructed. + void Reset(); + + // REQUIRES: Finish() has not been called since the last call to Reset(). + // REQUIRES: key is larger than any previously added key + void Add(const Slice& key, const Slice& value); + + // Finish building the block and return a slice that refers to the + // block contents. The returned slice will remain valid for the + // lifetime of this builder or until Reset() is called. + Slice Finish(); + + // Returns an estimate of the current (uncompressed) size of the block + // we are building. + size_t CurrentSizeEstimate() const; + + // Return true iff no entries have been added since the last Reset() + bool empty() const { + return buffer_.empty(); + } + + private: + const Options* options_; + std::string buffer_; // Destination buffer + std::vector restarts_; // Restart points + int counter_; // Number of entries emitted since restart + bool finished_; // Has Finish() been called? + std::string last_key_; + + // No copying allowed + BlockBuilder(const BlockBuilder&); + void operator=(const BlockBuilder&); +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_TABLE_BLOCK_BUILDER_H_ diff --git a/ios/Pods/leveldb-library/table/filter_block.cc b/ios/Pods/leveldb-library/table/filter_block.cc new file mode 100644 index 00000000..1ed51341 --- /dev/null +++ b/ios/Pods/leveldb-library/table/filter_block.cc @@ -0,0 +1,111 @@ +// Copyright (c) 2012 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "table/filter_block.h" + +#include "leveldb/filter_policy.h" +#include "util/coding.h" + +namespace leveldb { + +// See doc/table_format.md for an explanation of the filter block format. + +// Generate new filter every 2KB of data +static const size_t kFilterBaseLg = 11; +static const size_t kFilterBase = 1 << kFilterBaseLg; + +FilterBlockBuilder::FilterBlockBuilder(const FilterPolicy* policy) + : policy_(policy) { +} + +void FilterBlockBuilder::StartBlock(uint64_t block_offset) { + uint64_t filter_index = (block_offset / kFilterBase); + assert(filter_index >= filter_offsets_.size()); + while (filter_index > filter_offsets_.size()) { + GenerateFilter(); + } +} + +void FilterBlockBuilder::AddKey(const Slice& key) { + Slice k = key; + start_.push_back(keys_.size()); + keys_.append(k.data(), k.size()); +} + +Slice FilterBlockBuilder::Finish() { + if (!start_.empty()) { + GenerateFilter(); + } + + // Append array of per-filter offsets + const uint32_t array_offset = result_.size(); + for (size_t i = 0; i < filter_offsets_.size(); i++) { + PutFixed32(&result_, filter_offsets_[i]); + } + + PutFixed32(&result_, array_offset); + result_.push_back(kFilterBaseLg); // Save encoding parameter in result + return Slice(result_); +} + +void FilterBlockBuilder::GenerateFilter() { + const size_t num_keys = start_.size(); + if (num_keys == 0) { + // Fast path if there are no keys for this filter + filter_offsets_.push_back(result_.size()); + return; + } + + // Make list of keys from flattened key structure + start_.push_back(keys_.size()); // Simplify length computation + tmp_keys_.resize(num_keys); + for (size_t i = 0; i < num_keys; i++) { + const char* base = keys_.data() + start_[i]; + size_t length = start_[i+1] - start_[i]; + tmp_keys_[i] = Slice(base, length); + } + + // Generate filter for current set of keys and append to result_. + filter_offsets_.push_back(result_.size()); + policy_->CreateFilter(&tmp_keys_[0], static_cast(num_keys), &result_); + + tmp_keys_.clear(); + keys_.clear(); + start_.clear(); +} + +FilterBlockReader::FilterBlockReader(const FilterPolicy* policy, + const Slice& contents) + : policy_(policy), + data_(NULL), + offset_(NULL), + num_(0), + base_lg_(0) { + size_t n = contents.size(); + if (n < 5) return; // 1 byte for base_lg_ and 4 for start of offset array + base_lg_ = contents[n-1]; + uint32_t last_word = DecodeFixed32(contents.data() + n - 5); + if (last_word > n - 5) return; + data_ = contents.data(); + offset_ = data_ + last_word; + num_ = (n - 5 - last_word) / 4; +} + +bool FilterBlockReader::KeyMayMatch(uint64_t block_offset, const Slice& key) { + uint64_t index = block_offset >> base_lg_; + if (index < num_) { + uint32_t start = DecodeFixed32(offset_ + index*4); + uint32_t limit = DecodeFixed32(offset_ + index*4 + 4); + if (start <= limit && limit <= static_cast(offset_ - data_)) { + Slice filter = Slice(data_ + start, limit - start); + return policy_->KeyMayMatch(key, filter); + } else if (start == limit) { + // Empty filters do not match any keys + return false; + } + } + return true; // Errors are treated as potential matches +} + +} diff --git a/ios/Pods/leveldb-library/table/filter_block.h b/ios/Pods/leveldb-library/table/filter_block.h new file mode 100644 index 00000000..c67d010b --- /dev/null +++ b/ios/Pods/leveldb-library/table/filter_block.h @@ -0,0 +1,68 @@ +// Copyright (c) 2012 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// A filter block is stored near the end of a Table file. It contains +// filters (e.g., bloom filters) for all data blocks in the table combined +// into a single filter block. + +#ifndef STORAGE_LEVELDB_TABLE_FILTER_BLOCK_H_ +#define STORAGE_LEVELDB_TABLE_FILTER_BLOCK_H_ + +#include +#include +#include +#include +#include "leveldb/slice.h" +#include "util/hash.h" + +namespace leveldb { + +class FilterPolicy; + +// A FilterBlockBuilder is used to construct all of the filters for a +// particular Table. It generates a single string which is stored as +// a special block in the Table. +// +// The sequence of calls to FilterBlockBuilder must match the regexp: +// (StartBlock AddKey*)* Finish +class FilterBlockBuilder { + public: + explicit FilterBlockBuilder(const FilterPolicy*); + + void StartBlock(uint64_t block_offset); + void AddKey(const Slice& key); + Slice Finish(); + + private: + void GenerateFilter(); + + const FilterPolicy* policy_; + std::string keys_; // Flattened key contents + std::vector start_; // Starting index in keys_ of each key + std::string result_; // Filter data computed so far + std::vector tmp_keys_; // policy_->CreateFilter() argument + std::vector filter_offsets_; + + // No copying allowed + FilterBlockBuilder(const FilterBlockBuilder&); + void operator=(const FilterBlockBuilder&); +}; + +class FilterBlockReader { + public: + // REQUIRES: "contents" and *policy must stay live while *this is live. + FilterBlockReader(const FilterPolicy* policy, const Slice& contents); + bool KeyMayMatch(uint64_t block_offset, const Slice& key); + + private: + const FilterPolicy* policy_; + const char* data_; // Pointer to filter data (at block-start) + const char* offset_; // Pointer to beginning of offset array (at block-end) + size_t num_; // Number of entries in offset array + size_t base_lg_; // Encoding parameter (see kFilterBaseLg in .cc file) +}; + +} + +#endif // STORAGE_LEVELDB_TABLE_FILTER_BLOCK_H_ diff --git a/ios/Pods/leveldb-library/table/format.cc b/ios/Pods/leveldb-library/table/format.cc new file mode 100644 index 00000000..24e4e024 --- /dev/null +++ b/ios/Pods/leveldb-library/table/format.cc @@ -0,0 +1,144 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "table/format.h" + +#include "leveldb/env.h" +#include "port/port.h" +#include "table/block.h" +#include "util/coding.h" +#include "util/crc32c.h" + +namespace leveldb { + +void BlockHandle::EncodeTo(std::string* dst) const { + // Sanity check that all fields have been set + assert(offset_ != ~static_cast(0)); + assert(size_ != ~static_cast(0)); + PutVarint64(dst, offset_); + PutVarint64(dst, size_); +} + +Status BlockHandle::DecodeFrom(Slice* input) { + if (GetVarint64(input, &offset_) && + GetVarint64(input, &size_)) { + return Status::OK(); + } else { + return Status::Corruption("bad block handle"); + } +} + +void Footer::EncodeTo(std::string* dst) const { + const size_t original_size = dst->size(); + metaindex_handle_.EncodeTo(dst); + index_handle_.EncodeTo(dst); + dst->resize(2 * BlockHandle::kMaxEncodedLength); // Padding + PutFixed32(dst, static_cast(kTableMagicNumber & 0xffffffffu)); + PutFixed32(dst, static_cast(kTableMagicNumber >> 32)); + assert(dst->size() == original_size + kEncodedLength); + (void)original_size; // Disable unused variable warning. +} + +Status Footer::DecodeFrom(Slice* input) { + const char* magic_ptr = input->data() + kEncodedLength - 8; + const uint32_t magic_lo = DecodeFixed32(magic_ptr); + const uint32_t magic_hi = DecodeFixed32(magic_ptr + 4); + const uint64_t magic = ((static_cast(magic_hi) << 32) | + (static_cast(magic_lo))); + if (magic != kTableMagicNumber) { + return Status::Corruption("not an sstable (bad magic number)"); + } + + Status result = metaindex_handle_.DecodeFrom(input); + if (result.ok()) { + result = index_handle_.DecodeFrom(input); + } + if (result.ok()) { + // We skip over any leftover data (just padding for now) in "input" + const char* end = magic_ptr + 8; + *input = Slice(end, input->data() + input->size() - end); + } + return result; +} + +Status ReadBlock(RandomAccessFile* file, + const ReadOptions& options, + const BlockHandle& handle, + BlockContents* result) { + result->data = Slice(); + result->cachable = false; + result->heap_allocated = false; + + // Read the block contents as well as the type/crc footer. + // See table_builder.cc for the code that built this structure. + size_t n = static_cast(handle.size()); + char* buf = new char[n + kBlockTrailerSize]; + Slice contents; + Status s = file->Read(handle.offset(), n + kBlockTrailerSize, &contents, buf); + if (!s.ok()) { + delete[] buf; + return s; + } + if (contents.size() != n + kBlockTrailerSize) { + delete[] buf; + return Status::Corruption("truncated block read"); + } + + // Check the crc of the type and the block contents + const char* data = contents.data(); // Pointer to where Read put the data + if (options.verify_checksums) { + const uint32_t crc = crc32c::Unmask(DecodeFixed32(data + n + 1)); + const uint32_t actual = crc32c::Value(data, n + 1); + if (actual != crc) { + delete[] buf; + s = Status::Corruption("block checksum mismatch"); + return s; + } + } + + switch (data[n]) { + case kNoCompression: + if (data != buf) { + // File implementation gave us pointer to some other data. + // Use it directly under the assumption that it will be live + // while the file is open. + delete[] buf; + result->data = Slice(data, n); + result->heap_allocated = false; + result->cachable = false; // Do not double-cache + } else { + result->data = Slice(buf, n); + result->heap_allocated = true; + result->cachable = true; + } + + // Ok + break; + case kSnappyCompression: { + size_t ulength = 0; + if (!port::Snappy_GetUncompressedLength(data, n, &ulength)) { + delete[] buf; + return Status::Corruption("corrupted compressed block contents"); + } + char* ubuf = new char[ulength]; + if (!port::Snappy_Uncompress(data, n, ubuf)) { + delete[] buf; + delete[] ubuf; + return Status::Corruption("corrupted compressed block contents"); + } + delete[] buf; + result->data = Slice(ubuf, ulength); + result->heap_allocated = true; + result->cachable = true; + break; + } + default: + delete[] buf; + return Status::Corruption("bad block type"); + } + + return Status::OK(); +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/table/format.h b/ios/Pods/leveldb-library/table/format.h new file mode 100644 index 00000000..6c0b80c0 --- /dev/null +++ b/ios/Pods/leveldb-library/table/format.h @@ -0,0 +1,108 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_TABLE_FORMAT_H_ +#define STORAGE_LEVELDB_TABLE_FORMAT_H_ + +#include +#include +#include "leveldb/slice.h" +#include "leveldb/status.h" +#include "leveldb/table_builder.h" + +namespace leveldb { + +class Block; +class RandomAccessFile; +struct ReadOptions; + +// BlockHandle is a pointer to the extent of a file that stores a data +// block or a meta block. +class BlockHandle { + public: + BlockHandle(); + + // The offset of the block in the file. + uint64_t offset() const { return offset_; } + void set_offset(uint64_t offset) { offset_ = offset; } + + // The size of the stored block + uint64_t size() const { return size_; } + void set_size(uint64_t size) { size_ = size; } + + void EncodeTo(std::string* dst) const; + Status DecodeFrom(Slice* input); + + // Maximum encoding length of a BlockHandle + enum { kMaxEncodedLength = 10 + 10 }; + + private: + uint64_t offset_; + uint64_t size_; +}; + +// Footer encapsulates the fixed information stored at the tail +// end of every table file. +class Footer { + public: + Footer() { } + + // The block handle for the metaindex block of the table + const BlockHandle& metaindex_handle() const { return metaindex_handle_; } + void set_metaindex_handle(const BlockHandle& h) { metaindex_handle_ = h; } + + // The block handle for the index block of the table + const BlockHandle& index_handle() const { + return index_handle_; + } + void set_index_handle(const BlockHandle& h) { + index_handle_ = h; + } + + void EncodeTo(std::string* dst) const; + Status DecodeFrom(Slice* input); + + // Encoded length of a Footer. Note that the serialization of a + // Footer will always occupy exactly this many bytes. It consists + // of two block handles and a magic number. + enum { + kEncodedLength = 2*BlockHandle::kMaxEncodedLength + 8 + }; + + private: + BlockHandle metaindex_handle_; + BlockHandle index_handle_; +}; + +// kTableMagicNumber was picked by running +// echo http://code.google.com/p/leveldb/ | sha1sum +// and taking the leading 64 bits. +static const uint64_t kTableMagicNumber = 0xdb4775248b80fb57ull; + +// 1-byte type + 32-bit crc +static const size_t kBlockTrailerSize = 5; + +struct BlockContents { + Slice data; // Actual contents of data + bool cachable; // True iff data can be cached + bool heap_allocated; // True iff caller should delete[] data.data() +}; + +// Read the block identified by "handle" from "file". On failure +// return non-OK. On success fill *result and return OK. +extern Status ReadBlock(RandomAccessFile* file, + const ReadOptions& options, + const BlockHandle& handle, + BlockContents* result); + +// Implementation details follow. Clients should ignore, + +inline BlockHandle::BlockHandle() + : offset_(~static_cast(0)), + size_(~static_cast(0)) { +} + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_TABLE_FORMAT_H_ diff --git a/ios/Pods/leveldb-library/table/iterator.cc b/ios/Pods/leveldb-library/table/iterator.cc new file mode 100644 index 00000000..3d1c87fd --- /dev/null +++ b/ios/Pods/leveldb-library/table/iterator.cc @@ -0,0 +1,67 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "leveldb/iterator.h" + +namespace leveldb { + +Iterator::Iterator() { + cleanup_.function = NULL; + cleanup_.next = NULL; +} + +Iterator::~Iterator() { + if (cleanup_.function != NULL) { + (*cleanup_.function)(cleanup_.arg1, cleanup_.arg2); + for (Cleanup* c = cleanup_.next; c != NULL; ) { + (*c->function)(c->arg1, c->arg2); + Cleanup* next = c->next; + delete c; + c = next; + } + } +} + +void Iterator::RegisterCleanup(CleanupFunction func, void* arg1, void* arg2) { + assert(func != NULL); + Cleanup* c; + if (cleanup_.function == NULL) { + c = &cleanup_; + } else { + c = new Cleanup; + c->next = cleanup_.next; + cleanup_.next = c; + } + c->function = func; + c->arg1 = arg1; + c->arg2 = arg2; +} + +namespace { +class EmptyIterator : public Iterator { + public: + EmptyIterator(const Status& s) : status_(s) { } + virtual bool Valid() const { return false; } + virtual void Seek(const Slice& target) { } + virtual void SeekToFirst() { } + virtual void SeekToLast() { } + virtual void Next() { assert(false); } + virtual void Prev() { assert(false); } + Slice key() const { assert(false); return Slice(); } + Slice value() const { assert(false); return Slice(); } + virtual Status status() const { return status_; } + private: + Status status_; +}; +} // namespace + +Iterator* NewEmptyIterator() { + return new EmptyIterator(Status::OK()); +} + +Iterator* NewErrorIterator(const Status& status) { + return new EmptyIterator(status); +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/table/iterator_wrapper.h b/ios/Pods/leveldb-library/table/iterator_wrapper.h new file mode 100644 index 00000000..f410c3fa --- /dev/null +++ b/ios/Pods/leveldb-library/table/iterator_wrapper.h @@ -0,0 +1,66 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_TABLE_ITERATOR_WRAPPER_H_ +#define STORAGE_LEVELDB_TABLE_ITERATOR_WRAPPER_H_ + +#include "leveldb/iterator.h" +#include "leveldb/slice.h" + +namespace leveldb { + +// A internal wrapper class with an interface similar to Iterator that +// caches the valid() and key() results for an underlying iterator. +// This can help avoid virtual function calls and also gives better +// cache locality. +class IteratorWrapper { + public: + IteratorWrapper(): iter_(NULL), valid_(false) { } + explicit IteratorWrapper(Iterator* iter): iter_(NULL) { + Set(iter); + } + ~IteratorWrapper() { delete iter_; } + Iterator* iter() const { return iter_; } + + // Takes ownership of "iter" and will delete it when destroyed, or + // when Set() is invoked again. + void Set(Iterator* iter) { + delete iter_; + iter_ = iter; + if (iter_ == NULL) { + valid_ = false; + } else { + Update(); + } + } + + + // Iterator interface methods + bool Valid() const { return valid_; } + Slice key() const { assert(Valid()); return key_; } + Slice value() const { assert(Valid()); return iter_->value(); } + // Methods below require iter() != NULL + Status status() const { assert(iter_); return iter_->status(); } + void Next() { assert(iter_); iter_->Next(); Update(); } + void Prev() { assert(iter_); iter_->Prev(); Update(); } + void Seek(const Slice& k) { assert(iter_); iter_->Seek(k); Update(); } + void SeekToFirst() { assert(iter_); iter_->SeekToFirst(); Update(); } + void SeekToLast() { assert(iter_); iter_->SeekToLast(); Update(); } + + private: + void Update() { + valid_ = iter_->Valid(); + if (valid_) { + key_ = iter_->key(); + } + } + + Iterator* iter_; + bool valid_; + Slice key_; +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_TABLE_ITERATOR_WRAPPER_H_ diff --git a/ios/Pods/leveldb-library/table/merger.cc b/ios/Pods/leveldb-library/table/merger.cc new file mode 100644 index 00000000..2dde4dc2 --- /dev/null +++ b/ios/Pods/leveldb-library/table/merger.cc @@ -0,0 +1,197 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "table/merger.h" + +#include "leveldb/comparator.h" +#include "leveldb/iterator.h" +#include "table/iterator_wrapper.h" + +namespace leveldb { + +namespace { +class MergingIterator : public Iterator { + public: + MergingIterator(const Comparator* comparator, Iterator** children, int n) + : comparator_(comparator), + children_(new IteratorWrapper[n]), + n_(n), + current_(NULL), + direction_(kForward) { + for (int i = 0; i < n; i++) { + children_[i].Set(children[i]); + } + } + + virtual ~MergingIterator() { + delete[] children_; + } + + virtual bool Valid() const { + return (current_ != NULL); + } + + virtual void SeekToFirst() { + for (int i = 0; i < n_; i++) { + children_[i].SeekToFirst(); + } + FindSmallest(); + direction_ = kForward; + } + + virtual void SeekToLast() { + for (int i = 0; i < n_; i++) { + children_[i].SeekToLast(); + } + FindLargest(); + direction_ = kReverse; + } + + virtual void Seek(const Slice& target) { + for (int i = 0; i < n_; i++) { + children_[i].Seek(target); + } + FindSmallest(); + direction_ = kForward; + } + + virtual void Next() { + assert(Valid()); + + // Ensure that all children are positioned after key(). + // If we are moving in the forward direction, it is already + // true for all of the non-current_ children since current_ is + // the smallest child and key() == current_->key(). Otherwise, + // we explicitly position the non-current_ children. + if (direction_ != kForward) { + for (int i = 0; i < n_; i++) { + IteratorWrapper* child = &children_[i]; + if (child != current_) { + child->Seek(key()); + if (child->Valid() && + comparator_->Compare(key(), child->key()) == 0) { + child->Next(); + } + } + } + direction_ = kForward; + } + + current_->Next(); + FindSmallest(); + } + + virtual void Prev() { + assert(Valid()); + + // Ensure that all children are positioned before key(). + // If we are moving in the reverse direction, it is already + // true for all of the non-current_ children since current_ is + // the largest child and key() == current_->key(). Otherwise, + // we explicitly position the non-current_ children. + if (direction_ != kReverse) { + for (int i = 0; i < n_; i++) { + IteratorWrapper* child = &children_[i]; + if (child != current_) { + child->Seek(key()); + if (child->Valid()) { + // Child is at first entry >= key(). Step back one to be < key() + child->Prev(); + } else { + // Child has no entries >= key(). Position at last entry. + child->SeekToLast(); + } + } + } + direction_ = kReverse; + } + + current_->Prev(); + FindLargest(); + } + + virtual Slice key() const { + assert(Valid()); + return current_->key(); + } + + virtual Slice value() const { + assert(Valid()); + return current_->value(); + } + + virtual Status status() const { + Status status; + for (int i = 0; i < n_; i++) { + status = children_[i].status(); + if (!status.ok()) { + break; + } + } + return status; + } + + private: + void FindSmallest(); + void FindLargest(); + + // We might want to use a heap in case there are lots of children. + // For now we use a simple array since we expect a very small number + // of children in leveldb. + const Comparator* comparator_; + IteratorWrapper* children_; + int n_; + IteratorWrapper* current_; + + // Which direction is the iterator moving? + enum Direction { + kForward, + kReverse + }; + Direction direction_; +}; + +void MergingIterator::FindSmallest() { + IteratorWrapper* smallest = NULL; + for (int i = 0; i < n_; i++) { + IteratorWrapper* child = &children_[i]; + if (child->Valid()) { + if (smallest == NULL) { + smallest = child; + } else if (comparator_->Compare(child->key(), smallest->key()) < 0) { + smallest = child; + } + } + } + current_ = smallest; +} + +void MergingIterator::FindLargest() { + IteratorWrapper* largest = NULL; + for (int i = n_-1; i >= 0; i--) { + IteratorWrapper* child = &children_[i]; + if (child->Valid()) { + if (largest == NULL) { + largest = child; + } else if (comparator_->Compare(child->key(), largest->key()) > 0) { + largest = child; + } + } + } + current_ = largest; +} +} // namespace + +Iterator* NewMergingIterator(const Comparator* cmp, Iterator** list, int n) { + assert(n >= 0); + if (n == 0) { + return NewEmptyIterator(); + } else if (n == 1) { + return list[0]; + } else { + return new MergingIterator(cmp, list, n); + } +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/table/merger.h b/ios/Pods/leveldb-library/table/merger.h new file mode 100644 index 00000000..91ddd80f --- /dev/null +++ b/ios/Pods/leveldb-library/table/merger.h @@ -0,0 +1,26 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_TABLE_MERGER_H_ +#define STORAGE_LEVELDB_TABLE_MERGER_H_ + +namespace leveldb { + +class Comparator; +class Iterator; + +// Return an iterator that provided the union of the data in +// children[0,n-1]. Takes ownership of the child iterators and +// will delete them when the result iterator is deleted. +// +// The result does no duplicate suppression. I.e., if a particular +// key is present in K child iterators, it will be yielded K times. +// +// REQUIRES: n >= 0 +extern Iterator* NewMergingIterator( + const Comparator* comparator, Iterator** children, int n); + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_TABLE_MERGER_H_ diff --git a/ios/Pods/leveldb-library/table/table.cc b/ios/Pods/leveldb-library/table/table.cc new file mode 100644 index 00000000..decf8082 --- /dev/null +++ b/ios/Pods/leveldb-library/table/table.cc @@ -0,0 +1,285 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "leveldb/table.h" + +#include "leveldb/cache.h" +#include "leveldb/comparator.h" +#include "leveldb/env.h" +#include "leveldb/filter_policy.h" +#include "leveldb/options.h" +#include "table/block.h" +#include "table/filter_block.h" +#include "table/format.h" +#include "table/two_level_iterator.h" +#include "util/coding.h" + +namespace leveldb { + +struct Table::Rep { + ~Rep() { + delete filter; + delete [] filter_data; + delete index_block; + } + + Options options; + Status status; + RandomAccessFile* file; + uint64_t cache_id; + FilterBlockReader* filter; + const char* filter_data; + + BlockHandle metaindex_handle; // Handle to metaindex_block: saved from footer + Block* index_block; +}; + +Status Table::Open(const Options& options, + RandomAccessFile* file, + uint64_t size, + Table** table) { + *table = NULL; + if (size < Footer::kEncodedLength) { + return Status::Corruption("file is too short to be an sstable"); + } + + char footer_space[Footer::kEncodedLength]; + Slice footer_input; + Status s = file->Read(size - Footer::kEncodedLength, Footer::kEncodedLength, + &footer_input, footer_space); + if (!s.ok()) return s; + + Footer footer; + s = footer.DecodeFrom(&footer_input); + if (!s.ok()) return s; + + // Read the index block + BlockContents contents; + Block* index_block = NULL; + if (s.ok()) { + ReadOptions opt; + if (options.paranoid_checks) { + opt.verify_checksums = true; + } + s = ReadBlock(file, opt, footer.index_handle(), &contents); + if (s.ok()) { + index_block = new Block(contents); + } + } + + if (s.ok()) { + // We've successfully read the footer and the index block: we're + // ready to serve requests. + Rep* rep = new Table::Rep; + rep->options = options; + rep->file = file; + rep->metaindex_handle = footer.metaindex_handle(); + rep->index_block = index_block; + rep->cache_id = (options.block_cache ? options.block_cache->NewId() : 0); + rep->filter_data = NULL; + rep->filter = NULL; + *table = new Table(rep); + (*table)->ReadMeta(footer); + } else { + delete index_block; + } + + return s; +} + +void Table::ReadMeta(const Footer& footer) { + if (rep_->options.filter_policy == NULL) { + return; // Do not need any metadata + } + + // TODO(sanjay): Skip this if footer.metaindex_handle() size indicates + // it is an empty block. + ReadOptions opt; + if (rep_->options.paranoid_checks) { + opt.verify_checksums = true; + } + BlockContents contents; + if (!ReadBlock(rep_->file, opt, footer.metaindex_handle(), &contents).ok()) { + // Do not propagate errors since meta info is not needed for operation + return; + } + Block* meta = new Block(contents); + + Iterator* iter = meta->NewIterator(BytewiseComparator()); + std::string key = "filter."; + key.append(rep_->options.filter_policy->Name()); + iter->Seek(key); + if (iter->Valid() && iter->key() == Slice(key)) { + ReadFilter(iter->value()); + } + delete iter; + delete meta; +} + +void Table::ReadFilter(const Slice& filter_handle_value) { + Slice v = filter_handle_value; + BlockHandle filter_handle; + if (!filter_handle.DecodeFrom(&v).ok()) { + return; + } + + // We might want to unify with ReadBlock() if we start + // requiring checksum verification in Table::Open. + ReadOptions opt; + if (rep_->options.paranoid_checks) { + opt.verify_checksums = true; + } + BlockContents block; + if (!ReadBlock(rep_->file, opt, filter_handle, &block).ok()) { + return; + } + if (block.heap_allocated) { + rep_->filter_data = block.data.data(); // Will need to delete later + } + rep_->filter = new FilterBlockReader(rep_->options.filter_policy, block.data); +} + +Table::~Table() { + delete rep_; +} + +static void DeleteBlock(void* arg, void* ignored) { + delete reinterpret_cast(arg); +} + +static void DeleteCachedBlock(const Slice& key, void* value) { + Block* block = reinterpret_cast(value); + delete block; +} + +static void ReleaseBlock(void* arg, void* h) { + Cache* cache = reinterpret_cast(arg); + Cache::Handle* handle = reinterpret_cast(h); + cache->Release(handle); +} + +// Convert an index iterator value (i.e., an encoded BlockHandle) +// into an iterator over the contents of the corresponding block. +Iterator* Table::BlockReader(void* arg, + const ReadOptions& options, + const Slice& index_value) { + Table* table = reinterpret_cast(arg); + Cache* block_cache = table->rep_->options.block_cache; + Block* block = NULL; + Cache::Handle* cache_handle = NULL; + + BlockHandle handle; + Slice input = index_value; + Status s = handle.DecodeFrom(&input); + // We intentionally allow extra stuff in index_value so that we + // can add more features in the future. + + if (s.ok()) { + BlockContents contents; + if (block_cache != NULL) { + char cache_key_buffer[16]; + EncodeFixed64(cache_key_buffer, table->rep_->cache_id); + EncodeFixed64(cache_key_buffer+8, handle.offset()); + Slice key(cache_key_buffer, sizeof(cache_key_buffer)); + cache_handle = block_cache->Lookup(key); + if (cache_handle != NULL) { + block = reinterpret_cast(block_cache->Value(cache_handle)); + } else { + s = ReadBlock(table->rep_->file, options, handle, &contents); + if (s.ok()) { + block = new Block(contents); + if (contents.cachable && options.fill_cache) { + cache_handle = block_cache->Insert( + key, block, block->size(), &DeleteCachedBlock); + } + } + } + } else { + s = ReadBlock(table->rep_->file, options, handle, &contents); + if (s.ok()) { + block = new Block(contents); + } + } + } + + Iterator* iter; + if (block != NULL) { + iter = block->NewIterator(table->rep_->options.comparator); + if (cache_handle == NULL) { + iter->RegisterCleanup(&DeleteBlock, block, NULL); + } else { + iter->RegisterCleanup(&ReleaseBlock, block_cache, cache_handle); + } + } else { + iter = NewErrorIterator(s); + } + return iter; +} + +Iterator* Table::NewIterator(const ReadOptions& options) const { + return NewTwoLevelIterator( + rep_->index_block->NewIterator(rep_->options.comparator), + &Table::BlockReader, const_cast(this), options); +} + +Status Table::InternalGet(const ReadOptions& options, const Slice& k, + void* arg, + void (*saver)(void*, const Slice&, const Slice&)) { + Status s; + Iterator* iiter = rep_->index_block->NewIterator(rep_->options.comparator); + iiter->Seek(k); + if (iiter->Valid()) { + Slice handle_value = iiter->value(); + FilterBlockReader* filter = rep_->filter; + BlockHandle handle; + if (filter != NULL && + handle.DecodeFrom(&handle_value).ok() && + !filter->KeyMayMatch(handle.offset(), k)) { + // Not found + } else { + Iterator* block_iter = BlockReader(this, options, iiter->value()); + block_iter->Seek(k); + if (block_iter->Valid()) { + (*saver)(arg, block_iter->key(), block_iter->value()); + } + s = block_iter->status(); + delete block_iter; + } + } + if (s.ok()) { + s = iiter->status(); + } + delete iiter; + return s; +} + + +uint64_t Table::ApproximateOffsetOf(const Slice& key) const { + Iterator* index_iter = + rep_->index_block->NewIterator(rep_->options.comparator); + index_iter->Seek(key); + uint64_t result; + if (index_iter->Valid()) { + BlockHandle handle; + Slice input = index_iter->value(); + Status s = handle.DecodeFrom(&input); + if (s.ok()) { + result = handle.offset(); + } else { + // Strange: we can't decode the block handle in the index block. + // We'll just return the offset of the metaindex block, which is + // close to the whole file size for this case. + result = rep_->metaindex_handle.offset(); + } + } else { + // key is past the last key in the file. Approximate the offset + // by returning the offset of the metaindex block (which is + // right near the end of the file). + result = rep_->metaindex_handle.offset(); + } + delete index_iter; + return result; +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/table/table_builder.cc b/ios/Pods/leveldb-library/table/table_builder.cc new file mode 100644 index 00000000..62002c84 --- /dev/null +++ b/ios/Pods/leveldb-library/table/table_builder.cc @@ -0,0 +1,270 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "leveldb/table_builder.h" + +#include +#include "leveldb/comparator.h" +#include "leveldb/env.h" +#include "leveldb/filter_policy.h" +#include "leveldb/options.h" +#include "table/block_builder.h" +#include "table/filter_block.h" +#include "table/format.h" +#include "util/coding.h" +#include "util/crc32c.h" + +namespace leveldb { + +struct TableBuilder::Rep { + Options options; + Options index_block_options; + WritableFile* file; + uint64_t offset; + Status status; + BlockBuilder data_block; + BlockBuilder index_block; + std::string last_key; + int64_t num_entries; + bool closed; // Either Finish() or Abandon() has been called. + FilterBlockBuilder* filter_block; + + // We do not emit the index entry for a block until we have seen the + // first key for the next data block. This allows us to use shorter + // keys in the index block. For example, consider a block boundary + // between the keys "the quick brown fox" and "the who". We can use + // "the r" as the key for the index block entry since it is >= all + // entries in the first block and < all entries in subsequent + // blocks. + // + // Invariant: r->pending_index_entry is true only if data_block is empty. + bool pending_index_entry; + BlockHandle pending_handle; // Handle to add to index block + + std::string compressed_output; + + Rep(const Options& opt, WritableFile* f) + : options(opt), + index_block_options(opt), + file(f), + offset(0), + data_block(&options), + index_block(&index_block_options), + num_entries(0), + closed(false), + filter_block(opt.filter_policy == NULL ? NULL + : new FilterBlockBuilder(opt.filter_policy)), + pending_index_entry(false) { + index_block_options.block_restart_interval = 1; + } +}; + +TableBuilder::TableBuilder(const Options& options, WritableFile* file) + : rep_(new Rep(options, file)) { + if (rep_->filter_block != NULL) { + rep_->filter_block->StartBlock(0); + } +} + +TableBuilder::~TableBuilder() { + assert(rep_->closed); // Catch errors where caller forgot to call Finish() + delete rep_->filter_block; + delete rep_; +} + +Status TableBuilder::ChangeOptions(const Options& options) { + // Note: if more fields are added to Options, update + // this function to catch changes that should not be allowed to + // change in the middle of building a Table. + if (options.comparator != rep_->options.comparator) { + return Status::InvalidArgument("changing comparator while building table"); + } + + // Note that any live BlockBuilders point to rep_->options and therefore + // will automatically pick up the updated options. + rep_->options = options; + rep_->index_block_options = options; + rep_->index_block_options.block_restart_interval = 1; + return Status::OK(); +} + +void TableBuilder::Add(const Slice& key, const Slice& value) { + Rep* r = rep_; + assert(!r->closed); + if (!ok()) return; + if (r->num_entries > 0) { + assert(r->options.comparator->Compare(key, Slice(r->last_key)) > 0); + } + + if (r->pending_index_entry) { + assert(r->data_block.empty()); + r->options.comparator->FindShortestSeparator(&r->last_key, key); + std::string handle_encoding; + r->pending_handle.EncodeTo(&handle_encoding); + r->index_block.Add(r->last_key, Slice(handle_encoding)); + r->pending_index_entry = false; + } + + if (r->filter_block != NULL) { + r->filter_block->AddKey(key); + } + + r->last_key.assign(key.data(), key.size()); + r->num_entries++; + r->data_block.Add(key, value); + + const size_t estimated_block_size = r->data_block.CurrentSizeEstimate(); + if (estimated_block_size >= r->options.block_size) { + Flush(); + } +} + +void TableBuilder::Flush() { + Rep* r = rep_; + assert(!r->closed); + if (!ok()) return; + if (r->data_block.empty()) return; + assert(!r->pending_index_entry); + WriteBlock(&r->data_block, &r->pending_handle); + if (ok()) { + r->pending_index_entry = true; + r->status = r->file->Flush(); + } + if (r->filter_block != NULL) { + r->filter_block->StartBlock(r->offset); + } +} + +void TableBuilder::WriteBlock(BlockBuilder* block, BlockHandle* handle) { + // File format contains a sequence of blocks where each block has: + // block_data: uint8[n] + // type: uint8 + // crc: uint32 + assert(ok()); + Rep* r = rep_; + Slice raw = block->Finish(); + + Slice block_contents; + CompressionType type = r->options.compression; + // TODO(postrelease): Support more compression options: zlib? + switch (type) { + case kNoCompression: + block_contents = raw; + break; + + case kSnappyCompression: { + std::string* compressed = &r->compressed_output; + if (port::Snappy_Compress(raw.data(), raw.size(), compressed) && + compressed->size() < raw.size() - (raw.size() / 8u)) { + block_contents = *compressed; + } else { + // Snappy not supported, or compressed less than 12.5%, so just + // store uncompressed form + block_contents = raw; + type = kNoCompression; + } + break; + } + } + WriteRawBlock(block_contents, type, handle); + r->compressed_output.clear(); + block->Reset(); +} + +void TableBuilder::WriteRawBlock(const Slice& block_contents, + CompressionType type, + BlockHandle* handle) { + Rep* r = rep_; + handle->set_offset(r->offset); + handle->set_size(block_contents.size()); + r->status = r->file->Append(block_contents); + if (r->status.ok()) { + char trailer[kBlockTrailerSize]; + trailer[0] = type; + uint32_t crc = crc32c::Value(block_contents.data(), block_contents.size()); + crc = crc32c::Extend(crc, trailer, 1); // Extend crc to cover block type + EncodeFixed32(trailer+1, crc32c::Mask(crc)); + r->status = r->file->Append(Slice(trailer, kBlockTrailerSize)); + if (r->status.ok()) { + r->offset += block_contents.size() + kBlockTrailerSize; + } + } +} + +Status TableBuilder::status() const { + return rep_->status; +} + +Status TableBuilder::Finish() { + Rep* r = rep_; + Flush(); + assert(!r->closed); + r->closed = true; + + BlockHandle filter_block_handle, metaindex_block_handle, index_block_handle; + + // Write filter block + if (ok() && r->filter_block != NULL) { + WriteRawBlock(r->filter_block->Finish(), kNoCompression, + &filter_block_handle); + } + + // Write metaindex block + if (ok()) { + BlockBuilder meta_index_block(&r->options); + if (r->filter_block != NULL) { + // Add mapping from "filter.Name" to location of filter data + std::string key = "filter."; + key.append(r->options.filter_policy->Name()); + std::string handle_encoding; + filter_block_handle.EncodeTo(&handle_encoding); + meta_index_block.Add(key, handle_encoding); + } + + // TODO(postrelease): Add stats and other meta blocks + WriteBlock(&meta_index_block, &metaindex_block_handle); + } + + // Write index block + if (ok()) { + if (r->pending_index_entry) { + r->options.comparator->FindShortSuccessor(&r->last_key); + std::string handle_encoding; + r->pending_handle.EncodeTo(&handle_encoding); + r->index_block.Add(r->last_key, Slice(handle_encoding)); + r->pending_index_entry = false; + } + WriteBlock(&r->index_block, &index_block_handle); + } + + // Write footer + if (ok()) { + Footer footer; + footer.set_metaindex_handle(metaindex_block_handle); + footer.set_index_handle(index_block_handle); + std::string footer_encoding; + footer.EncodeTo(&footer_encoding); + r->status = r->file->Append(footer_encoding); + if (r->status.ok()) { + r->offset += footer_encoding.size(); + } + } + return r->status; +} + +void TableBuilder::Abandon() { + Rep* r = rep_; + assert(!r->closed); + r->closed = true; +} + +uint64_t TableBuilder::NumEntries() const { + return rep_->num_entries; +} + +uint64_t TableBuilder::FileSize() const { + return rep_->offset; +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/table/two_level_iterator.cc b/ios/Pods/leveldb-library/table/two_level_iterator.cc new file mode 100644 index 00000000..7822ebab --- /dev/null +++ b/ios/Pods/leveldb-library/table/two_level_iterator.cc @@ -0,0 +1,182 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "table/two_level_iterator.h" + +#include "leveldb/table.h" +#include "table/block.h" +#include "table/format.h" +#include "table/iterator_wrapper.h" + +namespace leveldb { + +namespace { + +typedef Iterator* (*BlockFunction)(void*, const ReadOptions&, const Slice&); + +class TwoLevelIterator: public Iterator { + public: + TwoLevelIterator( + Iterator* index_iter, + BlockFunction block_function, + void* arg, + const ReadOptions& options); + + virtual ~TwoLevelIterator(); + + virtual void Seek(const Slice& target); + virtual void SeekToFirst(); + virtual void SeekToLast(); + virtual void Next(); + virtual void Prev(); + + virtual bool Valid() const { + return data_iter_.Valid(); + } + virtual Slice key() const { + assert(Valid()); + return data_iter_.key(); + } + virtual Slice value() const { + assert(Valid()); + return data_iter_.value(); + } + virtual Status status() const { + // It'd be nice if status() returned a const Status& instead of a Status + if (!index_iter_.status().ok()) { + return index_iter_.status(); + } else if (data_iter_.iter() != NULL && !data_iter_.status().ok()) { + return data_iter_.status(); + } else { + return status_; + } + } + + private: + void SaveError(const Status& s) { + if (status_.ok() && !s.ok()) status_ = s; + } + void SkipEmptyDataBlocksForward(); + void SkipEmptyDataBlocksBackward(); + void SetDataIterator(Iterator* data_iter); + void InitDataBlock(); + + BlockFunction block_function_; + void* arg_; + const ReadOptions options_; + Status status_; + IteratorWrapper index_iter_; + IteratorWrapper data_iter_; // May be NULL + // If data_iter_ is non-NULL, then "data_block_handle_" holds the + // "index_value" passed to block_function_ to create the data_iter_. + std::string data_block_handle_; +}; + +TwoLevelIterator::TwoLevelIterator( + Iterator* index_iter, + BlockFunction block_function, + void* arg, + const ReadOptions& options) + : block_function_(block_function), + arg_(arg), + options_(options), + index_iter_(index_iter), + data_iter_(NULL) { +} + +TwoLevelIterator::~TwoLevelIterator() { +} + +void TwoLevelIterator::Seek(const Slice& target) { + index_iter_.Seek(target); + InitDataBlock(); + if (data_iter_.iter() != NULL) data_iter_.Seek(target); + SkipEmptyDataBlocksForward(); +} + +void TwoLevelIterator::SeekToFirst() { + index_iter_.SeekToFirst(); + InitDataBlock(); + if (data_iter_.iter() != NULL) data_iter_.SeekToFirst(); + SkipEmptyDataBlocksForward(); +} + +void TwoLevelIterator::SeekToLast() { + index_iter_.SeekToLast(); + InitDataBlock(); + if (data_iter_.iter() != NULL) data_iter_.SeekToLast(); + SkipEmptyDataBlocksBackward(); +} + +void TwoLevelIterator::Next() { + assert(Valid()); + data_iter_.Next(); + SkipEmptyDataBlocksForward(); +} + +void TwoLevelIterator::Prev() { + assert(Valid()); + data_iter_.Prev(); + SkipEmptyDataBlocksBackward(); +} + + +void TwoLevelIterator::SkipEmptyDataBlocksForward() { + while (data_iter_.iter() == NULL || !data_iter_.Valid()) { + // Move to next block + if (!index_iter_.Valid()) { + SetDataIterator(NULL); + return; + } + index_iter_.Next(); + InitDataBlock(); + if (data_iter_.iter() != NULL) data_iter_.SeekToFirst(); + } +} + +void TwoLevelIterator::SkipEmptyDataBlocksBackward() { + while (data_iter_.iter() == NULL || !data_iter_.Valid()) { + // Move to next block + if (!index_iter_.Valid()) { + SetDataIterator(NULL); + return; + } + index_iter_.Prev(); + InitDataBlock(); + if (data_iter_.iter() != NULL) data_iter_.SeekToLast(); + } +} + +void TwoLevelIterator::SetDataIterator(Iterator* data_iter) { + if (data_iter_.iter() != NULL) SaveError(data_iter_.status()); + data_iter_.Set(data_iter); +} + +void TwoLevelIterator::InitDataBlock() { + if (!index_iter_.Valid()) { + SetDataIterator(NULL); + } else { + Slice handle = index_iter_.value(); + if (data_iter_.iter() != NULL && handle.compare(data_block_handle_) == 0) { + // data_iter_ is already constructed with this iterator, so + // no need to change anything + } else { + Iterator* iter = (*block_function_)(arg_, options_, handle); + data_block_handle_.assign(handle.data(), handle.size()); + SetDataIterator(iter); + } + } +} + +} // namespace + +Iterator* NewTwoLevelIterator( + Iterator* index_iter, + BlockFunction block_function, + void* arg, + const ReadOptions& options) { + return new TwoLevelIterator(index_iter, block_function, arg, options); +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/table/two_level_iterator.h b/ios/Pods/leveldb-library/table/two_level_iterator.h new file mode 100644 index 00000000..629ca345 --- /dev/null +++ b/ios/Pods/leveldb-library/table/two_level_iterator.h @@ -0,0 +1,34 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_TABLE_TWO_LEVEL_ITERATOR_H_ +#define STORAGE_LEVELDB_TABLE_TWO_LEVEL_ITERATOR_H_ + +#include "leveldb/iterator.h" + +namespace leveldb { + +struct ReadOptions; + +// Return a new two level iterator. A two-level iterator contains an +// index iterator whose values point to a sequence of blocks where +// each block is itself a sequence of key,value pairs. The returned +// two-level iterator yields the concatenation of all key/value pairs +// in the sequence of blocks. Takes ownership of "index_iter" and +// will delete it when no longer needed. +// +// Uses a supplied function to convert an index_iter value into +// an iterator over the contents of the corresponding block. +extern Iterator* NewTwoLevelIterator( + Iterator* index_iter, + Iterator* (*block_function)( + void* arg, + const ReadOptions& options, + const Slice& index_value), + void* arg, + const ReadOptions& options); + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_TABLE_TWO_LEVEL_ITERATOR_H_ diff --git a/ios/Pods/leveldb-library/util/arena.cc b/ios/Pods/leveldb-library/util/arena.cc new file mode 100644 index 00000000..74078213 --- /dev/null +++ b/ios/Pods/leveldb-library/util/arena.cc @@ -0,0 +1,68 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "util/arena.h" +#include + +namespace leveldb { + +static const int kBlockSize = 4096; + +Arena::Arena() : memory_usage_(0) { + alloc_ptr_ = NULL; // First allocation will allocate a block + alloc_bytes_remaining_ = 0; +} + +Arena::~Arena() { + for (size_t i = 0; i < blocks_.size(); i++) { + delete[] blocks_[i]; + } +} + +char* Arena::AllocateFallback(size_t bytes) { + if (bytes > kBlockSize / 4) { + // Object is more than a quarter of our block size. Allocate it separately + // to avoid wasting too much space in leftover bytes. + char* result = AllocateNewBlock(bytes); + return result; + } + + // We waste the remaining space in the current block. + alloc_ptr_ = AllocateNewBlock(kBlockSize); + alloc_bytes_remaining_ = kBlockSize; + + char* result = alloc_ptr_; + alloc_ptr_ += bytes; + alloc_bytes_remaining_ -= bytes; + return result; +} + +char* Arena::AllocateAligned(size_t bytes) { + const int align = (sizeof(void*) > 8) ? sizeof(void*) : 8; + assert((align & (align-1)) == 0); // Pointer size should be a power of 2 + size_t current_mod = reinterpret_cast(alloc_ptr_) & (align-1); + size_t slop = (current_mod == 0 ? 0 : align - current_mod); + size_t needed = bytes + slop; + char* result; + if (needed <= alloc_bytes_remaining_) { + result = alloc_ptr_ + slop; + alloc_ptr_ += needed; + alloc_bytes_remaining_ -= needed; + } else { + // AllocateFallback always returned aligned memory + result = AllocateFallback(bytes); + } + assert((reinterpret_cast(result) & (align-1)) == 0); + return result; +} + +char* Arena::AllocateNewBlock(size_t block_bytes) { + char* result = new char[block_bytes]; + blocks_.push_back(result); + memory_usage_.NoBarrier_Store( + reinterpret_cast(MemoryUsage() + block_bytes + sizeof(char*))); + return result; +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/util/arena.h b/ios/Pods/leveldb-library/util/arena.h new file mode 100644 index 00000000..48bab337 --- /dev/null +++ b/ios/Pods/leveldb-library/util/arena.h @@ -0,0 +1,68 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_UTIL_ARENA_H_ +#define STORAGE_LEVELDB_UTIL_ARENA_H_ + +#include +#include +#include +#include +#include "port/port.h" + +namespace leveldb { + +class Arena { + public: + Arena(); + ~Arena(); + + // Return a pointer to a newly allocated memory block of "bytes" bytes. + char* Allocate(size_t bytes); + + // Allocate memory with the normal alignment guarantees provided by malloc + char* AllocateAligned(size_t bytes); + + // Returns an estimate of the total memory usage of data allocated + // by the arena. + size_t MemoryUsage() const { + return reinterpret_cast(memory_usage_.NoBarrier_Load()); + } + + private: + char* AllocateFallback(size_t bytes); + char* AllocateNewBlock(size_t block_bytes); + + // Allocation state + char* alloc_ptr_; + size_t alloc_bytes_remaining_; + + // Array of new[] allocated memory blocks + std::vector blocks_; + + // Total memory usage of the arena. + port::AtomicPointer memory_usage_; + + // No copying allowed + Arena(const Arena&); + void operator=(const Arena&); +}; + +inline char* Arena::Allocate(size_t bytes) { + // The semantics of what to return are a bit messy if we allow + // 0-byte allocations, so we disallow them here (we don't need + // them for our internal use). + assert(bytes > 0); + if (bytes <= alloc_bytes_remaining_) { + char* result = alloc_ptr_; + alloc_ptr_ += bytes; + alloc_bytes_remaining_ -= bytes; + return result; + } + return AllocateFallback(bytes); +} + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_UTIL_ARENA_H_ diff --git a/ios/Pods/leveldb-library/util/bloom.cc b/ios/Pods/leveldb-library/util/bloom.cc new file mode 100644 index 00000000..bf3e4ca6 --- /dev/null +++ b/ios/Pods/leveldb-library/util/bloom.cc @@ -0,0 +1,95 @@ +// Copyright (c) 2012 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "leveldb/filter_policy.h" + +#include "leveldb/slice.h" +#include "util/hash.h" + +namespace leveldb { + +namespace { +static uint32_t BloomHash(const Slice& key) { + return Hash(key.data(), key.size(), 0xbc9f1d34); +} + +class BloomFilterPolicy : public FilterPolicy { + private: + size_t bits_per_key_; + size_t k_; + + public: + explicit BloomFilterPolicy(int bits_per_key) + : bits_per_key_(bits_per_key) { + // We intentionally round down to reduce probing cost a little bit + k_ = static_cast(bits_per_key * 0.69); // 0.69 =~ ln(2) + if (k_ < 1) k_ = 1; + if (k_ > 30) k_ = 30; + } + + virtual const char* Name() const { + return "leveldb.BuiltinBloomFilter2"; + } + + virtual void CreateFilter(const Slice* keys, int n, std::string* dst) const { + // Compute bloom filter size (in both bits and bytes) + size_t bits = n * bits_per_key_; + + // For small n, we can see a very high false positive rate. Fix it + // by enforcing a minimum bloom filter length. + if (bits < 64) bits = 64; + + size_t bytes = (bits + 7) / 8; + bits = bytes * 8; + + const size_t init_size = dst->size(); + dst->resize(init_size + bytes, 0); + dst->push_back(static_cast(k_)); // Remember # of probes in filter + char* array = &(*dst)[init_size]; + for (int i = 0; i < n; i++) { + // Use double-hashing to generate a sequence of hash values. + // See analysis in [Kirsch,Mitzenmacher 2006]. + uint32_t h = BloomHash(keys[i]); + const uint32_t delta = (h >> 17) | (h << 15); // Rotate right 17 bits + for (size_t j = 0; j < k_; j++) { + const uint32_t bitpos = h % bits; + array[bitpos/8] |= (1 << (bitpos % 8)); + h += delta; + } + } + } + + virtual bool KeyMayMatch(const Slice& key, const Slice& bloom_filter) const { + const size_t len = bloom_filter.size(); + if (len < 2) return false; + + const char* array = bloom_filter.data(); + const size_t bits = (len - 1) * 8; + + // Use the encoded k so that we can read filters generated by + // bloom filters created using different parameters. + const size_t k = array[len-1]; + if (k > 30) { + // Reserved for potentially new encodings for short bloom filters. + // Consider it a match. + return true; + } + + uint32_t h = BloomHash(key); + const uint32_t delta = (h >> 17) | (h << 15); // Rotate right 17 bits + for (size_t j = 0; j < k; j++) { + const uint32_t bitpos = h % bits; + if ((array[bitpos/8] & (1 << (bitpos % 8))) == 0) return false; + h += delta; + } + return true; + } +}; +} + +const FilterPolicy* NewBloomFilterPolicy(int bits_per_key) { + return new BloomFilterPolicy(bits_per_key); +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/util/cache.cc b/ios/Pods/leveldb-library/util/cache.cc new file mode 100644 index 00000000..ce468861 --- /dev/null +++ b/ios/Pods/leveldb-library/util/cache.cc @@ -0,0 +1,405 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include +#include +#include + +#include "leveldb/cache.h" +#include "port/port.h" +#include "util/hash.h" +#include "util/mutexlock.h" + +namespace leveldb { + +Cache::~Cache() { +} + +namespace { + +// LRU cache implementation +// +// Cache entries have an "in_cache" boolean indicating whether the cache has a +// reference on the entry. The only ways that this can become false without the +// entry being passed to its "deleter" are via Erase(), via Insert() when +// an element with a duplicate key is inserted, or on destruction of the cache. +// +// The cache keeps two linked lists of items in the cache. All items in the +// cache are in one list or the other, and never both. Items still referenced +// by clients but erased from the cache are in neither list. The lists are: +// - in-use: contains the items currently referenced by clients, in no +// particular order. (This list is used for invariant checking. If we +// removed the check, elements that would otherwise be on this list could be +// left as disconnected singleton lists.) +// - LRU: contains the items not currently referenced by clients, in LRU order +// Elements are moved between these lists by the Ref() and Unref() methods, +// when they detect an element in the cache acquiring or losing its only +// external reference. + +// An entry is a variable length heap-allocated structure. Entries +// are kept in a circular doubly linked list ordered by access time. +struct LRUHandle { + void* value; + void (*deleter)(const Slice&, void* value); + LRUHandle* next_hash; + LRUHandle* next; + LRUHandle* prev; + size_t charge; // TODO(opt): Only allow uint32_t? + size_t key_length; + bool in_cache; // Whether entry is in the cache. + uint32_t refs; // References, including cache reference, if present. + uint32_t hash; // Hash of key(); used for fast sharding and comparisons + char key_data[1]; // Beginning of key + + Slice key() const { + // For cheaper lookups, we allow a temporary Handle object + // to store a pointer to a key in "value". + if (next == this) { + return *(reinterpret_cast(value)); + } else { + return Slice(key_data, key_length); + } + } +}; + +// We provide our own simple hash table since it removes a whole bunch +// of porting hacks and is also faster than some of the built-in hash +// table implementations in some of the compiler/runtime combinations +// we have tested. E.g., readrandom speeds up by ~5% over the g++ +// 4.4.3's builtin hashtable. +class HandleTable { + public: + HandleTable() : length_(0), elems_(0), list_(NULL) { Resize(); } + ~HandleTable() { delete[] list_; } + + LRUHandle* Lookup(const Slice& key, uint32_t hash) { + return *FindPointer(key, hash); + } + + LRUHandle* Insert(LRUHandle* h) { + LRUHandle** ptr = FindPointer(h->key(), h->hash); + LRUHandle* old = *ptr; + h->next_hash = (old == NULL ? NULL : old->next_hash); + *ptr = h; + if (old == NULL) { + ++elems_; + if (elems_ > length_) { + // Since each cache entry is fairly large, we aim for a small + // average linked list length (<= 1). + Resize(); + } + } + return old; + } + + LRUHandle* Remove(const Slice& key, uint32_t hash) { + LRUHandle** ptr = FindPointer(key, hash); + LRUHandle* result = *ptr; + if (result != NULL) { + *ptr = result->next_hash; + --elems_; + } + return result; + } + + private: + // The table consists of an array of buckets where each bucket is + // a linked list of cache entries that hash into the bucket. + uint32_t length_; + uint32_t elems_; + LRUHandle** list_; + + // Return a pointer to slot that points to a cache entry that + // matches key/hash. If there is no such cache entry, return a + // pointer to the trailing slot in the corresponding linked list. + LRUHandle** FindPointer(const Slice& key, uint32_t hash) { + LRUHandle** ptr = &list_[hash & (length_ - 1)]; + while (*ptr != NULL && + ((*ptr)->hash != hash || key != (*ptr)->key())) { + ptr = &(*ptr)->next_hash; + } + return ptr; + } + + void Resize() { + uint32_t new_length = 4; + while (new_length < elems_) { + new_length *= 2; + } + LRUHandle** new_list = new LRUHandle*[new_length]; + memset(new_list, 0, sizeof(new_list[0]) * new_length); + uint32_t count = 0; + for (uint32_t i = 0; i < length_; i++) { + LRUHandle* h = list_[i]; + while (h != NULL) { + LRUHandle* next = h->next_hash; + uint32_t hash = h->hash; + LRUHandle** ptr = &new_list[hash & (new_length - 1)]; + h->next_hash = *ptr; + *ptr = h; + h = next; + count++; + } + } + assert(elems_ == count); + delete[] list_; + list_ = new_list; + length_ = new_length; + } +}; + +// A single shard of sharded cache. +class LRUCache { + public: + LRUCache(); + ~LRUCache(); + + // Separate from constructor so caller can easily make an array of LRUCache + void SetCapacity(size_t capacity) { capacity_ = capacity; } + + // Like Cache methods, but with an extra "hash" parameter. + Cache::Handle* Insert(const Slice& key, uint32_t hash, + void* value, size_t charge, + void (*deleter)(const Slice& key, void* value)); + Cache::Handle* Lookup(const Slice& key, uint32_t hash); + void Release(Cache::Handle* handle); + void Erase(const Slice& key, uint32_t hash); + void Prune(); + size_t TotalCharge() const { + MutexLock l(&mutex_); + return usage_; + } + + private: + void LRU_Remove(LRUHandle* e); + void LRU_Append(LRUHandle*list, LRUHandle* e); + void Ref(LRUHandle* e); + void Unref(LRUHandle* e); + bool FinishErase(LRUHandle* e); + + // Initialized before use. + size_t capacity_; + + // mutex_ protects the following state. + mutable port::Mutex mutex_; + size_t usage_; + + // Dummy head of LRU list. + // lru.prev is newest entry, lru.next is oldest entry. + // Entries have refs==1 and in_cache==true. + LRUHandle lru_; + + // Dummy head of in-use list. + // Entries are in use by clients, and have refs >= 2 and in_cache==true. + LRUHandle in_use_; + + HandleTable table_; +}; + +LRUCache::LRUCache() + : usage_(0) { + // Make empty circular linked lists. + lru_.next = &lru_; + lru_.prev = &lru_; + in_use_.next = &in_use_; + in_use_.prev = &in_use_; +} + +LRUCache::~LRUCache() { + assert(in_use_.next == &in_use_); // Error if caller has an unreleased handle + for (LRUHandle* e = lru_.next; e != &lru_; ) { + LRUHandle* next = e->next; + assert(e->in_cache); + e->in_cache = false; + assert(e->refs == 1); // Invariant of lru_ list. + Unref(e); + e = next; + } +} + +void LRUCache::Ref(LRUHandle* e) { + if (e->refs == 1 && e->in_cache) { // If on lru_ list, move to in_use_ list. + LRU_Remove(e); + LRU_Append(&in_use_, e); + } + e->refs++; +} + +void LRUCache::Unref(LRUHandle* e) { + assert(e->refs > 0); + e->refs--; + if (e->refs == 0) { // Deallocate. + assert(!e->in_cache); + (*e->deleter)(e->key(), e->value); + free(e); + } else if (e->in_cache && e->refs == 1) { // No longer in use; move to lru_ list. + LRU_Remove(e); + LRU_Append(&lru_, e); + } +} + +void LRUCache::LRU_Remove(LRUHandle* e) { + e->next->prev = e->prev; + e->prev->next = e->next; +} + +void LRUCache::LRU_Append(LRUHandle* list, LRUHandle* e) { + // Make "e" newest entry by inserting just before *list + e->next = list; + e->prev = list->prev; + e->prev->next = e; + e->next->prev = e; +} + +Cache::Handle* LRUCache::Lookup(const Slice& key, uint32_t hash) { + MutexLock l(&mutex_); + LRUHandle* e = table_.Lookup(key, hash); + if (e != NULL) { + Ref(e); + } + return reinterpret_cast(e); +} + +void LRUCache::Release(Cache::Handle* handle) { + MutexLock l(&mutex_); + Unref(reinterpret_cast(handle)); +} + +Cache::Handle* LRUCache::Insert( + const Slice& key, uint32_t hash, void* value, size_t charge, + void (*deleter)(const Slice& key, void* value)) { + MutexLock l(&mutex_); + + LRUHandle* e = reinterpret_cast( + malloc(sizeof(LRUHandle)-1 + key.size())); + e->value = value; + e->deleter = deleter; + e->charge = charge; + e->key_length = key.size(); + e->hash = hash; + e->in_cache = false; + e->refs = 1; // for the returned handle. + memcpy(e->key_data, key.data(), key.size()); + + if (capacity_ > 0) { + e->refs++; // for the cache's reference. + e->in_cache = true; + LRU_Append(&in_use_, e); + usage_ += charge; + FinishErase(table_.Insert(e)); + } // else don't cache. (Tests use capacity_==0 to turn off caching.) + + while (usage_ > capacity_ && lru_.next != &lru_) { + LRUHandle* old = lru_.next; + assert(old->refs == 1); + bool erased = FinishErase(table_.Remove(old->key(), old->hash)); + if (!erased) { // to avoid unused variable when compiled NDEBUG + assert(erased); + } + } + + return reinterpret_cast(e); +} + +// If e != NULL, finish removing *e from the cache; it has already been removed +// from the hash table. Return whether e != NULL. Requires mutex_ held. +bool LRUCache::FinishErase(LRUHandle* e) { + if (e != NULL) { + assert(e->in_cache); + LRU_Remove(e); + e->in_cache = false; + usage_ -= e->charge; + Unref(e); + } + return e != NULL; +} + +void LRUCache::Erase(const Slice& key, uint32_t hash) { + MutexLock l(&mutex_); + FinishErase(table_.Remove(key, hash)); +} + +void LRUCache::Prune() { + MutexLock l(&mutex_); + while (lru_.next != &lru_) { + LRUHandle* e = lru_.next; + assert(e->refs == 1); + bool erased = FinishErase(table_.Remove(e->key(), e->hash)); + if (!erased) { // to avoid unused variable when compiled NDEBUG + assert(erased); + } + } +} + +static const int kNumShardBits = 4; +static const int kNumShards = 1 << kNumShardBits; + +class ShardedLRUCache : public Cache { + private: + LRUCache shard_[kNumShards]; + port::Mutex id_mutex_; + uint64_t last_id_; + + static inline uint32_t HashSlice(const Slice& s) { + return Hash(s.data(), s.size(), 0); + } + + static uint32_t Shard(uint32_t hash) { + return hash >> (32 - kNumShardBits); + } + + public: + explicit ShardedLRUCache(size_t capacity) + : last_id_(0) { + const size_t per_shard = (capacity + (kNumShards - 1)) / kNumShards; + for (int s = 0; s < kNumShards; s++) { + shard_[s].SetCapacity(per_shard); + } + } + virtual ~ShardedLRUCache() { } + virtual Handle* Insert(const Slice& key, void* value, size_t charge, + void (*deleter)(const Slice& key, void* value)) { + const uint32_t hash = HashSlice(key); + return shard_[Shard(hash)].Insert(key, hash, value, charge, deleter); + } + virtual Handle* Lookup(const Slice& key) { + const uint32_t hash = HashSlice(key); + return shard_[Shard(hash)].Lookup(key, hash); + } + virtual void Release(Handle* handle) { + LRUHandle* h = reinterpret_cast(handle); + shard_[Shard(h->hash)].Release(handle); + } + virtual void Erase(const Slice& key) { + const uint32_t hash = HashSlice(key); + shard_[Shard(hash)].Erase(key, hash); + } + virtual void* Value(Handle* handle) { + return reinterpret_cast(handle)->value; + } + virtual uint64_t NewId() { + MutexLock l(&id_mutex_); + return ++(last_id_); + } + virtual void Prune() { + for (int s = 0; s < kNumShards; s++) { + shard_[s].Prune(); + } + } + virtual size_t TotalCharge() const { + size_t total = 0; + for (int s = 0; s < kNumShards; s++) { + total += shard_[s].TotalCharge(); + } + return total; + } +}; + +} // end anonymous namespace + +Cache* NewLRUCache(size_t capacity) { + return new ShardedLRUCache(capacity); +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/util/coding.cc b/ios/Pods/leveldb-library/util/coding.cc new file mode 100644 index 00000000..21e3186d --- /dev/null +++ b/ios/Pods/leveldb-library/util/coding.cc @@ -0,0 +1,194 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "util/coding.h" + +namespace leveldb { + +void EncodeFixed32(char* buf, uint32_t value) { + if (port::kLittleEndian) { + memcpy(buf, &value, sizeof(value)); + } else { + buf[0] = value & 0xff; + buf[1] = (value >> 8) & 0xff; + buf[2] = (value >> 16) & 0xff; + buf[3] = (value >> 24) & 0xff; + } +} + +void EncodeFixed64(char* buf, uint64_t value) { + if (port::kLittleEndian) { + memcpy(buf, &value, sizeof(value)); + } else { + buf[0] = value & 0xff; + buf[1] = (value >> 8) & 0xff; + buf[2] = (value >> 16) & 0xff; + buf[3] = (value >> 24) & 0xff; + buf[4] = (value >> 32) & 0xff; + buf[5] = (value >> 40) & 0xff; + buf[6] = (value >> 48) & 0xff; + buf[7] = (value >> 56) & 0xff; + } +} + +void PutFixed32(std::string* dst, uint32_t value) { + char buf[sizeof(value)]; + EncodeFixed32(buf, value); + dst->append(buf, sizeof(buf)); +} + +void PutFixed64(std::string* dst, uint64_t value) { + char buf[sizeof(value)]; + EncodeFixed64(buf, value); + dst->append(buf, sizeof(buf)); +} + +char* EncodeVarint32(char* dst, uint32_t v) { + // Operate on characters as unsigneds + unsigned char* ptr = reinterpret_cast(dst); + static const int B = 128; + if (v < (1<<7)) { + *(ptr++) = v; + } else if (v < (1<<14)) { + *(ptr++) = v | B; + *(ptr++) = v>>7; + } else if (v < (1<<21)) { + *(ptr++) = v | B; + *(ptr++) = (v>>7) | B; + *(ptr++) = v>>14; + } else if (v < (1<<28)) { + *(ptr++) = v | B; + *(ptr++) = (v>>7) | B; + *(ptr++) = (v>>14) | B; + *(ptr++) = v>>21; + } else { + *(ptr++) = v | B; + *(ptr++) = (v>>7) | B; + *(ptr++) = (v>>14) | B; + *(ptr++) = (v>>21) | B; + *(ptr++) = v>>28; + } + return reinterpret_cast(ptr); +} + +void PutVarint32(std::string* dst, uint32_t v) { + char buf[5]; + char* ptr = EncodeVarint32(buf, v); + dst->append(buf, ptr - buf); +} + +char* EncodeVarint64(char* dst, uint64_t v) { + static const int B = 128; + unsigned char* ptr = reinterpret_cast(dst); + while (v >= B) { + *(ptr++) = (v & (B-1)) | B; + v >>= 7; + } + *(ptr++) = static_cast(v); + return reinterpret_cast(ptr); +} + +void PutVarint64(std::string* dst, uint64_t v) { + char buf[10]; + char* ptr = EncodeVarint64(buf, v); + dst->append(buf, ptr - buf); +} + +void PutLengthPrefixedSlice(std::string* dst, const Slice& value) { + PutVarint32(dst, value.size()); + dst->append(value.data(), value.size()); +} + +int VarintLength(uint64_t v) { + int len = 1; + while (v >= 128) { + v >>= 7; + len++; + } + return len; +} + +const char* GetVarint32PtrFallback(const char* p, + const char* limit, + uint32_t* value) { + uint32_t result = 0; + for (uint32_t shift = 0; shift <= 28 && p < limit; shift += 7) { + uint32_t byte = *(reinterpret_cast(p)); + p++; + if (byte & 128) { + // More bytes are present + result |= ((byte & 127) << shift); + } else { + result |= (byte << shift); + *value = result; + return reinterpret_cast(p); + } + } + return NULL; +} + +bool GetVarint32(Slice* input, uint32_t* value) { + const char* p = input->data(); + const char* limit = p + input->size(); + const char* q = GetVarint32Ptr(p, limit, value); + if (q == NULL) { + return false; + } else { + *input = Slice(q, limit - q); + return true; + } +} + +const char* GetVarint64Ptr(const char* p, const char* limit, uint64_t* value) { + uint64_t result = 0; + for (uint32_t shift = 0; shift <= 63 && p < limit; shift += 7) { + uint64_t byte = *(reinterpret_cast(p)); + p++; + if (byte & 128) { + // More bytes are present + result |= ((byte & 127) << shift); + } else { + result |= (byte << shift); + *value = result; + return reinterpret_cast(p); + } + } + return NULL; +} + +bool GetVarint64(Slice* input, uint64_t* value) { + const char* p = input->data(); + const char* limit = p + input->size(); + const char* q = GetVarint64Ptr(p, limit, value); + if (q == NULL) { + return false; + } else { + *input = Slice(q, limit - q); + return true; + } +} + +const char* GetLengthPrefixedSlice(const char* p, const char* limit, + Slice* result) { + uint32_t len; + p = GetVarint32Ptr(p, limit, &len); + if (p == NULL) return NULL; + if (p + len > limit) return NULL; + *result = Slice(p, len); + return p + len; +} + +bool GetLengthPrefixedSlice(Slice* input, Slice* result) { + uint32_t len; + if (GetVarint32(input, &len) && + input->size() >= len) { + *result = Slice(input->data(), len); + input->remove_prefix(len); + return true; + } else { + return false; + } +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/util/coding.h b/ios/Pods/leveldb-library/util/coding.h new file mode 100644 index 00000000..3993c4a7 --- /dev/null +++ b/ios/Pods/leveldb-library/util/coding.h @@ -0,0 +1,104 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// Endian-neutral encoding: +// * Fixed-length numbers are encoded with least-significant byte first +// * In addition we support variable length "varint" encoding +// * Strings are encoded prefixed by their length in varint format + +#ifndef STORAGE_LEVELDB_UTIL_CODING_H_ +#define STORAGE_LEVELDB_UTIL_CODING_H_ + +#include +#include +#include +#include "leveldb/slice.h" +#include "port/port.h" + +namespace leveldb { + +// Standard Put... routines append to a string +extern void PutFixed32(std::string* dst, uint32_t value); +extern void PutFixed64(std::string* dst, uint64_t value); +extern void PutVarint32(std::string* dst, uint32_t value); +extern void PutVarint64(std::string* dst, uint64_t value); +extern void PutLengthPrefixedSlice(std::string* dst, const Slice& value); + +// Standard Get... routines parse a value from the beginning of a Slice +// and advance the slice past the parsed value. +extern bool GetVarint32(Slice* input, uint32_t* value); +extern bool GetVarint64(Slice* input, uint64_t* value); +extern bool GetLengthPrefixedSlice(Slice* input, Slice* result); + +// Pointer-based variants of GetVarint... These either store a value +// in *v and return a pointer just past the parsed value, or return +// NULL on error. These routines only look at bytes in the range +// [p..limit-1] +extern const char* GetVarint32Ptr(const char* p,const char* limit, uint32_t* v); +extern const char* GetVarint64Ptr(const char* p,const char* limit, uint64_t* v); + +// Returns the length of the varint32 or varint64 encoding of "v" +extern int VarintLength(uint64_t v); + +// Lower-level versions of Put... that write directly into a character buffer +// REQUIRES: dst has enough space for the value being written +extern void EncodeFixed32(char* dst, uint32_t value); +extern void EncodeFixed64(char* dst, uint64_t value); + +// Lower-level versions of Put... that write directly into a character buffer +// and return a pointer just past the last byte written. +// REQUIRES: dst has enough space for the value being written +extern char* EncodeVarint32(char* dst, uint32_t value); +extern char* EncodeVarint64(char* dst, uint64_t value); + +// Lower-level versions of Get... that read directly from a character buffer +// without any bounds checking. + +inline uint32_t DecodeFixed32(const char* ptr) { + if (port::kLittleEndian) { + // Load the raw bytes + uint32_t result; + memcpy(&result, ptr, sizeof(result)); // gcc optimizes this to a plain load + return result; + } else { + return ((static_cast(static_cast(ptr[0]))) + | (static_cast(static_cast(ptr[1])) << 8) + | (static_cast(static_cast(ptr[2])) << 16) + | (static_cast(static_cast(ptr[3])) << 24)); + } +} + +inline uint64_t DecodeFixed64(const char* ptr) { + if (port::kLittleEndian) { + // Load the raw bytes + uint64_t result; + memcpy(&result, ptr, sizeof(result)); // gcc optimizes this to a plain load + return result; + } else { + uint64_t lo = DecodeFixed32(ptr); + uint64_t hi = DecodeFixed32(ptr + 4); + return (hi << 32) | lo; + } +} + +// Internal routine for use by fallback path of GetVarint32Ptr +extern const char* GetVarint32PtrFallback(const char* p, + const char* limit, + uint32_t* value); +inline const char* GetVarint32Ptr(const char* p, + const char* limit, + uint32_t* value) { + if (p < limit) { + uint32_t result = *(reinterpret_cast(p)); + if ((result & 128) == 0) { + *value = result; + return p + 1; + } + } + return GetVarint32PtrFallback(p, limit, value); +} + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_UTIL_CODING_H_ diff --git a/ios/Pods/leveldb-library/util/comparator.cc b/ios/Pods/leveldb-library/util/comparator.cc new file mode 100644 index 00000000..4b7b5724 --- /dev/null +++ b/ios/Pods/leveldb-library/util/comparator.cc @@ -0,0 +1,81 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include +#include +#include "leveldb/comparator.h" +#include "leveldb/slice.h" +#include "port/port.h" +#include "util/logging.h" + +namespace leveldb { + +Comparator::~Comparator() { } + +namespace { +class BytewiseComparatorImpl : public Comparator { + public: + BytewiseComparatorImpl() { } + + virtual const char* Name() const { + return "leveldb.BytewiseComparator"; + } + + virtual int Compare(const Slice& a, const Slice& b) const { + return a.compare(b); + } + + virtual void FindShortestSeparator( + std::string* start, + const Slice& limit) const { + // Find length of common prefix + size_t min_length = std::min(start->size(), limit.size()); + size_t diff_index = 0; + while ((diff_index < min_length) && + ((*start)[diff_index] == limit[diff_index])) { + diff_index++; + } + + if (diff_index >= min_length) { + // Do not shorten if one string is a prefix of the other + } else { + uint8_t diff_byte = static_cast((*start)[diff_index]); + if (diff_byte < static_cast(0xff) && + diff_byte + 1 < static_cast(limit[diff_index])) { + (*start)[diff_index]++; + start->resize(diff_index + 1); + assert(Compare(*start, limit) < 0); + } + } + } + + virtual void FindShortSuccessor(std::string* key) const { + // Find first character that can be incremented + size_t n = key->size(); + for (size_t i = 0; i < n; i++) { + const uint8_t byte = (*key)[i]; + if (byte != static_cast(0xff)) { + (*key)[i] = byte + 1; + key->resize(i+1); + return; + } + } + // *key is a run of 0xffs. Leave it alone. + } +}; +} // namespace + +static port::OnceType once = LEVELDB_ONCE_INIT; +static const Comparator* bytewise; + +static void InitModule() { + bytewise = new BytewiseComparatorImpl; +} + +const Comparator* BytewiseComparator() { + port::InitOnce(&once, InitModule); + return bytewise; +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/util/crc32c.cc b/ios/Pods/leveldb-library/util/crc32c.cc new file mode 100644 index 00000000..edd61cfd --- /dev/null +++ b/ios/Pods/leveldb-library/util/crc32c.cc @@ -0,0 +1,350 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// A portable implementation of crc32c, optimized to handle +// four bytes at a time. + +#include "util/crc32c.h" + +#include + +#include "port/port.h" +#include "util/coding.h" + +namespace leveldb { +namespace crc32c { + +static const uint32_t table0_[256] = { + 0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, + 0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb, + 0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b, + 0x4d43cfd0, 0xbf284cd3, 0xac78bf27, 0x5e133c24, + 0x105ec76f, 0xe235446c, 0xf165b798, 0x030e349b, + 0xd7c45070, 0x25afd373, 0x36ff2087, 0xc494a384, + 0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54, + 0x5d1d08bf, 0xaf768bbc, 0xbc267848, 0x4e4dfb4b, + 0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a, + 0xe72719c1, 0x154c9ac2, 0x061c6936, 0xf477ea35, + 0xaa64d611, 0x580f5512, 0x4b5fa6e6, 0xb93425e5, + 0x6dfe410e, 0x9f95c20d, 0x8cc531f9, 0x7eaeb2fa, + 0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45, + 0xf779deae, 0x05125dad, 0x1642ae59, 0xe4292d5a, + 0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a, + 0x7da08661, 0x8fcb0562, 0x9c9bf696, 0x6ef07595, + 0x417b1dbc, 0xb3109ebf, 0xa0406d4b, 0x522bee48, + 0x86e18aa3, 0x748a09a0, 0x67dafa54, 0x95b17957, + 0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687, + 0x0c38d26c, 0xfe53516f, 0xed03a29b, 0x1f682198, + 0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927, + 0x96bf4dcc, 0x64d4cecf, 0x77843d3b, 0x85efbe38, + 0xdbfc821c, 0x2997011f, 0x3ac7f2eb, 0xc8ac71e8, + 0x1c661503, 0xee0d9600, 0xfd5d65f4, 0x0f36e6f7, + 0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096, + 0xa65c047d, 0x5437877e, 0x4767748a, 0xb50cf789, + 0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859, + 0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, 0x3fd5af46, + 0x7198540d, 0x83f3d70e, 0x90a324fa, 0x62c8a7f9, + 0xb602c312, 0x44694011, 0x5739b3e5, 0xa55230e6, + 0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36, + 0x3cdb9bdd, 0xceb018de, 0xdde0eb2a, 0x2f8b6829, + 0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c, + 0x456cac67, 0xb7072f64, 0xa457dc90, 0x563c5f93, + 0x082f63b7, 0xfa44e0b4, 0xe9141340, 0x1b7f9043, + 0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, 0xdce5075c, + 0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3, + 0x55326b08, 0xa759e80b, 0xb4091bff, 0x466298fc, + 0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c, + 0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, 0xccbbc033, + 0xa24bb5a6, 0x502036a5, 0x4370c551, 0xb11b4652, + 0x65d122b9, 0x97baa1ba, 0x84ea524e, 0x7681d14d, + 0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d, + 0xef087a76, 0x1d63f975, 0x0e330a81, 0xfc588982, + 0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d, + 0x758fe5d6, 0x87e466d5, 0x94b49521, 0x66df1622, + 0x38cc2a06, 0xcaa7a905, 0xd9f75af1, 0x2b9cd9f2, + 0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, 0xec064eed, + 0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530, + 0x0417b1db, 0xf67c32d8, 0xe52cc12c, 0x1747422f, + 0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff, + 0x8ecee914, 0x7ca56a17, 0x6ff599e3, 0x9d9e1ae0, + 0xd3d3e1ab, 0x21b862a8, 0x32e8915c, 0xc083125f, + 0x144976b4, 0xe622f5b7, 0xf5720643, 0x07198540, + 0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90, + 0x9e902e7b, 0x6cfbad78, 0x7fab5e8c, 0x8dc0dd8f, + 0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee, + 0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, 0x37faccf1, + 0x69e9f0d5, 0x9b8273d6, 0x88d28022, 0x7ab90321, + 0xae7367ca, 0x5c18e4c9, 0x4f48173d, 0xbd23943e, + 0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81, + 0x34f4f86a, 0xc69f7b69, 0xd5cf889d, 0x27a40b9e, + 0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e, + 0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351 +}; +static const uint32_t table1_[256] = { + 0x00000000, 0x13a29877, 0x274530ee, 0x34e7a899, + 0x4e8a61dc, 0x5d28f9ab, 0x69cf5132, 0x7a6dc945, + 0x9d14c3b8, 0x8eb65bcf, 0xba51f356, 0xa9f36b21, + 0xd39ea264, 0xc03c3a13, 0xf4db928a, 0xe7790afd, + 0x3fc5f181, 0x2c6769f6, 0x1880c16f, 0x0b225918, + 0x714f905d, 0x62ed082a, 0x560aa0b3, 0x45a838c4, + 0xa2d13239, 0xb173aa4e, 0x859402d7, 0x96369aa0, + 0xec5b53e5, 0xfff9cb92, 0xcb1e630b, 0xd8bcfb7c, + 0x7f8be302, 0x6c297b75, 0x58ced3ec, 0x4b6c4b9b, + 0x310182de, 0x22a31aa9, 0x1644b230, 0x05e62a47, + 0xe29f20ba, 0xf13db8cd, 0xc5da1054, 0xd6788823, + 0xac154166, 0xbfb7d911, 0x8b507188, 0x98f2e9ff, + 0x404e1283, 0x53ec8af4, 0x670b226d, 0x74a9ba1a, + 0x0ec4735f, 0x1d66eb28, 0x298143b1, 0x3a23dbc6, + 0xdd5ad13b, 0xcef8494c, 0xfa1fe1d5, 0xe9bd79a2, + 0x93d0b0e7, 0x80722890, 0xb4958009, 0xa737187e, + 0xff17c604, 0xecb55e73, 0xd852f6ea, 0xcbf06e9d, + 0xb19da7d8, 0xa23f3faf, 0x96d89736, 0x857a0f41, + 0x620305bc, 0x71a19dcb, 0x45463552, 0x56e4ad25, + 0x2c896460, 0x3f2bfc17, 0x0bcc548e, 0x186eccf9, + 0xc0d23785, 0xd370aff2, 0xe797076b, 0xf4359f1c, + 0x8e585659, 0x9dface2e, 0xa91d66b7, 0xbabffec0, + 0x5dc6f43d, 0x4e646c4a, 0x7a83c4d3, 0x69215ca4, + 0x134c95e1, 0x00ee0d96, 0x3409a50f, 0x27ab3d78, + 0x809c2506, 0x933ebd71, 0xa7d915e8, 0xb47b8d9f, + 0xce1644da, 0xddb4dcad, 0xe9537434, 0xfaf1ec43, + 0x1d88e6be, 0x0e2a7ec9, 0x3acdd650, 0x296f4e27, + 0x53028762, 0x40a01f15, 0x7447b78c, 0x67e52ffb, + 0xbf59d487, 0xacfb4cf0, 0x981ce469, 0x8bbe7c1e, + 0xf1d3b55b, 0xe2712d2c, 0xd69685b5, 0xc5341dc2, + 0x224d173f, 0x31ef8f48, 0x050827d1, 0x16aabfa6, + 0x6cc776e3, 0x7f65ee94, 0x4b82460d, 0x5820de7a, + 0xfbc3faf9, 0xe861628e, 0xdc86ca17, 0xcf245260, + 0xb5499b25, 0xa6eb0352, 0x920cabcb, 0x81ae33bc, + 0x66d73941, 0x7575a136, 0x419209af, 0x523091d8, + 0x285d589d, 0x3bffc0ea, 0x0f186873, 0x1cbaf004, + 0xc4060b78, 0xd7a4930f, 0xe3433b96, 0xf0e1a3e1, + 0x8a8c6aa4, 0x992ef2d3, 0xadc95a4a, 0xbe6bc23d, + 0x5912c8c0, 0x4ab050b7, 0x7e57f82e, 0x6df56059, + 0x1798a91c, 0x043a316b, 0x30dd99f2, 0x237f0185, + 0x844819fb, 0x97ea818c, 0xa30d2915, 0xb0afb162, + 0xcac27827, 0xd960e050, 0xed8748c9, 0xfe25d0be, + 0x195cda43, 0x0afe4234, 0x3e19eaad, 0x2dbb72da, + 0x57d6bb9f, 0x447423e8, 0x70938b71, 0x63311306, + 0xbb8de87a, 0xa82f700d, 0x9cc8d894, 0x8f6a40e3, + 0xf50789a6, 0xe6a511d1, 0xd242b948, 0xc1e0213f, + 0x26992bc2, 0x353bb3b5, 0x01dc1b2c, 0x127e835b, + 0x68134a1e, 0x7bb1d269, 0x4f567af0, 0x5cf4e287, + 0x04d43cfd, 0x1776a48a, 0x23910c13, 0x30339464, + 0x4a5e5d21, 0x59fcc556, 0x6d1b6dcf, 0x7eb9f5b8, + 0x99c0ff45, 0x8a626732, 0xbe85cfab, 0xad2757dc, + 0xd74a9e99, 0xc4e806ee, 0xf00fae77, 0xe3ad3600, + 0x3b11cd7c, 0x28b3550b, 0x1c54fd92, 0x0ff665e5, + 0x759baca0, 0x663934d7, 0x52de9c4e, 0x417c0439, + 0xa6050ec4, 0xb5a796b3, 0x81403e2a, 0x92e2a65d, + 0xe88f6f18, 0xfb2df76f, 0xcfca5ff6, 0xdc68c781, + 0x7b5fdfff, 0x68fd4788, 0x5c1aef11, 0x4fb87766, + 0x35d5be23, 0x26772654, 0x12908ecd, 0x013216ba, + 0xe64b1c47, 0xf5e98430, 0xc10e2ca9, 0xd2acb4de, + 0xa8c17d9b, 0xbb63e5ec, 0x8f844d75, 0x9c26d502, + 0x449a2e7e, 0x5738b609, 0x63df1e90, 0x707d86e7, + 0x0a104fa2, 0x19b2d7d5, 0x2d557f4c, 0x3ef7e73b, + 0xd98eedc6, 0xca2c75b1, 0xfecbdd28, 0xed69455f, + 0x97048c1a, 0x84a6146d, 0xb041bcf4, 0xa3e32483 +}; +static const uint32_t table2_[256] = { + 0x00000000, 0xa541927e, 0x4f6f520d, 0xea2ec073, + 0x9edea41a, 0x3b9f3664, 0xd1b1f617, 0x74f06469, + 0x38513ec5, 0x9d10acbb, 0x773e6cc8, 0xd27ffeb6, + 0xa68f9adf, 0x03ce08a1, 0xe9e0c8d2, 0x4ca15aac, + 0x70a27d8a, 0xd5e3eff4, 0x3fcd2f87, 0x9a8cbdf9, + 0xee7cd990, 0x4b3d4bee, 0xa1138b9d, 0x045219e3, + 0x48f3434f, 0xedb2d131, 0x079c1142, 0xa2dd833c, + 0xd62de755, 0x736c752b, 0x9942b558, 0x3c032726, + 0xe144fb14, 0x4405696a, 0xae2ba919, 0x0b6a3b67, + 0x7f9a5f0e, 0xdadbcd70, 0x30f50d03, 0x95b49f7d, + 0xd915c5d1, 0x7c5457af, 0x967a97dc, 0x333b05a2, + 0x47cb61cb, 0xe28af3b5, 0x08a433c6, 0xade5a1b8, + 0x91e6869e, 0x34a714e0, 0xde89d493, 0x7bc846ed, + 0x0f382284, 0xaa79b0fa, 0x40577089, 0xe516e2f7, + 0xa9b7b85b, 0x0cf62a25, 0xe6d8ea56, 0x43997828, + 0x37691c41, 0x92288e3f, 0x78064e4c, 0xdd47dc32, + 0xc76580d9, 0x622412a7, 0x880ad2d4, 0x2d4b40aa, + 0x59bb24c3, 0xfcfab6bd, 0x16d476ce, 0xb395e4b0, + 0xff34be1c, 0x5a752c62, 0xb05bec11, 0x151a7e6f, + 0x61ea1a06, 0xc4ab8878, 0x2e85480b, 0x8bc4da75, + 0xb7c7fd53, 0x12866f2d, 0xf8a8af5e, 0x5de93d20, + 0x29195949, 0x8c58cb37, 0x66760b44, 0xc337993a, + 0x8f96c396, 0x2ad751e8, 0xc0f9919b, 0x65b803e5, + 0x1148678c, 0xb409f5f2, 0x5e273581, 0xfb66a7ff, + 0x26217bcd, 0x8360e9b3, 0x694e29c0, 0xcc0fbbbe, + 0xb8ffdfd7, 0x1dbe4da9, 0xf7908dda, 0x52d11fa4, + 0x1e704508, 0xbb31d776, 0x511f1705, 0xf45e857b, + 0x80aee112, 0x25ef736c, 0xcfc1b31f, 0x6a802161, + 0x56830647, 0xf3c29439, 0x19ec544a, 0xbcadc634, + 0xc85da25d, 0x6d1c3023, 0x8732f050, 0x2273622e, + 0x6ed23882, 0xcb93aafc, 0x21bd6a8f, 0x84fcf8f1, + 0xf00c9c98, 0x554d0ee6, 0xbf63ce95, 0x1a225ceb, + 0x8b277743, 0x2e66e53d, 0xc448254e, 0x6109b730, + 0x15f9d359, 0xb0b84127, 0x5a968154, 0xffd7132a, + 0xb3764986, 0x1637dbf8, 0xfc191b8b, 0x595889f5, + 0x2da8ed9c, 0x88e97fe2, 0x62c7bf91, 0xc7862def, + 0xfb850ac9, 0x5ec498b7, 0xb4ea58c4, 0x11abcaba, + 0x655baed3, 0xc01a3cad, 0x2a34fcde, 0x8f756ea0, + 0xc3d4340c, 0x6695a672, 0x8cbb6601, 0x29faf47f, + 0x5d0a9016, 0xf84b0268, 0x1265c21b, 0xb7245065, + 0x6a638c57, 0xcf221e29, 0x250cde5a, 0x804d4c24, + 0xf4bd284d, 0x51fcba33, 0xbbd27a40, 0x1e93e83e, + 0x5232b292, 0xf77320ec, 0x1d5de09f, 0xb81c72e1, + 0xccec1688, 0x69ad84f6, 0x83834485, 0x26c2d6fb, + 0x1ac1f1dd, 0xbf8063a3, 0x55aea3d0, 0xf0ef31ae, + 0x841f55c7, 0x215ec7b9, 0xcb7007ca, 0x6e3195b4, + 0x2290cf18, 0x87d15d66, 0x6dff9d15, 0xc8be0f6b, + 0xbc4e6b02, 0x190ff97c, 0xf321390f, 0x5660ab71, + 0x4c42f79a, 0xe90365e4, 0x032da597, 0xa66c37e9, + 0xd29c5380, 0x77ddc1fe, 0x9df3018d, 0x38b293f3, + 0x7413c95f, 0xd1525b21, 0x3b7c9b52, 0x9e3d092c, + 0xeacd6d45, 0x4f8cff3b, 0xa5a23f48, 0x00e3ad36, + 0x3ce08a10, 0x99a1186e, 0x738fd81d, 0xd6ce4a63, + 0xa23e2e0a, 0x077fbc74, 0xed517c07, 0x4810ee79, + 0x04b1b4d5, 0xa1f026ab, 0x4bdee6d8, 0xee9f74a6, + 0x9a6f10cf, 0x3f2e82b1, 0xd50042c2, 0x7041d0bc, + 0xad060c8e, 0x08479ef0, 0xe2695e83, 0x4728ccfd, + 0x33d8a894, 0x96993aea, 0x7cb7fa99, 0xd9f668e7, + 0x9557324b, 0x3016a035, 0xda386046, 0x7f79f238, + 0x0b899651, 0xaec8042f, 0x44e6c45c, 0xe1a75622, + 0xdda47104, 0x78e5e37a, 0x92cb2309, 0x378ab177, + 0x437ad51e, 0xe63b4760, 0x0c158713, 0xa954156d, + 0xe5f54fc1, 0x40b4ddbf, 0xaa9a1dcc, 0x0fdb8fb2, + 0x7b2bebdb, 0xde6a79a5, 0x3444b9d6, 0x91052ba8 +}; +static const uint32_t table3_[256] = { + 0x00000000, 0xdd45aab8, 0xbf672381, 0x62228939, + 0x7b2231f3, 0xa6679b4b, 0xc4451272, 0x1900b8ca, + 0xf64463e6, 0x2b01c95e, 0x49234067, 0x9466eadf, + 0x8d665215, 0x5023f8ad, 0x32017194, 0xef44db2c, + 0xe964b13d, 0x34211b85, 0x560392bc, 0x8b463804, + 0x924680ce, 0x4f032a76, 0x2d21a34f, 0xf06409f7, + 0x1f20d2db, 0xc2657863, 0xa047f15a, 0x7d025be2, + 0x6402e328, 0xb9474990, 0xdb65c0a9, 0x06206a11, + 0xd725148b, 0x0a60be33, 0x6842370a, 0xb5079db2, + 0xac072578, 0x71428fc0, 0x136006f9, 0xce25ac41, + 0x2161776d, 0xfc24ddd5, 0x9e0654ec, 0x4343fe54, + 0x5a43469e, 0x8706ec26, 0xe524651f, 0x3861cfa7, + 0x3e41a5b6, 0xe3040f0e, 0x81268637, 0x5c632c8f, + 0x45639445, 0x98263efd, 0xfa04b7c4, 0x27411d7c, + 0xc805c650, 0x15406ce8, 0x7762e5d1, 0xaa274f69, + 0xb327f7a3, 0x6e625d1b, 0x0c40d422, 0xd1057e9a, + 0xaba65fe7, 0x76e3f55f, 0x14c17c66, 0xc984d6de, + 0xd0846e14, 0x0dc1c4ac, 0x6fe34d95, 0xb2a6e72d, + 0x5de23c01, 0x80a796b9, 0xe2851f80, 0x3fc0b538, + 0x26c00df2, 0xfb85a74a, 0x99a72e73, 0x44e284cb, + 0x42c2eeda, 0x9f874462, 0xfda5cd5b, 0x20e067e3, + 0x39e0df29, 0xe4a57591, 0x8687fca8, 0x5bc25610, + 0xb4868d3c, 0x69c32784, 0x0be1aebd, 0xd6a40405, + 0xcfa4bccf, 0x12e11677, 0x70c39f4e, 0xad8635f6, + 0x7c834b6c, 0xa1c6e1d4, 0xc3e468ed, 0x1ea1c255, + 0x07a17a9f, 0xdae4d027, 0xb8c6591e, 0x6583f3a6, + 0x8ac7288a, 0x57828232, 0x35a00b0b, 0xe8e5a1b3, + 0xf1e51979, 0x2ca0b3c1, 0x4e823af8, 0x93c79040, + 0x95e7fa51, 0x48a250e9, 0x2a80d9d0, 0xf7c57368, + 0xeec5cba2, 0x3380611a, 0x51a2e823, 0x8ce7429b, + 0x63a399b7, 0xbee6330f, 0xdcc4ba36, 0x0181108e, + 0x1881a844, 0xc5c402fc, 0xa7e68bc5, 0x7aa3217d, + 0x52a0c93f, 0x8fe56387, 0xedc7eabe, 0x30824006, + 0x2982f8cc, 0xf4c75274, 0x96e5db4d, 0x4ba071f5, + 0xa4e4aad9, 0x79a10061, 0x1b838958, 0xc6c623e0, + 0xdfc69b2a, 0x02833192, 0x60a1b8ab, 0xbde41213, + 0xbbc47802, 0x6681d2ba, 0x04a35b83, 0xd9e6f13b, + 0xc0e649f1, 0x1da3e349, 0x7f816a70, 0xa2c4c0c8, + 0x4d801be4, 0x90c5b15c, 0xf2e73865, 0x2fa292dd, + 0x36a22a17, 0xebe780af, 0x89c50996, 0x5480a32e, + 0x8585ddb4, 0x58c0770c, 0x3ae2fe35, 0xe7a7548d, + 0xfea7ec47, 0x23e246ff, 0x41c0cfc6, 0x9c85657e, + 0x73c1be52, 0xae8414ea, 0xcca69dd3, 0x11e3376b, + 0x08e38fa1, 0xd5a62519, 0xb784ac20, 0x6ac10698, + 0x6ce16c89, 0xb1a4c631, 0xd3864f08, 0x0ec3e5b0, + 0x17c35d7a, 0xca86f7c2, 0xa8a47efb, 0x75e1d443, + 0x9aa50f6f, 0x47e0a5d7, 0x25c22cee, 0xf8878656, + 0xe1873e9c, 0x3cc29424, 0x5ee01d1d, 0x83a5b7a5, + 0xf90696d8, 0x24433c60, 0x4661b559, 0x9b241fe1, + 0x8224a72b, 0x5f610d93, 0x3d4384aa, 0xe0062e12, + 0x0f42f53e, 0xd2075f86, 0xb025d6bf, 0x6d607c07, + 0x7460c4cd, 0xa9256e75, 0xcb07e74c, 0x16424df4, + 0x106227e5, 0xcd278d5d, 0xaf050464, 0x7240aedc, + 0x6b401616, 0xb605bcae, 0xd4273597, 0x09629f2f, + 0xe6264403, 0x3b63eebb, 0x59416782, 0x8404cd3a, + 0x9d0475f0, 0x4041df48, 0x22635671, 0xff26fcc9, + 0x2e238253, 0xf36628eb, 0x9144a1d2, 0x4c010b6a, + 0x5501b3a0, 0x88441918, 0xea669021, 0x37233a99, + 0xd867e1b5, 0x05224b0d, 0x6700c234, 0xba45688c, + 0xa345d046, 0x7e007afe, 0x1c22f3c7, 0xc167597f, + 0xc747336e, 0x1a0299d6, 0x782010ef, 0xa565ba57, + 0xbc65029d, 0x6120a825, 0x0302211c, 0xde478ba4, + 0x31035088, 0xec46fa30, 0x8e647309, 0x5321d9b1, + 0x4a21617b, 0x9764cbc3, 0xf54642fa, 0x2803e842 +}; + +// Used to fetch a naturally-aligned 32-bit word in little endian byte-order +static inline uint32_t LE_LOAD32(const uint8_t *p) { + return DecodeFixed32(reinterpret_cast(p)); +} + +// Determine if the CPU running this program can accelerate the CRC32C +// calculation. +static bool CanAccelerateCRC32C() { + // port::AcceleretedCRC32C returns zero when unable to accelerate. + static const char kTestCRCBuffer[] = "TestCRCBuffer"; + static const char kBufSize = sizeof(kTestCRCBuffer) - 1; + static const uint32_t kTestCRCValue = 0xdcbc59fa; + + return port::AcceleratedCRC32C(0, kTestCRCBuffer, kBufSize) == kTestCRCValue; +} + +uint32_t Extend(uint32_t crc, const char* buf, size_t size) { + static bool accelerate = CanAccelerateCRC32C(); + if (accelerate) { + return port::AcceleratedCRC32C(crc, buf, size); + } + + const uint8_t *p = reinterpret_cast(buf); + const uint8_t *e = p + size; + uint32_t l = crc ^ 0xffffffffu; + +#define STEP1 do { \ + int c = (l & 0xff) ^ *p++; \ + l = table0_[c] ^ (l >> 8); \ +} while (0) +#define STEP4 do { \ + uint32_t c = l ^ LE_LOAD32(p); \ + p += 4; \ + l = table3_[c & 0xff] ^ \ + table2_[(c >> 8) & 0xff] ^ \ + table1_[(c >> 16) & 0xff] ^ \ + table0_[c >> 24]; \ +} while (0) + + // Point x at first 4-byte aligned byte in string. This might be + // just past the end of the string. + const uintptr_t pval = reinterpret_cast(p); + const uint8_t* x = reinterpret_cast(((pval + 3) >> 2) << 2); + if (x <= e) { + // Process bytes until finished or p is 4-byte aligned + while (p != x) { + STEP1; + } + } + // Process bytes 16 at a time + while ((e-p) >= 16) { + STEP4; STEP4; STEP4; STEP4; + } + // Process bytes 4 at a time + while ((e-p) >= 4) { + STEP4; + } + // Process the last few bytes + while (p != e) { + STEP1; + } +#undef STEP4 +#undef STEP1 + return l ^ 0xffffffffu; +} + +} // namespace crc32c +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/util/crc32c.h b/ios/Pods/leveldb-library/util/crc32c.h new file mode 100644 index 00000000..1d7e5c07 --- /dev/null +++ b/ios/Pods/leveldb-library/util/crc32c.h @@ -0,0 +1,45 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_UTIL_CRC32C_H_ +#define STORAGE_LEVELDB_UTIL_CRC32C_H_ + +#include +#include + +namespace leveldb { +namespace crc32c { + +// Return the crc32c of concat(A, data[0,n-1]) where init_crc is the +// crc32c of some string A. Extend() is often used to maintain the +// crc32c of a stream of data. +extern uint32_t Extend(uint32_t init_crc, const char* data, size_t n); + +// Return the crc32c of data[0,n-1] +inline uint32_t Value(const char* data, size_t n) { + return Extend(0, data, n); +} + +static const uint32_t kMaskDelta = 0xa282ead8ul; + +// Return a masked representation of crc. +// +// Motivation: it is problematic to compute the CRC of a string that +// contains embedded CRCs. Therefore we recommend that CRCs stored +// somewhere (e.g., in files) should be masked before being stored. +inline uint32_t Mask(uint32_t crc) { + // Rotate right by 15 bits and add a constant. + return ((crc >> 15) | (crc << 17)) + kMaskDelta; +} + +// Return the crc whose masked representation is masked_crc. +inline uint32_t Unmask(uint32_t masked_crc) { + uint32_t rot = masked_crc - kMaskDelta; + return ((rot >> 17) | (rot << 15)); +} + +} // namespace crc32c +} // namespace leveldb + +#endif // STORAGE_LEVELDB_UTIL_CRC32C_H_ diff --git a/ios/Pods/leveldb-library/util/env.cc b/ios/Pods/leveldb-library/util/env.cc new file mode 100644 index 00000000..c58a0821 --- /dev/null +++ b/ios/Pods/leveldb-library/util/env.cc @@ -0,0 +1,100 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "leveldb/env.h" + +namespace leveldb { + +Env::~Env() { +} + +Status Env::NewAppendableFile(const std::string& fname, WritableFile** result) { + return Status::NotSupported("NewAppendableFile", fname); +} + +SequentialFile::~SequentialFile() { +} + +RandomAccessFile::~RandomAccessFile() { +} + +WritableFile::~WritableFile() { +} + +Logger::~Logger() { +} + +FileLock::~FileLock() { +} + +void Log(Logger* info_log, const char* format, ...) { + if (info_log != NULL) { + va_list ap; + va_start(ap, format); + info_log->Logv(format, ap); + va_end(ap); + } +} + +static Status DoWriteStringToFile(Env* env, const Slice& data, + const std::string& fname, + bool should_sync) { + WritableFile* file; + Status s = env->NewWritableFile(fname, &file); + if (!s.ok()) { + return s; + } + s = file->Append(data); + if (s.ok() && should_sync) { + s = file->Sync(); + } + if (s.ok()) { + s = file->Close(); + } + delete file; // Will auto-close if we did not close above + if (!s.ok()) { + env->DeleteFile(fname); + } + return s; +} + +Status WriteStringToFile(Env* env, const Slice& data, + const std::string& fname) { + return DoWriteStringToFile(env, data, fname, false); +} + +Status WriteStringToFileSync(Env* env, const Slice& data, + const std::string& fname) { + return DoWriteStringToFile(env, data, fname, true); +} + +Status ReadFileToString(Env* env, const std::string& fname, std::string* data) { + data->clear(); + SequentialFile* file; + Status s = env->NewSequentialFile(fname, &file); + if (!s.ok()) { + return s; + } + static const int kBufferSize = 8192; + char* space = new char[kBufferSize]; + while (true) { + Slice fragment; + s = file->Read(kBufferSize, &fragment, space); + if (!s.ok()) { + break; + } + data->append(fragment.data(), fragment.size()); + if (fragment.empty()) { + break; + } + } + delete[] space; + delete file; + return s; +} + +EnvWrapper::~EnvWrapper() { +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/util/env_posix.cc b/ios/Pods/leveldb-library/util/env_posix.cc new file mode 100644 index 00000000..84aabb20 --- /dev/null +++ b/ios/Pods/leveldb-library/util/env_posix.cc @@ -0,0 +1,695 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "leveldb/env.h" +#include "leveldb/slice.h" +#include "port/port.h" +#include "util/logging.h" +#include "util/mutexlock.h" +#include "util/posix_logger.h" +#include "util/env_posix_test_helper.h" + +namespace leveldb { + +namespace { + +static int open_read_only_file_limit = -1; +static int mmap_limit = -1; + +static Status IOError(const std::string& context, int err_number) { + return Status::IOError(context, strerror(err_number)); +} + +// Helper class to limit resource usage to avoid exhaustion. +// Currently used to limit read-only file descriptors and mmap file usage +// so that we do not end up running out of file descriptors, virtual memory, +// or running into kernel performance problems for very large databases. +class Limiter { + public: + // Limit maximum number of resources to |n|. + Limiter(intptr_t n) { + SetAllowed(n); + } + + // If another resource is available, acquire it and return true. + // Else return false. + bool Acquire() { + if (GetAllowed() <= 0) { + return false; + } + MutexLock l(&mu_); + intptr_t x = GetAllowed(); + if (x <= 0) { + return false; + } else { + SetAllowed(x - 1); + return true; + } + } + + // Release a resource acquired by a previous call to Acquire() that returned + // true. + void Release() { + MutexLock l(&mu_); + SetAllowed(GetAllowed() + 1); + } + + private: + port::Mutex mu_; + port::AtomicPointer allowed_; + + intptr_t GetAllowed() const { + return reinterpret_cast(allowed_.Acquire_Load()); + } + + // REQUIRES: mu_ must be held + void SetAllowed(intptr_t v) { + allowed_.Release_Store(reinterpret_cast(v)); + } + + Limiter(const Limiter&); + void operator=(const Limiter&); +}; + +class PosixSequentialFile: public SequentialFile { + private: + std::string filename_; + FILE* file_; + + public: + PosixSequentialFile(const std::string& fname, FILE* f) + : filename_(fname), file_(f) { } + virtual ~PosixSequentialFile() { fclose(file_); } + + virtual Status Read(size_t n, Slice* result, char* scratch) { + Status s; + size_t r = fread_unlocked(scratch, 1, n, file_); + *result = Slice(scratch, r); + if (r < n) { + if (feof(file_)) { + // We leave status as ok if we hit the end of the file + } else { + // A partial read with an error: return a non-ok status + s = IOError(filename_, errno); + } + } + return s; + } + + virtual Status Skip(uint64_t n) { + if (fseek(file_, n, SEEK_CUR)) { + return IOError(filename_, errno); + } + return Status::OK(); + } +}; + +// pread() based random-access +class PosixRandomAccessFile: public RandomAccessFile { + private: + std::string filename_; + bool temporary_fd_; // If true, fd_ is -1 and we open on every read. + int fd_; + Limiter* limiter_; + + public: + PosixRandomAccessFile(const std::string& fname, int fd, Limiter* limiter) + : filename_(fname), fd_(fd), limiter_(limiter) { + temporary_fd_ = !limiter->Acquire(); + if (temporary_fd_) { + // Open file on every access. + close(fd_); + fd_ = -1; + } + } + + virtual ~PosixRandomAccessFile() { + if (!temporary_fd_) { + close(fd_); + limiter_->Release(); + } + } + + virtual Status Read(uint64_t offset, size_t n, Slice* result, + char* scratch) const { + int fd = fd_; + if (temporary_fd_) { + fd = open(filename_.c_str(), O_RDONLY); + if (fd < 0) { + return IOError(filename_, errno); + } + } + + Status s; + ssize_t r = pread(fd, scratch, n, static_cast(offset)); + *result = Slice(scratch, (r < 0) ? 0 : r); + if (r < 0) { + // An error: return a non-ok status + s = IOError(filename_, errno); + } + if (temporary_fd_) { + // Close the temporary file descriptor opened earlier. + close(fd); + } + return s; + } +}; + +// mmap() based random-access +class PosixMmapReadableFile: public RandomAccessFile { + private: + std::string filename_; + void* mmapped_region_; + size_t length_; + Limiter* limiter_; + + public: + // base[0,length-1] contains the mmapped contents of the file. + PosixMmapReadableFile(const std::string& fname, void* base, size_t length, + Limiter* limiter) + : filename_(fname), mmapped_region_(base), length_(length), + limiter_(limiter) { + } + + virtual ~PosixMmapReadableFile() { + munmap(mmapped_region_, length_); + limiter_->Release(); + } + + virtual Status Read(uint64_t offset, size_t n, Slice* result, + char* scratch) const { + Status s; + if (offset + n > length_) { + *result = Slice(); + s = IOError(filename_, EINVAL); + } else { + *result = Slice(reinterpret_cast(mmapped_region_) + offset, n); + } + return s; + } +}; + +class PosixWritableFile : public WritableFile { + private: + std::string filename_; + FILE* file_; + + public: + PosixWritableFile(const std::string& fname, FILE* f) + : filename_(fname), file_(f) { } + + ~PosixWritableFile() { + if (file_ != NULL) { + // Ignoring any potential errors + fclose(file_); + } + } + + virtual Status Append(const Slice& data) { + size_t r = fwrite_unlocked(data.data(), 1, data.size(), file_); + if (r != data.size()) { + return IOError(filename_, errno); + } + return Status::OK(); + } + + virtual Status Close() { + Status result; + if (fclose(file_) != 0) { + result = IOError(filename_, errno); + } + file_ = NULL; + return result; + } + + virtual Status Flush() { + if (fflush_unlocked(file_) != 0) { + return IOError(filename_, errno); + } + return Status::OK(); + } + + Status SyncDirIfManifest() { + const char* f = filename_.c_str(); + const char* sep = strrchr(f, '/'); + Slice basename; + std::string dir; + if (sep == NULL) { + dir = "."; + basename = f; + } else { + dir = std::string(f, sep - f); + basename = sep + 1; + } + Status s; + if (basename.starts_with("MANIFEST")) { + int fd = open(dir.c_str(), O_RDONLY); + if (fd < 0) { + s = IOError(dir, errno); + } else { + if (fsync(fd) < 0) { + s = IOError(dir, errno); + } + close(fd); + } + } + return s; + } + + virtual Status Sync() { + // Ensure new files referred to by the manifest are in the filesystem. + Status s = SyncDirIfManifest(); + if (!s.ok()) { + return s; + } + if (fflush_unlocked(file_) != 0 || + fdatasync(fileno(file_)) != 0) { + s = Status::IOError(filename_, strerror(errno)); + } + return s; + } +}; + +static int LockOrUnlock(int fd, bool lock) { + errno = 0; + struct flock f; + memset(&f, 0, sizeof(f)); + f.l_type = (lock ? F_WRLCK : F_UNLCK); + f.l_whence = SEEK_SET; + f.l_start = 0; + f.l_len = 0; // Lock/unlock entire file + return fcntl(fd, F_SETLK, &f); +} + +class PosixFileLock : public FileLock { + public: + int fd_; + std::string name_; +}; + +// Set of locked files. We keep a separate set instead of just +// relying on fcntrl(F_SETLK) since fcntl(F_SETLK) does not provide +// any protection against multiple uses from the same process. +class PosixLockTable { + private: + port::Mutex mu_; + std::set locked_files_; + public: + bool Insert(const std::string& fname) { + MutexLock l(&mu_); + return locked_files_.insert(fname).second; + } + void Remove(const std::string& fname) { + MutexLock l(&mu_); + locked_files_.erase(fname); + } +}; + +class PosixEnv : public Env { + public: + PosixEnv(); + virtual ~PosixEnv() { + char msg[] = "Destroying Env::Default()\n"; + fwrite(msg, 1, sizeof(msg), stderr); + abort(); + } + + virtual Status NewSequentialFile(const std::string& fname, + SequentialFile** result) { + FILE* f = fopen(fname.c_str(), "r"); + if (f == NULL) { + *result = NULL; + return IOError(fname, errno); + } else { + *result = new PosixSequentialFile(fname, f); + return Status::OK(); + } + } + + virtual Status NewRandomAccessFile(const std::string& fname, + RandomAccessFile** result) { + *result = NULL; + Status s; + int fd = open(fname.c_str(), O_RDONLY); + if (fd < 0) { + s = IOError(fname, errno); + } else if (mmap_limit_.Acquire()) { + uint64_t size; + s = GetFileSize(fname, &size); + if (s.ok()) { + void* base = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + if (base != MAP_FAILED) { + *result = new PosixMmapReadableFile(fname, base, size, &mmap_limit_); + } else { + s = IOError(fname, errno); + } + } + close(fd); + if (!s.ok()) { + mmap_limit_.Release(); + } + } else { + *result = new PosixRandomAccessFile(fname, fd, &fd_limit_); + } + return s; + } + + virtual Status NewWritableFile(const std::string& fname, + WritableFile** result) { + Status s; + FILE* f = fopen(fname.c_str(), "w"); + if (f == NULL) { + *result = NULL; + s = IOError(fname, errno); + } else { + *result = new PosixWritableFile(fname, f); + } + return s; + } + + virtual Status NewAppendableFile(const std::string& fname, + WritableFile** result) { + Status s; + FILE* f = fopen(fname.c_str(), "a"); + if (f == NULL) { + *result = NULL; + s = IOError(fname, errno); + } else { + *result = new PosixWritableFile(fname, f); + } + return s; + } + + virtual bool FileExists(const std::string& fname) { + return access(fname.c_str(), F_OK) == 0; + } + + virtual Status GetChildren(const std::string& dir, + std::vector* result) { + result->clear(); + DIR* d = opendir(dir.c_str()); + if (d == NULL) { + return IOError(dir, errno); + } + struct dirent* entry; + while ((entry = readdir(d)) != NULL) { + result->push_back(entry->d_name); + } + closedir(d); + return Status::OK(); + } + + virtual Status DeleteFile(const std::string& fname) { + Status result; + if (unlink(fname.c_str()) != 0) { + result = IOError(fname, errno); + } + return result; + } + + virtual Status CreateDir(const std::string& name) { + Status result; + if (mkdir(name.c_str(), 0755) != 0) { + result = IOError(name, errno); + } + return result; + } + + virtual Status DeleteDir(const std::string& name) { + Status result; + if (rmdir(name.c_str()) != 0) { + result = IOError(name, errno); + } + return result; + } + + virtual Status GetFileSize(const std::string& fname, uint64_t* size) { + Status s; + struct stat sbuf; + if (stat(fname.c_str(), &sbuf) != 0) { + *size = 0; + s = IOError(fname, errno); + } else { + *size = sbuf.st_size; + } + return s; + } + + virtual Status RenameFile(const std::string& src, const std::string& target) { + Status result; + if (rename(src.c_str(), target.c_str()) != 0) { + result = IOError(src, errno); + } + return result; + } + + virtual Status LockFile(const std::string& fname, FileLock** lock) { + *lock = NULL; + Status result; + int fd = open(fname.c_str(), O_RDWR | O_CREAT, 0644); + if (fd < 0) { + result = IOError(fname, errno); + } else if (!locks_.Insert(fname)) { + close(fd); + result = Status::IOError("lock " + fname, "already held by process"); + } else if (LockOrUnlock(fd, true) == -1) { + result = IOError("lock " + fname, errno); + close(fd); + locks_.Remove(fname); + } else { + PosixFileLock* my_lock = new PosixFileLock; + my_lock->fd_ = fd; + my_lock->name_ = fname; + *lock = my_lock; + } + return result; + } + + virtual Status UnlockFile(FileLock* lock) { + PosixFileLock* my_lock = reinterpret_cast(lock); + Status result; + if (LockOrUnlock(my_lock->fd_, false) == -1) { + result = IOError("unlock", errno); + } + locks_.Remove(my_lock->name_); + close(my_lock->fd_); + delete my_lock; + return result; + } + + virtual void Schedule(void (*function)(void*), void* arg); + + virtual void StartThread(void (*function)(void* arg), void* arg); + + virtual Status GetTestDirectory(std::string* result) { + const char* env = getenv("TEST_TMPDIR"); + if (env && env[0] != '\0') { + *result = env; + } else { + char buf[100]; + snprintf(buf, sizeof(buf), "/tmp/leveldbtest-%d", int(geteuid())); + *result = buf; + } + // Directory may already exist + CreateDir(*result); + return Status::OK(); + } + + static uint64_t gettid() { + pthread_t tid = pthread_self(); + uint64_t thread_id = 0; + memcpy(&thread_id, &tid, std::min(sizeof(thread_id), sizeof(tid))); + return thread_id; + } + + virtual Status NewLogger(const std::string& fname, Logger** result) { + FILE* f = fopen(fname.c_str(), "w"); + if (f == NULL) { + *result = NULL; + return IOError(fname, errno); + } else { + *result = new PosixLogger(f, &PosixEnv::gettid); + return Status::OK(); + } + } + + virtual uint64_t NowMicros() { + struct timeval tv; + gettimeofday(&tv, NULL); + return static_cast(tv.tv_sec) * 1000000 + tv.tv_usec; + } + + virtual void SleepForMicroseconds(int micros) { + usleep(micros); + } + + private: + void PthreadCall(const char* label, int result) { + if (result != 0) { + fprintf(stderr, "pthread %s: %s\n", label, strerror(result)); + abort(); + } + } + + // BGThread() is the body of the background thread + void BGThread(); + static void* BGThreadWrapper(void* arg) { + reinterpret_cast(arg)->BGThread(); + return NULL; + } + + pthread_mutex_t mu_; + pthread_cond_t bgsignal_; + pthread_t bgthread_; + bool started_bgthread_; + + // Entry per Schedule() call + struct BGItem { void* arg; void (*function)(void*); }; + typedef std::deque BGQueue; + BGQueue queue_; + + PosixLockTable locks_; + Limiter mmap_limit_; + Limiter fd_limit_; +}; + +// Return the maximum number of concurrent mmaps. +static int MaxMmaps() { + if (mmap_limit >= 0) { + return mmap_limit; + } + // Up to 1000 mmaps for 64-bit binaries; none for smaller pointer sizes. + mmap_limit = sizeof(void*) >= 8 ? 1000 : 0; + return mmap_limit; +} + +// Return the maximum number of read-only files to keep open. +static intptr_t MaxOpenFiles() { + if (open_read_only_file_limit >= 0) { + return open_read_only_file_limit; + } + struct rlimit rlim; + if (getrlimit(RLIMIT_NOFILE, &rlim)) { + // getrlimit failed, fallback to hard-coded default. + open_read_only_file_limit = 50; + } else if (rlim.rlim_cur == RLIM_INFINITY) { + open_read_only_file_limit = std::numeric_limits::max(); + } else { + // Allow use of 20% of available file descriptors for read-only files. + open_read_only_file_limit = rlim.rlim_cur / 5; + } + return open_read_only_file_limit; +} + +PosixEnv::PosixEnv() + : started_bgthread_(false), + mmap_limit_(MaxMmaps()), + fd_limit_(MaxOpenFiles()) { + PthreadCall("mutex_init", pthread_mutex_init(&mu_, NULL)); + PthreadCall("cvar_init", pthread_cond_init(&bgsignal_, NULL)); +} + +void PosixEnv::Schedule(void (*function)(void*), void* arg) { + PthreadCall("lock", pthread_mutex_lock(&mu_)); + + // Start background thread if necessary + if (!started_bgthread_) { + started_bgthread_ = true; + PthreadCall( + "create thread", + pthread_create(&bgthread_, NULL, &PosixEnv::BGThreadWrapper, this)); + } + + // If the queue is currently empty, the background thread may currently be + // waiting. + if (queue_.empty()) { + PthreadCall("signal", pthread_cond_signal(&bgsignal_)); + } + + // Add to priority queue + queue_.push_back(BGItem()); + queue_.back().function = function; + queue_.back().arg = arg; + + PthreadCall("unlock", pthread_mutex_unlock(&mu_)); +} + +void PosixEnv::BGThread() { + while (true) { + // Wait until there is an item that is ready to run + PthreadCall("lock", pthread_mutex_lock(&mu_)); + while (queue_.empty()) { + PthreadCall("wait", pthread_cond_wait(&bgsignal_, &mu_)); + } + + void (*function)(void*) = queue_.front().function; + void* arg = queue_.front().arg; + queue_.pop_front(); + + PthreadCall("unlock", pthread_mutex_unlock(&mu_)); + (*function)(arg); + } +} + +namespace { +struct StartThreadState { + void (*user_function)(void*); + void* arg; +}; +} +static void* StartThreadWrapper(void* arg) { + StartThreadState* state = reinterpret_cast(arg); + state->user_function(state->arg); + delete state; + return NULL; +} + +void PosixEnv::StartThread(void (*function)(void* arg), void* arg) { + pthread_t t; + StartThreadState* state = new StartThreadState; + state->user_function = function; + state->arg = arg; + PthreadCall("start thread", + pthread_create(&t, NULL, &StartThreadWrapper, state)); +} + +} // namespace + +static pthread_once_t once = PTHREAD_ONCE_INIT; +static Env* default_env; +static void InitDefaultEnv() { default_env = new PosixEnv; } + +void EnvPosixTestHelper::SetReadOnlyFDLimit(int limit) { + assert(default_env == NULL); + open_read_only_file_limit = limit; +} + +void EnvPosixTestHelper::SetReadOnlyMMapLimit(int limit) { + assert(default_env == NULL); + mmap_limit = limit; +} + +Env* Env::Default() { + pthread_once(&once, InitDefaultEnv); + return default_env; +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/util/env_posix_test_helper.h b/ios/Pods/leveldb-library/util/env_posix_test_helper.h new file mode 100644 index 00000000..03869605 --- /dev/null +++ b/ios/Pods/leveldb-library/util/env_posix_test_helper.h @@ -0,0 +1,28 @@ +// Copyright 2017 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_UTIL_ENV_POSIX_TEST_HELPER_H_ +#define STORAGE_LEVELDB_UTIL_ENV_POSIX_TEST_HELPER_H_ + +namespace leveldb { + +class EnvPosixTest; + +// A helper for the POSIX Env to facilitate testing. +class EnvPosixTestHelper { + private: + friend class EnvPosixTest; + + // Set the maximum number of read-only files that will be opened. + // Must be called before creating an Env. + static void SetReadOnlyFDLimit(int limit); + + // Set the maximum number of read-only files that will be mapped via mmap. + // Must be called before creating an Env. + static void SetReadOnlyMMapLimit(int limit); +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_UTIL_ENV_POSIX_TEST_HELPER_H_ diff --git a/ios/Pods/leveldb-library/util/filter_policy.cc b/ios/Pods/leveldb-library/util/filter_policy.cc new file mode 100644 index 00000000..7b045c8c --- /dev/null +++ b/ios/Pods/leveldb-library/util/filter_policy.cc @@ -0,0 +1,11 @@ +// Copyright (c) 2012 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "leveldb/filter_policy.h" + +namespace leveldb { + +FilterPolicy::~FilterPolicy() { } + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/util/hash.cc b/ios/Pods/leveldb-library/util/hash.cc new file mode 100644 index 00000000..ed439ce7 --- /dev/null +++ b/ios/Pods/leveldb-library/util/hash.cc @@ -0,0 +1,52 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include +#include "util/coding.h" +#include "util/hash.h" + +// The FALLTHROUGH_INTENDED macro can be used to annotate implicit fall-through +// between switch labels. The real definition should be provided externally. +// This one is a fallback version for unsupported compilers. +#ifndef FALLTHROUGH_INTENDED +#define FALLTHROUGH_INTENDED do { } while (0) +#endif + +namespace leveldb { + +uint32_t Hash(const char* data, size_t n, uint32_t seed) { + // Similar to murmur hash + const uint32_t m = 0xc6a4a793; + const uint32_t r = 24; + const char* limit = data + n; + uint32_t h = seed ^ (n * m); + + // Pick up four bytes at a time + while (data + 4 <= limit) { + uint32_t w = DecodeFixed32(data); + data += 4; + h += w; + h *= m; + h ^= (h >> 16); + } + + // Pick up remaining bytes + switch (limit - data) { + case 3: + h += static_cast(data[2]) << 16; + FALLTHROUGH_INTENDED; + case 2: + h += static_cast(data[1]) << 8; + FALLTHROUGH_INTENDED; + case 1: + h += static_cast(data[0]); + h *= m; + h ^= (h >> r); + break; + } + return h; +} + + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/util/hash.h b/ios/Pods/leveldb-library/util/hash.h new file mode 100644 index 00000000..8889d56b --- /dev/null +++ b/ios/Pods/leveldb-library/util/hash.h @@ -0,0 +1,19 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// Simple hash function used for internal data structures + +#ifndef STORAGE_LEVELDB_UTIL_HASH_H_ +#define STORAGE_LEVELDB_UTIL_HASH_H_ + +#include +#include + +namespace leveldb { + +extern uint32_t Hash(const char* data, size_t n, uint32_t seed); + +} + +#endif // STORAGE_LEVELDB_UTIL_HASH_H_ diff --git a/ios/Pods/leveldb-library/util/histogram.cc b/ios/Pods/leveldb-library/util/histogram.cc new file mode 100644 index 00000000..bb95f583 --- /dev/null +++ b/ios/Pods/leveldb-library/util/histogram.cc @@ -0,0 +1,139 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include +#include +#include "port/port.h" +#include "util/histogram.h" + +namespace leveldb { + +const double Histogram::kBucketLimit[kNumBuckets] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 25, 30, 35, 40, 45, + 50, 60, 70, 80, 90, 100, 120, 140, 160, 180, 200, 250, 300, 350, 400, 450, + 500, 600, 700, 800, 900, 1000, 1200, 1400, 1600, 1800, 2000, 2500, 3000, + 3500, 4000, 4500, 5000, 6000, 7000, 8000, 9000, 10000, 12000, 14000, + 16000, 18000, 20000, 25000, 30000, 35000, 40000, 45000, 50000, 60000, + 70000, 80000, 90000, 100000, 120000, 140000, 160000, 180000, 200000, + 250000, 300000, 350000, 400000, 450000, 500000, 600000, 700000, 800000, + 900000, 1000000, 1200000, 1400000, 1600000, 1800000, 2000000, 2500000, + 3000000, 3500000, 4000000, 4500000, 5000000, 6000000, 7000000, 8000000, + 9000000, 10000000, 12000000, 14000000, 16000000, 18000000, 20000000, + 25000000, 30000000, 35000000, 40000000, 45000000, 50000000, 60000000, + 70000000, 80000000, 90000000, 100000000, 120000000, 140000000, 160000000, + 180000000, 200000000, 250000000, 300000000, 350000000, 400000000, + 450000000, 500000000, 600000000, 700000000, 800000000, 900000000, + 1000000000, 1200000000, 1400000000, 1600000000, 1800000000, 2000000000, + 2500000000.0, 3000000000.0, 3500000000.0, 4000000000.0, 4500000000.0, + 5000000000.0, 6000000000.0, 7000000000.0, 8000000000.0, 9000000000.0, + 1e200, +}; + +void Histogram::Clear() { + min_ = kBucketLimit[kNumBuckets-1]; + max_ = 0; + num_ = 0; + sum_ = 0; + sum_squares_ = 0; + for (int i = 0; i < kNumBuckets; i++) { + buckets_[i] = 0; + } +} + +void Histogram::Add(double value) { + // Linear search is fast enough for our usage in db_bench + int b = 0; + while (b < kNumBuckets - 1 && kBucketLimit[b] <= value) { + b++; + } + buckets_[b] += 1.0; + if (min_ > value) min_ = value; + if (max_ < value) max_ = value; + num_++; + sum_ += value; + sum_squares_ += (value * value); +} + +void Histogram::Merge(const Histogram& other) { + if (other.min_ < min_) min_ = other.min_; + if (other.max_ > max_) max_ = other.max_; + num_ += other.num_; + sum_ += other.sum_; + sum_squares_ += other.sum_squares_; + for (int b = 0; b < kNumBuckets; b++) { + buckets_[b] += other.buckets_[b]; + } +} + +double Histogram::Median() const { + return Percentile(50.0); +} + +double Histogram::Percentile(double p) const { + double threshold = num_ * (p / 100.0); + double sum = 0; + for (int b = 0; b < kNumBuckets; b++) { + sum += buckets_[b]; + if (sum >= threshold) { + // Scale linearly within this bucket + double left_point = (b == 0) ? 0 : kBucketLimit[b-1]; + double right_point = kBucketLimit[b]; + double left_sum = sum - buckets_[b]; + double right_sum = sum; + double pos = (threshold - left_sum) / (right_sum - left_sum); + double r = left_point + (right_point - left_point) * pos; + if (r < min_) r = min_; + if (r > max_) r = max_; + return r; + } + } + return max_; +} + +double Histogram::Average() const { + if (num_ == 0.0) return 0; + return sum_ / num_; +} + +double Histogram::StandardDeviation() const { + if (num_ == 0.0) return 0; + double variance = (sum_squares_ * num_ - sum_ * sum_) / (num_ * num_); + return sqrt(variance); +} + +std::string Histogram::ToString() const { + std::string r; + char buf[200]; + snprintf(buf, sizeof(buf), + "Count: %.0f Average: %.4f StdDev: %.2f\n", + num_, Average(), StandardDeviation()); + r.append(buf); + snprintf(buf, sizeof(buf), + "Min: %.4f Median: %.4f Max: %.4f\n", + (num_ == 0.0 ? 0.0 : min_), Median(), max_); + r.append(buf); + r.append("------------------------------------------------------\n"); + const double mult = 100.0 / num_; + double sum = 0; + for (int b = 0; b < kNumBuckets; b++) { + if (buckets_[b] <= 0.0) continue; + sum += buckets_[b]; + snprintf(buf, sizeof(buf), + "[ %7.0f, %7.0f ) %7.0f %7.3f%% %7.3f%% ", + ((b == 0) ? 0.0 : kBucketLimit[b-1]), // left + kBucketLimit[b], // right + buckets_[b], // count + mult * buckets_[b], // percentage + mult * sum); // cumulative percentage + r.append(buf); + + // Add hash marks based on percentage; 20 marks for 100%. + int marks = static_cast(20*(buckets_[b] / num_) + 0.5); + r.append(marks, '#'); + r.push_back('\n'); + } + return r; +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/util/histogram.h b/ios/Pods/leveldb-library/util/histogram.h new file mode 100644 index 00000000..1ef9f3c8 --- /dev/null +++ b/ios/Pods/leveldb-library/util/histogram.h @@ -0,0 +1,42 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_UTIL_HISTOGRAM_H_ +#define STORAGE_LEVELDB_UTIL_HISTOGRAM_H_ + +#include + +namespace leveldb { + +class Histogram { + public: + Histogram() { } + ~Histogram() { } + + void Clear(); + void Add(double value); + void Merge(const Histogram& other); + + std::string ToString() const; + + private: + double min_; + double max_; + double num_; + double sum_; + double sum_squares_; + + enum { kNumBuckets = 154 }; + static const double kBucketLimit[kNumBuckets]; + double buckets_[kNumBuckets]; + + double Median() const; + double Percentile(double p) const; + double Average() const; + double StandardDeviation() const; +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_UTIL_HISTOGRAM_H_ diff --git a/ios/Pods/leveldb-library/util/logging.cc b/ios/Pods/leveldb-library/util/logging.cc new file mode 100644 index 00000000..ca6b3244 --- /dev/null +++ b/ios/Pods/leveldb-library/util/logging.cc @@ -0,0 +1,72 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "util/logging.h" + +#include +#include +#include +#include +#include "leveldb/env.h" +#include "leveldb/slice.h" + +namespace leveldb { + +void AppendNumberTo(std::string* str, uint64_t num) { + char buf[30]; + snprintf(buf, sizeof(buf), "%llu", (unsigned long long) num); + str->append(buf); +} + +void AppendEscapedStringTo(std::string* str, const Slice& value) { + for (size_t i = 0; i < value.size(); i++) { + char c = value[i]; + if (c >= ' ' && c <= '~') { + str->push_back(c); + } else { + char buf[10]; + snprintf(buf, sizeof(buf), "\\x%02x", + static_cast(c) & 0xff); + str->append(buf); + } + } +} + +std::string NumberToString(uint64_t num) { + std::string r; + AppendNumberTo(&r, num); + return r; +} + +std::string EscapeString(const Slice& value) { + std::string r; + AppendEscapedStringTo(&r, value); + return r; +} + +bool ConsumeDecimalNumber(Slice* in, uint64_t* val) { + uint64_t v = 0; + int digits = 0; + while (!in->empty()) { + char c = (*in)[0]; + if (c >= '0' && c <= '9') { + ++digits; + const int delta = (c - '0'); + static const uint64_t kMaxUint64 = ~static_cast(0); + if (v > kMaxUint64/10 || + (v == kMaxUint64/10 && delta > kMaxUint64%10)) { + // Overflow + return false; + } + v = (v * 10) + delta; + in->remove_prefix(1); + } else { + break; + } + } + *val = v; + return (digits > 0); +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/util/logging.h b/ios/Pods/leveldb-library/util/logging.h new file mode 100644 index 00000000..1b450d24 --- /dev/null +++ b/ios/Pods/leveldb-library/util/logging.h @@ -0,0 +1,43 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// Must not be included from any .h files to avoid polluting the namespace +// with macros. + +#ifndef STORAGE_LEVELDB_UTIL_LOGGING_H_ +#define STORAGE_LEVELDB_UTIL_LOGGING_H_ + +#include +#include +#include +#include "port/port.h" + +namespace leveldb { + +class Slice; +class WritableFile; + +// Append a human-readable printout of "num" to *str +extern void AppendNumberTo(std::string* str, uint64_t num); + +// Append a human-readable printout of "value" to *str. +// Escapes any non-printable characters found in "value". +extern void AppendEscapedStringTo(std::string* str, const Slice& value); + +// Return a human-readable printout of "num" +extern std::string NumberToString(uint64_t num); + +// Return a human-readable version of "value". +// Escapes any non-printable characters found in "value". +extern std::string EscapeString(const Slice& value); + +// Parse a human-readable number from "*in" into *value. On success, +// advances "*in" past the consumed number and sets "*val" to the +// numeric value. Otherwise, returns false and leaves *in in an +// unspecified state. +extern bool ConsumeDecimalNumber(Slice* in, uint64_t* val); + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_UTIL_LOGGING_H_ diff --git a/ios/Pods/leveldb-library/util/mutexlock.h b/ios/Pods/leveldb-library/util/mutexlock.h new file mode 100644 index 00000000..1ff5a9ef --- /dev/null +++ b/ios/Pods/leveldb-library/util/mutexlock.h @@ -0,0 +1,41 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_UTIL_MUTEXLOCK_H_ +#define STORAGE_LEVELDB_UTIL_MUTEXLOCK_H_ + +#include "port/port.h" +#include "port/thread_annotations.h" + +namespace leveldb { + +// Helper class that locks a mutex on construction and unlocks the mutex when +// the destructor of the MutexLock object is invoked. +// +// Typical usage: +// +// void MyClass::MyMethod() { +// MutexLock l(&mu_); // mu_ is an instance variable +// ... some complex code, possibly with multiple return paths ... +// } + +class SCOPED_LOCKABLE MutexLock { + public: + explicit MutexLock(port::Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu) + : mu_(mu) { + this->mu_->Lock(); + } + ~MutexLock() UNLOCK_FUNCTION() { this->mu_->Unlock(); } + + private: + port::Mutex *const mu_; + // No copying allowed + MutexLock(const MutexLock&); + void operator=(const MutexLock&); +}; + +} // namespace leveldb + + +#endif // STORAGE_LEVELDB_UTIL_MUTEXLOCK_H_ diff --git a/ios/Pods/leveldb-library/util/options.cc b/ios/Pods/leveldb-library/util/options.cc new file mode 100644 index 00000000..b5e62276 --- /dev/null +++ b/ios/Pods/leveldb-library/util/options.cc @@ -0,0 +1,30 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "leveldb/options.h" + +#include "leveldb/comparator.h" +#include "leveldb/env.h" + +namespace leveldb { + +Options::Options() + : comparator(BytewiseComparator()), + create_if_missing(false), + error_if_exists(false), + paranoid_checks(false), + env(Env::Default()), + info_log(NULL), + write_buffer_size(4<<20), + max_open_files(1000), + block_cache(NULL), + block_size(4096), + block_restart_interval(16), + max_file_size(2<<20), + compression(kSnappyCompression), + reuse_logs(false), + filter_policy(NULL) { +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/util/posix_logger.h b/ios/Pods/leveldb-library/util/posix_logger.h new file mode 100644 index 00000000..9741b1af --- /dev/null +++ b/ios/Pods/leveldb-library/util/posix_logger.h @@ -0,0 +1,98 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// Logger implementation that can be shared by all environments +// where enough posix functionality is available. + +#ifndef STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_ +#define STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_ + +#include +#include +#include +#include +#include "leveldb/env.h" + +namespace leveldb { + +class PosixLogger : public Logger { + private: + FILE* file_; + uint64_t (*gettid_)(); // Return the thread id for the current thread + public: + PosixLogger(FILE* f, uint64_t (*gettid)()) : file_(f), gettid_(gettid) { } + virtual ~PosixLogger() { + fclose(file_); + } + virtual void Logv(const char* format, va_list ap) { + const uint64_t thread_id = (*gettid_)(); + + // We try twice: the first time with a fixed-size stack allocated buffer, + // and the second time with a much larger dynamically allocated buffer. + char buffer[500]; + for (int iter = 0; iter < 2; iter++) { + char* base; + int bufsize; + if (iter == 0) { + bufsize = sizeof(buffer); + base = buffer; + } else { + bufsize = 30000; + base = new char[bufsize]; + } + char* p = base; + char* limit = base + bufsize; + + struct timeval now_tv; + gettimeofday(&now_tv, NULL); + const time_t seconds = now_tv.tv_sec; + struct tm t; + localtime_r(&seconds, &t); + p += snprintf(p, limit - p, + "%04d/%02d/%02d-%02d:%02d:%02d.%06d %llx ", + t.tm_year + 1900, + t.tm_mon + 1, + t.tm_mday, + t.tm_hour, + t.tm_min, + t.tm_sec, + static_cast(now_tv.tv_usec), + static_cast(thread_id)); + + // Print the message + if (p < limit) { + va_list backup_ap; + va_copy(backup_ap, ap); + p += vsnprintf(p, limit - p, format, backup_ap); + va_end(backup_ap); + } + + // Truncate to available space if necessary + if (p >= limit) { + if (iter == 0) { + continue; // Try again with larger buffer + } else { + p = limit - 1; + } + } + + // Add newline if necessary + if (p == base || p[-1] != '\n') { + *p++ = '\n'; + } + + assert(p <= limit); + fwrite(base, 1, p - base, file_); + fflush(file_); + if (base != buffer) { + delete[] base; + } + break; + } + } +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_ diff --git a/ios/Pods/leveldb-library/util/random.h b/ios/Pods/leveldb-library/util/random.h new file mode 100644 index 00000000..ddd51b1c --- /dev/null +++ b/ios/Pods/leveldb-library/util/random.h @@ -0,0 +1,64 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_UTIL_RANDOM_H_ +#define STORAGE_LEVELDB_UTIL_RANDOM_H_ + +#include + +namespace leveldb { + +// A very simple random number generator. Not especially good at +// generating truly random bits, but good enough for our needs in this +// package. +class Random { + private: + uint32_t seed_; + public: + explicit Random(uint32_t s) : seed_(s & 0x7fffffffu) { + // Avoid bad seeds. + if (seed_ == 0 || seed_ == 2147483647L) { + seed_ = 1; + } + } + uint32_t Next() { + static const uint32_t M = 2147483647L; // 2^31-1 + static const uint64_t A = 16807; // bits 14, 8, 7, 5, 2, 1, 0 + // We are computing + // seed_ = (seed_ * A) % M, where M = 2^31-1 + // + // seed_ must not be zero or M, or else all subsequent computed values + // will be zero or M respectively. For all other values, seed_ will end + // up cycling through every number in [1,M-1] + uint64_t product = seed_ * A; + + // Compute (product % M) using the fact that ((x << 31) % M) == x. + seed_ = static_cast((product >> 31) + (product & M)); + // The first reduction may overflow by 1 bit, so we may need to + // repeat. mod == M is not possible; using > allows the faster + // sign-bit-based test. + if (seed_ > M) { + seed_ -= M; + } + return seed_; + } + // Returns a uniformly distributed value in the range [0..n-1] + // REQUIRES: n > 0 + uint32_t Uniform(int n) { return Next() % n; } + + // Randomly returns true ~"1/n" of the time, and false otherwise. + // REQUIRES: n > 0 + bool OneIn(int n) { return (Next() % n) == 0; } + + // Skewed: pick "base" uniformly from range [0,max_log] and then + // return "base" random bits. The effect is to pick a number in the + // range [0,2^max_log-1] with exponential bias towards smaller numbers. + uint32_t Skewed(int max_log) { + return Uniform(1 << Uniform(max_log + 1)); + } +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_UTIL_RANDOM_H_ diff --git a/ios/Pods/leveldb-library/util/status.cc b/ios/Pods/leveldb-library/util/status.cc new file mode 100644 index 00000000..a44f35b3 --- /dev/null +++ b/ios/Pods/leveldb-library/util/status.cc @@ -0,0 +1,75 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include +#include "port/port.h" +#include "leveldb/status.h" + +namespace leveldb { + +const char* Status::CopyState(const char* state) { + uint32_t size; + memcpy(&size, state, sizeof(size)); + char* result = new char[size + 5]; + memcpy(result, state, size + 5); + return result; +} + +Status::Status(Code code, const Slice& msg, const Slice& msg2) { + assert(code != kOk); + const uint32_t len1 = msg.size(); + const uint32_t len2 = msg2.size(); + const uint32_t size = len1 + (len2 ? (2 + len2) : 0); + char* result = new char[size + 5]; + memcpy(result, &size, sizeof(size)); + result[4] = static_cast(code); + memcpy(result + 5, msg.data(), len1); + if (len2) { + result[5 + len1] = ':'; + result[6 + len1] = ' '; + memcpy(result + 7 + len1, msg2.data(), len2); + } + state_ = result; +} + +std::string Status::ToString() const { + if (state_ == NULL) { + return "OK"; + } else { + char tmp[30]; + const char* type; + switch (code()) { + case kOk: + type = "OK"; + break; + case kNotFound: + type = "NotFound: "; + break; + case kCorruption: + type = "Corruption: "; + break; + case kNotSupported: + type = "Not implemented: "; + break; + case kInvalidArgument: + type = "Invalid argument: "; + break; + case kIOError: + type = "IO error: "; + break; + default: + snprintf(tmp, sizeof(tmp), "Unknown code(%d): ", + static_cast(code())); + type = tmp; + break; + } + std::string result(type); + uint32_t length; + memcpy(&length, state_, sizeof(length)); + result.append(state_ + 5, length); + return result; + } +} + +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/util/testharness.cc b/ios/Pods/leveldb-library/util/testharness.cc new file mode 100644 index 00000000..402fab34 --- /dev/null +++ b/ios/Pods/leveldb-library/util/testharness.cc @@ -0,0 +1,77 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "util/testharness.h" + +#include +#include +#include +#include + +namespace leveldb { +namespace test { + +namespace { +struct Test { + const char* base; + const char* name; + void (*func)(); +}; +std::vector* tests; +} + +bool RegisterTest(const char* base, const char* name, void (*func)()) { + if (tests == NULL) { + tests = new std::vector; + } + Test t; + t.base = base; + t.name = name; + t.func = func; + tests->push_back(t); + return true; +} + +int RunAllTests() { + const char* matcher = getenv("LEVELDB_TESTS"); + + int num = 0; + if (tests != NULL) { + for (size_t i = 0; i < tests->size(); i++) { + const Test& t = (*tests)[i]; + if (matcher != NULL) { + std::string name = t.base; + name.push_back('.'); + name.append(t.name); + if (strstr(name.c_str(), matcher) == NULL) { + continue; + } + } + fprintf(stderr, "==== Test %s.%s\n", t.base, t.name); + (*t.func)(); + ++num; + } + } + fprintf(stderr, "==== PASSED %d tests\n", num); + return 0; +} + +std::string TmpDir() { + std::string dir; + Status s = Env::Default()->GetTestDirectory(&dir); + ASSERT_TRUE(s.ok()) << s.ToString(); + return dir; +} + +int RandomSeed() { + const char* env = getenv("TEST_RANDOM_SEED"); + int result = (env != NULL ? atoi(env) : 301); + if (result <= 0) { + result = 301; + } + return result; +} + +} // namespace test +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/util/testharness.h b/ios/Pods/leveldb-library/util/testharness.h new file mode 100644 index 00000000..da4fe68b --- /dev/null +++ b/ios/Pods/leveldb-library/util/testharness.h @@ -0,0 +1,138 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_UTIL_TESTHARNESS_H_ +#define STORAGE_LEVELDB_UTIL_TESTHARNESS_H_ + +#include +#include +#include +#include "leveldb/env.h" +#include "leveldb/slice.h" +#include "util/random.h" + +namespace leveldb { +namespace test { + +// Run some of the tests registered by the TEST() macro. If the +// environment variable "LEVELDB_TESTS" is not set, runs all tests. +// Otherwise, runs only the tests whose name contains the value of +// "LEVELDB_TESTS" as a substring. E.g., suppose the tests are: +// TEST(Foo, Hello) { ... } +// TEST(Foo, World) { ... } +// LEVELDB_TESTS=Hello will run the first test +// LEVELDB_TESTS=o will run both tests +// LEVELDB_TESTS=Junk will run no tests +// +// Returns 0 if all tests pass. +// Dies or returns a non-zero value if some test fails. +extern int RunAllTests(); + +// Return the directory to use for temporary storage. +extern std::string TmpDir(); + +// Return a randomization seed for this run. Typically returns the +// same number on repeated invocations of this binary, but automated +// runs may be able to vary the seed. +extern int RandomSeed(); + +// An instance of Tester is allocated to hold temporary state during +// the execution of an assertion. +class Tester { + private: + bool ok_; + const char* fname_; + int line_; + std::stringstream ss_; + + public: + Tester(const char* f, int l) + : ok_(true), fname_(f), line_(l) { + } + + ~Tester() { + if (!ok_) { + fprintf(stderr, "%s:%d:%s\n", fname_, line_, ss_.str().c_str()); + exit(1); + } + } + + Tester& Is(bool b, const char* msg) { + if (!b) { + ss_ << " Assertion failure " << msg; + ok_ = false; + } + return *this; + } + + Tester& IsOk(const Status& s) { + if (!s.ok()) { + ss_ << " " << s.ToString(); + ok_ = false; + } + return *this; + } + +#define BINARY_OP(name,op) \ + template \ + Tester& name(const X& x, const Y& y) { \ + if (! (x op y)) { \ + ss_ << " failed: " << x << (" " #op " ") << y; \ + ok_ = false; \ + } \ + return *this; \ + } + + BINARY_OP(IsEq, ==) + BINARY_OP(IsNe, !=) + BINARY_OP(IsGe, >=) + BINARY_OP(IsGt, >) + BINARY_OP(IsLe, <=) + BINARY_OP(IsLt, <) +#undef BINARY_OP + + // Attach the specified value to the error message if an error has occurred + template + Tester& operator<<(const V& value) { + if (!ok_) { + ss_ << " " << value; + } + return *this; + } +}; + +#define ASSERT_TRUE(c) ::leveldb::test::Tester(__FILE__, __LINE__).Is((c), #c) +#define ASSERT_OK(s) ::leveldb::test::Tester(__FILE__, __LINE__).IsOk((s)) +#define ASSERT_EQ(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsEq((a),(b)) +#define ASSERT_NE(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsNe((a),(b)) +#define ASSERT_GE(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsGe((a),(b)) +#define ASSERT_GT(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsGt((a),(b)) +#define ASSERT_LE(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsLe((a),(b)) +#define ASSERT_LT(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsLt((a),(b)) + +#define TCONCAT(a,b) TCONCAT1(a,b) +#define TCONCAT1(a,b) a##b + +#define TEST(base,name) \ +class TCONCAT(_Test_,name) : public base { \ + public: \ + void _Run(); \ + static void _RunIt() { \ + TCONCAT(_Test_,name) t; \ + t._Run(); \ + } \ +}; \ +bool TCONCAT(_Test_ignored_,name) = \ + ::leveldb::test::RegisterTest(#base, #name, &TCONCAT(_Test_,name)::_RunIt); \ +void TCONCAT(_Test_,name)::_Run() + +// Register the specified test. Typically not used directly, but +// invoked via the macro expansion of TEST. +extern bool RegisterTest(const char* base, const char* name, void (*func)()); + + +} // namespace test +} // namespace leveldb + +#endif // STORAGE_LEVELDB_UTIL_TESTHARNESS_H_ diff --git a/ios/Pods/leveldb-library/util/testutil.cc b/ios/Pods/leveldb-library/util/testutil.cc new file mode 100644 index 00000000..bee56bf7 --- /dev/null +++ b/ios/Pods/leveldb-library/util/testutil.cc @@ -0,0 +1,51 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "util/testutil.h" + +#include "util/random.h" + +namespace leveldb { +namespace test { + +Slice RandomString(Random* rnd, int len, std::string* dst) { + dst->resize(len); + for (int i = 0; i < len; i++) { + (*dst)[i] = static_cast(' ' + rnd->Uniform(95)); // ' ' .. '~' + } + return Slice(*dst); +} + +std::string RandomKey(Random* rnd, int len) { + // Make sure to generate a wide variety of characters so we + // test the boundary conditions for short-key optimizations. + static const char kTestChars[] = { + '\0', '\1', 'a', 'b', 'c', 'd', 'e', '\xfd', '\xfe', '\xff' + }; + std::string result; + for (int i = 0; i < len; i++) { + result += kTestChars[rnd->Uniform(sizeof(kTestChars))]; + } + return result; +} + + +extern Slice CompressibleString(Random* rnd, double compressed_fraction, + size_t len, std::string* dst) { + int raw = static_cast(len * compressed_fraction); + if (raw < 1) raw = 1; + std::string raw_data; + RandomString(rnd, raw, &raw_data); + + // Duplicate the random data until we have filled "len" bytes + dst->clear(); + while (dst->size() < len) { + dst->append(raw_data); + } + dst->resize(len); + return Slice(*dst); +} + +} // namespace test +} // namespace leveldb diff --git a/ios/Pods/leveldb-library/util/testutil.h b/ios/Pods/leveldb-library/util/testutil.h new file mode 100644 index 00000000..d7e45837 --- /dev/null +++ b/ios/Pods/leveldb-library/util/testutil.h @@ -0,0 +1,63 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_UTIL_TESTUTIL_H_ +#define STORAGE_LEVELDB_UTIL_TESTUTIL_H_ + +#include "leveldb/env.h" +#include "leveldb/slice.h" +#include "util/random.h" + +namespace leveldb { +namespace test { + +// Store in *dst a random string of length "len" and return a Slice that +// references the generated data. +extern Slice RandomString(Random* rnd, int len, std::string* dst); + +// Return a random key with the specified length that may contain interesting +// characters (e.g. \x00, \xff, etc.). +extern std::string RandomKey(Random* rnd, int len); + +// Store in *dst a string of length "len" that will compress to +// "N*compressed_fraction" bytes and return a Slice that references +// the generated data. +extern Slice CompressibleString(Random* rnd, double compressed_fraction, + size_t len, std::string* dst); + +// A wrapper that allows injection of errors. +class ErrorEnv : public EnvWrapper { + public: + bool writable_file_error_; + int num_writable_file_errors_; + + ErrorEnv() : EnvWrapper(Env::Default()), + writable_file_error_(false), + num_writable_file_errors_(0) { } + + virtual Status NewWritableFile(const std::string& fname, + WritableFile** result) { + if (writable_file_error_) { + ++num_writable_file_errors_; + *result = NULL; + return Status::IOError(fname, "fake error"); + } + return target()->NewWritableFile(fname, result); + } + + virtual Status NewAppendableFile(const std::string& fname, + WritableFile** result) { + if (writable_file_error_) { + ++num_writable_file_errors_; + *result = NULL; + return Status::IOError(fname, "fake error"); + } + return target()->NewAppendableFile(fname, result); + } +}; + +} // namespace test +} // namespace leveldb + +#endif // STORAGE_LEVELDB_UTIL_TESTUTIL_H_ diff --git a/package.json b/package.json index 6d542d40..399a3a9c 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "react-addons-update": "^15.6.2", "react-art": "^16.8.4", "react-dom": "^16.8.4", - "react-native": "^0.59.1", + "react-native": "0.59.4", "react-native-app-intro-slider": "^1.0.1", "react-native-calendars": "https://github.com/MarieEveLegault/react-native-calendar-kalend.git", "react-native-camera": "^2.0.2", @@ -37,7 +37,6 @@ "react-native-datepicker": "^1.7.2", "react-native-extra-dimensions-android": "^1.2.5", "react-native-firebase": "^5.2.2", - "react-native-fs": "^2.13.3", "react-native-gesture-handler": "^1.1.0", "react-native-google-signin": "^1.2.1", "react-native-iphone-x-helper": "^1.2.0", @@ -57,10 +56,9 @@ "react-redux": "^6.0.0", "redux": "^4.0.1", "redux-persist": "^5.10.0", - "redux-thunk": "^2.3.0", "rn-fetch-blob": "^0.10.15", "rn-viewpager": "^1.2.9", - "sqlite3": "^4.0.6" + "uuid": "^3.3.2" }, "devDependencies": { "@babel/core": "^7.3.4", diff --git a/src/actions/allEvents.js b/src/actions/allEvents.js new file mode 100644 index 00000000..afecf0c5 --- /dev/null +++ b/src/actions/allEvents.js @@ -0,0 +1,21 @@ +import {ADD_EVENT, CLEAR_EVENTS} from '../constants/reducer_constants/allEvents'; + +export function clearAllEvents () { + const action = { + type: CLEAR_EVENTS + }; + + return action; +} + +export function addEvents (event) { + const action = { + type: ADD_EVENT, + event + }; + + return action; +} + + + diff --git a/src/actions/index.js b/src/actions/index.js index 91b0580e..4a094d38 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -3,6 +3,8 @@ import { SET_SELECTED_SCHEDULE, SET_UNAVAILABLE_HOURS, SET_SCHOOL_INFORMATION, + SET_SELECTED_CALENDAR, + UPDATE_NFE, SET_LANGUAGE, SET_BOTTOM_STRINGS, SET_IMG, @@ -26,7 +28,6 @@ import { DELETE_COURSE, DELETE_GENERATED_CALENDAR, UPDATE_FE, - UPDATE_NFE, UPDATE_COURSE, CLEAR_GENERATED_CALENDAR, CLEAR_CALENDAR, @@ -44,6 +45,7 @@ import { CLEAR_DASHBOARD_DATA, } from '../constants'; +export * from './allEvents'; /*** UPDATE ***/ export function updateFixedEvents (index, event) { @@ -250,6 +252,15 @@ export function setSchoolInformation (info) { return action; } +export function setSelectedCalendar(index) { + const action = { + type: SET_SELECTED_CALENDAR, + index + }; + + return action; +} + export function setLanguage (language) { const action = { type: SET_LANGUAGE, @@ -258,6 +269,7 @@ export function setLanguage (language) { return action; } + export function setDashboardData (data) { const action = { type: SET_DASHBOARD_DATA, @@ -433,4 +445,4 @@ export function clearTutorialStatus () { }; return action; -} \ No newline at end of file +} diff --git a/src/assets/strings.js b/src/assets/strings.js index 7082b44d..0da92476 100644 --- a/src/assets/strings.js +++ b/src/assets/strings.js @@ -5,7 +5,8 @@ const en = { CompareSchedule: { name: 'Compare', - addPermission: 'This person can now see your calendar', + addPermission: 'A notification has been sent to the other person', + permissionError: 'Cannot send notification to the other person', removePermission: 'Successfully removed the selected person/people', noCheckbox: 'Please select one or more users to compare schedules with', availabilities: 'Availabilities', @@ -22,6 +23,7 @@ const en = { email: 'Email', close: 'Close', add: 'Add', + invalidEmail: 'You cannot add yourself', allowPopover: 'Add users so that they can see your calendar!', availabilitiesPopover: 'Select users from the list above and tap here to see when you\'re all available!', deletePopover: 'Select the users for which you don\'t want to share your calendar with anymore and tap here to remove them!' @@ -67,7 +69,7 @@ const en = { addTitle: 'Add Fixed Event', editTitle: 'Edit Fixed Event', description: 'Add your events, office hours, appointments, etc.', - recurrence: ['None', 'Everyday', 'Weekly', 'Monthly'], + recurrence: ['None', 'Daily', 'Weekly', 'Monthly'], cancel: 'Cancel', snackbarSuccess: 'Event successfully added', snackbarFailure: 'Invalid field(s), please review to add event', @@ -364,6 +366,28 @@ const en = { importError: 'Imported some of the calendar events', importSuccess: ' successfully imported!' }, + SharingNotification: { + title: 'Sharing Request', + subtitle: 'Compare Schedule', + body: ' would like to share calendars with you', + allow: 'Allow', + deny: 'Deny', + allowBody: 'Calendar shared!', + denyBody: 'Request cancelled' + }, + SharingManagement: { + title: 'Sharing Requests', + allowSuccess: 'Successfully shared calendars', + allowError: 'Could not share calendars ', + denySuccess: 'Removed the selected request', + emptyTitle: 'You have no sharing requests', + emptyDescription: 'Tap to refresh the notifications', + }, + SharingManagementItem: { + allow: 'Allow', + deny: 'Deny', + + } }; @@ -391,6 +415,7 @@ const fr = { email: 'Courriel', close: 'Fermer', add: 'Ajouter', + invalidEmail: 'Vous ne pouvez pas vous ajoutez', allowPopover: 'Ajoutez des utilisateurs pour qu\'ils puissent voir votre calendrier!', availabilitiesPopover: 'Sélectionnez des utilisateurs parmi la liste ci-dessus et appuyer ici pour voir quand vous êtes tous disponibles!', deletePopover: 'Sélectionnez les utilisateurs pour lesquels vous ne voulez plus partager votre calendrier avec et appuyer ici pour les retirer!' @@ -736,6 +761,18 @@ const fr = { noEvents: 'Aucun événement trouvé dans votre sélection de calendrier(s)', importError: 'Importé certains des événements du calendrier', importSuccess: ' importer avec succès!' + }, + SharingNotification: { + title: 'Demande de partage', + subtitle: 'Comparaison d\'horaires', + body: ' aimerait partager de calendriers avec vous', + allow: 'Autoriser', + deny: 'Refuser', + allowBody: 'Calendrier partagé', + denyBody: 'Requête annulé' + }, + SharingManagement: { + title: 'Requête de partage de calendrier' } }; diff --git a/src/background/bgActions.js b/src/background/bgActions.js new file mode 100644 index 00000000..05ffae71 --- /dev/null +++ b/src/background/bgActions.js @@ -0,0 +1,85 @@ +import firebase from 'react-native-firebase'; +import { dark_blue } from '../styles'; +import { getStrings } from '../services/helper'; +import { requestCalendarPermissions } from '../services/firebase_messaging'; + + +export default async (notificationOpen) => { + let strings = getStrings().SharingNotification; + let notification = notificationOpen.notification; + let action = notificationOpen.action; + + if (action === 'allow') { + let newNotification = new firebase.notifications.Notification({ + sound: 'default', + show_in_foreground: true, + }) + .setNotificationId(notification.notificationId) + .setSubtitle(notification.subtitle) + .setTitle(notification.title) + .setBody(strings.allowBody) + .android.setAutoCancel(true) + .android.setClickAction('clicked') + .android.setChannelId(notification.android.channelId) + .android.setSmallIcon('ic_icon') + .android.setColor(dark_blue) + .android.setColorized(true) + .android.setTimeoutAfter(2000) + .android.setPriority(firebase.notifications.Android.Priority.High); + requestCalendarPermissions({ + requester: {email: notification.data.senderEmail}, + accepter : {email: notification.data.receiverEmail} + }) + .then(res => res.json()) + .then((success) => { + console.log('success', success); + if(success) { + firebase.database() + .ref(`notifications/${notification.data.path}/${notification.notificationId}/`) + .update({ + allow: true, + dismiss: false + }); + + firebase.notifications() + .displayNotification(newNotification); + } + }); + } else if (action === 'deny') { + let newNotification = new firebase.notifications.Notification({ + sound: 'default', + show_in_foreground: true, + }) + .setNotificationId(notification.notificationId) + .setSubtitle(notification.subtitle) + .setTitle(notification.title) + .setBody(strings.denyBody) + .android.setAutoCancel(true) + .android.setClickAction('clicked') + .android.setChannelId(notification.android.channelId) + .android.setSmallIcon('ic_icon') + .android.setColor(dark_blue) + .android.setColorized(true) + .android.setTimeoutAfter(2000) + .android.setPriority(firebase.notifications.Android.Priority.High); + + + firebase.database() + .ref(`notifications/${notification.data.path}/${notification.notificationId}/`) + .update({ + allow: false, + dismiss: false + }); + + firebase.notifications() + .displayNotification(newNotification); + } else if (action === 'prompt') { + firebase.database() + .ref(`notifications/${notification.data.path}/${notification.notificationId}/`) + .update({ + dismiss: true + }); + } + + return Promise.resolve(); +}; \ No newline at end of file diff --git a/src/background/bgMessaging.js b/src/background/bgMessaging.js new file mode 100644 index 00000000..c17cfe96 --- /dev/null +++ b/src/background/bgMessaging.js @@ -0,0 +1,47 @@ +import firebase from 'react-native-firebase'; +import { dark_blue } from '../styles'; +import { getStrings } from '../services/helper'; + +export default async (message) => { + + const strings = getStrings().SharingNotification; + // Creates buttons to the notification + const allow = new firebase.notifications.Android.Action('allow', 'ic_launcher', strings.allow); + const deny = new firebase.notifications.Android.Action('deny', 'ic_launcher', strings.deny); + allow.setShowUserInterface(false); + deny.setShowUserInterface(false); + + // Creates a channel for the android notification + const channel = new firebase.notifications.Android.Channel('sharing-schedule', 'Sharing Schedules', firebase.notifications.Android.Importance.Max) + .setDescription('Receive sharing request from other users'); + firebase.notifications().android.createChannel(channel); + + const localNotification = new firebase.notifications.Notification({ + sound: 'default', + show_in_foreground: true, + }) + .setNotificationId(message.data.notificationId) + .setTitle(strings.title) + .setBody(message.data.name + strings.body) + .setSubtitle(strings.subtitle) + .setData({ + requester: message.data.senderEmail, + accepter: message.data.receiverEmail, + path: message.from.split('/')[2] + }) + .android.addAction(allow) + .android.addAction(deny) + .android.setAutoCancel(true) + .android.setClickAction('prompt') + .android.setChannelId(message.data.type) + .android.setSmallIcon('ic_icon') + .android.setColor(dark_blue) + .android.setColorized(true) + .android.setPriority(firebase.notifications.Android.Priority.High); + + firebase.notifications() + .displayNotification(localNotification) + .catch(err => console.log('Notification err ', err)); + + return Promise.resolve(); +}; \ No newline at end of file diff --git a/src/components/CalendarScheduleItem.js b/src/components/CalendarScheduleItem.js index 27ae5683..5c88b92c 100644 --- a/src/components/CalendarScheduleItem.js +++ b/src/components/CalendarScheduleItem.js @@ -26,12 +26,15 @@ class CalendarScheduleItem extends React.PureComponent { theme={{colors:{accent:dark_blue}}} /> - - - + { + this.props.photo == undefined ? null : + + + + } - + {this.props.name} diff --git a/src/components/CameraRollImage.js b/src/components/CameraRollImage.js index f48ab05e..d9b4a3fe 100644 --- a/src/components/CameraRollImage.js +++ b/src/components/CameraRollImage.js @@ -1,7 +1,7 @@ import React from 'react'; import { Image, TouchableOpacity, View, Animated } from 'react-native'; import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; -import { cameraRollImageStyles as styles, blue, white } from '../styles'; +import { cameraRollImageStyles as styles, white, dark_blue } from '../styles'; const selectedIconSize = 35; @@ -71,12 +71,12 @@ class CameraRollImage extends React.PureComponent { + color={white} /> + color={dark_blue} /> diff --git a/src/components/EventOverview.js b/src/components/EventOverview.js index 7fb3b638..64c76678 100644 --- a/src/components/EventOverview.js +++ b/src/components/EventOverview.js @@ -118,7 +118,7 @@ class EventOverview extends React.PureComponent { {this.strings.recurrence} - {this.props.recurrence} + {this.props.recurrence[0].toUpperCase() + this.props.recurrence.slice(1).toLowerCase()} ; diff --git a/src/components/SharingManagementItem.js b/src/components/SharingManagementItem.js new file mode 100644 index 00000000..f46023c3 --- /dev/null +++ b/src/components/SharingManagementItem.js @@ -0,0 +1,46 @@ +import React from 'react'; +import { View, Text } from 'react-native'; +import { sharingManagementItemsStyles as styles, whiteRipple, blueRipple } from '../styles'; +import { TouchableRipple } from 'react-native-paper'; +import { getStrings } from '../services/helper'; + +class SharingManagementItem extends React.PureComponent { + strings = getStrings().SharingManagementItem; + + deny = () => { + this.props.denyItem(this.props.id); + } + + allow = () => { + this.props.allowItem(this.props.id); + } + + render() { + const { title, subtitle, id, total} = this.props; + + return ( + + + {title} + {subtitle} + + + + {this.strings.deny} + + + {this.strings.allow} + + + + ); + } +} + +export default SharingManagementItem; \ No newline at end of file diff --git a/src/components/screens/CompareSchedule.js b/src/components/screens/CompareSchedule.js index 7c58587d..c48da394 100644 --- a/src/components/screens/CompareSchedule.js +++ b/src/components/screens/CompareSchedule.js @@ -1,6 +1,6 @@ import React from 'react'; import { StatusBar, View, Platform, FlatList, Text, TouchableOpacity, ActivityIndicator, RefreshControl, Animated, NativeModules, LayoutAnimation } from 'react-native'; -import { TextInput, Snackbar, TouchableRipple } from 'react-native-paper'; +import { TextInput, Snackbar, TouchableRipple, IconButton, Badge } from 'react-native-paper'; import { connect } from 'react-redux'; import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'; import { Agenda, LocaleConfig } from 'react-native-calendars'; @@ -13,8 +13,11 @@ import { setTutorialStatus } from '../../actions'; import { store } from '../../store'; import { compareScheduleStyles as styles, dark_blue, gray, whiteRipple, blueRipple, statusBarDark, statusBarLightPopover } from '../../styles'; import updateNavigation from '../NavigationHelper'; -import { getAvailabilitiesCalendars, listSharedKalendCalendars, addPermissionPerson, deleteOtherSharedCalendar } from '../../services/service'; +import { getAvailabilitiesCalendars, listSharedKalendCalendars, deleteOtherSharedCalendar } from '../../services/service'; import CalendarScheduleItem from '../CalendarScheduleItem'; +import { getUserInfoByColumnService } from '../../services/api/storage_services'; +import firebase from 'react-native-firebase'; +import { SharingManagementRoute } from '../../constants/screenNames'; LocaleConfig.locales.en = LocaleConfig.locales['']; LocaleConfig.locales['fr'] = { @@ -58,6 +61,7 @@ class CompareSchedule extends React.PureComponent { endDate: moment().startOf('day').add(90, 'd'), showCalendar: false, animatedHeight: this.listHeight, + hasNotification: false, allowPopover: false, availabilitiesPopover: false, deletePopover: false @@ -76,6 +80,27 @@ class CompareSchedule extends React.PureComponent { this.willFocusSubscription = this.props.navigation.addListener( 'willFocus', () => { + firebase.database() + .ref(`notifications/${this.props.id}/`) + .once('value', + async (data) => { + data = await data.val(); + + let notDimissed = []; + if (data) { + Object.keys(data).map(i => { + if (!('dismiss' in data[i]) || data[i].dismiss) { + notDimissed.push(data[i]); + } + }); + } + + this.setState({ + hasNotification: notDimissed.length !== 0, + }); + }) + .catch(err => console.log(err)); + this.setState({allowPopover: !this.props.showTutorial}); if (!this.props.showTutorial) { this.darkenStatusBar(); @@ -123,27 +148,57 @@ class CompareSchedule extends React.PureComponent { + name={(item.name ? item.name : item.id)} + photo={item.photo} /> ); }; /** * Callback fuction when the button add is touched in the modal */ - addPerson = () => { - addPermissionPerson(this.state.searchText) - .then(() => { - this.setState({ - snackbarText: this.strings.addPermission, - snackbarVisible: true - }); - }) - .catch((err) => { - this.setState({ - snackbarText: err, - snackbarVisible: true - }); + addPerson = async () => { + if (this.state.searchText === this.props.email) { + this.setState({ + snackbarText: this.strings.permissionError, + snackbarVisible: true }); + } else { + getUserInfoByColumnService({ + columns: ['ID'], + where: { + value: this.state.searchText, + field: 'EMAIL' + } + }).then(res => res.json()) + .then(data => { + if (!data) { + alert('No user found'); + return; + } else { + firebase.database().ref(`notifications/${data.ID}/`) + .push({ + name: this.props.name, + senderEmail: this.props.email, + receiverEmail: this.state.searchText, + createdAt: new Date().toJSON(), + allow: false, + dismiss: true + }) + .then(() => { + this.setState({ + snackbarText: this.strings.addPermission, + snackbarVisible: true + }); + }) + .catch(() => { + this.setState({ + snackbarText: this.strings.permissionError, + snackbarVisible: true + }); + }); + } + }); + } } /** @@ -381,7 +436,7 @@ class CompareSchedule extends React.PureComponent { } render() { - const { agendaKey, userAvailabilities, searchModalVisible, snackbarVisible, snackbarText, snackbarTime, loadingSharedList, agendaData, showCalendar, animatedHeight } = this.state; + const { agendaKey, userAvailabilities, searchModalVisible, snackbarVisible, snackbarText, snackbarTime, loadingSharedList, agendaData, showCalendar, animatedHeight, hasNotification } = this.state; return( @@ -393,7 +448,20 @@ class CompareSchedule extends React.PureComponent { showCalendar ? null : - {this.strings.compareWith} + + {this.strings.compareWith} + + + this.props.navigation.navigate(SharingManagementRoute, {title: getStrings().SharingManagement.title})} /> + this.props.navigation.navigate(SharingManagementRoute, {title: getStrings().SharingManagement.title})}> + + + + { loadingSharedList ? @@ -567,9 +635,13 @@ class CompareSchedule extends React.PureComponent { let mapStateToProps = (state) => { const { id } = state.CalendarReducer; + const { name, email } = state.HomeReducer.profile ? state.HomeReducer.profile.profile.user : {name: '', email: ''}; return { calendarID: id, + name, + email, + id: state.HomeReducer.profile ? state.HomeReducer.profile.profile.user.id : '', showTutorial: state.SettingsReducer.tutorialStatus.compareSchedule }; }; diff --git a/src/components/screens/Dashboard.js b/src/components/screens/Dashboard.js index 16ba4b2a..b178392c 100644 --- a/src/components/screens/Dashboard.js +++ b/src/components/screens/Dashboard.js @@ -13,6 +13,8 @@ import { calendarColors, calendarInsideColors } from '../../../config/config'; import { ReviewEventRoute } from '../../constants/screenNames'; import { getStrings } from '../../services/helper'; import { getDataforDashboard, sortEventsInDictonary } from '../../services/service'; +import { updateUser } from '../../services/api/storage_services'; +import firebase from 'react-native-firebase'; // import ModalEvent from '../ModalEvent'; // import DeleteModal from '../DeleteModal'; @@ -129,6 +131,20 @@ class Dashboard extends React.PureComponent { } componentDidMount() { + firebase.messaging().getToken().then(fcmToken => { + if (fcmToken) { + console.log('token firebase', fcmToken); + updateUser({values:[fcmToken], columns:['FIREBASEID']}); + } + }); + + this.onTokenRefreshListener = firebase.messaging().onTokenRefresh(fcmToken => { + // Process your token as required + console.log('token firebase', fcmToken); + updateUser({values:[fcmToken], columns:['FIREBASEID']}); + }); + + // this.setState({isVisible: true}); this.willFocusSubscription = this.props.navigation.addListener( 'willFocus', () => { @@ -163,16 +179,16 @@ class Dashboard extends React.PureComponent { componentWillUnmount() { this.willFocusSubscription.remove(); + this.onTokenRefreshListener(); } setDashboardDataService = () => { getDataforDashboard() .then(items => { - setTimeout(() => { - let dict = sortEventsInDictonary(items); - this.props.dispatch(setDashboardData(dict)); - this.setState({items: dict}); - },2000); + let dict = sortEventsInDictonary(items); + this.props.dispatch(setDashboardData(dict)); + this.setState({items: dict}); + console.log(dict); }) .catch(err => { console.log('err', err); diff --git a/src/components/screens/Home.js b/src/components/screens/Home.js index a406d89e..41ed7bf9 100644 --- a/src/components/screens/Home.js +++ b/src/components/screens/Home.js @@ -12,8 +12,10 @@ import updateNavigation from '../NavigationHelper'; import { bindActionCreators } from 'redux'; import { googleSignIn, googleIsSignedIn, googleGetCurrentUserInfo } from '../../services/google_identity'; import { createCalendar, getCalendarID2 } from '../../services/service'; +import { storeUserInfoService, updateUser, getUserValuesService } from '../../services/api/storage_services'; import { homeStyles as styles, dark_blue, white } from '../../styles'; import { getStrings } from '../../services/helper'; +import firebase from 'react-native-firebase'; /** * Home/Login screen of the app. @@ -35,27 +37,50 @@ class Home extends React.PureComponent { * Sets the user information */ setUser = (userInfo) => { - this.props.logonUser(userInfo); + storeUserInfoService(userInfo) + .then(res => res.json()) + .then((success) => { + if (success) { + this.props.logonUser(userInfo); + this.setCalendar().then(id => { + updateUser({values:[id], columns:['CALENDARID']}); + this.nextScreen(); + }); + } else { + alert('There was an error setting Users data'); + } + }) + .catch((err) => { + console.log('err', err); + }); } /** * Creates the Kalend calendar in the user's Google Account */ setCalendar() { - getCalendarID2().then(data => { - if (data.calendarID === undefined) { - createCalendar().then(data => { - this.props.setCalendarID(data.calendarID); - this.props.setCalendarColor(data.calendarColor); - this.props.navigation.navigate(DashboardNavigator); + return new Promise( async (resolve, reject) => { + await getCalendarID2() + .then( data => { + if (data.calendarID === undefined) { + createCalendar() + .then(data => { + this.props.setCalendarID(data.calendarID); + this.props.setCalendarColor(data.calendarColor); + resolve(data.calendarID); + }); + } else { + this.props.setCalendarID(data.calendarID); + this.props.setCalendarColor(data.calendarColor); + resolve(data.calendarID); + } + }).catch(err => { + reject(err); + alert(err); }); - } else { - this.props.setCalendarID(data.calendarID); - this.props.setCalendarColor(data.calendarColor); - this.props.navigation.navigate(DashboardNavigator); - } }); - } + } + /** * Log In the user with their Google Account @@ -77,23 +102,34 @@ class Home extends React.PureComponent { googleGetCurrentUserInfo().then((userInfo) => { if (userInfo !== undefined) { this.setUser(userInfo); - this.setCalendar(); } googleSignIn().then((userInfo) => { - if (userInfo !== null) { + if (userInfo) { this.setUser(userInfo); - this.setCalendar(); } this.state.clicked = false; }); }); } else { - this.setCalendar(); + this.setCalendar().then(id => { + updateUser({values:[id], columns:['CALENDARID']}); + }); + this.nextScreen(); } }); } } + nextScreen = async () => { + firebase.messaging().hasPermission() + .then(async () => { + await firebase.messaging().requestPermission(); + let data = await getUserValuesService({columns:['ID']}).then(res => res.json()); + firebase.messaging().subscribeToTopic((data.ID).toString()); + this.props.navigation.navigate(DashboardNavigator); + }); + } + showWebsite = (url) => { if (Platform.OS === 'ios') { this.openSafari(url); @@ -149,7 +185,6 @@ class Home extends React.PureComponent { color={GoogleSigninButton.Color.Light} onPress={this.signIn} /> - { this.props.language === 'en' ? this.showWebsite('https://cdhstudio.ca/') : this.showWebsite('https://cdhstudio.ca/fr'); diff --git a/src/components/screens/LoadingScreen.js b/src/components/screens/LoadingScreen.js index 7ae81fe5..99dcd099 100644 --- a/src/components/screens/LoadingScreen.js +++ b/src/components/screens/LoadingScreen.js @@ -1,13 +1,15 @@ import React from 'react'; -import { StatusBar, View, Animated, Easing, Platform } from 'react-native'; +import { StatusBar, View, Animated, Easing, Platform, Alert } from 'react-native'; import { connect } from 'react-redux'; import LottieView from 'lottie-react-native'; import AnimatedGradient from '../AnimatedGradient'; -import { WelcomeScreen, LoginNavigator, DashboardOptionsNavigator } from '../../constants/screenNames'; +import { WelcomeScreen, DashboardOptionsNavigator } from '../../constants/screenNames'; import { gradientColors } from '../../../config/config'; import { loadingStyles as styles, blue, statusBarDark } from '../../styles'; import { setBottomString, setLanguage } from '../../actions'; import { getStrings } from '../../services/helper'; +import firebase from 'react-native-firebase'; +import { requestCalendarPermissions } from '../../services/firebase_messaging'; const logoFile = require('../../assets/logoAnim.json'); const gradientAnimDuration = 2250; @@ -18,6 +20,8 @@ const logoAnimDuration = 3000; */ class LoadingScreen extends React.PureComponent { + notificationStrings = getStrings().SharingNotification; + constructor(props) { super(props); this.state = { @@ -55,6 +59,65 @@ class LoadingScreen extends React.PureComponent { this.setState({ colors: gradientColors }); + + this.createNotificationListeners(); + } + + createNotificationListeners = async () => { + /* + * Triggered for data only payload in foreground + * */ + this.messageListener = firebase.messaging().onMessage((message) => { + Alert.alert(this.notificationStrings.title, message.data.name + this.notificationStrings.body, [ + {text: 'Allow', onPress: () => { + requestCalendarPermissions({ + requester: {email: message.data.senderEmail}, + accepter : {email: message.data.receiverEmail} + }) + .then(res => res.json()) + .then(success => { + if(success) { + firebase.database() + .ref(`notifications/${message.from.split('/')[2]}/${message.data.notificationId}/`) + .update({ + allow: true, + dismiss: false + }); + Alert.alert('', this.notificationStrings.allowBody, [{text: 'Ok'}], {cancelable: true}); + } + }); + } + }, + {text: 'Deny', onPress: () => { + firebase.database() + .ref(`notifications/${message.from.split('/')[2]}/${message.data.notificationId}/`) + .update({ + allow: false, + dismiss: false + }); + Alert.alert('', this.notificationStrings.denyBody, [{text: 'Ok'}], {cancelable: true}); + }, style: 'cancel'} + ], {cancelable: true}); + }); + + this.notificationOpenedListener = firebase.notifications().onNotificationOpened((notificationOpen) => { + const action = notificationOpen.action; + const notification = notificationOpen.notification; + + if (action === 'allow' || action === 'deny') { + firebase.notifications().removeDeliveredNotification(notification.notificationId); + } + }); + } + + showAlert(title, body) { + Alert.alert( + title, body, + [ + { text: 'OK', onPress: () => console.log('OK Pressed') }, + ], + { cancelable: false }, + ); } componentWillMount() { @@ -63,7 +126,7 @@ class LoadingScreen extends React.PureComponent { switch (this.props.main) { case 'Home': this.setState({ - nextScreen: LoginNavigator + nextScreen: WelcomeScreen }); break; case 'SchoolSchedule': diff --git a/src/components/screens/ReviewEvent.js b/src/components/screens/ReviewEvent.js index 4a88a1ad..39c7c9a6 100644 --- a/src/components/screens/ReviewEvent.js +++ b/src/components/screens/ReviewEvent.js @@ -4,9 +4,11 @@ import { FAB } from 'react-native-paper'; import Popover from 'react-native-popover-view'; import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'; import { connect } from 'react-redux'; +import EventOverview from '../EventOverview'; +import { bindActionCreators } from 'redux'; +import { storeInsertedCalendars } from '../../services/api/storage_services'; import { deleteCourse, deleteFixedEvent, deleteNonFixedEvent, clearGeneratedCalendars, clearGeneratedNonFixedEvents, clearCourse, clearFixedEvents, setNavigationScreen, setTutorialStatus } from '../../actions'; import { SchoolScheduleRoute, FixedEventRoute, NonFixedEventRoute, ScheduleCreationRoute, SchoolInformationRoute, CourseRoute, UnavailableRoute } from '../../constants/screenNames'; -import EventOverview from '../EventOverview'; import updateNavigation from '../NavigationHelper'; import { store } from '../../store'; import { reviewEventStyles as styles, white, blue, statusBlueColor, statusBarPopover, statusBarDark, black, dark_blue, statusBarLightPopover } from '../../styles'; @@ -172,17 +174,17 @@ class ReviewEvent extends React.PureComponent { switch (category) { case SchoolScheduleRoute: - dataToDispatch = deleteCourse(id); + dataToDispatch = this.props.deleteCourse; newEvents = this.state.schoolScheduleData; objectToChange = 'schoolScheduleData'; break; case FixedEventRoute: - dataToDispatch = deleteFixedEvent(id); + dataToDispatch = this.props.deleteFixedEvent; newEvents = this.state.fixedEventData; objectToChange = 'fixedEventData'; break; case NonFixedEventRoute: - dataToDispatch = deleteNonFixedEvent(id); + dataToDispatch = this.props.deleteNonFixedEvent; newEvents = this.state.nonFixedEventData; objectToChange = 'nonFixedEventData'; break; @@ -195,7 +197,7 @@ class ReviewEvent extends React.PureComponent { if (index != id) return event; }); - this.props.dispatch(dataToDispatch); + dataToDispatch(id); this.setState({[objectToChange]: newEvents}); } @@ -224,8 +226,8 @@ class ReviewEvent extends React.PureComponent { * Goes to the appropriate Schedule Creation Screen */ navigateCreationScreen = () => { - this.props.dispatch(clearGeneratedCalendars()); - this.props.dispatch(clearGeneratedNonFixedEvents()); + this.props.clearGeneratedCalendars(); + this.props.clearGeneratedNonFixedEvents(); if (this.state.schoolScheduleData.length == 0 && this.state.nonFixedEventData.length == 0 && this.state.fixedEventData.length == 0 ) { Alert.alert( @@ -238,30 +240,37 @@ class ReviewEvent extends React.PureComponent { ); return; } - - if (this.state.nonFixedEventData.length == 0) { - insertFixedEventsToGoogle() - .then(() => { - this.props.dispatch(clearCourse()); - this.props.dispatch(clearFixedEvents()); - this.props.dispatch(setNavigationScreen({successfullyInsertedEvents: true})); - this.props.navigation.pop(); - }) - .catch(err => { - if (err) { - Alert.alert( - this.strings.error, - err, - [ - {text: this.strings.ok}, - ], - {cancelable: false} - ); - } - }); - } else { - this.props.navigation.navigate(ScheduleCreationRoute, {title: getStrings().ScheduleCreation.title}); - } + + insertFixedEventsToGoogle() + .then((promises) => { + + if (this.state.nonFixedEventData.length == 0) { + storeInsertedCalendars(promises).then(success => { + + if(success) { + this.props.clearCourse(); + this.props.clearFixedEvents(); + this.props.setNavigationScreen({successfullyInsertedEvents: true}); + this.props.navigation.pop(); + } + }); + } else { + this.props.navigation.navigate(ScheduleCreationRoute, {title: getStrings().ScheduleCreation.title}); + } + }) + .catch(err => { + console.log('err', err); + if (err) { + Alert.alert( + this.strings.error, + err, + [ + {text: this.strings.ok}, + ], + {cancelable: false} + ); + } + }); } showPopover = (isVisible) => { @@ -453,12 +462,12 @@ class ReviewEvent extends React.PureComponent { fromView={this.refs.check} onClose={() => { this.setState({checkPopover:false}); - this.props.dispatch(setTutorialStatus('reviewEvents', true)); + this.props.setTutorialStatus('reviewEvents', true); this.restoreStatusBar(); }}> { this.setState({checkPopover:false}); - this.props.dispatch(setTutorialStatus('reviewEvents', true)); + this.props.setTutorialStatus('reviewEvents', true); this.restoreStatusBar(); }}> {this.strings.checkPopover} @@ -490,4 +499,9 @@ function mapStateToProps(state) { }; } -export default connect(mapStateToProps, null)(ReviewEvent); \ No newline at end of file + +let mapDispatchToProps = (dispatch) => { + return bindActionCreators({ clearGeneratedNonFixedEvents, clearGeneratedCalendars, clearCourse, clearFixedEvents, setNavigationScreen, setTutorialStatus, deleteCourse, deleteFixedEvent, deleteNonFixedEvent}, dispatch); +}; + +export default connect(mapStateToProps, mapDispatchToProps)(ReviewEvent); \ No newline at end of file diff --git a/src/components/screens/ScheduleCreation.js b/src/components/screens/ScheduleCreation.js index 1284bcff..3739330a 100644 --- a/src/components/screens/ScheduleCreation.js +++ b/src/components/screens/ScheduleCreation.js @@ -3,8 +3,10 @@ import { StatusBar, BackHandler, Alert, Text, View, Platform } from 'react-nativ import * as Progress from 'react-native-progress'; import { Surface } from 'react-native-paper'; import { HeaderBackButton } from 'react-navigation'; -import { generateCalendars, setUserInfo, insertFixedEventsToGoogle } from '../../services/service'; +import { generateCalendars, setUserInfo, deleteCreatedGoogleEvents } from '../../services/service'; import { connect } from 'react-redux'; +import { addEvents } from '../../actions'; +import { bindActionCreators } from 'redux'; import { DashboardNavigator, ScheduleSelectionRoute, ReviewEventRoute } from '../../constants/screenNames'; import { scheduleCreateStyles as styles, dark_blue, white } from '../../styles'; import updateNavigation from '../NavigationHelper'; @@ -39,29 +41,10 @@ class ScheduleCreation extends React.PureComponent { componentWillMount() { // Adds a little delay before going to the next screen setUserInfo(); - insertFixedEventsToGoogle() - .then(() => { - if (this.props.NonFixedEventsReducer.length != 0) { - setTimeout(() =>{ - this.generateScheduleService(); - }, 3000); - } else { - this.setState({goToNextScreen: true}); - this.navigateToSelection(); - } - }) - .catch(err => { - if (err) { - Alert.alert( - this.strings.error, - err, - [ - {text: this.strings.ok, onPress: () => this.props.navigation.pop()}, - ], - {cancelable: false} - ); - } - }); + setTimeout(() =>{ + this.generateScheduleService(); + }, 3000); + BackHandler.addEventListener('hardwareBackPress', this.handleBackButton); this.props.navigation.setParams({onBackPress: this.handleBackButton}); } @@ -87,13 +70,16 @@ class ScheduleCreation extends React.PureComponent { { text: getStrings().Dashboard.name, onPress: () => { - this.props.navigation.navigate(DashboardNavigator); + deleteCreatedGoogleEvents() + .then(() => this.props.navigation.navigate(DashboardNavigator)); + } }, { text: getStrings().ReviewEvent.name, onPress: () => { - this.props.navigation.navigate(ReviewEventRoute, {title: getStrings().ReviewEvent.title}); + deleteCreatedGoogleEvents() + .then(() => this.props.navigation.navigate(ReviewEventRoute, {title: getStrings().ReviewEvent.title})); }, }, ], @@ -154,4 +140,8 @@ let mapStateToProps = (state) => { }; }; -export default connect(mapStateToProps, null)(ScheduleCreation); \ No newline at end of file +let mapDispatchToProps = (dispatch) => { + return bindActionCreators({ addEvents }, dispatch); +}; + +export default connect(mapStateToProps, mapDispatchToProps)(ScheduleCreation); \ No newline at end of file diff --git a/src/components/screens/ScheduleSelection.js b/src/components/screens/ScheduleSelection.js index 90841f62..b6b13441 100644 --- a/src/components/screens/ScheduleSelection.js +++ b/src/components/screens/ScheduleSelection.js @@ -2,12 +2,12 @@ import React from 'react'; import { Platform, StatusBar, View, BackHandler, Alert, Text, ScrollView, Dimensions, TouchableOpacity, FlatList } from 'react-native'; import { connect } from 'react-redux'; import { HeaderBackButton } from 'react-navigation'; -import { setSelectedSchedule, deleteGeneratedCalendar, clearGeneratedCalendars, clearGeneratedNonFixedEvents } from '../../actions'; +import { setSelectedSchedule, deleteGeneratedCalendar, clearGeneratedCalendars, clearGeneratedNonFixedEvents, clearAllEvents} from '../../actions'; import { calendarColors, calendarInsideColors } from '../../../config/config'; import { DashboardNavigator, ScheduleSelectionDetailsRoute, ReviewEventRoute } from '../../constants/screenNames'; import updateNavigation from '../NavigationHelper'; import converter from 'number-to-words'; -import { eventsToScheduleSelectionData } from '../../services/service'; +import { eventsToScheduleSelectionData, deleteCreatedGoogleEvents } from '../../services/service'; import { scheduleSelectionStyle as styles, black, white } from '../../styles'; import { getStrings } from '../../services/helper'; @@ -431,17 +431,25 @@ class ScheduleSelection extends React.PureComponent { { text: getStrings().Dashboard.name, onPress: () => { - this.props.navigation.navigate(DashboardNavigator); - this.props.dispatch(clearGeneratedCalendars()); - this.props.dispatch(clearGeneratedNonFixedEvents()); + deleteCreatedGoogleEvents() + .then(() => { + this.props.navigation.navigate(DashboardNavigator); + this.props.dispatch(clearGeneratedCalendars()); + this.props.dispatch(clearGeneratedNonFixedEvents()); + this.props.dispatch(clearAllEvents()); + }); } }, { text: getStrings().ReviewEvent.name, onPress: () => { - this.props.navigation.navigate(ReviewEventRoute, {title: getStrings().ReviewEvent.title}); - this.props.dispatch(clearGeneratedCalendars()); - this.props.dispatch(clearGeneratedNonFixedEvents()); + deleteCreatedGoogleEvents() + .then(() => { + this.props.navigation.navigate(ReviewEventRoute, {title: getStrings().ReviewEvent.title}); + this.props.dispatch(clearGeneratedCalendars()); + this.props.dispatch(clearGeneratedNonFixedEvents()); + this.props.dispatch(clearAllEvents()); + }); }, }, ], diff --git a/src/components/screens/ScheduleSelectionDetails.js b/src/components/screens/ScheduleSelectionDetails.js index a794614c..64c5b808 100644 --- a/src/components/screens/ScheduleSelectionDetails.js +++ b/src/components/screens/ScheduleSelectionDetails.js @@ -5,9 +5,10 @@ import { connect } from 'react-redux'; import { calendarColors } from '../../../config/config'; import { DashboardNavigator } from '../../constants/screenNames'; import { insertGeneratedEvent } from '../../services/service'; +import { storeInsertedCalendars } from '../../services/api/storage_services'; import { getStrings } from '../../services/helper'; import updateNavigation from '../NavigationHelper'; -import { clearGeneratedCalendars, clearGeneratedNonFixedEvents, clearNonFixedEvents, clearFixedEvents, clearCourse} from '../../actions'; +import { clearGeneratedCalendars, clearGeneratedNonFixedEvents, clearNonFixedEvents, clearFixedEvents, clearCourse, addEvents, clearAllEvents, setSelectedCalendar } from '../../actions'; import { scheduleSelectionDetailsStyle as styles, white, dark_blue, blue } from '../../styles'; const moment = require('moment'); @@ -260,14 +261,46 @@ class ScheduleSelectionDetails extends React.PureComponent { /** * Goes to the next screen */ - nextScreen = () => { + nextScreen = async () => { if (this.state.data.aiEvents) { - this.state.data.aiEvents.forEach(event => { - insertGeneratedEvent(event); + this.props.dispatch(setSelectedCalendar(this.props.index)); + await this.insertGeneratedEvents(this.state.data.aiEvents).then(() => { + //storeGeneratedCalendars(this.props.GeneratedCalendarsReducer); + storeInsertedCalendars(this.props.AllEventsReducer) + .then(success => { + if (success) { + this.clearEvents(); + this.props.navigation.navigate(DashboardNavigator); + } else { + alert('There was a problem storing Generated Events'); + } + }) + .catch(err => { + alert(err); + }); }); } - this.clearEvents(); - this.props.navigation.navigate(DashboardNavigator); + } + + insertGeneratedEvents = (events) => { + let promises = []; + events.forEach(event => { + promises.push(new Promise((resolve, reject) => { + insertGeneratedEvent(event) + .then(data => { + if (data.error) { + reject(data.error); + return; + } + + data.category = 1; + resolve(data); + this.props.dispatch(addEvents(data)); + }); + })); + }); + + return Promise.all(promises); } clearEvents = () => { @@ -276,6 +309,7 @@ class ScheduleSelectionDetails extends React.PureComponent { this.props.dispatch(clearNonFixedEvents()); this.props.dispatch(clearFixedEvents()); this.props.dispatch(clearCourse()); + this.props.dispatch(clearAllEvents()); } render() { @@ -316,7 +350,7 @@ class ScheduleSelectionDetails extends React.PureComponent { let mapStateToProps = (state) => { const { index } = state.ScheduleSelectionReducer; - const { GeneratedNonFixedEventsReducer } = state; + const { GeneratedNonFixedEventsReducer, GeneratedCalendarsReducer, AllEventsReducer } = state; let { fixedEventsColor, nonFixedEventsColor, courseColor } = state.CalendarReducer; for (let i = 0; i < calendarColors.length; i++) { @@ -353,6 +387,8 @@ let mapStateToProps = (state) => { return { index, GeneratedNonFixedEventsReducer, + GeneratedCalendarsReducer, + AllEventsReducer, fixedEventsColor, nonFixedEventsColor, courseColor diff --git a/src/components/screens/SchoolInformation.js b/src/components/screens/SchoolInformation.js index 9be307d8..f3711cc6 100644 --- a/src/components/screens/SchoolInformation.js +++ b/src/components/screens/SchoolInformation.js @@ -12,6 +12,7 @@ import { SchoolScheduleRoute, CourseRoute } from '../../constants/screenNames'; import updateNavigation from '../NavigationHelper'; import { dateVerification, getStrings } from '../../services/helper'; import { ScrollView } from 'react-native-gesture-handler'; +import { storeSchoolInfoService } from '../../services/api/storage_services'; const moment = require('moment'); const viewHeight = 495.75; @@ -46,6 +47,7 @@ class SchoolInformation extends React.PureComponent { schoolValidated: true, checked: 'none', + value:'', otherSchool: '' }; @@ -79,22 +81,41 @@ class SchoolInformation extends React.PureComponent { */ saveInformation = () => { if (this.fieldValidation()) { - this.props.dispatch(setSchoolInformation(this.state)); - let temp = this.props.navigation.state.params; + let {startDate, endDate, value, checked} = this.state; + value = (checked == 'third') ? 0: value; - if (temp) { - if (temp.schoolSchedule || temp.reviewEvent) { - if (this.state.checked === 'third') { - this.props.navigation.navigate(CourseRoute, {addTitle: getStrings().Course.addTitle, editTitle: getStrings().Course.editTitle}); + storeSchoolInfoService({startDate, endDate, value}) + .then(res => res.json()) + .then(success => { + console.log('success', success); + if (success) { + this.props.dispatch(setSchoolInformation(this.state)); + this.navigateAfterSettingUp(); } else { - this.props.navigation.navigate(SchoolScheduleRoute, {title: getStrings().SchoolSchedule.title}); + alert('failed'); } + }) + .catch(err => { + console.log('errrr', err); + }); + } + } + + navigateAfterSettingUp = () => { + let temp = this.props.navigation.state.params; + + if (temp) { + if (temp.schoolSchedule || temp.reviewEvent) { + if (this.state.checked === 'third') { + this.props.navigation.navigate(CourseRoute, {addTitle: getStrings().Course.addTitle, editTitle: getStrings().Course.editTitle}); } else { - this.props.navigation.pop(); + this.props.navigation.navigate(SchoolScheduleRoute, {title: getStrings().SchoolSchedule.title}); } } else { this.props.navigation.pop(); } + } else { + this.props.navigation.pop(); } } @@ -133,6 +154,7 @@ class SchoolInformation extends React.PureComponent { onPress={() => { this.setState({ checked: 'first', + value: 1, schoolValidated: true }); this.refs._other.blur(); @@ -141,6 +163,7 @@ class SchoolInformation extends React.PureComponent { { this.setState({ checked: 'first', + value: 1, schoolValidated: true }); this.refs._other.blur(); @@ -159,6 +182,7 @@ class SchoolInformation extends React.PureComponent { onPress={() => { this.setState({ checked: 'second', + value: 2, schoolValidated: true }); this.refs._other.blur(); @@ -167,6 +191,7 @@ class SchoolInformation extends React.PureComponent { { this.setState({ checked: 'second', + value: 2, schoolValidated: true }); this.refs._other.blur(); diff --git a/src/components/screens/SchoolScheduleSelectPicture.js b/src/components/screens/SchoolScheduleSelectPicture.js index 1bf76e5a..b90871f4 100644 --- a/src/components/screens/SchoolScheduleSelectPicture.js +++ b/src/components/screens/SchoolScheduleSelectPicture.js @@ -7,7 +7,7 @@ import updateNavigation from '../NavigationHelper'; import { setImageURI } from '../../actions'; import CameraRollImage from '../CameraRollImage'; import { SchoolScheduleCreationRoute } from '../../constants/screenNames'; -import { selectPictureStyles as styles, white, blue } from '../../styles'; +import { selectPictureStyles as styles, white, dark_blue } from '../../styles'; import { getStrings } from '../../services/helper'; import CameraRoll from '@react-native-community/cameraroll'; @@ -236,7 +236,8 @@ class SchoolScheduleSelectPicture extends React.PureComponent { diff --git a/src/components/screens/Settings.js b/src/components/screens/Settings.js index 8a8eb92a..ed1c90af 100644 --- a/src/components/screens/Settings.js +++ b/src/components/screens/Settings.js @@ -17,6 +17,8 @@ import { setCalendarID, clearTutorialStatus } from '../../actions'; import EventsColorPicker from '../EventsColorPicker'; import ImportCalendar from '../ImportCalendar'; import LanguageSwitcher from '../LanguageSwitcher'; +import { logOutUser } from '../../services/api/storage_services'; +import firebase from 'react-native-firebase'; const viewHeight = 669.1428833007812; @@ -53,10 +55,42 @@ class Settings extends React.PureComponent { this.restoreStatusBar(); } - logout = () => { - googleSignOut(); - clearEveryReducer(); - this.props.navigation.navigate(LoginNavigator); + showWebsite = (url) => { + if (Platform.OS === 'ios') { + this.openSafari(url); + } else { + this.openChrome(url); + } + } + + openSafari = (url) => { + SafariView.isAvailable() + .then(SafariView.show({url, + tintColor: dark_blue, + barTintColor: '#fff', + fromBottom: true })) + .catch(() => this.openChrome(url)); + } + + openChrome = (url) => { + CustomTabs.openURL(url, { + toolbarColor: dark_blue, + enableUrlBarHiding: true, + showPageTitle: true, + enableDefaultShare: true, + forceCloseOnRedirection: true, + }); + } + + logout = async () => { + await googleSignOut(); + await logOutUser() + .then(res => res.json()) + .then(id => { + firebase.messaging().unsubscribeFromTopic((id).toString()); + clearEveryReducer(); + this.props.navigation.navigate(LoginNavigator); + }); } dismissImportCalendar = () => { @@ -146,7 +180,7 @@ class Settings extends React.PureComponent { - + {/* */} diff --git a/src/components/screens/SharingManagement.js b/src/components/screens/SharingManagement.js new file mode 100644 index 00000000..33a91304 --- /dev/null +++ b/src/components/screens/SharingManagement.js @@ -0,0 +1,206 @@ +import React from 'react'; +import { View, Platform, StatusBar, Text, FlatList, ActivityIndicator, RefreshControl, TouchableOpacity } from 'react-native'; +import firebase from 'react-native-firebase'; +import { connect } from 'react-redux'; +import MaterialIcons from 'react-native-vector-icons/MaterialIcons'; +import { sharingManagementStyles as styles, white, gray, dark_blue } from '../../styles'; +import { Snackbar } from 'react-native-paper'; +import { getStrings } from '../../services/helper'; +import SharingManagementItem from '../SharingManagementItem'; +import { requestCalendarPermissions } from '../../services/firebase_messaging'; + +class SharingManagement extends React.PureComponent { + strings = getStrings().SharingManagement; + + static navigationOptions = ({ navigation }) => { + return { + title: navigation.state.params.title, + headerStyle: { + backgroundColor: white, + } + }; + }; + + constructor(props) { + super(props); + + this.state = { + data: [], + loadingList: false, + snackbarVisible: false, + snackbarTime: 3000, + snackbarText: '', + }; + } + + componentWillMount() { + this.getData(); + } + + getData = () => { + this.setState({loadingList: true}); + firebase.database() + .ref(`notifications/${this.props.id}/`) + .once('value', + async (data) => { + data = await data.val(); + + let notDimissed = []; + if (data) { + Object.keys(data).map(i => { + if (!('dismiss' in data[i]) || data[i].dismiss) { + notDimissed.push({ + ...data[i], + notificationPath: i + }); + } + }); + } + + this.setState({ + loadingList: false, + data: notDimissed + }); + }); + } + + + /** + * The callback function when the CalendarItem is touched + */ + _onPressItem = (id) => { + this.setState((state) => { + const selected = new Map(state.selected); + selected.set(id, !selected.get(id)); + return {selected}; + }); + }; + + _deleteItem = (id) => { + let data = this.state.data.slice(); + data.splice(id, 1); + this.setState({ + data + }); + } + + _onAllowItem = (id) => { + requestCalendarPermissions({ + requester: {email: this.state.data[id].senderEmail}, + accepter: {email: this.state.data[id].receiverEmail} + }) + .then(res => res.json()) + .then(success => { + if (success) { + firebase.database() + .ref(`notifications/${this.props.id}/${this.state.data[id].notificationPath}/`) + .update({ + allow: true, + dismiss: false + }); + this._deleteItem(id); + this.setState({ + snackbarVisible: true, + snackbarText: this.strings.allowSuccess, + }); + } else { + this.setState({ + snackbarVisible: true, + snackbarText: this.strings.allowError, + }); + } + }); + } + + _onDenyItem = (id) => { + firebase.database() + .ref(`notifications/${this.props.id}/${this.state.data[id].notificationPath}/`) + .update({ + allow: false, + dismiss: false + }); + + this._deleteItem(id); + + this.setState({ + snackbarVisible: true, + snackbarText: this.strings.denySuccess, + }); + } + + /** + * The render function for the items in the flatList + */ + _renderItem = ({item, index}) => { + return ( + + ); + }; + + render() { + const { data, loadingList, snackbarText, snackbarTime, snackbarVisible } = this.state; + + return ( + + + + + { + loadingList ? + + + : + index.toString()} + style={styles.flatList} + scrollEnabled={data.length !== 0} + ListEmptyComponent={() => ( + + + + {this.strings.emptyTitle} + {this.strings.emptyDescription} + + + )} + refreshControl={ + + } /> + } + + + this.setState({ snackbarVisible: false })} + style={styles.snackbar} + duration={snackbarTime}> + {snackbarText} + + + ); + } +} + +let mapStateToProps = (state) => { + const { id, email } = state.HomeReducer.profile.profile.user; + return { + id, email + }; +}; + +export default connect(mapStateToProps)(SharingManagement); \ No newline at end of file diff --git a/src/components/screens/UnavailableHours.js b/src/components/screens/UnavailableHours.js index e7d2975b..3df67bf1 100644 --- a/src/components/screens/UnavailableHours.js +++ b/src/components/screens/UnavailableHours.js @@ -4,6 +4,7 @@ import DatePicker from 'react-native-datepicker'; import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'; import { connect } from 'react-redux'; import {setUnavailableHours} from '../../actions'; +import { storeUserHours } from '../../services/api/storage_services'; import { UnavailableFixedRoute } from '../../constants/screenNames'; import updateNavigation from '../NavigationHelper'; import { unavailableHoursStyles as styles, white, statusBlueColor, dark_blue, lightBlue } from '../../styles'; @@ -82,11 +83,29 @@ class UnavailableHours extends React.PureComponent { * To go to the next screen and save the required information */ next = () => { + let data = this.formatDataForServer(); + this.props.dispatch(setUnavailableHours(this.state)); + storeUserHours(data).then(success => { + if(success) this.props.navigation.pop(); + }); - this.props.navigation.pop(); } + formatDataForServer = () => { + let data = []; + if (this.state.commutingWeek) data.push({'START': this.state.startCommuteWeek, 'END': this.state.endCommuteWeek, 'WEEK': true, 'CATEGORY': 'COMMUTE'}); + if (this.state.commutingWeekEnd) data.push({'START': this.state.startCommuteWeekEnd, 'END': this.state.endCommuteWeekEnd, 'WEEK': false, 'CATEGORY': 'COMMUTE'}); + if (this.state.otherWeek) data.push({'START': this.state.startOtherWeek, 'END': this.state.endOtherWeek, 'WEEK': true, 'CATEGORY': 'OTHER'}); + if (this.state.otherWeekEnd) data.push({'START': this.state.startOtherWeekEND, 'END': this.state.endOtherWeekEND, 'WEEK': false, 'CATEGORY': 'OTHER'}); + if (this.state.sleepWeek) data.push({'START': this.state.startSleepWeek, 'END':this.state.endSleepWeek, 'WEEK': true, 'CATEGORY': 'SLEEP'}); + if (this.state.sleepWeekEnd) data.push({'START': this.state.startSleepWeekEnd, 'END': this.state.endSleepWeekEnd, 'WEEK': false, 'CATEGORY': 'SLEEP'}); + if (this.state.eatingWeek) data.push({'START': this.state.startEatingWeek, 'END': this.state.startEatingWeek, 'WEEK': true, 'CATEGORY': 'EATING'}); + if (this.state.eatingWeekEnd) data.push({'START': this.state.startEatingWeekEnd, 'END': this.state.endEatingWeekEnd, 'WEEK': false, 'CATEGORY': 'EATING'}); + + return data; + } + render() { return( diff --git a/src/constants.js b/src/constants.js index 301e8693..5efe4de3 100644 --- a/src/constants.js +++ b/src/constants.js @@ -26,6 +26,8 @@ export const UPDATE_NFE = 'UPDATE_NFE'; // GET export const GET_SCHOOL_INFORMATION = 'GET_SCHOOL_INFORMATION'; +export const GET_GENERATED_CALENDAR = 'GET_GENERATED_CALENDAR'; + // CLEAR export const CLEAR_FE = 'CLEAR_FE'; @@ -34,6 +36,7 @@ export const CLEAR_SELECTED_SCHEDULE = 'CLEAR_SELECTED_SCHEDULE'; export const CLEAR_IMG = 'CLEAR_IMG'; export const CLEAR_COURSE = 'CLEAR_COURSE'; export const CLEAR_DASHBOARD_DATA = 'CLEAR_DASHBOARD_DATA'; +export const CLEAR_GENERATED_CALENDAR = 'CLEAR_GENERATED_CALENDAR'; export const CLEAR_GENERATED_NFE = 'CLEAR_GENERATED_NFE'; export const CLEAR_CALENDAR = 'CLEAR_CALENDAR'; export const CLEAR_NAV_SCREEN = 'CLEAR_NAV_SCREEN'; @@ -42,13 +45,11 @@ export const CLEAR_SCHOOL_INFORMATION = 'CLEAR_SCHOOL_INFORMATION'; export const CLEAR_UNAVAILABLE_HOURS = 'CLEAR_UNAVAILABLE_HOURS'; export const CLEAR_SETTINGS = 'CLEAR_SETTINGS'; export const CLEAR_BOTTOM_STRINGS = 'CLEAR_BOTTOM_STRINGS'; -export const CLEAR_GENERATED_CALENDAR = 'CLEAR_GENERATED_CALENDAR'; export const CLEAR_TUTORIAL_STATUS ='CLEAR_TUTORIAL_STATUS'; // SET export const SET_IMG = 'SET_IMG'; export const SET_NAV_SCREEN = 'SET_NAV_SCREEN'; -export const SET_UNAVAILABLE_HOURS = 'SET_UNAVAILABLE_HOURS'; export const SET_SELECTED_SCHEDULE = 'SET_SELECTED_SCHEDULE'; export const SET_BOTTOM_STRINGS = 'SET_BOTTOM_STRINGS'; export const SET_NONFIXED_COLOR = 'SET_NONFIXED_COLOR'; @@ -58,4 +59,6 @@ export const SET_CALENDAR_COLOR = 'SET_CALENDAR_COLOR'; export const SET_DASHBOARD_DATA = 'SET_DASHBOARD_DATA'; export const SET_LANGUAGE = 'SET_LANGUAGE'; export const SET_SCHOOL_INFORMATION = 'SET_SCHOOL_INFORMATION'; -export const SET_TUTORIAL_STATUS = 'SET_TUTORIAL_STATUS'; \ No newline at end of file +export const SET_TUTORIAL_STATUS = 'SET_TUTORIAL_STATUS'; +export const SET_UNAVAILABLE_HOURS = 'SET_UNAVAILABLE_HOURS'; +export const SET_SELECTED_CALENDAR = 'SET_SELECTED_CALENDAR'; diff --git a/src/constants/reducer_constants/allEvents.js b/src/constants/reducer_constants/allEvents.js new file mode 100644 index 00000000..c01c1325 --- /dev/null +++ b/src/constants/reducer_constants/allEvents.js @@ -0,0 +1,2 @@ +export const ADD_EVENT = 'ADD_EVENT'; +export const CLEAR_EVENTS = 'CLEAR_EVENTS'; \ No newline at end of file diff --git a/src/constants/screenNames.js b/src/constants/screenNames.js index 8bee10ae..7b791736 100644 --- a/src/constants/screenNames.js +++ b/src/constants/screenNames.js @@ -21,4 +21,5 @@ export const LoginNavigator = 'LoginNavigator'; export const WelcomeScreen = 'WelcomeScreen'; export const CleanReducersRoute = 'CleanReducers'; -export const CalendarPermissionRoute = 'CalendarPermission'; \ No newline at end of file +export const CalendarPermissionRoute = 'CalendarPermission'; +export const SharingManagementRoute = 'SharingManagement'; \ No newline at end of file diff --git a/src/reducers/AllEventsReducer.js b/src/reducers/AllEventsReducer.js new file mode 100644 index 00000000..242428a1 --- /dev/null +++ b/src/reducers/AllEventsReducer.js @@ -0,0 +1,16 @@ +import { ADD_EVENT, CLEAR_EVENTS } from '../constants/reducer_constants/allEvents'; + +export default function AllEventsReducer(state = [], action) { + const { event } = action; + + switch (action.type) { + case ADD_EVENT: + return [...state, event]; + + case CLEAR_EVENTS: + return []; + + default: + return state; + } +} \ No newline at end of file diff --git a/src/reducers/GeneratedCalendarsReducer.js b/src/reducers/GeneratedCalendarsReducer.js index d43ecb4b..069e0a33 100644 --- a/src/reducers/GeneratedCalendarsReducer.js +++ b/src/reducers/GeneratedCalendarsReducer.js @@ -1,4 +1,4 @@ -import {ADD_GENERATED_CALENDAR, CLEAR_GENERATED_CALENDAR, DELETE_GENERATED_CALENDAR} from '../constants'; +import {ADD_GENERATED_CALENDAR, CLEAR_GENERATED_CALENDAR, DELETE_GENERATED_CALENDAR, SET_SELECTED_CALENDAR} from '../constants'; export default function GeneratedCalendarsReducer(state = [], action) { const { calendar, index } = action; @@ -14,6 +14,9 @@ export default function GeneratedCalendarsReducer(state = [], action) { case CLEAR_GENERATED_CALENDAR: return []; + case SET_SELECTED_CALENDAR: + state[index].selected = true; + return state; default: return state; } diff --git a/src/reducers/SettingsReducer.js b/src/reducers/SettingsReducer.js index b5e1ddec..41929092 100644 --- a/src/reducers/SettingsReducer.js +++ b/src/reducers/SettingsReducer.js @@ -3,8 +3,8 @@ import { SET_LANGUAGE, CLEAR_SETTINGS, SET_TUTORIAL_STATUS, CLEAR_TUTORIAL_STATU let defaultState = { tutorialStatus: { dashboard: false, - reviewEvents: false, - compareSchedule: false + reviewEvents: true, + compareSchedule: true } }; diff --git a/src/reducers/index.js b/src/reducers/index.js index 3f2895ee..385cf4c7 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -14,6 +14,7 @@ import GeneratedCalendarsReducer from './GeneratedCalendarsReducer'; import SettingsReducer from './SettingsReducer'; import BottomNavReducer from './BottomNavReducer'; import DashboardReducer from './DashboardReducer'; +import AllEventsReducer from './AllEventsReducer'; export default combineReducers( { @@ -29,6 +30,7 @@ export default combineReducers( GeneratedNonFixedEventsReducer, SchoolInformationReducer, GeneratedCalendarsReducer, + AllEventsReducer, SettingsReducer, BottomNavReducer, DashboardReducer diff --git a/src/services/api/storage_services.js b/src/services/api/storage_services.js new file mode 100644 index 00000000..5c8c0e97 --- /dev/null +++ b/src/services/api/storage_services.js @@ -0,0 +1,70 @@ +let server = 'http://52.60.127.46:8080/'; + +let apiHelperCall = (URL, method, data) => { + + let fetchData = { + method, + credentials: 'same-origin', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + } + }; + + if( method == 'POST') fetchData.body = JSON.stringify(data); + + return fetch(URL, fetchData); +}; + +export const storeUserInfoService = (info) => { + return apiHelperCall(server + 'api/logUser','POST', info); +}; + +export const getUserInfoService = () => { + return apiHelperCall(server + 'api/getUserInfo','GET'); +}; + +export const getUserInfoByColumnService = (info) => { + return apiHelperCall(server + 'api/getUserInfoByColumns','POST', info); +}; + +export const getUserValuesService = (info) => { + return apiHelperCall(server + 'api/getUserValues','POST', info); +}; + +export const updateUser = (info) => { + return apiHelperCall(server + 'api/updateUser','POST', info); +}; + +export const storeSchoolInfoService = (info) => { + return apiHelperCall(server + 'api/storeSchoolInfo','POST', info); +}; + +export const getSchoolInfoService = () => { + return apiHelperCall(server + 'api/getSchoolInfo','GET'); +}; + +export const storeUserHours = (info) => { + return apiHelperCall(server + 'api/storeUserHours', 'POST', info); +}; + +export const getUserHours = () => { + return apiHelperCall(server + 'api/storeUserHours', 'GET'); +}; + +export const storeInsertedCalendars = (info) => { + return apiHelperCall(server + 'api/storeInsertedCalendars', 'POST', info); +}; + +export const storeGeneratedCalendars = (info) => { + return apiHelperCall(server + 'api/storeGeneratedCalendars', 'POST', info); +}; + + +export const getEvents = () => { + return apiHelperCall(server + 'api/getEvents', 'GET'); +}; + +export const logOutUser = () => { + return apiHelperCall(server + 'api/logOut', 'POST ', {}); +}; \ No newline at end of file diff --git a/src/services/firebase_messaging.js b/src/services/firebase_messaging.js new file mode 100644 index 00000000..66503179 --- /dev/null +++ b/src/services/firebase_messaging.js @@ -0,0 +1,22 @@ +let server = 'http://52.60.127.46:8080/'; + +let apiHelperCall = (URL, method, data) => { + + let fetchData = { + method, + credentials: 'same-origin', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + } + }; + + if( method == 'POST') fetchData.body = JSON.stringify(data); + + return fetch(URL, fetchData); +}; + + +export const requestCalendarPermissions = (info) => { + return apiHelperCall(server + 'api/setCalendarAccess','POST', info); +}; \ No newline at end of file diff --git a/src/services/google_calendar.js b/src/services/google_calendar.js index 55a6425c..e7850b23 100644 --- a/src/services/google_calendar.js +++ b/src/services/google_calendar.js @@ -1,5 +1,4 @@ -import { store } from '../store'; -let accessToken; +import { getUserValuesService } from './api/storage_services'; /** * Helper method for the Google Calendar API calls @@ -9,9 +8,9 @@ let accessToken; * @param {Object} body The body of the call * @param {Object} query Query parameter object to be appended to the URL */ -let apiHelperCall = (URL, method, body, query) => { - accessToken = store.getState().HomeReducer.profile.profile.accessToken; - //accessToken = "ya29.Glu-BlpDlUfWvL5rkqAwV6WUfx4XCfsGku8G072--YzoPjC3_6yb4Rh4b0pXNI5uxF35W_V_-eOhxYkfIyU3XuHlsN0rkt_32sXKe1zxPv6C6TYr_-idfDxj_cE8" +let apiHelperCall = async (URL, method, body, query) => { + let tokenData = await getUserValuesService({columns:['ACCESSTOKEN']}).then(res => res.json()); + let accessToken = tokenData.ACCESSTOKEN; let fetchData = { method, @@ -82,7 +81,6 @@ let getCalendarList = () => { * @returns {Promise} A promise containing an object with the information about the newly created calendar */ let createSecondaryCalendar = (data) => { - console.log('secondary', data); return apiHelperCall('https://www.googleapis.com/calendar/v3/calendars', 'POST', data); }; @@ -242,7 +240,9 @@ let addQuickEvent = (calendarId, data, query) => { * @returns {Promise} A promise containing an object with all of the recurrent events */ let getEventsInstances = (calendarId, eventId, data, query) => { - return apiHelperCall('https://www.googleapis.com/calendar/v3/calendars/' + calendarId + '/events/' + eventId + '/instances', 'GET', data, query); + return new Promise(resolve => { + resolve(apiHelperCall('https://www.googleapis.com/calendar/v3/calendars/' + calendarId + '/events/' + eventId + '/instances', 'GET', data, query)); + }); }; /** diff --git a/src/services/google_identity.js b/src/services/google_identity.js index 2a7fc13c..9829ac9e 100644 --- a/src/services/google_identity.js +++ b/src/services/google_identity.js @@ -21,7 +21,6 @@ let googleSignIn = async () => { let googleSignOut = async () => { try { - await GoogleSignin.revokeAccess(); await GoogleSignin.signOut(); } catch (error) { // console.error(error); @@ -50,4 +49,8 @@ let googleGetCurrentUserInfo = async () => { } }; -module.exports = { googleSignIn, googleSignOut, googleRevokeAccess, googleIsSignedIn, googleGetCurrentUserInfo }; +let getTokens = async () => { + return await GoogleSignin.getTokens(); +}; + +module.exports = { googleSignIn, googleSignOut, googleRevokeAccess, googleIsSignedIn, googleGetCurrentUserInfo, getTokens }; diff --git a/src/services/helper.js b/src/services/helper.js index 7ff53710..cb72d62e 100644 --- a/src/services/helper.js +++ b/src/services/helper.js @@ -22,7 +22,6 @@ export const convertToDictionary = (data) => { return dict; }; - export const convertEventsToDictionary = async (data) => { let calendarID = store.getState().CalendarReducer.id; let dict = {}; @@ -30,27 +29,34 @@ export const convertEventsToDictionary = async (data) => { if (data == undefined) return; data.forEach(async (event) => { - if (event.recurrence) { + if (event.RECURRENCE) { // Get all recurring events if it has recurrence - await getEventsInstances(calendarID, event.id).then(instances => { + await getEventsInstances(calendarID, event.ID).then(async instances => { + let tempEvent = event; + instances.items.forEach(eventRec => { let item = {}; + item.category = tempEvent.CATEGORY; + item.location = event.LOCATION; + item.description = event.DESCRIPTION; item.name = eventRec.summary; - let keyDate = eventRec.start.dateTime.split('T')[0]; + let keyDate = (eventRec.start.date) ? eventRec.start.date : eventRec.start.dateTime.split('T')[0]; item.date = keyDate; - item.actualTime = eventRec.start.dateTime; - - item.time = `${convertLocalTimeStringToSimple(eventRec.start.dateTime)} - ${convertLocalTimeStringToSimple(event.end.dateTime)}`; + item.actualTime = (eventRec.start.date) ? eventRec.start.date : eventRec.start.dateTime; + item.time = (eventRec.start.date)? '' : `${convertLocalTimeStringToSimple(eventRec.start.dateTime)} - ${convertLocalTimeStringToSimple(eventRec.end.dateTime)}`; (dict[keyDate] != undefined) ? dict[keyDate].push(item) : dict[keyDate] = [item]; }); }); } else { let item = {}; - let keyDate = event.start.dateTime.split('T')[0]; - item.name = event.summary; + item.name = event.SUMMARY; + item.category = event.CATEGORY; + item.location = event.LOCATION; + item.description = event.DESCRIPTION; + let keyDate = event.START.split('T')[0]; item.date = keyDate; - item.actualTime = event.start.dateTime; - item.time = `${convertLocalTimeStringToSimple(event.start.dateTime)} - ${convertLocalTimeStringToSimple(event.end.dateTime)}`; + item.actualTime = event.START; + item.time = (event.ALLDAY) ? '': `${convertLocalTimeStringToSimple(event.START)} - ${convertLocalTimeStringToSimple(event.END)}`; (dict[keyDate] != undefined) ? dict[keyDate].push(item) : dict[keyDate] = [item]; } }); diff --git a/src/services/service.js b/src/services/service.js index 82f81386..97f22d60 100644 --- a/src/services/service.js +++ b/src/services/service.js @@ -1,8 +1,9 @@ import { formatData, getStartDate, containsDateTime, divideDuration, getRndInteger, convertEventsToDictionary, selectionSort, getRandomDate, getStrings } from './helper'; -import { insertEvent, getCalendarList, createSecondaryCalendar, getAvailabilities, listEvents, getCalendar, insertAccessRule, getAccessRules, removeAccessRules, deleteCalendar } from './google_calendar'; +import { insertEvent, getCalendarList, createSecondaryCalendar, getAvailabilities, getCalendar, insertAccessRule, getAccessRules, removeAccessRules, deleteCalendar, deleteEvent } from './google_calendar'; import { googleGetCurrentUserInfo } from './google_identity'; import { store } from '../store'; -import { addGeneratedNonFixedEvent, addCourse, addGeneratedCalendar, clearGeneratedNonFixedEvents, logonUser } from '../actions'; +import { getEvents, getUserInfoByColumnService } from './api/storage_services'; +import { addGeneratedNonFixedEvent, addCourse, addGeneratedCalendar, clearGeneratedNonFixedEvents, logonUser, addEvents } from '../actions'; import firebase from 'react-native-firebase'; const strings = getStrings().ServicesError; @@ -217,6 +218,7 @@ export const InsertFixedEventToCalendar = (event) => { export const getCalendarID2 = () => { return new Promise( async function(resolve) { await getCalendarList().then((data) => { + console.log ('data', data); let calendarID; let calendarColor; for (let i = 0; i < data.items.length; i++) { @@ -492,15 +494,17 @@ export const generateCalendars = async () => { }; export const getDataforDashboard = async () => { - let calendarID = store.getState().CalendarReducer.id; return new Promise(async (resolve, reject) => { - await listEvents(calendarID).then(data => { - if (data.error) reject('There was a problem featching your data'); - convertEventsToDictionary(data.items).then(dict => { - if(dict == undefined) reject('There was an error in converting data to dict'); - resolve(dict); + await getEvents() + .then(res => res.json()) + .then((events) => { + if(events.length != 0) { + convertEventsToDictionary(events).then(dict => { + if(dict == undefined) reject('There was an error in converting data to dict'); + resolve(dict); + }); + } }); - }); }); }; @@ -509,6 +513,7 @@ export const sortEventsInDictonary = (dict) => { let sortedValue = selectionSort(value); dict[key] = sortedValue; } + return dict; }; @@ -518,7 +523,10 @@ export const insertFixedEventsToGoogle = async () => { await store.getState().CoursesReducer.forEach(async (event) => { promises.push(new Promise(function(resolve,reject) { InsertCourseEventToCalendar(event).then(data => { + console.log('course', data); if(data.error) reject(strings.insertFixedCourse); + data.category = 3; + store.dispatch(addEvents(data)); resolve(data); }); })); @@ -539,7 +547,9 @@ export const insertFixedEventsToGoogle = async () => { promises.push(new Promise(function(resolve,reject) { InsertFixedEventToCalendar(info).then(data => { - if (data.error) reject(strings.insertFixed); + if (data.error) reject(strings.insertFixed); + data.category = 2; + store.dispatch(addEvents(data)); resolve(data); }); })); @@ -636,13 +646,30 @@ export const listPermissions = () => { * Function in compare schedule, to list everyone who you can compare the schedules */ export const listSharedKalendCalendars = () => { - return new Promise((resolve, reject) => { - getCalendarList().then(data => { + return new Promise( async(resolve, reject) => { + getCalendarList().then(async data => { if (data.error) reject('The calendar does not exists'); + + let promises = []; + let sharedCalendars = data.items.filter(i => i.accessRole == 'freeBusyReader' && i.summary == 'Kalend'); + await sharedCalendars.forEach((i) => { + promises.push( new Promise((resolve) => { + getUserInfoByColumnService({columns: ['PHOTOURL','FULLNAME'], where: {value: i.id, field: 'CALENDARID'} }) + .then(res => res.json()) + .then(info => { + if (info) { + i.name = info.FULLNAME; + i.photo = info.PHOTOURL; + } + resolve(i); + }); + })); + + }); - let sharedCalendars = data.items.filter(i => i.accessRole === 'freeBusyReader' && i.summary === 'Kalend'); - - resolve(sharedCalendars); + Promise.all(promises).then(data => { + resolve(data); + }); }); }); }; @@ -676,4 +703,22 @@ export const getAvailabilitiesCalendars = (calendarIds, startTime, endTime) => { resolve(data); }); }); +}; + +/** + * + * Function called in compare schedule, to remove someone else from your shared calendars + * + * @param {Strings} calendarId The ID of the Calendar + * @param {String} events IDs of the events pushed to google Calendar + */ +export const deleteCreatedGoogleEvents = () => { + let events = store.getState().AllEventsReducer; + let calendarID = store.getState().CalendarReducer.id; + let promises = []; + events.forEach(event => { + promises.push(deleteEvent(calendarID, event.id)); + }); + + return Promise.all(promises); }; \ No newline at end of file diff --git a/src/styles.js b/src/styles.js index b909eb27..38f72b61 100644 --- a/src/styles.js +++ b/src/styles.js @@ -1909,7 +1909,7 @@ export const compareScheduleStyles = StyleSheet.create({ flatList: { flexWrap: 'wrap', - paddingVertical: 10, + paddingVertical: Platform.OS === 'ios' ? 0 : 10, marginLeft: -7 }, @@ -2551,4 +2551,97 @@ export const importCalendarStyles = StyleSheet.create({ color: gray, paddingTop: 10 } +}); + +export const sharingManagementItemsStyles = StyleSheet.create({ + + content: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + padding: 10, + margin: 5, + marginBottom: 5, + marginHorizontal: 15, + borderRadius: 5, + ...Platform.select({ + ios: { + shadowColor: '#000000', + shadowOffset: { width: 0, height: 2 }, + shadowOpacity: 0.3, + shadowRadius: 3, + }, + android: { + elevation: 4, + }, + }), + backgroundColor: white + }, + + buttons: { + flexDirection: 'row', + }, + + allow: { + marginHorizontal: 10, + backgroundColor: dark_blue, + borderRadius: 5, + padding: 8 + }, + + allowText: { + fontFamily: 'Raleway-Regular', + color: white, + }, + + deny: { + marginHorizontal: 10, + backgroundColor: white, + borderRadius: 5, + padding: 8 + }, + + denyText: { + fontFamily: 'Raleway-Regular', + color: dark_blue, + }, + + title: { + fontFamily: 'Raleway-Bold', + color: gray + }, + email: { + fontFamily: 'Raleway-Regular', + color: gray + } +}); + +export const sharingManagementStyles = StyleSheet.create({ + content: { + flex: 1, + width: '100%', + height: '100%', + }, + + activityIndicatorContainer: { + justifyContent: 'center', + alignItems: 'center', + height: '100%' + }, + + emptyContainer: { + height: Dimensions.get('window').height - getStatusBarHeight() - Header.HEIGHT - 30, + justifyContent: 'center', + alignItems: 'center' + }, + + emptyTitle: { + fontFamily: 'Raleway-Bold', + color: gray + }, + + emptyDescription: { + fontFamily: 'Raleway-Regular', + color: gray + }, }); \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index e6eb74e3..f0e285f5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -669,9 +669,9 @@ integrity sha512-gSpqtFrypY3qr6QR17ADV7qnfWU3BEzMffaKu4kcX8fz21kSjpS1OaklyAsQxhIiEHgK64V3QYduqttMKQChrQ== "@react-native-community/cli@^1.2.1": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-1.8.0.tgz#92792e7949c963b1affedb272b3c3af87d1c73f0" - integrity sha512-VACBOX7YHbN+9+yqw3ihf3mSNvKRuq0MfR04RADDlMgk9VvdmhTl27miQn3RHsjlSy9xum3nSFYC3zlVlW4Hqw== + version "1.9.1" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-1.9.1.tgz#47e261a4a8bdfdcbd9a971b90e56257bee5af1ac" + integrity sha512-OPZi/DP3WWBXgZzu+JmhCnGPvmuz/eEgCzXpaumOEnBRXENrKzHvVzi9oG3m2YSgIra0WEQeLBeogw1R/te0vQ== dependencies: chalk "^1.1.1" commander "^2.19.0" @@ -714,9 +714,9 @@ integrity sha512-L02BSwDTHGc5BPrtllMTOKSKg9QyJbz001pIkD2FGmUFA9Nfvs0cne36N4nnrR5jQhSzwnmnQpzXkQ/yzQxwMg== "@react-native-community/viewpager@^1.1.5": - version "1.1.5" - resolved "https://registry.yarnpkg.com/@react-native-community/viewpager/-/viewpager-1.1.5.tgz#98f1a3adabfc33dafe5baaf653ce300c2475e62e" - integrity sha512-JJf6no31hH+Zuhex6F3VdmQ3TLdtdCtcVY4Ej53wp7qFvnmzCGs595czFKULPTpp821ioqXppX40ZZ6jMVQefQ== + version "1.1.6" + resolved "https://registry.yarnpkg.com/@react-native-community/viewpager/-/viewpager-1.1.6.tgz#267da51adbdebfb709e2e22f5e06399f49e6b1ae" + integrity sha512-WnlLGNdzkL0GQQ1WK0++giXOgQcEU6Dx+WEj7uYmqLNCsIc1Jhvm1ChTEKOs5N7Otz+VgoPBOvQyEuAUKooSOg== "@react-navigation/core@~3.3.0": version "3.3.1" @@ -1024,9 +1024,9 @@ astral-regex@^1.0.0: integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== async-each@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.2.tgz#8b8a7ca2a658f927e9f307d6d1a42f4199f0f735" - integrity sha512-6xrbvN0MOBKSJDdonmSSz2OwFSgxRaVtBDes26mj9KIGtDo+g9xosFRSC+i1gQh2oAN/tQ62AI/pGZGQjVOiRg== + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== async-limiter@~1.0.0: version "1.0.0" @@ -1281,7 +1281,7 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= -base-64@0.1.0, base-64@^0.1.0: +base-64@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/base-64/-/base-64-0.1.0.tgz#780a99c84e7d600260361511c4877613bf24f6bb" integrity sha1-eAqZyE59YAJgNhURxId2E78k9rs= @@ -1643,9 +1643,9 @@ commondir@^1.0.1: integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= component-emitter@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" - integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== compressible@~2.0.16: version "2.0.16" @@ -2701,12 +2701,12 @@ fs.realpath@^1.0.0: integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= fsevents@^1.2.3, fsevents@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.7.tgz#4851b664a3783e52003b3c66eb0eee1074933aa4" - integrity sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw== + version "1.2.8" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.8.tgz#57ea5320f762cd4696e5e8e87120eccc8b11cacf" + integrity sha512-tPvHgPGB7m40CZ68xqFGkKuzN+RnpGmSV+hgeKxhRpbxdqKXUFJGC3yonBOLzQBcJyGpdZFDfCsdOC2KFsXzeA== dependencies: - nan "^2.9.2" - node-pre-gyp "^0.10.0" + nan "^2.12.1" + node-pre-gyp "^0.12.0" function-bind@^1.1.1: version "1.1.1" @@ -4526,7 +4526,7 @@ micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" -"mime-db@>= 1.38.0 < 2": +"mime-db@>= 1.38.0 < 2", mime-db@~1.39.0: version "1.39.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.39.0.tgz#f95a20275742f7d2ad0429acfe40f4233543780e" integrity sha512-DTsrw/iWVvwHH+9Otxccdyy0Tgiil6TWK/xhfARJZF/QFhwOgZgOIvA2/VIGpM8U7Q8z5nDmdDWC6tuVMJNibw== @@ -4536,11 +4536,6 @@ mime-db@~1.23.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.23.0.tgz#a31b4070adaea27d732ea333740a64d0ec9a6659" integrity sha1-oxtAcK2uon1zLqMzdApk0OyaZlk= -mime-db@~1.38.0: - version "1.38.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.38.0.tgz#1a2aab16da9eb167b49c6e4df2d9c68d63d8e2ad" - integrity sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg== - mime-types@2.1.11: version "2.1.11" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.11.tgz#c259c471bda808a85d6cd193b430a5fae4473b3c" @@ -4549,11 +4544,11 @@ mime-types@2.1.11: mime-db "~1.23.0" mime-types@^2.1.12, mime-types@~2.1.18, mime-types@~2.1.19: - version "2.1.22" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.22.tgz#fe6b355a190926ab7698c9a0556a11199b2199bd" - integrity sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog== + version "2.1.23" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.23.tgz#d4eacd87de99348a6858fe1e479aad877388d977" + integrity sha512-ROk/m+gMVSrRxTkMlaQOvFmFmYDc7sZgrjjM76abqmd2Cc5fCV7jAMA5XUccEtJ3cYiYdgixUVI+fApc2LkXlw== dependencies: - mime-db "~1.38.0" + mime-db "~1.39.0" mime@1.4.1: version "1.4.1" @@ -4672,16 +4667,11 @@ mute-stream@0.0.7: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= -nan@^2.9.2: +nan@^2.12.1: version "2.13.2" resolved "https://registry.yarnpkg.com/nan/-/nan-2.13.2.tgz#f51dc7ae66ba7d5d55e1e6d4d8092e802c9aefe7" integrity sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw== -nan@~2.10.0: - version "2.10.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" - integrity sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA== - nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -4767,26 +4757,10 @@ node-notifier@^5.2.1: shellwords "^0.1.1" which "^1.3.0" -node-pre-gyp@^0.10.0: - version "0.10.3" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" - integrity sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A== - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.1" - needle "^2.2.1" - nopt "^4.0.1" - npm-packlist "^1.1.6" - npmlog "^4.0.2" - rc "^1.2.7" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^4" - -node-pre-gyp@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz#db1f33215272f692cd38f03238e3e9b47c5dd054" - integrity sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q== +node-pre-gyp@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" + integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A== dependencies: detect-libc "^1.0.2" mkdirp "^0.5.1" @@ -5133,9 +5107,9 @@ parse5@4.0.0: integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== parseurl@~1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" - integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== pascalcase@^0.1.1: version "0.1.1" @@ -5496,9 +5470,9 @@ react-native-app-intro-slider@^1.0.1: xdate "^0.8.0" react-native-camera@^2.0.2: - version "2.4.0" - resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-2.4.0.tgz#1f3c6fc2afcc556b4f2b7b6a166f86e4a88ca95d" - integrity sha512-BPPcZEqnEyVjn9bwnuu9hrLErAb3OCyL9+mU/uOoejmIf/6GpdJdbGAkpP6kPDiBWo3b1ki34b7Zccv6Y3MFBA== + version "2.6.0" + resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-2.6.0.tgz#bf97b0fc68aa8732d815e9bbd92e63529f51d598" + integrity sha512-g0Hi4yhUg1yBsYbW9aLxVaX+rgl9sKrrDAGF6difiRTvwCUEqlID2DosLCQQPkLSniJHVa8gc+SwCegahU23aA== dependencies: prop-types "^15.6.2" @@ -5527,14 +5501,6 @@ react-native-firebase@^5.2.2: opencollective-postinstall "^2.0.0" prop-types "^15.6.2" -react-native-fs@^2.13.3: - version "2.13.3" - resolved "https://registry.yarnpkg.com/react-native-fs/-/react-native-fs-2.13.3.tgz#a422f0ecd8a093a7e99d8d51ff51440e090a18a8" - integrity sha512-B62LSSAEYQGItg7KVTzTVVCxezOYFBYp4DMVFbdoZUd1mZVFdqR2sy1HY1mye1VI/Lf3IbxSyZEQ0GmrrdwLjg== - dependencies: - base-64 "^0.1.0" - utf8 "^2.1.1" - react-native-gesture-handler@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.1.0.tgz#2a7d545ad2e0ca23adce22b2af441ad360ecccee" @@ -5545,9 +5511,9 @@ react-native-gesture-handler@^1.1.0: prop-types "^15.5.10" react-native-google-signin@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/react-native-google-signin/-/react-native-google-signin-1.2.2.tgz#8131b3f0668b3dc96f963835ae821613f022070f" - integrity sha512-SqqZihkwO7Zbz7IsFqudEpa1kkoSjbDHsj6xyOZxTyGz/QgGVMkfJzrNNduZd9vJv+OJjdxzrz2dUNuNqTPFzA== + version "1.2.3" + resolved "https://registry.yarnpkg.com/react-native-google-signin/-/react-native-google-signin-1.2.3.tgz#700943177a55cd8668a8fb85e370bcf1cb920d1e" + integrity sha512-9n1vkxYI2uwt91Jvx2BUqL5xeyNivytMnaR5OWIVujVGj1y2bpn4XCwT7R2C2WzYRrcD8xw9R6Pp5R4Linj1hg== react-native-iphone-x-helper@^1.2.0: version "1.2.0" @@ -5681,7 +5647,7 @@ react-native-web@^0.11.1: prop-types "^15.6.0" react-timer-mixin "^0.13.4" -react-native@^0.59.1: +react-native@0.59.4: version "0.59.4" resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.59.4.tgz#c0725e2e8efdea135533794ce95fea2289fe619a" integrity sha512-etnXQp9IZgC8Vj5gsxZEDP4xRjJVNIj5/BSE1WcNAONG6tu6+mDBntx1jxHInwh61WYNgoQJuQGsbN5Na59ZDw== @@ -5917,11 +5883,6 @@ redux-persist@^5.10.0: resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-5.10.0.tgz#5d8d802c5571e55924efc1c3a9b23575283be62b" integrity sha512-sSJAzNq7zka3qVHKce1hbvqf0Vf5DuTVm7dr4GtsqQVOexnrvbV47RWFiPxQ8fscnyiuWyD2O92DOxPl0tGCRg== -redux-thunk@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622" - integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw== - redux@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.1.tgz#436cae6cc40fbe4727689d7c8fae44808f1bfef5" @@ -6521,15 +6482,6 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -sqlite3@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-4.0.6.tgz#e587b583b5acc6cb38d4437dedb2572359c080ad" - integrity sha512-EqBXxHdKiwvNMRCgml86VTL5TK1i0IKiumnfxykX0gh6H6jaKijAXvE9O1N7+omfNSawR2fOmIyJZcfe8HYWpw== - dependencies: - nan "~2.10.0" - node-pre-gyp "^0.11.0" - request "^2.87.0" - sshpk@^1.7.0: version "1.16.1" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" @@ -7003,11 +6955,6 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== -utf8@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/utf8/-/utf8-2.1.2.tgz#1fa0d9270e9be850d9b05027f63519bf46457d96" - integrity sha1-H6DZJw6b6FDZsFAn9jUZv0ZFfZY= - util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"