@treeviz/gedcom-parser 2.0.9 → 2.0.12
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/dist/classes/common.d.ts +6 -1
- package/dist/classes/common.d.ts.map +1 -1
- package/dist/classes/fam.d.ts +9 -1
- package/dist/classes/fam.d.ts.map +1 -1
- package/dist/classes/gedcom.d.ts +6 -2
- package/dist/classes/gedcom.d.ts.map +1 -1
- package/dist/classes/index.js +740 -51
- package/dist/classes/indi.d.ts +6 -0
- package/dist/classes/indi.d.ts.map +1 -1
- package/dist/cli/index.js +3194 -2499
- package/dist/constants/constants.d.ts +7 -0
- package/dist/constants/constants.d.ts.map +1 -1
- package/dist/constants/index.js +1531 -916
- package/dist/factories/index.js +654 -40
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5201 -4407
- package/dist/interfaces/fam.d.ts +7 -1
- package/dist/interfaces/fam.d.ts.map +1 -1
- package/dist/interfaces/gedcom.d.ts +4 -0
- package/dist/interfaces/gedcom.d.ts.map +1 -1
- package/dist/interfaces/indi.d.ts +5 -1
- package/dist/interfaces/indi.d.ts.map +1 -1
- package/dist/kinship-translator/index.d.ts +1 -0
- package/dist/kinship-translator/index.d.ts.map +1 -1
- package/dist/kinship-translator/index.js +655 -41
- package/dist/kinship-translator/kinship-translator.ru.d.ts +18 -0
- package/dist/kinship-translator/kinship-translator.ru.d.ts.map +1 -0
- package/dist/kinship-translator/patterns.ru.d.ts +2 -0
- package/dist/kinship-translator/patterns.ru.d.ts.map +1 -0
- package/dist/kinship-translator/translators.d.ts +1 -0
- package/dist/kinship-translator/translators.d.ts.map +1 -1
- package/dist/kinship-translator/types.d.ts +1 -1
- package/dist/kinship-translator/types.d.ts.map +1 -1
- package/dist/structures/gedcom.d.ts +1 -0
- package/dist/structures/gedcom.d.ts.map +1 -1
- package/dist/types/types.d.ts +10 -0
- package/dist/types/types.d.ts.map +1 -1
- package/dist/utils/fact-edit.d.ts +22 -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/index.d.ts +4 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +850 -56
- package/dist/utils/parser.d.ts +3 -0
- package/dist/utils/parser.d.ts.map +1 -1
- package/package.json +1 -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 APP_BRANDING = "TreeViz - The Family Tree Visualiser & Editor";
|
|
11
12
|
var REF_LINE_REG = /^0 (?:(@[_a-zA-Z0-9]*@) )?(?<type>_[_A-Z][_a-zA-Z]{2,}|_?[A-Z][a-zA-Z]{2,}) ?(?<value>.*)/gm;
|
|
12
13
|
var LINE_REG = /(?<indent>^[0-9]) (?:(@[_a-zA-Z0-9]*@) )?(?<type>_[_A-Z][_a-zA-Z]{2,}|_?[A-Z][a-zA-Z]{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
|
|
@@ -95,7 +97,8 @@ __export(translators_exports, {
|
|
|
95
97
|
en: () => KinshipTranslatorEn,
|
|
96
98
|
es: () => KinshipTranslatorEs,
|
|
97
99
|
fr: () => KinshipTranslatorFr,
|
|
98
|
-
hu: () => KinshipTranslatorHU
|
|
100
|
+
hu: () => KinshipTranslatorHU,
|
|
101
|
+
ru: () => KinshipTranslatorRu
|
|
99
102
|
});
|
|
100
103
|
var getGedcomId = (gedcom) => {
|
|
101
104
|
if (!gedcom) {
|
|
@@ -542,1050 +545,1317 @@ var dateFormatter = (indi, showMarriages = false, showDays = false, showPlaces =
|
|
|
542
545
|
} : {}
|
|
543
546
|
};
|
|
544
547
|
};
|
|
545
|
-
|
|
546
|
-
|
|
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 = {};
|
|
547
556
|
this.isListable = true;
|
|
548
|
-
this.
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
this.initUniqueId();
|
|
552
|
-
if (id) {
|
|
553
|
-
this._id = id;
|
|
554
|
-
} else {
|
|
555
|
-
delete this._id;
|
|
557
|
+
this.marker = void 0;
|
|
558
|
+
if (items) {
|
|
559
|
+
this.concat(items);
|
|
556
560
|
}
|
|
557
561
|
}
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
this.uniqueId = this.uniqueId?.replace(/^[^:]+/, `~${type}`);
|
|
561
|
-
}
|
|
562
|
-
this._type = type;
|
|
562
|
+
get length() {
|
|
563
|
+
return this.values().length;
|
|
563
564
|
}
|
|
564
|
-
|
|
565
|
-
return this.
|
|
565
|
+
has(indi) {
|
|
566
|
+
return !!this.item(
|
|
567
|
+
typeof indi === "string" ? indi : indi?.id ?? ""
|
|
568
|
+
);
|
|
566
569
|
}
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
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;
|
|
571
576
|
}
|
|
572
|
-
|
|
573
|
-
const
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
if (
|
|
577
|
-
|
|
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);
|
|
578
583
|
}
|
|
579
|
-
|
|
580
|
-
|
|
584
|
+
});
|
|
585
|
+
return propList;
|
|
581
586
|
}
|
|
582
|
-
|
|
583
|
-
return this.
|
|
587
|
+
keys() {
|
|
588
|
+
return Object.keys(this.items);
|
|
584
589
|
}
|
|
585
|
-
|
|
586
|
-
this.
|
|
590
|
+
values() {
|
|
591
|
+
return Object.values(this.items);
|
|
587
592
|
}
|
|
588
|
-
|
|
589
|
-
return
|
|
593
|
+
entries() {
|
|
594
|
+
return Object.entries(this.items);
|
|
590
595
|
}
|
|
591
|
-
|
|
592
|
-
this._value = value;
|
|
596
|
+
setLength(_type) {
|
|
593
597
|
}
|
|
594
|
-
|
|
595
|
-
return this.
|
|
598
|
+
first() {
|
|
599
|
+
return this.index(0);
|
|
596
600
|
}
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
* @param gedcom - The GedComType to set as the gedcom reference
|
|
600
|
-
*/
|
|
601
|
-
setGedcom(gedcom) {
|
|
602
|
-
this._gedcom = gedcom;
|
|
601
|
+
last() {
|
|
602
|
+
return this.index(this.keys().length - 1);
|
|
603
603
|
}
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
604
|
+
index(index) {
|
|
605
|
+
const keys = this.keys();
|
|
606
|
+
const key = keys[index];
|
|
607
|
+
return key && this.items[key];
|
|
607
608
|
}
|
|
608
|
-
|
|
609
|
-
if (
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
this.value
|
|
613
|
-
);
|
|
609
|
+
item(name, value) {
|
|
610
|
+
if (arguments.length > 1) {
|
|
611
|
+
set(this.items, name, value);
|
|
612
|
+
this.setLength();
|
|
614
613
|
}
|
|
615
|
-
return this;
|
|
614
|
+
return get(this.items, name);
|
|
616
615
|
}
|
|
617
|
-
|
|
618
|
-
|
|
616
|
+
removeItem(name) {
|
|
617
|
+
unset(this.items, name);
|
|
618
|
+
this.setLength();
|
|
619
619
|
}
|
|
620
|
-
|
|
621
|
-
|
|
620
|
+
exclude(excludedList) {
|
|
621
|
+
excludedList.keys().forEach((itemId) => {
|
|
622
|
+
delete this.items[itemId];
|
|
623
|
+
});
|
|
624
|
+
this.setLength();
|
|
625
|
+
return this;
|
|
622
626
|
}
|
|
623
|
-
|
|
624
|
-
if (
|
|
625
|
-
|
|
626
|
-
this.
|
|
627
|
-
}
|
|
628
|
-
|
|
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 ?? {});
|
|
629
634
|
}
|
|
635
|
+
this.setLength();
|
|
636
|
+
return this;
|
|
630
637
|
}
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
exportValue() {
|
|
635
|
-
return this.value;
|
|
638
|
+
merge(mergedList) {
|
|
639
|
+
this.concat(mergedList?.items);
|
|
640
|
+
return this;
|
|
636
641
|
}
|
|
637
|
-
|
|
638
|
-
|
|
642
|
+
intersection(mergedList) {
|
|
643
|
+
const inter = intersectionBy(
|
|
644
|
+
this.values(),
|
|
645
|
+
mergedList?.values() ?? [],
|
|
646
|
+
"id"
|
|
647
|
+
);
|
|
648
|
+
return new _List(inter);
|
|
639
649
|
}
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
}
|
|
648
|
-
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);
|
|
649
657
|
}
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
if (
|
|
654
|
-
|
|
655
|
-
|
|
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");
|
|
656
673
|
}
|
|
657
|
-
const values = [
|
|
658
|
-
...curValue.values(),
|
|
659
|
-
...value instanceof List ? value.values() : [value]
|
|
660
|
-
];
|
|
661
|
-
curValue.concat({
|
|
662
|
-
...!unique ? values : uniqBy(
|
|
663
|
-
values,
|
|
664
|
-
(value2) => value2 instanceof _Common ? value2?.value : void 0
|
|
665
|
-
)
|
|
666
|
-
});
|
|
667
|
-
} else {
|
|
668
|
-
this.set(name, value);
|
|
669
674
|
}
|
|
670
|
-
return
|
|
675
|
+
return this;
|
|
671
676
|
}
|
|
672
|
-
|
|
673
|
-
if (
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
for (const part of nameParts) {
|
|
679
|
-
const indexPart = Number(part);
|
|
680
|
-
const itemIndex = part.match(/items\[(?<itemIndex>\d+)\]/)?.groups?.itemIndex;
|
|
681
|
-
const itemId = part.match(/items\[(?<itemId>@[A-Z]+\d+@)\]/)?.groups?.itemId;
|
|
682
|
-
const usedPart = itemId || itemIndex;
|
|
683
|
-
if (last instanceof List) {
|
|
684
|
-
if (!isNaN(indexPart)) {
|
|
685
|
-
last = last.index(indexPart);
|
|
686
|
-
} else {
|
|
687
|
-
if (usedPart) {
|
|
688
|
-
last = last.item(usedPart);
|
|
689
|
-
} else {
|
|
690
|
-
last = last?.index(0)?.get(part);
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
} else {
|
|
694
|
-
const usedIndex = Number(itemIndex ?? indexPart);
|
|
695
|
-
if (!isNaN(usedIndex)) {
|
|
696
|
-
last = last?.toList().index(usedIndex);
|
|
697
|
-
} else {
|
|
698
|
-
last = last?.get(itemId ?? part);
|
|
699
|
-
}
|
|
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;
|
|
700
683
|
}
|
|
701
|
-
|
|
702
|
-
|
|
684
|
+
this.items[item.id] = item;
|
|
685
|
+
if (increase) {
|
|
686
|
+
this.setLength("increase");
|
|
703
687
|
}
|
|
704
688
|
}
|
|
705
|
-
return
|
|
689
|
+
return this;
|
|
706
690
|
}
|
|
707
|
-
|
|
708
|
-
|
|
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;
|
|
709
697
|
}
|
|
710
|
-
|
|
711
|
-
|
|
698
|
+
copy(ClassName = _List) {
|
|
699
|
+
const newList = new ClassName();
|
|
700
|
+
Object.assign(newList.items, this.items);
|
|
701
|
+
newList.setLength();
|
|
702
|
+
return newList;
|
|
712
703
|
}
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
const name2Parts = name2.split(".");
|
|
716
|
-
if (nameParts.length !== name2Parts.length) {
|
|
717
|
-
throw new Error("Tag pathes must be of the same depth");
|
|
718
|
-
}
|
|
719
|
-
if (nameParts.length > 1 && nameParts[0] !== name2Parts[0]) {
|
|
720
|
-
throw new Error("Final tags must be siblings");
|
|
721
|
-
}
|
|
722
|
-
const valueCommon = this.get(name);
|
|
723
|
-
if (valueCommon instanceof _Common) {
|
|
724
|
-
return valueCommon?.toValue() !== condition ? void 0 : this.get(name2);
|
|
725
|
-
}
|
|
726
|
-
const valueCommon2 = this.get(name2)?.toList();
|
|
727
|
-
const ifList = new List();
|
|
728
|
-
valueCommon?.forEach((item, key) => {
|
|
729
|
-
const pair = valueCommon2?.item(key);
|
|
730
|
-
ifList.item(key, item?.toValue() !== condition ? void 0 : pair);
|
|
731
|
-
});
|
|
732
|
-
return ifList;
|
|
733
|
-
}
|
|
734
|
-
toString() {
|
|
735
|
-
return this.value?.toString() || "";
|
|
736
|
-
}
|
|
737
|
-
toValue() {
|
|
738
|
-
return this.value;
|
|
739
|
-
}
|
|
740
|
-
toProp(tag) {
|
|
741
|
-
const prop = this.get(tag);
|
|
742
|
-
return prop;
|
|
743
|
-
}
|
|
744
|
-
toList() {
|
|
745
|
-
return new List().concat(
|
|
746
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
747
|
-
this.id ? { [this.id]: this } : { ...[this] }
|
|
748
|
-
);
|
|
749
|
-
}
|
|
750
|
-
index(i) {
|
|
751
|
-
return this.toList()?.index(i);
|
|
704
|
+
except(item, ClassName = _List) {
|
|
705
|
+
return this.copy(ClassName).delete(item);
|
|
752
706
|
}
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
{ ...[this] }
|
|
758
|
-
)
|
|
759
|
-
);
|
|
707
|
+
forEach(iterate) {
|
|
708
|
+
this.entries().forEach(([key, item], index) => {
|
|
709
|
+
iterate(item, key, index);
|
|
710
|
+
});
|
|
760
711
|
}
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
this,
|
|
766
|
-
options.obje.namespace,
|
|
767
|
-
options.obje.override
|
|
768
|
-
);
|
|
769
|
-
}
|
|
712
|
+
map(iterate) {
|
|
713
|
+
return this.entries().map(([key, item], index) => {
|
|
714
|
+
return iterate(item, key, index);
|
|
715
|
+
});
|
|
770
716
|
}
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
717
|
+
reduce(iterate, initialValue) {
|
|
718
|
+
return this.entries().reduce((acc, [key, item], index) => {
|
|
719
|
+
return iterate(acc, item, key, index);
|
|
720
|
+
}, initialValue);
|
|
774
721
|
}
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
const
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
if (prop instanceof _Common) {
|
|
793
|
-
json[validKey] = prop.toObject(validKey, options);
|
|
794
|
-
} else {
|
|
795
|
-
json = {
|
|
796
|
-
...json,
|
|
797
|
-
...prop.toObject(validKey, options)
|
|
798
|
-
};
|
|
799
|
-
}
|
|
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();
|
|
736
|
+
}
|
|
737
|
+
if (Array.isArray(value)) {
|
|
738
|
+
return value.includes(itemValue);
|
|
800
739
|
}
|
|
740
|
+
return itemValue === value;
|
|
741
|
+
})) {
|
|
742
|
+
newList.item(itemId, item);
|
|
801
743
|
}
|
|
802
744
|
});
|
|
803
|
-
return
|
|
745
|
+
return newList;
|
|
804
746
|
}
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
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;
|
|
813
757
|
}
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
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);
|
|
821
767
|
}
|
|
768
|
+
return itemValue === value;
|
|
769
|
+
})) {
|
|
770
|
+
foundItem = item;
|
|
771
|
+
return true;
|
|
822
772
|
}
|
|
773
|
+
return false;
|
|
823
774
|
});
|
|
824
|
-
return
|
|
775
|
+
return foundItem;
|
|
825
776
|
}
|
|
826
|
-
|
|
827
|
-
const
|
|
828
|
-
const
|
|
829
|
-
|
|
830
|
-
this
|
|
831
|
-
this._main,
|
|
832
|
-
this._parent
|
|
833
|
-
);
|
|
834
|
-
if (newId && this._id) {
|
|
835
|
-
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);
|
|
836
782
|
}
|
|
837
|
-
const
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
if (
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
} else {
|
|
865
|
-
gedcom.push(
|
|
866
|
-
...prop.toGedcomLines(validKey, level, options)
|
|
867
|
-
);
|
|
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;
|
|
868
810
|
}
|
|
811
|
+
return sortValue2 * (direction === "DESC" ? -1 : 1);
|
|
869
812
|
}
|
|
813
|
+
);
|
|
814
|
+
sortedItems.forEach(([key, value]) => {
|
|
815
|
+
newList.item(key, value);
|
|
870
816
|
});
|
|
871
|
-
return
|
|
872
|
-
}
|
|
873
|
-
isGenoPro() {
|
|
874
|
-
const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
|
|
875
|
-
const sour = get(head, "SOUR.value");
|
|
876
|
-
return !!sour?.toLowerCase()?.startsWith("genopro");
|
|
877
|
-
}
|
|
878
|
-
isAhnenblatt() {
|
|
879
|
-
const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
|
|
880
|
-
const sour = get(head, "SOUR.value");
|
|
881
|
-
return !!sour?.toLowerCase()?.startsWith("ahnenblatt");
|
|
882
|
-
}
|
|
883
|
-
isGeni() {
|
|
884
|
-
const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
|
|
885
|
-
const sour = get(head, "SOUR.value");
|
|
886
|
-
return !!sour?.toLowerCase()?.startsWith("geni");
|
|
887
|
-
}
|
|
888
|
-
isAncestry() {
|
|
889
|
-
const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
|
|
890
|
-
const sour = get(head, "SOUR.value");
|
|
891
|
-
return !!sour?.toLowerCase()?.startsWith("ancestry");
|
|
892
|
-
}
|
|
893
|
-
isMyHeritage() {
|
|
894
|
-
const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
|
|
895
|
-
const sour = get(head, "SOUR.value");
|
|
896
|
-
return !!sour?.toLowerCase()?.startsWith("myheritage");
|
|
817
|
+
return newList;
|
|
897
818
|
}
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
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;
|
|
911
885
|
}
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
886
|
+
findIndex(item) {
|
|
887
|
+
if (!item?.id) {
|
|
888
|
+
return -1;
|
|
889
|
+
}
|
|
890
|
+
return this.keys().findIndex((key) => key === item.id);
|
|
916
891
|
}
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
const sour = get(head, "SOUR.value");
|
|
920
|
-
return sour === "GNO2GED";
|
|
892
|
+
getItems() {
|
|
893
|
+
return this.items;
|
|
921
894
|
}
|
|
922
|
-
|
|
923
|
-
const
|
|
924
|
-
return
|
|
895
|
+
toJson(tag, options) {
|
|
896
|
+
const json = this.toObject(tag, options);
|
|
897
|
+
return JSON.stringify(json);
|
|
925
898
|
}
|
|
926
|
-
|
|
927
|
-
const
|
|
928
|
-
|
|
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;
|
|
929
918
|
}
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
if (id !== void 0) return id;
|
|
934
|
-
}
|
|
935
|
-
if (this?.isMyHeritage()) {
|
|
936
|
-
const id = this.getMyHeritageTreeId();
|
|
937
|
-
if (id !== void 0) return id;
|
|
938
|
-
}
|
|
939
|
-
if (this?.isFamilySearch()) {
|
|
940
|
-
const id = this.getFamilySearchTreeId();
|
|
941
|
-
if (id !== void 0) return id;
|
|
942
|
-
}
|
|
943
|
-
if (this?.isGNO2GED()) {
|
|
944
|
-
const id = this.getGNO2GEDTreeId();
|
|
945
|
-
if (id !== void 0) return id;
|
|
946
|
-
}
|
|
947
|
-
if (this?.isAhnenblatt()) {
|
|
948
|
-
const id = this.getAhnenblattTreeId();
|
|
949
|
-
if (id !== void 0) return id;
|
|
950
|
-
}
|
|
951
|
-
if (this?.isGeni()) {
|
|
952
|
-
const id = this.getGeniTreeId();
|
|
953
|
-
if (id !== void 0) return id;
|
|
954
|
-
}
|
|
955
|
-
if (this?.isGenoPro()) {
|
|
956
|
-
const id = this.getGenoProTreeId();
|
|
957
|
-
if (id !== void 0) return id;
|
|
958
|
-
}
|
|
959
|
-
return this.getUniversalTreeId();
|
|
919
|
+
toGedcom(tag, level = 0, options) {
|
|
920
|
+
const gedcom = this.toGedcomLines(tag, level, options);
|
|
921
|
+
return gedcom.join("\n");
|
|
960
922
|
}
|
|
961
|
-
|
|
962
|
-
const
|
|
963
|
-
|
|
923
|
+
toGedcomLines(tag, level = 0, options) {
|
|
924
|
+
const gedcom = [];
|
|
925
|
+
this.entries().forEach(([_, item]) => {
|
|
926
|
+
const validTag = getValidTag(tag);
|
|
927
|
+
const validKey = item.id;
|
|
928
|
+
const validValue = validKey ? validTag : item.exportValue();
|
|
929
|
+
gedcom.push(
|
|
930
|
+
`${level} ${validKey || validTag}${validValue ? ` ${validValue}` : ""}`
|
|
931
|
+
);
|
|
932
|
+
gedcom.push(
|
|
933
|
+
...item.toGedcomLines(
|
|
934
|
+
validTag,
|
|
935
|
+
level + 1,
|
|
936
|
+
options
|
|
937
|
+
)
|
|
938
|
+
);
|
|
939
|
+
});
|
|
940
|
+
return gedcom;
|
|
964
941
|
}
|
|
965
|
-
|
|
966
|
-
const
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
942
|
+
toValue() {
|
|
943
|
+
const propList = new _List();
|
|
944
|
+
this.entries().forEach(([key, item]) => {
|
|
945
|
+
propList.item(key, item?.toValue());
|
|
946
|
+
});
|
|
947
|
+
return propList;
|
|
971
948
|
}
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
return rin;
|
|
976
|
-
}
|
|
977
|
-
return "familysearch";
|
|
949
|
+
// @deprecated use get instead
|
|
950
|
+
toProp(tag) {
|
|
951
|
+
return this.get(tag);
|
|
978
952
|
}
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
953
|
+
toList() {
|
|
954
|
+
return new _List().concat(this.items);
|
|
955
|
+
}
|
|
956
|
+
toValueList() {
|
|
957
|
+
const newList = new _List();
|
|
958
|
+
this.values().forEach((value) => {
|
|
959
|
+
value.value && newList.item(value.value, value);
|
|
960
|
+
});
|
|
961
|
+
return newList;
|
|
962
|
+
}
|
|
963
|
+
};
|
|
964
|
+
|
|
965
|
+
// src/classes/common.ts
|
|
966
|
+
var Common = class _Common {
|
|
967
|
+
constructor(gedcom, id, main, parent) {
|
|
968
|
+
this.isListable = true;
|
|
969
|
+
this._gedcom = gedcom;
|
|
970
|
+
this._main = main;
|
|
971
|
+
this._parent = parent;
|
|
972
|
+
this.initUniqueId();
|
|
973
|
+
if (id) {
|
|
974
|
+
this._id = id;
|
|
975
|
+
} else {
|
|
976
|
+
delete this._id;
|
|
983
977
|
}
|
|
984
|
-
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
985
|
-
return fileName || "FamilySearch Import";
|
|
986
978
|
}
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
const idMatch = fileName.match(/_(\d+)/);
|
|
991
|
-
if (idMatch) {
|
|
992
|
-
return idMatch[1];
|
|
993
|
-
}
|
|
979
|
+
set type(type) {
|
|
980
|
+
if (type) {
|
|
981
|
+
this.uniqueId = this.uniqueId?.replace(/^[^:]+/, `~${type}`);
|
|
994
982
|
}
|
|
995
|
-
|
|
983
|
+
this._type = type;
|
|
996
984
|
}
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
985
|
+
get type() {
|
|
986
|
+
return this._type;
|
|
1000
987
|
}
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
const idMatch = fileName.match(/_(\d+)/);
|
|
1005
|
-
if (idMatch) {
|
|
1006
|
-
return idMatch[1];
|
|
1007
|
-
}
|
|
988
|
+
initUniqueId() {
|
|
989
|
+
if (this._gedcom) {
|
|
990
|
+
this.uniqueId = `~Common:${this._gedcom.refcount++}`;
|
|
1008
991
|
}
|
|
1009
|
-
return void 0;
|
|
1010
992
|
}
|
|
1011
|
-
|
|
1012
|
-
const
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
if (fileName) {
|
|
1018
|
-
const idMatch = fileName.match(/_(\d+)/);
|
|
1019
|
-
if (idMatch) {
|
|
1020
|
-
return idMatch[1];
|
|
993
|
+
set uniqueId(id) {
|
|
994
|
+
const currentId = this._uniqueId;
|
|
995
|
+
if (this._gedcom?.reflist && id) {
|
|
996
|
+
this._uniqueId = id;
|
|
997
|
+
if (currentId && this._gedcom.reflist[currentId]) {
|
|
998
|
+
delete this._gedcom.reflist[currentId];
|
|
1021
999
|
}
|
|
1000
|
+
this._gedcom.reflist[id] = this;
|
|
1022
1001
|
}
|
|
1023
|
-
return void 0;
|
|
1024
1002
|
}
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
1003
|
+
get uniqueId() {
|
|
1004
|
+
return this._uniqueId;
|
|
1028
1005
|
}
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
if (rin) {
|
|
1032
|
-
return rin;
|
|
1033
|
-
}
|
|
1034
|
-
return `gno_${this._gedcom?.refcount || "unknown"}`;
|
|
1006
|
+
set id(id) {
|
|
1007
|
+
this._id = idGetter(id);
|
|
1035
1008
|
}
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
if (treeName) {
|
|
1039
|
-
return treeName;
|
|
1040
|
-
}
|
|
1041
|
-
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1042
|
-
return fileName || "GNO2GED Export";
|
|
1009
|
+
get id() {
|
|
1010
|
+
return idGetter(this._id);
|
|
1043
1011
|
}
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
const sourceType = this.getSourceType();
|
|
1050
|
-
const prefix = sourceType ? sourceType.toLowerCase() : "tree";
|
|
1051
|
-
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1052
|
-
if (fileName) {
|
|
1053
|
-
const idMatch = fileName.match(/_(\d+)/);
|
|
1054
|
-
if (idMatch) {
|
|
1055
|
-
return `${prefix}_${idMatch[1]}`;
|
|
1056
|
-
}
|
|
1057
|
-
}
|
|
1058
|
-
return `${prefix}_${this._gedcom?.refcount || "unknown"}`;
|
|
1012
|
+
set value(value) {
|
|
1013
|
+
this._value = value;
|
|
1014
|
+
}
|
|
1015
|
+
get value() {
|
|
1016
|
+
return this._value;
|
|
1059
1017
|
}
|
|
1060
1018
|
/**
|
|
1061
|
-
*
|
|
1062
|
-
*
|
|
1019
|
+
* Set the gedcom reference for this object
|
|
1020
|
+
* @param gedcom - The GedComType to set as the gedcom reference
|
|
1063
1021
|
*/
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
const prefix = sourceType ? `${sourceType}-` : "";
|
|
1067
|
-
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1068
|
-
if (fileName) {
|
|
1069
|
-
const cleanName = fileName.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
1070
|
-
return `${prefix}${cleanName}`;
|
|
1071
|
-
}
|
|
1072
|
-
const sourName = get(this, "HEAD.SOUR.NAME.value") || get(this.getGedcom(), "HEAD.SOUR.NAME.value");
|
|
1073
|
-
if (sourName) {
|
|
1074
|
-
return `${prefix}${sourName}`;
|
|
1075
|
-
}
|
|
1076
|
-
const sourValue = get(this, "HEAD.SOUR.value") || get(this.getGedcom(), "HEAD.SOUR.value");
|
|
1077
|
-
if (sourValue) {
|
|
1078
|
-
return `${prefix}${sourValue}`;
|
|
1079
|
-
}
|
|
1080
|
-
return `${prefix}Unknown Tree`;
|
|
1022
|
+
setGedcom(gedcom) {
|
|
1023
|
+
this._gedcom = gedcom;
|
|
1081
1024
|
}
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
if (this
|
|
1088
|
-
|
|
1089
|
-
|
|
1025
|
+
// avoid to override
|
|
1026
|
+
get originalValue() {
|
|
1027
|
+
return this._value;
|
|
1028
|
+
}
|
|
1029
|
+
get ref() {
|
|
1030
|
+
if (typeof this.value === "string" && isId(this.value) && this.refType) {
|
|
1031
|
+
return this._gedcom?.[getListTag(this.refType)]?.item(
|
|
1032
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1033
|
+
this.value
|
|
1034
|
+
);
|
|
1090
1035
|
}
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1036
|
+
return this;
|
|
1037
|
+
}
|
|
1038
|
+
get main() {
|
|
1039
|
+
return this._main;
|
|
1040
|
+
}
|
|
1041
|
+
get parent() {
|
|
1042
|
+
return this._parent;
|
|
1043
|
+
}
|
|
1044
|
+
addRef(refNode) {
|
|
1045
|
+
if (typeof refNode.value === "string" && isId(refNode.value) && refNode.refType) {
|
|
1046
|
+
if (!this._refs) {
|
|
1047
|
+
this._refs = new List();
|
|
1048
|
+
}
|
|
1049
|
+
this._refs.item(refNode.value, refNode);
|
|
1094
1050
|
}
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1051
|
+
}
|
|
1052
|
+
getRefs() {
|
|
1053
|
+
return this._refs;
|
|
1054
|
+
}
|
|
1055
|
+
exportValue() {
|
|
1056
|
+
return this.value;
|
|
1057
|
+
}
|
|
1058
|
+
removeValue() {
|
|
1059
|
+
delete this._value;
|
|
1060
|
+
}
|
|
1061
|
+
set(name, value) {
|
|
1062
|
+
if (isGedcomTrailerTag(name)) {
|
|
1063
|
+
return void 0;
|
|
1098
1064
|
}
|
|
1099
|
-
if (
|
|
1100
|
-
const
|
|
1101
|
-
|
|
1065
|
+
if (typeof value === "string") {
|
|
1066
|
+
const usedValue = createCommon(this._gedcom, void 0, this.main);
|
|
1067
|
+
usedValue.value = value;
|
|
1068
|
+
set(this, name, usedValue);
|
|
1069
|
+
} else {
|
|
1070
|
+
set(this, name, value);
|
|
1102
1071
|
}
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1072
|
+
return get(this, name);
|
|
1073
|
+
}
|
|
1074
|
+
assign(name, value, unique = false) {
|
|
1075
|
+
if (isGedcomTrailerTag(name)) {
|
|
1076
|
+
return void 0;
|
|
1106
1077
|
}
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
if (
|
|
1078
|
+
let curValue = this.get(name);
|
|
1079
|
+
if (curValue?.isListable) {
|
|
1080
|
+
if (curValue instanceof _Common) {
|
|
1081
|
+
curValue = new List().concat({ ...[curValue] });
|
|
1082
|
+
this.set(name, curValue);
|
|
1083
|
+
}
|
|
1084
|
+
const values = [
|
|
1085
|
+
...curValue.values(),
|
|
1086
|
+
...value instanceof List ? value.values() : [value]
|
|
1087
|
+
];
|
|
1088
|
+
curValue.concat({
|
|
1089
|
+
...!unique ? values : uniqBy(
|
|
1090
|
+
values,
|
|
1091
|
+
(value2) => value2 instanceof _Common ? value2?.value : void 0
|
|
1092
|
+
)
|
|
1093
|
+
});
|
|
1094
|
+
} else {
|
|
1095
|
+
this.set(name, value);
|
|
1110
1096
|
}
|
|
1111
|
-
return this
|
|
1097
|
+
return get(this, name);
|
|
1112
1098
|
}
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
if (
|
|
1126
|
-
|
|
1099
|
+
get(name) {
|
|
1100
|
+
if (!name.includes(".")) {
|
|
1101
|
+
return get(this, name);
|
|
1102
|
+
}
|
|
1103
|
+
const nameParts = name.split(".");
|
|
1104
|
+
let last = this;
|
|
1105
|
+
for (const part of nameParts) {
|
|
1106
|
+
const indexPart = Number(part);
|
|
1107
|
+
const itemIndex = part.match(/items\[(?<itemIndex>\d+)\]/)?.groups?.itemIndex;
|
|
1108
|
+
const itemId = part.match(/items\[(?<itemId>@[A-Z]+\d+@)\]/)?.groups?.itemId;
|
|
1109
|
+
const usedPart = itemId || itemIndex;
|
|
1110
|
+
if (last instanceof List) {
|
|
1111
|
+
if (!isNaN(indexPart)) {
|
|
1112
|
+
last = last.index(indexPart);
|
|
1113
|
+
} else {
|
|
1114
|
+
if (usedPart) {
|
|
1115
|
+
last = last.item(usedPart);
|
|
1116
|
+
} else {
|
|
1117
|
+
last = last?.index(0)?.get(part);
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
} else {
|
|
1121
|
+
const usedIndex = Number(itemIndex ?? indexPart);
|
|
1122
|
+
if (!isNaN(usedIndex)) {
|
|
1123
|
+
last = last?.toList().index(usedIndex);
|
|
1124
|
+
} else {
|
|
1125
|
+
last = last?.get(itemId ?? part);
|
|
1127
1126
|
}
|
|
1128
1127
|
}
|
|
1128
|
+
if (!last) {
|
|
1129
|
+
break;
|
|
1130
|
+
}
|
|
1129
1131
|
}
|
|
1130
|
-
|
|
1131
|
-
};
|
|
1132
|
-
var createCommon = (gedcom, id, main, parent) => {
|
|
1133
|
-
return createProxy(
|
|
1134
|
-
new Common(gedcom, id, main, parent)
|
|
1135
|
-
);
|
|
1136
|
-
};
|
|
1137
|
-
var isOnlyMainProp = (key) => {
|
|
1138
|
-
return key === "_gedcom" || key === "_main" || key === "_parent" || key === "_uniqueId" || key === "_type" || key === "_refs" || key === "id" || key === "_id";
|
|
1139
|
-
};
|
|
1140
|
-
var isValidKey = (common, key) => {
|
|
1141
|
-
const prop = get(common, key);
|
|
1142
|
-
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);
|
|
1143
|
-
};
|
|
1144
|
-
var getValidKeys = (common) => {
|
|
1145
|
-
return Object.keys(common).filter((key) => {
|
|
1146
|
-
return isValidKey(common, key);
|
|
1147
|
-
});
|
|
1148
|
-
};
|
|
1149
|
-
var getValidTag = (tag) => {
|
|
1150
|
-
return tag.replace(/^@@/, "");
|
|
1151
|
-
};
|
|
1152
|
-
var getListTag = (tag) => {
|
|
1153
|
-
return `@@${tag}`;
|
|
1154
|
-
};
|
|
1155
|
-
var isId = (string) => {
|
|
1156
|
-
return ID_REG.test(string);
|
|
1157
|
-
};
|
|
1158
|
-
var idGetter = (id) => {
|
|
1159
|
-
if (id === void 0) {
|
|
1160
|
-
return void 0;
|
|
1132
|
+
return last;
|
|
1161
1133
|
}
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
if (!parts?.at && !parts?.letter) {
|
|
1165
|
-
newId = `@U${newId}`;
|
|
1166
|
-
} else if (!parts.at) {
|
|
1167
|
-
newId = `@${newId}`;
|
|
1168
|
-
} else if (!parts.letter) {
|
|
1169
|
-
newId = newId.replace(/^@/, "@U");
|
|
1134
|
+
remove(name) {
|
|
1135
|
+
unset(this, name);
|
|
1170
1136
|
}
|
|
1171
|
-
|
|
1172
|
-
|
|
1137
|
+
getGedcom() {
|
|
1138
|
+
return this._gedcom;
|
|
1173
1139
|
}
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
// length = 0;
|
|
1180
|
-
constructor(items) {
|
|
1181
|
-
this.items = {};
|
|
1182
|
-
this.isListable = true;
|
|
1183
|
-
this.marker = void 0;
|
|
1184
|
-
if (items) {
|
|
1185
|
-
this.concat(items);
|
|
1140
|
+
getIf(name, condition, name2) {
|
|
1141
|
+
const nameParts = name.split(".");
|
|
1142
|
+
const name2Parts = name2.split(".");
|
|
1143
|
+
if (nameParts.length !== name2Parts.length) {
|
|
1144
|
+
throw new Error("Tag pathes must be of the same depth");
|
|
1186
1145
|
}
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
);
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
propList.item(key, item.get(name));
|
|
1200
|
-
});
|
|
1201
|
-
return propList;
|
|
1202
|
-
}
|
|
1203
|
-
getIf(name, condition, name2) {
|
|
1204
|
-
const propList = new _List();
|
|
1205
|
-
this.entries().forEach(([key, item]) => {
|
|
1206
|
-
const passedItem = item.getIf(name, condition, name2);
|
|
1207
|
-
if (passedItem) {
|
|
1208
|
-
propList.item(key, passedItem);
|
|
1209
|
-
}
|
|
1146
|
+
if (nameParts.length > 1 && nameParts[0] !== name2Parts[0]) {
|
|
1147
|
+
throw new Error("Final tags must be siblings");
|
|
1148
|
+
}
|
|
1149
|
+
const valueCommon = this.get(name);
|
|
1150
|
+
if (valueCommon instanceof _Common) {
|
|
1151
|
+
return valueCommon?.toValue() !== condition ? void 0 : this.get(name2);
|
|
1152
|
+
}
|
|
1153
|
+
const valueCommon2 = this.get(name2)?.toList();
|
|
1154
|
+
const ifList = new List();
|
|
1155
|
+
valueCommon?.forEach((item, key) => {
|
|
1156
|
+
const pair = valueCommon2?.item(key);
|
|
1157
|
+
ifList.item(key, item?.toValue() !== condition ? void 0 : pair);
|
|
1210
1158
|
});
|
|
1211
|
-
return
|
|
1212
|
-
}
|
|
1213
|
-
keys() {
|
|
1214
|
-
return Object.keys(this.items);
|
|
1159
|
+
return ifList;
|
|
1215
1160
|
}
|
|
1216
|
-
|
|
1217
|
-
return
|
|
1161
|
+
toString() {
|
|
1162
|
+
return this.value?.toString() || "";
|
|
1218
1163
|
}
|
|
1219
|
-
|
|
1220
|
-
return
|
|
1164
|
+
toValue() {
|
|
1165
|
+
return this.value;
|
|
1221
1166
|
}
|
|
1222
|
-
|
|
1167
|
+
toProp(tag) {
|
|
1168
|
+
const prop = this.get(tag);
|
|
1169
|
+
return prop;
|
|
1223
1170
|
}
|
|
1224
|
-
|
|
1225
|
-
return
|
|
1171
|
+
toList() {
|
|
1172
|
+
return new List().concat(
|
|
1173
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1174
|
+
this.id ? { [this.id]: this } : { ...[this] }
|
|
1175
|
+
);
|
|
1226
1176
|
}
|
|
1227
|
-
|
|
1228
|
-
return this.index(
|
|
1177
|
+
index(i) {
|
|
1178
|
+
return this.toList()?.index(i);
|
|
1229
1179
|
}
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1180
|
+
toValueList() {
|
|
1181
|
+
return new List().concat(
|
|
1182
|
+
this.value ? { [this.value]: this } : (
|
|
1183
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1184
|
+
{ ...[this] }
|
|
1185
|
+
)
|
|
1186
|
+
);
|
|
1234
1187
|
}
|
|
1235
|
-
|
|
1236
|
-
if (
|
|
1237
|
-
|
|
1238
|
-
|
|
1188
|
+
standardizeObject(tag, options) {
|
|
1189
|
+
if (tag === "OBJE" && !options?.original && options?.obje?.standardize && options?.obje?.namespace && "standardizeMedia" in this) {
|
|
1190
|
+
const standardize = this.standardizeMedia;
|
|
1191
|
+
return standardize.call(
|
|
1192
|
+
this,
|
|
1193
|
+
options.obje.namespace,
|
|
1194
|
+
options.obje.override
|
|
1195
|
+
);
|
|
1239
1196
|
}
|
|
1240
|
-
return get(this.items, name);
|
|
1241
1197
|
}
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1198
|
+
toJson(tag, options) {
|
|
1199
|
+
const json = this.toObject(tag, options);
|
|
1200
|
+
return JSON.stringify(json);
|
|
1245
1201
|
}
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1202
|
+
toObject(tag, options) {
|
|
1203
|
+
this.standardizeObject(tag, options);
|
|
1204
|
+
const validKeys = getValidKeys(this);
|
|
1205
|
+
let json = {};
|
|
1206
|
+
validKeys.forEach((key) => {
|
|
1207
|
+
if (key === "id" && this.id !== void 0) {
|
|
1208
|
+
json.id = this.id;
|
|
1209
|
+
} else if (key === "_id" && this._id !== void 0) {
|
|
1210
|
+
json.id = this._id;
|
|
1211
|
+
} else if (key === "value" && this.value !== void 0) {
|
|
1212
|
+
json.value = this.value;
|
|
1213
|
+
} else if (key === "_value" && this._value !== void 0) {
|
|
1214
|
+
json.value = this._value;
|
|
1215
|
+
} else {
|
|
1216
|
+
const validKey = key;
|
|
1217
|
+
const prop = this.get(validKey);
|
|
1218
|
+
if (typeof prop?.toObject === "function") {
|
|
1219
|
+
if (prop instanceof _Common) {
|
|
1220
|
+
json[validKey] = prop.toObject(validKey, options);
|
|
1221
|
+
} else {
|
|
1222
|
+
json = {
|
|
1223
|
+
...json,
|
|
1224
|
+
...prop.toObject(validKey, options)
|
|
1225
|
+
};
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1249
1229
|
});
|
|
1250
|
-
|
|
1251
|
-
return this;
|
|
1230
|
+
return json;
|
|
1252
1231
|
}
|
|
1253
|
-
|
|
1254
|
-
if (
|
|
1255
|
-
|
|
1256
|
-
this.append(item);
|
|
1257
|
-
});
|
|
1258
|
-
} else {
|
|
1259
|
-
Object.assign(this.items, items ?? {});
|
|
1232
|
+
merge(other, override = false, avoidKeys = []) {
|
|
1233
|
+
if (!other) {
|
|
1234
|
+
return this;
|
|
1260
1235
|
}
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1236
|
+
const validKeys = getValidKeys(other);
|
|
1237
|
+
validKeys.forEach((validKey) => {
|
|
1238
|
+
if (avoidKeys.includes(validKey)) {
|
|
1239
|
+
return;
|
|
1240
|
+
}
|
|
1241
|
+
const current = this.get(validKey);
|
|
1242
|
+
const mergeValue = other.get(validKey);
|
|
1243
|
+
if (mergeValue) {
|
|
1244
|
+
if (current instanceof _Common || current instanceof List) {
|
|
1245
|
+
this.assign(validKey, mergeValue, true);
|
|
1246
|
+
} else if (!current || override && validKey !== "id" && validKey !== "_id") {
|
|
1247
|
+
this.set(validKey, mergeValue);
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
});
|
|
1266
1251
|
return this;
|
|
1267
1252
|
}
|
|
1268
|
-
|
|
1269
|
-
const
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1253
|
+
clone(newId = false, avoidKeys = []) {
|
|
1254
|
+
const ctor = this.constructor;
|
|
1255
|
+
const instance = new ctor(
|
|
1256
|
+
this._gedcom,
|
|
1257
|
+
this._id,
|
|
1258
|
+
this._main,
|
|
1259
|
+
this._parent
|
|
1273
1260
|
);
|
|
1274
|
-
|
|
1261
|
+
if (newId && this._id) {
|
|
1262
|
+
instance.id = `IFT${this._id.replace(/[^0-9]/g, "")}`;
|
|
1263
|
+
}
|
|
1264
|
+
const cloned = createProxy(instance);
|
|
1265
|
+
cloned.merge(this, true, avoidKeys);
|
|
1266
|
+
return cloned;
|
|
1275
1267
|
}
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
this.values(),
|
|
1279
|
-
mergedList?.values() ?? [],
|
|
1280
|
-
"id"
|
|
1281
|
-
);
|
|
1282
|
-
return new _List(inter);
|
|
1268
|
+
// fromGedcom<T = typeof this>(value: string) {
|
|
1269
|
+
fromGedcom(_value) {
|
|
1283
1270
|
}
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
if (this.items[item.id]) {
|
|
1288
|
-
delete this.items[item.id];
|
|
1289
|
-
increase = false;
|
|
1290
|
-
}
|
|
1291
|
-
this.items = Object.assign(
|
|
1292
|
-
{
|
|
1293
|
-
[item.id]: item
|
|
1294
|
-
},
|
|
1295
|
-
this.items
|
|
1296
|
-
);
|
|
1297
|
-
if (increase) {
|
|
1298
|
-
this.setLength("increase");
|
|
1299
|
-
}
|
|
1300
|
-
}
|
|
1301
|
-
return this;
|
|
1271
|
+
toGedcom(tag, level = 0, options) {
|
|
1272
|
+
const gedcom = this.toGedcomLines(tag, level, options);
|
|
1273
|
+
return gedcom.join("\n");
|
|
1302
1274
|
}
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1275
|
+
toGedcomLines(tag, level = 0, options) {
|
|
1276
|
+
this.standardizeObject(tag, options);
|
|
1277
|
+
const validKeys = getValidKeys(this);
|
|
1278
|
+
const gedcom = [];
|
|
1279
|
+
validKeys.forEach((key) => {
|
|
1280
|
+
const validKey = key;
|
|
1281
|
+
const prop = this.get(validKey);
|
|
1282
|
+
if (typeof prop?.toGedcomLines === "function") {
|
|
1283
|
+
if (prop instanceof _Common) {
|
|
1284
|
+
const value = prop.exportValue();
|
|
1285
|
+
gedcom.push(
|
|
1286
|
+
`${level} ${validKey}${value ? ` ${value}` : ""}`
|
|
1287
|
+
);
|
|
1288
|
+
gedcom.push(
|
|
1289
|
+
...prop.toGedcomLines(validKey, level + 1, options)
|
|
1290
|
+
);
|
|
1291
|
+
} else {
|
|
1292
|
+
gedcom.push(
|
|
1293
|
+
...prop.toGedcomLines(validKey, level, options)
|
|
1294
|
+
);
|
|
1295
|
+
}
|
|
1313
1296
|
}
|
|
1314
|
-
}
|
|
1315
|
-
return
|
|
1297
|
+
});
|
|
1298
|
+
return gedcom;
|
|
1316
1299
|
}
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
delete this.items[item.id];
|
|
1320
|
-
this.setLength("decrease");
|
|
1321
|
-
}
|
|
1322
|
-
return this;
|
|
1300
|
+
getHeadRecord() {
|
|
1301
|
+
return get(this, "HEAD") || get(this.getGedcom(), "HEAD");
|
|
1323
1302
|
}
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
Object.assign(newList.items, this.items);
|
|
1327
|
-
newList.setLength();
|
|
1328
|
-
return newList;
|
|
1303
|
+
getOriginalHeadRecord() {
|
|
1304
|
+
return get(this, ORIG_HEAD_TAG) || get(this.getGedcom(), ORIG_HEAD_TAG) || get(this.getHeadRecord(), ORIG_HEAD_TAG);
|
|
1329
1305
|
}
|
|
1330
|
-
|
|
1331
|
-
|
|
1306
|
+
getSourceHeads() {
|
|
1307
|
+
const heads = [this.getOriginalHeadRecord(), this.getHeadRecord()];
|
|
1308
|
+
return heads.filter((head, index) => {
|
|
1309
|
+
return Boolean(head && heads.indexOf(head) === index);
|
|
1310
|
+
});
|
|
1332
1311
|
}
|
|
1333
|
-
|
|
1334
|
-
this.
|
|
1335
|
-
|
|
1312
|
+
getFromSourceHeads(path) {
|
|
1313
|
+
for (const head of this.getSourceHeads()) {
|
|
1314
|
+
const value = get(head, path);
|
|
1315
|
+
if (value !== void 0 && value !== null && value !== "") {
|
|
1316
|
+
return value;
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
return void 0;
|
|
1320
|
+
}
|
|
1321
|
+
sourStartsWith(prefix) {
|
|
1322
|
+
return this.getSourceHeads().some((head) => {
|
|
1323
|
+
const sour = get(head, "SOUR.value");
|
|
1324
|
+
return !!sour?.toLowerCase()?.startsWith(prefix);
|
|
1336
1325
|
});
|
|
1337
1326
|
}
|
|
1338
|
-
|
|
1339
|
-
return this.
|
|
1340
|
-
|
|
1327
|
+
isGenoPro() {
|
|
1328
|
+
return this.sourStartsWith("genopro");
|
|
1329
|
+
}
|
|
1330
|
+
isAhnenblatt() {
|
|
1331
|
+
return this.sourStartsWith("ahnenblatt");
|
|
1332
|
+
}
|
|
1333
|
+
isGeni() {
|
|
1334
|
+
return this.sourStartsWith("geni");
|
|
1335
|
+
}
|
|
1336
|
+
isAncestry() {
|
|
1337
|
+
return this.sourStartsWith("ancestry");
|
|
1338
|
+
}
|
|
1339
|
+
isMyHeritage() {
|
|
1340
|
+
return this.sourStartsWith("myheritage");
|
|
1341
|
+
}
|
|
1342
|
+
/**
|
|
1343
|
+
* Get the source type as a string (for prefixing tree IDs and names)
|
|
1344
|
+
* Returns the detected source type or undefined if unknown
|
|
1345
|
+
*/
|
|
1346
|
+
getSourceType() {
|
|
1347
|
+
if (this.isAncestry()) return "Ancestry";
|
|
1348
|
+
if (this.isMyHeritage()) return "MyHeritage";
|
|
1349
|
+
if (this.isFamilySearch()) return "FamilySearch";
|
|
1350
|
+
if (this.isGNO2GED()) return "GNO2GED";
|
|
1351
|
+
if (this.isGenoPro()) return "GenoPro";
|
|
1352
|
+
if (this.isAhnenblatt()) return "Ahnenblatt";
|
|
1353
|
+
if (this.isGeni()) return "Geni";
|
|
1354
|
+
return void 0;
|
|
1355
|
+
}
|
|
1356
|
+
isFamilySearch() {
|
|
1357
|
+
return this.getSourceHeads().some((head) => {
|
|
1358
|
+
const sourName = get(head, "SOUR.NAME.value");
|
|
1359
|
+
return sourName === "FamilySearch API";
|
|
1341
1360
|
});
|
|
1342
1361
|
}
|
|
1343
|
-
|
|
1344
|
-
return this.
|
|
1345
|
-
|
|
1346
|
-
|
|
1362
|
+
isGNO2GED() {
|
|
1363
|
+
return this.getSourceHeads().some((head) => {
|
|
1364
|
+
const sour = get(head, "SOUR.value");
|
|
1365
|
+
return sour === "GNO2GED";
|
|
1366
|
+
});
|
|
1347
1367
|
}
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1368
|
+
getAncestryTreeId() {
|
|
1369
|
+
return this.getFromSourceHeads("SOUR._TREE.RIN.value") || (get(this, "HEAD.SOUR._TREE.RIN.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.RIN.value"));
|
|
1370
|
+
}
|
|
1371
|
+
getMyHeritageTreeId() {
|
|
1372
|
+
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"));
|
|
1373
|
+
}
|
|
1374
|
+
getTreeId() {
|
|
1375
|
+
if (this?.isAncestry()) {
|
|
1376
|
+
const id = this.getAncestryTreeId();
|
|
1377
|
+
if (id !== void 0) return id;
|
|
1378
|
+
}
|
|
1379
|
+
if (this?.isMyHeritage()) {
|
|
1380
|
+
const id = this.getMyHeritageTreeId();
|
|
1381
|
+
if (id !== void 0) return id;
|
|
1382
|
+
}
|
|
1383
|
+
if (this?.isFamilySearch()) {
|
|
1384
|
+
const id = this.getFamilySearchTreeId();
|
|
1385
|
+
if (id !== void 0) return id;
|
|
1386
|
+
}
|
|
1387
|
+
if (this?.isGNO2GED()) {
|
|
1388
|
+
const id = this.getGNO2GEDTreeId();
|
|
1389
|
+
if (id !== void 0) return id;
|
|
1390
|
+
}
|
|
1391
|
+
if (this?.isAhnenblatt()) {
|
|
1392
|
+
const id = this.getAhnenblattTreeId();
|
|
1393
|
+
if (id !== void 0) return id;
|
|
1394
|
+
}
|
|
1395
|
+
if (this?.isGeni()) {
|
|
1396
|
+
const id = this.getGeniTreeId();
|
|
1397
|
+
if (id !== void 0) return id;
|
|
1398
|
+
}
|
|
1399
|
+
if (this?.isGenoPro()) {
|
|
1400
|
+
const id = this.getGenoProTreeId();
|
|
1401
|
+
if (id !== void 0) return id;
|
|
1402
|
+
}
|
|
1403
|
+
return this.getUniversalTreeId();
|
|
1404
|
+
}
|
|
1405
|
+
getAncestryTreeName() {
|
|
1406
|
+
return this.getFromSourceHeads("SOUR._TREE.value") || (get(this, "HEAD.SOUR._TREE.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.value"));
|
|
1407
|
+
}
|
|
1408
|
+
getMyHeritageTreeName() {
|
|
1409
|
+
const path = "HEAD.FILE.value";
|
|
1410
|
+
const treeDetails = get(this, path) || get(this.getGedcom(), path);
|
|
1411
|
+
return treeDetails?.match(
|
|
1412
|
+
/Exported by MyHeritage.com from (?<tree>.+) in.+$/
|
|
1413
|
+
)?.groups?.tree;
|
|
1414
|
+
}
|
|
1415
|
+
getFamilySearchTreeId() {
|
|
1416
|
+
const rin = this.getFromSourceHeads("SOUR._TREE.RIN.value") || get(this, "HEAD.SOUR._TREE.RIN.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.RIN.value");
|
|
1417
|
+
if (rin) {
|
|
1418
|
+
return rin;
|
|
1419
|
+
}
|
|
1420
|
+
return "familysearch";
|
|
1421
|
+
}
|
|
1422
|
+
getFamilySearchTreeName() {
|
|
1423
|
+
const treeName = this.getFromSourceHeads("SOUR._TREE.value") || get(this, "HEAD.SOUR._TREE.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.value");
|
|
1424
|
+
if (treeName) {
|
|
1425
|
+
return treeName;
|
|
1426
|
+
}
|
|
1427
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1428
|
+
return fileName || "FamilySearch Import";
|
|
1429
|
+
}
|
|
1430
|
+
getAhnenblattTreeId() {
|
|
1431
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1432
|
+
if (fileName) {
|
|
1433
|
+
const idMatch = fileName.match(/_(\d+)/);
|
|
1434
|
+
if (idMatch) {
|
|
1435
|
+
return idMatch[1];
|
|
1369
1436
|
}
|
|
1370
|
-
}
|
|
1371
|
-
return
|
|
1437
|
+
}
|
|
1438
|
+
return void 0;
|
|
1372
1439
|
}
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
return
|
|
1440
|
+
getAhnenblattTreeName() {
|
|
1441
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1442
|
+
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
1443
|
+
}
|
|
1444
|
+
getGeniTreeId() {
|
|
1445
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1446
|
+
if (fileName) {
|
|
1447
|
+
const idMatch = fileName.match(/_(\d+)/);
|
|
1448
|
+
if (idMatch) {
|
|
1449
|
+
return idMatch[1];
|
|
1383
1450
|
}
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
return true;
|
|
1451
|
+
}
|
|
1452
|
+
return void 0;
|
|
1453
|
+
}
|
|
1454
|
+
getGeniTreeName() {
|
|
1455
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1456
|
+
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
1457
|
+
}
|
|
1458
|
+
getGenoProTreeId() {
|
|
1459
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1460
|
+
if (fileName) {
|
|
1461
|
+
const idMatch = fileName.match(/_(\d+)/);
|
|
1462
|
+
if (idMatch) {
|
|
1463
|
+
return idMatch[1];
|
|
1398
1464
|
}
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
return foundItem;
|
|
1465
|
+
}
|
|
1466
|
+
return void 0;
|
|
1402
1467
|
}
|
|
1403
|
-
|
|
1404
|
-
const
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1468
|
+
getGenoProTreeName() {
|
|
1469
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1470
|
+
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
1471
|
+
}
|
|
1472
|
+
getGNO2GEDTreeId() {
|
|
1473
|
+
const rin = get(this, "HEAD._TREE.RIN.value") || get(this.getGedcom(), "HEAD._TREE.RIN.value");
|
|
1474
|
+
if (rin) {
|
|
1475
|
+
return rin;
|
|
1408
1476
|
}
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
sortValue2 = -1;
|
|
1432
|
-
} else if (valueA < valueB) {
|
|
1433
|
-
sortValue2 = -1;
|
|
1434
|
-
} else if (valueA > valueB) {
|
|
1435
|
-
sortValue2 = 1;
|
|
1436
|
-
}
|
|
1437
|
-
return sortValue2 * (direction === "DESC" ? -1 : 1);
|
|
1477
|
+
return `gno_${this._gedcom?.refcount || "unknown"}`;
|
|
1478
|
+
}
|
|
1479
|
+
getGNO2GEDTreeName() {
|
|
1480
|
+
const treeName = get(this, "HEAD._TREE.value") || get(this.getGedcom(), "HEAD._TREE.value");
|
|
1481
|
+
if (treeName) {
|
|
1482
|
+
return treeName;
|
|
1483
|
+
}
|
|
1484
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1485
|
+
return fileName || "GNO2GED Export";
|
|
1486
|
+
}
|
|
1487
|
+
/**
|
|
1488
|
+
* Universal tree ID getter for unknown/unrecognized GEDCOM sources
|
|
1489
|
+
* Tries to extract an ID from various common locations
|
|
1490
|
+
*/
|
|
1491
|
+
getUniversalTreeId() {
|
|
1492
|
+
const sourceType = this.getSourceType();
|
|
1493
|
+
const prefix = sourceType ? sourceType.toLowerCase() : "tree";
|
|
1494
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1495
|
+
if (fileName) {
|
|
1496
|
+
const idMatch = fileName.match(/_(\d+)/);
|
|
1497
|
+
if (idMatch) {
|
|
1498
|
+
return `${prefix}_${idMatch[1]}`;
|
|
1438
1499
|
}
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
newList.item(key, value);
|
|
1442
|
-
});
|
|
1443
|
-
return newList;
|
|
1500
|
+
}
|
|
1501
|
+
return `${prefix}_${this._gedcom?.refcount || "unknown"}`;
|
|
1444
1502
|
}
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1503
|
+
/**
|
|
1504
|
+
* Universal tree name getter for unknown/unrecognized GEDCOM sources
|
|
1505
|
+
* Tries to extract a name from various common locations
|
|
1506
|
+
*/
|
|
1507
|
+
getUniversalTreeName() {
|
|
1508
|
+
const sourceType = this.getSourceType();
|
|
1509
|
+
const prefix = sourceType ? `${sourceType}-` : "";
|
|
1510
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1511
|
+
if (fileName) {
|
|
1512
|
+
const cleanName = fileName.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
1513
|
+
return `${prefix}${cleanName}`;
|
|
1452
1514
|
}
|
|
1453
|
-
this.
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1515
|
+
const sourName = this.getFromSourceHeads("SOUR.NAME.value") || get(this, "HEAD.SOUR.NAME.value") || get(this.getGedcom(), "HEAD.SOUR.NAME.value");
|
|
1516
|
+
if (sourName) {
|
|
1517
|
+
return `${prefix}${sourName}`;
|
|
1518
|
+
}
|
|
1519
|
+
const sourValue = this.getFromSourceHeads("SOUR.value") || get(this, "HEAD.SOUR.value") || get(this.getGedcom(), "HEAD.SOUR.value");
|
|
1520
|
+
if (sourValue) {
|
|
1521
|
+
return `${prefix}${sourValue}`;
|
|
1522
|
+
}
|
|
1523
|
+
return `${prefix}Unknown Tree`;
|
|
1524
|
+
}
|
|
1525
|
+
getTreeName() {
|
|
1526
|
+
if (this?.isAncestry()) {
|
|
1527
|
+
const name = this.getAncestryTreeName();
|
|
1528
|
+
if (name) return name;
|
|
1529
|
+
}
|
|
1530
|
+
if (this?.isMyHeritage()) {
|
|
1531
|
+
const name = this.getMyHeritageTreeName();
|
|
1532
|
+
if (name) return name;
|
|
1533
|
+
}
|
|
1534
|
+
if (this?.isFamilySearch()) {
|
|
1535
|
+
const name = this.getFamilySearchTreeName();
|
|
1536
|
+
if (name) return name;
|
|
1537
|
+
}
|
|
1538
|
+
if (this?.isGNO2GED()) {
|
|
1539
|
+
const name = this.getGNO2GEDTreeName();
|
|
1540
|
+
if (name) return name;
|
|
1541
|
+
}
|
|
1542
|
+
if (this?.isAhnenblatt()) {
|
|
1543
|
+
const name = this.getAhnenblattTreeName();
|
|
1544
|
+
if (name) return name;
|
|
1545
|
+
}
|
|
1546
|
+
if (this?.isGeni()) {
|
|
1547
|
+
const name = this.getGeniTreeName();
|
|
1548
|
+
if (name) return name;
|
|
1549
|
+
}
|
|
1550
|
+
if (this?.isGenoPro()) {
|
|
1551
|
+
const name = this.getGenoProTreeName();
|
|
1552
|
+
if (name) return name;
|
|
1553
|
+
}
|
|
1554
|
+
return this.getUniversalTreeName();
|
|
1555
|
+
}
|
|
1556
|
+
};
|
|
1557
|
+
var createProxy = (target) => {
|
|
1558
|
+
return new Proxy(target, {
|
|
1559
|
+
get(t, prop, receiver) {
|
|
1560
|
+
if (prop === "unwrapped") {
|
|
1561
|
+
return target;
|
|
1472
1562
|
}
|
|
1473
|
-
if (
|
|
1474
|
-
|
|
1563
|
+
if (prop in t) {
|
|
1564
|
+
return Reflect.get(t, prop, receiver);
|
|
1475
1565
|
}
|
|
1476
|
-
|
|
1477
|
-
const
|
|
1478
|
-
if (
|
|
1479
|
-
|
|
1480
|
-
groupped[newGroup.group].marker = newGroup.marker ?? newGroup.group;
|
|
1481
|
-
}
|
|
1482
|
-
groupped[newGroup.group]?.append(item);
|
|
1483
|
-
});
|
|
1484
|
-
});
|
|
1485
|
-
if (sort) {
|
|
1486
|
-
return Object.entries(groupped).toSorted(([ak, a], [bk, b]) => {
|
|
1487
|
-
if (typeof sort === "function") {
|
|
1488
|
-
return sort(a, ak, b, bk);
|
|
1489
|
-
}
|
|
1490
|
-
if (ak === "Unknown") {
|
|
1491
|
-
return 1;
|
|
1492
|
-
}
|
|
1493
|
-
if (bk === "Unknown") {
|
|
1494
|
-
return -1;
|
|
1495
|
-
}
|
|
1496
|
-
if (sort === "group") {
|
|
1497
|
-
return ak.localeCompare(bk);
|
|
1498
|
-
}
|
|
1499
|
-
return (b?.length ?? 0) - (a?.length ?? 0);
|
|
1500
|
-
}).reduce((acc, [key, value]) => {
|
|
1501
|
-
if (minOccurance > -1 && (value?.length ?? 0) < minOccurance) {
|
|
1502
|
-
const otherKey = lessOccuranceLabel;
|
|
1503
|
-
acc[otherKey] = acc[otherKey] && value ? acc[otherKey].merge(value) : value;
|
|
1504
|
-
} else {
|
|
1505
|
-
acc[key] = value;
|
|
1566
|
+
if (!isOnlyMainProp(prop)) {
|
|
1567
|
+
const ref = t.ref;
|
|
1568
|
+
if (ref && prop in ref) {
|
|
1569
|
+
return Reflect.get(ref, prop, receiver);
|
|
1506
1570
|
}
|
|
1507
|
-
|
|
1508
|
-
}, {});
|
|
1571
|
+
}
|
|
1509
1572
|
}
|
|
1510
|
-
|
|
1573
|
+
});
|
|
1574
|
+
};
|
|
1575
|
+
var createCommon = (gedcom, id, main, parent) => {
|
|
1576
|
+
return createProxy(
|
|
1577
|
+
new Common(gedcom, id, main, parent)
|
|
1578
|
+
);
|
|
1579
|
+
};
|
|
1580
|
+
var isOnlyMainProp = (key) => {
|
|
1581
|
+
return key === "_gedcom" || key === "_main" || key === "_parent" || key === "_uniqueId" || key === "_type" || key === "_refs" || key === "id" || key === "_id";
|
|
1582
|
+
};
|
|
1583
|
+
var isValidKey = (common, key) => {
|
|
1584
|
+
const prop = get(common, key);
|
|
1585
|
+
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);
|
|
1586
|
+
};
|
|
1587
|
+
var getValidKeys = (common) => {
|
|
1588
|
+
return Object.keys(common).filter((key) => {
|
|
1589
|
+
return isValidKey(common, key);
|
|
1590
|
+
});
|
|
1591
|
+
};
|
|
1592
|
+
var getValidTag = (tag) => {
|
|
1593
|
+
return tag.replace(/^@@/, "");
|
|
1594
|
+
};
|
|
1595
|
+
var getListTag = (tag) => {
|
|
1596
|
+
return `@@${tag}`;
|
|
1597
|
+
};
|
|
1598
|
+
var isId = (string) => {
|
|
1599
|
+
return ID_REG.test(string);
|
|
1600
|
+
};
|
|
1601
|
+
var idGetter = (id) => {
|
|
1602
|
+
if (id === void 0) {
|
|
1603
|
+
return void 0;
|
|
1604
|
+
}
|
|
1605
|
+
let newId = `${id}`;
|
|
1606
|
+
const parts = newId?.match(ID_GETTER_REG)?.groups;
|
|
1607
|
+
if (!parts?.at && !parts?.letter) {
|
|
1608
|
+
newId = `@U${newId}`;
|
|
1609
|
+
} else if (!parts.at) {
|
|
1610
|
+
newId = `@${newId}`;
|
|
1611
|
+
} else if (!parts.letter) {
|
|
1612
|
+
newId = newId.replace(/^@/, "@U");
|
|
1613
|
+
}
|
|
1614
|
+
if (!newId.endsWith("@")) {
|
|
1615
|
+
newId = `${newId}@`;
|
|
1616
|
+
}
|
|
1617
|
+
return newId;
|
|
1618
|
+
};
|
|
1619
|
+
|
|
1620
|
+
// src/utils/fact-edit.ts
|
|
1621
|
+
var SINGLETON_TAGS = /* @__PURE__ */ new Set(["BIRT", "DEAT", "SSN", "SEX", "DSCR"]);
|
|
1622
|
+
var firstRecord = (node) => {
|
|
1623
|
+
if (!node) {
|
|
1624
|
+
return void 0;
|
|
1625
|
+
}
|
|
1626
|
+
if (node instanceof List) {
|
|
1627
|
+
return node.index(0);
|
|
1628
|
+
}
|
|
1629
|
+
return node.index(0) ?? node;
|
|
1630
|
+
};
|
|
1631
|
+
var setDateOn = (gedcom, owner, parent, date) => {
|
|
1632
|
+
const trimmed = date.trim();
|
|
1633
|
+
if (!trimmed) {
|
|
1634
|
+
return;
|
|
1635
|
+
}
|
|
1636
|
+
let dateNode = parent.get("DATE");
|
|
1637
|
+
if (!dateNode || dateNode instanceof List) {
|
|
1638
|
+
dateNode = createCommonDate(gedcom, void 0, owner, parent);
|
|
1639
|
+
dateNode.type = "DATE";
|
|
1640
|
+
parent.set("DATE", dateNode);
|
|
1641
|
+
}
|
|
1642
|
+
dateNode.value = trimmed;
|
|
1643
|
+
};
|
|
1644
|
+
var fillFact = (gedcom, owner, event, input) => {
|
|
1645
|
+
if (input.value?.trim()) {
|
|
1646
|
+
event.value = input.value.trim();
|
|
1647
|
+
}
|
|
1648
|
+
if (input.type?.trim()) {
|
|
1649
|
+
event.set("TYPE", input.type.trim());
|
|
1650
|
+
}
|
|
1651
|
+
if (input.date) {
|
|
1652
|
+
setDateOn(gedcom, owner, event, input.date);
|
|
1653
|
+
}
|
|
1654
|
+
if (input.place?.trim()) {
|
|
1655
|
+
event.set("PLAC", input.place.trim());
|
|
1656
|
+
}
|
|
1657
|
+
if (input.note?.trim()) {
|
|
1658
|
+
event.set("NOTE", input.note.trim());
|
|
1659
|
+
}
|
|
1660
|
+
};
|
|
1661
|
+
var addIndividualFact = (indi, input) => {
|
|
1662
|
+
const gedcom = indi.getGedcom();
|
|
1663
|
+
if (!gedcom) {
|
|
1664
|
+
return void 0;
|
|
1665
|
+
}
|
|
1666
|
+
const tag = input.tag;
|
|
1667
|
+
let event = SINGLETON_TAGS.has(tag) ? firstRecord(indi.get(tag)) : void 0;
|
|
1668
|
+
if (!event) {
|
|
1669
|
+
event = createCommon(gedcom, void 0, indi);
|
|
1670
|
+
event.type = tag;
|
|
1671
|
+
if (SINGLETON_TAGS.has(tag)) {
|
|
1672
|
+
indi.set(tag, event);
|
|
1673
|
+
} else {
|
|
1674
|
+
indi.assign(tag, event);
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1677
|
+
fillFact(gedcom, indi, event, input);
|
|
1678
|
+
return event;
|
|
1679
|
+
};
|
|
1680
|
+
var addFamilyFact = (fam, input) => {
|
|
1681
|
+
const gedcom = fam.getGedcom();
|
|
1682
|
+
if (!gedcom) {
|
|
1683
|
+
return void 0;
|
|
1684
|
+
}
|
|
1685
|
+
const event = createCommon(gedcom, void 0, fam);
|
|
1686
|
+
event.type = input.tag;
|
|
1687
|
+
fam.assign(input.tag, event);
|
|
1688
|
+
fillFact(gedcom, fam, event, input);
|
|
1689
|
+
return event;
|
|
1690
|
+
};
|
|
1691
|
+
|
|
1692
|
+
// src/utils/family-edit.ts
|
|
1693
|
+
var PEDIGREE_VALUES = [
|
|
1694
|
+
"birth" /* BIRTH */,
|
|
1695
|
+
"adopted" /* ADOPTED */,
|
|
1696
|
+
"foster" /* FOSTER */,
|
|
1697
|
+
"step" /* STEP */,
|
|
1698
|
+
"sealing" /* SEALING */
|
|
1699
|
+
];
|
|
1700
|
+
var toGedcomPedigree = (value) => {
|
|
1701
|
+
const normalized = String(value || "birth" /* BIRTH */).toLowerCase();
|
|
1702
|
+
if (normalized === "biological" /* BIOLOGICAL */ || normalized === "birth" /* BIRTH */) {
|
|
1703
|
+
return "birth" /* BIRTH */;
|
|
1704
|
+
}
|
|
1705
|
+
const match = PEDIGREE_VALUES.find((item) => item === normalized);
|
|
1706
|
+
return match ?? "birth" /* BIRTH */;
|
|
1707
|
+
};
|
|
1708
|
+
var pointerIds = (tag) => {
|
|
1709
|
+
if (!tag) {
|
|
1710
|
+
return [];
|
|
1711
|
+
}
|
|
1712
|
+
if (tag instanceof List) {
|
|
1713
|
+
return tag.values().map((item) => item?.toValue?.()).filter((value2) => !!value2);
|
|
1714
|
+
}
|
|
1715
|
+
const value = tag.toValue?.();
|
|
1716
|
+
return value ? [String(value)] : [];
|
|
1717
|
+
};
|
|
1718
|
+
var firstPointerId = (tag) => pointerIds(tag)[0];
|
|
1719
|
+
var makePointer = (gedcom, parent, value, refType) => {
|
|
1720
|
+
const pointer = createCommon(gedcom, void 0, parent);
|
|
1721
|
+
pointer.value = value;
|
|
1722
|
+
pointer.refType = refType;
|
|
1723
|
+
return pointer;
|
|
1724
|
+
};
|
|
1725
|
+
var familyHasParent = (fam, indiId) => pointerIds(fam.get("HUSB")).includes(indiId) || pointerIds(fam.get("WIFE")).includes(indiId);
|
|
1726
|
+
var familyHasChild = (fam, indiId) => pointerIds(fam.get("CHIL")).includes(indiId);
|
|
1727
|
+
var spouseTagFor = (indi, fam) => {
|
|
1728
|
+
const husbId = firstPointerId(fam.get("HUSB"));
|
|
1729
|
+
const wifeId = firstPointerId(fam.get("WIFE"));
|
|
1730
|
+
if (husbId === indi.id) {
|
|
1731
|
+
return "HUSB";
|
|
1732
|
+
}
|
|
1733
|
+
if (wifeId === indi.id) {
|
|
1734
|
+
return "WIFE";
|
|
1735
|
+
}
|
|
1736
|
+
if (indi.isFemale()) {
|
|
1737
|
+
return wifeId && wifeId !== indi.id ? "HUSB" : "WIFE";
|
|
1738
|
+
}
|
|
1739
|
+
if (indi.isMale()) {
|
|
1740
|
+
return husbId && husbId !== indi.id ? "WIFE" : "HUSB";
|
|
1741
|
+
}
|
|
1742
|
+
return husbId ? "WIFE" : "HUSB";
|
|
1743
|
+
};
|
|
1744
|
+
var canAttachAsSpouse = (fam, indi) => {
|
|
1745
|
+
if (!indi.id) {
|
|
1746
|
+
return false;
|
|
1747
|
+
}
|
|
1748
|
+
if (familyHasParent(fam, indi.id)) {
|
|
1749
|
+
return true;
|
|
1750
|
+
}
|
|
1751
|
+
const tag = spouseTagFor(indi, fam);
|
|
1752
|
+
const occupied = firstPointerId(fam.get(tag));
|
|
1753
|
+
return !occupied || occupied === indi.id;
|
|
1754
|
+
};
|
|
1755
|
+
var pointerByValue = (tag, id) => {
|
|
1756
|
+
if (!tag) {
|
|
1757
|
+
return void 0;
|
|
1758
|
+
}
|
|
1759
|
+
const fromValues = tag.toValueList?.().item(id);
|
|
1760
|
+
if (fromValues) {
|
|
1761
|
+
return fromValues;
|
|
1762
|
+
}
|
|
1763
|
+
return tag.toList()?.values().find((item) => item?.toValue?.() === id);
|
|
1764
|
+
};
|
|
1765
|
+
var setChildPedigree = (fam, child, pedigree, parent) => {
|
|
1766
|
+
if (!fam.id || !child.id) {
|
|
1767
|
+
return;
|
|
1768
|
+
}
|
|
1769
|
+
const pedi = toGedcomPedigree(pedigree);
|
|
1770
|
+
const famc = pointerByValue(child.get("FAMC"), fam.id);
|
|
1771
|
+
if (famc) {
|
|
1772
|
+
famc.set("PEDI", pedi);
|
|
1773
|
+
}
|
|
1774
|
+
const chil = pointerByValue(fam.get("CHIL"), child.id);
|
|
1775
|
+
if (!chil) {
|
|
1776
|
+
return;
|
|
1777
|
+
}
|
|
1778
|
+
const setFather = !parent || parent.isMale() || parent.isUnknownSex();
|
|
1779
|
+
const setMother = !parent || parent.isFemale() || parent.isUnknownSex();
|
|
1780
|
+
if (setFather) {
|
|
1781
|
+
chil.set("_FREL", pedi);
|
|
1782
|
+
}
|
|
1783
|
+
if (setMother) {
|
|
1784
|
+
chil.set("_MREL", pedi);
|
|
1511
1785
|
}
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
return
|
|
1786
|
+
};
|
|
1787
|
+
var attachSpouseToFamily = (fam, indi) => {
|
|
1788
|
+
const gedcom = fam.getGedcom() ?? indi.getGedcom();
|
|
1789
|
+
if (!indi.id || !fam.id || !gedcom) {
|
|
1790
|
+
return false;
|
|
1517
1791
|
}
|
|
1518
|
-
|
|
1519
|
-
return
|
|
1792
|
+
if (!canAttachAsSpouse(fam, indi)) {
|
|
1793
|
+
return false;
|
|
1520
1794
|
}
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1795
|
+
const tag = spouseTagFor(indi, fam);
|
|
1796
|
+
if (firstPointerId(fam.get(tag)) !== indi.id) {
|
|
1797
|
+
fam.set(tag, makePointer(gedcom, fam, indi.id, "INDI"));
|
|
1524
1798
|
}
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
}
|
|
1533
|
-
json[validTag].push(
|
|
1534
|
-
item.toObject(validTag, options)
|
|
1535
|
-
);
|
|
1536
|
-
} else {
|
|
1537
|
-
json[validTag] = item.toObject(
|
|
1538
|
-
validTag,
|
|
1539
|
-
options
|
|
1540
|
-
);
|
|
1541
|
-
}
|
|
1542
|
-
});
|
|
1543
|
-
return json;
|
|
1799
|
+
indi.assign("FAMS", makePointer(gedcom, indi, fam.id, "FAM"), true);
|
|
1800
|
+
return true;
|
|
1801
|
+
};
|
|
1802
|
+
var attachChildToFamily = (fam, child, pedigree, parent) => {
|
|
1803
|
+
const gedcom = fam.getGedcom() ?? child.getGedcom();
|
|
1804
|
+
if (!child.id || !fam.id || !gedcom) {
|
|
1805
|
+
return false;
|
|
1544
1806
|
}
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
return gedcom.join("\n");
|
|
1807
|
+
if (!familyHasChild(fam, child.id)) {
|
|
1808
|
+
fam.assign("CHIL", makePointer(gedcom, fam, child.id, "INDI"), true);
|
|
1548
1809
|
}
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
const validTag = getValidTag(tag);
|
|
1553
|
-
const validKey = item.id;
|
|
1554
|
-
const validValue = validKey ? validTag : item.exportValue();
|
|
1555
|
-
gedcom.push(
|
|
1556
|
-
`${level} ${validKey || validTag}${validValue ? ` ${validValue}` : ""}`
|
|
1557
|
-
);
|
|
1558
|
-
gedcom.push(
|
|
1559
|
-
...item.toGedcomLines(
|
|
1560
|
-
validTag,
|
|
1561
|
-
level + 1,
|
|
1562
|
-
options
|
|
1563
|
-
)
|
|
1564
|
-
);
|
|
1565
|
-
});
|
|
1566
|
-
return gedcom;
|
|
1810
|
+
const existingFamc = pointerByValue(child.get("FAMC"), fam.id);
|
|
1811
|
+
if (!existingFamc) {
|
|
1812
|
+
child.assign("FAMC", makePointer(gedcom, child, fam.id, "FAM"), true);
|
|
1567
1813
|
}
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
return
|
|
1814
|
+
setChildPedigree(fam, child, pedigree, parent);
|
|
1815
|
+
return true;
|
|
1816
|
+
};
|
|
1817
|
+
var findReusableParentChildFamily = (parent, child) => {
|
|
1818
|
+
if (!parent.id || !child.id) {
|
|
1819
|
+
return void 0;
|
|
1574
1820
|
}
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1821
|
+
let reusableFamc;
|
|
1822
|
+
let already = false;
|
|
1823
|
+
child.getFamilies("FAMC")?.forEach((fam) => {
|
|
1824
|
+
if (!fam) {
|
|
1825
|
+
return;
|
|
1826
|
+
}
|
|
1827
|
+
if (familyHasParent(fam, parent.id) && familyHasChild(fam, child.id)) {
|
|
1828
|
+
already = true;
|
|
1829
|
+
return;
|
|
1830
|
+
}
|
|
1831
|
+
if (!reusableFamc && canAttachAsSpouse(fam, parent)) {
|
|
1832
|
+
reusableFamc = fam;
|
|
1833
|
+
}
|
|
1834
|
+
});
|
|
1835
|
+
if (already) {
|
|
1836
|
+
return "already";
|
|
1578
1837
|
}
|
|
1579
|
-
|
|
1580
|
-
return
|
|
1838
|
+
if (reusableFamc) {
|
|
1839
|
+
return reusableFamc;
|
|
1581
1840
|
}
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
}
|
|
1587
|
-
|
|
1841
|
+
const parentFams = [];
|
|
1842
|
+
parent.getFamilies("FAMS")?.forEach((fam) => {
|
|
1843
|
+
if (fam) {
|
|
1844
|
+
parentFams.push(fam);
|
|
1845
|
+
}
|
|
1846
|
+
});
|
|
1847
|
+
if (parentFams.length === 1) {
|
|
1848
|
+
return parentFams[0];
|
|
1588
1849
|
}
|
|
1850
|
+
return void 0;
|
|
1851
|
+
};
|
|
1852
|
+
|
|
1853
|
+
// src/utils/get-family-with.ts
|
|
1854
|
+
var getFamilyWith = (person1, person2, famType = "FAMS") => {
|
|
1855
|
+
return person1?.get(famType)?.toValueList().find((fam) => {
|
|
1856
|
+
const family = fam;
|
|
1857
|
+
return famType === "FAMC" || family?.HUSB?.value === person2 || family?.WIFE?.value === person2;
|
|
1858
|
+
});
|
|
1589
1859
|
};
|
|
1590
1860
|
|
|
1591
1861
|
// src/utils/get-places.ts
|
|
@@ -2218,6 +2488,31 @@ var Fam = class extends Common {
|
|
|
2218
2488
|
getParents() {
|
|
2219
2489
|
return this.getHusband().copy().merge(this.getWife());
|
|
2220
2490
|
}
|
|
2491
|
+
hasParent(indi) {
|
|
2492
|
+
const indiId = typeof indi === "string" ? indi : indi?.id;
|
|
2493
|
+
return !!indiId && familyHasParent(this, indiId);
|
|
2494
|
+
}
|
|
2495
|
+
hasChild(indi) {
|
|
2496
|
+
const indiId = typeof indi === "string" ? indi : indi?.id;
|
|
2497
|
+
return !!indiId && familyHasChild(this, indiId);
|
|
2498
|
+
}
|
|
2499
|
+
canAddSpouse(indi) {
|
|
2500
|
+
return canAttachAsSpouse(this, indi);
|
|
2501
|
+
}
|
|
2502
|
+
addSpouse(indi) {
|
|
2503
|
+
return attachSpouseToFamily(this, indi);
|
|
2504
|
+
}
|
|
2505
|
+
addChild(child, pedigree, parent) {
|
|
2506
|
+
return attachChildToFamily(
|
|
2507
|
+
this,
|
|
2508
|
+
child,
|
|
2509
|
+
pedigree,
|
|
2510
|
+
parent
|
|
2511
|
+
);
|
|
2512
|
+
}
|
|
2513
|
+
addFact(input) {
|
|
2514
|
+
return addFamilyFact(this, input);
|
|
2515
|
+
}
|
|
2221
2516
|
toList() {
|
|
2222
2517
|
return new Families().concat(
|
|
2223
2518
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -2318,19 +2613,51 @@ var ALLOWED_FACTS = [
|
|
|
2318
2613
|
"OCCU",
|
|
2319
2614
|
"OCCUPATIONS",
|
|
2320
2615
|
"RESI",
|
|
2616
|
+
"BIRT",
|
|
2617
|
+
"DEAT",
|
|
2321
2618
|
"BAPT",
|
|
2619
|
+
"BAPM",
|
|
2322
2620
|
"CHRI",
|
|
2323
2621
|
"CHR",
|
|
2622
|
+
"CHRA",
|
|
2324
2623
|
"BURI",
|
|
2325
|
-
"
|
|
2624
|
+
"CREM",
|
|
2625
|
+
"ADOP",
|
|
2626
|
+
"BARM",
|
|
2627
|
+
"BASM",
|
|
2628
|
+
"BLES",
|
|
2629
|
+
"CONF",
|
|
2630
|
+
"FCOM",
|
|
2631
|
+
"ORDN",
|
|
2632
|
+
"NATU",
|
|
2633
|
+
"EMIG",
|
|
2634
|
+
"IMMI",
|
|
2635
|
+
"CENS",
|
|
2636
|
+
"PROB",
|
|
2637
|
+
"WILL",
|
|
2326
2638
|
"GRAD",
|
|
2639
|
+
"RETI",
|
|
2640
|
+
"EDUC",
|
|
2327
2641
|
"DIV",
|
|
2328
|
-
"IMMI",
|
|
2329
2642
|
"RELI",
|
|
2643
|
+
"CAST",
|
|
2644
|
+
"DSCR",
|
|
2645
|
+
"NATI",
|
|
2646
|
+
"PROP",
|
|
2647
|
+
"SSN",
|
|
2648
|
+
"TITL",
|
|
2649
|
+
"ADDR",
|
|
2650
|
+
"BAPL",
|
|
2651
|
+
"CONL",
|
|
2652
|
+
"ENDL",
|
|
2653
|
+
"SLGC",
|
|
2330
2654
|
"_MILT",
|
|
2331
2655
|
"_MILTID",
|
|
2332
2656
|
"FACT",
|
|
2333
|
-
"_ORIG"
|
|
2657
|
+
"_ORIG",
|
|
2658
|
+
"_WLNK",
|
|
2659
|
+
"WWW",
|
|
2660
|
+
"URL"
|
|
2334
2661
|
];
|
|
2335
2662
|
var DISALLOWED_CUSTOM_FACTS = ["DNA Test", "Newspaper"];
|
|
2336
2663
|
var CustomFactRenderers = {
|
|
@@ -2874,7 +3201,7 @@ var Indi = class extends Common {
|
|
|
2874
3201
|
return result;
|
|
2875
3202
|
}
|
|
2876
3203
|
ancestryLink() {
|
|
2877
|
-
const www = this._gedcom?.HEAD?.SOUR?.CORP?.WWW?.value;
|
|
3204
|
+
const www = this.getFromSourceHeads("SOUR.CORP.WWW.value") || this._gedcom?.HEAD?.SOUR?.CORP?.WWW?.value;
|
|
2878
3205
|
const tree = this.getAncestryTreeId();
|
|
2879
3206
|
if (this.id) {
|
|
2880
3207
|
return `https://${www}/family-tree/person/tree/${tree}/person/${this.id.replace(
|
|
@@ -2886,7 +3213,7 @@ var Indi = class extends Common {
|
|
|
2886
3213
|
async ancestryMedia(namespace) {
|
|
2887
3214
|
const list = {};
|
|
2888
3215
|
const objeList = this.get("OBJE")?.toList().copy();
|
|
2889
|
-
const www = this._gedcom?.HEAD?.SOUR?.CORP?.WWW?.value;
|
|
3216
|
+
const www = this.getFromSourceHeads("SOUR.CORP.WWW.value") || this._gedcom?.HEAD?.SOUR?.CORP?.WWW?.value;
|
|
2890
3217
|
const tree = this.getAncestryTreeId();
|
|
2891
3218
|
if (objeList) {
|
|
2892
3219
|
await Promise.all(
|
|
@@ -2946,7 +3273,7 @@ var Indi = class extends Common {
|
|
|
2946
3273
|
return list;
|
|
2947
3274
|
}
|
|
2948
3275
|
myheritageLink(poolId = 0) {
|
|
2949
|
-
const www = this._gedcom?.HEAD?.SOUR?.CORP?.value?.toLowerCase().replace(/^www\./gi, "");
|
|
3276
|
+
const www = (this.getFromSourceHeads("SOUR.CORP.value") || this._gedcom?.HEAD?.SOUR?.CORP?.value)?.toLowerCase().replace(/^www\./gi, "");
|
|
2950
3277
|
const site = this.getMyHeritageTreeId();
|
|
2951
3278
|
const file = this._gedcom?.HEAD?.get("FILE")?.toValue()?.match(/Exported by MyHeritage.com from .+ in (?<site>.+) on .+$/)?.groups?.site;
|
|
2952
3279
|
const normalizedFile = file?.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-");
|
|
@@ -3467,6 +3794,57 @@ var Indi = class extends Common {
|
|
|
3467
3794
|
isUnknownSex() {
|
|
3468
3795
|
return !this.isMale() && !this.isFemale();
|
|
3469
3796
|
}
|
|
3797
|
+
addSpouse(other) {
|
|
3798
|
+
if (!this.id || !other?.id || this.id === other.id || !this._gedcom) {
|
|
3799
|
+
return void 0;
|
|
3800
|
+
}
|
|
3801
|
+
const existing = getFamilyWith(this, other.id);
|
|
3802
|
+
if (existing) {
|
|
3803
|
+
return existing;
|
|
3804
|
+
}
|
|
3805
|
+
const fam = this._gedcom.createFamily();
|
|
3806
|
+
if (!fam.addSpouse(this) || !fam.addSpouse(other)) {
|
|
3807
|
+
return void 0;
|
|
3808
|
+
}
|
|
3809
|
+
return fam;
|
|
3810
|
+
}
|
|
3811
|
+
addChild(child, pedigree) {
|
|
3812
|
+
if (!this.id || !child?.id || this.id === child.id || !this._gedcom) {
|
|
3813
|
+
return void 0;
|
|
3814
|
+
}
|
|
3815
|
+
const existing = findReusableParentChildFamily(
|
|
3816
|
+
this,
|
|
3817
|
+
child
|
|
3818
|
+
);
|
|
3819
|
+
if (existing === "already") {
|
|
3820
|
+
const fam2 = child.getFamilies("FAMC")?.find(
|
|
3821
|
+
(item) => !!item && item.hasParent(this.id) && item.hasChild(child.id)
|
|
3822
|
+
);
|
|
3823
|
+
if (fam2) {
|
|
3824
|
+
setChildPedigree(
|
|
3825
|
+
fam2,
|
|
3826
|
+
child,
|
|
3827
|
+
pedigree,
|
|
3828
|
+
this
|
|
3829
|
+
);
|
|
3830
|
+
}
|
|
3831
|
+
return fam2;
|
|
3832
|
+
}
|
|
3833
|
+
const fam = existing ?? this._gedcom.createFamily();
|
|
3834
|
+
if (!fam.addSpouse(this)) {
|
|
3835
|
+
return void 0;
|
|
3836
|
+
}
|
|
3837
|
+
if (!fam.addChild(child, pedigree, this)) {
|
|
3838
|
+
return void 0;
|
|
3839
|
+
}
|
|
3840
|
+
return fam;
|
|
3841
|
+
}
|
|
3842
|
+
addParent(parent, pedigree) {
|
|
3843
|
+
return parent.addChild(this, pedigree);
|
|
3844
|
+
}
|
|
3845
|
+
addFact(input) {
|
|
3846
|
+
return addIndividualFact(this, input);
|
|
3847
|
+
}
|
|
3470
3848
|
getParentType(id) {
|
|
3471
3849
|
let indi;
|
|
3472
3850
|
if (typeof id === "string" || typeof id === "number") {
|
|
@@ -3667,7 +4045,9 @@ var Indi = class extends Common {
|
|
|
3667
4045
|
}
|
|
3668
4046
|
}
|
|
3669
4047
|
if (kinship !== "child" || !breakAfterSpouse) {
|
|
3670
|
-
indi.getBiologicalFathers().copy().merge(indi.getBiologicalMothers()).merge(
|
|
4048
|
+
indi.getBiologicalFathers().copy().merge(indi.getBiologicalMothers()).merge(
|
|
4049
|
+
indi.getFathers().copy().merge(indi.getMothers())
|
|
4050
|
+
).forEach((relative) => {
|
|
3671
4051
|
if (!visited.has(relative)) {
|
|
3672
4052
|
const currentRelation = indi.getParentType(relative);
|
|
3673
4053
|
const isNonBiological = !!currentRelation && currentRelation !== "biological" /* BIOLOGICAL */;
|
|
@@ -5962,6 +6342,249 @@ var KinshipTranslatorEs = class extends KinshipTranslatorBasic {
|
|
|
5962
6342
|
}
|
|
5963
6343
|
};
|
|
5964
6344
|
|
|
6345
|
+
// src/kinship-translator/patterns.ru.ts
|
|
6346
|
+
var InLawsRu = {
|
|
6347
|
+
"\u0441\u0443\u043F\u0440\u0443\u0433(?:\u0430)? (\u0440\u0435\u0431\u0451\u043D\u043A\u0430|\u0434\u043E\u0447\u0435\u0440\u0438|\u0441\u044B\u043D\u0430)": "\u0437\u044F\u0442\u044C/\u043D\u0435\u0432\u0435\u0441\u0442\u043A\u0430",
|
|
6348
|
+
"\u0436\u0435\u043D\u0430 (\u0440\u0435\u0431\u0451\u043D\u043A\u0430|\u0434\u043E\u0447\u0435\u0440\u0438|\u0441\u044B\u043D\u0430)": "\u043D\u0435\u0432\u0435\u0441\u0442\u043A\u0430",
|
|
6349
|
+
"\u043C\u0443\u0436 (\u0440\u0435\u0431\u0451\u043D\u043A\u0430|\u0434\u043E\u0447\u0435\u0440\u0438|\u0441\u044B\u043D\u0430)": "\u0437\u044F\u0442\u044C",
|
|
6350
|
+
"\u043C\u0430\u0442\u044C (\u0441\u0443\u043F\u0440\u0443\u0433\u0430|\u0436\u0435\u043D\u044B|\u043C\u0443\u0436\u0430)": "\u0442\u0451\u0449\u0430",
|
|
6351
|
+
"\u043E\u0442\u0435\u0446 (\u0441\u0443\u043F\u0440\u0443\u0433\u0430|\u0436\u0435\u043D\u044B|\u043C\u0443\u0436\u0430)": "\u0442\u0435\u0441\u0442\u044C",
|
|
6352
|
+
"\u0440\u043E\u0434\u0438\u0442\u0435\u043B\u044C (\u0441\u0443\u043F\u0440\u0443\u0433\u0430|\u0436\u0435\u043D\u044B|\u043C\u0443\u0436\u0430)": "\u0442\u0435\u0441\u0442\u044C/\u0442\u0451\u0449\u0430",
|
|
6353
|
+
"\u0436\u0435\u043D\u0430 (\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?(\u0431\u0440\u0430\u0442\u0430|\u0441\u0435\u0441\u0442\u0440\u044B|\u0441\u0438\u0431\u043B\u0438\u043D\u0433\u0430)": "\u043D\u0435\u0432\u0435\u0441\u0442\u043A\u0430",
|
|
6354
|
+
"\u043C\u0443\u0436 (\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?(\u0431\u0440\u0430\u0442\u0430|\u0441\u0435\u0441\u0442\u0440\u044B|\u0441\u0438\u0431\u043B\u0438\u043D\u0433\u0430)": "\u0437\u044F\u0442\u044C",
|
|
6355
|
+
"\u0441\u0443\u043F\u0440\u0443\u0433(?:\u0430)? (\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?(\u0431\u0440\u0430\u0442\u0430|\u0441\u0435\u0441\u0442\u0440\u044B|\u0441\u0438\u0431\u043B\u0438\u043D\u0433\u0430)": "\u0437\u044F\u0442\u044C/\u043D\u0435\u0432\u0435\u0441\u0442\u043A\u0430",
|
|
6356
|
+
"(\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?\u0441\u0435\u0441\u0442\u0440\u0430 (\u0441\u0443\u043F\u0440\u0443\u0433\u0430|\u0436\u0435\u043D\u044B|\u043C\u0443\u0436\u0430)": "\u0437\u043E\u043B\u043E\u0432\u043A\u0430",
|
|
6357
|
+
"(\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?\u0431\u0440\u0430\u0442 (\u0441\u0443\u043F\u0440\u0443\u0433\u0430|\u0436\u0435\u043D\u044B|\u043C\u0443\u0436\u0430)": "\u0448\u0443\u0440\u0438\u043D",
|
|
6358
|
+
"(\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?\u0441\u0438\u0431\u043B\u0438\u043D\u0433 (\u0441\u0443\u043F\u0440\u0443\u0433\u0430|\u0436\u0435\u043D\u044B|\u043C\u0443\u0436\u0430)": "\u0448\u0443\u0440\u0438\u043D/\u0437\u043E\u043B\u043E\u0432\u043A\u0430"
|
|
6359
|
+
};
|
|
6360
|
+
|
|
6361
|
+
// src/kinship-translator/kinship-translator.ru.ts
|
|
6362
|
+
var GENITIVE = {
|
|
6363
|
+
\u0441\u044B\u043D: "\u0441\u044B\u043D\u0430",
|
|
6364
|
+
\u0434\u043E\u0447\u044C: "\u0434\u043E\u0447\u0435\u0440\u0438",
|
|
6365
|
+
\u0440\u0435\u0431\u0451\u043D\u043E\u043A: "\u0440\u0435\u0431\u0451\u043D\u043A\u0430",
|
|
6366
|
+
\u0431\u0440\u0430\u0442: "\u0431\u0440\u0430\u0442\u0430",
|
|
6367
|
+
\u0441\u0435\u0441\u0442\u0440\u0430: "\u0441\u0435\u0441\u0442\u0440\u044B",
|
|
6368
|
+
\u0441\u0438\u0431\u043B\u0438\u043D\u0433: "\u0441\u0438\u0431\u043B\u0438\u043D\u0433\u0430",
|
|
6369
|
+
\u043E\u0442\u0435\u0446: "\u043E\u0442\u0446\u0430",
|
|
6370
|
+
\u043C\u0430\u0442\u044C: "\u043C\u0430\u0442\u0435\u0440\u0438",
|
|
6371
|
+
\u0440\u043E\u0434\u0438\u0442\u0435\u043B\u044C: "\u0440\u043E\u0434\u0438\u0442\u0435\u043B\u044F",
|
|
6372
|
+
\u043C\u0443\u0436: "\u043C\u0443\u0436\u0430",
|
|
6373
|
+
\u0436\u0435\u043D\u0430: "\u0436\u0435\u043D\u044B",
|
|
6374
|
+
\u0441\u0443\u043F\u0440\u0443\u0433: "\u0441\u0443\u043F\u0440\u0443\u0433\u0430",
|
|
6375
|
+
\u0441\u0443\u043F\u0440\u0443\u0433\u0430: "\u0441\u0443\u043F\u0440\u0443\u0433\u0438"
|
|
6376
|
+
};
|
|
6377
|
+
var toGenitive = (word) => GENITIVE[word] ?? word;
|
|
6378
|
+
var cousinWord = (degree, sex) => {
|
|
6379
|
+
const stem = degree <= 1 ? "\u0434\u0432\u043E\u044E\u0440\u043E\u0434\u043D" : degree === 2 ? "\u0442\u0440\u043E\u044E\u0440\u043E\u0434\u043D" : degree === 3 ? "\u0447\u0435\u0442\u0432\u0435\u0440\u043E\u044E\u0440\u043E\u0434\u043D" : `${degree + 1}-\u044E\u0440\u043E\u0434\u043D`;
|
|
6380
|
+
if (sex === "m") {
|
|
6381
|
+
return `${stem}\u044B\u0439 \u0431\u0440\u0430\u0442`;
|
|
6382
|
+
}
|
|
6383
|
+
if (sex === "f") {
|
|
6384
|
+
return `${stem}\u0430\u044F \u0441\u0435\u0441\u0442\u0440\u0430`;
|
|
6385
|
+
}
|
|
6386
|
+
return `${stem}\u044B\u0439 \u0431\u0440\u0430\u0442/\u0441\u0435\u0441\u0442\u0440\u0430`;
|
|
6387
|
+
};
|
|
6388
|
+
var praRepeat = (count) => count > 0 ? "\u043F\u0440\u0430".repeat(count) : "";
|
|
6389
|
+
var sexOf = (person) => {
|
|
6390
|
+
if (person?.isMale?.()) {
|
|
6391
|
+
return "m";
|
|
6392
|
+
}
|
|
6393
|
+
if (person?.isFemale?.()) {
|
|
6394
|
+
return "f";
|
|
6395
|
+
}
|
|
6396
|
+
return "n";
|
|
6397
|
+
};
|
|
6398
|
+
var KinshipTranslatorRu = class extends KinshipTranslatorBasic {
|
|
6399
|
+
indirect() {
|
|
6400
|
+
let degree = Math.abs(this.pathN?.degree ?? 0);
|
|
6401
|
+
if (degree > 0) {
|
|
6402
|
+
degree = degree - 1;
|
|
6403
|
+
}
|
|
6404
|
+
return cousinWord(degree, sexOf(this.personN));
|
|
6405
|
+
}
|
|
6406
|
+
removal() {
|
|
6407
|
+
const level = this.pathN?.level ?? 0;
|
|
6408
|
+
let degree = Math.abs(this.pathN?.degree ?? 0);
|
|
6409
|
+
if (degree > 0) {
|
|
6410
|
+
degree = degree - 1;
|
|
6411
|
+
}
|
|
6412
|
+
if (!degree) {
|
|
6413
|
+
return level < 0 ? this.nibling() : this.auncle();
|
|
6414
|
+
}
|
|
6415
|
+
const removed = Math.abs(level);
|
|
6416
|
+
return `${cousinWord(degree, sexOf(this.personN))} (${removed}\xD7 \u0447\u0435\u0440\u0435\u0437 \u043F\u043E\u043A\u043E\u043B\u0435\u043D\u0438\u0435)`;
|
|
6417
|
+
}
|
|
6418
|
+
auncle() {
|
|
6419
|
+
const level = Math.abs(this.pathN?.level ?? 0);
|
|
6420
|
+
const pra = praRepeat(Math.max(0, level - 2));
|
|
6421
|
+
const sex = sexOf(this.personN);
|
|
6422
|
+
if (sex === "m") {
|
|
6423
|
+
return `${pra}\u0434\u044F\u0434\u044F`;
|
|
6424
|
+
}
|
|
6425
|
+
if (sex === "f") {
|
|
6426
|
+
return `${pra}\u0442\u0451\u0442\u044F`;
|
|
6427
|
+
}
|
|
6428
|
+
return `${pra}\u0434\u044F\u0434\u044F/\u0442\u0451\u0442\u044F`;
|
|
6429
|
+
}
|
|
6430
|
+
nibling() {
|
|
6431
|
+
const level = Math.abs(this.pathN?.level ?? 0);
|
|
6432
|
+
const pra = praRepeat(Math.max(0, level - 2));
|
|
6433
|
+
const sex = sexOf(this.personN);
|
|
6434
|
+
if (sex === "m") {
|
|
6435
|
+
return `${pra}\u043F\u043B\u0435\u043C\u044F\u043D\u043D\u0438\u043A`;
|
|
6436
|
+
}
|
|
6437
|
+
if (sex === "f") {
|
|
6438
|
+
return `${pra}\u043F\u043B\u0435\u043C\u044F\u043D\u043D\u0438\u0446\u0430`;
|
|
6439
|
+
}
|
|
6440
|
+
return `${pra}\u043F\u043B\u0435\u043C\u044F\u043D\u043D\u0438\u043A/\u043F\u043B\u0435\u043C\u044F\u043D\u043D\u0438\u0446\u0430`;
|
|
6441
|
+
}
|
|
6442
|
+
parent() {
|
|
6443
|
+
const level = Math.abs(this.pathN?.level ?? 0);
|
|
6444
|
+
const sex = sexOf(this.personN);
|
|
6445
|
+
if (level <= 1) {
|
|
6446
|
+
if (sex === "m") {
|
|
6447
|
+
return "\u043E\u0442\u0435\u0446";
|
|
6448
|
+
}
|
|
6449
|
+
if (sex === "f") {
|
|
6450
|
+
return "\u043C\u0430\u0442\u044C";
|
|
6451
|
+
}
|
|
6452
|
+
return "\u0440\u043E\u0434\u0438\u0442\u0435\u043B\u044C";
|
|
6453
|
+
}
|
|
6454
|
+
if (level === 2) {
|
|
6455
|
+
if (sex === "m") {
|
|
6456
|
+
return "\u0434\u0435\u0434";
|
|
6457
|
+
}
|
|
6458
|
+
if (sex === "f") {
|
|
6459
|
+
return "\u0431\u0430\u0431\u0443\u0448\u043A\u0430";
|
|
6460
|
+
}
|
|
6461
|
+
return "\u0434\u0435\u0434/\u0431\u0430\u0431\u0443\u0448\u043A\u0430";
|
|
6462
|
+
}
|
|
6463
|
+
const pra = praRepeat(level - 2);
|
|
6464
|
+
if (sex === "m") {
|
|
6465
|
+
return `${pra}\u0434\u0435\u0434`;
|
|
6466
|
+
}
|
|
6467
|
+
if (sex === "f") {
|
|
6468
|
+
return `${pra}\u0431\u0430\u0431\u0443\u0448\u043A\u0430`;
|
|
6469
|
+
}
|
|
6470
|
+
return `${pra}\u0434\u0435\u0434/\u0431\u0430\u0431\u0443\u0448\u043A\u0430`;
|
|
6471
|
+
}
|
|
6472
|
+
child() {
|
|
6473
|
+
const level = Math.abs(this.pathN?.level ?? 0);
|
|
6474
|
+
const sex = sexOf(this.personN);
|
|
6475
|
+
if (level <= 1) {
|
|
6476
|
+
if (sex === "m") {
|
|
6477
|
+
return "\u0441\u044B\u043D";
|
|
6478
|
+
}
|
|
6479
|
+
if (sex === "f") {
|
|
6480
|
+
return "\u0434\u043E\u0447\u044C";
|
|
6481
|
+
}
|
|
6482
|
+
return "\u0440\u0435\u0431\u0451\u043D\u043E\u043A";
|
|
6483
|
+
}
|
|
6484
|
+
if (level === 2) {
|
|
6485
|
+
if (sex === "m") {
|
|
6486
|
+
return "\u0432\u043D\u0443\u043A";
|
|
6487
|
+
}
|
|
6488
|
+
if (sex === "f") {
|
|
6489
|
+
return "\u0432\u043D\u0443\u0447\u043A\u0430";
|
|
6490
|
+
}
|
|
6491
|
+
return "\u0432\u043D\u0443\u043A/\u0432\u043D\u0443\u0447\u043A\u0430";
|
|
6492
|
+
}
|
|
6493
|
+
const pra = praRepeat(level - 2);
|
|
6494
|
+
if (sex === "m") {
|
|
6495
|
+
return `${pra}\u0432\u043D\u0443\u043A`;
|
|
6496
|
+
}
|
|
6497
|
+
if (sex === "f") {
|
|
6498
|
+
return `${pra}\u0432\u043D\u0443\u0447\u043A\u0430`;
|
|
6499
|
+
}
|
|
6500
|
+
return `${pra}\u0432\u043D\u0443\u043A/\u0432\u043D\u0443\u0447\u043A\u0430`;
|
|
6501
|
+
}
|
|
6502
|
+
sibling() {
|
|
6503
|
+
const sex = sexOf(this.personN);
|
|
6504
|
+
if (sex === "m") {
|
|
6505
|
+
return "\u0431\u0440\u0430\u0442";
|
|
6506
|
+
}
|
|
6507
|
+
if (sex === "f") {
|
|
6508
|
+
return "\u0441\u0435\u0441\u0442\u0440\u0430";
|
|
6509
|
+
}
|
|
6510
|
+
return "\u0441\u0438\u0431\u043B\u0438\u043D\u0433";
|
|
6511
|
+
}
|
|
6512
|
+
halfBlood(relation) {
|
|
6513
|
+
if (!relation || !this.isHalfBlood) {
|
|
6514
|
+
return relation ?? "";
|
|
6515
|
+
}
|
|
6516
|
+
if (/сестра|дочь|мать|тётя|бабушка|жена|племянница|внучка/.test(
|
|
6517
|
+
relation
|
|
6518
|
+
)) {
|
|
6519
|
+
return `\u0441\u0432\u043E\u0434\u043D\u0430\u044F ${relation}`;
|
|
6520
|
+
}
|
|
6521
|
+
return `\u0441\u0432\u043E\u0434\u043D\u044B\u0439 ${relation}`;
|
|
6522
|
+
}
|
|
6523
|
+
spouse() {
|
|
6524
|
+
const sex = sexOf(this.personN);
|
|
6525
|
+
if (sex === "m") {
|
|
6526
|
+
return "\u043C\u0443\u0436";
|
|
6527
|
+
}
|
|
6528
|
+
if (sex === "f") {
|
|
6529
|
+
return "\u0436\u0435\u043D\u0430";
|
|
6530
|
+
}
|
|
6531
|
+
return "\u0441\u0443\u043F\u0440\u0443\u0433";
|
|
6532
|
+
}
|
|
6533
|
+
ofSpouse(relation) {
|
|
6534
|
+
if (!relation) {
|
|
6535
|
+
return "";
|
|
6536
|
+
}
|
|
6537
|
+
const spouse = this.path?.[1].indi;
|
|
6538
|
+
const sex = sexOf(spouse);
|
|
6539
|
+
const spouseType = sex === "m" ? "\u043C\u0443\u0436" : sex === "f" ? "\u0436\u0435\u043D\u0430" : "\u0441\u0443\u043F\u0440\u0443\u0433";
|
|
6540
|
+
return `${relation} ${toGenitive(spouseType)}`;
|
|
6541
|
+
}
|
|
6542
|
+
spouseOf(relation) {
|
|
6543
|
+
if (!relation) {
|
|
6544
|
+
return "";
|
|
6545
|
+
}
|
|
6546
|
+
const spouse = this.path?.[this.path.length - 1].indi;
|
|
6547
|
+
const sex = sexOf(spouse);
|
|
6548
|
+
const spouseType = sex === "m" ? "\u043C\u0443\u0436" : sex === "f" ? "\u0436\u0435\u043D\u0430" : "\u0441\u0443\u043F\u0440\u0443\u0433";
|
|
6549
|
+
return `${spouseType} ${toGenitive(relation)}`;
|
|
6550
|
+
}
|
|
6551
|
+
of(relation) {
|
|
6552
|
+
const formattedName = nameFormatter(this.path?.[0]?.indi, {
|
|
6553
|
+
nameOrder: "first-last"
|
|
6554
|
+
});
|
|
6555
|
+
let name = formattedName.inOrder.filter(Boolean).join(" ");
|
|
6556
|
+
if (this.displayName === "none") {
|
|
6557
|
+
name = "";
|
|
6558
|
+
} else if (this.displayName === "givenname") {
|
|
6559
|
+
name = formattedName.givenname;
|
|
6560
|
+
} else if (this.displayName === "surname") {
|
|
6561
|
+
name = `${formattedName.surname}`;
|
|
6562
|
+
}
|
|
6563
|
+
if (!name || !relation) {
|
|
6564
|
+
return relation ?? "";
|
|
6565
|
+
}
|
|
6566
|
+
return `${name}: ${relation}`;
|
|
6567
|
+
}
|
|
6568
|
+
inLaw(relation) {
|
|
6569
|
+
let inLawRelation = relation;
|
|
6570
|
+
Object.keys(InLawsRu).find((pattern) => {
|
|
6571
|
+
const regex = new RegExp(`^${pattern}$`);
|
|
6572
|
+
if (relation?.match(regex)) {
|
|
6573
|
+
inLawRelation = InLawsRu[pattern];
|
|
6574
|
+
return true;
|
|
6575
|
+
}
|
|
6576
|
+
return false;
|
|
6577
|
+
});
|
|
6578
|
+
return inLawRelation ?? "";
|
|
6579
|
+
}
|
|
6580
|
+
relationType(relation) {
|
|
6581
|
+
if (!relation || !this.pathN?.relation) {
|
|
6582
|
+
return relation ?? "";
|
|
6583
|
+
}
|
|
6584
|
+
return `${this.pathN.relation} ${relation}`;
|
|
6585
|
+
}
|
|
6586
|
+
};
|
|
6587
|
+
|
|
5965
6588
|
// src/kinship-translator/kinship-translator.ts
|
|
5966
6589
|
var KinshipTranslator = class {
|
|
5967
6590
|
constructor(person1, person2, lang = "en", entirePath, displayName = "givenname") {
|
|
@@ -6318,14 +6941,6 @@ var isCommonDate = (value) => {
|
|
|
6318
6941
|
return !!value && value !== null && typeof value === "object" && "_date" in value;
|
|
6319
6942
|
};
|
|
6320
6943
|
|
|
6321
|
-
// src/utils/get-family-with.ts
|
|
6322
|
-
var getFamilyWith = (person1, person2, famType = "FAMS") => {
|
|
6323
|
-
return person1?.get(famType)?.toValueList().find((fam) => {
|
|
6324
|
-
const family = fam;
|
|
6325
|
-
return famType === "FAMC" || family?.HUSB?.value === person2 || family?.WIFE?.value === person2;
|
|
6326
|
-
});
|
|
6327
|
-
};
|
|
6328
|
-
|
|
6329
6944
|
// src/constants/orders.ts
|
|
6330
6945
|
var DEFAULT = {};
|
|
6331
6946
|
var BIRTH_ASC = {
|
|
@@ -6565,4 +7180,4 @@ var getMarriageAscAndBirth = (person) => (itemA, keyA, itemB, keyB) => {
|
|
|
6565
7180
|
return getBirthAsc(itemA, keyA, itemB);
|
|
6566
7181
|
};
|
|
6567
7182
|
|
|
6568
|
-
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 };
|
|
7183
|
+
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 };
|