pervert-monkey 1.0.9 → 1.0.10

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 (65) hide show
  1. package/dist/core/pervertmonkey.core.es.d.ts +121 -59
  2. package/dist/core/pervertmonkey.core.es.js +1001 -315
  3. package/dist/core/pervertmonkey.core.es.js.map +1 -1
  4. package/dist/core/pervertmonkey.core.umd.js +1001 -315
  5. package/dist/core/pervertmonkey.core.umd.js.map +1 -1
  6. package/dist/userscripts/3hentai.user.js +14 -8
  7. package/dist/userscripts/camgirlfinder.user.js +1 -1
  8. package/dist/userscripts/camwhores.user.js +15 -9
  9. package/dist/userscripts/e-hentai.user.js +12 -6
  10. package/dist/userscripts/ebalka.user.js +11 -5
  11. package/dist/userscripts/eporner.user.js +15 -10
  12. package/dist/userscripts/erome.user.js +11 -10
  13. package/dist/userscripts/eroprofile.user.js +9 -5
  14. package/dist/userscripts/javhdporn.user.js +9 -5
  15. package/dist/userscripts/missav.user.js +10 -6
  16. package/dist/userscripts/motherless.user.js +11 -7
  17. package/dist/userscripts/namethatporn.user.js +17 -13
  18. package/dist/userscripts/nhentai.user.js +12 -6
  19. package/dist/userscripts/obmenvsem.user.js +14 -18
  20. package/dist/userscripts/pornhub.user.js +14 -10
  21. package/dist/userscripts/spankbang.user.js +10 -6
  22. package/dist/userscripts/thisvid.user.js +27 -21
  23. package/dist/userscripts/xhamster.user.js +26 -26
  24. package/dist/userscripts/xvideos.user.js +19 -17
  25. package/package.json +5 -3
  26. package/src/core/{data-control → data-handler}/data-filter.ts +3 -8
  27. package/src/core/{data-control → data-handler}/data-manager.ts +8 -7
  28. package/src/core/data-handler/index.ts +2 -0
  29. package/src/core/index.ts +4 -4
  30. package/src/core/infinite-scroll/index.ts +20 -29
  31. package/src/core/parsers/index.ts +4 -0
  32. package/src/core/{pagination-parsing → parsers/pagination-parser}/index.ts +3 -0
  33. package/src/core/{pagination-parsing → parsers/pagination-parser}/pagination-strategies/PaginationStrategy.ts +1 -1
  34. package/src/core/{pagination-parsing → parsers/pagination-parser}/pagination-strategies/PaginationStrategyDataParams.ts +1 -1
  35. package/src/core/{pagination-parsing → parsers/pagination-parser}/pagination-strategies/PaginationStrategyPathnameParams.ts +2 -1
  36. package/src/core/{pagination-parsing → parsers/pagination-parser}/pagination-utils/index.ts +1 -4
  37. package/src/core/parsers/thumb-data-parser.ts +96 -0
  38. package/src/core/parsers/thumb-img-parser.ts +62 -0
  39. package/src/core/parsers/thumbs-parser.ts +29 -0
  40. package/src/core/rules/index.ts +39 -207
  41. package/src/userscripts/index.ts +1 -1
  42. package/src/userscripts/scripts/3hentai.ts +14 -6
  43. package/src/userscripts/scripts/camwhores.ts +19 -13
  44. package/src/userscripts/scripts/e-hentai.ts +13 -7
  45. package/src/userscripts/scripts/ebalka.ts +11 -5
  46. package/src/userscripts/scripts/eporner.ts +16 -10
  47. package/src/userscripts/scripts/erome.ts +11 -10
  48. package/src/userscripts/scripts/eroprofile.ts +10 -6
  49. package/src/userscripts/scripts/javhdporn.ts +9 -5
  50. package/src/userscripts/scripts/missav.ts +10 -6
  51. package/src/userscripts/scripts/motherless.ts +11 -7
  52. package/src/userscripts/scripts/namethatporn.ts +18 -14
  53. package/src/userscripts/scripts/nhentai.ts +13 -8
  54. package/src/userscripts/scripts/obmenvsem.ts +14 -13
  55. package/src/userscripts/scripts/pornhub.ts +14 -10
  56. package/src/userscripts/scripts/spankbang.ts +10 -6
  57. package/src/userscripts/scripts/thisvid.ts +32 -27
  58. package/src/userscripts/scripts/xhamster.ts +37 -38
  59. package/src/userscripts/scripts/xvideos.ts +18 -16
  60. package/src/utils/index.ts +7 -19
  61. package/src/utils/parsers/index.ts +4 -0
  62. package/src/utils/strings/index.ts +2 -0
  63. package/src/core/data-control/index.ts +0 -2
  64. /package/src/core/{pagination-parsing → parsers/pagination-parser}/pagination-strategies/PaginationStrategySearchParams.ts +0 -0
  65. /package/src/core/{pagination-parsing → parsers/pagination-parser}/pagination-strategies/index.ts +0 -0
@@ -11,7 +11,7 @@
11
11
  // @source github:smartacephale/sleazy-fork
12
12
  // @supportURL https://github.com/smartacephale/sleazy-fork/issues
13
13
  // @match https://*.3hentai.net/*
14
- // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.9/dist/core/pervertmonkey.core.umd.js
14
+ // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.10/dist/core/pervertmonkey.core.umd.js
15
15
  // @require data:application/javascript,var core = window.pervertmonkey.core || pervertmonkey.core; var utils = core;
16
16
  // @grant GM_addStyle
17
17
  // @grant unsafeWindow
