@treeviz/gedcom-parser 2.1.12 → 2.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/classes/common.d.ts.map +1 -1
- package/dist/classes/date.d.ts +2 -0
- package/dist/classes/date.d.ts.map +1 -1
- package/dist/classes/index.js +69 -26
- package/dist/classes/indi.d.ts +2 -2
- package/dist/classes/indi.d.ts.map +1 -1
- package/dist/cli/index.js +70 -27
- package/dist/constants/index.js +1175 -1131
- package/dist/factories/index.js +1220 -1176
- package/dist/factories/kinship-factory.d.ts +2 -2
- package/dist/factories/kinship-factory.d.ts.map +1 -1
- package/dist/index.js +70 -27
- package/dist/kinship-translator/index.js +1220 -1176
- package/dist/kinship-translator/kinship-translator.basic.d.ts +3 -1
- package/dist/kinship-translator/kinship-translator.basic.d.ts.map +1 -1
- package/dist/kinship-translator/kinship-translator.d.ts +3 -2
- package/dist/kinship-translator/kinship-translator.d.ts.map +1 -1
- package/dist/structures/gedcom.d.ts +1 -0
- package/dist/structures/gedcom.d.ts.map +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 +3 -0
- package/dist/types/types.d.ts.map +1 -1
- package/dist/utils/common-creator.d.ts.map +1 -1
- package/dist/utils/date-formatter.d.ts.map +1 -1
- package/dist/utils/gedcom7-schema.d.ts.map +1 -1
- package/dist/utils/index.js +70 -27
- package/package.json +1 -1
|
@@ -9,11 +9,12 @@ var __export = (target, all) => {
|
|
|
9
9
|
|
|
10
10
|
// src/kinship-translator/kinship-translator.basic.ts
|
|
11
11
|
var KinshipTranslatorBasic = class {
|
|
12
|
-
constructor(path, displayName = "givenname") {
|
|
12
|
+
constructor(path, displayName = "givenname", nameOrder = "first-last") {
|
|
13
13
|
this.isOfSpouse = false;
|
|
14
14
|
this.isSpouseOf = false;
|
|
15
15
|
this._path = path;
|
|
16
16
|
this.displayName = displayName;
|
|
17
|
+
this.nameOrder = nameOrder;
|
|
17
18
|
}
|
|
18
19
|
get path() {
|
|
19
20
|
return this._path;
|
|
@@ -608,7 +609,7 @@ var KinshipTranslatorHU = class extends KinshipTranslatorBasic {
|
|
|
608
609
|
}
|
|
609
610
|
of(relation) {
|
|
610
611
|
const formattedName = nameFormatter(this.path?.[0]?.indi, {
|
|
611
|
-
nameOrder:
|
|
612
|
+
nameOrder: this.nameOrder
|
|
612
613
|
});
|
|
613
614
|
let name = formattedName.inOrder.filter(Boolean).join(" ");
|
|
614
615
|
if (this.displayName === "none") {
|
|
@@ -822,7 +823,7 @@ var KinshipTranslatorEn = class extends KinshipTranslatorBasic {
|
|
|
822
823
|
}
|
|
823
824
|
of(relation) {
|
|
824
825
|
const formattedName = nameFormatter(this.path?.[0]?.indi, {
|
|
825
|
-
nameOrder:
|
|
826
|
+
nameOrder: this.nameOrder
|
|
826
827
|
});
|
|
827
828
|
let name = formattedName.inOrder.filter(Boolean).join(" ");
|
|
828
829
|
if (this.displayName === "none") {
|
|
@@ -1032,7 +1033,7 @@ var KinshipTranslatorFr = class extends KinshipTranslatorBasic {
|
|
|
1032
1033
|
}
|
|
1033
1034
|
of(relation) {
|
|
1034
1035
|
const formattedName = nameFormatter(this.path?.[0]?.indi, {
|
|
1035
|
-
nameOrder:
|
|
1036
|
+
nameOrder: this.nameOrder
|
|
1036
1037
|
});
|
|
1037
1038
|
let name = formattedName.inOrder.filter(Boolean).join(" ");
|
|
1038
1039
|
if (this.displayName === "none") {
|
|
@@ -1370,7 +1371,7 @@ var KinshipTranslatorEs = class extends KinshipTranslatorBasic {
|
|
|
1370
1371
|
}
|
|
1371
1372
|
of(relation) {
|
|
1372
1373
|
const formattedName = nameFormatter(this.path?.[0]?.indi, {
|
|
1373
|
-
nameOrder:
|
|
1374
|
+
nameOrder: this.nameOrder
|
|
1374
1375
|
});
|
|
1375
1376
|
let name = formattedName.inOrder.filter(Boolean).join(" ");
|
|
1376
1377
|
if (this.displayName === "none") {
|
|
@@ -1677,7 +1678,7 @@ var KinshipTranslatorRu = class extends KinshipTranslatorBasic {
|
|
|
1677
1678
|
}
|
|
1678
1679
|
of(relation) {
|
|
1679
1680
|
const formattedName = nameFormatter(this.path?.[0]?.indi, {
|
|
1680
|
-
nameOrder:
|
|
1681
|
+
nameOrder: this.nameOrder
|
|
1681
1682
|
});
|
|
1682
1683
|
let name = formattedName.inOrder.filter(Boolean).join(" ");
|
|
1683
1684
|
if (this.displayName === "none") {
|
|
@@ -1913,7 +1914,7 @@ var KinshipTranslatorJa = class extends KinshipTranslatorBasic {
|
|
|
1913
1914
|
}
|
|
1914
1915
|
of(relation) {
|
|
1915
1916
|
const formattedName = nameFormatter(this.path?.[0]?.indi, {
|
|
1916
|
-
nameOrder:
|
|
1917
|
+
nameOrder: this.nameOrder
|
|
1917
1918
|
});
|
|
1918
1919
|
let name = formattedName.inOrder.filter(Boolean).join(" ");
|
|
1919
1920
|
if (this.displayName === "none") {
|
|
@@ -2162,7 +2163,7 @@ var KinshipTranslatorZh = class extends KinshipTranslatorBasic {
|
|
|
2162
2163
|
}
|
|
2163
2164
|
of(relation) {
|
|
2164
2165
|
const formattedName = nameFormatter(this.path?.[0]?.indi, {
|
|
2165
|
-
nameOrder:
|
|
2166
|
+
nameOrder: this.nameOrder
|
|
2166
2167
|
});
|
|
2167
2168
|
let name = formattedName.inOrder.filter(Boolean).join(" ");
|
|
2168
2169
|
if (this.displayName === "none") {
|
|
@@ -2231,22 +2232,30 @@ var KinshipTranslatorZh = class extends KinshipTranslatorBasic {
|
|
|
2231
2232
|
};
|
|
2232
2233
|
|
|
2233
2234
|
// src/kinship-translator/kinship-translator.ts
|
|
2235
|
+
var nameOrderForLang = (lang) => lang === "hu" || lang === "ja" || lang === "zh" ? "last-first" : "first-last";
|
|
2234
2236
|
var KinshipTranslator = class {
|
|
2235
|
-
constructor(person1, person2, lang = "en", entirePath, displayName = "givenname") {
|
|
2237
|
+
constructor(person1, person2, lang = "en", entirePath, displayName = "givenname", nameOrder) {
|
|
2236
2238
|
this.displayName = displayName;
|
|
2237
2239
|
this.lang = lang;
|
|
2238
2240
|
this.entirePath = entirePath;
|
|
2239
2241
|
this.person1 = person1;
|
|
2240
2242
|
this.person2 = typeof person2 === "string" ? this.person1.getGedcom()?.indi(person2) : person2;
|
|
2241
2243
|
this.path = this.person1.path(this.person2);
|
|
2244
|
+
const order = nameOrder ?? nameOrderForLang(lang);
|
|
2245
|
+
this.nameOrder = order;
|
|
2242
2246
|
if (translators_exports[lang]) {
|
|
2243
2247
|
this.translator = new translators_exports[lang](
|
|
2244
2248
|
this.path ?? [],
|
|
2245
|
-
displayName
|
|
2249
|
+
displayName,
|
|
2250
|
+
order
|
|
2246
2251
|
);
|
|
2247
2252
|
}
|
|
2248
2253
|
if (!this.translator) {
|
|
2249
|
-
this.translator = new KinshipTranslatorEn(
|
|
2254
|
+
this.translator = new KinshipTranslatorEn(
|
|
2255
|
+
this.path ?? [],
|
|
2256
|
+
displayName,
|
|
2257
|
+
order
|
|
2258
|
+
);
|
|
2250
2259
|
}
|
|
2251
2260
|
}
|
|
2252
2261
|
get path0() {
|
|
@@ -2291,14 +2300,16 @@ var KinshipTranslator = class {
|
|
|
2291
2300
|
showMainPerson,
|
|
2292
2301
|
this.lang,
|
|
2293
2302
|
false,
|
|
2294
|
-
this.displayName
|
|
2303
|
+
this.displayName,
|
|
2304
|
+
this.nameOrder
|
|
2295
2305
|
),
|
|
2296
2306
|
relative: this.path?.[index - 1]?.indi.kinship(
|
|
2297
2307
|
path2.indi.id,
|
|
2298
2308
|
showMainPerson,
|
|
2299
2309
|
this.lang,
|
|
2300
2310
|
false,
|
|
2301
|
-
this.displayName
|
|
2311
|
+
this.displayName,
|
|
2312
|
+
this.nameOrder
|
|
2302
2313
|
)
|
|
2303
2314
|
}));
|
|
2304
2315
|
return path;
|
|
@@ -2344,244 +2355,6 @@ var getKinshipTranslatorClass = () => {
|
|
|
2344
2355
|
return KinshipTranslatorClass;
|
|
2345
2356
|
};
|
|
2346
2357
|
|
|
2347
|
-
// src/utils/get-all-prop.ts
|
|
2348
|
-
var getAllProp = (indi, prop) => {
|
|
2349
|
-
return prop && (indi?.get(prop)?.toList().values() ?? []).filter(Boolean) || [];
|
|
2350
|
-
};
|
|
2351
|
-
|
|
2352
|
-
// src/utils/date-formatter.ts
|
|
2353
|
-
var ACCEPTED_DATE_FORMATS = [
|
|
2354
|
-
"yyyy.MM.dd.",
|
|
2355
|
-
"yyyy-MM-dd",
|
|
2356
|
-
"MM/dd/yyyy"
|
|
2357
|
-
];
|
|
2358
|
-
var ACCEPTED_DATE_FORMATS_REGEX = new RegExp(
|
|
2359
|
-
`(${ACCEPTED_DATE_FORMATS.map(
|
|
2360
|
-
(acceptedFormat) => acceptedFormat.replace(/[^.\-/]/g, "\\d")
|
|
2361
|
-
).join("|")})`,
|
|
2362
|
-
"gi"
|
|
2363
|
-
);
|
|
2364
|
-
var commonDateFormatter = (date, format2 = "yyyy", prefix = "") => {
|
|
2365
|
-
const formattedDate = date?.toValue(format2);
|
|
2366
|
-
if (!formattedDate) {
|
|
2367
|
-
return void 0;
|
|
2368
|
-
}
|
|
2369
|
-
return `${prefix}${formattedDate}`.trim();
|
|
2370
|
-
};
|
|
2371
|
-
var noteDateFormatter = (date, format2 = "yyyy", prefix = "", shortNote = true, showNote = true) => {
|
|
2372
|
-
const rawDate = commonDateFormatter(date, format2, "");
|
|
2373
|
-
if (!rawDate) {
|
|
2374
|
-
return void 0;
|
|
2375
|
-
}
|
|
2376
|
-
const note = date?.toNote(shortNote) ?? "";
|
|
2377
|
-
return `${prefix}${note && showNote ? i18n.t(`${note} {{date}}`, { date: rawDate }) : rawDate}`;
|
|
2378
|
-
};
|
|
2379
|
-
var marriageDateFormatter = (fam, showDays = false, showPlaces = false, shortNote = true, showNote = true, showDisplayTextIfNoDate = true, showAllEvents = false, dateFormatPattern) => {
|
|
2380
|
-
const fullDateFormat = i18n.t("dateFormat");
|
|
2381
|
-
const marriageDates = [];
|
|
2382
|
-
const marriagePlaces = [];
|
|
2383
|
-
const marriages = (fam?.toValueList().values() ?? []).flatMap((fam2) => {
|
|
2384
|
-
const family = fam2;
|
|
2385
|
-
const marrEvents = (family?.MARR?.toList().values() ?? []).filter(
|
|
2386
|
-
Boolean
|
|
2387
|
-
);
|
|
2388
|
-
if (marrEvents.length === 0) {
|
|
2389
|
-
const displayText = family?.get("DISPLAYTEXT")?.toValue() ?? "";
|
|
2390
|
-
if (showDisplayTextIfNoDate && displayText) {
|
|
2391
|
-
const displayDate = displayText.match(
|
|
2392
|
-
ACCEPTED_DATE_FORMATS_REGEX
|
|
2393
|
-
)?.[0];
|
|
2394
|
-
if (displayDate) {
|
|
2395
|
-
marriagePlaces.push(displayText.replace(displayDate, ""));
|
|
2396
|
-
const marriageDate = createCommonDate(
|
|
2397
|
-
fam2?.getGedcom(),
|
|
2398
|
-
void 0,
|
|
2399
|
-
family
|
|
2400
|
-
);
|
|
2401
|
-
marriageDate.value = displayDate;
|
|
2402
|
-
marriageDates.push(marriageDate);
|
|
2403
|
-
} else {
|
|
2404
|
-
marriagePlaces.push(displayText);
|
|
2405
|
-
marriageDates.push(void 0);
|
|
2406
|
-
return ["\u221E"];
|
|
2407
|
-
}
|
|
2408
|
-
}
|
|
2409
|
-
return [];
|
|
2410
|
-
}
|
|
2411
|
-
const eventsToProcess = showAllEvents ? marrEvents : marrEvents.slice(0, 1);
|
|
2412
|
-
return eventsToProcess.map((marrEvent) => {
|
|
2413
|
-
const marriageEventDetail = marrEvent;
|
|
2414
|
-
const marriageDate = marriageEventDetail?.DATE;
|
|
2415
|
-
const marriagePlace = showPlaces ? marriageEventDetail?.PLAC?.value : void 0;
|
|
2416
|
-
marriagePlaces.push(marriagePlace);
|
|
2417
|
-
marriageDates.push(marriageDate);
|
|
2418
|
-
const formattedDate = noteDateFormatter(
|
|
2419
|
-
marriageDate,
|
|
2420
|
-
showDays ? fullDateFormat : "yyyy",
|
|
2421
|
-
"\u221E",
|
|
2422
|
-
shortNote,
|
|
2423
|
-
showNote
|
|
2424
|
-
);
|
|
2425
|
-
return formattedDate ? formattedDate : void 0;
|
|
2426
|
-
});
|
|
2427
|
-
});
|
|
2428
|
-
const marriageArray = marriages.length ? marriages.filter(Boolean) : [];
|
|
2429
|
-
const datesArray = marriageArray.filter(Boolean);
|
|
2430
|
-
const placesArray = marriagePlaces.filter(Boolean);
|
|
2431
|
-
const dates = datesArray.join(" ").trim();
|
|
2432
|
-
return {
|
|
2433
|
-
rawArray: marriageDates,
|
|
2434
|
-
inArray: datesArray,
|
|
2435
|
-
inOrder: dates,
|
|
2436
|
-
places: placesArray,
|
|
2437
|
-
marriage: marriageArray,
|
|
2438
|
-
...showPlaces ? {
|
|
2439
|
-
marriages,
|
|
2440
|
-
marriagePlaces
|
|
2441
|
-
} : {}
|
|
2442
|
-
};
|
|
2443
|
-
};
|
|
2444
|
-
var dateFormatter = (indi, showMarriages = false, showDays = false, showPlaces = false, shortNote = true, showNote = true, isOnStage, showAllEvents = false, dateFormatPattern) => {
|
|
2445
|
-
const fullDateFormat = i18n.t("dateFormat");
|
|
2446
|
-
const birthEvents = getAllProp(indi, "BIRT");
|
|
2447
|
-
const firstBirthValue = birthEvents[0];
|
|
2448
|
-
const deathEvents = getAllProp(indi, "DEAT");
|
|
2449
|
-
const firstDeathValue = deathEvents[0];
|
|
2450
|
-
const birth = commonDateFormatter(
|
|
2451
|
-
firstBirthValue?.DATE,
|
|
2452
|
-
showDays ? fullDateFormat : "yyyy"
|
|
2453
|
-
);
|
|
2454
|
-
const birthPlace = showPlaces ? firstBirthValue?.PLAC?.value : void 0;
|
|
2455
|
-
const death = commonDateFormatter(
|
|
2456
|
-
firstDeathValue?.DATE,
|
|
2457
|
-
showDays ? fullDateFormat : "yyyy"
|
|
2458
|
-
);
|
|
2459
|
-
const deathPlace = showPlaces ? firstDeathValue?.PLAC?.value : void 0;
|
|
2460
|
-
const marriagePlaces = [];
|
|
2461
|
-
const marriages = [];
|
|
2462
|
-
if (showMarriages || isOnStage) {
|
|
2463
|
-
(indi?.get("FAMS")?.toValueList().values() ?? []).forEach((fam) => {
|
|
2464
|
-
const famRef = fam?.ref;
|
|
2465
|
-
const marriageDates = marriageDateFormatter(
|
|
2466
|
-
famRef,
|
|
2467
|
-
showDays,
|
|
2468
|
-
showPlaces,
|
|
2469
|
-
shortNote,
|
|
2470
|
-
showNote,
|
|
2471
|
-
true,
|
|
2472
|
-
showAllEvents);
|
|
2473
|
-
marriages.push(...marriageDates?.marriage ?? []);
|
|
2474
|
-
marriagePlaces.push(...marriageDates?.marriagePlaces ?? []);
|
|
2475
|
-
});
|
|
2476
|
-
}
|
|
2477
|
-
const birthStrings = [];
|
|
2478
|
-
const birthPlaces = [];
|
|
2479
|
-
const eventsToProcess = showAllEvents ? birthEvents : birthEvents.slice(0, 1);
|
|
2480
|
-
eventsToProcess.forEach((birthEvent) => {
|
|
2481
|
-
const birthDate = commonDateFormatter(
|
|
2482
|
-
birthEvent?.DATE,
|
|
2483
|
-
showDays ? fullDateFormat : "yyyy"
|
|
2484
|
-
);
|
|
2485
|
-
const birthEventNote = birthEvent?.DATE?.toNote(shortNote) ?? "";
|
|
2486
|
-
const birthEventPlace = showPlaces ? birthEvent?.PLAC?.value : void 0;
|
|
2487
|
-
if (birthDate) {
|
|
2488
|
-
birthStrings.push(
|
|
2489
|
-
`*${birthEventNote && showNote ? i18n.t(`${birthEventNote} {{date}}`, {
|
|
2490
|
-
date: birthDate
|
|
2491
|
-
}) : birthDate}`
|
|
2492
|
-
);
|
|
2493
|
-
}
|
|
2494
|
-
birthPlaces.push(birthEventPlace);
|
|
2495
|
-
});
|
|
2496
|
-
const deathStrings = [];
|
|
2497
|
-
const deathPlaces = [];
|
|
2498
|
-
const deathEventsToProcess = showAllEvents ? deathEvents : deathEvents.slice(0, 1);
|
|
2499
|
-
deathEventsToProcess.forEach((deathEvent) => {
|
|
2500
|
-
const deathDate = commonDateFormatter(
|
|
2501
|
-
deathEvent?.DATE,
|
|
2502
|
-
showDays ? fullDateFormat : "yyyy"
|
|
2503
|
-
);
|
|
2504
|
-
const deathEventNote = deathEvent?.DATE?.toNote(shortNote) ?? "";
|
|
2505
|
-
const deathEventPlace = showPlaces ? deathEvent?.PLAC?.value : void 0;
|
|
2506
|
-
if (deathDate) {
|
|
2507
|
-
deathStrings.push(
|
|
2508
|
-
`\u2020${deathEventNote && showNote ? i18n.t(`${deathEventNote} {{date}}`, {
|
|
2509
|
-
date: deathDate
|
|
2510
|
-
}) : deathDate}`
|
|
2511
|
-
);
|
|
2512
|
-
}
|
|
2513
|
-
deathPlaces.push(deathEventPlace);
|
|
2514
|
-
});
|
|
2515
|
-
const birthString = birthStrings[0] ?? "";
|
|
2516
|
-
const deathString = deathStrings[0] ?? "";
|
|
2517
|
-
const marriageArray = marriages.length ? marriages.filter(Boolean) : [];
|
|
2518
|
-
const datesArray = !birth && !death ? marriageArray : [...birthStrings, ...marriageArray, ...deathStrings];
|
|
2519
|
-
const placesArray = !birth && !death ? marriagePlaces : [...birthPlaces, ...marriagePlaces, ...deathPlaces];
|
|
2520
|
-
const nonNullDatesArray = datesArray.filter(Boolean);
|
|
2521
|
-
const dates = nonNullDatesArray.join(" ").trim();
|
|
2522
|
-
return {
|
|
2523
|
-
inArray: nonNullDatesArray,
|
|
2524
|
-
inOrder: dates,
|
|
2525
|
-
places: placesArray,
|
|
2526
|
-
birth: birthString,
|
|
2527
|
-
marriage: marriageArray,
|
|
2528
|
-
death: deathString,
|
|
2529
|
-
...showPlaces ? {
|
|
2530
|
-
birthPlace,
|
|
2531
|
-
deathPlace,
|
|
2532
|
-
...showMarriages ? { marriages, marriagePlaces } : {}
|
|
2533
|
-
} : {},
|
|
2534
|
-
...showAllEvents ? {
|
|
2535
|
-
births: birthStrings,
|
|
2536
|
-
birthPlaces,
|
|
2537
|
-
deaths: deathStrings,
|
|
2538
|
-
deathPlaces
|
|
2539
|
-
} : {}
|
|
2540
|
-
};
|
|
2541
|
-
};
|
|
2542
|
-
|
|
2543
|
-
// src/utils/range.ts
|
|
2544
|
-
var toTuple = (r) => {
|
|
2545
|
-
if (Array.isArray(r)) {
|
|
2546
|
-
const [s2, e2] = r;
|
|
2547
|
-
return [
|
|
2548
|
-
s2 === void 0 ? void 0 : Number(s2),
|
|
2549
|
-
e2 === void 0 ? void 0 : Number(e2)
|
|
2550
|
-
];
|
|
2551
|
-
}
|
|
2552
|
-
if (r === "-" || r === "") return [void 0, void 0];
|
|
2553
|
-
const [s, e] = r.split("-");
|
|
2554
|
-
return [s ? Number(s) : void 0, e ? Number(e) : void 0];
|
|
2555
|
-
};
|
|
2556
|
-
var isValidRange = (range) => {
|
|
2557
|
-
if (!Array.isArray(range) && range !== "" && range !== "-" && !/^\d*-\d*$/.test(range)) {
|
|
2558
|
-
return false;
|
|
2559
|
-
}
|
|
2560
|
-
if (Array.isArray(range) && range.some((r) => typeof r === "string" && isNaN(Number(r)))) {
|
|
2561
|
-
return false;
|
|
2562
|
-
}
|
|
2563
|
-
return true;
|
|
2564
|
-
};
|
|
2565
|
-
var inRange = (year, range, trueIfNoYear = false) => {
|
|
2566
|
-
if (!isValidRange(range)) {
|
|
2567
|
-
return false;
|
|
2568
|
-
}
|
|
2569
|
-
if (!year) {
|
|
2570
|
-
return trueIfNoYear;
|
|
2571
|
-
}
|
|
2572
|
-
const [start = -Infinity, end = Infinity] = toTuple(range);
|
|
2573
|
-
if (!start && !end) {
|
|
2574
|
-
return true;
|
|
2575
|
-
}
|
|
2576
|
-
if (start && !end) {
|
|
2577
|
-
return Number(year) >= Number(start);
|
|
2578
|
-
}
|
|
2579
|
-
if (!start && end) {
|
|
2580
|
-
return Number(year) <= Number(end);
|
|
2581
|
-
}
|
|
2582
|
-
return Number(start) <= Number(year) && Number(year) <= Number(end);
|
|
2583
|
-
};
|
|
2584
|
-
|
|
2585
2358
|
// src/constants/constants.ts
|
|
2586
2359
|
var ID_REG = /^@[_a-zA-Z0-9]+@/;
|
|
2587
2360
|
var ID_GETTER_REG = /^(?<at>@)?(?<letter>[A-Z])?/i;
|
|
@@ -2666,1087 +2439,1355 @@ var objeXrefKey = (obje, fallback = 0) => {
|
|
|
2666
2439
|
return `@O${fallback}@`;
|
|
2667
2440
|
};
|
|
2668
2441
|
var objeNoteValue = (obje) => mediaIdValue(obje, "FILE.NOTE") || mediaIdValue(obje, "NOTE") || "";
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2442
|
+
|
|
2443
|
+
// src/classes/common.ts
|
|
2444
|
+
var Common = class _Common {
|
|
2445
|
+
constructor(gedcom, id, main, parent) {
|
|
2673
2446
|
this.isListable = true;
|
|
2674
|
-
this.
|
|
2675
|
-
|
|
2676
|
-
|
|
2447
|
+
this._gedcom = gedcom;
|
|
2448
|
+
this._main = main;
|
|
2449
|
+
this._parent = parent;
|
|
2450
|
+
this.initUniqueId();
|
|
2451
|
+
if (id) {
|
|
2452
|
+
this._id = id;
|
|
2453
|
+
} else {
|
|
2454
|
+
delete this._id;
|
|
2677
2455
|
}
|
|
2678
2456
|
}
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
typeof indi === "string" ? indi : indi?.id ?? ""
|
|
2685
|
-
);
|
|
2457
|
+
set type(type) {
|
|
2458
|
+
if (type) {
|
|
2459
|
+
this.uniqueId = this.uniqueId?.replace(/^[^:]+/, `~${type}`);
|
|
2460
|
+
}
|
|
2461
|
+
this._type = type;
|
|
2686
2462
|
}
|
|
2687
|
-
get(
|
|
2688
|
-
|
|
2689
|
-
this.entries().forEach(([key, item]) => {
|
|
2690
|
-
propList.item(key, item.get(name));
|
|
2691
|
-
});
|
|
2692
|
-
return propList;
|
|
2463
|
+
get type() {
|
|
2464
|
+
return this._type;
|
|
2693
2465
|
}
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2466
|
+
initUniqueId() {
|
|
2467
|
+
if (this._gedcom) {
|
|
2468
|
+
this.uniqueId = `~Common:${this._gedcom.refcount++}`;
|
|
2469
|
+
}
|
|
2470
|
+
}
|
|
2471
|
+
set uniqueId(id) {
|
|
2472
|
+
const currentId = this._uniqueId;
|
|
2473
|
+
if (this._gedcom?.reflist && id) {
|
|
2474
|
+
this._uniqueId = id;
|
|
2475
|
+
if (currentId && this._gedcom.reflist[currentId]) {
|
|
2476
|
+
delete this._gedcom.reflist[currentId];
|
|
2700
2477
|
}
|
|
2701
|
-
|
|
2702
|
-
|
|
2478
|
+
this._gedcom.reflist[id] = this;
|
|
2479
|
+
}
|
|
2703
2480
|
}
|
|
2704
|
-
|
|
2705
|
-
return
|
|
2481
|
+
get uniqueId() {
|
|
2482
|
+
return this._uniqueId;
|
|
2706
2483
|
}
|
|
2707
|
-
|
|
2708
|
-
|
|
2484
|
+
set id(id) {
|
|
2485
|
+
this._id = idGetter(id);
|
|
2709
2486
|
}
|
|
2710
|
-
|
|
2711
|
-
return
|
|
2487
|
+
get id() {
|
|
2488
|
+
return idGetter(this._id);
|
|
2712
2489
|
}
|
|
2713
|
-
|
|
2490
|
+
set value(value) {
|
|
2491
|
+
this._value = value;
|
|
2714
2492
|
}
|
|
2715
|
-
|
|
2716
|
-
return this.
|
|
2493
|
+
get value() {
|
|
2494
|
+
return this._value;
|
|
2717
2495
|
}
|
|
2718
|
-
|
|
2719
|
-
|
|
2496
|
+
/**
|
|
2497
|
+
* Set the gedcom reference for this object
|
|
2498
|
+
* @param gedcom - The GedComType to set as the gedcom reference
|
|
2499
|
+
*/
|
|
2500
|
+
setGedcom(gedcom) {
|
|
2501
|
+
this._gedcom = gedcom;
|
|
2720
2502
|
}
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
return key && this.items[key];
|
|
2503
|
+
// avoid to override
|
|
2504
|
+
get originalValue() {
|
|
2505
|
+
return this._value;
|
|
2725
2506
|
}
|
|
2726
|
-
|
|
2727
|
-
if (
|
|
2728
|
-
|
|
2729
|
-
|
|
2507
|
+
get ref() {
|
|
2508
|
+
if (typeof this.value === "string" && isId(this.value) && this.refType) {
|
|
2509
|
+
return this._gedcom?.[getListTag(this.refType)]?.item(
|
|
2510
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2511
|
+
this.value
|
|
2512
|
+
);
|
|
2730
2513
|
}
|
|
2731
|
-
return
|
|
2514
|
+
return this;
|
|
2732
2515
|
}
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
this.setLength();
|
|
2516
|
+
get main() {
|
|
2517
|
+
return this._main;
|
|
2736
2518
|
}
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
delete this.items[itemId];
|
|
2740
|
-
});
|
|
2741
|
-
this.setLength();
|
|
2742
|
-
return this;
|
|
2519
|
+
get parent() {
|
|
2520
|
+
return this._parent;
|
|
2743
2521
|
}
|
|
2744
|
-
|
|
2745
|
-
if (
|
|
2746
|
-
|
|
2747
|
-
this.
|
|
2748
|
-
}
|
|
2749
|
-
|
|
2750
|
-
Object.assign(this.items, items ?? {});
|
|
2522
|
+
addRef(refNode) {
|
|
2523
|
+
if (typeof refNode.value === "string" && isId(refNode.value) && refNode.refType) {
|
|
2524
|
+
if (!this._refs) {
|
|
2525
|
+
this._refs = new List();
|
|
2526
|
+
}
|
|
2527
|
+
this._refs.item(refNode.value, refNode);
|
|
2751
2528
|
}
|
|
2752
|
-
this.setLength();
|
|
2753
|
-
return this;
|
|
2754
2529
|
}
|
|
2755
|
-
|
|
2756
|
-
this.
|
|
2757
|
-
return this;
|
|
2530
|
+
getRefs() {
|
|
2531
|
+
return this._refs;
|
|
2758
2532
|
}
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
this.values(),
|
|
2762
|
-
mergedList?.values() ?? [],
|
|
2763
|
-
"id"
|
|
2764
|
-
);
|
|
2765
|
-
return new _List(inter);
|
|
2533
|
+
exportValue() {
|
|
2534
|
+
return this.value;
|
|
2766
2535
|
}
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
this.values(),
|
|
2770
|
-
mergedList?.values() ?? [],
|
|
2771
|
-
"id"
|
|
2772
|
-
);
|
|
2773
|
-
return new _List(inter);
|
|
2536
|
+
removeValue() {
|
|
2537
|
+
delete this._value;
|
|
2774
2538
|
}
|
|
2775
|
-
|
|
2776
|
-
if (
|
|
2777
|
-
|
|
2778
|
-
if (this.items[item.id]) {
|
|
2779
|
-
delete this.items[item.id];
|
|
2780
|
-
increase = false;
|
|
2781
|
-
}
|
|
2782
|
-
this.items = Object.assign(
|
|
2783
|
-
{
|
|
2784
|
-
[item.id]: item
|
|
2785
|
-
},
|
|
2786
|
-
this.items
|
|
2787
|
-
);
|
|
2788
|
-
if (increase) {
|
|
2789
|
-
this.setLength("increase");
|
|
2790
|
-
}
|
|
2539
|
+
set(name, value) {
|
|
2540
|
+
if (isGedcomTrailerTag(name)) {
|
|
2541
|
+
return void 0;
|
|
2791
2542
|
}
|
|
2792
|
-
|
|
2543
|
+
if (typeof value === "string") {
|
|
2544
|
+
const usedValue = createCommon(this._gedcom, void 0, this.main);
|
|
2545
|
+
usedValue.value = value;
|
|
2546
|
+
set(this, name, usedValue);
|
|
2547
|
+
} else {
|
|
2548
|
+
set(this, name, value);
|
|
2549
|
+
}
|
|
2550
|
+
return get(this, name);
|
|
2793
2551
|
}
|
|
2794
|
-
|
|
2795
|
-
if (
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
this.setLength("increase");
|
|
2552
|
+
assign(name, value, unique = false) {
|
|
2553
|
+
if (isGedcomTrailerTag(name)) {
|
|
2554
|
+
return void 0;
|
|
2555
|
+
}
|
|
2556
|
+
let curValue = this.get(name);
|
|
2557
|
+
if (curValue?.isListable) {
|
|
2558
|
+
if (curValue instanceof _Common) {
|
|
2559
|
+
curValue = new List().concat({ ...[curValue] });
|
|
2560
|
+
this.set(name, curValue);
|
|
2804
2561
|
}
|
|
2562
|
+
const values = [
|
|
2563
|
+
...curValue.values(),
|
|
2564
|
+
...value instanceof List ? value.values() : [value]
|
|
2565
|
+
];
|
|
2566
|
+
curValue.concat({
|
|
2567
|
+
...!unique ? values : uniqBy(
|
|
2568
|
+
values,
|
|
2569
|
+
(value2) => value2 instanceof _Common ? value2?.value : void 0
|
|
2570
|
+
)
|
|
2571
|
+
});
|
|
2572
|
+
} else {
|
|
2573
|
+
this.set(name, value);
|
|
2805
2574
|
}
|
|
2806
|
-
return this;
|
|
2575
|
+
return get(this, name);
|
|
2807
2576
|
}
|
|
2808
|
-
|
|
2809
|
-
if (
|
|
2810
|
-
|
|
2811
|
-
this.setLength("decrease");
|
|
2577
|
+
get(name) {
|
|
2578
|
+
if (!name.includes(".")) {
|
|
2579
|
+
return get(this, name);
|
|
2812
2580
|
}
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2581
|
+
const nameParts = name.split(".");
|
|
2582
|
+
let last = this;
|
|
2583
|
+
for (const part of nameParts) {
|
|
2584
|
+
const indexPart = Number(part);
|
|
2585
|
+
const itemIndex = part.match(/items\[(?<itemIndex>\d+)\]/)?.groups?.itemIndex;
|
|
2586
|
+
const itemId = part.match(/items\[(?<itemId>@[A-Z]+\d+@)\]/)?.groups?.itemId;
|
|
2587
|
+
const usedPart = itemId || itemIndex;
|
|
2588
|
+
if (last instanceof List) {
|
|
2589
|
+
if (!isNaN(indexPart)) {
|
|
2590
|
+
last = last.index(indexPart);
|
|
2591
|
+
} else {
|
|
2592
|
+
if (usedPart) {
|
|
2593
|
+
last = last.item(usedPart);
|
|
2594
|
+
} else {
|
|
2595
|
+
last = last?.index(0)?.get(part);
|
|
2596
|
+
}
|
|
2597
|
+
}
|
|
2598
|
+
} else {
|
|
2599
|
+
const usedIndex = Number(itemIndex ?? indexPart);
|
|
2600
|
+
if (!isNaN(usedIndex)) {
|
|
2601
|
+
last = last?.toList().index(usedIndex);
|
|
2602
|
+
} else {
|
|
2603
|
+
last = last?.get(itemId ?? part);
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
if (!last) {
|
|
2607
|
+
break;
|
|
2608
|
+
}
|
|
2609
|
+
}
|
|
2610
|
+
return last;
|
|
2823
2611
|
}
|
|
2824
|
-
|
|
2825
|
-
this
|
|
2826
|
-
iterate(item, key, index);
|
|
2827
|
-
});
|
|
2612
|
+
remove(name) {
|
|
2613
|
+
unset(this, name);
|
|
2828
2614
|
}
|
|
2829
|
-
|
|
2830
|
-
return this.
|
|
2831
|
-
return iterate(item, key, index);
|
|
2832
|
-
});
|
|
2615
|
+
getGedcom() {
|
|
2616
|
+
return this._gedcom;
|
|
2833
2617
|
}
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2618
|
+
getIf(name, condition, name2) {
|
|
2619
|
+
const nameParts = name.split(".");
|
|
2620
|
+
const name2Parts = name2.split(".");
|
|
2621
|
+
if (nameParts.length !== name2Parts.length) {
|
|
2622
|
+
throw new Error("Tag pathes must be of the same depth");
|
|
2623
|
+
}
|
|
2624
|
+
if (nameParts.length > 1 && nameParts[0] !== name2Parts[0]) {
|
|
2625
|
+
throw new Error("Final tags must be siblings");
|
|
2626
|
+
}
|
|
2627
|
+
const valueCommon = this.get(name);
|
|
2628
|
+
if (valueCommon instanceof _Common) {
|
|
2629
|
+
return valueCommon?.toValue() !== condition ? void 0 : this.get(name2);
|
|
2630
|
+
}
|
|
2631
|
+
const valueCommon2 = this.get(name2)?.toList();
|
|
2632
|
+
const ifList = new List();
|
|
2633
|
+
valueCommon?.forEach((item, key) => {
|
|
2634
|
+
const pair = valueCommon2?.item(key);
|
|
2635
|
+
ifList.item(key, item?.toValue() !== condition ? void 0 : pair);
|
|
2636
|
+
});
|
|
2637
|
+
return ifList;
|
|
2838
2638
|
}
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2639
|
+
toString() {
|
|
2640
|
+
return this.value?.toString() || "";
|
|
2641
|
+
}
|
|
2642
|
+
toValue() {
|
|
2643
|
+
return this.value;
|
|
2644
|
+
}
|
|
2645
|
+
toProp(tag) {
|
|
2646
|
+
const prop = this.get(tag);
|
|
2647
|
+
return prop;
|
|
2648
|
+
}
|
|
2649
|
+
toList() {
|
|
2650
|
+
return new List().concat(
|
|
2651
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2652
|
+
this.id ? { [this.id]: this } : { ...[this] }
|
|
2653
|
+
);
|
|
2654
|
+
}
|
|
2655
|
+
index(i) {
|
|
2656
|
+
return this.toList()?.index(i);
|
|
2657
|
+
}
|
|
2658
|
+
toValueList() {
|
|
2659
|
+
return new List().concat(
|
|
2660
|
+
this.value ? { [this.value]: this } : (
|
|
2661
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2662
|
+
{ ...[this] }
|
|
2663
|
+
)
|
|
2664
|
+
);
|
|
2665
|
+
}
|
|
2666
|
+
standardizeObject(tag, options) {
|
|
2667
|
+
if (tag === "OBJE" && options?.obje?.standardize && "standardizeMedia" in this) {
|
|
2668
|
+
const standardize = this.standardizeMedia;
|
|
2669
|
+
return standardize.call(
|
|
2670
|
+
this,
|
|
2671
|
+
options.obje.namespace,
|
|
2672
|
+
options.obje.override,
|
|
2673
|
+
this.isAncestry() ? ancestryMediaFileUrl : void 0,
|
|
2674
|
+
options.gedcomVersion
|
|
2675
|
+
);
|
|
2676
|
+
}
|
|
2677
|
+
}
|
|
2678
|
+
toJson(tag, options) {
|
|
2679
|
+
const json = this.toObject(tag, options);
|
|
2680
|
+
return JSON.stringify(json);
|
|
2681
|
+
}
|
|
2682
|
+
toObject(tag, options) {
|
|
2683
|
+
this.standardizeObject(tag, options);
|
|
2684
|
+
const validKeys = getValidKeys(this);
|
|
2685
|
+
let json = {};
|
|
2686
|
+
validKeys.forEach((key) => {
|
|
2687
|
+
if (options?.persist && (key === "DAY" || key === "MONTH" || key === "YEAR")) {
|
|
2845
2688
|
return;
|
|
2846
2689
|
}
|
|
2847
|
-
if (
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2690
|
+
if (key === "id" && this.id !== void 0) {
|
|
2691
|
+
json.id = this.id;
|
|
2692
|
+
} else if (key === "_id" && this._id !== void 0) {
|
|
2693
|
+
json.id = this._id;
|
|
2694
|
+
} else if (key === "value" && this.value !== void 0) {
|
|
2695
|
+
json.value = this.value;
|
|
2696
|
+
} else if (key === "_value" && this._value !== void 0) {
|
|
2697
|
+
json.value = this._value;
|
|
2698
|
+
} else {
|
|
2699
|
+
const validKey = key;
|
|
2700
|
+
const prop = this.get(validKey);
|
|
2701
|
+
if (typeof prop?.toObject === "function") {
|
|
2702
|
+
if (prop instanceof _Common) {
|
|
2703
|
+
json[validKey] = prop.toObject(validKey, options);
|
|
2704
|
+
} else if (prop instanceof List) {
|
|
2705
|
+
json = {
|
|
2706
|
+
...json,
|
|
2707
|
+
...prop.toObject(validKey, options)
|
|
2708
|
+
};
|
|
2709
|
+
}
|
|
2856
2710
|
}
|
|
2857
|
-
return itemValue === value;
|
|
2858
|
-
})) {
|
|
2859
|
-
newList.item(itemId, item);
|
|
2860
2711
|
}
|
|
2861
2712
|
});
|
|
2862
|
-
return
|
|
2713
|
+
return json;
|
|
2863
2714
|
}
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
}
|
|
2873
|
-
return false;
|
|
2715
|
+
merge(other, override = false, avoidKeys = []) {
|
|
2716
|
+
if (!other) {
|
|
2717
|
+
return this;
|
|
2718
|
+
}
|
|
2719
|
+
const validKeys = getValidKeys(other);
|
|
2720
|
+
validKeys.forEach((validKey) => {
|
|
2721
|
+
if (avoidKeys.includes(validKey)) {
|
|
2722
|
+
return;
|
|
2874
2723
|
}
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
if (
|
|
2883
|
-
|
|
2724
|
+
const current = this.get(validKey);
|
|
2725
|
+
const mergeValue = other.get(validKey);
|
|
2726
|
+
if (mergeValue) {
|
|
2727
|
+
if (current instanceof _Common && !current.isListable) {
|
|
2728
|
+
if (override) {
|
|
2729
|
+
this.set(validKey, mergeValue);
|
|
2730
|
+
}
|
|
2731
|
+
} else if (current instanceof _Common || current instanceof List) {
|
|
2732
|
+
this.assign(validKey, mergeValue, true);
|
|
2733
|
+
} else if (!current || override && validKey !== "id" && validKey !== "_id") {
|
|
2734
|
+
this.set(validKey, mergeValue);
|
|
2884
2735
|
}
|
|
2885
|
-
return itemValue === value;
|
|
2886
|
-
})) {
|
|
2887
|
-
foundItem = item;
|
|
2888
|
-
return true;
|
|
2889
2736
|
}
|
|
2890
|
-
return false;
|
|
2891
2737
|
});
|
|
2892
|
-
return
|
|
2738
|
+
return this;
|
|
2893
2739
|
}
|
|
2894
|
-
|
|
2895
|
-
const
|
|
2896
|
-
const
|
|
2897
|
-
|
|
2898
|
-
|
|
2740
|
+
clone(newId = false, avoidKeys = []) {
|
|
2741
|
+
const ctor = this.constructor;
|
|
2742
|
+
const instance = new ctor(
|
|
2743
|
+
this._gedcom,
|
|
2744
|
+
this._id,
|
|
2745
|
+
this._main,
|
|
2746
|
+
this._parent
|
|
2747
|
+
);
|
|
2748
|
+
if (newId && this._id) {
|
|
2749
|
+
instance.id = `IFT${this._id.replace(/[^0-9]/g, "")}`;
|
|
2899
2750
|
}
|
|
2900
|
-
const
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2751
|
+
const cloned = createProxy(instance);
|
|
2752
|
+
cloned.merge(this, true, avoidKeys);
|
|
2753
|
+
return cloned;
|
|
2754
|
+
}
|
|
2755
|
+
// fromGedcom<T = typeof this>(value: string) {
|
|
2756
|
+
fromGedcom(_value) {
|
|
2757
|
+
}
|
|
2758
|
+
toGedcom(tag, level = 0, options) {
|
|
2759
|
+
const gedcom = this.toGedcomLines(tag, level, options);
|
|
2760
|
+
return gedcom.join("\n");
|
|
2761
|
+
}
|
|
2762
|
+
toGedcomLines(tag, level = 0, options) {
|
|
2763
|
+
this.standardizeObject(tag, options);
|
|
2764
|
+
const validKeys = getValidKeys(this);
|
|
2765
|
+
const gedcom = [];
|
|
2766
|
+
const isGedcom7Export = options?.gedcomVersion === "7.0";
|
|
2767
|
+
validKeys.forEach((key) => {
|
|
2768
|
+
const validKey = key;
|
|
2769
|
+
if (isGedcom7Export && validKey === "CONC") {
|
|
2770
|
+
return;
|
|
2771
|
+
}
|
|
2772
|
+
const prop = this.get(validKey);
|
|
2773
|
+
if (typeof prop?.toGedcomLines === "function") {
|
|
2774
|
+
if (prop instanceof _Common) {
|
|
2775
|
+
const value = prop.exportValue();
|
|
2776
|
+
gedcom.push(
|
|
2777
|
+
`${level} ${validKey}${value ? ` ${value}` : ""}`
|
|
2778
|
+
);
|
|
2779
|
+
gedcom.push(
|
|
2780
|
+
...prop.toGedcomLines(validKey, level + 1, options)
|
|
2781
|
+
);
|
|
2782
|
+
} else if (prop instanceof List) {
|
|
2783
|
+
gedcom.push(
|
|
2784
|
+
...prop.toGedcomLines(validKey, level, options)
|
|
2785
|
+
);
|
|
2927
2786
|
}
|
|
2928
|
-
return sortValue * (direction === "DESC" ? -1 : 1);
|
|
2929
2787
|
}
|
|
2930
|
-
);
|
|
2931
|
-
sortedItems.forEach(([key, value]) => {
|
|
2932
|
-
newList.item(key, value);
|
|
2933
2788
|
});
|
|
2934
|
-
return
|
|
2789
|
+
return gedcom;
|
|
2935
2790
|
}
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
const isIterator = typeof groups === "function";
|
|
2939
|
-
if (!isIterator && (!groups || !Object.keys(groups).length)) {
|
|
2940
|
-
groupped.Unknown = new ClassName().merge(this);
|
|
2941
|
-
groupped.Unknown.marker = "Unknown";
|
|
2942
|
-
return groupped;
|
|
2943
|
-
}
|
|
2944
|
-
this.forEach((item, itemId) => {
|
|
2945
|
-
const group = [];
|
|
2946
|
-
if (isIterator) {
|
|
2947
|
-
const newGroups = groups(item, itemId);
|
|
2948
|
-
group.push(
|
|
2949
|
-
...Array.isArray(newGroups) ? newGroups : [newGroups]
|
|
2950
|
-
);
|
|
2951
|
-
} else {
|
|
2952
|
-
const [key, { getter }] = Object.entries(
|
|
2953
|
-
typeof groups === "string" ? { [groups]: {} } : groups
|
|
2954
|
-
)[0];
|
|
2955
|
-
const raw = item.get(key)?.index(0);
|
|
2956
|
-
let value = raw?.toValue();
|
|
2957
|
-
if (getter && typeof getter === "function") {
|
|
2958
|
-
value = getter(value, raw);
|
|
2959
|
-
}
|
|
2960
|
-
if (value) {
|
|
2961
|
-
group.push(value);
|
|
2962
|
-
}
|
|
2963
|
-
}
|
|
2964
|
-
if (!group.length) {
|
|
2965
|
-
group.push("Unknown");
|
|
2966
|
-
}
|
|
2967
|
-
group.forEach((g) => {
|
|
2968
|
-
const newGroup = typeof g === "string" ? { group: g } : g;
|
|
2969
|
-
if (!groupped[newGroup.group]) {
|
|
2970
|
-
groupped[newGroup.group] = new ClassName();
|
|
2971
|
-
groupped[newGroup.group].marker = newGroup.marker ?? newGroup.group;
|
|
2972
|
-
}
|
|
2973
|
-
groupped[newGroup.group]?.append(item);
|
|
2974
|
-
});
|
|
2975
|
-
});
|
|
2976
|
-
if (sort) {
|
|
2977
|
-
return Object.entries(groupped).toSorted(([ak, a], [bk, b]) => {
|
|
2978
|
-
if (typeof sort === "function") {
|
|
2979
|
-
return sort(a, ak, b, bk);
|
|
2980
|
-
}
|
|
2981
|
-
if (ak === "Unknown") {
|
|
2982
|
-
return 1;
|
|
2983
|
-
}
|
|
2984
|
-
if (bk === "Unknown") {
|
|
2985
|
-
return -1;
|
|
2986
|
-
}
|
|
2987
|
-
if (sort === "group") {
|
|
2988
|
-
return ak.localeCompare(bk);
|
|
2989
|
-
}
|
|
2990
|
-
return (b?.length ?? 0) - (a?.length ?? 0);
|
|
2991
|
-
}).reduce((acc, [key, value]) => {
|
|
2992
|
-
if (minOccurance > -1 && (value?.length ?? 0) < minOccurance) {
|
|
2993
|
-
const otherKey = lessOccuranceLabel;
|
|
2994
|
-
acc[otherKey] = acc[otherKey] && value ? acc[otherKey].merge(value) : value;
|
|
2995
|
-
} else {
|
|
2996
|
-
acc[key] = value;
|
|
2997
|
-
}
|
|
2998
|
-
return acc;
|
|
2999
|
-
}, {});
|
|
3000
|
-
}
|
|
3001
|
-
return groupped;
|
|
3002
|
-
}
|
|
3003
|
-
findIndex(item) {
|
|
3004
|
-
if (!item?.id) {
|
|
3005
|
-
return -1;
|
|
3006
|
-
}
|
|
3007
|
-
return this.keys().findIndex((key) => key === item.id);
|
|
2791
|
+
getHeadRecord() {
|
|
2792
|
+
return get(this, "HEAD") || get(this.getGedcom(), "HEAD");
|
|
3008
2793
|
}
|
|
3009
|
-
|
|
3010
|
-
return this.
|
|
2794
|
+
getOriginalHeadRecord() {
|
|
2795
|
+
return get(this, ORIG_HEAD_TAG) || get(this.getGedcom(), ORIG_HEAD_TAG) || get(this.getHeadRecord(), ORIG_HEAD_TAG);
|
|
3011
2796
|
}
|
|
3012
|
-
|
|
3013
|
-
const
|
|
3014
|
-
return
|
|
2797
|
+
getSourceHeads() {
|
|
2798
|
+
const heads = [this.getOriginalHeadRecord(), this.getHeadRecord()];
|
|
2799
|
+
return heads.filter((head, index) => {
|
|
2800
|
+
return Boolean(head && heads.indexOf(head) === index);
|
|
2801
|
+
});
|
|
3015
2802
|
}
|
|
3016
|
-
|
|
3017
|
-
const
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
if (!Array.isArray(json[validTag])) {
|
|
3022
|
-
json[validTag] = [json[validTag]];
|
|
3023
|
-
}
|
|
3024
|
-
json[validTag].push(
|
|
3025
|
-
item.toObject(validTag, options)
|
|
3026
|
-
);
|
|
3027
|
-
} else {
|
|
3028
|
-
json[validTag] = item.toObject(
|
|
3029
|
-
validTag,
|
|
3030
|
-
options
|
|
3031
|
-
);
|
|
2803
|
+
getFromSourceHeads(path) {
|
|
2804
|
+
for (const head of this.getSourceHeads()) {
|
|
2805
|
+
const value = get(head, path);
|
|
2806
|
+
if (value !== void 0 && value !== null && value !== "") {
|
|
2807
|
+
return value;
|
|
3032
2808
|
}
|
|
2809
|
+
}
|
|
2810
|
+
return void 0;
|
|
2811
|
+
}
|
|
2812
|
+
sourStartsWith(prefix) {
|
|
2813
|
+
return this.getSourceHeads().some((head) => {
|
|
2814
|
+
const sour = get(head, "SOUR.value");
|
|
2815
|
+
return !!sour?.toLowerCase()?.startsWith(prefix);
|
|
3033
2816
|
});
|
|
3034
|
-
return json;
|
|
3035
2817
|
}
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
return gedcom.join("\n");
|
|
2818
|
+
isGenoPro() {
|
|
2819
|
+
return this.sourStartsWith("genopro");
|
|
3039
2820
|
}
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
this.entries().forEach(([_, item]) => {
|
|
3043
|
-
const validTag = getValidTag(tag);
|
|
3044
|
-
const xref = item.id;
|
|
3045
|
-
const payload = item.exportValue?.();
|
|
3046
|
-
if (xref) {
|
|
3047
|
-
gedcom.push(
|
|
3048
|
-
`${level} ${xref} ${validTag}${payload ? ` ${payload}` : ""}`
|
|
3049
|
-
);
|
|
3050
|
-
} else {
|
|
3051
|
-
gedcom.push(
|
|
3052
|
-
`${level} ${validTag}${payload ? ` ${payload}` : ""}`
|
|
3053
|
-
);
|
|
3054
|
-
}
|
|
3055
|
-
gedcom.push(
|
|
3056
|
-
...item.toGedcomLines(
|
|
3057
|
-
validTag,
|
|
3058
|
-
level + 1,
|
|
3059
|
-
options
|
|
3060
|
-
)
|
|
3061
|
-
);
|
|
3062
|
-
});
|
|
3063
|
-
return gedcom;
|
|
2821
|
+
isAhnenblatt() {
|
|
2822
|
+
return this.sourStartsWith("ahnenblatt");
|
|
3064
2823
|
}
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
this.entries().forEach(([key, item]) => {
|
|
3068
|
-
propList.item(key, item?.toValue());
|
|
3069
|
-
});
|
|
3070
|
-
return propList;
|
|
2824
|
+
isGeni() {
|
|
2825
|
+
return this.sourStartsWith("geni");
|
|
3071
2826
|
}
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
return this.get(tag);
|
|
2827
|
+
isAncestry() {
|
|
2828
|
+
return this.sourStartsWith("ancestry");
|
|
3075
2829
|
}
|
|
3076
|
-
|
|
3077
|
-
return
|
|
2830
|
+
isMyHeritage() {
|
|
2831
|
+
return this.sourStartsWith("myheritage");
|
|
3078
2832
|
}
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
2833
|
+
/**
|
|
2834
|
+
* Get the source type as a string (for prefixing tree IDs and names)
|
|
2835
|
+
* Returns the detected source type or undefined if unknown
|
|
2836
|
+
*/
|
|
2837
|
+
getSourceType() {
|
|
2838
|
+
if (this.isAncestry()) return "Ancestry";
|
|
2839
|
+
if (this.isMyHeritage()) return "MyHeritage";
|
|
2840
|
+
if (this.isFamilySearch()) return "FamilySearch";
|
|
2841
|
+
if (this.isGNO2GED()) return "GNO2GED";
|
|
2842
|
+
if (this.isGenoPro()) return "GenoPro";
|
|
2843
|
+
if (this.isAhnenblatt()) return "Ahnenblatt";
|
|
2844
|
+
if (this.isGeni()) return "Geni";
|
|
2845
|
+
return void 0;
|
|
2846
|
+
}
|
|
2847
|
+
isFamilySearch() {
|
|
2848
|
+
return this.getSourceHeads().some((head) => {
|
|
2849
|
+
const sourName = get(head, "SOUR.NAME.value");
|
|
2850
|
+
return sourName === "FamilySearch API";
|
|
3083
2851
|
});
|
|
3084
|
-
return newList;
|
|
3085
2852
|
}
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
this.isListable = true;
|
|
3092
|
-
this._gedcom = gedcom;
|
|
3093
|
-
this._main = main;
|
|
3094
|
-
this._parent = parent;
|
|
3095
|
-
this.initUniqueId();
|
|
3096
|
-
if (id) {
|
|
3097
|
-
this._id = id;
|
|
3098
|
-
} else {
|
|
3099
|
-
delete this._id;
|
|
3100
|
-
}
|
|
2853
|
+
isGNO2GED() {
|
|
2854
|
+
return this.getSourceHeads().some((head) => {
|
|
2855
|
+
const sour = get(head, "SOUR.value");
|
|
2856
|
+
return sour === "GNO2GED";
|
|
2857
|
+
});
|
|
3101
2858
|
}
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
this.uniqueId = this.uniqueId?.replace(/^[^:]+/, `~${type}`);
|
|
3105
|
-
}
|
|
3106
|
-
this._type = type;
|
|
2859
|
+
getAncestryTreeId() {
|
|
2860
|
+
return this.getFromSourceHeads("SOUR._TREE.RIN.value") || (get(this, "HEAD.SOUR._TREE.RIN.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.RIN.value"));
|
|
3107
2861
|
}
|
|
3108
|
-
|
|
3109
|
-
return this.
|
|
2862
|
+
getMyHeritageTreeId() {
|
|
2863
|
+
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"));
|
|
3110
2864
|
}
|
|
3111
|
-
|
|
3112
|
-
if (this
|
|
3113
|
-
|
|
2865
|
+
getTreeId() {
|
|
2866
|
+
if (this?.isAncestry()) {
|
|
2867
|
+
const id = this.getAncestryTreeId();
|
|
2868
|
+
if (id !== void 0) return id;
|
|
3114
2869
|
}
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
2870
|
+
if (this?.isMyHeritage()) {
|
|
2871
|
+
const id = this.getMyHeritageTreeId();
|
|
2872
|
+
if (id !== void 0) return id;
|
|
2873
|
+
}
|
|
2874
|
+
if (this?.isFamilySearch()) {
|
|
2875
|
+
const id = this.getFamilySearchTreeId();
|
|
2876
|
+
if (id !== void 0) return id;
|
|
2877
|
+
}
|
|
2878
|
+
if (this?.isGNO2GED()) {
|
|
2879
|
+
const id = this.getGNO2GEDTreeId();
|
|
2880
|
+
if (id !== void 0) return id;
|
|
2881
|
+
}
|
|
2882
|
+
if (this?.isAhnenblatt()) {
|
|
2883
|
+
const id = this.getAhnenblattTreeId();
|
|
2884
|
+
if (id !== void 0) return id;
|
|
2885
|
+
}
|
|
2886
|
+
if (this?.isGeni()) {
|
|
2887
|
+
const id = this.getGeniTreeId();
|
|
2888
|
+
if (id !== void 0) return id;
|
|
2889
|
+
}
|
|
2890
|
+
if (this?.isGenoPro()) {
|
|
2891
|
+
const id = this.getGenoProTreeId();
|
|
2892
|
+
if (id !== void 0) return id;
|
|
3124
2893
|
}
|
|
2894
|
+
return this.getUniversalTreeId();
|
|
3125
2895
|
}
|
|
3126
|
-
|
|
3127
|
-
return this.
|
|
2896
|
+
getAncestryTreeName() {
|
|
2897
|
+
return this.getFromSourceHeads("SOUR._TREE.value") || (get(this, "HEAD.SOUR._TREE.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.value"));
|
|
3128
2898
|
}
|
|
3129
|
-
|
|
3130
|
-
|
|
2899
|
+
getMyHeritageTreeName() {
|
|
2900
|
+
const path = "HEAD.FILE.value";
|
|
2901
|
+
const treeDetails = get(this, path) || get(this.getGedcom(), path);
|
|
2902
|
+
return treeDetails?.match(
|
|
2903
|
+
/Exported by MyHeritage.com from (?<tree>.+) in.+$/
|
|
2904
|
+
)?.groups?.tree;
|
|
3131
2905
|
}
|
|
3132
|
-
|
|
3133
|
-
|
|
2906
|
+
getFamilySearchTreeId() {
|
|
2907
|
+
const rin = this.getFromSourceHeads("SOUR._TREE.RIN.value") || get(this, "HEAD.SOUR._TREE.RIN.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.RIN.value");
|
|
2908
|
+
if (rin) {
|
|
2909
|
+
return rin;
|
|
2910
|
+
}
|
|
2911
|
+
return "familysearch";
|
|
3134
2912
|
}
|
|
3135
|
-
|
|
3136
|
-
this.
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
return this._value;
|
|
3140
|
-
}
|
|
3141
|
-
/**
|
|
3142
|
-
* Set the gedcom reference for this object
|
|
3143
|
-
* @param gedcom - The GedComType to set as the gedcom reference
|
|
3144
|
-
*/
|
|
3145
|
-
setGedcom(gedcom) {
|
|
3146
|
-
this._gedcom = gedcom;
|
|
3147
|
-
}
|
|
3148
|
-
// avoid to override
|
|
3149
|
-
get originalValue() {
|
|
3150
|
-
return this._value;
|
|
3151
|
-
}
|
|
3152
|
-
get ref() {
|
|
3153
|
-
if (typeof this.value === "string" && isId(this.value) && this.refType) {
|
|
3154
|
-
return this._gedcom?.[getListTag(this.refType)]?.item(
|
|
3155
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3156
|
-
this.value
|
|
3157
|
-
);
|
|
2913
|
+
getFamilySearchTreeName() {
|
|
2914
|
+
const treeName = this.getFromSourceHeads("SOUR._TREE.value") || get(this, "HEAD.SOUR._TREE.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.value");
|
|
2915
|
+
if (treeName) {
|
|
2916
|
+
return treeName;
|
|
3158
2917
|
}
|
|
3159
|
-
|
|
2918
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
2919
|
+
return fileName || "FamilySearch Import";
|
|
3160
2920
|
}
|
|
3161
|
-
|
|
3162
|
-
|
|
2921
|
+
getAhnenblattTreeId() {
|
|
2922
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
2923
|
+
if (fileName) {
|
|
2924
|
+
const idMatch = fileName.match(/_(\d+)/);
|
|
2925
|
+
if (idMatch) {
|
|
2926
|
+
return idMatch[1];
|
|
2927
|
+
}
|
|
2928
|
+
}
|
|
2929
|
+
return void 0;
|
|
3163
2930
|
}
|
|
3164
|
-
|
|
3165
|
-
|
|
2931
|
+
getAhnenblattTreeName() {
|
|
2932
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
2933
|
+
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
3166
2934
|
}
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
2935
|
+
getGeniTreeId() {
|
|
2936
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
2937
|
+
if (fileName) {
|
|
2938
|
+
const idMatch = fileName.match(/_(\d+)/);
|
|
2939
|
+
if (idMatch) {
|
|
2940
|
+
return idMatch[1];
|
|
3171
2941
|
}
|
|
3172
|
-
this._refs.item(refNode.value, refNode);
|
|
3173
2942
|
}
|
|
2943
|
+
return void 0;
|
|
3174
2944
|
}
|
|
3175
|
-
|
|
3176
|
-
|
|
2945
|
+
getGeniTreeName() {
|
|
2946
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
2947
|
+
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
3177
2948
|
}
|
|
3178
|
-
|
|
3179
|
-
|
|
2949
|
+
getGenoProTreeId() {
|
|
2950
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
2951
|
+
if (fileName) {
|
|
2952
|
+
const idMatch = fileName.match(/_(\d+)/);
|
|
2953
|
+
if (idMatch) {
|
|
2954
|
+
return idMatch[1];
|
|
2955
|
+
}
|
|
2956
|
+
}
|
|
2957
|
+
return void 0;
|
|
3180
2958
|
}
|
|
3181
|
-
|
|
3182
|
-
|
|
2959
|
+
getGenoProTreeName() {
|
|
2960
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
2961
|
+
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
3183
2962
|
}
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
if (typeof value === "string") {
|
|
3189
|
-
const usedValue = createCommon(this._gedcom, void 0, this.main);
|
|
3190
|
-
usedValue.value = value;
|
|
3191
|
-
set(this, name, usedValue);
|
|
3192
|
-
} else {
|
|
3193
|
-
set(this, name, value);
|
|
2963
|
+
getGNO2GEDTreeId() {
|
|
2964
|
+
const rin = get(this, "HEAD._TREE.RIN.value") || get(this.getGedcom(), "HEAD._TREE.RIN.value");
|
|
2965
|
+
if (rin) {
|
|
2966
|
+
return rin;
|
|
3194
2967
|
}
|
|
3195
|
-
return
|
|
2968
|
+
return `gno_${this._gedcom?.refcount || "unknown"}`;
|
|
3196
2969
|
}
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
2970
|
+
getGNO2GEDTreeName() {
|
|
2971
|
+
const treeName = get(this, "HEAD._TREE.value") || get(this.getGedcom(), "HEAD._TREE.value");
|
|
2972
|
+
if (treeName) {
|
|
2973
|
+
return treeName;
|
|
3200
2974
|
}
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
2975
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
2976
|
+
return fileName || "GNO2GED Export";
|
|
2977
|
+
}
|
|
2978
|
+
/**
|
|
2979
|
+
* Universal tree ID getter for unknown/unrecognized GEDCOM sources
|
|
2980
|
+
* Tries to extract an ID from various common locations
|
|
2981
|
+
*/
|
|
2982
|
+
getUniversalTreeId() {
|
|
2983
|
+
const sourceType = this.getSourceType();
|
|
2984
|
+
const prefix = sourceType ? sourceType.toLowerCase() : "tree";
|
|
2985
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
2986
|
+
if (fileName) {
|
|
2987
|
+
const idMatch = fileName.match(/_(\d+)/);
|
|
2988
|
+
if (idMatch) {
|
|
2989
|
+
return `${prefix}_${idMatch[1]}`;
|
|
3206
2990
|
}
|
|
3207
|
-
const values = [
|
|
3208
|
-
...curValue.values(),
|
|
3209
|
-
...value instanceof List ? value.values() : [value]
|
|
3210
|
-
];
|
|
3211
|
-
curValue.concat({
|
|
3212
|
-
...!unique ? values : uniqBy(
|
|
3213
|
-
values,
|
|
3214
|
-
(value2) => value2 instanceof _Common ? value2?.value : void 0
|
|
3215
|
-
)
|
|
3216
|
-
});
|
|
3217
|
-
} else {
|
|
3218
|
-
this.set(name, value);
|
|
3219
2991
|
}
|
|
3220
|
-
return
|
|
2992
|
+
return `${prefix}_${this._gedcom?.refcount || "unknown"}`;
|
|
3221
2993
|
}
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
2994
|
+
/**
|
|
2995
|
+
* Universal tree name getter for unknown/unrecognized GEDCOM sources
|
|
2996
|
+
* Tries to extract a name from various common locations
|
|
2997
|
+
*/
|
|
2998
|
+
getUniversalTreeName() {
|
|
2999
|
+
const sourceType = this.getSourceType();
|
|
3000
|
+
const prefix = sourceType ? `${sourceType}-` : "";
|
|
3001
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
3002
|
+
if (fileName) {
|
|
3003
|
+
const cleanName = fileName.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
3004
|
+
return `${prefix}${cleanName}`;
|
|
3225
3005
|
}
|
|
3226
|
-
const
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
const indexPart = Number(part);
|
|
3230
|
-
const itemIndex = part.match(/items\[(?<itemIndex>\d+)\]/)?.groups?.itemIndex;
|
|
3231
|
-
const itemId = part.match(/items\[(?<itemId>@[A-Z]+\d+@)\]/)?.groups?.itemId;
|
|
3232
|
-
const usedPart = itemId || itemIndex;
|
|
3233
|
-
if (last instanceof List) {
|
|
3234
|
-
if (!isNaN(indexPart)) {
|
|
3235
|
-
last = last.index(indexPart);
|
|
3236
|
-
} else {
|
|
3237
|
-
if (usedPart) {
|
|
3238
|
-
last = last.item(usedPart);
|
|
3239
|
-
} else {
|
|
3240
|
-
last = last?.index(0)?.get(part);
|
|
3241
|
-
}
|
|
3242
|
-
}
|
|
3243
|
-
} else {
|
|
3244
|
-
const usedIndex = Number(itemIndex ?? indexPart);
|
|
3245
|
-
if (!isNaN(usedIndex)) {
|
|
3246
|
-
last = last?.toList().index(usedIndex);
|
|
3247
|
-
} else {
|
|
3248
|
-
last = last?.get(itemId ?? part);
|
|
3249
|
-
}
|
|
3250
|
-
}
|
|
3251
|
-
if (!last) {
|
|
3252
|
-
break;
|
|
3253
|
-
}
|
|
3006
|
+
const sourName = this.getFromSourceHeads("SOUR.NAME.value") || get(this, "HEAD.SOUR.NAME.value") || get(this.getGedcom(), "HEAD.SOUR.NAME.value");
|
|
3007
|
+
if (sourName) {
|
|
3008
|
+
return `${prefix}${sourName}`;
|
|
3254
3009
|
}
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
getGedcom() {
|
|
3261
|
-
return this._gedcom;
|
|
3010
|
+
const sourValue = this.getFromSourceHeads("SOUR.value") || get(this, "HEAD.SOUR.value") || get(this.getGedcom(), "HEAD.SOUR.value");
|
|
3011
|
+
if (sourValue) {
|
|
3012
|
+
return `${prefix}${sourValue}`;
|
|
3013
|
+
}
|
|
3014
|
+
return `${prefix}Unknown Tree`;
|
|
3262
3015
|
}
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
throw new Error("Tag pathes must be of the same depth");
|
|
3016
|
+
getTreeName() {
|
|
3017
|
+
if (this?.isAncestry()) {
|
|
3018
|
+
const name = this.getAncestryTreeName();
|
|
3019
|
+
if (name) return name;
|
|
3268
3020
|
}
|
|
3269
|
-
if (
|
|
3270
|
-
|
|
3021
|
+
if (this?.isMyHeritage()) {
|
|
3022
|
+
const name = this.getMyHeritageTreeName();
|
|
3023
|
+
if (name) return name;
|
|
3271
3024
|
}
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3025
|
+
if (this?.isFamilySearch()) {
|
|
3026
|
+
const name = this.getFamilySearchTreeName();
|
|
3027
|
+
if (name) return name;
|
|
3275
3028
|
}
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
return
|
|
3293
|
-
}
|
|
3294
|
-
toList() {
|
|
3295
|
-
return new List().concat(
|
|
3296
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3297
|
-
this.id ? { [this.id]: this } : { ...[this] }
|
|
3298
|
-
);
|
|
3299
|
-
}
|
|
3300
|
-
index(i) {
|
|
3301
|
-
return this.toList()?.index(i);
|
|
3029
|
+
if (this?.isGNO2GED()) {
|
|
3030
|
+
const name = this.getGNO2GEDTreeName();
|
|
3031
|
+
if (name) return name;
|
|
3032
|
+
}
|
|
3033
|
+
if (this?.isAhnenblatt()) {
|
|
3034
|
+
const name = this.getAhnenblattTreeName();
|
|
3035
|
+
if (name) return name;
|
|
3036
|
+
}
|
|
3037
|
+
if (this?.isGeni()) {
|
|
3038
|
+
const name = this.getGeniTreeName();
|
|
3039
|
+
if (name) return name;
|
|
3040
|
+
}
|
|
3041
|
+
if (this?.isGenoPro()) {
|
|
3042
|
+
const name = this.getGenoProTreeName();
|
|
3043
|
+
if (name) return name;
|
|
3044
|
+
}
|
|
3045
|
+
return this.getUniversalTreeName();
|
|
3302
3046
|
}
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
);
|
|
3310
|
-
}
|
|
3311
|
-
standardizeObject(tag, options) {
|
|
3312
|
-
if (tag === "OBJE" && options?.obje?.standardize && "standardizeMedia" in this) {
|
|
3313
|
-
const standardize = this.standardizeMedia;
|
|
3314
|
-
return standardize.call(
|
|
3315
|
-
this,
|
|
3316
|
-
options.obje.namespace,
|
|
3317
|
-
options.obje.override,
|
|
3318
|
-
this.isAncestry() ? ancestryMediaFileUrl : void 0,
|
|
3319
|
-
options.gedcomVersion
|
|
3320
|
-
);
|
|
3321
|
-
}
|
|
3322
|
-
}
|
|
3323
|
-
toJson(tag, options) {
|
|
3324
|
-
const json = this.toObject(tag, options);
|
|
3325
|
-
return JSON.stringify(json);
|
|
3326
|
-
}
|
|
3327
|
-
toObject(tag, options) {
|
|
3328
|
-
this.standardizeObject(tag, options);
|
|
3329
|
-
const validKeys = getValidKeys(this);
|
|
3330
|
-
let json = {};
|
|
3331
|
-
validKeys.forEach((key) => {
|
|
3332
|
-
if (options?.persist && (key === "DAY" || key === "MONTH" || key === "YEAR")) {
|
|
3333
|
-
return;
|
|
3334
|
-
}
|
|
3335
|
-
if (key === "id" && this.id !== void 0) {
|
|
3336
|
-
json.id = this.id;
|
|
3337
|
-
} else if (key === "_id" && this._id !== void 0) {
|
|
3338
|
-
json.id = this._id;
|
|
3339
|
-
} else if (key === "value" && this.value !== void 0) {
|
|
3340
|
-
json.value = this.value;
|
|
3341
|
-
} else if (key === "_value" && this._value !== void 0) {
|
|
3342
|
-
json.value = this._value;
|
|
3343
|
-
} else {
|
|
3344
|
-
const validKey = key;
|
|
3345
|
-
const prop = this.get(validKey);
|
|
3346
|
-
if (typeof prop?.toObject === "function") {
|
|
3347
|
-
if (prop instanceof _Common) {
|
|
3348
|
-
json[validKey] = prop.toObject(validKey, options);
|
|
3349
|
-
} else if (prop instanceof List) {
|
|
3350
|
-
json = {
|
|
3351
|
-
...json,
|
|
3352
|
-
...prop.toObject(validKey, options)
|
|
3353
|
-
};
|
|
3354
|
-
}
|
|
3355
|
-
}
|
|
3047
|
+
};
|
|
3048
|
+
var createProxy = (target) => {
|
|
3049
|
+
return new Proxy(target, {
|
|
3050
|
+
get(t, prop, receiver) {
|
|
3051
|
+
if (prop === "unwrapped") {
|
|
3052
|
+
return target;
|
|
3356
3053
|
}
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
}
|
|
3360
|
-
merge(other, override = false, avoidKeys = []) {
|
|
3361
|
-
if (!other) {
|
|
3362
|
-
return this;
|
|
3363
|
-
}
|
|
3364
|
-
const validKeys = getValidKeys(other);
|
|
3365
|
-
validKeys.forEach((validKey) => {
|
|
3366
|
-
if (avoidKeys.includes(validKey)) {
|
|
3367
|
-
return;
|
|
3054
|
+
if (prop in t) {
|
|
3055
|
+
return Reflect.get(t, prop, receiver);
|
|
3368
3056
|
}
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
this.assign(validKey, mergeValue, true);
|
|
3374
|
-
} else if (!current || override && validKey !== "id" && validKey !== "_id") {
|
|
3375
|
-
this.set(validKey, mergeValue);
|
|
3057
|
+
if (!isOnlyMainProp(prop)) {
|
|
3058
|
+
const ref = t.ref;
|
|
3059
|
+
if (ref && prop in ref) {
|
|
3060
|
+
return Reflect.get(ref, prop, receiver);
|
|
3376
3061
|
}
|
|
3377
3062
|
}
|
|
3378
|
-
});
|
|
3379
|
-
return this;
|
|
3380
|
-
}
|
|
3381
|
-
clone(newId = false, avoidKeys = []) {
|
|
3382
|
-
const ctor = this.constructor;
|
|
3383
|
-
const instance = new ctor(
|
|
3384
|
-
this._gedcom,
|
|
3385
|
-
this._id,
|
|
3386
|
-
this._main,
|
|
3387
|
-
this._parent
|
|
3388
|
-
);
|
|
3389
|
-
if (newId && this._id) {
|
|
3390
|
-
instance.id = `IFT${this._id.replace(/[^0-9]/g, "")}`;
|
|
3391
3063
|
}
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3064
|
+
});
|
|
3065
|
+
};
|
|
3066
|
+
var createCommon = (gedcom, id, main, parent) => {
|
|
3067
|
+
return createProxy(
|
|
3068
|
+
new Common(gedcom, id, main, parent)
|
|
3069
|
+
);
|
|
3070
|
+
};
|
|
3071
|
+
var isOnlyMainProp = (key) => {
|
|
3072
|
+
return key === "_gedcom" || key === "_main" || key === "_parent" || key === "_uniqueId" || key === "_type" || key === "_refs" || key === "id" || key === "_id";
|
|
3073
|
+
};
|
|
3074
|
+
var isValidKey = (common, key) => {
|
|
3075
|
+
const prop = get(common, key);
|
|
3076
|
+
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);
|
|
3077
|
+
};
|
|
3078
|
+
var getValidKeys = (common) => {
|
|
3079
|
+
return Object.keys(common).filter((key) => {
|
|
3080
|
+
return isValidKey(common, key);
|
|
3081
|
+
});
|
|
3082
|
+
};
|
|
3083
|
+
var getValidTag = (tag) => {
|
|
3084
|
+
return tag.replace(/^@@/, "");
|
|
3085
|
+
};
|
|
3086
|
+
var getListTag = (tag) => {
|
|
3087
|
+
return `@@${tag}`;
|
|
3088
|
+
};
|
|
3089
|
+
var isId = (string) => {
|
|
3090
|
+
return ID_REG.test(string);
|
|
3091
|
+
};
|
|
3092
|
+
var idGetter = (id) => {
|
|
3093
|
+
if (id === void 0) {
|
|
3094
|
+
return void 0;
|
|
3395
3095
|
}
|
|
3396
|
-
|
|
3397
|
-
|
|
3096
|
+
let newId = `${id}`;
|
|
3097
|
+
const parts = newId?.match(ID_GETTER_REG)?.groups;
|
|
3098
|
+
if (!parts?.at && !parts?.letter) {
|
|
3099
|
+
newId = `@U${newId}`;
|
|
3100
|
+
} else if (!parts.at) {
|
|
3101
|
+
newId = `@${newId}`;
|
|
3102
|
+
} else if (!parts.letter) {
|
|
3103
|
+
newId = newId.replace(/^@/, "@U");
|
|
3398
3104
|
}
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
return gedcom.join("\n");
|
|
3105
|
+
if (!newId.endsWith("@")) {
|
|
3106
|
+
newId = `${newId}@`;
|
|
3402
3107
|
}
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
const value = prop.exportValue();
|
|
3417
|
-
gedcom.push(
|
|
3418
|
-
`${level} ${validKey}${value ? ` ${value}` : ""}`
|
|
3419
|
-
);
|
|
3420
|
-
gedcom.push(
|
|
3421
|
-
...prop.toGedcomLines(validKey, level + 1, options)
|
|
3422
|
-
);
|
|
3423
|
-
} else if (prop instanceof List) {
|
|
3424
|
-
gedcom.push(
|
|
3425
|
-
...prop.toGedcomLines(validKey, level, options)
|
|
3426
|
-
);
|
|
3427
|
-
}
|
|
3428
|
-
}
|
|
3429
|
-
});
|
|
3430
|
-
return gedcom;
|
|
3108
|
+
return newId;
|
|
3109
|
+
};
|
|
3110
|
+
|
|
3111
|
+
// src/classes/list.ts
|
|
3112
|
+
var List = class _List {
|
|
3113
|
+
// length = 0;
|
|
3114
|
+
constructor(items) {
|
|
3115
|
+
this.items = {};
|
|
3116
|
+
this.isListable = true;
|
|
3117
|
+
this.marker = void 0;
|
|
3118
|
+
if (items) {
|
|
3119
|
+
this.concat(items);
|
|
3120
|
+
}
|
|
3431
3121
|
}
|
|
3432
|
-
|
|
3433
|
-
return
|
|
3122
|
+
get length() {
|
|
3123
|
+
return this.values().length;
|
|
3434
3124
|
}
|
|
3435
|
-
|
|
3436
|
-
return
|
|
3125
|
+
has(indi) {
|
|
3126
|
+
return !!this.item(
|
|
3127
|
+
typeof indi === "string" ? indi : indi?.id ?? ""
|
|
3128
|
+
);
|
|
3437
3129
|
}
|
|
3438
|
-
|
|
3439
|
-
const
|
|
3440
|
-
|
|
3441
|
-
|
|
3130
|
+
get(name) {
|
|
3131
|
+
const propList = new _List();
|
|
3132
|
+
this.entries().forEach(([key, item]) => {
|
|
3133
|
+
propList.item(key, item.get(name));
|
|
3442
3134
|
});
|
|
3135
|
+
return propList;
|
|
3443
3136
|
}
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3137
|
+
getIf(name, condition, name2) {
|
|
3138
|
+
const propList = new _List();
|
|
3139
|
+
this.entries().forEach(([key, item]) => {
|
|
3140
|
+
const passedItem = item.getIf(name, condition, name2);
|
|
3141
|
+
if (passedItem) {
|
|
3142
|
+
propList.item(key, passedItem);
|
|
3449
3143
|
}
|
|
3450
|
-
}
|
|
3451
|
-
return void 0;
|
|
3452
|
-
}
|
|
3453
|
-
sourStartsWith(prefix) {
|
|
3454
|
-
return this.getSourceHeads().some((head) => {
|
|
3455
|
-
const sour = get(head, "SOUR.value");
|
|
3456
|
-
return !!sour?.toLowerCase()?.startsWith(prefix);
|
|
3457
3144
|
});
|
|
3145
|
+
return propList;
|
|
3458
3146
|
}
|
|
3459
|
-
|
|
3460
|
-
return this.
|
|
3147
|
+
keys() {
|
|
3148
|
+
return Object.keys(this.items);
|
|
3461
3149
|
}
|
|
3462
|
-
|
|
3463
|
-
return this.
|
|
3150
|
+
values() {
|
|
3151
|
+
return Object.values(this.items);
|
|
3464
3152
|
}
|
|
3465
|
-
|
|
3466
|
-
return this.
|
|
3153
|
+
entries() {
|
|
3154
|
+
return Object.entries(this.items);
|
|
3467
3155
|
}
|
|
3468
|
-
|
|
3469
|
-
return this.sourStartsWith("ancestry");
|
|
3156
|
+
setLength(_type) {
|
|
3470
3157
|
}
|
|
3471
|
-
|
|
3472
|
-
return this.
|
|
3158
|
+
first() {
|
|
3159
|
+
return this.index(0);
|
|
3473
3160
|
}
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
* Returns the detected source type or undefined if unknown
|
|
3477
|
-
*/
|
|
3478
|
-
getSourceType() {
|
|
3479
|
-
if (this.isAncestry()) return "Ancestry";
|
|
3480
|
-
if (this.isMyHeritage()) return "MyHeritage";
|
|
3481
|
-
if (this.isFamilySearch()) return "FamilySearch";
|
|
3482
|
-
if (this.isGNO2GED()) return "GNO2GED";
|
|
3483
|
-
if (this.isGenoPro()) return "GenoPro";
|
|
3484
|
-
if (this.isAhnenblatt()) return "Ahnenblatt";
|
|
3485
|
-
if (this.isGeni()) return "Geni";
|
|
3486
|
-
return void 0;
|
|
3161
|
+
last() {
|
|
3162
|
+
return this.index(this.keys().length - 1);
|
|
3487
3163
|
}
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
});
|
|
3164
|
+
index(index) {
|
|
3165
|
+
const keys = this.keys();
|
|
3166
|
+
const key = keys[index];
|
|
3167
|
+
return key && this.items[key];
|
|
3493
3168
|
}
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
}
|
|
3169
|
+
item(name, value) {
|
|
3170
|
+
if (arguments.length > 1) {
|
|
3171
|
+
set(this.items, name, value);
|
|
3172
|
+
this.setLength();
|
|
3173
|
+
}
|
|
3174
|
+
return get(this.items, name);
|
|
3499
3175
|
}
|
|
3500
|
-
|
|
3501
|
-
|
|
3176
|
+
removeItem(name) {
|
|
3177
|
+
unset(this.items, name);
|
|
3178
|
+
this.setLength();
|
|
3502
3179
|
}
|
|
3503
|
-
|
|
3504
|
-
|
|
3180
|
+
exclude(excludedList) {
|
|
3181
|
+
excludedList.keys().forEach((itemId) => {
|
|
3182
|
+
delete this.items[itemId];
|
|
3183
|
+
});
|
|
3184
|
+
this.setLength();
|
|
3185
|
+
return this;
|
|
3505
3186
|
}
|
|
3506
|
-
|
|
3507
|
-
if (
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
if (id !== void 0) return id;
|
|
3514
|
-
}
|
|
3515
|
-
if (this?.isFamilySearch()) {
|
|
3516
|
-
const id = this.getFamilySearchTreeId();
|
|
3517
|
-
if (id !== void 0) return id;
|
|
3518
|
-
}
|
|
3519
|
-
if (this?.isGNO2GED()) {
|
|
3520
|
-
const id = this.getGNO2GEDTreeId();
|
|
3521
|
-
if (id !== void 0) return id;
|
|
3522
|
-
}
|
|
3523
|
-
if (this?.isAhnenblatt()) {
|
|
3524
|
-
const id = this.getAhnenblattTreeId();
|
|
3525
|
-
if (id !== void 0) return id;
|
|
3526
|
-
}
|
|
3527
|
-
if (this?.isGeni()) {
|
|
3528
|
-
const id = this.getGeniTreeId();
|
|
3529
|
-
if (id !== void 0) return id;
|
|
3530
|
-
}
|
|
3531
|
-
if (this?.isGenoPro()) {
|
|
3532
|
-
const id = this.getGenoProTreeId();
|
|
3533
|
-
if (id !== void 0) return id;
|
|
3187
|
+
concat(items) {
|
|
3188
|
+
if (Array.isArray(items)) {
|
|
3189
|
+
items.forEach((item) => {
|
|
3190
|
+
this.append(item);
|
|
3191
|
+
});
|
|
3192
|
+
} else {
|
|
3193
|
+
Object.assign(this.items, items ?? {});
|
|
3534
3194
|
}
|
|
3535
|
-
|
|
3195
|
+
this.setLength();
|
|
3196
|
+
return this;
|
|
3536
3197
|
}
|
|
3537
|
-
|
|
3538
|
-
|
|
3198
|
+
merge(mergedList) {
|
|
3199
|
+
this.concat(mergedList?.items);
|
|
3200
|
+
return this;
|
|
3539
3201
|
}
|
|
3540
|
-
|
|
3541
|
-
const
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
)
|
|
3202
|
+
intersection(mergedList) {
|
|
3203
|
+
const inter = intersectionBy(
|
|
3204
|
+
this.values(),
|
|
3205
|
+
mergedList?.values() ?? [],
|
|
3206
|
+
"id"
|
|
3207
|
+
);
|
|
3208
|
+
return new _List(inter);
|
|
3546
3209
|
}
|
|
3547
|
-
|
|
3548
|
-
const
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3210
|
+
difference(mergedList) {
|
|
3211
|
+
const inter = differenceBy(
|
|
3212
|
+
this.values(),
|
|
3213
|
+
mergedList?.values() ?? [],
|
|
3214
|
+
"id"
|
|
3215
|
+
);
|
|
3216
|
+
return new _List(inter);
|
|
3553
3217
|
}
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3218
|
+
prepend(item) {
|
|
3219
|
+
if (item.id) {
|
|
3220
|
+
let increase = true;
|
|
3221
|
+
if (this.items[item.id]) {
|
|
3222
|
+
delete this.items[item.id];
|
|
3223
|
+
increase = false;
|
|
3224
|
+
}
|
|
3225
|
+
this.items = Object.assign(
|
|
3226
|
+
{
|
|
3227
|
+
[item.id]: item
|
|
3228
|
+
},
|
|
3229
|
+
this.items
|
|
3230
|
+
);
|
|
3231
|
+
if (increase) {
|
|
3232
|
+
this.setLength("increase");
|
|
3233
|
+
}
|
|
3558
3234
|
}
|
|
3559
|
-
|
|
3560
|
-
return fileName || "FamilySearch Import";
|
|
3235
|
+
return this;
|
|
3561
3236
|
}
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3237
|
+
append(item) {
|
|
3238
|
+
if (item.id) {
|
|
3239
|
+
let increase = true;
|
|
3240
|
+
if (this.items[item.id]) {
|
|
3241
|
+
delete this.items[item.id];
|
|
3242
|
+
increase = false;
|
|
3243
|
+
}
|
|
3244
|
+
this.items[item.id] = item;
|
|
3245
|
+
if (increase) {
|
|
3246
|
+
this.setLength("increase");
|
|
3568
3247
|
}
|
|
3569
3248
|
}
|
|
3570
|
-
return
|
|
3571
|
-
}
|
|
3572
|
-
getAhnenblattTreeName() {
|
|
3573
|
-
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
3574
|
-
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
3249
|
+
return this;
|
|
3575
3250
|
}
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
if (idMatch) {
|
|
3581
|
-
return idMatch[1];
|
|
3582
|
-
}
|
|
3251
|
+
delete(item) {
|
|
3252
|
+
if (item.id && this.items[item.id]) {
|
|
3253
|
+
delete this.items[item.id];
|
|
3254
|
+
this.setLength("decrease");
|
|
3583
3255
|
}
|
|
3584
|
-
return
|
|
3256
|
+
return this;
|
|
3585
3257
|
}
|
|
3586
|
-
|
|
3587
|
-
const
|
|
3588
|
-
|
|
3258
|
+
copy(ClassName = _List) {
|
|
3259
|
+
const newList = new ClassName();
|
|
3260
|
+
Object.assign(newList.items, this.items);
|
|
3261
|
+
newList.setLength();
|
|
3262
|
+
return newList;
|
|
3589
3263
|
}
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
if (fileName) {
|
|
3593
|
-
const idMatch = fileName.match(/_(\d+)/);
|
|
3594
|
-
if (idMatch) {
|
|
3595
|
-
return idMatch[1];
|
|
3596
|
-
}
|
|
3597
|
-
}
|
|
3598
|
-
return void 0;
|
|
3264
|
+
except(item, ClassName = _List) {
|
|
3265
|
+
return this.copy(ClassName).delete(item);
|
|
3599
3266
|
}
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3267
|
+
forEach(iterate) {
|
|
3268
|
+
this.entries().forEach(([key, item], index) => {
|
|
3269
|
+
iterate(item, key, index);
|
|
3270
|
+
});
|
|
3603
3271
|
}
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
}
|
|
3609
|
-
return `gno_${this._gedcom?.refcount || "unknown"}`;
|
|
3272
|
+
map(iterate) {
|
|
3273
|
+
return this.entries().map(([key, item], index) => {
|
|
3274
|
+
return iterate(item, key, index);
|
|
3275
|
+
});
|
|
3610
3276
|
}
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
}
|
|
3616
|
-
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
3617
|
-
return fileName || "GNO2GED Export";
|
|
3277
|
+
reduce(iterate, initialValue) {
|
|
3278
|
+
return this.entries().reduce((acc, [key, item], index) => {
|
|
3279
|
+
return iterate(acc, item, key, index);
|
|
3280
|
+
}, initialValue);
|
|
3618
3281
|
}
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
3627
|
-
if (fileName) {
|
|
3628
|
-
const idMatch = fileName.match(/_(\d+)/);
|
|
3629
|
-
if (idMatch) {
|
|
3630
|
-
return `${prefix}_${idMatch[1]}`;
|
|
3282
|
+
filter(filters, ClassName = _List) {
|
|
3283
|
+
const newList = new ClassName();
|
|
3284
|
+
const isIterator = typeof filters === "function";
|
|
3285
|
+
this.entries().forEach(([itemId, item], index) => {
|
|
3286
|
+
if (isIterator) {
|
|
3287
|
+
filters(item, itemId, index) && newList.item(itemId, item);
|
|
3288
|
+
return;
|
|
3631
3289
|
}
|
|
3632
|
-
|
|
3633
|
-
|
|
3290
|
+
if (!Object.keys(filters).length || Object.entries(filters).every(([key, value]) => {
|
|
3291
|
+
let itemValue;
|
|
3292
|
+
if (key === "id") {
|
|
3293
|
+
itemValue = item.toProp("id");
|
|
3294
|
+
} else {
|
|
3295
|
+
itemValue = item.toProp(key)?.toValue();
|
|
3296
|
+
}
|
|
3297
|
+
if (Array.isArray(value)) {
|
|
3298
|
+
return value.includes(itemValue);
|
|
3299
|
+
}
|
|
3300
|
+
return itemValue === value;
|
|
3301
|
+
})) {
|
|
3302
|
+
newList.item(itemId, item);
|
|
3303
|
+
}
|
|
3304
|
+
});
|
|
3305
|
+
return newList;
|
|
3634
3306
|
}
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3307
|
+
find(filters, _ClassName = _List) {
|
|
3308
|
+
let foundItem;
|
|
3309
|
+
const isIterator = typeof filters === "function";
|
|
3310
|
+
this.entries().find(([itemId, item], index) => {
|
|
3311
|
+
if (isIterator) {
|
|
3312
|
+
if (filters(item, itemId, index)) {
|
|
3313
|
+
foundItem = item;
|
|
3314
|
+
return true;
|
|
3315
|
+
}
|
|
3316
|
+
return false;
|
|
3317
|
+
}
|
|
3318
|
+
if (!Object.keys(filters).length || Object.entries(filters).every(([key, value]) => {
|
|
3319
|
+
let itemValue;
|
|
3320
|
+
if (key === "id") {
|
|
3321
|
+
itemValue = item.toProp("id");
|
|
3322
|
+
} else {
|
|
3323
|
+
itemValue = item.toProp(key)?.toValue();
|
|
3324
|
+
}
|
|
3325
|
+
if (Array.isArray(value)) {
|
|
3326
|
+
return value.includes(itemValue);
|
|
3327
|
+
}
|
|
3328
|
+
return itemValue === value;
|
|
3329
|
+
})) {
|
|
3330
|
+
foundItem = item;
|
|
3331
|
+
return true;
|
|
3332
|
+
}
|
|
3333
|
+
return false;
|
|
3334
|
+
});
|
|
3335
|
+
return foundItem;
|
|
3656
3336
|
}
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
if (this?.isMyHeritage()) {
|
|
3663
|
-
const name = this.getMyHeritageTreeName();
|
|
3664
|
-
if (name) return name;
|
|
3665
|
-
}
|
|
3666
|
-
if (this?.isFamilySearch()) {
|
|
3667
|
-
const name = this.getFamilySearchTreeName();
|
|
3668
|
-
if (name) return name;
|
|
3669
|
-
}
|
|
3670
|
-
if (this?.isGNO2GED()) {
|
|
3671
|
-
const name = this.getGNO2GEDTreeName();
|
|
3672
|
-
if (name) return name;
|
|
3337
|
+
orderBy(orders, ClassName = _List) {
|
|
3338
|
+
const newList = new ClassName();
|
|
3339
|
+
const isIterator = typeof orders === "function";
|
|
3340
|
+
if (!isIterator && (!orders || !Object.keys(orders).length)) {
|
|
3341
|
+
return newList.merge(this);
|
|
3673
3342
|
}
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3343
|
+
const sortedItems = this.entries().toSorted(
|
|
3344
|
+
([itemAId, itemA], [itemBId, itemB]) => {
|
|
3345
|
+
if (isIterator) {
|
|
3346
|
+
return orders(itemA, itemAId, itemB, itemBId);
|
|
3347
|
+
}
|
|
3348
|
+
const [key, { direction, getter }] = Object.entries(
|
|
3349
|
+
typeof orders === "string" ? { [orders]: { direction: "ASC" } } : orders
|
|
3350
|
+
)[0];
|
|
3351
|
+
const rawA = itemA.get(key);
|
|
3352
|
+
const rawB = itemB.get(key);
|
|
3353
|
+
let valueA = rawA?.toValue();
|
|
3354
|
+
let valueB = rawB?.toValue();
|
|
3355
|
+
if (getter && typeof getter === "function") {
|
|
3356
|
+
valueA = getter(valueA, rawA);
|
|
3357
|
+
valueB = getter(valueB, rawB);
|
|
3358
|
+
}
|
|
3359
|
+
let sortValue = 0;
|
|
3360
|
+
if (!valueA && valueA !== 0 && !valueB && valueB !== 0) {
|
|
3361
|
+
sortValue = 0;
|
|
3362
|
+
} else if (!valueB && valueB !== 0) {
|
|
3363
|
+
sortValue = 1;
|
|
3364
|
+
} else if (!valueA && valueA !== 0) {
|
|
3365
|
+
sortValue = -1;
|
|
3366
|
+
} else if (valueA < valueB) {
|
|
3367
|
+
sortValue = -1;
|
|
3368
|
+
} else if (valueA > valueB) {
|
|
3369
|
+
sortValue = 1;
|
|
3370
|
+
}
|
|
3371
|
+
return sortValue * (direction === "DESC" ? -1 : 1);
|
|
3372
|
+
}
|
|
3373
|
+
);
|
|
3374
|
+
sortedItems.forEach(([key, value]) => {
|
|
3375
|
+
newList.item(key, value);
|
|
3376
|
+
});
|
|
3377
|
+
return newList;
|
|
3378
|
+
}
|
|
3379
|
+
groupBy(groups, sort, minOccurance = -1, lessOccuranceLabel = "Appearing less than 5 times", ClassName = _List) {
|
|
3380
|
+
const groupped = {};
|
|
3381
|
+
const isIterator = typeof groups === "function";
|
|
3382
|
+
if (!isIterator && (!groups || !Object.keys(groups).length)) {
|
|
3383
|
+
groupped.Unknown = new ClassName().merge(this);
|
|
3384
|
+
groupped.Unknown.marker = "Unknown";
|
|
3385
|
+
return groupped;
|
|
3677
3386
|
}
|
|
3678
|
-
|
|
3679
|
-
const
|
|
3680
|
-
if (
|
|
3387
|
+
this.forEach((item, itemId) => {
|
|
3388
|
+
const group = [];
|
|
3389
|
+
if (isIterator) {
|
|
3390
|
+
const newGroups = groups(item, itemId);
|
|
3391
|
+
group.push(
|
|
3392
|
+
...Array.isArray(newGroups) ? newGroups : [newGroups]
|
|
3393
|
+
);
|
|
3394
|
+
} else {
|
|
3395
|
+
const [key, { getter }] = Object.entries(
|
|
3396
|
+
typeof groups === "string" ? { [groups]: {} } : groups
|
|
3397
|
+
)[0];
|
|
3398
|
+
const raw = item.get(key)?.index(0);
|
|
3399
|
+
let value = raw?.toValue();
|
|
3400
|
+
if (getter && typeof getter === "function") {
|
|
3401
|
+
value = getter(value, raw);
|
|
3402
|
+
}
|
|
3403
|
+
if (value) {
|
|
3404
|
+
group.push(value);
|
|
3405
|
+
}
|
|
3406
|
+
}
|
|
3407
|
+
if (!group.length) {
|
|
3408
|
+
group.push("Unknown");
|
|
3409
|
+
}
|
|
3410
|
+
group.forEach((g) => {
|
|
3411
|
+
const newGroup = typeof g === "string" ? { group: g } : g;
|
|
3412
|
+
if (!groupped[newGroup.group]) {
|
|
3413
|
+
groupped[newGroup.group] = new ClassName();
|
|
3414
|
+
groupped[newGroup.group].marker = newGroup.marker ?? newGroup.group;
|
|
3415
|
+
}
|
|
3416
|
+
groupped[newGroup.group]?.append(item);
|
|
3417
|
+
});
|
|
3418
|
+
});
|
|
3419
|
+
if (sort) {
|
|
3420
|
+
return Object.entries(groupped).toSorted(([ak, a], [bk, b]) => {
|
|
3421
|
+
if (typeof sort === "function") {
|
|
3422
|
+
return sort(a, ak, b, bk);
|
|
3423
|
+
}
|
|
3424
|
+
if (ak === "Unknown") {
|
|
3425
|
+
return 1;
|
|
3426
|
+
}
|
|
3427
|
+
if (bk === "Unknown") {
|
|
3428
|
+
return -1;
|
|
3429
|
+
}
|
|
3430
|
+
if (sort === "group") {
|
|
3431
|
+
return ak.localeCompare(bk);
|
|
3432
|
+
}
|
|
3433
|
+
return (b?.length ?? 0) - (a?.length ?? 0);
|
|
3434
|
+
}).reduce((acc, [key, value]) => {
|
|
3435
|
+
if (minOccurance > -1 && (value?.length ?? 0) < minOccurance) {
|
|
3436
|
+
const otherKey = lessOccuranceLabel;
|
|
3437
|
+
acc[otherKey] = acc[otherKey] && value ? acc[otherKey].merge(value) : value;
|
|
3438
|
+
} else {
|
|
3439
|
+
acc[key] = value;
|
|
3440
|
+
}
|
|
3441
|
+
return acc;
|
|
3442
|
+
}, {});
|
|
3681
3443
|
}
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3444
|
+
return groupped;
|
|
3445
|
+
}
|
|
3446
|
+
findIndex(item) {
|
|
3447
|
+
if (!item?.id) {
|
|
3448
|
+
return -1;
|
|
3685
3449
|
}
|
|
3686
|
-
return this.
|
|
3450
|
+
return this.keys().findIndex((key) => key === item.id);
|
|
3451
|
+
}
|
|
3452
|
+
getItems() {
|
|
3453
|
+
return this.items;
|
|
3454
|
+
}
|
|
3455
|
+
toJson(tag, options) {
|
|
3456
|
+
const json = this.toObject(tag, options);
|
|
3457
|
+
return JSON.stringify(json);
|
|
3458
|
+
}
|
|
3459
|
+
toObject(tag, options) {
|
|
3460
|
+
const json = {};
|
|
3461
|
+
this.entries().forEach(([_, item]) => {
|
|
3462
|
+
const validTag = getValidTag(tag);
|
|
3463
|
+
if (json[validTag]) {
|
|
3464
|
+
if (!Array.isArray(json[validTag])) {
|
|
3465
|
+
json[validTag] = [json[validTag]];
|
|
3466
|
+
}
|
|
3467
|
+
json[validTag].push(
|
|
3468
|
+
item.toObject(validTag, options)
|
|
3469
|
+
);
|
|
3470
|
+
} else {
|
|
3471
|
+
json[validTag] = item.toObject(
|
|
3472
|
+
validTag,
|
|
3473
|
+
options
|
|
3474
|
+
);
|
|
3475
|
+
}
|
|
3476
|
+
});
|
|
3477
|
+
return json;
|
|
3478
|
+
}
|
|
3479
|
+
toGedcom(tag, level = 0, options) {
|
|
3480
|
+
const gedcom = this.toGedcomLines(tag, level, options);
|
|
3481
|
+
return gedcom.join("\n");
|
|
3482
|
+
}
|
|
3483
|
+
toGedcomLines(tag, level = 0, options) {
|
|
3484
|
+
const gedcom = [];
|
|
3485
|
+
this.entries().forEach(([_, item]) => {
|
|
3486
|
+
const validTag = getValidTag(tag);
|
|
3487
|
+
const xref = item.id;
|
|
3488
|
+
const payload = item.exportValue?.();
|
|
3489
|
+
if (xref) {
|
|
3490
|
+
gedcom.push(
|
|
3491
|
+
`${level} ${xref} ${validTag}${payload ? ` ${payload}` : ""}`
|
|
3492
|
+
);
|
|
3493
|
+
} else {
|
|
3494
|
+
gedcom.push(
|
|
3495
|
+
`${level} ${validTag}${payload ? ` ${payload}` : ""}`
|
|
3496
|
+
);
|
|
3497
|
+
}
|
|
3498
|
+
gedcom.push(
|
|
3499
|
+
...item.toGedcomLines(
|
|
3500
|
+
validTag,
|
|
3501
|
+
level + 1,
|
|
3502
|
+
options
|
|
3503
|
+
)
|
|
3504
|
+
);
|
|
3505
|
+
});
|
|
3506
|
+
return gedcom;
|
|
3507
|
+
}
|
|
3508
|
+
toValue() {
|
|
3509
|
+
const propList = new _List();
|
|
3510
|
+
this.entries().forEach(([key, item]) => {
|
|
3511
|
+
propList.item(key, item?.toValue());
|
|
3512
|
+
});
|
|
3513
|
+
return propList;
|
|
3514
|
+
}
|
|
3515
|
+
// @deprecated use get instead
|
|
3516
|
+
toProp(tag) {
|
|
3517
|
+
return this.get(tag);
|
|
3518
|
+
}
|
|
3519
|
+
toList() {
|
|
3520
|
+
return new _List().concat(this.items);
|
|
3521
|
+
}
|
|
3522
|
+
toValueList() {
|
|
3523
|
+
const newList = new _List();
|
|
3524
|
+
this.values().forEach((value) => {
|
|
3525
|
+
value.value && newList.item(value.value, value);
|
|
3526
|
+
});
|
|
3527
|
+
return newList;
|
|
3528
|
+
}
|
|
3529
|
+
};
|
|
3530
|
+
|
|
3531
|
+
// src/utils/get-all-prop.ts
|
|
3532
|
+
var getAllProp = (indi, prop) => {
|
|
3533
|
+
return prop && (indi?.get(prop)?.toList().values() ?? []).filter(Boolean) || [];
|
|
3534
|
+
};
|
|
3535
|
+
|
|
3536
|
+
// src/utils/date-formatter.ts
|
|
3537
|
+
var ACCEPTED_DATE_FORMATS = [
|
|
3538
|
+
"yyyy.MM.dd.",
|
|
3539
|
+
"yyyy-MM-dd",
|
|
3540
|
+
"MM/dd/yyyy"
|
|
3541
|
+
];
|
|
3542
|
+
var ACCEPTED_DATE_FORMATS_REGEX = new RegExp(
|
|
3543
|
+
`(${ACCEPTED_DATE_FORMATS.map(
|
|
3544
|
+
(acceptedFormat) => acceptedFormat.replace(/[^.\-/]/g, "\\d")
|
|
3545
|
+
).join("|")})`,
|
|
3546
|
+
"gi"
|
|
3547
|
+
);
|
|
3548
|
+
var firstDate = (date) => {
|
|
3549
|
+
if (!date) return void 0;
|
|
3550
|
+
if (isCommonDate(date)) return date;
|
|
3551
|
+
if (date instanceof List) {
|
|
3552
|
+
return firstDate(
|
|
3553
|
+
date.index(0)
|
|
3554
|
+
);
|
|
3555
|
+
}
|
|
3556
|
+
const node = date;
|
|
3557
|
+
if (typeof node.toValue === "function") {
|
|
3558
|
+
return node;
|
|
3687
3559
|
}
|
|
3560
|
+
return void 0;
|
|
3688
3561
|
};
|
|
3689
|
-
var
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3562
|
+
var dateNote = (date, shortNote = true) => {
|
|
3563
|
+
if (date && typeof date.toNote === "function") {
|
|
3564
|
+
return date.toNote(shortNote) ?? "";
|
|
3565
|
+
}
|
|
3566
|
+
return "";
|
|
3567
|
+
};
|
|
3568
|
+
var commonDateFormatter = (date, format2 = "yyyy", prefix = "") => {
|
|
3569
|
+
const used = firstDate(date);
|
|
3570
|
+
const formattedDate = used?.toValue(format2);
|
|
3571
|
+
if (!formattedDate) {
|
|
3572
|
+
return void 0;
|
|
3573
|
+
}
|
|
3574
|
+
return `${prefix}${formattedDate}`.trim();
|
|
3575
|
+
};
|
|
3576
|
+
var noteDateFormatter = (date, format2 = "yyyy", prefix = "", shortNote = true, showNote = true) => {
|
|
3577
|
+
const used = firstDate(date);
|
|
3578
|
+
const rawDate = commonDateFormatter(used, format2, "");
|
|
3579
|
+
if (!rawDate) {
|
|
3580
|
+
return void 0;
|
|
3581
|
+
}
|
|
3582
|
+
const note = dateNote(used, shortNote);
|
|
3583
|
+
return `${prefix}${note && showNote ? i18n.t(`${note} {{date}}`, { date: rawDate }) : rawDate}`;
|
|
3584
|
+
};
|
|
3585
|
+
var marriageDateFormatter = (fam, showDays = false, showPlaces = false, shortNote = true, showNote = true, showDisplayTextIfNoDate = true, showAllEvents = false, dateFormatPattern) => {
|
|
3586
|
+
const fullDateFormat = i18n.t("dateFormat");
|
|
3587
|
+
const marriageDates = [];
|
|
3588
|
+
const marriagePlaces = [];
|
|
3589
|
+
const marriages = (fam?.toValueList().values() ?? []).flatMap((fam2) => {
|
|
3590
|
+
const family = fam2;
|
|
3591
|
+
const marrEvents = (family?.MARR?.toList().values() ?? []).filter(
|
|
3592
|
+
Boolean
|
|
3593
|
+
);
|
|
3594
|
+
if (marrEvents.length === 0) {
|
|
3595
|
+
const displayText = family?.get("DISPLAYTEXT")?.toValue() ?? "";
|
|
3596
|
+
if (showDisplayTextIfNoDate && displayText) {
|
|
3597
|
+
const displayDate = displayText.match(
|
|
3598
|
+
ACCEPTED_DATE_FORMATS_REGEX
|
|
3599
|
+
)?.[0];
|
|
3600
|
+
if (displayDate) {
|
|
3601
|
+
marriagePlaces.push(displayText.replace(displayDate, ""));
|
|
3602
|
+
const marriageDate = createCommonDate(
|
|
3603
|
+
fam2?.getGedcom(),
|
|
3604
|
+
void 0,
|
|
3605
|
+
family
|
|
3606
|
+
);
|
|
3607
|
+
marriageDate.value = displayDate;
|
|
3608
|
+
marriageDates.push(marriageDate);
|
|
3609
|
+
} else {
|
|
3610
|
+
marriagePlaces.push(displayText);
|
|
3611
|
+
marriageDates.push(void 0);
|
|
3612
|
+
return ["\u221E"];
|
|
3702
3613
|
}
|
|
3703
3614
|
}
|
|
3615
|
+
return [];
|
|
3704
3616
|
}
|
|
3617
|
+
const eventsToProcess = showAllEvents ? marrEvents : marrEvents.slice(0, 1);
|
|
3618
|
+
return eventsToProcess.map((marrEvent) => {
|
|
3619
|
+
const marriageEventDetail = marrEvent;
|
|
3620
|
+
const marriageDate = marriageEventDetail?.DATE;
|
|
3621
|
+
const marriagePlace = showPlaces ? marriageEventDetail?.PLAC?.value : void 0;
|
|
3622
|
+
marriagePlaces.push(marriagePlace);
|
|
3623
|
+
marriageDates.push(marriageDate);
|
|
3624
|
+
const formattedDate = noteDateFormatter(
|
|
3625
|
+
marriageDate,
|
|
3626
|
+
showDays ? fullDateFormat : "yyyy",
|
|
3627
|
+
"\u221E",
|
|
3628
|
+
shortNote,
|
|
3629
|
+
showNote
|
|
3630
|
+
);
|
|
3631
|
+
return formattedDate ? formattedDate : void 0;
|
|
3632
|
+
});
|
|
3705
3633
|
});
|
|
3634
|
+
const marriageArray = marriages.length ? marriages.filter(Boolean) : [];
|
|
3635
|
+
const datesArray = marriageArray.filter(Boolean);
|
|
3636
|
+
const placesArray = marriagePlaces.filter(Boolean);
|
|
3637
|
+
const dates = datesArray.join(" ").trim();
|
|
3638
|
+
return {
|
|
3639
|
+
rawArray: marriageDates,
|
|
3640
|
+
inArray: datesArray,
|
|
3641
|
+
inOrder: dates,
|
|
3642
|
+
places: placesArray,
|
|
3643
|
+
marriage: marriageArray,
|
|
3644
|
+
...showPlaces ? {
|
|
3645
|
+
marriages,
|
|
3646
|
+
marriagePlaces
|
|
3647
|
+
} : {}
|
|
3648
|
+
};
|
|
3706
3649
|
};
|
|
3707
|
-
var
|
|
3708
|
-
|
|
3709
|
-
|
|
3650
|
+
var dateFormatter = (indi, showMarriages = false, showDays = false, showPlaces = false, shortNote = true, showNote = true, isOnStage, showAllEvents = false, dateFormatPattern) => {
|
|
3651
|
+
const fullDateFormat = i18n.t("dateFormat");
|
|
3652
|
+
const birthEvents = getAllProp(indi, "BIRT");
|
|
3653
|
+
const firstBirthValue = birthEvents[0];
|
|
3654
|
+
const deathEvents = getAllProp(indi, "DEAT");
|
|
3655
|
+
const firstDeathValue = deathEvents[0];
|
|
3656
|
+
const birth = commonDateFormatter(
|
|
3657
|
+
firstBirthValue?.DATE,
|
|
3658
|
+
showDays ? fullDateFormat : "yyyy"
|
|
3710
3659
|
);
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
const
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3660
|
+
const birthPlace = showPlaces ? firstBirthValue?.PLAC?.value : void 0;
|
|
3661
|
+
const death = commonDateFormatter(
|
|
3662
|
+
firstDeathValue?.DATE,
|
|
3663
|
+
showDays ? fullDateFormat : "yyyy"
|
|
3664
|
+
);
|
|
3665
|
+
const deathPlace = showPlaces ? firstDeathValue?.PLAC?.value : void 0;
|
|
3666
|
+
const marriagePlaces = [];
|
|
3667
|
+
const marriages = [];
|
|
3668
|
+
if (showMarriages || isOnStage) {
|
|
3669
|
+
(indi?.get("FAMS")?.toValueList().values() ?? []).forEach((fam) => {
|
|
3670
|
+
const famRef = fam?.ref;
|
|
3671
|
+
const marriageDates = marriageDateFormatter(
|
|
3672
|
+
famRef,
|
|
3673
|
+
showDays,
|
|
3674
|
+
showPlaces,
|
|
3675
|
+
shortNote,
|
|
3676
|
+
showNote,
|
|
3677
|
+
true,
|
|
3678
|
+
showAllEvents);
|
|
3679
|
+
marriages.push(...marriageDates?.marriage ?? []);
|
|
3680
|
+
marriagePlaces.push(...marriageDates?.marriagePlaces ?? []);
|
|
3681
|
+
});
|
|
3682
|
+
}
|
|
3683
|
+
const birthStrings = [];
|
|
3684
|
+
const birthPlaces = [];
|
|
3685
|
+
const eventsToProcess = showAllEvents ? birthEvents : birthEvents.slice(0, 1);
|
|
3686
|
+
eventsToProcess.forEach((birthEvent) => {
|
|
3687
|
+
const birthDateNode = firstDate(birthEvent?.DATE);
|
|
3688
|
+
const birthDate = commonDateFormatter(
|
|
3689
|
+
birthDateNode,
|
|
3690
|
+
showDays ? fullDateFormat : "yyyy"
|
|
3691
|
+
);
|
|
3692
|
+
const birthEventNote = dateNote(birthDateNode, shortNote);
|
|
3693
|
+
const birthEventPlace = showPlaces ? birthEvent?.PLAC?.value : void 0;
|
|
3694
|
+
if (birthDate) {
|
|
3695
|
+
birthStrings.push(
|
|
3696
|
+
`*${birthEventNote && showNote ? i18n.t(`${birthEventNote} {{date}}`, {
|
|
3697
|
+
date: birthDate
|
|
3698
|
+
}) : birthDate}`
|
|
3699
|
+
);
|
|
3700
|
+
}
|
|
3701
|
+
birthPlaces.push(birthEventPlace);
|
|
3722
3702
|
});
|
|
3703
|
+
const deathStrings = [];
|
|
3704
|
+
const deathPlaces = [];
|
|
3705
|
+
const deathEventsToProcess = showAllEvents ? deathEvents : deathEvents.slice(0, 1);
|
|
3706
|
+
deathEventsToProcess.forEach((deathEvent) => {
|
|
3707
|
+
const deathDateNode = firstDate(deathEvent?.DATE);
|
|
3708
|
+
const deathDate = commonDateFormatter(
|
|
3709
|
+
deathDateNode,
|
|
3710
|
+
showDays ? fullDateFormat : "yyyy"
|
|
3711
|
+
);
|
|
3712
|
+
const deathEventNote = dateNote(deathDateNode, shortNote);
|
|
3713
|
+
const deathEventPlace = showPlaces ? deathEvent?.PLAC?.value : void 0;
|
|
3714
|
+
if (deathDate) {
|
|
3715
|
+
deathStrings.push(
|
|
3716
|
+
`\u2020${deathEventNote && showNote ? i18n.t(`${deathEventNote} {{date}}`, {
|
|
3717
|
+
date: deathDate
|
|
3718
|
+
}) : deathDate}`
|
|
3719
|
+
);
|
|
3720
|
+
}
|
|
3721
|
+
deathPlaces.push(deathEventPlace);
|
|
3722
|
+
});
|
|
3723
|
+
const birthString = birthStrings[0] ?? "";
|
|
3724
|
+
const deathString = deathStrings[0] ?? "";
|
|
3725
|
+
const marriageArray = marriages.length ? marriages.filter(Boolean) : [];
|
|
3726
|
+
const datesArray = !birth && !death ? marriageArray : [...birthStrings, ...marriageArray, ...deathStrings];
|
|
3727
|
+
const placesArray = !birth && !death ? marriagePlaces : [...birthPlaces, ...marriagePlaces, ...deathPlaces];
|
|
3728
|
+
const nonNullDatesArray = datesArray.filter(Boolean);
|
|
3729
|
+
const dates = nonNullDatesArray.join(" ").trim();
|
|
3730
|
+
return {
|
|
3731
|
+
inArray: nonNullDatesArray,
|
|
3732
|
+
inOrder: dates,
|
|
3733
|
+
places: placesArray,
|
|
3734
|
+
birth: birthString,
|
|
3735
|
+
marriage: marriageArray,
|
|
3736
|
+
death: deathString,
|
|
3737
|
+
...showPlaces ? {
|
|
3738
|
+
birthPlace,
|
|
3739
|
+
deathPlace,
|
|
3740
|
+
...showMarriages ? { marriages, marriagePlaces } : {}
|
|
3741
|
+
} : {},
|
|
3742
|
+
...showAllEvents ? {
|
|
3743
|
+
births: birthStrings,
|
|
3744
|
+
birthPlaces,
|
|
3745
|
+
deaths: deathStrings,
|
|
3746
|
+
deathPlaces
|
|
3747
|
+
} : {}
|
|
3748
|
+
};
|
|
3723
3749
|
};
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3750
|
+
|
|
3751
|
+
// src/utils/range.ts
|
|
3752
|
+
var toTuple = (r) => {
|
|
3753
|
+
if (Array.isArray(r)) {
|
|
3754
|
+
const [s2, e2] = r;
|
|
3755
|
+
return [
|
|
3756
|
+
s2 === void 0 ? void 0 : Number(s2),
|
|
3757
|
+
e2 === void 0 ? void 0 : Number(e2)
|
|
3758
|
+
];
|
|
3759
|
+
}
|
|
3760
|
+
if (r === "-" || r === "") return [void 0, void 0];
|
|
3761
|
+
const [s, e] = r.split("-");
|
|
3762
|
+
return [s ? Number(s) : void 0, e ? Number(e) : void 0];
|
|
3729
3763
|
};
|
|
3730
|
-
var
|
|
3731
|
-
|
|
3764
|
+
var isValidRange = (range) => {
|
|
3765
|
+
if (!Array.isArray(range) && range !== "" && range !== "-" && !/^\d*-\d*$/.test(range)) {
|
|
3766
|
+
return false;
|
|
3767
|
+
}
|
|
3768
|
+
if (Array.isArray(range) && range.some((r) => typeof r === "string" && isNaN(Number(r)))) {
|
|
3769
|
+
return false;
|
|
3770
|
+
}
|
|
3771
|
+
return true;
|
|
3732
3772
|
};
|
|
3733
|
-
var
|
|
3734
|
-
if (
|
|
3735
|
-
return
|
|
3773
|
+
var inRange = (year, range, trueIfNoYear = false) => {
|
|
3774
|
+
if (!isValidRange(range)) {
|
|
3775
|
+
return false;
|
|
3736
3776
|
}
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
if (!parts?.at && !parts?.letter) {
|
|
3740
|
-
newId = `@U${newId}`;
|
|
3741
|
-
} else if (!parts.at) {
|
|
3742
|
-
newId = `@${newId}`;
|
|
3743
|
-
} else if (!parts.letter) {
|
|
3744
|
-
newId = newId.replace(/^@/, "@U");
|
|
3777
|
+
if (!year) {
|
|
3778
|
+
return trueIfNoYear;
|
|
3745
3779
|
}
|
|
3746
|
-
|
|
3747
|
-
|
|
3780
|
+
const [start = -Infinity, end = Infinity] = toTuple(range);
|
|
3781
|
+
if (!start && !end) {
|
|
3782
|
+
return true;
|
|
3748
3783
|
}
|
|
3749
|
-
|
|
3784
|
+
if (start && !end) {
|
|
3785
|
+
return Number(year) >= Number(start);
|
|
3786
|
+
}
|
|
3787
|
+
if (!start && end) {
|
|
3788
|
+
return Number(year) <= Number(end);
|
|
3789
|
+
}
|
|
3790
|
+
return Number(start) <= Number(year) && Number(year) <= Number(end);
|
|
3750
3791
|
};
|
|
3751
3792
|
|
|
3752
3793
|
// src/classes/date.ts
|
|
@@ -3800,6 +3841,8 @@ var formatDateWithComponents = (date, hasDay, hasMonth, hasYear, noteValue, base
|
|
|
3800
3841
|
var CommonDate = class extends Common {
|
|
3801
3842
|
constructor(gedcom, id, main, parent) {
|
|
3802
3843
|
super(gedcom, id, main, parent);
|
|
3844
|
+
/** One DATE per event — merge must not turn this into a List. */
|
|
3845
|
+
this.isListable = false;
|
|
3803
3846
|
delete this.id;
|
|
3804
3847
|
}
|
|
3805
3848
|
get calendar() {
|
|
@@ -7320,14 +7363,15 @@ var Indi = class extends Common {
|
|
|
7320
7363
|
}
|
|
7321
7364
|
return foundPath;
|
|
7322
7365
|
}
|
|
7323
|
-
kinship(other, showMainPerson, lang = "en", entirePath, displayName = "givenname") {
|
|
7366
|
+
kinship(other, showMainPerson, lang = "en", entirePath, displayName = "givenname", nameOrder) {
|
|
7324
7367
|
const KinshipTranslatorClass2 = getKinshipTranslatorClass();
|
|
7325
7368
|
const translator = new KinshipTranslatorClass2(
|
|
7326
7369
|
this,
|
|
7327
7370
|
other,
|
|
7328
7371
|
lang,
|
|
7329
7372
|
entirePath,
|
|
7330
|
-
showMainPerson ? displayName : void 0
|
|
7373
|
+
showMainPerson ? displayName : void 0,
|
|
7374
|
+
nameOrder
|
|
7331
7375
|
);
|
|
7332
7376
|
return translator.translate(!!showMainPerson);
|
|
7333
7377
|
}
|
|
@@ -8321,7 +8365,7 @@ var KinshipTranslatorDe = class extends KinshipTranslatorBasic {
|
|
|
8321
8365
|
}
|
|
8322
8366
|
of(relation) {
|
|
8323
8367
|
const formattedName = nameFormatter(this.path?.[0]?.indi, {
|
|
8324
|
-
nameOrder:
|
|
8368
|
+
nameOrder: this.nameOrder
|
|
8325
8369
|
});
|
|
8326
8370
|
let name = formattedName.inOrder.filter(Boolean).join(" ");
|
|
8327
8371
|
if (this.displayName === "none") {
|