clearcote 0.2.0 → 0.4.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 CHANGED
@@ -48,19 +48,21 @@ const browser = await launch({
48
48
  fingerprint: "user-7423",
49
49
  proxy: { server: "http://host:8080", username: "u", password: "p" }, // standard Playwright option
50
50
  timezone: "America/New_York",
51
- webrtcIp: "203.0.113.10", // make WebRTC report the proxy egress IP
51
+ webrtcIp: "203.0.113.10", // make WebRTC report the proxy egress IP, not your host's
52
52
  });
53
53
  ```
54
54
 
55
+ **WebRTC won't leak your real IP.** The engine *fabricates* the WebRTC server-reflexive (`srflx`) candidate at `webrtcIp` and sends **no real STUN** from your host — so WebRTC reports the proxy IP and your real IP never leaks at the packet level. A plain candidate "relabel" doesn't stop the leak (the real STUN packet still goes out from your host); Clearcote sends none. Raw host candidates are suppressed, and the candidate set stays coherent (not empty/disabled).
56
+
55
57
  ### Auto geo-match (`geoip`)
56
58
 
57
- Set `geoip: true` and Clearcote resolves the **proxy's exit IP** (looked up *through* the proxy) and auto-fills any unset `timezone`, `acceptLanguage`, and `location` so they match the proxy's region — no manual timezone/locale bookkeeping:
59
+ Set `geoip: true` and Clearcote resolves the **proxy's exit IP** (looked up *through* the proxy) and auto-fills any unset `timezone`, `acceptLanguage`, `location`, **and `webrtcIp`** so the whole identity — clock, language, geo, and WebRTC IP — matches the proxy's region:
58
60
 
59
61
  ```ts
60
62
  const browser = await launch({
61
63
  fingerprint: "user-7423",
62
64
  proxy: { server: "http://host:8080", username: "u", password: "p" },
63
- geoip: true, // timezone + navigator.languages/Accept-Language auto-set from the proxy's geo
65
+ geoip: true, // timezone, languages, location, AND WebRTC IP all auto-set to the proxy's geo
64
66
  });
