mirror of
https://github.com/PeWu/topola-viewer.git
synced 2026-04-11 00:56:16 +00:00
Name types in details panel (#109)
This commit is contained in:
12
package-lock.json
generated
12
package-lock.json
generated
@@ -5,7 +5,6 @@
|
|||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "topola-viewer",
|
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@artsy/fresnel": "^1.3.1",
|
"@artsy/fresnel": "^1.3.1",
|
||||||
@@ -38,6 +37,7 @@
|
|||||||
"semantic-ui-css": "^2.4.1",
|
"semantic-ui-css": "^2.4.1",
|
||||||
"semantic-ui-react": "^2.0.3",
|
"semantic-ui-react": "^2.0.3",
|
||||||
"topola": "^3.5.0",
|
"topola": "^3.5.0",
|
||||||
|
"turbocommons-ts": "^3.8.0",
|
||||||
"unified": "^10.1.0",
|
"unified": "^10.1.0",
|
||||||
"wikitree-js": "^0.1.0"
|
"wikitree-js": "^0.1.0"
|
||||||
},
|
},
|
||||||
@@ -22907,6 +22907,11 @@
|
|||||||
"node": "*"
|
"node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/turbocommons-ts": {
|
||||||
|
"version": "3.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/turbocommons-ts/-/turbocommons-ts-3.8.0.tgz",
|
||||||
|
"integrity": "sha512-EQRCm2r944M/TqzfRutaCwTN+eHVLPAedaWF8catAHd49biN1UjB9CGLTBT2kI3i9lCccSt84s8YFf54u1WcAg=="
|
||||||
|
},
|
||||||
"node_modules/tweetnacl": {
|
"node_modules/tweetnacl": {
|
||||||
"version": "0.14.5",
|
"version": "0.14.5",
|
||||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||||
@@ -44181,6 +44186,11 @@
|
|||||||
"safe-buffer": "^5.0.1"
|
"safe-buffer": "^5.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"turbocommons-ts": {
|
||||||
|
"version": "3.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/turbocommons-ts/-/turbocommons-ts-3.8.0.tgz",
|
||||||
|
"integrity": "sha512-EQRCm2r944M/TqzfRutaCwTN+eHVLPAedaWF8catAHd49biN1UjB9CGLTBT2kI3i9lCccSt84s8YFf54u1WcAg=="
|
||||||
|
},
|
||||||
"tweetnacl": {
|
"tweetnacl": {
|
||||||
"version": "0.14.5",
|
"version": "0.14.5",
|
||||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
"semantic-ui-css": "^2.4.1",
|
"semantic-ui-css": "^2.4.1",
|
||||||
"semantic-ui-react": "^2.0.3",
|
"semantic-ui-react": "^2.0.3",
|
||||||
"topola": "^3.5.0",
|
"topola": "^3.5.0",
|
||||||
|
"turbocommons-ts": "^3.8.0",
|
||||||
"unified": "^10.1.0",
|
"unified": "^10.1.0",
|
||||||
"wikitree-js": "^0.1.0"
|
"wikitree-js": "^0.1.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -14,12 +14,13 @@ import {GedcomEntry} from 'parse-gedcom';
|
|||||||
import {IntlShape} from 'react-intl';
|
import {IntlShape} from 'react-intl';
|
||||||
import {TopolaError} from '../util/error';
|
import {TopolaError} from '../util/error';
|
||||||
import {isValidDateOrRange} from '../util/date_util';
|
import {isValidDateOrRange} from '../util/date_util';
|
||||||
|
import {StringUtils} from 'turbocommons-ts';
|
||||||
import {
|
import {
|
||||||
getAncestors as getAncestorsApi,
|
getAncestors as getAncestorsApi,
|
||||||
getRelatives as getRelativesApi,
|
getRelatives as getRelativesApi,
|
||||||
clientLogin,
|
clientLogin,
|
||||||
getLoggedInUserName,
|
getLoggedInUserName,
|
||||||
Person
|
Person,
|
||||||
} from 'wikitree-js';
|
} from 'wikitree-js';
|
||||||
|
|
||||||
/** Prefix for IDs of private individuals. */
|
/** Prefix for IDs of private individuals. */
|
||||||
@@ -66,7 +67,7 @@ async function getAncestors(
|
|||||||
if (cachedData) {
|
if (cachedData) {
|
||||||
return JSON.parse(cachedData);
|
return JSON.parse(cachedData);
|
||||||
}
|
}
|
||||||
const result = getAncestorsApi(key, {}, getApiOptions(handleCors));
|
const result = await getAncestorsApi(key, {}, getApiOptions(handleCors));
|
||||||
setSessionStorageItem(cacheKey, JSON.stringify(result));
|
setSessionStorageItem(cacheKey, JSON.stringify(result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -225,6 +226,12 @@ export async function loadWikiTree(
|
|||||||
generation++;
|
generation++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Map from human-readable person id to person names
|
||||||
|
const personNames = new Map<
|
||||||
|
string,
|
||||||
|
{birth?: string; married?: string; aka?: string}
|
||||||
|
>();
|
||||||
|
|
||||||
// Map from person id to the set of families where they are a spouse.
|
// Map from person id to the set of families where they are a spouse.
|
||||||
const families = new Map<number, Set<string>>();
|
const families = new Map<number, Set<string>>();
|
||||||
// Map from family id to the set of children.
|
// Map from family id to the set of children.
|
||||||
@@ -268,6 +275,9 @@ export async function loadWikiTree(
|
|||||||
`https://www.wikitree.com${person.PhotoData.path}`,
|
`https://www.wikitree.com${person.PhotoData.path}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
personNames.set(person.Name, convertPersonNames(person));
|
||||||
|
|
||||||
if (person.Spouses) {
|
if (person.Spouses) {
|
||||||
Object.values(person.Spouses).forEach((spouse) => {
|
Object.values(person.Spouses).forEach((spouse) => {
|
||||||
const famId = getFamilyId(person.Id, spouse.Id);
|
const famId = getFamilyId(person.Id, spouse.Id);
|
||||||
@@ -314,7 +324,7 @@ export async function loadWikiTree(
|
|||||||
});
|
});
|
||||||
|
|
||||||
const chartData = normalizeGedcom({indis, fams});
|
const chartData = normalizeGedcom({indis, fams});
|
||||||
const gedcom = buildGedcom(chartData, fullSizePhotoUrls);
|
const gedcom = buildGedcom(chartData, fullSizePhotoUrls, personNames);
|
||||||
return {chartData, gedcom};
|
return {chartData, gedcom};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,6 +397,50 @@ function convertPerson(person: Person, intl: IntlShape): JsonIndi {
|
|||||||
}
|
}
|
||||||
return indi;
|
return indi;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
Resolve birth name, married name and aka name with following logic:
|
||||||
|
- birth name is always prioritized and is set if exists and is not unknown
|
||||||
|
- married name is based on LastNameCurrent and is set if it's different than birth name
|
||||||
|
and one of the spouses has it as their birth name
|
||||||
|
- aka name is based on LastNameOther and is set if it's different than others
|
||||||
|
*/
|
||||||
|
function convertPersonNames(person: Person) {
|
||||||
|
return {
|
||||||
|
birth:
|
||||||
|
person.LastNameAtBirth !== 'Unknown' ? person.LastNameAtBirth : undefined,
|
||||||
|
married:
|
||||||
|
person.Spouses &&
|
||||||
|
person.LastNameCurrent !== 'Unknown' &&
|
||||||
|
person.LastNameCurrent !== person.LastNameAtBirth &&
|
||||||
|
Object.entries(person.Spouses)
|
||||||
|
.flatMap(([, spousePerson]) =>
|
||||||
|
spousePerson.LastNameAtBirth.split(/[- ,]/),
|
||||||
|
)
|
||||||
|
.filter(
|
||||||
|
(spousePersonNamePart) =>
|
||||||
|
/* In some languages the same names can differ a bit between genders,
|
||||||
|
so regular equals comparison cannot be used.
|
||||||
|
To verify if spouse has the same name, person name is split to include people with double names,
|
||||||
|
then there is a check if any name part is at least 75% similar to spouse name.
|
||||||
|
*/
|
||||||
|
person.LastNameCurrent.split(/[- ,]/).filter(
|
||||||
|
(personNamePart) =>
|
||||||
|
StringUtils.compareSimilarityPercent(
|
||||||
|
spousePersonNamePart,
|
||||||
|
personNamePart,
|
||||||
|
) >= 75,
|
||||||
|
).length,
|
||||||
|
).length
|
||||||
|
? person.LastNameCurrent
|
||||||
|
: undefined,
|
||||||
|
aka:
|
||||||
|
person.LastNameOther !== 'Unknown' &&
|
||||||
|
person.LastNameAtBirth !== person.LastNameOther &&
|
||||||
|
person.LastNameCurrent !== person.LastNameOther
|
||||||
|
? person.LastNameOther
|
||||||
|
: undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a date in the format returned by WikiTree and converts in to
|
* Parses a date in the format returned by WikiTree and converts in to
|
||||||
@@ -468,6 +522,24 @@ function dateOrRangeToGedcom(dateOrRange: DateOrRange): string {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function nameToGedcom(type: string, firstName?: string, lastName?: string) {
|
||||||
|
return {
|
||||||
|
level: 1,
|
||||||
|
pointer: '',
|
||||||
|
tag: 'NAME',
|
||||||
|
data: `${firstName || ''} /${lastName || ''}/`,
|
||||||
|
tree: [
|
||||||
|
{
|
||||||
|
level: 2,
|
||||||
|
pointer: '',
|
||||||
|
tag: 'TYPE',
|
||||||
|
data: type,
|
||||||
|
tree: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function eventToGedcom(event: JsonEvent): GedcomEntry[] {
|
function eventToGedcom(event: JsonEvent): GedcomEntry[] {
|
||||||
const result = [];
|
const result = [];
|
||||||
if (isValidDateOrRange(event)) {
|
if (isValidDateOrRange(event)) {
|
||||||
@@ -524,6 +596,7 @@ function imageToGedcom(
|
|||||||
function indiToGedcom(
|
function indiToGedcom(
|
||||||
indi: JsonIndi,
|
indi: JsonIndi,
|
||||||
fullSizePhotoUrl: Map<string, string>,
|
fullSizePhotoUrl: Map<string, string>,
|
||||||
|
personNames: {birth?: string; married?: string; aka?: string},
|
||||||
): GedcomEntry {
|
): GedcomEntry {
|
||||||
// WikiTree URLs replace spaces with underscores.
|
// WikiTree URLs replace spaces with underscores.
|
||||||
const escapedId = indi.id.replace(/ /g, '_');
|
const escapedId = indi.id.replace(/ /g, '_');
|
||||||
@@ -532,16 +605,21 @@ function indiToGedcom(
|
|||||||
pointer: `@${indi.id}@`,
|
pointer: `@${indi.id}@`,
|
||||||
tag: 'INDI',
|
tag: 'INDI',
|
||||||
data: '',
|
data: '',
|
||||||
tree: [
|
|
||||||
{
|
|
||||||
level: 1,
|
|
||||||
pointer: '',
|
|
||||||
tag: 'NAME',
|
|
||||||
data: `${indi.firstName || ''} /${indi.lastName || ''}/`,
|
|
||||||
tree: [],
|
tree: [],
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (personNames.birth) {
|
||||||
|
record.tree.push(nameToGedcom('birth', indi.firstName, personNames.birth));
|
||||||
|
}
|
||||||
|
if (personNames.married) {
|
||||||
|
record.tree.push(
|
||||||
|
nameToGedcom('married', indi.firstName, personNames.married),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (personNames.aka) {
|
||||||
|
record.tree.push(nameToGedcom('aka', indi.firstName, personNames.aka));
|
||||||
|
}
|
||||||
|
|
||||||
if (indi.birth) {
|
if (indi.birth) {
|
||||||
record.tree.push({
|
record.tree.push({
|
||||||
level: 1,
|
level: 1,
|
||||||
@@ -653,11 +731,16 @@ function famToGedcom(fam: JsonFam): GedcomEntry {
|
|||||||
function buildGedcom(
|
function buildGedcom(
|
||||||
data: JsonGedcomData,
|
data: JsonGedcomData,
|
||||||
fullSizePhotoUrls: Map<string, string>,
|
fullSizePhotoUrls: Map<string, string>,
|
||||||
|
personNames: Map<string, {birth?: string; married?: string; aka?: string}>,
|
||||||
): GedcomData {
|
): GedcomData {
|
||||||
const gedcomIndis: {[key: string]: GedcomEntry} = {};
|
const gedcomIndis: {[key: string]: GedcomEntry} = {};
|
||||||
const gedcomFams: {[key: string]: GedcomEntry} = {};
|
const gedcomFams: {[key: string]: GedcomEntry} = {};
|
||||||
data.indis.forEach((indi) => {
|
data.indis.forEach((indi) => {
|
||||||
gedcomIndis[indi.id] = indiToGedcom(indi, fullSizePhotoUrls);
|
gedcomIndis[indi.id] = indiToGedcom(
|
||||||
|
indi,
|
||||||
|
fullSizePhotoUrls,
|
||||||
|
personNames.get(indi.id) || {},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
data.fams.forEach((fam) => {
|
data.fams.forEach((fam) => {
|
||||||
gedcomFams[fam.id] = famToGedcom(fam);
|
gedcomFams[fam.id] = famToGedcom(fam);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {GedcomEntry} from 'parse-gedcom';
|
|||||||
import {MultilineText} from './multiline-text';
|
import {MultilineText} from './multiline-text';
|
||||||
import {TranslatedTag} from './translated-tag';
|
import {TranslatedTag} from './translated-tag';
|
||||||
import {Header, Item} from 'semantic-ui-react';
|
import {Header, Item} from 'semantic-ui-react';
|
||||||
|
import {FormattedMessage} from 'react-intl';
|
||||||
import {WrappedImage} from './wrapped-image';
|
import {WrappedImage} from './wrapped-image';
|
||||||
|
|
||||||
const EXCLUDED_TAGS = [
|
const EXCLUDED_TAGS = [
|
||||||
@@ -83,18 +84,27 @@ function noteDetails(entry: GedcomEntry) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function nameDetails(entry: GedcomEntry) {
|
function nameDetails(entry: GedcomEntry) {
|
||||||
|
const fullName = entry.data.replaceAll('/', '');
|
||||||
|
|
||||||
|
const nameType = entry.tree.find(
|
||||||
|
(entry) => entry.tag === 'TYPE' && entry.data !== 'Unknown',
|
||||||
|
)?.data;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Header size="large">
|
<>
|
||||||
{entry.data
|
<Header as="span" size="large">
|
||||||
.split('/')
|
{fullName ? (
|
||||||
.filter((name) => !!name)
|
fullName
|
||||||
.map((name, index) => (
|
) : (
|
||||||
<div key={index}>
|
<FormattedMessage id="name.unknown_name" defaultMessage="N.N." />
|
||||||
{name}
|
)}
|
||||||
<br />
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</Header>
|
</Header>
|
||||||
|
{fullName && nameType && (
|
||||||
|
<Item.Meta>
|
||||||
|
<TranslatedTag tag={nameType} />
|
||||||
|
</Item.Meta>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {compareDates, formatDateOrRange} from '../util/date_util';
|
|||||||
import {DateOrRange, getDate} from 'topola';
|
import {DateOrRange, getDate} from 'topola';
|
||||||
import {dereference, GedcomData, getData, getName} from '../util/gedcom_util';
|
import {dereference, GedcomData, getData, getName} from '../util/gedcom_util';
|
||||||
import {GedcomEntry} from 'parse-gedcom';
|
import {GedcomEntry} from 'parse-gedcom';
|
||||||
import {IntlShape, useIntl} from 'react-intl';
|
import {FormattedMessage, IntlShape, useIntl} from 'react-intl';
|
||||||
import {Link, useLocation} from 'react-router-dom';
|
import {Link, useLocation} from 'react-router-dom';
|
||||||
import {MultilineText} from './multiline-text';
|
import {MultilineText} from './multiline-text';
|
||||||
import {pointerToId} from '../util/gedcom_util';
|
import {pointerToId} from '../util/gedcom_util';
|
||||||
@@ -16,9 +16,6 @@ function PersonLink(props: {person: GedcomEntry}) {
|
|||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
const name = getName(props.person);
|
const name = getName(props.person);
|
||||||
if (!name) {
|
|
||||||
return <></>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const search = queryString.parse(location.search);
|
const search = queryString.parse(location.search);
|
||||||
search['indi'] = pointerToId(props.person.pointer);
|
search['indi'] = pointerToId(props.person.pointer);
|
||||||
@@ -26,7 +23,11 @@ function PersonLink(props: {person: GedcomEntry}) {
|
|||||||
return (
|
return (
|
||||||
<Item.Meta>
|
<Item.Meta>
|
||||||
<Link to={{pathname: '/view', search: queryString.stringify(search)}}>
|
<Link to={{pathname: '/view', search: queryString.stringify(search)}}>
|
||||||
{name}
|
{name ? (
|
||||||
|
name
|
||||||
|
) : (
|
||||||
|
<FormattedMessage id="name.unknown_name" defaultMessage="N.N." />
|
||||||
|
)}
|
||||||
</Link>
|
</Link>
|
||||||
</Item.Meta>
|
</Item.Meta>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -22,6 +22,11 @@ const TAG_DESCRIPTIONS = new Map([
|
|||||||
['OCCU', 'Occupation'],
|
['OCCU', 'Occupation'],
|
||||||
['TITL', 'Title'],
|
['TITL', 'Title'],
|
||||||
['WWW', 'WWW'],
|
['WWW', 'WWW'],
|
||||||
|
['birth', 'Birth name'],
|
||||||
|
['married', 'Married name'],
|
||||||
|
['maiden', 'Maiden name'],
|
||||||
|
['immigrant', 'Immigrant name'],
|
||||||
|
['aka', 'Also known as'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
|||||||
@@ -6,10 +6,7 @@ import {FormattedMessage, useIntl} from 'react-intl';
|
|||||||
import {MenuItem, MenuType} from './menu_item';
|
import {MenuItem, MenuType} from './menu_item';
|
||||||
import {useEffect, useRef, useState} from 'react';
|
import {useEffect, useRef, useState} from 'react';
|
||||||
import {useHistory, useLocation} from 'react-router';
|
import {useHistory, useLocation} from 'react-router';
|
||||||
import {
|
import {getLoggedInUserName, navigateToLoginPage} from 'wikitree-js';
|
||||||
getLoggedInUserName,
|
|
||||||
navigateToLoginPage,
|
|
||||||
} from 'wikitree-js';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
menuType: MenuType;
|
menuType: MenuType;
|
||||||
|
|||||||
@@ -55,6 +55,10 @@
|
|||||||
"gedcom.WWW": "Stránka WWW",
|
"gedcom.WWW": "Stránka WWW",
|
||||||
"gedcom.RELI": "Vyznání",
|
"gedcom.RELI": "Vyznání",
|
||||||
"gedcom._UPD": "Poslední aktualizace",
|
"gedcom._UPD": "Poslední aktualizace",
|
||||||
|
"gedcom.birth": "Rodinné jméno",
|
||||||
|
"gedcom.married": "Manželské jméno",
|
||||||
|
"gedcom.maiden": "Jméno za svobodna",
|
||||||
|
"gedcom.aka": "Také znám(a) jako",
|
||||||
"date.abt": "kolem",
|
"date.abt": "kolem",
|
||||||
"date.cal": "spočteno",
|
"date.cal": "spočteno",
|
||||||
"date.est": "asi",
|
"date.est": "asi",
|
||||||
|
|||||||
@@ -51,6 +51,10 @@
|
|||||||
"gedcom.TITL": "Titel",
|
"gedcom.TITL": "Titel",
|
||||||
"gedcom.WWW": "Website",
|
"gedcom.WWW": "Website",
|
||||||
"gedcom._UPD": "Zuletzt aktualisiert",
|
"gedcom._UPD": "Zuletzt aktualisiert",
|
||||||
|
"gedcom.birth": "Geburtsname",
|
||||||
|
"gedcom.married": "Ehenamen",
|
||||||
|
"gedcom.maiden": "Mädchenname",
|
||||||
|
"gedcom.aka": "Auch bekannt als",
|
||||||
"date.abt": "about",
|
"date.abt": "about",
|
||||||
"date.cal": "berechnet",
|
"date.cal": "berechnet",
|
||||||
"date.est": "geschätzt",
|
"date.est": "geschätzt",
|
||||||
|
|||||||
@@ -50,6 +50,10 @@
|
|||||||
"gedcom.RIN": "ID",
|
"gedcom.RIN": "ID",
|
||||||
"gedcom.TITL": "Titre",
|
"gedcom.TITL": "Titre",
|
||||||
"gedcom.WWW": "Site Web",
|
"gedcom.WWW": "Site Web",
|
||||||
|
"gedcom.birth": "Nom de naissance",
|
||||||
|
"gedcom.married": "Nom marital",
|
||||||
|
"gedcom.maiden": "Nom de jeune fille",
|
||||||
|
"gedcom.aka": "Alias",
|
||||||
"gedcom._UPD": "Dernière mise à jour",
|
"gedcom._UPD": "Dernière mise à jour",
|
||||||
"date.abt": "environ",
|
"date.abt": "environ",
|
||||||
"date.cal": "calculé",
|
"date.cal": "calculé",
|
||||||
|
|||||||
@@ -53,6 +53,10 @@
|
|||||||
"gedcom.TITL": "Titolo",
|
"gedcom.TITL": "Titolo",
|
||||||
"gedcom.WWW": "Sito web",
|
"gedcom.WWW": "Sito web",
|
||||||
"gedcom._UPD": "Ultimo aggiornamento",
|
"gedcom._UPD": "Ultimo aggiornamento",
|
||||||
|
"gedcom.birth": "Nome alla nascita",
|
||||||
|
"gedcom.married": "Nome da coniugato/a",
|
||||||
|
"gedcom.maiden": "Nome da nubile",
|
||||||
|
"gedcom.aka": "Conosciuto anche come",
|
||||||
"date.abt": "circa",
|
"date.abt": "circa",
|
||||||
"date.cal": "calcolato",
|
"date.cal": "calcolato",
|
||||||
"date.est": "stimato",
|
"date.est": "stimato",
|
||||||
|
|||||||
@@ -58,6 +58,11 @@
|
|||||||
"gedcom._UPD": "Ostatnia aktualizacja",
|
"gedcom._UPD": "Ostatnia aktualizacja",
|
||||||
"gedcom.MARR": "Małżeństwo",
|
"gedcom.MARR": "Małżeństwo",
|
||||||
"gedcom.DIV": "Rozwód",
|
"gedcom.DIV": "Rozwód",
|
||||||
|
"gedcom.birth": "Nazwisko rodowe",
|
||||||
|
"gedcom.married": "Nazwisko po małżeństwie",
|
||||||
|
"gedcom.maiden": "Nazwisko panieńskie",
|
||||||
|
"gedcom.immigrant": "Nazwisko po imigracji",
|
||||||
|
"gedcom.aka": "Alias",
|
||||||
"date.abt": "około",
|
"date.abt": "około",
|
||||||
"date.cal": "wyliczone",
|
"date.cal": "wyliczone",
|
||||||
"date.est": "oszacowane",
|
"date.est": "oszacowane",
|
||||||
@@ -85,5 +90,6 @@
|
|||||||
"config.colors": "Kolory",
|
"config.colors": "Kolory",
|
||||||
"config.colors.NO_COLOR": "brak",
|
"config.colors.NO_COLOR": "brak",
|
||||||
"config.colors.COLOR_BY_GENERATION": "według pokolenia",
|
"config.colors.COLOR_BY_GENERATION": "według pokolenia",
|
||||||
"config.colors.COLOR_BY_SEX": "według płci"
|
"config.colors.COLOR_BY_SEX": "według płci",
|
||||||
|
"name.unknown_name": "N.N."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,10 @@
|
|||||||
"gedcom.TITL": "Титул",
|
"gedcom.TITL": "Титул",
|
||||||
"gedcom.WWW": "Веб-сайт WWW",
|
"gedcom.WWW": "Веб-сайт WWW",
|
||||||
"gedcom._UPD": "Последнее обновление",
|
"gedcom._UPD": "Последнее обновление",
|
||||||
|
"gedcom.birth": "Имя при рождении",
|
||||||
|
"gedcom.married": "Имя в браке",
|
||||||
|
"gedcom.maiden": "Девичья фамилия",
|
||||||
|
"gedcom.aka": "Он(а) же",
|
||||||
"date.abt": "около",
|
"date.abt": "около",
|
||||||
"date.cal": "рассчитано",
|
"date.cal": "рассчитано",
|
||||||
"date.est": "приблизительно",
|
"date.est": "приблизительно",
|
||||||
|
|||||||
Reference in New Issue
Block a user