From 5ac561a33814489c47e7c41492b7d65b6ec295f7 Mon Sep 17 00:00:00 2001 From: "[denghongtao]" <[denghongtao@easycorp.ltd]> Date: Mon, 14 Mar 2022 09:17:47 +0800 Subject: [PATCH] Update old test --- test/class/product.class.php | 215 +++++++++++++++ test/class/program.class.php | 432 ++++++++++++++++++++++++++++++ test/class/project.class.php | 493 +++++++++++++++++++++++++++++++++++ 3 files changed, 1140 insertions(+) create mode 100644 test/class/product.class.php create mode 100644 test/class/program.class.php create mode 100644 test/class/project.class.php diff --git a/test/class/product.class.php b/test/class/product.class.php new file mode 100644 index 0000000000..d530549d00 --- /dev/null +++ b/test/class/product.class.php @@ -0,0 +1,215 @@ +product = $tester->loadModel('product'); + } + + public function createObject($param = array()) + { + global $createFields; + $whitelist = array(); + $createFields = array('program' => 1, 'line' => 0, 'lineName' => '', 'newLine' => 0, 'name' => '', 'code' => '', 'PO' => 'admin', 'QD' => '', 'RD' => '', + 'reviewer' => '', 'type' => 'normal', 'status' => 'normal', 'desc' => '', 'acl' => 'open', 'uid' => ''); + foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue; + foreach($param as $key => $value) $_POST[$key] = $value; + + //global $tester; + //$objectModel = $tester->loadModel($module); + //$objectID = $this->objectModel->create(); + $objectID = $this->product->create(); + unset($_POST); + + if(dao::isError()) + { + return dao::getError(); + } + else + { + $object = $this->product->getByID($objectID); + return $object; + } + } + + public function testGetLatestProject($productID) + { + $project = $this->product->getLatestProject($productID); + if($project == false) return '没有数据'; + return $project; + } + + public function getAllProducts($programID) + { + return $this->product->getList($programID); + } + + public function getAllProductsCount($programID) + { + return count($this->getAllProducts($programID)); + } + + public function getNoclosedProducts($programID) + { + return $this->product->getList($programID, 'noclosed'); + } + + public function getNoclosedProductsCount($programID) + { + return count($this->getNoclosedProducts($programID)); + } + + public function getClosedProducts($programID) + { + return $this->product->getList($programID, 'closed'); + } + + public function getClosedProductsCount($programID) + { + return count($this->getClosedProducts($programID)); + } + + public function getInvolvedProducts($programID) + { + return $this->product->getList($programID, 'involved'); + } + + public function getInvolvedProductsCount($programID) + { + return count($this->getInvolvedProducts($programID)); + } + + public function getProductsByLine($programID, $line = 0) + { + return $this->product->getList($programID, 'all', 0, $line); + } + + public function countProductsByLine($programID, $line = 0) + { + return count($this->getProductsByLine($programID, $line)); + } + + public function getProductList($programID, $status = 'all', $line = 0) + { + return $this->product->getList($programID, $status, 0, $line); + } + + public function getProductCount($programID, $status = 'all', $line = 0) + { + return count($this->getProductList($programID, $status, $line)); + } + public function getProductPairs($programID) + { + $pairs = $this->product->getPairs('', $programID); + if($pairs == array()) return '没有数据'; + return $pairs; + } + public function getProductPairsCount($programID) + { + $pairsCount = count($this->getProductPairs($programID)); + if($pairsCount == '没有数据') return '0'; + return $pairsCount; + } + + public function getAllPairs($programID) + { + $pairs = $this->product->getPairs('all', $programID); + if($pairs == array()) return '没有数据'; + return $pairs; + } + public function getAllPairsCount($programID) + { + $pairsCount = count($this->getAllPairs($programID)); + if($pairsCount == '没有数据') return '0'; + return $pairsCount; + } + public function getNoclosedPairs($programID) + { + $pairs = $this->product->getPairs('noclosed', $programID); + if($pairs == array()) return '没有数据'; + return $pairs; + } + public function getNoclosedPairsCount($programID) + { + $pairsCount = count($this->getNoclosedPairs($programID)); + if($pairsCount == '没有数据') return '0'; + return $pairsCount; + } + + public function getProductPairsByOrder($programID, $orderBy = 'id_desc', $mode = '') + { + $this->product->orderBy = $orderBy; + $pairs = $this->product->getPairs($mode, $programID); + return checkOrder($pairs, $orderBy); + } + + public function getAllProjectsByProduct($productID) + { + $projects = $this->product->getProjectListByProduct($productID, 'all'); + if($projects == array()) return '没有数据'; + return $projects; + } + + public function getProjectsByStatus($productID, $status) + { + $projects = $this->product->getProjectListByProduct($productID, $browseType); + if($projects == array()) return '没有数据'; + return $projects; + } + + public function getProjectPairsByProductID($productID) + { + $projects = $this->product->getProjectPairsByProduct($productID, 0, 0); + if($projects == array()) return '没有数据'; + return $projects; + } + + public function getAppendProject($projectID) + { + $project = $this->product->getProjectPairsByProduct(10086, 0, $projectID); + if($project == array()) return '没有数据'; + return $project; + } + + public function testIsClickable($productID, $status) + { + $product = $this->product->getById($productID); + $isClick = $this->product->isClickable($product, $status); + return $isClick == false ? 'false' : 'true'; + } + + public function updateObject($module, $objectID, $param = array()) + { + global $tester; + $objectModel = $tester->loadModel($module); + + $object = $objectModel->getById($objectID); + foreach($object as $field => $value) + { + if(in_array($field, array_keys($param))) + { + $_POST[$field] = $param[$field]; + } + else + { + $_POST[$field] = $value; + } + } + + $change = $objectModel->update($objectID); + if($change == array()) $change = '没有数据更新'; + unset($_POST); + + if(dao::isError()) + { + return dao::getError(); + } + else + { + return $change; + } + } +} diff --git a/test/class/program.class.php b/test/class/program.class.php new file mode 100644 index 0000000000..4ad230b59a --- /dev/null +++ b/test/class/program.class.php @@ -0,0 +1,432 @@ +program = $tester->loadModel('program'); + } + + function create($data) + { + global $app; + + $_POST = ''; + $_POST = $data; + + $programID = $this->program->create(); + + if(dao::isError()) return array('message' => dao::getError()); + + $program = $this->program->getById($programID); + + $app->dbh->query("DELETE FROM ". TABLE_PROGRAM ." where name = '" . $data['name']. "'"); + return $program; + } + function createData($status) + { + $data = array( + 'parent' => 0, + 'name' => '测试新增项目集一', + 'budget' => '', + 'budgetUnit' => 'CNY', + 'begin' => '2022-01-12', + 'end' => '2022-02-12', + 'desc' => '测试项目集描述', + 'acl' => 'private', + 'whitelist' => '' + ); + + switch($status) + { + case '1': // 创建新项目集 + break; + case '2': // 项目集名称为空时 + $data['name'] = ''; + break; + case '3': // 项目集的开始时间为空 + $data['begin'] = ''; + break; + case '4': // 项目集的完成时间为空 + $data['end'] = ''; + break; + case '5': // 项目集的计划完成时间大于计划开始时间 + $data['end'] = '2022-01-10'; + break; + case '6': // 项目集的完成日期大于父项目集的完成日期 + $data['parent'] = '1'; + $data['begin'] = '2018-01-01'; + $data['end'] = '2022-02-10'; + break; + default: + } + return $this->create($data); + } + + public function createStakeholder($programID) + { + $_POST['accounts'] = array('dev1', 'dev2'); + $stakeHolder = $this->program->createStakeholder($programID); + + return $this->program->getStakeholdersByPrograms($programID); + } + + public function getBudgetLeft($programID) + { + $program = $this->program->getById(1); + + return $this->program->getBudgetLeft($program); + } + + public function getBudgetUnitList() + { + global $app; + $app->loadConfig('project'); + $app->loadLang('project'); + + return $this->program->getBudgetUnitList(); + } + + public function getById($programID) + { + if(empty($this->program->getById($programID))) + { + return array('code' => 'fail', 'message' => 'Not Found'); + } + else + { + return $this->program->getById($programID); + } + } + + public function getChildren($programID) + { + $programInfo = $this->program->getChildren($programID); + if(empty($programInfo)) + { + return array('code' => 'fail' , 'message' => 'Not Found'); + } + else + { + return $programInfo; + } + } + + public function getInvolvedPrograms($account) + { + return $this->program->getInvolvedPrograms($account); + } + + public function getPairsByList($programIDList = '') + { + if(empty($this->program->getPairsByList($programIDList))) + { + return array('code' => 'fail', 'message' => 'Not Found'); + } + else + { + return $this->program->getPairsByList($programIDList); + } + } + + public function getPairs() + { + $programs = $this->program->getPairs(); + if(!$programs) return 0; + return $programs; + } + + public function getCount() + { + return count($this->program->getPairs()); + } + + public function getParentPairs() + { + return $this->program->getParentPairs(); + } + + public function getCount1() + { + return count($this->program->getParentPairs()); + } + + public function getParentPM($programIdList) + { + return $this->program->getParentPM($programIdList); + } + + public function getProductPairsByID($programID = 0) + { + $program = $this->program->getByID($programID); + if(empty($program)) return array('message' => 'Not Found'); + return $this->program->getProductPairs($programID, 'assign', 'all'); + } + + public function getProductPairsByMod($mode = 'assign') + { + return $this->program->getProductPairs(1, $mode, 'noclosed'); + } + + public function getProductPairsByStatus($status = 'all') + { + return $this->program->getProductPairs(1, 'assign', $status); + } + + public function getCount2($programID = 0, $mode = 'assign', $status = 'all') + { + return count($this->program->getProductPairs($programID, $mode, $status)); + } + + public function getProgressList() + { + return $this->program->getProgressList(); + } + + public function getCount3() + { + return count($this->program->getProgressList()); + } + + public function getStatsByProgramID($programID = 0) + { + return count($this->program->getProjectStats($programID)); + } + + public function getStatsByStatus($browseType = 'all') + { + $projects = $this->program->getProjectStats('0', $browseType); + + if(!$projects) return 0; + foreach($projects as $project) + { + if($project->status != $browseType and $browseType != 'all' and $browseType != 'undone') return 0; + if($browseType == 'undone' and ($project->status != ('wait' or 'doing'))) return 0; + } + + return count($projects); + } + + public function getStatsByOrder($orderBy = 'id_desc') + { + $projects = $this->program->getProjectStats('0', 'all', '0', $orderBy); + + return checkOrder($projects, $orderBy); + } + + public function getStatsAddProgramTitle($programTitle = 0) + { + return $this->program->getProjectStats('0', 'all', '0', 'id_desc', '', $programTitle); + } + + public function getStatsByInvolved($involved = 0, $count = '') + { + $projects = $this->program->getProjectStats('0', 'all', '0', 'id_desc', '', '0', $involved); + + if($count == 'count') return count($projects); + return $projects; + } + + public function getByPrograms($programIdList = 0) + { + $stakeHolders = $this->program->getStakeholdersByPrograms($programIdList); + + return $stakeHolders; + } + + public function getCount4($programIdList = 0) + { + $stakeHolders = $this->program->getStakeholdersByPrograms($programIdList); + + return count($stakeHolders); + } + + public function getByID1($programID = 0) + { + $stakeholders = $this->program->getStakeholders($programID); + + return $stakeholders; + } + + public function getByOrder($orderBy = 'id_desc') + { + $stakeholders = $this->program->getStakeholders(2, $orderBy); + + return checkOrder($stakeholders, $orderBy); + } + + public function getCount5($programID = 0) + { + $stakeholders = $this->program->getStakeholders($programID); + + return count($stakeholders); + } + + public function getById2($programID) + { + if(empty($this->program->getTeamMemberPairs($programID))) + { + return array('code' => 'fail', 'message' => 'Not Found'); + } + else + { + return $this->program->getTeamMemberPairs($programID); + } + } + + public function getCount6($programID) + { + return count($this->program->getTeamMemberPairs($programID)); + } + + public function getById3($programID = 0) + { + if(empty($this->program->getTopById($programID))) + { + return array('code' => 'fail', 'message' => 'Not Found'); + } + else + { + return $this->program->getByTopId($programID); + } + } + + public function getTopPairs($count = '') + { + if($count == 'count') return count($this->program->getTopPairs()); + return $this->program->getTopPairs(); + } + + public function getUnfinished($programID) + { + $program = $this->program->getById($programID); + + return $this->program->hasUnfinished($program); + } + + public function getKanbanGroup($type = ''){ + $program = $this->program->getKanbanGroup(); + return $program; + } + + public function getListByStatus($status) + { + $this->program->cookie->showClosed = 'ture'; + $programs = $this->program->getList($status); + if(!$programs) return 0; + foreach($programs as $program) + { + if($program->status != $status and $status != 'all') return 0; + } + return count($programs); + } + + public function getListByOrder($orderBy) + { + $programs = $this->program->getList('all', $orderBy); + return checkOrder($programs, $orderBy); + } + + public function getListByProgramID($programID = 0) + { + return count($this->program->getProjectList($programID)); + } + + public function getListByStatusNo($browseType = 'all') + { + $projects = $this->program->getProjectList('0', $browseType); + + if(!$projects) return 0; + foreach($projects as $project) + { + if($project->status != $browseType and $browseType != 'all' and $browseType != 'undone') return 0; + if($browseType == 'undone' and ($project->status != ('wait' or 'doing'))) return 0; + } + + return count($projects); + } + + public function getListByOrderId($orderBy = 'id_desc') + { + $projects = $this->program->getProjectList('0', 'all', '0', $orderBy); + + return checkOrder($projects, $orderBy); + } + + public function getListAddProgramTitle($programTitle = 0) + { + return $this->program->getProjectList('0', 'all', '0', 'id_desc', '', $programTitle); + } + + public function getListByInvolved($involved = 0, $count = '') + { + $projects = $this->program->getProjectList('0', 'all', '0', 'id_desc', '', '0', $involved); + + if($count == 'count') return count($projects); + return $projects; + } + + public function setTreePath($programID) + { + $programPath = $this->program->setTreePath($programID); + if($programPath) + { + return $this->program->getById($programID); + } + else + { + return 0; + } + } + + public function update($programID, $data) + { + global $app; + + $_POST = $data; + $result = $this->program->update(10); + if(dao::isError()) return array('message' => dao::getError()); + + $app->dbh->query("UPDATE " . TABLE_PROGRAM . " SET name = '" . $result[0]['old']. "' where id = '" . $programID . "'"); + return $result; + } + + public function updateProgram($programID, $status = 0) + { + $data = array( + 'parent' => '0', + 'name' => '测试更新项目集十', + 'begin' => '2020-10-10', + 'end' => '2020-10-11', + 'acl' => 'private', + 'budget' => '100', + 'budgetUnit' => 'CNY', + 'whitelist' => array('dev10', 'dev12') + ); + + switch($status) + { + case '1': // 项目集名称已经存在时 + $data['name'] = '项目集1'; + break; + case '2': // 当计划开始为空时更新项目集信息 + $data['begin'] = ''; + break; + case '3': // 当计划完成为空时更新项目集信息 + $data['end'] = ''; + break; + case '4': // 当计划完成小于计划开始时 + $data['end'] = '2020-01-01'; + break; + case '5': // 项目集开始时间小于父项目集时 + $data['parent'] = '9'; + $data['begin'] = '2019-01-01'; + break; + default: // 更新id为10的项目集信息 + } + return $this->update($programID, $data); + } +} +?> diff --git a/test/class/project.class.php b/test/class/project.class.php new file mode 100644 index 0000000000..be3d90cb2c --- /dev/null +++ b/test/class/project.class.php @@ -0,0 +1,493 @@ +project = $tester->loadModel('project'); + } + + /** + * * Check project status after activate a project.▫ + * *▫ + * * @param int $projectID▫ + * * @access public + * * @return bool + * */ + public function checkStatus($projectID) + { + $oldProject = $this->project->getById($projectID); + if($oldProject->status != 'closed') return false; + + $change = $this->project->activate($projectID); + + $project = $this->project->getById($projectID); + if($project->status != 'doing') return false; + + return true; + } + + public function checkHasChildren($projectID) + { + return $this->project->checkHasChildren($projectID); + } + + /** + * Check project status after close a project. + * + * @param int $projectID + * @access public + * @return bool + */ + public function checkStatusOff($projectID, $closeTime = array()) + { + $checkStatus = array(); + $closeEnd = array('realEnd' => ''); + foreach($closeEnd as $filed => $defaultValue) $_POST[$filed] = $defaultValue; + foreach($closeTime as $key => $value) $_POST[$key] = $value; + + $oldProject = $this->project->getById($projectID); + if($oldProject->status == 'suspended' or $oldProject->status == 'closed') return false; + + $change = $this->project->close($projectID); + + $project = $this->project->getById($projectID); + if($project->status != 'closed') return false; + + return true; + } + + /** + * Check budget unit list. + * + * @param string $checkList▫ + * @access public + * @return bool + */ + public function checkBudgetUnitList($checkList = array('CNY' => '人民币', 'USD' => '美元')) + { + $budgetList = $this->project->getBudgetUnitList(); + foreach($budgetList as $enBudget => $zhBudget) + { + if($checkList[$enBudget] != $zhBudget) return false; + } + return true; + } + + /** + * * Check projectList get from getByIdList. + * * + * * @param array $projectIdList + * * @param int $count + * * @access public + * * @return array + * */ + public function getByIdList($projectIdList, $count) + { + $projectList = $this->project->getByIdList($projectIdList); + if(count($projectList) != $count) return false; + return $projectList; + } + + /** + * * Get project by ID. + * * + * * @param int $projectID + * * @access public + * * @return object + * */ + public function getProjectByID($projectID) + { + return $this->project->getByID($projectID); + } + + /** + * * Get program by ID. + * * + * * @param int $programID + * * @access public + * * @return object + * */ + public function getProgramByID($programID) + { + return $this->project->getByID($programID, 'program'); + } + + /** + * * Get sprint by ID. + * * + * * @param int $sprintID + * * @access public + * * @return object + * */ + + public function getSprintByID($sprintID) + { + return $this->project->getByID($sprintID, 'sprint'); + } + + /** + * * Get stage by ID. + * * + * * @param int $stageID + * * @access public + * * @return object + * */ + public function getStageByID($stageID) + { + return $this->project->getByID($stageID, 'stage'); + } + + /** + * * Get Kanban by ID, + * * + * * @param int $kanbanID + * * @access public + * * @return void + * */ + public function getKanbanByID($kanbanID) + { + return $this->project->getByID($kanbanID, 'kanban'); + } + + /** + * * Get project by status. + * * + * * @param string $status + * * @access public + * * @return int + * */ + public function getBystatus($status) + { + $projects = $this->project->getOverviewList('byStatus', $status); + if(!$projects) + { + $result = array(); + $result['code'] = 'fail'; + $result['message'] = 'No data.'; + + return $result; + } + + if($status == 'undone') $status = 'wait,doing,suspended'; + + foreach($projects as $project) + { + if(strpos(",$status,", $project->status) === false) + { + $result = array(); + $result['code'] = 'fail'; + $result['message'] = 'Error data.'; + + return $result; + } + } + + return count($projects); + } + + /** + * * Get project list by order. + * * + * * @param string $orderBy + * * @access public + * * @return void + * */ + public function getListByOrder($orderBy) + { + $projects = $this->project->getOverviewList('byStatus', 'wait', $orderBy); + return checkOrder($projects, $orderBy); + } + + /** + * * Get project by ID. + * * + * * @param int $projectID + * * @access public + * * @return void + * */ + public function getByID($projectID) + { + return $this->project->getOverviewList('byID', $projectID); + } + + /** + * * Get project pairs by ID list. + * * + * * @param array $IDList + * * @access public + * * @return int + * */ + public function getByIdListFind($IDList) + { + $projects = $this->project->getPairsByIdList($IDList); + if(empty($projects)) + { + $result = array(); + $result['code'] = 'fail'; + $result['message'] = 'No data.'; + + return $result; + } + + foreach($projects as $projectID => $projectName) + { + if(!empty($IDList) and !in_array($projectID, $IDList)) + { + $result = array(); + $result['code'] = 'fail'; + $result['message'] = 'Error Data.'; + + return $result; + } + } + + return count($projects); + } + + /** + * * Get parentName. + * *▫ + * * @param int $projectID▫ + * * @access public + * * @return array + * */ + public function getParentName($projectID) + { + $program = $this->project->getParentName($projectID); + if(empty($program)) return false; + return $program; + } + + /** + * * Get team member pairs.▫ + * *▫ + * * @param int $projectID▫ + * * @access public + * * @return int + * */ + public function getTeamMemberPairs($projectID) + { + $members = array_filter($this->project->getTeamMemberPairs($projectID)); + if(empty($members)) return false; + return count($members); + } + + /** + * /** + * * Check members.▫ + * *▫ + * * @param array $members▫ + * * @param array $users▫ + * * @access public + * * @return bool + * */ + public function checkMembers($members, $users) + { + foreach($users as $user) + { + if(!isset($members[$user])) return false; + } + return true; + } + + /** + * Get team memberm. + *▫ + * @param int $projectID▫ + * @param array $users▫ + * @param bool $tutorial▫ + * @access public + * @return int + */ + public function getTeamMembers($projectID, $users, $tutorial = false) + { + if($tutorial) define('TUTORIAL', true); + $members = $this->project->getTeamMembers($projectID); + if(empty($members)) return false; + if(!empty($users)) $this->checkMembers($members, $users); + return count($members); + } + + /* + * Check project status after start a project. + *▫ + * @param int $projectID▫ + * @access public + * @return bool + */ + public function checkStatusBegin($projectID) + { + $oldProject = $this->project->getById($projectID); + if($oldProject->status != 'suspended' and $oldProject->status != 'wait') return false; + + $change = $this->project->start($projectID); + $project = $this->project->getById($projectID); + if($project->status != 'doing') return false; + + return true; + } + + /* + * Check project status after suspend a project. + * + * @param int $projectID▫ + * @access public + * @return bool + */ + public function checkStatusStop($projectID) + { + $oldProject = $this->project->getById($projectID); + if($oldProject->status == 'suspended' or $oldProject->status == 'closed') return false; + + $change = $this->project->suspend($projectID); + $project = $this->project->getById($projectID); + if($project->status != 'suspended') return false; + + return true; + } + + public function getExecutionData($projectID, $type = '') + { + $table = 'zt_project'; + $executions = $this->project->getDataByProject($table, $projectID, $type); + if(empty($executions)) return false; + return $executions; + } + + /** + * * Get builds from getDataByProject. + * * + * * @param int $projectID + * * @access public + * * @return array + * */ + public function getBuildData($projectID) + { + $builds = $this->project->getDataByProject(TABLE_BUILD, $projectID); + if(empty($builds)) return false; + return $builds; + } + + /** + * * Get releases from getDataByProject. + * * + * * @param int $projectID + * * @access public + * * @return array + * */ + public function getReleaseData($projectID) + { + $releases = $this->project->getDataByProject(TABLE_RELEASE, $projectID); + if(empty($releases)) return false; + return $releases; + } + + public function getByProgram($programID) + { + $projects = $this->project->getPairsByProgram($programID); + if(empty($projects)) + { + $result = array(); + $result['code'] = 'fail'; + $result['message'] = 'No data.'; + + return $result; + } + + return count($projects); + } + + /** + * Get project pairs by status. + * + * @param string $status + * @access public + * @return int + */ + + public function getByStatusPairs($status) + { + $projects = $this->project->getPairsByProgram(2, $status); + if(empty($projects)) + { + $result = array(); + $result['code'] = 'fail'; + $result['message'] = 'No data.'; + + return $result; + } + + return count($projects); + } + + /** + * Get project list by order. + * + * @param string $orderBy + * @access public + * @return int + */ + + public function getConsumed($projectIdList) + { + $projects = $this->project->getProjectsConsumed($projectIdList, $time = ''); + return $projects; + } + + public function getByStatusExe($status) + { + $executions = $this->project->getStats(0, $status); + if(empty($executions)) return false; + if($status != 'all') + { + foreach($executions as $execution) + { + if($execution->status != $status) return false; + } + } + return count($executions); + } + + /* + * Get executions by project. + * + * @param int $projectID + * @access public + * @return int + */ + public function getByProject($projectID) + { + $executions = $this->project->getStats($projectID, 'all'); + if(empty($executions)) return false; + foreach($executions as $execution) + { + if($execution->project != $projectID) return false; + } + return count($executions); + } + + /* + * Get executions by order. + * + * @param string $orderBy + + * @access public + * @return bool + */ + + public function getTotalBugBy($projectIdList, $status) + { + $projects = $this->project->getTotalBugByProject($projectIdList, $status); + return $projects; + } + + public function getWorkHour($projectID) + { + $projects = $this->project->getWorkhour($projectID); + } + +} +?>