@treeviz/gedcom-parser 2.1.3 → 2.1.4
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/index.js +202 -6
- package/dist/classes/indi.d.ts +7 -2
- package/dist/classes/indi.d.ts.map +1 -1
- package/dist/cli/index.js +466 -268
- package/dist/constants/index.js +201 -5
- package/dist/factories/index.js +201 -5
- package/dist/index.js +809 -386
- package/dist/interfaces/indi.d.ts +8 -3
- package/dist/interfaces/indi.d.ts.map +1 -1
- package/dist/kinship-translator/index.js +201 -5
- package/dist/utils/family-edit.d.ts +81 -2
- package/dist/utils/family-edit.d.ts.map +1 -1
- package/dist/utils/index.js +428 -7
- package/package.json +1 -1
package/dist/constants/index.js
CHANGED
|
@@ -176,6 +176,10 @@ var storeCache = {
|
|
|
176
176
|
}
|
|
177
177
|
}, 100)
|
|
178
178
|
};
|
|
179
|
+
var resetRelativesCache = () => {
|
|
180
|
+
caches.relativesOnDegreeCache = {};
|
|
181
|
+
caches.relativesOnLevelCache = {};
|
|
182
|
+
};
|
|
179
183
|
var relativesCache = (cacheKey) => (gedcom, key, subKey, value) => {
|
|
180
184
|
const gedcomId = getGedcomId(gedcom);
|
|
181
185
|
const fullKey = `${gedcomId}:${key}`;
|
|
@@ -1720,6 +1724,28 @@ var addNonEvent = (owner, input) => {
|
|
|
1720
1724
|
};
|
|
1721
1725
|
|
|
1722
1726
|
// src/utils/family-edit.ts
|
|
1727
|
+
var refTypeForTag = (tag) => {
|
|
1728
|
+
if (tag === "FAMS" || tag === "FAMC") return "FAM";
|
|
1729
|
+
return "INDI";
|
|
1730
|
+
};
|
|
1731
|
+
var normalizeSinglePointer = (owner, tag) => {
|
|
1732
|
+
const node = owner.get(tag);
|
|
1733
|
+
if (!node) return;
|
|
1734
|
+
if (node instanceof List && node.length === 1) {
|
|
1735
|
+
const only = node.index(0);
|
|
1736
|
+
if (only) {
|
|
1737
|
+
owner.set(tag, only);
|
|
1738
|
+
return;
|
|
1739
|
+
}
|
|
1740
|
+
const raw = node.values()[0];
|
|
1741
|
+
if (typeof raw === "string") {
|
|
1742
|
+
const gedcom = owner.getGedcom?.();
|
|
1743
|
+
if (gedcom) {
|
|
1744
|
+
owner.set(tag, makePointer(gedcom, owner, raw, refTypeForTag(tag)));
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
};
|
|
1723
1749
|
var PEDIGREE_VALUES = [
|
|
1724
1750
|
"birth" /* BIRTH */,
|
|
1725
1751
|
"adopted" /* ADOPTED */,
|
|
@@ -1827,6 +1853,9 @@ var attachSpouseToFamily = (fam, indi) => {
|
|
|
1827
1853
|
fam.set(tag, makePointer(gedcom, fam, indi.id, "INDI"));
|
|
1828
1854
|
}
|
|
1829
1855
|
indi.assign("FAMS", makePointer(gedcom, indi, fam.id, "FAM"), true);
|
|
1856
|
+
normalizeSinglePointer(indi, "FAMS");
|
|
1857
|
+
normalizeSinglePointer(fam, spouseTagFor(indi, fam));
|
|
1858
|
+
resetRelativesCache();
|
|
1830
1859
|
return true;
|
|
1831
1860
|
};
|
|
1832
1861
|
var attachChildToFamily = (fam, child, pedigree, parent) => {
|
|
@@ -1842,14 +1871,122 @@ var attachChildToFamily = (fam, child, pedigree, parent) => {
|
|
|
1842
1871
|
child.assign("FAMC", makePointer(gedcom, child, fam.id, "FAM"), true);
|
|
1843
1872
|
}
|
|
1844
1873
|
setChildPedigree(fam, child, pedigree, parent);
|
|
1874
|
+
normalizeSinglePointer(child, "FAMC");
|
|
1875
|
+
normalizeSinglePointer(fam, "CHIL");
|
|
1876
|
+
resetRelativesCache();
|
|
1845
1877
|
return true;
|
|
1846
1878
|
};
|
|
1847
|
-
var
|
|
1879
|
+
var removePointerByValue = (owner, tag, targetId) => {
|
|
1880
|
+
const node = owner.get(tag);
|
|
1881
|
+
if (!node) {
|
|
1882
|
+
return false;
|
|
1883
|
+
}
|
|
1884
|
+
if (node instanceof List) {
|
|
1885
|
+
const keysToRemove = [];
|
|
1886
|
+
node.entries().forEach(([key, item]) => {
|
|
1887
|
+
if (item?.toValue?.() === targetId || item?.id === targetId || String(key) === targetId) {
|
|
1888
|
+
keysToRemove.push(key);
|
|
1889
|
+
}
|
|
1890
|
+
});
|
|
1891
|
+
keysToRemove.forEach((key) => {
|
|
1892
|
+
node.removeItem(key);
|
|
1893
|
+
});
|
|
1894
|
+
if (node.length === 0) {
|
|
1895
|
+
owner.remove(tag);
|
|
1896
|
+
}
|
|
1897
|
+
return keysToRemove.length > 0;
|
|
1898
|
+
}
|
|
1899
|
+
if (node.toValue?.() === targetId) {
|
|
1900
|
+
owner.remove(tag);
|
|
1901
|
+
return true;
|
|
1902
|
+
}
|
|
1903
|
+
const asList = node.toList?.();
|
|
1904
|
+
if (asList && asList.length > 0) {
|
|
1905
|
+
const keysToRemove = [];
|
|
1906
|
+
asList.entries().forEach(([key, item]) => {
|
|
1907
|
+
if (item?.toValue?.() === targetId || item?.id === targetId) {
|
|
1908
|
+
keysToRemove.push(key);
|
|
1909
|
+
}
|
|
1910
|
+
});
|
|
1911
|
+
if (keysToRemove.length === asList.length) {
|
|
1912
|
+
owner.remove(tag);
|
|
1913
|
+
return true;
|
|
1914
|
+
}
|
|
1915
|
+
if (keysToRemove.length > 0) {
|
|
1916
|
+
const remaining = asList.values().filter((item) => item?.toValue?.() !== targetId);
|
|
1917
|
+
if (remaining.length === 1 && remaining[0]) {
|
|
1918
|
+
owner.set(tag, remaining[0]);
|
|
1919
|
+
} else {
|
|
1920
|
+
owner.set(tag, new List(remaining));
|
|
1921
|
+
}
|
|
1922
|
+
return true;
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
return false;
|
|
1926
|
+
};
|
|
1927
|
+
var familyMemberCount = (fam) => {
|
|
1928
|
+
let count = 0;
|
|
1929
|
+
if (firstPointerId(fam.get("HUSB"))) {
|
|
1930
|
+
count += 1;
|
|
1931
|
+
}
|
|
1932
|
+
if (firstPointerId(fam.get("WIFE"))) {
|
|
1933
|
+
count += 1;
|
|
1934
|
+
}
|
|
1935
|
+
count += pointerIds(fam.get("CHIL")).length;
|
|
1936
|
+
return count;
|
|
1937
|
+
};
|
|
1938
|
+
var isDegenerateFamily = (fam) => familyMemberCount(fam) <= 1;
|
|
1939
|
+
var pruneEmptyFamilies = (gedcom) => {
|
|
1940
|
+
const emptyIds = [];
|
|
1941
|
+
gedcom.fams()?.forEach((fam, id) => {
|
|
1942
|
+
if (fam && isDegenerateFamily(fam) && id) {
|
|
1943
|
+
emptyIds.push(id);
|
|
1944
|
+
}
|
|
1945
|
+
});
|
|
1946
|
+
if (emptyIds.length === 0) {
|
|
1947
|
+
return [];
|
|
1948
|
+
}
|
|
1949
|
+
gedcom.indis()?.forEach((indi) => {
|
|
1950
|
+
if (!indi) {
|
|
1951
|
+
return;
|
|
1952
|
+
}
|
|
1953
|
+
emptyIds.forEach((famId) => {
|
|
1954
|
+
removePointerByValue(indi, "FAMS", famId);
|
|
1955
|
+
removePointerByValue(indi, "FAMC", famId);
|
|
1956
|
+
});
|
|
1957
|
+
});
|
|
1958
|
+
emptyIds.forEach((famId) => {
|
|
1959
|
+
gedcom.fams()?.removeItem(famId);
|
|
1960
|
+
});
|
|
1961
|
+
return emptyIds;
|
|
1962
|
+
};
|
|
1963
|
+
var findSharedSpouseFamily = (parent, coParentId) => {
|
|
1964
|
+
let found;
|
|
1965
|
+
parent.getFamilies("FAMS")?.forEach((fam) => {
|
|
1966
|
+
if (!found && fam && familyHasParent(fam, coParentId)) {
|
|
1967
|
+
found = fam;
|
|
1968
|
+
}
|
|
1969
|
+
});
|
|
1970
|
+
return found;
|
|
1971
|
+
};
|
|
1972
|
+
var findReusableParentChildFamily = (parent, child, options) => {
|
|
1848
1973
|
if (!parent.id || !child.id) {
|
|
1849
1974
|
return void 0;
|
|
1850
1975
|
}
|
|
1976
|
+
const reuseParentFamilies = options?.reuseParentFamilies !== false;
|
|
1977
|
+
const gedcom = parent.getGedcom() ?? child.getGedcom();
|
|
1851
1978
|
let reusableFamc;
|
|
1979
|
+
let coupleFam;
|
|
1852
1980
|
let already = false;
|
|
1981
|
+
const noteCoupleWith = (coParentId) => {
|
|
1982
|
+
if (!coParentId || coParentId === parent.id || coupleFam || !parent.id) {
|
|
1983
|
+
return;
|
|
1984
|
+
}
|
|
1985
|
+
const shared = findSharedSpouseFamily(parent, coParentId);
|
|
1986
|
+
if (shared) {
|
|
1987
|
+
coupleFam = shared;
|
|
1988
|
+
}
|
|
1989
|
+
};
|
|
1853
1990
|
child.getFamilies("FAMC")?.forEach((fam) => {
|
|
1854
1991
|
if (!fam) {
|
|
1855
1992
|
return;
|
|
@@ -1858,6 +1995,8 @@ var findReusableParentChildFamily = (parent, child) => {
|
|
|
1858
1995
|
already = true;
|
|
1859
1996
|
return;
|
|
1860
1997
|
}
|
|
1998
|
+
pointerIds(fam.get("HUSB")).forEach(noteCoupleWith);
|
|
1999
|
+
pointerIds(fam.get("WIFE")).forEach(noteCoupleWith);
|
|
1861
2000
|
if (!reusableFamc && canAttachAsSpouse(fam, parent)) {
|
|
1862
2001
|
reusableFamc = fam;
|
|
1863
2002
|
}
|
|
@@ -1865,9 +2004,21 @@ var findReusableParentChildFamily = (parent, child) => {
|
|
|
1865
2004
|
if (already) {
|
|
1866
2005
|
return "already";
|
|
1867
2006
|
}
|
|
2007
|
+
if (coupleFam) {
|
|
2008
|
+
return coupleFam;
|
|
2009
|
+
}
|
|
1868
2010
|
if (reusableFamc) {
|
|
1869
2011
|
return reusableFamc;
|
|
1870
2012
|
}
|
|
2013
|
+
if (options?.targetFamilyId && gedcom) {
|
|
2014
|
+
const target = gedcom.fam(options.targetFamilyId);
|
|
2015
|
+
if (target && (familyHasParent(target, parent.id) || canAttachAsSpouse(target, parent))) {
|
|
2016
|
+
return target;
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
if (!reuseParentFamilies) {
|
|
2020
|
+
return void 0;
|
|
2021
|
+
}
|
|
1871
2022
|
const parentFams = [];
|
|
1872
2023
|
parent.getFamilies("FAMS")?.forEach((fam) => {
|
|
1873
2024
|
if (fam) {
|
|
@@ -1879,6 +2030,41 @@ var findReusableParentChildFamily = (parent, child) => {
|
|
|
1879
2030
|
}
|
|
1880
2031
|
return void 0;
|
|
1881
2032
|
};
|
|
2033
|
+
var consolidateChildIntoFamily = (child, keep) => {
|
|
2034
|
+
if (!child.id || !keep.id) {
|
|
2035
|
+
return [];
|
|
2036
|
+
}
|
|
2037
|
+
const keepParentIds = /* @__PURE__ */ new Set([
|
|
2038
|
+
...pointerIds(keep.get("HUSB")),
|
|
2039
|
+
...pointerIds(keep.get("WIFE"))
|
|
2040
|
+
]);
|
|
2041
|
+
const removed = [];
|
|
2042
|
+
child.getFamilies("FAMC")?.forEach((fam) => {
|
|
2043
|
+
if (!fam?.id || fam.id === keep.id) {
|
|
2044
|
+
return;
|
|
2045
|
+
}
|
|
2046
|
+
const famParentIds = [
|
|
2047
|
+
...pointerIds(fam.get("HUSB")),
|
|
2048
|
+
...pointerIds(fam.get("WIFE"))
|
|
2049
|
+
];
|
|
2050
|
+
if (famParentIds.length === 0 || !famParentIds.every((id) => keepParentIds.has(id))) {
|
|
2051
|
+
return;
|
|
2052
|
+
}
|
|
2053
|
+
removePointerByValue(fam, "CHIL", child.id);
|
|
2054
|
+
normalizeSinglePointer(fam, "CHIL");
|
|
2055
|
+
removePointerByValue(child, "FAMC", fam.id);
|
|
2056
|
+
normalizeSinglePointer(child, "FAMC");
|
|
2057
|
+
removed.push(fam.id);
|
|
2058
|
+
});
|
|
2059
|
+
const gedcom = child.getGedcom() ?? keep.getGedcom();
|
|
2060
|
+
if (gedcom && removed.length > 0) {
|
|
2061
|
+
pruneEmptyFamilies(gedcom);
|
|
2062
|
+
}
|
|
2063
|
+
if (removed.length > 0) {
|
|
2064
|
+
resetRelativesCache();
|
|
2065
|
+
}
|
|
2066
|
+
return removed;
|
|
2067
|
+
};
|
|
1882
2068
|
|
|
1883
2069
|
// src/utils/get-family-with.ts
|
|
1884
2070
|
var getFamilyWith = (person1, person2, famType = "FAMS") => {
|
|
@@ -3910,13 +4096,17 @@ var Indi = class extends Common {
|
|
|
3910
4096
|
}
|
|
3911
4097
|
return fam;
|
|
3912
4098
|
}
|
|
3913
|
-
addChild(child, pedigree) {
|
|
4099
|
+
addChild(child, pedigree, options) {
|
|
3914
4100
|
if (!this.id || !child?.id || this.id === child.id || !this._gedcom) {
|
|
3915
4101
|
return void 0;
|
|
3916
4102
|
}
|
|
3917
4103
|
const existing = findReusableParentChildFamily(
|
|
3918
4104
|
this,
|
|
3919
|
-
child
|
|
4105
|
+
child,
|
|
4106
|
+
{
|
|
4107
|
+
reuseParentFamilies: options?.reuseParentFamilies,
|
|
4108
|
+
targetFamilyId: options?.targetFamilyId
|
|
4109
|
+
}
|
|
3920
4110
|
);
|
|
3921
4111
|
if (existing === "already") {
|
|
3922
4112
|
const fam2 = child.getFamilies("FAMC")?.find(
|
|
@@ -3939,10 +4129,16 @@ var Indi = class extends Common {
|
|
|
3939
4129
|
if (!fam.addChild(child, pedigree, this)) {
|
|
3940
4130
|
return void 0;
|
|
3941
4131
|
}
|
|
4132
|
+
if (existing) {
|
|
4133
|
+
consolidateChildIntoFamily(child, fam);
|
|
4134
|
+
}
|
|
3942
4135
|
return fam;
|
|
3943
4136
|
}
|
|
3944
|
-
addParent(parent, pedigree) {
|
|
3945
|
-
return parent.addChild(this, pedigree
|
|
4137
|
+
addParent(parent, pedigree, options) {
|
|
4138
|
+
return parent.addChild(this, pedigree, {
|
|
4139
|
+
reuseParentFamilies: false,
|
|
4140
|
+
targetFamilyId: options?.targetFamilyId
|
|
4141
|
+
});
|
|
3946
4142
|
}
|
|
3947
4143
|
/**
|
|
3948
4144
|
* Link an existing top-level OBJE record to this individual (`1 OBJE @On@`).
|
package/dist/factories/index.js
CHANGED
|
@@ -1932,6 +1932,10 @@ var storeCache = {
|
|
|
1932
1932
|
}
|
|
1933
1933
|
}, 100)
|
|
1934
1934
|
};
|
|
1935
|
+
var resetRelativesCache = () => {
|
|
1936
|
+
caches.relativesOnDegreeCache = {};
|
|
1937
|
+
caches.relativesOnLevelCache = {};
|
|
1938
|
+
};
|
|
1935
1939
|
var relativesCache = (cacheKey) => (gedcom, key, subKey, value) => {
|
|
1936
1940
|
const gedcomId = getGedcomId(gedcom);
|
|
1937
1941
|
const fullKey = `${gedcomId}:${key}`;
|
|
@@ -2197,6 +2201,28 @@ var addNonEvent = (owner, input) => {
|
|
|
2197
2201
|
};
|
|
2198
2202
|
|
|
2199
2203
|
// src/utils/family-edit.ts
|
|
2204
|
+
var refTypeForTag = (tag) => {
|
|
2205
|
+
if (tag === "FAMS" || tag === "FAMC") return "FAM";
|
|
2206
|
+
return "INDI";
|
|
2207
|
+
};
|
|
2208
|
+
var normalizeSinglePointer = (owner, tag) => {
|
|
2209
|
+
const node = owner.get(tag);
|
|
2210
|
+
if (!node) return;
|
|
2211
|
+
if (node instanceof List && node.length === 1) {
|
|
2212
|
+
const only = node.index(0);
|
|
2213
|
+
if (only) {
|
|
2214
|
+
owner.set(tag, only);
|
|
2215
|
+
return;
|
|
2216
|
+
}
|
|
2217
|
+
const raw = node.values()[0];
|
|
2218
|
+
if (typeof raw === "string") {
|
|
2219
|
+
const gedcom = owner.getGedcom?.();
|
|
2220
|
+
if (gedcom) {
|
|
2221
|
+
owner.set(tag, makePointer(gedcom, owner, raw, refTypeForTag(tag)));
|
|
2222
|
+
}
|
|
2223
|
+
}
|
|
2224
|
+
}
|
|
2225
|
+
};
|
|
2200
2226
|
var PEDIGREE_VALUES = [
|
|
2201
2227
|
"birth" /* BIRTH */,
|
|
2202
2228
|
"adopted" /* ADOPTED */,
|
|
@@ -2304,6 +2330,9 @@ var attachSpouseToFamily = (fam, indi) => {
|
|
|
2304
2330
|
fam.set(tag, makePointer(gedcom, fam, indi.id, "INDI"));
|
|
2305
2331
|
}
|
|
2306
2332
|
indi.assign("FAMS", makePointer(gedcom, indi, fam.id, "FAM"), true);
|
|
2333
|
+
normalizeSinglePointer(indi, "FAMS");
|
|
2334
|
+
normalizeSinglePointer(fam, spouseTagFor(indi, fam));
|
|
2335
|
+
resetRelativesCache();
|
|
2307
2336
|
return true;
|
|
2308
2337
|
};
|
|
2309
2338
|
var attachChildToFamily = (fam, child, pedigree, parent) => {
|
|
@@ -2319,14 +2348,122 @@ var attachChildToFamily = (fam, child, pedigree, parent) => {
|
|
|
2319
2348
|
child.assign("FAMC", makePointer(gedcom, child, fam.id, "FAM"), true);
|
|
2320
2349
|
}
|
|
2321
2350
|
setChildPedigree(fam, child, pedigree, parent);
|
|
2351
|
+
normalizeSinglePointer(child, "FAMC");
|
|
2352
|
+
normalizeSinglePointer(fam, "CHIL");
|
|
2353
|
+
resetRelativesCache();
|
|
2322
2354
|
return true;
|
|
2323
2355
|
};
|
|
2324
|
-
var
|
|
2356
|
+
var removePointerByValue = (owner, tag, targetId) => {
|
|
2357
|
+
const node = owner.get(tag);
|
|
2358
|
+
if (!node) {
|
|
2359
|
+
return false;
|
|
2360
|
+
}
|
|
2361
|
+
if (node instanceof List) {
|
|
2362
|
+
const keysToRemove = [];
|
|
2363
|
+
node.entries().forEach(([key, item]) => {
|
|
2364
|
+
if (item?.toValue?.() === targetId || item?.id === targetId || String(key) === targetId) {
|
|
2365
|
+
keysToRemove.push(key);
|
|
2366
|
+
}
|
|
2367
|
+
});
|
|
2368
|
+
keysToRemove.forEach((key) => {
|
|
2369
|
+
node.removeItem(key);
|
|
2370
|
+
});
|
|
2371
|
+
if (node.length === 0) {
|
|
2372
|
+
owner.remove(tag);
|
|
2373
|
+
}
|
|
2374
|
+
return keysToRemove.length > 0;
|
|
2375
|
+
}
|
|
2376
|
+
if (node.toValue?.() === targetId) {
|
|
2377
|
+
owner.remove(tag);
|
|
2378
|
+
return true;
|
|
2379
|
+
}
|
|
2380
|
+
const asList = node.toList?.();
|
|
2381
|
+
if (asList && asList.length > 0) {
|
|
2382
|
+
const keysToRemove = [];
|
|
2383
|
+
asList.entries().forEach(([key, item]) => {
|
|
2384
|
+
if (item?.toValue?.() === targetId || item?.id === targetId) {
|
|
2385
|
+
keysToRemove.push(key);
|
|
2386
|
+
}
|
|
2387
|
+
});
|
|
2388
|
+
if (keysToRemove.length === asList.length) {
|
|
2389
|
+
owner.remove(tag);
|
|
2390
|
+
return true;
|
|
2391
|
+
}
|
|
2392
|
+
if (keysToRemove.length > 0) {
|
|
2393
|
+
const remaining = asList.values().filter((item) => item?.toValue?.() !== targetId);
|
|
2394
|
+
if (remaining.length === 1 && remaining[0]) {
|
|
2395
|
+
owner.set(tag, remaining[0]);
|
|
2396
|
+
} else {
|
|
2397
|
+
owner.set(tag, new List(remaining));
|
|
2398
|
+
}
|
|
2399
|
+
return true;
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
return false;
|
|
2403
|
+
};
|
|
2404
|
+
var familyMemberCount = (fam) => {
|
|
2405
|
+
let count = 0;
|
|
2406
|
+
if (firstPointerId(fam.get("HUSB"))) {
|
|
2407
|
+
count += 1;
|
|
2408
|
+
}
|
|
2409
|
+
if (firstPointerId(fam.get("WIFE"))) {
|
|
2410
|
+
count += 1;
|
|
2411
|
+
}
|
|
2412
|
+
count += pointerIds(fam.get("CHIL")).length;
|
|
2413
|
+
return count;
|
|
2414
|
+
};
|
|
2415
|
+
var isDegenerateFamily = (fam) => familyMemberCount(fam) <= 1;
|
|
2416
|
+
var pruneEmptyFamilies = (gedcom) => {
|
|
2417
|
+
const emptyIds = [];
|
|
2418
|
+
gedcom.fams()?.forEach((fam, id) => {
|
|
2419
|
+
if (fam && isDegenerateFamily(fam) && id) {
|
|
2420
|
+
emptyIds.push(id);
|
|
2421
|
+
}
|
|
2422
|
+
});
|
|
2423
|
+
if (emptyIds.length === 0) {
|
|
2424
|
+
return [];
|
|
2425
|
+
}
|
|
2426
|
+
gedcom.indis()?.forEach((indi) => {
|
|
2427
|
+
if (!indi) {
|
|
2428
|
+
return;
|
|
2429
|
+
}
|
|
2430
|
+
emptyIds.forEach((famId) => {
|
|
2431
|
+
removePointerByValue(indi, "FAMS", famId);
|
|
2432
|
+
removePointerByValue(indi, "FAMC", famId);
|
|
2433
|
+
});
|
|
2434
|
+
});
|
|
2435
|
+
emptyIds.forEach((famId) => {
|
|
2436
|
+
gedcom.fams()?.removeItem(famId);
|
|
2437
|
+
});
|
|
2438
|
+
return emptyIds;
|
|
2439
|
+
};
|
|
2440
|
+
var findSharedSpouseFamily = (parent, coParentId) => {
|
|
2441
|
+
let found;
|
|
2442
|
+
parent.getFamilies("FAMS")?.forEach((fam) => {
|
|
2443
|
+
if (!found && fam && familyHasParent(fam, coParentId)) {
|
|
2444
|
+
found = fam;
|
|
2445
|
+
}
|
|
2446
|
+
});
|
|
2447
|
+
return found;
|
|
2448
|
+
};
|
|
2449
|
+
var findReusableParentChildFamily = (parent, child, options) => {
|
|
2325
2450
|
if (!parent.id || !child.id) {
|
|
2326
2451
|
return void 0;
|
|
2327
2452
|
}
|
|
2453
|
+
const reuseParentFamilies = options?.reuseParentFamilies !== false;
|
|
2454
|
+
const gedcom = parent.getGedcom() ?? child.getGedcom();
|
|
2328
2455
|
let reusableFamc;
|
|
2456
|
+
let coupleFam;
|
|
2329
2457
|
let already = false;
|
|
2458
|
+
const noteCoupleWith = (coParentId) => {
|
|
2459
|
+
if (!coParentId || coParentId === parent.id || coupleFam || !parent.id) {
|
|
2460
|
+
return;
|
|
2461
|
+
}
|
|
2462
|
+
const shared = findSharedSpouseFamily(parent, coParentId);
|
|
2463
|
+
if (shared) {
|
|
2464
|
+
coupleFam = shared;
|
|
2465
|
+
}
|
|
2466
|
+
};
|
|
2330
2467
|
child.getFamilies("FAMC")?.forEach((fam) => {
|
|
2331
2468
|
if (!fam) {
|
|
2332
2469
|
return;
|
|
@@ -2335,6 +2472,8 @@ var findReusableParentChildFamily = (parent, child) => {
|
|
|
2335
2472
|
already = true;
|
|
2336
2473
|
return;
|
|
2337
2474
|
}
|
|
2475
|
+
pointerIds(fam.get("HUSB")).forEach(noteCoupleWith);
|
|
2476
|
+
pointerIds(fam.get("WIFE")).forEach(noteCoupleWith);
|
|
2338
2477
|
if (!reusableFamc && canAttachAsSpouse(fam, parent)) {
|
|
2339
2478
|
reusableFamc = fam;
|
|
2340
2479
|
}
|
|
@@ -2342,9 +2481,21 @@ var findReusableParentChildFamily = (parent, child) => {
|
|
|
2342
2481
|
if (already) {
|
|
2343
2482
|
return "already";
|
|
2344
2483
|
}
|
|
2484
|
+
if (coupleFam) {
|
|
2485
|
+
return coupleFam;
|
|
2486
|
+
}
|
|
2345
2487
|
if (reusableFamc) {
|
|
2346
2488
|
return reusableFamc;
|
|
2347
2489
|
}
|
|
2490
|
+
if (options?.targetFamilyId && gedcom) {
|
|
2491
|
+
const target = gedcom.fam(options.targetFamilyId);
|
|
2492
|
+
if (target && (familyHasParent(target, parent.id) || canAttachAsSpouse(target, parent))) {
|
|
2493
|
+
return target;
|
|
2494
|
+
}
|
|
2495
|
+
}
|
|
2496
|
+
if (!reuseParentFamilies) {
|
|
2497
|
+
return void 0;
|
|
2498
|
+
}
|
|
2348
2499
|
const parentFams = [];
|
|
2349
2500
|
parent.getFamilies("FAMS")?.forEach((fam) => {
|
|
2350
2501
|
if (fam) {
|
|
@@ -2356,6 +2507,41 @@ var findReusableParentChildFamily = (parent, child) => {
|
|
|
2356
2507
|
}
|
|
2357
2508
|
return void 0;
|
|
2358
2509
|
};
|
|
2510
|
+
var consolidateChildIntoFamily = (child, keep) => {
|
|
2511
|
+
if (!child.id || !keep.id) {
|
|
2512
|
+
return [];
|
|
2513
|
+
}
|
|
2514
|
+
const keepParentIds = /* @__PURE__ */ new Set([
|
|
2515
|
+
...pointerIds(keep.get("HUSB")),
|
|
2516
|
+
...pointerIds(keep.get("WIFE"))
|
|
2517
|
+
]);
|
|
2518
|
+
const removed = [];
|
|
2519
|
+
child.getFamilies("FAMC")?.forEach((fam) => {
|
|
2520
|
+
if (!fam?.id || fam.id === keep.id) {
|
|
2521
|
+
return;
|
|
2522
|
+
}
|
|
2523
|
+
const famParentIds = [
|
|
2524
|
+
...pointerIds(fam.get("HUSB")),
|
|
2525
|
+
...pointerIds(fam.get("WIFE"))
|
|
2526
|
+
];
|
|
2527
|
+
if (famParentIds.length === 0 || !famParentIds.every((id) => keepParentIds.has(id))) {
|
|
2528
|
+
return;
|
|
2529
|
+
}
|
|
2530
|
+
removePointerByValue(fam, "CHIL", child.id);
|
|
2531
|
+
normalizeSinglePointer(fam, "CHIL");
|
|
2532
|
+
removePointerByValue(child, "FAMC", fam.id);
|
|
2533
|
+
normalizeSinglePointer(child, "FAMC");
|
|
2534
|
+
removed.push(fam.id);
|
|
2535
|
+
});
|
|
2536
|
+
const gedcom = child.getGedcom() ?? keep.getGedcom();
|
|
2537
|
+
if (gedcom && removed.length > 0) {
|
|
2538
|
+
pruneEmptyFamilies(gedcom);
|
|
2539
|
+
}
|
|
2540
|
+
if (removed.length > 0) {
|
|
2541
|
+
resetRelativesCache();
|
|
2542
|
+
}
|
|
2543
|
+
return removed;
|
|
2544
|
+
};
|
|
2359
2545
|
|
|
2360
2546
|
// src/utils/get-places.ts
|
|
2361
2547
|
var getPlaces = (common, type = ["ALL" /* All */], maxLevel = 1, level = 0, mainKey) => {
|
|
@@ -4407,13 +4593,17 @@ var Indi = class extends Common {
|
|
|
4407
4593
|
}
|
|
4408
4594
|
return fam;
|
|
4409
4595
|
}
|
|
4410
|
-
addChild(child, pedigree) {
|
|
4596
|
+
addChild(child, pedigree, options) {
|
|
4411
4597
|
if (!this.id || !child?.id || this.id === child.id || !this._gedcom) {
|
|
4412
4598
|
return void 0;
|
|
4413
4599
|
}
|
|
4414
4600
|
const existing = findReusableParentChildFamily(
|
|
4415
4601
|
this,
|
|
4416
|
-
child
|
|
4602
|
+
child,
|
|
4603
|
+
{
|
|
4604
|
+
reuseParentFamilies: options?.reuseParentFamilies,
|
|
4605
|
+
targetFamilyId: options?.targetFamilyId
|
|
4606
|
+
}
|
|
4417
4607
|
);
|
|
4418
4608
|
if (existing === "already") {
|
|
4419
4609
|
const fam2 = child.getFamilies("FAMC")?.find(
|
|
@@ -4436,10 +4626,16 @@ var Indi = class extends Common {
|
|
|
4436
4626
|
if (!fam.addChild(child, pedigree, this)) {
|
|
4437
4627
|
return void 0;
|
|
4438
4628
|
}
|
|
4629
|
+
if (existing) {
|
|
4630
|
+
consolidateChildIntoFamily(child, fam);
|
|
4631
|
+
}
|
|
4439
4632
|
return fam;
|
|
4440
4633
|
}
|
|
4441
|
-
addParent(parent, pedigree) {
|
|
4442
|
-
return parent.addChild(this, pedigree
|
|
4634
|
+
addParent(parent, pedigree, options) {
|
|
4635
|
+
return parent.addChild(this, pedigree, {
|
|
4636
|
+
reuseParentFamilies: false,
|
|
4637
|
+
targetFamilyId: options?.targetFamilyId
|
|
4638
|
+
});
|
|
4443
4639
|
}
|
|
4444
4640
|
/**
|
|
4445
4641
|
* Link an existing top-level OBJE record to this individual (`1 OBJE @On@`).
|