@duckduckgo/autoconsent 16.30.0 → 16.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/.github/workflows/asana-sync.yml +1 -1
  2. package/CHANGELOG.md +39 -0
  3. package/dist/addon-firefox/compact-rules.json +1 -1
  4. package/dist/addon-firefox/content.bundle.js +47 -10
  5. package/dist/addon-firefox/manifest.json +1 -1
  6. package/dist/addon-firefox/rule-index.json +1 -1
  7. package/dist/addon-firefox/rules.json +1 -1
  8. package/dist/addon-mv3/compact-rules.json +1 -1
  9. package/dist/addon-mv3/content.bundle.js +47 -10
  10. package/dist/addon-mv3/manifest.json +1 -1
  11. package/dist/addon-mv3/rule-index.json +1 -1
  12. package/dist/addon-mv3/rules.json +1 -1
  13. package/dist/autoconsent.cjs.js +47 -10
  14. package/dist/autoconsent.esm.js +47 -10
  15. package/dist/autoconsent.playwright.js +47 -10
  16. package/dist/autoconsent.standalone.js +48 -11
  17. package/lib/cmps/cookiebot.ts +4 -0
  18. package/lib/heuristic-patterns.ts +45 -8
  19. package/lib/heuristics.ts +2 -1
  20. package/package.json +1 -1
  21. package/rules/autoconsent/doordash-storefront.json +34 -0
  22. package/rules/autoconsent/walmart-ca.json +44 -0
  23. package/rules/autoconsent/xnxx-com.json +1 -1
  24. package/rules/autoconsent/xvideos.json +1 -1
  25. package/rules/compact-rules.json +1 -1
  26. package/rules/rule-index.json +1 -1
  27. package/rules/rules.json +1 -1
  28. package/tests/cookiebot.spec.ts +4 -0
  29. package/tests/doordash-storefront.spec.ts +6 -0
  30. package/tests/walmart-ca.spec.ts +3 -0
  31. package/tests/xnxx.spec.ts +8 -2
  32. package/tests/xvideos.spec.ts +3 -3
  33. package/tests-wtr/heuristics/get-actionable-popups.html +15 -0
  34. package/tests-wtr/heuristics/get-actionable-popups.ts +20 -0
  35. package/tests-wtr/heuristics/heuristic-cmp.html +17 -0
  36. package/tests-wtr/heuristics/heuristic-cmp.ts +34 -0
  37. package/tests-wtr/heuristics/heuristics-utils.test.ts +135 -0
  38. package/tests-wtr/rules/cmp-test-urls.json +0 -1
  39. package/rules/generated/auto_CA_algonquincollege.com_o8v.json +0 -40
  40. package/tests/generated/auto_CA_algonquincollege.com_o8v.spec.ts +0 -6
