UNPKG

gedcom

Version:

a simple and readable gedcom parser

1,499 lines (1,488 loc) 789 kB
import { createRequire } from "node:module"; //#region rolldown:runtime var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports); var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (var keys$7 = __getOwnPropNames(from), i = 0, n = keys$7.length, key; i < n; i++) { key = keys$7[i]; if (!__hasOwnProp.call(to, key) && key !== except) { __defProp(to, key, { get: ((k) => from[k]).bind(null, key), enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } } } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); var __require = /* @__PURE__ */ createRequire(import.meta.url); //#endregion //#region lib/formal_names.ts const FORMAL_NAMES = { ABBR: "ABBREVIATION", ADDR: "ADDRESS", ADR1: "ADDRESS1", ADR2: "ADDRESS2", ADOP: "ADOPTION", AFN: "AFN", AGE: "AGE", AGNC: "AGENCY", ALIA: "ALIAS", ANCE: "ANCESTORS", ANCI: "ANCES_INTEREST", ANUL: "ANNULMENT", ASSO: "ASSOCIATES", AUTH: "AUTHOR", BAPL: "BAPTISM-LDS", BAPM: "BAPTISM", BARM: "BAR_MITZVAH", BASM: "BAS_MITZVAH", BIRT: "BIRTH", BLES: "BLESSING", BURI: "BURIAL", CALN: "CALL_NUMBER", CAST: "CASTE", CAUS: "CAUSE", CENS: "CENSUS", CHAN: "CHANGE", CHAR: "CHARACTER", CHIL: "CHILD", CHR: "CHRISTENING", CHRA: "ADULT_CHRISTENING", CITY: "CITY", CONC: "CONCATENATION", CONF: "CONFIRMATION", CONL: "CONFIRMATION_LDS", CONT: "CONTINUED", COPR: "COPYRIGHT", CORP: "CORPORATE", CREM: "CREMATION", CTRY: "COUNTRY", DATA: "DATA", DATE: "DATE", DEAT: "DEATH", DESC: "DESCENDANTS", DESI: "DESCENDANT_INT", DEST: "DESTINATION", DIV: "DIVORCE", DIVF: "DIVORCE_FILED", DSCR: "PHY_DESCRIPTION", EDUC: "EDUCATION", EMAI: "EMAIL", EMIG: "EMIGRATION", ENDL: "ENDOWMENT", ENGA: "ENGAGEMENT", EVEN: "EVENT", FACT: "FACT", FAM: "FAMILY", FAMC: "FAMILY_CHILD", FAMF: "FAMILY_FILE", FAMS: "FAMILY_SPOUSE", FAX: "FACIMILIE", FCOM: "FIRST_COMMUNICATION", FILE: "FILE", FORM: "FORMAT", FONE: "PHONETIC", GEDC: "GEDCOM", GIVN: "GIVEN_NAME", GRAD: "GRADUATION", HEAD: "HEADER", HUSB: "HUSBAND", IDNO: "IDENT_NUMVER", IMMI: "IMMIGRATION", INDI: "INDIVIDUAL", LANG: "LANGUAGE", LATI: "LATITUDE", LONG: "LONGITUDE", MAP: "MAP", MARB: "MARRIAGE_BANN", MARC: "MARRIAGE_CONTRACT", MARL: "MARRIAGE_LICENSE", MARR: "MARRIAGE", MARS: "MARRIAGE_SETTLEMENT", MEDI: "MEDIA", NAME: "NAME", NATI: "NATIONALITY", NATU: "NATURALIZATION", NCHI: "CHILDREN_COUNT", NICK: "NICKNAME", NMR: "MARRIAGE_COUNT", NOTE: "NOTE", NPFX: "NAME_PREFIX", NSFX: "NAME_SUFFIX", OBJE: "OBJECT", OCCU: "OCCUPATION", ORDI: "ORDINANCE", ORDN: "ORDINATION", PAGE: "PAGE", PEDI: "PEDIGREE", PHON: "PHONE", PLAC: "PLACE", POST: "POSTAL_CODE", PROB: "PROBATE", PROP: "PROPERTY", PUBL: "PUBLICATION", QUAY: "QUALITY_OF_DATA", REFN: "REFERENCE", RELA: "RELATIONSHIP", RELI: "RELIGION", REPO: "REPOSITORY", RESI: "RESIDENCE", RESN: "RESTRICTION", RETI: "RETIREMENT", RFN: "REC_FILE_NUMBER", RIN: "REC_ID_NUMBER", ROLE: "ROLE", ROMN: "ROMANIZED", SEX: "SEX", SLGC: "SEALING_CHILD", SLGS: "SEALING_SPOUCE", SOUR: "SOURCE", SPFX: "SURN_PREFIX", SSN: "SURN_PREFIX", STAE: "STATE", STAT: "STATUS", SUBM: "SUBMITTER", SUBN: "SUBMISSION", SURN: "SURNAME", TEMP: "TEMPLE", TEXT: "TEXT", TIME: "TIME", TITL: "TITLE", TRLR: "TRAILER", TYPE: "TYPE", VERS: "VERSION", WIFE: "WIFE", WILL: "WILL", WWW: "WEB" }; //#endregion //#region lib/tokenize.ts const cDigit = "0-9"; const rLevel = /* @__PURE__ */ new RegExp(`^([${cDigit}]*)`); const cDelim = /(\s+)/; const rDelim = /* @__PURE__ */ new RegExp(`^([${cDelim}])`); const cAt = "@"; const cAlpha = "A-ZÀ-ÿa-z_"; const cAlphanum = `${cAlpha}${cDigit}`; const cPointerChar = `${cAlpha}${cDigit}${cDelim}#`; const rPointer = /* @__PURE__ */ new RegExp(`^${cAt}([${cAlphanum}])([${cPointerChar}\\-])*${cAt}`); const rTag = /* @__PURE__ */ new RegExp(`^(_?[${cAlphanum}]+)`); const rLineItem = /* @__PURE__ */ new RegExp(/^(.*)/); /** * Lowest-level API to parse-gedcom: parses a single line * of GEDCOM into its constituent tag, level, xref_id, * and so on. It's unlikely that external applications would use this API. * Instead they will more often use `parse`. * * @param buf - One line of GEDCOM data as a string * @returns a line object. */ function tokenize(buf, lineNumber) { function expect(re, message) { const match = buf.match(re); if (!match) throw new Error(`${message} at line ${lineNumber}`); buf = buf.substring(match[0].length); return match[1]; } buf = buf.trimStart(); let xref_id = void 0; const levelStr = expect(rLevel, "Expected level"); if (levelStr.length > 2 || levelStr.length === 2 && levelStr[0] === "0") throw new Error(`Invalid level: ${levelStr} at line ${lineNumber}`); const level = Number.parseInt(levelStr); expect(rDelim, "Expected delimiter after level"); const xref = buf.match(rPointer); if (xref) { xref_id = xref[0]; buf = buf.substring(xref[0].length); expect(rDelim, "Expected delimiter after pointer"); } const tag = expect(rTag, "Expected tag"); const line = { level, tag }; if (xref_id) line.xref_id = xref_id; const plaintext = tag === "CONC" || tag === "CONT" || tag === "NOTE"; const delim = buf.match(rDelim); if (delim) { buf = buf.substring(delim[0].length); const pointer_match = !plaintext && buf.match(rPointer); const value_match = buf.match(rLineItem); if (pointer_match) line.pointer = pointer_match[0]; else if (value_match) line.value = value_match[1]; } return line; } //#endregion //#region lib/parse-to-unist.ts const rTerminator = /(\r|\n|\r\n|\n\r)/g; function lineToNode({ tag, value, xref_id, pointer }) { const node = { type: tag, data: { formal_name: FORMAL_NAMES[tag], ...value !== void 0 ? { value } : {} }, children: [] }; if (xref_id) node.data.xref_id = xref_id; if (pointer) node.data.pointer = pointer; if (tag.startsWith("_")) node.data.custom_tag = true; return node; } function handleContinued({ tag, value, pointer }, head, lineNumber) { if (!(tag === "CONC" || tag === "CONT")) return false; if (pointer) throw new Error(`Cannot concatenate a pointer (CONC/CONT cannot have a pointer value) at line ${lineNumber}`); if (head.data) { if (!head.data.value) head.data.value = ""; if (tag === "CONT") head.data.value += "\n"; if (value) head.data.value += value; } return true; } /** * Parse a string of GEDCOM data into an unist-compatible * abstract syntax tree. This is the core function for transforming * GEDCOM into JSON data that captures all of its detail, but * for practical usage you may also want to run `compact` * on the generated syntax tree to compress attributes. * * **Note**: the AST format uses 'children' to indicate the children * of abstract syntax tree nodes, but these are not equivalent to * parent/child relationships in family data. * * @param input - GEDCOM data as a string * @returns ast */ function parse(input) { const root$3 = { data: {}, type: "root", children: [] }; const lines = input.split(rTerminator).filter((str) => str.trim()); let stack = []; let lastLevel = 0; for (let i = 0; i < lines.length; i++) { const lineNumber = i + 1; const tokens = tokenize(lines[i], lineNumber); if (handleContinued(tokens, stack[stack.length - 1], lineNumber)) continue; const node = lineToNode(tokens); const { level } = tokens; if (level === 0) { root$3.children.push(node); stack = [node]; } else if (lastLevel === level - 1 || level <= lastLevel) { for (let i$1 = 0; i$1 <= lastLevel - level; i$1++) stack.pop(); stack[stack.length - 1].children.push(node); stack.push(node); } else throw new Error(`Illegal nesting at line ${lineNumber}: transition from level ${lastLevel} to ${level}`); lastLevel = level; } return root$3; } //#endregion //#region node_modules/.pnpm/unist-util-is@6.0.0/node_modules/unist-util-is/lib/index.js /** * Generate an assertion from a test. * * Useful if you’re going to test many nodes, for example when creating a * utility where something else passes a compatible test. * * The created function is a bit faster because it expects valid input only: * a `node`, `index`, and `parent`. * * @param {Test} test * * when nullish, checks if `node` is a `Node`. * * when `string`, works like passing `(node) => node.type === test`. * * when `function` checks if function passed the node is true. * * when `object`, checks that all keys in test are in node, and that they have (strictly) equal values. * * when `array`, checks if any one of the subtests pass. * @returns {Check} * An assertion. */ const convert = (function(test) { if (test === null || test === void 0) return ok; if (typeof test === "function") return castFactory(test); if (typeof test === "object") return Array.isArray(test) ? anyFactory(test) : propsFactory(test); if (typeof test === "string") return typeFactory(test); throw new Error("Expected function, string, or object as test"); }); /** * @param {Array<Props | TestFunction | string>} tests * @returns {Check} */ function anyFactory(tests) { /** @type {Array<Check>} */ const checks = []; let index = -1; while (++index < tests.length) checks[index] = convert(tests[index]); return castFactory(any); /** * @this {unknown} * @type {TestFunction} */ function any(...parameters) { let index$1 = -1; while (++index$1 < checks.length) if (checks[index$1].apply(this, parameters)) return true; return false; } } /** * Turn an object into a test for a node with a certain fields. * * @param {Props} check * @returns {Check} */ function propsFactory(check) { const checkAsRecord = check; return castFactory(all); /** * @param {Node} node * @returns {boolean} */ function all(node) { const nodeAsRecord = node; /** @type {string} */ let key; for (key in check) if (nodeAsRecord[key] !== checkAsRecord[key]) return false; return true; } } /** * Turn a string into a test for a node with a certain type. * * @param {string} check * @returns {Check} */ function typeFactory(check) { return castFactory(type); /** * @param {Node} node */ function type(node) { return node && node.type === check; } } /** * Turn a custom test into a test for a node that passes that test. * * @param {TestFunction} testFunction * @returns {Check} */ function castFactory(testFunction) { return check; /** * @this {unknown} * @type {Check} */ function check(value, index, parent) { return Boolean(looksLikeANode(value) && testFunction.call(this, value, typeof index === "number" ? index : void 0, parent || void 0)); } } function ok() { return true; } /** * @param {unknown} value * @returns {value is Node} */ function looksLikeANode(value) { return value !== null && typeof value === "object" && "type" in value; } //#endregion //#region node_modules/.pnpm/unist-util-remove@4.0.0/node_modules/unist-util-remove/lib/index.js /** * @typedef {import('unist').Node} Node * @typedef {import('unist').Parent} Parent * @typedef {import('unist-util-is').Test} Test */ /** * @typedef Options * Configuration. * @property {boolean | null | undefined} [cascade=true] * Whether to drop parent nodes if they had children, but all their children * were filtered out (default: `true`). */ /** * Change the given `tree` by removing all nodes that pass `test`. * * `tree` itself is never tested. * The tree is walked in preorder (NLR), visiting the node itself, then its * head, etc. * * @overload * @param {Node} node * @param {Test} [test] * @returns {undefined} * * @overload * @param {Node} node * @param {Options | null | undefined} options * @param {Test} [test] * @returns {undefined} * * @param {Node} tree * Tree to change. * @param {Options | Test} options * Configuration (optional). * @param {Test} [test] * `unist-util-is` compatible test. * @returns {undefined} * Nothing. */ function remove(tree, options, test) { const is = convert(test || options); let cascade = true; if (options && typeof options === "object" && "cascade" in options && typeof options.cascade === "boolean") cascade = options.cascade; preorder$1(tree); /** * Check and remove nodes recursively in preorder. * For each composite node, modify its children array in-place. * * @param {Node} node * @param {number | undefined} [index] * @param {Parent | undefined} [parent] * @returns {boolean} */ function preorder$1(node, index, parent) { if (node !== tree && is(node, index, parent)) return false; if ("children" in node && Array.isArray(node.children)) { const nodeAsParent = node; const children = nodeAsParent.children; let oldChildIndex = -1; let newChildIndex = 0; if (children.length > 0) { while (++oldChildIndex < children.length) if (preorder$1(children[oldChildIndex], oldChildIndex, nodeAsParent)) children[newChildIndex++] = children[oldChildIndex]; if (node !== tree && cascade && !newChildIndex) return false; children.length = newChildIndex; } } return true; } } //#endregion //#region node_modules/.pnpm/unist-util-visit-parents@6.0.1/node_modules/unist-util-visit-parents/lib/color.node.js /** * @param {string} d * @returns {string} */ function color(d) { return "\x1B[33m" + d + "\x1B[39m"; } //#endregion //#region node_modules/.pnpm/unist-util-visit-parents@6.0.1/node_modules/unist-util-visit-parents/lib/index.js /** * @typedef {import('unist').Node} UnistNode * @typedef {import('unist').Parent} UnistParent */ /** * @typedef {Exclude<import('unist-util-is').Test, undefined> | undefined} Test * Test from `unist-util-is`. * * Note: we have remove and add `undefined`, because otherwise when generating * automatic `.d.ts` files, TS tries to flatten paths from a local perspective, * which doesn’t work when publishing on npm. */ /** * @typedef {( * Fn extends (value: any) => value is infer Thing * ? Thing * : Fallback * )} Predicate * Get the value of a type guard `Fn`. * @template Fn * Value; typically function that is a type guard (such as `(x): x is Y`). * @template Fallback * Value to yield if `Fn` is not a type guard. */ /** * @typedef {( * Check extends null | undefined // No test. * ? Value * : Value extends {type: Check} // String (type) test. * ? Value * : Value extends Check // Partial test. * ? Value * : Check extends Function // Function test. * ? Predicate<Check, Value> extends Value * ? Predicate<Check, Value> * : never * : never // Some other test? * )} MatchesOne * Check whether a node matches a primitive check in the type system. * @template Value * Value; typically unist `Node`. * @template Check * Value; typically `unist-util-is`-compatible test, but not arrays. */ /** * @typedef {( * Check extends Array<any> * ? MatchesOne<Value, Check[keyof Check]> * : MatchesOne<Value, Check> * )} Matches * Check whether a node matches a check in the type system. * @template Value * Value; typically unist `Node`. * @template Check * Value; typically `unist-util-is`-compatible test. */ /** * @typedef {0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10} Uint * Number; capped reasonably. */ /** * @typedef {I extends 0 ? 1 : I extends 1 ? 2 : I extends 2 ? 3 : I extends 3 ? 4 : I extends 4 ? 5 : I extends 5 ? 6 : I extends 6 ? 7 : I extends 7 ? 8 : I extends 8 ? 9 : 10} Increment * Increment a number in the type system. * @template {Uint} [I=0] * Index. */ /** * @typedef {( * Node extends UnistParent * ? Node extends {children: Array<infer Children>} * ? Child extends Children ? Node : never * : never * : never * )} InternalParent * Collect nodes that can be parents of `Child`. * @template {UnistNode} Node * All node types in a tree. * @template {UnistNode} Child * Node to search for. */ /** * @typedef {InternalParent<InclusiveDescendant<Tree>, Child>} Parent * Collect nodes in `Tree` that can be parents of `Child`. * @template {UnistNode} Tree * All node types in a tree. * @template {UnistNode} Child * Node to search for. */ /** * @typedef {( * Depth extends Max * ? never * : * | InternalParent<Node, Child> * | InternalAncestor<Node, InternalParent<Node, Child>, Max, Increment<Depth>> * )} InternalAncestor * Collect nodes in `Tree` that can be ancestors of `Child`. * @template {UnistNode} Node * All node types in a tree. * @template {UnistNode} Child * Node to search for. * @template {Uint} [Max=10] * Max; searches up to this depth. * @template {Uint} [Depth=0] * Current depth. */ /** * @typedef {InternalAncestor<InclusiveDescendant<Tree>, Child>} Ancestor * Collect nodes in `Tree` that can be ancestors of `Child`. * @template {UnistNode} Tree * All node types in a tree. * @template {UnistNode} Child * Node to search for. */ /** * @typedef {( * Tree extends UnistParent * ? Depth extends Max * ? Tree * : Tree | InclusiveDescendant<Tree['children'][number], Max, Increment<Depth>> * : Tree * )} InclusiveDescendant * Collect all (inclusive) descendants of `Tree`. * * > 👉 **Note**: for performance reasons, this seems to be the fastest way to * > recurse without actually running into an infinite loop, which the * > previous version did. * > * > Practically, a max of `2` is typically enough assuming a `Root` is * > passed, but it doesn’t improve performance. * > It gets higher with `List > ListItem > Table > TableRow > TableCell`. * > Using up to `10` doesn’t hurt or help either. * @template {UnistNode} Tree * Tree type. * @template {Uint} [Max=10] * Max; searches up to this depth. * @template {Uint} [Depth=0] * Current depth. */ /** * @typedef {'skip' | boolean} Action * Union of the action types. * * @typedef {number} Index * Move to the sibling at `index` next (after node itself is completely * traversed). * * Useful if mutating the tree, such as removing the node the visitor is * currently on, or any of its previous siblings. * Results less than 0 or greater than or equal to `children.length` stop * traversing the parent. * * @typedef {[(Action | null | undefined | void)?, (Index | null | undefined)?]} ActionTuple * List with one or two values, the first an action, the second an index. * * @typedef {Action | ActionTuple | Index | null | undefined | void} VisitorResult * Any value that can be returned from a visitor. */ /** * @callback Visitor * Handle a node (matching `test`, if given). * * Visitors are free to transform `node`. * They can also transform the parent of node (the last of `ancestors`). * * Replacing `node` itself, if `SKIP` is not returned, still causes its * descendants to be walked (which is a bug). * * When adding or removing previous siblings of `node` (or next siblings, in * case of reverse), the `Visitor` should return a new `Index` to specify the * sibling to traverse after `node` is traversed. * Adding or removing next siblings of `node` (or previous siblings, in case * of reverse) is handled as expected without needing to return a new `Index`. * * Removing the children property of an ancestor still results in them being * traversed. * @param {Visited} node * Found node. * @param {Array<VisitedParents>} ancestors * Ancestors of `node`. * @returns {VisitorResult} * What to do next. * * An `Index` is treated as a tuple of `[CONTINUE, Index]`. * An `Action` is treated as a tuple of `[Action]`. * * Passing a tuple back only makes sense if the `Action` is `SKIP`. * When the `Action` is `EXIT`, that action can be returned. * When the `Action` is `CONTINUE`, `Index` can be returned. * @template {UnistNode} [Visited=UnistNode] * Visited node type. * @template {UnistParent} [VisitedParents=UnistParent] * Ancestor type. */ /** * @typedef {Visitor<Matches<InclusiveDescendant<Tree>, Check>, Ancestor<Tree, Matches<InclusiveDescendant<Tree>, Check>>>} BuildVisitor * Build a typed `Visitor` function from a tree and a test. * * It will infer which values are passed as `node` and which as `parents`. * @template {UnistNode} [Tree=UnistNode] * Tree type. * @template {Test} [Check=Test] * Test type. */ /** @type {Readonly<ActionTuple>} */ const empty = []; /** * Continue traversing as normal. */ const CONTINUE = true; /** * Stop traversing immediately. */ const EXIT = false; /** * Do not traverse this node’s children. */ const SKIP = "skip"; /** * Visit nodes, with ancestral information. * * This algorithm performs *depth-first* *tree traversal* in *preorder* * (**NLR**) or if `reverse` is given, in *reverse preorder* (**NRL**). * * You can choose for which nodes `visitor` is called by passing a `test`. * For complex tests, you should test yourself in `visitor`, as it will be * faster and will have improved type information. * * Walking the tree is an intensive task. * Make use of the return values of the visitor when possible. * Instead of walking a tree multiple times, walk it once, use `unist-util-is` * to check if a node matches, and then perform different operations. * * You can change the tree. * See `Visitor` for more info. * * @overload * @param {Tree} tree * @param {Check} check * @param {BuildVisitor<Tree, Check>} visitor * @param {boolean | null | undefined} [reverse] * @returns {undefined} * * @overload * @param {Tree} tree * @param {BuildVisitor<Tree>} visitor * @param {boolean | null | undefined} [reverse] * @returns {undefined} * * @param {UnistNode} tree * Tree to traverse. * @param {Visitor | Test} test * `unist-util-is`-compatible test * @param {Visitor | boolean | null | undefined} [visitor] * Handle each node. * @param {boolean | null | undefined} [reverse] * Traverse in reverse preorder (NRL) instead of the default preorder (NLR). * @returns {undefined} * Nothing. * * @template {UnistNode} Tree * Node type. * @template {Test} Check * `unist-util-is`-compatible test. */ function visitParents(tree, test, visitor, reverse) { /** @type {Test} */ let check; if (typeof test === "function" && typeof visitor !== "function") { reverse = visitor; visitor = test; } else check = test; const is = convert(check); const step = reverse ? -1 : 1; factory(tree, void 0, [])(); /** * @param {UnistNode} node * @param {number | undefined} index * @param {Array<UnistParent>} parents */ function factory(node, index, parents) { const value = node && typeof node === "object" ? node : {}; if (typeof value.type === "string") { const name = typeof value.tagName === "string" ? value.tagName : typeof value.name === "string" ? value.name : void 0; Object.defineProperty(visit, "name", { value: "node (" + color(node.type + (name ? "<" + name + ">" : "")) + ")" }); } return visit; function visit() { /** @type {Readonly<ActionTuple>} */ let result = empty; /** @type {Readonly<ActionTuple>} */ let subresult; /** @type {number} */ let offset; /** @type {Array<UnistParent>} */ let grandparents; if (!test || is(node, index, parents[parents.length - 1] || void 0)) { result = toResult(visitor(node, parents)); if (result[0] === EXIT) return result; } if ("children" in node && node.children) { const nodeAsParent = node; if (nodeAsParent.children && result[0] !== SKIP) { offset = (reverse ? nodeAsParent.children.length : -1) + step; grandparents = parents.concat(nodeAsParent); while (offset > -1 && offset < nodeAsParent.children.length) { const child = nodeAsParent.children[offset]; subresult = factory(child, offset, grandparents)(); if (subresult[0] === EXIT) return subresult; offset = typeof subresult[1] === "number" ? subresult[1] : offset + step; } } } return result; } } } /** * Turn a return value into a clean result. * * @param {VisitorResult} value * Valid return values from visitors. * @returns {Readonly<ActionTuple>} * Clean result. */ function toResult(value) { if (Array.isArray(value)) return value; if (typeof value === "number") return [CONTINUE, value]; return value === null || value === void 0 ? empty : [value]; } //#endregion //#region lib/unist-compact.ts function addValue(data, path, value) { if (!data[path]) data[path] = value; else data["+" + path] = (data["+" + path] || []).concat(value); } /** * This applies an opinionated transformation to GEDCOM data, * making it easier for common use cases. In the raw GEDCOM * AST, attributes like birth years are represented as nodes. * This transformation compresses those attributes into properties * of a node’s `.data` member. * * Here's how this transformation works: * * For example, let's say you have this content: * * ``` * 0 INDI * 1 BIRT * 2 DATE 12 MAY 1920 * 1 DEAT * 2 DATE 1960 * ``` * * The output of `parse` will create nodes for the INDI, BIRT, DATE, * DEAT, and DATE objects. If you simply want to ask 'when was this individual * alive?' This can be a difficult question to answer. Compact will transform * those nodes into a simplified form: * * ```js * { * type: "INDI", * data: { * formal_name: "INDIVIDUAL", * "BIRTH/DATE": "12 MAY 1920", * "DEATH/DATE": "1960", * }, * value: undefined, * children: [], * } * ``` * * If there are multiple values for something like a birth date, they'll be * included in an additional property with a `+`: * * { * "BIRTH/DATE": "12 MAY 1920", * "+BIRTH/DATE": ["13 MAY 1920"], * } * * This also removes nodes from the syntax tree that are unlikely * to have any use for genealogical or visualization applications. * * @param root - a parsed GEDCOM document * @param removeNodes - a list of nodes that should be removed. * @returns the same document, with attributes compacted. */ function compact(root$3, removeNodes = [ "TRLR", "SUBM", "SUBN", "HEAD", "NOTE", "SOUR" ]) { remove(root$3, removeNodes); for (const child of root$3.children) { if (!child.data) child.data = {}; visitParents(child, (node, ancestors) => { const path = ancestors.slice(1).concat(node).map((a) => a.data?.formal_name || a.type).join("/"); if (node.data?.value) addValue(child.data, path, node.data.value); else if (node.data?.pointer) addValue(child.data, `@${path}`, node.data.pointer); }); child.children = []; } return root$3; } //#endregion //#region lib/to-d3-force.ts function removeBidirectionals(linkIndex, links) { const pairs = [ ["@HUSBAND", "@FAMILY_SPOUSE"], ["@WIFE", "@FAMILY_SPOUSE"], ["@FAMILY_CHILD", "@CHILD"] ]; for (const [_$15, group] of linkIndex) for (const pair of pairs) { const [a, b] = pair.map((key) => group.find((elem) => elem.value === key)); if (a && b) links.splice(links.indexOf(a), 1); } } /** * Transforms a GEDCOM AST - likely produced using * `parse` - into a data structure suited for * a [D3 force directed graph](https://observablehq.com/@d3/force-directed-graph) * layout. * * @param root - Parsed GEDCOM content * @returns D3-friendly JSON */ function toD3Force(root$3) { const nodes = compact(root$3).children; const index = new Set(nodes.map((child) => child.data?.xref_id).filter(Boolean)); const links = []; const linkIndex = /* @__PURE__ */ new Map(); for (const node of nodes) { if (!node.data) continue; for (const [key, value] of Object.entries(node.data).filter(([key$1, _$15]) => key$1.startsWith("@"))) { if (!index.has(value)) throw new Error(`Undefined reference: ${value}`); if (!node.data?.xref_id) throw new Error(`Link from node with no xref id`); const source = node.data?.xref_id; const target = value; const link = { source, target, value: key }; links.push(link); const idxKey = [source, target].sort().join("/"); if (!linkIndex.has(idxKey)) linkIndex.set(idxKey, [link]); else linkIndex.get(idxKey).push(link); } } removeBidirectionals(linkIndex, links); return { nodes, links }; } //#endregion //#region node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/lodash.js var require_lodash$2 = /* @__PURE__ */ __commonJSMin(((exports, module) => { (function() { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined$1; /** Used as the semantic version number. */ var VERSION = "4.17.21"; /** Used as the size to enable large array optimizations. */ var LARGE_ARRAY_SIZE$2 = 200; /** Error message constants. */ var CORE_ERROR_TEXT = "Unsupported core-js use. Try https://npms.io/search?q=ponyfill.", FUNC_ERROR_TEXT$1 = "Expected a function", INVALID_TEMPL_VAR_ERROR_TEXT = "Invalid `variable` option passed into `_.template`"; /** Used to stand-in for `undefined` hash values. */ var HASH_UNDEFINED$3 = "__lodash_hash_undefined__"; /** Used as the maximum memoize cache size. */ var MAX_MEMOIZE_SIZE$1 = 500; /** Used as the internal argument placeholder. */ var PLACEHOLDER = "__lodash_placeholder__"; /** Used to compose bitmasks for cloning. */ var CLONE_DEEP_FLAG$1 = 1, CLONE_FLAT_FLAG$1 = 2, CLONE_SYMBOLS_FLAG$2 = 4; /** Used to compose bitmasks for value comparisons. */ var COMPARE_PARTIAL_FLAG$6 = 1, COMPARE_UNORDERED_FLAG$4 = 2; /** Used to compose bitmasks for function metadata. */ var WRAP_BIND_FLAG = 1, WRAP_BIND_KEY_FLAG = 2, WRAP_CURRY_BOUND_FLAG = 4, WRAP_CURRY_FLAG = 8, WRAP_CURRY_RIGHT_FLAG = 16, WRAP_PARTIAL_FLAG = 32, WRAP_PARTIAL_RIGHT_FLAG = 64, WRAP_ARY_FLAG = 128, WRAP_REARG_FLAG = 256, WRAP_FLIP_FLAG = 512; /** Used as default options for `_.truncate`. */ var DEFAULT_TRUNC_LENGTH = 30, DEFAULT_TRUNC_OMISSION = "..."; /** Used to detect hot functions by number of calls within a span of milliseconds. */ var HOT_COUNT$1 = 800, HOT_SPAN$1 = 16; /** Used to indicate the type of lazy iteratees. */ var LAZY_FILTER_FLAG = 1, LAZY_MAP_FLAG = 2, LAZY_WHILE_FLAG = 3; /** Used as references for various `Number` constants. */ var INFINITY$2 = Infinity, MAX_SAFE_INTEGER$2 = 9007199254740991, MAX_INTEGER = 17976931348623157e292, NAN = NaN; /** Used as references for the maximum length and index of an array. */ var MAX_ARRAY_LENGTH = 4294967295, MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; /** Used to associate wrap methods with their bit flags. */ var wrapFlags = [ ["ary", WRAP_ARY_FLAG], ["bind", WRAP_BIND_FLAG], ["bindKey", WRAP_BIND_KEY_FLAG], ["curry", WRAP_CURRY_FLAG], ["curryRight", WRAP_CURRY_RIGHT_FLAG], ["flip", WRAP_FLIP_FLAG], ["partial", WRAP_PARTIAL_FLAG], ["partialRight", WRAP_PARTIAL_RIGHT_FLAG], ["rearg", WRAP_REARG_FLAG] ]; /** `Object#toString` result references. */ var argsTag$4 = "[object Arguments]", arrayTag$3 = "[object Array]", asyncTag$1 = "[object AsyncFunction]", boolTag$4 = "[object Boolean]", dateTag$4 = "[object Date]", domExcTag = "[object DOMException]", errorTag$3 = "[object Error]", funcTag$3 = "[object Function]", genTag$2 = "[object GeneratorFunction]", mapTag$8 = "[object Map]", numberTag$4 = "[object Number]", nullTag$1 = "[object Null]", objectTag$4 = "[object Object]", promiseTag$1 = "[object Promise]", proxyTag$1 = "[object Proxy]", regexpTag$4 = "[object RegExp]", setTag$8 = "[object Set]", stringTag$5 = "[object String]", symbolTag$4 = "[object Symbol]", undefinedTag$1 = "[object Undefined]", weakMapTag$3 = "[object WeakMap]", weakSetTag = "[object WeakSet]"; var arrayBufferTag$4 = "[object ArrayBuffer]", dataViewTag$5 = "[object DataView]", float32Tag$3 = "[object Float32Array]", float64Tag$3 = "[object Float64Array]", int8Tag$3 = "[object Int8Array]", int16Tag$3 = "[object Int16Array]", int32Tag$3 = "[object Int32Array]", uint8Tag$3 = "[object Uint8Array]", uint8ClampedTag$3 = "[object Uint8ClampedArray]", uint16Tag$3 = "[object Uint16Array]", uint32Tag$3 = "[object Uint32Array]"; /** Used to match empty string literals in compiled template source. */ var reEmptyStringLeading = /\b__p \+= '';/g, reEmptyStringMiddle = /\b(__p \+=) '' \+/g, reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; /** Used to match HTML entities and HTML characters. */ var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g, reUnescapedHtml = /[&<>"']/g, reHasEscapedHtml = RegExp(reEscapedHtml.source), reHasUnescapedHtml = RegExp(reUnescapedHtml.source); /** Used to match template delimiters. */ var reEscape = /<%-([\s\S]+?)%>/g, reEvaluate = /<%([\s\S]+?)%>/g, reInterpolate = /<%=([\s\S]+?)%>/g; /** Used to match property names within property paths. */ var reIsDeepProp$1 = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, reIsPlainProp$1 = /^\w*$/, rePropName$1 = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; /** * Used to match `RegExp` * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). */ var reRegExpChar$1 = /[\\^$.*+?()[\]{}|]/g, reHasRegExpChar = RegExp(reRegExpChar$1.source); /** Used to match leading whitespace. */ var reTrimStart = /^\s+/; /** Used to match a single whitespace character. */ var reWhitespace = /\s/; /** Used to match wrap detail comments. */ var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/, reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/, reSplitDetails = /,? & /; /** Used to match words composed of alphanumeric characters. */ var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g; /** * Used to validate the `validate` option in `_.template` variable. * * Forbids characters which could potentially change the meaning of the function argument definition: * - "()," (modification of function parameters) * - "=" (default value) * - "[]{}" (destructuring of function parameters) * - "/" (beginning of a comment) * - whitespace */ var reForbiddenIdentifierChars = /[()=,{}\[\]\/\s]/; /** Used to match backslashes in property paths. */ var reEscapeChar$1 = /\\(\\)?/g; /** * Used to match * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components). */ var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; /** Used to match `RegExp` flags from their coerced string values. */ var reFlags$1 = /\w*$/; /** Used to detect bad signed hexadecimal string values. */ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; /** Used to detect binary string values. */ var reIsBinary = /^0b[01]+$/i; /** Used to detect host constructors (Safari). */ var reIsHostCtor$1 = /^\[object .+?Constructor\]$/; /** Used to detect octal string values. */ var reIsOctal = /^0o[0-7]+$/i; /** Used to detect unsigned integer values. */ var reIsUint$1 = /^(?:0|[1-9]\d*)$/; /** Used to match Latin Unicode letters (excluding mathematical operators). */ var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g; /** Used to ensure capturing order of template delimiters. */ var reNoMatch = /($^)/; /** Used to match unescaped characters in compiled string literals. */ var reUnescapedString = /['\n\r\u2028\u2029\\]/g; /** Used to compose unicode character classes. */ var rsAstralRange$1 = "\\ud800-\\udfff", rsComboRange$1 = "\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff", rsDingbatRange = "\\u2700-\\u27bf", rsLowerRange = "a-z\\xdf-\\xf6\\xf8-\\xff", rsMathOpRange = "\\xac\\xb1\\xd7\\xf7", rsNonCharRange = "\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf", rsPunctuationRange = "\\u2000-\\u206f", rsSpaceRange = " \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000", rsUpperRange = "A-Z\\xc0-\\xd6\\xd8-\\xde", rsVarRange$1 = "\\ufe0e\\ufe0f", rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange; /** Used to compose unicode capture groups. */ var rsApos = "['’]", rsAstral$1 = "[" + rsAstralRange$1 + "]", rsBreak = "[" + rsBreakRange + "]", rsCombo$1 = "[" + rsComboRange$1 + "]", rsDigits = "\\d+", rsDingbat = "[" + rsDingbatRange + "]", rsLower = "[" + rsLowerRange + "]", rsMisc = "[^" + rsAstralRange$1 + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + "]", rsFitz$1 = "\\ud83c[\\udffb-\\udfff]", rsModifier$1 = "(?:" + rsCombo$1 + "|" + rsFitz$1 + ")", rsNonAstral$1 = "[^" + rsAstralRange$1 + "]", rsRegional$1 = "(?:\\ud83c[\\udde6-\\uddff]){2}", rsSurrPair$1 = "[\\ud800-\\udbff][\\udc00-\\udfff]", rsUpper = "[" + rsUpperRange + "]", rsZWJ$1 = "\\u200d"; /** Used to compose unicode regexes. */ var rsMiscLower = "(?:" + rsLower + "|" + rsMisc + ")", rsMiscUpper = "(?:" + rsUpper + "|" + rsMisc + ")", rsOptContrLower = "(?:" + rsApos + "(?:d|ll|m|re|s|t|ve))?", rsOptContrUpper = "(?:" + rsApos + "(?:D|LL|M|RE|S|T|VE))?", reOptMod$1 = rsModifier$1 + "?", rsOptVar$1 = "[" + rsVarRange$1 + "]?", rsOptJoin$1 = "(?:" + rsZWJ$1 + "(?:" + [ rsNonAstral$1, rsRegional$1, rsSurrPair$1 ].join("|") + ")" + rsOptVar$1 + reOptMod$1 + ")*", rsOrdLower = "\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])", rsOrdUpper = "\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])", rsSeq$1 = rsOptVar$1 + reOptMod$1 + rsOptJoin$1, rsEmoji = "(?:" + [ rsDingbat, rsRegional$1, rsSurrPair$1 ].join("|") + ")" + rsSeq$1, rsSymbol$1 = "(?:" + [ rsNonAstral$1 + rsCombo$1 + "?", rsCombo$1, rsRegional$1, rsSurrPair$1, rsAstral$1 ].join("|") + ")"; /** Used to match apostrophes. */ var reApos = RegExp(rsApos, "g"); /** * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). */ var reComboMark = RegExp(rsCombo$1, "g"); /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ var reUnicode$1 = RegExp(rsFitz$1 + "(?=" + rsFitz$1 + ")|" + rsSymbol$1 + rsSeq$1, "g"); /** Used to match complex or compound words. */ var reUnicodeWord = RegExp([ rsUpper + "?" + rsLower + "+" + rsOptContrLower + "(?=" + [ rsBreak, rsUpper, "$" ].join("|") + ")", rsMiscUpper + "+" + rsOptContrUpper + "(?=" + [ rsBreak, rsUpper + rsMiscLower, "$" ].join("|") + ")", rsUpper + "?" + rsMiscLower + "+" + rsOptContrLower, rsUpper + "+" + rsOptContrUpper, rsOrdUpper, rsOrdLower, rsDigits, rsEmoji ].join("|"), "g"); /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ var reHasUnicode$1 = RegExp("[" + rsZWJ$1 + rsAstralRange$1 + rsComboRange$1 + rsVarRange$1 + "]"); /** Used to detect strings that need a more robust regexp to match words. */ var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/; /** Used to assign default `context` object properties. */ var contextProps = [ "Array", "Buffer", "DataView", "Date", "Error", "Float32Array", "Float64Array", "Function", "Int8Array", "Int16Array", "Int32Array", "Map", "Math", "Object", "Promise", "RegExp", "Set", "String", "Symbol", "TypeError", "Uint8Array", "Uint8ClampedArray", "Uint16Array", "Uint32Array", "WeakMap", "_", "clearTimeout", "isFinite", "parseInt", "setTimeout" ]; /** Used to make template sourceURLs easier to identify. */ var templateCounter = -1; /** Used to identify `toStringTag` values of typed arrays. */ var typedArrayTags$1 = {}; typedArrayTags$1[float32Tag$3] = typedArrayTags$1[float64Tag$3] = typedArrayTags$1[int8Tag$3] = typedArrayTags$1[int16Tag$3] = typedArrayTags$1[int32Tag$3] = typedArrayTags$1[uint8Tag$3] = typedArrayTags$1[uint8ClampedTag$3] = typedArrayTags$1[uint16Tag$3] = typedArrayTags$1[uint32Tag$3] = true; typedArrayTags$1[argsTag$4] = typedArrayTags$1[arrayTag$3] = typedArrayTags$1[arrayBufferTag$4] = typedArrayTags$1[boolTag$4] = typedArrayTags$1[dataViewTag$5] = typedArrayTags$1[dateTag$4] = typedArrayTags$1[errorTag$3] = typedArrayTags$1[funcTag$3] = typedArrayTags$1[mapTag$8] = typedArrayTags$1[numberTag$4] = typedArrayTags$1[objectTag$4] = typedArrayTags$1[regexpTag$4] = typedArrayTags$1[setTag$8] = typedArrayTags$1[stringTag$5] = typedArrayTags$1[weakMapTag$3] = false; /** Used to identify `toStringTag` values supported by `_.clone`. */ var cloneableTags$1 = {}; cloneableTags$1[argsTag$4] = cloneableTags$1[arrayTag$3] = cloneableTags$1[arrayBufferTag$4] = cloneableTags$1[dataViewTag$5] = cloneableTags$1[boolTag$4] = cloneableTags$1[dateTag$4] = cloneableTags$1[float32Tag$3] = cloneableTags$1[float64Tag$3] = cloneableTags$1[int8Tag$3] = cloneableTags$1[int16Tag$3] = cloneableTags$1[int32Tag$3] = cloneableTags$1[mapTag$8] = cloneableTags$1[numberTag$4] = cloneableTags$1[objectTag$4] = cloneableTags$1[regexpTag$4] = cloneableTags$1[setTag$8] = cloneableTags$1[stringTag$5] = cloneableTags$1[symbolTag$4] = cloneableTags$1[uint8Tag$3] = cloneableTags$1[uint8ClampedTag$3] = cloneableTags$1[uint16Tag$3] = cloneableTags$1[uint32Tag$3] = true; cloneableTags$1[errorTag$3] = cloneableTags$1[funcTag$3] = cloneableTags$1[weakMapTag$3] = false; /** Used to map Latin Unicode letters to basic Latin letters. */ var deburredLetters = { "À": "A", "Á": "A", "Â": "A", "Ã": "A", "Ä": "A", "Å": "A", "à": "a", "á": "a", "â": "a", "ã": "a", "ä": "a", "å": "a", "Ç": "C", "ç": "c", "Ð": "D", "ð": "d", "È": "E", "É": "E", "Ê": "E", "Ë": "E", "è": "e", "é": "e", "ê": "e", "ë": "e", "Ì": "I", "Í": "I", "Î": "I", "Ï": "I", "ì": "i", "í": "i", "î": "i", "ï": "i", "Ñ": "N", "ñ": "n", "Ò": "O", "Ó": "O", "Ô": "O", "Õ": "O", "Ö": "O", "Ø": "O", "ò": "o", "ó": "o", "ô": "o", "õ": "o", "ö": "o", "ø": "o", "Ù": "U", "Ú": "U", "Û": "U", "Ü": "U", "ù": "u", "ú": "u", "û": "u", "ü": "u", "Ý": "Y", "ý": "y", "ÿ": "y", "Æ": "Ae", "æ": "ae", "Þ": "Th", "þ": "th", "ß": "ss", "Ā": "A", "Ă": "A", "Ą": "A", "ā": "a", "ă": "a", "ą": "a", "Ć": "C", "Ĉ": "C", "Ċ": "C", "Č": "C", "ć": "c", "ĉ": "c", "ċ": "c", "č": "c", "Ď": "D", "Đ": "D", "ď": "d", "đ": "d", "Ē": "E", "Ĕ": "E", "Ė": "E", "Ę": "E", "Ě": "E", "ē": "e", "ĕ": "e", "ė": "e", "ę": "e", "ě": "e", "Ĝ": "G", "Ğ": "G", "Ġ": "G", "Ģ": "G", "ĝ": "g", "ğ": "g", "ġ": "g", "ģ": "g", "Ĥ": "H", "Ħ": "H", "ĥ": "h", "ħ": "h", "Ĩ": "I", "Ī": "I", "Ĭ": "I", "Į": "I", "İ": "I", "ĩ": "i", "ī": "i", "ĭ": "i", "į": "i", "ı": "i", "Ĵ": "J", "ĵ": "j", "Ķ": "K", "ķ": "k", "ĸ": "k", "Ĺ": "L", "Ļ": "L", "Ľ": "L", "Ŀ": "L", "Ł": "L", "ĺ": "l", "ļ": "l", "ľ": "l", "ŀ": "l", "ł": "l", "Ń": "N", "Ņ": "N", "Ň": "N", "Ŋ": "N", "ń": "n", "ņ": "n", "ň": "n", "ŋ": "n", "Ō": "O", "Ŏ": "O", "Ő": "O", "ō": "o", "ŏ": "o", "ő": "o", "Ŕ": "R", "Ŗ": "R", "Ř": "R", "ŕ": "r", "ŗ": "r", "ř": "r", "Ś": "S", "Ŝ": "S", "Ş": "S", "Š": "S", "ś": "s", "ŝ": "s", "ş": "s", "š": "s", "Ţ": "T", "Ť": "T", "Ŧ": "T", "ţ": "t", "ť": "t", "ŧ": "t", "Ũ": "U", "Ū": "U", "Ŭ": "U", "Ů": "U", "Ű": "U", "Ų": "U", "ũ": "u", "ū": "u", "ŭ": "u", "ů": "u", "ű": "u", "ų": "u", "Ŵ": "W", "ŵ": "w", "Ŷ": "Y", "ŷ": "y", "Ÿ": "Y", "Ź": "Z", "Ż": "Z", "Ž": "Z", "ź": "z", "ż": "z", "ž": "z", "IJ": "IJ", "ij": "ij", "Œ": "Oe", "œ": "oe", "ʼn": "'n", "ſ": "s" }; /** Used to map characters to HTML entities. */ var htmlEscapes = { "&": "&amp;", "<": "&lt;", ">": "&gt;", "\"": "&quot;", "'": "&#39;" }; /** Used to map HTML entities to characters. */ var htmlUnescapes = { "&amp;": "&", "&lt;": "<", "&gt;": ">", "&quot;": "\"", "&#39;": "'" }; /** Used to escape characters for inclusion in compiled string literals. */ var stringEscapes = { "\\": "\\", "'": "'", "\n": "n", "\r": "r", "\u2028": "u2028", "\u2029": "u2029" }; /** Built-in method references without a dependency on `root`. */ var freeParseFloat = parseFloat, freeParseInt = parseInt; /** Detect free variable `global` from Node.js. */ var freeGlobal$3 = typeof global == "object" && global && global.Object === Object && global; /** Detect free variable `self`. */ var freeSelf$1 = typeof self == "object" && self && self.Object === Object && self; /** Used as a reference to the global object. */ var root$3 = freeGlobal$3 || freeSelf$1 || Function("return this")(); /** Detect free variable `exports`. */ var freeExports$3 = typeof exports == "object" && exports && !exports.nodeType && exports; /** Detect free variable `module`. */ var freeModule$3 = freeExports$3 && typeof module == "object" && module && !module.nodeType && module; /** Detect the popular CommonJS extension `module.exports`. */ var moduleExports = freeModule$3 && freeModule$3.exports === freeExports$3; /** Detect free variable `process` from Node.js. */ var freeProcess$1 = moduleExports && freeGlobal$3.process; /** Used to access faster Node.js helpers. */ var nodeUtil$4 = function() { try { var types = freeModule$3 && freeModule$3.require && freeModule$3.require("util").types; if (types) return types; return freeProcess$1 && freeProcess$1.binding && freeProcess$1.binding("util"); } catch (e) {} }(); var nodeIsArrayBuffer = nodeUtil$4 && nodeUtil$4.isArrayBuffer, nodeIsDate = nodeUtil$4 && nodeUtil$4.isDate, nodeIsMap$1 = nodeUtil$4 && nodeUtil$4.isMap, nodeIsRegExp = nodeUtil$4 && nodeUtil$4.isRegExp, nodeIsSet$1 = nodeUtil$4 && nodeUtil$4.isSet, nodeIsTypedArray$1 = nodeUtil$4 && nodeUtil$4.isTypedArray; /** * A faster alternative to `Function#apply`, this function invokes `func` * with the `this` binding of `thisArg` and the arguments of `args`. * * @private * @param {Function} func The function to invoke. * @param {*} thisArg The `this` binding of `func`. * @param {Array} args The arguments to invoke `func` with. * @returns {*} Returns the result of `func`. */ function apply$2(func, thisArg, args) { switch (args.length) { case 0: return func.call(thisArg); case 1: return func.call(thisArg, args[0]); case 2: return func.call(thisArg, args[0], args[1]); case 3: return func.call(thisArg, args[0], args[1], args[2]); } return func.apply(thisArg, args); } /** * A specialized version of `baseAggregator` for arrays. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} setter The function to set `accumulator` values. * @param {Function} iteratee The iteratee to transform keys. * @param {Object} accumulator The initial aggregated object. * @returns {Function} Returns `accumulator`. */ function arrayAggregator(array, setter, iteratee, accumulator) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) { var value = array[index]; setter(accumulator, value, iteratee(value), array); } return accumulator; } /** * A specialized version of `_.forEach` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns `array`. */ function arrayEach$4(array, iteratee) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) if (iteratee(array[index], index, array) === false) break; return array; } /** * A specialized version of `_.forEachRight` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns `array`. */ function arrayEachRight(array, iteratee) { var length = array == null ? 0 : array.length; while (length--) if (iteratee(array[length], length, array) === false) break; return array; } /** * A specialized version of `_.every` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {boolean} Returns `true` if all elements pass the predicate check, * else `false`. */ function arrayEvery(array, predicate) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) if (!predicate(array[index], index, array)) return false; return true; } /** * A specialized version of `_.filter` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {Array} Returns the new filtered array. */ function arrayFilter$3(array, predicate) { var index = -1, length = array == null ? 0 : array.length, resIndex = 0, result = []; while (++index < length) { var value = array[index]; if (predicate(value, index, array)) result[resIndex++] = value; } return result; } /** * A specialized version of `_.includes` for arrays without support for * specifying an index to s