|
@@ -0,0 +1,546 @@
|
|
|
|
+package com.rc.httpcore.client.retrofit
|
|
|
|
+
|
|
|
|
+import com.rc.httpcore.HttpClient
|
|
|
|
+import com.rc.httpcore.client.ExamClient
|
|
|
|
+import com.rc.httpcore.exception.NetException
|
|
|
|
+import com.rc.httpcore.vo.CommonListResponse
|
|
|
|
+import com.rc.httpcore.vo.CommonResponse
|
|
|
|
+import com.rc.httpcore.vo.request.*
|
|
|
|
+import com.rc.httpcore.vo.response.*
|
|
|
|
+import io.reactivex.Observable
|
|
|
|
+
|
|
|
|
+class ExamRetrofit : ExamClient {
|
|
|
|
+
|
|
|
|
+ private val apiService by lazy {
|
|
|
|
+ HttpClient.createRetrofitApi(ApiService::class.java)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 登录获取token
|
|
|
|
+ */
|
|
|
|
+ override fun authOneLogin(): Observable<Boolean> {
|
|
|
|
+ val param = AccessTokenReq().apply {
|
|
|
|
+ username = "onecUser"
|
|
|
|
+ password = "admin123"
|
|
|
|
+ }
|
|
|
|
+ return apiService.authOneLogin(param)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ HttpClient.token = response.data?.access_token
|
|
|
|
+ return@map !HttpClient.token.isNullOrEmpty()
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 查询APK版本
|
|
|
|
+ *
|
|
|
|
+ * @param id 设备唯一编码
|
|
|
|
+ */
|
|
|
|
+ override fun apkVersion(id: String): Observable<ApkInfoResp> {
|
|
|
|
+ return apiService.apkVersion(id)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+ return@map response.data
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 上传APK更新状态
|
|
|
|
+ *
|
|
|
|
+ * @param state 0:升级失败; 1:升级成功; 2:升级中
|
|
|
|
+ */
|
|
|
|
+ override fun onepcApkUpdate(id: String, state: String): Observable<Boolean> {
|
|
|
|
+ return apiService.onepcApkUpdate(id, state)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+ return@map true
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 查询轮播图
|
|
|
|
+ *
|
|
|
|
+ * @param id 设备唯一编码
|
|
|
|
+ */
|
|
|
|
+ override fun bannerImages(id: String): Observable<List<BannerImageBean>> {
|
|
|
|
+ return apiService.bannerImages(id)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+ return@map response.data
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 人脸比对
|
|
|
|
+ */
|
|
|
|
+ override fun faceCompare(param: FaceCompareReq): Observable<Boolean> {
|
|
|
|
+ return apiService.faceCompare(param)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map true
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 学习一体机 用户端登录
|
|
|
|
+ *
|
|
|
|
+ * @param param 刷学生卡数据 userName
|
|
|
|
+ */
|
|
|
|
+ override fun learnLogin(param: LearnLoginReq): Observable<LearnLoginVo> {
|
|
|
|
+ return apiService.learnLogin(param)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+// if (response.code == "4466") {
|
|
|
|
+// response.data?.isLogin = "1"
|
|
|
|
+// response.data?.expires_in = response.msg
|
|
|
|
+//// HttpClient.token = response.data?.access_token
|
|
|
|
+// return@map response.data
|
|
|
|
+// } else {
|
|
|
|
+ HttpClient.token = response.data?.access_token
|
|
|
|
+ return@map response.data
|
|
|
|
+// }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ override fun loginToken(param: LearnLoginReq): Observable<LearnLoginVo> {
|
|
|
|
+ return apiService.loginToken(param)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+// HttpClient.token = response.data?.access_token
|
|
|
|
+ return@map response.data
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 安全学习-学习分类
|
|
|
|
+ */
|
|
|
|
+ override fun categoryTreeList(): Observable<List<CategoryTree>> {
|
|
|
|
+ return apiService.categoryTreeList("0")
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response.data
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 安全学习-查询学习资源列表
|
|
|
|
+ */
|
|
|
|
+ override fun examCourseList(param: CourseListReq): Observable<CommonListResponse<ExamCourseVo>> {
|
|
|
|
+ val filters = mutableMapOf<String, Any>().apply {
|
|
|
|
+ put("cateId", param.cateId ?: "")
|
|
|
|
+ put("title", param.title ?: "")
|
|
|
|
+ put("pageNum", param.pageNum)
|
|
|
|
+ put("pageSize", param.pageSize)
|
|
|
|
+ if (!param.scopeType.isNullOrEmpty()) {
|
|
|
|
+ put("scopeType", param.scopeType)
|
|
|
|
+ }
|
|
|
|
+// put("status", "1")
|
|
|
|
+ }
|
|
|
|
+ return apiService.examCourseList(filters)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 安全学习-获取学习资源详细信息
|
|
|
|
+ */
|
|
|
|
+ override fun examCourseDetail(id: String): Observable<ExamCourseVo> {
|
|
|
|
+ return apiService.examCourseDetail(id)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response.data
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 安全学习-开始学习
|
|
|
|
+ */
|
|
|
|
+ override fun examLearnStart(param: ExamLearnReq): Observable<Boolean> {
|
|
|
|
+ return apiService.examLearnStart(param)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map true
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 安全学习-开始学习
|
|
|
|
+ */
|
|
|
|
+ override fun examLearnFinish(param: ExamLearnReq): Observable<LearnBonusBean> {
|
|
|
|
+ return apiService.examLearnFinish(param)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response.data
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 安全学习-个人学习记录
|
|
|
|
+ */
|
|
|
|
+ override fun examLearnRecord(param: LearnRecordReq): Observable<CommonListResponse<LearnRecordVo>> {
|
|
|
|
+ return apiService.examLearnRecord(param.pageNum, param.pageSize, param)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 查询题目类型下拉框
|
|
|
|
+ */
|
|
|
|
+ override fun classifyQueryOption(): Observable<List<TopicClassifyVo>> {
|
|
|
|
+ return apiService.classifyQueryOption(Object())
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response.data
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 查询模拟列表
|
|
|
|
+ */
|
|
|
|
+ override fun onlineList(param: MockTestReq): Observable<CommonListResponse<MockTestVo>> {
|
|
|
|
+ return apiService.onlineList(param.pageNum, param.pageSize, param.classifyIds)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 开始-查询考试前后否需要人脸验证
|
|
|
|
+ *
|
|
|
|
+ * @param examId 非模拟考试模式下都传-1
|
|
|
|
+ */
|
|
|
|
+ override fun examStartVerify(type: String, examId: String): Observable<ExamVerify> {
|
|
|
|
+ return apiService.examStartVerify(type, examId)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response.data
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 开始考试-创建考卷
|
|
|
|
+ *
|
|
|
|
+ * @param examId 非模拟考试模式下都传-1
|
|
|
|
+ */
|
|
|
|
+ override fun examStart(type: String, examId: String): Observable<ExamTopic> {
|
|
|
|
+ return apiService.examStart(type, examId)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response.data
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 考试 保存用户答案 一题一交
|
|
|
|
+ */
|
|
|
|
+ override fun examFillAnswer(param: ExamAnswerReq): Observable<Boolean> {
|
|
|
|
+ return apiService.examFillAnswer(param)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map true
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 交卷- 完成考试
|
|
|
|
+ */
|
|
|
|
+ override fun examHandPaper(param: HandPaperReq): Observable<HandPaperBean> {
|
|
|
|
+ return apiService.examHandPaper(param)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response.data
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 个人考试成绩列表查询
|
|
|
|
+ */
|
|
|
|
+ override fun paperMyList(param: ExamScoreReq): Observable<CommonListResponse<ExamTopic>> {
|
|
|
|
+ return apiService.paperMyList(param.pageNum, param.pageSize, param)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 个人考试成绩详情查询
|
|
|
|
+ */
|
|
|
|
+ override fun paperDetail(id: String): Observable<ExamTopic> {
|
|
|
|
+ return apiService.paperDetail(id)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response.data
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 考试 查询问题和选项 - 一题一查
|
|
|
|
+ */
|
|
|
|
+ override fun paperExamQuDetail(param: PaperQuReq): Observable<ExamTopic.ElPaperQu> {
|
|
|
|
+ return apiService.paperExamQuDetail(param)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response.data
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 查询我的证书列表
|
|
|
|
+ */
|
|
|
|
+ override fun queryMyCert(pageNum: Int, pageSize: Int): Observable<CommonListResponse<CertVo>> {
|
|
|
|
+ return apiService.queryMyCert(pageNum, pageSize, Object())
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 模拟练习-开始练习
|
|
|
|
+ */
|
|
|
|
+ override fun mockTestStart(ids: String): Observable<ExamTopic> {
|
|
|
|
+ return apiService.mockTestStart(ids)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response.data
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 练习 查询问题和选项 - 一题一查
|
|
|
|
+ */
|
|
|
|
+ override fun paperMockQuDetail(param: PaperQuReq): Observable<ExamTopic.ElPaperQu> {
|
|
|
|
+ return apiService.paperMockQuDetail(param)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response.data
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 练习 保存用户答案 - 一题一交
|
|
|
|
+ */
|
|
|
|
+ override fun mockAnswer(param: MockAnswerReq): Observable<Boolean> {
|
|
|
|
+ return apiService.mockAnswer(param)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map true
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 结束练习
|
|
|
|
+ */
|
|
|
|
+ override fun handPractise(param: HandPractiseReq): Observable<HandPractiseBean> {
|
|
|
|
+ return apiService.handPractise(param)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response.data
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 个人中心-用户信息
|
|
|
|
+ */
|
|
|
|
+ override fun queryUserInfo(): Observable<UserInfo> {
|
|
|
|
+ return apiService.queryUserInfo()
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response.data
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 个人中心-违规信息
|
|
|
|
+ */
|
|
|
|
+ override fun queryViolationList(param: ViolationReq): Observable<List<ViolationBean>> {
|
|
|
|
+ return apiService.queryViolationList(
|
|
|
|
+ param.pageNum,
|
|
|
|
+ param.pageSize,
|
|
|
|
+ param.statTime,
|
|
|
|
+ param.endTime,
|
|
|
|
+ param.overStatus
|
|
|
|
+ )
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response.rows
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 是否有待处理的违规
|
|
|
|
+ */
|
|
|
|
+ override fun existTodoViolation(): Observable<Boolean> {
|
|
|
|
+ return apiService.existTodoViolation()
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map true
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 开始考核-生成考核考卷
|
|
|
|
+ * @param id 章节ID
|
|
|
|
+ */
|
|
|
|
+ override fun classTestStart(id: String): Observable<ExamTopic> {
|
|
|
|
+ return apiService.classTestStart(id)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response.data
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 结束考核
|
|
|
|
+ * @param id 考核ID(试卷ID)
|
|
|
|
+ */
|
|
|
|
+ override fun handAssess(id: String): Observable<HandPractiseBean> {
|
|
|
|
+ return apiService.handAssess(id)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response.data
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 考核记录列表
|
|
|
|
+ */
|
|
|
|
+ override fun classTestRecord(param: AssessRecordReq): Observable<CommonListResponse<AccessRecordBean>> {
|
|
|
|
+ return apiService.classTestRecord(param.chapterId, param.pageNum, param.pageSize)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 考核详情
|
|
|
|
+ * @param id 考核ID(试卷ID)
|
|
|
|
+ */
|
|
|
|
+ override fun classTestDetail(id: String): Observable<ExamTopic> {
|
|
|
|
+ return apiService.classTestDetail(id)
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map response.data
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 退出登录
|
|
|
|
+ */
|
|
|
|
+ override fun loginOut(): Observable<Boolean> {
|
|
|
|
+ return apiService.loginOut()
|
|
|
|
+ .map { response ->
|
|
|
|
+ if (!response.isSuccess()) {
|
|
|
|
+ throw NetException(response.code, response.msg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return@map true
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|