Mercurial > hg > drupalISMI
comparison ISMIBioFilter/ISMIBioFilter.module @ 0:124ef8f3b22d
initial
author | Dirk Wintergruen <dwinter@mpiwg-berlin.mpg.de> |
---|---|
date | Fri, 27 Mar 2015 19:21:42 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:124ef8f3b22d |
---|---|
1 <?php | |
2 | |
3 /** | |
4 * @file | |
5 * Provides a Markdown input filter. | |
6 */ | |
7 | |
8 | |
9 | |
10 | |
11 function ISMIBioFilter_menu(){ | |
12 $items['showBio/%'] = array( | |
13 'title' => 'View', | |
14 'description' => 'show an object.', | |
15 'page callback' => 'ISMIBioFilter_showBio_page', | |
16 'access arguments' => array('access content'), | |
17 'page arguments' => array(1), | |
18 | |
19 'access arguments' => array('access content'), | |
20 'type' => MENU_LOCAL_TASK, | |
21 | |
22 ); | |
23 | |
24 $items['showEntity/%'] = array( | |
25 'title' => 'View', | |
26 'description' => 'show an object.', | |
27 'page callback' => 'ISMIBioFilter_showEntity_page', | |
28 'access arguments' => array('access content'), | |
29 'page arguments' => array(1), | |
30 | |
31 'access arguments' => array('access content'), | |
32 'type' => MENU_LOCAL_TASK, | |
33 | |
34 ); | |
35 | |
36 | |
37 return $items; | |
38 | |
39 | |
40 } | |
41 | |
42 | |
43 function ISMIBioFilter_showEntity_page($keys){ | |
44 #$results = db_query("SELECT * FROM {field_data_field_id} n where field_id_value ='" . $keys . "' and bundle = 'openmind_entity' "); | |
45 #$results = db_query("SELECT * FROM {field_data_field_id} n where field_id_value ='" . $keys . "' "); | |
46 | |
47 $query = new EntityFieldQuery; | |
48 $query->entityCondition('entity_type', 'node') | |
49 ->entityCondition('bundle', 'openmind_entity') | |
50 ->fieldCondition('field_id', 'value',$value = $keys); | |
51 $results = $query->execute(); | |
52 | |
53 if (isset($results['node'])){ | |
54 $nids = array_keys($results['node']); | |
55 | |
56 foreach ($nids as $nid){ | |
57 | |
58 drupal_goto("node/" . $nid); | |
59 } | |
60 } else { | |
61 drupal_goto("/unknownEntity"); | |
62 } | |
63 | |
64 } | |
65 | |
66 function ISMIBioFilter_showBio_page($keys){ | |
67 ##$results = db_query("SELECT * FROM {field_data_field_original_url} n where field_original_url_value ='" . $keys . "'"); | |
68 | |
69 # zerlege den string | |
70 $paths = explode("/",$keys); | |
71 #gebraucht wird nur der letzte teil | |
72 | |
73 $fn = $paths[sizeof(paths)-1]; | |
74 dpm($fn); | |
75 dpm($keys); | |
76 drupal_goto($fn); | |
77 #foreach ($results as $result){ | |
78 # drupal_goto("node/" . $result->entity_id); | |
79 #} | |
80 } | |
81 /** | |
82 * Implements hook_help(). | |
83 */ | |
84 function ISMIBioFilter_help($path, $arg) { | |
85 switch ($path) { | |
86 case 'admin/help#ISMIBioFilter': | |
87 return t('<p> Filters the original biographies to make the Drupal compatible.</p>'); | |
88 } | |
89 } | |
90 | |
91 /** | |
92 * Implements hook_filter_info(). | |
93 */ | |
94 function ISMIBioFilter_filter_info() { | |
95 $filters['filter_ISMIBioFilter'] = array( | |
96 'title' => t('ISMIBioFilter'), | |
97 'description' => t('Filter for the Biographies from the Springer Website'), | |
98 'process callback' => '_filter_ISMIBioFilter', | |
99 'settings callback' => '_filter_ISMIBioFilter_settings', | |
100 'tips callback' => '_filter_ISMIBioFilter_tips', | |
101 ); | |
102 | |
103 return $filters; | |
104 } | |
105 | |
106 | |
107 function _ISMIBioFilter_getSources($rel){ | |
108 $vals = array(); | |
109 $relNode = relation_load($rel->rid); | |
110 $eps = relation_get_endpoints($relNode); | |
111 foreach($eps as $ep){ | |
112 | |
113 $vals[]=array_shift(array_values($ep)); | |
114 | |
115 } | |
116 | |
117 return $vals; | |
118 } | |
119 | |
120 function _ISMIBioFilter_getTargets($rel){ | |
121 $vals = array(); | |
122 $relNode = relation_load($rel->rid); | |
123 $eps = relation_get_endpoints($relNode); | |
124 foreach($eps as $ep){ | |
125 | |
126 $ar = array_values($ep); | |
127 array_shift($ar); | |
128 $vals[]=array_shift($ar); | |
129 } | |
130 | |
131 return $vals; | |
132 } | |
133 | |
134 | |
135 /** | |
136 * Returns the ISMIBioFilter input filter tips. | |
137 * @TODO: make it easier for translators. | |
138 */ | |
139 function _filter_ISMIBioFilter_tips($format, $long = FALSE) { | |
140 if ($long) { | |
141 return t('no tip'); | |
142 } | |
143 else { | |
144 return t('no tip'); | |
145 } | |
146 } | |
147 | |
148 /** | |
149 * Implements hook_block_view(). | |
150 */ | |
151 function ISMIBioFilter_block_view($delta = '') { | |
152 $block = array(); | |
153 switch ($delta) { | |
154 case 'ISMIBioFilter_help': | |
155 $block['title'] = t('ISMIBio filter tips'); | |
156 $block['content'] = _ISMIBioFilter_help_block(); | |
157 break; | |
158 | |
159 | |
160 case 'ISMIObjects_main': | |
161 // main info for an object | |
162 | |
163 $node = menu_get_object(); | |
164 | |
165 //node hat keine objektype dann mache nichts | |
166 if (!isset($node->field_oc)){ | |
167 break; | |
168 } | |
169 | |
170 $tid = $node->field_oc[LANGUAGE_NONE][0]['tid']; | |
171 $taxonomy = taxonomy_term_load($tid)->name; | |
172 | |
173 switch($taxonomy){ | |
174 | |
175 case 'PERSON': | |
176 $ov = $node->field_ov[LANGUAGE_NONE][0]['value']; | |
177 $nov = $node->field_nov[LANGUAGE_NONE][0]['value']; | |
178 $block['title'] = t('Person'); | |
179 //$block['content']= theme('ISMIPersons_main',array('node' => $node)); | |
180 | |
181 $rows[] = array("Name",$ov); | |
182 $rows[] = array("Normalisiert",$nov); | |
183 | |
184 $block['content']=theme('table', array('header' => null, 'rows' => $rows)); | |
185 | |
186 | |
187 //is_prime_alias_name_of,invOf_is_prime_alias_name_of, invOf_is_alias_name_of ,is_alias_name_of | |
188 $rels = relation_query("node",$node->nid)->execute(); | |
189 $prime_alias = ""; | |
190 $aliases = array(); | |
191 | |
192 foreach($rels as $rel){ | |
193 | |
194 switch($rel->relation_type){ | |
195 case "is_prime_alias_name_of": | |
196 $prime_alias = _ISMIBioFilter_getSources($rel); | |
197 break; | |
198 | |
199 case "is_alias_name_of": | |
200 $aliases = _ISMIBioFilter_getSources($rel); | |
201 break; | |
202 } | |
203 } | |
204 | |
205 $block['content'] .= theme("ISMIObject_aliases",array("prime_alias"=>$prime_alias,"aliases"=>$aliases)); | |
206 break; | |
207 | |
208 case 'TEXT': | |
209 $ov = $node->field_ov[LANGUAGE_NONE][0]['value']; | |
210 $nov = $node->field_nov[LANGUAGE_NONE][0]['value']; | |
211 $block['title'] = t('Text'); | |
212 //$block['content']= theme('ISMIPersons_main',array('node' => $node)); | |
213 | |
214 $rows[] = array("Title",$ov); | |
215 $rows[] = array("Normalisiert",$nov); | |
216 | |
217 $block['content']=theme('table', array('header' => null, 'rows' => $rows)); | |
218 $rels = relation_query("node",$node->nid)->execute(); | |
219 $prime_alias = ""; | |
220 $aliases = array(); | |
221 | |
222 foreach($rels as $rel){ | |
223 | |
224 switch($rel->relation_type){ | |
225 case "is_prime_alias_name_of": | |
226 $prime_alias = _ISMIBioFilter_getSources($rel); | |
227 break; | |
228 | |
229 case "is_alias_name_of": | |
230 $aliases = array_merge($aliases,_ISMIBioFilter_getSources($rel)); | |
231 break; | |
232 } | |
233 } | |
234 | |
235 $block['content'] .= theme("ISMIObject_aliases",array("prime_alias"=>$prime_alias,"aliases"=>$aliases)); | |
236 | |
237 } | |
238 | |
239 break; | |
240 | |
241 case 'ISMIObjects_titles': | |
242 | |
243 $node = menu_get_object(); | |
244 //node hat keine objektype dann mache nichts | |
245 if (!isset($node->field_oc)){ | |
246 break; | |
247 } | |
248 | |
249 | |
250 $tid = $node->field_oc[LANGUAGE_NONE][0]['tid']; | |
251 $taxonomy = taxonomy_term_load($tid)->name; | |
252 | |
253 switch($taxonomy){ | |
254 | |
255 case 'PERSON': | |
256 $rels = relation_query("node",$node->nid)->execute(); | |
257 | |
258 foreach($rels as $rel){ | |
259 | |
260 if ($rel->relation_type=="was_created_by"){ | |
261 $relNode = relation_load($rel->rid); | |
262 $targets = relation_get_endpoints($relNode); | |
263 foreach($targets as $target){ | |
264 | |
265 $titles[]=array_shift(array_values($target)); | |
266 | |
267 | |
268 | |
269 | |
270 } | |
271 } | |
272 } | |
273 | |
274 $block['title'] = t('Titles'); | |
275 $block['content']= theme('ISMIPersons_titles',array('titles' => $titles)); | |
276 | |
277 } | |
278 break; | |
279 | |
280 case 'ISMIText_witnesses': | |
281 $node = menu_get_object(); | |
282 //node hat keine objektype dann mache nichts | |
283 if (!isset($node->field_oc)){ | |
284 break; | |
285 } | |
286 | |
287 | |
288 $tid = $node->field_oc[LANGUAGE_NONE][0]['tid']; | |
289 $taxonomy = taxonomy_term_load($tid)->name; | |
290 | |
291 switch($taxonomy){ | |
292 | |
293 case 'TEXT': | |
294 $rels = relation_query("node",$node->nid)->execute(); | |
295 $titles=array(); | |
296 foreach($rels as $rel){ | |
297 | |
298 if ($rel->relation_type=="is_exemplar_of"){ | |
299 $titles = array_merge($titles,_ISMIBioFilter_getSources($rel)); | |
300 | |
301 } | |
302 } | |
303 | |
304 _ISMIBioFilter_enrich($titles); | |
305 | |
306 $block['title'] = t('Witnesses'); | |
307 //$block['content']= theme('ISMIWitnesses_list',array('witnesses' => $titles)); | |
308 | |
309 // create table | |
310 $rows=array(); | |
311 | |
312 foreach ($titles as $witness){ | |
313 | |
314 $rows[]=array( | |
315 l($witness->field_nov[LANGUAGE_NONE][0]['value'],$witness->nid), | |
316 l($witness->codex->field_nov[LANGUAGE_NONE][0]['value'],$witness->codex->nid), | |
317 l($witness->collection->field_nov[LANGUAGE_NONE][0]['value'],$witness->collection->nid), | |
318 l($witness->repository->field_nov[LANGUAGE_NONE][0]['value'],$witness->repository->nid), | |
319 l($witness->place->field_nov[LANGUAGE_NONE][0]['value'],$witness->place->nid) | |
320 ); | |
321 } | |
322 | |
323 $header = array("witness","codex","collection","repository","place"); | |
324 $block['content'] = array( | |
325 '#theme' => 'table', | |
326 '#header' => $header, | |
327 '#rows' => $rows, | |
328 ); | |
329 #$block['content'] = theme("table",array('header'=>null,'rows'=>$rows)); | |
330 } | |
331 break; | |
332 | |
333 | |
334 case 'ISMIPersons_bea': | |
335 $node = menu_get_object(); | |
336 //node hat keine objektype dann mache nichts | |
337 if (!isset($node->field_oc)){ | |
338 break; | |
339 } | |
340 | |
341 $tid = $node->field_oc[LANGUAGE_NONE][0]['tid']; | |
342 $taxonomy = taxonomy_term_load($tid)->name; | |
343 switch($taxonomy){ | |
344 | |
345 case 'PERSON': | |
346 | |
347 | |
348 | |
349 $author_id = $node->field_id[LANGUAGE_NONE][0]['value']; | |
350 | |
351 | |
352 $query = new EntityFieldQuery; | |
353 $query->entityCondition('entity_type', 'node') | |
354 ->entityCondition('bundle', 'biography') | |
355 ->fieldCondition('field_id', 'value',$value = $author_id); | |
356 $results = $query->execute(); | |
357 | |
358 if (isset($results['node'])){ | |
359 $nids = array_keys($results['node']); | |
360 | |
361 foreach ($nids as $nid){ | |
362 | |
363 $body = entity_load_single("node", $nid)->body[LANGUAGE_NONE][0]['value']; | |
364 | |
365 $block['title'] = t('BEA'); | |
366 $block['content']= $body; | |
367 } | |
368 } | |
369 } | |
370 break; | |
371 | |
372 | |
373 case 'ISMIObjects_relations': | |
374 $node = menu_get_object(); | |
375 $author_id = $node->field_id[LANGUAGE_NONE][0]['value']; | |
376 | |
377 | |
378 $rels = relation_query("node",$node->nid)->execute(); | |
379 | |
380 $block['content'] = ISMIBioFilter_RelationsFormat("node",$node,$rels); | |
381 | |
382 break; | |
383 } | |
384 | |
385 return $block; | |
386 } | |
387 | |
388 /** | |
389 * Implements hook_block_info(). | |
390 */ | |
391 function ISMIBioFilter_block_info() { | |
392 $blocks = array(); | |
393 $blocks['ISMIBioFilter_help'] = array( | |
394 'info' => t('ISMI Bio filter tips'), | |
395 ); | |
396 $blocks['ISMIObjects_main'] = array( | |
397 'info' => t('ISMI Main information of an object'), | |
398 ); | |
399 | |
400 $blocks['ISMIObjects_titles'] = array( | |
401 'info' => t('ISMI Titles related to an object'), | |
402 ); | |
403 | |
404 $blocks['ISMIPersons_bea'] = array( | |
405 'info' => t('ISMI Bea Entry of Person'), | |
406 ); | |
407 | |
408 $blocks['ISMIObjects_relations'] = array( | |
409 'info' => t('ISMI all relations'), | |
410 ); | |
411 | |
412 $blocks['ISMIText_witnesses'] = array( | |
413 'info' => t('ISMI witnesses'), | |
414 ); | |
415 | |
416 return $blocks; | |
417 } | |
418 | |
419 /** | |
420 * Provides content for the ISMIBioFilter help block. | |
421 */ | |
422 function _ISMIBioFilter_help_block() { | |
423 return '<pre>' . t('Replaces external links to authors in the text to links to nodes in this website. ') . '</pre>'; | |
424 } | |
425 | |
426 /** | |
427 * | |
428 * Filter process callback. | |
429 */ | |
430 function _filter_ISMIBioFilter($text, $format) { | |
431 if (!empty($text)) { | |
432 | |
433 $params = drupal_get_query_parameters(); | |
434 | |
435 $text=preg_replace('/href="([^>]+?_BEA.htm)"\>/', 'href="$1">', $text); | |
436 | |
437 $text=preg_replace('#</span>\n#',"</span>",$text); #remove returns nach span otherwise this gives an extra space | |
438 | |
439 $text=preg_replace('#style="[^"]+#',"",$text); #remove all style information | |
440 | |
441 | |
442 } | |
443 | |
444 return $text; | |
445 } | |
446 | |
447 /** | |
448 * Filter settings callback. Just provides a version overview. | |
449 */ | |
450 function _filter_ISMIBioFilter_settings($form, &$form_state, $filter, $format, $defaults) { | |
451 module_load_include('php', 'ISMIBioFilter', 'ISMIBioFilter'); | |
452 | |
453 $settings['ISMIBioFilter_wrapper'] = array( | |
454 '#type' => 'fieldset', | |
455 '#title' => t('ISMIBioFilter'), | |
456 ); | |
457 $links = array('NO LINK', | |
458 /*'Markdown PHP Version: <a href="http://michelf.com/projects/php-ISMIBioFilter/">' . MARKDOWN_VERSION . '</a>', | |
459 'Markdown Extra Version: <a href="http://michelf.com/projects/php-ISMIBioFilter/">' . MARKDOWNEXTRA_VERSION . '</a>',*/ | |
460 ); | |
461 $settings['ISMIBioFilter_wrapper']['ISMIBioFilter_status'] = array( | |
462 '#title' => t('Versions'), | |
463 '#type' => 'item', | |
464 '#markup' => theme('item_list', array('items' => $links)), | |
465 ); | |
466 | |
467 return $settings; | |
468 } | |
469 | |
470 | |
471 /* add id to url */ | |
472 | |
473 function ISMIBioFilter_addIDs(){ | |
474 $txt = file_get_contents(drupal_get_path("module", "ISMIBioFilter") . "/bio2ismi.txt"); | |
475 $lines = explode("\n",$txt); | |
476 foreach ($lines as $line){ | |
477 $content = explode(" ",$line); | |
478 $id = $content[0]; | |
479 $origPath=$content[sizeof($content)-1]; | |
480 $path = explode("/",$origPath); | |
481 $url = $path[sizeof($path)-1]; | |
482 | |
483 | |
484 $nodePath = explode("/",drupal_lookup_path("source",$url)); | |
485 #$nodePath = explode("/",drupal_lookup_path("source",str_replace(".htm","",$url))); | |
486 | |
487 $nodeId = $nodePath[sizeof($nodePath)-1]; | |
488 | |
489 if ($nodeId != ""){ | |
490 $node = node_load($nodeId); | |
491 | |
492 $node->field_id[LANGUAGE_NONE][0]['value']=$id; | |
493 dpm($node); | |
494 | |
495 node_save($node); | |
496 } | |
497 } | |
498 | |
499 | |
500 } | |
501 | |
502 | |
503 function ISMIBioFilter_field_formatter_info(){ | |
504 return array( | |
505 // This formatter shows the obejct with fullmetadata | |
506 'ISMIBioFilter_entityLink' => array( | |
507 'label' => t('Entity Link Formatter'), | |
508 'field types' => array('text'), | |
509 ), | |
510 ); | |
511 } | |
512 | |
513 function ISMIBioFilter_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) { | |
514 $element = array(); | |
515 | |
516 #TODO make this configurable | |
517 $text ="Show data entry"; | |
518 | |
519 switch ($instance['label']){ | |
520 case 'author_id': | |
521 $text = "More about the author"; | |
522 } | |
523 | |
524 switch ($display['type']) { | |
525 // This formatter simply outputs the field as text and with a color. | |
526 case 'ISMIBioFilter_entityLink': | |
527 foreach ($items as $delta => $item) { | |
528 if ($item['value']!=""){ | |
529 | |
530 $element[$delta]['#markup'] = l($text,"showEntity/" . $item['value']); | |
531 | |
532 } | |
533 } | |
534 break; | |
535 | |
536 } | |
537 return $element; | |
538 } | |
539 | |
540 | |
541 | |
542 function ISMIBioFilter_theme(){ | |
543 | |
544 return array( | |
545 'ISMIObject_aliases' => array( | |
546 'variables' => array($prime_alias=null,$aliases=null), | |
547 'template' => 'ISMIObject-aliases', | |
548 ), | |
549 | |
550 'ISMIPersons_titles' => array( | |
551 'variables' => array('titles' => NULL), | |
552 'template' => 'ISMITitlesOfPerson', | |
553 ), | |
554 | |
555 'ISMIWitnesses_list' => array( | |
556 'variables' => array('witnesses' => NULL), | |
557 'template' => 'ISMIWitnesses-list', | |
558 ), | |
559 ); | |
560 } | |
561 | |
562 function ISMIBioFilter_RelationsFormat($entity_type,$entity,$rels){ | |
563 $ret =""; | |
564 $sentences = array(); | |
565 | |
566 | |
567 foreach ($rels as $item) { | |
568 list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity); | |
569 $relation = (object) relation_load($item->rid); | |
570 | |
571 $relation_type = relation_type_load($relation->relation_type); | |
572 | |
573 $subject = entity_label($entity_type, $entity) . ' '; // Subject of the sentence. | |
574 $subject_is_source = ($relation->endpoints[LANGUAGE_NONE]['0']['entity_id']) == $id ? TRUE : FALSE; | |
575 $count = 0; // For comma separation of objects. | |
576 $duplicate = FALSE; // To make sure duplicates of $entity get included in object list. | |
577 $objects = ''; // Comma separated list of entities that are the object of the sentence. | |
578 // Gramatical predicate of teh sentence. | |
579 $predicate = $relation_type->directional ? $relation_type->reverse_label : $relation_type->label; | |
580 | |
581 foreach ($relation->endpoints[LANGUAGE_NONE] as $endpoint) { | |
582 // Add all entities that aren't this entity to the sentence $objects. | |
583 // Check for duplicates of the $subject first. | |
584 if ($endpoint['entity_type'] == $entity_type && $endpoint['entity_id'] == $id && $duplicate == FALSE) { | |
585 $duplicate = TRUE; | |
586 // Use the forward label as sentence predicate if r_index == 0. | |
587 // (only makes a difference if relation is directional). | |
588 if ($endpoint['r_index'] == 0) { | |
589 $predicate = ' ' . $relation_type->label; | |
590 } | |
591 } | |
592 else { | |
593 // If the relation is directional and the subject isn't the source, | |
594 // we want to list the source without any siblings. If it is | |
595 // directional and the subject is a source, list all targets. | |
596 // If non-directional, list everything as normal. | |
597 if (!$relation_type->directional || $subject_is_source || $endpoint['r_index'] == 0) { | |
598 $object_entities = entity_load($endpoint['entity_type'], array($endpoint['entity_id'])); | |
599 $object_entity = reset($object_entities); | |
600 $object_label = entity_label($endpoint['entity_type'], $object_entity); | |
601 $object_uri = entity_uri($endpoint['entity_type'], $object_entity); | |
602 // Just add a space before the first element, comma and space before further ones. | |
603 $objects .= $count ? ', ' : ' '; | |
604 $count += 1; | |
605 $objects .= l($object_label, $object_uri['path']); | |
606 | |
607 $ret .=theme('item_list',array('items' => array(".." . $predicate . $objects))); | |
608 } | |
609 } | |
610 | |
611 | |
612 } | |
613 | |
614 | |
615 | |
616 | |
617 } | |
618 | |
619 return $ret; | |
620 } | |
621 | |
622 function _ISMIBioFilter_non_indentical($tars,$nid){ | |
623 $ret=array(); | |
624 foreach($tars as $tar){ | |
625 if($tar->nid!=$nid){ | |
626 $ret[]=$tar; | |
627 } | |
628 } | |
629 return $ret; | |
630 } | |
631 function _ISMIBioFilter_enrich(&$titles){ | |
632 foreach($titles as $title){ | |
633 $title->codex=_ISMIBioFilter_find_unique_entity("is_part_of",$title->nid); | |
634 $title->collection=_ISMIBioFilter_find_unique_entity("is_part_of",$title->codex->nid); | |
635 $title->repository=_ISMIBioFilter_find_unique_entity("is_part_of",$title->collection->nid); | |
636 $title->place=_ISMIBioFilter_find_unique_entity("is_in",$title->repository->nid); | |
637 | |
638 } | |
639 } | |
640 | |
641 | |
642 | |
643 | |
644 | |
645 function _ISMIBioFilter_find_unique_entity($rel_type,$nid){ | |
646 $rels = relation_query("node",$nid)->execute(); | |
647 $is_in_place=array(); | |
648 foreach($rels as $rel){ | |
649 if ($rel->relation_type==$rel_type){ | |
650 $reps = _ISMIBioFilter_getTargets($rel); | |
651 $is_in_place = array_merge($is_in_place,_ISMIBioFilter_non_indentical($reps,$nid)); | |
652 } | |
653 | |
654 } | |
655 return $is_in_place[0]; | |
656 } | |
657 | |
658 | |
659 |