2011-02-03 00:23:24 +00:00
|
|
|
<?php
|
|
|
|
/*
|
|
|
|
* StatusNet - the distributed open-source microblogging tool
|
|
|
|
* Copyright (C) 2011, StatusNet, Inc.
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Affero General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (!defined('STATUSNET')) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2011-03-09 03:20:43 +00:00
|
|
|
/**
|
|
|
|
* Class to represent extended profile data
|
|
|
|
*/
|
2011-02-03 00:23:24 +00:00
|
|
|
class ExtendedProfile
|
|
|
|
{
|
2011-03-10 03:27:21 +00:00
|
|
|
protected $fields;
|
|
|
|
|
2011-03-09 03:20:43 +00:00
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*
|
|
|
|
* @param Profile $profile
|
2019-08-09 15:22:55 +01:00
|
|
|
* @throws NoSuchUserException
|
2011-03-09 03:20:43 +00:00
|
|
|
*/
|
2019-08-09 15:22:55 +01:00
|
|
|
public function __construct(Profile $profile)
|
2011-02-03 01:29:34 +00:00
|
|
|
{
|
2019-08-09 15:22:55 +01:00
|
|
|
$this->profile = $profile;
|
|
|
|
$this->user = $profile->getUser();
|
|
|
|
$this->fields = $this->loadFields();
|
2011-03-11 00:57:41 +00:00
|
|
|
$this->sections = $this->getSections();
|
|
|
|
//common_debug(var_export($this->sections, true));
|
|
|
|
|
2011-03-10 22:14:21 +00:00
|
|
|
//common_debug(var_export($this->fields, true));
|
2011-02-03 01:29:34 +00:00
|
|
|
}
|
|
|
|
|
2011-03-09 03:20:43 +00:00
|
|
|
/**
|
|
|
|
* Load extended profile fields
|
|
|
|
*
|
|
|
|
* @return array $fields the list of fields
|
2019-08-09 15:22:55 +01:00
|
|
|
* @throws Exception
|
2011-03-09 03:20:43 +00:00
|
|
|
*/
|
2019-08-09 15:22:55 +01:00
|
|
|
public function loadFields()
|
2011-02-03 01:29:34 +00:00
|
|
|
{
|
|
|
|
$detail = new Profile_detail();
|
2015-07-17 11:46:09 +01:00
|
|
|
$detail->profile_id = $this->profile->getID();
|
2011-02-03 01:29:34 +00:00
|
|
|
$detail->find();
|
2011-03-08 05:34:57 +00:00
|
|
|
|
|
|
|
$fields = array();
|
|
|
|
|
|
|
|
while ($detail->fetch()) {
|
2011-03-10 02:00:24 +00:00
|
|
|
$fields[$detail->field_name][] = clone($detail);
|
2011-02-03 01:29:34 +00:00
|
|
|
}
|
2011-03-09 03:20:43 +00:00
|
|
|
|
2011-02-03 01:29:34 +00:00
|
|
|
return $fields;
|
|
|
|
}
|
|
|
|
|
2011-03-09 03:20:43 +00:00
|
|
|
/**
|
|
|
|
* Get a the self-tags associated with this profile
|
|
|
|
*
|
|
|
|
* @return string the concatenated string of tags
|
|
|
|
*/
|
2019-08-09 15:22:55 +01:00
|
|
|
public function getTags()
|
2011-03-09 03:20:43 +00:00
|
|
|
{
|
2015-07-17 11:46:09 +01:00
|
|
|
return implode(' ', Profile_tag::getSelfTagsArray($this->profile));
|
2011-03-09 03:20:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return a simple string value. Checks for fields that should
|
|
|
|
* be stored in the regular profile and returns values from it
|
|
|
|
* if appropriate.
|
|
|
|
*
|
|
|
|
* @param string $name name of the detail field to get the
|
|
|
|
* value from
|
|
|
|
*
|
|
|
|
* @return string the value
|
|
|
|
*/
|
2019-08-09 15:22:55 +01:00
|
|
|
public function getTextValue($name)
|
2011-03-09 03:20:43 +00:00
|
|
|
{
|
2019-08-09 15:22:55 +01:00
|
|
|
$key = strtolower($name);
|
2011-03-09 03:20:43 +00:00
|
|
|
$profileFields = array('fullname', 'location', 'bio');
|
|
|
|
|
2011-03-10 03:27:21 +00:00
|
|
|
if (in_array($key, $profileFields)) {
|
2011-03-09 03:20:43 +00:00
|
|
|
return $this->profile->$name;
|
2019-08-09 15:22:55 +01:00
|
|
|
} elseif (array_key_exists($key, $this->fields)) {
|
2011-03-10 03:27:21 +00:00
|
|
|
return $this->fields[$key][0]->field_value;
|
2011-03-09 03:20:43 +00:00
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-09 15:22:55 +01:00
|
|
|
public function getDateValue($name)
|
|
|
|
{
|
2011-03-16 08:09:38 +00:00
|
|
|
$key = strtolower($name);
|
|
|
|
if (array_key_exists($key, $this->fields)) {
|
|
|
|
return $this->fields[$key][0]->date;
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-03-15 17:10:18 +00:00
|
|
|
// XXX: getPhones, getIms, and getWebsites pretty much do the same thing,
|
|
|
|
// so refactor.
|
2019-08-09 15:22:55 +01:00
|
|
|
public function getPhones()
|
2011-03-10 22:14:21 +00:00
|
|
|
{
|
2011-03-14 08:49:46 +00:00
|
|
|
$phones = (isset($this->fields['phone'])) ? $this->fields['phone'] : null;
|
2011-03-11 00:57:41 +00:00
|
|
|
$pArrays = array();
|
|
|
|
|
|
|
|
if (empty($phones)) {
|
|
|
|
$pArrays[] = array(
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties.
|
2011-03-10 22:14:21 +00:00
|
|
|
'label' => _m('Phone'),
|
2011-03-13 23:32:13 +00:00
|
|
|
'index' => 0,
|
2019-08-09 15:22:55 +01:00
|
|
|
'type' => 'phone',
|
2011-03-11 00:57:41 +00:00
|
|
|
'vcard' => 'tel',
|
2019-08-09 15:22:55 +01:00
|
|
|
'rel' => 'office',
|
2011-03-14 08:49:46 +00:00
|
|
|
'value' => null
|
2011-03-11 00:57:41 +00:00
|
|
|
);
|
|
|
|
} else {
|
|
|
|
for ($i = 0; $i < sizeof($phones); $i++) {
|
|
|
|
$pa = array(
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties.
|
2011-03-11 00:57:41 +00:00
|
|
|
'label' => _m('Phone'),
|
2019-08-09 15:22:55 +01:00
|
|
|
'type' => 'phone',
|
2011-03-14 08:49:46 +00:00
|
|
|
'index' => intval($phones[$i]->value_index),
|
2019-08-09 15:22:55 +01:00
|
|
|
'rel' => $phones[$i]->rel,
|
2011-03-11 00:57:41 +00:00
|
|
|
'value' => $phones[$i]->field_value,
|
|
|
|
'vcard' => 'tel'
|
|
|
|
);
|
2011-03-14 08:49:46 +00:00
|
|
|
|
2019-08-09 15:22:55 +01:00
|
|
|
$pArrays[] = $pa;
|
2011-03-11 00:57:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return $pArrays;
|
2011-03-10 22:14:21 +00:00
|
|
|
}
|
|
|
|
|
2019-08-09 15:22:55 +01:00
|
|
|
public function getIms()
|
2011-03-15 05:38:34 +00:00
|
|
|
{
|
|
|
|
$ims = (isset($this->fields['im'])) ? $this->fields['im'] : null;
|
|
|
|
$iArrays = array();
|
|
|
|
|
|
|
|
if (empty($ims)) {
|
|
|
|
$iArrays[] = array(
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties (Instant Messaging).
|
2011-03-15 05:38:34 +00:00
|
|
|
'label' => _m('IM'),
|
|
|
|
'type' => 'im'
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
for ($i = 0; $i < sizeof($ims); $i++) {
|
|
|
|
$ia = array(
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties (Instant Messaging).
|
2011-03-15 05:38:34 +00:00
|
|
|
'label' => _m('IM'),
|
2019-08-09 15:22:55 +01:00
|
|
|
'type' => 'im',
|
2011-03-15 05:38:34 +00:00
|
|
|
'index' => intval($ims[$i]->value_index),
|
2019-08-09 15:22:55 +01:00
|
|
|
'rel' => $ims[$i]->rel,
|
2011-03-15 05:38:34 +00:00
|
|
|
'value' => $ims[$i]->field_value,
|
|
|
|
);
|
|
|
|
|
|
|
|
$iArrays[] = $ia;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $iArrays;
|
|
|
|
}
|
|
|
|
|
2019-08-09 15:22:55 +01:00
|
|
|
public function getWebsites()
|
2011-03-15 17:10:18 +00:00
|
|
|
{
|
|
|
|
$sites = (isset($this->fields['website'])) ? $this->fields['website'] : null;
|
|
|
|
$wArrays = array();
|
|
|
|
|
|
|
|
if (empty($sites)) {
|
|
|
|
$wArrays[] = array(
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties.
|
2011-03-15 17:10:18 +00:00
|
|
|
'label' => _m('Website'),
|
|
|
|
'type' => 'website'
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
for ($i = 0; $i < sizeof($sites); $i++) {
|
|
|
|
$wa = array(
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties.
|
2011-03-15 17:10:18 +00:00
|
|
|
'label' => _m('Website'),
|
2019-08-09 15:22:55 +01:00
|
|
|
'type' => 'website',
|
2011-03-15 17:10:18 +00:00
|
|
|
'index' => intval($sites[$i]->value_index),
|
2019-08-09 15:22:55 +01:00
|
|
|
'rel' => $sites[$i]->rel,
|
2011-03-15 17:10:18 +00:00
|
|
|
'value' => $sites[$i]->field_value,
|
|
|
|
);
|
|
|
|
|
|
|
|
$wArrays[] = $wa;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $wArrays;
|
|
|
|
}
|
|
|
|
|
2019-08-09 15:22:55 +01:00
|
|
|
public function getExperiences()
|
2011-03-14 22:29:11 +00:00
|
|
|
{
|
2011-03-15 00:27:50 +00:00
|
|
|
$companies = (isset($this->fields['company'])) ? $this->fields['company'] : null;
|
2011-03-14 22:29:11 +00:00
|
|
|
$start = (isset($this->fields['start'])) ? $this->fields['start'] : null;
|
2019-08-09 15:22:55 +01:00
|
|
|
$end = (isset($this->fields['end'])) ? $this->fields['end'] : null;
|
2011-03-14 22:29:11 +00:00
|
|
|
|
2011-03-15 00:27:50 +00:00
|
|
|
$eArrays = array();
|
2011-03-14 22:29:11 +00:00
|
|
|
|
2011-03-15 00:27:50 +00:00
|
|
|
if (empty($companies)) {
|
2011-03-14 22:29:11 +00:00
|
|
|
$eArrays[] = array(
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties.
|
2019-08-09 15:22:55 +01:00
|
|
|
'label' => _m('Employer'),
|
|
|
|
'type' => 'experience',
|
2011-03-15 00:27:50 +00:00
|
|
|
'company' => null,
|
2019-08-09 15:22:55 +01:00
|
|
|
'start' => null,
|
|
|
|
'end' => null,
|
2011-03-15 00:27:50 +00:00
|
|
|
'current' => false,
|
2019-08-09 15:22:55 +01:00
|
|
|
'index' => 0
|
2011-03-14 22:29:11 +00:00
|
|
|
);
|
2011-03-15 00:27:50 +00:00
|
|
|
} else {
|
|
|
|
for ($i = 0; $i < sizeof($companies); $i++) {
|
|
|
|
$ea = array(
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties.
|
2019-08-09 15:22:55 +01:00
|
|
|
'label' => _m('Employer'),
|
|
|
|
'type' => 'experience',
|
2011-03-15 00:27:50 +00:00
|
|
|
'company' => $companies[$i]->field_value,
|
2019-08-09 15:22:55 +01:00
|
|
|
'index' => intval($companies[$i]->value_index),
|
2011-03-15 00:27:50 +00:00
|
|
|
'current' => $end[$i]->rel,
|
2019-08-09 15:22:55 +01:00
|
|
|
'start' => $start[$i]->date,
|
|
|
|
'end' => $end[$i]->date
|
2011-03-15 00:27:50 +00:00
|
|
|
);
|
2019-08-09 15:22:55 +01:00
|
|
|
$eArrays[] = $ea;
|
2011-03-15 00:27:50 +00:00
|
|
|
}
|
2011-03-14 22:29:11 +00:00
|
|
|
}
|
|
|
|
return $eArrays;
|
|
|
|
}
|
|
|
|
|
2019-08-09 15:22:55 +01:00
|
|
|
public function getEducation()
|
2011-03-15 03:58:35 +00:00
|
|
|
{
|
|
|
|
$schools = (isset($this->fields['school'])) ? $this->fields['school'] : null;
|
|
|
|
$degrees = (isset($this->fields['degree'])) ? $this->fields['degree'] : null;
|
2011-03-15 05:02:24 +00:00
|
|
|
$descs = (isset($this->fields['degree_descr'])) ? $this->fields['degree_descr'] : null;
|
2011-03-15 03:58:35 +00:00
|
|
|
$start = (isset($this->fields['school_start'])) ? $this->fields['school_start'] : null;
|
|
|
|
$end = (isset($this->fields['school_end'])) ? $this->fields['school_end'] : null;
|
|
|
|
$iArrays = array();
|
|
|
|
|
|
|
|
if (empty($schools)) {
|
|
|
|
$iArrays[] = array(
|
|
|
|
'type' => 'education',
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties.
|
2011-03-15 03:58:35 +00:00
|
|
|
'label' => _m('Institution'),
|
|
|
|
'school' => null,
|
|
|
|
'degree' => null,
|
|
|
|
'description' => null,
|
|
|
|
'start' => null,
|
|
|
|
'end' => null,
|
|
|
|
'index' => 0
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
for ($i = 0; $i < sizeof($schools); $i++) {
|
|
|
|
$ia = array(
|
2019-08-09 15:22:55 +01:00
|
|
|
'type' => 'education',
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties.
|
2019-08-09 15:22:55 +01:00
|
|
|
'label' => _m('Institution'),
|
|
|
|
'school' => $schools[$i]->field_value,
|
|
|
|
'degree' => isset($degrees[$i]->field_value) ? $degrees[$i]->field_value : null,
|
2011-03-15 05:02:24 +00:00
|
|
|
'description' => isset($descs[$i]->field_value) ? $descs[$i]->field_value : null,
|
2019-08-09 15:22:55 +01:00
|
|
|
'index' => intval($schools[$i]->value_index),
|
|
|
|
'start' => $start[$i]->date,
|
|
|
|
'end' => $end[$i]->date
|
2011-03-15 03:58:35 +00:00
|
|
|
);
|
2019-08-09 15:22:55 +01:00
|
|
|
$iArrays[] = $ia;
|
2011-03-15 03:58:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $iArrays;
|
|
|
|
}
|
|
|
|
|
2011-03-09 03:20:43 +00:00
|
|
|
/**
|
|
|
|
* Return all the sections of the extended profile
|
|
|
|
*
|
|
|
|
* @return array the big list of sections and fields
|
2019-08-09 15:22:55 +01:00
|
|
|
* @throws Exception
|
2011-03-09 03:20:43 +00:00
|
|
|
*/
|
2019-08-09 15:22:55 +01:00
|
|
|
public function getSections()
|
2011-02-03 00:23:24 +00:00
|
|
|
{
|
2019-08-09 15:22:55 +01:00
|
|
|
$gsefields = GNUsocialProfileExtensionField::allFields();
|
|
|
|
$extra_fields = [];
|
|
|
|
gnusocial_profile_merge($this->profile);
|
|
|
|
foreach ($gsefields as $field) {
|
|
|
|
$field_key = $field->systemname;
|
|
|
|
switch ($field->type) {
|
|
|
|
case 'text':
|
|
|
|
$extra_fields[$field_key]['type'] = 'custom-textarea';
|
|
|
|
break;
|
|
|
|
case 'str':
|
|
|
|
default:
|
|
|
|
$extra_fields[$field_key]['type'] = 'custom-text';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
$extra_fields[$field_key]['label'] = $field->title;
|
|
|
|
$extra_fields[$field_key]['value'] = $this->profile->$field_key;
|
|
|
|
}
|
2011-02-03 00:23:24 +00:00
|
|
|
return array(
|
|
|
|
'basic' => array(
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties.
|
2011-02-03 00:23:24 +00:00
|
|
|
'label' => _m('Personal'),
|
|
|
|
'fields' => array(
|
|
|
|
'fullname' => array(
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties.
|
2011-02-03 00:23:24 +00:00
|
|
|
'label' => _m('Full name'),
|
|
|
|
'profile' => 'fullname',
|
|
|
|
'vcard' => 'fn',
|
|
|
|
),
|
|
|
|
'title' => array(
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties.
|
2011-02-03 00:23:24 +00:00
|
|
|
'label' => _m('Title'),
|
|
|
|
'vcard' => 'title',
|
|
|
|
),
|
|
|
|
'manager' => array(
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties.
|
2011-02-03 00:23:24 +00:00
|
|
|
'label' => _m('Manager'),
|
|
|
|
'type' => 'person',
|
|
|
|
'vcard' => 'x-manager',
|
|
|
|
),
|
|
|
|
'location' => array(
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties.
|
2011-02-03 00:23:24 +00:00
|
|
|
'label' => _m('Location'),
|
|
|
|
'profile' => 'location'
|
|
|
|
),
|
|
|
|
'bio' => array(
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties.
|
2011-02-03 00:23:24 +00:00
|
|
|
'label' => _m('Bio'),
|
|
|
|
'type' => 'textarea',
|
|
|
|
'profile' => 'bio',
|
|
|
|
),
|
|
|
|
'tags' => array(
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties.
|
2011-02-03 00:23:24 +00:00
|
|
|
'label' => _m('Tags'),
|
|
|
|
'type' => 'tags',
|
|
|
|
'profile' => 'tags',
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
'contact' => array(
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties.
|
2011-02-03 00:23:24 +00:00
|
|
|
'label' => _m('Contact'),
|
|
|
|
'fields' => array(
|
2019-08-09 15:22:55 +01:00
|
|
|
'phone' => $this->getPhones(),
|
|
|
|
'im' => $this->getIms(),
|
2011-03-15 17:10:18 +00:00
|
|
|
'website' => $this->getWebsites()
|
2011-02-03 00:23:24 +00:00
|
|
|
),
|
|
|
|
),
|
|
|
|
'personal' => array(
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties.
|
2011-02-03 00:23:24 +00:00
|
|
|
'label' => _m('Personal'),
|
|
|
|
'fields' => array(
|
|
|
|
'birthday' => array(
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties.
|
2011-02-03 00:23:24 +00:00
|
|
|
'label' => _m('Birthday'),
|
|
|
|
'type' => 'date',
|
|
|
|
'vcard' => 'bday',
|
|
|
|
),
|
|
|
|
'spouse' => array(
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties.
|
2011-02-03 00:23:24 +00:00
|
|
|
'label' => _m('Spouse\'s name'),
|
|
|
|
'vcard' => 'x-spouse',
|
|
|
|
),
|
|
|
|
'kids' => array(
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties.
|
2011-02-03 00:23:24 +00:00
|
|
|
'label' => _m('Kids\' names')
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
'experience' => array(
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties.
|
2011-02-03 00:23:24 +00:00
|
|
|
'label' => _m('Work experience'),
|
|
|
|
'fields' => array(
|
2011-03-15 03:58:35 +00:00
|
|
|
'experience' => $this->getExperiences()
|
2011-02-03 00:23:24 +00:00
|
|
|
),
|
|
|
|
),
|
|
|
|
'education' => array(
|
2011-04-07 21:25:16 +01:00
|
|
|
// TRANS: Field label for extended profile properties.
|
2011-02-03 00:23:24 +00:00
|
|
|
'label' => _m('Education'),
|
|
|
|
'fields' => array(
|
2011-03-15 03:58:35 +00:00
|
|
|
'education' => $this->getEducation()
|
2011-02-03 00:23:24 +00:00
|
|
|
),
|
|
|
|
),
|
2019-08-09 15:22:55 +01:00
|
|
|
'extra' => [
|
|
|
|
'label' => _m('Extra fields'),
|
|
|
|
'fields' => $extra_fields,
|
|
|
|
]
|
2011-02-03 00:23:24 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|