sourcemonkey 0.0.0-stage → 0.5.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/LICENSE +21 -0
- package/README.md +87 -2
- package/dist/bytes.js +37 -0
- package/dist/channel-placeholder.js +5 -0
- package/dist/collection-scan.js +17 -0
- package/dist/collections.html +353 -0
- package/dist/compare.html +358 -0
- package/dist/composed-source.js +205 -0
- package/dist/connect-prompt.html +47 -0
- package/dist/debug/icons.html +211 -0
- package/dist/debug/storage.html +163 -0
- package/dist/debug-log.js +75 -0
- package/dist/diagnostic-location.js +64 -0
- package/dist/eval-hook.js +308 -0
- package/dist/extension/background.js +5263 -0
- package/dist/extension/channel.js +133 -0
- package/dist/extension/code-links.js +187 -0
- package/dist/extension/code-tabs.js +460 -0
- package/dist/extension/collection-dialog.js +619 -0
- package/dist/extension/collection-display.js +322 -0
- package/dist/extension/collections.js +2905 -0
- package/dist/extension/compare.js +867 -0
- package/dist/extension/concurrency.js +186 -0
- package/dist/extension/connect-grants.js +109 -0
- package/dist/extension/connect-prompt-page.js +70 -0
- package/dist/extension/connect-prompt.js +266 -0
- package/dist/extension/copy-button.js +63 -0
- package/dist/extension/copy-dialog.js +502 -0
- package/dist/extension/copy-preference.js +66 -0
- package/dist/extension/debug/icons.js +203 -0
- package/dist/extension/debug/storage.js +365 -0
- package/dist/extension/deep-link.js +77 -0
- package/dist/extension/delete-dialog.js +432 -0
- package/dist/extension/delete-icon.js +40 -0
- package/dist/extension/details-tooltips.js +66 -0
- package/dist/extension/directories.js +679 -0
- package/dist/extension/export-backup.js +407 -0
- package/dist/extension/export-dialog.js +142 -0
- package/dist/extension/file-access.js +74 -0
- package/dist/extension/file-changes.js +346 -0
- package/dist/extension/frame-info.js +85 -0
- package/dist/extension/github-provider.js +336 -0
- package/dist/extension/glyph.js +84 -0
- package/dist/extension/gm-bindings.js +601 -0
- package/dist/extension/gm-download.js +419 -0
- package/dist/extension/gm-menu.js +228 -0
- package/dist/extension/gm-notification.js +141 -0
- package/dist/extension/gm-originator-map.js +23 -0
- package/dist/extension/gm-tab-data.js +121 -0
- package/dist/extension/gm-tab.js +160 -0
- package/dist/extension/gm-url-change.js +111 -0
- package/dist/extension/gm-url-scheme.js +27 -0
- package/dist/extension/gm-values.js +176 -0
- package/dist/extension/gm-window-control.js +104 -0
- package/dist/extension/gm-xhr-headers.js +333 -0
- package/dist/extension/gm-xhr.js +584 -0
- package/dist/extension/injector.js +3145 -0
- package/dist/extension/install-capture.js +277 -0
- package/dist/extension/line-diff.js +233 -0
- package/dist/extension/local-copy.js +560 -0
- package/dist/extension/local-delete.js +276 -0
- package/dist/extension/location-kinds.js +108 -0
- package/dist/extension/log-format.js +158 -0
- package/dist/extension/managed-changes.js +361 -0
- package/dist/extension/managed-items.js +57 -0
- package/dist/extension/match-index.js +375 -0
- package/dist/extension/missing-scripts.js +66 -0
- package/dist/extension/more-menu.js +109 -0
- package/dist/extension/move-dialog.js +197 -0
- package/dist/extension/offscreen.js +37 -0
- package/dist/extension/options.js +504 -0
- package/dist/extension/page-heading.js +170 -0
- package/dist/extension/page-links.js +199 -0
- package/dist/extension/parse-check-client.js +70 -0
- package/dist/extension/parse-check.js +161 -0
- package/dist/extension/parse-sandbox-host.js +172 -0
- package/dist/extension/parse-sandbox.js +175 -0
- package/dist/extension/popup-commands-open.js +41 -0
- package/dist/extension/popup-view.js +387 -0
- package/dist/extension/popup.js +703 -0
- package/dist/extension/prism-userscript.js +53 -0
- package/dist/extension/refresh-error.js +136 -0
- package/dist/extension/refresh-targets.js +160 -0
- package/dist/extension/related-versions.js +1144 -0
- package/dist/extension/resize-observer-loop.js +19 -0
- package/dist/extension/row-cache.js +387 -0
- package/dist/extension/script-blobs.js +413 -0
- package/dist/extension/script-details.js +658 -0
- package/dist/extension/script-enablement.js +285 -0
- package/dist/extension/script-identity.js +310 -0
- package/dist/extension/script-keys.js +54 -0
- package/dist/extension/script-log-id.js +155 -0
- package/dist/extension/script-log.js +290 -0
- package/dist/extension/script-rejection.js +104 -0
- package/dist/extension/script-sites.js +158 -0
- package/dist/extension/script-store.js +3507 -0
- package/dist/extension/script-updater.js +991 -0
- package/dist/extension/script-url-hash.js +61 -0
- package/dist/extension/select-all.js +37 -0
- package/dist/extension/select-open-guard.js +90 -0
- package/dist/extension/site-icon.js +1261 -0
- package/dist/extension/sm-dev-link.js +302 -0
- package/dist/extension/solo-click.js +58 -0
- package/dist/extension/sticky-numbers.js +188 -0
- package/dist/extension/storage-breakdown.js +253 -0
- package/dist/extension/storage-scan.js +86 -0
- package/dist/extension/storage-usage.js +194 -0
- package/dist/extension/structural-keys.js +29 -0
- package/dist/extension/sw-teardown.js +36 -0
- package/dist/extension/tab-status.js +403 -0
- package/dist/extension/toolbar-summary.js +105 -0
- package/dist/extension/user-scripts-access.js +43 -0
- package/dist/extension/userscript.js +3672 -0
- package/dist/extension/value-store.js +204 -0
- package/dist/extension/version-probe-fetch.js +68 -0
- package/dist/extension/worker-client.js +109 -0
- package/dist/extension/worker-ops.js +171 -0
- package/dist/extension/zip-writer.js +24 -0
- package/dist/external-files.js +878 -0
- package/dist/file-loader.js +436 -0
- package/dist/file-locations.js +439 -0
- package/dist/generated-wrappers.js +5 -0
- package/dist/github-auth.js +148 -0
- package/dist/github-urls.js +46 -0
- package/dist/gm-api-catalog.js +217 -0
- package/dist/gm-connect.js +273 -0
- package/dist/gm-xhr-types.js +5 -0
- package/dist/http-read.js +142 -0
- package/dist/icons/icon-128.png +0 -0
- package/dist/icons/icon-16.png +0 -0
- package/dist/icons/icon-48.png +0 -0
- package/dist/local-file-overrides.js +558 -0
- package/dist/manifest.json +38 -0
- package/dist/markup-response.js +126 -0
- package/dist/match-targets.js +305 -0
- package/dist/menu-captions.js +22 -0
- package/dist/offscreen.html +39 -0
- package/dist/options.html +197 -0
- package/dist/parse-check-protocol.js +51 -0
- package/dist/parse-location.js +171 -0
- package/dist/parse-sandbox.html +56 -0
- package/dist/phase-timing.js +155 -0
- package/dist/popup.html +197 -0
- package/dist/public-suffixes.js +6957 -0
- package/dist/run-context.js +31 -0
- package/dist/runtime-messages.js +34 -0
- package/dist/sandboxed-page.js +35 -0
- package/dist/script-build.js +787 -0
- package/dist/script-display.js +383 -0
- package/dist/script-icon.js +43 -0
- package/dist/script-links.js +204 -0
- package/dist/script-source-url.js +214 -0
- package/dist/script-world.js +65 -0
- package/dist/sm-dev-protocol.js +84 -0
- package/dist/source-map.js +177 -0
- package/dist/stack-link.js +138 -0
- package/dist/styles.css +825 -0
- package/dist/unsafe-window-use.js +229 -0
- package/dist/url-match.js +734 -0
- package/dist/userscript-header.js +248 -0
- package/dist/userscript.html +1165 -0
- package/dist/vendor/fflate.LICENSE +21 -0
- package/dist/vendor/fflate.js +2692 -0
- package/dist/vendor/prism/prism-line-numbers.css +1 -0
- package/dist/vendor/prism/prism-line-numbers.js +1 -0
- package/dist/vendor/prism/prism.css +1 -0
- package/dist/vendor/prism/prism.js +1946 -0
- package/dist/version-compare.js +141 -0
- package/dist/version-probe.js +120 -0
- package/lib/build-info.json +1 -0
- package/lib/bytes.d.ts +3 -0
- package/lib/bytes.js +37 -0
- package/lib/channel-placeholder.d.ts +1 -0
- package/lib/channel-placeholder.js +5 -0
- package/lib/collection-scan.d.ts +8 -0
- package/lib/collection-scan.js +17 -0
- package/lib/composed-source.d.ts +28 -0
- package/lib/composed-source.js +205 -0
- package/lib/debug-log.d.ts +9 -0
- package/lib/debug-log.js +75 -0
- package/lib/diagnostic-location.d.ts +8 -0
- package/lib/diagnostic-location.js +64 -0
- package/lib/eval-hook.d.ts +34 -0
- package/lib/eval-hook.js +308 -0
- package/lib/external-files.d.ts +111 -0
- package/lib/external-files.js +878 -0
- package/lib/file-loader.d.ts +48 -0
- package/lib/file-loader.js +436 -0
- package/lib/file-locations.d.ts +44 -0
- package/lib/file-locations.js +439 -0
- package/lib/generated-wrappers.d.ts +11 -0
- package/lib/generated-wrappers.js +5 -0
- package/lib/github-auth.d.ts +12 -0
- package/lib/github-auth.js +148 -0
- package/lib/github-urls.d.ts +1 -0
- package/lib/github-urls.js +46 -0
- package/lib/gm-api-catalog.d.ts +24 -0
- package/lib/gm-api-catalog.js +217 -0
- package/lib/gm-connect.d.ts +34 -0
- package/lib/gm-connect.js +273 -0
- package/lib/gm-xhr-types.d.ts +68 -0
- package/lib/gm-xhr-types.js +5 -0
- package/lib/harness/browser-extensions.d.ts +73 -0
- package/lib/harness/browser-extensions.js +285 -0
- package/lib/harness/browser-lang.d.ts +20 -0
- package/lib/harness/browser-lang.js +86 -0
- package/lib/harness/browser-launch.d.ts +14 -0
- package/lib/harness/browser-launch.js +184 -0
- package/lib/harness/checks.d.ts +110 -0
- package/lib/harness/checks.js +321 -0
- package/lib/harness/cli.d.ts +2 -0
- package/lib/harness/cli.js +2259 -0
- package/lib/harness/command-args.d.ts +91 -0
- package/lib/harness/command-args.js +369 -0
- package/lib/harness/command-lines.d.ts +80 -0
- package/lib/harness/command-lines.js +180 -0
- package/lib/harness/command-list.d.ts +206 -0
- package/lib/harness/command-list.js +1475 -0
- package/lib/harness/console-commands.d.ts +463 -0
- package/lib/harness/console-commands.js +3216 -0
- package/lib/harness/download-watch.d.ts +21 -0
- package/lib/harness/download-watch.js +156 -0
- package/lib/harness/extension-backend.d.ts +41 -0
- package/lib/harness/extension-backend.js +100 -0
- package/lib/harness/extension-host.d.ts +112 -0
- package/lib/harness/extension-host.js +552 -0
- package/lib/harness/extension-launch.d.ts +67 -0
- package/lib/harness/extension-launch.js +285 -0
- package/lib/harness/extension-link.d.ts +315 -0
- package/lib/harness/extension-link.js +607 -0
- package/lib/harness/external-manager.d.ts +146 -0
- package/lib/harness/external-manager.js +414 -0
- package/lib/harness/fixture.d.ts +165 -0
- package/lib/harness/fixture.js +461 -0
- package/lib/harness/frame-sessions.d.ts +71 -0
- package/lib/harness/frame-sessions.js +248 -0
- package/lib/harness/frames.d.ts +68 -0
- package/lib/harness/frames.js +216 -0
- package/lib/harness/help-format.d.ts +17 -0
- package/lib/harness/help-format.js +127 -0
- package/lib/harness/host.d.ts +352 -0
- package/lib/harness/host.js +423 -0
- package/lib/harness/index.d.ts +8 -0
- package/lib/harness/index.js +10 -0
- package/lib/harness/input-file.d.ts +18 -0
- package/lib/harness/input-file.js +61 -0
- package/lib/harness/json-output.d.ts +565 -0
- package/lib/harness/json-output.js +71 -0
- package/lib/harness/manager-actions.d.ts +21 -0
- package/lib/harness/manager-actions.js +129 -0
- package/lib/harness/manager-commands.d.ts +142 -0
- package/lib/harness/manager-commands.js +1196 -0
- package/lib/harness/manager-fetch.d.ts +33 -0
- package/lib/harness/manager-fetch.js +239 -0
- package/lib/harness/managers.d.ts +24 -0
- package/lib/harness/managers.js +27 -0
- package/lib/harness/output-style.d.ts +125 -0
- package/lib/harness/output-style.js +322 -0
- package/lib/harness/page-commands.d.ts +134 -0
- package/lib/harness/page-commands.js +1141 -0
- package/lib/harness/page-output.d.ts +67 -0
- package/lib/harness/page-output.js +139 -0
- package/lib/harness/page-watch.d.ts +171 -0
- package/lib/harness/page-watch.js +607 -0
- package/lib/harness/parse-check-node.d.ts +3 -0
- package/lib/harness/parse-check-node.js +132 -0
- package/lib/harness/path-args.d.ts +22 -0
- package/lib/harness/path-args.js +148 -0
- package/lib/harness/playwright-chromium.d.ts +16 -0
- package/lib/harness/playwright-chromium.js +86 -0
- package/lib/harness/prepare.d.ts +168 -0
- package/lib/harness/prepare.js +364 -0
- package/lib/harness/prompt-editor.d.ts +17 -0
- package/lib/harness/prompt-editor.js +354 -0
- package/lib/harness/prompt-history.d.ts +13 -0
- package/lib/harness/prompt-history.js +89 -0
- package/lib/harness/rebuild-advice.d.ts +6 -0
- package/lib/harness/rebuild-advice.js +39 -0
- package/lib/harness/run-log.d.ts +47 -0
- package/lib/harness/run-log.js +140 -0
- package/lib/harness/run-logs.d.ts +132 -0
- package/lib/harness/run-logs.js +241 -0
- package/lib/harness/run.d.ts +194 -0
- package/lib/harness/run.js +1973 -0
- package/lib/harness/runs.d.ts +229 -0
- package/lib/harness/runs.js +726 -0
- package/lib/harness/save-html.d.ts +39 -0
- package/lib/harness/save-html.js +89 -0
- package/lib/harness/saved-pages.d.ts +120 -0
- package/lib/harness/saved-pages.js +275 -0
- package/lib/harness/script-mark.d.ts +17 -0
- package/lib/harness/script-mark.js +56 -0
- package/lib/harness/snapshot.d.ts +143 -0
- package/lib/harness/snapshot.js +474 -0
- package/lib/harness/stuck-tabs.d.ts +19 -0
- package/lib/harness/stuck-tabs.js +131 -0
- package/lib/harness/tab-refs.d.ts +20 -0
- package/lib/harness/tab-refs.js +80 -0
- package/lib/harness/tampermonkey.d.ts +71 -0
- package/lib/harness/tampermonkey.js +356 -0
- package/lib/harness/tm-ids.d.ts +18 -0
- package/lib/harness/tm-ids.js +88 -0
- package/lib/harness/violentmonkey.d.ts +34 -0
- package/lib/harness/violentmonkey.js +162 -0
- package/lib/harness/wait.d.ts +77 -0
- package/lib/harness/wait.js +458 -0
- package/lib/http-read.d.ts +30 -0
- package/lib/http-read.js +142 -0
- package/lib/local-file-overrides.d.ts +35 -0
- package/lib/local-file-overrides.js +558 -0
- package/lib/manifest.json +38 -0
- package/lib/markup-response.d.ts +11 -0
- package/lib/markup-response.js +126 -0
- package/lib/match-targets.d.ts +18 -0
- package/lib/match-targets.js +305 -0
- package/lib/menu-captions.d.ts +1 -0
- package/lib/menu-captions.js +22 -0
- package/lib/parse-check-protocol.d.ts +27 -0
- package/lib/parse-check-protocol.js +51 -0
- package/lib/parse-location.d.ts +12 -0
- package/lib/parse-location.js +171 -0
- package/lib/phase-timing.d.ts +12 -0
- package/lib/phase-timing.js +155 -0
- package/lib/public-suffixes.d.ts +1 -0
- package/lib/public-suffixes.js +6957 -0
- package/lib/run-context.d.ts +2 -0
- package/lib/run-context.js +31 -0
- package/lib/runtime-messages.d.ts +10 -0
- package/lib/runtime-messages.js +34 -0
- package/lib/sandboxed-page.d.ts +5 -0
- package/lib/sandboxed-page.js +35 -0
- package/lib/script-build.d.ts +111 -0
- package/lib/script-build.js +787 -0
- package/lib/script-display.d.ts +51 -0
- package/lib/script-display.js +383 -0
- package/lib/script-icon.d.ts +16 -0
- package/lib/script-icon.js +43 -0
- package/lib/script-links.d.ts +24 -0
- package/lib/script-links.js +204 -0
- package/lib/script-source-url.d.ts +8 -0
- package/lib/script-source-url.js +214 -0
- package/lib/script-world.d.ts +6 -0
- package/lib/script-world.js +65 -0
- package/lib/sm-dev-protocol.d.ts +251 -0
- package/lib/sm-dev-protocol.js +84 -0
- package/lib/source-map.d.ts +32 -0
- package/lib/source-map.js +177 -0
- package/lib/stack-link.d.ts +15 -0
- package/lib/stack-link.js +138 -0
- package/lib/unsafe-window-use.d.ts +1 -0
- package/lib/unsafe-window-use.js +229 -0
- package/lib/url-match.d.ts +40 -0
- package/lib/url-match.js +734 -0
- package/lib/userscript-header.d.ts +33 -0
- package/lib/userscript-header.js +248 -0
- package/lib/version-compare.d.ts +6 -0
- package/lib/version-compare.js +141 -0
- package/lib/version-probe.d.ts +17 -0
- package/lib/version-probe.js +120 -0
- package/package.json +55 -3
- package/skills/SourceMonkey-dev/SKILL.md +868 -0
- package/skills/SourceMonkey-dev/references/cdp.md +293 -0
- package/skills/SourceMonkey-dev/references/commands.md +297 -0
- package/skills/SourceMonkey-dev/references/other-managers.md +63 -0
- package/skills/SourceMonkey-dev/references/specs.md +46 -0
- package/skills/SourceMonkey-friction/SKILL.md +103 -0
- package/skills/SourceMonkey-friction/references/template.md +59 -0
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
// Telling locations apart (http, file, container and collection
|
|
2
|
+
// paths), path helpers, reading a `file://` URL, and Chrome's `file://`
|
|
3
|
+
// directory listings.
|
|
4
|
+
//
|
|
5
|
+
// The part of directories.ts that loading a script's local files
|
|
6
|
+
// needs, in its own module so the development harness can use it
|
|
7
|
+
// without the collection scanners and GitHub provider. directories.ts
|
|
8
|
+
// re-exports it for its other callers.
|
|
9
|
+
import { MANIFEST_FILENAME } from './collection-scan.js';
|
|
10
|
+
// ---------- Collection-kind detection ----------
|
|
11
|
+
// All collection-kind checks key off the raw input string the user
|
|
12
|
+
// typed. `http://` / `https://` selects an HTTP collection; everything
|
|
13
|
+
// else is treated as an absolute filesystem path. Suffix tests look at
|
|
14
|
+
// the URL pathname (sans query/fragment) so e.g. `…/foo.user.js?v=2`
|
|
15
|
+
// still classifies as a single-file URL.
|
|
16
|
+
// The shapes a user may type as a location, as a sentence fragment.
|
|
17
|
+
// Shared because two validators reject on it — `isValidLocationShape`
|
|
18
|
+
// (directories.ts) and the viewer's preview (`isPreviewableInput`) — and their
|
|
19
|
+
// messages had already drifted into two different descriptions of one
|
|
20
|
+
// rule.
|
|
21
|
+
export const LOCATION_SHAPES = 'must be a URL or absolute file path';
|
|
22
|
+
export function isHttpUrl(input) {
|
|
23
|
+
return /^https?:\/\//i.test(input);
|
|
24
|
+
}
|
|
25
|
+
export function isFileUrl(input) {
|
|
26
|
+
return /^file:\/\//i.test(input);
|
|
27
|
+
}
|
|
28
|
+
const CONTAINER_PATH_PREFIX = 'container:';
|
|
29
|
+
// The fixed path of the built-in default container for a scheme.
|
|
30
|
+
export function containerPath(kind) {
|
|
31
|
+
return CONTAINER_PATH_PREFIX + kind;
|
|
32
|
+
}
|
|
33
|
+
// A fresh path for a user-created container.
|
|
34
|
+
export function newContainerPath() {
|
|
35
|
+
return CONTAINER_PATH_PREFIX + crypto.randomUUID();
|
|
36
|
+
}
|
|
37
|
+
// A collection that is a local folder scanned for `*.user.js` files —
|
|
38
|
+
// the kind whose listing is its source of truth, so a file it no
|
|
39
|
+
// longer shows is dropped (see `rebuildCollection`). Everything else
|
|
40
|
+
// (http(s) and GitHub, a manifest, a single-file container) names its
|
|
41
|
+
// scripts some other way.
|
|
42
|
+
export function isLocalDirectoryCollection(collectionPath) {
|
|
43
|
+
return !isHttpUrl(collectionPath)
|
|
44
|
+
&& !isManifestCollection(collectionPath)
|
|
45
|
+
&& !isContainerCollection(collectionPath);
|
|
46
|
+
}
|
|
47
|
+
export function isContainerCollection(input) {
|
|
48
|
+
return input.startsWith(CONTAINER_PATH_PREFIX);
|
|
49
|
+
}
|
|
50
|
+
// Which scheme this container is the built-in default for — or null
|
|
51
|
+
// for a user-created container (and for anything that isn't a
|
|
52
|
+
// container). NOT a restriction on what the container may hold.
|
|
53
|
+
export function containerKind(input) {
|
|
54
|
+
if (input === 'container:file')
|
|
55
|
+
return 'file';
|
|
56
|
+
if (input === 'container:http')
|
|
57
|
+
return 'http';
|
|
58
|
+
if (input === 'container:github')
|
|
59
|
+
return 'github';
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
export function collectionKind(path) {
|
|
63
|
+
if (isContainerCollection(path))
|
|
64
|
+
return 'scripts';
|
|
65
|
+
if (isManifestCollection(path))
|
|
66
|
+
return 'manifest';
|
|
67
|
+
return 'directory';
|
|
68
|
+
}
|
|
69
|
+
// Pathname of an http(s) or file:// URL, sans query and fragment.
|
|
70
|
+
// Returns '' if the string doesn't parse as a URL — callers gate on
|
|
71
|
+
// isHttpUrl / isFileUrl first.
|
|
72
|
+
export function urlPathname(input) {
|
|
73
|
+
try {
|
|
74
|
+
return new URL(input).pathname;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return '';
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Pathname for *any* collection-input form (raw filesystem path,
|
|
81
|
+
// file:// URL, or http(s):// URL). Used by suffix tests that don't care
|
|
82
|
+
// about scheme.
|
|
83
|
+
function locationPathname(input) {
|
|
84
|
+
if (isHttpUrl(input) || isFileUrl(input))
|
|
85
|
+
return urlPathname(input);
|
|
86
|
+
return input;
|
|
87
|
+
}
|
|
88
|
+
// Canonical URL form for a collection input. Raw filesystem paths get
|
|
89
|
+
// percent-encoded and wrapped as file://; URLs pass through. Used as
|
|
90
|
+
// the base for URL.resolution of manifest entries so a local manifest
|
|
91
|
+
// can list relative paths the same way an HTTP one can.
|
|
92
|
+
export function collectionCanonicalUrl(input) {
|
|
93
|
+
if (isHttpUrl(input) || isFileUrl(input))
|
|
94
|
+
return input;
|
|
95
|
+
return pathToFileUrl(input);
|
|
96
|
+
}
|
|
97
|
+
// Inverse of collectionCanonicalUrl for local inputs: a file:// URL
|
|
98
|
+
// turns into the absolute filesystem path it points at; a raw path
|
|
99
|
+
// passes through. Lets the local directory/single-file branches accept
|
|
100
|
+
// the URL form the user typed without each branch having to
|
|
101
|
+
// special-case the parse. Percent-encoded segments (e.g.
|
|
102
|
+
// `my%20scripts`) are decoded so downstream path helpers see the
|
|
103
|
+
// on-disk name verbatim.
|
|
104
|
+
export function locationFsPath(input) {
|
|
105
|
+
if (!isFileUrl(input))
|
|
106
|
+
return input;
|
|
107
|
+
try {
|
|
108
|
+
return decodeURIComponent(new URL(input).pathname);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return input; // unparseable URL → let the caller's I/O fail with a clearer message
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Windows drive-letter (`file:///C:/…`) and UNC (`file://server/…`)
|
|
115
|
+
// URLs. `locationFsPath` mangles both — it strips only the leading POSIX
|
|
116
|
+
// slash and discards `host` — so the canonicalizer below leaves them
|
|
117
|
+
// as URLs rather than producing a path that points somewhere else.
|
|
118
|
+
// The rest of the module is POSIX-only by design (see `pathToFileUrl`,
|
|
119
|
+
// `parentDir`), so this is containment, not Windows support.
|
|
120
|
+
// Exported because the collections page's `?refresh_file=` validator
|
|
121
|
+
// has to refuse the same two shapes before comparing paths — a mangled
|
|
122
|
+
// path there would silently match the wrong local collection.
|
|
123
|
+
export function isNonPosixFileUrl(input) {
|
|
124
|
+
let u;
|
|
125
|
+
try {
|
|
126
|
+
u = new URL(input);
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
return u.host !== '' || /^\/[A-Za-z]:/.test(u.pathname);
|
|
132
|
+
}
|
|
133
|
+
// One canonical spelling for a collection input, so every entry point
|
|
134
|
+
// agrees on what a given file is called: the collections page's path
|
|
135
|
+
// field, an `addCollection` call, and a captured `file://` navigation
|
|
136
|
+
// all have to produce the same `relativePath`, or one file on disk ends
|
|
137
|
+
// up with two installed rows.
|
|
138
|
+
//
|
|
139
|
+
// The bare filesystem path is the winner because it is what the path
|
|
140
|
+
// field (the oldest and most common route) has always stored. http(s)
|
|
141
|
+
// inputs pass through untouched — there is only one spelling of those.
|
|
142
|
+
export function canonicalCollectionInput(input) {
|
|
143
|
+
if (!isFileUrl(input) || isNonPosixFileUrl(input))
|
|
144
|
+
return input;
|
|
145
|
+
return locationFsPath(input);
|
|
146
|
+
}
|
|
147
|
+
// True for any input pointing at an individual `.user.js` script —
|
|
148
|
+
// http(s):// URL, file:// URL, or absolute local path — based on the
|
|
149
|
+
// pathname suffix. Single-script inputs don't get their own collection
|
|
150
|
+
// row; the install flow puts them into a container collection (by
|
|
151
|
+
// default the one for their scheme — see `containerKindForSingleFileInput`).
|
|
152
|
+
export function isSingleFileInput(input) {
|
|
153
|
+
return locationPathname(input).endsWith('.user.js');
|
|
154
|
+
}
|
|
155
|
+
// True for any manifest collection — http(s):// URL, file:// URL, or an
|
|
156
|
+
// absolute local path — whose pathname's basename is exactly
|
|
157
|
+
// `MANIFEST_FILENAME`. The fixed-filename rule (rather than a generic
|
|
158
|
+
// `.json` suffix) keeps unrelated JSON files from being mistaken for
|
|
159
|
+
// script manifests and gives the convention a single, searchable name.
|
|
160
|
+
export function isManifestCollection(input) {
|
|
161
|
+
const p = locationPathname(input);
|
|
162
|
+
return p === MANIFEST_FILENAME
|
|
163
|
+
|| p.endsWith('/' + MANIFEST_FILENAME);
|
|
164
|
+
}
|
|
165
|
+
// ---------- URL / path helpers ----------
|
|
166
|
+
// Build a file:// URL from an absolute filesystem path, percent-encoding
|
|
167
|
+
// each segment so spaces and other reserved characters produce a valid
|
|
168
|
+
// URL. POSIX paths get the conventional `file://` + leading slash.
|
|
169
|
+
export function pathToFileUrl(absolutePath) {
|
|
170
|
+
const trimmed = absolutePath.replace(/\/+$/, '');
|
|
171
|
+
const encoded = trimmed.split('/').map(encodeURIComponent).join('/');
|
|
172
|
+
return encoded.startsWith('/') ? `file://${encoded}` : `file:///${encoded}`;
|
|
173
|
+
}
|
|
174
|
+
export function joinPath(base, child) {
|
|
175
|
+
return base.replace(/\/+$/, '') + '/' + child;
|
|
176
|
+
}
|
|
177
|
+
// Return the parent directory of an absolute POSIX path. The result
|
|
178
|
+
// has no trailing slash; for a top-level path like `/foo` returns `/`.
|
|
179
|
+
export function parentDir(absolutePath) {
|
|
180
|
+
const trimmed = absolutePath.replace(/\/+$/, '');
|
|
181
|
+
const slash = trimmed.lastIndexOf('/');
|
|
182
|
+
if (slash < 0)
|
|
183
|
+
return '';
|
|
184
|
+
if (slash === 0)
|
|
185
|
+
return '/';
|
|
186
|
+
return trimmed.slice(0, slash);
|
|
187
|
+
}
|
|
188
|
+
// Return the leaf name of an absolute POSIX path (the part after the
|
|
189
|
+
// last `/`). Trailing slashes are stripped first.
|
|
190
|
+
export function baseName(absolutePath) {
|
|
191
|
+
const trimmed = absolutePath.replace(/\/+$/, '');
|
|
192
|
+
const slash = trimmed.lastIndexOf('/');
|
|
193
|
+
return slash < 0 ? trimmed : trimmed.slice(slash + 1);
|
|
194
|
+
}
|
|
195
|
+
// ---------- Reading a file:// URL ----------
|
|
196
|
+
// A `file://` URL's text.
|
|
197
|
+
//
|
|
198
|
+
// Why XMLHttpRequest in page contexts: fetch() treats
|
|
199
|
+
// chrome-extension:// → file:// as cross-origin and returns an opaque
|
|
200
|
+
// response (status 0, unreadable body). XHR doesn't apply that
|
|
201
|
+
// restriction. For file:// XHRs, `status` stays 0 even on success
|
|
202
|
+
// (there's no HTTP layer); a missing file fires `onerror`, while a
|
|
203
|
+
// readable file (including a 0-byte one) fires `onload`.
|
|
204
|
+
//
|
|
205
|
+
// Service-worker fallback: MV3 service workers have no XMLHttpRequest
|
|
206
|
+
// at all, so we can't use the XHR path there. fetch() does work from a
|
|
207
|
+
// SW for `file://` URLs as long as the manifest grants `file:///*` in
|
|
208
|
+
// host_permissions (and the user has flipped "Allow access to file
|
|
209
|
+
// URLs") — the cross-origin restriction above is a document-context
|
|
210
|
+
// behavior, not a SW one. Node (the harness) takes this path too. We
|
|
211
|
+
// pick the path at call time by checking for XHR availability.
|
|
212
|
+
export function readFileUrlText(url) {
|
|
213
|
+
if (typeof XMLHttpRequest !== 'undefined')
|
|
214
|
+
return fetchFileUrlTextXhr(url);
|
|
215
|
+
return fetchFileUrlTextFetch(url);
|
|
216
|
+
}
|
|
217
|
+
// `readFileUrlText`, plus what a listing of the file's folder would
|
|
218
|
+
// report for it: its size in bytes and its modified time. One read
|
|
219
|
+
// instead of a listing and a read, for a check that knows the file's
|
|
220
|
+
// path. `fsMtime` is absent when Chrome sent no `Last-Modified`.
|
|
221
|
+
export async function readFileUrlWithStat(url) {
|
|
222
|
+
const { bytes, lastModified } = typeof XMLHttpRequest !== 'undefined'
|
|
223
|
+
? await fetchFileUrlBytesXhr(url)
|
|
224
|
+
: await fetchFileUrlBytesFetch(url);
|
|
225
|
+
// Decoded as the worker's `response.text()` does: UTF-8, a UTF-8 BOM
|
|
226
|
+
// dropped, bad bytes replaced rather than thrown on. (A page's
|
|
227
|
+
// `responseText` would also detect a UTF-16 BOM; nothing here reads
|
|
228
|
+
// one, and no page calls this today.)
|
|
229
|
+
const text = new TextDecoder().decode(bytes);
|
|
230
|
+
const fsMtime = fsMtimeFromLastModified(lastModified);
|
|
231
|
+
return { text, size: bytes.byteLength, ...(fsMtime !== undefined ? { fsMtime } : {}) };
|
|
232
|
+
}
|
|
233
|
+
// Chrome gives a `file://` response the file's modified time as
|
|
234
|
+
// `Last-Modified`. Its directory listing reports the same time in whole
|
|
235
|
+
// seconds, which `Last-Modified` can't be finer than, so dividing gives
|
|
236
|
+
// the listing's number exactly. That lets a direct read stand in for
|
|
237
|
+
// listing the folder.
|
|
238
|
+
export function fsMtimeFromLastModified(header) {
|
|
239
|
+
if (!header)
|
|
240
|
+
return undefined;
|
|
241
|
+
const ms = Date.parse(header);
|
|
242
|
+
return Number.isFinite(ms) ? Math.floor(ms / 1000) : undefined;
|
|
243
|
+
}
|
|
244
|
+
function fetchFileUrlBytesXhr(url) {
|
|
245
|
+
return new Promise((resolve, reject) => {
|
|
246
|
+
const xhr = new XMLHttpRequest();
|
|
247
|
+
xhr.open('GET', url);
|
|
248
|
+
xhr.responseType = 'arraybuffer';
|
|
249
|
+
xhr.onload = () => resolve({
|
|
250
|
+
bytes: xhr.response ?? new ArrayBuffer(0),
|
|
251
|
+
lastModified: xhr.getResponseHeader('last-modified'),
|
|
252
|
+
});
|
|
253
|
+
xhr.onerror = () => reject(new Error(`Could not read ${url}`));
|
|
254
|
+
xhr.send();
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
async function fetchFileUrlBytesFetch(url) {
|
|
258
|
+
const response = await fetchFileUrlResponse(url);
|
|
259
|
+
return { bytes: await response.arrayBuffer(), lastModified: response.headers.get('last-modified') };
|
|
260
|
+
}
|
|
261
|
+
function fetchFileUrlTextXhr(url) {
|
|
262
|
+
return new Promise((resolve, reject) => {
|
|
263
|
+
const xhr = new XMLHttpRequest();
|
|
264
|
+
xhr.open('GET', url);
|
|
265
|
+
xhr.responseType = 'text';
|
|
266
|
+
// For file:// XHRs status is always 0. A readable file (including
|
|
267
|
+
// a 0-byte one) fires `onload`; a missing file fires `onerror`.
|
|
268
|
+
// Resolve with whatever responseText we got — '' is a valid result
|
|
269
|
+
// for an empty file and must not be conflated with "missing".
|
|
270
|
+
xhr.onload = () => resolve(xhr.responseText ?? '');
|
|
271
|
+
xhr.onerror = () => reject(new Error(`Could not read ${url}`));
|
|
272
|
+
xhr.send();
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
// Service-worker path: fetch() works for file:// URLs when the SW has
|
|
276
|
+
// the matching host permission. `response.ok` is true for file://
|
|
277
|
+
// fetches that succeed (Chrome synthesises status 200); a 404-style
|
|
278
|
+
// missing file shows up as a fetch rejection or response.ok === false,
|
|
279
|
+
// not a thrown exception with a specific status code, so we have to
|
|
280
|
+
// inspect both.
|
|
281
|
+
async function fetchFileUrlTextFetch(url) {
|
|
282
|
+
// An empty body here is a 0-byte file, not an error — keep it
|
|
283
|
+
// distinct from "missing" so the row renders Size=0 Status=ERROR
|
|
284
|
+
// (no metadata block) rather than getting flagged as gone.
|
|
285
|
+
return await (await fetchFileUrlResponse(url)).text();
|
|
286
|
+
}
|
|
287
|
+
// The worker's `file://` response, once it is known to have read. Shared
|
|
288
|
+
// by the text and byte readers, so a failure reads the same from both.
|
|
289
|
+
async function fetchFileUrlResponse(url) {
|
|
290
|
+
let response;
|
|
291
|
+
try {
|
|
292
|
+
response = await fetch(url);
|
|
293
|
+
}
|
|
294
|
+
catch (err) {
|
|
295
|
+
throw new Error(`Could not read ${url}: ${err instanceof Error ? err.message : String(err)}`);
|
|
296
|
+
}
|
|
297
|
+
if (!response.ok && response.status !== 0) {
|
|
298
|
+
throw new Error(`Could not read ${url}: HTTP ${response.status}`);
|
|
299
|
+
}
|
|
300
|
+
// Opaque responses (response.type === 'opaque') have an unreadable
|
|
301
|
+
// body; surface a distinct error rather than returning empty content,
|
|
302
|
+
// so a manual refresh from a page context can succeed where the SW
|
|
303
|
+
// path fell through.
|
|
304
|
+
if (response.type === 'opaque') {
|
|
305
|
+
throw new Error(`Could not read ${url} in background refresh (file:// fetch is not permitted there). ` +
|
|
306
|
+
`Try Refresh from the script page.`);
|
|
307
|
+
}
|
|
308
|
+
return response;
|
|
309
|
+
}
|
|
310
|
+
// Chrome's file:// directory listing is an HTML page that injects
|
|
311
|
+
// entries via JavaScript calls like:
|
|
312
|
+
// addRow("name", "url", isdir, size, "size_str", date, "date_str")
|
|
313
|
+
// where `isdir` is 0/1 (older Chrome) or true/false. We pull:
|
|
314
|
+
// - the name (first arg) and the isdir flag (third) to classify;
|
|
315
|
+
// - the numeric size (fourth) and date (sixth) so the refresh
|
|
316
|
+
// pipeline can skip refetching files whose size+mtime are
|
|
317
|
+
// unchanged.
|
|
318
|
+
//
|
|
319
|
+
// This is intentionally tolerant: Chrome's exact listing format isn't
|
|
320
|
+
// a stable contract, so the regex matches the common shape and ignores
|
|
321
|
+
// any addRow calls it can't parse. The size/mtime captures are
|
|
322
|
+
// optional — entries without them parse but with size/mtime undefined,
|
|
323
|
+
// at which point the refresh pipeline falls back to always-refetch
|
|
324
|
+
// for those files.
|
|
325
|
+
//
|
|
326
|
+
// An empty result is ambiguous on its own — a listing with no rows, or
|
|
327
|
+
// a page that isn't a listing at all — which is why `listDirectory`
|
|
328
|
+
// checks `isDirectoryListing` first.
|
|
329
|
+
export function parseListing(html) {
|
|
330
|
+
const entries = [];
|
|
331
|
+
const re = /addRow\("((?:\\.|[^"\\])*)"\s*,\s*"(?:\\.|[^"\\])*"\s*,\s*(0|1|true|false)\b(?:\s*,\s*(-?\d+))?(?:\s*,\s*"(?:\\.|[^"\\])*")?(?:\s*,\s*(-?\d+))?/g;
|
|
332
|
+
let m;
|
|
333
|
+
while ((m = re.exec(html)) !== null) {
|
|
334
|
+
let name;
|
|
335
|
+
try {
|
|
336
|
+
// The captured first argument is a JS string literal body —
|
|
337
|
+
// JSON.parse round-trips the standard \" \\ \n \uXXXX escapes.
|
|
338
|
+
name = JSON.parse('"' + m[1] + '"');
|
|
339
|
+
}
|
|
340
|
+
catch {
|
|
341
|
+
continue;
|
|
342
|
+
}
|
|
343
|
+
if (name === '..' || name === '.')
|
|
344
|
+
continue;
|
|
345
|
+
const isDir = m[2] === '1' || m[2] === 'true';
|
|
346
|
+
const entry = { name, isDir };
|
|
347
|
+
if (m[3] !== undefined)
|
|
348
|
+
entry.size = Number(m[3]);
|
|
349
|
+
if (m[4] !== undefined)
|
|
350
|
+
entry.mtime = Number(m[4]);
|
|
351
|
+
entries.push(entry);
|
|
352
|
+
}
|
|
353
|
+
return entries;
|
|
354
|
+
}
|
|
355
|
+
// How many directory listings this JS context has fetched SUCCESSFULLY
|
|
356
|
+
// since the last reset. Scoped and counted narrowly on purpose:
|
|
357
|
+
//
|
|
358
|
+
// - Per-context, not global. This module is imported by the
|
|
359
|
+
// extension pages too, and a check that runs in the page that
|
|
360
|
+
// clicked never touches the worker's copy of this number.
|
|
361
|
+
// - Every listing the context does, not just batched ones — the
|
|
362
|
+
// recursive `scanForUserScripts` walk and collection refreshes land
|
|
363
|
+
// here too, so a test has to reset around the window it cares about.
|
|
364
|
+
// - Cache hits don't count, which is the point: it is the number a
|
|
365
|
+
// test asserts on to show a batch shared one listing rather than
|
|
366
|
+
// doing N.
|
|
367
|
+
//
|
|
368
|
+
// Exposed through the SW test surface (see src/extension/background.ts).
|
|
369
|
+
let listingFetches = 0;
|
|
370
|
+
export function getDirectoryListingFetches() {
|
|
371
|
+
return listingFetches;
|
|
372
|
+
}
|
|
373
|
+
export function resetDirectoryListingFetches() {
|
|
374
|
+
listingFetches = 0;
|
|
375
|
+
}
|
|
376
|
+
// Is this page Chrome's directory listing at all? The listing page
|
|
377
|
+
// opens with a `start("<path>")` call before any rows, and an empty
|
|
378
|
+
// directory still has that. Anything without it — an error page, a
|
|
379
|
+
// path that is now a file, a format Chrome changed under us — is
|
|
380
|
+
// refused rather than read as "no entries", because those two answers
|
|
381
|
+
// have opposite consequences for a refresh: an empty listing drops
|
|
382
|
+
// every script in the collection, a failed one leaves them all alone.
|
|
383
|
+
export function isDirectoryListing(html) {
|
|
384
|
+
return /\bstart\s*\(\s*"/.test(html);
|
|
385
|
+
}
|
|
386
|
+
export const NOT_A_DIRECTORY_LISTING = 'Chrome did not return a directory listing for this folder';
|
|
387
|
+
export async function listDirectory(absolutePath, cache) {
|
|
388
|
+
const hit = cache?.get(absolutePath);
|
|
389
|
+
if (hit)
|
|
390
|
+
return hit;
|
|
391
|
+
const pending = (async () => {
|
|
392
|
+
// Chrome only serves the directory listing for URLs ending with `/`.
|
|
393
|
+
const url = pathToFileUrl(absolutePath) + '/';
|
|
394
|
+
const html = await readFileUrlText(url);
|
|
395
|
+
if (!isDirectoryListing(html)) {
|
|
396
|
+
throw new Error(`Could not read ${url}: ${NOT_A_DIRECTORY_LISTING}`);
|
|
397
|
+
}
|
|
398
|
+
const entries = parseListing(html);
|
|
399
|
+
// Counted after the fetch resolves, so the number means what its
|
|
400
|
+
// name says. A throw leaves it alone.
|
|
401
|
+
listingFetches += 1;
|
|
402
|
+
return entries;
|
|
403
|
+
})();
|
|
404
|
+
if (cache) {
|
|
405
|
+
cache.set(absolutePath, pending);
|
|
406
|
+
// A failed listing must not be remembered. Otherwise one transient
|
|
407
|
+
// read error is inherited by every later sibling in the batch, none
|
|
408
|
+
// of which ever retries — turning a single script's bad luck into
|
|
409
|
+
// the whole page refetching bodies it didn't need to. (Safe either
|
|
410
|
+
// way: `refreshScript` catches, leaving the scan bare, which means
|
|
411
|
+
// always-fetch. The cost is wasted reads, never a missed change.)
|
|
412
|
+
// The identity check keeps a late rejection from evicting a newer
|
|
413
|
+
// entry that has already replaced it.
|
|
414
|
+
void pending.catch(() => {
|
|
415
|
+
if (cache.get(absolutePath) === pending)
|
|
416
|
+
cache.delete(absolutePath);
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
return pending;
|
|
420
|
+
}
|
|
421
|
+
// Whether `cache` already holds a listing for this directory — i.e.
|
|
422
|
+
// whether the next `statFromListing` will pay for a fetch. Read by the
|
|
423
|
+
// refresh path's phase timer so a shared listing shows up as a shared
|
|
424
|
+
// listing rather than as a phase that mysteriously got fast.
|
|
425
|
+
export function hasCachedListing(cache, absoluteDir) {
|
|
426
|
+
return cache?.has(absoluteDir) ?? false;
|
|
427
|
+
}
|
|
428
|
+
// Targeted version of listDirectory: list a single directory and return
|
|
429
|
+
// just the entry for `fileName` (or null if absent). Used by the
|
|
430
|
+
// single-file refresh path so it can capture the file's current
|
|
431
|
+
// size/mtime without doing a full recursive scan — keeps the
|
|
432
|
+
// unchanged-file skip honest for the next Refresh All.
|
|
433
|
+
//
|
|
434
|
+
// `cache` is optional and batch-scoped: a navigation's fan-out passes
|
|
435
|
+
// one so N scripts in the same folder list it once between them.
|
|
436
|
+
export async function statFromListing(absoluteDir, fileName, cache) {
|
|
437
|
+
const entries = await listDirectory(absoluteDir, cache);
|
|
438
|
+
return entries.find((e) => e.name === fileName) ?? null;
|
|
439
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/* Generated by scripts/build.mjs. Do not edit. */
|
|
2
|
+
|
|
3
|
+
export const WRAPPER_PRELUDE = "(function(){\"use strict\";if(typeof self===\"undefined\")return;var e=\"__SM_KEY__\";var n=function(e){var n=document.__smGate;if(typeof n!==\"function\"){var t=Object.create(null),r=Object.create,i=Reflect.apply,a=Promise;var o=console.info.bind(console);var rs=function(e){return new a(function(n){n(e)})};var rj=function(e){return new a(function(n,t){t(e)})};n=function(e){if(typeof e!==\"string\")return void 0;var n=t[e];if(!n){n=r(null);n.apply=i;n.resolve=rs;n.reject=rj;n.info=o;t[e]=n}return n};var u=r(null);u.value=n;Object.defineProperty(document,\"__smGate\",u)}return n(e)}(e);var t=\"sourcemonkey-sync-\"+e;var r=\"sourcemonkey-reply-\"+e;var i=Reflect.apply;var a=Object.hasOwn;var o=Object.create;var u=Object.defineProperty;var c=setTimeout;var s=clearTimeout;var f=queueMicrotask;function bare(e){if(!e||typeof e!==\"object\")return e;var n=o(null);var t=X(e);for(var r=0;r<t.length;r++)n[t[r]]=e[t[r]];return n}function dataDesc(e,n,t,r){var i=o(null);i.value=e;i.writable=n;i.enumerable=t;i.configurable=r;return i}function drainQueue(e){var t=n.cfgQueue;if(!t)return;n.cfgQueue=null;for(var r=0;r<t.length;r++){try{e(t[r])}catch(e){try{console.info(\"[SourceMonkey] prelude init threw for\",t[r]&&t[r].id,e)}catch(e){}}}}if(n.prelude&&n.prelude.scripts){drainQueue(n.prelude.init);return}var d=o(null);function makeEntry(e){return{cfg:e,matched:true,decision:null,runAtFired:false,replayLoad:false,pendingRun:null,runRegistered:false,loadedAtRun:e.loadedAt,asyncListenersInstalled:false,send}}function hasOwnRuntimeChannel(){try{return typeof chrome!==\"undefined\"&&!!chrome.runtime&&typeof chrome.runtime.id===\"string\"&&typeof chrome.runtime.sendMessage===\"function\"}catch(e){return false}}var l=hasOwnRuntimeChannel();var v=l?chrome.runtime.sendMessage.bind(chrome.runtime):null;var y=eval;var p=null;var m=null;var g=null;var h=null;var w=null;try{p=CustomEvent}catch(e){}try{g=JSON.stringify;h=JSON.parse}catch(e){}try{w=Object.getOwnPropertyDescriptor(CustomEvent.prototype,\"detail\").get}catch(e){}try{if(document&&typeof document.dispatchEvent===\"function\"){m=document.dispatchEvent.bind(document)}}catch(e){}var b=[];var S=false;function dispatchToBridge(e){var n=o(null);n.detail=e;n.cancelable=true;return!m(new p(t,n))}function bridgeDispatch(e,n){try{if(!p||!m||!g)return false;var t=g({requestId:n==null?undefined:n,payload:e});if(!dispatchToBridge(t))holdForBridge(t,n);return true}catch(e){return false}}function addHeld(e,n){u(e,e.length,dataDesc(n,true,true,true))}function holdForBridge(e,n){addHeld(b,{detail:e,requestId:n});if(S)return;S=true;try{window.addEventListener(\"sourcemonkey-bridge-ready\",resendHeld,true)}catch(e){}}function dropHeld(e){var n=[];for(var t=0;t<b.length;t++){if(b[t].requestId!==e)addHeld(n,b[t])}b=n}function resendHeld(){var e=b;b=[];for(var n=0;n<e.length;n++){try{if(!dispatchToBridge(e[n].detail))addHeld(b,e[n])}catch(e){}}}var k=Object.create(null);function onReply(e,n){k[e]=n}function offReply(e){delete k[e]}if(!l){try{document.addEventListener(r,function(e){try{var n=bare(h(i(w,e,[])));if(!n||typeof n.requestId!==\"string\")return;f(function(){var e=k[n.requestId];if(!e)return;delete k[n.requestId];e(n.reply)})}catch(e){}},true)}catch(e){}}var A=false;try{A=self.origin===\"null\"}catch(e){}function send(e){try{e.opaqueOrigin=A}catch(e){}try{if(l){var n=v(e);if(n&&typeof n.catch===\"function\")n.catch(function(){});return}}catch(e){}bridgeDispatch(e,null)}function hasGmRuntime(){return!!n.gm}var R=1e4;var E=\"SourceMonkey could not be asked whether to run it\";function noDecision(e){return{action:\"skip\",reason:\"no-decision\",detail:e}}function askFailed(e){return noDecision(\"Asking SourceMonkey whether to run it failed: \"+(e&&e.message||String(e)))}function sentence(e){return String(e).replace(/\\.+\\s*$/,\"\")+\".\"}function awaitDecision(e,n){var t=e.cfg;var r=!!(t.matching&&t.matching.tld);var decided=function(e){e=bare(e);if(e&&typeof e===\"object\"&&(e.action===\"run\"||e.action===\"run-new\"||e.action===\"skip\"))return e;if(e&&typeof e===\"object\"&&typeof e.bridgeError===\"string\")return noDecision(e.bridgeError);return noDecision(\"SourceMonkey's answer whether to run it was unreadable\")};var i=noDecision(\"SourceMonkey did not answer whether to run it within \"+R/1e3+\" seconds\");var a=false;var finish=function(e){if(a)return;a=true;try{n(e)}catch(e){}};var cleanup=function(){};var o=c(function(){seal(i)},R);var seal=function(e){try{s(o)}catch(e){}try{cleanup()}catch(e){}finish(e)};try{if(l){var u=v({type:\"sm:check-pending\",id:t.id,name:t.name,loadedAt:t.loadedAt,url:location.href,needsValues:!!t.needsGmValues,tld:r});if(u&&typeof u.then===\"function\"){u.then(function(e){seal(decided(e))},function(e){seal(askFailed(e))})}else{seal(noDecision(E))}return}var f=\"sm-\"+Math.random().toString(36).slice(2)+\"-\"+Date.now();var d={type:\"sm:check-pending\",id:t.id,name:t.name,loadedAt:t.loadedAt,url:location.href,needsValues:!!t.needsGmValues,tld:r};onReply(f,function(e){seal(decided(e))});cleanup=function(){offReply(f);dropHeld(f)};var y=bridgeDispatch(d,f);if(!y)seal(noDecision(E))}catch(e){seal(askFailed(e))}}var L=new WeakSet;function stackHitsScript(e,n){try{var t=e&&typeof e===\"object\"&&e.stack;if(typeof t!==\"string\")return false;if(t.indexOf(n.cfg.sourceUrl)!==-1)return true}catch(e){}return false}function filenameHitsScript(e,n){try{if(typeof e!==\"string\")return false;if(e.indexOf(n.cfg.sourceUrl)!==-1)return true}catch(e){}return false}function reportAsync(e,n,t){try{if(n&&typeof n===\"object\"){if(L.has(n))return;L.add(n)}}catch(e){}var r;try{r=n&&n.message?String(n.message):String(n)}catch(e){r=\"(unstringifiable error)\"}var i=\"\";try{if(n&&typeof n.stack===\"string\")i=n.stack}catch(e){}try{console.info(\"[SourceMonkey] caught async \"+t+\" in\",e.cfg.name)}catch(e){}send({type:\"sm:error\",id:e.cfg.id,name:e.cfg.name,loadedAt:e.loadedAtRun,url:location.href,message:r,stack:i})}var O=5e3;var M=0;var D=false;function sendFocusSignal(){var e=Date.now();if(e-M<O)return;M=e;send({type:\"sm:focus\",url:location.href})}function installFocusSignal(){if(D)return;D=true;try{window.addEventListener(\"focus\",sendFocusSignal);document.addEventListener(\"visibilitychange\",function(){if(!document.hidden)sendFocusSignal()})}catch(e){}}function installAsyncListeners(e){if(e.asyncListenersInstalled)return;e.asyncListenersInstalled=true;try{window.addEventListener(\"error\",function(n){if(!n)return;if(filenameHitsScript(n.filename,e)||stackHitsScript(n.error,e)){reportAsync(e,n.error||n.message||\"error\",\"error\")}},true);window.addEventListener(\"unhandledrejection\",function(n){if(n&&stackHitsScript(n.reason,e)){reportAsync(e,n.reason,\"unhandledrejection\")}},true)}catch(e){}}var F=200;var I=null;try{window.addEventListener(\"load\",function(e){I=e},{once:true})}catch(e){}var P=false;function runWithLoadReplay(e){var n=window;var t=o(null);var r=0;var a=_(n,\"addEventListener\");var u=n.addEventListener;var c=n.onload;var s=false;try{n.addEventListener=function(e,a){var o=this==null||isSandbox(this)?n:this;if(e===\"load\"&&o===n&&a){t[r++]=a;return}return i(u,o,arguments)};s=true}catch(e){}try{P=s;e()}finally{P=false;if(s){try{if(a)Q(n,\"addEventListener\",a);else delete n.addEventListener}catch(e){}}try{if(n.onload!==c&&typeof n.onload===\"function\")t[r++]=n.onload}catch(e){}}var f=I;for(var d=0;d<r;d++)replayLoad(t[d],f)}function replayLoad(e,n){c(function(){if(typeof e===\"function\")i(e,window,[n]);else if(e&&typeof e.handleEvent===\"function\"){i(e.handleEvent,e,[n])}},0)}function waitForRunAt(e,n){if(e===\"document-start\"){waitForNode(function(){return document.documentElement},false,true,n);return}if(e===\"document-body\"){waitForNode(function(){return document.body},true,false,n);return}if(e===\"document-end\"){if(document.readyState!==\"loading\"){n();return}document.addEventListener(\"DOMContentLoaded\",function(){n()},{once:true});return}if(document.readyState===\"complete\"){n();return}var t=false;var r=null;var runIdle=function(){if(t)return;t=true;if(r!==null)s(r);window.removeEventListener(\"load\",runIdle);document.removeEventListener(\"readystatechange\",onReadyState);document.removeEventListener(\"DOMContentLoaded\",onContentLoaded);n(true)};var onReadyState=function(){if(document.readyState===\"complete\")runIdle()};var onContentLoaded=function(){if(r===null)r=c(runIdle,F)};window.addEventListener(\"load\",runIdle);document.addEventListener(\"readystatechange\",onReadyState);if(document.readyState===\"loading\"){document.addEventListener(\"DOMContentLoaded\",onContentLoaded)}else{onContentLoaded()}}function waitForNode(e,n,t,r){if(e()){r();return}var i=false;var a=null;var finish=function(e){if(i)return;i=true;try{if(a)a.disconnect()}catch(e){}try{document.removeEventListener(\"DOMContentLoaded\",onEnd,true)}catch(e){}if(e)r()};var onEnd=function(){finish(!!e()||t)};if(document.readyState!==\"loading\"){onEnd();return}try{a=new MutationObserver(function(){if(e())finish(true)});a.observe(document,{childList:true,subtree:n});document.addEventListener(\"DOMContentLoaded\",onEnd,true)}catch(e){finish(true)}}function testRx(e,n){try{return new RegExp(e[0],e[1]).test(n)}catch(e){return false}}function matchScript(e,n){for(var t=0;t<n.exclude.length;t++)if(testRx(n.exclude[t],e))return false;for(var r=0;r<n.include.length;r++)if(testRx(n.include[r],e))return true;return false}function inTopFrame(){try{return window.top===window}catch(e){return false}}function emitStartupLogs(e){var n=e.startupLogs;if(!n||!n.length)return;for(var t=0;t<n.length;t++){var r=n[t];try{console.info(\"[SourceMonkey] \"+e.name+\": \"+r.message)}catch(e){}}}function initScript(e){if(!e||!e.id)return;if(d[e.id]){if(e.manualRun)return rerunManual(d[e.id],e);return d[e.id]}var n=makeEntry(e);d[e.id]=n;if(e.matching){n.matched=matchScript(location.href,e.matching);if(!n.matched)return n}installAsyncListeners(n);installFocusSignal();if(inTopFrame())emitStartupLogs(e);if(e.manualRun){startManualRun(n,e);return n}waitForRunAt(e.runAt,function(e){n.runAtFired=true;n.replayLoad=!!e;flushPending(n)});if(canSkipDecision(e)){n.decision=bare({action:\"run\"});return n}awaitDecision(n,function(t){n.decision=t;if(t&&t.startupLogs===true&&!inTopFrame())emitStartupLogs(e);if(n.decision.action===\"skip\"){if(n.decision.reason===\"no-match\"){n.matched=false;n.pendingRun=null;return}if(n.decision.reason===\"no-decision\"){try{console.info(\"[SourceMonkey] \"+e.name+\": It did not run. \"+sentence(n.decision.detail))}catch(e){}}send({type:\"sm:abandoned\",id:e.id,name:e.name,loadedAt:e.loadedAt,url:location.href,reason:n.decision.reason||\"skip\",detail:n.decision.detail});n.pendingRun=null;return}flushPending(n)});return n}function startManualRun(e,n){e.runAtFired=true;e.decision=bare({action:\"run\"});if(n.manualRun.gmValues){e.decision.gmValues=n.manualRun.gmValues;e.decision.gmSeq=n.manualRun.gmSeq}}function rerunManual(e,t){try{if(n.gm&&typeof n.gm.retireRun===\"function\")n.gm.retireRun(t.id)}catch(e){}e.cfg=t;e.matched=t.matching?matchScript(location.href,t.matching):true;e.pendingRun=null;e.runRegistered=false;e.replayLoad=false;e.loadedAtRun=t.loadedAt;if(e.matched){installAsyncListeners(e);startManualRun(e,t)}return e}function canSkipDecision(e){if(e.runAt!==\"document-start\")return false;if(e.needsGmValues)return false;if(e.matching&&e.matching.tld)return false;if(e.needsGmRuntime&&!hasGmRuntime())return false;try{if(window.top!==window)return false;var n=performance.getEntriesByType(\"navigation\")[0];if(!n||n.type===\"reload\")return false}catch(e){return false}if(typeof e.run===\"string\")return smDevMarker(j+e.run);return!smDevMarker(x)}var x=\"sourcemonkey-sm-dev\";var j=\"sourcemonkey-sm-dev-run:\";function smDevMarker(e){try{var n=new CustomEvent(e,{cancelable:true});window.dispatchEvent(n);return n.defaultPrevented}catch(e){return false}}function flushPending(e){if(!e.runAtFired||!e.decision)return;if(e.decision.action===\"skip\")return;var n=e.pendingRun;e.pendingRun=null;if(typeof n!==\"function\")return;if(e.replayLoad&&I){runWithLoadReplay(function(){runMain(e,n)})}else{runMain(e,n)}}function runMain(e,t){var r=e.cfg;var i=e.decision;if(i.action===\"run-new\"&&typeof i.body===\"string\"){var a=typeof i.loadedAt===\"number\"?i.loadedAt:r.loadedAt;var o=false;var u=null;var c=true;if(i.needsRuntime&&!hasGmRuntime()){c=false;try{console.info(\"[SourceMonkey] \"+r.name+\": The updated copy needs the GM runtime, which this page does not have yet, so the previous version ran. Reload the page to pick it up.\")}catch(e){}}if(c&&i.seedValues){c=false;var s=i.gmValues;if(s&&typeof s===\"object\"){try{n.gm.storage.init(r.id,s,i.gmSeq);c=true}catch(e){}}if(!c){try{console.info(\"[SourceMonkey] \"+r.name+\": Could not load this script's stored GM values for the updated copy, so the previous version ran. Reload the page to retry.\")}catch(e){}}}if(c){try{y(i.body+\"\\n//# sourceURL=\"+r.sourceUrl)}catch(e){u=e;var f=e&&e.message?String(e.message):String(e);if(f.indexOf(\"unsafe-eval\")!==-1||f.indexOf(\"Content Security Policy\")!==-1){o=true}}}if(o||!c){if(o){try{console.info(\"[SourceMonkey] swap blocked by page CSP for \"+r.name+\", running prior version\")}catch(e){}}}else{e.loadedAtRun=a;try{console.log(\"[SourceMonkey] script\",r.name,\"running on\",location.href,\"(swapped to newer version)\")}catch(e){}send({type:\"sm:swapped\",id:r.id,name:r.name,fromLoadedAt:r.loadedAt,loadedAt:a,gmSeq:i.gmSeq,url:location.href});if(u){var d=u&&u.message?u.message:String(u);var l=u&&typeof u.stack===\"string\"?u.stack:\"\";try{console.info(\"[SourceMonkey] swapped script\",r.name,\"threw:\",u)}catch(e){}send({type:\"sm:error\",id:r.id,name:r.name,loadedAt:a,url:location.href,message:d,stack:l})}return}}try{console.log(\"[SourceMonkey] script\",r.name,\"running on\",location.href)}catch(e){}send({type:\"sm:start\",id:r.id,name:r.name,loadedAt:r.loadedAt,gmSeq:i.gmSeq,url:location.href});try{t(e)}catch(e){var v=e&&e.message?e.message:String(e);var p=e&&typeof e.stack===\"string\"?e.stack:\"\";try{console.info(\"[SourceMonkey] script\",r.name,\"threw:\",e)}catch(e){}send({type:\"sm:error\",id:r.id,name:r.name,loadedAt:r.loadedAt,url:location.href,message:v,stack:p})}}n.run=function(e,n){var t=d[e];if(!t)return;t.runRegistered=true;if(!t.matched)return;t.pendingRun=n;flushPending(t)};n.sealed=function(e){var n=d[e];if(!n||n.runRegistered)return;if(!n.matched)return;var t=\"Script source failed to parse (a @require or the script body has a syntax error); nothing was run\";try{console.info(\"[SourceMonkey]\",n.cfg.name+\":\",t)}catch(e){}send({type:\"sm:error\",id:n.cfg.id,name:n.cfg.name,loadedAt:n.loadedAtRun,url:location.href,message:t})};var T=Proxy;var W=WeakMap;var q=W.prototype.get;var N=W.prototype.set;var C=W.prototype.has;function wmGet(e,n){return i(q,e,[n])}function wmSet(e,n,t){i(N,e,[n,t])}function wmHas(e,n){return i(C,e,[n])}var B=Reflect.construct;var H=Reflect.defineProperty;var G=Reflect.deleteProperty;var V=Reflect.get;var K=Reflect.set;var _=Object.getOwnPropertyDescriptor;var U=Object.getPrototypeOf;var Q=Object.defineProperty;var X=Reflect.ownKeys;var Y=Function.prototype.toString;var z=Function.prototype.bind;var J=Object.prototype;var $=Symbol.unscopables;var Z=/\\{\\s*\\[native code\\]\\s*\\}\\s*$/;var ee=new W;var ne=new W;var te=new W;function isSandbox(e){return!!(e&&typeof e===\"object\"&&wmHas(ee,e))}var re=Object.create(null);(\"addEventListener alert atob blur btoa cancelAnimationFrame cancelIdleCallback \"+\"captureEvents clearInterval clearTimeout close confirm createImageBitmap \"+\"dispatchEvent fetch find focus getComputedStyle getSelection matchMedia \"+\"moveBy moveTo open postMessage print prompt queueMicrotask releaseEvents \"+\"removeEventListener reportError requestAnimationFrame requestIdleCallback \"+\"resizeBy resizeTo scroll scrollBy scrollTo setInterval setTimeout \"+\"showDirectoryPicker stop structuredClone webkitCancelAnimationFrame \"+\"webkitRequestAnimationFrame\").split(\" \").forEach(function(e){re[e]=true});function isNative(e){var n=wmGet(te,e);if(n===undefined){try{n=Z.test(i(Y,e,[]))}catch(e){n=false}wmSet(te,e,n)}return n}var ie=new W;function hasStatics(e){var n=wmGet(ie,e);if(n===undefined){var t=X(e);n=false;for(var r=0;r<t.length;r++){if(t[r]!==\"length\"&&t[r]!==\"name\"){n=true;break}}wmSet(ie,e,n)}return n}function isWindowMethod(e,n){if(typeof n!==\"function\"||e===\"eval\")return false;if(typeof e===\"string\"&&re[e])return true;if(a(n,\"prototype\"))return false;if(a(J,e)&&J[e]===n)return false;return isNative(n)&&!hasStatics(n)}function boundToWindow(e){var n=wmGet(ne,e);if(!n){if(isNative(e)){n=i(z,e,[window])}else{n=function(){if(new.target!==undefined)return B(e,arguments,new.target===n?e:new.target);return i(e,window,arguments)}}wmSet(ne,e,n)}return n}var ae=o(null);var oe=o(null);var ue=[];var ce={};var se=o(null);(\"Object Function Array Number Boolean String Symbol BigInt Date RegExp \"+\"Error TypeError RangeError SyntaxError ReferenceError EvalError URIError \"+\"AggregateError Promise Proxy Reflect JSON Math Intl Atomics Map Set \"+\"WeakMap WeakSet WeakRef FinalizationRegistry ArrayBuffer SharedArrayBuffer \"+\"DataView Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array \"+\"Int32Array Uint32Array Float32Array Float64Array BigInt64Array \"+\"BigUint64Array NaN Infinity \"+\"XMLHttpRequest WebSocket EventSource MutationObserver \"+\"IntersectionObserver Worker Request Response Headers Image \"+\"Event CustomEvent\").split(\" \").forEach(function(e){se[e]=true});if(!l)(function(){for(var e=window;e;e=U(e)){var n=X(e);for(var t=0;t<n.length;t++){var r=n[t];if(typeof r!==\"string\"||r in ae||isOurKey(r))continue;var i;if(e===window&&r[0]>=\"A\"&&r[0]<=\"Z\"&&!se[r]){i=ce}else{i=bare(_(e,r));if(!i)continue}ae[r]=i;if(e===window){oe[r]=true;ue.push(r)}}}})();function builtinDescriptor(e){var n=ae[e];if(n!==ce)return n||null;n=bare(_(window,e));if(!n){delete ae[e];delete oe[e];return null}ae[e]=n;return n}function isLiveName(e){if(typeof e!==\"string\")return false;if(isIndex(e))return true;if(P&&e===\"addEventListener\")return true;var t=n.liveWindowNames;return!!(t&&t[e]===true)}function isIndex(e){if(!(e[0]>=\"0\"&&e[0]<=\"9\"))return false;return\"\"+(e>>>0)===e&&e!==\"4294967295\"}var fe=o(null);(\"opener event length frames parent self external clientInformation \"+\"innerWidth innerHeight outerWidth outerHeight screenX screenY \"+\"screenLeft screenTop scrollX scrollY pageXOffset pageYOffset \"+\"devicePixelRatio origin screen performance visualViewport \"+\"locationbar menubar personalbar scrollbars statusbar toolbar\").split(\" \").forEach(function(e){fe[e]=true});function isBuiltin(e){return e in ae&&(ae[e]!==ce||builtinDescriptor(e)!==null)}function isShown(e){return typeof e!==\"string\"||isBuiltin(e)||isLiveName(e)}function shownDescriptor(e){if(typeof e!==\"string\"||isLiveName(e))return windowDescriptor(e);return builtinDescriptor(e)}function isOurKey(e){return typeof e===\"string\"&&e[0]===\"_\"&&e[1]===\"_\"&&e[2]===\"s\"&&e[3]===\"m\"}function windowDescriptor(e){for(var n=window;n;n=U(n)){var t=bare(_(n,e));if(t)return t}return null}function isWindowAlias(e){return e===\"window\"||e===\"self\"||e===\"globalThis\"}function isSelfAlias(e){return e===\"top\"||e===\"parent\"||e===\"frames\"}function makeSandbox(e){var n=o(null);var t;var r=X(e);for(var u=0;u<r.length;u++){if(e[r[u]]===undefined)continue;Q(n,r[u],dataDesc(e[r[u]],true,false,true))}var c=o(null);function pageValue(e){var n;if(typeof e!==\"string\"||isLiveName(e)){n=window[e]}else{if(e in c)return c[e];var r=builtinDescriptor(e);if(!r)return undefined;if(!r.get&&!r.set&&\"value\"in r){n=r.value;if(n===window&&(isWindowAlias(e)||isSelfAlias(e)))n=t;else if(isWindowMethod(e,n))n=boundToWindow(n);c[e]=n;return n}n=r.get?i(r.get,window,[]):undefined}if(n===window&&(isWindowAlias(e)||isSelfAlias(e)))return t;if(isWindowMethod(e,n))return boundToWindow(n);return n}t=new T(n,{has:function(e,n){if(isOurKey(n))return n in window;if(n in e)return true;return isShown(n)&&(typeof n!==\"string\"||isLiveName(n)?n in window:true)},get:function(e,n){if(isOurKey(n))return window[n];if(a(e,n)){var r=V(e,n,t);if(typeof n===\"string\"&&re[n]&&typeof r===\"function\"){var i=_(e,n);if(i&&(i.configurable||i.writable))return boundToWindow(r)}return r}return pageValue(n)},set:function(e,n,r){if(isOurKey(n)){window[n]=r;return true}if(a(e,n))return K(e,n,r,t);var o=shownDescriptor(n);if(o&&o.set&&!(typeof n===\"string\"&&fe[n]===true)){i(o.set,window,[r]);return true}if(typeof n===\"string\"&&fe[n]===true){return H(e,n,dataDesc(r,true,true,true))}if(o&&(o.get||!o.writable))return false;return H(e,n,dataDesc(r,true,true,true))},defineProperty:function(e,n,t){if(isOurKey(n))return H(window,n,t);return H(e,n,t)},deleteProperty:function(e,n){if(isOurKey(n))return G(window,n);return G(e,n)},getOwnPropertyDescriptor:function(e,n){if(!isOurKey(n)&&a(e,n))return _(e,n);var t;if(isOurKey(n)||typeof n!==\"string\"||isLiveName(n)){t=_(window,n)}else if(oe[n]){t=bare(builtinDescriptor(n))||undefined}if(!t)return undefined;t.configurable=true;if(\"value\"in t)t.value=pageValue(n);return t},ownKeys:function(e){var n=o(null);var t=[];var add=function(e){if(typeof e===\"symbol\"){for(var r=0;r<t.length;r++)if(t[r]===e)return}else{if(n[e])return;n[e]=true}Q(t,t.length,dataDesc(e,true,true,true))};var r;for(r=0;r<ue.length;r++){if(oe[ue[r]])add(ue[r])}var i=X(window);for(r=0;r<i.length;r++){if(typeof i[r]===\"symbol\"||isLiveName(i[r]))add(i[r])}var a=X(e);for(r=0;r<a.length;r++)add(a[r]);return t},getPrototypeOf:function(){return U(window)},setPrototypeOf:function(){return false},preventExtensions:function(){return false}});var s=new T(o(null),{has:function(e,t){if(typeof t!==\"string\"||isOurKey(t))return false;if(a(n,t)||isWindowAlias(t))return true;if(!isSelfAlias(t)&&isBuiltin(t)||isLiveName(t))return true;return isSelfAlias(t)&&window[t]===window},get:function(e,n){if(n===$)return undefined;return t[n]},set:function(e,n,r){return K(t,n,r)}});wmSet(ee,t,s);return t}function scopeOf(e){return ee&&wmGet(ee,e)||e}function callAs(e,n){return i(e,n,[])}n.prelude={scripts:d,init:initScript,decisionTimeoutMs:R,send,sandbox:makeSandbox,scopeOf,callAs};if(!l){var announce=function(){try{if(p&&m)m(new p(\"sourcemonkey-main-ready\"))}catch(e){}};try{window.addEventListener(\"sourcemonkey-bridge-ready\",announce,true)}catch(e){}announce()}drainQueue(initScript)})();";
|
|
4
|
+
export const WRAPPER_BRIDGE = "(function(){\"use strict\";var e=\"__SM_KEY__\";var t=\"__SM_ONLY__\";var r=t===\"_\"+\"_SM_ONLY__\"?null:t;function ours(e){return r===null||typeof e!==\"string\"||e===r}function scriptOf(e){return e.type.indexOf(\"sm:gm-\")===0?e.scriptId:e.id}var n=\"sourcemonkey-reply-\"+e;var o=\"sourcemonkey-push-\"+e;var a=\"sourcemonkey-sync-\"+e;var i=\"sourcemonkey-bridge-ready\";var s=\"sourcemonkey-insert-\"+e;var m=\"sourcemonkey-main-ready\";var c=[\"sm:start\",\"sm:error\",\"sm:swapped\",\"sm:abandoned\",\"sm:check-pending\",\"sm:focus\",\"sm:gm-batch-write\",\"sm:gm-xhr-start\",\"sm:gm-xhr-abort\",\"sm:gm-tab-open\",\"sm:gm-tab-close\",\"sm:gm-notification-show\",\"sm:gm-menu-register\",\"sm:gm-menu-unregister\",\"sm:gm-download-start\",\"sm:gm-download-abort\",\"sm:gm-window-close\",\"sm:gm-window-focus\",\"sm:gm-tab-data\",\"sm:gm-resync\",\"sm:gm-log\",\"sm:gm-dom-blocked\",\"sm:gm-call\"];var u=[\"sm:gm-value-update\",\"sm:gm-values-stale\",\"sm:gm-xhr-event\",\"sm:gm-tab-closed\",\"sm:gm-notification-event\",\"sm:gm-menu-fire\",\"sm:gm-download-event\"];var f=[\"sm:gm-resync-hint\",\"sm:url-change\"];if(typeof chrome===\"undefined\"||!chrome.runtime||!chrome.runtime.sendMessage)return;var d=\"__smBridgeInstalled_\"+e;if(window[d])return;window[d]=true;function stamp(e){var t={};for(var r in e){if(r===\"__viaBridge\"||r===\"__proto__\")continue;if(Object.prototype.hasOwnProperty.call(e,r))t[r]=e[r]}t.__viaBridge=true;return t}function relay(e,t){if(!e||typeof e!==\"object\")return;if(c.indexOf(e.type)===-1)return;if(!ours(scriptOf(e)))return;if(typeof t!==\"string\"){var r=chrome.runtime.sendMessage(stamp(e));if(r&&typeof r.catch===\"function\")r.catch(function(){});return}var post=function(e){try{toPage(n,{requestId:t,reply:e||{bridgeError:\"SourceMonkey gave no answer\"}})}catch(e){}};var failed=function(e){post({bridgeError:\"Asking SourceMonkey failed: \"+(e&&e.message||String(e))})};try{var o=chrome.runtime.sendMessage(stamp(e));if(o&&typeof o.then===\"function\"){o.then(post,failed)}else{post(null)}}catch(e){failed(e)}}function toPage(e,t){document.dispatchEvent(new CustomEvent(e,{detail:JSON.stringify(t)}))}document.addEventListener(a,function(e){try{if(e&&typeof e.preventDefault===\"function\")e.preventDefault();if(!e||typeof e.detail!==\"string\")return;var t=JSON.parse(e.detail);if(!t||typeof t!==\"object\")return;relay(t.payload,t.requestId)}catch(e){}},true);var g=null;try{g=Node.prototype.appendChild}catch(e){}if(g)window.addEventListener(s,function(e){try{var t=e.relatedTarget;var r=e.composedPath()[0];if(!(t instanceof Element)||!(r instanceof Node))return;g.call(r,t);e.preventDefault();e.stopImmediatePropagation()}catch(e){}},true);var p=null;try{p=chrome.runtime.id}catch(e){}try{if(chrome.runtime.onMessage&&typeof chrome.runtime.onMessage.addListener===\"function\"){chrome.runtime.onMessage.addListener(function(e,t){try{if(!t||t.id!==p||t.tab)return;if(!e||typeof e!==\"object\")return;if(f.indexOf(e.type)===-1){if(u.indexOf(e.type)===-1)return;if(e.smWorld!==\"MAIN\")return;if(!ours(e.smScript))return}toPage(o,e)}catch(e){}})}}catch(e){}var y=false;try{window.addEventListener(m,function(){y=true},true)}catch(e){}try{window.dispatchEvent(new CustomEvent(i))}catch(e){}var SM_MAIN_IN_FRAMES=true;var l=SM_MAIN_IN_FRAMES||window===window.top;if(!y&&l){setTimeout(function(){if(y)return;try{var e=chrome.runtime.sendMessage({type:\"sm:main-blocked\"});if(e&&typeof e.catch===\"function\")e.catch(function(){})}catch(e){}},0)}})();";
|
|
5
|
+
export const WRAPPER_GM_RUNTIME = "(function(){\"use strict\";if(typeof window===\"undefined\")return;var e=\"__SM_KEY__\";var r=function(e){var r=document.__smGate;if(typeof r!==\"function\"){var t=Object.create(null),n=Object.create,a=Reflect.apply,o=Promise;var i=console.info.bind(console);var rs=function(e){return new o(function(r){r(e)})};var rj=function(e){return new o(function(r,t){t(e)})};r=function(e){if(typeof e!==\"string\")return void 0;var r=t[e];if(!r){r=n(null);r.apply=a;r.resolve=rs;r.reject=rj;r.info=i;t[e]=r}return r};var u=n(null);u.value=r;Object.defineProperty(document,\"__smGate\",u)}return r(e)}(e);if(r.gm)return;var t=Promise;var n=Error;var a=Date.now.bind(Date);var o=Number.prototype.toString;var i=Math.random;var u=JSON.stringify;var l=Object.keys;var c=Array.isArray;var s=Object.prototype.toString;var f=Date;var d=Date.prototype.getTime;var y=RegExp;var p=typeof Map===\"function\"?Map:null;var v=p?Map.prototype.forEach:null;var h=typeof Set===\"function\"?Set:null;var g=h?Set.prototype.forEach:null;var m=typeof BigInt===\"function\"?BigInt:null;var b=typeof Uint8Array===\"function\"?Uint8Array:null;var w=typeof DataView===\"function\"?DataView:null;var S=String.fromCharCode;var k=typeof btoa===\"function\"?btoa:null;var M=typeof atob===\"function\"?atob:null;var C=typeof ReadableStream===\"function\"?ReadableStream:null;var T=typeof DOMException===\"function\"?DOMException:n;var x=Object.getPrototypeOf;var E=null;var q=null;var B=null;var I=null;var R=null;var A=null;(function(){function getter(e,r){var t=Object.getOwnPropertyDescriptor(e,r);return t&&typeof t.get===\"function\"?t.get:null}try{E=getter(RegExp.prototype,\"source\");q=getter(RegExp.prototype,\"flags\")}catch(e){}try{B=getter(ArrayBuffer.prototype,\"byteLength\");I=getter(DataView.prototype,\"byteLength\");R=getter(x(Uint8Array.prototype),\"length\");A=x(Uint8Array.prototype).subarray}catch(e){}})();var O={};var U={};(function(){var e;var r=[\"Int8Array\",\"Uint8Array\",\"Uint8ClampedArray\",\"Int16Array\",\"Uint16Array\",\"Int32Array\",\"Uint32Array\",\"Float16Array\",\"Float32Array\",\"Float64Array\",\"BigInt64Array\",\"BigUint64Array\"];for(e=0;e<r.length;e++){try{if(typeof window[r[e]]===\"function\")O[r[e]]=window[r[e]]}catch(e){}}var t=[\"Error\",\"EvalError\",\"RangeError\",\"ReferenceError\",\"SyntaxError\",\"TypeError\",\"URIError\"];for(e=0;e<t.length;e++){try{if(typeof window[t[e]]===\"function\")U[t[e]]=window[t[e]]}catch(e){}}})();var j=Object.create;var L=Object.defineProperty;var N=Reflect.apply;var _=setTimeout;var D=clearTimeout;var P=queueMicrotask;var X=Object.getOwnPropertyDescriptor;var G=Object.prototype.hasOwnProperty;var F=null;var V=null;var K=null;try{F=document.createElement.bind(document);V=Node.prototype.appendChild;K=Element.prototype.setAttribute}catch(e){}var W=null;try{if(typeof navigator!==\"undefined\"&&navigator.clipboard&&typeof navigator.clipboard.writeText===\"function\"){W=navigator.clipboard.writeText.bind(navigator.clipboard)}}catch(e){}var H=typeof Blob===\"function\"?Blob:null;var J=null;try{if(typeof URL!==\"undefined\"&&typeof URL.createObjectURL===\"function\"){J=URL.createObjectURL.bind(URL)}}catch(e){}var z=null;try{z=chrome.runtime.id}catch(e){}var Q=null;try{if(typeof z===\"string\"&&typeof chrome.runtime.sendMessage===\"function\"){Q=chrome.runtime.sendMessage.bind(chrome.runtime)}}catch(e){}var Y=\"sourcemonkey-reply-\"+e;var $=\"sourcemonkey-push-\"+e;var Z=\"sourcemonkey-sync-\"+e;var ee=\"sourcemonkey-insert-\"+e;var re=3e4;var te=null;var ne=1;var ae=[];function dispatchPush(e){for(var r=0;r<ae.length;r++){try{ae[r](e)}catch(e){}}}var oe=JSON.parse;var ie=null;try{ie=Object.getOwnPropertyDescriptor(CustomEvent.prototype,\"detail\").get}catch(e){}function bare(e){if(!e||typeof e!==\"object\")return e;var r=j(null);var t=l(e);for(var n=0;n<t.length;n++)r[t[n]]=e[t[n]];return r}function detailOf(e){return bare(oe(N(ie,e,[])))}function installBridgeListener(){var e=j(null);try{document.addEventListener($,function(e){try{var r=detailOf(e);if(r&&typeof r===\"object\")P(function(){dispatchPush(r)})}catch(e){}},true);document.addEventListener(Y,function(r){try{var t=detailOf(r);if(!t||typeof t.requestId!==\"string\")return;P(function(){var r=e[t.requestId];if(!r)return;delete e[t.requestId];try{D(r.timer)}catch(e){}r.resolve(bare(t.reply))})}catch(e){}},true)}catch(e){return}te=e}if(!Q)installBridgeListener();var ue=null;var le=null;try{ue=CustomEvent}catch(e){}try{if(document&&typeof document.dispatchEvent===\"function\"){le=document.dispatchEvent.bind(document)}}catch(e){}function bridgeDispatch(e,r){if(!ue||!le){throw new n(\"[SourceMonkey] GM bridge unavailable\")}var t;try{var a=j(null);a.requestId=r;a.payload=e;t=u(a)}catch(e){throw new n(\"[SourceMonkey] This call carries a value SourceMonkey cannot send. \"+\"Pass data that survives JSON: no circular references, functions, or BigInt\")}if(!dispatchToBridge(t))holdForBridge(t,r)}var ce=\"sourcemonkey-bridge-ready\";var se=[];var fe=false;function dispatchToBridge(e){var r=j(null);r.detail=e;r.cancelable=true;return!le(new ue(Z,r))}function holdForBridge(e,r){setOwnBare(se,se.length,{detail:e,requestId:r});if(fe)return;fe=true;try{window.addEventListener(ce,resendHeld,true)}catch(e){}}function dropHeld(e){var r=[];for(var t=0;t<se.length;t++){if(se[t].requestId!==e)setOwnBare(r,r.length,se[t])}se=r}function resendHeld(){var e=se;se=[];for(var r=0;r<e.length;r++){try{if(!dispatchToBridge(e[r].detail))setOwnBare(se,se.length,e[r])}catch(e){}}}function bridgeSend(e){if(!te){return t.reject(new n(\"[SourceMonkey] GM bridge unavailable\"))}var r=\"gm-\"+ne+++\"-\"+randomPart();return new t(function(t,a){var o=_(function(){delete te[r];dropHeld(r);a(new n(\"[SourceMonkey] GM bridge timed out after \"+re+\"ms\"))},re);te[r]={resolve:t,timer:o};try{bridgeDispatch(e,r)}catch(e){delete te[r];try{D(o)}catch(e){}a(e)}})}function transportSendNow(e){if(Q){var r=Q(e);if(r&&typeof r.catch===\"function\")r.catch(function(){});return}try{bridgeDispatch(e)}catch(e){}}var de=t.prototype.then;function guarded(e){setOwnBare(e,\"then\",guardedThen);setOwnBare(e,\"catch\",guardedCatch);setOwnBare(e,\"constructor\",undefined);return e}function setOwnBare(e,r,t){var n=j(null);n.value=t;n.writable=true;n.enumerable=false;n.configurable=true;L(e,r,n)}function guardedThen(e,r){return guarded(N(de,this,[e,r]))}function guardedCatch(e){return guarded(N(de,this,[undefined,e]))}function transportSend(e){if(Q){try{var r=Q(e);if(r&&typeof r.then===\"function\")return r;return t.resolve(r)}catch(e){return t.reject(e)}}return guarded(bridgeSend(e))}function onPush(e){ae.push(e)}if(Q){try{if(chrome.runtime.onMessage&&typeof chrome.runtime.onMessage.addListener===\"function\"){chrome.runtime.onMessage.addListener(function(e,r){if(!r||r.id!==z||r.tab)return;if(!e||typeof e!==\"object\")return;dispatchPush(e)})}}catch(e){}}var ye=j(null);var pe={};var ve=\"__smv__\";var he=1;var ge={};var me={};var be=32768;function bytesToBase64(e){var r=\"\";var t=N(R,e,[]);for(var n=0;n<t;n+=be){var a=N(A,e,[n,n+be]);var o=j(null);o.value=N(R,a,[]);L(a,\"length\",o);r+=N(S,null,a)}return k(r)}function base64ToBytes(e){var r=M(e);var t=new b(r.length);for(var n=0;n<r.length;n++)t[n]=r.charCodeAt(n);return t}var we=!!(k&&M&&b&&B&&I&&R);function encodeBranded(e,r,t){var n=N(s,e,[]);if(n===\"[object Date]\"){t.plain=false;var a=N(d,e,[]);return[\"d\",a===a?a:\"nan\"]}if(n===\"[object RegExp]\"&&E&&q){var o=N(E,e,[]);var i=N(q,e,[]);t.plain=false;return[\"re\",String(o),String(i)]}if(we&&n===\"[object ArrayBuffer]\"){N(B,e,[]);t.plain=false;return[\"ab\",bytesToBase64(new b(e))]}if(we&&n===\"[object DataView]\"){N(I,e,[]);t.plain=false;return[\"dv\",bytesToBase64(new b(e.buffer,e.byteOffset,e.byteLength))]}if(we){var u=n.slice(8,n.length-1);if(N(G,O,[u])){N(R,e,[]);t.plain=false;return[\"ta\",u,bytesToBase64(new b(e.buffer,e.byteOffset,e.byteLength))]}}if(n===\"[object Error]\"&&x(e)!==Object.prototype){t.plain=false;var c=[];var f=l(e);for(var y=0;y<f.length;y++){var m=encodeNode(e[f[y]],r,t);if(m!==ge)c.push([f[y],m])}return[\"err\",String(e.name),String(e.message),e.stack===undefined?null:String(e.stack),c]}if(p&&n===\"[object Map]\"){t.plain=false;var w=[];N(v,e,[function(e,n){var a=encodeNode(n,r,t);var o=encodeNode(e,r,t);w.push([a===ge?[\"u\"]:a,o===ge?[\"u\"]:o])}]);return[\"m\",w]}if(h&&n===\"[object Set]\"){t.plain=false;var S=[];N(g,e,[function(e){var n=encodeNode(e,r,t);S.push(n===ge?[\"u\"]:n)}]);return[\"s\",S]}return me}function encodeNode(e,r,t){var a=typeof e;if(e===null)return[\"p\",null];if(a===\"string\"||a===\"boolean\")return[\"p\",e];if(a===\"number\"){if(e!==e){t.plain=false;return[\"nan\"]}if(e===Infinity){t.plain=false;return[\"inf\"]}if(e===-Infinity){t.plain=false;return[\"-inf\"]}if(e===0&&1/e===-Infinity){t.plain=false;return[\"-0\"]}return[\"p\",e]}if(a===\"undefined\"){t.plain=false;return[\"u\"]}if(a===\"bigint\"){t.plain=false;return[\"big\",String(e)]}if(a===\"function\"||a===\"symbol\")return ge;if(a!==\"object\")return ge;for(var o=0;o<r.length;o++){if(r[o]===e){throw new n(\"[SourceMonkey] GM_setValue: a stored value cannot contain a circular reference\")}}r.push(e);try{if(c(e)){var i=[];for(var u=0;u<e.length;u++){var s=encodeNode(e[u],r,t);i.push(s===ge?[\"p\",null]:s)}return[\"a\",i]}var f=t.plain;var d;try{d=encodeBranded(e,r,t)}catch(e){d=me}if(d!==me)return d;t.plain=f;var y=e.toJSON;if(typeof y===\"function\"){var p=encodeNode(y.call(e),r,t);return p===ge?[\"u\"]:p}var v=l(e);var h=[];for(var g=0;g<v.length;g++){var m=encodeNode(e[v[g]],r,t);if(m===ge)continue;if(v[g]===ve)t.plain=false;h.push([v[g],m])}return[\"o\",h]}finally{r.pop()}}function encodeValue(e){var r={plain:true};var t=encodeNode(e,[],r);if(t===ge){r.plain=false;t=[\"u\"]}if(r.plain)return e;var n={};n[ve]=he;n.v=t;return n}function setDecoded(e,r,t){if(r===\"__proto__\"){L(e,r,{value:t,writable:true,enumerable:true,configurable:true})}else{e[r]=t}}function decodeNode(e){if(!c(e))return undefined;var r;switch(e[0]){case\"p\":return e[1];case\"u\":return undefined;case\"nan\":return NaN;case\"inf\":return Infinity;case\"-inf\":return-Infinity;case\"-0\":return-0;case\"big\":return m?m(e[1]):e[1];case\"d\":return new f(typeof e[1]===\"number\"?e[1]:NaN);case\"re\":return new y(e[1],e[2]);case\"ab\":return base64ToBytes(e[1]).buffer;case\"dv\":return new w(base64ToBytes(e[1]).buffer);case\"ta\":{var t=base64ToBytes(e[2]);if(!N(G,O,[e[1]]))return t;return new O[e[1]](t.buffer)}case\"err\":{var a=N(G,U,[e[1]])?U[e[1]]:n;var o=new a(e[2]);if(o.name!==e[1])o.name=e[1];if(e[3]!==null&&e[3]!==undefined){try{o.stack=e[3]}catch(e){}}var i=e[4];if(c(i)){for(r=0;r<i.length;r++)setDecoded(o,i[r][0],decodeNode(i[r][1]))}return o}case\"a\":{var u=[];for(r=0;r<e[1].length;r++)u.push(decodeNode(e[1][r]));return u}case\"o\":{var l={};for(r=0;r<e[1].length;r++)setDecoded(l,e[1][r][0],decodeNode(e[1][r][1]));return l}case\"m\":{var s=new p;for(r=0;r<e[1].length;r++)s.set(decodeNode(e[1][r][0]),decodeNode(e[1][r][1]));return s}case\"s\":{var d=new h;for(r=0;r<e[1].length;r++)d.add(decodeNode(e[1][r]));return d}default:return undefined}}function decodeValue(e){if(!e||typeof e!==\"object\"||c(e))return e;if(!N(G,e,[ve]))return e;if(e[ve]!==he)return e;try{return decodeNode(e.v)}catch(r){try{console.info(\"[SourceMonkey] stored value could not be decoded:\",r)}catch(e){}return e}}function ensureStore(e){var r=ye[e];if(r)return r;r={cache:{},pending:[],sendQueued:false,ready:false,listeners:null,nextListenerId:1,resyncInFlight:false,resyncAgain:false,lastResyncAt:0,seqByKey:j(null),snapSeq:0,unanswered:j(null),held:j(null)};ye[e]=r;return r}function knownSeq(e,r){return N(G,e.seqByKey,[r])?e.seqByKey[r]:e.snapSeq}function pinKnownSeq(e,r){if(!N(G,e.seqByKey,[r]))e.seqByKey[r]=e.snapSeq}function adoptSnapshotSeq(e,r){var t=l(e.seqByKey);for(var n=0;n<t.length;n++){var a=t[n];if(!hasUnanswered(e,a)&&e.seqByKey[a]<=r)delete e.seqByKey[a]}if(r>e.snapSeq)e.snapSeq=r}function hasUnanswered(e,r){return N(G,e.unanswered,[r])&&e.unanswered[r]>0}function fireListeners(e,r,t,n,a){var o=ye[e];if(!o||!o.listeners)return;var i=l(o.listeners);for(var u=0;u<i.length;u++){var c=o.listeners[i[u]];if(!c||c.key!==r)continue;try{c.callback(r,t,n,a)}catch(e){reportCallbackError(e)}}}function scheduleFlush(e){var r=ye[e];if(!r||r.sendQueued)return;r.sendQueued=true;var run=function(){flushStore(e,\"task\")};if(P)P(run);else t.resolve().then(run)}function flushStore(e,r){var t=ye[e];if(!t)return;t.sendQueued=false;if(t.pending.length===0)return;var n=t.pending;t.pending=[];var a=[];for(var o=0;o<n.length;o++){var i=n[o];if(i.value===pe){a.push({key:i.key,deleted:true})}else{a.push({key:i.key,value:i.value})}}var u=false;var answer=function(r){if(u)return;u=true;settleBatch(e,n,r)};try{var l={type:\"sm:gm-batch-write\",scriptId:e,writes:a};if(r===\"pagehide\"){transportSendNow(l);answer(null);return}var c=transportSend(l);if(c&&typeof c.then===\"function\"){c.then(function(r){if(r&&r.ok===true&&typeof r.seq===\"number\"){answer(r.seq);return}try{console.info(\"[SourceMonkey] storage flush not confirmed\",e,r&&r.error)}catch(e){}answer(null)},function(r){try{console.info(\"[SourceMonkey] storage flush rejected\",e,r&&r.message)}catch(e){}answer(null)})}else{answer(null)}}catch(r){try{console.info(\"[SourceMonkey] storage flush threw\",e,r&&r.message)}catch(e){}answer(null)}}function settleBatch(e,r,t){var n=ye[e];if(!n)return;var a=[];for(var o=0;o<r.length;o++){var i=r[o].key;if(hasUnanswered(n,i))n.unanswered[i]--;if(t!==null&&t>knownSeq(n,i))n.seqByKey[i]=t;a.push(i)}for(var u=0;u<a.length;u++){var l=a[u];if(hasUnanswered(n,l)||!N(G,n.held,[l]))continue;var c=n.held[l];delete n.held[l];applyRemoteWrite(e,n,c.write,c.seq)}}function flushAll(e){var r=l(ye);for(var t=0;t<r.length;t++){if(ye[r[t]].pending.length)flushStore(r[t],e)}}try{window.addEventListener(\"pagehide\",function(){flushAll(\"pagehide\")},{capture:true});window.addEventListener(\"visibilitychange\",function(){if(!document)return;if(document.visibilityState===\"hidden\")flushAll(\"task\");else resyncListeningStores()},{capture:true})}catch(e){}function applyRemoteUpdate(e,r,t){if(!r||!r.length||typeof t!==\"number\")return;var n=ye[e];if(!n||!n.ready)return;for(var a=0;a<r.length;a++)applyRemoteWrite(e,n,r[a],t)}function applyRemoteWrite(e,r,t,n){var a=t.key;if(hasUnanswered(r,a)){var o=r.held[a];if(!o||o.seq<=n)r.held[a]={write:t,seq:n};return}var i=N(G,r.seqByKey,[a]);if(i?n<r.seqByKey[a]:n<=r.snapSeq)return;r.seqByKey[a]=n;var u=N(G,r.cache,[a])?r.cache[a]:undefined;if(t.deleted){if(!N(G,r.cache,[a]))return;delete r.cache[a];fireListeners(e,a,u,undefined,true)}else{var l=decodeValue(t.value);r.cache[a]=l;fireListeners(e,a,u,l,true)}}var Se=5e3;function hasValueListeners(e){return!!(e&&e.listeners&&l(e.listeners).length>0)}function sameStoredValue(e,r){if(e===r)return true;if(e===null||r===null)return false;if(typeof e!==\"object\"||typeof r!==\"object\")return false;try{return u(e)===u(r)}catch(e){return false}}function applyResyncSnapshot(e,r,t){var n=ye[e];if(!n||!n.ready||!r||typeof t!==\"number\")return;var stale=function(e){if(hasUnanswered(n,e)){pinKnownSeq(n,e);return true}return knownSeq(n,e)>t};var a=j(null);var o=l(r);for(var i=0;i<o.length;i++){var u=o[i];a[u]=true;if(stale(u))continue;var c=N(G,n.cache,[u]);var s=c?n.cache[u]:undefined;var f=false;var d=null;if(c){try{d=encodeValue(s);f=true}catch(e){}}if(f&&sameStoredValue(d,r[u]))continue;var y=decodeValue(r[u]);n.cache[u]=y;fireListeners(e,u,s,y,true)}var p=l(n.cache);for(var v=0;v<p.length;v++){var h=p[v];if(a[h]||stale(h))continue;var g=n.cache[h];delete n.cache[h];fireListeners(e,h,g,undefined,true)}adoptSnapshotSeq(n,t)}function requestResync(e,r){var t=ye[e];if(!t||!t.ready)return;if(t.resyncInFlight){if(r)t.resyncAgain=true;return}var n=a();if(!r&&t.lastResyncAt&&n-t.lastResyncAt<Se)return;t.lastResyncAt=n;t.resyncInFlight=true;var done=function(){t.resyncInFlight=false;if(t.resyncAgain){t.resyncAgain=false;requestResync(e,true)}};transportSend({type:\"sm:gm-resync\",scriptId:e}).then(function(r){if(r&&r.ok&&r.values)applyResyncSnapshot(e,r.values,r.seq);done()},done)}function resyncListeningStores(){var e=l(ye);for(var r=0;r<e.length;r++){if(hasValueListeners(ye[e[r]]))requestResync(e[r])}}try{window.addEventListener(\"pageshow\",function(e){if(!e||!e.persisted)return;var r=l(ye);for(var t=0;t<r.length;t++)requestResync(r[t],true)},{capture:true})}catch(e){}onPush(function(e){if(e.type===\"sm:gm-resync-hint\"){resyncListeningStores();return}if(e.type===\"sm:gm-values-stale\"){if(typeof e.scriptId===\"string\")requestResync(e.scriptId,true);return}if(e.type!==\"sm:gm-value-update\")return;if(typeof e.scriptId!==\"string\")return;if(!e.writes||typeof e.writes.length!==\"number\")return;applyRemoteUpdate(e.scriptId,e.writes,e.seq)});var ke={init:function(e,r,t){var n=ensureStore(e);var a=typeof t===\"number\"?t:0;var o=j(null);var i=l(r||{});for(var u=0;u<i.length;u++)o[i[u]]=decodeValue(r[i[u]]);if(n.ready){var keep=function(e){if(hasUnanswered(n,e)){pinKnownSeq(n,e);return true}return knownSeq(n,e)>a};var c=l(n.cache);for(var s=0;s<c.length;s++){var f=c[s];if(keep(f))o[f]=n.cache[f]}for(var d=0;d<i.length;d++){var y=i[d];if(N(G,n.cache,[y]))continue;if(keep(y))delete o[y]}}n.cache=o;adoptSnapshotSeq(n,a);n.ready=true},get:function(e,r,t){var n=ye[e];if(!n||!n.ready)return t;if(N(G,n.cache,[r]))return n.cache[r];return t},set:function(e,r,t){var n=ensureStore(e);var a=encodeValue(t);var o=N(G,n.cache,[r])?n.cache[r]:undefined;n.cache[r]=t;n.unanswered[r]=(hasUnanswered(n,r)?n.unanswered[r]:0)+1;n.pending.push({key:r,value:a});scheduleFlush(e);fireListeners(e,r,o,t,false)},del:function(e,r){var t=ensureStore(e);var n=N(G,t.cache,[r])?t.cache[r]:undefined;delete t.cache[r];t.unanswered[r]=(hasUnanswered(t,r)?t.unanswered[r]:0)+1;t.pending.push({key:r,value:pe});scheduleFlush(e);fireListeners(e,r,n,undefined,false)},list:function(e){var r=ye[e];if(!r||!r.ready)return[];return l(r.cache)},addValueChangeListener:function(e,r,t){if(typeof t!==\"function\"){throw new n(\"[SourceMonkey] GM_addValueChangeListener: callback must be a function\")}var a=ensureStore(e);if(!a.listeners)a.listeners=j(null);var o=String(a.nextListenerId++);a.listeners[o]={key:String(r),callback:t};return o},encodeValue,decodeValue,removeValueChangeListener:function(e,r){var t=ye[e];if(!t||!t.listeners)return;var n=String(r);if(N(G,t.listeners,[n]))delete t.listeners[n]}};function defaultParent(){return document.head||document.documentElement}function defaultParentFor(e){var r=String(e).toUpperCase();if(r===\"SCRIPT\"||r===\"STYLE\"||r===\"LINK\"||r===\"META\"||r===\"TITLE\"||r===\"BASE\"){return document.head||document.documentElement}return document.body||document.head||document.documentElement}function applyAttr(e,r,t){if(t===false)return;var n=t===true?\"\":String(t);if(K){N(K,e,[r,n])}else{e.setAttribute(r,n)}}var Me=null;var Ce=null;var Te=null;var xe=null;var Ee=null;var qe=null;var Be=null;var Ie=null;try{Me=MouseEvent;Ce=EventTarget.prototype.dispatchEvent;Te=Node.prototype.getRootNode;xe=X(Node.prototype,\"parentNode\").get;Ee=X(Node.prototype,\"ownerDocument\").get;qe=X(ShadowRoot.prototype,\"host\").get;Be=X(ShadowRoot.prototype,\"mode\").get;Ie=ShadowRoot}catch(e){}function inClosedShadowRoot(e){for(var r=0;r<64;r++){var t=N(Te,e,[]);if(!(t instanceof Ie))return false;if(N(Be,t,[])===\"closed\")return true;e=N(qe,t,[])}return true}function insertViaBridge(e,r){if(Q||!Me||!Ce||!Be)return\"no-bridge\";try{if(inClosedShadowRoot(e))return\"closed-shadow-root\";var t=j(null);t.relatedTarget=r;t.cancelable=true;t.composed=true;var n=new Me(ee,t);var a=N(Ce,e,[n])===false&&N(xe,r,[])===e;if(a)return null;return(N(Ee,e,[])||e)===document?\"no-bridge\":\"other-document\"}catch(e){return\"no-bridge\"}}function insertNode(e,r){var t=insertViaBridge(e,r);if(t===null)return null;if(V)N(V,e,[r]);else e.appendChild(r);return t}var Re=j(null);function reportBlockedStyle(e,r,t){if(Re[e])return;Re[e]=true;var n=t===\"closed-shadow-root\"?\"SourceMonkey can't exempt a style added inside a closed shadow root.\":t===\"other-document\"?\"SourceMonkey can't exempt a style added to another frame's document.\":\"SourceMonkey couldn't exempt it: its isolated-world helper wasn't loaded in this document yet.\";var a=\"The page's Content Security Policy blocked the style \"+r+\" added, so its rules don't apply. \"+n+\" Add @inject-into content to run\"+\" the script isolated from the page, where all its styles are exempt.\";try{console.info(\"[SourceMonkey:\"+e+\"] \"+a)}catch(e){}transportSend({type:\"sm:gm-dom-blocked\",scriptId:e,api:r,why:t}).catch(function(){})}function styleWasBlocked(e){try{if(e.type&&!/^text\\/css$/i.test(e.type))return false;return e.isConnected===true&&e.sheet===null}catch(e){return false}}var Ae={addStyle:function(e,r){var t=F?F(\"style\"):document.createElement(\"style\");t.textContent=String(r==null?\"\":r);var n=defaultParent();if(n){var a=insertNode(n,t);if(a!==null&&styleWasBlocked(t))reportBlockedStyle(e,\"GM_addStyle\",a)}return t},addElement:function(e,r,t,a){var o,i,u;if(r&&typeof r===\"object\"&&typeof r.nodeType===\"number\"){o=r;i=t;u=a}else{o=null;i=r;u=t}if(i==null||typeof i===\"string\"&&i.trim()===\"\"){throw new n(\"[SourceMonkey] GM_addElement: tag name is required\")}if(!o)o=defaultParentFor(i);var c=F?F(String(i)):document.createElement(String(i));if(u&&typeof u===\"object\"){var s=l(u);for(var f=0;f<s.length;f++){var d=s[f];if(d===\"textContent\"){c.textContent=String(u[d]==null?\"\":u[d])}else{try{applyAttr(c,d,u[d])}catch(e){}}}}if(o){var y=insertNode(o,c);if(y!==null&&String(i).toUpperCase()===\"STYLE\"&&styleWasBlocked(c)){reportBlockedStyle(e,\"GM_addElement\",y)}}return c}};var Oe=j(null);function ensureResourceBox(e){var r=Oe[e];if(r)return r;r={byName:j(null),textCache:j(null),urlCache:j(null)};Oe[e]=r;return r}function _resDecodeBase64(e){var r=atob(e);var t=r.length;var n=new Uint8Array(t);for(var a=0;a<t;a++)n[a]=r.charCodeAt(a);return n}var Ue={init:function(e,r){var t=ensureResourceBox(e);t.byName=j(null);t.textCache=j(null);t.urlCache=j(null);if(!r||typeof r!==\"object\")return;var n=l(r);for(var a=0;a<n.length;a++){var o=n[a];var i=r[o];if(i&&typeof i===\"object\"){t.byName[o]={b64:String(i.b64||\"\"),ct:String(i.ct||\"\")}}}},getText:function(e,r){var t=Oe[e];if(!t)return undefined;var n=String(r);if(N(G,t.textCache,[n]))return t.textCache[n];if(!N(G,t.byName,[n]))return undefined;var a=_resDecodeBase64(t.byName[n].b64);var o;try{o=new TextDecoder(\"utf-8\",{fatal:false}).decode(a)}catch(e){o=\"\"}t.textCache[n]=o;return o},getUrl:function(e,r){var t=Oe[e];if(!t)return undefined;var n=String(r);if(N(G,t.urlCache,[n]))return t.urlCache[n];if(!N(G,t.byName,[n]))return undefined;if(!H||!J)return undefined;var a=t.byName[n];var o=_resDecodeBase64(a.b64);var i=a.ct||\"application/octet-stream\";var u;try{u=new H([o],{type:i})}catch(e){return undefined}var l;try{l=J(u)}catch(e){return undefined}t.urlCache[n]=l;return l}};var je=j(null);var Le=1;var Ne=typeof TextDecoder===\"function\"?TextDecoder:null;var _e=Ne?Ne.prototype.decode:null;var De=b&&typeof b.fromBase64===\"function\"?b.fromBase64:null;var Pe=String.prototype.charCodeAt;var Xe=String.prototype.indexOf;var Ge=Symbol.iterator;var Fe=typeof DOMParser===\"function\"?DOMParser:null;var Ve=Fe?Fe.prototype.parseFromString:null;var Ke=typeof URL===\"function\"?URL:null;var We=null;var He=null;var Je=null;var ze=null;var Qe=null;var Ye=null;var $e=null;var Ze=null;var er=String.prototype.toLowerCase;var rr=String.prototype.slice;var tr=String.prototype.trim;var nr=String;var ar=null;var or=null;var ir=typeof FileReader===\"function\"?FileReader:null;var ur=null;var lr=null;var cr=null;var sr=null;var fr=null;var dr=typeof ArrayBuffer===\"function\"?ArrayBuffer.isView:null;var yr=null;var pr=null;var vr=null;(function(){function getter(e,r){var t=X(e,r);return t&&typeof t.get===\"function\"?t.get:null}try{var e=x(b.prototype);We=e.set;He=getter(e,\"buffer\");Je=getter(e,\"byteLength\")}catch(e){}try{ar=getter(Blob.prototype,\"size\");or=getter(Blob.prototype,\"type\");ur=FileReader.prototype.readAsArrayBuffer;lr=getter(FileReader.prototype,\"result\");cr=getter(FileReader.prototype,\"error\");sr=EventTarget.prototype.addEventListener;fr=getter(File.prototype,\"name\")}catch(e){}try{yr=FormData.prototype.entries;pr=x(N(yr,new FormData,[])).next}catch(e){}try{vr=URLSearchParams.prototype.toString}catch(e){}try{ze=getter(Ke.prototype,\"href\")}catch(e){}try{Qe=getter(Node.prototype,\"baseURI\")}catch(e){}try{var r=ReadableStreamDefaultController.prototype;Ye=r.enqueue;$e=r.close;Ze=r.error}catch(e){}})();function setOwn(e,r,t){var n=j(null);n.value=t;n.writable=true;n.enumerable=true;n.configurable=true;L(e,r,n)}function plainCopy(e){var r={};var t=l(e);for(var n=0;n<t.length;n++)setOwn(r,t[n],e[t[n]]);return r}function ownIterable(e){setOwn(e,Ge,function(){var r=0;return{next:function(){return r<e.length?{value:e[r++],done:false}:{value:undefined,done:true}}}});return e}function randomPart(){return N(o,i()*4294967296>>>0,[36])}function decodeBase64(e){if(De)return N(De,b,[e]);var r=M(e);var t=r.length;var n=new b(t);for(var a=0;a<t;a++)n[a]=N(Pe,r,[a]);return n}function charsetOf(e){if(typeof e!==\"string\")return\"\";var r=N(er,e,[]);var t=N(Xe,r,[\"charset=\"]);if(t<0)return\"\";var n=N(rr,r,[t+8]);var a=N(Xe,n,[\";\"]);if(a>=0)n=N(rr,n,[0,a]);n=N(tr,n,[]);if(n.length>1&&(n[0]==='\"'||n[0]===\"'\"))n=N(rr,n,[1,-1]);return n}function responseDecoder(e,r){var t=e.responseType===\"json\"?\"\":charsetOf(e.overrideMimeType)||charsetOf(r);if(t){try{return new Ne(t)}catch(e){}}return new Ne}function responseMime(e,r){return typeof e.overrideMimeType===\"string\"&&e.overrideMimeType?e.overrideMimeType:r||\"\"}function encodeRequestBody(e,r,t){if(e===undefined||e===null)return t(bare({}));if(typeof e===\"string\"){if(!r)return t(bare({data:e}));var n=new b(e.length);for(var a=0;a<e.length;a++)n[a]=N(Pe,e,[a])&255;return t(bare({body:bare({kind:\"bytes\",data:bytesToBase64(n),type:\"\"})}))}if(typeof e!==\"object\")return t(bare({data:nr(e)}));var o=null;try{o=N(yr,e,[])}catch(e){}if(o){var i=[];for(;;){var u=N(pr,o,[]);if(u.done)break;setOwn(i,i.length,u.value)}var l=jsonArray();var next=function(e){if(e===i.length)return t(bare({body:bare({kind:\"form\",entries:l})}));var r=nr(i[e][0]);var n=i[e][1];if(typeof n===\"string\"){setOwn(l,l.length,bare({name:r,value:n}));return next(e+1)}readBlob(n,function(a){if(typeof a!==\"string\")return t(a);setOwn(l,l.length,bare({name:r,data:a,filename:N(fr,n,[]),type:N(or,n,[])}));next(e+1)})};return next(0)}try{return t(bare({body:bare({kind:\"params\",data:N(vr,e,[])})}))}catch(e){}var c=false;try{N(ar,e,[]);c=true}catch(e){}var s=false;try{N(B,e,[]);s=true}catch(e){}if(c||s||dr&&dr(e)){var f=c?e:new H(ownIterable([e]));var d=c?N(or,e,[]):\"\";return readBlob(f,function(e){if(typeof e!==\"string\")return t(e);t(bare({body:bare({kind:\"bytes\",data:e,type:d})}))})}t(bare({data:nr(e)}))}function jsonArray(){var e=[];var r=j(null);r.value=undefined;L(e,\"toJSON\",r);return e}function readBlob(e,r){var t;try{t=new ir;var a=j(null);a.once=true;N(sr,t,[\"loadend\",function(){var e=N(lr,t,[]);if(!e){var a=N(cr,t,[]);return r(new n(nr(a&&a.message||\"The body could not be read\")))}try{r(bytesToBase64(new b(e)))}catch(e){r(e)}},a]);N(ur,t,[e])}catch(e){r(e instanceof n?e:new n(nr(e)))}}var hr=typeof reportError===\"function\"?reportError:null;function reportCallbackError(e){if(!(e instanceof n)){try{console.info(\"[SourceMonkey] A callback threw:\",e)}catch(e){}return}if(hr){try{N(hr,self,[e]);return}catch(e){}}_(function(){throw e},0)}function isTextResponseType(e){return e!==\"blob\"&&e!==\"arraybuffer\"&&e!==\"stream\"}function xhrBodyStream(e,r){var t=j(null);t.start=function(e){r.streamController=e};t.cancel=function(){r.streamController=null;if(je[e]===r)abortRequest(e)};return new C(t)}function xhrState(e){var r=e.head;return{readyState:e.readyState,status:r?r.status:0,statusText:r?r.statusText:\"\",finalUrl:r?r.finalUrl:e.url,responseHeaders:r?r.responseHeaders:\"\",responseText:e.text,response:e.stream?e.stream:e.text!==\"\"&&(e.responseType===\"\"||e.responseType===\"text\")?e.text:null,context:e.context}}function setReadyState(e,r){e.readyState=r;callXhrCallback(e.onreadystatechange,xhrState(e))}function xhrStarted(e){if(e.readyState>0)return;e.readyState=1;callXhrCallback(e.onloadstart,xhrState(e))}function streamXhrEvent(e,r){var t=je[e];if(!t)return;armXhrTtl(e,t);var live=function(){return je[e]===t};xhrStarted(t);if(!live())return;if(r.kind===\"headers\"){t.head=r;t.total=typeof r.total===\"number\"?r.total:null;if(t.decodes)t.decoder=responseDecoder(t,r.mimeType);setReadyState(t,2);return}if(t.decodes&&!t.decoder)t.decoder=responseDecoder(t,\"\");var n=decodeBase64(r.data);try{if(t.decoder)t.text+=N(_e,t.decoder,[n,{stream:true}]);else if(t.stream){if(t.streamController)N(Ye,t.streamController,[n])}else setOwn(t.pieces,t.pieces.length,n)}catch(r){failXhrBody(e,r);return}t.loaded=r.loaded;if(t.readyState<3)setReadyState(t,3);if(!live())return;var a=xhrState(t);setOwn(a,\"lengthComputable\",t.total!==null);setOwn(a,\"loaded\",t.loaded);setOwn(a,\"total\",t.total!==null?t.total:0);callXhrCallback(t.onprogress,a)}function failXhrBody(e,r){stopXhrInWorker(e);dispatchXhrEvent(e,{kind:\"error\",message:tooLargeMessage(r)})}function tooLargeMessage(e){return\"[SourceMonkey] GM_xmlhttpRequest: The response is too large for the page to hold (\"+String(e&&e.message||e)+\"). For a large file, use responseType 'blob' or 'stream'\"}function stopXhrInWorker(e){try{Kr.sendAsync({type:\"sm:gm-xhr-abort\",id:e}).catch(function(){})}catch(e){}}function finishXhrBody(e,r){var t=e.responseType;var n=responseMime(e,r.responseMimeType);if(e.stream){setOwn(r,\"responseText\",\"\");setOwn(r,\"response\",e.stream);if(e.streamController){try{N($e,e.streamController,[])}catch(e){}}return}if(!e.decodes){setOwn(r,\"responseText\",\"\");if(t===\"blob\"){var a=j(null);a.type=n;setOwn(r,\"response\",new H(ownIterable(e.pieces),a))}else{var o=0;for(var i=0;i<e.pieces.length;i++)o+=N(Je,e.pieces[i],[]);var u=new b(o);var l=0;for(var c=0;c<e.pieces.length;c++){N(We,u,[e.pieces[c],l]);l+=N(Je,e.pieces[c],[])}setOwn(r,\"response\",N(He,u,[]))}e.pieces=[];return}var s=e.text+(e.decoder?N(_e,e.decoder,[]):\"\");setOwn(r,\"responseText\",s);var f;if(t===\"json\"){try{f=oe(s)}catch(e){f=null}}else if(t===\"document\"){var d=N(Xe,n,[\"xml\"])!==-1?\"application/xml\":\"text/html\";try{f=N(Ve,new Fe,[s,d])}catch(e){f=null}}else{f=s}setOwn(r,\"response\",f)}function dispatchXhrEvent(e,r){var t=je[e];if(!t)return;delete je[e];settleXhr(t,r,false)}function abortRequest(e){var r=je[e];if(!r)return;delete je[e];stopXhrInWorker(e);if(r.ttlTimer){try{D(r.ttlTimer)}catch(e){}r.ttlTimer=null}_(function(){settleXhr(r,bare({kind:\"abort\"}),true)},0)}function settleXhr(e,r,t){if(e.ttlTimer){try{D(e.ttlTimer)}catch(e){}}e.readyState=4;var a;var o=r.kind;if(o===\"load\"&&r.response&&typeof r.response===\"object\"){try{a=plainCopy(bare(r.response));finishXhrBody(e,a);setOwn(a,\"readyState\",4);setOwn(a,\"context\",e.context)}catch(r){o=\"error\";a=emptyXhrResponse(e);setOwn(a,\"error\",tooLargeMessage(r))}}else{a=emptyXhrResponse(e);if(o===\"error\")setOwn(a,\"error\",r.message);if(e.stream){setOwn(a,\"response\",e.stream);if(e.streamController){var i=o===\"error\"?new n(r.message||\"[SourceMonkey] GM_xmlhttpRequest: The request failed\"):new T(o===\"timeout\"?\"[SourceMonkey] GM_xmlhttpRequest: The request timed out\":\"[SourceMonkey] GM_xmlhttpRequest: The request was aborted\",o===\"timeout\"?\"TimeoutError\":\"AbortError\");try{N(Ze,e.streamController,[i])}catch(e){}e.streamController=null}}}var u;if(o===\"load\")u=e.onload;else if(o===\"error\")u=e.onerror;else if(o===\"timeout\")u=e.ontimeout;else if(o===\"abort\")u=e.onabort;if(!t)callXhrCallback(e.onreadystatechange,a);callXhrCallback(u,a);callXhrCallback(e.onloadend,a);if(e.settle)e.settle(o===\"load\",a)}function emptyXhrResponse(e){return{readyState:4,status:0,statusText:\"\",responseText:\"\",response:null,responseHeaders:\"\",finalUrl:e.head?e.head.finalUrl:e.url,context:e.context}}function callXhrCallback(e,r){if(typeof e!==\"function\")return;try{e(r)}catch(e){reportCallbackError(e)}}var gr=5*60*1e3;function armXhrTtl(e,r){if(r.ttlTimer){try{D(r.ttlTimer)}catch(e){}}r.ttlTimer=_(function(){stopXhrInWorker(e);dispatchXhrEvent(e,{kind:\"error\",message:\"[SourceMonkey] GM_xmlhttpRequest: No message from SourceMonkey for \"+gr/6e4+\" minutes, so the page stopped waiting for this request\"})},gr)}onPush(function(e){if(e.type!==\"sm:gm-xhr-event\")return;if(typeof e.id!==\"string\"||!e.event||typeof e.event!==\"object\")return;var r=bare(e.event);if(r.kind===\"headers\"||r.kind===\"progress\")streamXhrEvent(e.id,r);else dispatchXhrEvent(e.id,r)});function urlArg(e){if(e===null||typeof e!==\"object\")return e;try{return N(ze,e,[])}catch(e){}return typeof e.href===\"string\"&&!(\"url\"in e)?e.href:e}var mr={start:function(e,r,a){if(!r||typeof r!==\"object\"){var o=new n(\"[SourceMonkey] GM_xmlhttpRequest: details object required\");if(a)return guarded(new t(function(e,r){r(o)}));throw o}r=bare(r);var i=null;var u=null;if(a){u=guarded(new t(function(e,r){i=function(t,n){if(!t)return r(n);setOwnBare(n,\"then\",undefined);e(n)}}))}var l=u||{};var c=urlArg(r.url);if(typeof c!==\"string\"||!c){var s=new n(\"[SourceMonkey] GM_xmlhttpRequest: url required\");if(typeof r.onerror!==\"function\"&&!u)throw s;callXhrCallback(r.onerror,s);if(i)i(false,s);setOwn(l,\"abort\",function(){});return l}c=resolvePageUrl(c);var f=\"xhr-\"+Le+++\"-\"+randomPart();var d=typeof r.responseType===\"string\"?r.responseType:\"\";var y={onloadstart:r.onloadstart,onprogress:r.onprogress,onreadystatechange:r.onreadystatechange,onload:r.onload,onerror:r.onerror,ontimeout:r.ontimeout,onabort:r.onabort,onloadend:r.onloadend,url:c,responseType:d,overrideMimeType:r.overrideMimeType,context:r.context,settle:i,ttlTimer:null,readyState:0,head:null,total:null,loaded:0,decodes:isTextResponseType(d),decoder:null,text:\"\",pieces:[],stream:null,streamController:null};if(d===\"stream\"&&C)y.stream=xhrBodyStream(f,y);je[f]=y;armXhrTtl(f,y);var p=j(null);p.method=typeof r.method===\"string\"?r.method:\"GET\";p.url=c;p.headers=plainHeaders(r.headers);p.timeout=typeof r.timeout===\"number\"?r.timeout:undefined;p.responseType=typeof r.responseType===\"string\"?r.responseType:undefined;p.anonymous=r.anonymous?true:undefined;p.nocache=r.nocache?true:undefined;p.revalidate=r.revalidate?true:undefined;p.redirect=typeof r.redirect===\"string\"?r.redirect:undefined;var send=function(r){if(je[f]!==y)return;if(r instanceof n){xhrStarted(y);dispatchXhrEvent(f,{kind:\"error\",message:\"[SourceMonkey] GM_xmlhttpRequest: Could not read the request body: \"+nr(r.message||r)});return}p.data=r.data;p.body=r.body;var t=j(null);t.type=\"sm:gm-xhr-start\";t.id=f;t.scriptId=e;t.request=p;Kr.sendAsync(t).then(function(e){if(e&&e.ok===true){var r=je[f];if(r)xhrStarted(r);return}var t=je[f];if(t)xhrStarted(t);var n=e&&e.error||\"SourceMonkey did not accept the request\";dispatchXhrEvent(f,{kind:\"error\",message:\"[SourceMonkey] GM_xmlhttpRequest: \"+n})},function(e){var r=je[f];if(r)xhrStarted(r);dispatchXhrEvent(f,{kind:\"error\",message:String(e&&e.message||e)})})};try{encodeRequestBody(r.data,!!r.binary,send)}catch(e){send(e instanceof n?e:new n(nr(e)))}setOwn(l,\"abort\",function(){abortRequest(f)});return l}};var br=null;try{if(typeof console!==\"undefined\"&&typeof console.log===\"function\"){br=console.log.bind(console)}}catch(e){}var _renderArg=function(e){if(e===null)return\"null\";if(e===undefined)return\"undefined\";var r=typeof e;if(r===\"string\")return e;if(r===\"number\"||r===\"boolean\"||r===\"bigint\")return String(e);if(r===\"function\")return\"[Function: \"+(e.name||\"anonymous\")+\"]\";if(e instanceof Error){var t=\"\";try{t=e.stack?\"\\n\"+e.stack:\"\"}catch(e){}return String(e.message||e)+t}try{return JSON.stringify(e)}catch(e){}try{return String(e)}catch(e){return\"[unserializable]\"}};var _renderArgs=function(e){var r=[];for(var t=0;t<e.length;t++)r.push(_renderArg(e[t]));return r.join(\" \")};var wr={write:function(e,r){if(br){var t=[\"[SourceMonkey:\"+e+\"]\"];for(var n=0;n<r.length;n++)t.push(r[n]);try{N(br,null,t)}catch(e){}}try{var a=_renderArgs(r);var o=transportSend({type:\"sm:gm-log\",scriptId:e,message:a});if(o&&typeof o.catch===\"function\")o.catch(function(){})}catch(e){}}};var Sr=j(null);var kr=1;var Mr={open:function(e,r,t){r=urlArg(r);if(typeof r!==\"string\"||!r){throw new n(\"[SourceMonkey] GM_openInTab: url required\")}var a=true;var o=false;if(typeof t===\"boolean\"){a=!t}else if(t&&typeof t===\"object\"){if(typeof t.active===\"boolean\")a=t.active;else if(typeof t.loadInBackground===\"boolean\")a=!t.loadInBackground;if(typeof t.insert===\"boolean\")o=t.insert}var i=\"tab-\"+kr+++\"-\"+Math.random().toString(36).slice(2,10);var u={closed:false,onclose:null,tabId:null};Sr[i]=u;var l={get closed(){return u.closed},set onclose(e){u.onclose=typeof e===\"function\"?e:null},get onclose(){return u.onclose},close:function(){if(u.closed)return;Kr.sendAsync({type:\"sm:gm-tab-close\",requestId:i}).catch(function(){})}};Kr.sendAsync({type:\"sm:gm-tab-open\",scriptId:e,requestId:i,url:r,active:a,insert:o}).then(function(e){if(e&&e.ok&&typeof e.tabId===\"number\"){u.tabId=e.tabId}else{var r=e&&e.error||\"SourceMonkey did not accept the request\";try{console.info(\"[SourceMonkey] GM_openInTab failed:\",r)}catch(e){}dispatchTabClose(i)}},function(e){try{console.info(\"[SourceMonkey] GM_openInTab send failed:\",e&&e.message||e)}catch(e){}dispatchTabClose(i)});return l}};function dispatchTabClose(e){var r=Sr[e];if(!r||r.closed)return;r.closed=true;delete Sr[e];var t=r.onclose;if(typeof t===\"function\"){try{t()}catch(e){reportCallbackError(e)}}}function tabDataCall(e,r,t){var a=Kr.sendAsync(r).then(function(r){if(r&&r.ok)return r.value;throw new n(\"[SourceMonkey] \"+e+\": \"+(r&&r.error||\"SourceMonkey sent no reply\"))});a.then(function(r){if(typeof t!==\"function\")return;try{t(r)}catch(r){try{console.info(\"[SourceMonkey] \"+e+\" callback threw:\",r)}catch(e){}}},function(r){var t=r&&r.message||String(r);if(t.indexOf(\"[SourceMonkey]\")!==0)t=\"[SourceMonkey] \"+e+\": \"+t;try{console.info(t)}catch(e){}});return typeof t===\"function\"?undefined:a}var Cr={get:function(e,r){return tabDataCall(\"GM_getTab\",{type:\"sm:gm-tab-data\",scriptId:e,action:\"get\"},r)},save:function(e,r,t){var n=r;if(r!=null&&typeof r===\"object\"){n={};var a=l(r);for(var o=0;o<a.length;o++)n[a[o]]=r[a[o]]}return tabDataCall(\"GM_saveTab\",{type:\"sm:gm-tab-data\",scriptId:e,action:\"save\",data:n},t)},list:function(e,r){return tabDataCall(\"GM_getTabs\",{type:\"sm:gm-tab-data\",scriptId:e,action:\"list\"},r)}};var Tr=j(null);var xr=1;var Er={show:function(e,r){var a=null;var o=null;var i=null;if(r[0]&&typeof r[0]===\"object\"){var u=r[0];a={text:u.text!=null?String(u.text):\"\",title:u.title!=null?String(u.title):\"\",image:u.image!=null?String(u.image):\"\",timeout:typeof u.timeout===\"number\"?u.timeout:0,silent:!!u.silent,tag:u.tag!=null?String(u.tag):\"\"};if(typeof u.onclick===\"function\")o=u.onclick;if(typeof u.ondone===\"function\")i=u.ondone;if(typeof r[1]===\"function\")i=r[1]}else{a={text:r[0]!=null?String(r[0]):\"\",title:r[1]!=null?String(r[1]):\"\",image:r[2]!=null?String(r[2]):\"\",timeout:0,silent:false,tag:\"\"};if(typeof r[3]===\"function\")o=r[3]}if(!a.text){return t.reject(new n(\"[SourceMonkey] GM_notification: `text` is required\"))}var l=\"notif-\"+xr+++\"-\"+Math.random().toString(36).slice(2,10);Tr[l]={onclick:o,ondone:i};return Kr.sendAsync({type:\"sm:gm-notification-show\",scriptId:e,requestId:l,details:a}).then(function(e){if(!e||!e.ok){delete Tr[l];throw new n(\"[SourceMonkey] GM_notification: \"+(e&&e.error||\"show failed\"))}return e.notificationId},function(e){delete Tr[l];throw e})}};function dispatchNotificationEvent(e,r){var t=Tr[e];if(!t)return;if(r===\"clicked\"){var n=t.onclick;if(typeof n===\"function\"){try{n()}catch(e){reportCallbackError(e)}}}else if(r===\"closed\"){delete Tr[e];var a=t.ondone;if(typeof a===\"function\"){try{a()}catch(e){reportCallbackError(e)}}}}var qr=j(null);var Br=1;var Ir=250;function normalizeDownloadArgs(e,r){var t=null;e=urlArg(e);if(typeof e===\"string\"){t={url:e,name:r}}else if(e&&typeof e===\"object\"){t=e}else{throw new n(\"[SourceMonkey] GM_download: details object or url required\")}var a=urlArg(t.url);if(typeof a!==\"string\"||!a){throw new n(\"[SourceMonkey] GM_download: url required\")}return{url:resolvePageUrl(a),name:t.name!=null?String(t.name):\"\",headers:plainHeaders(t.headers),saveAs:!!t.saveAs,timeout:typeof t.timeout===\"number\"?t.timeout:0,onload:typeof t.onload===\"function\"?t.onload:null,onerror:typeof t.onerror===\"function\"?t.onerror:null,ontimeout:typeof t.ontimeout===\"function\"?t.ontimeout:null,onprogress:typeof t.onprogress===\"function\"?t.onprogress:null,onabort:typeof t.onabort===\"function\"?t.onabort:null}}function resolvePageUrl(e){try{var r=Qe&&N(Qe,document,[])||location.href;return N(ze,new Ke(e,r),[])}catch(r){return e}}function plainHeaders(e){if(!e||typeof e!==\"object\")return undefined;var r=null;var t=l(e);for(var n=0;n<t.length;n++){var a=e[t[n]];if(c(a)){var o=\"\";for(var i=0;i<a.length;i++){var u=a[i];if(u!==null&&(typeof u===\"object\"||typeof u===\"function\"||typeof u===\"symbol\")){o=null;break}o+=(i?\",\":\"\")+(u===undefined||u===null?\"\":u)}if(o===null)continue;a=o}if(a===undefined||typeof a===\"function\"||typeof a===\"symbol\"||a!==null&&typeof a===\"object\")continue;if(!r)r=j(null);r[t[n]]=\"\"+a}return r||undefined}function isInPageDownloadUrl(e){var r=\"\";try{r=new URL(e).protocol}catch(e){return false}return r===\"blob:\"||r===\"data:\"}function downloadViaAnchor(e,r){try{var t=F?F(\"a\"):document.createElement(\"a\");t.href=e;t.download=r||\"\";t.style.display=\"none\";var n=document.body||document.documentElement;if(!n)return\"no document to append the download anchor to\";if(V)N(V,n,[t]);else n.appendChild(t);try{t.click()}finally{try{n.removeChild(t)}catch(e){}}return null}catch(e){return String(e&&e.message||e)}}var Rr={start:function(e,r,t){var n=normalizeDownloadArgs(r,t);var a=\"dl-\"+Br+++\"-\"+Math.random().toString(36).slice(2,10);var o=isInPageDownloadUrl(n.url);qr[a]={onload:n.onload,onerror:n.onerror,ontimeout:n.ontimeout,onprogress:n.onprogress,onabort:n.onabort,transport:o?\"page\":\"sw\"};if(o){var i=downloadViaAnchor(n.url,n.name);if(i!==null){_(function(){dispatchDownloadEvent(a,{kind:\"error\",error:\"not_succeeded\",details:{message:i}})},0)}else{_(function(){dispatchDownloadEvent(a,{kind:\"load\",downloadId:-1,filename:n.name,finalUrl:n.url,totalBytes:0})},Ir)}}else{Kr.sendAsync({type:\"sm:gm-download-start\",scriptId:e,requestId:a,url:n.url,name:n.name,headers:n.headers,saveAs:n.saveAs,timeout:n.timeout,wantsProgress:!!n.onprogress}).then(function(e){if(e&&e.ok===true)return;dispatchDownloadEvent(a,{kind:\"error\",error:\"not_supported\",details:{message:e&&e.error||\"SourceMonkey did not accept the request\"}})},function(e){dispatchDownloadEvent(a,{kind:\"error\",error:\"not_supported\",details:{message:String(e&&e.message||e)}})})}return{abort:function(){var e=qr[a];if(!e)return;if(e.transport===\"sw\"){Kr.sendAsync({type:\"sm:gm-download-abort\",requestId:a}).catch(function(){})}dispatchDownloadEvent(a,{kind:\"error\",error:\"download_canceled\",details:{current:\"USER_CANCELED\"}})}}}};function dispatchDownloadEvent(e,r){var t=qr[e];if(!t)return;if(r.kind===\"progress\"){if(typeof t.onprogress!==\"function\")return;try{t.onprogress({lengthComputable:!!r.lengthComputable,loaded:r.loaded,total:r.total})}catch(e){reportCallbackError(e)}return}delete qr[e];var n=null;var a=null;if(r.kind===\"load\"){n=t.onload;a={downloadId:r.downloadId,filename:r.filename,finalUrl:r.finalUrl,totalBytes:r.totalBytes}}else if(r.kind===\"timeout\"){n=t.ontimeout;a={}}else if(r.kind===\"error\"){a={error:r.error,details:r.details||{}};n=r.error===\"download_canceled\"&&typeof t.onabort===\"function\"?t.onabort:t.onerror}if(typeof n!==\"function\")return;try{n(a)}catch(e){reportCallbackError(e)}}var Ar=j(null);var Or=1;function ensureMenuScript(e){var r=Ar[e];if(r)return r;r=j(null);Ar[e]=r;return r}var Ur={register:function(e,r,t,a){if(typeof t!==\"function\"){throw new n(\"[SourceMonkey] GM_registerMenuCommand: callback must be a function\")}var o;if(a&&typeof a===\"object\"&&a.id!=null){o=String(a.id)}else{o=\"mc-\"+Or+++\"-\"+Math.random().toString(36).slice(2,10)}ensureMenuScript(e)[o]=t;var i=String(r==null?\"\":r);Kr.sendAsync({type:\"sm:gm-menu-register\",scriptId:e,commandId:o,name:i}).catch(function(e){try{console.info(\"[SourceMonkey] GM_registerMenuCommand send failed:\",e&&e.message||e)}catch(e){}});return o},unregister:function(e,r){var t=String(r);var n=Ar[e];if(n&&N(G,n,[t]))delete n[t];Kr.sendAsync({type:\"sm:gm-menu-unregister\",scriptId:e,commandId:t}).catch(function(e){try{console.info(\"[SourceMonkey] GM_unregisterMenuCommand send failed:\",e&&e.message||e)}catch(e){}})}};function retireMenuCommands(e){var r=Ar[e];if(!r)return;var t=l(r);for(var n=0;n<t.length;n++)Ur.unregister(e,t[n])}function dispatchMenuFire(e,r){var t=Ar[e];if(!t)return;var n=t[r];if(typeof n!==\"function\")return;try{n()}catch(e){reportCallbackError(e)}}var jr=false;var Lr=false;var Nr=[];var _r=null;var Dr=null;var Pr=null;var Xr=null;function addUrlChangeHandler(e){if(typeof e!==\"function\")return;if(Nr.indexOf(e)!==-1)return;Nr.push(e)}function removeUrlChangeHandler(e){var r=Nr.indexOf(e);if(r!==-1)Nr.splice(r,1)}function makeUrlChangeInfo(e){var r=j(null);r.url=e;return r}function dispatchUrlChange(e){if(Nr.length===0)return;var r=Nr.slice();var t=makeUrlChangeInfo(e);for(var n=0;n<r.length;n++){var a=r[n];try{a(t)}catch(e){reportCallbackError(e)}}}function noteUrlChanged(e){if(!jr)return;if(typeof e!==\"string\"||e===\"\")return;dispatchUrlChange(e)}function isUrlChangeType(e){return e===\"urlchange\"}function ensureUrlChangeProperty(){if(N(G,window,[\"onurlchange\"]))return;try{L(window,\"onurlchange\",{get:function(){return _r},set:function(e){_r=e===undefined?null:e;if(typeof e===\"function\"){if(!Dr){Dr=function(e){if(typeof _r===\"function\")_r(e)}}addUrlChangeHandler(Dr)}else if(e!==null&&e!==undefined){try{console.info(\"[SourceMonkey] window.onurlchange must be a function; ignoring\",typeof e)}catch(e){}}},configurable:true,enumerable:true})}catch(e){}}function ensureUrlChangePatch(){if(Lr)return true;var e=null;var r=null;try{e=window.addEventListener;r=window.removeEventListener;window.addEventListener=function(e,r){if(isUrlChangeType(e)){addUrlChangeHandler(r);return undefined}return N(Pr,this==null?window:this,arguments)};window.removeEventListener=function(e,r){if(isUrlChangeType(e)){removeUrlChangeHandler(r);return undefined}return N(Xr,this==null?window:this,arguments)};Pr=e;Xr=r;Lr=true;return true}catch(t){try{window.addEventListener=e}catch(e){}try{window.removeEventListener=r}catch(e){}return false}}function installUrlChange(){if(!ensureUrlChangePatch())return;jr=true;ensureUrlChangeProperty();if(!r.liveWindowNames){var e=j(null);e.onurlchange=true;e.addEventListener=true;e.removeEventListener=true;r.liveWindowNames=e}}var Gr={enable:function(e){installUrlChange()}};var Fr=j(null);function isTopFrame(){try{return window.top===window.self}catch(e){return false}}function makeWindowControl(e,r){if(r!==\"close\"&&r!==\"focus\")return undefined;if(r===\"close\"&&!isTopFrame())return undefined;var t=r===\"close\"?\"sm:gm-window-close\":\"sm:gm-window-focus\";return function(){try{var n=Kr.sendAsync({type:t,scriptId:e});if(n&&typeof n.then===\"function\"){n.then(function(e){if(e&&e.ok)return;var t=e&&e.error?e.error:\"SourceMonkey sent no reply\";try{console.info(\"[SourceMonkey] window.\"+r+\":\",t)}catch(e){}},function(e){try{console.info(\"[SourceMonkey] window.\"+r+\" send failed:\",e&&e.message||e)}catch(e){}})}}catch(e){try{console.info(\"[SourceMonkey] window.\"+r+\" failed:\",e)}catch(e){}}return undefined}}function installWindowControl(e,r){if(Fr[r])return;var t=makeWindowControl(e,r);if(!t)return;try{L(window,r,{value:t,writable:true,configurable:true,enumerable:true});Fr[r]=true}catch(e){try{window[r]=t;Fr[r]=true}catch(e){}}}var Vr={enable:function(e,r){if(r!==\"close\"&&r!==\"focus\")return;installWindowControl(e,r)},make:makeWindowControl};onPush(function(e){if(e.type===\"sm:gm-tab-closed\"&&typeof e.requestId===\"string\"){dispatchTabClose(e.requestId)}else if(e.type===\"sm:gm-notification-event\"&&typeof e.requestId===\"string\"&&typeof e.event===\"string\"){dispatchNotificationEvent(e.requestId,e.event)}else if(e.type===\"sm:gm-menu-fire\"&&typeof e.scriptId===\"string\"&&typeof e.commandId===\"string\"){dispatchMenuFire(e.scriptId,e.commandId)}else if(e.type===\"sm:gm-download-event\"&&typeof e.requestId===\"string\"&&e.event){dispatchDownloadEvent(e.requestId,e.event)}else if(e.type===\"sm:url-change\"&&typeof e.url===\"string\"){noteUrlChanged(e.url)}});var Kr={sendAsync:function(e){return transportSend(e)},storage:ke,dom:Ae,resource:Ue,xhr:mr,log:wr,tab:Mr,tabData:Cr,notification:Er,download:Rr,menu:Ur,retireRun:function(e){retireMenuCommands(e);var r=ye[e];if(r)r.listeners=null},urlchange:Gr,windowControl:Vr,clipboard:{write:function(e){if(!W){return t.reject(new n(\"[SourceMonkey] navigator.clipboard.writeText unavailable\"))}try{return W(String(e==null?\"\":e))}catch(e){return t.reject(e)}}}};try{Object.defineProperty(r,\"gm\",{value:Kr,enumerable:true})}catch(e){r.gm=Kr}})();";
|