Exemple #1
0
 /**
  * get the person box stylesheet class for the given person
  *
  * @param WT_Individual $person
  *
  * @return string returns 'person_box', 'person_boxF', or 'person_boxNN'
  */
 function getPersonStyle($person)
 {
     switch ($person->getSex()) {
         case 'M':
             $class = 'person_box';
             break;
         case 'F':
             $class = 'person_boxF';
             break;
         default:
             $class = 'person_boxNN';
             break;
     }
     if ($person->isOld()) {
         $class .= ' old';
     } elseif ($person->isNew()) {
         $class .= ' new';
     }
     return $class;
 }
/**
 * print the information for an individual chart box
 *
 * find and print a given individuals information for a pedigree chart
 *
 * @param WT_Individual $person The person to print
 * @param int           $style  the style to print the box in, 1 for smaller boxes, 2 for larger boxes
 * @param int           $count  on some charts it is important to keep a count of how many boxes were printed
 * @param string        $personcount
 */
function print_pedigree_person($person, $style = 1, $count = 0, $personcount = "1")
{
    global $GEDCOM;
    global $SHOW_HIGHLIGHT_IMAGES, $bwidth, $bheight, $PEDIGREE_FULL_DETAILS, $SHOW_PEDIGREE_PLACES;
    global $TEXT_DIRECTION, $DEFAULT_PEDIGREE_GENERATIONS, $OLD_PGENS, $talloffset, $PEDIGREE_LAYOUT;
    global $chart_style, $box_width, $generations, $show_spouse, $show_full;
    global $CHART_BOX_TAGS, $SHOW_LDS_AT_GLANCE, $PEDIGREE_SHOW_GENDER;
    global $SEARCH_SPIDER;
    if ($style != 2) {
        $style = 1;
    }
    if (empty($show_full)) {
        $show_full = 0;
    }
    if (empty($PEDIGREE_FULL_DETAILS)) {
        $PEDIGREE_FULL_DETAILS = 0;
    }
    if (!isset($OLD_PGENS)) {
        $OLD_PGENS = $DEFAULT_PEDIGREE_GENERATIONS;
    }
    if (!isset($talloffset)) {
        $talloffset = $PEDIGREE_LAYOUT;
    }
    // NOTE: Start div out-rand()
    if (!$person) {
        echo "<div id=\"out-", Uuid::uuid4(), "\" class=\"person_boxNN\" style=\"width: ", $bwidth, "px; height: ", $bheight, "px; overflow: hidden;\">";
        echo '<br>';
        echo '</div>';
        return;
    }
    $pid = $person->getXref();
    if ($count == 0) {
        $count = rand();
    }
    $lbwidth = $bwidth * 0.75;
    if ($lbwidth < 150) {
        $lbwidth = 150;
    }
    $tmp = array('M' => '', 'F' => 'F', 'U' => 'NN');
    $isF = $tmp[$person->getSex()];
    $personlinks = '';
    $icons = '';
    $genderImage = '';
    $BirthDeath = '';
    $birthplace = '';
    $outBoxAdd = '';
    $showid = '';
    $iconsStyleAdd = 'float:right;';
    if ($TEXT_DIRECTION == 'rtl') {
        $iconsStyleAdd = 'float:left;';
    }
    $boxID = $pid . '.' . $personcount . '.' . $count . '.' . Uuid::uuid4();
    $mouseAction4 = " onclick=\"expandbox('" . $boxID . "', {$style}); return false;\"";
    if ($person->canShowName()) {
        if (empty($SEARCH_SPIDER)) {
            //-- draw a box for the family popup
            // NOTE: Start div I.$pid.$personcount.$count.links
            $personlinks .= '<ul class="person_box' . $isF . '">';
            $personlinks .= '<li><a href="pedigree.php?rootid=' . $pid . '&amp;show_full=' . $PEDIGREE_FULL_DETAILS . '&amp;PEDIGREE_GENERATIONS=' . $OLD_PGENS . '&amp;talloffset=' . $talloffset . '&amp;ged=' . rawurlencode($GEDCOM) . '"><b>' . WT_I18N::translate('Pedigree') . '</b></a></li>';
            if (array_key_exists('googlemap', WT_Module::getActiveModules())) {
                $personlinks .= '<li><a href="module.php?mod=googlemap&amp;mod_action=pedigree_map&amp;rootid=' . $pid . '&amp;ged=' . WT_GEDURL . '"><b>' . WT_I18N::translate('Pedigree map') . '</b></a></li>';
            }
            if (WT_USER_GEDCOM_ID && WT_USER_GEDCOM_ID != $pid) {
                $personlinks .= '<li><a href="relationship.php?show_full=' . $PEDIGREE_FULL_DETAILS . '&amp;pid1=' . WT_USER_GEDCOM_ID . '&amp;pid2=' . $pid . '&amp;show_full=' . $PEDIGREE_FULL_DETAILS . '&amp;pretty=2&amp;followspouse=1&amp;ged=' . WT_GEDURL . '"><b>' . WT_I18N::translate('Relationship to me') . '</b></a></li>';
            }
            $personlinks .= '<li><a href="descendancy.php?rootid=' . $pid . '&amp;show_full=' . $PEDIGREE_FULL_DETAILS . '&amp;generations=' . $generations . '&amp;box_width=' . $box_width . '&amp;ged=' . rawurlencode($GEDCOM) . '"><b>' . WT_I18N::translate('Descendants') . '</b></a></li>';
            $personlinks .= '<li><a href="ancestry.php?rootid=' . $pid . '&amp;show_full=' . $PEDIGREE_FULL_DETAILS . '&amp;chart_style=' . $chart_style . '&amp;PEDIGREE_GENERATIONS=' . $OLD_PGENS . '&amp;box_width=' . $box_width . '&amp;ged=' . rawurlencode($GEDCOM) . '"><b>' . WT_I18N::translate('Ancestors') . '</b></a></li>';
            $personlinks .= '<li><a href="compact.php?rootid=' . $pid . '&amp;ged=' . rawurlencode($GEDCOM) . '"><b>' . WT_I18N::translate('Compact tree') . '</b></a></li>';
            if (function_exists("imagettftext")) {
                $personlinks .= '<li><a href="fanchart.php?rootid=' . $pid . '&amp;PEDIGREE_GENERATIONS=' . $OLD_PGENS . '&amp;ged=' . rawurlencode($GEDCOM) . '"><b>' . WT_I18N::translate('Fan chart') . '</b></a></li>';
            }
            $personlinks .= '<li><a href="hourglass.php?rootid=' . $pid . '&amp;show_full=' . $PEDIGREE_FULL_DETAILS . '&amp;chart_style=' . $chart_style . '&amp;PEDIGREE_GENERATIONS=' . $OLD_PGENS . '&amp;box_width=' . $box_width . '&amp;ged=' . rawurlencode($GEDCOM) . '&amp;show_spouse=' . $show_spouse . '"><b>' . WT_I18N::translate('Hourglass chart') . '</b></a></li>';
            if (array_key_exists('tree', WT_Module::getActiveModules())) {
                $personlinks .= '<li><a href="module.php?mod=tree&amp;mod_action=treeview&amp;ged=' . WT_GEDURL . '&amp;rootid=' . $pid . '"><b>' . WT_I18N::translate('Interactive tree') . '</b></a></li>';
            }
            foreach ($person->getSpouseFamilies() as $family) {
                $spouse = $family->getSpouse($person);
                if ($spouse) {
                    $personlinks .= '<li>';
                    $personlinks .= '<a href="' . $family->getHtmlUrl() . '"><b>' . WT_I18N::translate('Family with spouse') . '</b></a><br>';
                    $personlinks .= '<a href="' . $spouse->getHtmlUrl() . '">' . $spouse->getFullName() . '</a>';
                    $personlinks .= '</li>';
                    $personlinks .= '<li><ul>';
                }
                foreach ($family->getChildren() as $child) {
                    $personlinks .= '<li><a href="' . $child->getHtmlUrl() . '">';
                    $personlinks .= $child->getFullName();
                    $personlinks .= '</a></li>';
                }
                $personlinks .= '</ul></li>';
            }
            $personlinks .= '</ul>';
            // NOTE: Start div out-$pid.$personcount.$count
            if ($style == 1) {
                $outBoxAdd .= " class=\"person_box{$isF} person_box_template style1\" style=\"width: " . $bwidth . "px; height: " . $bheight . "px; z-index:-1;\"";
            } else {
                $outBoxAdd .= " class=\"person_box{$isF} person_box_template style0\"";
            }
            // NOTE: Zoom
            if (!$show_full) {
                $outBoxAdd .= $mouseAction4;
            } else {
                $icons .= "<a href=\"#\"" . $mouseAction4 . " id=\"iconz-{$boxID}\" class=\"icon-zoomin\" title=\"" . WT_I18N::translate('Zoom in/out on this box.') . "\"></a>";
                $icons .= '<div class="itr"><a href="#" class="icon-pedigree"></a><div class="popup">' . $personlinks . '</div></div>';
            }
        } else {
            if ($style == 1) {
                $outBoxAdd .= "class=\"person_box{$isF}\" style=\"width: " . $bwidth . "px; height: " . $bheight . "px; overflow: hidden;\"";
            } else {
                $outBoxAdd .= "class=\"person_box{$isF}\" style=\"overflow: hidden;\"";
            }
            // NOTE: Zoom
            if (!$SEARCH_SPIDER) {
                $outBoxAdd .= $mouseAction4;
            }
        }
    } else {
        if ($style == 1) {
            $outBoxAdd .= "class=\"person_box{$isF} person_box_template style1\" style=\"width: " . $bwidth . "px; height: " . $bheight . "px;\"";
        } else {
            $outBoxAdd .= "class=\"person_box{$isF} person_box_template style0\"";
        }
    }
    //-- find the name
    $name = $person->getFullName();
    $shortname = $person->getShortName();
    if ($SHOW_HIGHLIGHT_IMAGES) {
        $thumbnail = $person->displayImage();
    } else {
        $thumbnail = '';
    }
    //-- find additional name, e.g. Hebrew
    $addname = $person->getAddName();
    if ($PEDIGREE_SHOW_GENDER && $show_full) {
        $genderImage = " " . $person->getSexImage('small', "box-{$boxID}-gender");
    }
    // Here for alternate name2
    if ($addname) {
        $addname = "<br><span id=\"addnamedef-{$boxID}\" class=\"name1\"> " . $addname . "</span>";
    }
    if ($SHOW_LDS_AT_GLANCE && $show_full) {
        $addname = ' <span class="details$style">' . get_lds_glance($person) . '</span>' . $addname;
    }
    if ($show_full && $person->canShow()) {
        $opt_tags = preg_split('/\\W/', $CHART_BOX_TAGS, 0, PREG_SPLIT_NO_EMPTY);
        // Show BIRT or equivalent event
        foreach (explode('|', WT_EVENTS_BIRT) as $birttag) {
            if (!in_array($birttag, $opt_tags)) {
                $event = $person->getFirstFact($birttag);
                if ($event) {
                    $BirthDeath .= $event->summary();
                    break;
                }
            }
        }
        // Show optional events (before death)
        foreach ($opt_tags as $key => $tag) {
            if (!preg_match('/^(' . WT_EVENTS_DEAT . ')$/', $tag)) {
                $event = $person->getFirstFact($tag);
                if (!is_null($event)) {
                    $BirthDeath .= $event->summary();
                    unset($opt_tags[$key]);
                }
            }
        }
        // Show DEAT or equivalent event
        foreach (explode('|', WT_EVENTS_DEAT) as $deattag) {
            $event = $person->getFirstFact($deattag);
            if ($event) {
                $BirthDeath .= $event->summary();
                if (in_array($deattag, $opt_tags)) {
                    unset($opt_tags[array_search($deattag, $opt_tags)]);
                }
                break;
            }
        }
        // Show remaining optional events (after death)
        foreach ($opt_tags as $tag) {
            $event = $person->getFirstFact($tag);
            if ($event) {
                $BirthDeath .= $event->summary();
            }
        }
    }
    // Output to template
    $classfacts = '';
    if ($show_full) {
        require WT_THEME_DIR . 'templates/personbox_template.php';
    } else {
        require WT_THEME_DIR . 'templates/compactbox_template.php';
    }
}
 /**
  * Draw a person name preceded by sex icon, with parents as tooltip
  *
  * @param WT_Individual $individual an individual
  * @param string        $dashed     if = 'dashed' print dashed top border to separate multiple spuses
  *
  * @return string
  */
 private function drawPersonName(WT_Individual $individual, $dashed = '')
 {
     if ($this->all_partners === 'true') {
         $family = $individual->getPrimaryChildFamily();
         if ($family) {
             switch ($individual->getSex()) {
                 case 'M':
                     $title = ' title="' . strip_tags(WT_I18N::translate('Son of %s', $family->getFullName())) . '"';
                     break;
                 case 'F':
                     $title = ' title="' . strip_tags(WT_I18N::translate('Daughter of %s', $family->getFullName())) . '"';
                     break;
                 case 'U':
                     $title = ' title="' . strip_tags(WT_I18N::translate('Child of %s', $family->getFullName())) . '"';
                     break;
             }
         } else {
             $title = '';
         }
     } else {
         $title = '';
     }
     $sex = $individual->getSex();
     return '<div class="tv' . $sex . ' ' . $dashed . '"' . $title . '><a href="' . $individual->getHtmlUrl() . '"></a>' . $individual->getFullName() . ' <span class="dates">' . $individual->getLifeSpan() . '</span></div>';
 }
