Project

General

Profile

1 1365 Luisehahne
<?php
2
/**
3
 *
4 1529 Luisehahne
 * @category        framework
5 1698 Luisehahne
 * @package         frontend
6 1529 Luisehahne
 * @author          Ryan Djurovich, WebsiteBaker Project
7 1698 Luisehahne
 * @copyright       2009-2012, WebsiteBaker Org. e.V.
8 1365 Luisehahne
 * @link			http://www.websitebaker2.org/
9
 * @license         http://www.gnu.org/licenses/gpl.html
10
 * @platform        WebsiteBaker 2.8.x
11 1374 Luisehahne
 * @requirements    PHP 5.2.2 and higher
12 1365 Luisehahne
 * @version         $Id$
13 1457 Luisehahne
 * @filesource		$HeadURL$
14
 * @lastmodified    $Date$
15 1365 Luisehahne
 *
16
 */
17 1496 DarkViper
/* -------------------------------------------------------- */
18
// Must include code to stop this file being accessed directly
19 1499 DarkViper
if(!defined('WB_PATH')) {
20
	require_once(dirname(__FILE__).'/globalExceptionHandler.php');
21
	throw new IllegalFileException();
22
}
23 1496 DarkViper
/* -------------------------------------------------------- */
24 1365 Luisehahne
// Include PHPLIB template class
25
require_once(WB_PATH."/include/phplib/template.inc");
26
// Include new wbmailer class (subclass of PHPmailer)
27
require_once(WB_PATH."/framework/class.wbmailer.php");
28 1462 DarkViper
//require_once(WB_PATH."/framework/SecureForm.php");
29 1365 Luisehahne
30
class wb extends SecureForm
31
{
32
33 1457 Luisehahne
 	public $password_chars = 'a-zA-Z0-9\_\-\!\#\*\+\@\$\&\:';	// General initialization function
34 1365 Luisehahne
	// performed when frontend or backend is loaded.
35
36 1394 Luisehahne
	public function  __construct($mode = SecureForm::FRONTEND) {
37
		parent::__construct($mode);
38 1365 Luisehahne
	}
39
40 1373 Luisehahne
/* ****************
41 1440 Luisehahne
 * check if one or more group_ids are in both group_lists
42
 *
43
 * @access public
44
 * @param mixed $groups_list1: an array or a coma seperated list of group-ids
45
 * @param mixed $groups_list2: an array or a coma seperated list of group-ids
46
 * @param array &$matches: an array-var whitch will return possible matches
47
 * @return bool: true there is a match, otherwise false
48
 */
49 1698 Luisehahne
	public function is_group_match( $groups_list1 = '', $groups_list2 = '', &$matches = null )
50 1440 Luisehahne
	{
51
		if( $groups_list1 == '' ) { return false; }
52
		if( $groups_list2 == '' ) { return false; }
53
		if( !is_array($groups_list1) )
54
		{
55
			$groups_list1 = explode(',', $groups_list1);
56
		}
57
		if( !is_array($groups_list2) )
58
		{
59
			$groups_list2 = explode(',', $groups_list2);
60
		}
61
		$matches = array_intersect( $groups_list1, $groups_list2);
62
		return ( sizeof($matches) != 0 );
63
	}
64
/* ****************
65 1373 Luisehahne
 * check if current user is member of at least one of given groups
66
 * ADMIN (uid=1) always is treated like a member of any groups
67
 *
68
 * @access public
69
 * @param mixed $groups_list: an array or a coma seperated list of group-ids
70
 * @return bool: true if current user is member of one of this groups, otherwise false
71
 */
72 1698 Luisehahne
	public function ami_group_member( $groups_list = '' )
73 1373 Luisehahne
	{
74
		if( $this->get_user_id() == 1 ) { return true; }
75
		return $this->is_group_match( $groups_list, $this->get_groups_id() );
76
	}
77
78 1365 Luisehahne
	// Check whether a page is visible or not.
79
	// This will check page-visibility and user- and group-rights.
80
	/* page_is_visible() returns
81
		false: if page-visibility is 'none' or 'deleted', or page-vis. is 'registered' or 'private' and user isn't allowed to see the page.
82
		true: if page-visibility is 'public' or 'hidden', or page-vis. is 'registered' or 'private' and user _is_ allowed to see the page.
83
	*/
84 1698 Luisehahne
	public function page_is_visible($page)
85 1365 Luisehahne
    {
86 1698 Luisehahne
		// First check if visibility is 'none', 'deleted'
87 1373 Luisehahne
		$show_it = false; // shall we show the page?
88 1698 Luisehahne
		switch( $page['visibility'] )
89
		{
90
			case 'none':
91
			case 'deleted':
92
				$show_it = false;
93
				break;
94
			case 'hidden':
95
			case 'public':
96
				$show_it = true;
97
				break;
98
			case 'private':
99
			case 'registered':
100
				if($this->is_authenticated() == true)
101
				{
102
					$show_it = ( $this->is_group_match($this->get_groups_id(), $page['viewing_groups']) ||
103
								 $this->is_group_match($this->get_user_id(), $page['viewing_users']) );
104
				}
105 1373 Luisehahne
		}
106
107 1365 Luisehahne
		return($show_it);
108
	}
109 1698 Luisehahne
110 1365 Luisehahne
	// Check if there is at least one active section on this page
111 1698 Luisehahne
	public function page_is_active($page)
112 1365 Luisehahne
    {
113
		global $database;
114
		$now = time();
115 1698 Luisehahne
		$sql  = 'SELECT COUNT(*) FROM `'.TABLE_PREFIX.'sections` ';
116
		$sql .= 'WHERE ('.$now.' BETWEEN `publ_start` AND `publ_end`) OR ';
117
		$sql .=       '('.$now.' > `publ_start` AND `publ_end`=0) ';
118
		$sql .=       'AND `page_id`='.(int)$page['page_id'];
119
		return ($database->get_one($sql) != false);
120
   	}
121 1365 Luisehahne
122
	// Check whether we should show a page or not (for front-end)
123 1698 Luisehahne
	public function show_page($page)
124 1365 Luisehahne
    {
125 1698 Luisehahne
		if( !is_array($page) )
126
		{
127
			$sql  = 'SELECT `page_id`, `visibility`, `viewing_groups`, `viewing_users` ';
128
			$sql .= 'FROM `'.TABLE_PREFIX.'pages` WHERE `page_id`='.(int)$page;
129
			if( ($res_pages = $database->query($sql))!= null )
130
			{
131
				if( !($page = $res_pages->fetchRow()) ) { return false; }
132
			}
133
		}
134
		return ($this->page_is_visible($page) && $this->page_is_active($page));
135 1365 Luisehahne
	}
136
137
	// Check if the user is already authenticated or not
138 1698 Luisehahne
	public function is_authenticated() {
139 1487 DarkViper
		$retval = ( isset($_SESSION['USER_ID']) AND
140
		            $_SESSION['USER_ID'] != "" AND
141
		            is_numeric($_SESSION['USER_ID']));
142
        return $retval;
143 1365 Luisehahne
	}
144
145
	// Modified addslashes function which takes into account magic_quotes
146
	function add_slashes($input) {
147 1487 DarkViper
		if( get_magic_quotes_gpc() || (!is_string($input)) ) {
148 1365 Luisehahne
			return $input;
149
		}
150 1487 DarkViper
		return addslashes($input);
151 1365 Luisehahne
	}
152
153
	// Ditto for stripslashes
154
	// Attn: this is _not_ the counterpart to $this->add_slashes() !
155
	// Use stripslashes() to undo a preliminarily done $this->add_slashes()
156
	// The purpose of $this->strip_slashes() is to undo the effects of magic_quotes_gpc==On
157
	function strip_slashes($input) {
158
		if ( !get_magic_quotes_gpc() || ( !is_string($input) ) ) {
159
			return $input;
160
		}
161 1487 DarkViper
		return stripslashes($input);
162 1365 Luisehahne
	}
163
164
	// Escape backslashes for use with mySQL LIKE strings
165
	function escape_backslashes($input) {
166
		return str_replace("\\","\\\\",$input);
167
	}
168
169
	function page_link($link){
170
		// Check for :// in the link (used in URL's) as well as mailto:
171 1373 Luisehahne
		if(strstr($link, '://') == '' AND substr($link, 0, 7) != 'mailto:') {
172 1365 Luisehahne
			return WB_URL.PAGES_DIRECTORY.$link.PAGE_EXTENSION;
173
		} else {
174
			return $link;
175
		}
176
	}
177 1698 Luisehahne
178 1365 Luisehahne
	// Get POST data
179
	function get_post($field) {
180 1487 DarkViper
		return (isset($_POST[$field]) ? $_POST[$field] : null);
181 1365 Luisehahne
	}
182
183
	// Get POST data and escape it
184
	function get_post_escaped($field) {
185
		$result = $this->get_post($field);
186
		return (is_null($result)) ? null : $this->add_slashes($result);
187
	}
188 1698 Luisehahne
189 1365 Luisehahne
	// Get GET data
190
	function get_get($field) {
191 1487 DarkViper
		return (isset($_GET[$field]) ? $_GET[$field] : null);
192 1365 Luisehahne
	}
193
194
	// Get SESSION data
195
	function get_session($field) {
196 1487 DarkViper
		return (isset($_SESSION[$field]) ? $_SESSION[$field] : null);
197 1365 Luisehahne
	}
198
199
	// Get SERVER data
200
	function get_server($field) {
201 1487 DarkViper
		return (isset($_SERVER[$field]) ? $_SERVER[$field] : null);
202 1365 Luisehahne
	}
203
204
	// Get the current users id
205
	function get_user_id() {
206 1511 Luisehahne
		return $this->get_session('USER_ID');
207 1365 Luisehahne
	}
208
209 1373 Luisehahne
	// Get the current users group id
210 1365 Luisehahne
	function get_group_id() {
211 1511 Luisehahne
		return $this->get_session('GROUP_ID');
212 1365 Luisehahne
	}
213
214
	// Get the current users group ids
215
	function get_groups_id() {
216 1511 Luisehahne
		return explode(",", $this->get_session('GROUPS_ID'));
217 1365 Luisehahne
	}
218
219
	// Get the current users group name
220
	function get_group_name() {
221 1511 Luisehahne
		return implode(",", $this->get_session('GROUP_NAME'));
222 1365 Luisehahne
	}
223
224
	// Get the current users group name
225
	function get_groups_name() {
226 1511 Luisehahne
		return $this->get_session('GROUP_NAME');
227 1365 Luisehahne
	}
228
229
	// Get the current users username
230
	function get_username() {
231 1511 Luisehahne
		return $this->get_session('USERNAME');
232 1365 Luisehahne
	}
233
234
	// Get the current users display name
235
	function get_display_name() {
236 1511 Luisehahne
		return $this->get_session('DISPLAY_NAME');
237 1365 Luisehahne
	}
238
239
	// Get the current users email address
240
	function get_email() {
241 1511 Luisehahne
		return $this->get_session('EMAIL');
242 1365 Luisehahne
	}
243
244
	// Get the current users home folder
245
	function get_home_folder() {
246 1511 Luisehahne
		return $this->get_session('HOME_FOLDER');
247 1365 Luisehahne
	}
248
249
	// Get the current users timezone
250
	function get_timezone() {
251 1487 DarkViper
		return (isset($_SESSION['USE_DEFAULT_TIMEZONE']) ? '-72000' : $_SESSION['TIMEZONE']);
252 1365 Luisehahne
	}
253
254 1373 Luisehahne
	// Validate supplied email address
255
	function validate_email($email) {
256
		if(function_exists('idn_to_ascii')){ /* use pear if available */
257
			$email = idn_to_ascii($email);
258
		}else {
259
			require_once(WB_PATH.'/include/idna_convert/idna_convert.class.php');
260
			$IDN = new idna_convert();
261
			$email = $IDN->encode($email);
262
			unset($IDN);
263 1372 Luisehahne
		}
264 1378 Luisehahne
		// regex from NorHei 2011-01-11
265
		$retval = preg_match("/^((([!#$%&'*+\\-\/\=?^_`{|}~\w])|([!#$%&'*+\\-\/\=?^_`{|}~\w][!#$%&'*+\\-\/\=?^_`{|}~\.\w]{0,}[!#$%&'*+\\-\/\=?^_`{|}~\w]))[@]\w+(([-.]|\-\-)\w+)*\.\w+(([-.]|\-\-)\w+)*)$/", $email);
266
		return ($retval != false);
267 1372 Luisehahne
	}
268
269 1698 Luisehahne
	/**
270
	 * wb::send_header()
271
     * replace header('Location:...  with new method
272
	 * if header send failed you get a manuell redirected link, so script don't break
273
	 * @param string $location, redirected url
274
	 * @return void
275
	 */
276
	public function send_header ($location) {
277
		if(!headers_sent()) {
278
			header('Location: '.$location);
279
		    exit(0);
280
		} else {
281
//			$aDebugBacktrace = debug_backtrace();
282
//			array_walk( $aDebugBacktrace, create_function( '$a,$b', 'print "<br /><b>". basename( $a[\'file\'] ). "</b> &nbsp; <font color=\"red\">{$a[\'line\']}</font> &nbsp; <font color=\"green\">{$a[\'function\']} ()</font> &nbsp; -- ". dirname( $a[\'file\'] ). "/";' ) );
283
		    $msg =  "<div style=\"text-align:center;\"><h2>An error has occurred</h2><p>The <strong>Redirect</strong> could not be start automatically.\n" .
284
		         "Please click <a style=\"font-weight:bold;\" " .
285
		         "href=\"".$location."\">on this link</a> to continue!</p></div>\n";
286
287
			throw new AppException($msg);
288
		}
289
	}
290
291 1372 Luisehahne
/* ****************
292 1365 Luisehahne
 * set one or more bit in a integer value
293
 *
294
 * @access public
295
 * @param int $value: reference to the integer, containing the value
296
 * @param int $bits2set: the bitmask witch shall be added to value
297
 * @return void
298
 */
299
	function bit_set( &$value, $bits2set )
300
	{
301
		$value |= $bits2set;
302
	}
303
304
/* ****************
305
 * reset one or more bit from a integer value
306
 *
307
 * @access public
308
 * @param int $value: reference to the integer, containing the value
309
 * @param int $bits2reset: the bitmask witch shall be removed from value
310
 * @return void
311
 */
312
	function bit_reset( &$value, $bits2reset)
313
	{
314
		$value &= ~$bits2reset;
315
	}
316
317
/* ****************
318
 * check if one or more bit in a integer value are set
319
 *
320
 * @access public
321
 * @param int $value: reference to the integer, containing the value
322
 * @param int $bits2set: the bitmask witch shall be added to value
323
 * @return void
324
 */
325
	function bit_isset( $value, $bits2test )
326
	{
327
		return (($value & $bits2test) == $bits2test);
328
	}
329
330
	// Print a success message which then automatically redirects the user to another page
331 1373 Luisehahne
	function print_success( $message, $redirect = 'index.php' ) {
332 1365 Luisehahne
	    global $TEXT;
333 1443 Luisehahne
        if(is_array($message)) {
334
           $message = implode ('<br />',$message);
335
        }
336 1373 Luisehahne
	    // fetch redirect timer for sucess messages from settings table
337 1397 Luisehahne
	    $redirect_timer = ((defined( 'REDIRECT_TIMER' )) && (REDIRECT_TIMER <= 10000)) ? REDIRECT_TIMER : 0;
338 1365 Luisehahne
	    // add template variables
339 1529 Luisehahne
		// Setup template object, parse vars to it, then parse it
340 1625 Luisehahne
		$tpl = new Template(dirname($this->correct_theme_source('success.htt')));
341 1365 Luisehahne
	    $tpl->set_file( 'page', 'success.htt' );
342
	    $tpl->set_block( 'page', 'main_block', 'main' );
343 1373 Luisehahne
	    $tpl->set_block( 'main_block', 'show_redirect_block', 'show_redirect' );
344
	    $tpl->set_var( 'MESSAGE', $message );
345
	    $tpl->set_var( 'REDIRECT', $redirect );
346
	    $tpl->set_var( 'REDIRECT_TIMER', $redirect_timer );
347 1372 Luisehahne
	    $tpl->set_var( 'NEXT', $TEXT['NEXT'] );
348
	    $tpl->set_var( 'BACK', $TEXT['BACK'] );
349 1397 Luisehahne
	    if ($redirect_timer == -1) {
350 1365 Luisehahne
	        $tpl->set_block( 'show_redirect', '' );
351 1373 Luisehahne
	    }
352
	    else {
353 1365 Luisehahne
	        $tpl->parse( 'show_redirect', 'show_redirect_block', true );
354
	    }
355
	    $tpl->parse( 'main', 'main_block', false );
356
	    $tpl->pparse( 'output', 'page' );
357
	}
358
359
	// Print an error message
360 1373 Luisehahne
	function print_error($message, $link = 'index.php', $auto_footer = true) {
361 1365 Luisehahne
		global $TEXT;
362 1443 Luisehahne
        if(is_array($message)) {
363
           $message = implode ('<br />',$message);
364
        }
365 1529 Luisehahne
		// Setup template object, parse vars to it, then parse it
366 1625 Luisehahne
		$success_template = new Template(dirname($this->correct_theme_source('error.htt')));
367 1365 Luisehahne
		$success_template->set_file('page', 'error.htt');
368
		$success_template->set_block('page', 'main_block', 'main');
369
		$success_template->set_var('MESSAGE', $message);
370
		$success_template->set_var('LINK', $link);
371
		$success_template->set_var('BACK', $TEXT['BACK']);
372
		$success_template->parse('main', 'main_block', false);
373
		$success_template->pparse('output', 'page');
374
		if ( $auto_footer == true ) {
375
			if ( method_exists($this, "print_footer") ) {
376
				$this->print_footer();
377
			}
378
		}
379
		exit();
380
	}
381 1684 Luisehahne
/*
382
 * @param string $message: the message to format
383
 * @param string $status:  ('ok' / 'error' / '') status defines the apereance of the box
384
 * @return string: the html-formatted message (using template 'message.htt')
385
 */
386
	public function format_message($message, $status = 'ok')
387
	{
388
		$id = uniqid('x');
389
		$tpl = new Template(dirname($this->correct_theme_source('message.htt')));
390
		$tpl->set_file('page', 'message.htt');
391
		$tpl->set_block('page', 'main_block', 'main');
392
		$tpl->set_var('MESSAGE', $message);
393
 	    $tpl->set_var( 'THEME_URL', THEME_URL );
394
		$tpl->set_var( 'ID', $id );
395
		if($status == 'ok' || $status == 'error' || $status = 'warning')
396
		{
397
			$tpl->set_var('BOX_STATUS', ' box-'.$status);
398
		}else
399
		{
400
			$tpl->set_var('BOX_STATUS', '');
401
		}
402
		$tpl->set_var('STATUS', $status);
403
		if(!defined('REDIRECT_TIMER') ) { define('REDIRECT_TIMER', -1); }
404
		$retval = '';
405
		if( $status != 'error' )
406
		{
407
			switch(REDIRECT_TIMER):
408
				case 0: // do not show message
409
					unset($tpl);
410
					break;
411
				case -1: // show message permanently
412
					$tpl->parse('main', 'main_block', false);
413
					$retval = $tpl->finish($tpl->parse('output', 'page', false));
414
					unset($tpl);
415
					break;
416
				default: // hide message after REDIRECTOR_TIMER milliseconds
417
					$retval = '<script type="text/javascript">/* <![CDATA[ */ function '.$id.'_hide() {'.
418
							  'document.getElementById(\''.$id.'\').style.display = \'none\';}'.
419
							  'window.setTimeout(\''.$id.'_hide()\', '.REDIRECT_TIMER.');/* ]]> */ </script>';
420
					$tpl->parse('main', 'main_block', false);
421
					$retval = $tpl->finish($tpl->parse('output', 'page', false)).$retval;
422
					unset($tpl);
423
			endswitch;
424
		}else
425
		{
426
			$tpl->parse('main', 'main_block', false);
427
			$retval = $tpl->finish($tpl->parse('output', 'page', false)).$retval;
428
			unset($tpl);
429
		}
430
		return $retval;
431
	}
432 1365 Luisehahne
433
	// Validate send email
434 1650 darkviper
	function mail($fromaddress, $toaddress, $subject, $message, $fromname='', $replyTo='') {
435 1698 Luisehahne
/*
436 1487 DarkViper
	INTEGRATED OPEN SOURCE PHPMAILER CLASS FOR SMTP SUPPORT AND MORE
437
	SOME SERVICE PROVIDERS DO NOT SUPPORT SENDING MAIL VIA PHP AS IT DOES NOT PROVIDE SMTP AUTHENTICATION
438
	NEW WBMAILER CLASS IS ABLE TO SEND OUT MESSAGES USING SMTP WHICH RESOLVE THESE ISSUE (C. Sommer)
439 1365 Luisehahne
440 1487 DarkViper
	NOTE:
441
	To use SMTP for sending out mails, you have to specify the SMTP host of your domain
442
	via the Settings panel in the backend of Website Baker
443 1698 Luisehahne
*/
444 1365 Luisehahne
445
		$fromaddress = preg_replace('/[\r\n]/', '', $fromaddress);
446
		$toaddress = preg_replace('/[\r\n]/', '', $toaddress);
447
		$subject = preg_replace('/[\r\n]/', '', $subject);
448 1650 darkviper
		$replyTo = preg_replace('/[\r\n]/', '', $replyTo);
449 1463 Luisehahne
		// $message_alt = $message;
450
		// $message = preg_replace('/[\r\n]/', '<br \>', $message);
451
452 1365 Luisehahne
		// create PHPMailer object and define default settings
453
		$myMail = new wbmailer();
454
		// set user defined from address
455
		if ($fromaddress!='') {
456 1487 DarkViper
			if($fromname!='') $myMail->FromName = $fromname;  // FROM-NAME
457
			$myMail->From = $fromaddress;                     // FROM:
458 1650 darkviper
//			$myMail->AddReplyTo($fromaddress);                // REPLY TO:
459
		}
460
		if($replyTo) {
461 1655 Luisehahne
			$myMail->AddReplyTo($replyTo);                // REPLY TO:
462 1365 Luisehahne
		}
463
		// define recepient and information to send out
464 1487 DarkViper
		$myMail->AddAddress($toaddress);                      // TO:
465
		$myMail->Subject = $subject;                          // SUBJECT
466
		$myMail->Body = nl2br($message);                      // CONTENT (HTML)
467
		$myMail->AltBody = strip_tags($message);              // CONTENT (TEXT)
468 1365 Luisehahne
		// check if there are any send mail errors, otherwise say successful
469
		if (!$myMail->Send()) {
470
			return false;
471
		} else {
472
			return true;
473
		}
474
	}
475
476 1625 Luisehahne
	 /**
477
	  * checks if there is an alternative Theme template
478
	  *
479
	  * @param string $sThemeFile set the template.htt
480
	  * @return string the relative theme path
481
	  *
482
	  */
483
        function correct_theme_source($sThemeFile = 'start.htt') {
484
		$sRetval = $sThemeFile;
485
		if (file_exists(THEME_PATH.'/templates/'.$sThemeFile )) {
486
			$sRetval = THEME_PATH.'/templates/'.$sThemeFile;
487
		} else {
488 1641 Luisehahne
			if (file_exists(ADMIN_PATH.'/skel/themes/htt/'.$sThemeFile ) ) {
489
			$sRetval = ADMIN_PATH.'/skel/themes/htt/'.$sThemeFile;
490 1625 Luisehahne
			} else {
491
				throw new InvalidArgumentException('missing template file '.$sThemeFile);
492
			}
493
		}
494
		return $sRetval;
495
        }
496 1529 Luisehahne
497
	/**
498
	 * Check if a foldername doesn't have invalid characters
499
	 *
500
	 * @param String $str to check
501
	 * @return Bool
502
	 */
503
	function checkFolderName($str){
504
		return !( preg_match('#\^|\\\|\/|\.|\?|\*|"|\'|\<|\>|\:|\|#i', $str) ? TRUE : FALSE );
505
	}
506
507
	/**
508
	 * Check the given path to make sure current path is within given basedir
509
	 * normally document root
510
	 *
511
	 * @param String $sCurrentPath
512
	 * @param String $sBaseDir
513
	 * @return $sCurrentPath or FALSE
514
	 */
515
	function checkpath($sCurrentPath, $sBaseDir = WB_PATH){
516
		// Clean the cuurent path
517
        $sCurrentPath = rawurldecode($sCurrentPath);
518
        $sCurrentPath = realpath($sCurrentPath);
519
        $sBaseDir = realpath($sBaseDir);
520
		// $sBaseDir needs to exist in the $sCurrentPath
521
		$pos = stripos ($sCurrentPath, $sBaseDir );
522
523
		if ( $pos === FALSE ){
524
			return false;
525
		} elseif( $pos == 0 ) {
526
			return $sCurrentPath;
527
		} else {
528
			return false;
529
		}
530
	}
531
532 1365 Luisehahne
}