65
67
  ```
66
68
 
@@ -97,9 +99,9 @@ All optional. Anything not listed here is passed straight through to Playwright
97
99
  | `location` | `--fingerprint-location` | `"lat,lng"` (only when geo permission is granted). |
98
100
  | `timezone` | `--timezone` | IANA timezone, e.g. `America/New_York`. |
99
101
  | `acceptLanguage` | `--accept-lang` | `navigator.languages` + `Accept-Language` header, e.g. `en-US,en`. |
100
- | `webrtcIp` | `--webrtc-ip` | WebRTC egress IP to report (your proxy IP). |
102
+ | `webrtcIp` | `--webrtc-ip` | WebRTC IP to report. The engine **fabricates** the `srflx` candidate at this IP and sends **no real STUN** from the host, so the real IP never leaks (not merely relabeled). |
101
103
  | `disableGpuFingerprint` | `--disable-gpu-fingerprint` | Turn off GPU/WebGL spoofing. |
102
- | `geoip` | _(directive)_ | `true` → resolve the proxy's exit-IP geo and auto-fill timezone/acceptLanguage/location. |
104
+ | `geoip` | _(directive)_ | `true` → resolve the proxy's exit-IP geo and auto-fill timezone/acceptLanguage/location/**webrtcIp**. |
103
105
 
104
106
  ## API
105
107
 
@@ -128,6 +130,32 @@ A SHA-256 mismatch is a hard error — the SDK refuses to run an unverified bina
128
130
  independently confirm the published checksums and GPG signatures on the
129
131
  [release page](https://github.com/clearcotelabs/clearcote-browser/releases).
130
132
 
133
+ ### Stay on the latest build (`autoUpdate`)
134
+
135
+ By default the SDK installs the **exact browser build pinned into this package** — reproducible,
136
+ and the baked-in SHA-256 is the trust anchor. To follow new browser releases **without upgrading
137
+ the package every time**, opt in:
138
+
139
+ ```ts
140
+ const browser = await launch({ fingerprint: "seed-123", autoUpdate: true });
141
+ ```
142
+
143
+ or set the environment variable globally:
144
+
145
+ ```bash
146
+ CLEARCOTE_AUTO_UPDATE=1
147
+ ```
148
+
149
+ With `autoUpdate`, the SDK resolves the **newest GitHub release**, downloads its zip, and verifies
150
+ it against that release's published `SHA256SUMS.txt`. When a **`gpg`** binary is available it
151
+ additionally imports the release's public key, confirms its fingerprint equals the pinned
152
+ `CA96F185 F96A693A EDB3AC1F CB00D851 B7A86B0F`, and verifies the signed checksum — so an
153
+ auto-resolved build is cryptographically authenticated, not just downloaded. If GitHub is
154
+ unreachable it falls back to the pinned release; if the latest release *is* the pinned one, the
155
+ audited baked-in hashes are used. Each build is cached per tag, so this only downloads when a new
156
+ version actually ships. (For locked-down/reproducible deployments, leave `autoUpdate` off and bump
157
+ the package deliberately.)
158
+
131
159
  ## License
132
160
 
133
161
  BSD-3-Clause. See [LICENSE](../../LICENSE).
@@ -3,6 +3,14 @@ export interface DownloadOptions {
3
3
  cacheDir?: string;
4
4
  /** Suppress progress logging. */
5
5
  quiet?: boolean;
6
+ /**
7
+ * Opt in to resolving and downloading the LATEST GitHub release instead of the version pinned
8
+ * into this SDK, so you don't have to upgrade the package for every browser build. Verified
9
+ * against the release's own SHA256SUMS.txt (+ GPG signature when `gpg` is installed). Falls back
10
+ * to the pinned release if GitHub can't be reached. Default: false.
11
+ * Also enabled by setting the env var `CLEARCOTE_AUTO_UPDATE=1`.
12
+ */
13
+ autoUpdate?: boolean;
6
14
  }
7
15
  /**
8
16
  * Ensure the Clearcote binary is present and verified; return the path to chrome.exe.
@@ -1 +1 @@
1
- {"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../src/download.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAqED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,IAAI,GAAE,eAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6C9E"}
1
+ {"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../src/download.ts"],"names":[],"mappings":"AAyBA,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAkQD;;;GAGG;AACH,wBAAsB,YAAY,CAAC,IAAI,GAAE,eAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsB9E"}
package/dist/download.js CHANGED
@@ -1,20 +1,36 @@
1
1
  // Resolve the Clearcote browser binary: use an explicit path / env override if given, otherwise
2
- // download the pinned release, verify its SHA-256 against the value baked into the SDK, extract
3
- // it to a per-version cache, and return the path to chrome.exe. The hash check is mandatory —
4
- // a mismatch throws and the partial download is deleted.
2
+ // download a release, verify it, extract it to a per-version cache, and return chrome.exe.
3
+ //
4
+ // Two modes:
5
+ // • pinned (default) — download the exact release baked into this SDK and verify its zip +
6
+ // chrome.exe against the SHA-256 hashes shipped in release.ts. The hash
7
+ // IS the trust anchor: you audit it once, in the package you installed.
8
+ // • autoUpdate (opt-in) — resolve the NEWEST GitHub release at runtime, verify the zip against
9
+ // that release's published SHA256SUMS.txt, and — when a `gpg` binary is
10
+ // available — verify SHA256SUMS.txt.asc against the pinned signing-key
11
+ // fingerprint. Lets you stay current without bumping the SDK. Falls back
12
+ // to the pinned release if GitHub is unreachable.
13
+ // A hash mismatch (either mode) is always a hard failure and the partial download is deleted.
14
+ import { spawnSync } from "node:child_process";
5
15
  import { createHash } from "node:crypto";
6
- import { createReadStream, createWriteStream, existsSync, mkdirSync, readdirSync, writeFileSync } from "node:fs";
16
+ import { createReadStream, createWriteStream, existsSync, mkdirSync, mkdtempSync, readdirSync, writeFileSync } from "node:fs";
7
17
  import { rm } from "node:fs/promises";
8
18
  import os from "node:os";
9
19
  import path from "node:path";
10
20
  import { Readable } from "node:stream";
11
21
  import { pipeline } from "node:stream/promises";
12
22
  import extract from "extract-zip";
13
- import { RELEASE } from "./release.js";
23
+ import { RELEASE, REPO, SIGNING_KEY_FPR } from "./release.js";
14
24
  function log(quiet, msg) {
15
25
  if (!quiet)
16
26
  process.stderr.write(`[clearcote] ${msg}\n`);
17
27
  }
28
+ function autoUpdateRequested(opt) {
29
+ if (opt !== undefined)
30
+ return opt;
31
+ const env = process.env.CLEARCOTE_AUTO_UPDATE;
32
+ return env === "1" || env === "true";
33
+ }
18
34
  function defaultCacheRoot() {
19
35
  if (process.env.CLEARCOTE_CACHE)
20
36
  return process.env.CLEARCOTE_CACHE;
@@ -56,18 +72,18 @@ function sha256File(file) {
56
72
  .on("end", () => resolve(hash.digest("hex")));
57
73
  });
58
74
  }
59
- async function downloadTo(url, dest, quiet) {
75
+ async function downloadTo(url, dest, expectedSize, quiet) {
60
76
  const res = await fetch(url, { redirect: "follow" });
61
77
  if (!res.ok || !res.body) {
62
78
  throw new Error(`Clearcote download failed: HTTP ${res.status} ${res.statusText} for ${url}`);
63
79
  }
64
- const total = Number(res.headers.get("content-length")) || RELEASE.size;
80
+ const total = Number(res.headers.get("content-length")) || expectedSize;
65
81
  let seen = 0;
66
82
  let lastPct = -1;
67
83
  const progress = new TransformStream({
68
84
  transform(chunk, controller) {
69
85
  seen += chunk.byteLength;
70
- const pct = Math.floor((seen / total) * 100);
86
+ const pct = total ? Math.floor((seen / total) * 100) : 0;
71
87
  if (!quiet && pct !== lastPct && pct % 5 === 0) {
72
88
  lastPct = pct;
73
89
  process.stderr.write(`\r[clearcote] downloading ${pct}% (${(seen / 1e6).toFixed(0)}/${(total / 1e6).toFixed(0)} MB)`);
@@ -79,44 +95,201 @@ async function downloadTo(url, dest, quiet) {
79
95
  if (!quiet)
80
96
  process.stderr.write("\n");
81
97
  }
98
+ async function fetchText(url) {
99
+ const res = await fetch(url, { redirect: "follow", headers: { "User-Agent": "clearcote-sdk" } });
100
+ if (!res.ok)
101
+ throw new Error(`HTTP ${res.status} for ${url}`);
102
+ return res.text();
103
+ }
104
+ async function fetchToFile(url, dest) {
105
+ writeFileSync(dest, await fetchText(url));
106
+ }
107
+ /** Pull the zip + chrome.exe hashes out of a SHA256SUMS.txt body. */
108
+ function parseSums(text, zipName) {
109
+ const out = {};
110
+ for (const raw of text.split(/\r?\n/)) {
111
+ const m = raw.trim().match(/^([0-9a-fA-F]{64})\s+[*]?(.+)$/);
112
+ if (!m)
113
+ continue;
114
+ const base = m[2].split(/[\\/]/).pop();
115
+ if (base === zipName)
116
+ out.zip = m[1].toLowerCase();
117
+ else if (base === "chrome.exe")
118
+ out.exe = m[1].toLowerCase();
119
+ }
120
+ return out;
121
+ }
122
+ /** Resolve the newest non-draft GitHub release with a windows-x64 zip + SHA256SUMS.txt. */
123
+ async function resolveLatest(quiet) {
124
+ let list;
125
+ try {
126
+ const res = await fetch(`https://api.github.com/repos/${REPO}/releases?per_page=30`, {
127
+ redirect: "follow",
128
+ headers: { "User-Agent": "clearcote-sdk", Accept: "application/vnd.github+json" },
129
+ });
130
+ if (!res.ok)
131
+ throw new Error(`GitHub API HTTP ${res.status}`);
132
+ list = (await res.json());
133
+ }
134
+ catch (e) {
135
+ log(quiet, `auto-update: couldn't reach GitHub (${e.message}); using pinned ${RELEASE.tag}`);
136
+ return null;
137
+ }
138
+ const releases = list
139
+ .filter((r) => r && !r.draft)
140
+ .sort((a, b) => String(b.published_at || "").localeCompare(String(a.published_at || "")));
141
+ for (const r of releases) {
142
+ const assets = r.assets || [];
143
+ const zip = assets.find((a) => /^clearcote-.*-windows-x64\.zip$/.test(a.name));
144
+ const sums = assets.find((a) => a.name === "SHA256SUMS.txt");
145
+ if (!zip || !sums)
146
+ continue;
147
+ let parsed;
148
+ try {
149
+ parsed = parseSums(await fetchText(sums.browser_download_url), zip.name);
150
+ }
151
+ catch {
152
+ continue;
153
+ }
154
+ if (!parsed.zip)
155
+ continue;
156
+ const m = zip.name.match(/^clearcote-(.+)-windows-x64\.zip$/);
157
+ return {
158
+ tag: r.tag_name,
159
+ version: m ? m[1] : r.tag_name,
160
+ asset: zip.name,
161
+ url: zip.browser_download_url,
162
+ sha256: parsed.zip,
163
+ exeSha256: parsed.exe || "",
164
+ size: zip.size || 0,
165
+ os: "win32",
166
+ unpinned: true,
167
+ ascUrl: assets.find((a) => a.name === "SHA256SUMS.txt.asc")?.browser_download_url,
168
+ keyUrl: assets.find((a) => a.name === "clearcote-signing-key.asc")?.browser_download_url,
169
+ };
170
+ }
171
+ return null;
172
+ }
173
+ function hasGpg() {
174
+ try {
175
+ return spawnSync("gpg", ["--version"], { stdio: "ignore" }).status === 0;
176
+ }
177
+ catch {
178
+ return false;
179
+ }
180
+ }
82
181
  /**
83
- * Ensure the Clearcote binary is present and verified; return the path to chrome.exe.
84
- * Cached per release tag, so subsequent calls are instant.
182
+ * Best-effort GPG check for an auto-resolved release: import the published key into a throwaway
183
+ * keyring, confirm its fingerprint equals the pinned one, then verify SHA256SUMS.txt.asc.
184
+ * Returns "ok" | "skipped" (no gpg / no signature) | "failed". A "failed" result is treated as a
185
+ * hard error by the caller; "skipped" proceeds (integrity is still guaranteed by the SHA-256 check).
85
186
  */
