@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
package/dist/factories/index.js
CHANGED
|
@@ -104,244 +104,6 @@ var SPOUSE = {
|
|
|
104
104
|
PART: "spouse" /* SPOUSE */
|
|
105
105
|
};
|
|
106
106
|
|
|
107
|
-
// src/utils/get-all-prop.ts
|
|
108
|
-
var getAllProp = (indi, prop) => {
|
|
109
|
-
return prop && (indi?.get(prop)?.toList().values() ?? []).filter(Boolean) || [];
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
// src/utils/date-formatter.ts
|
|
113
|
-
var ACCEPTED_DATE_FORMATS = [
|
|
114
|
-
"yyyy.MM.dd.",
|
|
115
|
-
"yyyy-MM-dd",
|
|
116
|
-
"MM/dd/yyyy"
|
|
117
|
-
];
|
|
118
|
-
var ACCEPTED_DATE_FORMATS_REGEX = new RegExp(
|
|
119
|
-
`(${ACCEPTED_DATE_FORMATS.map(
|
|
120
|
-
(acceptedFormat) => acceptedFormat.replace(/[^.\-/]/g, "\\d")
|
|
121
|
-
).join("|")})`,
|
|
122
|
-
"gi"
|
|
123
|
-
);
|
|
124
|
-
var commonDateFormatter = (date, format2 = "yyyy", prefix = "") => {
|
|
125
|
-
const formattedDate = date?.toValue(format2);
|
|
126
|
-
if (!formattedDate) {
|
|
127
|
-
return void 0;
|
|
128
|
-
}
|
|
129
|
-
return `${prefix}${formattedDate}`.trim();
|
|
130
|
-
};
|
|
131
|
-
var noteDateFormatter = (date, format2 = "yyyy", prefix = "", shortNote = true, showNote = true) => {
|
|
132
|
-
const rawDate = commonDateFormatter(date, format2, "");
|
|
133
|
-
if (!rawDate) {
|
|
134
|
-
return void 0;
|
|
135
|
-
}
|
|
136
|
-
const note = date?.toNote(shortNote) ?? "";
|
|
137
|
-
return `${prefix}${note && showNote ? i18n.t(`${note} {{date}}`, { date: rawDate }) : rawDate}`;
|
|
138
|
-
};
|
|
139
|
-
var marriageDateFormatter = (fam, showDays = false, showPlaces = false, shortNote = true, showNote = true, showDisplayTextIfNoDate = true, showAllEvents = false, dateFormatPattern) => {
|
|
140
|
-
const fullDateFormat = i18n.t("dateFormat");
|
|
141
|
-
const marriageDates = [];
|
|
142
|
-
const marriagePlaces = [];
|
|
143
|
-
const marriages = (fam?.toValueList().values() ?? []).flatMap((fam2) => {
|
|
144
|
-
const family = fam2;
|
|
145
|
-
const marrEvents = (family?.MARR?.toList().values() ?? []).filter(
|
|
146
|
-
Boolean
|
|
147
|
-
);
|
|
148
|
-
if (marrEvents.length === 0) {
|
|
149
|
-
const displayText = family?.get("DISPLAYTEXT")?.toValue() ?? "";
|
|
150
|
-
if (showDisplayTextIfNoDate && displayText) {
|
|
151
|
-
const displayDate = displayText.match(
|
|
152
|
-
ACCEPTED_DATE_FORMATS_REGEX
|
|
153
|
-
)?.[0];
|
|
154
|
-
if (displayDate) {
|
|
155
|
-
marriagePlaces.push(displayText.replace(displayDate, ""));
|
|
156
|
-
const marriageDate = createCommonDate(
|
|
157
|
-
fam2?.getGedcom(),
|
|
158
|
-
void 0,
|
|
159
|
-
family
|
|
160
|
-
);
|
|
161
|
-
marriageDate.value = displayDate;
|
|
162
|
-
marriageDates.push(marriageDate);
|
|
163
|
-
} else {
|
|
164
|
-
marriagePlaces.push(displayText);
|
|
165
|
-
marriageDates.push(void 0);
|
|
166
|
-
return ["\u221E"];
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
return [];
|
|
170
|
-
}
|
|
171
|
-
const eventsToProcess = showAllEvents ? marrEvents : marrEvents.slice(0, 1);
|
|
172
|
-
return eventsToProcess.map((marrEvent) => {
|
|
173
|
-
const marriageEventDetail = marrEvent;
|
|
174
|
-
const marriageDate = marriageEventDetail?.DATE;
|
|
175
|
-
const marriagePlace = showPlaces ? marriageEventDetail?.PLAC?.value : void 0;
|
|
176
|
-
marriagePlaces.push(marriagePlace);
|
|
177
|
-
marriageDates.push(marriageDate);
|
|
178
|
-
const formattedDate = noteDateFormatter(
|
|
179
|
-
marriageDate,
|
|
180
|
-
showDays ? fullDateFormat : "yyyy",
|
|
181
|
-
"\u221E",
|
|
182
|
-
shortNote,
|
|
183
|
-
showNote
|
|
184
|
-
);
|
|
185
|
-
return formattedDate ? formattedDate : void 0;
|
|
186
|
-
});
|
|
187
|
-
});
|
|
188
|
-
const marriageArray = marriages.length ? marriages.filter(Boolean) : [];
|
|
189
|
-
const datesArray = marriageArray.filter(Boolean);
|
|
190
|
-
const placesArray = marriagePlaces.filter(Boolean);
|
|
191
|
-
const dates = datesArray.join(" ").trim();
|
|
192
|
-
return {
|
|
193
|
-
rawArray: marriageDates,
|
|
194
|
-
inArray: datesArray,
|
|
195
|
-
inOrder: dates,
|
|
196
|
-
places: placesArray,
|
|
197
|
-
marriage: marriageArray,
|
|
198
|
-
...showPlaces ? {
|
|
199
|
-
marriages,
|
|
200
|
-
marriagePlaces
|
|
201
|
-
} : {}
|
|
202
|
-
};
|
|
203
|
-
};
|
|
204
|
-
var dateFormatter = (indi, showMarriages = false, showDays = false, showPlaces = false, shortNote = true, showNote = true, isOnStage, showAllEvents = false, dateFormatPattern) => {
|
|
205
|
-
const fullDateFormat = i18n.t("dateFormat");
|
|
206
|
-
const birthEvents = getAllProp(indi, "BIRT");
|
|
207
|
-
const firstBirthValue = birthEvents[0];
|
|
208
|
-
const deathEvents = getAllProp(indi, "DEAT");
|
|
209
|
-
const firstDeathValue = deathEvents[0];
|
|
210
|
-
const birth = commonDateFormatter(
|
|
211
|
-
firstBirthValue?.DATE,
|
|
212
|
-
showDays ? fullDateFormat : "yyyy"
|
|
213
|
-
);
|
|
214
|
-
const birthPlace = showPlaces ? firstBirthValue?.PLAC?.value : void 0;
|
|
215
|
-
const death = commonDateFormatter(
|
|
216
|
-
firstDeathValue?.DATE,
|
|
217
|
-
showDays ? fullDateFormat : "yyyy"
|
|
218
|
-
);
|
|
219
|
-
const deathPlace = showPlaces ? firstDeathValue?.PLAC?.value : void 0;
|
|
220
|
-
const marriagePlaces = [];
|
|
221
|
-
const marriages = [];
|
|
222
|
-
if (showMarriages || isOnStage) {
|
|
223
|
-
(indi?.get("FAMS")?.toValueList().values() ?? []).forEach((fam) => {
|
|
224
|
-
const famRef = fam?.ref;
|
|
225
|
-
const marriageDates = marriageDateFormatter(
|
|
226
|
-
famRef,
|
|
227
|
-
showDays,
|
|
228
|
-
showPlaces,
|
|
229
|
-
shortNote,
|
|
230
|
-
showNote,
|
|
231
|
-
true,
|
|
232
|
-
showAllEvents);
|
|
233
|
-
marriages.push(...marriageDates?.marriage ?? []);
|
|
234
|
-
marriagePlaces.push(...marriageDates?.marriagePlaces ?? []);
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
const birthStrings = [];
|
|
238
|
-
const birthPlaces = [];
|
|
239
|
-
const eventsToProcess = showAllEvents ? birthEvents : birthEvents.slice(0, 1);
|
|
240
|
-
eventsToProcess.forEach((birthEvent) => {
|
|
241
|
-
const birthDate = commonDateFormatter(
|
|
242
|
-
birthEvent?.DATE,
|
|
243
|
-
showDays ? fullDateFormat : "yyyy"
|
|
244
|
-
);
|
|
245
|
-
const birthEventNote = birthEvent?.DATE?.toNote(shortNote) ?? "";
|
|
246
|
-
const birthEventPlace = showPlaces ? birthEvent?.PLAC?.value : void 0;
|
|
247
|
-
if (birthDate) {
|
|
248
|
-
birthStrings.push(
|
|
249
|
-
`*${birthEventNote && showNote ? i18n.t(`${birthEventNote} {{date}}`, {
|
|
250
|
-
date: birthDate
|
|
251
|
-
}) : birthDate}`
|
|
252
|
-
);
|
|
253
|
-
}
|
|
254
|
-
birthPlaces.push(birthEventPlace);
|
|
255
|
-
});
|
|
256
|
-
const deathStrings = [];
|
|
257
|
-
const deathPlaces = [];
|
|
258
|
-
const deathEventsToProcess = showAllEvents ? deathEvents : deathEvents.slice(0, 1);
|
|
259
|
-
deathEventsToProcess.forEach((deathEvent) => {
|
|
260
|
-
const deathDate = commonDateFormatter(
|
|
261
|
-
deathEvent?.DATE,
|
|
262
|
-
showDays ? fullDateFormat : "yyyy"
|
|
263
|
-
);
|
|
264
|
-
const deathEventNote = deathEvent?.DATE?.toNote(shortNote) ?? "";
|
|
265
|
-
const deathEventPlace = showPlaces ? deathEvent?.PLAC?.value : void 0;
|
|
266
|
-
if (deathDate) {
|
|
267
|
-
deathStrings.push(
|
|
268
|
-
`\u2020${deathEventNote && showNote ? i18n.t(`${deathEventNote} {{date}}`, {
|
|
269
|
-
date: deathDate
|
|
270
|
-
}) : deathDate}`
|
|
271
|
-
);
|
|
272
|
-
}
|
|
273
|
-
deathPlaces.push(deathEventPlace);
|
|
274
|
-
});
|
|
275
|
-
const birthString = birthStrings[0] ?? "";
|
|
276
|
-
const deathString = deathStrings[0] ?? "";
|
|
277
|
-
const marriageArray = marriages.length ? marriages.filter(Boolean) : [];
|
|
278
|
-
const datesArray = !birth && !death ? marriageArray : [...birthStrings, ...marriageArray, ...deathStrings];
|
|
279
|
-
const placesArray = !birth && !death ? marriagePlaces : [...birthPlaces, ...marriagePlaces, ...deathPlaces];
|
|
280
|
-
const nonNullDatesArray = datesArray.filter(Boolean);
|
|
281
|
-
const dates = nonNullDatesArray.join(" ").trim();
|
|
282
|
-
return {
|
|
283
|
-
inArray: nonNullDatesArray,
|
|
284
|
-
inOrder: dates,
|
|
285
|
-
places: placesArray,
|
|
286
|
-
birth: birthString,
|
|
287
|
-
marriage: marriageArray,
|
|
288
|
-
death: deathString,
|
|
289
|
-
...showPlaces ? {
|
|
290
|
-
birthPlace,
|
|
291
|
-
deathPlace,
|
|
292
|
-
...showMarriages ? { marriages, marriagePlaces } : {}
|
|
293
|
-
} : {},
|
|
294
|
-
...showAllEvents ? {
|
|
295
|
-
births: birthStrings,
|
|
296
|
-
birthPlaces,
|
|
297
|
-
deaths: deathStrings,
|
|
298
|
-
deathPlaces
|
|
299
|
-
} : {}
|
|
300
|
-
};
|
|
301
|
-
};
|
|
302
|
-
|
|
303
|
-
// src/utils/range.ts
|
|
304
|
-
var toTuple = (r) => {
|
|
305
|
-
if (Array.isArray(r)) {
|
|
306
|
-
const [s2, e2] = r;
|
|
307
|
-
return [
|
|
308
|
-
s2 === void 0 ? void 0 : Number(s2),
|
|
309
|
-
e2 === void 0 ? void 0 : Number(e2)
|
|
310
|
-
];
|
|
311
|
-
}
|
|
312
|
-
if (r === "-" || r === "") return [void 0, void 0];
|
|
313
|
-
const [s, e] = r.split("-");
|
|
314
|
-
return [s ? Number(s) : void 0, e ? Number(e) : void 0];
|
|
315
|
-
};
|
|
316
|
-
var isValidRange = (range) => {
|
|
317
|
-
if (!Array.isArray(range) && range !== "" && range !== "-" && !/^\d*-\d*$/.test(range)) {
|
|
318
|
-
return false;
|
|
319
|
-
}
|
|
320
|
-
if (Array.isArray(range) && range.some((r) => typeof r === "string" && isNaN(Number(r)))) {
|
|
321
|
-
return false;
|
|
322
|
-
}
|
|
323
|
-
return true;
|
|
324
|
-
};
|
|
325
|
-
var inRange = (year, range, trueIfNoYear = false) => {
|
|
326
|
-
if (!isValidRange(range)) {
|
|
327
|
-
return false;
|
|
328
|
-
}
|
|
329
|
-
if (!year) {
|
|
330
|
-
return trueIfNoYear;
|
|
331
|
-
}
|
|
332
|
-
const [start = -Infinity, end = Infinity] = toTuple(range);
|
|
333
|
-
if (!start && !end) {
|
|
334
|
-
return true;
|
|
335
|
-
}
|
|
336
|
-
if (start && !end) {
|
|
337
|
-
return Number(year) >= Number(start);
|
|
338
|
-
}
|
|
339
|
-
if (!start && end) {
|
|
340
|
-
return Number(year) <= Number(end);
|
|
341
|
-
}
|
|
342
|
-
return Number(start) <= Number(year) && Number(year) <= Number(end);
|
|
343
|
-
};
|
|
344
|
-
|
|
345
107
|
// src/constants/constants.ts
|
|
346
108
|
var ID_REG = /^@[_a-zA-Z0-9]+@/;
|
|
347
109
|
var ID_GETTER_REG = /^(?<at>@)?(?<letter>[A-Z])?/i;
|
|
@@ -426,1087 +188,1355 @@ var objeXrefKey = (obje, fallback = 0) => {
|
|
|
426
188
|
return `@O${fallback}@`;
|
|
427
189
|
};
|
|
428
190
|
var objeNoteValue = (obje) => mediaIdValue(obje, "FILE.NOTE") || mediaIdValue(obje, "NOTE") || "";
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
191
|
+
|
|
192
|
+
// src/classes/common.ts
|
|
193
|
+
var Common = class _Common {
|
|
194
|
+
constructor(gedcom, id, main, parent) {
|
|
433
195
|
this.isListable = true;
|
|
434
|
-
this.
|
|
435
|
-
|
|
436
|
-
|
|
196
|
+
this._gedcom = gedcom;
|
|
197
|
+
this._main = main;
|
|
198
|
+
this._parent = parent;
|
|
199
|
+
this.initUniqueId();
|
|
200
|
+
if (id) {
|
|
201
|
+
this._id = id;
|
|
202
|
+
} else {
|
|
203
|
+
delete this._id;
|
|
437
204
|
}
|
|
438
205
|
}
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
typeof indi === "string" ? indi : indi?.id ?? ""
|
|
445
|
-
);
|
|
206
|
+
set type(type) {
|
|
207
|
+
if (type) {
|
|
208
|
+
this.uniqueId = this.uniqueId?.replace(/^[^:]+/, `~${type}`);
|
|
209
|
+
}
|
|
210
|
+
this._type = type;
|
|
446
211
|
}
|
|
447
|
-
get(
|
|
448
|
-
|
|
449
|
-
this.entries().forEach(([key, item]) => {
|
|
450
|
-
propList.item(key, item.get(name));
|
|
451
|
-
});
|
|
452
|
-
return propList;
|
|
212
|
+
get type() {
|
|
213
|
+
return this._type;
|
|
453
214
|
}
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
215
|
+
initUniqueId() {
|
|
216
|
+
if (this._gedcom) {
|
|
217
|
+
this.uniqueId = `~Common:${this._gedcom.refcount++}`;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
set uniqueId(id) {
|
|
221
|
+
const currentId = this._uniqueId;
|
|
222
|
+
if (this._gedcom?.reflist && id) {
|
|
223
|
+
this._uniqueId = id;
|
|
224
|
+
if (currentId && this._gedcom.reflist[currentId]) {
|
|
225
|
+
delete this._gedcom.reflist[currentId];
|
|
460
226
|
}
|
|
461
|
-
|
|
462
|
-
|
|
227
|
+
this._gedcom.reflist[id] = this;
|
|
228
|
+
}
|
|
463
229
|
}
|
|
464
|
-
|
|
465
|
-
return
|
|
230
|
+
get uniqueId() {
|
|
231
|
+
return this._uniqueId;
|
|
466
232
|
}
|
|
467
|
-
|
|
468
|
-
|
|
233
|
+
set id(id) {
|
|
234
|
+
this._id = idGetter(id);
|
|
469
235
|
}
|
|
470
|
-
|
|
471
|
-
return
|
|
236
|
+
get id() {
|
|
237
|
+
return idGetter(this._id);
|
|
472
238
|
}
|
|
473
|
-
|
|
239
|
+
set value(value) {
|
|
240
|
+
this._value = value;
|
|
474
241
|
}
|
|
475
|
-
|
|
476
|
-
return this.
|
|
242
|
+
get value() {
|
|
243
|
+
return this._value;
|
|
477
244
|
}
|
|
478
|
-
|
|
479
|
-
|
|
245
|
+
/**
|
|
246
|
+
* Set the gedcom reference for this object
|
|
247
|
+
* @param gedcom - The GedComType to set as the gedcom reference
|
|
248
|
+
*/
|
|
249
|
+
setGedcom(gedcom) {
|
|
250
|
+
this._gedcom = gedcom;
|
|
480
251
|
}
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
return key && this.items[key];
|
|
252
|
+
// avoid to override
|
|
253
|
+
get originalValue() {
|
|
254
|
+
return this._value;
|
|
485
255
|
}
|
|
486
|
-
|
|
487
|
-
if (
|
|
488
|
-
|
|
489
|
-
|
|
256
|
+
get ref() {
|
|
257
|
+
if (typeof this.value === "string" && isId(this.value) && this.refType) {
|
|
258
|
+
return this._gedcom?.[getListTag(this.refType)]?.item(
|
|
259
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
260
|
+
this.value
|
|
261
|
+
);
|
|
490
262
|
}
|
|
491
|
-
return
|
|
263
|
+
return this;
|
|
492
264
|
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
this.setLength();
|
|
265
|
+
get main() {
|
|
266
|
+
return this._main;
|
|
496
267
|
}
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
delete this.items[itemId];
|
|
500
|
-
});
|
|
501
|
-
this.setLength();
|
|
502
|
-
return this;
|
|
268
|
+
get parent() {
|
|
269
|
+
return this._parent;
|
|
503
270
|
}
|
|
504
|
-
|
|
505
|
-
if (
|
|
506
|
-
|
|
507
|
-
this.
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
Object.assign(this.items, items ?? {});
|
|
271
|
+
addRef(refNode) {
|
|
272
|
+
if (typeof refNode.value === "string" && isId(refNode.value) && refNode.refType) {
|
|
273
|
+
if (!this._refs) {
|
|
274
|
+
this._refs = new List();
|
|
275
|
+
}
|
|
276
|
+
this._refs.item(refNode.value, refNode);
|
|
511
277
|
}
|
|
512
|
-
this.setLength();
|
|
513
|
-
return this;
|
|
514
278
|
}
|
|
515
|
-
|
|
516
|
-
this.
|
|
517
|
-
return this;
|
|
279
|
+
getRefs() {
|
|
280
|
+
return this._refs;
|
|
518
281
|
}
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
this.values(),
|
|
522
|
-
mergedList?.values() ?? [],
|
|
523
|
-
"id"
|
|
524
|
-
);
|
|
525
|
-
return new _List(inter);
|
|
282
|
+
exportValue() {
|
|
283
|
+
return this.value;
|
|
526
284
|
}
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
this.values(),
|
|
530
|
-
mergedList?.values() ?? [],
|
|
531
|
-
"id"
|
|
532
|
-
);
|
|
533
|
-
return new _List(inter);
|
|
285
|
+
removeValue() {
|
|
286
|
+
delete this._value;
|
|
534
287
|
}
|
|
535
|
-
|
|
536
|
-
if (
|
|
537
|
-
|
|
538
|
-
if (this.items[item.id]) {
|
|
539
|
-
delete this.items[item.id];
|
|
540
|
-
increase = false;
|
|
541
|
-
}
|
|
542
|
-
this.items = Object.assign(
|
|
543
|
-
{
|
|
544
|
-
[item.id]: item
|
|
545
|
-
},
|
|
546
|
-
this.items
|
|
547
|
-
);
|
|
548
|
-
if (increase) {
|
|
549
|
-
this.setLength("increase");
|
|
550
|
-
}
|
|
288
|
+
set(name, value) {
|
|
289
|
+
if (isGedcomTrailerTag(name)) {
|
|
290
|
+
return void 0;
|
|
551
291
|
}
|
|
552
|
-
|
|
292
|
+
if (typeof value === "string") {
|
|
293
|
+
const usedValue = createCommon(this._gedcom, void 0, this.main);
|
|
294
|
+
usedValue.value = value;
|
|
295
|
+
set(this, name, usedValue);
|
|
296
|
+
} else {
|
|
297
|
+
set(this, name, value);
|
|
298
|
+
}
|
|
299
|
+
return get(this, name);
|
|
553
300
|
}
|
|
554
|
-
|
|
555
|
-
if (
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
this.setLength("increase");
|
|
301
|
+
assign(name, value, unique = false) {
|
|
302
|
+
if (isGedcomTrailerTag(name)) {
|
|
303
|
+
return void 0;
|
|
304
|
+
}
|
|
305
|
+
let curValue = this.get(name);
|
|
306
|
+
if (curValue?.isListable) {
|
|
307
|
+
if (curValue instanceof _Common) {
|
|
308
|
+
curValue = new List().concat({ ...[curValue] });
|
|
309
|
+
this.set(name, curValue);
|
|
564
310
|
}
|
|
311
|
+
const values = [
|
|
312
|
+
...curValue.values(),
|
|
313
|
+
...value instanceof List ? value.values() : [value]
|
|
314
|
+
];
|
|
315
|
+
curValue.concat({
|
|
316
|
+
...!unique ? values : uniqBy(
|
|
317
|
+
values,
|
|
318
|
+
(value2) => value2 instanceof _Common ? value2?.value : void 0
|
|
319
|
+
)
|
|
320
|
+
});
|
|
321
|
+
} else {
|
|
322
|
+
this.set(name, value);
|
|
565
323
|
}
|
|
566
|
-
return this;
|
|
324
|
+
return get(this, name);
|
|
567
325
|
}
|
|
568
|
-
|
|
569
|
-
if (
|
|
570
|
-
|
|
571
|
-
this.setLength("decrease");
|
|
326
|
+
get(name) {
|
|
327
|
+
if (!name.includes(".")) {
|
|
328
|
+
return get(this, name);
|
|
572
329
|
}
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
330
|
+
const nameParts = name.split(".");
|
|
331
|
+
let last = this;
|
|
332
|
+
for (const part of nameParts) {
|
|
333
|
+
const indexPart = Number(part);
|
|
334
|
+
const itemIndex = part.match(/items\[(?<itemIndex>\d+)\]/)?.groups?.itemIndex;
|
|
335
|
+
const itemId = part.match(/items\[(?<itemId>@[A-Z]+\d+@)\]/)?.groups?.itemId;
|
|
336
|
+
const usedPart = itemId || itemIndex;
|
|
337
|
+
if (last instanceof List) {
|
|
338
|
+
if (!isNaN(indexPart)) {
|
|
339
|
+
last = last.index(indexPart);
|
|
340
|
+
} else {
|
|
341
|
+
if (usedPart) {
|
|
342
|
+
last = last.item(usedPart);
|
|
343
|
+
} else {
|
|
344
|
+
last = last?.index(0)?.get(part);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
} else {
|
|
348
|
+
const usedIndex = Number(itemIndex ?? indexPart);
|
|
349
|
+
if (!isNaN(usedIndex)) {
|
|
350
|
+
last = last?.toList().index(usedIndex);
|
|
351
|
+
} else {
|
|
352
|
+
last = last?.get(itemId ?? part);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
if (!last) {
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return last;
|
|
583
360
|
}
|
|
584
|
-
|
|
585
|
-
this
|
|
586
|
-
iterate(item, key, index);
|
|
587
|
-
});
|
|
361
|
+
remove(name) {
|
|
362
|
+
unset(this, name);
|
|
588
363
|
}
|
|
589
|
-
|
|
590
|
-
return this.
|
|
591
|
-
return iterate(item, key, index);
|
|
592
|
-
});
|
|
364
|
+
getGedcom() {
|
|
365
|
+
return this._gedcom;
|
|
593
366
|
}
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
367
|
+
getIf(name, condition, name2) {
|
|
368
|
+
const nameParts = name.split(".");
|
|
369
|
+
const name2Parts = name2.split(".");
|
|
370
|
+
if (nameParts.length !== name2Parts.length) {
|
|
371
|
+
throw new Error("Tag pathes must be of the same depth");
|
|
372
|
+
}
|
|
373
|
+
if (nameParts.length > 1 && nameParts[0] !== name2Parts[0]) {
|
|
374
|
+
throw new Error("Final tags must be siblings");
|
|
375
|
+
}
|
|
376
|
+
const valueCommon = this.get(name);
|
|
377
|
+
if (valueCommon instanceof _Common) {
|
|
378
|
+
return valueCommon?.toValue() !== condition ? void 0 : this.get(name2);
|
|
379
|
+
}
|
|
380
|
+
const valueCommon2 = this.get(name2)?.toList();
|
|
381
|
+
const ifList = new List();
|
|
382
|
+
valueCommon?.forEach((item, key) => {
|
|
383
|
+
const pair = valueCommon2?.item(key);
|
|
384
|
+
ifList.item(key, item?.toValue() !== condition ? void 0 : pair);
|
|
385
|
+
});
|
|
386
|
+
return ifList;
|
|
598
387
|
}
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
388
|
+
toString() {
|
|
389
|
+
return this.value?.toString() || "";
|
|
390
|
+
}
|
|
391
|
+
toValue() {
|
|
392
|
+
return this.value;
|
|
393
|
+
}
|
|
394
|
+
toProp(tag) {
|
|
395
|
+
const prop = this.get(tag);
|
|
396
|
+
return prop;
|
|
397
|
+
}
|
|
398
|
+
toList() {
|
|
399
|
+
return new List().concat(
|
|
400
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
401
|
+
this.id ? { [this.id]: this } : { ...[this] }
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
index(i) {
|
|
405
|
+
return this.toList()?.index(i);
|
|
406
|
+
}
|
|
407
|
+
toValueList() {
|
|
408
|
+
return new List().concat(
|
|
409
|
+
this.value ? { [this.value]: this } : (
|
|
410
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
411
|
+
{ ...[this] }
|
|
412
|
+
)
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
standardizeObject(tag, options) {
|
|
416
|
+
if (tag === "OBJE" && options?.obje?.standardize && "standardizeMedia" in this) {
|
|
417
|
+
const standardize = this.standardizeMedia;
|
|
418
|
+
return standardize.call(
|
|
419
|
+
this,
|
|
420
|
+
options.obje.namespace,
|
|
421
|
+
options.obje.override,
|
|
422
|
+
this.isAncestry() ? ancestryMediaFileUrl : void 0,
|
|
423
|
+
options.gedcomVersion
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
toJson(tag, options) {
|
|
428
|
+
const json = this.toObject(tag, options);
|
|
429
|
+
return JSON.stringify(json);
|
|
430
|
+
}
|
|
431
|
+
toObject(tag, options) {
|
|
432
|
+
this.standardizeObject(tag, options);
|
|
433
|
+
const validKeys = getValidKeys(this);
|
|
434
|
+
let json = {};
|
|
435
|
+
validKeys.forEach((key) => {
|
|
436
|
+
if (options?.persist && (key === "DAY" || key === "MONTH" || key === "YEAR")) {
|
|
605
437
|
return;
|
|
606
438
|
}
|
|
607
|
-
if (
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
439
|
+
if (key === "id" && this.id !== void 0) {
|
|
440
|
+
json.id = this.id;
|
|
441
|
+
} else if (key === "_id" && this._id !== void 0) {
|
|
442
|
+
json.id = this._id;
|
|
443
|
+
} else if (key === "value" && this.value !== void 0) {
|
|
444
|
+
json.value = this.value;
|
|
445
|
+
} else if (key === "_value" && this._value !== void 0) {
|
|
446
|
+
json.value = this._value;
|
|
447
|
+
} else {
|
|
448
|
+
const validKey = key;
|
|
449
|
+
const prop = this.get(validKey);
|
|
450
|
+
if (typeof prop?.toObject === "function") {
|
|
451
|
+
if (prop instanceof _Common) {
|
|
452
|
+
json[validKey] = prop.toObject(validKey, options);
|
|
453
|
+
} else if (prop instanceof List) {
|
|
454
|
+
json = {
|
|
455
|
+
...json,
|
|
456
|
+
...prop.toObject(validKey, options)
|
|
457
|
+
};
|
|
458
|
+
}
|
|
616
459
|
}
|
|
617
|
-
return itemValue === value;
|
|
618
|
-
})) {
|
|
619
|
-
newList.item(itemId, item);
|
|
620
460
|
}
|
|
621
461
|
});
|
|
622
|
-
return
|
|
462
|
+
return json;
|
|
623
463
|
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
}
|
|
633
|
-
return false;
|
|
464
|
+
merge(other, override = false, avoidKeys = []) {
|
|
465
|
+
if (!other) {
|
|
466
|
+
return this;
|
|
467
|
+
}
|
|
468
|
+
const validKeys = getValidKeys(other);
|
|
469
|
+
validKeys.forEach((validKey) => {
|
|
470
|
+
if (avoidKeys.includes(validKey)) {
|
|
471
|
+
return;
|
|
634
472
|
}
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
if (
|
|
643
|
-
|
|
473
|
+
const current = this.get(validKey);
|
|
474
|
+
const mergeValue = other.get(validKey);
|
|
475
|
+
if (mergeValue) {
|
|
476
|
+
if (current instanceof _Common && !current.isListable) {
|
|
477
|
+
if (override) {
|
|
478
|
+
this.set(validKey, mergeValue);
|
|
479
|
+
}
|
|
480
|
+
} else if (current instanceof _Common || current instanceof List) {
|
|
481
|
+
this.assign(validKey, mergeValue, true);
|
|
482
|
+
} else if (!current || override && validKey !== "id" && validKey !== "_id") {
|
|
483
|
+
this.set(validKey, mergeValue);
|
|
644
484
|
}
|
|
645
|
-
return itemValue === value;
|
|
646
|
-
})) {
|
|
647
|
-
foundItem = item;
|
|
648
|
-
return true;
|
|
649
485
|
}
|
|
650
|
-
return false;
|
|
651
486
|
});
|
|
652
|
-
return
|
|
487
|
+
return this;
|
|
653
488
|
}
|
|
654
|
-
|
|
655
|
-
const
|
|
656
|
-
const
|
|
657
|
-
|
|
658
|
-
|
|
489
|
+
clone(newId = false, avoidKeys = []) {
|
|
490
|
+
const ctor = this.constructor;
|
|
491
|
+
const instance = new ctor(
|
|
492
|
+
this._gedcom,
|
|
493
|
+
this._id,
|
|
494
|
+
this._main,
|
|
495
|
+
this._parent
|
|
496
|
+
);
|
|
497
|
+
if (newId && this._id) {
|
|
498
|
+
instance.id = `IFT${this._id.replace(/[^0-9]/g, "")}`;
|
|
659
499
|
}
|
|
660
|
-
const
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
500
|
+
const cloned = createProxy(instance);
|
|
501
|
+
cloned.merge(this, true, avoidKeys);
|
|
502
|
+
return cloned;
|
|
503
|
+
}
|
|
504
|
+
// fromGedcom<T = typeof this>(value: string) {
|
|
505
|
+
fromGedcom(_value) {
|
|
506
|
+
}
|
|
507
|
+
toGedcom(tag, level = 0, options) {
|
|
508
|
+
const gedcom = this.toGedcomLines(tag, level, options);
|
|
509
|
+
return gedcom.join("\n");
|
|
510
|
+
}
|
|
511
|
+
toGedcomLines(tag, level = 0, options) {
|
|
512
|
+
this.standardizeObject(tag, options);
|
|
513
|
+
const validKeys = getValidKeys(this);
|
|
514
|
+
const gedcom = [];
|
|
515
|
+
const isGedcom7Export = options?.gedcomVersion === "7.0";
|
|
516
|
+
validKeys.forEach((key) => {
|
|
517
|
+
const validKey = key;
|
|
518
|
+
if (isGedcom7Export && validKey === "CONC") {
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
const prop = this.get(validKey);
|
|
522
|
+
if (typeof prop?.toGedcomLines === "function") {
|
|
523
|
+
if (prop instanceof _Common) {
|
|
524
|
+
const value = prop.exportValue();
|
|
525
|
+
gedcom.push(
|
|
526
|
+
`${level} ${validKey}${value ? ` ${value}` : ""}`
|
|
527
|
+
);
|
|
528
|
+
gedcom.push(
|
|
529
|
+
...prop.toGedcomLines(validKey, level + 1, options)
|
|
530
|
+
);
|
|
531
|
+
} else if (prop instanceof List) {
|
|
532
|
+
gedcom.push(
|
|
533
|
+
...prop.toGedcomLines(validKey, level, options)
|
|
534
|
+
);
|
|
687
535
|
}
|
|
688
|
-
return sortValue * (direction === "DESC" ? -1 : 1);
|
|
689
536
|
}
|
|
690
|
-
);
|
|
691
|
-
sortedItems.forEach(([key, value]) => {
|
|
692
|
-
newList.item(key, value);
|
|
693
537
|
});
|
|
694
|
-
return
|
|
538
|
+
return gedcom;
|
|
695
539
|
}
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
const isIterator = typeof groups === "function";
|
|
699
|
-
if (!isIterator && (!groups || !Object.keys(groups).length)) {
|
|
700
|
-
groupped.Unknown = new ClassName().merge(this);
|
|
701
|
-
groupped.Unknown.marker = "Unknown";
|
|
702
|
-
return groupped;
|
|
703
|
-
}
|
|
704
|
-
this.forEach((item, itemId) => {
|
|
705
|
-
const group = [];
|
|
706
|
-
if (isIterator) {
|
|
707
|
-
const newGroups = groups(item, itemId);
|
|
708
|
-
group.push(
|
|
709
|
-
...Array.isArray(newGroups) ? newGroups : [newGroups]
|
|
710
|
-
);
|
|
711
|
-
} else {
|
|
712
|
-
const [key, { getter }] = Object.entries(
|
|
713
|
-
typeof groups === "string" ? { [groups]: {} } : groups
|
|
714
|
-
)[0];
|
|
715
|
-
const raw = item.get(key)?.index(0);
|
|
716
|
-
let value = raw?.toValue();
|
|
717
|
-
if (getter && typeof getter === "function") {
|
|
718
|
-
value = getter(value, raw);
|
|
719
|
-
}
|
|
720
|
-
if (value) {
|
|
721
|
-
group.push(value);
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
if (!group.length) {
|
|
725
|
-
group.push("Unknown");
|
|
726
|
-
}
|
|
727
|
-
group.forEach((g) => {
|
|
728
|
-
const newGroup = typeof g === "string" ? { group: g } : g;
|
|
729
|
-
if (!groupped[newGroup.group]) {
|
|
730
|
-
groupped[newGroup.group] = new ClassName();
|
|
731
|
-
groupped[newGroup.group].marker = newGroup.marker ?? newGroup.group;
|
|
732
|
-
}
|
|
733
|
-
groupped[newGroup.group]?.append(item);
|
|
734
|
-
});
|
|
735
|
-
});
|
|
736
|
-
if (sort) {
|
|
737
|
-
return Object.entries(groupped).toSorted(([ak, a], [bk, b]) => {
|
|
738
|
-
if (typeof sort === "function") {
|
|
739
|
-
return sort(a, ak, b, bk);
|
|
740
|
-
}
|
|
741
|
-
if (ak === "Unknown") {
|
|
742
|
-
return 1;
|
|
743
|
-
}
|
|
744
|
-
if (bk === "Unknown") {
|
|
745
|
-
return -1;
|
|
746
|
-
}
|
|
747
|
-
if (sort === "group") {
|
|
748
|
-
return ak.localeCompare(bk);
|
|
749
|
-
}
|
|
750
|
-
return (b?.length ?? 0) - (a?.length ?? 0);
|
|
751
|
-
}).reduce((acc, [key, value]) => {
|
|
752
|
-
if (minOccurance > -1 && (value?.length ?? 0) < minOccurance) {
|
|
753
|
-
const otherKey = lessOccuranceLabel;
|
|
754
|
-
acc[otherKey] = acc[otherKey] && value ? acc[otherKey].merge(value) : value;
|
|
755
|
-
} else {
|
|
756
|
-
acc[key] = value;
|
|
757
|
-
}
|
|
758
|
-
return acc;
|
|
759
|
-
}, {});
|
|
760
|
-
}
|
|
761
|
-
return groupped;
|
|
762
|
-
}
|
|
763
|
-
findIndex(item) {
|
|
764
|
-
if (!item?.id) {
|
|
765
|
-
return -1;
|
|
766
|
-
}
|
|
767
|
-
return this.keys().findIndex((key) => key === item.id);
|
|
540
|
+
getHeadRecord() {
|
|
541
|
+
return get(this, "HEAD") || get(this.getGedcom(), "HEAD");
|
|
768
542
|
}
|
|
769
|
-
|
|
770
|
-
return this.
|
|
543
|
+
getOriginalHeadRecord() {
|
|
544
|
+
return get(this, ORIG_HEAD_TAG) || get(this.getGedcom(), ORIG_HEAD_TAG) || get(this.getHeadRecord(), ORIG_HEAD_TAG);
|
|
771
545
|
}
|
|
772
|
-
|
|
773
|
-
const
|
|
774
|
-
return
|
|
546
|
+
getSourceHeads() {
|
|
547
|
+
const heads = [this.getOriginalHeadRecord(), this.getHeadRecord()];
|
|
548
|
+
return heads.filter((head, index) => {
|
|
549
|
+
return Boolean(head && heads.indexOf(head) === index);
|
|
550
|
+
});
|
|
775
551
|
}
|
|
776
|
-
|
|
777
|
-
const
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
if (!Array.isArray(json[validTag])) {
|
|
782
|
-
json[validTag] = [json[validTag]];
|
|
783
|
-
}
|
|
784
|
-
json[validTag].push(
|
|
785
|
-
item.toObject(validTag, options)
|
|
786
|
-
);
|
|
787
|
-
} else {
|
|
788
|
-
json[validTag] = item.toObject(
|
|
789
|
-
validTag,
|
|
790
|
-
options
|
|
791
|
-
);
|
|
552
|
+
getFromSourceHeads(path) {
|
|
553
|
+
for (const head of this.getSourceHeads()) {
|
|
554
|
+
const value = get(head, path);
|
|
555
|
+
if (value !== void 0 && value !== null && value !== "") {
|
|
556
|
+
return value;
|
|
792
557
|
}
|
|
558
|
+
}
|
|
559
|
+
return void 0;
|
|
560
|
+
}
|
|
561
|
+
sourStartsWith(prefix) {
|
|
562
|
+
return this.getSourceHeads().some((head) => {
|
|
563
|
+
const sour = get(head, "SOUR.value");
|
|
564
|
+
return !!sour?.toLowerCase()?.startsWith(prefix);
|
|
793
565
|
});
|
|
794
|
-
return json;
|
|
795
566
|
}
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
return gedcom.join("\n");
|
|
567
|
+
isGenoPro() {
|
|
568
|
+
return this.sourStartsWith("genopro");
|
|
799
569
|
}
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
this.entries().forEach(([_, item]) => {
|
|
803
|
-
const validTag = getValidTag(tag);
|
|
804
|
-
const xref = item.id;
|
|
805
|
-
const payload = item.exportValue?.();
|
|
806
|
-
if (xref) {
|
|
807
|
-
gedcom.push(
|
|
808
|
-
`${level} ${xref} ${validTag}${payload ? ` ${payload}` : ""}`
|
|
809
|
-
);
|
|
810
|
-
} else {
|
|
811
|
-
gedcom.push(
|
|
812
|
-
`${level} ${validTag}${payload ? ` ${payload}` : ""}`
|
|
813
|
-
);
|
|
814
|
-
}
|
|
815
|
-
gedcom.push(
|
|
816
|
-
...item.toGedcomLines(
|
|
817
|
-
validTag,
|
|
818
|
-
level + 1,
|
|
819
|
-
options
|
|
820
|
-
)
|
|
821
|
-
);
|
|
822
|
-
});
|
|
823
|
-
return gedcom;
|
|
570
|
+
isAhnenblatt() {
|
|
571
|
+
return this.sourStartsWith("ahnenblatt");
|
|
824
572
|
}
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
this.entries().forEach(([key, item]) => {
|
|
828
|
-
propList.item(key, item?.toValue());
|
|
829
|
-
});
|
|
830
|
-
return propList;
|
|
573
|
+
isGeni() {
|
|
574
|
+
return this.sourStartsWith("geni");
|
|
831
575
|
}
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
return this.get(tag);
|
|
576
|
+
isAncestry() {
|
|
577
|
+
return this.sourStartsWith("ancestry");
|
|
835
578
|
}
|
|
836
|
-
|
|
837
|
-
return
|
|
579
|
+
isMyHeritage() {
|
|
580
|
+
return this.sourStartsWith("myheritage");
|
|
838
581
|
}
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
582
|
+
/**
|
|
583
|
+
* Get the source type as a string (for prefixing tree IDs and names)
|
|
584
|
+
* Returns the detected source type or undefined if unknown
|
|
585
|
+
*/
|
|
586
|
+
getSourceType() {
|
|
587
|
+
if (this.isAncestry()) return "Ancestry";
|
|
588
|
+
if (this.isMyHeritage()) return "MyHeritage";
|
|
589
|
+
if (this.isFamilySearch()) return "FamilySearch";
|
|
590
|
+
if (this.isGNO2GED()) return "GNO2GED";
|
|
591
|
+
if (this.isGenoPro()) return "GenoPro";
|
|
592
|
+
if (this.isAhnenblatt()) return "Ahnenblatt";
|
|
593
|
+
if (this.isGeni()) return "Geni";
|
|
594
|
+
return void 0;
|
|
595
|
+
}
|
|
596
|
+
isFamilySearch() {
|
|
597
|
+
return this.getSourceHeads().some((head) => {
|
|
598
|
+
const sourName = get(head, "SOUR.NAME.value");
|
|
599
|
+
return sourName === "FamilySearch API";
|
|
843
600
|
});
|
|
844
|
-
return newList;
|
|
845
601
|
}
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
this.isListable = true;
|
|
852
|
-
this._gedcom = gedcom;
|
|
853
|
-
this._main = main;
|
|
854
|
-
this._parent = parent;
|
|
855
|
-
this.initUniqueId();
|
|
856
|
-
if (id) {
|
|
857
|
-
this._id = id;
|
|
858
|
-
} else {
|
|
859
|
-
delete this._id;
|
|
860
|
-
}
|
|
602
|
+
isGNO2GED() {
|
|
603
|
+
return this.getSourceHeads().some((head) => {
|
|
604
|
+
const sour = get(head, "SOUR.value");
|
|
605
|
+
return sour === "GNO2GED";
|
|
606
|
+
});
|
|
861
607
|
}
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
this.uniqueId = this.uniqueId?.replace(/^[^:]+/, `~${type}`);
|
|
865
|
-
}
|
|
866
|
-
this._type = type;
|
|
608
|
+
getAncestryTreeId() {
|
|
609
|
+
return this.getFromSourceHeads("SOUR._TREE.RIN.value") || (get(this, "HEAD.SOUR._TREE.RIN.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.RIN.value"));
|
|
867
610
|
}
|
|
868
|
-
|
|
869
|
-
return this.
|
|
611
|
+
getMyHeritageTreeId() {
|
|
612
|
+
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"));
|
|
870
613
|
}
|
|
871
|
-
|
|
872
|
-
if (this
|
|
873
|
-
|
|
614
|
+
getTreeId() {
|
|
615
|
+
if (this?.isAncestry()) {
|
|
616
|
+
const id = this.getAncestryTreeId();
|
|
617
|
+
if (id !== void 0) return id;
|
|
874
618
|
}
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
619
|
+
if (this?.isMyHeritage()) {
|
|
620
|
+
const id = this.getMyHeritageTreeId();
|
|
621
|
+
if (id !== void 0) return id;
|
|
622
|
+
}
|
|
623
|
+
if (this?.isFamilySearch()) {
|
|
624
|
+
const id = this.getFamilySearchTreeId();
|
|
625
|
+
if (id !== void 0) return id;
|
|
626
|
+
}
|
|
627
|
+
if (this?.isGNO2GED()) {
|
|
628
|
+
const id = this.getGNO2GEDTreeId();
|
|
629
|
+
if (id !== void 0) return id;
|
|
630
|
+
}
|
|
631
|
+
if (this?.isAhnenblatt()) {
|
|
632
|
+
const id = this.getAhnenblattTreeId();
|
|
633
|
+
if (id !== void 0) return id;
|
|
634
|
+
}
|
|
635
|
+
if (this?.isGeni()) {
|
|
636
|
+
const id = this.getGeniTreeId();
|
|
637
|
+
if (id !== void 0) return id;
|
|
638
|
+
}
|
|
639
|
+
if (this?.isGenoPro()) {
|
|
640
|
+
const id = this.getGenoProTreeId();
|
|
641
|
+
if (id !== void 0) return id;
|
|
884
642
|
}
|
|
643
|
+
return this.getUniversalTreeId();
|
|
885
644
|
}
|
|
886
|
-
|
|
887
|
-
return this.
|
|
645
|
+
getAncestryTreeName() {
|
|
646
|
+
return this.getFromSourceHeads("SOUR._TREE.value") || (get(this, "HEAD.SOUR._TREE.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.value"));
|
|
888
647
|
}
|
|
889
|
-
|
|
890
|
-
|
|
648
|
+
getMyHeritageTreeName() {
|
|
649
|
+
const path = "HEAD.FILE.value";
|
|
650
|
+
const treeDetails = get(this, path) || get(this.getGedcom(), path);
|
|
651
|
+
return treeDetails?.match(
|
|
652
|
+
/Exported by MyHeritage.com from (?<tree>.+) in.+$/
|
|
653
|
+
)?.groups?.tree;
|
|
891
654
|
}
|
|
892
|
-
|
|
893
|
-
|
|
655
|
+
getFamilySearchTreeId() {
|
|
656
|
+
const rin = this.getFromSourceHeads("SOUR._TREE.RIN.value") || get(this, "HEAD.SOUR._TREE.RIN.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.RIN.value");
|
|
657
|
+
if (rin) {
|
|
658
|
+
return rin;
|
|
659
|
+
}
|
|
660
|
+
return "familysearch";
|
|
894
661
|
}
|
|
895
|
-
|
|
896
|
-
this.
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
return this._value;
|
|
900
|
-
}
|
|
901
|
-
/**
|
|
902
|
-
* Set the gedcom reference for this object
|
|
903
|
-
* @param gedcom - The GedComType to set as the gedcom reference
|
|
904
|
-
*/
|
|
905
|
-
setGedcom(gedcom) {
|
|
906
|
-
this._gedcom = gedcom;
|
|
907
|
-
}
|
|
908
|
-
// avoid to override
|
|
909
|
-
get originalValue() {
|
|
910
|
-
return this._value;
|
|
911
|
-
}
|
|
912
|
-
get ref() {
|
|
913
|
-
if (typeof this.value === "string" && isId(this.value) && this.refType) {
|
|
914
|
-
return this._gedcom?.[getListTag(this.refType)]?.item(
|
|
915
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
916
|
-
this.value
|
|
917
|
-
);
|
|
662
|
+
getFamilySearchTreeName() {
|
|
663
|
+
const treeName = this.getFromSourceHeads("SOUR._TREE.value") || get(this, "HEAD.SOUR._TREE.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.value");
|
|
664
|
+
if (treeName) {
|
|
665
|
+
return treeName;
|
|
918
666
|
}
|
|
919
|
-
|
|
667
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
668
|
+
return fileName || "FamilySearch Import";
|
|
920
669
|
}
|
|
921
|
-
|
|
922
|
-
|
|
670
|
+
getAhnenblattTreeId() {
|
|
671
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
672
|
+
if (fileName) {
|
|
673
|
+
const idMatch = fileName.match(/_(\d+)/);
|
|
674
|
+
if (idMatch) {
|
|
675
|
+
return idMatch[1];
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
return void 0;
|
|
923
679
|
}
|
|
924
|
-
|
|
925
|
-
|
|
680
|
+
getAhnenblattTreeName() {
|
|
681
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
682
|
+
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
926
683
|
}
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
684
|
+
getGeniTreeId() {
|
|
685
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
686
|
+
if (fileName) {
|
|
687
|
+
const idMatch = fileName.match(/_(\d+)/);
|
|
688
|
+
if (idMatch) {
|
|
689
|
+
return idMatch[1];
|
|
931
690
|
}
|
|
932
|
-
this._refs.item(refNode.value, refNode);
|
|
933
691
|
}
|
|
692
|
+
return void 0;
|
|
934
693
|
}
|
|
935
|
-
|
|
936
|
-
|
|
694
|
+
getGeniTreeName() {
|
|
695
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
696
|
+
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
937
697
|
}
|
|
938
|
-
|
|
939
|
-
|
|
698
|
+
getGenoProTreeId() {
|
|
699
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
700
|
+
if (fileName) {
|
|
701
|
+
const idMatch = fileName.match(/_(\d+)/);
|
|
702
|
+
if (idMatch) {
|
|
703
|
+
return idMatch[1];
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
return void 0;
|
|
940
707
|
}
|
|
941
|
-
|
|
942
|
-
|
|
708
|
+
getGenoProTreeName() {
|
|
709
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
710
|
+
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
943
711
|
}
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
if (typeof value === "string") {
|
|
949
|
-
const usedValue = createCommon(this._gedcom, void 0, this.main);
|
|
950
|
-
usedValue.value = value;
|
|
951
|
-
set(this, name, usedValue);
|
|
952
|
-
} else {
|
|
953
|
-
set(this, name, value);
|
|
712
|
+
getGNO2GEDTreeId() {
|
|
713
|
+
const rin = get(this, "HEAD._TREE.RIN.value") || get(this.getGedcom(), "HEAD._TREE.RIN.value");
|
|
714
|
+
if (rin) {
|
|
715
|
+
return rin;
|
|
954
716
|
}
|
|
955
|
-
return
|
|
717
|
+
return `gno_${this._gedcom?.refcount || "unknown"}`;
|
|
956
718
|
}
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
719
|
+
getGNO2GEDTreeName() {
|
|
720
|
+
const treeName = get(this, "HEAD._TREE.value") || get(this.getGedcom(), "HEAD._TREE.value");
|
|
721
|
+
if (treeName) {
|
|
722
|
+
return treeName;
|
|
960
723
|
}
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
724
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
725
|
+
return fileName || "GNO2GED Export";
|
|
726
|
+
}
|
|
727
|
+
/**
|
|
728
|
+
* Universal tree ID getter for unknown/unrecognized GEDCOM sources
|
|
729
|
+
* Tries to extract an ID from various common locations
|
|
730
|
+
*/
|
|
731
|
+
getUniversalTreeId() {
|
|
732
|
+
const sourceType = this.getSourceType();
|
|
733
|
+
const prefix = sourceType ? sourceType.toLowerCase() : "tree";
|
|
734
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
735
|
+
if (fileName) {
|
|
736
|
+
const idMatch = fileName.match(/_(\d+)/);
|
|
737
|
+
if (idMatch) {
|
|
738
|
+
return `${prefix}_${idMatch[1]}`;
|
|
966
739
|
}
|
|
967
|
-
const values = [
|
|
968
|
-
...curValue.values(),
|
|
969
|
-
...value instanceof List ? value.values() : [value]
|
|
970
|
-
];
|
|
971
|
-
curValue.concat({
|
|
972
|
-
...!unique ? values : uniqBy(
|
|
973
|
-
values,
|
|
974
|
-
(value2) => value2 instanceof _Common ? value2?.value : void 0
|
|
975
|
-
)
|
|
976
|
-
});
|
|
977
|
-
} else {
|
|
978
|
-
this.set(name, value);
|
|
979
740
|
}
|
|
980
|
-
return
|
|
741
|
+
return `${prefix}_${this._gedcom?.refcount || "unknown"}`;
|
|
981
742
|
}
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
743
|
+
/**
|
|
744
|
+
* Universal tree name getter for unknown/unrecognized GEDCOM sources
|
|
745
|
+
* Tries to extract a name from various common locations
|
|
746
|
+
*/
|
|
747
|
+
getUniversalTreeName() {
|
|
748
|
+
const sourceType = this.getSourceType();
|
|
749
|
+
const prefix = sourceType ? `${sourceType}-` : "";
|
|
750
|
+
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
751
|
+
if (fileName) {
|
|
752
|
+
const cleanName = fileName.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
753
|
+
return `${prefix}${cleanName}`;
|
|
985
754
|
}
|
|
986
|
-
const
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
const indexPart = Number(part);
|
|
990
|
-
const itemIndex = part.match(/items\[(?<itemIndex>\d+)\]/)?.groups?.itemIndex;
|
|
991
|
-
const itemId = part.match(/items\[(?<itemId>@[A-Z]+\d+@)\]/)?.groups?.itemId;
|
|
992
|
-
const usedPart = itemId || itemIndex;
|
|
993
|
-
if (last instanceof List) {
|
|
994
|
-
if (!isNaN(indexPart)) {
|
|
995
|
-
last = last.index(indexPart);
|
|
996
|
-
} else {
|
|
997
|
-
if (usedPart) {
|
|
998
|
-
last = last.item(usedPart);
|
|
999
|
-
} else {
|
|
1000
|
-
last = last?.index(0)?.get(part);
|
|
1001
|
-
}
|
|
1002
|
-
}
|
|
1003
|
-
} else {
|
|
1004
|
-
const usedIndex = Number(itemIndex ?? indexPart);
|
|
1005
|
-
if (!isNaN(usedIndex)) {
|
|
1006
|
-
last = last?.toList().index(usedIndex);
|
|
1007
|
-
} else {
|
|
1008
|
-
last = last?.get(itemId ?? part);
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
if (!last) {
|
|
1012
|
-
break;
|
|
1013
|
-
}
|
|
755
|
+
const sourName = this.getFromSourceHeads("SOUR.NAME.value") || get(this, "HEAD.SOUR.NAME.value") || get(this.getGedcom(), "HEAD.SOUR.NAME.value");
|
|
756
|
+
if (sourName) {
|
|
757
|
+
return `${prefix}${sourName}`;
|
|
1014
758
|
}
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
getGedcom() {
|
|
1021
|
-
return this._gedcom;
|
|
759
|
+
const sourValue = this.getFromSourceHeads("SOUR.value") || get(this, "HEAD.SOUR.value") || get(this.getGedcom(), "HEAD.SOUR.value");
|
|
760
|
+
if (sourValue) {
|
|
761
|
+
return `${prefix}${sourValue}`;
|
|
762
|
+
}
|
|
763
|
+
return `${prefix}Unknown Tree`;
|
|
1022
764
|
}
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
throw new Error("Tag pathes must be of the same depth");
|
|
765
|
+
getTreeName() {
|
|
766
|
+
if (this?.isAncestry()) {
|
|
767
|
+
const name = this.getAncestryTreeName();
|
|
768
|
+
if (name) return name;
|
|
1028
769
|
}
|
|
1029
|
-
if (
|
|
1030
|
-
|
|
770
|
+
if (this?.isMyHeritage()) {
|
|
771
|
+
const name = this.getMyHeritageTreeName();
|
|
772
|
+
if (name) return name;
|
|
1031
773
|
}
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
774
|
+
if (this?.isFamilySearch()) {
|
|
775
|
+
const name = this.getFamilySearchTreeName();
|
|
776
|
+
if (name) return name;
|
|
1035
777
|
}
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
return
|
|
1053
|
-
}
|
|
1054
|
-
toList() {
|
|
1055
|
-
return new List().concat(
|
|
1056
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1057
|
-
this.id ? { [this.id]: this } : { ...[this] }
|
|
1058
|
-
);
|
|
1059
|
-
}
|
|
1060
|
-
index(i) {
|
|
1061
|
-
return this.toList()?.index(i);
|
|
778
|
+
if (this?.isGNO2GED()) {
|
|
779
|
+
const name = this.getGNO2GEDTreeName();
|
|
780
|
+
if (name) return name;
|
|
781
|
+
}
|
|
782
|
+
if (this?.isAhnenblatt()) {
|
|
783
|
+
const name = this.getAhnenblattTreeName();
|
|
784
|
+
if (name) return name;
|
|
785
|
+
}
|
|
786
|
+
if (this?.isGeni()) {
|
|
787
|
+
const name = this.getGeniTreeName();
|
|
788
|
+
if (name) return name;
|
|
789
|
+
}
|
|
790
|
+
if (this?.isGenoPro()) {
|
|
791
|
+
const name = this.getGenoProTreeName();
|
|
792
|
+
if (name) return name;
|
|
793
|
+
}
|
|
794
|
+
return this.getUniversalTreeName();
|
|
1062
795
|
}
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
);
|
|
1070
|
-
}
|
|
1071
|
-
standardizeObject(tag, options) {
|
|
1072
|
-
if (tag === "OBJE" && options?.obje?.standardize && "standardizeMedia" in this) {
|
|
1073
|
-
const standardize = this.standardizeMedia;
|
|
1074
|
-
return standardize.call(
|
|
1075
|
-
this,
|
|
1076
|
-
options.obje.namespace,
|
|
1077
|
-
options.obje.override,
|
|
1078
|
-
this.isAncestry() ? ancestryMediaFileUrl : void 0,
|
|
1079
|
-
options.gedcomVersion
|
|
1080
|
-
);
|
|
1081
|
-
}
|
|
1082
|
-
}
|
|
1083
|
-
toJson(tag, options) {
|
|
1084
|
-
const json = this.toObject(tag, options);
|
|
1085
|
-
return JSON.stringify(json);
|
|
1086
|
-
}
|
|
1087
|
-
toObject(tag, options) {
|
|
1088
|
-
this.standardizeObject(tag, options);
|
|
1089
|
-
const validKeys = getValidKeys(this);
|
|
1090
|
-
let json = {};
|
|
1091
|
-
validKeys.forEach((key) => {
|
|
1092
|
-
if (options?.persist && (key === "DAY" || key === "MONTH" || key === "YEAR")) {
|
|
1093
|
-
return;
|
|
1094
|
-
}
|
|
1095
|
-
if (key === "id" && this.id !== void 0) {
|
|
1096
|
-
json.id = this.id;
|
|
1097
|
-
} else if (key === "_id" && this._id !== void 0) {
|
|
1098
|
-
json.id = this._id;
|
|
1099
|
-
} else if (key === "value" && this.value !== void 0) {
|
|
1100
|
-
json.value = this.value;
|
|
1101
|
-
} else if (key === "_value" && this._value !== void 0) {
|
|
1102
|
-
json.value = this._value;
|
|
1103
|
-
} else {
|
|
1104
|
-
const validKey = key;
|
|
1105
|
-
const prop = this.get(validKey);
|
|
1106
|
-
if (typeof prop?.toObject === "function") {
|
|
1107
|
-
if (prop instanceof _Common) {
|
|
1108
|
-
json[validKey] = prop.toObject(validKey, options);
|
|
1109
|
-
} else if (prop instanceof List) {
|
|
1110
|
-
json = {
|
|
1111
|
-
...json,
|
|
1112
|
-
...prop.toObject(validKey, options)
|
|
1113
|
-
};
|
|
1114
|
-
}
|
|
1115
|
-
}
|
|
796
|
+
};
|
|
797
|
+
var createProxy = (target) => {
|
|
798
|
+
return new Proxy(target, {
|
|
799
|
+
get(t, prop, receiver) {
|
|
800
|
+
if (prop === "unwrapped") {
|
|
801
|
+
return target;
|
|
1116
802
|
}
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
}
|
|
1120
|
-
merge(other, override = false, avoidKeys = []) {
|
|
1121
|
-
if (!other) {
|
|
1122
|
-
return this;
|
|
1123
|
-
}
|
|
1124
|
-
const validKeys = getValidKeys(other);
|
|
1125
|
-
validKeys.forEach((validKey) => {
|
|
1126
|
-
if (avoidKeys.includes(validKey)) {
|
|
1127
|
-
return;
|
|
803
|
+
if (prop in t) {
|
|
804
|
+
return Reflect.get(t, prop, receiver);
|
|
1128
805
|
}
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
this.assign(validKey, mergeValue, true);
|
|
1134
|
-
} else if (!current || override && validKey !== "id" && validKey !== "_id") {
|
|
1135
|
-
this.set(validKey, mergeValue);
|
|
806
|
+
if (!isOnlyMainProp(prop)) {
|
|
807
|
+
const ref = t.ref;
|
|
808
|
+
if (ref && prop in ref) {
|
|
809
|
+
return Reflect.get(ref, prop, receiver);
|
|
1136
810
|
}
|
|
1137
811
|
}
|
|
1138
|
-
});
|
|
1139
|
-
return this;
|
|
1140
|
-
}
|
|
1141
|
-
clone(newId = false, avoidKeys = []) {
|
|
1142
|
-
const ctor = this.constructor;
|
|
1143
|
-
const instance = new ctor(
|
|
1144
|
-
this._gedcom,
|
|
1145
|
-
this._id,
|
|
1146
|
-
this._main,
|
|
1147
|
-
this._parent
|
|
1148
|
-
);
|
|
1149
|
-
if (newId && this._id) {
|
|
1150
|
-
instance.id = `IFT${this._id.replace(/[^0-9]/g, "")}`;
|
|
1151
812
|
}
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
813
|
+
});
|
|
814
|
+
};
|
|
815
|
+
var createCommon = (gedcom, id, main, parent) => {
|
|
816
|
+
return createProxy(
|
|
817
|
+
new Common(gedcom, id, main, parent)
|
|
818
|
+
);
|
|
819
|
+
};
|
|
820
|
+
var isOnlyMainProp = (key) => {
|
|
821
|
+
return key === "_gedcom" || key === "_main" || key === "_parent" || key === "_uniqueId" || key === "_type" || key === "_refs" || key === "id" || key === "_id";
|
|
822
|
+
};
|
|
823
|
+
var isValidKey = (common, key) => {
|
|
824
|
+
const prop = get(common, key);
|
|
825
|
+
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);
|
|
826
|
+
};
|
|
827
|
+
var getValidKeys = (common) => {
|
|
828
|
+
return Object.keys(common).filter((key) => {
|
|
829
|
+
return isValidKey(common, key);
|
|
830
|
+
});
|
|
831
|
+
};
|
|
832
|
+
var getValidTag = (tag) => {
|
|
833
|
+
return tag.replace(/^@@/, "");
|
|
834
|
+
};
|
|
835
|
+
var getListTag = (tag) => {
|
|
836
|
+
return `@@${tag}`;
|
|
837
|
+
};
|
|
838
|
+
var isId = (string) => {
|
|
839
|
+
return ID_REG.test(string);
|
|
840
|
+
};
|
|
841
|
+
var idGetter = (id) => {
|
|
842
|
+
if (id === void 0) {
|
|
843
|
+
return void 0;
|
|
1155
844
|
}
|
|
1156
|
-
|
|
1157
|
-
|
|
845
|
+
let newId = `${id}`;
|
|
846
|
+
const parts = newId?.match(ID_GETTER_REG)?.groups;
|
|
847
|
+
if (!parts?.at && !parts?.letter) {
|
|
848
|
+
newId = `@U${newId}`;
|
|
849
|
+
} else if (!parts.at) {
|
|
850
|
+
newId = `@${newId}`;
|
|
851
|
+
} else if (!parts.letter) {
|
|
852
|
+
newId = newId.replace(/^@/, "@U");
|
|
1158
853
|
}
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
return gedcom.join("\n");
|
|
854
|
+
if (!newId.endsWith("@")) {
|
|
855
|
+
newId = `${newId}@`;
|
|
1162
856
|
}
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
const value = prop.exportValue();
|
|
1177
|
-
gedcom.push(
|
|
1178
|
-
`${level} ${validKey}${value ? ` ${value}` : ""}`
|
|
1179
|
-
);
|
|
1180
|
-
gedcom.push(
|
|
1181
|
-
...prop.toGedcomLines(validKey, level + 1, options)
|
|
1182
|
-
);
|
|
1183
|
-
} else if (prop instanceof List) {
|
|
1184
|
-
gedcom.push(
|
|
1185
|
-
...prop.toGedcomLines(validKey, level, options)
|
|
1186
|
-
);
|
|
1187
|
-
}
|
|
1188
|
-
}
|
|
1189
|
-
});
|
|
1190
|
-
return gedcom;
|
|
857
|
+
return newId;
|
|
858
|
+
};
|
|
859
|
+
|
|
860
|
+
// src/classes/list.ts
|
|
861
|
+
var List = class _List {
|
|
862
|
+
// length = 0;
|
|
863
|
+
constructor(items) {
|
|
864
|
+
this.items = {};
|
|
865
|
+
this.isListable = true;
|
|
866
|
+
this.marker = void 0;
|
|
867
|
+
if (items) {
|
|
868
|
+
this.concat(items);
|
|
869
|
+
}
|
|
1191
870
|
}
|
|
1192
|
-
|
|
1193
|
-
return
|
|
871
|
+
get length() {
|
|
872
|
+
return this.values().length;
|
|
1194
873
|
}
|
|
1195
|
-
|
|
1196
|
-
return
|
|
874
|
+
has(indi) {
|
|
875
|
+
return !!this.item(
|
|
876
|
+
typeof indi === "string" ? indi : indi?.id ?? ""
|
|
877
|
+
);
|
|
1197
878
|
}
|
|
1198
|
-
|
|
1199
|
-
const
|
|
1200
|
-
|
|
1201
|
-
|
|
879
|
+
get(name) {
|
|
880
|
+
const propList = new _List();
|
|
881
|
+
this.entries().forEach(([key, item]) => {
|
|
882
|
+
propList.item(key, item.get(name));
|
|
1202
883
|
});
|
|
884
|
+
return propList;
|
|
1203
885
|
}
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
886
|
+
getIf(name, condition, name2) {
|
|
887
|
+
const propList = new _List();
|
|
888
|
+
this.entries().forEach(([key, item]) => {
|
|
889
|
+
const passedItem = item.getIf(name, condition, name2);
|
|
890
|
+
if (passedItem) {
|
|
891
|
+
propList.item(key, passedItem);
|
|
1209
892
|
}
|
|
1210
|
-
}
|
|
1211
|
-
return void 0;
|
|
1212
|
-
}
|
|
1213
|
-
sourStartsWith(prefix) {
|
|
1214
|
-
return this.getSourceHeads().some((head) => {
|
|
1215
|
-
const sour = get(head, "SOUR.value");
|
|
1216
|
-
return !!sour?.toLowerCase()?.startsWith(prefix);
|
|
1217
893
|
});
|
|
894
|
+
return propList;
|
|
1218
895
|
}
|
|
1219
|
-
|
|
1220
|
-
return this.
|
|
896
|
+
keys() {
|
|
897
|
+
return Object.keys(this.items);
|
|
1221
898
|
}
|
|
1222
|
-
|
|
1223
|
-
return this.
|
|
899
|
+
values() {
|
|
900
|
+
return Object.values(this.items);
|
|
1224
901
|
}
|
|
1225
|
-
|
|
1226
|
-
return this.
|
|
902
|
+
entries() {
|
|
903
|
+
return Object.entries(this.items);
|
|
1227
904
|
}
|
|
1228
|
-
|
|
1229
|
-
return this.sourStartsWith("ancestry");
|
|
905
|
+
setLength(_type) {
|
|
1230
906
|
}
|
|
1231
|
-
|
|
1232
|
-
return this.
|
|
907
|
+
first() {
|
|
908
|
+
return this.index(0);
|
|
1233
909
|
}
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
* Returns the detected source type or undefined if unknown
|
|
1237
|
-
*/
|
|
1238
|
-
getSourceType() {
|
|
1239
|
-
if (this.isAncestry()) return "Ancestry";
|
|
1240
|
-
if (this.isMyHeritage()) return "MyHeritage";
|
|
1241
|
-
if (this.isFamilySearch()) return "FamilySearch";
|
|
1242
|
-
if (this.isGNO2GED()) return "GNO2GED";
|
|
1243
|
-
if (this.isGenoPro()) return "GenoPro";
|
|
1244
|
-
if (this.isAhnenblatt()) return "Ahnenblatt";
|
|
1245
|
-
if (this.isGeni()) return "Geni";
|
|
1246
|
-
return void 0;
|
|
910
|
+
last() {
|
|
911
|
+
return this.index(this.keys().length - 1);
|
|
1247
912
|
}
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
});
|
|
913
|
+
index(index) {
|
|
914
|
+
const keys = this.keys();
|
|
915
|
+
const key = keys[index];
|
|
916
|
+
return key && this.items[key];
|
|
1253
917
|
}
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
}
|
|
918
|
+
item(name, value) {
|
|
919
|
+
if (arguments.length > 1) {
|
|
920
|
+
set(this.items, name, value);
|
|
921
|
+
this.setLength();
|
|
922
|
+
}
|
|
923
|
+
return get(this.items, name);
|
|
1259
924
|
}
|
|
1260
|
-
|
|
1261
|
-
|
|
925
|
+
removeItem(name) {
|
|
926
|
+
unset(this.items, name);
|
|
927
|
+
this.setLength();
|
|
1262
928
|
}
|
|
1263
|
-
|
|
1264
|
-
|
|
929
|
+
exclude(excludedList) {
|
|
930
|
+
excludedList.keys().forEach((itemId) => {
|
|
931
|
+
delete this.items[itemId];
|
|
932
|
+
});
|
|
933
|
+
this.setLength();
|
|
934
|
+
return this;
|
|
1265
935
|
}
|
|
1266
|
-
|
|
1267
|
-
if (
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
if (id !== void 0) return id;
|
|
1274
|
-
}
|
|
1275
|
-
if (this?.isFamilySearch()) {
|
|
1276
|
-
const id = this.getFamilySearchTreeId();
|
|
1277
|
-
if (id !== void 0) return id;
|
|
1278
|
-
}
|
|
1279
|
-
if (this?.isGNO2GED()) {
|
|
1280
|
-
const id = this.getGNO2GEDTreeId();
|
|
1281
|
-
if (id !== void 0) return id;
|
|
1282
|
-
}
|
|
1283
|
-
if (this?.isAhnenblatt()) {
|
|
1284
|
-
const id = this.getAhnenblattTreeId();
|
|
1285
|
-
if (id !== void 0) return id;
|
|
1286
|
-
}
|
|
1287
|
-
if (this?.isGeni()) {
|
|
1288
|
-
const id = this.getGeniTreeId();
|
|
1289
|
-
if (id !== void 0) return id;
|
|
1290
|
-
}
|
|
1291
|
-
if (this?.isGenoPro()) {
|
|
1292
|
-
const id = this.getGenoProTreeId();
|
|
1293
|
-
if (id !== void 0) return id;
|
|
936
|
+
concat(items) {
|
|
937
|
+
if (Array.isArray(items)) {
|
|
938
|
+
items.forEach((item) => {
|
|
939
|
+
this.append(item);
|
|
940
|
+
});
|
|
941
|
+
} else {
|
|
942
|
+
Object.assign(this.items, items ?? {});
|
|
1294
943
|
}
|
|
1295
|
-
|
|
944
|
+
this.setLength();
|
|
945
|
+
return this;
|
|
1296
946
|
}
|
|
1297
|
-
|
|
1298
|
-
|
|
947
|
+
merge(mergedList) {
|
|
948
|
+
this.concat(mergedList?.items);
|
|
949
|
+
return this;
|
|
1299
950
|
}
|
|
1300
|
-
|
|
1301
|
-
const
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
)
|
|
951
|
+
intersection(mergedList) {
|
|
952
|
+
const inter = intersectionBy(
|
|
953
|
+
this.values(),
|
|
954
|
+
mergedList?.values() ?? [],
|
|
955
|
+
"id"
|
|
956
|
+
);
|
|
957
|
+
return new _List(inter);
|
|
1306
958
|
}
|
|
1307
|
-
|
|
1308
|
-
const
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
959
|
+
difference(mergedList) {
|
|
960
|
+
const inter = differenceBy(
|
|
961
|
+
this.values(),
|
|
962
|
+
mergedList?.values() ?? [],
|
|
963
|
+
"id"
|
|
964
|
+
);
|
|
965
|
+
return new _List(inter);
|
|
1313
966
|
}
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
967
|
+
prepend(item) {
|
|
968
|
+
if (item.id) {
|
|
969
|
+
let increase = true;
|
|
970
|
+
if (this.items[item.id]) {
|
|
971
|
+
delete this.items[item.id];
|
|
972
|
+
increase = false;
|
|
973
|
+
}
|
|
974
|
+
this.items = Object.assign(
|
|
975
|
+
{
|
|
976
|
+
[item.id]: item
|
|
977
|
+
},
|
|
978
|
+
this.items
|
|
979
|
+
);
|
|
980
|
+
if (increase) {
|
|
981
|
+
this.setLength("increase");
|
|
982
|
+
}
|
|
1318
983
|
}
|
|
1319
|
-
|
|
1320
|
-
return fileName || "FamilySearch Import";
|
|
984
|
+
return this;
|
|
1321
985
|
}
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
986
|
+
append(item) {
|
|
987
|
+
if (item.id) {
|
|
988
|
+
let increase = true;
|
|
989
|
+
if (this.items[item.id]) {
|
|
990
|
+
delete this.items[item.id];
|
|
991
|
+
increase = false;
|
|
992
|
+
}
|
|
993
|
+
this.items[item.id] = item;
|
|
994
|
+
if (increase) {
|
|
995
|
+
this.setLength("increase");
|
|
1328
996
|
}
|
|
1329
997
|
}
|
|
1330
|
-
return
|
|
1331
|
-
}
|
|
1332
|
-
getAhnenblattTreeName() {
|
|
1333
|
-
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1334
|
-
return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
998
|
+
return this;
|
|
1335
999
|
}
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
if (idMatch) {
|
|
1341
|
-
return idMatch[1];
|
|
1342
|
-
}
|
|
1000
|
+
delete(item) {
|
|
1001
|
+
if (item.id && this.items[item.id]) {
|
|
1002
|
+
delete this.items[item.id];
|
|
1003
|
+
this.setLength("decrease");
|
|
1343
1004
|
}
|
|
1344
|
-
return
|
|
1005
|
+
return this;
|
|
1345
1006
|
}
|
|
1346
|
-
|
|
1347
|
-
const
|
|
1348
|
-
|
|
1007
|
+
copy(ClassName = _List) {
|
|
1008
|
+
const newList = new ClassName();
|
|
1009
|
+
Object.assign(newList.items, this.items);
|
|
1010
|
+
newList.setLength();
|
|
1011
|
+
return newList;
|
|
1349
1012
|
}
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
if (fileName) {
|
|
1353
|
-
const idMatch = fileName.match(/_(\d+)/);
|
|
1354
|
-
if (idMatch) {
|
|
1355
|
-
return idMatch[1];
|
|
1356
|
-
}
|
|
1357
|
-
}
|
|
1358
|
-
return void 0;
|
|
1013
|
+
except(item, ClassName = _List) {
|
|
1014
|
+
return this.copy(ClassName).delete(item);
|
|
1359
1015
|
}
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1016
|
+
forEach(iterate) {
|
|
1017
|
+
this.entries().forEach(([key, item], index) => {
|
|
1018
|
+
iterate(item, key, index);
|
|
1019
|
+
});
|
|
1363
1020
|
}
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
}
|
|
1369
|
-
return `gno_${this._gedcom?.refcount || "unknown"}`;
|
|
1021
|
+
map(iterate) {
|
|
1022
|
+
return this.entries().map(([key, item], index) => {
|
|
1023
|
+
return iterate(item, key, index);
|
|
1024
|
+
});
|
|
1370
1025
|
}
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
}
|
|
1376
|
-
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1377
|
-
return fileName || "GNO2GED Export";
|
|
1026
|
+
reduce(iterate, initialValue) {
|
|
1027
|
+
return this.entries().reduce((acc, [key, item], index) => {
|
|
1028
|
+
return iterate(acc, item, key, index);
|
|
1029
|
+
}, initialValue);
|
|
1378
1030
|
}
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
|
|
1387
|
-
if (fileName) {
|
|
1388
|
-
const idMatch = fileName.match(/_(\d+)/);
|
|
1389
|
-
if (idMatch) {
|
|
1390
|
-
return `${prefix}_${idMatch[1]}`;
|
|
1031
|
+
filter(filters, ClassName = _List) {
|
|
1032
|
+
const newList = new ClassName();
|
|
1033
|
+
const isIterator = typeof filters === "function";
|
|
1034
|
+
this.entries().forEach(([itemId, item], index) => {
|
|
1035
|
+
if (isIterator) {
|
|
1036
|
+
filters(item, itemId, index) && newList.item(itemId, item);
|
|
1037
|
+
return;
|
|
1391
1038
|
}
|
|
1392
|
-
|
|
1393
|
-
|
|
1039
|
+
if (!Object.keys(filters).length || Object.entries(filters).every(([key, value]) => {
|
|
1040
|
+
let itemValue;
|
|
1041
|
+
if (key === "id") {
|
|
1042
|
+
itemValue = item.toProp("id");
|
|
1043
|
+
} else {
|
|
1044
|
+
itemValue = item.toProp(key)?.toValue();
|
|
1045
|
+
}
|
|
1046
|
+
if (Array.isArray(value)) {
|
|
1047
|
+
return value.includes(itemValue);
|
|
1048
|
+
}
|
|
1049
|
+
return itemValue === value;
|
|
1050
|
+
})) {
|
|
1051
|
+
newList.item(itemId, item);
|
|
1052
|
+
}
|
|
1053
|
+
});
|
|
1054
|
+
return newList;
|
|
1394
1055
|
}
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1056
|
+
find(filters, _ClassName = _List) {
|
|
1057
|
+
let foundItem;
|
|
1058
|
+
const isIterator = typeof filters === "function";
|
|
1059
|
+
this.entries().find(([itemId, item], index) => {
|
|
1060
|
+
if (isIterator) {
|
|
1061
|
+
if (filters(item, itemId, index)) {
|
|
1062
|
+
foundItem = item;
|
|
1063
|
+
return true;
|
|
1064
|
+
}
|
|
1065
|
+
return false;
|
|
1066
|
+
}
|
|
1067
|
+
if (!Object.keys(filters).length || Object.entries(filters).every(([key, value]) => {
|
|
1068
|
+
let itemValue;
|
|
1069
|
+
if (key === "id") {
|
|
1070
|
+
itemValue = item.toProp("id");
|
|
1071
|
+
} else {
|
|
1072
|
+
itemValue = item.toProp(key)?.toValue();
|
|
1073
|
+
}
|
|
1074
|
+
if (Array.isArray(value)) {
|
|
1075
|
+
return value.includes(itemValue);
|
|
1076
|
+
}
|
|
1077
|
+
return itemValue === value;
|
|
1078
|
+
})) {
|
|
1079
|
+
foundItem = item;
|
|
1080
|
+
return true;
|
|
1081
|
+
}
|
|
1082
|
+
return false;
|
|
1083
|
+
});
|
|
1084
|
+
return foundItem;
|
|
1416
1085
|
}
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
if (this?.isMyHeritage()) {
|
|
1423
|
-
const name = this.getMyHeritageTreeName();
|
|
1424
|
-
if (name) return name;
|
|
1425
|
-
}
|
|
1426
|
-
if (this?.isFamilySearch()) {
|
|
1427
|
-
const name = this.getFamilySearchTreeName();
|
|
1428
|
-
if (name) return name;
|
|
1429
|
-
}
|
|
1430
|
-
if (this?.isGNO2GED()) {
|
|
1431
|
-
const name = this.getGNO2GEDTreeName();
|
|
1432
|
-
if (name) return name;
|
|
1086
|
+
orderBy(orders, ClassName = _List) {
|
|
1087
|
+
const newList = new ClassName();
|
|
1088
|
+
const isIterator = typeof orders === "function";
|
|
1089
|
+
if (!isIterator && (!orders || !Object.keys(orders).length)) {
|
|
1090
|
+
return newList.merge(this);
|
|
1433
1091
|
}
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1092
|
+
const sortedItems = this.entries().toSorted(
|
|
1093
|
+
([itemAId, itemA], [itemBId, itemB]) => {
|
|
1094
|
+
if (isIterator) {
|
|
1095
|
+
return orders(itemA, itemAId, itemB, itemBId);
|
|
1096
|
+
}
|
|
1097
|
+
const [key, { direction, getter }] = Object.entries(
|
|
1098
|
+
typeof orders === "string" ? { [orders]: { direction: "ASC" } } : orders
|
|
1099
|
+
)[0];
|
|
1100
|
+
const rawA = itemA.get(key);
|
|
1101
|
+
const rawB = itemB.get(key);
|
|
1102
|
+
let valueA = rawA?.toValue();
|
|
1103
|
+
let valueB = rawB?.toValue();
|
|
1104
|
+
if (getter && typeof getter === "function") {
|
|
1105
|
+
valueA = getter(valueA, rawA);
|
|
1106
|
+
valueB = getter(valueB, rawB);
|
|
1107
|
+
}
|
|
1108
|
+
let sortValue = 0;
|
|
1109
|
+
if (!valueA && valueA !== 0 && !valueB && valueB !== 0) {
|
|
1110
|
+
sortValue = 0;
|
|
1111
|
+
} else if (!valueB && valueB !== 0) {
|
|
1112
|
+
sortValue = 1;
|
|
1113
|
+
} else if (!valueA && valueA !== 0) {
|
|
1114
|
+
sortValue = -1;
|
|
1115
|
+
} else if (valueA < valueB) {
|
|
1116
|
+
sortValue = -1;
|
|
1117
|
+
} else if (valueA > valueB) {
|
|
1118
|
+
sortValue = 1;
|
|
1119
|
+
}
|
|
1120
|
+
return sortValue * (direction === "DESC" ? -1 : 1);
|
|
1121
|
+
}
|
|
1122
|
+
);
|
|
1123
|
+
sortedItems.forEach(([key, value]) => {
|
|
1124
|
+
newList.item(key, value);
|
|
1125
|
+
});
|
|
1126
|
+
return newList;
|
|
1127
|
+
}
|
|
1128
|
+
groupBy(groups, sort, minOccurance = -1, lessOccuranceLabel = "Appearing less than 5 times", ClassName = _List) {
|
|
1129
|
+
const groupped = {};
|
|
1130
|
+
const isIterator = typeof groups === "function";
|
|
1131
|
+
if (!isIterator && (!groups || !Object.keys(groups).length)) {
|
|
1132
|
+
groupped.Unknown = new ClassName().merge(this);
|
|
1133
|
+
groupped.Unknown.marker = "Unknown";
|
|
1134
|
+
return groupped;
|
|
1437
1135
|
}
|
|
1438
|
-
|
|
1439
|
-
const
|
|
1440
|
-
if (
|
|
1136
|
+
this.forEach((item, itemId) => {
|
|
1137
|
+
const group = [];
|
|
1138
|
+
if (isIterator) {
|
|
1139
|
+
const newGroups = groups(item, itemId);
|
|
1140
|
+
group.push(
|
|
1141
|
+
...Array.isArray(newGroups) ? newGroups : [newGroups]
|
|
1142
|
+
);
|
|
1143
|
+
} else {
|
|
1144
|
+
const [key, { getter }] = Object.entries(
|
|
1145
|
+
typeof groups === "string" ? { [groups]: {} } : groups
|
|
1146
|
+
)[0];
|
|
1147
|
+
const raw = item.get(key)?.index(0);
|
|
1148
|
+
let value = raw?.toValue();
|
|
1149
|
+
if (getter && typeof getter === "function") {
|
|
1150
|
+
value = getter(value, raw);
|
|
1151
|
+
}
|
|
1152
|
+
if (value) {
|
|
1153
|
+
group.push(value);
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
if (!group.length) {
|
|
1157
|
+
group.push("Unknown");
|
|
1158
|
+
}
|
|
1159
|
+
group.forEach((g) => {
|
|
1160
|
+
const newGroup = typeof g === "string" ? { group: g } : g;
|
|
1161
|
+
if (!groupped[newGroup.group]) {
|
|
1162
|
+
groupped[newGroup.group] = new ClassName();
|
|
1163
|
+
groupped[newGroup.group].marker = newGroup.marker ?? newGroup.group;
|
|
1164
|
+
}
|
|
1165
|
+
groupped[newGroup.group]?.append(item);
|
|
1166
|
+
});
|
|
1167
|
+
});
|
|
1168
|
+
if (sort) {
|
|
1169
|
+
return Object.entries(groupped).toSorted(([ak, a], [bk, b]) => {
|
|
1170
|
+
if (typeof sort === "function") {
|
|
1171
|
+
return sort(a, ak, b, bk);
|
|
1172
|
+
}
|
|
1173
|
+
if (ak === "Unknown") {
|
|
1174
|
+
return 1;
|
|
1175
|
+
}
|
|
1176
|
+
if (bk === "Unknown") {
|
|
1177
|
+
return -1;
|
|
1178
|
+
}
|
|
1179
|
+
if (sort === "group") {
|
|
1180
|
+
return ak.localeCompare(bk);
|
|
1181
|
+
}
|
|
1182
|
+
return (b?.length ?? 0) - (a?.length ?? 0);
|
|
1183
|
+
}).reduce((acc, [key, value]) => {
|
|
1184
|
+
if (minOccurance > -1 && (value?.length ?? 0) < minOccurance) {
|
|
1185
|
+
const otherKey = lessOccuranceLabel;
|
|
1186
|
+
acc[otherKey] = acc[otherKey] && value ? acc[otherKey].merge(value) : value;
|
|
1187
|
+
} else {
|
|
1188
|
+
acc[key] = value;
|
|
1189
|
+
}
|
|
1190
|
+
return acc;
|
|
1191
|
+
}, {});
|
|
1441
1192
|
}
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1193
|
+
return groupped;
|
|
1194
|
+
}
|
|
1195
|
+
findIndex(item) {
|
|
1196
|
+
if (!item?.id) {
|
|
1197
|
+
return -1;
|
|
1445
1198
|
}
|
|
1446
|
-
return this.
|
|
1199
|
+
return this.keys().findIndex((key) => key === item.id);
|
|
1200
|
+
}
|
|
1201
|
+
getItems() {
|
|
1202
|
+
return this.items;
|
|
1203
|
+
}
|
|
1204
|
+
toJson(tag, options) {
|
|
1205
|
+
const json = this.toObject(tag, options);
|
|
1206
|
+
return JSON.stringify(json);
|
|
1207
|
+
}
|
|
1208
|
+
toObject(tag, options) {
|
|
1209
|
+
const json = {};
|
|
1210
|
+
this.entries().forEach(([_, item]) => {
|
|
1211
|
+
const validTag = getValidTag(tag);
|
|
1212
|
+
if (json[validTag]) {
|
|
1213
|
+
if (!Array.isArray(json[validTag])) {
|
|
1214
|
+
json[validTag] = [json[validTag]];
|
|
1215
|
+
}
|
|
1216
|
+
json[validTag].push(
|
|
1217
|
+
item.toObject(validTag, options)
|
|
1218
|
+
);
|
|
1219
|
+
} else {
|
|
1220
|
+
json[validTag] = item.toObject(
|
|
1221
|
+
validTag,
|
|
1222
|
+
options
|
|
1223
|
+
);
|
|
1224
|
+
}
|
|
1225
|
+
});
|
|
1226
|
+
return json;
|
|
1227
|
+
}
|
|
1228
|
+
toGedcom(tag, level = 0, options) {
|
|
1229
|
+
const gedcom = this.toGedcomLines(tag, level, options);
|
|
1230
|
+
return gedcom.join("\n");
|
|
1231
|
+
}
|
|
1232
|
+
toGedcomLines(tag, level = 0, options) {
|
|
1233
|
+
const gedcom = [];
|
|
1234
|
+
this.entries().forEach(([_, item]) => {
|
|
1235
|
+
const validTag = getValidTag(tag);
|
|
1236
|
+
const xref = item.id;
|
|
1237
|
+
const payload = item.exportValue?.();
|
|
1238
|
+
if (xref) {
|
|
1239
|
+
gedcom.push(
|
|
1240
|
+
`${level} ${xref} ${validTag}${payload ? ` ${payload}` : ""}`
|
|
1241
|
+
);
|
|
1242
|
+
} else {
|
|
1243
|
+
gedcom.push(
|
|
1244
|
+
`${level} ${validTag}${payload ? ` ${payload}` : ""}`
|
|
1245
|
+
);
|
|
1246
|
+
}
|
|
1247
|
+
gedcom.push(
|
|
1248
|
+
...item.toGedcomLines(
|
|
1249
|
+
validTag,
|
|
1250
|
+
level + 1,
|
|
1251
|
+
options
|
|
1252
|
+
)
|
|
1253
|
+
);
|
|
1254
|
+
});
|
|
1255
|
+
return gedcom;
|
|
1256
|
+
}
|
|
1257
|
+
toValue() {
|
|
1258
|
+
const propList = new _List();
|
|
1259
|
+
this.entries().forEach(([key, item]) => {
|
|
1260
|
+
propList.item(key, item?.toValue());
|
|
1261
|
+
});
|
|
1262
|
+
return propList;
|
|
1263
|
+
}
|
|
1264
|
+
// @deprecated use get instead
|
|
1265
|
+
toProp(tag) {
|
|
1266
|
+
return this.get(tag);
|
|
1267
|
+
}
|
|
1268
|
+
toList() {
|
|
1269
|
+
return new _List().concat(this.items);
|
|
1270
|
+
}
|
|
1271
|
+
toValueList() {
|
|
1272
|
+
const newList = new _List();
|
|
1273
|
+
this.values().forEach((value) => {
|
|
1274
|
+
value.value && newList.item(value.value, value);
|
|
1275
|
+
});
|
|
1276
|
+
return newList;
|
|
1277
|
+
}
|
|
1278
|
+
};
|
|
1279
|
+
|
|
1280
|
+
// src/utils/get-all-prop.ts
|
|
1281
|
+
var getAllProp = (indi, prop) => {
|
|
1282
|
+
return prop && (indi?.get(prop)?.toList().values() ?? []).filter(Boolean) || [];
|
|
1283
|
+
};
|
|
1284
|
+
|
|
1285
|
+
// src/utils/date-formatter.ts
|
|
1286
|
+
var ACCEPTED_DATE_FORMATS = [
|
|
1287
|
+
"yyyy.MM.dd.",
|
|
1288
|
+
"yyyy-MM-dd",
|
|
1289
|
+
"MM/dd/yyyy"
|
|
1290
|
+
];
|
|
1291
|
+
var ACCEPTED_DATE_FORMATS_REGEX = new RegExp(
|
|
1292
|
+
`(${ACCEPTED_DATE_FORMATS.map(
|
|
1293
|
+
(acceptedFormat) => acceptedFormat.replace(/[^.\-/]/g, "\\d")
|
|
1294
|
+
).join("|")})`,
|
|
1295
|
+
"gi"
|
|
1296
|
+
);
|
|
1297
|
+
var firstDate = (date) => {
|
|
1298
|
+
if (!date) return void 0;
|
|
1299
|
+
if (isCommonDate(date)) return date;
|
|
1300
|
+
if (date instanceof List) {
|
|
1301
|
+
return firstDate(
|
|
1302
|
+
date.index(0)
|
|
1303
|
+
);
|
|
1304
|
+
}
|
|
1305
|
+
const node = date;
|
|
1306
|
+
if (typeof node.toValue === "function") {
|
|
1307
|
+
return node;
|
|
1447
1308
|
}
|
|
1309
|
+
return void 0;
|
|
1448
1310
|
};
|
|
1449
|
-
var
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1311
|
+
var dateNote = (date, shortNote = true) => {
|
|
1312
|
+
if (date && typeof date.toNote === "function") {
|
|
1313
|
+
return date.toNote(shortNote) ?? "";
|
|
1314
|
+
}
|
|
1315
|
+
return "";
|
|
1316
|
+
};
|
|
1317
|
+
var commonDateFormatter = (date, format2 = "yyyy", prefix = "") => {
|
|
1318
|
+
const used = firstDate(date);
|
|
1319
|
+
const formattedDate = used?.toValue(format2);
|
|
1320
|
+
if (!formattedDate) {
|
|
1321
|
+
return void 0;
|
|
1322
|
+
}
|
|
1323
|
+
return `${prefix}${formattedDate}`.trim();
|
|
1324
|
+
};
|
|
1325
|
+
var noteDateFormatter = (date, format2 = "yyyy", prefix = "", shortNote = true, showNote = true) => {
|
|
1326
|
+
const used = firstDate(date);
|
|
1327
|
+
const rawDate = commonDateFormatter(used, format2, "");
|
|
1328
|
+
if (!rawDate) {
|
|
1329
|
+
return void 0;
|
|
1330
|
+
}
|
|
1331
|
+
const note = dateNote(used, shortNote);
|
|
1332
|
+
return `${prefix}${note && showNote ? i18n.t(`${note} {{date}}`, { date: rawDate }) : rawDate}`;
|
|
1333
|
+
};
|
|
1334
|
+
var marriageDateFormatter = (fam, showDays = false, showPlaces = false, shortNote = true, showNote = true, showDisplayTextIfNoDate = true, showAllEvents = false, dateFormatPattern) => {
|
|
1335
|
+
const fullDateFormat = i18n.t("dateFormat");
|
|
1336
|
+
const marriageDates = [];
|
|
1337
|
+
const marriagePlaces = [];
|
|
1338
|
+
const marriages = (fam?.toValueList().values() ?? []).flatMap((fam2) => {
|
|
1339
|
+
const family = fam2;
|
|
1340
|
+
const marrEvents = (family?.MARR?.toList().values() ?? []).filter(
|
|
1341
|
+
Boolean
|
|
1342
|
+
);
|
|
1343
|
+
if (marrEvents.length === 0) {
|
|
1344
|
+
const displayText = family?.get("DISPLAYTEXT")?.toValue() ?? "";
|
|
1345
|
+
if (showDisplayTextIfNoDate && displayText) {
|
|
1346
|
+
const displayDate = displayText.match(
|
|
1347
|
+
ACCEPTED_DATE_FORMATS_REGEX
|
|
1348
|
+
)?.[0];
|
|
1349
|
+
if (displayDate) {
|
|
1350
|
+
marriagePlaces.push(displayText.replace(displayDate, ""));
|
|
1351
|
+
const marriageDate = createCommonDate(
|
|
1352
|
+
fam2?.getGedcom(),
|
|
1353
|
+
void 0,
|
|
1354
|
+
family
|
|
1355
|
+
);
|
|
1356
|
+
marriageDate.value = displayDate;
|
|
1357
|
+
marriageDates.push(marriageDate);
|
|
1358
|
+
} else {
|
|
1359
|
+
marriagePlaces.push(displayText);
|
|
1360
|
+
marriageDates.push(void 0);
|
|
1361
|
+
return ["\u221E"];
|
|
1462
1362
|
}
|
|
1463
1363
|
}
|
|
1364
|
+
return [];
|
|
1464
1365
|
}
|
|
1366
|
+
const eventsToProcess = showAllEvents ? marrEvents : marrEvents.slice(0, 1);
|
|
1367
|
+
return eventsToProcess.map((marrEvent) => {
|
|
1368
|
+
const marriageEventDetail = marrEvent;
|
|
1369
|
+
const marriageDate = marriageEventDetail?.DATE;
|
|
1370
|
+
const marriagePlace = showPlaces ? marriageEventDetail?.PLAC?.value : void 0;
|
|
1371
|
+
marriagePlaces.push(marriagePlace);
|
|
1372
|
+
marriageDates.push(marriageDate);
|
|
1373
|
+
const formattedDate = noteDateFormatter(
|
|
1374
|
+
marriageDate,
|
|
1375
|
+
showDays ? fullDateFormat : "yyyy",
|
|
1376
|
+
"\u221E",
|
|
1377
|
+
shortNote,
|
|
1378
|
+
showNote
|
|
1379
|
+
);
|
|
1380
|
+
return formattedDate ? formattedDate : void 0;
|
|
1381
|
+
});
|
|
1465
1382
|
});
|
|
1383
|
+
const marriageArray = marriages.length ? marriages.filter(Boolean) : [];
|
|
1384
|
+
const datesArray = marriageArray.filter(Boolean);
|
|
1385
|
+
const placesArray = marriagePlaces.filter(Boolean);
|
|
1386
|
+
const dates = datesArray.join(" ").trim();
|
|
1387
|
+
return {
|
|
1388
|
+
rawArray: marriageDates,
|
|
1389
|
+
inArray: datesArray,
|
|
1390
|
+
inOrder: dates,
|
|
1391
|
+
places: placesArray,
|
|
1392
|
+
marriage: marriageArray,
|
|
1393
|
+
...showPlaces ? {
|
|
1394
|
+
marriages,
|
|
1395
|
+
marriagePlaces
|
|
1396
|
+
} : {}
|
|
1397
|
+
};
|
|
1466
1398
|
};
|
|
1467
|
-
var
|
|
1468
|
-
|
|
1469
|
-
|
|
1399
|
+
var dateFormatter = (indi, showMarriages = false, showDays = false, showPlaces = false, shortNote = true, showNote = true, isOnStage, showAllEvents = false, dateFormatPattern) => {
|
|
1400
|
+
const fullDateFormat = i18n.t("dateFormat");
|
|
1401
|
+
const birthEvents = getAllProp(indi, "BIRT");
|
|
1402
|
+
const firstBirthValue = birthEvents[0];
|
|
1403
|
+
const deathEvents = getAllProp(indi, "DEAT");
|
|
1404
|
+
const firstDeathValue = deathEvents[0];
|
|
1405
|
+
const birth = commonDateFormatter(
|
|
1406
|
+
firstBirthValue?.DATE,
|
|
1407
|
+
showDays ? fullDateFormat : "yyyy"
|
|
1470
1408
|
);
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
const
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1409
|
+
const birthPlace = showPlaces ? firstBirthValue?.PLAC?.value : void 0;
|
|
1410
|
+
const death = commonDateFormatter(
|
|
1411
|
+
firstDeathValue?.DATE,
|
|
1412
|
+
showDays ? fullDateFormat : "yyyy"
|
|
1413
|
+
);
|
|
1414
|
+
const deathPlace = showPlaces ? firstDeathValue?.PLAC?.value : void 0;
|
|
1415
|
+
const marriagePlaces = [];
|
|
1416
|
+
const marriages = [];
|
|
1417
|
+
if (showMarriages || isOnStage) {
|
|
1418
|
+
(indi?.get("FAMS")?.toValueList().values() ?? []).forEach((fam) => {
|
|
1419
|
+
const famRef = fam?.ref;
|
|
1420
|
+
const marriageDates = marriageDateFormatter(
|
|
1421
|
+
famRef,
|
|
1422
|
+
showDays,
|
|
1423
|
+
showPlaces,
|
|
1424
|
+
shortNote,
|
|
1425
|
+
showNote,
|
|
1426
|
+
true,
|
|
1427
|
+
showAllEvents);
|
|
1428
|
+
marriages.push(...marriageDates?.marriage ?? []);
|
|
1429
|
+
marriagePlaces.push(...marriageDates?.marriagePlaces ?? []);
|
|
1430
|
+
});
|
|
1431
|
+
}
|
|
1432
|
+
const birthStrings = [];
|
|
1433
|
+
const birthPlaces = [];
|
|
1434
|
+
const eventsToProcess = showAllEvents ? birthEvents : birthEvents.slice(0, 1);
|
|
1435
|
+
eventsToProcess.forEach((birthEvent) => {
|
|
1436
|
+
const birthDateNode = firstDate(birthEvent?.DATE);
|
|
1437
|
+
const birthDate = commonDateFormatter(
|
|
1438
|
+
birthDateNode,
|
|
1439
|
+
showDays ? fullDateFormat : "yyyy"
|
|
1440
|
+
);
|
|
1441
|
+
const birthEventNote = dateNote(birthDateNode, shortNote);
|
|
1442
|
+
const birthEventPlace = showPlaces ? birthEvent?.PLAC?.value : void 0;
|
|
1443
|
+
if (birthDate) {
|
|
1444
|
+
birthStrings.push(
|
|
1445
|
+
`*${birthEventNote && showNote ? i18n.t(`${birthEventNote} {{date}}`, {
|
|
1446
|
+
date: birthDate
|
|
1447
|
+
}) : birthDate}`
|
|
1448
|
+
);
|
|
1449
|
+
}
|
|
1450
|
+
birthPlaces.push(birthEventPlace);
|
|
1482
1451
|
});
|
|
1452
|
+
const deathStrings = [];
|
|
1453
|
+
const deathPlaces = [];
|
|
1454
|
+
const deathEventsToProcess = showAllEvents ? deathEvents : deathEvents.slice(0, 1);
|
|
1455
|
+
deathEventsToProcess.forEach((deathEvent) => {
|
|
1456
|
+
const deathDateNode = firstDate(deathEvent?.DATE);
|
|
1457
|
+
const deathDate = commonDateFormatter(
|
|
1458
|
+
deathDateNode,
|
|
1459
|
+
showDays ? fullDateFormat : "yyyy"
|
|
1460
|
+
);
|
|
1461
|
+
const deathEventNote = dateNote(deathDateNode, shortNote);
|
|
1462
|
+
const deathEventPlace = showPlaces ? deathEvent?.PLAC?.value : void 0;
|
|
1463
|
+
if (deathDate) {
|
|
1464
|
+
deathStrings.push(
|
|
1465
|
+
`\u2020${deathEventNote && showNote ? i18n.t(`${deathEventNote} {{date}}`, {
|
|
1466
|
+
date: deathDate
|
|
1467
|
+
}) : deathDate}`
|
|
1468
|
+
);
|
|
1469
|
+
}
|
|
1470
|
+
deathPlaces.push(deathEventPlace);
|
|
1471
|
+
});
|
|
1472
|
+
const birthString = birthStrings[0] ?? "";
|
|
1473
|
+
const deathString = deathStrings[0] ?? "";
|
|
1474
|
+
const marriageArray = marriages.length ? marriages.filter(Boolean) : [];
|
|
1475
|
+
const datesArray = !birth && !death ? marriageArray : [...birthStrings, ...marriageArray, ...deathStrings];
|
|
1476
|
+
const placesArray = !birth && !death ? marriagePlaces : [...birthPlaces, ...marriagePlaces, ...deathPlaces];
|
|
1477
|
+
const nonNullDatesArray = datesArray.filter(Boolean);
|
|
1478
|
+
const dates = nonNullDatesArray.join(" ").trim();
|
|
1479
|
+
return {
|
|
1480
|
+
inArray: nonNullDatesArray,
|
|
1481
|
+
inOrder: dates,
|
|
1482
|
+
places: placesArray,
|
|
1483
|
+
birth: birthString,
|
|
1484
|
+
marriage: marriageArray,
|
|
1485
|
+
death: deathString,
|
|
1486
|
+
...showPlaces ? {
|
|
1487
|
+
birthPlace,
|
|
1488
|
+
deathPlace,
|
|
1489
|
+
...showMarriages ? { marriages, marriagePlaces } : {}
|
|
1490
|
+
} : {},
|
|
1491
|
+
...showAllEvents ? {
|
|
1492
|
+
births: birthStrings,
|
|
1493
|
+
birthPlaces,
|
|
1494
|
+
deaths: deathStrings,
|
|
1495
|
+
deathPlaces
|
|
1496
|
+
} : {}
|
|
1497
|
+
};
|
|
1483
1498
|
};
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1499
|
+
|
|
1500
|
+
// src/utils/range.ts
|
|
1501
|
+
var toTuple = (r) => {
|
|
1502
|
+
if (Array.isArray(r)) {
|
|
1503
|
+
const [s2, e2] = r;
|
|
1504
|
+
return [
|
|
1505
|
+
s2 === void 0 ? void 0 : Number(s2),
|
|
1506
|
+
e2 === void 0 ? void 0 : Number(e2)
|
|
1507
|
+
];
|
|
1508
|
+
}
|
|
1509
|
+
if (r === "-" || r === "") return [void 0, void 0];
|
|
1510
|
+
const [s, e] = r.split("-");
|
|
1511
|
+
return [s ? Number(s) : void 0, e ? Number(e) : void 0];
|
|
1489
1512
|
};
|
|
1490
|
-
var
|
|
1491
|
-
|
|
1513
|
+
var isValidRange = (range) => {
|
|
1514
|
+
if (!Array.isArray(range) && range !== "" && range !== "-" && !/^\d*-\d*$/.test(range)) {
|
|
1515
|
+
return false;
|
|
1516
|
+
}
|
|
1517
|
+
if (Array.isArray(range) && range.some((r) => typeof r === "string" && isNaN(Number(r)))) {
|
|
1518
|
+
return false;
|
|
1519
|
+
}
|
|
1520
|
+
return true;
|
|
1492
1521
|
};
|
|
1493
|
-
var
|
|
1494
|
-
if (
|
|
1495
|
-
return
|
|
1522
|
+
var inRange = (year, range, trueIfNoYear = false) => {
|
|
1523
|
+
if (!isValidRange(range)) {
|
|
1524
|
+
return false;
|
|
1496
1525
|
}
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
if (!parts?.at && !parts?.letter) {
|
|
1500
|
-
newId = `@U${newId}`;
|
|
1501
|
-
} else if (!parts.at) {
|
|
1502
|
-
newId = `@${newId}`;
|
|
1503
|
-
} else if (!parts.letter) {
|
|
1504
|
-
newId = newId.replace(/^@/, "@U");
|
|
1526
|
+
if (!year) {
|
|
1527
|
+
return trueIfNoYear;
|
|
1505
1528
|
}
|
|
1506
|
-
|
|
1507
|
-
|
|
1529
|
+
const [start = -Infinity, end = Infinity] = toTuple(range);
|
|
1530
|
+
if (!start && !end) {
|
|
1531
|
+
return true;
|
|
1508
1532
|
}
|
|
1509
|
-
|
|
1533
|
+
if (start && !end) {
|
|
1534
|
+
return Number(year) >= Number(start);
|
|
1535
|
+
}
|
|
1536
|
+
if (!start && end) {
|
|
1537
|
+
return Number(year) <= Number(end);
|
|
1538
|
+
}
|
|
1539
|
+
return Number(start) <= Number(year) && Number(year) <= Number(end);
|
|
1510
1540
|
};
|
|
1511
1541
|
|
|
1512
1542
|
// src/classes/date.ts
|
|
@@ -1560,6 +1590,8 @@ var formatDateWithComponents = (date, hasDay, hasMonth, hasYear, noteValue, base
|
|
|
1560
1590
|
var CommonDate = class extends Common {
|
|
1561
1591
|
constructor(gedcom, id, main, parent) {
|
|
1562
1592
|
super(gedcom, id, main, parent);
|
|
1593
|
+
/** One DATE per event — merge must not turn this into a List. */
|
|
1594
|
+
this.isListable = false;
|
|
1563
1595
|
delete this.id;
|
|
1564
1596
|
}
|
|
1565
1597
|
get calendar() {
|
|
@@ -5108,14 +5140,15 @@ var Indi = class extends Common {
|
|
|
5108
5140
|
}
|
|
5109
5141
|
return foundPath;
|
|
5110
5142
|
}
|
|
5111
|
-
kinship(other, showMainPerson, lang = "en", entirePath, displayName = "givenname") {
|
|
5143
|
+
kinship(other, showMainPerson, lang = "en", entirePath, displayName = "givenname", nameOrder) {
|
|
5112
5144
|
const KinshipTranslatorClass2 = getKinshipTranslatorClass();
|
|
5113
5145
|
const translator = new KinshipTranslatorClass2(
|
|
5114
5146
|
this,
|
|
5115
5147
|
other,
|
|
5116
5148
|
lang,
|
|
5117
5149
|
entirePath,
|
|
5118
|
-
showMainPerson ? displayName : void 0
|
|
5150
|
+
showMainPerson ? displayName : void 0,
|
|
5151
|
+
nameOrder
|
|
5119
5152
|
);
|
|
5120
5153
|
return translator.translate(!!showMainPerson);
|
|
5121
5154
|
}
|
|
@@ -6039,11 +6072,12 @@ var hungarianOrdinalize = (n) => {
|
|
|
6039
6072
|
|
|
6040
6073
|
// src/kinship-translator/kinship-translator.basic.ts
|
|
6041
6074
|
var KinshipTranslatorBasic = class {
|
|
6042
|
-
constructor(path, displayName = "givenname") {
|
|
6075
|
+
constructor(path, displayName = "givenname", nameOrder = "first-last") {
|
|
6043
6076
|
this.isOfSpouse = false;
|
|
6044
6077
|
this.isSpouseOf = false;
|
|
6045
6078
|
this._path = path;
|
|
6046
6079
|
this.displayName = displayName;
|
|
6080
|
+
this.nameOrder = nameOrder;
|
|
6047
6081
|
}
|
|
6048
6082
|
get path() {
|
|
6049
6083
|
return this._path;
|
|
@@ -6466,7 +6500,7 @@ var KinshipTranslatorHU = class extends KinshipTranslatorBasic {
|
|
|
6466
6500
|
}
|
|
6467
6501
|
of(relation) {
|
|
6468
6502
|
const formattedName = nameFormatter(this.path?.[0]?.indi, {
|
|
6469
|
-
nameOrder:
|
|
6503
|
+
nameOrder: this.nameOrder
|
|
6470
6504
|
});
|
|
6471
6505
|
let name = formattedName.inOrder.filter(Boolean).join(" ");
|
|
6472
6506
|
if (this.displayName === "none") {
|
|
@@ -6680,7 +6714,7 @@ var KinshipTranslatorEn = class extends KinshipTranslatorBasic {
|
|
|
6680
6714
|
}
|
|
6681
6715
|
of(relation) {
|
|
6682
6716
|
const formattedName = nameFormatter(this.path?.[0]?.indi, {
|
|
6683
|
-
nameOrder:
|
|
6717
|
+
nameOrder: this.nameOrder
|
|
6684
6718
|
});
|
|
6685
6719
|
let name = formattedName.inOrder.filter(Boolean).join(" ");
|
|
6686
6720
|
if (this.displayName === "none") {
|
|
@@ -6896,7 +6930,7 @@ var KinshipTranslatorDe = class extends KinshipTranslatorBasic {
|
|
|
6896
6930
|
}
|
|
6897
6931
|
of(relation) {
|
|
6898
6932
|
const formattedName = nameFormatter(this.path?.[0]?.indi, {
|
|
6899
|
-
nameOrder:
|
|
6933
|
+
nameOrder: this.nameOrder
|
|
6900
6934
|
});
|
|
6901
6935
|
let name = formattedName.inOrder.filter(Boolean).join(" ");
|
|
6902
6936
|
if (this.displayName === "none") {
|
|
@@ -7113,7 +7147,7 @@ var KinshipTranslatorFr = class extends KinshipTranslatorBasic {
|
|
|
7113
7147
|
}
|
|
7114
7148
|
of(relation) {
|
|
7115
7149
|
const formattedName = nameFormatter(this.path?.[0]?.indi, {
|
|
7116
|
-
nameOrder:
|
|
7150
|
+
nameOrder: this.nameOrder
|
|
7117
7151
|
});
|
|
7118
7152
|
let name = formattedName.inOrder.filter(Boolean).join(" ");
|
|
7119
7153
|
if (this.displayName === "none") {
|
|
@@ -7451,7 +7485,7 @@ var KinshipTranslatorEs = class extends KinshipTranslatorBasic {
|
|
|
7451
7485
|
}
|
|
7452
7486
|
of(relation) {
|
|
7453
7487
|
const formattedName = nameFormatter(this.path?.[0]?.indi, {
|
|
7454
|
-
nameOrder:
|
|
7488
|
+
nameOrder: this.nameOrder
|
|
7455
7489
|
});
|
|
7456
7490
|
let name = formattedName.inOrder.filter(Boolean).join(" ");
|
|
7457
7491
|
if (this.displayName === "none") {
|
|
@@ -7758,7 +7792,7 @@ var KinshipTranslatorRu = class extends KinshipTranslatorBasic {
|
|
|
7758
7792
|
}
|
|
7759
7793
|
of(relation) {
|
|
7760
7794
|
const formattedName = nameFormatter(this.path?.[0]?.indi, {
|
|
7761
|
-
nameOrder:
|
|
7795
|
+
nameOrder: this.nameOrder
|
|
7762
7796
|
});
|
|
7763
7797
|
let name = formattedName.inOrder.filter(Boolean).join(" ");
|
|
7764
7798
|
if (this.displayName === "none") {
|
|
@@ -7994,7 +8028,7 @@ var KinshipTranslatorJa = class extends KinshipTranslatorBasic {
|
|
|
7994
8028
|
}
|
|
7995
8029
|
of(relation) {
|
|
7996
8030
|
const formattedName = nameFormatter(this.path?.[0]?.indi, {
|
|
7997
|
-
nameOrder:
|
|
8031
|
+
nameOrder: this.nameOrder
|
|
7998
8032
|
});
|
|
7999
8033
|
let name = formattedName.inOrder.filter(Boolean).join(" ");
|
|
8000
8034
|
if (this.displayName === "none") {
|
|
@@ -8243,7 +8277,7 @@ var KinshipTranslatorZh = class extends KinshipTranslatorBasic {
|
|
|
8243
8277
|
}
|
|
8244
8278
|
of(relation) {
|
|
8245
8279
|
const formattedName = nameFormatter(this.path?.[0]?.indi, {
|
|
8246
|
-
nameOrder:
|
|
8280
|
+
nameOrder: this.nameOrder
|
|
8247
8281
|
});
|
|
8248
8282
|
let name = formattedName.inOrder.filter(Boolean).join(" ");
|
|
8249
8283
|
if (this.displayName === "none") {
|
|
@@ -8312,22 +8346,30 @@ var KinshipTranslatorZh = class extends KinshipTranslatorBasic {
|
|
|
8312
8346
|
};
|
|
8313
8347
|
|
|
8314
8348
|
// src/kinship-translator/kinship-translator.ts
|
|
8349
|
+
var nameOrderForLang = (lang) => lang === "hu" || lang === "ja" || lang === "zh" ? "last-first" : "first-last";
|
|
8315
8350
|
var KinshipTranslator = class {
|
|
8316
|
-
constructor(person1, person2, lang = "en", entirePath, displayName = "givenname") {
|
|
8351
|
+
constructor(person1, person2, lang = "en", entirePath, displayName = "givenname", nameOrder) {
|
|
8317
8352
|
this.displayName = displayName;
|
|
8318
8353
|
this.lang = lang;
|
|
8319
8354
|
this.entirePath = entirePath;
|
|
8320
8355
|
this.person1 = person1;
|
|
8321
8356
|
this.person2 = typeof person2 === "string" ? this.person1.getGedcom()?.indi(person2) : person2;
|
|
8322
8357
|
this.path = this.person1.path(this.person2);
|
|
8358
|
+
const order = nameOrder ?? nameOrderForLang(lang);
|
|
8359
|
+
this.nameOrder = order;
|
|
8323
8360
|
if (translators_exports[lang]) {
|
|
8324
8361
|
this.translator = new translators_exports[lang](
|
|
8325
8362
|
this.path ?? [],
|
|
8326
|
-
displayName
|
|
8363
|
+
displayName,
|
|
8364
|
+
order
|
|
8327
8365
|
);
|
|
8328
8366
|
}
|
|
8329
8367
|
if (!this.translator) {
|
|
8330
|
-
this.translator = new KinshipTranslatorEn(
|
|
8368
|
+
this.translator = new KinshipTranslatorEn(
|
|
8369
|
+
this.path ?? [],
|
|
8370
|
+
displayName,
|
|
8371
|
+
order
|
|
8372
|
+
);
|
|
8331
8373
|
}
|
|
8332
8374
|
}
|
|
8333
8375
|
get path0() {
|
|
@@ -8372,14 +8414,16 @@ var KinshipTranslator = class {
|
|
|
8372
8414
|
showMainPerson,
|
|
8373
8415
|
this.lang,
|
|
8374
8416
|
false,
|
|
8375
|
-
this.displayName
|
|
8417
|
+
this.displayName,
|
|
8418
|
+
this.nameOrder
|
|
8376
8419
|
),
|
|
8377
8420
|
relative: this.path?.[index - 1]?.indi.kinship(
|
|
8378
8421
|
path2.indi.id,
|
|
8379
8422
|
showMainPerson,
|
|
8380
8423
|
this.lang,
|
|
8381
8424
|
false,
|
|
8382
|
-
this.displayName
|
|
8425
|
+
this.displayName,
|
|
8426
|
+
this.nameOrder
|
|
8383
8427
|
)
|
|
8384
8428
|
}));
|
|
8385
8429
|
return path;
|