Exemple #4
0
function get_relationship_name_from_path($path, WT_Individual $person1 = null, WT_Individual $person2 = null)
{
    if (!preg_match('/^(mot|fat|par|hus|wif|spo|son|dau|chi|bro|sis|sib)*$/', $path)) {
        // TODO: Update all the “3 RELA ” values in class_person
        return '<span class="error">' . $path . '</span>';
    }
    // The path does not include the starting person.  In some languages, the
    // translation for a man’s (relative) is different to a woman’s (relative),
    // due to inflection.
    $sex1 = $person1 ? $person1->getSex() : 'U';
    // The sex of the last person in the relationship determines the name in
    // many cases.  e.g. great-aunt / great-uncle
    if (preg_match('/(fat|hus|son|bro)$/', $path)) {
        $sex2 = 'M';
    } elseif (preg_match('/(mot|wif|dau|sis)$/', $path)) {
        $sex2 = 'F';
    } else {
        $sex2 = 'U';
    }
    switch ($path) {
        case '':
            return WT_I18N::translate('self');
            //  Level One relationships
        //  Level One relationships
        case 'mot':
            return WT_I18N::translate('mother');
        case 'fat':
            return WT_I18N::translate('father');
        case 'par':
            return WT_I18N::translate('parent');
        case 'hus':
            if ($person1 && $person2) {
                foreach ($person1->getSpouseFamilies() as $family) {
                    if ($person2 === $family->getSpouse($person1)) {
                        if ($family->getFacts('_NMR')) {
                            return WT_I18N::translate_c('MALE', 'partner');
                        } elseif ($family->getFacts(WT_EVENTS_DIV)) {
                            return WT_I18N::translate('ex-husband');
                        }
                    }
                }
            }
            return WT_I18N::translate('husband');
        case 'wif':
            if ($person1 && $person1) {
                foreach ($person1->getSpouseFamilies() as $family) {
                    if ($person2 === $family->getSpouse($person1)) {
                        if ($family->getFacts('_NMR')) {
                            return WT_I18N::translate_c('FEMALE', 'partner');
                        } elseif ($family->getFacts(WT_EVENTS_DIV)) {
                            return WT_I18N::translate('ex-wife');
                        }
                    }
                }
            }
            return WT_I18N::translate('wife');
        case 'spo':
            if ($person1 && $person2) {
                foreach ($person1->getSpouseFamilies() as $family) {
                    if ($person2 === $family->getSpouse($person1)) {
                        if ($family->getFacts('_NMR')) {
                            return WT_I18N::translate_c('MALE/FEMALE', 'partner');
                        } elseif ($family->getFacts(WT_EVENTS_DIV)) {
                            return WT_I18N::translate('ex-spouse');
                        }
                    }
                }
            }
            return WT_I18N::translate('spouse');
        case 'son':
            return WT_I18N::translate('son');
        case 'dau':
            return WT_I18N::translate('daughter');
        case 'chi':
            return WT_I18N::translate('child');
        case 'bro':
            if ($person1 && $person2) {
                $dob1 = $person1->getBirthDate();
                $dob2 = $person2->getBirthDate();
                if ($dob1->isOK() && $dob2->isOK()) {
                    if (abs($dob1->JD() - $dob2->JD()) < 2 && !$dob1->qual1 && !$dob2->qual1) {
                        // Exclude BEF, AFT, etc.
                        return WT_I18N::translate('twin brother');
                    } elseif ($dob1->MaxJD() < $dob2->MinJD()) {
                        return WT_I18N::translate('younger brother');
                    } elseif ($dob1->MinJD() > $dob2->MaxJD()) {
                        return WT_I18N::translate('elder brother');
                    }
                }
            }
            return WT_I18N::translate('brother');
        case 'sis':
            if ($person1 && $person2) {
                $dob1 = $person1->getBirthDate();
                $dob2 = $person2->getBirthDate();
                if ($dob1->isOK() && $dob2->isOK()) {
                    if (abs($dob1->JD() - $dob2->JD()) < 2 && !$dob1->qual1 && !$dob2->qual1) {
                        // Exclude BEF, AFT, etc.
                        return WT_I18N::translate('twin sister');
                    } elseif ($dob1->MaxJD() < $dob2->MinJD()) {
                        return WT_I18N::translate('younger sister');
                    } elseif ($dob1->MinJD() > $dob2->MaxJD()) {
                        return WT_I18N::translate('elder sister');
                    }
                }
            }
            return WT_I18N::translate('sister');
        case 'sib':
            if ($person1 && $person2) {
                $dob1 = $person1->getBirthDate();
                $dob2 = $person2->getBirthDate();
                if ($dob1->isOK() && $dob2->isOK()) {
                    if (abs($dob1->JD() - $dob2->JD()) < 2 && !$dob1->qual1 && !$dob2->qual1) {
                        // Exclude BEF, AFT, etc.
                        return WT_I18N::translate('twin sibling');
                    } elseif ($dob1->MaxJD() < $dob2->MinJD()) {
                        return WT_I18N::translate('younger sibling');
                    } elseif ($dob1->MinJD() > $dob2->MaxJD()) {
                        return WT_I18N::translate('elder sibling');
                    }
                }
            }
            return WT_I18N::translate('sibling');
            // Level Two relationships
        // Level Two relationships
        case 'brochi':
            return WT_I18N::translate_c('brother’s child', 'nephew/niece');
        case 'brodau':
            return WT_I18N::translate_c('brother’s daughter', 'niece');
        case 'broson':
            return WT_I18N::translate_c('brother’s son', 'nephew');
        case 'browif':
            return WT_I18N::translate_c('brother’s wife', 'sister-in-law');
        case 'chichi':
            return WT_I18N::translate_c('child’s child', 'grandchild');
        case 'chidau':
            return WT_I18N::translate_c('child’s daughter', 'granddaughter');
        case 'chihus':
            return WT_I18N::translate_c('child’s husband', 'son-in-law');
        case 'chison':
            return WT_I18N::translate_c('child’s son', 'grandson');
        case 'chispo':
            return WT_I18N::translate_c('child’s spouse', 'son/daughter-in-law');
        case 'chiwif':
            return WT_I18N::translate_c('child’s wife', 'daughter-in-law');
        case 'dauchi':
            return WT_I18N::translate_c('daughter’s child', 'grandchild');
        case 'daudau':
            return WT_I18N::translate_c('daughter’s daughter', 'granddaughter');
        case 'dauhus':
            return WT_I18N::translate_c('daughter’s husband', 'son-in-law');
        case 'dauson':
            return WT_I18N::translate_c('daughter’s son', 'grandson');
        case 'fatbro':
            return WT_I18N::translate_c('father’s brother', 'uncle');
        case 'fatchi':
            return WT_I18N::translate_c('father’s child', 'half-sibling');
        case 'fatdau':
            return WT_I18N::translate_c('father’s daughter', 'half-sister');
        case 'fatfat':
            return WT_I18N::translate_c('father’s father', 'paternal grandfather');
        case 'fatmot':
            return WT_I18N::translate_c('father’s mother', 'paternal grandmother');
        case 'fatpar':
            return WT_I18N::translate_c('father’s parent', 'paternal grandparent');
        case 'fatsib':
            return WT_I18N::translate_c('father’s sibling', 'aunt/uncle');
        case 'fatsis':
            return WT_I18N::translate_c('father’s sister', 'aunt');
        case 'fatson':
            return WT_I18N::translate_c('father’s son', 'half-brother');
        case 'fatwif':
            return WT_I18N::translate_c('father’s wife', 'step-mother');
        case 'husbro':
            return WT_I18N::translate_c('husband’s brother', 'brother-in-law');
        case 'huschi':
            return WT_I18N::translate_c('husband’s child', 'step-child');
        case 'husdau':
            return WT_I18N::translate_c('husband’s daughter', 'step-daughter');
        case 'husfat':
            return WT_I18N::translate_c('husband’s father', 'father-in-law');
        case 'husmot':
            return WT_I18N::translate_c('husband’s mother', 'mother-in-law');
        case 'hussib':
            return WT_I18N::translate_c('husband’s sibling', 'brother/sister-in-law');
        case 'hussis':
            return WT_I18N::translate_c('husband’s sister', 'sister-in-law');
        case 'husson':
            return WT_I18N::translate_c('husband’s son', 'step-son');
        case 'motbro':
            return WT_I18N::translate_c('mother’s brother', 'uncle');
        case 'motchi':
            return WT_I18N::translate_c('mother’s child', 'half-sibling');
        case 'motdau':
            return WT_I18N::translate_c('mother’s daughter', 'half-sister');
        case 'motfat':
            return WT_I18N::translate_c('mother’s father', 'maternal grandfather');
        case 'mothus':
            return WT_I18N::translate_c('mother’s husband', 'step-father');
        case 'motmot':
            return WT_I18N::translate_c('mother’s mother', 'maternal grandmother');
        case 'motpar':
            return WT_I18N::translate_c('mother’s parent', 'maternal grandparent');
        case 'motsib':
            return WT_I18N::translate_c('mother’s sibling', 'aunt/uncle');
        case 'motsis':
            return WT_I18N::translate_c('mother’s sister', 'aunt');
        case 'motson':
            return WT_I18N::translate_c('mother’s son', 'half-brother');
        case 'parbro':
            return WT_I18N::translate_c('parent’s brother', 'uncle');
        case 'parchi':
            return WT_I18N::translate_c('parent’s child', 'half-sibling');
        case 'pardau':
            return WT_I18N::translate_c('parent’s daughter', 'half-sister');
        case 'parfat':
            return WT_I18N::translate_c('parent’s father', 'grandfather');
        case 'parmot':
            return WT_I18N::translate_c('parent’s mother', 'grandmother');
        case 'parpar':
            return WT_I18N::translate_c('parent’s parent', 'grandparent');
        case 'parsib':
            return WT_I18N::translate_c('parent’s sibling', 'aunt/uncle');
        case 'parsis':
            return WT_I18N::translate_c('parent’s sister', 'aunt');
        case 'parson':
            return WT_I18N::translate_c('parent’s son', 'half-brother');
        case 'parspo':
            return WT_I18N::translate_c('parent’s spouse', 'step-parent');
        case 'sibchi':
            return WT_I18N::translate_c('sibling’s child', 'nephew/niece');
        case 'sibdau':
            return WT_I18N::translate_c('sibling’s daughter', 'niece');
        case 'sibson':
            return WT_I18N::translate_c('sibling’s son', 'nephew');
        case 'sibspo':
            return WT_I18N::translate_c('sibling’s spouse', 'brother/sister-in-law');
        case 'sischi':
            return WT_I18N::translate_c('sister’s child', 'nephew/niece');
        case 'sisdau':
            return WT_I18N::translate_c('sister’s daughter', 'niece');
        case 'sishus':
            return WT_I18N::translate_c('sister’s husband', 'brother-in-law');
        case 'sisson':
            return WT_I18N::translate_c('sister’s son', 'nephew');
        case 'sonchi':
            return WT_I18N::translate_c('son’s child', 'grandchild');
        case 'sondau':
            return WT_I18N::translate_c('son’s daughter', 'granddaughter');
        case 'sonson':
            return WT_I18N::translate_c('son’s son', 'grandson');
        case 'sonwif':
            return WT_I18N::translate_c('son’s wife', 'daughter-in-law');
        case 'spobro':
            return WT_I18N::translate_c('spouse’s brother', 'brother-in-law');
        case 'spochi':
            return WT_I18N::translate_c('spouse’s child', 'step-child');
        case 'spodau':
            return WT_I18N::translate_c('spouse’s daughter', 'step-daughter');
        case 'spofat':
            return WT_I18N::translate_c('spouse’s father', 'father-in-law');
        case 'spomot':
            return WT_I18N::translate_c('spouse’s mother', 'mother-in-law');
        case 'sposis':
            return WT_I18N::translate_c('spouse’s sister', 'sister-in-law');
        case 'sposon':
            return WT_I18N::translate_c('spouse’s son', 'step-son');
        case 'spopar':
            return WT_I18N::translate_c('spouse’s parent', 'mother/father-in-law');
        case 'sposib':
            return WT_I18N::translate_c('spouse’s sibling', 'brother/sister-in-law');
        case 'wifbro':
            return WT_I18N::translate_c('wife’s brother', 'brother-in-law');
        case 'wifchi':
            return WT_I18N::translate_c('wife’s child', 'step-child');
        case 'wifdau':
            return WT_I18N::translate_c('wife’s daughter', 'step-daughter');
        case 'wiffat':
            return WT_I18N::translate_c('wife’s father', 'father-in-law');
        case 'wifmot':
            return WT_I18N::translate_c('wife’s mother', 'mother-in-law');
        case 'wifsib':
            return WT_I18N::translate_c('wife’s sibling', 'brother/sister-in-law');
        case 'wifsis':
            return WT_I18N::translate_c('wife’s sister', 'sister-in-law');
        case 'wifson':
            return WT_I18N::translate_c('wife’s son', 'step-son');
            // Level Three relationships
            // I have commented out some of the unknown-sex relationships that are unlikely to to occur.
            // Feel free to add them in, if you think they might be needed
        // Level Three relationships
        // I have commented out some of the unknown-sex relationships that are unlikely to to occur.
        // Feel free to add them in, if you think they might be needed
        case 'brochichi':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) brother’s child’s child', 'great-nephew/niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) brother’s child’s child', 'great-nephew/niece');
            }
        case 'brochidau':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) brother’s child’s daughter', 'great-niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) brother’s child’s daughter', 'great-niece');
            }
        case 'brochison':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) brother’s child’s son', 'great-nephew');
            } else {
                return WT_I18N::translate_c('(a woman’s) brother’s child’s son', 'great-nephew');
            }
        case 'brodauchi':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) brother’s daughter’s child', 'great-nephew/niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) brother’s daughter’s child', 'great-nephew/niece');
            }
        case 'brodaudau':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) brother’s daughter’s daughter', 'great-niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) brother’s daughter’s daughter', 'great-niece');
            }
        case 'brodauhus':
            return WT_I18N::translate_c('brother’s daughter’s husband', 'nephew-in-law');
        case 'brodauson':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) brother’s daughter’s son', 'great-nephew');
            } else {
                return WT_I18N::translate_c('(a woman’s) brother’s daughter’s son', 'great-nephew');
            }
        case 'brosonchi':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) brother’s son’s child', 'great-nephew/niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) brother’s son’s child', 'great-nephew/niece');
            }
        case 'brosondau':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) brother’s son’s daughter', 'great-niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) brother’s son’s daughter', 'great-niece');
            }
        case 'brosonson':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) brother’s son’s son', 'great-nephew');
            } else {
                return WT_I18N::translate_c('(a woman’s) brother’s son’s son', 'great-nephew');
            }
        case 'brosonwif':
            return WT_I18N::translate_c('brother’s son’s wife', 'niece-in-law');
        case 'browifbro':
            return WT_I18N::translate_c('brother’s wife’s brother', 'brother-in-law');
        case 'browifsib':
            return WT_I18N::translate_c('brother’s wife’s sibling', 'brother/sister-in-law');
        case 'browifsis':
            return WT_I18N::translate_c('brother’s wife’s sister', 'sister-in-law');
        case 'chichichi':
            return WT_I18N::translate_c('child’s child’s child', 'great-grandchild');
        case 'chichidau':
            return WT_I18N::translate_c('child’s child’s daughter', 'great-granddaughter');
        case 'chichison':
            return WT_I18N::translate_c('child’s child’s son', 'great-grandson');
        case 'chidauchi':
            return WT_I18N::translate_c('child’s daughter’s child', 'great-grandchild');
        case 'chidaudau':
            return WT_I18N::translate_c('child’s daughter’s daughter', 'great-granddaughter');
        case 'chidauhus':
            return WT_I18N::translate_c('child’s daughter’s husband', 'granddaughter’s husband');
        case 'chidauson':
            return WT_I18N::translate_c('child’s daughter’s son', 'great-grandson');
        case 'chisonchi':
            return WT_I18N::translate_c('child’s son’s child', 'great-grandchild');
        case 'chisondau':
            return WT_I18N::translate_c('child’s son’s daughter', 'great-granddaughter');
        case 'chisonson':
            return WT_I18N::translate_c('child’s son’s son', 'great-grandson');
        case 'chisonwif':
            return WT_I18N::translate_c('child’s son’s wife', 'grandson’s wife');
        case 'dauchichi':
            return WT_I18N::translate_c('daughter’s child’s child', 'great-grandchild');
        case 'dauchidau':
            return WT_I18N::translate_c('daughter’s child’s daughter', 'great-granddaughter');
        case 'dauchison':
            return WT_I18N::translate_c('daughter’s child’s son', 'great-grandson');
        case 'daudauchi':
            return WT_I18N::translate_c('daughter’s daughter’s child', 'great-grandchild');
        case 'daudaudau':
            return WT_I18N::translate_c('daughter’s daughter’s daughter', 'great-granddaughter');
        case 'daudauhus':
            return WT_I18N::translate_c('daughter’s daughter’s husband', 'granddaughter’s husband');
        case 'daudauson':
            return WT_I18N::translate_c('daughter’s daughter’s son', 'great-grandson');
        case 'dauhusfat':
            return WT_I18N::translate_c('daughter’s husband’s father', 'son-in-law’s father');
        case 'dauhusmot':
            return WT_I18N::translate_c('daughter’s husband’s mother', 'son-in-law’s mother');
        case 'dauhuspar':
            return WT_I18N::translate_c('daughter’s husband’s parent', 'son-in-law’s parent');
        case 'dausonchi':
            return WT_I18N::translate_c('daughter’s son’s child', 'great-grandchild');
        case 'dausondau':
            return WT_I18N::translate_c('daughter’s son’s daughter', 'great-granddaughter');
        case 'dausonson':
            return WT_I18N::translate_c('daughter’s son’s son', 'great-grandson');
        case 'dausonwif':
            return WT_I18N::translate_c('daughter’s son’s wife', 'grandson’s wife');
        case 'fatbrochi':
            return WT_I18N::translate_c('father’s brother’s child', 'first cousin');
        case 'fatbrodau':
            return WT_I18N::translate_c('father’s brother’s daughter', 'first cousin');
        case 'fatbroson':
            return WT_I18N::translate_c('father’s brother’s son', 'first cousin');
        case 'fatbrowif':
            return WT_I18N::translate_c('father’s brother’s wife', 'aunt');
        case 'fatfatbro':
            return WT_I18N::translate_c('father’s father’s brother', 'great-uncle');
        case 'fatfatfat':
            return WT_I18N::translate_c('father’s father’s father', 'great-grandfather');
        case 'fatfatmot':
            return WT_I18N::translate_c('father’s father’s mother', 'great-grandmother');
        case 'fatfatpar':
            return WT_I18N::translate_c('father’s father’s parent', 'great-grandparent');
        case 'fatfatsib':
            return WT_I18N::translate_c('father’s father’s sibling', 'great-aunt/uncle');
        case 'fatfatsis':
            return WT_I18N::translate_c('father’s father’s sister', 'great-aunt');
        case 'fatmotbro':
            return WT_I18N::translate_c('father’s mother’s brother', 'great-uncle');
        case 'fatmotfat':
            return WT_I18N::translate_c('father’s mother’s father', 'great-grandfather');
        case 'fatmotmot':
            return WT_I18N::translate_c('father’s mother’s mother', 'great-grandmother');
        case 'fatmotpar':
            return WT_I18N::translate_c('father’s mother’s parent', 'great-grandparent');
        case 'fatmotsib':
            return WT_I18N::translate_c('father’s mother’s sibling', 'great-aunt/uncle');
        case 'fatmotsis':
            return WT_I18N::translate_c('father’s mother’s sister', 'great-aunt');
        case 'fatparbro':
            return WT_I18N::translate_c('father’s parent’s brother', 'great-uncle');
        case 'fatparfat':
            return WT_I18N::translate_c('father’s parent’s father', 'great-grandfather');
        case 'fatparmot':
            return WT_I18N::translate_c('father’s parent’s mother', 'great-grandmother');
        case 'fatparpar':
            return WT_I18N::translate_c('father’s parent’s parent', 'great-grandparent');
        case 'fatparsib':
            return WT_I18N::translate_c('father’s parent’s sibling', 'great-aunt/uncle');
        case 'fatparsis':
            return WT_I18N::translate_c('father’s parent’s sister', 'great-aunt');
        case 'fatsischi':
            return WT_I18N::translate_c('father’s sister’s child', 'first cousin');
        case 'fatsisdau':
            return WT_I18N::translate_c('father’s sister’s daughter', 'first cousin');
        case 'fatsishus':
            return WT_I18N::translate_c('father’s sister’s husband', 'uncle');
        case 'fatsisson':
            return WT_I18N::translate_c('father’s sister’s son', 'first cousin');
        case 'fatwifchi':
            return WT_I18N::translate_c('father’s wife’s child', 'step-sibling');
        case 'fatwifdau':
            return WT_I18N::translate_c('father’s wife’s daughter', 'step-sister');
        case 'fatwifson':
            return WT_I18N::translate_c('father’s wife’s son', 'step-brother');
        case 'husbrowif':
            return WT_I18N::translate_c('husband’s brother’s wife', 'sister-in-law');
        case 'hussishus':
            return WT_I18N::translate_c('husband’s sister’s husband', 'brother-in-law');
        case 'motbrochi':
            return WT_I18N::translate_c('mother’s brother’s child', 'first cousin');
        case 'motbrodau':
            return WT_I18N::translate_c('mother’s brother’s daughter', 'first cousin');
        case 'motbroson':
            return WT_I18N::translate_c('mother’s brother’s son', 'first cousin');
        case 'motbrowif':
            return WT_I18N::translate_c('mother’s brother’s wife', 'aunt');
        case 'motfatbro':
            return WT_I18N::translate_c('mother’s father’s brother', 'great-uncle');
        case 'motfatfat':
            return WT_I18N::translate_c('mother’s father’s father', 'great-grandfather');
        case 'motfatmot':
            return WT_I18N::translate_c('mother’s father’s mother', 'great-grandmother');
        case 'motfatpar':
            return WT_I18N::translate_c('mother’s father’s parent', 'great-grandparent');
        case 'motfatsib':
            return WT_I18N::translate_c('mother’s father’s sibling', 'great-aunt/uncle');
        case 'motfatsis':
            return WT_I18N::translate_c('mother’s father’s sister', 'great-aunt');
        case 'mothuschi':
            return WT_I18N::translate_c('mother’s husband’s child', 'step-sibling');
        case 'mothusdau':
            return WT_I18N::translate_c('mother’s husband’s daughter', 'step-sister');
        case 'mothusson':
            return WT_I18N::translate_c('mother’s husband’s son', 'step-brother');
        case 'motmotbro':
            return WT_I18N::translate_c('mother’s mother’s brother', 'great-uncle');
        case 'motmotfat':
            return WT_I18N::translate_c('mother’s mother’s father', 'great-grandfather');
        case 'motmotmot':
            return WT_I18N::translate_c('mother’s mother’s mother', 'great-grandmother');
        case 'motmotpar':
            return WT_I18N::translate_c('mother’s mother’s parent', 'great-grandparent');
        case 'motmotsib':
            return WT_I18N::translate_c('mother’s mother’s sibling', 'great-aunt/uncle');
        case 'motmotsis':
            return WT_I18N::translate_c('mother’s mother’s sister', 'great-aunt');
        case 'motparbro':
            return WT_I18N::translate_c('mother’s parent’s brother', 'great-uncle');
        case 'motparfat':
            return WT_I18N::translate_c('mother’s parent’s father', 'great-grandfather');
        case 'motparmot':
            return WT_I18N::translate_c('mother’s parent’s mother', 'great-grandmother');
        case 'motparpar':
            return WT_I18N::translate_c('mother’s parent’s parent', 'great-grandparent');
        case 'motparsib':
            return WT_I18N::translate_c('mother’s parent’s sibling', 'great-aunt/uncle');
        case 'motparsis':
            return WT_I18N::translate_c('mother’s parent’s sister', 'great-aunt');
        case 'motsischi':
            return WT_I18N::translate_c('mother’s sister’s child', 'first cousin');
        case 'motsisdau':
            return WT_I18N::translate_c('mother’s sister’s daughter', 'first cousin');
        case 'motsishus':
            return WT_I18N::translate_c('mother’s sister’s husband', 'uncle');
        case 'motsisson':
            return WT_I18N::translate_c('mother’s sister’s son', 'first cousin');
        case 'parbrowif':
            return WT_I18N::translate_c('parent’s brother’s wife', 'aunt');
        case 'parfatbro':
            return WT_I18N::translate_c('parent’s father’s brother', 'great-uncle');
        case 'parfatfat':
            return WT_I18N::translate_c('parent’s father’s father', 'great-grandfather');
        case 'parfatmot':
            return WT_I18N::translate_c('parent’s father’s mother', 'great-grandmother');
        case 'parfatpar':
            return WT_I18N::translate_c('parent’s father’s parent', 'great-grandparent');
        case 'parfatsib':
            return WT_I18N::translate_c('parent’s father’s sibling', 'great-aunt/uncle');
        case 'parfatsis':
            return WT_I18N::translate_c('parent’s father’s sister', 'great-aunt');
        case 'parmotbro':
            return WT_I18N::translate_c('parent’s mother’s brother', 'great-uncle');
        case 'parmotfat':
            return WT_I18N::translate_c('parent’s mother’s father', 'great-grandfather');
        case 'parmotmot':
            return WT_I18N::translate_c('parent’s mother’s mother', 'great-grandmother');
        case 'parmotpar':
            return WT_I18N::translate_c('parent’s mother’s parent', 'great-grandparent');
        case 'parmotsib':
            return WT_I18N::translate_c('parent’s mother’s sibling', 'great-aunt/uncle');
        case 'parmotsis':
            return WT_I18N::translate_c('parent’s mother’s sister', 'great-aunt');
        case 'parparbro':
            return WT_I18N::translate_c('parent’s parent’s brother', 'great-uncle');
        case 'parparfat':
            return WT_I18N::translate_c('parent’s parent’s father', 'great-grandfather');
        case 'parparmot':
            return WT_I18N::translate_c('parent’s parent’s mother', 'great-grandmother');
        case 'parparpar':
            return WT_I18N::translate_c('parent’s parent’s parent', 'great-grandparent');
        case 'parparsib':
            return WT_I18N::translate_c('parent’s parent’s sibling', 'great-aunt/uncle');
        case 'parparsis':
            return WT_I18N::translate_c('parent’s parent’s sister', 'great-aunt');
        case 'parsishus':
            return WT_I18N::translate_c('parent’s sister’s husband', 'uncle');
        case 'parspochi':
            return WT_I18N::translate_c('parent’s spouse’s child', 'step-sibling');
        case 'parspodau':
            return WT_I18N::translate_c('parent’s spouse’s daughter', 'step-sister');
        case 'parsposon':
            return WT_I18N::translate_c('parent’s spouse’s son', 'step-brother');
        case 'sibchichi':
            return WT_I18N::translate_c('sibling’s child’s child', 'great-nephew/niece');
        case 'sibchidau':
            return WT_I18N::translate_c('sibling’s child’s daughter', 'great-niece');
        case 'sibchison':
            return WT_I18N::translate_c('sibling’s child’s son', 'great-nephew');
        case 'sibdauchi':
            return WT_I18N::translate_c('sibling’s daughter’s child', 'great-nephew/niece');
        case 'sibdaudau':
            return WT_I18N::translate_c('sibling’s daughter’s daughter', 'great-niece');
        case 'sibdauhus':
            return WT_I18N::translate_c('sibling’s daughter’s husband', 'nephew-in-law');
        case 'sibdauson':
            return WT_I18N::translate_c('sibling’s daughter’s son', 'great-nephew');
        case 'sibsonchi':
            return WT_I18N::translate_c('sibling’s son’s child', 'great-nephew/niece');
        case 'sibsondau':
            return WT_I18N::translate_c('sibling’s son’s daughter', 'great-niece');
        case 'sibsonson':
            return WT_I18N::translate_c('sibling’s son’s son', 'great-nephew');
        case 'sibsonwif':
            return WT_I18N::translate_c('sibling’s son’s wife', 'niece-in-law');
        case 'sischichi':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) sister’s child’s child', 'great-nephew/niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) sister’s child’s child', 'great-nephew/niece');
            }
        case 'sischidau':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) sister’s child’s daughter', 'great-niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) sister’s child’s daughter', 'great-niece');
            }
        case 'sischison':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) sister’s child’s son', 'great-nephew');
            } else {
                return WT_I18N::translate_c('(a woman’s) sister’s child’s son', 'great-nephew');
            }
        case 'sisdauchi':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) sister’s daughter’s child', 'great-nephew/niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) sister’s daughter’s child', 'great-nephew/niece');
            }
        case 'sisdaudau':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) sister’s daughter’s daughter', 'great-niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) sister’s daughter’s daughter', 'great-niece');
            }
        case 'sisdauhus':
            return WT_I18N::translate_c('sisters’s daughter’s husband', 'nephew-in-law');
        case 'sisdauson':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) sister’s daughter’s son', 'great-nephew');
            } else {
                return WT_I18N::translate_c('(a woman’s) sister’s daughter’s son', 'great-nephew');
            }
        case 'sishusbro':
            return WT_I18N::translate_c('sister’s husband’s brother', 'brother-in-law');
        case 'sishussib':
            return WT_I18N::translate_c('sister’s husband’s sibling', 'brother/sister-in-law');
        case 'sishussis':
            return WT_I18N::translate_c('sister’s husband’s sister', 'sister-in-law');
        case 'sissonchi':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) sister’s son’s child', 'great-nephew/niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) sister’s son’s child', 'great-nephew/niece');
            }
        case 'sissondau':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) sister’s son’s daughter', 'great-niece');
            } else {
                return WT_I18N::translate_c('(a woman’s) sister’s son’s daughter', 'great-niece');
            }
        case 'sissonson':
            if ($sex1 == 'M') {
                return WT_I18N::translate_c('(a man’s) sister’s son’s son', 'great-nephew');
            } else {
                return WT_I18N::translate_c('(a woman’s) sister’s son’s son', 'great-nephew');
            }
        case 'sissonwif':
            return WT_I18N::translate_c('sisters’s son’s wife', 'niece-in-law');
        case 'sonchichi':
            return WT_I18N::translate_c('son’s child’s child', 'great-grandchild');
        case 'sonchidau':
            return WT_I18N::translate_c('son’s child’s daughter', 'great-granddaughter');
        case 'sonchison':
            return WT_I18N::translate_c('son’s child’s son', 'great-grandson');
        case 'sondauchi':
            return WT_I18N::translate_c('son’s daughter’s child', 'great-grandchild');
        case 'sondaudau':
            return WT_I18N::translate_c('son’s daughter’s daughter', 'great-granddaughter');
        case 'sondauhus':
            return WT_I18N::translate_c('son’s daughter’s husband', 'granddaughter’s husband');
        case 'sondauson':
            return WT_I18N::translate_c('son’s daughter’s son', 'great-grandson');
        case 'sonsonchi':
            return WT_I18N::translate_c('son’s son’s child', 'great-grandchild');
        case 'sonsondau':
            return WT_I18N::translate_c('son’s son’s daughter', 'great-granddaughter');
        case 'sonsonson':
            return WT_I18N::translate_c('son’s son’s son', 'great-grandson');
        case 'sonsonwif':
            return WT_I18N::translate_c('son’s son’s wife', 'grandson’s wife');
        case 'sonwiffat':
            return WT_I18N::translate_c('son’s wife’s father', 'daughter-in-law’s father');
        case 'sonwifmot':
            return WT_I18N::translate_c('son’s wife’s mother', 'daughter-in-law’s mother');
        case 'sonwifpar':
            return WT_I18N::translate_c('son’s wife’s parent', 'daughter-in-law’s parent');
        case 'wifbrowif':
            return WT_I18N::translate_c('wife’s brother’s wife', 'sister-in-law');
        case 'wifsishus':
            return WT_I18N::translate_c('wife’s sister’s husband', 'brother-in-law');
            // Some “special case” level four relationships that have specific names in certain languages
        // Some “special case” level four relationships that have specific names in certain languages
        case 'fatfatbrowif':
            return WT_I18N::translate_c('father’s father’s brother’s wife', 'great-aunt');
        case 'fatfatsibspo':
            return WT_I18N::translate_c('father’s father’s sibling’s spouse', 'great-aunt/uncle');
        case 'fatfatsishus':
            return WT_I18N::translate_c('father’s father’s sister’s husband', 'great-uncle');
        case 'fatmotbrowif':
            return WT_I18N::translate_c('father’s mother’s brother’s wife', 'great-aunt');
        case 'fatmotsibspo':
            return WT_I18N::translate_c('father’s mother’s sibling’s spouse', 'great-aunt/uncle');
        case 'fatmotsishus':
            return WT_I18N::translate_c('father’s mother’s sister’s husband', 'great-uncle');
        case 'fatparbrowif':
            return WT_I18N::translate_c('father’s parent’s brother’s wife', 'great-aunt');
        case 'fatparsibspo':
            return WT_I18N::translate_c('father’s parent’s sibling’s spouse', 'great-aunt/uncle');
        case 'fatparsishus':
            return WT_I18N::translate_c('father’s parent’s sister’s husband', 'great-uncle');
        case 'motfatbrowif':
            return WT_I18N::translate_c('mother’s father’s brother’s wife', 'great-aunt');
        case 'motfatsibspo':
            return WT_I18N::translate_c('mother’s father’s sibling’s spouse', 'great-aunt/uncle');
        case 'motfatsishus':
            return WT_I18N::translate_c('mother’s father’s sister’s husband', 'great-uncle');
        case 'motmotbrowif':
            return WT_I18N::translate_c('mother’s mother’s brother’s wife', 'great-aunt');
        case 'motmotsibspo':
            return WT_I18N::translate_c('mother’s mother’s sibling’s spouse', 'great-aunt/uncle');
        case 'motmotsishus':
            return WT_I18N::translate_c('mother’s mother’s sister’s husband', 'great-uncle');
        case 'motparbrowif':
            return WT_I18N::translate_c('mother’s parent’s brother’s wife', 'great-aunt');
        case 'motparsibspo':
            return WT_I18N::translate_c('mother’s parent’s sibling’s spouse', 'great-aunt/uncle');
        case 'motparsishus':
            return WT_I18N::translate_c('mother’s parent’s sister’s husband', 'great-uncle');
        case 'parfatbrowif':
            return WT_I18N::translate_c('parent’s father’s brother’s wife', 'great-aunt');
        case 'parfatsibspo':
            return WT_I18N::translate_c('parent’s father’s sibling’s spouse', 'great-aunt/uncle');
        case 'parfatsishus':
            return WT_I18N::translate_c('parent’s father’s sister’s husband', 'great-uncle');
        case 'parmotbrowif':
            return WT_I18N::translate_c('parent’s mother’s brother’s wife', 'great-aunt');
        case 'parmotsibspo':
            return WT_I18N::translate_c('parent’s mother’s sibling’s spouse', 'great-aunt/uncle');
        case 'parmotsishus':
            return WT_I18N::translate_c('parent’s mother’s sister’s husband', 'great-uncle');
        case 'parparbrowif':
            return WT_I18N::translate_c('parent’s parent’s brother’s wife', 'great-aunt');
        case 'parparsibspo':
            return WT_I18N::translate_c('parent’s parent’s sibling’s spouse', 'great-aunt/uncle');
        case 'parparsishus':
            return WT_I18N::translate_c('parent’s parent’s sister’s husband', 'great-uncle');
        case 'fatfatbrodau':
            return WT_I18N::translate_c('father’s father’s brother’s daughter', 'first cousin once removed ascending');
        case 'fatfatbroson':
            return WT_I18N::translate_c('father’s father’s brother’s son', 'first cousin once removed ascending');
        case 'fatfatbrochi':
            return WT_I18N::translate_c('father’s father’s brother’s child', 'first cousin once removed ascending');
        case 'fatfatsisdau':
            return WT_I18N::translate_c('father’s father’s sister’s daughter', 'first cousin once removed ascending');
        case 'fatfatsisson':
            return WT_I18N::translate_c('father’s father’s sister’s son', 'first cousin once removed ascending');
        case 'fatfatsischi':
            return WT_I18N::translate_c('father’s father’s sister’s child', 'first cousin once removed ascending');
        case 'fatmotbrodau':
            return WT_I18N::translate_c('father’s mother’s brother’s daughter', 'first cousin once removed ascending');
        case 'fatmotbroson':
            return WT_I18N::translate_c('father’s mother’s brother’s son', 'first cousin once removed ascending');
        case 'fatmotbrochi':
            return WT_I18N::translate_c('father’s mother’s brother’s child', 'first cousin once removed ascending');
        case 'fatmotsisdau':
            return WT_I18N::translate_c('father’s mother’s sister’s daughter', 'first cousin once removed ascending');
        case 'fatmotsisson':
            return WT_I18N::translate_c('father’s mother’s sister’s son', 'first cousin once removed ascending');
        case 'fatmotsischi':
            return WT_I18N::translate_c('father’s mother’s sister’s child', 'first cousin once removed ascending');
        case 'motfatbrodau':
            return WT_I18N::translate_c('mother’s father’s brother’s daughter', 'first cousin once removed ascending');
        case 'motfatbroson':
            return WT_I18N::translate_c('mother’s father’s brother’s son', 'first cousin once removed ascending');
        case 'motfatbrochi':
            return WT_I18N::translate_c('mother’s father’s brother’s child', 'first cousin once removed ascending');
        case 'motfatsisdau':
            return WT_I18N::translate_c('mother’s father’s sister’s daughter', 'first cousin once removed ascending');
        case 'motfatsisson':
            return WT_I18N::translate_c('mother’s father’s sister’s son', 'first cousin once removed ascending');
        case 'motfatsischi':
            return WT_I18N::translate_c('mother’s father’s sister’s child', 'first cousin once removed ascending');
        case 'motmotbrodau':
            return WT_I18N::translate_c('mother’s mother’s brother’s daughter', 'first cousin once removed ascending');
        case 'motmotbroson':
            return WT_I18N::translate_c('mother’s mother’s brother’s son', 'first cousin once removed ascending');
        case 'motmotbrochi':
            return WT_I18N::translate_c('mother’s mother’s brother’s child', 'first cousin once removed ascending');
        case 'motmotsisdau':
            return WT_I18N::translate_c('mother’s mother’s sister’s daughter', 'first cousin once removed ascending');
        case 'motmotsisson':
            return WT_I18N::translate_c('mother’s mother’s sister’s son', 'first cousin once removed ascending');
        case 'motmotsischi':
            return WT_I18N::translate_c('mother’s mother’s sister’s child', 'first cousin once removed ascending');
    }
    // Some “special case” level five relationships that have specific names in certain languages
    if (preg_match('/^(mot|fat|par)fatbro(son|dau|chi)dau$/', $path)) {
        return WT_I18N::translate_c('grandfather’s brother’s granddaughter', 'second cousin');
    } else {
        if (preg_match('/^(mot|fat|par)fatbro(son|dau|chi)son$/', $path)) {
            return WT_I18N::translate_c('grandfather’s brother’s grandson', 'second cousin');
        } else {
            if (preg_match('/^(mot|fat|par)fatbro(son|dau|chi)chi$/', $path)) {
                return WT_I18N::translate_c('grandfather’s brother’s grandchild', 'second cousin');
            } else {
                if (preg_match('/^(mot|fat|par)fatsis(son|dau|chi)dau$/', $path)) {
                    return WT_I18N::translate_c('grandfather’s sister’s granddaughter', 'second cousin');
                } else {
                    if (preg_match('/^(mot|fat|par)fatsis(son|dau|chi)son$/', $path)) {
                        return WT_I18N::translate_c('grandfather’s sister’s grandson', 'second cousin');
                    } else {
                        if (preg_match('/^(mot|fat|par)fatsis(son|dau|chi)chi$/', $path)) {
                            return WT_I18N::translate_c('grandfather’s sister’s grandchild', 'second cousin');
                        } else {
                            if (preg_match('/^(mot|fat|par)fatsib(son|dau|chi)dau$/', $path)) {
                                return WT_I18N::translate_c('grandfather’s sibling’s granddaughter', 'second cousin');
                            } else {
                                if (preg_match('/^(mot|fat|par)fatsib(son|dau|chi)son$/', $path)) {
                                    return WT_I18N::translate_c('grandfather’s sibling’s grandson', 'second cousin');
                                } else {
                                    if (preg_match('/^(mot|fat|par)fatsib(son|dau|chi)chi$/', $path)) {
                                        return WT_I18N::translate_c('grandfather’s sibling’s grandchild', 'second cousin');
                                    } else {
                                        if (preg_match('/^(mot|fat|par)motbro(son|dau|chi)dau$/', $path)) {
                                            return WT_I18N::translate_c('grandmother’s brother’s granddaughter', 'second cousin');
                                        } else {
                                            if (preg_match('/^(mot|fat|par)motbro(son|dau|chi)son$/', $path)) {
                                                return WT_I18N::translate_c('grandmother’s brother’s grandson', 'second cousin');
                                            } else {
                                                if (preg_match('/^(mot|fat|par)motbro(son|dau|chi)chi$/', $path)) {
                                                    return WT_I18N::translate_c('grandmother’s brother’s grandchild', 'second cousin');
                                                } else {
                                                    if (preg_match('/^(mot|fat|par)motsis(son|dau|chi)dau$/', $path)) {
                                                        return WT_I18N::translate_c('grandmother’s sister’s granddaughter', 'second cousin');
                                                    } else {
                                                        if (preg_match('/^(mot|fat|par)motsis(son|dau|chi)son$/', $path)) {
                                                            return WT_I18N::translate_c('grandmother’s sister’s grandson', 'second cousin');
                                                        } else {
                                                            if (preg_match('/^(mot|fat|par)motsis(son|dau|chi)chi$/', $path)) {
                                                                return WT_I18N::translate_c('grandmother’s sister’s grandchild', 'second cousin');
                                                            } else {
                                                                if (preg_match('/^(mot|fat|par)motsib(son|dau|chi)dau$/', $path)) {
                                                                    return WT_I18N::translate_c('grandmother’s sibling’s granddaughter', 'second cousin');
                                                                } else {
                                                                    if (preg_match('/^(mot|fat|par)motsib(son|dau|chi)son$/', $path)) {
                                                                        return WT_I18N::translate_c('grandmother’s sibling’s grandson', 'second cousin');
                                                                    } else {
                                                                        if (preg_match('/^(mot|fat|par)motsib(son|dau|chi)chi$/', $path)) {
                                                                            return WT_I18N::translate_c('grandmother’s sibling’s grandchild', 'second cousin');
                                                                        } else {
                                                                            if (preg_match('/^(mot|fat|par)parbro(son|dau|chi)dau$/', $path)) {
                                                                                return WT_I18N::translate_c('grandparent’s brother’s granddaughter', 'second cousin');
                                                                            } else {
                                                                                if (preg_match('/^(mot|fat|par)parbro(son|dau|chi)son$/', $path)) {
                                                                                    return WT_I18N::translate_c('grandparent’s brother’s grandson', 'second cousin');
                                                                                } else {
                                                                                    if (preg_match('/^(mot|fat|par)parbro(son|dau|chi)chi$/', $path)) {
                                                                                        return WT_I18N::translate_c('grandparent’s brother’s grandchild', 'second cousin');
                                                                                    } else {
                                                                                        if (preg_match('/^(mot|fat|par)parsis(son|dau|chi)dau$/', $path)) {
                                                                                            return WT_I18N::translate_c('grandparent’s sister’s granddaughter', 'second cousin');
                                                                                        } else {
                                                                                            if (preg_match('/^(mot|fat|par)parsis(son|dau|chi)son$/', $path)) {
                                                                                                return WT_I18N::translate_c('grandparent’s sister’s grandson', 'second cousin');
                                                                                            } else {
                                                                                                if (preg_match('/^(mot|fat|par)parsis(son|dau|chi)chi$/', $path)) {
                                                                                                    return WT_I18N::translate_c('grandparent’s sister’s grandchild', 'second cousin');
                                                                                                } else {
                                                                                                    if (preg_match('/^(mot|fat|par)parsib(son|dau|chi)dau$/', $path)) {
                                                                                                        return WT_I18N::translate_c('grandparent’s sibling’s granddaughter', 'second cousin');
                                                                                                    } else {
                                                                                                        if (preg_match('/^(mot|fat|par)parsib(son|dau|chi)son$/', $path)) {
                                                                                                            return WT_I18N::translate_c('grandparent’s sibling’s grandson', 'second cousin');
                                                                                                        } else {
                                                                                                            if (preg_match('/^(mot|fat|par)parsib(son|dau|chi)chi$/', $path)) {
                                                                                                                return WT_I18N::translate_c('grandparent’s sibling’s grandchild', 'second cousin');
                                                                                                            }
                                                                                                        }
                                                                                                    }
                                                                                                }
                                                                                            }
                                                                                        }
                                                                                    }
                                                                                }
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    // Look for generic/pattern relationships.
    // TODO: these are heavily based on English relationship names.
    // We need feedback from other languages to improve this.
    // Dutch has special names for 8 generations of great-great-..., so these need explicit naming
    // Spanish has special names for four but also has two different numbering patterns
    if (preg_match('/^((?:mot|fat|par)+)(bro|sis|sib)$/', $path, $match)) {
        // siblings of direct ancestors
        $up = strlen($match[1]) / 3;
        $bef_last = substr($path, -6, 3);
        switch ($up) {
            case 3:
                switch ($sex2) {
                    case 'M':
                        if ($bef_last == 'fat') {
                            return WT_I18N::translate_c('great-grandfather’s brother', 'great-great-uncle');
                        } else {
                            if ($bef_last == 'mot') {
                                return WT_I18N::translate_c('great-grandmother’s brother', 'great-great-uncle');
                            } else {
                                return WT_I18N::translate_c('great-grandparent’s brother', 'great-great-uncle');
                            }
                        }
                    case 'F':
                        return WT_I18N::translate('great-great-aunt');
                    case 'U':
                        return WT_I18N::translate('great-great-aunt/uncle');
                }
                break;
            case 4:
                switch ($sex2) {
                    case 'M':
                        if ($bef_last == 'fat') {
                            return WT_I18N::translate_c('great-great-grandfather’s brother', 'great-great-great-uncle');
                        } else {
                            if ($bef_last == 'mot') {
                                return WT_I18N::translate_c('great-great-grandmother’s brother', 'great-great-great-uncle');
                            } else {
                                return WT_I18N::translate_c('great-great-grandparent’s brother', 'great-great-great-uncle');
                            }
                        }
                    case 'F':
                        return WT_I18N::translate('great-great-great-aunt');
                    case 'U':
                        return WT_I18N::translate('great-great-great-aunt/uncle');
                }
                break;
            case 5:
                switch ($sex2) {
                    case 'M':
                        if ($bef_last == 'fat') {
                            return WT_I18N::translate_c('great-great-great-grandfather’s brother', 'great ×4 uncle');
                        } else {
                            if ($bef_last == 'mot') {
                                return WT_I18N::translate_c('great-great-great-grandmother’s brother', 'great ×4 uncle');
                            } else {
                                return WT_I18N::translate_c('great-great-great-grandparent’s brother', 'great ×4 uncle');
                            }
                        }
                    case 'F':
                        return WT_I18N::translate('great ×4 aunt');
                    case 'U':
                        return WT_I18N::translate('great ×4 aunt/uncle');
                }
                break;
            case 6:
                switch ($sex2) {
                    case 'M':
                        if ($bef_last == 'fat') {
                            return WT_I18N::translate_c('great ×4 grandfather’s brother', 'great ×5 uncle');
                        } else {
                            if ($bef_last == 'mot') {
                                return WT_I18N::translate_c('great ×4 grandmother’s brother', 'great ×5 uncle');
                            } else {
                                return WT_I18N::translate_c('great ×4 grandparent’s brother', 'great ×5 uncle');
                            }
                        }
                    case 'F':
                        return WT_I18N::translate('great ×5 aunt');
                    case 'U':
                        return WT_I18N::translate('great ×5 aunt/uncle');
                }
                break;
            case 7:
                switch ($sex2) {
                    case 'M':
                        if ($bef_last == 'fat') {
                            return WT_I18N::translate_c('great ×5 grandfather’s brother', 'great ×6 uncle');
                        } else {
                            if ($bef_last == 'mot') {
                                return WT_I18N::translate_c('great ×5 grandmother’s brother', 'great ×6 uncle');
                            } else {
                                return WT_I18N::translate_c('great ×5 grandparent’s brother', 'great ×6 uncle');
                            }
                        }
                    case 'F':
                        return WT_I18N::translate('great ×6 aunt');
                    case 'U':
                        return WT_I18N::translate('great ×6 aunt/uncle');
                }
                break;
            case 8:
                switch ($sex2) {
                    case 'M':
                        if ($bef_last == 'fat') {
                            return WT_I18N::translate_c('great ×6 grandfather’s brother', 'great ×7 uncle');
                        } else {
                            if ($bef_last == 'mot') {
                                return WT_I18N::translate_c('great ×6 grandmother’s brother', 'great ×7 uncle');
                            } else {
                                return WT_I18N::translate_c('great ×6 grandparent’s brother', 'great ×7 uncle');
                            }
                        }
                    case 'F':
                        return WT_I18N::translate('great ×7 aunt');
                    case 'U':
                        return WT_I18N::translate('great ×7 aunt/uncle');
                }
                break;
            default:
                // Different languages have different rules for naming generations.
                // An English great ×12 uncle is a Danish great ×10 uncle.
                //
                // Need to find out which languages use which rules.
                switch (WT_LOCALE) {
                    case 'da':
                        switch ($sex2) {
                            case 'M':
                                return WT_I18N::translate('great ×%d uncle', $up - 4);
                            case 'F':
                                return WT_I18N::translate('great ×%d aunt', $up - 4);
                            case 'U':
                                return WT_I18N::translate('great ×%d aunt/uncle', $up - 4);
                        }
                    case 'pl':
                        switch ($sex2) {
                            case 'M':
                                if ($bef_last == 'fat') {
                                    return WT_I18N::translate_c('great ×(%d-1) grandfather’s brother', 'great ×%d uncle', $up - 2);
                                } else {
                                    if ($bef_last == 'mot') {
                                        return WT_I18N::translate_c('great ×(%d-1) grandmother’s brother', 'great ×%d uncle', $up - 2);
                                    } else {
                                        return WT_I18N::translate_c('great ×(%d-1) grandparent’s brother', 'great ×%d uncle', $up - 2);
                                    }
                                }
                            case 'F':
                                return WT_I18N::translate('great ×%d aunt', $up - 2);
                            case 'U':
                                return WT_I18N::translate('great ×%d aunt/uncle', $up - 2);
                        }
                    case 'it':
                        // Source: Michele Locati
                    // Source: Michele Locati
                    case 'en_AU':
                    case 'en_GB':
                    case 'en_US':
                    default:
                        switch ($sex2) {
                            case 'M':
                                // I18N: if you need a different number for %d, contact the developers, as a code-change is required
                                return WT_I18N::translate('great ×%d uncle', $up - 1);
                            case 'F':
                                return WT_I18N::translate('great ×%d aunt', $up - 1);
                            case 'U':
                                return WT_I18N::translate('great ×%d aunt/uncle', $up - 1);
                        }
                }
        }
    }
    if (preg_match('/^(?:bro|sis|sib)((?:son|dau|chi)+)$/', $path, $match)) {
        // direct descendants of siblings
        $down = strlen($match[1]) / 3 + 1;
        // Add one, as we count generations from the common ancestor
        $first = substr($path, 0, 3);
        switch ($down) {
            case 4:
                switch ($sex2) {
                    case 'M':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great-grandson', 'great-great-nephew');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great-grandson', 'great-great-nephew');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great-great-nephew', 'great-great-nephew');
                            }
                        }
                    case 'F':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great-granddaughter', 'great-great-niece');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great-granddaughter', 'great-great-niece');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great-great-niece', 'great-great-niece');
                            }
                        }
                    case 'U':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great-grandchild', 'great-great-nephew/niece');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great-grandchild', 'great-great-nephew/niece');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great-great-nephew/niece', 'great-great-nephew/niece');
                            }
                        }
                }
            case 5:
                switch ($sex2) {
                    case 'M':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great-great-grandson', 'great-great-great-nephew');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great-great-grandson', 'great-great-great-nephew');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great-great-great-nephew', 'great-great-great-nephew');
                            }
                        }
                    case 'F':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great-great-granddaughter', 'great-great-great-niece');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great-great-granddaughter', 'great-great-great-niece');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great-great-great-niece', 'great-great-great-niece');
                            }
                        }
                    case 'U':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great-great-grandchild', 'great-great-great-nephew/niece');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great-great-grandchild', 'great-great-great-nephew/niece');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great-great-great-nephew/niece', 'great-great-great-nephew/niece');
                            }
                        }
                }
            case 6:
                switch ($sex2) {
                    case 'M':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great-great-great-grandson', 'great ×4 nephew');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great-great-great-grandson', 'great ×4 nephew');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great ×4 nephew', 'great ×4 nephew');
                            }
                        }
                    case 'F':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great-great-great-granddaughter', 'great ×4 niece');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great-great-great-granddaughter', 'great ×4 niece');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great ×4 niece', 'great ×4 niece');
                            }
                        }
                    case 'U':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great-great-great-grandchild', 'great ×4 nephew/niece');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great-great-great-grandchild', 'great ×4 nephew/niece');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great ×4 nephew/niece', 'great ×4 nephew/niece');
                            }
                        }
                }
            case 7:
                switch ($sex2) {
                    case 'M':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great ×4 grandson', 'great ×5 nephew');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great ×4 grandson', 'great ×5 nephew');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great ×5 nephew', 'great ×5 nephew');
                            }
                        }
                    case 'F':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great ×4 granddaughter', 'great ×5 niece');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great ×4 granddaughter', 'great ×5 niece');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great ×5 niece', 'great ×5 niece');
                            }
                        }
                    case 'U':
                        if ($first == 'bro' && $sex1 == 'M') {
                            return WT_I18N::translate_c('(a man’s) brother’s great ×4 grandchild', 'great ×5 nephew/niece');
                        } else {
                            if ($first == 'sis' && $sex1 == 'M') {
                                return WT_I18N::translate_c('(a man’s) sister’s great ×4 grandchild', 'great ×5 nephew/niece');
                            } else {
                                return WT_I18N::translate_c('(a woman’s) great ×5 nephew/niece', 'great ×5 nephew/niece');
                            }
                        }
                }
            default:
                // Different languages have different rules for naming generations.
                // An English great ×12 nephew is a Polish great ×11 nephew.
                //
                // Need to find out which languages use which rules.
                switch (WT_LOCALE) {
                    case 'pl':
                        // Source: Lukasz Wilenski
                        switch ($sex2) {
                            case 'M':
                                if ($first == 'bro' && $sex1 == 'M') {
                                    return WT_I18N::translate_c('(a man’s) brother’s great ×(%d-1) grandson', 'great ×%d nephew', $down - 3);
                                } else {
                                    if ($first == 'sis' && $sex1 == 'M') {
                                        return WT_I18N::translate_c('(a man’s) sister’s great ×(%d-1) grandson', 'great ×%d nephew', $down - 3);
                                    } else {
                                        return WT_I18N::translate_c('(a woman’s) great ×%d nephew', 'great ×%d nephew', $down - 3);
                                    }
                                }
                            case 'F':
                                if ($first == 'bro' && $sex1 == 'M') {
                                    return WT_I18N::translate_c('(a man’s) brother’s great ×(%d-1) granddaughter', 'great ×%d niece', $down - 3);
                                } else {
                                    if ($first == 'sis' && $sex1 == 'M') {
                                        return WT_I18N::translate_c('(a man’s) sister’s great ×(%d-1) granddaughter', 'great ×%d niece', $down - 3);
                                    } else {
                                        return WT_I18N::translate_c('(a woman’s) great ×%d niece', 'great ×%d niece', $down - 3);
                                    }
                                }
                            case 'U':
                                if ($first == 'bro' && $sex1 == 'M') {
                                    return WT_I18N::translate_c('(a man’s) brother’s great ×(%d-1) grandchild', 'great ×%d nephew/niece', $down - 3);
                                } else {
                                    if ($first == 'sis' && $sex1 == 'M') {
                                        return WT_I18N::translate_c('(a man’s) sister’s great ×(%d-1) grandchild', 'great ×%d nephew/niece', $down - 3);
                                    } else {
                                        return WT_I18N::translate_c('(a woman’s) great ×%d nephew/niece', 'great ×%d nephew/niece', $down - 3);
                                    }
                                }
                        }
                    case 'he':
                        // Source: Meliza Amity
                        switch ($sex2) {
                            case 'M':
                                return WT_I18N::translate('great ×%d nephew', $down - 1);
                            case 'F':
                                return WT_I18N::translate('great ×%d niece', $down - 1);
                            case 'U':
                                return WT_I18N::translate('great ×%d nephew/niece', $down - 1);
                        }
                    case 'it':
                        // Source: Michele Locati.
                    // Source: Michele Locati.
                    case 'en_AU':
                    case 'en_GB':
                    case 'en_US':
                    default:
                        switch ($sex2) {
                            case 'M':
                                // I18N: if you need a different number for %d, contact the developers, as a code-change is required
                                return WT_I18N::translate('great ×%d nephew', $down - 2);
                            case 'F':
                                return WT_I18N::translate('great ×%d niece', $down - 2);
                            case 'U':
                                return WT_I18N::translate('great ×%d nephew/niece', $down - 2);
                        }
                }
        }
    }
    if (preg_match('/^((?:mot|fat|par)*)$/', $path, $match)) {
        // direct ancestors
        $up = strlen($match[1]) / 3;
        switch ($up) {
            case 4:
                switch ($sex2) {
                    case 'M':
                        return WT_I18N::translate('great-great-grandfather');
                    case 'F':
                        return WT_I18N::translate('great-great-grandmother');
                    case 'U':
                        return WT_I18N::translate('great-great-grandparent');
                }
                break;
            case 5:
                switch ($sex2) {
                    case 'M':
                        return WT_I18N::translate('great-great-great-grandfather');
                    case 'F':
                        return WT_I18N::translate('great-great-great-grandmother');
                    case 'U':
                        return WT_I18N::translate('great-great-great-grandparent');
                }
                break;
            case 6:
                switch ($sex2) {
                    case 'M':
                        return WT_I18N::translate('great ×4 grandfather');
                    case 'F':
                        return WT_I18N::translate('great ×4 grandmother');
                    case 'U':
                        return WT_I18N::translate('great ×4 grandparent');
                }
                break;
            case 7:
                switch ($sex2) {
                    case 'M':
                        return WT_I18N::translate('great ×5 grandfather');
                    case 'F':
                        return WT_I18N::translate('great ×5 grandmother');
                    case 'U':
                        return WT_I18N::translate('great ×5 grandparent');
                }
                break;
            case 8:
                switch ($sex2) {
                    case 'M':
                        return WT_I18N::translate('great ×6 grandfather');
                    case 'F':
                        return WT_I18N::translate('great ×6 grandmother');
                    case 'U':
                        return WT_I18N::translate('great ×6 grandparent');
                }
                break;
            case 9:
                switch ($sex2) {
                    case 'M':
                        return WT_I18N::translate('great ×7 grandfather');
                    case 'F':
                        return WT_I18N::translate('great ×7 grandmother');
                    case 'U':
                        return WT_I18N::translate('great ×7 grandparent');
                }
                break;
            default:
                // Different languages have different rules for naming generations.
                // An English great ×12 grandfather is a Danish great ×11 grandfather.
                //
                // Need to find out which languages use which rules.
                switch (WT_LOCALE) {
                    case 'da':
                        // Source: Patrick Sorensen
                        switch ($sex2) {
                            case 'M':
                                return WT_I18N::translate('great ×%d grandfather', $up - 3);
                            case 'F':
                                return WT_I18N::translate('great ×%d grandmother', $up - 3);
                            case 'U':
                                return WT_I18N::translate('great ×%d grandparent', $up - 3);
                        }
                    case 'it':
                        // Source: Michele Locati
                    // Source: Michele Locati
                    case 'es':
                        // Source: Wes Groleau
                        switch ($sex2) {
                            case 'M':
                                return WT_I18N::translate('great ×%d grandfather', $up);
                            case 'F':
                                return WT_I18N::translate('great ×%d grandmother', $up);
                            case 'U':
                                return WT_I18N::translate('great ×%d grandparent', $up);
                        }
                    case 'fr':
                        // Source: Jacqueline Tetreault
                    // Source: Jacqueline Tetreault
                    case 'fr_CA':
                        switch ($sex2) {
                            case 'M':
                                return WT_I18N::translate('great ×%d grandfather', $up - 1);
                            case 'F':
                                return WT_I18N::translate('great ×%d grandmother', $up - 1);
                            case 'U':
                                return WT_I18N::translate('great ×%d grandparent', $up - 1);
                        }
                    case 'nn':
                        // Source: Hogne Røed Nilsen (https://bugs.launchpad.net/webtrees/+bug/1168553)
                    // Source: Hogne Røed Nilsen (https://bugs.launchpad.net/webtrees/+bug/1168553)
                    case 'nb':
                        switch ($sex2) {
                            case 'M':
                                // I18N: if you need a different number for %d, contact the developers, as a code-change is required
                                return WT_I18N::translate('great ×%d grandfather', $up - 3);
                            case 'F':
                                return WT_I18N::translate('great ×%d grandmother', $up - 3);
                            case 'U':
                                return WT_I18N::translate('great ×%d grandparent', $up - 3);
                        }
                    case 'en_AU':
                    case 'en_GB':
                    case 'en_US':
                    default:
                        switch ($sex2) {
                            case 'M':
                                // I18N: if you need a different number for %d, contact the developers, as a code-change is required
                                return WT_I18N::translate('great ×%d grandfather', $up - 2);
                            case 'F':
                                return WT_I18N::translate('great ×%d grandmother', $up - 2);
                            case 'U':
                                return WT_I18N::translate('great ×%d grandparent', $up - 2);
                        }
                }
        }
    }
    if (preg_match('/^((?:son|dau|chi)*)$/', $path, $match)) {
        // direct descendants
        $up = strlen($match[1]) / 3;
        switch ($up) {
            case 4:
                switch ($sex2) {
                    case 'son':
                        return WT_I18N::translate('great-great-grandson');
                    case 'dau':
                        return WT_I18N::translate('great-great-granddaughter');
                    case 'chi':
                        return WT_I18N::translate('great-great-grandchild');
                }
                break;
            case 5:
                switch ($sex2) {
                    case 'M':
                        return WT_I18N::translate('great-great-great-grandson');
                    case 'F':
                        return WT_I18N::translate('great-great-great-granddaughter');
                    case 'U':
                        return WT_I18N::translate('great-great-great-grandchild');
                }
                break;
            case 6:
                switch ($sex2) {
                    case 'M':
                        return WT_I18N::translate('great ×4 grandson');
                    case 'F':
                        return WT_I18N::translate('great ×4 granddaughter');
                    case 'U':
                        return WT_I18N::translate('great ×4 grandchild');
                }
                break;
            case 7:
                switch ($sex2) {
                    case 'M':
                        return WT_I18N::translate('great ×5 grandson');
                    case 'F':
                        return WT_I18N::translate('great ×5 granddaughter');
                    case 'U':
                        return WT_I18N::translate('great ×5 grandchild');
                }
                break;
            case 8:
                switch ($sex2) {
                    case 'M':
                        return WT_I18N::translate('great ×6 grandson');
                    case 'F':
                        return WT_I18N::translate('great ×6 granddaughter');
                    case 'U':
                        return WT_I18N::translate('great ×6 grandchild');
                }
                break;
            case 9:
                switch ($sex2) {
                    case 'M':
                        return WT_I18N::translate('great ×7 grandson');
                    case 'F':
                        return WT_I18N::translate('great ×7 granddaughter');
                    case 'U':
                        return WT_I18N::translate('great ×7 grandchild');
                }
                break;
            default:
                // Different languages have different rules for naming generations.
                // An English great ×12 grandson is a Danish great ×11 grandson.
                //
                // Need to find out which languages use which rules.
                switch (WT_LOCALE) {
                    case 'nn':
                        // Source: Hogne Røed Nilsen
                    // Source: Hogne Røed Nilsen
                    case 'nb':
                    case 'da':
                        // Source: Patrick Sorensen
                        switch ($sex2) {
                            case 'M':
                                return WT_I18N::translate('great ×%d grandson', $up - 3);
                            case 'F':
                                return WT_I18N::translate('great ×%d granddaughter', $up - 3);
                            case 'U':
                                return WT_I18N::translate('great ×%d grandchild', $up - 3);
                        }
                    case 'it':
                        // Source: Michele Locati
                    // Source: Michele Locati
                    case 'es':
                        // Source: Wes Groleau (adding doesn’t change behavior, but needs to be better researched)
                    // Source: Wes Groleau (adding doesn’t change behavior, but needs to be better researched)
                    case 'en_AU':
                    case 'en_GB':
                    case 'en_US':
                    default:
                        switch ($sex2) {
                            case 'M':
                                // I18N: if you need a different number for %d, contact the developers, as a code-change is required
                                return WT_I18N::translate('great ×%d grandson', $up - 2);
                            case 'F':
                                return WT_I18N::translate('great ×%d granddaughter', $up - 2);
                            case 'U':
                                return WT_I18N::translate('great ×%d grandchild', $up - 2);
                        }
                }
        }
    }
    if (preg_match('/^((?:mot|fat|par)+)(?:bro|sis|sib)((?:son|dau|chi)+)$/', $path, $match)) {
        // cousins in English
        $ascent = $match[1];
        $descent = $match[2];
        $up = strlen($ascent) / 3;
        $down = strlen($descent) / 3;
        $cousin = min($up, $down);
        // Moved out of switch (en/default case) so that
        $removed = abs($down - $up);
        // Spanish (and other languages) can use it, too.
        // Different languages have different rules for naming cousins.  For example,
        // an English “second cousin once removed” is a Polish “cousin of 7th degree”.
        //
        // Need to find out which languages use which rules.
        switch (WT_LOCALE) {
            case 'pl':
                // Source: Lukasz Wilenski
                return cousin_name($up + $down + 2, $sex2);
            case 'it':
                // Source: Michele Locati.  See italian_cousins_names.zip
                // http://webtrees.net/forums/8-translation/1200-great-xn-grandparent?limit=6&start=6
                return cousin_name($up + $down - 3, $sex2);
            case 'es':
                // Source: Wes Groleau.  See http://UniGen.us/Parentesco.html & http://UniGen.us/Parentesco-D.html
                if ($down == $up) {
                    return cousin_name($cousin, $sex2);
                } elseif ($down < $up) {
                    return cousin_name2($cousin + 1, $sex2, get_relationship_name_from_path('sib' . $descent, null, null));
                } else {
                    switch ($sex2) {
                        case 'M':
                            return cousin_name2($cousin + 1, $sex2, get_relationship_name_from_path('bro' . $descent, null, null));
                        case 'F':
                            return cousin_name2($cousin + 1, $sex2, get_relationship_name_from_path('sis' . $descent, null, null));
                        case 'U':
                            return cousin_name2($cousin + 1, $sex2, get_relationship_name_from_path('sib' . $descent, null, null));
                    }
                }
            case 'en_AU':
                // See: http://en.wikipedia.org/wiki/File:CousinTree.svg
            // See: http://en.wikipedia.org/wiki/File:CousinTree.svg
            case 'en_GB':
            case 'en_US':
            default:
                switch ($removed) {
                    case 0:
                        return cousin_name($cousin, $sex2);
                    case 1:
                        if ($up > $down) {
                            /* I18N: %s=“fifth cousin”, etc. http://www.ancestry.com/learn/library/article.aspx?article=2856 */
                            return WT_I18N::translate('%s once removed ascending', cousin_name($cousin, $sex2));
                        } else {
                            /* I18N: %s=“fifth cousin”, etc. http://www.ancestry.com/learn/library/article.aspx?article=2856 */
                            return WT_I18N::translate('%s once removed descending', cousin_name($cousin, $sex2));
                        }
                    case 2:
                        if ($up > $down) {
                            /* I18N: %s=“fifth cousin”, etc. */
                            return WT_I18N::translate('%s twice removed ascending', cousin_name($cousin, $sex2));
                        } else {
                            /* I18N: %s=“fifth cousin”, etc. */
                            return WT_I18N::translate('%s twice removed descending', cousin_name($cousin, $sex2));
                        }
                    case 3:
                        if ($up > $down) {
                            /* I18N: %s=“fifth cousin”, etc. */
                            return WT_I18N::translate('%s three times removed ascending', cousin_name($cousin, $sex2));
                        } else {
                            /* I18N: %s=“fifth cousin”, etc. */
                            return WT_I18N::translate('%s three times removed descending', cousin_name($cousin, $sex2));
                        }
                    default:
                        if ($up > $down) {
                            /* I18N: %1$s=“fifth cousin”, etc., %2$d>=4 */
                            return WT_I18N::translate('%1$s %2$d times removed ascending', cousin_name($cousin, $sex2), $removed);
                        } else {
                            /* I18N: %1$s=“fifth cousin”, etc., %2$d>=4 */
                            return WT_I18N::translate('%1$s %2$d times removed descending', cousin_name($cousin, $sex2), $removed);
                        }
                }
        }
    }
    // Split the relationship into sub-relationships, e.g., third-cousin’s great-uncle.
    // Try splitting at every point, and choose the path with the shorted translated name.
    $relationship = null;
    $path1 = substr($path, 0, 3);
    $path2 = substr($path, 3);
    while ($path2) {
        $tmp = WT_I18N::translate('%1$s’s %2$s', get_relationship_name_from_path($path1, null, null), get_relationship_name_from_path($path2, null, null));
        if (!$relationship || strlen($tmp) < strlen($relationship)) {
            $relationship = $tmp;
        }
        $path1 .= substr($path2, 0, 3);
        $path2 = substr($path2, 3);
    }
    return $relationship;
}
/**
 * import record into database
 *
 * this function will parse the given gedcom record and add it to the database
 *
 * @param string  $gedrec the raw gedcom record to parse
 * @param integer $ged_id import the record into this gedcom
 * @param boolean $update whether or not this is an updated record that has been accepted
 */
