version:2.9

fix:优化接口,增加检测其他应用
update:
This commit is contained in:
2022-03-01 10:34:46 +08:00
parent 97bc5d6a75
commit ee731661fc
55 changed files with 1165 additions and 1342 deletions

View File

@@ -27,9 +27,9 @@ import com.aoleyun.sn.bean.PoweroffBean;
import com.aoleyun.sn.bean.SnRunLog;
import com.aoleyun.sn.bean.WiFiAlias;
import com.aoleyun.sn.comm.JGYActions;
import com.aoleyun.sn.network.api.newapi.GetPublicIPApi;
import com.aoleyun.sn.network.api.newapi.SnTimeControlApi;
import com.aoleyun.sn.network.api.newapi.TopAppControlApi;
import com.aoleyun.sn.network.api.GetPublicIPApi;
import com.aoleyun.sn.network.api.SnTimeControlApi;
import com.aoleyun.sn.network.api.TopAppControlApi;
import com.aoleyun.sn.service.LogcatService;
import com.aoleyun.sn.service.main.MainService;
import com.aoleyun.sn.utils.ApkUtils;
@@ -621,33 +621,26 @@ public class HTTPInterface {
public static void getAppLimit(Context context) {
NetInterfaceManager.getInstance()
.getAppLimitObservable()
.subscribe(new Observer<ResponseBody>() {
.subscribe(new Observer<BaseResponse>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("getAppLimit", "onSubscribe: ");
}
@Override
public void onNext(@NonNull ResponseBody responseBody) {
try {
String bodyString = responseBody.string();
Log.e("getAppLimit", "onNext: " + bodyString);
JsonObject jsonObject = JsonParser.parseString(bodyString).getAsJsonObject();
int code = jsonObject.get("code").getAsInt();
if (code == 200) {
String data = jsonObject.get("data").getAsJsonObject().get("result").getAsString();
public void onNext(@NonNull BaseResponse baseResponse) {
Log.e("getAppLimit", "onNext: " + baseResponse);
JsonObject jsonObject = JsonParser.parseString(baseResponse.data.toString()).getAsJsonObject();
if (baseResponse.code == 200) {
String data = jsonObject.get("result").getAsString();
//开机图标 只记录后台传的包名
boolean write = Settings.System.putString(context.getContentResolver(), JGYActions.ACTION_JGY_SHORTCUTLIST, data);
Log.e(TAG, "onNext: only_jgy_shortcut_list: " + write);
JGYUtils.getInstance().writeAppPackageList(context, data);
JGYUtils.getInstance().deleteOtherApp();
} else {
Log.e("getAppLimit", "onNext: " + bodyString);
Log.e("getAppLimit", "onNext: " + baseResponse);
}
} catch (IOException e) {
e.printStackTrace();
Log.e("getAppLimit", "onNext: IOException: " + e.getMessage());
}
}
@Override

View File

@@ -8,6 +8,7 @@ import android.util.Log;
import com.alibaba.fastjson.JSONObject;
import com.aoleyun.sn.BuildConfig;
import com.aoleyun.sn.bean.AppListInfo;
import com.aoleyun.sn.bean.Appground;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.bean.BrowserBookmarks;
@@ -30,40 +31,40 @@ import com.aoleyun.sn.network.api.ForceDownloadApi;
import com.aoleyun.sn.network.api.NetAndLaunchApi;
import com.aoleyun.sn.network.api.SystemSettingApi;
import com.aoleyun.sn.network.api.UploadAppInfoApi;
import com.aoleyun.sn.network.api.newapi.AppinsideWebApi;
import com.aoleyun.sn.network.api.newapi.BrowserBookmarksApi;
import com.aoleyun.sn.network.api.newapi.BrowserListApi;
import com.aoleyun.sn.network.api.newapi.CheckTestUpdateApi;
import com.aoleyun.sn.network.api.newapi.CheckUpdateApi;
import com.aoleyun.sn.network.api.newapi.CustomROMAppApi;
import com.aoleyun.sn.network.api.newapi.DefaultAppApi;
import com.aoleyun.sn.network.api.newapi.DesktopIconApi;
import com.aoleyun.sn.network.api.newapi.DevicesLockedStateApi;
import com.aoleyun.sn.network.api.newapi.GetAllAppApi;
import com.aoleyun.sn.network.api.newapi.GetAppLogApi;
import com.aoleyun.sn.network.api.newapi.GetBatchApi;
import com.aoleyun.sn.network.api.newapi.GetDesktopApi;
import com.aoleyun.sn.network.api.newapi.GetDeveloperApi;
import com.aoleyun.sn.network.api.newapi.GetEBagCodeApi;
import com.aoleyun.sn.network.api.newapi.GetLockStateApi;
import com.aoleyun.sn.network.api.newapi.GetJpushTagsApi;
import com.aoleyun.sn.network.api.newapi.GetPoweroffApi;
import com.aoleyun.sn.network.api.newapi.GetSnRunLogApi;
import com.aoleyun.sn.network.api.newapi.GetUploadIsLogApi;
import com.aoleyun.sn.network.api.newapi.GetUploadLogApi;
import com.aoleyun.sn.network.api.newapi.GetWiFiAliasApi;
import com.aoleyun.sn.network.api.newapi.LogoImgApi;
import com.aoleyun.sn.network.api.newapi.MACAddressApi;
import com.aoleyun.sn.network.api.newapi.NewAppinsideWebApi;
import com.aoleyun.sn.network.api.newapi.ScreenLockStateApi;
import com.aoleyun.sn.network.api.newapi.SendDownloadInfoApi;
import com.aoleyun.sn.network.api.newapi.SendDownloadTimesApi;
import com.aoleyun.sn.network.api.newapi.SendRestoreTimesApi;
import com.aoleyun.sn.network.api.newapi.SendScreenshotApi;
import com.aoleyun.sn.network.api.newapi.SnTimeControlApi;
import com.aoleyun.sn.network.api.newapi.StudentsInfosApi;
import com.aoleyun.sn.network.api.newapi.TopAppControlApi;
import com.aoleyun.sn.network.api.newapi.UpdateDeviceInfoApi;
import com.aoleyun.sn.network.api.AppinsideWebApi;
import com.aoleyun.sn.network.api.BrowserBookmarksApi;
import com.aoleyun.sn.network.api.BrowserListApi;
import com.aoleyun.sn.network.api.CheckTestUpdateApi;
import com.aoleyun.sn.network.api.CheckUpdateApi;
import com.aoleyun.sn.network.api.CustomROMAppApi;
import com.aoleyun.sn.network.api.DefaultAppApi;
import com.aoleyun.sn.network.api.DesktopIconApi;
import com.aoleyun.sn.network.api.DevicesLockedStateApi;
import com.aoleyun.sn.network.api.GetAllAppApi;
import com.aoleyun.sn.network.api.GetAppLogApi;
import com.aoleyun.sn.network.api.GetBatchApi;
import com.aoleyun.sn.network.api.GetDesktopApi;
import com.aoleyun.sn.network.api.GetDeveloperApi;
import com.aoleyun.sn.network.api.GetEBagCodeApi;
import com.aoleyun.sn.network.api.GetLockStateApi;
import com.aoleyun.sn.network.api.GetJpushTagsApi;
import com.aoleyun.sn.network.api.GetPoweroffApi;
import com.aoleyun.sn.network.api.GetSnRunLogApi;
import com.aoleyun.sn.network.api.GetUploadIsLogApi;
import com.aoleyun.sn.network.api.GetUploadLogApi;
import com.aoleyun.sn.network.api.GetWiFiAliasApi;
import com.aoleyun.sn.network.api.LogoImgApi;
import com.aoleyun.sn.network.api.MACAddressApi;
import com.aoleyun.sn.network.api.NewAppinsideWebApi;
import com.aoleyun.sn.network.api.ScreenLockStateApi;
import com.aoleyun.sn.network.api.SendDownloadInfoApi;
import com.aoleyun.sn.network.api.SendDownloadTimesApi;
import com.aoleyun.sn.network.api.SendRestoreTimesApi;
import com.aoleyun.sn.network.api.SendScreenshotApi;
import com.aoleyun.sn.network.api.SnTimeControlApi;
import com.aoleyun.sn.network.api.StudentsInfosApi;
import com.aoleyun.sn.network.api.TopAppControlApi;
import com.aoleyun.sn.network.api.UpdateDeviceInfoApi;
import com.aoleyun.sn.rlog.LogDBManager;
import com.aoleyun.sn.utils.ApkUtils;
import com.aoleyun.sn.utils.JGYUtils;
@@ -76,7 +77,6 @@ import com.google.gson.JsonParser;
import com.tencent.android.tpush.XGIOperateCallback;
import com.tencent.android.tpush.XGPushManager;
import com.tencent.mmkv.MMKV;
import com.trello.rxlifecycle4.LifecycleProvider;
import com.trello.rxlifecycle4.RxLifecycle;
import com.trello.rxlifecycle4.android.ActivityEvent;
@@ -95,10 +95,10 @@ import java.util.concurrent.TimeUnit;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.ObservableEmitter;
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
import io.reactivex.rxjava3.core.ObservableSource;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.functions.Function;
import io.reactivex.rxjava3.schedulers.Schedulers;
import io.reactivex.rxjava3.subjects.BehaviorSubject;
import okhttp3.Cache;
@@ -338,7 +338,7 @@ public class NetInterfaceManager {
.observeOn(AndroidSchedulers.mainThread());
}
public Observable<ResponseBody> getAppLimitObservable() {
public Observable<BaseResponse> getAppLimitObservable() {
return mRetrofit.create(AppLimitApi.class)
.getAppLimitApi(NetInterfaceManager.HTTP_KEY, Utils.getSerial())
.subscribeOn(Schedulers.io())
@@ -559,7 +559,7 @@ public class NetInterfaceManager {
public void getLockedState(BehaviorSubject<ActivityEvent> provider, ObserverCallback callback) {
long lastTime = mMMKV.decodeLong(GET_LOCKED_STATE_TIME, 0);
if (System.currentTimeMillis() - ONE_MINUTE_TIME < lastTime) {
if (System.currentTimeMillis() - TEN_MINUTE_TIME < lastTime) {
callback.onComplete();
return;
}
@@ -691,7 +691,8 @@ public class NetInterfaceManager {
}
String address = String.valueOf(SPUtils.get(mContext, "AmapAddress", "-"));
if ("-".equals(address)) {
address = (String) SPUtils.get(mContext, "AmapError", "-");
address = "定位失败";
// address = (String) SPUtils.get(mContext, "AmapError", "-");
}
String longitude = String.valueOf(SPUtils.get(mContext, "longitude", "0"));
String latitude = String.valueOf(SPUtils.get(mContext, "latitude", "0"));
@@ -813,6 +814,4 @@ public class NetInterfaceManager {
}
});
}
}

View File

@@ -10,13 +10,24 @@ public class UrlAddress {
/*根网址*/
public static final String HTTP_TAG_HEAD_NEW = BuildConfig.ROOT_URL;
/*下载接口 根据包名匹配 请求后更新下载次数*/
public static final String SEND_DOWNLOAD_TIMES = "count/index";
/*app下载完成发送下载次数*/
public static final String SEND_DOWNLOAD_FILE_INFO = "app/downloadApp";
/*获取系统默认程序*/
public static final String GET_DEFAULT_APP = "app/getDefaultApp";
/*下载接口 根据包名匹配 请求后更新下载次数*/
public static final String SEND_DOWNLOAD_TIMES = "count/index";
/*获取设备锁定状态*/
public static final String GET_DEVICES_LOCKED = "lock/index";
/*获取批次*/
public static final String GET_BATCH = "log/getBatch";
/*上传锁屏状态*/
public static final String GET_LOCK_STATE = "Application/getLockState";
/*APPID管控*/
public static final String GET_APPID = "application/index";
/*获取系统设置*/
public static final String GET_FIRMWARE = "firmware/get";
/*上传安装的应用信息*/
public static final String UPLOAD_APPINFO = "log/index";
/*发送设备信息*/
public static final String SEND_DEVICES = "Mac/getMac";
/*发送app使用情况*/
@@ -67,8 +78,7 @@ public class UrlAddress {
public static final String GET_ALL_APP = "recommend/index";
/*获取电子书包激活码*/
public static final String GET_EBAG_CODE = "And/getEbagCode";
/*获取系统默认程序*/
public static final String GET_DEFAULT_APP = "app/getDefaultApp";
/*恢复出厂设置次数*/
public static final String SEND_RESTORE_TIMES = "And/restore";
/*获取远程关机时间*/

View File

@@ -1,9 +1,9 @@
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.network.UrlAddress;
import io.reactivex.rxjava3.core.Observable;
import okhttp3.ResponseBody;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;
@@ -11,7 +11,7 @@ import retrofit2.http.POST;
public interface AppLimitApi {
@FormUrlEncoded
@POST(UrlAddress.SET_WHITE_PACKAGE_LIST)
Observable<ResponseBody> getAppLimitApi(
Observable<BaseResponse> getAppLimitApi(
@Field("key") String key,
@Field("sn") String sn
);

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.Appground;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.bean.BrowserBookmarks;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.bean.BrowserData;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.bean.ForceDownloadData;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.network.UrlAddress;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.network.UrlAddress;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.bean.DefaultApp;

View File

@@ -1,5 +1,7 @@
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.network.UrlAddress;
import io.reactivex.rxjava3.core.Observable;
import okhttp3.ResponseBody;
import retrofit2.http.Field;
@@ -8,7 +10,7 @@ import retrofit2.http.POST;
public interface DeselectIDApi {
@FormUrlEncoded
@POST("application/index")
@POST(UrlAddress.GET_APPID)
Observable<ResponseBody> getDeselectIDApi(
@Field("key") String key,
@Field("sn") String sn

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.network.UrlAddress;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.network.UrlAddress;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.AppListInfo;
import com.aoleyun.sn.bean.BaseResponse;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.network.UrlAddress;

View File

@@ -1,4 +1,6 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.network.UrlAddress;
import io.reactivex.rxjava3.core.Observable;
import okhttp3.ResponseBody;
@@ -8,7 +10,7 @@ import retrofit2.http.POST;
public interface GetBatchApi {
@FormUrlEncoded
@POST("log/getBatch")
@POST(UrlAddress.GET_BATCH)
Observable<ResponseBody> getBatch(
@Field("sn") String sn
);

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.network.UrlAddress;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.network.UrlAddress;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.network.UrlAddress;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.network.UrlAddress;

View File

@@ -1,4 +1,6 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.network.UrlAddress;
import io.reactivex.rxjava3.core.Observable;
import okhttp3.ResponseBody;
@@ -8,7 +10,7 @@ import retrofit2.http.POST;
public interface GetLockStateApi {
@FormUrlEncoded
@POST("Application/getLockState")
@POST(UrlAddress.GET_LOCK_STATE)
Observable<ResponseBody> getLockState(
@Field("sn") String sn,
@Field("status") String status,

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.bean.PoweroffBean;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.network.UrlAddress;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.bean.SnRunLog;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.bean.SnRunLog;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.bean.SnRunLog;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.bean.LogoImg;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.network.UrlAddress;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.network.UrlAddress;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.network.UrlAddress;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.network.UrlAddress;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.network.UrlAddress;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.BuildConfig;
import com.aoleyun.sn.bean.BaseResponse;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.network.UrlAddress;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.network.UrlAddress;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.bean.StudentsInfo;

View File

@@ -1,15 +1,16 @@
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.network.UrlAddress;
import io.reactivex.rxjava3.core.Observable;
import okhttp3.ResponseBody;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;
public interface SystemSettingApi {
@FormUrlEncoded
@POST("firmware/get")
@POST(UrlAddress.GET_FIRMWARE)
Observable<ResponseBody> getSystemSettingApi(
@Field("key") String key,
@Field("sn") String sn

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.network.UrlAddress;

View File

@@ -1,4 +1,4 @@
package com.aoleyun.sn.network.api.newapi;
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.network.UrlAddress;

View File

@@ -1,6 +1,7 @@
package com.aoleyun.sn.network.api;
import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.network.UrlAddress;
import io.reactivex.rxjava3.core.Observable;
import retrofit2.http.Field;
@@ -9,7 +10,7 @@ import retrofit2.http.POST;
public interface UploadAppInfoApi {
@FormUrlEncoded
@POST("log/index")
@POST(UrlAddress.UPLOAD_APPINFO)
Observable<BaseResponse> getUploadAppInfoApi(
@Field("key") String key,
@Field("sn") String sn,