├── .gitignore ├── src ├── assets │ ├── icon-128.png │ └── icon-16.png ├── pages │ ├── options.html │ ├── blocked.js │ └── blocked.html ├── manifest.json └── index.js ├── package.json ├── eslint.config.mjs ├── README.md └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .DS_Store 3 | .eslintcache 4 | -------------------------------------------------------------------------------- /src/assets/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdguardTeam/dns-sde-extension/HEAD/src/assets/icon-128.png -------------------------------------------------------------------------------- /src/assets/icon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdguardTeam/dns-sde-extension/HEAD/src/assets/icon-16.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ag-dns-sde-demo", 3 | "description": "A simple DNS server for Agama SDE", 4 | "version": "0.1.1", 5 | "license": "GPL-3.0", 6 | "scripts": { 7 | "lint": "eslint --cache --max-warnings=0 ." 8 | }, 9 | "devDependencies": { 10 | "@eslint/js": "^9.13.0", 11 | "@stylistic/eslint-plugin-js": "^2.10.0", 12 | "eslint": "^9.13.0", 13 | "globals": "^15.11.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import globals from "globals"; 2 | import pluginJs from "@eslint/js"; 3 | import stylisticJs from '@stylistic/eslint-plugin-js' 4 | 5 | export default [ 6 | { 7 | languageOptions: { 8 | globals: { 9 | ...globals.browser, 10 | chrome: 'readonly', 11 | }, 12 | }, 13 | plugins: { 14 | '@stylistic/js': stylisticJs, 15 | }, 16 | rules: { 17 | indent: [ 18 | 'error', 19 | 4, 20 | { 21 | SwitchCase: 1, 22 | ignoreComments: false, 23 | }, 24 | ], 25 | '@stylistic/js/indent': ['error', 4], 26 | 'max-len': ['error', { 27 | code: 120, 28 | comments: 120, 29 | tabWidth: 4, 30 | ignoreUrls: true, 31 | }], 32 | } 33 | }, 34 | pluginJs.configs.recommended, 35 | ]; 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AdGuard DNS SDE Demo Extension 2 | 3 | This browser extension demonstrates how Structured DNS errors can work if supported natively by browsers. 4 | It listens for web requests and identifies loading errors on main frames. 5 | When an error is detected, it queries the AdGuard DNS DoH (DNS-over-HTTPS) service 6 | with structured DNS errors enabled to check if the page was blocked. 7 | 8 | If AdGuard DNS has blocked the page, the extension displays a custom block page 9 | with detailed information about the block. 10 | 11 | ## How to use 12 | 13 | 1. Go to `chrome://extensions/`. 14 | 1. Enable developer mode. 15 | 1. Install the extension from `src` directory by clicking `Load unpacked`. 16 | 1. The extension options page will open. 17 | 1. Set the AdGuard DNS custom server due to the instructions on the options page. 18 | 19 | > **Note:** No other DNS should be set on the system level or in your network settings. 20 | 21 | ## Permissions required 22 | 23 | - `webRequest` - necessary for detecting tab loading errors. 24 | -------------------------------------------------------------------------------- /src/pages/options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |

10 | This extension demonstrates how Structured DNS errors can work if supported natively by browsers. 11 |

12 | 13 |

14 | You should first configure your browser to use AdGuard DNS: 15 |

16 | 17 |
    18 |
  1. Open Security settings in a new tab: chrome://settings/security
  2. 19 |
  3. Enable Use secure DNS
  4. 20 |
  5. In Select DNS provider choose Add custom DNS service provider
  6. 21 |
  7. Enter https://dns.adguard-dns.com/dns-query
  8. 22 |
23 | 24 |

25 | Now every time you try to open a website blocked by AdGuard DNS, the extension will detect that and show you a page indicating that the page was blocked by DNS. 26 | 27 | To see an example try visiting ad.doubleclick.net. 28 |

