webforai 2.1.1 → 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.
- package/README.md +63 -1
- package/dist/adapters/index.js +58 -0
- package/dist/adapters/registry.js +149 -0
- package/dist/adapters/sites/declarative.js +178 -0
- package/dist/adapters/sites/hackernews.js +94 -0
- package/dist/adapters/sites/youtube.js +165 -0
- package/dist/adapters/types.js +0 -0
- package/dist/bin.js +3197 -402
- package/dist/cjs/adapters/index.js +86 -0
- package/dist/cjs/adapters/registry.js +178 -0
- package/dist/cjs/adapters/sites/declarative.js +202 -0
- package/dist/cjs/adapters/sites/hackernews.js +117 -0
- package/dist/cjs/adapters/sites/youtube.js +191 -0
- package/dist/cjs/adapters/types.js +16 -0
- package/dist/cjs/constants.js +2 -2
- package/dist/cjs/extractors/index.js +5 -0
- package/dist/cjs/extractors/lib/constants.js +186 -0
- package/dist/cjs/extractors/lib/sanitize.js +425 -0
- package/dist/cjs/extractors/lib/score.js +264 -0
- package/dist/cjs/extractors/lib/terminators.js +131 -0
- package/dist/cjs/extractors/lib/ui-chrome.js +119 -0
- package/dist/cjs/extractors/pipeExtractors.js +12 -9
- package/dist/cjs/extractors/presets/auto.js +44 -0
- package/dist/cjs/extractors/presets/minimal-filter.js +27 -48
- package/dist/cjs/extractors/presets/takumi.js +84 -122
- package/dist/cjs/html-to-markdown.js +44 -7
- package/dist/cjs/html-to-mdast.js +9 -1
- package/dist/cjs/index.js +31 -2
- package/dist/cjs/mdast-handlers/custom-a-handler.js +25 -9
- package/dist/cjs/mdast-handlers/custom-img-handler.js +23 -1
- package/dist/cjs/mdast-handlers/custom-table-handler.js +16 -0
- package/dist/cjs/mdast-handlers/definition-list-handler.js +99 -0
- package/dist/cjs/mdast-handlers/math-handler.js +12 -3
- package/dist/cjs/mdast-handlers/sup-sub-handler.js +39 -0
- package/dist/cjs/metadata/index.js +223 -0
- package/dist/cjs/normalize/index.js +168 -0
- package/dist/cjs/platform/client.js +147 -0
- package/dist/cjs/platform/error.js +36 -0
- package/dist/cjs/platform/fetch.js +37 -0
- package/dist/cjs/platform/index.js +40 -0
- package/dist/cjs/platform/types.js +34 -0
- package/dist/cjs/utils/hast-fast.js +284 -0
- package/dist/constants.js +2 -2
- package/dist/extractors/index.js +3 -0
- package/dist/extractors/lib/constants.js +150 -0
- package/dist/extractors/lib/sanitize.js +415 -0
- package/dist/extractors/lib/score.js +242 -0
- package/dist/extractors/lib/terminators.js +107 -0
- package/dist/extractors/lib/ui-chrome.js +96 -0
- package/dist/extractors/pipeExtractors.js +12 -9
- package/dist/extractors/presets/auto.js +20 -0
- package/dist/extractors/presets/minimal-filter.js +35 -47
- package/dist/extractors/presets/takumi.js +91 -122
- package/dist/html-to-markdown.js +42 -6
- package/dist/html-to-mdast.js +9 -1
- package/dist/index.js +31 -2
- package/dist/mdast-handlers/custom-a-handler.js +25 -9
- package/dist/mdast-handlers/custom-img-handler.js +23 -1
- package/dist/mdast-handlers/custom-table-handler.js +16 -0
- package/dist/mdast-handlers/definition-list-handler.js +76 -0
- package/dist/mdast-handlers/math-handler.js +12 -3
- package/dist/mdast-handlers/sup-sub-handler.js +16 -0
- package/dist/metadata/index.js +198 -0
- package/dist/normalize/index.js +149 -0
- package/dist/platform/client.js +125 -0
- package/dist/platform/error.js +13 -0
- package/dist/platform/fetch.js +14 -0
- package/dist/platform/index.js +19 -0
- package/dist/platform/types.js +9 -0
- package/dist/types/adapters/index.d.ts +24 -0
- package/dist/types/adapters/index.js.map +1 -0
- package/dist/types/adapters/registry.d.ts +35 -0
- package/dist/types/adapters/registry.js.map +1 -0
- package/dist/types/adapters/sites/declarative.d.ts +13 -0
- package/dist/types/adapters/sites/declarative.js.map +1 -0
- package/dist/types/adapters/sites/hackernews.d.ts +13 -0
- package/dist/types/adapters/sites/hackernews.js.map +1 -0
- package/dist/types/adapters/sites/youtube.d.ts +31 -0
- package/dist/types/adapters/sites/youtube.js.map +1 -0
- package/dist/types/adapters/types.d.ts +99 -0
- package/dist/types/adapters/types.js.map +1 -0
- package/dist/types/cli/bin.js.map +1 -1
- package/dist/types/cli/commands/skill/content.d.ts +9 -0
- package/dist/types/cli/commands/skill/content.js.map +1 -0
- package/dist/types/cli/commands/skill/index.d.ts +19 -0
- package/dist/types/cli/commands/skill/index.js.map +1 -0
- package/dist/types/cli/commands/webforai/interactive.d.ts +7 -0
- package/dist/types/cli/commands/webforai/interactive.js.map +1 -0
- package/dist/types/cli/commands/webforai/loadHtml.js.map +1 -1
- package/dist/types/cli/commands/webforai/options.d.ts +55 -0
- package/dist/types/cli/commands/webforai/options.js.map +1 -0
- package/dist/types/cli/commands/webforai/run.d.ts +10 -0
- package/dist/types/cli/commands/webforai/run.js.map +1 -0
- package/dist/types/cli/constants.d.ts +14 -4
- package/dist/types/cli/constants.js.map +1 -1
- package/dist/types/cli/helpers/selectExtractMode.js.map +1 -1
- package/dist/types/cli/helpers/selectLoader.js.map +1 -1
- package/dist/types/constants.d.ts +7 -1
- package/dist/types/constants.js.map +1 -1
- package/dist/types/extractors/index.d.ts +1 -0
- package/dist/types/extractors/index.js.map +1 -1
- package/dist/types/extractors/lib/constants.d.ts +81 -0
- package/dist/types/extractors/lib/constants.js.map +1 -0
- package/dist/types/extractors/lib/sanitize.d.ts +66 -0
- package/dist/types/extractors/lib/sanitize.js.map +1 -0
- package/dist/types/extractors/lib/score.d.ts +85 -0
- package/dist/types/extractors/lib/score.js.map +1 -0
- package/dist/types/extractors/lib/terminators.d.ts +26 -0
- package/dist/types/extractors/lib/terminators.js.map +1 -0
- package/dist/types/extractors/lib/ui-chrome.d.ts +18 -0
- package/dist/types/extractors/lib/ui-chrome.js.map +1 -0
- package/dist/types/extractors/pipeExtractors.d.ts +5 -0
- package/dist/types/extractors/pipeExtractors.js.map +1 -1
- package/dist/types/extractors/presets/auto.d.ts +30 -0
- package/dist/types/extractors/presets/auto.js.map +1 -0
- package/dist/types/extractors/presets/minimal-filter.d.ts +10 -2
- package/dist/types/extractors/presets/minimal-filter.js.map +1 -1
- package/dist/types/extractors/presets/takumi.d.ts +19 -3
- package/dist/types/extractors/presets/takumi.js.map +1 -1
- package/dist/types/extractors/types.d.ts +8 -0
- package/dist/types/html-to-markdown.d.ts +38 -0
- package/dist/types/html-to-markdown.js.map +1 -1
- package/dist/types/html-to-mdast.d.ts +11 -0
- package/dist/types/html-to-mdast.js.map +1 -1
- package/dist/types/index.d.ts +6 -3
- package/dist/types/index.js.map +1 -1
- package/dist/types/mdast-handlers/custom-a-handler.js.map +1 -1
- package/dist/types/mdast-handlers/custom-img-handler.js.map +1 -1
- package/dist/types/mdast-handlers/custom-table-handler.js.map +1 -1
- package/dist/types/mdast-handlers/definition-list-handler.d.ts +13 -0
- package/dist/types/mdast-handlers/definition-list-handler.js.map +1 -0
- package/dist/types/mdast-handlers/math-handler.js.map +1 -1
- package/dist/types/mdast-handlers/sup-sub-handler.d.ts +10 -0
- package/dist/types/mdast-handlers/sup-sub-handler.js.map +1 -0
- package/dist/types/metadata/index.d.ts +47 -0
- package/dist/types/metadata/index.js.map +1 -0
- package/dist/types/normalize/index.d.ts +53 -0
- package/dist/types/normalize/index.js.map +1 -0
- package/dist/types/platform/client.d.ts +54 -0
- package/dist/types/platform/client.js.map +1 -0
- package/dist/types/platform/error.d.ts +20 -0
- package/dist/types/platform/error.js.map +1 -0
- package/dist/types/platform/fetch.d.ts +34 -0
- package/dist/types/platform/fetch.js.map +1 -0
- package/dist/types/platform/index.d.ts +4 -0
- package/dist/types/platform/index.js.map +1 -0
- package/dist/types/platform/types.d.ts +135 -0
- package/dist/types/platform/types.js.map +1 -0
- package/dist/types/utils/hast-fast.d.ts +101 -0
- package/dist/types/utils/hast-fast.js.map +1 -0
- package/dist/utils/hast-fast.js +246 -0
- package/package.json +10 -3
- package/dist/types/cli/commands/webforai/index.d.ts +0 -6
- 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);
|
package/dist/cjs/constants.js
CHANGED
|
@@ -21,8 +21,8 @@ __export(constants_exports, {
|
|
|
21
21
|
DEFAULT_EXTRACTORS: () => DEFAULT_EXTRACTORS
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(constants_exports);
|
|
24
|
-
var
|
|
25
|
-
const DEFAULT_EXTRACTORS = [
|
|
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,6 +18,8 @@ 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,
|
|
21
23
|
minimalFilter: () => import_minimal_filter.minimalFilter,
|
|
22
24
|
pipeExtractors: () => import_pipeExtractors.pipeExtractors,
|
|
23
25
|
takumiExtractor: () => import_takumi.takumiExtractor
|
|
@@ -26,8 +28,11 @@ module.exports = __toCommonJS(extractors_exports);
|
|
|
26
28
|
var import_pipeExtractors = require("./pipeExtractors");
|
|
27
29
|
var import_takumi = require("./presets/takumi");
|
|
28
30
|
var import_minimal_filter = require("./presets/minimal-filter");
|
|
31
|
+
var import_auto = require("./presets/auto");
|
|
29
32
|
// Annotate the CommonJS export names for ESM import in node:
|
|
30
33
|
0 && (module.exports = {
|
|
34
|
+
autoExtractor,
|
|
35
|
+
createAutoExtractor,
|
|
31
36
|
minimalFilter,
|
|
32
37
|
pipeExtractors,
|
|
33
38
|
takumiExtractor
|
|
@@ -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
|
+
});
|