@treeviz/gedcom-parser 1.0.23 → 2.0.1

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.
@@ -1,6 +1,6 @@
1
- import { I as ICacheManager, P as PlaceParts } from '../place-parser-Dl5iva3h.js';
1
+ import { I as ICacheManager, P as PlaceParts } from '../place-parser-BLwBjtXS.js';
2
2
  import { Locale } from 'date-fns';
3
- import { af as IndiType, ac as IndiKey, ai as Language } from '../index-CSjQRlxq.js';
3
+ import { af as IndiType, ac as IndiKey, ai as Language } from '../index-B3Po1Kaw.js';
4
4
 
5
5
  /**
6
6
  * Factory function type for creating cache manager instances.
@@ -1109,11 +1109,30 @@ var Common = class _Common {
1109
1109
  const sour = get(head, "SOUR.value");
1110
1110
  return !!sour?.toLowerCase()?.startsWith("myheritage");
1111
1111
  }
1112
+ /**
1113
+ * Get the source type as a string (for prefixing tree IDs and names)
1114
+ * Returns the detected source type or undefined if unknown
1115
+ */
1116
+ getSourceType() {
1117
+ if (this.isAncestry()) return "Ancestry";
1118
+ if (this.isMyHeritage()) return "MyHeritage";
1119
+ if (this.isFamilySearch()) return "FamilySearch";
1120
+ if (this.isGNO2GED()) return "GNO2GED";
1121
+ if (this.isGenoPro()) return "GenoPro";
1122
+ if (this.isAhnenblatt()) return "Ahnenblatt";
1123
+ if (this.isGeni()) return "Geni";
1124
+ return void 0;
1125
+ }
1112
1126
  isFamilySearch() {
1113
1127
  const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
1114
1128
  const sourName = get(head, "SOUR.NAME.value");
1115
1129
  return sourName === "FamilySearch API";
1116
1130
  }
