xref: /webtrees/app/Gedcom.php (revision d93e9e4d83f7254758fa30cfc930abc5dce3d121)
10f471f91SGreg Roach<?php
23976b470SGreg Roach
30f471f91SGreg Roach/**
40f471f91SGreg Roach * webtrees: online genealogy
55bfc6897SGreg Roach * Copyright (C) 2022 webtrees development team
60f471f91SGreg Roach * This program is free software: you can redistribute it and/or modify
70f471f91SGreg Roach * it under the terms of the GNU General Public License as published by
80f471f91SGreg Roach * the Free Software Foundation, either version 3 of the License, or
90f471f91SGreg Roach * (at your option) any later version.
100f471f91SGreg Roach * This program is distributed in the hope that it will be useful,
110f471f91SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
120f471f91SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
130f471f91SGreg Roach * GNU General Public License for more details.
140f471f91SGreg Roach * You should have received a copy of the GNU General Public License
1589f7189bSGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>.
160f471f91SGreg Roach */
17fcfa147eSGreg Roach
18e7f56f2aSGreg Roachdeclare(strict_types=1);
19e7f56f2aSGreg Roach
200f471f91SGreg Roachnamespace Fisharebest\Webtrees;
210f471f91SGreg Roach
22e669bb4bSGreg Roachuse Fisharebest\Webtrees\Contracts\ElementFactoryInterface;
2300c92694SGreg Roachuse Fisharebest\Webtrees\Contracts\ElementInterface;
2400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AddressCity;
2500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AddressCountry;
2600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AddressEmail;
2700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AddressFax;
2800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AddressLine;
2900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AddressLine1;
3000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AddressLine2;
3100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AddressLine3;
3200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AddressPostalCode;
3300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AddressState;
3400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AddressWebPage;
3500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AdoptedByWhichParent;
3600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Adoption;
3700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AdultChristening;
3800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AgeAtEvent;
3900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AncestralFileNumber;
4000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Annulment;
4100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ApprovedSystemId;
4200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AutomatedRecordId;
4300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Baptism;
4400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\BarMitzvah;
4500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\BasMitzvah;
4600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Birth;
4700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Blessing;
4800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Burial;
4900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CasteName;
5000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CauseOfEvent;
5100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Census;
5200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CertaintyAssessment;
5300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Change;
5400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ChangeDate;
5500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CharacterSet;
5600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ChildLinkageStatus;
5700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Christening;
5800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Confirmation;
5900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ContentDescription;
6000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Coordinates;
6100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CopyrightFile;
6200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CopyrightSourceData;
6300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CountOfChildren;
6400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CountOfMarriages;
65701f5d18SGreg Roachuse Fisharebest\Webtrees\Elements\Creation;
6600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Cremation;
6700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CustomElement;
6800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CustomEvent;
6900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CustomFact;
7000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CustomFamilyEvent;
7100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CustomIndividualEvent;
7200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\DateLdsOrd;
7300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\DateValue;
7400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Death;
7500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\DescriptiveTitle;
7600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Divorce;
7700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\DivorceFiled;
7800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Emigration;
7900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\EmptyElement;
8000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Engagement;
8100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\EventAttributeType;
8200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\EventOrFactClassification;
8300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\EventsRecorded;
8400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\EventTypeCitedFrom;
85701f5d18SGreg Roachuse Fisharebest\Webtrees\Elements\ExternalIdentifier;
86701f5d18SGreg Roachuse Fisharebest\Webtrees\Elements\ExternalIdentifierType;
8700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\FamilyCensus;
885d2c6313SGreg Roachuse Fisharebest\Webtrees\Elements\FamilyEvent;
895d2c6313SGreg Roachuse Fisharebest\Webtrees\Elements\FamilyFact;
9000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\FamilyRecord;
9100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\FamilyResidence;
9200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\FamilySearchFamilyTreeId;
9300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\FamilyStatusText;
9400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\FileName;
9500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\FirstCommunion;
9600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Form;
9700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\GedcomElement;
9800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\GenerationsOfAncestors;
9900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\GenerationsOfDescendants;
10000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\GovIdentifier;
10100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Graduation;
10200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\HeaderRecord;
10300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\HierarchicalRelationship;
10400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Immigration;
1055d2c6313SGreg Roachuse Fisharebest\Webtrees\Elements\IndividualEvent;
1065d2c6313SGreg Roachuse Fisharebest\Webtrees\Elements\IndividualFact;
10700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\IndividualRecord;
10800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\LanguageId;
10900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\LdsBaptism;
11000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\LdsBaptismDateStatus;
11100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\LdsChildSealing;
11200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\LdsChildSealingDateStatus;
11300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\LdsConfirmation;
11400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\LdsEndowment;
11500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\LdsEndowmentDateStatus;
116701f5d18SGreg Roachuse Fisharebest\Webtrees\Elements\LdsInitiatory;
117701f5d18SGreg Roachuse Fisharebest\Webtrees\Elements\LdsOrdinanceStatus;
11800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\LdsSpouseSealing;
11900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\LdsSpouseSealingDateStatus;
12000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\LocationRecord;
12100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\MaidenheadLocator;
12200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Marriage;
12300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\MarriageBanns;
12400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\MarriageContract;
12500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\MarriageLicence;
12600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\MarriageSettlement;
12700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\MarriageType;
12800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\MediaRecord;
12900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\MultimediaFileReference;
13000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\MultimediaFormat;
13100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NameOfBusiness;
13200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NameOfFamilyFile;
13300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NameOfProduct;
13400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NameOfRepository;
13500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NameOfSourceData;
13600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NamePersonal;
13700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NamePhoneticVariation;
13800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NamePieceGiven;
13900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NamePieceNickname;
14000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NamePiecePrefix;
14100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NamePieceSuffix;
14200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NamePieceSurname;
14300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NamePieceSurnamePrefix;
14400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NameRomanizedVariation;
14500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NameType;
14600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NationalIdNumber;
147f15544dcSGreg Roachuse Fisharebest\Webtrees\Elements\NationalOrTribalOrigin;
14800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Naturalization;
14900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NobilityTypeTitle;
150701f5d18SGreg Roachuse Fisharebest\Webtrees\Elements\NonEvent;
15100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NoteRecord;
15200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NoteStructure;
15300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Occupation;
15400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\OrdinanceProcessFlag;
15500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Ordination;
15600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PafUid;
15700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PedigreeLinkageType;
15800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PermanentRecordFileNumber;
15900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PhoneNumber;
16000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PhoneticType;
16100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PhysicalDescription;
16200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PlaceHierarchy;
16300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PlaceLatitude;
16400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PlaceLivingOrdinance;
16500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PlaceLongtitude;
16600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PlaceName;
16700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PlacePhoneticVariation;
16800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PlaceRomanizedVariation;
16900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Possessions;
17000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Probate;
17100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PublicationDate;
17200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ReceivingSystemName;
17300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\RelationIsDescriptor;
17400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ReligiousAffiliation;
17500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\RepositoryRecord;
17600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ResearchTask;
17700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ResearchTaskPriority;
17800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ResearchTaskStatus;
17900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ResearchTaskType;
18000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Residence;
18100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ResponsibleAgency;
18200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\RestrictionNotice;
18300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Retirement;
18400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\RoleInEvent;
18500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\RomanizedType;
18600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ScholasticAchievement;
18700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SexValue;
18800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SexXValue;
18900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SocialSecurityNumber;
19000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SourceCallNumber;
19100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SourceData;
19200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SourceFiledByEntry;
19300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SourceJurisdictionPlace;
19400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SourceMediaType;
19500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SourceOriginator;
19600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SourcePublicationFacts;
19700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SourceRecord;
19800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SubmissionRecord;
19900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SubmitterName;
20000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SubmitterRecord;
20100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SubmitterRegisteredRfn;
20200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SubmitterText;
20300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\TempleCode;
20400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\TextFromSource;
20500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\TimeValue;
20600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\TransmissionDate;
207701f5d18SGreg Roachuse Fisharebest\Webtrees\Elements\Uid;
20800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\UserReferenceNumber;
20900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\UserReferenceType;
21000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\VersionNumber;
21100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\WebtreesUser;
21200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\WhereWithinSource;
21300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Will;
21400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\XrefAssociate;
21500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\XrefFamily;
21600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\XrefIndividual;
21700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\XrefLocation;
21800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\XrefMedia;
21900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\XrefRepository;
220701f5d18SGreg Roachuse Fisharebest\Webtrees\Elements\XrefSharedNote;
22100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\XrefSource;
22200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\XrefSubmission;
22300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\XrefSubmitter;
22400c92694SGreg Roach
2250f471f91SGreg Roach/**
2260f471f91SGreg Roach * GEDCOM 5.5.1 specification
2270f471f91SGreg Roach */
228c1010edaSGreg Roachclass Gedcom
229c1010edaSGreg Roach{
2300f471f91SGreg Roach    // 255 less the EOL character.
23116d6367aSGreg Roach    public const LINE_LENGTH = 253;
2328d0ebef0SGreg Roach
2338d0ebef0SGreg Roach    // Gedcom tags which indicate the start of life.
23469d5bee2SGreg Roach    public const BIRTH_EVENTS = ['BIRT', 'CHR', 'BAPM'];
2358d0ebef0SGreg Roach
2368d0ebef0SGreg Roach    // Gedcom tags which indicate the end of life.
23716d6367aSGreg Roach    public const DEATH_EVENTS = ['DEAT', 'BURI', 'CREM'];
2388d0ebef0SGreg Roach
2398d0ebef0SGreg Roach    // Gedcom tags which indicate the start of a relationship.
24016d6367aSGreg Roach    public const MARRIAGE_EVENTS = ['MARR', '_NMR'];
2418d0ebef0SGreg Roach
2428d0ebef0SGreg Roach    // Gedcom tags which indicate the end of a relationship.
24316d6367aSGreg Roach    public const DIVORCE_EVENTS = ['DIV', 'ANUL', '_SEPR'];
2448d0ebef0SGreg Roach
2458d0ebef0SGreg Roach    // Regular expression to match a GEDCOM tag.
24616d6367aSGreg Roach    public const REGEX_TAG = '[_A-Z][_A-Z0-9]*';
2478d0ebef0SGreg Roach
2488d0ebef0SGreg Roach    // Regular expression to match a GEDCOM XREF.
249f81cefe9SGreg Roach    public const REGEX_XREF = '[A-Za-z0-9:_.-]{1,20}';
2508d0ebef0SGreg Roach
251c67b9b50SGreg Roach    // Regular expression to match a GEDCOM fact/event for editing raw GEDCOM.
2528c21b414SGreg Roach    private const REGEX_VALUE   = '( .+)?';
2538c21b414SGreg Roach    private const REGEX_LEVEL_9 = '\n9 ' . self::REGEX_TAG . self::REGEX_VALUE;
2548c21b414SGreg Roach    private const REGEX_LEVEL_8 = '\n8 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_9 . ')*';
2558c21b414SGreg Roach    private const REGEX_LEVEL_7 = '\n7 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_8 . ')*';
2568c21b414SGreg Roach    private const REGEX_LEVEL_6 = '\n6 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_7 . ')*';
2578c21b414SGreg Roach    private const REGEX_LEVEL_5 = '\n5 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_6 . ')*';
2588c21b414SGreg Roach    private const REGEX_LEVEL_4 = '\n4 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_5 . ')*';
2598c21b414SGreg Roach    private const REGEX_LEVEL_3 = '\n3 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_4 . ')*';
2608c21b414SGreg Roach    private const REGEX_LEVEL_2 = '\n2 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_3 . ')*';
261c67b9b50SGreg Roach    public const REGEX_FACT     = '1 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_2 . ')*\n?';
2628c21b414SGreg Roach
2631c6adce8SGreg Roach    // Separates the parts of a place name.
264ead61980SGreg Roach    public const PLACE_SEPARATOR = ', ';
265392561bbSGreg Roach
266392561bbSGreg Roach    // Regex to match a (badly formed) GEDCOM place separator.
26790949315SGreg Roach    public const PLACE_SEPARATOR_REGEX = '/ *,[, ]*/';
26890949315SGreg Roach
26990949315SGreg Roach    // LATI and LONG tags
27090949315SGreg Roach    public const LATITUDE_NORTH = 'N';
27190949315SGreg Roach    public const LATITUDE_SOUTH = 'S';
27290949315SGreg Roach    public const LONGITUDE_EAST = 'E';
27390949315SGreg Roach    public const LONGITUDE_WEST = 'W';
27471f696adSGreg Roach
27571f696adSGreg Roach    // Not all record types allow a CHAN event.
27671f696adSGreg Roach    public const RECORDS_WITH_CHAN = [
27771f696adSGreg Roach        Family::RECORD_TYPE,
27871f696adSGreg Roach        Individual::RECORD_TYPE,
27971f696adSGreg Roach        Media::RECORD_TYPE,
28071f696adSGreg Roach        Note::RECORD_TYPE,
28171f696adSGreg Roach        Repository::RECORD_TYPE,
28271f696adSGreg Roach        Source::RECORD_TYPE,
28371f696adSGreg Roach        Submitter::RECORD_TYPE,
28471f696adSGreg Roach    ];
285c8183f29SGreg Roach
286c8183f29SGreg Roach    // These preferences control multiple tag definitions
287c8183f29SGreg Roach    public const HIDDEN_TAGS = [
288c8183f29SGreg Roach        // Individual names
289c8183f29SGreg Roach        'NAME_NPFX'  => ['INDI:NAME:NPFX', 'INDI:NAME:FONE:NPFX', 'INDI:NAME:ROMN:NPFX'],
290c8183f29SGreg Roach        'NAME_SPFX'  => ['INDI:NAME:SPFX', 'INDI:NAME:FONE:SPFX', 'INDI:NAME:ROMN:SPFX'],
291c8183f29SGreg Roach        'NAME_NSFX'  => ['INDI:NAME:NSFX', 'INDI:NAME:FONE:NSFX', 'INDI:NAME:ROMN:NSFX'],
292c8183f29SGreg Roach        'NAME_NICK'  => ['INDI:NAME:NICK', 'INDI:NAME:FONE:NICK', 'INDI:NAME:ROMN:NICK'],
293c8183f29SGreg Roach        'NAME_FONE'  => ['INDI:NAME:FONE'],
294c8183f29SGreg Roach        'NAME_ROMN'  => ['INDI:NAME:ROMN'],
29503c55594SGreg Roach        'NAME_NOTE'  => ['INDI:NAME:NOTE', 'INDI:NAME:FONE:NOTE', 'INDI:NAME:ROMN:NOTE'],
29603c55594SGreg Roach        'NAME_SOUR'  => ['INDI:NAME:SOUR', 'INDI:NAME:FONE:SOUR', 'INDI:NAME:ROMN:SOUR'],
297c8183f29SGreg Roach        // Places
298302fdb8dSGreg Roach        'PLAC_MAP'   => [':PLAC:MAP'],
299302fdb8dSGreg Roach        'PLAC_FONE'  => [':PLAC:FONE'],
300302fdb8dSGreg Roach        'PLAC_ROMN'  => [':PLAC:ROMN'],
301302fdb8dSGreg Roach        'PLAC_FORM'  => [':PLAC:FORM', 'HEAD:PLAC'],
302302fdb8dSGreg Roach        'PLAC_NOTE'  => [':PLAC:NOTE'],
303c8183f29SGreg Roach        // Addresses
304302fdb8dSGreg Roach        'ADDR_EMAIL' => [':EMAIL'],
305302fdb8dSGreg Roach        'ADDR_PHON'  => [':PHON'],
306302fdb8dSGreg Roach        'ADDR_WWW'   => [':WWW'],
307c8183f29SGreg Roach        // Source citations
308c8183f29SGreg Roach        'SOUR_EVEN'  => [':SOUR:EVEN'],
309c8183f29SGreg Roach        'SOUR_DATE'  => [':SOUR:DATA:DATE'],
310c8183f29SGreg Roach        'SOUR_NOTE'  => [':SOUR:NOTE'],
311c8183f29SGreg Roach        'SOUR_QUAY'  => [':SOUR:QUAY'],
312c8183f29SGreg Roach        // Sources
31340c249dcSGreg Roach        'SOUR_DATA'  => ['SOUR:DATA:EVEN', 'SOUR:DATA:AGNC', 'SOUR:DATA:NOTE'],
314c8183f29SGreg Roach        // Individuals
315c8183f29SGreg Roach        'BIRT_FAMC'  => ['INDI:BIRT:FAMC'],
316c8183f29SGreg Roach        'RELI'       => ['INDI:RELI'],
317c8183f29SGreg Roach        'BAPM'       => ['INDI:BAPM'],
318c8183f29SGreg Roach        'CHR'        => ['INDI:CHR', 'INDI:CHRA'],
319c8183f29SGreg Roach        'FCOM'       => ['INDI:FCOM', 'INDI:CONF'],
320c8183f29SGreg Roach        'ORDN'       => ['INDI:ORDN'],
321c8183f29SGreg Roach        'BARM'       => ['INDI:BARM', 'INDI:BASM'],
322c8183f29SGreg Roach        'ALIA'       => ['INDI:ALIA'],
323c8183f29SGreg Roach        'ASSO'       => ['INDI:ASSO'],
324c8183f29SGreg Roach        // Families
325c8183f29SGreg Roach        'ENGA'       => ['FAM:ENGA'],
326c8183f29SGreg Roach        'MARB'       => ['FAM:MARB'],
327c8183f29SGreg Roach        'MARC'       => ['FAM:MARC'],
328c8183f29SGreg Roach        'MARL'       => ['FAM:MARL'],
329c8183f29SGreg Roach        'MARS'       => ['FAM:MARS'],
330c8183f29SGreg Roach        'ANUL'       => ['FAM:ANUL'],
331c8183f29SGreg Roach        'DIVF'       => ['FAM:DIVF'],
332c8183f29SGreg Roach        'FAM_RESI'   => ['FAM:RESI'],
333c8183f29SGreg Roach        'FAM_CENS'   => ['FAM:CENS'],
334c8183f29SGreg Roach        // LDS church
335c8183f29SGreg Roach        'LDS'        => ['INDI:BAPL', 'INDI:CONL', 'INDI:ENDL', 'INDI:SLGC', 'FAM:SLGS', 'HEAD:SUBN'],
336c8183f29SGreg Roach        // Identifiers
337c8183f29SGreg Roach        'AFN'        => ['INDI:AFN'],
338c8183f29SGreg Roach        'IDNO'       => ['INDI:IDNO'],
339c8183f29SGreg Roach        'SSN'        => ['INDI:SSN'],
340302fdb8dSGreg Roach        'RFN'        => [':RFN'],
341302fdb8dSGreg Roach        'REFN'       => [':REFN'],
342302fdb8dSGreg Roach        'RIN'        => [':RIN'],
343c8183f29SGreg Roach        // Submitters
344c8183f29SGreg Roach        'SUBM'       => ['INDI:SUBM', 'FAM:SUBM'],
345c8183f29SGreg Roach        'ANCI'       => ['INDI:ANCI', 'INDI:DESI'],
346c8183f29SGreg Roach    ];
34700c92694SGreg Roach
34800c92694SGreg Roach    // Custom GEDCOM tags that can be created in webtrees.
34900c92694SGreg Roach    public const CUSTOM_FAMILY_TAGS = [
35038f085bcSGreg Roach        'FACT',
35100c92694SGreg Roach        '_COML',
35200c92694SGreg Roach        '_MARI',
35300c92694SGreg Roach        '_MBON',
35400c92694SGreg Roach        '_NMR',
35500c92694SGreg Roach        '_SEPR',
35600c92694SGreg Roach    ];
35700c92694SGreg Roach
35800c92694SGreg Roach    public const CUSTOM_INDIVIDUAL_TAGS = [
35900c92694SGreg Roach        '_BRTM',
36000c92694SGreg Roach        '_CIRC',
36100c92694SGreg Roach        '_DEG',
36200c92694SGreg Roach        '_DNA',
36300c92694SGreg Roach        '_EXCM',
36400c92694SGreg Roach        '_EYEC',
36500c92694SGreg Roach        '_FNRL',
36600c92694SGreg Roach        '_FSFTID',
36700c92694SGreg Roach        '_HAIR',
36800c92694SGreg Roach        '_HEIG',
36900c92694SGreg Roach        '_INTE',
37000c92694SGreg Roach        '_MDCL',
37100c92694SGreg Roach        '_MEDC',
37200c92694SGreg Roach        '_MILI',
37300c92694SGreg Roach        '_MILT',
37400c92694SGreg Roach        '_NAMS',
375a49c80d4SGreg Roach        '_NMAR',
37600c92694SGreg Roach        '_PRMN',
37700c92694SGreg Roach        '_WEIG',
37800c92694SGreg Roach        '_YART',
37900c92694SGreg Roach    ];
38000c92694SGreg Roach
381356588a1SGreg Roach    // Some applications create GEDCOM files containing records without XREFS.
382356588a1SGreg Roach    // We cannot process these.
383356588a1SGreg Roach    public const CUSTOM_RECORDS_WITHOUT_XREFS = [
384356588a1SGreg Roach        'EMOTIONALRELATIONSHIP', // GenoPro
385356588a1SGreg Roach        'GENOMAP', // GenoPro
386356588a1SGreg Roach        'GLOBAL', // GenoPro
387356588a1SGreg Roach        'LABEL', // GenoPro
388356588a1SGreg Roach        'PEDIGREELINK', // GenoPro
389356588a1SGreg Roach        'SOCIALRELATIONSHIP', // GenoPro
390356588a1SGreg Roach        '_EVDEF', // RootsMagic
391356588a1SGreg Roach        '_EVENT_DEFN', // PAF and Legacy
392356588a1SGreg Roach        '_HASHTAG_DEFN', // Legacy
39354671e98SGreg Roach        '_PUBLISH', // MyHeritage
3940e542193SGreg Roach        '_TASK', // Ages
395356588a1SGreg Roach        '_TODO', // Legacy
396356588a1SGreg Roach    ];
397356588a1SGreg Roach
39800c92694SGreg Roach    /**
39900c92694SGreg Roach     * Definitions for GEDCOM 5.5.1.
40000c92694SGreg Roach     *
40100c92694SGreg Roach     * @return array<string,ElementInterface>
40200c92694SGreg Roach     */
40300c92694SGreg Roach    private function gedcom551Tags(): array
40400c92694SGreg Roach    {
40500c92694SGreg Roach        return [
40600c92694SGreg Roach            'FAM'                        => new FamilyRecord(I18N::translate('Family')),
40700c92694SGreg Roach            'FAM:*:ADDR'                 => new AddressLine(I18N::translate('Address')),
40800c92694SGreg Roach            'FAM:*:ADDR:ADR1'            => new AddressLine1(I18N::translate('Address line 1')),
40900c92694SGreg Roach            'FAM:*:ADDR:ADR2'            => new AddressLine2(I18N::translate('Address line 2')),
41000c92694SGreg Roach            'FAM:*:ADDR:ADR3'            => new AddressLine3(I18N::translate('Address line 3')),
41100c92694SGreg Roach            'FAM:*:ADDR:CITY'            => new AddressCity(I18N::translate('City')),
41200c92694SGreg Roach            'FAM:*:ADDR:CTRY'            => new AddressCountry(I18N::translate('Country')),
41300c92694SGreg Roach            'FAM:*:ADDR:POST'            => new AddressPostalCode(I18N::translate('Postal code')),
41400c92694SGreg Roach            'FAM:*:ADDR:STAE'            => new AddressState(I18N::translate('State')),
41500c92694SGreg Roach            'FAM:*:AGNC'                 => new ResponsibleAgency(I18N::translate('Agency')),
41600c92694SGreg Roach            'FAM:*:CAUS'                 => new CauseOfEvent(I18N::translate('Cause')),
41700c92694SGreg Roach            'FAM:*:DATE'                 => new DateValue(I18N::translate('Date')),
41800c92694SGreg Roach            'FAM:*:EMAIL'                => new AddressEmail(I18N::translate('Email address')),
41900c92694SGreg Roach            'FAM:*:FAX'                  => new AddressFax(I18N::translate('Fax')),
42000c92694SGreg Roach            'FAM:*:HUSB'                 => new EmptyElement(I18N::translate('Husband'), ['AGE' => '0:1']),
42100c92694SGreg Roach            'FAM:*:HUSB:AGE'             => new AgeAtEvent(I18N::translate('Husband’s age')),
42200c92694SGreg Roach            'FAM:*:NOTE'                 => new NoteStructure(I18N::translate('Note')),
42300c92694SGreg Roach            'FAM:*:OBJE'                 => new XrefMedia(I18N::translate('Media object')),
42400c92694SGreg Roach            'FAM:*:PHON'                 => new PhoneNumber(I18N::translate('Phone')),
42500c92694SGreg Roach            'FAM:*:PLAC'                 => new PlaceName(I18N::translate('Place')),
42600c92694SGreg Roach            'FAM:*:PLAC:FONE'            => new PlacePhoneticVariation(I18N::translate('Phonetic place')),
42700c92694SGreg Roach            'FAM:*:PLAC:FONE:TYPE'       => new PhoneticType(I18N::translate('Type')),
42800c92694SGreg Roach            'FAM:*:PLAC:FORM'            => new PlaceHierarchy(I18N::translate('Format')),
42900c92694SGreg Roach            'FAM:*:PLAC:MAP'             => new Coordinates(I18N::translate('Coordinates')),
43000c92694SGreg Roach            'FAM:*:PLAC:MAP:LATI'        => new PlaceLatitude(I18N::translate('Latitude')),
43100c92694SGreg Roach            'FAM:*:PLAC:MAP:LONG'        => new PlaceLongtitude(I18N::translate('Longitude')),
43200c92694SGreg Roach            'FAM:*:PLAC:NOTE'            => new NoteStructure(I18N::translate('Note')),
43300c92694SGreg Roach            'FAM:*:PLAC:ROMN'            => new PlaceRomanizedVariation(I18N::translate('Romanized place')),
43400c92694SGreg Roach            'FAM:*:PLAC:ROMN:TYPE'       => new RomanizedType(I18N::translate('Type')),
43500c92694SGreg Roach            'FAM:*:RELI'                 => new ReligiousAffiliation(I18N::translate('Religion'), []),
43600c92694SGreg Roach            'FAM:*:RESN'                 => new RestrictionNotice(I18N::translate('Restriction')),
43700c92694SGreg Roach            'FAM:*:SOUR'                 => new XrefSource(I18N::translate('Source citation')),
43800c92694SGreg Roach            'FAM:*:SOUR:DATA'            => new SourceData(I18N::translate('Data')),
439352bd396SGreg Roach            'FAM:*:SOUR:DATA:DATE'       => new DateValue(I18N::translate('Date of entry in original source')),
44000c92694SGreg Roach            'FAM:*:SOUR:DATA:TEXT'       => new TextFromSource(I18N::translate('Text')),
44100c92694SGreg Roach            'FAM:*:SOUR:EVEN'            => new EventTypeCitedFrom(I18N::translate('Event')),
44200c92694SGreg Roach            'FAM:*:SOUR:EVEN:ROLE'       => new RoleInEvent(I18N::translate('Role')),
44300c92694SGreg Roach            'FAM:*:SOUR:NOTE'            => new NoteStructure(I18N::translate('Note')),
44400c92694SGreg Roach            'FAM:*:SOUR:OBJE'            => new XrefMedia(I18N::translate('Media object')),
44500c92694SGreg Roach            'FAM:*:SOUR:PAGE'            => new WhereWithinSource(I18N::translate('Citation details')),
44600c92694SGreg Roach            'FAM:*:SOUR:QUAY'            => new CertaintyAssessment(I18N::translate('Quality of data')),
44700c92694SGreg Roach            'FAM:*:TYPE'                 => new EventOrFactClassification(I18N::translate('Type')),
44800c92694SGreg Roach            'FAM:*:WIFE'                 => new EmptyElement(I18N::translate('Wife'), ['AGE' => '0:1']),
44900c92694SGreg Roach            'FAM:*:WIFE:AGE'             => new AgeAtEvent(I18N::translate('Wife’s age')),
45000c92694SGreg Roach            'FAM:*:WWW'                  => new AddressWebPage(I18N::translate('URL')),
45100c92694SGreg Roach            'FAM:ANUL'                   => new Annulment(I18N::translate('Annulment')),
45200c92694SGreg Roach            'FAM:CENS'                   => new FamilyCensus(I18N::translate('Family census')),
45300c92694SGreg Roach            'FAM:CHAN'                   => new Change(I18N::translate('Last change')),
45400c92694SGreg Roach            'FAM:CHAN:DATE'              => new ChangeDate(I18N::translate('Date of last change')),
45500c92694SGreg Roach            'FAM:CHAN:DATE:TIME'         => new TimeValue(I18N::translate('Time of last change')),
45600c92694SGreg Roach            'FAM:CHIL'                   => new XrefIndividual(I18N::translate('Child')),
45700c92694SGreg Roach            'FAM:DIV'                    => new Divorce(I18N::translate('Divorce')),
45800c92694SGreg Roach            'FAM:DIV:DATE'               => new DateValue(I18N::translate('Date of divorce')),
45900c92694SGreg Roach            'FAM:DIVF'                   => new DivorceFiled(I18N::translate('Divorce filed')),
46000c92694SGreg Roach            'FAM:ENGA'                   => new Engagement(I18N::translate('Engagement')),
46100c92694SGreg Roach            'FAM:ENGA:DATE'              => new DateValue(I18N::translate('Date of engagement')),
46200c92694SGreg Roach            'FAM:ENGA:PLAC'              => new PlaceName(I18N::translate('Place of engagement')),
4635d2c6313SGreg Roach            'FAM:EVEN'                   => new FamilyEvent(I18N::translate('Event')),
4645d2c6313SGreg Roach            'FAM:EVEN:TYPE'              => new EventOrFactClassification(I18N::translate('Type of event')),
46500c92694SGreg Roach            'FAM:HUSB'                   => new XrefIndividual(I18N::translate('Husband')),
46600c92694SGreg Roach            'FAM:MARB'                   => new MarriageBanns(I18N::translate('Marriage banns')),
46700c92694SGreg Roach            'FAM:MARB:DATE'              => new DateValue(I18N::translate('Date of marriage banns')),
46800c92694SGreg Roach            'FAM:MARB:PLAC'              => new PlaceName(I18N::translate('Place of marriage banns')),
46900c92694SGreg Roach            'FAM:MARC'                   => new MarriageContract(I18N::translate('Marriage contract')),
47000c92694SGreg Roach            'FAM:MARL'                   => new MarriageLicence(I18N::translate('Marriage license')),
47100c92694SGreg Roach            'FAM:MARR'                   => new Marriage(I18N::translate('Marriage')),
47200c92694SGreg Roach            'FAM:MARR:DATE'              => new DateValue(I18N::translate('Date of marriage')),
47300c92694SGreg Roach            'FAM:MARR:PLAC'              => new PlaceName(I18N::translate('Place of marriage')),
47400c92694SGreg Roach            'FAM:MARR:TYPE'              => new MarriageType(I18N::translate('Type of marriage')),
47500c92694SGreg Roach            'FAM:MARS'                   => new MarriageSettlement(I18N::translate('Marriage settlement')),
47600c92694SGreg Roach            'FAM:NCHI'                   => new CountOfChildren(I18N::translate('Number of children')),
47700c92694SGreg Roach            'FAM:NOTE'                   => new NoteStructure(I18N::translate('Note')),
47800c92694SGreg Roach            'FAM:OBJE'                   => new XrefMedia(I18N::translate('Media object')),
47900c92694SGreg Roach            'FAM:REFN'                   => new UserReferenceNumber(I18N::translate('Reference number')),
48000c92694SGreg Roach            'FAM:REFN:TYPE'              => new UserReferenceType(I18N::translate('Type of reference number')),
48100c92694SGreg Roach            'FAM:RESI'                   => new FamilyResidence(I18N::translate('Family residence')),
48200c92694SGreg Roach            'FAM:RESN'                   => new RestrictionNotice(I18N::translate('Restriction')),
48300c92694SGreg Roach            'FAM:RIN'                    => new AutomatedRecordId(I18N::translate('Record ID number')),
48400c92694SGreg Roach            'FAM:SLGS'                   => new LdsSpouseSealing(I18N::translate('LDS spouse sealing')),
48500c92694SGreg Roach            'FAM:SLGS:DATE'              => new DateLdsOrd(I18N::translate('Date of LDS spouse sealing')),
48600c92694SGreg Roach            'FAM:SLGS:PLAC'              => new PlaceLivingOrdinance(I18N::translate('Place of LDS spouse sealing')),
48700c92694SGreg Roach            'FAM:SLGS:STAT'              => new LdsSpouseSealingDateStatus(I18N::translate('Status')),
48800c92694SGreg Roach            'FAM:SLGS:STAT:DATE'         => new ChangeDate(I18N::translate('Status change date')),
48900c92694SGreg Roach            'FAM:SLGS:TEMP'              => new TempleCode(I18N::translate('Temple')),
49000c92694SGreg Roach            'FAM:SOUR'                   => new XrefSource(I18N::translate('Source citation')),
49100c92694SGreg Roach            'FAM:SOUR:DATA'              => new SourceData(I18N::translate('Data')),
492352bd396SGreg Roach            'FAM:SOUR:DATA:DATE'         => new DateValue(I18N::translate('Date of entry in original source')),
49300c92694SGreg Roach            'FAM:SOUR:DATA:TEXT'         => new TextFromSource(I18N::translate('Text')),
49400c92694SGreg Roach            'FAM:SOUR:EVEN'              => new EventTypeCitedFrom(I18N::translate('Event')),
49500c92694SGreg Roach            'FAM:SOUR:EVEN:ROLE'         => new RoleInEvent(I18N::translate('Role')),
49600c92694SGreg Roach            'FAM:SOUR:NOTE'              => new NoteStructure(I18N::translate('Note')),
49700c92694SGreg Roach            'FAM:SOUR:OBJE'              => new XrefMedia(I18N::translate('Media object')),
49800c92694SGreg Roach            'FAM:SOUR:PAGE'              => new WhereWithinSource(I18N::translate('Citation details')),
49900c92694SGreg Roach            'FAM:SOUR:QUAY'              => new CertaintyAssessment(I18N::translate('Quality of data')),
50000c92694SGreg Roach            'FAM:SUBM'                   => new XrefSubmitter(I18N::translate('Submitter')),
50100c92694SGreg Roach            'FAM:WIFE'                   => new XrefIndividual(I18N::translate('Wife')),
50200c92694SGreg Roach            'HEAD'                       => new HeaderRecord(I18N::translate('Header')),
50300c92694SGreg Roach            'HEAD:CHAR'                  => new CharacterSet(I18N::translate('Character set')),
50400c92694SGreg Roach            'HEAD:CHAR:VERS'             => new VersionNumber(I18N::translate('Version')),
50500c92694SGreg Roach            'HEAD:COPR'                  => new CopyrightFile(I18N::translate('Copyright')),
50600c92694SGreg Roach            'HEAD:DATE'                  => new TransmissionDate(I18N::translate('Date')),
50700c92694SGreg Roach            'HEAD:DATE:TIME'             => new TimeValue(I18N::translate('Time')),
50800c92694SGreg Roach            'HEAD:DEST'                  => new ReceivingSystemName(I18N::translate('Destination')),
50900c92694SGreg Roach            'HEAD:FILE'                  => new FileName(I18N::translate('Filename')),
51000c92694SGreg Roach            'HEAD:GEDC'                  => new GedcomElement(I18N::translate('GEDCOM')),
51100c92694SGreg Roach            'HEAD:GEDC:FORM'             => new Form(I18N::translate('Format')),
51200c92694SGreg Roach            'HEAD:GEDC:VERS'             => new VersionNumber(I18N::translate('Version')),
51300c92694SGreg Roach            'HEAD:LANG'                  => new LanguageId(I18N::translate('Language')),
51400c92694SGreg Roach            'HEAD:NOTE'                  => new ContentDescription(I18N::translate('Note')),
51500c92694SGreg Roach            'HEAD:PLAC'                  => new EmptyElement(I18N::translate('Place hierarchy'), ['FORM' => '1:1']),
51600c92694SGreg Roach            'HEAD:PLAC:FORM'             => new PlaceHierarchy(I18N::translate('Format')),
5174c10b11dSGreg Roach            'HEAD:SOUR'                  => new ApprovedSystemId(I18N::translate('Application ID')),
51800c92694SGreg Roach            'HEAD:SOUR:CORP'             => new NameOfBusiness(I18N::translate('Corporation')),
51900c92694SGreg Roach            'HEAD:SOUR:CORP:ADDR'        => new AddressLine(I18N::translate('Address')),
52000c92694SGreg Roach            'HEAD:SOUR:CORP:ADDR:ADR1'   => new AddressLine1(I18N::translate('Address line 1')),
52100c92694SGreg Roach            'HEAD:SOUR:CORP:ADDR:ADR2'   => new AddressLine2(I18N::translate('Address line 2')),
52200c92694SGreg Roach            'HEAD:SOUR:CORP:ADDR:ADR3'   => new AddressLine3(I18N::translate('Address line 3')),
52300c92694SGreg Roach            'HEAD:SOUR:CORP:ADDR:CITY'   => new AddressCity(I18N::translate('City')),
52400c92694SGreg Roach            'HEAD:SOUR:CORP:ADDR:CTRY'   => new AddressCountry(I18N::translate('Country')),
52500c92694SGreg Roach            'HEAD:SOUR:CORP:ADDR:POST'   => new AddressPostalCode(I18N::translate('Postal code')),
52600c92694SGreg Roach            'HEAD:SOUR:CORP:ADDR:STAE'   => new AddressState(I18N::translate('State')),
52700c92694SGreg Roach            'HEAD:SOUR:CORP:EMAIL'       => new AddressEmail(I18N::translate('Email address')),
52800c92694SGreg Roach            'HEAD:SOUR:CORP:FAX'         => new AddressFax(I18N::translate('Fax')),
52900c92694SGreg Roach            'HEAD:SOUR:CORP:PHON'        => new PhoneNumber(I18N::translate('Phone')),
53000c92694SGreg Roach            'HEAD:SOUR:CORP:WWW'         => new AddressWebPage(I18N::translate('URL')),
5314c10b11dSGreg Roach            'HEAD:SOUR:DATA'             => new NameOfSourceData(I18N::translate('Data')),
53200c92694SGreg Roach            'HEAD:SOUR:DATA:COPR'        => new CopyrightSourceData(I18N::translate('Copyright')),
53300c92694SGreg Roach            'HEAD:SOUR:DATA:DATE'        => new PublicationDate(I18N::translate('Date')),
5344c10b11dSGreg Roach            'HEAD:SOUR:NAME'             => new NameOfProduct(I18N::translate('Application name')),
53500c92694SGreg Roach            'HEAD:SOUR:VERS'             => new VersionNumber(I18N::translate('Version')),
53600c92694SGreg Roach            'HEAD:SUBM'                  => new XrefSubmitter(I18N::translate('Submitter')),
53700c92694SGreg Roach            'HEAD:SUBN'                  => new XrefSubmission(I18N::translate('Submission')),
53800c92694SGreg Roach            'INDI'                       => new IndividualRecord(I18N::translate('Individual')),
53900c92694SGreg Roach            'INDI:*:ADDR'                => new AddressLine(I18N::translate('Address')),
54000c92694SGreg Roach            'INDI:*:ADDR:ADR1'           => new AddressLine1(I18N::translate('Address line 1')),
54100c92694SGreg Roach            'INDI:*:ADDR:ADR2'           => new AddressLine2(I18N::translate('Address line 2')),
54200c92694SGreg Roach            'INDI:*:ADDR:ADR3'           => new AddressLine3(I18N::translate('Address line 3')),
54300c92694SGreg Roach            'INDI:*:ADDR:CITY'           => new AddressCity(I18N::translate('City')),
54400c92694SGreg Roach            'INDI:*:ADDR:CTRY'           => new AddressCountry(I18N::translate('Country')),
54500c92694SGreg Roach            'INDI:*:ADDR:POST'           => new AddressPostalCode(I18N::translate('Postal code')),
54600c92694SGreg Roach            'INDI:*:ADDR:STAE'           => new AddressState(I18N::translate('State')),
54700c92694SGreg Roach            'INDI:*:AGE'                 => new AgeAtEvent(I18N::translate('Age')),
54800c92694SGreg Roach            'INDI:*:AGNC'                => new ResponsibleAgency(I18N::translate('Agency')),
54900c92694SGreg Roach            'INDI:*:CAUS'                => new CauseOfEvent(I18N::translate('Cause')),
55000c92694SGreg Roach            'INDI:*:DATE'                => new DateValue(I18N::translate('Date')),
55100c92694SGreg Roach            'INDI:*:EMAIL'               => new AddressEmail(I18N::translate('Email address')),
55200c92694SGreg Roach            'INDI:*:FAX'                 => new AddressFax(I18N::translate('Fax')),
55300c92694SGreg Roach            'INDI:*:NOTE'                => new NoteStructure(I18N::translate('Note')),
55400c92694SGreg Roach            'INDI:*:OBJE'                => new XrefMedia(I18N::translate('Media object')),
55500c92694SGreg Roach            'INDI:*:PHON'                => new PhoneNumber(I18N::translate('Phone')),
55600c92694SGreg Roach            'INDI:*:PLAC'                => new PlaceName(I18N::translate('Place')),
55700c92694SGreg Roach            'INDI:*:PLAC:FONE'           => new PlacePhoneticVariation(I18N::translate('Phonetic place')),
55800c92694SGreg Roach            'INDI:*:PLAC:FONE:TYPE'      => new PhoneticType(I18N::translate('Type')),
55900c92694SGreg Roach            'INDI:*:PLAC:FORM'           => new PlaceHierarchy(I18N::translate('Format')),
56000c92694SGreg Roach            'INDI:*:PLAC:MAP'            => new Coordinates(I18N::translate('Coordinates')),
56100c92694SGreg Roach            'INDI:*:PLAC:MAP:LATI'       => new PlaceLatitude(I18N::translate('Latitude')),
56200c92694SGreg Roach            'INDI:*:PLAC:MAP:LONG'       => new PlaceLongtitude(I18N::translate('Longitude')),
56300c92694SGreg Roach            'INDI:*:PLAC:NOTE'           => new NoteStructure(I18N::translate('Note')),
56400c92694SGreg Roach            'INDI:*:PLAC:ROMN'           => new PlaceRomanizedVariation(I18N::translate('Romanized place')),
56500c92694SGreg Roach            'INDI:*:PLAC:ROMN:TYPE'      => new RomanizedType(I18N::translate('Type')),
56600c92694SGreg Roach            'INDI:*:RELI'                => new ReligiousAffiliation(I18N::translate('Religion'), []),
56700c92694SGreg Roach            'INDI:*:RESN'                => new RestrictionNotice(I18N::translate('Restriction')),
56800c92694SGreg Roach            'INDI:*:SOUR'                => new XrefSource(I18N::translate('Source citation')),
56900c92694SGreg Roach            'INDI:*:SOUR:DATA'           => new SourceData(I18N::translate('Data')),
570352bd396SGreg Roach            'INDI:*:SOUR:DATA:DATE'      => new DateValue(I18N::translate('Date of entry in original source')),
57100c92694SGreg Roach            'INDI:*:SOUR:DATA:TEXT'      => new TextFromSource(I18N::translate('Text')),
57200c92694SGreg Roach            'INDI:*:SOUR:EVEN'           => new EventTypeCitedFrom(I18N::translate('Event')),
57300c92694SGreg Roach            'INDI:*:SOUR:EVEN:ROLE'      => new RoleInEvent(I18N::translate('Role')),
57400c92694SGreg Roach            'INDI:*:SOUR:NOTE'           => new NoteStructure(I18N::translate('Note')),
57500c92694SGreg Roach            'INDI:*:SOUR:OBJE'           => new XrefMedia(I18N::translate('Media object')),
57600c92694SGreg Roach            'INDI:*:SOUR:PAGE'           => new WhereWithinSource(I18N::translate('Citation details')),
57700c92694SGreg Roach            'INDI:*:SOUR:QUAY'           => new CertaintyAssessment(I18N::translate('Quality of data')),
57800c92694SGreg Roach            'INDI:*:TYPE'                => new EventOrFactClassification(I18N::translate('Type')),
57900c92694SGreg Roach            'INDI:*:WWW'                 => new AddressWebPage(I18N::translate('URL')),
58000c92694SGreg Roach            'INDI:ADOP'                  => new Adoption(I18N::translate('Adoption')),
58100c92694SGreg Roach            'INDI:ADOP:DATE'             => new DateValue(I18N::translate('Date of adoption')),
58200c92694SGreg Roach            'INDI:ADOP:FAMC'             => new XrefFamily(I18N::translate('Adoptive parents')),
58300c92694SGreg Roach            'INDI:ADOP:FAMC:ADOP'        => new AdoptedByWhichParent(I18N::translate('Adoption')),
58400c92694SGreg Roach            'INDI:ADOP:PLAC'             => new PlaceName(I18N::translate('Place of adoption')),
58500c92694SGreg Roach            'INDI:AFN'                   => new AncestralFileNumber(I18N::translate('Ancestral file number')),
58600c92694SGreg Roach            'INDI:ALIA'                  => new XrefIndividual(I18N::translate('Alias')),
58700c92694SGreg Roach            'INDI:ANCI'                  => new XrefSubmitter(I18N::translate('Ancestors interest')),
58800c92694SGreg Roach            'INDI:ASSO'                  => new XrefAssociate(I18N::translate('Associate')),
58900c92694SGreg Roach            'INDI:ASSO:RELA'             => new RelationIsDescriptor(I18N::translate('Relationship')),
59000c92694SGreg Roach            'INDI:BAPL'                  => new LdsBaptism(I18N::translate('LDS baptism')),
59100c92694SGreg Roach            'INDI:BAPL:DATE'             => new DateLdsOrd(I18N::translate('Date of LDS baptism')),
59200c92694SGreg Roach            'INDI:BAPL:PLAC'             => new PlaceLivingOrdinance(I18N::translate('Place of LDS baptism')),
59300c92694SGreg Roach            'INDI:BAPL:STAT'             => new LdsBaptismDateStatus(I18N::translate('Status')),
59400c92694SGreg Roach            'INDI:BAPL:STAT:DATE'        => new ChangeDate(I18N::translate('Status change date')),
59500c92694SGreg Roach            'INDI:BAPL:TEMP'             => new TempleCode(I18N::translate('Temple')),
59600c92694SGreg Roach            'INDI:BAPM'                  => new Baptism(I18N::translate('Baptism')),
59700c92694SGreg Roach            'INDI:BAPM:DATE'             => new DateValue(I18N::translate('Date of baptism')),
59800c92694SGreg Roach            'INDI:BAPM:PLAC'             => new PlaceName(I18N::translate('Place of baptism')),
59900c92694SGreg Roach            'INDI:BARM'                  => new BarMitzvah(I18N::translate('Bar mitzvah')),
60000c92694SGreg Roach            'INDI:BARM:DATE'             => new DateValue(I18N::translate('Date of bar mitzvah')),
60100c92694SGreg Roach            'INDI:BARM:PLAC'             => new PlaceName(I18N::translate('Place of bar mitzvah')),
60200c92694SGreg Roach            'INDI:BASM'                  => new BasMitzvah(I18N::translate('Bat mitzvah')),
60300c92694SGreg Roach            'INDI:BASM:DATE'             => new BasMitzvah(I18N::translate('Date of bat mitzvah')),
60400c92694SGreg Roach            'INDI:BASM:PLAC'             => new DateValue(I18N::translate('Place of bat mitzvah')),
60500c92694SGreg Roach            'INDI:BIRT'                  => new Birth(I18N::translate('Birth')),
60600c92694SGreg Roach            'INDI:BIRT:DATE'             => new DateValue(I18N::translate('Date of birth')),
60700c92694SGreg Roach            'INDI:BIRT:FAMC'             => new XrefFamily(I18N::translate('Birth parents')),
60800c92694SGreg Roach            'INDI:BIRT:PLAC'             => new PlaceName(I18N::translate('Place of birth')),
60900c92694SGreg Roach            'INDI:BLES'                  => new Blessing(I18N::translate('Blessing')),
61000c92694SGreg Roach            'INDI:BLES:DATE'             => new DateValue(I18N::translate('Date of blessing')),
61100c92694SGreg Roach            'INDI:BLES:PLAC'             => new PlaceName(I18N::translate('Place of blessing')),
61200c92694SGreg Roach            'INDI:BURI'                  => new Burial(I18N::translate('Burial')),
61300c92694SGreg Roach            'INDI:BURI:DATE'             => new DateValue(I18N::translate('Date of burial')),
61400c92694SGreg Roach            'INDI:BURI:PLAC'             => new PlaceName(I18N::translate('Place of burial')),
61500c92694SGreg Roach            'INDI:CAST'                  => new CasteName(I18N::translate('Caste')),
61600c92694SGreg Roach            'INDI:CENS'                  => new Census(I18N::translate('Census')),
61700c92694SGreg Roach            'INDI:CENS:DATE'             => new DateValue(I18N::translate('Census date')),
61800c92694SGreg Roach            'INDI:CENS:PLAC'             => new PlaceName(I18N::translate('Census place')),
61900c92694SGreg Roach            'INDI:CHAN'                  => new Change(I18N::translate('Last change')),
62000c92694SGreg Roach            'INDI:CHAN:DATE'             => new ChangeDate(I18N::translate('Date of last change')),
62100c92694SGreg Roach            'INDI:CHAN:DATE:TIME'        => new TimeValue(I18N::translate('Time of last change')),
62200c92694SGreg Roach            'INDI:CHR'                   => new Christening(I18N::translate('Christening')),
62300c92694SGreg Roach            'INDI:CHR:DATE'              => new DateValue(I18N::translate('Date of christening')),
62400c92694SGreg Roach            'INDI:CHR:FAMC'              => new XrefFamily(I18N::translate('Godparents')),
62500c92694SGreg Roach            'INDI:CHR:PLAC'              => new PlaceName(I18N::translate('Place of christening')),
62600c92694SGreg Roach            'INDI:CHRA'                  => new AdultChristening(I18N::translate('Adult christening')),
62700c92694SGreg Roach            'INDI:CHRA:PLAC'             => new PlaceName(I18N::translate('Place of christening')),
62800c92694SGreg Roach            'INDI:CONF'                  => new Confirmation(I18N::translate('Confirmation')),
62900c92694SGreg Roach            'INDI:CONF:DATE'             => new DateValue(I18N::translate('Date of confirmation')),
63000c92694SGreg Roach            'INDI:CONF:PLAC'             => new PlaceName(I18N::translate('Place of confirmation')),
63100c92694SGreg Roach            'INDI:CONL'                  => new LdsConfirmation(I18N::translate('LDS confirmation')),
63200c92694SGreg Roach            'INDI:CONL:DATE'             => new DateLdsOrd(I18N::translate('Date of LDS confirmation')),
63300c92694SGreg Roach            'INDI:CONL:PLAC'             => new PlaceLivingOrdinance(I18N::translate('Place of LDS confirmation')),
634701f5d18SGreg Roach            'INDI:CONL:STAT'             => new LdsBaptismDateStatus(I18N::translate('Status')),
63500c92694SGreg Roach            'INDI:CONL:STAT:DATE'        => new ChangeDate(I18N::translate('Status change date')),
63600c92694SGreg Roach            'INDI:CONL:TEMP'             => new TempleCode(I18N::translate('Temple')),
63700c92694SGreg Roach            'INDI:CREM'                  => new Cremation(I18N::translate('Cremation')),
63800c92694SGreg Roach            'INDI:CREM:DATE'             => new DateValue(I18N::translate('Date of cremation')),
63900c92694SGreg Roach            'INDI:CREM:PLAC'             => new PlaceName(I18N::translate('Place of cremation')),
64000c92694SGreg Roach            'INDI:DEAT'                  => new Death(I18N::translate('Death')),
64100c92694SGreg Roach            'INDI:DEAT:CAUS'             => new CauseOfEvent(I18N::translate('Cause of death')),
64200c92694SGreg Roach            'INDI:DEAT:DATE'             => new DateValue(I18N::translate('Date of death')),
64300c92694SGreg Roach            'INDI:DEAT:PLAC'             => new PlaceName(I18N::translate('Place of death')),
64400c92694SGreg Roach            'INDI:DESI'                  => new XrefSubmitter(I18N::translate('Descendants interest')),
64500c92694SGreg Roach            'INDI:DSCR'                  => new PhysicalDescription(I18N::translate('Description')),
64600c92694SGreg Roach            'INDI:EDUC'                  => new ScholasticAchievement(I18N::translate('Education')),
64700c92694SGreg Roach            'INDI:EDUC:AGNC'             => new ResponsibleAgency(I18N::translate('School or college')),
64800c92694SGreg Roach            'INDI:EMIG'                  => new Emigration(I18N::translate('Emigration')),
64900c92694SGreg Roach            'INDI:EMIG:DATE'             => new DateValue(I18N::translate('Date of emigration')),
65000c92694SGreg Roach            'INDI:EMIG:PLAC'             => new PlaceName(I18N::translate('Place of emigration')),
65100c92694SGreg Roach            'INDI:ENDL'                  => new LdsEndowment(I18N::translate('LDS endowment')),
65200c92694SGreg Roach            'INDI:ENDL:DATE'             => new DateLdsOrd(I18N::translate('Date of LDS endowment')),
65300c92694SGreg Roach            'INDI:ENDL:PLAC'             => new PlaceLivingOrdinance(I18N::translate('Place of LDS endowment')),
65400c92694SGreg Roach            'INDI:ENDL:STAT'             => new LdsEndowmentDateStatus(I18N::translate('Status')),
65500c92694SGreg Roach            'INDI:ENDL:STAT:DATE'        => new ChangeDate(I18N::translate('Status change date')),
65600c92694SGreg Roach            'INDI:ENDL:TEMP'             => new TempleCode(I18N::translate('Temple')),
6575d2c6313SGreg Roach            'INDI:EVEN'                  => new IndividualEvent(I18N::translate('Event')),
65800c92694SGreg Roach            'INDI:EVEN:DATE'             => new DateValue(I18N::translate('Date of event')),
65900c92694SGreg Roach            'INDI:EVEN:PLAC'             => new PlaceName(I18N::translate('Place of event')),
6605d2c6313SGreg Roach            'INDI:EVEN:TYPE'             => new EventOrFactClassification(I18N::translate('Type of event')),
6615d2c6313SGreg Roach            'INDI:FACT'                  => new IndividualFact(I18N::translate('Fact')),
6625d2c6313SGreg Roach            'INDI:FACT:TYPE'             => new EventOrFactClassification(I18N::translate('Type of fact')),
66300c92694SGreg Roach            'INDI:FAMC'                  => new XrefFamily(I18N::translate('Family as a child'), ['NOTE' => '0:1', 'PEDI' => '0:1', 'STAT' => '0:1']),
66400c92694SGreg Roach            'INDI:FAMC:PEDI'             => new PedigreeLinkageType(I18N::translate('Relationship to parents')),
66500c92694SGreg Roach            'INDI:FAMC:STAT'             => new ChildLinkageStatus(I18N::translate('Status')),
66600c92694SGreg Roach            'INDI:FAMS'                  => new XrefFamily(I18N::translate('Family as a spouse')),
66700c92694SGreg Roach            'INDI:FCOM'                  => new FirstCommunion(I18N::translate('First communion')),
66800c92694SGreg Roach            'INDI:FCOM:DATE'             => new DateValue(I18N::translate('Date of first communion')),
66900c92694SGreg Roach            'INDI:FCOM:PLAC'             => new PlaceName(I18N::translate('Place of first communion')),
67000c92694SGreg Roach            'INDI:GRAD'                  => new Graduation(I18N::translate('Graduation')),
67100c92694SGreg Roach            'INDI:GRAD:AGNC'             => new ResponsibleAgency(I18N::translate('School or college')),
67200c92694SGreg Roach            'INDI:IDNO'                  => new NationalIdNumber(I18N::translate('Identification number')),
6735d2c6313SGreg Roach            'INDI:IDNO:TYPE'             => new EventOrFactClassification(I18N::translate('Type of identification number')),
67400c92694SGreg Roach            'INDI:IMMI'                  => new Immigration(I18N::translate('Immigration')),
67500c92694SGreg Roach            'INDI:IMMI:DATE'             => new DateValue(I18N::translate('Date of immigration')),
67600c92694SGreg Roach            'INDI:IMMI:PLAC'             => new PlaceName(I18N::translate('Place of immigration')),
67700c92694SGreg Roach            'INDI:NAME'                  => new NamePersonal(I18N::translate('Name')),
67803c55594SGreg Roach            'INDI:NAME:*:SOUR'           => new XrefSource(I18N::translate('Source citation')),
67903c55594SGreg Roach            'INDI:NAME:*:SOUR:DATA'      => new SourceData(I18N::translate('Data')),
68003c55594SGreg Roach            'INDI:NAME:*:SOUR:DATA:DATE' => new DateValue(I18N::translate('Date of entry in original source')),
68103c55594SGreg Roach            'INDI:NAME:*:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')),
68203c55594SGreg Roach            'INDI:NAME:*:SOUR:EVEN'      => new EventTypeCitedFrom(I18N::translate('Event')),
68303c55594SGreg Roach            'INDI:NAME:*:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')),
68403c55594SGreg Roach            'INDI:NAME:*:SOUR:NOTE'      => new NoteStructure(I18N::translate('Note')),
68503c55594SGreg Roach            'INDI:NAME:*:SOUR:OBJE'      => new XrefMedia(I18N::translate('Media object')),
68603c55594SGreg Roach            'INDI:NAME:*:SOUR:PAGE'      => new WhereWithinSource(I18N::translate('Citation details')),
68703c55594SGreg Roach            'INDI:NAME:*:SOUR:QUAY'      => new CertaintyAssessment(I18N::translate('Quality of data')),
68800c92694SGreg Roach            'INDI:NAME:FONE'             => new NamePhoneticVariation(I18N::translate('Phonetic name')),
68900c92694SGreg Roach            'INDI:NAME:FONE:GIVN'        => new NamePieceGiven(I18N::translate('Given names')),
69000c92694SGreg Roach            'INDI:NAME:FONE:NICK'        => new NamePieceNickname(I18N::translate('Nickname')),
69103c55594SGreg Roach            'INDI:NAME:FONE:NOTE'        => new NoteStructure(I18N::translate('Note')),
69200c92694SGreg Roach            'INDI:NAME:FONE:NPFX'        => new NamePiecePrefix(I18N::translate('Name prefix')),
69300c92694SGreg Roach            'INDI:NAME:FONE:NSFX'        => new NamePieceSuffix(I18N::translate('Name suffix')),
69403c55594SGreg Roach            'INDI:NAME:FONE:SOUR'        => new XrefSource(I18N::translate('Source citation')),
69500c92694SGreg Roach            'INDI:NAME:FONE:SPFX'        => new NamePieceSurnamePrefix(I18N::translate('Surname prefix')),
69600c92694SGreg Roach            'INDI:NAME:FONE:SURN'        => new NamePieceSurname(I18N::translate('Surname')),
69700c92694SGreg Roach            'INDI:NAME:FONE:TYPE'        => new PhoneticType(I18N::translate('Phonetic type')),
69800c92694SGreg Roach            'INDI:NAME:GIVN'             => new NamePieceGiven(I18N::translate('Given names')),
69900c92694SGreg Roach            'INDI:NAME:NICK'             => new NamePieceNickname(I18N::translate('Nickname')),
70000c92694SGreg Roach            'INDI:NAME:NPFX'             => new NamePiecePrefix(I18N::translate('Name prefix')),
70100c92694SGreg Roach            'INDI:NAME:NSFX'             => new NamePieceSuffix(I18N::translate('Name suffix')),
70200c92694SGreg Roach            'INDI:NAME:ROMN'             => new NameRomanizedVariation(I18N::translate('Romanized name')),
70300c92694SGreg Roach            'INDI:NAME:ROMN:GIVN'        => new NamePieceGiven(I18N::translate('Given names')),
70400c92694SGreg Roach            'INDI:NAME:ROMN:NICK'        => new NamePieceNickname(I18N::translate('Nickname')),
70503c55594SGreg Roach            'INDI:NAME:ROMN:NOTE'        => new NoteStructure(I18N::translate('Note')),
70600c92694SGreg Roach            'INDI:NAME:ROMN:NPFX'        => new NamePiecePrefix(I18N::translate('Name prefix')),
70700c92694SGreg Roach            'INDI:NAME:ROMN:NSFX'        => new NamePieceSuffix(I18N::translate('Name suffix')),
70803c55594SGreg Roach            'INDI:NAME:ROMN:SOUR'        => new XrefSource(I18N::translate('Source citation')),
70900c92694SGreg Roach            'INDI:NAME:ROMN:SPFX'        => new NamePieceSurnamePrefix(I18N::translate('Surname prefix')),
71000c92694SGreg Roach            'INDI:NAME:ROMN:SURN'        => new NamePieceSurname(I18N::translate('Surname')),
71100c92694SGreg Roach            'INDI:NAME:ROMN:TYPE'        => new RomanizedType(I18N::translate('Romanized type')),
71200c92694SGreg Roach            'INDI:NAME:SPFX'             => new NamePieceSurnamePrefix(I18N::translate('Surname prefix')),
71300c92694SGreg Roach            'INDI:NAME:SURN'             => new NamePieceSurname(I18N::translate('Surname')),
71400c92694SGreg Roach            'INDI:NAME:TYPE'             => new NameType(I18N::translate('Type of name')),
715f15544dcSGreg Roach            'INDI:NATI'                  => new NationalOrTribalOrigin(I18N::translate('Nationality')),
71600c92694SGreg Roach            'INDI:NATU'                  => new Naturalization(I18N::translate('Naturalization')),
71700c92694SGreg Roach            'INDI:NATU:DATE'             => new DateValue(I18N::translate('Date of naturalization')),
71800c92694SGreg Roach            'INDI:NATU:PLAC'             => new PlaceName(I18N::translate('Place of naturalization')),
71900c92694SGreg Roach            'INDI:NCHI'                  => new CountOfChildren(I18N::translate('Number of children')),
72000c92694SGreg Roach            'INDI:NMR'                   => new CountOfMarriages(I18N::translate('Number of marriages')),
72100c92694SGreg Roach            'INDI:NOTE'                  => new NoteStructure(I18N::translate('Note')),
72200c92694SGreg Roach            'INDI:OBJE'                  => new XrefMedia(I18N::translate('Media object')),
72300c92694SGreg Roach            'INDI:OCCU'                  => new Occupation(I18N::translate('Occupation')),
72400c92694SGreg Roach            'INDI:OCCU:AGNC'             => new ResponsibleAgency(I18N::translate('Employer')),
72500c92694SGreg Roach            'INDI:ORDN'                  => new Ordination(I18N::translate('Ordination')),
72600c92694SGreg Roach            'INDI:ORDN:AGNC'             => new Ordination(I18N::translate('Religious institution')),
72700c92694SGreg Roach            'INDI:ORDN:DATE'             => new Ordination(I18N::translate('Date of ordination')),
72800c92694SGreg Roach            'INDI:ORDN:PLAC'             => new Ordination(I18N::translate('Place of ordination')),
72900c92694SGreg Roach            'INDI:PROB'                  => new Probate(I18N::translate('Probate')),
73000c92694SGreg Roach            'INDI:PROP'                  => new Possessions(I18N::translate('Property')),
73100c92694SGreg Roach            'INDI:REFN'                  => new UserReferenceNumber(I18N::translate('Reference number')),
73200c92694SGreg Roach            'INDI:REFN:TYPE'             => new UserReferenceType(I18N::translate('Type of reference number')),
73300c92694SGreg Roach            'INDI:RELI'                  => new ReligiousAffiliation(I18N::translate('Religion')),
73400c92694SGreg Roach            'INDI:RESI'                  => new Residence(I18N::translate('Residence')),
73500c92694SGreg Roach            'INDI:RESI:DATE'             => new DateValue(I18N::translate('Date of residence')),
73600c92694SGreg Roach            'INDI:RESI:PLAC'             => new PlaceName(I18N::translate('Place of residence')),
73700c92694SGreg Roach            'INDI:RESN'                  => new RestrictionNotice(I18N::translate('Restriction')),
73800c92694SGreg Roach            'INDI:RETI'                  => new Retirement(I18N::translate('Retirement')),
73900c92694SGreg Roach            'INDI:RETI:AGNC'             => new ResponsibleAgency(I18N::translate('Employer')),
74000c92694SGreg Roach            'INDI:RFN'                   => new PermanentRecordFileNumber(I18N::translate('Record file number')),
74100c92694SGreg Roach            'INDI:RIN'                   => new AutomatedRecordId(I18N::translate('Record ID number')),
74200c92694SGreg Roach            'INDI:SEX'                   => new SexValue(I18N::translate('Gender')),
74300c92694SGreg Roach            'INDI:SLGC'                  => new LdsChildSealing(I18N::translate('LDS child sealing')),
74400c92694SGreg Roach            'INDI:SLGC:DATE'             => new DateLdsOrd(I18N::translate('Date of LDS child sealing')),
74500c92694SGreg Roach            'INDI:SLGC:FAMC'             => new XrefFamily(I18N::translate('Parents')),
74600c92694SGreg Roach            'INDI:SLGC:PLAC'             => new PlaceLivingOrdinance(I18N::translate('Place of LDS child sealing')),
74700c92694SGreg Roach            'INDI:SLGC:STAT'             => new LdsChildSealingDateStatus(I18N::translate('Status')),
74800c92694SGreg Roach            'INDI:SLGC:STAT:DATE'        => new ChangeDate(I18N::translate('Status change date')),
74900c92694SGreg Roach            'INDI:SLGC:TEMP'             => new TempleCode(I18N::translate('Temple')),
75000c92694SGreg Roach            'INDI:SOUR'                  => new XrefSource(I18N::translate('Source citation')),
75100c92694SGreg Roach            'INDI:SOUR:DATA'             => new SourceData(I18N::translate('Data')),
752352bd396SGreg Roach            'INDI:SOUR:DATA:DATE'        => new DateValue(I18N::translate('Date of entry in original source')),
75300c92694SGreg Roach            'INDI:SOUR:DATA:TEXT'        => new TextFromSource(I18N::translate('Text')),
75400c92694SGreg Roach            'INDI:SOUR:EVEN'             => new EventTypeCitedFrom(I18N::translate('Event')),
75500c92694SGreg Roach            'INDI:SOUR:EVEN:ROLE'        => new RoleInEvent(I18N::translate('Role')),
75600c92694SGreg Roach            'INDI:SOUR:NOTE'             => new NoteStructure(I18N::translate('Note')),
75700c92694SGreg Roach            'INDI:SOUR:OBJE'             => new XrefMedia(I18N::translate('Media object')),
75800c92694SGreg Roach            'INDI:SOUR:PAGE'             => new WhereWithinSource(I18N::translate('Citation details')),
75900c92694SGreg Roach            'INDI:SOUR:QUAY'             => new CertaintyAssessment(I18N::translate('Quality of data')),
76000c92694SGreg Roach            'INDI:SSN'                   => new SocialSecurityNumber(I18N::translate('Social security number')),
76100c92694SGreg Roach            'INDI:SUBM'                  => new XrefSubmitter(I18N::translate('Submitter')),
76200c92694SGreg Roach            'INDI:TITL'                  => new NobilityTypeTitle(I18N::translate('Title')),
76300c92694SGreg Roach            'INDI:WILL'                  => new Will(I18N::translate('Will')),
76400c92694SGreg Roach            'NOTE'                       => new NoteRecord(I18N::translate('Shared note')),
76500c92694SGreg Roach            'NOTE:CHAN'                  => new Change(I18N::translate('Last change')),
76600c92694SGreg Roach            'NOTE:CHAN:DATE'             => new ChangeDate(I18N::translate('Date of last change')),
76700c92694SGreg Roach            'NOTE:CHAN:DATE:TIME'        => new TimeValue(I18N::translate('Time of last change')),
76800c92694SGreg Roach            'NOTE:CHAN:NOTE'             => new NoteStructure(I18N::translate('Note')),
76978c3bcf9SGreg Roach            'NOTE:CONC'                  => new SubmitterText(I18N::translate('Note')),
7706e233fa7SGreg Roach            'NOTE:CONT'                  => new SubmitterText(I18N::translate('Continuation')),
77100c92694SGreg Roach            'NOTE:REFN'                  => new UserReferenceNumber(I18N::translate('Reference number')),
77200c92694SGreg Roach            'NOTE:REFN:TYPE'             => new UserReferenceType(I18N::translate('Type of reference number')),
77300c92694SGreg Roach            'NOTE:RIN'                   => new AutomatedRecordId(I18N::translate('Record ID number')),
77400c92694SGreg Roach            'NOTE:SOUR'                  => new XrefSource(I18N::translate('Source citation')),
77500c92694SGreg Roach            'NOTE:SOUR:DATA'             => new SourceData(I18N::translate('Data')),
776352bd396SGreg Roach            'NOTE:SOUR:DATA:DATE'        => new DateValue(I18N::translate('Date of entry in original source')),
77700c92694SGreg Roach            'NOTE:SOUR:DATA:TEXT'        => new TextFromSource(I18N::translate('Text')),
77800c92694SGreg Roach            'NOTE:SOUR:EVEN'             => new EventTypeCitedFrom(I18N::translate('Event')),
77900c92694SGreg Roach            'NOTE:SOUR:EVEN:ROLE'        => new RoleInEvent(I18N::translate('Role')),
78000c92694SGreg Roach            'NOTE:SOUR:NOTE'             => new NoteStructure(I18N::translate('Note')),
78100c92694SGreg Roach            'NOTE:SOUR:OBJE'             => new XrefMedia(I18N::translate('Media object')),
78200c92694SGreg Roach            'NOTE:SOUR:PAGE'             => new WhereWithinSource(I18N::translate('Citation details')),
78300c92694SGreg Roach            'NOTE:SOUR:QUAY'             => new CertaintyAssessment(I18N::translate('Quality of data')),
78400c92694SGreg Roach            'OBJE'                       => new MediaRecord(I18N::translate('Media object')),
78500c92694SGreg Roach            'OBJE:BLOB'                  => new CustomElement(I18N::translate('Binary data object')),
78600c92694SGreg Roach            'OBJE:CHAN'                  => new Change(I18N::translate('Last change')),
78700c92694SGreg Roach            'OBJE:CHAN:DATE'             => new ChangeDate(I18N::translate('Date of last change')),
78800c92694SGreg Roach            'OBJE:CHAN:DATE:TIME'        => new TimeValue(I18N::translate('Time of last change')),
78900c92694SGreg Roach            'OBJE:CHAN:NOTE'             => new NoteStructure(I18N::translate('Note')),
79000c92694SGreg Roach            'OBJE:FILE'                  => new MultimediaFileReference(I18N::translate('Filename')),
79100c92694SGreg Roach            'OBJE:FILE:FORM'             => new MultimediaFormat(I18N::translate('Format')),
79200c92694SGreg Roach            'OBJE:FILE:FORM:TYPE'        => new SourceMediaType(I18N::translate('Media type')),
79300c92694SGreg Roach            'OBJE:FILE:TITL'             => new DescriptiveTitle(I18N::translate('Title')),
79400c92694SGreg Roach            'OBJE:NOTE'                  => new NoteStructure(I18N::translate('Note')),
79500c92694SGreg Roach            'OBJE:REFN'                  => new UserReferenceNumber(I18N::translate('Reference number')),
79600c92694SGreg Roach            'OBJE:REFN:TYPE'             => new UserReferenceType(I18N::translate('Type of reference number')),
79700c92694SGreg Roach            'OBJE:RIN'                   => new AutomatedRecordId(I18N::translate('Record ID number')),
79800c92694SGreg Roach            'OBJE:SOUR'                  => new XrefSource(I18N::translate('Source citation')),
79900c92694SGreg Roach            'OBJE:SOUR:DATA'             => new SourceData(I18N::translate('Data')),
800352bd396SGreg Roach            'OBJE:SOUR:DATA:DATE'        => new DateValue(I18N::translate('Date of entry in original source')),
80100c92694SGreg Roach            'OBJE:SOUR:DATA:TEXT'        => new TextFromSource(I18N::translate('Text')),
80200c92694SGreg Roach            'OBJE:SOUR:EVEN'             => new EventTypeCitedFrom(I18N::translate('Event')),
80300c92694SGreg Roach            'OBJE:SOUR:EVEN:ROLE'        => new RoleInEvent(I18N::translate('Role')),
80400c92694SGreg Roach            'OBJE:SOUR:NOTE'             => new NoteStructure(I18N::translate('Note')),
80500c92694SGreg Roach            'OBJE:SOUR:OBJE'             => new XrefMedia(I18N::translate('Media object')),
80600c92694SGreg Roach            'OBJE:SOUR:PAGE'             => new WhereWithinSource(I18N::translate('Citation details')),
80700c92694SGreg Roach            'OBJE:SOUR:QUAY'             => new CertaintyAssessment(I18N::translate('Quality of data')),
80800c92694SGreg Roach            'REPO'                       => new RepositoryRecord(I18N::translate('Repository')),
80900c92694SGreg Roach            'REPO:ADDR'                  => new AddressLine(I18N::translate('Address')),
81000c92694SGreg Roach            'REPO:ADDR:ADR1'             => new AddressLine1(I18N::translate('Address line 1')),
81100c92694SGreg Roach            'REPO:ADDR:ADR2'             => new AddressLine2(I18N::translate('Address line 2')),
81200c92694SGreg Roach            'REPO:ADDR:ADR3'             => new AddressLine3(I18N::translate('Address line 3')),
81300c92694SGreg Roach            'REPO:ADDR:CITY'             => new AddressCity(I18N::translate('City')),
81400c92694SGreg Roach            'REPO:ADDR:CTRY'             => new AddressCountry(I18N::translate('Country')),
81500c92694SGreg Roach            'REPO:ADDR:POST'             => new AddressPostalCode(I18N::translate('Postal code')),
81600c92694SGreg Roach            'REPO:ADDR:STAE'             => new AddressState(I18N::translate('State')),
81700c92694SGreg Roach            'REPO:CHAN'                  => new Change(I18N::translate('Last change')),
81800c92694SGreg Roach            'REPO:CHAN:DATE'             => new ChangeDate(I18N::translate('Date of last change')),
81900c92694SGreg Roach            'REPO:CHAN:DATE:TIME'        => new TimeValue(I18N::translate('Time of last change')),
82000c92694SGreg Roach            'REPO:CHAN:NOTE'             => new NoteStructure(I18N::translate('Note')),
82100c92694SGreg Roach            'REPO:EMAIL'                 => new AddressEmail(I18N::translate('Email address')),
82200c92694SGreg Roach            'REPO:FAX'                   => new AddressFax(I18N::translate('Fax')),
82300c92694SGreg Roach            'REPO:NAME'                  => new NameOfRepository(I18N::translateContext('Repository', 'Name')),
82400c92694SGreg Roach            'REPO:NOTE'                  => new NoteStructure(I18N::translate('Note')),
82500c92694SGreg Roach            'REPO:PHON'                  => new PhoneNumber(I18N::translate('Phone')),
82600c92694SGreg Roach            'REPO:REFN'                  => new UserReferenceNumber(I18N::translate('Reference number')),
82700c92694SGreg Roach            'REPO:REFN:TYPE'             => new UserReferenceType(I18N::translate('Type of reference number')),
82800c92694SGreg Roach            'REPO:RIN'                   => new AutomatedRecordId(I18N::translate('Record ID number')),
82900c92694SGreg Roach            'REPO:WWW'                   => new AddressWebPage(I18N::translate('URL')),
83000c92694SGreg Roach            'SOUR'                       => new SourceRecord(I18N::translate('Source')),
83100c92694SGreg Roach            'SOUR:ABBR'                  => new SourceFiledByEntry(I18N::translate('Abbreviation')),
83200c92694SGreg Roach            'SOUR:AUTH'                  => new SourceOriginator(I18N::translate('Author')),
83300c92694SGreg Roach            'SOUR:CHAN'                  => new Change(I18N::translate('Last change')),
83400c92694SGreg Roach            'SOUR:CHAN:DATE'             => new ChangeDate(I18N::translate('Date of last change')),
83500c92694SGreg Roach            'SOUR:CHAN:DATE:TIME'        => new TimeValue(I18N::translate('Time of last change')),
83600c92694SGreg Roach            'SOUR:CHAN:NOTE'             => new NoteStructure(I18N::translate('Note')),
83700c92694SGreg Roach            'SOUR:DATA'                  => new EmptyElement(I18N::translate('Data'), ['EVEN' => '0:M', 'AGNC' => '0:1', 'NOTE' => '0:M']),
83800c92694SGreg Roach            'SOUR:DATA:AGNC'             => new ResponsibleAgency(I18N::translate('Agency')),
83900c92694SGreg Roach            'SOUR:DATA:EVEN'             => new EventsRecorded(I18N::translate('Events')),
84000c92694SGreg Roach            'SOUR:DATA:EVEN:DATE'        => new DateValue(I18N::translate('Date range')),
84100c92694SGreg Roach            'SOUR:DATA:EVEN:PLAC'        => new SourceJurisdictionPlace(I18N::translate('Place'), []),
84200c92694SGreg Roach            'SOUR:DATA:NOTE'             => new NoteStructure(I18N::translate('Note')),
84300c92694SGreg Roach            'SOUR:NOTE'                  => new NoteStructure(I18N::translate('Note')),
84400c92694SGreg Roach            'SOUR:OBJE'                  => new XrefMedia(I18N::translate('Media object')),
84500c92694SGreg Roach            'SOUR:PUBL'                  => new SourcePublicationFacts(I18N::translate('Publication')),
84600c92694SGreg Roach            'SOUR:REFN'                  => new UserReferenceNumber(I18N::translate('Reference number')),
84700c92694SGreg Roach            'SOUR:REFN:TYPE'             => new UserReferenceType(I18N::translate('Type of reference number')),
84800c92694SGreg Roach            'SOUR:REPO'                  => new XrefRepository(I18N::translate('Repository')),
84900c92694SGreg Roach            'SOUR:REPO:CALN'             => new SourceCallNumber(I18N::translate('Call number')),
85000c92694SGreg Roach            'SOUR:REPO:CALN:MEDI'        => new SourceMediaType(I18N::translate('Media type')),
85100c92694SGreg Roach            'SOUR:REPO:NOTE'             => new NoteStructure(I18N::translate('Note')),
85200c92694SGreg Roach            'SOUR:RIN'                   => new AutomatedRecordId(I18N::translate('Record ID number')),
85300c92694SGreg Roach            'SOUR:TEXT'                  => new TextFromSource(I18N::translate('Text')),
85400c92694SGreg Roach            'SOUR:TITL'                  => new DescriptiveTitle(I18N::translate('Title')),
85500c92694SGreg Roach            'SUBM'                       => new SubmitterRecord(I18N::translate('Submitter')),
85600c92694SGreg Roach            'SUBM:ADDR'                  => new AddressLine(I18N::translate('Address')),
85700c92694SGreg Roach            'SUBM:ADDR:ADR1'             => new AddressLine1(I18N::translate('Address line 1')),
85800c92694SGreg Roach            'SUBM:ADDR:ADR2'             => new AddressLine2(I18N::translate('Address line 2')),
85900c92694SGreg Roach            'SUBM:ADDR:ADR3'             => new AddressLine3(I18N::translate('Address line 3')),
86000c92694SGreg Roach            'SUBM:ADDR:CITY'             => new AddressCity(I18N::translate('City')),
86100c92694SGreg Roach            'SUBM:ADDR:CTRY'             => new AddressCountry(I18N::translate('Country')),
86200c92694SGreg Roach            'SUBM:ADDR:POST'             => new AddressPostalCode(I18N::translate('Postal code')),
86300c92694SGreg Roach            'SUBM:ADDR:STAE'             => new AddressState(I18N::translate('State')),
86400c92694SGreg Roach            'SUBM:CHAN'                  => new Change(I18N::translate('Last change')),
86500c92694SGreg Roach            'SUBM:CHAN:DATE'             => new ChangeDate(I18N::translate('Date of last change')),
86600c92694SGreg Roach            'SUBM:CHAN:DATE:TIME'        => new TimeValue(I18N::translate('Time of last change')),
86700c92694SGreg Roach            'SUBM:CHAN:NOTE'             => new NoteStructure(I18N::translate('Note')),
86800c92694SGreg Roach            'SUBM:EMAIL'                 => new AddressEmail(I18N::translate('Email address')),
86900c92694SGreg Roach            'SUBM:FAX'                   => new AddressFax(I18N::translate('Fax')),
87000c92694SGreg Roach            'SUBM:LANG'                  => new LanguageId(I18N::translate('Language')),
87100c92694SGreg Roach            'SUBM:NAME'                  => new SubmitterName(I18N::translate('Name')),
87200c92694SGreg Roach            'SUBM:NOTE'                  => new NoteStructure(I18N::translate('Note')),
87300c92694SGreg Roach            'SUBM:OBJE'                  => new XrefMedia(I18N::translate('Media object')),
87400c92694SGreg Roach            'SUBM:PHON'                  => new PhoneNumber(I18N::translate('Phone')),
87500c92694SGreg Roach            'SUBM:RFN'                   => new SubmitterRegisteredRfn(I18N::translate('Record file number')),
87600c92694SGreg Roach            'SUBM:RIN'                   => new AutomatedRecordId(I18N::translate('Record ID number')),
87700c92694SGreg Roach            'SUBM:WWW'                   => new AddressWebPage(I18N::translate('URL')),
87800c92694SGreg Roach            'SUBN'                       => new SubmissionRecord(I18N::translate('Submission')),
87900c92694SGreg Roach            'SUBN:ANCE'                  => new GenerationsOfAncestors(I18N::translate('Generations of ancestors')),
88000c92694SGreg Roach            'SUBN:CHAN'                  => new Change(I18N::translate('Last change')),
88100c92694SGreg Roach            'SUBN:CHAN:DATE'             => new ChangeDate(I18N::translate('Date of last change')),
88200c92694SGreg Roach            'SUBN:CHAN:DATE:TIME'        => new TimeValue(I18N::translate('Time of last change')),
88300c92694SGreg Roach            'SUBN:CHAN:NOTE'             => new NoteStructure(I18N::translate('Note')),
88400c92694SGreg Roach            'SUBN:DESC'                  => new GenerationsOfDescendants(I18N::translate('Generations of descendants')),
88500c92694SGreg Roach            'SUBN:FAMF'                  => new NameOfFamilyFile(I18N::translate('Family file')),
88600c92694SGreg Roach            'SUBN:NOTE'                  => new NoteStructure(I18N::translate('Note')),
88700c92694SGreg Roach            'SUBN:ORDI'                  => new OrdinanceProcessFlag(I18N::translate('Ordinance')),
88800c92694SGreg Roach            'SUBN:RIN'                   => new AutomatedRecordId(I18N::translate('Record ID number')),
88900c92694SGreg Roach            'SUBN:SUBM'                  => new XrefSubmitter(I18N::translate('Submitter')),
89000c92694SGreg Roach            'SUBN:TEMP'                  => new TempleCode(/* I18N: https://en.wikipedia.org/wiki/Temple_(LDS_Church)*/ I18N::translate('Temple')),
89100c92694SGreg Roach            'TRLR'                       => new EmptyElement(I18N::translate('Trailer')),
89200c92694SGreg Roach        ];
89300c92694SGreg Roach    }
89400c92694SGreg Roach
89500c92694SGreg Roach    /**
896701f5d18SGreg Roach     * Definitions for GEDCOM 7.
897701f5d18SGreg Roach     *
898701f5d18SGreg Roach     * @return array<string,ElementInterface>
899701f5d18SGreg Roach     */
900701f5d18SGreg Roach    private function gedcom7Tags(): array
901701f5d18SGreg Roach    {
902701f5d18SGreg Roach        return [
903701f5d18SGreg Roach            'FAM:NO' => new NonEvent('Event did not happen'),
904701f5d18SGreg Roach            'INDI:NO' => new NonEvent('Event did not happen'),
905701f5d18SGreg Roach            'FAM:*:ASSO'                 => new XrefAssociate(I18N::translate('Associate')),
906701f5d18SGreg Roach            'FAM:*:ASSO:PHRASE'          => new CustomElement(I18N::translate('Phrase')),
907701f5d18SGreg Roach            'FAM:*:ASSO:ROLE'            => new RoleInEvent(I18N::translate('Role')),
908701f5d18SGreg Roach            'FAM:*:ASSO:ROLE:PHRASE'     => new CustomElement(I18N::translate('Phrase')),
909701f5d18SGreg Roach            'FAM:*:DATE:TIME'            => new TimeValue(I18N::translate('Time')),
910701f5d18SGreg Roach            'FAM:*:PLAC:EXID'            => new ExternalIdentifier(I18N::translate('External identifier')),
911701f5d18SGreg Roach            'FAM:*:PLAC:EXID:TYPE'       => new ExternalIdentifierType(I18N::translate('Type')),
912701f5d18SGreg Roach            'FAM:*:SDATE'                => new CustomElement(I18N::translate('Sort date')),
913701f5d18SGreg Roach            'FAM:*:SDATE:PHRASE'         => new CustomElement(I18N::translate('Phrase')),
914701f5d18SGreg Roach            'FAM:*:SDATE:TIME'           => new CustomElement(I18N::translate('Sort time')),
915701f5d18SGreg Roach            'FAM:*:SNOTE'                => new XrefSharedNote(I18N::translate('Shared note')),
916701f5d18SGreg Roach            'FAM:*:UID'                  => new Uid(I18N::translate('Unique identifier')),
917701f5d18SGreg Roach            'FAM:ASSO'                   => new XrefAssociate(I18N::translate('Associate')),
918701f5d18SGreg Roach            'FAM:ASSO:PHRASE'            => new CustomElement(I18N::translate('Phrase')),
919701f5d18SGreg Roach            'FAM:ASSO:ROLE'              => new RoleInEvent(I18N::translate('Role')),
920701f5d18SGreg Roach            'FAM:ASSO:ROLE:PHRASE'       => new CustomElement(I18N::translate('Phrase')),
921701f5d18SGreg Roach            'FAM:CREA'                   => new Creation(I18N::translate('Created at')),
922701f5d18SGreg Roach            'FAM:CREA:DATE'              => new DateValue(I18N::translate('Creation date')),
923701f5d18SGreg Roach            'FAM:CREA:DATE:TIME'         => new TimeValue(I18N::translate('Creation time')),
924701f5d18SGreg Roach            'FAM:EXID'                   => new ExternalIdentifier(I18N::translate('External identifier')),
925701f5d18SGreg Roach            'FAM:EXID:TYPE'              => new ExternalIdentifierType(I18N::translate('Type')),
9265d2c6313SGreg Roach            'FAM:FACT'                   => new FamilyFact(I18N::translate('Fact')),
927701f5d18SGreg Roach            'FAM:REFN'                   => new UserReferenceNumber(I18N::translate('Reference number')),
928701f5d18SGreg Roach            'FAM:REFN:TYPE'              => new UserReferenceType(I18N::translate('Type')),
929701f5d18SGreg Roach            'FAM:SNOTE'                  => new XrefSharedNote(I18N::translate('Shared note')),
930701f5d18SGreg Roach            'FAM:UID'                    => new Uid(I18N::translate('Unique identifier')),
931701f5d18SGreg Roach            'INDI:*:ASSO'                => new XrefAssociate(I18N::translate('Associate')),
932701f5d18SGreg Roach            'INDI:*:ASSO:PHRASE'         => new CustomElement(I18N::translate('Phrase')),
933701f5d18SGreg Roach            'INDI:*:ASSO:ROLE'           => new RoleInEvent(I18N::translate('Role')),
934701f5d18SGreg Roach            'INDI:*:ASSO:ROLE:PHRASE'    => new CustomElement(I18N::translate('Phrase')),
935701f5d18SGreg Roach            'INDI:*:DATE:TIME'           => new TimeValue(I18N::translate('Time')),
936701f5d18SGreg Roach            'INDI:*:PLAC:EXID'           => new ExternalIdentifier(I18N::translate('External identifier')),
937701f5d18SGreg Roach            'INDI:*:PLAC:EXID:TYPE'      => new ExternalIdentifierType(I18N::translate('Type')),
938701f5d18SGreg Roach            'INDI:*:SDATE'               => new CustomElement(I18N::translate('Sort date')),
939701f5d18SGreg Roach            'INDI:*:SDATE:PHRASE'        => new CustomElement(I18N::translate('Phrase')),
940701f5d18SGreg Roach            'INDI:*:SDATE:TIME'          => new CustomElement(I18N::translate('Sort time')),
941701f5d18SGreg Roach            'INDI:*:SNOTE'               => new XrefSharedNote(I18N::translate('Shared note')),
942701f5d18SGreg Roach            'INDI:*:UID'                 => new Uid(I18N::translate('Unique identifier')),
943701f5d18SGreg Roach            'INDI:ADOP:FAMC:ADOP:PHRASE' => new CustomElement(I18N::translate('Phrase')),
944701f5d18SGreg Roach            'INDI:ALIA:PHRASE'           => new CustomElement(I18N::translate('Phrase')),
945701f5d18SGreg Roach            'INDI:ASSO'                  => new XrefAssociate(I18N::translate('Associate')),
946701f5d18SGreg Roach            'INDI:ASSO:PHRASE'           => new CustomElement(I18N::translate('Phrase')),
947701f5d18SGreg Roach            'INDI:ASSO:ROLE'             => new RoleInEvent(I18N::translate('Role')),
948701f5d18SGreg Roach            'INDI:ASSO:ROLE:PHRASE'      => new CustomElement(I18N::translate('Phrase')),
949701f5d18SGreg Roach            'INDI:BIRT:DATE:TIME'        => new TimeValue(I18N::translate('Time of birth')),
950701f5d18SGreg Roach            'INDI:CREA'                  => new Creation(I18N::translate('Created at')),
951701f5d18SGreg Roach            'INDI:CREA:DATE'             => new DateValue(I18N::translate('Creation date')),
952701f5d18SGreg Roach            'INDI:CREA:DATE:TIME'        => new TimeValue(I18N::translate('Creation time')),
953701f5d18SGreg Roach            'INDI:DEAT:DATE:TIME'        => new TimeValue(I18N::translate('Time of death')),
954701f5d18SGreg Roach            'INDI:EXID'                  => new ExternalIdentifier(I18N::translate('External identifier')),
955701f5d18SGreg Roach            'INDI:EXID:TYPE'             => new ExternalIdentifierType(I18N::translate('Type')),
956701f5d18SGreg Roach            'INDI:INIL'                  => /* I18N: GEDCOM tag INIL - an LDS ceremony */ new LdsInitiatory(I18N::translate('LDS initiatory')),
957701f5d18SGreg Roach            'INDI:INIL:STAT'             => new LdsOrdinanceStatus(I18N::translate('Status')),
958701f5d18SGreg Roach            'INDI:INIL:STAT:DATE'        => new ChangeDate(I18N::translate('Date of status change')),
959701f5d18SGreg Roach            'INDI:INIL:STAT:DATE:TIME'   => new TimeValue(I18N::translate('Time of status change')),
960701f5d18SGreg Roach            'INDI:INIL:TEMP'             => new TempleCode(I18N::translate('Temple')),
961701f5d18SGreg Roach            'INDI:REFN'                  => new UserReferenceNumber(I18N::translate('Reference number')),
962701f5d18SGreg Roach            'INDI:REFN:TYPE'             => new UserReferenceType(I18N::translate('Type')),
963701f5d18SGreg Roach            'INDI:SNOTE'                 => new XrefSharedNote(I18N::translate('Shared note')),
964701f5d18SGreg Roach            'INDI:UID'                   => new Uid(I18N::translate('Unique identifier')),
965701f5d18SGreg Roach            'OBJE:CREA'                  => new Creation(I18N::translate('Created at')),
966701f5d18SGreg Roach            'OBJE:CREA:DATE'             => new DateValue(I18N::translate('Creation date')),
967701f5d18SGreg Roach            'OBJE:CREA:DATE:TIME'        => new TimeValue(I18N::translate('Creation time')),
968701f5d18SGreg Roach            'OBJE:SNOTE'                 => new XrefSharedNote(I18N::translate('Shared note')),
969701f5d18SGreg Roach            'REPO:CREA'                  => new Creation(I18N::translate('Created at')),
970701f5d18SGreg Roach            'REPO:CREA:DATE'             => new DateValue(I18N::translate('Creation date')),
971701f5d18SGreg Roach            'REPO:CREA:DATE:TIME'        => new TimeValue(I18N::translate('Creation time')),
972701f5d18SGreg Roach            'REPO:EXID'                  => new ExternalIdentifier(I18N::translate('External identifier')),
973701f5d18SGreg Roach            'REPO:EXID:TYPE'             => new ExternalIdentifierType(I18N::translate('Type')),
974701f5d18SGreg Roach            'REPO:REFN'                  => new UserReferenceNumber(I18N::translate('Reference number')),
975701f5d18SGreg Roach            'REPO:REFN:TYPE'             => new UserReferenceType(I18N::translate('Type')),
976701f5d18SGreg Roach            'REPO:SNOTE'                 => new XrefSharedNote(I18N::translate('Shared note')),
977701f5d18SGreg Roach            'REPO:UID'                   => new Uid(I18N::translate('Unique identifier')),
978701f5d18SGreg Roach            'SNOTE:CREA'                 => new Creation(I18N::translate('Created at')),
979701f5d18SGreg Roach            'SNOTE:CREA:DATE'            => new DateValue(I18N::translate('Creation date')),
980701f5d18SGreg Roach            'SNOTE:CREA:DATE:TIME'       => new TimeValue(I18N::translate('Creation time')),
981701f5d18SGreg Roach            'SNOTE:EXID'                 => new ExternalIdentifier(I18N::translate('External identifier')),
982701f5d18SGreg Roach            'SNOTE:EXID:TYPE'            => new ExternalIdentifierType(I18N::translate('Type')),
983701f5d18SGreg Roach            'SNOTE:REFN'                 => new UserReferenceNumber(I18N::translate('Reference number')),
984701f5d18SGreg Roach            'SNOTE:REFN:TYPE'            => new UserReferenceType(I18N::translate('Type')),
985701f5d18SGreg Roach            'SNOTE:UID'                  => new Uid(I18N::translate('Unique identifier')),
986701f5d18SGreg Roach            'SOUR:CREA'                  => new Creation(I18N::translate('Created at')),
987701f5d18SGreg Roach            'SOUR:CREA:DATE'             => new DateValue(I18N::translate('Creation date')),
988701f5d18SGreg Roach            'SOUR:CREA:DATE:TIME'        => new TimeValue(I18N::translate('Creation time')),
989701f5d18SGreg Roach            'SOUR:EXID'                  => new ExternalIdentifier(I18N::translate('External identifier')),
990701f5d18SGreg Roach            'SOUR:EXID:TYPE'             => new ExternalIdentifierType(I18N::translate('Type')),
991701f5d18SGreg Roach            'SOUR:REFN'                  => new UserReferenceNumber(I18N::translate('Reference number')),
992701f5d18SGreg Roach            'SOUR:REFN:TYPE'             => new UserReferenceType(I18N::translate('Type')),
993701f5d18SGreg Roach            'SOUR:SNOTE'                 => new XrefSharedNote(I18N::translate('Shared note')),
994701f5d18SGreg Roach            'SOUR:UID'                   => new Uid(I18N::translate('Unique identifier')),
995701f5d18SGreg Roach            'SUBM:CREA'                  => new Creation(I18N::translate('Created at')),
996701f5d18SGreg Roach            'SUBM:CREA:DATE'             => new DateValue(I18N::translate('Creation date')),
997701f5d18SGreg Roach            'SUBM:CREA:DATE:TIME'        => new TimeValue(I18N::translate('Creation time')),
998701f5d18SGreg Roach            'SUBM:EXID'                  => new ExternalIdentifier(I18N::translate('External identifier')),
999701f5d18SGreg Roach            'SUBM:EXID:TYPE'             => new ExternalIdentifierType(I18N::translate('Type')),
1000701f5d18SGreg Roach            'SUBM:REFN'                  => new UserReferenceNumber(I18N::translate('Reference number')),
1001701f5d18SGreg Roach            'SUBM:REFN:TYPE'             => new UserReferenceType(I18N::translate('Type')),
1002701f5d18SGreg Roach            'SUBM:SNOTE'                 => new XrefSharedNote(I18N::translate('Shared note')),
1003701f5d18SGreg Roach            'SUBM:UID'                   => new Uid(I18N::translate('Unique identifier')),
1004701f5d18SGreg Roach        ];
1005701f5d18SGreg Roach    }
1006701f5d18SGreg Roach
1007701f5d18SGreg Roach    /**
1008744f65c6SGreg Roach     * Aldfaer also uses: _BOLD, _ITALIC, _UNDERLINE, _COLOR
1009744f65c6SGreg Roach     *
101000c92694SGreg Roach     * @return array<string,ElementInterface>
1011cb0c239dSGreg Roach     */
1012cb0c239dSGreg Roach    private function aldfaerTags(): array
1013cb0c239dSGreg Roach    {
1014cb0c239dSGreg Roach        return [
10159e97502fSGreg Roach            'FAM:MARR_CIVIL'           => new Marriage(I18N::translate('Civil marriage')),
10169e97502fSGreg Roach            'FAM:MARR_PARTNERS'        => new Marriage(I18N::translate('Registered partnership')),
10179e97502fSGreg Roach            'FAM:MARR_RELIGIOUS'       => new Marriage(I18N::translate('Religious marriage')),
10189e97502fSGreg Roach            'FAM:MARR_UNKNOWN'         => new Marriage(I18N::translate('Marriage')),
1019744f65c6SGreg Roach            'FAM:_ALDFAER_NOREL'       => new EmptyElement('No relation'), // What is this?
1020744f65c6SGreg Roach            'HEAD:SUBM:ADDR'           => new AddressLine(I18N::translate('Address')),
1021744f65c6SGreg Roach            'HEAD:SUBM:PHON'           => new PhoneNumber(I18N::translate('Phone')),
1022744f65c6SGreg Roach            'HEAD:SUBM:_EMAI'          => new AddressEmail(I18N::translate('Email')),
1023744f65c6SGreg Roach            'HEAD:SUBM:_FAX'           => new AddressFax(I18N::translate('Fax')),
1024744f65c6SGreg Roach            'HEAD:SUBM:_WWW'           => new AddressWebPage(I18N::translate('URL')),
1025744f65c6SGreg Roach            'INDI:BIRT:_ALDFAER_TIME'  => new TimeValue(I18N::translate('Time of birth')),
1026cb0c239dSGreg Roach            'INDI:BIRT:_LENGTH'        => new CustomElement(I18N::translate('Length')),
1027cb0c239dSGreg Roach            'INDI:BIRT:_WEIGHT'        => new CustomElement(I18N::translate('Weight')),
1028744f65c6SGreg Roach            'INDI:DEAT:_ALDFAER_TIME'  => new TimeValue(I18N::translate('Time of death')),
1029744f65c6SGreg Roach            'INDI:_REFERENCE'          => new CustomElement(''),
1030744f65c6SGreg Roach            'INDI:_PRIVACY'            => new CustomElement(''),
1031744f65c6SGreg Roach            'INDI:_PRIVACY:_OBJECTION' => new CustomElement(''),
1032744f65c6SGreg Roach            'INDI:_PRIVACY:_PUBLISH'   => new CustomElement(''),
1033744f65c6SGreg Roach            'INDI:NAME:_SURNAS'        => new CustomElement(I18N::translate('Alternative spelling of surname')),
1034744f65c6SGreg Roach            'INDI:DEAT:_DATE'          => new DateValue(I18N::translate('Date')),
1035744f65c6SGreg Roach            'INDI:_INQUBIRT'           => new CustomElement(I18N::translate('')),
1036744f65c6SGreg Roach            'INDI:_INQUCHIL'           => new CustomElement(I18N::translate('')),
1037744f65c6SGreg Roach            'INDI:_INQURELA'           => new CustomElement(I18N::translate('')),
1038744f65c6SGreg Roach            'INDI:_INQUDEAT'           => new CustomElement(I18N::translate('')),
1039744f65c6SGreg Roach            'INDI:_INQUVAR1'           => new CustomElement(I18N::translate('')),
1040744f65c6SGreg Roach            'INDI:_INQUVAR1CAT'        => new CustomElement(I18N::translate('')),
1041744f65c6SGreg Roach            'INDI:_INQUVAR2'           => new CustomElement(I18N::translate('')),
1042744f65c6SGreg Roach            'INDI:_INQUVAR2CAT'        => new CustomElement(I18N::translate('')),
1043744f65c6SGreg Roach            'INDI:_INQUVAR3'           => new CustomElement(I18N::translate('')),
1044744f65c6SGreg Roach            'INDI:_INQUVAR3CAT'        => new CustomElement(I18N::translate('')),
1045744f65c6SGreg Roach            'INDI:_NOPARTNER'          => new CustomElement(I18N::translate('')),
1046744f65c6SGreg Roach            'INDI:_NEW'                => new CustomElement(I18N::translate('')),
1047cb0c239dSGreg Roach        ];
1048cb0c239dSGreg Roach    }
1049cb0c239dSGreg Roach
1050cb0c239dSGreg Roach    /**
1051cb0c239dSGreg Roach     * @return array<string,ElementInterface>
105213d1ef26SGreg Roach     *
105313d1ef26SGreg Roach     * @see https://www.webtrees.net/index.php/en/forum/help-for-release-2-1-x/36664-2-1-beta-support-for-indi-even-sour-data-note-and-the-like
105400c92694SGreg Roach     */
105500c92694SGreg Roach    private function ancestryTags(): array
105600c92694SGreg Roach    {
105700c92694SGreg Roach        return [
105897ed7714SGreg Roach            'HEAD:SOUR:_TREE'       => new CustomElement(I18N::translate('Family tree')),
105997ed7714SGreg Roach            'HEAD:SOUR:_TREE:NOTE'  => new SubmitterText(I18N::translate('Note')),
106097ed7714SGreg Roach            'HEAD:SOUR:_TREE:RIN'   => new AutomatedRecordId(I18N::translate('Record ID number')),
106110b4ce2aSGreg Roach            'INDI:*:SOUR:_APID'     => /* I18N: GEDCOM tag _APID */ new CustomElement(I18N::translate('Ancestry PID')),
106213d1ef26SGreg Roach            'INDI:*:SOUR:DATA:NOTE' => new SubmitterText(I18N::translate('Note')),
106300c92694SGreg Roach            'INDI:_EMPLOY'          => new CustomFact(I18N::translate('Occupation')),
10649b0286b1SGreg Roach            'INDI:_FUN'             => new CustomEvent(I18N::translate('Funeral')),
1065701f5d18SGreg Roach            'INDI:_INIT'            => new LdsInitiatory(I18N::translate('LDS initiatory')),
10669b0286b1SGreg Roach            'INDI:_ORDI'            => new CustomEvent(I18N::translate('Ordination')),
10679b0286b1SGreg Roach            'INDI:_ORIG'            => new CustomFact(I18N::translate('Origin')),
10689b0286b1SGreg Roach            'INDI:_DEST'            => new CustomFact(I18N::translate('Destination')),
106913d1ef26SGreg Roach            'OBJE:DATE'             => new DateValue(I18N::translate('Date')),
107013d1ef26SGreg Roach            'OBJE:PLAC'             => new PlaceName(I18N::translate('Place')),
107113d1ef26SGreg Roach            'OBJE:_CREA'            => /* I18N: GEDCOM tag _CREA */ new CustomElement(I18N::translate('Created at')),
107213d1ef26SGreg Roach            'OBJE:_ORIG'            => /* I18N: GEDCOM tag _ORIG */ new CustomElement(I18N::translate('Original text')),
107313d1ef26SGreg Roach            'OBJE:_ORIG:_URL'       => new AddressWebPage(I18N::translate('URL')),
107400c92694SGreg Roach        ];
107500c92694SGreg Roach    }
107600c92694SGreg Roach
107700c92694SGreg Roach    /**
107800c92694SGreg Roach     * @return array<string,ElementInterface>
107900c92694SGreg Roach     *
108000c92694SGreg Roach     * @see https://wiki-de.genealogy.net/GEDCOM/_Nutzerdef-Tag
108100c92694SGreg Roach     */
108200c92694SGreg Roach    private function brothersKeeperTags(): array
108300c92694SGreg Roach    {
108400c92694SGreg Roach        return [
108500c92694SGreg Roach            'FAM:*:_EVN'       => new CustomElement('Event number'),
10864c10b11dSGreg Roach            'FAM:CHIL:_FREL'   => new CustomElement(I18N::translate('Relationship to father')),
10874c10b11dSGreg Roach            'FAM:CHIL:_MREL'   => new CustomElement(I18N::translate('Relationship to mother')),
108800c92694SGreg Roach            'FAM:_COML'        => new CustomFamilyEvent(I18N::translate('Common law marriage')),
108900c92694SGreg Roach            'FAM:_MARI'        => new CustomFamilyEvent(I18N::translate('Marriage intention')),
109000c92694SGreg Roach            'FAM:_MBON'        => new CustomFamilyEvent(I18N::translate('Marriage bond')),
109100c92694SGreg Roach            'FAM:_NMR'         => new CustomFamilyEvent(I18N::translate('Not married'), ['NOTE' => '0:M', 'SOUR' => '0:M']),
109200c92694SGreg Roach            'FAM:_PRMN'        => new CustomElement(I18N::translate('Permanent number')),
109300c92694SGreg Roach            'FAM:_SEPR'        => new CustomFamilyEvent(I18N::translate('Separated')),
109400c92694SGreg Roach            'FAM:_TODO'        => new CustomElement(I18N::translate('Research task')),
109500c92694SGreg Roach            'INDI:*:_EVN'      => new CustomElement('Event number'),
109600c92694SGreg Roach            'INDI:NAME:_ADPN'  => new NamePersonal(I18N::translate('Adopted name'), []),
109700c92694SGreg Roach            'INDI:NAME:_AKAN'  => new NamePersonal(I18N::translate('Also known as'), []),
109800c92694SGreg Roach            'INDI:NAME:_BIRN'  => new NamePersonal(I18N::translate('Birth name'), []),
109900c92694SGreg Roach            'INDI:NAME:_CALL'  => new NamePersonal('Called name', []),
110000c92694SGreg Roach            'INDI:NAME:_CENN'  => new NamePersonal('Census name', []),
110100c92694SGreg Roach            'INDI:NAME:_CURN'  => new NamePersonal('Current name', []),
110200c92694SGreg Roach            'INDI:NAME:_FARN'  => new NamePersonal(I18N::translate('Estate name'), []),
110300c92694SGreg Roach            'INDI:NAME:_FKAN'  => new NamePersonal('Formal name', []),
110400c92694SGreg Roach            'INDI:NAME:_FRKA'  => new NamePersonal('Formerly known as', []),
110500c92694SGreg Roach            'INDI:NAME:_GERN'  => new NamePersonal('German name', []),
110600c92694SGreg Roach            'INDI:NAME:_HEBN'  => new NamePersonal(I18N::translate('Hebrew name'), []),
110700c92694SGreg Roach            'INDI:NAME:_HNM'   => new NamePersonal(I18N::translate('Hebrew name'), []),
110800c92694SGreg Roach            'INDI:NAME:_INDG'  => new NamePersonal('Indigenous name', []),
110900c92694SGreg Roach            'INDI:NAME:_INDN'  => new NamePersonal('Indian name', []),
111000c92694SGreg Roach            'INDI:NAME:_LNCH'  => new NamePersonal('Legal name change', []),
111100c92694SGreg Roach            'INDI:NAME:_MARN'  => new NamePersonal('Married name', []),
111200c92694SGreg Roach            'INDI:NAME:_MARNM' => new NamePersonal('Married name', []),
111300c92694SGreg Roach            'INDI:NAME:_OTHN'  => new NamePersonal('Other name', []),
111400c92694SGreg Roach            'INDI:NAME:_RELN'  => new NamePersonal('Religious name', []),
111500c92694SGreg Roach            'INDI:NAME:_SHON'  => new NamePersonal('Short name', []),
111600c92694SGreg Roach            'INDI:NAME:_SLDN'  => new NamePersonal('Soldier name', []),
111700c92694SGreg Roach            'INDI:_ADPF'       => new CustomElement(I18N::translate('Adopted by father')),
111800c92694SGreg Roach            'INDI:_ADPM'       => new CustomElement(I18N::translate('Adopted by mother')),
111900c92694SGreg Roach            'INDI:_BRTM'       => new CustomIndividualEvent(I18N::translate('Brit milah')),
112000c92694SGreg Roach            'INDI:_BRTM:DATE'  => new DateValue(I18N::translate('Date of brit milah')),
112100c92694SGreg Roach            'INDI:_BRTM:PLAC'  => new PlaceName(I18N::translate('Place of brit milah')),
112200c92694SGreg Roach            'INDI:_EMAIL'      => new AddressEmail(I18N::translate('Email address')),
112300c92694SGreg Roach            'INDI:_EYEC'       => new CustomFact(I18N::translate('Eye color')),
1124ab31afd8SGreg Roach            'INDI:_FNRL'       => new CustomElement(I18N::translate('Funeral')),
112500c92694SGreg Roach            'INDI:_HAIR'       => new CustomFact(I18N::translate('Hair color')),
112600c92694SGreg Roach            'INDI:_HEIG'       => new CustomFact(I18N::translate('Height')),
112700c92694SGreg Roach            'INDI:_INTE'       => new CustomElement(I18N::translate('Interment')),
112800c92694SGreg Roach            'INDI:_MEDC'       => new CustomFact(I18N::translate('Medical')),
112900c92694SGreg Roach            'INDI:_MILT'       => new CustomElement(I18N::translate('Military service')),
113000c92694SGreg Roach            'INDI:_NLIV'       => new CustomFact(I18N::translate('Not living')),
1131*d93e9e4dSGreg Roach            'INDI:_NMAR'       => new CustomEvent(I18N::translate('Never married'), ['NOTE' => '0:M', 'SOUR' => '0:M']),
113200c92694SGreg Roach            'INDI:_PRMN'       => new CustomElement(I18N::translate('Permanent number')),
113300c92694SGreg Roach            'INDI:_TODO'       => new CustomElement(I18N::translate('Research task')),
113400c92694SGreg Roach            'INDI:_WEIG'       => new CustomFact(I18N::translate('Weight')),
113500c92694SGreg Roach            'INDI:_YART'       => new CustomIndividualEvent(I18N::translate('Yahrzeit')),
113600c92694SGreg Roach            // 1 XXXX
113700c92694SGreg Roach            // 2 _EVN ##
113800c92694SGreg Roach            // 1 ASSO @Xnnn@
113900c92694SGreg Roach            // 2 RELA Witness at event _EVN ##
114000c92694SGreg Roach        ];
114100c92694SGreg Roach    }
114200c92694SGreg Roach
114300c92694SGreg Roach    /**
114400c92694SGreg Roach     * @return array<string,ElementInterface>
114500c92694SGreg Roach     */
114600c92694SGreg Roach    private function familySearchTags(): array
114700c92694SGreg Roach    {
114800c92694SGreg Roach        return [
114900c92694SGreg Roach            'INDI:_FSFTID' => /* I18N: familysearch.org */ new FamilySearchFamilyTreeId(I18N::translate('FamilySearch ID')),
115000c92694SGreg Roach        ];
115100c92694SGreg Roach    }
115200c92694SGreg Roach
115300c92694SGreg Roach    /**
115400c92694SGreg Roach     * @return array<string,ElementInterface>
115500c92694SGreg Roach     */
115600c92694SGreg Roach    private function familyTreeBuilderTags(): array
115700c92694SGreg Roach    {
115800c92694SGreg Roach        return [
1159f0e4072fSGreg Roach            '*:_UPD'              => /* I18N: GEDCOM tag _UPD */ new CustomElement(I18N::translate('Updated at')), // e.g. "1 _UPD 14 APR 2012 00:14:10 GMT-5"
116000c92694SGreg Roach            'INDI:NAME:_AKA'      => new NamePersonal(I18N::translate('Also known as'), []),
116100c92694SGreg Roach            'OBJE:_ALBUM'         => new CustomElement(I18N::translate('Album')), // XREF to an album
116200c92694SGreg Roach            'OBJE:_DATE'          => new DateValue(I18N::translate('Date')),
116300c92694SGreg Roach            'OBJE:_FILESIZE'      => new CustomElement(I18N::translate('File size')),
116400c92694SGreg Roach            'OBJE:_PHOTO_RIN'     => new CustomElement(I18N::translate('Record ID number')),
116500c92694SGreg Roach            'OBJE:_PLACE'         => new PlaceName(I18N::translate('Place')),
116600c92694SGreg Roach            '_ALBUM:_PHOTO'       => new CustomElement(I18N::translate('Photo')),
116700c92694SGreg Roach            '_ALBUM:_PHOTO:_PRIN' => new CustomElement(I18N::translate('Highlighted image')),
116800c92694SGreg Roach        ];
116900c92694SGreg Roach    }
117000c92694SGreg Roach
117100c92694SGreg Roach    /**
117200c92694SGreg Roach     * @return array<string,ElementInterface>
117300c92694SGreg Roach     *
117400c92694SGreg Roach     * @see https://wiki-de.genealogy.net/GEDCOM/_Nutzerdef-Tag
117500c92694SGreg Roach     */
117600c92694SGreg Roach    private function familyTreeMakerTags(): array
117700c92694SGreg Roach    {
117800c92694SGreg Roach        return [
117900c92694SGreg Roach            'FAM:CHIL:_FREL'              => new CustomElement(I18N::translate('Relationship to father')),
118000c92694SGreg Roach            'FAM:CHIL:_MREL'              => new CustomElement(I18N::translate('Relationship to mother')),
118100c92694SGreg Roach            'FAM:_DETS'                   => new CustomElement(I18N::translate('Death of one spouse')),
118200c92694SGreg Roach            'FAM:_FA1'                    => new CustomElement(I18N::translate('Fact 1')),
118300c92694SGreg Roach            'FAM:_FA10'                   => new CustomElement(I18N::translate('Fact 10')),
118400c92694SGreg Roach            'FAM:_FA11'                   => new CustomElement(I18N::translate('Fact 11')),
118500c92694SGreg Roach            'FAM:_FA12'                   => new CustomElement(I18N::translate('Fact 12')),
118600c92694SGreg Roach            'FAM:_FA13'                   => new CustomElement(I18N::translate('Fact 13')),
118700c92694SGreg Roach            'FAM:_FA2'                    => new CustomElement(I18N::translate('Fact 2')),
118800c92694SGreg Roach            'FAM:_FA3'                    => new CustomElement(I18N::translate('Fact 3')),
118900c92694SGreg Roach            'FAM:_FA4'                    => new CustomElement(I18N::translate('Fact 4')),
119000c92694SGreg Roach            'FAM:_FA5'                    => new CustomElement(I18N::translate('Fact 5')),
119100c92694SGreg Roach            'FAM:_FA6'                    => new CustomElement(I18N::translate('Fact 6')),
119200c92694SGreg Roach            'FAM:_FA7'                    => new CustomElement(I18N::translate('Fact 7')),
119300c92694SGreg Roach            'FAM:_FA8'                    => new CustomElement(I18N::translate('Fact 8')),
119400c92694SGreg Roach            'FAM:_FA9'                    => new CustomElement(I18N::translate('Fact 9')),
119500c92694SGreg Roach            'FAM:_MEND'                   => new CustomElement(I18N::translate('Marriage ending status')),
119600c92694SGreg Roach            'FAM:_MSTAT'                  => new CustomElement(I18N::translate('Marriage beginning status')),
119700c92694SGreg Roach            'FAM:_SEPR'                   => new CustomElement(I18N::translate('Separation')),
11984c10b11dSGreg Roach            'HEAD:_SCHEMA'                => new CustomElement(I18N::translate('Schema')),
119900c92694SGreg Roach            'HEAD:_SCHEMA:FAM'            => new CustomElement(I18N::translate('Family')),
120000c92694SGreg Roach            'HEAD:_SCHEMA:FAM:_FA*:LABL'  => new CustomElement(I18N::translate('Label')),
120100c92694SGreg Roach            'HEAD:_SCHEMA:FAM:_FA1'       => new CustomElement(I18N::translate('Fact 1')),
120200c92694SGreg Roach            'HEAD:_SCHEMA:FAM:_FA10'      => new CustomElement(I18N::translate('Fact 10')),
120300c92694SGreg Roach            'HEAD:_SCHEMA:FAM:_FA11'      => new CustomElement(I18N::translate('Fact 11')),
120400c92694SGreg Roach            'HEAD:_SCHEMA:FAM:_FA12'      => new CustomElement(I18N::translate('Fact 12')),
120500c92694SGreg Roach            'HEAD:_SCHEMA:FAM:_FA13'      => new CustomElement(I18N::translate('Fact 13')),
120600c92694SGreg Roach            'HEAD:_SCHEMA:FAM:_FA2'       => new CustomElement(I18N::translate('Fact 2')),
120700c92694SGreg Roach            'HEAD:_SCHEMA:FAM:_FA3'       => new CustomElement(I18N::translate('Fact 3')),
120800c92694SGreg Roach            'HEAD:_SCHEMA:FAM:_FA4'       => new CustomElement(I18N::translate('Fact 4')),
120900c92694SGreg Roach            'HEAD:_SCHEMA:FAM:_FA5'       => new CustomElement(I18N::translate('Fact 5')),
121000c92694SGreg Roach            'HEAD:_SCHEMA:FAM:_FA6'       => new CustomElement(I18N::translate('Fact 6')),
121100c92694SGreg Roach            'HEAD:_SCHEMA:FAM:_FA7'       => new CustomElement(I18N::translate('Fact 7')),
121200c92694SGreg Roach            'HEAD:_SCHEMA:FAM:_FA8'       => new CustomElement(I18N::translate('Fact 8')),
121300c92694SGreg Roach            'HEAD:_SCHEMA:FAM:_FA9'       => new CustomElement(I18N::translate('Fact 9')),
121400c92694SGreg Roach            'HEAD:_SCHEMA:FAM:_M*:LABL'   => new CustomElement(I18N::translate('Label')),
121500c92694SGreg Roach            'HEAD:_SCHEMA:FAM:_MEND'      => new CustomElement(I18N::translate('Marriage ending status')),
121600c92694SGreg Roach            'HEAD:_SCHEMA:FAM:_MSTAT'     => new CustomElement(I18N::translate('Marriage beginning status')),
121700c92694SGreg Roach            'HEAD:_SCHEMA:INDI'           => new CustomElement(I18N::translate('Individual')),
121800c92694SGreg Roach            'HEAD:_SCHEMA:INDI:_FA*:LABL' => new CustomElement(I18N::translate('Label')),
121900c92694SGreg Roach            'HEAD:_SCHEMA:INDI:_FA1'      => new CustomElement(I18N::translate('Fact 1')),
122000c92694SGreg Roach            'HEAD:_SCHEMA:INDI:_FA10'     => new CustomElement(I18N::translate('Fact 10')),
122100c92694SGreg Roach            'HEAD:_SCHEMA:INDI:_FA11'     => new CustomElement(I18N::translate('Fact 11')),
122200c92694SGreg Roach            'HEAD:_SCHEMA:INDI:_FA12'     => new CustomElement(I18N::translate('Fact 12')),
122300c92694SGreg Roach            'HEAD:_SCHEMA:INDI:_FA13'     => new CustomElement(I18N::translate('Fact 13')),
122400c92694SGreg Roach            'HEAD:_SCHEMA:INDI:_FA2'      => new CustomElement(I18N::translate('Fact 2')),
122500c92694SGreg Roach            'HEAD:_SCHEMA:INDI:_FA3'      => new CustomElement(I18N::translate('Fact 3')),
122600c92694SGreg Roach            'HEAD:_SCHEMA:INDI:_FA4'      => new CustomElement(I18N::translate('Fact 4')),
122700c92694SGreg Roach            'HEAD:_SCHEMA:INDI:_FA5'      => new CustomElement(I18N::translate('Fact 5')),
122800c92694SGreg Roach            'HEAD:_SCHEMA:INDI:_FA6'      => new CustomElement(I18N::translate('Fact 6')),
122900c92694SGreg Roach            'HEAD:_SCHEMA:INDI:_FA7'      => new CustomElement(I18N::translate('Fact 7')),
123000c92694SGreg Roach            'HEAD:_SCHEMA:INDI:_FA8'      => new CustomElement(I18N::translate('Fact 8')),
123100c92694SGreg Roach            'HEAD:_SCHEMA:INDI:_FA9'      => new CustomElement(I18N::translate('Fact 9')),
12324c10b11dSGreg Roach            'HEAD:_SCHEMA:INDI:_FREL'     => new CustomElement(I18N::translate('Relationship to father')),
123300c92694SGreg Roach            'HEAD:_SCHEMA:INDI:_M*:LABL'  => new CustomElement(I18N::translate('Label')),
12344c10b11dSGreg Roach            'HEAD:_SCHEMA:INDI:_MREL'     => new CustomElement(I18N::translate('Relationship to mother')),
12354c10b11dSGreg Roach            'INDI:*:SOUR:_APID'           => /* I18N: GEDCOM tag _APID */ new CustomElement(I18N::translate('Ancestry.com source identifier')),
12364c10b11dSGreg Roach            'INDI:*:SOUR:_LINK'           => new CustomElement(I18N::translate('External link')),
123700c92694SGreg Roach            'INDI:NAME:_AKA'              => new NamePersonal(I18N::translate('Also known as'), []),
123800c92694SGreg Roach            'INDI:NAME:_MARNM'            => new NamePersonal(I18N::translate('Married name'), []),
12394c10b11dSGreg Roach            'INDI:_CIRC'                  => new CustomElement(I18N::translate('Circumcision')),
124000c92694SGreg Roach            'INDI:_DCAUSE'                => new CustomElement(I18N::translate('Cause of death')),
124100c92694SGreg Roach            'INDI:_DEG'                   => new CustomElement(I18N::translate('Degree')),
124200c92694SGreg Roach            'INDI:_DNA'                   => new CustomElement(I18N::translate('DNA markers')),
124300c92694SGreg Roach            'INDI:_ELEC'                  => new CustomElement('Elected'),
124400c92694SGreg Roach            'INDI:_EMPLOY'                => new CustomElement('Employment'),
124500c92694SGreg Roach            'INDI:_EXCM'                  => new CustomElement('Excommunicated'),
12464c10b11dSGreg Roach            'INDI:_FA1'                   => new CustomElement(I18N::translate('Fact 1')),
12474c10b11dSGreg Roach            'INDI:_FA10'                  => new CustomElement(I18N::translate('Fact 10')),
12484c10b11dSGreg Roach            'INDI:_FA11'                  => new CustomElement(I18N::translate('Fact 11')),
12494c10b11dSGreg Roach            'INDI:_FA12'                  => new CustomElement(I18N::translate('Fact 12')),
12504c10b11dSGreg Roach            'INDI:_FA13'                  => new CustomElement(I18N::translate('Fact 13')),
12514c10b11dSGreg Roach            'INDI:_FA2'                   => new CustomElement(I18N::translate('Fact 2')),
12524c10b11dSGreg Roach            'INDI:_FA3'                   => new CustomElement(I18N::translate('Fact 3')),
12534c10b11dSGreg Roach            'INDI:_FA4'                   => new CustomElement(I18N::translate('Fact 4')),
12544c10b11dSGreg Roach            'INDI:_FA5'                   => new CustomElement(I18N::translate('Fact 5')),
12554c10b11dSGreg Roach            'INDI:_FA6'                   => new CustomElement(I18N::translate('Fact 6')),
12564c10b11dSGreg Roach            'INDI:_FA7'                   => new CustomElement(I18N::translate('Fact 7')),
12574c10b11dSGreg Roach            'INDI:_FA8'                   => new CustomElement(I18N::translate('Fact 8')),
12584c10b11dSGreg Roach            'INDI:_FA9'                   => new CustomElement(I18N::translate('Fact 9')),
12594c10b11dSGreg Roach            'INDI:_MDCL'                  => new CustomElement(I18N::translate('Medical')),
126000c92694SGreg Roach            'INDI:_MILT'                  => new CustomElement(I18N::translate('Military service')),
126100c92694SGreg Roach            'INDI:_MILTID'                => new CustomElement('Military ID number'),
126200c92694SGreg Roach            'INDI:_MISN'                  => new CustomElement('Mission'),
126300c92694SGreg Roach            'INDI:_NAMS'                  => new CustomElement(I18N::translate('Namesake')),
126400c92694SGreg Roach            'INDI:_UNKN'                  => new CustomElement(I18N::translate('Unknown')), // Special individual ID code for later file comparisons
126500c92694SGreg Roach        ];
126600c92694SGreg Roach    }
126700c92694SGreg Roach
126800c92694SGreg Roach    /**
126900c92694SGreg Roach     * @return array<string,ElementInterface>
127000c92694SGreg Roach     */
127100c92694SGreg Roach    private function gedcomLTags(): array
127200c92694SGreg Roach    {
127300c92694SGreg Roach        return [
12744c10b11dSGreg Roach            'FAM:*:ADDR:_NAME'                => new CustomElement(I18N::translate('Name of addressee')),
127500c92694SGreg Roach            // I18N: https://gov.genealogy.net
127600c92694SGreg Roach            'FAM:*:PLAC:_GOV'                 => new GovIdentifier(I18N::translate('GOV identifier')),
127700c92694SGreg Roach            'FAM:*:PLAC:_LOC'                 => new XrefLocation(I18N::translate('Location')),
127800c92694SGreg Roach            // I18N: https://en.wikipedia.org/wiki/Maidenhead_Locator_System
127900c92694SGreg Roach            'FAM:*:PLAC:_MAIDENHEAD'          => new MaidenheadLocator(I18N::translate('Maidenhead location code')),
12804c10b11dSGreg Roach            'FAM:*:PLAC:_POST'                => new AddressPostalCode(I18N::translate('Postal code')),
128100c92694SGreg Roach            'FAM:*:PLAC:_POST:DATE'           => new DateValue(I18N::translate('Date')),
128200c92694SGreg Roach            'FAM:*:_ASSO'                     => new XrefAssociate(I18N::translate('Associate')),
128300c92694SGreg Roach            'FAM:*:_ASSO:NOTE'                => new NoteStructure(I18N::translate('Note')),
128400c92694SGreg Roach            'FAM:*:_ASSO:RELA'                => new RelationIsDescriptor(I18N::translate('Relationship')),
128500c92694SGreg Roach            'FAM:*:_ASSO:SOUR'                => new XrefSource(I18N::translate('Source citation')),
128600c92694SGreg Roach            'FAM:*:_ASSO:SOUR:DATA'           => new SourceData(I18N::translate('Data')),
1287352bd396SGreg Roach            'FAM:*:_ASSO:SOUR:DATA:DATE'      => new DateValue(I18N::translate('Date of entry in original source')),
128800c92694SGreg Roach            'FAM:*:_ASSO:SOUR:DATA:TEXT'      => new TextFromSource(I18N::translate('Text')),
128900c92694SGreg Roach            'FAM:*:_ASSO:SOUR:EVEN'           => new EventTypeCitedFrom(I18N::translate('Event')),
129000c92694SGreg Roach            'FAM:*:_ASSO:SOUR:EVEN:ROLE'      => new RoleInEvent(I18N::translate('Role')),
129100c92694SGreg Roach            'FAM:*:_ASSO:SOUR:NOTE'           => new NoteStructure(I18N::translate('Note')),
129200c92694SGreg Roach            'FAM:*:_ASSO:SOUR:OBJE'           => new XrefMedia(I18N::translate('Media object')),
129300c92694SGreg Roach            'FAM:*:_ASSO:SOUR:PAGE'           => new WhereWithinSource(I18N::translate('Citation details')),
129400c92694SGreg Roach            'FAM:*:_ASSO:SOUR:QUAY'           => new CertaintyAssessment(I18N::translate('Quality of data')),
12954c10b11dSGreg Roach            'FAM:*:_WITN'                     => new CustomElement(I18N::translate('Witnesses')),
129676f1fa21SRichard Cissée            'FAM:_ASSO'                       => new XrefAssociate(I18N::translate('Associate')),
129776f1fa21SRichard Cissée            'FAM:_ASSO:RELA'                  => new RelationIsDescriptor(I18N::translate('Relationship')),
129800c92694SGreg Roach            'FAM:_STAT'                       => new FamilyStatusText(I18N::translate('Family status')),
129900c92694SGreg Roach            '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']),
130000c92694SGreg Roach            'FAM:_TODO:DATA'                  => new SubmitterText(I18N::translate('The solution')),
130100c92694SGreg Roach            'FAM:_TODO:DATE'                  => new DateValue(I18N::translate('Creation date')),
130200c92694SGreg Roach            'FAM:_TODO:DESC'                  => new CustomElement(I18N::translate('Description')),
1303afb53502SGreg Roach            'FAM:_TODO:NOTE'                  => new NoteStructure(I18N::translate('Note')),
13044c10b11dSGreg Roach            'FAM:_TODO:REPO'                  => new XrefRepository(I18N::translate('Repository'), []),
130500c92694SGreg Roach            'FAM:_TODO:STAT'                  => new ResearchTaskStatus(I18N::translate('Status')),
130600c92694SGreg Roach            'FAM:_TODO:TYPE'                  => new ResearchTaskType(I18N::translate('Type of research task')),
130700c92694SGreg Roach            'FAM:_TODO:_CAT'                  => new CustomElement(I18N::translate('Category')),
130800c92694SGreg Roach            'FAM:_TODO:_CDATE'                => new DateValue(I18N::translate('Completion date')),
130900c92694SGreg Roach            'FAM:_TODO:_PRTY'                 => new ResearchTaskPriority(I18N::translate('Priority')),
131000c92694SGreg Roach            'FAM:_TODO:_RDATE'                => new DateValue(I18N::translate('Reminder date')),
131100c92694SGreg Roach            'FAM:_UID'                        => new PafUid(I18N::translate('Unique identifier')),
13124c10b11dSGreg Roach            'HEAD:GEDC:VERS:_ADDENDUM'        => new EmptyElement(I18N::translate('GEDCOM-L')),
131300c92694SGreg Roach            'HEAD:GEDC:VERS:_ADDENDUM:VERS'   => new VersionNumber(I18N::translate('Version')),
131400c92694SGreg Roach            'HEAD:GEDC:VERS:_ADDENDUM:WWW'    => new AddressWebPage(I18N::translate('URL')),
13154c10b11dSGreg Roach            'HEAD:SOUR:CORP:ADDR:_NAME'       => new CustomElement(I18N::translate('Name of addressee')),
131600c92694SGreg Roach            'HEAD:_SCHEMA'                    => new EmptyElement(I18N::translate('Schema')),
131700c92694SGreg Roach            'HEAD:_SCHEMA:*'                  => new EmptyElement(I18N::translate('Base GEDCOM tag')),
131800c92694SGreg Roach            'HEAD:_SCHEMA:*:*'                => new EmptyElement(I18N::translate('New GEDCOM tag')),
131900c92694SGreg Roach            'HEAD:_SCHEMA:*:*:*'              => new EmptyElement(I18N::translate('New GEDCOM tag')),
132000c92694SGreg Roach            'HEAD:_SCHEMA:*:*:*:*'            => new EmptyElement(I18N::translate('New GEDCOM tag')),
132100c92694SGreg Roach            'HEAD:_SCHEMA:*:*:*:*:*'          => new EmptyElement(I18N::translate('New GEDCOM tag')),
132200c92694SGreg Roach            'HEAD:_SCHEMA:*:*:*:*:*:*'        => new EmptyElement(I18N::translate('New GEDCOM tag')),
132300c92694SGreg Roach            'HEAD:_SCHEMA:*:*:*:*:*:*:_DEFN'  => new EmptyElement(I18N::translate('Definition')),
132400c92694SGreg Roach            'HEAD:_SCHEMA:*:*:*:*:*:_DEFN'    => new EmptyElement(I18N::translate('Definition')),
132500c92694SGreg Roach            'HEAD:_SCHEMA:*:*:*:*:_DEFN'      => new EmptyElement(I18N::translate('Definition')),
132600c92694SGreg Roach            'HEAD:_SCHEMA:*:*:*:_DEFN'        => new EmptyElement(I18N::translate('Definition')),
132700c92694SGreg Roach            'HEAD:_SCHEMA:*:*:_DEFN'          => new EmptyElement(I18N::translate('Definition')),
13284c10b11dSGreg Roach            'INDI:*:ADDR:_NAME'               => new CustomElement(I18N::translate('Name of addressee')),
132900c92694SGreg Roach            // I18N: https://gov.genealogy.net
133000c92694SGreg Roach            'INDI:*:PLAC:_GOV'                => new GovIdentifier(I18N::translate('GOV identifier')),
133100c92694SGreg Roach            'INDI:*:PLAC:_LOC'                => new XrefLocation(I18N::translate('Location')),
133200c92694SGreg Roach            // I18N: https://en.wikipedia.org/wiki/Maidenhead_Locator_System
133300c92694SGreg Roach            'INDI:*:PLAC:_MAIDENHEAD'         => new MaidenheadLocator(I18N::translate('Maidenhead location code')),
13344c10b11dSGreg Roach            'INDI:*:PLAC:_POST'               => new AddressPostalCode(I18N::translate('Postal code')),
133500c92694SGreg Roach            'INDI:*:PLAC:_POST:DATE'          => new DateValue(I18N::translate('Date')),
133600c92694SGreg Roach            'INDI:*:_ASSO'                    => new XrefAssociate(I18N::translate('Associate')),
133700c92694SGreg Roach            'INDI:*:_ASSO:NOTE'               => new NoteStructure(I18N::translate('Note')),
133800c92694SGreg Roach            'INDI:*:_ASSO:RELA'               => new RelationIsDescriptor(I18N::translate('Relationship')),
133900c92694SGreg Roach            'INDI:*:_ASSO:SOUR'               => new XrefSource(I18N::translate('Source citation')),
134000c92694SGreg Roach            'INDI:*:_ASSO:SOUR:DATA'          => new SourceData(I18N::translate('Data')),
1341352bd396SGreg Roach            'INDI:*:_ASSO:SOUR:DATA:DATE'     => new DateValue(I18N::translate('Date of entry in original source')),
134200c92694SGreg Roach            'INDI:*:_ASSO:SOUR:DATA:TEXT'     => new TextFromSource(I18N::translate('Text')),
134300c92694SGreg Roach            'INDI:*:_ASSO:SOUR:EVEN'          => new EventTypeCitedFrom(I18N::translate('Event')),
134400c92694SGreg Roach            'INDI:*:_ASSO:SOUR:EVEN:ROLE'     => new RoleInEvent(I18N::translate('Role')),
134500c92694SGreg Roach            'INDI:*:_ASSO:SOUR:NOTE'          => new NoteStructure(I18N::translate('Note')),
134600c92694SGreg Roach            'INDI:*:_ASSO:SOUR:OBJE'          => new XrefMedia(I18N::translate('Media object')),
134700c92694SGreg Roach            'INDI:*:_ASSO:SOUR:PAGE'          => new WhereWithinSource(I18N::translate('Citation details')),
134800c92694SGreg Roach            'INDI:*:_ASSO:SOUR:QUAY'          => new CertaintyAssessment(I18N::translate('Quality of data')),
13494c10b11dSGreg Roach            'INDI:*:_WITN'                    => new CustomElement(I18N::translate('Witnesses')),
13504c10b11dSGreg Roach            'INDI:BAPM:_GODP'                 => new CustomElement(I18N::translate('Godparents')),
13514c10b11dSGreg Roach            'INDI:CHR:_GODP'                  => new CustomElement(I18N::translate('Godparents')),
135200c92694SGreg Roach            'INDI:NAME:_RUFNAME'              => new NamePieceGiven(I18N::translate('Rufname')),
135300c92694SGreg Roach            'INDI:OBJE:_PRIM'                 => new CustomElement(I18N::translate('Highlighted image')),
135400c92694SGreg Roach            'INDI:SEX'                        => new SexXValue(I18N::translate('Gender')),
135500c92694SGreg Roach            'INDI:_TODO'                      => new ResearchTask(I18N::translate('Research task')),
135600c92694SGreg Roach            'INDI:_TODO:DATA'                 => new SubmitterText(I18N::translate('The solution')),
135700c92694SGreg Roach            'INDI:_TODO:DATE'                 => new DateValue(I18N::translate('Creation date')),
135800c92694SGreg Roach            'INDI:_TODO:DESC'                 => new CustomElement(I18N::translate('Description')),
1359afb53502SGreg Roach            'INDI:_TODO:NOTE'                 => new NoteStructure(I18N::translate('Note')),
13604c10b11dSGreg Roach            'INDI:_TODO:REPO'                 => new XrefRepository(I18N::translate('Repository'), []),
136100c92694SGreg Roach            'INDI:_TODO:STAT'                 => new ResearchTaskStatus(I18N::translate('Status')),
136200c92694SGreg Roach            'INDI:_TODO:TYPE'                 => new ResearchTaskType(I18N::translate('Type of research task')),
136300c92694SGreg Roach            'INDI:_TODO:_CAT'                 => new CustomElement(I18N::translate('Category')),
136400c92694SGreg Roach            'INDI:_TODO:_CDATE'               => new DateValue(I18N::translate('Completion date')),
136500c92694SGreg Roach            'INDI:_TODO:_PRTY'                => new ResearchTaskPriority(I18N::translate('Priority')),
136600c92694SGreg Roach            'INDI:_TODO:_RDATE'               => new DateValue(I18N::translate('Reminder date')),
136700c92694SGreg Roach            'INDI:_UID'                       => new PafUid(I18N::translate('Unique identifier')),
136800c92694SGreg Roach            'NOTE:_UID'                       => new PafUid(I18N::translate('Unique identifier')),
136900c92694SGreg Roach            'OBJE:FILE:_PRIM'                 => new CustomElement(I18N::translate('Highlighted image')),
137000c92694SGreg Roach            'OBJE:_UID'                       => new PafUid(I18N::translate('Unique identifier')),
13714c10b11dSGreg Roach            'REPO:ADDR:_NAME'                 => new CustomElement(I18N::translate('Name of addressee')),
137200c92694SGreg Roach            'REPO:_UID'                       => new PafUid(I18N::translate('Unique identifier')),
137300c92694SGreg Roach            'SOUR:_UID'                       => new PafUid(I18N::translate('Unique identifier')),
1374b0a20e09SRichard Cissée            'SOUR:DATA:EVEN:PLAC:_LOC'        => new XrefLocation(I18N::translate('Location')),
1375b0a20e09SRichard Cissée            // I18N: https://en.wikipedia.org/wiki/Maidenhead_Locator_System
1376b0a20e09SRichard Cissée            'SOUR:DATA:EVEN:PLAC:_MAIDENHEAD' => new MaidenheadLocator(I18N::translate('Maidenhead location code')),
13774c10b11dSGreg Roach            'SOUR:DATA:EVEN:PLAC:_POST'       => new AddressPostalCode(I18N::translate('Postal code')),
1378b0a20e09SRichard Cissée            'SOUR:DATA:EVEN:PLAC:_POST:DATE'  => new DateValue(I18N::translate('Date')),
13794c10b11dSGreg Roach            'SUBM:ADDR:_NAME'                 => new CustomElement(I18N::translate('Name of addressee')),
138000c92694SGreg Roach            'SUBM:_UID'                       => new PafUid(I18N::translate('Unique identifier')),
138100c92694SGreg Roach            'SUBN:_UID'                       => new PafUid(I18N::translate('Unique identifier')),
138200c92694SGreg Roach            '_LOC'                            => new LocationRecord(I18N::translate('Location')),
138300c92694SGreg Roach            '_LOC:CHAN'                       => new Change(I18N::translate('Last change')),
138400c92694SGreg Roach            '_LOC:CHAN:DATE'                  => new ChangeDate(I18N::translate('Date of last change')),
1385701f5d18SGreg Roach            '_LOC:CHAN:DATE:TIME'             => new TimeValue(I18N::translate('Time of last change')),
138600c92694SGreg Roach            '_LOC:CHAN:NOTE'                  => new NoteStructure(I18N::translate('Note')),
138700c92694SGreg Roach            '_LOC:EVEN'                       => new CustomEvent(I18N::translate('Event')),
138800c92694SGreg Roach            '_LOC:EVEN:DATE'                  => new DateValue(I18N::translate('Date of event')),
138900c92694SGreg Roach            '_LOC:EVEN:PLAC'                  => new PlaceName(I18N::translate('Place of event')),
139000c92694SGreg Roach            '_LOC:EVEN:PLAC:FONE'             => new PlacePhoneticVariation(I18N::translate('Phonetic place')),
139100c92694SGreg Roach            '_LOC:EVEN:PLAC:FONE:TYPE'        => new PhoneticType(I18N::translate('Type')),
139200c92694SGreg Roach            '_LOC:EVEN:PLAC:FORM'             => new PlaceHierarchy(I18N::translate('Format')),
139300c92694SGreg Roach            '_LOC:EVEN:PLAC:MAP'              => new EmptyElement(I18N::translate('Coordinates'), ['LATI' => '1:1', 'LONG' => '1:1']),
139400c92694SGreg Roach            '_LOC:EVEN:PLAC:MAP:LATI'         => new PlaceLatitude(I18N::translate('Latitude')),
139500c92694SGreg Roach            '_LOC:EVEN:PLAC:MAP:LONG'         => new PlaceLongtitude(I18N::translate('Longitude')),
139600c92694SGreg Roach            '_LOC:EVEN:PLAC:NOTE'             => new NoteStructure(I18N::translate('Note')),
139700c92694SGreg Roach            '_LOC:EVEN:PLAC:ROMN'             => new PlaceRomanizedVariation(I18N::translate('Romanized place')),
139800c92694SGreg Roach            '_LOC:EVEN:PLAC:ROMN:TYPE'        => new RomanizedType(I18N::translate('Type')),
1399fd586be4SGreg Roach            '_LOC:EVEN:PLAC:_LOC'             => new XrefLocation(I18N::translate('Location')),
140000c92694SGreg Roach            '_LOC:EVEN:TYPE'                  => new EventAttributeType(I18N::translate('Type of event')),
140100c92694SGreg Roach            '_LOC:EVEN:AGNC'                  => new ResponsibleAgency(I18N::translate('Agency')),
140200c92694SGreg Roach            '_LOC:EVEN:ADDR'                  => new AddressLine(I18N::translate('Address')),
140300c92694SGreg Roach            '_LOC:EVEN:ADDR:ADR1'             => new AddressLine1(I18N::translate('Address line 1')),
140400c92694SGreg Roach            '_LOC:EVEN:ADDR:ADR2'             => new AddressLine2(I18N::translate('Address line 2')),
140500c92694SGreg Roach            '_LOC:EVEN:ADDR:ADR3'             => new AddressLine3(I18N::translate('Address line 3')),
140600c92694SGreg Roach            '_LOC:EVEN:ADDR:CITY'             => new AddressCity(I18N::translate('City')),
140700c92694SGreg Roach            '_LOC:EVEN:ADDR:CTRY'             => new AddressCountry(I18N::translate('Country')),
140800c92694SGreg Roach            '_LOC:EVEN:ADDR:POST'             => new AddressPostalCode(I18N::translate('Postal code')),
140900c92694SGreg Roach            '_LOC:EVEN:ADDR:STAE'             => new AddressState(I18N::translate('State')),
141000c92694SGreg Roach            '_LOC:EVEN:CAUS'                  => new CauseOfEvent(I18N::translate('Cause')),
141100c92694SGreg Roach            '_LOC:EVEN:RELI'                  => new ReligiousAffiliation(I18N::translate('Religion'), []),
141200c92694SGreg Roach            '_LOC:EVEN:RESN'                  => new RestrictionNotice(I18N::translate('Restriction')),
141300c92694SGreg Roach            '_LOC:EVEN:SOUR'                  => new XrefSource(I18N::translate('Source citation')),
141400c92694SGreg Roach            '_LOC:EVEN:NOTE'                  => new NoteStructure(I18N::translate('Note')),
141500c92694SGreg Roach            '_LOC:EVEN:OBJE'                  => new XrefMedia(I18N::translate('Media object')),
141600c92694SGreg Roach            '_LOC:MAP'                        => new EmptyElement(I18N::translate('Coordinates'), ['LATI' => '1:1', 'LONG' => '1:1']),
141700c92694SGreg Roach            '_LOC:MAP:LATI'                   => new PlaceLatitude(I18N::translate('Latitude')),
141800c92694SGreg Roach            '_LOC:MAP:LONG'                   => new PlaceLongtitude(I18N::translate('Longitude')),
141900c92694SGreg Roach            '_LOC:NAME'                       => new PlaceName(I18N::translate('Place'), ['ABBR' => '0:1', 'DATE' => '0:1', 'LANG' => '0:1', 'SOUR' => '0:M']),
142000c92694SGreg Roach            '_LOC:NAME:ABBR'                  => new CustomElement(I18N::translate('Abbreviation')),
142100c92694SGreg Roach            '_LOC:NAME:ABBR:TYPE'             => new CustomElement(I18N::translate('Type of abbreviation')),
142200c92694SGreg Roach            '_LOC:NAME:DATE'                  => new DateValue(I18N::translate('Date')),
142300c92694SGreg Roach            '_LOC:NAME:LANG'                  => new LanguageId(I18N::translate('Language')),
142400c92694SGreg Roach            '_LOC:NAME:SOUR'                  => new XrefSource(I18N::translate('Source')),
142500c92694SGreg Roach            '_LOC:NOTE'                       => new NoteStructure(I18N::translate('Note')),
142600c92694SGreg Roach            '_LOC:OBJE'                       => new XrefMedia(I18N::translate('Media')),
14274c10b11dSGreg Roach            '_LOC:RELI'                       => new ReligiousAffiliation(I18N::translate('Religion'), []),
142800c92694SGreg Roach            '_LOC:SOUR'                       => new XrefSource(I18N::translate('Source')),
142900c92694SGreg Roach            '_LOC:SOUR:DATA'                  => new SourceData(I18N::translate('Data')),
1430352bd396SGreg Roach            '_LOC:SOUR:DATA:DATE'             => new DateValue(I18N::translate('Date of entry in original source')),
143100c92694SGreg Roach            '_LOC:SOUR:DATA:TEXT'             => new TextFromSource(I18N::translate('Text')),
143200c92694SGreg Roach            '_LOC:SOUR:EVEN'                  => new EventTypeCitedFrom(I18N::translate('Event')),
143300c92694SGreg Roach            '_LOC:SOUR:EVEN:ROLE'             => new RoleInEvent(I18N::translate('Role')),
143400c92694SGreg Roach            '_LOC:SOUR:NOTE'                  => new NoteStructure(I18N::translate('Note')),
143500c92694SGreg Roach            '_LOC:SOUR:OBJE'                  => new XrefMedia(I18N::translate('Media object')),
143600c92694SGreg Roach            '_LOC:SOUR:PAGE'                  => new WhereWithinSource(I18N::translate('Citation details')),
143700c92694SGreg Roach            '_LOC:SOUR:QUAY'                  => new CertaintyAssessment(I18N::translate('Quality of data')),
143800c92694SGreg Roach            '_LOC:TYPE'                       => new CustomElement(I18N::translate('Type of location'), ['DATE' => '0:1', '_GOVTYPE' => '0:1', 'SOUR' => '0:M']),
143900c92694SGreg Roach            '_LOC:TYPE:DATE'                  => new DateValue(I18N::translate('Date')),
144000c92694SGreg Roach            '_LOC:TYPE:SOUR'                  => new XrefSource(I18N::translate('Source')),
14414c10b11dSGreg Roach            '_LOC:TYPE:_GOVTYPE'              => new CustomElement(I18N::translate('GOV identifier type')),
14424c10b11dSGreg Roach            '_LOC:_AIDN'                      => new CustomElement(I18N::translate('Administrative ID')),
144300c92694SGreg Roach            '_LOC:_AIDN:DATE'                 => new DateValue(I18N::translate('Date')),
144400c92694SGreg Roach            '_LOC:_AIDN:SOUR'                 => new XrefSource(I18N::translate('Source')),
144500c92694SGreg Roach            '_LOC:_AIDN:TYPE'                 => new CustomElement(I18N::translate('Type of administrative ID')),
14464c10b11dSGreg Roach            '_LOC:_DMGD'                      => new CustomElement(I18N::translate('Demographic data')),
144700c92694SGreg Roach            '_LOC:_DMGD:DATE'                 => new DateValue(I18N::translate('Date')),
144800c92694SGreg Roach            '_LOC:_DMGD:SOUR'                 => new XrefSource(I18N::translate('Source')),
144900c92694SGreg Roach            '_LOC:_DMGD:TYPE'                 => new CustomElement(I18N::translate('Type of demographic data')),
145000c92694SGreg Roach            // I18N: https://gov.genealogy.net
145100c92694SGreg Roach            '_LOC:_GOV'                       => new GovIdentifier(I18N::translate('GOV identifier')),
1452cbecd0bdSGreg Roach            '_LOC:_LOC'                       => new XrefLocation(I18N::translate('Parent location'), ['DATE' => '0:1', 'SOUR' => '0:M', 'TYPE' => '0:1']),
145300c92694SGreg Roach            '_LOC:_LOC:DATE'                  => new DateValue(I18N::translate('Date')),
145400c92694SGreg Roach            '_LOC:_LOC:SOUR'                  => new XrefSource(I18N::translate('Source')),
145500c92694SGreg Roach            '_LOC:_LOC:TYPE'                  => new HierarchicalRelationship(I18N::translate('Hierarchical relationship')),
145600c92694SGreg Roach            // I18N: https://en.wikipedia.org/wiki/Maidenhead_Locator_System
145700c92694SGreg Roach            '_LOC:_MAIDENHEAD'                => new MaidenheadLocator(I18N::translate('Maidenhead location code')),
145800c92694SGreg Roach            '_LOC:_POST'                      => new AddressPostalCode(I18N::translate('Postal code')),
145900c92694SGreg Roach            '_LOC:_POST:DATE'                 => new DateValue(I18N::translate('Date')),
146000c92694SGreg Roach            '_LOC:_POST:SOUR'                 => new XrefSource(I18N::translate('Source')),
146100c92694SGreg Roach            '_LOC:_UID'                       => new PafUid(I18N::translate('Unique identifier')),
146200c92694SGreg Roach            '_LOC:*:SOUR:DATA'                => new SourceData(I18N::translate('Data')),
1463352bd396SGreg Roach            '_LOC:*:SOUR:DATA:DATE'           => new DateValue(I18N::translate('Date of entry in original source')),
146400c92694SGreg Roach            '_LOC:*:SOUR:DATA:TEXT'           => new TextFromSource(I18N::translate('Text')),
146500c92694SGreg Roach            '_LOC:*:SOUR:EVEN'                => new EventTypeCitedFrom(I18N::translate('Event')),
146600c92694SGreg Roach            '_LOC:*:SOUR:EVEN:ROLE'           => new RoleInEvent(I18N::translate('Role')),
146700c92694SGreg Roach            '_LOC:*:SOUR:NOTE'                => new NoteStructure(I18N::translate('Note')),
146800c92694SGreg Roach            '_LOC:*:SOUR:OBJE'                => new XrefMedia(I18N::translate('Media object')),
146900c92694SGreg Roach            '_LOC:*:SOUR:PAGE'                => new WhereWithinSource(I18N::translate('Citation details')),
147000c92694SGreg Roach            '_LOC:*:SOUR:QUAY'                => new CertaintyAssessment(I18N::translate('Quality of data')),
147100c92694SGreg Roach        ];
147200c92694SGreg Roach    }
147300c92694SGreg Roach
147400c92694SGreg Roach    /**
147500c92694SGreg Roach     * @return array<string,ElementInterface>
147600c92694SGreg Roach     */
1477b9a9ffe2SGreg Roach    private function geneatique(): array
1478b9a9ffe2SGreg Roach    {
1479b9a9ffe2SGreg Roach        return [
1480f15544dcSGreg Roach            'INDI:DEAT:DATE:TIME' => new TimeValue(I18N::translate('Time of death')),
1481eae6f507SGreg Roach            'OBJE:FORM'           => new MultimediaFormat(I18N::translate('Format')),
1482eae6f507SGreg Roach            'OBJE:TITL'           => new DescriptiveTitle(I18N::translate('Title')),
1483eae6f507SGreg Roach            'INDI:NAME:_AKA'      => new NamePersonal(I18N::translate('Also known as'), []),
1484eae6f507SGreg Roach            'INDI:NAME:_MARNM'    => new NamePersonal(I18N::translate('Also known as'), []),
1485f15544dcSGreg Roach
1486b9a9ffe2SGreg Roach            /*
1487b9a9ffe2SGreg Roach            Pour déclarer les témoins dans les actes de naissance
1488b9a9ffe2SGreg Roach
1489b9a9ffe2SGreg Roach            Balise GEDCOM non valide. INDI:BIRT:ASSO
1490b9a9ffe2SGreg Roach            INDI:BIRT:ASSO:TYPE
1491b9a9ffe2SGreg Roach            INDI:BIRT:ASSO:RELA
1492b9a9ffe2SGreg Roach            INDI:DEAT:PLAC:QUAY
1493b9a9ffe2SGreg Roach            INDI:BIRT:OBJE:QUAY
1494b9a9ffe2SGreg Roach            INDI:BIRT:SOUR:TEXT
1495b9a9ffe2SGreg Roach
1496b9a9ffe2SGreg Roach            Dans les mariages
1497b9a9ffe2SGreg Roach
1498b9a9ffe2SGreg Roach            FAM:MARR:ASSO
1499b9a9ffe2SGreg Roach            FAM:MARR:ASSO:TYPE
1500b9a9ffe2SGreg Roach            FAM:MARR:ASSO:RELA
1501b9a9ffe2SGreg Roach            FAM:MARR:WWW:QUAY
1502b9a9ffe2SGreg Roach            OBJE:WWW
1503b9a9ffe2SGreg Roach            OBJE:SOUR:TEXTHTTPS
1504b9a9ffe2SGreg Roach            OBJE:NOTE:WWW
1505b9a9ffe2SGreg Roach            SOUR:QUAY
1506b9a9ffe2SGreg Roach            SOUR:TYPE
1507b9a9ffe2SGreg Roach            */
1508b9a9ffe2SGreg Roach        ];
1509b9a9ffe2SGreg Roach    }
1510b9a9ffe2SGreg Roach
1511b9a9ffe2SGreg Roach    /**
1512b9a9ffe2SGreg Roach     * @return array<string,ElementInterface>
1513b9a9ffe2SGreg Roach     */
151400c92694SGreg Roach    private function genPlusWinTags(): array
151500c92694SGreg Roach    {
151600c92694SGreg Roach        return [
151700c92694SGreg Roach            'FAM:*:ADDR:_NUM'         => new CustomElement(I18N::translate('House number')),
151800c92694SGreg Roach            'FAM:*:ADDR:_STRASSE'     => new CustomElement(I18N::translate('Street name')),
151900c92694SGreg Roach            'FAM:*:DATE:_ZUS'         => new CustomElement(I18N::translate('Additional information')),
152000c92694SGreg Roach            'FAM:*:OBJE:_PRIM'        => new CustomElement(I18N::translate('Highlighted image')),
152100c92694SGreg Roach            'FAM:*:PLAC:_AON'         => new CustomElement(I18N::translate('Alternative place name')),
152200c92694SGreg Roach            // I18N: https://foko.genealogy.net
152300c92694SGreg Roach            'FAM:*:PLAC:_FCTRY'       => new CustomElement(I18N::translate('FOKO country')),
152400c92694SGreg Roach            // I18N: https://foko.genealogy.net
152500c92694SGreg Roach            'FAM:*:PLAC:_FSTAE'       => new CustomElement(I18N::translate('FOKO country')),
152600c92694SGreg Roach            // I18N: https://gov.genealogy.net
152700c92694SGreg Roach            'FAM:*:PLAC:_GOV'         => new GovIdentifier(I18N::translate('GOV identifier')),
152800c92694SGreg Roach            // I18N: https://en.wikipedia.org/wiki/Maidenhead_Locator_System
152900c92694SGreg Roach            'FAM:*:PLAC:_MAIDENHEAD'  => new MaidenheadLocator(I18N::translate('Maidenhead location code')),
153000c92694SGreg Roach            'FAM:*:PLAC:_POST'        => new AddressPostalCode(I18N::translate('Postal code')),
153100c92694SGreg Roach            'FAM:*:PLAC:_SIC'         => new CustomElement(I18N::translate('Reliability of the information')),
153200c92694SGreg Roach            'FAM:*:PLAC:_ZUS'         => new CustomElement(I18N::translate('Additional information')),
153300c92694SGreg Roach            'FAM:*:SOUR:_ORI'         => new TextFromSource(I18N::translate('Original text')),
153400c92694SGreg Roach            'FAM:*:SOUR:_ZUS'         => new CustomElement(I18N::translate('Additional information')),
153500c92694SGreg Roach            'FAM:*:SOUR:PAGE:_ZUS'    => new CustomElement(I18N::translate('Additional information')),
153600c92694SGreg Roach            'FAM:*:_ASSO'             => new XrefAssociate(I18N::translate('Associate')),
153700c92694SGreg Roach            'FAM:*:_CERT'             => new CustomElement(I18N::translate('Certificate number')),
153800c92694SGreg Roach            'FAM:*:_COM'              => new CustomElement(I18N::translate('Comment')),
153900c92694SGreg Roach            'FAM:*:_SITE'             => new CustomElement(I18N::translate('Extra information')),
15401c2da29dSRichard Cissée            'FAM:*:_WITN'             => new CustomElement(I18N::translate('Witnesses')),
154100c92694SGreg Roach            'FAM:OBJE:_PRIM'          => new CustomElement(I18N::translate('Highlighted image')),
154200c92694SGreg Roach            'FAM:SOUR:_ORI'           => new TextFromSource(I18N::translate('Original text')),
154300c92694SGreg Roach            'FAM:SOUR:_ZUS'           => new CustomElement(I18N::translate('Additional information')),
154400c92694SGreg Roach            'FAM:SOUR:PAGE:_ZUS'      => new CustomElement(I18N::translate('Additional information')),
154500c92694SGreg Roach            'FAM:_CREAT'              => new DateValue(I18N::translate('Creation date')),
154600c92694SGreg Roach            'FAM:_LIV'                => new CustomElement(I18N::translate('Cohabitation')),
154700c92694SGreg Roach            'FAM:_NAME'               => new CustomElement(I18N::translate('Joint family name')),
154800c92694SGreg Roach            'FAM:_UID'                => new PafUid(I18N::translate('Unique identifier')),
154900c92694SGreg Roach            'INDI:*:ADDR:_NUM'        => new CustomElement(I18N::translate('House number')),
155000c92694SGreg Roach            'INDI:*:ADDR:_STRASSE'    => new CustomElement(I18N::translate('Street name')),
155100c92694SGreg Roach            'INDI:*:DATE:_ZUS'        => new CustomElement(I18N::translate('Additional information')),
155200c92694SGreg Roach            'INDI:*:OBJE:_PRIM'       => new CustomElement(I18N::translate('Highlighted image')),
155300c92694SGreg Roach            'INDI:*:PLAC:_AON'        => new CustomElement(I18N::translate('Alternative place name')),
155400c92694SGreg Roach            // I18N: https://foko.genealogy.net
155500c92694SGreg Roach            'INDI:*:PLAC:_FCTRY'      => new CustomElement(I18N::translate('FOKO country')),
155600c92694SGreg Roach            // I18N: https://foko.genealogy.net
155700c92694SGreg Roach            'INDI:*:PLAC:_FSTAE'      => new CustomElement(I18N::translate('FOKO country')),
155800c92694SGreg Roach            // I18N: https://gov.genealogy.net
155900c92694SGreg Roach            'INDI:*:PLAC:_GOV'        => new GovIdentifier(I18N::translate('GOV identifier')),
156000c92694SGreg Roach            // I18N: https://en.wikipedia.org/wiki/Maidenhead_Locator_System
156100c92694SGreg Roach            'INDI:*:PLAC:_MAIDENHEAD' => new MaidenheadLocator(I18N::translate('Maidenhead location code')),
156200c92694SGreg Roach            'INDI:*:PLAC:_POST'       => new AddressPostalCode(I18N::translate('Postal code')),
156300c92694SGreg Roach            'INDI:*:PLAC:_SIC'        => new CustomElement(I18N::translate('Reliability of the information')),
156400c92694SGreg Roach            'INDI:*:PLAC:_ZUS'        => new CustomElement(I18N::translate('Additional information')),
156500c92694SGreg Roach            'INDI:*:SOUR:_ORI'        => new TextFromSource(I18N::translate('Original text')),
156600c92694SGreg Roach            'INDI:*:SOUR:_ZUS'        => new CustomElement(I18N::translate('Additional information')),
156700c92694SGreg Roach            'INDI:*:SOUR:PAGE:_ZUS'   => new CustomElement(I18N::translate('Additional information')),
156800c92694SGreg Roach            'INDI:*:_ASSO'            => new XrefAssociate(I18N::translate('Associate')),
156900c92694SGreg Roach            'INDI:*:_CERT'            => new CustomElement(I18N::translate('Certificate number')),
157000c92694SGreg Roach            'INDI:*:_COM'             => new CustomElement(I18N::translate('Comment')),
157100c92694SGreg Roach            'INDI:*:_SITE'            => new CustomElement(I18N::translate('Extra information')),
15721c2da29dSRichard Cissée            'INDI:*:_WITN'            => new CustomElement(I18N::translate('Witnesses')),
15731c2da29dSRichard Cissée            'INDI:BAPM:_GODP'         => new CustomElement(I18N::translate('Godparents')),
15741c2da29dSRichard Cissée            'INDI:CHR:_GODP'          => new CustomElement(I18N::translate('Godparents')),
157500c92694SGreg Roach            'INDI:OBJE:_PRIM'         => new CustomElement(I18N::translate('Highlighted image')),
157600c92694SGreg Roach            'INDI:SOUR:_ORI'          => new TextFromSource(I18N::translate('Original text')),
157700c92694SGreg Roach            'INDI:SOUR:_ZUS'          => new CustomElement(I18N::translate('Additional information')),
157800c92694SGreg Roach            'INDI:SOUR:PAGE:_ZUS'     => new CustomElement(I18N::translate('Additional information')),
157900c92694SGreg Roach            'INDI:NAME:_AKA'          => new CustomElement(I18N::translate('Also known as')),
158000c92694SGreg Roach            // https://en.wikipedia.org/wiki/Rufname
158100c92694SGreg Roach            'INDI:NAME:RUFN'          => new CustomElement(I18N::translate('Rufname')),
158200c92694SGreg Roach            'INDI:_CREAT'             => new CustomElement(I18N::translate('Creation date')),
158300c92694SGreg Roach            'INDI:_HEIM'              => new CustomElement(/* I18N: German Bürgerort */ I18N::translate('Place of citizenship')),
158400c92694SGreg Roach            'INDI:_UID'               => new PafUid(I18N::translate('Unique identifier')),
158500c92694SGreg Roach            'NOTE:_CREAT'             => new DateValue(I18N::translate('Creation date')),
158600c92694SGreg Roach            'NOTE:_UID'               => new PafUid(I18N::translate('Unique identifier')),
158700c92694SGreg Roach            'OBJE:_CREAT'             => new DateValue(I18N::translate('Creation date')),
158800c92694SGreg Roach            'OBJE:_UID'               => new PafUid(I18N::translate('Unique identifier')),
158900c92694SGreg Roach            'REPO:_CREAT'             => new DateValue(I18N::translate('Creation date')),
159000c92694SGreg Roach            'REPO:_UID'               => new PafUid(I18N::translate('Unique identifier')),
159100c92694SGreg Roach            'SOUR:_CREAT'             => new DateValue(I18N::translate('Creation date')),
159200c92694SGreg Roach            'SOUR:_KTIT'              => new SourceFiledByEntry(I18N::translate('Abbreviation')),
159300c92694SGreg Roach            'SOUR:_UID'               => new PafUid(I18N::translate('Unique identifier')),
159400c92694SGreg Roach        ];
159500c92694SGreg Roach    }
159600c92694SGreg Roach
159700c92694SGreg Roach    /**
1598b9a9ffe2SGreg Roach     * @return array<string,ElementInterface>
1599b9a9ffe2SGreg Roach     */
1600b9a9ffe2SGreg Roach    private function heredis(): array
1601b9a9ffe2SGreg Roach    {
1602b9a9ffe2SGreg Roach        return [
1603b9a9ffe2SGreg Roach            'INDI:SIGN'                   => new CustomElement(I18N::translate('Signature')),
1604b9a9ffe2SGreg Roach            /* Reported on the forum - but what do they mean?
1605b9a9ffe2SGreg Roach            'INDI:_FIL'                   => new CustomElement(I18N::translate('???')),
1606b9a9ffe2SGreg Roach            'INDI:*:_FNA'                 => new CustomElement(I18N::translate('???')),
1607b9a9ffe2SGreg Roach            'INDI:????:????:_SUBMAP'      => new EmptyElement(I18N::translate('Coordinates'), ['INDI' => '1:1', 'LONG' => '1:1']),
1608b9a9ffe2SGreg Roach            'INDI:????:????:_SUBMAP:LATI' => new PlaceLatitude(I18N::translate('Latitude')),
1609b9a9ffe2SGreg Roach            'INDI:????:????:_SUBMAP:LONG' => new PlaceLongtitude(I18N::translate('Longitude')),
1610b9a9ffe2SGreg Roach            */
1611b9a9ffe2SGreg Roach        ];
1612b9a9ffe2SGreg Roach    }
1613b9a9ffe2SGreg Roach
1614b9a9ffe2SGreg Roach    /**
161500c92694SGreg Roach     * @see http://support.legacyfamilytree.com/article/AA-00520/0/GEDCOM-Files-custom-tags-in-Legacy.html
161600c92694SGreg Roach     *
161700c92694SGreg Roach     * @return array<string,ElementInterface>
161800c92694SGreg Roach     */
161900c92694SGreg Roach    private function legacyTags(): array
162000c92694SGreg Roach    {
162100c92694SGreg Roach        return [
162200c92694SGreg Roach            'FAM:*:ADDR:_PRIV'             => new CustomElement(I18N::translate('Private')),
162300c92694SGreg Roach            'FAM:*:PLAC:_VERI'             => new CustomElement(I18N::translate('Verified')),
1624082e1164SGreg Roach            'FAM:*:SOUR:DATE'              => new DateValue(I18N::translate('Date')),
162500c92694SGreg Roach            'FAM:*:SOUR:_VERI'             => new CustomElement(I18N::translate('Verified')),
162600c92694SGreg Roach            'FAM:*:_PRIV'                  => new CustomElement(I18N::translate('Private')),
162700c92694SGreg Roach            'FAM:CHIL:_FREL'               => new CustomElement(I18N::translate('Relationship to father')),
162800c92694SGreg Roach            'FAM:CHIL:_MREL'               => new CustomElement(I18N::translate('Relationship to mother')),
162900c92694SGreg Roach            'FAM:CHIL:_STAT'               => new CustomElement(I18N::translate('Status')),
163000c92694SGreg Roach            'FAM:EVEN:_OVER'               => new CustomElement('Event sentence override'),
1631082e1164SGreg Roach            'FAM:MARR:_HTITL'              => new CustomElement(I18N::translate('Label for husband')),
16328a093e2dSGreg Roach            'FAM:MARR:_RPT_PHRS'           => /* I18N: GEDCOM gag _RPT_PHRS */ new CustomElement(I18N::translate('Report phrase')),
16338a093e2dSGreg Roach            'FAM:MARR:_RPT_PHRS2'          => /* I18N: GEDCOM gag _RPT_PHRS */ new CustomElement(I18N::translate('Report phrase')),
163400c92694SGreg Roach            'FAM:MARR:_STAT'               => new CustomElement(I18N::translate('Status')),
1635082e1164SGreg Roach            'FAM:MARR:_WTITL'              => new CustomElement(I18N::translate('Label for wife')),
163600c92694SGreg Roach            'FAM:_NONE'                    => new CustomElement(I18N::translate('No children')),
1637082e1164SGreg Roach            'FAM:_TAG'                     => new CustomElement('Tag'),
1638082e1164SGreg Roach            'FAM:_TAG2'                    => new CustomElement('Tag #2'),
1639082e1164SGreg Roach            'FAM:_TAG3'                    => new CustomElement('Tag #3'),
1640082e1164SGreg Roach            'FAM:_TAG4'                    => new CustomElement('Tag #4'),
1641082e1164SGreg Roach            'FAM:_TAG5'                    => new CustomElement('Tag #5'),
1642082e1164SGreg Roach            'FAM:_TAG6'                    => new CustomElement('Tag #6'),
1643082e1164SGreg Roach            'FAM:_TAG7'                    => new CustomElement('Tag #7'),
1644082e1164SGreg Roach            'FAM:_TAG8'                    => new CustomElement('Tag #8'),
1645082e1164SGreg Roach            'FAM:_TAG9'                    => new CustomElement('Tag #9'),
164600c92694SGreg Roach            'FAM:_UID'                     => new PafUid(I18N::translate('Unique identifier')),
164700c92694SGreg Roach            'HEAD:_EVENT_DEFN'             => new CustomElement('Event definition'),
164800c92694SGreg Roach            'HEAD:_EVENT_DEFN:_CONF_FLAG'  => new CustomElement(I18N::translate('Private')),
164900c92694SGreg Roach            'HEAD:_EVENT_DEFN:_DATE_TYPE'  => new CustomElement(I18N::translate('Date')),
165000c92694SGreg Roach            'HEAD:_EVENT_DEFN:_DESC_FLAG'  => new CustomElement(I18N::translate('Description')),
165100c92694SGreg Roach            'HEAD:_EVENT_DEFN:_PLACE_TYPE' => new CustomElement(I18N::translate('Place')),
165200c92694SGreg Roach            'HEAD:_EVENT_DEFN:_PP_EXCLUDE' => new CustomElement('Exclude event from potential problems report'),
165300c92694SGreg Roach            'HEAD:_EVENT_DEFN:_SEN1'       => new CustomElement('Event sentence definition'),
165400c92694SGreg Roach            'HEAD:_EVENT_DEFN:_SEN2'       => new CustomElement('Event sentence definition'),
165500c92694SGreg Roach            'HEAD:_EVENT_DEFN:_SEN3'       => new CustomElement('Event sentence definition'),
165600c92694SGreg Roach            'HEAD:_EVENT_DEFN:_SEN4'       => new CustomElement('Event sentence definition'),
165700c92694SGreg Roach            'HEAD:_EVENT_DEFN:_SEN5'       => new CustomElement('Event sentence definition'),
165800c92694SGreg Roach            'HEAD:_EVENT_DEFN:_SEN6'       => new CustomElement('Event sentence definition'),
165900c92694SGreg Roach            'HEAD:_EVENT_DEFN:_SEN7'       => new CustomElement('Event sentence definition'),
166000c92694SGreg Roach            'HEAD:_EVENT_DEFN:_SEN8'       => new CustomElement('Event sentence definition'),
166100c92694SGreg Roach            'HEAD:_EVENT_DEFN:_SENDOF'     => new CustomElement('Event sentence, female, date only'),
166200c92694SGreg Roach            'HEAD:_EVENT_DEFN:_SENDOM'     => new CustomElement('Event sentence, male, date only'),
166300c92694SGreg Roach            'HEAD:_EVENT_DEFN:_SENDOU'     => new CustomElement('Event sentence, unknown sex, date only'),
166400c92694SGreg Roach            'HEAD:_EVENT_DEFN:_SENDPF'     => new CustomElement('Event sentence, female, date and place'),
166500c92694SGreg Roach            'HEAD:_EVENT_DEFN:_SENDPM'     => new CustomElement('Event sentence, male, date and place'),
166600c92694SGreg Roach            'HEAD:_EVENT_DEFN:_SENDPU'     => new CustomElement('Event sentence, unknown sex, date and place'),
166700c92694SGreg Roach            'HEAD:_EVENT_DEFN:_SENF'       => new CustomElement('Event sentence, female'),
166800c92694SGreg Roach            'HEAD:_EVENT_DEFN:_SENM'       => new CustomElement('Event sentence, male'),
166900c92694SGreg Roach            'HEAD:_EVENT_DEFN:_SENPOF'     => new CustomElement('Event sentence, unknown sex'),
167000c92694SGreg Roach            'HEAD:_EVENT_DEFN:_SENPOM'     => new CustomElement('Event sentence, female, place only'),
167100c92694SGreg Roach            'HEAD:_EVENT_DEFN:_SENPOU'     => new CustomElement('Event sentence, male, place only'),
167200c92694SGreg Roach            'HEAD:_EVENT_DEFN:_SENU'       => new CustomElement('Event sentence, unknown sex, place only'),
167300c92694SGreg Roach            'HEAD:_PLAC_DEFN'              => new CustomElement('Place definition'),
167400c92694SGreg Roach            'HEAD:_PLAC_DEFN:_PREP'        => new CustomElement('Place preposition'),
167500c92694SGreg Roach            'INDI:*:ADDR:_EMAIL'           => new CustomElement(I18N::translate('Email')),
167600c92694SGreg Roach            'INDI:*:ADDR:_LIST1'           => new CustomElement('Include in the “newsletter” group'),
167700c92694SGreg Roach            'INDI:*:ADDR:_LIST2'           => new CustomElement('Include in the “family association” group'),
167800c92694SGreg Roach            'INDI:*:ADDR:_LIST3'           => new CustomElement('Include in the “birthday” group'),
167900c92694SGreg Roach            'INDI:*:ADDR:_LIST4'           => new CustomElement('Include in the “research” group'),
168000c92694SGreg Roach            'INDI:*:ADDR:_LIST5'           => new CustomElement('Include in the “christmas” group'),
168100c92694SGreg Roach            'INDI:*:ADDR:_LIST6'           => new CustomElement('Include in the “holiday” group'),
168200c92694SGreg Roach            'INDI:*:ADDR:_NAME'            => new CustomElement(I18N::translate('Name of addressee')),
168300c92694SGreg Roach            'INDI:*:ADDR:_PRIV'            => new CustomElement(I18N::translate('Private')),
168400c92694SGreg Roach            'INDI:*:ADDR:_SORT'            => new CustomElement('The spelling of a name to be used when sorting addresses for a report'),
168500c92694SGreg Roach            'INDI:*:ADDR:_TAG'             => new CustomElement('Tag'),
168600c92694SGreg Roach            'INDI:*:PLAC:_TAG'             => new CustomElement('Tag'),
168700c92694SGreg Roach            'INDI:*:PLAC:_VERI'            => new CustomElement(I18N::translate('Verified')),
1688082e1164SGreg Roach            'INDI:*:SOUR:DATE'             => new DateValue(I18N::translate('Date')),
168900c92694SGreg Roach            'INDI:*:SOUR:_VERI'            => new CustomElement(I18N::translate('Verified')),
169000c92694SGreg Roach            'INDI:*:_PRIV'                 => new CustomElement(I18N::translate('Private')),
169100c92694SGreg Roach            'INDI:EVEN:_OVER'              => new CustomElement('Event sentence override'),
169200c92694SGreg Roach            'INDI:SOUR:_VERI'              => new CustomElement(I18N::translate('Verified')),
169300c92694SGreg Roach            'INDI:_TAG'                    => new CustomElement('Tag'),
169400c92694SGreg Roach            'INDI:_TAG2'                   => new CustomElement('Tag #2'),
169500c92694SGreg Roach            'INDI:_TAG3'                   => new CustomElement('Tag #3'),
169600c92694SGreg Roach            'INDI:_TAG4'                   => new CustomElement('Tag #4'),
169700c92694SGreg Roach            'INDI:_TAG5'                   => new CustomElement('Tag #5'),
169800c92694SGreg Roach            'INDI:_TAG6'                   => new CustomElement('Tag #6'),
169900c92694SGreg Roach            'INDI:_TAG7'                   => new CustomElement('Tag #7'),
170000c92694SGreg Roach            'INDI:_TAG8'                   => new CustomElement('Tag #8'),
170100c92694SGreg Roach            'INDI:_TAG9'                   => new CustomElement('Tag #9'),
170200c92694SGreg Roach            'INDI:_TODO'                   => new CustomElement(I18N::translate('Research task')),
170300c92694SGreg Roach            'INDI:_TODO:PRTY'              => new CustomElement(I18N::translate('Priority')),
170400c92694SGreg Roach            'INDI:_TODO:_CAT'              => new CustomElement(I18N::translate('Category')),
170500c92694SGreg Roach            'INDI:_TODO:_CDATE'            => new CustomElement(I18N::translate('Completion date')),
170600c92694SGreg Roach            'INDI:_TODO:_LOCL'             => new CustomElement(I18N::translate('Location')),
170700c92694SGreg Roach            'INDI:_TODO:_RDATE'            => new CustomElement(I18N::translate('Reminder date')),
170800c92694SGreg Roach            'INDI:_UID'                    => new PafUid(I18N::translate('Unique identifier')),
170900c92694SGreg Roach            'INDI:_URL'                    => new AddressWebPage(I18N::translate('URL')),
171000c92694SGreg Roach            'OBJE:_DATE'                   => new CustomElement(I18N::translate('Date')),
171100c92694SGreg Roach            'OBJE:_PRIM'                   => new CustomElement(I18N::translate('Highlighted image')),
171200c92694SGreg Roach            'OBJE:_SCBK'                   => new CustomElement(I18N::translate('Scrapbook')),
171300c92694SGreg Roach            'OBJE:_SOUND'                  => new CustomElement(I18N::translate('Audio')),
171400c92694SGreg Roach            'OBJE:_TYPE'                   => new CustomElement(I18N::translate('Type')),
171500c92694SGreg Roach            'OBJE:_UID'                    => new PafUid(I18N::translate('Unique identifier')),
171600c92694SGreg Roach            'REPO:_UID'                    => new PafUid(I18N::translate('Unique identifier')),
171700c92694SGreg Roach            'SOUR:_ITALIC'                 => new CustomElement('The source title should be printed in italic on reports'),
171800c92694SGreg Roach            'SOUR:_PAREN'                  => new CustomElement('The source title should be printed within parentheses on reports'),
171900c92694SGreg Roach            'SOUR:_QUOTED'                 => new CustomElement('The source title should be printed within quotes on reports'),
172000c92694SGreg Roach            'SOUR:_TAG'                    => new CustomElement('Exclude the source citation detail on reports'),
172100c92694SGreg Roach            'SOUR:_TAG2'                   => new CustomElement('Exclude the source citation on reports'),
172200c92694SGreg Roach            'SOUR:_TAG3'                   => new CustomElement('Include the source citation detail text on reports'),
172300c92694SGreg Roach            'SOUR:_TAG4'                   => new CustomElement('Include the source citation detail notes on reports'),
172400c92694SGreg Roach            'SOUR:_UID'                    => new PafUid(I18N::translate('Unique identifier')),
172500c92694SGreg Roach        ];
172600c92694SGreg Roach    }
172700c92694SGreg Roach
172800c92694SGreg Roach    /**
172900c92694SGreg Roach     * @return array<string,ElementInterface>
173000c92694SGreg Roach     */
173154671e98SGreg Roach    private function myHeritageTags(): array
173254671e98SGreg Roach    {
173354671e98SGreg Roach        return [
173454671e98SGreg Roach            'FAM:*:_UID'                  => new PafUid(I18N::translate('Unique identifier')),
173554671e98SGreg Roach            'FAM:*:RIN'                   => new AutomatedRecordId(I18N::translate('Record ID number')),
173654671e98SGreg Roach            'HEAD:DATE:_TIMEZONE'         => new CustomElement(I18N::translate('Time zone')),
173754671e98SGreg Roach            'HEAD:SOUR:_RTLSAVE'          => new CustomElement(I18N::translate('Text direction')), // ?
173854671e98SGreg Roach            'HEAD:_RINS'                  => new CustomElement(I18N::translate('Record ID number')), // ?
173954671e98SGreg Roach            'HEAD:_UID'                   => new PafUid(I18N::translate('Unique identifier')),
174054671e98SGreg Roach            'HEAD:_PROJECT_GUID'          => new PafUid(I18N::translate('Unique identifier')),
174154671e98SGreg Roach            'HEAD:_EXPORTED_FROM_SITE_ID' => new CustomElement(I18N::translate('Site identification code')),
174254671e98SGreg Roach            'HEAD:_DESCRIPTION_AWARE'     => new CustomElement(I18N::translate('Description')), // ?
174354671e98SGreg Roach            'INDI:*:_UID'                 => new PafUid(I18N::translate('Unique identifier')),
174454671e98SGreg Roach            'INDI:*:RIN'                  => new AutomatedRecordId(I18N::translate('Record ID number')),
174554671e98SGreg Roach            '*:_UPD'                      => new CustomElement(I18N::translate('Updated at')),
174654671e98SGreg Roach        ];
174754671e98SGreg Roach    }
174854671e98SGreg Roach
174954671e98SGreg Roach    /**
175054671e98SGreg Roach     * @return array<string,ElementInterface>
175154671e98SGreg Roach     */
175200c92694SGreg Roach    private function personalAncestralFileTags(): array
175300c92694SGreg Roach    {
175400c92694SGreg Roach        return [
175500c92694SGreg Roach            'FAM:_UID'        => new PafUid(I18N::translate('Unique identifier')),
175600c92694SGreg Roach            'INDI:NAME:_ADPN' => new NamePersonal(I18N::translate('Adopted name'), []),
175700c92694SGreg Roach            'INDI:NAME:_AKA'  => new NamePersonal(I18N::translate('Also known as'), []),
175800c92694SGreg Roach            'INDI:NAME:_AKAN' => new NamePersonal(I18N::translate('Also known as'), []),
175900c92694SGreg Roach            'INDI:ADDR'       => new AddressLine(I18N::translate('Address')),
176000c92694SGreg Roach            'INDI:ADDR:ADR1'  => new AddressLine1(I18N::translate('Address line 1')),
176100c92694SGreg Roach            'INDI:ADDR:ADR2'  => new AddressLine2(I18N::translate('Address line 2')),
176200c92694SGreg Roach            'INDI:ADDR:CITY'  => new AddressCity(I18N::translate('City')),
176300c92694SGreg Roach            'INDI:ADDR:CTRY'  => new AddressCountry(I18N::translate('Country')),
176400c92694SGreg Roach            'INDI:ADDR:POST'  => new AddressPostalCode(I18N::translate('Postal code')),
176500c92694SGreg Roach            'INDI:ADDR:STAE'  => new AddressState(I18N::translate('State')),
176600c92694SGreg Roach            'INDI:ADDR:_NAME' => new CustomElement(I18N::translate('Name of addressee')),
176700c92694SGreg Roach            'INDI:EMAIL'      => new AddressEmail(I18N::translate('Email address')),
176800c92694SGreg Roach            'INDI:FAX'        => new AddressFax(I18N::translate('Fax')),
176900c92694SGreg Roach            'INDI:PHON'       => new PhoneNumber(I18N::translate('Phone')),
177000c92694SGreg Roach            'INDI:URL'        => new CustomElement(I18N::translate('URL')),
177100c92694SGreg Roach            'INDI:_UID'       => new PafUid(I18N::translate('Unique identifier')),
177200c92694SGreg Roach            'OBJE:_UID'       => new PafUid(I18N::translate('Unique identifier')),
177300c92694SGreg Roach            'REPO:_UID'       => new PafUid(I18N::translate('Unique identifier')),
177400c92694SGreg Roach            'SOUR:_UID'       => new PafUid(I18N::translate('Unique identifier')),
177500c92694SGreg Roach        ];
177600c92694SGreg Roach    }
177700c92694SGreg Roach
177800c92694SGreg Roach    /**
177900c92694SGreg Roach     * @return array<string,ElementInterface>
178000c92694SGreg Roach     */
178100c92694SGreg Roach    private function phpGedViewTags(): array
178200c92694SGreg Roach    {
178300c92694SGreg Roach        return [
178400c92694SGreg Roach            'FAM:CHAN:_PGVU'        => new WebtreesUser(I18N::translate('Author of last change')),
178500c92694SGreg Roach            'FAM:COMM'              => new CustomElement(I18N::translate('Comment')),
178600c92694SGreg Roach            'INDI:*:ASSO'           => new XrefAssociate(I18N::translate('Associate')),
178700c92694SGreg Roach            'INDI:*:ASSO:RELA'      => new RelationIsDescriptor(I18N::translate('Relationship')),
178800c92694SGreg Roach            'INDI:*:PLAC:_HEB'      => new NoteStructure(I18N::translate('Place in Hebrew')),
178900c92694SGreg Roach            'INDI:BURI:CEME'        => new CustomElement(I18N::translate('Cemetery')),
179000c92694SGreg Roach            'INDI:CHAN:_PGVU'       => new WebtreesUser(I18N::translate('Author of last change')),
179100c92694SGreg Roach            'INDI:COMM'             => new CustomElement(I18N::translate('Comment')),
179200c92694SGreg Roach            'INDI:NAME:_HEB'        => new NamePersonal(I18N::translate('Name in Hebrew'), []),
179300c92694SGreg Roach            'INDI:_HOL'             => new CustomIndividualEvent(I18N::translate('Holocaust')),
179400c92694SGreg Roach            'INDI:_MILI'            => new CustomIndividualEvent(I18N::translate('Military')),
179500c92694SGreg Roach            'INDI:_PGV_OBJS'        => new XrefMedia(I18N::translate('Re-order media')),
179600c92694SGreg Roach            'NOTE:CHAN:_PGVU'       => new WebtreesUser(I18N::translate('Author of last change')),
179700c92694SGreg Roach            'OBJE:CHAN:_PGVU'       => new WebtreesUser(I18N::translate('Author of last change')),
179800c92694SGreg Roach            'OBJE:_THUM'            => new CustomElement(I18N::translate('Thumbnail image')),
179900c92694SGreg Roach            'REPO:CHAN:_PGVU'       => new WebtreesUser(I18N::translate('Author of last change')),
180000c92694SGreg Roach            'SOUR:CHAN:_PGVU'       => new WebtreesUser(I18N::translate('Author of last change')),
180100c92694SGreg Roach            'SOUR:SERV'             => new CustomElement(I18N::translate('Remote server')),
180200c92694SGreg Roach            'SOUR:URL'              => new AddressWebPage(I18N::translate('URL')),
180300c92694SGreg Roach            'SOUR:URL:TYPE'         => new CustomElement(I18N::translate('Type')), // e.g. "FamilySearch"
180400c92694SGreg Roach            'SOUR:URL:_BLOCK'       => new CustomElement(I18N::translate('Block')), // "e.g. "false"
180500c92694SGreg Roach            'SOUR:_DBID'            => new CustomElement(I18N::translate('Database name')),
180600c92694SGreg Roach            'SOUR:_DBID:_PASS'      => new CustomElement(I18N::translate('Database password')),
180700c92694SGreg Roach            'SOUR:_DBID:_PASS:RESN' => new RestrictionNotice(I18N::translate('Restriction')),
180800c92694SGreg Roach            'SOUR:_DBID:_USER'      => new CustomElement(I18N::translate('Database user account')),
180900c92694SGreg Roach        ];
181000c92694SGreg Roach    }
181100c92694SGreg Roach
181200c92694SGreg Roach    /**
181300c92694SGreg Roach     * @return array<string,ElementInterface>
181400c92694SGreg Roach     */
181500c92694SGreg Roach    private function reunionTags(): array
181600c92694SGreg Roach    {
181700c92694SGreg Roach        return [
181800c92694SGreg Roach            'FAM:_UID'   => new PafUid(I18N::translate('Unique identifier')),
181900c92694SGreg Roach            'INDI:CITN'  => new CustomElement(I18N::translate('Citizenship')),
182000c92694SGreg Roach            'INDI:EMAL'  => new AddressEmail(I18N::translate('Email address')),
182100c92694SGreg Roach            'INDI:_LEGA' => new CustomElement(I18N::translate('Legatee')),
182200c92694SGreg Roach            'INDI:_MDCL' => new CustomElement(I18N::translate('Medical')),
18234c10b11dSGreg Roach            'INDI:_PURC' => /* I18N: GEDCOM tag _PURC */ new CustomElement(I18N::translate('Land purchase')),
18244c10b11dSGreg Roach            'INDI:_SALE' => /* I18N: GEDCOM tag _SALE */ new CustomElement(I18N::translate('Land sale')),
182500c92694SGreg Roach            'INDI:_UID'  => new PafUid(I18N::translate('Unique identifier')),
182600c92694SGreg Roach            'OBJE:_UID'  => new PafUid(I18N::translate('Unique identifier')),
182700c92694SGreg Roach            'REPO:_UID'  => new PafUid(I18N::translate('Unique identifier')),
182800c92694SGreg Roach            'SOUR:_UID'  => new PafUid(I18N::translate('Unique identifier')),
182900c92694SGreg Roach        ];
183000c92694SGreg Roach    }
183100c92694SGreg Roach
183200c92694SGreg Roach    /**
183300c92694SGreg Roach     * @return array<string,ElementInterface>
183400c92694SGreg Roach     */
183500c92694SGreg Roach    private function rootsMagicTags(): array
183600c92694SGreg Roach    {
183700c92694SGreg Roach        return [
183800c92694SGreg Roach            'FAM:_UID'          => new PafUid(I18N::translate('Unique identifier')),
183900c92694SGreg Roach            'INDI:_DNA'         => new CustomElement(I18N::translate('DNA markers')),
184000c92694SGreg Roach            'INDI:_UID'         => new PafUid(I18N::translate('Unique identifier')),
184100c92694SGreg Roach            'INDI:_WEBTAG'      => new CustomElement(I18N::translate('External link')),
184200c92694SGreg Roach            'INDI:_WEBTAG:NAME' => new CustomElement(I18N::translate('Text')),
184300c92694SGreg Roach            'INDI:_WEBTAG:URL'  => new AddressWebPage(I18N::translate('URL')),
184400c92694SGreg Roach            'OBJE:_UID'         => new PafUid(I18N::translate('Unique identifier')),
184500c92694SGreg Roach            'REPO:_UID'         => new PafUid(I18N::translate('Unique identifier')),
184600c92694SGreg Roach            'SOUR:_BIBL'        => new CustomElement(I18N::translate('Bibliography')),
184700c92694SGreg Roach            'SOUR:_SUBQ'        => new CustomElement(I18N::translate('Abbreviation')),
184800c92694SGreg Roach            'SOUR:_UID'         => new PafUid(I18N::translate('Unique identifier')),
184900c92694SGreg Roach        ];
185000c92694SGreg Roach    }
185100c92694SGreg Roach
185200c92694SGreg Roach    /**
185300c92694SGreg Roach     * @return array<string,ElementInterface>
185400c92694SGreg Roach     */
185500c92694SGreg Roach    private function theMasterGenealogistTags(): array
185600c92694SGreg Roach    {
185700c92694SGreg Roach        return [
185800c92694SGreg Roach            'INDI:*:_SDATE' => new DateValue(I18N::translate('Sort date')),
185900c92694SGreg Roach            'INDI:NAME:_DATE'  => new DateValue(I18N::translate('Date')),
186000c92694SGreg Roach        ];
186100c92694SGreg Roach    }
186200c92694SGreg Roach
186300c92694SGreg Roach    /**
186400c92694SGreg Roach     * Custom tags for webtrees.
186500c92694SGreg Roach     *
186600c92694SGreg Roach     * @return array<string,ElementInterface>
186700c92694SGreg Roach     */
186800c92694SGreg Roach    private function webtreesTags(): array
186900c92694SGreg Roach    {
187000c92694SGreg Roach        return [
187100c92694SGreg Roach            'FAM:CHAN:_WT_USER'           => new WebtreesUser(I18N::translate('Author of last change')),
18725d2c6313SGreg Roach            'FAM:FACT'                    => new FamilyFact(I18N::translate('Fact')),
18735d2c6313SGreg Roach            'FAM:FACT:TYPE'               => new EventOrFactClassification(I18N::translate('Type of fact')),
187400c92694SGreg Roach            'FAM:*:_ASSO'                 => new XrefAssociate(I18N::translate('Associate')),
187500c92694SGreg Roach            'FAM:*:_ASSO:NOTE'            => new NoteStructure(I18N::translate('Note')),
187600c92694SGreg Roach            'FAM:*:_ASSO:RELA'            => new RelationIsDescriptor(I18N::translate('Relationship')),
187700c92694SGreg Roach            'FAM:*:_ASSO:SOUR'            => new XrefSource(I18N::translate('Source citation')),
187800c92694SGreg Roach            'FAM:*:_ASSO:SOUR:DATA'       => new SourceData(I18N::translate('Data')),
1879352bd396SGreg Roach            'FAM:*:_ASSO:SOUR:DATA:DATE'  => new DateValue(I18N::translate('Date of entry in original source')),
188000c92694SGreg Roach            'FAM:*:_ASSO:SOUR:DATA:TEXT'  => new TextFromSource(I18N::translate('Text')),
188100c92694SGreg Roach            'FAM:*:_ASSO:SOUR:EVEN'       => new EventTypeCitedFrom(I18N::translate('Event')),
188200c92694SGreg Roach            'FAM:*:_ASSO:SOUR:EVEN:ROLE'  => new RoleInEvent(I18N::translate('Role')),
188300c92694SGreg Roach            'FAM:*:_ASSO:SOUR:NOTE'       => new NoteStructure(I18N::translate('Note')),
188400c92694SGreg Roach            'FAM:*:_ASSO:SOUR:OBJE'       => new XrefMedia(I18N::translate('Media object')),
188500c92694SGreg Roach            'FAM:*:_ASSO:SOUR:PAGE'       => new WhereWithinSource(I18N::translate('Citation details')),
188600c92694SGreg Roach            'FAM:*:_ASSO:SOUR:QUAY'       => new CertaintyAssessment(I18N::translate('Quality of data')),
188700c92694SGreg Roach            'INDI:CHAN:_WT_USER'          => new WebtreesUser(I18N::translate('Author of last change')),
188800c92694SGreg Roach            'INDI:*:_ASSO'                => new XrefAssociate(I18N::translate('Associate')),
188900c92694SGreg Roach            'INDI:*:_ASSO:NOTE'           => new NoteStructure(I18N::translate('Note')),
189000c92694SGreg Roach            'INDI:*:_ASSO:RELA'           => new RelationIsDescriptor(I18N::translate('Relationship')),
189100c92694SGreg Roach            'INDI:*:_ASSO:SOUR'           => new XrefSource(I18N::translate('Source citation')),
189200c92694SGreg Roach            'INDI:*:_ASSO:SOUR:DATA'      => new SourceData(I18N::translate('Data')),
1893352bd396SGreg Roach            'INDI:*:_ASSO:SOUR:DATA:DATE' => new DateValue(I18N::translate('Date of entry in original source')),
189400c92694SGreg Roach            'INDI:*:_ASSO:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')),
189500c92694SGreg Roach            'INDI:*:_ASSO:SOUR:EVEN'      => new EventTypeCitedFrom(I18N::translate('Event')),
189600c92694SGreg Roach            'INDI:*:_ASSO:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')),
189700c92694SGreg Roach            'INDI:*:_ASSO:SOUR:NOTE'      => new NoteStructure(I18N::translate('Note')),
189800c92694SGreg Roach            'INDI:*:_ASSO:SOUR:OBJE'      => new XrefMedia(I18N::translate('Media object')),
189900c92694SGreg Roach            'INDI:*:_ASSO:SOUR:PAGE'      => new WhereWithinSource(I18N::translate('Citation details')),
190000c92694SGreg Roach            'INDI:*:_ASSO:SOUR:QUAY'      => new CertaintyAssessment(I18N::translate('Quality of data')),
190100c92694SGreg Roach            'NOTE:CHAN:_WT_USER'          => new WebtreesUser(I18N::translate('Author of last change')),
190200c92694SGreg Roach            'NOTE:RESN'                   => new RestrictionNotice(I18N::translate('Restriction')),
190300c92694SGreg Roach            'OBJE:CHAN:_WT_USER'          => new WebtreesUser(I18N::translate('Author of last change')),
190400c92694SGreg Roach            'OBJE:RESN'                   => new RestrictionNotice(I18N::translate('Restriction')),
190500c92694SGreg Roach            'REPO:CHAN:_WT_USER'          => new WebtreesUser(I18N::translate('Author of last change')),
190600c92694SGreg Roach            'REPO:RESN'                   => new RestrictionNotice(I18N::translate('Restriction')),
190700c92694SGreg Roach            'SOUR:CHAN:_WT_USER'          => new WebtreesUser(I18N::translate('Author of last change')),
190800c92694SGreg Roach            'SOUR:RESN'                   => new RestrictionNotice(I18N::translate('Restriction')),
190900c92694SGreg Roach            'SUBM:CHAN:_WT_USER'          => new WebtreesUser(I18N::translate('Author of last change')),
191000c92694SGreg Roach            'SUBM:RESN'                   => new RestrictionNotice(I18N::translate('Restriction')),
191100c92694SGreg Roach            '_LOC:CHAN:_WT_USER'          => new WebtreesUser(I18N::translate('Author of last change')),
191200c92694SGreg Roach            '_LOC:RESN'                   => new RestrictionNotice(I18N::translate('Restriction')),
191300c92694SGreg Roach        ];
191400c92694SGreg Roach    }
191500c92694SGreg Roach
191600c92694SGreg Roach    /**
191700c92694SGreg Roach     * @return array<string,array<int,array<int,string>>>
191800c92694SGreg Roach     */
191900c92694SGreg Roach    private function webtreesSubTags(): array
192000c92694SGreg Roach    {
192100c92694SGreg Roach        return [
192200c92694SGreg Roach            'FAM'              => [['_UID', '0:M']],
192300c92694SGreg Roach            'FAM:*:SOUR:DATA'  => [['TEXT', '0:1']],
192400c92694SGreg Roach            'FAM:ANUL'         => [['_ASSO', '0:M', 'NOTE']],
192500c92694SGreg Roach            'FAM:CENS'         => [['_ASSO', '0:M', 'NOTE']],
192600c92694SGreg Roach            'FAM:CHAN'         => [['_WT_USER', '0:1']],
192700c92694SGreg Roach            'FAM:DIV'          => [['_ASSO', '0:M', 'NOTE']],
192800c92694SGreg Roach            'FAM:DIVF'         => [['_ASSO', '0:M', 'NOTE']],
192900c92694SGreg Roach            'FAM:ENGA'         => [['_ASSO', '0:M', 'NOTE']],
193000c92694SGreg Roach            'FAM:EVEN'         => [['_ASSO', '0:M', 'NOTE']],
193100c92694SGreg Roach            'FAM:MARB'         => [['_ASSO', '0:M', 'NOTE']],
193200c92694SGreg Roach            'FAM:MARC'         => [['_ASSO', '0:M', 'NOTE']],
193300c92694SGreg Roach            'FAM:MARL'         => [['_ASSO', '0:M', 'NOTE']],
193400c92694SGreg Roach            'FAM:MARR'         => [['_ASSO', '2:M', 'NOTE']],
193500c92694SGreg Roach            'FAM:MARS'         => [['_ASSO', '0:M', 'NOTE']],
193600c92694SGreg Roach            'FAM:SLGS'         => [['_ASSO', '0:M', 'NOTE']],
193700c92694SGreg Roach            'FAM:SOUR:DATA'    => [['TEXT', '0:1']],
193800c92694SGreg Roach            'INDI'             => [['_UID', '0:M']],
193900c92694SGreg Roach            'INDI:*:SOUR:DATA' => [['TEXT', '0:1']],
194000c92694SGreg Roach            'INDI:ADOP'        => [['_ASSO', '0:M', 'NOTE']],
194100c92694SGreg Roach            'INDI:BAPL'        => [['_ASSO', '0:M', 'NOTE']],
194200c92694SGreg Roach            'INDI:BAPM'        => [['_ASSO', '2:M', 'NOTE']],
194300c92694SGreg Roach            'INDI:BARM'        => [['_ASSO', '0:M', 'NOTE']],
194400c92694SGreg Roach            'INDI:BASM'        => [['_ASSO', '0:M', 'NOTE']],
194500c92694SGreg Roach            'INDI:BIRT'        => [['_ASSO', '0:M', 'NOTE'], ['FAMC', '0:0']],
194600c92694SGreg Roach            'INDI:BURI'        => [['_ASSO', '0:M', 'NOTE']],
194700c92694SGreg Roach            'INDI:CENS'        => [['_ASSO', '0:M', 'NOTE']],
194800c92694SGreg Roach            'INDI:CHAN'        => [['_WT_USER', '0:1']],
194900c92694SGreg Roach            'INDI:CHR'         => [['_ASSO', '2:M', 'NOTE']],
195000c92694SGreg Roach            'INDI:CHRA'        => [['_ASSO', '0:M', 'NOTE']],
195100c92694SGreg Roach            'INDI:CONF'        => [['_ASSO', '0:M', 'NOTE']],
195200c92694SGreg Roach            'INDI:CONL'        => [['_ASSO', '0:M', 'NOTE']],
195300c92694SGreg Roach            'INDI:CREM'        => [['_ASSO', '0:M', 'NOTE']],
195400c92694SGreg Roach            'INDI:DEAT'        => [['_ASSO', '0:M', 'NOTE']],
195500c92694SGreg Roach            'INDI:EDUC'        => [['_ASSO', '0:M', 'NOTE']],
195600c92694SGreg Roach            'INDI:EMIG'        => [['_ASSO', '0:M', 'NOTE']],
195700c92694SGreg Roach            'INDI:ENDL'        => [['_ASSO', '0:M', 'NOTE']],
195800c92694SGreg Roach            'INDI:EVEN'        => [['_ASSO', '0:M', 'NOTE']],
195900c92694SGreg Roach            'INDI:GRAD'        => [['_ASSO', '0:M', 'NOTE']],
196000c92694SGreg Roach            'INDI:IMMI'        => [['_ASSO', '0:M', 'NOTE']],
196100c92694SGreg Roach            'INDI:NATU'        => [['_ASSO', '0:M', 'NOTE']],
196200c92694SGreg Roach            'INDI:OCCU'        => [['_ASSO', '0:M', 'NOTE']],
196300c92694SGreg Roach            'INDI:ORDN'        => [['_ASSO', '0:M', 'NOTE']],
196400c92694SGreg Roach            'INDI:PROB'        => [['_ASSO', '0:M', 'NOTE']],
196500c92694SGreg Roach            'INDI:PROP'        => [['_ASSO', '0:M', 'NOTE']],
196600c92694SGreg Roach            'INDI:RESI'        => [['_ASSO', '0:M', 'NOTE']],
196700c92694SGreg Roach            'INDI:RETI'        => [['_ASSO', '0:M', 'NOTE']],
196800c92694SGreg Roach            'INDI:SLGC'        => [['_ASSO', '0:M', 'NOTE']],
196900c92694SGreg Roach            'INDI:SOUR:DATA'   => [['TEXT', '0:1']],
197000c92694SGreg Roach            'INDI:TITL'        => [['_ASSO', '0:M', 'NOTE']],
197100c92694SGreg Roach            'INDI:WILL'        => [['_ASSO', '0:M', 'NOTE']],
197200c92694SGreg Roach            'NOTE'             => [['RESN', '0:1', 'CHAN']],
197300c92694SGreg Roach            'NOTE:CHAN'        => [['_WT_USER', '0:1']],
197400c92694SGreg Roach            'NOTE:SOUR:DATA'   => [['TEXT', '0:1']],
197500c92694SGreg Roach            'OBJE'             => [['RESN', '0:1', 'CHAN'], ['_UID', '0:M']],
197600c92694SGreg Roach            'OBJE:CHAN'        => [['_WT_USER', '0:1']],
197700c92694SGreg Roach            'OBJE:SOUR:DATA'   => [['TEXT', '0:1']],
197800c92694SGreg Roach            'REPO'             => [['RESN', '0:1', 'CHAN'], ['_UID', '0:M']],
197900c92694SGreg Roach            'REPO:CHAN'        => [['_WT_USER', '0:1']],
198000c92694SGreg Roach            'SOUR'             => [['RESN', '0:1', 'CHAN'], ['_UID', '0:M']],
198100c92694SGreg Roach            'SOUR:CHAN'        => [['_WT_USER', '0:1']],
198200c92694SGreg Roach            'SUBM'             => [['RESN', '0:1', 'CHAN']],
198300c92694SGreg Roach            'SUBM:CHAN'        => [['_WT_USER', '0:1']],
198400c92694SGreg Roach        ];
198500c92694SGreg Roach    }
198600c92694SGreg Roach
198700c92694SGreg Roach    /**
198800c92694SGreg Roach     * @return array<string,array<int,array<int,string>>>
198900c92694SGreg Roach     */
199000c92694SGreg Roach    private function customSubTags(): array
199100c92694SGreg Roach    {
199200c92694SGreg Roach        $custom_family_tags     = array_filter(explode(',', Site::getPreference('CUSTOM_FAMILY_TAGS')));
199300c92694SGreg Roach        $custom_individual_tags = array_filter(explode(',', Site::getPreference('CUSTOM_INDIVIDUAL_TAGS')));
199400c92694SGreg Roach
199500c92694SGreg Roach        $subtags = [
199600c92694SGreg Roach            'FAM'  => array_map(static fn (string $tag): array => [$tag, '0:M'], $custom_family_tags),
199700c92694SGreg Roach            'INDI' => array_map(static fn (string $tag): array => [$tag, '0:M'], $custom_individual_tags),
199800c92694SGreg Roach        ];
199900c92694SGreg Roach
2000d4193d5fSGreg Roach        if (Site::getPreference('CUSTOM_TIME_TAGS') === '1') {
2001d4193d5fSGreg Roach            $subtags['INDI:BIRT:DATE'][] = ['TIME', '0:1'];
2002d4193d5fSGreg Roach            $subtags['INDI:DEAT:DATE'][] = ['TIME', '0:1'];
2003d4193d5fSGreg Roach        }
2004d4193d5fSGreg Roach
200500c92694SGreg Roach        if (Site::getPreference('CUSTOM_GEDCOM_L_TAGS') === '1') {
200600c92694SGreg Roach            $subtags['FAM'][]               = ['_ASSO', '0:M'];
200700c92694SGreg Roach            $subtags['FAM'][]               = ['_STAT', '0:1'];
200800c92694SGreg Roach            $subtags['FAM'][]               = ['_UID', '0:M'];
2009f91876f3SGreg Roach            $subtags['FAM:*:ADDR']          = [['_NAME', '0:1:?', 'ADR1']];
201000c92694SGreg Roach            $subtags['FAM:*:PLAC']          = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
201100c92694SGreg Roach            $subtags['FAM:ENGA:PLAC']       = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
201200c92694SGreg Roach            $subtags['FAM:MARB:PLAC']       = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
20131c2da29dSRichard Cissée            $subtags['FAM:MARR']            = [['_WITN', '0:1']];
201400c92694SGreg Roach            $subtags['FAM:MARR:PLAC']       = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
201500c92694SGreg Roach            $subtags['FAM:SLGS:PLAC']       = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
201600c92694SGreg Roach            $subtags['INDI'][]              = ['_UID', '0:M'];
2017f91876f3SGreg Roach            $subtags['INDI:*:ADDR']         = [['_NAME', '0:1:?', 'ADR1']];
201800c92694SGreg Roach            $subtags['INDI:*:PLAC']         = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
201900c92694SGreg Roach            $subtags['INDI:ADOP:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
202000c92694SGreg Roach            $subtags['INDI:BAPL:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
20211c2da29dSRichard Cissée            $subtags['INDI:BAPM']           = [['_GODP', '0:1'], ['_WITN', '0:1']];
202200c92694SGreg Roach            $subtags['INDI:BAPM:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
202300c92694SGreg Roach            $subtags['INDI:BARM:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
202400c92694SGreg Roach            $subtags['INDI:BASM:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
202500c92694SGreg Roach            $subtags['INDI:BIRT:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
202600c92694SGreg Roach            $subtags['INDI:BLES:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
202700c92694SGreg Roach            $subtags['INDI:BURI:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
202800c92694SGreg Roach            $subtags['INDI:CENS:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
20291c2da29dSRichard Cissée            $subtags['INDI:CHR']            = [['_GODP', '0:1'], ['_WITN', '0:1']];
203000c92694SGreg Roach            $subtags['INDI:CHR:PLAC']       = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
203100c92694SGreg Roach            $subtags['INDI:CHRA:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
203200c92694SGreg Roach            $subtags['INDI:CONF:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
203300c92694SGreg Roach            $subtags['INDI:CONL:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
203400c92694SGreg Roach            $subtags['INDI:CREM:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
203500c92694SGreg Roach            $subtags['INDI:DEAT:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
203600c92694SGreg Roach            $subtags['INDI:EMIG:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
203700c92694SGreg Roach            $subtags['INDI:ENDL:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
203800c92694SGreg Roach            $subtags['INDI:EVEN:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
203900c92694SGreg Roach            $subtags['INDI:FCOM:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
204000c92694SGreg Roach            $subtags['INDI:IMMI:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
204100c92694SGreg Roach            $subtags['INDI:NAME']           = [['_RUFN', '0:1']];
204200c92694SGreg Roach            $subtags['INDI:NATU:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
204300c92694SGreg Roach            $subtags['INDI:ORDN:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
204400c92694SGreg Roach            $subtags['INDI:RESI:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
204500c92694SGreg Roach            $subtags['INDI:SLGC:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
204600c92694SGreg Roach            $subtags['NOTE']                = [['_UID', '0:M']];
204700c92694SGreg Roach            $subtags['OBJE']                = [['_PRIM', '0:1:?'], ['_UID', '0:M']];
204800c92694SGreg Roach            $subtags['REPO']                = [['_UID', '0:M']];
204900c92694SGreg Roach            $subtags['REPO:ADDR']           = [['_NAME', '0:1', 'ADR1']];
205000c92694SGreg Roach            $subtags['SOUR']                = [['_UID', '0:M']];
205100c92694SGreg Roach            $subtags['SOUR:DATA:EVEN:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
205200c92694SGreg Roach            $subtags['SUBM']                = [['_UID', '0:M']];
205300c92694SGreg Roach            $subtags['SUBM:ADDR']           = [['_NAME', '0:1', 'ADR1']];
205400c92694SGreg Roach        }
205500c92694SGreg Roach
205600c92694SGreg Roach        return $subtags;
205700c92694SGreg Roach    }
205800c92694SGreg Roach
20599e97502fSGreg Roach    /**
20609e97502fSGreg Roach     * @param ElementFactoryInterface $element_factory
20619e97502fSGreg Roach     * @param bool                    $include_custom_tags
20629e97502fSGreg Roach     *
20639e97502fSGreg Roach     * @return void
20649e97502fSGreg Roach     */
2065e669bb4bSGreg Roach    public function registerTags(ElementFactoryInterface $element_factory, bool $include_custom_tags): void
206600c92694SGreg Roach    {
206700c92694SGreg Roach        // Standard GEDCOM.
2068e669bb4bSGreg Roach        $element_factory->registerTags($this->gedcom551Tags());
206900c92694SGreg Roach
207000c92694SGreg Roach        // webtrees extensions.
2071e669bb4bSGreg Roach        $element_factory->registerTags($this->webtreesTags());
2072e669bb4bSGreg Roach
2073e669bb4bSGreg Roach        if ($include_custom_tags) {
2074e669bb4bSGreg Roach            // webtrees extensions.
2075e669bb4bSGreg Roach            $element_factory->registerSubTags($this->webtreesSubTags());
207600c92694SGreg Roach
207700c92694SGreg Roach            // Third-party extensions.
2078cb0c239dSGreg Roach            $element_factory->registerTags($this->aldfaerTags());
2079e669bb4bSGreg Roach            $element_factory->registerTags($this->ancestryTags());
2080e669bb4bSGreg Roach            $element_factory->registerTags($this->brothersKeeperTags());
2081e669bb4bSGreg Roach            $element_factory->registerTags($this->familySearchTags());
2082e669bb4bSGreg Roach            $element_factory->registerTags($this->familyTreeBuilderTags());
2083e669bb4bSGreg Roach            $element_factory->registerTags($this->familyTreeMakerTags());
2084701f5d18SGreg Roach            $element_factory->registerTags($this->gedcom7Tags());
2085e669bb4bSGreg Roach            $element_factory->registerTags($this->gedcomLTags());
2086b9a9ffe2SGreg Roach            $element_factory->registerTags($this->geneatique());
2087e669bb4bSGreg Roach            $element_factory->registerTags($this->genPlusWinTags());
2088b9a9ffe2SGreg Roach            $element_factory->registerTags($this->heredis());
2089e669bb4bSGreg Roach            $element_factory->registerTags($this->legacyTags());
209054671e98SGreg Roach            $element_factory->registerTags($this->myHeritageTags());
2091e669bb4bSGreg Roach            $element_factory->registerTags($this->personalAncestralFileTags());
2092e669bb4bSGreg Roach            $element_factory->registerTags($this->phpGedViewTags());
2093e669bb4bSGreg Roach            $element_factory->registerTags($this->reunionTags());
2094e669bb4bSGreg Roach            $element_factory->registerTags($this->rootsMagicTags());
2095e669bb4bSGreg Roach            $element_factory->registerTags($this->theMasterGenealogistTags());
209600c92694SGreg Roach
209700c92694SGreg Roach            // Creating tags from all the above are grouped into one place
2098e669bb4bSGreg Roach            $element_factory->registerSubTags($this->customSubTags());
2099e669bb4bSGreg Roach        }
210000c92694SGreg Roach    }
21010f471f91SGreg Roach}
2102