@treeviz/gedcom-parser 2.0.9 → 2.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/classes/common.d.ts +6 -1
  2. package/dist/classes/common.d.ts.map +1 -1
  3. package/dist/classes/fam.d.ts +9 -1
  4. package/dist/classes/fam.d.ts.map +1 -1
  5. package/dist/classes/gedcom.d.ts +6 -2
  6. package/dist/classes/gedcom.d.ts.map +1 -1
  7. package/dist/classes/index.js +740 -51
  8. package/dist/classes/indi.d.ts +6 -0
  9. package/dist/classes/indi.d.ts.map +1 -1
  10. package/dist/cli/index.js +3194 -2499
  11. package/dist/constants/constants.d.ts +7 -0
  12. package/dist/constants/constants.d.ts.map +1 -1
  13. package/dist/constants/index.js +1531 -916
  14. package/dist/factories/index.js +654 -40
  15. package/dist/index.d.ts +2 -0
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +5201 -4407
  18. package/dist/interfaces/fam.d.ts +7 -1
  19. package/dist/interfaces/fam.d.ts.map +1 -1
  20. package/dist/interfaces/gedcom.d.ts +4 -0
  21. package/dist/interfaces/gedcom.d.ts.map +1 -1
  22. package/dist/interfaces/indi.d.ts +5 -1
  23. package/dist/interfaces/indi.d.ts.map +1 -1
  24. package/dist/kinship-translator/index.d.ts +1 -0
  25. package/dist/kinship-translator/index.d.ts.map +1 -1
  26. package/dist/kinship-translator/index.js +655 -41
  27. package/dist/kinship-translator/kinship-translator.ru.d.ts +18 -0
  28. package/dist/kinship-translator/kinship-translator.ru.d.ts.map +1 -0
  29. package/dist/kinship-translator/patterns.ru.d.ts +2 -0
  30. package/dist/kinship-translator/patterns.ru.d.ts.map +1 -0
  31. package/dist/kinship-translator/translators.d.ts +1 -0
  32. package/dist/kinship-translator/translators.d.ts.map +1 -1
  33. package/dist/kinship-translator/types.d.ts +1 -1
  34. package/dist/kinship-translator/types.d.ts.map +1 -1
  35. package/dist/structures/gedcom.d.ts +1 -0
  36. package/dist/structures/gedcom.d.ts.map +1 -1
  37. package/dist/types/types.d.ts +10 -0
  38. package/dist/types/types.d.ts.map +1 -1
  39. package/dist/utils/fact-edit.d.ts +22 -0
  40. package/dist/utils/fact-edit.d.ts.map +1 -0
  41. package/dist/utils/family-edit.d.ts +23 -0
  42. package/dist/utils/family-edit.d.ts.map +1 -0
  43. package/dist/utils/gedcom-trailer.d.ts +6 -0
  44. package/dist/utils/gedcom-trailer.d.ts.map +1 -0
  45. package/dist/utils/index.d.ts +4 -1
  46. package/dist/utils/index.d.ts.map +1 -1
  47. package/dist/utils/index.js +850 -56
  48. package/dist/utils/parser.d.ts +3 -0
  49. package/dist/utils/parser.d.ts.map +1 -1
  50. package/package.json +1 -1
@@ -194,7 +194,8 @@ __export(translators_exports, {
194
194
  en: () => KinshipTranslatorEn,
195
195
  es: () => KinshipTranslatorEs,
196
196
  fr: () => KinshipTranslatorFr,
197
- hu: () => KinshipTranslatorHU
197
+ hu: () => KinshipTranslatorHU,
198
+ ru: () => KinshipTranslatorRu
198
199
  });
199
200
 
200
201
  // src/utils/ordinalize.ts
@@ -1247,6 +1248,249 @@ var KinshipTranslatorEs = class extends KinshipTranslatorBasic {
1247
1248
  }
1248
1249
  };
1249
1250
 
