480 lines
17 KiB
Java
Executable File
480 lines
17 KiB
Java
Executable File
/*
|
|
* Copyright(C)2001-2012 Actionsoft Co.,Ltd
|
|
* AWS(Actionsoft workflow suite) BPM(Business Process Management) PLATFORM Source code
|
|
* AWS is a application middleware for BPM System
|
|
|
|
|
|
* 本软件工程编译的二进制文件及源码版权归北京炎黄盈动科技发展有限责任公司所有,
|
|
* 受中国国家版权局备案及相关法律保护,未经书面法律许可,任何个人或组织都不得泄漏、
|
|
* 传播此源码文件的全部或部分文件,不得对编译文件进行逆向工程,违者必究。
|
|
|
|
* $$本源码是炎黄盈动最高保密级别的文件$$
|
|
*
|
|
* http://www.actionsoft.com.cn
|
|
*
|
|
*/
|
|
|
|
package com.actionsoft.apps.coe.pal;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
|
|
|
import com.actionsoft.apps.coe.pal.components.web.BPMOrgTreeWeb;
|
|
import com.actionsoft.apps.coe.pal.log.CoEOpLogAPI;
|
|
import com.actionsoft.apps.coe.pal.log.CoEOpLogConst;
|
|
import com.actionsoft.apps.coe.pal.pal.manage.publish.web.PublishManageWeb;
|
|
import com.actionsoft.apps.coe.pal.pal.repository.web.CoeProcessLevelWeb;
|
|
import com.actionsoft.bpms.commons.cluster.loadbalancer.ClusterAPI;
|
|
import com.actionsoft.bpms.commons.cluster.loadbalancer.listener.NodeListener;
|
|
import com.actionsoft.bpms.commons.htmlframework.AlertWindow;
|
|
import com.actionsoft.bpms.commons.login.BPMClientPortalController;
|
|
import com.actionsoft.bpms.commons.login.constant.LoginConst;
|
|
import com.actionsoft.bpms.commons.mvc.view.ResponseObject;
|
|
import com.actionsoft.bpms.commons.portal.SystemController;
|
|
import com.actionsoft.bpms.commons.security.basic.PermAPIManager;
|
|
import com.actionsoft.bpms.commons.security.logging.model.Level;
|
|
import com.actionsoft.bpms.commons.session.SessionImpl;
|
|
import com.actionsoft.bpms.commons.session.cache.SessionCache;
|
|
import com.actionsoft.bpms.commons.session.model.SessionModel;
|
|
import com.actionsoft.bpms.org.web.CompanyWeb;
|
|
import com.actionsoft.bpms.server.*;
|
|
import com.actionsoft.bpms.server.bind.annotation.Controller;
|
|
import com.actionsoft.bpms.server.bind.annotation.Mapping;
|
|
import com.actionsoft.apps.coe.pal.constant.CoEConstant;
|
|
import com.actionsoft.apps.coe.pal.install.CoeSuitInstall;
|
|
import com.actionsoft.apps.coe.pal.install.util.InitUtil;
|
|
import com.actionsoft.apps.coe.pal.install.web.CoEInitWeb;
|
|
import com.actionsoft.apps.coe.pal.portal.web.CoEPortalSkins;
|
|
import com.actionsoft.apps.coe.pal.portal.web.NavigationWeb;
|
|
import com.actionsoft.apps.coe.pal.system.property.CoePropertyUtil;
|
|
import com.actionsoft.apps.coe.pal.team.user.web.UserWeb;
|
|
import com.actionsoft.apps.coe.pal.util.Table2Excel;
|
|
import com.actionsoft.exception.AWSForbiddenException;
|
|
import com.actionsoft.exception.AWSQuotaException;
|
|
import com.actionsoft.sdk.local.SDK;
|
|
|
|
@Controller
|
|
public class CoECommonController {
|
|
|
|
@Mapping("com.actionsoft.apps.coe.pal_user_login_from_other")
|
|
public String loginCoeFromOther(UserContext me) {
|
|
// String sid = new SSOUtil().registerClientSessionNoPassword(me.getUID(), me.getLanguage(), me.getClientIP(), me.getDeviceType());
|
|
SessionModel sessionModel = new SessionImpl().registerSession(LoginConst.SYSTEM_COE, me.getUID(), me.getClientIP(), me.getLanguage(), me.getDeviceType(), true, null);
|
|
ResponseObject ro = ResponseObject.newOkResponse();
|
|
ro.put("sid", sessionModel.getSessionId());
|
|
return ro.toString();
|
|
}
|
|
|
|
// @Mapping("COE_USER_LOGIN")
|
|
@Mapping("com.actionsoft.apps.coe.pal_user_login")
|
|
public String loginCoE(String userid, String pwd, String clientIp, String lang, RequestParams request) {
|
|
if (!SDK.getAppAPI().isActive(CoEConstant.APP_ID)) {
|
|
String msg = "该应用已暂停,登录被拒绝";
|
|
throw new AWSForbiddenException(msg);
|
|
}
|
|
|
|
// init extend params
|
|
Map<String, Object> params = new HashMap<String, Object>();
|
|
Map<String, String> webReq = request.asMap();
|
|
if (!webReq.containsKey("pwdEncode")) {
|
|
webReq.put("pwdEncode", "RSA");
|
|
}
|
|
for (String key : webReq.keySet()) {
|
|
if (key.equalsIgnoreCase("userid") || key.equalsIgnoreCase("pwd") || key.equalsIgnoreCase("sid") || key.equalsIgnoreCase("lang") || key.equalsIgnoreCase("deviceType") || key.equalsIgnoreCase("cmd")) {
|
|
//
|
|
} else {
|
|
params.put(key, webReq.get(key));
|
|
}
|
|
}
|
|
|
|
if (!Quota.isCoE()) {
|
|
SDK.getLogAPI().auditClient("COE登录", userid, "Login", "", "许可未授权该功能", clientIp, Level.ERROR);
|
|
throw new AWSQuotaException("许可未授权该功能");
|
|
}
|
|
|
|
UserWeb userWeb = new UserWeb();
|
|
ResponseObject ro;
|
|
if (!userWeb.validateIsAccessCOE(userid)) {
|
|
ro = ResponseObject.newErrResponse("未授权的登录请求,访问被拒绝");
|
|
SDK.getLogAPI().auditClient("COE登录", userid, "Login", "", "未授权的登录请求,访问被拒绝", clientIp, Level.ERROR);
|
|
return ro.toString();
|
|
} else {
|
|
ro = BPMClientPortalController.getInstance().validateIdentity(LoginConst.SYSTEM_COE, userid, pwd, lang, clientIp, "pc", false, params);
|
|
}
|
|
|
|
// 注释 by sunlh 使用平台返回的提示语
|
|
// if (!ro.isOk()) {
|
|
// int i = (Integer) ro.get("status");
|
|
// if (i == LoginConst.LOGIN_STATUS_ERR1 || i == LoginConst.LOGIN_STATUS_ERR6) {
|
|
// ro.msg("用户或密码错误");
|
|
// }
|
|
// }
|
|
|
|
ResponseObject r = ResponseObject.newOkResponse();
|
|
if (!ro.isOk()) {
|
|
r.err(ro.getMsg());
|
|
ro = r;
|
|
}
|
|
return ro.toString();
|
|
}
|
|
|
|
// @Mapping("COE_USER_HOME")
|
|
@Mapping("com.actionsoft.apps.coe.pal_user_home_page")
|
|
public String homeCoE(UserContext user, String bip, RequestParams request, String mainType) {
|
|
CoEPortalSkins skins = new CoEPortalSkins();
|
|
try {
|
|
return skins.getVueHomePage(user, mainType);
|
|
} catch (Exception e) {
|
|
return AlertWindow.getErrorMessagePage("发生错误", e.getMessage());
|
|
}
|
|
}
|
|
|
|
// @Mapping("COE_USER_LOGOUT")
|
|
@Mapping("com.actionsoft.apps.coe.pal_user_logout")
|
|
public String logoutClient(UserContext me) {
|
|
return new CoEPortalSkins().getLogoutPage(me);
|
|
}
|
|
|
|
/**
|
|
* 用户管理-查询PAL用户
|
|
* @param me
|
|
* @return
|
|
*/
|
|
@Mapping("com.actionsoft.apps.coe.pal_user_data_query")
|
|
public String queryCoePalUserData(UserContext me) {
|
|
UserWeb web = new UserWeb(me);
|
|
return web.queryCoePalUserData();
|
|
}
|
|
|
|
/**
|
|
* 用户管理-批量变更用户角色
|
|
* @param me
|
|
* @param userIds
|
|
* @return
|
|
*/
|
|
@Mapping("com.actionsoft.apps.coe.pal_user_role_change")
|
|
public String changeCoePalUserRole(UserContext me, String userIds) {
|
|
UserWeb web = new UserWeb(me);
|
|
return web.changeCoePalUserRole(userIds);
|
|
}
|
|
|
|
/**
|
|
* 用户管理-批量删除PAL用户
|
|
* @param me
|
|
* @param userIds
|
|
* @return
|
|
*/
|
|
@Mapping("com.actionsoft.apps.coe.pal_user_remove")
|
|
public String removeCoePalUser(UserContext me, String userIds) {
|
|
UserWeb web = new UserWeb(me);
|
|
return web.removeCoePalUser(userIds);
|
|
}
|
|
|
|
/**
|
|
* 用户管理-批量设置/保存PAL用户
|
|
* @param me
|
|
* @param managerUsers
|
|
* @param generalUsers
|
|
* @return
|
|
*/
|
|
@Mapping("com.actionsoft.apps.coe.pal_user_save")
|
|
public String saveCoePalUser(UserContext me, String managerUsers, String generalUsers) {
|
|
UserWeb web = new UserWeb(me);
|
|
return web.saveCoePalUser(managerUsers, generalUsers);
|
|
}
|
|
|
|
// 普通用户的组织管理
|
|
// @Mapping("COE_AVERAGE_USER_ORG")
|
|
@Mapping("com.actionsoft.apps.coe.pal_average_user_org")
|
|
public String CoEAverageUserOrg(UserContext me) {
|
|
// 检查是否有访问模块的权限
|
|
if (!PermAPIManager.getInstance().havingModelPermission(me.getUID(), "obj_2daac0a24d7d47cd933e580aa142c8bd")) {
|
|
CoEOpLogAPI.auditErrorOp(me, CoEOpLogConst.MODULE_CATEGORY_BPM_ORG, CoEOpLogConst.OP_ACCESS, CoEOpLogConst.INFO_BPM_ORG_ACCESS_DENIED);
|
|
throw new AWSForbiddenException("访问组织服务的权限不足,访问被拒绝");
|
|
}
|
|
// 提权
|
|
SessionModel session = SessionCache.getModel(me.getSessionId());
|
|
if(session==null) { //获取不到session时
|
|
//String s_sql = "SELECT * FROM SYS_SESSION WHERE SESSIONID = ?";
|
|
//RowMap s_map = DBSql.getMap(s_sql, new Object[] { me.getSessionId() });
|
|
} else {
|
|
session.setSessionScope(LoginConst.SYSTEM_ADMIN_CONSOLE);
|
|
}
|
|
ClusterAPI.sendClusterOp("type", NodeListener.TYPE_SID_SCOPE, "sid", me.getSessionId());
|
|
CoEOpLogAPI.auditOkOp(me, CoEOpLogConst.MODULE_CATEGORY_BPM_ORG, CoEOpLogConst.OP_ACCESS, CoEOpLogConst.INFO_BPM_ORG_ACCESS);
|
|
return new CompanyWeb(me).getOrganizationPortal(me);
|
|
}
|
|
|
|
// 获取组织人员数据
|
|
// @Mapping("COE_LANGUAGE_USER__GRID_GETPERSONJSON")
|
|
@Mapping("com.actionsoft.apps.coe.pal_languageuser_grid_person_data_query")
|
|
public String CoELanguageUserGridGetPersonJson(UserContext me, String opentype, String parentid, String parame) {
|
|
if (opentype == null) {
|
|
opentype = "";
|
|
}
|
|
if (parentid == null) {
|
|
parentid = "0";
|
|
}
|
|
if (parame == null) {
|
|
parame = "0";
|
|
}
|
|
UserWeb web = new UserWeb(me);
|
|
return web.getPersons(opentype, parentid, parame);
|
|
}
|
|
|
|
// @Mapping("COE_TEAM_BPA_DESIGN_STEP_RULE_ALLRULES")
|
|
@Mapping("com.actionsoft.apps.coe.pal_team_bpa_design_step_rule_all_rules")
|
|
public String CoETeamBPADesignStepRuleAllRules(UserContext me, String workFlowId, String workFlowStepId, String typeId) {
|
|
// WFFlexDesignStepRuleWeb web = new WFFlexDesignStepRuleWeb(me);
|
|
// if ("0".equals(typeId)) {
|
|
// ProjectWeb web2 = new ProjectWeb(me);
|
|
// return
|
|
// web2.getWFSystemRuleTreeDesignPage(Integer.parseInt(workFlowId),
|
|
// Integer.parseInt(workFlowStepId));
|
|
// } else {
|
|
// return web.getAllRules2JSON(Integer.parseInt(workFlowId),
|
|
// Integer.parseInt(workFlowStepId));
|
|
// }
|
|
return "未实现,请修改";
|
|
}
|
|
|
|
// 打开Step1页面
|
|
// @Mapping("COE_INSTALL_STEP1")
|
|
@Mapping("com.actionsoft.apps.coe.pal_install_step1_page")
|
|
public String CoEInstallSystemInitStep1(UserContext me, RequestParams params) {
|
|
CoEInitWeb initWeb = new CoEInitWeb(me);
|
|
int step = params.getInt("initStep", 0);
|
|
return initWeb.getStep1Html(step);
|
|
}
|
|
|
|
// 打开Step1页面
|
|
// @Mapping("COE_INSTALL_STEP2")
|
|
@Mapping("com.actionsoft.apps.coe.pal_install_step2_page")
|
|
public String CoEInstallSystemInitStep2(UserContext me) {
|
|
CoEInitWeb initWeb = new CoEInitWeb(me);
|
|
return initWeb.getStep2Html();
|
|
}
|
|
|
|
// 初始化Step1
|
|
// @Mapping("COE_INSTALL_SYSTEM_INIT_STEP1_START")
|
|
@Mapping("com.actionsoft.apps.coe.pal_install_system_init_step1_start")
|
|
public String CoEInstallSystemInitStep1Start(UserContext me) {
|
|
CoeSuitInstall c = new CoeSuitInstall();
|
|
c.sid = me.getUID();
|
|
new Thread(c).start();
|
|
return ResponseObject.newOkResponse("cmd:step1_start").toString();
|
|
}
|
|
|
|
// 获得初始化数据1
|
|
// @Mapping("COE_INSTALL_SYSTEM_INIT_GETINFO_STEP1")
|
|
@Mapping("com.actionsoft.apps.coe.pal_install_system_init_step1_info_query")
|
|
public String CoEInstallSystemInitGetInfoStep1(UserContext me) {
|
|
StringBuffer sb = new StringBuffer();
|
|
try {
|
|
ConcurrentLinkedQueue<String> linkedList = InitUtil.link1;
|
|
if (linkedList != null) {
|
|
int size = linkedList.size();
|
|
for (int i = 0; i < size; i++) {
|
|
sb.append(linkedList.remove());
|
|
}
|
|
}
|
|
} catch (Exception e) {
|
|
}
|
|
return sb.toString();
|
|
}
|
|
|
|
// 获得初始化BI维度表结构数据
|
|
// @Mapping("COE_INSTALL_SYSTEM_INIT_GETINFO_STEP3")
|
|
@Mapping("com.actionsoft.apps.coe.pal_install_system_init_step3_info_query")
|
|
public String CoEInstallSystemInitGetInfoStep3(UserContext me) {
|
|
StringBuffer sb = new StringBuffer();
|
|
try {
|
|
ConcurrentLinkedQueue<String> linkedList = InitUtil.link3;
|
|
if (linkedList != null) {
|
|
int size = linkedList.size();
|
|
for (int i = 0; i < size; i++) {
|
|
sb.append(linkedList.remove());
|
|
}
|
|
}
|
|
} catch (Exception e) {
|
|
}
|
|
return sb.toString();
|
|
}
|
|
|
|
// 获得CoEBI表结构
|
|
// @Mapping("COE_INSTALL_SYSTEM_INIT_GETCOEBI")
|
|
@Mapping("com.actionsoft.apps.coe.pal_install_system_init_coebi_query")
|
|
public String CoEInstallSystemInitgetCoEBI(UserContext me) {
|
|
// 初始化CCBI连接
|
|
InitUtil.installCCBI();
|
|
CoEInitWeb c = new CoEInitWeb(me);
|
|
return c.getCoE_structure_table();
|
|
}
|
|
|
|
// 获得最新的bi配置数据
|
|
// @Mapping("COE_INSTALL_SYSTEM_INIT_GETBIDATA")
|
|
@Mapping("com.actionsoft.apps.coe.pal_install_system_init_bi_data_query")
|
|
public String CoEInstallSystemInitgetBIData(UserContext me) {
|
|
CoEInitWeb c = new CoEInitWeb(me);
|
|
return c.getSys_cc_profileJson(CoePropertyUtil.getPropertyValue("CoeDBConnection"));
|
|
}
|
|
|
|
// COEBI连接配置保存操作
|
|
// @Mapping("COE_INSTALL_SYSTEM_INIT_BIDATAUPDATE")
|
|
@Mapping("com.actionsoft.apps.coe.pal_install_system_init_bi_data_update")
|
|
public String CoEInstallSystemInitBIDataUpdate(UserContext me, String uuid, String name, String logenable, String profile) {
|
|
CoEInitWeb c = new CoEInitWeb(me);
|
|
return c.updateBIData(uuid, name, logenable, profile);
|
|
}
|
|
|
|
// Step2 下一步操作
|
|
// @Mapping("COE_INSTALL_SYSTEM_INIT_STEP2_END")
|
|
@Mapping("com.actionsoft.apps.coe.pal_install_system_init_step2_end")
|
|
public String CoEInstallSystemInitStep2End(UserContext me) {
|
|
if (CoePropertyUtil.getPropertyValue("InitStep").equals("1")) {
|
|
CoePropertyUtil.createProperty("InitStep", "2");
|
|
}
|
|
return "";
|
|
}
|
|
|
|
// 进入初始化界面
|
|
// @Mapping("COE_INSTALL_TO_INITSYSTEM")
|
|
@Mapping("com.actionsoft.apps.coe.pal_install_to_init_system_page")
|
|
public String CoEInstallToInitSystem(UserContext me) {
|
|
NavigationWeb web = new NavigationWeb(me);
|
|
if (me.getUID().equals("admin")) {
|
|
return web.getInitHtml(CoePropertyUtil.getPropertyValue("InitStep"));
|
|
} else {
|
|
return web.getInitAlertHtml("<I18N#对不起,您不是管理员!>");
|
|
}
|
|
}
|
|
|
|
// 检察服务器是否正在执行job
|
|
// @Mapping("COE_CHECK_EXCUTEJOB")
|
|
@Mapping("com.actionsoft.apps.coe.pal_excutejob_check")
|
|
public String CoECheckExcuteJob(UserContext me) {
|
|
return CoePropertyUtil.getPropertyValue("excuteJob");
|
|
}
|
|
|
|
// ====================升级功能开始=======================
|
|
// @Mapping("COE_ADMIN_CHECK_PLATFORM_VERSION")
|
|
@Mapping("com.actionsoft.apps.coe.pal_admin_platform_version_check")
|
|
public String checkPlatformVersion(UserContext me, Boolean isPreviewPatch) {
|
|
return new SystemController().checkPlatformVersion(me, isPreviewPatch);
|
|
}
|
|
|
|
// @Mapping("COE_ADMIN_DOWNLOAD_PLATFORM_VERSION")
|
|
@Mapping("com.actionsoft.apps.coe.pal_admin_platform_version_download")
|
|
public String downloadPlatformVersion(UserContext me, String versionid, String filesize, String url, String md5digest, String isdegrade, String releasetype) {
|
|
return new SystemController().downloadPlatformVersion(me, versionid, filesize, url, md5digest, isdegrade, releasetype);
|
|
}
|
|
|
|
// @Mapping("COE_ADMIN_CANCEL_DOWNLOAD_PLATFORM_VERSION")
|
|
@Mapping("com.actionsoft.apps.coe.pal_admin_platform_version_cancel")
|
|
public String cancelDownloadPlatformVersion(UserContext me, String versionid) {
|
|
return new SystemController().cancelDownloadPlatformVersion(me, versionid);
|
|
}
|
|
|
|
// @Mapping("COE_ADMIN_CHANGE_UPGRADE_STATE")
|
|
@Mapping("com.actionsoft.apps.coe.pal_admin_upgrade_sataus_change")
|
|
public String installUpgradeState(UserContext me, String op, String plandate, String state, String versionid) {
|
|
return new SystemController().installUpgradeState(me, op, plandate, state, versionid);
|
|
}
|
|
// ====================升级功能结束=======================
|
|
|
|
/**
|
|
* html中的table导出excel的公共方法
|
|
* @param me
|
|
* @param titles table的表头内容
|
|
* @param content table中的内容
|
|
* @param appId
|
|
* @return
|
|
* @author zhangming
|
|
*/
|
|
// @Mapping("COE_TABLE_EXPORT_EXCEL")
|
|
@Mapping("com.actionsoft.apps.coe.pal_table_excel_export")
|
|
public String exportExcel(UserContext me, String titles, String content, String appId) {
|
|
return Table2Excel.exportExcel(me, titles, content, appId);
|
|
}
|
|
|
|
/**
|
|
* 搜索用户
|
|
* @param me
|
|
* @param name
|
|
* @return
|
|
*/
|
|
// @Mapping("COE_TEAM_USER_SEARCH")
|
|
@Mapping("com.actionsoft.apps.coe.pal_teamuser_search")
|
|
public String searchUser(UserContext me, String name) {
|
|
UserWeb web = new UserWeb(me);
|
|
return web.searchUser(name);
|
|
}
|
|
|
|
/**
|
|
* 查询导航栏初始化数据
|
|
* vue
|
|
*/
|
|
@Mapping("com.actionsoft.apps.coe.pal_nav_header_data")
|
|
public String getPalNavHeaderData(UserContext uc, String mainType){
|
|
NavigationWeb web = new NavigationWeb(uc);
|
|
return web.getPalNavHeaderData(mainType);
|
|
}
|
|
|
|
/**
|
|
* 获取用户相关权限
|
|
* @param uc
|
|
* @param wsId
|
|
* @param teamId
|
|
* @return
|
|
*/
|
|
@Mapping("com.actionsoft.apps.coe.pal_user_perm_query")
|
|
public String getUserPerm(UserContext uc, String wsId, String teamId) {
|
|
NavigationWeb web = new NavigationWeb(uc);
|
|
return web.getUserPerm(wsId, teamId);
|
|
}
|
|
|
|
/**
|
|
* 记录各模块的访问日志
|
|
* @param me
|
|
* @param moduleCategory
|
|
* @return
|
|
*/
|
|
@Mapping("com.actionsoft.apps.coe.pal_access_log_save")
|
|
public String saveAccessLog(UserContext me, String moduleCategory) {
|
|
NavigationWeb web = new NavigationWeb(me);
|
|
return web.saveAccessLog(moduleCategory);
|
|
}
|
|
|
|
@Mapping("com.actionsoft.apps.coe.pal_search_org_tree_node")
|
|
public String searchOrgInfo(UserContext me,String orgName){
|
|
BPMOrgTreeWeb treeWeb = new BPMOrgTreeWeb(me);
|
|
return treeWeb.searchOrgIdByName(orgName);
|
|
}
|
|
|
|
@Mapping("com.actionsoft.apps.coe.pal_search_org_tree_parent_node")
|
|
public String searchParentOrgId(UserContext me,String orgId){
|
|
BPMOrgTreeWeb treeWeb = new BPMOrgTreeWeb(me);
|
|
return treeWeb.searchParentOrgId(orgId);
|
|
}
|
|
|
|
|
|
@Mapping("com.actionsoft.apps.coe.pal_search_user_tree_node")
|
|
public String searchUserInfo(UserContext me,String userName){
|
|
BPMOrgTreeWeb treeWeb = new BPMOrgTreeWeb(me);
|
|
return treeWeb.searchUserIdByName(userName);
|
|
}
|
|
|
|
@Mapping("com.actionsoft.apps.coe.pal_search_user_tree_parent_node")
|
|
public String searchParentUserId(UserContext me,String userid){
|
|
BPMOrgTreeWeb treeWeb = new BPMOrgTreeWeb(me);
|
|
return treeWeb.searchParentUserId(userid);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|