@treeviz/gedcom-parser 2.1.22 → 2.1.24
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/gedcom.d.ts.map +1 -1
- package/dist/classes/index.js +32 -4
- package/dist/classes/list.d.ts.map +1 -1
- package/dist/cli/index.js +751 -721
- package/dist/constants/constants.d.ts +0 -4
- package/dist/constants/constants.d.ts.map +1 -1
- package/dist/constants/index.js +2 -3
- package/dist/factories/index.js +1 -1
- package/dist/index.js +1213 -1183
- package/dist/kinship-translator/index.js +1 -1
- package/dist/structures/individual.d.ts +2 -0
- package/dist/structures/individual.d.ts.map +1 -1
- package/dist/types/types.d.ts +2 -0
- package/dist/types/types.d.ts.map +1 -1
- package/dist/utils/family-edit.d.ts +7 -0
- package/dist/utils/family-edit.d.ts.map +1 -1
- package/dist/utils/gedcom7-schema.d.ts.map +1 -1
- package/dist/utils/index.js +42 -11
- package/dist/utils/parser.d.ts +13 -8
- package/dist/utils/parser.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -16,7 +16,6 @@ var ID_REG = /^@[_a-zA-Z0-9]+@/;
|
|
|
16
16
|
var ID_GETTER_REG = /^(?<at>@)?(?<letter>[A-Z])?/i;
|
|
17
17
|
var ID_SPLIT_REG = /^@[_a-zA-Z0-9]+@:/;
|
|
18
18
|
var ORIG_HEAD_TAG = "_ORIGHEAD";
|
|
19
|
-
var MAX_FILE_SIZE_TO_SYNC = 1024 * 1024 * 20;
|
|
20
19
|
|
|
21
20
|
// src/utils/gedcom-trailer.ts
|
|
22
21
|
var TRAILER_LINE = /^0 TRLR\s*$/i;
|
|
@@ -510,7 +509,7 @@ var List = class _List {
|
|
|
510
509
|
const gedcom = [];
|
|
511
510
|
this.entries().forEach(([_, item]) => {
|
|
512
511
|
const validTag = getValidTag(tag);
|
|
513
|
-
const xref = item.id;
|
|
512
|
+
const xref = validTag === "CONT" || validTag === "CONC" ? void 0 : item.id;
|
|
514
513
|
const payload = item.exportValue?.();
|
|
515
514
|
if (xref) {
|
|
516
515
|
gedcom.push(
|
|
@@ -1300,6 +1299,68 @@ var idGetter = (id) => {
|
|
|
1300
1299
|
return newId;
|
|
1301
1300
|
};
|
|
1302
1301
|
|
|
1302
|
+
// src/factories/cache-factory.ts
|
|
1303
|
+
var defaultCacheFactory = () => {
|
|
1304
|
+
let cache = null;
|
|
1305
|
+
return {
|
|
1306
|
+
getItem: async () => cache,
|
|
1307
|
+
setItem: async (value) => {
|
|
1308
|
+
cache = value;
|
|
1309
|
+
}
|
|
1310
|
+
};
|
|
1311
|
+
};
|
|
1312
|
+
var cacheFactory = defaultCacheFactory;
|
|
1313
|
+
var setCacheManagerFactory = (factory) => {
|
|
1314
|
+
cacheFactory = factory;
|
|
1315
|
+
};
|
|
1316
|
+
var getCacheManagerFactory = () => {
|
|
1317
|
+
return cacheFactory;
|
|
1318
|
+
};
|
|
1319
|
+
var resetCacheManagerFactory = () => {
|
|
1320
|
+
cacheFactory = defaultCacheFactory;
|
|
1321
|
+
};
|
|
1322
|
+
|
|
1323
|
+
// src/factories/date-locale-factory.ts
|
|
1324
|
+
var dateLocaleProvider = () => void 0;
|
|
1325
|
+
var setDateLocaleProvider = (provider) => {
|
|
1326
|
+
dateLocaleProvider = provider;
|
|
1327
|
+
};
|
|
1328
|
+
var getDateLocale = () => {
|
|
1329
|
+
const result = dateLocaleProvider();
|
|
1330
|
+
return result;
|
|
1331
|
+
};
|
|
1332
|
+
var resetDateLocaleProvider = () => {
|
|
1333
|
+
dateLocaleProvider = () => void 0;
|
|
1334
|
+
};
|
|
1335
|
+
|
|
1336
|
+
// src/factories/i18n-factory.ts
|
|
1337
|
+
var i18nProvider = (key) => key;
|
|
1338
|
+
var setI18nProvider = (provider) => {
|
|
1339
|
+
i18nProvider = provider;
|
|
1340
|
+
};
|
|
1341
|
+
var getI18n = () => {
|
|
1342
|
+
return i18nProvider;
|
|
1343
|
+
};
|
|
1344
|
+
var resetI18nProvider = () => {
|
|
1345
|
+
i18nProvider = (key) => key;
|
|
1346
|
+
};
|
|
1347
|
+
var i18n = {
|
|
1348
|
+
t: (key, options) => i18nProvider(key, options)
|
|
1349
|
+
};
|
|
1350
|
+
|
|
1351
|
+
// src/kinship-translator/translators.ts
|
|
1352
|
+
var translators_exports = {};
|
|
1353
|
+
__export(translators_exports, {
|
|
1354
|
+
de: () => KinshipTranslatorDe,
|
|
1355
|
+
en: () => KinshipTranslatorEn,
|
|
1356
|
+
es: () => KinshipTranslatorEs,
|
|
1357
|
+
fr: () => KinshipTranslatorFr,
|
|
1358
|
+
hu: () => KinshipTranslatorHU,
|
|
1359
|
+
ja: () => KinshipTranslatorJa,
|
|
1360
|
+
ru: () => KinshipTranslatorRu,
|
|
1361
|
+
zh: () => KinshipTranslatorZh
|
|
1362
|
+
});
|
|
1363
|
+
|
|
1303
1364
|
// src/types/types.ts
|
|
1304
1365
|
var RelationType = /* @__PURE__ */ ((RelationType2) => {
|
|
1305
1366
|
RelationType2["BIOLOGICAL"] = "biological";
|
|
@@ -1328,996 +1389,92 @@ var Range = /* @__PURE__ */ ((Range2) => {
|
|
|
1328
1389
|
return Range2;
|
|
1329
1390
|
})(Range || {});
|
|
1330
1391
|
|
|
1331
|
-
// src/
|
|
1332
|
-
var
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
getItem: async () => cache,
|
|
1336
|
-
setItem: async (value) => {
|
|
1337
|
-
cache = value;
|
|
1338
|
-
}
|
|
1339
|
-
};
|
|
1392
|
+
// src/constants/filters.ts
|
|
1393
|
+
var EVERY = {};
|
|
1394
|
+
var FEMALE = {
|
|
1395
|
+
SEX: "F"
|
|
1340
1396
|
};
|
|
1341
|
-
var
|
|
1342
|
-
|
|
1343
|
-
cacheFactory = factory;
|
|
1397
|
+
var MALE = {
|
|
1398
|
+
SEX: "M"
|
|
1344
1399
|
};
|
|
1345
|
-
var
|
|
1346
|
-
|
|
1400
|
+
var ADOPTED = {
|
|
1401
|
+
PEDI: "adopted" /* ADOPTED */
|
|
1347
1402
|
};
|
|
1348
|
-
var
|
|
1349
|
-
|
|
1403
|
+
var BIRTH = {
|
|
1404
|
+
PEDI: "birth" /* BIRTH */
|
|
1350
1405
|
};
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
var getGedcomId = (gedcom) => {
|
|
1354
|
-
if (!gedcom) {
|
|
1355
|
-
return "unknown";
|
|
1356
|
-
}
|
|
1357
|
-
const treeId = gedcom.getTreeId?.() || "";
|
|
1358
|
-
const treeName = gedcom.getTreeName?.() || "";
|
|
1359
|
-
const sanitizedName = treeName.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
1360
|
-
if (treeId && sanitizedName) {
|
|
1361
|
-
return `${treeId}_${sanitizedName}`;
|
|
1362
|
-
} else if (treeId) {
|
|
1363
|
-
return treeId;
|
|
1364
|
-
} else if (sanitizedName) {
|
|
1365
|
-
return sanitizedName;
|
|
1366
|
-
}
|
|
1367
|
-
return `gedcom_${gedcom.refcount}`;
|
|
1406
|
+
var FOSTER = {
|
|
1407
|
+
PEDI: "foster" /* FOSTER */
|
|
1368
1408
|
};
|
|
1369
|
-
var
|
|
1370
|
-
|
|
1371
|
-
relativesOnDegreeCache: {},
|
|
1372
|
-
relativesOnLevelCache: {},
|
|
1373
|
-
profilePictureCache: {}
|
|
1409
|
+
var SEALING = {
|
|
1410
|
+
PEDI: "sealing" /* SEALING */
|
|
1374
1411
|
};
|
|
1375
|
-
var
|
|
1376
|
-
|
|
1377
|
-
if (!cacheDbs) {
|
|
1378
|
-
const getInstance = getCacheManagerFactory();
|
|
1379
|
-
cacheDbs = {
|
|
1380
|
-
pathCache: getInstance(
|
|
1381
|
-
"ftv",
|
|
1382
|
-
"Main",
|
|
1383
|
-
"path",
|
|
1384
|
-
true
|
|
1385
|
-
),
|
|
1386
|
-
relativesOnDegreeCache: getInstance("ftv", "Main", "path", true),
|
|
1387
|
-
relativesOnLevelCache: getInstance(
|
|
1388
|
-
"ftv",
|
|
1389
|
-
"Main",
|
|
1390
|
-
"path",
|
|
1391
|
-
true
|
|
1392
|
-
),
|
|
1393
|
-
profilePictureCache: getInstance(
|
|
1394
|
-
"ftv",
|
|
1395
|
-
"Main",
|
|
1396
|
-
"images",
|
|
1397
|
-
false
|
|
1398
|
-
)
|
|
1399
|
-
};
|
|
1400
|
-
}
|
|
1401
|
-
return cacheDbs;
|
|
1412
|
+
var STEP = {
|
|
1413
|
+
PEDI: "step" /* STEP */
|
|
1402
1414
|
};
|
|
1403
|
-
var
|
|
1404
|
-
|
|
1405
|
-
// kept in memory only. These debounced functions exist to satisfy the type system
|
|
1406
|
-
// but are never called.
|
|
1407
|
-
pathCache: debounce((value) => {
|
|
1408
|
-
if (value) {
|
|
1409
|
-
getCacheDbs().pathCache.setItem(value);
|
|
1410
|
-
}
|
|
1411
|
-
}, 50),
|
|
1412
|
-
relativesOnLevelCache: debounce((value) => {
|
|
1413
|
-
if (value) {
|
|
1414
|
-
getCacheDbs().relativesOnLevelCache.setItem(value);
|
|
1415
|
-
}
|
|
1416
|
-
}, 50),
|
|
1417
|
-
relativesOnDegreeCache: debounce((value) => {
|
|
1418
|
-
if (value) {
|
|
1419
|
-
getCacheDbs().relativesOnDegreeCache.setItem(value);
|
|
1420
|
-
}
|
|
1421
|
-
}, 50),
|
|
1422
|
-
// Image bytes are stored as one IndexedDB record per photo.
|
|
1423
|
-
profilePictureCache: debounce((value) => {
|
|
1424
|
-
}, 100)
|
|
1415
|
+
var BIOLOGICAL = {
|
|
1416
|
+
PEDI: "biological" /* BIOLOGICAL */
|
|
1425
1417
|
};
|
|
1426
|
-
var
|
|
1427
|
-
|
|
1428
|
-
if (cacheInitialized) {
|
|
1429
|
-
return;
|
|
1430
|
-
}
|
|
1431
|
-
cacheInitialized = true;
|
|
1418
|
+
var FRIEND = {
|
|
1419
|
+
PART: "friend" /* FRIEND */
|
|
1432
1420
|
};
|
|
1433
|
-
var
|
|
1434
|
-
|
|
1435
|
-
caches.relativesOnLevelCache = {};
|
|
1421
|
+
var OTHER = {
|
|
1422
|
+
PART: "other" /* OTHER */
|
|
1436
1423
|
};
|
|
1437
|
-
var
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1424
|
+
var PARTNER = {
|
|
1425
|
+
PART: "partner" /* PARTNER */
|
|
1426
|
+
};
|
|
1427
|
+
var SINGLE = {
|
|
1428
|
+
PART: "single" /* SINGLE */
|
|
1429
|
+
};
|
|
1430
|
+
var SPOUSE = {
|
|
1431
|
+
PART: "spouse" /* SPOUSE */
|
|
1432
|
+
};
|
|
1433
|
+
var UNKOWN = {
|
|
1434
|
+
PART: "unknown" /* UNKOWN */
|
|
1435
|
+
};
|
|
1436
|
+
|
|
1437
|
+
// src/utils/get-family-with.ts
|
|
1438
|
+
var getFamilyWith = (person1, person2, famType = "FAMS") => {
|
|
1439
|
+
return person1?.get(famType)?.toValueList().find((fam) => {
|
|
1440
|
+
const family = fam;
|
|
1441
|
+
return famType === "FAMC" || family?.HUSB?.value === person2 || family?.WIFE?.value === person2;
|
|
1442
|
+
});
|
|
1443
|
+
};
|
|
1444
|
+
|
|
1445
|
+
// src/constants/orders.ts
|
|
1446
|
+
var DEFAULT = {};
|
|
1447
|
+
var BIRTH_ASC = {
|
|
1448
|
+
"BIRT.DATE": {
|
|
1449
|
+
direction: "ASC",
|
|
1450
|
+
getter: (value, raw) => {
|
|
1451
|
+
if (isCommonDate(raw) && raw.rawValue) {
|
|
1452
|
+
return raw.rawValue.getTime();
|
|
1453
|
+
}
|
|
1454
|
+
return new Date(value).getTime();
|
|
1448
1455
|
}
|
|
1449
|
-
typedCache2[fullKey][subKey] = value;
|
|
1450
|
-
return typedCache2[fullKey][subKey];
|
|
1451
1456
|
}
|
|
1452
|
-
const typedCache = caches[cacheKey];
|
|
1453
|
-
return typedCache?.[fullKey]?.[subKey];
|
|
1454
1457
|
};
|
|
1455
|
-
var
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1458
|
+
var BIRTH_DESC = {
|
|
1459
|
+
"BIRT.DATE": {
|
|
1460
|
+
direction: "DESC",
|
|
1461
|
+
getter: (value, raw) => {
|
|
1462
|
+
if (isCommonDate(raw) && raw.rawValue) {
|
|
1463
|
+
return raw.rawValue.getTime();
|
|
1464
|
+
}
|
|
1465
|
+
return new Date(value).getTime();
|
|
1466
|
+
}
|
|
1460
1467
|
}
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
caches.profilePictureCache = {};
|
|
1472
|
-
}
|
|
1473
|
-
if (value && caches.profilePictureCache) {
|
|
1474
|
-
caches.profilePictureCache[fullKey] = value;
|
|
1475
|
-
storeCache.profilePictureCache(caches.profilePictureCache);
|
|
1476
|
-
return caches.profilePictureCache[fullKey];
|
|
1477
|
-
}
|
|
1478
|
-
const cached = caches.profilePictureCache?.[fullKey];
|
|
1479
|
-
return cached;
|
|
1480
|
-
};
|
|
1481
|
-
var isNonBiologicalPath = (path) => path.some(
|
|
1482
|
-
(item) => item.relation && item.relation !== "biological" /* BIOLOGICAL */
|
|
1483
|
-
);
|
|
1484
|
-
var invertHop = (kinship) => {
|
|
1485
|
-
if (kinship === "parent") {
|
|
1486
|
-
return "child";
|
|
1487
|
-
}
|
|
1488
|
-
if (kinship === "child") {
|
|
1489
|
-
return "parent";
|
|
1490
|
-
}
|
|
1491
|
-
return kinship;
|
|
1492
|
-
};
|
|
1493
|
-
var hopRelation = (from, toIndi, kinship, inherited) => {
|
|
1494
|
-
if (kinship === "parent" || kinship === "child") {
|
|
1495
|
-
const parent = kinship === "parent" ? toIndi : from.indi;
|
|
1496
|
-
const child = kinship === "parent" ? from.indi : toIndi;
|
|
1497
|
-
const currentRelation = child.getParentType(parent);
|
|
1498
|
-
if (currentRelation && currentRelation !== "biological" /* BIOLOGICAL */) {
|
|
1499
|
-
return currentRelation;
|
|
1500
|
-
}
|
|
1501
|
-
}
|
|
1502
|
-
if (inherited && inherited !== "biological" /* BIOLOGICAL */) {
|
|
1503
|
-
return inherited;
|
|
1504
|
-
}
|
|
1505
|
-
return void 0;
|
|
1506
|
-
};
|
|
1507
|
-
var rebuildPathFromHops = (hops, skipRelation = false) => {
|
|
1508
|
-
if (hops.length === 0) {
|
|
1509
|
-
return [];
|
|
1510
|
-
}
|
|
1511
|
-
const path = [
|
|
1512
|
-
{
|
|
1513
|
-
indi: hops[0].indi,
|
|
1514
|
-
kinship: "self",
|
|
1515
|
-
level: 0,
|
|
1516
|
-
levelUp: 0,
|
|
1517
|
-
levelDown: 0,
|
|
1518
|
-
degree: 0
|
|
1519
|
-
}
|
|
1520
|
-
];
|
|
1521
|
-
for (let i = 1; i < hops.length; i++) {
|
|
1522
|
-
const prev = path[i - 1];
|
|
1523
|
-
const { indi, kinship } = hops[i];
|
|
1524
|
-
const relation = skipRelation ? void 0 : hopRelation(prev, indi, kinship, prev.relation);
|
|
1525
|
-
if (kinship === "parent") {
|
|
1526
|
-
path.push({
|
|
1527
|
-
indi,
|
|
1528
|
-
kinship,
|
|
1529
|
-
relation,
|
|
1530
|
-
level: prev.level + 1,
|
|
1531
|
-
levelUp: prev.levelUp + 1,
|
|
1532
|
-
levelDown: prev.levelDown,
|
|
1533
|
-
degree: prev.degree
|
|
1534
|
-
});
|
|
1535
|
-
continue;
|
|
1536
|
-
}
|
|
1537
|
-
if (kinship === "child") {
|
|
1538
|
-
path.push({
|
|
1539
|
-
indi,
|
|
1540
|
-
kinship,
|
|
1541
|
-
relation,
|
|
1542
|
-
level: prev.level - 1,
|
|
1543
|
-
levelUp: prev.levelUp,
|
|
1544
|
-
levelDown: prev.levelDown + 1,
|
|
1545
|
-
degree: prev.levelUp ? prev.level > 0 ? prev.levelUp - prev.level + 1 : prev.levelDown - Math.abs(prev.level) : 0
|
|
1546
|
-
});
|
|
1547
|
-
continue;
|
|
1548
|
-
}
|
|
1549
|
-
path.push({
|
|
1550
|
-
indi,
|
|
1551
|
-
kinship,
|
|
1552
|
-
relation,
|
|
1553
|
-
level: prev.level,
|
|
1554
|
-
levelUp: prev.levelUp,
|
|
1555
|
-
levelDown: prev.levelDown,
|
|
1556
|
-
degree: prev.degree
|
|
1557
|
-
});
|
|
1558
|
-
}
|
|
1559
|
-
return path;
|
|
1560
|
-
};
|
|
1561
|
-
var storePathIfBetter = (gedcom, fromId, toId, path) => {
|
|
1562
|
-
const key = `${fromId}|${toId}`;
|
|
1563
|
-
const existing = pathCache(gedcom, key);
|
|
1564
|
-
if (existing && (!isNonBiologicalPath(existing) || isNonBiologicalPath(path))) {
|
|
1565
|
-
return;
|
|
1566
|
-
}
|
|
1567
|
-
pathCache(gedcom, key, path);
|
|
1568
|
-
};
|
|
1569
|
-
var cacheDiscoveredPath = (gedcom, path) => {
|
|
1570
|
-
const n = path.length;
|
|
1571
|
-
if (n < 2) {
|
|
1572
|
-
return;
|
|
1573
|
-
}
|
|
1574
|
-
for (let i = 0; i < n; i++) {
|
|
1575
|
-
const fromId = path[i].indi.id;
|
|
1576
|
-
if (!fromId) {
|
|
1577
|
-
continue;
|
|
1578
|
-
}
|
|
1579
|
-
for (let j = i + 1; j < n; j++) {
|
|
1580
|
-
const toId = path[j].indi.id;
|
|
1581
|
-
if (!toId) {
|
|
1582
|
-
continue;
|
|
1583
|
-
}
|
|
1584
|
-
const isOriginalPair = i === 0 && j === n - 1;
|
|
1585
|
-
const isDirectHop = j === i + 1;
|
|
1586
|
-
const slice = path.slice(i, j + 1);
|
|
1587
|
-
const sliceMixed = isNonBiologicalPath(slice);
|
|
1588
|
-
if (!isOriginalPair && !isDirectHop && sliceMixed) {
|
|
1589
|
-
continue;
|
|
1590
|
-
}
|
|
1591
|
-
const forward = i === 0 ? slice : rebuildPathFromHops(slice, !sliceMixed);
|
|
1592
|
-
const reverseHops = [
|
|
1593
|
-
{
|
|
1594
|
-
indi: slice[slice.length - 1].indi,
|
|
1595
|
-
kinship: "self"
|
|
1596
|
-
}
|
|
1597
|
-
];
|
|
1598
|
-
for (let k = slice.length - 2; k >= 0; k--) {
|
|
1599
|
-
reverseHops.push({
|
|
1600
|
-
indi: slice[k].indi,
|
|
1601
|
-
kinship: invertHop(slice[k + 1].kinship)
|
|
1602
|
-
});
|
|
1603
|
-
}
|
|
1604
|
-
const reverse = rebuildPathFromHops(reverseHops, !sliceMixed);
|
|
1605
|
-
storePathIfBetter(gedcom, fromId, toId, forward);
|
|
1606
|
-
storePathIfBetter(gedcom, toId, fromId, reverse);
|
|
1607
|
-
}
|
|
1608
|
-
}
|
|
1609
|
-
};
|
|
1610
|
-
|
|
1611
|
-
// src/utils/family-edit.ts
|
|
1612
|
-
var refTypeForTag = (tag) => {
|
|
1613
|
-
if (tag === "FAMS" || tag === "FAMC") return "FAM";
|
|
1614
|
-
return "INDI";
|
|
1615
|
-
};
|
|
1616
|
-
var normalizeSinglePointer = (owner, tag) => {
|
|
1617
|
-
const node = owner.get(tag);
|
|
1618
|
-
if (!node) return;
|
|
1619
|
-
if (node instanceof List && node.length === 1) {
|
|
1620
|
-
const only = node.index(0);
|
|
1621
|
-
if (only) {
|
|
1622
|
-
owner.set(tag, only);
|
|
1623
|
-
return;
|
|
1624
|
-
}
|
|
1625
|
-
const raw = node.values()[0];
|
|
1626
|
-
if (typeof raw === "string") {
|
|
1627
|
-
const gedcom = owner.getGedcom?.();
|
|
1628
|
-
if (gedcom) {
|
|
1629
|
-
owner.set(tag, makePointer(gedcom, owner, raw, refTypeForTag(tag)));
|
|
1630
|
-
}
|
|
1631
|
-
}
|
|
1632
|
-
}
|
|
1633
|
-
};
|
|
1634
|
-
var PEDIGREE_VALUES = [
|
|
1635
|
-
"birth" /* BIRTH */,
|
|
1636
|
-
"adopted" /* ADOPTED */,
|
|
1637
|
-
"foster" /* FOSTER */,
|
|
1638
|
-
"step" /* STEP */,
|
|
1639
|
-
"sealing" /* SEALING */
|
|
1640
|
-
];
|
|
1641
|
-
var toGedcomPedigree = (value) => {
|
|
1642
|
-
const normalized = String(value || "birth" /* BIRTH */).toLowerCase();
|
|
1643
|
-
if (normalized === "biological" /* BIOLOGICAL */ || normalized === "birth" /* BIRTH */) {
|
|
1644
|
-
return "birth" /* BIRTH */;
|
|
1645
|
-
}
|
|
1646
|
-
const match = PEDIGREE_VALUES.find((item) => item === normalized);
|
|
1647
|
-
return match ?? "birth" /* BIRTH */;
|
|
1648
|
-
};
|
|
1649
|
-
var pointerIds = (tag) => {
|
|
1650
|
-
if (!tag) {
|
|
1651
|
-
return [];
|
|
1652
|
-
}
|
|
1653
|
-
if (tag instanceof List) {
|
|
1654
|
-
return tag.values().map((item) => item?.toValue?.()).filter((value2) => !!value2);
|
|
1655
|
-
}
|
|
1656
|
-
const value = tag.toValue?.();
|
|
1657
|
-
return value ? [String(value)] : [];
|
|
1658
|
-
};
|
|
1659
|
-
var firstPointerId = (tag) => pointerIds(tag)[0];
|
|
1660
|
-
var makePointer = (gedcom, parent, value, refType) => {
|
|
1661
|
-
const pointer = createCommon(gedcom, void 0, parent);
|
|
1662
|
-
pointer.value = value;
|
|
1663
|
-
pointer.refType = refType;
|
|
1664
|
-
return pointer;
|
|
1665
|
-
};
|
|
1666
|
-
var nextRecordId = (ids, prefix) => {
|
|
1667
|
-
let max = 0;
|
|
1668
|
-
ids.forEach((id) => {
|
|
1669
|
-
const match = String(id).match(/(\d+)/);
|
|
1670
|
-
const n = match ? Number.parseInt(match[1], 10) : 0;
|
|
1671
|
-
if (n > max) {
|
|
1672
|
-
max = n;
|
|
1673
|
-
}
|
|
1674
|
-
});
|
|
1675
|
-
return `@${prefix}${max + 1}@`;
|
|
1676
|
-
};
|
|
1677
|
-
var familyHasParent = (fam, indiId) => pointerIds(fam.get("HUSB")).includes(indiId) || pointerIds(fam.get("WIFE")).includes(indiId);
|
|
1678
|
-
var familyHasChild = (fam, indiId) => pointerIds(fam.get("CHIL")).includes(indiId);
|
|
1679
|
-
var spouseTagFor = (indi, fam) => {
|
|
1680
|
-
const husbId = firstPointerId(fam.get("HUSB"));
|
|
1681
|
-
const wifeId = firstPointerId(fam.get("WIFE"));
|
|
1682
|
-
if (husbId === indi.id) {
|
|
1683
|
-
return "HUSB";
|
|
1684
|
-
}
|
|
1685
|
-
if (wifeId === indi.id) {
|
|
1686
|
-
return "WIFE";
|
|
1687
|
-
}
|
|
1688
|
-
if (indi.isFemale()) {
|
|
1689
|
-
return wifeId && wifeId !== indi.id ? "HUSB" : "WIFE";
|
|
1690
|
-
}
|
|
1691
|
-
if (indi.isMale()) {
|
|
1692
|
-
return husbId && husbId !== indi.id ? "WIFE" : "HUSB";
|
|
1693
|
-
}
|
|
1694
|
-
return husbId ? "WIFE" : "HUSB";
|
|
1695
|
-
};
|
|
1696
|
-
var canAttachAsSpouse = (fam, indi) => {
|
|
1697
|
-
if (!indi.id) {
|
|
1698
|
-
return false;
|
|
1699
|
-
}
|
|
1700
|
-
if (familyHasParent(fam, indi.id)) {
|
|
1701
|
-
return true;
|
|
1702
|
-
}
|
|
1703
|
-
const tag = spouseTagFor(indi, fam);
|
|
1704
|
-
const occupied = firstPointerId(fam.get(tag));
|
|
1705
|
-
return !occupied || occupied === indi.id;
|
|
1706
|
-
};
|
|
1707
|
-
var pointerByValue = (tag, id) => {
|
|
1708
|
-
if (!tag) {
|
|
1709
|
-
return void 0;
|
|
1710
|
-
}
|
|
1711
|
-
const fromValues = tag.toValueList?.().item(id);
|
|
1712
|
-
if (fromValues) {
|
|
1713
|
-
return fromValues;
|
|
1714
|
-
}
|
|
1715
|
-
return tag.toList()?.values().find((item) => item?.toValue?.() === id);
|
|
1716
|
-
};
|
|
1717
|
-
var setChildPedigree = (fam, child, pedigree, parent) => {
|
|
1718
|
-
if (!fam.id || !child.id) {
|
|
1719
|
-
return;
|
|
1720
|
-
}
|
|
1721
|
-
const pedi = toGedcomPedigree(pedigree);
|
|
1722
|
-
const famc = pointerByValue(child.get("FAMC"), fam.id);
|
|
1723
|
-
if (famc) {
|
|
1724
|
-
famc.set("PEDI", pedi);
|
|
1725
|
-
}
|
|
1726
|
-
const chil = pointerByValue(fam.get("CHIL"), child.id);
|
|
1727
|
-
if (!chil) {
|
|
1728
|
-
return;
|
|
1729
|
-
}
|
|
1730
|
-
const setFather = !parent || parent.isMale() || parent.isUnknownSex();
|
|
1731
|
-
const setMother = !parent || parent.isFemale() || parent.isUnknownSex();
|
|
1732
|
-
if (setFather) {
|
|
1733
|
-
chil.set("_FREL", pedi);
|
|
1734
|
-
}
|
|
1735
|
-
if (setMother) {
|
|
1736
|
-
chil.set("_MREL", pedi);
|
|
1737
|
-
}
|
|
1738
|
-
};
|
|
1739
|
-
var attachSpouseToFamily = (fam, indi) => {
|
|
1740
|
-
const gedcom = fam.getGedcom() ?? indi.getGedcom();
|
|
1741
|
-
if (!indi.id || !fam.id || !gedcom) {
|
|
1742
|
-
return false;
|
|
1743
|
-
}
|
|
1744
|
-
if (!canAttachAsSpouse(fam, indi)) {
|
|
1745
|
-
return false;
|
|
1746
|
-
}
|
|
1747
|
-
const tag = spouseTagFor(indi, fam);
|
|
1748
|
-
if (firstPointerId(fam.get(tag)) !== indi.id) {
|
|
1749
|
-
fam.set(tag, makePointer(gedcom, fam, indi.id, "INDI"));
|
|
1750
|
-
}
|
|
1751
|
-
indi.assign("FAMS", makePointer(gedcom, indi, fam.id, "FAM"), true);
|
|
1752
|
-
normalizeSinglePointer(indi, "FAMS");
|
|
1753
|
-
normalizeSinglePointer(fam, spouseTagFor(indi, fam));
|
|
1754
|
-
resetRelativesCache();
|
|
1755
|
-
return true;
|
|
1756
|
-
};
|
|
1757
|
-
var attachChildToFamily = (fam, child, pedigree, parent) => {
|
|
1758
|
-
const gedcom = fam.getGedcom() ?? child.getGedcom();
|
|
1759
|
-
if (!child.id || !fam.id || !gedcom) {
|
|
1760
|
-
return false;
|
|
1761
|
-
}
|
|
1762
|
-
if (!familyHasChild(fam, child.id)) {
|
|
1763
|
-
fam.assign("CHIL", makePointer(gedcom, fam, child.id, "INDI"), true);
|
|
1764
|
-
}
|
|
1765
|
-
const existingFamc = pointerByValue(child.get("FAMC"), fam.id);
|
|
1766
|
-
if (!existingFamc) {
|
|
1767
|
-
child.assign("FAMC", makePointer(gedcom, child, fam.id, "FAM"), true);
|
|
1768
|
-
}
|
|
1769
|
-
setChildPedigree(fam, child, pedigree, parent);
|
|
1770
|
-
normalizeSinglePointer(child, "FAMC");
|
|
1771
|
-
normalizeSinglePointer(fam, "CHIL");
|
|
1772
|
-
resetRelativesCache();
|
|
1773
|
-
return true;
|
|
1774
|
-
};
|
|
1775
|
-
var removePointerByValue = (owner, tag, targetId) => {
|
|
1776
|
-
const node = owner.get(tag);
|
|
1777
|
-
if (!node) {
|
|
1778
|
-
return false;
|
|
1779
|
-
}
|
|
1780
|
-
if (node instanceof List) {
|
|
1781
|
-
const keysToRemove = [];
|
|
1782
|
-
node.entries().forEach(([key, item]) => {
|
|
1783
|
-
if (item?.toValue?.() === targetId || item?.id === targetId || String(key) === targetId) {
|
|
1784
|
-
keysToRemove.push(key);
|
|
1785
|
-
}
|
|
1786
|
-
});
|
|
1787
|
-
keysToRemove.forEach((key) => {
|
|
1788
|
-
node.removeItem(key);
|
|
1789
|
-
});
|
|
1790
|
-
if (node.length === 0) {
|
|
1791
|
-
owner.remove(tag);
|
|
1792
|
-
}
|
|
1793
|
-
return keysToRemove.length > 0;
|
|
1794
|
-
}
|
|
1795
|
-
if (node.toValue?.() === targetId) {
|
|
1796
|
-
owner.remove(tag);
|
|
1797
|
-
return true;
|
|
1798
|
-
}
|
|
1799
|
-
const asList = node.toList?.();
|
|
1800
|
-
if (asList && asList.length > 0) {
|
|
1801
|
-
const keysToRemove = [];
|
|
1802
|
-
asList.entries().forEach(([key, item]) => {
|
|
1803
|
-
if (item?.toValue?.() === targetId || item?.id === targetId) {
|
|
1804
|
-
keysToRemove.push(key);
|
|
1805
|
-
}
|
|
1806
|
-
});
|
|
1807
|
-
if (keysToRemove.length === asList.length) {
|
|
1808
|
-
owner.remove(tag);
|
|
1809
|
-
return true;
|
|
1810
|
-
}
|
|
1811
|
-
if (keysToRemove.length > 0) {
|
|
1812
|
-
const remaining = asList.values().filter((item) => item?.toValue?.() !== targetId);
|
|
1813
|
-
if (remaining.length === 1 && remaining[0]) {
|
|
1814
|
-
owner.set(tag, remaining[0]);
|
|
1815
|
-
} else {
|
|
1816
|
-
owner.set(tag, new List(remaining));
|
|
1817
|
-
}
|
|
1818
|
-
return true;
|
|
1819
|
-
}
|
|
1820
|
-
}
|
|
1821
|
-
return false;
|
|
1822
|
-
};
|
|
1823
|
-
var familyMemberCount = (fam) => {
|
|
1824
|
-
let count = 0;
|
|
1825
|
-
if (firstPointerId(fam.get("HUSB"))) {
|
|
1826
|
-
count += 1;
|
|
1827
|
-
}
|
|
1828
|
-
if (firstPointerId(fam.get("WIFE"))) {
|
|
1829
|
-
count += 1;
|
|
1830
|
-
}
|
|
1831
|
-
count += pointerIds(fam.get("CHIL")).length;
|
|
1832
|
-
return count;
|
|
1833
|
-
};
|
|
1834
|
-
var isDegenerateFamily = (fam) => familyMemberCount(fam) <= 1;
|
|
1835
|
-
var pruneEmptyFamilies = (gedcom) => {
|
|
1836
|
-
const emptyIds = [];
|
|
1837
|
-
gedcom.fams()?.forEach((fam, id) => {
|
|
1838
|
-
if (fam && isDegenerateFamily(fam) && id) {
|
|
1839
|
-
emptyIds.push(id);
|
|
1840
|
-
}
|
|
1841
|
-
});
|
|
1842
|
-
if (emptyIds.length === 0) {
|
|
1843
|
-
return [];
|
|
1844
|
-
}
|
|
1845
|
-
gedcom.indis()?.forEach((indi) => {
|
|
1846
|
-
if (!indi) {
|
|
1847
|
-
return;
|
|
1848
|
-
}
|
|
1849
|
-
emptyIds.forEach((famId) => {
|
|
1850
|
-
removePointerByValue(indi, "FAMS", famId);
|
|
1851
|
-
removePointerByValue(indi, "FAMC", famId);
|
|
1852
|
-
});
|
|
1853
|
-
});
|
|
1854
|
-
emptyIds.forEach((famId) => {
|
|
1855
|
-
gedcom.fams()?.removeItem(famId);
|
|
1856
|
-
});
|
|
1857
|
-
return emptyIds;
|
|
1858
|
-
};
|
|
1859
|
-
var findDegenerateFamiliesForIndi = (indi) => {
|
|
1860
|
-
const found = [];
|
|
1861
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1862
|
-
["FAMC", "FAMS"].forEach((pointer) => {
|
|
1863
|
-
indi.getFamilies(pointer)?.forEach((fam) => {
|
|
1864
|
-
if (!fam?.id || seen.has(fam.id) || !isDegenerateFamily(fam)) {
|
|
1865
|
-
return;
|
|
1866
|
-
}
|
|
1867
|
-
seen.add(fam.id);
|
|
1868
|
-
found.push(fam);
|
|
1869
|
-
});
|
|
1870
|
-
});
|
|
1871
|
-
return found;
|
|
1872
|
-
};
|
|
1873
|
-
var coupleKeyForFam = (fam) => {
|
|
1874
|
-
const husb = firstPointerId(fam.get("HUSB"));
|
|
1875
|
-
const wife = firstPointerId(fam.get("WIFE"));
|
|
1876
|
-
if (!husb || !wife) {
|
|
1877
|
-
return void 0;
|
|
1878
|
-
}
|
|
1879
|
-
return husb < wife ? `${husb}|${wife}` : `${wife}|${husb}`;
|
|
1880
|
-
};
|
|
1881
|
-
var findDuplicateCoupleFamiliesForIndi = (indi) => {
|
|
1882
|
-
const gedcom = indi.getGedcom();
|
|
1883
|
-
if (!gedcom) {
|
|
1884
|
-
return [];
|
|
1885
|
-
}
|
|
1886
|
-
const relevantKeys = /* @__PURE__ */ new Set();
|
|
1887
|
-
["FAMC", "FAMS"].forEach((pointer) => {
|
|
1888
|
-
indi.getFamilies(pointer)?.forEach((fam) => {
|
|
1889
|
-
const key = fam ? coupleKeyForFam(fam) : void 0;
|
|
1890
|
-
if (key) {
|
|
1891
|
-
relevantKeys.add(key);
|
|
1892
|
-
}
|
|
1893
|
-
});
|
|
1894
|
-
});
|
|
1895
|
-
if (relevantKeys.size === 0) {
|
|
1896
|
-
return [];
|
|
1897
|
-
}
|
|
1898
|
-
const byKey = /* @__PURE__ */ new Map();
|
|
1899
|
-
gedcom.fams()?.forEach((fam) => {
|
|
1900
|
-
if (!fam?.id) {
|
|
1901
|
-
return;
|
|
1902
|
-
}
|
|
1903
|
-
const key = coupleKeyForFam(fam);
|
|
1904
|
-
if (!key || !relevantKeys.has(key)) {
|
|
1905
|
-
return;
|
|
1906
|
-
}
|
|
1907
|
-
const list = byKey.get(key) ?? [];
|
|
1908
|
-
list.push(fam);
|
|
1909
|
-
byKey.set(key, list);
|
|
1910
|
-
});
|
|
1911
|
-
return [...byKey.entries()].filter(([, families]) => families.length > 1).map(([key, families]) => ({ key, families }));
|
|
1912
|
-
};
|
|
1913
|
-
var mergeDuplicateCoupleFamilies = (gedcom, families) => {
|
|
1914
|
-
const usable = families.filter((fam) => !!fam?.id);
|
|
1915
|
-
if (usable.length === 0) {
|
|
1916
|
-
return void 0;
|
|
1917
|
-
}
|
|
1918
|
-
if (usable.length === 1) {
|
|
1919
|
-
return usable[0];
|
|
1920
|
-
}
|
|
1921
|
-
const sorted = [...usable].sort((a, b) => {
|
|
1922
|
-
const childDiff = pointerIds(b.get("CHIL")).length - pointerIds(a.get("CHIL")).length;
|
|
1923
|
-
if (childDiff !== 0) {
|
|
1924
|
-
return childDiff;
|
|
1925
|
-
}
|
|
1926
|
-
return String(a.id).localeCompare(String(b.id));
|
|
1927
|
-
});
|
|
1928
|
-
const keep = sorted[0];
|
|
1929
|
-
const drops = sorted.slice(1);
|
|
1930
|
-
if (!keep?.id) {
|
|
1931
|
-
return void 0;
|
|
1932
|
-
}
|
|
1933
|
-
drops.forEach((drop) => {
|
|
1934
|
-
if (!drop?.id || drop.id === keep.id) {
|
|
1935
|
-
return;
|
|
1936
|
-
}
|
|
1937
|
-
pointerIds(drop.get("CHIL")).forEach((childId) => {
|
|
1938
|
-
const child = gedcom.indi(childId);
|
|
1939
|
-
if (!child) {
|
|
1940
|
-
return;
|
|
1941
|
-
}
|
|
1942
|
-
attachChildToFamily(keep, child);
|
|
1943
|
-
removePointerByValue(drop, "CHIL", childId);
|
|
1944
|
-
normalizeSinglePointer(drop, "CHIL");
|
|
1945
|
-
removePointerByValue(child, "FAMC", drop.id);
|
|
1946
|
-
normalizeSinglePointer(child, "FAMC");
|
|
1947
|
-
});
|
|
1948
|
-
const husbId = firstPointerId(drop.get("HUSB"));
|
|
1949
|
-
const wifeId = firstPointerId(drop.get("WIFE"));
|
|
1950
|
-
[husbId, wifeId].forEach((parentId) => {
|
|
1951
|
-
if (!parentId) {
|
|
1952
|
-
return;
|
|
1953
|
-
}
|
|
1954
|
-
const parent = gedcom.indi(parentId);
|
|
1955
|
-
if (parent) {
|
|
1956
|
-
removePointerByValue(parent, "FAMS", drop.id);
|
|
1957
|
-
normalizeSinglePointer(parent, "FAMS");
|
|
1958
|
-
}
|
|
1959
|
-
});
|
|
1960
|
-
gedcom.fams()?.removeItem(drop.id);
|
|
1961
|
-
});
|
|
1962
|
-
resetRelativesCache();
|
|
1963
|
-
return keep;
|
|
1964
|
-
};
|
|
1965
|
-
var pruneFamiliesByIds = (gedcom, famIds) => {
|
|
1966
|
-
const unique = [...new Set(famIds.filter(Boolean))];
|
|
1967
|
-
if (unique.length === 0) {
|
|
1968
|
-
return 0;
|
|
1969
|
-
}
|
|
1970
|
-
gedcom.indis()?.forEach((indi) => {
|
|
1971
|
-
if (!indi) {
|
|
1972
|
-
return;
|
|
1973
|
-
}
|
|
1974
|
-
unique.forEach((famId) => {
|
|
1975
|
-
removePointerByValue(indi, "FAMS", famId);
|
|
1976
|
-
removePointerByValue(indi, "FAMC", famId);
|
|
1977
|
-
});
|
|
1978
|
-
});
|
|
1979
|
-
unique.forEach((famId) => {
|
|
1980
|
-
gedcom.fams()?.removeItem(famId);
|
|
1981
|
-
});
|
|
1982
|
-
return unique.length;
|
|
1983
|
-
};
|
|
1984
|
-
var findSharedSpouseFamily = (parent, coParentId) => {
|
|
1985
|
-
let found;
|
|
1986
|
-
parent.getFamilies("FAMS")?.forEach((fam) => {
|
|
1987
|
-
if (!found && fam && familyHasParent(fam, coParentId)) {
|
|
1988
|
-
found = fam;
|
|
1989
|
-
}
|
|
1990
|
-
});
|
|
1991
|
-
return found;
|
|
1992
|
-
};
|
|
1993
|
-
var unlinkRelative = (anchor, relative, kind) => {
|
|
1994
|
-
if (!anchor.id || !relative.id || anchor.id === relative.id) {
|
|
1995
|
-
return false;
|
|
1996
|
-
}
|
|
1997
|
-
let changed = false;
|
|
1998
|
-
if (kind === "spouse") {
|
|
1999
|
-
anchor.getFamilies("FAMS")?.forEach((fam) => {
|
|
2000
|
-
if (!fam?.id || !familyHasParent(fam, relative.id)) {
|
|
2001
|
-
return;
|
|
2002
|
-
}
|
|
2003
|
-
if (firstPointerId(fam.get("HUSB")) === relative.id) {
|
|
2004
|
-
fam.remove("HUSB");
|
|
2005
|
-
changed = true;
|
|
2006
|
-
}
|
|
2007
|
-
if (firstPointerId(fam.get("WIFE")) === relative.id) {
|
|
2008
|
-
fam.remove("WIFE");
|
|
2009
|
-
changed = true;
|
|
2010
|
-
}
|
|
2011
|
-
changed = removePointerByValue(relative, "FAMS", fam.id) || changed;
|
|
2012
|
-
});
|
|
2013
|
-
} else if (kind === "parent") {
|
|
2014
|
-
anchor.getFamilies("FAMC")?.forEach((fam) => {
|
|
2015
|
-
if (!fam?.id || !familyHasParent(fam, relative.id)) {
|
|
2016
|
-
return;
|
|
2017
|
-
}
|
|
2018
|
-
if (firstPointerId(fam.get("HUSB")) === relative.id) {
|
|
2019
|
-
fam.remove("HUSB");
|
|
2020
|
-
changed = true;
|
|
2021
|
-
}
|
|
2022
|
-
if (firstPointerId(fam.get("WIFE")) === relative.id) {
|
|
2023
|
-
fam.remove("WIFE");
|
|
2024
|
-
changed = true;
|
|
2025
|
-
}
|
|
2026
|
-
changed = removePointerByValue(relative, "FAMS", fam.id) || changed;
|
|
2027
|
-
});
|
|
2028
|
-
} else if (kind === "sibling") {
|
|
2029
|
-
anchor.getFamilies("FAMC")?.forEach((fam) => {
|
|
2030
|
-
if (!fam?.id || !familyHasChild(fam, relative.id)) {
|
|
2031
|
-
return;
|
|
2032
|
-
}
|
|
2033
|
-
changed = removePointerByValue(fam, "CHIL", relative.id) || changed;
|
|
2034
|
-
changed = removePointerByValue(relative, "FAMC", fam.id) || changed;
|
|
2035
|
-
});
|
|
2036
|
-
} else {
|
|
2037
|
-
anchor.getFamilies("FAMS")?.forEach((fam) => {
|
|
2038
|
-
if (!fam?.id || !familyHasChild(fam, relative.id)) {
|
|
2039
|
-
return;
|
|
2040
|
-
}
|
|
2041
|
-
changed = removePointerByValue(fam, "CHIL", relative.id) || changed;
|
|
2042
|
-
changed = removePointerByValue(relative, "FAMC", fam.id) || changed;
|
|
2043
|
-
});
|
|
2044
|
-
}
|
|
2045
|
-
if (changed) {
|
|
2046
|
-
const gedcom = anchor.getGedcom() ?? relative.getGedcom();
|
|
2047
|
-
if (gedcom) {
|
|
2048
|
-
pruneEmptyFamilies(gedcom);
|
|
2049
|
-
}
|
|
2050
|
-
resetRelativesCache();
|
|
2051
|
-
}
|
|
2052
|
-
return changed;
|
|
2053
|
-
};
|
|
2054
|
-
var deleteIndividual = (gedcom, indiId) => {
|
|
2055
|
-
const indi = gedcom.indi(indiId);
|
|
2056
|
-
if (!indi?.id) {
|
|
2057
|
-
return false;
|
|
2058
|
-
}
|
|
2059
|
-
const famsIds = pointerIds(indi.get("FAMS"));
|
|
2060
|
-
const famcIds = pointerIds(indi.get("FAMC"));
|
|
2061
|
-
famsIds.forEach((famId) => {
|
|
2062
|
-
const fam = gedcom.fam(famId);
|
|
2063
|
-
if (!fam) {
|
|
2064
|
-
return;
|
|
2065
|
-
}
|
|
2066
|
-
if (firstPointerId(fam.get("HUSB")) === indiId) {
|
|
2067
|
-
fam.remove("HUSB");
|
|
2068
|
-
}
|
|
2069
|
-
if (firstPointerId(fam.get("WIFE")) === indiId) {
|
|
2070
|
-
fam.remove("WIFE");
|
|
2071
|
-
}
|
|
2072
|
-
});
|
|
2073
|
-
famcIds.forEach((famId) => {
|
|
2074
|
-
const fam = gedcom.fam(famId);
|
|
2075
|
-
if (fam) {
|
|
2076
|
-
removePointerByValue(fam, "CHIL", indiId);
|
|
2077
|
-
}
|
|
2078
|
-
});
|
|
2079
|
-
gedcom.fams()?.forEach((fam) => {
|
|
2080
|
-
if (fam && familyHasChild(fam, indiId)) {
|
|
2081
|
-
removePointerByValue(fam, "CHIL", indiId);
|
|
2082
|
-
}
|
|
2083
|
-
if (fam && familyHasParent(fam, indiId)) {
|
|
2084
|
-
if (firstPointerId(fam.get("HUSB")) === indiId) {
|
|
2085
|
-
fam.remove("HUSB");
|
|
2086
|
-
}
|
|
2087
|
-
if (firstPointerId(fam.get("WIFE")) === indiId) {
|
|
2088
|
-
fam.remove("WIFE");
|
|
2089
|
-
}
|
|
2090
|
-
}
|
|
2091
|
-
});
|
|
2092
|
-
gedcom.indis()?.removeItem(indiId);
|
|
2093
|
-
pruneEmptyFamilies(gedcom);
|
|
2094
|
-
resetRelativesCache();
|
|
2095
|
-
return true;
|
|
2096
|
-
};
|
|
2097
|
-
var findReusableParentChildFamily = (parent, child, options) => {
|
|
2098
|
-
if (!parent.id || !child.id) {
|
|
2099
|
-
return void 0;
|
|
2100
|
-
}
|
|
2101
|
-
const reuseParentFamilies = options?.reuseParentFamilies !== false;
|
|
2102
|
-
const gedcom = parent.getGedcom() ?? child.getGedcom();
|
|
2103
|
-
let reusableFamc;
|
|
2104
|
-
let coupleFam;
|
|
2105
|
-
let already = false;
|
|
2106
|
-
const noteCoupleWith = (coParentId) => {
|
|
2107
|
-
if (!coParentId || coParentId === parent.id || coupleFam || !parent.id) {
|
|
2108
|
-
return;
|
|
2109
|
-
}
|
|
2110
|
-
const shared = findSharedSpouseFamily(parent, coParentId);
|
|
2111
|
-
if (shared) {
|
|
2112
|
-
coupleFam = shared;
|
|
2113
|
-
}
|
|
2114
|
-
};
|
|
2115
|
-
child.getFamilies("FAMC")?.forEach((fam) => {
|
|
2116
|
-
if (!fam) {
|
|
2117
|
-
return;
|
|
2118
|
-
}
|
|
2119
|
-
if (familyHasParent(fam, parent.id) && familyHasChild(fam, child.id)) {
|
|
2120
|
-
already = true;
|
|
2121
|
-
return;
|
|
2122
|
-
}
|
|
2123
|
-
pointerIds(fam.get("HUSB")).forEach(noteCoupleWith);
|
|
2124
|
-
pointerIds(fam.get("WIFE")).forEach(noteCoupleWith);
|
|
2125
|
-
if (!reusableFamc && canAttachAsSpouse(fam, parent)) {
|
|
2126
|
-
reusableFamc = fam;
|
|
2127
|
-
}
|
|
2128
|
-
});
|
|
2129
|
-
if (already) {
|
|
2130
|
-
return "already";
|
|
2131
|
-
}
|
|
2132
|
-
if (coupleFam) {
|
|
2133
|
-
return coupleFam;
|
|
2134
|
-
}
|
|
2135
|
-
if (reusableFamc) {
|
|
2136
|
-
return reusableFamc;
|
|
2137
|
-
}
|
|
2138
|
-
if (options?.targetFamilyId && gedcom) {
|
|
2139
|
-
const target = gedcom.fam(options.targetFamilyId);
|
|
2140
|
-
if (target && (familyHasParent(target, parent.id) || canAttachAsSpouse(target, parent))) {
|
|
2141
|
-
return target;
|
|
2142
|
-
}
|
|
2143
|
-
}
|
|
2144
|
-
if (!reuseParentFamilies) {
|
|
2145
|
-
return void 0;
|
|
2146
|
-
}
|
|
2147
|
-
const parentFams = [];
|
|
2148
|
-
parent.getFamilies("FAMS")?.forEach((fam) => {
|
|
2149
|
-
if (fam) {
|
|
2150
|
-
parentFams.push(fam);
|
|
2151
|
-
}
|
|
2152
|
-
});
|
|
2153
|
-
if (parentFams.length === 1) {
|
|
2154
|
-
return parentFams[0];
|
|
2155
|
-
}
|
|
2156
|
-
return void 0;
|
|
2157
|
-
};
|
|
2158
|
-
var consolidateChildIntoFamily = (child, keep) => {
|
|
2159
|
-
if (!child.id || !keep.id) {
|
|
2160
|
-
return [];
|
|
2161
|
-
}
|
|
2162
|
-
const keepParentIds = /* @__PURE__ */ new Set([
|
|
2163
|
-
...pointerIds(keep.get("HUSB")),
|
|
2164
|
-
...pointerIds(keep.get("WIFE"))
|
|
2165
|
-
]);
|
|
2166
|
-
const removed = [];
|
|
2167
|
-
child.getFamilies("FAMC")?.forEach((fam) => {
|
|
2168
|
-
if (!fam?.id || fam.id === keep.id) {
|
|
2169
|
-
return;
|
|
2170
|
-
}
|
|
2171
|
-
const famParentIds = [
|
|
2172
|
-
...pointerIds(fam.get("HUSB")),
|
|
2173
|
-
...pointerIds(fam.get("WIFE"))
|
|
2174
|
-
];
|
|
2175
|
-
if (famParentIds.length === 0 || !famParentIds.every((id) => keepParentIds.has(id))) {
|
|
2176
|
-
return;
|
|
2177
|
-
}
|
|
2178
|
-
removePointerByValue(fam, "CHIL", child.id);
|
|
2179
|
-
normalizeSinglePointer(fam, "CHIL");
|
|
2180
|
-
removePointerByValue(child, "FAMC", fam.id);
|
|
2181
|
-
normalizeSinglePointer(child, "FAMC");
|
|
2182
|
-
removed.push(fam.id);
|
|
2183
|
-
});
|
|
2184
|
-
const gedcom = child.getGedcom() ?? keep.getGedcom();
|
|
2185
|
-
if (gedcom && removed.length > 0) {
|
|
2186
|
-
pruneEmptyFamilies(gedcom);
|
|
2187
|
-
}
|
|
2188
|
-
if (removed.length > 0) {
|
|
2189
|
-
resetRelativesCache();
|
|
2190
|
-
}
|
|
2191
|
-
return removed;
|
|
2192
|
-
};
|
|
2193
|
-
|
|
2194
|
-
// src/factories/date-locale-factory.ts
|
|
2195
|
-
var dateLocaleProvider = () => void 0;
|
|
2196
|
-
var setDateLocaleProvider = (provider) => {
|
|
2197
|
-
dateLocaleProvider = provider;
|
|
2198
|
-
};
|
|
2199
|
-
var getDateLocale = () => {
|
|
2200
|
-
const result = dateLocaleProvider();
|
|
2201
|
-
return result;
|
|
2202
|
-
};
|
|
2203
|
-
var resetDateLocaleProvider = () => {
|
|
2204
|
-
dateLocaleProvider = () => void 0;
|
|
2205
|
-
};
|
|
2206
|
-
|
|
2207
|
-
// src/factories/i18n-factory.ts
|
|
2208
|
-
var i18nProvider = (key) => key;
|
|
2209
|
-
var setI18nProvider = (provider) => {
|
|
2210
|
-
i18nProvider = provider;
|
|
2211
|
-
};
|
|
2212
|
-
var getI18n = () => {
|
|
2213
|
-
return i18nProvider;
|
|
2214
|
-
};
|
|
2215
|
-
var resetI18nProvider = () => {
|
|
2216
|
-
i18nProvider = (key) => key;
|
|
2217
|
-
};
|
|
2218
|
-
var i18n = {
|
|
2219
|
-
t: (key, options) => i18nProvider(key, options)
|
|
2220
|
-
};
|
|
2221
|
-
|
|
2222
|
-
// src/kinship-translator/translators.ts
|
|
2223
|
-
var translators_exports = {};
|
|
2224
|
-
__export(translators_exports, {
|
|
2225
|
-
de: () => KinshipTranslatorDe,
|
|
2226
|
-
en: () => KinshipTranslatorEn,
|
|
2227
|
-
es: () => KinshipTranslatorEs,
|
|
2228
|
-
fr: () => KinshipTranslatorFr,
|
|
2229
|
-
hu: () => KinshipTranslatorHU,
|
|
2230
|
-
ja: () => KinshipTranslatorJa,
|
|
2231
|
-
ru: () => KinshipTranslatorRu,
|
|
2232
|
-
zh: () => KinshipTranslatorZh
|
|
2233
|
-
});
|
|
2234
|
-
|
|
2235
|
-
// src/constants/filters.ts
|
|
2236
|
-
var EVERY = {};
|
|
2237
|
-
var FEMALE = {
|
|
2238
|
-
SEX: "F"
|
|
2239
|
-
};
|
|
2240
|
-
var MALE = {
|
|
2241
|
-
SEX: "M"
|
|
2242
|
-
};
|
|
2243
|
-
var ADOPTED = {
|
|
2244
|
-
PEDI: "adopted" /* ADOPTED */
|
|
2245
|
-
};
|
|
2246
|
-
var BIRTH = {
|
|
2247
|
-
PEDI: "birth" /* BIRTH */
|
|
2248
|
-
};
|
|
2249
|
-
var FOSTER = {
|
|
2250
|
-
PEDI: "foster" /* FOSTER */
|
|
2251
|
-
};
|
|
2252
|
-
var SEALING = {
|
|
2253
|
-
PEDI: "sealing" /* SEALING */
|
|
2254
|
-
};
|
|
2255
|
-
var STEP = {
|
|
2256
|
-
PEDI: "step" /* STEP */
|
|
2257
|
-
};
|
|
2258
|
-
var BIOLOGICAL = {
|
|
2259
|
-
PEDI: "biological" /* BIOLOGICAL */
|
|
2260
|
-
};
|
|
2261
|
-
var FRIEND = {
|
|
2262
|
-
PART: "friend" /* FRIEND */
|
|
2263
|
-
};
|
|
2264
|
-
var OTHER = {
|
|
2265
|
-
PART: "other" /* OTHER */
|
|
2266
|
-
};
|
|
2267
|
-
var PARTNER = {
|
|
2268
|
-
PART: "partner" /* PARTNER */
|
|
2269
|
-
};
|
|
2270
|
-
var SINGLE = {
|
|
2271
|
-
PART: "single" /* SINGLE */
|
|
2272
|
-
};
|
|
2273
|
-
var SPOUSE = {
|
|
2274
|
-
PART: "spouse" /* SPOUSE */
|
|
2275
|
-
};
|
|
2276
|
-
var UNKOWN = {
|
|
2277
|
-
PART: "unknown" /* UNKOWN */
|
|
2278
|
-
};
|
|
2279
|
-
|
|
2280
|
-
// src/utils/get-family-with.ts
|
|
2281
|
-
var getFamilyWith = (person1, person2, famType = "FAMS") => {
|
|
2282
|
-
return person1?.get(famType)?.toValueList().find((fam) => {
|
|
2283
|
-
const family = fam;
|
|
2284
|
-
return famType === "FAMC" || family?.HUSB?.value === person2 || family?.WIFE?.value === person2;
|
|
2285
|
-
});
|
|
2286
|
-
};
|
|
2287
|
-
|
|
2288
|
-
// src/constants/orders.ts
|
|
2289
|
-
var DEFAULT = {};
|
|
2290
|
-
var BIRTH_ASC = {
|
|
2291
|
-
"BIRT.DATE": {
|
|
2292
|
-
direction: "ASC",
|
|
2293
|
-
getter: (value, raw) => {
|
|
2294
|
-
if (isCommonDate(raw) && raw.rawValue) {
|
|
2295
|
-
return raw.rawValue.getTime();
|
|
2296
|
-
}
|
|
2297
|
-
return new Date(value).getTime();
|
|
2298
|
-
}
|
|
2299
|
-
}
|
|
2300
|
-
};
|
|
2301
|
-
var BIRTH_DESC = {
|
|
2302
|
-
"BIRT.DATE": {
|
|
2303
|
-
direction: "DESC",
|
|
2304
|
-
getter: (value, raw) => {
|
|
2305
|
-
if (isCommonDate(raw) && raw.rawValue) {
|
|
2306
|
-
return raw.rawValue.getTime();
|
|
2307
|
-
}
|
|
2308
|
-
return new Date(value).getTime();
|
|
2309
|
-
}
|
|
2310
|
-
}
|
|
2311
|
-
};
|
|
2312
|
-
var DEATH_ASC = {
|
|
2313
|
-
"DEAT.DATE": {
|
|
2314
|
-
direction: "ASC",
|
|
2315
|
-
getter: (value, raw) => {
|
|
2316
|
-
if (isCommonDate(raw) && raw.rawValue) {
|
|
2317
|
-
return raw.rawValue.getTime();
|
|
2318
|
-
}
|
|
2319
|
-
return new Date(value).getTime();
|
|
2320
|
-
}
|
|
1468
|
+
};
|
|
1469
|
+
var DEATH_ASC = {
|
|
1470
|
+
"DEAT.DATE": {
|
|
1471
|
+
direction: "ASC",
|
|
1472
|
+
getter: (value, raw) => {
|
|
1473
|
+
if (isCommonDate(raw) && raw.rawValue) {
|
|
1474
|
+
return raw.rawValue.getTime();
|
|
1475
|
+
}
|
|
1476
|
+
return new Date(value).getTime();
|
|
1477
|
+
}
|
|
2321
1478
|
}
|
|
2322
1479
|
};
|
|
2323
1480
|
var DEATH_DESC = {
|
|
@@ -2482,46 +1639,303 @@ var getNameAscAndBirth = (nameOrder = "first-last") => (itemA, keyA, itemB, keyB
|
|
|
2482
1639
|
if (nameSort !== 0) {
|
|
2483
1640
|
return nameSort;
|
|
2484
1641
|
}
|
|
2485
|
-
return getBirthAsc(itemA, keyA, itemB);
|
|
1642
|
+
return getBirthAsc(itemA, keyA, itemB);
|
|
1643
|
+
};
|
|
1644
|
+
var getMarriageAsc = (person, famType = "FAMS") => (itemA, _keyA, itemB, _keyB) => {
|
|
1645
|
+
if (!person && famType === "FAMS") {
|
|
1646
|
+
return 0;
|
|
1647
|
+
}
|
|
1648
|
+
const familyA = getFamilyWith(itemA, person);
|
|
1649
|
+
const familyB = getFamilyWith(itemB, person);
|
|
1650
|
+
const marriageA = familyA?.MARR?.DATE?.rawValue;
|
|
1651
|
+
const marriageB = familyB?.MARR?.DATE?.rawValue;
|
|
1652
|
+
if (marriageA?.getTime() === marriageB?.getTime()) {
|
|
1653
|
+
return 0;
|
|
1654
|
+
}
|
|
1655
|
+
if (!marriageA || marriageB && marriageA > marriageB) {
|
|
1656
|
+
return 1;
|
|
1657
|
+
}
|
|
1658
|
+
return -1;
|
|
1659
|
+
};
|
|
1660
|
+
var getMarriageAscAndChildBirth = (person) => (itemA, keyA, itemB, keyB) => {
|
|
1661
|
+
const marriageSort = getMarriageAsc(person)(itemA, keyA, itemB, keyB);
|
|
1662
|
+
if (marriageSort !== 0) {
|
|
1663
|
+
return marriageSort;
|
|
1664
|
+
}
|
|
1665
|
+
const familyA = getFamilyWith(itemA, person);
|
|
1666
|
+
const familyB = getFamilyWith(itemB, person);
|
|
1667
|
+
const childA = familyA?.getChildren().orderBy(BIRTH_ASC).index(0);
|
|
1668
|
+
const childB = familyB?.getChildren().orderBy(BIRTH_ASC).index(0);
|
|
1669
|
+
return getBirthAsc(childA, keyA, childB);
|
|
1670
|
+
};
|
|
1671
|
+
var getMarriageAscAndBirth = (person) => (itemA, keyA, itemB, keyB) => {
|
|
1672
|
+
const marriageSort = getMarriageAsc(person, "FAMC")(
|
|
1673
|
+
itemA,
|
|
1674
|
+
keyA,
|
|
1675
|
+
itemB,
|
|
1676
|
+
keyB
|
|
1677
|
+
);
|
|
1678
|
+
if (marriageSort !== 0) {
|
|
1679
|
+
return marriageSort;
|
|
1680
|
+
}
|
|
1681
|
+
return getBirthAsc(itemA, keyA, itemB);
|
|
1682
|
+
};
|
|
1683
|
+
var getGedcomId = (gedcom) => {
|
|
1684
|
+
if (!gedcom) {
|
|
1685
|
+
return "unknown";
|
|
1686
|
+
}
|
|
1687
|
+
const treeId = gedcom.getTreeId?.() || "";
|
|
1688
|
+
const treeName = gedcom.getTreeName?.() || "";
|
|
1689
|
+
const sanitizedName = treeName.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
1690
|
+
if (treeId && sanitizedName) {
|
|
1691
|
+
return `${treeId}_${sanitizedName}`;
|
|
1692
|
+
} else if (treeId) {
|
|
1693
|
+
return treeId;
|
|
1694
|
+
} else if (sanitizedName) {
|
|
1695
|
+
return sanitizedName;
|
|
1696
|
+
}
|
|
1697
|
+
return `gedcom_${gedcom.refcount}`;
|
|
1698
|
+
};
|
|
1699
|
+
var caches = {
|
|
1700
|
+
pathCache: {},
|
|
1701
|
+
relativesOnDegreeCache: {},
|
|
1702
|
+
relativesOnLevelCache: {},
|
|
1703
|
+
profilePictureCache: {}
|
|
1704
|
+
};
|
|
1705
|
+
var cacheDbs;
|
|
1706
|
+
var getCacheDbs = () => {
|
|
1707
|
+
if (!cacheDbs) {
|
|
1708
|
+
const getInstance = getCacheManagerFactory();
|
|
1709
|
+
cacheDbs = {
|
|
1710
|
+
pathCache: getInstance(
|
|
1711
|
+
"ftv",
|
|
1712
|
+
"Main",
|
|
1713
|
+
"path",
|
|
1714
|
+
true
|
|
1715
|
+
),
|
|
1716
|
+
relativesOnDegreeCache: getInstance("ftv", "Main", "path", true),
|
|
1717
|
+
relativesOnLevelCache: getInstance(
|
|
1718
|
+
"ftv",
|
|
1719
|
+
"Main",
|
|
1720
|
+
"path",
|
|
1721
|
+
true
|
|
1722
|
+
),
|
|
1723
|
+
profilePictureCache: getInstance(
|
|
1724
|
+
"ftv",
|
|
1725
|
+
"Main",
|
|
1726
|
+
"images",
|
|
1727
|
+
false
|
|
1728
|
+
)
|
|
1729
|
+
};
|
|
1730
|
+
}
|
|
1731
|
+
return cacheDbs;
|
|
1732
|
+
};
|
|
1733
|
+
var storeCache = {
|
|
1734
|
+
// NOTE: pathCache, relativesOnLevelCache, and relativesOnDegreeCache are intentionally
|
|
1735
|
+
// kept in memory only. These debounced functions exist to satisfy the type system
|
|
1736
|
+
// but are never called.
|
|
1737
|
+
pathCache: debounce((value) => {
|
|
1738
|
+
if (value) {
|
|
1739
|
+
getCacheDbs().pathCache.setItem(value);
|
|
1740
|
+
}
|
|
1741
|
+
}, 50),
|
|
1742
|
+
relativesOnLevelCache: debounce((value) => {
|
|
1743
|
+
if (value) {
|
|
1744
|
+
getCacheDbs().relativesOnLevelCache.setItem(value);
|
|
1745
|
+
}
|
|
1746
|
+
}, 50),
|
|
1747
|
+
relativesOnDegreeCache: debounce((value) => {
|
|
1748
|
+
if (value) {
|
|
1749
|
+
getCacheDbs().relativesOnDegreeCache.setItem(value);
|
|
1750
|
+
}
|
|
1751
|
+
}, 50),
|
|
1752
|
+
// Image bytes are stored as one IndexedDB record per photo.
|
|
1753
|
+
profilePictureCache: debounce((value) => {
|
|
1754
|
+
}, 100)
|
|
1755
|
+
};
|
|
1756
|
+
var cacheInitialized = false;
|
|
1757
|
+
var initializeCache = async () => {
|
|
1758
|
+
if (cacheInitialized) {
|
|
1759
|
+
return;
|
|
1760
|
+
}
|
|
1761
|
+
cacheInitialized = true;
|
|
1762
|
+
};
|
|
1763
|
+
var resetRelativesCache = () => {
|
|
1764
|
+
caches.relativesOnDegreeCache = {};
|
|
1765
|
+
caches.relativesOnLevelCache = {};
|
|
1766
|
+
};
|
|
1767
|
+
var relativesCache = (cacheKey) => (gedcom, key, subKey, value) => {
|
|
1768
|
+
const gedcomId = getGedcomId(gedcom);
|
|
1769
|
+
const fullKey = `${gedcomId}:${key}`;
|
|
1770
|
+
const cache = caches[cacheKey];
|
|
1771
|
+
if (!cache) {
|
|
1772
|
+
caches[cacheKey] = {};
|
|
1773
|
+
}
|
|
1774
|
+
if (value) {
|
|
1775
|
+
const typedCache2 = caches[cacheKey];
|
|
1776
|
+
if (!typedCache2[fullKey]) {
|
|
1777
|
+
typedCache2[fullKey] = {};
|
|
1778
|
+
}
|
|
1779
|
+
typedCache2[fullKey][subKey] = value;
|
|
1780
|
+
return typedCache2[fullKey][subKey];
|
|
1781
|
+
}
|
|
1782
|
+
const typedCache = caches[cacheKey];
|
|
1783
|
+
return typedCache?.[fullKey]?.[subKey];
|
|
1784
|
+
};
|
|
1785
|
+
var pathCache = (gedcom, key, value) => {
|
|
1786
|
+
const gedcomId = getGedcomId(gedcom);
|
|
1787
|
+
const fullKey = `${gedcomId}:${key}`;
|
|
1788
|
+
if (!caches.pathCache) {
|
|
1789
|
+
caches.pathCache = {};
|
|
1790
|
+
}
|
|
1791
|
+
if (value && caches.pathCache) {
|
|
1792
|
+
caches.pathCache[fullKey] = value;
|
|
1793
|
+
return caches.pathCache[fullKey];
|
|
1794
|
+
}
|
|
1795
|
+
return caches.pathCache?.[fullKey];
|
|
1796
|
+
};
|
|
1797
|
+
var profilePictureCache = (gedcom, key, value) => {
|
|
1798
|
+
const gedcomId = getGedcomId(gedcom);
|
|
1799
|
+
const fullKey = `${gedcomId}:${key}`;
|
|
1800
|
+
if (!caches.profilePictureCache) {
|
|
1801
|
+
caches.profilePictureCache = {};
|
|
1802
|
+
}
|
|
1803
|
+
if (value && caches.profilePictureCache) {
|
|
1804
|
+
caches.profilePictureCache[fullKey] = value;
|
|
1805
|
+
storeCache.profilePictureCache(caches.profilePictureCache);
|
|
1806
|
+
return caches.profilePictureCache[fullKey];
|
|
1807
|
+
}
|
|
1808
|
+
const cached = caches.profilePictureCache?.[fullKey];
|
|
1809
|
+
return cached;
|
|
1810
|
+
};
|
|
1811
|
+
var isNonBiologicalPath = (path) => path.some(
|
|
1812
|
+
(item) => item.relation && item.relation !== "biological" /* BIOLOGICAL */
|
|
1813
|
+
);
|
|
1814
|
+
var invertHop = (kinship) => {
|
|
1815
|
+
if (kinship === "parent") {
|
|
1816
|
+
return "child";
|
|
1817
|
+
}
|
|
1818
|
+
if (kinship === "child") {
|
|
1819
|
+
return "parent";
|
|
1820
|
+
}
|
|
1821
|
+
return kinship;
|
|
1822
|
+
};
|
|
1823
|
+
var hopRelation = (from, toIndi, kinship, inherited) => {
|
|
1824
|
+
if (kinship === "parent" || kinship === "child") {
|
|
1825
|
+
const parent = kinship === "parent" ? toIndi : from.indi;
|
|
1826
|
+
const child = kinship === "parent" ? from.indi : toIndi;
|
|
1827
|
+
const currentRelation = child.getParentType(parent);
|
|
1828
|
+
if (currentRelation && currentRelation !== "biological" /* BIOLOGICAL */) {
|
|
1829
|
+
return currentRelation;
|
|
1830
|
+
}
|
|
1831
|
+
}
|
|
1832
|
+
if (inherited && inherited !== "biological" /* BIOLOGICAL */) {
|
|
1833
|
+
return inherited;
|
|
1834
|
+
}
|
|
1835
|
+
return void 0;
|
|
1836
|
+
};
|
|
1837
|
+
var rebuildPathFromHops = (hops, skipRelation = false) => {
|
|
1838
|
+
if (hops.length === 0) {
|
|
1839
|
+
return [];
|
|
1840
|
+
}
|
|
1841
|
+
const path = [
|
|
1842
|
+
{
|
|
1843
|
+
indi: hops[0].indi,
|
|
1844
|
+
kinship: "self",
|
|
1845
|
+
level: 0,
|
|
1846
|
+
levelUp: 0,
|
|
1847
|
+
levelDown: 0,
|
|
1848
|
+
degree: 0
|
|
1849
|
+
}
|
|
1850
|
+
];
|
|
1851
|
+
for (let i = 1; i < hops.length; i++) {
|
|
1852
|
+
const prev = path[i - 1];
|
|
1853
|
+
const { indi, kinship } = hops[i];
|
|
1854
|
+
const relation = skipRelation ? void 0 : hopRelation(prev, indi, kinship, prev.relation);
|
|
1855
|
+
if (kinship === "parent") {
|
|
1856
|
+
path.push({
|
|
1857
|
+
indi,
|
|
1858
|
+
kinship,
|
|
1859
|
+
relation,
|
|
1860
|
+
level: prev.level + 1,
|
|
1861
|
+
levelUp: prev.levelUp + 1,
|
|
1862
|
+
levelDown: prev.levelDown,
|
|
1863
|
+
degree: prev.degree
|
|
1864
|
+
});
|
|
1865
|
+
continue;
|
|
1866
|
+
}
|
|
1867
|
+
if (kinship === "child") {
|
|
1868
|
+
path.push({
|
|
1869
|
+
indi,
|
|
1870
|
+
kinship,
|
|
1871
|
+
relation,
|
|
1872
|
+
level: prev.level - 1,
|
|
1873
|
+
levelUp: prev.levelUp,
|
|
1874
|
+
levelDown: prev.levelDown + 1,
|
|
1875
|
+
degree: prev.levelUp ? prev.level > 0 ? prev.levelUp - prev.level + 1 : prev.levelDown - Math.abs(prev.level) : 0
|
|
1876
|
+
});
|
|
1877
|
+
continue;
|
|
1878
|
+
}
|
|
1879
|
+
path.push({
|
|
1880
|
+
indi,
|
|
1881
|
+
kinship,
|
|
1882
|
+
relation,
|
|
1883
|
+
level: prev.level,
|
|
1884
|
+
levelUp: prev.levelUp,
|
|
1885
|
+
levelDown: prev.levelDown,
|
|
1886
|
+
degree: prev.degree
|
|
1887
|
+
});
|
|
1888
|
+
}
|
|
1889
|
+
return path;
|
|
2486
1890
|
};
|
|
2487
|
-
var
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
const familyB = getFamilyWith(itemB, person);
|
|
2493
|
-
const marriageA = familyA?.MARR?.DATE?.rawValue;
|
|
2494
|
-
const marriageB = familyB?.MARR?.DATE?.rawValue;
|
|
2495
|
-
if (marriageA?.getTime() === marriageB?.getTime()) {
|
|
2496
|
-
return 0;
|
|
2497
|
-
}
|
|
2498
|
-
if (!marriageA || marriageB && marriageA > marriageB) {
|
|
2499
|
-
return 1;
|
|
1891
|
+
var storePathIfBetter = (gedcom, fromId, toId, path) => {
|
|
1892
|
+
const key = `${fromId}|${toId}`;
|
|
1893
|
+
const existing = pathCache(gedcom, key);
|
|
1894
|
+
if (existing && (!isNonBiologicalPath(existing) || isNonBiologicalPath(path))) {
|
|
1895
|
+
return;
|
|
2500
1896
|
}
|
|
2501
|
-
|
|
1897
|
+
pathCache(gedcom, key, path);
|
|
2502
1898
|
};
|
|
2503
|
-
var
|
|
2504
|
-
const
|
|
2505
|
-
if (
|
|
2506
|
-
return
|
|
1899
|
+
var cacheDiscoveredPath = (gedcom, path) => {
|
|
1900
|
+
const n = path.length;
|
|
1901
|
+
if (n < 2) {
|
|
1902
|
+
return;
|
|
2507
1903
|
}
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
1904
|
+
for (let i = 0; i < n; i++) {
|
|
1905
|
+
const fromId = path[i].indi.id;
|
|
1906
|
+
if (!fromId) {
|
|
1907
|
+
continue;
|
|
1908
|
+
}
|
|
1909
|
+
for (let j = i + 1; j < n; j++) {
|
|
1910
|
+
const toId = path[j].indi.id;
|
|
1911
|
+
if (!toId) {
|
|
1912
|
+
continue;
|
|
1913
|
+
}
|
|
1914
|
+
const isOriginalPair = i === 0 && j === n - 1;
|
|
1915
|
+
const isDirectHop = j === i + 1;
|
|
1916
|
+
const slice = path.slice(i, j + 1);
|
|
1917
|
+
const sliceMixed = isNonBiologicalPath(slice);
|
|
1918
|
+
if (!isOriginalPair && !isDirectHop && sliceMixed) {
|
|
1919
|
+
continue;
|
|
1920
|
+
}
|
|
1921
|
+
const forward = i === 0 ? slice : rebuildPathFromHops(slice, !sliceMixed);
|
|
1922
|
+
const reverseHops = [
|
|
1923
|
+
{
|
|
1924
|
+
indi: slice[slice.length - 1].indi,
|
|
1925
|
+
kinship: "self"
|
|
1926
|
+
}
|
|
1927
|
+
];
|
|
1928
|
+
for (let k = slice.length - 2; k >= 0; k--) {
|
|
1929
|
+
reverseHops.push({
|
|
1930
|
+
indi: slice[k].indi,
|
|
1931
|
+
kinship: invertHop(slice[k + 1].kinship)
|
|
1932
|
+
});
|
|
1933
|
+
}
|
|
1934
|
+
const reverse = rebuildPathFromHops(reverseHops, !sliceMixed);
|
|
1935
|
+
storePathIfBetter(gedcom, fromId, toId, forward);
|
|
1936
|
+
storePathIfBetter(gedcom, toId, fromId, reverse);
|
|
1937
|
+
}
|
|
2523
1938
|
}
|
|
2524
|
-
return getBirthAsc(itemA, keyA, itemB);
|
|
2525
1939
|
};
|
|
2526
1940
|
|
|
2527
1941
|
// src/utils/get-all-prop.ts
|
|
@@ -2757,6 +2171,180 @@ var dateFormatter = (indi, showMarriages = false, showDays = false, showPlaces =
|
|
|
2757
2171
|
};
|
|
2758
2172
|
};
|
|
2759
2173
|
|
|
2174
|
+
// src/utils/fact-edit.ts
|
|
2175
|
+
var SINGLETON_TAGS = /* @__PURE__ */ new Set(["BIRT", "DEAT", "SSN", "SEX", "DSCR"]);
|
|
2176
|
+
var firstRecord = (node) => {
|
|
2177
|
+
if (!node) {
|
|
2178
|
+
return void 0;
|
|
2179
|
+
}
|
|
2180
|
+
if (node instanceof List) {
|
|
2181
|
+
return node.index(0);
|
|
2182
|
+
}
|
|
2183
|
+
return node.index(0) ?? node;
|
|
2184
|
+
};
|
|
2185
|
+
var setDateOn = (gedcom, owner, parent, date) => {
|
|
2186
|
+
const trimmed = date.trim();
|
|
2187
|
+
if (!trimmed) {
|
|
2188
|
+
return;
|
|
2189
|
+
}
|
|
2190
|
+
let dateNode = parent.get("DATE");
|
|
2191
|
+
if (!dateNode || dateNode instanceof List) {
|
|
2192
|
+
dateNode = createCommonDate(gedcom, void 0, owner, parent);
|
|
2193
|
+
dateNode.type = "DATE";
|
|
2194
|
+
parent.set("DATE", dateNode);
|
|
2195
|
+
}
|
|
2196
|
+
dateNode.value = trimmed;
|
|
2197
|
+
};
|
|
2198
|
+
var fillFact = (gedcom, owner, event, input) => {
|
|
2199
|
+
if (input.value?.trim()) {
|
|
2200
|
+
event.value = input.value.trim();
|
|
2201
|
+
}
|
|
2202
|
+
if (input.type?.trim()) {
|
|
2203
|
+
event.set("TYPE", input.type.trim());
|
|
2204
|
+
}
|
|
2205
|
+
if (input.date) {
|
|
2206
|
+
setDateOn(gedcom, owner, event, input.date);
|
|
2207
|
+
}
|
|
2208
|
+
if (input.place?.trim()) {
|
|
2209
|
+
event.set("PLAC", input.place.trim());
|
|
2210
|
+
}
|
|
2211
|
+
if (input.note?.trim()) {
|
|
2212
|
+
event.set("NOTE", input.note.trim());
|
|
2213
|
+
}
|
|
2214
|
+
};
|
|
2215
|
+
var updateFactRecord = (owner, event, input) => {
|
|
2216
|
+
const gedcom = owner.getGedcom();
|
|
2217
|
+
if (!gedcom) {
|
|
2218
|
+
return event;
|
|
2219
|
+
}
|
|
2220
|
+
const asOwner = owner;
|
|
2221
|
+
if (input.value !== void 0) {
|
|
2222
|
+
const trimmed = input.value.trim();
|
|
2223
|
+
if (trimmed) {
|
|
2224
|
+
event.value = trimmed;
|
|
2225
|
+
} else {
|
|
2226
|
+
event.removeValue();
|
|
2227
|
+
}
|
|
2228
|
+
}
|
|
2229
|
+
if (input.type !== void 0) {
|
|
2230
|
+
const trimmed = input.type.trim();
|
|
2231
|
+
if (trimmed) {
|
|
2232
|
+
event.set("TYPE", trimmed);
|
|
2233
|
+
} else {
|
|
2234
|
+
event.remove("TYPE");
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
if (input.date !== void 0) {
|
|
2238
|
+
const trimmed = input.date.trim();
|
|
2239
|
+
if (trimmed) {
|
|
2240
|
+
setDateOn(gedcom, asOwner, event, trimmed);
|
|
2241
|
+
} else {
|
|
2242
|
+
event.remove("DATE");
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
if (input.place !== void 0) {
|
|
2246
|
+
const trimmed = input.place.trim();
|
|
2247
|
+
if (trimmed) {
|
|
2248
|
+
event.set("PLAC", trimmed);
|
|
2249
|
+
} else {
|
|
2250
|
+
event.remove("PLAC");
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
if (input.note !== void 0) {
|
|
2254
|
+
const trimmed = input.note.trim();
|
|
2255
|
+
if (trimmed) {
|
|
2256
|
+
event.set("NOTE", trimmed);
|
|
2257
|
+
} else {
|
|
2258
|
+
event.remove("NOTE");
|
|
2259
|
+
}
|
|
2260
|
+
}
|
|
2261
|
+
return event;
|
|
2262
|
+
};
|
|
2263
|
+
var setFamilyMarriage = (fam, input) => {
|
|
2264
|
+
const existing = firstRecord(fam.get("MARR"));
|
|
2265
|
+
if (existing) {
|
|
2266
|
+
return updateFactRecord(fam, existing, {
|
|
2267
|
+
date: input.date,
|
|
2268
|
+
place: input.place
|
|
2269
|
+
});
|
|
2270
|
+
}
|
|
2271
|
+
return addFamilyFact(fam, {
|
|
2272
|
+
tag: "MARR",
|
|
2273
|
+
date: input.date,
|
|
2274
|
+
place: input.place
|
|
2275
|
+
});
|
|
2276
|
+
};
|
|
2277
|
+
var addIndividualFact = (indi, input) => {
|
|
2278
|
+
const gedcom = indi.getGedcom();
|
|
2279
|
+
if (!gedcom) {
|
|
2280
|
+
return void 0;
|
|
2281
|
+
}
|
|
2282
|
+
const tag = input.tag;
|
|
2283
|
+
let event = SINGLETON_TAGS.has(tag) ? firstRecord(indi.get(tag)) : void 0;
|
|
2284
|
+
if (!event) {
|
|
2285
|
+
event = createCommon(gedcom, void 0, indi);
|
|
2286
|
+
event.type = tag;
|
|
2287
|
+
if (SINGLETON_TAGS.has(tag)) {
|
|
2288
|
+
indi.set(tag, event);
|
|
2289
|
+
} else {
|
|
2290
|
+
indi.assign(tag, event);
|
|
2291
|
+
}
|
|
2292
|
+
}
|
|
2293
|
+
fillFact(gedcom, indi, event, input);
|
|
2294
|
+
return event;
|
|
2295
|
+
};
|
|
2296
|
+
var addFamilyFact = (fam, input) => {
|
|
2297
|
+
const gedcom = fam.getGedcom();
|
|
2298
|
+
if (!gedcom) {
|
|
2299
|
+
return void 0;
|
|
2300
|
+
}
|
|
2301
|
+
const event = createCommon(gedcom, void 0, fam);
|
|
2302
|
+
event.type = input.tag;
|
|
2303
|
+
fam.assign(input.tag, event);
|
|
2304
|
+
fillFact(gedcom, fam, event, input);
|
|
2305
|
+
return event;
|
|
2306
|
+
};
|
|
2307
|
+
var setCauseOfDeath = (indi, text) => {
|
|
2308
|
+
const trimmed = text.trim();
|
|
2309
|
+
if (!trimmed) {
|
|
2310
|
+
return void 0;
|
|
2311
|
+
}
|
|
2312
|
+
const death = firstRecord(indi.get("DEAT")) || addIndividualFact(indi, { tag: "DEAT", value: "Y" });
|
|
2313
|
+
if (!death) {
|
|
2314
|
+
return void 0;
|
|
2315
|
+
}
|
|
2316
|
+
death.set("CAUS", trimmed);
|
|
2317
|
+
return death;
|
|
2318
|
+
};
|
|
2319
|
+
var setDeceased = (indi, deceased) => {
|
|
2320
|
+
if (!deceased) {
|
|
2321
|
+
indi.remove("DEAT");
|
|
2322
|
+
return;
|
|
2323
|
+
}
|
|
2324
|
+
if (firstRecord(indi.get("DEAT"))) {
|
|
2325
|
+
return;
|
|
2326
|
+
}
|
|
2327
|
+
addIndividualFact(indi, { tag: "DEAT", value: "Y" });
|
|
2328
|
+
};
|
|
2329
|
+
var addNonEvent = (owner, input) => {
|
|
2330
|
+
const gedcom = owner.getGedcom();
|
|
2331
|
+
const eventType = input.event?.trim().toUpperCase();
|
|
2332
|
+
if (!gedcom || !eventType) {
|
|
2333
|
+
return void 0;
|
|
2334
|
+
}
|
|
2335
|
+
const no = createCommon(gedcom, void 0, owner);
|
|
2336
|
+
no.type = "NO";
|
|
2337
|
+
no.value = eventType;
|
|
2338
|
+
if (input.date?.trim()) {
|
|
2339
|
+
setDateOn(gedcom, owner, no, input.date);
|
|
2340
|
+
}
|
|
2341
|
+
if (input.note?.trim()) {
|
|
2342
|
+
no.set("NOTE", input.note.trim());
|
|
2343
|
+
}
|
|
2344
|
+
owner.assign("NO", no);
|
|
2345
|
+
return no;
|
|
2346
|
+
};
|
|
2347
|
+
|
|
2760
2348
|
// src/utils/get-places.ts
|
|
2761
2349
|
var PlaceType = /* @__PURE__ */ ((PlaceType2) => {
|
|
2762
2350
|
PlaceType2["All"] = "ALL";
|
|
@@ -9125,209 +8713,643 @@ var CommonDate = class extends Common {
|
|
|
9125
8713
|
if (!formatted) {
|
|
9126
8714
|
return formatted;
|
|
9127
8715
|
}
|
|
9128
|
-
const note = this.NOTE?.value?.trim();
|
|
9129
|
-
const qualifier = note ? EXPORT_QUALIFIERS[note] : void 0;
|
|
9130
|
-
const standardized = qualifier ? formatted.replace(note, qualifier) : formatted;
|
|
9131
|
-
const withMonths = standardized.replace(
|
|
9132
|
-
GEDCOM_MONTHS,
|
|
9133
|
-
(month) => month.toUpperCase()
|
|
9134
|
-
);
|
|
9135
|
-
if (this._calendar && this._calendar !== "GREGORIAN") {
|
|
9136
|
-
return `${this._calendar} ${withMonths}`;
|
|
8716
|
+
const note = this.NOTE?.value?.trim();
|
|
8717
|
+
const qualifier = note ? EXPORT_QUALIFIERS[note] : void 0;
|
|
8718
|
+
const standardized = qualifier ? formatted.replace(note, qualifier) : formatted;
|
|
8719
|
+
const withMonths = standardized.replace(
|
|
8720
|
+
GEDCOM_MONTHS,
|
|
8721
|
+
(month) => month.toUpperCase()
|
|
8722
|
+
);
|
|
8723
|
+
if (this._calendar && this._calendar !== "GREGORIAN") {
|
|
8724
|
+
return `${this._calendar} ${withMonths}`;
|
|
8725
|
+
}
|
|
8726
|
+
return withMonths;
|
|
8727
|
+
}
|
|
8728
|
+
toGedcomLines(tag, level = 0, options) {
|
|
8729
|
+
const internal = new RegExp(
|
|
8730
|
+
`^${level} (DAY|MONTH|YEAR)( |$)|^${level} NOTE (Abt\\.|Bef\\.|Aft\\.)$`
|
|
8731
|
+
);
|
|
8732
|
+
return super.toGedcomLines(tag, level, options).filter((line) => !internal.test(line));
|
|
8733
|
+
}
|
|
8734
|
+
inRange(range, trueIfNoYear = false) {
|
|
8735
|
+
return inRange(this.YEAR?.value, range, trueIfNoYear);
|
|
8736
|
+
}
|
|
8737
|
+
};
|
|
8738
|
+
var createCommonDate = (gedcom, id, main, parent) => {
|
|
8739
|
+
return createProxy(
|
|
8740
|
+
new CommonDate(gedcom, id, main, parent)
|
|
8741
|
+
);
|
|
8742
|
+
};
|
|
8743
|
+
var isCommonDate = (value) => {
|
|
8744
|
+
return !!value && value !== null && typeof value === "object" && "_date" in value;
|
|
8745
|
+
};
|
|
8746
|
+
|
|
8747
|
+
// src/utils/family-edit.ts
|
|
8748
|
+
var GEDCOM_MONTHS2 = [
|
|
8749
|
+
"JAN",
|
|
8750
|
+
"FEB",
|
|
8751
|
+
"MAR",
|
|
8752
|
+
"APR",
|
|
8753
|
+
"MAY",
|
|
8754
|
+
"JUN",
|
|
8755
|
+
"JUL",
|
|
8756
|
+
"AUG",
|
|
8757
|
+
"SEP",
|
|
8758
|
+
"OCT",
|
|
8759
|
+
"NOV",
|
|
8760
|
+
"DEC"
|
|
8761
|
+
];
|
|
8762
|
+
var CREATED_AT_TAG = "_CREATED_AT";
|
|
8763
|
+
var stampCreatedAt = (gedcom, indi, when = /* @__PURE__ */ new Date()) => {
|
|
8764
|
+
const existing = indi.get(CREATED_AT_TAG);
|
|
8765
|
+
if (isCommonDate(existing) && existing.rawValue instanceof Date && !Number.isNaN(existing.rawValue.getTime())) {
|
|
8766
|
+
return;
|
|
8767
|
+
}
|
|
8768
|
+
const dateNode = createCommonDate(gedcom, void 0, indi, indi);
|
|
8769
|
+
dateNode.type = CREATED_AT_TAG;
|
|
8770
|
+
dateNode.value = `${when.getDate()} ${GEDCOM_MONTHS2[when.getMonth()]} ${when.getFullYear()}`;
|
|
8771
|
+
indi.set(CREATED_AT_TAG, dateNode);
|
|
8772
|
+
};
|
|
8773
|
+
var refTypeForTag = (tag) => {
|
|
8774
|
+
if (tag === "FAMS" || tag === "FAMC") return "FAM";
|
|
8775
|
+
return "INDI";
|
|
8776
|
+
};
|
|
8777
|
+
var normalizeSinglePointer = (owner, tag) => {
|
|
8778
|
+
const node = owner.get(tag);
|
|
8779
|
+
if (!node) return;
|
|
8780
|
+
if (node instanceof List && node.length === 1) {
|
|
8781
|
+
const only = node.index(0);
|
|
8782
|
+
if (only) {
|
|
8783
|
+
owner.set(tag, only);
|
|
8784
|
+
return;
|
|
8785
|
+
}
|
|
8786
|
+
const raw = node.values()[0];
|
|
8787
|
+
if (typeof raw === "string") {
|
|
8788
|
+
const gedcom = owner.getGedcom?.();
|
|
8789
|
+
if (gedcom) {
|
|
8790
|
+
owner.set(tag, makePointer(gedcom, owner, raw, refTypeForTag(tag)));
|
|
8791
|
+
}
|
|
8792
|
+
}
|
|
8793
|
+
}
|
|
8794
|
+
};
|
|
8795
|
+
var PEDIGREE_VALUES = [
|
|
8796
|
+
"birth" /* BIRTH */,
|
|
8797
|
+
"adopted" /* ADOPTED */,
|
|
8798
|
+
"foster" /* FOSTER */,
|
|
8799
|
+
"step" /* STEP */,
|
|
8800
|
+
"sealing" /* SEALING */
|
|
8801
|
+
];
|
|
8802
|
+
var toGedcomPedigree = (value) => {
|
|
8803
|
+
const normalized = String(value || "birth" /* BIRTH */).toLowerCase();
|
|
8804
|
+
if (normalized === "biological" /* BIOLOGICAL */ || normalized === "birth" /* BIRTH */) {
|
|
8805
|
+
return "birth" /* BIRTH */;
|
|
8806
|
+
}
|
|
8807
|
+
const match = PEDIGREE_VALUES.find((item) => item === normalized);
|
|
8808
|
+
return match ?? "birth" /* BIRTH */;
|
|
8809
|
+
};
|
|
8810
|
+
var pointerIds = (tag) => {
|
|
8811
|
+
if (!tag) {
|
|
8812
|
+
return [];
|
|
8813
|
+
}
|
|
8814
|
+
if (tag instanceof List) {
|
|
8815
|
+
return tag.values().map((item) => item?.toValue?.()).filter((value2) => !!value2);
|
|
8816
|
+
}
|
|
8817
|
+
const value = tag.toValue?.();
|
|
8818
|
+
return value ? [String(value)] : [];
|
|
8819
|
+
};
|
|
8820
|
+
var firstPointerId = (tag) => pointerIds(tag)[0];
|
|
8821
|
+
var makePointer = (gedcom, parent, value, refType) => {
|
|
8822
|
+
const pointer = createCommon(gedcom, void 0, parent);
|
|
8823
|
+
pointer.value = value;
|
|
8824
|
+
pointer.refType = refType;
|
|
8825
|
+
return pointer;
|
|
8826
|
+
};
|
|
8827
|
+
var nextRecordId = (ids, prefix) => {
|
|
8828
|
+
let max = 0;
|
|
8829
|
+
ids.forEach((id) => {
|
|
8830
|
+
const match = String(id).match(/(\d+)/);
|
|
8831
|
+
const n = match ? Number.parseInt(match[1], 10) : 0;
|
|
8832
|
+
if (n > max) {
|
|
8833
|
+
max = n;
|
|
8834
|
+
}
|
|
8835
|
+
});
|
|
8836
|
+
return `@${prefix}${max + 1}@`;
|
|
8837
|
+
};
|
|
8838
|
+
var familyHasParent = (fam, indiId) => pointerIds(fam.get("HUSB")).includes(indiId) || pointerIds(fam.get("WIFE")).includes(indiId);
|
|
8839
|
+
var familyHasChild = (fam, indiId) => pointerIds(fam.get("CHIL")).includes(indiId);
|
|
8840
|
+
var spouseTagFor = (indi, fam) => {
|
|
8841
|
+
const husbId = firstPointerId(fam.get("HUSB"));
|
|
8842
|
+
const wifeId = firstPointerId(fam.get("WIFE"));
|
|
8843
|
+
if (husbId === indi.id) {
|
|
8844
|
+
return "HUSB";
|
|
8845
|
+
}
|
|
8846
|
+
if (wifeId === indi.id) {
|
|
8847
|
+
return "WIFE";
|
|
8848
|
+
}
|
|
8849
|
+
if (indi.isFemale()) {
|
|
8850
|
+
return wifeId && wifeId !== indi.id ? "HUSB" : "WIFE";
|
|
8851
|
+
}
|
|
8852
|
+
if (indi.isMale()) {
|
|
8853
|
+
return husbId && husbId !== indi.id ? "WIFE" : "HUSB";
|
|
8854
|
+
}
|
|
8855
|
+
return husbId ? "WIFE" : "HUSB";
|
|
8856
|
+
};
|
|
8857
|
+
var canAttachAsSpouse = (fam, indi) => {
|
|
8858
|
+
if (!indi.id) {
|
|
8859
|
+
return false;
|
|
8860
|
+
}
|
|
8861
|
+
if (familyHasParent(fam, indi.id)) {
|
|
8862
|
+
return true;
|
|
8863
|
+
}
|
|
8864
|
+
const tag = spouseTagFor(indi, fam);
|
|
8865
|
+
const occupied = firstPointerId(fam.get(tag));
|
|
8866
|
+
return !occupied || occupied === indi.id;
|
|
8867
|
+
};
|
|
8868
|
+
var pointerByValue = (tag, id) => {
|
|
8869
|
+
if (!tag) {
|
|
8870
|
+
return void 0;
|
|
8871
|
+
}
|
|
8872
|
+
const fromValues = tag.toValueList?.().item(id);
|
|
8873
|
+
if (fromValues) {
|
|
8874
|
+
return fromValues;
|
|
8875
|
+
}
|
|
8876
|
+
return tag.toList()?.values().find((item) => item?.toValue?.() === id);
|
|
8877
|
+
};
|
|
8878
|
+
var setChildPedigree = (fam, child, pedigree, parent) => {
|
|
8879
|
+
if (!fam.id || !child.id) {
|
|
8880
|
+
return;
|
|
8881
|
+
}
|
|
8882
|
+
const pedi = toGedcomPedigree(pedigree);
|
|
8883
|
+
const famc = pointerByValue(child.get("FAMC"), fam.id);
|
|
8884
|
+
if (famc) {
|
|
8885
|
+
famc.set("PEDI", pedi);
|
|
8886
|
+
}
|
|
8887
|
+
const chil = pointerByValue(fam.get("CHIL"), child.id);
|
|
8888
|
+
if (!chil) {
|
|
8889
|
+
return;
|
|
8890
|
+
}
|
|
8891
|
+
const setFather = !parent || parent.isMale() || parent.isUnknownSex();
|
|
8892
|
+
const setMother = !parent || parent.isFemale() || parent.isUnknownSex();
|
|
8893
|
+
if (setFather) {
|
|
8894
|
+
chil.set("_FREL", pedi);
|
|
8895
|
+
}
|
|
8896
|
+
if (setMother) {
|
|
8897
|
+
chil.set("_MREL", pedi);
|
|
8898
|
+
}
|
|
8899
|
+
};
|
|
8900
|
+
var attachSpouseToFamily = (fam, indi) => {
|
|
8901
|
+
const gedcom = fam.getGedcom() ?? indi.getGedcom();
|
|
8902
|
+
if (!indi.id || !fam.id || !gedcom) {
|
|
8903
|
+
return false;
|
|
8904
|
+
}
|
|
8905
|
+
if (!canAttachAsSpouse(fam, indi)) {
|
|
8906
|
+
return false;
|
|
8907
|
+
}
|
|
8908
|
+
const tag = spouseTagFor(indi, fam);
|
|
8909
|
+
if (firstPointerId(fam.get(tag)) !== indi.id) {
|
|
8910
|
+
fam.set(tag, makePointer(gedcom, fam, indi.id, "INDI"));
|
|
8911
|
+
}
|
|
8912
|
+
indi.assign("FAMS", makePointer(gedcom, indi, fam.id, "FAM"), true);
|
|
8913
|
+
normalizeSinglePointer(indi, "FAMS");
|
|
8914
|
+
normalizeSinglePointer(fam, spouseTagFor(indi, fam));
|
|
8915
|
+
resetRelativesCache();
|
|
8916
|
+
return true;
|
|
8917
|
+
};
|
|
8918
|
+
var attachChildToFamily = (fam, child, pedigree, parent) => {
|
|
8919
|
+
const gedcom = fam.getGedcom() ?? child.getGedcom();
|
|
8920
|
+
if (!child.id || !fam.id || !gedcom) {
|
|
8921
|
+
return false;
|
|
8922
|
+
}
|
|
8923
|
+
if (!familyHasChild(fam, child.id)) {
|
|
8924
|
+
fam.assign("CHIL", makePointer(gedcom, fam, child.id, "INDI"), true);
|
|
8925
|
+
}
|
|
8926
|
+
const existingFamc = pointerByValue(child.get("FAMC"), fam.id);
|
|
8927
|
+
if (!existingFamc) {
|
|
8928
|
+
child.assign("FAMC", makePointer(gedcom, child, fam.id, "FAM"), true);
|
|
8929
|
+
}
|
|
8930
|
+
setChildPedigree(fam, child, pedigree, parent);
|
|
8931
|
+
normalizeSinglePointer(child, "FAMC");
|
|
8932
|
+
normalizeSinglePointer(fam, "CHIL");
|
|
8933
|
+
resetRelativesCache();
|
|
8934
|
+
return true;
|
|
8935
|
+
};
|
|
8936
|
+
var removePointerByValue = (owner, tag, targetId) => {
|
|
8937
|
+
const node = owner.get(tag);
|
|
8938
|
+
if (!node) {
|
|
8939
|
+
return false;
|
|
8940
|
+
}
|
|
8941
|
+
if (node instanceof List) {
|
|
8942
|
+
const keysToRemove = [];
|
|
8943
|
+
node.entries().forEach(([key, item]) => {
|
|
8944
|
+
if (item?.toValue?.() === targetId || item?.id === targetId || String(key) === targetId) {
|
|
8945
|
+
keysToRemove.push(key);
|
|
8946
|
+
}
|
|
8947
|
+
});
|
|
8948
|
+
keysToRemove.forEach((key) => {
|
|
8949
|
+
node.removeItem(key);
|
|
8950
|
+
});
|
|
8951
|
+
if (node.length === 0) {
|
|
8952
|
+
owner.remove(tag);
|
|
8953
|
+
}
|
|
8954
|
+
return keysToRemove.length > 0;
|
|
8955
|
+
}
|
|
8956
|
+
if (node.toValue?.() === targetId) {
|
|
8957
|
+
owner.remove(tag);
|
|
8958
|
+
return true;
|
|
8959
|
+
}
|
|
8960
|
+
const asList = node.toList?.();
|
|
8961
|
+
if (asList && asList.length > 0) {
|
|
8962
|
+
const keysToRemove = [];
|
|
8963
|
+
asList.entries().forEach(([key, item]) => {
|
|
8964
|
+
if (item?.toValue?.() === targetId || item?.id === targetId) {
|
|
8965
|
+
keysToRemove.push(key);
|
|
8966
|
+
}
|
|
8967
|
+
});
|
|
8968
|
+
if (keysToRemove.length === asList.length) {
|
|
8969
|
+
owner.remove(tag);
|
|
8970
|
+
return true;
|
|
8971
|
+
}
|
|
8972
|
+
if (keysToRemove.length > 0) {
|
|
8973
|
+
const remaining = asList.values().filter((item) => item?.toValue?.() !== targetId);
|
|
8974
|
+
if (remaining.length === 1 && remaining[0]) {
|
|
8975
|
+
owner.set(tag, remaining[0]);
|
|
8976
|
+
} else {
|
|
8977
|
+
owner.set(tag, new List(remaining));
|
|
8978
|
+
}
|
|
8979
|
+
return true;
|
|
9137
8980
|
}
|
|
9138
|
-
return withMonths;
|
|
9139
8981
|
}
|
|
9140
|
-
|
|
9141
|
-
|
|
9142
|
-
|
|
9143
|
-
|
|
9144
|
-
|
|
8982
|
+
return false;
|
|
8983
|
+
};
|
|
8984
|
+
var familyMemberCount = (fam) => {
|
|
8985
|
+
let count = 0;
|
|
8986
|
+
if (firstPointerId(fam.get("HUSB"))) {
|
|
8987
|
+
count += 1;
|
|
9145
8988
|
}
|
|
9146
|
-
|
|
9147
|
-
|
|
8989
|
+
if (firstPointerId(fam.get("WIFE"))) {
|
|
8990
|
+
count += 1;
|
|
9148
8991
|
}
|
|
8992
|
+
count += pointerIds(fam.get("CHIL")).length;
|
|
8993
|
+
return count;
|
|
9149
8994
|
};
|
|
9150
|
-
var
|
|
9151
|
-
|
|
9152
|
-
|
|
9153
|
-
)
|
|
8995
|
+
var isDegenerateFamily = (fam) => familyMemberCount(fam) <= 1;
|
|
8996
|
+
var pruneEmptyFamilies = (gedcom) => {
|
|
8997
|
+
const emptyIds = [];
|
|
8998
|
+
gedcom.fams()?.forEach((fam, id) => {
|
|
8999
|
+
if (fam && isDegenerateFamily(fam) && id) {
|
|
9000
|
+
emptyIds.push(id);
|
|
9001
|
+
}
|
|
9002
|
+
});
|
|
9003
|
+
if (emptyIds.length === 0) {
|
|
9004
|
+
return [];
|
|
9005
|
+
}
|
|
9006
|
+
gedcom.indis()?.forEach((indi) => {
|
|
9007
|
+
if (!indi) {
|
|
9008
|
+
return;
|
|
9009
|
+
}
|
|
9010
|
+
emptyIds.forEach((famId) => {
|
|
9011
|
+
removePointerByValue(indi, "FAMS", famId);
|
|
9012
|
+
removePointerByValue(indi, "FAMC", famId);
|
|
9013
|
+
});
|
|
9014
|
+
});
|
|
9015
|
+
emptyIds.forEach((famId) => {
|
|
9016
|
+
gedcom.fams()?.removeItem(famId);
|
|
9017
|
+
});
|
|
9018
|
+
return emptyIds;
|
|
9154
9019
|
};
|
|
9155
|
-
var
|
|
9156
|
-
|
|
9020
|
+
var findDegenerateFamiliesForIndi = (indi) => {
|
|
9021
|
+
const found = [];
|
|
9022
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9023
|
+
["FAMC", "FAMS"].forEach((pointer) => {
|
|
9024
|
+
indi.getFamilies(pointer)?.forEach((fam) => {
|
|
9025
|
+
if (!fam?.id || seen.has(fam.id) || !isDegenerateFamily(fam)) {
|
|
9026
|
+
return;
|
|
9027
|
+
}
|
|
9028
|
+
seen.add(fam.id);
|
|
9029
|
+
found.push(fam);
|
|
9030
|
+
});
|
|
9031
|
+
});
|
|
9032
|
+
return found;
|
|
9157
9033
|
};
|
|
9158
|
-
|
|
9159
|
-
|
|
9160
|
-
|
|
9161
|
-
|
|
9162
|
-
if (!node) {
|
|
9034
|
+
var coupleKeyForFam = (fam) => {
|
|
9035
|
+
const husb = firstPointerId(fam.get("HUSB"));
|
|
9036
|
+
const wife = firstPointerId(fam.get("WIFE"));
|
|
9037
|
+
if (!husb || !wife) {
|
|
9163
9038
|
return void 0;
|
|
9164
9039
|
}
|
|
9165
|
-
|
|
9166
|
-
return node.index(0);
|
|
9167
|
-
}
|
|
9168
|
-
return node.index(0) ?? node;
|
|
9040
|
+
return husb < wife ? `${husb}|${wife}` : `${wife}|${husb}`;
|
|
9169
9041
|
};
|
|
9170
|
-
var
|
|
9171
|
-
const
|
|
9172
|
-
if (!
|
|
9173
|
-
return;
|
|
9042
|
+
var findDuplicateCoupleFamiliesForIndi = (indi) => {
|
|
9043
|
+
const gedcom = indi.getGedcom();
|
|
9044
|
+
if (!gedcom) {
|
|
9045
|
+
return [];
|
|
9174
9046
|
}
|
|
9175
|
-
|
|
9176
|
-
|
|
9177
|
-
|
|
9178
|
-
|
|
9179
|
-
|
|
9047
|
+
const relevantKeys = /* @__PURE__ */ new Set();
|
|
9048
|
+
["FAMC", "FAMS"].forEach((pointer) => {
|
|
9049
|
+
indi.getFamilies(pointer)?.forEach((fam) => {
|
|
9050
|
+
const key = fam ? coupleKeyForFam(fam) : void 0;
|
|
9051
|
+
if (key) {
|
|
9052
|
+
relevantKeys.add(key);
|
|
9053
|
+
}
|
|
9054
|
+
});
|
|
9055
|
+
});
|
|
9056
|
+
if (relevantKeys.size === 0) {
|
|
9057
|
+
return [];
|
|
9180
9058
|
}
|
|
9181
|
-
|
|
9059
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
9060
|
+
gedcom.fams()?.forEach((fam) => {
|
|
9061
|
+
if (!fam?.id) {
|
|
9062
|
+
return;
|
|
9063
|
+
}
|
|
9064
|
+
const key = coupleKeyForFam(fam);
|
|
9065
|
+
if (!key || !relevantKeys.has(key)) {
|
|
9066
|
+
return;
|
|
9067
|
+
}
|
|
9068
|
+
const list = byKey.get(key) ?? [];
|
|
9069
|
+
list.push(fam);
|
|
9070
|
+
byKey.set(key, list);
|
|
9071
|
+
});
|
|
9072
|
+
return [...byKey.entries()].filter(([, families]) => families.length > 1).map(([key, families]) => ({ key, families }));
|
|
9182
9073
|
};
|
|
9183
|
-
var
|
|
9184
|
-
|
|
9185
|
-
|
|
9074
|
+
var mergeDuplicateCoupleFamilies = (gedcom, families) => {
|
|
9075
|
+
const usable = families.filter((fam) => !!fam?.id);
|
|
9076
|
+
if (usable.length === 0) {
|
|
9077
|
+
return void 0;
|
|
9186
9078
|
}
|
|
9187
|
-
if (
|
|
9188
|
-
|
|
9079
|
+
if (usable.length === 1) {
|
|
9080
|
+
return usable[0];
|
|
9189
9081
|
}
|
|
9190
|
-
|
|
9191
|
-
|
|
9082
|
+
const sorted = [...usable].sort((a, b) => {
|
|
9083
|
+
const childDiff = pointerIds(b.get("CHIL")).length - pointerIds(a.get("CHIL")).length;
|
|
9084
|
+
if (childDiff !== 0) {
|
|
9085
|
+
return childDiff;
|
|
9086
|
+
}
|
|
9087
|
+
return String(a.id).localeCompare(String(b.id));
|
|
9088
|
+
});
|
|
9089
|
+
const keep = sorted[0];
|
|
9090
|
+
const drops = sorted.slice(1);
|
|
9091
|
+
if (!keep?.id) {
|
|
9092
|
+
return void 0;
|
|
9192
9093
|
}
|
|
9193
|
-
|
|
9194
|
-
|
|
9094
|
+
drops.forEach((drop) => {
|
|
9095
|
+
if (!drop?.id || drop.id === keep.id) {
|
|
9096
|
+
return;
|
|
9097
|
+
}
|
|
9098
|
+
pointerIds(drop.get("CHIL")).forEach((childId) => {
|
|
9099
|
+
const child = gedcom.indi(childId);
|
|
9100
|
+
if (!child) {
|
|
9101
|
+
return;
|
|
9102
|
+
}
|
|
9103
|
+
attachChildToFamily(keep, child);
|
|
9104
|
+
removePointerByValue(drop, "CHIL", childId);
|
|
9105
|
+
normalizeSinglePointer(drop, "CHIL");
|
|
9106
|
+
removePointerByValue(child, "FAMC", drop.id);
|
|
9107
|
+
normalizeSinglePointer(child, "FAMC");
|
|
9108
|
+
});
|
|
9109
|
+
const husbId = firstPointerId(drop.get("HUSB"));
|
|
9110
|
+
const wifeId = firstPointerId(drop.get("WIFE"));
|
|
9111
|
+
[husbId, wifeId].forEach((parentId) => {
|
|
9112
|
+
if (!parentId) {
|
|
9113
|
+
return;
|
|
9114
|
+
}
|
|
9115
|
+
const parent = gedcom.indi(parentId);
|
|
9116
|
+
if (parent) {
|
|
9117
|
+
removePointerByValue(parent, "FAMS", drop.id);
|
|
9118
|
+
normalizeSinglePointer(parent, "FAMS");
|
|
9119
|
+
}
|
|
9120
|
+
});
|
|
9121
|
+
gedcom.fams()?.removeItem(drop.id);
|
|
9122
|
+
});
|
|
9123
|
+
resetRelativesCache();
|
|
9124
|
+
return keep;
|
|
9125
|
+
};
|
|
9126
|
+
var pruneFamiliesByIds = (gedcom, famIds) => {
|
|
9127
|
+
const unique = [...new Set(famIds.filter(Boolean))];
|
|
9128
|
+
if (unique.length === 0) {
|
|
9129
|
+
return 0;
|
|
9130
|
+
}
|
|
9131
|
+
gedcom.indis()?.forEach((indi) => {
|
|
9132
|
+
if (!indi) {
|
|
9133
|
+
return;
|
|
9134
|
+
}
|
|
9135
|
+
unique.forEach((famId) => {
|
|
9136
|
+
removePointerByValue(indi, "FAMS", famId);
|
|
9137
|
+
removePointerByValue(indi, "FAMC", famId);
|
|
9138
|
+
});
|
|
9139
|
+
});
|
|
9140
|
+
unique.forEach((famId) => {
|
|
9141
|
+
gedcom.fams()?.removeItem(famId);
|
|
9142
|
+
});
|
|
9143
|
+
return unique.length;
|
|
9144
|
+
};
|
|
9145
|
+
var findSharedSpouseFamily = (parent, coParentId) => {
|
|
9146
|
+
let found;
|
|
9147
|
+
parent.getFamilies("FAMS")?.forEach((fam) => {
|
|
9148
|
+
if (!found && fam && familyHasParent(fam, coParentId)) {
|
|
9149
|
+
found = fam;
|
|
9150
|
+
}
|
|
9151
|
+
});
|
|
9152
|
+
return found;
|
|
9153
|
+
};
|
|
9154
|
+
var unlinkRelative = (anchor, relative, kind) => {
|
|
9155
|
+
if (!anchor.id || !relative.id || anchor.id === relative.id) {
|
|
9156
|
+
return false;
|
|
9157
|
+
}
|
|
9158
|
+
let changed = false;
|
|
9159
|
+
if (kind === "spouse") {
|
|
9160
|
+
anchor.getFamilies("FAMS")?.forEach((fam) => {
|
|
9161
|
+
if (!fam?.id || !familyHasParent(fam, relative.id)) {
|
|
9162
|
+
return;
|
|
9163
|
+
}
|
|
9164
|
+
if (firstPointerId(fam.get("HUSB")) === relative.id) {
|
|
9165
|
+
fam.remove("HUSB");
|
|
9166
|
+
changed = true;
|
|
9167
|
+
}
|
|
9168
|
+
if (firstPointerId(fam.get("WIFE")) === relative.id) {
|
|
9169
|
+
fam.remove("WIFE");
|
|
9170
|
+
changed = true;
|
|
9171
|
+
}
|
|
9172
|
+
changed = removePointerByValue(relative, "FAMS", fam.id) || changed;
|
|
9173
|
+
});
|
|
9174
|
+
} else if (kind === "parent") {
|
|
9175
|
+
anchor.getFamilies("FAMC")?.forEach((fam) => {
|
|
9176
|
+
if (!fam?.id || !familyHasParent(fam, relative.id)) {
|
|
9177
|
+
return;
|
|
9178
|
+
}
|
|
9179
|
+
if (firstPointerId(fam.get("HUSB")) === relative.id) {
|
|
9180
|
+
fam.remove("HUSB");
|
|
9181
|
+
changed = true;
|
|
9182
|
+
}
|
|
9183
|
+
if (firstPointerId(fam.get("WIFE")) === relative.id) {
|
|
9184
|
+
fam.remove("WIFE");
|
|
9185
|
+
changed = true;
|
|
9186
|
+
}
|
|
9187
|
+
changed = removePointerByValue(relative, "FAMS", fam.id) || changed;
|
|
9188
|
+
});
|
|
9189
|
+
} else if (kind === "sibling") {
|
|
9190
|
+
anchor.getFamilies("FAMC")?.forEach((fam) => {
|
|
9191
|
+
if (!fam?.id || !familyHasChild(fam, relative.id)) {
|
|
9192
|
+
return;
|
|
9193
|
+
}
|
|
9194
|
+
changed = removePointerByValue(fam, "CHIL", relative.id) || changed;
|
|
9195
|
+
changed = removePointerByValue(relative, "FAMC", fam.id) || changed;
|
|
9196
|
+
});
|
|
9197
|
+
} else {
|
|
9198
|
+
anchor.getFamilies("FAMS")?.forEach((fam) => {
|
|
9199
|
+
if (!fam?.id || !familyHasChild(fam, relative.id)) {
|
|
9200
|
+
return;
|
|
9201
|
+
}
|
|
9202
|
+
changed = removePointerByValue(fam, "CHIL", relative.id) || changed;
|
|
9203
|
+
changed = removePointerByValue(relative, "FAMC", fam.id) || changed;
|
|
9204
|
+
});
|
|
9195
9205
|
}
|
|
9196
|
-
if (
|
|
9197
|
-
|
|
9206
|
+
if (changed) {
|
|
9207
|
+
const gedcom = anchor.getGedcom() ?? relative.getGedcom();
|
|
9208
|
+
if (gedcom) {
|
|
9209
|
+
pruneEmptyFamilies(gedcom);
|
|
9210
|
+
}
|
|
9211
|
+
resetRelativesCache();
|
|
9198
9212
|
}
|
|
9213
|
+
return changed;
|
|
9199
9214
|
};
|
|
9200
|
-
var
|
|
9201
|
-
const
|
|
9202
|
-
if (!
|
|
9203
|
-
return
|
|
9215
|
+
var deleteIndividual = (gedcom, indiId) => {
|
|
9216
|
+
const indi = gedcom.indi(indiId);
|
|
9217
|
+
if (!indi?.id) {
|
|
9218
|
+
return false;
|
|
9204
9219
|
}
|
|
9205
|
-
const
|
|
9206
|
-
|
|
9207
|
-
|
|
9208
|
-
|
|
9209
|
-
|
|
9210
|
-
|
|
9211
|
-
event.removeValue();
|
|
9220
|
+
const famsIds = pointerIds(indi.get("FAMS"));
|
|
9221
|
+
const famcIds = pointerIds(indi.get("FAMC"));
|
|
9222
|
+
famsIds.forEach((famId) => {
|
|
9223
|
+
const fam = gedcom.fam(famId);
|
|
9224
|
+
if (!fam) {
|
|
9225
|
+
return;
|
|
9212
9226
|
}
|
|
9213
|
-
|
|
9214
|
-
|
|
9215
|
-
const trimmed = input.type.trim();
|
|
9216
|
-
if (trimmed) {
|
|
9217
|
-
event.set("TYPE", trimmed);
|
|
9218
|
-
} else {
|
|
9219
|
-
event.remove("TYPE");
|
|
9227
|
+
if (firstPointerId(fam.get("HUSB")) === indiId) {
|
|
9228
|
+
fam.remove("HUSB");
|
|
9220
9229
|
}
|
|
9221
|
-
|
|
9222
|
-
|
|
9223
|
-
const trimmed = input.date.trim();
|
|
9224
|
-
if (trimmed) {
|
|
9225
|
-
setDateOn(gedcom, asOwner, event, trimmed);
|
|
9226
|
-
} else {
|
|
9227
|
-
event.remove("DATE");
|
|
9230
|
+
if (firstPointerId(fam.get("WIFE")) === indiId) {
|
|
9231
|
+
fam.remove("WIFE");
|
|
9228
9232
|
}
|
|
9229
|
-
}
|
|
9230
|
-
|
|
9231
|
-
const
|
|
9232
|
-
if (
|
|
9233
|
-
|
|
9234
|
-
} else {
|
|
9235
|
-
event.remove("PLAC");
|
|
9233
|
+
});
|
|
9234
|
+
famcIds.forEach((famId) => {
|
|
9235
|
+
const fam = gedcom.fam(famId);
|
|
9236
|
+
if (fam) {
|
|
9237
|
+
removePointerByValue(fam, "CHIL", indiId);
|
|
9236
9238
|
}
|
|
9237
|
-
}
|
|
9238
|
-
|
|
9239
|
-
|
|
9240
|
-
|
|
9241
|
-
|
|
9242
|
-
|
|
9243
|
-
|
|
9239
|
+
});
|
|
9240
|
+
gedcom.fams()?.forEach((fam) => {
|
|
9241
|
+
if (fam && familyHasChild(fam, indiId)) {
|
|
9242
|
+
removePointerByValue(fam, "CHIL", indiId);
|
|
9243
|
+
}
|
|
9244
|
+
if (fam && familyHasParent(fam, indiId)) {
|
|
9245
|
+
if (firstPointerId(fam.get("HUSB")) === indiId) {
|
|
9246
|
+
fam.remove("HUSB");
|
|
9247
|
+
}
|
|
9248
|
+
if (firstPointerId(fam.get("WIFE")) === indiId) {
|
|
9249
|
+
fam.remove("WIFE");
|
|
9250
|
+
}
|
|
9244
9251
|
}
|
|
9245
|
-
}
|
|
9246
|
-
return event;
|
|
9247
|
-
};
|
|
9248
|
-
var setFamilyMarriage = (fam, input) => {
|
|
9249
|
-
const existing = firstRecord(fam.get("MARR"));
|
|
9250
|
-
if (existing) {
|
|
9251
|
-
return updateFactRecord(fam, existing, {
|
|
9252
|
-
date: input.date,
|
|
9253
|
-
place: input.place
|
|
9254
|
-
});
|
|
9255
|
-
}
|
|
9256
|
-
return addFamilyFact(fam, {
|
|
9257
|
-
tag: "MARR",
|
|
9258
|
-
date: input.date,
|
|
9259
|
-
place: input.place
|
|
9260
9252
|
});
|
|
9253
|
+
gedcom.indis()?.removeItem(indiId);
|
|
9254
|
+
pruneEmptyFamilies(gedcom);
|
|
9255
|
+
resetRelativesCache();
|
|
9256
|
+
return true;
|
|
9261
9257
|
};
|
|
9262
|
-
var
|
|
9263
|
-
|
|
9264
|
-
if (!gedcom) {
|
|
9258
|
+
var findReusableParentChildFamily = (parent, child, options) => {
|
|
9259
|
+
if (!parent.id || !child.id) {
|
|
9265
9260
|
return void 0;
|
|
9266
9261
|
}
|
|
9267
|
-
const
|
|
9268
|
-
|
|
9269
|
-
|
|
9270
|
-
|
|
9271
|
-
|
|
9272
|
-
|
|
9273
|
-
|
|
9274
|
-
|
|
9275
|
-
|
|
9262
|
+
const reuseParentFamilies = options?.reuseParentFamilies !== false;
|
|
9263
|
+
const gedcom = parent.getGedcom() ?? child.getGedcom();
|
|
9264
|
+
let reusableFamc;
|
|
9265
|
+
let coupleFam;
|
|
9266
|
+
let already = false;
|
|
9267
|
+
const noteCoupleWith = (coParentId) => {
|
|
9268
|
+
if (!coParentId || coParentId === parent.id || coupleFam || !parent.id) {
|
|
9269
|
+
return;
|
|
9270
|
+
}
|
|
9271
|
+
const shared = findSharedSpouseFamily(parent, coParentId);
|
|
9272
|
+
if (shared) {
|
|
9273
|
+
coupleFam = shared;
|
|
9274
|
+
}
|
|
9275
|
+
};
|
|
9276
|
+
child.getFamilies("FAMC")?.forEach((fam) => {
|
|
9277
|
+
if (!fam) {
|
|
9278
|
+
return;
|
|
9279
|
+
}
|
|
9280
|
+
if (familyHasParent(fam, parent.id) && familyHasChild(fam, child.id)) {
|
|
9281
|
+
already = true;
|
|
9282
|
+
return;
|
|
9283
|
+
}
|
|
9284
|
+
pointerIds(fam.get("HUSB")).forEach(noteCoupleWith);
|
|
9285
|
+
pointerIds(fam.get("WIFE")).forEach(noteCoupleWith);
|
|
9286
|
+
if (!reusableFamc && canAttachAsSpouse(fam, parent)) {
|
|
9287
|
+
reusableFamc = fam;
|
|
9276
9288
|
}
|
|
9289
|
+
});
|
|
9290
|
+
if (already) {
|
|
9291
|
+
return "already";
|
|
9277
9292
|
}
|
|
9278
|
-
|
|
9279
|
-
|
|
9280
|
-
};
|
|
9281
|
-
var addFamilyFact = (fam, input) => {
|
|
9282
|
-
const gedcom = fam.getGedcom();
|
|
9283
|
-
if (!gedcom) {
|
|
9284
|
-
return void 0;
|
|
9293
|
+
if (coupleFam) {
|
|
9294
|
+
return coupleFam;
|
|
9285
9295
|
}
|
|
9286
|
-
|
|
9287
|
-
|
|
9288
|
-
fam.assign(input.tag, event);
|
|
9289
|
-
fillFact(gedcom, fam, event, input);
|
|
9290
|
-
return event;
|
|
9291
|
-
};
|
|
9292
|
-
var setCauseOfDeath = (indi, text) => {
|
|
9293
|
-
const trimmed = text.trim();
|
|
9294
|
-
if (!trimmed) {
|
|
9295
|
-
return void 0;
|
|
9296
|
+
if (reusableFamc) {
|
|
9297
|
+
return reusableFamc;
|
|
9296
9298
|
}
|
|
9297
|
-
|
|
9298
|
-
|
|
9299
|
-
|
|
9299
|
+
if (options?.targetFamilyId && gedcom) {
|
|
9300
|
+
const target = gedcom.fam(options.targetFamilyId);
|
|
9301
|
+
if (target && (familyHasParent(target, parent.id) || canAttachAsSpouse(target, parent))) {
|
|
9302
|
+
return target;
|
|
9303
|
+
}
|
|
9300
9304
|
}
|
|
9301
|
-
|
|
9302
|
-
|
|
9303
|
-
};
|
|
9304
|
-
var setDeceased = (indi, deceased) => {
|
|
9305
|
-
if (!deceased) {
|
|
9306
|
-
indi.remove("DEAT");
|
|
9307
|
-
return;
|
|
9305
|
+
if (!reuseParentFamilies) {
|
|
9306
|
+
return void 0;
|
|
9308
9307
|
}
|
|
9309
|
-
|
|
9310
|
-
|
|
9308
|
+
const parentFams = [];
|
|
9309
|
+
parent.getFamilies("FAMS")?.forEach((fam) => {
|
|
9310
|
+
if (fam) {
|
|
9311
|
+
parentFams.push(fam);
|
|
9312
|
+
}
|
|
9313
|
+
});
|
|
9314
|
+
if (parentFams.length === 1) {
|
|
9315
|
+
return parentFams[0];
|
|
9311
9316
|
}
|
|
9312
|
-
|
|
9317
|
+
return void 0;
|
|
9313
9318
|
};
|
|
9314
|
-
var
|
|
9315
|
-
|
|
9316
|
-
|
|
9317
|
-
if (!gedcom || !eventType) {
|
|
9318
|
-
return void 0;
|
|
9319
|
+
var consolidateChildIntoFamily = (child, keep) => {
|
|
9320
|
+
if (!child.id || !keep.id) {
|
|
9321
|
+
return [];
|
|
9319
9322
|
}
|
|
9320
|
-
const
|
|
9321
|
-
|
|
9322
|
-
|
|
9323
|
-
|
|
9324
|
-
|
|
9323
|
+
const keepParentIds = /* @__PURE__ */ new Set([
|
|
9324
|
+
...pointerIds(keep.get("HUSB")),
|
|
9325
|
+
...pointerIds(keep.get("WIFE"))
|
|
9326
|
+
]);
|
|
9327
|
+
const removed = [];
|
|
9328
|
+
child.getFamilies("FAMC")?.forEach((fam) => {
|
|
9329
|
+
if (!fam?.id || fam.id === keep.id) {
|
|
9330
|
+
return;
|
|
9331
|
+
}
|
|
9332
|
+
const famParentIds = [
|
|
9333
|
+
...pointerIds(fam.get("HUSB")),
|
|
9334
|
+
...pointerIds(fam.get("WIFE"))
|
|
9335
|
+
];
|
|
9336
|
+
if (famParentIds.length === 0 || !famParentIds.every((id) => keepParentIds.has(id))) {
|
|
9337
|
+
return;
|
|
9338
|
+
}
|
|
9339
|
+
removePointerByValue(fam, "CHIL", child.id);
|
|
9340
|
+
normalizeSinglePointer(fam, "CHIL");
|
|
9341
|
+
removePointerByValue(child, "FAMC", fam.id);
|
|
9342
|
+
normalizeSinglePointer(child, "FAMC");
|
|
9343
|
+
removed.push(fam.id);
|
|
9344
|
+
});
|
|
9345
|
+
const gedcom = child.getGedcom() ?? keep.getGedcom();
|
|
9346
|
+
if (gedcom && removed.length > 0) {
|
|
9347
|
+
pruneEmptyFamilies(gedcom);
|
|
9325
9348
|
}
|
|
9326
|
-
if (
|
|
9327
|
-
|
|
9349
|
+
if (removed.length > 0) {
|
|
9350
|
+
resetRelativesCache();
|
|
9328
9351
|
}
|
|
9329
|
-
|
|
9330
|
-
return no;
|
|
9352
|
+
return removed;
|
|
9331
9353
|
};
|
|
9332
9354
|
|
|
9333
9355
|
// src/classes/fam.ts
|
|
@@ -9902,7 +9924,7 @@ var createGedcomUid = () => {
|
|
|
9902
9924
|
};
|
|
9903
9925
|
|
|
9904
9926
|
// src/utils/gedcom7-metadata.ts
|
|
9905
|
-
var
|
|
9927
|
+
var GEDCOM_MONTHS3 = [
|
|
9906
9928
|
"JAN",
|
|
9907
9929
|
"FEB",
|
|
9908
9930
|
"MAR",
|
|
@@ -9918,7 +9940,7 @@ var GEDCOM_MONTHS2 = [
|
|
|
9918
9940
|
];
|
|
9919
9941
|
var formatGedcom7Timestamp = (date = /* @__PURE__ */ new Date()) => {
|
|
9920
9942
|
const day = String(date.getUTCDate());
|
|
9921
|
-
const month =
|
|
9943
|
+
const month = GEDCOM_MONTHS3[date.getUTCMonth()];
|
|
9922
9944
|
const year = String(date.getUTCFullYear());
|
|
9923
9945
|
const hh = String(date.getUTCHours()).padStart(2, "0");
|
|
9924
9946
|
const mm = String(date.getUTCMinutes()).padStart(2, "0");
|
|
@@ -9996,12 +10018,14 @@ var TREEVIZ_EXTENSION_URIS = {
|
|
|
9996
10018
|
_MTTAG: `${TREEVIZ_EXTENSION_BASE_URI}#_MTTAG`,
|
|
9997
10019
|
_MTCAT: `${TREEVIZ_EXTENSION_BASE_URI}#_MTCAT`,
|
|
9998
10020
|
_CLON: `${TREEVIZ_EXTENSION_BASE_URI}#_CLON`,
|
|
10021
|
+
_CREATED_AT: `${TREEVIZ_EXTENSION_BASE_URI}#_CREATED_AT`,
|
|
9999
10022
|
_MSER: `${TREEVIZ_EXTENSION_BASE_URI}#_MSER`,
|
|
10000
10023
|
_OID: `${TREEVIZ_EXTENSION_BASE_URI}#_OID`,
|
|
10001
10024
|
_LKID: `${TREEVIZ_EXTENSION_BASE_URI}#_LKID`,
|
|
10002
10025
|
_PHOTO_RIN: `${TREEVIZ_EXTENSION_BASE_URI}#_PHOTO_RIN`,
|
|
10003
10026
|
_EXPORTED_FROM_SITE_ID: `${TREEVIZ_EXTENSION_BASE_URI}#_EXPORTED_FROM_SITE_ID`,
|
|
10004
10027
|
_FS_ID: `${TREEVIZ_EXTENSION_BASE_URI}#_FS_ID`,
|
|
10028
|
+
_CON_INDI: `${TREEVIZ_EXTENSION_BASE_URI}#_CON_INDI`,
|
|
10005
10029
|
_FS_LINK: `${TREEVIZ_EXTENSION_BASE_URI}#_FS_LINK`,
|
|
10006
10030
|
_FS_MATCH: `${TREEVIZ_EXTENSION_BASE_URI}#_FS_MATCH`,
|
|
10007
10031
|
_FS_SOUR: `${TREEVIZ_EXTENSION_BASE_URI}#_FS_SOUR`,
|
|
@@ -10151,7 +10175,7 @@ var collectExtensionTagsFrom = (node, into = /* @__PURE__ */ new Set()) => {
|
|
|
10151
10175
|
// package.json
|
|
10152
10176
|
var package_default = {
|
|
10153
10177
|
name: "@treeviz/gedcom-parser",
|
|
10154
|
-
version: "2.1.
|
|
10178
|
+
version: "2.1.24"};
|
|
10155
10179
|
|
|
10156
10180
|
// src/utils/get-product-details.ts
|
|
10157
10181
|
var isDevelopment = () => {
|
|
@@ -11414,6 +11438,7 @@ var mergeGedcoms = (targetGedcom, sourceGedcom, strategy = "id") => {
|
|
|
11414
11438
|
}
|
|
11415
11439
|
} else {
|
|
11416
11440
|
if (clonedIndi.id) {
|
|
11441
|
+
stampCreatedAt(mergedGedcom, clonedIndi);
|
|
11417
11442
|
mergedGedcom.indis()?.item(clonedIndi.id, clonedIndi);
|
|
11418
11443
|
}
|
|
11419
11444
|
}
|
|
@@ -11538,7 +11563,7 @@ var create = (gedcom, type, id, nodes) => {
|
|
|
11538
11563
|
prevNode = createSour(gedcom, void 0, mainNode, curNode);
|
|
11539
11564
|
} else if (type === "OBJE") {
|
|
11540
11565
|
prevNode = createObje(gedcom, void 0, mainNode, curNode);
|
|
11541
|
-
} else if (type === "DATE") {
|
|
11566
|
+
} else if (type === "DATE" || type === "_CREATED_AT") {
|
|
11542
11567
|
prevNode = createCommonDate(gedcom, void 0, mainNode, curNode);
|
|
11543
11568
|
} else if (type === "NOTE" || type === "SNOTE" || type === "_TREEVIZ_LIFE_STORY" || type === "_TREEVIZ_FAMILY_STORY") {
|
|
11544
11569
|
prevNode = createCommonNote(gedcom, void 0, mainNode, curNode);
|
|
@@ -11565,7 +11590,12 @@ var GedcomTree = {
|
|
|
11565
11590
|
},
|
|
11566
11591
|
parseHierarchy: function(content, options) {
|
|
11567
11592
|
content = content.replace(/^\uFEFF+/, "");
|
|
11568
|
-
const {
|
|
11593
|
+
const {
|
|
11594
|
+
settings,
|
|
11595
|
+
filename = "",
|
|
11596
|
+
purgeOversized = false,
|
|
11597
|
+
maxFileSizeToPurge
|
|
11598
|
+
} = options ?? {};
|
|
11569
11599
|
const { linkedPersons = "skip", linkingKey } = settings ?? {};
|
|
11570
11600
|
const gedcom = createGedCom();
|
|
11571
11601
|
gedcom.removeValue();
|
|
@@ -11667,7 +11697,7 @@ var GedcomTree = {
|
|
|
11667
11697
|
return acc;
|
|
11668
11698
|
}, []);
|
|
11669
11699
|
let linesJoined = lines.join("\n");
|
|
11670
|
-
if (!linesJoined.includes("1 _IS_PURGED true") && getRawSize(linesJoined) >
|
|
11700
|
+
if (purgeOversized && typeof maxFileSizeToPurge === "number" && !linesJoined.includes("1 _IS_PURGED true") && getRawSize(linesJoined) > maxFileSizeToPurge) {
|
|
11671
11701
|
linesJoined = linesJoined.replace(
|
|
11672
11702
|
/1\s(NOTE|OBJE|SOUR)([^\n]*\n)([23456789]\s.+\n)*/gm,
|
|
11673
11703
|
""
|
|
@@ -11829,4 +11859,4 @@ var createEmptyGedcom = (options) => {
|
|
|
11829
11859
|
return gedcom;
|
|
11830
11860
|
};
|
|
11831
11861
|
|
|
11832
|
-
export { ACCEPTED_DATE_FORMATS, ACCEPTED_DATE_FORMATS_REGEX, ADOPTED, ANCESTRY_MEDIA_RETRIEVAL_PREFIX, ANCESTRY_TREE_MEDIA_NAMESPACE, APP_BRANDING, BIOLOGICAL, BIRTH, BIRTH_ASC, BIRTH_DESC, Common, CommonDate, CommonName, CommonNote, CustomTags, DATE_ASC, DATE_DESC, DEATH_ASC, DEATH_DESC, DEFAULT, DEFAULT_GEDCOM_EXPORT_VERSION, EVERY, Existed, FEMALE, FOSTER, FRIEND, Fam, Families, GEDCOM7_CALENDARS, GEDCOM7_PEDI_VALUES, GEDCOM7_RESN_VALUES, GEDCOM7_ROLE_VALUES, GEDCOM7_SEX_VALUES, GEDCOM_EXPORT_VERSIONS, GEDZIP_EXTENSION, GEDZIP_GEDCOM_ENTRY, GEDZIP_MIME, GedCom, parser_default as GedcomTree, ID_GETTER_REG, ID_REG, ID_SPLIT_REG, Indi, Individuals, KinshipTranslator, KinshipTranslatorBasic, KinshipTranslatorDe as KinshipTranslatorDE, KinshipTranslatorEn as KinshipTranslatorEN, KinshipTranslatorEs as KinshipTranslatorES, KinshipTranslatorFr as KinshipTranslatorFR, KinshipTranslatorHU, KinshipTranslatorJa as KinshipTranslatorJA, KinshipTranslatorRu as KinshipTranslatorRU, KinshipTranslatorZh as KinshipTranslatorZH, LINE_REG, List, MALE,
|
|
11862
|
+
export { ACCEPTED_DATE_FORMATS, ACCEPTED_DATE_FORMATS_REGEX, ADOPTED, ANCESTRY_MEDIA_RETRIEVAL_PREFIX, ANCESTRY_TREE_MEDIA_NAMESPACE, APP_BRANDING, BIOLOGICAL, BIRTH, BIRTH_ASC, BIRTH_DESC, CREATED_AT_TAG, Common, CommonDate, CommonName, CommonNote, CustomTags, DATE_ASC, DATE_DESC, DEATH_ASC, DEATH_DESC, DEFAULT, DEFAULT_GEDCOM_EXPORT_VERSION, EVERY, Existed, FEMALE, FOSTER, FRIEND, Fam, Families, GEDCOM7_CALENDARS, GEDCOM7_PEDI_VALUES, GEDCOM7_RESN_VALUES, GEDCOM7_ROLE_VALUES, GEDCOM7_SEX_VALUES, GEDCOM_EXPORT_VERSIONS, GEDZIP_EXTENSION, GEDZIP_GEDCOM_ENTRY, GEDZIP_MIME, GedCom, parser_default as GedcomTree, ID_GETTER_REG, ID_REG, ID_SPLIT_REG, Indi, Individuals, KinshipTranslator, KinshipTranslatorBasic, KinshipTranslatorDe as KinshipTranslatorDE, KinshipTranslatorEn as KinshipTranslatorEN, KinshipTranslatorEs as KinshipTranslatorES, KinshipTranslatorFr as KinshipTranslatorFR, KinshipTranslatorHU, KinshipTranslatorJa as KinshipTranslatorJA, KinshipTranslatorRu as KinshipTranslatorRU, KinshipTranslatorZh as KinshipTranslatorZH, LINE_REG, List, MALE, ORIG_HEAD_TAG, OTHER, Obje, Objects, PARTNER, PEDIGREE_VALUES, PartnerType, PlaceType, REF_LINE_REG, Range, RelationType, Repo, Repositories, SEALING, SINGLE, SPOUSE, STEP, Sour, Sources, Subm, Submitters, TREEVIZ_EXTENSION_BASE_URI, TREEVIZ_EXTENSION_URIS, UNKOWN, addFamilyFact, addIndividualFact, addNonEvent, ancestryMediaFileUrl, applyGedcom7DatePhrases, applyGedcom7Enumerations, applyGedcom7RecordMetadata, attachChildToFamily, attachSpouseToFamily, buildGedzip, buildGedzipBlob, bytesToDataUrl, cacheDiscoveredPath, canAttachAsSpouse, collectExtensionTagsFrom, commonDateFormatter, consolidateChildIntoFamily, coupleKeyForFam, create, createCommon, createCommonDate, createCommonName, createCommonNote, createEmptyGedcom, createFam, createGedCom, createGedcomUid, createIndi, createObje, createProxy, createRepo, createSour, createSubm, dateFormatter, parser_default as default, deleteIndividual, downloadGedzipMedia, ensureExtensionSchema, extractGedzip, extractGedzipGedcom, extractSeparationYears, extractSplitPoints, familyHasChild, familyHasParent, findDegenerateFamiliesForIndi, findDuplicateCoupleFamiliesForIndi, findMatchingRangeForSplitRange, findReusableParentChildFamily, firstPointerId, formatGedcom7Timestamp, fromTuple, generateSplitRanges, getAllProp, getBirthAsc, getCacheManagerFactory, getDateLocale, getExtensionSchema, getFamilyWith, getFileExtension, getI18n, getKinshipTranslatorClass, getListTag, getMarriageAsc, getMarriageAscAndBirth, getMarriageAscAndChildBirth, getName, getNameAsc, getNameAscAndBirth, getNameDesc, getPlaceParserProvider, getPlaceParts, getPlaceTranslatorProvider, getPlaces, getRawSize, getValidKey, getValidKeys, getValidTag, getVersion, hungarianOrdinalize, i18n, idGetter, implemented, inRange, inferMediaForm, initializeCache, isAncestryOriginObje, isCommonDate, isDegenerateFamily, isDevelopment, isGedcom7, isGedcomString, isGedzipContainer, isId, isImageFormat, isIntersectedRange, isObjePointer, isOnlyMainProp, isRangeContained, isRemoteOrEmbeddedMediaUrl, isValidKey, makePointer, marriageDateFormatter, mergeDuplicateCoupleFamilies, mergeGedcoms, mergeMediaLists, mergeMediaListsByObjeKey, nameFormatter, nextRecordId, normalizeGedcomVersion, notImplemented, noteDateFormatter, objeNoteValue, objeXrefKey, ordinalize, parseAncestryNamespaceFromUrl, parseGedcom7CalendarPrefix, parseRangeBounds, pathCache, placeTranslator, pointerIds, profilePictureCache, pruneEmptyFamilies, pruneFamiliesByIds, registerExtensionTag, relativesCache, remountGedzipMediaAsDataUrls, removePointerByValue, resetCacheManagerFactory, resetDateLocaleProvider, resetI18nProvider, resetKinshipTranslatorClass, resetPlaceParserProvider, resetPlaceTranslatorProvider, resetRelativesCache, resolveLocalMediaUrl, resolveMediaContent, resolveObjeForm, resolveObjeMediaId, rewriteGedcomFilePaths, setCacheManagerFactory, setCauseOfDeath, setChildPedigree, setDateLocaleProvider, setDeceased, setFamilyMarriage, setI18nProvider, setKinshipTranslatorClass, setLocalMediaResolver, setMediaContentResolver, setNestedGroup, setPlaceParserProvider, setPlaceTranslatorProvider, splitOverlappingRanges, splitRange, spouseTagFor, stampCreatedAt, toGedcomPedigree, translators_exports as translators, unlinkRelative, updateFactRecord, validateGedcomContent, withGedcom7Calendar };
|