cross-seed 6.0.0-8 → 6.0.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 (70) hide show
  1. package/dist/action.js +177 -71
  2. package/dist/action.js.map +1 -1
  3. package/dist/arr.js +62 -54
  4. package/dist/arr.js.map +1 -1
  5. package/dist/clients/Deluge.js +70 -46
  6. package/dist/clients/Deluge.js.map +1 -1
  7. package/dist/clients/QBittorrent.js +110 -68
  8. package/dist/clients/QBittorrent.js.map +1 -1
  9. package/dist/clients/RTorrent.js +46 -23
  10. package/dist/clients/RTorrent.js.map +1 -1
  11. package/dist/clients/TorrentClient.js +14 -1
  12. package/dist/clients/TorrentClient.js.map +1 -1
  13. package/dist/clients/Transmission.js +30 -10
  14. package/dist/clients/Transmission.js.map +1 -1
  15. package/dist/cmd.js +46 -23
  16. package/dist/cmd.js.map +1 -1
  17. package/dist/config.template.cjs +59 -59
  18. package/dist/config.template.cjs.map +1 -1
  19. package/dist/configSchema.js +90 -26
  20. package/dist/configSchema.js.map +1 -1
  21. package/dist/configuration.js +4 -1
  22. package/dist/configuration.js.map +1 -1
  23. package/dist/constants.js +77 -9
  24. package/dist/constants.js.map +1 -1
  25. package/dist/dataFiles.js +4 -5
  26. package/dist/dataFiles.js.map +1 -1
  27. package/dist/db.js +2 -1
  28. package/dist/db.js.map +1 -1
  29. package/dist/decide.js +279 -169
  30. package/dist/decide.js.map +1 -1
  31. package/dist/diff.js +13 -3
  32. package/dist/diff.js.map +1 -1
  33. package/dist/errors.js.map +1 -1
  34. package/dist/indexers.js +94 -33
  35. package/dist/indexers.js.map +1 -1
  36. package/dist/inject.js +448 -0
  37. package/dist/inject.js.map +1 -0
  38. package/dist/jobs.js +13 -6
  39. package/dist/jobs.js.map +1 -1
  40. package/dist/logger.js +27 -9
  41. package/dist/logger.js.map +1 -1
  42. package/dist/migrations/00-initialSchema.js.map +1 -1
  43. package/dist/migrations/05-caps.js.map +1 -1
  44. package/dist/migrations/06-uniqueDecisions.js +29 -0
  45. package/dist/migrations/06-uniqueDecisions.js.map +1 -0
  46. package/dist/migrations/07-limits.js +12 -0
  47. package/dist/migrations/07-limits.js.map +1 -0
  48. package/dist/migrations/migrations.js +4 -0
  49. package/dist/migrations/migrations.js.map +1 -1
  50. package/dist/parseTorrent.js +6 -0
  51. package/dist/parseTorrent.js.map +1 -1
  52. package/dist/pipeline.js +224 -112
  53. package/dist/pipeline.js.map +1 -1
  54. package/dist/preFilter.js +122 -55
  55. package/dist/preFilter.js.map +1 -1
  56. package/dist/pushNotifier.js +7 -5
  57. package/dist/pushNotifier.js.map +1 -1
  58. package/dist/searchee.js +198 -17
  59. package/dist/searchee.js.map +1 -1
  60. package/dist/server.js +106 -54
  61. package/dist/server.js.map +1 -1
  62. package/dist/startup.js +16 -7
  63. package/dist/startup.js.map +1 -1
  64. package/dist/torrent.js +116 -50
  65. package/dist/torrent.js.map +1 -1
  66. package/dist/torznab.js +323 -153
  67. package/dist/torznab.js.map +1 -1
  68. package/dist/utils.js +229 -44
  69. package/dist/utils.js.map +1 -1
  70. package/package.json +11 -6
package/dist/decide.js CHANGED
@@ -1,21 +1,19 @@
1
- import { existsSync, writeFileSync } from "fs";
1
+ import { existsSync, statSync, unlinkSync, utimesSync, writeFileSync, } from "fs";
2
+ import ms from "ms";
2
3
  import path from "path";
3
4
  import { appDir } from "./configuration.js";
4
- import { Decision, MatchMode, RELEASE_GROUP_REGEX, REPACK_PROPER_REGEX, RESOLUTION_REGEX, TORRENT_CACHE_FOLDER, } from "./constants.js";
5
+ import { ANIME_GROUP_REGEX, Decision, isAnyMatchedDecision, isStaticDecision, MatchMode, parseSource, REPACK_PROPER_REGEX, RES_STRICT_REGEX, SEASON_REGEX, TORRENT_CACHE_FOLDER, } from "./constants.js";
5
6
  import { db } from "./db.js";
6
7
  import { Label, logger } from "./logger.js";
7
- import { findBlockedStringInReleaseMaybe } from "./preFilter.js";
8
+ import { Metafile } from "./parseTorrent.js";
9
+ import { findBlockedStringInReleaseMaybe, isSingleEpisode, } from "./preFilter.js";
10
+ import { resultOf, resultOfErr } from "./Result.js";
8
11
  import { getRuntimeConfig } from "./runtimeConfig.js";
12
+ import { getReleaseGroup, } from "./searchee.js";
9
13
  import { parseTorrentFromFilename, snatch, SnatchError } from "./torrent.js";