1131
+ isGNO2GED() {
1132
+ const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
1133
+ const sour = get(head, "SOUR.value");
1134
+ return sour === "GNO2GED";
1135
+ }
1117
1136
  getAncestryTreeId() {
1118
1137
  const path = "HEAD.SOUR._TREE.RIN.value";
1119
1138
  return get(this, path) || get(this.getGedcom(), path);
@@ -1124,11 +1143,34 @@ var Common = class _Common {
1124
1143
  }
1125
1144
  getTreeId() {
1126
1145
  if (this?.isAncestry()) {
1127
- return this.getAncestryTreeId();
1146
+ const id = this.getAncestryTreeId();
1147
+ if (id !== void 0) return id;
1128
1148
  }
1129
1149
  if (this?.isMyHeritage()) {
1130
- return this.getMyHeritageTreeId();
1150
+ const id = this.getMyHeritageTreeId();
1151
+ if (id !== void 0) return id;
1152
+ }
1153
+ if (this?.isFamilySearch()) {
1154
+ const id = this.getFamilySearchTreeId();
1155
+ if (id !== void 0) return id;
1131
1156
  }
1157
+ if (this?.isGNO2GED()) {
1158
+ const id = this.getGNO2GEDTreeId();
1159
+ if (id !== void 0) return id;
1160
+ }
1161
+ if (this?.isAhnenblatt()) {
1162
+ const id = this.getAhnenblattTreeId();
1163
+ if (id !== void 0) return id;
1164
+ }
1165
+ if (this?.isGeni()) {
1166
+ const id = this.getGeniTreeId();
1167
+ if (id !== void 0) return id;
1168
+ }
1169
+ if (this?.isGenoPro()) {
1170
+ const id = this.getGenoProTreeId();
1171
+ if (id !== void 0) return id;
1172
+ }
1173
+ return this.getUniversalTreeId();
1132
1174
  }
1133
1175
  getAncestryTreeName() {
1134
1176
  const path = "HEAD.SOUR._TREE.value";
@@ -1141,13 +1183,146 @@ var Common = class _Common {
1141
1183
  /Exported by MyHeritage.com from (?<tree>.+) in.+$/
1142
1184
  )?.groups?.tree;
1143
1185
  }
1186
+ getFamilySearchTreeId() {
1187
+ const rin = get(this, "HEAD.SOUR._TREE.RIN.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.RIN.value");
1188
+ if (rin) {
1189
+ return rin;
1190
+ }
1191
+ return "familysearch";
1192
+ }
1193
+ getFamilySearchTreeName() {
1194
+ const treeName = get(this, "HEAD.SOUR._TREE.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.value");
1195
+ if (treeName) {
1196
+ return treeName;
1197
+ }
1198
+ const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1199
+ return fileName || "FamilySearch Import";
1200
+ }
1201
+ getAhnenblattTreeId() {
1202
+ const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1203
+ if (fileName) {
1204
+ const idMatch = fileName.match(/_(\d+)/);
1205
+ if (idMatch) {
1206
+ return idMatch[1];
1207
+ }
1208
+ }
1209
+ return void 0;
1210
+ }
1211
+ getAhnenblattTreeName() {
1212
+ const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1213
+ return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
1214
+ }
1215
+ getGeniTreeId() {
1216
+ const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1217
+ if (fileName) {
1218
+ const idMatch = fileName.match(/_(\d+)/);
1219
+ if (idMatch) {
1220
+ return idMatch[1];
1221
+ }
1222
+ }
1223
+ return void 0;
1224
+ }
1225
+ getGeniTreeName() {
1226
+ const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1227
+ return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
1228
+ }
1229
+ getGenoProTreeId() {
1230
+ const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1231
+ if (fileName) {
1232
+ const idMatch = fileName.match(/_(\d+)/);
1233
+ if (idMatch) {
1234
+ return idMatch[1];
1235
+ }
1236
+ }
1237
+ return void 0;
1238
+ }
1239
+ getGenoProTreeName() {
1240
+ const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1241
+ return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
1242
+ }
1243
+ getGNO2GEDTreeId() {
1244
+ const rin = get(this, "HEAD._TREE.RIN.value") || get(this.getGedcom(), "HEAD._TREE.RIN.value");
1245
+ if (rin) {
1246
+ return rin;
1247
+ }
1248
+ return `gno_${this._gedcom?.refcount || "unknown"}`;
1249
+ }
1250
+ getGNO2GEDTreeName() {
1251
+ const treeName = get(this, "HEAD._TREE.value") || get(this.getGedcom(), "HEAD._TREE.value");
1252
+ if (treeName) {
1253
+ return treeName;
1254
+ }
1255
+ const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1256
+ return fileName || "GNO2GED Export";
1257
+ }
1258
+ /**
1259
+ * Universal tree ID getter for unknown/unrecognized GEDCOM sources
1260
+ * Tries to extract an ID from various common locations
1261
+ */
1262
+ getUniversalTreeId() {
1263
+ const sourceType = this.getSourceType();
1264
+ const prefix = sourceType ? sourceType.toLowerCase() : "tree";
1265
+ const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1266
+ if (fileName) {
1267
+ const idMatch = fileName.match(/_(\d+)/);
1268
+ if (idMatch) {
1269
+ return `${prefix}_${idMatch[1]}`;
1270
+ }
1271
+ }
1272
+ return `${prefix}_${this._gedcom?.refcount || "unknown"}`;
1273
+ }
1274
+ /**
1275
+ * Universal tree name getter for unknown/unrecognized GEDCOM sources
1276
+ * Tries to extract a name from various common locations
1277
+ */
1278
+ getUniversalTreeName() {
1279
+ const sourceType = this.getSourceType();
1280
+ const prefix = sourceType ? `${sourceType}-` : "";
1281
+ const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1282
+ if (fileName) {
1283
+ const cleanName = fileName.replace(/\.ged$/i, "").replace(/_/g, " ");
1284
+ return `${prefix}${cleanName}`;
1285
+ }
1286
+ const sourName = get(this, "HEAD.SOUR.NAME.value") || get(this.getGedcom(), "HEAD.SOUR.NAME.value");
1287
+ if (sourName) {
1288
+ return `${prefix}${sourName}`;
1289
+ }
1290
+ const sourValue = get(this, "HEAD.SOUR.value") || get(this.getGedcom(), "HEAD.SOUR.value");
1291
+ if (sourValue) {
1292
+ return `${prefix}${sourValue}`;
1293
+ }
1294
+ return `${prefix}Unknown Tree`;
1295
+ }
1144
1296
  getTreeName() {
1145
1297
  if (this?.isAncestry()) {
1146
- return this.getAncestryTreeName();
1298
+ const name = this.getAncestryTreeName();
1299
+ if (name) return name;
1147
1300
  }
1148
1301
  if (this?.isMyHeritage()) {
1149
- return this.getMyHeritageTreeName();
1302
+ const name = this.getMyHeritageTreeName();
1303
+ if (name) return name;
1304
+ }
1305
+ if (this?.isFamilySearch()) {
1306
+ const name = this.getFamilySearchTreeName();
1307
+ if (name) return name;
1308
+ }
1309
+ if (this?.isGNO2GED()) {
1310
+ const name = this.getGNO2GEDTreeName();
1311
+ if (name) return name;
1312
+ }
1313
+ if (this?.isAhnenblatt()) {
1314
+ const name = this.getAhnenblattTreeName();
1315
+ if (name) return name;
1150
1316
  }
1317
+ if (this?.isGeni()) {
1318
+ const name = this.getGeniTreeName();
1319
+ if (name) return name;
1320
+ }
1321
+ if (this?.isGenoPro()) {
1322
+ const name = this.getGenoProTreeName();
1323
+ if (name) return name;
1324
+ }
1325
+ return this.getUniversalTreeName();
1151
1326
  }
1152
1327
  };
