From 387a674132a1bcd3bfcf5e74e852832a7b3d82b2 Mon Sep 17 00:00:00 2001 From: tophf Date: Thu, 27 Jun 2024 19:07:52 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20master=20from=20source=20@=20f?= =?UTF-8?q?4f8afbb72aa28d48af9ef336e77bfda97780083=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 404.html | 67 + 404/index.html | 67 + _gatsby/slices/_gatsby-scripts-1.html | 7 + api/gm/index.html | 931 ++++++++ api/matching/index.html | 180 ++ api/metadata-block/index.html | 249 +++ app-34a1f4a0ffa1cb3f26bf.js | 3 + app-34a1f4a0ffa1cb3f26bf.js.LICENSE.txt | 39 + app-34a1f4a0ffa1cb3f26bf.js.map | 1 + ...07d707efd756d62ecd-136fbf9ff633dfdf85f8.js | 2 + ...07efd756d62ecd-136fbf9ff633dfdf85f8.js.map | 1 + chunk-map.json | 1 + ...--src-pages-404-js-46b68fb482f8da1ad363.js | 2 + ...c-pages-404-js-46b68fb482f8da1ad363.js.map | 1 + ...src-pages-posts-js-fc6fa34bb65b110d3292.js | 2 + ...pages-posts-js-fc6fa34bb65b110d3292.js.map | 1 + ...-content-api-gm-md-e370c49c5015bc169b2e.js | 2 + ...tent-api-gm-md-e370c49c5015bc169b2e.js.map | 1 + ...nt-api-matching-md-12c8796b550f6b5ade8f.js | 2 + ...pi-matching-md-12c8796b550f6b5ade8f.js.map | 1 + ...-metadata-block-md-6bc422df2ff381e778f7.js | 2 + ...adata-block-md-6bc422df2ff381e778f7.js.map | 1 + ...ntent-faq-index-md-570cb893b4552d45d4df.js | 2 + ...t-faq-index-md-570cb893b4552d45d4df.js.map | 1 + ...nt-get-it-index-md-7caef1d57daa91eb9b82.js | 2 + ...et-it-index-md-7caef1d57daa91eb9b82.js.map | 1 + ...serscript-index-md-843b89f58ed3a115133a.js | 2 + ...cript-index-md-843b89f58ed3a115133a.js.map | 1 + ...hortcuts-index-mdx-3c2d1730a5d846490a0d.js | 2 + ...cuts-index-mdx-3c2d1730a5d846490a0d.js.map | 1 + ...rving-dom-index-md-540390cb26964b66dd2c.js | 2 + ...g-dom-index-md-540390cb26964b66dd2c.js.map | 1 + ...rn-syntax-index-md-2249f80f32a7a98a58a1.js | 2 + ...yntax-index-md-2249f80f32a7a98a58a1.js.map | 1 + ...h-content-index-md-99e05bcd09b9b9588c13.js | 2 + ...ntent-index-md-99e05bcd09b9b9588c13.js.map | 1 + ...alization-index-md-21f86dacb5097cae5177.js | 2 + ...ation-index-md-21f86dacb5097cae5177.js.map | 1 + ...cript-generator-md-248b5772daa83c5e648f.js | 2 + ...t-generator-md-248b5772daa83c5e648f.js.map | 1 + ...te-editor-index-md-8f2f374171e9f3a50200.js | 2 + ...ditor-index-md-8f2f374171e9f3a50200.js.map | 1 + ...ct-into-context-md-27c339db9032b21d3a6e.js | 2 + ...nto-context-md-27c339db9032b21d3a6e.js.map | 1 + ...-with-blob-urls-md-c36e1c51944e3bdec63f.js | 2 + ...h-blob-urls-md-c36e1c51944e3bdec63f.js.map | 1 + ...s-for-blacklist-md-2f2444b9de6e96c66a75.js | 2 + ...r-blacklist-md-2f2444b9de6e96c66a75.js.map | 1 + ...onkey-workflows-md-f9bd17ffd75d78c988ce.js | 2 + ...y-workflows-md-f9bd17ffd75d78c988ce.js.map | 1 + ...t-privacy-index-md-43ad4d0d12554942e98a.js | 2 + ...ivacy-index-md-43ad4d0d12554942e98a.js.map | 1 + ...s-install-beta-mdx-352287dcf7ae506f38b3.js | 2 + ...stall-beta-mdx-352287dcf7ae506f38b3.js.map | 1 + ...install-stable-mdx-4d79f994d595ea448b6a.js | 2 + ...all-stable-mdx-4d79f994d595ea448b6a.js.map | 1 + components/install-beta/index.html | 108 + components/install-stable/index.html | 148 ++ faq/index.html | 90 + favicon-32x32.png | Bin 0 -> 2542 bytes get-it/index.html | 251 +++ guide/creating-a-userscript/index.html | 119 ++ guide/keyboard-shortcuts/index.html | 121 ++ guide/observing-dom/index.html | 127 ++ guide/using-modern-syntax/index.html | 122 ++ icons/icon-144x144.png | Bin 0 -> 15546 bytes icons/icon-192x192.png | Bin 0 -> 26182 bytes icons/icon-256x256.png | Bin 0 -> 37511 bytes icons/icon-384x384.png | Bin 0 -> 88797 bytes icons/icon-48x48.png | Bin 0 -> 4394 bytes icons/icon-512x512.png | Bin 0 -> 143950 bytes icons/icon-72x72.png | Bin 0 -> 7266 bytes icons/icon-96x96.png | Bin 0 -> 10612 bytes index.html | 186 ++ localization/index.html | 89 + manifest.webmanifest | 1 + page-data/404.html/page-data.json | 1 + page-data/404/page-data.json | 1 + page-data/api/gm/page-data.json | 1 + page-data/api/matching/page-data.json | 1 + page-data/api/metadata-block/page-data.json | 1 + page-data/app-data.json | 1 + .../components/install-beta/page-data.json | 1 + .../components/install-stable/page-data.json | 1 + page-data/faq/page-data.json | 1 + page-data/get-it/page-data.json | 1 + .../creating-a-userscript/page-data.json | 1 + .../guide/keyboard-shortcuts/page-data.json | 1 + page-data/guide/observing-dom/page-data.json | 1 + .../guide/using-modern-syntax/page-data.json | 1 + page-data/index/page-data.json | 1 + page-data/localization/page-data.json | 1 + .../page-data.json | 1 + .../page-data.json | 1 + .../posts/inject-into-context/page-data.json | 1 + .../page-data.json | 1 + page-data/posts/page-data.json | 1 + .../smart-rules-for-blacklist/page-data.json | 1 + .../violentmonkey-workflows/page-data.json | 1 + page-data/privacy/page-data.json | 1 + page-data/sq/d/1116475411.json | 1 + page-data/sq/d/1700780748.json | 1 + page-data/sq/d/2344890832.json | 1 + page-data/sq/d/3202921338.json | 1 + page-data/sq/d/3798213247.json | 1 + polyfill-d4361b856f0eb8aaa3a2.js | 2 + polyfill-d4361b856f0eb8aaa3a2.js.map | 1 + .../index.html | 125 ++ .../index.html | 199 ++ posts/index.html | 67 + posts/inject-into-context/index.html | 129 ++ .../inject-scripts-with-blob-urls/index.html | 128 ++ posts/smart-rules-for-blacklist/index.html | 137 ++ posts/violentmonkey-workflows/index.html | 97 + privacy/index.html | 82 + sitemap-0.xml | 1 + sitemap-index.xml | 1 + .../222b7/editor-4.png | Bin 0 -> 1052 bytes .../98314/editor-4.png | Bin 0 -> 5936 bytes .../a6d36/editor-4.png | Bin 0 -> 9388 bytes .../ff46a/editor-4.png | Bin 0 -> 3224 bytes .../9d635/maxthon.png | Bin 0 -> 521 bytes .../9d635/github.png | Bin 0 -> 841 bytes .../1fbe8/match.png | Bin 0 -> 8985 bytes .../222b7/match.png | Bin 0 -> 1614 bytes .../a6d36/match.png | Bin 0 -> 11549 bytes .../ff46a/match.png | Bin 0 -> 4742 bytes .../222b7/editor-1.png | Bin 0 -> 1116 bytes .../e9131/editor-1.png | Bin 0 -> 4158 bytes .../ff46a/editor-1.png | Bin 0 -> 3189 bytes .../222b7/easy-1.png | Bin 0 -> 2092 bytes .../24c7e/easy-1.png | Bin 0 -> 5240 bytes .../ff46a/easy-1.png | Bin 0 -> 6572 bytes .../942f4/chrome.png | Bin 0 -> 1546 bytes .../9d635/firefox.png | Bin 0 -> 3070 bytes .../9d635/edge.png | Bin 0 -> 2466 bytes .../222b7/editor-2.png | Bin 0 -> 5233 bytes .../e9131/editor-2.png | Bin 0 -> 17488 bytes .../ff46a/editor-2.png | Bin 0 -> 20574 bytes .../13a9a/editor-3.png | Bin 0 -> 10454 bytes .../222b7/editor-3.png | Bin 0 -> 3442 bytes .../ff46a/editor-3.png | Bin 0 -> 10347 bytes .../vm-6437e4e5a400c6eff1c23ead4d549b0a.png | Bin 0 -> 10337 bytes styles.0d9914f9f88a16b032ba.css | 1 + sw.js | 13 + webpack-runtime-c1cfbe8f76e2d4cb7669.js | 2 + webpack-runtime-c1cfbe8f76e2d4cb7669.js.map | 1 + webpack.stats.json | 1 + ~partytown/debug/partytown-atomics.js | 572 +++++ ~partytown/debug/partytown-media.js | 374 ++++ ~partytown/debug/partytown-sandbox-sw.js | 559 +++++ ~partytown/debug/partytown-sw.js | 59 + ~partytown/debug/partytown-ww-atomics.js | 1881 +++++++++++++++++ ~partytown/debug/partytown-ww-sw.js | 1873 ++++++++++++++++ ~partytown/debug/partytown.js | 75 + ~partytown/partytown-atomics.js | 2 + ~partytown/partytown-media.js | 2 + ~partytown/partytown-sw.js | 2 + ~partytown/partytown.js | 2 + 159 files changed, 9393 insertions(+) create mode 100644 404.html create mode 100644 404/index.html create mode 100644 _gatsby/slices/_gatsby-scripts-1.html create mode 100644 api/gm/index.html create mode 100644 api/matching/index.html create mode 100644 api/metadata-block/index.html create mode 100644 app-34a1f4a0ffa1cb3f26bf.js create mode 100644 app-34a1f4a0ffa1cb3f26bf.js.LICENSE.txt create mode 100644 app-34a1f4a0ffa1cb3f26bf.js.map create mode 100644 c5a3695c8d75dc4f08b1dd07d707efd756d62ecd-136fbf9ff633dfdf85f8.js create mode 100644 c5a3695c8d75dc4f08b1dd07d707efd756d62ecd-136fbf9ff633dfdf85f8.js.map create mode 100644 chunk-map.json create mode 100644 component---src-pages-404-js-46b68fb482f8da1ad363.js create mode 100644 component---src-pages-404-js-46b68fb482f8da1ad363.js.map create mode 100644 component---src-pages-posts-js-fc6fa34bb65b110d3292.js create mode 100644 component---src-pages-posts-js-fc6fa34bb65b110d3292.js.map create mode 100644 component---src-templates-post-index-js-content-file-path-content-api-gm-md-e370c49c5015bc169b2e.js create mode 100644 component---src-templates-post-index-js-content-file-path-content-api-gm-md-e370c49c5015bc169b2e.js.map create mode 100644 component---src-templates-post-index-js-content-file-path-content-api-matching-md-12c8796b550f6b5ade8f.js create mode 100644 component---src-templates-post-index-js-content-file-path-content-api-matching-md-12c8796b550f6b5ade8f.js.map create mode 100644 component---src-templates-post-index-js-content-file-path-content-api-metadata-block-md-6bc422df2ff381e778f7.js create mode 100644 component---src-templates-post-index-js-content-file-path-content-api-metadata-block-md-6bc422df2ff381e778f7.js.map create mode 100644 component---src-templates-post-index-js-content-file-path-content-faq-index-md-570cb893b4552d45d4df.js create mode 100644 component---src-templates-post-index-js-content-file-path-content-faq-index-md-570cb893b4552d45d4df.js.map create mode 100644 component---src-templates-post-index-js-content-file-path-content-get-it-index-md-7caef1d57daa91eb9b82.js create mode 100644 component---src-templates-post-index-js-content-file-path-content-get-it-index-md-7caef1d57daa91eb9b82.js.map create mode 100644 component---src-templates-post-index-js-content-file-path-content-guide-creating-a-userscript-index-md-843b89f58ed3a115133a.js create mode 100644 component---src-templates-post-index-js-content-file-path-content-guide-creating-a-userscript-index-md-843b89f58ed3a115133a.js.map create mode 100644 component---src-templates-post-index-js-content-file-path-content-guide-keyboard-shortcuts-index-mdx-3c2d1730a5d846490a0d.js create mode 100644 component---src-templates-post-index-js-content-file-path-content-guide-keyboard-shortcuts-index-mdx-3c2d1730a5d846490a0d.js.map create mode 100644 component---src-templates-post-index-js-content-file-path-content-guide-observing-dom-index-md-540390cb26964b66dd2c.js create mode 100644 component---src-templates-post-index-js-content-file-path-content-guide-observing-dom-index-md-540390cb26964b66dd2c.js.map create mode 100644 component---src-templates-post-index-js-content-file-path-content-guide-using-modern-syntax-index-md-2249f80f32a7a98a58a1.js create mode 100644 component---src-templates-post-index-js-content-file-path-content-guide-using-modern-syntax-index-md-2249f80f32a7a98a58a1.js.map create mode 100644 component---src-templates-post-index-js-content-file-path-content-index-md-99e05bcd09b9b9588c13.js create mode 100644 component---src-templates-post-index-js-content-file-path-content-index-md-99e05bcd09b9b9588c13.js.map create mode 100644 component---src-templates-post-index-js-content-file-path-content-localization-index-md-21f86dacb5097cae5177.js create mode 100644 component---src-templates-post-index-js-content-file-path-content-localization-index-md-21f86dacb5097cae5177.js.map create mode 100644 component---src-templates-post-index-js-content-file-path-content-posts-features-in-userscript-generator-md-248b5772daa83c5e648f.js create mode 100644 component---src-templates-post-index-js-content-file-path-content-posts-features-in-userscript-generator-md-248b5772daa83c5e648f.js.map create mode 100644 component---src-templates-post-index-js-content-file-path-content-posts-how-to-edit-scripts-with-your-favorite-editor-index-md-8f2f374171e9f3a50200.js create mode 100644 component---src-templates-post-index-js-content-file-path-content-posts-how-to-edit-scripts-with-your-favorite-editor-index-md-8f2f374171e9f3a50200.js.map create mode 100644 component---src-templates-post-index-js-content-file-path-content-posts-inject-into-context-md-27c339db9032b21d3a6e.js create mode 100644 component---src-templates-post-index-js-content-file-path-content-posts-inject-into-context-md-27c339db9032b21d3a6e.js.map create mode 100644 component---src-templates-post-index-js-content-file-path-content-posts-inject-scripts-with-blob-urls-md-c36e1c51944e3bdec63f.js create mode 100644 component---src-templates-post-index-js-content-file-path-content-posts-inject-scripts-with-blob-urls-md-c36e1c51944e3bdec63f.js.map create mode 100644 component---src-templates-post-index-js-content-file-path-content-posts-smart-rules-for-blacklist-md-2f2444b9de6e96c66a75.js create mode 100644 component---src-templates-post-index-js-content-file-path-content-posts-smart-rules-for-blacklist-md-2f2444b9de6e96c66a75.js.map create mode 100644 component---src-templates-post-index-js-content-file-path-content-posts-violentmonkey-workflows-md-f9bd17ffd75d78c988ce.js create mode 100644 component---src-templates-post-index-js-content-file-path-content-posts-violentmonkey-workflows-md-f9bd17ffd75d78c988ce.js.map create mode 100644 component---src-templates-post-index-js-content-file-path-content-privacy-index-md-43ad4d0d12554942e98a.js create mode 100644 component---src-templates-post-index-js-content-file-path-content-privacy-index-md-43ad4d0d12554942e98a.js.map create mode 100644 component---src-templates-post-index-js-content-file-path-src-components-install-beta-mdx-352287dcf7ae506f38b3.js create mode 100644 component---src-templates-post-index-js-content-file-path-src-components-install-beta-mdx-352287dcf7ae506f38b3.js.map create mode 100644 component---src-templates-post-index-js-content-file-path-src-components-install-stable-mdx-4d79f994d595ea448b6a.js create mode 100644 component---src-templates-post-index-js-content-file-path-src-components-install-stable-mdx-4d79f994d595ea448b6a.js.map create mode 100644 components/install-beta/index.html create mode 100644 components/install-stable/index.html create mode 100644 faq/index.html create mode 100644 favicon-32x32.png create mode 100644 get-it/index.html create mode 100644 guide/creating-a-userscript/index.html create mode 100644 guide/keyboard-shortcuts/index.html create mode 100644 guide/observing-dom/index.html create mode 100644 guide/using-modern-syntax/index.html create mode 100644 icons/icon-144x144.png create mode 100644 icons/icon-192x192.png create mode 100644 icons/icon-256x256.png create mode 100644 icons/icon-384x384.png create mode 100644 icons/icon-48x48.png create mode 100644 icons/icon-512x512.png create mode 100644 icons/icon-72x72.png create mode 100644 icons/icon-96x96.png create mode 100644 index.html create mode 100644 localization/index.html create mode 100644 manifest.webmanifest create mode 100644 page-data/404.html/page-data.json create mode 100644 page-data/404/page-data.json create mode 100644 page-data/api/gm/page-data.json create mode 100644 page-data/api/matching/page-data.json create mode 100644 page-data/api/metadata-block/page-data.json create mode 100644 page-data/app-data.json create mode 100644 page-data/components/install-beta/page-data.json create mode 100644 page-data/components/install-stable/page-data.json create mode 100644 page-data/faq/page-data.json create mode 100644 page-data/get-it/page-data.json create mode 100644 page-data/guide/creating-a-userscript/page-data.json create mode 100644 page-data/guide/keyboard-shortcuts/page-data.json create mode 100644 page-data/guide/observing-dom/page-data.json create mode 100644 page-data/guide/using-modern-syntax/page-data.json create mode 100644 page-data/index/page-data.json create mode 100644 page-data/localization/page-data.json create mode 100644 page-data/posts/features-in-userscript-generator/page-data.json create mode 100644 page-data/posts/how-to-edit-scripts-with-your-favorite-editor/page-data.json create mode 100644 page-data/posts/inject-into-context/page-data.json create mode 100644 page-data/posts/inject-scripts-with-blob-urls/page-data.json create mode 100644 page-data/posts/page-data.json create mode 100644 page-data/posts/smart-rules-for-blacklist/page-data.json create mode 100644 page-data/posts/violentmonkey-workflows/page-data.json create mode 100644 page-data/privacy/page-data.json create mode 100644 page-data/sq/d/1116475411.json create mode 100644 page-data/sq/d/1700780748.json create mode 100644 page-data/sq/d/2344890832.json create mode 100644 page-data/sq/d/3202921338.json create mode 100644 page-data/sq/d/3798213247.json create mode 100644 polyfill-d4361b856f0eb8aaa3a2.js create mode 100644 polyfill-d4361b856f0eb8aaa3a2.js.map create mode 100644 posts/features-in-userscript-generator/index.html create mode 100644 posts/how-to-edit-scripts-with-your-favorite-editor/index.html create mode 100644 posts/index.html create mode 100644 posts/inject-into-context/index.html create mode 100644 posts/inject-scripts-with-blob-urls/index.html create mode 100644 posts/smart-rules-for-blacklist/index.html create mode 100644 posts/violentmonkey-workflows/index.html create mode 100644 privacy/index.html create mode 100644 sitemap-0.xml create mode 100644 sitemap-index.xml create mode 100644 static/397e6adb14ec725f269e09d9ed10a7dd/222b7/editor-4.png create mode 100644 static/397e6adb14ec725f269e09d9ed10a7dd/98314/editor-4.png create mode 100644 static/397e6adb14ec725f269e09d9ed10a7dd/a6d36/editor-4.png create mode 100644 static/397e6adb14ec725f269e09d9ed10a7dd/ff46a/editor-4.png create mode 100644 static/417c33e94510295d5d31457c6a370464/9d635/maxthon.png create mode 100644 static/49c98c639750ed124996d21d44c0a89e/9d635/github.png create mode 100644 static/5353fff61b7784074245599dfc3ebf63/1fbe8/match.png create mode 100644 static/5353fff61b7784074245599dfc3ebf63/222b7/match.png create mode 100644 static/5353fff61b7784074245599dfc3ebf63/a6d36/match.png create mode 100644 static/5353fff61b7784074245599dfc3ebf63/ff46a/match.png create mode 100644 static/5ec1ba52eccf7f65d5ca483f1a10c645/222b7/editor-1.png create mode 100644 static/5ec1ba52eccf7f65d5ca483f1a10c645/e9131/editor-1.png create mode 100644 static/5ec1ba52eccf7f65d5ca483f1a10c645/ff46a/editor-1.png create mode 100644 static/80726b39919f5a205b7af42b156d5bc9/222b7/easy-1.png create mode 100644 static/80726b39919f5a205b7af42b156d5bc9/24c7e/easy-1.png create mode 100644 static/80726b39919f5a205b7af42b156d5bc9/ff46a/easy-1.png create mode 100644 static/8cc7a9ead9c41330ebc5e5e4e6fa5a52/942f4/chrome.png create mode 100644 static/b302ac873f1a2ebe23de71f9e88e0ff8/9d635/firefox.png create mode 100644 static/c2d555bd768e2e4658e93229e4a2c51c/9d635/edge.png create mode 100644 static/e22c3fb14e374e6c860d18f0ed827f66/222b7/editor-2.png create mode 100644 static/e22c3fb14e374e6c860d18f0ed827f66/e9131/editor-2.png create mode 100644 static/e22c3fb14e374e6c860d18f0ed827f66/ff46a/editor-2.png create mode 100644 static/eefcff0818337e0a57ec6dc6b89acb7c/13a9a/editor-3.png create mode 100644 static/eefcff0818337e0a57ec6dc6b89acb7c/222b7/editor-3.png create mode 100644 static/eefcff0818337e0a57ec6dc6b89acb7c/ff46a/editor-3.png create mode 100644 static/vm-6437e4e5a400c6eff1c23ead4d549b0a.png create mode 100644 styles.0d9914f9f88a16b032ba.css create mode 100644 sw.js create mode 100644 webpack-runtime-c1cfbe8f76e2d4cb7669.js create mode 100644 webpack-runtime-c1cfbe8f76e2d4cb7669.js.map create mode 100644 webpack.stats.json create mode 100644 ~partytown/debug/partytown-atomics.js create mode 100644 ~partytown/debug/partytown-media.js create mode 100644 ~partytown/debug/partytown-sandbox-sw.js create mode 100644 ~partytown/debug/partytown-sw.js create mode 100644 ~partytown/debug/partytown-ww-atomics.js create mode 100644 ~partytown/debug/partytown-ww-sw.js create mode 100644 ~partytown/debug/partytown.js create mode 100644 ~partytown/partytown-atomics.js create mode 100644 ~partytown/partytown-media.js create mode 100644 ~partytown/partytown-sw.js create mode 100644 ~partytown/partytown.js diff --git a/404.html b/404.html new file mode 100644 index 00000000..62e31c22 --- /dev/null +++ b/404.html @@ -0,0 +1,67 @@ +Violentmonkey

