xref: /webtrees/app/Factories/ElementFactory.php (revision 87c4c864592057c1fb70471c5b9678d93bf1e2be)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2021 webtrees development team
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees\Factories;
21
22use Fisharebest\Webtrees\Contracts\ElementFactoryInterface;
23use Fisharebest\Webtrees\Contracts\ElementInterface;
24use Fisharebest\Webtrees\Elements\AddressCity;
25use Fisharebest\Webtrees\Elements\AddressCountry;
26use Fisharebest\Webtrees\Elements\AddressEmail;
27use Fisharebest\Webtrees\Elements\AddressFax;
28use Fisharebest\Webtrees\Elements\AddressLine;
29use Fisharebest\Webtrees\Elements\AddressLine1;
30use Fisharebest\Webtrees\Elements\AddressLine2;
31use Fisharebest\Webtrees\Elements\AddressLine3;
32use Fisharebest\Webtrees\Elements\AddressPostalCode;
33use Fisharebest\Webtrees\Elements\AddressState;
34use Fisharebest\Webtrees\Elements\AddressWebPage;
35use Fisharebest\Webtrees\Elements\AdoptedByWhichParent;
36use Fisharebest\Webtrees\Elements\Adoption;
37use Fisharebest\Webtrees\Elements\AdultChristening;
38use Fisharebest\Webtrees\Elements\AgeAtEvent;
39use Fisharebest\Webtrees\Elements\AncestralFileNumber;
40use Fisharebest\Webtrees\Elements\Annulment;
41use Fisharebest\Webtrees\Elements\ApprovedSystemId;
42use Fisharebest\Webtrees\Elements\AttributeDescriptor;
43use Fisharebest\Webtrees\Elements\AutomatedRecordId;
44use Fisharebest\Webtrees\Elements\Baptism;
45use Fisharebest\Webtrees\Elements\BasMitzvah;
46use Fisharebest\Webtrees\Elements\Birth;
47use Fisharebest\Webtrees\Elements\Blessing;
48use Fisharebest\Webtrees\Elements\Burial;
49use Fisharebest\Webtrees\Elements\CasteName;
50use Fisharebest\Webtrees\Elements\CauseOfEvent;
51use Fisharebest\Webtrees\Elements\Census;
52use Fisharebest\Webtrees\Elements\CertaintyAssessment;
53use Fisharebest\Webtrees\Elements\Change;
54use Fisharebest\Webtrees\Elements\ChangeDate;
55use Fisharebest\Webtrees\Elements\CharacterSet;
56use Fisharebest\Webtrees\Elements\ChildLinkageStatus;
57use Fisharebest\Webtrees\Elements\Christening;
58use Fisharebest\Webtrees\Elements\Confirmation;
59use Fisharebest\Webtrees\Elements\ContentDescription;
60use Fisharebest\Webtrees\Elements\CopyrightFile;
61use Fisharebest\Webtrees\Elements\CopyrightSourceData;
62use Fisharebest\Webtrees\Elements\CountOfChildren;
63use Fisharebest\Webtrees\Elements\CountOfMarriages;
64use Fisharebest\Webtrees\Elements\Cremation;
65use Fisharebest\Webtrees\Elements\DateLdsOrd;
66use Fisharebest\Webtrees\Elements\DateValue;
67use Fisharebest\Webtrees\Elements\Death;
68use Fisharebest\Webtrees\Elements\DescriptiveTitle;
69use Fisharebest\Webtrees\Elements\Divorce;
70use Fisharebest\Webtrees\Elements\DivorceFiled;
71use Fisharebest\Webtrees\Elements\Emigration;
72use Fisharebest\Webtrees\Elements\EmptyElement;
73use Fisharebest\Webtrees\Elements\Engagement;
74use Fisharebest\Webtrees\Elements\EntryRecordingDate;
75use Fisharebest\Webtrees\Elements\EventAttributeType;
76use Fisharebest\Webtrees\Elements\EventDescriptor;
77use Fisharebest\Webtrees\Elements\EventOrFactClassification;
78use Fisharebest\Webtrees\Elements\EventsRecorded;
79use Fisharebest\Webtrees\Elements\EventTypeCitedFrom;
80use Fisharebest\Webtrees\Elements\FamilyRecord;
81use Fisharebest\Webtrees\Elements\FileName;
82use Fisharebest\Webtrees\Elements\FirstCommunion;
83use Fisharebest\Webtrees\Elements\Form;
84use Fisharebest\Webtrees\Elements\Gedcom;
85use Fisharebest\Webtrees\Elements\GenerationsOfAncestors;
86use Fisharebest\Webtrees\Elements\GenerationsOfDescendants;
87use Fisharebest\Webtrees\Elements\Graduation;
88use Fisharebest\Webtrees\Elements\HeaderRecord;
89use Fisharebest\Webtrees\Elements\Immigration;
90use Fisharebest\Webtrees\Elements\IndividualRecord;
91use Fisharebest\Webtrees\Elements\LanguageId;
92use Fisharebest\Webtrees\Elements\LdsBaptism;
93use Fisharebest\Webtrees\Elements\LdsBaptismDateStatus;
94use Fisharebest\Webtrees\Elements\LdsChildSealing;
95use Fisharebest\Webtrees\Elements\LdsChildSealingDateStatus;
96use Fisharebest\Webtrees\Elements\LdsConfirmation;
97use Fisharebest\Webtrees\Elements\LdsEndowment;
98use Fisharebest\Webtrees\Elements\LdsEndowmentDateStatus;
99use Fisharebest\Webtrees\Elements\LdsSpouseSealing;
100use Fisharebest\Webtrees\Elements\LdsSpouseSealingDateStatus;
101use Fisharebest\Webtrees\Elements\Marriage;
102use Fisharebest\Webtrees\Elements\MarriageBanns;
103use Fisharebest\Webtrees\Elements\MarriageContract;
104use Fisharebest\Webtrees\Elements\MarriageLicence;
105use Fisharebest\Webtrees\Elements\MarriageSettlement;
106use Fisharebest\Webtrees\Elements\MarriageType;
107use Fisharebest\Webtrees\Elements\MediaRecord;
108use Fisharebest\Webtrees\Elements\MultimediaFileReference;
109use Fisharebest\Webtrees\Elements\MultimediaFormat;
110use Fisharebest\Webtrees\Elements\NameOfBusiness;
111use Fisharebest\Webtrees\Elements\NameOfFamilyFile;
112use Fisharebest\Webtrees\Elements\NameOfProduct;
113use Fisharebest\Webtrees\Elements\NameOfRepository;
114use Fisharebest\Webtrees\Elements\NameOfSourceData;
115use Fisharebest\Webtrees\Elements\NamePersonal;
116use Fisharebest\Webtrees\Elements\NamePhoneticVariation;
117use Fisharebest\Webtrees\Elements\NamePieceGiven;
118use Fisharebest\Webtrees\Elements\NamePieceNickname;
119use Fisharebest\Webtrees\Elements\NamePiecePrefix;
120use Fisharebest\Webtrees\Elements\NamePieceSuffix;
121use Fisharebest\Webtrees\Elements\NamePieceSurname;
122use Fisharebest\Webtrees\Elements\NamePieceSurnamePrefix;
123use Fisharebest\Webtrees\Elements\NameRomanizedVariation;
124use Fisharebest\Webtrees\Elements\NameType;
125use Fisharebest\Webtrees\Elements\NationalIdNumber;
126use Fisharebest\Webtrees\Elements\NationOrTribalOrigin;
127use Fisharebest\Webtrees\Elements\Naturalization;
128use Fisharebest\Webtrees\Elements\NobilityTypeTitle;
129use Fisharebest\Webtrees\Elements\NoteRecord;
130use Fisharebest\Webtrees\Elements\NoteStructure;
131use Fisharebest\Webtrees\Elements\Occupation;
132use Fisharebest\Webtrees\Elements\OrdinanceProcessFlag;
133use Fisharebest\Webtrees\Elements\Ordination;
134use Fisharebest\Webtrees\Elements\PafUid;
135use Fisharebest\Webtrees\Elements\PedigreeLinkageType;
136use Fisharebest\Webtrees\Elements\PermanentRecordFileNumber;
137use Fisharebest\Webtrees\Elements\PhoneNumber;
138use Fisharebest\Webtrees\Elements\PhoneticType;
139use Fisharebest\Webtrees\Elements\PhysicalDescription;
140use Fisharebest\Webtrees\Elements\PlaceHierarchy;
141use Fisharebest\Webtrees\Elements\PlaceLatitude;
142use Fisharebest\Webtrees\Elements\PlaceLivingOrdinance;
143use Fisharebest\Webtrees\Elements\PlaceLongtitude;
144use Fisharebest\Webtrees\Elements\PlaceName;
145use Fisharebest\Webtrees\Elements\PlacePhoneticVariation;
146use Fisharebest\Webtrees\Elements\PlaceRomanizedVariation;
147use Fisharebest\Webtrees\Elements\Possessions;
148use Fisharebest\Webtrees\Elements\Probate;
149use Fisharebest\Webtrees\Elements\PublicationDate;
150use Fisharebest\Webtrees\Elements\ReceivingSystemName;
151use Fisharebest\Webtrees\Elements\RelationIsDescriptor;
152use Fisharebest\Webtrees\Elements\ReligiousAffiliation;
153use Fisharebest\Webtrees\Elements\RepositoryRecord;
154use Fisharebest\Webtrees\Elements\ResearchTask;
155use Fisharebest\Webtrees\Elements\Residence;
156use Fisharebest\Webtrees\Elements\ResponsibleAgency;
157use Fisharebest\Webtrees\Elements\RestrictionNotice;
158use Fisharebest\Webtrees\Elements\Retirement;
159use Fisharebest\Webtrees\Elements\RoleInEvent;
160use Fisharebest\Webtrees\Elements\RomanizedType;
161use Fisharebest\Webtrees\Elements\ScholasticAchievement;
162use Fisharebest\Webtrees\Elements\SexValue;
163use Fisharebest\Webtrees\Elements\SocialSecurityNumber;
164use Fisharebest\Webtrees\Elements\SourceCallNumber;
165use Fisharebest\Webtrees\Elements\SourceData;
166use Fisharebest\Webtrees\Elements\SourceFiledByEntry;
167use Fisharebest\Webtrees\Elements\SourceJurisdictionPlace;
168use Fisharebest\Webtrees\Elements\SourceMediaType;
169use Fisharebest\Webtrees\Elements\SourceOriginator;
170use Fisharebest\Webtrees\Elements\SourcePublicationFacts;
171use Fisharebest\Webtrees\Elements\SourceRecord;
172use Fisharebest\Webtrees\Elements\SubmissionRecord;
173use Fisharebest\Webtrees\Elements\SubmitterName;
174use Fisharebest\Webtrees\Elements\SubmitterRecord;
175use Fisharebest\Webtrees\Elements\SubmitterRegisteredRfn;
176use Fisharebest\Webtrees\Elements\SubmitterText;
177use Fisharebest\Webtrees\Elements\TempleCode;
178use Fisharebest\Webtrees\Elements\TextFromSource;
179use Fisharebest\Webtrees\Elements\TimeValue;
180use Fisharebest\Webtrees\Elements\TransmissionDate;
181use Fisharebest\Webtrees\Elements\UnknownElement;
182use Fisharebest\Webtrees\Elements\UserReferenceNumber;
183use Fisharebest\Webtrees\Elements\UserReferenceType;
184use Fisharebest\Webtrees\Elements\VersionNumber;
185use Fisharebest\Webtrees\Elements\WebtreesUser;
186use Fisharebest\Webtrees\Elements\WhereWithinSource;
187use Fisharebest\Webtrees\Elements\Will;
188use Fisharebest\Webtrees\Elements\XrefFamily;
189use Fisharebest\Webtrees\Elements\XrefIndividual;
190use Fisharebest\Webtrees\Elements\XrefMedia;
191use Fisharebest\Webtrees\Elements\XrefRepository;
192use Fisharebest\Webtrees\Elements\XrefSource;
193use Fisharebest\Webtrees\Elements\XrefSubmission;
194use Fisharebest\Webtrees\Elements\XrefSubmitter;
195use Fisharebest\Webtrees\I18N;
196
197use function preg_match;
198use function strpos;
199
200/**
201 * Make a GEDCOM element.
202 */
203class ElementFactory implements ElementFactoryInterface
204{
205    /** @var null|array<string,ElementInterface> */
206    private $elements;
207
208    /**
209     * Create a GEDCOM element that corresponds to a GEDCOM tag.
210     * Finds the correct element for all valid tags.
211     * Finds a likely element for custom tags.
212     *
213     * @param string $tag - Colon delimited hierarchy, e.g. 'INDI:BIRT:PLAC'
214     *
215     * @return ElementInterface
216     */
217    public function make(string $tag): ElementInterface
218    {
219        return $this->elements()[$tag] ?? $this->findElementByWildcard($tag) ?? new UnknownElement($tag);
220    }
221
222    /**
223     * @param string $tag
224     *
225     * @return ElementInterface|null
226     */
227    private function findElementByWildcard(string $tag): ?ElementInterface
228    {
229        foreach ($this->elements() as $tags => $element) {
230            if (strpos($tags, '*') !== false) {
231                $regex = '/^' . strtr($tags, ['*' => '[^:]+']) . '$/';
232
233                if (preg_match($regex, $tag)) {
234                    return $element;
235                }
236            }
237        }
238
239        return null;
240    }
241
242    /**
243     * Register more elements.
244     *
245     * @param array<string,ElementInterface> $elements
246     */
247    public function register(array $elements): void
248    {
249        $this->elements = array_merge($this->elements(), $elements);
250    }
251
252    /**
253     * Association between GEDCOM tags and GEDCOM elements.
254     * We can't initialise this in the constructor, as the I18N package isn't available then.
255     *
256     * @return array<string,ElementInterface>
257     */
258    private function elements(): array
259    {
260        if ($this->elements === null) {
261            // Custom tags are indicated with ***
262            $this->elements = [
263                'FAM'                      => new FamilyRecord(I18N::translate('Family')),
264                'FAM:*:ADDR'               => new AddressLine(I18N::translate('Address')),
265                'FAM:*:ADDR:ADR1'          => new AddressLine1(I18N::translate('Address line 1')),
266                'FAM:*:ADDR:ADR2'          => new AddressLine2(I18N::translate('Address line 2')),
267                'FAM:*:ADDR:ADR3'          => new AddressLine3(I18N::translate('Address line 3')),
268                'FAM:*:ADDR:CITY'          => new AddressCity(I18N::translate('City')),
269                'FAM:*:ADDR:CTRY'          => new AddressCountry(I18N::translate('Country')),
270                'FAM:*:ADDR:POST'          => new AddressPostalCode(I18N::translate('Postal code')),
271                'FAM:*:ADDR:STAE'          => new AddressState(I18N::translate('State')),
272                'FAM:*:AGNC'               => new ResponsibleAgency(I18N::translate('Agency')),
273                'FAM:*:CAUS'               => new CauseOfEvent(I18N::translate('Cause')),
274                'FAM:*:DATE'               => new DateValue(I18N::translate('Date')),
275                'FAM:*:EMAIL'              => new AddressEmail(I18N::translate('Email address')),
276                'FAM:*:FAX'                => new AddressFax(I18N::translate('Fax')),
277                'FAM:*:HUSB'               => new EmptyElement(I18N::translate('Husband'), ['AGE' => '0:1']),
278                'FAM:*:HUSB:AGE'           => new AgeAtEvent(I18N::translate('Husband’s age')),
279                'FAM:*:NOTE'               => new NoteStructure(I18N::translate('Note')),
280                'FAM:*:OBJE'               => new XrefMedia(I18N::translate('Media object')),
281                'FAM:*:PHON'               => new PhoneNumber(I18N::translate('Phone')),
282                'FAM:*:PLAC'               => new PlaceName(I18N::translate('Place')),
283                'FAM:*:PLAC:FONE'          => new PlacePhoneticVariation(I18N::translate('Phonetic place')),
284                'FAM:*:PLAC:FONE:TYPE'     => new PhoneticType(I18N::translate('Type')),
285                'FAM:*:PLAC:FORM'          => new PlaceHierarchy(I18N::translate('Format')),
286                'FAM:*:PLAC:MAP'           => new EmptyElement(I18N::translate('Coordinates')),
287                'FAM:*:PLAC:MAP:LATI'      => new PlaceLatitude(I18N::translate('Latitude')),
288                'FAM:*:PLAC:MAP:LONG'      => new PlaceLongtitude(I18N::translate('Longitude')),
289                'FAM:*:PLAC:NOTE'          => new NoteStructure(I18N::translate('Note')),
290                'FAM:*:PLAC:ROMN'          => new PlaceRomanizedVariation(I18N::translate('Romanized place')),
291                'FAM:*:PLAC:ROMN:TYPE'     => new RomanizedType(I18N::translate('Type')),
292                'FAM:*:RELI'               => new ReligiousAffiliation(I18N::translate('Religion')),
293                'FAM:*:RESN'               => new RestrictionNotice(I18N::translate('Restriction')),
294                'FAM:*:SOUR'               => new XrefSource(I18N::translate('Source')),
295                'FAM:*:SOUR:DATA'          => new SourceData(I18N::translate('Data')),
296                'FAM:*:SOUR:DATA:DATE'     => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
297                'FAM:*:SOUR:DATA:TEXT'     => new TextFromSource(I18N::translate('Text')),
298                'FAM:*:SOUR:EVEN'          => new EventTypeCitedFrom(I18N::translate('Event')),
299                'FAM:*:SOUR:EVEN:ROLE'     => new RoleInEvent(I18N::translate('Role')),
300                'FAM:*:SOUR:NOTE'          => new NoteStructure(I18N::translate('Note')),
301                'FAM:*:SOUR:OBJE'          => new XrefMedia(I18N::translate('Media object')),
302                'FAM:*:SOUR:PAGE'          => new WhereWithinSource(I18N::translate('Citation details')),
303                'FAM:*:SOUR:QUAY'          => new CertaintyAssessment(I18N::translate('Quality of data')),
304                'FAM:*:TYPE'               => new EventOrFactClassification(I18N::translate('Type')),
305                'FAM:*:WIFE'               => new EmptyElement(I18N::translate('Wife'), ['AGE' => '0:1']),
306                'FAM:*:WIFE:AGE'           => new AgeAtEvent(I18N::translate('Wife’s age')),
307                'FAM:*:WWW'                => new AddressWebPage(I18N::translate('URL')),
308                'FAM:*:_ASSO'              => new XrefIndividual(I18N::translate('Associate')), // ***
309                'FAM:*:_ASSO:RELA'         => new RelationIsDescriptor(I18N::translate('Relationship')), // ***
310                'FAM:ANUL'                 => new Annulment(I18N::translate('Annulment')),
311                'FAM:CENS'                 => new Census(I18N::translate('Census')),
312                'FAM:CHAN'                 => new Change(I18N::translate('Last change')),
313                'FAM:CHAN:DATE'            => new ChangeDate(I18N::translate('Date of last change')),
314                'FAM:CHAN:DATE:TIME'       => new TimeValue(I18N::translate('Time')),
315                'FAM:CHAN:_WT_USER'        => new WebtreesUser(I18N::translate('Author of last change')), // *** webtrees
316                'FAM:CHIL'                 => new XrefIndividual(I18N::translate('Child')),
317                'FAM:DIV'                  => new Divorce(I18N::translate('Divorce')),
318                'FAM:DIVF'                 => new DivorceFiled(I18N::translate('Divorce filed')),
319                'FAM:ENGA'                 => new Engagement(I18N::translate('Engagement')),
320                'FAM:ENGA:DATE'            => new DateValue(I18N::translate('Date of engagement')),
321                'FAM:ENGA:PLACE'           => new PlaceName(I18N::translate('Place of engagement')),
322                'FAM:EVEN'                 => new EventDescriptor(I18N::translate('Event')),
323                'FAM:EVEN:TYPE'            => new EventAttributeType(I18N::translate('Type of event')),
324                'FAM:HUSB'                 => new XrefIndividual(I18N::translate('Husband')),
325                'FAM:MARB'                 => new MarriageBanns(I18N::translate('Marriage banns')),
326                'FAM:MARB:DATE'            => new DateValue(I18N::translate('Date of marriage banns')),
327                'FAM:MARB:PLAC'            => new PlaceName(I18N::translate('Place of marriage banns')),
328                'FAM:MARC'                 => new MarriageContract(I18N::translate('Marriage contract')),
329                'FAM:MARL'                 => new MarriageLicence(I18N::translate('Marriage license')),
330                'FAM:MARR'                 => new Marriage(I18N::translate('Marriage')),
331                'FAM:MARR:DATE'            => new DateValue(I18N::translate('Date of marriage')),
332                'FAM:MARR:PLAC'            => new PlaceName(I18N::translate('Place of marriage')),
333                'FAM:MARR:TYPE'            => new MarriageType(I18N::translate('Type of marriage')),
334                'FAM:MARS'                 => new MarriageSettlement(I18N::translate('Marriage settlement')),
335                'FAM:NCHI'                 => new CountOfChildren(I18N::translate('Number of children')),
336                'FAM:NOTE'                 => new NoteStructure(I18N::translate('Note')),
337                'FAM:OBJE'                 => new XrefMedia(I18N::translate('Media object')),
338                'FAM:REFN'                 => new UserReferenceNumber(I18N::translate('Reference number')),
339                'FAM:REFN:TYPE'            => new UserReferenceType(I18N::translate('Type')),
340                'FAM:RESI'                 => new Residence(I18N::translate('Residence')),
341                'FAM:RESN'                 => new RestrictionNotice(I18N::translate('Restriction')),
342                'FAM:RIN'                  => new AutomatedRecordId(I18N::translate('Record ID number')),
343                'FAM:SLGS'                 => new LdsSpouseSealing(I18N::translate('LDS spouse sealing')),
344                'FAM:SLGS:DATE'            => new DateLdsOrd(I18N::translate('Date')),
345                'FAM:SLGS:NOTE'            => new NoteStructure(I18N::translate('Note')),
346                'FAM:SLGS:PLAC'            => new PlaceLivingOrdinance(I18N::translate('Place')),
347                'FAM:SLGS:STAT'            => new LdsSpouseSealingDateStatus(I18N::translate('Status')),
348                'FAM:SLGS:STAT:DATE'       => new ChangeDate(I18N::translate('Status change date')),
349                'FAM:SLGS:TEMP'            => new TempleCode(/* I18N: https://en.wikipedia.org/wiki/Temple_(LDS_Church)*/ I18N::translate('Temple')),
350                'FAM:SOUR'                 => new XrefSource(I18N::translate('Source')),
351                'FAM:SOUR:DATA'            => new SourceData(I18N::translate('Data')),
352                'FAM:SOUR:DATA:DATE'       => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
353                'FAM:SOUR:DATA:TEXT'       => new TextFromSource(I18N::translate('Text')),
354                'FAM:SOUR:EVEN'            => new EventTypeCitedFrom(I18N::translate('Event')),
355                'FAM:SOUR:EVEN:ROLE'       => new RoleInEvent(I18N::translate('Role')),
356                'FAM:SOUR:NOTE'            => new NoteStructure(I18N::translate('Note')),
357                'FAM:SOUR:OBJE'            => new XrefMedia(I18N::translate('Media object')),
358                'FAM:SOUR:PAGE'            => new WhereWithinSource(I18N::translate('Citation details')),
359                'FAM:SOUR:QUAY'            => new CertaintyAssessment(I18N::translate('Quality of data')),
360                'FAM:SUBM'                 => new XrefSubmitter(I18N::translate('Submitter')),
361                'FAM:WIFE'                 => new XrefIndividual(I18N::translate('Wife')),
362                'FAM:_TODO'                => new ResearchTask(I18N::translate('Research task')), // *** webtrees
363                'FAM:_TODO:DATE'           => new TransmissionDate(I18N::translate('Date')), // *** webtrees
364                'FAM:_TODO:_WT_USER'       => new WebtreesUser(I18N::translate('User')), // *** webtrees
365                'FAM:_UID'                 => new PafUid(I18N::translate('Unique identifier')), // ***
366                'HEAD'                     => new HeaderRecord(I18N::translate('Header')),
367                'HEAD:CHAR'                => new CharacterSet(I18N::translate('Character set')),
368                'HEAD:CHAR:VERS'           => new VersionNumber(I18N::translate('Version')),
369                'HEAD:COPR'                => new CopyrightFile(I18N::translate('Copyright')),
370                'HEAD:DATE'                => new TransmissionDate(I18N::translate('Date')),
371                'HEAD:DATE:TIME'           => new TimeValue(I18N::translate('Time')),
372                'HEAD:DEST'                => new ReceivingSystemName(I18N::translate('Destination')),
373                'HEAD:FILE'                => new FileName(I18N::translate('Filename')),
374                'HEAD:GEDC'                => new Gedcom(I18N::translate('GEDCOM file')),
375                'HEAD:GEDC:FORM'           => new Form(I18N::translate('Format')),
376                'HEAD:GEDC:VERS'           => new VersionNumber(I18N::translate('Version')),
377                'HEAD:LANG'                => new LanguageId(I18N::translate('Language')),
378                'HEAD:NOTE'                => new ContentDescription(I18N::translate('Note')),
379                'HEAD:PLAC'                => new EmptyElement(I18N::translate('Place'), ['FORM' => '1:1']),
380                'HEAD:PLAC:FORM'           => new PlaceHierarchy(I18N::translate('Format')),
381                'HEAD:SOUR'                => new ApprovedSystemId('Genealogy software'),
382                'HEAD:SOUR:CORP'           => new NameOfBusiness(I18N::translate('Corporation')),
383                'HEAD:SOUR:CORP:ADDR'      => new AddressLine(I18N::translate('Address')),
384                'HEAD:SOUR:CORP:ADDR:ADR1' => new AddressLine1(I18N::translate('Address line 1')),
385                'HEAD:SOUR:CORP:ADDR:ADR2' => new AddressLine2(I18N::translate('Address line 2')),
386                'HEAD:SOUR:CORP:ADDR:ADR3' => new AddressLine3(I18N::translate('Address line 3')),
387                'HEAD:SOUR:CORP:ADDR:CITY' => new AddressCity(I18N::translate('City')),
388                'HEAD:SOUR:CORP:ADDR:CTRY' => new AddressCountry(I18N::translate('Country')),
389                'HEAD:SOUR:CORP:ADDR:POST' => new AddressPostalCode(I18N::translate('Postal code')),
390                'HEAD:SOUR:CORP:ADDR:STAE' => new AddressState(I18N::translate('State')),
391                'HEAD:SOUR:CORP:EMAIL'     => new AddressEmail(I18N::translate('Email address')),
392                'HEAD:SOUR:CORP:FAX'       => new AddressFax(I18N::translate('Fax')),
393                'HEAD:SOUR:CORP:PHON'      => new PhoneNumber(I18N::translate('Phone')),
394                'HEAD:SOUR:CORP:WWW'       => new AddressWebPage(I18N::translate('URL')),
395                'HEAD:SOUR:DATA'           => new NameOfSourceData('Data'),
396                'HEAD:SOUR:DATA:COPR'      => new CopyrightSourceData(I18N::translate('Copyright')),
397                'HEAD:SOUR:DATA:DATE'      => new PublicationDate(I18N::translate('Date')),
398                'HEAD:SOUR:NAME'           => new NameOfProduct('Software product'),
399                'HEAD:SOUR:VERS'           => new VersionNumber(I18N::translate('Version')),
400                'HEAD:SUBM'                => new XrefSubmitter(I18N::translate('Submitter')),
401                'HEAD:SUBN'                => new XrefSubmission(I18N::translate('Submission')),
402                'INDI'                     => new IndividualRecord(I18N::translate('Individual')),
403                'INDI:*:ADDR'              => new AddressLine(I18N::translate('Address')),
404                'INDI:*:ADDR:ADR1'         => new AddressLine1(I18N::translate('Address line 1')),
405                'INDI:*:ADDR:ADR2'         => new AddressLine2(I18N::translate('Address line 2')),
406                'INDI:*:ADDR:ADR3'         => new AddressLine3(I18N::translate('Address line 3')),
407                'INDI:*:ADDR:CITY'         => new AddressCity(I18N::translate('City')),
408                'INDI:*:ADDR:CTRY'         => new AddressCountry(I18N::translate('Country')),
409                'INDI:*:ADDR:POST'         => new AddressPostalCode(I18N::translate('Postal code')),
410                'INDI:*:ADDR:STAE'         => new AddressState(I18N::translate('State')),
411                'INDI:*:AGE'               => new AgeAtEvent(I18N::translate('Age')),
412                'INDI:*:AGNC'              => new ResponsibleAgency(I18N::translate('Agency')),
413                'INDI:*:ASSO'              => new XrefIndividual(I18N::translate('Associate')), // ***
414                'INDI:*:ASSO:RELA'         => new RelationIsDescriptor(I18N::translate('Relationship')),
415                'INDI:*:CAUS'              => new CauseOfEvent(I18N::translate('Cause')),
416                'INDI:*:DATE'              => new DateValue(I18N::translate('Date')),
417                'INDI:*:EMAIL'             => new AddressEmail(I18N::translate('Email address')),
418                'INDI:*:FAX'               => new AddressFax(I18N::translate('Fax')),
419                'INDI:*:NOTE'              => new NoteStructure(I18N::translate('Note')),
420                'INDI:*:OBJE'              => new XrefMedia(I18N::translate('Media object')),
421                'INDI:*:PHON'              => new PhoneNumber(I18N::translate('Phone')),
422                'INDI:*:PLAC'              => new PlaceName(I18N::translate('Place')),
423                'INDI:*:PLAC:FONE'         => new PlacePhoneticVariation(I18N::translate('Phonetic place')),
424                'INDI:*:PLAC:FONE:TYPE'    => new PhoneticType(I18N::translate('Type')),
425                'INDI:*:PLAC:FORM'         => new PlaceHierarchy(I18N::translate('Format')),
426                'INDI:*:PLAC:MAP'          => new EmptyElement(I18N::translate('Coordinates')),
427                'INDI:*:PLAC:MAP:LATI'     => new PlaceLatitude(I18N::translate('Latitude')),
428                'INDI:*:PLAC:MAP:LONG'     => new PlaceLongtitude(I18N::translate('Longitude')),
429                'INDI:*:PLAC:NOTE'         => new NoteStructure(I18N::translate('Note')),
430                'INDI:*:PLAC:ROMN'         => new PlaceRomanizedVariation(I18N::translate('Romanized place')),
431                'INDI:*:PLAC:ROMN:TYPE'    => new RomanizedType(I18N::translate('Type')),
432                'INDI:*:PLAC:_HEB'         => new NoteStructure(I18N::translate('Place in Hebrew')), // ***
433                'INDI:*:RELI'              => new ReligiousAffiliation(I18N::translate('Religion')),
434                'INDI:*:RESN'              => new RestrictionNotice(I18N::translate('Restriction')),
435                'INDI:*:SOUR'              => new XrefSource(I18N::translate('Source')),
436                'INDI:*:SOUR:DATA'         => new SourceData(I18N::translate('Data')),
437                'INDI:*:SOUR:DATA:DATE'    => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
438                'INDI:*:SOUR:DATA:TEXT'    => new TextFromSource(I18N::translate('Text')),
439                'INDI:*:SOUR:EVEN'         => new EventTypeCitedFrom(I18N::translate('Event')),
440                'INDI:*:SOUR:EVEN:ROLE'    => new RoleInEvent(I18N::translate('Role')),
441                'INDI:*:SOUR:NOTE'         => new NoteStructure(I18N::translate('Note')),
442                'INDI:*:SOUR:OBJE'         => new XrefMedia(I18N::translate('Media object')),
443                'INDI:*:SOUR:PAGE'         => new WhereWithinSource(I18N::translate('Citation details')),
444                'INDI:*:SOUR:QUAY'         => new CertaintyAssessment(I18N::translate('Quality of data')),
445                'INDI:*:TYPE'              => new EventOrFactClassification(I18N::translate('Type')),
446                'INDI:*:WWW'               => new AddressWebPage(I18N::translate('URL')),
447                'INDI:*:_ASSO'             => new XrefIndividual(I18N::translate('Associate')), // ***
448                'INDI:*:_ASSO:RELA'        => new RelationIsDescriptor(I18N::translate('Relationship')), // ***
449                'INDI:ADOP'                => new Adoption(I18N::translate('Adoption')),
450                'INDI:ADOP:DATE'           => new DateValue(I18N::translate('Date of adoption')),
451                'INDI:ADOP:FAMC'           => new XrefFamily(I18N::translate('Adoptive parents')),
452                'INDI:ADOP:FAMC:ADOP'      => new AdoptedByWhichParent(I18N::translate('Adoption')),
453                'INDI:ADOP:PLAC'           => new PlaceName(I18N::translate('Place of adoption')),
454                'INDI:AFN'                 => new AncestralFileNumber(I18N::translate('Ancestral file number')),
455                'INDI:ALIA'                => new XrefIndividual(I18N::translate('Alias')),
456                'INDI:ANCI'                => new XrefSubmitter(I18N::translate('Ancestors interest')),
457                'INDI:ASSO'                => new XrefIndividual(I18N::translate('Associate')),
458                'INDI:ASSO:NOTE'           => new NoteStructure(I18N::translate('Note')),
459                'INDI:ASSO:RELA'           => new RelationIsDescriptor(I18N::translate('Relationship')),
460                'INDI:BAPL'                => new LdsBaptism(I18N::translate('LDS baptism')),
461                'INDI:BAPL:DATE'           => new DateLdsOrd(I18N::translate('Date of LDS baptism')),
462                'INDI:BAPL:NOTE'           => new NoteStructure(I18N::translate('Note')),
463                'INDI:BAPL:PLAC'           => new PlaceLivingOrdinance(I18N::translate('Place of LDS baptism')),
464                'INDI:BAPL:STAT'           => new LdsBaptismDateStatus(I18N::translate('Status')),
465                'INDI:BAPL:STAT:DATE'      => new ChangeDate(I18N::translate('Status change date')),
466                'INDI:BAPL:TEMP'           => new TempleCode(/* I18N: https://en.wikipedia.org/wiki/Temple_(LDS_Church)*/ I18N::translate('Temple')),
467                'INDI:BAPM'                => new Baptism(I18N::translate('Baptism')),
468                'INDI:BAPM:DATE'           => new DateValue(I18N::translate('Date of baptism')),
469                'INDI:BAPM:PLAC'           => new PlaceName(I18N::translate('Place of baptism')),
470                'INDI:BARM'                => new PlaceName(I18N::translate('Bar mitzvah')),
471                'INDI:BARM:DATE'           => new DateValue(I18N::translate('Date of bar mitzvah')),
472                'INDI:BARM:PLAC'           => new PlaceName(I18N::translate('Place of bar mitzvah')),
473                'INDI:BASM'                => new BasMitzvah(I18N::translate('Bat mitzvah')),
474                'INDI:BASM:DATE'           => new BasMitzvah(I18N::translate('Date of bat mitzvah')),
475                'INDI:BASM:PLAC'           => new DateValue(I18N::translate('Place of bat mitzvah')),
476                'INDI:BIRT'                => new Birth(I18N::translate('Birth')),
477                'INDI:BIRT:DATE'           => new DateValue(I18N::translate('Date of birth')),
478                'INDI:BIRT:FAMC'           => new XrefFamily(I18N::translate('Birth parents')),
479                'INDI:BIRT:PLAC'           => new PlaceName(I18N::translate('Place of birth')),
480                'INDI:BLES'                => new Blessing(I18N::translate('Blessing')),
481                'INDI:BLES:DATE'           => new DateValue(I18N::translate('Date of blessing')),
482                'INDI:BLES:PLAC'           => new PlaceName(I18N::translate('Place of blessing')),
483                'INDI:BURI'                => new Burial(I18N::translate('Burial')),
484                'INDI:BURI:DATE'           => new DateValue(I18N::translate('Date of burial')),
485                'INDI:BURI:PLAC'           => new PlaceName(I18N::translate('Place of burial')),
486                'INDI:CAST'                => new CasteName(I18N::translate('Caste')),
487                'INDI:CENS'                => new Census(I18N::translate('Census')),
488                'INDI:CENS:DATE'           => new DateValue(I18N::translate('Census date')),
489                'INDI:CENS:PLAC'           => new PlaceName(I18N::translate('Census place')),
490                'INDI:CHAN'                => new Change(I18N::translate('Last change')),
491                'INDI:CHAN:DATE'           => new ChangeDate(I18N::translate('Date of last change')),
492                'INDI:CHAN:DATE:TIME'      => new TimeValue(I18N::translate('Time')),
493                'INDI:CHAN:_WT_USER'       => new WebtreesUser(I18N::translate('Author of last change')), // *** webtrees
494                'INDI:CHR'                 => new Christening(I18N::translate('Christening')),
495                'INDI:CHR:DATE'            => new DateValue(I18N::translate('Date of christening')),
496                'INDI:CHR:FAMC'            => new XrefFamily(I18N::translate('Godparents')),
497                'INDI:CHR:PLAC'            => new PlaceName(I18N::translate('Place of christening')),
498                'INDI:CHRA'                => new AdultChristening(I18N::translate('Adult christening')),
499                'INDI:CONF'                => new Confirmation(I18N::translate('Confirmation')),
500                'INDI:CONF:DATE'           => new DateValue(I18N::translate('Date of confirmation')),
501                'INDI:CONF:PLAC'           => new PlaceName(I18N::translate('Place of confirmation')),
502                'INDI:CONL'                => new LdsConfirmation(I18N::translate('LDS confirmation')),
503                'INDI:CONL:DATE'           => new DateLdsOrd(I18N::translate('Date of LDS confirmation')),
504                'INDI:CONL:NOTE'           => new NoteStructure(I18N::translate('Note')),
505                'INDI:CONL:PLAC'           => new PlaceLivingOrdinance(I18N::translate('Place of LDS confirmation')),
506                'INDI:CONL:STAT'           => new LdsSpouseSealingDateStatus(I18N::translate('Status')),
507                'INDI:CONL:STAT:DATE'      => new ChangeDate(I18N::translate('Status change date')),
508                'INDI:CONL:TEMP'           => new TempleCode(/* I18N: https://en.wikipedia.org/wiki/Temple_(LDS_Church)*/ I18N::translate('Temple')),
509                'INDI:CREM'                => new Cremation(I18N::translate('Cremation')),
510                'INDI:CREM:DATE'           => new Cremation(I18N::translate('Date of cremation')),
511                'INDI:CREM:PLAC'           => new Cremation(I18N::translate('Place of cremation')),
512                'INDI:DEAT'                => new Death(I18N::translate('Death')),
513                'INDI:DEAT:CAUS'           => new CauseOfEvent(I18N::translate('Cause of death')),
514                'INDI:DEAT:DATE'           => new DateValue(I18N::translate('Date of death')),
515                'INDI:DEAT:PLAC'           => new PlaceName(I18N::translate('Place of death')),
516                'INDI:DESI'                => new XrefSubmitter(I18N::translate('Descendants interest')),
517                'INDI:DSCR'                => new PhysicalDescription(I18N::translate('Description')),
518                'INDI:EDUC'                => new ScholasticAchievement(I18N::translate('Education')),
519                'INDI:EDUC:AGNC'           => new ResponsibleAgency(I18N::translate('School or college')),
520                'INDI:EMIG'                => new Emigration(I18N::translate('Emigration')),
521                'INDI:EMIG:DATE'           => new DateValue(I18N::translate('Date of emigration')),
522                'INDI:EMIG:PLAC'           => new PlaceName(I18N::translate('Place of emigration')),
523                'INDI:ENDL'                => new LdsEndowment(I18N::translate('LDS endowment')),
524                'INDI:ENDL:DATE'           => new DateLdsOrd(I18N::translate('Date of LDS endowment')),
525                'INDI:ENDL:NOTE'           => new NoteStructure(I18N::translate('Note')),
526                'INDI:ENDL:PLAC'           => new PlaceLivingOrdinance(I18N::translate('Place of LDS endowment')),
527                'INDI:ENDL:STAT'           => new LdsEndowmentDateStatus(I18N::translate('Status')),
528                'INDI:ENDL:STAT:DATE'      => new ChangeDate(I18N::translate('Status change date')),
529                'INDI:ENDL:TEMP'           => new TempleCode(/* I18N: https://en.wikipedia.org/wiki/Temple_(LDS_Church)*/ I18N::translate('Temple')),
530                'INDI:EVEN'                => new EventDescriptor(I18N::translate('Event')),
531                'INDI:EVEN:DATE'           => new DateValue(I18N::translate('Date of event')),
532                'INDI:EVEN:PLAC'           => new PlaceName(I18N::translate('Place of event')),
533                'INDI:EVEN:TYPE'           => new EventAttributeType(I18N::translate('Type of event')),
534                'INDI:FACT'                => new AttributeDescriptor(I18N::translate('Fact')),
535                'INDI:FACT:TYPE'           => new EventAttributeType(I18N::translate('Type of fact')),
536                'INDI:FAMC'                => new XrefFamily(I18N::translate('Family as a child')),
537                'INDI:FAMC:NOTE'           => new NoteStructure(I18N::translate('Note')),
538                'INDI:FAMC:PEDI'           => new PedigreeLinkageType(I18N::translate('Relationship to parents')),
539                'INDI:FAMC:STAT'           => new ChildLinkageStatus(I18N::translate('Status')),
540                'INDI:FAMS'                => new XrefFamily(I18N::translate('Family as a spouse')),
541                'INDI:FCOM'                => new FirstCommunion(I18N::translate('First communion')),
542                'INDI:FCOM:DATE'           => new DateValue(I18N::translate('Date of first communion')),
543                'INDI:FCOM:PLAC'           => new PlaceName(I18N::translate('Place of first communion')),
544                'INDI:GRAD'                => new Graduation(I18N::translate('Graduation')),
545                'INDI:GRAD:AGNC'           => new ResponsibleAgency(I18N::translate('School or college')),
546                'INDI:IDNO'                => new NationalIdNumber(I18N::translate('Identification number')),
547                'INDI:IMMI'                => new Immigration(I18N::translate('Immigration')),
548                'INDI:IMMI:DATE'           => new DateValue(I18N::translate('Date of immigration')),
549                'INDI:IMMI:PLAC'           => new PlaceName(I18N::translate('Place of immigration')),
550                'INDI:NAME'                => new NamePersonal(I18N::translate('Name')),
551                'INDI:NAME:FONE'           => new NamePhoneticVariation(I18N::translate('Phonetic name')),
552                'INDI:NAME:FONE:GIVN'      => new NamePieceGiven(I18N::translate('Given names')),
553                'INDI:NAME:FONE:NICK'      => new NamePieceNickname(I18N::translate('Nickname')),
554                'INDI:NAME:FONE:NPFX'      => new NamePiecePrefix(I18N::translate('Name prefix')),
555                'INDI:NAME:FONE:NSFX'      => new NamePieceSuffix(I18N::translate('Name suffix')),
556                'INDI:NAME:FONE:SPFX'      => new NamePieceSurnamePrefix(I18N::translate('Surname prefix')),
557                'INDI:NAME:FONE:SURN'      => new NamePieceSurname(I18N::translate('Surname')),
558                'INDI:NAME:FONE:TYPE'      => new PhoneticType(I18N::translate('Type of name')),
559                'INDI:NAME:GIVN'           => new NamePieceGiven(I18N::translate('Given names')),
560                'INDI:NAME:NICK'           => new NamePieceNickname(I18N::translate('Nickname')),
561                'INDI:NAME:NOTE'           => new NoteStructure(I18N::translate('Note')),
562                'INDI:NAME:NPFX'           => new NamePiecePrefix(I18N::translate('Name prefix')),
563                'INDI:NAME:NSFX'           => new NamePieceSuffix(I18N::translate('Name suffix')),
564                'INDI:NAME:ROMN'           => new NameRomanizedVariation(I18N::translate('Romanized name')),
565                'INDI:NAME:ROMN:GIVN'      => new NamePieceGiven(I18N::translate('Given names')),
566                'INDI:NAME:ROMN:NICK'      => new NamePieceNickname(I18N::translate('Nickname')),
567                'INDI:NAME:ROMN:NPFX'      => new NamePiecePrefix(I18N::translate('Name prefix')),
568                'INDI:NAME:ROMN:NSFX'      => new NamePieceSuffix(I18N::translate('Name suffix')),
569                'INDI:NAME:ROMN:SPFX'      => new NamePieceSurnamePrefix(I18N::translate('Surname prefix')),
570                'INDI:NAME:ROMN:SURN'      => new NamePieceSurname(I18N::translate('Surname')),
571                'INDI:NAME:ROMN:TYPE'      => new RomanizedType(I18N::translate('Type')),
572                'INDI:NAME:SPFX'           => new NamePieceSurnamePrefix(I18N::translate('Surname prefix')),
573                'INDI:NAME:SURN'           => new NamePieceSurname(I18N::translate('Surname')),
574                'INDI:NAME:TYPE'           => new NameType(I18N::translate('Type of name')),
575                'INDI:NATI'                => new NationOrTribalOrigin(I18N::translate('Nationality')),
576                'INDI:NATU'                => new Naturalization(I18N::translate('Naturalization')),
577                'INDI:NATU:DATE'           => new DateValue(I18N::translate('Date of naturalization')),
578                'INDI:NATU:PLAC'           => new PlaceName(I18N::translate('Place of naturalization')),
579                'INDI:NCHI'                => new CountOfChildren(I18N::translate('Number of children')),
580                'INDI:NMR'                 => new CountOfMarriages(I18N::translate('Number of marriages')),
581                'INDI:NOTE'                => new NoteStructure(I18N::translate('Note')),
582                'INDI:OBJE'                => new XrefMedia(I18N::translate('Media object')),
583                'INDI:OCCU'                => new Occupation(I18N::translate('Occupation')),
584                'INDI:OCCU:AGNC'           => new ResponsibleAgency(I18N::translate('Employer')),
585                'INDI:ORDN'                => new Ordination(I18N::translate('Ordination')),
586                'INDI:ORDN:AGNC'           => new Ordination(I18N::translate('Religious institution')),
587                'INDI:ORDN:DATE'           => new Ordination(I18N::translate('Date of ordination')),
588                'INDI:ORDN:PLAC'           => new Ordination(I18N::translate('Place of ordination')),
589                'INDI:PROB'                => new Probate(I18N::translate('Probate')),
590                'INDI:PROP'                => new Possessions(I18N::translate('Property')),
591                'INDI:REFN'                => new UserReferenceNumber(I18N::translate('Reference number')),
592                'INDI:REFN:TYPE'           => new UserReferenceType(I18N::translate('Type')),
593                'INDI:RELI'                => new ReligiousAffiliation(I18N::translate('Religion')),
594                'INDI:RESI'                => new Residence(I18N::translate('Residence')),
595                'INDI:RESI:DATE'           => new DateValue(I18N::translate('Date of residence')),
596                'INDI:RESI:PLAC'           => new PlaceName(I18N::translate('Place of residence')),
597                'INDI:RESN'                => new RestrictionNotice(I18N::translate('Restriction')),
598                'INDI:RETI'                => new Retirement(I18N::translate('Retirement')),
599                'INDI:RETI:AGNC'           => new ResponsibleAgency(I18N::translate('Employer')),
600                'INDI:RFN'                 => new PermanentRecordFileNumber(I18N::translate('Record file number')),
601                'INDI:RIN'                 => new AutomatedRecordId(I18N::translate('Record ID number')),
602                'INDI:SEX'                 => new SexValue(I18N::translate('Gender')),
603                'INDI:SLGC'                => new LdsChildSealing(I18N::translate('LDS child sealing')),
604                'INDI:SLGC:DATE'           => new DateLdsOrd(I18N::translate('Date of LDS child sealing')),
605                'INDI:SLGC:FAMC'           => new XrefFamily(I18N::translate('Parents')),
606                'INDI:SLGC:NOTE'           => new NoteStructure(I18N::translate('Note')),
607                'INDI:SLGC:PLAC'           => new PlaceLivingOrdinance(I18N::translate('Place of LDS child sealing')),
608                'INDI:SLGC:STAT'           => new LdsChildSealingDateStatus(I18N::translate('Status')),
609                'INDI:SLGC:STAT:DATE'      => new ChangeDate(I18N::translate('Status change date')),
610                'INDI:SLGC:TEMP'           => new TempleCode(/* I18N: https://en.wikipedia.org/wiki/Temple_(LDS_Church)*/ I18N::translate('Temple')),
611                'INDI:SOUR'                => new XrefSource(I18N::translate('Source')),
612                'INDI:SOUR:DATA'           => new SourceData(I18N::translate('Data')),
613                'INDI:SOUR:DATA:DATE'      => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
614                'INDI:SOUR:DATA:TEXT'      => new TextFromSource(I18N::translate('Text')),
615                'INDI:SOUR:EVEN'           => new EventTypeCitedFrom(I18N::translate('Event')),
616                'INDI:SOUR:EVEN:ROLE'      => new RoleInEvent(I18N::translate('Role')),
617                'INDI:SOUR:NOTE'           => new NoteStructure(I18N::translate('Note')),
618                'INDI:SOUR:OBJE'           => new XrefMedia(I18N::translate('Media object')),
619                'INDI:SOUR:PAGE'           => new WhereWithinSource(I18N::translate('Citation details')),
620                'INDI:SOUR:QUAY'           => new CertaintyAssessment(I18N::translate('Quality of data')),
621                'INDI:SSN'                 => new SocialSecurityNumber(I18N::translate('Social security number')),
622                'INDI:SUBM'                => new XrefSubmitter(I18N::translate('Submitter')),
623                'INDI:TITL'                => new NobilityTypeTitle(I18N::translate('Title')),
624                'INDI:WILL'                => new Will(I18N::translate('Will')),
625                'INDI:_TODO'               => new ResearchTask(I18N::translate('Research task')), // *** webtrees
626                'INDI:_TODO:DATE'          => new TransmissionDate(I18N::translate('Date')), // *** webtrees
627                'INDI:_TODO:_WT_USER'      => new WebtreesUser(I18N::translate('User')), // *** webtrees
628                'INDI:_UID'                => new PafUid(I18N::translate('Unique identifier')), // ***
629                'INDI:_WT_OBJE_SORT'       => new XrefMedia(I18N::translate('Re-order media')), // *** webtrees 1.7
630                'NOTE'                     => new NoteRecord(I18N::translate('Note')),
631                'NOTE:CHAN'                => new Change(I18N::translate('Last change')),
632                'NOTE:CHAN:DATE'           => new ChangeDate(I18N::translate('Date of last change')),
633                'NOTE:CHAN:DATE:TIME'      => new TimeValue(I18N::translate('Time')),
634                'NOTE:CHAN:NOTE'           => new NoteStructure(I18N::translate('Note')),
635                'NOTE:CHAN:_WT_USER'       => new WebtreesUser(I18N::translate('Author of last change')), // *** webtrees
636                'NOTE:CONC'                => new SubmitterText(I18N::translate('Note')),
637                'NOTE:CONT'                => new SubmitterText(I18N::translate('Continued')),
638                'NOTE:REFN'                => new UserReferenceNumber(I18N::translate('Reference number')),
639                'NOTE:REFN:TYPE'           => new UserReferenceType(I18N::translate('Type')),
640                'NOTE:RESN'                => new RestrictionNotice(I18N::translate('Restriction')), // *** webtrees
641                'NOTE:RIN'                 => new AutomatedRecordId(I18N::translate('Record ID number')),
642                'NOTE:SOUR'                => new XrefSource(I18N::translate('Source')),
643                'NOTE:SOUR:DATA'           => new SourceData(I18N::translate('Data')),
644                'NOTE:SOUR:DATA:DATE'      => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
645                'NOTE:SOUR:DATA:TEXT'      => new TextFromSource(I18N::translate('Text')),
646                'NOTE:SOUR:EVEN'           => new EventTypeCitedFrom(I18N::translate('Event')),
647                'NOTE:SOUR:EVEN:ROLE'      => new RoleInEvent(I18N::translate('Role')),
648                'NOTE:SOUR:NOTE'           => new NoteStructure(I18N::translate('Note')),
649                'NOTE:SOUR:OBJE'           => new XrefMedia(I18N::translate('Media object')),
650                'NOTE:SOUR:PAGE'           => new WhereWithinSource(I18N::translate('Citation details')),
651                'NOTE:SOUR:QUAY'           => new CertaintyAssessment(I18N::translate('Quality of data')),
652                'NOTE:_UID'                => new PafUid(I18N::translate('Unique identifier')), // ***
653                'OBJE'                     => new MediaRecord(I18N::translate('Media object')),
654                'OBJE:CHAN'                => new Change(I18N::translate('Last change')),
655                'OBJE:CHAN:DATE'           => new ChangeDate(I18N::translate('Date of last change')),
656                'OBJE:CHAN:DATE:TIME'      => new TimeValue(I18N::translate('Time')),
657                'OBJE:CHAN:NOTE'           => new NoteStructure(I18N::translate('Note')),
658                'OBJE:CHAN:_WT_USER'       => new WebtreesUser(I18N::translate('Author of last change')), // *** webtrees
659                'OBJE:FILE'                => new MultimediaFileReference(I18N::translate('Filename')),
660                'OBJE:FILE:FORM'           => new MultimediaFormat(I18N::translate('Format')),
661                'OBJE:FILE:FORM:TYPE'      => new SourceMediaType(I18N::translate('Media type')),
662                'OBJE:FILE:TITL'           => new DescriptiveTitle(I18N::translate('Title')),
663                'OBJE:NOTE'                => new NoteStructure(I18N::translate('Note')),
664                'OBJE:REFN'                => new UserReferenceNumber(I18N::translate('Reference number')),
665                'OBJE:REFN:TYPE'           => new UserReferenceType(I18N::translate('Type')),
666                'OBJE:RESN'                => new RestrictionNotice(I18N::translate('Restriction')), // *** webtrees
667                'OBJE:RIN'                 => new AutomatedRecordId(I18N::translate('Record ID number')),
668                'OBJE:SOUR'                => new XrefSource(I18N::translate('Source')),
669                'OBJE:SOUR:DATA'           => new SourceData(I18N::translate('Data')),
670                'OBJE:SOUR:DATA:DATE'      => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
671                'OBJE:SOUR:DATA:TEXT'      => new TextFromSource(I18N::translate('Text')),
672                'OBJE:SOUR:EVEN'           => new EventTypeCitedFrom(I18N::translate('Event')),
673                'OBJE:SOUR:EVEN:ROLE'      => new RoleInEvent(I18N::translate('Role')),
674                'OBJE:SOUR:NOTE'           => new NoteStructure(I18N::translate('Note')),
675                'OBJE:SOUR:OBJE'           => new XrefMedia(I18N::translate('Media object')),
676                'OBJE:SOUR:PAGE'           => new WhereWithinSource(I18N::translate('Citation details')),
677                'OBJE:SOUR:QUAY'           => new CertaintyAssessment(I18N::translate('Quality of data')),
678                'OBJE:_UID'                => new PafUid(I18N::translate('Unique identifier')), // ***
679                'REPO'                     => new RepositoryRecord(I18N::translate('Repository')),
680                'REPO:ADDR'                => new AddressLine(I18N::translate('Address')),
681                'REPO:ADDR:ADR1'           => new AddressLine1(I18N::translate('Address line 1')),
682                'REPO:ADDR:ADR2'           => new AddressLine2(I18N::translate('Address line 2')),
683                'REPO:ADDR:ADR3'           => new AddressLine3(I18N::translate('Address line 3')),
684                'REPO:ADDR:CITY'           => new AddressCity(I18N::translate('City')),
685                'REPO:ADDR:CTRY'           => new AddressCountry(I18N::translate('Country')),
686                'REPO:ADDR:POST'           => new AddressPostalCode(I18N::translate('Postal code')),
687                'REPO:ADDR:STAE'           => new AddressState(I18N::translate('State')),
688                'REPO:CHAN'                => new Change(I18N::translate('Last change')),
689                'REPO:CHAN:DATE'           => new ChangeDate(I18N::translate('Date of last change')),
690                'REPO:CHAN:DATE:TIME'      => new TimeValue(I18N::translate('Time')),
691                'REPO:CHAN:NOTE'           => new NoteStructure(I18N::translate('Note')),
692                'REPO:CHAN:_WT_USER'       => new WebtreesUser(I18N::translate('Author of last change')), // *** webtrees
693                'REPO:EMAIL'               => new AddressEmail(I18N::translate('Email address')),
694                'REPO:FAX'                 => new AddressFax(I18N::translate('Fax')),
695                'REPO:NAME'                => new NameOfRepository(I18N::translateContext('Repository', 'Name')),
696                'REPO:NOTE'                => new NoteStructure(I18N::translate('Note')),
697                'REPO:PHON'                => new PhoneNumber(I18N::translate('Phone')),
698                'REPO:REFN'                => new UserReferenceNumber(I18N::translate('Reference number')),
699                'REPO:REFN:TYPE'           => new UserReferenceType(I18N::translate('Type')),
700                'REPO:RESN'                => new RestrictionNotice(I18N::translate('Restriction')), // *** webtrees
701                'REPO:RIN'                 => new AutomatedRecordId(I18N::translate('Record ID number')),
702                'REPO:WWW'                 => new AddressWebPage(I18N::translate('URL')),
703                'REPO:_UID'                => new PafUid(I18N::translate('Unique identifier')), // ***
704                'SOUR'                     => new SourceRecord(I18N::translate('Source')),
705                'SOUR:ABBR'                => new SourceFiledByEntry(I18N::translate('Abbreviation')),
706                'SOUR:AUTH'                => new SourceOriginator(I18N::translate('Author')),
707                'SOUR:CHAN'                => new Change(I18N::translate('Last change')),
708                'SOUR:CHAN:DATE'           => new ChangeDate(I18N::translate('Date of last change')),
709                'SOUR:CHAN:DATE:TIME'      => new TimeValue(I18N::translate('Time')),
710                'SOUR:CHAN:NOTE'           => new NoteStructure(I18N::translate('Note')),
711                'SOUR:CHAN:_WT_USER'       => new WebtreesUser(I18N::translate('Author of last change')), // *** webtrees
712                'SOUR:DATA'                => new EmptyElement(I18N::translate('Data'), ['EVEN' => '0:M', 'AGNC' => '0:1', 'NOTE' => '0:M']),
713                'SOUR:DATA:AGNC'           => new ResponsibleAgency(I18N::translate('Agency')),
714                'SOUR:DATA:EVEN'           => new EventsRecorded(I18N::translate('Events')),
715                'SOUR:DATA:EVEN:DATE'      => new DateValue(I18N::translate('Date range')),
716                'SOUR:DATA:EVEN:PLAC'      => new SourceJurisdictionPlace(I18N::translate('Place')),
717                'SOUR:DATA:NOTE'           => new NoteStructure(I18N::translate('Note')),
718                'SOUR:NOTE'                => new NoteStructure(I18N::translate('Note')),
719                'SOUR:OBJE'                => new XrefMedia(I18N::translate('Media object')),
720                'SOUR:PUBL'                => new SourcePublicationFacts(I18N::translate('Publication')),
721                'SOUR:REFN'                => new UserReferenceNumber(I18N::translate('Reference number')),
722                'SOUR:REFN:TYPE'           => new UserReferenceType(I18N::translate('Type')),
723                'SOUR:REPO'                => new XrefRepository(I18N::translate('Repository')),
724                'SOUR:REPO:CALN'           => new SourceCallNumber(I18N::translate('Call number')),
725                'SOUR:REPO:CALN:MEDI'      => new SourceMediaType(I18N::translate('Media type')),
726                'SOUR:REPO:NOTE'           => new NoteStructure(I18N::translate('Note')),
727                'SOUR:RESN'                => new RestrictionNotice(I18N::translate('Restriction')), // *** webtrees
728                'SOUR:RIN'                 => new AutomatedRecordId(I18N::translate('Record ID number')),
729                'SOUR:TEXT'                => new TextFromSource(I18N::translate('Text')),
730                'SOUR:TITL'                => new DescriptiveTitle(I18N::translate('Title')),
731                'SOUR:_UID'                => new PafUid(I18N::translate('Unique identifier')), // ***
732                'SUBM'                     => new SubmitterRecord(I18N::translate('Submitter')),
733                'SUBM:ADDR'                => new AddressLine(I18N::translate('Address')),
734                'SUBM:ADDR:ADR1'           => new AddressLine1(I18N::translate('Address line 1')),
735                'SUBM:ADDR:ADR2'           => new AddressLine2(I18N::translate('Address line 2')),
736                'SUBM:ADDR:ADR3'           => new AddressLine3(I18N::translate('Address line 3')),
737                'SUBM:ADDR:CITY'           => new AddressCity(I18N::translate('City')),
738                'SUBM:ADDR:CTRY'           => new AddressCountry(I18N::translate('Country')),
739                'SUBM:ADDR:POST'           => new AddressPostalCode(I18N::translate('Postal code')),
740                'SUBM:ADDR:STAE'           => new AddressState(I18N::translate('State')),
741                'SUBM:CHAN'                => new Change(I18N::translate('Last change')),
742                'SUBM:CHAN:DATE'           => new ChangeDate(I18N::translate('Date of last change')),
743                'SUBM:CHAN:DATE:TIME'      => new TimeValue(I18N::translate('Time')),
744                'SUBM:CHAN:NOTE'           => new NoteStructure(I18N::translate('Note')),
745                'SUBM:CHAN:_WT_USER'       => new WebtreesUser(I18N::translate('Author of last change')), // *** webtrees
746                'SUBM:EMAIL'               => new AddressEmail(I18N::translate('Email address')),
747                'SUBM:FAX'                 => new AddressFax(I18N::translate('Fax')),
748                'SUBM:LANG'                => new LanguageId(I18N::translate('Language')),
749                'SUBM:NAME'                => new SubmitterName(I18N::translate('Name')),
750                'SUBM:NOTE'                => new NoteStructure(I18N::translate('Note')),
751                'SUBM:OBJE'                => new XrefMedia(I18N::translate('Media object')),
752                'SUBM:PHON'                => new PhoneNumber(I18N::translate('Phone')),
753                'SUBM:RESN'                => new RestrictionNotice(I18N::translate('Restriction')), // *** webtrees
754                'SUBM:RFN'                 => new SubmitterRegisteredRfn(I18N::translate('Record file number')),
755                'SUBM:RIN'                 => new AutomatedRecordId(I18N::translate('Record ID number')),
756                'SUBM:WWW'                 => new AddressWebPage(I18N::translate('URL')),
757                'SUBM:_UID'                => new PafUid(I18N::translate('Unique identifier')), // ***
758                'SUBN'                     => new SubmissionRecord(I18N::translate('Submission')),
759                'SUBN:ANCE'                => new GenerationsOfAncestors(I18N::translate('Generations of ancestors')),
760                'SUBN:CHAN'                => new Change(I18N::translate('Last change')),
761                'SUBN:CHAN:DATE'           => new ChangeDate(I18N::translate('Date of last change')),
762                'SUBN:CHAN:DATE:TIME'      => new TimeValue(I18N::translate('Time')),
763                'SUBN:CHAN:NOTE'           => new NoteStructure(I18N::translate('Note')),
764                'SUBN:CHAN:_WT_USER'       => new WebtreesUser(I18N::translate('Author of last change')), // *** webtrees
765                'SUBN:DESC'                => new GenerationsOfDescendants(I18N::translate('Generations of descendants')),
766                'SUBN:FAMF'                => new NameOfFamilyFile(I18N::translate('Family file')),
767                'SUBN:NOTE'                => new NoteStructure(I18N::translate('Note')),
768                'SUBN:ORDI'                => new OrdinanceProcessFlag(I18N::translate('Ordinance')),
769                'SUBN:RESN'                => new RestrictionNotice(I18N::translate('Restriction')), // *** webtrees
770                'SUBN:RIN'                 => new AutomatedRecordId(I18N::translate('Record ID number')),
771                'SUBN:SUBM'                => new XrefSubmitter(I18N::translate('Submitter')),
772                'SUBN:TEMP'                => new TempleCode(/* I18N: https://en.wikipedia.org/wiki/Temple_(LDS_Church)*/ I18N::translate('Temple')),
773                'SUBN:_UID'                => new PafUid(I18N::translate('Unique identifier')), // ***
774                'TRLR'                     => new EmptyElement(I18N::translate('Trailer')),
775            ];
776        }
777
778        return $this->elements;
779    }
780}
781