@treeviz/gedcom-parser 2.0.10 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +236 -989
- package/dist/classes/common.d.ts +10 -5
- package/dist/classes/common.d.ts.map +1 -1
- package/dist/classes/date.d.ts +2 -0
- package/dist/classes/date.d.ts.map +1 -1
- package/dist/classes/fam.d.ts +10 -1
- package/dist/classes/fam.d.ts.map +1 -1
- package/dist/classes/fams.d.ts.map +1 -1
- package/dist/classes/gedcom.d.ts +45 -4
- package/dist/classes/gedcom.d.ts.map +1 -1
- package/dist/classes/index.js +1770 -279
- package/dist/classes/indi.d.ts +24 -1
- package/dist/classes/indi.d.ts.map +1 -1
- package/dist/classes/list.d.ts.map +1 -1
- package/dist/classes/note.d.ts.map +1 -1
- package/dist/classes/obje.d.ts +2 -1
- package/dist/classes/obje.d.ts.map +1 -1
- package/dist/cli/index.js +2802 -1296
- package/dist/constants/constants.d.ts +7 -0
- package/dist/constants/constants.d.ts.map +1 -1
- package/dist/constants/index.js +1599 -989
- package/dist/factories/index.js +719 -110
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3837 -2028
- package/dist/interfaces/common.d.ts +6 -4
- package/dist/interfaces/common.d.ts.map +1 -1
- package/dist/interfaces/fam.d.ts +10 -1
- package/dist/interfaces/fam.d.ts.map +1 -1
- package/dist/interfaces/gedcom.d.ts +25 -1
- package/dist/interfaces/gedcom.d.ts.map +1 -1
- package/dist/interfaces/indi.d.ts +15 -1
- package/dist/interfaces/indi.d.ts.map +1 -1
- package/dist/kinship-translator/index.js +719 -110
- package/dist/structures/gedcom.d.ts +2 -0
- package/dist/structures/gedcom.d.ts.map +1 -1
- package/dist/types/types.d.ts +32 -4
- package/dist/types/types.d.ts.map +1 -1
- package/dist/utils/common-creator.d.ts.map +1 -1
- package/dist/utils/fact-edit.d.ts +34 -0
- package/dist/utils/fact-edit.d.ts.map +1 -0
- package/dist/utils/family-edit.d.ts +23 -0
- package/dist/utils/family-edit.d.ts.map +1 -0
- package/dist/utils/gedcom-trailer.d.ts +6 -0
- package/dist/utils/gedcom-trailer.d.ts.map +1 -0
- package/dist/utils/gedcom-version.d.ts +6 -0
- package/dist/utils/gedcom-version.d.ts.map +1 -0
- package/dist/utils/gedcom7-dates.d.ts +20 -0
- package/dist/utils/gedcom7-dates.d.ts.map +1 -0
- package/dist/utils/gedcom7-enumerations.d.ts +26 -0
- package/dist/utils/gedcom7-enumerations.d.ts.map +1 -0
- package/dist/utils/gedcom7-metadata.d.ts +19 -0
- package/dist/utils/gedcom7-metadata.d.ts.map +1 -0
- package/dist/utils/gedcom7-schema.d.ts +27 -0
- package/dist/utils/gedcom7-schema.d.ts.map +1 -0
- package/dist/utils/gedzip.d.ts +81 -0
- package/dist/utils/gedzip.d.ts.map +1 -0
- package/dist/utils/index.d.ts +13 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2225 -416
- package/dist/utils/local-media.d.ts +30 -0
- package/dist/utils/local-media.d.ts.map +1 -0
- package/dist/utils/media-utils.d.ts +10 -6
- package/dist/utils/media-utils.d.ts.map +1 -1
- package/dist/utils/multimedia.d.ts +38 -0
- package/dist/utils/multimedia.d.ts.map +1 -0
- package/dist/utils/parser.d.ts +3 -0
- package/dist/utils/parser.d.ts.map +1 -1
- package/dist/utils/uid.d.ts +6 -0
- package/dist/utils/uid.d.ts.map +1 -0
- package/package.json +2 -1
package/dist/constants/index.js
CHANGED
|
@@ -8,11 +8,13 @@ var __export = (target, all) => {
|
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
// src/constants/constants.ts
|
|
11
|
-
var
|
|
12
|
-
var
|
|
11
|
+
var APP_BRANDING = "TreeViz - The Family Tree Visualiser & Editor";
|
|
12
|
+
var REF_LINE_REG = /^0 (?:(@[_a-zA-Z0-9]*@) )?(?<type>_[_A-Z][_a-zA-Z0-9]{2,}|_?[A-Z][A-Za-z0-9]{2,}) ?(?<value>.*)/gm;
|
|
13
|
+
var LINE_REG = /(?<indent>^[0-9]{1,2}) (?:(@[_a-zA-Z0-9]*@) )?(?<type>_[_A-Z][_a-zA-Z0-9]{2,}|_?[A-Z][A-Za-z0-9]{2,}) ?(?<value>.*)/;
|
|
13
14
|
var ID_REG = /^@[_a-zA-Z0-9]+@/;
|
|
14
15
|
var ID_GETTER_REG = /^(?<at>@)?(?<letter>[A-Z])?/i;
|
|
15
16
|
var ID_SPLIT_REG = /^@[_a-zA-Z0-9]+@:/;
|
|
17
|
+
var ORIG_HEAD_TAG = "_ORIGHEAD";
|
|
16
18
|
var MAX_FILE_SIZE_TO_SYNC = 1024 * 1024 * 20;
|
|
17
19
|
|
|
18
20
|
// src/constants/filters.ts
|
|
@@ -543,1050 +545,1347 @@ var dateFormatter = (indi, showMarriages = false, showDays = false, showPlaces =
|
|
|
543
545
|
} : {}
|
|
544
546
|
};
|
|
545
547
|
};
|
|
546
|
-
|
|
547
|
-
|
|
548
|
+
|
|
549
|
+
// src/utils/gedcom-trailer.ts
|
|
550
|
+
var GEDCOM_TRAILER_TAG = "TRLR";
|
|
551
|
+
var isGedcomTrailerTag = (tag) => tag === GEDCOM_TRAILER_TAG;
|
|
552
|
+
var List = class _List {
|
|
553
|
+
// length = 0;
|
|
554
|
+
constructor(items) {
|
|
555
|
+
this.items = {};
|
|
548
556
|
this.isListable = true;
|
|
549
|
-
this.
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
this.initUniqueId();
|
|
553
|
-
if (id) {
|
|
554
|
-
this._id = id;
|
|
555
|
-
} else {
|
|
556
|
-
delete this._id;
|
|
557
|
+
this.marker = void 0;
|
|
558
|
+
if (items) {
|
|
559
|
+
this.concat(items);
|
|
557
560
|
}
|
|
558
561
|
}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
this.uniqueId = this.uniqueId?.replace(/^[^:]+/, `~${type}`);
|
|
562
|
-
}
|
|
563
|
-
this._type = type;
|
|
562
|
+
get length() {
|
|
563
|
+
return this.values().length;
|
|
564
564
|
}
|
|
565
|
-
|
|
566
|
-
return this.
|
|
565
|
+
has(indi) {
|
|
566
|
+
return !!this.item(
|
|
567
|
+
typeof indi === "string" ? indi : indi?.id ?? ""
|
|
568
|
+
);
|
|
567
569
|
}
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
570
|
+
get(name) {
|
|
571
|
+
const propList = new _List();
|
|
572
|
+
this.entries().forEach(([key, item]) => {
|
|
573
|
+
propList.item(key, item.get(name));
|
|
574
|
+
});
|
|
575
|
+
return propList;
|
|
572
576
|
}
|
|
573
|
-
|
|
574
|
-
const
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
if (
|
|
578
|
-
|
|
577
|
+
getIf(name, condition, name2) {
|
|
578
|
+
const propList = new _List();
|
|
579
|
+
this.entries().forEach(([key, item]) => {
|
|
580
|
+
const passedItem = item.getIf(name, condition, name2);
|
|
581
|
+
if (passedItem) {
|
|
582
|
+
propList.item(key, passedItem);
|
|
579
583
|
}
|
|
580
|
-
|
|
581
|
-
|
|
584
|
+
});
|
|
585
|
+
return propList;
|
|
582
586
|
}
|
|
583
|
-
|
|
584
|
-
return this.
|
|
587
|
+
keys() {
|
|
588
|
+
return Object.keys(this.items);
|
|
585
589
|
}
|
|
586
|
-
|
|
587
|
-
this.
|
|
590
|
+
values() {
|
|
591
|
+
return Object.values(this.items);
|
|
588
592
|
}
|
|
589
|
-
|
|
590
|
-
return
|
|
593
|
+
entries() {
|
|
594
|
+
return Object.entries(this.items);
|
|
591
595
|
}
|
|
592
|
-
|
|
593
|
-
this._value = value;
|
|
596
|
+
setLength(_type) {
|
|
594
597
|
}
|
|
595
|
-
|
|
596
|
-
return this.
|
|
598
|
+
first() {
|
|
599
|
+
return this.index(0);
|
|
597
600
|
}
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
* @param gedcom - The GedComType to set as the gedcom reference
|
|
601
|
-
*/
|
|
602
|
-
setGedcom(gedcom) {
|
|
603
|
-
this._gedcom = gedcom;
|
|
601
|
+
last() {
|
|
602
|
+
return this.index(this.keys().length - 1);
|
|
604
603
|
}
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
604
|
+
index(index) {
|
|
605
|
+
const keys = this.keys();
|
|
606
|
+
const key = keys[index];
|
|
607
|
+
return key && this.items[key];
|
|
608
608
|
}
|
|
609
|
-
|
|
610
|
-
if (
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
this.value
|
|
614
|
-
);
|
|
609
|
+
item(name, value) {
|
|
610
|
+
if (arguments.length > 1) {
|
|
611
|
+
set(this.items, name, value);
|
|
612
|
+
this.setLength();
|
|
615
613
|
}
|
|
616
|
-
return this;
|
|
614
|
+
return get(this.items, name);
|
|
617
615
|
}
|
|
618
|
-
|
|
619
|
-
|
|
616
|
+
removeItem(name) {
|
|
617
|
+
unset(this.items, name);
|
|
618
|
+
this.setLength();
|
|
620
619
|
}
|
|
621
|
-
|
|
622
|
-
|
|
620
|
+
exclude(excludedList) {
|
|
621
|
+
excludedList.keys().forEach((itemId) => {
|
|
622
|
+
delete this.items[itemId];
|
|
623
|
+
});
|
|
624
|
+
this.setLength();
|
|
625
|
+
return this;
|
|
623
626
|
}
|
|
624
|
-
|
|
625
|
-
if (
|
|
626
|
-
|
|
627
|
-
this.
|
|
628
|
-
}
|
|
629
|
-
|
|
627
|
+
concat(items) {
|
|
628
|
+
if (Array.isArray(items)) {
|
|
629
|
+
items.forEach((item) => {
|
|
630
|
+
this.append(item);
|
|
631
|
+
});
|
|
632
|
+
} else {
|
|
633
|
+
Object.assign(this.items, items ?? {});
|
|
630
634
|
}
|
|
635
|
+
this.setLength();
|
|
636
|
+
return this;
|
|
631
637
|
}
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
exportValue() {
|
|
636
|
-
return this.value;
|
|
638
|
+
merge(mergedList) {
|
|
639
|
+
this.concat(mergedList?.items);
|
|
640
|
+
return this;
|
|
637
641
|
}
|
|
638
|
-
|
|
639
|
-
|
|
642
|
+
intersection(mergedList) {
|
|
643
|
+
const inter = intersectionBy(
|
|
644
|
+
this.values(),
|
|
645
|
+
mergedList?.values() ?? [],
|
|
646
|
+
"id"
|
|
647
|
+
);
|
|
648
|
+
return new _List(inter);
|
|
640
649
|
}
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
}
|
|
649
|
-
return get(this, name);
|
|
650
|
+
difference(mergedList) {
|
|
651
|
+
const inter = differenceBy(
|
|
652
|
+
this.values(),
|
|
653
|
+
mergedList?.values() ?? [],
|
|
654
|
+
"id"
|
|
655
|
+
);
|
|
656
|
+
return new _List(inter);
|
|
650
657
|
}
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
if (
|
|
655
|
-
|
|
656
|
-
|
|
658
|
+
prepend(item) {
|
|
659
|
+
if (item.id) {
|
|
660
|
+
let increase = true;
|
|
661
|
+
if (this.items[item.id]) {
|
|
662
|
+
delete this.items[item.id];
|
|
663
|
+
increase = false;
|
|
664
|
+
}
|
|
665
|
+
this.items = Object.assign(
|
|
666
|
+
{
|
|
667
|
+
[item.id]: item
|
|
668
|
+
},
|
|
669
|
+
this.items
|
|
670
|
+
);
|
|
671
|
+
if (increase) {
|
|
672
|
+
this.setLength("increase");
|
|
657
673
|
}
|
|
658
|
-
const values = [
|
|
659
|
-
...curValue.values(),
|
|
660
|
-
...value instanceof List ? value.values() : [value]
|
|
661
|
-
];
|
|
662
|
-
curValue.concat({
|
|
663
|
-
...!unique ? values : uniqBy(
|
|
664
|
-
values,
|
|
665
|
-
(value2) => value2 instanceof _Common ? value2?.value : void 0
|
|
666
|
-
)
|
|
667
|
-
});
|
|
668
|
-
} else {
|
|
669
|
-
this.set(name, value);
|
|
670
674
|
}
|
|
671
|
-
return
|
|
675
|
+
return this;
|
|
672
676
|
}
|
|
673
|
-
|
|
674
|
-
if (
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
for (const part of nameParts) {
|
|
680
|
-
const indexPart = Number(part);
|
|
681
|
-
const itemIndex = part.match(/items\[(?<itemIndex>\d+)\]/)?.groups?.itemIndex;
|
|
682
|
-
const itemId = part.match(/items\[(?<itemId>@[A-Z]+\d+@)\]/)?.groups?.itemId;
|
|
683
|
-
const usedPart = itemId || itemIndex;
|
|
684
|
-
if (last instanceof List) {
|
|
685
|
-
if (!isNaN(indexPart)) {
|
|
686
|
-
last = last.index(indexPart);
|
|
687
|
-
} else {
|
|
688
|
-
if (usedPart) {
|
|
689
|
-
last = last.item(usedPart);
|
|
690
|
-
} else {
|
|
691
|
-
last = last?.index(0)?.get(part);
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
} else {
|
|
695
|
-
const usedIndex = Number(itemIndex ?? indexPart);
|
|
696
|
-
if (!isNaN(usedIndex)) {
|
|
697
|
-
last = last?.toList().index(usedIndex);
|
|
698
|
-
} else {
|
|
699
|
-
last = last?.get(itemId ?? part);
|
|
700
|
-
}
|
|
677
|
+
append(item) {
|
|
678
|
+
if (item.id) {
|
|
679
|
+
let increase = true;
|
|
680
|
+
if (this.items[item.id]) {
|
|
681
|
+
delete this.items[item.id];
|
|
682
|
+
increase = false;
|
|
701
683
|
}
|
|
702
|
-
|
|
703
|
-
|
|
684
|
+
this.items[item.id] = item;
|
|
685
|
+
if (increase) {
|
|
686
|
+
this.setLength("increase");
|
|
704
687
|
}
|
|
705
688
|
}
|
|
706
|
-
return
|
|
689
|
+
return this;
|
|
707
690
|
}
|
|
708
|
-
|
|
709
|
-
|
|
691
|
+
delete(item) {
|
|
692
|
+
if (item.id && this.items[item.id]) {
|
|
693
|
+
delete this.items[item.id];
|
|
694
|
+
this.setLength("decrease");
|
|
695
|
+
}
|
|
696
|
+
return this;
|
|
710
697
|
}
|
|
711
|
-
|
|
712
|
-
|
|
698
|
+
copy(ClassName = _List) {
|
|
699
|
+
const newList = new ClassName();
|
|
700
|
+
Object.assign(newList.items, this.items);
|
|
701
|
+
newList.setLength();
|
|
702
|
+
return newList;
|
|
713
703
|
}
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
const name2Parts = name2.split(".");
|
|
717
|
-
if (nameParts.length !== name2Parts.length) {
|
|
718
|
-
throw new Error("Tag pathes must be of the same depth");
|
|
719
|
-
}
|
|
720
|
-
if (nameParts.length > 1 && nameParts[0] !== name2Parts[0]) {
|
|
721
|
-
throw new Error("Final tags must be siblings");
|
|
722
|
-
}
|
|
723
|
-
const valueCommon = this.get(name);
|
|
724
|
-
if (valueCommon instanceof _Common) {
|
|
725
|
-
return valueCommon?.toValue() !== condition ? void 0 : this.get(name2);
|
|
726
|
-
}
|
|
727
|
-
const valueCommon2 = this.get(name2)?.toList();
|
|
728
|
-
const ifList = new List();
|
|
729
|
-
valueCommon?.forEach((item, key) => {
|
|
730
|
-
const pair = valueCommon2?.item(key);
|
|
731
|
-
ifList.item(key, item?.toValue() !== condition ? void 0 : pair);
|
|
732
|
-
});
|
|
733
|
-
return ifList;
|
|
734
|
-
}
|
|
735
|
-
toString() {
|
|
736
|
-
return this.value?.toString() || "";
|
|
737
|
-
}
|
|
738
|
-
toValue() {
|
|
739
|
-
return this.value;
|
|
740
|
-
}
|
|
741
|
-
toProp(tag) {
|
|
742
|
-
const prop = this.get(tag);
|
|
743
|
-
return prop;
|
|
744
|
-
}
|
|
745
|
-
toList() {
|
|
746
|
-
return new List().concat(
|
|
747
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
748
|
-
this.id ? { [this.id]: this } : { ...[this] }
|
|
749
|
-
);
|
|
750
|
-
}
|
|
751
|
-
index(i) {
|
|
752
|
-
return this.toList()?.index(i);
|
|
704
|
+
except(item, ClassName = _List) {
|
|
705
|
+
return this.copy(ClassName).delete(item);
|
|
753
706
|
}
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
{ ...[this] }
|
|
759
|
-
)
|
|
760
|
-
);
|
|
707
|
+
forEach(iterate) {
|
|
708
|
+
this.entries().forEach(([key, item], index) => {
|
|
709
|
+
iterate(item, key, index);
|
|
710
|
+
});
|
|
761
711
|
}
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
this,
|
|
767
|
-
options.obje.namespace,
|
|
768
|
-
options.obje.override
|
|
769
|
-
);
|
|
770
|
-
}
|
|
712
|
+
map(iterate) {
|
|
713
|
+
return this.entries().map(([key, item], index) => {
|
|
714
|
+
return iterate(item, key, index);
|
|
715
|
+
});
|
|
771
716
|
}
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
717
|
+
reduce(iterate, initialValue) {
|
|
718
|
+
return this.entries().reduce((acc, [key, item], index) => {
|
|
719
|
+
return iterate(acc, item, key, index);
|
|
720
|
+
}, initialValue);
|
|
775
721
|
}
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
const
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
const validKey = key;
|
|
791
|
-
const prop = this.get(validKey);
|
|
792
|
-
if (typeof prop?.toObject === "function") {
|
|
793
|
-
if (prop instanceof _Common) {
|
|
794
|
-
json[validKey] = prop.toObject(validKey, options);
|
|
795
|
-
} else {
|
|
796
|
-
json = {
|
|
797
|
-
...json,
|
|
798
|
-
...prop.toObject(validKey, options)
|
|
799
|
-
};
|
|
800
|
-
}
|
|
722
|
+
filter(filters, ClassName = _List) {
|
|
723
|
+
const newList = new ClassName();
|
|
724
|
+
const isIterator = typeof filters === "function";
|
|
725
|
+
this.entries().forEach(([itemId, item], index) => {
|
|
726
|
+
if (isIterator) {
|
|
727
|
+
filters(item, itemId, index) && newList.item(itemId, item);
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
if (!Object.keys(filters).length || Object.entries(filters).every(([key, value]) => {
|
|
731
|
+
let itemValue;
|
|
732
|
+
if (key === "id") {
|
|
733
|
+
itemValue = item.toProp("id");
|
|
734
|
+
} else {
|
|
735
|
+
itemValue = item.toProp(key)?.toValue();
|
|
801
736
|
}
|
|
737
|
+
if (Array.isArray(value)) {
|
|
738
|
+
return value.includes(itemValue);
|
|
739
|
+
}
|
|
740
|
+
return itemValue === value;
|
|
741
|
+
})) {
|
|
742
|
+
newList.item(itemId, item);
|
|
802
743
|
}
|
|
803
744
|
});
|
|
804
|
-
return
|
|
745
|
+
return newList;
|
|
805
746
|
}
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
747
|
+
find(filters, _ClassName = _List) {
|
|
748
|
+
let foundItem;
|
|
749
|
+
const isIterator = typeof filters === "function";
|
|
750
|
+
this.entries().find(([itemId, item], index) => {
|
|
751
|
+
if (isIterator) {
|
|
752
|
+
if (filters(item, itemId, index)) {
|
|
753
|
+
foundItem = item;
|
|
754
|
+
return true;
|
|
755
|
+
}
|
|
756
|
+
return false;
|
|
814
757
|
}
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
758
|
+
if (!Object.keys(filters).length || Object.entries(filters).every(([key, value]) => {
|
|
759
|
+
let itemValue;
|
|
760
|
+
if (key === "id") {
|
|
761
|
+
itemValue = item.toProp("id");
|
|
762
|
+
} else {
|
|
763
|
+
itemValue = item.toProp(key)?.toValue();
|
|
764
|
+
}
|
|
765
|
+
if (Array.isArray(value)) {
|
|
766
|
+
return value.includes(itemValue);
|
|
822
767
|
}
|
|
768
|
+
return itemValue === value;
|
|
769
|
+
})) {
|
|
770
|
+
foundItem = item;
|
|
771
|
+
return true;
|
|
823
772
|
}
|
|
773
|
+
return false;
|
|
824
774
|
});
|
|
825
|
-
return
|
|
775
|
+
return foundItem;
|
|
826
776
|
}
|
|
827
|
-
|
|
828
|
-
const
|
|
829
|
-
const
|
|
830
|
-
|
|
831
|
-
this
|
|
832
|
-
this._main,
|
|
833
|
-
this._parent
|
|
834
|
-
);
|
|
835
|
-
if (newId && this._id) {
|
|
836
|
-
instance.id = `IFT${this._id.replace(/[^0-9]/g, "")}`;
|
|
777
|
+
orderBy(orders, ClassName = _List) {
|
|
778
|
+
const newList = new ClassName();
|
|
779
|
+
const isIterator = typeof orders === "function";
|
|
780
|
+
if (!isIterator && (!orders || !Object.keys(orders).length)) {
|
|
781
|
+
return newList.merge(this);
|
|
837
782
|
}
|
|
838
|
-
const
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
if (
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
} else {
|
|
866
|
-
gedcom.push(
|
|
867
|
-
...prop.toGedcomLines(validKey, level, options)
|
|
868
|
-
);
|
|
783
|
+
const sortedItems = this.entries().toSorted(
|
|
784
|
+
([itemAId, itemA], [itemBId, itemB]) => {
|
|
785
|
+
if (isIterator) {
|
|
786
|
+
return orders(itemA, itemAId, itemB, itemBId);
|
|
787
|
+
}
|
|
788
|
+
const [key, { direction, getter }] = Object.entries(
|
|
789
|
+
typeof orders === "string" ? { [orders]: { direction: "ASC" } } : orders
|
|
790
|
+
)[0];
|
|
791
|
+
const rawA = itemA.get(key);
|
|
792
|
+
const rawB = itemB.get(key);
|
|
793
|
+
let valueA = rawA?.toValue();
|
|
794
|
+
let valueB = rawB?.toValue();
|
|
795
|
+
if (getter && typeof getter === "function") {
|
|
796
|
+
valueA = getter(valueA, rawA);
|
|
797
|
+
valueB = getter(valueB, rawB);
|
|
798
|
+
}
|
|
799
|
+
let sortValue2 = 0;
|
|
800
|
+
if (!valueA && valueA !== 0 && !valueB && valueB !== 0) {
|
|
801
|
+
sortValue2 = 0;
|
|
802
|
+
} else if (!valueB && valueB !== 0) {
|
|
803
|
+
sortValue2 = 1;
|
|
804
|
+
} else if (!valueA && valueA !== 0) {
|
|
805
|
+
sortValue2 = -1;
|
|
806
|
+
} else if (valueA < valueB) {
|
|
807
|
+
sortValue2 = -1;
|
|
808
|
+
} else if (valueA > valueB) {
|
|
809
|
+
sortValue2 = 1;
|
|
869
810
|
}
|
|
811
|
+
return sortValue2 * (direction === "DESC" ? -1 : 1);
|
|
870
812
|
}
|
|
813
|
+
);
|
|
814
|
+
sortedItems.forEach(([key, value]) => {
|
|
815
|
+
newList.item(key, value);
|
|
871
816
|
});
|
|
872
|
-
return
|
|
873
|
-
}
|
|
874
|
-
isGenoPro() {
|
|
875
|
-
const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
|
|
876
|
-
const sour = get(head, "SOUR.value");
|
|
877
|
-
return !!sour?.toLowerCase()?.startsWith("genopro");
|
|
878
|
-
}
|
|
879
|
-
isAhnenblatt() {
|
|
880
|
-
const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
|
|
881
|
-
const sour = get(head, "SOUR.value");
|
|
882
|
-
return !!sour?.toLowerCase()?.startsWith("ahnenblatt");
|
|
883
|
-
}
|
|
884
|
-
isGeni() {
|
|
885
|
-
const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
|
|
886
|
-
const sour = get(head, "SOUR.value");
|
|
887
|
-
return !!sour?.toLowerCase()?.startsWith("geni");
|
|
888
|
-
}
|
|
889
|
-
isAncestry() {
|
|
890
|
-
const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
|
|
891
|
-
const sour = get(head, "SOUR.value");
|
|
892
|
-
return !!sour?.toLowerCase()?.startsWith("ancestry");
|
|
893
|
-
}
|
|
894
|
-
isMyHeritage() {
|
|
895
|
-
const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
|
|
896
|
-
const sour = get(head, "SOUR.value");
|
|
897
|
-
return !!sour?.toLowerCase()?.startsWith("myheritage");
|
|
817
|
+
return newList;
|
|
898
818
|
}
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
819
|
+
groupBy(groups, sort, minOccurance = -1, lessOccuranceLabel = "Appearing less than 5 times", ClassName = _List) {
|
|
820
|
+
const groupped = {};
|
|
821
|
+
const isIterator = typeof groups === "function";
|
|
822
|
+
if (!isIterator && (!groups || !Object.keys(groups).length)) {
|
|
823
|
+
groupped.Unknown = new ClassName().merge(this);
|
|
824
|
+
groupped.Unknown.marker = "Unknown";
|
|
825
|
+
return groupped;
|
|
826
|
+
}
|
|
827
|
+
this.forEach((item, itemId) => {
|
|
828
|
+
const group = [];
|
|
829
|
+
if (isIterator) {
|
|
830
|
+
const newGroups = groups(item, itemId);
|
|
831
|
+
group.push(
|
|
832
|
+
...Array.isArray(newGroups) ? newGroups : [newGroups]
|
|
833
|
+
);
|
|
834
|
+
} else {
|
|
835
|
+
const [key, { getter }] = Object.entries(
|
|
836
|
+
typeof groups === "string" ? { [groups]: {} } : groups
|
|
837
|
+
)[0];
|
|
838
|
+
const raw = item.get(key)?.index(0);
|
|
839
|
+
let value = raw?.toValue();
|
|
840
|
+
if (getter && typeof getter === "function") {
|
|
841
|
+
value = getter(value, raw);
|
|
842
|
+
}
|
|
843
|
+
if (value) {
|
|
844
|
+
group.push(value);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
if (!group.length) {
|
|
848
|
+
group.push("Unknown");
|
|
849
|
+
}
|
|
850
|
+
group.forEach((g) => {
|
|
851
|
+
const newGroup = typeof g === "string" ? { group: g } : g;
|
|
852
|
+
if (!groupped[newGroup.group]) {
|
|
853
|
+
groupped[newGroup.group] = new ClassName();
|
|
854
|
+
groupped[newGroup.group].marker = newGroup.marker ?? newGroup.group;
|
|
855
|
+
}
|
|
856
|
+
groupped[newGroup.group]?.append(item);
|
|
857
|
+
});
|
|
858
|
+
});
|
|
859
|
+
if (sort) {
|
|
860
|
+
return Object.entries(groupped).toSorted(([ak, a], [bk, b]) => {
|
|
861
|
+
if (typeof sort === "function") {
|
|
862
|
+
return sort(a, ak, b, bk);
|
|
863
|
+
}
|
|
864
|
+
if (ak === "Unknown") {
|
|
865
|
+
return 1;
|
|
866
|
+
}
|
|
867
|
+
if (bk === "Unknown") {
|
|
868
|
+
return -1;
|
|
869
|
+
}
|
|
870
|
+
if (sort === "group") {
|
|
871
|
+
return ak.localeCompare(bk);
|
|
872
|
+
}
|
|
873
|
+
return (b?.length ?? 0) - (a?.length ?? 0);
|
|
874
|
+
}).reduce((acc, [key, value]) => {
|
|
875
|
+
if (minOccurance > -1 && (value?.length ?? 0) < minOccurance) {
|
|
876
|
+
const otherKey = lessOccuranceLabel;
|
|
877
|
+
acc[otherKey] = acc[otherKey] && value ? acc[otherKey].merge(value) : value;
|
|
878
|
+
} else {
|
|
879
|
+
acc[key] = value;
|
|
880
|
+
}
|
|
881
|
+
return acc;
|
|
882
|
+
}, {});
|
|
883
|
+
}
|
|
884
|
+
return groupped;
|
|
912
885
|
}
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
886
|
+
findIndex(item) {
|
|
887
|
+
if (!item?.id) {
|
|
888
|
+
return -1;
|
|
889
|
+
}
|
|
890
|
+
return this.keys().findIndex((key) => key === item.id);
|
|
917
891
|
}
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
const sour = get(head, "SOUR.value");
|
|
921
|
-
return sour === "GNO2GED";
|
|
892
|
+
getItems() {
|
|
893
|
+
return this.items;
|
|
922
894
|
}
|
|
923
|
-
|
|
924
|
-
const
|
|
925
|
-
return
|
|
895
|
+
toJson(tag, options) {
|
|
896
|
+
const json = this.toObject(tag, options);
|
|
897
|
+
return JSON.stringify(json);
|
|
926
898
|
}
|
|
927
|
-
|
|
928
|
-
const
|
|
929
|
-
|
|
899
|
+
toObject(tag, options) {
|
|
900
|
+
const json = {};
|
|
901
|
+
this.entries().forEach(([_, item]) => {
|
|
902
|
+
const validTag = getValidTag(tag);
|
|
903
|
+
if (json[validTag]) {
|
|
904
|
+
if (!Array.isArray(json[validTag])) {
|
|
905
|
+
json[validTag] = [json[validTag]];
|
|
906
|
+
}
|
|
907
|
+
json[validTag].push(
|
|
908
|
+
item.toObject(validTag, options)
|
|
909
|
+
);
|
|
910
|
+
} else {
|
|
911
|
+
json[validTag] = item.toObject(
|
|
912
|
+
validTag,
|
|
913
|
+
options
|
|
914
|
+
);
|
|
915
|
+
}
|
|
916
|
+
});
|
|
917
|
+
return json;
|
|
930
918
|
}
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
if (id !== void 0) return id;
|
|
935
|
-
}
|
|
936
|
-
if (this?.isMyHeritage()) {
|
|
937
|
-
const id = this.getMyHeritageTreeId();
|
|
938
|
-
if (id !== void 0) return id;
|
|
939
|
-
}
|
|
940
|
-
if (this?.isFamilySearch()) {
|
|
941
|
-
const id = this.getFamilySearchTreeId();
|
|
942
|
-
if (id !== void 0) return id;
|
|
943
|
-
}
|
|
944
|
-
if (this?.isGNO2GED()) {
|
|
945
|
-
const id = this.getGNO2GEDTreeId();
|
|
946
|
-
if (id !== void 0) return id;
|
|
947
|
-
}
|
|
948
|
-
if (this?.isAhnenblatt()) {
|
|
949
|
-
const id = this.getAhnenblattTreeId();
|
|
950
|
-
if (id !== void 0) return id;
|
|
951
|
-
}
|
|
952
|
-
if (this?.isGeni()) {
|
|
953
|
-
const id = this.getGeniTreeId();
|
|
954
|
-
if (id !== void 0) return id;
|
|
955
|
-
}
|
|
956
|
-
if (this?.isGenoPro()) {
|
|
957
|
-
const id = this.getGenoProTreeId();
|
|
958
|
-
if (id !== void 0) return id;
|
|
959
|
-
}
|
|
960
|
-
return this.getUniversalTreeId();
|
|
919
|
+
toGedcom(tag, level = 0, options) {
|
|
920
|
+
const gedcom = this.toGedcomLines(tag, level, options);
|
|
921
|
+
return gedcom.join("\n");
|
|
961
922
|
}
|
|
962
|
-
|
|
963
|
-
const
|
|
964
|
-
|
|
923
|
+
toGedcomLines(tag, level = 0, options) {
|
|
924
|
+
const gedcom = [];
|
|
925
|
+
this.entries().forEach(([_, item]) => {
|
|
926
|
+
const validTag = getValidTag(tag);
|
|
927
|
+
const xref = item.id;
|
|
928
|
+
const payload = item.exportValue?.();
|
|
929
|
+
if (xref) {
|
|
930
|
+
gedcom.push(
|
|
931
|
+
`${level} ${xref} ${validTag}${payload ? ` ${payload}` : ""}`
|
|
932
|
+
);
|
|
933
|
+
} else {
|
|
934
|
+
gedcom.push(
|
|
935
|
+
`${level} ${validTag}${payload ? ` ${payload}` : ""}`
|
|
936
|
+
);
|
|
937
|
+
}
|
|
938
|
+
gedcom.push(
|
|
939
|
+
...item.toGedcomLines(
|
|
940
|
+
validTag,
|
|
941
|
+
level + 1,
|
|
942
|
+
options
|
|
943
|
+
)
|
|
944
|
+
);
|
|
945
|
+
});
|
|
946
|
+
return gedcom;
|
|
965
947
|
}
|
|
966
|
-
|
|
967
|
-
const
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
948
|
+
toValue() {
|
|
949
|
+
const propList = new _List();
|
|
950
|
+
this.entries().forEach(([key, item]) => {
|
|
951
|
+
propList.item(key, item?.toValue());
|
|
952
|
+
});
|
|
953
|
+
return propList;
|
|
972
954
|
}
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
return rin;
|
|
977
|
-
}
|
|
978
|
-
return "familysearch";
|
|
955
|
+
// @deprecated use get instead
|
|
956
|
+
toProp(tag) {
|
|
957
|
+
return this.get(tag);
|
|
979
958
|
}
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
959
|
+
toList() {
|
|
960
|
+
return new _List().concat(this.items);
|
|
961
|
+
}
|
|
962
|
+
toValueList() {
|
|
963
|
+
const newList = new _List();
|
|
964
|
+
this.values().forEach((value) => {
|
|
965
|
+
value.value && newList.item(value.value, value);
|
|
966
|
+
});
|
|
967
|
+
return newList;
|
|
968
|
+
}
|
|
969
|
+
};
|
|
970
|
+
|
|
971
|
+
// src/classes/common.ts
|
|
972
|
+
var Common = class _Common {
|
|
973
|
+
constructor(gedcom, id, main, parent) {
|
|
974
|
+
this.isListable = true;
|
|
975
|
+
this._gedcom = gedcom;
|
|
976
|
+
this._main = main;
|
|
977
|
+
this._parent = parent;
|
|
978
|
+
this.initUniqueId();
|
|
979
|
+
if (id) {
|
|
980
|
+
this._id = id;
|
|
981
|
+
} else {
|
|
982
|
+
delete this._id;
|
|
984
983
|
}
|
|
985
|
-
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
986
|
-
return fileName || "FamilySearch Import";
|
|
987
984
|
}
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
const idMatch = fileName.match(/_(\d+)/);
|
|
992
|
-
if (idMatch) {
|
|
993
|
-
return idMatch[1];
|
|
994
|
-
}
|
|
985
|
+
set type(type) {
|
|
986
|
+
if (type) {
|
|
987
|
+
this.uniqueId = this.uniqueId?.replace(/^[^:]+/, `~${type}`);
|
|
995
988
|
}
|
|
996
|
-
|
|
989
|
+
this._type = type;
|
|
997
990
|
}
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
991
|
+
get type() {
|
|
992
|
+
return this._type;
|
|
1001
993
|
}
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
const idMatch = fileName.match(/_(\d+)/);
|
|
1006
|
-
if (idMatch) {
|
|
1007
|
-
return idMatch[1];
|
|
1008
|
-
}
|
|
994
|
+
initUniqueId() {
|
|
995
|
+
if (this._gedcom) {
|
|
996
|
+
this.uniqueId = `~Common:${this._gedcom.refcount++}`;
|
|
1009
997
|
}
|
|
1010
|
-
return void 0;
|
|
1011
|
-
}
|
|
1012
|
-
getGeniTreeName() {
|
|
1013
|
-
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1014
|
-
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
1015
998
|
}
|
|
1016
|
-
|
|
1017
|
-
const
|
|
1018
|
-
if (
|
|
1019
|
-
|
|
1020
|
-
if (
|
|
1021
|
-
|
|
999
|
+
set uniqueId(id) {
|
|
1000
|
+
const currentId = this._uniqueId;
|
|
1001
|
+
if (this._gedcom?.reflist && id) {
|
|
1002
|
+
this._uniqueId = id;
|
|
1003
|
+
if (currentId && this._gedcom.reflist[currentId]) {
|
|
1004
|
+
delete this._gedcom.reflist[currentId];
|
|
1022
1005
|
}
|
|
1006
|
+
this._gedcom.reflist[id] = this;
|
|
1023
1007
|
}
|
|
1024
|
-
return void 0;
|
|
1025
1008
|
}
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
1009
|
+
get uniqueId() {
|
|
1010
|
+
return this._uniqueId;
|
|
1029
1011
|
}
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
if (rin) {
|
|
1033
|
-
return rin;
|
|
1034
|
-
}
|
|
1035
|
-
return `gno_${this._gedcom?.refcount || "unknown"}`;
|
|
1012
|
+
set id(id) {
|
|
1013
|
+
this._id = idGetter(id);
|
|
1036
1014
|
}
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
if (treeName) {
|
|
1040
|
-
return treeName;
|
|
1041
|
-
}
|
|
1042
|
-
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1043
|
-
return fileName || "GNO2GED Export";
|
|
1015
|
+
get id() {
|
|
1016
|
+
return idGetter(this._id);
|
|
1044
1017
|
}
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
const sourceType = this.getSourceType();
|
|
1051
|
-
const prefix = sourceType ? sourceType.toLowerCase() : "tree";
|
|
1052
|
-
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1053
|
-
if (fileName) {
|
|
1054
|
-
const idMatch = fileName.match(/_(\d+)/);
|
|
1055
|
-
if (idMatch) {
|
|
1056
|
-
return `${prefix}_${idMatch[1]}`;
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1059
|
-
return `${prefix}_${this._gedcom?.refcount || "unknown"}`;
|
|
1018
|
+
set value(value) {
|
|
1019
|
+
this._value = value;
|
|
1020
|
+
}
|
|
1021
|
+
get value() {
|
|
1022
|
+
return this._value;
|
|
1060
1023
|
}
|
|
1061
1024
|
/**
|
|
1062
|
-
*
|
|
1063
|
-
*
|
|
1025
|
+
* Set the gedcom reference for this object
|
|
1026
|
+
* @param gedcom - The GedComType to set as the gedcom reference
|
|
1064
1027
|
*/
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
const prefix = sourceType ? `${sourceType}-` : "";
|
|
1068
|
-
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1069
|
-
if (fileName) {
|
|
1070
|
-
const cleanName = fileName.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
1071
|
-
return `${prefix}${cleanName}`;
|
|
1072
|
-
}
|
|
1073
|
-
const sourName = get(this, "HEAD.SOUR.NAME.value") || get(this.getGedcom(), "HEAD.SOUR.NAME.value");
|
|
1074
|
-
if (sourName) {
|
|
1075
|
-
return `${prefix}${sourName}`;
|
|
1076
|
-
}
|
|
1077
|
-
const sourValue = get(this, "HEAD.SOUR.value") || get(this.getGedcom(), "HEAD.SOUR.value");
|
|
1078
|
-
if (sourValue) {
|
|
1079
|
-
return `${prefix}${sourValue}`;
|
|
1080
|
-
}
|
|
1081
|
-
return `${prefix}Unknown Tree`;
|
|
1082
|
-
}
|
|
1083
|
-
getTreeName() {
|
|
1084
|
-
if (this?.isAncestry()) {
|
|
1085
|
-
const name = this.getAncestryTreeName();
|
|
1086
|
-
if (name) return name;
|
|
1087
|
-
}
|
|
1088
|
-
if (this?.isMyHeritage()) {
|
|
1089
|
-
const name = this.getMyHeritageTreeName();
|
|
1090
|
-
if (name) return name;
|
|
1091
|
-
}
|
|
1092
|
-
if (this?.isFamilySearch()) {
|
|
1093
|
-
const name = this.getFamilySearchTreeName();
|
|
1094
|
-
if (name) return name;
|
|
1095
|
-
}
|
|
1096
|
-
if (this?.isGNO2GED()) {
|
|
1097
|
-
const name = this.getGNO2GEDTreeName();
|
|
1098
|
-
if (name) return name;
|
|
1099
|
-
}
|
|
1100
|
-
if (this?.isAhnenblatt()) {
|
|
1101
|
-
const name = this.getAhnenblattTreeName();
|
|
1102
|
-
if (name) return name;
|
|
1103
|
-
}
|
|
1104
|
-
if (this?.isGeni()) {
|
|
1105
|
-
const name = this.getGeniTreeName();
|
|
1106
|
-
if (name) return name;
|
|
1107
|
-
}
|
|
1108
|
-
if (this?.isGenoPro()) {
|
|
1109
|
-
const name = this.getGenoProTreeName();
|
|
1110
|
-
if (name) return name;
|
|
1111
|
-
}
|
|
1112
|
-
return this.getUniversalTreeName();
|
|
1113
|
-
}
|
|
1114
|
-
};
|
|
1115
|
-
var createProxy = (target) => {
|
|
1116
|
-
return new Proxy(target, {
|
|
1117
|
-
get(t, prop, receiver) {
|
|
1118
|
-
if (prop === "unwrapped") {
|
|
1119
|
-
return target;
|
|
1120
|
-
}
|
|
1121
|
-
if (prop in t) {
|
|
1122
|
-
return Reflect.get(t, prop, receiver);
|
|
1123
|
-
}
|
|
1124
|
-
if (!isOnlyMainProp(prop)) {
|
|
1125
|
-
const ref = t.ref;
|
|
1126
|
-
if (ref && prop in ref) {
|
|
1127
|
-
return Reflect.get(ref, prop, receiver);
|
|
1128
|
-
}
|
|
1129
|
-
}
|
|
1130
|
-
}
|
|
1131
|
-
});
|
|
1132
|
-
};
|
|
1133
|
-
var createCommon = (gedcom, id, main, parent) => {
|
|
1134
|
-
return createProxy(
|
|
1135
|
-
new Common(gedcom, id, main, parent)
|
|
1136
|
-
);
|
|
1137
|
-
};
|
|
1138
|
-
var isOnlyMainProp = (key) => {
|
|
1139
|
-
return key === "_gedcom" || key === "_main" || key === "_parent" || key === "_uniqueId" || key === "_type" || key === "_refs" || key === "id" || key === "_id";
|
|
1140
|
-
};
|
|
1141
|
-
var isValidKey = (common, key) => {
|
|
1142
|
-
const prop = get(common, key);
|
|
1143
|
-
return key !== "_gedcom" && key !== "_main" && key !== "_parent" && key !== "_uniqueId" && key !== "_refs" && key !== "_type" && (key === "id" || key === "_id" || key === "value" || key === "_value" || prop instanceof Common || prop instanceof List);
|
|
1144
|
-
};
|
|
1145
|
-
var getValidKeys = (common) => {
|
|
1146
|
-
return Object.keys(common).filter((key) => {
|
|
1147
|
-
return isValidKey(common, key);
|
|
1148
|
-
});
|
|
1149
|
-
};
|
|
1150
|
-
var getValidTag = (tag) => {
|
|
1151
|
-
return tag.replace(/^@@/, "");
|
|
1152
|
-
};
|
|
1153
|
-
var getListTag = (tag) => {
|
|
1154
|
-
return `@@${tag}`;
|
|
1155
|
-
};
|
|
1156
|
-
var isId = (string) => {
|
|
1157
|
-
return ID_REG.test(string);
|
|
1158
|
-
};
|
|
1159
|
-
var idGetter = (id) => {
|
|
1160
|
-
if (id === void 0) {
|
|
1161
|
-
return void 0;
|
|
1162
|
-
}
|
|
1163
|
-
let newId = `${id}`;
|
|
1164
|
-
const parts = newId?.match(ID_GETTER_REG)?.groups;
|
|
1165
|
-
if (!parts?.at && !parts?.letter) {
|
|
1166
|
-
newId = `@U${newId}`;
|
|
1167
|
-
} else if (!parts.at) {
|
|
1168
|
-
newId = `@${newId}`;
|
|
1169
|
-
} else if (!parts.letter) {
|
|
1170
|
-
newId = newId.replace(/^@/, "@U");
|
|
1028
|
+
setGedcom(gedcom) {
|
|
1029
|
+
this._gedcom = gedcom;
|
|
1171
1030
|
}
|
|
1172
|
-
|
|
1173
|
-
|
|
1031
|
+
// avoid to override
|
|
1032
|
+
get originalValue() {
|
|
1033
|
+
return this._value;
|
|
1174
1034
|
}
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
//
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
constructor(items) {
|
|
1182
|
-
this.items = {};
|
|
1183
|
-
this.isListable = true;
|
|
1184
|
-
this.marker = void 0;
|
|
1185
|
-
if (items) {
|
|
1186
|
-
this.concat(items);
|
|
1035
|
+
get ref() {
|
|
1036
|
+
if (typeof this.value === "string" && isId(this.value) && this.refType) {
|
|
1037
|
+
return this._gedcom?.[getListTag(this.refType)]?.item(
|
|
1038
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1039
|
+
this.value
|
|
1040
|
+
);
|
|
1187
1041
|
}
|
|
1042
|
+
return this;
|
|
1188
1043
|
}
|
|
1189
|
-
get
|
|
1190
|
-
return this.
|
|
1191
|
-
}
|
|
1192
|
-
has(indi) {
|
|
1193
|
-
return !!this.item(
|
|
1194
|
-
typeof indi === "string" ? indi : indi?.id ?? ""
|
|
1195
|
-
);
|
|
1044
|
+
get main() {
|
|
1045
|
+
return this._main;
|
|
1196
1046
|
}
|
|
1197
|
-
get(
|
|
1198
|
-
|
|
1199
|
-
this.entries().forEach(([key, item]) => {
|
|
1200
|
-
propList.item(key, item.get(name));
|
|
1201
|
-
});
|
|
1202
|
-
return propList;
|
|
1047
|
+
get parent() {
|
|
1048
|
+
return this._parent;
|
|
1203
1049
|
}
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
if (passedItem) {
|
|
1209
|
-
propList.item(key, passedItem);
|
|
1050
|
+
addRef(refNode) {
|
|
1051
|
+
if (typeof refNode.value === "string" && isId(refNode.value) && refNode.refType) {
|
|
1052
|
+
if (!this._refs) {
|
|
1053
|
+
this._refs = new List();
|
|
1210
1054
|
}
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
}
|
|
1214
|
-
keys() {
|
|
1215
|
-
return Object.keys(this.items);
|
|
1216
|
-
}
|
|
1217
|
-
values() {
|
|
1218
|
-
return Object.values(this.items);
|
|
1219
|
-
}
|
|
1220
|
-
entries() {
|
|
1221
|
-
return Object.entries(this.items);
|
|
1222
|
-
}
|
|
1223
|
-
setLength(_type) {
|
|
1055
|
+
this._refs.item(refNode.value, refNode);
|
|
1056
|
+
}
|
|
1224
1057
|
}
|
|
1225
|
-
|
|
1226
|
-
return this.
|
|
1058
|
+
getRefs() {
|
|
1059
|
+
return this._refs;
|
|
1227
1060
|
}
|
|
1228
|
-
|
|
1229
|
-
return this.
|
|
1061
|
+
exportValue() {
|
|
1062
|
+
return this.value;
|
|
1230
1063
|
}
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
const key = keys[index];
|
|
1234
|
-
return key && this.items[key];
|
|
1064
|
+
removeValue() {
|
|
1065
|
+
delete this._value;
|
|
1235
1066
|
}
|
|
1236
|
-
|
|
1237
|
-
if (
|
|
1238
|
-
|
|
1239
|
-
this.setLength();
|
|
1067
|
+
set(name, value) {
|
|
1068
|
+
if (isGedcomTrailerTag(name)) {
|
|
1069
|
+
return void 0;
|
|
1240
1070
|
}
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
this.setLength();
|
|
1246
|
-
}
|
|
1247
|
-
exclude(excludedList) {
|
|
1248
|
-
excludedList.keys().forEach((itemId) => {
|
|
1249
|
-
delete this.items[itemId];
|
|
1250
|
-
});
|
|
1251
|
-
this.setLength();
|
|
1252
|
-
return this;
|
|
1253
|
-
}
|
|
1254
|
-
concat(items) {
|
|
1255
|
-
if (Array.isArray(items)) {
|
|
1256
|
-
items.forEach((item) => {
|
|
1257
|
-
this.append(item);
|
|
1258
|
-
});
|
|
1071
|
+
if (typeof value === "string") {
|
|
1072
|
+
const usedValue = createCommon(this._gedcom, void 0, this.main);
|
|
1073
|
+
usedValue.value = value;
|
|
1074
|
+
set(this, name, usedValue);
|
|
1259
1075
|
} else {
|
|
1260
|
-
|
|
1076
|
+
set(this, name, value);
|
|
1261
1077
|
}
|
|
1262
|
-
this
|
|
1263
|
-
return this;
|
|
1078
|
+
return get(this, name);
|
|
1264
1079
|
}
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
);
|
|
1275
|
-
return new _List(inter);
|
|
1276
|
-
}
|
|
1277
|
-
difference(mergedList) {
|
|
1278
|
-
const inter = differenceBy(
|
|
1279
|
-
this.values(),
|
|
1280
|
-
mergedList?.values() ?? [],
|
|
1281
|
-
"id"
|
|
1282
|
-
);
|
|
1283
|
-
return new _List(inter);
|
|
1284
|
-
}
|
|
1285
|
-
prepend(item) {
|
|
1286
|
-
if (item.id) {
|
|
1287
|
-
let increase = true;
|
|
1288
|
-
if (this.items[item.id]) {
|
|
1289
|
-
delete this.items[item.id];
|
|
1290
|
-
increase = false;
|
|
1291
|
-
}
|
|
1292
|
-
this.items = Object.assign(
|
|
1293
|
-
{
|
|
1294
|
-
[item.id]: item
|
|
1295
|
-
},
|
|
1296
|
-
this.items
|
|
1297
|
-
);
|
|
1298
|
-
if (increase) {
|
|
1299
|
-
this.setLength("increase");
|
|
1080
|
+
assign(name, value, unique = false) {
|
|
1081
|
+
if (isGedcomTrailerTag(name)) {
|
|
1082
|
+
return void 0;
|
|
1083
|
+
}
|
|
1084
|
+
let curValue = this.get(name);
|
|
1085
|
+
if (curValue?.isListable) {
|
|
1086
|
+
if (curValue instanceof _Common) {
|
|
1087
|
+
curValue = new List().concat({ ...[curValue] });
|
|
1088
|
+
this.set(name, curValue);
|
|
1300
1089
|
}
|
|
1090
|
+
const values = [
|
|
1091
|
+
...curValue.values(),
|
|
1092
|
+
...value instanceof List ? value.values() : [value]
|
|
1093
|
+
];
|
|
1094
|
+
curValue.concat({
|
|
1095
|
+
...!unique ? values : uniqBy(
|
|
1096
|
+
values,
|
|
1097
|
+
(value2) => value2 instanceof _Common ? value2?.value : void 0
|
|
1098
|
+
)
|
|
1099
|
+
});
|
|
1100
|
+
} else {
|
|
1101
|
+
this.set(name, value);
|
|
1301
1102
|
}
|
|
1302
|
-
return this;
|
|
1103
|
+
return get(this, name);
|
|
1303
1104
|
}
|
|
1304
|
-
|
|
1305
|
-
if (
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1105
|
+
get(name) {
|
|
1106
|
+
if (!name.includes(".")) {
|
|
1107
|
+
return get(this, name);
|
|
1108
|
+
}
|
|
1109
|
+
const nameParts = name.split(".");
|
|
1110
|
+
let last = this;
|
|
1111
|
+
for (const part of nameParts) {
|
|
1112
|
+
const indexPart = Number(part);
|
|
1113
|
+
const itemIndex = part.match(/items\[(?<itemIndex>\d+)\]/)?.groups?.itemIndex;
|
|
1114
|
+
const itemId = part.match(/items\[(?<itemId>@[A-Z]+\d+@)\]/)?.groups?.itemId;
|
|
1115
|
+
const usedPart = itemId || itemIndex;
|
|
1116
|
+
if (last instanceof List) {
|
|
1117
|
+
if (!isNaN(indexPart)) {
|
|
1118
|
+
last = last.index(indexPart);
|
|
1119
|
+
} else {
|
|
1120
|
+
if (usedPart) {
|
|
1121
|
+
last = last.item(usedPart);
|
|
1122
|
+
} else {
|
|
1123
|
+
last = last?.index(0)?.get(part);
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
} else {
|
|
1127
|
+
const usedIndex = Number(itemIndex ?? indexPart);
|
|
1128
|
+
if (!isNaN(usedIndex)) {
|
|
1129
|
+
last = last?.toList().index(usedIndex);
|
|
1130
|
+
} else {
|
|
1131
|
+
last = last?.get(itemId ?? part);
|
|
1132
|
+
}
|
|
1310
1133
|
}
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
this.setLength("increase");
|
|
1134
|
+
if (!last) {
|
|
1135
|
+
break;
|
|
1314
1136
|
}
|
|
1315
1137
|
}
|
|
1316
|
-
return
|
|
1138
|
+
return last;
|
|
1317
1139
|
}
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1140
|
+
remove(name) {
|
|
1141
|
+
unset(this, name);
|
|
1142
|
+
}
|
|
1143
|
+
getGedcom() {
|
|
1144
|
+
return this._gedcom;
|
|
1145
|
+
}
|
|
1146
|
+
getIf(name, condition, name2) {
|
|
1147
|
+
const nameParts = name.split(".");
|
|
1148
|
+
const name2Parts = name2.split(".");
|
|
1149
|
+
if (nameParts.length !== name2Parts.length) {
|
|
1150
|
+
throw new Error("Tag pathes must be of the same depth");
|
|
1322
1151
|
}
|
|
1323
|
-
|
|
1152
|
+
if (nameParts.length > 1 && nameParts[0] !== name2Parts[0]) {
|
|
1153
|
+
throw new Error("Final tags must be siblings");
|
|
1154
|
+
}
|
|
1155
|
+
const valueCommon = this.get(name);
|
|
1156
|
+
if (valueCommon instanceof _Common) {
|
|
1157
|
+
return valueCommon?.toValue() !== condition ? void 0 : this.get(name2);
|
|
1158
|
+
}
|
|
1159
|
+
const valueCommon2 = this.get(name2)?.toList();
|
|
1160
|
+
const ifList = new List();
|
|
1161
|
+
valueCommon?.forEach((item, key) => {
|
|
1162
|
+
const pair = valueCommon2?.item(key);
|
|
1163
|
+
ifList.item(key, item?.toValue() !== condition ? void 0 : pair);
|
|
1164
|
+
});
|
|
1165
|
+
return ifList;
|
|
1324
1166
|
}
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
Object.assign(newList.items, this.items);
|
|
1328
|
-
newList.setLength();
|
|
1329
|
-
return newList;
|
|
1167
|
+
toString() {
|
|
1168
|
+
return this.value?.toString() || "";
|
|
1330
1169
|
}
|
|
1331
|
-
|
|
1332
|
-
return this.
|
|
1170
|
+
toValue() {
|
|
1171
|
+
return this.value;
|
|
1333
1172
|
}
|
|
1334
|
-
|
|
1335
|
-
this.
|
|
1336
|
-
|
|
1337
|
-
});
|
|
1173
|
+
toProp(tag) {
|
|
1174
|
+
const prop = this.get(tag);
|
|
1175
|
+
return prop;
|
|
1338
1176
|
}
|
|
1339
|
-
|
|
1340
|
-
return
|
|
1341
|
-
|
|
1342
|
-
|
|
1177
|
+
toList() {
|
|
1178
|
+
return new List().concat(
|
|
1179
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1180
|
+
this.id ? { [this.id]: this } : { ...[this] }
|
|
1181
|
+
);
|
|
1343
1182
|
}
|
|
1344
|
-
|
|
1345
|
-
return this.
|
|
1346
|
-
return iterate(acc, item, key, index);
|
|
1347
|
-
}, initialValue);
|
|
1183
|
+
index(i) {
|
|
1184
|
+
return this.toList()?.index(i);
|
|
1348
1185
|
}
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1186
|
+
toValueList() {
|
|
1187
|
+
return new List().concat(
|
|
1188
|
+
this.value ? { [this.value]: this } : (
|
|
1189
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1190
|
+
{ ...[this] }
|
|
1191
|
+
)
|
|
1192
|
+
);
|
|
1193
|
+
}
|
|
1194
|
+
standardizeObject(tag, options) {
|
|
1195
|
+
if (tag === "OBJE" && options?.obje?.standardize && "standardizeMedia" in this) {
|
|
1196
|
+
const standardize = this.standardizeMedia;
|
|
1197
|
+
return standardize.call(
|
|
1198
|
+
this,
|
|
1199
|
+
options.obje.namespace,
|
|
1200
|
+
options.obje.override,
|
|
1201
|
+
void 0,
|
|
1202
|
+
options.gedcomVersion
|
|
1203
|
+
);
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
toJson(tag, options) {
|
|
1207
|
+
const json = this.toObject(tag, options);
|
|
1208
|
+
return JSON.stringify(json);
|
|
1209
|
+
}
|
|
1210
|
+
toObject(tag, options) {
|
|
1211
|
+
this.standardizeObject(tag, options);
|
|
1212
|
+
const validKeys = getValidKeys(this);
|
|
1213
|
+
let json = {};
|
|
1214
|
+
validKeys.forEach((key) => {
|
|
1215
|
+
if (key === "id" && this.id !== void 0) {
|
|
1216
|
+
json.id = this.id;
|
|
1217
|
+
} else if (key === "_id" && this._id !== void 0) {
|
|
1218
|
+
json.id = this._id;
|
|
1219
|
+
} else if (key === "value" && this.value !== void 0) {
|
|
1220
|
+
json.value = this.value;
|
|
1221
|
+
} else if (key === "_value" && this._value !== void 0) {
|
|
1222
|
+
json.value = this._value;
|
|
1223
|
+
} else {
|
|
1224
|
+
const validKey = key;
|
|
1225
|
+
const prop = this.get(validKey);
|
|
1226
|
+
if (typeof prop?.toObject === "function") {
|
|
1227
|
+
if (prop instanceof _Common) {
|
|
1228
|
+
json[validKey] = prop.toObject(validKey, options);
|
|
1229
|
+
} else if (prop instanceof List) {
|
|
1230
|
+
json = {
|
|
1231
|
+
...json,
|
|
1232
|
+
...prop.toObject(validKey, options)
|
|
1233
|
+
};
|
|
1234
|
+
}
|
|
1366
1235
|
}
|
|
1367
|
-
return itemValue === value;
|
|
1368
|
-
})) {
|
|
1369
|
-
newList.item(itemId, item);
|
|
1370
1236
|
}
|
|
1371
1237
|
});
|
|
1372
|
-
return
|
|
1238
|
+
return json;
|
|
1373
1239
|
}
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
}
|
|
1383
|
-
return false;
|
|
1240
|
+
merge(other, override = false, avoidKeys = []) {
|
|
1241
|
+
if (!other) {
|
|
1242
|
+
return this;
|
|
1243
|
+
}
|
|
1244
|
+
const validKeys = getValidKeys(other);
|
|
1245
|
+
validKeys.forEach((validKey) => {
|
|
1246
|
+
if (avoidKeys.includes(validKey)) {
|
|
1247
|
+
return;
|
|
1384
1248
|
}
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1249
|
+
const current = this.get(validKey);
|
|
1250
|
+
const mergeValue = other.get(validKey);
|
|
1251
|
+
if (mergeValue) {
|
|
1252
|
+
if (current instanceof _Common || current instanceof List) {
|
|
1253
|
+
this.assign(validKey, mergeValue, true);
|
|
1254
|
+
} else if (!current || override && validKey !== "id" && validKey !== "_id") {
|
|
1255
|
+
this.set(validKey, mergeValue);
|
|
1391
1256
|
}
|
|
1392
|
-
if (Array.isArray(value)) {
|
|
1393
|
-
return value.includes(itemValue);
|
|
1394
|
-
}
|
|
1395
|
-
return itemValue === value;
|
|
1396
|
-
})) {
|
|
1397
|
-
foundItem = item;
|
|
1398
|
-
return true;
|
|
1399
1257
|
}
|
|
1400
|
-
return false;
|
|
1401
1258
|
});
|
|
1402
|
-
return
|
|
1259
|
+
return this;
|
|
1403
1260
|
}
|
|
1404
|
-
|
|
1405
|
-
const
|
|
1406
|
-
const
|
|
1407
|
-
|
|
1408
|
-
|
|
1261
|
+
clone(newId = false, avoidKeys = []) {
|
|
1262
|
+
const ctor = this.constructor;
|
|
1263
|
+
const instance = new ctor(
|
|
1264
|
+
this._gedcom,
|
|
1265
|
+
this._id,
|
|
1266
|
+
this._main,
|
|
1267
|
+
this._parent
|
|
1268
|
+
);
|
|
1269
|
+
if (newId && this._id) {
|
|
1270
|
+
instance.id = `IFT${this._id.replace(/[^0-9]/g, "")}`;
|
|
1409
1271
|
}
|
|
1410
|
-
const
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1272
|
+
const cloned = createProxy(instance);
|
|
1273
|
+
cloned.merge(this, true, avoidKeys);
|
|
1274
|
+
return cloned;
|
|
1275
|
+
}
|
|
1276
|
+
// fromGedcom<T = typeof this>(value: string) {
|
|
1277
|
+
fromGedcom(_value) {
|
|
1278
|
+
}
|
|
1279
|
+
toGedcom(tag, level = 0, options) {
|
|
1280
|
+
const gedcom = this.toGedcomLines(tag, level, options);
|
|
1281
|
+
return gedcom.join("\n");
|
|
1282
|
+
}
|
|
1283
|
+
toGedcomLines(tag, level = 0, options) {
|
|
1284
|
+
this.standardizeObject(tag, options);
|
|
1285
|
+
const validKeys = getValidKeys(this);
|
|
1286
|
+
const gedcom = [];
|
|
1287
|
+
const isGedcom7Export = options?.gedcomVersion === "7.0";
|
|
1288
|
+
validKeys.forEach((key) => {
|
|
1289
|
+
const validKey = key;
|
|
1290
|
+
if (isGedcom7Export && validKey === "CONC") {
|
|
1291
|
+
return;
|
|
1292
|
+
}
|
|
1293
|
+
const prop = this.get(validKey);
|
|
1294
|
+
if (typeof prop?.toGedcomLines === "function") {
|
|
1295
|
+
if (prop instanceof _Common) {
|
|
1296
|
+
const value = prop.exportValue();
|
|
1297
|
+
gedcom.push(
|
|
1298
|
+
`${level} ${validKey}${value ? ` ${value}` : ""}`
|
|
1299
|
+
);
|
|
1300
|
+
gedcom.push(
|
|
1301
|
+
...prop.toGedcomLines(validKey, level + 1, options)
|
|
1302
|
+
);
|
|
1303
|
+
} else if (prop instanceof List) {
|
|
1304
|
+
gedcom.push(
|
|
1305
|
+
...prop.toGedcomLines(validKey, level, options)
|
|
1306
|
+
);
|
|
1437
1307
|
}
|
|
1438
|
-
return sortValue2 * (direction === "DESC" ? -1 : 1);
|
|
1439
1308
|
}
|
|
1440
|
-
);
|
|
1441
|
-
sortedItems.forEach(([key, value]) => {
|
|
1442
|
-
newList.item(key, value);
|
|
1443
1309
|
});
|
|
1444
|
-
return
|
|
1310
|
+
return gedcom;
|
|
1445
1311
|
}
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1312
|
+
getHeadRecord() {
|
|
1313
|
+
return get(this, "HEAD") || get(this.getGedcom(), "HEAD");
|
|
1314
|
+
}
|
|
1315
|
+
getOriginalHeadRecord() {
|
|
1316
|
+
return get(this, ORIG_HEAD_TAG) || get(this.getGedcom(), ORIG_HEAD_TAG) || get(this.getHeadRecord(), ORIG_HEAD_TAG);
|
|
1317
|
+
}
|
|
1318
|
+
getSourceHeads() {
|
|
1319
|
+
const heads = [this.getOriginalHeadRecord(), this.getHeadRecord()];
|
|
1320
|
+
return heads.filter((head, index) => {
|
|
1321
|
+
return Boolean(head && heads.indexOf(head) === index);
|
|
1322
|
+
});
|
|
1323
|
+
}
|
|
1324
|
+
getFromSourceHeads(path) {
|
|
1325
|
+
for (const head of this.getSourceHeads()) {
|
|
1326
|
+
const value = get(head, path);
|
|
1327
|
+
if (value !== void 0 && value !== null && value !== "") {
|
|
1328
|
+
return value;
|
|
1329
|
+
}
|
|
1453
1330
|
}
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1331
|
+
return void 0;
|
|
1332
|
+
}
|
|
1333
|
+
sourStartsWith(prefix) {
|
|
1334
|
+
return this.getSourceHeads().some((head) => {
|
|
1335
|
+
const sour = get(head, "SOUR.value");
|
|
1336
|
+
return !!sour?.toLowerCase()?.startsWith(prefix);
|
|
1337
|
+
});
|
|
1338
|
+
}
|
|
1339
|
+
isGenoPro() {
|
|
1340
|
+
return this.sourStartsWith("genopro");
|
|
1341
|
+
}
|
|
1342
|
+
isAhnenblatt() {
|
|
1343
|
+
return this.sourStartsWith("ahnenblatt");
|
|
1344
|
+
}
|
|
1345
|
+
isGeni() {
|
|
1346
|
+
return this.sourStartsWith("geni");
|
|
1347
|
+
}
|
|
1348
|
+
isAncestry() {
|
|
1349
|
+
return this.sourStartsWith("ancestry");
|
|
1350
|
+
}
|
|
1351
|
+
isMyHeritage() {
|
|
1352
|
+
return this.sourStartsWith("myheritage");
|
|
1353
|
+
}
|
|
1354
|
+
/**
|
|
1355
|
+
* Get the source type as a string (for prefixing tree IDs and names)
|
|
1356
|
+
* Returns the detected source type or undefined if unknown
|
|
1357
|
+
*/
|
|
1358
|
+
getSourceType() {
|
|
1359
|
+
if (this.isAncestry()) return "Ancestry";
|
|
1360
|
+
if (this.isMyHeritage()) return "MyHeritage";
|
|
1361
|
+
if (this.isFamilySearch()) return "FamilySearch";
|
|
1362
|
+
if (this.isGNO2GED()) return "GNO2GED";
|
|
1363
|
+
if (this.isGenoPro()) return "GenoPro";
|
|
1364
|
+
if (this.isAhnenblatt()) return "Ahnenblatt";
|
|
1365
|
+
if (this.isGeni()) return "Geni";
|
|
1366
|
+
return void 0;
|
|
1367
|
+
}
|
|
1368
|
+
isFamilySearch() {
|
|
1369
|
+
return this.getSourceHeads().some((head) => {
|
|
1370
|
+
const sourName = get(head, "SOUR.NAME.value");
|
|
1371
|
+
return sourName === "FamilySearch API";
|
|
1372
|
+
});
|
|
1373
|
+
}
|
|
1374
|
+
isGNO2GED() {
|
|
1375
|
+
return this.getSourceHeads().some((head) => {
|
|
1376
|
+
const sour = get(head, "SOUR.value");
|
|
1377
|
+
return sour === "GNO2GED";
|
|
1378
|
+
});
|
|
1379
|
+
}
|
|
1380
|
+
getAncestryTreeId() {
|
|
1381
|
+
return this.getFromSourceHeads("SOUR._TREE.RIN.value") || (get(this, "HEAD.SOUR._TREE.RIN.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.RIN.value"));
|
|
1382
|
+
}
|
|
1383
|
+
getMyHeritageTreeId() {
|
|
1384
|
+
return this.getFromSourceHeads("_EXPORTED_FROM_SITE_ID.value") || (get(this, "HEAD._EXPORTED_FROM_SITE_ID.value") || get(this.getGedcom(), "HEAD._EXPORTED_FROM_SITE_ID.value"));
|
|
1385
|
+
}
|
|
1386
|
+
getTreeId() {
|
|
1387
|
+
if (this?.isAncestry()) {
|
|
1388
|
+
const id = this.getAncestryTreeId();
|
|
1389
|
+
if (id !== void 0) return id;
|
|
1390
|
+
}
|
|
1391
|
+
if (this?.isMyHeritage()) {
|
|
1392
|
+
const id = this.getMyHeritageTreeId();
|
|
1393
|
+
if (id !== void 0) return id;
|
|
1394
|
+
}
|
|
1395
|
+
if (this?.isFamilySearch()) {
|
|
1396
|
+
const id = this.getFamilySearchTreeId();
|
|
1397
|
+
if (id !== void 0) return id;
|
|
1398
|
+
}
|
|
1399
|
+
if (this?.isGNO2GED()) {
|
|
1400
|
+
const id = this.getGNO2GEDTreeId();
|
|
1401
|
+
if (id !== void 0) return id;
|
|
1402
|
+
}
|
|
1403
|
+
if (this?.isAhnenblatt()) {
|
|
1404
|
+
const id = this.getAhnenblattTreeId();
|
|
1405
|
+
if (id !== void 0) return id;
|
|
1406
|
+
}
|
|
1407
|
+
if (this?.isGeni()) {
|
|
1408
|
+
const id = this.getGeniTreeId();
|
|
1409
|
+
if (id !== void 0) return id;
|
|
1410
|
+
}
|
|
1411
|
+
if (this?.isGenoPro()) {
|
|
1412
|
+
const id = this.getGenoProTreeId();
|
|
1413
|
+
if (id !== void 0) return id;
|
|
1414
|
+
}
|
|
1415
|
+
return this.getUniversalTreeId();
|
|
1416
|
+
}
|
|
1417
|
+
getAncestryTreeName() {
|
|
1418
|
+
return this.getFromSourceHeads("SOUR._TREE.value") || (get(this, "HEAD.SOUR._TREE.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.value"));
|
|
1419
|
+
}
|
|
1420
|
+
getMyHeritageTreeName() {
|
|
1421
|
+
const path = "HEAD.FILE.value";
|
|
1422
|
+
const treeDetails = get(this, path) || get(this.getGedcom(), path);
|
|
1423
|
+
return treeDetails?.match(
|
|
1424
|
+
/Exported by MyHeritage.com from (?<tree>.+) in.+$/
|
|
1425
|
+
)?.groups?.tree;
|
|
1426
|
+
}
|
|
1427
|
+
getFamilySearchTreeId() {
|
|
1428
|
+
const rin = this.getFromSourceHeads("SOUR._TREE.RIN.value") || get(this, "HEAD.SOUR._TREE.RIN.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.RIN.value");
|
|
1429
|
+
if (rin) {
|
|
1430
|
+
return rin;
|
|
1431
|
+
}
|
|
1432
|
+
return "familysearch";
|
|
1433
|
+
}
|
|
1434
|
+
getFamilySearchTreeName() {
|
|
1435
|
+
const treeName = this.getFromSourceHeads("SOUR._TREE.value") || get(this, "HEAD.SOUR._TREE.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.value");
|
|
1436
|
+
if (treeName) {
|
|
1437
|
+
return treeName;
|
|
1438
|
+
}
|
|
1439
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1440
|
+
return fileName || "FamilySearch Import";
|
|
1441
|
+
}
|
|
1442
|
+
getAhnenblattTreeId() {
|
|
1443
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1444
|
+
if (fileName) {
|
|
1445
|
+
const idMatch = fileName.match(/_(\d+)/);
|
|
1446
|
+
if (idMatch) {
|
|
1447
|
+
return idMatch[1];
|
|
1473
1448
|
}
|
|
1474
|
-
|
|
1475
|
-
|
|
1449
|
+
}
|
|
1450
|
+
return void 0;
|
|
1451
|
+
}
|
|
1452
|
+
getAhnenblattTreeName() {
|
|
1453
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1454
|
+
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
1455
|
+
}
|
|
1456
|
+
getGeniTreeId() {
|
|
1457
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1458
|
+
if (fileName) {
|
|
1459
|
+
const idMatch = fileName.match(/_(\d+)/);
|
|
1460
|
+
if (idMatch) {
|
|
1461
|
+
return idMatch[1];
|
|
1476
1462
|
}
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
if (
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1463
|
+
}
|
|
1464
|
+
return void 0;
|
|
1465
|
+
}
|
|
1466
|
+
getGeniTreeName() {
|
|
1467
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1468
|
+
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
1469
|
+
}
|
|
1470
|
+
getGenoProTreeId() {
|
|
1471
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1472
|
+
if (fileName) {
|
|
1473
|
+
const idMatch = fileName.match(/_(\d+)/);
|
|
1474
|
+
if (idMatch) {
|
|
1475
|
+
return idMatch[1];
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1478
|
+
return void 0;
|
|
1479
|
+
}
|
|
1480
|
+
getGenoProTreeName() {
|
|
1481
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1482
|
+
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
1483
|
+
}
|
|
1484
|
+
getGNO2GEDTreeId() {
|
|
1485
|
+
const rin = get(this, "HEAD._TREE.RIN.value") || get(this.getGedcom(), "HEAD._TREE.RIN.value");
|
|
1486
|
+
if (rin) {
|
|
1487
|
+
return rin;
|
|
1488
|
+
}
|
|
1489
|
+
return `gno_${this._gedcom?.refcount || "unknown"}`;
|
|
1490
|
+
}
|
|
1491
|
+
getGNO2GEDTreeName() {
|
|
1492
|
+
const treeName = get(this, "HEAD._TREE.value") || get(this.getGedcom(), "HEAD._TREE.value");
|
|
1493
|
+
if (treeName) {
|
|
1494
|
+
return treeName;
|
|
1495
|
+
}
|
|
1496
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1497
|
+
return fileName || "GNO2GED Export";
|
|
1498
|
+
}
|
|
1499
|
+
/**
|
|
1500
|
+
* Universal tree ID getter for unknown/unrecognized GEDCOM sources
|
|
1501
|
+
* Tries to extract an ID from various common locations
|
|
1502
|
+
*/
|
|
1503
|
+
getUniversalTreeId() {
|
|
1504
|
+
const sourceType = this.getSourceType();
|
|
1505
|
+
const prefix = sourceType ? sourceType.toLowerCase() : "tree";
|
|
1506
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1507
|
+
if (fileName) {
|
|
1508
|
+
const idMatch = fileName.match(/_(\d+)/);
|
|
1509
|
+
if (idMatch) {
|
|
1510
|
+
return `${prefix}_${idMatch[1]}`;
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
return `${prefix}_${this._gedcom?.refcount || "unknown"}`;
|
|
1514
|
+
}
|
|
1515
|
+
/**
|
|
1516
|
+
* Universal tree name getter for unknown/unrecognized GEDCOM sources
|
|
1517
|
+
* Tries to extract a name from various common locations
|
|
1518
|
+
*/
|
|
1519
|
+
getUniversalTreeName() {
|
|
1520
|
+
const sourceType = this.getSourceType();
|
|
1521
|
+
const prefix = sourceType ? `${sourceType}-` : "";
|
|
1522
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1523
|
+
if (fileName) {
|
|
1524
|
+
const cleanName = fileName.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
1525
|
+
return `${prefix}${cleanName}`;
|
|
1526
|
+
}
|
|
1527
|
+
const sourName = this.getFromSourceHeads("SOUR.NAME.value") || get(this, "HEAD.SOUR.NAME.value") || get(this.getGedcom(), "HEAD.SOUR.NAME.value");
|
|
1528
|
+
if (sourName) {
|
|
1529
|
+
return `${prefix}${sourName}`;
|
|
1530
|
+
}
|
|
1531
|
+
const sourValue = this.getFromSourceHeads("SOUR.value") || get(this, "HEAD.SOUR.value") || get(this.getGedcom(), "HEAD.SOUR.value");
|
|
1532
|
+
if (sourValue) {
|
|
1533
|
+
return `${prefix}${sourValue}`;
|
|
1534
|
+
}
|
|
1535
|
+
return `${prefix}Unknown Tree`;
|
|
1536
|
+
}
|
|
1537
|
+
getTreeName() {
|
|
1538
|
+
if (this?.isAncestry()) {
|
|
1539
|
+
const name = this.getAncestryTreeName();
|
|
1540
|
+
if (name) return name;
|
|
1541
|
+
}
|
|
1542
|
+
if (this?.isMyHeritage()) {
|
|
1543
|
+
const name = this.getMyHeritageTreeName();
|
|
1544
|
+
if (name) return name;
|
|
1545
|
+
}
|
|
1546
|
+
if (this?.isFamilySearch()) {
|
|
1547
|
+
const name = this.getFamilySearchTreeName();
|
|
1548
|
+
if (name) return name;
|
|
1549
|
+
}
|
|
1550
|
+
if (this?.isGNO2GED()) {
|
|
1551
|
+
const name = this.getGNO2GEDTreeName();
|
|
1552
|
+
if (name) return name;
|
|
1553
|
+
}
|
|
1554
|
+
if (this?.isAhnenblatt()) {
|
|
1555
|
+
const name = this.getAhnenblattTreeName();
|
|
1556
|
+
if (name) return name;
|
|
1557
|
+
}
|
|
1558
|
+
if (this?.isGeni()) {
|
|
1559
|
+
const name = this.getGeniTreeName();
|
|
1560
|
+
if (name) return name;
|
|
1561
|
+
}
|
|
1562
|
+
if (this?.isGenoPro()) {
|
|
1563
|
+
const name = this.getGenoProTreeName();
|
|
1564
|
+
if (name) return name;
|
|
1565
|
+
}
|
|
1566
|
+
return this.getUniversalTreeName();
|
|
1567
|
+
}
|
|
1568
|
+
};
|
|
1569
|
+
var createProxy = (target) => {
|
|
1570
|
+
return new Proxy(target, {
|
|
1571
|
+
get(t, prop, receiver) {
|
|
1572
|
+
if (prop === "unwrapped") {
|
|
1573
|
+
return target;
|
|
1574
|
+
}
|
|
1575
|
+
if (prop in t) {
|
|
1576
|
+
return Reflect.get(t, prop, receiver);
|
|
1577
|
+
}
|
|
1578
|
+
if (!isOnlyMainProp(prop)) {
|
|
1579
|
+
const ref = t.ref;
|
|
1580
|
+
if (ref && prop in ref) {
|
|
1581
|
+
return Reflect.get(ref, prop, receiver);
|
|
1507
1582
|
}
|
|
1508
|
-
|
|
1509
|
-
}, {});
|
|
1583
|
+
}
|
|
1510
1584
|
}
|
|
1511
|
-
|
|
1585
|
+
});
|
|
1586
|
+
};
|
|
1587
|
+
var createCommon = (gedcom, id, main, parent) => {
|
|
1588
|
+
return createProxy(
|
|
1589
|
+
new Common(gedcom, id, main, parent)
|
|
1590
|
+
);
|
|
1591
|
+
};
|
|
1592
|
+
var isOnlyMainProp = (key) => {
|
|
1593
|
+
return key === "_gedcom" || key === "_main" || key === "_parent" || key === "_uniqueId" || key === "_type" || key === "_refs" || key === "id" || key === "_id";
|
|
1594
|
+
};
|
|
1595
|
+
var isValidKey = (common, key) => {
|
|
1596
|
+
const prop = get(common, key);
|
|
1597
|
+
return key !== "_gedcom" && key !== "_main" && key !== "_parent" && key !== "_uniqueId" && key !== "_refs" && key !== "_type" && !(typeof key === "string" && isGedcomTrailerTag(key)) && (key === "id" || key === "_id" || key === "value" || key === "_value" || prop instanceof Common || prop instanceof List);
|
|
1598
|
+
};
|
|
1599
|
+
var getValidKeys = (common) => {
|
|
1600
|
+
return Object.keys(common).filter((key) => {
|
|
1601
|
+
return isValidKey(common, key);
|
|
1602
|
+
});
|
|
1603
|
+
};
|
|
1604
|
+
var getValidTag = (tag) => {
|
|
1605
|
+
return tag.replace(/^@@/, "");
|
|
1606
|
+
};
|
|
1607
|
+
var getListTag = (tag) => {
|
|
1608
|
+
return `@@${tag}`;
|
|
1609
|
+
};
|
|
1610
|
+
var isId = (string) => {
|
|
1611
|
+
return ID_REG.test(string);
|
|
1612
|
+
};
|
|
1613
|
+
var idGetter = (id) => {
|
|
1614
|
+
if (id === void 0) {
|
|
1615
|
+
return void 0;
|
|
1616
|
+
}
|
|
1617
|
+
let newId = `${id}`;
|
|
1618
|
+
const parts = newId?.match(ID_GETTER_REG)?.groups;
|
|
1619
|
+
if (!parts?.at && !parts?.letter) {
|
|
1620
|
+
newId = `@U${newId}`;
|
|
1621
|
+
} else if (!parts.at) {
|
|
1622
|
+
newId = `@${newId}`;
|
|
1623
|
+
} else if (!parts.letter) {
|
|
1624
|
+
newId = newId.replace(/^@/, "@U");
|
|
1625
|
+
}
|
|
1626
|
+
if (!newId.endsWith("@")) {
|
|
1627
|
+
newId = `${newId}@`;
|
|
1628
|
+
}
|
|
1629
|
+
return newId;
|
|
1630
|
+
};
|
|
1631
|
+
|
|
1632
|
+
// src/utils/fact-edit.ts
|
|
1633
|
+
var SINGLETON_TAGS = /* @__PURE__ */ new Set(["BIRT", "DEAT", "SSN", "SEX", "DSCR"]);
|
|
1634
|
+
var firstRecord = (node) => {
|
|
1635
|
+
if (!node) {
|
|
1636
|
+
return void 0;
|
|
1637
|
+
}
|
|
1638
|
+
if (node instanceof List) {
|
|
1639
|
+
return node.index(0);
|
|
1640
|
+
}
|
|
1641
|
+
return node.index(0) ?? node;
|
|
1642
|
+
};
|
|
1643
|
+
var setDateOn = (gedcom, owner, parent, date) => {
|
|
1644
|
+
const trimmed = date.trim();
|
|
1645
|
+
if (!trimmed) {
|
|
1646
|
+
return;
|
|
1647
|
+
}
|
|
1648
|
+
let dateNode = parent.get("DATE");
|
|
1649
|
+
if (!dateNode || dateNode instanceof List) {
|
|
1650
|
+
dateNode = createCommonDate(gedcom, void 0, owner, parent);
|
|
1651
|
+
dateNode.type = "DATE";
|
|
1652
|
+
parent.set("DATE", dateNode);
|
|
1653
|
+
}
|
|
1654
|
+
dateNode.value = trimmed;
|
|
1655
|
+
};
|
|
1656
|
+
var fillFact = (gedcom, owner, event, input) => {
|
|
1657
|
+
if (input.value?.trim()) {
|
|
1658
|
+
event.value = input.value.trim();
|
|
1659
|
+
}
|
|
1660
|
+
if (input.type?.trim()) {
|
|
1661
|
+
event.set("TYPE", input.type.trim());
|
|
1662
|
+
}
|
|
1663
|
+
if (input.date) {
|
|
1664
|
+
setDateOn(gedcom, owner, event, input.date);
|
|
1665
|
+
}
|
|
1666
|
+
if (input.place?.trim()) {
|
|
1667
|
+
event.set("PLAC", input.place.trim());
|
|
1668
|
+
}
|
|
1669
|
+
if (input.note?.trim()) {
|
|
1670
|
+
event.set("NOTE", input.note.trim());
|
|
1671
|
+
}
|
|
1672
|
+
};
|
|
1673
|
+
var addIndividualFact = (indi, input) => {
|
|
1674
|
+
const gedcom = indi.getGedcom();
|
|
1675
|
+
if (!gedcom) {
|
|
1676
|
+
return void 0;
|
|
1677
|
+
}
|
|
1678
|
+
const tag = input.tag;
|
|
1679
|
+
let event = SINGLETON_TAGS.has(tag) ? firstRecord(indi.get(tag)) : void 0;
|
|
1680
|
+
if (!event) {
|
|
1681
|
+
event = createCommon(gedcom, void 0, indi);
|
|
1682
|
+
event.type = tag;
|
|
1683
|
+
if (SINGLETON_TAGS.has(tag)) {
|
|
1684
|
+
indi.set(tag, event);
|
|
1685
|
+
} else {
|
|
1686
|
+
indi.assign(tag, event);
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
fillFact(gedcom, indi, event, input);
|
|
1690
|
+
return event;
|
|
1691
|
+
};
|
|
1692
|
+
var addFamilyFact = (fam, input) => {
|
|
1693
|
+
const gedcom = fam.getGedcom();
|
|
1694
|
+
if (!gedcom) {
|
|
1695
|
+
return void 0;
|
|
1696
|
+
}
|
|
1697
|
+
const event = createCommon(gedcom, void 0, fam);
|
|
1698
|
+
event.type = input.tag;
|
|
1699
|
+
fam.assign(input.tag, event);
|
|
1700
|
+
fillFact(gedcom, fam, event, input);
|
|
1701
|
+
return event;
|
|
1702
|
+
};
|
|
1703
|
+
var addNonEvent = (owner, input) => {
|
|
1704
|
+
const gedcom = owner.getGedcom();
|
|
1705
|
+
const eventType = input.event?.trim().toUpperCase();
|
|
1706
|
+
if (!gedcom || !eventType) {
|
|
1707
|
+
return void 0;
|
|
1708
|
+
}
|
|
1709
|
+
const no = createCommon(gedcom, void 0, owner);
|
|
1710
|
+
no.type = "NO";
|
|
1711
|
+
no.value = eventType;
|
|
1712
|
+
if (input.date?.trim()) {
|
|
1713
|
+
setDateOn(gedcom, owner, no, input.date);
|
|
1714
|
+
}
|
|
1715
|
+
if (input.note?.trim()) {
|
|
1716
|
+
no.set("NOTE", input.note.trim());
|
|
1717
|
+
}
|
|
1718
|
+
owner.assign("NO", no);
|
|
1719
|
+
return no;
|
|
1720
|
+
};
|
|
1721
|
+
|
|
1722
|
+
// src/utils/family-edit.ts
|
|
1723
|
+
var PEDIGREE_VALUES = [
|
|
1724
|
+
"birth" /* BIRTH */,
|
|
1725
|
+
"adopted" /* ADOPTED */,
|
|
1726
|
+
"foster" /* FOSTER */,
|
|
1727
|
+
"step" /* STEP */,
|
|
1728
|
+
"sealing" /* SEALING */
|
|
1729
|
+
];
|
|
1730
|
+
var toGedcomPedigree = (value) => {
|
|
1731
|
+
const normalized = String(value || "birth" /* BIRTH */).toLowerCase();
|
|
1732
|
+
if (normalized === "biological" /* BIOLOGICAL */ || normalized === "birth" /* BIRTH */) {
|
|
1733
|
+
return "birth" /* BIRTH */;
|
|
1734
|
+
}
|
|
1735
|
+
const match = PEDIGREE_VALUES.find((item) => item === normalized);
|
|
1736
|
+
return match ?? "birth" /* BIRTH */;
|
|
1737
|
+
};
|
|
1738
|
+
var pointerIds = (tag) => {
|
|
1739
|
+
if (!tag) {
|
|
1740
|
+
return [];
|
|
1512
1741
|
}
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
return -1;
|
|
1516
|
-
}
|
|
1517
|
-
return this.keys().findIndex((key) => key === item.id);
|
|
1742
|
+
if (tag instanceof List) {
|
|
1743
|
+
return tag.values().map((item) => item?.toValue?.()).filter((value2) => !!value2);
|
|
1518
1744
|
}
|
|
1519
|
-
|
|
1520
|
-
|
|
1745
|
+
const value = tag.toValue?.();
|
|
1746
|
+
return value ? [String(value)] : [];
|
|
1747
|
+
};
|
|
1748
|
+
var firstPointerId = (tag) => pointerIds(tag)[0];
|
|
1749
|
+
var makePointer = (gedcom, parent, value, refType) => {
|
|
1750
|
+
const pointer = createCommon(gedcom, void 0, parent);
|
|
1751
|
+
pointer.value = value;
|
|
1752
|
+
pointer.refType = refType;
|
|
1753
|
+
return pointer;
|
|
1754
|
+
};
|
|
1755
|
+
var familyHasParent = (fam, indiId) => pointerIds(fam.get("HUSB")).includes(indiId) || pointerIds(fam.get("WIFE")).includes(indiId);
|
|
1756
|
+
var familyHasChild = (fam, indiId) => pointerIds(fam.get("CHIL")).includes(indiId);
|
|
1757
|
+
var spouseTagFor = (indi, fam) => {
|
|
1758
|
+
const husbId = firstPointerId(fam.get("HUSB"));
|
|
1759
|
+
const wifeId = firstPointerId(fam.get("WIFE"));
|
|
1760
|
+
if (husbId === indi.id) {
|
|
1761
|
+
return "HUSB";
|
|
1521
1762
|
}
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
return JSON.stringify(json);
|
|
1763
|
+
if (wifeId === indi.id) {
|
|
1764
|
+
return "WIFE";
|
|
1525
1765
|
}
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
this.entries().forEach(([_, item]) => {
|
|
1529
|
-
const validTag = getValidTag(tag);
|
|
1530
|
-
if (json[validTag]) {
|
|
1531
|
-
if (!Array.isArray(json[validTag])) {
|
|
1532
|
-
json[validTag] = [json[validTag]];
|
|
1533
|
-
}
|
|
1534
|
-
json[validTag].push(
|
|
1535
|
-
item.toObject(validTag, options)
|
|
1536
|
-
);
|
|
1537
|
-
} else {
|
|
1538
|
-
json[validTag] = item.toObject(
|
|
1539
|
-
validTag,
|
|
1540
|
-
options
|
|
1541
|
-
);
|
|
1542
|
-
}
|
|
1543
|
-
});
|
|
1544
|
-
return json;
|
|
1766
|
+
if (indi.isFemale()) {
|
|
1767
|
+
return wifeId && wifeId !== indi.id ? "HUSB" : "WIFE";
|
|
1545
1768
|
}
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
return gedcom.join("\n");
|
|
1769
|
+
if (indi.isMale()) {
|
|
1770
|
+
return husbId && husbId !== indi.id ? "WIFE" : "HUSB";
|
|
1549
1771
|
}
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
const validValue = validKey ? validTag : item.exportValue();
|
|
1556
|
-
gedcom.push(
|
|
1557
|
-
`${level} ${validKey || validTag}${validValue ? ` ${validValue}` : ""}`
|
|
1558
|
-
);
|
|
1559
|
-
gedcom.push(
|
|
1560
|
-
...item.toGedcomLines(
|
|
1561
|
-
validTag,
|
|
1562
|
-
level + 1,
|
|
1563
|
-
options
|
|
1564
|
-
)
|
|
1565
|
-
);
|
|
1566
|
-
});
|
|
1567
|
-
return gedcom;
|
|
1772
|
+
return husbId ? "WIFE" : "HUSB";
|
|
1773
|
+
};
|
|
1774
|
+
var canAttachAsSpouse = (fam, indi) => {
|
|
1775
|
+
if (!indi.id) {
|
|
1776
|
+
return false;
|
|
1568
1777
|
}
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
this.entries().forEach(([key, item]) => {
|
|
1572
|
-
propList.item(key, item?.toValue());
|
|
1573
|
-
});
|
|
1574
|
-
return propList;
|
|
1778
|
+
if (familyHasParent(fam, indi.id)) {
|
|
1779
|
+
return true;
|
|
1575
1780
|
}
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1781
|
+
const tag = spouseTagFor(indi, fam);
|
|
1782
|
+
const occupied = firstPointerId(fam.get(tag));
|
|
1783
|
+
return !occupied || occupied === indi.id;
|
|
1784
|
+
};
|
|
1785
|
+
var pointerByValue = (tag, id) => {
|
|
1786
|
+
if (!tag) {
|
|
1787
|
+
return void 0;
|
|
1579
1788
|
}
|
|
1580
|
-
|
|
1581
|
-
|
|
1789
|
+
const fromValues = tag.toValueList?.().item(id);
|
|
1790
|
+
if (fromValues) {
|
|
1791
|
+
return fromValues;
|
|
1582
1792
|
}
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1793
|
+
return tag.toList()?.values().find((item) => item?.toValue?.() === id);
|
|
1794
|
+
};
|
|
1795
|
+
var setChildPedigree = (fam, child, pedigree, parent) => {
|
|
1796
|
+
if (!fam.id || !child.id) {
|
|
1797
|
+
return;
|
|
1798
|
+
}
|
|
1799
|
+
const pedi = toGedcomPedigree(pedigree);
|
|
1800
|
+
const famc = pointerByValue(child.get("FAMC"), fam.id);
|
|
1801
|
+
if (famc) {
|
|
1802
|
+
famc.set("PEDI", pedi);
|
|
1803
|
+
}
|
|
1804
|
+
const chil = pointerByValue(fam.get("CHIL"), child.id);
|
|
1805
|
+
if (!chil) {
|
|
1806
|
+
return;
|
|
1807
|
+
}
|
|
1808
|
+
const setFather = !parent || parent.isMale() || parent.isUnknownSex();
|
|
1809
|
+
const setMother = !parent || parent.isFemale() || parent.isUnknownSex();
|
|
1810
|
+
if (setFather) {
|
|
1811
|
+
chil.set("_FREL", pedi);
|
|
1812
|
+
}
|
|
1813
|
+
if (setMother) {
|
|
1814
|
+
chil.set("_MREL", pedi);
|
|
1815
|
+
}
|
|
1816
|
+
};
|
|
1817
|
+
var attachSpouseToFamily = (fam, indi) => {
|
|
1818
|
+
const gedcom = fam.getGedcom() ?? indi.getGedcom();
|
|
1819
|
+
if (!indi.id || !fam.id || !gedcom) {
|
|
1820
|
+
return false;
|
|
1821
|
+
}
|
|
1822
|
+
if (!canAttachAsSpouse(fam, indi)) {
|
|
1823
|
+
return false;
|
|
1824
|
+
}
|
|
1825
|
+
const tag = spouseTagFor(indi, fam);
|
|
1826
|
+
if (firstPointerId(fam.get(tag)) !== indi.id) {
|
|
1827
|
+
fam.set(tag, makePointer(gedcom, fam, indi.id, "INDI"));
|
|
1828
|
+
}
|
|
1829
|
+
indi.assign("FAMS", makePointer(gedcom, indi, fam.id, "FAM"), true);
|
|
1830
|
+
return true;
|
|
1831
|
+
};
|
|
1832
|
+
var attachChildToFamily = (fam, child, pedigree, parent) => {
|
|
1833
|
+
const gedcom = fam.getGedcom() ?? child.getGedcom();
|
|
1834
|
+
if (!child.id || !fam.id || !gedcom) {
|
|
1835
|
+
return false;
|
|
1836
|
+
}
|
|
1837
|
+
if (!familyHasChild(fam, child.id)) {
|
|
1838
|
+
fam.assign("CHIL", makePointer(gedcom, fam, child.id, "INDI"), true);
|
|
1839
|
+
}
|
|
1840
|
+
const existingFamc = pointerByValue(child.get("FAMC"), fam.id);
|
|
1841
|
+
if (!existingFamc) {
|
|
1842
|
+
child.assign("FAMC", makePointer(gedcom, child, fam.id, "FAM"), true);
|
|
1843
|
+
}
|
|
1844
|
+
setChildPedigree(fam, child, pedigree, parent);
|
|
1845
|
+
return true;
|
|
1846
|
+
};
|
|
1847
|
+
var findReusableParentChildFamily = (parent, child) => {
|
|
1848
|
+
if (!parent.id || !child.id) {
|
|
1849
|
+
return void 0;
|
|
1850
|
+
}
|
|
1851
|
+
let reusableFamc;
|
|
1852
|
+
let already = false;
|
|
1853
|
+
child.getFamilies("FAMC")?.forEach((fam) => {
|
|
1854
|
+
if (!fam) {
|
|
1855
|
+
return;
|
|
1856
|
+
}
|
|
1857
|
+
if (familyHasParent(fam, parent.id) && familyHasChild(fam, child.id)) {
|
|
1858
|
+
already = true;
|
|
1859
|
+
return;
|
|
1860
|
+
}
|
|
1861
|
+
if (!reusableFamc && canAttachAsSpouse(fam, parent)) {
|
|
1862
|
+
reusableFamc = fam;
|
|
1863
|
+
}
|
|
1864
|
+
});
|
|
1865
|
+
if (already) {
|
|
1866
|
+
return "already";
|
|
1867
|
+
}
|
|
1868
|
+
if (reusableFamc) {
|
|
1869
|
+
return reusableFamc;
|
|
1870
|
+
}
|
|
1871
|
+
const parentFams = [];
|
|
1872
|
+
parent.getFamilies("FAMS")?.forEach((fam) => {
|
|
1873
|
+
if (fam) {
|
|
1874
|
+
parentFams.push(fam);
|
|
1875
|
+
}
|
|
1876
|
+
});
|
|
1877
|
+
if (parentFams.length === 1) {
|
|
1878
|
+
return parentFams[0];
|
|
1589
1879
|
}
|
|
1880
|
+
return void 0;
|
|
1881
|
+
};
|
|
1882
|
+
|
|
1883
|
+
// src/utils/get-family-with.ts
|
|
1884
|
+
var getFamilyWith = (person1, person2, famType = "FAMS") => {
|
|
1885
|
+
return person1?.get(famType)?.toValueList().find((fam) => {
|
|
1886
|
+
const family = fam;
|
|
1887
|
+
return famType === "FAMC" || family?.HUSB?.value === person2 || family?.WIFE?.value === person2;
|
|
1888
|
+
});
|
|
1590
1889
|
};
|
|
1591
1890
|
|
|
1592
1891
|
// src/utils/get-places.ts
|
|
@@ -1653,16 +1952,58 @@ var getPlaces = (common, type = ["ALL" /* All */], maxLevel = 1, level = 0, main
|
|
|
1653
1952
|
});
|
|
1654
1953
|
return places;
|
|
1655
1954
|
};
|
|
1955
|
+
|
|
1956
|
+
// src/utils/local-media.ts
|
|
1957
|
+
var localMediaResolver;
|
|
1958
|
+
var isRemoteOrEmbeddedMediaUrl = (path) => {
|
|
1959
|
+
if (!path) {
|
|
1960
|
+
return false;
|
|
1961
|
+
}
|
|
1962
|
+
return path.startsWith("data:") || path.startsWith("blob:") || /^https?:\/\//i.test(path);
|
|
1963
|
+
};
|
|
1964
|
+
var resolveLocalMediaUrl = async (path) => {
|
|
1965
|
+
if (!path) {
|
|
1966
|
+
return void 0;
|
|
1967
|
+
}
|
|
1968
|
+
if (isRemoteOrEmbeddedMediaUrl(path)) {
|
|
1969
|
+
return path;
|
|
1970
|
+
}
|
|
1971
|
+
const resolved = await localMediaResolver?.(path);
|
|
1972
|
+
return resolved;
|
|
1973
|
+
};
|
|
1656
1974
|
var implemented = (type, ...args) => {
|
|
1657
1975
|
};
|
|
1658
1976
|
|
|
1659
1977
|
// src/utils/media-utils.ts
|
|
1660
1978
|
var getFileExtension = (filename) => {
|
|
1661
|
-
|
|
1662
|
-
|
|
1979
|
+
if (!filename) {
|
|
1980
|
+
return "";
|
|
1981
|
+
}
|
|
1982
|
+
if (filename.startsWith("data:")) {
|
|
1983
|
+
const mime = filename.slice(5).split(";")[0] || "";
|
|
1984
|
+
const subtype = (mime.split("/")[1] || "").toLowerCase();
|
|
1985
|
+
if (subtype === "jpeg") {
|
|
1986
|
+
return "jpg";
|
|
1987
|
+
}
|
|
1988
|
+
return subtype.split("+")[0] || "";
|
|
1989
|
+
}
|
|
1990
|
+
const withoutQuery = filename.split(/[?#]/)[0] || filename;
|
|
1991
|
+
const match = withoutQuery.match(/\.([^.]+)$/);
|
|
1992
|
+
return match ? match[1].toLowerCase() : "";
|
|
1663
1993
|
};
|
|
1664
1994
|
var isImageFormat = (format2) => {
|
|
1665
|
-
if (!format2)
|
|
1995
|
+
if (!format2) {
|
|
1996
|
+
return false;
|
|
1997
|
+
}
|
|
1998
|
+
let normalized = format2.toLowerCase().trim();
|
|
1999
|
+
if (normalized.startsWith("data:")) {
|
|
2000
|
+
normalized = getFileExtension(normalized);
|
|
2001
|
+
} else if (normalized.includes("/")) {
|
|
2002
|
+
normalized = normalized.split("/")[1]?.split("+")[0] || "";
|
|
2003
|
+
if (normalized === "jpeg") {
|
|
2004
|
+
normalized = "jpg";
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
1666
2007
|
const imageFormats = [
|
|
1667
2008
|
"jpg",
|
|
1668
2009
|
"jpeg",
|
|
@@ -1674,7 +2015,11 @@ var isImageFormat = (format2) => {
|
|
|
1674
2015
|
"tiff",
|
|
1675
2016
|
"tif"
|
|
1676
2017
|
];
|
|
1677
|
-
return imageFormats.includes(
|
|
2018
|
+
return imageFormats.includes(normalized);
|
|
2019
|
+
};
|
|
2020
|
+
var resolveObjeForm = (obje) => {
|
|
2021
|
+
const value = obje?.get?.("FILE.FORM")?.toValue?.() ?? obje?.get?.("FORM")?.toValue?.();
|
|
2022
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
1678
2023
|
};
|
|
1679
2024
|
var uniqueItemsCache = /* @__PURE__ */ new WeakMap();
|
|
1680
2025
|
var setNestedGroup = (obj, key, value, uniqueCounting = true) => {
|
|
@@ -2219,6 +2564,34 @@ var Fam = class extends Common {
|
|
|
2219
2564
|
getParents() {
|
|
2220
2565
|
return this.getHusband().copy().merge(this.getWife());
|
|
2221
2566
|
}
|
|
2567
|
+
hasParent(indi) {
|
|
2568
|
+
const indiId = typeof indi === "string" ? indi : indi?.id;
|
|
2569
|
+
return !!indiId && familyHasParent(this, indiId);
|
|
2570
|
+
}
|
|
2571
|
+
hasChild(indi) {
|
|
2572
|
+
const indiId = typeof indi === "string" ? indi : indi?.id;
|
|
2573
|
+
return !!indiId && familyHasChild(this, indiId);
|
|
2574
|
+
}
|
|
2575
|
+
canAddSpouse(indi) {
|
|
2576
|
+
return canAttachAsSpouse(this, indi);
|
|
2577
|
+
}
|
|
2578
|
+
addSpouse(indi) {
|
|
2579
|
+
return attachSpouseToFamily(this, indi);
|
|
2580
|
+
}
|
|
2581
|
+
addChild(child, pedigree, parent) {
|
|
2582
|
+
return attachChildToFamily(
|
|
2583
|
+
this,
|
|
2584
|
+
child,
|
|
2585
|
+
pedigree,
|
|
2586
|
+
parent
|
|
2587
|
+
);
|
|
2588
|
+
}
|
|
2589
|
+
addFact(input) {
|
|
2590
|
+
return addFamilyFact(this, input);
|
|
2591
|
+
}
|
|
2592
|
+
addNonEvent(input) {
|
|
2593
|
+
return addNonEvent(this, input);
|
|
2594
|
+
}
|
|
2222
2595
|
toList() {
|
|
2223
2596
|
return new Families().concat(
|
|
2224
2597
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -2319,19 +2692,51 @@ var ALLOWED_FACTS = [
|
|
|
2319
2692
|
"OCCU",
|
|
2320
2693
|
"OCCUPATIONS",
|
|
2321
2694
|
"RESI",
|
|
2695
|
+
"BIRT",
|
|
2696
|
+
"DEAT",
|
|
2322
2697
|
"BAPT",
|
|
2698
|
+
"BAPM",
|
|
2323
2699
|
"CHRI",
|
|
2324
2700
|
"CHR",
|
|
2701
|
+
"CHRA",
|
|
2325
2702
|
"BURI",
|
|
2326
|
-
"
|
|
2703
|
+
"CREM",
|
|
2704
|
+
"ADOP",
|
|
2705
|
+
"BARM",
|
|
2706
|
+
"BASM",
|
|
2707
|
+
"BLES",
|
|
2708
|
+
"CONF",
|
|
2709
|
+
"FCOM",
|
|
2710
|
+
"ORDN",
|
|
2711
|
+
"NATU",
|
|
2712
|
+
"EMIG",
|
|
2713
|
+
"IMMI",
|
|
2714
|
+
"CENS",
|
|
2715
|
+
"PROB",
|
|
2716
|
+
"WILL",
|
|
2327
2717
|
"GRAD",
|
|
2718
|
+
"RETI",
|
|
2719
|
+
"EDUC",
|
|
2328
2720
|
"DIV",
|
|
2329
|
-
"IMMI",
|
|
2330
2721
|
"RELI",
|
|
2722
|
+
"CAST",
|
|
2723
|
+
"DSCR",
|
|
2724
|
+
"NATI",
|
|
2725
|
+
"PROP",
|
|
2726
|
+
"SSN",
|
|
2727
|
+
"TITL",
|
|
2728
|
+
"ADDR",
|
|
2729
|
+
"BAPL",
|
|
2730
|
+
"CONL",
|
|
2731
|
+
"ENDL",
|
|
2732
|
+
"SLGC",
|
|
2331
2733
|
"_MILT",
|
|
2332
2734
|
"_MILTID",
|
|
2333
2735
|
"FACT",
|
|
2334
|
-
"_ORIG"
|
|
2736
|
+
"_ORIG",
|
|
2737
|
+
"_WLNK",
|
|
2738
|
+
"WWW",
|
|
2739
|
+
"URL"
|
|
2335
2740
|
];
|
|
2336
2741
|
var DISALLOWED_CUSTOM_FACTS = ["DNA Test", "Newspaper"];
|
|
2337
2742
|
var CustomFactRenderers = {
|
|
@@ -2875,7 +3280,7 @@ var Indi = class extends Common {
|
|
|
2875
3280
|
return result;
|
|
2876
3281
|
}
|
|
2877
3282
|
ancestryLink() {
|
|
2878
|
-
const www = this._gedcom?.HEAD?.SOUR?.CORP?.WWW?.value;
|
|
3283
|
+
const www = this.getFromSourceHeads("SOUR.CORP.WWW.value") || this._gedcom?.HEAD?.SOUR?.CORP?.WWW?.value;
|
|
2879
3284
|
const tree = this.getAncestryTreeId();
|
|
2880
3285
|
if (this.id) {
|
|
2881
3286
|
return `https://${www}/family-tree/person/tree/${tree}/person/${this.id.replace(
|
|
@@ -2887,7 +3292,7 @@ var Indi = class extends Common {
|
|
|
2887
3292
|
async ancestryMedia(namespace) {
|
|
2888
3293
|
const list = {};
|
|
2889
3294
|
const objeList = this.get("OBJE")?.toList().copy();
|
|
2890
|
-
const www = this._gedcom?.HEAD?.SOUR?.CORP?.WWW?.value;
|
|
3295
|
+
const www = this.getFromSourceHeads("SOUR.CORP.WWW.value") || this._gedcom?.HEAD?.SOUR?.CORP?.WWW?.value;
|
|
2891
3296
|
const tree = this.getAncestryTreeId();
|
|
2892
3297
|
if (objeList) {
|
|
2893
3298
|
await Promise.all(
|
|
@@ -2905,10 +3310,14 @@ var Indi = class extends Common {
|
|
|
2905
3310
|
const clone = obje?.get("_CLON._OID")?.toValue();
|
|
2906
3311
|
const mser = obje?.get("_MSER._LKID")?.toValue();
|
|
2907
3312
|
let url = obje?.get("FILE")?.toValue();
|
|
2908
|
-
const title = obje?.get("TITL")?.toValue() ?? "";
|
|
2909
|
-
const type = obje
|
|
2910
|
-
|
|
2911
|
-
|
|
3313
|
+
const title = obje?.get("FILE.TITL")?.toValue() ?? obje?.get("TITL")?.toValue() ?? "";
|
|
3314
|
+
const type = resolveObjeForm(obje) ?? (url ? getFileExtension(url) : void 0) ?? "raw";
|
|
3315
|
+
let imgId = clone || mser;
|
|
3316
|
+
const hasEmbeddedOrLocalFile = !!url && (url.startsWith("data:") || url.startsWith("blob:") || !/^https?:\/\//i.test(url));
|
|
3317
|
+
if (!hasEmbeddedOrLocalFile && (!www || !tree || !this.id)) {
|
|
3318
|
+
return;
|
|
3319
|
+
}
|
|
3320
|
+
if (!this.id) {
|
|
2912
3321
|
return;
|
|
2913
3322
|
}
|
|
2914
3323
|
if (!namespace && !url) {
|
|
@@ -2926,13 +3335,16 @@ var Indi = class extends Common {
|
|
|
2926
3335
|
}
|
|
2927
3336
|
url = url || `https://${www}/mediaui-viewer/tree/${tree}/media/${media}`;
|
|
2928
3337
|
}
|
|
3338
|
+
if (!imgId && hasEmbeddedOrLocalFile && url) {
|
|
3339
|
+
imgId = typeof media === "string" && media || `local-${String(key).replace(/[@]/g, "")}-${getFileExtension(url) || "bin"}`;
|
|
3340
|
+
}
|
|
2929
3341
|
if (url && imgId) {
|
|
2930
|
-
const id = `${tree}-${this.id}-${imgId}`;
|
|
3342
|
+
const id = `${tree || "gedzip"}-${this.id}-${imgId}`;
|
|
2931
3343
|
list[id] = {
|
|
2932
3344
|
key,
|
|
2933
3345
|
isPrimary,
|
|
2934
3346
|
id,
|
|
2935
|
-
tree,
|
|
3347
|
+
tree: tree || "gedzip",
|
|
2936
3348
|
imgId,
|
|
2937
3349
|
person: this.id,
|
|
2938
3350
|
title,
|
|
@@ -2947,7 +3359,7 @@ var Indi = class extends Common {
|
|
|
2947
3359
|
return list;
|
|
2948
3360
|
}
|
|
2949
3361
|
myheritageLink(poolId = 0) {
|
|
2950
|
-
const www = this._gedcom?.HEAD?.SOUR?.CORP?.value?.toLowerCase().replace(/^www\./gi, "");
|
|
3362
|
+
const www = (this.getFromSourceHeads("SOUR.CORP.value") || this._gedcom?.HEAD?.SOUR?.CORP?.value)?.toLowerCase().replace(/^www\./gi, "");
|
|
2951
3363
|
const site = this.getMyHeritageTreeId();
|
|
2952
3364
|
const file = this._gedcom?.HEAD?.get("FILE")?.toValue()?.match(/Exported by MyHeritage.com from .+ in (?<site>.+) on .+$/)?.groups?.site;
|
|
2953
3365
|
const normalizedFile = file?.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-");
|
|
@@ -2978,9 +3390,11 @@ var Indi = class extends Common {
|
|
|
2978
3390
|
obje.standardizeMedia();
|
|
2979
3391
|
const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
|
|
2980
3392
|
const url = obje?.get("FILE")?.toValue();
|
|
2981
|
-
const title = obje?.get("NOTE")?.toValue() ?? "";
|
|
2982
|
-
const type = obje
|
|
2983
|
-
const
|
|
3393
|
+
const title = obje?.get("FILE.NOTE")?.toValue() ?? obje?.get("NOTE")?.toValue() ?? "";
|
|
3394
|
+
const type = resolveObjeForm(obje) ?? (url ? getFileExtension(url) : void 0) ?? "raw";
|
|
3395
|
+
const photoRin = obje?.get("_PHOTO_RIN")?.toValue();
|
|
3396
|
+
const hasEmbeddedOrLocalFile = !!url && (url.startsWith("data:") || url.startsWith("blob:") || !/^https?:\/\//i.test(url));
|
|
3397
|
+
const imgId = photoRin || (hasEmbeddedOrLocalFile && url ? `local-${String(key).replace(/[@]/g, "")}-${getFileExtension(url) || "bin"}` : void 0);
|
|
2984
3398
|
if (url && imgId) {
|
|
2985
3399
|
const id = `${tree}-${this.id}-${imgId}`;
|
|
2986
3400
|
list[id] = {
|
|
@@ -3103,10 +3517,10 @@ var Indi = class extends Common {
|
|
|
3103
3517
|
const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
|
|
3104
3518
|
const url = obje?.get("FILE")?.toValue();
|
|
3105
3519
|
const title = obje?.get("TITL")?.toValue() ?? "";
|
|
3106
|
-
const type = obje
|
|
3520
|
+
const type = resolveObjeForm(obje) ?? (url ? getFileExtension(url) : void 0) ?? "raw";
|
|
3107
3521
|
if (url) {
|
|
3108
3522
|
const urlMatch = url.match(/\/([^/]+)\?hash=/);
|
|
3109
|
-
const imgId = urlMatch?.[1] || `img-${index}-${Date.now().toString(36)}
|
|
3523
|
+
const imgId = urlMatch?.[1] || (url.startsWith("data:") ? `data-${index}-${getFileExtension(url) || "bin"}` : `img-${index}-${Date.now().toString(36)}`);
|
|
3110
3524
|
const id = `geni-${geniId}-${imgId}`;
|
|
3111
3525
|
list[id] = {
|
|
3112
3526
|
isPrimary,
|
|
@@ -3143,10 +3557,10 @@ var Indi = class extends Common {
|
|
|
3143
3557
|
obje.standardizeMedia();
|
|
3144
3558
|
const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
|
|
3145
3559
|
const url = obje?.get("FILE")?.toValue();
|
|
3146
|
-
const title = obje?.get("TITL")?.toValue() ?? "";
|
|
3147
|
-
const type = obje
|
|
3560
|
+
const title = obje?.get("FILE.TITL")?.toValue() ?? obje?.get("TITL")?.toValue() ?? "";
|
|
3561
|
+
const type = resolveObjeForm(obje) ?? (url ? getFileExtension(url) : void 0) ?? "raw";
|
|
3148
3562
|
if (url) {
|
|
3149
|
-
const imgId = `media-${index}-${url.split("/").pop()?.split("?")[0]?.substring(0, 20) || Date.now().toString(36)}`;
|
|
3563
|
+
const imgId = `media-${index}-${url.startsWith("data:") ? getFileExtension(url) || "bin" : url.split("/").pop()?.split("?")[0]?.substring(0, 20) || Date.now().toString(36)}`;
|
|
3150
3564
|
const id = `${treeId}-${this.id}-${imgId}`;
|
|
3151
3565
|
list[id] = {
|
|
3152
3566
|
isPrimary,
|
|
@@ -3186,7 +3600,20 @@ var Indi = class extends Common {
|
|
|
3186
3600
|
cacheKey
|
|
3187
3601
|
);
|
|
3188
3602
|
if (cached !== void 0) {
|
|
3189
|
-
|
|
3603
|
+
if (cached?.file && !isRemoteOrEmbeddedMediaUrl(cached.file)) {
|
|
3604
|
+
const resolvedCached = await resolveLocalMediaUrl(cached.file);
|
|
3605
|
+
if (resolvedCached && isRemoteOrEmbeddedMediaUrl(resolvedCached)) {
|
|
3606
|
+
const refreshed = { ...cached, file: resolvedCached };
|
|
3607
|
+
profilePictureCache(
|
|
3608
|
+
this._gedcom,
|
|
3609
|
+
cacheKey,
|
|
3610
|
+
refreshed
|
|
3611
|
+
);
|
|
3612
|
+
return refreshed;
|
|
3613
|
+
}
|
|
3614
|
+
} else {
|
|
3615
|
+
return cached;
|
|
3616
|
+
}
|
|
3190
3617
|
}
|
|
3191
3618
|
const mediaList = await this.multimedia(namespace);
|
|
3192
3619
|
if (!mediaList) {
|
|
@@ -3198,39 +3625,40 @@ var Indi = class extends Common {
|
|
|
3198
3625
|
return void 0;
|
|
3199
3626
|
}
|
|
3200
3627
|
const mediaArray = Object.values(mediaList);
|
|
3201
|
-
const
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3628
|
+
const toDisplayableProfile = async (media, isPrimary) => {
|
|
3629
|
+
const resolvedFile = await resolveLocalMediaUrl(media.url);
|
|
3630
|
+
if (!resolvedFile || !isRemoteOrEmbeddedMediaUrl(resolvedFile)) {
|
|
3631
|
+
return void 0;
|
|
3632
|
+
}
|
|
3633
|
+
return {
|
|
3634
|
+
file: resolvedFile,
|
|
3635
|
+
form: media.contentType,
|
|
3636
|
+
title: media.title,
|
|
3637
|
+
isPrimary
|
|
3210
3638
|
};
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
this._gedcom,
|
|
3217
|
-
cacheKey,
|
|
3218
|
-
void 0
|
|
3219
|
-
);
|
|
3220
|
-
return void 0;
|
|
3221
|
-
}
|
|
3222
|
-
const secondaryMedia = mediaArray.find(
|
|
3223
|
-
(media) => isImageFormat(media.contentType || getFileExtension(media.url))
|
|
3639
|
+
};
|
|
3640
|
+
const candidates = mediaArray.filter(
|
|
3641
|
+
(media) => isImageFormat(
|
|
3642
|
+
media.contentType || media.url || getFileExtension(media.url)
|
|
3643
|
+
)
|
|
3224
3644
|
);
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3645
|
+
const ordered = [
|
|
3646
|
+
...candidates.filter((media) => media.isPrimary),
|
|
3647
|
+
...candidates.filter((media) => !media.isPrimary)
|
|
3648
|
+
];
|
|
3649
|
+
for (const media of ordered) {
|
|
3650
|
+
if (onlyPrimary && !media.isPrimary) {
|
|
3651
|
+
break;
|
|
3652
|
+
}
|
|
3653
|
+
const result = await toDisplayableProfile(media, !!media.isPrimary);
|
|
3654
|
+
if (result) {
|
|
3655
|
+
profilePictureCache(
|
|
3656
|
+
this._gedcom,
|
|
3657
|
+
cacheKey,
|
|
3658
|
+
result
|
|
3659
|
+
);
|
|
3660
|
+
return result;
|
|
3661
|
+
}
|
|
3234
3662
|
}
|
|
3235
3663
|
profilePictureCache(
|
|
3236
3664
|
this._gedcom,
|
|
@@ -3468,6 +3896,156 @@ var Indi = class extends Common {
|
|
|
3468
3896
|
isUnknownSex() {
|
|
3469
3897
|
return !this.isMale() && !this.isFemale();
|
|
3470
3898
|
}
|
|
3899
|
+
addSpouse(other) {
|
|
3900
|
+
if (!this.id || !other?.id || this.id === other.id || !this._gedcom) {
|
|
3901
|
+
return void 0;
|
|
3902
|
+
}
|
|
3903
|
+
const existing = getFamilyWith(this, other.id);
|
|
3904
|
+
if (existing) {
|
|
3905
|
+
return existing;
|
|
3906
|
+
}
|
|
3907
|
+
const fam = this._gedcom.createFamily();
|
|
3908
|
+
if (!fam.addSpouse(this) || !fam.addSpouse(other)) {
|
|
3909
|
+
return void 0;
|
|
3910
|
+
}
|
|
3911
|
+
return fam;
|
|
3912
|
+
}
|
|
3913
|
+
addChild(child, pedigree) {
|
|
3914
|
+
if (!this.id || !child?.id || this.id === child.id || !this._gedcom) {
|
|
3915
|
+
return void 0;
|
|
3916
|
+
}
|
|
3917
|
+
const existing = findReusableParentChildFamily(
|
|
3918
|
+
this,
|
|
3919
|
+
child
|
|
3920
|
+
);
|
|
3921
|
+
if (existing === "already") {
|
|
3922
|
+
const fam2 = child.getFamilies("FAMC")?.find(
|
|
3923
|
+
(item) => !!item && item.hasParent(this.id) && item.hasChild(child.id)
|
|
3924
|
+
);
|
|
3925
|
+
if (fam2) {
|
|
3926
|
+
setChildPedigree(
|
|
3927
|
+
fam2,
|
|
3928
|
+
child,
|
|
3929
|
+
pedigree,
|
|
3930
|
+
this
|
|
3931
|
+
);
|
|
3932
|
+
}
|
|
3933
|
+
return fam2;
|
|
3934
|
+
}
|
|
3935
|
+
const fam = existing ?? this._gedcom.createFamily();
|
|
3936
|
+
if (!fam.addSpouse(this)) {
|
|
3937
|
+
return void 0;
|
|
3938
|
+
}
|
|
3939
|
+
if (!fam.addChild(child, pedigree, this)) {
|
|
3940
|
+
return void 0;
|
|
3941
|
+
}
|
|
3942
|
+
return fam;
|
|
3943
|
+
}
|
|
3944
|
+
addParent(parent, pedigree) {
|
|
3945
|
+
return parent.addChild(this, pedigree);
|
|
3946
|
+
}
|
|
3947
|
+
/**
|
|
3948
|
+
* Link an existing top-level OBJE record to this individual (`1 OBJE @On@`).
|
|
3949
|
+
*/
|
|
3950
|
+
attachMultimedia(objeOrKey, options) {
|
|
3951
|
+
if (!this._gedcom || !this.id) {
|
|
3952
|
+
return void 0;
|
|
3953
|
+
}
|
|
3954
|
+
const obje = typeof objeOrKey === "string" ? this._gedcom.obje(objeOrKey) : objeOrKey;
|
|
3955
|
+
if (!obje?.id) {
|
|
3956
|
+
return void 0;
|
|
3957
|
+
}
|
|
3958
|
+
const already = this.get("OBJE")?.toList()?.values()?.some((item) => item?.toValue?.() === obje.id);
|
|
3959
|
+
if (!already) {
|
|
3960
|
+
const pointer = makePointer(
|
|
3961
|
+
this._gedcom,
|
|
3962
|
+
this,
|
|
3963
|
+
obje.id,
|
|
3964
|
+
"OBJE"
|
|
3965
|
+
);
|
|
3966
|
+
this.assign("OBJE", pointer);
|
|
3967
|
+
}
|
|
3968
|
+
if (options?.primary) {
|
|
3969
|
+
this.get("OBJE")?.toList()?.forEach((item) => {
|
|
3970
|
+
const target = item?.refType === "OBJE" ? this._gedcom?.obje(
|
|
3971
|
+
String(item.toValue())
|
|
3972
|
+
) : item;
|
|
3973
|
+
if (!target) {
|
|
3974
|
+
return;
|
|
3975
|
+
}
|
|
3976
|
+
if (target.id === obje.id) {
|
|
3977
|
+
target.set("_PRIM", "Y");
|
|
3978
|
+
} else if (target.get("_PRIM")?.toValue() === "Y") {
|
|
3979
|
+
target.set("_PRIM", "N");
|
|
3980
|
+
}
|
|
3981
|
+
});
|
|
3982
|
+
obje.set("_PRIM", "Y");
|
|
3983
|
+
}
|
|
3984
|
+
return obje;
|
|
3985
|
+
}
|
|
3986
|
+
detachMultimedia(objeKey) {
|
|
3987
|
+
const list = this.get("OBJE")?.toList();
|
|
3988
|
+
if (!list) {
|
|
3989
|
+
return;
|
|
3990
|
+
}
|
|
3991
|
+
const toRemove = list.values().filter(
|
|
3992
|
+
(item) => item?.toValue?.() === objeKey || item?.id === objeKey
|
|
3993
|
+
);
|
|
3994
|
+
toRemove.forEach((item) => {
|
|
3995
|
+
if (item) {
|
|
3996
|
+
list.delete(item);
|
|
3997
|
+
}
|
|
3998
|
+
});
|
|
3999
|
+
if (list.length === 0) {
|
|
4000
|
+
this.remove("OBJE");
|
|
4001
|
+
}
|
|
4002
|
+
}
|
|
4003
|
+
/**
|
|
4004
|
+
* Create a multimedia record and attach it to this person.
|
|
4005
|
+
*/
|
|
4006
|
+
attachMediaFromUrl(url, options) {
|
|
4007
|
+
if (!this._gedcom || !url) {
|
|
4008
|
+
return void 0;
|
|
4009
|
+
}
|
|
4010
|
+
const obje = this._gedcom.createMultimediaRecord({
|
|
4011
|
+
file: url,
|
|
4012
|
+
form: options?.form,
|
|
4013
|
+
title: options?.title,
|
|
4014
|
+
mediType: options?.mediType,
|
|
4015
|
+
primary: options?.primary,
|
|
4016
|
+
gedcomVersion: options?.gedcomVersion
|
|
4017
|
+
});
|
|
4018
|
+
return this.attachMultimedia(obje, { primary: options?.primary });
|
|
4019
|
+
}
|
|
4020
|
+
/**
|
|
4021
|
+
* Link a shared SNOTE record via `1 NOTE @Nn@` (GEDCOM 7).
|
|
4022
|
+
*/
|
|
4023
|
+
attachSharedNote(noteOrKey) {
|
|
4024
|
+
if (!this._gedcom || !this.id) {
|
|
4025
|
+
return void 0;
|
|
4026
|
+
}
|
|
4027
|
+
const note = typeof noteOrKey === "string" ? this._gedcom.snote(noteOrKey) : noteOrKey;
|
|
4028
|
+
if (!note?.id) {
|
|
4029
|
+
return void 0;
|
|
4030
|
+
}
|
|
4031
|
+
const already = this.get("NOTE")?.toList()?.values()?.some((item) => item?.toValue?.() === note.id);
|
|
4032
|
+
if (!already) {
|
|
4033
|
+
const pointer = makePointer(
|
|
4034
|
+
this._gedcom,
|
|
4035
|
+
this,
|
|
4036
|
+
note.id,
|
|
4037
|
+
"SNOTE"
|
|
4038
|
+
);
|
|
4039
|
+
this.assign("NOTE", pointer);
|
|
4040
|
+
}
|
|
4041
|
+
return note;
|
|
4042
|
+
}
|
|
4043
|
+
addFact(input) {
|
|
4044
|
+
return addIndividualFact(this, input);
|
|
4045
|
+
}
|
|
4046
|
+
addNonEvent(input) {
|
|
4047
|
+
return addNonEvent(this, input);
|
|
4048
|
+
}
|
|
3471
4049
|
getParentType(id) {
|
|
3472
4050
|
let indi;
|
|
3473
4051
|
if (typeof id === "string" || typeof id === "number") {
|
|
@@ -3508,7 +4086,7 @@ var Indi = class extends Common {
|
|
|
3508
4086
|
if (!famChild) {
|
|
3509
4087
|
const childIndi = this._gedcom?.indi(child.id);
|
|
3510
4088
|
const childState = childIndi?.get("FAMC")?.toList()?.filter((item) => item.value === family.id).index(0);
|
|
3511
|
-
childType = childState?.get("PEDI")?.toValue() || "biological" /* BIOLOGICAL */;
|
|
4089
|
+
childType = (childState?.get("PEDI") ?? childState?.get("PEDT"))?.toValue() || "biological" /* BIOLOGICAL */;
|
|
3512
4090
|
} else {
|
|
3513
4091
|
childType = famChild.get(usedRel)?.toValue() || "biological" /* BIOLOGICAL */;
|
|
3514
4092
|
}
|
|
@@ -3668,7 +4246,9 @@ var Indi = class extends Common {
|
|
|
3668
4246
|
}
|
|
3669
4247
|
}
|
|
3670
4248
|
if (kinship !== "child" || !breakAfterSpouse) {
|
|
3671
|
-
indi.getBiologicalFathers().copy().merge(indi.getBiologicalMothers()).merge(
|
|
4249
|
+
indi.getBiologicalFathers().copy().merge(indi.getBiologicalMothers()).merge(
|
|
4250
|
+
indi.getFathers().copy().merge(indi.getMothers())
|
|
4251
|
+
).forEach((relative) => {
|
|
3672
4252
|
if (!visited.has(relative)) {
|
|
3673
4253
|
const currentRelation = indi.getParentType(relative);
|
|
3674
4254
|
const isNonBiological = !!currentRelation && currentRelation !== "biological" /* BIOLOGICAL */;
|
|
@@ -4067,7 +4647,7 @@ var Indi = class extends Common {
|
|
|
4067
4647
|
return;
|
|
4068
4648
|
}
|
|
4069
4649
|
const childState = child?.get("FAMC")?.toList()?.filter((item) => item.value === family.id).index(0);
|
|
4070
|
-
const childType = childState?.get("PEDI")?.toValue() || "biological" /* BIOLOGICAL */;
|
|
4650
|
+
const childType = (childState?.get("PEDI") ?? childState?.get("PEDT"))?.toValue() || "biological" /* BIOLOGICAL */;
|
|
4071
4651
|
if (childType?.toLowerCase() === filter.PEDI.toLowerCase()) {
|
|
4072
4652
|
children.append(child);
|
|
4073
4653
|
}
|
|
@@ -4175,7 +4755,7 @@ var Indi = class extends Common {
|
|
|
4175
4755
|
const child = this.id && family.CHIL?.toValueList()?.item(this.id);
|
|
4176
4756
|
if (!child) {
|
|
4177
4757
|
const childState = this?.get("FAMC")?.toList()?.filter((item) => item.value === family.id).index(0);
|
|
4178
|
-
const parentType = childState?.get("PEDI")?.toValue() || "biological" /* BIOLOGICAL */;
|
|
4758
|
+
const parentType = (childState?.get("PEDI") ?? childState?.get("PEDT"))?.toValue() || "biological" /* BIOLOGICAL */;
|
|
4179
4759
|
if (parentType?.toLowerCase() === filter.PEDI.toLowerCase()) {
|
|
4180
4760
|
parents.merge(family.getParents());
|
|
4181
4761
|
}
|
|
@@ -6374,7 +6954,11 @@ var STANDARD_QUALIFIERS = {
|
|
|
6374
6954
|
BEF: "Bef.",
|
|
6375
6955
|
BEFORE: "Bef.",
|
|
6376
6956
|
AFT: "Aft.",
|
|
6377
|
-
AFTER: "Aft."
|
|
6957
|
+
AFTER: "Aft.",
|
|
6958
|
+
CAL: "Abt.",
|
|
6959
|
+
// calculated ≈ about for display
|
|
6960
|
+
EST: "Abt."
|
|
6961
|
+
// estimated ≈ about for display
|
|
6378
6962
|
};
|
|
6379
6963
|
var EXPORT_QUALIFIERS = {
|
|
6380
6964
|
"Abt.": "ABT",
|
|
@@ -6382,6 +6966,11 @@ var EXPORT_QUALIFIERS = {
|
|
|
6382
6966
|
"Aft.": "AFT"
|
|
6383
6967
|
};
|
|
6384
6968
|
var GEDCOM_MONTHS = /\b(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\b/g;
|
|
6969
|
+
var CALENDAR_PREFIX = /^(?<calendar>GREGORIAN|JULIAN|FRENCH_R|HEBREW)\b\s+/i;
|
|
6970
|
+
var isGedcomDateValueForm = (value) => (
|
|
6971
|
+
// Require space/end after the token so display forms like "Abt." are not opaque.
|
|
6972
|
+
/^(FROM|TO|BET|AFT|BEF|ABT|CAL|EST|INT)(\s|$)/i.test(value) || /\bAND\b/i.test(value)
|
|
6973
|
+
);
|
|
6385
6974
|
var NOTE_MARKER = "####";
|
|
6386
6975
|
var formatDateWithComponents = (date, hasDay, hasMonth, hasYear, noteValue, baseFormat = "dd MMM yyyy", locale) => {
|
|
6387
6976
|
const hasNote = baseFormat.includes("NOTE");
|
|
@@ -6406,29 +6995,45 @@ var CommonDate = class extends Common {
|
|
|
6406
6995
|
super(gedcom, id, main, parent);
|
|
6407
6996
|
delete this.id;
|
|
6408
6997
|
}
|
|
6998
|
+
get calendar() {
|
|
6999
|
+
return this._calendar;
|
|
7000
|
+
}
|
|
6409
7001
|
set value(value) {
|
|
6410
7002
|
if (value) {
|
|
6411
|
-
const noteRegExp = /^(?<note>[a-zA-Z]+\.)/;
|
|
6412
|
-
const noteMatch = value.match(noteRegExp)?.groups;
|
|
6413
7003
|
let validValue = value;
|
|
7004
|
+
const calendarMatch = validValue.match(CALENDAR_PREFIX);
|
|
7005
|
+
if (calendarMatch?.groups?.calendar) {
|
|
7006
|
+
this._calendar = calendarMatch.groups.calendar.toUpperCase();
|
|
7007
|
+
validValue = validValue.slice(calendarMatch[0].length);
|
|
7008
|
+
} else {
|
|
7009
|
+
this._calendar = void 0;
|
|
7010
|
+
}
|
|
7011
|
+
const noteRegExp = /^(?<note>[a-zA-Z]+\.)/;
|
|
7012
|
+
const noteMatch = validValue.match(noteRegExp)?.groups;
|
|
6414
7013
|
if (noteMatch?.note) {
|
|
6415
7014
|
this.NOTE = this.NOTE || createCommon(this._gedcom, void 0, this.main);
|
|
6416
7015
|
this.NOTE.value = noteMatch?.note;
|
|
6417
|
-
validValue =
|
|
7016
|
+
validValue = validValue.replace(noteRegExp, "");
|
|
6418
7017
|
} else {
|
|
6419
|
-
const qualifierMatch =
|
|
6420
|
-
/^(?<qualifier>ABT|ABOUT|BEF|BEFORE|AFT|AFTER)\b\s*/i
|
|
7018
|
+
const qualifierMatch = validValue.match(
|
|
7019
|
+
/^(?<qualifier>ABT|ABOUT|BEF|BEFORE|AFT|AFTER|CAL|EST)\b\s*/i
|
|
6421
7020
|
);
|
|
6422
7021
|
const qualifier = qualifierMatch?.groups?.qualifier?.toUpperCase();
|
|
6423
7022
|
const note = qualifier ? STANDARD_QUALIFIERS[qualifier] : void 0;
|
|
6424
7023
|
if (note) {
|
|
6425
7024
|
this.NOTE = this.NOTE || createCommon(this._gedcom, void 0, this.main);
|
|
6426
7025
|
this.NOTE.value = note;
|
|
6427
|
-
validValue =
|
|
7026
|
+
validValue = validValue.slice(qualifierMatch[0].length);
|
|
6428
7027
|
}
|
|
6429
7028
|
}
|
|
6430
7029
|
const acceptedDate = this.isValidDateFormat(validValue);
|
|
6431
|
-
if (
|
|
7030
|
+
if (isGedcomDateValueForm(validValue.trim())) {
|
|
7031
|
+
delete this.DAY;
|
|
7032
|
+
delete this.MONTH;
|
|
7033
|
+
delete this.YEAR;
|
|
7034
|
+
this._date = void 0;
|
|
7035
|
+
this._value = value;
|
|
7036
|
+
} else if (acceptedDate) {
|
|
6432
7037
|
this.DAY = this.DAY || createCommon(this._gedcom, void 0, this.main);
|
|
6433
7038
|
this.DAY.value = format(acceptedDate, "dd");
|
|
6434
7039
|
this.MONTH = this.MONTH || createCommon(this._gedcom, void 0, this.main);
|
|
@@ -6531,6 +7136,15 @@ var CommonDate = class extends Common {
|
|
|
6531
7136
|
);
|
|
6532
7137
|
}
|
|
6533
7138
|
exportValue() {
|
|
7139
|
+
if (typeof this._value === "string") {
|
|
7140
|
+
const withoutCalendar = this._value.replace(CALENDAR_PREFIX, "");
|
|
7141
|
+
if (isGedcomDateValueForm(withoutCalendar.trim())) {
|
|
7142
|
+
return this._value.replace(
|
|
7143
|
+
/^((?:GREGORIAN|JULIAN|FRENCH_R|HEBREW)\s+)?(FROM|TO|BET|AFT|BEF|ABT|CAL|EST|INT)\b/i,
|
|
7144
|
+
(_m, cal, q) => `${cal || ""}${q.toUpperCase()}`
|
|
7145
|
+
);
|
|
7146
|
+
}
|
|
7147
|
+
}
|
|
6534
7148
|
const formatted = this.toValue("NOTE dd MMM yyyy", null);
|
|
6535
7149
|
if (!formatted) {
|
|
6536
7150
|
return formatted;
|
|
@@ -6538,10 +7152,14 @@ var CommonDate = class extends Common {
|
|
|
6538
7152
|
const note = this.NOTE?.value?.trim();
|
|
6539
7153
|
const qualifier = note ? EXPORT_QUALIFIERS[note] : void 0;
|
|
6540
7154
|
const standardized = qualifier ? formatted.replace(note, qualifier) : formatted;
|
|
6541
|
-
|
|
7155
|
+
const withMonths = standardized.replace(
|
|
6542
7156
|
GEDCOM_MONTHS,
|
|
6543
7157
|
(month) => month.toUpperCase()
|
|
6544
7158
|
);
|
|
7159
|
+
if (this._calendar && this._calendar !== "GREGORIAN") {
|
|
7160
|
+
return `${this._calendar} ${withMonths}`;
|
|
7161
|
+
}
|
|
7162
|
+
return withMonths;
|
|
6545
7163
|
}
|
|
6546
7164
|
toGedcomLines(tag, level = 0, options) {
|
|
6547
7165
|
const internal = new RegExp(
|
|
@@ -6562,14 +7180,6 @@ var isCommonDate = (value) => {
|
|
|
6562
7180
|
return !!value && value !== null && typeof value === "object" && "_date" in value;
|
|
6563
7181
|
};
|
|
6564
7182
|
|
|
6565
|
-
// src/utils/get-family-with.ts
|
|
6566
|
-
var getFamilyWith = (person1, person2, famType = "FAMS") => {
|
|
6567
|
-
return person1?.get(famType)?.toValueList().find((fam) => {
|
|
6568
|
-
const family = fam;
|
|
6569
|
-
return famType === "FAMC" || family?.HUSB?.value === person2 || family?.WIFE?.value === person2;
|
|
6570
|
-
});
|
|
6571
|
-
};
|
|
6572
|
-
|
|
6573
7183
|
// src/constants/orders.ts
|
|
6574
7184
|
var DEFAULT = {};
|
|
6575
7185
|
var BIRTH_ASC = {
|
|
@@ -6809,4 +7419,4 @@ var getMarriageAscAndBirth = (person) => (itemA, keyA, itemB, keyB) => {
|
|
|
6809
7419
|
return getBirthAsc(itemA, keyA, itemB);
|
|
6810
7420
|
};
|
|
6811
7421
|
|
|
6812
|
-
export { ADOPTED, BIOLOGICAL, BIRTH, BIRTH_ASC, BIRTH_DESC, DATE_ASC, DATE_DESC, DEATH_ASC, DEATH_DESC, DEFAULT, EVERY, FEMALE, FOSTER, FRIEND, ID_GETTER_REG, ID_REG, ID_SPLIT_REG, LINE_REG, MALE, MAX_FILE_SIZE_TO_SYNC, OTHER, PARTNER, REF_LINE_REG, SEALING, SINGLE, SPOUSE, STEP, UNKOWN, getBirthAsc, getMarriageAsc, getMarriageAscAndBirth, getMarriageAscAndChildBirth, getNameAsc, getNameAscAndBirth, getNameDesc };
|
|
7422
|
+
export { ADOPTED, APP_BRANDING, BIOLOGICAL, BIRTH, BIRTH_ASC, BIRTH_DESC, DATE_ASC, DATE_DESC, DEATH_ASC, DEATH_DESC, DEFAULT, EVERY, FEMALE, FOSTER, FRIEND, ID_GETTER_REG, ID_REG, ID_SPLIT_REG, LINE_REG, MALE, MAX_FILE_SIZE_TO_SYNC, ORIG_HEAD_TAG, OTHER, PARTNER, REF_LINE_REG, SEALING, SINGLE, SPOUSE, STEP, UNKOWN, getBirthAsc, getMarriageAsc, getMarriageAscAndBirth, getMarriageAscAndChildBirth, getNameAsc, getNameAscAndBirth, getNameDesc };
|