@@ -21,11 +21,19 @@
21
21
  (function (core, utils) {
22
22
  'use strict';
23
23
 
24
- new core.RulesGlobal({
24
+ new core.Rules({
25
25
  containerSelectorLast: ".listing-container",
26
- thumbsSelector: ".doujin-col",
27
- titleSelector: ".title",
28
- getThumbImgDataStrategy: "auto",
26
+ thumbs: {
27
+ selector: ".doujin-col"
28
+ },
29
+ thumb: {
30
+ selectors: {
31
+ title: ".title"
32
+ }
33
+ },
34
+ thumbImg: {
35
+ strategy: "auto"
36
+ },
29
37
  gropeStrategy: "all-in-all",
30
38
  customDataSelectorFns: ["filterInclude", "filterExclude"],
31
39
  schemeOptions: ["Text Filter", "Badge", "Advanced"],
@@ -47,9 +55,7 @@
47
55
  const t = e;
48
56
  const origin = t.src;
49
57
  t.src = t.src.replace(/\w+\.\w+$/, "1t.jpg");
50
- t.onerror = (_) => {
51
- t.src = origin;
52
- };
58
+ t.onerror = (_) => tick.stop();
53
59
  tick.start(
54
60
  () => {
55
61
  t.src = rotate(t.src);
@@ -11,7 +11,7 @@
11
11
  // @source github:smartacephale/sleazy-fork
12
12
  // @supportURL https://github.com/smartacephale/sleazy-fork/issues
13
13
  // @match https://camgirlfinder.net/*
14
- // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.9/dist/core/pervertmonkey.core.umd.js
14
+ // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.10/dist/core/pervertmonkey.core.umd.js
15
15
  // @require data:application/javascript,var core = window.pervertmonkey.core || pervertmonkey.core; var utils = core;
16
16
  // @grant none
17
17
  // @run-at document-idle
@@ -13,7 +13,7 @@
13
13
  // @match https://*.camwhores.tv
14
14
  // @match https://*.camwhores.*/*
15
15
  // @exclude https://*.camwhores.tv/*mode=async*
16
- // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.9/dist/core/pervertmonkey.core.umd.js
16
+ // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.10/dist/core/pervertmonkey.core.umd.js
17
17
  // @require data:application/javascript,var core = window.pervertmonkey.core || pervertmonkey.core; var utils = core;
18
18
  // @grant GM_addStyle
19
19
  // @grant unsafeWindow
@@ -91,20 +91,26 @@
91
91
  const IS_COMMUNITY_LIST = /\/members\/$/.test(location.pathname);
92
92
  const IS_VIDEO_PAGE = /^(\/videos)?\/\d+\//.test(location.pathname);
93
93
  const IS_LOGGED_IN = document.cookie.includes("kt_member");
94
- const rules = new core.RulesGlobal({
94
+ const rules = new core.Rules({
95
95
  containerSelector: '[id*="playlist"]:has(> .item .title),[id*="videos"]:has(> .item .title),form:has(>.item .title)',
96
96
  paginationStrategyOptions: {
97
97
  paginationSelector: ".pagination:not([id *= member])",
98
98
  overwritePaginationLast: IS_MEMBER_PAGE ? () => 1 : (x) => x === 9 ? 9999 : x
99
99
  },
100
- getThumbImgDataAttrSelector: "data-original",
101
- getThumbImgDataStrategy: "auto",
102
- thumbsSelector: ".list-videos .item, .playlist .item, .list-playlists > div > .item, .item:has(.title)",
103
- gropeStrategy: "all-in-all",
104
- getThumbDataStrategy: "auto-select",
105
- customThumbDataSelectors: {
106
- private: { type: "boolean", selector: "[class*=private]" }
100
+ thumbs: {
101
+ selector: ".list-videos .item, .playlist .item, .list-playlists > div > .item, .item:has(.title)"
102
+ },
103
+ thumb: {
104
+ strategy: "auto-select",
105
+ selectors: {
106
+ private: { type: "boolean", selector: "[class*=private]" }
107
+ }
107
108
  },
109
+ thumbImg: {
110
+ selector: "data-original",
111
+ strategy: "auto"
112
+ },
113
+ gropeStrategy: "all-in-all",
108
114
  customDataSelectorFns: [
109
115
  "filterInclude",
110
116
  "filterExclude",
@@ -11,7 +11,7 @@
11
11
  // @source github:smartacephale/sleazy-fork
12
12
  // @supportURL https://github.com/smartacephale/sleazy-fork/issues
13
13
  // @match https://*.e-hentai.org/*
14
- // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.9/dist/core/pervertmonkey.core.umd.js
14
+ // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.10/dist/core/pervertmonkey.core.umd.js
15
15
  // @require data:application/javascript,var core = window.pervertmonkey.core || pervertmonkey.core; var utils = core;
16
16
  // @grant GM_addStyle
17
17
  // @grant unsafeWindow
@@ -21,12 +21,18 @@
21
21
  (function (core, utils) {
22
22
  'use strict';
23
23
 
24
- new core.RulesGlobal({
25
- thumbsSelector: ".gl1t",
26
- titleSelector: ".glname",
24
+ new core.Rules({
25
+ thumbs: { selector: ".gl1t" },
26
+ thumb: {
27
+ selectors: {
28
+ title: ".glname"
29
+ }
30
+ },
31
+ thumbImg: {
32
+ selector: "data-lazy-load",
33
+ strategy: "auto"
34
+ },
27
35
  containerSelectorLast: ".itg.gld",
28
- getThumbImgDataAttrSelector: "data-lazy-load",
29
- getThumbImgDataStrategy: "auto",
30
36
  paginationStrategyOptions: createPaginationStrategyOptions(),
31
37
  customDataSelectorFns: ["filterInclude", "filterExclude"],
32
38
  schemeOptions: ["Text Filter", "Badge", "Advanced"]
@@ -15,7 +15,7 @@
15
15
  // @match https://*ebalka.*.*/*
16
16
  // @match https://*.ebalk*.*/*
17
17
  // @match https://*.fuckingbear*.*/*
18
- // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.9/dist/core/pervertmonkey.core.umd.js
18
+ // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.10/dist/core/pervertmonkey.core.umd.js
19
19
  // @require data:application/javascript,var core = window.pervertmonkey.core || pervertmonkey.core; var utils = core;
20
20
  // @grant GM_addStyle
21
21
  // @grant unsafeWindow
@@ -25,14 +25,20 @@
25
25
  (function (core, utils) {
26
26
  'use strict';
27
27
 
28
- new core.RulesGlobal({
28
+ new core.Rules({
29
29
  containerSelectorLast: ".content__video",
30
30
  paginationStrategyOptions: {
31
31
  paginationSelector: ".pagination:not([id *= member])"
32
32
  },
33
- thumbsSelector: ".card_video",
34
- titleSelector: ".card__title",
35
- durationSelector: ".card__spot > span:last-child",
33
+ thumbs: {
34
+ selector: ".card_video"
35
+ },
36
+ thumb: {
37
+ selectors: {
38
+ title: ".card__title",
39
+ duration: ".card__spot > span:last-child"
40
+ }
41
+ },
36
42
  animatePreview,
37
43
  schemeOptions: ["Text Filter", "Badge", "Duration Filter", "Advanced"]
38
44
  });
@@ -12,7 +12,7 @@
12
12
  // @supportURL https://github.com/smartacephale/sleazy-fork/issues
13
13
  // @match https://*.eporner.com/*
14
14
  // @match https://*.eporner.*/*
15
- // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.9/dist/core/pervertmonkey.core.umd.js
15
+ // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.10/dist/core/pervertmonkey.core.umd.js
16
16
  // @require data:application/javascript,var core = window.pervertmonkey.core || pervertmonkey.core; var utils = core;
17
17
  // @grant GM_addStyle
18
18
  // @grant unsafeWindow
@@ -25,20 +25,25 @@
25
25
  var _unsafeWindow = (() => typeof unsafeWindow != "undefined" ? unsafeWindow : undefined)();
26
26
 
27
27
  const show_video_prev = _unsafeWindow.show_video_prev;
28
- new core.RulesGlobal({
28
+ new core.Rules({
29
29
  paginationStrategyOptions: {
30
30
  paginationSelector: ".numlist2"
31
31
  },
32
- customThumbDataSelectors: {
33
- quality: { type: "number", selector: '[title="Quality"]' }
32
+ thumb: {
33
+ selectors: {
34
+ quality: { type: "number", selector: '[title="Quality"]' },
35
+ title: "a",
36
+ uploader: '[title="Uploader"]',
37
+ duration: '[title="Duration"]'
38
+ }
39
+ },
40
+ thumbImg: {
41
+ strategy: "auto"
42
+ },
43
+ thumbs: {
44
+ selector: "div[id^=vf][data-id]"
34
45
  },
35
46
  containerSelectorLast: "#vidresults",
36
- thumbsSelector: "div[id^=vf][data-id]",
37
- uploaderSelector: '[title="Uploader"]',
38
- titleSelector: "a",
39
- durationSelector: '[title="Duration"]',
40
- getThumbImgDataStrategy: "auto",
41
- getThumbImgDataAttrDelete: "auto",
42
47
  customDataSelectorFns: [
43
48
  "filterInclude",
44
49
  "filterExclude",
@@ -11,7 +11,7 @@
11
11
  // @source github:smartacephale/sleazy-fork
12
12
  // @supportURL https://github.com/smartacephale/sleazy-fork/issues
13
13
  // @match *://*.erome.com/*
14
- // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.9/dist/core/pervertmonkey.core.umd.js
14
+ // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.10/dist/core/pervertmonkey.core.umd.js
15
15
  // @require data:application/javascript,var core = window.pervertmonkey.core || pervertmonkey.core; var utils = core;
16
16
  // @grant GM_addStyle
17
17
  // @grant unsafeWindow
@@ -25,16 +25,17 @@
25
25
  var _unsafeWindow = (() => typeof unsafeWindow != "undefined" ? unsafeWindow : undefined)();
26
26
 
27
27
  const $ = _unsafeWindow.$;
28
- const rules = new core.RulesGlobal({
28
+ const rules = new core.Rules({
29
29
  containerSelector: "#albums",
30
- thumbsSelector: "div[id^=album-]",
31
- titleSelector: ".album-title",
32
- uploaderSelector: ".album-user",
33
30
  gropeStrategy: "all-in-one",
34
- customThumbDataSelectors: {
35
- videoAlbum: {
36
- type: "boolean",
37
- selector: ".album-videos"
31
+ thumbs: {
32
+ selector: "div[id^=album-]"
33
+ },
34
+ thumb: {
35
+ selectors: {
36
+ title: ".album-title",
37
+ uploader: ".album-user",
38
+ videoAlbum: { type: "boolean", selector: ".album-videos" }
38
39
  }
39
40
  },
40
41
  storeOptions: { showPhotos: true },
@@ -67,7 +68,7 @@
67
68
  "Advanced"
68
69
  ]
69
70
  });
70
- rules.infiniteScroller?.onScroll(() => {
71
+ rules.infiniteScroller?.subject.subscribe(() => {
71
72
  setTimeout(() => new LazyLoad(), 100);
72
73
  });
73
74
  _GM_addStyle(`
@@ -11,7 +11,7 @@
11
11
  // @source github:smartacephale/sleazy-fork
12
12
  // @supportURL https://github.com/smartacephale/sleazy-fork/issues
13
13
  // @match https://*.eroprofile.com/*
14
- // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.9/dist/core/pervertmonkey.core.umd.js
14
+ // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.10/dist/core/pervertmonkey.core.umd.js
15
15
  // @require data:application/javascript,var core = window.pervertmonkey.core || pervertmonkey.core; var utils = core;
16
16
  // @grant GM_addStyle
17
17
  // @grant unsafeWindow
@@ -22,15 +22,19 @@
22
22
  'use strict';
23
23
 
24
24
  document.querySelector(".videoGrid")?.after(document.querySelector(".clB"));
25
- new core.RulesGlobal({
25
+ new core.Rules({
26
26
  paginationStrategyOptions: {
27
27
  paginationSelector: ".boxNav2",
28
28
  searchParamSelector: "pnum"
29
29
  },
30
- titleSelector: "[title]",
31
- durationSelector: ".videoDur",
30
+ thumbs: { selector: ".video" },
31
+ thumb: {
32
+ selectors: {
33
+ title: "[title]",
34
+ duration: ".videoDur"
35
+ }
36
+ },
32
37
  containerSelector: ".videoGrid",
33
- thumbsSelector: ".video",
34
38
  customDataSelectorFns: ["filterInclude", "filterExclude", "filterDuration"],
35
39
  schemeOptions: [
36
40
  "Text Filter",
@@ -12,7 +12,7 @@
12
12
  // @supportURL https://github.com/smartacephale/sleazy-fork/issues
13
13
  // @match https://*.javhdporn.net/*
14
14
  // @match https://*.javhdporn.*/*
15
- // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.9/dist/core/pervertmonkey.core.umd.js
15
+ // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.10/dist/core/pervertmonkey.core.umd.js
16
16
  // @require data:application/javascript,var core = window.pervertmonkey.core || pervertmonkey.core; var utils = core;
17
17
  // @grant GM_addStyle
18
18
  // @grant unsafeWindow
@@ -22,11 +22,15 @@
22
22
  (function (core) {
23
23
  'use strict';
24
24
 
25
- new core.RulesGlobal({
25
+ new core.Rules({
26
26
  containerSelector: "div:has(> article)",
27
- thumbsSelector: "article.thumb-block",
28
- titleSelector: "header.entry-header",
29
- durationSelector: ".duration",
27
+ thumbs: { selector: "article.thumb-block" },
28
+ thumb: {
29
+ selectors: {
30
+ title: "header.entry-header",
31
+ duration: ".duration"
32
+ }
33
+ },
30
34
  paginationStrategyOptions: {
31
35
  pathnameSelector: /\/page\/(\d+)\/?$/
32
36
  },
@@ -15,7 +15,7 @@
15
15
  // @match https://*.missav.ws/*
16
16
  // @match https://*.missav.to/*
17
17
  // @match https://*.missav.live/*
18
- // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.9/dist/core/pervertmonkey.core.umd.js
18
+ // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.10/dist/core/pervertmonkey.core.umd.js
19
19
  // @require data:application/javascript,var core = window.pervertmonkey.core || pervertmonkey.core; var utils = core;
20
20
  // @grant GM_addStyle
21
21
  // @grant unsafeWindow
@@ -25,15 +25,19 @@
25
25
  (function (core) {
26
26
  'use strict';
27
27
 
28
- new core.RulesGlobal({
28
+ new core.Rules({
29
29
  paginationStrategyOptions: {
30
30
  paginationSelector: "nav[x-data]"
31
31
  },
32
32
  containerSelector: ".grid[x-data]",
33
- thumbsSelector: "div:has(> .thumbnail.group)",
34
- getThumbImgDataStrategy: "auto",
35
- titleSelector: "div > div > a.text-secondary",
36
- durationSelector: "div > a > span.text-xs",
33
+ thumbs: { selector: "div:has(> .thumbnail.group)" },
34
+ thumb: {
35
+ selectors: {
36
+ title: "div > div > a.text-secondary",
37
+ duration: "div > a > span.text-xs"
38
+ }
39
+ },
40
+ thumbImg: { strategy: "auto" },
37
41
  schemeOptions: ["Text Filter", "Duration Filter", "Badge", "Advanced"]
38
42
  });
39
43
 
@@ -11,7 +11,7 @@
11
11
  // @source github:smartacephale/sleazy-fork
12
12
  // @supportURL https://github.com/smartacephale/sleazy-fork/issues
13
13
  // @match https://motherless.com/*
14
- // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.9/dist/core/pervertmonkey.core.umd.js
14
+ // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.10/dist/core/pervertmonkey.core.umd.js
15
15
  // @require data:application/javascript,var core = window.pervertmonkey.core || pervertmonkey.core; var utils = core;
16
16
  // @grant GM_addElement
17
17
  // @grant GM_addStyle
@@ -28,13 +28,17 @@
28
28
 
29
29
  _unsafeWindow.__is_premium = true;
30
30
  const $ = _unsafeWindow.$;
31
- const rules = new core.RulesGlobal({
31
+ const rules = new core.Rules({
32
32
  containerSelectorLast: ".content-inner",
33
- thumbsSelector: ".thumb-container, .mobile-thumb",
34
- uploaderSelector: ".uploader",
35
- titleSelector: ".title",
36
- durationSelector: ".size",
37
- getThumbImgDataStrategy: "auto",
33
+ thumbs: { selector: ".thumb-container, .mobile-thumb" },
34
+ thumb: {
35
+ selectors: {
36
+ uploader: ".uploader",
37
+ title: ".title",
38
+ duration: ".size"
39
+ }
40
+ },
41
+ thumbImg: { strategy: "auto" },
38
42
  paginationStrategyOptions: {
39
43
  paginationSelector: ".pagination_link, .ml-pagination"
40
44
  },
@@ -11,7 +11,7 @@
11
11
  // @source github:smartacephale/sleazy-fork
12
12
  // @supportURL https://github.com/smartacephale/sleazy-fork/issues
13
13
  // @match https://namethatporn.com/*
14
- // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.9/dist/core/pervertmonkey.core.umd.js
14
+ // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.10/dist/core/pervertmonkey.core.umd.js
15
15
  // @require data:application/javascript,var core = window.pervertmonkey.core || pervertmonkey.core; var utils = core;
16
16
  // @grant GM_addStyle
17
17
  // @grant unsafeWindow
@@ -23,23 +23,27 @@
23
23
 
24
24
  var _unsafeWindow = (() => typeof unsafeWindow != "undefined" ? unsafeWindow : undefined)();
25
25
 
26
- new core.RulesGlobal({
27
- thumbsSelector: ".item, .nsw_r_w",
26
+ new core.Rules({
27
+ thumbs: { selector: ".item, .nsw_r_w" },
28
28
  containerSelector: "#items_wrapper, #nsw_r",
29
- titleSelector: ".item_title, .nsw_r_tit",
30
- uploaderSelector: ".item_answer b, .nsw_r_desc",
29
+ thumb: {
30
+ selectors: {
31
+ title: ".item_title, .nsw_r_tit",
32
+ uploader: ".item_answer b, .nsw_r_desc",
33
+ solved: {
34
+ type: "boolean",
35
+ selector: ".item_solved, .nsw_r_slvd"
36
+ }
37
+ }
38
+ },
39
+ thumbImg: {
40
+ strategy: "auto",
41
+ selector: (img) => img.getAttribute("data-dyn")?.concat(".webp") || img.getAttribute("src")
42
+ },
31
43
  paginationStrategyOptions: {
32
44
  paginationSelector: "#smi_wrp, #nsw_p"
33
45
  },
34
- customThumbDataSelectors: {
35
- solved: {
36
- type: "boolean",
37
- selector: ".item_solved, .nsw_r_slvd"
38
- }
39
- },
40
46
  gropeStrategy: "all-in-all",
41
- getThumbImgDataStrategy: "auto",
42
- getThumbImgDataAttrSelector: (img) => img.getAttribute("data-dyn")?.concat(".webp") || img.getAttribute("src"),
43
47
  customDataSelectorFns: [
44
48
  "filterInclude",
45
49
  "filterExclude",
@@ -12,7 +12,7 @@
12
12
  // @supportURL https://github.com/smartacephale/sleazy-fork/issues
13
13
  // @match https://*.nhentai.net/*
14
14
  // @match https://*.nhentai.*/*
15
- // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.9/dist/core/pervertmonkey.core.umd.js
15
+ // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.10/dist/core/pervertmonkey.core.umd.js
16
16
  // @require data:application/javascript,var core = window.pervertmonkey.core || pervertmonkey.core; var utils = core;
17
17
  // @grant GM_addStyle
18
18
  // @grant unsafeWindow
@@ -24,12 +24,18 @@
24
24
 
25
25
  const IS_TITLE_PAGE = /^\/g\/\d+/.test(location.pathname);
26
26
  const IS_SEARCH_PAGE = /^\/search\//.test(location.pathname);
27
- const nhentaiRules = new core.RulesGlobal({
28
- getThumbImgDataAttrDelete: "auto",
29
- getThumbImgDataStrategy: "auto",
30
- thumbsSelector: ".gallery",
27
+ const nhentaiRules = new core.Rules({
28
+ thumbs: { selector: ".gallery" },
29
+ thumb: {
30
+ selectors: {
31
+ title: ".caption"
32
+ }
33
+ },
34
+ thumbImg: {
35
+ strategy: "auto",
36
+ shouldDelete: "auto"
37
+ },
31
38
  containerSelectorLast: ".index-container, .container",
32
- titleSelector: ".caption",
33
39
  customDataSelectorFns: ["filterInclude", "filterExclude"],
34
40
  schemeOptions: ["Text Filter", "Badge", "Advanced"],
35
41
  gropeStrategy: "all-in-all"
@@ -12,7 +12,7 @@
12
12
  // @supportURL https://github.com/smartacephale/sleazy-fork/issues
13
13
  // @match https://*.obmenvsem.com/*
14
14
  // @match https://*.obmenvsem.*/*
15
- // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.9/dist/core/pervertmonkey.core.umd.js
15
+ // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.10/dist/core/pervertmonkey.core.umd.js
16
16
  // @require data:application/javascript,var core = window.pervertmonkey.core || pervertmonkey.core; var utils = core;
17
17
  // @grant GM_addStyle
18
18
  // @grant unsafeWindow
@@ -24,12 +24,6 @@
24
24
 
25
25
  var _GM_addStyle = (() => typeof GM_addStyle != "undefined" ? GM_addStyle : undefined)();
26
26
 
27
- var Pe=Object.defineProperty;var a=(e,t)=>Pe(e,"name",{value:t,configurable:true});var P=class{type=3;name="";prefix="";value="";suffix="";modifier=3;constructor(t,r,n,c,l,f){this.type=t,this.name=r,this.prefix=n,this.value=c,this.suffix=l,this.modifier=f;}hasCustomName(){return this.name!==""&&typeof this.name!="number"}};a(P,"Part");var Re=/[$_\p{ID_Start}]/u,Ee=/[$_\u200C\u200D\p{ID_Continue}]/u,v=".*";function Oe(e,t){return (t?/^[\x00-\xFF]*$/:/^[\x00-\x7F]*$/).test(e)}a(Oe,"isASCII");function D(e,t=false){let r=[],n=0;for(;n<e.length;){let c=e[n],l=a(function(f){if(!t)throw new TypeError(f);r.push({type:"INVALID_CHAR",index:n,value:e[n++]});},"ErrorOrInvalid");if(c==="*"){r.push({type:"ASTERISK",index:n,value:e[n++]});continue}if(c==="+"||c==="?"){r.push({type:"OTHER_MODIFIER",index:n,value:e[n++]});continue}if(c==="\\"){r.push({type:"ESCAPED_CHAR",index:n++,value:e[n++]});continue}if(c==="{"){r.push({type:"OPEN",index:n,value:e[n++]});continue}if(c==="}"){r.push({type:"CLOSE",index:n,value:e[n++]});continue}if(c===":"){let f="",s=n+1;for(;s<e.length;){let i=e.substr(s,1);if(s===n+1&&Re.test(i)||s!==n+1&&Ee.test(i)){f+=e[s++];continue}break}if(!f){l(`Missing parameter name at ${n}`);continue}r.push({type:"NAME",index:n,value:f}),n=s;continue}if(c==="("){let f=1,s="",i=n+1,o=false;if(e[i]==="?"){l(`Pattern cannot start with "?" at ${i}`);continue}for(;i<e.length;){if(!Oe(e[i],false)){l(`Invalid character '${e[i]}' at ${i}.`),o=true;break}if(e[i]==="\\"){s+=e[i++]+e[i++];continue}if(e[i]===")"){if(f--,f===0){i++;break}}else if(e[i]==="("&&(f++,e[i+1]!=="?")){l(`Capturing groups are not allowed at ${i}`),o=true;break}s+=e[i++];}if(o)continue;if(f){l(`Unbalanced pattern at ${n}`);continue}if(!s){l(`Missing pattern at ${n}`);continue}r.push({type:"REGEX",index:n,value:s}),n=i;continue}r.push({type:"CHAR",index:n,value:e[n++]});}return r.push({type:"END",index:n,value:""}),r}a(D,"lexer");function F(e,t={}){let r=D(e);t.delimiter??="/#?",t.prefixes??="./";let n=`[^${x(t.delimiter)}]+?`,c=[],l=0,f=0,i=new Set,o=a(u=>{if(f<r.length&&r[f].type===u)return r[f++].value},"tryConsume"),h=a(()=>o("OTHER_MODIFIER")??o("ASTERISK"),"tryConsumeModifier"),p=a(u=>{let d=o(u);if(d!==void 0)return d;let{type:g,index:y}=r[f];throw new TypeError(`Unexpected ${g} at ${y}, expected ${u}`)},"mustConsume"),A=a(()=>{let u="",d;for(;d=o("CHAR")??o("ESCAPED_CHAR");)u+=d;return u},"consumeText"),xe=a(u=>u,"DefaultEncodePart"),N=t.encodePart||xe,H="",$=a(u=>{H+=u;},"appendToPendingFixedValue"),M=a(()=>{H.length&&(c.push(new P(3,"","",N(H),"",3)),H="");},"maybeAddPartFromPendingFixedValue"),X=a((u,d,g,y,Z)=>{let m=3;switch(Z){case "?":m=1;break;case "*":m=0;break;case "+":m=2;break}if(!d&&!g&&m===3){$(u);return}if(M(),!d&&!g){if(!u)return;c.push(new P(3,"","",N(u),"",m));return}let S;g?g==="*"?S=v:S=g:S=n;let k=2;S===n?(k=1,S=""):S===v&&(k=0,S="");let E;if(d?E=d:g&&(E=l++),i.has(E))throw new TypeError(`Duplicate name '${E}'.`);i.add(E),c.push(new P(k,E,N(u),S,N(y),m));},"addPart");for(;f<r.length;){let u=o("CHAR"),d=o("NAME"),g=o("REGEX");if(!d&&!g&&(g=o("ASTERISK")),d||g){let m=u??"";t.prefixes.indexOf(m)===-1&&($(m),m=""),M();let S=h();X(m,d,g,"",S);continue}let y=u??o("ESCAPED_CHAR");if(y){$(y);continue}if(o("OPEN")){let m=A(),S=o("NAME"),k=o("REGEX");!S&&!k&&(k=o("ASTERISK"));let E=A();p("CLOSE");let be=h();X(m,S,k,E,be);continue}M(),p("END");}return c}a(F,"parse");function x(e){return e.replace(/([.+*?^${}()[\]|/\\])/g,"\\$1")}a(x,"escapeString");function B(e){return e&&e.ignoreCase?"ui":"u"}a(B,"flags");function q(e,t,r){return W(F(e,r),t,r)}a(q,"stringToRegexp");function T(e){switch(e){case 0:return "*";case 1:return "?";case 2:return "+";case 3:return ""}}a(T,"modifierToString");function W(e,t,r={}){r.delimiter??="/#?",r.prefixes??="./",r.sensitive??=false,r.strict??=false,r.end??=true,r.start??=true,r.endsWith="";let n=r.start?"^":"";for(let s of e){if(s.type===3){s.modifier===3?n+=x(s.value):n+=`(?:${x(s.value)})${T(s.modifier)}`;continue}t&&t.push(s.name);let i=`[^${x(r.delimiter)}]+?`,o=s.value;if(s.type===1?o=i:s.type===0&&(o=v),!s.prefix.length&&!s.suffix.length){s.modifier===3||s.modifier===1?n+=`(${o})${T(s.modifier)}`:n+=`((?:${o})${T(s.modifier)})`;continue}if(s.modifier===3||s.modifier===1){n+=`(?:${x(s.prefix)}(${o})${x(s.suffix)})`,n+=T(s.modifier);continue}n+=`(?:${x(s.prefix)}`,n+=`((?:${o})(?:`,n+=x(s.suffix),n+=x(s.prefix),n+=`(?:${o}))*)${x(s.suffix)})`,s.modifier===0&&(n+="?");}let c=`[${x(r.endsWith)}]|$`,l=`[${x(r.delimiter)}]`;if(r.end)return r.strict||(n+=`${l}?`),r.endsWith.length?n+=`(?=${c})`:n+="$",new RegExp(n,B(r));r.strict||(n+=`(?:${l}(?=${c}))?`);let f=false;if(e.length){let s=e[e.length-1];s.type===3&&s.modifier===3&&(f=r.delimiter.indexOf(s)>-1);}return f||(n+=`(?=${l}|${c})`),new RegExp(n,B(r))}a(W,"partsToRegexp");var b={delimiter:"",prefixes:"",sensitive:true,strict:true},J={delimiter:".",prefixes:"",sensitive:true,strict:true},Q={delimiter:"/",prefixes:"/",sensitive:true,strict:true};function ee(e,t){return e.length?e[0]==="/"?true:!t||e.length<2?false:(e[0]=="\\"||e[0]=="{")&&e[1]=="/":false}a(ee,"isAbsolutePathname");function te(e,t){return e.startsWith(t)?e.substring(t.length,e.length):e}a(te,"maybeStripPrefix");function ke(e,t){return e.endsWith(t)?e.substr(0,e.length-t.length):e}a(ke,"maybeStripSuffix");function _(e){return !e||e.length<2?false:e[0]==="["||(e[0]==="\\"||e[0]==="{")&&e[1]==="["}a(_,"treatAsIPv6Hostname");var re=["ftp","file","http","https","ws","wss"];function U(e){if(!e)return true;for(let t of re)if(e.test(t))return true;return false}a(U,"isSpecialScheme");function ne(e,t){if(e=te(e,"#"),t||e==="")return e;let r=new URL("https://example.com");return r.hash=e,r.hash?r.hash.substring(1,r.hash.length):""}a(ne,"canonicalizeHash");function se(e,t){if(e=te(e,"?"),t||e==="")return e;let r=new URL("https://example.com");return r.search=e,r.search?r.search.substring(1,r.search.length):""}a(se,"canonicalizeSearch");function ie(e,t){return t||e===""?e:_(e)?K(e):j(e)}a(ie,"canonicalizeHostname");function ae(e,t){if(t||e==="")return e;let r=new URL("https://example.com");return r.password=e,r.password}a(ae,"canonicalizePassword");function oe(e,t){if(t||e==="")return e;let r=new URL("https://example.com");return r.username=e,r.username}a(oe,"canonicalizeUsername");function ce(e,t,r){if(r||e==="")return e;if(t&&!re.includes(t))return new URL(`${t}:${e}`).pathname;let n=e[0]=="/";return e=new URL(n?e:"/-"+e,"https://example.com").pathname,n||(e=e.substring(2,e.length)),e}a(ce,"canonicalizePathname");function le(e,t,r){return z(t)===e&&(e=""),r||e===""?e:G(e)}a(le,"canonicalizePort");function fe(e,t){return e=ke(e,":"),t||e===""?e:w(e)}a(fe,"canonicalizeProtocol");function z(e){switch(e){case "ws":case "http":return "80";case "wws":case "https":return "443";case "ftp":return "21";default:return ""}}a(z,"defaultPortForProtocol");function w(e){if(e==="")return e;if(/^[-+.A-Za-z0-9]*$/.test(e))return e.toLowerCase();throw new TypeError(`Invalid protocol '${e}'.`)}a(w,"protocolEncodeCallback");function he(e){if(e==="")return e;let t=new URL("https://example.com");return t.username=e,t.username}a(he,"usernameEncodeCallback");function ue(e){if(e==="")return e;let t=new URL("https://example.com");return t.password=e,t.password}a(ue,"passwordEncodeCallback");function j(e){if(e==="")return e;if(/[\t\n\r #%/:<>?@[\]^\\|]/g.test(e))throw new TypeError(`Invalid hostname '${e}'`);let t=new URL("https://example.com");return t.hostname=e,t.hostname}a(j,"hostnameEncodeCallback");function K(e){if(e==="")return e;if(/[^0-9a-fA-F[\]:]/g.test(e))throw new TypeError(`Invalid IPv6 hostname '${e}'`);return e.toLowerCase()}a(K,"ipv6HostnameEncodeCallback");function G(e){if(e===""||/^[0-9]*$/.test(e)&&parseInt(e)<=65535)return e;throw new TypeError(`Invalid port '${e}'.`)}a(G,"portEncodeCallback");function de(e){if(e==="")return e;let t=new URL("https://example.com");return t.pathname=e[0]!=="/"?"/-"+e:e,e[0]!=="/"?t.pathname.substring(2,t.pathname.length):t.pathname}a(de,"standardURLPathnameEncodeCallback");function pe(e){return e===""?e:new URL(`data:${e}`).pathname}a(pe,"pathURLPathnameEncodeCallback");function ge(e){if(e==="")return e;let t=new URL("https://example.com");return t.search=e,t.search.substring(1,t.search.length)}a(ge,"searchEncodeCallback");function me(e){if(e==="")return e;let t=new URL("https://example.com");return t.hash=e,t.hash.substring(1,t.hash.length)}a(me,"hashEncodeCallback");var C=class{#i;#n=[];#t={};#e=0;#s=1;#l=0;#o=0;#d=0;#p=0;#g=false;constructor(t){this.#i=t;}get result(){return this.#t}parse(){for(this.#n=D(this.#i,true);this.#e<this.#n.length;this.#e+=this.#s){if(this.#s=1,this.#n[this.#e].type==="END"){if(this.#o===0){this.#b(),this.#f()?this.#r(9,1):this.#h()?this.#r(8,1):this.#r(7,0);continue}else if(this.#o===2){this.#u(5);continue}this.#r(10,0);break}if(this.#d>0)if(this.#A())this.#d-=1;else continue;if(this.#T()){this.#d+=1;continue}switch(this.#o){case 0:this.#P()&&this.#u(1);break;case 1:if(this.#P()){this.#C();let t=7,r=1;this.#E()?(t=2,r=3):this.#g&&(t=2),this.#r(t,r);}break;case 2:this.#S()?this.#u(3):(this.#x()||this.#h()||this.#f())&&this.#u(5);break;case 3:this.#O()?this.#r(4,1):this.#S()&&this.#r(5,1);break;case 4:this.#S()&&this.#r(5,1);break;case 5:this.#y()?this.#p+=1:this.#w()&&(this.#p-=1),this.#k()&&!this.#p?this.#r(6,1):this.#x()?this.#r(7,0):this.#h()?this.#r(8,1):this.#f()&&this.#r(9,1);break;case 6:this.#x()?this.#r(7,0):this.#h()?this.#r(8,1):this.#f()&&this.#r(9,1);break;case 7:this.#h()?this.#r(8,1):this.#f()&&this.#r(9,1);break;case 8:this.#f()&&this.#r(9,1);break;}}this.#t.hostname!==void 0&&this.#t.port===void 0&&(this.#t.port="");}#r(t,r){switch(this.#o){case 0:break;case 1:this.#t.protocol=this.#c();break;case 2:break;case 3:this.#t.username=this.#c();break;case 4:this.#t.password=this.#c();break;case 5:this.#t.hostname=this.#c();break;case 6:this.#t.port=this.#c();break;case 7:this.#t.pathname=this.#c();break;case 8:this.#t.search=this.#c();break;case 9:this.#t.hash=this.#c();break;}this.#o!==0&&t!==10&&([1,2,3,4].includes(this.#o)&&[6,7,8,9].includes(t)&&(this.#t.hostname??=""),[1,2,3,4,5,6].includes(this.#o)&&[8,9].includes(t)&&(this.#t.pathname??=this.#g?"/":""),[1,2,3,4,5,6,7].includes(this.#o)&&t===9&&(this.#t.search??="")),this.#R(t,r);}#R(t,r){this.#o=t,this.#l=this.#e+r,this.#e+=r,this.#s=0;}#b(){this.#e=this.#l,this.#s=0;}#u(t){this.#b(),this.#o=t;}#m(t){return t<0&&(t=this.#n.length-t),t<this.#n.length?this.#n[t]:this.#n[this.#n.length-1]}#a(t,r){let n=this.#m(t);return n.value===r&&(n.type==="CHAR"||n.type==="ESCAPED_CHAR"||n.type==="INVALID_CHAR")}#P(){return this.#a(this.#e,":")}#E(){return this.#a(this.#e+1,"/")&&this.#a(this.#e+2,"/")}#S(){return this.#a(this.#e,"@")}#O(){return this.#a(this.#e,":")}#k(){return this.#a(this.#e,":")}#x(){return this.#a(this.#e,"/")}#h(){if(this.#a(this.#e,"?"))return true;if(this.#n[this.#e].value!=="?")return false;let t=this.#m(this.#e-1);return t.type!=="NAME"&&t.type!=="REGEX"&&t.type!=="CLOSE"&&t.type!=="ASTERISK"}#f(){return this.#a(this.#e,"#")}#T(){return this.#n[this.#e].type=="OPEN"}#A(){return this.#n[this.#e].type=="CLOSE"}#y(){return this.#a(this.#e,"[")}#w(){return this.#a(this.#e,"]")}#c(){let t=this.#n[this.#e],r=this.#m(this.#l).index;return this.#i.substring(r,t.index)}#C(){let t={};Object.assign(t,b),t.encodePart=w;let r=q(this.#c(),void 0,t);this.#g=U(r);}};a(C,"Parser");var V=["protocol","username","password","hostname","port","pathname","search","hash"],O="*";function Se(e,t){if(typeof e!="string")throw new TypeError("parameter 1 is not of type 'string'.");let r=new URL(e,t);return {protocol:r.protocol.substring(0,r.protocol.length-1),username:r.username,password:r.password,hostname:r.hostname,port:r.port,pathname:r.pathname,search:r.search!==""?r.search.substring(1,r.search.length):void 0,hash:r.hash!==""?r.hash.substring(1,r.hash.length):void 0}}a(Se,"extractValues");function R(e,t){return t?I(e):e}a(R,"processBaseURLString");function L(e,t,r){let n;if(typeof t.baseURL=="string")try{n=new URL(t.baseURL),t.protocol===void 0&&(e.protocol=R(n.protocol.substring(0,n.protocol.length-1),r)),!r&&t.protocol===void 0&&t.hostname===void 0&&t.port===void 0&&t.username===void 0&&(e.username=R(n.username,r)),!r&&t.protocol===void 0&&t.hostname===void 0&&t.port===void 0&&t.username===void 0&&t.password===void 0&&(e.password=R(n.password,r)),t.protocol===void 0&&t.hostname===void 0&&(e.hostname=R(n.hostname,r)),t.protocol===void 0&&t.hostname===void 0&&t.port===void 0&&(e.port=R(n.port,r)),t.protocol===void 0&&t.hostname===void 0&&t.port===void 0&&t.pathname===void 0&&(e.pathname=R(n.pathname,r)),t.protocol===void 0&&t.hostname===void 0&&t.port===void 0&&t.pathname===void 0&&t.search===void 0&&(e.search=R(n.search.substring(1,n.search.length),r)),t.protocol===void 0&&t.hostname===void 0&&t.port===void 0&&t.pathname===void 0&&t.search===void 0&&t.hash===void 0&&(e.hash=R(n.hash.substring(1,n.hash.length),r));}catch{throw new TypeError(`invalid baseURL '${t.baseURL}'.`)}if(typeof t.protocol=="string"&&(e.protocol=fe(t.protocol,r)),typeof t.username=="string"&&(e.username=oe(t.username,r)),typeof t.password=="string"&&(e.password=ae(t.password,r)),typeof t.hostname=="string"&&(e.hostname=ie(t.hostname,r)),typeof t.port=="string"&&(e.port=le(t.port,e.protocol,r)),typeof t.pathname=="string"){if(e.pathname=t.pathname,n&&!ee(e.pathname,r)){let c=n.pathname.lastIndexOf("/");c>=0&&(e.pathname=R(n.pathname.substring(0,c+1),r)+e.pathname);}e.pathname=ce(e.pathname,e.protocol,r);}return typeof t.search=="string"&&(e.search=se(t.search,r)),typeof t.hash=="string"&&(e.hash=ne(t.hash,r)),e}a(L,"applyInit");function I(e){return e.replace(/([+*?:{}()\\])/g,"\\$1")}a(I,"escapePatternString");function Te(e){return e.replace(/([.+*?^${}()[\]|/\\])/g,"\\$1")}a(Te,"escapeRegexpString");function Ae(e,t){t.delimiter??="/#?",t.prefixes??="./",t.sensitive??=false,t.strict??=false,t.end??=true,t.start??=true,t.endsWith="";let r=".*",n=`[^${Te(t.delimiter)}]+?`,c=/[$_\u200C\u200D\p{ID_Continue}]/u,l="";for(let f=0;f<e.length;++f){let s=e[f];if(s.type===3){if(s.modifier===3){l+=I(s.value);continue}l+=`{${I(s.value)}}${T(s.modifier)}`;continue}let i=s.hasCustomName(),o=!!s.suffix.length||!!s.prefix.length&&(s.prefix.length!==1||!t.prefixes.includes(s.prefix)),h=f>0?e[f-1]:null,p=f<e.length-1?e[f+1]:null;if(!o&&i&&s.type===1&&s.modifier===3&&p&&!p.prefix.length&&!p.suffix.length)if(p.type===3){let A=p.value.length>0?p.value[0]:"";o=c.test(A);}else o=!p.hasCustomName();if(!o&&!s.prefix.length&&h&&h.type===3){let A=h.value[h.value.length-1];o=t.prefixes.includes(A);}o&&(l+="{"),l+=I(s.prefix),i&&(l+=`:${s.name}`),s.type===2?l+=`(${s.value})`:s.type===1?i||(l+=`(${n})`):s.type===0&&(!i&&(!h||h.type===3||h.modifier!==3||o||s.prefix!=="")?l+="*":l+=`(${r})`),s.type===1&&i&&s.suffix.length&&c.test(s.suffix[0])&&(l+="\\"),l+=I(s.suffix),o&&(l+="}"),s.modifier!==3&&(l+=T(s.modifier));}return l}a(Ae,"partsToPattern");var Y=class{#i;#n={};#t={};#e={};#s={};#l=false;constructor(t={},r,n){try{let c;if(typeof r=="string"?c=r:n=r,typeof t=="string"){let i=new C(t);if(i.parse(),t=i.result,c===void 0&&typeof t.protocol!="string")throw new TypeError("A base URL must be provided for a relative constructor string.");t.baseURL=c;}else {if(!t||typeof t!="object")throw new TypeError("parameter 1 is not of type 'string' and cannot convert to dictionary.");if(c)throw new TypeError("parameter 1 is not of type 'string'.")}typeof n>"u"&&(n={ignoreCase:!1});let l={ignoreCase:n.ignoreCase===!0},f={pathname:O,protocol:O,username:O,password:O,hostname:O,port:O,search:O,hash:O};this.#i=L(f,t,!0),z(this.#i.protocol)===this.#i.port&&(this.#i.port="");let s;for(s of V){if(!(s in this.#i))continue;let i={},o=this.#i[s];switch(this.#t[s]=[],s){case "protocol":Object.assign(i,b),i.encodePart=w;break;case "username":Object.assign(i,b),i.encodePart=he;break;case "password":Object.assign(i,b),i.encodePart=ue;break;case "hostname":Object.assign(i,J),_(o)?i.encodePart=K:i.encodePart=j;break;case "port":Object.assign(i,b),i.encodePart=G;break;case "pathname":U(this.#n.protocol)?(Object.assign(i,Q,l),i.encodePart=de):(Object.assign(i,b,l),i.encodePart=pe);break;case "search":Object.assign(i,b,l),i.encodePart=ge;break;case "hash":Object.assign(i,b,l),i.encodePart=me;break}try{this.#s[s]=F(o,i),this.#n[s]=W(this.#s[s],this.#t[s],i),this.#e[s]=Ae(this.#s[s],i),this.#l=this.#l||this.#s[s].some(h=>h.type===2);}catch{throw new TypeError(`invalid ${s} pattern '${this.#i[s]}'.`)}}}catch(c){throw new TypeError(`Failed to construct 'URLPattern': ${c.message}`)}}get[Symbol.toStringTag](){return "URLPattern"}test(t={},r){let n={pathname:"",protocol:"",username:"",password:"",hostname:"",port:"",search:"",hash:""};if(typeof t!="string"&&r)throw new TypeError("parameter 1 is not of type 'string'.");if(typeof t>"u")return false;try{typeof t=="object"?n=L(n,t,!1):n=L(n,Se(t,r),!1);}catch{return false}let c;for(c of V)if(!this.#n[c].exec(n[c]))return false;return true}exec(t={},r){let n={pathname:"",protocol:"",username:"",password:"",hostname:"",port:"",search:"",hash:""};if(typeof t!="string"&&r)throw new TypeError("parameter 1 is not of type 'string'.");if(typeof t>"u")return;try{typeof t=="object"?n=L(n,t,!1):n=L(n,Se(t,r),!1);}catch{return null}let c={};r?c.inputs=[t,r]:c.inputs=[t];let l;for(l of V){let f=this.#n[l].exec(n[l]);if(!f)return null;let s={};for(let[i,o]of this.#t[l].entries())if(typeof o=="string"||typeof o=="number"){let h=f[i+1];s[o]=h;}c[l]={input:n[l]??"",groups:s};}return c}static compareComponent(t,r,n){let c=a((i,o)=>{for(let h of ["type","modifier","prefix","value","suffix"]){if(i[h]<o[h])return -1;if(i[h]===o[h])continue;return 1}return 0},"comparePart"),l=new P(3,"","","","",3),f=new P(0,"","","","",3),s=a((i,o)=>{let h=0;for(;h<Math.min(i.length,o.length);++h){let p=c(i[h],o[h]);if(p)return p}return i.length===o.length?0:c(i[h]??l,o[h]??l)},"comparePartList");return !r.#e[t]&&!n.#e[t]?0:r.#e[t]&&!n.#e[t]?s(r.#s[t],[f]):!r.#e[t]&&n.#e[t]?s([f],n.#s[t]):s(r.#s[t],n.#s[t])}get protocol(){return this.#e.protocol}get username(){return this.#e.username}get password(){return this.#e.password}get hostname(){return this.#e.hostname}get port(){return this.#e.port}get pathname(){return this.#e.pathname}get search(){return this.#e.search}get hash(){return this.#e.hash}get hasRegExpGroups(){return this.#l}};a(Y,"URLPattern");
28
-
29
- function parseUrl(s) {
30
- return new URL(typeof s === "string" ? s : s.href);
31
- }
32
-
33
27
  const IS_USER_FILES = location.pathname.startsWith("/user_files");
34
28
  const SEARCH_PARAM = IS_USER_FILES ? "start" : "page";
35
29
  function setup() {
@@ -42,10 +36,10 @@
42
36
  _GM_addStyle("a.block[href *= info] > img:first-child { height: 240px; }");
43
37
  }
44
38
  setup();
45
- new core.RulesGlobal({
39
+ new core.Rules({
46
40
  paginationStrategyOptions: {
47
41
  getPaginationUrlGenerator() {
48
- const url = parseUrl(location.href);
42
+ const url = utils.parseUrl(location.href);
49
43
  return (offset) => {
50
44
  const offsetValue = IS_USER_FILES ? offset * 24 : offset;
51
45
  url.searchParams.set(SEARCH_PARAM, offsetValue.toString());
@@ -57,16 +51,18 @@
57
51
  paginationSelector: ".item.pages, .pagination"
58
52
  },
59
53
  containerSelectorLast: ".container",
60
- thumbsSelector: ".item:has(> a.block[href *= info] > img)",
61
- getThumbImgDataAttrSelector(img) {
62
- const url = img.closest("a").href;
63
- utils.fetchHtml(url).then((dom) => {
64
- img.src = dom.querySelector("img[src*=attach]")?.src || img.src;
65
- });
66
- return img.src;
54
+ thumbs: { selector: ".item:has(> a.block[href *= info] > img)" },
55
+ thumb: { strategy: "auto-text" },
56
+ thumbImg: {
57
+ strategy: "auto",
58
+ selector: (img) => {
59
+ const url = img.closest("a").href;
60
+ utils.fetchHtml(url).then((dom) => {
61
+ img.src = dom.querySelector("img[src*=attach]")?.src || img.src;
62
+ });
63
+ return img.src;
64
+ }
67
65
  },
68
- getThumbImgDataStrategy: "auto",
69
- getThumbDataStrategy: "auto-text",
70
66
  schemeOptions: ["Text Filter", "Duration Filter", "Badge", "Advanced"]
71
67
  });
72
68
 
@@ -12,7 +12,7 @@
12
12
  // @supportURL https://github.com/smartacephale/sleazy-fork/issues
13
13
  // @match https://*.pornhub.com/*
14
14
  // @exclude https://*.pornhub.com/embed/*
15
- // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.9/dist/core/pervertmonkey.core.umd.js
15
+ // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.10/dist/core/pervertmonkey.core.umd.js
16
16
  // @require data:application/javascript,var core = window.pervertmonkey.core || pervertmonkey.core; var utils = core;
17
17
  // @grant GM_addStyle
18
18
  // @grant unsafeWindow
@@ -22,21 +22,25 @@
22
22
  (function (core) {
23
23
  'use strict';
24
24
 
25
- new core.RulesGlobal({
25
+ new core.Rules({
26
26
  paginationStrategyOptions: {
27
27
  paginationSelector: ".paginationGated",
28
28
  overwritePaginationLast: (n) => n === 9 ? 999 : n
29
29
  },
30
30
  containerSelector: () => [...document.querySelectorAll("ul:has(> li[data-video-vkey])")].filter((e) => e.children.length > 0 && e.checkVisibility()).pop(),
31
- dataManagerOptions: {
32
- parseDataParentHomogenity: { id: true, className: true }
31
+ dataHomogenity: { id: true, className: true },
32
+ thumbs: { selector: "li[data-video-vkey]" },
33
+ thumb: {
34
+ selectors: {
35
+ title: "span.title",
36
+ uploader: ".usernameWrap",
37
+ duration: ".duration"
38
+ }
39
+ },
40
+ thumbImg: {
41
+ strategy: "auto",
42
+ selector: ["data-mediumthumb", "data-image"]
33
43
  },
34
- thumbsSelector: "li[data-video-vkey]",
35
- getThumbImgDataStrategy: "auto",
36
- getThumbImgDataAttrSelector: ["data-mediumthumb", "data-image"],
37
- uploaderSelector: ".usernameWrap",
38
- titleSelector: "span.title",
39
- durationSelector: ".duration",
40
44
  gropeStrategy: "all-in-all",
41
45
  schemeOptions: ["Text Filter", "Duration Filter", "Badge", "Advanced"]
42
46
  });