euparliamentmonitor 0.9.21 → 0.9.23

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.
Files changed (47) hide show
  1. package/package.json +6 -2
  2. package/scripts/aggregator/article-metadata.js +69 -14
  3. package/scripts/aggregator/editorial-brief-resolver.js +23 -0
  4. package/scripts/aggregator/html/headline.d.ts +41 -9
  5. package/scripts/aggregator/html/headline.js +69 -10
  6. package/scripts/aggregator/html/shell.js +73 -17
  7. package/scripts/aggregator/manifest/index.d.ts +1 -1
  8. package/scripts/aggregator/manifest/index.js +1 -1
  9. package/scripts/aggregator/manifest/resolver.d.ts +28 -1
  10. package/scripts/aggregator/manifest/resolver.js +61 -5
  11. package/scripts/aggregator/markdown-renderer.js +11 -0
  12. package/scripts/aggregator/metadata/artifact-category-heading.d.ts +81 -0
  13. package/scripts/aggregator/metadata/artifact-category-heading.js +353 -0
  14. package/scripts/aggregator/metadata/artifact-walker.js +29 -10
  15. package/scripts/aggregator/metadata/brief-body.d.ts +12 -0
  16. package/scripts/aggregator/metadata/brief-body.js +69 -0
  17. package/scripts/aggregator/metadata/briefing-highlight.d.ts +47 -0
  18. package/scripts/aggregator/metadata/briefing-highlight.js +469 -0
  19. package/scripts/aggregator/metadata/editorial-highlight.d.ts +18 -0
  20. package/scripts/aggregator/metadata/editorial-highlight.js +40 -1
  21. package/scripts/aggregator/metadata/heading-rules.d.ts +2 -81
  22. package/scripts/aggregator/metadata/heading-rules.js +78 -269
  23. package/scripts/aggregator/metadata/keyword-filters.d.ts +60 -0
  24. package/scripts/aggregator/metadata/keyword-filters.js +156 -0
  25. package/scripts/aggregator/metadata/lede-extractor.js +11 -2
  26. package/scripts/aggregator/metadata/priority-finding-cleaning.d.ts +22 -0
  27. package/scripts/aggregator/metadata/priority-finding-cleaning.js +181 -0
  28. package/scripts/aggregator/metadata/priority-finding-highlight.js +75 -159
  29. package/scripts/aggregator/metadata/resolve-helpers.d.ts +34 -0
  30. package/scripts/aggregator/metadata/resolve-helpers.js +202 -15
  31. package/scripts/aggregator/metadata/seo-budgets.d.ts +140 -0
  32. package/scripts/aggregator/metadata/seo-budgets.js +202 -0
  33. package/scripts/aggregator/metadata/text-truncate.d.ts +75 -0
  34. package/scripts/aggregator/metadata/text-truncate.js +277 -0
  35. package/scripts/aggregator/metadata/text-utils-constants.d.ts +96 -0
  36. package/scripts/aggregator/metadata/text-utils-constants.js +209 -0
  37. package/scripts/aggregator/metadata/text-utils.d.ts +32 -143
  38. package/scripts/aggregator/metadata/text-utils.js +119 -439
  39. package/scripts/aggregator/metadata/title-rejection.d.ts +37 -0
  40. package/scripts/aggregator/metadata/title-rejection.js +179 -0
  41. package/scripts/copy-vendor.js +84 -112
  42. package/scripts/dump-article-seo.js +640 -0
  43. package/scripts/fix-mermaid-diagrams.js +931 -0
  44. package/scripts/generators/news-indexes/backfill.d.ts +6 -1
  45. package/scripts/generators/news-indexes/backfill.js +71 -4
  46. package/scripts/validate-article-seo.js +534 -0
  47. package/scripts/validate-mermaid-diagrams.js +306 -0
@@ -0,0 +1,209 @@
1
+ // SPDX-FileCopyrightText: 2024-2026 Hack23 AB
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * @module Aggregator/Metadata/TextUtilsConstants
5
+ * @description Shared byte-budget constants and vocabularies used by
6
+ * the metadata text helpers. Extracted from `text-utils.ts` so the
7
+ * truncation/extraction helpers can live in `text-truncate.ts`
8
+ * without creating a circular import — both modules import from
9
+ * here, and `text-utils.ts` re-exports the truncators for back-compat
10
+ * with existing call-sites.
11
+ *
12
+ * **No imports.** This is a pure leaf module: only constants and
13
+ * vocabularies, no functions, no I/O.
14
+ */
15
+ // ────────────────────────────────────────────────────────────────────────
16
+ // Length budgets — meta description / title size envelopes
17
+ // ────────────────────────────────────────────────────────────────────────
18
+ /** Maximum `<meta description>` length we will emit. */
19
+ export const DESCRIPTION_MAX_LENGTH = 180;
20
+ /**
21
+ * Maximum `og:description` / `twitter:description` length we will
22
+ * emit. Facebook truncates at ~300 characters in the preview card;
23
+ * Twitter at ~200. We aim for the longer cap so LinkedIn / Slack
24
+ * (which use the full OG payload) get the full BLUF context, then
25
+ * let Twitter clip naturally. Below this length the extended
26
+ * description is emitted verbatim; above it we sentence-boundary
27
+ * truncate.
28
+ */
29
+ export const EXTENDED_DESCRIPTION_MAX_LENGTH = 300;
30
+ /** Target minimum extended-description length before we even emit it. */
31
+ export const EXTENDED_DESCRIPTION_MIN_LENGTH = 200;
32
+ /** Target minimum `<meta description>` length before we append context. */
33
+ export const DESCRIPTION_MIN_LENGTH = 140;
34
+ /**
35
+ * Length below which a raw description is considered too short to stand
36
+ * on its own and gets enriched with date/context. Independent from
37
+ * {@link DESCRIPTION_MIN_LENGTH} (which controls sentence-boundary
38
+ * truncation behaviour). Set lower than DESCRIPTION_MIN_LENGTH so a
39
+ * clean 100-140 char prose lede is preserved verbatim instead of being
40
+ * padded with date/context boilerplate.
41
+ */
42
+ export const ENRICHMENT_TRIGGER_LENGTH = 100;
43
+ /** Maximum `<title>` length — anything longer is truncated with an ellipsis. */
44
+ export const TITLE_MAX_LENGTH = 140;
45
+ /**
46
+ * Soft target for headline-style titles produced as a fallback from
47
+ * BLUF/lede prose. When the candidate exceeds `TITLE_MAX_LENGTH`, the
48
+ * truncator first looks for a natural clause boundary
49
+ * (`.`, `:`, `—`, `;`) inside the `[HEADLINE_SOFT_MIN, TITLE_MAX_LENGTH]`
50
+ * window and breaks there instead of mid-clause-with-ellipsis. This
51
+ * turns a 137-character truncated prose paragraph into a complete
52
+ * journalistic clause, which scans much better in news cards and SERP
53
+ * snippets without sacrificing the keyword-rich opening.
54
+ */
55
+ export const HEADLINE_SOFT_MIN = 60;
56
+ /**
57
+ * Lower floor for clause-boundary acceptance when the soft-min window
58
+ * returns nothing. Used by {@link truncateTitle} as a second-tier
59
+ * fallback: when a long prose paragraph has its only natural clause
60
+ * boundaries (`: `, ` — `) clustered in the opening 30-60 characters
61
+ * (typical of Reader-Briefing-style ledes like `Immediate priority:
62
+ * DMA enforcement — …`), accept the strongest such boundary rather
63
+ * than fall through to template-fallback composition. This keeps
64
+ * scan-friendly editorial fragments intact while still rejecting
65
+ * fragments shorter than a typical news-card title.
66
+ */
67
+ export const HEADLINE_HARD_MIN = 30;
68
+ /**
69
+ * Punctuation marks that signal a natural clause boundary inside a
70
+ * BLUF / lede paragraph. Listed in preferred-break order: a colon or
71
+ * em-dash that introduces a list of consequences is the best break,
72
+ * full stops are next, and semicolons last. Single ASCII space is
73
+ * always a fallback boundary handled separately.
74
+ */
75
+ export const HEADLINE_CLAUSE_BOUNDARIES = [': ', ' — ', ' – ', '. ', '; ', ', '];
76
+ // ────────────────────────────────────────────────────────────────────────
77
+ // Banner / metadata-row vocabularies
78
+ // ────────────────────────────────────────────────────────────────────────
79
+ /**
80
+ * Emoji-banner prefixes that Stage-B agents use to decorate metadata rows
81
+ * (e.g. `📋 Analysis Owner:`). Any line starting with one of these is
82
+ * metadata, never prose.
83
+ */
84
+ export const EMOJI_BANNER_CHARS = [
85
+ '📋',
86
+ '📅',
87
+ '🔍',
88
+ '🏛',
89
+ '📰',
90
+ '📊',
91
+ '🏷',
92
+ '📈',
93
+ '📉',
94
+ '⚠',
95
+ '🔔',
96
+ '🎯',
97
+ '🗳',
98
+ '🏢',
99
+ '📄',
100
+ ];
101
+ /**
102
+ * Label prefixes that a prose description must never start with. Every
103
+ * entry matches case-insensitively at the start of a trimmed line, followed
104
+ * by optional space and a colon.
105
+ */
106
+ export const METADATA_LINE_PREFIXES = [
107
+ 'Admiralty Grade',
108
+ 'Analysis Date',
109
+ 'Analysis Owner',
110
+ 'Article Type',
111
+ 'Article Window',
112
+ 'Assessment Date',
113
+ 'Briefing',
114
+ 'Briefing Date',
115
+ 'Classification',
116
+ 'Classification Date',
117
+ 'Confidence',
118
+ 'Confidence in Evidence',
119
+ 'Data Sources',
120
+ 'Date',
121
+ 'Document Type',
122
+ 'Filing Date',
123
+ 'Generated',
124
+ 'Horizon',
125
+ 'IMF Status',
126
+ 'Last Updated',
127
+ 'Parliamentary Status',
128
+ 'Parliamentary Term',
129
+ 'Period',
130
+ 'Prepared',
131
+ 'Purpose',
132
+ 'Region',
133
+ 'Reporting',
134
+ 'Reporting Period',
135
+ 'Reporting Window',
136
+ 'Run',
137
+ 'Run ID',
138
+ 'Series',
139
+ 'Series Run',
140
+ 'Source',
141
+ 'Sources',
142
+ 'SPDX-FileCopyrightText',
143
+ 'SPDX-License-Identifier',
144
+ 'Topic',
145
+ 'Type',
146
+ // Bare `WEP:` (Words of Estimative Probability) lines appear in
147
+ // `intelligence/synthesis-summary.md` between a KJ-N heading and its
148
+ // prose body (e.g. `**WEP: ALMOST CERTAINLY (>95%)** | Admiralty: A1`).
149
+ // The line is grade/confidence metadata, not editorial prose — without
150
+ // this prefix it leaked into `<meta description>` as an all-caps shout
151
+ // (run #26223932441, propositions 2026-05-21).
152
+ 'WEP',
153
+ 'WEP Band',
154
+ 'WEP Grade',
155
+ 'Window',
156
+ ];
157
+ // ────────────────────────────────────────────────────────────────────────
158
+ // Trailing-cleanup vocabularies (used by truncation helpers)
159
+ // ────────────────────────────────────────────────────────────────────────
160
+ /** Connector / determiner words that read as broken copy when they are
161
+ * the final token before a truncation ellipsis. */
162
+ export const TRAILING_STOP_WORDS = new Set([
163
+ 'the',
164
+ 'a',
165
+ 'an',
166
+ 'of',
167
+ 'to',
168
+ 'for',
169
+ 'in',
170
+ 'on',
171
+ 'at',
172
+ 'by',
173
+ 'and',
174
+ 'or',
175
+ 'with',
176
+ 'from',
177
+ ]);
178
+ /** Trailing characters we always strip before appending our own ellipsis,
179
+ * so we never emit double-ellipsis or stray punctuation. */
180
+ export const TRAILING_PUNCT = /[.,;:—\-…\s]/u;
181
+ /**
182
+ * Abbreviation tokens (lowercase, including the trailing period) that
183
+ * should NOT count as sentence terminators when `extractFirstSentence`
184
+ * scans for a `.` boundary. Single-letter all-caps initials
185
+ * (`U.S.`, `E.U.`) are handled by the all-caps-initial check.
186
+ */
187
+ export const ABBREVIATION_PREFIXES = [
188
+ 'mr.',
189
+ 'mrs.',
190
+ 'ms.',
191
+ 'dr.',
192
+ 'st.',
193
+ 'no.',
194
+ 'vs.',
195
+ 'e.g.',
196
+ 'i.e.',
197
+ 'etc.',
198
+ 'cf.',
199
+ 'al.',
200
+ // EP fiscal-year and quarter shorthand: Q1., Q2., Q3., Q4., H1., H2., FY.
201
+ 'q1.',
202
+ 'q2.',
203
+ 'q3.',
204
+ 'q4.',
205
+ 'h1.',
206
+ 'h2.',
207
+ 'fy.',
208
+ ];
209
+ //# sourceMappingURL=text-utils-constants.js.map
@@ -1,97 +1,21 @@
1
1
  /**
2
2
  * @module Aggregator/Metadata/TextUtils
3
- * @description Pure text / Markdown utility helpers extracted from
4
- * `article-metadata.ts` as a leaf module in the `metadata/` bounded
5
- * context. Every helper here is concerned with **how to massage a
6
- * string** into a meta-tag-safe shape strip Markdown decorations,
7
- * recognise banner / metadata rows that must never reach the
8
- * description, clamp text to byte budgets without producing broken
9
- * copy, and identify the first complete sentence in a prose paragraph.
3
+ * @description Pure text / Markdown classification + label-stripping
4
+ * helpers used by the metadata resolver chain. Constants live in
5
+ * `text-utils-constants.ts`; byte-budget truncators and sentence-
6
+ * extraction live in `text-truncate.ts`. This file re-exports the
7
+ * full public surface so existing call-sites keep working.
10
8
  *
11
- * Bounded-context rules for this file:
12
- * - **No upward imports** — pure helpers, no dependencies on other
13
- * `src/aggregator/` modules, no I/O, no globals.
14
- * - **Deterministic** — same input always produces same output; safe to
15
- * property-test.
9
+ * Bounded-context rules:
10
+ * - **No upward imports** — pure helpers, no I/O, no globals.
11
+ * - **Deterministic** same input always produces same output.
16
12
  * - **Locale-agnostic** — every helper works on raw Markdown / prose
17
13
  * in any of the 14 publishing languages. Banner-row detection is
18
14
  * driven by structural shape (double-bold + pipe-separator), not by
19
15
  * a hard-coded English vocabulary.
20
- *
21
- * The companion file `article-metadata.ts` re-exports the public surface
22
- * for back-compat. New code should import directly from this module.
23
- */
24
- /** Maximum `<meta description>` length we will emit. */
25
- export declare const DESCRIPTION_MAX_LENGTH = 180;
26
- /**
27
- * Maximum `og:description` / `twitter:description` length we will
28
- * emit. Facebook truncates at ~300 characters in the preview card;
29
- * Twitter at ~200. We aim for the longer cap so LinkedIn / Slack
30
- * (which use the full OG payload) get the full BLUF context, then
31
- * let Twitter clip naturally. Below this length the extended
32
- * description is emitted verbatim; above it we sentence-boundary
33
- * truncate the same way as {@link truncateDescription}.
34
- */
35
- export declare const EXTENDED_DESCRIPTION_MAX_LENGTH = 300;
36
- /** Target minimum extended-description length before we even emit it. */
37
- export declare const EXTENDED_DESCRIPTION_MIN_LENGTH = 200;
38
- /** Target minimum `<meta description>` length before we append context. */
39
- export declare const DESCRIPTION_MIN_LENGTH = 140;
40
- /**
41
- * Length below which a raw description is considered too short to stand
42
- * on its own and gets enriched with date/context. Independent from
43
- * {@link DESCRIPTION_MIN_LENGTH} (which controls sentence-boundary
44
- * truncation behaviour). Set lower than DESCRIPTION_MIN_LENGTH so a
45
- * clean 100-140 char prose lede is preserved verbatim instead of being
46
- * padded with date/context boilerplate.
47
- */
48
- export declare const ENRICHMENT_TRIGGER_LENGTH = 100;
49
- /** Maximum `<title>` length — anything longer is truncated with an ellipsis. */
50
- export declare const TITLE_MAX_LENGTH = 140;
51
- /**
52
- * Soft target for headline-style titles produced as a fallback from
53
- * BLUF/lede prose. When the candidate exceeds `TITLE_MAX_LENGTH`, the
54
- * truncator first looks for a natural clause boundary
55
- * (`.`, `:`, `—`, `;`) inside the `[HEADLINE_SOFT_MIN, TITLE_MAX_LENGTH]`
56
- * window and breaks there instead of mid-clause-with-ellipsis. This
57
- * turns a 137-character truncated prose paragraph into a complete
58
- * journalistic clause, which scans much better in news cards and SERP
59
- * snippets without sacrificing the keyword-rich opening.
60
- */
61
- export declare const HEADLINE_SOFT_MIN = 60;
62
- /**
63
- * Punctuation marks that signal a natural clause boundary inside a
64
- * BLUF / lede paragraph. Listed in preferred-break order: a colon or
65
- * em-dash that introduces a list of consequences is the best break,
66
- * full stops are next, and semicolons last. Single ASCII space is
67
- * always a fallback boundary handled separately.
68
16
  */
69
- export declare const HEADLINE_CLAUSE_BOUNDARIES: readonly string[];
70
- /**
71
- * Emoji-banner prefixes that Stage-B agents use to decorate metadata rows
72
- * (e.g. `📋 Analysis Owner:`). Any line starting with one of these is
73
- * metadata, never prose.
74
- */
75
- export declare const EMOJI_BANNER_CHARS: string[];
76
- /**
77
- * Label prefixes that a prose description must never start with. Every
78
- * entry matches case-insensitively at the start of a trimmed line, followed
79
- * by optional space and a colon.
80
- */
81
- export declare const METADATA_LINE_PREFIXES: readonly string[];
82
- /** Connector / determiner words that read as broken copy when they are
83
- * the final token before a truncation ellipsis. */
84
- export declare const TRAILING_STOP_WORDS: Set<string>;
85
- /** Trailing characters we always strip before appending our own ellipsis,
86
- * so we never emit double-ellipsis or stray punctuation. */
87
- export declare const TRAILING_PUNCT: RegExp;
88
- /**
89
- * Abbreviation tokens (lowercase, including the trailing period) that
90
- * should NOT count as sentence terminators when {@link extractFirstSentence}
91
- * scans for a `.` boundary. Single-letter all-caps initials
92
- * (`U.S.`, `E.U.`) are handled by the all-caps-initial check below.
93
- */
94
- export declare const ABBREVIATION_PREFIXES: readonly string[];
17
+ export { ABBREVIATION_PREFIXES, DESCRIPTION_MAX_LENGTH, DESCRIPTION_MIN_LENGTH, EMOJI_BANNER_CHARS, ENRICHMENT_TRIGGER_LENGTH, EXTENDED_DESCRIPTION_MAX_LENGTH, EXTENDED_DESCRIPTION_MIN_LENGTH, HEADLINE_CLAUSE_BOUNDARIES, HEADLINE_SOFT_MIN, METADATA_LINE_PREFIXES, TITLE_MAX_LENGTH, TRAILING_PUNCT, TRAILING_STOP_WORDS, } from './text-utils-constants.js';
18
+ export { extractFirstSentence, stripTrailingStopWordsAndPunctuation, truncateDescription, truncateExtendedDescription, truncateTitle, } from './text-truncate.js';
95
19
  /**
96
20
  * Return `true` when a line cannot serve as a prose description. Rejects
97
21
  * Markdown structural lines (headings, blockquotes, tables, HTML),
@@ -118,6 +42,28 @@ export declare function shouldSkipDescriptionLine(line: string): boolean;
118
42
  * @returns Line with the all-caps opener removed
119
43
  */
120
44
  export declare function stripLeadingProseLabel(line: string): string;
45
+ /**
46
+ * Strip a leading `**Label:**` / `**Label:**` prefix from a Markdown
47
+ * BLUF line, in any of the 14 publishing languages. Translated
48
+ * executive briefs open the `## FOR IMMEDIATE ACTION` section with
49
+ * patterns such as `**Issue:** …`, `**Fråga:** …`, `**Asunto:** …`,
50
+ * `**主題:** …`, `**الموضوع:** …`, `**Thema:** …`, `**Sujet :** …` —
51
+ * without this stripper the localized label leaked into
52
+ * `<meta description>` for every non-English locale (the English
53
+ * `**Issue:**` line is already filtered by `METADATA_LINE_PREFIXES`).
54
+ *
55
+ * The matcher is *structural*, not vocabulary-driven: it accepts up to
56
+ * 5 word/glyph tokens (letters, marks, digits, spaces, hyphens),
57
+ * followed by either an ASCII colon `:` or full-width colon `:`,
58
+ * followed by `**`, followed by whitespace. Returns the line verbatim
59
+ * when no qualifying opener is present so it is safe to apply
60
+ * unconditionally.
61
+ *
62
+ * @param raw - Raw Markdown line (still carrying `**…**` decorations)
63
+ * @returns Line with the leading `**Label:**` prefix removed, or the
64
+ * original input when no such prefix exists
65
+ */
66
+ export declare function stripLeadingBoldLabel(raw: string): string;
121
67
  /**
122
68
  * Strip inline Markdown decorations so we can use the remaining text as
123
69
  * plain-text meta-tag content. Removes link syntax, emphasis, inline code
@@ -128,61 +74,4 @@ export declare function stripLeadingProseLabel(line: string): string;
128
74
  * @returns Plain-text variant
129
75
  */
130
76
  export declare function stripInlineMarkdown(raw: string): string;
131
- /**
132
- * Clamp a string to `DESCRIPTION_MAX_LENGTH` characters, appending
133
- * an ellipsis when truncation actually happens. Does not break words if
134
- * avoidable — a trailing partial word is trimmed back to the previous
135
- * space first.
136
- *
137
- * @param text - Raw description text
138
- * @returns Truncated description with trailing ellipsis when clipped
139
- */
140
- export declare function truncateDescription(text: string): string;
141
- /**
142
- * Clamp an extended description to {@link EXTENDED_DESCRIPTION_MAX_LENGTH}
143
- * characters using the same sentence-boundary-preserving logic as
144
- * {@link truncateDescription}. Returns `''` when the input is empty
145
- * or shorter than the meta-description maximum (no point in emitting
146
- * an "extended" description that's actually shorter than the regular
147
- * one).
148
- *
149
- * @param text - Raw extended-description text (e.g. full BLUF paragraph)
150
- * @returns Truncated extended description, or `''` when not worth emitting
151
- */
152
- export declare function truncateExtendedDescription(text: string): string;
153
- /**
154
- * Clamp a title to `TITLE_MAX_LENGTH` characters in the same
155
- * word-boundary-preserving fashion as {@link truncateDescription}.
156
- *
157
- * @param text - Raw title text
158
- * @returns Truncated title with trailing ellipsis when clipped
159
- */
160
- export declare function truncateTitle(text: string): string;
161
- /**
162
- * Return the first complete sentence from a prose paragraph, suitable
163
- * for use as a fallback editorial title when the artefact H1 is
164
- * categorical (e.g. `# EU Parliament Committee Reports`) and the
165
- * resolver must derive `<title>` from the BLUF / lede summary instead.
166
- *
167
- * A "sentence" is the prefix up to the first sentence-terminator
168
- * (`. `, `! `, `? `, `; `) inside the `[HEADLINE_SOFT_MIN,
169
- * TITLE_MAX_LENGTH]` window. Common abbreviations (`Q1.`, `Q2.`,
170
- * `H1.`, `H2.`, `Mr.`, `Mrs.`, `e.g.`, `i.e.`, `vs.`) are skipped
171
- * so they don't terminate the sentence prematurely. When no
172
- * acceptable terminator exists in the window, returns the entire
173
- * input unchanged so {@link truncateTitle} can handle clause-boundary
174
- * truncation downstream.
175
- *
176
- * This produces journalistically clean titles even for the
177
- * propositions / committee-reports cases where the BLUF paragraph
178
- * opens with a single long sentence that exceeds 140 chars —
179
- * `truncateTitle` then breaks on a clause boundary, and the result is
180
- * still grammatical because the input was a sentence prefix rather
181
- * than an arbitrary paragraph slice.
182
- *
183
- * @param paragraph - Prose paragraph (post-{@link stripInlineMarkdown})
184
- * @returns First sentence, or the original paragraph when none can be
185
- * identified within the soft-min window
186
- */
187
- export declare function extractFirstSentence(paragraph: string): string;
188
77
  //# sourceMappingURL=text-utils.d.ts.map