Completed
Push — develop ( 15826b...d8b18f )
by Greg
10:40 queued 04:07
created

ElementFactory::gedcom551()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 469
Code Lines 467

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 467
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 469
rs 8

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
18
declare(strict_types=1);
19
20
namespace Fisharebest\Webtrees\Factories;
21
22
use Fisharebest\Webtrees\Contracts\ElementFactoryInterface;
23
use Fisharebest\Webtrees\Contracts\ElementInterface;
24
use Fisharebest\Webtrees\Elements\AddressCity;
25
use Fisharebest\Webtrees\Elements\AddressCountry;
26
use Fisharebest\Webtrees\Elements\AddressEmail;
27
use Fisharebest\Webtrees\Elements\AddressFax;
28
use Fisharebest\Webtrees\Elements\AddressLine;
29
use Fisharebest\Webtrees\Elements\AddressLine1;
30
use Fisharebest\Webtrees\Elements\AddressLine2;
31
use Fisharebest\Webtrees\Elements\AddressLine3;
32
use Fisharebest\Webtrees\Elements\AddressPostalCode;
33
use Fisharebest\Webtrees\Elements\AddressState;
34
use Fisharebest\Webtrees\Elements\AddressWebPage;
35
use Fisharebest\Webtrees\Elements\AdoptedByWhichParent;
36
use Fisharebest\Webtrees\Elements\Adoption;
37
use Fisharebest\Webtrees\Elements\AdultChristening;
38
use Fisharebest\Webtrees\Elements\AgeAtEvent;
39
use Fisharebest\Webtrees\Elements\AncestralFileNumber;
40
use Fisharebest\Webtrees\Elements\Annulment;
41
use Fisharebest\Webtrees\Elements\ApprovedSystemId;
42
use Fisharebest\Webtrees\Elements\AttributeDescriptor;
43
use Fisharebest\Webtrees\Elements\AutomatedRecordId;
44
use Fisharebest\Webtrees\Elements\Baptism;
45
use Fisharebest\Webtrees\Elements\BasMitzvah;
46
use Fisharebest\Webtrees\Elements\Birth;
47
use Fisharebest\Webtrees\Elements\Blessing;
48
use Fisharebest\Webtrees\Elements\Burial;
49
use Fisharebest\Webtrees\Elements\CasteName;
50
use Fisharebest\Webtrees\Elements\CauseOfEvent;
51
use Fisharebest\Webtrees\Elements\Census;
52
use Fisharebest\Webtrees\Elements\CertaintyAssessment;
53
use Fisharebest\Webtrees\Elements\Change;
54
use Fisharebest\Webtrees\Elements\ChangeDate;
55
use Fisharebest\Webtrees\Elements\CharacterSet;
56
use Fisharebest\Webtrees\Elements\ChildLinkageStatus;
57
use Fisharebest\Webtrees\Elements\Christening;
58
use Fisharebest\Webtrees\Elements\Confirmation;
59
use Fisharebest\Webtrees\Elements\ContentDescription;
60
use Fisharebest\Webtrees\Elements\CopyrightFile;
61
use Fisharebest\Webtrees\Elements\CopyrightSourceData;
62
use Fisharebest\Webtrees\Elements\CountOfChildren;
63
use Fisharebest\Webtrees\Elements\CountOfMarriages;
64
use Fisharebest\Webtrees\Elements\Cremation;
65
use Fisharebest\Webtrees\Elements\CustomElement;
66
use Fisharebest\Webtrees\Elements\CustomEvent;
67
use Fisharebest\Webtrees\Elements\CustomFact;
68
use Fisharebest\Webtrees\Elements\DateLdsOrd;
69
use Fisharebest\Webtrees\Elements\DateValue;
70
use Fisharebest\Webtrees\Elements\Death;
71
use Fisharebest\Webtrees\Elements\DescriptiveTitle;
72
use Fisharebest\Webtrees\Elements\Divorce;
73
use Fisharebest\Webtrees\Elements\DivorceFiled;
74
use Fisharebest\Webtrees\Elements\Emigration;
75
use Fisharebest\Webtrees\Elements\EmptyElement;
76
use Fisharebest\Webtrees\Elements\Engagement;
77
use Fisharebest\Webtrees\Elements\EntryRecordingDate;
78
use Fisharebest\Webtrees\Elements\EventAttributeType;
79
use Fisharebest\Webtrees\Elements\EventDescriptor;
80
use Fisharebest\Webtrees\Elements\EventOrFactClassification;
81
use Fisharebest\Webtrees\Elements\EventsRecorded;
82
use Fisharebest\Webtrees\Elements\EventTypeCitedFrom;
83
use Fisharebest\Webtrees\Elements\FamilyRecord;
84
use Fisharebest\Webtrees\Elements\FamilySearchFamilyTreeId;
85
use Fisharebest\Webtrees\Elements\FamilyStatusText;
86
use Fisharebest\Webtrees\Elements\FileName;
87
use Fisharebest\Webtrees\Elements\FirstCommunion;
88
use Fisharebest\Webtrees\Elements\Form;
89
use Fisharebest\Webtrees\Elements\GedcomElement;
90
use Fisharebest\Webtrees\Elements\GenerationsOfAncestors;
91
use Fisharebest\Webtrees\Elements\GenerationsOfDescendants;
92
use Fisharebest\Webtrees\Elements\GovIdentifier;
93
use Fisharebest\Webtrees\Elements\Graduation;
94
use Fisharebest\Webtrees\Elements\HeaderRecord;
95
use Fisharebest\Webtrees\Elements\HierarchicalRelationship;
96
use Fisharebest\Webtrees\Elements\Immigration;
97
use Fisharebest\Webtrees\Elements\IndividualRecord;
98
use Fisharebest\Webtrees\Elements\LanguageId;
99
use Fisharebest\Webtrees\Elements\LdsBaptism;
100
use Fisharebest\Webtrees\Elements\LdsBaptismDateStatus;
101
use Fisharebest\Webtrees\Elements\LdsChildSealing;
102
use Fisharebest\Webtrees\Elements\LdsChildSealingDateStatus;
103
use Fisharebest\Webtrees\Elements\LdsConfirmation;
104
use Fisharebest\Webtrees\Elements\LdsEndowment;
105
use Fisharebest\Webtrees\Elements\LdsEndowmentDateStatus;
106
use Fisharebest\Webtrees\Elements\LdsSpouseSealing;
107
use Fisharebest\Webtrees\Elements\LdsSpouseSealingDateStatus;
108
use Fisharebest\Webtrees\Elements\LocationRecord;
109
use Fisharebest\Webtrees\Elements\MaidenheadLocator;
110
use Fisharebest\Webtrees\Elements\Marriage;
111
use Fisharebest\Webtrees\Elements\MarriageBanns;
112
use Fisharebest\Webtrees\Elements\MarriageContract;
113
use Fisharebest\Webtrees\Elements\MarriageLicence;
114
use Fisharebest\Webtrees\Elements\MarriageSettlement;
115
use Fisharebest\Webtrees\Elements\MarriageType;
116
use Fisharebest\Webtrees\Elements\MediaRecord;
117
use Fisharebest\Webtrees\Elements\MultimediaFileReference;
118
use Fisharebest\Webtrees\Elements\MultimediaFormat;
119
use Fisharebest\Webtrees\Elements\NameOfBusiness;
120
use Fisharebest\Webtrees\Elements\NameOfFamilyFile;
121
use Fisharebest\Webtrees\Elements\NameOfProduct;
122
use Fisharebest\Webtrees\Elements\NameOfRepository;
123
use Fisharebest\Webtrees\Elements\NameOfSourceData;
124
use Fisharebest\Webtrees\Elements\NamePersonal;
125
use Fisharebest\Webtrees\Elements\NamePhoneticVariation;
126
use Fisharebest\Webtrees\Elements\NamePieceGiven;
127
use Fisharebest\Webtrees\Elements\NamePieceNickname;
128
use Fisharebest\Webtrees\Elements\NamePiecePrefix;
129
use Fisharebest\Webtrees\Elements\NamePieceSuffix;
130
use Fisharebest\Webtrees\Elements\NamePieceSurname;
131
use Fisharebest\Webtrees\Elements\NamePieceSurnamePrefix;
132
use Fisharebest\Webtrees\Elements\NameRomanizedVariation;
133
use Fisharebest\Webtrees\Elements\NameType;
134
use Fisharebest\Webtrees\Elements\NationalIdNumber;
135
use Fisharebest\Webtrees\Elements\NationOrTribalOrigin;
136
use Fisharebest\Webtrees\Elements\Naturalization;
137
use Fisharebest\Webtrees\Elements\NobilityTypeTitle;
138
use Fisharebest\Webtrees\Elements\NoteRecord;
139
use Fisharebest\Webtrees\Elements\NoteStructure;
140
use Fisharebest\Webtrees\Elements\Occupation;
141
use Fisharebest\Webtrees\Elements\OrdinanceProcessFlag;
142
use Fisharebest\Webtrees\Elements\Ordination;
143
use Fisharebest\Webtrees\Elements\PafUid;
144
use Fisharebest\Webtrees\Elements\PedigreeLinkageType;
145
use Fisharebest\Webtrees\Elements\PermanentRecordFileNumber;
146
use Fisharebest\Webtrees\Elements\PhoneNumber;
147
use Fisharebest\Webtrees\Elements\PhoneticType;
148
use Fisharebest\Webtrees\Elements\PhysicalDescription;
149
use Fisharebest\Webtrees\Elements\PlaceHierarchy;
150
use Fisharebest\Webtrees\Elements\PlaceLatitude;
151
use Fisharebest\Webtrees\Elements\PlaceLivingOrdinance;
152
use Fisharebest\Webtrees\Elements\PlaceLongtitude;
153
use Fisharebest\Webtrees\Elements\PlaceName;
154
use Fisharebest\Webtrees\Elements\PlacePhoneticVariation;
155
use Fisharebest\Webtrees\Elements\PlaceRomanizedVariation;
156
use Fisharebest\Webtrees\Elements\Possessions;
157
use Fisharebest\Webtrees\Elements\Probate;
158
use Fisharebest\Webtrees\Elements\PublicationDate;
159
use Fisharebest\Webtrees\Elements\ReceivingSystemName;
160
use Fisharebest\Webtrees\Elements\RelationIsDescriptor;
161
use Fisharebest\Webtrees\Elements\ReligiousAffiliation;
162
use Fisharebest\Webtrees\Elements\RepositoryRecord;
163
use Fisharebest\Webtrees\Elements\ResearchTask;
164
use Fisharebest\Webtrees\Elements\ResearchTaskPriority;
165
use Fisharebest\Webtrees\Elements\ResearchTaskStatus;
166
use Fisharebest\Webtrees\Elements\ResearchTaskType;
167
use Fisharebest\Webtrees\Elements\Residence;
168
use Fisharebest\Webtrees\Elements\ResponsibleAgency;
169
use Fisharebest\Webtrees\Elements\RestrictionNotice;
170
use Fisharebest\Webtrees\Elements\Retirement;
171
use Fisharebest\Webtrees\Elements\RoleInEvent;
172
use Fisharebest\Webtrees\Elements\RomanizedType;
173
use Fisharebest\Webtrees\Elements\ScholasticAchievement;
174
use Fisharebest\Webtrees\Elements\SexValue;
175
use Fisharebest\Webtrees\Elements\SexXValue;
176
use Fisharebest\Webtrees\Elements\SocialSecurityNumber;
177
use Fisharebest\Webtrees\Elements\SourceCallNumber;
178
use Fisharebest\Webtrees\Elements\SourceData;
179
use Fisharebest\Webtrees\Elements\SourceFiledByEntry;
180
use Fisharebest\Webtrees\Elements\SourceJurisdictionPlace;
181
use Fisharebest\Webtrees\Elements\SourceMediaType;
182
use Fisharebest\Webtrees\Elements\SourceOriginator;
183
use Fisharebest\Webtrees\Elements\SourcePublicationFacts;
184
use Fisharebest\Webtrees\Elements\SourceRecord;
185
use Fisharebest\Webtrees\Elements\SubmissionRecord;
186
use Fisharebest\Webtrees\Elements\SubmitterName;
187
use Fisharebest\Webtrees\Elements\SubmitterRecord;
188
use Fisharebest\Webtrees\Elements\SubmitterRegisteredRfn;
189
use Fisharebest\Webtrees\Elements\SubmitterText;
190
use Fisharebest\Webtrees\Elements\TempleCode;
191
use Fisharebest\Webtrees\Elements\TextFromSource;
192
use Fisharebest\Webtrees\Elements\TimeValue;
193
use Fisharebest\Webtrees\Elements\TransmissionDate;
194
use Fisharebest\Webtrees\Elements\UnknownElement;
195
use Fisharebest\Webtrees\Elements\UserReferenceNumber;
196
use Fisharebest\Webtrees\Elements\UserReferenceType;
197
use Fisharebest\Webtrees\Elements\VersionNumber;
198
use Fisharebest\Webtrees\Elements\WebtreesUser;
199
use Fisharebest\Webtrees\Elements\WhereWithinSource;
200
use Fisharebest\Webtrees\Elements\Will;
201
use Fisharebest\Webtrees\Elements\XrefAssociate;
202
use Fisharebest\Webtrees\Elements\XrefFamily;
203
use Fisharebest\Webtrees\Elements\XrefIndividual;
204
use Fisharebest\Webtrees\Elements\XrefLocation;
205
use Fisharebest\Webtrees\Elements\XrefMedia;
206
use Fisharebest\Webtrees\Elements\XrefRepository;
207
use Fisharebest\Webtrees\Elements\XrefSource;
208
use Fisharebest\Webtrees\Elements\XrefSubmission;
209
use Fisharebest\Webtrees\Elements\XrefSubmitter;
210
use Fisharebest\Webtrees\I18N;
211
212
use function preg_match;
213
use function strpos;
214
215
/**
216
 * Make a GEDCOM element.
217
 */