Not Found

You just hit a route that doesn't exist... the sadness.

Open Chat
+ + \ No newline at end of file diff --git a/404/index.html b/404/index.html new file mode 100644 index 00000000..8e7b5996 --- /dev/null +++ b/404/index.html @@ -0,0 +1,67 @@ +Violentmonkey

Not Found

You just hit a route that doesn't exist... the sadness.

Open Chat
+ + \ No newline at end of file diff --git a/_gatsby/slices/_gatsby-scripts-1.html b/_gatsby/slices/_gatsby-scripts-1.html new file mode 100644 index 00000000..c1bbbe3c --- /dev/null +++ b/_gatsby/slices/_gatsby-scripts-1.html @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/api/gm/index.html b/api/gm/index.html new file mode 100644 index 00000000..12284503 --- /dev/null +++ b/api/gm/index.html @@ -0,0 +1,931 @@ +Violentmonkey

Privileged APIs

Table of Contents

Violentmonkey APIs are derived from those in Greasemonkey v3, and most of them work the same way, GM.* Greasemonkey v4-compatible aliases were added in VM2.12.0.

+

unsafeWindow

+

unsafeWindow is the actual window object of the page.

+

It is useful when @grant is declared with anything other than none.

+
    +
  • +

    If @grant none is declared, or no @grant is declared at all:

    +

    Sandbox is disabled, meaning the script can add/modify globals directly without the need to use unsafeWindow.

    +
      +
    • window: the original window object
    • +
    • unsafeWindow: the original window object
    • +
    +
  • +
  • +

    If any API is declared with @grant:

    +

    Sandbox is enabled, meaning the script is executed in an isolated context where window is a wrapper of the original window object. So you might need unsafeWindow if you want to modify a global variable.

    +
      +
    • window: a wrapper of the original window object, adding a new attribute to window does not work if it is expected to be accessed by a script in the original world
    • +
    • unsafeWindow: the original window object
    • +
    +
  • +
+

GM_*

+

GM_* are a group of special APIs provided by Violentmonkey.

+

GM_info

+

An object that exposes information about the current userscript. It has following properties:

+
    +
  • +uuid: string +

    A unique ID of the script.

    +
  • +
  • +scriptMetaStr: string +

    The meta block of the script.

    +
  • +
  • +scriptWillUpdate: boolean +

    Whether the script will be updated automatically.

    +
  • +
  • +scriptHandler: string +

    The name of userscript manager, which should be the string Violentmonkey.

    +
  • +
  • +version: string +

    Version of Violentmonkey.

    +
  • +
  • +isIncognito: boolean- since VM2.15.4 +

    True when this is an incognito profile (Chrome) or private mode (Firefox).

    +
  • +
  • +platform: object- since VM2.12.4 +

    Unlike navigator.userAgent, which can be overriden by other extensions/userscripts or by devtools in device-emulation mode, GM_info.platform is more reliable as the data is obtained in the background page of Violentmonkey using a specialized extension API (browser.runtime.getPlatformInfo and getBrowserInfo).

    +
      +
    • +arch: string +

      One of "arm", "mips", "mips64", "x86-32", "x86-64".

      +
    • +
    • +browserName: string +

      "chrome", "firefox" or whatever was returned by the API.

      +
    • +
    • +browserVersion: string +
    • +
    • +os: string +

      One of "android", "cros", "linux", "mac", "openbsd", "win".

      +
    • +
    +
  • +
  • +script: object +

    Contains structured fields from the Metadata Block:

    +
      +
    • +description: string +
    • +
    • +excludes: string[] +
    • +
    • +includes: string[] +
    • +
    • +matches: string[] +
    • +
    • +name: string +
    • +
    • +namespace: string +
    • +
    • +resources: Array<{name, url}> +
    • +
    • +runAt: string +
    • +
    • +version: string +
    • +
    +
  • +
  • +injectInto: string- since VM2.10.0 +

    The injection mode of current script. See @inject-into for more information.

    +
  • +
+

GM_getValue

+

Retrieves a value for current script from storage.

+
let value = GM_getValue(key, defaultValue)
+
+
    +
  • +key: string +

    The name for value to load.

    +
  • +
  • +defaultValue: any +

    The default value to return if no value exists in the storage.

    +
  • +
+

GM_getValues

+

Since VM2.19.1

+

Retrieves multiple values for current script from storage.

+
let values = GM_getValues(['foo', 'bar'])
+let values2 = GM_getValues({ foo: 1, bar: [2] })
+
+
    +
  • +what: string[] | Object +

    When providing an array of keys to read, the output will only contain keys that exist in storage:

    +
    res = { foo: 123, bar: [1, 2, 3] } // all values were in storage
    +res = { foo: 123 } // `bar` is missing
    +
    +

    When providing an object, its keys are names to read from storage and values are the defaults to be used in the output object if the value was not in storage:

    +
    res = { foo: 123, bar: [1, 2, 3] } // all values were in storage
    +res = { foo: 123, bar: [2] } // `bar` is missing, so your default value is used
    +
    +
  • +
+

GM_setValue

+

Sets a key / value pair for current script to storage.

+
GM_setValue(key, value)
+
+
    +
  • +key: string +

    The unique name for value within this script.

    +
  • +
  • +value: any +

    The value to be stored, which must be JSON serializable (string, number, boolean, null, or an array/object consisting of these types) so for example you can't store DOM elements or objects with cyclic dependencies.

    +
  • +
+

GM_setValues

+

Since VM2.19.1

+

Writes multiple values to current script's storage.

+
GM_setValues({ foo: 1, bar: [1, 2, 3] })
+
+
    +
  • +data: Object +

    Each key:value pair in the object will be stored individually, so the example above is basically a more efficient version of GM_setValue('foo', 1); GM_setValue('bar', [1, 2, 3]);

    +

    Must be JSON serializable (see GM_setValue).

    +
  • +
+

GM_deleteValue

+

Deletes an existing key / value pair for current script from storage.

+
GM_deleteValue(key)
+
+
    +
  • +key: string +

    The unique name for value within this script.

    +
  • +
+

GM_deleteValues

+

Since VM2.19.1

+

Deletes values with the specified keys in current script's storage.

+
GM_deleteValues(['foo', 'bar'])
+
+
    +
  • +keys: string[] +

    Array of keys to delete.

    +
  • +
+

GM_listValues

+

Returns an array of keys of all available values within this script.

+
let arrayOfKeys = GM_listValues()
+
+

GM_addValueChangeListener

+

Adds a change listener to the storage and returns the listener ID.

+
let listenerId = GM_addValueChangeListener(name, callback)
+
+
    +
  • +name: string +

    The name of the observed variable

    +
  • +
  • +callback: (name, oldValue, newValue, remote) => void +
      +
    • +name: string +

      The name of the observed variable

      +
    • +
    • +oldValue: any +

      The old value of the observed variable (undefined if it was created)

      +
    • +
    • +newValue: any +

      The new value of the observed variable (undefined if it was deleted)

      +
    • +
    • +remote: boolean +

      true if modified by the userscript instance of another tab or false for this script instance. Can be used by scripts of different browser tabs to communicate with each other.

      +
    • +
    +
  • +
+

GM_removeValueChangeListener

+

Removes a change listener by its ID.

+
GM_removeValueChangeListener(listenerId)
+
+
    +
  • +listenerId: string +
  • +
+

GM_getResourceText

+

Retrieves a text resource from the metadata block.

+
let text = GM_getResourceText(name)
+
+
    +
  • +name: string +

    Name of a resource defined in the metadata block.

    +
  • +
+

GM_getResourceURL

+

Retrieves a blob: or data: URL of a resource from the metadata block.

+
let blobUrl = GM_getResourceURL(name);
+let blobOrDataUrl = GM_getResourceURL(name, isBlobUrl);
+
+
    +
  • +name: string +

    Name of a resource defined in the metadata block.

    +
  • +
  • +isBlobUrl: boolean = true- since VM2.13.1 +
      +
    • +

      true returns a blob: URL. It's short and cacheable, so it's good for reusing in multiple DOM elements.

      +
    • +
    • +

      false returns a data: URL. It's long so reusing it in DOM may be less performant due to the lack of caching, but it's particularly handy for direct synchronous decoding of the data on sites that forbid fetching blob: in their CSP.

      +
    • +
    +
  • +
+

Note: when setting this URL as src or href of a DOM element, it may fail on some sites with a particularly strict CSP that forbids blob: or data: URLs. Such sites are rare though. The workaround in Chrome is to use GM_addElement, whereas in Firefox you'll have to disable CSP either globally via about:config or by using an additional extension that modifies HTTP headers selectively.

+

GM_addElement

+

Since VM2.13.1

+

Appends and returns an element with the specified attributes with the primary purpose of circumventing a strict Content-Security-Policy that forbids adding inline code or style.

+
let element1 = GM_addElement(tagName, attributes);
+let element2 = GM_addElement(parentNode, tagName, attributes);
+
+
    +
  • +parentNode?: Node | Element | ShadowRoot +

    The parent node to which the new node will be appended.

    +

    It can be inside ShadowDOM: someElement.shadowRoot.

    +

    When omitted, it'll be determined automatically:

    +
      +
    1. document.head (<head>) for script, link, style, meta tags.
    2. +
    3. document.body (<body>) for other tags or when there's no <head>.
    4. +
    5. document.documentElement (<html> or an XML root node) otherwise.
    6. +
    +
  • +
  • +tagName: string +

    A tag name like 'script'.

    +
  • +
  • +attributes?: object +

    The keys are HTML attributes, not DOM properties, except textContent which sets DOM property textContent. The values are strings so if you want to assign a private function to onload you can do it after the element is created.

    +
  • +
