@amatiscorp/disguard 1.4.0 → 1.6.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 (83) hide show
  1. package/README.md +309 -14
  2. package/dist/AntiSpam.d.ts +9 -1
  3. package/dist/AntiSpam.d.ts.map +1 -1
  4. package/dist/AntiSpam.js +155 -2
  5. package/dist/AntiSpam.js.map +1 -1
  6. package/dist/defaults.d.ts.map +1 -1
  7. package/dist/defaults.js +95 -1
  8. package/dist/defaults.js.map +1 -1
  9. package/dist/detectors/blank.d.ts +3 -0
  10. package/dist/detectors/blank.d.ts.map +1 -0
  11. package/dist/detectors/blank.js +25 -0
  12. package/dist/detectors/blank.js.map +1 -0
  13. package/dist/detectors/embed.d.ts +3 -0
  14. package/dist/detectors/embed.d.ts.map +1 -0
  15. package/dist/detectors/embed.js +25 -0
  16. package/dist/detectors/embed.js.map +1 -0
  17. package/dist/detectors/emojis.d.ts.map +1 -1
  18. package/dist/detectors/emojis.js +19 -1
  19. package/dist/detectors/emojis.js.map +1 -1
  20. package/dist/detectors/files.d.ts.map +1 -1
  21. package/dist/detectors/files.js +29 -1
  22. package/dist/detectors/files.js.map +1 -1
  23. package/dist/detectors/forward.d.ts +3 -0
  24. package/dist/detectors/forward.d.ts.map +1 -0
  25. package/dist/detectors/forward.js +35 -0
  26. package/dist/detectors/forward.js.map +1 -0
  27. package/dist/detectors/ghost.d.ts.map +1 -1
  28. package/dist/detectors/ghost.js +7 -0
  29. package/dist/detectors/ghost.js.map +1 -1
  30. package/dist/detectors/impersonate.d.ts +3 -0
  31. package/dist/detectors/impersonate.d.ts.map +1 -0
  32. package/dist/detectors/impersonate.js +86 -0
  33. package/dist/detectors/impersonate.js.map +1 -0
  34. package/dist/detectors/joins.d.ts +4 -0
  35. package/dist/detectors/joins.d.ts.map +1 -0
  36. package/dist/detectors/joins.js +30 -0
  37. package/dist/detectors/joins.js.map +1 -0
  38. package/dist/detectors/polls.d.ts +3 -0
  39. package/dist/detectors/polls.d.ts.map +1 -0
  40. package/dist/detectors/polls.js +35 -0
  41. package/dist/detectors/polls.js.map +1 -0
  42. package/dist/detectors/raid.d.ts +3 -0
  43. package/dist/detectors/raid.d.ts.map +1 -0
  44. package/dist/detectors/raid.js +23 -0
  45. package/dist/detectors/raid.js.map +1 -0
  46. package/dist/detectors/replies.d.ts +3 -0
  47. package/dist/detectors/replies.d.ts.map +1 -0
  48. package/dist/detectors/replies.js +32 -0
  49. package/dist/detectors/replies.js.map +1 -0
  50. package/dist/detectors/stickers.d.ts +3 -0
  51. package/dist/detectors/stickers.d.ts.map +1 -0
  52. package/dist/detectors/stickers.js +60 -0
  53. package/dist/detectors/stickers.js.map +1 -0
  54. package/dist/detectors/voice.d.ts +3 -0
  55. package/dist/detectors/voice.d.ts.map +1 -0
  56. package/dist/detectors/voice.js +35 -0
  57. package/dist/detectors/voice.js.map +1 -0
  58. package/dist/detectors/words.d.ts.map +1 -1
  59. package/dist/detectors/words.js +27 -3
  60. package/dist/detectors/words.js.map +1 -1
  61. package/dist/enforcement.d.ts +2 -1
  62. package/dist/enforcement.d.ts.map +1 -1
  63. package/dist/enforcement.js +100 -5
  64. package/dist/enforcement.js.map +1 -1
  65. package/dist/index.d.ts +5 -3
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +9 -1
  68. package/dist/index.js.map +1 -1
  69. package/dist/store/MemoryStore.d.ts +6 -0
  70. package/dist/store/MemoryStore.d.ts.map +1 -1
  71. package/dist/store/MemoryStore.js +44 -0
  72. package/dist/store/MemoryStore.js.map +1 -1
  73. package/dist/types.d.ts +131 -2
  74. package/dist/types.d.ts.map +1 -1
  75. package/dist/utils/flags.d.ts +5 -0
  76. package/dist/utils/flags.d.ts.map +1 -0
  77. package/dist/utils/flags.js +41 -0
  78. package/dist/utils/flags.js.map +1 -0
  79. package/dist/utils/normalize.d.ts +2 -0
  80. package/dist/utils/normalize.d.ts.map +1 -1
  81. package/dist/utils/normalize.js +46 -0
  82. package/dist/utils/normalize.js.map +1 -1
  83. package/package.json +2 -2