10
- import { humanReadableSize } from "./utils.js";
11
- const createReasonLogger = (Title, tracker, name) => (decision, cached, searchee, candidate) => {
12
- function logReason(reason) {
13
- logger.verbose({
14
- label: Label.DECIDE,
15
- message: `${name} - no match for ${tracker} torrent ${Title} - ${reason}`,
16
- });
17
- }
18
- const sizeDiff = candidate.size - searchee.length;
14
+ import { extractInt, getFuzzySizeFactor, getLogString, getMediaType, getMinSizeRatio, sanitizeInfoHash, stripExtension, wait, } from "./utils.js";
15
+ function logDecision(searchee, candidate, decision, metafile, tracker) {
16
+ const { matchMode } = getRuntimeConfig();
19
17
  let reason;
20
18
  switch (decision) {
21
19
  case Decision.MATCH_PARTIAL:
@@ -24,15 +22,17 @@ const createReasonLogger = (Title, tracker, name) => (decision, cached, searchee
24
22
  return;
25
23
  case Decision.MATCH:
26
24
  return;
25
+ case Decision.FUZZY_SIZE_MISMATCH:
26
+ reason = `the total sizes are outside of the fuzzySizeThreshold range: ${Math.abs((candidate.size - searchee.length) / searchee.length).toFixed(3)} > ${getFuzzySizeFactor()}`;
27
+ break;
27
28
  case Decision.SIZE_MISMATCH:
28
- reason = `its size does not match - (${Math.abs(sizeDiff) > 10000000 // 10MB is the rounding error
29
- ? `${humanReadableSize(searchee.length)} -> ${humanReadableSize(candidate.size)}`
30
- : `${sizeDiff > 0 ? "+" : ""}${sizeDiff} bytes`})`;
29
+ reason = `some files are missing or have different sizes${compareFileTreesPartial(metafile, searchee) ? ` (will match in partial match mode)` : ""}`;
30
+ break;
31
+ case Decision.PARTIAL_SIZE_MISMATCH:
32
+ reason = `too many files are missing or have different sizes: torrent progress would be ${(getPartialSizeRatio(metafile, searchee) * 100).toFixed(3)}%`;
31
33
  break;
32
34
  case Decision.RESOLUTION_MISMATCH:
33
- reason = `its resolution does not match - (${searchee.name
34
- .match(RESOLUTION_REGEX)?.[0]
35
- ?.trim()} -> ${candidate.name.match(RESOLUTION_REGEX)?.[0]?.trim()})`;
35
+ reason = `its resolution does not match: ${searchee.title.match(RES_STRICT_REGEX)?.groups?.res} -> ${candidate.name.match(RES_STRICT_REGEX)?.groups?.res}`;
36
36
  break;
37
37
  case Decision.NO_DOWNLOAD_LINK:
38
38
  reason = "it doesn't have a download link";
@@ -43,34 +43,40 @@ const createReasonLogger = (Title, tracker, name) => (decision, cached, searchee
43
43
  case Decision.DOWNLOAD_FAILED:
44
44
  reason = "the torrent file failed to download";
45
45
  break;
46
+ case Decision.MAGNET_LINK:
47
+ reason = "the torrent is a magnet link";
48
+ break;
49
+ case Decision.SAME_INFO_HASH:
50
+ reason = "the info hash is the same";
51
+ break;
46
52
  case Decision.INFO_HASH_ALREADY_EXISTS:
47
53
  reason = "the info hash matches a torrent you already have";
48
54
  break;
49
55
  case Decision.FILE_TREE_MISMATCH:
50
- reason = "it has a different file tree";
56
+ reason = `it has a different file tree${matchMode === MatchMode.SAFE ? " (will match in risky or partial match mode)" : ""}`;
51
57
  break;
52
58
  case Decision.RELEASE_GROUP_MISMATCH:
53
- reason = `it has a different release group - (${searchee.name
54
- .match(RELEASE_GROUP_REGEX)?.[0]
55
- ?.trim()} -> ${candidate.name
56
- .match(RELEASE_GROUP_REGEX)?.[0]
57
- ?.trim()})`;
59
+ reason = `it has a different release group: ${getReleaseGroup(stripExtension(searchee.title))} -> ${getReleaseGroup(stripExtension(candidate.name))}`;
58
60
  break;
59
61
  case Decision.PROPER_REPACK_MISMATCH:
60
- reason = `one is a different subsequent release - (${searchee.name.match(REPACK_PROPER_REGEX)?.groups?.type ??
61
- "INITIAL"} -> ${candidate.name.match(REPACK_PROPER_REGEX)?.groups?.type ?? "INITIAL"})`;
62
+ reason = `one is a different subsequent release: ${searchee.title.match(REPACK_PROPER_REGEX)?.groups?.type ??
63
+ "INITIAL"} -> ${candidate.name.match(REPACK_PROPER_REGEX)?.groups?.type ?? "INITIAL"}`;
64
+ break;
65
+ case Decision.SOURCE_MISMATCH:
66
+ reason = `it has a different source: ${parseSource(searchee.title)} -> ${parseSource(candidate.name)}`;
62
67
  break;
63
68
  case Decision.BLOCKED_RELEASE:
64
- reason = `it matches the blocklist - ("${findBlockedStringInReleaseMaybe(searchee, getRuntimeConfig().blockList)}")`;
69
+ reason = `it matches the blocklist: "${findBlockedStringInReleaseMaybe(searchee, getRuntimeConfig().blockList)}"`;
65
70
  break;
66
71
  default:
67
72
  reason = decision;
68
73
  break;
69
74
  }
70
- if (!cached) {
71
- logReason(reason);
72
- }
73
- };
75
+ logger.verbose({
76
+ label: Label.DECIDE,
77
+ message: `${getLogString(searchee)} - no match for ${tracker} torrent ${candidate.name}${metafile ? ` [${sanitizeInfoHash(metafile.infoHash)}]` : ""} - ${reason}`,
78
+ });
79
+ }
74
80
  export function compareFileTrees(candidate, searchee) {
75
81
  const cmp = (elOfA, elOfB) => {
76
82
  const lengthsAreEqual = elOfB.length === elOfA.length;
@@ -80,13 +86,21 @@ export function compareFileTrees(candidate, searchee) {
80
86
  return candidate.files.every((elOfA) => searchee.files.some((elOfB) => cmp(elOfA, elOfB)));
81
87
  }
82
88
  export function compareFileTreesIgnoringNames(candidate, searchee) {
83
- const cmp = (candidate, searchee) => {
84
- return searchee.length === candidate.length;
85
- };
86
- return candidate.files.every((elOfA) => searchee.files.some((elOfB) => cmp(elOfA, elOfB)));
89
+ const availableFiles = searchee.files.slice();
90
+ for (const candidateFile of candidate.files) {
91
+ let matchedSearcheeFiles = availableFiles.filter((searcheeFile) => searcheeFile.length === candidateFile.length);
92
+ if (matchedSearcheeFiles.length > 1) {
93
+ matchedSearcheeFiles = matchedSearcheeFiles.filter((searcheeFile) => searcheeFile.name === candidateFile.name);
94
+ }
95
+ if (matchedSearcheeFiles.length === 0) {
96
+ return false;
97
+ }
98
+ const index = availableFiles.indexOf(matchedSearcheeFiles[0]);
99
+ availableFiles.splice(index, 1);
100
+ }
101
+ return true;
87
102
  }
88
- export function compareFileTreesPartialIgnoringNames(candidate, searchee) {
89
- const { fuzzySizeThreshold } = getRuntimeConfig();
103
+ export function getPartialSizeRatio(candidate, searchee) {
90
104
  let matchedSizes = 0;
91
105
  for (const candidateFile of candidate.files) {
92
106
  const searcheeHasFileSize = searchee.files.some((searcheeFile) => searcheeFile.length === candidateFile.length);
@@ -94,215 +108,311 @@ export function compareFileTreesPartialIgnoringNames(candidate, searchee) {
94
108
  matchedSizes += candidateFile.length;
95
109
  }
96
110
  }
97
- return matchedSizes / candidate.length >= 1 - fuzzySizeThreshold;
111
+ return matchedSizes / candidate.length;
98
112
  }
99
113
  export function compareFileTreesPartial(candidate, searchee) {
100
- const { fuzzySizeThreshold } = getRuntimeConfig();
101
114
  let matchedSizes = 0;
115
+ const availableFiles = searchee.files.slice();
102
116
  for (const candidateFile of candidate.files) {
103
- let matchedSearcheeFiles = searchee.files.filter((searcheeFile) => searcheeFile.length === candidateFile.length);
117
+ let matchedSearcheeFiles = availableFiles.filter((searcheeFile) => searcheeFile.length === candidateFile.length);
104
118
  if (matchedSearcheeFiles.length > 1) {
105
119
  matchedSearcheeFiles = matchedSearcheeFiles.filter((searcheeFile) => searcheeFile.name === candidateFile.name);
106
120
  }
107
121
  if (matchedSearcheeFiles.length) {
108
122
  matchedSizes += candidateFile.length;
123
+ const index = availableFiles.indexOf(matchedSearcheeFiles[0]);
124
+ availableFiles.splice(index, 1);
109
125
  }
110
126
  }
111
127
  const totalPieces = Math.ceil(candidate.length / candidate.pieceLength);
112
128
  const availablePieces = Math.floor(matchedSizes / candidate.pieceLength);
113
- return availablePieces / totalPieces >= 1 - fuzzySizeThreshold;
129
+ return availablePieces / totalPieces >= getMinSizeRatio();
114
130
  }
115
- function sizeDoesMatch(resultSize, searchee) {
116
- const { fuzzySizeThreshold } = getRuntimeConfig();
131
+ function fuzzySizeDoesMatch(resultSize, searchee) {
132
+ const fuzzySizeFactor = getFuzzySizeFactor();
117
133
  const { length } = searchee;
118
- const lowerBound = length - fuzzySizeThreshold * length;
119
- const upperBound = length + fuzzySizeThreshold * length;
134
+ const lowerBound = length - fuzzySizeFactor * length;
135
+ const upperBound = length + fuzzySizeFactor * length;
120
136
  return resultSize >= lowerBound && resultSize <= upperBound;
121
137
  }
122
- function releaseVersionDoesMatch(searcheeName, candidateName, matchMode) {
123
- const searcheeVersionType = searcheeName.match(REPACK_PROPER_REGEX);
124
- const candidateVersionType = candidateName.match(REPACK_PROPER_REGEX);
125
- const searcheeTypeStr = searcheeVersionType?.groups?.type
126
- ?.trim()
138
+ function resolutionDoesMatch(searcheeTitle, candidateName) {
139
+ const searcheeRes = searcheeTitle
140
+ .match(RES_STRICT_REGEX)
141
+ ?.groups?.res?.trim()
127
142
  ?.toLowerCase();
128
- const candidateTypeStr = candidateVersionType?.groups?.type
129
- ?.trim()
143
+ const candidateRes = candidateName
144
+ .match(RES_STRICT_REGEX)
145
+ ?.groups?.res?.trim()
130
146
  ?.toLowerCase();
131
- if (searcheeTypeStr !== candidateTypeStr ||
132
- searcheeVersionType?.groups?.arrtype) {
133
- return matchMode !== MatchMode.SAFE;
134
- }
135
- return true;
147
+ if (!searcheeRes || !candidateRes)
148
+ return true;
149
+ return extractInt(searcheeRes) === extractInt(candidateRes);
136
150
  }
137
- function releaseGroupDoesMatch(searcheeName, candidateName, matchMode) {
138
- const searcheeReleaseGroup = searcheeName
139
- .match(RELEASE_GROUP_REGEX)?.[0]
140
- ?.trim()
151
+ function releaseGroupDoesMatch(searcheeTitle, candidateName) {
152
+ const searcheeReleaseGroup = getReleaseGroup(stripExtension(searcheeTitle))?.toLowerCase();
153
+ const candidateReleaseGroup = getReleaseGroup(stripExtension(candidateName))?.toLowerCase();
154
+ if (!searcheeReleaseGroup || !candidateReleaseGroup) {
155
+ return true; // Pass if missing -GRP
156
+ }
157
+ if (searcheeReleaseGroup.startsWith(candidateReleaseGroup) ||
158
+ candidateReleaseGroup.startsWith(searcheeReleaseGroup)) {
159
+ return true; // -GRP matches
160
+ }
161
+ // Anime naming can cause weird things to match as release groups
162
+ const searcheeAnimeGroup = searcheeTitle
163
+ .match(ANIME_GROUP_REGEX)
164
+ ?.groups?.group?.trim()
141
165
  ?.toLowerCase();
142
- const candidateReleaseGroup = candidateName
143
- .match(RELEASE_GROUP_REGEX)?.[0]
144
- ?.trim()
166
+ const candidateAnimeGroup = candidateName
167
+ .match(ANIME_GROUP_REGEX)
168
+ ?.groups?.group?.trim()
145
169
  ?.toLowerCase();
146
- if (searcheeReleaseGroup === candidateReleaseGroup) {
170
+ if (!searcheeAnimeGroup && !candidateAnimeGroup) {
171
+ return false;
172
+ }
173
+ // Most checks will never get here, below are rare edge cases
174
+ if (searcheeAnimeGroup === candidateAnimeGroup) {
147
175
  return true;
148
176
  }
149
- // if we are unsure, pass in risky or partial mode but fail in safe mode
150
- if (!searcheeReleaseGroup || !candidateReleaseGroup) {
151
- return matchMode !== MatchMode.SAFE;
177
+ if (searcheeAnimeGroup && searcheeAnimeGroup === candidateReleaseGroup) {
178
+ return true;
179
+ }
180
+ if (candidateAnimeGroup && searcheeReleaseGroup === candidateAnimeGroup) {
181
+ return true;
152
182
  }
153
- return searcheeReleaseGroup.startsWith(candidateReleaseGroup);
183
+ return false;
184
+ }
185
+ function sourceDoesMatch(searcheeTitle, candidateName) {
186
+ const searcheeSource = parseSource(searcheeTitle);
187
+ const candidateSource = parseSource(candidateName);
188
+ if (!searcheeSource || !candidateSource)
189
+ return true;
190
+ return searcheeSource === candidateSource;
154
191
  }
155
- async function assessCandidateHelper({ link, size, name, tracker }, searchee, hashesToExclude) {
156
- const { matchMode, blockList } = getRuntimeConfig();
192
+ export async function assessCandidate(metaOrCandidate, searchee, hashesToExclude) {
193
+ const { blockList, includeSingleEpisodes, matchMode } = getRuntimeConfig();
194
+ // When metaOrCandidate is a Metafile, skip straight to the
195
+ // main matching algorithms as we don't need pre-download filtering.
196
+ const isCandidate = !(metaOrCandidate instanceof Metafile);
197
+ const name = metaOrCandidate.name;
198
+ const size = isCandidate ? metaOrCandidate.size : metaOrCandidate.length;
199
+ if (isCandidate) {
200
+ if (!releaseGroupDoesMatch(searchee.title, name)) {
201
+ return { decision: Decision.RELEASE_GROUP_MISMATCH };
202
+ }
203
+ if (!resolutionDoesMatch(searchee.title, name)) {
204
+ return { decision: Decision.RESOLUTION_MISMATCH };
205
+ }
206
+ if (!sourceDoesMatch(searchee.title, name)) {
207
+ return { decision: Decision.SOURCE_MISMATCH };
208
+ }
209
+ if (size && !fuzzySizeDoesMatch(size, searchee)) {
210
+ return { decision: Decision.FUZZY_SIZE_MISMATCH };
211
+ }
212
+ if (!metaOrCandidate.link) {
213
+ return { decision: Decision.NO_DOWNLOAD_LINK };
214
+ }
215
+ }
157
216
  if (findBlockedStringInReleaseMaybe(searchee, blockList)) {
158
217
  return { decision: Decision.BLOCKED_RELEASE };
159
218
  }
160
- if (size && !sizeDoesMatch(size, searchee)) {
161
- return { decision: Decision.SIZE_MISMATCH };
219
+ let metafile;
220
+ if (isCandidate) {
221
+ let res = await snatch(metaOrCandidate);
222
+ if (res.isErr()) {
223
+ const e = res.unwrapErr();
224
+ if ([Label.ANNOUNCE, Label.RSS].includes(searchee.label) &&
225
+ ![SnatchError.RATE_LIMITED, SnatchError.MAGNET_LINK].includes(e)) {
226
+ await wait(ms("30 seconds"));
227
+ res = await snatch(metaOrCandidate);
228
+ }
229
+ if (res.isErr()) {
230
+ const err = res.unwrapErr();
231
+ return err === SnatchError.MAGNET_LINK
232
+ ? { decision: Decision.MAGNET_LINK }
233
+ : err === SnatchError.RATE_LIMITED
234
+ ? { decision: Decision.RATE_LIMITED }
235
+ : { decision: Decision.DOWNLOAD_FAILED };
236
+ }
237
+ }
238
+ metafile = res.unwrap();
239
+ cacheTorrentFile(metafile);
240
+ metaOrCandidate.size = metafile.length; // Trackers can be wrong
162
241
  }
163
- if (!link)
164
- return { decision: Decision.NO_DOWNLOAD_LINK };
165
- if (!releaseGroupDoesMatch(searchee.name, name, matchMode)) {
166
- return { decision: Decision.RELEASE_GROUP_MISMATCH };
242
+ else {
243
+ metafile = metaOrCandidate;
167
244
  }
168
- if (!releaseVersionDoesMatch(searchee.name, name, matchMode)) {
169
- return { decision: Decision.PROPER_REPACK_MISMATCH };
245
+ if (searchee.infoHash === metafile.infoHash) {
246
+ return { decision: Decision.SAME_INFO_HASH, metafile };
170
247
  }
171
- const result = await snatch(link, tracker);
172
- if (result.isErr()) {
173
- return result.unwrapErr() === SnatchError.RATE_LIMITED
174
- ? { decision: Decision.RATE_LIMITED }
175
- : { decision: Decision.DOWNLOAD_FAILED };
248
+ if (hashesToExclude.includes(metafile.infoHash)) {
249
+ return { decision: Decision.INFO_HASH_ALREADY_EXISTS, metafile };
176
250
  }
177
- const candidateMeta = result.unwrap();
178
- if (hashesToExclude.includes(candidateMeta.infoHash)) {
179
- return { decision: Decision.INFO_HASH_ALREADY_EXISTS };
251
+ // Prevent candidate episodes from matching searchee season packs
252
+ if (!includeSingleEpisodes &&
253
+ SEASON_REGEX.test(searchee.title) &&
254
+ isSingleEpisode(metafile, getMediaType(metafile))) {
255
+ return { decision: Decision.FILE_TREE_MISMATCH, metafile };
180
256
  }
181
- const sizeMatch = compareFileTreesIgnoringNames(candidateMeta, searchee);
182
- const perfectMatch = compareFileTrees(candidateMeta, searchee);
257
+ const perfectMatch = compareFileTrees(metafile, searchee);
183
258
  if (perfectMatch) {
184
- return { decision: Decision.MATCH, metafile: candidateMeta };
259
+ return { decision: Decision.MATCH, metafile };
185
260
  }
186
- if (sizeMatch &&
187
- matchMode !== MatchMode.SAFE &&
188
- searchee.files.length === 1) {
189
- return {
190
- decision: Decision.MATCH_SIZE_ONLY,
191
- metafile: candidateMeta,
192
- };
261
+ const sizeMatch = compareFileTreesIgnoringNames(metafile, searchee);
262
+ if (sizeMatch && matchMode !== MatchMode.SAFE) {
263
+ return { decision: Decision.MATCH_SIZE_ONLY, metafile };
193
264
  }
194
265
  if (matchMode === MatchMode.PARTIAL) {
195
- const partialSizeMatch = compareFileTreesPartialIgnoringNames(candidateMeta, searchee);
266
+ const partialSizeMatch = getPartialSizeRatio(metafile, searchee) >= getMinSizeRatio();
196
267
  if (!partialSizeMatch) {
197
- return { decision: Decision.SIZE_MISMATCH };
268
+ return { decision: Decision.PARTIAL_SIZE_MISMATCH, metafile };
198
269
  }
199
- const partialMatch = compareFileTreesPartial(candidateMeta, searchee);
270
+ const partialMatch = compareFileTreesPartial(metafile, searchee);
200
271
  if (partialMatch) {
201
- return {
202
- decision: Decision.MATCH_PARTIAL,
203
- metafile: candidateMeta,
204
- };
272
+ return { decision: Decision.MATCH_PARTIAL, metafile };
205
273
  }
206
274
  }
207
275
  else if (!sizeMatch) {
208
- return { decision: Decision.SIZE_MISMATCH };
276
+ return { decision: Decision.SIZE_MISMATCH, metafile };
209
277
  }
210
- return { decision: Decision.FILE_TREE_MISMATCH };
278
+ return { decision: Decision.FILE_TREE_MISMATCH, metafile };
211
279
  }
212
280
  function existsInTorrentCache(infoHash) {
213
- return existsSync(path.join(appDir(), TORRENT_CACHE_FOLDER, `${infoHash}.cached.torrent`));
281
+ const torrentPath = path.join(appDir(), TORRENT_CACHE_FOLDER, `${infoHash}.cached.torrent`);
282
+ if (!existsSync(torrentPath))
283
+ return false;
284
+ utimesSync(torrentPath, new Date(), statSync(torrentPath).mtime);
285
+ return true;
214
286
  }
215
- async function getCachedTorrentFile(infoHash) {
216
- return parseTorrentFromFilename(path.join(appDir(), TORRENT_CACHE_FOLDER, `${infoHash}.cached.torrent`));
287
+ async function getCachedTorrentFile(infoHash, options = { deleteOnFail: true }) {
288
+ const torrentPath = path.join(appDir(), TORRENT_CACHE_FOLDER, `${infoHash}.cached.torrent`);
289
+ try {
290
+ return resultOf(await parseTorrentFromFilename(torrentPath));
291
+ }
292
+ catch (e) {
293
+ logger.error({
294
+ label: Label.DECIDE,
295
+ message: `Failed to parse cached torrent ${sanitizeInfoHash(infoHash)}${options.deleteOnFail ? " - deleting" : ""}`,
296
+ });
297
+ logger.debug(e);
298
+ if (options.deleteOnFail) {
299
+ unlinkSync(torrentPath);
300
+ }
301
+ return resultOfErr(e);
302
+ }
217
303
  }
218
304
  function cacheTorrentFile(meta) {
219
- writeFileSync(path.join(appDir(), TORRENT_CACHE_FOLDER, `${meta.infoHash}.cached.torrent`), meta.encode());
305
+ const torrentPath = path.join(appDir(), TORRENT_CACHE_FOLDER, `${meta.infoHash}.cached.torrent`);
306
+ if (existsInTorrentCache(meta.infoHash))
307
+ return;
308
+ writeFileSync(torrentPath, meta.encode());
220
309
  }
221
- async function assessAndSaveResults(result, searchee, guid, infoHashesToExclude) {
222
- const assessment = await assessCandidateHelper(result, searchee, infoHashesToExclude);
223
- if (assessment.decision === Decision.MATCH ||
224
- assessment.decision === Decision.MATCH_SIZE_ONLY ||
225
- assessment.decision === Decision.MATCH_PARTIAL) {
226
- cacheTorrentFile(assessment.metafile);
227
- }
310
+ async function assessAndSaveResults(metaOrCandidate, searchee, guid, infoHashesToExclude, firstSeen) {
311
+ const assessment = await assessCandidate(metaOrCandidate, searchee, infoHashesToExclude);
228
312
  await db.transaction(async (trx) => {
229
- const now = Date.now();
230
313
  const { id } = await trx("searchee")
231
314
  .select("id")
232
- .where({ name: searchee.name })
315
+ .where({ name: searchee.title })
233
316
  .first();
234
- await trx("decision").insert({
317
+ await trx("decision")
318
+ .insert({
235
319
  searchee_id: id,
236
320
  guid: guid,
321
+ info_hash: assessment.metafile?.infoHash ?? null,
237
322
  decision: assessment.decision,
238
- info_hash: assessment.decision === Decision.MATCH ||
239
- assessment.decision === Decision.MATCH_SIZE_ONLY ||
240
- assessment.decision === Decision.MATCH_PARTIAL
241
- ? assessment.metafile.infoHash
242
- : null,
243
- last_seen: now,
244
- first_seen: now,
245
- });
323
+ first_seen: firstSeen,
324
+ last_seen: Date.now(),
325
+ fuzzy_size_factor: getFuzzySizeFactor(),
326
+ })
327
+ .onConflict(["searchee_id", "guid"])
328
+ .merge();
246
329
  });
247
330
  return assessment;
248
331
  }
249
- async function assessCandidateCaching(candidate, searchee, infoHashesToExclude) {
332
+ /**
333
+ * Some trackers have alt titles which get their own guid but resolve to same torrent
334
+ * @param guid The guid of the candidate
335
+ * @returns The info hash of the torrent if found
336
+ */
337
+ async function fuzzyGuidLookup(guid) {
338
+ if (!guid.includes(".tv/torrent/"))
339
+ return;
340
+ const torrentIdStr = guid.match(/\.tv\/torrent\/(\d+)\/group/)?.[1];
341
+ if (!torrentIdStr)
342
+ return;
343
+ return (await db("decision")
344
+ .select({ infoHash: "info_hash" })
345
+ .where("guid", "like", `%.tv/torrent/${torrentIdStr}/group%`)
346
+ .whereNotNull("info_hash")
347
+ .first())?.infoHash;
348
+ }
349
+ export async function assessCandidateCaching(candidate, searchee, infoHashesToExclude) {
250
350
  const { guid, name, tracker } = candidate;
251
- const logReason = createReasonLogger(name, tracker, searchee.name);
252
351
  const cacheEntry = await db("decision")
253
352
  .select({
254
- decision: "decision.decision",
255
- infoHash: "decision.info_hash",
256
353
  id: "decision.id",
354
+ infoHash: "decision.info_hash",
355
+ decision: "decision.decision",
356
+ firstSeen: "decision.first_seen",
357
+ fuzzySizeFactor: "decision.fuzzy_size_factor",
257
358
  })
258
359
  .join("searchee", "decision.searchee_id", "searchee.id")
259
- .where({ name: searchee.name, guid })
360
+ .where({ name: searchee.title, guid })
260
361
  .first();
362
+ const metaInfoHash = (await db("decision")
363
+ .select({ infoHash: "info_hash" })
364
+ .where({ guid })
365
+ .whereNotNull("info_hash")
366
+ .first())?.infoHash ?? (await fuzzyGuidLookup(guid));
367
+ const metaOrCandidate = metaInfoHash
368
+ ? existsInTorrentCache(metaInfoHash)
369
+ ? (await getCachedTorrentFile(metaInfoHash)).orElse(candidate)
370
+ : candidate
371
+ : candidate;
372
+ if (metaOrCandidate instanceof Metafile) {
373
+ logger.verbose({
374
+ label: Label.DECIDE,
375
+ message: `Using cached torrent ${sanitizeInfoHash(metaInfoHash)} for ${tracker} assessment ${name}`,
376
+ });
377
+ candidate.size = metaOrCandidate.length; // Trackers can be wrong
378
+ }
261
379
  let assessment;
262
- if (!cacheEntry?.decision ||
263
- cacheEntry.decision === Decision.DOWNLOAD_FAILED ||
264
- cacheEntry.decision === Decision.RATE_LIMITED) {
265
- assessment = await assessAndSaveResults(candidate, searchee, guid, infoHashesToExclude);
266
- logReason(assessment.decision, false, searchee, candidate);
380
+ if (!cacheEntry?.decision) {
381
+ // New candidate, could be metafile from cache
382
+ assessment = await assessAndSaveResults(metaOrCandidate, searchee, guid, infoHashesToExclude, Date.now());
267
383
  }
268
- else if ((cacheEntry.decision === Decision.MATCH ||
269
- cacheEntry.decision === Decision.MATCH_SIZE_ONLY ||
270
- cacheEntry.decision === Decision.MATCH_PARTIAL) &&
384
+ else if (isAnyMatchedDecision(cacheEntry.decision) &&
271
385
  infoHashesToExclude.includes(cacheEntry.infoHash)) {
272
- // has been added since the last run
386
+ // Already injected fast path, preserve match decision
273
387
  assessment = { decision: Decision.INFO_HASH_ALREADY_EXISTS };
274
- await db("decision")
275
- .where({ id: cacheEntry.id })
276
- .update({ decision: Decision.INFO_HASH_ALREADY_EXISTS });
277
- }
278
- else if ((cacheEntry.decision === Decision.MATCH ||
279
- cacheEntry.decision === Decision.MATCH_SIZE_ONLY ||
280
- cacheEntry.decision === Decision.MATCH_PARTIAL) &&
281
- existsInTorrentCache(cacheEntry.infoHash)) {
282
- // cached match
283
- assessment = {
284
- decision: cacheEntry.decision,
285
- metafile: await getCachedTorrentFile(cacheEntry.infoHash),
286
- };
388
+ await db("decision").where({ id: cacheEntry.id }).update({
389
+ last_seen: Date.now(),
390
+ });
287
391
  }
288
- else if (cacheEntry.decision === Decision.MATCH ||
289
- cacheEntry.decision === Decision.MATCH_SIZE_ONLY ||
290
- cacheEntry.decision === Decision.MATCH_PARTIAL) {
291
- assessment = await assessAndSaveResults(candidate, searchee, guid, infoHashesToExclude);
292
- logReason(assessment.decision, false, searchee, candidate);
392
+ else if (isStaticDecision(cacheEntry.decision)) {
393
+ // These decisions will never change unless we update their logic
394
+ assessment = { decision: cacheEntry.decision };
395
+ await db("decision").where({ id: cacheEntry.id }).update({
396
+ last_seen: Date.now(),
397
+ });
293
398
  }
294
399
  else {
295
- // cached rejection
296
- assessment = { decision: cacheEntry.decision };
297
- logReason(cacheEntry.decision, true, searchee, candidate);
400
+ // Re-assess decisions using Metafile if cached
401
+ if (cacheEntry.decision !== Decision.FUZZY_SIZE_MISMATCH ||
402
+ cacheEntry.fuzzySizeFactor < getFuzzySizeFactor()) {
403
+ assessment = await assessAndSaveResults(metaOrCandidate, searchee, guid, infoHashesToExclude, cacheEntry.firstSeen);
404
+ }
405
+ else {
406
+ assessment = { decision: Decision.FUZZY_SIZE_MISMATCH };
407
+ await db("decision").where({ id: cacheEntry.id }).update({
408
+ last_seen: Date.now(),
409
+ });
410
+ }
298
411
  }
299
- // if previously known
300
- if (cacheEntry) {
301
- await db("decision")
302
- .where({ id: cacheEntry.id })
303
- .update({ last_seen: Date.now() });
412
+ const wasCached = cacheEntry?.decision === assessment.decision;
413
+ if (!wasCached) {
414
+ logDecision(searchee, candidate, assessment.decision, assessment.metafile, tracker);
304
415
  }
305
416
  return assessment;
306
417
  }
307
- export { assessCandidateCaching as assessCandidate };
308
418
  //# sourceMappingURL=decide.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"decide.js","sourceRoot":"","sources":["../src/decide.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAC/C,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EACN,QAAQ,EACR,SAAS,EACT,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,GACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG5C,OAAO,EAAE,+BAA+B,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAO/C,MAAM,kBAAkB,GACvB,CAAC,KAAa,EAAE,OAAe,EAAE,IAAY,EAAE,EAAE,CACjD,CACC,QAAkB,EAClB,MAAM,EACN,QAAkB,EAClB,SAAoB,EACb,EAAE;IACT,SAAS,SAAS,CAAC,MAAM;QACxB,MAAM,CAAC,OAAO,CAAC;YACd,KAAK,EAAE,KAAK,CAAC,MAAM;YACnB,OAAO,EAAE,GAAG,IAAI,mBAAmB,OAAO,YAAY,KAAK,MAAM,MAAM,EAAE;SACzE,CAAC,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC;IAElD,IAAI,MAAM,CAAC;IACX,QAAQ,QAAQ,EAAE,CAAC;QAClB,KAAK,QAAQ,CAAC,aAAa;YAC1B,OAAO;QACR,KAAK,QAAQ,CAAC,eAAe;YAC5B,OAAO;QACR,KAAK,QAAQ,CAAC,KAAK;YAClB,OAAO;QACR,KAAK,QAAQ,CAAC,aAAa;YAC1B,MAAM,GAAG,8BACR,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC,6BAA6B;gBAC1D,CAAC,CAAC,GAAG,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;gBACjF,CAAC,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,QAAQ,QACzC,GAAG,CAAC;YACJ,MAAM;QACP,KAAK,QAAQ,CAAC,mBAAmB;YAChC,MAAM,GAAG,oCAAoC,QAAQ,CAAC,IAAI;iBACxD,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC7B,EAAE,IAAI,EAAE,OAAO,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC;YACvE,MAAM;QACP,KAAK,QAAQ,CAAC,gBAAgB;YAC7B,MAAM,GAAG,iCAAiC,CAAC;YAC3C,MAAM;QACP,KAAK,QAAQ,CAAC,YAAY;YACzB,MAAM,GAAG,kDAAkD,CAAC;YAC5D,MAAM;QACP,KAAK,QAAQ,CAAC,eAAe;YAC5B,MAAM,GAAG,qCAAqC,CAAC;YAC/C,MAAM;QACP,KAAK,QAAQ,CAAC,wBAAwB;YACrC,MAAM,GAAG,kDAAkD,CAAC;YAC5D,MAAM;QACP,KAAK,QAAQ,CAAC,kBAAkB;YAC/B,MAAM,GAAG,8BAA8B,CAAC;YACxC,MAAM;QACP,KAAK,QAAQ,CAAC,sBAAsB;YACnC,MAAM,GAAG,uCAAuC,QAAQ,CAAC,IAAI;iBAC3D,KAAK,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,CAAC;gBAChC,EAAE,IAAI,EAAE,OAAO,SAAS,CAAC,IAAI;iBAC5B,KAAK,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,CAAC;gBAChC,EAAE,IAAI,EAAE,GAAG,CAAC;YACb,MAAM;QACP,KAAK,QAAQ,CAAC,sBAAsB;YACnC,MAAM,GAAG,4CACR,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,IAAI;gBACtD,SACD,OAAO,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,IAAI,IAAI,SAAS,GAAG,CAAC;YAC/E,MAAM;QACP,KAAK,QAAQ,CAAC,eAAe;YAC5B,MAAM,GAAG,gCAAgC,+BAA+B,CACvE,QAAQ,EACR,gBAAgB,EAAE,CAAC,SAAS,CAC5B,IAAI,CAAC;YACN,MAAM;QACP;YACC,MAAM,GAAG,QAAQ,CAAC;YAClB,MAAM;IACR,CAAC;IACD,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,SAAS,CAAC,MAAM,CAAC,CAAC;IACnB,CAAC;AACF,CAAC,CAAC;AAEH,MAAM,UAAU,gBAAgB,CAC/B,SAAmB,EACnB,QAAkB;IAElB,MAAM,GAAG,GAAG,CAAC,KAAW,EAAE,KAAW,EAAE,EAAE;QACxC,MAAM,eAAe,GAAG,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC;QACtD,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC;QAEhD,OAAO,eAAe,IAAI,aAAa,CAAC;IACzC,CAAC,CAAC;IAEF,OAAO,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CACtC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CACjD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,6BAA6B,CAC5C,SAAmB,EACnB,QAAkB;IAElB,MAAM,GAAG,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE;QACnC,OAAO,QAAQ,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,CAAC;IAC7C,CAAC,CAAC;IAEF,OAAO,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CACtC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CACjD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oCAAoC,CACnD,SAAmB,EACnB,QAAkB;IAElB,MAAM,EAAE,kBAAkB,EAAE,GAAG,gBAAgB,EAAE,CAAC;IAClD,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,aAAa,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;QAC7C,MAAM,mBAAmB,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAC9C,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,KAAK,aAAa,CAAC,MAAM,CAC9D,CAAC;QACF,IAAI,mBAAmB,EAAE,CAAC;YACzB,YAAY,IAAI,aAAa,CAAC,MAAM,CAAC;QACtC,CAAC;IACF,CAAC;IACD,OAAO,YAAY,GAAG,SAAS,CAAC,MAAM,IAAI,CAAC,GAAG,kBAAkB,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,uBAAuB,CACtC,SAAmB,EACnB,QAAkB;IAElB,MAAM,EAAE,kBAAkB,EAAE,GAAG,gBAAgB,EAAE,CAAC;IAClD,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,aAAa,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;QAC7C,IAAI,oBAAoB,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAC/C,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,KAAK,aAAa,CAAC,MAAM,CAC9D,CAAC;QACF,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrC,oBAAoB,GAAG,oBAAoB,CAAC,MAAM,CACjD,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,KAAK,aAAa,CAAC,IAAI,CAC1D,CAAC;QACH,CAAC;QACD,IAAI,oBAAoB,CAAC,MAAM,EAAE,CAAC;YACjC,YAAY,IAAI,aAAa,CAAC,MAAM,CAAC;QACtC,CAAC;IACF,CAAC;IACD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;IACxE,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;IACzE,OAAO,eAAe,GAAG,WAAW,IAAI,CAAC,GAAG,kBAAkB,CAAC;AAChE,CAAC;AAED,SAAS,aAAa,CAAC,UAAkB,EAAE,QAAkB;IAC5D,MAAM,EAAE,kBAAkB,EAAE,GAAG,gBAAgB,EAAE,CAAC;IAElD,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC;IAC5B,MAAM,UAAU,GAAG,MAAM,GAAG,kBAAkB,GAAG,MAAM,CAAC;IACxD,MAAM,UAAU,GAAG,MAAM,GAAG,kBAAkB,GAAG,MAAM,CAAC;IACxD,OAAO,UAAU,IAAI,UAAU,IAAI,UAAU,IAAI,UAAU,CAAC;AAC7D,CAAC;AACD,SAAS,uBAAuB,CAC/B,YAAoB,EACpB,aAAqB,EACrB,SAAoB;IAEpB,MAAM,mBAAmB,GAAG,YAAY,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACpE,MAAM,oBAAoB,GAAG,aAAa,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACtE,MAAM,eAAe,GAAG,mBAAmB,EAAE,MAAM,EAAE,IAAI;QACxD,EAAE,IAAI,EAAE;QACR,EAAE,WAAW,EAAE,CAAC;IACjB,MAAM,gBAAgB,GAAG,oBAAoB,EAAE,MAAM,EAAE,IAAI;QAC1D,EAAE,IAAI,EAAE;QACR,EAAE,WAAW,EAAE,CAAC;IAEjB,IACC,eAAe,KAAK,gBAAgB;QACpC,mBAAmB,EAAE,MAAM,EAAE,OAAO,EACnC,CAAC;QACF,OAAO,SAAS,KAAK,SAAS,CAAC,IAAI,CAAC;IACrC,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AACD,SAAS,qBAAqB,CAC7B,YAAoB,EACpB,aAAqB,EACrB,SAAoB;IAEpB,MAAM,oBAAoB,GAAG,YAAY;SACvC,KAAK,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,CAAC;QAChC,EAAE,IAAI,EAAE;QACR,EAAE,WAAW,EAAE,CAAC;IACjB,MAAM,qBAAqB,GAAG,aAAa;SACzC,KAAK,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,CAAC;QAChC,EAAE,IAAI,EAAE;QACR,EAAE,WAAW,EAAE,CAAC;IACjB,IAAI,oBAAoB,KAAK,qBAAqB,EAAE,CAAC;QACpD,OAAO,IAAI,CAAC;IACb,CAAC;IACD,wEAAwE;IACxE,IAAI,CAAC,oBAAoB,IAAI,CAAC,qBAAqB,EAAE,CAAC;QACrD,OAAO,SAAS,KAAK,SAAS,CAAC,IAAI,CAAC;IACrC,CAAC;IACD,OAAO,oBAAoB,CAAC,UAAU,CAAC,qBAAqB,CAAC,CAAC;AAC/D,CAAC;AAED,KAAK,UAAU,qBAAqB,CACnC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAa,EACxC,QAAkB,EAClB,eAAyB;IAEzB,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,gBAAgB,EAAE,CAAC;IACpD,IAAI,+BAA+B,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,CAAC;QAC1D,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,eAAe,EAAE,CAAC;IAC/C,CAAC;IAED,IAAI,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC;QAC5C,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,aAAa,EAAE,CAAC;IAC7C,CAAC;IAED,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,gBAAgB,EAAE,CAAC;IAE1D,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC;QAC5D,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,sBAAsB,EAAE,CAAC;IACtD,CAAC;IACD,IAAI,CAAC,uBAAuB,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC;QAC9D,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,sBAAsB,EAAE,CAAC;IACtD,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAE3C,IAAI,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC;QACpB,OAAO,MAAM,CAAC,SAAS,EAAE,KAAK,WAAW,CAAC,YAAY;YACrD,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,YAAY,EAAE;YACrC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,eAAe,EAAE,CAAC;IAC3C,CAAC;IAED,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;IAEtC,IAAI,eAAe,CAAC,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtD,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,wBAAwB,EAAE,CAAC;IACxD,CAAC;IACD,MAAM,SAAS,GAAG,6BAA6B,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;IACzE,MAAM,YAAY,GAAG,gBAAgB,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;IAE/D,IAAI,YAAY,EAAE,CAAC;QAClB,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC9D,CAAC;IACD,IACC,SAAS;QACT,SAAS,KAAK,SAAS,CAAC,IAAI;QAC5B,QAAQ,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAC1B,CAAC;QACF,OAAO;YACN,QAAQ,EAAE,QAAQ,CAAC,eAAe;YAClC,QAAQ,EAAE,aAAa;SACvB,CAAC;IACH,CAAC;IAED,IAAI,SAAS,KAAK,SAAS,CAAC,OAAO,EAAE,CAAC;QACrC,MAAM,gBAAgB,GAAG,oCAAoC,CAC5D,aAAa,EACb,QAAQ,CACR,CAAC;QACF,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACvB,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,aAAa,EAAE,CAAC;QAC7C,CAAC;QAED,MAAM,YAAY,GAAG,uBAAuB,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;QACtE,IAAI,YAAY,EAAE,CAAC;YAClB,OAAO;gBACN,QAAQ,EAAE,QAAQ,CAAC,aAAa;gBAChC,QAAQ,EAAE,aAAa;aACvB,CAAC;QACH,CAAC;IACF,CAAC;SAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACvB,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,aAAa,EAAE,CAAC;IAC7C,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,kBAAkB,EAAE,CAAC;AAClD,CAAC;AAED,SAAS,oBAAoB,CAAC,QAAgB;IAC7C,OAAO,UAAU,CAChB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,oBAAoB,EAAE,GAAG,QAAQ,iBAAiB,CAAC,CACvE,CAAC;AACH,CAAC;AAED,KAAK,UAAU,oBAAoB,CAAC,QAAgB;IACnD,OAAO,wBAAwB,CAC9B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,oBAAoB,EAAE,GAAG,QAAQ,iBAAiB,CAAC,CACvE,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAc;IACvC,aAAa,CACZ,IAAI,CAAC,IAAI,CACR,MAAM,EAAE,EACR,oBAAoB,EACpB,GAAG,IAAI,CAAC,QAAQ,iBAAiB,CACjC,EACD,IAAI,CAAC,MAAM,EAAE,CACb,CAAC;AACH,CAAC;AAED,KAAK,UAAU,oBAAoB,CAClC,MAAiB,EACjB,QAAkB,EAClB,IAAY,EACZ,mBAA6B;IAE7B,MAAM,UAAU,GAAG,MAAM,qBAAqB,CAC7C,MAAM,EACN,QAAQ,EACR,mBAAmB,CACnB,CAAC;IAEF,IACC,UAAU,CAAC,QAAQ,KAAK,QAAQ,CAAC,KAAK;QACtC,UAAU,CAAC,QAAQ,KAAK,QAAQ,CAAC,eAAe;QAChD,UAAU,CAAC,QAAQ,KAAK,QAAQ,CAAC,aAAa,EAC7C,CAAC;QACF,gBAAgB,CAAC,UAAU,CAAC,QAAS,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC;aAClC,MAAM,CAAC,IAAI,CAAC;aACZ,KAAK,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;aAC9B,KAAK,EAAE,CAAC;QACV,MAAM,GAAG,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC;YAC5B,WAAW,EAAE,EAAE;YACf,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,UAAU,CAAC,QAAQ;YAC7B,SAAS,EACR,UAAU,CAAC,QAAQ,KAAK,QAAQ,CAAC,KAAK;gBACtC,UAAU,CAAC,QAAQ,KAAK,QAAQ,CAAC,eAAe;gBAChD,UAAU,CAAC,QAAQ,KAAK,QAAQ,CAAC,aAAa;gBAC7C,CAAC,CAAC,UAAU,CAAC,QAAS,CAAC,QAAQ;gBAC/B,CAAC,CAAC,IAAI;YACR,SAAS,EAAE,GAAG;YACd,UAAU,EAAE,GAAG;SACf,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,OAAO,UAAU,CAAC;AACnB,CAAC;AAED,KAAK,UAAU,sBAAsB,CACpC,SAAoB,EACpB,QAAkB,EAClB,mBAA6B;IAE7B,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC;IAC1C,MAAM,SAAS,GAAG,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IAEnE,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC;SACrC,MAAM,CAAC;QACP,QAAQ,EAAE,mBAAmB;QAC7B,QAAQ,EAAE,oBAAoB;QAC9B,EAAE,EAAE,aAAa;KACjB,CAAC;SACD,IAAI,CAAC,UAAU,EAAE,sBAAsB,EAAE,aAAa,CAAC;SACvD,KAAK,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;SACpC,KAAK,EAAE,CAAC;IACV,IAAI,UAA4B,CAAC;IAEjC,IACC,CAAC,UAAU,EAAE,QAAQ;QACrB,UAAU,CAAC,QAAQ,KAAK,QAAQ,CAAC,eAAe;QAChD,UAAU,CAAC,QAAQ,KAAK,QAAQ,CAAC,YAAY,EAC5C,CAAC;QACF,UAAU,GAAG,MAAM,oBAAoB,CACtC,SAAS,EACT,QAAQ,EACR,IAAI,EACJ,mBAAmB,CACnB,CAAC;QACF,SAAS,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC5D,CAAC;SAAM,IACN,CAAC,UAAU,CAAC,QAAQ,KAAK,QAAQ,CAAC,KAAK;QACtC,UAAU,CAAC,QAAQ,KAAK,QAAQ,CAAC,eAAe;QAChD,UAAU,CAAC,QAAQ,KAAK,QAAQ,CAAC,aAAa,CAAC;QAChD,mBAAmB,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,EAChD,CAAC;QACF,oCAAoC;QACpC,UAAU,GAAG,EAAE,QAAQ,EAAE,QAAQ,CAAC,wBAAwB,EAAE,CAAC;QAC7D,MAAM,EAAE,CAAC,UAAU,CAAC;aAClB,KAAK,CAAC,EAAE,EAAE,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC;aAC5B,MAAM,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,wBAAwB,EAAE,CAAC,CAAC;IAC3D,CAAC;SAAM,IACN,CAAC,UAAU,CAAC,QAAQ,KAAK,QAAQ,CAAC,KAAK;QACtC,UAAU,CAAC,QAAQ,KAAK,QAAQ,CAAC,eAAe;QAChD,UAAU,CAAC,QAAQ,KAAK,QAAQ,CAAC,aAAa,CAAC;QAChD,oBAAoB,CAAC,UAAU,CAAC,QAAQ,CAAC,EACxC,CAAC;QACF,eAAe;QACf,UAAU,GAAG;YACZ,QAAQ,EAAE,UAAU,CAAC,QAAQ;YAC7B,QAAQ,EAAE,MAAM,oBAAoB,CAAC,UAAU,CAAC,QAAQ,CAAC;SACzD,CAAC;IACH,CAAC;SAAM,IACN,UAAU,CAAC,QAAQ,KAAK,QAAQ,CAAC,KAAK;QACtC,UAAU,CAAC,QAAQ,KAAK,QAAQ,CAAC,eAAe;QAChD,UAAU,CAAC,QAAQ,KAAK,QAAQ,CAAC,aAAa,EAC7C,CAAC;QACF,UAAU,GAAG,MAAM,oBAAoB,CACtC,SAAS,EACT,QAAQ,EACR,IAAI,EACJ,mBAAmB,CACnB,CAAC;QACF,SAAS,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC5D,CAAC;SAAM,CAAC;QACP,mBAAmB;QACnB,UAAU,GAAG,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC;QAC/C,SAAS,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC3D,CAAC;IACD,sBAAsB;IACtB,IAAI,UAAU,EAAE,CAAC;QAChB,MAAM,EAAE,CAAC,UAAU,CAAC;aAClB,KAAK,CAAC,EAAE,EAAE,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC;aAC5B,MAAM,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,UAAU,CAAC;AACnB,CAAC;AAED,OAAO,EAAE,sBAAsB,IAAI,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"decide.js","sourceRoot":"","sources":["../src/decide.ts"],"names":[],"mappings":"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"}