+

Examples:

+
// using a private function in `onload`
+let el = GM_addElement('script', { src: 'https://....' });
+el.onload = () => console.log('loaded', el);
+
+
// same as GM_addStyle('a { color:red }')
+let el = GM_addElement('style', { textContent: 'a { color:red }' });
+
+
// appending to an arbitrary node
+let el = GM_addElement(parentElement.shadowRoot, 'iframe', { src: url });
+
+

Notes:

+
    +
  • The element is returned immediately (synchronously) even with GM.addElement, no need for .then(), but you can use it if you want, just once though as it's auto-removed to avoid recursion. The API is synchronous because Violentmonkey runs scripts only when the root element appears, so there's always a node to serve as a parent.
  • +
  • Invalid arguments will raise an exception, which can be caught using try {} catch (e) {}, just like standard DOM API document.createElement.
  • +
+

GM_addStyle

+

Appends and returns a <style> element with the specified CSS.

+
let styleElement = GM_addStyle(css);
+
+
    +
  • +css: string +

    The CSS code to inject.

    +
  • +
+

Older versions of Violentmonkey (prior to 2.12.0) returned an imitation of Promise, +which is still maintained for compatibility, so don't be surprised if you see code like +GM_addStyle(css).then(el => { /* whatever */ });

+

GM_openInTab

+

Opens URL in a new tab.

+
    +
  1. +

    using an object

    +
    let tabControl = GM_openInTab(url, options)
    +
    +
      +
    • +url: string +

      The URL to open in a new tab. URL relative to current page is also allowed.

      +

      Note that Firefox disallows data:, blob:, chrome:, file:, and many about: URLs.

      +
    • +
    • +options?: object +
        +
      • +active: boolean = true +

        Make the new tab active (i.e. open in foreground).

        +
      • +
      • +container?: number- since VM2.12.5, Firefox-only +

        Set tab's container in Firefox:

        +
          +
        • not specified = reuse script's tab container
        • +
        • 0 = default (main) container
        • +
        • 1, 2, etc. = internal container index
        • +
        +
      • +
      • +insert: boolean = true- since VM2.11.0 +

        Insert the new tab next to the current tab and set its "openerTab" so when it's closed the original tab will be focused automatically. When false or not specified, the usual browser behavior is to open the tab at the end of the tab list.

        +
      • +
      • +pinned: boolean = false- since VM2.12.5 +

        Pin the tab (i.e. show without a title at the beginning of the tab list).

        +
      • +
      +
    • +
    +
  2. +
  3. +

    Using a boolean, compatible with Greasemonkey:

    +
    let tabControl = GM_openInTab(url, openInBackground)
    +
    +
      +
    • +openInBackground: boolean +

      Open the tab in background. +Note, this is a reverse of the first usage method so for example true is the same as { active: false }.

      +
    • +
    +
  4. +
+

Returns an object with following properties:

+
    +
  • +onclose?: () => void +

    Сan be assigned to a function. If provided, it will be called when the opened tab is closed.

    +
  • +
  • +closed: boolean +

    Whether the opened tab is closed.

    +
  • +
  • +close: () => void +

    A function to explicitly close the opened tab.

    +
  • +
+
let tabControl = GM_openInTab(url);
+tabControl.onclose = () => console.log('tab is closed');
+tabControl.close();
+
+

GM_registerMenuCommand

+

Registers a command in Violentmonkey popup menu.

+
GM_registerMenuCommand('Text', onClick)
+const id2 = GM_registerMenuCommand('Text2', onClick, { title: 'Two' })
+const id3 = GM_registerMenuCommand('Text3', onClick, { autoClose: false })
+
+

Returns the command's caption since VM2.12.5 or id since VM2.15.9.

+
    +
  • +caption: string +

    This text will be shown in the popup menu.

    +
  • +
  • +onClick: (event) => void +

    When the command is clicked in the menu, this function will run with the following parameter:

    +
      +
    • event: MouseEvent | KeyboardEvent- since VM2.13.1 is the event that activated the command so you can check event.button, event.shiftKey, event.key, and so on.
    • +
    +
  • +
  • +options?: object- since VM2.15.9 +
      +
    • +id?: string +

      Default: caption text since VM2.16.2. +Default in 2.15.9-2.16.1: a randomly generated string.

      +
    • +
    • +title?: string +

      A hint shown in the status bar when hovering the command.

      +
    • +
    • +autoClose?: boolean = true +

      Whether to auto-close the popup after the user invoked the command.

      +
    • +
    +
  • +
+

If you want to add a shortcut, please refer to keyboard shortcut.

+

Here's how you can change the command in-place, thus preserving its relative position in the list of multiple commands:

+
const id = 'status';
+const inplace = id === GM_registerMenuCommand('Enabled', onClick, { id });
+if (inplace) {
+  // supported: change the command in-place using the same `id`
+  GM_registerMenuCommand('Disabled', onClick, { id, title: 'Status' });
+} else {
+  // not supported: recreate the commands
+  GM_unregisterMenuCommand('Enabled');
+  GM_unregisterMenuCommand('Foo');
+  GM_unregisterMenuCommand('Bar');
+  GM_registerMenuCommand('Disabled', onClick);
+  GM_registerMenuCommand('Foo', onClick2);
+  GM_registerMenuCommand('Bar', onClick3);
+}
+
+

GM_unregisterMenuCommand

+

Unregisters a command which has been registered to Violentmonkey popup menu.

+
GM_unregisterMenuCommand(captionOrId)
+
+
    +
  • +captionOrId: string +

    The caption or id of the command to unregister. +See GM_registerMenuCommand for more info.

    +
  • +
+

GM_notification

+

Shows an HTML5 desktop notification.

+
    +
  1. +

    using an object:

    +
    let control = GM_notification(options)
    +
    +
      +
    • +options: object +
        +
      • +text: string +

        Main text of the notification.

        +
      • +
      • +title?: string +

        Title of the notification.

        +
      • +
      • +image?: string +

        URL of an image to show in the notification.

        +
      • +
      • +silent?: boolean = false- since VM2.15.2, Chrome 70 +

        No sounds/vibrations when showing the notification. Only for Chromium-based browsers as of Aug 2023.

        +
      • +
      • +tag?: string- since VM2.15.4 +

        Unique name of the notification, e.g. 'abc', same as the web Notification API. Names are scoped to each userscript i.e. your tag won't clash with another script's tag.

        +

        The purpose of a tagged notification is to replace an older notification with the same tag, even if it was shown in another tab (or before this tab was navigated elsewhere and your notification had zombieTimeout).

        +
      • +
      • +zombieTimeout?: number = 0- since VM2.15.4 +

        Number of milliseconds to keep the notification after the userscript "dies", i.e. when its tab or frame is reloaded/closed/navigated. If not specified or invalid, the default behavior is to immediately remove the notifications.

        +
      • +
      • +zombieUrl?: string- since VM2.16.1 +

        URL to open when a zombie notification is clicked, see zombieTimeout for more info.

        +
      • +
      • +onclick?: () => void +

        Callback when the notification is clicked by user. As of VM2.15.2 it also forces the notification to be visible until clicked in Chrome which by default hides the notification after a few seconds.

        +
      • +
      • +ondone?: () => void +

        Callback when the notification is closed, either by user or by system.

        +
      • +
      +
    • +
    +
  2. +
  3. +

    Using separate parameters, compatible with Greasemonkey:

    +
    GM_notification(text, title, image, onclick)
    +
    +
      +
    • +text: string +

      Main text of the notification.

      +
    • +
    • +title?: string +

      Title of the notification.

      +
    • +
    • +image?: string +

      URL of an image to show in the notification.

      +
    • +
    • +onclick?: () => void +

      Callback when the notification is clicked by user.

      +
    • +
    +
  4. +
+

As of VM2.12.8 returns a control object with the following properties:

+
    +
  • +remove: () => Promise<void> +

    A function to remove the notification.

    +
  • +
+

GM_setClipboard

+

Sets data to system clipboard.

+
GM_setClipboard(data, type)
+
+
    +
  • +data: string +

    The data to be copied to system clipboard.

    +
  • +
  • +type: string = 'text/plain' +

    The MIME type of data to copy.

    +
  • +
+

GM_xmlhttpRequest

+

Makes a request like XMLHttpRequest, with some special capabilities, not restricted by same-origin policy.

+

Note: h is lowercase (the historical spelling).

+
let control = GM_xmlhttpRequest(details)
+
+
    +
  • +details: object +
      +
    • +url: string +

      URL relative to current page is also allowed.

      +
    • +
    • +method?: string +

      Usually GET.

      +
    • +
    • +user?: string +

      User for authentication.

      +
    • +
    • +password?: string +

      Password for authentication.

      +
    • +
    • +overrideMimeType?: string +

      A MIME type to specify with the request.

      +
    • +
    • +headers?: object +

      For example { 'name1': 'value1', 'name2': 'value2' }.

      +

      Some special headers are also allowed:

      +
        +
      • 'Cookie'
      • +
      • 'Host'
      • +
      • 'Origin'
      • +
      • 'Referer'
      • +
      • 'User-Agent'
      • +
      +
    • +
    • +responseType?: string +

      One of the following:

      +
        +
      • 'text' 👈 default
      • +
      • 'json'
      • +
      • 'blob'
      • +
      • 'arraybuffer'
      • +
      • 'document' (since VM2.12.0)
      • +
      +
    • +
    • +timeout?: number- since VM2.9.5 +

      Time to wait for the request, none by default.

      +
    • +
    • +data?: string | ArrayBuffer | Blob | DataView | FormData | ReadableStream | TypedArray | URLSearchParams +

      Data to send with the request, usually for POST and PUT requests.

      +
    • +
    • +binary?: boolean- since VM2.12.2 +

      Send the data string as a blob. This is for compatibility with Tampermonkey/Greasemonkey, where only string type is allowed in data.

      +
    • +
    • +context?: any +

      Can be an object and will be assigned to context of the response object.

      +
    • +
    • +anonymous?: boolean = false- since VM2.10.1 +

      When set to true, no cookie will be sent with the request and since VM2.12.5 the response cookies will be ignored.

      +

      When absent, an inverted value of Greasemonkey4-compatible withCredentials is used. Note that Violentmonkey sends cookies by default, like Tampermonkey, but unlike Greasemonkey4 (same-origin url only).

      +
    • +
    +

    Event handlers:

    +
      +
    • +onabort?: () => void +
    • +
    • +onerror?: () => void +
    • +
    • +onload?: () => void +
    • +
    • +onloadend?: () => void +
    • +
    • +onloadstart?: () => void- since VM2.12.5 +
    • +
    • +onprogress?: () => void +
    • +
    • +onreadystatechange?: () => void +
    • +
    • +ontimeout?: () => void +
    • +
    +

    Each event handler is a function that accepts one argument responseObject

    +
  • +
+
+

Note:

+
    +
  • synchronous is not supported.
  • +
+
+

Returns a control object with the following properties:

+
    +
  • +abort: () => void +

    A function to abort the request.

    +
  • +
+

The response object is passed to each event handler with the following properties, most of which are identical to those provided by the standard XMLHttpRequest:

+
    +
  • +status: number +
  • +
  • +statusText: string +
  • +
  • +readyState: number +
  • +
  • +responseHeaders: string +
  • +
  • +response: string | Blob | ArrayBuffer | Document | object | null +
  • +
  • responseText: string | undefined, only provided when available
  • +
  • responseXML: Document | null- since VM2.13.4, only provided when available
  • +
  • lengthComputable: boolean, only provided when available
  • +
  • loaded: number, only provided when available
  • +
  • total: number, only provided when available
  • +
  • finalUrl: string, the final URL after redirection
  • +
  • context: any, the same context object you specified in details
  • +
+

GM_download

+

Since VM2.9.5

+

Downloads a URL to a local file.

+
    +
  1. +

    using an object:

    +
    GM_download(options)
    +
    +
      +
    • +

      options: object:

      +
        +
      • +url: string +

        The URL to download.

        +
      • +
      • +name: string +

        The filename to save to. Folders/subpaths aren't supported yet.

        +
      • +
      +

      Most GM_xmlhttpRequest options are supported.

      +
        +
      • +headers?: object +
      • +
      • +timeout?: number- since VM2.9.5 +
      • +
      • +context?: any- since VM2.13.4 +
      • +
      • +user?: string- since VM2.13.4 +
      • +
      • +password?: string- since VM2.13.4 +
      • +
      • +anonymous?: boolean = false- since VM2.13.4 +
      • +
      • +onabort?: () => void- since VM2.13.4 +
      • +
      • +onerror?: () => void +
      • +
      • +onload?: () => void +
      • +
      • +onloadend?: () => void- since VM2.13.4 +
      • +
      • +onloadstart?: () => void- since VM2.13.4 +
      • +
      • +onprogress?: () => void +
      • +
      • +onreadystatechange?: () => void- since VM2.13.4 +
      • +
      • +ontimeout?: () => void +
      • +
      +

      The onload event handler is called after the data is downloaded from URL, before writing the file.

      +
    • +
    +
  2. +
  3. +

    using separate parameters:

    +
    GM_download(url, name)
    +
    +
      +
    • +url: string +

      The URL to download.

      +
    • +
    • +name: string +

      The filename to save to. Folders/subpaths aren't supported yet.

      +
    • +
    +
  4. +
+

Returns a control object with the following properties, same as GM_xmlhttpRequest:

+
    +
  • +abort: () => void +

    A function to abort the request.

    +
  • +
+

GM.*

+

GM (since VM2.12.0) is a single variable with Greasemonkey4-compatible aliases, the async functions return a Promise that's resolved with the returned value.

+

Open Chat
+ + \ No newline at end of file diff --git a/api/matching/index.html b/api/matching/index.html new file mode 100644 index 00000000..475f2220 --- /dev/null +++ b/api/matching/index.html @@ -0,0 +1,180 @@ +Violentmonkey

Matching

Table of Contents

There are four types of rules: @match / @exclude-match / @include / @exclude in Violentmonkey.

+

@match / @exclude-match

+

It is recommended to use @match / @exclude-match rather than @include / @exclude because the match rules are safer and more strict.

+

@match defines a URL matching rule. @exclude-match defines a match rule but used to exclude the matched URLs, similar to @exclude.

+

For more details, see Match Patterns for Chrome extensions.

+

Note that match patterns only work on scheme, host and path, i.e. match patterns always ignore query string and hash.

+

Since Violentmonkey v2.10.4, some additional rules are accepted:

+
    +
  • the scheme part accepts http* to match http or https;
  • +
  • the host part accepts wildcards (*) at any position, e.g. www.google.*;
  • +
  • the host part accepts .tld to match any top level domain suffix.
  • +
+

Examples:

+
// @match *://*/*
+// @exclude-match *://*.tk/*
+
+

@include / @exclude

+

Each @include and @exclude rule can be one of the following:

+
    +
  • +

    a normal string

    +

    If the string does not start or end with a slash (/), it will be used as a normal string.

    +

    If there are wildcards (*), each of them matches any characters.

    +

    e.g. https://www.google.com/* matches the following:

    +
      +
    • https://www.google.com/
    • +
    • https://www.google.com/any/subview
    • +
    +

    but not the following:

    +
      +
    • http://www.google.com/
    • +
    • https://www.google.com.hk/
    • +
    +

    If there is no wildcard in the string, the rule matches the entire URL.

    +

    e.g. https://www.google.com/ matches only https://www.google.com/ but not https://www.google.com/any/subview.

    +

    The host part accepts .tld to match top level domain suffix.

    +

    e.g. https://www.google.tld/ matches both https://www.google.com/ and https://www.google.co.jp/.

    +
  • +
  • +

    a regular expression

    +

    If the string starts and ends with a slash (/), it will be compiled as a regular expression.

    +

    e.g. /\.google\.com[\.\/]/ matches the following:

    +
      +
    • https://www.google.com/,
    • +
    • https://www.google.com/any/subview
    • +
    • http://www.google.com/
    • +
    • https://www.google.com.hk/
    • +
    +
  • +
+

Examples:

+
// @include *
+// @include https://www.google.com/*
+// @include /\.com\.hk\//
+// @exclude https://www.google.com/exact/url
+
+

How does a script match?

+

In short, a script will execute if it matches any @match or @include rule and does not match any @exclude-match or @exclude rule.

+

Here is the long version:

+
    +
  • If any @exclude-match or @exclude rule matches, the script does not match.
  • +
  • Otherwise if any @match rule is defined, the script matches only if some of the @match rules match.
  • +
  • If no @match rule is defined, we fallback to @include rules and the script matches only if some of the @include rules match.
  • +
  • If neither @match nor @include rule is defined, the script is assumed to match.
  • +
+ + + match.png + +

Matching SPA sites like fb, github, twitter, youtube

+

Userscript extensions use the native behavior of the browser - it runs scripts defined by extensions only during the standard "hard" navigation, not during "soft" navigation via history.pushState or replaceState or #hash changes used by many modern SPA sites.

+

You can verify the type by opening devtools network log, then navigate in this tab (e.g. click a link) and look at the type of the request for this navigation: a Document (Chrome) or HTML (Firefox) means "hard" navigation i.e. the browser creates a new environment for the page and loads its HTML from the server including its scripts and userscripts from extensions.

+

1. Run your userscript on the entire SPA site:

+
// @match *://www.youtube.com/*
+
+

2. Then watch for changes either using vm-url or manually:

+
onUrlChange();
+
+if (self.navigation) {
+  navigation.addEventListener('navigatesuccess', onUrlChange);
+} else {
+  let u = location.href;
+  new MutationObserver(() => u !== (u = location.href) && onUrlChange())
+    .observe(document, {subtree: true, childList: true});
+}
+
+function onUrlChange() {
+  if (!location.pathname.startsWith('/watch')) {
+    // deactivate();
+    return;
+  }
+  console.log('processing', location.href);
+  // activate();
+}
+

Open Chat
+ + \ No newline at end of file diff --git a/api/metadata-block/index.html b/api/metadata-block/index.html new file mode 100644 index 00000000..e605ef9b --- /dev/null +++ b/api/metadata-block/index.html @@ -0,0 +1,249 @@ +Violentmonkey

Metadata Block

Table of Contents

The metadata must follow the format:

+
// ==UserScript==
+// @key value
+// ==/UserScript==
+
+

Each line of the block must start with //, the first line must be // ==UserScript== and the last line must be // ==/UserScript==. No extra space is allowed at the beginning or ending of line.

+

Some of the keys can be localized for multiple languages, by adding a colon and the locale code to the key, e.g. @name:zh-CN. The locale code is case insensitive.

+

Labels:

+
    +
  • required The key must be set.
  • +
  • multilingual The key can be localized by appending a colon and the locale code, e.g. @name:zh-CN.
  • +
  • multiple The key can be set multiple times.
  • +
+

@name

+

requiredmultilingual

+

The name of the script, shown in script list and menus. It must be unique within a @namespace. If a script is being installed, and a script with the same @namespace and @name already exists, it will be replaced by the new one. Creating a script with same @namespace and @name will cause a conflict error.

+

Examples:

+
// @name          Violentmonkey Script
+// @name:zh-CN    暴力猴脚本
+
+

@namespace

+

The combination of @namespace and @name is the unique identifier for a userscript. @namespace can be any string, for example the homepage of a group of userscripts by the same author. If not provided the @namespace falls back to an empty string ('').

+

Examples:

+
// @namespace https://violentmonkey.github.io
+
+

@match / @exclude-match

+

multiple

+

Define rules to decide whether a script should be executed. It is recommended to use @match instead of @include.

+

See more about matching.

+

@include / @exclude

+

multiple

+

The old way to decide whether a script should be executed.

+

See more about matching.

+

@version

+

Version of the script, it can be used to check if a script has new versions. It is composed of several parts, joined by .. Each part must start with numbers, and can be followed by alphabetic characters.

+

Note: If no @version is specified, the script will not be updated automatically.

+

Examples:

+
// @version 1.0
+
+// @version 1.2a.3
+
+

@description

+

multiple

+

A brief summary to describe the script.

+

Examples:

+
// @description         This script rocks.
+// @description:zh-CN   这个脚本很棒!
+
+

@icon

+

Specify an icon for the script.

+

Examples:

+
// @icon https://my.cdn.com/icon.png
+
+

@require

+

multiple

+

Require another script to execute before the current one. The value is the URL to the required script, which may be relative to the URL the script is being installed from.

+

The required script will be downloaded along with installation and execute before the script.

+

Local files are not allowed to be required due to security concern. Also it does not make sense since scripts are supposed to work on different devices.

+

Examples:

+
// @require https://my.cdn.com/jquery.js
+
+

@resource

+

multiple

+

Some static resources that can be accessed in the script by GM_getResourceText and GM_getResourceURL. The value is composed of two parts, joined with one or more white spaces. The first part is the name of the resource, no white space is allowed in it. The second part is the URL to the resource, which may be relative to the URL the script is being installed from.

+

The resource will be downloaded along with installation and can be accessed when the script executes.

+

Examples:

+
// @resource logo https://my.cdn.com/logo.png
+// @resource text https://my.cdn.com/some-text.txt
+
+

@run-at

+

Specifies when the script will run.

+
    +
  • +

    document-start

    +

    Run as early as possible, document.documentElement is present, but may be without either document.head or document.body or both. Other scripts in the page may run earlier, see the note below.

    +
  • +
  • +

    document-body (since v2.12.10)

    +

    Run after document.body appears, possibly with some child elements inside, because detection is asynchronous (using a one-time MutationObserver).

    +
  • +
  • +

    document-end default

    +

    Run when DOMContentLoaded is fired, synchronously. At this time, the basic HTML of the page is ready and other resources like images might still be on the way.

    +
  • +
  • +

    document-idle

    +

    Run after DOMContentLoaded is fired, asynchronously, i.e. after yielding to the previously scheduled callbacks or urgent tasks like rendering. Prefer this mode for scripts that take more than a couple of milliseconds to compile and run (you can see it in devtools performance profiler), so that they don't delay the moment the page becomes usable.

    +
  • +
+

When using document-start in Violentmonkey ManifestV2 there's a limited method of ensuring the userscript runs before other scripts in the page:

+
    +
  • the userscript must use the default page injection mode
  • +
  • the user must enable Synchronous page mode (Chrome/Firefox) or Alternative page mode (Firefox only, enabled by default) in Violentmonkey's advanced settings;
  • +
  • the user didn't change the injection mode to content in script's editor or script's settings or in Violentmonkey's settings;
  • +
  • the cookies are not explicitly blocked for the site;
  • +
  • it's not the incognito mode;
  • +
  • Firefox-only: the site doesn't block script elements via its CSP;
  • +
+

@noframes

+

When present, the script will execute only in top level document, but not in nested frames.

+
// @noframes
+
+

@grant

+

multiple

+

Specify which special APIs should be granted and can be used when the script executes.

+

If no @grant is present, @grant none is assumed.

+
    +
  • +

    In case you don't need special API or sandboxing

    +
    // @grant none
    +
    +

    Sandbox is disabled in this mode, meaning the script can add/modify globals directly without the need to use unsafeWindow.

    +
  • +
  • +

    In case any special API is used, it must be explicitly granted

    +
    // @grant GM_getValue
    +// @grant GM_setValue
    +
    +

    …or for the new GM.* API methods (Since VM2.12.10):

    +
    // @grant GM.getValue
    +// @grant GM.setValue
    +
    +
  • +
+

In addition to GM API the following privileges may be granted:

+
    +
  • +

    // @grant window.close

    +

    Since VM2.6.2
    +Allows closing the tab via window.close()

    +
  • +
  • +

    // @grant window.focus

    +

    Since VM2.12.10
    +Allows focusing the tab via window.focus() even if the user didn't interact with it first.

    +
  • +
+

@inject-into

+

Added in Violentmonkey v2.10.0

+

Decide which context the script will be injected into.

+

If not set in the metadata block, the default value auto will be used. +However, you can change the default value in Violentmonkey settings.

+

Possible values:

+
    +
  • +

    page

    +

    Inject into context of the web page.

    +

    In this mode, unsafeWindow refers to the window object, +allowing the script to access JavaScript objects of the web page, +just like normal page scripts can.

    +
  • +
  • +

    content

    +

    Inject into context of content scripts.

    +

    In this mode, unsafeWindow refers to the global object in content script. +As a result, the script can access and modify the page's DOM, +but cannot access JavaScript objects of the web page.

    +
  • +
  • +

    auto default

    +

    Try to inject into context of the web page. If blocked by CSP rules, inject as a content script.

    +
  • +
+

@downloadURL

+

The URL the script can be downloaded from. Checked for updates automatically at a regular interval, and also manually on user request. Automatically added when using "Install from URL."

+

@supportURL

+

If supplied, the question mark icon in the user scripts list will link to this.

+

@homepageURL

+

If supplied, the home icon in the user scripts list will link to this.

+

@unwrap

+

Since VM2.13.1.

+

If supplied, the script will be injected as is into the global scope of the page, i.e. without our standard wrapper like window.VMxxx=function(){...}.

+

The @grant key is ignored so the script won't have access to GM.* or GM_* API. +The @inject-into key is supported as usual.

+

A typical use case is direct access to global page variables declared as const or let. In a standard userscript you would have to create a script element yourself explicitly by using document.createElement or GM_addElement, then transfer the result via a CustomEvent or unsafeWindow.foo.

+

Another use case is migration from other extensions that run your JavaScript code as is, without userscript API.

+

@top-level-await

+

Since VM2.19.2.

+

Enables top-level await in your script. Useful when the rest of your script's code depends on some external event e.g. when waiting for an element using MutationObserver or fetching data from network.

+
    +
  • Avoid using it to import dependencies that should always run; prefer using @require and @resource.
  • +
  • Can't be used with @unwrap.
  • +

