@browserless.io/browserless 2.0.0-beta-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (875) hide show
  1. package/CHANGELOG.md +674 -0
  2. package/LICENSE +6 -0
  3. package/README.md +132 -0
  4. package/assets/logo.png +0 -0
  5. package/bin/browserless.js +227 -0
  6. package/browser.json +7 -0
  7. package/build/browserless.d.ts +33 -0
  8. package/build/browserless.js +146 -0
  9. package/build/browsers/cdp-chromium.d.ts +41 -0
  10. package/build/browsers/cdp-chromium.js +287 -0
  11. package/build/browsers/index.d.ts +26 -0
  12. package/build/browsers/index.js +183 -0
  13. package/build/browsers/playwright-chromium.d.ts +34 -0
  14. package/build/browsers/playwright-chromium.js +106 -0
  15. package/build/browsers/playwright-firefox.d.ts +34 -0
  16. package/build/browsers/playwright-firefox.js +101 -0
  17. package/build/browsers/playwright-webkit.d.ts +34 -0
  18. package/build/browsers/playwright-webkit.js +101 -0
  19. package/build/config.d.ts +138 -0
  20. package/build/config.js +349 -0
  21. package/build/constants.d.ts +4 -0
  22. package/build/constants.js +4 -0
  23. package/build/data/classes.json +1 -0
  24. package/build/data/selectors.json +1 -0
  25. package/build/exports.d.ts +20 -0
  26. package/build/exports.js +22 -0
  27. package/build/file-system.d.ts +24 -0
  28. package/build/file-system.js +46 -0
  29. package/build/hooks.d.ts +5 -0
  30. package/build/hooks.js +20 -0
  31. package/build/http.d.ts +175 -0
  32. package/build/http.js +104 -0
  33. package/build/index.d.ts +1 -0
  34. package/build/index.js +39 -0
  35. package/build/limiter.d.ts +24 -0
  36. package/build/limiter.js +147 -0
  37. package/build/limiter.spec.d.ts +1 -0
  38. package/build/limiter.spec.js +241 -0
  39. package/build/metrics.d.ts +24 -0
  40. package/build/metrics.js +86 -0
  41. package/build/metrics.spec.d.ts +1 -0
  42. package/build/metrics.spec.js +35 -0
  43. package/build/mime-types.d.ts +1 -0
  44. package/build/mime-types.js +328 -0
  45. package/build/monitoring.d.ts +13 -0
  46. package/build/monitoring.js +38 -0
  47. package/build/routes/chromium/http/content-post.body.json +514 -0
  48. package/build/routes/chromium/http/content-post.d.ts +34 -0
  49. package/build/routes/chromium/http/content-post.js +109 -0
  50. package/build/routes/chromium/http/content-post.query.json +183 -0
  51. package/build/routes/chromium/http/content-post.response.json +5 -0
  52. package/build/routes/chromium/http/download-post.body.json +32 -0
  53. package/build/routes/chromium/http/download-post.d.ts +16 -0
  54. package/build/routes/chromium/http/download-post.js +92 -0
  55. package/build/routes/chromium/http/download-post.query.json +120 -0
  56. package/build/routes/chromium/http/download-post.response.json +4 -0
  57. package/build/routes/chromium/http/function-post.body.json +32 -0
  58. package/build/routes/chromium/http/function-post.d.ts +18 -0
  59. package/build/routes/chromium/http/function-post.js +53 -0
  60. package/build/routes/chromium/http/function-post.query.json +120 -0
  61. package/build/routes/chromium/http/function-post.response.json +4 -0
  62. package/build/routes/chromium/http/pdf-post.body.json +654 -0
  63. package/build/routes/chromium/http/pdf-post.d.ts +35 -0
  64. package/build/routes/chromium/http/pdf-post.js +107 -0
  65. package/build/routes/chromium/http/pdf-post.query.json +120 -0
  66. package/build/routes/chromium/http/pdf-post.response.json +5 -0
  67. package/build/routes/chromium/http/performance.body.json +26 -0
  68. package/build/routes/chromium/http/performance.d.ts +17 -0
  69. package/build/routes/chromium/http/performance.js +30 -0
  70. package/build/routes/chromium/http/performance.query.json +120 -0
  71. package/build/routes/chromium/http/performance.response.json +7 -0
  72. package/build/routes/chromium/http/scrape-post.body.json +561 -0
  73. package/build/routes/chromium/http/scrape-post.d.ts +106 -0
  74. package/build/routes/chromium/http/scrape-post.js +205 -0
  75. package/build/routes/chromium/http/scrape-post.query.json +183 -0
  76. package/build/routes/chromium/http/scrape-post.response.json +325 -0
  77. package/build/routes/chromium/http/screenshot-post.body.json +604 -0
  78. package/build/routes/chromium/http/screenshot-post.d.ts +37 -0
  79. package/build/routes/chromium/http/screenshot-post.js +124 -0
  80. package/build/routes/chromium/http/screenshot-post.query.json +120 -0
  81. package/build/routes/chromium/http/screenshot-post.response.json +5 -0
  82. package/build/routes/chromium/tests/content.spec.d.ts +1 -0
  83. package/build/routes/chromium/tests/content.spec.js +285 -0
  84. package/build/routes/chromium/tests/download.spec.d.ts +1 -0
  85. package/build/routes/chromium/tests/download.spec.js +67 -0
  86. package/build/routes/chromium/tests/function.spec.d.ts +1 -0
  87. package/build/routes/chromium/tests/function.spec.js +245 -0
  88. package/build/routes/chromium/tests/pdf.spec.d.ts +1 -0
  89. package/build/routes/chromium/tests/pdf.spec.js +333 -0
  90. package/build/routes/chromium/tests/performance.spec.d.ts +1 -0
  91. package/build/routes/chromium/tests/performance.spec.js +124 -0
  92. package/build/routes/chromium/tests/scrape.spec.d.ts +1 -0
  93. package/build/routes/chromium/tests/scrape.spec.js +354 -0
  94. package/build/routes/chromium/tests/screenshot.spec.d.ts +1 -0
  95. package/build/routes/chromium/tests/screenshot.spec.js +339 -0
  96. package/build/routes/chromium/tests/websocket.spec.d.ts +1 -0
  97. package/build/routes/chromium/tests/websocket.spec.js +309 -0
  98. package/build/routes/chromium/utils/function/client.d.ts +26 -0
  99. package/build/routes/chromium/utils/function/client.js +66 -0
  100. package/build/routes/chromium/utils/function/handler.d.ts +18 -0
  101. package/build/routes/chromium/utils/function/handler.js +95 -0
  102. package/build/routes/chromium/utils/performance/child.d.ts +1 -0
  103. package/build/routes/chromium/utils/performance/child.js +29 -0
  104. package/build/routes/chromium/utils/performance/main.d.ts +3 -0
  105. package/build/routes/chromium/utils/performance/main.js +65 -0
  106. package/build/routes/chromium/utils/performance/types.d.ts +21 -0
  107. package/build/routes/chromium/utils/performance/types.js +1 -0
  108. package/build/routes/chromium/ws/browser.d.ts +6 -0
  109. package/build/routes/chromium/ws/browser.js +11 -0
  110. package/build/routes/chromium/ws/browser.query.json +120 -0
  111. package/build/routes/chromium/ws/cdp-chromium.d.ts +6 -0
  112. package/build/routes/chromium/ws/cdp-chromium.js +11 -0
  113. package/build/routes/chromium/ws/cdp-chromium.query.json +120 -0
  114. package/build/routes/chromium/ws/page.d.ts +6 -0
  115. package/build/routes/chromium/ws/page.js +11 -0
  116. package/build/routes/chromium/ws/page.query.json +120 -0
  117. package/build/routes/chromium/ws/playwright-chromium.d.ts +6 -0
  118. package/build/routes/chromium/ws/playwright-chromium.js +19 -0
  119. package/build/routes/chromium/ws/playwright-chromium.query.json +100 -0
  120. package/build/routes/firefox/tests/websocket.spec.d.ts +1 -0
  121. package/build/routes/firefox/tests/websocket.spec.js +104 -0
  122. package/build/routes/firefox/ws/playwright-firefox.d.ts +6 -0
  123. package/build/routes/firefox/ws/playwright-firefox.js +19 -0
  124. package/build/routes/firefox/ws/playwright-firefox.query.json +100 -0
  125. package/build/routes/management/http/config-get.d.ts +25 -0
  126. package/build/routes/management/http/config-get.js +43 -0
  127. package/build/routes/management/http/config-get.response.json +107 -0
  128. package/build/routes/management/http/metrics-get.d.ts +4 -0
  129. package/build/routes/management/http/metrics-get.js +24 -0
  130. package/build/routes/management/http/metrics-get.response.json +94 -0
  131. package/build/routes/management/http/metrics-total-get.d.ts +4 -0
  132. package/build/routes/management/http/metrics-total-get.js +60 -0
  133. package/build/routes/management/http/metrics-total-get.response.json +72 -0
  134. package/build/routes/management/http/sessions-get.d.ts +4 -0
  135. package/build/routes/management/http/sessions-get.js +21 -0
  136. package/build/routes/management/http/sessions-get.response.json +221 -0
  137. package/build/routes/management/http/static-get.d.ts +3 -0
  138. package/build/routes/management/http/static-get.js +67 -0
  139. package/build/routes/management/tests/management.spec.d.ts +1 -0
  140. package/build/routes/management/tests/management.spec.js +41 -0
  141. package/build/routes/webkit/tests/websocket.spec.d.ts +1 -0
  142. package/build/routes/webkit/tests/websocket.spec.js +104 -0
  143. package/build/routes/webkit/ws/playwright-webkit.d.ts +6 -0
  144. package/build/routes/webkit/ws/playwright-webkit.js +19 -0
  145. package/build/routes/webkit/ws/playwright-webkit.query.json +100 -0
  146. package/build/server.d.ts +38 -0
  147. package/build/server.js +365 -0
  148. package/build/shim.d.ts +9 -0
  149. package/build/shim.js +54 -0
  150. package/build/shim.spec.d.ts +1 -0
  151. package/build/shim.spec.js +114 -0
  152. package/build/types.d.ts +360 -0
  153. package/build/types.js +6 -0
  154. package/build/utils.d.ts +111 -0
  155. package/build/utils.js +570 -0
  156. package/build/webhooks.d.ts +11 -0
  157. package/build/webhooks.js +43 -0
  158. package/docker/base/.dockerignore +16 -0
  159. package/docker/base/Dockerfile +70 -0
  160. package/docker/chrome/.dockerignore +16 -0
  161. package/docker/chrome/Dockerfile +40 -0
  162. package/docker/firefox/.dockerignore +16 -0
  163. package/docker/firefox/Dockerfile +39 -0
  164. package/docker/multi/.dockerignore +16 -0
  165. package/docker/multi/Dockerfile +37 -0
  166. package/docker/sdk/.dockerignore +16 -0
  167. package/docker/sdk/Dockerfile +34 -0
  168. package/docker/webkit/.dockerignore +16 -0
  169. package/docker/webkit/Dockerfile +40 -0
  170. package/extensions/screencast/background.js +143 -0
  171. package/extensions/screencast/content_script.js +18 -0
  172. package/extensions/screencast/manifest.json +19 -0
  173. package/extensions/ublock/1p-filters.html +69 -0
  174. package/extensions/ublock/3p-filters.html +119 -0
  175. package/extensions/ublock/LICENSE.txt +674 -0
  176. package/extensions/ublock/_locales/ar/messages.json +1290 -0
  177. package/extensions/ublock/_locales/az/messages.json +1290 -0
  178. package/extensions/ublock/_locales/be/messages.json +1290 -0
  179. package/extensions/ublock/_locales/bg/messages.json +1290 -0
  180. package/extensions/ublock/_locales/bn/messages.json +1290 -0
  181. package/extensions/ublock/_locales/br_FR/messages.json +1290 -0
  182. package/extensions/ublock/_locales/bs/messages.json +1290 -0
  183. package/extensions/ublock/_locales/ca/messages.json +1290 -0
  184. package/extensions/ublock/_locales/cs/messages.json +1290 -0
  185. package/extensions/ublock/_locales/cv/messages.json +1290 -0
  186. package/extensions/ublock/_locales/da/messages.json +1290 -0
  187. package/extensions/ublock/_locales/de/messages.json +1290 -0
  188. package/extensions/ublock/_locales/el/messages.json +1290 -0
  189. package/extensions/ublock/_locales/en/messages.json +1292 -0
  190. package/extensions/ublock/_locales/en_GB/messages.json +1290 -0
  191. package/extensions/ublock/_locales/eo/messages.json +1290 -0
  192. package/extensions/ublock/_locales/es/messages.json +1290 -0
  193. package/extensions/ublock/_locales/et/messages.json +1290 -0
  194. package/extensions/ublock/_locales/eu/messages.json +1290 -0
  195. package/extensions/ublock/_locales/fa/messages.json +1290 -0
  196. package/extensions/ublock/_locales/fi/messages.json +1290 -0
  197. package/extensions/ublock/_locales/fil/messages.json +1290 -0
  198. package/extensions/ublock/_locales/fr/messages.json +1290 -0
  199. package/extensions/ublock/_locales/fy/messages.json +1290 -0
  200. package/extensions/ublock/_locales/gl/messages.json +1290 -0
  201. package/extensions/ublock/_locales/gu/messages.json +1290 -0
  202. package/extensions/ublock/_locales/he/messages.json +1290 -0
  203. package/extensions/ublock/_locales/hi/messages.json +1290 -0
  204. package/extensions/ublock/_locales/hr/messages.json +1290 -0
  205. package/extensions/ublock/_locales/hu/messages.json +1290 -0
  206. package/extensions/ublock/_locales/hy/messages.json +1290 -0
  207. package/extensions/ublock/_locales/id/messages.json +1290 -0
  208. package/extensions/ublock/_locales/it/messages.json +1290 -0
  209. package/extensions/ublock/_locales/ja/messages.json +1290 -0
  210. package/extensions/ublock/_locales/ka/messages.json +1290 -0
  211. package/extensions/ublock/_locales/kk/messages.json +1290 -0
  212. package/extensions/ublock/_locales/kn/messages.json +1290 -0
  213. package/extensions/ublock/_locales/ko/messages.json +1290 -0
  214. package/extensions/ublock/_locales/ku/messages.json +1290 -0
  215. package/extensions/ublock/_locales/lt/messages.json +1290 -0
  216. package/extensions/ublock/_locales/lv/messages.json +1290 -0
  217. package/extensions/ublock/_locales/mk/messages.json +1290 -0
  218. package/extensions/ublock/_locales/ml/messages.json +1290 -0
  219. package/extensions/ublock/_locales/mr/messages.json +1290 -0
  220. package/extensions/ublock/_locales/ms/messages.json +1290 -0
  221. package/extensions/ublock/_locales/nb/messages.json +1290 -0
  222. package/extensions/ublock/_locales/nl/messages.json +1290 -0
  223. package/extensions/ublock/_locales/no/messages.json +1290 -0
  224. package/extensions/ublock/_locales/oc/messages.json +1290 -0
  225. package/extensions/ublock/_locales/pa/messages.json +1290 -0
  226. package/extensions/ublock/_locales/pl/messages.json +1290 -0
  227. package/extensions/ublock/_locales/pt_BR/messages.json +1290 -0
  228. package/extensions/ublock/_locales/pt_PT/messages.json +1290 -0
  229. package/extensions/ublock/_locales/ro/messages.json +1290 -0
  230. package/extensions/ublock/_locales/ru/messages.json +1290 -0
  231. package/extensions/ublock/_locales/si/messages.json +1290 -0
  232. package/extensions/ublock/_locales/sk/messages.json +1290 -0
  233. package/extensions/ublock/_locales/sl/messages.json +1290 -0
  234. package/extensions/ublock/_locales/so/messages.json +1290 -0
  235. package/extensions/ublock/_locales/sq/messages.json +1290 -0
  236. package/extensions/ublock/_locales/sr/messages.json +1290 -0
  237. package/extensions/ublock/_locales/sv/messages.json +1290 -0
  238. package/extensions/ublock/_locales/sw/messages.json +1290 -0
  239. package/extensions/ublock/_locales/ta/messages.json +1290 -0
  240. package/extensions/ublock/_locales/te/messages.json +1290 -0
  241. package/extensions/ublock/_locales/th/messages.json +1290 -0
  242. package/extensions/ublock/_locales/tr/messages.json +1290 -0
  243. package/extensions/ublock/_locales/uk/messages.json +1290 -0
  244. package/extensions/ublock/_locales/ur/messages.json +1290 -0
  245. package/extensions/ublock/_locales/vi/messages.json +1290 -0
  246. package/extensions/ublock/_locales/zh_CN/messages.json +1290 -0
  247. package/extensions/ublock/_locales/zh_TW/messages.json +1290 -0
  248. package/extensions/ublock/about.html +63 -0
  249. package/extensions/ublock/advanced-settings.html +42 -0
  250. package/extensions/ublock/asset-viewer.html +50 -0
  251. package/extensions/ublock/assets/assets.json +903 -0
  252. package/extensions/ublock/assets/resources/scriptlets.js +4255 -0
  253. package/extensions/ublock/assets/thirdparties/easylist/easylist.txt +65576 -0
  254. package/extensions/ublock/assets/thirdparties/easylist/easyprivacy.txt +33219 -0
  255. package/extensions/ublock/assets/thirdparties/pgl.yoyo.org/as/README.md +29 -0
  256. package/extensions/ublock/assets/thirdparties/pgl.yoyo.org/as/serverlist +3732 -0
  257. package/extensions/ublock/assets/thirdparties/publicsuffix.org/list/effective_tld_names.dat +15431 -0
  258. package/extensions/ublock/assets/thirdparties/urlhaus-filter/LICENSE.md +42 -0
  259. package/extensions/ublock/assets/thirdparties/urlhaus-filter/urlhaus-filter-online.txt +1970 -0
  260. package/extensions/ublock/assets/ublock/badlists.txt +77 -0
  261. package/extensions/ublock/assets/ublock/badware.min.txt +3033 -0
  262. package/extensions/ublock/assets/ublock/filters.min.txt +23419 -0
  263. package/extensions/ublock/assets/ublock/privacy.min.txt +575 -0
  264. package/extensions/ublock/assets/ublock/quick-fixes.min.txt +99 -0
  265. package/extensions/ublock/assets/ublock/unbreak.min.txt +2448 -0
  266. package/extensions/ublock/background.html +12 -0
  267. package/extensions/ublock/cloud-ui.html +23 -0
  268. package/extensions/ublock/code-viewer.html +53 -0
  269. package/extensions/ublock/css/1p-filters.css +26 -0
  270. package/extensions/ublock/css/3p-filters.css +250 -0
  271. package/extensions/ublock/css/about.css +3 -0
  272. package/extensions/ublock/css/advanced-settings.css +26 -0
  273. package/extensions/ublock/css/asset-viewer.css +79 -0
  274. package/extensions/ublock/css/click2load.css +53 -0
  275. package/extensions/ublock/css/cloud-ui.css +104 -0
  276. package/extensions/ublock/css/code-viewer.css +67 -0
  277. package/extensions/ublock/css/codemirror.css +326 -0
  278. package/extensions/ublock/css/common.css +347 -0
  279. package/extensions/ublock/css/dashboard-common.css +55 -0
  280. package/extensions/ublock/css/dashboard.css +115 -0
  281. package/extensions/ublock/css/devtools.css +22 -0
  282. package/extensions/ublock/css/document-blocked.css +146 -0
  283. package/extensions/ublock/css/dyna-rules.css +79 -0
  284. package/extensions/ublock/css/epicker-ui.css +270 -0
  285. package/extensions/ublock/css/fa-icons.css +149 -0
  286. package/extensions/ublock/css/fonts/Inter/Inter-Regular.woff2 +0 -0
  287. package/extensions/ublock/css/fonts/Inter/Inter-SemiBold.woff2 +0 -0
  288. package/extensions/ublock/css/fonts/Inter/LICENSE.txt +93 -0
  289. package/extensions/ublock/css/fonts/Metropolis/Metropolis-Regular.woff2 +0 -0
  290. package/extensions/ublock/css/fonts/Metropolis/Metropolis-SemiBold.woff2 +0 -0
  291. package/extensions/ublock/css/fonts/Metropolis/README.md +25 -0
  292. package/extensions/ublock/css/fonts/Metropolis/UNLICENSE +24 -0
  293. package/extensions/ublock/css/logger-ui-inspector.css +116 -0
  294. package/extensions/ublock/css/logger-ui.css +978 -0
  295. package/extensions/ublock/css/popup-fenix.css +778 -0
  296. package/extensions/ublock/css/settings.css +74 -0
  297. package/extensions/ublock/css/support.css +110 -0
  298. package/extensions/ublock/css/themes/default.css +526 -0
  299. package/extensions/ublock/css/whitelist.css +22 -0
  300. package/extensions/ublock/dashboard.html +47 -0
  301. package/extensions/ublock/devtools.html +58 -0
  302. package/extensions/ublock/document-blocked.html +64 -0
  303. package/extensions/ublock/dyna-rules.html +67 -0
  304. package/extensions/ublock/img/cloud.png +0 -0
  305. package/extensions/ublock/img/flags-of-the-world/README +9 -0
  306. package/extensions/ublock/img/flags-of-the-world/ad.png +0 -0
  307. package/extensions/ublock/img/flags-of-the-world/ae.png +0 -0
  308. package/extensions/ublock/img/flags-of-the-world/af.png +0 -0
  309. package/extensions/ublock/img/flags-of-the-world/ag.png +0 -0
  310. package/extensions/ublock/img/flags-of-the-world/ai.png +0 -0
  311. package/extensions/ublock/img/flags-of-the-world/al.png +0 -0
  312. package/extensions/ublock/img/flags-of-the-world/am.png +0 -0
  313. package/extensions/ublock/img/flags-of-the-world/ao.png +0 -0
  314. package/extensions/ublock/img/flags-of-the-world/aq.png +0 -0
  315. package/extensions/ublock/img/flags-of-the-world/ar.png +0 -0
  316. package/extensions/ublock/img/flags-of-the-world/as.png +0 -0
  317. package/extensions/ublock/img/flags-of-the-world/at.png +0 -0
  318. package/extensions/ublock/img/flags-of-the-world/au.png +0 -0
  319. package/extensions/ublock/img/flags-of-the-world/aw.png +0 -0
  320. package/extensions/ublock/img/flags-of-the-world/ax.png +0 -0
  321. package/extensions/ublock/img/flags-of-the-world/az.png +0 -0
  322. package/extensions/ublock/img/flags-of-the-world/ba.png +0 -0
  323. package/extensions/ublock/img/flags-of-the-world/bb.png +0 -0
  324. package/extensions/ublock/img/flags-of-the-world/bd.png +0 -0
  325. package/extensions/ublock/img/flags-of-the-world/be.png +0 -0
  326. package/extensions/ublock/img/flags-of-the-world/bf.png +0 -0
  327. package/extensions/ublock/img/flags-of-the-world/bg.png +0 -0
  328. package/extensions/ublock/img/flags-of-the-world/bh.png +0 -0
  329. package/extensions/ublock/img/flags-of-the-world/bi.png +0 -0
  330. package/extensions/ublock/img/flags-of-the-world/bj.png +0 -0
  331. package/extensions/ublock/img/flags-of-the-world/bl.png +0 -0
  332. package/extensions/ublock/img/flags-of-the-world/bm.png +0 -0
  333. package/extensions/ublock/img/flags-of-the-world/bn.png +0 -0
  334. package/extensions/ublock/img/flags-of-the-world/bo.png +0 -0
  335. package/extensions/ublock/img/flags-of-the-world/bq.png +0 -0
  336. package/extensions/ublock/img/flags-of-the-world/br.png +0 -0
  337. package/extensions/ublock/img/flags-of-the-world/bs.png +0 -0
  338. package/extensions/ublock/img/flags-of-the-world/bt.png +0 -0
  339. package/extensions/ublock/img/flags-of-the-world/bv.png +0 -0
  340. package/extensions/ublock/img/flags-of-the-world/bw.png +0 -0
  341. package/extensions/ublock/img/flags-of-the-world/by.png +0 -0
  342. package/extensions/ublock/img/flags-of-the-world/bz.png +0 -0
  343. package/extensions/ublock/img/flags-of-the-world/ca.png +0 -0
  344. package/extensions/ublock/img/flags-of-the-world/cc.png +0 -0
  345. package/extensions/ublock/img/flags-of-the-world/cd.png +0 -0
  346. package/extensions/ublock/img/flags-of-the-world/cf.png +0 -0
  347. package/extensions/ublock/img/flags-of-the-world/cg.png +0 -0
  348. package/extensions/ublock/img/flags-of-the-world/ch.png +0 -0
  349. package/extensions/ublock/img/flags-of-the-world/ci.png +0 -0
  350. package/extensions/ublock/img/flags-of-the-world/ck.png +0 -0
  351. package/extensions/ublock/img/flags-of-the-world/cl.png +0 -0
  352. package/extensions/ublock/img/flags-of-the-world/cm.png +0 -0
  353. package/extensions/ublock/img/flags-of-the-world/cn.png +0 -0
  354. package/extensions/ublock/img/flags-of-the-world/co.png +0 -0
  355. package/extensions/ublock/img/flags-of-the-world/cr.png +0 -0
  356. package/extensions/ublock/img/flags-of-the-world/cu.png +0 -0
  357. package/extensions/ublock/img/flags-of-the-world/cv.png +0 -0
  358. package/extensions/ublock/img/flags-of-the-world/cw.png +0 -0
  359. package/extensions/ublock/img/flags-of-the-world/cx.png +0 -0
  360. package/extensions/ublock/img/flags-of-the-world/cy.png +0 -0
  361. package/extensions/ublock/img/flags-of-the-world/cz.png +0 -0
  362. package/extensions/ublock/img/flags-of-the-world/de.png +0 -0
  363. package/extensions/ublock/img/flags-of-the-world/dj.png +0 -0
  364. package/extensions/ublock/img/flags-of-the-world/dk.png +0 -0
  365. package/extensions/ublock/img/flags-of-the-world/dm.png +0 -0
  366. package/extensions/ublock/img/flags-of-the-world/do.png +0 -0
  367. package/extensions/ublock/img/flags-of-the-world/dz.png +0 -0
  368. package/extensions/ublock/img/flags-of-the-world/ec.png +0 -0
  369. package/extensions/ublock/img/flags-of-the-world/ee.png +0 -0
  370. package/extensions/ublock/img/flags-of-the-world/eg.png +0 -0
  371. package/extensions/ublock/img/flags-of-the-world/eh.png +0 -0
  372. package/extensions/ublock/img/flags-of-the-world/er.png +0 -0
  373. package/extensions/ublock/img/flags-of-the-world/es.png +0 -0
  374. package/extensions/ublock/img/flags-of-the-world/et.png +0 -0
  375. package/extensions/ublock/img/flags-of-the-world/fi.png +0 -0
  376. package/extensions/ublock/img/flags-of-the-world/fj.png +0 -0
  377. package/extensions/ublock/img/flags-of-the-world/fk.png +0 -0
  378. package/extensions/ublock/img/flags-of-the-world/fm.png +0 -0
  379. package/extensions/ublock/img/flags-of-the-world/fo.png +0 -0
  380. package/extensions/ublock/img/flags-of-the-world/fr.png +0 -0
  381. package/extensions/ublock/img/flags-of-the-world/ga.png +0 -0
  382. package/extensions/ublock/img/flags-of-the-world/gb-eng.png +0 -0
  383. package/extensions/ublock/img/flags-of-the-world/gb-nir.png +0 -0
  384. package/extensions/ublock/img/flags-of-the-world/gb-sct.png +0 -0
  385. package/extensions/ublock/img/flags-of-the-world/gb-wls.png +0 -0
  386. package/extensions/ublock/img/flags-of-the-world/gb.png +0 -0
  387. package/extensions/ublock/img/flags-of-the-world/gd.png +0 -0
  388. package/extensions/ublock/img/flags-of-the-world/ge.png +0 -0
  389. package/extensions/ublock/img/flags-of-the-world/gf.png +0 -0
  390. package/extensions/ublock/img/flags-of-the-world/gg.png +0 -0
  391. package/extensions/ublock/img/flags-of-the-world/gh.png +0 -0
  392. package/extensions/ublock/img/flags-of-the-world/gi.png +0 -0
  393. package/extensions/ublock/img/flags-of-the-world/gl.png +0 -0
  394. package/extensions/ublock/img/flags-of-the-world/gm.png +0 -0
  395. package/extensions/ublock/img/flags-of-the-world/gn.png +0 -0
  396. package/extensions/ublock/img/flags-of-the-world/gp.png +0 -0
  397. package/extensions/ublock/img/flags-of-the-world/gq.png +0 -0
  398. package/extensions/ublock/img/flags-of-the-world/gr.png +0 -0
  399. package/extensions/ublock/img/flags-of-the-world/gs.png +0 -0
  400. package/extensions/ublock/img/flags-of-the-world/gt.png +0 -0
  401. package/extensions/ublock/img/flags-of-the-world/gu.png +0 -0
  402. package/extensions/ublock/img/flags-of-the-world/gw.png +0 -0
  403. package/extensions/ublock/img/flags-of-the-world/gy.png +0 -0
  404. package/extensions/ublock/img/flags-of-the-world/hk.png +0 -0
  405. package/extensions/ublock/img/flags-of-the-world/hm.png +0 -0
  406. package/extensions/ublock/img/flags-of-the-world/hn.png +0 -0
  407. package/extensions/ublock/img/flags-of-the-world/hr.png +0 -0
  408. package/extensions/ublock/img/flags-of-the-world/ht.png +0 -0
  409. package/extensions/ublock/img/flags-of-the-world/hu.png +0 -0
  410. package/extensions/ublock/img/flags-of-the-world/id.png +0 -0
  411. package/extensions/ublock/img/flags-of-the-world/ie.png +0 -0
  412. package/extensions/ublock/img/flags-of-the-world/il.png +0 -0
  413. package/extensions/ublock/img/flags-of-the-world/im.png +0 -0
  414. package/extensions/ublock/img/flags-of-the-world/in.png +0 -0
  415. package/extensions/ublock/img/flags-of-the-world/io.png +0 -0
  416. package/extensions/ublock/img/flags-of-the-world/iq.png +0 -0
  417. package/extensions/ublock/img/flags-of-the-world/ir.png +0 -0
  418. package/extensions/ublock/img/flags-of-the-world/is.png +0 -0
  419. package/extensions/ublock/img/flags-of-the-world/it.png +0 -0
  420. package/extensions/ublock/img/flags-of-the-world/je.png +0 -0
  421. package/extensions/ublock/img/flags-of-the-world/jm.png +0 -0
  422. package/extensions/ublock/img/flags-of-the-world/jo.png +0 -0
  423. package/extensions/ublock/img/flags-of-the-world/jp.png +0 -0
  424. package/extensions/ublock/img/flags-of-the-world/ke.png +0 -0
  425. package/extensions/ublock/img/flags-of-the-world/kg.png +0 -0
  426. package/extensions/ublock/img/flags-of-the-world/kh.png +0 -0
  427. package/extensions/ublock/img/flags-of-the-world/ki.png +0 -0
  428. package/extensions/ublock/img/flags-of-the-world/km.png +0 -0
  429. package/extensions/ublock/img/flags-of-the-world/kn.png +0 -0
  430. package/extensions/ublock/img/flags-of-the-world/kp.png +0 -0
  431. package/extensions/ublock/img/flags-of-the-world/kr.png +0 -0
  432. package/extensions/ublock/img/flags-of-the-world/kw.png +0 -0
  433. package/extensions/ublock/img/flags-of-the-world/ky.png +0 -0
  434. package/extensions/ublock/img/flags-of-the-world/kz.png +0 -0
  435. package/extensions/ublock/img/flags-of-the-world/la.png +0 -0
  436. package/extensions/ublock/img/flags-of-the-world/lb.png +0 -0
  437. package/extensions/ublock/img/flags-of-the-world/lc.png +0 -0
  438. package/extensions/ublock/img/flags-of-the-world/li.png +0 -0
  439. package/extensions/ublock/img/flags-of-the-world/lk.png +0 -0
  440. package/extensions/ublock/img/flags-of-the-world/lr.png +0 -0
  441. package/extensions/ublock/img/flags-of-the-world/ls.png +0 -0
  442. package/extensions/ublock/img/flags-of-the-world/lt.png +0 -0
  443. package/extensions/ublock/img/flags-of-the-world/lu.png +0 -0
  444. package/extensions/ublock/img/flags-of-the-world/lv.png +0 -0
  445. package/extensions/ublock/img/flags-of-the-world/ly.png +0 -0
  446. package/extensions/ublock/img/flags-of-the-world/ma.png +0 -0
  447. package/extensions/ublock/img/flags-of-the-world/mc.png +0 -0
  448. package/extensions/ublock/img/flags-of-the-world/md.png +0 -0
  449. package/extensions/ublock/img/flags-of-the-world/me.png +0 -0
  450. package/extensions/ublock/img/flags-of-the-world/mf.png +0 -0
  451. package/extensions/ublock/img/flags-of-the-world/mg.png +0 -0
  452. package/extensions/ublock/img/flags-of-the-world/mh.png +0 -0
  453. package/extensions/ublock/img/flags-of-the-world/mk.png +0 -0
  454. package/extensions/ublock/img/flags-of-the-world/ml.png +0 -0
  455. package/extensions/ublock/img/flags-of-the-world/mm.png +0 -0
  456. package/extensions/ublock/img/flags-of-the-world/mn.png +0 -0
  457. package/extensions/ublock/img/flags-of-the-world/mo.png +0 -0
  458. package/extensions/ublock/img/flags-of-the-world/mp.png +0 -0
  459. package/extensions/ublock/img/flags-of-the-world/mq.png +0 -0
  460. package/extensions/ublock/img/flags-of-the-world/mr.png +0 -0
  461. package/extensions/ublock/img/flags-of-the-world/ms.png +0 -0
  462. package/extensions/ublock/img/flags-of-the-world/mt.png +0 -0
  463. package/extensions/ublock/img/flags-of-the-world/mu.png +0 -0
  464. package/extensions/ublock/img/flags-of-the-world/mv.png +0 -0
  465. package/extensions/ublock/img/flags-of-the-world/mw.png +0 -0
  466. package/extensions/ublock/img/flags-of-the-world/mx.png +0 -0
  467. package/extensions/ublock/img/flags-of-the-world/my.png +0 -0
  468. package/extensions/ublock/img/flags-of-the-world/mz.png +0 -0
  469. package/extensions/ublock/img/flags-of-the-world/na.png +0 -0
  470. package/extensions/ublock/img/flags-of-the-world/nc.png +0 -0
  471. package/extensions/ublock/img/flags-of-the-world/ne.png +0 -0
  472. package/extensions/ublock/img/flags-of-the-world/nf.png +0 -0
  473. package/extensions/ublock/img/flags-of-the-world/ng.png +0 -0
  474. package/extensions/ublock/img/flags-of-the-world/ni.png +0 -0
  475. package/extensions/ublock/img/flags-of-the-world/nl.png +0 -0
  476. package/extensions/ublock/img/flags-of-the-world/no.png +0 -0
  477. package/extensions/ublock/img/flags-of-the-world/np.png +0 -0
  478. package/extensions/ublock/img/flags-of-the-world/nr.png +0 -0
  479. package/extensions/ublock/img/flags-of-the-world/nu.png +0 -0
  480. package/extensions/ublock/img/flags-of-the-world/nz.png +0 -0
  481. package/extensions/ublock/img/flags-of-the-world/om.png +0 -0
  482. package/extensions/ublock/img/flags-of-the-world/pa.png +0 -0
  483. package/extensions/ublock/img/flags-of-the-world/pe.png +0 -0
  484. package/extensions/ublock/img/flags-of-the-world/pf.png +0 -0
  485. package/extensions/ublock/img/flags-of-the-world/pg.png +0 -0
  486. package/extensions/ublock/img/flags-of-the-world/ph.png +0 -0
  487. package/extensions/ublock/img/flags-of-the-world/pk.png +0 -0
  488. package/extensions/ublock/img/flags-of-the-world/pl.png +0 -0
  489. package/extensions/ublock/img/flags-of-the-world/pm.png +0 -0
  490. package/extensions/ublock/img/flags-of-the-world/pn.png +0 -0
  491. package/extensions/ublock/img/flags-of-the-world/pr.png +0 -0
  492. package/extensions/ublock/img/flags-of-the-world/ps.png +0 -0
  493. package/extensions/ublock/img/flags-of-the-world/pt.png +0 -0
  494. package/extensions/ublock/img/flags-of-the-world/pw.png +0 -0
  495. package/extensions/ublock/img/flags-of-the-world/py.png +0 -0
  496. package/extensions/ublock/img/flags-of-the-world/qa.png +0 -0
  497. package/extensions/ublock/img/flags-of-the-world/re.png +0 -0
  498. package/extensions/ublock/img/flags-of-the-world/ro.png +0 -0
  499. package/extensions/ublock/img/flags-of-the-world/rs.png +0 -0
  500. package/extensions/ublock/img/flags-of-the-world/ru.png +0 -0
  501. package/extensions/ublock/img/flags-of-the-world/rw.png +0 -0
  502. package/extensions/ublock/img/flags-of-the-world/sa.png +0 -0
  503. package/extensions/ublock/img/flags-of-the-world/sb.png +0 -0
  504. package/extensions/ublock/img/flags-of-the-world/sc.png +0 -0
  505. package/extensions/ublock/img/flags-of-the-world/sd.png +0 -0
  506. package/extensions/ublock/img/flags-of-the-world/se.png +0 -0
  507. package/extensions/ublock/img/flags-of-the-world/sg.png +0 -0
  508. package/extensions/ublock/img/flags-of-the-world/sh.png +0 -0
  509. package/extensions/ublock/img/flags-of-the-world/si.png +0 -0
  510. package/extensions/ublock/img/flags-of-the-world/sj.png +0 -0
  511. package/extensions/ublock/img/flags-of-the-world/sk.png +0 -0
  512. package/extensions/ublock/img/flags-of-the-world/sl.png +0 -0
  513. package/extensions/ublock/img/flags-of-the-world/sm.png +0 -0
  514. package/extensions/ublock/img/flags-of-the-world/sn.png +0 -0
  515. package/extensions/ublock/img/flags-of-the-world/so.png +0 -0
  516. package/extensions/ublock/img/flags-of-the-world/sr.png +0 -0
  517. package/extensions/ublock/img/flags-of-the-world/ss.png +0 -0
  518. package/extensions/ublock/img/flags-of-the-world/st.png +0 -0
  519. package/extensions/ublock/img/flags-of-the-world/sv.png +0 -0
  520. package/extensions/ublock/img/flags-of-the-world/sx.png +0 -0
  521. package/extensions/ublock/img/flags-of-the-world/sy.png +0 -0
  522. package/extensions/ublock/img/flags-of-the-world/sz.png +0 -0
  523. package/extensions/ublock/img/flags-of-the-world/tc.png +0 -0
  524. package/extensions/ublock/img/flags-of-the-world/td.png +0 -0
  525. package/extensions/ublock/img/flags-of-the-world/tf.png +0 -0
  526. package/extensions/ublock/img/flags-of-the-world/tg.png +0 -0
  527. package/extensions/ublock/img/flags-of-the-world/th.png +0 -0
  528. package/extensions/ublock/img/flags-of-the-world/tj.png +0 -0
  529. package/extensions/ublock/img/flags-of-the-world/tk.png +0 -0
  530. package/extensions/ublock/img/flags-of-the-world/tl.png +0 -0
  531. package/extensions/ublock/img/flags-of-the-world/tm.png +0 -0
  532. package/extensions/ublock/img/flags-of-the-world/tn.png +0 -0
  533. package/extensions/ublock/img/flags-of-the-world/to.png +0 -0
  534. package/extensions/ublock/img/flags-of-the-world/tr.png +0 -0
  535. package/extensions/ublock/img/flags-of-the-world/tt.png +0 -0
  536. package/extensions/ublock/img/flags-of-the-world/tv.png +0 -0
  537. package/extensions/ublock/img/flags-of-the-world/tw.png +0 -0
  538. package/extensions/ublock/img/flags-of-the-world/tz.png +0 -0
  539. package/extensions/ublock/img/flags-of-the-world/ua.png +0 -0
  540. package/extensions/ublock/img/flags-of-the-world/ug.png +0 -0
  541. package/extensions/ublock/img/flags-of-the-world/um.png +0 -0
  542. package/extensions/ublock/img/flags-of-the-world/us.png +0 -0
  543. package/extensions/ublock/img/flags-of-the-world/uy.png +0 -0
  544. package/extensions/ublock/img/flags-of-the-world/uz.png +0 -0
  545. package/extensions/ublock/img/flags-of-the-world/va.png +0 -0
  546. package/extensions/ublock/img/flags-of-the-world/vc.png +0 -0
  547. package/extensions/ublock/img/flags-of-the-world/ve.png +0 -0
  548. package/extensions/ublock/img/flags-of-the-world/vg.png +0 -0
  549. package/extensions/ublock/img/flags-of-the-world/vi.png +0 -0
  550. package/extensions/ublock/img/flags-of-the-world/vn.png +0 -0
  551. package/extensions/ublock/img/flags-of-the-world/vu.png +0 -0
  552. package/extensions/ublock/img/flags-of-the-world/wf.png +0 -0
  553. package/extensions/ublock/img/flags-of-the-world/ws.png +0 -0
  554. package/extensions/ublock/img/flags-of-the-world/xk.png +0 -0
  555. package/extensions/ublock/img/flags-of-the-world/ye.png +0 -0
  556. package/extensions/ublock/img/flags-of-the-world/yt.png +0 -0
  557. package/extensions/ublock/img/flags-of-the-world/za.png +0 -0
  558. package/extensions/ublock/img/flags-of-the-world/zm.png +0 -0
  559. package/extensions/ublock/img/flags-of-the-world/zw.png +0 -0
  560. package/extensions/ublock/img/fontawesome/LICENSE.txt +25 -0
  561. package/extensions/ublock/img/fontawesome/fontawesome-defs.svg +79 -0
  562. package/extensions/ublock/img/help16.png +0 -0
  563. package/extensions/ublock/img/icon_128.png +0 -0
  564. package/extensions/ublock/img/icon_16-loading.png +0 -0
  565. package/extensions/ublock/img/icon_16-off.png +0 -0
  566. package/extensions/ublock/img/icon_16.png +0 -0
  567. package/extensions/ublock/img/icon_32-loading.png +0 -0
  568. package/extensions/ublock/img/icon_32-off.png +0 -0
  569. package/extensions/ublock/img/icon_32.png +0 -0
  570. package/extensions/ublock/img/icon_64-loading.png +0 -0
  571. package/extensions/ublock/img/icon_64-off.png +0 -0
  572. package/extensions/ublock/img/icon_64.png +0 -0
  573. package/extensions/ublock/img/material-design.svg +16 -0
  574. package/extensions/ublock/img/photon.svg +16 -0
  575. package/extensions/ublock/img/ublock-defs.svg +27 -0
  576. package/extensions/ublock/img/ublock.svg +44 -0
  577. package/extensions/ublock/is-webrtc-supported.html +9 -0
  578. package/extensions/ublock/js/1p-filters.js +336 -0
  579. package/extensions/ublock/js/3p-filters.js +867 -0
  580. package/extensions/ublock/js/about.js +34 -0
  581. package/extensions/ublock/js/advanced-settings.js +194 -0
  582. package/extensions/ublock/js/asset-viewer.js +112 -0
  583. package/extensions/ublock/js/assets.js +1448 -0
  584. package/extensions/ublock/js/background.js +404 -0
  585. package/extensions/ublock/js/base64-custom.js +246 -0
  586. package/extensions/ublock/js/benchmarks.js +421 -0
  587. package/extensions/ublock/js/biditrie.js +947 -0
  588. package/extensions/ublock/js/cachestorage.js +510 -0
  589. package/extensions/ublock/js/click2load.js +60 -0
  590. package/extensions/ublock/js/cloud-ui.js +238 -0
  591. package/extensions/ublock/js/code-viewer.js +311 -0
  592. package/extensions/ublock/js/codemirror/search-thread.js +199 -0
  593. package/extensions/ublock/js/codemirror/search.js +504 -0
  594. package/extensions/ublock/js/codemirror/ubo-dynamic-filtering.js +239 -0
  595. package/extensions/ublock/js/codemirror/ubo-static-filtering.js +1126 -0
  596. package/extensions/ublock/js/commands.js +181 -0
  597. package/extensions/ublock/js/console.js +59 -0
  598. package/extensions/ublock/js/contentscript-extra.js +662 -0
  599. package/extensions/ublock/js/contentscript.js +1366 -0
  600. package/extensions/ublock/js/contextmenu.js +270 -0
  601. package/extensions/ublock/js/cosmetic-filtering.js +983 -0
  602. package/extensions/ublock/js/dashboard-common.js +215 -0
  603. package/extensions/ublock/js/dashboard.js +166 -0
  604. package/extensions/ublock/js/devtools.js +184 -0
  605. package/extensions/ublock/js/diff-updater.js +288 -0
  606. package/extensions/ublock/js/document-blocked.js +230 -0
  607. package/extensions/ublock/js/dom.js +213 -0
  608. package/extensions/ublock/js/dyna-rules.js +678 -0
  609. package/extensions/ublock/js/dynamic-net-filtering.js +488 -0
  610. package/extensions/ublock/js/epicker-ui.js +924 -0
  611. package/extensions/ublock/js/fa-icons.js +129 -0
  612. package/extensions/ublock/js/filtering-context.js +461 -0
  613. package/extensions/ublock/js/filtering-engines.js +50 -0
  614. package/extensions/ublock/js/hnswitches.js +289 -0
  615. package/extensions/ublock/js/hntrie.js +780 -0
  616. package/extensions/ublock/js/html-filtering.js +465 -0
  617. package/extensions/ublock/js/httpheader-filtering.js +213 -0
  618. package/extensions/ublock/js/i18n.js +346 -0
  619. package/extensions/ublock/js/is-webrtc-supported.js +52 -0
  620. package/extensions/ublock/js/logger-ui-inspector.js +652 -0
  621. package/extensions/ublock/js/logger-ui.js +3028 -0
  622. package/extensions/ublock/js/logger.js +84 -0
  623. package/extensions/ublock/js/lz4.js +190 -0
  624. package/extensions/ublock/js/messaging.js +2095 -0
  625. package/extensions/ublock/js/pagestore.js +1140 -0
  626. package/extensions/ublock/js/popup-fenix.js +1529 -0
  627. package/extensions/ublock/js/redirect-engine.js +494 -0
  628. package/extensions/ublock/js/redirect-resources.js +193 -0
  629. package/extensions/ublock/js/reverselookup-worker.js +287 -0
  630. package/extensions/ublock/js/reverselookup.js +223 -0
  631. package/extensions/ublock/js/scriptlet-filtering.js +556 -0
  632. package/extensions/ublock/js/scriptlets/cosmetic-logger.js +376 -0
  633. package/extensions/ublock/js/scriptlets/cosmetic-off.js +48 -0
  634. package/extensions/ublock/js/scriptlets/cosmetic-on.js +48 -0
  635. package/extensions/ublock/js/scriptlets/cosmetic-report.js +142 -0
  636. package/extensions/ublock/js/scriptlets/dom-inspector.js +906 -0
  637. package/extensions/ublock/js/scriptlets/dom-survey-elements.js +72 -0
  638. package/extensions/ublock/js/scriptlets/dom-survey-scripts.js +126 -0
  639. package/extensions/ublock/js/scriptlets/epicker.js +1365 -0
  640. package/extensions/ublock/js/scriptlets/load-3p-css.js +67 -0
  641. package/extensions/ublock/js/scriptlets/load-large-media-all.js +62 -0
  642. package/extensions/ublock/js/scriptlets/load-large-media-interactive.js +299 -0
  643. package/extensions/ublock/js/scriptlets/noscript-spoof.js +89 -0
  644. package/extensions/ublock/js/scriptlets/should-inject-contentscript.js +40 -0
  645. package/extensions/ublock/js/scriptlets/subscriber.js +113 -0
  646. package/extensions/ublock/js/scriptlets/updater.js +101 -0
  647. package/extensions/ublock/js/settings.js +317 -0
  648. package/extensions/ublock/js/start.js +509 -0
  649. package/extensions/ublock/js/static-dnr-filtering.js +497 -0
  650. package/extensions/ublock/js/static-ext-filtering-db.js +171 -0
  651. package/extensions/ublock/js/static-ext-filtering.js +184 -0
  652. package/extensions/ublock/js/static-filtering-io.js +144 -0
  653. package/extensions/ublock/js/static-filtering-parser.js +4459 -0
  654. package/extensions/ublock/js/static-net-filtering.js +5631 -0
  655. package/extensions/ublock/js/storage.js +1683 -0
  656. package/extensions/ublock/js/support.js +335 -0
  657. package/extensions/ublock/js/tab.js +1178 -0
  658. package/extensions/ublock/js/tasks.js +42 -0
  659. package/extensions/ublock/js/text-encode.js +275 -0
  660. package/extensions/ublock/js/text-utils.js +107 -0
  661. package/extensions/ublock/js/theme.js +151 -0
  662. package/extensions/ublock/js/traffic.js +1260 -0
  663. package/extensions/ublock/js/ublock.js +696 -0
  664. package/extensions/ublock/js/uri-utils.js +175 -0
  665. package/extensions/ublock/js/url-net-filtering.js +336 -0
  666. package/extensions/ublock/js/utils.js +208 -0
  667. package/extensions/ublock/js/vapi-background-ext.js +254 -0
  668. package/extensions/ublock/js/vapi-background.js +1802 -0
  669. package/extensions/ublock/js/vapi-client-extra.js +312 -0
  670. package/extensions/ublock/js/vapi-client.js +280 -0
  671. package/extensions/ublock/js/vapi-common.js +308 -0
  672. package/extensions/ublock/js/vapi.js +89 -0
  673. package/extensions/ublock/js/wasm/README.md +24 -0
  674. package/extensions/ublock/js/wasm/biditrie.wasm +0 -0
  675. package/extensions/ublock/js/wasm/biditrie.wat +728 -0
  676. package/extensions/ublock/js/wasm/hntrie.wasm +0 -0
  677. package/extensions/ublock/js/wasm/hntrie.wat +724 -0
  678. package/extensions/ublock/js/webext.js +164 -0
  679. package/extensions/ublock/js/whitelist.js +258 -0
  680. package/extensions/ublock/lib/codemirror/LICENSE +21 -0
  681. package/extensions/ublock/lib/codemirror/README.md +47 -0
  682. package/extensions/ublock/lib/codemirror/addon/comment/comment.js +211 -0
  683. package/extensions/ublock/lib/codemirror/addon/display/panel.js +133 -0
  684. package/extensions/ublock/lib/codemirror/addon/edit/closebrackets.js +201 -0
  685. package/extensions/ublock/lib/codemirror/addon/edit/matchbrackets.js +160 -0
  686. package/extensions/ublock/lib/codemirror/addon/fold/foldcode.js +157 -0
  687. package/extensions/ublock/lib/codemirror/addon/fold/foldgutter.css +20 -0
  688. package/extensions/ublock/lib/codemirror/addon/fold/foldgutter.js +163 -0
  689. package/extensions/ublock/lib/codemirror/addon/hint/show-hint.css +36 -0
  690. package/extensions/ublock/lib/codemirror/addon/hint/show-hint.js +509 -0
  691. package/extensions/ublock/lib/codemirror/addon/merge/merge.css +119 -0
  692. package/extensions/ublock/lib/codemirror/addon/merge/merge.js +1006 -0
  693. package/extensions/ublock/lib/codemirror/addon/scroll/annotatescrollbar.js +128 -0
  694. package/extensions/ublock/lib/codemirror/addon/search/matchesonscrollbar.css +8 -0
  695. package/extensions/ublock/lib/codemirror/addon/search/searchcursor.js +296 -0
  696. package/extensions/ublock/lib/codemirror/addon/selection/active-line.js +72 -0
  697. package/extensions/ublock/lib/codemirror/lib/codemirror.css +350 -0
  698. package/extensions/ublock/lib/codemirror/lib/codemirror.js +9800 -0
  699. package/extensions/ublock/lib/codemirror/mode/css/css.js +864 -0
  700. package/extensions/ublock/lib/codemirror/mode/htmlmixed/htmlmixed.js +153 -0
  701. package/extensions/ublock/lib/codemirror/mode/javascript/javascript.js +942 -0
  702. package/extensions/ublock/lib/codemirror/mode/xml/xml.js +413 -0
  703. package/extensions/ublock/lib/codemirror/theme/night.css +27 -0
  704. package/extensions/ublock/lib/csstree/LICENSE +19 -0
  705. package/extensions/ublock/lib/csstree/css-tree.js +17 -0
  706. package/extensions/ublock/lib/diff/README.md +34 -0
  707. package/extensions/ublock/lib/diff/swatinem_diff.js +272 -0
  708. package/extensions/ublock/lib/hsluv/LICENSE +20 -0
  709. package/extensions/ublock/lib/hsluv/README +3 -0
  710. package/extensions/ublock/lib/hsluv/hsluv-0.1.0.min.js +8 -0
  711. package/extensions/ublock/lib/js-beautify/LICENSE +9 -0
  712. package/extensions/ublock/lib/js-beautify/README +5 -0
  713. package/extensions/ublock/lib/js-beautify/beautifier.min.js +2 -0
  714. package/extensions/ublock/lib/lz4/README.md +52 -0
  715. package/extensions/ublock/lib/lz4/lz4-block-codec-any.js +151 -0
  716. package/extensions/ublock/lib/lz4/lz4-block-codec-js.js +297 -0
  717. package/extensions/ublock/lib/lz4/lz4-block-codec-wasm.js +195 -0
  718. package/extensions/ublock/lib/lz4/lz4-block-codec.wasm +0 -0
  719. package/extensions/ublock/lib/lz4/lz4-block-codec.wat +745 -0
  720. package/extensions/ublock/lib/publicsuffixlist/publicsuffixlist.js +641 -0
  721. package/extensions/ublock/lib/publicsuffixlist/wasm/README.md +29 -0
  722. package/extensions/ublock/lib/publicsuffixlist/wasm/publicsuffixlist.wasm +0 -0
  723. package/extensions/ublock/lib/publicsuffixlist/wasm/publicsuffixlist.wat +322 -0
  724. package/extensions/ublock/lib/punycode.js +493 -0
  725. package/extensions/ublock/lib/regexanalyzer/CHANGES.md +15 -0
  726. package/extensions/ublock/lib/regexanalyzer/README.md +14 -0
  727. package/extensions/ublock/lib/regexanalyzer/regex.js +2276 -0
  728. package/extensions/ublock/logger-ui.html +232 -0
  729. package/extensions/ublock/managed_storage.json +73 -0
  730. package/extensions/ublock/manifest.json +115 -0
  731. package/extensions/ublock/no-dashboard.html +27 -0
  732. package/extensions/ublock/popup-fenix.html +114 -0
  733. package/extensions/ublock/settings.html +98 -0
  734. package/extensions/ublock/support.html +131 -0
  735. package/extensions/ublock/web_accessible_resources/1x1.gif +0 -0
  736. package/extensions/ublock/web_accessible_resources/2x2.png +0 -0
  737. package/extensions/ublock/web_accessible_resources/32x32.png +0 -0
  738. package/extensions/ublock/web_accessible_resources/3x2.png +0 -0
  739. package/extensions/ublock/web_accessible_resources/README.txt +11 -0
  740. package/extensions/ublock/web_accessible_resources/addthis_widget.js +39 -0
  741. package/extensions/ublock/web_accessible_resources/amazon_ads.js +70 -0
  742. package/extensions/ublock/web_accessible_resources/amazon_apstag.js +62 -0
  743. package/extensions/ublock/web_accessible_resources/ampproject_v0.js +34 -0
  744. package/extensions/ublock/web_accessible_resources/chartbeat.js +30 -0
  745. package/extensions/ublock/web_accessible_resources/click2load.html +28 -0
  746. package/extensions/ublock/web_accessible_resources/doubleclick_instream_ad_status.js +1 -0
  747. package/extensions/ublock/web_accessible_resources/empty +0 -0
  748. package/extensions/ublock/web_accessible_resources/epicker-ui.html +76 -0
  749. package/extensions/ublock/web_accessible_resources/fingerprint2.js +55 -0
  750. package/extensions/ublock/web_accessible_resources/fingerprint3.js +45 -0
  751. package/extensions/ublock/web_accessible_resources/google-analytics_analytics.js +110 -0
  752. package/extensions/ublock/web_accessible_resources/google-analytics_cx_api.js +36 -0
  753. package/extensions/ublock/web_accessible_resources/google-analytics_ga.js +130 -0
  754. package/extensions/ublock/web_accessible_resources/google-analytics_inpage_linkid.js +28 -0
  755. package/extensions/ublock/web_accessible_resources/google-ima.js +855 -0
  756. package/extensions/ublock/web_accessible_resources/googlesyndication_adsbygoogle.js +56 -0
  757. package/extensions/ublock/web_accessible_resources/googletagmanager_gtm.js +43 -0
  758. package/extensions/ublock/web_accessible_resources/googletagservices_gpt.js +153 -0
  759. package/extensions/ublock/web_accessible_resources/hd-main.js +46 -0
  760. package/extensions/ublock/web_accessible_resources/ligatus_angular-tag.js +29 -0
  761. package/extensions/ublock/web_accessible_resources/monkeybroker.js +43 -0
  762. package/extensions/ublock/web_accessible_resources/mxpnl_mixpanel.js +51 -0
  763. package/extensions/ublock/web_accessible_resources/nobab.js +87 -0
  764. package/extensions/ublock/web_accessible_resources/nobab2.js +42 -0
  765. package/extensions/ublock/web_accessible_resources/noeval-silent.js +28 -0
  766. package/extensions/ublock/web_accessible_resources/noeval.js +30 -0
  767. package/extensions/ublock/web_accessible_resources/nofab.js +67 -0
  768. package/extensions/ublock/web_accessible_resources/noop-0.1s.mp3 +0 -0
  769. package/extensions/ublock/web_accessible_resources/noop-0.5s.mp3 +0 -0
  770. package/extensions/ublock/web_accessible_resources/noop-1s.mp4 +0 -0
  771. package/extensions/ublock/web_accessible_resources/noop-vmap1.0.xml +1 -0
  772. package/extensions/ublock/web_accessible_resources/noop.css +1 -0
  773. package/extensions/ublock/web_accessible_resources/noop.html +5 -0
  774. package/extensions/ublock/web_accessible_resources/noop.js +3 -0
  775. package/extensions/ublock/web_accessible_resources/noop.json +1 -0
  776. package/extensions/ublock/web_accessible_resources/noop.txt +1 -0
  777. package/extensions/ublock/web_accessible_resources/outbrain-widget.js +72 -0
  778. package/extensions/ublock/web_accessible_resources/popads-dummy.js +30 -0
  779. package/extensions/ublock/web_accessible_resources/popads.js +40 -0
  780. package/extensions/ublock/web_accessible_resources/prebid-ads.js +26 -0
  781. package/extensions/ublock/web_accessible_resources/scorecardresearch_beacon.js +31 -0
  782. package/extensions/ublock/whitelist.html +63 -0
  783. package/external/.gitkeep +0 -0
  784. package/fonts/Calibri Bold Italic.ttf +0 -0
  785. package/fonts/Calibri Bold.TTF +0 -0
  786. package/fonts/Calibri Italic.ttf +0 -0
  787. package/fonts/Calibri Light Italic.ttf +0 -0
  788. package/fonts/Calibri Light.ttf +0 -0
  789. package/fonts/Calibri Regular.ttf +0 -0
  790. package/fonts/Emoji.ttf +0 -0
  791. package/fonts/SegoeUI-Bold.ttf +0 -0
  792. package/fonts/SegoeUI-Light.ttf +0 -0
  793. package/fonts/SegoeUI-Regular.ttf +0 -0
  794. package/fonts/SegoeUI-Semibold.ttf +0 -0
  795. package/fonts/SegoeUI-Semilight.ttf +0 -0
  796. package/fonts/Tahoma Bold.ttf +0 -0
  797. package/fonts/Tahoma.ttf +0 -0
  798. package/fonts/fonts.conf +21 -0
  799. package/package.json +177 -0
  800. package/scripts/build-function.js +18 -0
  801. package/scripts/build-open-api.js +274 -0
  802. package/scripts/build-schemas.js +86 -0
  803. package/scripts/build-selectors.js +36 -0
  804. package/scripts/clean.js +7 -0
  805. package/scripts/install-adblock.js +45 -0
  806. package/scripts/install-cdp-json.js +37 -0
  807. package/scripts/start.sh +30 -0
  808. package/scripts/test.sh +17 -0
  809. package/src/browserless.ts +253 -0
  810. package/src/browsers/cdp-chromium.ts +422 -0
  811. package/src/browsers/index.ts +296 -0
  812. package/src/browsers/playwright-chromium.ts +168 -0
  813. package/src/browsers/playwright-firefox.ts +161 -0
  814. package/src/browsers/playwright-webkit.ts +161 -0
  815. package/src/config.ts +426 -0
  816. package/src/constants.ts +4 -0
  817. package/src/exports.ts +23 -0
  818. package/src/file-system.ts +54 -0
  819. package/src/hooks.ts +37 -0
  820. package/src/http.ts +157 -0
  821. package/src/index.ts +41 -0
  822. package/src/limiter.spec.ts +365 -0
  823. package/src/limiter.ts +225 -0
  824. package/src/metrics.spec.ts +49 -0
  825. package/src/metrics.ts +108 -0
  826. package/src/mime-types.ts +332 -0
  827. package/src/monitoring.ts +53 -0
  828. package/src/routes/chromium/http/content-post.ts +238 -0
  829. package/src/routes/chromium/http/download-post.ts +162 -0
  830. package/src/routes/chromium/http/function-post.ts +98 -0
  831. package/src/routes/chromium/http/pdf-post.ts +234 -0
  832. package/src/routes/chromium/http/performance.ts +71 -0
  833. package/src/routes/chromium/http/scrape-post.ts +439 -0
  834. package/src/routes/chromium/http/screenshot-post.ts +262 -0
  835. package/src/routes/chromium/tests/content.spec.ts +340 -0
  836. package/src/routes/chromium/tests/download.spec.ts +77 -0
  837. package/src/routes/chromium/tests/function.spec.ts +279 -0
  838. package/src/routes/chromium/tests/pdf.spec.ts +375 -0
  839. package/src/routes/chromium/tests/performance.spec.ts +155 -0
  840. package/src/routes/chromium/tests/scrape.spec.ts +414 -0
  841. package/src/routes/chromium/tests/screenshot.spec.ts +387 -0
  842. package/src/routes/chromium/tests/websocket.spec.ts +407 -0
  843. package/src/routes/chromium/utils/function/client.ts +99 -0
  844. package/src/routes/chromium/utils/function/handler.ts +172 -0
  845. package/src/routes/chromium/utils/performance/child.ts +38 -0
  846. package/src/routes/chromium/utils/performance/main.ts +90 -0
  847. package/src/routes/chromium/utils/performance/types.ts +24 -0
  848. package/src/routes/chromium/ws/browser.ts +31 -0
  849. package/src/routes/chromium/ws/cdp-chromium.ts +31 -0
  850. package/src/routes/chromium/ws/page.ts +31 -0
  851. package/src/routes/chromium/ws/playwright-chromium.ts +44 -0
  852. package/src/routes/firefox/tests/websocket.spec.ts +146 -0
  853. package/src/routes/firefox/ws/playwright-firefox.ts +44 -0
  854. package/src/routes/management/http/config-get.ts +82 -0
  855. package/src/routes/management/http/metrics-get.ts +43 -0
  856. package/src/routes/management/http/metrics-total-get.ts +89 -0
  857. package/src/routes/management/http/sessions-get.ts +39 -0
  858. package/src/routes/management/http/static-get.ts +109 -0
  859. package/src/routes/management/tests/management.spec.ts +71 -0
  860. package/src/routes/webkit/tests/websocket.spec.ts +146 -0
  861. package/src/routes/webkit/ws/playwright-webkit.ts +44 -0
  862. package/src/server.ts +609 -0
  863. package/src/shim.spec.ts +154 -0
  864. package/src/shim.ts +78 -0
  865. package/src/types.ts +470 -0
  866. package/src/utils.ts +787 -0
  867. package/src/webhooks.ts +50 -0
  868. package/static/docs/browserless-logo.png +0 -0
  869. package/static/docs/docs.js +2 -0
  870. package/static/docs/index.html +71 -0
  871. package/static/docs/swagger.json +4232 -0
  872. package/static/favicon-32x32.png +0 -0
  873. package/static/function/client.js +31623 -0
  874. package/static/function/index.html +12 -0
  875. package/tsconfig.json +31 -0