1251
+ // src/kinship-translator/patterns.ru.ts
1252
+ var InLawsRu = {
1253
+ "\u0441\u0443\u043F\u0440\u0443\u0433(?:\u0430)? (\u0440\u0435\u0431\u0451\u043D\u043A\u0430|\u0434\u043E\u0447\u0435\u0440\u0438|\u0441\u044B\u043D\u0430)": "\u0437\u044F\u0442\u044C/\u043D\u0435\u0432\u0435\u0441\u0442\u043A\u0430",
1254
+ "\u0436\u0435\u043D\u0430 (\u0440\u0435\u0431\u0451\u043D\u043A\u0430|\u0434\u043E\u0447\u0435\u0440\u0438|\u0441\u044B\u043D\u0430)": "\u043D\u0435\u0432\u0435\u0441\u0442\u043A\u0430",
1255
+ "\u043C\u0443\u0436 (\u0440\u0435\u0431\u0451\u043D\u043A\u0430|\u0434\u043E\u0447\u0435\u0440\u0438|\u0441\u044B\u043D\u0430)": "\u0437\u044F\u0442\u044C",
1256
+ "\u043C\u0430\u0442\u044C (\u0441\u0443\u043F\u0440\u0443\u0433\u0430|\u0436\u0435\u043D\u044B|\u043C\u0443\u0436\u0430)": "\u0442\u0451\u0449\u0430",
1257
+ "\u043E\u0442\u0435\u0446 (\u0441\u0443\u043F\u0440\u0443\u0433\u0430|\u0436\u0435\u043D\u044B|\u043C\u0443\u0436\u0430)": "\u0442\u0435\u0441\u0442\u044C",
1258
+ "\u0440\u043E\u0434\u0438\u0442\u0435\u043B\u044C (\u0441\u0443\u043F\u0440\u0443\u0433\u0430|\u0436\u0435\u043D\u044B|\u043C\u0443\u0436\u0430)": "\u0442\u0435\u0441\u0442\u044C/\u0442\u0451\u0449\u0430",
1259
+ "\u0436\u0435\u043D\u0430 (\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?(\u0431\u0440\u0430\u0442\u0430|\u0441\u0435\u0441\u0442\u0440\u044B|\u0441\u0438\u0431\u043B\u0438\u043D\u0433\u0430)": "\u043D\u0435\u0432\u0435\u0441\u0442\u043A\u0430",
1260
+ "\u043C\u0443\u0436 (\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?(\u0431\u0440\u0430\u0442\u0430|\u0441\u0435\u0441\u0442\u0440\u044B|\u0441\u0438\u0431\u043B\u0438\u043D\u0433\u0430)": "\u0437\u044F\u0442\u044C",
1261
+ "\u0441\u0443\u043F\u0440\u0443\u0433(?:\u0430)? (\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?(\u0431\u0440\u0430\u0442\u0430|\u0441\u0435\u0441\u0442\u0440\u044B|\u0441\u0438\u0431\u043B\u0438\u043D\u0433\u0430)": "\u0437\u044F\u0442\u044C/\u043D\u0435\u0432\u0435\u0441\u0442\u043A\u0430",
1262
+ "(\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?\u0441\u0435\u0441\u0442\u0440\u0430 (\u0441\u0443\u043F\u0440\u0443\u0433\u0430|\u0436\u0435\u043D\u044B|\u043C\u0443\u0436\u0430)": "\u0437\u043E\u043B\u043E\u0432\u043A\u0430",
1263
+ "(\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?\u0431\u0440\u0430\u0442 (\u0441\u0443\u043F\u0440\u0443\u0433\u0430|\u0436\u0435\u043D\u044B|\u043C\u0443\u0436\u0430)": "\u0448\u0443\u0440\u0438\u043D",
1264
+ "(\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?\u0441\u0438\u0431\u043B\u0438\u043D\u0433 (\u0441\u0443\u043F\u0440\u0443\u0433\u0430|\u0436\u0435\u043D\u044B|\u043C\u0443\u0436\u0430)": "\u0448\u0443\u0440\u0438\u043D/\u0437\u043E\u043B\u043E\u0432\u043A\u0430"
1265
+ };
1266
+
1267
+ // src/kinship-translator/kinship-translator.ru.ts
1268
+ var GENITIVE = {
1269
+ \u0441\u044B\u043D: "\u0441\u044B\u043D\u0430",
1270
+ \u0434\u043E\u0447\u044C: "\u0434\u043E\u0447\u0435\u0440\u0438",
1271
+ \u0440\u0435\u0431\u0451\u043D\u043E\u043A: "\u0440\u0435\u0431\u0451\u043D\u043A\u0430",
1272
+ \u0431\u0440\u0430\u0442: "\u0431\u0440\u0430\u0442\u0430",
1273
+ \u0441\u0435\u0441\u0442\u0440\u0430: "\u0441\u0435\u0441\u0442\u0440\u044B",
1274
+ \u0441\u0438\u0431\u043B\u0438\u043D\u0433: "\u0441\u0438\u0431\u043B\u0438\u043D\u0433\u0430",
1275
+ \u043E\u0442\u0435\u0446: "\u043E\u0442\u0446\u0430",
1276
+ \u043C\u0430\u0442\u044C: "\u043C\u0430\u0442\u0435\u0440\u0438",
1277
+ \u0440\u043E\u0434\u0438\u0442\u0435\u043B\u044C: "\u0440\u043E\u0434\u0438\u0442\u0435\u043B\u044F",
1278
+ \u043C\u0443\u0436: "\u043C\u0443\u0436\u0430",
1279
+ \u0436\u0435\u043D\u0430: "\u0436\u0435\u043D\u044B",
1280
+ \u0441\u0443\u043F\u0440\u0443\u0433: "\u0441\u0443\u043F\u0440\u0443\u0433\u0430",
1281
+ \u0441\u0443\u043F\u0440\u0443\u0433\u0430: "\u0441\u0443\u043F\u0440\u0443\u0433\u0438"
1282
+ };
1283
+ var toGenitive = (word) => GENITIVE[word] ?? word;
1284
+ var cousinWord = (degree, sex) => {
1285
+ const stem = degree <= 1 ? "\u0434\u0432\u043E\u044E\u0440\u043E\u0434\u043D" : degree === 2 ? "\u0442\u0440\u043E\u044E\u0440\u043E\u0434\u043D" : degree === 3 ? "\u0447\u0435\u0442\u0432\u0435\u0440\u043E\u044E\u0440\u043E\u0434\u043D" : `${degree + 1}-\u044E\u0440\u043E\u0434\u043D`;
1286
+ if (sex === "m") {
1287
+ return `${stem}\u044B\u0439 \u0431\u0440\u0430\u0442`;
1288
+ }
1289
+ if (sex === "f") {
1290
+ return `${stem}\u0430\u044F \u0441\u0435\u0441\u0442\u0440\u0430`;
1291
+ }
1292
+ return `${stem}\u044B\u0439 \u0431\u0440\u0430\u0442/\u0441\u0435\u0441\u0442\u0440\u0430`;
1293
+ };
1294
+ var praRepeat = (count) => count > 0 ? "\u043F\u0440\u0430".repeat(count) : "";
1295
+ var sexOf = (person) => {
1296
+ if (person?.isMale?.()) {
1297
+ return "m";
1298
+ }
1299
+ if (person?.isFemale?.()) {
1300
+ return "f";
1301
+ }
1302
+ return "n";
1303
+ };
1304
+ var KinshipTranslatorRu = class extends KinshipTranslatorBasic {
1305
+ indirect() {
1306
+ let degree = Math.abs(this.pathN?.degree ?? 0);
1307
+ if (degree > 0) {
1308
+ degree = degree - 1;
1309
+ }
1310
+ return cousinWord(degree, sexOf(this.personN));
1311
+ }
1312
+ removal() {
1313
+ const level = this.pathN?.level ?? 0;
1314
+ let degree = Math.abs(this.pathN?.degree ?? 0);
1315
+ if (degree > 0) {
1316
+ degree = degree - 1;
1317
+ }
1318
+ if (!degree) {
1319
+ return level < 0 ? this.nibling() : this.auncle();
1320
+ }
1321
+ const removed = Math.abs(level);
1322
+ return `${cousinWord(degree, sexOf(this.personN))} (${removed}\xD7 \u0447\u0435\u0440\u0435\u0437 \u043F\u043E\u043A\u043E\u043B\u0435\u043D\u0438\u0435)`;
1323
+ }
1324
+ auncle() {
1325
+ const level = Math.abs(this.pathN?.level ?? 0);
1326
+ const pra = praRepeat(Math.max(0, level - 2));
1327
+ const sex = sexOf(this.personN);
1328
+ if (sex === "m") {
1329
+ return `${pra}\u0434\u044F\u0434\u044F`;
1330
+ }
1331
+ if (sex === "f") {
1332
+ return `${pra}\u0442\u0451\u0442\u044F`;
1333
+ }
1334
+ return `${pra}\u0434\u044F\u0434\u044F/\u0442\u0451\u0442\u044F`;
1335
+ }
1336
+ nibling() {
1337
+ const level = Math.abs(this.pathN?.level ?? 0);
1338
+ const pra = praRepeat(Math.max(0, level - 2));
1339
+ const sex = sexOf(this.personN);
1340
+ if (sex === "m") {
1341
+ return `${pra}\u043F\u043B\u0435\u043C\u044F\u043D\u043D\u0438\u043A`;
1342
+ }
1343
+ if (sex === "f") {
1344
+ return `${pra}\u043F\u043B\u0435\u043C\u044F\u043D\u043D\u0438\u0446\u0430`;
1345
+ }
1346
+ return `${pra}\u043F\u043B\u0435\u043C\u044F\u043D\u043D\u0438\u043A/\u043F\u043B\u0435\u043C\u044F\u043D\u043D\u0438\u0446\u0430`;
1347
+ }
1348
+ parent() {
1349
+ const level = Math.abs(this.pathN?.level ?? 0);
1350
+ const sex = sexOf(this.personN);
1351
+ if (level <= 1) {
1352
+ if (sex === "m") {
1353
+ return "\u043E\u0442\u0435\u0446";
1354
+ }
1355
+ if (sex === "f") {
1356
+ return "\u043C\u0430\u0442\u044C";
1357
+ }
1358
+ return "\u0440\u043E\u0434\u0438\u0442\u0435\u043B\u044C";
1359
+ }
1360
+ if (level === 2) {
1361
+ if (sex === "m") {
1362
+ return "\u0434\u0435\u0434";
1363
+ }
1364
+ if (sex === "f") {
1365
+ return "\u0431\u0430\u0431\u0443\u0448\u043A\u0430";
1366
+ }
1367
+ return "\u0434\u0435\u0434/\u0431\u0430\u0431\u0443\u0448\u043A\u0430";
1368
+ }
1369
+ const pra = praRepeat(level - 2);
1370
+ if (sex === "m") {
1371
+ return `${pra}\u0434\u0435\u0434`;
1372
+ }
1373
+ if (sex === "f") {
1374
+ return `${pra}\u0431\u0430\u0431\u0443\u0448\u043A\u0430`;
1375
+ }
1376
+ return `${pra}\u0434\u0435\u0434/\u0431\u0430\u0431\u0443\u0448\u043A\u0430`;
1377
+ }
1378
+ child() {
1379
+ const level = Math.abs(this.pathN?.level ?? 0);
1380
+ const sex = sexOf(this.personN);
1381
+ if (level <= 1) {
1382
+ if (sex === "m") {
1383
+ return "\u0441\u044B\u043D";
1384
+ }
1385
+ if (sex === "f") {
1386
+ return "\u0434\u043E\u0447\u044C";
1387
+ }
1388
+ return "\u0440\u0435\u0431\u0451\u043D\u043E\u043A";
1389
+ }
1390
+ if (level === 2) {
1391
+ if (sex === "m") {
1392
+ return "\u0432\u043D\u0443\u043A";
1393
+ }
1394
+ if (sex === "f") {
1395
+ return "\u0432\u043D\u0443\u0447\u043A\u0430";
1396
+ }
1397
+ return "\u0432\u043D\u0443\u043A/\u0432\u043D\u0443\u0447\u043A\u0430";
1398
+ }
1399
+ const pra = praRepeat(level - 2);
1400
+ if (sex === "m") {
1401
+ return `${pra}\u0432\u043D\u0443\u043A`;
1402
+ }
1403
+ if (sex === "f") {
1404
+ return `${pra}\u0432\u043D\u0443\u0447\u043A\u0430`;
1405
+ }
1406
+ return `${pra}\u0432\u043D\u0443\u043A/\u0432\u043D\u0443\u0447\u043A\u0430`;
1407
+ }
1408
+ sibling() {
1409
+ const sex = sexOf(this.personN);
1410
+ if (sex === "m") {
1411
+ return "\u0431\u0440\u0430\u0442";
1412
+ }
1413
+ if (sex === "f") {
1414
+ return "\u0441\u0435\u0441\u0442\u0440\u0430";
1415
+ }
1416
+ return "\u0441\u0438\u0431\u043B\u0438\u043D\u0433";
1417
+ }
1418
+ halfBlood(relation) {
1419
+ if (!relation || !this.isHalfBlood) {
1420
+ return relation ?? "";
1421
+ }
1422
+ if (/сестра|дочь|мать|тётя|бабушка|жена|племянница|внучка/.test(
1423
+ relation
1424
+ )) {
1425
+ return `\u0441\u0432\u043E\u0434\u043D\u0430\u044F ${relation}`;
1426
+ }
1427
+ return `\u0441\u0432\u043E\u0434\u043D\u044B\u0439 ${relation}`;
1428
+ }
1429
+ spouse() {
1430
+ const sex = sexOf(this.personN);
1431
+ if (sex === "m") {
1432
+ return "\u043C\u0443\u0436";
1433
+ }
1434
+ if (sex === "f") {
1435
+ return "\u0436\u0435\u043D\u0430";
1436
+ }
1437
+ return "\u0441\u0443\u043F\u0440\u0443\u0433";
1438
+ }
1439
+ ofSpouse(relation) {
1440
+ if (!relation) {
1441
+ return "";
1442
+ }
1443
+ const spouse = this.path?.[1].indi;
1444
+ const sex = sexOf(spouse);
1445
+ const spouseType = sex === "m" ? "\u043C\u0443\u0436" : sex === "f" ? "\u0436\u0435\u043D\u0430" : "\u0441\u0443\u043F\u0440\u0443\u0433";
1446
+ return `${relation} ${toGenitive(spouseType)}`;
1447
+ }
1448
+ spouseOf(relation) {
1449
+ if (!relation) {
1450
+ return "";
1451
+ }
1452
+ const spouse = this.path?.[this.path.length - 1].indi;
1453
+ const sex = sexOf(spouse);
1454
+ const spouseType = sex === "m" ? "\u043C\u0443\u0436" : sex === "f" ? "\u0436\u0435\u043D\u0430" : "\u0441\u0443\u043F\u0440\u0443\u0433";
1455
+ return `${spouseType} ${toGenitive(relation)}`;
1456
+ }
1457
+ of(relation) {
1458
+ const formattedName = nameFormatter(this.path?.[0]?.indi, {
1459
+ nameOrder: "first-last"
1460
+ });
1461
+ let name = formattedName.inOrder.filter(Boolean).join(" ");
1462
+ if (this.displayName === "none") {
1463
+ name = "";
1464
+ } else if (this.displayName === "givenname") {
1465
+ name = formattedName.givenname;
1466
+ } else if (this.displayName === "surname") {
1467
+ name = `${formattedName.surname}`;
1468
+ }
1469
+ if (!name || !relation) {
1470
+ return relation ?? "";
1471
+ }
1472
+ return `${name}: ${relation}`;
1473
+ }
1474
+ inLaw(relation) {
1475
+ let inLawRelation = relation;
1476
+ Object.keys(InLawsRu).find((pattern) => {
1477
+ const regex = new RegExp(`^${pattern}$`);
1478
+ if (relation?.match(regex)) {
1479
+ inLawRelation = InLawsRu[pattern];
1480
+ return true;
1481
+ }
1482
+ return false;
1483
+ });
1484
+ return inLawRelation ?? "";
1485
+ }
1486
+ relationType(relation) {
1487
+ if (!relation || !this.pathN?.relation) {
1488
+ return relation ?? "";
1489
+ }
1490
+ return `${this.pathN.relation} ${relation}`;
1491
+ }
1492
+ };
1493
+
1250
1494
  // src/kinship-translator/kinship-translator.ts