Open Chat
+ + \ No newline at end of file diff --git a/app-34a1f4a0ffa1cb3f26bf.js b/app-34a1f4a0ffa1cb3f26bf.js new file mode 100644 index 00000000..5d0bd878 --- /dev/null +++ b/app-34a1f4a0ffa1cb3f26bf.js @@ -0,0 +1,3 @@ +/*! For license information please see app-34a1f4a0ffa1cb3f26bf.js.LICENSE.txt */ +(self.webpackChunkviolentmonkey_github_io=self.webpackChunkviolentmonkey_github_io||[]).push([[524],{9356:function(e,t,n){"use strict";var r;n.r(t),n.d(t,{BaseContext:function(){return y},Link:function(){return K},Location:function(){return ee},LocationContext:function(){return b},LocationProvider:function(){return Z},Match:function(){return ne},Redirect:function(){return P},Router:function(){return ue},ServerLocation:function(){return te},createHistory:function(){return d},createMemorySource:function(){return p},globalHistory:function(){return m},insertParams:function(){return N},isRedirect:function(){return x},match:function(){return T},navigate:function(){return v},pick:function(){return R},redirectTo:function(){return E},resolve:function(){return O},shallowCompare:function(){return $},startsWith:function(){return C},useBaseContext:function(){return w},useLocation:function(){return fe},useLocationContext:function(){return k},useMatch:function(){return he},useNavigate:function(){return de},useParams:function(){return pe},validateRedirect:function(){return L}});n(993),n(541);var o=n(9474),a=n(2736),i=n.n(a),l=n(9597),s=n.n(l);function u(){return u=Object.assign?Object.assign.bind():function(e){for(var t=1;t=0||(o[n]=e[n]);return o}const f=e=>{const{search:t,hash:n,href:r,origin:o,protocol:a,host:i,hostname:l,port:s}=e.location;let{pathname:u}=e.location;return!u&&r&&h&&(u=new URL(r).pathname),{pathname:encodeURI(decodeURI(u)),search:t,hash:n,href:r,origin:o,protocol:a,host:i,hostname:l,port:s,state:e.history.state,key:e.history.state&&e.history.state.key||"initial"}},d=(e,t)=>{let n=[],r=f(e),o=!1,a=()=>{};return{get location(){return r},get transitioning(){return o},_onTransitionComplete(){o=!1,a()},listen(t){n.push(t);const o=()=>{r=f(e),t({location:r,action:"POP"})};return e.addEventListener("popstate",o),()=>{e.removeEventListener("popstate",o),n=n.filter((e=>e!==t))}},navigate(t,{state:i,replace:l=!1}={}){if("number"==typeof t)e.history.go(t);else{i=u({},i,{key:Date.now()+""});try{o||l?e.history.replaceState(i,null,t):e.history.pushState(i,null,t)}catch(n){e.location[l?"replace":"assign"](t)}}r=f(e),o=!0;const s=new Promise((e=>a=e));return n.forEach((e=>e({location:r,action:"PUSH"}))),s}}},p=(e="/")=>{const t=e.indexOf("?"),n={pathname:t>-1?e.substr(0,t):e,search:t>-1?e.substr(t):""};let r=0;const o=[n],a=[null];return{get location(){return o[r]},addEventListener(e,t){},removeEventListener(e,t){},history:{get entries(){return o},get index(){return r},get state(){return a[r]},pushState(e,t,n){const[i,l=""]=n.split("?");r++,o.push({pathname:i,search:l.length?`?${l}`:l}),a.push(e)},replaceState(e,t,n){const[i,l=""]=n.split("?");o[r]={pathname:i,search:l},a[r]=e},go(e){const t=r+e;t<0||t>a.length-1||(r=t)}}}},h=!("undefined"==typeof window||!window.document||!window.document.createElement),m=d(h?window:p()),{navigate:v}=m;function g(e,t){return o.createServerContext?((e,t=null)=>(globalThis.__SERVER_CONTEXT||(globalThis.__SERVER_CONTEXT={}),globalThis.__SERVER_CONTEXT[e]||(globalThis.__SERVER_CONTEXT[e]=o.createServerContext(e,t)),globalThis.__SERVER_CONTEXT[e]))(e,t):o.createContext(t)}const y=g("Base",{baseuri:"/",basepath:"/"}),b=g("Location"),w=()=>o.useContext(y),k=()=>o.useContext(b);function S(e){this.uri=e}const x=e=>e instanceof S,E=e=>{throw new S(e)};function _(e){const{to:t,replace:n=!0,state:r,noThrow:a,baseuri:i}=e;o.useEffect((()=>{Promise.resolve().then((()=>{const o=O(t,i);v(N(o,e),{replace:n,state:r})}))}),[]);const l=O(t,i);return a||E(N(l,e)),null}const P=e=>{const t=k(),{baseuri:n}=w();return o.createElement(_,u({},t,{baseuri:n},e))};P.propTypes={from:i().string,to:i().string.isRequired};const C=(e,t)=>e.substr(0,t.length)===t,R=(e,t)=>{let n,r;const[o]=t.split("?"),a=A(o),i=""===a[0],l=z(e);for(let u=0,c=l.length;u dynamic segment "${r[1]}" is a reserved name. Please use a different name in path "${o.path}".`);const t=decodeURIComponent(n);f[r[1]]=t}else if(t!==n){e=!0;break}}if(!e){n={route:o,params:f,uri:"/"+a.slice(0,p).join("/")};break}}return n||r||null},T=(e,t)=>R([{path:e}],t),O=(e,t)=>{if(C(e,"/"))return e;const[n,r]=e.split("?"),[o]=t.split("?"),a=A(n),i=A(o);if(""===a[0])return U(o,r);if(!C(a[0],".")){const e=i.concat(a).join("/");return U(("/"===o?"":"/")+e,r)}const l=i.concat(a),s=[];for(let u=0,c=l.length;u{const[n,r=""]=e.split("?");let o="/"+A(n).map((e=>{const n=j.exec(e);return n?t[n[1]]:e})).join("/");const{location:{search:a=""}={}}=t,i=a.split("?")[1]||"";return o=U(o,r,i),o},L=(e,t)=>{const n=e=>I(e);return A(e).filter(n).sort().join("/")===A(t).filter(n).sort().join("/")},j=/^:(.+)/,I=e=>j.test(e),D=e=>e&&"*"===e[0],M=(e,t)=>({route:e,score:e.default?0:A(e.path).reduce(((e,t)=>(e+=4,(e=>""===e)(t)?e+=1:I(t)?e+=2:D(t)?e-=5:e+=3,e)),0),index:t}),z=e=>e.map(M).sort(((e,t)=>e.scoret.score?-1:e.index-t.index)),A=e=>e.replace(/(^\/+|\/+$)/g,"").split("/"),U=(e,...t)=>e+((t=t.filter((e=>e&&e.length>0)))&&t.length>0?`?${t.join("&")}`:""),F=["uri","path"],$=(e,t)=>{const n=Object.keys(e);return n.length===Object.keys(t).length&&n.every((n=>t.hasOwnProperty(n)&&e[n]===t[n]))},H=e=>e.replace(/(^\/+|\/+$)/g,""),B=e=>t=>{if(!t)return null;if(t.type===o.Fragment&&t.props.children)return o.Children.map(t.props.children,B(e));if(s()(t.props.path||t.props.default||t.type===P,`: Children of must have a \`path\` or \`default\` prop, or be a \`\`. None found on element type \`${t.type}\``),s()(!!(t.type!==P||t.props.from&&t.props.to),` requires both "from" and "to" props when inside a .`),s()(!(t.type===P&&!L(t.props.from,t.props.to)),` has mismatched dynamic segments, ensure both paths have the exact same dynamic segments.`),t.props.default)return{value:t,default:!0};const n=t.type===P?t.props.from:t.props.path,r="/"===n?e:`${H(e)}/${H(n)}`;return{value:t,default:t.props.default,path:t.props.children?`${H(r)}/*`:r}},W=["innerRef"],q=["to","state","replace","getProps"],V=["key"];let{forwardRef:Q}=r||(r=n.t(o,2));void 0===Q&&(Q=e=>e);const G=()=>{},K=Q(((e,t)=>{let{innerRef:n}=e,r=c(e,W);const{baseuri:a}=w(),{location:i}=k(),{to:l,state:s,replace:f,getProps:d=G}=r,p=c(r,q),h=O(l,a),m=encodeURI(h),g=i.pathname===m,y=C(i.pathname,m);return o.createElement("a",u({ref:t||n,"aria-current":g?"page":void 0},p,d({isCurrent:g,isPartiallyCurrent:y,href:h,location:i}),{href:h,onClick:e=>{if(p.onClick&&p.onClick(e),(e=>!e.defaultPrevented&&0===e.button&&!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey))(e)){e.preventDefault();let t=f;if("boolean"!=typeof f&&g){const e=c(u({},i.state),V);t=$(u({},s),e)}v(h,{state:s,replace:t})}}}))}));K.displayName="Link",K.propTypes={to:i().string.isRequired};class J extends o.Component{constructor(...e){super(...e),this.displayName="ReactUseErrorBoundary"}componentDidCatch(...e){this.setState({}),this.props.onError(...e)}render(){return this.props.children}}const Y=o.createContext({componentDidCatch:{current:void 0},error:void 0,setError:()=>!1});function X({children:e}){const[t,n]=o.useState(),r=o.useRef(),a=o.useMemo((()=>({componentDidCatch:r,error:t,setError:n})),[t]);return o.createElement(Y.Provider,{value:a},o.createElement(J,{error:t,onError:(e,t)=>{n(e),null==r.current||r.current(e,t)}},e))}X.displayName="ReactUseErrorBoundaryContext";const Z=function(e){var t,n;function r(t){return o.createElement(X,null,o.createElement(e,u({key:"WrappedComponent"},t)))}return r.displayName=`WithErrorBoundary(${null!=(t=null!=(n=e.displayName)?n:e.name)?t:"Component"})`,r}((({history:e=m,children:t})=>{const{location:n}=e,[r,a]=o.useState({location:n}),[i]=function(e){const t=o.useContext(Y);t.componentDidCatch.current=void 0;const n=o.useCallback((()=>{t.setError(void 0)}),[]);return[t.error,n]}();if(o.useEffect((()=>{e._onTransitionComplete()}),[r.location]),o.useEffect((()=>{let t=!1;const n=e.listen((({location:e})=>{Promise.resolve().then((()=>{requestAnimationFrame((()=>{t||a({location:e})}))}))}));return()=>{t=!0,n()}}),[]),i){if(!x(i))throw i;v(i.uri,{replace:!0})}return o.createElement(b.Provider,{value:r},"function"==typeof t?t(r):t||null)})),ee=({children:e})=>{const t=k();return t?e(t):o.createElement(Z,null,e)},te=({url:e,children:t})=>{const n=e.indexOf("?");let r,a="";return n>-1?(r=e.substring(0,n),a=e.substring(n)):r=e,o.createElement(b.Provider,{value:{location:{pathname:r,search:a,hash:""}}},t)},ne=({path:e,children:t})=>{const{baseuri:n}=w(),{location:r}=k(),o=O(e,n),a=T(o,r.pathname);return t({location:r,match:a?u({},a.params,{uri:a.uri,path:e}):null})},re=["uri","location","component"],oe=["children","style","component","uri","location"],ae=e=>{let{uri:t,location:n,component:r}=e,a=c(e,re);return o.createElement(le,u({},a,{component:r,uri:t,location:n}))};let ie=0;const le=e=>{let{children:t,style:n,component:r="div",uri:a,location:i}=e,l=c(e,oe);const s=o.useRef(),f=o.useRef(!0),d=o.useRef(a),p=o.useRef(i.pathname),h=o.useRef(!1);o.useEffect((()=>(ie++,m(),()=>{ie--,0===ie&&(f.current=!0)})),[]),o.useEffect((()=>{let e=!1,t=!1;a!==d.current&&(d.current=a,e=!0),i.pathname!==p.current&&(p.current=i.pathname,t=!0),h.current=e||t&&i.pathname===a,h.current&&m()}),[a,i]);const m=o.useCallback((()=>{var e;f.current?f.current=!1:(e=s.current,h.current&&e&&e.focus())}),[]);return o.createElement(r,u({style:u({outline:"none"},n),tabIndex:"-1",ref:s},l),t)},se=["location","primary","children","basepath","baseuri","component"],ue=e=>{const t=w(),n=k();return o.createElement(ce,u({},t,n,e))};function ce(e){const{location:t,primary:n=!0,children:r,basepath:a,component:i="div"}=e,l=c(e,se),s=o.Children.toArray(r).reduce(((e,t)=>{const n=B(a)(t);return e.concat(n)}),[]),{pathname:f}=t,d=R(s,f);if(d){const{params:e,uri:r,route:s,route:{value:c}}=d,f=s.default?a:s.path.replace(/\*$/,""),p=u({},e,{uri:r,location:t}),h=o.cloneElement(c,p,c.props.children?o.createElement(ue,{location:t,primary:n},c.props.children):void 0),m=n?ae:i,v=n?u({uri:r,location:t,component:i},l):l;return o.createElement(y.Provider,{value:{baseuri:r,basepath:f}},o.createElement(m,v,h))}return null}const fe=()=>{const e=k();if(!e)throw new Error("useLocation hook was used but a LocationContext.Provider was not found in the parent tree. Make sure this is used in a component that is a child of Router");return e.location},de=()=>{throw new Error("useNavigate is removed. Use import { navigate } from 'gatsby' instead")},pe=()=>{const e=w();if(!e)throw new Error("useParams hook was used but a LocationContext.Provider was not found in the parent tree. Make sure this is used in a component that is a child of Router");const t=fe(),n=T(e.basepath,t.pathname);return n?n.params:null},he=e=>{if(!e)throw new Error("useMatch(path: string) requires an argument of a string to match against");const t=w();if(!t)throw new Error("useMatch hook was used but a LocationContext.Provider was not found in the parent tree. Make sure this is used in a component that is a child of Router");const n=fe(),r=O(e,t.baseuri),o=T(r,n.pathname);return o?u({},o.params,{uri:o.uri,path:e}):null}},407:function(e){"use strict";var t=/[|\\{}()[\]^$+*?.]/g;e.exports=function(e){if("string"!=typeof e)throw new TypeError("Expected a string");return e.replace(t,"\\$&")}},2941:function(e,t){"use strict";t.T=void 0;const n=[".html",".json",".js",".map",".txt",".xml",".pdf"];t.T=(e,t="always")=>{if("/"===e)return e;const r=e.endsWith("/");return((e,t)=>{for(const n of e)if(t.endsWith(n))return!0;return!1})(n,e)?e:"always"===t?r?e:`${e}/`:"never"===t&&r?e.slice(0,-1):e}},9120:function(e,t,n){"use strict";t.__esModule=!0,t.onInitialClientRender=void 0;n(8573),n(2431);t.onInitialClientRender=()=>{}},842:function(e,t,n){"use strict";n(9445),n(3006),t.__esModule=!0,t.getForwards=function(e){return null==e?void 0:e.flatMap((e=>(null==e?void 0:e.forward)||[]))}},2431:function(e,t,n){"use strict";t.__esModule=!0,t.injectPartytownSnippet=function(e){if(!e.length)return;const t=document.querySelector("script[data-partytown]"),n=document.querySelector('iframe[src*="~partytown/partytown-sandbox-sw"]');t&&t.remove();n&&n.remove();const a=(0,o.getForwards)(e),i=document.createElement("script");i.dataset.partytown="",i.innerHTML=(0,r.partytownSnippet)({forward:a}),document.head.appendChild(i)};var r=n(7375),o=n(842)},8769:function(e,t,n){"use strict";var r=n(9474),o={stream:!0},a=new Map,i=Symbol.for("react.element"),l=Symbol.for("react.lazy"),s=Symbol.for("react.default_value"),u=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ContextRegistry;function c(e,t,n){this._status=e,this._value=t,this._response=n}function f(e){switch(e._status){case 3:return e._value;case 1:var t=JSON.parse(e._value,e._response._fromJSON);return e._status=3,e._value=t;case 2:for(var r=(t=e._value).chunks,o=0;o=t.f?o():e.fonts.load(function(e){return _(e)+" "+e.f+"00 300px "+x(e.c)}(t.a),t.h).then((function(e){1<=e.length?r():setTimeout(a,25)}),(function(){o()}))}()})),o=null,a=new Promise((function(e,n){o=setTimeout(n,t.f)}));Promise.race([a,r]).then((function(){o&&(clearTimeout(o),o=null),t.g(t.a)}),(function(){t.j(t.a)}))};var M={D:"serif",C:"sans-serif"},z=null;function A(){if(null===z){var e=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))/.exec(window.navigator.userAgent);z=!!e&&(536>parseInt(e[1],10)||536===parseInt(e[1],10)&&11>=parseInt(e[2],10))}return z}function U(e,t,n){for(var r in M)if(M.hasOwnProperty(r)&&t===e.f[M[r]]&&n===e.f[M[r]])return!0;return!1}function F(e){var t,n=e.g.a.offsetWidth,r=e.h.a.offsetWidth;(t=n===e.f.serif&&r===e.f["sans-serif"])||(t=A()&&U(e,n,r)),t?l()-e.A>=e.w?A()&&U(e,n,r)&&(null===e.u||e.u.hasOwnProperty(e.a.c))?$(e,e.v):$(e,e.B):function(e){setTimeout(i((function(){F(this)}),e),50)}(e):$(e,e.v)}function $(e,t){setTimeout(i((function(){d(this.g.a),d(this.h.a),d(this.j.a),d(this.m.a),t(this.a)}),e),0)}function H(e,t,n){this.c=e,this.a=t,this.f=0,this.m=this.j=!1,this.s=n}D.prototype.start=function(){this.f.serif=this.j.a.offsetWidth,this.f["sans-serif"]=this.m.a.offsetWidth,this.A=l(),F(this)};var B=null;function W(e){0==--e.f&&e.j&&(e.m?((e=e.a).g&&p(e.f,[e.a.c("wf","active")],[e.a.c("wf","loading"),e.a.c("wf","inactive")]),T(e,"active")):R(e.a))}function q(e){this.j=e,this.a=new O,this.h=0,this.f=this.g=!0}function V(e,t,n,r,o){var a=0==--e.h;(e.f||e.g)&&setTimeout((function(){var e=o||null,l=r||{};if(0===n.length&&a)R(t.a);else{t.f+=n.length,a&&(t.j=a);var s,u=[];for(s=0;sPromise.all([n.e(869),n.e(125)]).then(n.bind(n,768)),"component---src-pages-posts-js":()=>Promise.all([n.e(869),n.e(226)]).then(n.bind(n,9029)),"component---src-templates-post-index-js-content-file-path-content-api-gm-md":()=>Promise.all([n.e(869),n.e(686)]).then(n.bind(n,3769)),"component---src-templates-post-index-js-content-file-path-content-api-matching-md":()=>Promise.all([n.e(869),n.e(409)]).then(n.bind(n,784)),"component---src-templates-post-index-js-content-file-path-content-api-metadata-block-md":()=>Promise.all([n.e(869),n.e(419)]).then(n.bind(n,3802)),"component---src-templates-post-index-js-content-file-path-content-faq-index-md":()=>Promise.all([n.e(869),n.e(346)]).then(n.bind(n,6372)),"component---src-templates-post-index-js-content-file-path-content-get-it-index-md":()=>Promise.all([n.e(869),n.e(74),n.e(662)]).then(n.bind(n,9361)),"component---src-templates-post-index-js-content-file-path-content-guide-creating-a-userscript-index-md":()=>Promise.all([n.e(869),n.e(147)]).then(n.bind(n,4397)),"component---src-templates-post-index-js-content-file-path-content-guide-keyboard-shortcuts-index-mdx":()=>Promise.all([n.e(869),n.e(772)]).then(n.bind(n,4098)),"component---src-templates-post-index-js-content-file-path-content-guide-observing-dom-index-md":()=>Promise.all([n.e(869),n.e(909)]).then(n.bind(n,7028)),"component---src-templates-post-index-js-content-file-path-content-guide-using-modern-syntax-index-md":()=>Promise.all([n.e(869),n.e(95)]).then(n.bind(n,902)),"component---src-templates-post-index-js-content-file-path-content-index-md":()=>Promise.all([n.e(869),n.e(74),n.e(271)]).then(n.bind(n,6855)),"component---src-templates-post-index-js-content-file-path-content-localization-index-md":()=>Promise.all([n.e(869),n.e(305)]).then(n.bind(n,2396)),"component---src-templates-post-index-js-content-file-path-content-posts-features-in-userscript-generator-md":()=>Promise.all([n.e(869),n.e(251)]).then(n.bind(n,8418)),"component---src-templates-post-index-js-content-file-path-content-posts-how-to-edit-scripts-with-your-favorite-editor-index-md":()=>Promise.all([n.e(869),n.e(748)]).then(n.bind(n,1155)),"component---src-templates-post-index-js-content-file-path-content-posts-inject-into-context-md":()=>Promise.all([n.e(869),n.e(477)]).then(n.bind(n,8071)),"component---src-templates-post-index-js-content-file-path-content-posts-inject-scripts-with-blob-urls-md":()=>Promise.all([n.e(869),n.e(583)]).then(n.bind(n,8604)),"component---src-templates-post-index-js-content-file-path-content-posts-smart-rules-for-blacklist-md":()=>Promise.all([n.e(869),n.e(470)]).then(n.bind(n,6578)),"component---src-templates-post-index-js-content-file-path-content-posts-violentmonkey-workflows-md":()=>Promise.all([n.e(869),n.e(760)]).then(n.bind(n,94)),"component---src-templates-post-index-js-content-file-path-content-privacy-index-md":()=>Promise.all([n.e(869),n.e(814)]).then(n.bind(n,3627)),"component---src-templates-post-index-js-content-file-path-src-components-install-beta-mdx":()=>Promise.all([n.e(869),n.e(609)]).then(n.bind(n,7152)),"component---src-templates-post-index-js-content-file-path-src-components-install-stable-mdx":()=>Promise.all([n.e(869),n.e(74),n.e(6)]).then(n.bind(n,2467))}},8806:function(e,t,n){e.exports=[{plugin:n(7815),options:{plugins:[],trackingIds:["G-2E0X3LSCBM"],gtagConfig:{anonymize_ip:!0},pluginConfig:{exclude:["/auth_**"],head:!1,respectDNT:!1,origin:"https://www.googletagmanager.com",delayOnRouteUpdate:0}}},{plugin:n(8058),options:{plugins:[],icon:"src/assets/vm.png",legacy:!0,theme_color_in_head:!0,cache_busting_mode:"query",crossOrigin:"anonymous",include_favicon:!0,cacheDigest:"e0d9ed50fb982761b0f7cdea8b093ae9"}},{plugin:n(4650),options:{plugins:[],offsetY:70,className:"anchor"}},{plugin:n(1468),options:{plugins:[],backgroundColor:"transparent",linkImagesToOriginal:!1,maxWidth:650,showCaptions:!1,markdownCaptions:!1,quality:50,withWebp:!1,withAvif:!1,loading:"lazy",decoding:"async",disableBgImageOnAlpha:!1,disableBgImage:!1}},{plugin:n(4254),options:{plugins:[]}},{plugin:n(1873),options:{plugins:[]}},{plugin:n(9120),options:{plugins:[]}}]},4303:function(e,t,n){n(6851),n(2859);const r=n(8806),{getResourceURLsForPathname:o,loadPage:a,loadPageSync:i}=n(1026).Zf;t.N=(e,t={},n,l)=>{let s=r.map((n=>{if(!n.plugin[e])return;t.getResourceURLsForPathname=o,t.loadPage=a,t.loadPageSync=i;const r=n.plugin[e](t,n.options);return r&&l&&(t=l({args:t,result:r,plugin:n})),r}));return s=s.filter((e=>void 0!==e)),s.length>0?s:n?[n]:[]},t.v=(e,t,n)=>r.reduce(((n,r)=>r.plugin[e]?n.then((()=>r.plugin[e](t,r.options))):n),Promise.resolve())},5747:function(e,t){t.U=()=>""},5961:function(e,t,n){"use strict";n.d(t,{A:function(){return r}});var r=function(e){return e=e||Object.create(null),{on:function(t,n){(e[t]||(e[t]=[])).push(n)},off:function(t,n){e[t]&&e[t].splice(e[t].indexOf(n)>>>0,1)},emit:function(t,n){(e[t]||[]).slice().map((function(e){e(n)})),(e["*"]||[]).slice().map((function(e){e(t,n)}))}}}()},4043:function(e,t,n){"use strict";n.d(t,{Yl:function(){return d},Hh:function(){return h},UA:function(){return p},QX:function(){return f}});n(3763),n(5376),n(6748),n(9387);var r=n(9356),o=n(3334),a=e=>{if(void 0===e)return e;let[t,n=""]=e.split("?");return n&&(n="?"+n),"/"===t?"/"+n:"/"===t.charAt(t.length-1)?t.slice(0,-1)+n:t+n},i=n(2364);const l=new Map;let s=[];const u=e=>{let t=e;if(-1!==e.indexOf("?")){const[n,r]=e.split("?");t=`${n}?${encodeURIComponent(r)}`}const n=decodeURIComponent(t);return(0,o.A)(n,decodeURIComponent("")).split("#")[0]};function c(e){return e.startsWith("/")||e.startsWith("https://")||e.startsWith("http://")?e:new URL(e,window.location.href+(window.location.href.endsWith("/")?"":"/")).pathname}const f=e=>{s=e},d=e=>{const t=m(e),n=s.map((({path:e,matchPath:t})=>({path:t,originalPath:e}))),o=(0,r.pick)(n,t);return o?a(o.route.originalPath):null},p=e=>{const t=m(e),n=s.map((({path:e,matchPath:t})=>({path:t,originalPath:e}))),o=(0,r.pick)(n,t);return o?o.params:{}},h=e=>{const t=u(c(e));if(l.has(t))return l.get(t);const n=(0,i.X)(e);if(n)return h(n.toPath);let r=d(t);return r||(r=m(e)),l.set(t,r),r},m=e=>{let t=u(c(e));return"/index.html"===t&&(t="/"),t=a(t),t}},8136:function(e,t,n){"use strict";n.r(t),n.d(t,{Link:function(){return l.N_},PageRenderer:function(){return a()},Script:function(){return S.Script},ScriptStrategy:function(){return S.ScriptStrategy},Slice:function(){return b},StaticQuery:function(){return s.de},StaticQueryContext:function(){return s.G},collectedScriptsByPage:function(){return S.collectedScriptsByPage},graphql:function(){return E},navigate:function(){return l.oo},parsePath:function(){return l.Rr},prefetchPathname:function(){return x},scriptCache:function(){return S.scriptCache},scriptCallbackCache:function(){return S.scriptCallbackCache},useScrollRestoration:function(){return i.RV},useStaticQuery:function(){return s.GR},withAssetPrefix:function(){return l.Zf},withPrefix:function(){return l.Fe}});var r=n(1026),o=n(9318),a=n.n(o),i=n(4730),l=n(7243),s=n(9092),u=(n(3763),n(116),n(5376),n(9474)),c=n(8595),f=n(5747),d=n(7729);const p=({sliceId:e,children:t})=>{const n=[u.createElement("slice-start",{id:`${e}-1`}),u.createElement("slice-end",{id:`${e}-1`})];return t&&(n.push(t),n.push(u.createElement("slice-start",{id:`${e}-2`}),u.createElement("slice-end",{id:`${e}-2`}))),n},h=["sliceName","allowEmpty","children"],m=e=>{let{sliceName:t,allowEmpty:n,children:r}=e,o=(0,c.A)(e,h);const a=(0,u.useContext)(d.Jr),i=(0,u.useContext)(d.hr),l=a[t];if(!l){if(n)return null;throw new Error(`Slice "${l}" for "${t}" slot not found`)}const s=((e,t)=>Object.keys(t).length?`${e}-${(0,f.U)(t)}`:e)(l,o);let m=i[s];return m?r&&(m.hasChildren=!0):i[s]=m={props:o,sliceName:l,hasChildren:!!r},u.createElement(p,{sliceId:s},r)};var v=n(4432);const g=["sliceName","allowEmpty","children"],y=e=>{let{sliceName:t,allowEmpty:n,children:r}=e,o=(0,c.A)(e,g);const a=(0,u.useContext)(d.Jr),i=(0,u.useContext)(d.dd),l=a[t],s=i.get(l);if(!s){if(n)return null;throw new Error(`Slice "${l}" for "${t}" slot not found`)}return u.createElement(s.component,(0,v.A)({sliceContext:s.sliceContext,data:s.data},o),r)};function b(e){{const n=Object.assign({},e,{sliceName:e.alias});delete n.alias,delete n.__renderedByLocation;const r=(0,u.useContext)(d.j$),o=k(e);if(Object.keys(o).length)throw new w("browser"===r.renderEnvironment,n.sliceName,o,e.__renderedByLocation);if("server"===r.renderEnvironment)return u.createElement(m,n);if("browser"===r.renderEnvironment)return u.createElement(y,n);if("engines"===r.renderEnvironment||"dev-ssr"===r.renderEnvironment)return u.createElement(y,n);if("slices"===r.renderEnvironment){let n="";try{n=`\n\nSlice component "${r.sliceRoot.name}" (${r.sliceRoot.componentPath}) tried to render `}catch(t){}throw new Error(`Nested slices are not supported.${n}\n\nSee https://gatsbyjs.com/docs/reference/built-in-components/gatsby-slice#nested-slices`)}throw new Error(`Slice context "${r.renderEnvironment}" is not supported.`)}}class w extends Error{constructor(e,t,n,r){const o=Object.entries(n).map((([e,t])=>`not serializable "${t}" type passed to "${e}" prop`)).join(", "),a="SlicePropsError";let i="",l="";if(e){const e=u.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactDebugCurrentFrame.getCurrentStack().trim().split("\n").slice(1);e[0]=e[0].trim(),i="\n"+e.join("\n"),l=`Slice "${t}" was passed props that are not serializable (${o}).`}else{l=`${a}: Slice "${t}" was passed props that are not serializable (${o}).`;i=`${l}\n${(new Error).stack.trim().split("\n").slice(2).join("\n")}`}super(l),this.name=a,i?this.stack=i:Error.captureStackTrace(this,w),r&&(this.forcedLocation=Object.assign({},r,{functionName:"Slice"}))}}const k=(e,t={},n=[],r=null)=>{for(const[o,a]of Object.entries(e)){if(null==a||!r&&"children"===o)continue;const e=r?`${r}.${o}`:o;"function"==typeof a?t[e]=typeof a:"object"==typeof a&&n.indexOf(a)<=0&&(n.push(a),k(a,t,n,e))}return t};var S=n(8573);const x=r.Ay.enqueue;function E(){throw new Error("It appears like Gatsby is misconfigured. Gatsby related `graphql` calls are supposed to only be evaluated at compile time, and then compiled away. Unfortunately, something went wrong and the query was left in the compiled code.\n\nUnless your site has a complex or custom babel/Gatsby configuration this is likely a bug in Gatsby.")}},1026:function(e,t,n){"use strict";n.d(t,{Wi:function(){return u},N5:function(){return y},Ay:function(){return S},Rh:function(){return E},LE:function(){return x},Zf:function(){return k},iC:function(){return w}});n(4724),n(3763),n(2859),n(1622),n(987),n(2445),n(5376);var r=n(6821);const o=function(e){if("undefined"==typeof document)return!1;const t=document.createElement("link");try{if(t.relList&&"function"==typeof t.relList.supports)return t.relList.supports(e)}catch(n){return!1}return!1}("prefetch")?function(e,t){return new Promise(((n,r)=>{if("undefined"==typeof document)return void r();const o=document.createElement("link");o.setAttribute("rel","prefetch"),o.setAttribute("href",e),Object.keys(t).forEach((e=>{o.setAttribute(e,t[e])})),o.onload=n,o.onerror=r;(document.getElementsByTagName("head")[0]||document.getElementsByName("script")[0].parentNode).appendChild(o)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.onload=()=>{200===r.status?t():n()},r.send(null)}))},a={};var i=function(e,t){return new Promise((n=>{a[e]?n():o(e,t).then((()=>{n(),a[e]=!0})).catch((()=>{}))}))},l=n(5961),s=n(4043);const u={Error:"error",Success:"success"},c=e=>{const[t,n]=e.split("?");var r;return`/page-data/${"/"===t?"index":(r="/"===(r=t)[0]?r.slice(1):r).endsWith("/")?r.slice(0,-1):r}/page-data.json${n?`?${n}`:""}`},f=e=>e.startsWith("//");function d(e,t="GET"){return new Promise((n=>{const r=new XMLHttpRequest;r.open(t,e,!0),r.onreadystatechange=()=>{4==r.readyState&&n(r)},r.send(null)}))}const p=/bot|crawler|spider|crawling/i,h=(e,t=null,n)=>{var r;const o={componentChunkName:e.componentChunkName,path:e.path,webpackCompilationHash:e.webpackCompilationHash,matchPath:e.matchPath,staticQueryHashes:e.staticQueryHashes,getServerDataError:e.getServerDataError,slicesMap:null!==(r=e.slicesMap)&&void 0!==r?r:{}};return{component:t,head:n,json:e.result,page:o}};function m(e){return new Promise((t=>{try{const n=e.readRoot();t(n)}catch(n){if(!Object.hasOwnProperty.call(n,"_response")||!Object.hasOwnProperty.call(n,"_status"))throw n;setTimeout((()=>{m(e).then(t)}),200)}}))}class v{constructor(e,t){this.inFlightNetworkRequests=new Map,this.pageDb=new Map,this.inFlightDb=new Map,this.staticQueryDb={},this.pageDataDb=new Map,this.partialHydrationDb=new Map,this.slicesDataDb=new Map,this.sliceInflightDb=new Map,this.slicesDb=new Map,this.isPrefetchQueueRunning=!1,this.prefetchQueued=[],this.prefetchTriggered=new Set,this.prefetchCompleted=new Set,this.loadComponent=e,(0,s.QX)(t)}memoizedGet(e){let t=this.inFlightNetworkRequests.get(e);return t||(t=d(e,"GET"),this.inFlightNetworkRequests.set(e,t)),t.then((t=>(this.inFlightNetworkRequests.delete(e),t))).catch((t=>{throw this.inFlightNetworkRequests.delete(e),t}))}setApiRunner(e){this.apiRunner=e,this.prefetchDisabled=e("disableCorePrefetching").some((e=>e))}fetchPageDataJson(e){const{pagePath:t,retries:n=0}=e,r=c(t);return this.memoizedGet(r).then((r=>{const{status:o,responseText:a}=r;if(200===o)try{const n=JSON.parse(a);if(void 0===n.path)throw new Error("not a valid pageData response");const r=t.split("?")[1];return r&&!n.path.includes(r)&&(n.path+=`?${r}`),Object.assign(e,{status:u.Success,payload:n})}catch(i){}return 404===o||200===o?"/404.html"===t||"/500.html"===t?Object.assign(e,{status:u.Error}):this.fetchPageDataJson(Object.assign(e,{pagePath:"/404.html",notFound:!0})):500===o?this.fetchPageDataJson(Object.assign(e,{pagePath:"/500.html",internalServerError:!0})):n<3?this.fetchPageDataJson(Object.assign(e,{retries:n+1})):Object.assign(e,{status:u.Error})}))}fetchPartialHydrationJson(e){const{pagePath:t,retries:n=0}=e,r=c(t).replace(".json","-rsc.json");return this.memoizedGet(r).then((r=>{const{status:o,responseText:a}=r;if(200===o)try{return Object.assign(e,{status:u.Success,payload:a})}catch(i){}return 404===o||200===o?"/404.html"===t||"/500.html"===t?Object.assign(e,{status:u.Error}):this.fetchPartialHydrationJson(Object.assign(e,{pagePath:"/404.html",notFound:!0})):500===o?this.fetchPartialHydrationJson(Object.assign(e,{pagePath:"/500.html",internalServerError:!0})):n<3?this.fetchPartialHydrationJson(Object.assign(e,{retries:n+1})):Object.assign(e,{status:u.Error})}))}loadPageDataJson(e){const t=(0,s.Hh)(e);if(this.pageDataDb.has(t)){const e=this.pageDataDb.get(t);return Promise.resolve(e)}return this.fetchPageDataJson({pagePath:t}).then((e=>(this.pageDataDb.set(t,e),e)))}loadPartialHydrationJson(e){const t=(0,s.Hh)(e);if(this.partialHydrationDb.has(t)){const e=this.partialHydrationDb.get(t);return Promise.resolve(e)}return this.fetchPartialHydrationJson({pagePath:t}).then((e=>(this.partialHydrationDb.set(t,e),e)))}loadSliceDataJson(e){if(this.slicesDataDb.has(e)){const t=this.slicesDataDb.get(e);return Promise.resolve({sliceName:e,jsonPayload:t})}return d(`/slice-data/${e}.json`,"GET").then((t=>{const n=JSON.parse(t.responseText);return this.slicesDataDb.set(e,n),{sliceName:e,jsonPayload:n}}))}findMatchPath(e){return(0,s.Yl)(e)}loadPage(e){const t=(0,s.Hh)(e);if(this.pageDb.has(t)){const e=this.pageDb.get(t);return e.error?Promise.resolve({error:e.error,status:e.status}):Promise.resolve(e.payload)}if(this.inFlightDb.has(t))return this.inFlightDb.get(t);const n=[this.loadAppData(),this.loadPageDataJson(t)];const o=Promise.all(n).then((e=>{const[n,o,a]=e;if(o.status===u.Error||(null==a?void 0:a.status)===u.Error)return{status:u.Error};let i=o.payload;const{componentChunkName:s,staticQueryHashes:c=[],slicesMap:f={}}=i,d={},p=Array.from(new Set(Object.values(f))),v=e=>{if(this.slicesDb.has(e.name))return this.slicesDb.get(e.name);if(this.sliceInflightDb.has(e.name))return this.sliceInflightDb.get(e.name);const t=this.loadComponent(e.componentChunkName).then((t=>{return{component:(n=t,n&&n.default||n),sliceContext:e.result.sliceContext,data:e.result.data};var n}));return this.sliceInflightDb.set(e.name,t),t.then((t=>{this.slicesDb.set(e.name,t),this.sliceInflightDb.delete(e.name)})),t};return Promise.all(p.map((e=>this.loadSliceDataJson(e)))).then((e=>{const f=[],p=[...c];for(const{jsonPayload:t,sliceName:n}of Object.values(e)){f.push(Object.assign({name:n},t));for(const e of t.staticQueryHashes)p.includes(e)||p.push(e)}const g=[Promise.all(f.map(v)),this.loadComponent(s,"head")];g.push(this.loadComponent(s));const y=Promise.all(g).then((e=>{const[t,l,s]=e;d.createdAt=new Date;for(const n of t)(!n||n instanceof Error)&&(d.status=u.Error,d.error=n);let c;if((!s||s instanceof Error)&&(d.status=u.Error,d.error=s),d.status!==u.Error){if(d.status=u.Success,!0!==o.notFound&&!0!==(null==a?void 0:a.notFound)||(d.notFound=!0),i=Object.assign(i,{webpackCompilationHash:n?n.webpackCompilationHash:""}),"string"==typeof(null==a?void 0:a.payload)){c=h(i,null,l),c.partialHydration=a.payload;const e=new ReadableStream({start(e){const t=new TextEncoder;e.enqueue(t.encode(a.payload))},pull(e){e.close()},cancel(){}});return m((0,r.createFromReadableStream)(e)).then((e=>(c.partialHydration=e,c)))}c=h(i,s,l)}return c})),b=Promise.all(p.map((e=>{if(this.staticQueryDb[e]){const t=this.staticQueryDb[e];return{staticQueryHash:e,jsonPayload:t}}return this.memoizedGet(`/page-data/sq/d/${e}.json`).then((t=>{const n=JSON.parse(t.responseText);return{staticQueryHash:e,jsonPayload:n}})).catch((()=>{throw new Error(`We couldn't load "/page-data/sq/d/${e}.json"`)}))}))).then((e=>{const t={};return e.forEach((({staticQueryHash:e,jsonPayload:n})=>{t[e]=n,this.staticQueryDb[e]=n})),t}));return Promise.all([y,b]).then((([e,n])=>{let r;return e&&(r=Object.assign({},e,{staticQueryResults:n}),d.payload=r,l.A.emit("onPostLoadPageResources",{page:r,pageResources:r})),this.pageDb.set(t,d),d.error?{error:d.error,status:d.status}:r})).catch((e=>({error:e,status:u.Error})))}))}));return o.then((()=>{this.inFlightDb.delete(t)})).catch((e=>{throw this.inFlightDb.delete(t),e})),this.inFlightDb.set(t,o),o}loadPageSync(e,t={}){const n=(0,s.Hh)(e);if(this.pageDb.has(n)){const e=this.pageDb.get(n);if(e.payload)return e.payload;if(null!=t&&t.withErrorDetails)return{error:e.error,status:e.status}}}shouldPrefetch(e){return!!(()=>{if("connection"in navigator&&void 0!==navigator.connection){if((navigator.connection.effectiveType||"").includes("2g"))return!1;if(navigator.connection.saveData)return!1}return!0})()&&((!navigator.userAgent||!p.test(navigator.userAgent))&&!this.pageDb.has(e))}prefetch(e){if(!this.shouldPrefetch(e))return{then:e=>e(!1),abort:()=>{}};if(this.prefetchTriggered.has(e))return{then:e=>e(!0),abort:()=>{}};const t={resolve:null,reject:null,promise:null};t.promise=new Promise(((e,n)=>{t.resolve=e,t.reject=n})),this.prefetchQueued.push([e,t]);const n=new AbortController;return n.signal.addEventListener("abort",(()=>{const t=this.prefetchQueued.findIndex((([t])=>t===e));-1!==t&&this.prefetchQueued.splice(t,1)})),this.isPrefetchQueueRunning||(this.isPrefetchQueueRunning=!0,setTimeout((()=>{this._processNextPrefetchBatch()}),3e3)),{then:(e,n)=>t.promise.then(e,n),abort:n.abort.bind(n)}}_processNextPrefetchBatch(){(window.requestIdleCallback||(e=>setTimeout(e,0)))((()=>{const e=this.prefetchQueued.splice(0,4),t=Promise.all(e.map((([e,t])=>(this.prefetchTriggered.has(e)||(this.apiRunner("onPrefetchPathname",{pathname:e}),this.prefetchTriggered.add(e)),this.prefetchDisabled?t.resolve(!1):this.doPrefetch((0,s.Hh)(e)).then((()=>{this.prefetchCompleted.has(e)||(this.apiRunner("onPostPrefetchPathname",{pathname:e}),this.prefetchCompleted.add(e)),t.resolve(!0)}))))));this.prefetchQueued.length?t.then((()=>{setTimeout((()=>{this._processNextPrefetchBatch()}),3e3)})):this.isPrefetchQueueRunning=!1}))}doPrefetch(e){const t=c(e);return i(t,{crossOrigin:"anonymous",as:"fetch"}).then((()=>this.loadPageDataJson(e)))}hovering(e){this.loadPage(e)}getResourceURLsForPathname(e){const t=(0,s.Hh)(e),n=this.pageDataDb.get(t);if(n){const e=h(n.payload);return[...g(e.page.componentChunkName),c(t)]}return null}isPageNotFound(e){const t=(0,s.Hh)(e),n=this.pageDb.get(t);return!n||n.notFound}loadAppData(e=0){return this.memoizedGet("/page-data/app-data.json").then((t=>{const{status:n,responseText:r}=t;let o;if(200!==n&&e<3)return this.loadAppData(e+1);if(200===n)try{const e=JSON.parse(r);if(void 0===e.webpackCompilationHash)throw new Error("not a valid app-data response");o=e}catch(a){}return o}))}}const g=e=>(window.___chunkMapping[e]||[]).map((e=>""+e));class y extends v{constructor(e,t,n){super(((t,n="components")=>{if(!e[n="components"][t])throw new Error(`We couldn't find the correct component chunk with the name "${t}"`);return e[n][t]().catch((e=>e))}),t),n&&this.pageDataDb.set((0,s.Hh)(n.path),{pagePath:n.path,payload:n,status:"success"})}doPrefetch(e){return super.doPrefetch(e).then((e=>{if(e.status!==u.Success)return Promise.resolve();const t=e.payload,n=t.componentChunkName,r=g(n);return Promise.all(r.map(i)).then((()=>t))}))}loadPageDataJson(e){return super.loadPageDataJson(e).then((t=>t.notFound?f(e)?t:d(e,"HEAD").then((e=>200===e.status?{status:u.Error}:t)):t))}loadPartialHydrationJson(e){return super.loadPartialHydrationJson(e).then((t=>t.notFound?f(e)?t:d(e,"HEAD").then((e=>200===e.status?{status:u.Error}:t)):t))}}let b;const w=e=>{b=e},k={enqueue:e=>b.prefetch(e),getResourceURLsForPathname:e=>b.getResourceURLsForPathname(e),loadPage:e=>b.loadPage(e),loadPageSync:(e,t={})=>b.loadPageSync(e,t),prefetch:e=>b.prefetch(e),isPageNotFound:e=>b.isPageNotFound(e),hovering:e=>b.hovering(e),loadAppData:()=>b.loadAppData()};var S=k;function x(){return b?b.staticQueryDb:{}}function E(){return b?b.slicesDb:{}}},9390:function(e,t,n){"use strict";n.d(t,{A:function(){return x}});var r=n(9474),o=n(2736),a=n.n(o),i=n(4303),l=n(4043),s=(n(4724),n(3763),n(5376),n(8136)),u=n(9356),c=n(7257);function f({children:e,callback:t}){return(0,r.useEffect)((()=>{t()})),e}n(2445);const d=["link","meta","style","title","base","noscript","script","html","body"];function p(e,t){if(e instanceof HTMLElement&&t instanceof HTMLElement){const n=t.getAttribute("nonce");if(n&&!e.getAttribute("nonce")){const r=t.cloneNode(!0);return r.setAttribute("nonce",""),r.nonce=n,n===e.nonce&&e.isEqualNode(r)}}return e.isEqualNode(t)}function h(e,t={html:{},body:{}}){const n=new Map,r=[];for(const s of e.childNodes){var o,a;const e=s.nodeName.toLowerCase(),u=null===(o=s.attributes)||void 0===o||null===(a=o.id)||void 0===a?void 0:a.value;if(g(s)){if(v(e))if("html"===e||"body"===e)for(const n of s.attributes){const r="style"===n.name;var i;if(t[e]=Object.assign({},t[e]),r||(t[e][n.name]=n.value),r)t[e].style=`${null!==(i=t[e])&&void 0!==i&&i.style?t[e].style:""}${n.value} `}else{let e=s.cloneNode(!0);if(e.setAttribute("data-gatsby-head",!0),"script"===e.nodeName.toLowerCase()&&(e=m(e)),u)if(n.has(u)){var l;const t=n.get(u);null===(l=r[t].parentNode)||void 0===l||l.removeChild(r[t]),r[t]=e}else r.push(e),n.set(u,r.length-1);else r.push(e)}s.childNodes.length&&r.push(...h(s,t).validHeadNodes)}}return{validHeadNodes:r,htmlAndBodyAttributes:t}}function m(e){const t=document.createElement("script");for(const n of e.attributes)t.setAttribute(n.name,n.value);return t.innerHTML=e.innerHTML,t}function v(e){return d.includes(e)}function g(e){return 1===e.nodeType}const y=document.createElement("div"),b={html:[],body:[]},w=()=>{const{validHeadNodes:e,htmlAndBodyAttributes:t}=h(y);b.html=Object.keys(t.html),b.body=Object.keys(t.body),function(e){if(!e)return;const{html:t,body:n}=e,r=document.querySelector("html");r&&Object.entries(t).forEach((([e,t])=>{r.setAttribute(e,t)}));const o=document.querySelector("body");o&&Object.entries(n).forEach((([e,t])=>{o.setAttribute(e,t)}))}(t);const n=document.querySelectorAll("[data-gatsby-head]");if(0===n.length)return void document.head.append(...e);const r=[];!function({oldNodes:e,newNodes:t,onStale:n,onNew:r}){for(const o of e){const e=t.findIndex((e=>p(e,o)));-1===e?n(o):t.splice(e,1)}for(const o of t)r(o)}({oldNodes:n,newNodes:e,onStale:e=>e.parentNode.removeChild(e),onNew:e=>r.push(e)}),document.head.append(...r)};function k({pageComponent:e,staticQueryResults:t,pageComponentProps:n}){(0,r.useEffect)((()=>{if(null!=e&&e.Head){!function(e){if("function"!=typeof e)throw new Error(`Expected "Head" export to be a function got "${typeof e}".`)}(e.Head);const{render:a}=(0,c.n)(),l=r.createElement(e.Head,{location:{pathname:(o=n).location.pathname},params:o.params,data:o.data||{},serverData:o.serverData,pageContext:o.pageContext}),d=(0,i.N)("wrapRootElement",{element:l},l,(({result:e})=>({element:e}))).pop();a(r.createElement(f,{callback:w},r.createElement(s.StaticQueryContext.Provider,{value:t},r.createElement(u.LocationProvider,null,d))),y)}var o;return()=>{!function(){const e=document.querySelectorAll("[data-gatsby-head]");for(const t of e)t.parentNode.removeChild(t)}(),function(e){if(!e)return;const{html:t,body:n}=e;if(t){const e=document.querySelector("html");t.forEach((t=>{e&&e.removeAttribute(t)}))}if(n){const e=document.querySelector("body");n.forEach((t=>{e&&e.removeAttribute(t)}))}}(b)}}))}function S(e){const t=Object.assign({},e,{params:Object.assign({},(0,l.UA)(e.location.pathname),e.pageResources.json.pageContext.__params)});let n;var o;n=e.pageResources.partialHydration?e.pageResources.partialHydration:(0,r.createElement)((o=e.pageResources.component)&&o.default||o,Object.assign({},t,{key:e.path||e.pageResources.page.path}));k({pageComponent:e.pageResources.head,staticQueryResults:e.pageResources.staticQueryResults,pageComponentProps:t});return(0,i.N)("wrapPageElement",{element:n,props:t},n,(({result:e})=>({element:e,props:t}))).pop()}S.propTypes={location:a().object.isRequired,pageResources:a().object.isRequired,data:a().object,pageContext:a().object.isRequired};var x=S},2056:function(e,t,n){"use strict";var r=n(4432),o=(n(4724),n(1622),n(4303)),a=n(9474),i=n(9356),l=n(4730),s=n(9092),u=n(7729),c=n(2736),f=n.n(c),d=n(1026),p=n(2364),h=n(5961);const m={id:"gatsby-announcer",style:{position:"absolute",top:0,width:1,height:1,padding:0,overflow:"hidden",clip:"rect(0, 0, 0, 0)",whiteSpace:"nowrap",border:0},"aria-live":"assertive","aria-atomic":"true"};var v=n(7243);function g(e){const t=(0,p.X)(e),{hash:n,search:r}=window.location;return null!=t&&(window.___replace(t.toPath+r+n),!0)}let y="";window.addEventListener("unhandledrejection",(e=>{/loading chunk \d* failed./i.test(e.reason)&&y&&(window.location.pathname=y)}));const b=(e,t)=>{g(e.pathname)||(y=e.pathname,(0,o.N)("onPreRouteUpdate",{location:e,prevLocation:t}))},w=(e,t)=>{g(e.pathname)||(0,o.N)("onRouteUpdate",{location:e,prevLocation:t})},k=(e,t={})=>{if("number"==typeof e)return void i.globalHistory.navigate(e);const{pathname:n,search:r,hash:a}=(0,v.Rr)(e),l=(0,p.X)(n);if(l&&(e=l.toPath+r+a),window.___swUpdated)return void(window.location=n+r+a);const s=setTimeout((()=>{h.A.emit("onDelayedLoadPageResources",{pathname:n}),(0,o.N)("onRouteUpdateDelayed",{location:window.location})}),1e3);d.Ay.loadPage(n+r).then((o=>{if(!o||o.status===d.Wi.Error)return window.history.replaceState({},"",location.href),window.location=n,void clearTimeout(s);o&&o.page.webpackCompilationHash!==window.___webpackCompilationHash&&("serviceWorker"in navigator&&null!==navigator.serviceWorker.controller&&"activated"===navigator.serviceWorker.controller.state&&navigator.serviceWorker.controller.postMessage({gatsbyApi:"clearPathResources"}),window.location=n+r+a),(0,i.navigate)(e,t),clearTimeout(s)}))};function S(e,{location:t}){const{pathname:n,hash:r}=t,a=(0,o.N)("shouldUpdateScroll",{prevRouterProps:e,pathname:n,routerProps:{location:t},getSavedScrollPosition:e=>[0,this._stateStorage.read(e,e.key)]});if(a.length>0)return a[a.length-1];if(e){const{location:{pathname:t}}=e;if(t===n)return r?decodeURI(r.slice(1)):[0,0]}return!0}class x extends a.Component{constructor(e){super(e),this.announcementRef=a.createRef()}componentDidUpdate(e,t){requestAnimationFrame((()=>{let e=`new page at ${this.props.location.pathname}`;document.title&&(e=document.title);const t=document.querySelectorAll("#gatsby-focus-wrapper h1");t&&t.length&&(e=t[0].textContent);const n=`Navigated to ${e}`;if(this.announcementRef.current){this.announcementRef.current.innerText!==n&&(this.announcementRef.current.innerText=n)}}))}render(){return a.createElement("div",(0,r.A)({},m,{ref:this.announcementRef}))}}const E=(e,t)=>{var n,r;return e.href!==t.href||(null==e||null===(n=e.state)||void 0===n?void 0:n.key)!==(null==t||null===(r=t.state)||void 0===r?void 0:r.key)};class _ extends a.Component{constructor(e){super(e),b(e.location,null)}componentDidMount(){w(this.props.location,null)}shouldComponentUpdate(e){return!!E(this.props.location,e.location)&&(b(e.location,this.props.location),!0)}componentDidUpdate(e){E(e.location,this.props.location)&&w(this.props.location,e.location)}render(){return a.createElement(a.Fragment,null,this.props.children,a.createElement(x,{location:location}))}}_.propTypes={location:f().object.isRequired};var P=n(9390),C=n(4012);function R(e,t){for(var n in e)if(!(n in t))return!0;for(var r in t)if(e[r]!==t[r])return!0;return!1}class T extends a.Component{constructor(e){super();const{location:t,pageResources:n}=e;this.state={location:Object.assign({},t),pageResources:n||d.Ay.loadPageSync(t.pathname+t.search,{withErrorDetails:!0})}}static getDerivedStateFromProps({location:e},t){if(t.location.href!==e.href){return{pageResources:d.Ay.loadPageSync(e.pathname+e.search,{withErrorDetails:!0}),location:Object.assign({},e)}}return{location:Object.assign({},e)}}loadResources(e){d.Ay.loadPage(e).then((t=>{t&&t.status!==d.Wi.Error?this.setState({location:Object.assign({},window.location),pageResources:t}):(window.history.replaceState({},"",location.href),window.location=e)}))}shouldComponentUpdate(e,t){return t.pageResources?this.state.pageResources!==t.pageResources||(this.state.pageResources.component!==t.pageResources.component||(this.state.pageResources.json!==t.pageResources.json||(!(this.state.location.key===t.location.key||!t.pageResources.page||!t.pageResources.page.matchPath&&!t.pageResources.page.path)||function(e,t,n){return R(e.props,t)||R(e.state,n)}(this,e,t)))):(this.loadResources(e.location.pathname+e.location.search),!1)}render(){return this.props.children(this.state)}}var O=T,N=n(3334),L=n(7257);const j=new d.N5(C,[],window.pageData);(0,d.iC)(j),j.setApiRunner(o.N);const{render:I,hydrate:D}=(0,L.n)();window.asyncRequires=C,window.___emitter=h.A,window.___loader=d.Zf,i.globalHistory.listen((e=>{e.location.action=e.action})),window.___push=e=>k(e,{replace:!1}),window.___replace=e=>k(e,{replace:!0}),window.___navigate=(e,t)=>k(e,t);const M="gatsby-reload-compilation-hash-match";(0,o.v)("onClientEntry").then((()=>{(0,o.N)("registerServiceWorker").filter(Boolean).length>0&&n(9695);const e=e=>a.createElement(i.BaseContext.Provider,{value:{baseuri:"/",basepath:"/"}},a.createElement(P.A,e)),t=a.createContext({}),c={renderEnvironment:"browser"};class f extends a.Component{render(){const{children:e}=this.props;return a.createElement(i.Location,null,(({location:n})=>a.createElement(O,{location:n},(({pageResources:n,location:r})=>{const o=(0,d.LE)(),i=(0,d.Rh)();return a.createElement(s.G.Provider,{value:o},a.createElement(u.j$.Provider,{value:c},a.createElement(u.dd.Provider,{value:i},a.createElement(u.Jr.Provider,{value:n.page.slicesMap},a.createElement(t.Provider,{value:{pageResources:n,location:r}},e)))))}))))}}class p extends a.Component{render(){return a.createElement(t.Consumer,null,(({pageResources:t,location:n})=>a.createElement(_,{location:n},a.createElement(l.z_,{location:n,shouldUpdateScroll:S},a.createElement(i.Router,{basepath:"",location:n,id:"gatsby-focus-wrapper"},a.createElement(e,(0,r.A)({path:"/404.html"===t.page.path||"/500.html"===t.page.path?(0,N.A)(n.pathname,""):encodeURI((t.page.matchPath||t.page.path).split("?")[0])},this.props,{location:n,pageResources:t},t.json)))))))}}const{pagePath:h,location:m}=window;h&&""+h!==m.pathname+(h.includes("?")?m.search:"")&&!(j.findMatchPath((0,N.A)(m.pathname,""))||h.match(/^\/(404|500)(\/?|.html)$/)||h.match(/^\/offline-plugin-app-shell-fallback\/?$/))&&(0,i.navigate)(""+h+(h.includes("?")?"":m.search)+m.hash,{replace:!0});const v=()=>{try{return sessionStorage}catch(e){return null}};d.Zf.loadPage(m.pathname+m.search).then((e=>{var t;const n=v();if(null!=e&&null!==(t=e.page)&&void 0!==t&&t.webpackCompilationHash&&e.page.webpackCompilationHash!==window.___webpackCompilationHash&&("serviceWorker"in navigator&&null!==navigator.serviceWorker.controller&&"activated"===navigator.serviceWorker.controller.state&&navigator.serviceWorker.controller.postMessage({gatsbyApi:"clearPathResources"}),n)){if(!("1"===n.getItem(M)))return n.setItem(M,"1"),void window.location.reload(!0)}if(n&&n.removeItem(M),!e||e.status===d.Wi.Error){const t=`page resources for ${m.pathname} not found. Not rendering React`;if(e&&e.error)throw console.error(t),e.error;throw new Error(t)}const r=(0,o.N)("wrapRootElement",{element:a.createElement(p,null)},a.createElement(p,null),(({result:e})=>({element:e}))).pop(),i=function(){const e=a.useRef(!1);return a.useEffect((()=>{e.current||(e.current=!0,performance.mark&&performance.mark("onInitialClientRender"),(0,o.N)("onInitialClientRender"))}),[]),a.createElement(f,null,r)},l=document.getElementById("gatsby-focus-wrapper");let s=I;l&&l.children.length&&(s=D);const u=(0,o.N)("replaceHydrateFunction",void 0,s)[0];function c(){const e="undefined"!=typeof window?document.getElementById("___gatsby"):null;u(a.createElement(i,null),e)}const h=document;if("complete"===h.readyState||"loading"!==h.readyState&&!h.documentElement.doScroll)setTimeout((function(){c()}),0);else{const e=function(){h.removeEventListener("DOMContentLoaded",e,!1),window.removeEventListener("load",e,!1),c()};h.addEventListener("DOMContentLoaded",e,!1),window.addEventListener("load",e,!1)}}))}))},4966:function(e,t,n){"use strict";n.r(t);var r=n(9474),o=n(2736),a=n.n(o),i=n(1026),l=n(9390);const s=({location:e})=>{const t=i.Ay.loadPageSync(e.pathname);return t?r.createElement(l.A,Object.assign({location:e,pageResources:t},t.json)):null};s.propTypes={location:a().shape({pathname:a().string.isRequired}).isRequired},t.default=s},9318:function(e,t,n){var r;e.exports=(r=n(4966))&&r.default||r},7257:function(e,t,n){"use strict";n.d(t,{n:function(){return o}});n(3763),n(5376);const r=new WeakMap;function o(){const e=n(8088);return{render:(t,n)=>{let o=r.get(n);o||r.set(n,o=e.createRoot(n)),o.render(t)},hydrate:(t,n)=>e.hydrateRoot(n,t)}}},2364:function(e,t,n){"use strict";n.d(t,{X:function(){return i}});n(3763),n(2445),n(5376);var r=JSON.parse('[{"fromPath":"/api/","isPermanent":true,"ignoreCase":true,"redirectInBrowser":true,"toPath":"/api/gm/"},{"fromPath":"/2018/11/23/inject-into-context/","isPermanent":true,"ignoreCase":true,"redirectInBrowser":true,"toPath":"/posts/inject-into-context/"},{"fromPath":"/2017/10/28/inject-scripts-with-blob-urls/","isPermanent":true,"ignoreCase":true,"redirectInBrowser":true,"toPath":"/posts/inject-scripts-with-blob-urls/"},{"fromPath":"/2017/04/15/smart-rules-for-blacklist/","isPermanent":true,"ignoreCase":true,"redirectInBrowser":true,"toPath":"/posts/smart-rules-for-blacklist/"},{"fromPath":"/guide/","isPermanent":true,"ignoreCase":true,"redirectInBrowser":true,"toPath":"/guide/creating-a-userscript/"},{"fromPath":"/2017/03/14/how-to-edit-scripts-with-your-favorite-editor/","isPermanent":true,"ignoreCase":true,"redirectInBrowser":true,"toPath":"/posts/how-to-edit-scripts-with-your-favorite-editor/"}]');const o=new Map,a=new Map;function i(e){let t=o.get(e);return t||(t=a.get(e.toLowerCase())),t}r.forEach((e=>{e.ignoreCase?a.set(e.fromPath,e):o.set(e.fromPath,e)}))},9695:function(e,t,n){"use strict";n.r(t);var r=n(4303);"https:"!==window.location.protocol&&"localhost"!==window.location.hostname?console.error("Service workers can only be used over HTTPS, or on localhost for development"):"serviceWorker"in navigator&&navigator.serviceWorker.register("/sw.js").then((function(e){e.addEventListener("updatefound",(()=>{(0,r.N)("onServiceWorkerUpdateFound",{serviceWorker:e});const t=e.installing;console.log("installingWorker",t),t.addEventListener("statechange",(()=>{switch(t.state){case"installed":navigator.serviceWorker.controller?(window.___swUpdated=!0,(0,r.N)("onServiceWorkerUpdateReady",{serviceWorker:e}),window.___failedResources&&(console.log("resources failed, SW updated - reloading"),window.location.reload())):(console.log("Content is now available offline!"),(0,r.N)("onServiceWorkerInstalled",{serviceWorker:e}));break;case"redundant":console.error("The installing service worker became redundant."),(0,r.N)("onServiceWorkerRedundant",{serviceWorker:e});break;case"activated":(0,r.N)("onServiceWorkerActive",{serviceWorker:e})}}))}))})).catch((function(e){console.error("Error during service worker registration:",e)}))},7729:function(e,t,n){"use strict";n.d(t,{Jr:function(){return i},dd:function(){return o},hr:function(){return l},j$:function(){return a}});var r=n(9474);const o=r.createContext({}),a=r.createContext({}),i=r.createContext({}),l=r.createContext({})},9092:function(e,t,n){"use strict";n.d(t,{de:function(){return c},G:function(){return i},GR:function(){return f}});var r=n(9474),o=n(2736),a=n.n(o);n(541);const i=(l="StaticQuery",s={},r.createServerContext?((e,t=null)=>(globalThis.__SERVER_CONTEXT||(globalThis.__SERVER_CONTEXT={}),globalThis.__SERVER_CONTEXT[e]||(globalThis.__SERVER_CONTEXT[e]=r.createServerContext(e,t)),globalThis.__SERVER_CONTEXT[e]))(l,s):r.createContext(s));var l,s;function u({staticQueryData:e,data:t,query:n,render:o}){const a=t?t.data:e[n]&&e[n].data;return r.createElement(r.Fragment,null,a&&o(a),!a&&r.createElement("div",null,"Loading (StaticQuery)"))}const c=e=>{const{data:t,query:n,render:o,children:a}=e;return r.createElement(i.Consumer,null,(e=>r.createElement(u,{data:t,query:n,render:o||a,staticQueryData:e})))};c.propTypes={data:a().object,query:a().string.isRequired,render:a().func,children:a().func};const f=e=>{var t;r.useContext;const n=r.useContext(i);if(isNaN(Number(e)))throw new Error(`useStaticQuery was called with a string but expects to be called using \`graphql\`. Try this:\n\nimport { useStaticQuery, graphql } from 'gatsby';\n\nuseStaticQuery(graphql\`${e}\`);\n`);if(null!==(t=n[e])&&void 0!==t&&t.data)return n[e].data;throw new Error("The result of this StaticQuery could not be fetched.\n\nThis is likely a bug in Gatsby and if refreshing the page does not fix it, please open an issue in https://github.com/gatsbyjs/gatsby/issues")}},3334:function(e,t,n){"use strict";function r(e,t=""){return t?e===t?"/":e.startsWith(`${t}/`)?e.slice(t.length):e:e}n.d(t,{A:function(){return r}})},1873:function(e,t,n){"use strict";n.r(t),n.d(t,{onRouteUpdate:function(){return o}});n(4724),n(2859);var r=n(9734);function o(){const{hash:e}=window.location;let t;try{t=e&&document.querySelector(e)}catch(n){}if(t){const e=t.getBoundingClientRect(),n=document.scrollingElement;n.scrollTop=n.scrollTop+e.top-70}}n.n(r)().load({google:{families:["Roboto:400,400i,500,700"]}}),document.addEventListener("click",(e=>{var t;const{target:n}=e,r=function(e,t){var n,r,o;const a=null===(n=e.closest("[data-ga-category]"))||void 0===n?void 0:n.dataset.gaCategory,i=null===(r=e.closest("[data-ga-action]"))||void 0===r?void 0:r.dataset.gaAction,l=null===(o=e.closest("[data-ga-label]"))||void 0===o?void 0:o.dataset.gaLabel;return Object.assign({category:"global"},t,a&&{category:a},i&&{action:i},l&&{label:l})}(n,{action:"click"});var o,a;(r.category&&!r.label&&(r.label=null===(t=n.closest("a"))||void 0===t?void 0:t.textContent),r.label)&&(null===(o=(a=window).gtag)||void 0===o||o.call(a,"event","click",{category:r.category,label:r.label}));const i=n.closest("a");(null==i?void 0:i.closest("[data-ga-category=webext-beta]"))&&i.textContent.includes("Firefox")&&(e.preventDefault(),async function(){const{location:e}=window;try{const t=await fetch("https://api.github.com/repos/violentmonkey/violentmonkey/releases"),n=await t.json(),r=n.find((e=>e.prerelease)).assets.find((e=>e.name.endsWith(".xpi")));e.assign(r.browser_download_url)}catch(t){e.assign("https://github.com/violentmonkey/violentmonkey/releases")}}())}))},4254:function(e,t,n){"use strict";n.r(t),n.d(t,{onClientEntry:function(){return s}});var r=n(8136),o=(n(4724),n(9605),n(1622),n(987),n(407)),a=n.n(o);const i=e=>"/"===e[0]?e:`/${e}`,l=(e,t)=>n=>{if(window.___failedResources)return!0;if((e=>0!==e.button||e.altKey||e.ctrlKey||e.metaKey||e.shiftKey)(n))return!0;if((e=>e.defaultPrevented)(n))return!0;const o=(e=>{for(;e.parentNode;e=e.parentNode)if("a"===e.nodeName.toLowerCase())return e;return null})(n.target);if(null==o)return!0;if(!0===(l=o).hasAttribute("download")||!1===(e=>!1===e.hasAttribute("target")||null==e.target||["_self",""].includes(e.target)||"_parent"===e.target&&(!e.ownerDocument.defaultView.parent||e.ownerDocument.defaultView.parent===e.ownerDocument.defaultView)||"_top"===e.target&&(!e.ownerDocument.defaultView.top||e.ownerDocument.defaultView.top===e.ownerDocument.defaultView))(l))return!0;var l;const s=document.createElement("a");""!==o.href&&(s.href=o.href),"SVGAnimatedString"in window&&o.href instanceof SVGAnimatedString&&(s.href=o.href.animVal);const u=document.createElement("a");if(u.href=window.location.href,!1===((e,t)=>e.protocol===t.protocol&&e.host===t.host)(u,s))return!0;const c=new RegExp(`^${a()((0,r.withPrefix)("/"))}`);if(((e,t)=>!1===t.test(i(e.pathname))||-1!==e.pathname.search(/^.*\.((?!htm)[a-z0-9]{1,5})$/i))(s,c))return!0;if(((e,t)=>""!==t.hash&&(""===t.pathname||t.pathname===e.pathname))(u,s))return!0;if(t.excludePattern){if(new RegExp(t.excludePattern).test(s.pathname))return!0}n.preventDefault();const f=i(s.pathname).replace(c,"/");return e(`${f}${s.search}${s.hash}`),!1};const s=(e,t={})=>{!function(e,t,n){const r=l(n,t);e.addEventListener("click",r)}(window,t,(e=>{(0,r.navigate)(e)}))}},7815:function(e,t,n){"use strict";n(1622),t.onRouteUpdate=function(e,t){var n=e.location;if(void 0===t&&(t={}),"function"!=typeof gtag)return null;var r=t.pluginConfig||{};if(n&&void 0!==window.excludeGtagPaths&&window.excludeGtagPaths.some((function(e){return e.test(n.pathname)})))return null;var o=function(){var e=n?n.pathname+n.search+n.hash:void 0;window.gtag("event","page_view",{page_path:e})},a=r.delayOnRouteUpdate,i=void 0===a?0:a;return"requestAnimationFrame"in window?requestAnimationFrame((function(){requestAnimationFrame((function(){return setTimeout(o,i)}))})):setTimeout(o,32+i),null}},8058:function(e,t,n){"use strict";n.r(t),n.d(t,{onRouteUpdate:function(){return r}});n(8136),n(2550);const r=function({location:e},t){0}},2550:function(e,t,n){"use strict";var r=n(8136)},4650:function(e,t,n){"use strict";n(1622),n(987);var r=0,o=function(e){var t=window.decodeURI(e.replace("#",""));if(""!==t){var n=document.getElementById(t);if(n){var o=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop,a=document.documentElement.clientTop||document.body.clientTop||0,i=window.getComputedStyle(n),l=i.getPropertyValue("scroll-margin-top")||i.getPropertyValue("scroll-snap-margin-top")||"0px";return n.getBoundingClientRect().top+o-parseInt(l,10)-a-r}}return null};t.onInitialClientRender=function(e,t){t.offsetY&&(r=t.offsetY),requestAnimationFrame((function(){var e=o(window.location.hash);null!==e&&window.scrollTo(0,e)}))},t.shouldUpdateScroll=function(e){var t=e.routerProps.location,n=o(t.hash);return null===n||[0,n]}},2068:function(e,t){"use strict";t.DEFAULT_OPTIONS={maxWidth:650,wrapperStyle:"",backgroundColor:"white",linkImagesToOriginal:!0,showCaptions:!1,markdownCaptions:!1,withWebp:!1,withAvif:!1,tracedSVG:!1,loading:"lazy",decoding:"async",disableBgImageOnAlpha:!1,disableBgImage:!1},t.EMPTY_ALT="GATSBY_EMPTY_ALT",t.imageClass="gatsby-resp-image-image",t.imageWrapperClass="gatsby-resp-image-wrapper",t.imageBackgroundClass="gatsby-resp-image-background-image"},1468:function(e,t,n){"use strict";var r=n(2068),o=r.DEFAULT_OPTIONS,a=r.imageClass,i=r.imageBackgroundClass,l=r.imageWrapperClass;t.onRouteUpdate=function(e,t){for(var n=Object.assign({},o,t),r=document.querySelectorAll("."+l),s=function(){var e=r[u],t=e.querySelector("."+i),o=e.querySelector("."+a),l=function(){t.style.transition="opacity 0.5s 0.5s",o.style.transition="opacity 0.5s",s()},s=function e(){t.style.opacity=0,o.style.opacity=1,o.style.color="inherit",o.style.boxShadow="inset 0px 0px 0px 400px "+n.backgroundColor,o.removeEventListener("load",l),o.removeEventListener("error",e)};o.style.opacity=0,o.addEventListener("load",l),o.addEventListener("error",s),o.complete&&s()},u=0;u