@@ -0,0 +1,1448 @@
1
+ /*******************************************************************************
2
+
3
+ uBlock Origin - a browser extension to block requests.
4
+ Copyright (C) 2014-present Raymond Hill
5
+
6
+ This program is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ This program is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with this program. If not, see {http://www.gnu.org/licenses/}.
18
+
19
+ Home: https://github.com/gorhill/uBlock
20
+ */
21
+
22
+ 'use strict';
23
+
24
+ /******************************************************************************/
25
+
26
+ import cacheStorage from './cachestorage.js';
27
+ import logger from './logger.js';
28
+ import µb from './background.js';
29
+ import { ubolog } from './console.js';
30
+ import { i18n$ } from './i18n.js';
31
+ import * as sfp from './static-filtering-parser.js';
32
+ import { orphanizeString, } from './text-utils.js';
33
+
34
+ /******************************************************************************/
35
+
36
+ const reIsExternalPath = /^(?:[a-z-]+):\/\//;
37
+ const reIsUserAsset = /^user-/;
38
+ const errorCantConnectTo = i18n$('errorCantConnectTo');
39
+ const MS_PER_HOUR = 60 * 60 * 1000;
40
+ const MS_PER_DAY = 24 * MS_PER_HOUR;
41
+ const EXPIRES_DEFAULT = 7;
42
+
43
+ const assets = {};
44
+
45
+ // A hint for various pieces of code to take measures if possible to save
46
+ // bandwidth of remote servers.
47
+ let remoteServerFriendly = false;
48
+
49
+ /******************************************************************************/
50
+
51
+ const stringIsNotEmpty = s => typeof s === 'string' && s !== '';
52
+
53
+ const parseExpires = s => {
54
+ const matches = s.match(/(\d+)\s*([dhm]?)/i);
55
+ if ( matches === null ) { return 0; }
56
+ let updateAfter = parseInt(matches[1], 10);
57
+ if ( matches[2] === 'h' ) {
58
+ updateAfter = Math.max(updateAfter, 4) / 24;
59
+ } else if ( matches[2] === 'm' ) {
60
+ updateAfter = Math.max(updateAfter, 240) / 1440;
61
+ }
62
+ return updateAfter;
63
+ };
64
+
65
+ const extractMetadataFromList = (content, fields) => {
66
+ const out = {};
67
+ const head = content.slice(0, 1024);
68
+ for ( let field of fields ) {
69
+ field = field.replace(/\s+/g, '-');
70
+ const re = new RegExp(`^(?:! *|# +)${field.replace(/-/g, '(?: +|-)')}: *(.+)$`, 'im');
71
+ const match = re.exec(head);
72
+ let value = match && match[1].trim() || undefined;
73
+ if ( value !== undefined && value.startsWith('%') ) {
74
+ value = undefined;
75
+ }
76
+ field = field.toLowerCase().replace(
77
+ /-[a-z]/g, s => s.charAt(1).toUpperCase()
78
+ );
79
+ out[field] = value && orphanizeString(value);
80
+ }
81
+ // Pre-process known fields
82
+ if ( out.lastModified ) {
83
+ out.lastModified = (new Date(out.lastModified)).getTime() || 0;
84
+ }
85
+ if ( out.expires ) {
86
+ out.expires = parseExpires(out.expires);
87
+ }
88
+ if ( out.diffExpires ) {
89
+ out.diffExpires = parseExpires(out.diffExpires);
90
+ }
91
+ return out;
92
+ };
93
+ assets.extractMetadataFromList = extractMetadataFromList;
94
+
95
+ const resourceTimeFromXhr = xhr => {
96
+ try {
97
+ // First lookup timestamp from content
98
+ let assetTime = 0;
99
+ if ( typeof xhr.response === 'string' ) {
100
+ const metadata = extractMetadataFromList(xhr.response, [
101
+ 'Last-Modified'
102
+ ]);
103
+ assetTime = metadata.lastModified || 0;
104
+ }
105
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Age
106
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Date
107
+ let networkTime = 0;
108
+ if ( assetTime === 0 ) {
109
+ const age = parseInt(xhr.getResponseHeader('Age'), 10);
110
+ if ( isNaN(age) === false ) {
111
+ const time = (new Date(xhr.getResponseHeader('Date'))).getTime();
112
+ if ( isNaN(time) === false ) {
113
+ networkTime = time - age * 1000;
114
+ }
115
+ }
116
+ }
117
+ return Math.max(assetTime, networkTime, 0);
118
+ } catch(_) {
119
+ }
120
+ return 0;
121
+ };
122
+
123
+ const resourceTimeFromParts = (parts, time) => {
124
+ const goodParts = parts.filter(part => typeof part === 'object');
125
+ return goodParts.reduce((acc, part) =>
126
+ ((part.resourceTime || 0) > acc ? part.resourceTime : acc),
127
+ time
128
+ );
129
+ };
130
+
131
+ const resourceIsStale = (networkDetails, cacheDetails) => {
132
+ if ( typeof networkDetails.resourceTime !== 'number' ) { return false; }
133
+ if ( networkDetails.resourceTime === 0 ) { return false; }
134
+ if ( typeof cacheDetails.resourceTime !== 'number' ) { return false; }
135
+ if ( cacheDetails.resourceTime === 0 ) { return false; }
136
+ if ( networkDetails.resourceTime < cacheDetails.resourceTime ) {
137
+ ubolog(`Skip ${networkDetails.url}\n\tolder than ${cacheDetails.remoteURL}`);
138
+ return true;
139
+ }
140
+ return false;
141
+ };
142
+
143
+ const getUpdateAfterTime = (assetKey, diff = false) => {
144
+ const entry = assetCacheRegistry[assetKey];
145
+ if ( entry ) {
146
+ if ( diff && typeof entry.diffExpires === 'number' ) {
147
+ return entry.diffExpires * MS_PER_DAY;
148
+ }
149
+ if ( typeof entry.expires === 'number' ) {
150
+ return entry.expires * MS_PER_DAY;
151
+ }
152
+ }
153
+ if ( assetSourceRegistry ) {
154
+ const entry = assetSourceRegistry[assetKey];
155
+ if ( entry && typeof entry.updateAfter === 'number' ) {
156
+ return entry.updateAfter * MS_PER_DAY;
157
+ }
158
+ }
159
+ return EXPIRES_DEFAULT * MS_PER_DAY; // default to 7-day
160
+ };
161
+
162
+ const getWriteTime = assetKey => {
163
+ const entry = assetCacheRegistry[assetKey];
164
+ if ( entry ) { return entry.writeTime || 0; }
165
+ return 0;
166
+ };
167
+
168
+ const isDiffUpdatableAsset = content => {
169
+ if ( typeof content !== 'string' ) { return false; }
170
+ const data = extractMetadataFromList(content, [
171
+ 'Diff-Path',
172
+ ]);
173
+ return typeof data.diffPath === 'string' &&
174
+ data.diffPath.startsWith('%') === false;
175
+ };
176
+
177
+ /******************************************************************************/
178
+
179
+ // favorLocal: avoid making network requests whenever possible
180
+ // favorOrigin: avoid using CDN URLs whenever possible
181
+
182
+ const getContentURLs = (assetKey, options = {}) => {
183
+ const contentURLs = [];
184
+ const entry = assetSourceRegistry[assetKey];
185
+ if ( entry instanceof Object === false ) { return contentURLs; }
186
+ if ( typeof entry.contentURL === 'string' ) {
187
+ contentURLs.push(entry.contentURL);
188
+ } else if ( Array.isArray(entry.contentURL) ) {
189
+ contentURLs.push(...entry.contentURL);
190
+ } else if ( reIsExternalPath.test(assetKey) ) {
191
+ contentURLs.push(assetKey);
192
+ }
193
+ if ( options.favorLocal ) {
194
+ contentURLs.sort((a, b) => {
195
+ if ( reIsExternalPath.test(a) ) { return 1; }
196
+ if ( reIsExternalPath.test(b) ) { return -1; }
197
+ return 0;
198
+ });
199
+ }
200
+ if ( Array.isArray(entry.cdnURLs) ) {
201
+ const cdnURLs = entry.cdnURLs.slice();
202
+ for ( let i = 0, n = cdnURLs.length; i < n; i++ ) {
203
+ const j = Math.floor(Math.random() * n);
204
+ if ( j === i ) { continue; }
205
+ [ cdnURLs[j], cdnURLs[i] ] = [ cdnURLs[i], cdnURLs[j] ];
206
+ }
207
+ if ( options.favorLocal || options.favorOrigin ) {
208
+ contentURLs.push(...cdnURLs);
209
+ } else {
210
+ contentURLs.unshift(...cdnURLs);
211
+ }
212
+ }
213
+ return contentURLs;
214
+ };
215
+
216
+ /******************************************************************************/
217
+
218
+ const observers = [];
219
+
220
+ assets.addObserver = function(observer) {
221
+ if ( observers.indexOf(observer) === -1 ) {
222
+ observers.push(observer);
223
+ }
224
+ };
225
+
226
+ assets.removeObserver = function(observer) {
227
+ let pos;
228
+ while ( (pos = observers.indexOf(observer)) !== -1 ) {
229
+ observers.splice(pos, 1);
230
+ }
231
+ };
232
+
233
+ const fireNotification = function(topic, details) {
234
+ let result;
235
+ for ( const observer of observers ) {
236
+ const r = observer(topic, details);
237
+ if ( r !== undefined ) { result = r; }
238
+ }
239
+ return result;
240
+ };
241
+
242
+ /******************************************************************************/
243
+
244
+ assets.fetch = function(url, options = {}) {
245
+ return new Promise((resolve, reject) => {
246
+ // Start of executor
247
+
248
+ const timeoutAfter = µb.hiddenSettings.assetFetchTimeout || 30;
249
+ const xhr = new XMLHttpRequest();
250
+ let contentLoaded = 0;
251
+
252
+ const cleanup = function() {
253
+ xhr.removeEventListener('load', onLoadEvent);
254
+ xhr.removeEventListener('error', onErrorEvent);
255
+ xhr.removeEventListener('abort', onErrorEvent);
256
+ xhr.removeEventListener('progress', onProgressEvent);
257
+ timeoutTimer.off();
258
+ };
259
+
260
+ const fail = function(details, msg) {
261
+ logger.writeOne({
262
+ realm: 'message',
263
+ type: 'error',
264
+ text: msg,
265
+ });
266
+ details.content = '';
267
+ details.error = msg;
268
+ reject(details);
269
+ };
270
+
271
+ // https://github.com/gorhill/uMatrix/issues/15
272
+ const onLoadEvent = function() {
273
+ cleanup();
274
+ // xhr for local files gives status 0, but actually succeeds
275
+ const details = {
276
+ url,
277
+ statusCode: this.status || 200,
278
+ statusText: this.statusText || ''
279
+ };
280
+ if ( details.statusCode < 200 || details.statusCode >= 300 ) {
281
+ return fail(details, `${url}: ${details.statusCode} ${details.statusText}`);
282
+ }
283
+ details.content = this.response;
284
+ details.resourceTime = resourceTimeFromXhr(this);
285
+ resolve(details);
286
+ };
287
+
288
+ const onErrorEvent = function() {
289
+ cleanup();
290
+ fail({ url }, errorCantConnectTo.replace('{{msg}}', url));
291
+ };
292
+
293
+ const onTimeout = function() {
294
+ xhr.abort();
295
+ };
296
+
297
+ // https://github.com/gorhill/uBlock/issues/2526
298
+ // - Timeout only when there is no progress.
299
+ const onProgressEvent = function(ev) {
300
+ if ( ev.loaded === contentLoaded ) { return; }
301
+ contentLoaded = ev.loaded;
302
+ timeoutTimer.offon({ sec: timeoutAfter });
303
+ };
304
+
305
+ const timeoutTimer = vAPI.defer.create(onTimeout);
306
+
307
+ // Be ready for thrown exceptions:
308
+ // I am pretty sure it used to work, but now using a URL such as
309
+ // `file:///` on Chromium 40 results in an exception being thrown.
310
+ try {
311
+ xhr.open('get', url, true);
312
+ xhr.addEventListener('load', onLoadEvent);
313
+ xhr.addEventListener('error', onErrorEvent);
314
+ xhr.addEventListener('abort', onErrorEvent);
315
+ xhr.addEventListener('progress', onProgressEvent);
316
+ xhr.responseType = options.responseType || 'text';
317
+ xhr.send();
318
+ timeoutTimer.on({ sec: timeoutAfter });
319
+ } catch (e) {
320
+ onErrorEvent.call(xhr);
321
+ }
322
+
323
+ // End of executor
324
+ });
325
+ };
326
+
327
+ /******************************************************************************/
328
+
329
+ assets.fetchText = async function(url) {
330
+ const isExternal = reIsExternalPath.test(url);
331
+ let actualUrl = isExternal ? url : vAPI.getURL(url);
332
+
333
+ // https://github.com/gorhill/uBlock/issues/2592
334
+ // Force browser cache to be bypassed, but only for resources which have
335
+ // been fetched more than one hour ago.
336
+ // https://github.com/uBlockOrigin/uBlock-issues/issues/682#issuecomment-515197130
337
+ // Provide filter list authors a way to completely bypass
338
+ // the browser cache.
339
+ // https://github.com/gorhill/uBlock/commit/048bfd251c9b#r37972005
340
+ // Use modulo prime numbers to avoid generating the same token at the
341
+ // same time across different days.
342
+ // Do not bypass browser cache if we are asked to be gentle on remote
343
+ // servers.
344
+ if ( isExternal && remoteServerFriendly !== true ) {
345
+ const cacheBypassToken =
346
+ µb.hiddenSettings.updateAssetBypassBrowserCache
347
+ ? Math.floor(Date.now() / 1000) % 86413
348
+ : Math.floor(Date.now() / 3600000) % 13;
349
+ const queryValue = `_=${cacheBypassToken}`;
350
+ if ( actualUrl.indexOf('?') === -1 ) {
351
+ actualUrl += '?';
352
+ } else {
353
+ actualUrl += '&';
354
+ }
355
+ actualUrl += queryValue;
356
+ }
357
+
358
+ let details = { content: '' };
359
+ try {
360
+ details = await assets.fetch(actualUrl);
361
+
362
+ // Consider an empty result to be an error
363
+ if ( stringIsNotEmpty(details.content) === false ) {
364
+ details.content = '';
365
+ }
366
+
367
+ // We never download anything else than plain text: discard if
368
+ // response appears to be a HTML document: could happen when server
369
+ // serves some kind of error page for example.
370
+ const text = details.content.trim();
371
+ if ( text.startsWith('<') && text.endsWith('>') ) {
372
+ details.content = '';
373
+ details.error = 'assets.fetchText(): Not a text file';
374
+ }
375
+ } catch(ex) {
376
+ details = ex;
377
+ }
378
+
379
+ // We want to return the caller's URL, not our internal one which may
380
+ // differ from the caller's one.
381
+ details.url = url;
382
+
383
+ return details;
384
+ };
385
+
386
+ /******************************************************************************/
387
+
388
+ // https://github.com/gorhill/uBlock/issues/3331
389
+ // Support the seamless loading of sublists.
390
+
391
+ assets.fetchFilterList = async function(mainlistURL) {
392
+ const toParsedURL = url => {
393
+ try {
394
+ return new URL(url.trim());
395
+ } catch (ex) {
396
+ }
397
+ };
398
+
399
+ // https://github.com/NanoAdblocker/NanoCore/issues/239
400
+ // Anything under URL's root directory is allowed to be fetched. The
401
+ // URL of a sublist will always be relative to the URL of the parent
402
+ // list (instead of the URL of the root list).
403
+ let rootDirectoryURL = toParsedURL(
404
+ reIsExternalPath.test(mainlistURL)
405
+ ? mainlistURL
406
+ : vAPI.getURL(mainlistURL)
407
+ );
408
+ if ( rootDirectoryURL !== undefined ) {
409
+ const pos = rootDirectoryURL.pathname.lastIndexOf('/');
410
+ if ( pos !== -1 ) {
411
+ rootDirectoryURL.pathname =
412
+ rootDirectoryURL.pathname.slice(0, pos + 1);
413
+ } else {
414
+ rootDirectoryURL = undefined;
415
+ }
416
+ }
417
+
418
+ const sublistURLs = new Set();
419
+
420
+ // https://github.com/uBlockOrigin/uBlock-issues/issues/1113
421
+ // Process only `!#include` directives which are not excluded by an
422
+ // `!#if` directive.
423
+ const processIncludeDirectives = function(results) {
424
+ const out = [];
425
+ const reInclude = /^!#include +(\S+)[^\n\r]*(?:[\n\r]+|$)/gm;
426
+ for ( const result of results ) {
427
+ if ( typeof result === 'string' ) {
428
+ out.push(result);
429
+ continue;
430
+ }
431
+ if ( result instanceof Object === false ) { continue; }
432
+ const content = result.content;
433
+ const slices = sfp.utils.preparser.splitter(
434
+ content,
435
+ vAPI.webextFlavor.env
436
+ );
437
+ for ( let i = 0, n = slices.length - 1; i < n; i++ ) {
438
+ const slice = content.slice(slices[i+0], slices[i+1]);
439
+ if ( (i & 1) !== 0 ) {
440
+ out.push(slice);
441
+ continue;
442
+ }
443
+ let lastIndex = 0;
444
+ for (;;) {
445
+ if ( rootDirectoryURL === undefined ) { break; }
446
+ const match = reInclude.exec(slice);
447
+ if ( match === null ) { break; }
448
+ if ( toParsedURL(match[1]) !== undefined ) { continue; }
449
+ if ( match[1].indexOf('..') !== -1 ) { continue; }
450
+ // Compute nested list path relative to parent list path
451
+ const pos = result.url.lastIndexOf('/');
452
+ if ( pos === -1 ) { continue; }
453
+ const subURL = result.url.slice(0, pos + 1) + match[1].trim();
454
+ if ( sublistURLs.has(subURL) ) { continue; }
455
+ sublistURLs.add(subURL);
456
+ out.push(
457
+ slice.slice(lastIndex, match.index + match[0].length),
458
+ `! >>>>>>>> ${subURL}\n`,
459
+ assets.fetchText(subURL),
460
+ `! <<<<<<<< ${subURL}\n`
461
+ );
462
+ lastIndex = reInclude.lastIndex;
463
+ }
464
+ out.push(lastIndex === 0 ? slice : slice.slice(lastIndex));
465
+ }
466
+ }
467
+ return out;
468
+ };
469
+
470
+ // https://github.com/AdguardTeam/FiltersRegistry/issues/82
471
+ // Not checking for `errored` status was causing repeated notifications
472
+ // to the caller. This can happen when more than one out of multiple
473
+ // sublists can't be fetched.
474
+
475
+ let allParts = [
476
+ this.fetchText(mainlistURL)
477
+ ];
478
+ // Abort processing `include` directives if at least one included sublist
479
+ // can't be fetched.
480
+ let resourceTime = 0;
481
+ do {
482
+ allParts = await Promise.all(allParts);
483
+ const part = allParts
484
+ .find(part => typeof part === 'object' && part.error !== undefined);
485
+ if ( part !== undefined ) {
486
+ return { url: mainlistURL, content: '', error: part.error };
487
+ }
488
+ resourceTime = resourceTimeFromParts(allParts, resourceTime);
489
+ // Skip pre-parser directives for diff-updatable assets
490
+ if ( allParts.length === 1 && allParts[0] instanceof Object ) {
491
+ if ( isDiffUpdatableAsset(allParts[0].content) ) {
492
+ allParts[0] = allParts[0].content;
493
+ break;
494
+ }
495
+ }
496
+ allParts = processIncludeDirectives(allParts);
497
+ } while ( allParts.some(part => typeof part !== 'string') );
498
+ // If we reach this point, this means all fetches were successful.
499
+ return {
500
+ url: mainlistURL,
501
+ resourceTime,
502
+ content: allParts.length === 1
503
+ ? allParts[0]
504
+ : allParts.join('') + '\n'
505
+ };
506
+ };
507
+
508
+ /*******************************************************************************
509
+
510
+ The purpose of the asset source registry is to keep key detail information
511
+ about an asset:
512
+ - Where to load it from: this may consist of one or more URLs, either local
513
+ or remote.
514
+ - After how many days an asset should be deemed obsolete -- i.e. in need of
515
+ an update.
516
+ - The origin and type of an asset.
517
+ - The last time an asset was registered.
518
+
519
+ **/
520
+
521
+ let assetSourceRegistryPromise;
522
+ let assetSourceRegistry = Object.create(null);
523
+
524
+ function getAssetSourceRegistry() {
525
+ if ( assetSourceRegistryPromise === undefined ) {
526
+ assetSourceRegistryPromise = cacheStorage.get(
527
+ 'assetSourceRegistry'
528
+ ).then(bin => {
529
+ if (
530
+ bin instanceof Object &&
531
+ bin.assetSourceRegistry instanceof Object
532
+ ) {
533
+ assetSourceRegistry = bin.assetSourceRegistry;
534
+ return assetSourceRegistry;
535
+ }
536
+ return assets.fetchText(
537
+ µb.assetsBootstrapLocation || µb.assetsJsonPath
538
+ ).then(details => {
539
+ return details.content !== ''
540
+ ? details
541
+ : assets.fetchText(µb.assetsJsonPath);
542
+ }).then(details => {
543
+ updateAssetSourceRegistry(details.content, true);
544
+ return assetSourceRegistry;
545
+ });
546
+ });
547
+ }
548
+
549
+ return assetSourceRegistryPromise;
550
+ }
551
+
552
+ function registerAssetSource(assetKey, newDict) {
553
+ const currentDict = assetSourceRegistry[assetKey] || {};
554
+ for ( const [ k, v ] of Object.entries(newDict) ) {
555
+ if ( v === undefined || v === null ) {
556
+ delete currentDict[k];
557
+ } else {
558
+ currentDict[k] = newDict[k];
559
+ }
560
+ }
561
+ let contentURL = newDict.contentURL;
562
+ if ( contentURL !== undefined ) {
563
+ if ( typeof contentURL === 'string' ) {
564
+ contentURL = currentDict.contentURL = [ contentURL ];
565
+ } else if ( Array.isArray(contentURL) === false ) {
566
+ contentURL = currentDict.contentURL = [];
567
+ }
568
+ let remoteURLCount = 0;
569
+ for ( let i = 0; i < contentURL.length; i++ ) {
570
+ if ( reIsExternalPath.test(contentURL[i]) ) {
571
+ remoteURLCount += 1;
572
+ }
573
+ }
574
+ currentDict.hasLocalURL = remoteURLCount !== contentURL.length;
575
+ currentDict.hasRemoteURL = remoteURLCount !== 0;
576
+ } else if ( currentDict.contentURL === undefined ) {
577
+ currentDict.contentURL = [];
578
+ }
579
+ if ( currentDict.submitter ) {
580
+ currentDict.submitTime = Date.now(); // To detect stale entries
581
+ }
582
+ assetSourceRegistry[assetKey] = currentDict;
583
+ }
584
+
585
+ function unregisterAssetSource(assetKey) {
586
+ assetCacheRemove(assetKey);
587
+ delete assetSourceRegistry[assetKey];
588
+ }
589
+
590
+ const saveAssetSourceRegistry = (( ) => {
591
+ const save = ( ) => {
592
+ timer.off();
593
+ cacheStorage.set({ assetSourceRegistry });
594
+ };
595
+ const timer = vAPI.defer.create(save);
596
+ return function(lazily) {
597
+ if ( lazily ) {
598
+ timer.offon(500);
599
+ } else {
600
+ save();
601
+ }
602
+ };
603
+ })();
604
+
605
+ async function assetSourceGetDetails(assetKey) {
606
+ await getAssetSourceRegistry();
607
+ const entry = assetSourceRegistry[assetKey];
608
+ if ( entry === undefined ) { return; }
609
+ return entry;
610
+ }
611
+
612
+ function updateAssetSourceRegistry(json, silent = false) {
613
+ let newDict;
614
+ try {
615
+ newDict = JSON.parse(json);
616
+ newDict['assets.json'].defaultListset =
617
+ Array.from(Object.entries(newDict))
618
+ .filter(a => a[1].content === 'filters' && a[1].off === undefined)
619
+ .map(a => a[0]);
620
+ } catch (ex) {
621
+ }
622
+ if ( newDict instanceof Object === false ) { return; }
623
+
624
+ const oldDict = assetSourceRegistry;
625
+
626
+ fireNotification('assets.json-updated', { newDict, oldDict });
627
+
628
+ // Remove obsolete entries (only those which were built-in).
629
+ for ( const assetKey in oldDict ) {
630
+ if (
631
+ newDict[assetKey] === undefined &&
632
+ oldDict[assetKey].submitter === undefined
633
+ ) {
634
+ unregisterAssetSource(assetKey);
635
+ }
636
+ }
637
+ // Add/update existing entries. Notify of new asset sources.
638
+ for ( const assetKey in newDict ) {
639
+ if ( oldDict[assetKey] === undefined && !silent ) {
640
+ fireNotification(
641
+ 'builtin-asset-source-added',
642
+ { assetKey: assetKey, entry: newDict[assetKey] }
643
+ );
644
+ }
645
+ registerAssetSource(assetKey, newDict[assetKey]);
646
+ }
647
+ saveAssetSourceRegistry();
648
+ }
649
+
650
+ assets.registerAssetSource = async function(assetKey, details) {
651
+ await getAssetSourceRegistry();
652
+ registerAssetSource(assetKey, details);
653
+ saveAssetSourceRegistry(true);
654
+ };
655
+
656
+ assets.unregisterAssetSource = async function(assetKey) {
657
+ await getAssetSourceRegistry();
658
+ unregisterAssetSource(assetKey);
659
+ saveAssetSourceRegistry(true);
660
+ };
661
+
662
+ /*******************************************************************************
663
+
664
+ The purpose of the asset cache registry is to keep track of all assets
665
+ which have been persisted into the local cache.
666
+
667
+ **/
668
+
669
+ const assetCacheRegistryStartTime = Date.now();
670
+ let assetCacheRegistryPromise;
671
+ let assetCacheRegistry = {};
672
+
673
+ function getAssetCacheRegistry() {
674
+ if ( assetCacheRegistryPromise === undefined ) {
675
+ assetCacheRegistryPromise = cacheStorage.get(
676
+ 'assetCacheRegistry'
677
+ ).then(bin => {
678
+ if (
679
+ bin instanceof Object &&
680
+ bin.assetCacheRegistry instanceof Object
681
+ ) {
682
+ if ( Object.keys(assetCacheRegistry).length === 0 ) {
683
+ assetCacheRegistry = bin.assetCacheRegistry;
684
+ } else {
685
+ console.error(
686
+ 'getAssetCacheRegistry(): assetCacheRegistry reassigned!'
687
+ );
688
+ if (
689
+ Object.keys(bin.assetCacheRegistry).sort().join() !==
690
+ Object.keys(assetCacheRegistry).sort().join()
691
+ ) {
692
+ console.error(
693
+ 'getAssetCacheRegistry(): assetCacheRegistry changes overwritten!'
694
+ );
695
+ }
696
+ }
697
+ }
698
+ return assetCacheRegistry;
699
+ });
700
+ }
701
+
702
+ return assetCacheRegistryPromise;
703
+ }
704
+
705
+ const saveAssetCacheRegistry = (( ) => {
706
+ const save = function() {
707
+ timer.off();
708
+ cacheStorage.set({ assetCacheRegistry });
709
+ };
710
+ const timer = vAPI.defer.create(save);
711
+ return function(lazily) {
712
+ if ( lazily ) {
713
+ timer.offon({ sec: 30 });
714
+ } else {
715
+ save();
716
+ }
717
+ };
718
+ })();
719
+
720
+ async function assetCacheRead(assetKey, updateReadTime = false) {
721
+ const t0 = Date.now();
722
+ const internalKey = `cache/${assetKey}`;
723
+
724
+ const reportBack = function(content) {
725
+ if ( content instanceof Blob ) { content = ''; }
726
+ const details = { assetKey, content };
727
+ if ( content === '' ) { details.error = 'ENOTFOUND'; }
728
+ return details;
729
+ };
730
+
731
+ const [ , bin ] = await Promise.all([
732
+ getAssetCacheRegistry(),
733
+ cacheStorage.get(internalKey),
734
+ ]);
735
+
736
+ if ( µb.readyToFilter !== true ) {
737
+ µb.supportStats.maxAssetCacheWait = Math.max(
738
+ Date.now() - t0,
739
+ parseInt(µb.supportStats.maxAssetCacheWait, 10) || 0
740
+ ) + ' ms';
741
+ }
742
+
743
+ if (
744
+ bin instanceof Object === false ||
745
+ bin.hasOwnProperty(internalKey) === false
746
+ ) {
747
+ return reportBack('');
748
+ }
749
+
750
+ const entry = assetCacheRegistry[assetKey];
751
+ if ( entry === undefined ) {
752
+ return reportBack('');
753
+ }
754
+
755
+ entry.readTime = Date.now();
756
+ if ( updateReadTime ) {
757
+ saveAssetCacheRegistry(true);
758
+ }
759
+
760
+ return reportBack(bin[internalKey]);
761
+ }
762
+
763
+ async function assetCacheWrite(assetKey, details) {
764
+ let content = '';
765
+ let options = {};
766
+ if ( typeof details === 'string' ) {
767
+ content = details;
768
+ } else if ( details instanceof Object ) {
769
+ content = details.content || '';
770
+ options = details;
771
+ }
772
+
773
+ if ( content === '' ) {
774
+ return assetCacheRemove(assetKey);
775
+ }
776
+
777
+ const cacheDict = await getAssetCacheRegistry();
778
+
779
+ let entry = cacheDict[assetKey];
780
+ if ( entry === undefined ) {
781
+ entry = cacheDict[assetKey] = {};
782
+ }
783
+ entry.writeTime = entry.readTime = Date.now();
784
+ entry.resourceTime = options.resourceTime || 0;
785
+ if ( typeof options.url === 'string' ) {
786
+ entry.remoteURL = options.url;
787
+ }
788
+ cacheStorage.set({
789
+ assetCacheRegistry,
790
+ [`cache/${assetKey}`]: content
791
+ });
792
+
793
+ const result = { assetKey, content };
794
+ // https://github.com/uBlockOrigin/uBlock-issues/issues/248
795
+ if ( options.silent !== true ) {
796
+ fireNotification('after-asset-updated', result);
797
+ }
798
+ return result;
799
+ }
800
+
801
+ async function assetCacheRemove(pattern) {
802
+ const cacheDict = await getAssetCacheRegistry();
803
+ const removedEntries = [];
804
+ const removedContent = [];
805
+ for ( const assetKey in cacheDict ) {
806
+ if ( pattern instanceof RegExp && !pattern.test(assetKey) ) {
807
+ continue;
808
+ }
809
+ if ( typeof pattern === 'string' && assetKey !== pattern ) {
810
+ continue;
811
+ }
812
+ removedEntries.push(assetKey);
813
+ removedContent.push('cache/' + assetKey);
814
+ delete cacheDict[assetKey];
815
+ }
816
+ if ( removedContent.length !== 0 ) {
817
+ await Promise.all([
818
+ cacheStorage.remove(removedContent),
819
+ cacheStorage.set({ assetCacheRegistry }),
820
+ ]);
821
+ }
822
+ for ( let i = 0; i < removedEntries.length; i++ ) {
823
+ fireNotification('after-asset-updated', {
824
+ assetKey: removedEntries[i]
825
+ });
826
+ }
827
+ }
828
+
829
+ async function assetCacheGetDetails(assetKey) {
830
+ const cacheDict = await getAssetCacheRegistry();
831
+ const entry = cacheDict[assetKey];
832
+ if ( entry === undefined ) { return; }
833
+ return entry;
834
+ }
835
+
836
+ async function assetCacheSetDetails(assetKey, details) {
837
+ const cacheDict = await getAssetCacheRegistry();
838
+ const entry = cacheDict[assetKey];
839
+ if ( entry === undefined ) { return; }
840
+ let modified = false;
841
+ for ( const [ k, v ] of Object.entries(details) ) {
842
+ if ( v === undefined ) {
843
+ if ( entry[k] !== undefined ) {
844
+ delete entry[k];
845
+ modified = true;
846
+ continue;
847
+ }
848
+ }
849
+ if ( v !== entry[k] ) {
850
+ entry[k] = v;
851
+ modified = true;
852
+ }
853
+ }
854
+ if ( modified ) {
855
+ saveAssetCacheRegistry();
856
+ }
857
+ }
858
+
859
+ async function assetCacheMarkAsDirty(pattern, exclude) {
860
+ const cacheDict = await getAssetCacheRegistry();
861
+ let mustSave = false;
862
+ for ( const assetKey in cacheDict ) {
863
+ if ( pattern instanceof RegExp ) {
864
+ if ( pattern.test(assetKey) === false ) { continue; }
865
+ } else if ( typeof pattern === 'string' ) {
866
+ if ( assetKey !== pattern ) { continue; }
867
+ } else if ( Array.isArray(pattern) ) {
868
+ if ( pattern.indexOf(assetKey) === -1 ) { continue; }
869
+ }
870
+ if ( exclude instanceof RegExp ) {
871
+ if ( exclude.test(assetKey) ) { continue; }
872
+ } else if ( typeof exclude === 'string' ) {
873
+ if ( assetKey === exclude ) { continue; }
874
+ } else if ( Array.isArray(exclude) ) {
875
+ if ( exclude.indexOf(assetKey) !== -1 ) { continue; }
876
+ }
877
+ const cacheEntry = cacheDict[assetKey];
878
+ if ( !cacheEntry.writeTime ) { continue; }
879
+ cacheDict[assetKey].writeTime = 0;
880
+ mustSave = true;
881
+ }
882
+ if ( mustSave ) {
883
+ cacheStorage.set({ assetCacheRegistry });
884
+ }
885
+ }
886
+
887
+ /*******************************************************************************
888
+
889
+ User assets are NOT persisted in the cache storage. User assets are
890
+ recognized by the asset key which always starts with 'user-'.
891
+
892
+ TODO(seamless migration):
893
+ Can remove instances of old user asset keys when I am confident all users
894
+ are using uBO v1.11 and beyond.
895
+
896
+ **/
897
+
898
+ /*******************************************************************************
899
+
900
+ User assets are NOT persisted in the cache storage. User assets are
901
+ recognized by the asset key which always starts with 'user-'.
902
+
903
+ **/
904
+
905
+ const readUserAsset = async function(assetKey) {
906
+ const bin = await vAPI.storage.get(assetKey);
907
+ const content =
908
+ bin instanceof Object && typeof bin[assetKey] === 'string'
909
+ ? bin[assetKey]
910
+ : '';
911
+ return { assetKey, content };
912
+ };
913
+
914
+ const saveUserAsset = function(assetKey, content) {
915
+ return vAPI.storage.set({ [assetKey]: content }).then(( ) => {
916
+ return { assetKey, content };
917
+ });
918
+ };
919
+
920
+ /******************************************************************************/
921
+
922
+ assets.get = async function(assetKey, options = {}) {
923
+ if ( assetKey === µb.userFiltersPath ) {
924
+ return readUserAsset(assetKey);
925
+ }
926
+
927
+ let assetDetails = {};
928
+
929
+ const reportBack = (content, url = '', err = undefined) => {
930
+ const details = { assetKey, content };
931
+ if ( err !== undefined ) {
932
+ details.error = assetDetails.lastError = err;
933
+ } else {
934
+ assetDetails.lastError = undefined;
935
+ }
936
+ if ( options.needSourceURL ) {
937
+ if (
938
+ url === '' &&
939
+ assetCacheRegistry instanceof Object &&
940
+ assetCacheRegistry[assetKey] instanceof Object
941
+ ) {
942
+ details.sourceURL = assetCacheRegistry[assetKey].remoteURL;
943
+ }
944
+ if ( reIsExternalPath.test(url) ) {
945
+ details.sourceURL = url;
946
+ }
947
+ }
948
+ return details;
949
+ };
950
+
951
+ // Skip read-time property for non-updatable assets: the property is
952
+ // completely unused for such assets and thus there is no point incurring
953
+ // storage write overhead at launch when reading compiled or selfie assets.
954
+ const updateReadTime = /^(?:compiled|selfie)\//.test(assetKey) === false;
955
+
956
+ const details = await assetCacheRead(assetKey, updateReadTime);
957
+ if ( details.content !== '' ) {
958
+ return reportBack(details.content);
959
+ }
960
+
961
+ const assetRegistry = await getAssetSourceRegistry();
962
+
963
+ assetDetails = assetRegistry[assetKey] || {};
964
+
965
+ const contentURLs = getContentURLs(assetKey, options);
966
+ if ( contentURLs.length === 0 && reIsExternalPath.test(assetKey) ) {
967
+ assetDetails.content = 'filters';
968
+ contentURLs.push(assetKey);
969
+ }
970
+
971
+ let error = 'ENOTFOUND';
972
+ for ( const contentURL of contentURLs ) {
973
+ const details = assetDetails.content === 'filters'
974
+ ? await assets.fetchFilterList(contentURL)
975
+ : await assets.fetchText(contentURL);
976
+ if ( details.error !== undefined ) {
977
+ error = details.error;
978
+ }
979
+ if ( details.content === '' ) { continue; }
980
+ if ( reIsExternalPath.test(contentURL) && options.dontCache !== true ) {
981
+ assetCacheWrite(assetKey, {
982
+ content: details.content,
983
+ url: contentURL,
984
+ silent: options.silent === true,
985
+ });
986
+ registerAssetSource(assetKey, { error: undefined });
987
+ }
988
+ return reportBack(details.content, contentURL);
989
+ }
990
+ if ( assetRegistry[assetKey] !== undefined ) {
991
+ registerAssetSource(assetKey, {
992
+ error: { time: Date.now(), error }
993
+ });
994
+ }
995
+ return reportBack('', '', error);
996
+ };
997
+
998
+ /******************************************************************************/
999
+
1000
+ async function getRemote(assetKey, options = {}) {
1001
+ const [
1002
+ assetDetails = {},
1003
+ cacheDetails = {},
1004
+ ] = await Promise.all([
1005
+ assetSourceGetDetails(assetKey),
1006
+ assetCacheGetDetails(assetKey),
1007
+ ]);
1008
+
1009
+ let error;
1010
+ let stale = false;
1011
+
1012
+ const reportBack = function(content, url = '', err = '') {
1013
+ const details = { assetKey, content, url };
1014
+ if ( err !== '') {
1015
+ details.error = assetDetails.lastError = err;
1016
+ } else {
1017
+ assetDetails.lastError = undefined;
1018
+ }
1019
+ return details;
1020
+ };
1021
+
1022
+ for ( const contentURL of getContentURLs(assetKey, options) ) {
1023
+ if ( reIsExternalPath.test(contentURL) === false ) { continue; }
1024
+
1025
+ const result = assetDetails.content === 'filters'
1026
+ ? await assets.fetchFilterList(contentURL)
1027
+ : await assets.fetchText(contentURL);
1028
+
1029
+ // Failure
1030
+ if ( stringIsNotEmpty(result.content) === false ) {
1031
+ error = result.statusText;
1032
+ if ( result.statusCode === 0 ) {
1033
+ error = 'network error';
1034
+ }
1035
+ continue;
1036
+ }
1037
+
1038
+ error = undefined;
1039
+
1040
+ // If fetched resource is older than cached one, ignore
1041
+ stale = resourceIsStale(result, cacheDetails);
1042
+ if ( stale ) { continue; }
1043
+
1044
+ // Success
1045
+ assetCacheWrite(assetKey, {
1046
+ content: result.content,
1047
+ url: contentURL,
1048
+ resourceTime: result.resourceTime || 0,
1049
+ });
1050
+
1051
+ if ( assetDetails.content === 'filters' ) {
1052
+ const metadata = extractMetadataFromList(result.content, [
1053
+ 'Last-Modified',
1054
+ 'Expires',
1055
+ 'Diff-Name',
1056
+ 'Diff-Path',
1057
+ 'Diff-Expires',
1058
+ ]);
1059
+ assetCacheSetDetails(assetKey, metadata);
1060
+ }
1061
+
1062
+ registerAssetSource(assetKey, { birthtime: undefined, error: undefined });
1063
+ return reportBack(result.content, contentURL);
1064
+ }
1065
+
1066
+ if ( error !== undefined ) {
1067
+ registerAssetSource(assetKey, { error: { time: Date.now(), error } });
1068
+ return reportBack('', '', 'ENOTFOUND');
1069
+ }
1070
+
1071
+ if ( stale ) {
1072
+ assetCacheSetDetails(assetKey, { writeTime: cacheDetails.resourceTime });
1073
+ }
1074
+
1075
+ return reportBack('');
1076
+ }
1077
+
1078
+ /******************************************************************************/
1079
+
1080
+ assets.put = async function(assetKey, content) {
1081
+ return reIsUserAsset.test(assetKey)
1082
+ ? await saveUserAsset(assetKey, content)
1083
+ : await assetCacheWrite(assetKey, content);
1084
+ };
1085
+
1086
+ /******************************************************************************/
1087
+
1088
+ assets.metadata = async function() {
1089
+ await Promise.all([
1090
+ getAssetSourceRegistry(),
1091
+ getAssetCacheRegistry(),
1092
+ ]);
1093
+
1094
+ const assetDict = JSON.parse(JSON.stringify(assetSourceRegistry));
1095
+ const cacheDict = assetCacheRegistry;
1096
+ const now = Date.now();
1097
+ for ( const assetKey in assetDict ) {
1098
+ const assetEntry = assetDict[assetKey];
1099
+ const cacheEntry = cacheDict[assetKey];
1100
+ if (
1101
+ assetEntry.content === 'filters' &&
1102
+ assetEntry.external !== true
1103
+ ) {
1104
+ assetEntry.isDefault =
1105
+ assetEntry.off === undefined ||
1106
+ assetEntry.off === true &&
1107
+ µb.listMatchesEnvironment(assetEntry);
1108
+ }
1109
+ if ( cacheEntry ) {
1110
+ assetEntry.cached = true;
1111
+ assetEntry.writeTime = cacheEntry.writeTime;
1112
+ const obsoleteAfter = cacheEntry.writeTime + getUpdateAfterTime(assetKey);
1113
+ assetEntry.obsolete = obsoleteAfter < now;
1114
+ assetEntry.remoteURL = cacheEntry.remoteURL;
1115
+ } else if (
1116
+ assetEntry.contentURL &&
1117
+ assetEntry.contentURL.length !== 0
1118
+ ) {
1119
+ assetEntry.writeTime = 0;
1120
+ assetEntry.obsolete = true;
1121
+ }
1122
+ }
1123
+
1124
+ return assetDict;
1125
+ };
1126
+
1127
+ /******************************************************************************/
1128
+
1129
+ assets.purge = assetCacheMarkAsDirty;
1130
+
1131
+ assets.remove = function(pattern) {
1132
+ return assetCacheRemove(pattern);
1133
+ };
1134
+
1135
+ assets.rmrf = function() {
1136
+ return assetCacheRemove(/./);
1137
+ };
1138
+
1139
+ /******************************************************************************/
1140
+
1141
+ assets.getUpdateAges = async function(conditions = {}) {
1142
+ const assetDict = await assets.metadata();
1143
+ const now = Date.now();
1144
+ const out = [];
1145
+ for ( const [ assetKey, asset ] of Object.entries(assetDict) ) {
1146
+ if ( asset.hasRemoteURL !== true ) { continue; }
1147
+ const tokens = conditions[asset.content];
1148
+ if ( Array.isArray(tokens) === false ) { continue; }
1149
+ if ( tokens.includes('*') === false ) {
1150
+ if ( tokens.includes(assetKey) === false ) { continue; }
1151
+ }
1152
+ const age = now - (asset.writeTime || 0);
1153
+ out.push({
1154
+ assetKey,
1155
+ age,
1156
+ ageNormalized: age / getUpdateAfterTime(assetKey),
1157
+ });
1158
+ }
1159
+ return out;
1160
+ };
1161
+
1162
+ /******************************************************************************/
1163
+
1164
+ // Asset updater area.
1165
+ const updaterAssetDelayDefault = 120000;
1166
+ const updaterUpdated = [];
1167
+ const updaterFetched = new Set();
1168
+
1169
+ let updaterStatus;
1170
+ let updaterAssetDelay = updaterAssetDelayDefault;
1171
+ let updaterAuto = false;
1172
+
1173
+ const getAssetDiffDetails = assetKey => {
1174
+ const out = { assetKey };
1175
+ const cacheEntry = assetCacheRegistry[assetKey];
1176
+ if ( cacheEntry === undefined ) { return; }
1177
+ out.patchPath = cacheEntry.diffPath;
1178
+ if ( out.patchPath === undefined ) { return; }
1179
+ const match = /#.+$/.exec(out.patchPath);
1180
+ if ( match !== null ) {
1181
+ out.diffName = match[0].slice(1);
1182
+ } else {
1183
+ out.diffName = cacheEntry.diffName;
1184
+ }
1185
+ if ( out.diffName === undefined ) { return; }
1186
+ out.diffExpires = getUpdateAfterTime(assetKey, true);
1187
+ out.lastModified = cacheEntry.lastModified;
1188
+ out.writeTime = cacheEntry.writeTime;
1189
+ const assetEntry = assetSourceRegistry[assetKey];
1190
+ if ( assetEntry === undefined ) { return; }
1191
+ if ( Array.isArray(assetEntry.cdnURLs) === false ) { return; }
1192
+ out.cdnURLs = assetEntry.cdnURLs.slice();
1193
+ return out;
1194
+ };
1195
+
1196
+ async function diffUpdater() {
1197
+ if ( updaterAuto === false ) { return; }
1198
+ if ( µb.hiddenSettings.differentialUpdate === false ) { return; }
1199
+ const toUpdate = await getUpdateCandidates();
1200
+ const now = Date.now();
1201
+ const toHardUpdate = [];
1202
+ const toSoftUpdate = [];
1203
+ while ( toUpdate.length !== 0 ) {
1204
+ const assetKey = toUpdate.shift();
1205
+ const assetDetails = getAssetDiffDetails(assetKey);
1206
+ if ( assetDetails === undefined ) { continue; }
1207
+ assetDetails.what = 'update';
1208
+ if ( (getWriteTime(assetKey) + assetDetails.diffExpires) > now ) {
1209
+ assetDetails.fetch = false;
1210
+ toSoftUpdate.push(assetDetails);
1211
+ } else {
1212
+ assetDetails.fetch = true;
1213
+ toHardUpdate.push(assetDetails);
1214
+ }
1215
+ }
1216
+ if ( toHardUpdate.length === 0 ) { return; }
1217
+ ubolog('Diff updater: cycle start');
1218
+ return new Promise(resolve => {
1219
+ let pendingOps = 0;
1220
+ const bc = new globalThis.BroadcastChannel('diffUpdater');
1221
+ const terminate = error => {
1222
+ worker.terminate();
1223
+ bc.close();
1224
+ resolve();
1225
+ if ( typeof error !== 'string' ) { return; }
1226
+ ubolog(`Diff updater: terminate because ${error}`);
1227
+ };
1228
+ const checkAndCorrectDiffPath = data => {
1229
+ if ( typeof data.text !== 'string' ) { return; }
1230
+ if ( data.text === '' ) { return; }
1231
+ const metadata = extractMetadataFromList(data.text, [ 'Diff-Path' ]);
1232
+ if ( metadata instanceof Object === false ) { return; }
1233
+ if ( metadata.diffPath === data.patchPath ) { return; }
1234
+ assetCacheSetDetails(data.assetKey, metadata);
1235
+ };
1236
+ bc.onmessage = ev => {
1237
+ const data = ev.data;
1238
+ if ( data.what === 'ready' ) {
1239
+ ubolog('Diff updater: hard updating', toHardUpdate.map(v => v.assetKey).join());
1240
+ while ( toHardUpdate.length !== 0 ) {
1241
+ const assetDetails = toHardUpdate.shift();
1242
+ assetDetails.fetch = true;
1243
+ bc.postMessage(assetDetails);
1244
+ pendingOps += 1;
1245
+ }
1246
+ return;
1247
+ }
1248
+ if ( data.what === 'broken' ) {
1249
+ terminate(data.error);
1250
+ return;
1251
+ }
1252
+ if ( data.status === 'needtext' ) {
1253
+ ubolog('Diff updater: need text for', data.assetKey);
1254
+ assetCacheRead(data.assetKey).then(result => {
1255
+ data.text = result.content;
1256
+ data.status = undefined;
1257
+ checkAndCorrectDiffPath(data);
1258
+ bc.postMessage(data);
1259
+ });
1260
+ return;
1261
+ }
1262
+ if ( data.status === 'updated' ) {
1263
+ ubolog(`Diff updater: successfully patched ${data.assetKey} using ${data.patchURL} (${data.patchSize})`);
1264
+ const metadata = extractMetadataFromList(data.text, [
1265
+ 'Last-Modified',
1266
+ 'Expires',
1267
+ 'Diff-Name',
1268
+ 'Diff-Path',
1269
+ 'Diff-Expires',
1270
+ ]);
1271
+ assetCacheWrite(data.assetKey, {
1272
+ content: data.text,
1273
+ resourceTime: metadata.lastModified || 0,
1274
+ });
1275
+ assetCacheSetDetails(data.assetKey, metadata);
1276
+ updaterUpdated.push(data.assetKey);
1277
+ } else if ( data.error ) {
1278
+ ubolog(`Diff updater: failed to update ${data.assetKey} using ${data.patchPath}\n\treason: ${data.error}`);
1279
+ } else if ( data.status === 'nopatch-yet' || data.status === 'nodiff' ) {
1280
+ ubolog(`Diff updater: skip update of ${data.assetKey} using ${data.patchPath}\n\treason: ${data.status}`);
1281
+ assetCacheSetDetails(data.assetKey, { writeTime: data.writeTime });
1282
+ vAPI.messaging.broadcast({
1283
+ what: 'assetUpdated',
1284
+ key: data.assetKey,
1285
+ cached: true,
1286
+ });
1287
+ } else {
1288
+ ubolog(`Diff updater: ${data.assetKey} / ${data.patchPath} / ${data.status}`);
1289
+ }
1290
+ pendingOps -= 1;
1291
+ if ( pendingOps === 0 && toSoftUpdate.length !== 0 ) {
1292
+ ubolog('Diff updater: soft updating', toSoftUpdate.map(v => v.assetKey).join());
1293
+ while ( toSoftUpdate.length !== 0 ) {
1294
+ bc.postMessage(toSoftUpdate.shift());
1295
+ pendingOps += 1;
1296
+ }
1297
+ }
1298
+ if ( pendingOps !== 0 ) { return; }
1299
+ ubolog('Diff updater: cycle complete');
1300
+ terminate();
1301
+ };
1302
+ const worker = new Worker('js/diff-updater.js');
1303
+ });
1304
+ }
1305
+
1306
+ function updateFirst() {
1307
+ ubolog('Updater: cycle start');
1308
+ ubolog('Updater: prefer', updaterAuto ? 'CDNs' : 'origin');
1309
+ updaterStatus = 'updating';
1310
+ updaterFetched.clear();
1311
+ updaterUpdated.length = 0;
1312
+ diffUpdater().catch(reason => {
1313
+ ubolog(reason);
1314
+ }).finally(( ) => {
1315
+ updateNext();
1316
+ });
1317
+ }
1318
+
1319
+ async function getUpdateCandidates() {
1320
+ const [ assetDict, cacheDict ] = await Promise.all([
1321
+ getAssetSourceRegistry(),
1322
+ getAssetCacheRegistry(),
1323
+ ]);
1324
+ const toUpdate = [];
1325
+ for ( const assetKey in assetDict ) {
1326
+ const assetEntry = assetDict[assetKey];
1327
+ if ( assetEntry.hasRemoteURL !== true ) { continue; }
1328
+ if ( updaterFetched.has(assetKey) ) { continue; }
1329
+ const cacheEntry = cacheDict[assetKey];
1330
+ if (
1331
+ fireNotification('before-asset-updated', {
1332
+ assetKey,
1333
+ type: assetEntry.content
1334
+ }) === true
1335
+ ) {
1336
+ toUpdate.push(assetKey);
1337
+ continue;
1338
+ }
1339
+ // This will remove a cached asset when it's no longer in use.
1340
+ if ( cacheEntry && cacheEntry.readTime < assetCacheRegistryStartTime ) {
1341
+ assetCacheRemove(assetKey);
1342
+ }
1343
+ }
1344
+ // https://github.com/uBlockOrigin/uBlock-issues/issues/1165
1345
+ // Update most obsolete asset first.
1346
+ toUpdate.sort((a, b) => {
1347
+ const ta = cacheDict[a] !== undefined ? cacheDict[a].writeTime : 0;
1348
+ const tb = cacheDict[b] !== undefined ? cacheDict[b].writeTime : 0;
1349
+ return ta - tb;
1350
+ });
1351
+ return toUpdate;
1352
+ }
1353
+
1354
+ async function updateNext() {
1355
+ const toUpdate = await getUpdateCandidates();
1356
+ const now = Date.now();
1357
+ const toHardUpdate = [];
1358
+
1359
+ while ( toUpdate.length !== 0 ) {
1360
+ const assetKey = toUpdate.shift();
1361
+ const writeTime = getWriteTime(assetKey);
1362
+ const updateDelay = getUpdateAfterTime(assetKey);
1363
+ if ( (writeTime + updateDelay) > now ) { continue; }
1364
+ toHardUpdate.push(assetKey);
1365
+ }
1366
+ if ( toHardUpdate.length === 0 ) {
1367
+ return updateDone();
1368
+ }
1369
+
1370
+ const assetKey = toHardUpdate.pop();
1371
+ updaterFetched.add(assetKey);
1372
+
1373
+ // In auto-update context, be gentle on remote servers.
1374
+ remoteServerFriendly = updaterAuto;
1375
+
1376
+ let result;
1377
+ if ( assetKey !== 'assets.json' || µb.hiddenSettings.debugAssetsJson !== true ) {
1378
+ result = await getRemote(assetKey, { favorOrigin: updaterAuto === false });
1379
+ } else {
1380
+ result = await assets.fetchText(µb.assetsJsonPath);
1381
+ result.assetKey = 'assets.json';
1382
+ }
1383
+
1384
+ remoteServerFriendly = false;
1385
+
1386
+ if ( result.error ) {
1387
+ ubolog(`Full updater: failed to update ${assetKey}`);
1388
+ fireNotification('asset-update-failed', { assetKey: result.assetKey });
1389
+ } else {
1390
+ ubolog(`Full updater: successfully updated ${assetKey}`);
1391
+ updaterUpdated.push(result.assetKey);
1392
+ if ( result.assetKey === 'assets.json' && result.content !== '' ) {
1393
+ updateAssetSourceRegistry(result.content);
1394
+ }
1395
+ }
1396
+
1397
+ updaterTimer.on(updaterAssetDelay);
1398
+ }
1399
+
1400
+ const updaterTimer = vAPI.defer.create(updateNext);
1401
+
1402
+ function updateDone() {
1403
+ const assetKeys = updaterUpdated.slice(0);
1404
+ updaterFetched.clear();
1405
+ updaterUpdated.length = 0;
1406
+ updaterStatus = undefined;
1407
+ updaterAuto = false;
1408
+ updaterAssetDelay = updaterAssetDelayDefault;
1409
+ ubolog('Updater: cycle end');
1410
+ if ( assetKeys.length ) {
1411
+ ubolog(`Updater: ${assetKeys.join()} were updated`);
1412
+ }
1413
+ fireNotification('after-assets-updated', { assetKeys });
1414
+ }
1415
+
1416
+ assets.updateStart = function(details) {
1417
+ const oldUpdateDelay = updaterAssetDelay;
1418
+ const newUpdateDelay = typeof details.delay === 'number'
1419
+ ? details.delay
1420
+ : updaterAssetDelayDefault;
1421
+ updaterAssetDelay = Math.min(oldUpdateDelay, newUpdateDelay);
1422
+ updaterAuto = details.auto === true;
1423
+ if ( updaterStatus !== undefined ) {
1424
+ if ( newUpdateDelay < oldUpdateDelay ) {
1425
+ updaterTimer.offon(updaterAssetDelay);
1426
+ }
1427
+ return;
1428
+ }
1429
+ updateFirst();
1430
+ };
1431
+
1432
+ assets.updateStop = function() {
1433
+ updaterTimer.off();
1434
+ if ( updaterStatus !== undefined ) {
1435
+ updateDone();
1436
+ }
1437
+ };
1438
+
1439
+ assets.isUpdating = function() {
1440
+ return updaterStatus === 'updating' &&
1441
+ updaterAssetDelay <= µb.hiddenSettings.manualUpdateAssetFetchPeriod;
1442
+ };
1443
+
1444
+ /******************************************************************************/
1445
+
1446
+ export default assets;
1447
+
1448
+ /******************************************************************************/