218
class ElementFactory implements ElementFactoryInterface
219
{
220
    /** @var array<string,ElementInterface> */
221
    private array $elements = [];
222
223
    /**
224
     * Create a GEDCOM element that corresponds to a GEDCOM tag.
225
     * Finds the correct element for all valid tags.
226
     * Finds a likely element for custom tags.
227
     *
228
     * @param string $tag - Colon delimited hierarchy, e.g. 'INDI:BIRT:PLAC'
229
     *
230
     * @return ElementInterface
231
     */
232
    public function make(string $tag): ElementInterface
233
    {
234
        return $this->elements()[$tag] ?? $this->findElementByWildcard($tag) ?? new UnknownElement($tag);
235
    }
236
237
    /**
238
     * Association between GEDCOM tags and GEDCOM elements.
239
     * We can't initialise this in the constructor, as the I18N package isn't available then.
240
     *
241
     * @return array<string,ElementInterface>
242
     */
243
    private function elements(): array
244
    {
245
        if ($this->elements === []) {
246
            // Gedcom 5.5.1
247
            $this->elements = $this->gedcom551();
248
249
            // Aldfaer extensions
250
            $this->register([
251
                'FAM:MARR_CIVIL'     => new CustomEvent(I18N::translate('Civil marriage')),
252
                'FAM:MARR_RELIGIOUS' => new CustomEvent(I18N::translate('Religious marriage')),
253
                'FAM:MARR_PARTNERS'  => new CustomEvent(I18N::translate('Registered partnership')),
254
                'FAM:MARR_UNKNOWN'   => new CustomEvent(I18N::translate('Marriage type unknown')),
255
            ]);
256
257
            // Ancestry extensions
258
            $this->register([
259
                'INDI:*:SOUR:_APID' => new CustomElement(I18N::translate('Ancestry PID')),
260
                'INDI:_EMPLOY'      => new CustomEvent(I18N::translate('Occupation')),
261
            ]);
262
263
            // Brother’s Keeper extensions
264
            $this->register([
265
                'FAM:*:_EVN'       => new CustomElement('Event number'),
266
                'FAM:CHIL:_FREL'   => new CustomElement('Relationship to father'),
267
                'FAM:CHIL:_MREL'   => new CustomElement('Relationship to mother'),
268
                'FAM:_COML'        => new CustomEvent(I18N::translate('Common law marriage')),
269
                'FAM:_MARI'        => new CustomEvent(I18N::translate('Marriage intention')),
270
                'FAM:_MBON'        => new CustomEvent(I18N::translate('Marriage bond')),
271
                'FAM:_NMR'         => new CustomEvent(I18N::translate('Not married'), ['NOTE' => '0:M', 'SOUR' => '0:M']),
272
                'FAM:_PRMN'        => new CustomElement(I18N::translate('Permanent number')),
273
                'FAM:_SEPR'        => new CustomEvent(I18N::translate('Separated')),
274
                'FAM:_TODO'        => new CustomElement(I18N::translate('Research task')),
275
                'INDI:*:_EVN'      => new CustomElement('Event number'),
276
                'INDI:NAME:_ADPN'  => new NamePersonal(I18N::translate('Adopted name'), []),
277
                'INDI:NAME:_AKAN'  => new NamePersonal(I18N::translate('Also known as'), []),
278
                'INDI:NAME:_BIRN'  => new NamePersonal(I18N::translate('Birth name'), []),
279
                'INDI:NAME:_CALL'  => new NamePersonal('Called name', []),
280
                'INDI:NAME:_CENN'  => new NamePersonal('Census name', []),
281
                'INDI:NAME:_CURN'  => new NamePersonal('Current name', []),
282
                'INDI:NAME:_FARN'  => new NamePersonal(I18N::translate('Estate name'), []),
283
                'INDI:NAME:_FKAN'  => new NamePersonal('Formal name', []),
284
                'INDI:NAME:_FRKA'  => new NamePersonal('Formerly known as', []),
285
                'INDI:NAME:_GERN'  => new NamePersonal('German name', []),
286
                'INDI:NAME:_HEBN'  => new NamePersonal(I18N::translate('Hebrew name'), []),
287
                'INDI:NAME:_HNM'   => new NamePersonal(I18N::translate('Hebrew name'), []),
288
                'INDI:NAME:_INDG'  => new NamePersonal('Indigenous name', []),
289
                'INDI:NAME:_INDN'  => new NamePersonal('Indian name', []),
290
                'INDI:NAME:_LNCH'  => new NamePersonal('Legal name change', []),
291
                'INDI:NAME:_MARN'  => new NamePersonal('Married name', []),
292
                'INDI:NAME:_MARNM' => new NamePersonal('Married name', []),
293
                'INDI:NAME:_OTHN'  => new NamePersonal('Other name', []),
294
                'INDI:NAME:_RELN'  => new NamePersonal('Religious name', []),
295
                'INDI:NAME:_SHON'  => new NamePersonal('Short name', []),
296
                'INDI:NAME:_SLDN'  => new NamePersonal('Soldier name', []),
297
                'INDI:_ADPF'       => new CustomElement(I18N::translate('Adopted by father')),
298
                'INDI:_ADPM'       => new CustomElement(I18N::translate('Adopted by mother')),
299
                'INDI:_BRTM'       => new CustomEvent(I18N::translate('Brit milah')),
300
                'INDI:_BRTM:DATE'  => new DateValue(I18N::translate('Date of brit milah')),
301
                'INDI:_BRTM:PLAC'  => new PlaceName(I18N::translate('Place of brit milah')),
302
                'INDI:_EMAIL'      => new AddressEmail(I18N::translate('Email address')),
303
                'INDI:_EYEC'       => new CustomFact(I18N::translate('Eye color')),
304
                'INDI:_FRNL'       => new CustomElement(I18N::translate('Funeral')),
305
                'INDI:_HAIR'       => new CustomFact(I18N::translate('Hair color')),
306
                'INDI:_HEIG'       => new CustomFact(I18N::translate('Height')),
307
                'INDI:_INTE'       => new CustomElement(I18N::translate('Interment')),
308
                'INDI:_MEDC'       => new CustomFact(I18N::translate('Medical')),
309
                'INDI:_MILT'       => new CustomElement(I18N::translate('Military service')),
310
                'INDI:_NLIV'       => new CustomFact(I18N::translate('Not living')),
311
                'INDI:_NMAR'       => new CustomEvent(I18N::translate('Never married'), ['NOTE' => '0:M', 'SOUR' => '0:M']),
312
                'INDI:_PRMN'       => new CustomElement(I18N::translate('Permanent number')),
313
                'INDI:_TODO'       => new CustomElement(I18N::translate('Research task')),
314
                'INDI:_WEIG'       => new CustomFact(I18N::translate('Weight')),
315
                'INDI:_YART'       => new CustomEvent(I18N::translate('Yahrzeit')),
316
                // 1 XXXX
317
                // 2 _EVN ##
318
                // 1 ASSO @Xnnn@
319
                // 2 RELA Witness at event _EVN ##
320
            ]);
321
322
            // familysearch.org extensions
323
            $this->register([
324
                'INDI:_FSFTID' => /* I18N: familysearch.org */ new FamilySearchFamilyTreeId(I18N::translate('FamilySearch ID')),
325
            ]);
326
327
            // Family Tree Builder extensions
328
            $this->register([
329
                '*:_UPD'              => new CustomElement(I18N::translate('Last change')), // e.g. "1 _UPD 14 APR 2012 00:14:10 GMT-5"
330
                'INDI:NAME:_AKA'      => new NamePersonal(I18N::translate('Also known as'), []),
331
                'OBJE:_ALBUM'         => new CustomElement(I18N::translate('Album')), // XREF to an album
332
                'OBJE:_DATE'          => new DateValue(I18N::translate('Date')),
333
                'OBJE:_FILESIZE'      => new CustomElement(I18N::translate('File size')),
334
                'OBJE:_PHOTO_RIN'     => new CustomElement(I18N::translate('Photo')),
335
                'OBJE:_PLACE'         => new PlaceName(I18N::translate('Place')),
336
                '_ALBUM:_PHOTO'       => new CustomElement(I18N::translate('Photo')),
337
                '_ALBUM:_PHOTO:_PRIN' => new CustomElement(I18N::translate('Highlighted image')),
338
            ]);
339
340
            // Family Tree Maker extensions
341
            $this->register([
342
                'FAM:CHIL:_FREL'              => new CustomElement(I18N::translate('Relationship to father')),
343
                'FAM:CHIL:_MREL'              => new CustomElement(I18N::translate('Relationship to mother')),
344
                'FAM:_DETS'                   => new CustomElement(I18N::translate('Death of one spouse')),
345
                'FAM:_FA1'                    => new CustomElement('Fact 1'),
346
                'FAM:_FA10'                   => new CustomElement('Fact 10'),
347
                'FAM:_FA11'                   => new CustomElement('Fact 11'),
348
                'FAM:_FA12'                   => new CustomElement('Fact 12'),
349
                'FAM:_FA13'                   => new CustomElement('Fact 13'),
350
                'FAM:_FA2'                    => new CustomElement('Fact 2'),
351
                'FAM:_FA3'                    => new CustomElement('Fact 3'),
352
                'FAM:_FA4'                    => new CustomElement('Fact 4'),
353
                'FAM:_FA5'                    => new CustomElement('Fact 5'),
354
                'FAM:_FA6'                    => new CustomElement('Fact 6'),
355
                'FAM:_FA7'                    => new CustomElement('Fact 7'),
356
                'FAM:_FA8'                    => new CustomElement('Fact 8'),
357
                'FAM:_FA9'                    => new CustomElement('Fact 9'),
358
                'FAM:_MEND'                   => new CustomElement(I18N::translate('Marriage ending status')),
359
                'FAM:_MSTAT'                  => new CustomElement(I18N::translate('Marriage beginning status')),
360
                'FAM:_SEPR'                   => new CustomElement(I18N::translate('Separation')),
361
                'HEAD:_SCHEMA'                => new CustomElement('Schema'),
362
                'HEAD:_SCHEMA:FAM'            => new CustomElement(I18N::translate('Family')),
363
                'HEAD:_SCHEMA:FAM:_FA*:LABL'  => new CustomElement(I18N::translate('Label')),
364
                'HEAD:_SCHEMA:FAM:_FA1'       => new CustomElement(I18N::translate('Fact 1')),
365
                'HEAD:_SCHEMA:FAM:_FA10'      => new CustomElement(I18N::translate('Fact 10')),
366
                'HEAD:_SCHEMA:FAM:_FA11'      => new CustomElement(I18N::translate('Fact 11')),
367
                'HEAD:_SCHEMA:FAM:_FA12'      => new CustomElement(I18N::translate('Fact 12')),
368
                'HEAD:_SCHEMA:FAM:_FA13'      => new CustomElement(I18N::translate('Fact 13')),
369
                'HEAD:_SCHEMA:FAM:_FA2'       => new CustomElement(I18N::translate('Fact 2')),
370
                'HEAD:_SCHEMA:FAM:_FA3'       => new CustomElement(I18N::translate('Fact 3')),
371
                'HEAD:_SCHEMA:FAM:_FA4'       => new CustomElement(I18N::translate('Fact 4')),
372
                'HEAD:_SCHEMA:FAM:_FA5'       => new CustomElement(I18N::translate('Fact 5')),
373
                'HEAD:_SCHEMA:FAM:_FA6'       => new CustomElement(I18N::translate('Fact 6')),
374
                'HEAD:_SCHEMA:FAM:_FA7'       => new CustomElement(I18N::translate('Fact 7')),
375
                'HEAD:_SCHEMA:FAM:_FA8'       => new CustomElement(I18N::translate('Fact 8')),
376
                'HEAD:_SCHEMA:FAM:_FA9'       => new CustomElement(I18N::translate('Fact 9')),
377
                'HEAD:_SCHEMA:FAM:_M*:LABL'   => new CustomElement(I18N::translate('Label')),
378
                'HEAD:_SCHEMA:FAM:_MEND'      => new CustomElement(I18N::translate('Marriage ending status')),
379
                'HEAD:_SCHEMA:FAM:_MSTAT'     => new CustomElement(I18N::translate('Marriage beginning status')),
380
                'HEAD:_SCHEMA:INDI'           => new CustomElement(I18N::translate('Individual')),
381
                'HEAD:_SCHEMA:INDI:_FA*:LABL' => new CustomElement(I18N::translate('Label')),
382
                'HEAD:_SCHEMA:INDI:_FA1'      => new CustomElement(I18N::translate('Fact 1')),
383
                'HEAD:_SCHEMA:INDI:_FA10'     => new CustomElement(I18N::translate('Fact 10')),
384
                'HEAD:_SCHEMA:INDI:_FA11'     => new CustomElement(I18N::translate('Fact 11')),
385
                'HEAD:_SCHEMA:INDI:_FA12'     => new CustomElement(I18N::translate('Fact 12')),
386
                'HEAD:_SCHEMA:INDI:_FA13'     => new CustomElement(I18N::translate('Fact 13')),
387
                'HEAD:_SCHEMA:INDI:_FA2'      => new CustomElement(I18N::translate('Fact 2')),
388
                'HEAD:_SCHEMA:INDI:_FA3'      => new CustomElement(I18N::translate('Fact 3')),
389
                'HEAD:_SCHEMA:INDI:_FA4'      => new CustomElement(I18N::translate('Fact 4')),
390
                'HEAD:_SCHEMA:INDI:_FA5'      => new CustomElement(I18N::translate('Fact 5')),
391
                'HEAD:_SCHEMA:INDI:_FA6'      => new CustomElement(I18N::translate('Fact 6')),
392
                'HEAD:_SCHEMA:INDI:_FA7'      => new CustomElement(I18N::translate('Fact 7')),
393
                'HEAD:_SCHEMA:INDI:_FA8'      => new CustomElement(I18N::translate('Fact 8')),
394
                'HEAD:_SCHEMA:INDI:_FA9'      => new CustomElement(I18N::translate('Fact 9')),
395
                'HEAD:_SCHEMA:INDI:_FREL'     => new CustomElement('Relationship to father'),
396
                'HEAD:_SCHEMA:INDI:_M*:LABL'  => new CustomElement(I18N::translate('Label')),
397
                'HEAD:_SCHEMA:INDI:_MREL'     => new CustomElement('Relationship to mother'),
398
                'INDI:*:SOUR:_APID'           => new CustomElement('Ancestry.com source identifier'),
399
                'INDI:*:SOUR:_LINK'           => new CustomElement('External link'),
400
                'INDI:NAME:_AKA'              => new NamePersonal(I18N::translate('Also known as'), []),
401
                'INDI:NAME:_MARNM'            => new NamePersonal(I18N::translate('Married name'), []),
402
                'INDI:_CIRC'                  => new CustomElement('Circumcision'),
403
                'INDI:_DCAUSE'                => new CustomElement(I18N::translate('Cause of death')),
404
                'INDI:_DEG'                   => new CustomElement(I18N::translate('Degree')),
405
                'INDI:_DNA'                   => new CustomElement(I18N::translate('DNA markers')),
406
                'INDI:_ELEC'                  => new CustomElement('Elected'),
407
                'INDI:_EMPLOY'                => new CustomElement('Employment'),
408
                'INDI:_EXCM'                  => new CustomElement('Excommunicated'),
409
                'INDI:_FA1'                   => new CustomElement('Fact 1'),
410
                'INDI:_FA10'                  => new CustomElement('Fact 10'),
411
                'INDI:_FA11'                  => new CustomElement('Fact 11'),
412
                'INDI:_FA12'                  => new CustomElement('Fact 12'),
413
                'INDI:_FA13'                  => new CustomElement('Fact 13'),
414
                'INDI:_FA2'                   => new CustomElement('Fact 2'),
415
                'INDI:_FA3'                   => new CustomElement('Fact 3'),
416
                'INDI:_FA4'                   => new CustomElement('Fact 4'),
417
                'INDI:_FA5'                   => new CustomElement('Fact 5'),
418
                'INDI:_FA6'                   => new CustomElement('Fact 6'),
419
                'INDI:_FA7'                   => new CustomElement('Fact 7'),
420
                'INDI:_FA8'                   => new CustomElement('Fact 8'),
421
                'INDI:_FA9'                   => new CustomElement('Fact 9'),
422
                'INDI:_MDCL'                  => new CustomElement('Medical'),
423
                'INDI:_MILT'                  => new CustomElement(I18N::translate('Military service')),
424
                'INDI:_MILTID'                => new CustomElement('Military ID number'),
425
                'INDI:_MISN'                  => new CustomElement('Mission'),
426
                'INDI:_NAMS'                  => new CustomElement(I18N::translate('Namesake')),
427
                'INDI:_UNKN'                  => new CustomElement(I18N::translate('Unknown')), // Special individual ID code for later file comparisons
428
                // The context and meaning of these tags is unknown
429
                '_FOOT'                       => new CustomElement(''),
430
                '_FUN'                        => new CustomElement(''),
431
                '_JUST'                       => new CustomElement(''),
432
                '_PHOTO'                      => new CustomElement(''),
433
            ]);
434
435
            // Gedcom 5.3 extensions
436
            $this->register([
437
                'EVEN'                       => new CustomElement('Event'),
438
                'EVEN:*:*:NAME'              => new CustomElement(I18N::translate('Name')),
439
                'EVEN:*:AUDIO'               => new CustomElement(I18N::translate('Audio')),
440
                'EVEN:*:BROT'                => new PlaceName('Brother'),
441
                'EVEN:*:BUYR'                => new PlaceName('Buyer'),
442
                'EVEN:*:CHIL'                => new PlaceName('Child'),
443
                'EVEN:*:DATE'                => new DateValue('Date'),
444
                'EVEN:*:FATH'                => new PlaceName('Father'),
445
                'EVEN:*:GODP'                => new PlaceName('Godparent'),
446
                'EVEN:*:HDOH'                => new PlaceName('Head of household'),
447
                'EVEN:*:HEIR'                => new PlaceName('Heir'),
448
                'EVEN:*:HFAT'                => new PlaceName('Husband’s father'),
449
                'EVEN:*:HMOT'                => new PlaceName('Husband’s mother'),
450
                'EVEN:*:HUSB'                => new PlaceName('Husband'),
451
                'EVEN:*:IMAGE'               => new CustomElement('Image'),
452
                'EVEN:*:INDI'                => new PlaceName('Individual'),
453
                'EVEN:*:INFT'                => new PlaceName('Informant'),
454
                'EVEN:*:LEGA'                => new PlaceName('Legatee'),
455
                'EVEN:*:MBR'                 => new PlaceName('Member'),
456
                'EVEN:*:MOTH'                => new PlaceName('Mother'),
457
                'EVEN:*:OFFI'                => new PlaceName('Official'),
458
                'EVEN:*:PARE'                => new PlaceName('Parent'),
459
                'EVEN:*:PHOTO'               => new CustomElement(I18N::translate('Photo')),
460
                'EVEN:*:PHUS'                => new PlaceName('Previous husband'),
461
                'EVEN:*:PLAC'                => new PlaceName('Place'),
462
                'EVEN:*:PWIF'                => new PlaceName('Previous wife'),
463
                'EVEN:*:RECO'                => new PlaceName('Recorder'),
464
                'EVEN:*:REL'                 => new PlaceName('Relative'),
465
                'EVEN:*:SELR'                => new PlaceName('Seller'),
466
                'EVEN:*:SIBL'                => new PlaceName('Sibling'),
467
                'EVEN:*:SIST'                => new PlaceName('Sister'),
468
                'EVEN:*:SPOU'                => new PlaceName('Spouse'),
469
                'EVEN:*:TXPY'                => new PlaceName('Taxpayer'),
470
                'EVEN:*:VIDEO'               => new CustomElement(I18N::translate('Video')),
471
                'EVEN:*:WFAT'                => new PlaceName('Wife’s father'),
472
                'EVEN:*:WIFE'                => new PlaceName('Wife'),
473
                'EVEN:*:WITN'                => new PlaceName('Witness'),
474
                'EVEN:*:WMOT'                => new PlaceName('Wife’s mother'),
475
                'EVEN:TYPE'                  => new CustomElement('Type of event'),
476
                'FAM:*:*:QUAY'               => new CertaintyAssessment(I18N::translate('Quality of data')),
477
                'FAM:*:PLAC:SITE'            => new CustomElement('Site'),
478
                'FAM:*:QUAY'                 => new CertaintyAssessment(I18N::translate('Quality of data')),
479
                'FAM:AUDIO'                  => new CustomElement(I18N::translate('Audio')),
480
                'FAM:IMAGE'                  => new CustomElement('Image'),
481
                'FAM:PHOTO'                  => new CustomElement(I18N::translate('Photo')),
482
                'FAM:VIDEO'                  => new CustomElement(I18N::translate('Video')),
483
                'HEAD:SCHEMA'                => new CustomElement(I18N::translate('Unknown')),
484
                'HEAD:SCHEMA:FAM'            => new CustomElement(I18N::translate('Family')),
485
                'HEAD:SCHEMA:FAM:*:_*'       => new CustomElement('Custom event'),
486
                'HEAD:SCHEMA:FAM:*:_*:DEFN'  => new CustomElement('Definition'),
487
                'HEAD:SCHEMA:FAM:*:_*:ISA'   => new CustomElement('Type of event'),
488
                'HEAD:SCHEMA:FAM:*:_*:LABL'  => new CustomElement('Label'),
489
                'HEAD:SCHEMA:FAM:_*'         => new CustomElement('Custom event'),
490
                'HEAD:SCHEMA:FAM:_*:DEFN'    => new CustomElement('Definition'),
491
                'HEAD:SCHEMA:FAM:_*:ISA'     => new CustomElement('Type of event'),
492
                'HEAD:SCHEMA:FAM:_*:LABL'    => new CustomElement('Label'),
493
                'HEAD:SCHEMA:INDI'           => new CustomElement(I18N::translate('Individual')),
494
                'HEAD:SCHEMA:INDI:*:_*'      => new CustomElement('Custom event'),
495
                'HEAD:SCHEMA:INDI:*:_*:DEFN' => new CustomElement('Definition'),
496
                'HEAD:SCHEMA:INDI:*:_*:ISA'  => new CustomElement('Type of event'),
497
                'HEAD:SCHEMA:INDI:*:_*:LABL' => new CustomElement('Label'),
498
                'HEAD:SCHEMA:INDI:_*'        => new CustomElement('Custom event'),
499
                'HEAD:SCHEMA:INDI:_*:DEFN'   => new CustomElement('Definition'),
500
                'HEAD:SCHEMA:INDI:_*:ISA'    => new CustomElement('Type of event'),
501
                'HEAD:SCHEMA:INDI:_*:LABL'   => new CustomElement('Label'),
502
                'INDI:*:*:QUAY'              => new CertaintyAssessment(I18N::translate('Quality of data')),
503
                'INDI:*:PLAC:SITE'           => new CustomElement('Site'),
504
                'INDI:*:QUAY'                => new CertaintyAssessment(I18N::translate('Quality of data')),
505
                'INDI:AUDIO'                 => new CustomElement(I18N::translate('Audio')),
506
                'INDI:BURI:PLAC:CEME'        => new CustomElement(I18N::translate('Cemetery')),
507
                'INDI:BURI:PLAC:CEME:PLOT'   => new CustomElement('Burial plot'),
508
                'INDI:IMAGE'                 => new CustomElement('Image'),
509
                'INDI:NAMR'                  => new CustomElement(I18N::translate('Religious name')),
510
                'INDI:NAMS'                  => new CustomElement(I18N::translate('Namesake')),
511
                'INDI:PHOTO'                 => new CustomElement(I18N::translate('Photo')),
512
                'INDI:SIGN'                  => new CustomElement('Signature'),
513
                'INDI:VIDEO'                 => new CustomElement(I18N::translate('Video')),
514
                'REPO:CALN:ITEM'             => new CustomElement('Item'),
515
                'REPO:CALN:PAGE'             => new CustomElement('Page'),
516
                'REPO:CALN:SHEE'             => new CustomElement('Sheet'),
517
                'REPO:CNTC'                  => new CustomElement('Contact person'),
518
                'REPO:MEDI'                  => new SourceMediaType(I18N::translate('Media type')),
519
                'REPO:REFN'                  => new CustomElement('Reference number'),
520
                'SOUR:AUDIO'                 => new CustomElement(I18N::translate('Audio')),
521
                'SOUR:CENS'                  => new CustomElement('Census'),
522
                'SOUR:CENS:DATE'             => new CustomElement('Census'),
523
                'SOUR:CENS:DWEL'             => new CustomElement('Dwelling number'),
524
                'SOUR:CENS:FAMN'             => new CustomElement('Family number'),
525
                'SOUR:CENS:LINE'             => new CustomElement('Line number'),
526
                'SOUR:CLAS'                  => new CustomElement('Source classification'),
527
                'SOUR:CPLR'                  => new CustomElement('Compiler'),
528
                'SOUR:EDTR'                  => new CustomElement('Editor'),
529
                'SOUR:EVEN'                  => new CustomElement('Source events'),
530
                'SOUR:FIDE'                  => new CustomElement('Fidelity'),
531
                'SOUR:FILM'                  => new CustomElement(I18N::translate('Microfilm')),
532
                'SOUR:IMAGE'                 => new CustomElement('Image'),
533
                'SOUR:INDX'                  => new CustomElement('Indexed'),
534
                'SOUR:INTV'                  => new CustomElement('Interviewer'),
535
                'SOUR:ORIG'                  => new CustomElement('Originator'),
536
                'SOUR:ORIG:NAME'             => new CustomElement('Name'),
537
                'SOUR:ORIG:NOTE'             => new CustomElement('Note'),
538
                'SOUR:ORIG:TYPE'             => new CustomElement('Type'),
539
                'SOUR:PERI'                  => new CustomElement('Date period'),
540
                'SOUR:PHOTO'                 => new CustomElement(I18N::translate('Photo')),
541
                'SOUR:PUBL:DATE'             => new CustomElement('Date'),
542
                'SOUR:PUBL:EDTN'             => new CustomElement('Edition'),
543
                'SOUR:PUBL:ISSU'             => new CustomElement('Issue'),
544
                'SOUR:PUBL:LCCN'             => new CustomElement('Library of Congress call number'),
545
                'SOUR:PUBL:NAME'             => new CustomElement('Name'),
546
                'SOUR:PUBL:PUBR'             => new CustomElement('Publisher'),
547
                'SOUR:PUBL:SERS'             => new CustomElement('Series'),
548
                'SOUR:PUBL:TYPE'             => new CustomElement('Type'),
549
                'SOUR:QUAY'                  => new CertaintyAssessment(I18N::translate('Quality of data')),
550
                'SOUR:RECO'                  => new CustomElement('Recording agency?'),
551
                'SOUR:REFS'                  => new XrefSource('Referenced source'),
552
                'SOUR:REPO:DPRT:ARVL'        => new CustomElement('Departure'),
553
                'SOUR:REPO:DPRT:ARVL:DATE'   => new DateValue('Date'),
554
                'SOUR:REPO:DPRT:ARVL:PLAC'   => new PlaceName('Place'),
555
                'SOUR:REPO:NAME'             => new CustomElement('Name of vessel'),
556
                'SOUR:REPO:NOTE'             => new NoteStructure(I18N::translate('Note')),
557
                'SOUR:REPO:PORT'             => new CustomElement('Port'),
558
                'SOUR:REPO:PORT:ARVL'        => new CustomElement('Arrival'),
559
                'SOUR:REPO:PORT:ARVL:DATE'   => new DateValue('Date'),
560
                'SOUR:REPO:PORT:ARVL:PLAC'   => new PlaceName('Place'),
561
                'SOUR:REPO:TEXT'             => new TextFromSource(I18N::translate('Text')),
562
                'SOUR:SEQU'                  => new CustomElement('Sequence'),
563
                'SOUR:STAT'                  => new CustomElement('Search status'),
564
                'SOUR:STAT:DATE'             => new DateValue('Date'),
565
                'SOUR:TEXT'                  => new TextFromSource(I18N::translate('Text')),
566
                'SOUR:TYPE'                  => new CustomElement('Type of source'),
567
                'SOUR:VIDEO'                 => new CustomElement(I18N::translate('Video')),
568
                'SOUR:XLTR'                  => new CustomElement('Translator'),
569
            ]);
570
571
            // Gedcom 5.5 extensions
572
            $this->register([
573
                'OBJE:BLOB' => new UnknownElement(I18N::translate('Binary data object')),
574
            ]);
575
576
            // Gedcom-L extensions
577
            $this->register([
578
                'FAM:*:ADDR:_NAME'               => new CustomElement('Name of addressee'),
579
                'FAM:*:PLAC:_GOV'                => new GovIdentifier(I18N::translate('GOV identifier')),
580
                'FAM:*:PLAC:_LOC'                => new XrefLocation(I18N::translate('Location')),
581
                'FAM:*:PLAC:_MAIDENHEAD'         => new MaidenheadLocator('Maidenhead locator'),
582
                'FAM:*:PLAC:_POST'               => new AddressPostalCode('Postal code'),
583
                'FAM:*:PLAC:_POST:DATE'          => new DateValue(I18N::translate('Date')),
584
                'FAM:*:_ASSO'                    => new XrefAssociate(I18N::translate('Associate')),
585
                'FAM:*:_ASSO:NOTE'               => new NoteStructure(I18N::translate('Note')),
586
                'FAM:*:_ASSO:RELA'               => new RelationIsDescriptor(I18N::translate('Relationship')),
587
                'FAM:*:_ASSO:SOUR'               => new XrefSource(I18N::translate('Source citation')),
588
                'FAM:*:_ASSO:SOUR:DATA'          => new SourceData(I18N::translate('Data')),
589
                'FAM:*:_ASSO:SOUR:DATA:DATE'     => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
590
                'FAM:*:_ASSO:SOUR:DATA:TEXT'     => new TextFromSource(I18N::translate('Text')),
591
                'FAM:*:_ASSO:SOUR:EVEN'          => new EventTypeCitedFrom(I18N::translate('Event')),
592
                'FAM:*:_ASSO:SOUR:EVEN:ROLE'     => new RoleInEvent(I18N::translate('Role')),
593
                'FAM:*:_ASSO:SOUR:NOTE'          => new NoteStructure(I18N::translate('Note')),
594
                'FAM:*:_ASSO:SOUR:OBJE'          => new XrefMedia(I18N::translate('Media object')),
595
                'FAM:*:_ASSO:SOUR:PAGE'          => new WhereWithinSource(I18N::translate('Citation details')),
596
                'FAM:*:_ASSO:SOUR:QUAY'          => new CertaintyAssessment(I18N::translate('Quality of data')),
597
                'FAM:*:_WITN'                    => new CustomElement('Witness'),
598
                'FAM:_STAT'                      => new FamilyStatusText(I18N::translate('Family status'), ['DATE' => '0:1', 'PLAC' => '0:1', 'NOTE' => '0:M', 'SOUR' => '0:M']),
599
                'FAM:_TODO'                      => new ResearchTask(I18N::translate('Research task'), ['DESC' => '1:1', '_CAT' => '0:1', '_PRTY' => '0:1', 'TYPE' => '0:1', 'NOTE' => '0:M', 'DATA' => '0:1', 'STAT' => '0:1', '_CDATE' => '0:1', '_RDATE' => '0:1', 'REPO' => '0:1', '_UID' => '0:M']),
600
                'FAM:_TODO:DATA'                 => new SubmitterText(I18N::translate('The solution')),
601
                'FAM:_TODO:DATE'                 => new DateValue(I18N::translate('Creation date')),
602
                'FAM:_TODO:DESC'                 => new CustomElement(I18N::translate('Description')),
603
                'FAM:_TODO:NOTE'                 => new SubmitterText(I18N::translate('The problem')),
604
                'FAM:_TODO:REPO'                 => new XrefRepository('Repository', []),
605
                'FAM:_TODO:STAT'                 => new ResearchTaskStatus(I18N::translate('Status')),
606
                'FAM:_TODO:TYPE'                 => new ResearchTaskType(I18N::translate('Type of research task')),
607
                'FAM:_TODO:_CAT'                 => new CustomElement(I18N::translate('Category')),
608
                'FAM:_TODO:_CDATE'               => new DateValue(I18N::translate('Completion date')),
609
                'FAM:_TODO:_PRTY'                => new ResearchTaskPriority(I18N::translate('Priority')),
610
                'FAM:_TODO:_RDATE'               => new DateValue(I18N::translate('Reminder date')),
611
                'FAM:_UID'                       => new PafUid(I18N::translate('Unique identifier')),
612
                'HEAD:SOUR:CORP:ADDR:_NAME'      => new CustomElement('Name of addressee'),
613
                'HEAD:_SCHEMA'                   => new EmptyElement(I18N::translate('Schema')),
614
                'HEAD:_SCHEMA:*'                 => new EmptyElement(I18N::translate('Base GEDCOM tag')),
615
                'HEAD:_SCHEMA:*:*'               => new EmptyElement(I18N::translate('New GEDCOM tag')),
616
                'HEAD:_SCHEMA:*:*:*'             => new EmptyElement(I18N::translate('New GEDCOM tag')),
617
                'HEAD:_SCHEMA:*:*:*:*'           => new EmptyElement(I18N::translate('New GEDCOM tag')),
618
                'HEAD:_SCHEMA:*:*:*:*:*'         => new EmptyElement(I18N::translate('New GEDCOM tag')),
619
                'HEAD:_SCHEMA:*:*:*:*:*:*'       => new EmptyElement(I18N::translate('New GEDCOM tag')),
620
                'HEAD:_SCHEMA:*:*:*:*:*:*:_DEFN' => new EmptyElement(I18N::translate('Definition')),
621
                'HEAD:_SCHEMA:*:*:*:*:*:_DEFN'   => new EmptyElement(I18N::translate('Definition')),
622
                'HEAD:_SCHEMA:*:*:*:*:_DEFN'     => new EmptyElement(I18N::translate('Definition')),
623
                'HEAD:_SCHEMA:*:*:*:_DEFN'       => new EmptyElement(I18N::translate('Definition')),
624
                'HEAD:_SCHEMA:*:*:_DEFN'         => new EmptyElement(I18N::translate('Definition')),
625
                'INDI:*:ADDR:_NAME'              => new CustomElement('Name of addressee'),
626
                'INDI:*:PLAC:_GOV'               => new GovIdentifier(I18N::translate('GOV identifier')),
627
                'INDI:*:PLAC:_LOC'               => new XrefLocation(I18N::translate('Location')),
628
                'INDI:*:PLAC:_MAIDENHEAD'        => new MaidenheadLocator('Maidenhead locator'),
629
                'INDI:*:PLAC:_POST'              => new AddressPostalCode('Postal code'),
630
                'INDI:*:PLAC:_POST:DATE'         => new DateValue(I18N::translate('Date')),
631
                'INDI:*:_ASSO'                   => new XrefAssociate(I18N::translate('Associate')),
632
                'INDI:*:_ASSO:NOTE'              => new NoteStructure(I18N::translate('Note')),
633
                'INDI:*:_ASSO:RELA'              => new RelationIsDescriptor(I18N::translate('Relationship')),
634
                'INDI:*:_ASSO:SOUR'              => new XrefSource(I18N::translate('Source citation')),
635
                'INDI:*:_ASSO:SOUR:DATA'         => new SourceData(I18N::translate('Data')),
636
                'INDI:*:_ASSO:SOUR:DATA:DATE'    => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
637
                'INDI:*:_ASSO:SOUR:DATA:TEXT'    => new TextFromSource(I18N::translate('Text')),
638
                'INDI:*:_ASSO:SOUR:EVEN'         => new EventTypeCitedFrom(I18N::translate('Event')),
639
                'INDI:*:_ASSO:SOUR:EVEN:ROLE'    => new RoleInEvent(I18N::translate('Role')),
640
                'INDI:*:_ASSO:SOUR:NOTE'         => new NoteStructure(I18N::translate('Note')),
641
                'INDI:*:_ASSO:SOUR:OBJE'         => new XrefMedia(I18N::translate('Media object')),
642
                'INDI:*:_ASSO:SOUR:PAGE'         => new WhereWithinSource(I18N::translate('Citation details')),
643
                'INDI:*:_ASSO:SOUR:QUAY'         => new CertaintyAssessment(I18N::translate('Quality of data')),
644
                'INDI:*:_WITN'                   => new CustomElement('Witness'),
645
                'INDI:BAPM:_GODP'                => new CustomElement('Godparent'),
646
                'INDI:CHR:_GODP'                 => new CustomElement('Godparent'),
647
                'INDI:NAME:_RUFNAME'             => new NamePieceGiven(I18N::translate('Rufname')),
648
                'INDI:OBJE:_PRIM'                => new CustomElement(I18N::translate('Highlighted image')),
649
                'INDI:SEX'                       => new SexXValue(I18N::translate('Gender')),
650
                'INDI:_TODO'                     => new ResearchTask(I18N::translate('Research task')),
651
                'INDI:_TODO:DATA'                => new SubmitterText(I18N::translate('The solution')),
652
                'INDI:_TODO:DATE'                => new DateValue(I18N::translate('Creation date')),
653
                'INDI:_TODO:DESC'                => new CustomElement(I18N::translate('Description')),
654
                'INDI:_TODO:NOTE'                => new SubmitterText(I18N::translate('The problem')),
655
                'INDI:_TODO:REPO'                => new XrefRepository('Repository', []),
656
                'INDI:_TODO:STAT'                => new ResearchTaskStatus(I18N::translate('Status')),
657
                'INDI:_TODO:TYPE'                => new ResearchTaskType(I18N::translate('Type of research task')),
658
                'INDI:_TODO:_CAT'                => new CustomElement(I18N::translate('Category')),
659
                'INDI:_TODO:_CDATE'              => new DateValue(I18N::translate('Completion date')),
660
                'INDI:_TODO:_PRTY'               => new ResearchTaskPriority(I18N::translate('Priority')),
661
                'INDI:_TODO:_RDATE'              => new DateValue(I18N::translate('Reminder date')),
662
                'INDI:_UID'                      => new PafUid(I18N::translate('Unique identifier')),
663
                'NOTE:_UID'                      => new PafUid(I18N::translate('Unique identifier')),
664
                'OBJE:FILE:_PRIM'                => new CustomElement(I18N::translate('Highlighted image')),
665
                'OBJE:_UID'                      => new PafUid(I18N::translate('Unique identifier')),
666
                'REPO:ADDR:_NAME'                => new CustomElement('Name of addressee'),
667
                'REPO:_UID'                      => new PafUid(I18N::translate('Unique identifier')),
668
                'SOUR:_UID'                      => new PafUid(I18N::translate('Unique identifier')),
669
                'SUBM:ADDR:_NAME'                => new CustomElement('Name of addressee'),
670
                'SUBM:_UID'                      => new PafUid(I18N::translate('Unique identifier')),
671
                'SUBN:_UID'                      => new PafUid(I18N::translate('Unique identifier')),
672
                '_LOC'                           => new LocationRecord(I18N::translate('Location')),
673
                '_LOC:CHAN'                      => new Change(I18N::translate('Last change')),
674
                '_LOC:CHAN:DATE'                 => new ChangeDate(I18N::translate('Date of last change')),
675
                '_LOC:CHAN:DATE:TIME'            => new TimeValue(I18N::translate('Time')),
676
                '_LOC:CHAN:NOTE'                 => new NoteStructure(I18N::translate('Note')),
677
                '_LOC:EVEN'                      => new EventDescriptor(I18N::translate('Event'), ['TYPE' => '0:1']),
678
                '_LOC:EVEN:TYPE'                 => new EventAttributeType(I18N::translate('Type of event')),
679
                '_LOC:MAP'                       => new EmptyElement(I18N::translate('Coordinates')),
680
                '_LOC:MAP:LATI'                  => new PlaceLatitude(I18N::translate('Latitude')),
681
                '_LOC:MAP:LONG'                  => new PlaceLongtitude(I18N::translate('Longitude')),
682
                '_LOC:NAME'                      => new PlaceName(I18N::translate('Place'), ['ABBR' => '0:1', 'DATE' => '0:1', 'LANG' => '0:1', 'SOUR' => '0:M']),
683
                '_LOC:NAME:ABBR'                 => new CustomElement(I18N::translate('Abbreviation')),
684
                '_LOC:NAME:ABBR:TYPE'            => new CustomElement(I18N::translate('Type of abbreviation')),
685
                '_LOC:NAME:DATE'                 => new DateValue(I18N::translate('Date')),
686
                '_LOC:NAME:LANG'                 => new LanguageId(I18N::translate('Language')),
687
                '_LOC:NAME:SOUR'                 => new XrefSource(I18N::translate('Source')),
688
                '_LOC:NOTE'                      => new NoteStructure(I18N::translate('Note')),
689
                '_LOC:OBJE'                      => new XrefMedia(I18N::translate('Media')),
690
                '_LOC:RELI'                      => new ReligiousAffiliation('Religion', []),
691
                '_LOC:SOUR'                      => new XrefSource(I18N::translate('Source')),
692
                '_LOC:SOUR:DATA'                 => new SourceData(I18N::translate('Data')),
693
                '_LOC:SOUR:DATA:DATE'            => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
694
                '_LOC:SOUR:DATA:TEXT'            => new TextFromSource(I18N::translate('Text')),
695
                '_LOC:SOUR:EVEN'                 => new EventTypeCitedFrom(I18N::translate('Event')),
696
                '_LOC:SOUR:EVEN:ROLE'            => new RoleInEvent(I18N::translate('Role')),
697
                '_LOC:SOUR:NOTE'                 => new NoteStructure(I18N::translate('Note')),
698
                '_LOC:SOUR:OBJE'                 => new XrefMedia(I18N::translate('Media object')),
699
                '_LOC:SOUR:PAGE'                 => new WhereWithinSource(I18N::translate('Citation details')),
700
                '_LOC:SOUR:QUAY'                 => new CertaintyAssessment(I18N::translate('Quality of data')),
701
                '_LOC:TYPE'                      => new CustomElement(I18N::translate('Type of location')),
702
                '_LOC:TYPE:DATE'                 => new DateValue(I18N::translate('Date')),
703
                '_LOC:TYPE:SOUR'                 => new XrefSource(I18N::translate('Source')),
704
                '_LOC:TYPE:_GOVTYPE'             => new CustomElement('GOV identifier type'),
705
                '_LOC:_AIDN'                     => new CustomElement('Administrative ID'),
706
                '_LOC:_AIDN:DATE'                => new DateValue(I18N::translate('Date')),
707
                '_LOC:_AIDN:SOUR'                => new XrefSource(I18N::translate('Source')),
708
                '_LOC:_AIDN:TYPE'                => new CustomElement(I18N::translate('Type of administrative ID')),
709
                '_LOC:_DMGD'                     => new CustomElement('Demographic data'),
710
                '_LOC:_DMGD:DATE'                => new DateValue(I18N::translate('Date')),
711
                '_LOC:_DMGD:SOUR'                => new XrefSource(I18N::translate('Source')),
712
                '_LOC:_DMGD:TYPE'                => new CustomElement(I18N::translate('Type of demographic data')),
713
                '_LOC:_GOV'                      => new GovIdentifier(I18N::translate('GOV identifier')),
714
                '_LOC:_LOC'                      => new XrefLocation(I18N::translate('Parent'), ['DATE' => '0:1', 'SOUR' => '0:M', 'TYPE' => '0:1']),
715
                '_LOC:_LOC:DATE'                 => new DateValue(I18N::translate('Date')),
716
                '_LOC:_LOC:SOUR'                 => new XrefSource(I18N::translate('Source')),
717
                '_LOC:_LOC:TYPE'                 => new HierarchicalRelationship(I18N::translate('Hierarchical relationship')),
718
                '_LOC:_MAIDENHEAD'               => new MaidenheadLocator('Maidenhead locator'),
719
                '_LOC:_POST'                     => new AddressPostalCode(I18N::translate('Postal code')),
720
                '_LOC:_POST:DATE'                => new DateValue(I18N::translate('Date')),
721
                '_LOC:_POST:SOUR'                => new XrefSource(I18N::translate('Source')),
722
                '_LOC:_UID'                      => new PafUid(I18N::translate('Unique identifier')),
723
                '_LOC:*:SOUR:DATA'               => new SourceData(I18N::translate('Data')),
724
                '_LOC:*:SOUR:DATA:DATE'          => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
725
                '_LOC:*:SOUR:DATA:TEXT'          => new TextFromSource(I18N::translate('Text')),
726
                '_LOC:*:SOUR:EVEN'               => new EventTypeCitedFrom(I18N::translate('Event')),
727
                '_LOC:*:SOUR:EVEN:ROLE'          => new RoleInEvent(I18N::translate('Role')),
728
                '_LOC:*:SOUR:NOTE'               => new NoteStructure(I18N::translate('Note')),
729
                '_LOC:*:SOUR:OBJE'               => new XrefMedia(I18N::translate('Media object')),
730
                '_LOC:*:SOUR:PAGE'               => new WhereWithinSource(I18N::translate('Citation details')),
731
                '_LOC:*:SOUR:QUAY'               => new CertaintyAssessment(I18N::translate('Quality of data')),
732
            ]);
733
734
            // Legacy extensions
735
            $this->register([
736
                'FAM:*:ADDR:_PRIV'             => new CustomElement('Indicates that an address or event is marked as Private.'),
737
                'FAM:*:PLAC:_VERI'             => new CustomElement('Indicates that a source citation or place name has a checkmark in the Verified column.'),
738
                'FAM:*:SOUR:_VERI'             => new CustomElement('Indicates that a source citation or place name has a checkmark in the Verified column.'),
739
                'FAM:*:_PRIV'                  => new CustomElement('Indicates that an address or event is marked as Private.'),
740
                'FAM:CHIL:_FREL'               => new CustomElement('The Relationship of a child to the Father (under a CHIL block under a FAM record).'),
741
                'FAM:CHIL:_MREL'               => new CustomElement('The Relationship of a child to the Mother (under a CHIL block under a FAM record).'),
742
                'FAM:CHIL:_STAT'               => new CustomElement('The Status of a marriage (Married, Unmarried, etc.).  Also the Status of a child (Twin, Triplet, etc.).  (The marriage status of Divorced is exported using a DIV tag.)'),
743
                'FAM:EVEN:_OVER'               => new CustomElement('An event sentence override (under an EVEN block).'),
744
                'FAM:MARR:_STAT'               => new CustomElement('The Status of a marriage (Married, Unmarried, etc.).  Also the Status of a child (Twin, Triplet, etc.).  (The marriage status of Divorced is exported using a DIV tag.)'),
745
                'FAM:SOUR:_VERI'               => new CustomElement('Indicates that a source citation or place name has a checkmark in the Verified column.'),
746
                'FAM:_NONE'                    => new CustomElement('Indicates that a couple had no children (under a FAM record).'),
747
                'HEAD:_EVENT_DEFN'             => new CustomElement('Indicates the start of an Event Definition record that describes the attributes of an event or fact.'),
748
                'HEAD:_EVENT_DEFN:_CONF_FLAG'  => new CustomElement('Indicates that an event is Confidential or Private (under an _EVENT_DEFN record).'),
749
                'HEAD:_EVENT_DEFN:_DATE_TYPE'  => new CustomElement('Indicates whether or not a Date field is shown for a specific event (under an _EVENT_DEFN record).'),
750
                'HEAD:_EVENT_DEFN:_DESC_FLAG'  => new CustomElement('Indicates whether or not a Description field is shown for a specific event (under an _EVENT_DEFN record).'),
751
                'HEAD:_EVENT_DEFN:_PLACE_TYPE' => new CustomElement('Indicates whether or not a Place field is shown for a specific event (under an _EVENT_DEFN record).'),
752
                'HEAD:_EVENT_DEFN:_PP_EXCLUDE' => new CustomElement('Indicates that an event is to be Excluded from the Potential Problems reporting (under an _EVENT_DEFN record).'),
753
                'HEAD:_EVENT_DEFN:_SEN1'       => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'),
754
                'HEAD:_EVENT_DEFN:_SEN2'       => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'),
755
                'HEAD:_EVENT_DEFN:_SEN3'       => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'),
756
                'HEAD:_EVENT_DEFN:_SEN4'       => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'),
757
                'HEAD:_EVENT_DEFN:_SEN5'       => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'),
758
                'HEAD:_EVENT_DEFN:_SEN6'       => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'),
759
                'HEAD:_EVENT_DEFN:_SEN7'       => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'),
760
                'HEAD:_EVENT_DEFN:_SEN8'       => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'),
761
                'HEAD:_EVENT_DEFN:_SENDOF'     => new CustomElement('Event sentence for PAF5 if only the Date field is filled in for a Male individual (under an _EVENT_DEFN record).'),
762
                'HEAD:_EVENT_DEFN:_SENDOM'     => new CustomElement('Event sentence for PAF5 if only the Date field is filled in for a Male individual (under an _EVENT_DEFN record).'),
763
                'HEAD:_EVENT_DEFN:_SENDOU'     => new CustomElement('Event sentence for PAF5 if only the Date field is filled in for a Male individual (under an _EVENT_DEFN record).'),
764
                'HEAD:_EVENT_DEFN:_SENDPF'     => new CustomElement('Event sentence for PAF5 if only the Date and Place fields are filled in for a Male individual (under an _EVENT_DEFN record).'),
765
                'HEAD:_EVENT_DEFN:_SENDPM'     => new CustomElement('Event sentence for PAF5 if only the Date and Place fields are filled in for a Male individual (under an _EVENT_DEFN record).'),
766
                'HEAD:_EVENT_DEFN:_SENDPU'     => new CustomElement('Event sentence for PAF5 if only the Date and Place fields are filled in for a Male individual (under an _EVENT_DEFN record).'),
767
                'HEAD:_EVENT_DEFN:_SENF'       => new CustomElement('Event sentence for PAF5 if all fields are filled in for a Male individual (under an _EVENT_DEFN record).'),
768
                'HEAD:_EVENT_DEFN:_SENM'       => new CustomElement('Event sentence for PAF5 if all fields are filled in for a Male individual (under an _EVENT_DEFN record).'),
769
                'HEAD:_EVENT_DEFN:_SENPOF'     => new CustomElement('Event sentence for PAF5 if only the Place field is filled in for a Male individual (under an _EVENT_DEFN record).'),
770
                'HEAD:_EVENT_DEFN:_SENPOM'     => new CustomElement('Event sentence for PAF5 if only the Place field is filled in for a Male individual (under an _EVENT_DEFN record).'),
771
                'HEAD:_EVENT_DEFN:_SENPOU'     => new CustomElement('Event sentence for PAF5 if only the Place field is filled in for a Male individual (under an _EVENT_DEFN record).'),
772
                'HEAD:_EVENT_DEFN:_SENU'       => new CustomElement('Event sentence for PAF5 if all fields are filled in for a Male individual (under an _EVENT_DEFN record).'),
773
                'HEAD:_PLAC_DEFN'              => new CustomElement('Indicates the start of a Place Definition record that describes the attribute of a place.'),
774
                'HEAD:_PLAC_DEFN:_PREP'        => new CustomElement('A location Preposition (under a _PLAC_DEFN record).'),
775
                'INDI:*:ADDR:_LIST3 YES'       => new CustomElement('Indicates that a person’s address is part of the Birthday grouping (under an ADDR block).'),
776
                'INDI:*:ADDR:_LIST4 YES'       => new CustomElement('Indicates that a person’s address is part of the Research grouping (under an ADDR block).'),
777
                'INDI:*:ADDR:_LIST5 YES'       => new CustomElement('Indicates that a person’s address is part of the Christmas grouping (under an ADDR block).'),
778
                'INDI:*:ADDR:_LIST6 YES'       => new CustomElement('Indicates that a person’s address is part of the Holiday grouping (under an ADDR block).'),
779
                'INDI:*:ADDR:_NAME'            => new CustomElement('The name of an individual as part of an address (under an ADDR block).'),
780
                'INDI:*:ADDR:_PRIV'            => new CustomElement('Indicates that an address or event is marked as Private.'),
781
                'INDI:*:ADDR:_SORT'            => new CustomElement('The spelling of a name to be used when sorting addresses for a report (under an ADDR block).'),
782
                'INDI:*:ADDR:_TAG'             => new CustomElement('Indicates that an address, or place has been tagged.  Also used for Tag 1 selection for an individual.'),
783
                'INDI:*:PLAC:_TAG'             => new CustomElement('Indicates that an address, or place has been tagged.  Also used for Tag 1 selection for an individual.'),
784
                'INDI:*:PLAC:_VERI'            => new CustomElement('Indicates that a source citation or place name has a checkmark in the Verified column.'),
785
                'INDI:*:SOUR:_VERI'            => new CustomElement('Indicates that a source citation or place name has a checkmark in the Verified column.'),
786
                'INDI:*:_PRIV'                 => new CustomElement('Indicates that an address or event is marked as Private.'),
787
                'INDI:ADDR:_EMAIL'             => new CustomElement('An email address (under an ADDR block).'),
788
                'INDI:ADDR:_LIST1 YES'         => new CustomElement('Indicates that a person’s address is part of the Newsletter grouping (under an ADDR block).'),
789
                'INDI:ADDR:_LIST2 YES'         => new CustomElement('Indicates that a person’s address is part of the Family Association grouping (under an ADDR block).'),
790
                'INDI:EVEN:_OVER'              => new CustomElement('An event sentence override (under an EVEN block).'),
791
                'INDI:SOUR:_VERI'              => new CustomElement('Indicates that a source citation or place name has a checkmark in the Verified column.'),
792
                'INDI:_TAG'                    => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'),
793
                'INDI:_TAG2'                   => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'),
794
                'INDI:_TAG3'                   => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'),
795
                'INDI:_TAG4'                   => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'),
796
                'INDI:_TAG5'                   => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'),
797
                'INDI:_TAG6'                   => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'),
798
                'INDI:_TAG7'                   => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'),
799
                'INDI:_TAG8'                   => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'),
800
                'INDI:_TAG9'                   => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'),
801
                'INDI:_TODO'                   => new CustomElement('Research task'),
802
                'INDI:_TODO:_CAT'              => new CustomElement('The Category of a To-Do item (under a _TODO record).'),
803
                'INDI:_TODO:_CDATE'            => new CustomElement('Closed Date of a To-Do item (under a _TODO record).'),
804
                'INDI:_TODO:_LOCL'             => new CustomElement('The Locality of a To-Do item (under a _TODO record).'),
805
                'INDI:_TODO:_RDATE'            => new CustomElement('Reminder date on to-do items. (Under a _TODO record.)'),
806
                'INDI:_UID'                    => new CustomElement('A Unique Identification Number given to each individual in a family file.'),
807
                'INDI:_URL'                    => new CustomElement('An Internet address (under an INDI record).'),
808
                'OBJE:_DATE'                   => new CustomElement('A date associated with a multimedia object, usually a picture or video (under an OBJE block).'),
809
                'OBJE:_PRIM'                   => new CustomElement('Means a multimedia object, usually a picture, is the Primary object (the one that is shown on a report) (under an OBJE block).'),
810
                'OBJE:_SCBK'                   => new CustomElement('Indicates that a Picture is tagged to be included in a scrapbook report (under an OBJE block).'),
811
                'OBJE:_SOUND'                  => new CustomElement('A sound file name that is attached to a picture (under an OBJE block).'),
812
                'OBJE:_TYPE'                   => new CustomElement('The type of a multimedia object: Photo, Sound, or Video (under an OBJE block).'),
813
                'SOUR:_ITALIC Y'               => new CustomElement('Indicates that a source title should be printed on a report in italics (under a SOUR record).'),
814
                'SOUR:_PAREN'                  => new CustomElement('Indicates that the Publication Facts of a source should be printed within parentheses on a report (under a SOUR record).'),
815
                'SOUR:_QUOTED Y'               => new CustomElement('Indicates that a source title should be printed within quotes on a report (under a SOUR record).'),
816
                'SOUR:_TAG NO'                 => new CustomElement('When used under a SOUR record, indicates to exclude the source citation detail on reports.'),
817
                'SOUR:_TAG2 NO'                => new CustomElement('When used under a SOUR record, indicates to exclude the source citation on reports.'),
818
                'SOUR:_TAG3 YES'               => new CustomElement('When used under a SOUR record, indicates to include the source citation detail text on reports.'),
819
                'SOUR:_TAG4 YES'               => new CustomElement('When used under a SOUR record, indicates to include the source citation detail notes on reports.'),
820
                '_PREF'                        => new CustomElement('Indicates a Preferred spouse, child or parents.'), // How is this used?
821
            ]);
822
823
            // Personal Ancestral File extensions
824
            $this->register([
825
                'INDI:NAME:_ADPN' => new NamePersonal(I18N::translate('Adopted name'), []),
826
                'INDI:NAME:_AKA'  => new NamePersonal(I18N::translate('Also known as'), []),
827
                'INDI:NAME:_AKAN' => new NamePersonal(I18N::translate('Also known as'), []),
828
                'INDI:_EMAIL'     => new AddressEmail(I18N::translate('Email address')),
829
                'URL'             => new CustomElement(I18N::translate('URL')),
830
                '_HEB'            => new CustomElement(I18N::translate('Hebrew')),
831
                '_NAME'           => new CustomElement(I18N::translate('Mailing name')),
832
                '_SCBK'           => new CustomElement(I18N::translate('Scrapbook')),
833
                '_SSHOW'          => new CustomElement(I18N::translate('Slide show')),
834
                '_TYPE'           => new CustomElement(I18N::translate('Media type')),
835
                '_URL'            => new CustomElement(I18N::translate('URL')),
836
            ]);
837
838
            // PhpGedView extensions
839
            $this->register([
840
                'FAM:CHAN:_PGVU'        => new WebtreesUser(I18N::translate('Author of last change')),
841
                'FAM:COMM'              => new CustomElement(I18N::translate('Comment')),
842
                'INDI:*:ASSO'           => new XrefAssociate(I18N::translate('Associate')),
843
                'INDI:*:ASSO:RELA'      => new RelationIsDescriptor(I18N::translate('Relationship')),
844
                'INDI:*:PLAC:_HEB'      => new NoteStructure(I18N::translate('Place in Hebrew')),
845
                'INDI:ADDR'             => new AddressLine(I18N::translate('Address'), []),
846
                'INDI:BIRT:DATE:TIME'   => new TimeValue(I18N::translate('Time')),
847
                'INDI:BURI:CEME'        => new CustomElement(I18N::translate('Cemetery')),
848
                'INDI:CHAN:_PGVU'       => new WebtreesUser(I18N::translate('Author of last change')),
849
                'INDI:COMM'             => new CustomElement(I18N::translate('Comment')),
850
                'INDI:DEAT:DATE:TIME'   => new TimeValue(I18N::translate('Time')),
851
                'INDI:EMAIL'            => new AddressEmail(I18N::translate('Email address')),
852
                'INDI:NAME:_HEB'        => new NamePersonal(I18N::translate('Name in Hebrew'), []),
853
                'INDI:_FNRL'            => new CustomEvent(I18N::translate('Funeral')),
854
                'INDI:_HOL'             => new CustomEvent(I18N::translate('Holocaust')),
855
                'INDI:_MILI'            => new CustomEvent(I18N::translate('Military')),
856
                'INDI:_PGV_OBJS'        => new XrefMedia(I18N::translate('Re-order media')),
857
                'NOTE:CHAN:_PGVU'       => new WebtreesUser(I18N::translate('Author of last change')),
858
                'OBJE:CHAN:_PGVU'       => new WebtreesUser(I18N::translate('Author of last change')),
859
                'OBJE:_PRIM'            => new CustomElement(I18N::translate('Highlighted image')),
860
                'OBJE:_THUM'            => new CustomElement(I18N::translate('Thumbnail image')),
861
                'REPO:CHAN:_PGVU'       => new WebtreesUser(I18N::translate('Author of last change')),
862
                'SOUR:CHAN:_PGVU'       => new WebtreesUser(I18N::translate('Author of last change')),
863
                'SOUR:SERV'             => new CustomElement(I18N::translate('Remote server')),
864
                'SOUR:URL'              => new AddressWebPage(I18N::translate('URL')),
865
                'SOUR:URL:TYPE'         => new CustomElement(I18N::translate('Type')), // e.g. "FamilySearch"
866
                'SOUR:URL:_BLOCK'       => new CustomElement(I18N::translate('Block')), // "e.g. "false"
867
                'SOUR:_DBID'            => new CustomElement(I18N::translate('Database name')),
868
                'SOUR:_DBID:_PASS'      => new CustomElement(I18N::translate('Database password')),
869
                'SOUR:_DBID:_PASS:RESN' => new RestrictionNotice(I18N::translate('Restriction')),
870
                'SOUR:_DBID:_USER'      => new CustomElement(I18N::translate('Database user account')),
871
            ]);
872
873
            // Reunion extensions
874
            $this->register([
875
                'INDI:EMAL'  => new AddressEmail(I18N::translate('Email address')),
876
                'INDI:CITN'  => new CustomElement(I18N::translate('Citizenship')),
877
                'INDI:_LEGA' => new CustomElement(I18N::translate('Legatee')),
878
                'INDI:_MDCL' => new CustomElement(I18N::translate('Medical')),
879
                'INDI:_PURC' => new CustomElement('Land purchase'),
880
                'INDI:_SALE' => new CustomElement('Land sale'),
881
            ]);
882
883
            // Roots Magic extensions
884
            $this->register([
885
                'INDI:_DNA'         => new CustomElement(I18N::translate('DNA markers')),
886
                'INDI:_WEBTAG'      => new CustomElement(I18N::translate('External link')),
887
                'INDI:_WEBTAG:NAME' => new CustomElement(I18N::translate('Text')),
888
                'INDI:_WEBTAG:URL'  => new AddressWebPage(I18N::translate('URL')),
889
                'SOUR:_BIBL'        => new CustomElement(I18N::translate('Bibliography')),
890
                'SOUR:_SUBQ'        => new CustomElement(I18N::translate('Abbreviation')),
891
            ]);
892
893
            // webtrees extensions
894
            $this->register([
895
                'FAM:CHAN:_WT_USER'           => new WebtreesUser(I18N::translate('Author of last change')),
896
                'FAM:_ASSO'                   => new XrefAssociate(I18N::translate('Associate')),
897
                'FAM:_ASSO:RELA'              => new RelationIsDescriptor(I18N::translate('Relationship')),
898
                'FAM:*:_ASSO'                 => new XrefAssociate(I18N::translate('Associate')),
899
                'FAM:*:_ASSO:NOTE'            => new NoteStructure(I18N::translate('Note')),
900
                'FAM:*:_ASSO:RELA'            => new RelationIsDescriptor(I18N::translate('Relationship')),
901
                'FAM:*:_ASSO:SOUR'            => new XrefSource(I18N::translate('Source citation')),
902
                'FAM:*:_ASSO:SOUR:DATA'       => new SourceData(I18N::translate('Data')),
903
                'FAM:*:_ASSO:SOUR:DATA:DATE'  => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
904
                'FAM:*:_ASSO:SOUR:DATA:TEXT'  => new TextFromSource(I18N::translate('Text')),
905
                'FAM:*:_ASSO:SOUR:EVEN'       => new EventTypeCitedFrom(I18N::translate('Event')),
906
                'FAM:*:_ASSO:SOUR:EVEN:ROLE'  => new RoleInEvent(I18N::translate('Role')),
907
                'FAM:*:_ASSO:SOUR:NOTE'       => new NoteStructure(I18N::translate('Note')),
908
                'FAM:*:_ASSO:SOUR:OBJE'       => new XrefMedia(I18N::translate('Media object')),
909
                'FAM:*:_ASSO:SOUR:PAGE'       => new WhereWithinSource(I18N::translate('Citation details')),
910
                'FAM:*:_ASSO:SOUR:QUAY'       => new CertaintyAssessment(I18N::translate('Quality of data')),
911
                'INDI:CHAN:_WT_USER'          => new WebtreesUser(I18N::translate('Author of last change')),
912
                'INDI:*:_ASSO'                => new XrefAssociate(I18N::translate('Associate')),
913
                'INDI:*:_ASSO:NOTE'           => new NoteStructure(I18N::translate('Note')),
914
                'INDI:*:_ASSO:RELA'           => new RelationIsDescriptor(I18N::translate('Relationship')),
915
                'INDI:*:_ASSO:SOUR'           => new XrefSource(I18N::translate('Source citation')),
916
                'INDI:*:_ASSO:SOUR:DATA'      => new SourceData(I18N::translate('Data')),
917
                'INDI:*:_ASSO:SOUR:DATA:DATE' => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
918
                'INDI:*:_ASSO:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')),
919
                'INDI:*:_ASSO:SOUR:EVEN'      => new EventTypeCitedFrom(I18N::translate('Event')),
920
                'INDI:*:_ASSO:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')),
921
                'INDI:*:_ASSO:SOUR:NOTE'      => new NoteStructure(I18N::translate('Note')),
922
                'INDI:*:_ASSO:SOUR:OBJE'      => new XrefMedia(I18N::translate('Media object')),
923
                'INDI:*:_ASSO:SOUR:PAGE'      => new WhereWithinSource(I18N::translate('Citation details')),
924
                'INDI:*:_ASSO:SOUR:QUAY'      => new CertaintyAssessment(I18N::translate('Quality of data')),
925
                'NOTE:CHAN:_WT_USER'          => new WebtreesUser(I18N::translate('Author of last change')),
926
                'NOTE:RESN'                   => new RestrictionNotice(I18N::translate('Restriction')),
927
                'OBJE:CHAN:_WT_USER'          => new WebtreesUser(I18N::translate('Author of last change')),
928
                'OBJE:RESN'                   => new RestrictionNotice(I18N::translate('Restriction')),
929
                'REPO:CHAN:_WT_USER'          => new WebtreesUser(I18N::translate('Author of last change')),
930
                'REPO:RESN'                   => new RestrictionNotice(I18N::translate('Restriction')),
931
                'SOUR:CHAN:_WT_USER'          => new WebtreesUser(I18N::translate('Author of last change')),
932
                'SOUR:RESN'                   => new RestrictionNotice(I18N::translate('Restriction')),
933
                'SUBM:CHAN:_WT_USER'          => new WebtreesUser(I18N::translate('Author of last change')),
934
                'SUBM:RESN'                   => new RestrictionNotice(I18N::translate('Restriction')),
935
                '_LOC:CHAN:_WT_USER'          => new WebtreesUser(I18N::translate('Author of last change')),
936
                '_LOC:RESN'                   => new RestrictionNotice(I18N::translate('Restriction')),
937
            ]);
