Authored by xuqi

Merge branch 'develop' of http://git.dev.yoho.cn/web/yohobuy into develop

@@ -30,7 +30,7 @@ @@ -30,7 +30,7 @@
30 </span> 30 </span>
31 </li> 31 </li>
32 <li class="input-container-li clearfix"> 32 <li class="input-container-li clearfix">
33 - <input type="hidden" name="code" value="159bI6arxsuaPBxG2iV9OE9BrgDnAPiTecUqYh2iUC3ntt6S0eOtxXpVu+jWIlveXx9NRuwS9zdrXzcUyOd+d3ikzYBAo0k"> 33 + <input type="hidden" name="code" value="{{code}}">
34 <input id="reset-pwd-btn" class="btn reset-pwd-btn" type="submit" value="提交" disabled=""> 34 <input id="reset-pwd-btn" class="btn reset-pwd-btn" type="submit" value="提交" disabled="">
35 </li> 35 </li>
36 </ul> 36 </ul>
1 -{{> layout/simple-header}}  
2 -<div class="verification-page back-page passport-page yoho-page clearfix">  
3 -{{# verification}}  
4 - {{> passport/cover}}  
5 - <div class="content">  
6 - <form id="verification-form" class="verification-form" method="POST" action="/passport/back/backmobile">  
7 - <ul>  
8 - <li class="head-title">验证身份</li>  
9 - <li class="po-re">  
10 - <label class="pn-label">手机号码</label>  
11 - <span class="country-code">+{{area}}</span>  
12 - <span class="phone-num">{{phoneNum}}</span>  
13 - </li>  
14 - <li class="po-re">  
15 - <input id="captcha" class="input va captcha" type="text" name="captcha">  
16 - <input id="send-captcha" class="btn send-captcha" type="button" value="发送验证码" disabled="">  
17 - <div id="captcha-tip" class="captcha-tips"><i class="iconfont">&#xe61f;</i>验证码已发送至您的手机,请查收</div>  
18 - <span id="err-tip" class="err-tip hide">  
19 - <i></i>  
20 - <em>请输入验证码</em>  
21 - </span>  
22 - </li>  
23 - <li>  
24 - <input name="area" id="area" type="hidden" value="{{area}}">  
25 - <input name="mobile" id="mobile" type="hidden" value="{{phoneNum}}">  
26 - <input name="captchaPic" id="captchaPic" type="hidden" value="g7ce">  
27 - <input name="refer" id="refer" type="hidden" value="">  
28 - <input id="next-step" class="btn next-step disable" type="submit" value="下一步" disabled="">  
29 - </li>  
30 - </ul>  
31 - </form>  
32 - </div>  
33 -{{/ verification}}  
34 -</div> 1 +{{> layout/simple-header}}
  2 +<div class="verification-page back-page passport-page yoho-page clearfix">
  3 +{{# verification}}
  4 + {{> passport/cover}}
  5 + <div class="content">
  6 + <form id="verification-form" class="verification-form" method="POST" action="/passport/back/backmobile">
  7 + <ul>
  8 + <li class="head-title">验证身份</li>
  9 + <li class="po-re">
  10 + <label class="pn-label">手机号码</label>
  11 + <span class="country-code">+{{area}}</span>
  12 + <span class="phone-num">{{phoneNum}}</span>
  13 + </li>
  14 + <li class="po-re">
  15 + <input id="captcha" class="input va captcha" type="text" name="captcha">
  16 + <input id="send-captcha" class="btn send-captcha" type="button" value="发送验证码" disabled="">
  17 + <div id="captcha-tip" class="captcha-tips"><i class="iconfont">&#xe61f;</i>验证码已发送至您的手机,请查收</div>
  18 + <span id="err-tip" class="err-tip hide">
  19 + <i></i>
  20 + <em>请输入验证码</em>
  21 + </span>
  22 + </li>
  23 + <li>
  24 + <input name="area" id="area" type="hidden" value="{{area}}">
  25 + <input name="mobile" id="mobile" type="hidden" value="{{phoneNum}}">
  26 + <input name="captchaPic" id="captchaPic" type="hidden" value="{{captcha}}">
  27 + <input name="refer" id="refer" type="hidden" value="">
  28 + <input id="next-step" class="btn next-step disable" type="submit" value="下一步" disabled="">
  29 + </li>
  30 + </ul>
  31 + </form>
  32 + </div>
  33 +{{/ verification}}
  34 +</div>
35 {{> layout/footer}} 35 {{> layout/footer}}
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 <li class="clearfix"> 4 <li class="clearfix">
5 <select id="region" class="region" name="region"> 5 <select id="region" class="region" name="region">
6 {{#each region}} 6 {{#each region}}
7 - <option {{#if selected}}selected="selected"{{/if}} value="{{id}}">{{name}}</option> 7 + <option {{#if selected}}selected="selected"{{/if}} value="{{areaCode}}">{{name}}</option>
8 {{/each}} 8 {{/each}}
9 </select> 9 </select>
10 </li> 10 </li>
@@ -73,7 +73,7 @@ class Bootstrap extends Bootstrap_Abstract @@ -73,7 +73,7 @@ class Bootstrap extends Bootstrap_Abstract
73 $action = 'Index'; 73 $action = 'Index';
74 74
75 // 二级域名 75 // 二级域名
76 - if (3 === $level) { 76 + if (2 === $level) {
77 $subDomain = strval($hostParts[0]); 77 $subDomain = strval($hostParts[0]);
78 switch (strtolower($subDomain)) { 78 switch (strtolower($subDomain)) {
79 case 'www': // 主站 79 case 'www': // 主站
@@ -90,6 +90,10 @@ class Bootstrap extends Bootstrap_Abstract @@ -90,6 +90,10 @@ class Bootstrap extends Bootstrap_Abstract
90 case 'list': // 商品列表 90 case 'list': // 商品列表
91 $module = 'Product'; 91 $module = 'Product';
92 break; 92 break;
  93 + case 'sale'://促销
  94 + $module = 'Product';
  95 + $controller = 'sale';
  96 +
93 default: // 其它(识别为品牌) 97 default: // 其它(识别为品牌)
94 $module = 'Product'; 98 $module = 'Product';
95 $action = 'Brand'; 99 $action = 'Brand';
@@ -24,6 +24,7 @@ class PassportModel @@ -24,6 +24,7 @@ class PassportModel
24 const BACK_LFFT_BANNER_CODE = '3bbaf502c447a2ddad60879042e286d8';//找回密码左边的banner 24 const BACK_LFFT_BANNER_CODE = '3bbaf502c447a2ddad60879042e286d8';//找回密码左边的banner
25 const SIGNIN_LEFT_BANNER_CODE ='db350894e01e90eac55cd3a13ad77331';//登录页左边的banner 25 const SIGNIN_LEFT_BANNER_CODE ='db350894e01e90eac55cd3a13ad77331';//登录页左边的banner
26 const AUTOUSERINFO_LEFT_BANNER_CODE ='c62d5da06d843b6ed78d8d27e87fa143';//完善信息页左边的banner 26 const AUTOUSERINFO_LEFT_BANNER_CODE ='c62d5da06d843b6ed78d8d27e87fa143';//完善信息页左边的banner
  27 + const BACK_FIND_SECRET_KEY = '_+@#$%^';
27 28
28 //简单头部 29 //简单头部
29 public static function getSimpleHeader($isLogin, $username = '') 30 public static function getSimpleHeader($isLogin, $username = '')
@@ -75,6 +76,11 @@ class PassportModel @@ -75,6 +76,11 @@ class PassportModel
75 $ret['img'] = Images::getImageUrl($val['src'], 252, 190); 76 $ret['img'] = Images::getImageUrl($val['src'], 252, 190);
76 $ret['url'] = $val['url']; 77 $ret['url'] = $val['url'];
77 } 78 }
  79 + else
  80 + {
  81 + $ret['img'] = 'http://img12.static.yhbimg.com/yhb-img01/2015/12/01/07/020a0b6e7ff908d0c2bc4045b4fef42b9f.png?imageView/2/w/252/h/190';
  82 + $ret['url'] = '';
  83 + }
78 return $ret; 84 return $ret;
79 } 85 }
80 86
@@ -56,6 +56,7 @@ class BackController extends WebAction @@ -56,6 +56,7 @@ class BackController extends WebAction
56 $data = BackData::sendCodeToMobile($mobile); 56 $data = BackData::sendCodeToMobile($mobile);
57 $this->setSession('phoneNum', $phoneNum); 57 $this->setSession('phoneNum', $phoneNum);
58 $this->setSession('area', $area); 58 $this->setSession('area', $area);
  59 + $this->setSession('captcha', $captcha);
59 if($data['code'] == 200) { 60 if($data['code'] == 200) {
60 $this->redirect('verification'); 61 $this->redirect('verification');
61 } 62 }
@@ -66,7 +67,7 @@ class BackController extends WebAction @@ -66,7 +67,7 @@ class BackController extends WebAction
66 } 67 }
67 68
68 /** 69 /**
69 - * 发送邮件 70 + * 发送邮件页面
70 */ 71 */
71 public function sendemailAction() { 72 public function sendemailAction() {
72 $phoneNum = $this->getSession('phoneNum'); 73 $phoneNum = $this->getSession('phoneNum');
@@ -96,14 +97,14 @@ class BackController extends WebAction @@ -96,14 +97,14 @@ class BackController extends WebAction
96 'sendEmail' => array( 97 'sendEmail' => array(
97 'coverHref' => $banner['url'], 98 'coverHref' => $banner['url'],
98 'coverImg' => $banner['img'], 99 'coverImg' => $banner['img'],
99 - 'countrys' => array() 100 + 'countrys' => array(),
100 ) 101 )
101 ); 102 );
102 $this->_view->display('send-email', $data); 103 $this->_view->display('send-email', $data);
103 } 104 }
104 105
105 /** 106 /**
106 - * 重置密码 107 + * 重置密码页面
107 */ 108 */
108 public function backcodeAction() { 109 public function backcodeAction() {
109 $code = $this->get('code'); 110 $code = $this->get('code');
@@ -118,14 +119,15 @@ class BackController extends WebAction @@ -118,14 +119,15 @@ class BackController extends WebAction
118 'resetPwd' => array( 119 'resetPwd' => array(
119 'coverHref' => $banner['url'], 120 'coverHref' => $banner['url'],
120 'coverImg' => $banner['img'], 121 'coverImg' => $banner['img'],
121 - 'countrys' => array() 122 + 'countrys' => array(),
  123 + 'code' => $code,
122 ) 124 )
123 ); 125 );
124 $this->_view->display('reset-pwd', $data); 126 $this->_view->display('reset-pwd', $data);
125 } 127 }
126 128
127 /** 129 /**
128 - * 更新密码 130 + * 更新密码接口
129 * 131 *
130 */ 132 */
131 public function updateAction() 133 public function updateAction()
@@ -134,10 +136,22 @@ class BackController extends WebAction @@ -134,10 +136,22 @@ class BackController extends WebAction
134 $password = $this->post('pwd'); 136 $password = $this->post('pwd');
135 $info = $this->checkCode($code); 137 $info = $this->checkCode($code);
136 if(Helpers::verifyPassword($password) && !empty($info)) { 138 if(Helpers::verifyPassword($password) && !empty($info)) {
137 - $uid = $info['uid'];  
138 //修改密码 139 //修改密码
  140 + if(isset($info['mobile'])) {//手机号修改密码
  141 + $mobile = $info['mobile'];
  142 + $token = $info['token'];
  143 + $area = $info['area'];
  144 + $data = BackData::modifyPasswordByMobile($mobile, $token, $password, $area);
  145 + if($data['code']) {
  146 + $this->redirect('resetSuccess');
  147 + }
  148 + } else if(isset($info['uid'])) {//其他方式修改密码
  149 + $uid = $info['uid'];
  150 + $this->redirect('resetSuccess');
  151 + }
139 } 152 }
140 - 153 + //跳转错误页面
  154 + $this->redirect('/error/index');
141 } 155 }
142 156
143 /** 157 /**
@@ -157,14 +171,15 @@ class BackController extends WebAction @@ -157,14 +171,15 @@ class BackController extends WebAction
157 } 171 }
158 172
159 /** 173 /**
160 - * 手机验证 174 + * 手机验证页面
161 */ 175 */
162 public function verificationAction() { 176 public function verificationAction() {
163 $phoneNum = $this->getSession('phoneNum'); 177 $phoneNum = $this->getSession('phoneNum');
164 $area = $this->getSession('area'); 178 $area = $this->getSession('area');
165 -// if(empty($phoneNum)) {  
166 -// $this->redirect('index');  
167 -// } 179 + $captcha = $this->getSession('captcha');
  180 + if(empty($phoneNum)) {
  181 + $this->redirect('index');
  182 + }
168 $banner = PassportModel::getLeftBanner(PassportModel::BACK_LFFT_BANNER_CODE); 183 $banner = PassportModel::getLeftBanner(PassportModel::BACK_LFFT_BANNER_CODE);
169 $data = array( 184 $data = array(
170 'simpleHeader' => PassportModel::getSimpleHeader(false), 185 'simpleHeader' => PassportModel::getSimpleHeader(false),
@@ -174,6 +189,7 @@ class BackController extends WebAction @@ -174,6 +189,7 @@ class BackController extends WebAction
174 'coverImg' => $banner['img'], 189 'coverImg' => $banner['img'],
175 'phoneNum' => $phoneNum, 190 'phoneNum' => $phoneNum,
176 'area' => $area, 191 'area' => $area,
  192 + 'captcha'=> $captcha,
177 'countrys' => array() 193 'countrys' => array()
178 ) 194 )
179 ); 195 );
@@ -181,6 +197,32 @@ class BackController extends WebAction @@ -181,6 +197,32 @@ class BackController extends WebAction
181 } 197 }
182 198
183 /** 199 /**
  200 + * 手机找回密码验证
  201 + */
  202 + public function backmobileAction()
  203 + {
  204 + $mobile = $this->post('mobile');//phoneNum
  205 + $area = $this->post('area');
  206 + //$captcha = $this->post('captcha');
  207 + $code = $this->post('captcha');//code
  208 + if($this->getSession('phoneNum') == $mobile && $this->getSession('area') == $area)
  209 + {
  210 + $result = BackData::validateMobileCode($mobile, $code, $area);
  211 + if($result['code'] == 200) {
  212 + $str = json_encode(array(
  213 + 'mobile'=> $mobile,
  214 + 'area' => $area,
  215 + 'token'=> $result['data']['token'],
  216 + 'create_time' => time()
  217 + ));
  218 + $code = AuthCode::encode($str, PassportModel::BACK_FIND_SECRET_KEY);
  219 + $url = '/passport/back/backcode?code='.base64_encode($code);
  220 + $this->redirect(SITE_MAIN.$url);
  221 + }
  222 + }
  223 + }
  224 +
  225 + /**
184 * 检查code 226 * 检查code
185 * 227 *
186 * @param string $code 228 * @param string $code
@@ -188,9 +230,8 @@ class BackController extends WebAction @@ -188,9 +230,8 @@ class BackController extends WebAction
188 */ 230 */
189 private function checkCode($code) 231 private function checkCode($code)
190 { 232 {
191 - $key = '_+@#$%^';  
192 $code = base64_decode($code); 233 $code = base64_decode($code);
193 - $info = json_decode(AuthCode::decode($code, $key), true); 234 + $info = json_decode(AuthCode::decode($code, PassportModel::BACK_FIND_SECRET_KEY), true);
194 if ($info['create_time'] < 1 || (time() - $info['create_time']) > 86400) { 235 if ($info['create_time'] < 1 || (time() - $info['create_time']) > 86400) {
195 return array(); 236 return array();
196 } 237 }
1 <?php 1 <?php
2 2
3 -use Action\AbstractAction; 3 +use Action\WebAction;
4 use LibModels\Web\Passport\RegData; 4 use LibModels\Web\Passport\RegData;
5 use LibModels\Web\Passport\LoginData; 5 use LibModels\Web\Passport\LoginData;
6 use Passport\PassportModel as PassportModel; 6 use Passport\PassportModel as PassportModel;
7 use Plugin\Helpers; 7 use Plugin\Helpers;
8 -  
9 -class LoginController extends AbstractAction 8 +class LoginController extends WebAction
10 { 9 {
11 10
12 /** 11 /**
@@ -23,7 +22,7 @@ class LoginController extends AbstractAction @@ -23,7 +22,7 @@ class LoginController extends AbstractAction
23 $this->setCookie('_TOKEN', ''); 22 $this->setCookie('_TOKEN', '');
24 23
25 //登录后跳转页面 24 //登录后跳转页面
26 - $refer = empty($_SERVER["HTTP_REFERER"])?'':$_SERVER["HTTP_REFERER"]; 25 + $refer = empty($_SERVER["HTTP_REFERER"]) ? '' : $_SERVER["HTTP_REFERER"];
27 if (!empty($refer)) { 26 if (!empty($refer)) {
28 $this->setCookie('refer', $refer); 27 $this->setCookie('refer', $refer);
29 } 28 }
@@ -40,13 +39,21 @@ class LoginController extends AbstractAction @@ -40,13 +39,21 @@ class LoginController extends AbstractAction
40 $simpleHeader = PassportModel::getSimpleHeader($isLogin, $username); 39 $simpleHeader = PassportModel::getSimpleHeader($isLogin, $username);
41 //获取登陆页左侧资源 40 //获取登陆页左侧资源
42 $cover = PassportModel::getLeftBanner(PassportModel::SIGNIN_LEFT_BANNER_CODE); 41 $cover = PassportModel::getLeftBanner(PassportModel::SIGNIN_LEFT_BANNER_CODE);
  42 + //是否记住密码
  43 + $isRemember = $this->getCookie('isRemember', FALSE);
  44 + $account = '';
  45 + $password = '';
  46 + if ($isRemember) {
  47 + $account = $this->decrypt($this->getCookie('account', ''));
  48 + $password = $this->decrypt($this->getCookie('userInfo', ''));
  49 + }
43 //整合 50 //整合
44 $data = array( 51 $data = array(
45 'loginPage' => true, 52 'loginPage' => true,
46 'simpleHeader' => $simpleHeader, 53 'simpleHeader' => $simpleHeader,
47 'passport' => array( 54 'passport' => array(
48 'coverHref' => $cover['url'], 55 'coverHref' => $cover['url'],
49 - 'coverImg' => !empty($cover['img'])?$cover['img']:'http://img12.static.yhbimg.com/yhb-img01/2015/12/01/07/020a0b6e7ff908d0c2bc4045b4fef42b9f.png?imageView/2/w/252/h/190', 56 + 'coverImg' => !empty($cover['img']) ? $cover['img'] : 'http://img12.static.yhbimg.com/yhb-img01/2015/12/01/07/020a0b6e7ff908d0c2bc4045b4fef42b9f.png?imageView/2/w/252/h/190',
50 'countryCode' => '+86', 57 'countryCode' => '+86',
51 'countryName' => '中国', 58 'countryName' => '中国',
52 'countryList' => RegData::getAreasData(), 59 'countryList' => RegData::getAreasData(),
@@ -58,6 +65,9 @@ class LoginController extends AbstractAction @@ -58,6 +65,9 @@ class LoginController extends AbstractAction
58 'alipayLogin' => Helpers::url('/passport/autosign/alipay'), 65 'alipayLogin' => Helpers::url('/passport/autosign/alipay'),
59 'doubanLogin' => Helpers::url('/passport/autosign/douban'), 66 'doubanLogin' => Helpers::url('/passport/autosign/douban'),
60 'renrenLogin' => Helpers::url('/passport/autosign/renren'), 67 'renrenLogin' => Helpers::url('/passport/autosign/renren'),
  68 + 'isRemember' => $isRemember,
  69 + 'password' => $password,
  70 + 'account' => $account
61 ), 71 ),
62 ); 72 );
63 73
@@ -84,15 +94,17 @@ class LoginController extends AbstractAction @@ -84,15 +94,17 @@ class LoginController extends AbstractAction
84 94
85 /* 判断参数是否传递 */ 95 /* 判断参数是否传递 */
86 $area = trim($this->post('areaCode', '86')); 96 $area = trim($this->post('areaCode', '86'));
87 - $profile = trim($this->post('account')); 97 + $account = trim($this->post('account'));
88 $password = trim($this->post('password')); 98 $password = trim($this->post('password'));
89 - if (!is_numeric($area) || empty($profile) || empty($password)) { 99 + $isRemember = trim($this->post('isRemember'));
  100 + $isRemember = false;
  101 + if (!is_numeric($area) || empty($account) || empty($password)) {
90 break; 102 break;
91 } 103 }
92 104
93 /* 判断参数是否有效 */ 105 /* 判断参数是否有效 */
94 - $verifyEmail = Helpers::verifyEmail($profile);  
95 - $verifyMobile = ($area === '86') ? Helpers::verifyMobile($profile) : Helpers::verifyAreaMobile($profile, $area); 106 + $verifyEmail = Helpers::verifyEmail($account);
  107 + $verifyMobile = ($area === '86') ? Helpers::verifyMobile($account) : Helpers::verifyAreaMobile($account, $area);
96 if (!$verifyEmail && !$verifyMobile) { 108 if (!$verifyEmail && !$verifyMobile) {
97 break; 109 break;
98 } 110 }
@@ -106,10 +118,21 @@ class LoginController extends AbstractAction @@ -106,10 +118,21 @@ class LoginController extends AbstractAction
106 /* 调用登录接口进行登录 */ 118 /* 调用登录接口进行登录 */
107 // 获取未登录时的唯一识别码 119 // 获取未登录时的唯一识别码
108 $shoppingKey = Helpers::getShoppingKeyByCookie(); 120 $shoppingKey = Helpers::getShoppingKeyByCookie();
109 - $data = LoginData::signin($area, $profile, $password, $shoppingKey); 121 + $data = LoginData::signin($area, $account, $password, $shoppingKey);
110 if (!isset($data['code']) || $data['code'] != 200 || !isset($data['data']['uid'])) { 122 if (!isset($data['code']) || $data['code'] != 200 || !isset($data['data']['uid'])) {
111 break; 123 break;
112 } 124 }
  125 + //登录成功记录账户信息
  126 + if ($isRemember) {
  127 + $this->setCookie('account', $this->encrypt($account), time() + 3600 * 24 * 7, '/');
  128 + $this->setCookie('userInfo', $this->encrypt($password), time() + 3600 * 24 * 7, '/');
  129 + $this->setCookie('isRemember', $isRemember, time() + 3600 * 24 * 7);
  130 + }
  131 + else {
  132 + $this->setCookie('account', '', -1, '/');
  133 + $this->setCookie('userInfo', '', -1, '/');
  134 + $this->setCookie('isRemember', '', -1, '/');
  135 + }
113 136
114 $refer = $this->getCookie('refer'); 137 $refer = $this->getCookie('refer');
115 if (empty($refer)) { 138 if (empty($refer)) {
@@ -152,4 +175,60 @@ class LoginController extends AbstractAction @@ -152,4 +175,60 @@ class LoginController extends AbstractAction
152 $this->go($refer); 175 $this->go($refer);
153 } 176 }
154 177
  178 + /*
  179 + * 加密算法
  180 + */
  181 +
  182 + private function encrypt($data, $key='yohobuy')
  183 + {
  184 + $key = md5($key);
  185 + $x = 0;
  186 + $str='';
  187 + $char='';
  188 + $len = strlen($data);
  189 + $l = strlen($key);
  190 + for ($i = 0; $i < $len; $i++) {
  191 + if ($x == $l) {
  192 + $x = 0;
  193 + }
  194 + $char .= $key{$x};
  195 + $x++;
  196 + }
  197 + for ($i = 0; $i < $len; $i++) {
  198 + $str .= chr(ord($data{$i}) + (ord($char{$i})) % 256);
  199 + }
  200 + return base64_encode($str);
  201 + }
  202 +
  203 + /*
  204 + * 解密算法
  205 + */
  206 +
  207 + private function decrypt($data, $key='yohobuy')
  208 + {
  209 + $key = md5($key);
  210 + $x = 0;
  211 + $str='';
  212 + $char='';
  213 + $data = base64_decode($data);
  214 + $len = strlen($data);
  215 + $l = strlen($key);
  216 + for ($i = 0; $i < $len; $i++) {
  217 + if ($x == $l) {
  218 + $x = 0;
  219 + }
  220 + $char .= substr($key, $x, 1);
  221 + $x++;
  222 + }
  223 + for ($i = 0; $i < $len; $i++) {
  224 + if (ord(substr($data, $i, 1)) < ord(substr($char, $i, 1))) {
  225 + $str .= chr((ord(substr($data, $i, 1)) + 256) - ord(substr($char, $i, 1)));
  226 + }
  227 + else {
  228 + $str .= chr(ord(substr($data, $i, 1)) - ord(substr($char, $i, 1)));
  229 + }
  230 + }
  231 + return $str;
  232 + }
  233 +
155 } 234 }