1251
1495
  var KinshipTranslator = class {
1252
1496
  constructor(person1, person2, lang = "en", entirePath, displayName = "givenname") {
@@ -1602,6 +1846,11 @@ var inRange = (year, range, trueIfNoYear = false) => {
1602
1846
  // src/constants/constants.ts
1603
1847
  var ID_REG = /^@[_a-zA-Z0-9]+@/;
1604
1848
  var ID_GETTER_REG = /^(?<at>@)?(?<letter>[A-Z])?/i;
1849
+ var ORIG_HEAD_TAG = "_ORIGHEAD";
1850
+
1851
+ // src/utils/gedcom-trailer.ts
1852
+ var GEDCOM_TRAILER_TAG = "TRLR";
1853
+ var isGedcomTrailerTag = (tag) => tag === GEDCOM_TRAILER_TAG;
1605
1854
  var List = class _List {
1606
1855
  // length = 0;
1607
1856
  constructor(items) {
@@ -2112,6 +2361,9 @@ var Common = class _Common {
2112
2361
  delete this._value;
2113
2362
  }
2114
2363
  set(name, value) {
2364
+ if (isGedcomTrailerTag(name)) {
2365
+ return void 0;
2366
+ }
2115
2367
  if (typeof value === "string") {
2116
2368
  const usedValue = createCommon(this._gedcom, void 0, this.main);
2117
2369
  usedValue.value = value;
@@ -2122,6 +2374,9 @@ var Common = class _Common {
2122
2374
  return get(this, name);
2123
2375
  }
2124
2376
  assign(name, value, unique = false) {
2377
+ if (isGedcomTrailerTag(name)) {
2378
+ return void 0;
2379
+ }
2125
2380
  let curValue = this.get(name);
2126
2381
  if (curValue?.isListable) {
2127
2382
  if (curValue instanceof _Common) {
@@ -2344,30 +2599,47 @@ var Common = class _Common {
2344
2599
  });
2345
2600
  return gedcom;
2346
2601
  }
2602
+ getHeadRecord() {
2603
+ return get(this, "HEAD") || get(this.getGedcom(), "HEAD");
2604
+ }
2605
+ getOriginalHeadRecord() {
2606
+ return get(this, ORIG_HEAD_TAG) || get(this.getGedcom(), ORIG_HEAD_TAG) || get(this.getHeadRecord(), ORIG_HEAD_TAG);
2607
+ }
2608
+ getSourceHeads() {
2609
+ const heads = [this.getOriginalHeadRecord(), this.getHeadRecord()];
2610
+ return heads.filter((head, index) => {
2611
+ return Boolean(head && heads.indexOf(head) === index);
2612
+ });
2613
+ }
2614
+ getFromSourceHeads(path) {
2615
+ for (const head of this.getSourceHeads()) {
2616
+ const value = get(head, path);
2617
+ if (value !== void 0 && value !== null && value !== "") {
2618
+ return value;
2619
+ }
2620
+ }
2621
+ return void 0;
2622
+ }
2623
+ sourStartsWith(prefix) {
2624
+ return this.getSourceHeads().some((head) => {
2625
+ const sour = get(head, "SOUR.value");
2626
+ return !!sour?.toLowerCase()?.startsWith(prefix);
2627
+ });
2628
+ }
2347
2629
  isGenoPro() {
2348
- const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
2349
- const sour = get(head, "SOUR.value");
2350
- return !!sour?.toLowerCase()?.startsWith("genopro");
2630
+ return this.sourStartsWith("genopro");
2351
2631
  }
2352
2632
  isAhnenblatt() {
2353
- const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
2354
- const sour = get(head, "SOUR.value");
2355
- return !!sour?.toLowerCase()?.startsWith("ahnenblatt");
2633
+ return this.sourStartsWith("ahnenblatt");
2356
2634
  }
2357
2635
  isGeni() {
2358
- const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
2359
- const sour = get(head, "SOUR.value");
2360
- return !!sour?.toLowerCase()?.startsWith("geni");
2636
+ return this.sourStartsWith("geni");
2361
2637
  }
2362
2638
  isAncestry() {
2363
- const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
2364
- const sour = get(head, "SOUR.value");
2365
- return !!sour?.toLowerCase()?.startsWith("ancestry");
2639
+ return this.sourStartsWith("ancestry");
2366
2640
  }
2367
2641
  isMyHeritage() {
2368
- const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
2369
- const sour = get(head, "SOUR.value");
2370
- return !!sour?.toLowerCase()?.startsWith("myheritage");
2642
+ return this.sourStartsWith("myheritage");
2371
2643
  }
2372
2644
  /**
2373
2645
  * Get the source type as a string (for prefixing tree IDs and names)
@@ -2384,22 +2656,22 @@ var Common = class _Common {
2384
2656
  return void 0;
2385
2657
  }
2386
2658
  isFamilySearch() {
2387
- const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
2388
- const sourName = get(head, "SOUR.NAME.value");
2389
- return sourName === "FamilySearch API";
2659
+ return this.getSourceHeads().some((head) => {
2660
+ const sourName = get(head, "SOUR.NAME.value");
2661
+ return sourName === "FamilySearch API";
2662
+ });
2390
2663
  }
2391
2664
  isGNO2GED() {
2392
- const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
2393
- const sour = get(head, "SOUR.value");
2394
- return sour === "GNO2GED";
2665
+ return this.getSourceHeads().some((head) => {
2666
+ const sour = get(head, "SOUR.value");
2667
+ return sour === "GNO2GED";
2668
+ });
2395
2669
  }
2396
2670
  getAncestryTreeId() {
2397
- const path = "HEAD.SOUR._TREE.RIN.value";
2398
- return get(this, path) || get(this.getGedcom(), path);
2671
+ return this.getFromSourceHeads("SOUR._TREE.RIN.value") || (get(this, "HEAD.SOUR._TREE.RIN.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.RIN.value"));
2399
2672
  }
2400
2673
  getMyHeritageTreeId() {
2401
- const path = "HEAD._EXPORTED_FROM_SITE_ID.value";
2402
- return get(this, path) || get(this.getGedcom(), path);
2674
+ return this.getFromSourceHeads("_EXPORTED_FROM_SITE_ID.value") || (get(this, "HEAD._EXPORTED_FROM_SITE_ID.value") || get(this.getGedcom(), "HEAD._EXPORTED_FROM_SITE_ID.value"));
2403
2675
  }
2404
2676
  getTreeId() {
2405
2677
  if (this?.isAncestry()) {
@@ -2433,8 +2705,7 @@ var Common = class _Common {
2433
2705
  return this.getUniversalTreeId();
2434
2706
  }
2435
2707
  getAncestryTreeName() {
2436
- const path = "HEAD.SOUR._TREE.value";
2437
- return get(this, path) || get(this.getGedcom(), path);
2708
+ return this.getFromSourceHeads("SOUR._TREE.value") || (get(this, "HEAD.SOUR._TREE.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.value"));
2438
2709
  }
2439
2710
  getMyHeritageTreeName() {
2440
2711
  const path = "HEAD.FILE.value";
@@ -2444,14 +2715,14 @@ var Common = class _Common {
2444
2715
  )?.groups?.tree;
2445
2716
  }
2446
2717
  getFamilySearchTreeId() {
2447
- const rin = get(this, "HEAD.SOUR._TREE.RIN.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.RIN.value");
2718
+ const rin = this.getFromSourceHeads("SOUR._TREE.RIN.value") || get(this, "HEAD.SOUR._TREE.RIN.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.RIN.value");
2448
2719
  if (rin) {
2449
2720
  return rin;
2450
2721
  }
2451
2722
  return "familysearch";
2452
2723
  }
2453
2724
  getFamilySearchTreeName() {
2454
- const treeName = get(this, "HEAD.SOUR._TREE.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.value");
2725
+ const treeName = this.getFromSourceHeads("SOUR._TREE.value") || get(this, "HEAD.SOUR._TREE.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.value");
2455
2726
  if (treeName) {
2456
2727
  return treeName;
2457
2728
  }
@@ -2543,11 +2814,11 @@ var Common = class _Common {
2543
2814
  const cleanName = fileName.replace(/\.ged$/i, "").replace(/_/g, " ");
2544
2815
  return `${prefix}${cleanName}`;
2545
2816
  }
2546
- const sourName = get(this, "HEAD.SOUR.NAME.value") || get(this.getGedcom(), "HEAD.SOUR.NAME.value");
2817
+ const sourName = this.getFromSourceHeads("SOUR.NAME.value") || get(this, "HEAD.SOUR.NAME.value") || get(this.getGedcom(), "HEAD.SOUR.NAME.value");
2547
2818
  if (sourName) {
2548
2819
  return `${prefix}${sourName}`;
2549
2820
  }
2550
- const sourValue = get(this, "HEAD.SOUR.value") || get(this.getGedcom(), "HEAD.SOUR.value");
2821
+ const sourValue = this.getFromSourceHeads("SOUR.value") || get(this, "HEAD.SOUR.value") || get(this.getGedcom(), "HEAD.SOUR.value");
2551
2822
  if (sourValue) {
2552
2823
  return `${prefix}${sourValue}`;
2553
2824
  }
@@ -2613,7 +2884,7 @@ var isOnlyMainProp = (key) => {
2613
2884
  };
2614
2885
  var isValidKey = (common, key) => {
2615
2886
  const prop = get(common, key);
2616
- return key !== "_gedcom" && key !== "_main" && key !== "_parent" && key !== "_uniqueId" && key !== "_refs" && key !== "_type" && (key === "id" || key === "_id" || key === "value" || key === "_value" || prop instanceof Common || prop instanceof List);
2887
+ return key !== "_gedcom" && key !== "_main" && key !== "_parent" && key !== "_uniqueId" && key !== "_refs" && key !== "_type" && !(typeof key === "string" && isGedcomTrailerTag(key)) && (key === "id" || key === "_id" || key === "value" || key === "_value" || prop instanceof Common || prop instanceof List);
2617
2888
  };
2618
2889
  var getValidKeys = (common) => {
2619
2890
  return Object.keys(common).filter((key) => {
@@ -3288,6 +3559,239 @@ var cacheDiscoveredPath = (gedcom, path) => {
3288
3559
  }
3289
3560
  };
3290
3561
 
3562
+ // src/utils/fact-edit.ts
3563
+ var SINGLETON_TAGS = /* @__PURE__ */ new Set(["BIRT", "DEAT", "SSN", "SEX", "DSCR"]);
3564
+ var firstRecord = (node) => {
3565
+ if (!node) {
3566
+ return void 0;
3567
+ }
3568
+ if (node instanceof List) {
3569
+ return node.index(0);
3570
+ }
3571
+ return node.index(0) ?? node;
3572
+ };
3573
+ var setDateOn = (gedcom, owner, parent, date) => {
3574
+ const trimmed = date.trim();
3575
+ if (!trimmed) {
3576
+ return;
3577
+ }
3578
+ let dateNode = parent.get("DATE");
3579
+ if (!dateNode || dateNode instanceof List) {
3580
+ dateNode = createCommonDate(gedcom, void 0, owner, parent);
3581
+ dateNode.type = "DATE";
3582
+ parent.set("DATE", dateNode);
3583
+ }
3584
+ dateNode.value = trimmed;
3585
+ };
3586
+ var fillFact = (gedcom, owner, event, input) => {
3587
+ if (input.value?.trim()) {
3588
+ event.value = input.value.trim();
3589
+ }
3590
+ if (input.type?.trim()) {
3591
+ event.set("TYPE", input.type.trim());
3592
+ }
3593
+ if (input.date) {
3594
+ setDateOn(gedcom, owner, event, input.date);
3595
+ }
3596
+ if (input.place?.trim()) {
3597
+ event.set("PLAC", input.place.trim());
3598
+ }
3599
+ if (input.note?.trim()) {
3600
+ event.set("NOTE", input.note.trim());
3601
+ }
3602
+ };
3603
+ var addIndividualFact = (indi, input) => {
3604
+ const gedcom = indi.getGedcom();
3605
+ if (!gedcom) {
3606
+ return void 0;
3607
+ }
3608
+ const tag = input.tag;
3609
+ let event = SINGLETON_TAGS.has(tag) ? firstRecord(indi.get(tag)) : void 0;
3610
+ if (!event) {
3611
+ event = createCommon(gedcom, void 0, indi);
3612
+ event.type = tag;
3613
+ if (SINGLETON_TAGS.has(tag)) {
3614
+ indi.set(tag, event);
3615
+ } else {
3616
+ indi.assign(tag, event);
3617
+ }
3618
+ }
3619
+ fillFact(gedcom, indi, event, input);
3620
+ return event;
3621
+ };
3622
+ var addFamilyFact = (fam, input) => {
3623
+ const gedcom = fam.getGedcom();
3624
+ if (!gedcom) {
3625
+ return void 0;
3626
+ }
3627
+ const event = createCommon(gedcom, void 0, fam);
3628
+ event.type = input.tag;
3629
+ fam.assign(input.tag, event);
3630
+ fillFact(gedcom, fam, event, input);
3631
+ return event;
3632
+ };
3633
+
3634
+ // src/utils/family-edit.ts
3635
+ var PEDIGREE_VALUES = [
3636
+ "birth" /* BIRTH */,
3637
+ "adopted" /* ADOPTED */,
3638
+ "foster" /* FOSTER */,
3639
+ "step" /* STEP */,
3640
+ "sealing" /* SEALING */
3641
+ ];
3642
+ var toGedcomPedigree = (value) => {
3643
+ const normalized = String(value || "birth" /* BIRTH */).toLowerCase();
3644
+ if (normalized === "biological" /* BIOLOGICAL */ || normalized === "birth" /* BIRTH */) {
3645
+ return "birth" /* BIRTH */;
3646
+ }
3647
+ const match = PEDIGREE_VALUES.find((item) => item === normalized);
3648
+ return match ?? "birth" /* BIRTH */;
3649
+ };
3650
+ var pointerIds = (tag) => {
3651
+ if (!tag) {
3652
+ return [];
3653
+ }
3654
+ if (tag instanceof List) {
3655
+ return tag.values().map((item) => item?.toValue?.()).filter((value2) => !!value2);
3656
+ }
3657
+ const value = tag.toValue?.();
3658
+ return value ? [String(value)] : [];
3659
+ };
3660
+ var firstPointerId = (tag) => pointerIds(tag)[0];
3661
+ var makePointer = (gedcom, parent, value, refType) => {
3662
+ const pointer = createCommon(gedcom, void 0, parent);
3663
+ pointer.value = value;
3664
+ pointer.refType = refType;
3665
+ return pointer;
3666
+ };
3667
+ var familyHasParent = (fam, indiId) => pointerIds(fam.get("HUSB")).includes(indiId) || pointerIds(fam.get("WIFE")).includes(indiId);
3668
+ var familyHasChild = (fam, indiId) => pointerIds(fam.get("CHIL")).includes(indiId);
3669
+ var spouseTagFor = (indi, fam) => {
3670
+ const husbId = firstPointerId(fam.get("HUSB"));
3671
+ const wifeId = firstPointerId(fam.get("WIFE"));
3672
+ if (husbId === indi.id) {
3673
+ return "HUSB";
3674
+ }
3675
+ if (wifeId === indi.id) {
3676
+ return "WIFE";
3677
+ }
3678
+ if (indi.isFemale()) {
3679
+ return wifeId && wifeId !== indi.id ? "HUSB" : "WIFE";
3680
+ }
3681
+ if (indi.isMale()) {
3682
+ return husbId && husbId !== indi.id ? "WIFE" : "HUSB";
3683
+ }
3684
+ return husbId ? "WIFE" : "HUSB";
3685
+ };
3686
+ var canAttachAsSpouse = (fam, indi) => {
3687
+ if (!indi.id) {
3688
+ return false;
3689
+ }
3690
+ if (familyHasParent(fam, indi.id)) {
3691
+ return true;
3692
+ }
3693
+ const tag = spouseTagFor(indi, fam);
3694
+ const occupied = firstPointerId(fam.get(tag));
3695
+ return !occupied || occupied === indi.id;
3696
+ };
3697
+ var pointerByValue = (tag, id) => {
3698
+ if (!tag) {
3699
+ return void 0;
3700
+ }
3701
+ const fromValues = tag.toValueList?.().item(id);
3702
+ if (fromValues) {
3703
+ return fromValues;
3704
+ }
3705
+ return tag.toList()?.values().find((item) => item?.toValue?.() === id);
3706
+ };
3707
+ var setChildPedigree = (fam, child, pedigree, parent) => {
3708
+ if (!fam.id || !child.id) {
3709
+ return;
3710
+ }
3711
+ const pedi = toGedcomPedigree(pedigree);
3712
+ const famc = pointerByValue(child.get("FAMC"), fam.id);
3713
+ if (famc) {
3714
+ famc.set("PEDI", pedi);
3715
+ }
3716
+ const chil = pointerByValue(fam.get("CHIL"), child.id);
3717
+ if (!chil) {
3718
+ return;
3719
+ }
3720
+ const setFather = !parent || parent.isMale() || parent.isUnknownSex();
3721
+ const setMother = !parent || parent.isFemale() || parent.isUnknownSex();
3722
+ if (setFather) {
3723
+ chil.set("_FREL", pedi);
3724
+ }
3725
+ if (setMother) {
3726
+ chil.set("_MREL", pedi);
3727
+ }
3728
+ };
3729
+ var attachSpouseToFamily = (fam, indi) => {
3730
+ const gedcom = fam.getGedcom() ?? indi.getGedcom();
3731
+ if (!indi.id || !fam.id || !gedcom) {
3732
+ return false;
3733
+ }
3734
+ if (!canAttachAsSpouse(fam, indi)) {
3735
+ return false;
3736
+ }
3737
+ const tag = spouseTagFor(indi, fam);
3738
+ if (firstPointerId(fam.get(tag)) !== indi.id) {
3739
+ fam.set(tag, makePointer(gedcom, fam, indi.id, "INDI"));
3740
+ }
3741
+ indi.assign("FAMS", makePointer(gedcom, indi, fam.id, "FAM"), true);
3742
+ return true;
3743
+ };
3744
+ var attachChildToFamily = (fam, child, pedigree, parent) => {
3745
+ const gedcom = fam.getGedcom() ?? child.getGedcom();
3746
+ if (!child.id || !fam.id || !gedcom) {
3747
+ return false;
3748
+ }
3749
+ if (!familyHasChild(fam, child.id)) {
3750
+ fam.assign("CHIL", makePointer(gedcom, fam, child.id, "INDI"), true);
3751
+ }
3752
+ const existingFamc = pointerByValue(child.get("FAMC"), fam.id);
3753
+ if (!existingFamc) {
3754
+ child.assign("FAMC", makePointer(gedcom, child, fam.id, "FAM"), true);
3755
+ }
3756
+ setChildPedigree(fam, child, pedigree, parent);
3757
+ return true;
3758
+ };
3759
+ var findReusableParentChildFamily = (parent, child) => {
3760
+ if (!parent.id || !child.id) {
3761
+ return void 0;
3762
+ }
3763
+ let reusableFamc;
3764
+ let already = false;
3765
+ child.getFamilies("FAMC")?.forEach((fam) => {
3766
+ if (!fam) {
3767
+ return;
3768
+ }
3769
+ if (familyHasParent(fam, parent.id) && familyHasChild(fam, child.id)) {
3770
+ already = true;
3771
+ return;
3772
+ }
3773
+ if (!reusableFamc && canAttachAsSpouse(fam, parent)) {
3774
+ reusableFamc = fam;
3775
+ }
3776
+ });
3777
+ if (already) {
3778
+ return "already";
3779
+ }
3780
+ if (reusableFamc) {
3781
+ return reusableFamc;
3782
+ }
3783
+ const parentFams = [];
3784
+ parent.getFamilies("FAMS")?.forEach((fam) => {
3785
+ if (fam) {
3786
+ parentFams.push(fam);
3787
+ }
3788
+ });
3789
+ if (parentFams.length === 1) {
3790
+ return parentFams[0];
3791
+ }
3792
+ return void 0;
3793
+ };
3794
+
3291
3795
  // src/utils/get-places.ts
3292
3796
  var getPlaces = (common, type = ["ALL" /* All */], maxLevel = 1, level = 0, mainKey) => {
3293
3797
  const types = Array.isArray(type) ? type : [type];
@@ -3918,6 +4422,31 @@ var Fam = class extends Common {
3918
4422
  getParents() {
3919
4423
  return this.getHusband().copy().merge(this.getWife());
3920
4424
  }
4425
+ hasParent(indi) {
4426
+ const indiId = typeof indi === "string" ? indi : indi?.id;
4427
+ return !!indiId && familyHasParent(this, indiId);
4428
+ }
4429
+ hasChild(indi) {
4430
+ const indiId = typeof indi === "string" ? indi : indi?.id;
4431
+ return !!indiId && familyHasChild(this, indiId);
4432
+ }
4433
+ canAddSpouse(indi) {
4434
+ return canAttachAsSpouse(this, indi);
4435
+ }
4436
+ addSpouse(indi) {
4437
+ return attachSpouseToFamily(this, indi);
4438
+ }
4439
+ addChild(child, pedigree, parent) {
4440
+ return attachChildToFamily(
4441
+ this,
4442
+ child,
4443
+ pedigree,
4444
+ parent
4445
+ );
4446
+ }
4447
+ addFact(input) {
4448
+ return addFamilyFact(this, input);
4449
+ }
3921
4450
  toList() {
3922
4451
  return new Families().concat(
3923
4452
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -4018,19 +4547,51 @@ var ALLOWED_FACTS = [
4018
4547
  "OCCU",
4019
4548
  "OCCUPATIONS",
4020
4549
  "RESI",
4550
+ "BIRT",
4551
+ "DEAT",
4021
4552
  "BAPT",
4553
+ "BAPM",
4022
4554
  "CHRI",
4023
4555
  "CHR",
4556
+ "CHRA",
4024
4557
  "BURI",
4025
- "EDUC",
4558
+ "CREM",
4559
+ "ADOP",
4560
+ "BARM",
4561
+ "BASM",
4562
+ "BLES",
4563
+ "CONF",
4564
+ "FCOM",
4565
+ "ORDN",
4566
+ "NATU",
4567
+ "EMIG",
4568
+ "IMMI",
4569
+ "CENS",
4570
+ "PROB",
4571
+ "WILL",
4026
4572
  "GRAD",
4573
+ "RETI",
4574
+ "EDUC",
4027
4575
  "DIV",
4028
- "IMMI",
4029
4576
  "RELI",
4577
+ "CAST",
4578
+ "DSCR",
4579
+ "NATI",
4580
+ "PROP",
4581
+ "SSN",
4582
+ "TITL",
4583
+ "ADDR",
4584
+ "BAPL",
4585
+ "CONL",
4586
+ "ENDL",
4587
+ "SLGC",
4030
4588
  "_MILT",
4031
4589
  "_MILTID",
4032
4590
  "FACT",
4033
- "_ORIG"
4591
+ "_ORIG",
4592
+ "_WLNK",
4593
+ "WWW",
4594
+ "URL"
4034
4595
  ];
4035
4596
  var DISALLOWED_CUSTOM_FACTS = ["DNA Test", "Newspaper"];
4036
4597
  var CustomFactRenderers = {
@@ -4574,7 +5135,7 @@ var Indi = class extends Common {
4574
5135
  return result;
4575
5136
  }
4576
5137
  ancestryLink() {
4577
- const www = this._gedcom?.HEAD?.SOUR?.CORP?.WWW?.value;
5138
+ const www = this.getFromSourceHeads("SOUR.CORP.WWW.value") || this._gedcom?.HEAD?.SOUR?.CORP?.WWW?.value;
4578
5139
  const tree = this.getAncestryTreeId();
4579
5140
  if (this.id) {
4580
5141
  return `https://${www}/family-tree/person/tree/${tree}/person/${this.id.replace(
@@ -4586,7 +5147,7 @@ var Indi = class extends Common {
4586
5147
  async ancestryMedia(namespace) {
4587
5148
  const list = {};
4588
5149
  const objeList = this.get("OBJE")?.toList().copy();
4589
- const www = this._gedcom?.HEAD?.SOUR?.CORP?.WWW?.value;
5150
+ const www = this.getFromSourceHeads("SOUR.CORP.WWW.value") || this._gedcom?.HEAD?.SOUR?.CORP?.WWW?.value;
4590
5151
  const tree = this.getAncestryTreeId();
4591
5152
  if (objeList) {
4592
5153
  await Promise.all(
@@ -4646,7 +5207,7 @@ var Indi = class extends Common {
4646
5207
  return list;
4647
5208
  }
4648
5209
  myheritageLink(poolId = 0) {
4649
- const www = this._gedcom?.HEAD?.SOUR?.CORP?.value?.toLowerCase().replace(/^www\./gi, "");
5210
+ const www = (this.getFromSourceHeads("SOUR.CORP.value") || this._gedcom?.HEAD?.SOUR?.CORP?.value)?.toLowerCase().replace(/^www\./gi, "");
4650
5211
  const site = this.getMyHeritageTreeId();
4651
5212
  const file = this._gedcom?.HEAD?.get("FILE")?.toValue()?.match(/Exported by MyHeritage.com from .+ in (?<site>.+) on .+$/)?.groups?.site;
4652
5213
  const normalizedFile = file?.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-");
@@ -5167,6 +5728,57 @@ var Indi = class extends Common {
5167
5728
  isUnknownSex() {
5168
5729
  return !this.isMale() && !this.isFemale();
5169
5730
  }
5731
+ addSpouse(other) {
5732
+ if (!this.id || !other?.id || this.id === other.id || !this._gedcom) {
5733
+ return void 0;
5734
+ }
5735
+ const existing = getFamilyWith(this, other.id);
5736
+ if (existing) {
5737
+ return existing;
5738
+ }
5739
+ const fam = this._gedcom.createFamily();
5740
+ if (!fam.addSpouse(this) || !fam.addSpouse(other)) {
5741
+ return void 0;
5742
+ }
5743
+ return fam;
5744
+ }
5745
+ addChild(child, pedigree) {
5746
+ if (!this.id || !child?.id || this.id === child.id || !this._gedcom) {
5747
+ return void 0;
5748
+ }
5749
+ const existing = findReusableParentChildFamily(
5750
+ this,
5751
+ child
5752
+ );
5753
+ if (existing === "already") {
5754
+ const fam2 = child.getFamilies("FAMC")?.find(
5755
+ (item) => !!item && item.hasParent(this.id) && item.hasChild(child.id)
5756
+ );
5757
+ if (fam2) {
5758
+ setChildPedigree(
5759
+ fam2,
5760
+ child,
5761
+ pedigree,
5762
+ this
5763
+ );
5764
+ }
5765
+ return fam2;
5766
+ }
5767
+ const fam = existing ?? this._gedcom.createFamily();
5768
+ if (!fam.addSpouse(this)) {
5769
+ return void 0;
5770
+ }
5771
+ if (!fam.addChild(child, pedigree, this)) {
5772
+ return void 0;
5773
+ }
5774
+ return fam;
5775
+ }
5776
+ addParent(parent, pedigree) {
5777
+ return parent.addChild(this, pedigree);
5778
+ }
5779
+ addFact(input) {
5780
+ return addIndividualFact(this, input);
5781
+ }
5170
5782
  getParentType(id) {
5171
5783
  let indi;
5172
5784
  if (typeof id === "string" || typeof id === "number") {
@@ -5367,7 +5979,9 @@ var Indi = class extends Common {
5367
5979
  }
5368
5980
  }
5369
5981
  if (kinship !== "child" || !breakAfterSpouse) {
5370
- indi.getBiologicalFathers().copy().merge(indi.getBiologicalMothers()).merge(indi.getFathers().copy().merge(indi.getMothers())).forEach((relative) => {
5982
+ indi.getBiologicalFathers().copy().merge(indi.getBiologicalMothers()).merge(
5983
+ indi.getFathers().copy().merge(indi.getMothers())
5984
+ ).forEach((relative) => {
5371
5985
  if (!visited.has(relative)) {
5372
5986
  const currentRelation = indi.getParentType(relative);
5373
5987
  const isNonBiological = !!currentRelation && currentRelation !== "biological" /* BIOLOGICAL */;
@@ -6495,4 +7109,4 @@ var KinshipTranslatorDe = class extends KinshipTranslatorBasic {
6495
7109
  }
6496
7110
  };
6497
7111
 
6498
- export { KinshipTranslator, KinshipTranslatorBasic, KinshipTranslatorDe as KinshipTranslatorDE, KinshipTranslatorEn as KinshipTranslatorEN, KinshipTranslatorEs as KinshipTranslatorES, KinshipTranslatorFr as KinshipTranslatorFR, KinshipTranslatorHU, translators_exports as translators };
7112
+ export { KinshipTranslator, KinshipTranslatorBasic, KinshipTranslatorDe as KinshipTranslatorDE, KinshipTranslatorEn as KinshipTranslatorEN, KinshipTranslatorEs as KinshipTranslatorES, KinshipTranslatorFr as KinshipTranslatorFR, KinshipTranslatorHU, KinshipTranslatorRu as KinshipTranslatorRU, translators_exports as translators };