938
        }
939
940
        return $this->elements;
941
    }
942
943
    /**
944
     * Register more elements.
945
     *
946
     * @param array<string,ElementInterface> $elements
947
     */
948
    public function register(array $elements): void
949
    {
950
        $this->elements = array_merge($this->elements(), $elements);
951
    }
952
953
    /**
954
     * @param string $tag
955
     *
956
     * @return ElementInterface|null
957
     */
958
    private function findElementByWildcard(string $tag): ?ElementInterface
959
    {
960
        foreach ($this->elements() as $tags => $element) {
961
            if (strpos($tags, '*') !== false) {
962
                $regex = '/^' . strtr($tags, ['*' => '[^:]+']) . '$/';
963
964
                if (preg_match($regex, $tag)) {
965
                    return $element;
966
                }
967
            }
968
        }
969
970
        return null;
971
    }
972
973
    /**
974
     * Definitions for GEDCOM 5.5.1.
975
     *
976
     * @return array<string,ElementInterface>
977
     */
978
    private function gedcom551(): array
979
    {
980
        return [
981
            'FAM'                      => new FamilyRecord(I18N::translate('Family')),
982
            'FAM:*:ADDR'               => new AddressLine(I18N::translate('Address')),
983
            'FAM:*:ADDR:ADR1'          => new AddressLine1(I18N::translate('Address line 1')),
984
            'FAM:*:ADDR:ADR2'          => new AddressLine2(I18N::translate('Address line 2')),
985
            'FAM:*:ADDR:ADR3'          => new AddressLine3(I18N::translate('Address line 3')),
986
            'FAM:*:ADDR:CITY'          => new AddressCity(I18N::translate('City')),
987
            'FAM:*:ADDR:CTRY'          => new AddressCountry(I18N::translate('Country')),
988
            'FAM:*:ADDR:POST'          => new AddressPostalCode(I18N::translate('Postal code')),
989
            'FAM:*:ADDR:STAE'          => new AddressState(I18N::translate('State')),
990
            'FAM:*:AGNC'               => new ResponsibleAgency(I18N::translate('Agency')),
991
            'FAM:*:CAUS'               => new CauseOfEvent(I18N::translate('Cause')),
992
            'FAM:*:DATE'               => new DateValue(I18N::translate('Date')),
993
            'FAM:*:EMAIL'              => new AddressEmail(I18N::translate('Email address')),
994
            'FAM:*:FAX'                => new AddressFax(I18N::translate('Fax')),
995
            'FAM:*:HUSB'               => new EmptyElement(I18N::translate('Husband'), ['AGE' => '0:1']),
996
            'FAM:*:HUSB:AGE'           => new AgeAtEvent(I18N::translate('Husband’s age')),
997
            'FAM:*:NOTE'               => new NoteStructure(I18N::translate('Note')),
998
            'FAM:*:OBJE'               => new XrefMedia(I18N::translate('Media object')),
999
            'FAM:*:PHON'               => new PhoneNumber(I18N::translate('Phone')),
1000
            'FAM:*:PLAC'               => new PlaceName(I18N::translate('Place')),
1001
            'FAM:*:PLAC:FONE'          => new PlacePhoneticVariation(I18N::translate('Phonetic place')),
1002
            'FAM:*:PLAC:FONE:TYPE'     => new PhoneticType(I18N::translate('Type')),
1003
            'FAM:*:PLAC:FORM'          => new PlaceHierarchy(I18N::translate('Format')),
1004
            'FAM:*:PLAC:MAP'           => new EmptyElement(I18N::translate('Coordinates')),
1005
            'FAM:*:PLAC:MAP:LATI'      => new PlaceLatitude(I18N::translate('Latitude')),
1006
            'FAM:*:PLAC:MAP:LONG'      => new PlaceLongtitude(I18N::translate('Longitude')),
1007
            'FAM:*:PLAC:NOTE'          => new NoteStructure(I18N::translate('Note')),
1008
            'FAM:*:PLAC:ROMN'          => new PlaceRomanizedVariation(I18N::translate('Romanized place')),
1009
            'FAM:*:PLAC:ROMN:TYPE'     => new RomanizedType(I18N::translate('Type')),
1010
            'FAM:*:RELI'               => new ReligiousAffiliation(I18N::translate('Religion')),
1011
            'FAM:*:RESN'               => new RestrictionNotice(I18N::translate('Restriction')),
1012
            'FAM:*:SOUR'               => new XrefSource(I18N::translate('Source')),
1013
            'FAM:*:SOUR:DATA'          => new SourceData(I18N::translate('Data')),
1014
            'FAM:*:SOUR:DATA:DATE'     => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
1015
            'FAM:*:SOUR:DATA:TEXT'     => new TextFromSource(I18N::translate('Text')),
1016
            'FAM:*:SOUR:EVEN'          => new EventTypeCitedFrom(I18N::translate('Event')),
1017
            'FAM:*:SOUR:EVEN:ROLE'     => new RoleInEvent(I18N::translate('Role')),
1018
            'FAM:*:SOUR:NOTE'          => new NoteStructure(I18N::translate('Note')),
1019
            'FAM:*:SOUR:OBJE'          => new XrefMedia(I18N::translate('Media object')),
1020
            'FAM:*:SOUR:PAGE'          => new WhereWithinSource(I18N::translate('Citation details')),
1021
            'FAM:*:SOUR:QUAY'          => new CertaintyAssessment(I18N::translate('Quality of data')),
1022
            'FAM:*:TYPE'               => new EventOrFactClassification(I18N::translate('Type')),
1023
            'FAM:*:WIFE'               => new EmptyElement(I18N::translate('Wife'), ['AGE' => '0:1']),
1024
            'FAM:*:WIFE:AGE'           => new AgeAtEvent(I18N::translate('Wife’s age')),
1025
            'FAM:*:WWW'                => new AddressWebPage(I18N::translate('URL')),
1026
            'FAM:ANUL'                 => new Annulment(I18N::translate('Annulment')),
1027
            'FAM:CENS'                 => new Census(I18N::translate('Census')),
1028
            'FAM:CHAN'                 => new Change(I18N::translate('Last change')),
1029
            'FAM:CHAN:DATE'            => new ChangeDate(I18N::translate('Date of last change')),
1030
            'FAM:CHAN:DATE:TIME'       => new TimeValue(I18N::translate('Time')),
1031
            'FAM:CHIL'                 => new XrefIndividual(I18N::translate('Child')),
1032
            'FAM:DIV'                  => new Divorce(I18N::translate('Divorce')),
1033
            'FAM:DIVF'                 => new DivorceFiled(I18N::translate('Divorce filed')),
1034
            'FAM:ENGA'                 => new Engagement(I18N::translate('Engagement')),
1035
            'FAM:ENGA:DATE'            => new DateValue(I18N::translate('Date of engagement')),
1036
            'FAM:ENGA:PLACE'           => new PlaceName(I18N::translate('Place of engagement')),
1037
            'FAM:EVEN'                 => new EventDescriptor(I18N::translate('Event')),
1038
            'FAM:EVEN:TYPE'            => new EventAttributeType(I18N::translate('Type of event')),
1039
            'FAM:HUSB'                 => new XrefIndividual(I18N::translate('Husband')),
1040
            'FAM:MARB'                 => new MarriageBanns(I18N::translate('Marriage banns')),
1041
            'FAM:MARB:DATE'            => new DateValue(I18N::translate('Date of marriage banns')),
1042
            'FAM:MARB:PLAC'            => new PlaceName(I18N::translate('Place of marriage banns')),
1043
            'FAM:MARC'                 => new MarriageContract(I18N::translate('Marriage contract')),
1044
            'FAM:MARL'                 => new MarriageLicence(I18N::translate('Marriage license')),
1045
            'FAM:MARR'                 => new Marriage(I18N::translate('Marriage')),
1046
            'FAM:MARR:DATE'            => new DateValue(I18N::translate('Date of marriage')),
1047
            'FAM:MARR:PLAC'            => new PlaceName(I18N::translate('Place of marriage')),
1048
            'FAM:MARR:TYPE'            => new MarriageType(I18N::translate('Type of marriage')),
1049
            'FAM:MARS'                 => new MarriageSettlement(I18N::translate('Marriage settlement')),
1050
            'FAM:NCHI'                 => new CountOfChildren(I18N::translate('Number of children')),
1051
            'FAM:NOTE'                 => new NoteStructure(I18N::translate('Note')),
1052
            'FAM:OBJE'                 => new XrefMedia(I18N::translate('Media object')),
1053
            'FAM:REFN'                 => new UserReferenceNumber(I18N::translate('Reference number')),
1054
            'FAM:REFN:TYPE'            => new UserReferenceType(I18N::translate('Type')),
1055
            'FAM:RESI'                 => new Residence(I18N::translate('Residence')),
1056
            'FAM:RESN'                 => new RestrictionNotice(I18N::translate('Restriction')),
1057
            'FAM:RIN'                  => new AutomatedRecordId(I18N::translate('Record ID number')),
1058
            'FAM:SLGS'                 => new LdsSpouseSealing(I18N::translate('LDS spouse sealing')),
1059
            'FAM:SLGS:DATE'            => new DateLdsOrd(I18N::translate('Date')),
1060
            'FAM:SLGS:PLAC'            => new PlaceLivingOrdinance(I18N::translate('Place')),
1061
            'FAM:SLGS:STAT'            => new LdsSpouseSealingDateStatus(I18N::translate('Status')),
1062
            'FAM:SLGS:STAT:DATE'       => new ChangeDate(I18N::translate('Status change date')),
1063
            'FAM:SLGS:TEMP'            => new TempleCode(I18N::translate('Temple')),
1064
            'FAM:SOUR'                 => new XrefSource(I18N::translate('Source')),
1065
            'FAM:SOUR:DATA'            => new SourceData(I18N::translate('Data')),
1066
            'FAM:SOUR:DATA:DATE'       => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
1067
            'FAM:SOUR:DATA:TEXT'       => new TextFromSource(I18N::translate('Text')),
1068
            'FAM:SOUR:EVEN'            => new EventTypeCitedFrom(I18N::translate('Event')),
1069
            'FAM:SOUR:EVEN:ROLE'       => new RoleInEvent(I18N::translate('Role')),
1070
            'FAM:SOUR:OBJE'            => new XrefMedia(I18N::translate('Media object')),
1071
            'FAM:SOUR:PAGE'            => new WhereWithinSource(I18N::translate('Citation details')),
1072
            'FAM:SOUR:QUAY'            => new CertaintyAssessment(I18N::translate('Quality of data')),
1073
            'FAM:SUBM'                 => new XrefSubmitter(I18N::translate('Submitter')),
1074
            'FAM:WIFE'                 => new XrefIndividual(I18N::translate('Wife')),
1075
            'HEAD'                     => new HeaderRecord(I18N::translate('Header')),
1076
            'HEAD:CHAR'                => new CharacterSet(I18N::translate('Character set')),
1077
            'HEAD:CHAR:VERS'           => new VersionNumber(I18N::translate('Version')),
1078
            'HEAD:COPR'                => new CopyrightFile(I18N::translate('Copyright')),
1079
            'HEAD:DATE'                => new TransmissionDate(I18N::translate('Date')),
1080
            'HEAD:DATE:TIME'           => new TimeValue(I18N::translate('Time')),
1081
            'HEAD:DEST'                => new ReceivingSystemName(I18N::translate('Destination')),
1082
            'HEAD:FILE'                => new FileName(I18N::translate('Filename')),
1083
            'HEAD:GEDC'                => new GedcomElement(I18N::translate('GEDCOM')),
1084
            'HEAD:GEDC:FORM'           => new Form(I18N::translate('Format')),
1085
            'HEAD:GEDC:VERS'           => new VersionNumber(I18N::translate('Version')),
1086
            'HEAD:LANG'                => new LanguageId(I18N::translate('Language')),
1087
            'HEAD:NOTE'                => new ContentDescription(I18N::translate('Note')),
1088
            'HEAD:PLAC'                => new EmptyElement(I18N::translate('Place hierarchy'), ['FORM' => '1:1']),
1089
            'HEAD:PLAC:FORM'           => new PlaceHierarchy(I18N::translate('Format')),
1090
            'HEAD:SOUR'                => new ApprovedSystemId('Genealogy software'),
1091
            'HEAD:SOUR:CORP'           => new NameOfBusiness(I18N::translate('Corporation')),
1092
            'HEAD:SOUR:CORP:ADDR'      => new AddressLine(I18N::translate('Address')),
1093
            'HEAD:SOUR:CORP:ADDR:ADR1' => new AddressLine1(I18N::translate('Address line 1')),
1094
            'HEAD:SOUR:CORP:ADDR:ADR2' => new AddressLine2(I18N::translate('Address line 2')),
1095
            'HEAD:SOUR:CORP:ADDR:ADR3' => new AddressLine3(I18N::translate('Address line 3')),
1096
            'HEAD:SOUR:CORP:ADDR:CITY' => new AddressCity(I18N::translate('City')),
1097
            'HEAD:SOUR:CORP:ADDR:CTRY' => new AddressCountry(I18N::translate('Country')),
1098
            'HEAD:SOUR:CORP:ADDR:POST' => new AddressPostalCode(I18N::translate('Postal code')),
1099
            'HEAD:SOUR:CORP:ADDR:STAE' => new AddressState(I18N::translate('State')),
1100
            'HEAD:SOUR:CORP:EMAIL'     => new AddressEmail(I18N::translate('Email address')),
1101
            'HEAD:SOUR:CORP:FAX'       => new AddressFax(I18N::translate('Fax')),
1102
            'HEAD:SOUR:CORP:PHON'      => new PhoneNumber(I18N::translate('Phone')),
1103
            'HEAD:SOUR:CORP:WWW'       => new AddressWebPage(I18N::translate('URL')),
1104
            'HEAD:SOUR:DATA'           => new NameOfSourceData('Data'),
1105
            'HEAD:SOUR:DATA:COPR'      => new CopyrightSourceData(I18N::translate('Copyright')),
1106
            'HEAD:SOUR:DATA:DATE'      => new PublicationDate(I18N::translate('Date')),
1107
            'HEAD:SOUR:NAME'           => new NameOfProduct('Software product'),
1108
            'HEAD:SOUR:VERS'           => new VersionNumber(I18N::translate('Version')),
1109
            'HEAD:SUBM'                => new XrefSubmitter(I18N::translate('Submitter')),
1110
            'HEAD:SUBN'                => new XrefSubmission(I18N::translate('Submission')),
1111
            'INDI'                     => new IndividualRecord(I18N::translate('Individual')),
1112
            'INDI:*:ADDR'              => new AddressLine(I18N::translate('Address')),
1113
            'INDI:*:ADDR:ADR1'         => new AddressLine1(I18N::translate('Address line 1')),
1114
            'INDI:*:ADDR:ADR2'         => new AddressLine2(I18N::translate('Address line 2')),
1115
            'INDI:*:ADDR:ADR3'         => new AddressLine3(I18N::translate('Address line 3')),
1116
            'INDI:*:ADDR:CITY'         => new AddressCity(I18N::translate('City')),
1117
            'INDI:*:ADDR:CTRY'         => new AddressCountry(I18N::translate('Country')),
1118
            'INDI:*:ADDR:POST'         => new AddressPostalCode(I18N::translate('Postal code')),
1119
            'INDI:*:ADDR:STAE'         => new AddressState(I18N::translate('State')),
1120
            'INDI:*:AGE'               => new AgeAtEvent(I18N::translate('Age')),
1121
            'INDI:*:AGNC'              => new ResponsibleAgency(I18N::translate('Agency')),
1122
            'INDI:*:CAUS'              => new CauseOfEvent(I18N::translate('Cause')),
1123
            'INDI:*:DATE'              => new DateValue(I18N::translate('Date')),
1124
            'INDI:*:EMAIL'             => new AddressEmail(I18N::translate('Email address')),
1125
            'INDI:*:FAX'               => new AddressFax(I18N::translate('Fax')),
1126
            'INDI:*:NOTE'              => new NoteStructure(I18N::translate('Note')),
1127
            'INDI:*:OBJE'              => new XrefMedia(I18N::translate('Media object')),
1128
            'INDI:*:PHON'              => new PhoneNumber(I18N::translate('Phone')),
1129
            'INDI:*:PLAC'              => new PlaceName(I18N::translate('Place')),
1130
            'INDI:*:PLAC:FONE'         => new PlacePhoneticVariation(I18N::translate('Phonetic place')),
1131
            'INDI:*:PLAC:FONE:TYPE'    => new PhoneticType(I18N::translate('Type')),
1132
            'INDI:*:PLAC:FORM'         => new PlaceHierarchy(I18N::translate('Format')),
1133
            'INDI:*:PLAC:MAP'          => new EmptyElement(I18N::translate('Coordinates')),
1134
            'INDI:*:PLAC:MAP:LATI'     => new PlaceLatitude(I18N::translate('Latitude')),
1135
            'INDI:*:PLAC:MAP:LONG'     => new PlaceLongtitude(I18N::translate('Longitude')),
1136
            'INDI:*:PLAC:NOTE'         => new NoteStructure(I18N::translate('Note')),
1137
            'INDI:*:PLAC:ROMN'         => new PlaceRomanizedVariation(I18N::translate('Romanized place')),
1138
            'INDI:*:PLAC:ROMN:TYPE'    => new RomanizedType(I18N::translate('Type')),
1139
            'INDI:*:RELI'              => new ReligiousAffiliation(I18N::translate('Religion')),
1140
            'INDI:*:RESN'              => new RestrictionNotice(I18N::translate('Restriction')),
1141
            'INDI:*:SOUR'              => new XrefSource(I18N::translate('Source')),
1142
            'INDI:*:SOUR:DATA'         => new SourceData(I18N::translate('Data')),
1143
            'INDI:*:SOUR:DATA:DATE'    => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
1144
            'INDI:*:SOUR:DATA:TEXT'    => new TextFromSource(I18N::translate('Text')),
1145
            'INDI:*:SOUR:EVEN'         => new EventTypeCitedFrom(I18N::translate('Event')),
1146
            'INDI:*:SOUR:EVEN:ROLE'    => new RoleInEvent(I18N::translate('Role')),
1147
            'INDI:*:SOUR:NOTE'         => new NoteStructure(I18N::translate('Note')),
1148
            'INDI:*:SOUR:OBJE'         => new XrefMedia(I18N::translate('Media object')),
1149
            'INDI:*:SOUR:PAGE'         => new WhereWithinSource(I18N::translate('Citation details')),
1150
            'INDI:*:SOUR:QUAY'         => new CertaintyAssessment(I18N::translate('Quality of data')),
1151
            'INDI:*:TYPE'              => new EventOrFactClassification(I18N::translate('Type')),
1152
            'INDI:*:WWW'               => new AddressWebPage(I18N::translate('URL')),
1153
            'INDI:ADOP'                => new Adoption(I18N::translate('Adoption')),
1154
            'INDI:ADOP:DATE'           => new DateValue(I18N::translate('Date of adoption')),
1155
            'INDI:ADOP:FAMC'           => new XrefFamily(I18N::translate('Adoptive parents')),
1156
            'INDI:ADOP:FAMC:ADOP'      => new AdoptedByWhichParent(I18N::translate('Adoption')),
1157
            'INDI:ADOP:PLAC'           => new PlaceName(I18N::translate('Place of adoption')),
1158
            'INDI:AFN'                 => new AncestralFileNumber(I18N::translate('Ancestral file number')),
1159
            'INDI:ALIA'                => new XrefIndividual(I18N::translate('Alias')),
1160
            'INDI:ANCI'                => new XrefSubmitter(I18N::translate('Ancestors interest')),
1161
            'INDI:ASSO'                => new XrefAssociate(I18N::translate('Associate')),
1162
            'INDI:ASSO:RELA'           => new RelationIsDescriptor(I18N::translate('Relationship')),
1163
            'INDI:BAPL'                => new LdsBaptism(I18N::translate('LDS baptism')),
1164
            'INDI:BAPL:DATE'           => new DateLdsOrd(I18N::translate('Date of LDS baptism')),
1165
            'INDI:BAPL:PLAC'           => new PlaceLivingOrdinance(I18N::translate('Place of LDS baptism')),
1166
            'INDI:BAPL:STAT'           => new LdsBaptismDateStatus(I18N::translate('Status')),
1167
            'INDI:BAPL:STAT:DATE'      => new ChangeDate(I18N::translate('Status change date')),
1168
            'INDI:BAPL:TEMP'           => new TempleCode(I18N::translate('Temple')),
1169
            'INDI:BAPM'                => new Baptism(I18N::translate('Baptism')),
1170
            'INDI:BAPM:DATE'           => new DateValue(I18N::translate('Date of baptism')),
1171
            'INDI:BAPM:PLAC'           => new PlaceName(I18N::translate('Place of baptism')),
1172
            'INDI:BARM'                => new PlaceName(I18N::translate('Bar mitzvah')),
1173
            'INDI:BARM:DATE'           => new DateValue(I18N::translate('Date of bar mitzvah')),
1174
            'INDI:BARM:PLAC'           => new PlaceName(I18N::translate('Place of bar mitzvah')),
1175
            'INDI:BASM'                => new BasMitzvah(I18N::translate('Bat mitzvah')),
1176
            'INDI:BASM:DATE'           => new BasMitzvah(I18N::translate('Date of bat mitzvah')),
1177
            'INDI:BASM:PLAC'           => new DateValue(I18N::translate('Place of bat mitzvah')),
1178
            'INDI:BIRT'                => new Birth(I18N::translate('Birth')),
1179
            'INDI:BIRT:DATE'           => new DateValue(I18N::translate('Date of birth')),
1180
            'INDI:BIRT:FAMC'           => new XrefFamily(I18N::translate('Birth parents')),
1181
            'INDI:BIRT:PLAC'           => new PlaceName(I18N::translate('Place of birth')),
1182
            'INDI:BLES'                => new Blessing(I18N::translate('Blessing')),
1183
            'INDI:BLES:DATE'           => new DateValue(I18N::translate('Date of blessing')),
1184
            'INDI:BLES:PLAC'           => new PlaceName(I18N::translate('Place of blessing')),
1185
            'INDI:BURI'                => new Burial(I18N::translate('Burial')),
1186
            'INDI:BURI:DATE'           => new DateValue(I18N::translate('Date of burial')),
1187
            'INDI:BURI:PLAC'           => new PlaceName(I18N::translate('Place of burial')),
1188
            'INDI:CAST'                => new CasteName(I18N::translate('Caste')),
1189
            'INDI:CENS'                => new Census(I18N::translate('Census')),
1190
            'INDI:CENS:DATE'           => new DateValue(I18N::translate('Census date')),
1191
            'INDI:CENS:PLAC'           => new PlaceName(I18N::translate('Census place')),
1192
            'INDI:CHAN'                => new Change(I18N::translate('Last change')),
1193
            'INDI:CHAN:DATE'           => new ChangeDate(I18N::translate('Date of last change')),
1194
            'INDI:CHAN:DATE:TIME'      => new TimeValue(I18N::translate('Time')),
1195
            'INDI:CHR'                 => new Christening(I18N::translate('Christening')),
1196
            'INDI:CHR:DATE'            => new DateValue(I18N::translate('Date of christening')),
1197
            'INDI:CHR:FAMC'            => new XrefFamily(I18N::translate('Godparents')),
1198
            'INDI:CHR:PLAC'            => new PlaceName(I18N::translate('Place of christening')),
1199
            'INDI:CHRA'                => new AdultChristening(I18N::translate('Adult christening')),
1200
            'INDI:CONF'                => new Confirmation(I18N::translate('Confirmation')),
1201
            'INDI:CONF:DATE'           => new DateValue(I18N::translate('Date of confirmation')),
1202
            'INDI:CONF:PLAC'           => new PlaceName(I18N::translate('Place of confirmation')),
1203
            'INDI:CONL'                => new LdsConfirmation(I18N::translate('LDS confirmation')),
1204
            'INDI:CONL:DATE'           => new DateLdsOrd(I18N::translate('Date of LDS confirmation')),
1205
            'INDI:CONL:PLAC'           => new PlaceLivingOrdinance(I18N::translate('Place of LDS confirmation')),
1206
            'INDI:CONL:STAT'           => new LdsSpouseSealingDateStatus(I18N::translate('Status')),
1207
            'INDI:CONL:STAT:DATE'      => new ChangeDate(I18N::translate('Status change date')),
1208
            'INDI:CONL:TEMP'           => new TempleCode(I18N::translate('Temple')),
1209
            'INDI:CREM'                => new Cremation(I18N::translate('Cremation')),
1210
            'INDI:CREM:DATE'           => new Cremation(I18N::translate('Date of cremation')),
1211
            'INDI:CREM:PLAC'           => new Cremation(I18N::translate('Place of cremation')),
1212
            'INDI:DEAT'                => new Death(I18N::translate('Death')),
1213
            'INDI:DEAT:CAUS'           => new CauseOfEvent(I18N::translate('Cause of death')),
1214
            'INDI:DEAT:DATE'           => new DateValue(I18N::translate('Date of death')),
1215
            'INDI:DEAT:PLAC'           => new PlaceName(I18N::translate('Place of death')),
1216
            'INDI:DESI'                => new XrefSubmitter(I18N::translate('Descendants interest')),
1217
            'INDI:DSCR'                => new PhysicalDescription(I18N::translate('Description')),
1218
            'INDI:EDUC'                => new ScholasticAchievement(I18N::translate('Education')),
1219
            'INDI:EDUC:AGNC'           => new ResponsibleAgency(I18N::translate('School or college')),
1220
            'INDI:EMIG'                => new Emigration(I18N::translate('Emigration')),
1221
            'INDI:EMIG:DATE'           => new DateValue(I18N::translate('Date of emigration')),
1222
            'INDI:EMIG:PLAC'           => new PlaceName(I18N::translate('Place of emigration')),
1223
            'INDI:ENDL'                => new LdsEndowment(I18N::translate('LDS endowment')),
1224
            'INDI:ENDL:DATE'           => new DateLdsOrd(I18N::translate('Date of LDS endowment')),
1225
            'INDI:ENDL:PLAC'           => new PlaceLivingOrdinance(I18N::translate('Place of LDS endowment')),
1226
            'INDI:ENDL:STAT'           => new LdsEndowmentDateStatus(I18N::translate('Status')),
1227
            'INDI:ENDL:STAT:DATE'      => new ChangeDate(I18N::translate('Status change date')),
1228
            'INDI:ENDL:TEMP'           => new TempleCode(I18N::translate('Temple')),
1229
            'INDI:EVEN'                => new EventDescriptor(I18N::translate('Event')),
1230
            'INDI:EVEN:DATE'           => new DateValue(I18N::translate('Date of event')),
1231
            'INDI:EVEN:PLAC'           => new PlaceName(I18N::translate('Place of event')),
1232
            'INDI:EVEN:TYPE'           => new EventAttributeType(I18N::translate('Type of event')),
1233
            'INDI:FACT'                => new AttributeDescriptor(I18N::translate('Fact')),
1234
            'INDI:FACT:TYPE'           => new EventAttributeType(I18N::translate('Type of fact')),
1235
            'INDI:FAMC'                => new XrefFamily(I18N::translate('Family as a child'), ['NOTE' => '0:1', 'PEDI' => '0:1', 'STAT' => '0:1']),
1236
            'INDI:FAMC:PEDI'           => new PedigreeLinkageType(I18N::translate('Relationship to parents')),
1237
            'INDI:FAMC:STAT'           => new ChildLinkageStatus(I18N::translate('Status')),
1238
            'INDI:FAMS'                => new XrefFamily(I18N::translate('Family as a spouse')),
1239
            'INDI:FCOM'                => new FirstCommunion(I18N::translate('First communion')),
1240
            'INDI:FCOM:DATE'           => new DateValue(I18N::translate('Date of first communion')),
1241
            'INDI:FCOM:PLAC'           => new PlaceName(I18N::translate('Place of first communion')),
1242
            'INDI:GRAD'                => new Graduation(I18N::translate('Graduation')),
1243
            'INDI:GRAD:AGNC'           => new ResponsibleAgency(I18N::translate('School or college')),
1244
            'INDI:IDNO'                => new NationalIdNumber(I18N::translate('Identification number')),
1245
            'INDI:IMMI'                => new Immigration(I18N::translate('Immigration')),
1246
            'INDI:IMMI:DATE'           => new DateValue(I18N::translate('Date of immigration')),
1247
            'INDI:IMMI:PLAC'           => new PlaceName(I18N::translate('Place of immigration')),
1248
            'INDI:NAME'                => new NamePersonal(I18N::translate('Name')),
1249
            'INDI:NAME:FONE'           => new NamePhoneticVariation(I18N::translate('Phonetic name'), ['TYPE' => '0,1']),
1250
            'INDI:NAME:FONE:GIVN'      => new NamePieceGiven(I18N::translate('Given names')),
1251
            'INDI:NAME:FONE:NICK'      => new NamePieceNickname(I18N::translate('Nickname')),
1252
            'INDI:NAME:FONE:NPFX'      => new NamePiecePrefix(I18N::translate('Name prefix')),
1253
            'INDI:NAME:FONE:NSFX'      => new NamePieceSuffix(I18N::translate('Name suffix')),
1254
            'INDI:NAME:FONE:SPFX'      => new NamePieceSurnamePrefix(I18N::translate('Surname prefix')),
1255
            'INDI:NAME:FONE:SURN'      => new NamePieceSurname(I18N::translate('Surname')),
1256
            'INDI:NAME:FONE:TYPE'      => new PhoneticType(I18N::translate('Phonetic type')),
1257
            'INDI:NAME:GIVN'           => new NamePieceGiven(I18N::translate('Given names')),
1258
            'INDI:NAME:NICK'           => new NamePieceNickname(I18N::translate('Nickname')),
1259
            'INDI:NAME:NPFX'           => new NamePiecePrefix(I18N::translate('Name prefix')),
1260
            'INDI:NAME:NSFX'           => new NamePieceSuffix(I18N::translate('Name suffix')),
1261
            'INDI:NAME:ROMN'           => new NameRomanizedVariation(I18N::translate('Romanized name'), ['TYPE' => '0,1']),
1262
            'INDI:NAME:ROMN:GIVN'      => new NamePieceGiven(I18N::translate('Given names')),
1263
            'INDI:NAME:ROMN:NICK'      => new NamePieceNickname(I18N::translate('Nickname')),
1264
            'INDI:NAME:ROMN:NPFX'      => new NamePiecePrefix(I18N::translate('Name prefix')),
1265
            'INDI:NAME:ROMN:NSFX'      => new NamePieceSuffix(I18N::translate('Name suffix')),
1266
            'INDI:NAME:ROMN:SPFX'      => new NamePieceSurnamePrefix(I18N::translate('Surname prefix')),
1267
            'INDI:NAME:ROMN:SURN'      => new NamePieceSurname(I18N::translate('Surname')),
1268
            'INDI:NAME:ROMN:TYPE'      => new RomanizedType(I18N::translate('Romanized type')),
1269
            'INDI:NAME:SPFX'           => new NamePieceSurnamePrefix(I18N::translate('Surname prefix')),
1270
            'INDI:NAME:SURN'           => new NamePieceSurname(I18N::translate('Surname')),
1271
            'INDI:NAME:TYPE'           => new NameType(I18N::translate('Type of name')),
1272
            'INDI:NATI'                => new NationOrTribalOrigin(I18N::translate('Nationality')),
1273
            'INDI:NATU'                => new Naturalization(I18N::translate('Naturalization')),
1274
            'INDI:NATU:DATE'           => new DateValue(I18N::translate('Date of naturalization')),
1275
            'INDI:NATU:PLAC'           => new PlaceName(I18N::translate('Place of naturalization')),
1276
            'INDI:NCHI'                => new CountOfChildren(I18N::translate('Number of children')),
1277
            'INDI:NMR'                 => new CountOfMarriages(I18N::translate('Number of marriages')),
1278
            'INDI:NOTE'                => new NoteStructure(I18N::translate('Note')),
1279
            'INDI:OBJE'                => new XrefMedia(I18N::translate('Media object')),
1280
            'INDI:OCCU'                => new Occupation(I18N::translate('Occupation')),
1281
            'INDI:OCCU:AGNC'           => new ResponsibleAgency(I18N::translate('Employer')),
1282
            'INDI:ORDN'                => new Ordination(I18N::translate('Ordination')),
1283
            'INDI:ORDN:AGNC'           => new Ordination(I18N::translate('Religious institution')),
1284
            'INDI:ORDN:DATE'           => new Ordination(I18N::translate('Date of ordination')),
1285
            'INDI:ORDN:PLAC'           => new Ordination(I18N::translate('Place of ordination')),
1286
            'INDI:PROB'                => new Probate(I18N::translate('Probate')),
1287
            'INDI:PROP'                => new Possessions(I18N::translate('Property')),
1288
            'INDI:REFN'                => new UserReferenceNumber(I18N::translate('Reference number')),
1289
            'INDI:REFN:TYPE'           => new UserReferenceType(I18N::translate('Type')),
1290
            'INDI:RELI'                => new ReligiousAffiliation(I18N::translate('Religion')),
1291
            'INDI:RESI'                => new Residence(I18N::translate('Residence')),
1292
            'INDI:RESI:DATE'           => new DateValue(I18N::translate('Date of residence')),
1293
            'INDI:RESI:PLAC'           => new PlaceName(I18N::translate('Place of residence')),
1294
            'INDI:RESN'                => new RestrictionNotice(I18N::translate('Restriction')),
1295
            'INDI:RETI'                => new Retirement(I18N::translate('Retirement')),
1296
            'INDI:RETI:AGNC'           => new ResponsibleAgency(I18N::translate('Employer')),
1297
            'INDI:RFN'                 => new PermanentRecordFileNumber(I18N::translate('Record file number')),
1298
            'INDI:RIN'                 => new AutomatedRecordId(I18N::translate('Record ID number')),
1299
            'INDI:SEX'                 => new SexValue(I18N::translate('Gender')),
1300
            'INDI:SLGC'                => new LdsChildSealing(I18N::translate('LDS child sealing')),
1301
            'INDI:SLGC:DATE'           => new DateLdsOrd(I18N::translate('Date of LDS child sealing')),
1302
            'INDI:SLGC:FAMC'           => new XrefFamily(I18N::translate('Parents')),
1303
            'INDI:SLGC:PLAC'           => new PlaceLivingOrdinance(I18N::translate('Place of LDS child sealing')),
1304
            'INDI:SLGC:STAT'           => new LdsChildSealingDateStatus(I18N::translate('Status')),
1305
            'INDI:SLGC:STAT:DATE'      => new ChangeDate(I18N::translate('Status change date')),
1306
            'INDI:SLGC:TEMP'           => new TempleCode(I18N::translate('Temple')),
1307
            'INDI:SOUR'                => new XrefSource(I18N::translate('Source')),
1308
            'INDI:SOUR:DATA'           => new SourceData(I18N::translate('Data')),
1309
            'INDI:SOUR:DATA:DATE'      => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
1310
            'INDI:SOUR:DATA:TEXT'      => new TextFromSource(I18N::translate('Text')),
1311
            'INDI:SOUR:EVEN'           => new EventTypeCitedFrom(I18N::translate('Event')),
1312
            'INDI:SOUR:EVEN:ROLE'      => new RoleInEvent(I18N::translate('Role')),
1313
            'INDI:SOUR:OBJE'           => new XrefMedia(I18N::translate('Media object')),
1314
            'INDI:SOUR:PAGE'           => new WhereWithinSource(I18N::translate('Citation details')),
1315
            'INDI:SOUR:QUAY'           => new CertaintyAssessment(I18N::translate('Quality of data')),
1316
            'INDI:SSN'                 => new SocialSecurityNumber(I18N::translate('Social security number')),
1317
            'INDI:SUBM'                => new XrefSubmitter(I18N::translate('Submitter')),
1318
            'INDI:TITL'                => new NobilityTypeTitle(I18N::translate('Title')),
1319
            'INDI:WILL'                => new Will(I18N::translate('Will')),
1320
            'NOTE'                     => new NoteRecord(I18N::translate('Note')),
1321
            'NOTE:CHAN'                => new Change(I18N::translate('Last change')),
1322
            'NOTE:CHAN:DATE'           => new ChangeDate(I18N::translate('Date of last change')),
1323
            'NOTE:CHAN:DATE:TIME'      => new TimeValue(I18N::translate('Time')),
1324
            'NOTE:CHAN:NOTE'           => new NoteStructure(I18N::translate('Note')),
1325
            'NOTE:CONC'                => new SubmitterText(I18N::translate('Note')),
1326
            'NOTE:CONT'                => new SubmitterText(I18N::translate('Continued')),
1327
            'NOTE:REFN'                => new UserReferenceNumber(I18N::translate('Reference number')),
1328
            'NOTE:REFN:TYPE'           => new UserReferenceType(I18N::translate('Type')),
1329
            'NOTE:RIN'                 => new AutomatedRecordId(I18N::translate('Record ID number')),
1330
            'NOTE:SOUR'                => new XrefSource(I18N::translate('Source')),
1331
            'NOTE:SOUR:DATA'           => new SourceData(I18N::translate('Data')),
1332
            'NOTE:SOUR:DATA:DATE'      => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
1333
            'NOTE:SOUR:DATA:TEXT'      => new TextFromSource(I18N::translate('Text')),
1334
            'NOTE:SOUR:EVEN'           => new EventTypeCitedFrom(I18N::translate('Event')),
1335
            'NOTE:SOUR:EVEN:ROLE'      => new RoleInEvent(I18N::translate('Role')),
1336
            'NOTE:SOUR:NOTE'           => new NoteStructure(I18N::translate('Note')),
1337
            'NOTE:SOUR:OBJE'           => new XrefMedia(I18N::translate('Media object')),
1338
            'NOTE:SOUR:PAGE'           => new WhereWithinSource(I18N::translate('Citation details')),
1339
            'NOTE:SOUR:QUAY'           => new CertaintyAssessment(I18N::translate('Quality of data')),
1340
            'OBJE'                     => new MediaRecord(I18N::translate('Media object')),
1341
            'OBJE:CHAN'                => new Change(I18N::translate('Last change')),
1342
            'OBJE:CHAN:DATE'           => new ChangeDate(I18N::translate('Date of last change')),
1343
            'OBJE:CHAN:DATE:TIME'      => new TimeValue(I18N::translate('Time')),
1344
            'OBJE:CHAN:NOTE'           => new NoteStructure(I18N::translate('Note')),
1345
            'OBJE:FILE'                => new MultimediaFileReference(I18N::translate('Filename')),
1346
            'OBJE:FILE:FORM'           => new MultimediaFormat(I18N::translate('Format')),
1347
            'OBJE:FILE:FORM:TYPE'      => new SourceMediaType(I18N::translate('Media type')),
1348
            'OBJE:FILE:TITL'           => new DescriptiveTitle(I18N::translate('Title')),
1349
            'OBJE:NOTE'                => new NoteStructure(I18N::translate('Note')),
1350
            'OBJE:REFN'                => new UserReferenceNumber(I18N::translate('Reference number')),
1351
            'OBJE:REFN:TYPE'           => new UserReferenceType(I18N::translate('Type')),
1352
            'OBJE:RIN'                 => new AutomatedRecordId(I18N::translate('Record ID number')),
1353
            'OBJE:SOUR'                => new XrefSource(I18N::translate('Source')),
1354
            'OBJE:SOUR:DATA'           => new SourceData(I18N::translate('Data')),
1355
            'OBJE:SOUR:DATA:DATE'      => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
1356
            'OBJE:SOUR:DATA:TEXT'      => new TextFromSource(I18N::translate('Text')),
1357
            'OBJE:SOUR:EVEN'           => new EventTypeCitedFrom(I18N::translate('Event')),
1358
            'OBJE:SOUR:EVEN:ROLE'      => new RoleInEvent(I18N::translate('Role')),
1359
            'OBJE:SOUR:NOTE'           => new NoteStructure(I18N::translate('Note')),
1360
            'OBJE:SOUR:OBJE'           => new XrefMedia(I18N::translate('Media object')),
1361
            'OBJE:SOUR:PAGE'           => new WhereWithinSource(I18N::translate('Citation details')),
1362
            'OBJE:SOUR:QUAY'           => new CertaintyAssessment(I18N::translate('Quality of data')),
1363
            'REPO'                     => new RepositoryRecord(I18N::translate('Repository')),
1364
            'REPO:ADDR'                => new AddressLine(I18N::translate('Address')),
1365
            'REPO:ADDR:ADR1'           => new AddressLine1(I18N::translate('Address line 1')),
1366
            'REPO:ADDR:ADR2'           => new AddressLine2(I18N::translate('Address line 2')),
1367
            'REPO:ADDR:ADR3'           => new AddressLine3(I18N::translate('Address line 3')),
1368
            'REPO:ADDR:CITY'           => new AddressCity(I18N::translate('City')),
1369
            'REPO:ADDR:CTRY'           => new AddressCountry(I18N::translate('Country')),
1370
            'REPO:ADDR:POST'           => new AddressPostalCode(I18N::translate('Postal code')),
1371
            'REPO:ADDR:STAE'           => new AddressState(I18N::translate('State')),
1372
            'REPO:CHAN'                => new Change(I18N::translate('Last change')),
1373
            'REPO:CHAN:DATE'           => new ChangeDate(I18N::translate('Date of last change')),
1374
            'REPO:CHAN:DATE:TIME'      => new TimeValue(I18N::translate('Time')),
1375
            'REPO:CHAN:NOTE'           => new NoteStructure(I18N::translate('Note')),
1376
            'REPO:EMAIL'               => new AddressEmail(I18N::translate('Email address')),
1377
            'REPO:FAX'                 => new AddressFax(I18N::translate('Fax')),
1378
            'REPO:NAME'                => new NameOfRepository(I18N::translateContext('Repository', 'Name')),
1379
            'REPO:NOTE'                => new NoteStructure(I18N::translate('Note')),
1380
            'REPO:PHON'                => new PhoneNumber(I18N::translate('Phone')),
1381
            'REPO:REFN'                => new UserReferenceNumber(I18N::translate('Reference number')),
1382
            'REPO:REFN:TYPE'           => new UserReferenceType(I18N::translate('Type')),
1383
            'REPO:RIN'                 => new AutomatedRecordId(I18N::translate('Record ID number')),
1384
            'REPO:WWW'                 => new AddressWebPage(I18N::translate('URL')),
1385
            'SOUR'                     => new SourceRecord(I18N::translate('Source')),
1386
            'SOUR:ABBR'                => new SourceFiledByEntry(I18N::translate('Abbreviation')),
1387
            'SOUR:AUTH'                => new SourceOriginator(I18N::translate('Author')),
1388
            'SOUR:CHAN'                => new Change(I18N::translate('Last change')),
1389
            'SOUR:CHAN:DATE'           => new ChangeDate(I18N::translate('Date of last change')),
1390
            'SOUR:CHAN:DATE:TIME'      => new TimeValue(I18N::translate('Time')),
1391
            'SOUR:CHAN:NOTE'           => new NoteStructure(I18N::translate('Note')),
1392
            'SOUR:DATA'                => new EmptyElement(I18N::translate('Data'), ['EVEN' => '0:M', 'AGNC' => '0:1', 'NOTE' => '0:M']),
1393
            'SOUR:DATA:AGNC'           => new ResponsibleAgency(I18N::translate('Agency')),
1394
            'SOUR:DATA:EVEN'           => new EventsRecorded(I18N::translate('Events')),
1395
            'SOUR:DATA:EVEN:DATE'      => new DateValue(I18N::translate('Date range')),
1396
            'SOUR:DATA:EVEN:PLAC'      => new SourceJurisdictionPlace(I18N::translate('Place')),
1397
            'SOUR:DATA:NOTE'           => new NoteStructure(I18N::translate('Note')),
1398
            'SOUR:NOTE'                => new NoteStructure(I18N::translate('Note')),
1399
            'SOUR:OBJE'                => new XrefMedia(I18N::translate('Media object')),
1400
            'SOUR:PUBL'                => new SourcePublicationFacts(I18N::translate('Publication')),
1401
            'SOUR:REFN'                => new UserReferenceNumber(I18N::translate('Reference number')),
1402
            'SOUR:REFN:TYPE'           => new UserReferenceType(I18N::translate('Type')),
1403
            'SOUR:REPO'                => new XrefRepository(I18N::translate('Repository')),
1404
            'SOUR:REPO:CALN'           => new SourceCallNumber(I18N::translate('Call number')),
1405
            'SOUR:REPO:CALN:MEDI'      => new SourceMediaType(I18N::translate('Media type')),
1406
            'SOUR:REPO:NOTE'           => new NoteStructure(I18N::translate('Note')),
1407
            'SOUR:RIN'                 => new AutomatedRecordId(I18N::translate('Record ID number')),
1408
            'SOUR:TEXT'                => new TextFromSource(I18N::translate('Text')),
1409
            'SOUR:TITL'                => new DescriptiveTitle(I18N::translate('Title')),
1410
            'SUBM'                     => new SubmitterRecord(I18N::translate('Submitter')),
1411
            'SUBM:ADDR'                => new AddressLine(I18N::translate('Address')),
1412
            'SUBM:ADDR:ADR1'           => new AddressLine1(I18N::translate('Address line 1')),
1413
            'SUBM:ADDR:ADR2'           => new AddressLine2(I18N::translate('Address line 2')),
1414
            'SUBM:ADDR:ADR3'           => new AddressLine3(I18N::translate('Address line 3')),
1415
            'SUBM:ADDR:CITY'           => new AddressCity(I18N::translate('City')),
1416
            'SUBM:ADDR:CTRY'           => new AddressCountry(I18N::translate('Country')),
1417
            'SUBM:ADDR:POST'           => new AddressPostalCode(I18N::translate('Postal code')),
1418
            'SUBM:ADDR:STAE'           => new AddressState(I18N::translate('State')),
1419
            'SUBM:CHAN'                => new Change(I18N::translate('Last change')),
1420
            'SUBM:CHAN:DATE'           => new ChangeDate(I18N::translate('Date of last change')),
1421
            'SUBM:CHAN:DATE:TIME'      => new TimeValue(I18N::translate('Time')),
1422
            'SUBM:CHAN:NOTE'           => new NoteStructure(I18N::translate('Note')),
1423
            'SUBM:EMAIL'               => new AddressEmail(I18N::translate('Email address')),
1424
            'SUBM:FAX'                 => new AddressFax(I18N::translate('Fax')),
1425
            'SUBM:LANG'                => new LanguageId(I18N::translate('Language')),
1426
            'SUBM:NAME'                => new SubmitterName(I18N::translate('Name')),
1427
            'SUBM:NOTE'                => new NoteStructure(I18N::translate('Note')),
1428
            'SUBM:OBJE'                => new XrefMedia(I18N::translate('Media object')),
1429
            'SUBM:PHON'                => new PhoneNumber(I18N::translate('Phone')),
1430
            'SUBM:RFN'                 => new SubmitterRegisteredRfn(I18N::translate('Record file number')),
1431
            'SUBM:RIN'                 => new AutomatedRecordId(I18N::translate('Record ID number')),
1432
            'SUBM:WWW'                 => new AddressWebPage(I18N::translate('URL')),
1433
            'SUBN'                     => new SubmissionRecord(I18N::translate('Submission')),
1434
            'SUBN:ANCE'                => new GenerationsOfAncestors(I18N::translate('Generations of ancestors')),
1435
            'SUBN:CHAN'                => new Change(I18N::translate('Last change')),
1436
            'SUBN:CHAN:DATE'           => new ChangeDate(I18N::translate('Date of last change')),
1437
            'SUBN:CHAN:DATE:TIME'      => new TimeValue(I18N::translate('Time')),
1438
            'SUBN:CHAN:NOTE'           => new NoteStructure(I18N::translate('Note')),
1439
            'SUBN:DESC'                => new GenerationsOfDescendants(I18N::translate('Generations of descendants')),
1440
            'SUBN:FAMF'                => new NameOfFamilyFile(I18N::translate('Family file')),
1441
            'SUBN:NOTE'                => new NoteStructure(I18N::translate('Note')),
1442
            'SUBN:ORDI'                => new OrdinanceProcessFlag(I18N::translate('Ordinance')),
1443
            'SUBN:RIN'                 => new AutomatedRecordId(I18N::translate('Record ID number')),
1444
            'SUBN:SUBM'                => new XrefSubmitter(I18N::translate('Submitter')),
1445
            'SUBN:TEMP'                => new TempleCode(/* I18N: https://en.wikipedia.org/wiki/Temple_(LDS_Church)*/ I18N::translate('Temple')),
1446
            'TRLR'                     => new EmptyElement(I18N::translate('Trailer')),
1447
        ];
1448
    }
1449
}
1450