polite-crawler 0.1.3 → 0.2.0
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/README.md +50 -121
- package/build/{browser-CKRNbIDT.mjs → browser-56dBBLec.mjs} +7 -3
- package/build/browser-56dBBLec.mjs.map +1 -0
- package/build/classify.d.mts +50 -2
- package/build/{cli-daemon--cTmq0Z5.mjs → cli-daemon-qS4PH2bM.mjs} +3 -3
- package/build/{cli-daemon--cTmq0Z5.mjs.map → cli-daemon-qS4PH2bM.mjs.map} +1 -1
- package/build/cli-recipes-qbLRVThF.mjs +59 -0
- package/build/cli-recipes-qbLRVThF.mjs.map +1 -0
- package/build/cli.mjs +431 -27
- package/build/cli.mjs.map +1 -1
- package/build/{daemon-fZTE24P5.mjs → daemon-BXBbUrni.mjs} +11 -7
- package/build/daemon-BXBbUrni.mjs.map +1 -0
- package/build/{diff-NQcQqKe9.mjs → diff-CpKN0Jdc.mjs} +7 -3
- package/build/{diff-NQcQqKe9.mjs.map → diff-CpKN0Jdc.mjs.map} +1 -1
- package/build/{extract-ByFfc8Zk.mjs → extract-DqeqiNHb.mjs} +12 -4
- package/build/extract-DqeqiNHb.mjs.map +1 -0
- package/build/{html-BACljlkf.d.mts → html-DMgIeQfJ.d.mts} +16 -2
- package/build/html.d.mts +1 -2
- package/build/index.d.mts +4227 -40
- package/build/index.mjs +17 -901
- package/build/{log-Dx-wXjJl.mjs → log-CmBWcyQm.mjs} +5 -1
- package/build/log-CmBWcyQm.mjs.map +1 -0
- package/build/mcp-package-Y0bREnOS.mjs +40 -0
- package/build/mcp-package-Y0bREnOS.mjs.map +1 -0
- package/build/{ollama-BJxkjny4.mjs → ollama-D1xRh3hY.mjs} +7 -3
- package/build/ollama-D1xRh3hY.mjs.map +1 -0
- package/build/{open-C4fhXJgD.mjs → open-CEo22Hpu.mjs} +84 -296
- package/build/open-CEo22Hpu.mjs.map +1 -0
- package/build/politeness.d.mts +366 -2
- package/build/recipe-B2SkepDZ.mjs +285 -0
- package/build/recipe-B2SkepDZ.mjs.map +1 -0
- package/build/recipe-product-CyZE3Ukd.mjs +914 -0
- package/build/recipe-product-CyZE3Ukd.mjs.map +1 -0
- package/build/{render-C1CUraWF.mjs → render-CKE2LILH.mjs} +10 -3
- package/build/render-CKE2LILH.mjs.map +1 -0
- package/build/robots.d.mts +143 -2
- package/build/robots.mjs +1 -1
- package/build/robots.mjs.map +1 -1
- package/build/{rolldown-runtime-D7D4PA-g.mjs → rolldown-runtime-8H4AJuhK.mjs} +1 -0
- package/build/{runtime-JToRO63o.mjs → runtime-C_2BQibH.mjs} +84 -18
- package/build/runtime-C_2BQibH.mjs.map +1 -0
- package/build/signals.d.mts +45 -2
- package/build/{transformers-BQMlaGj4.mjs → transformers-BNiuiLxT.mjs} +3 -3
- package/build/transformers-BNiuiLxT.mjs.map +1 -0
- package/build/{version-ntbY-6wh.mjs → version-Djva7JkN.mjs} +7 -2
- package/build/version-Djva7JkN.mjs.map +1 -0
- package/build/{wacz-BFNG42Kt.mjs → wacz-DKk2HBmx.mjs} +4 -4
- package/build/{wacz-BFNG42Kt.mjs.map → wacz-DKk2HBmx.mjs.map} +1 -1
- package/build/{warc-CVS0t1fW.mjs → warc-C_ew76bV.mjs} +4 -4
- package/build/{warc-CVS0t1fW.mjs.map → warc-C_ew76bV.mjs.map} +1 -1
- package/build/{webbotauth-CjJdTAfE.mjs → webbotauth-Dq_dA_u3.mjs} +2 -2
- package/build/webbotauth-Dq_dA_u3.mjs.map +1 -0
- package/package.json +5 -11
- package/build/browser-CKRNbIDT.mjs.map +0 -1
- package/build/classify-CrfyXcwo.d.mts +0 -51
- package/build/daemon-DP4EqjFL.d.mts +0 -3772
- package/build/daemon-fZTE24P5.mjs.map +0 -1
- package/build/extract-ByFfc8Zk.mjs.map +0 -1
- package/build/index.mjs.map +0 -1
- package/build/log-Dx-wXjJl.mjs.map +0 -1
- package/build/loopback-C_QYowSf.mjs +0 -22
- package/build/loopback-C_QYowSf.mjs.map +0 -1
- package/build/mcp.d.mts +0 -199
- package/build/mcp.mjs +0 -1555
- package/build/mcp.mjs.map +0 -1
- package/build/ollama-BJxkjny4.mjs.map +0 -1
- package/build/open-C4fhXJgD.mjs.map +0 -1
- package/build/politeness-yI3xBEx9.d.mts +0 -367
- package/build/render-C1CUraWF.mjs.map +0 -1
- package/build/robots-R-qaEBOb.d.mts +0 -144
- package/build/runtime-JToRO63o.mjs.map +0 -1
- package/build/signals-BHpy2xb2.d.mts +0 -46
- package/build/transformers-BQMlaGj4.mjs.map +0 -1
- package/build/urls-BTDSgDLC.d.mts +0 -16
- package/build/version-ntbY-6wh.mjs.map +0 -1
- package/build/webbotauth-CjJdTAfE.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract-DqeqiNHb.mjs","names":[],"sources":["../src/extract.ts"],"sourcesContent":["import type { VersionText } from \"./docs.ts\";\nimport type { Archived } from \"./fallback.ts\";\nimport { archivedNote, archivedOf } from \"./fallback.ts\";\nimport type { Folded } from \"./fold.ts\";\nimport { fold, foldText } from \"./fold.ts\";\nimport { typesOf } from \"./html.ts\";\nimport type { CrawlRuntime } from \"./runtime.ts\";\n// the time travel of `read` and `verify` chooses the version, so the three agree\nimport { HELD_BACK, isHeldBack, isoTime, recordOverride, versionAtTime } from \"./runtime.ts\";\nimport type { AiInput } from \"./signals.ts\";\nimport { canonicalUrl } from \"./urls.ts\";\n\n/**\n * The field check takes the values that a caller proposes for the fields of a stored page. It finds\n * each value in the stored text or in the JSON-LD. A model or a person gives the values. The check\n * does not make values: it only checks and locates the values that it gets.\n *\n * Each field gets one status:\n *\n * - `verified`: the stored text holds the exact value. The result gives the span (or the JSON-LD\n * path) and the capture.\n * - `normalized`: the stored text holds the value under a stated normalization, for example a\n * different number format. The result names the normalization and gives the span of the stored text.\n * - `ambiguous`: the value matches, but the stored text does not give one meaning. The result gives\n * each span, and it does not choose one.\n * - `not-found`: the stored text does not hold the value.\n * - `held-back`: the page asked not to be AI input. The result tells nothing about the value.\n * - `invalid`: the value is not a value of its kind, so the check did not search for it.\n *\n * The time of the check is linear in the length of the text, for a fixed set of fields.\n */\n\n// ── the public types ────────────────────────────────────────────────────────\n\n/** The kinds of field that the check reads. `json-ld:<path>` reads a value at a path of the JSON-LD, for example `json-ld:Product.offers.price`. */\nexport type FieldKind =\n \"text\" | \"number\" | \"money\" | \"date\" | \"url\" | \"email\" | \"phone\" | `json-ld:${string}`;\n\n/**\n * These kinds read the text of the page. The kind `json-ld:<path>` reads the JSON-LD.\n *\n * @beta\n */\nexport const FIELD_KINDS: readonly string[] = [\n \"text\",\n \"number\",\n \"money\",\n \"date\",\n \"url\",\n \"email\",\n \"phone\",\n];\n\n/** This is the value that a caller proposes for one field. */\nexport interface FieldClaim {\n /** This value is the proposal. The check removes the spaces at its start and at its end. */\n readonly value: string | number;\n /** This value is the kind of the field. The default is `number` for a number and `text` for a text. */\n readonly kind?: FieldKind | undefined;\n}\n\n/** The status of one field. The module comment of `extract.ts` and the README tell what each status means. */\nexport type FieldStatus =\n \"verified\" | \"normalized\" | \"ambiguous\" | \"not-found\" | \"held-back\" | \"invalid\";\n\n/** These positions locate a value in the text of a version. The end is not part of the value. */\nexport interface FieldSpan {\n readonly start: number;\n readonly end: number;\n /** This value is `full_text` when the value is only in the whole text of a page that the reader cut. */\n readonly in: \"text\" | \"full_text\";\n}\n\n/** This is one place that an ambiguous field matches. */\nexport interface FieldCandidate {\n readonly span: FieldSpan | null;\n /** This path locates a value of the JSON-LD (`jsonld[0].offers[1].price`) or a stored link (`links[3]`). */\n readonly path: string | null;\n /** This value is the exact stored text, or the stored value of the JSON-LD. */\n readonly raw: string | number | boolean;\n readonly excerpt: string;\n /** These are the meanings that the stored text can have, for example two dates for `03/04/2026`. */\n readonly readings: readonly string[];\n}\n\n/** This is the check of one field, before the runtime adds the capture. */\nexport interface FieldCheck {\n readonly status: FieldStatus;\n /** This value is the kind that the check used. */\n readonly kind: string;\n readonly span: FieldSpan | null;\n readonly path: string | null;\n /** This value is the exact stored text of the match, or the stored value of the JSON-LD. */\n readonly raw: string | number | boolean | null;\n /** This text is the stored text around the match. */\n readonly excerpt: string | null;\n /** This value names the normalization of a `normalized` match, for example `thousands-separator`. Two or more names are joined with `+`. */\n readonly normalization: string | null;\n /** This value is the meaning of the stored text that matched, for example `1234.5` or `2026-03-04`. */\n readonly reading: string | null;\n /** This value is the number of places that match. */\n readonly count: number;\n /** These are the places of an ambiguous field, one for each meaning, 5 or fewer. */\n readonly candidates: readonly FieldCandidate[];\n readonly note: string | null;\n}\n\n/** This is the result of one field: the check, and the capture of the text that the check read. */\nexport interface FieldResult extends FieldCheck {\n readonly capture: string | null;\n /** This time (ISO 8601) is the fetch time of that capture. */\n readonly fetched_at: string | null;\n}\n\n/** These are the counts of the statuses of the fields. */\nexport interface ExtractSummary {\n readonly fields: number;\n readonly verified: number;\n readonly normalized: number;\n readonly ambiguous: number;\n readonly not_found: number;\n readonly held_back: number;\n readonly invalid: number;\n}\n\n/**\n * This is the text of a document that `checkFields` reads, with its metadata.\n *\n * @beta\n */\nexport interface ExtractSource {\n readonly text: string;\n /** This text is the whole text of a page that the reader cut. The check reads it when the value is not in `text`. */\n readonly full_text?: string | undefined;\n /** This URL is the address of the page. The check resolves a relative URL against it. */\n readonly url?: string | null | undefined;\n /** The check reads `jsonld`, `jsonld_dropped`, `links` and `truncated` of this metadata. */\n readonly meta?: Readonly<Record<string, unknown>> | undefined;\n}\n\n/**\n * This is the result of `checkFields`.\n *\n * @beta\n */\nexport interface FieldsChecked {\n readonly fields: Readonly<Record<string, FieldCheck>>;\n readonly summary: ExtractSummary;\n /** This value counts the units of work of the check. It grows in proportion to the length of the text. */\n readonly steps: number;\n}\n\n/** These options control a check of fields against a stored document. */\nexport interface ExtractOptions {\n /** This id checks the version of one capture, not the current version. */\n readonly capture?: string | undefined;\n /**\n * This time checks the version that was current at that time: an ISO 8601 text or a `Date`. A date\n * with no time is the start of that day in UTC. Give `capture` or `at`, not the two.\n */\n readonly at?: string | Date | undefined;\n /** This value is true when a person gave this URL directly. It is the only way to check a held-back document. The crawler logs it. */\n readonly userProvided?: boolean | undefined;\n}\n\n/** This is the result of a check of fields against a stored document. */\nexport interface ExtractResult {\n readonly doc: string;\n readonly url: string | null;\n readonly captures: readonly string[];\n /** This id is the capture of the text that the check read. A held-back document gives null. */\n readonly capture: string | null;\n /** This hash is the blob of that capture. */\n readonly blob: string | null;\n /** This time (ISO 8601) is the fetch time of that capture. */\n readonly fetched_at: string | null;\n readonly held_back: boolean;\n /** These are the results of the fields, with the names that the caller gave. */\n readonly fields: Readonly<Record<string, FieldResult>>;\n readonly summary: ExtractSummary;\n readonly note: string | null;\n /** This time (ISO 8601) is the `at` of the check. The result has it only when the check gave `at`. */\n readonly at?: string | undefined;\n /** This value is true when `at` is before the first capture of the document. Then no field is found. */\n readonly before_first?: boolean | undefined;\n /**\n * This value tells that the checked text is an archived copy, with the archive and the date of the\n * copy. The note says so too. A citation of a value names the archive and that date.\n */\n readonly archived?: Archived | undefined;\n}\n\n// ── the work counter and the stored text ────────────────────────────────────\n\ninterface Work {\n steps: number;\n}\n\n/** A text of the document, folded one time for each check, with the tokens of each kind. */\ninterface Doc {\n readonly name: \"text\" | \"full_text\";\n readonly text: string;\n readonly folded: Folded;\n readonly cache: Map<string, unknown>;\n}\n\nconst prepare = (name: \"text\" | \"full_text\", text: string, work: Work): Doc => {\n // foldText is linear: each unit of the text gives a constant number of units of work\n work.steps += text.length;\n return { name, text, folded: foldText(text, \"quote\"), cache: new Map() };\n};\n\nconst cached = <T>(doc: Doc, key: string, make: () => T): T => {\n if (doc.cache.has(key)) return doc.cache.get(key) as T;\n const value = make();\n doc.cache.set(key, value);\n return value;\n};\n\n/** This function gives the original span of the folded units from `i` to `j`. */\nconst spanOf = (doc: Doc, i: number, j: number): FieldSpan => ({\n start: doc.folded.start[i]!,\n end: doc.folded.end[j - 1]!,\n in: doc.name,\n});\n\nconst EXCERPT = 60;\n\n/** This function moves a position off the second half of a surrogate pair. */\nconst onBoundary = (text: string, position: number, forward: boolean): number => {\n const code = text.charCodeAt(position);\n if (position > 0 && position < text.length && code >= 0xdc00 && code <= 0xdfff) {\n return forward ? position + 1 : position - 1;\n }\n return position;\n};\n\nconst excerptOf = (text: string, start: number, end: number): string => {\n const from = onBoundary(text, Math.max(0, start - EXCERPT), false);\n const to = onBoundary(text, Math.min(text.length, end + EXCERPT), true);\n return `${from > 0 ? \"…\" : \"\"}${text.slice(from, to)}${to < text.length ? \"…\" : \"\"}`;\n};\n\nconst isDigitCode = (code: number): boolean => code >= 48 && code <= 57;\nconst isDigitAt = (text: string, at: number): boolean =>\n at >= 0 && at < text.length && isDigitCode(text.charCodeAt(at));\nconst WORD = /^[\\p{L}\\p{N}]$/u;\n/** This function tells if the unit at a position is a letter or a digit. */\nconst isWordAt = (text: string, at: number): boolean => {\n if (at < 0 || at >= text.length) return false;\n const code = text.charCodeAt(at);\n if (code < 0x80) {\n return isDigitCode(code) || (code >= 97 && code <= 122) || (code >= 65 && code <= 90);\n }\n return WORD.test(text[at]!);\n};\nconst isLetterAt = (text: string, at: number): boolean =>\n isWordAt(text, at) && !isDigitAt(text, at);\n\n// ── the decision ────────────────────────────────────────────────────────────\n\ninterface Where {\n readonly span: FieldSpan | null;\n readonly path: string | null;\n}\n\n/** A place of the stored data that can hold a value of a kind, with its meanings. */\ninterface Cand<R> {\n readonly where: Where;\n readonly raw: string | number | boolean;\n /** This text is the exact stored text, for the exact comparison. */\n readonly exact: string;\n readonly excerpt: () => string;\n readonly readings: readonly R[];\n /** This part of the place also matches exactly, for example the amount of a money value. */\n readonly alt?: { readonly where: Where; readonly exact: string } | undefined;\n}\n\n/** The comparison of one meaning of the value with one meaning of the stored text. */\ninterface Compared {\n /** This value is false when the stored text says less than the value, for example a date with no year. */\n readonly clean: boolean;\n readonly key: string;\n readonly reading: string;\n readonly labels: readonly string[];\n}\n\ninterface Comparator<C, R> {\n readonly compare: (claim: C, reading: R) => Compared | undefined;\n readonly display: (reading: R) => string;\n /** This function tells if two matches have one meaning. The default compares the keys. */\n readonly same?: (a: Compared, b: Compared) => boolean;\n}\n\nconst MAX_CANDIDATES = 5;\n\nconst LABEL_ORDER = [\n \"unicode\",\n \"whitespace\",\n \"case\",\n \"thousands-separator\",\n \"decimal-comma\",\n \"number-form\",\n \"currency-symbol\",\n \"currency-position\",\n \"amount-only\",\n \"date-iso\",\n \"date-ymd\",\n \"date-dmy\",\n \"date-mdy\",\n \"date-numeric\",\n \"date-written\",\n \"date-form\",\n \"date-partial\",\n \"url-resolved\",\n \"url-scheme\",\n \"url-form\",\n \"email-case\",\n \"phone-digits\",\n \"phone-suffix\",\n];\n\nconst labelText = (labels: Iterable<string>): string => {\n const set = new Set(labels);\n return LABEL_ORDER.filter((label) => set.has(label)).join(\"+\");\n};\n\nconst empty = (status: FieldStatus, kind: string, note: string | null = null): FieldCheck => ({\n status,\n kind,\n span: null,\n path: null,\n raw: null,\n excerpt: null,\n normalization: null,\n reading: null,\n count: 0,\n candidates: [],\n note,\n});\n\ninterface Matched<R> {\n readonly cand: Cand<R>;\n readonly compared: Compared;\n readonly clean: boolean;\n}\n\n/**\n * This function decides the status of a field from its places. An exact match wins. A normalized\n * match needs one meaning: two meanings, or a place that the text does not make clear, give\n * `ambiguous`. The cost is linear in the number of places.\n */\nconst decide = <C, R>(\n kind: string,\n claimText: string,\n claims: readonly C[],\n cands: readonly Cand<R>[],\n comparator: Comparator<C, R>,\n work: Work,\n): FieldCheck => {\n let exactCount = 0;\n let exactFirst:\n { readonly where: Where; readonly cand: Cand<R>; readonly raw: string } | undefined;\n for (const cand of cands) {\n work.steps += 1;\n if (cand.exact === claimText) {\n exactCount += 1;\n exactFirst ??= { where: cand.where, cand, raw: cand.exact };\n } else if (cand.alt !== undefined && cand.alt.exact === claimText) {\n exactCount += 1;\n exactFirst ??= { where: cand.alt.where, cand, raw: cand.alt.exact };\n }\n }\n if (exactFirst !== undefined) {\n const reading = exactFirst.cand.readings[0];\n return {\n ...empty(\"verified\", kind),\n span: exactFirst.where.span,\n path: exactFirst.where.path,\n raw: exactFirst.where === exactFirst.cand.where ? exactFirst.cand.raw : exactFirst.raw,\n excerpt: exactFirst.cand.excerpt(),\n reading:\n exactFirst.cand.readings.length === 1 && reading !== undefined\n ? comparator.display(reading)\n : null,\n count: exactCount,\n };\n }\n const matches: Matched<R>[] = [];\n for (const cand of cands) {\n let best: Compared | undefined;\n for (const reading of cand.readings) {\n for (const claim of claims) {\n work.steps += 1;\n const compared = comparator.compare(claim, reading);\n if (compared !== undefined && (best === undefined || (compared.clean && !best.clean)))\n best = compared;\n }\n }\n if (best === undefined) continue;\n matches.push({\n cand,\n compared: best,\n clean: best.clean && cand.readings.length === 1 && claims.length === 1,\n });\n }\n if (matches.length === 0) return empty(\"not-found\", kind);\n const same = comparator.same ?? ((a: Compared, b: Compared): boolean => a.key === b.key);\n const candidateOf = (match: Matched<R>): FieldCandidate => ({\n span: match.cand.where.span,\n path: match.cand.where.path,\n raw: match.cand.raw,\n excerpt: match.cand.excerpt(),\n readings: match.cand.readings.map(comparator.display),\n });\n const clean = matches.filter((match) => match.clean);\n if (clean.length > 0) {\n // one representative of each meaning; two are enough to know that the field is ambiguous\n const meanings: Matched<R>[] = [];\n for (const match of clean) {\n work.steps += 1;\n if (meanings.some((known) => same(known.compared, match.compared))) continue;\n if (meanings.length < MAX_CANDIDATES) meanings.push(match);\n else break;\n }\n const first = clean[0]!;\n if (meanings.length === 1) {\n return {\n ...empty(\"normalized\", kind),\n span: first.cand.where.span,\n path: first.cand.where.path,\n raw: first.cand.raw,\n excerpt: first.cand.excerpt(),\n normalization: labelText(first.compared.labels),\n reading: first.compared.reading,\n count: clean.length,\n };\n }\n return {\n ...empty(\n \"ambiguous\",\n kind,\n \"the value matches places with different meanings, so the check does not choose one\",\n ),\n count: clean.length,\n candidates: meanings.map(candidateOf),\n };\n }\n const note =\n claims.length > 1\n ? \"the value itself has more than one meaning: give it in a form with one meaning\"\n : \"the stored text matches, but it does not give one meaning, so the check does not choose one\";\n return {\n ...empty(\"ambiguous\", kind, note),\n count: matches.length,\n candidates: matches.slice(0, MAX_CANDIDATES).map(candidateOf),\n };\n};\n\n// ── text ────────────────────────────────────────────────────────────────────\n\n/** This function gives each start of a needle in a text, in linear time (Knuth, Morris and Pratt). */\nconst occurrences = (hay: string, needle: string, work: Work): number[] => {\n const m = needle.length;\n const fail = new Int32Array(m);\n for (let q = 0, i = 1; i < m; i += 1) {\n while (q > 0 && needle.charCodeAt(i) !== needle.charCodeAt(q)) {\n q = fail[q - 1]!;\n work.steps += 1;\n }\n if (needle.charCodeAt(i) === needle.charCodeAt(q)) q += 1;\n fail[i] = q;\n work.steps += 1;\n }\n const hits: number[] = [];\n for (let q = 0, i = 0; i < hay.length; i += 1) {\n while (q > 0 && hay.charCodeAt(i) !== needle.charCodeAt(q)) {\n q = fail[q - 1]!;\n work.steps += 1;\n }\n if (hay.charCodeAt(i) === needle.charCodeAt(q)) q += 1;\n work.steps += 1;\n if (q === m) {\n hits.push(i - m + 1);\n q = fail[q - 1]!;\n }\n }\n return hits;\n};\n\nconst IGNORABLE = /\\p{Default_Ignorable_Code_Point}/gu;\nconst QUOTES = /[‘’‚‛′]/g;\nconst DOUBLE_QUOTES = /[“”„‟″]/g;\nconst DASHES = /[‐‑‒–—―−﹘﹣]/g;\n\n/** This function applies the Unicode part of the fold: NFKC, no ignorable characters, and ASCII quotes and dashes. */\nconst unicodeForm = (text: string): string =>\n text\n .normalize(\"NFKC\")\n .replace(IGNORABLE, \"\")\n .replace(QUOTES, \"'\")\n .replace(DOUBLE_QUOTES, '\"')\n .replace(DASHES, \"-\");\nconst spaceForm = (text: string): string => text.replace(/\\s+/gu, \" \").trim();\n\nconst LAYER_SETS: ReadonlyArray<readonly (\"unicode\" | \"whitespace\" | \"case\")[]> = [\n [\"unicode\"],\n [\"whitespace\"],\n [\"case\"],\n [\"unicode\", \"whitespace\"],\n [\"unicode\", \"case\"],\n [\"whitespace\", \"case\"],\n];\n\n/** This function names the parts of the fold that make the stored text equal to the value. */\nconst textLabels = (stored: string, value: string): string[] => {\n const apply = (text: string, layers: readonly string[]): string => {\n let out = text;\n if (layers.includes(\"unicode\")) out = unicodeForm(out);\n if (layers.includes(\"whitespace\")) out = spaceForm(out);\n if (layers.includes(\"case\")) out = out.toLowerCase();\n return out;\n };\n for (const layers of LAYER_SETS) {\n if (apply(stored, layers) === apply(value, layers)) return [...layers];\n }\n return [\"unicode\", \"whitespace\", \"case\"];\n};\n\n/**\n * This function finds a text value in a text, with the fold of `verify`. A match must start and\n * end at the edge of a word. The positions are in the original text.\n */\nconst checkText = (doc: Doc, claim: string, work: Work): FieldCheck => {\n const needle = fold(claim, \"quote\");\n if (needle.length === 0) return empty(\"invalid\", \"text\", \"the value has no text\");\n const hay = doc.folded.text;\n const hits = occurrences(hay, needle, work);\n const wordStart = isWordAt(needle, 0);\n const wordEnd = isWordAt(needle, needle.length - 1);\n let count = 0;\n let next = 0;\n let firstExact: FieldSpan | undefined;\n let first: FieldSpan | undefined;\n for (const at of hits) {\n work.steps += 1;\n if (at < next) continue;\n const end = at + needle.length;\n if (wordStart && isWordAt(hay, at - 1)) continue;\n if (wordEnd && isWordAt(hay, end)) continue;\n next = end;\n count += 1;\n const span = spanOf(doc, at, end);\n first ??= span;\n if (firstExact === undefined && doc.text.slice(span.start, span.end) === claim)\n firstExact = span;\n }\n if (first === undefined) return empty(\"not-found\", \"text\");\n const span = firstExact ?? first;\n const stored = doc.text.slice(span.start, span.end);\n return {\n ...empty(firstExact !== undefined ? \"verified\" : \"normalized\", \"text\"),\n span,\n raw: stored,\n excerpt: excerptOf(doc.text, span.start, span.end),\n normalization: firstExact !== undefined ? null : labelText(textLabels(stored, claim)),\n count,\n };\n};\n\n// ── numbers ─────────────────────────────────────────────────────────────────\n\n/** One meaning of a number: its canonical value, and the form that the text gives it. */\ninterface NumReading {\n /** This text is the canonical decimal value, for example `1234.5`. */\n readonly value: string;\n /** This text is the value with its digits as written, for example `+01234.50`. */\n readonly plain: string;\n /** This character separates the thousands, or it is null. */\n readonly group: string | null;\n /** This character is the decimal point or the decimal comma, or it is null. */\n readonly point: string | null;\n}\n\nconst THOUSANDS: ReadonlySet<string> = new Set([\",\", \".\", \"'\", \" \"]);\nconst DECIMALS: ReadonlySet<string> = new Set([\".\", \",\"]);\n/** The no-break and thin spaces that separate the thousands in some languages. */\nconst GROUP_SPACES: ReadonlySet<number> = new Set([0xa0, 0x202f, 0x2009, 0x2007]);\n\nconst makeReading = (\n sign: string,\n int: string,\n frac: string,\n group: string | null,\n point: string | null,\n): NumReading => {\n const intPart = int.replace(/^0+(?=\\d)/, \"\");\n const fracPart = frac.replace(/0+$/, \"\");\n const zero = /^0+$/.test(intPart) && fracPart === \"\";\n return {\n value: `${sign === \"-\" && !zero ? \"-\" : \"\"}${intPart}${fracPart === \"\" ? \"\" : `.${fracPart}`}`,\n plain: `${sign}${int}${frac === \"\" ? \"\" : `.${frac}`}`,\n group,\n point,\n };\n};\n\n/**\n * This function gives each meaning of a number as written. A group of exactly three digits after\n * one separator gives two meanings (`1,234` is 1234 or 1.234), and the function gives the two.\n */\nconst numberReadings = (written: string): NumReading[] => {\n let sign = \"\";\n let rest = written;\n if (rest.startsWith(\"-\") || rest.startsWith(\"+\")) {\n sign = rest[0]!;\n rest = rest.slice(1);\n }\n const groups: string[] = [];\n const seps: string[] = [];\n let from = 0;\n for (let at = 0; at < rest.length; at += 1) {\n if (isDigitCode(rest.charCodeAt(at))) continue;\n groups.push(rest.slice(from, at));\n seps.push(rest[at]!);\n from = at + 1;\n }\n groups.push(rest.slice(from));\n if (groups.some((group) => group.length === 0)) return [];\n const found = new Map<string, NumReading>();\n const add = (int: string, frac: string, group: string | null, point: string | null): void => {\n const reading = makeReading(sign, int, frac, group, point);\n if (!found.has(reading.value)) found.set(reading.value, reading);\n };\n if (seps.length === 0) {\n add(groups[0]!, \"\", null, null);\n return [...found.values()];\n }\n const t = seps[0]!;\n const grouped = (count: number): boolean => {\n const head = groups[0]!;\n if (head.length > 3 || head.startsWith(\"0\")) return false;\n for (let k = 1; k <= count; k += 1) {\n if (groups[k]!.length !== 3 || seps[k - 1] !== t) return false;\n }\n return true;\n };\n if (THOUSANDS.has(t) && grouped(seps.length)) add(groups.join(\"\"), \"\", t, null);\n const d = seps[seps.length - 1]!;\n if (\n seps.length >= 2 &&\n DECIMALS.has(d) &&\n d !== t &&\n THOUSANDS.has(t) &&\n grouped(seps.length - 1)\n ) {\n add(groups.slice(0, -1).join(\"\"), groups[groups.length - 1]!, t, d);\n }\n if (seps.length === 1 && DECIMALS.has(d)) add(groups[0]!, groups[1]!, null, d);\n return [...found.values()];\n};\n\n/** This function writes a JavaScript `number` in decimal digits, with no exponent. */\nconst decimalOf = (value: number): string | undefined => {\n if (!Number.isFinite(value)) return undefined;\n const text = String(value);\n const match = /^(-?)(\\d+)(?:\\.(\\d+))?e([+-]\\d+)$/i.exec(text);\n if (match === null) return text;\n const digits = `${match[2]!}${match[3] ?? \"\"}`;\n const point = match[2]!.length + Number(match[4]);\n const body =\n point <= 0\n ? `0.${\"0\".repeat(-point)}${digits}`\n : point >= digits.length\n ? `${digits}${\"0\".repeat(point - digits.length)}`\n : `${digits.slice(0, point)}.${digits.slice(point)}`;\n return `${match[1]!}${body}`;\n};\n\n/** This function reads a proposed number. A JavaScript `number` has one meaning: its point is a decimal point. */\nconst claimNumber = (value: string | number): NumReading[] => {\n if (typeof value === \"number\") {\n const text = decimalOf(value);\n if (text === undefined) return [];\n const sign = text.startsWith(\"-\") ? \"-\" : \"\";\n const [int = \"\", frac = \"\"] = text.replace(/^-/, \"\").split(\".\");\n return [makeReading(sign, int, frac, null, frac === \"\" ? null : \".\")];\n }\n const text = fold(value, \"quote\").trim();\n if (!/^[+-]?\\d[\\d.,' ]*$/.test(text) || !/\\d$/.test(text)) return [];\n return numberReadings(text);\n};\n\ninterface NumToken {\n readonly i: number;\n readonly j: number;\n readonly readings: readonly NumReading[];\n}\n\n/**\n * This function finds the numbers of a folded text. A number is digits with separators. A letter\n * before it makes a name (`A320`), so it is not a number. Each unit is read a constant number of times.\n */\nconst numberTokens = (doc: Doc, work: Work): readonly NumToken[] =>\n cached(doc, \"number\", () => {\n const f = doc.folded.text;\n const n = f.length;\n const out: NumToken[] = [];\n const isSep = (at: number): boolean => {\n const char = f[at];\n if (char === \",\" || char === \".\" || char === \"'\") return true;\n if (char !== \" \") return false;\n const from = doc.folded.start[at]!;\n return (\n doc.folded.end[at]! - from === 1 &&\n GROUP_SPACES.has(doc.text.charCodeAt(from)) &&\n (at + 1 >= n || doc.folded.start[at + 1] === from + 1)\n );\n };\n let i = 0;\n while (i < n) {\n work.steps += 1;\n if (!isDigitAt(f, i)) {\n i += 1;\n continue;\n }\n const start = i;\n let j = i;\n while (j < n && isDigitAt(f, j)) {\n j += 1;\n work.steps += 1;\n }\n while (j + 1 < n && isSep(j) && isDigitAt(f, j + 1)) {\n j += 1;\n while (j < n && isDigitAt(f, j)) {\n j += 1;\n work.steps += 1;\n }\n }\n i = j;\n const before = start > 0 ? f[start - 1]! : \"\";\n // a name (A320), a fraction with no integer part (.5) or a piece of a longer number\n if (isLetterAt(f, start - 1) || before === \".\" || (before === \",\" && isDigitAt(f, start - 2)))\n continue;\n const signed = (before === \"-\" || before === \"+\") && !isWordAt(f, start - 2);\n const from = signed ? start - 1 : start;\n const readings = numberReadings(f.slice(from, j));\n if (readings.length > 0) {\n out.push({ i: from, j, readings });\n continue;\n }\n // the separators make no number (1.2.3, 12,34,5): each run of digits is a number\n let a = start;\n while (a < j) {\n let b = a;\n while (b < j && isDigitAt(f, b)) b += 1;\n out.push({ i: a, j: b, readings: [makeReading(\"\", f.slice(a, b), \"\", null, null)] });\n a = b + 1;\n }\n }\n return out;\n });\n\nconst numberLabels = (claim: NumReading, reading: NumReading): string[] => {\n const labels = new Set<string>();\n if (claim.group !== reading.group) labels.add(\"thousands-separator\");\n if (claim.point !== reading.point && (claim.point === \",\" || reading.point === \",\"))\n labels.add(\"decimal-comma\");\n // the same value with other digits: zeros at the start or the end, or a plus sign\n if (claim.plain !== reading.plain) labels.add(\"number-form\");\n return [...labels];\n};\n\nconst NUMBER: Comparator<NumReading, NumReading> = {\n compare: (claim, reading) => {\n if (claim.value !== reading.value) return undefined;\n const labels = numberLabels(claim, reading);\n // the same digits as written: only the characters differ (fullwidth digits, a minus sign)\n return {\n clean: true,\n key: reading.value,\n reading: reading.value,\n labels: labels.length === 0 ? [\"unicode\"] : labels,\n };\n },\n display: (reading) => reading.value,\n};\n\nconst numberCands = (doc: Doc, work: Work): Cand<NumReading>[] =>\n numberTokens(doc, work).map((token) => {\n const span = spanOf(doc, token.i, token.j);\n const exact = doc.text.slice(span.start, span.end);\n return {\n where: { span, path: null },\n raw: exact,\n exact,\n excerpt: () => excerptOf(doc.text, span.start, span.end),\n readings: token.readings,\n };\n });\n\n// ── money ───────────────────────────────────────────────────────────────────\n\n/** The codes of ISO 4217 that the check knows, for the common currencies. */\nconst CODES: readonly string[] = [\n \"USD\",\n \"EUR\",\n \"GBP\",\n \"JPY\",\n \"CNY\",\n \"CAD\",\n \"AUD\",\n \"NZD\",\n \"CHF\",\n \"SEK\",\n \"NOK\",\n \"DKK\",\n \"ISK\",\n \"PLN\",\n \"CZK\",\n \"HUF\",\n \"RON\",\n \"BGN\",\n \"TRY\",\n \"ILS\",\n \"INR\",\n \"PKR\",\n \"BDT\",\n \"LKR\",\n \"KRW\",\n \"SGD\",\n \"HKD\",\n \"TWD\",\n \"THB\",\n \"MYR\",\n \"IDR\",\n \"PHP\",\n \"VND\",\n \"BRL\",\n \"MXN\",\n \"ARS\",\n \"CLP\",\n \"COP\",\n \"PEN\",\n \"UYU\",\n \"ZAR\",\n \"NGN\",\n \"EGP\",\n \"KES\",\n \"MAD\",\n \"AED\",\n \"SAR\",\n \"QAR\",\n \"KWD\",\n \"BHD\",\n \"OMR\",\n \"JOD\",\n \"RUB\",\n \"UAH\",\n \"KZT\",\n \"GEL\",\n];\n\n/** The currency symbols, folded, with the currencies of each. A symbol of more than one currency does not say which. */\nconst SYMBOLS: ReadonlyArray<readonly [string, readonly string[]]> = [\n [\"us$\", [\"USD\"]],\n [\"ca$\", [\"CAD\"]],\n [\"c$\", [\"CAD\"]],\n [\"au$\", [\"AUD\"]],\n [\"a$\", [\"AUD\"]],\n [\"nz$\", [\"NZD\"]],\n [\"hk$\", [\"HKD\"]],\n [\"s$\", [\"SGD\"]],\n [\"r$\", [\"BRL\"]],\n [\"mx$\", [\"MXN\"]],\n [\"nt$\", [\"TWD\"]],\n [\"$\", [\"USD\", \"CAD\", \"AUD\", \"NZD\", \"MXN\", \"SGD\", \"HKD\", \"TWD\", \"ARS\", \"CLP\", \"COP\"]],\n [\"€\", [\"EUR\"]],\n [\"£\", [\"GBP\"]],\n [\"cn¥\", [\"CNY\"]],\n [\"jp¥\", [\"JPY\"]],\n [\"¥\", [\"JPY\", \"CNY\"]],\n [\"₹\", [\"INR\"]],\n [\"₩\", [\"KRW\"]],\n [\"₽\", [\"RUB\"]],\n [\"₺\", [\"TRY\"]],\n [\"₪\", [\"ILS\"]],\n [\"₫\", [\"VND\"]],\n [\"฿\", [\"THB\"]],\n [\"₱\", [\"PHP\"]],\n [\"₦\", [\"NGN\"]],\n [\"₴\", [\"UAH\"]],\n [\"₸\", [\"KZT\"]],\n [\"₾\", [\"GEL\"]],\n [\"zł\", [\"PLN\"]],\n [\"kč\", [\"CZK\"]],\n [\"kr\", [\"SEK\", \"NOK\", \"DKK\", \"ISK\"]],\n];\n\ninterface Marker {\n /** This text is the marker as the folded text writes it. */\n readonly text: string;\n readonly codes: readonly string[];\n /** This label names the currency: its code, or the symbol when the symbol has more than one currency. */\n readonly label: string;\n readonly alpha: boolean;\n /** This value is true for a code of ISO 4217. A page writes a code in capitals, so `15 try` is not an amount. */\n readonly code: boolean;\n}\n\nconst MARKERS: readonly Marker[] = [\n ...SYMBOLS.map(([text, codes]) => ({\n text,\n codes,\n label: codes.length === 1 ? codes[0]! : text,\n alpha: /^[a-z]/.test(text),\n code: false,\n })),\n ...CODES.map((code) => ({\n text: code.toLowerCase(),\n codes: [code],\n label: code,\n alpha: true,\n code: true,\n })),\n].sort((a, b) => b.text.length - a.text.length);\n\n/** This function finds a currency marker that ends at a position (exclusive), or undefined. */\nconst markerEndingAt = (f: string, end: number): Marker | undefined => {\n for (const marker of MARKERS) {\n const from = end - marker.text.length;\n if (from < 0 || !f.startsWith(marker.text, from)) continue;\n if (marker.alpha && isLetterAt(f, from - 1)) continue;\n return marker;\n }\n return undefined;\n};\n\n/** This function finds a currency marker that starts at a position, or undefined. */\nconst markerStartingAt = (f: string, from: number): Marker | undefined => {\n for (const marker of MARKERS) {\n if (!f.startsWith(marker.text, from)) continue;\n if (marker.alpha && isLetterAt(f, from + marker.text.length)) continue;\n return marker;\n }\n return undefined;\n};\n\ninterface MoneyReading {\n readonly amount: NumReading;\n readonly marker: Marker | null;\n readonly before: boolean;\n}\n\nconst moneyText = (reading: MoneyReading): string =>\n reading.marker === null\n ? reading.amount.value\n : `${reading.marker.label} ${reading.amount.value}`;\n\nconst MONEY: Comparator<MoneyReading, MoneyReading> = {\n compare: (claim, reading) => {\n if (claim.amount.value !== reading.amount.value || reading.marker === null) return undefined;\n const labels = new Set(numberLabels(claim.amount, reading.amount));\n let clean = true;\n if (claim.marker === null) labels.add(\"amount-only\");\n else {\n if (claim.marker.label !== reading.marker.label) {\n if (!claim.marker.codes.some((code) => reading.marker!.codes.includes(code)))\n return undefined;\n // \"$\" can be one of several currencies, so it does not say which one the value names\n clean = false;\n }\n if (claim.marker.text !== reading.marker.text) labels.add(\"currency-symbol\");\n if (claim.before !== reading.before) labels.add(\"currency-position\");\n }\n if (labels.size === 0) labels.add(\"whitespace\");\n return { clean, key: moneyText(reading), reading: moneyText(reading), labels: [...labels] };\n },\n display: moneyText,\n};\n\n/** This function reads a proposed amount of money: an amount, with a currency symbol or code before or after it. */\nconst claimMoney = (value: string | number): MoneyReading[] => {\n if (typeof value === \"number\")\n return claimNumber(value).map((amount) => ({ amount, marker: null, before: false }));\n const text = fold(value, \"quote\").trim();\n const head = markerStartingAt(text, 0);\n if (head !== undefined) {\n return claimNumber(text.slice(head.text.length).trim()).map((amount) => ({\n amount,\n marker: head,\n before: true,\n }));\n }\n const tail = markerEndingAt(text, text.length);\n if (tail !== undefined) {\n return claimNumber(text.slice(0, text.length - tail.text.length).trim()).map((amount) => ({\n amount,\n marker: tail,\n before: false,\n }));\n }\n return claimNumber(text).map((amount) => ({ amount, marker: null, before: false }));\n};\n\n/** This function finds the amounts of money of a text. An amount is a number with a currency marker before or after it, with one space or none. */\nconst moneyCands = (doc: Doc, work: Work): Cand<MoneyReading>[] =>\n cached(doc, \"money\", () => {\n const f = doc.folded.text;\n const out: Cand<MoneyReading>[] = [];\n // a code of ISO 4217 counts only in capitals in the original text\n const written = (marker: Marker | undefined, from: number): Marker | undefined => {\n if (marker === undefined || !marker.code) return marker;\n const original = doc.text.slice(\n doc.folded.start[from]!,\n doc.folded.end[from + marker.text.length - 1]!,\n );\n return original === marker.label ? marker : undefined;\n };\n for (const token of numberTokens(doc, work)) {\n work.steps += MARKERS.length;\n const gapBefore = f[token.i - 1] === \" \" ? 1 : 0;\n const found = markerEndingAt(f, token.i - gapBefore);\n const before = written(\n found,\n token.i - gapBefore - (found === undefined ? 0 : found.text.length),\n );\n let marker = before;\n let i = token.i;\n let j = token.j;\n if (before !== undefined) i = token.i - gapBefore - before.text.length;\n else {\n const gapAfter = f[token.j] === \" \" ? 1 : 0;\n const after = written(markerStartingAt(f, token.j + gapAfter), token.j + gapAfter);\n if (after === undefined) continue;\n marker = after;\n j = token.j + gapAfter + after.text.length;\n }\n const span = spanOf(doc, i, j);\n const amount = spanOf(doc, token.i, token.j);\n const exact = doc.text.slice(span.start, span.end);\n out.push({\n where: { span, path: null },\n raw: exact,\n exact,\n excerpt: () => excerptOf(doc.text, span.start, span.end),\n readings: token.readings.map((reading) => ({\n amount: reading,\n marker: marker ?? null,\n before: before !== undefined,\n })),\n alt: {\n where: { span: amount, path: null },\n exact: doc.text.slice(amount.start, amount.end),\n },\n });\n }\n return out;\n });\n\n// ── dates ───────────────────────────────────────────────────────────────────\n\ntype DateForm = \"iso\" | \"ymd\" | \"dmy\" | \"mdy\" | \"numeric\" | \"written\";\n\ninterface DateReading {\n readonly y: number | null;\n readonly m: number;\n readonly d: number | null;\n readonly form: DateForm;\n}\n\nconst MONTHS: ReadonlyMap<string, number> = new Map([\n [\"january\", 1],\n [\"jan\", 1],\n [\"february\", 2],\n [\"feb\", 2],\n [\"march\", 3],\n [\"mar\", 3],\n [\"april\", 4],\n [\"apr\", 4],\n [\"may\", 5],\n [\"june\", 6],\n [\"jun\", 6],\n [\"july\", 7],\n [\"jul\", 7],\n [\"august\", 8],\n [\"aug\", 8],\n [\"september\", 9],\n [\"sept\", 9],\n [\"sep\", 9],\n [\"october\", 10],\n [\"oct\", 10],\n [\"november\", 11],\n [\"nov\", 11],\n [\"december\", 12],\n [\"dec\", 12],\n]);\nconst WEEKDAYS: ReadonlySet<string> = new Set([\n \"monday\",\n \"mon\",\n \"tuesday\",\n \"tue\",\n \"tues\",\n \"wednesday\",\n \"wed\",\n \"thursday\",\n \"thu\",\n \"thur\",\n \"thurs\",\n \"friday\",\n \"fri\",\n \"saturday\",\n \"sat\",\n \"sunday\",\n \"sun\",\n]);\nconst ORDINALS: ReadonlySet<string> = new Set([\"st\", \"nd\", \"rd\", \"th\"]);\n\nconst daysIn = (m: number, y: number | null): number =>\n m === 2\n ? y === null || (y % 4 === 0 && (y % 100 !== 0 || y % 400 === 0))\n ? 29\n : 28\n : [4, 6, 9, 11].includes(m)\n ? 30\n : 31;\n\nconst validDate = (y: number | null, m: number, d: number | null): boolean =>\n m >= 1 &&\n m <= 12 &&\n (y === null || (y >= 1000 && y <= 2999)) &&\n (d === null || (d >= 1 && d <= daysIn(m, y)));\n\nconst pad = (value: number, size: number): string => String(value).padStart(size, \"0\");\nconst dateText = (reading: DateReading): string =>\n reading.y === null\n ? `--${pad(reading.m, 2)}${reading.d === null ? \"\" : `-${pad(reading.d, 2)}`}`\n : `${pad(reading.y, 4)}-${pad(reading.m, 2)}${reading.d === null ? \"\" : `-${pad(reading.d, 2)}`}`;\n\nconst NUM = 0;\nconst ALPHA = 1;\nconst PUNCT = 2;\n\n/** A token of a folded text: a run of digits, a run of letters or one other character. */\ninterface Lexeme {\n readonly type: 0 | 1 | 2;\n readonly i: number;\n readonly j: number;\n readonly text: string;\n /** This value is true when a space comes before the token. */\n readonly gap: boolean;\n}\n\nconst lex = (f: string, work: Work): Lexeme[] => {\n const out: Lexeme[] = [];\n let gap = false;\n let i = 0;\n while (i < f.length) {\n work.steps += 1;\n const char = f[i]!;\n if (char === \" \") {\n gap = true;\n i += 1;\n continue;\n }\n let j = i + 1;\n let type: 0 | 1 | 2 = PUNCT;\n if (isDigitAt(f, i)) {\n type = NUM;\n while (isDigitAt(f, j)) j += 1;\n } else if (isLetterAt(f, i)) {\n type = ALPHA;\n while (isLetterAt(f, j)) j += 1;\n }\n work.steps += j - i;\n out.push({ type, i, j, text: f.slice(i, j), gap });\n gap = false;\n i = j;\n }\n return out;\n};\n\nconst isNum = (token: Lexeme | undefined, min: number, max: number): token is Lexeme =>\n token !== undefined && token.type === NUM && token.text.length >= min && token.text.length <= max;\nconst isPunct = (token: Lexeme | undefined, chars: string): token is Lexeme =>\n token !== undefined && token.type === PUNCT && !token.gap && chars.includes(token.text);\nconst glued = (token: Lexeme | undefined): boolean => token !== undefined && !token.gap;\n\ninterface DateMatch {\n /** This value is the index of the token after the date. */\n readonly end: number;\n readonly readings: readonly DateReading[];\n}\n\n/** This function reads a day after a month or before it: one or two digits, and an ordinal suffix. */\nconst dayAt = (\n tokens: readonly Lexeme[],\n k: number,\n): { readonly d: number; readonly next: number } | undefined => {\n const token = tokens[k];\n if (!isNum(token, 1, 2)) return undefined;\n const after = tokens[k + 1];\n if (after !== undefined && glued(after)) {\n if (after.type === ALPHA) {\n if (!ORDINALS.has(after.text)) return undefined;\n return { d: Number(token.text), next: k + 2 };\n }\n // a time (5:30) or a decimal (4.5) is not a day\n if (\n after.type === PUNCT &&\n (after.text === \":\" || after.text === \".\") &&\n isNum(tokens[k + 2], 1, 4) &&\n glued(tokens[k + 2])\n )\n return undefined;\n if (after.type === NUM) return undefined;\n }\n return { d: Number(token.text), next: k + 1 };\n};\n\nconst yearAt = (\n tokens: readonly Lexeme[],\n k: number,\n): { readonly y: number; readonly next: number } | undefined => {\n let at = k;\n if (isPunct(tokens[at], \",\")) at += 1;\n const token = tokens[at];\n if (!isNum(token, 4, 4)) return undefined;\n if (glued(tokens[at + 1]) && tokens[at + 1]!.type === NUM) return undefined;\n return { y: Number(token.text), next: at + 1 };\n};\n\n/** This function reads a date that starts at a token, or gives undefined. It looks at a constant number of tokens. */\nconst dateAt = (tokens: readonly Lexeme[], t: number): DateMatch | undefined => {\n const a = tokens[t]!;\n const previous = tokens[t - 1];\n const chained =\n previous !== undefined &&\n !a.gap &&\n (previous.type === NUM || (previous.type === PUNCT && \"/.-\".includes(previous.text)));\n if (a.type === NUM && !chained) {\n const p1 = tokens[t + 1];\n const b = tokens[t + 2];\n const p2 = tokens[t + 3];\n const c = tokens[t + 4];\n const numeric =\n isPunct(p1, \"-/.\") &&\n isNum(b, 1, 2) &&\n !b.gap &&\n isPunct(p2, p1.text) &&\n glued(c) &&\n c!.type === NUM;\n if (numeric && a.text.length === 4 && isNum(c, 1, 2)) {\n const y = Number(a.text);\n const m = Number(b.text);\n const d = Number(c.text);\n if (!validDate(y, m, d)) return undefined;\n const iso = p1.text === \"-\" && b.text.length === 2 && c.text.length === 2;\n return { end: t + 5, readings: [{ y, m, d, form: iso ? \"iso\" : \"ymd\" }] };\n }\n if (numeric && a.text.length <= 2 && isNum(c, 4, 4)) {\n const first = Number(a.text);\n const second = Number(b.text);\n const y = Number(c.text);\n if (glued(tokens[t + 5]) && tokens[t + 5]!.type === NUM) return undefined;\n const readings: DateReading[] = [];\n if (first === second) {\n if (validDate(y, first, second)) readings.push({ y, m: first, d: second, form: \"numeric\" });\n } else {\n if (validDate(y, first, second)) readings.push({ y, m: first, d: second, form: \"mdy\" });\n if (validDate(y, second, first)) readings.push({ y, m: second, d: first, form: \"dmy\" });\n }\n return readings.length === 0 ? undefined : { end: t + 5, readings };\n }\n }\n if (a.type === ALPHA) {\n const m = MONTHS.get(a.text);\n if (m === undefined) return undefined;\n let k = t + 1;\n if (isPunct(tokens[k], \".\")) k += 1;\n const day = tokens[k]?.gap === true || k > t + 1 ? dayAt(tokens, k) : undefined;\n if (day !== undefined) {\n const year = yearAt(tokens, day.next);\n const y = year?.y ?? null;\n if (!validDate(y, m, day.d)) return undefined;\n return { end: year?.next ?? day.next, readings: [{ y, m, d: day.d, form: \"written\" }] };\n }\n const year = yearAt(tokens, k);\n if (year === undefined || !validDate(year.y, m, null)) return undefined;\n return { end: year.next, readings: [{ y: year.y, m, d: null, form: \"written\" }] };\n }\n if (a.type === NUM && !chained) {\n const day = dayAt(tokens, t);\n if (day === undefined) return undefined;\n let k = day.next;\n if (tokens[k]?.type === ALPHA && tokens[k]!.text === \"of\") k += 1;\n const month = tokens[k];\n if (month === undefined || month.type !== ALPHA || !month.gap) return undefined;\n const m = MONTHS.get(month.text);\n if (m === undefined) return undefined;\n k += 1;\n if (isPunct(tokens[k], \".\")) k += 1;\n const year = yearAt(tokens, k);\n const y = year?.y ?? null;\n if (!validDate(y, m, day.d)) return undefined;\n return { end: year?.next ?? k, readings: [{ y, m, d: day.d, form: \"written\" }] };\n }\n return undefined;\n};\n\ninterface DateToken {\n readonly i: number;\n readonly j: number;\n readonly readings: readonly DateReading[];\n}\n\nconst scanDates = (f: string, work: Work): DateToken[] => {\n const tokens = lex(f, work);\n const out: DateToken[] = [];\n let t = 0;\n while (t < tokens.length) {\n work.steps += 1;\n const found = dateAt(tokens, t);\n if (found === undefined) {\n t += 1;\n continue;\n }\n out.push({ i: tokens[t]!.i, j: tokens[found.end - 1]!.j, readings: found.readings });\n t = found.end;\n }\n return out;\n};\n\nconst dateCands = (doc: Doc, work: Work): Cand<DateReading>[] =>\n cached(doc, \"date\", () =>\n scanDates(doc.folded.text, work).map((token) => {\n const span = spanOf(doc, token.i, token.j);\n const exact = doc.text.slice(span.start, span.end);\n return {\n where: { span, path: null },\n raw: exact,\n exact,\n excerpt: () => excerptOf(doc.text, span.start, span.end),\n readings: token.readings,\n };\n }),\n );\n\n/** This function reads a proposed date: ISO 8601, written English months, or numbers. It gives no reading for a text that is not one date. */\nconst claimDate = (\n value: string | number,\n): { readonly readings: DateReading[]; readonly time: boolean } => {\n if (typeof value === \"number\") return { readings: [], time: false };\n const text = fold(value, \"quote\").trim();\n const iso =\n /^(\\d{4})-(\\d{2})(?:-(\\d{2}))?(t\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d+)?)?(?:z|[+-]\\d{2}:?\\d{2})?)?$/.exec(\n text,\n );\n if (iso !== null) {\n const y = Number(iso[1]);\n const m = Number(iso[2]);\n const d = iso[3] === undefined ? null : Number(iso[3]);\n if (iso[4] !== undefined && d === null) return { readings: [], time: false };\n return validDate(y, m, d)\n ? { readings: [{ y, m, d, form: \"iso\" }], time: iso[4] !== undefined }\n : { readings: [], time: false };\n }\n const work: Work = { steps: 0 };\n const tokens = lex(text, work);\n let t = 0;\n if (tokens[0]?.type === ALPHA && WEEKDAYS.has(tokens[0].text)) {\n t = 1;\n if (tokens[1]?.type === PUNCT && tokens[1].text === \",\") t = 2;\n }\n const found = t < tokens.length ? dateAt(tokens, t) : undefined;\n const rest = found === undefined ? [] : tokens.slice(found.end);\n if (found === undefined || rest.some((token) => token.text !== \".\"))\n return { readings: [], time: false };\n return { readings: [...found.readings], time: false };\n};\n\nconst DATE: Comparator<DateReading, DateReading> = {\n compare: (claim, reading) => {\n if (claim.m !== reading.m) return undefined;\n if (claim.y !== null && reading.y !== null && claim.y !== reading.y) return undefined;\n if (claim.d !== null && reading.d !== null && claim.d !== reading.d) return undefined;\n // the stored text says less than the value: the check does not add the year or the day\n const missing =\n (claim.y !== null && reading.y === null) || (claim.d !== null && reading.d === null);\n const partial =\n missing ||\n (claim.y === null && reading.y !== null) ||\n (claim.d === null && reading.d !== null);\n const labels = [claim.form === reading.form ? \"date-form\" : `date-${reading.form}`];\n if (partial) labels.push(\"date-partial\");\n return { clean: !missing, key: dateText(reading), reading: dateText(reading), labels };\n },\n display: dateText,\n};\n\n// ── phone numbers ───────────────────────────────────────────────────────────\n\ninterface PhoneReading {\n /** These digits are the number with no international prefix and no national trunk prefix. */\n readonly digits: string;\n /** This value is true when the number starts with `+` or `00`. */\n readonly intl: boolean;\n}\n\nconst phoneReading = (written: string): PhoneReading | undefined => {\n // \"+44 (0)20\" writes the trunk prefix of the national form in brackets\n const text = written.replace(/\\(0\\)/g, \"\");\n let digits = text.replace(/\\D/g, \"\");\n let intl = text.trimStart().startsWith(\"+\");\n if (!intl && digits.startsWith(\"00\")) {\n intl = true;\n digits = digits.slice(2);\n } else if (!intl && digits.startsWith(\"0\")) digits = digits.slice(1);\n if (digits.length < 7 || digits.length > 15) return undefined;\n return { digits, intl };\n};\n\nconst phoneText = (reading: PhoneReading): string => `${reading.intl ? \"+\" : \"\"}${reading.digits}`;\n\n/** The longest country code has three digits. */\nconst COUNTRY_DIGITS = 3;\n\nconst PHONE: Comparator<PhoneReading, PhoneReading> = {\n compare: (claim, reading) => {\n const key = reading.digits;\n if (claim.digits === reading.digits)\n return { clean: true, key, reading: phoneText(reading), labels: [\"phone-digits\"] };\n if (reading.digits.endsWith(claim.digits))\n return { clean: true, key, reading: phoneText(reading), labels: [\"phone-suffix\"] };\n if (claim.digits.endsWith(reading.digits)) {\n // the stored number has no country code, and the value has one: the rest is the national number\n const country = claim.digits.length - reading.digits.length;\n const clean = claim.intl && !reading.intl && country <= COUNTRY_DIGITS;\n return { clean, key, reading: phoneText(reading), labels: [\"phone-suffix\"] };\n }\n return undefined;\n },\n display: phoneText,\n same: (a, b) => a.key.endsWith(b.key) || b.key.endsWith(a.key),\n};\n\nconst PHONE_CHARS = \"-.()/\";\n\n/** This function finds the phone numbers of a folded text: 7 to 15 digits with spaces, dashes, points, brackets and slashes. */\nconst phoneCands = (doc: Doc, work: Work): Cand<PhoneReading>[] =>\n cached(doc, \"phone\", () => {\n const f = doc.folded.text;\n const n = f.length;\n const out: Cand<PhoneReading>[] = [];\n let i = 0;\n while (i < n) {\n work.steps += 1;\n const char = f[i]!;\n const starts =\n (isDigitAt(f, i) ||\n ((char === \"+\" || char === \"(\") && (isDigitAt(f, i + 1) || f[i + 1] === \"(\"))) &&\n !isWordAt(f, i - 1) &&\n f[i - 1] !== \"+\";\n if (!starts) {\n i += 1;\n continue;\n }\n let j = i;\n while (j < n) {\n work.steps += 1;\n const unit = f[j]!;\n if (isDigitAt(f, j) || PHONE_CHARS.includes(unit) || (unit === \"+\" && j === i)) {\n j += 1;\n continue;\n }\n if (unit === \" \" && (isDigitAt(f, j + 1) || f[j + 1] === \"(\")) {\n j += 1;\n continue;\n }\n break;\n }\n let e = j;\n while (e > i && !isDigitAt(f, e - 1)) e -= 1;\n const next = Math.max(j, i + 1);\n if (e > i && !isWordAt(f, e)) {\n const span = spanOf(doc, i, e);\n const exact = doc.text.slice(span.start, span.end);\n const reading = phoneReading(f.slice(i, e));\n if (reading !== undefined) {\n out.push({\n where: { span, path: null },\n raw: exact,\n exact,\n excerpt: () => excerptOf(doc.text, span.start, span.end),\n readings: [reading],\n });\n }\n }\n i = next;\n }\n return out;\n });\n\nconst claimPhone = (value: string | number): PhoneReading[] => {\n const text = (typeof value === \"number\" ? String(value) : fold(value, \"quote\").trim()).replace(\n /^tel:/,\n \"\",\n );\n if (!/^\\+?[\\d\\s\\-.()/]+$/.test(text)) return [];\n const reading = phoneReading(text);\n return reading === undefined ? [] : [reading];\n};\n\n// ── URLs ────────────────────────────────────────────────────────────────────\n\ninterface UrlReading {\n /** This URL is the canonical form (`canonicalUrl`). */\n readonly url: string;\n /** This value is true when the stored text has no scheme (`www.example.com`). */\n readonly schemeless: boolean;\n /** This value is true when the value was relative and the check resolved it against the page URL. */\n readonly relative: boolean;\n readonly written: string;\n}\n\nconst withoutScheme = (url: string): string => url.replace(/^[a-z][a-z0-9+.-]*:/i, \"\");\n\nconst URL_STOP = /[\\s<>\"`{}|\\\\^]/u;\nconst URL_TRAIL = /[.,;:!?'\"]/;\n\n/** This function finds the URLs of a text: `http://`, `https://` and `www.` forms. It reads the original text, because a path keeps its case. */\nconst urlCands = (doc: Doc, work: Work): Cand<UrlReading>[] =>\n cached(doc, \"url\", () => {\n const text = doc.text;\n const n = text.length;\n const out: Cand<UrlReading>[] = [];\n let i = 0;\n while (i < n) {\n work.steps += 1;\n const code = text.charCodeAt(i) | 0x20;\n let prefix = 0;\n if (code === 0x68 && !isWordAt(text, i - 1)) {\n const head = text.slice(i, i + 8).toLowerCase();\n prefix = head.startsWith(\"https://\") ? 8 : head.startsWith(\"http://\") ? 7 : 0;\n } else if (\n code === 0x77 &&\n !isWordAt(text, i - 1) &&\n text[i - 1] !== \"/\" &&\n text[i - 1] !== \".\"\n ) {\n prefix = text.slice(i, i + 4).toLowerCase() === \"www.\" ? 4 : 0;\n }\n if (prefix === 0) {\n i += 1;\n continue;\n }\n const start = i;\n let j = start + prefix;\n while (j < n && !URL_STOP.test(text[j]!)) {\n j += 1;\n work.steps += 1;\n }\n i = j;\n let e = j;\n // a final point or bracket belongs to the sentence, not to the URL; the counts make it linear\n const balance = { \")\": 0, \"]\": 0 };\n for (let at = start; at < j; at += 1) {\n const char = text[at];\n if (char === \"(\") balance[\")\"] += 1;\n else if (char === \")\") balance[\")\"] -= 1;\n else if (char === \"[\") balance[\"]\"] += 1;\n else if (char === \"]\") balance[\"]\"] -= 1;\n }\n work.steps += j - start;\n while (e > start + prefix) {\n work.steps += 1;\n const last = text[e - 1]!;\n if (URL_TRAIL.test(last)) {\n e -= 1;\n continue;\n }\n if ((last === \")\" || last === \"]\") && balance[last] < 0) {\n balance[last] += 1;\n e -= 1;\n continue;\n }\n break;\n }\n if (e <= start + prefix) continue;\n const written = text.slice(start, e);\n const schemeless = prefix === 4;\n let url: string;\n try {\n url = canonicalUrl(schemeless ? `https://${written}` : written);\n } catch {\n continue;\n }\n const span: FieldSpan = { start, end: e, in: doc.name };\n out.push({\n where: { span, path: null },\n raw: written,\n exact: written,\n excerpt: () => excerptOf(text, start, e),\n readings: [{ url, schemeless, relative: false, written }],\n });\n }\n return out;\n });\n\n/** This function gives the stored links of a page as places of a URL. The store keeps the canonical form of each link. */\nconst linkCands = (meta: Readonly<Record<string, unknown>>, work: Work): Cand<UrlReading>[] => {\n const links = meta[\"links\"];\n if (!Array.isArray(links)) return [];\n const out: Cand<UrlReading>[] = [];\n for (const [index, link] of links.entries()) {\n work.steps += 1;\n if (link === null || typeof link !== \"object\") continue;\n const href = (link as { href?: unknown }).href;\n const label = (link as { text?: unknown }).text;\n if (typeof href !== \"string\") continue;\n out.push({\n where: { span: null, path: `links[${String(index)}]` },\n raw: href,\n exact: href,\n excerpt: () => (typeof label === \"string\" && label.length > 0 ? `${label} (${href})` : href),\n readings: [{ url: href, schemeless: false, relative: false, written: href }],\n });\n }\n return out;\n};\n\n/** This function reads a proposed URL, and resolves a relative URL against the URL of the page. Only `http` and `https` URLs are URLs of this kind. */\nconst claimUrl = (value: string | number, base: string | null): UrlReading[] => {\n if (typeof value === \"number\") return [];\n const text = value.trim().replace(/^<(.*)>$/s, \"$1\");\n if (text.length === 0 || /\\s/.test(text)) return [];\n const hasScheme = /^[a-z][a-z0-9+.-]*:/i.test(text);\n const written = !hasScheme && /^www\\./i.test(text) ? `//${text}` : text;\n let resolved: URL;\n try {\n resolved = hasScheme ? new URL(written) : new URL(written, base ?? undefined);\n } catch {\n return [];\n }\n if (resolved.protocol !== \"http:\" && resolved.protocol !== \"https:\") return [];\n return [\n { url: canonicalUrl(resolved.href), schemeless: false, relative: !hasScheme, written: text },\n ];\n};\n\n/** A text with an `http` or `https` scheme, a `www.` host, or a path from the root. */\nconst LOOKS_LIKE_URL = /^(?:https?:\\/\\/|www\\.|\\/|\\.\\.?\\/)/i;\n\nconst URL_KIND: Comparator<UrlReading, UrlReading> = {\n compare: (claim, reading) => {\n const labels: string[] = [];\n if (claim.relative || reading.relative) labels.push(\"url-resolved\");\n if (reading.schemeless) {\n if (withoutScheme(claim.url) !== withoutScheme(reading.url)) return undefined;\n labels.push(\"url-scheme\");\n return { clean: true, key: claim.url, reading: claim.url, labels };\n }\n if (claim.url !== reading.url) return undefined;\n if (labels.length === 0) labels.push(\"url-form\");\n return { clean: true, key: reading.url, reading: reading.url, labels };\n },\n display: (reading) => reading.url,\n};\n\n// ── email addresses ─────────────────────────────────────────────────────────\n\nconst LOCAL = /^[A-Za-z0-9._%+-]$/;\nconst DOMAIN = /^[A-Za-z0-9.-]$/;\nconst DOMAIN_NAME = /^[a-z0-9-]+(\\.[a-z0-9-]+)*\\.[a-z]{2,}$/i;\n\n/** This function finds the email addresses of a text. Each unit is read two times at most. */\nconst emailCands = (doc: Doc, work: Work): Cand<string>[] =>\n cached(doc, \"email\", () => {\n const text = doc.text;\n const n = text.length;\n const out: Cand<string>[] = [];\n let i = 0;\n while (i < n) {\n work.steps += 1;\n if (text[i] !== \"@\") {\n i += 1;\n continue;\n }\n let s = i;\n while (s > 0 && LOCAL.test(text[s - 1]!)) {\n s -= 1;\n work.steps += 1;\n }\n while (s < i && text[s] === \".\") s += 1;\n let e = i + 1;\n while (e < n && DOMAIN.test(text[e]!)) {\n e += 1;\n work.steps += 1;\n }\n const next = e;\n while (e > i + 1 && (text[e - 1] === \".\" || text[e - 1] === \"-\")) e -= 1;\n if (s < i && DOMAIN_NAME.test(text.slice(i + 1, e))) {\n const written = text.slice(s, e);\n const start = s;\n const end = e;\n out.push({\n where: { span: { start, end, in: doc.name }, path: null },\n raw: written,\n exact: written,\n excerpt: () => excerptOf(text, start, end),\n readings: [written.toLowerCase()],\n });\n }\n i = Math.max(next, i + 1);\n }\n return out;\n });\n\nconst claimEmail = (value: string | number): string[] => {\n if (typeof value === \"number\") return [];\n const text = value.trim().replace(/^mailto:/i, \"\");\n const at = text.lastIndexOf(\"@\");\n if (at <= 0 || !/^[A-Za-z0-9._%+-]+$/.test(text.slice(0, at))) return [];\n return DOMAIN_NAME.test(text.slice(at + 1)) ? [text.toLowerCase()] : [];\n};\n\nconst EMAIL: Comparator<string, string> = {\n compare: (claim, reading) =>\n claim === reading ? { clean: true, key: reading, reading, labels: [\"email-case\"] } : undefined,\n display: (reading) => reading,\n};\n\n// ── JSON-LD ─────────────────────────────────────────────────────────────────\n\n/** A value of the JSON-LD at a path, with that path. */\ninterface Leaf {\n readonly path: string;\n readonly value: string | number | boolean;\n}\n\n/** A key of the JSON-LD goes into a path only when it is a name. Thus a path holds no other text of the page. */\nconst PATH_KEY = /^@?[A-Za-z_][A-Za-z0-9_-]{0,63}$/;\n\ninterface Visit {\n readonly value: unknown;\n readonly path: string;\n readonly depth: number;\n}\n\n/**\n * This function gives the values of the JSON-LD at a path. The first part of the path names a\n * schema.org type (`*` is each top-level record), and the path starts at each object of that type,\n * at any depth. Each array on the path gives each of its values.\n */\nconst leavesAt = (records: readonly unknown[], path: string, work: Work): Leaf[] => {\n const [head = \"\", ...rest] = path.split(\".\");\n const type = head.toLowerCase();\n const starts: Array<{ readonly value: unknown; readonly path: string }> = [];\n // an explicit stack: JSON-LD nested deeply cannot overflow the call stack\n const stack: Visit[] = [];\n for (let index = records.length - 1; index >= 0; index -= 1)\n stack.push({ value: records[index], path: `jsonld[${String(index)}]`, depth: 0 });\n while (stack.length > 0) {\n work.steps += 1;\n const { value, path: at, depth } = stack.pop()!;\n if (Array.isArray(value)) {\n for (let index = value.length - 1; index >= 0; index -= 1)\n stack.push({ value: value[index], path: `${at}[${String(index)}]`, depth: depth + 1 });\n continue;\n }\n if (value === null || typeof value !== \"object\") continue;\n const record = value as Record<string, unknown>;\n if (type === \"*\") {\n if (depth === 0) starts.push({ value: record, path: at });\n continue;\n }\n if (typesOf(record).some((name) => name.toLowerCase() === type))\n starts.push({ value: record, path: at });\n const keys = Object.keys(record);\n for (let index = keys.length - 1; index >= 0; index -= 1) {\n const key = keys[index]!;\n if (PATH_KEY.test(key))\n stack.push({ value: record[key], path: `${at}.${key}`, depth: depth + 1 });\n }\n }\n const out: Leaf[] = [];\n for (const start of starts) {\n const walk: Visit[] = [{ value: start.value, path: start.path, depth: 0 }];\n while (walk.length > 0) {\n work.steps += 1;\n const { value, path: at, depth } = walk.pop()!;\n if (Array.isArray(value)) {\n for (let index = value.length - 1; index >= 0; index -= 1)\n walk.push({ value: value[index], path: `${at}[${String(index)}]`, depth });\n continue;\n }\n if (depth === rest.length) {\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\")\n out.push({ path: at, value });\n else if (value !== null && typeof value === \"object\") {\n const inner = (value as Record<string, unknown>)[\"@value\"];\n if (typeof inner === \"string\" || typeof inner === \"number\" || typeof inner === \"boolean\")\n out.push({ path: `${at}.@value`, value: inner });\n }\n continue;\n }\n if (value === null || typeof value !== \"object\") continue;\n const key = rest[depth]!;\n const next = (value as Record<string, unknown>)[key];\n if (next !== undefined) walk.push({ value: next, path: `${at}.${key}`, depth: depth + 1 });\n }\n }\n return out;\n};\n\nconst leafText = (value: string | number | boolean): string =>\n typeof value === \"number\" ? (decimalOf(value) ?? String(value)) : String(value);\n\n/** This function checks a value against the JSON-LD at a path. It compares as a number, a date, a URL and a text, in that sequence. */\nconst checkJsonLd = (\n kind: string,\n path: string,\n value: string | number,\n claimText: string,\n source: ExtractSource,\n work: Work,\n): FieldCheck => {\n const meta = source.meta ?? {};\n const records = Array.isArray(meta[\"jsonld\"]) ? (meta[\"jsonld\"] as unknown[]) : [];\n const leaves = leavesAt(records, path, work);\n const dropped = meta[\"jsonld_dropped\"];\n const missing =\n typeof dropped === \"number\" && dropped > 0\n ? `the store keeps only a part of the JSON-LD of this page (${String(dropped)} records left out), so the path can be in the part that it left out`\n : null;\n if (leaves.length === 0) return empty(\"not-found\", kind, missing);\n const base = source.url ?? null;\n const cand = <R>(leaf: Leaf, readings: readonly R[]): Cand<R> => ({\n where: { span: null, path: leaf.path },\n raw: leaf.value,\n exact: leafText(leaf.value),\n excerpt: () => JSON.stringify(leaf.value).slice(0, 200),\n readings,\n });\n const stringOf = (leaf: Leaf): string | undefined =>\n typeof leaf.value === \"string\" ? leaf.value : undefined;\n const folded = fold(claimText, \"quote\");\n const TEXT: Comparator<string, string> = {\n compare: (claim, reading) =>\n fold(reading, \"quote\") === folded\n ? { clean: true, key: folded, reading: folded, labels: textLabels(reading, claim) }\n : undefined,\n display: (reading) => reading,\n };\n const attempts: Array<() => FieldCheck | undefined> = [\n () => {\n const claims = claimNumber(value);\n if (claims.length === 0) return undefined;\n const cands = leaves.map((leaf) =>\n cand(leaf, typeof leaf.value === \"boolean\" ? [] : claimNumber(leaf.value)),\n );\n return decide(kind, claimText, claims, cands, NUMBER, work);\n },\n () => {\n const claim = claimDate(value);\n if (claim.readings.length === 0) return undefined;\n const cands = leaves.map((leaf) => {\n const text = stringOf(leaf);\n return cand(leaf, text === undefined ? [] : claimDate(text).readings);\n });\n return decide(kind, claimText, claim.readings, cands, DATE, work);\n },\n () => {\n // only a text that looks like a URL is a URL here: each word is a relative URL\n const claims = LOOKS_LIKE_URL.test(claimText) ? claimUrl(value, base) : [];\n if (claims.length === 0) return undefined;\n const cands = leaves.map((leaf) => {\n const text = stringOf(leaf);\n return cand(\n leaf,\n text === undefined || !LOOKS_LIKE_URL.test(text.trim()) ? [] : claimUrl(text, base),\n );\n });\n return decide(kind, claimText, claims, cands, URL_KIND, work);\n },\n () => {\n if (folded.length === 0) return undefined;\n const cands = leaves.map((leaf) => cand(leaf, [leafText(leaf.value)]));\n return decide(kind, claimText, [claimText], cands, TEXT, work);\n },\n ];\n for (const attempt of attempts) {\n const result = attempt();\n if (result !== undefined && result.status !== \"not-found\") return result;\n }\n return empty(\"not-found\", kind, missing);\n};\n\n// ── the check of the fields ─────────────────────────────────────────────────\n\ninterface Context {\n readonly source: ExtractSource;\n readonly text: Doc;\n full: Doc | undefined | null;\n readonly work: Work;\n}\n\n/** This function gives the whole text of a page that the reader cut, or null. It folds that text at its first use only. */\nconst fullOf = (context: Context): Doc | null => {\n if (context.full === undefined) {\n const full = context.source.full_text;\n context.full =\n full === undefined || full === context.source.text\n ? null\n : prepare(\"full_text\", full, context.work);\n }\n return context.full;\n};\n\n/** This function checks a field in the text. When the reader cut the text and the text does not hold the value, it checks the whole text too. */\nconst inText = (context: Context, check: (doc: Doc) => FieldCheck): FieldCheck => {\n const first = check(context.text);\n if (first.status !== \"not-found\") return first;\n const full = fullOf(context);\n if (full === null) return first;\n const second = check(full);\n return second.status === \"not-found\" ? first : second;\n};\n\n/** This function reads the kind of a field. A kind that is not a kind throws a `RangeError`. */\nconst kindOf = (name: string, claim: FieldClaim): string => {\n const kind: string = claim.kind ?? (typeof claim.value === \"number\" ? \"number\" : \"text\");\n if (FIELD_KINDS.includes(kind)) return kind;\n if (kind.startsWith(\"json-ld:\") && kind.length > \"json-ld:\".length && !/\\s/.test(kind))\n return kind;\n throw new RangeError(\n `the kind of the field ${name} is ${FIELD_KINDS.join(\", \")} or json-ld:<path>, not ${JSON.stringify(kind)}`,\n );\n};\n\nconst INVALID: Readonly<Record<string, string>> = {\n number: \"the value is not a number\",\n money: \"the value is not an amount of money\",\n date: \"the value is not a date\",\n url: \"the value is not an http or https URL\",\n email: \"the value is not an email address\",\n phone: \"the value is not a phone number of 7 to 15 digits\",\n};\n\nconst checkOne = (name: string, claim: FieldClaim, context: Context): FieldCheck => {\n const kind = kindOf(name, claim);\n const value = claim.value;\n if (typeof value === \"number\" && !Number.isFinite(value))\n return empty(\"invalid\", kind, \"the value is not a finite number\");\n // a mailto: or tel: link names the address or the number, so the exact text is without it\n const prefix = kind === \"email\" ? /^mailto:/i : kind === \"phone\" ? /^tel:/i : undefined;\n const trimmed = typeof value === \"number\" ? (decimalOf(value) ?? \"\") : value.trim();\n const claimText = prefix === undefined ? trimmed : trimmed.replace(prefix, \"\");\n if (claimText.length === 0) return empty(\"invalid\", kind, \"the value is empty\");\n const work = context.work;\n const invalid = (): FieldCheck =>\n empty(\"invalid\", kind, INVALID[kind] ?? \"the value is not valid\");\n switch (kind) {\n case \"text\":\n return inText(context, (doc) => checkText(doc, claimText, work));\n case \"number\": {\n const claims = claimNumber(value);\n if (claims.length === 0) return invalid();\n return inText(context, (doc) =>\n decide(kind, claimText, claims, numberCands(doc, work), NUMBER, work),\n );\n }\n case \"money\": {\n const claims = claimMoney(value);\n if (claims.length === 0) return invalid();\n return inText(context, (doc) =>\n decide(kind, claimText, claims, moneyCands(doc, work), MONEY, work),\n );\n }\n case \"date\": {\n const claim = claimDate(value);\n if (claim.readings.length === 0) return invalid();\n const result = inText(context, (doc) =>\n decide(kind, claimText, claim.readings, dateCands(doc, work), DATE, work),\n );\n if (!claim.time || result.status === \"verified\") return result;\n const timeNote = \"the check compares the date of the value, not its time\";\n return { ...result, note: result.note === null ? timeNote : `${result.note}; ${timeNote}` };\n }\n case \"url\": {\n const claims = claimUrl(value, context.source.url ?? null);\n if (claims.length === 0) return invalid();\n const links = linkCands(context.source.meta ?? {}, work);\n return inText(context, (doc) =>\n decide(kind, claimText, claims, [...urlCands(doc, work), ...links], URL_KIND, work),\n );\n }\n case \"email\": {\n const claims = claimEmail(value);\n if (claims.length === 0) return invalid();\n return inText(context, (doc) =>\n decide(kind, claimText, claims, emailCands(doc, work), EMAIL, work),\n );\n }\n case \"phone\": {\n const claims = claimPhone(value);\n if (claims.length === 0) return invalid();\n return inText(context, (doc) =>\n decide(kind, claimText, claims, phoneCands(doc, work), PHONE, work),\n );\n }\n default:\n return checkJsonLd(\n kind,\n kind.slice(\"json-ld:\".length),\n value,\n claimText,\n context.source,\n work,\n );\n }\n};\n\n/** This function validates the fields, and gives their names and values. A field that is not valid throws a `RangeError`. */\nconst claimsOf = (\n fields: Readonly<Record<string, FieldClaim>>,\n): Array<readonly [string, FieldClaim]> => {\n if (fields === null || typeof fields !== \"object\" || Array.isArray(fields))\n throw new RangeError(\"fields must be an object of names and values\");\n const entries = Object.entries(fields);\n for (const [name, claim] of entries) {\n if (name.length === 0) throw new RangeError(\"the name of a field must not be empty\");\n if (claim === null || typeof claim !== \"object\")\n throw new RangeError(`the field ${name} must be an object with a value`);\n if (typeof claim.value !== \"string\" && typeof claim.value !== \"number\")\n throw new RangeError(`the value of the field ${name} must be a text or a number`);\n kindOf(name, claim);\n }\n return entries;\n};\n\nconst summaryOf = (statuses: readonly FieldStatus[]): ExtractSummary => {\n const count = (status: FieldStatus): number => statuses.filter((one) => one === status).length;\n return {\n fields: statuses.length,\n verified: count(\"verified\"),\n normalized: count(\"normalized\"),\n ambiguous: count(\"ambiguous\"),\n not_found: count(\"not-found\"),\n held_back: count(\"held-back\"),\n invalid: count(\"invalid\"),\n };\n};\n\n/**\n * This function checks the proposed values of fields against the text and the metadata of a\n * document. It sends no request and writes nothing. It does not make values. A field that is not\n * valid throws a `RangeError`. The work grows in proportion to the length of the text.\n *\n * @beta\n */\nexport const checkFields = (\n source: ExtractSource,\n fields: Readonly<Record<string, FieldClaim>>,\n): FieldsChecked => {\n const claims = claimsOf(fields);\n const work: Work = { steps: 0 };\n const context: Context = {\n source,\n text: prepare(\"text\", source.text, work),\n full: undefined,\n work,\n };\n const checked: Record<string, FieldCheck> = {};\n for (const [name, claim] of claims) checked[name] = checkOne(name, claim, context);\n return {\n fields: checked,\n summary: summaryOf(Object.values(checked).map((field) => field.status)),\n steps: work.steps,\n };\n};\n\n// ── the check of a stored document ──────────────────────────────────────────\n\nconst withCapture = (\n fields: Readonly<Record<string, FieldCheck>>,\n capture: string | null,\n fetchedAt: string | null,\n): Record<string, FieldResult> =>\n Object.fromEntries(\n Object.entries(fields).map(([name, field]) => [\n name,\n { ...field, capture, fetched_at: fetchedAt },\n ]),\n );\n\n/** This function gives the same result for each field, with no check: for a held-back document, or a time before the first capture. */\nconst sameForEach = (\n claims: ReadonlyArray<readonly [string, FieldClaim]>,\n status: FieldStatus,\n note: string,\n): Record<string, FieldResult> =>\n Object.fromEntries(\n claims.map(([name, claim]) => [\n name,\n { ...empty(status, kindOf(name, claim), note), capture: null, fetched_at: null },\n ]),\n );\n\n/**\n * This function checks the proposed values of fields against a stored document. It does not make\n * values. It applies the rules of `verify`:\n *\n * - With no option, it checks the current version. `capture` checks the version of one capture,\n * and `at` checks the version that was current at a time.\n * - A held-back document gives `held-back` for each field, with no position and no capture, unless\n * `userProvided`. The crawler then logs an override.\n * - A field that is not valid throws a `RangeError`, and an unknown document throws an error.\n *\n * @beta\n */\nexport const extractDocument = async (\n runtime: CrawlRuntime,\n id: string,\n fields: Readonly<Record<string, FieldClaim>>,\n options: ExtractOptions = {},\n): Promise<ExtractResult> => {\n const claims = claimsOf(fields);\n if (options.at !== undefined && options.capture !== undefined)\n throw new RangeError(\"give capture or at, not the two: each one chooses a version\");\n const at = options.at === undefined ? undefined : isoTime(\"at\", options.at);\n const doc = runtime.index.get(id);\n if (doc === undefined)\n throw new Error(`no stored document ${id}: find one with find(), or fetch its page`);\n let version: VersionText | undefined;\n let first: string | undefined;\n if (options.capture !== undefined) {\n version = runtime.index.versionText(id, options.capture);\n if (version === undefined)\n throw new Error(`the document ${id} has no version from the capture ${options.capture}`);\n } else if (at !== undefined) ({ version, first } = versionAtTime(runtime, id, at));\n else version = runtime.index.versionText(id);\n const aiInput: AiInput =\n doc.ai_input === \"no\" || version?.ai_input === \"no\"\n ? \"no\"\n : (version?.ai_input ?? doc.ai_input);\n const userProvided = options.userProvided ?? false;\n const base = {\n doc: doc.doc,\n url: doc.url,\n captures: doc.captures,\n ...(at === undefined ? {} : { at }),\n };\n if (isHeldBack({ ai_input: aiInput }, userProvided)) {\n // no check runs: the result is the same for each value, so it tells nothing about the text\n return {\n ...base,\n capture: null,\n blob: null,\n fetched_at: null,\n held_back: true,\n fields: sameForEach(claims, \"held-back\", HELD_BACK),\n summary: summaryOf(claims.map(() => \"held-back\")),\n note: HELD_BACK,\n };\n }\n if (aiInput === \"no\" && userProvided) await recordOverride(runtime, doc, \"extract\");\n if (version === undefined) {\n const note = `the document ${id} has no version at ${at ?? \"this time\"} or before${first === undefined ? \"\" : `: its first capture is from ${first}`}`;\n return {\n ...base,\n capture: null,\n blob: null,\n fetched_at: null,\n held_back: false,\n fields: sameForEach(claims, \"not-found\", note),\n summary: summaryOf(claims.map(() => \"not-found\")),\n note,\n before_first: true,\n };\n }\n const checked = checkFields(\n {\n text: version.text,\n full_text: version.full_text,\n url: version.url ?? doc.url,\n meta: version.meta,\n },\n Object.fromEntries(claims),\n );\n const incomplete = version.meta[\"truncated\"] === true && version.full_text === undefined;\n // an archived copy says so, as in read and verify, so a citation cannot present it as the current page\n const archived = archivedOf(version.meta);\n const notes = [\n ...(incomplete && checked.summary.not_found > 0\n ? [\n \"the reader stopped before the end of the file, so a value that is not found can be in the part that it did not read\",\n ]\n : []),\n ...(archived === undefined ? [] : [archivedNote(archived)]),\n ];\n return {\n ...base,\n capture: version.capture,\n blob: version.blob,\n fetched_at: version.fetched_at,\n held_back: false,\n fields: withCapture(checked.fields, version.capture, version.fetched_at),\n summary: checked.summary,\n note: notes.length > 0 ? notes.join(\"; \") : null,\n ...(archived === undefined ? {} : { archived }),\n };\n};\n"],"mappings":"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"}
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
//#region src/urls.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* This function gives one URL for each page: a lowercase host, and no fragment, tracking
|
|
4
|
+
* parameters, empty query or default port. It decodes the escapes of unreserved characters.
|
|
5
|
+
*/
|
|
6
|
+
declare const canonicalUrl: (value: string) => string;
|
|
7
|
+
/** These options set the hosts that a crawl or a discovery keeps. */
|
|
8
|
+
interface ScopeOptions {
|
|
9
|
+
/** With the default value true, the URLs on the sites of the start URLs are in scope. */
|
|
10
|
+
readonly sameSite?: boolean | undefined;
|
|
11
|
+
/** The URLs on these hosts are in scope too. A name that starts with `*.` names the hosts under it. */
|
|
12
|
+
readonly allowHosts?: readonly string[] | undefined;
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
1
15
|
//#region src/text.d.ts
|
|
2
16
|
/**
|
|
3
17
|
* This function gives the WHATWG name of the encoding of a body, for example `utf-8` or
|
|
@@ -93,5 +107,5 @@ declare const readJsonLd: (sources: readonly string[]) => Record<string, unknown
|
|
|
93
107
|
declare const typesOf: (record: Record<string, unknown>) => string[];
|
|
94
108
|
declare const extractPage: (html: string, pageUrl: string) => PageExtract;
|
|
95
109
|
//#endregion
|
|
96
|
-
export { typesOf as a, decodeBody as c, readJsonLd as i, PageLink as n, visibleText as o, extractPage as r, bodyEncoding as s, PageExtract as t };
|
|
97
|
-
//# sourceMappingURL=html-
|
|
110
|
+
export { typesOf as a, decodeBody as c, readJsonLd as i, ScopeOptions as l, PageLink as n, visibleText as o, extractPage as r, bodyEncoding as s, PageExtract as t, canonicalUrl as u };
|
|
111
|
+
//# sourceMappingURL=html-DMgIeQfJ.d.mts.map
|
package/build/html.d.mts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import { n as canonicalUrl } from "./
|
|
2
|
-
import { a as typesOf, c as decodeBody, i as readJsonLd, n as PageLink, o as visibleText, r as extractPage, s as bodyEncoding, t as PageExtract } from "./html-BACljlkf.mjs";
|
|
1
|
+
import { a as typesOf, c as decodeBody, i as readJsonLd, n as PageLink, o as visibleText, r as extractPage, s as bodyEncoding, t as PageExtract, u as canonicalUrl } from "./html-DMgIeQfJ.mjs";
|
|
3
2
|
export { PageExtract, PageLink, bodyEncoding, canonicalUrl, decodeBody, extractPage, readJsonLd, typesOf, visibleText };
|