29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AdGuard DNS SDE Demo", 3 | "description": "This extension demonstrates how Structured DNS errors can work if supported natively by browsers.", 4 | "version": "0.1.1", 5 | "manifest_version": 3, 6 | "author": "Adguard Software Ltd", 7 | "background": { 8 | "service_worker": "index.js" 9 | }, 10 | "permissions": [ 11 | "webRequest" 12 | ], 13 | "host_permissions": [ 14 | "*://*/*" 15 | ], 16 | "icons": { 17 | "16": "assets/icon-16.png", 18 | "128": "assets/icon-128.png" 19 | }, 20 | "action": { 21 | "default_icon": { 22 | "16": "assets/icon-16.png", 23 | "128": "assets/icon-128.png" 24 | } 25 | }, 26 | "web_accessible_resources": [ 27 | { 28 | "resources": [ 29 | "pages/blocked.html" 30 | ], 31 | "matches": [ 32 | "" 33 | ] 34 | } 35 | ], 36 | "options_ui": { 37 | "page": "pages/options.html", 38 | "open_in_tab": false 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/pages/blocked.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Minimal value of window.history.length for a blocked page — 3 | * when a new tab is opened (+1) and the blocked page is shown after redirection (+1). 4 | * That's why it is not usual `1` but `2`. 5 | */ 6 | const MIN_BLOCKED_PAGE_HISTORY_LENGTH = 2; 7 | 8 | /** 9 | * Replaces placeholders in the HTML with the values passed from the URL query params. 10 | * 11 | * Should be used in `blocked.html`. 12 | */ 13 | const replacePlaceholders = () => { 14 | const urlParams = new URLSearchParams(window.location.search); 15 | const whoBlocked = urlParams.get('whoBlocked'); 16 | const hostname = urlParams.get('hostname'); 17 | const reason = urlParams.get('reason'); 18 | const contactLink = urlParams.get('contactLink'); 19 | 20 | const titleElement = document.getElementById('whoBlocked'); 21 | titleElement.textContent = titleElement.textContent.replace('${whoBlocked}', whoBlocked); 22 | 23 | const descriptionElement = document.getElementById('reason'); 24 | descriptionElement.textContent = descriptionElement.textContent.replace('${hostname}', hostname); 25 | descriptionElement.textContent = descriptionElement.textContent.replace('${reason}', reason); 26 | 27 | document.getElementById('contactLink').href = contactLink; 28 | }; 29 | 30 | /** 31 | * Handles the 'Go back' button click event: 32 | * - if page was opened in the same tab, goes back to the previous page; 33 | * - if page was opened in a new tab, closes the tab. 34 | */ 35 | const handleGoBackButtonClick = () => { 36 | const goBackButton = document.getElementById('backBtn'); 37 | goBackButton.addEventListener('click', () => { 38 | // if the history length is greater than 2, go back to the previous page 39 | if (window.history.length > MIN_BLOCKED_PAGE_HISTORY_LENGTH) { 40 | try { 41 | window.history.go(-MIN_BLOCKED_PAGE_HISTORY_LENGTH); 42 | } catch (e) { 43 | console.error(`Error while going back: ${e}`); 44 | } 45 | } else { 46 | window.close(); 47 | } 48 | }); 49 | }; 50 | 51 | /** 52 | * Handles click events on _toggle details_. 53 | */ 54 | const handleToggleDetailsButtonClick = () => { 55 | const toggleButtons = document.querySelectorAll('.faq-item__toggle-btn'); 56 | 57 | toggleButtons.forEach((button) => { 58 | button.addEventListener('click', () => { 59 | button.classList.toggle('active'); 60 | 61 | const content = button.closest('.faq-item').querySelector('.faq-item__content'); 62 | content.classList.toggle('active'); 63 | }); 64 | }); 65 | }; 66 | 67 | const main = () => { 68 | document.addEventListener('DOMContentLoaded', async () => { 69 | replacePlaceholders(); 70 | handleGoBackButtonClick(); 71 | handleToggleDetailsButtonClick(); 72 | }); 73 | }; 74 | 75 | main(); 76 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * URL pattern to match all URLs. 3 | */ 4 | const ALL_URLS_PATTERN = ''; 5 | 6 | /** 7 | * Type of the main frame. 8 | */ 9 | const MAIN_FRAME_TYPE = 'main_frame'; 10 | 11 | /** 12 | * Possible errors that can occur due to DNS blocking. 13 | */ 14 | const POSSIBLE_ERRORS = new Set([ 15 | 'net::ERR_CONNECTION_REFUSED', 16 | 'net::ERR_NAME_NOT_RESOLVED', 17 | 'net::ERR_CONNECTION_RESET', 18 | 'net::ERR_ADDRESS_INVALID', 19 | ]); 20 | 21 | /** 22 | * Path to the blocked page. 23 | */ 24 | const BLOCKED_PAGE_PATH = 'pages/blocked.html'; 25 | 26 | /** 27 | * Returns the hostname from the given URL. 28 | * 29 | * @param {string} url URL to get the hostname from. 30 | * 31 | * @returns {string|null} Parsed hostname or null if the hostname cannot be parsed. 32 | */ 33 | const getHostname = (url) => { 34 | let hostname = null; 35 | 36 | try { 37 | hostname = new URL(url).hostname; 38 | } catch (e) { 39 | console.error(`Error while getting hostname: ${e}`); 40 | } 41 | 42 | return hostname; 43 | }; 44 | 45 | /** 46 | * Creates a URL to check if the given hostname is blocked by AdGuard DNS. 47 | * 48 | * @param {string} hostname Hostname to check. 49 | * 50 | * @returns {string} URL for a request to check the hostname. 51 | */ 52 | const createCheckingUrl = (hostname) => { 53 | return `https://dns.adguard.ch/resolve?name=${hostname}&sde=1`; 54 | }; 55 | 56 | /** 57 | * Fetches the data to check if the given hostname is blocked by AdGuard DNS. 58 | * 59 | * @param {string} hostname Hostname to check. 60 | * 61 | * @returns {Object|null} Valid data object or null if data cannot be fetched or parsed. 62 | */ 63 | const fetchCheckData = async (hostname) => { 64 | const checkingUrl = createCheckingUrl(hostname); 65 | 66 | let data = null; 67 | 68 | try { 69 | const response = await fetch(checkingUrl); 70 | data = await response.json(); 71 | } catch (e) { 72 | console.error(`Error while fetching or parsing data: ${e}`); 73 | } 74 | 75 | return data; 76 | }; 77 | 78 | /** 79 | * @typedef {Object} ParsedExtraData 80 | * @property {string} whoBlocked Who blocked the request. 81 | * @property {string} reason Reason why the request was blocked. 82 | * @property {string} contactLink Link to contact the blocking party. 83 | */ 84 | 85 | /** 86 | * Parses the `Extra` value from the checking response. 87 | * 88 | * @param {any} extraValue Value of the `Extra` field. 89 | * 90 | * @returns {ParsedExtraData|null} Parsed data or null if the data is invalid. 91 | */ 92 | const parseExtraValue = (extraValue) => { 93 | if (extraValue.length === 0) { 94 | return null; 95 | } 96 | 97 | const { data } = extraValue[0]; 98 | 99 | // data is a string which should be parsed: 100 | // eslint-disable-next-line max-len 101 | // "\n;; OPT PSEUDOSECTION:\n; EDNS: version 0; flags:; udp: 65535\n; EDE: 17 (Filtered): ({"j":"Filtered by AdGuard DNS","o":"AdGuard DNS","c":["mailto:support@adguard-dns.io"]}) 102 | 103 | const rawFilteredDataStr = data.split('\n').pop(); 104 | 105 | const filteredDataStr = rawFilteredDataStr 106 | .replace(/; EDE: 17 \(Filtered\): \(/, '') 107 | .replace(/\)$/, ''); 108 | 109 | try { 110 | const rawData = JSON.parse(filteredDataStr); 111 | return { 112 | whoBlocked: rawData?.o, 113 | reason: rawData?.j, 114 | contactLink: rawData?.c[0], 115 | } 116 | } catch (e) { 117 | console.error('[parseExtraPart] Error: ', e); 118 | } 119 | 120 | return null; 121 | }; 122 | 123 | /** 124 | * Checks whether the parsed extra data is about AdGuard DNS blocking. 125 | * 126 | * @param {ParsedExtraData} parsedExtraData Parsed extra data. 127 | * 128 | * @returns {boolean} True if the data is about AdGuard DNS blocking, false otherwise. 129 | */ 130 | const isAdGuardDnsBlocked = (parsedExtraData) => { 131 | const { whoBlocked, reason, contactLink } = parsedExtraData; 132 | 133 | if (!whoBlocked || !reason || !contactLink) { 134 | console.error('Missing required fields in Extra value'); 135 | return false; 136 | } 137 | 138 | return true; 139 | }; 140 | 141 | /** 142 | * Updated the blocked page with the parsed extra data. 143 | * 144 | * @param {number} tabId Tab ID to update. 145 | * @param {string} hostname Hostname of the blocked request. 146 | * @param {ParsedExtraData} parsedExtraData Parsed extra data. 147 | */ 148 | const updateBlockedPage = async (tabId, hostname, parsedExtraData) => { 149 | const { whoBlocked, reason, contactLink } = parsedExtraData; 150 | 151 | try { 152 | // pass the data to the blocked page via query params 153 | const paramsStr = `?whoBlocked=${whoBlocked}&hostname=${hostname}&reason=${reason}&contactLink=${contactLink}`; 154 | 155 | await chrome.tabs.update(tabId, { 156 | url: `${chrome.runtime.getURL(BLOCKED_PAGE_PATH)}${paramsStr}`, 157 | }); 158 | } catch (e) { 159 | console.error(`Error while updating blocked page: ${e}`); 160 | } 161 | }; 162 | 163 | /** 164 | * `webRequest.onErrorOccurred` is preferred over `webNavigation.onErrorOccurred` because it fires earlier. 165 | */ 166 | chrome.webRequest.onErrorOccurred.addListener( 167 | async (details) => { 168 | if (details.type === MAIN_FRAME_TYPE && POSSIBLE_ERRORS.has(details.error)) { 169 | const hostname = getHostname(details.url); 170 | if (!hostname) { 171 | console.error(`Cannot get hostname from the URL: ${details.url}`); 172 | return; 173 | } 174 | 175 | const checkingResponse = await fetchCheckData(hostname); 176 | 177 | if (!checkingResponse) { 178 | console.error('Cannot fetch data to check if the request is blocked by AdGuard DNS'); 179 | return; 180 | } 181 | 182 | const { Extra } = checkingResponse; 183 | if (!Extra) { 184 | console.info('Request is not blocked by AdGuard DNS'); 185 | return; 186 | } 187 | 188 | const parsedExtraData = parseExtraValue(Extra); 189 | if (!parsedExtraData) { 190 | console.error('Extra value is not valid'); 191 | return; 192 | } 193 | 194 | if (!isAdGuardDnsBlocked(parsedExtraData)) { 195 | console.info('Request is not blocked by AdGuard DNS'); 196 | return; 197 | } 198 | 199 | updateBlockedPage(details.tabId, hostname, parsedExtraData); 200 | } 201 | }, 202 | { 203 | urls: [ALL_URLS_PATTERN], 204 | types: [MAIN_FRAME_TYPE], 205 | } 206 | ); 207 | 208 | chrome.runtime.onInstalled.addListener((details) => { 209 | if (details.reason === 'install') { 210 | // open the options page after installation 211 | chrome.runtime.openOptionsPage(() => { 212 | if (chrome.runtime.lastError) { 213 | console.error(`Error while opening options page: ${chrome.runtime.lastError}`); 214 | } 215 | }); 216 | } 217 | }); 218 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@eslint-community/eslint-utils@^4.2.0": 6 | version "4.4.1" 7 | resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz#d1145bf2c20132d6400495d6df4bf59362fd9d56" 8 | integrity sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA== 9 | dependencies: 10 | eslint-visitor-keys "^3.4.3" 11 | 12 | "@eslint-community/regexpp@^4.11.0": 13 | version "4.12.1" 14 | resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0" 15 | integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== 16 | 17 | "@eslint/config-array@^0.18.0": 18 | version "0.18.0" 19 | resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.18.0.tgz#37d8fe656e0d5e3dbaea7758ea56540867fd074d" 20 | integrity sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw== 21 | dependencies: 22 | "@eslint/object-schema" "^2.1.4" 23 | debug "^4.3.1" 24 | minimatch "^3.1.2" 25 | 26 | "@eslint/core@^0.7.0": 27 | version "0.7.0" 28 | resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.7.0.tgz#a1bb4b6a4e742a5ff1894b7ee76fbf884ec72bd3" 29 | integrity sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw== 30 | 31 | "@eslint/eslintrc@^3.1.0": 32 | version "3.1.0" 33 | resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.1.0.tgz#dbd3482bfd91efa663cbe7aa1f506839868207b6" 34 | integrity sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ== 35 | dependencies: 36 | ajv "^6.12.4" 37 | debug "^4.3.2" 38 | espree "^10.0.1" 39 | globals "^14.0.0" 40 | ignore "^5.2.0" 41 | import-fresh "^3.2.1" 42 | js-yaml "^4.1.0" 43 | minimatch "^3.1.2" 44 | strip-json-comments "^3.1.1" 45 | 46 | "@eslint/js@9.13.0", "@eslint/js@^9.13.0": 47 | version "9.13.0" 48 | resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.13.0.tgz#c5f89bcd57eb54d5d4fa8b77693e9c28dc97e547" 49 | integrity sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA== 50 | 51 | "@eslint/object-schema@^2.1.4": 52 | version "2.1.4" 53 | resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.4.tgz#9e69f8bb4031e11df79e03db09f9dbbae1740843" 54 | integrity sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ== 55 | 56 | "@eslint/plugin-kit@^0.2.0": 57 | version "0.2.2" 58 | resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.2.tgz#5eff371953bc13e3f4d88150e2c53959f64f74f6" 59 | integrity sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw== 60 | dependencies: 61 | levn "^0.4.1" 62 | 63 | "@humanfs/core@^0.19.1": 64 | version "0.19.1" 65 | resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.1.tgz#17c55ca7d426733fe3c561906b8173c336b40a77" 66 | integrity sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA== 67 | 68 | "@humanfs/node@^0.16.5": 69 | version "0.16.6" 70 | resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.6.tgz#ee2a10eaabd1131987bf0488fd9b820174cd765e" 71 | integrity sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw== 72 | dependencies: 73 | "@humanfs/core" "^0.19.1" 74 | "@humanwhocodes/retry" "^0.3.0" 75 | 76 | "@humanwhocodes/module-importer@^1.0.1": 77 | version "1.0.1" 78 | resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" 79 | integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== 80 | 81 | "@humanwhocodes/retry@^0.3.0", "@humanwhocodes/retry@^0.3.1": 82 | version "0.3.1" 83 | resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.1.tgz#c72a5c76a9fbaf3488e231b13dc52c0da7bab42a" 84 | integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA== 85 | 86 | "@stylistic/eslint-plugin-js@^2.10.0": 87 | version "2.10.0" 88 | resolved "https://registry.yarnpkg.com/@stylistic/eslint-plugin-js/-/eslint-plugin-js-2.10.0.tgz#f78dd926bf6bd9d9ffcd12a7cd0f894eb8f18cd2" 89 | integrity sha512-H742K6j8EeWgStJphdwWBZRy9LXWUZ/EjFgqUy7PfuXNnldr6QbfZT3zug5QUkWyA9Qh7skmMF8aT7TsnNwJ6w== 90 | dependencies: 91 | eslint-visitor-keys "^4.2.0" 92 | espree "^10.3.0" 93 | 94 | "@types/estree@^1.0.6": 95 | version "1.0.6" 96 | resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" 97 | integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== 98 | 99 | "@types/json-schema@^7.0.15": 100 | version "7.0.15" 101 | resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" 102 | integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== 103 | 104 | acorn-jsx@^5.3.2: 105 | version "5.3.2" 106 | resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" 107 | integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== 108 | 109 | acorn@^8.14.0: 110 | version "8.14.0" 111 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0" 112 | integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== 113 | 114 | ajv@^6.12.4: 115 | version "6.12.6" 116 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" 117 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== 118 | dependencies: 119 | fast-deep-equal "^3.1.1" 120 | fast-json-stable-stringify "^2.0.0" 121 | json-schema-traverse "^0.4.1" 122 | uri-js "^4.2.2" 123 | 124 | ansi-styles@^4.1.0: 125 | version "4.3.0" 126 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 127 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 128 | dependencies: 129 | color-convert "^2.0.1" 130 | 131 | argparse@^2.0.1: 132 | version "2.0.1" 133 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" 134 | integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== 135 | 136 | balanced-match@^1.0.0: 137 | version "1.0.2" 138 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 139 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 140 | 141 | brace-expansion@^1.1.7: 142 | version "1.1.11" 143 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 144 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 145 | dependencies: 146 | balanced-match "^1.0.0" 147 | concat-map "0.0.1" 148 | 149 | callsites@^3.0.0: 150 | version "3.1.0" 151 | resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" 152 | integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== 153 | 154 | chalk@^4.0.0: 155 | version "4.1.2" 156 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" 157 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 158 | dependencies: 159 | ansi-styles "^4.1.0" 160 | supports-color "^7.1.0" 161 | 162 | color-convert@^2.0.1: 163 | version "2.0.1" 164 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 165 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 166 | dependencies: 167 | color-name "~1.1.4" 168 | 169 | color-name@~1.1.4: 170 | version "1.1.4" 171 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 172 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 173 | 174 | concat-map@0.0.1: 175 | version "0.0.1" 176 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 177 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== 178 | 179 | cross-spawn@^7.0.2: 180 | version "7.0.3" 181 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" 182 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 183 | dependencies: 184 | path-key "^3.1.0" 185 | shebang-command "^2.0.0" 186 | which "^2.0.1" 187 | 188 | debug@^4.3.1, debug@^4.3.2: 189 | version "4.3.7" 190 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" 191 | integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== 192 | dependencies: 193 | ms "^2.1.3" 194 | 195 | deep-is@^0.1.3: 196 | version "0.1.4" 197 | resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" 198 | integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== 199 | 200 | escape-string-regexp@^4.0.0: 201 | version "4.0.0" 202 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" 203 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 204 | 205 | eslint-scope@^8.1.0: 206 | version "8.2.0" 207 | resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.2.0.tgz#377aa6f1cb5dc7592cfd0b7f892fd0cf352ce442" 208 | integrity sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A== 209 | dependencies: 210 | esrecurse "^4.3.0" 211 | estraverse "^5.2.0" 212 | 213 | eslint-visitor-keys@^3.4.3: 214 | version "3.4.3" 215 | resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" 216 | integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== 217 | 218 | eslint-visitor-keys@^4.1.0, eslint-visitor-keys@^4.2.0: 219 | version "4.2.0" 220 | resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45" 221 | integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== 222 | 223 | eslint@^9.13.0: 224 | version "9.13.0" 225 | resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.13.0.tgz#7659014b7dda1ff876ecbd990f726e11c61596e6" 226 | integrity sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA== 227 | dependencies: 228 | "@eslint-community/eslint-utils" "^4.2.0" 229 | "@eslint-community/regexpp" "^4.11.0" 230 | "@eslint/config-array" "^0.18.0" 231 | "@eslint/core" "^0.7.0" 232 | "@eslint/eslintrc" "^3.1.0" 233 | "@eslint/js" "9.13.0" 234 | "@eslint/plugin-kit" "^0.2.0" 235 | "@humanfs/node" "^0.16.5" 236 | "@humanwhocodes/module-importer" "^1.0.1" 237 | "@humanwhocodes/retry" "^0.3.1" 238 | "@types/estree" "^1.0.6" 239 | "@types/json-schema" "^7.0.15" 240 | ajv "^6.12.4" 241 | chalk "^4.0.0" 242 | cross-spawn "^7.0.2" 243 | debug "^4.3.2" 244 | escape-string-regexp "^4.0.0" 245 | eslint-scope "^8.1.0" 246 | eslint-visitor-keys "^4.1.0" 247 | espree "^10.2.0" 248 | esquery "^1.5.0" 249 | esutils "^2.0.2" 250 | fast-deep-equal "^3.1.3" 251 | file-entry-cache "^8.0.0" 252 | find-up "^5.0.0" 253 | glob-parent "^6.0.2" 254 | ignore "^5.2.0" 255 | imurmurhash "^0.1.4" 256 | is-glob "^4.0.0" 257 | json-stable-stringify-without-jsonify "^1.0.1" 258 | lodash.merge "^4.6.2" 259 | minimatch "^3.1.2" 260 | natural-compare "^1.4.0" 261 | optionator "^0.9.3" 262 | text-table "^0.2.0" 263 | 264 | espree@^10.0.1, espree@^10.2.0, espree@^10.3.0: 265 | version "10.3.0" 266 | resolved "https://registry.yarnpkg.com/espree/-/espree-10.3.0.tgz#29267cf5b0cb98735b65e64ba07e0ed49d1eed8a" 267 | integrity sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg== 268 | dependencies: 269 | acorn "^8.14.0" 270 | acorn-jsx "^5.3.2" 271 | eslint-visitor-keys "^4.2.0" 272 | 273 | esquery@^1.5.0: 274 | version "1.6.0" 275 | resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" 276 | integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== 277 | dependencies: 278 | estraverse "^5.1.0" 279 | 280 | esrecurse@^4.3.0: 281 | version "4.3.0" 282 | resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" 283 | integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== 284 | dependencies: 285 | estraverse "^5.2.0" 286 | 287 | estraverse@^5.1.0, estraverse@^5.2.0: 288 | version "5.3.0" 289 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" 290 | integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== 291 | 292 | esutils@^2.0.2: 293 | version "2.0.3" 294 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" 295 | integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== 296 | 297 | fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: 298 | version "3.1.3" 299 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" 300 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 301 | 302 | fast-json-stable-stringify@^2.0.0: 303 | version "2.1.0" 304 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" 305 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== 306 | 307 | fast-levenshtein@^2.0.6: 308 | version "2.0.6" 309 | resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" 310 | integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== 311 | 312 | file-entry-cache@^8.0.0: 313 | version "8.0.0" 314 | resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz#7787bddcf1131bffb92636c69457bbc0edd6d81f" 315 | integrity sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ== 316 | dependencies: 317 | flat-cache "^4.0.0" 318 | 319 | find-up@^5.0.0: 320 | version "5.0.0" 321 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" 322 | integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== 323 | dependencies: 324 | locate-path "^6.0.0" 325 | path-exists "^4.0.0" 326 | 327 | flat-cache@^4.0.0: 328 | version "4.0.1" 329 | resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-4.0.1.tgz#0ece39fcb14ee012f4b0410bd33dd9c1f011127c" 330 | integrity sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw== 331 | dependencies: 332 | flatted "^3.2.9" 333 | keyv "^4.5.4" 334 | 335 | flatted@^3.2.9: 336 | version "3.3.1" 337 | resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" 338 | integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== 339 | 340 | glob-parent@^6.0.2: 341 | version "6.0.2" 342 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" 343 | integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== 344 | dependencies: 345 | is-glob "^4.0.3" 346 | 347 | globals@^14.0.0: 348 | version "14.0.0" 349 | resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e" 350 | integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ== 351 | 352 | globals@^15.11.0: 353 | version "15.11.0" 354 | resolved "https://registry.yarnpkg.com/globals/-/globals-15.11.0.tgz#b96ed4c6998540c6fb824b24b5499216d2438d6e" 355 | integrity sha512-yeyNSjdbyVaWurlwCpcA6XNBrHTMIeDdj0/hnvX/OLJ9ekOXYbLsLinH/MucQyGvNnXhidTdNhTtJaffL2sMfw== 356 | 357 | has-flag@^4.0.0: 358 | version "4.0.0" 359 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 360 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 361 | 362 | ignore@^5.2.0: 363 | version "5.3.2" 364 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" 365 | integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== 366 | 367 | import-fresh@^3.2.1: 368 | version "3.3.0" 369 | resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" 370 | integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== 371 | dependencies: 372 | parent-module "^1.0.0" 373 | resolve-from "^4.0.0" 374 | 375 | imurmurhash@^0.1.4: 376 | version "0.1.4" 377 | resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" 378 | integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== 379 | 380 | is-extglob@^2.1.1: 381 | version "2.1.1" 382 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 383 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== 384 | 385 | is-glob@^4.0.0, is-glob@^4.0.3: 386 | version "4.0.3" 387 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 388 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 389 | dependencies: 390 | is-extglob "^2.1.1" 391 | 392 | isexe@^2.0.0: 393 | version "2.0.0" 394 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 395 | integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== 396 | 397 | js-yaml@^4.1.0: 398 | version "4.1.0" 399 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" 400 | integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== 401 | dependencies: 402 | argparse "^2.0.1" 403 | 404 | json-buffer@3.0.1: 405 | version "3.0.1" 406 | resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" 407 | integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== 408 | 409 | json-schema-traverse@^0.4.1: 410 | version "0.4.1" 411 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" 412 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== 413 | 414 | json-stable-stringify-without-jsonify@^1.0.1: 415 | version "1.0.1" 416 | resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" 417 | integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== 418 | 419 | keyv@^4.5.4: 420 | version "4.5.4" 421 | resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" 422 | integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== 423 | dependencies: 424 | json-buffer "3.0.1" 425 | 426 | levn@^0.4.1: 427 | version "0.4.1" 428 | resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" 429 | integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== 430 | dependencies: 431 | prelude-ls "^1.2.1" 432 | type-check "~0.4.0" 433 | 434 | locate-path@^6.0.0: 435 | version "6.0.0" 436 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" 437 | integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== 438 | dependencies: 439 | p-locate "^5.0.0" 440 | 441 | lodash.merge@^4.6.2: 442 | version "4.6.2" 443 | resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" 444 | integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== 445 | 446 | minimatch@^3.1.2: 447 | version "3.1.2" 448 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" 449 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 450 | dependencies: 451 | brace-expansion "^1.1.7" 452 | 453 | ms@^2.1.3: 454 | version "2.1.3" 455 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" 456 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 457 | 458 | natural-compare@^1.4.0: 459 | version "1.4.0" 460 | resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" 461 | integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== 462 | 463 | optionator@^0.9.3: 464 | version "0.9.4" 465 | resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734" 466 | integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== 467 | dependencies: 468 | deep-is "^0.1.3" 469 | fast-levenshtein "^2.0.6" 470 | levn "^0.4.1" 471 | prelude-ls "^1.2.1" 472 | type-check "^0.4.0" 473 | word-wrap "^1.2.5" 474 | 475 | p-limit@^3.0.2: 476 | version "3.1.0" 477 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" 478 | integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== 479 | dependencies: 480 | yocto-queue "^0.1.0" 481 | 482 | p-locate@^5.0.0: 483 | version "5.0.0" 484 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" 485 | integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== 486 | dependencies: 487 | p-limit "^3.0.2" 488 | 489 | parent-module@^1.0.0: 490 | version "1.0.1" 491 | resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" 492 | integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== 493 | dependencies: 494 | callsites "^3.0.0" 495 | 496 | path-exists@^4.0.0: 497 | version "4.0.0" 498 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" 499 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== 500 | 501 | path-key@^3.1.0: 502 | version "3.1.1" 503 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 504 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 505 | 506 | prelude-ls@^1.2.1: 507 | version "1.2.1" 508 | resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" 509 | integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== 510 | 511 | punycode@^2.1.0: 512 | version "2.3.1" 513 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" 514 | integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== 515 | 516 | resolve-from@^4.0.0: 517 | version "4.0.0" 518 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" 519 | integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== 520 | 521 | shebang-command@^2.0.0: 522 | version "2.0.0" 523 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 524 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 525 | dependencies: 526 | shebang-regex "^3.0.0" 527 | 528 | shebang-regex@^3.0.0: 529 | version "3.0.0" 530 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 531 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 532 | 533 | strip-json-comments@^3.1.1: 534 | version "3.1.1" 535 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" 536 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== 537 | 538 | supports-color@^7.1.0: 539 | version "7.2.0" 540 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" 541 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 542 | dependencies: 543 | has-flag "^4.0.0" 544 | 545 | text-table@^0.2.0: 546 | version "0.2.0" 547 | resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" 548 | integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== 549 | 550 | type-check@^0.4.0, type-check@~0.4.0: 551 | version "0.4.0" 552 | resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" 553 | integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== 554 | dependencies: 555 | prelude-ls "^1.2.1" 556 | 557 | uri-js@^4.2.2: 558 | version "4.4.1" 559 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" 560 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== 561 | dependencies: 562 | punycode "^2.1.0" 563 | 564 | which@^2.0.1: 565 | version "2.0.2" 566 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 567 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 568 | dependencies: 569 | isexe "^2.0.0" 570 | 571 | word-wrap@^1.2.5: 572 | version "1.2.5" 573 | resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" 574 | integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== 575 | 576 | yocto-queue@^0.1.0: 577 | version "0.1.0" 578 | resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" 579 | integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== 580 | -------------------------------------------------------------------------------- /src/pages/blocked.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Access denied 6 | 21 | 22 | 23 | 24 | 25 | 26 |
27 |
28 |
29 |
30 |
31 |

32 | Access blocked by ${whoBlocked} 33 |

34 |
35 | AdGuard DNS blocked access to ${hostname} due to the following reason: ${reason}. 36 |
37 |
38 | 50 |
51 |
52 |
    53 |
  • 54 |
    55 |

    56 | 59 | 60 | 61 | 62 |

    63 |
    64 |
    65 |
    66 | Access to this website was blocked by the DNS server you are using. Different DNS servers may have different policies on what should be blocked. 67 |
    68 |
    69 |
    70 |
    71 |
  • 72 |
  • 73 |
    74 |

    75 | 78 | 79 | 80 | 81 |

    82 |
    83 |
    84 |
    85 | If you believe this website has been blocked in error, please 86 | let us know 87 |
    88 |
    89 |
    90 |
    91 |
  • 92 |
93 |
94 |
95 |
96 |
97 |
98 | 99 |
100 |
101 |
102 |
103 |
104 | 105 | 106 | 107 | --------------------------------------------------------------------------------