86
- export async function ensureBinary(opts = {}) {
87
- const base = path.join(opts.cacheDir || defaultCacheRoot(), RELEASE.tag);
88
- const browserDir = path.join(base, "browser");
89
- const marker = path.join(base, ".verified");
90
- if (existsSync(marker)) {
91
- const cached = findFile(browserDir, "chrome.exe");
92
- if (cached)
93
- return cached;
187
+ async function gpgVerifyAsync(rel, sumsBody, tmp, quiet) {
188
+ if (!rel.ascUrl || !rel.keyUrl)
189
+ return "skipped";
190
+ if (!hasGpg()) {
191
+ log(quiet, "auto-update: gpg not found — skipping signature check (zip is still SHA-256-verified)");
192
+ return "skipped";
193
+ }
194
+ const home = mkdtempSync(path.join(tmp, "ccgpg-"));
195
+ const keyPath = path.join(home, "key.asc");
196
+ const sumsPath = path.join(home, "SHA256SUMS.txt");
197
+ const ascPath = path.join(home, "SHA256SUMS.txt.asc");
198
+ const gpg = (args) => spawnSync("gpg", ["--homedir", home, "--batch", ...args], { encoding: "utf8" });
199
+ try {
200
+ writeFileSync(sumsPath, sumsBody);
201
+ await fetchToFile(rel.keyUrl, keyPath);
202
+ await fetchToFile(rel.ascUrl, ascPath);
203
+ if (gpg(["--import", keyPath]).status !== 0)
204
+ return "failed";
205
+ const shown = gpg(["--with-colons", "--fingerprint"]);
206
+ const fprs = (shown.stdout || "")
207
+ .split(/\r?\n/)
208
+ .filter((l) => l.startsWith("fpr:"))
209
+ .map((l) => l.split(":")[9]);
210
+ if (!fprs.includes(SIGNING_KEY_FPR)) {
211
+ log(quiet, `auto-update: signing key fingerprint mismatch (expected ${SIGNING_KEY_FPR})`);
212
+ return "failed";
213
+ }
214
+ const verified = gpg(["--verify", ascPath, sumsPath]);
215
+ return verified.status === 0 ? "ok" : "failed";
216
+ }
217
+ catch {
218
+ return "failed";
94
219
  }
220
+ finally {
221
+ await rm(home, { recursive: true, force: true });
222
+ }
223
+ }
224
+ /** Download + verify a resolved release into `base`, returning the extracted chrome.exe path. */
225
+ async function fetchAndVerify(rel, base, opts) {
226
+ const browserDir = path.join(base, "browser");
95
227
  mkdirSync(base, { recursive: true });
96
- const zipPath = path.join(base, RELEASE.asset);
97
- log(opts.quiet, `fetching Clearcote ${RELEASE.version} (${RELEASE.tag}, ~${(RELEASE.size / 1e6).toFixed(0)} MB)`);
98
- await downloadTo(RELEASE.url, zipPath, opts.quiet);
228
+ const zipPath = path.join(base, rel.asset);
229
+ log(opts.quiet, `fetching Clearcote ${rel.version} (${rel.tag}${rel.unpinned ? ", latest" : ""}, ~${(rel.size / 1e6).toFixed(0)} MB)`);
230
+ await downloadTo(rel.url, zipPath, rel.size, opts.quiet);
99
231
  log(opts.quiet, "verifying SHA-256");
100
232
  const got = await sha256File(zipPath);
101
- if (got.toLowerCase() !== RELEASE.sha256.toLowerCase()) {
233
+ if (got.toLowerCase() !== rel.sha256.toLowerCase()) {
102
234
  await rm(zipPath, { force: true });
103
- throw new Error(`Clearcote archive SHA-256 mismatch — refusing to use it.\n expected ${RELEASE.sha256}\n got ${got}`);
235
+ throw new Error(`Clearcote archive SHA-256 mismatch — refusing to use it.\n expected ${rel.sha256}\n got ${got}`);
236
+ }
237
+ // For an auto-resolved (un-pinned) release, also confirm authenticity via the signed checksum file.
238
+ if (rel.unpinned && rel.ascUrl) {
239
+ const sumsBody = await fetchText(`https://github.com/${REPO}/releases/download/${rel.tag}/SHA256SUMS.txt`).catch(() => "");
240
+ if (sumsBody) {
241
+ const verdict = await gpgVerifyAsync(rel, sumsBody, base, opts.quiet);
242
+ if (verdict === "failed") {
243
+ await rm(zipPath, { force: true });
244
+ throw new Error(`Clearcote ${rel.tag}: GPG signature verification FAILED against the pinned key ${SIGNING_KEY_FPR} — refusing to use it.`);
245
+ }
246
+ if (verdict === "ok")
247
+ log(opts.quiet, `auto-update: GPG signature OK (key ${SIGNING_KEY_FPR})`);
248
+ }
104
249
  }
105
250
  log(opts.quiet, "extracting");
106
251
  await rm(browserDir, { recursive: true, force: true });
107
252
  await extract(zipPath, { dir: browserDir });
108
253
  const exe = findFile(browserDir, "chrome.exe");
109
- if (!exe) {
254
+ if (!exe)
110
255
  throw new Error("Clearcote archive verified but chrome.exe was not found inside it.");
256
+ if (rel.exeSha256) {
257
+ const exeHash = await sha256File(exe);
258
+ if (exeHash.toLowerCase() !== rel.exeSha256.toLowerCase()) {
259
+ throw new Error(`Clearcote chrome.exe SHA-256 mismatch — refusing to use it.\n expected ${rel.exeSha256}\n got ${exeHash}`);
260
+ }
111
261
  }
112
- // defense in depth: verify the extracted exe too
113
- const exeHash = await sha256File(exe);
114
- if (exeHash.toLowerCase() !== RELEASE.exeSha256.toLowerCase()) {
115
- throw new Error(`Clearcote chrome.exe SHA-256 mismatch — refusing to use it.\n expected ${RELEASE.exeSha256}\n got ${exeHash}`);
116
- }
117
- writeFileSync(marker, `${RELEASE.sha256}\n`);
262
+ writeFileSync(path.join(base, ".verified"), `${rel.sha256}\n`);
118
263
  await rm(zipPath, { force: true }); // reclaim ~250 MB; keep only the extracted tree
119
264
  log(opts.quiet, `ready: ${exe}`);
120
265
  return exe;
121
266
  }
267
+ /**
268
+ * Ensure the Clearcote binary is present and verified; return the path to chrome.exe.
269
+ * Cached per release tag, so subsequent calls are instant.
270
+ */
271
+ export async function ensureBinary(opts = {}) {
272
+ const cacheRoot = opts.cacheDir || defaultCacheRoot();
273
+ let rel;
274
+ if (autoUpdateRequested(opts.autoUpdate)) {
275
+ const latest = await resolveLatest(opts.quiet);
276
+ if (latest && latest.tag === RELEASE.tag) {
277
+ // newest release IS the pinned one — prefer the baked-in hashes (the audited trust anchor).
278
+ rel = { ...RELEASE, unpinned: false };
279
+ }
280
+ else {
281
+ rel = latest ?? { ...RELEASE, unpinned: false };
282
+ }
283
+ }
284
+ else {
285
+ rel = { ...RELEASE, unpinned: false };
286
+ }
287
+ const base = path.join(cacheRoot, rel.tag);
288
+ if (existsSync(path.join(base, ".verified"))) {
289
+ const cached = findFile(path.join(base, "browser"), "chrome.exe");
290
+ if (cached)
291
+ return cached;
292
+ }
293
+ return fetchAndVerify(rel, base, opts);
294
+ }
122
295
  //# sourceMappingURL=download.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"download.js","sourceRoot":"","sources":["../src/download.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,gGAAgG;AAChG,8FAA8F;AAC9F,yDAAyD;AAEzD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACjH,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACtC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,OAAO,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AASvC,SAAS,GAAG,CAAC,KAA0B,EAAE,GAAW;IAClD,IAAI,CAAC,KAAK;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,gBAAgB;IACvB,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IACpE,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IAClH,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,EAAE,WAAW,CAAC,CAAC;AACjG,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW,EAAE,IAAY;IACzC,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC;IACpB,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC;QACpB,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAY,CAAC;QAClC,IAAI,OAAmC,CAAC;QACxC,IAAI,CAAC;YACH,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,CAAC,CAAC,WAAW,EAAE;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;iBACjC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE;gBAAE,OAAO,IAAI,CAAC;QACpE,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QAClC,gBAAgB,CAAC,IAAI,CAAC;aACnB,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;aACnB,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;aACjC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,GAAW,EAAE,IAAY,EAAE,KAA0B;IAC7E,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;IACrD,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,mCAAmC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,QAAQ,GAAG,EAAE,CAAC,CAAC;IAChG,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;IACxE,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC;IACjB,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAyB;QAC3D,SAAS,CAAC,KAAK,EAAE,UAAU;YACzB,IAAI,IAAI,KAAK,CAAC,UAAU,CAAC;YACzB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;YAC7C,IAAI,CAAC,KAAK,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC/C,OAAO,GAAG,GAAG,CAAC;gBACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6BAA6B,GAAG,MAAM,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YACxH,CAAC;YACD,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;KACF,CAAC,CAAC;IACH,MAAM,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAQ,CAAC,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;IACjG,IAAI,CAAC,KAAK;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAwB,EAAE;IAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,gBAAgB,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACzE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAE5C,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;QAClD,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;IAC5B,CAAC;IAED,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAE/C,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,sBAAsB,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAClH,MAAM,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAEnD,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;IACtC,IAAI,GAAG,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;QACvD,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,wEAAwE,OAAO,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAC5G,CAAC;IACJ,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAC9B,MAAM,EAAE,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,MAAM,OAAO,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC;IAE5C,MAAM,GAAG,GAAG,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAC/C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;IACxF,CAAC;IACD,iDAAiD;IACjD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,OAAO,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC;QAC9D,MAAM,IAAI,KAAK,CACb,2EAA2E,OAAO,CAAC,SAAS,gBAAgB,OAAO,EAAE,CACtH,CAAC;IACJ,CAAC;IAED,aAAa,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;IAC7C,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,gDAAgD;IACpF,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,EAAE,CAAC,CAAC;IACjC,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"download.js","sourceRoot":"","sources":["../src/download.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,2FAA2F;AAC3F,EAAE;AACF,aAAa;AACb,iGAAiG;AACjG,mGAAmG;AACnG,mGAAmG;AACnG,kGAAkG;AAClG,mGAAmG;AACnG,kGAAkG;AAClG,oGAAoG;AACpG,6EAA6E;AAC7E,8FAA8F;AAE9F,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC9H,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACtC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,OAAO,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAoB,MAAM,cAAc,CAAC;AA2BhF,SAAS,GAAG,CAAC,KAA0B,EAAE,GAAW;IAClD,IAAI,CAAC,KAAK;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,mBAAmB,CAAC,GAAwB;IACnD,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC;IAClC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;IAC9C,OAAO,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,MAAM,CAAC;AACvC,CAAC;AAED,SAAS,gBAAgB;IACvB,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IACpE,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IAClH,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,EAAE,WAAW,CAAC,CAAC;AACjG,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW,EAAE,IAAY;IACzC,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC;IACpB,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC;QACpB,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAY,CAAC;QAClC,IAAI,OAAmC,CAAC;QACxC,IAAI,CAAC;YACH,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,CAAC,CAAC,WAAW,EAAE;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;iBACjC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE;gBAAE,OAAO,IAAI,CAAC;QACpE,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QAClC,gBAAgB,CAAC,IAAI,CAAC;aACnB,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;aACnB,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;aACjC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,GAAW,EAAE,IAAY,EAAE,YAAoB,EAAE,KAA0B;IACnG,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;IACrD,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,mCAAmC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,QAAQ,GAAG,EAAE,CAAC,CAAC;IAChG,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,YAAY,CAAC;IACxE,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC;IACjB,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAyB;QAC3D,SAAS,CAAC,KAAK,EAAE,UAAU;YACzB,IAAI,IAAI,KAAK,CAAC,UAAU,CAAC;YACzB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACzD,IAAI,CAAC,KAAK,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC/C,OAAO,GAAG,GAAG,CAAC;gBACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6BAA6B,GAAG,MAAM,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YACxH,CAAC;YACD,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;KACF,CAAC,CAAC;IACH,MAAM,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAQ,CAAC,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;IACjG,IAAI,CAAC,KAAK;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,GAAW;IAClC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,YAAY,EAAE,eAAe,EAAE,EAAE,CAAC,CAAC;IACjG,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,MAAM,QAAQ,GAAG,EAAE,CAAC,CAAC;IAC9D,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;AACpB,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,GAAW,EAAE,IAAY;IAClD,aAAa,CAAC,IAAI,EAAE,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,qEAAqE;AACrE,SAAS,SAAS,CAAC,IAAY,EAAE,OAAe;IAC9C,MAAM,GAAG,GAAmC,EAAE,CAAC;IAC/C,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;QAC7D,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC;QACvC,IAAI,IAAI,KAAK,OAAO;YAAE,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;aAC9C,IAAI,IAAI,KAAK,YAAY;YAAE,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC/D,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,2FAA2F;AAC3F,KAAK,UAAU,aAAa,CAAC,KAA0B;IACrD,IAAI,IAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,gCAAgC,IAAI,uBAAuB,EAAE;YACnF,QAAQ,EAAE,QAAQ;YAClB,OAAO,EAAE,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,EAAE,6BAA6B,EAAE;SAClF,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9D,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAU,CAAC;IACrC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,GAAG,CAAC,KAAK,EAAE,uCAAwC,CAAW,CAAC,OAAO,mBAAmB,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACxG,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI;SAClB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;SAC5B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5F,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,MAAM,GAAU,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iCAAiC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/E,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,gBAAgB,CAAC,CAAC;QAC7D,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI;YAAE,SAAS;QAC5B,IAAI,MAAsC,CAAC;QAC3C,IAAI,CAAC;YACH,MAAM,GAAG,SAAS,CAAC,MAAM,SAAS,CAAC,IAAI,CAAC,oBAAoB,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3E,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,GAAG;YAAE,SAAS;QAC1B,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAC9D,OAAO;YACL,GAAG,EAAE,CAAC,CAAC,QAAQ;YACf,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ;YAC9B,KAAK,EAAE,GAAG,CAAC,IAAI;YACf,GAAG,EAAE,GAAG,CAAC,oBAAoB;YAC7B,MAAM,EAAE,MAAM,CAAC,GAAG;YAClB,SAAS,EAAE,MAAM,CAAC,GAAG,IAAI,EAAE;YAC3B,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC;YACnB,EAAE,EAAE,OAAO;YACX,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,oBAAoB,CAAC,EAAE,oBAAoB;YACjF,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,2BAA2B,CAAC,EAAE,oBAAoB;SACzF,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,MAAM;IACb,IAAI,CAAC;QACH,OAAO,SAAS,CAAC,KAAK,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;IAC3E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,cAAc,CAC3B,GAAoB,EACpB,QAAgB,EAChB,GAAW,EACX,KAA0B;IAE1B,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IACjD,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;QACd,GAAG,CAAC,KAAK,EAAE,uFAAuF,CAAC,CAAC;QACpG,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,CAAC,IAAc,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IAChH,IAAI,CAAC;QACH,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAClC,MAAM,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACvC,MAAM,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACvC,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,QAAQ,CAAC;QAC7D,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC,CAAC;QACtD,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;aAC9B,KAAK,CAAC,OAAO,CAAC;aACd,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;aACnC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;YACpC,GAAG,CAAC,KAAK,EAAE,2DAA2D,eAAe,GAAG,CAAC,CAAC;YAC1F,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;QACtD,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;AACH,CAAC;AAED,iGAAiG;AACjG,KAAK,UAAU,cAAc,CAAC,GAAoB,EAAE,IAAY,EAAE,IAAqB;IACrF,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC9C,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IAE3C,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,sBAAsB,GAAG,CAAC,OAAO,KAAK,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACvI,MAAM,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAEzD,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;IACtC,IAAI,GAAG,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;QACnD,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,wEAAwE,GAAG,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC,CAAC;IAC3H,CAAC;IAED,oGAAoG;IACpG,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,sBAAsB,IAAI,sBAAsB,GAAG,CAAC,GAAG,iBAAiB,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAC3H,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YACtE,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;gBACzB,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBACnC,MAAM,IAAI,KAAK,CACb,aAAa,GAAG,CAAC,GAAG,8DAA8D,eAAe,wBAAwB,CAC1H,CAAC;YACJ,CAAC;YACD,IAAI,OAAO,KAAK,IAAI;gBAAE,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,sCAAsC,eAAe,GAAG,CAAC,CAAC;QAClG,CAAC;IACH,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAC9B,MAAM,EAAE,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,MAAM,OAAO,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC;IAE5C,MAAM,GAAG,GAAG,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAC/C,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;IAChG,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QAClB,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,OAAO,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC;YAC1D,MAAM,IAAI,KAAK,CAAC,2EAA2E,GAAG,CAAC,SAAS,gBAAgB,OAAO,EAAE,CAAC,CAAC;QACrI,CAAC;IACH,CAAC;IAED,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC;IAC/D,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,gDAAgD;IACpF,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,EAAE,CAAC,CAAC;IACjC,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAwB,EAAE;IAC3D,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,IAAI,gBAAgB,EAAE,CAAC;IAEtD,IAAI,GAAoB,CAAC;IACzB,IAAI,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,MAAM,IAAI,MAAM,CAAC,GAAG,KAAK,OAAO,CAAC,GAAG,EAAE,CAAC;YACzC,4FAA4F;YAC5F,GAAG,GAAG,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;QACxC,CAAC;aAAM,CAAC;YACN,GAAG,GAAG,MAAM,IAAI,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;QAClD,CAAC;IACH,CAAC;SAAM,CAAC;QACN,GAAG,GAAG,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IACxC,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;QAC7C,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,YAAY,CAAC,CAAC;QAClE,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;IAC5B,CAAC;IACD,OAAO,cAAc,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACzC,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { Browser, BrowserContext, Page } from "playwright-core";
2
+ export interface HumanizeOptions {
3
+ /** Route clicks/moves/scroll through the engine's humanized (bezier, trusted) input. */
4
+ humanize?: boolean;
5
+ /** Show a red cursor dot that tracks the motion (visualization). */
6
+ showCursor?: boolean;
7
+ }
8
+ /** Overlay: a red dot that follows real mousemove events. Idempotent IIFE so it works both as
9
+ * an addInitScript source string AND when passed to page.evaluate (Node treats a bare arrow
10
+ * string as an uncalled expression — an IIFE actually runs). */
11
+ export declare const CURSOR_OVERLAY = "(() => {\n if (window.__clearcoteCursor) return; window.__clearcoteCursor = 1;\n const make = () => {\n if (document.getElementById('__clearcote_cursor')) return;\n const d = document.createElement('div'); d.id = '__clearcote_cursor';\n d.style.cssText = 'position:fixed;left:0;top:0;width:20px;height:20px;margin:-10px 0 0 -10px;' +\n 'border-radius:50%;border:2px solid #ff3b3b;background:rgba(255,59,59,.22);' +\n 'box-shadow:0 0 10px rgba(255,59,59,.6);pointer-events:none;z-index:2147483647';\n (document.body || document.documentElement).appendChild(d);\n };\n if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', make); else make();\n document.addEventListener('mousemove', (e) => {\n const d = document.getElementById('__clearcote_cursor');\n if (d) { d.style.left = e.clientX + 'px'; d.style.top = e.clientY + 'px'; }\n }, true);\n})();";
12
+ /** Wrap a single page's input methods + (optionally) inject the cursor overlay. */
13
+ export declare function attachHumanize(browser: Browser, page: Page, opts: HumanizeOptions): Promise<void>;
14
+ /** Install humanize/showCursor on a browser: wraps newPage/newContext so every page is covered. */
15
+ export declare function installHumanize(browser: Browser, opts: HumanizeOptions): void;
16
+ /** Install humanize/showCursor on a single context (used for launchPersistentContext). */
17
+ export declare function installHumanizeOnContext(context: BrowserContext, opts: HumanizeOptions, browser?: Browser | null): void;
18
+ //# sourceMappingURL=humanize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"humanize.d.ts","sourceRoot":"","sources":["../src/humanize.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAc,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEjF,MAAM,WAAW,eAAe;IAC9B,wFAAwF;IACxF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oEAAoE;IACpE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;gEAEgE;AAChE,eAAO,MAAM,cAAc,o5BAerB,CAAC;AAUP,mFAAmF;AACnF,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA0EvG;AAED,mGAAmG;AACnG,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,eAAe,GAAG,IAAI,CAc7E;AAED,0FAA0F;AAC1F,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,GACvE,IAAI,CAQN"}
@@ -0,0 +1,150 @@
1
+ // Humanized input + cursor visualization.
2
+ //
3
+ // `humanize: true` — routes page.click/hover/mouse.move/mouse.click through the engine's
4
+ // `Browser.humanizedClick` CDP command (real trusted WebMouseEvent along a cubic-bezier path,
5
+ // isTrusted===true, navigator.webdriver stays false), and eases mouse.wheel SDK-side.
6
+ // `showCursor: true` — injects a red cursor dot that follows the real mousemove events the engine
7
+ // fires, so you can watch the motion (cross-platform; no native overlay needed).
8
+ //
9
+ // Requires a Clearcote binary that exposes Browser.humanizedClick (the humanized-input engine
10
+ // build). On an older binary the command is absent; humanize falls back to native Playwright input.
11
+ /** Overlay: a red dot that follows real mousemove events. Idempotent IIFE so it works both as
12
+ * an addInitScript source string AND when passed to page.evaluate (Node treats a bare arrow
13
+ * string as an uncalled expression — an IIFE actually runs). */
14
+ export const CURSOR_OVERLAY = `(() => {
15
+ if (window.__clearcoteCursor) return; window.__clearcoteCursor = 1;
16
+ const make = () => {
17
+ if (document.getElementById('__clearcote_cursor')) return;
18
+ const d = document.createElement('div'); d.id = '__clearcote_cursor';
19
+ d.style.cssText = 'position:fixed;left:0;top:0;width:20px;height:20px;margin:-10px 0 0 -10px;' +
20
+ 'border-radius:50%;border:2px solid #ff3b3b;background:rgba(255,59,59,.22);' +
21
+ 'box-shadow:0 0 10px rgba(255,59,59,.6);pointer-events:none;z-index:2147483647';
22
+ (document.body || document.documentElement).appendChild(d);
23
+ };
24
+ if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', make); else make();
25
+ document.addEventListener('mousemove', (e) => {
26
+ const d = document.getElementById('__clearcote_cursor');
27
+ if (d) { d.style.left = e.clientX + 'px'; d.style.top = e.clientY + 'px'; }
28
+ }, true);
29
+ })();`;
30
+ const rand = (a, b) => a + Math.random() * (b - a);
31
+ async function pageTargetId(page) {
32
+ const s = await page.context().newCDPSession(page);
33
+ const info = await s.send("Target.getTargetInfo");
34
+ return info.targetInfo.targetId;
35
+ }
36
+ /** Wrap a single page's input methods + (optionally) inject the cursor overlay. */
37
+ export async function attachHumanize(browser, page, opts) {
38
+ if (opts.showCursor) {
39
+ const inject = () => page.evaluate(CURSOR_OVERLAY).catch(() => { });
40
+ inject();
41
+ page.on("load", () => { inject(); });
42
+ page.on("framenavigated", (f) => { if (f === page.mainFrame())
43
+ inject(); });
44
+ }
45
+ if (!opts.humanize)
46
+ return;
47
+ let bsession = null;
48
+ let tid = null;
49
+ let supported = true;
50
+ const humanizedMove = async (x, y, noClick, duration) => {
51
+ if (!supported)
52
+ return false;
53
+ try {
54
+ bsession ??= await browser.newBrowserCDPSession();
55
+ tid ??= await pageTargetId(page);
56
+ await bsession.send("Browser.humanizedClick", {
57
+ targetId: tid, x: Math.round(x), y: Math.round(y),
58
+ duration: duration ?? rand(0.45, 0.95), noClick,
59
+ });
60
+ return true;
61
+ }
62
+ catch (e) {
63
+ // older binary without the command -> stop trying, fall back to native input
64
+ supported = false;
65
+ return false;
66
+ }
67
+ };
68
+ const mouse = page.mouse;
69
+ const nativeMove = mouse.move.bind(mouse);
70
+ const nativeClick = mouse.click.bind(mouse);
71
+ const nativeWheel = mouse.wheel.bind(mouse);
72
+ mouse.move = async (x, y, options) => {
73
+ if (!(await humanizedMove(x, y, true)))
74
+ return nativeMove(x, y, options);
75
+ };
76
+ mouse.click = async (x, y, options) => {
77
+ if (!(await humanizedMove(x, y, false)))
78
+ return nativeClick(x, y, options);
79
+ };
80
+ // scroll easing (engine humanizedClick doesn't cover wheel): break into eased chunks
81
+ mouse.wheel = async (dx, dy) => {
82
+ const steps = Math.max(5, Math.min(20, Math.round((Math.abs(dx) + Math.abs(dy)) / 80)));
83
+ const ease = (u) => u * u * (3 - 2 * u);
84
+ let px = 0, py = 0;
85
+ for (let i = 1; i <= steps; i++) {
86
+ const f = ease(i / steps);
87
+ const nx = Math.round(dx * f), ny = Math.round(dy * f);
88
+ await nativeWheel(nx - px, ny - py);
89
+ px = nx;
90
+ py = ny;
91
+ await page.waitForTimeout(rand(12, 45));
92
+ }
93
+ if (px !== dx || py !== dy)
94
+ await nativeWheel(dx - px, dy - py);
95
+ };
96
+ const wrapTargeted = (name, noClick) => {
97
+ const orig = page[name].bind(page);
98
+ page[name] = async (selector, options = {}) => {
99
+ try {
100
+ const loc = page.locator(selector).first();
101
+ await loc.scrollIntoViewIfNeeded({ timeout: options.timeout ?? 30000 });
102
+ const box = await loc.boundingBox();
103
+ if (!box)
104
+ return orig(selector, options);
105
+ const x = box.x + box.width * rand(0.3, 0.7);
106
+ const y = box.y + box.height * rand(0.3, 0.7);
107
+ if (await humanizedMove(x, y, noClick))
108
+ return;
109
+ return orig(selector, options);
110
+ }
111
+ catch {
112
+ return orig(selector, options);
113
+ }
114
+ };
115
+ };
116
+ wrapTargeted("click", false);
117
+ wrapTargeted("hover", true);
118
+ }
119
+ /** Install humanize/showCursor on a browser: wraps newPage/newContext so every page is covered. */
120
+ export function installHumanize(browser, opts) {
121
+ if (!opts.humanize && !opts.showCursor)
122
+ return;
123
+ const origNewPage = browser.newPage.bind(browser);
124
+ browser.newPage = async (options) => {
125
+ const page = await origNewPage(options);
126
+ await attachHumanize(browser, page, opts);
127
+ return page;
128
+ };
129
+ const origNewContext = browser.newContext.bind(browser);
130
+ browser.newContext = async (options) => {
131
+ const ctx = await origNewContext(options);
132
+ installHumanizeOnContext(ctx, opts, browser);
133
+ return ctx;
134
+ };
135
+ }
136
+ /** Install humanize/showCursor on a single context (used for launchPersistentContext). */
137
+ export function installHumanizeOnContext(context, opts, browser) {
138
+ if (!opts.humanize && !opts.showCursor)
139
+ return;
140
+ const b = browser ?? context.browser();
141
+ if (opts.showCursor) {
142
+ context.addInitScript(CURSOR_OVERLAY).catch(() => { });
143
+ }
144
+ if (b) {
145
+ context.on("page", (p) => { attachHumanize(b, p, opts).catch(() => { }); });
146
+ for (const p of context.pages())
147
+ attachHumanize(b, p, opts).catch(() => { });
148
+ }
149
+ }
150
+ //# sourceMappingURL=humanize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"humanize.js","sourceRoot":"","sources":["../src/humanize.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,20 +1,22 @@
1
1
  import type { Browser, BrowserContext, BrowserContextOptions, LaunchOptions as PlaywrightLaunchOptions } from "playwright-core";
2
2
  import { type DownloadOptions } from "./download.js";
3
3
  import { type FingerprintOptions } from "./fingerprint.js";
4
+ import { type HumanizeOptions } from "./humanize.js";
4
5
  export type { FingerprintOptions } from "./fingerprint.js";
5
6
  export type { DownloadOptions } from "./download.js";
6
7
  export { resolveGeo, type Geo } from "./geoip.js";
8
+ export type { HumanizeOptions } from "./humanize.js";
7
9
  export { RELEASE } from "./release.js";
8
10
  /** When true (and a proxy is set), resolve the proxy's exit-IP geo and auto-fill any unset
9
11
  * `timezone` + `acceptLanguage` (+ `location`) so they match the proxy region. */
10
12
  interface GeoipOption {
11
13
  geoip?: boolean;
12
14
  }
13
- /** Options for {@link launch}: Playwright launch options + Clearcote fingerprint options. */
14
- export interface LaunchOptions extends PlaywrightLaunchOptions, FingerprintOptions, GeoipOption {
15
+ /** Options for {@link launch}: Playwright launch options + Clearcote fingerprint + download options. */
16
+ export interface LaunchOptions extends PlaywrightLaunchOptions, FingerprintOptions, GeoipOption, HumanizeOptions, DownloadOptions {
15
17
  }
16
18
  /** Options for {@link launchPersistentContext}. */
17
- export interface PersistentContextOptions extends PlaywrightLaunchOptions, BrowserContextOptions, FingerprintOptions, GeoipOption {
19
+ export interface PersistentContextOptions extends PlaywrightLaunchOptions, BrowserContextOptions, FingerprintOptions, GeoipOption, HumanizeOptions, DownloadOptions {
18
20
  }
19
21
  /**
20
22
  * Resolve the Clearcote chrome.exe path, downloading + verifying it if needed.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACV,OAAO,EACP,cAAc,EACd,qBAAqB,EACrB,aAAa,IAAI,uBAAuB,EACzC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAA4C,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAIrG,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,KAAK,GAAG,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;kFACkF;AAClF,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,6FAA6F;AAC7F,MAAM,WAAW,aAAc,SAAQ,uBAAuB,EAAE,kBAAkB,EAAE,WAAW;CAAG;AAElG,mDAAmD;AACnD,MAAM,WAAW,wBACf,SAAQ,uBAAuB,EAC7B,qBAAqB,EACrB,kBAAkB,EAClB,WAAW;CAAG;AAqBlB;;;GAGG;AACH,wBAAsB,cAAc,CAClC,OAAO,GAAE;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,eAAoB,GAC1D,OAAO,CAAC,MAAM,CAAC,CAIjB;AAED,iGAAiG;AACjG,wBAAsB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAE7E;AAED,yEAAyE;AACzE,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAW1E;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,cAAc,CAAC,CAWzB;;;;;;;;AAED,wBAAsF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACV,OAAO,EACP,cAAc,EACd,qBAAqB,EACrB,aAAa,IAAI,uBAAuB,EACzC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAA4C,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAErG,OAAO,EAA6C,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhG,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,KAAK,GAAG,EAAE,MAAM,YAAY,CAAC;AAClD,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;kFACkF;AAClF,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wGAAwG;AACxG,MAAM,WAAW,aAAc,SAAQ,uBAAuB,EAAE,kBAAkB,EAAE,WAAW,EAAE,eAAe,EAAE,eAAe;CAAG;AAEpI,mDAAmD;AACnD,MAAM,WAAW,wBACf,SAAQ,uBAAuB,EAC7B,qBAAqB,EACrB,kBAAkB,EAClB,WAAW,EACX,eAAe,EACf,eAAe;CAAG;AAwBtB;;;GAGG;AACH,wBAAsB,cAAc,CAClC,OAAO,GAAE;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,eAAoB,GAC1D,OAAO,CAAC,MAAM,CAAC,CAIjB;AAED,iGAAiG;AACjG,wBAAsB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAE7E;AAED,yEAAyE;AACzE,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAa1E;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,cAAc,CAAC,CAazB;;;;;;;;AAED,wBAAsF"}
package/dist/index.js CHANGED
@@ -13,10 +13,11 @@ import { chromium } from "playwright-core";
13
13
  import { ensureBinary } from "./download.js";
14
14
  import { fingerprintArgs, splitFingerprintOptions } from "./fingerprint.js";
15
15
  import { resolveGeo } from "./geoip.js";
16
+ import { installHumanize, installHumanizeOnContext } from "./humanize.js";
16
17
  import { RELEASE } from "./release.js";
17
18
  export { resolveGeo } from "./geoip.js";
18
19
  export { RELEASE } from "./release.js";
19
- /** Fill unset timezone/acceptLanguage/location on `fp` from the proxy's exit-IP geo. */
20
+ /** Fill unset timezone/acceptLanguage/location/webrtcIp on `fp` from the proxy's exit-IP geo. */
20
21
  async function applyGeoip(fp, proxy) {
21
22
  const geo = await resolveGeo(proxy);
22
23
  if (!geo)
@@ -27,6 +28,10 @@ async function applyGeoip(fp, proxy) {
27
28
  fp.acceptLanguage = geo.acceptLanguage;
28
29
  if (geo.location && fp.location == null)
29
30
  fp.location = geo.location;
31
+ // make WebRTC report the proxy egress IP too, coherent with HTTP egress (engine fabricates
32
+ // the srflx candidate at this IP; no real STUN leaves the host).
33
+ if (geo.ip && fp.webrtcIp == null)
34
+ fp.webrtcIp = geo.ip;
30
35
  }
31
36
  function ensureRunnableHere(exe) {
32
37
  if (process.platform !== "win32") {
@@ -44,7 +49,7 @@ export async function executablePath(options = {}) {
44
49
  return options.executablePath;
45
50
  if (process.env.CLEARCOTE_BINARY)
46
51
  return process.env.CLEARCOTE_BINARY;
47
- return ensureBinary({ cacheDir: options.cacheDir, quiet: options.quiet });
52
+ return ensureBinary({ cacheDir: options.cacheDir, quiet: options.quiet, autoUpdate: options.autoUpdate });
48
53
  }
49
54
  /** Pre-fetch + verify the Clearcote binary without launching it. Returns the chrome.exe path. */
50
55
  export async function download(options = {}) {
@@ -52,34 +57,38 @@ export async function download(options = {}) {
52
57
  }
53
58
  /** Launch Clearcote and return a standard Playwright {@link Browser}. */
54
59
  export async function launch(options = {}) {
55
- const { executablePath: exeOption, args, geoip, ...rest } = options;
60
+ const { executablePath: exeOption, args, geoip, humanize, showCursor, autoUpdate, cacheDir, quiet, ...rest } = options;
56
61
  const { fingerprint, rest: pwOptions } = splitFingerprintOptions(rest);
57
62
  if (geoip)
58
63
  await applyGeoip(fingerprint, pwOptions.proxy);
59
- const exe = await executablePath({ executablePath: exeOption });
64
+ const exe = await executablePath({ executablePath: exeOption, autoUpdate, cacheDir, quiet });
60
65
  ensureRunnableHere(exe);
61
- return chromium.launch({
66
+ const browser = await chromium.launch({
62
67
  ...pwOptions,
63
68
  executablePath: exe,
64
69
  args: [...fingerprintArgs(fingerprint), ...(args ?? [])],
65
70
  });
71
+ installHumanize(browser, { humanize, showCursor });
72
+ return browser;
66
73
  }
67
74
  /**
68
75
  * Launch Clearcote with a persistent profile directory and return a Playwright
69
76
  * {@link BrowserContext} (cookies, storage, etc. persist in `userDataDir`).
70
77
  */
71
78
  export async function launchPersistentContext(userDataDir, options = {}) {
72
- const { executablePath: exeOption, args, geoip, ...rest } = options;
79
+ const { executablePath: exeOption, args, geoip, humanize, showCursor, autoUpdate, cacheDir, quiet, ...rest } = options;
73
80
  const { fingerprint, rest: pwOptions } = splitFingerprintOptions(rest);
74
81
  if (geoip)
75
82
  await applyGeoip(fingerprint, pwOptions.proxy);
76
- const exe = await executablePath({ executablePath: exeOption });
83
+ const exe = await executablePath({ executablePath: exeOption, autoUpdate, cacheDir, quiet });
77
84
  ensureRunnableHere(exe);
78
- return chromium.launchPersistentContext(userDataDir, {
85
+ const context = await chromium.launchPersistentContext(userDataDir, {
79
86
  ...pwOptions,
80
87
  executablePath: exe,
81
88
  args: [...fingerprintArgs(fingerprint), ...(args ?? [])],
82
89
  });
90
+ installHumanizeOnContext(context, { humanize, showCursor });
91
+ return context;
83
92
  }
84
93
  export default { launch, launchPersistentContext, executablePath, download, RELEASE };
85
94
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/release.d.ts CHANGED
@@ -17,4 +17,11 @@ export interface ReleaseInfo {
17
17
  os: NodeJS.Platform;
18
18
  }
19
19
  export declare const RELEASE: ReleaseInfo;
20
+ /** GitHub repo (owner/name) the releases come from — used by the opt-in auto-update resolver. */
21
+ export declare const REPO = "clearcotelabs/clearcote-browser";
22
+ /** Clearcote's release-signing key fingerprint, pinned out-of-band. This NEVER changes between
23
+ * releases, so it is the durable trust anchor for `autoUpdate`: when a `gpg` binary is available,
24
+ * an auto-resolved (un-pinned) release's `SHA256SUMS.txt.asc` is verified against THIS fingerprint
25
+ * before the binary is trusted. (Pinned mode trusts the baked-in sha256 instead.) */
26
+ export declare const SIGNING_KEY_FPR = "CA96F185F96A693AEDB3AC1FCB00D851B7A86B0F";
20
27
  //# sourceMappingURL=release.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"release.d.ts","sourceRoot":"","sources":["../src/release.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,WAAW;IAC1B,+CAA+C;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,2FAA2F;IAC3F,SAAS,EAAE,MAAM,CAAC;IAClB,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC;CACrB;AAED,eAAO,MAAM,OAAO,EAAE,WASrB,CAAC"}
1
+ {"version":3,"file":"release.d.ts","sourceRoot":"","sources":["../src/release.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,WAAW;IAC1B,+CAA+C;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,2FAA2F;IAC3F,SAAS,EAAE,MAAM,CAAC;IAClB,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC;CACrB;AAED,eAAO,MAAM,OAAO,EAAE,WASrB,CAAC;AAEF,iGAAiG;AACjG,eAAO,MAAM,IAAI,oCAAoC,CAAC;AAEtD;;;qFAGqF;AACrF,eAAO,MAAM,eAAe,6CAA6C,CAAC"}
package/dist/release.js CHANGED
@@ -4,13 +4,20 @@
4
4
  // this package, the hash check guarantees you run exactly the published, signed binary.
5
5
  // Published checksums + GPG signatures live on the release page.
6
6
  export const RELEASE = {
7
- tag: "v0.1.0-pre.4",
7
+ tag: "v0.1.0-pre.5",
8
8
  version: "149.0.7827.114",
9
9
  asset: "clearcote-149.0.7827.114-windows-x64.zip",
10
- url: "https://github.com/clearcotelabs/clearcote-browser/releases/download/v0.1.0-pre.4/clearcote-149.0.7827.114-windows-x64.zip",
11
- sha256: "40972168909e887434a3db4188d336bb7389d319a5c75967fb66ca6114c22e4c",
10
+ url: "https://github.com/clearcotelabs/clearcote-browser/releases/download/v0.1.0-pre.5/clearcote-149.0.7827.114-windows-x64.zip",
11
+ sha256: "21b6c520f2866ead759c19aa02ac30570aee3ebb41f5196518c27604a693c7e6",
12
12
  exeSha256: "5743595256c89c6874804bf3315acce592fc7f1883760c8d380c010151a73b23",
13
- size: 253019015,
13
+ size: 242548712,
14
14
  os: "win32",
15
15
  };
16
+ /** GitHub repo (owner/name) the releases come from — used by the opt-in auto-update resolver. */
17
+ export const REPO = "clearcotelabs/clearcote-browser";
18
+ /** Clearcote's release-signing key fingerprint, pinned out-of-band. This NEVER changes between
19
+ * releases, so it is the durable trust anchor for `autoUpdate`: when a `gpg` binary is available,
20
+ * an auto-resolved (un-pinned) release's `SHA256SUMS.txt.asc` is verified against THIS fingerprint
21
+ * before the binary is trusted. (Pinned mode trusts the baked-in sha256 instead.) */
22
+ export const SIGNING_KEY_FPR = "CA96F185F96A693AEDB3AC1FCB00D851B7A86B0F";
16
23
  //# sourceMappingURL=release.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"release.js","sourceRoot":"","sources":["../src/release.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,wFAAwF;AACxF,2FAA2F;AAC3F,wFAAwF;AACxF,iEAAiE;AAqBjE,MAAM,CAAC,MAAM,OAAO,GAAgB;IAClC,GAAG,EAAE,cAAc;IACnB,OAAO,EAAE,gBAAgB;IACzB,KAAK,EAAE,0CAA0C;IACjD,GAAG,EAAE,4HAA4H;IACjI,MAAM,EAAE,kEAAkE;IAC1E,SAAS,EAAE,kEAAkE;IAC7E,IAAI,EAAE,SAAS;IACf,EAAE,EAAE,OAAO;CACZ,CAAC"}
1
+ {"version":3,"file":"release.js","sourceRoot":"","sources":["../src/release.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,wFAAwF;AACxF,2FAA2F;AAC3F,wFAAwF;AACxF,iEAAiE;AAqBjE,MAAM,CAAC,MAAM,OAAO,GAAgB;IAClC,GAAG,EAAE,cAAc;IACnB,OAAO,EAAE,gBAAgB;IACzB,KAAK,EAAE,0CAA0C;IACjD,GAAG,EAAE,4HAA4H;IACjI,MAAM,EAAE,kEAAkE;IAC1E,SAAS,EAAE,kEAAkE;IAC7E,IAAI,EAAE,SAAS;IACf,EAAE,EAAE,OAAO;CACZ,CAAC;AAEF,iGAAiG;AACjG,MAAM,CAAC,MAAM,IAAI,GAAG,iCAAiC,CAAC;AAEtD;;;qFAGqF;AACrF,MAAM,CAAC,MAAM,eAAe,GAAG,0CAA0C,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clearcote",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Playwright drop-in for the Clearcote anti-fingerprint Chromium build. launch() returns a standard Playwright Browser backed by the verified Clearcote binary, which is auto-downloaded and SHA-256 checked.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",