@@ -457,6 +457,7 @@ var DETECT_PATTERNS = [
457
457
  /we (?:use|serve)(?: optional)? cookies/gi,
458
458
  /we are using cookies/gi,
459
459
  /use of cookies/gi,
460
+ /website uses cookies to enhance your browsing experience/gi,
460
461
  /(?:this|our) (?:web)?site.{0,100}cookies/gi,
461
462
  /cookies (?:and|or) .{0,100} technologies/gi,
462
463
  /such as cookies/gi,
@@ -586,7 +587,16 @@ var DETECT_PATTERNS = [
586
587
  /^\s*empregamos cookies propias\b/gi,
587
588
  /este portal emprega cookies propias ou de terceiros con fins analíticos/gi,
588
589
  // Russian (RU)
589
- /мы используем файлы cookie и аналогичные технологии/gi,
590
+ // e.g. "мы используем файлы cookie", "сайт использует куки", "используются технологии cookie"
591
+ // note: \w does not match Cyrillic, so these use explicit character ranges
592
+ /использу[а-яё]*.{0,40}(?:файл[а-яё]*[\s-]+)?(?:cookie|куки)/gi,
593
+ /(?:cookie|куки).{0,40}использу[а-яё]*/gi,
594
+ /(?:использовани[а-яё]*|обработк[а-яё]*|хранени[а-яё]*).{0,20}(?:файл(?:ов|ы)[\s-]+)?(?:cookie|куки)/gi,
595
+ /технологи[а-яё]*\s+(?:cookie|куки)/gi,
596
+ // e.g. "сайт собирает cookie", "мы применяем файлы cookie", "сохраняем куки на вашем устройстве"
597
+ /(?:собира[а-яё]*|сбор|применя[а-яё]*|сохраня[а-яё]*|размеща[а-яё]*|устанавлива[а-яё]*).{0,30}(?:файл[а-яё]*[\s-]+)?(?:cookie|куки)/gi,
598
+ // "файлы cookie" / "cookie-файлы" / "куки-файлы" in any phrasing
599
+ /(?:файл[а-яё]*[\s-]+(?:cookie|куки)|(?:cookie|куки)[\s-]+файл[а-яё]*)/gi,
590
600
  // Italian (IT)
591
601
  /usiamo.{0,20}cookie/gi
592
602
  ];
@@ -601,8 +611,9 @@ var REJECT_PATTERNS_ENGLISH = [
601
611
  /^\s*(continue|proceed|continue\s+browsing)\s+without\s+(accepting|agreeing|consent|cookies|tracking)(\s*→)?\s*$/is,
602
612
  // essential/necessary/functional-only, e.g. "essential cookies only", "accept only essential cookies",
603
613
  // "allow necessary cookies continue", "use essential cookies only", "functional only", "i confirm necessary"
604
- // note that a necessary/essential/functional word is required
605
- /^\s*(i\s+)?(want\s+to\s+)?(only\s+)?(use|accept|allow|keep|enable|choose|continue\s+with|i\s+confirm)?\s*(only\s+)?(strictly\s+)?(necessary|essential|essentials|functional|required|minimal)\s*(only\s+)?(cookies)?\s*(continue|only)?\s*$/is,
614
+ /^\s*(i\s+)?(want\s+to\s+)?(only\s+)?(use|accept|allow|keep|enable|choose|continue\s+with|i\s+confirm)\s*(only\s+)?(strictly\s+)?(necessary|essential|essentials|functional|required|minimal)\s*(cookies)?\s*(continue|only)?\s*$/is,
615
+ /^\s*(i\s+)?(want\s+to\s+)?only\s+(strictly\s+)?(necessary|essential|essentials|functional|required|minimal)\s*(cookies)?\s*(continue|only)?\s*$/is,
616
+ /^\s*(strictly\s+)?(necessary|essential|essentials|functional|required|minimal)\s*(cookies)?\s+only\s*$/is,
606
617
  // e.g. "do not sell or share my personal information", "opt out of sale ..." (CCPA)
607
618
  /do\s+not\s+sell|opt\s+out\s+of\s+sale/is,
608
619
  // e.g. "opt-out of sale/share or targeted advertising", "opt-out of advertising/social media cookies"
@@ -741,7 +752,14 @@ var REJECT_PATTERNS_POLISH = [
741
752
  "niezb\u0119dne pliki cookie",
742
753
  /^funkcjonalne pliki cookie \(wymagane\)$/
743
754
  ];
744
- var REJECT_PATTERNS_RUSSIAN = ["\u043F\u0440\u0438\u043D\u0438\u043C\u0430\u0442\u044C \u0442\u043E\u043B\u044C\u043A\u043E \u043D\u0435\u043E\u0431\u0445\u043E\u0434\u0438\u043C\u044B\u0435 \u0444\u0430\u0439\u043B\u044B cookie"];
755
+ var REJECT_PATTERNS_RUSSIAN = [
756
+ // отклонить / отказаться / запретить (reject verbs); \w does not match Cyrillic
757
+ /(^|\s)(отклон[а-яё]*|отказ[а-яё]*|откаж[а-яё]*|запрет[а-яё]*|запрещ[а-яё]*)/is,
758
+ // "только необходимые (файлы cookie)" / "принять только необходимые куки"
759
+ /^\s*(принять\s+|принима[а-яё]+\s+|разрешить\s+|использовать\s+|оставить\s+)?(только|лишь)\s+(строго\s+)?(необходим[а-яё]+|нужн[а-яё]+|обязательн[а-яё]+|техническ[а-яё]+|функциональн[а-яё]+)(\s+файл[а-яё]*)?([\s-]+(cookie|куки)([\s-]+файл[а-яё]*)?)?\s*$/is,
760
+ // refusals: "не принимаю", "не согласен", "не соглашаюсь", "нет, спасибо"
761
+ /^\s*(не\s+(принима[а-яё]+|соглас[а-яё]+|разреша[а-яё]+|хочу)|нет(,?\s+спасибо)?)\s*$/is
762
+ ];
745
763
  var REJECT_PATTERNS_TURKISH = ["reddet", "\xE7erezleri reddet"];
746
764
  var REJECT_PATTERNS_INDONESIAN = ["tolak cookie"];
747
765
  var REJECT_PATTERNS = [
@@ -782,7 +800,9 @@ var BUTTON_NEVER_MATCH_PATTERNS = [
782
800
  /suscríbete/,
783
801
  /sin cookies .{0,10}euro/s,
784
802
  // Polish (PL)
785
- /subskrybuj/
803
+ /subskrybuj/,
804
+ // Russian (RU): paywall/subscription wording, e.g. "отказаться от подписки", "оплатить"
805
+ /подписатьс|подписк|оплатит|оплачива/is
786
806
  ];
787
807
  var DETECT_NEVER_MATCH_PATTERNS = [
788
808
  // e.g. "age verification", "age confirmation", "age check", "age gate", "age restriction"
@@ -947,8 +967,12 @@ var SETTINGS_PATTERNS = [
947
967
  "zmie\u0144 zgody",
948
968
  "zobacz preferencje",
949
969
  // Russian (RU)
950
- "\u043D\u0430\u0441\u0442\u0440\u043E\u0438\u0442\u044C \u0444\u0430\u0439\u043B\u044B cookie",
951
- "\u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438",
970
+ // e.g. "настроить", "настройки куки", "параметры конфиденциальности"; \w does not match Cyrillic
971
+ /^\s*((мои|моими|свои|своими)\s+)?(настро[а-яё]+|парамет[а-яё]+|предпочтени[а-яё]+)([\s-]+(мои|моими|свои|своими|файл[а-яё]*|cookie|куки[а-яё]*|конфиденциальност[а-яё]*|согласи[а-яё]*|приватност[а-яё]*))*\s*$/is,
972
+ // e.g. "управление файлами cookie", "изменить настройки", "выбрать категории"
973
+ // "подробн" is deliberately excluded: it would also match the "подробнее о cookie" policy link
974
+ /^\s*(управл[а-яё]+|измен[а-яё]+|выбрать|персонализ[а-яё]+|расширенн[а-яё]+|индивидуальн[а-яё]+)[\s-]+.{0,20}(настройк[а-яё]*|парамет[а-яё]*|предпочтени[а-яё]*|категори[а-яё]*|файл[а-яё]*|cookie|куки[а-яё]*|согласи[а-яё]*|конфиденциальност[а-яё]*)\s*$/is,
975
+ "\u043F\u043E\u0434\u0440\u043E\u0431\u043D\u044B\u0435 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438",
952
976
  // Italian (IT)
953
977
  "personalizza cookie",
954
978
  // English (EN)
@@ -1081,7 +1105,9 @@ var ACCEPT_PATTERNS = [
1081
1105
  "zezw\xF3l na wybrane",
1082
1106
  "zgoda na wybrane",
1083
1107
  // Russian (RU)
1084
- "\u043F\u0440\u0438\u043D\u044F\u0442\u044C \u0432\u0441\u0435 \u0444\u0430\u0439\u043B\u044B cookie",
1108
+ // e.g. "принять всё", "принять все файлы cookie", "разрешить куки", "я согласен"
1109
+ // confirm/save wording (подтвердить, сохранить) is acknowledge, not accept
1110
+ /^\s*(да,?\s+)?(я\s+)?(принять|принима[а-яё]+|соглас[а-яё]+|разрешить|разреша[а-яё]+)(\s+(вс[её]|(все\s+)?(файлы[\s-]+)?(cookie|куки)([\s-]+файл[а-яё]*)?|выбранные|выбор))?\s*$/is,
1085
1111
  "\u043F\u0440\u0438\u043D\u044F\u0442\u044C",
1086
1112
  // Turkish (TR)
1087
1113
  "kabul et",
@@ -1138,7 +1164,15 @@ var ACKNOWLEDGE_PATTERNS = [
1138
1164
  /^zamknij informację o( plikach)? cookies$/,
1139
1165
  "zapisz i zamknij",
1140
1166
  // Russian (RU)
1141
- "\u043F\u043E\u043D\u044F\u0442\u043D\u043E"
1167
+ // e.g. "понятно", "всё понятно", "хорошо", "ясно"; \w does not match Cyrillic
1168
+ /^\s*(хорошо|ясно|(вс[её]\s+)?(понятно|понял[аи]?))[!.]*\s*$/is,
1169
+ // e.g. "закрыть", "закрыть уведомление о cookie"
1170
+ /^\s*закрыть([\s-]+(это|эту|баннер|уведомлени[а-яё]*|окно|сообщени[а-яё]*|плашк[а-яё]*|информаци[а-яё]*)){0,2}([\s-]+(о|об)[\s-]+(cookie|куки[а-яё]*|файл[а-яё]*[\s-]+cookie))?\s*$/is,
1171
+ // e.g. "больше не показывать", "не показывать снова"
1172
+ /^\s*(больше\s+не\s+показывать|не\s+показывать(\s+(снова|больше|это\s+сообщение))?)\s*$/is,
1173
+ // e.g. "подтвердить", "подтверждаю выбор", "сохранить настройки", "сохранить и закрыть"
1174
+ /^\s*(подтвер(дить|ждаю|ждени[а-яё]*)|сохран(ить|яю|ение))([\s-]+(мой|мои|моё|свой|свои|своё)?[\s-]*(выбор[а-яё]*|настройк[а-яё]*|парамет[а-яё]*|предпочтени[а-яё]*|согласи[а-яё]*))?([\s-]+и[\s-]+(закрыть|продолжить))?\s*$/is,
1175
+ "\u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0438\u0442\u044C"
1142
1176
  ];
1143
1177
 
1144
1178
  // lib/heuristics.ts
@@ -1326,7 +1360,7 @@ function getPopupLikeElements(timeout = POPUP_SEARCH_MAX_TIME) {
1326
1360
  for (let node = walker.nextNode(); node; node = walker.nextNode()) {
1327
1361
  found.push(node);
1328
1362
  }
1329
- return excludeContainers(found);
1363
+ return excludeContainers(found.filter((element) => element.innerText?.trim()));
1330
1364
  }
1331
1365
  function getButtonData(el) {
1332
1366
  const actionableButtons = excludeContainers(getButtonLikeElements(el)).filter(
@@ -1877,6 +1911,9 @@ var Cookiebot = class extends AutoConsentCMPBase {
1877
1911
  let res = await this.mainWorldEval("EVAL_COOKIEBOT_3");
1878
1912
  await this.wait(1e3);
1879
1913
  res = res && await this.mainWorldEval("EVAL_COOKIEBOT_4");
1914
+ if (this.elementVisible("#CybotCookiebotDialogBodyButtonDecline")) {
1915
+ return await this.click("#CybotCookiebotDialogBodyButtonDecline");
1916
+ }
1880
1917
  return res;
1881
1918
  }
1882
1919
  async optIn() {
@@ -427,6 +427,7 @@ var DETECT_PATTERNS = [
427
427
  /we (?:use|serve)(?: optional)? cookies/gi,
428
428
  /we are using cookies/gi,
429
429
  /use of cookies/gi,
430
+ /website uses cookies to enhance your browsing experience/gi,
430
431
  /(?:this|our) (?:web)?site.{0,100}cookies/gi,
431
432
  /cookies (?:and|or) .{0,100} technologies/gi,
432
433
  /such as cookies/gi,
@@ -556,7 +557,16 @@ var DETECT_PATTERNS = [
556
557
  /^\s*empregamos cookies propias\b/gi,
557
558
  /este portal emprega cookies propias ou de terceiros con fins analíticos/gi,
558
559
  // Russian (RU)
559
- /мы используем файлы cookie и аналогичные технологии/gi,
560
+ // e.g. "мы используем файлы cookie", "сайт использует куки", "используются технологии cookie"
561
+ // note: \w does not match Cyrillic, so these use explicit character ranges
562
+ /использу[а-яё]*.{0,40}(?:файл[а-яё]*[\s-]+)?(?:cookie|куки)/gi,
563
+ /(?:cookie|куки).{0,40}использу[а-яё]*/gi,
564
+ /(?:использовани[а-яё]*|обработк[а-яё]*|хранени[а-яё]*).{0,20}(?:файл(?:ов|ы)[\s-]+)?(?:cookie|куки)/gi,
565
+ /технологи[а-яё]*\s+(?:cookie|куки)/gi,
566
+ // e.g. "сайт собирает cookie", "мы применяем файлы cookie", "сохраняем куки на вашем устройстве"
567
+ /(?:собира[а-яё]*|сбор|применя[а-яё]*|сохраня[а-яё]*|размеща[а-яё]*|устанавлива[а-яё]*).{0,30}(?:файл[а-яё]*[\s-]+)?(?:cookie|куки)/gi,
568
+ // "файлы cookie" / "cookie-файлы" / "куки-файлы" in any phrasing
569
+ /(?:файл[а-яё]*[\s-]+(?:cookie|куки)|(?:cookie|куки)[\s-]+файл[а-яё]*)/gi,
560
570
  // Italian (IT)
561
571
  /usiamo.{0,20}cookie/gi
562
572
  ];
@@ -571,8 +581,9 @@ var REJECT_PATTERNS_ENGLISH = [
571
581
  /^\s*(continue|proceed|continue\s+browsing)\s+without\s+(accepting|agreeing|consent|cookies|tracking)(\s*→)?\s*$/is,
572
582
  // essential/necessary/functional-only, e.g. "essential cookies only", "accept only essential cookies",
573
583
  // "allow necessary cookies continue", "use essential cookies only", "functional only", "i confirm necessary"
574
- // note that a necessary/essential/functional word is required
575
- /^\s*(i\s+)?(want\s+to\s+)?(only\s+)?(use|accept|allow|keep|enable|choose|continue\s+with|i\s+confirm)?\s*(only\s+)?(strictly\s+)?(necessary|essential|essentials|functional|required|minimal)\s*(only\s+)?(cookies)?\s*(continue|only)?\s*$/is,
584
+ /^\s*(i\s+)?(want\s+to\s+)?(only\s+)?(use|accept|allow|keep|enable|choose|continue\s+with|i\s+confirm)\s*(only\s+)?(strictly\s+)?(necessary|essential|essentials|functional|required|minimal)\s*(cookies)?\s*(continue|only)?\s*$/is,
585
+ /^\s*(i\s+)?(want\s+to\s+)?only\s+(strictly\s+)?(necessary|essential|essentials|functional|required|minimal)\s*(cookies)?\s*(continue|only)?\s*$/is,
586
+ /^\s*(strictly\s+)?(necessary|essential|essentials|functional|required|minimal)\s*(cookies)?\s+only\s*$/is,
576
587
  // e.g. "do not sell or share my personal information", "opt out of sale ..." (CCPA)
577
588
  /do\s+not\s+sell|opt\s+out\s+of\s+sale/is,
578
589
  // e.g. "opt-out of sale/share or targeted advertising", "opt-out of advertising/social media cookies"
@@ -711,7 +722,14 @@ var REJECT_PATTERNS_POLISH = [
711
722
  "niezb\u0119dne pliki cookie",
712
723
  /^funkcjonalne pliki cookie \(wymagane\)$/
713
724
  ];
714
- var REJECT_PATTERNS_RUSSIAN = ["\u043F\u0440\u0438\u043D\u0438\u043C\u0430\u0442\u044C \u0442\u043E\u043B\u044C\u043A\u043E \u043D\u0435\u043E\u0431\u0445\u043E\u0434\u0438\u043C\u044B\u0435 \u0444\u0430\u0439\u043B\u044B cookie"];
725
+ var REJECT_PATTERNS_RUSSIAN = [
726
+ // отклонить / отказаться / запретить (reject verbs); \w does not match Cyrillic
727
+ /(^|\s)(отклон[а-яё]*|отказ[а-яё]*|откаж[а-яё]*|запрет[а-яё]*|запрещ[а-яё]*)/is,
728
+ // "только необходимые (файлы cookie)" / "принять только необходимые куки"
729
+ /^\s*(принять\s+|принима[а-яё]+\s+|разрешить\s+|использовать\s+|оставить\s+)?(только|лишь)\s+(строго\s+)?(необходим[а-яё]+|нужн[а-яё]+|обязательн[а-яё]+|техническ[а-яё]+|функциональн[а-яё]+)(\s+файл[а-яё]*)?([\s-]+(cookie|куки)([\s-]+файл[а-яё]*)?)?\s*$/is,
730
+ // refusals: "не принимаю", "не согласен", "не соглашаюсь", "нет, спасибо"
731
+ /^\s*(не\s+(принима[а-яё]+|соглас[а-яё]+|разреша[а-яё]+|хочу)|нет(,?\s+спасибо)?)\s*$/is
732
+ ];
715
733
  var REJECT_PATTERNS_TURKISH = ["reddet", "\xE7erezleri reddet"];
716
734
  var REJECT_PATTERNS_INDONESIAN = ["tolak cookie"];
717
735
  var REJECT_PATTERNS = [
@@ -752,7 +770,9 @@ var BUTTON_NEVER_MATCH_PATTERNS = [
752
770
  /suscríbete/,
753
771
  /sin cookies .{0,10}euro/s,
754
772
  // Polish (PL)
755
- /subskrybuj/
773
+ /subskrybuj/,
774
+ // Russian (RU): paywall/subscription wording, e.g. "отказаться от подписки", "оплатить"
775
+ /подписатьс|подписк|оплатит|оплачива/is
756
776
  ];
757
777
  var DETECT_NEVER_MATCH_PATTERNS = [
758
778
  // e.g. "age verification", "age confirmation", "age check", "age gate", "age restriction"
@@ -917,8 +937,12 @@ var SETTINGS_PATTERNS = [
917
937
  "zmie\u0144 zgody",
918
938
  "zobacz preferencje",
919
939
  // Russian (RU)
920
- "\u043D\u0430\u0441\u0442\u0440\u043E\u0438\u0442\u044C \u0444\u0430\u0439\u043B\u044B cookie",
921
- "\u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438",
940
+ // e.g. "настроить", "настройки куки", "параметры конфиденциальности"; \w does not match Cyrillic
941
+ /^\s*((мои|моими|свои|своими)\s+)?(настро[а-яё]+|парамет[а-яё]+|предпочтени[а-яё]+)([\s-]+(мои|моими|свои|своими|файл[а-яё]*|cookie|куки[а-яё]*|конфиденциальност[а-яё]*|согласи[а-яё]*|приватност[а-яё]*))*\s*$/is,
942
+ // e.g. "управление файлами cookie", "изменить настройки", "выбрать категории"
943
+ // "подробн" is deliberately excluded: it would also match the "подробнее о cookie" policy link
944
+ /^\s*(управл[а-яё]+|измен[а-яё]+|выбрать|персонализ[а-яё]+|расширенн[а-яё]+|индивидуальн[а-яё]+)[\s-]+.{0,20}(настройк[а-яё]*|парамет[а-яё]*|предпочтени[а-яё]*|категори[а-яё]*|файл[а-яё]*|cookie|куки[а-яё]*|согласи[а-яё]*|конфиденциальност[а-яё]*)\s*$/is,
945
+ "\u043F\u043E\u0434\u0440\u043E\u0431\u043D\u044B\u0435 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438",
922
946
  // Italian (IT)
923
947
  "personalizza cookie",
924
948
  // English (EN)
@@ -1051,7 +1075,9 @@ var ACCEPT_PATTERNS = [
1051
1075
  "zezw\xF3l na wybrane",
1052
1076
  "zgoda na wybrane",
1053
1077
  // Russian (RU)
1054
- "\u043F\u0440\u0438\u043D\u044F\u0442\u044C \u0432\u0441\u0435 \u0444\u0430\u0439\u043B\u044B cookie",
1078
+ // e.g. "принять всё", "принять все файлы cookie", "разрешить куки", "я согласен"
1079
+ // confirm/save wording (подтвердить, сохранить) is acknowledge, not accept
1080
+ /^\s*(да,?\s+)?(я\s+)?(принять|принима[а-яё]+|соглас[а-яё]+|разрешить|разреша[а-яё]+)(\s+(вс[её]|(все\s+)?(файлы[\s-]+)?(cookie|куки)([\s-]+файл[а-яё]*)?|выбранные|выбор))?\s*$/is,
1055
1081
  "\u043F\u0440\u0438\u043D\u044F\u0442\u044C",
1056
1082
  // Turkish (TR)
1057
1083
  "kabul et",
@@ -1108,7 +1134,15 @@ var ACKNOWLEDGE_PATTERNS = [
1108
1134
  /^zamknij informację o( plikach)? cookies$/,
1109
1135
  "zapisz i zamknij",
1110
1136
  // Russian (RU)
1111
- "\u043F\u043E\u043D\u044F\u0442\u043D\u043E"
1137
+ // e.g. "понятно", "всё понятно", "хорошо", "ясно"; \w does not match Cyrillic
1138
+ /^\s*(хорошо|ясно|(вс[её]\s+)?(понятно|понял[аи]?))[!.]*\s*$/is,
1139
+ // e.g. "закрыть", "закрыть уведомление о cookie"
1140
+ /^\s*закрыть([\s-]+(это|эту|баннер|уведомлени[а-яё]*|окно|сообщени[а-яё]*|плашк[а-яё]*|информаци[а-яё]*)){0,2}([\s-]+(о|об)[\s-]+(cookie|куки[а-яё]*|файл[а-яё]*[\s-]+cookie))?\s*$/is,
1141
+ // e.g. "больше не показывать", "не показывать снова"
1142
+ /^\s*(больше\s+не\s+показывать|не\s+показывать(\s+(снова|больше|это\s+сообщение))?)\s*$/is,
1143
+ // e.g. "подтвердить", "подтверждаю выбор", "сохранить настройки", "сохранить и закрыть"
1144
+ /^\s*(подтвер(дить|ждаю|ждени[а-яё]*)|сохран(ить|яю|ение))([\s-]+(мой|мои|моё|свой|свои|своё)?[\s-]*(выбор[а-яё]*|настройк[а-яё]*|парамет[а-яё]*|предпочтени[а-яё]*|согласи[а-яё]*))?([\s-]+и[\s-]+(закрыть|продолжить))?\s*$/is,
1145
+ "\u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0438\u0442\u044C"
1112
1146
  ];
1113
1147
 
1114
1148
  // lib/heuristics.ts
@@ -1296,7 +1330,7 @@ function getPopupLikeElements(timeout = POPUP_SEARCH_MAX_TIME) {
1296
1330
  for (let node = walker.nextNode(); node; node = walker.nextNode()) {
1297
1331
  found.push(node);
1298
1332
  }
1299
- return excludeContainers(found);
1333
+ return excludeContainers(found.filter((element) => element.innerText?.trim()));
1300
1334
  }
1301
1335
  function getButtonData(el) {
1302
1336
  const actionableButtons = excludeContainers(getButtonLikeElements(el)).filter(
@@ -1847,6 +1881,9 @@ var Cookiebot = class extends AutoConsentCMPBase {
1847
1881
  let res = await this.mainWorldEval("EVAL_COOKIEBOT_3");
1848
1882
  await this.wait(1e3);
1849
1883
  res = res && await this.mainWorldEval("EVAL_COOKIEBOT_4");
1884
+ if (this.elementVisible("#CybotCookiebotDialogBodyButtonDecline")) {
1885
+ return await this.click("#CybotCookiebotDialogBodyButtonDecline");
1886
+ }
1850
1887
  return res;
1851
1888
  }
1852
1889
  async optIn() {
@@ -429,6 +429,7 @@
429
429
  /we (?:use|serve)(?: optional)? cookies/gi,
430
430
  /we are using cookies/gi,
431
431
  /use of cookies/gi,
432
+ /website uses cookies to enhance your browsing experience/gi,
432
433
  /(?:this|our) (?:web)?site.{0,100}cookies/gi,
433
434
  /cookies (?:and|or) .{0,100} technologies/gi,
434
435
  /such as cookies/gi,
@@ -558,7 +559,16 @@
558
559
  /^\s*empregamos cookies propias\b/gi,
559
560
  /este portal emprega cookies propias ou de terceiros con fins analíticos/gi,
560
561
  // Russian (RU)
561
- /мы используем файлы cookie и аналогичные технологии/gi,
562
+ // e.g. "мы используем файлы cookie", "сайт использует куки", "используются технологии cookie"
563
+ // note: \w does not match Cyrillic, so these use explicit character ranges
564
+ /использу[а-яё]*.{0,40}(?:файл[а-яё]*[\s-]+)?(?:cookie|куки)/gi,
565
+ /(?:cookie|куки).{0,40}использу[а-яё]*/gi,
566
+ /(?:использовани[а-яё]*|обработк[а-яё]*|хранени[а-яё]*).{0,20}(?:файл(?:ов|ы)[\s-]+)?(?:cookie|куки)/gi,
567
+ /технологи[а-яё]*\s+(?:cookie|куки)/gi,
568
+ // e.g. "сайт собирает cookie", "мы применяем файлы cookie", "сохраняем куки на вашем устройстве"
569
+ /(?:собира[а-яё]*|сбор|применя[а-яё]*|сохраня[а-яё]*|размеща[а-яё]*|устанавлива[а-яё]*).{0,30}(?:файл[а-яё]*[\s-]+)?(?:cookie|куки)/gi,
570
+ // "файлы cookie" / "cookie-файлы" / "куки-файлы" in any phrasing
571
+ /(?:файл[а-яё]*[\s-]+(?:cookie|куки)|(?:cookie|куки)[\s-]+файл[а-яё]*)/gi,
562
572
  // Italian (IT)
563
573
  /usiamo.{0,20}cookie/gi
564
574
  ];
@@ -573,8 +583,9 @@
573
583
  /^\s*(continue|proceed|continue\s+browsing)\s+without\s+(accepting|agreeing|consent|cookies|tracking)(\s*→)?\s*$/is,
574
584
  // essential/necessary/functional-only, e.g. "essential cookies only", "accept only essential cookies",
575
585
  // "allow necessary cookies continue", "use essential cookies only", "functional only", "i confirm necessary"
576
- // note that a necessary/essential/functional word is required
577
- /^\s*(i\s+)?(want\s+to\s+)?(only\s+)?(use|accept|allow|keep|enable|choose|continue\s+with|i\s+confirm)?\s*(only\s+)?(strictly\s+)?(necessary|essential|essentials|functional|required|minimal)\s*(only\s+)?(cookies)?\s*(continue|only)?\s*$/is,
586
+ /^\s*(i\s+)?(want\s+to\s+)?(only\s+)?(use|accept|allow|keep|enable|choose|continue\s+with|i\s+confirm)\s*(only\s+)?(strictly\s+)?(necessary|essential|essentials|functional|required|minimal)\s*(cookies)?\s*(continue|only)?\s*$/is,
587
+ /^\s*(i\s+)?(want\s+to\s+)?only\s+(strictly\s+)?(necessary|essential|essentials|functional|required|minimal)\s*(cookies)?\s*(continue|only)?\s*$/is,
588
+ /^\s*(strictly\s+)?(necessary|essential|essentials|functional|required|minimal)\s*(cookies)?\s+only\s*$/is,
578
589
  // e.g. "do not sell or share my personal information", "opt out of sale ..." (CCPA)
579
590
  /do\s+not\s+sell|opt\s+out\s+of\s+sale/is,
580
591
  // e.g. "opt-out of sale/share or targeted advertising", "opt-out of advertising/social media cookies"
@@ -713,7 +724,14 @@
713
724
  "niezb\u0119dne pliki cookie",
714
725
  /^funkcjonalne pliki cookie \(wymagane\)$/
715
726
  ];
716
- var REJECT_PATTERNS_RUSSIAN = ["\u043F\u0440\u0438\u043D\u0438\u043C\u0430\u0442\u044C \u0442\u043E\u043B\u044C\u043A\u043E \u043D\u0435\u043E\u0431\u0445\u043E\u0434\u0438\u043C\u044B\u0435 \u0444\u0430\u0439\u043B\u044B cookie"];
727
+ var REJECT_PATTERNS_RUSSIAN = [
728
+ // отклонить / отказаться / запретить (reject verbs); \w does not match Cyrillic
729
+ /(^|\s)(отклон[а-яё]*|отказ[а-яё]*|откаж[а-яё]*|запрет[а-яё]*|запрещ[а-яё]*)/is,
730
+ // "только необходимые (файлы cookie)" / "принять только необходимые куки"
731
+ /^\s*(принять\s+|принима[а-яё]+\s+|разрешить\s+|использовать\s+|оставить\s+)?(только|лишь)\s+(строго\s+)?(необходим[а-яё]+|нужн[а-яё]+|обязательн[а-яё]+|техническ[а-яё]+|функциональн[а-яё]+)(\s+файл[а-яё]*)?([\s-]+(cookie|куки)([\s-]+файл[а-яё]*)?)?\s*$/is,
732
+ // refusals: "не принимаю", "не согласен", "не соглашаюсь", "нет, спасибо"
733
+ /^\s*(не\s+(принима[а-яё]+|соглас[а-яё]+|разреша[а-яё]+|хочу)|нет(,?\s+спасибо)?)\s*$/is
734
+ ];
717
735
  var REJECT_PATTERNS_TURKISH = ["reddet", "\xE7erezleri reddet"];
718
736
  var REJECT_PATTERNS_INDONESIAN = ["tolak cookie"];
719
737
  var REJECT_PATTERNS = [
@@ -754,7 +772,9 @@
754
772
  /suscríbete/,
755
773
  /sin cookies .{0,10}euro/s,
756
774
  // Polish (PL)
757
- /subskrybuj/
775
+ /subskrybuj/,
776
+ // Russian (RU): paywall/subscription wording, e.g. "отказаться от подписки", "оплатить"
777
+ /подписатьс|подписк|оплатит|оплачива/is
758
778
  ];
759
779
  var DETECT_NEVER_MATCH_PATTERNS = [
760
780
  // e.g. "age verification", "age confirmation", "age check", "age gate", "age restriction"
@@ -919,8 +939,12 @@
919
939
  "zmie\u0144 zgody",
920
940
  "zobacz preferencje",
921
941
  // Russian (RU)
922
- "\u043D\u0430\u0441\u0442\u0440\u043E\u0438\u0442\u044C \u0444\u0430\u0439\u043B\u044B cookie",
923
- "\u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438",
942
+ // e.g. "настроить", "настройки куки", "параметры конфиденциальности"; \w does not match Cyrillic
943
+ /^\s*((мои|моими|свои|своими)\s+)?(настро[а-яё]+|парамет[а-яё]+|предпочтени[а-яё]+)([\s-]+(мои|моими|свои|своими|файл[а-яё]*|cookie|куки[а-яё]*|конфиденциальност[а-яё]*|согласи[а-яё]*|приватност[а-яё]*))*\s*$/is,
944
+ // e.g. "управление файлами cookie", "изменить настройки", "выбрать категории"
945
+ // "подробн" is deliberately excluded: it would also match the "подробнее о cookie" policy link
946
+ /^\s*(управл[а-яё]+|измен[а-яё]+|выбрать|персонализ[а-яё]+|расширенн[а-яё]+|индивидуальн[а-яё]+)[\s-]+.{0,20}(настройк[а-яё]*|парамет[а-яё]*|предпочтени[а-яё]*|категори[а-яё]*|файл[а-яё]*|cookie|куки[а-яё]*|согласи[а-яё]*|конфиденциальност[а-яё]*)\s*$/is,
947
+ "\u043F\u043E\u0434\u0440\u043E\u0431\u043D\u044B\u0435 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438",
924
948
  // Italian (IT)
925
949
  "personalizza cookie",
926
950
  // English (EN)
@@ -1053,7 +1077,9 @@
1053
1077
  "zezw\xF3l na wybrane",
1054
1078
  "zgoda na wybrane",
1055
1079
  // Russian (RU)
1056
- "\u043F\u0440\u0438\u043D\u044F\u0442\u044C \u0432\u0441\u0435 \u0444\u0430\u0439\u043B\u044B cookie",
1080
+ // e.g. "принять всё", "принять все файлы cookie", "разрешить куки", "я согласен"
1081
+ // confirm/save wording (подтвердить, сохранить) is acknowledge, not accept
1082
+ /^\s*(да,?\s+)?(я\s+)?(принять|принима[а-яё]+|соглас[а-яё]+|разрешить|разреша[а-яё]+)(\s+(вс[её]|(все\s+)?(файлы[\s-]+)?(cookie|куки)([\s-]+файл[а-яё]*)?|выбранные|выбор))?\s*$/is,
1057
1083
  "\u043F\u0440\u0438\u043D\u044F\u0442\u044C",
1058
1084
  // Turkish (TR)
1059
1085
  "kabul et",
@@ -1110,7 +1136,15 @@
1110
1136
  /^zamknij informację o( plikach)? cookies$/,
1111
1137
  "zapisz i zamknij",
1112
1138
  // Russian (RU)
1113
- "\u043F\u043E\u043D\u044F\u0442\u043D\u043E"
1139
+ // e.g. "понятно", "всё понятно", "хорошо", "ясно"; \w does not match Cyrillic
1140
+ /^\s*(хорошо|ясно|(вс[её]\s+)?(понятно|понял[аи]?))[!.]*\s*$/is,
1141
+ // e.g. "закрыть", "закрыть уведомление о cookie"
1142
+ /^\s*закрыть([\s-]+(это|эту|баннер|уведомлени[а-яё]*|окно|сообщени[а-яё]*|плашк[а-яё]*|информаци[а-яё]*)){0,2}([\s-]+(о|об)[\s-]+(cookie|куки[а-яё]*|файл[а-яё]*[\s-]+cookie))?\s*$/is,
1143
+ // e.g. "больше не показывать", "не показывать снова"
1144
+ /^\s*(больше\s+не\s+показывать|не\s+показывать(\s+(снова|больше|это\s+сообщение))?)\s*$/is,
1145
+ // e.g. "подтвердить", "подтверждаю выбор", "сохранить настройки", "сохранить и закрыть"
1146
+ /^\s*(подтвер(дить|ждаю|ждени[а-яё]*)|сохран(ить|яю|ение))([\s-]+(мой|мои|моё|свой|свои|своё)?[\s-]*(выбор[а-яё]*|настройк[а-яё]*|парамет[а-яё]*|предпочтени[а-яё]*|согласи[а-яё]*))?([\s-]+и[\s-]+(закрыть|продолжить))?\s*$/is,
1147
+ "\u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0438\u0442\u044C"
1114
1148
  ];
1115
1149
 
1116
1150
  // lib/heuristics.ts
@@ -1298,7 +1332,7 @@
1298
1332
  for (let node = walker.nextNode(); node; node = walker.nextNode()) {
1299
1333
  found.push(node);
1300
1334
  }
1301
- return excludeContainers(found);
1335
+ return excludeContainers(found.filter((element) => element.innerText?.trim()));
1302
1336
  }
1303
1337
  function getButtonData(el) {
1304
1338
  const actionableButtons = excludeContainers(getButtonLikeElements(el)).filter(
@@ -1849,6 +1883,9 @@
1849
1883
  let res = await this.mainWorldEval("EVAL_COOKIEBOT_3");
1850
1884
  await this.wait(1e3);
1851
1885
  res = res && await this.mainWorldEval("EVAL_COOKIEBOT_4");
1886
+ if (this.elementVisible("#CybotCookiebotDialogBodyButtonDecline")) {
1887
+ return await this.click("#CybotCookiebotDialogBodyButtonDecline");
1888
+ }
1852
1889
  return res;
1853
1890
  }
1854
1891
  async optIn() {