[ Index ] |
|
Code source de Phorum 5.1.25 |
1 <?php 2 3 //////////////////////////////////////////////////////////////////////////////// 4 // // 5 // Copyright (C) 2006 Phorum Development Team // 6 // http://www.phorum.org // 7 // // 8 // This program is free software. You can redistribute it and/or modify // 9 // it under the terms of either the current Phorum License (viewable at // 10 // phorum.org) or the Phorum License that was distributed with this file // 11 // // 12 // This program is distributed in the hope that it will be useful, // 13 // but WITHOUT ANY WARRANTY, without even the implied warranty of // 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // 15 // // 16 // You should have received a copy of the Phorum License // 17 // along with this program. // 18 //////////////////////////////////////////////////////////////////////////////// 19 define('phorum_page','moderation'); 20 21 include_once ("./common.php"); 22 include_once ("./include/moderation_functions.php"); 23 include_once ("./include/thread_info.php"); 24 include_once ("./include/email_functions.php"); 25 26 if(!phorum_check_read_common()) { 27 return; 28 } 29 30 $PHORUM["DATA"]["MODERATOR"] = phorum_user_access_allowed(PHORUM_USER_ALLOW_MODERATE_MESSAGES); 31 32 $msgthd_id = (isset($_POST["thread"])) ? (int)$_POST["thread"] : (int)$PHORUM['args'][2]; 33 34 $mod_step = (isset($_POST["mod_step"])) ? (int)$_POST["mod_step"] : (int)$PHORUM['args'][1]; 35 36 if(empty($msgthd_id) || !phorum_user_access_allowed(PHORUM_USER_ALLOW_MODERATE_MESSAGES)) { 37 phorum_return_to_list(); 38 } 39 40 // If the user is not fully logged in, send him to the login page. 41 // because moderation action can vary so much, the only safe bet is to send them 42 // to the referrer if they are not fully logged in 43 if(!$PHORUM["DATA"]["FULLY_LOGGEDIN"]){ 44 phorum_redirect_by_url(phorum_get_url(PHORUM_LOGIN_URL, "redir=".$_SERVER["HTTP_REFERER"])); 45 exit(); 46 } 47 48 49 $template="message"; 50 // set all our URL's 51 phorum_build_common_urls(); 52 53 // make it possible to override this var in a hook 54 $is_admin_user=$PHORUM["user"]["admin"]; 55 56 // a hook for doing stuff in moderation, i.e. logging moderator-actions 57 phorum_hook("moderation",$mod_step); 58 59 60 switch ($mod_step) { 61 62 case PHORUM_DELETE_MESSAGE: // this is a message delete 63 64 // check that they're an admin if they want to delete an announcement 65 $message = phorum_db_get_message($msgthd_id); 66 if ($message["sort"] == PHORUM_SORT_ANNOUNCEMENT && !$is_admin_user){ 67 $PHORUM['DATA']['MESSAGE']=$PHORUM["DATA"]["LANG"]["DeleteAnnouncementForbidden"]; 68 break; 69 } 70 $msg_ids=phorum_db_delete_message($msgthd_id, PHORUM_DELETE_MESSAGE); 71 foreach($msg_ids as $id){ 72 $files=phorum_db_get_message_file_list($id); 73 foreach($files as $file_id=>$data){ 74 phorum_db_file_delete($file_id); 75 } 76 } 77 phorum_hook("delete", $msg_ids); 78 $nummsgs=count($msg_ids); 79 $PHORUM['DATA']['MESSAGE']=$nummsgs." ".$PHORUM["DATA"]['LANG']['MsgDeletedOk']; 80 81 if(isset($PHORUM['args']['old_forum']) && !empty($PHORUM['args']['old_forum'])) { 82 $PHORUM['forum_id']=(int)$PHORUM['args']['old_forum']; 83 } 84 85 if(isset($PHORUM['args']["prepost"])) { 86 $PHORUM['DATA']["URL"]["REDIRECT"]=phorum_get_url(PHORUM_CONTROLCENTER_URL,"panel=".PHORUM_CC_UNAPPROVED); 87 } else { 88 $PHORUM['DATA']["URL"]["REDIRECT"]=$PHORUM["DATA"]["URL"]["TOP"]; 89 } 90 break; 91 92 case PHORUM_DELETE_TREE: // this is a message delete 93 // check that they're an admin if they want to delete an announcement 94 $message = phorum_db_get_message($msgthd_id); 95 if ($message["sort"] == PHORUM_SORT_ANNOUNCEMENT && !$is_admin_user){ 96 $PHORUM['DATA']['MESSAGE']=$PHORUM["DATA"]["LANG"]["DeleteAnnouncementForbidden"]; 97 break; 98 } 99 100 // Delete the message and all its replies. 101 $msg_ids=phorum_db_delete_message($msgthd_id, PHORUM_DELETE_TREE); 102 103 // Cleanup the attachments for all deleted messages. 104 foreach($msg_ids as $id){ 105 $files=phorum_db_get_message_file_list($id); 106 foreach($files as $file_id=>$data){ 107 phorum_db_file_delete($file_id); 108 } 109 } 110 111 // Check if we have moved threads to delete. 112 // We unset the forum id, so phorum_db_get_messages() 113 // will return messages with the same thread id in 114 // other forums as well (those are the move notifications). 115 $forum_id = $PHORUM["forum_id"]; 116 $PHORUM["forum_id"] = 0; 117 $moved = phorum_db_get_messages($msgthd_id); 118 $PHORUM["forum_id"] = $forum_id; 119 foreach ($moved as $id => $data) { 120 if (isset($data["meta"]["moved"])) { 121 phorum_db_delete_message($id, PHORUM_DELETE_MESSAGE); 122 } 123 } 124 125 // Run a hook for performing custom cleanup actions. 126 phorum_hook("delete", $msg_ids); 127 128 $nummsgs=count($msg_ids); 129 $PHORUM['DATA']['MESSAGE']=$nummsgs." ".$PHORUM["DATA"]["LANG"]['MsgDeletedOk']; 130 131 if(isset($PHORUM['args']['old_forum']) && !empty($PHORUM['args']['old_forum'])) { 132 $PHORUM['forum_id']=(int)$PHORUM['args']['old_forum']; 133 } 134 135 if(isset($PHORUM['args']["prepost"])) { 136 // add some additional args 137 $addcode = ""; 138 if(isset($PHORUM['args']['moddays']) && is_numeric($PHORUM['args']['moddays'])) { 139 $addcode.="moddays=".$PHORUM['args']['moddays']; 140 } 141 if(isset($PHORUM['args']['onlyunapproved']) && is_numeric($PHORUM['args']['onlyunapproved'])) { 142 if(!empty($addcode)) 143 $addcode.=","; 144 145 $addcode.="onlyunapproved=".$PHORUM['args']['onlyunapproved']; 146 } 147 $PHORUM['DATA']["URL"]["REDIRECT"]=phorum_get_url(PHORUM_CONTROLCENTER_URL,"panel=".PHORUM_CC_UNAPPROVED,$addcode); 148 } else { 149 $PHORUM['DATA']["URL"]["REDIRECT"]=$PHORUM["DATA"]["URL"]["TOP"]; 150 } 151 break; 152 153 case PHORUM_MOVE_THREAD: // this is the first step of a message move 154 // check if the thread to move is an announcement thread 155 $message = phorum_db_get_message($msgthd_id); 156 if ($message["sort"] == PHORUM_SORT_ANNOUNCEMENT) { 157 $PHORUM['DATA']['MESSAGE']=$PHORUM["DATA"]["LANG"]["MoveAnnouncementForbidden"]; 158 break; 159 } 160 $PHORUM['DATA']['URL']["ACTION"]=phorum_get_url(PHORUM_MODERATION_ACTION_URL); 161 $PHORUM['DATA']["FORM"]["forum_id"]=$PHORUM["forum_id"]; 162 $PHORUM['DATA']["FORM"]["thread_id"]=$msgthd_id; 163 $PHORUM['DATA']["FORM"]["mod_step"]=PHORUM_DO_THREAD_MOVE; 164 165 // get all the forums the moderator may move to 166 $PHORUM['DATA']["MoveForumsOption"]=""; 167 168 169 $forums=phorum_db_get_forums(0,-1,$PHORUM['vroot']); 170 asort($forums); 171 172 foreach($forums as $id=>$forum){ 173 if ($id == $PHORUM["forum_id"]) continue; 174 // add && phorum_user_moderate_allowed($id) if the mod should only be able 175 // to move to forums he also moderates 176 if($forum["folder_flag"]==0){ 177 // it makes no sense to move to the forum we are in already 178 if($forum['forum_id'] != $PHORUM['forum_id']) { 179 $forum_data[strtolower($forum["name"])]=array("forum_id"=>$id, "name"=>$forum["name"]); 180 } 181 } 182 } 183 184 $PHORUM['DATA']['FRM']=1; 185 $PHORUM['DATA']['FORUMS']=$forum_data; 186 $output=true; 187 188 $template="move_form"; 189 190 break; 191 192 case PHORUM_DO_THREAD_MOVE: // this is the last step of a message move 193 194 $movetoid=trim($_POST['moveto']); 195 $movetoid=(int)$movetoid; 196 197 // only do something if a forum was selected 198 if(empty($movetoid)) { 199 // in plain english as language-files are frozen 200 $PHORUM['DATA']['MESSAGE']="Please select a forum first."; 201 } else { 202 203 204 $PHORUM['DATA']['MESSAGE']=$PHORUM["DATA"]['LANG']['MsgMoveOk']; 205 $PHORUM['DATA']["URL"]["REDIRECT"]=$PHORUM["DATA"]["URL"]["TOP"]; 206 $message = phorum_db_get_message($msgthd_id); 207 208 // find out if we have a notification-message already in this 209 // target-forum for this thread ... it doesn't make sense to keep this 210 // message any longer as the thread has reappeared on its original location 211 $temp_forum_id=$PHORUM['forum_id']; 212 $PHORUM['forum_id']=$movetoid; 213 $check_messages=phorum_db_get_messages($msgthd_id); 214 215 unset($check_messages['users']); 216 217 // ok, we found exactly one message of this thread in the target forum 218 if(is_array($check_messages) && count($check_messages) == 1) { 219 // ... going to delete it 220 $tmp_message=array_shift($check_messages); 221 $retval=phorum_db_delete_message($tmp_message['message_id']); 222 } 223 224 $PHORUM['forum_id']=$temp_forum_id; 225 226 // Move the thread to another forum. 227 phorum_db_move_thread($msgthd_id, $movetoid); 228 229 // Create a new message in place of the old one to notify 230 // visitors that the thread was moved. 231 if(isset($_POST['create_notification']) && $_POST['create_notification']) { 232 $newmessage = $message; 233 $newmessage['body']=" -- moved topic -- "; 234 $newmessage['meta']=array('moved' => 1); 235 $newmessage['sort']=PHORUM_SORT_DEFAULT; 236 unset($newmessage['message_id']); 237 238 phorum_db_post_message($newmessage); 239 } 240 phorum_hook("move_thread", $msgthd_id); 241 } 242 break; 243 244 case PHORUM_CLOSE_THREAD: // we have to close a thread 245 246 $PHORUM['DATA']['MESSAGE']=$PHORUM["DATA"]['LANG']['ThreadClosedOk']; 247 $PHORUM['DATA']["URL"]["REDIRECT"]=$PHORUM["DATA"]["URL"]["TOP"]; 248 phorum_db_close_thread($msgthd_id); 249 phorum_hook("close_thread", $msgthd_id); 250 break; 251 252 case PHORUM_REOPEN_THREAD: // we have to reopen a thread 253 254 $PHORUM['DATA']['MESSAGE']=$PHORUM["DATA"]['LANG']['ThreadReopenedOk']; 255 $PHORUM['DATA']["URL"]["REDIRECT"]=$PHORUM["DATA"]["URL"]["TOP"]; 256 phorum_db_reopen_thread($msgthd_id); 257 phorum_hook("reopen_thread", $msgthd_id); 258 break; 259 260 case PHORUM_APPROVE_MESSAGE: // approving a message 261 262 $PHORUM['DATA']['MESSAGE']="1 ".$PHORUM["DATA"]['LANG']['MsgApprovedOk']; 263 264 $old_message = phorum_db_get_message($msgthd_id); 265 $newpost=array("status"=>PHORUM_STATUS_APPROVED); 266 267 // setting the new status 268 phorum_db_update_message($msgthd_id, $newpost); 269 270 // updating the thread-info 271 phorum_update_thread_info($old_message['thread']); 272 273 // updating the forum-stats 274 phorum_db_update_forum_stats(false, 1, $old_message["datestamp"]); 275 276 phorum_hook("after_approve", array($old_message, PHORUM_APPROVE_MESSAGE)); 277 278 if($old_message['status'] != PHORUM_STATUS_HIDDEN ) { 279 phorum_email_notice($old_message); 280 } 281 282 if(isset($PHORUM['args']['old_forum']) && is_numeric($PHORUM['args']['old_forum'])) { 283 $PHORUM['forum_id']=(int)$PHORUM['args']['old_forum']; 284 } 285 286 287 if(isset($PHORUM['args']["prepost"])) { 288 // add some additional args 289 $addcode = ""; 290 if(isset($PHORUM['args']['moddays']) && is_numeric($PHORUM['args']['moddays'])) { 291 $addcode.="moddays=".$PHORUM['args']['moddays']; 292 } 293 if(isset($PHORUM['args']['onlyunapproved']) && is_numeric($PHORUM['args']['onlyunapproved'])) { 294 if(!empty($addcode)) 295 $addcode.=","; 296 $addcode.="onlyunapproved=".$PHORUM['args']['onlyunapproved']; 297 } 298 $PHORUM['DATA']["URL"]["REDIRECT"]=phorum_get_url(PHORUM_CONTROLCENTER_URL,"panel=".PHORUM_CC_UNAPPROVED,$addcode); 299 } else { 300 $PHORUM['DATA']["URL"]["REDIRECT"]=$PHORUM["DATA"]["URL"]["TOP"]; 301 } 302 break; 303 304 case PHORUM_APPROVE_MESSAGE_TREE: // approve a message and all answers to it 305 306 $old_message = phorum_db_get_message($msgthd_id); 307 $newpost=array("status"=>PHORUM_STATUS_APPROVED); 308 309 $mids = phorum_db_get_messagetree($msgthd_id, $old_message["forum_id"]); 310 // make an array from the string 311 $mids_arr=explode(",",$mids); 312 313 // count the entries for later use 314 $num_approved=count($mids_arr); 315 foreach($mids_arr as $key => $mid) { 316 // setting the new status 317 phorum_db_update_message($mid, $newpost); 318 319 } 320 321 // updating the thread-info 322 phorum_update_thread_info($old_message['thread']); 323 324 // updating the forum-stats 325 phorum_db_update_forum_stats(false, "+$num_approved", $old_message["datestamp"]); 326 327 phorum_hook("after_approve", array($old_message, PHORUM_APPROVE_MESSAGE_TREE)); 328 329 if(isset($PHORUM['args']['old_forum']) && is_numeric($PHORUM['args']['old_forum'])) { 330 $PHORUM['forum_id']=(int)$PHORUM['args']['old_forum']; 331 } 332 333 334 $PHORUM['DATA']['MESSAGE']="$num_approved ".$PHORUM['DATA']['LANG']['MsgApprovedOk']; 335 if(isset($PHORUM['args']["prepost"])) { 336 // add some additional args 337 $addcode = ""; 338 if(isset($PHORUM['args']['moddays']) && is_numeric($PHORUM['args']['moddays'])) { 339 $addcode.="moddays=".$PHORUM['args']['moddays']; 340 } 341 if(isset($PHORUM['args']['onlyunapproved']) && is_numeric($PHORUM['args']['onlyunapproved'])) { 342 if(!empty($addcode)) 343 $addcode.=","; 344 345 $addcode.="onlyunapproved=".$PHORUM['args']['onlyunapproved']; 346 } 347 $PHORUM['DATA']["URL"]["REDIRECT"]=phorum_get_url(PHORUM_CONTROLCENTER_URL,"panel=".PHORUM_CC_UNAPPROVED,$addcode); 348 } else { 349 $PHORUM['DATA']["URL"]["REDIRECT"]=$PHORUM["DATA"]["URL"]["TOP"]; 350 } 351 break; 352 353 case PHORUM_HIDE_POST: // hiding a message (and its replies) 354 355 $old_message = phorum_db_get_message($msgthd_id); 356 $newpost=array("status"=>PHORUM_STATUS_HIDDEN); 357 358 $mids = phorum_db_get_messagetree($msgthd_id, $old_message["forum_id"]); 359 // make an array from the string 360 $mids_arr=explode(",",$mids); 361 362 // count the entries for later use 363 $num_hidden=count($mids_arr); 364 foreach($mids_arr as $key => $mid) { 365 // setting the new status 366 phorum_db_update_message($mid, $newpost); 367 368 } 369 370 phorum_hook("hide", $msgthd_id); 371 372 // updating the thread-info 373 phorum_update_thread_info($old_message['thread']); 374 375 // updating the forum-stats 376 phorum_db_update_forum_stats(false, "-$num_hidden", $old_message["datestamp"]); 377 378 $PHORUM['DATA']['MESSAGE']="$num_hidden ".$PHORUM['DATA']['LANG']['MsgHiddenOk']; 379 if(isset($PHORUM['args']["prepost"])) { 380 $PHORUM['DATA']["URL"]["REDIRECT"]=phorum_get_url(PHORUM_CONTROLCENTER_URL,"panel=".PHORUM_CC_UNAPPROVED); 381 } else { 382 $PHORUM['DATA']["URL"]["REDIRECT"]=$PHORUM["DATA"]["URL"]["TOP"]; 383 } 384 break; 385 386 case PHORUM_MERGE_THREAD: // this is the first step of a thread merge 387 388 $template="merge_form"; 389 $PHORUM['DATA']['URL']["ACTION"] = phorum_get_url(PHORUM_MODERATION_ACTION_URL); 390 $PHORUM['DATA']["FORM"]["forum_id"] = $PHORUM["forum_id"]; 391 $PHORUM['DATA']["FORM"]["thread_id"] = $msgthd_id; 392 $PHORUM['DATA']["FORM"]["mod_step"] = PHORUM_DO_THREAD_MERGE; 393 394 // the moderator selects the target thread to merge to 395 $merge_t1 = phorum_moderator_data_get('merge_t1'); 396 if( !$merge_t1 || $merge_t1==$msgthd_id ) { 397 phorum_moderator_data_put('merge_t1', $msgthd_id); 398 $PHORUM['DATA']["FORM"]["merge_none"] =true; 399 } 400 // the moderator selects the source thread to merge from 401 else { 402 $PHORUM['DATA']["FORM"]["merge_t1"] =$merge_t1; 403 $message = phorum_db_get_message($merge_t1, "message_id", true); 404 $PHORUM['DATA']["FORM"]["merge_subject1"] =htmlentities($message["subject"], ENT_COMPAT, $PHORUM["DATA"]["CHARSET"]); 405 $message = phorum_db_get_message($msgthd_id); 406 $PHORUM['DATA']["FORM"]["thread_subject"] =htmlentities($message["subject"], ENT_COMPAT, $PHORUM["DATA"]["CHARSET"]); 407 } 408 break; 409 410 case PHORUM_DO_THREAD_MERGE: // this is the last step of a thread merge 411 412 if( isset($_POST['thread1']) && $_POST['thread1']) { 413 // Commit Thread Merge 414 settype($_POST['thread1'], "int"); 415 settype($_POST['thread'], "int"); // Thread 2 416 $PHORUM['DATA']['MESSAGE'] = $PHORUM["DATA"]['LANG']['MsgMergeOk']; 417 $PHORUM['DATA']["URL"]["REDIRECT"] = $PHORUM["DATA"]["URL"]["TOP"]; 418 $PHORUM["reverse_threading"] = 0; 419 420 // Get the target thread. 421 $target =phorum_db_get_message($_POST['thread1'], "message_id", true); 422 if (!$target) die("Can't retrieve target thread " . $_POST['thread1']); 423 424 // Get all messages from the thread that we have to merge. 425 $merge_messages=phorum_db_get_messages($_POST['thread']); 426 unset($merge_messages['users']); 427 428 // Create new messages in the target thread for 429 // all messages that have to be merged. 430 $msgid_translation=array(); 431 foreach($merge_messages as $msg) 432 { 433 $oldid=$msg['message_id']; 434 435 $msg['thread'] = $target['thread']; // the thread we merge with 436 $msg['forum_id'] = $target['forum_id']; // the forum_id of the new thread 437 $msg['sort'] = $target['sort']; // the sort type of the new thread 438 439 if($msg['message_id'] == $msg['thread']) { 440 $msg['parent_id']=$target['thread']; 441 } elseif(isset($msgid_translation[$msg['parent_id']])) { 442 $msg['parent_id']=$msgid_translation[$msg['parent_id']]; 443 } else { 444 $msg['parent_id']=$msg['thread']; 445 } 446 447 unset($msg['message_id']); 448 unset($msg['modifystamp']); 449 450 phorum_db_post_message($msg,true); 451 452 // Link attached files to the new message id. 453 $linked_files = phorum_db_get_message_file_list($oldid); 454 foreach ($linked_files as $linked_file) { 455 phorum_db_file_link($linked_file["file_id"], $msg["message_id"], PHORUM_LINK_MESSAGE); 456 } 457 458 // save the new message-id for later use 459 $msgid_translation[$oldid]=$msg['message_id']; 460 } 461 462 // deleting messages which are now doubled 463 phorum_db_delete_message($_POST['thread'], PHORUM_DELETE_TREE); 464 465 // update message count / stats 466 phorum_db_update_forum_stats(true); 467 // change forum_id for the following calls to update the right forum 468 $PHORUM["forum_id"] =$target['forum_id']; 469 // update message count / stats 470 phorum_update_thread_info($target['thread']); 471 phorum_db_update_forum_stats(true); 472 } else { 473 // Cancel Thread Merge 474 $PHORUM['DATA']['MESSAGE']=$PHORUM["DATA"]['LANG']['MsgMergeCancel']; 475 $PHORUM['DATA']["URL"]["REDIRECT"]=$PHORUM["DATA"]["URL"]["TOP"]; 476 } 477 478 // unset temporary moderator_data 479 phorum_moderator_data_remove('merge_t1'); 480 481 break; 482 483 case PHORUM_SPLIT_THREAD: // this is the first step of a thread split 484 485 $PHORUM['DATA']['URL']["ACTION"]=phorum_get_url(PHORUM_MODERATION_ACTION_URL); 486 $PHORUM['DATA']["FORM"]["forum_id"]=$PHORUM["forum_id"]; 487 $message =phorum_db_get_message($msgthd_id); 488 $PHORUM['DATA']["FORM"]["thread_id"]=$message["thread"]; 489 $PHORUM['DATA']["FORM"]["message_id"]=$msgthd_id; 490 $PHORUM['DATA']["FORM"]["message_subject"]=htmlentities($message["subject"], ENT_COMPAT, $PHORUM["DATA"]["CHARSET"]); 491 $PHORUM['DATA']["FORM"]["mod_step"]=PHORUM_DO_THREAD_SPLIT; 492 $template="split_form"; 493 break; 494 495 case PHORUM_DO_THREAD_SPLIT: // this is the last step of a thread split 496 497 $PHORUM['DATA']['MESSAGE']=$PHORUM["DATA"]['LANG']['MsgSplitOk']; 498 $PHORUM['DATA']["URL"]["REDIRECT"]=$PHORUM["DATA"]["URL"]["TOP"]; 499 settype($_POST['forum_id'], "int"); 500 settype($_POST['message'], "int"); 501 settype($_POST['thread'], "int"); 502 phorum_db_split_thread($_POST['message'],$_POST['forum_id']); 503 // update message count / stats 504 phorum_update_thread_info($_POST['thread']); 505 phorum_update_thread_info($_POST['message']); 506 phorum_db_update_forum_stats(true); 507 break; 508 509 default: 510 511 if(!isset($PHORUM['DATA']['MESSAGE'])) $PHORUM['DATA']['MESSAGE']=""; 512 $PHORUM['DATA']["URL"]["REDIRECT"]=$PHORUM["DATA"]["URL"]["TOP"]; 513 } 514 515 if(!isset($PHORUM['DATA']['BACKMSG'])) { 516 $PHORUM['DATA']["BACKMSG"]=$PHORUM['DATA']["LANG"]["BackToList"]; 517 } 518 519 include phorum_get_template("header"); 520 phorum_hook("after_header"); 521 include phorum_get_template($template); 522 phorum_hook("before_footer"); 523 include phorum_get_template("footer"); 524 525 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Thu Nov 29 12:22:27 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |