webforai 2.1.0 → 3.0.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.
Files changed (154) hide show
  1. package/README.md +63 -1
  2. package/dist/adapters/index.js +58 -0
  3. package/dist/adapters/registry.js +149 -0
  4. package/dist/adapters/sites/declarative.js +178 -0
  5. package/dist/adapters/sites/hackernews.js +94 -0
  6. package/dist/adapters/sites/youtube.js +165 -0
  7. package/dist/adapters/types.js +0 -0
  8. package/dist/bin.js +3199 -399
  9. package/dist/cjs/adapters/index.js +86 -0
  10. package/dist/cjs/adapters/registry.js +178 -0
  11. package/dist/cjs/adapters/sites/declarative.js +202 -0
  12. package/dist/cjs/adapters/sites/hackernews.js +117 -0
  13. package/dist/cjs/adapters/sites/youtube.js +191 -0
  14. package/dist/cjs/adapters/types.js +16 -0
  15. package/dist/cjs/constants.js +2 -2
  16. package/dist/cjs/extractors/index.js +8 -0
  17. package/dist/cjs/extractors/lib/constants.js +186 -0
  18. package/dist/cjs/extractors/lib/sanitize.js +425 -0
  19. package/dist/cjs/extractors/lib/score.js +264 -0
  20. package/dist/cjs/extractors/lib/terminators.js +131 -0
  21. package/dist/cjs/extractors/lib/ui-chrome.js +119 -0
  22. package/dist/cjs/extractors/pipeExtractors.js +12 -9
  23. package/dist/cjs/extractors/presets/auto.js +44 -0
  24. package/dist/cjs/extractors/presets/minimal-filter.js +27 -48
  25. package/dist/cjs/extractors/presets/takumi.js +84 -122
  26. package/dist/cjs/html-to-markdown.js +44 -7
  27. package/dist/cjs/html-to-mdast.js +9 -1
  28. package/dist/cjs/index.js +33 -2
  29. package/dist/cjs/mdast-handlers/custom-a-handler.js +25 -9
  30. package/dist/cjs/mdast-handlers/custom-img-handler.js +23 -1
  31. package/dist/cjs/mdast-handlers/custom-table-handler.js +16 -0
  32. package/dist/cjs/mdast-handlers/definition-list-handler.js +99 -0
  33. package/dist/cjs/mdast-handlers/math-handler.js +12 -3
  34. package/dist/cjs/mdast-handlers/sup-sub-handler.js +39 -0
  35. package/dist/cjs/metadata/index.js +223 -0
  36. package/dist/cjs/normalize/index.js +168 -0
  37. package/dist/cjs/platform/client.js +147 -0
  38. package/dist/cjs/platform/error.js +36 -0
  39. package/dist/cjs/platform/fetch.js +37 -0
  40. package/dist/cjs/platform/index.js +40 -0
  41. package/dist/cjs/platform/types.js +34 -0
  42. package/dist/cjs/utils/hast-fast.js +284 -0
  43. package/dist/constants.js +2 -2
  44. package/dist/extractors/index.js +5 -0
  45. package/dist/extractors/lib/constants.js +150 -0
  46. package/dist/extractors/lib/sanitize.js +415 -0
  47. package/dist/extractors/lib/score.js +242 -0
  48. package/dist/extractors/lib/terminators.js +107 -0
  49. package/dist/extractors/lib/ui-chrome.js +96 -0
  50. package/dist/extractors/pipeExtractors.js +12 -9
  51. package/dist/extractors/presets/auto.js +20 -0
  52. package/dist/extractors/presets/minimal-filter.js +35 -47
  53. package/dist/extractors/presets/takumi.js +91 -122
  54. package/dist/html-to-markdown.js +42 -6
  55. package/dist/html-to-mdast.js +9 -1
  56. package/dist/index.js +34 -3
  57. package/dist/mdast-handlers/custom-a-handler.js +25 -9
  58. package/dist/mdast-handlers/custom-img-handler.js +23 -1
  59. package/dist/mdast-handlers/custom-table-handler.js +16 -0
  60. package/dist/mdast-handlers/definition-list-handler.js +76 -0
  61. package/dist/mdast-handlers/math-handler.js +12 -3
  62. package/dist/mdast-handlers/sup-sub-handler.js +16 -0
  63. package/dist/metadata/index.js +198 -0
  64. package/dist/normalize/index.js +149 -0
  65. package/dist/platform/client.js +125 -0
  66. package/dist/platform/error.js +13 -0
  67. package/dist/platform/fetch.js +14 -0
  68. package/dist/platform/index.js +19 -0
  69. package/dist/platform/types.js +9 -0
  70. package/dist/types/adapters/index.d.ts +24 -0
  71. package/dist/types/adapters/index.js.map +1 -0
  72. package/dist/types/adapters/registry.d.ts +35 -0
  73. package/dist/types/adapters/registry.js.map +1 -0
  74. package/dist/types/adapters/sites/declarative.d.ts +13 -0
  75. package/dist/types/adapters/sites/declarative.js.map +1 -0
  76. package/dist/types/adapters/sites/hackernews.d.ts +13 -0
  77. package/dist/types/adapters/sites/hackernews.js.map +1 -0
  78. package/dist/types/adapters/sites/youtube.d.ts +31 -0
  79. package/dist/types/adapters/sites/youtube.js.map +1 -0
  80. package/dist/types/adapters/types.d.ts +99 -0
  81. package/dist/types/adapters/types.js.map +1 -0
  82. package/dist/types/cli/bin.js.map +1 -1
  83. package/dist/types/cli/commands/skill/content.d.ts +9 -0
  84. package/dist/types/cli/commands/skill/content.js.map +1 -0
  85. package/dist/types/cli/commands/skill/index.d.ts +19 -0
  86. package/dist/types/cli/commands/skill/index.js.map +1 -0
  87. package/dist/types/cli/commands/webforai/interactive.d.ts +7 -0
  88. package/dist/types/cli/commands/webforai/interactive.js.map +1 -0
  89. package/dist/types/cli/commands/webforai/loadHtml.js.map +1 -1
  90. package/dist/types/cli/commands/webforai/options.d.ts +55 -0
  91. package/dist/types/cli/commands/webforai/options.js.map +1 -0
  92. package/dist/types/cli/commands/webforai/run.d.ts +10 -0
  93. package/dist/types/cli/commands/webforai/run.js.map +1 -0
  94. package/dist/types/cli/constants.d.ts +14 -4
  95. package/dist/types/cli/constants.js.map +1 -1
  96. package/dist/types/cli/helpers/selectExtractMode.js.map +1 -1
  97. package/dist/types/cli/helpers/selectLoader.js.map +1 -1
  98. package/dist/types/constants.d.ts +7 -1
  99. package/dist/types/constants.js.map +1 -1
  100. package/dist/types/extractors/index.d.ts +2 -0
  101. package/dist/types/extractors/index.js.map +1 -1
  102. package/dist/types/extractors/lib/constants.d.ts +81 -0
  103. package/dist/types/extractors/lib/constants.js.map +1 -0
  104. package/dist/types/extractors/lib/sanitize.d.ts +66 -0
  105. package/dist/types/extractors/lib/sanitize.js.map +1 -0
  106. package/dist/types/extractors/lib/score.d.ts +85 -0
  107. package/dist/types/extractors/lib/score.js.map +1 -0
  108. package/dist/types/extractors/lib/terminators.d.ts +26 -0
  109. package/dist/types/extractors/lib/terminators.js.map +1 -0
  110. package/dist/types/extractors/lib/ui-chrome.d.ts +18 -0
  111. package/dist/types/extractors/lib/ui-chrome.js.map +1 -0
  112. package/dist/types/extractors/pipeExtractors.d.ts +5 -0
  113. package/dist/types/extractors/pipeExtractors.js.map +1 -1
  114. package/dist/types/extractors/presets/auto.d.ts +30 -0
  115. package/dist/types/extractors/presets/auto.js.map +1 -0
  116. package/dist/types/extractors/presets/minimal-filter.d.ts +10 -2
  117. package/dist/types/extractors/presets/minimal-filter.js.map +1 -1
  118. package/dist/types/extractors/presets/takumi.d.ts +19 -3
  119. package/dist/types/extractors/presets/takumi.js.map +1 -1
  120. package/dist/types/extractors/types.d.ts +8 -0
  121. package/dist/types/html-to-markdown.d.ts +38 -0
  122. package/dist/types/html-to-markdown.js.map +1 -1
  123. package/dist/types/html-to-mdast.d.ts +11 -0
  124. package/dist/types/html-to-mdast.js.map +1 -1
  125. package/dist/types/index.d.ts +6 -3
  126. package/dist/types/index.js.map +1 -1
  127. package/dist/types/mdast-handlers/custom-a-handler.js.map +1 -1
  128. package/dist/types/mdast-handlers/custom-img-handler.js.map +1 -1
  129. package/dist/types/mdast-handlers/custom-table-handler.js.map +1 -1
  130. package/dist/types/mdast-handlers/definition-list-handler.d.ts +13 -0
  131. package/dist/types/mdast-handlers/definition-list-handler.js.map +1 -0
  132. package/dist/types/mdast-handlers/math-handler.js.map +1 -1
  133. package/dist/types/mdast-handlers/sup-sub-handler.d.ts +10 -0
  134. package/dist/types/mdast-handlers/sup-sub-handler.js.map +1 -0
  135. package/dist/types/metadata/index.d.ts +47 -0
  136. package/dist/types/metadata/index.js.map +1 -0
  137. package/dist/types/normalize/index.d.ts +53 -0
  138. package/dist/types/normalize/index.js.map +1 -0
  139. package/dist/types/platform/client.d.ts +54 -0
  140. package/dist/types/platform/client.js.map +1 -0
  141. package/dist/types/platform/error.d.ts +20 -0
  142. package/dist/types/platform/error.js.map +1 -0
  143. package/dist/types/platform/fetch.d.ts +34 -0
  144. package/dist/types/platform/fetch.js.map +1 -0
  145. package/dist/types/platform/index.d.ts +4 -0
  146. package/dist/types/platform/index.js.map +1 -0
  147. package/dist/types/platform/types.d.ts +135 -0
  148. package/dist/types/platform/types.js.map +1 -0
  149. package/dist/types/utils/hast-fast.d.ts +101 -0
  150. package/dist/types/utils/hast-fast.js.map +1 -0
  151. package/dist/utils/hast-fast.js +246 -0
  152. package/package.json +10 -3
  153. package/dist/types/cli/commands/webforai/index.d.ts +0 -6
  154. package/dist/types/cli/commands/webforai/index.js.map +0 -1
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var youtube_exports = {};
20
+ __export(youtube_exports, {
21
+ extractAssignedJson: () => extractAssignedJson,
22
+ isYoutubeElement: () => isYoutubeElement,
23
+ youtubeAdapter: () => youtubeAdapter,
24
+ youtubeCaptionTracks: () => youtubeCaptionTracks
25
+ });
26
+ module.exports = __toCommonJS(youtube_exports);
27
+ var import_hast_fast = require("../../utils/hast-fast");
28
+ const findObjectEnd = (source, start) => {
29
+ let depth = 0;
30
+ let inString = false;
31
+ let escaped = false;
32
+ for (let index = start; index < source.length; index++) {
33
+ const character = source[index];
34
+ if (escaped) {
35
+ escaped = false;
36
+ } else if (character === "\\") {
37
+ escaped = true;
38
+ } else if (character === '"') {
39
+ inString = !inString;
40
+ } else if (!inString) {
41
+ if (character === "{") {
42
+ depth += 1;
43
+ } else if (character === "}" && --depth === 0) {
44
+ return index + 1;
45
+ }
46
+ }
47
+ }
48
+ return -1;
49
+ };
50
+ const extractAssignedJson = (source, name) => {
51
+ const markerIndex = source.indexOf(`${name} =`);
52
+ if (markerIndex === -1) {
53
+ return void 0;
54
+ }
55
+ const start = source.indexOf("{", markerIndex);
56
+ if (start === -1) {
57
+ return void 0;
58
+ }
59
+ const end = findObjectEnd(source, start);
60
+ if (end === -1) {
61
+ return void 0;
62
+ }
63
+ try {
64
+ return JSON.parse(source.slice(start, end));
65
+ } catch {
66
+ return void 0;
67
+ }
68
+ };
69
+ const scriptText = (root) => (0, import_hast_fast.collectElements)(root, (element2) => element2.tagName === "script").map(
70
+ (script) => script.children.map((child) => child.type === "text" ? child.value : "").join("")
71
+ );
72
+ const findPlayerResponse = (root) => {
73
+ for (const source of scriptText(root)) {
74
+ if (!source.includes("ytInitialPlayerResponse")) {
75
+ continue;
76
+ }
77
+ const parsed = extractAssignedJson(source, "ytInitialPlayerResponse");
78
+ if (parsed && typeof parsed === "object") {
79
+ return parsed;
80
+ }
81
+ }
82
+ return void 0;
83
+ };
84
+ const youtubeCaptionTracks = (root) => {
85
+ const player = findPlayerResponse(root);
86
+ const renderer = player?.captions?.playerCaptionsTracklistRenderer;
87
+ const tracks = renderer?.captionTracks;
88
+ if (!Array.isArray(tracks)) {
89
+ return [];
90
+ }
91
+ return tracks.flatMap((track) => {
92
+ const url = typeof track.baseUrl === "string" ? track.baseUrl : void 0;
93
+ const languageCode = typeof track.languageCode === "string" ? track.languageCode : void 0;
94
+ if (!(url && languageCode)) {
95
+ return [];
96
+ }
97
+ const name = track.name?.simpleText;
98
+ return [
99
+ {
100
+ url,
101
+ languageCode,
102
+ name: typeof name === "string" ? name : void 0,
103
+ isAutomatic: track.kind === "asr"
104
+ }
105
+ ];
106
+ });
107
+ };
108
+ const text = (value) => ({ type: "text", value });
109
+ const element = (tagName, children) => ({
110
+ type: "element",
111
+ tagName,
112
+ properties: {},
113
+ children
114
+ });
115
+ const heading = (depth, value) => element(`h${depth}`, [text(value)]);
116
+ const paragraph = (value) => element("p", [text(value)]);
117
+ const descriptionNodes = (description) => description.split(/\n{2,}/).map((block) => block.trim()).filter((block) => block.length > 0).map(
118
+ (block) => element(
119
+ "p",
120
+ block.split("\n").flatMap((line, index) => index === 0 ? [text(line)] : [element("br", []), text(line)])
121
+ )
122
+ );
123
+ const formatDuration = (seconds) => {
124
+ const hours = Math.floor(seconds / 3600);
125
+ const minutes = Math.floor(seconds % 3600 / 60);
126
+ const remainder = seconds % 60;
127
+ const pad = (value) => String(value).padStart(2, "0");
128
+ return hours > 0 ? `${hours}:${pad(minutes)}:${pad(remainder)}` : `${minutes}:${pad(remainder)}`;
129
+ };
130
+ const metadataList = (details) => {
131
+ const items = [];
132
+ if (details.author) {
133
+ items.push(element("li", [text(`Channel: ${details.author}`)]));
134
+ }
135
+ const seconds = Number(details.lengthSeconds);
136
+ if (Number.isFinite(seconds) && seconds > 0) {
137
+ items.push(element("li", [text(`Duration: ${formatDuration(seconds)}`)]));
138
+ }
139
+ const views = Number(details.viewCount);
140
+ if (Number.isFinite(views) && views > 0) {
141
+ items.push(element("li", [text(`Views: ${views.toLocaleString("en-US")}`)]));
142
+ }
143
+ return items.length > 0 ? element("ul", items) : void 0;
144
+ };
145
+ const youtubeAdapter = {
146
+ id: "youtube",
147
+ matches: ({ url }) => {
148
+ if (!url) {
149
+ return false;
150
+ }
151
+ try {
152
+ return /(^|\.)(youtube\.com|youtu\.be|youtube-nocookie\.com)$/.test(new URL(url).hostname);
153
+ } catch {
154
+ return false;
155
+ }
156
+ },
157
+ // Scanning every script body for the JSON blob would cost a full traversal on every page, so
158
+ // the fallback keys off markers the signature already collected.
159
+ matchesFingerprint: ({ signature }) => Boolean(signature?.ids.has("movie_player") || signature?.classes.has("ytd-app")),
160
+ extract: ({ hast }) => {
161
+ const player = findPlayerResponse(hast);
162
+ const details = player?.videoDetails;
163
+ if (!details?.title) {
164
+ return void 0;
165
+ }
166
+ const children = [heading(1, details.title)];
167
+ const metadata = metadataList(details);
168
+ if (metadata) {
169
+ children.push(metadata);
170
+ }
171
+ const description = details.shortDescription?.trim();
172
+ if (description) {
173
+ children.push(heading(2, "Description"));
174
+ children.push(...descriptionNodes(description));
175
+ }
176
+ const tracks = youtubeCaptionTracks(hast);
177
+ if (tracks.length > 0) {
178
+ const languages = [...new Set(tracks.map((track) => track.languageCode))].sort();
179
+ children.push(paragraph(`Captions available: ${languages.join(", ")}`));
180
+ }
181
+ return { type: "root", children };
182
+ }
183
+ };
184
+ const isYoutubeElement = import_hast_fast.isElement;
185
+ // Annotate the CommonJS export names for ESM import in node:
186
+ 0 && (module.exports = {
187
+ extractAssignedJson,
188
+ isYoutubeElement,
189
+ youtubeAdapter,
190
+ youtubeCaptionTracks
191
+ });
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+ var types_exports = {};
16
+ module.exports = __toCommonJS(types_exports);
@@ -21,8 +21,8 @@ __export(constants_exports, {
21
21
  DEFAULT_EXTRACTORS: () => DEFAULT_EXTRACTORS
22
22
  });