@@ -0,0 +1,3 @@
1
+ import type { Detector } from "../types";
2
+ export declare const embedDetector: Detector;
3
+ //# sourceMappingURL=embed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embed.d.ts","sourceRoot":"","sources":["../../src/detectors/embed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAA2B,MAAM,UAAU,CAAC;AAGlE,eAAO,MAAM,aAAa,EAAE,QAiB3B,CAAC"}
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.embedDetector = void 0;
4
+ const incident_1 = require("./incident");
5
+ exports.embedDetector = {
6
+ type: "embed",
7
+ inspect({ message, snapshot, config }) {
8
+ const rules = config.embeds;
9
+ if (!rules.enabled || !message.guild)
10
+ return null;
11
+ if (rules.maxEmbeds < 1)
12
+ return null;
13
+ if (message.embeds.length <= rules.maxEmbeds)
14
+ return null;
15
+ return (0, incident_1.createIncident)("embed", snapshot, {
16
+ userId: message.author.id,
17
+ guildId: message.guild.id,
18
+ severity: rules.severity,
19
+ reason: `Demasiados embeds (${message.embeds.length}/${rules.maxEmbeds})`,
20
+ details: { count: message.embeds.length },
21
+ recommendedActions: ["delete", "warn"],
22
+ });
23
+ },
24
+ };
25
+ //# sourceMappingURL=embed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embed.js","sourceRoot":"","sources":["../../src/detectors/embed.ts"],"names":[],"mappings":";;;AACA,yCAA4C;AAE/B,QAAA,aAAa,GAAa;IACrC,IAAI,EAAE,OAAO;IACb,OAAO,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAiB;QAClD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAClD,IAAI,KAAK,CAAC,SAAS,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QACrC,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,KAAK,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAE1D,OAAO,IAAA,yBAAc,EAAC,OAAO,EAAE,QAAQ,EAAE;YACvC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;YACzB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;YACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,MAAM,EAAE,sBAAsB,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,KAAK,CAAC,SAAS,GAAG;YACzE,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE;YACzC,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;SACvC,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"emojis.d.ts","sourceRoot":"","sources":["../../src/detectors/emojis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAA2B,MAAM,UAAU,CAAC;AAIlE,eAAO,MAAM,aAAa,EAAE,QA8B3B,CAAC"}
1
+ {"version":3,"file":"emojis.d.ts","sourceRoot":"","sources":["../../src/detectors/emojis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAA2B,MAAM,UAAU,CAAC;AAIlE,eAAO,MAAM,aAAa,EAAE,QAgD3B,CAAC"}
@@ -5,7 +5,7 @@ const normalize_1 = require("../utils/normalize");
5
5
  const incident_1 = require("./incident");
6
6
  exports.emojiDetector = {
7
7
  type: "emoji",
8
- inspect({ message, snapshot, config }) {
8
+ inspect({ message, snapshot, history, config }) {
9
9
  const rules = config.emojis;
10
10
  if (!rules.enabled || !message.guild)
11
11
  return null;
@@ -29,6 +29,24 @@ exports.emojiDetector = {
29
29
  recommendedActions: ["delete", "warn"],
30
30
  });
31
31
  }
32
+ if (rules.maxInWindow > 0) {
33
+ let total = 0;
34
+ for (const item of history) {
35
+ if (snapshot.timestamp - item.timestamp > rules.windowMs)
36
+ continue;
37
+ total += item.emojiCount ?? 0;
38
+ }
39
+ if (total > rules.maxInWindow) {
40
+ return (0, incident_1.createIncident)("emoji", snapshot, {
41
+ userId: message.author.id,
42
+ guildId: message.guild.id,
43
+ severity: rules.severity,
44
+ reason: `Demasiados emojis en la ventana (${total}/${rules.maxInWindow})`,
45
+ details: { count: total, windowMs: rules.windowMs },
46
+ recommendedActions: ["delete", "warn"],
47
+ });
48
+ }
49
+ }
32
50
  return null;
33
51
  },
34
52
  };