1153
1328
  var createProxy = (target) => {
@@ -1562,66 +1737,125 @@ var getMarriageAscAndChildBirth = (person) => (itemA, keyA, itemB, keyB) => {
1562
1737
  const childB = familyB?.getChildren().orderBy(BIRTH_ASC).index(0);
1563
1738
  return getBirthAsc(childA, keyA, childB);
1564
1739
  };
1740
+ var getGedcomId = (gedcom) => {
1741
+ if (!gedcom) {
1742
+ return "unknown";
1743
+ }
1744
+ const treeId = gedcom.getTreeId?.() || "";
1745
+ const treeName = gedcom.getTreeName?.() || "";
1746
+ const sanitizedName = treeName.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
1747
+ if (treeId && sanitizedName) {
1748
+ return `${treeId}_${sanitizedName}`;
1749
+ } else if (treeId) {
1750
+ return treeId;
1751
+ } else if (sanitizedName) {
1752
+ return sanitizedName;
1753
+ }
1754
+ return `gedcom_${gedcom.refcount}`;
1755
+ };
1565
1756
  var caches = {
1566
1757
  pathCache: {},
1567
1758
  relativesOnDegreeCache: {},
1568
- relativesOnLevelCache: {}
1759
+ relativesOnLevelCache: {},
1760
+ profilePictureCache: {}
1569
1761
  };
1570
- var getInstance = getCacheManagerFactory();
1571
- var cacheDbs = {
1572
- pathCache: getInstance("ftv", "Main", "path", true),
1573
- relativesOnDegreeCache: getInstance(
1574
- "ftv",
1575
- "Main",
1576
- "path",
1577
- true
1578
- ),
1579
- relativesOnLevelCache: getInstance(
1580
- "ftv",
1581
- "Main",
1582
- "path",
1583
- true
1584
- )
1762
+ var cacheDbs;
1763
+ var getCacheDbs = () => {
1764
+ if (!cacheDbs) {
1765
+ const getInstance = getCacheManagerFactory();
1766
+ cacheDbs = {
1767
+ pathCache: getInstance(
1768
+ "ftv",
1769
+ "Main",
1770
+ "path",
1771
+ true
1772
+ ),
1773
+ relativesOnDegreeCache: getInstance("ftv", "Main", "path", true),
1774
+ relativesOnLevelCache: getInstance(
1775
+ "ftv",
1776
+ "Main",
1777
+ "path",
1778
+ true
1779
+ ),
1780
+ profilePictureCache: getInstance(
1781
+ "ftv",
1782
+ "Main",
1783
+ "images",
1784
+ false
1785
+ )
1786
+ };
1787
+ }
1788
+ return cacheDbs;
1585
1789
  };
1586
- ({
1790
+ var storeCache = {
1791
+ // NOTE: pathCache, relativesOnLevelCache, and relativesOnDegreeCache are intentionally
1792
+ // kept in memory only. These debounced functions exist to satisfy the type system
1793
+ // but are never called.
1587
1794
  pathCache: debounce((value) => {
1588
1795
  if (value) {
1589
- cacheDbs.pathCache.setItem(value);
1796
+ getCacheDbs().pathCache.setItem(value);
1590
1797
  }
1591
1798
  }, 50),
1592
1799
  relativesOnLevelCache: debounce((value) => {
1593
1800
  if (value) {
1594
- cacheDbs.relativesOnLevelCache.setItem(value);
1801
+ getCacheDbs().relativesOnLevelCache.setItem(value);
1595
1802
  }
1596
1803
  }, 50),
1597
1804
  relativesOnDegreeCache: debounce((value) => {
1598
1805
  if (value) {
1599
- cacheDbs.relativesOnDegreeCache.setItem(value);
1806
+ getCacheDbs().relativesOnDegreeCache.setItem(value);
1600
1807
  }
1601
- }, 50)
1602
- });
1603
- var relativesCache = (cacheKey) => (key, subKey, value) => {
1604
- if (!caches[cacheKey]) {
1808
+ }, 50),
1809
+ // profilePictureCache IS persisted to IndexedDB
1810
+ profilePictureCache: debounce((value) => {
1811
+ if (value) {
1812
+ getCacheDbs().profilePictureCache.setItem(value);
1813
+ }
1814
+ }, 100)
1815
+ };
1816
+ var relativesCache = (cacheKey) => (gedcom, key, subKey, value) => {
1817
+ const gedcomId = getGedcomId(gedcom);
1818
+ const fullKey = `${gedcomId}:${key}`;
1819
+ const cache = caches[cacheKey];
1820
+ if (!cache) {
1605
1821
  caches[cacheKey] = {};
1606
1822
  }
1607
- if (value && caches[cacheKey]) {
1608
- if (!caches[cacheKey][key]) {
1609
- caches[cacheKey][key] = {};
1823
+ if (value) {
1824
+ const typedCache2 = caches[cacheKey];
1825
+ if (!typedCache2[fullKey]) {
1826
+ typedCache2[fullKey] = {};
1610
1827
  }
1611
- caches[cacheKey][key][subKey] = value;
1612
- return caches[cacheKey][key][subKey];
1828
+ typedCache2[fullKey][subKey] = value;
1829
+ return typedCache2[fullKey][subKey];
1613
1830
  }
1614
- return caches[cacheKey]?.[key]?.[subKey];
1831
+ const typedCache = caches[cacheKey];
1832
+ return typedCache?.[fullKey]?.[subKey];
1615
1833
  };
1616
- var pathCache = (key, value) => {
1834
+ var pathCache = (gedcom, key, value) => {
1835
+ const gedcomId = getGedcomId(gedcom);
1836
+ const fullKey = `${gedcomId}:${key}`;
1617
1837
  if (!caches.pathCache) {
1618
1838
  caches.pathCache = {};
1619
1839
  }
1620
1840
  if (value && caches.pathCache) {
1621
- caches.pathCache[key] = value;
1622
- return caches.pathCache[key];
1841
+ caches.pathCache[fullKey] = value;
1842
+ return caches.pathCache[fullKey];
1623
1843
  }
1624
- return caches.pathCache?.[key];
1844
+ return caches.pathCache?.[fullKey];
1845
+ };
1846
+ var profilePictureCache = (gedcom, key, value) => {
1847
+ const gedcomId = getGedcomId(gedcom);
1848
+ const fullKey = `${gedcomId}:${key}`;
1849
+ if (!caches.profilePictureCache) {
1850
+ caches.profilePictureCache = {};
1851
+ }
1852
+ if (value && caches.profilePictureCache) {
1853
+ caches.profilePictureCache[fullKey] = value;
1854
+ storeCache.profilePictureCache(caches.profilePictureCache);
1855
+ return caches.profilePictureCache[fullKey];
1856
+ }
1857
+ const cached = caches.profilePictureCache?.[fullKey];
1858
+ return cached;
1625
1859
  };
1626
1860
 
1627
1861
  // src/utils/get-places.ts
@@ -2949,7 +3183,7 @@ var Indi = class extends Common {
2949
3183
  }
2950
3184
  async ancestryMedia(namespace) {
2951
3185
  const list = {};
2952
- const objeList = this.get("OBJE")?.toList();
3186
+ const objeList = this.get("OBJE")?.toList().copy();
2953
3187
  const www = this._gedcom?.HEAD?.SOUR?.CORP?.WWW?.value;
2954
3188
  const tree = this.getAncestryTreeId();
2955
3189
  if (objeList) {
@@ -2999,7 +3233,7 @@ var Indi = class extends Common {
2999
3233
  title,
3000
3234
  url,
3001
3235
  contentType: type,
3002
- downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName().replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
3236
+ downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
3003
3237
  };
3004
3238
  }
3005
3239
  })
@@ -3023,11 +3257,12 @@ var Indi = class extends Common {
3023
3257
  if (!tree) {
3024
3258
  return;
3025
3259
  }
3026
- const objeList = this.get("OBJE")?.toList();
3027
- const birthObj = this.get("BIRT.OBJE")?.toList();
3028
- const deathObj = this.get("DEAT.OBJE")?.toList();
3260
+ const objeList = this.get("OBJE")?.toList().copy();
3261
+ const birthObj = this.get("BIRT.OBJE")?.toList().copy();
3262
+ const deathObj = this.get("DEAT.OBJE")?.toList().copy();
3263
+ objeList?.merge(birthObj).merge(deathObj);
3029
3264
  (this.get("FAMS")?.toValueList().values() ?? []).concat(this.get("FAMC")?.toValueList().values() ?? []).forEach((fam) => {
3030
- objeList?.merge(birthObj).merge(deathObj).merge(fam?.get("MARR.OBJE"));
3265
+ objeList?.merge(fam?.get("MARR.OBJE"));
3031
3266
  });
3032
3267
  objeList?.forEach((o, index) => {
3033
3268
  if (!o) {
@@ -3053,7 +3288,7 @@ var Indi = class extends Common {
3053
3288
  title,
3054
3289
  url,
3055
3290
  contentType: type,
3056
- downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName().replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
3291
+ downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
3057
3292
  };
3058
3293
  }
3059
3294
  });
@@ -3145,6 +3380,85 @@ var Indi = class extends Common {
3145
3380
  };
3146
3381
  });
3147
3382
  }
3383
+ geniMedia() {
3384
+ const list = {};
3385
+ const objeList = this.get("OBJE")?.toList().copy();
3386
+ const sourList = this.get("SOUR")?.toList().copy();
3387
+ sourList?.forEach((sour) => {
3388
+ const sourObje = sour?.get("OBJE")?.toList();
3389
+ objeList?.merge(sourObje);
3390
+ });
3391
+ const rfn = this.get("RFN")?.toValue();
3392
+ const geniId = rfn?.replace(/^geni:/, "") || "unknown";
3393
+ objeList?.forEach((obje, index) => {
3394
+ if (!obje) {
3395
+ return;
3396
+ }
3397
+ const key = `@O${index}@`;
3398
+ const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
3399
+ const url = obje?.get("FILE")?.toValue();
3400
+ const title = obje?.get("TITL")?.toValue() ?? "";
3401
+ const type = obje?.get("FORM")?.toValue() ?? "raw";
3402
+ if (url) {
3403
+ const urlMatch = url.match(/\/([^/]+)\?hash=/);
3404
+ const imgId = urlMatch?.[1] || `img-${index}-${Date.now().toString(36)}`;
3405
+ const id = `geni-${geniId}-${imgId}`;
3406
+ list[id] = {
3407
+ isPrimary,
3408
+ key,
3409
+ id,
3410
+ tree: geniId,
3411
+ imgId,
3412
+ person: this.id,
3413
+ title,
3414
+ url,
3415
+ contentType: type,
3416
+ downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
3417
+ };
3418
+ }
3419
+ });
3420
+ return list;
3421
+ }
3422
+ universalMedia() {
3423
+ const list = {};
3424
+ if (!this.id) {
3425
+ return list;
3426
+ }
3427
+ const objeList = this.get("OBJE")?.toList().copy();
3428
+ if (!objeList || objeList.length === 0) {
3429
+ return list;
3430
+ }
3431
+ const rfn = this.get("RFN")?.toValue();
3432
+ const treeId = this.getUniversalTreeId() || rfn || "universal";
3433
+ objeList.forEach((obje, index) => {
3434
+ if (!obje) {
3435
+ return;
3436
+ }
3437
+ const key = `@O${index}@`;
3438
+ obje.standardizeMedia();
3439
+ const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
3440
+ const url = obje?.get("FILE")?.toValue();
3441
+ const title = obje?.get("TITL")?.toValue() ?? "";
3442
+ const type = obje?.get("FORM")?.toValue() ?? "raw";
3443
+ if (url) {
3444
+ const imgId = `media-${index}-${url.split("/").pop()?.split("?")[0]?.substring(0, 20) || Date.now().toString(36)}`;
3445
+ const id = `${treeId}-${this.id}-${imgId}`;
3446
+ list[id] = {
3447
+ isPrimary,
3448
+ key,
3449
+ id,
3450
+ tree: treeId,
3451
+ imgId,
3452
+ person: this.id,
3453
+ title,
3454
+ url,
3455
+ contentType: type,
3456
+ downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
3457
+ };
3458
+ }
3459
+ });
3460
+ return list;
3461
+ }
3148
3462
  async multimedia(namespace) {
3149
3463
  if (this?.isAncestry()) {
3150
3464
  return await this.ancestryMedia(namespace);
@@ -3152,11 +3466,30 @@ var Indi = class extends Common {
3152
3466
  if (this?.isMyHeritage()) {
3153
3467
  return this.myheritageMedia();
3154
3468
  }
3155
- return void 0;
3469
+ if (this?.isGeni()) {
3470
+ return this.geniMedia();
3471
+ }
3472
+ return this.universalMedia();
3156
3473
  }
3157
3474
  async getProfilePicture(namespace, onlyPrimary = true) {
3475
+ if (!this.id) {
3476
+ return void 0;
3477
+ }
3478
+ const cacheKey = this.id;
3479
+ const cached = profilePictureCache(
3480
+ this._gedcom,
3481
+ cacheKey
3482
+ );
3483
+ if (cached !== void 0) {
3484
+ return cached;
3485
+ }
3158
3486
  const mediaList = await this.multimedia(namespace);
3159
3487
  if (!mediaList) {
3488
+ profilePictureCache(
3489
+ this._gedcom,
3490
+ cacheKey,
3491
+ void 0
3492
+ );
3160
3493
  return void 0;
3161
3494
  }
3162
3495
  const mediaArray = Object.values(mediaList);
@@ -3164,27 +3497,41 @@ var Indi = class extends Common {
3164
3497
  (media) => media.isPrimary && isImageFormat(media.contentType || getFileExtension(media.url))
3165
3498
  );
3166
3499
  if (primaryMedia) {
3167
- return {
3500
+ const result = {
3168
3501
  file: primaryMedia.url,
3169
3502
  form: primaryMedia.contentType,
3170
3503
  title: primaryMedia.title,
3171
3504
  isPrimary: true
3172
3505
  };
3173
- }
3174
- if (!onlyPrimary) {
3506
+ profilePictureCache(this._gedcom, cacheKey, result);
3507
+ return result;
3508
+ }
3509
+ if (onlyPrimary) {
3510
+ profilePictureCache(
3511
+ this._gedcom,
3512
+ cacheKey,
3513
+ void 0
3514
+ );
3175
3515
  return void 0;
3176
3516
  }
3177
3517
  const secondaryMedia = mediaArray.find(
3178
3518
  (media) => isImageFormat(media.contentType || getFileExtension(media.url))
3179
3519
  );
3180
3520
  if (secondaryMedia) {
3181
- return {
3521
+ const result = {
3182
3522
  file: secondaryMedia.url,
3183
3523
  form: secondaryMedia.contentType,
3184
3524
  title: secondaryMedia.title,
3185
3525
  isPrimary: false
3186
3526
  };
3527
+ profilePictureCache(this._gedcom, cacheKey, result);
3528
+ return result;
3187
3529
  }
3530
+ profilePictureCache(
3531
+ this._gedcom,
3532
+ cacheKey,
3533
+ void 0
3534
+ );
3188
3535
  return void 0;
3189
3536
  }
3190
3537
  link(poolId) {
@@ -3552,7 +3899,7 @@ var Indi = class extends Common {
3552
3899
  return;
3553
3900
  }
3554
3901
  const cacheKey = `${this.id}|${usedIndi.id}`;
3555
- const cache = pathCache(cacheKey);
3902
+ const cache = pathCache(this._gedcom, cacheKey);
3556
3903
  if (cache) {
3557
3904
  return cache;
3558
3905
  }
@@ -3597,7 +3944,7 @@ var Indi = class extends Common {
3597
3944
  if (breakOnNext) {
3598
3945
  return void 0;
3599
3946
  }
3600
- pathCache(cacheKey, path2);
3947
+ pathCache(this._gedcom, cacheKey, path2);
3601
3948
  return path2;
3602
3949
  }
3603
3950
  visited.append(indi);
@@ -3767,7 +4114,7 @@ var Indi = class extends Common {
3767
4114
  }
3768
4115
  getRelativesOnDegree(degree = 0) {
3769
4116
  this.id = this.id || `@I${Math.random()}@`;
3770
- const cache = relativesOnDegreeCache(this.id, degree);
4117
+ const cache = relativesOnDegreeCache(this._gedcom, this.id, degree);
3771
4118
  if (cache) {
3772
4119
  return cache;
3773
4120
  }
@@ -3775,6 +4122,7 @@ var Indi = class extends Common {
3775
4122
  const excludes = persons;
3776
4123
  if (!Math.abs(degree)) {
3777
4124
  return relativesOnDegreeCache(
4125
+ this._gedcom,
3778
4126
  this.id,
3779
4127
  degree,
3780
4128
  persons.except(this)
@@ -3785,11 +4133,11 @@ var Indi = class extends Common {
3785
4133
  excludes.merge(persons);
3786
4134
  persons = this.getRelativesOnLevel(validDegree).getRelativesOnDegree(-validDegree).copy().exclude(excludes);
3787
4135
  }
3788
- return relativesOnDegreeCache(this.id, degree, persons);
4136
+ return relativesOnDegreeCache(this._gedcom, this.id, degree, persons);
3789
4137
  }
3790
4138
  getRelativesOnLevel(level = 0, filter) {
3791
4139
  this.id = this.id || `@I${Math.random()}@`;
3792
- const cache = relativesOnLevelCache(this.id, level);
4140
+ const cache = relativesOnLevelCache(this._gedcom, this.id, level);
3793
4141
  if (cache) {
3794
4142
  return cache;
3795
4143
  }
@@ -3800,7 +4148,7 @@ var Indi = class extends Common {
3800
4148
  };
3801
4149
  let families = this.get(config.key)?.toValueList();
3802
4150
  if (!families) {
3803
- return relativesOnLevelCache(this.id, level, persons);
4151
+ return relativesOnLevelCache(this._gedcom, this.id, level, persons);
3804
4152
  }
3805
4153
  if (filter) {
3806
4154
  families = families.filter(filter);
@@ -3811,7 +4159,12 @@ var Indi = class extends Common {
3811
4159
  persons = this.toFamilies(families).getParents();
3812
4160
  }
3813
4161
  if (level >= -1 && level <= 1) {
3814
- return relativesOnLevelCache(this.id, level, persons.except(this));
4162
+ return relativesOnLevelCache(
4163
+ this._gedcom,
4164
+ this.id,
4165
+ level,
4166
+ persons.except(this)
4167
+ );
3815
4168
  }
3816
4169
  for (let i = 1; i < Math.abs(level); i++) {
3817
4170
  if (config.isAscendant) {
@@ -3820,7 +4173,12 @@ var Indi = class extends Common {
3820
4173
  persons = persons.getParents();
3821
4174
  }
3822
4175
  }
3823
- return relativesOnLevelCache(this.id, level, persons.except(this));
4176
+ return relativesOnLevelCache(
4177
+ this._gedcom,
4178
+ this.id,
4179
+ level,
4180
+ persons.except(this)
4181
+ );
3824
4182
  }
3825
4183
  getAscendants(level = 0, filter) {
3826
4184
  if (!level) {
@@ -3859,7 +4217,12 @@ var Indi = class extends Common {
3859
4217
  }
3860
4218
  currentGen++;
3861
4219
  generations[currentGen] = descentants;
3862
- relativesOnLevelCache(this.id, -currentGen, descentants);
4220
+ relativesOnLevelCache(
4221
+ this._gedcom,
4222
+ this.id,
4223
+ -currentGen,
4224
+ descentants
4225
+ );
3863
4226
  descentants && relatives.merge(descentants);
3864
4227
  }
3865
4228
  return { relatives, generations };
@@ -3892,7 +4255,7 @@ var Indi = class extends Common {
3892
4255
  }
3893
4256
  currentGen++;
3894
4257
  generations[currentGen] = parents;
3895
- relativesOnLevelCache(this.id, currentGen, parents);
4258
+ relativesOnLevelCache(this._gedcom, this.id, currentGen, parents);
3896
4259
  parents && relatives.merge(parents);
3897
4260
  }
3898
4261
  return { relatives, generations };