23
23
  module.exports = __toCommonJS(constants_exports);
24
- var import_takumi = require("./extractors/presets/takumi");
25
- const DEFAULT_EXTRACTORS = [import_takumi.takumiExtractor];
24
+ var import_auto = require("./extractors/presets/auto");
25
+ const DEFAULT_EXTRACTORS = [import_auto.autoExtractor];
26
26
  // Annotate the CommonJS export names for ESM import in node:
27
27
  0 && (module.exports = {
28
28
  DEFAULT_EXTRACTORS
@@ -18,14 +18,22 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var extractors_exports = {};
20
20
  __export(extractors_exports, {
21
+ autoExtractor: () => import_auto.autoExtractor,
22
+ createAutoExtractor: () => import_auto.createAutoExtractor,
23
+ minimalFilter: () => import_minimal_filter.minimalFilter,
21
24
  pipeExtractors: () => import_pipeExtractors.pipeExtractors,
22
25
  takumiExtractor: () => import_takumi.takumiExtractor
23
26
  });
24
27
  module.exports = __toCommonJS(extractors_exports);
25
28
  var import_pipeExtractors = require("./pipeExtractors");
26
29
  var import_takumi = require("./presets/takumi");
30
+ var import_minimal_filter = require("./presets/minimal-filter");
31
+ var import_auto = require("./presets/auto");
27
32
  // Annotate the CommonJS export names for ESM import in node:
28
33
  0 && (module.exports = {
34
+ autoExtractor,
35
+ createAutoExtractor,
36
+ minimalFilter,
29
37
  pipeExtractors,
30
38
  takumiExtractor
31
39
  });
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var constants_exports = {};
20
+ __export(constants_exports, {
21
+ CANDIDATE_TAGS: () => CANDIDATE_TAGS,
22
+ CHROME_TAGS: () => CHROME_TAGS,
23
+ CONTENT_ROLES: () => CONTENT_ROLES,
24
+ CONTEXTUAL_LANDMARK_TAGS: () => CONTEXTUAL_LANDMARK_TAGS,
25
+ DROP_WHEN_EMPTY_TAGS: () => DROP_WHEN_EMPTY_TAGS,
26
+ EMBEDDED_CONTENT_TAGS: () => EMBEDDED_CONTENT_TAGS,
27
+ HIDDEN_CLASS_NAMES: () => HIDDEN_CLASS_NAMES,
28
+ MIN_CONTENT_LENGTH: () => MIN_CONTENT_LENGTH,
29
+ NON_CONTENT_TAGS: () => NON_CONTENT_TAGS,
30
+ REGEXPS: () => REGEXPS,
31
+ RESPONSIVE_DISPLAY_OVERRIDE: () => RESPONSIVE_DISPLAY_OVERRIDE,
32
+ SCOREABLE_TAGS: () => SCOREABLE_TAGS,
33
+ UNLIKELY_ROLES: () => UNLIKELY_ROLES,
34
+ minContentLength: () => minContentLength
35
+ });
36
+ module.exports = __toCommonJS(constants_exports);
37
+ const REGEXPS = {
38
+ /**
39
+ * Containers that almost never hold the article body.
40
+ *
41
+ * Note the words that are deliberately *absent*. `header` and `footer` match the heading
42
+ * anchors and article furniture that documentation generators emit (`<a class="header">`,
43
+ * `class="post-header"`), so matching them here deletes the page's headings. The landmark
44
+ * versions of those elements are handled structurally instead.
45
+ */
46
+ unlikelyCandidates: /-ad-|ai2html|banner|breadcrumb|combx|comment(?!ary)|community|cover-wrap|disqus|gdpr|legends|menu|related|remark|replies|rss|shoutbox|sidebar|site-index|skyscraper|social|sponsor|supplemental|ad-break|agegate|pagination|pager|popup|yom-remote|speechify-ignore|avatar|subscribe|newsletter|paywall|consent|cookie|toolbar|masthead|promo|share|sharing|widget|tooltip|dropdown|modal|overlay|backdrop|carousel|announcement|notification|toast|skip-link|screen-reader|visually-hidden|sr-only/i,
47
+ /** Rescues containers whose class merely happens to contain an unlikely substring. */
48
+ okMaybeItsaCandidate: /and|article|body|column|content|main|shadow|code|post|entry|story|markdown|prose|doc/i,
49
+ /** Very high-confidence boilerplate, not rescued by the clause above. */
50
+ stronglyUnlikely: /^(nav|navbar|breadcrumbs?|cookie-?(banner|consent|notice)|consent-?(banner|manager)|skip-?link|site-?header|site-?footer|global-?(header|footer)|social-?(share|links?)|share-?(bar|buttons?)|related-?(posts?|articles?)|newsletter-?(signup|form)|comment-?(form|list)|toc-?sidebar)$/i,
51
+ /** Class/id fragments that mark real article content. */
52
+ positive: /article|body|content|entry|hentry|h-entry|main|page|pagination|post|text|blog|story|markdown|prose|documentation|doc-?content|readme/i,
53
+ /** Class/id fragments that mark furniture. */
54
+ negative: /-ad-|hidden|^hid$| hid$|^hid |banner|combx|comment|com-|contact|foot|footer|footnote|gdpr|masthead|media|meta|outbrain|promo|related|scroll|share|shoutbox|sidebar|skyscraper|sponsor|shopping|tags|widget|toolbar|nav|menu|cookie|consent|subscribe|newsletter|popup|modal|overlay|breadcrumb|pagination|social/i,
55
+ /** Placeholder imagery that should never reach the output. */
56
+ hidden: /fallback-image/i,
57
+ byline: /byline|author|dateline|writtenby|p-author|c-author|post-meta|entry-meta/i,
58
+ /** Wiki/CMS chrome that generic scoring alone tends to keep. */
59
+ specialUnlikelyCandidates: /frb-|uls-menu|language-link|mw-editsection|noprint|navbox|metadata|catlinks|printfooter/i
60
+ };
61
+ const NON_CONTENT_TAGS = /* @__PURE__ */ new Set([
62
+ "script",
63
+ "style",
64
+ "link",
65
+ "meta",
66
+ "noscript",
67
+ "template",
68
+ "base",
69
+ "param",
70
+ "source",
71
+ "track",
72
+ "title"
73
+ ]);
74
+ const CHROME_TAGS = /* @__PURE__ */ new Set(["nav", "aside", "dialog", "menu"]);
75
+ const CONTEXTUAL_LANDMARK_TAGS = /* @__PURE__ */ new Set(["header", "footer"]);
76
+ const HIDDEN_CLASS_NAMES = /* @__PURE__ */ new Set([
77
+ "hidden",
78
+ "invisible",
79
+ "is-hidden",
80
+ "d-none",
81
+ "display-none",
82
+ "hide",
83
+ "is-invisible"
84
+ ]);
85
+ const RESPONSIVE_DISPLAY_OVERRIDE = /^(sm|md|lg|xl|2xl|print):(block|flex|grid|inline|inline-block|inline-flex|table|contents|list-item)$/;
86
+ const UNLIKELY_ROLES = /* @__PURE__ */ new Set([
87
+ "menu",
88
+ "menubar",
89
+ "menuitem",
90
+ "complementary",
91
+ "navigation",
92
+ "alert",
93
+ "alertdialog",
94
+ "dialog",
95
+ "banner",
96
+ "contentinfo",
97
+ "search",
98
+ "searchbox",
99
+ "toolbar",
100
+ "tablist",
101
+ "tooltip"
102
+ // `presentation` is deliberately absent. It marks an element as decorative *structure* — a
103
+ // layout table, a wrapper — while the content inside it is usually real. Treating it as
104
+ // chrome deletes article text.
105
+ ]);
106
+ const CONTENT_ROLES = /* @__PURE__ */ new Set(["main", "article", "document"]);
107
+ const SCOREABLE_TAGS = /* @__PURE__ */ new Set(["p", "td", "pre", "blockquote", "dd", "li", "figure", "section", "div"]);
108
+ const CANDIDATE_TAGS = /* @__PURE__ */ new Set([
109
+ "div",
110
+ "section",
111
+ "article",
112
+ "main",
113
+ "td",
114
+ "pre",
115
+ "blockquote",
116
+ "form",
117
+ "ul",
118
+ "ol",
119
+ "dl"
120
+ ]);
121
+ const EMBEDDED_CONTENT_TAGS = /* @__PURE__ */ new Set([
122
+ "img",
123
+ "picture",
124
+ "video",
125
+ "audio",
126
+ "iframe",
127
+ "embed",
128
+ "object",
129
+ "svg",
130
+ // Formulae hold no text of their own, so an empty-wrapper rule would otherwise delete them.
131
+ "math",
132
+ "mjx-container",
133
+ "canvas"
134
+ ]);
135
+ const DROP_WHEN_EMPTY_TAGS = /* @__PURE__ */ new Set([
136
+ "p",
137
+ "h1",
138
+ "h2",
139
+ "h3",
140
+ "h4",
141
+ "h5",
142
+ "h6",
143
+ "li",
144
+ "td",
145
+ "th",
146
+ "blockquote",
147
+ "figcaption",
148
+ "dd",
149
+ "dt",
150
+ "a",
151
+ "span",
152
+ "div",
153
+ "section",
154
+ "article"
155
+ ]);
156
+ const MIN_CONTENT_LENGTH = {
157
+ ja: 140,
158
+ zh: 140,
159
+ ko: 160,
160
+ th: 160,
161
+ default: 400
162
+ };
163
+ const minContentLength = (lang) => {
164
+ if (!lang) {
165
+ return MIN_CONTENT_LENGTH.default;
166
+ }
167
+ const primary = lang.toLowerCase().split("-")[0];
168
+ return MIN_CONTENT_LENGTH[primary] ?? MIN_CONTENT_LENGTH.default;
169
+ };
170
+ // Annotate the CommonJS export names for ESM import in node:
171
+ 0 && (module.exports = {
172
+ CANDIDATE_TAGS,
173
+ CHROME_TAGS,
174
+ CONTENT_ROLES,
175
+ CONTEXTUAL_LANDMARK_TAGS,
176
+ DROP_WHEN_EMPTY_TAGS,
177
+ EMBEDDED_CONTENT_TAGS,
178
+ HIDDEN_CLASS_NAMES,
179
+ MIN_CONTENT_LENGTH,
180
+ NON_CONTENT_TAGS,
181
+ REGEXPS,
182
+ RESPONSIVE_DISPLAY_OVERRIDE,
183
+ SCOREABLE_TAGS,
184
+ UNLIKELY_ROLES,
185
+ minContentLength
186
+ });