@@ -1 +1 @@
1
- {"version":3,"file":"emojis.js","sourceRoot":"","sources":["../../src/detectors/emojis.ts"],"names":[],"mappings":";;;AACA,kDAAiD;AACjD,yCAA4C;AAE/B,QAAA,aAAa,GAAa;IACrC,IAAI,EAAE,OAAO;IACb,OAAO,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAiB;QAClD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAElD,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;YAC9C,OAAO,IAAA,yBAAc,EAAC,OAAO,EAAE,QAAQ,EAAE;gBACvC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;gBACzB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;gBACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,MAAM,EAAE,wBAAwB,OAAO,CAAC,QAAQ,CAAC,IAAI,IAAI,KAAK,CAAC,WAAW,GAAG;gBAC7E,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;aACvC,CAAC,CAAC;QACL,CAAC;QAED,MAAM,MAAM,GAAG,IAAA,uBAAW,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,MAAM,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;YAC7B,OAAO,IAAA,yBAAc,EAAC,OAAO,EAAE,QAAQ,EAAE;gBACvC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;gBACzB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;gBACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,MAAM,EAAE,sBAAsB,MAAM,IAAI,KAAK,CAAC,SAAS,GAAG;gBAC1D,OAAO,EAAE,EAAE,MAAM,EAAE;gBACnB,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;aACvC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"emojis.js","sourceRoot":"","sources":["../../src/detectors/emojis.ts"],"names":[],"mappings":";;;AACA,kDAAiD;AACjD,yCAA4C;AAE/B,QAAA,aAAa,GAAa;IACrC,IAAI,EAAE,OAAO;IACb,OAAO,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAiB;QAC3D,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAElD,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;YAC9C,OAAO,IAAA,yBAAc,EAAC,OAAO,EAAE,QAAQ,EAAE;gBACvC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;gBACzB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;gBACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,MAAM,EAAE,wBAAwB,OAAO,CAAC,QAAQ,CAAC,IAAI,IAAI,KAAK,CAAC,WAAW,GAAG;gBAC7E,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;aACvC,CAAC,CAAC;QACL,CAAC;QAED,MAAM,MAAM,GAAG,IAAA,uBAAW,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,MAAM,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;YAC7B,OAAO,IAAA,yBAAc,EAAC,OAAO,EAAE,QAAQ,EAAE;gBACvC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;gBACzB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;gBACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,MAAM,EAAE,sBAAsB,MAAM,IAAI,KAAK,CAAC,SAAS,GAAG;gBAC1D,OAAO,EAAE,EAAE,MAAM,EAAE;gBACnB,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;aACvC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,KAAK,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;YAC1B,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;gBAC3B,IAAI,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,QAAQ;oBAAE,SAAS;gBACnE,KAAK,IAAI,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC;YAChC,CAAC;YACD,IAAI,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;gBAC9B,OAAO,IAAA,yBAAc,EAAC,OAAO,EAAE,QAAQ,EAAE;oBACvC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;oBACzB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;oBACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,MAAM,EAAE,oCAAoC,KAAK,IAAI,KAAK,CAAC,WAAW,GAAG;oBACzE,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE;oBACnD,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;iBACvC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/detectors/files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAA2B,MAAM,UAAU,CAAC;AAGlE,eAAO,MAAM,0BAA0B,UAYtC,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,QAuC1B,CAAC"}
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/detectors/files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAA2B,MAAM,UAAU,CAAC;AAGlE,eAAO,MAAM,0BAA0B,UAYtC,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,QAuE1B,CAAC"}
@@ -25,6 +25,20 @@ exports.fileDetector = {
25
25
  for (const attachment of message.attachments.values()) {
26
26
  const name = attachment.name ?? "";
27
27
  const ext = name.includes(".") ? name.split(".").pop()?.toLowerCase() ?? "" : "";
28
+ const parts = name.toLowerCase().split(".").filter(Boolean);
29
+ if (rules.blockDoubleExtensions && parts.length > 2) {
30
+ const inner = parts.slice(0, -1);
31
+ if (inner.some((part) => blocked.has(part))) {
32
+ return (0, incident_1.createIncident)("file", snapshot, {
33
+ userId: message.author.id,
34
+ guildId: message.guild.id,
35
+ severity: rules.severity,
36
+ reason: `Doble extensión peligrosa: ${name}`,
37
+ details: { name, extension: ext, size: attachment.size },
38
+ recommendedActions: ["delete", "warn", "timeout"],
39
+ });
40
+ }
41
+ }
28
42
  if (rules.maxBytes > 0 && attachment.size > rules.maxBytes) {
29
43
  return (0, incident_1.createIncident)("file", snapshot, {
30
44
  userId: message.author.id,
@@ -35,8 +49,22 @@ exports.fileDetector = {
35
49
  recommendedActions: ["delete", "warn"],
36
50
  });
37
51
  }
38
- if (!ext || !blocked.has(ext))
52
+ if (!ext || !blocked.has(ext)) {
53
+ if (rules.allowedExtensions.length > 0) {
54
+ const allowed = new Set(rules.allowedExtensions.map((item) => item.replace(/^\./, "").toLowerCase()));
55
+ if (!ext || !allowed.has(ext)) {
56
+ return (0, incident_1.createIncident)("file", snapshot, {
57
+ userId: message.author.id,
58
+ guildId: message.guild.id,
59
+ severity: rules.severity,
60
+ reason: ext ? `Extensión no permitida: .${ext}` : "Adjunto sin extensión no permitido",
61
+ details: { name, extension: ext, size: attachment.size },
62
+ recommendedActions: ["delete", "warn"],
63
+ });
64
+ }
65
+ }
39
66
  continue;
67
+ }
40
68
  return (0, incident_1.createIncident)("file", snapshot, {
41
69
  userId: message.author.id,
42
70
  guildId: message.guild.id,
@@ -1 +1 @@
1
- {"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/detectors/files.ts"],"names":[],"mappings":";;;AACA,yCAA4C;AAE/B,QAAA,0BAA0B,GAAG;IACxC,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;CACN,CAAC;AAEW,QAAA,YAAY,GAAa;IACpC,IAAI,EAAE,MAAM;IACZ,OAAO,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAiB;QAClD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEpF,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAC7E,CAAC;QAEF,KAAK,MAAM,UAAU,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;YACtD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,IAAI,EAAE,CAAC;YACnC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAEjF,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,IAAI,UAAU,CAAC,IAAI,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC3D,OAAO,IAAA,yBAAc,EAAC,MAAM,EAAE,QAAQ,EAAE;oBACtC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;oBACzB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;oBACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,MAAM,EAAE,6BAA6B,UAAU,CAAC,IAAI,MAAM,KAAK,CAAC,QAAQ,SAAS;oBACjF,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE;oBACxC,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;iBACvC,CAAC,CAAC;YACL,CAAC;YAED,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,SAAS;YAExC,OAAO,IAAA,yBAAc,EAAC,MAAM,EAAE,QAAQ,EAAE;gBACtC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;gBACzB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;gBACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,MAAM,EAAE,0BAA0B,GAAG,EAAE;gBACvC,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE;gBACxD,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC;aAClD,CAAC,CAAC;QACL,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/detectors/files.ts"],"names":[],"mappings":";;;AACA,yCAA4C;AAE/B,QAAA,0BAA0B,GAAG;IACxC,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;CACN,CAAC;AAEW,QAAA,YAAY,GAAa;IACpC,IAAI,EAAE,MAAM;IACZ,OAAO,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAiB;QAClD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEpF,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAC7E,CAAC;QAEF,KAAK,MAAM,UAAU,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;YACtD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,IAAI,EAAE,CAAC;YACnC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjF,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAE5D,IAAI,KAAK,CAAC,qBAAqB,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBACjC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;oBAC5C,OAAO,IAAA,yBAAc,EAAC,MAAM,EAAE,QAAQ,EAAE;wBACtC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;wBACzB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;wBACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;wBACxB,MAAM,EAAE,8BAA8B,IAAI,EAAE;wBAC5C,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE;wBACxD,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC;qBAClD,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,IAAI,UAAU,CAAC,IAAI,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC3D,OAAO,IAAA,yBAAc,EAAC,MAAM,EAAE,QAAQ,EAAE;oBACtC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;oBACzB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;oBACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,MAAM,EAAE,6BAA6B,UAAU,CAAC,IAAI,MAAM,KAAK,CAAC,QAAQ,SAAS;oBACjF,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE;oBACxC,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;iBACvC,CAAC,CAAC;YACL,CAAC;YAED,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC9B,IAAI,KAAK,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACvC,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAC7E,CAAC;oBACF,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;wBAC9B,OAAO,IAAA,yBAAc,EAAC,MAAM,EAAE,QAAQ,EAAE;4BACtC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;4BACzB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;4BACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;4BACxB,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,4BAA4B,GAAG,EAAE,CAAC,CAAC,CAAC,oCAAoC;4BACtF,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE;4BACxD,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;yBACvC,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;gBACD,SAAS;YACX,CAAC;YAED,OAAO,IAAA,yBAAc,EAAC,MAAM,EAAE,QAAQ,EAAE;gBACtC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;gBACzB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;gBACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,MAAM,EAAE,0BAA0B,GAAG,EAAE;gBACvC,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE;gBACxD,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC;aAClD,CAAC,CAAC;QACL,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Detector } from "../types";
2
+ export declare const forwardDetector: Detector;
3
+ //# sourceMappingURL=forward.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forward.d.ts","sourceRoot":"","sources":["../../src/detectors/forward.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAA2B,MAAM,UAAU,CAAC;AAIlE,eAAO,MAAM,eAAe,EAAE,QAyB7B,CAAC"}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.forwardDetector = void 0;
4
+ const flags_1 = require("../utils/flags");
5
+ const incident_1 = require("./incident");
6
+ exports.forwardDetector = {
7
+ type: "forward",
8
+ inspect({ message, snapshot, history, config }) {
9
+ const rules = config.forwards;
10
+ if (!rules.enabled || !message.guild)
11
+ return null;
12
+ if (!snapshot.isForward && !(0, flags_1.isForwardedMessage)(message))
13
+ return null;
14
+ let count = 0;
15
+ for (const item of history) {
16
+ if (snapshot.timestamp - item.timestamp > rules.windowMs)
17
+ continue;
18
+ if (item.isForward)
19
+ count += 1;
20
+ }
21
+ if (!snapshot.isForward)
22
+ count += 1;
23
+ if (count < rules.maxForwards)
24
+ return null;
25
+ return (0, incident_1.createIncident)("forward", snapshot, {
26
+ userId: message.author.id,
27
+ guildId: message.guild.id,
28
+ severity: rules.severity,
29
+ reason: `Demasiados mensajes reenviados (${count}/${rules.maxForwards} en ${rules.windowMs}ms)`,
30
+ details: { count, windowMs: rules.windowMs },
31
+ recommendedActions: ["delete", "warn"],
32
+ });
33
+ },
34
+ };
35
+ //# sourceMappingURL=forward.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forward.js","sourceRoot":"","sources":["../../src/detectors/forward.ts"],"names":[],"mappings":";;;AACA,0CAAoD;AACpD,yCAA4C;AAE/B,QAAA,eAAe,GAAa;IACvC,IAAI,EAAE,SAAS;IACf,OAAO,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAiB;QAC3D,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC;QAC9B,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAClD,IAAI,CAAC,QAAQ,CAAC,SAAS,IAAI,CAAC,IAAA,0BAAkB,EAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;QAErE,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YAC3B,IAAI,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,QAAQ;gBAAE,SAAS;YACnE,IAAI,IAAI,CAAC,SAAS;gBAAE,KAAK,IAAI,CAAC,CAAC;QACjC,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,SAAS;YAAE,KAAK,IAAI,CAAC,CAAC;QAEpC,IAAI,KAAK,GAAG,KAAK,CAAC,WAAW;YAAE,OAAO,IAAI,CAAC;QAE3C,OAAO,IAAA,yBAAc,EAAC,SAAS,EAAE,QAAQ,EAAE;YACzC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;YACzB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;YACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,MAAM,EAAE,mCAAmC,KAAK,IAAI,KAAK,CAAC,WAAW,OAAO,KAAK,CAAC,QAAQ,KAAK;YAC/F,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE;YAC5C,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;SACvC,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ghost.d.ts","sourceRoot":"","sources":["../../src/detectors/ghost.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAI1D,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,eAAe,EACvB,GAAG,EAAE,MAAM,GACV,QAAQ,GAAG,IAAI,CAgCjB"}
1
+ {"version":3,"file":"ghost.d.ts","sourceRoot":"","sources":["../../src/detectors/ghost.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAI1D,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,eAAe,EACvB,GAAG,EAAE,MAAM,GACV,QAAQ,GAAG,IAAI,CAuCjB"}
@@ -23,6 +23,13 @@ function inspectGhostPing(message, config, now) {
23
23
  attachmentHashes: [],
24
24
  attachmentCount: 0,
25
25
  mentionCount: 0,
26
+ isReply: false,
27
+ emojiCount: 0,
28
+ embedCount: 0,
29
+ isForward: false,
30
+ stickerCount: 0,
31
+ isVoice: false,
32
+ hasPoll: false,
26
33
  };
27
34
  return (0, incident_1.createIncident)("ghost", snapshot, {
28
35
  userId: message.author.id,
@@ -1 +1 @@
1
- {"version":3,"file":"ghost.js","sourceRoot":"","sources":["../../src/detectors/ghost.ts"],"names":[],"mappings":";;AAKA,4CAoCC;AAvCD,yCAA4C;AAG5C,SAAgB,gBAAgB,CAC9B,OAAgB,EAChB,MAAuB,EACvB,GAAW;IAEX,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACnD,IAAI,OAAO,CAAC,MAAM,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAEpC,MAAM,cAAc,GAAG,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;IACnH,MAAM,QAAQ,GACZ,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAErF,IAAI,QAAQ,GAAG,MAAM,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAE/C,MAAM,OAAO,GAAG,OAAO,CAAC,gBAAgB,IAAI,GAAG,CAAC;IAChD,IAAI,MAAM,CAAC,QAAQ,GAAG,CAAC,IAAI,GAAG,GAAG,OAAO,GAAG,MAAM,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAExE,MAAM,QAAQ,GAAoB;QAChC,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,UAAU,EAAE,EAAE;QACd,SAAS,EAAE,GAAG;QACd,gBAAgB,EAAE,EAAE;QACpB,eAAe,EAAE,CAAC;QAClB,YAAY,EAAE,CAAC;KAChB,CAAC;IAEF,OAAO,IAAA,yBAAc,EAAC,OAAO,EAAE,QAAQ,EAAE;QACvC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;QACzB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,MAAM,EAAE,uBAAuB,QAAQ,8BAA8B;QACrE,OAAO,EAAE,EAAE,QAAQ,EAAE;QACrB,kBAAkB,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC;KACxC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"ghost.js","sourceRoot":"","sources":["../../src/detectors/ghost.ts"],"names":[],"mappings":";;AAKA,4CA2CC;AA9CD,yCAA4C;AAG5C,SAAgB,gBAAgB,CAC9B,OAAgB,EAChB,MAAuB,EACvB,GAAW;IAEX,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACnD,IAAI,OAAO,CAAC,MAAM,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAEpC,MAAM,cAAc,GAAG,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;IACnH,MAAM,QAAQ,GACZ,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAErF,IAAI,QAAQ,GAAG,MAAM,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAE/C,MAAM,OAAO,GAAG,OAAO,CAAC,gBAAgB,IAAI,GAAG,CAAC;IAChD,IAAI,MAAM,CAAC,QAAQ,GAAG,CAAC,IAAI,GAAG,GAAG,OAAO,GAAG,MAAM,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAExE,MAAM,QAAQ,GAAoB;QAChC,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,UAAU,EAAE,EAAE;QACd,SAAS,EAAE,GAAG;QACd,gBAAgB,EAAE,EAAE;QACpB,eAAe,EAAE,CAAC;QAClB,YAAY,EAAE,CAAC;QACf,OAAO,EAAE,KAAK;QACd,UAAU,EAAE,CAAC;QACb,UAAU,EAAE,CAAC;QACb,SAAS,EAAE,KAAK;QAChB,YAAY,EAAE,CAAC;QACf,OAAO,EAAE,KAAK;QACd,OAAO,EAAE,KAAK;KACf,CAAC;IAEF,OAAO,IAAA,yBAAc,EAAC,OAAO,EAAE,QAAQ,EAAE;QACvC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;QACzB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,MAAM,EAAE,uBAAuB,QAAQ,8BAA8B;QACrE,OAAO,EAAE,EAAE,QAAQ,EAAE;QACrB,kBAAkB,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC;KACxC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Detector } from "../types";
2
+ export declare const impersonateDetector: Detector;
3
+ //# sourceMappingURL=impersonate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impersonate.d.ts","sourceRoot":"","sources":["../../src/detectors/impersonate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAA2B,MAAM,UAAU,CAAC;AAmDlE,eAAO,MAAM,mBAAmB,EAAE,QAgCjC,CAAC"}
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.impersonateDetector = void 0;
4
+ const normalize_1 = require("../utils/normalize");
5
+ const similarity_1 = require("../utils/similarity");
6
+ const incident_1 = require("./incident");
7
+ function nameKey(value) {
8
+ return (0, normalize_1.foldHomoglyphs)(value)
9
+ .toLowerCase()
10
+ .replace(/[^a-z0-9]/g, "");
11
+ }
12
+ function collectTargets(input) {
13
+ const rules = input.config.impersonate;
14
+ const names = [...rules.names];
15
+ if (rules.matchBot) {
16
+ const bot = input.message.client?.user;
17
+ if (bot) {
18
+ if (bot.username)
19
+ names.push(bot.username);
20
+ const display = bot.displayName;
21
+ const global = bot.globalName;
22
+ if (display)
23
+ names.push(display);
24
+ if (global)
25
+ names.push(global);
26
+ }
27
+ }
28
+ return names.map(nameKey).filter((item) => item.length >= 3);
29
+ }
30
+ function collectCandidates(input) {
31
+ const rules = input.config.impersonate;
32
+ const out = [];
33
+ const author = input.message.author;
34
+ const member = input.message.member;
35
+ if (rules.checkUsername && author.username) {
36
+ out.push({ kind: "username", value: author.username });
37
+ }
38
+ if (rules.checkDisplayName) {
39
+ if (author.globalName)
40
+ out.push({ kind: "displayName", value: author.globalName });
41
+ if (author.displayName)
42
+ out.push({ kind: "displayName", value: author.displayName });
43
+ if (member?.displayName)
44
+ out.push({ kind: "displayName", value: member.displayName });
45
+ }
46
+ if (rules.checkNickname && member?.nickname) {
47
+ out.push({ kind: "nickname", value: member.nickname });
48
+ }
49
+ return out;
50
+ }
51
+ exports.impersonateDetector = {
52
+ type: "impersonate",
53
+ inspect(input) {
54
+ const { message, snapshot, config } = input;
55
+ const rules = config.impersonate;
56
+ if (!rules.enabled || !message.guild)
57
+ return null;
58
+ if (message.author.bot)
59
+ return null;
60
+ if (message.client?.user && message.author.id === message.client.user.id)
61
+ return null;
62
+ const targets = collectTargets(input);
63
+ if (targets.length === 0)
64
+ return null;
65
+ for (const candidate of collectCandidates(input)) {
66
+ const key = nameKey(candidate.value);
67
+ if (key.length < 3)
68
+ continue;
69
+ for (const target of targets) {
70
+ const score = (0, similarity_1.similarity)(key, target);
71
+ if (score >= rules.minSimilarity) {
72
+ return (0, incident_1.createIncident)("impersonate", snapshot, {
73
+ userId: message.author.id,
74
+ guildId: message.guild.id,
75
+ severity: rules.severity,
76
+ reason: `Posible impersonación (${candidate.kind} ≈ nombre protegido)`,
77
+ details: { kind: candidate.kind, similarity: Number(score.toFixed(3)) },
78
+ recommendedActions: ["delete", "warn", "timeout"],
79
+ });
80
+ }
81
+ }
82
+ }
83
+ return null;
84
+ },
85
+ };
86
+ //# sourceMappingURL=impersonate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impersonate.js","sourceRoot":"","sources":["../../src/detectors/impersonate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { GuildMember } from "discord.js";
2
+ import type { Incident, JoinConfig } from "../types";
3
+ export declare function inspectJoin(member: GuildMember, joinCount: number, rules: JoinConfig, now: number): Incident | null;
4
+ //# sourceMappingURL=joins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"joins.d.ts","sourceRoot":"","sources":["../../src/detectors/joins.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAErD,wBAAgB,WAAW,CACzB,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,MAAM,GACV,QAAQ,GAAG,IAAI,CAuBjB"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.inspectJoin = inspectJoin;
4
+ function inspectJoin(member, joinCount, rules, now) {
5
+ if (!rules.enabled)
6
+ return null;
7
+ if (member.user.bot)
8
+ return null;
9
+ if (joinCount < rules.maxJoins)
10
+ return null;
11
+ if (rules.minAccountAgeDays > 0) {
12
+ const created = member.user.createdTimestamp;
13
+ const ageDays = (now - created) / (24 * 60 * 60 * 1000);
14
+ if (ageDays >= rules.minAccountAgeDays)
15
+ return null;
16
+ }
17
+ return {
18
+ type: "join",
19
+ severity: rules.severity,
20
+ userId: member.id,
21
+ guildId: member.guild.id,
22
+ channelId: member.guild.systemChannelId ?? "",
23
+ messageId: "",
24
+ reason: `Posible raid de joins (${joinCount}/${rules.maxJoins} en ${rules.windowMs}ms)`,
25
+ details: { joins: joinCount, windowMs: rules.windowMs },
26
+ recommendedActions: ["timeout"],
27
+ timestamp: now,
28
+ };
29
+ }
30
+ //# sourceMappingURL=joins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"joins.js","sourceRoot":"","sources":["../../src/detectors/joins.ts"],"names":[],"mappings":";;AAGA,kCA4BC;AA5BD,SAAgB,WAAW,CACzB,MAAmB,EACnB,SAAiB,EACjB,KAAiB,EACjB,GAAW;IAEX,IAAI,CAAC,KAAK,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACjC,IAAI,SAAS,GAAG,KAAK,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAE5C,IAAI,KAAK,CAAC,iBAAiB,GAAG,CAAC,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC;QAC7C,MAAM,OAAO,GAAG,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QACxD,IAAI,OAAO,IAAI,KAAK,CAAC,iBAAiB;YAAE,OAAO,IAAI,CAAC;IACtD,CAAC;IAED,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,MAAM,EAAE,MAAM,CAAC,EAAE;QACjB,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE;QACxB,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,eAAe,IAAI,EAAE;QAC7C,SAAS,EAAE,EAAE;QACb,MAAM,EAAE,0BAA0B,SAAS,IAAI,KAAK,CAAC,QAAQ,OAAO,KAAK,CAAC,QAAQ,KAAK;QACvF,OAAO,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE;QACvD,kBAAkB,EAAE,CAAC,SAAS,CAAC;QAC/B,SAAS,EAAE,GAAG;KACf,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Detector } from "../types";
2
+ export declare const pollDetector: Detector;
3
+ //# sourceMappingURL=polls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polls.d.ts","sourceRoot":"","sources":["../../src/detectors/polls.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAA2B,MAAM,UAAU,CAAC;AAIlE,eAAO,MAAM,YAAY,EAAE,QAyB1B,CAAC"}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.pollDetector = void 0;
4
+ const flags_1 = require("../utils/flags");
5
+ const incident_1 = require("./incident");
6
+ exports.pollDetector = {
7
+ type: "poll",
8
+ inspect({ message, snapshot, history, config }) {
9
+ const rules = config.polls;
10
+ if (!rules.enabled || !message.guild)
11
+ return null;
12
+ if (!snapshot.hasPoll && !(0, flags_1.hasPoll)(message))
13
+ return null;
14
+ let count = 0;
15
+ for (const item of history) {
16
+ if (snapshot.timestamp - item.timestamp > rules.windowMs)
17
+ continue;
18
+ if (item.hasPoll)
19
+ count += 1;
20
+ }
21
+ if (!snapshot.hasPoll)
22
+ count += 1;
23
+ if (count < rules.maxPolls)
24
+ return null;
25
+ return (0, incident_1.createIncident)("poll", snapshot, {
26
+ userId: message.author.id,
27
+ guildId: message.guild.id,
28
+ severity: rules.severity,
29
+ reason: `Demasiadas encuestas (${count}/${rules.maxPolls} en ${rules.windowMs}ms)`,
30
+ details: { count, windowMs: rules.windowMs },
31
+ recommendedActions: ["delete", "warn"],
32
+ });
33
+ },
34
+ };
35
+ //# sourceMappingURL=polls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polls.js","sourceRoot":"","sources":["../../src/detectors/polls.ts"],"names":[],"mappings":";;;AACA,0CAAyC;AACzC,yCAA4C;AAE/B,QAAA,YAAY,GAAa;IACpC,IAAI,EAAE,MAAM;IACZ,OAAO,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAiB;QAC3D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAClD,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,CAAC,IAAA,eAAO,EAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;QAExD,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YAC3B,IAAI,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,QAAQ;gBAAE,SAAS;YACnE,IAAI,IAAI,CAAC,OAAO;gBAAE,KAAK,IAAI,CAAC,CAAC;QAC/B,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,OAAO;YAAE,KAAK,IAAI,CAAC,CAAC;QAElC,IAAI,KAAK,GAAG,KAAK,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAExC,OAAO,IAAA,yBAAc,EAAC,MAAM,EAAE,QAAQ,EAAE;YACtC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;YACzB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;YACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,MAAM,EAAE,yBAAyB,KAAK,IAAI,KAAK,CAAC,QAAQ,OAAO,KAAK,CAAC,QAAQ,KAAK;YAClF,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE;YAC5C,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;SACvC,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Detector } from "../types";
2
+ export declare const raidDetector: Detector;
3
+ //# sourceMappingURL=raid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raid.d.ts","sourceRoot":"","sources":["../../src/detectors/raid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAA2B,MAAM,UAAU,CAAC;AAGlE,eAAO,MAAM,YAAY,EAAE,QAgB1B,CAAC"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.raidDetector = void 0;
4
+ const incident_1 = require("./incident");
5
+ exports.raidDetector = {
6
+ type: "raid",
7
+ inspect({ message, snapshot, config, uniqueUsersInChannel }) {
8
+ const rules = config.raid;
9
+ if (!rules.enabled || !message.guild)
10
+ return null;
11
+ if (uniqueUsersInChannel < rules.maxUsers)
12
+ return null;
13
+ return (0, incident_1.createIncident)("raid", snapshot, {
14
+ userId: message.author.id,
15
+ guildId: message.guild.id,
16
+ severity: rules.severity,
17
+ reason: `Posible raid de canal (${uniqueUsersInChannel} usuarios en ${rules.windowMs}ms)`,
18
+ details: { users: uniqueUsersInChannel, windowMs: rules.windowMs },
19
+ recommendedActions: ["delete", "timeout"],
20
+ });
21
+ },
22
+ };
23
+ //# sourceMappingURL=raid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raid.js","sourceRoot":"","sources":["../../src/detectors/raid.ts"],"names":[],"mappings":";;;AACA,yCAA4C;AAE/B,QAAA,YAAY,GAAa;IACpC,IAAI,EAAE,MAAM;IACZ,OAAO,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,oBAAoB,EAAiB;QACxE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC;QAC1B,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAClD,IAAI,oBAAoB,GAAG,KAAK,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAEvD,OAAO,IAAA,yBAAc,EAAC,MAAM,EAAE,QAAQ,EAAE;YACtC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;YACzB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;YACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,MAAM,EAAE,0BAA0B,oBAAoB,gBAAgB,KAAK,CAAC,QAAQ,KAAK;YACzF,OAAO,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE;YAClE,kBAAkB,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC;SAC1C,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Detector } from "../types";
2
+ export declare const replyDetector: Detector;
3
+ //# sourceMappingURL=replies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replies.d.ts","sourceRoot":"","sources":["../../src/detectors/replies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAA2B,MAAM,UAAU,CAAC;AAGlE,eAAO,MAAM,aAAa,EAAE,QAwB3B,CAAC"}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.replyDetector = void 0;
4
+ const incident_1 = require("./incident");
5
+ exports.replyDetector = {
6
+ type: "reply",
7
+ inspect({ message, snapshot, history, config }) {
8
+ const rules = config.replies;
9
+ if (!rules.enabled || !message.guild)
10
+ return null;
11
+ if (!snapshot.isReply)
12
+ return null;
13
+ let count = 0;
14
+ for (const item of history) {
15
+ if (snapshot.timestamp - item.timestamp > rules.windowMs)
16
+ continue;
17
+ if (item.isReply)
18
+ count += 1;
19
+ }
20
+ if (count < rules.maxReplies)
21
+ return null;
22
+ return (0, incident_1.createIncident)("reply", snapshot, {
23
+ userId: message.author.id,
24
+ guildId: message.guild.id,
25
+ severity: rules.severity,
26
+ reason: `Demasiadas respuestas seguidas (${count}/${rules.maxReplies} en ${rules.windowMs}ms)`,
27
+ details: { count, windowMs: rules.windowMs },
28
+ recommendedActions: ["delete", "warn"],
29
+ });
30
+ },
31
+ };
32
+ //# sourceMappingURL=replies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replies.js","sourceRoot":"","sources":["../../src/detectors/replies.ts"],"names":[],"mappings":";;;AACA,yCAA4C;AAE/B,QAAA,aAAa,GAAa;IACrC,IAAI,EAAE,OAAO;IACb,OAAO,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAiB;QAC3D,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC;QAC7B,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAClD,IAAI,CAAC,QAAQ,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAEnC,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YAC3B,IAAI,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,QAAQ;gBAAE,SAAS;YACnE,IAAI,IAAI,CAAC,OAAO;gBAAE,KAAK,IAAI,CAAC,CAAC;QAC/B,CAAC;QAED,IAAI,KAAK,GAAG,KAAK,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC;QAE1C,OAAO,IAAA,yBAAc,EAAC,OAAO,EAAE,QAAQ,EAAE;YACvC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;YACzB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;YACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,MAAM,EAAE,mCAAmC,KAAK,IAAI,KAAK,CAAC,UAAU,OAAO,KAAK,CAAC,QAAQ,KAAK;YAC9F,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE;YAC5C,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;SACvC,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Detector } from "../types";
2
+ export declare const stickerDetector: Detector;
3
+ //# sourceMappingURL=stickers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stickers.d.ts","sourceRoot":"","sources":["../../src/detectors/stickers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAA2B,MAAM,UAAU,CAAC;AAGlE,eAAO,MAAM,eAAe,EAAE,QAyD7B,CAAC"}
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stickerDetector = void 0;
4
+ const incident_1 = require("./incident");
5
+ exports.stickerDetector = {
6
+ type: "sticker",
7
+ inspect({ message, snapshot, history, config }) {
8
+ const rules = config.stickers;
9
+ if (!rules.enabled || !message.guild)
10
+ return null;
11
+ const count = message.stickers.size;
12
+ if (count === 0)
13
+ return null;
14
+ if (count > rules.maxStickers) {
15
+ return (0, incident_1.createIncident)("sticker", snapshot, {
16
+ userId: message.author.id,
17
+ guildId: message.guild.id,
18
+ severity: rules.severity,
19
+ reason: `Demasiados stickers (${count}/${rules.maxStickers})`,
20
+ details: { count },
21
+ recommendedActions: ["delete", "warn"],
22
+ });
23
+ }
24
+ if (rules.blockOnly) {
25
+ const empty = message.content.trim().length === 0 &&
26
+ message.attachments.size === 0 &&
27
+ message.embeds.length === 0;
28
+ if (empty) {
29
+ return (0, incident_1.createIncident)("sticker", snapshot, {
30
+ userId: message.author.id,
31
+ guildId: message.guild.id,
32
+ severity: rules.severity,
33
+ reason: "Mensaje que solo contiene stickers",
34
+ details: { count },
35
+ recommendedActions: ["delete"],
36
+ });
37
+ }
38
+ }
39
+ if (rules.maxInWindow > 0) {
40
+ let total = 0;
41
+ for (const item of history) {
42
+ if (snapshot.timestamp - item.timestamp > rules.windowMs)
43
+ continue;
44
+ total += item.stickerCount ?? 0;
45
+ }
46
+ if (total > rules.maxInWindow) {
47
+ return (0, incident_1.createIncident)("sticker", snapshot, {
48
+ userId: message.author.id,
49
+ guildId: message.guild.id,
50
+ severity: rules.severity,
51
+ reason: `Demasiados stickers en la ventana (${total}/${rules.maxInWindow})`,
52
+ details: { count: total, windowMs: rules.windowMs },
53
+ recommendedActions: ["delete", "warn"],
54
+ });
55
+ }
56
+ }
57
+ return null;
58
+ },
59
+ };
60
+ //# sourceMappingURL=stickers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stickers.js","sourceRoot":"","sources":["../../src/detectors/stickers.ts"],"names":[],"mappings":";;;AACA,yCAA4C;AAE/B,QAAA,eAAe,GAAa;IACvC,IAAI,EAAE,SAAS;IACf,OAAO,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAiB;QAC3D,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC;QAC9B,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAElD,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;QACpC,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAE7B,IAAI,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;YAC9B,OAAO,IAAA,yBAAc,EAAC,SAAS,EAAE,QAAQ,EAAE;gBACzC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;gBACzB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;gBACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,MAAM,EAAE,wBAAwB,KAAK,IAAI,KAAK,CAAC,WAAW,GAAG;gBAC7D,OAAO,EAAE,EAAE,KAAK,EAAE;gBAClB,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;aACvC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YACpB,MAAM,KAAK,GACT,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;gBACnC,OAAO,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC;gBAC9B,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;YAC9B,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,IAAA,yBAAc,EAAC,SAAS,EAAE,QAAQ,EAAE;oBACzC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;oBACzB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;oBACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,MAAM,EAAE,oCAAoC;oBAC5C,OAAO,EAAE,EAAE,KAAK,EAAE;oBAClB,kBAAkB,EAAE,CAAC,QAAQ,CAAC;iBAC/B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,IAAI,KAAK,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;YAC1B,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;gBAC3B,IAAI,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,QAAQ;oBAAE,SAAS;gBACnE,KAAK,IAAI,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC;YAClC,CAAC;YACD,IAAI,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;gBAC9B,OAAO,IAAA,yBAAc,EAAC,SAAS,EAAE,QAAQ,EAAE;oBACzC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;oBACzB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;oBACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,MAAM,EAAE,sCAAsC,KAAK,IAAI,KAAK,CAAC,WAAW,GAAG;oBAC3E,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE;oBACnD,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;iBACvC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Detector } from "../types";
2
+ export declare const voiceDetector: Detector;
3
+ //# sourceMappingURL=voice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice.d.ts","sourceRoot":"","sources":["../../src/detectors/voice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAA2B,MAAM,UAAU,CAAC;AAIlE,eAAO,MAAM,aAAa,EAAE,QAyB3B,CAAC"}