function import_record($gedrec, $ged_id, $update)
{
    global $USE_RIN, $GENERATE_UIDS, $keep_media;
    static $sql_insert_indi = null;
    static $sql_insert_fam = null;
    static $sql_insert_sour = null;
    static $sql_insert_media = null;
    static $sql_insert_other = null;
    if (!$sql_insert_indi) {
        $sql_insert_indi = WT_DB::prepare("INSERT INTO `##individuals` (i_id, i_file, i_rin, i_sex, i_gedcom) VALUES (?,?,?,?,?)");
        $sql_insert_fam = WT_DB::prepare("INSERT INTO `##families` (f_id, f_file, f_husb, f_wife, f_gedcom, f_numchil) VALUES (?,?,?,?,?,?)");
        $sql_insert_sour = WT_DB::prepare("INSERT INTO `##sources` (s_id, s_file, s_name, s_gedcom) VALUES (?,?,?,?)");
        $sql_insert_media = WT_DB::prepare("INSERT INTO `##media` (m_id, m_ext, m_type, m_titl, m_filename, m_file, m_gedcom) VALUES (?, ?, ?, ?, ?, ?, ?)");
        $sql_insert_other = WT_DB::prepare("INSERT INTO `##other` (o_id, o_file, o_type, o_gedcom) VALUES (?,?,?,?)");
    }
    // Escaped @ signs (only if importing from file)
    if (!$update) {
        $gedrec = str_replace('@@', '@', $gedrec);
    }
    // Standardise gedcom format
    $gedrec = reformat_record_import($gedrec);
    // import different types of records
    if (preg_match('/^0 @(' . WT_REGEX_XREF . ')@ (' . WT_REGEX_TAG . ')/', $gedrec, $match)) {
        list(, $xref, $type) = $match;
        // check for a _UID, if the record doesn't have one, add one
        if ($GENERATE_UIDS && !strpos($gedrec, "\n1 _UID ")) {
            $gedrec .= "\n1 _UID " . WT_Gedcom_Tag::createUid();
        }
    } elseif (preg_match('/0 (HEAD|TRLR)/', $gedrec, $match)) {
        $type = $match[1];
        $xref = $type;
        // For HEAD/TRLR, use type as pseudo XREF.
    } else {
        echo WT_I18N::translate('Invalid GEDCOM format'), '<br><pre>', $gedrec, '</pre>';
        return;
    }
    // If the user has downloaded their GEDCOM data (containing media objects) and edited it
    // using an application which does not support (and deletes) media objects, then add them
    // back in.
    if ($keep_media && $xref) {
        $old_linked_media = WT_DB::prepare("SELECT l_to FROM `##link` WHERE l_from=? AND l_file=? AND l_type='OBJE'")->execute(array($xref, $ged_id))->fetchOneColumn();
        foreach ($old_linked_media as $media_id) {
            $gedrec .= "\n1 OBJE @" . $media_id . "@";
        }
    }
    switch ($type) {
        case 'INDI':
            // Convert inline media into media objects
            $gedrec = convert_inline_media($ged_id, $gedrec);
            $record = new WT_Individual($xref, $gedrec, null, $ged_id);
            if ($USE_RIN && preg_match('/\\n1 RIN (.+)/', $gedrec, $match)) {
                $rin = $match[1];
            } else {
                $rin = $xref;
            }
            $sql_insert_indi->execute(array($xref, $ged_id, $rin, $record->getSex(), $gedrec));
            // Update the cross-reference/index tables.
            update_places($xref, $ged_id, $gedrec);
            update_dates($xref, $ged_id, $gedrec);
            update_links($xref, $ged_id, $gedrec);
            update_names($xref, $ged_id, $record);
            break;
        case 'FAM':
            // Convert inline media into media objects
            $gedrec = convert_inline_media($ged_id, $gedrec);
            if (preg_match('/\\n1 HUSB @(' . WT_REGEX_XREF . ')@/', $gedrec, $match)) {
                $husb = $match[1];
            } else {
                $husb = '';
            }
            if (preg_match('/\\n1 WIFE @(' . WT_REGEX_XREF . ')@/', $gedrec, $match)) {
                $wife = $match[1];
            } else {
                $wife = '';
            }
            $nchi = preg_match_all('/\\n1 CHIL @(' . WT_REGEX_XREF . ')@/', $gedrec, $match);
            if (preg_match('/\\n1 NCHI (\\d+)/', $gedrec, $match)) {
                $nchi = max($nchi, $match[1]);
            }
            $sql_insert_fam->execute(array($xref, $ged_id, $husb, $wife, $gedrec, $nchi));
            // Update the cross-reference/index tables.
            update_places($xref, $ged_id, $gedrec);
            update_dates($xref, $ged_id, $gedrec);
            update_links($xref, $ged_id, $gedrec);
            break;
        case 'SOUR':
            // Convert inline media into media objects
            $gedrec = convert_inline_media($ged_id, $gedrec);
            $record = new WT_Source($xref, $gedrec, null, $ged_id);
            if (preg_match('/\\n1 TITL (.+)/', $gedrec, $match)) {
                $name = $match[1];
            } elseif (preg_match('/\\n1 ABBR (.+)/', $gedrec, $match)) {
                $name = $match[1];
            } else {
                $name = $xref;
            }
            $sql_insert_sour->execute(array($xref, $ged_id, $name, $gedrec));
            // Update the cross-reference/index tables.
            update_links($xref, $ged_id, $gedrec);
            update_names($xref, $ged_id, $record);
            break;
        case 'REPO':
            // Convert inline media into media objects
            $gedrec = convert_inline_media($ged_id, $gedrec);
            $record = new WT_Repository($xref, $gedrec, null, $ged_id);
            $sql_insert_other->execute(array($xref, $ged_id, $type, $gedrec));
            // Update the cross-reference/index tables.
            update_links($xref, $ged_id, $gedrec);
            update_names($xref, $ged_id, $record);
            break;
        case 'NOTE':
            $record = new WT_Note($xref, $gedrec, null, $ged_id);
            $sql_insert_other->execute(array($xref, $ged_id, $type, $gedrec));
            // Update the cross-reference/index tables.
            update_links($xref, $ged_id, $gedrec);
            update_names($xref, $ged_id, $record);
            break;
        case 'OBJE':
            $record = new WT_Media($xref, $gedrec, null, $ged_id);
            $sql_insert_media->execute(array($xref, $record->extension(), $record->getMediaType(), $record->title, $record->file, $ged_id, $gedrec));
            // Update the cross-reference/index tables.
            update_links($xref, $ged_id, $gedrec);
            update_names($xref, $ged_id, $record);
            break;
        case 'HEAD':
            // Force HEAD records to have a creation date.
            if (!strpos($gedrec, "\n1 DATE ")) {
                $gedrec .= "\n1 DATE " . date('j M Y');
            }
            // No break;
        // No break;
        case 'TRLR':
        case 'SUBM':
        case 'SUBN':
            $sql_insert_other->execute(array($xref, $ged_id, $type, $gedrec));
            // Update the cross-reference/index tables.
            update_links($xref, $ged_id, $gedrec);
            break;
        default:
            $record = new WT_GedcomRecord($xref, $gedrec, null, $ged_id);
            $sql_insert_other->execute(array($xref, $ged_id, $type, $gedrec));
            // Update the cross-reference/index tables.
            update_links($xref, $ged_id, $gedrec);
            update_names($xref, $ged_id, $record);
            break;
    }
}