@treeviz/gedcom-parser 2.1.15 → 2.1.17
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 +41 -10
- package/dist/cli/index.js +41 -10
- package/dist/constants/index.js +1149 -1117
- package/dist/factories/index.js +1192 -1160
- package/dist/index.js +41 -10
- package/dist/kinship-translator/index.js +1192 -1160
- package/dist/structures/individual.d.ts +1 -0
- package/dist/structures/individual.d.ts.map +1 -1
- package/dist/types/types.d.ts +1 -0
- package/dist/types/types.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 +41 -10
- package/package.json +1 -1
|
@@ -2355,244 +2355,6 @@ var getKinshipTranslatorClass = () => {
|
|
|
2355
2355
|
return KinshipTranslatorClass;
|
|
2356
2356
|
};
|
|
2357
2357
|
|
|
2358
|
-
// src/utils/get-all-prop.ts
|
|
2359
|
-
var getAllProp = (indi, prop) => {
|
|
2360
|
-
return prop && (indi?.get(prop)?.toList().values() ?? []).filter(Boolean) || [];
|
|
2361
|
-
};
|
|
2362
|
-
|
|
2363
|
-
// src/utils/date-formatter.ts
|
|
2364
|
-
var ACCEPTED_DATE_FORMATS = [
|
|
2365
|
-
"yyyy.MM.dd.",
|
|
2366
|
-
"yyyy-MM-dd",
|
|
2367
|
-
"MM/dd/yyyy"
|
|
2368
|
-
];
|
|
2369
|
-
var ACCEPTED_DATE_FORMATS_REGEX = new RegExp(
|
|
2370
|
-
`(${ACCEPTED_DATE_FORMATS.map(
|
|
2371
|
-
(acceptedFormat) => acceptedFormat.replace(/[^.\-/]/g, "\\d")
|
|
2372
|
-
).join("|")})`,
|
|
2373
|
-
"gi"
|
|
2374
|
-
);
|
|
2375
|
-
var commonDateFormatter = (date, format2 = "yyyy", prefix = "") => {
|
|
2376
|
-
const formattedDate = date?.toValue(format2);
|
|
2377
|
-
if (!formattedDate) {
|
|
2378
|
-
return void 0;
|
|
2379
|
-
}
|
|
2380
|
-
return `${prefix}${formattedDate}`.trim();
|
|
2381
|
-
};
|
|
2382
|
-
var noteDateFormatter = (date, format2 = "yyyy", prefix = "", shortNote = true, showNote = true) => {
|
|
2383
|
-
const rawDate = commonDateFormatter(date, format2, "");
|
|
2384
|
-
if (!rawDate) {
|
|
2385
|
-
return void 0;
|
|
2386
|
-
}
|
|
2387
|
-
const note = date?.toNote(shortNote) ?? "";
|
|
2388
|
-
return `${prefix}${note && showNote ? i18n.t(`${note} {{date}}`, { date: rawDate }) : rawDate}`;
|
|
2389
|
-
};
|
|
2390
|
-
var marriageDateFormatter = (fam, showDays = false, showPlaces = false, shortNote = true, showNote = true, showDisplayTextIfNoDate = true, showAllEvents = false, dateFormatPattern) => {
|
|
2391
|
-
const fullDateFormat = i18n.t("dateFormat");
|
|
2392
|
-
const marriageDates = [];
|
|
2393
|
-
const marriagePlaces = [];
|
|
2394
|
-
const marriages = (fam?.toValueList().values() ?? []).flatMap((fam2) => {
|
|
2395
|
-
const family = fam2;
|
|
2396
|
-
const marrEvents = (family?.MARR?.toList().values() ?? []).filter(
|
|
2397
|
-
Boolean
|
|
2398
|
-
);
|
|
2399
|
-
if (marrEvents.length === 0) {
|
|
2400
|
-
const displayText = family?.get("DISPLAYTEXT")?.toValue() ?? "";
|
|
2401
|
-
if (showDisplayTextIfNoDate && displayText) {
|
|
2402
|
-
const displayDate = displayText.match(
|
|
2403
|
-
ACCEPTED_DATE_FORMATS_REGEX
|
|
2404
|
-
)?.[0];
|
|
2405
|
-
if (displayDate) {
|
|
2406
|
-
marriagePlaces.push(displayText.replace(displayDate, ""));
|
|
2407
|
-
const marriageDate = createCommonDate(
|
|
2408
|
-
fam2?.getGedcom(),
|
|
2409
|
-
void 0,
|
|
2410
|
-
family
|
|
2411
|
-
);
|
|
2412
|
-
marriageDate.value = displayDate;
|
|
2413
|
-
marriageDates.push(marriageDate);
|
|
2414
|
-
} else {
|
|
2415
|
-
marriagePlaces.push(displayText);
|
|
2416
|
-
marriageDates.push(void 0);
|
|
2417
|
-
return ["\u221E"];
|
|
2418
|
-
}
|
|
2419
|
-
}
|
|
2420
|
-
return [];
|
|
2421
|
-
}
|
|
2422
|
-
const eventsToProcess = showAllEvents ? marrEvents : marrEvents.slice(0, 1);
|
|
2423
|
-
return eventsToProcess.map((marrEvent) => {
|
|
2424
|
-
const marriageEventDetail = marrEvent;
|
|
2425
|
-
const marriageDate = marriageEventDetail?.DATE;
|
|
2426
|
-
const marriagePlace = showPlaces ? marriageEventDetail?.PLAC?.value : void 0;
|
|
2427
|
-
marriagePlaces.push(marriagePlace);
|
|
2428
|
-
marriageDates.push(marriageDate);
|
|
2429
|
-
const formattedDate = noteDateFormatter(
|
|
2430
|
-
marriageDate,
|
|
2431
|
-
showDays ? fullDateFormat : "yyyy",
|
|
2432
|
-
"\u221E",
|
|
2433
|
-
shortNote,
|
|
2434
|
-
showNote
|
|
2435
|
-
);
|
|
2436
|
-
return formattedDate ? formattedDate : void 0;
|
|
2437
|
-
});
|
|
2438
|
-
});
|
|
2439
|
-
const marriageArray = marriages.length ? marriages.filter(Boolean) : [];
|
|
2440
|
-
const datesArray = marriageArray.filter(Boolean);
|
|
2441
|
-
const placesArray = marriagePlaces.filter(Boolean);
|
|
2442
|
-
const dates = datesArray.join(" ").trim();
|
|
2443
|
-
return {
|
|
2444
|
-
rawArray: marriageDates,
|
|
2445
|
-
inArray: datesArray,
|
|
2446
|
-
inOrder: dates,
|
|
2447
|
-
places: placesArray,
|
|
2448
|
-
marriage: marriageArray,
|
|
2449
|
-
...showPlaces ? {
|
|
2450
|
-
marriages,
|
|
2451
|
-
marriagePlaces
|
|
2452
|
-
} : {}
|
|
2453
|
-
};
|
|
2454
|
-
};
|
|
2455
|
-
var dateFormatter = (indi, showMarriages = false, showDays = false, showPlaces = false, shortNote = true, showNote = true, isOnStage, showAllEvents = false, dateFormatPattern) => {
|
|
2456
|
-
const fullDateFormat = i18n.t("dateFormat");
|
|
2457
|
-
const birthEvents = getAllProp(indi, "BIRT");
|
|
2458
|
-
const firstBirthValue = birthEvents[0];
|
|
2459
|
-
const deathEvents = getAllProp(indi, "DEAT");
|
|
2460
|
-
const firstDeathValue = deathEvents[0];
|
|
2461
|
-
const birth = commonDateFormatter(
|
|
2462
|
-
firstBirthValue?.DATE,
|
|
2463
|
-
showDays ? fullDateFormat : "yyyy"
|
|
2464
|
-
);
|
|
2465
|
-
const birthPlace = showPlaces ? firstBirthValue?.PLAC?.value : void 0;
|
|
2466
|
-
const death = commonDateFormatter(
|
|
2467
|
-
firstDeathValue?.DATE,
|
|
2468
|
-
showDays ? fullDateFormat : "yyyy"
|
|
2469
|
-
);
|
|
2470
|
-
const deathPlace = showPlaces ? firstDeathValue?.PLAC?.value : void 0;
|
|
2471
|
-
const marriagePlaces = [];
|
|
2472
|
-
const marriages = [];
|
|
2473
|
-
if (showMarriages || isOnStage) {
|
|
2474
|
-
(indi?.get("FAMS")?.toValueList().values() ?? []).forEach((fam) => {
|
|
2475
|
-
const famRef = fam?.ref;
|
|
2476
|
-
const marriageDates = marriageDateFormatter(
|
|
2477
|
-
famRef,
|
|
2478
|
-
showDays,
|
|
2479
|
-
showPlaces,
|
|
2480
|
-
shortNote,
|
|
2481
|
-
showNote,
|
|
2482
|
-
true,
|
|
2483
|
-
showAllEvents);
|
|
2484
|
-
marriages.push(...marriageDates?.marriage ?? []);
|
|
2485
|
-
marriagePlaces.push(...marriageDates?.marriagePlaces ?? []);
|
|
2486
|
-
});
|
|
2487
|
-
}
|
|
2488
|
-
const birthStrings = [];
|
|
2489
|
-
const birthPlaces = [];
|
|
2490
|
-
const eventsToProcess = showAllEvents ? birthEvents : birthEvents.slice(0, 1);
|
|
2491
|
-
eventsToProcess.forEach((birthEvent) => {
|
|
2492
|
-
const birthDate = commonDateFormatter(
|
|
2493
|
-
birthEvent?.DATE,
|
|
2494
|
-
showDays ? fullDateFormat : "yyyy"
|
|
2495
|
-
);
|
|
2496
|
-
const birthEventNote = birthEvent?.DATE?.toNote(shortNote) ?? "";
|
|
2497
|
-
const birthEventPlace = showPlaces ? birthEvent?.PLAC?.value : void 0;
|
|
2498
|
-
if (birthDate) {
|
|
2499
|
-
birthStrings.push(
|
|
2500
|
-
`*${birthEventNote && showNote ? i18n.t(`${birthEventNote} {{date}}`, {
|
|
2501
|
-
date: birthDate
|
|
2502
|
-
}) : birthDate}`
|
|
2503
|
-
);
|
|
2504
|
-
}
|
|
2505
|
-
birthPlaces.push(birthEventPlace);
|
|
2506
|
-
});
|
|
2507
|
-
const deathStrings = [];
|
|
2508
|
-
const deathPlaces = [];
|
|
2509
|
-
const deathEventsToProcess = showAllEvents ? deathEvents : deathEvents.slice(0, 1);
|
|
2510
|
-
deathEventsToProcess.forEach((deathEvent) => {
|
|
2511
|
-
const deathDate = commonDateFormatter(
|
|
2512
|
-
deathEvent?.DATE,
|
|
2513
|
-
showDays ? fullDateFormat : "yyyy"
|
|
2514
|
-
);
|
|
2515
|
-
const deathEventNote = deathEvent?.DATE?.toNote(shortNote) ?? "";
|
|
2516
|
-
const deathEventPlace = showPlaces ? deathEvent?.PLAC?.value : void 0;
|
|
2517
|
-
if (deathDate) {
|
|
2518
|
-
deathStrings.push(
|
|
2519
|
-
`\u2020${deathEventNote && showNote ? i18n.t(`${deathEventNote} {{date}}`, {
|
|
2520
|
-
date: deathDate
|
|
2521
|
-
}) : deathDate}`
|
|
2522
|
-
);
|
|
2523
|
-
}
|
|
2524
|
-
deathPlaces.push(deathEventPlace);
|
|
2525
|
-
});
|
|
2526
|
-
const birthString = birthStrings[0] ?? "";
|
|
2527
|
-
const deathString = deathStrings[0] ?? "";
|
|
2528
|
-
const marriageArray = marriages.length ? marriages.filter(Boolean) : [];
|
|
2529
|
-
const datesArray = !birth && !death ? marriageArray : [...birthStrings, ...marriageArray, ...deathStrings];
|
|
2530
|
-
const placesArray = !birth && !death ? marriagePlaces : [...birthPlaces, ...marriagePlaces, ...deathPlaces];
|
|
2531
|
-
const nonNullDatesArray = datesArray.filter(Boolean);
|
|
2532
|
-
const dates = nonNullDatesArray.join(" ").trim();
|
|
2533
|
-
return {
|
|
2534
|
-
inArray: nonNullDatesArray,
|
|
2535
|
-
inOrder: dates,
|
|
2536
|
-
places: placesArray,
|
|
2537
|
-
birth: birthString,
|
|
2538
|
-
marriage: marriageArray,
|
|
2539
|
-
death: deathString,
|
|
2540
|
-
...showPlaces ? {
|
|
2541
|
-
birthPlace,
|
|
2542
|
-
deathPlace,
|
|
2543
|
-
...showMarriages ? { marriages, marriagePlaces } : {}
|
|
2544
|
-
} : {},
|
|
2545
|
-
...showAllEvents ? {
|
|
2546
|
-
births: birthStrings,
|
|
2547
|
-
birthPlaces,
|
|
2548
|
-
deaths: deathStrings,
|
|
2549
|
-
deathPlaces
|
|
2550
|
-
} : {}
|
|
2551
|
-
};
|
|
2552
|
-
};
|
|
2553
|
-
|
|
2554
|
-
// src/utils/range.ts
|
|
2555
|
-
var toTuple = (r) => {
|
|
2556
|
-
if (Array.isArray(r)) {
|
|
2557
|
-
const [s2, e2] = r;
|
|
2558
|
-
return [
|
|
2559
|
-
s2 === void 0 ? void 0 : Number(s2),
|
|
2560
|
-
e2 === void 0 ? void 0 : Number(e2)
|
|
2561
|
-
];
|
|
2562
|
-
}
|
|
2563
|
-
if (r === "-" || r === "") return [void 0, void 0];
|
|
2564
|
-
const [s, e] = r.split("-");
|
|
2565
|
-
return [s ? Number(s) : void 0, e ? Number(e) : void 0];
|
|
2566
|
-
};
|
|
2567
|
-
var isValidRange = (range) => {
|
|
2568
|
-
if (!Array.isArray(range) && range !== "" && range !== "-" && !/^\d*-\d*$/.test(range)) {
|
|
2569
|
-
return false;
|
|
2570
|
-
}
|
|
2571
|
-
if (Array.isArray(range) && range.some((r) => typeof r === "string" && isNaN(Number(r)))) {
|
|
2572
|
-
return false;
|
|
2573
|
-
}
|
|
2574
|
-
return true;
|
|
2575
|
-
};
|
|
2576
|
-
var inRange = (year, range, trueIfNoYear = false) => {
|
|
2577
|
-
if (!isValidRange(range)) {
|
|
2578
|
-
return false;
|
|
2579
|
-
}
|
|
2580
|
-
if (!year) {
|
|
2581
|
-
return trueIfNoYear;
|
|
2582
|
-
}
|
|
2583
|
-
const [start = -Infinity, end = Infinity] = toTuple(range);
|
|
2584
|
-
if (!start && !end) {
|
|
2585
|
-
return true;
|
|
2586
|
-
}
|
|
2587
|
-
if (start && !end) {
|
|
2588
|
-
return Number(year) >= Number(start);
|
|
2589
|
-
}
|
|
2590
|
-
if (!start && end) {
|
|
2591
|
-
return Number(year) <= Number(end);
|
|
2592
|
-
}
|
|
2593
|
-
return Number(start) <= Number(year) && Number(year) <= Number(end);
|
|
2594
|
-
};
|
|
2595
|
-
|
|
2596
2358
|
// src/constants/constants.ts
|
|
2597
2359
|
var ID_REG = /^@[_a-zA-Z0-9]+@/;
|
|
2598
2360
|
var ID_GETTER_REG = /^(?<at>@)?(?<letter>[A-Z])?/i;
|
|
@@ -2677,1087 +2439,1355 @@ var objeXrefKey = (obje, fallback = 0) => {
|
|
|
2677
2439
|
return `@O${fallback}@`;
|
|
2678
2440
|
};
|
|
2679
2441
|
var objeNoteValue = (obje) => mediaIdValue(obje, "FILE.NOTE") || mediaIdValue(obje, "NOTE") || "";
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2442
|
+
|
|
2443
|
+
// src/classes/common.ts
|
|
2444
|
+
var Common = class _Common {
|
|
2445
|
+
constructor(gedcom, id, main, parent) {
|
|
2684
2446
|
this.isListable = true;
|
|
2685
|
-
this.
|
|
2686
|
-
|
|
2687
|
-
|
|
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;
|
|
2688
2455
|
}
|
|
2689
2456
|
}
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
typeof indi === "string" ? indi : indi?.id ?? ""
|
|
2696
|
-
);
|
|
2457
|
+
set type(type) {
|
|
2458
|
+
if (type) {
|
|
2459
|
+
this.uniqueId = this.uniqueId?.replace(/^[^:]+/, `~${type}`);
|
|
2460
|
+
}
|
|
2461
|
+
this._type = type;
|
|
2697
2462
|
}
|
|
2698
|
-
get(
|
|
2699
|
-
|
|
2700
|
-
this.entries().forEach(([key, item]) => {
|
|
2701
|
-
propList.item(key, item.get(name));
|
|
2702
|
-
});
|
|
2703
|
-
return propList;
|
|
2463
|
+
get type() {
|
|
2464
|
+
return this._type;
|
|
2704
2465
|
}
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
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];
|
|
2711
2477
|
}
|
|
2712
|
-
|
|
2713
|
-
|
|
2478
|
+
this._gedcom.reflist[id] = this;
|
|
2479
|
+
}
|
|
2714
2480
|
}
|
|
2715
|
-
|
|
2716
|
-
return
|
|
2481
|
+
get uniqueId() {
|
|
2482
|
+
return this._uniqueId;
|
|
2717
2483
|
}
|
|
2718
|
-
|
|
2719
|
-
|
|
2484
|
+
set id(id) {
|
|
2485
|
+
this._id = idGetter(id);
|
|
2720
2486
|
}
|
|
2721
|
-
|
|
2722
|
-
return
|
|
2487
|
+
get id() {
|
|
2488
|
+
return idGetter(this._id);
|
|
2723
2489
|
}
|
|
2724
|
-
|
|
2490
|
+
set value(value) {
|
|
2491
|
+
this._value = value;
|
|
2725
2492
|
}
|
|
2726
|
-
|
|
2727
|
-
return this.
|
|
2493
|
+
get value() {
|
|
2494
|
+
return this._value;
|
|
2728
2495
|
}
|
|
2729
|
-
|
|
2730
|
-
|
|
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;
|
|
2731
2502
|
}
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
return key && this.items[key];
|
|
2503
|
+
// avoid to override
|
|
2504
|
+
get originalValue() {
|
|
2505
|
+
return this._value;
|
|
2736
2506
|
}
|
|
2737
|
-
|
|
2738
|
-
if (
|
|
2739
|
-
|
|
2740
|
-
|
|
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
|
+
);
|
|
2741
2513
|
}
|
|
2742
|
-
return
|
|
2514
|
+
return this;
|
|
2743
2515
|
}
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
this.setLength();
|
|
2516
|
+
get main() {
|
|
2517
|
+
return this._main;
|
|
2747
2518
|
}
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
delete this.items[itemId];
|
|
2751
|
-
});
|
|
2752
|
-
this.setLength();
|
|
2753
|
-
return this;
|
|
2519
|
+
get parent() {
|
|
2520
|
+
return this._parent;
|
|
2754
2521
|
}
|
|
2755
|
-
|
|
2756
|
-
if (
|
|
2757
|
-
|
|
2758
|
-
this.
|
|
2759
|
-
}
|
|
2760
|
-
|
|
2761
|
-
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);
|
|
2762
2528
|
}
|
|
2763
|
-
this.setLength();
|
|
2764
|
-
return this;
|
|
2765
2529
|
}
|
|
2766
|
-
|
|
2767
|
-
this.
|
|
2768
|
-
return this;
|
|
2530
|
+
getRefs() {
|
|
2531
|
+
return this._refs;
|
|
2769
2532
|
}
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
this.values(),
|
|
2773
|
-
mergedList?.values() ?? [],
|
|
2774
|
-
"id"
|
|
2775
|
-
);
|
|
2776
|
-
return new _List(inter);
|
|
2533
|
+
exportValue() {
|
|
2534
|
+
return this.value;
|
|
2777
2535
|
}
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
this.values(),
|
|
2781
|
-
mergedList?.values() ?? [],
|
|
2782
|
-
"id"
|
|
2783
|
-
);
|
|
2784
|
-
return new _List(inter);
|
|
2536
|
+
removeValue() {
|
|
2537
|
+
delete this._value;
|
|
2785
2538
|
}
|
|
2786
|
-
|
|
2787
|
-
if (
|
|
2788
|
-
|
|
2789
|
-
if (this.items[item.id]) {
|
|
2790
|
-
delete this.items[item.id];
|
|
2791
|
-
increase = false;
|
|
2792
|
-
}
|
|
2793
|
-
this.items = Object.assign(
|
|
2794
|
-
{
|
|
2795
|
-
[item.id]: item
|
|
2796
|
-
},
|
|
2797
|
-
this.items
|
|
2798
|
-
);
|
|
2799
|
-
if (increase) {
|
|
2800
|
-
this.setLength("increase");
|
|
2801
|
-
}
|
|
2539
|
+
set(name, value) {
|
|
2540
|
+
if (isGedcomTrailerTag(name)) {
|
|
2541
|
+
return void 0;
|
|
2802
2542
|
}
|
|
2803
|
-
|
|
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);
|
|
2804
2551
|
}
|
|
2805
|
-
|
|
2806
|
-
if (
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
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);
|
|
2815
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);
|
|
2816
2574
|
}
|
|
2817
|
-
return this;
|
|
2575
|
+
return get(this, name);
|
|
2818
2576
|
}
|
|
2819
|
-
|
|
2820
|
-
if (
|
|
2821
|
-
|
|
2822
|
-
this.setLength("decrease");
|
|
2577
|
+
get(name) {
|
|
2578
|
+
if (!name.includes(".")) {
|
|
2579
|
+
return get(this, name);
|
|
2823
2580
|
}
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
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;
|
|
2834
2611
|
}
|
|
2835
|
-
|
|
2836
|
-
this
|
|
2837
|
-
iterate(item, key, index);
|
|
2838
|
-
});
|
|
2612
|
+
remove(name) {
|
|
2613
|
+
unset(this, name);
|
|
2839
2614
|
}
|
|
2840
|
-
|
|
2841
|
-
return this.
|
|
2842
|
-
return iterate(item, key, index);
|
|
2843
|
-
});
|
|
2615
|
+
getGedcom() {
|
|
2616
|
+
return this._gedcom;
|
|
2844
2617
|
}
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
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;
|
|
2849
2638
|
}
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
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")) {
|
|
2856
2688
|
return;
|
|
2857
2689
|
}
|
|
2858
|
-
if (
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
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
|
+
}
|
|
2867
2710
|
}
|
|
2868
|
-
return itemValue === value;
|
|
2869
|
-
})) {
|
|
2870
|
-
newList.item(itemId, item);
|
|
2871
2711
|
}
|
|
2872
2712
|
});
|
|
2873
|
-
return
|
|
2713
|
+
return json;
|
|
2874
2714
|
}
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
}
|
|
2884
|
-
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;
|
|
2885
2723
|
}
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
if (
|
|
2894
|
-
|
|
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);
|
|
2895
2735
|
}
|
|
2896
|
-
return itemValue === value;
|
|
2897
|
-
})) {
|
|
2898
|
-
foundItem = item;
|
|
2899
|
-
return true;
|
|
2900
2736
|
}
|
|
2901
|
-
return false;
|
|
2902
2737
|
});
|
|
2903
|
-
return
|
|
2738
|
+
return this;
|
|
2904
2739
|
}
|
|
2905
|
-
|
|
2906
|
-
const
|
|
2907
|
-
const
|
|
2908
|
-
|
|
2909
|
-
|
|
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, "")}`;
|
|
2910
2750
|
}
|
|
2911
|
-
const
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
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
|
+
);
|
|
2938
2786
|
}
|
|
2939
|
-
return sortValue * (direction === "DESC" ? -1 : 1);
|
|
2940
2787
|
}
|
|
2941
|
-
);
|
|
2942
|
-
sortedItems.forEach(([key, value]) => {
|
|
2943
|
-
newList.item(key, value);
|
|
2944
2788
|
});
|
|
2945
|
-
return
|
|
2789
|
+
return gedcom;
|
|
2946
2790
|
}
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
const isIterator = typeof groups === "function";
|
|
2950
|
-
if (!isIterator && (!groups || !Object.keys(groups).length)) {
|
|
2951
|
-
groupped.Unknown = new ClassName().merge(this);
|
|
2952
|
-
groupped.Unknown.marker = "Unknown";
|
|
2953
|
-
return groupped;
|
|
2954
|
-
}
|
|
2955
|
-
this.forEach((item, itemId) => {
|
|
2956
|
-
const group = [];
|
|
2957
|
-
if (isIterator) {
|
|
2958
|
-
const newGroups = groups(item, itemId);
|
|
2959
|
-
group.push(
|
|
2960
|
-
...Array.isArray(newGroups) ? newGroups : [newGroups]
|
|
2961
|
-
);
|
|
2962
|
-
} else {
|
|
2963
|
-
const [key, { getter }] = Object.entries(
|
|
2964
|
-
typeof groups === "string" ? { [groups]: {} } : groups
|
|
2965
|
-
)[0];
|
|
2966
|
-
const raw = item.get(key)?.index(0);
|
|
2967
|
-
let value = raw?.toValue();
|
|
2968
|
-
if (getter && typeof getter === "function") {
|
|
2969
|
-
value = getter(value, raw);
|
|
2970
|
-
}
|
|
2971
|
-
if (value) {
|
|
2972
|
-
group.push(value);
|
|
2973
|
-
}
|
|
2974
|
-
}
|
|
2975
|
-
if (!group.length) {
|
|
2976
|
-
group.push("Unknown");
|
|
2977
|
-
}
|
|
2978
|
-
group.forEach((g) => {
|
|
2979
|
-
const newGroup = typeof g === "string" ? { group: g } : g;
|
|
2980
|
-
if (!groupped[newGroup.group]) {
|
|
2981
|
-
groupped[newGroup.group] = new ClassName();
|
|
2982
|
-
groupped[newGroup.group].marker = newGroup.marker ?? newGroup.group;
|
|
2983
|
-
}
|
|
2984
|
-
groupped[newGroup.group]?.append(item);
|
|
2985
|
-
});
|
|
2986
|
-
});
|
|
2987
|
-
if (sort) {
|
|
2988
|
-
return Object.entries(groupped).toSorted(([ak, a], [bk, b]) => {
|
|
2989
|
-
if (typeof sort === "function") {
|
|
2990
|
-
return sort(a, ak, b, bk);
|
|
2991
|
-
}
|
|
2992
|
-
if (ak === "Unknown") {
|
|
2993
|
-
return 1;
|
|
2994
|
-
}
|
|
2995
|
-
if (bk === "Unknown") {
|
|
2996
|
-
return -1;
|
|
2997
|
-
}
|
|
2998
|
-
if (sort === "group") {
|
|
2999
|
-
return ak.localeCompare(bk);
|
|
3000
|
-
}
|
|
3001
|
-
return (b?.length ?? 0) - (a?.length ?? 0);
|
|
3002
|
-
}).reduce((acc, [key, value]) => {
|
|
3003
|
-
if (minOccurance > -1 && (value?.length ?? 0) < minOccurance) {
|
|
3004
|
-
const otherKey = lessOccuranceLabel;
|
|
3005
|
-
acc[otherKey] = acc[otherKey] && value ? acc[otherKey].merge(value) : value;
|
|
3006
|
-
} else {
|
|
3007
|
-
acc[key] = value;
|
|
3008
|
-
}
|
|
3009
|
-
return acc;
|
|
3010
|
-
}, {});
|
|
3011
|
-
}
|
|
3012
|
-
return groupped;
|
|
3013
|
-
}
|
|
3014
|
-
findIndex(item) {
|
|
3015
|
-
if (!item?.id) {
|
|
3016
|
-
return -1;
|
|
3017
|
-
}
|
|
3018
|
-
return this.keys().findIndex((key) => key === item.id);
|
|
2791
|
+
getHeadRecord() {
|
|
2792
|
+
return get(this, "HEAD") || get(this.getGedcom(), "HEAD");
|
|
3019
2793
|
}
|
|
3020
|
-
|
|
3021
|
-
return this.
|
|
2794
|
+
getOriginalHeadRecord() {
|
|
2795
|
+
return get(this, ORIG_HEAD_TAG) || get(this.getGedcom(), ORIG_HEAD_TAG) || get(this.getHeadRecord(), ORIG_HEAD_TAG);
|
|
3022
2796
|
}
|
|
3023
|
-
|
|
3024
|
-
const
|
|
3025
|
-
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
|
+
});
|
|
3026
2802
|
}
|
|
3027
|
-
|
|
3028
|
-
const
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
if (!Array.isArray(json[validTag])) {
|
|
3033
|
-
json[validTag] = [json[validTag]];
|
|
3034
|
-
}
|
|
3035
|
-
json[validTag].push(
|
|
3036
|
-
item.toObject(validTag, options)
|
|
3037
|
-
);
|
|
3038
|
-
} else {
|
|
3039
|
-
json[validTag] = item.toObject(
|
|
3040
|
-
validTag,
|
|
3041
|
-
options
|
|
3042
|
-
);
|
|
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;
|
|
3043
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);
|
|
3044
2816
|
});
|
|
3045
|
-
return json;
|
|
3046
2817
|
}
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
return gedcom.join("\n");
|
|
2818
|
+
isGenoPro() {
|
|
2819
|
+
return this.sourStartsWith("genopro");
|
|
3050
2820
|
}
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
this.entries().forEach(([_, item]) => {
|
|
3054
|
-
const validTag = getValidTag(tag);
|
|
3055
|
-
const xref = item.id;
|
|
3056
|
-
const payload = item.exportValue?.();
|
|
3057
|
-
if (xref) {
|
|
3058
|
-
gedcom.push(
|
|
3059
|
-
`${level} ${xref} ${validTag}${payload ? ` ${payload}` : ""}`
|
|
3060
|
-
);
|
|
3061
|
-
} else {
|
|
3062
|
-
gedcom.push(
|
|
3063
|
-
`${level} ${validTag}${payload ? ` ${payload}` : ""}`
|
|
3064
|
-
);
|
|
3065
|
-
}
|
|
3066
|
-
gedcom.push(
|
|
3067
|
-
...item.toGedcomLines(
|
|
3068
|
-
validTag,
|
|
3069
|
-
level + 1,
|
|
3070
|
-
options
|
|
3071
|
-
)
|
|
3072
|
-
);
|
|
3073
|
-
});
|
|
3074
|
-
return gedcom;
|
|
2821
|
+
isAhnenblatt() {
|
|
2822
|
+
return this.sourStartsWith("ahnenblatt");
|
|
3075
2823
|
}
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
this.entries().forEach(([key, item]) => {
|
|
3079
|
-
propList.item(key, item?.toValue());
|
|
3080
|
-
});
|
|
3081
|
-
return propList;
|
|
2824
|
+
isGeni() {
|
|
2825
|
+
return this.sourStartsWith("geni");
|
|
3082
2826
|
}
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
return this.get(tag);
|
|
2827
|
+
isAncestry() {
|
|
2828
|
+
return this.sourStartsWith("ancestry");
|
|
3086
2829
|
}
|
|
3087
|
-
|
|
3088
|
-
return
|
|
2830
|
+
isMyHeritage() {
|
|
2831
|
+
return this.sourStartsWith("myheritage");
|
|
3089
2832
|
}
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
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";
|
|
3094
2851
|
});
|
|
3095
|
-
return newList;
|
|
3096
2852
|
}
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
this.isListable = true;
|
|
3103
|
-
this._gedcom = gedcom;
|
|
3104
|
-
this._main = main;
|
|
3105
|
-
this._parent = parent;
|
|
3106
|
-
this.initUniqueId();
|
|
3107
|
-
if (id) {
|
|
3108
|
-
this._id = id;
|
|
3109
|
-
} else {
|
|
3110
|
-
delete this._id;
|
|
3111
|
-
}
|
|
2853
|
+
isGNO2GED() {
|
|
2854
|
+
return this.getSourceHeads().some((head) => {
|
|
2855
|
+
const sour = get(head, "SOUR.value");
|
|
2856
|
+
return sour === "GNO2GED";
|
|
2857
|
+
});
|
|
3112
2858
|
}
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
this.uniqueId = this.uniqueId?.replace(/^[^:]+/, `~${type}`);
|
|
3116
|
-
}
|
|
3117
|
-
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"));
|
|
3118
2861
|
}
|
|
3119
|
-
|
|
3120
|
-
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"));
|
|
3121
2864
|
}
|
|
3122
|
-
|
|
3123
|
-
if (this
|
|
3124
|
-
|
|
2865
|
+
getTreeId() {
|
|
2866
|
+
if (this?.isAncestry()) {
|
|
2867
|
+
const id = this.getAncestryTreeId();
|
|
2868
|
+
if (id !== void 0) return id;
|
|
3125
2869
|
}
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
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;
|
|
3135
2893
|
}
|
|
2894
|
+
return this.getUniversalTreeId();
|
|
3136
2895
|
}
|
|
3137
|
-
|
|
3138
|
-
return this.
|
|
2896
|
+
getAncestryTreeName() {
|
|
2897
|
+
return this.getFromSourceHeads("SOUR._TREE.value") || (get(this, "HEAD.SOUR._TREE.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.value"));
|
|
3139
2898
|
}
|
|
3140
|
-
|
|
3141
|
-
|
|
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;
|
|
3142
2905
|
}
|
|
3143
|
-
|
|
3144
|
-
|
|
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";
|
|
3145
2912
|
}
|
|
3146
|
-
|
|
3147
|
-
this.
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
return this._value;
|
|
3151
|
-
}
|
|
3152
|
-
/**
|
|
3153
|
-
* Set the gedcom reference for this object
|
|
3154
|
-
* @param gedcom - The GedComType to set as the gedcom reference
|
|
3155
|
-
*/
|
|
3156
|
-
setGedcom(gedcom) {
|
|
3157
|
-
this._gedcom = gedcom;
|
|
3158
|
-
}
|
|
3159
|
-
// avoid to override
|
|
3160
|
-
get originalValue() {
|
|
3161
|
-
return this._value;
|
|
3162
|
-
}
|
|
3163
|
-
get ref() {
|
|
3164
|
-
if (typeof this.value === "string" && isId(this.value) && this.refType) {
|
|
3165
|
-
return this._gedcom?.[getListTag(this.refType)]?.item(
|
|
3166
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3167
|
-
this.value
|
|
3168
|
-
);
|
|
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;
|
|
3169
2917
|
}
|
|
3170
|
-
|
|
2918
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
2919
|
+
return fileName || "FamilySearch Import";
|
|
3171
2920
|
}
|
|
3172
|
-
|
|
3173
|
-
|
|
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;
|
|
3174
2930
|
}
|
|
3175
|
-
|
|
3176
|
-
|
|
2931
|
+
getAhnenblattTreeName() {
|
|
2932
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
2933
|
+
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
3177
2934
|
}
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
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];
|
|
3182
2941
|
}
|
|
3183
|
-
this._refs.item(refNode.value, refNode);
|
|
3184
2942
|
}
|
|
2943
|
+
return void 0;
|
|
3185
2944
|
}
|
|
3186
|
-
|
|
3187
|
-
|
|
2945
|
+
getGeniTreeName() {
|
|
2946
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
2947
|
+
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
3188
2948
|
}
|
|
3189
|
-
|
|
3190
|
-
|
|
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;
|
|
3191
2958
|
}
|
|
3192
|
-
|
|
3193
|
-
|
|
2959
|
+
getGenoProTreeName() {
|
|
2960
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
2961
|
+
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
3194
2962
|
}
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
if (typeof value === "string") {
|
|
3200
|
-
const usedValue = createCommon(this._gedcom, void 0, this.main);
|
|
3201
|
-
usedValue.value = value;
|
|
3202
|
-
set(this, name, usedValue);
|
|
3203
|
-
} else {
|
|
3204
|
-
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;
|
|
3205
2967
|
}
|
|
3206
|
-
return
|
|
2968
|
+
return `gno_${this._gedcom?.refcount || "unknown"}`;
|
|
3207
2969
|
}
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
2970
|
+
getGNO2GEDTreeName() {
|
|
2971
|
+
const treeName = get(this, "HEAD._TREE.value") || get(this.getGedcom(), "HEAD._TREE.value");
|
|
2972
|
+
if (treeName) {
|
|
2973
|
+
return treeName;
|
|
3211
2974
|
}
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
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]}`;
|
|
3217
2990
|
}
|
|
3218
|
-
const values = [
|
|
3219
|
-
...curValue.values(),
|
|
3220
|
-
...value instanceof List ? value.values() : [value]
|
|
3221
|
-
];
|
|
3222
|
-
curValue.concat({
|
|
3223
|
-
...!unique ? values : uniqBy(
|
|
3224
|
-
values,
|
|
3225
|
-
(value2) => value2 instanceof _Common ? value2?.value : void 0
|
|
3226
|
-
)
|
|
3227
|
-
});
|
|
3228
|
-
} else {
|
|
3229
|
-
this.set(name, value);
|
|
3230
2991
|
}
|
|
3231
|
-
return
|
|
2992
|
+
return `${prefix}_${this._gedcom?.refcount || "unknown"}`;
|
|
3232
2993
|
}
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
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}`;
|
|
3236
3005
|
}
|
|
3237
|
-
const
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
const indexPart = Number(part);
|
|
3241
|
-
const itemIndex = part.match(/items\[(?<itemIndex>\d+)\]/)?.groups?.itemIndex;
|
|
3242
|
-
const itemId = part.match(/items\[(?<itemId>@[A-Z]+\d+@)\]/)?.groups?.itemId;
|
|
3243
|
-
const usedPart = itemId || itemIndex;
|
|
3244
|
-
if (last instanceof List) {
|
|
3245
|
-
if (!isNaN(indexPart)) {
|
|
3246
|
-
last = last.index(indexPart);
|
|
3247
|
-
} else {
|
|
3248
|
-
if (usedPart) {
|
|
3249
|
-
last = last.item(usedPart);
|
|
3250
|
-
} else {
|
|
3251
|
-
last = last?.index(0)?.get(part);
|
|
3252
|
-
}
|
|
3253
|
-
}
|
|
3254
|
-
} else {
|
|
3255
|
-
const usedIndex = Number(itemIndex ?? indexPart);
|
|
3256
|
-
if (!isNaN(usedIndex)) {
|
|
3257
|
-
last = last?.toList().index(usedIndex);
|
|
3258
|
-
} else {
|
|
3259
|
-
last = last?.get(itemId ?? part);
|
|
3260
|
-
}
|
|
3261
|
-
}
|
|
3262
|
-
if (!last) {
|
|
3263
|
-
break;
|
|
3264
|
-
}
|
|
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}`;
|
|
3265
3009
|
}
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
getGedcom() {
|
|
3272
|
-
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`;
|
|
3273
3015
|
}
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
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;
|
|
3279
3020
|
}
|
|
3280
|
-
if (
|
|
3281
|
-
|
|
3021
|
+
if (this?.isMyHeritage()) {
|
|
3022
|
+
const name = this.getMyHeritageTreeName();
|
|
3023
|
+
if (name) return name;
|
|
3282
3024
|
}
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3025
|
+
if (this?.isFamilySearch()) {
|
|
3026
|
+
const name = this.getFamilySearchTreeName();
|
|
3027
|
+
if (name) return name;
|
|
3286
3028
|
}
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
return
|
|
3304
|
-
}
|
|
3305
|
-
toList() {
|
|
3306
|
-
return new List().concat(
|
|
3307
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3308
|
-
this.id ? { [this.id]: this } : { ...[this] }
|
|
3309
|
-
);
|
|
3310
|
-
}
|
|
3311
|
-
index(i) {
|
|
3312
|
-
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();
|
|
3313
3046
|
}
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
);
|
|
3321
|
-
}
|
|
3322
|
-
standardizeObject(tag, options) {
|
|
3323
|
-
if (tag === "OBJE" && options?.obje?.standardize && "standardizeMedia" in this) {
|
|
3324
|
-
const standardize = this.standardizeMedia;
|
|
3325
|
-
return standardize.call(
|
|
3326
|
-
this,
|
|
3327
|
-
options.obje.namespace,
|
|
3328
|
-
options.obje.override,
|
|
3329
|
-
this.isAncestry() ? ancestryMediaFileUrl : void 0,
|
|
3330
|
-
options.gedcomVersion
|
|
3331
|
-
);
|
|
3332
|
-
}
|
|
3333
|
-
}
|
|
3334
|
-
toJson(tag, options) {
|
|
3335
|
-
const json = this.toObject(tag, options);
|
|
3336
|
-
return JSON.stringify(json);
|
|
3337
|
-
}
|
|
3338
|
-
toObject(tag, options) {
|
|
3339
|
-
this.standardizeObject(tag, options);
|
|
3340
|
-
const validKeys = getValidKeys(this);
|
|
3341
|
-
let json = {};
|
|
3342
|
-
validKeys.forEach((key) => {
|
|
3343
|
-
if (options?.persist && (key === "DAY" || key === "MONTH" || key === "YEAR")) {
|
|
3344
|
-
return;
|
|
3345
|
-
}
|
|
3346
|
-
if (key === "id" && this.id !== void 0) {
|
|
3347
|
-
json.id = this.id;
|
|
3348
|
-
} else if (key === "_id" && this._id !== void 0) {
|
|
3349
|
-
json.id = this._id;
|
|
3350
|
-
} else if (key === "value" && this.value !== void 0) {
|
|
3351
|
-
json.value = this.value;
|
|
3352
|
-
} else if (key === "_value" && this._value !== void 0) {
|
|
3353
|
-
json.value = this._value;
|
|
3354
|
-
} else {
|
|
3355
|
-
const validKey = key;
|
|
3356
|
-
const prop = this.get(validKey);
|
|
3357
|
-
if (typeof prop?.toObject === "function") {
|
|
3358
|
-
if (prop instanceof _Common) {
|
|
3359
|
-
json[validKey] = prop.toObject(validKey, options);
|
|
3360
|
-
} else if (prop instanceof List) {
|
|
3361
|
-
json = {
|
|
3362
|
-
...json,
|
|
3363
|
-
...prop.toObject(validKey, options)
|
|
3364
|
-
};
|
|
3365
|
-
}
|
|
3366
|
-
}
|
|
3047
|
+
};
|
|
3048
|
+
var createProxy = (target) => {
|
|
3049
|
+
return new Proxy(target, {
|
|
3050
|
+
get(t, prop, receiver) {
|
|
3051
|
+
if (prop === "unwrapped") {
|
|
3052
|
+
return target;
|
|
3367
3053
|
}
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
}
|
|
3371
|
-
merge(other, override = false, avoidKeys = []) {
|
|
3372
|
-
if (!other) {
|
|
3373
|
-
return this;
|
|
3374
|
-
}
|
|
3375
|
-
const validKeys = getValidKeys(other);
|
|
3376
|
-
validKeys.forEach((validKey) => {
|
|
3377
|
-
if (avoidKeys.includes(validKey)) {
|
|
3378
|
-
return;
|
|
3054
|
+
if (prop in t) {
|
|
3055
|
+
return Reflect.get(t, prop, receiver);
|
|
3379
3056
|
}
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
this.assign(validKey, mergeValue, true);
|
|
3385
|
-
} else if (!current || override && validKey !== "id" && validKey !== "_id") {
|
|
3386
|
-
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);
|
|
3387
3061
|
}
|
|
3388
3062
|
}
|
|
3389
|
-
});
|
|
3390
|
-
return this;
|
|
3391
|
-
}
|
|
3392
|
-
clone(newId = false, avoidKeys = []) {
|
|
3393
|
-
const ctor = this.constructor;
|
|
3394
|
-
const instance = new ctor(
|
|
3395
|
-
this._gedcom,
|
|
3396
|
-
this._id,
|
|
3397
|
-
this._main,
|
|
3398
|
-
this._parent
|
|
3399
|
-
);
|
|
3400
|
-
if (newId && this._id) {
|
|
3401
|
-
instance.id = `IFT${this._id.replace(/[^0-9]/g, "")}`;
|
|
3402
3063
|
}
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
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;
|
|
3406
3095
|
}
|
|
3407
|
-
|
|
3408
|
-
|
|
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");
|
|
3409
3104
|
}
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
return gedcom.join("\n");
|
|
3105
|
+
if (!newId.endsWith("@")) {
|
|
3106
|
+
newId = `${newId}@`;
|
|
3413
3107
|
}
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
const value = prop.exportValue();
|
|
3428
|
-
gedcom.push(
|
|
3429
|
-
`${level} ${validKey}${value ? ` ${value}` : ""}`
|
|
3430
|
-
);
|
|
3431
|
-
gedcom.push(
|
|
3432
|
-
...prop.toGedcomLines(validKey, level + 1, options)
|
|
3433
|
-
);
|
|
3434
|
-
} else if (prop instanceof List) {
|
|
3435
|
-
gedcom.push(
|
|
3436
|
-
...prop.toGedcomLines(validKey, level, options)
|
|
3437
|
-
);
|
|
3438
|
-
}
|
|
3439
|
-
}
|
|
3440
|
-
});
|
|
3441
|
-
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
|
+
}
|
|
3442
3121
|
}
|
|
3443
|
-
|
|
3444
|
-
return
|
|
3122
|
+
get length() {
|
|
3123
|
+
return this.values().length;
|
|
3445
3124
|
}
|
|
3446
|
-
|
|
3447
|
-
return
|
|
3125
|
+
has(indi) {
|
|
3126
|
+
return !!this.item(
|
|
3127
|
+
typeof indi === "string" ? indi : indi?.id ?? ""
|
|
3128
|
+
);
|
|
3448
3129
|
}
|
|
3449
|
-
|
|
3450
|
-
const
|
|
3451
|
-
|
|
3452
|
-
|
|
3130
|
+
get(name) {
|
|
3131
|
+
const propList = new _List();
|
|
3132
|
+
this.entries().forEach(([key, item]) => {
|
|
3133
|
+
propList.item(key, item.get(name));
|
|
3453
3134
|
});
|
|
3135
|
+
return propList;
|
|
3454
3136
|
}
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
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);
|
|
3460
3143
|
}
|
|
3461
|
-
}
|
|
3462
|
-
return void 0;
|
|
3463
|
-
}
|
|
3464
|
-
sourStartsWith(prefix) {
|
|
3465
|
-
return this.getSourceHeads().some((head) => {
|
|
3466
|
-
const sour = get(head, "SOUR.value");
|
|
3467
|
-
return !!sour?.toLowerCase()?.startsWith(prefix);
|
|
3468
3144
|
});
|
|
3145
|
+
return propList;
|
|
3469
3146
|
}
|
|
3470
|
-
|
|
3471
|
-
return this.
|
|
3147
|
+
keys() {
|
|
3148
|
+
return Object.keys(this.items);
|
|
3472
3149
|
}
|
|
3473
|
-
|
|
3474
|
-
return this.
|
|
3150
|
+
values() {
|
|
3151
|
+
return Object.values(this.items);
|
|
3475
3152
|
}
|
|
3476
|
-
|
|
3477
|
-
return this.
|
|
3153
|
+
entries() {
|
|
3154
|
+
return Object.entries(this.items);
|
|
3478
3155
|
}
|
|
3479
|
-
|
|
3480
|
-
return this.sourStartsWith("ancestry");
|
|
3156
|
+
setLength(_type) {
|
|
3481
3157
|
}
|
|
3482
|
-
|
|
3483
|
-
return this.
|
|
3158
|
+
first() {
|
|
3159
|
+
return this.index(0);
|
|
3484
3160
|
}
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
* Returns the detected source type or undefined if unknown
|
|
3488
|
-
*/
|
|
3489
|
-
getSourceType() {
|
|
3490
|
-
if (this.isAncestry()) return "Ancestry";
|
|
3491
|
-
if (this.isMyHeritage()) return "MyHeritage";
|
|
3492
|
-
if (this.isFamilySearch()) return "FamilySearch";
|
|
3493
|
-
if (this.isGNO2GED()) return "GNO2GED";
|
|
3494
|
-
if (this.isGenoPro()) return "GenoPro";
|
|
3495
|
-
if (this.isAhnenblatt()) return "Ahnenblatt";
|
|
3496
|
-
if (this.isGeni()) return "Geni";
|
|
3497
|
-
return void 0;
|
|
3161
|
+
last() {
|
|
3162
|
+
return this.index(this.keys().length - 1);
|
|
3498
3163
|
}
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
});
|
|
3164
|
+
index(index) {
|
|
3165
|
+
const keys = this.keys();
|
|
3166
|
+
const key = keys[index];
|
|
3167
|
+
return key && this.items[key];
|
|
3504
3168
|
}
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
}
|
|
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);
|
|
3510
3175
|
}
|
|
3511
|
-
|
|
3512
|
-
|
|
3176
|
+
removeItem(name) {
|
|
3177
|
+
unset(this.items, name);
|
|
3178
|
+
this.setLength();
|
|
3513
3179
|
}
|
|
3514
|
-
|
|
3515
|
-
|
|
3180
|
+
exclude(excludedList) {
|
|
3181
|
+
excludedList.keys().forEach((itemId) => {
|
|
3182
|
+
delete this.items[itemId];
|
|
3183
|
+
});
|
|
3184
|
+
this.setLength();
|
|
3185
|
+
return this;
|
|
3516
3186
|
}
|
|
3517
|
-
|
|
3518
|
-
if (
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
if (id !== void 0) return id;
|
|
3525
|
-
}
|
|
3526
|
-
if (this?.isFamilySearch()) {
|
|
3527
|
-
const id = this.getFamilySearchTreeId();
|
|
3528
|
-
if (id !== void 0) return id;
|
|
3529
|
-
}
|
|
3530
|
-
if (this?.isGNO2GED()) {
|
|
3531
|
-
const id = this.getGNO2GEDTreeId();
|
|
3532
|
-
if (id !== void 0) return id;
|
|
3533
|
-
}
|
|
3534
|
-
if (this?.isAhnenblatt()) {
|
|
3535
|
-
const id = this.getAhnenblattTreeId();
|
|
3536
|
-
if (id !== void 0) return id;
|
|
3537
|
-
}
|
|
3538
|
-
if (this?.isGeni()) {
|
|
3539
|
-
const id = this.getGeniTreeId();
|
|
3540
|
-
if (id !== void 0) return id;
|
|
3541
|
-
}
|
|
3542
|
-
if (this?.isGenoPro()) {
|
|
3543
|
-
const id = this.getGenoProTreeId();
|
|
3544
|
-
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 ?? {});
|
|
3545
3194
|
}
|
|
3546
|
-
|
|
3195
|
+
this.setLength();
|
|
3196
|
+
return this;
|
|
3547
3197
|
}
|
|
3548
|
-
|
|
3549
|
-
|
|
3198
|
+
merge(mergedList) {
|
|
3199
|
+
this.concat(mergedList?.items);
|
|
3200
|
+
return this;
|
|
3550
3201
|
}
|
|
3551
|
-
|
|
3552
|
-
const
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
)
|
|
3202
|
+
intersection(mergedList) {
|
|
3203
|
+
const inter = intersectionBy(
|
|
3204
|
+
this.values(),
|
|
3205
|
+
mergedList?.values() ?? [],
|
|
3206
|
+
"id"
|
|
3207
|
+
);
|
|
3208
|
+
return new _List(inter);
|
|
3557
3209
|
}
|
|
3558
|
-
|
|
3559
|
-
const
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3210
|
+
difference(mergedList) {
|
|
3211
|
+
const inter = differenceBy(
|
|
3212
|
+
this.values(),
|
|
3213
|
+
mergedList?.values() ?? [],
|
|
3214
|
+
"id"
|
|
3215
|
+
);
|
|
3216
|
+
return new _List(inter);
|
|
3564
3217
|
}
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
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
|
+
}
|
|
3569
3234
|
}
|
|
3570
|
-
|
|
3571
|
-
return fileName || "FamilySearch Import";
|
|
3235
|
+
return this;
|
|
3572
3236
|
}
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
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");
|
|
3579
3247
|
}
|
|
3580
3248
|
}
|
|
3581
|
-
return
|
|
3582
|
-
}
|
|
3583
|
-
getAhnenblattTreeName() {
|
|
3584
|
-
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
3585
|
-
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
3249
|
+
return this;
|
|
3586
3250
|
}
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
if (idMatch) {
|
|
3592
|
-
return idMatch[1];
|
|
3593
|
-
}
|
|
3251
|
+
delete(item) {
|
|
3252
|
+
if (item.id && this.items[item.id]) {
|
|
3253
|
+
delete this.items[item.id];
|
|
3254
|
+
this.setLength("decrease");
|
|
3594
3255
|
}
|
|
3595
|
-
return
|
|
3256
|
+
return this;
|
|
3596
3257
|
}
|
|
3597
|
-
|
|
3598
|
-
const
|
|
3599
|
-
|
|
3258
|
+
copy(ClassName = _List) {
|
|
3259
|
+
const newList = new ClassName();
|
|
3260
|
+
Object.assign(newList.items, this.items);
|
|
3261
|
+
newList.setLength();
|
|
3262
|
+
return newList;
|
|
3600
3263
|
}
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
if (fileName) {
|
|
3604
|
-
const idMatch = fileName.match(/_(\d+)/);
|
|
3605
|
-
if (idMatch) {
|
|
3606
|
-
return idMatch[1];
|
|
3607
|
-
}
|
|
3608
|
-
}
|
|
3609
|
-
return void 0;
|
|
3264
|
+
except(item, ClassName = _List) {
|
|
3265
|
+
return this.copy(ClassName).delete(item);
|
|
3610
3266
|
}
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3267
|
+
forEach(iterate) {
|
|
3268
|
+
this.entries().forEach(([key, item], index) => {
|
|
3269
|
+
iterate(item, key, index);
|
|
3270
|
+
});
|
|
3614
3271
|
}
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
}
|
|
3620
|
-
return `gno_${this._gedcom?.refcount || "unknown"}`;
|
|
3272
|
+
map(iterate) {
|
|
3273
|
+
return this.entries().map(([key, item], index) => {
|
|
3274
|
+
return iterate(item, key, index);
|
|
3275
|
+
});
|
|
3621
3276
|
}
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
}
|
|
3627
|
-
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
3628
|
-
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);
|
|
3629
3281
|
}
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
3638
|
-
if (fileName) {
|
|
3639
|
-
const idMatch = fileName.match(/_(\d+)/);
|
|
3640
|
-
if (idMatch) {
|
|
3641
|
-
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;
|
|
3642
3289
|
}
|
|
3643
|
-
|
|
3644
|
-
|
|
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;
|
|
3645
3306
|
}
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
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;
|
|
3667
3336
|
}
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
if (this?.isMyHeritage()) {
|
|
3674
|
-
const name = this.getMyHeritageTreeName();
|
|
3675
|
-
if (name) return name;
|
|
3676
|
-
}
|
|
3677
|
-
if (this?.isFamilySearch()) {
|
|
3678
|
-
const name = this.getFamilySearchTreeName();
|
|
3679
|
-
if (name) return name;
|
|
3680
|
-
}
|
|
3681
|
-
if (this?.isGNO2GED()) {
|
|
3682
|
-
const name = this.getGNO2GEDTreeName();
|
|
3683
|
-
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);
|
|
3684
3342
|
}
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
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;
|
|
3688
3386
|
}
|
|
3689
|
-
|
|
3690
|
-
const
|
|
3691
|
-
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
|
+
}, {});
|
|
3692
3443
|
}
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3444
|
+
return groupped;
|
|
3445
|
+
}
|
|
3446
|
+
findIndex(item) {
|
|
3447
|
+
if (!item?.id) {
|
|
3448
|
+
return -1;
|
|
3696
3449
|
}
|
|
3697
|
-
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;
|
|
3698
3559
|
}
|
|
3560
|
+
return void 0;
|
|
3699
3561
|
};
|
|
3700
|
-
var
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
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"];
|
|
3713
3613
|
}
|
|
3714
3614
|
}
|
|
3615
|
+
return [];
|
|
3715
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
|
+
});
|
|
3716
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
|
+
};
|
|
3717
3649
|
};
|
|
3718
|
-
var
|
|
3719
|
-
|
|
3720
|
-
|
|
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"
|
|
3721
3659
|
);
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
const
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
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);
|
|
3733
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
|
+
};
|
|
3734
3749
|
};
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
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];
|
|
3740
3763
|
};
|
|
3741
|
-
var
|
|
3742
|
-
|
|
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;
|
|
3743
3772
|
};
|
|
3744
|
-
var
|
|
3745
|
-
if (
|
|
3746
|
-
return
|
|
3773
|
+
var inRange = (year, range, trueIfNoYear = false) => {
|
|
3774
|
+
if (!isValidRange(range)) {
|
|
3775
|
+
return false;
|
|
3747
3776
|
}
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
if (!parts?.at && !parts?.letter) {
|
|
3751
|
-
newId = `@U${newId}`;
|
|
3752
|
-
} else if (!parts.at) {
|
|
3753
|
-
newId = `@${newId}`;
|
|
3754
|
-
} else if (!parts.letter) {
|
|
3755
|
-
newId = newId.replace(/^@/, "@U");
|
|
3777
|
+
if (!year) {
|
|
3778
|
+
return trueIfNoYear;
|
|
3756
3779
|
}
|
|
3757
|
-
|
|
3758
|
-
|
|
3780
|
+
const [start = -Infinity, end = Infinity] = toTuple(range);
|
|
3781
|
+
if (!start && !end) {
|
|
3782
|
+
return true;
|
|
3759
3783
|
}
|
|
3760
|
-
|
|
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);
|
|
3761
3791
|
};
|
|
3762
3792
|
|
|
3763
3793
|
// src/classes/date.ts
|
|
@@ -3811,6 +3841,8 @@ var formatDateWithComponents = (date, hasDay, hasMonth, hasYear, noteValue, base
|
|
|
3811
3841
|
var CommonDate = class extends Common {
|
|
3812
3842
|
constructor(gedcom, id, main, parent) {
|
|
3813
3843
|
super(gedcom, id, main, parent);
|
|
3844
|
+
/** One DATE per event — merge must not turn this into a List. */
|
|
3845
|
+
this.isListable = false;
|
|
3814
3846
|
delete this.id;
|
|
3815
3847
|
}
|
|
3816
3848
|
get calendar() {
|