@sentiance-react-native/core 6.0.0-beta.17 → 6.0.0-beta.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,24 +1,9 @@
1
- ## Installation
1
+ # Sentiance Core module for React Native
2
2
 
3
- ```bash
4
- npm i @sentiance-react-native/core
5
- ```
3
+ ## Demo Application
6
4
 
7
- ## Usage
8
-
9
- ### Importing the package
10
-
11
- You can import the entire contents of the package for use under a namespace of your choosing:
5
+ https://github.com/sentiance/sample-apps-react-native
12
6
 
13
- ```javascript
14
- import * as SentianceCore from "@sentiance-react-native/core";
15
- ```
16
-
17
- or you can require specific functionality using named imports:
7
+ ## Usage
18
8
 
19
- ```javascript
20
- import {
21
- enableDetections,
22
- createUser
23
- } from "@sentiance-react-native/core";
24
- ```
9
+ To use the core SDK module, please visit the corresponding [API reference page.](https://docs.sentiance.com/sdk/api-reference/react-native/core)
@@ -43,7 +43,7 @@ public class SentianceConverter {
43
43
  }
44
44
 
45
45
  public static Map<String, String> convertReadableMapToMap(ReadableMap inputMap) {
46
- Map<String, String> map = new HashMap<String, String>();
46
+ Map<String, String> map = new HashMap<>();
47
47
  ReadableMapKeySetIterator iterator = inputMap.keySetIterator();
48
48
  while (iterator.hasNextKey()) {
49
49
  String key = iterator.nextKey();
@@ -120,99 +120,88 @@ public class SentianceConverter {
120
120
  }
121
121
 
122
122
  public static WritableMap convertUserCreationResult(UserCreationResult result) {
123
- WritableMap map = Arguments.createMap();
124
123
  UserInfo userInfo = result.getUserInfo();
125
- try {
126
- Token token = userInfo.getToken();
127
- map.putString("userId", userInfo.getUserId());
128
- map.putString("tokenId", token.getTokenId());
129
- map.putString("tokenExpiryDate", SentianceUtils.toDateString(token.getExpiryDate()));
130
- map.putBoolean("isTokenExpired", token.isExpired());
131
- } catch (Exception ignored) {
132
- }
124
+ Token token = userInfo.getToken();
133
125
 
134
- return map;
126
+ WritableMap userInfoMap = Arguments.createMap();
127
+ userInfoMap.putString("userId", userInfo.getUserId());
128
+ userInfoMap.putString("tokenId", token.getTokenId());
129
+ userInfoMap.putString("tokenExpiryDate", SentianceUtils.toDateString(token.getExpiryDate()));
130
+ userInfoMap.putBoolean("isTokenExpired", token.isExpired());
131
+
132
+ WritableMap userCreationResult = Arguments.createMap();
133
+ userCreationResult.putMap("userInfo", userInfoMap);
134
+ return userCreationResult;
135
135
  }
136
136
 
137
137
  public static WritableMap convertUserLinkingResult(UserLinkingResult result) {
138
- WritableMap map = Arguments.createMap();
139
138
  UserInfo userInfo = result.getUserInfo();
140
- try {
141
- Token token = userInfo.getToken();
142
- map.putString("userId", userInfo.getUserId());
143
- map.putString("tokenId", token.getTokenId());
144
- map.putString("tokenExpiryDate", SentianceUtils.toDateString(token.getExpiryDate()));
145
- map.putBoolean("isTokenExpired", token.isExpired());
146
- } catch (Exception ignored) {
147
- }
139
+ Token token = userInfo.getToken();
148
140
 
149
- return map;
141
+ WritableMap userInfoMap = Arguments.createMap();
142
+ userInfoMap.putString("userId", userInfo.getUserId());
143
+ userInfoMap.putString("tokenId", token.getTokenId());
144
+ userInfoMap.putString("tokenExpiryDate", SentianceUtils.toDateString(token.getExpiryDate()));
145
+ userInfoMap.putBoolean("isTokenExpired", token.isExpired());
146
+
147
+ WritableMap userLinkingResult = Arguments.createMap();
148
+ userLinkingResult.putMap("userInfo", userInfoMap);
149
+ return userLinkingResult;
150
150
  }
151
151
 
152
152
  public static WritableMap convertInstallId(String installId) {
153
153
  WritableMap map = Arguments.createMap();
154
- try {
155
- map.putString("installId", installId);
156
- } catch (Exception ignored) {
157
- }
154
+ map.putString("installId", installId);
155
+
158
156
  return map;
159
157
  }
160
158
 
161
159
  public static WritableMap convertSdkStatus(SdkStatus status) {
162
160
  WritableMap map = Arguments.createMap();
163
- try {
164
- map.putString("startStatus", status.startStatus.name());
165
- map.putString("detectionStatus", status.detectionStatus.name());
166
- map.putBoolean("canDetect", status.canDetect);
167
- map.putBoolean("isRemoteEnabled", status.isRemoteEnabled);
168
- map.putString("locationPermission", status.locationPermission.toString());
169
- map.putBoolean("isActivityRecognitionPermGranted", status.isActivityRecognitionPermGranted);
170
- map.putString("locationSetting", status.locationSetting.name());
171
- map.putBoolean("isAirplaneModeEnabled", status.isAirplaneModeEnabled);
172
- map.putBoolean("isLocationAvailable", status.isLocationAvailable);
173
- map.putBoolean("isAccelPresent", status.isAccelPresent);
174
- map.putBoolean("isGyroPresent", status.isGyroPresent);
175
- map.putBoolean("isGpsPresent", status.isGpsPresent);
176
- map.putBoolean("isGooglePlayServicesMissing", status.isGooglePlayServicesMissing);
177
- map.putBoolean("isBatteryOptimizationEnabled", status.isBatteryOptimizationEnabled);
178
- map.putBoolean("isBatterySavingEnabled", status.isBatterySavingEnabled);
179
- map.putBoolean("isBackgroundProcessingRestricted", status.isBackgroundProcessingRestricted);
180
- map.putBoolean("isPreciseLocationAuthorizationGranted", status.isPreciseLocationPermGranted);
181
- map.putBoolean("isSchedulingExactAlarmsPermitted", status.isSchedulingExactAlarmsPermitted);
182
- map.putString("wifiQuotaStatus", status.wifiQuotaStatus.toString());
183
- map.putString("mobileQuotaStatus", status.mobileQuotaStatus.toString());
184
- map.putString("diskQuotaStatus", status.diskQuotaStatus.toString());
185
- map.putBoolean("userExists", status.userExists);
186
- } catch (Exception ignored) {
187
- }
161
+ map.putString("startStatus", status.startStatus.name());
162
+ map.putString("detectionStatus", status.detectionStatus.name());
163
+ map.putBoolean("canDetect", status.canDetect);
164
+ map.putBoolean("isRemoteEnabled", status.isRemoteEnabled);
165
+ map.putString("locationPermission", status.locationPermission.toString());
166
+ map.putBoolean("isActivityRecognitionPermGranted", status.isActivityRecognitionPermGranted);
167
+ map.putString("locationSetting", status.locationSetting.name());
168
+ map.putBoolean("isAirplaneModeEnabled", status.isAirplaneModeEnabled);
169
+ map.putBoolean("isLocationAvailable", status.isLocationAvailable);
170
+ map.putBoolean("isAccelPresent", status.isAccelPresent);
171
+ map.putBoolean("isGyroPresent", status.isGyroPresent);
172
+ map.putBoolean("isGpsPresent", status.isGpsPresent);
173
+ map.putBoolean("isGooglePlayServicesMissing", status.isGooglePlayServicesMissing);
174
+ map.putBoolean("isBatteryOptimizationEnabled", status.isBatteryOptimizationEnabled);
175
+ map.putBoolean("isBatterySavingEnabled", status.isBatterySavingEnabled);
176
+ map.putBoolean("isBackgroundProcessingRestricted", status.isBackgroundProcessingRestricted);
177
+ map.putBoolean("isPreciseLocationAuthorizationGranted", status.isPreciseLocationPermGranted);
178
+ map.putBoolean("isSchedulingExactAlarmsPermitted", status.isSchedulingExactAlarmsPermitted);
179
+ map.putString("wifiQuotaStatus", status.wifiQuotaStatus.toString());
180
+ map.putString("mobileQuotaStatus", status.mobileQuotaStatus.toString());
181
+ map.putString("diskQuotaStatus", status.diskQuotaStatus.toString());
182
+ map.putBoolean("userExists", status.userExists);
188
183
 
189
184
  return map;
190
185
  }
191
186
 
192
187
  public static WritableMap convertUserActivity(UserActivity activity) {
193
188
  WritableMap map = Arguments.createMap();
194
- try {
195
- map.putString("type", convertUserActivityType(activity.getActivityType()));
196
-
197
- //Trip Info
198
- if (activity.getTripInfo() != null) {
199
- WritableMap tripInfoMap = Arguments.createMap();
200
- String tripType = convertTripType(activity.getTripInfo().getTripType());
201
- tripInfoMap.putString("type", tripType);
202
- map.putMap("tripInfo", tripInfoMap);
203
- }
204
-
205
- //Stationary Info
206
- if (activity.getStationaryInfo() != null) {
207
- WritableMap stationaryInfoMap = Arguments.createMap();
208
- if (activity.getStationaryInfo().getLocation() != null) {
209
- WritableMap locationMap = convertLocation(activity.getStationaryInfo().getLocation());
210
- stationaryInfoMap.putMap("location", locationMap);
211
- }
212
- map.putMap("stationaryInfo", stationaryInfoMap);
213
- }
189
+ map.putString("type", convertUserActivityType(activity.getActivityType()));
190
+
191
+ //Trip Info
192
+ if (activity.getTripInfo() != null) {
193
+ WritableMap tripInfoMap = Arguments.createMap();
194
+ String tripType = convertTripType(activity.getTripInfo().getTripType());
195
+ tripInfoMap.putString("type", tripType);
196
+ map.putMap("tripInfo", tripInfoMap);
197
+ }
214
198
 
215
- } catch (Exception ignored) {
199
+ //Stationary Info
200
+ if (activity.getStationaryInfo() != null) {
201
+ WritableMap stationaryInfoMap = Arguments.createMap();
202
+ WritableMap locationMap = convertLocation(activity.getStationaryInfo().getLocation());
203
+ stationaryInfoMap.putMap("location", locationMap);
204
+ map.putMap("stationaryInfo", stationaryInfoMap);
216
205
  }
217
206
 
218
207
  return map;
@@ -338,10 +327,8 @@ public class SentianceConverter {
338
327
  public static String stringifyStopTripError(StopTripError error) {
339
328
  StopTripFailureReason reason = error.getReason();
340
329
  String details = "";
341
- switch (reason) {
342
- case NO_ONGOING_TRIP:
343
- details = "There is no ongoing external trip.";
344
- break;
330
+ if (reason == StopTripFailureReason.NO_ONGOING_TRIP) {
331
+ details = "There is no ongoing external trip.";
345
332
  }
346
333
  return String.format("Reason: %s - %s", reason.name(), details);
347
334
  }
@@ -525,5 +525,15 @@ public class SentianceModule extends AbstractSentianceModule {
525
525
  .setTripTimeoutListener(emitter::sendOnTripTimedOutEvent);
526
526
  promise.resolve(null);
527
527
  }
528
+
529
+ @ReactMethod
530
+ public void addListener(String eventName) {
531
+ // Set up any upstream listeners or background tasks as necessary
532
+ }
533
+
534
+ @ReactMethod
535
+ public void removeListeners(Integer count) {
536
+ // Remove upstream listeners, stop unnecessary background tasks
537
+ }
528
538
  }
529
539
 
@@ -24,12 +24,12 @@ public class SentianceUtils {
24
24
  public static final String SENTIANCE_FALLBACK_NOTIFICATION_CHANNEL_NAME = "Sentiance";
25
25
  public static final String SENTIANCE_FALLBACK_NOTIFICATION_CHANNEL_ID = "Sentiance";
26
26
 
27
- public static final String SENTIANCE_NOTIFICATION_ID = "com.sentiance.react.bridge.notification_id";
28
- public static final String SENTIANCE_NOTIFICATION_TITLE = "com.sentiance.react.bridge.notification_title";
29
- public static final String SENTIANCE_NOTIFICATION_ICON = "com.sentiance.react.bridge.notification_icon";
30
- public static final String SENTIANCE_NOTIFICATION_CHANNEL_ID = "com.sentiance.react.bridge.channel_id";
31
- public static final String SENTIANCE_NOTIFICATION_CHANNEL_NAME = "com.sentiance.react.bridge.notification_channel_name";
32
- public static final String SENTIANCE_NOTIFICATION_NOTIFICATION_TEXT = "com.sentiance.react.bridge.notification_text";
27
+ public static final String SENTIANCE_NOTIFICATION_ID = "com.sentiance.react.bridge.core.notification_id";
28
+ public static final String SENTIANCE_NOTIFICATION_TITLE = "com.sentiance.react.bridge.core.notification_title";
29
+ public static final String SENTIANCE_NOTIFICATION_ICON = "com.sentiance.react.bridge.core.notification_icon";
30
+ public static final String SENTIANCE_NOTIFICATION_CHANNEL_ID = "com.sentiance.react.bridge.core.channel_id";
31
+ public static final String SENTIANCE_NOTIFICATION_CHANNEL_NAME = "com.sentiance.react.bridge.core.notification_channel_name";
32
+ public static final String SENTIANCE_NOTIFICATION_NOTIFICATION_TEXT = "com.sentiance.react.bridge.core.notification_text";
33
33
 
34
34
  private static final String DATE_TIME_PATTERN_M = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; // ISO_8601
35
35
 
@@ -1,6 +1,6 @@
1
1
  //
2
- // RNSentiance+Converter.h
3
- // RNSentiance
2
+ // RNSentianceCore+Converter.h
3
+ // RNSentianceCore
4
4
  //
5
5
  // Created by Sebouh Aguehian on 10/10/2021.
6
6
  // Copyright © 2021 Facebook. All rights reserved.
@@ -1,6 +1,6 @@
1
1
  //
2
- // RNSentianceConverter.m
3
- // RNSentiance
2
+ // RNSentianceCore+Converter.m
3
+ // RNSentianceCore
4
4
  //
5
5
  // Created by Sebouh Aguehian on 10/10/2021.
6
6
  // Copyright © 2021 Facebook. All rights reserved.
@@ -626,13 +626,13 @@
626
626
 
627
627
  - (NSString*)convertInitStateToString:(SENTSDKInitState) state {
628
628
  switch (state) {
629
- case SENTNotInitialized:
629
+ case SENTSDKInitStateNotInitialized:
630
630
  return @"NOT_INITIALIZED";
631
- case SENTInitInProgress:
631
+ case SENTSDKInitStateInProgress:
632
632
  return @"INIT_IN_PROGRESS";
633
- case SENTInitialized:
633
+ case SENTSDKInitStateInitialized:
634
634
  return @"INITIALIZED";
635
- case SENTResetting:
635
+ case SENTSDKInitStateResetting:
636
636
  return @"RESETTING";
637
637
  default:
638
638
  return @"UNRECOGNIZED_STATE";
@@ -685,16 +685,18 @@
685
685
  }
686
686
 
687
687
  - (NSDictionary *)convertUserCreationResult:(SENTUserCreationResult *)userCreationResult {
688
- NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
688
+ NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
689
689
 
690
- dict[@"userId"] = userCreationResult.userInfo.userId;
691
- dict[@"tokenId"] = userCreationResult.userInfo.token.tokenId;
690
+ userInfo[@"userId"] = userCreationResult.userInfo.userId;
691
+ userInfo[@"tokenId"] = userCreationResult.userInfo.token.tokenId;
692
692
 
693
693
  NSString *tokenExpiryDate = [[SENTDate alloc]initWithNSDate: userCreationResult.userInfo.token.expiryDate].description;
694
- dict[@"tokenExpiryDate"] = tokenExpiryDate;
695
- dict[@"isTokenExpired"] = @(userCreationResult.userInfo.token.isExpired);
694
+ userInfo[@"tokenExpiryDate"] = tokenExpiryDate;
695
+ userInfo[@"isTokenExpired"] = @(userCreationResult.userInfo.token.isExpired);
696
696
 
697
- return dict;
697
+ NSMutableDictionary *userCreationResultDict = [[NSMutableDictionary alloc] init];
698
+ userCreationResultDict[@"userInfo"] = userInfo;
699
+ return userCreationResultDict;
698
700
  }
699
701
 
700
702
  - (NSString *)stringifyUserCreationError:(SENTUserCreationError *)userCreationError {
@@ -754,16 +756,18 @@
754
756
  }
755
757
 
756
758
  - (NSDictionary *)convertUserLinkingResult:(SENTUserLinkingResult *)userLinkingResult {
757
- NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
759
+ NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
758
760
 
759
- dict[@"userId"] = userLinkingResult.userInfo.userId;
760
- dict[@"tokenId"] = userLinkingResult.userInfo.token.tokenId;
761
+ userInfo[@"userId"] = userLinkingResult.userInfo.userId;
762
+ userInfo[@"tokenId"] = userLinkingResult.userInfo.token.tokenId;
761
763
 
762
764
  NSString *tokenExpiryDate = [[SENTDate alloc]initWithNSDate: userLinkingResult.userInfo.token.expiryDate].description;
763
- dict[@"tokenExpiryDate"] = tokenExpiryDate;
764
- dict[@"isTokenExpired"] = @(userLinkingResult.userInfo.token.isExpired);
765
+ userInfo[@"tokenExpiryDate"] = tokenExpiryDate;
766
+ userInfo[@"isTokenExpired"] = @(userLinkingResult.userInfo.token.isExpired);
765
767
 
766
- return dict;
768
+ NSMutableDictionary *userLinkingResultDict = [[NSMutableDictionary alloc] init];
769
+ userLinkingResultDict[@"userInfo"] = userInfo;
770
+ return userLinkingResultDict;
767
771
  }
768
772
 
769
773
  - (NSString *)stringifyUserLinkingError:(SENTUserLinkingError *)userLinkingError {
@@ -313,8 +313,6 @@ RCT_EXPORT_METHOD(disableDetections:(RCTPromiseResolveBlock)resolve rejecter:(RC
313
313
 
314
314
  RCT_EXPORT_METHOD(getInitState:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
315
315
  {
316
- REJECT_IF_SDK_NOT_INITIALIZED(reject);
317
-
318
316
  @try {
319
317
  SENTSDKInitState initState = [[Sentiance sharedInstance] getInitState];
320
318
  resolve([self convertInitStateToString:initState]);
@@ -1030,7 +1028,7 @@ RCT_EXPORT_METHOD(listenTripTimeout:(RCTPromiseResolveBlock)resolve rejecter:(RC
1030
1028
  }
1031
1029
 
1032
1030
  - (BOOL)isSdkNotInitialized {
1033
- return [Sentiance sharedInstance].initState != SENTInitialized;
1031
+ return [Sentiance sharedInstance].initState != SENTSDKInitStateInitialized;
1034
1032
  }
1035
1033
 
1036
1034
  @end
@@ -1,6 +1,6 @@
1
1
  //
2
- // ErrorCodes.h
3
- // Pods
2
+ // RNSentianceErrorCodes.h
3
+ // RNSentianceCore
4
4
  //
5
5
  // Created by Hassan Shakeel on 05/05/2022.
6
6
  //
@@ -1,6 +1,6 @@
1
1
  //
2
- // ErrorCodes.m
3
- // RNSentiance
2
+ // RNSentianceErrorCodes.m
3
+ // RNSentianceCore
4
4
  //
5
5
  // Created by Hassan Shakeel on 05/05/2022.
6
6
  //
@@ -1,6 +1,6 @@
1
1
  //
2
- // SentianceHelper.h
3
- // Pods
2
+ // RNSentianceHelper.h
3
+ // RNSentianceCore
4
4
  //
5
5
  // Created by Hassan Shakeel on 10/05/2022.
6
6
  //
@@ -27,5 +27,7 @@
27
27
  launchOptions:(nullable NSDictionary *)launchOptions
28
28
  NS_SWIFT_NAME(initializeSDK(platformUrl:isAppSessionDataCollectionAllowed:launchOptions:));
29
29
 
30
+ - (void)enableDetectionsIfUserExists;
31
+
30
32
  @end
31
33
 
@@ -1,6 +1,6 @@
1
1
  //
2
- // SentianceHelper.m
3
- // DoubleConversion
2
+ // RNSentianceHelper.m
3
+ // RNSentianceCore
4
4
  //
5
5
  // Created by Hassan Shakeel on 10/05/2022.
6
6
  //
@@ -28,11 +28,17 @@
28
28
  - (SENTInitializationResult *)initializeSDKWithPlatformUrl:(NSString *)platformUrl
29
29
  isAppSessionDataCollectionAllowed:(BOOL *)isAppSessionDataCollectionAllowed
30
30
  launchOptions:(nullable NSDictionary *)launchOptions {
31
- SENTOptions *options = [[SENTOptions alloc] init];
31
+ SENTOptions *options = [[SENTOptions alloc] initFor:SENTOptionsInitPurposeAppLaunch];
32
32
  options.platformUrl = platformUrl;
33
33
  options.isAppSessionDataCollectionAllowed = isAppSessionDataCollectionAllowed;
34
34
  return [[Sentiance sharedInstance] initializeWithOptions:options launchOptions:launchOptions];
35
35
  }
36
36
 
37
+ - (void)enableDetectionsIfUserExists {
38
+ if ([Sentiance sharedInstance].userExists) {
39
+ [[Sentiance sharedInstance] enableDetectionsWithCompletionHandler:nil];
40
+ }
41
+ }
42
+
37
43
  @end
38
44
 
package/lib/index.d.ts CHANGED
@@ -111,7 +111,12 @@ declare module "sentiance-react-native-core" {
111
111
  backgroundRefreshStatus: BackgroundRefreshStatus; // iOS only
112
112
  }
113
113
 
114
- export interface EnableDisableDetectionsResult {
114
+ export interface EnableDetectionsResult {
115
+ sdkStatus: SdkStatus,
116
+ detectionStatus: DetectionStatus
117
+ }
118
+
119
+ export interface DisableDetectionsResult {
115
120
  sdkStatus: SdkStatus,
116
121
  detectionStatus: DetectionStatus
117
122
  }
@@ -121,11 +126,11 @@ declare module "sentiance-react-native-core" {
121
126
 
122
127
  userExists(): Promise<boolean>;
123
128
 
124
- enableDetections(): Promise<EnableDisableDetectionsResult>;
129
+ enableDetections(): Promise<EnableDetectionsResult>;
125
130
 
126
- enableDetectionsWithExpiryDate(expiryEpochTimeMs: number | null): Promise<EnableDisableDetectionsResult>;
131
+ enableDetectionsWithExpiryDate(expiryEpochTimeMs: number | null): Promise<EnableDetectionsResult>;
127
132
 
128
- disableDetections(): Promise<EnableDisableDetectionsResult>;
133
+ disableDetections(): Promise<DisableDetectionsResult>;
129
134
 
130
135
  reset(): Promise<ResetResult>;
131
136
 
@@ -185,7 +190,7 @@ declare module "sentiance-react-native-core" {
185
190
 
186
191
  createUser(options: UserCreationOptions): Promise<CreateUserResult>;
187
192
 
188
- linkUser(): Promise<UserLinkingResult>;
193
+ linkUser(linker: (installId) => boolean): Promise<UserLinkingResult>;
189
194
 
190
195
  linkUserWithAuthCode(authCode: string): Promise<UserLinkingResult>;
191
196
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentiance-react-native/core",
3
- "version": "6.0.0-beta.17",
3
+ "version": "6.0.0-beta.21",
4
4
  "description": "React Native Sentiance core library",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
@@ -29,10 +29,10 @@
29
29
  "targetSdk": 31,
30
30
  "compileSdk": 31,
31
31
  "buildTools": "30.0.3",
32
- "sentiance": "6.0.0-beta7"
32
+ "sentiance": "6.0.0"
33
33
  },
34
34
  "ios": {
35
- "sentiance": "6.0.0-beta14"
35
+ "sentiance": "6.0.0"
36
36
  }
37
37
  }
38
38
  }