@chainpatrol/sdk 1.7.0 → 1.9.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.
- package/CHANGELOG.md +28 -0
- package/dist/api/index.d.mts +36 -2
- package/dist/api/index.d.ts +36 -2
- package/dist/api/index.js +8 -0
- package/dist/api/index.js.map +1 -1
- package/dist/api/index.mjs +8 -0
- package/dist/api/index.mjs.map +1 -1
- package/dist/{chunk-ZTE6QNOQ.mjs → chunk-O5IZ7M5X.mjs} +10 -8
- package/dist/chunk-O5IZ7M5X.mjs.map +1 -0
- package/dist/index.js +738 -76
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +738 -76
- package/dist/index.mjs.map +1 -1
- package/dist/skill/cli.js +8 -6
- package/dist/skill/cli.js.map +1 -1
- package/dist/skill/cli.mjs +1 -1
- package/dist/skill/index.js +8 -6
- package/dist/skill/index.js.map +1 -1
- package/dist/skill/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/chunk-ZTE6QNOQ.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1255,17 +1255,17 @@ var PolyDateFormatter = class {
|
|
|
1255
1255
|
constructor(dt, intl, opts) {
|
|
1256
1256
|
this.opts = opts;
|
|
1257
1257
|
this.originalZone = void 0;
|
|
1258
|
-
let
|
|
1258
|
+
let z56 = void 0;
|
|
1259
1259
|
if (this.opts.timeZone) {
|
|
1260
1260
|
this.dt = dt;
|
|
1261
1261
|
} else if (dt.zone.type === "fixed") {
|
|
1262
1262
|
const gmtOffset = -1 * (dt.offset / 60);
|
|
1263
1263
|
const offsetZ = gmtOffset >= 0 ? `Etc/GMT+${gmtOffset}` : `Etc/GMT${gmtOffset}`;
|
|
1264
1264
|
if (dt.offset !== 0 && IANAZone.create(offsetZ).valid) {
|
|
1265
|
-
|
|
1265
|
+
z56 = offsetZ;
|
|
1266
1266
|
this.dt = dt;
|
|
1267
1267
|
} else {
|
|
1268
|
-
|
|
1268
|
+
z56 = "UTC";
|
|
1269
1269
|
this.dt = dt.offset === 0 ? dt : dt.setZone("UTC").plus({ minutes: dt.offset });
|
|
1270
1270
|
this.originalZone = dt.zone;
|
|
1271
1271
|
}
|
|
@@ -1273,14 +1273,14 @@ var PolyDateFormatter = class {
|
|
|
1273
1273
|
this.dt = dt;
|
|
1274
1274
|
} else if (dt.zone.type === "iana") {
|
|
1275
1275
|
this.dt = dt;
|
|
1276
|
-
|
|
1276
|
+
z56 = dt.zone.name;
|
|
1277
1277
|
} else {
|
|
1278
|
-
|
|
1278
|
+
z56 = "UTC";
|
|
1279
1279
|
this.dt = dt.setZone("UTC").plus({ minutes: dt.offset });
|
|
1280
1280
|
this.originalZone = dt.zone;
|
|
1281
1281
|
}
|
|
1282
1282
|
const intlOpts = __spreadValues({}, this.opts);
|
|
1283
|
-
intlOpts.timeZone = intlOpts.timeZone ||
|
|
1283
|
+
intlOpts.timeZone = intlOpts.timeZone || z56;
|
|
1284
1284
|
this.dtf = getCachedDTF(intl, intlOpts);
|
|
1285
1285
|
}
|
|
1286
1286
|
format() {
|
|
@@ -11430,6 +11430,50 @@ z.object({
|
|
|
11430
11430
|
endDate: z.date()
|
|
11431
11431
|
})
|
|
11432
11432
|
});
|
|
11433
|
+
var DATE_ONLY_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
|
|
11434
|
+
var utcDateSchema = (endOfDay) => z.preprocess((value) => {
|
|
11435
|
+
if (typeof value !== "string") {
|
|
11436
|
+
return value;
|
|
11437
|
+
}
|
|
11438
|
+
const parsed = DateTime.fromISO(value, { zone: "utc" });
|
|
11439
|
+
if (!parsed.isValid) {
|
|
11440
|
+
return new Date(Number.NaN);
|
|
11441
|
+
}
|
|
11442
|
+
return endOfDay && DATE_ONLY_PATTERN.test(value) ? parsed.endOf("day").toJSDate() : parsed.toJSDate();
|
|
11443
|
+
}, z.coerce.date());
|
|
11444
|
+
var funnelCountsSchema = z.object({
|
|
11445
|
+
blocked: z.number().int().nonnegative().describe(
|
|
11446
|
+
"Distinct assets whose earliest report for this org falls in the range and whose current status or pending status is BLOCKED"
|
|
11447
|
+
)
|
|
11448
|
+
});
|
|
11449
|
+
z.object({
|
|
11450
|
+
slug: z.string().min(1).describe("Organization slug"),
|
|
11451
|
+
startDate: utcDateSchema(false).describe(
|
|
11452
|
+
"Only include assets whose earliest report was created on or after this date. A date-only value (YYYY-MM-DD) starts at midnight UTC"
|
|
11453
|
+
),
|
|
11454
|
+
endDate: utcDateSchema(true).describe(
|
|
11455
|
+
"Only include assets whose earliest report was created on or before this date. A date-only value (YYYY-MM-DD) covers the whole day in UTC; pass a full timestamp for a precise cut-off"
|
|
11456
|
+
),
|
|
11457
|
+
brandIds: z.array(z.number().int().positive()).optional().describe("Only include assets belonging to these brands")
|
|
11458
|
+
}).refine((input) => input.startDate.getTime() <= input.endDate.getTime(), {
|
|
11459
|
+
message: "startDate must be on or before endDate",
|
|
11460
|
+
path: ["startDate"]
|
|
11461
|
+
});
|
|
11462
|
+
z.object({
|
|
11463
|
+
range: z.object({
|
|
11464
|
+
startDate: z.date(),
|
|
11465
|
+
endDate: z.date()
|
|
11466
|
+
}),
|
|
11467
|
+
customer: funnelCountsSchema.describe(
|
|
11468
|
+
"Currently blocked assets first reported by the customer (reportedByCustomer, external reporter, or customer-role user)"
|
|
11469
|
+
),
|
|
11470
|
+
chainpatrol: funnelCountsSchema.describe(
|
|
11471
|
+
"Currently blocked assets first reported by ChainPatrol staff or automation. Staff and automation are collapsed together."
|
|
11472
|
+
),
|
|
11473
|
+
totals: funnelCountsSchema.describe(
|
|
11474
|
+
"customer + chainpatrol. This is a first-report blocked cohort and does not equal metrics/found, which counts assets by blockedAt."
|
|
11475
|
+
)
|
|
11476
|
+
});
|
|
11433
11477
|
z.object({
|
|
11434
11478
|
slug: z.string().min(1),
|
|
11435
11479
|
startDate: z.date().optional(),
|
|
@@ -11461,8 +11505,8 @@ z.object({
|
|
|
11461
11505
|
})
|
|
11462
11506
|
)
|
|
11463
11507
|
});
|
|
11464
|
-
var
|
|
11465
|
-
var
|
|
11508
|
+
var DATE_ONLY_PATTERN2 = /^\d{4}-\d{2}-\d{2}$/;
|
|
11509
|
+
var utcDateSchema2 = (endOfDay) => z.preprocess((value) => {
|
|
11466
11510
|
if (typeof value !== "string") {
|
|
11467
11511
|
return value;
|
|
11468
11512
|
}
|
|
@@ -11470,14 +11514,14 @@ var utcDateSchema = (endOfDay) => z.preprocess((value) => {
|
|
|
11470
11514
|
if (!parsed.isValid) {
|
|
11471
11515
|
return new Date(Number.NaN);
|
|
11472
11516
|
}
|
|
11473
|
-
return endOfDay &&
|
|
11517
|
+
return endOfDay && DATE_ONLY_PATTERN2.test(value) ? parsed.endOf("day").toJSDate() : parsed.toJSDate();
|
|
11474
11518
|
}, z.coerce.date());
|
|
11475
11519
|
z.object({
|
|
11476
11520
|
slug: z.string().min(1).describe("Organization slug"),
|
|
11477
|
-
startDate:
|
|
11521
|
+
startDate: utcDateSchema2(false).optional().describe(
|
|
11478
11522
|
"Only include takedowns completed on or after this date. A date-only value (YYYY-MM-DD) starts at midnight UTC"
|
|
11479
11523
|
),
|
|
11480
|
-
endDate:
|
|
11524
|
+
endDate: utcDateSchema2(true).optional().describe(
|
|
11481
11525
|
"Only include takedowns completed on or before this date. A date-only value (YYYY-MM-DD) covers the whole day in UTC; pass a full timestamp for a precise cut-off"
|
|
11482
11526
|
),
|
|
11483
11527
|
blockLabel: z.string().optional().describe(
|
|
@@ -11500,6 +11544,55 @@ z.object({
|
|
|
11500
11544
|
"Median time from takedown start to completion, one entry per asset type, ascending by median"
|
|
11501
11545
|
)
|
|
11502
11546
|
});
|
|
11547
|
+
z.object({
|
|
11548
|
+
slug: z.string().min(1).describe("Organization slug"),
|
|
11549
|
+
months: z.number().int().min(2).max(36).default(12).describe("Size of the trailing window in whole months, including the current month"),
|
|
11550
|
+
assetTypes: z.array(z.nativeEnum(AssetType)).max(5).optional().describe(
|
|
11551
|
+
"Break the trend down by these asset types, one series each. Omit for a single series pooled across every asset type"
|
|
11552
|
+
),
|
|
11553
|
+
blockLabel: z.string().optional().describe(
|
|
11554
|
+
'Only include assets blocked with this review label, e.g. "Brand Impersonation", "Employee Impersonation" or "Targeting Org Users"'
|
|
11555
|
+
),
|
|
11556
|
+
brandType: z.nativeEnum(BrandType).optional().describe("Only include assets belonging to brands of this type"),
|
|
11557
|
+
countryCodes: z.array(z.string().length(2)).optional().describe("Only include assets scanned from these ISO 3166-1 alpha-2 countries"),
|
|
11558
|
+
brandIds: z.array(z.number().int().positive()).optional().describe("Only include assets belonging to these brands")
|
|
11559
|
+
});
|
|
11560
|
+
var MetricsTakedownTimeTrendPointSchema = z.object({
|
|
11561
|
+
period: z.string().describe("Month the takedowns completed in, as a yyyy-MM key"),
|
|
11562
|
+
medianTakedownMinutes: z.number().nullable().describe("Null when no takedowns completed in this month"),
|
|
11563
|
+
medianTakedownHours: z.number().nullable(),
|
|
11564
|
+
medianTakedownDays: z.number().nullable(),
|
|
11565
|
+
count: z.number().describe("Number of completed takedowns behind the median")
|
|
11566
|
+
});
|
|
11567
|
+
var MetricsTakedownTimeTrendChangeSchema = z.object({
|
|
11568
|
+
latest: MetricsTakedownTimeTrendPointSchema.nullable().describe(
|
|
11569
|
+
"Most recent month in the window that had completed takedowns"
|
|
11570
|
+
),
|
|
11571
|
+
previous: MetricsTakedownTimeTrendPointSchema.nullable().describe(
|
|
11572
|
+
"Month with completed takedowns immediately before `latest`, skipping empty months"
|
|
11573
|
+
),
|
|
11574
|
+
percentChange: z.number().nullable().describe(
|
|
11575
|
+
"Change in the median from `previous` to `latest`, as a percentage. Negative means takedowns got faster. Null when there is no comparable earlier month"
|
|
11576
|
+
),
|
|
11577
|
+
direction: z.enum(["improved", "worsened", "unchanged"]).nullable().describe("Sign of `percentChange`, read as lower-is-better. Null when it is null")
|
|
11578
|
+
});
|
|
11579
|
+
z.object({
|
|
11580
|
+
months: z.number().describe("Size of the trailing window that was used"),
|
|
11581
|
+
periods: z.array(z.string()).describe("Every yyyy-MM key in the window, oldest first"),
|
|
11582
|
+
series: z.array(
|
|
11583
|
+
z.object({
|
|
11584
|
+
assetType: z.nativeEnum(AssetType).nullable().describe("Null for the series pooled across every asset type"),
|
|
11585
|
+
points: z.array(MetricsTakedownTimeTrendPointSchema).describe(
|
|
11586
|
+
"One point per month in the window, oldest first. Months with no completed takedowns carry a null median"
|
|
11587
|
+
),
|
|
11588
|
+
change: MetricsTakedownTimeTrendChangeSchema.describe(
|
|
11589
|
+
"Month-over-month comparison for this series"
|
|
11590
|
+
)
|
|
11591
|
+
})
|
|
11592
|
+
).describe(
|
|
11593
|
+
"One series per requested asset type, in the order requested, or a single pooled series when no asset types were given"
|
|
11594
|
+
)
|
|
11595
|
+
});
|
|
11503
11596
|
z.object({
|
|
11504
11597
|
slug: z.string().optional().describe(
|
|
11505
11598
|
"Organization slug. Optional for organization-scoped API keys, which resolve the organization from the key itself. Required when your credentials can reach more than one organization."
|
|
@@ -11886,7 +11979,9 @@ var organizationMetricsIncludeFieldSchema = z.enum([
|
|
|
11886
11979
|
"newThreats",
|
|
11887
11980
|
"threatsWatchlisted",
|
|
11888
11981
|
"takedownsFiled",
|
|
11982
|
+
"takedownsInProgress",
|
|
11889
11983
|
"takedownsCompleted",
|
|
11984
|
+
"takedownsCancelled",
|
|
11890
11985
|
"domainThreats",
|
|
11891
11986
|
"twitterThreats",
|
|
11892
11987
|
"telegramThreats",
|
|
@@ -11928,7 +12023,7 @@ z.object({
|
|
|
11928
12023
|
startDate: z.coerce.date().optional(),
|
|
11929
12024
|
endDate: z.coerce.date().optional(),
|
|
11930
12025
|
include: z.array(organizationMetricsIncludeFieldSchema).optional().describe(
|
|
11931
|
-
"Subset of metrics to compute. When omitted or empty, every metric is computed (legacy behavior). Each value in `include` costs roughly one
|
|
12026
|
+
"Subset of metrics to compute. When omitted or empty, every metric is computed (legacy behavior). Each value in `include` costs roughly one aggregate query, so narrow the list when an agent only needs a couple of numbers \u2014 this is the main lever for keeping big-org calls inside the 30s function cap. Fields not in `include` come back as `null`. `takedownsInProgress` and `takedownsCancelled` count takedowns currently in that status whose `updatedAt` falls in the window (same windowing as `takedownsFiled`), so they reconcile with the takedowns list filtered by status over the same date range."
|
|
11932
12027
|
)
|
|
11933
12028
|
}).refine(
|
|
11934
12029
|
(value) => {
|
|
@@ -11956,7 +12051,9 @@ var metricsObjectSchema = z.object({
|
|
|
11956
12051
|
newThreats: metricValue,
|
|
11957
12052
|
threatsWatchlisted: metricValue,
|
|
11958
12053
|
takedownsFiled: metricValue,
|
|
12054
|
+
takedownsInProgress: metricValue,
|
|
11959
12055
|
takedownsCompleted: metricValue,
|
|
12056
|
+
takedownsCancelled: metricValue,
|
|
11960
12057
|
domainThreats: metricValue,
|
|
11961
12058
|
twitterThreats: metricValue,
|
|
11962
12059
|
telegramThreats: metricValue,
|
|
@@ -13339,20 +13436,20 @@ var convertA98ToXyz65_default = convertA98ToXyz65;
|
|
|
13339
13436
|
|
|
13340
13437
|
// ../../node_modules/culori/src/a98/convertXyz65ToA98.js
|
|
13341
13438
|
var gamma = (v) => Math.pow(Math.abs(v), 256 / 563) * Math.sign(v);
|
|
13342
|
-
var convertXyz65ToA98 = ({ x, y, z:
|
|
13439
|
+
var convertXyz65ToA98 = ({ x, y, z: z56, alpha }) => {
|
|
13343
13440
|
if (x === void 0) x = 0;
|
|
13344
13441
|
if (y === void 0) y = 0;
|
|
13345
|
-
if (
|
|
13442
|
+
if (z56 === void 0) z56 = 0;
|
|
13346
13443
|
let res = {
|
|
13347
13444
|
mode: "a98",
|
|
13348
13445
|
r: gamma(
|
|
13349
|
-
x * 2.0415879038107465 - y * 0.5650069742788597 - 0.3447313507783297 *
|
|
13446
|
+
x * 2.0415879038107465 - y * 0.5650069742788597 - 0.3447313507783297 * z56
|
|
13350
13447
|
),
|
|
13351
13448
|
g: gamma(
|
|
13352
|
-
x * -0.9692436362808798 + y * 1.8759675015077206 + 0.0415550574071756 *
|
|
13449
|
+
x * -0.9692436362808798 + y * 1.8759675015077206 + 0.0415550574071756 * z56
|
|
13353
13450
|
),
|
|
13354
13451
|
b: gamma(
|
|
13355
|
-
x * 0.0134442806320312 - y * 0.1183623922310184 + 1.0151749943912058 *
|
|
13452
|
+
x * 0.0134442806320312 - y * 0.1183623922310184 + 1.0151749943912058 * z56
|
|
13356
13453
|
)
|
|
13357
13454
|
};
|
|
13358
13455
|
if (alpha !== void 0) {
|
|
@@ -13419,14 +13516,14 @@ var convertLrgbToRgb = ({ r, g, b, alpha }, mode = "rgb") => {
|
|
|
13419
13516
|
var convertLrgbToRgb_default = convertLrgbToRgb;
|
|
13420
13517
|
|
|
13421
13518
|
// ../../node_modules/culori/src/xyz65/convertXyz65ToRgb.js
|
|
13422
|
-
var convertXyz65ToRgb = ({ x, y, z:
|
|
13519
|
+
var convertXyz65ToRgb = ({ x, y, z: z56, alpha }) => {
|
|
13423
13520
|
if (x === void 0) x = 0;
|
|
13424
13521
|
if (y === void 0) y = 0;
|
|
13425
|
-
if (
|
|
13522
|
+
if (z56 === void 0) z56 = 0;
|
|
13426
13523
|
let res = convertLrgbToRgb_default({
|
|
13427
|
-
r: x * 3.2409699419045226 - y * 1.537383177570094 - 0.4986107602930034 *
|
|
13428
|
-
g: x * -0.9692436362808796 + y * 1.8759675015077204 + 0.0415550574071756 *
|
|
13429
|
-
b: x * 0.0556300796969936 - y * 0.2039769588889765 + 1.0569715142428784 *
|
|
13524
|
+
r: x * 3.2409699419045226 - y * 1.537383177570094 - 0.4986107602930034 * z56,
|
|
13525
|
+
g: x * -0.9692436362808796 + y * 1.8759675015077204 + 0.0415550574071756 * z56,
|
|
13526
|
+
b: x * 0.0556300796969936 - y * 0.2039769588889765 + 1.0569715142428784 * z56
|
|
13430
13527
|
});
|
|
13431
13528
|
if (alpha !== void 0) {
|
|
13432
13529
|
res.alpha = alpha;
|
|
@@ -13676,13 +13773,13 @@ var convertLab65ToRgb_default = convertLab65ToRgb;
|
|
|
13676
13773
|
|
|
13677
13774
|
// ../../node_modules/culori/src/lab65/convertXyz65ToLab65.js
|
|
13678
13775
|
var f = (value) => value > e ? Math.cbrt(value) : (k * value + 16) / 116;
|
|
13679
|
-
var convertXyz65ToLab65 = ({ x, y, z:
|
|
13776
|
+
var convertXyz65ToLab65 = ({ x, y, z: z56, alpha }) => {
|
|
13680
13777
|
if (x === void 0) x = 0;
|
|
13681
13778
|
if (y === void 0) y = 0;
|
|
13682
|
-
if (
|
|
13779
|
+
if (z56 === void 0) z56 = 0;
|
|
13683
13780
|
let f0 = f(x / D65.X);
|
|
13684
13781
|
let f1 = f(y / D65.Y);
|
|
13685
|
-
let f22 = f(
|
|
13782
|
+
let f22 = f(z56 / D65.Z);
|
|
13686
13783
|
let res = {
|
|
13687
13784
|
mode: "lab65",
|
|
13688
13785
|
l: 116 * f1 - 16,
|
|
@@ -14339,10 +14436,10 @@ var convertItpToXyz65_default = convertItpToXyz65;
|
|
|
14339
14436
|
|
|
14340
14437
|
// ../../node_modules/culori/src/itp/convertXyz65ToItp.js
|
|
14341
14438
|
var toAbs = (c2 = 0) => Math.max(c2 * YW, 0);
|
|
14342
|
-
var convertXyz65ToItp = ({ x, y, z:
|
|
14439
|
+
var convertXyz65ToItp = ({ x, y, z: z56, alpha }) => {
|
|
14343
14440
|
const absX = toAbs(x);
|
|
14344
14441
|
const absY = toAbs(y);
|
|
14345
|
-
const absZ = toAbs(
|
|
14442
|
+
const absZ = toAbs(z56);
|
|
14346
14443
|
const l2 = transferPqEncode(
|
|
14347
14444
|
0.3592832590121217 * absX + 0.6976051147779502 * absY - 0.0358915932320289 * absZ
|
|
14348
14445
|
);
|
|
@@ -14400,15 +14497,15 @@ var jabPqEncode = (v) => {
|
|
|
14400
14497
|
return Math.pow((C1 + C2 * vn3) / (1 + C3 * vn3), p);
|
|
14401
14498
|
};
|
|
14402
14499
|
var abs = (v = 0) => Math.max(v * 203, 0);
|
|
14403
|
-
var convertXyz65ToJab = ({ x, y, z:
|
|
14500
|
+
var convertXyz65ToJab = ({ x, y, z: z56, alpha }) => {
|
|
14404
14501
|
x = abs(x);
|
|
14405
14502
|
y = abs(y);
|
|
14406
|
-
|
|
14407
|
-
let xp = 1.15 * x - 0.15 *
|
|
14503
|
+
z56 = abs(z56);
|
|
14504
|
+
let xp = 1.15 * x - 0.15 * z56;
|
|
14408
14505
|
let yp = 0.66 * y + 0.34 * x;
|
|
14409
|
-
let l2 = jabPqEncode(0.41478972 * xp + 0.579999 * yp + 0.014648 *
|
|
14410
|
-
let m = jabPqEncode(-0.20151 * xp + 1.120649 * yp + 0.0531008 *
|
|
14411
|
-
let s2 = jabPqEncode(-0.0166008 * xp + 0.2648 * yp + 0.6684799 *
|
|
14506
|
+
let l2 = jabPqEncode(0.41478972 * xp + 0.579999 * yp + 0.014648 * z56);
|
|
14507
|
+
let m = jabPqEncode(-0.20151 * xp + 1.120649 * yp + 0.0531008 * z56);
|
|
14508
|
+
let s2 = jabPqEncode(-0.0166008 * xp + 0.2648 * yp + 0.6684799 * z56);
|
|
14412
14509
|
let i = (l2 + m) / 2;
|
|
14413
14510
|
let res = {
|
|
14414
14511
|
mode: "jab",
|
|
@@ -14594,14 +14691,14 @@ var convertLabToXyz50 = ({ l: l2, a, b, alpha }) => {
|
|
|
14594
14691
|
var convertLabToXyz50_default = convertLabToXyz50;
|
|
14595
14692
|
|
|
14596
14693
|
// ../../node_modules/culori/src/xyz50/convertXyz50ToRgb.js
|
|
14597
|
-
var convertXyz50ToRgb = ({ x, y, z:
|
|
14694
|
+
var convertXyz50ToRgb = ({ x, y, z: z56, alpha }) => {
|
|
14598
14695
|
if (x === void 0) x = 0;
|
|
14599
14696
|
if (y === void 0) y = 0;
|
|
14600
|
-
if (
|
|
14697
|
+
if (z56 === void 0) z56 = 0;
|
|
14601
14698
|
let res = convertLrgbToRgb_default({
|
|
14602
|
-
r: x * 3.1341359569958707 - y * 1.6173863321612538 - 0.4906619460083532 *
|
|
14603
|
-
g: x * -0.978795502912089 + y * 1.916254567259524 + 0.03344273116131949 *
|
|
14604
|
-
b: x * 0.07195537988411677 - y * 0.2289768264158322 + 1.405386058324125 *
|
|
14699
|
+
r: x * 3.1341359569958707 - y * 1.6173863321612538 - 0.4906619460083532 * z56,
|
|
14700
|
+
g: x * -0.978795502912089 + y * 1.916254567259524 + 0.03344273116131949 * z56,
|
|
14701
|
+
b: x * 0.07195537988411677 - y * 0.2289768264158322 + 1.405386058324125 * z56
|
|
14605
14702
|
});
|
|
14606
14703
|
if (alpha !== void 0) {
|
|
14607
14704
|
res.alpha = alpha;
|
|
@@ -14632,13 +14729,13 @@ var convertRgbToXyz50_default = convertRgbToXyz50;
|
|
|
14632
14729
|
|
|
14633
14730
|
// ../../node_modules/culori/src/lab/convertXyz50ToLab.js
|
|
14634
14731
|
var f2 = (value) => value > e3 ? Math.cbrt(value) : (k3 * value + 16) / 116;
|
|
14635
|
-
var convertXyz50ToLab = ({ x, y, z:
|
|
14732
|
+
var convertXyz50ToLab = ({ x, y, z: z56, alpha }) => {
|
|
14636
14733
|
if (x === void 0) x = 0;
|
|
14637
14734
|
if (y === void 0) y = 0;
|
|
14638
|
-
if (
|
|
14735
|
+
if (z56 === void 0) z56 = 0;
|
|
14639
14736
|
let f0 = f2(x / D50.X);
|
|
14640
14737
|
let f1 = f2(y / D50.Y);
|
|
14641
|
-
let f22 = f2(
|
|
14738
|
+
let f22 = f2(z56 / D50.Z);
|
|
14642
14739
|
let res = {
|
|
14643
14740
|
mode: "lab",
|
|
14644
14741
|
l: 116 * f1 - 16,
|
|
@@ -14873,18 +14970,18 @@ var convertLchuvToLuv = ({ l: l2, c: c2, h, alpha }) => {
|
|
|
14873
14970
|
var convertLchuvToLuv_default = convertLchuvToLuv;
|
|
14874
14971
|
|
|
14875
14972
|
// ../../node_modules/culori/src/luv/convertXyz50ToLuv.js
|
|
14876
|
-
var u_fn = (x, y,
|
|
14877
|
-
var v_fn = (x, y,
|
|
14973
|
+
var u_fn = (x, y, z56) => 4 * x / (x + 15 * y + 3 * z56);
|
|
14974
|
+
var v_fn = (x, y, z56) => 9 * y / (x + 15 * y + 3 * z56);
|
|
14878
14975
|
var un = u_fn(D50.X, D50.Y, D50.Z);
|
|
14879
14976
|
var vn = v_fn(D50.X, D50.Y, D50.Z);
|
|
14880
14977
|
var l_fn = (value) => value <= e3 ? k3 * value : 116 * Math.cbrt(value) - 16;
|
|
14881
|
-
var convertXyz50ToLuv = ({ x, y, z:
|
|
14978
|
+
var convertXyz50ToLuv = ({ x, y, z: z56, alpha }) => {
|
|
14882
14979
|
if (x === void 0) x = 0;
|
|
14883
14980
|
if (y === void 0) y = 0;
|
|
14884
|
-
if (
|
|
14981
|
+
if (z56 === void 0) z56 = 0;
|
|
14885
14982
|
let l2 = l_fn(y / D50.Y);
|
|
14886
|
-
let u = u_fn(x, y,
|
|
14887
|
-
let v = v_fn(x, y,
|
|
14983
|
+
let u = u_fn(x, y, z56);
|
|
14984
|
+
let v = v_fn(x, y, z56);
|
|
14888
14985
|
if (!isFinite(u) || !isFinite(v)) {
|
|
14889
14986
|
l2 = u = v = 0;
|
|
14890
14987
|
} else {
|
|
@@ -14905,8 +15002,8 @@ var convertXyz50ToLuv = ({ x, y, z: z54, alpha }) => {
|
|
|
14905
15002
|
var convertXyz50ToLuv_default = convertXyz50ToLuv;
|
|
14906
15003
|
|
|
14907
15004
|
// ../../node_modules/culori/src/luv/convertLuvToXyz50.js
|
|
14908
|
-
var u_fn2 = (x, y,
|
|
14909
|
-
var v_fn2 = (x, y,
|
|
15005
|
+
var u_fn2 = (x, y, z56) => 4 * x / (x + 15 * y + 3 * z56);
|
|
15006
|
+
var v_fn2 = (x, y, z56) => 9 * y / (x + 15 * y + 3 * z56);
|
|
14910
15007
|
var un2 = u_fn2(D50.X, D50.Y, D50.Z);
|
|
14911
15008
|
var vn2 = v_fn2(D50.X, D50.Y, D50.Z);
|
|
14912
15009
|
var convertLuvToXyz50 = ({ l: l2, u, v, alpha }) => {
|
|
@@ -14920,8 +15017,8 @@ var convertLuvToXyz50 = ({ l: l2, u, v, alpha }) => {
|
|
|
14920
15017
|
let vp = v / (13 * l2) + vn2;
|
|
14921
15018
|
let y = D50.Y * (l2 <= 8 ? l2 / k3 : Math.pow((l2 + 16) / 116, 3));
|
|
14922
15019
|
let x = y * (9 * up) / (4 * vp);
|
|
14923
|
-
let
|
|
14924
|
-
let res = { mode: "xyz50", x, y, z:
|
|
15020
|
+
let z56 = y * (12 - 3 * up - 20 * vp) / (4 * vp);
|
|
15021
|
+
let res = { mode: "xyz50", x, y, z: z56 };
|
|
14925
15022
|
if (alpha !== void 0) {
|
|
14926
15023
|
res.alpha = alpha;
|
|
14927
15024
|
}
|
|
@@ -15538,15 +15635,15 @@ var convertP3ToXyz65 = (rgb2) => {
|
|
|
15538
15635
|
var convertP3ToXyz65_default = convertP3ToXyz65;
|
|
15539
15636
|
|
|
15540
15637
|
// ../../node_modules/culori/src/p3/convertXyz65ToP3.js
|
|
15541
|
-
var convertXyz65ToP3 = ({ x, y, z:
|
|
15638
|
+
var convertXyz65ToP3 = ({ x, y, z: z56, alpha }) => {
|
|
15542
15639
|
if (x === void 0) x = 0;
|
|
15543
15640
|
if (y === void 0) y = 0;
|
|
15544
|
-
if (
|
|
15641
|
+
if (z56 === void 0) z56 = 0;
|
|
15545
15642
|
let res = convertLrgbToRgb_default(
|
|
15546
15643
|
{
|
|
15547
|
-
r: x * 2.4934969119414263 - y * 0.9313836179191242 - 0.402710784450717 *
|
|
15548
|
-
g: x * -0.8294889695615749 + y * 1.7626640603183465 + 0.0236246858419436 *
|
|
15549
|
-
b: x * 0.0358458302437845 - y * 0.0761723892680418 + 0.9568845240076871 *
|
|
15644
|
+
r: x * 2.4934969119414263 - y * 0.9313836179191242 - 0.402710784450717 * z56,
|
|
15645
|
+
g: x * -0.8294889695615749 + y * 1.7626640603183465 + 0.0236246858419436 * z56,
|
|
15646
|
+
b: x * 0.0358458302437845 - y * 0.0761723892680418 + 0.9568845240076871 * z56
|
|
15550
15647
|
},
|
|
15551
15648
|
"p3"
|
|
15552
15649
|
);
|
|
@@ -15581,19 +15678,19 @@ var gamma2 = (v) => {
|
|
|
15581
15678
|
}
|
|
15582
15679
|
return 16 * v;
|
|
15583
15680
|
};
|
|
15584
|
-
var convertXyz50ToProphoto = ({ x, y, z:
|
|
15681
|
+
var convertXyz50ToProphoto = ({ x, y, z: z56, alpha }) => {
|
|
15585
15682
|
if (x === void 0) x = 0;
|
|
15586
15683
|
if (y === void 0) y = 0;
|
|
15587
|
-
if (
|
|
15684
|
+
if (z56 === void 0) z56 = 0;
|
|
15588
15685
|
let res = {
|
|
15589
15686
|
mode: "prophoto",
|
|
15590
15687
|
r: gamma2(
|
|
15591
|
-
x * 1.3457868816471585 - y * 0.2555720873797946 - 0.0511018649755453 *
|
|
15688
|
+
x * 1.3457868816471585 - y * 0.2555720873797946 - 0.0511018649755453 * z56
|
|
15592
15689
|
),
|
|
15593
15690
|
g: gamma2(
|
|
15594
|
-
x * -0.5446307051249019 + y * 1.5082477428451466 + 0.0205274474364214 *
|
|
15691
|
+
x * -0.5446307051249019 + y * 1.5082477428451466 + 0.0205274474364214 * z56
|
|
15595
15692
|
),
|
|
15596
|
-
b: gamma2(x * 0 + y * 0 + 1.2119675456389452 *
|
|
15693
|
+
b: gamma2(x * 0 + y * 0 + 1.2119675456389452 * z56)
|
|
15597
15694
|
};
|
|
15598
15695
|
if (alpha !== void 0) {
|
|
15599
15696
|
res.alpha = alpha;
|
|
@@ -15653,20 +15750,20 @@ var gamma3 = (v) => {
|
|
|
15653
15750
|
}
|
|
15654
15751
|
return 4.5 * v;
|
|
15655
15752
|
};
|
|
15656
|
-
var convertXyz65ToRec2020 = ({ x, y, z:
|
|
15753
|
+
var convertXyz65ToRec2020 = ({ x, y, z: z56, alpha }) => {
|
|
15657
15754
|
if (x === void 0) x = 0;
|
|
15658
15755
|
if (y === void 0) y = 0;
|
|
15659
|
-
if (
|
|
15756
|
+
if (z56 === void 0) z56 = 0;
|
|
15660
15757
|
let res = {
|
|
15661
15758
|
mode: "rec2020",
|
|
15662
15759
|
r: gamma3(
|
|
15663
|
-
x * 1.7166511879712683 - y * 0.3556707837763925 - 0.2533662813736599 *
|
|
15760
|
+
x * 1.7166511879712683 - y * 0.3556707837763925 - 0.2533662813736599 * z56
|
|
15664
15761
|
),
|
|
15665
15762
|
g: gamma3(
|
|
15666
|
-
x * -0.6666843518324893 + y * 1.6164812366349395 + 0.0157685458139111 *
|
|
15763
|
+
x * -0.6666843518324893 + y * 1.6164812366349395 + 0.0157685458139111 * z56
|
|
15667
15764
|
),
|
|
15668
15765
|
b: gamma3(
|
|
15669
|
-
x * 0.0176398574453108 - y * 0.0427706132578085 + 0.9421031212354739 *
|
|
15766
|
+
x * 0.0176398574453108 - y * 0.0427706132578085 + 0.9421031212354739 * z56
|
|
15670
15767
|
)
|
|
15671
15768
|
};
|
|
15672
15769
|
if (alpha !== void 0) {
|
|
@@ -15819,15 +15916,15 @@ var definition_default26 = definition26;
|
|
|
15819
15916
|
|
|
15820
15917
|
// ../../node_modules/culori/src/xyz65/convertXyz65ToXyz50.js
|
|
15821
15918
|
var convertXyz65ToXyz50 = (xyz652) => {
|
|
15822
|
-
let { x, y, z:
|
|
15919
|
+
let { x, y, z: z56, alpha } = xyz652;
|
|
15823
15920
|
if (x === void 0) x = 0;
|
|
15824
15921
|
if (y === void 0) y = 0;
|
|
15825
|
-
if (
|
|
15922
|
+
if (z56 === void 0) z56 = 0;
|
|
15826
15923
|
let res = {
|
|
15827
15924
|
mode: "xyz50",
|
|
15828
|
-
x: 1.0479298208405488 * x + 0.0229467933410191 * y - 0.0501922295431356 *
|
|
15829
|
-
y: 0.0296278156881593 * x + 0.990434484573249 * y - 0.0170738250293851 *
|
|
15830
|
-
z: -0.0092430581525912 * x + 0.0150551448965779 * y + 0.7518742899580008 *
|
|
15925
|
+
x: 1.0479298208405488 * x + 0.0229467933410191 * y - 0.0501922295431356 * z56,
|
|
15926
|
+
y: 0.0296278156881593 * x + 0.990434484573249 * y - 0.0170738250293851 * z56,
|
|
15927
|
+
z: -0.0092430581525912 * x + 0.0150551448965779 * y + 0.7518742899580008 * z56
|
|
15831
15928
|
};
|
|
15832
15929
|
if (alpha !== void 0) {
|
|
15833
15930
|
res.alpha = alpha;
|
|
@@ -15838,15 +15935,15 @@ var convertXyz65ToXyz50_default = convertXyz65ToXyz50;
|
|
|
15838
15935
|
|
|
15839
15936
|
// ../../node_modules/culori/src/xyz65/convertXyz50ToXyz65.js
|
|
15840
15937
|
var convertXyz50ToXyz65 = (xyz502) => {
|
|
15841
|
-
let { x, y, z:
|
|
15938
|
+
let { x, y, z: z56, alpha } = xyz502;
|
|
15842
15939
|
if (x === void 0) x = 0;
|
|
15843
15940
|
if (y === void 0) y = 0;
|
|
15844
|
-
if (
|
|
15941
|
+
if (z56 === void 0) z56 = 0;
|
|
15845
15942
|
let res = {
|
|
15846
15943
|
mode: "xyz65",
|
|
15847
|
-
x: 0.9554734527042182 * x - 0.0230985368742614 * y + 0.0632593086610217 *
|
|
15848
|
-
y: -0.0283697069632081 * x + 1.0099954580058226 * y + 0.021041398966943 *
|
|
15849
|
-
z: 0.0123140016883199 * x - 0.0205076964334779 * y + 1.3303659366080753 *
|
|
15944
|
+
x: 0.9554734527042182 * x - 0.0230985368742614 * y + 0.0632593086610217 * z56,
|
|
15945
|
+
y: -0.0283697069632081 * x + 1.0099954580058226 * y + 0.021041398966943 * z56,
|
|
15946
|
+
z: 0.0123140016883199 * x - 0.0205076964334779 * y + 1.3303659366080753 * z56
|
|
15850
15947
|
};
|
|
15851
15948
|
if (alpha !== void 0) {
|
|
15852
15949
|
res.alpha = alpha;
|
|
@@ -16116,6 +16213,571 @@ z.string().optional().nullable().transform((value) => {
|
|
|
16116
16213
|
}
|
|
16117
16214
|
);
|
|
16118
16215
|
|
|
16216
|
+
// ../../internal/utils/src/industry.ts
|
|
16217
|
+
var Industry = {
|
|
16218
|
+
// Finance
|
|
16219
|
+
BANKING: "banking",
|
|
16220
|
+
FINANCIAL_SERVICES: "financial_services",
|
|
16221
|
+
FINTECH: "fintech",
|
|
16222
|
+
PAYMENTS: "payments"};
|
|
16223
|
+
|
|
16224
|
+
// ../../internal/validation/src/dark-web/templates.ts
|
|
16225
|
+
var BRAND = { kind: "brand" };
|
|
16226
|
+
var lit = (value) => ({ kind: "literal", value });
|
|
16227
|
+
var phrase = (...tokens) => ({ type: "phrase", tokens });
|
|
16228
|
+
var bn = (slop, ...words) => ({
|
|
16229
|
+
type: "phrase",
|
|
16230
|
+
tokens: [BRAND, ...words.map(lit)],
|
|
16231
|
+
slop
|
|
16232
|
+
});
|
|
16233
|
+
var nb = (slop, ...words) => ({
|
|
16234
|
+
type: "phrase",
|
|
16235
|
+
tokens: [...words.map(lit), BRAND],
|
|
16236
|
+
slop
|
|
16237
|
+
});
|
|
16238
|
+
var word = (value) => ({ type: "term", value, match: "word" });
|
|
16239
|
+
var prefix = (value) => ({
|
|
16240
|
+
type: "term",
|
|
16241
|
+
value,
|
|
16242
|
+
match: "prefix"
|
|
16243
|
+
});
|
|
16244
|
+
var or = (...children) => ({
|
|
16245
|
+
type: "group",
|
|
16246
|
+
op: "OR",
|
|
16247
|
+
children
|
|
16248
|
+
});
|
|
16249
|
+
var and = (...children) => ({
|
|
16250
|
+
type: "group",
|
|
16251
|
+
op: "AND",
|
|
16252
|
+
children
|
|
16253
|
+
});
|
|
16254
|
+
var notOneOf = (...children) => ({
|
|
16255
|
+
type: "group",
|
|
16256
|
+
op: "OR",
|
|
16257
|
+
children,
|
|
16258
|
+
negated: true
|
|
16259
|
+
});
|
|
16260
|
+
var brandWith = (...values) => and(phrase(BRAND), or(...values.map(word)));
|
|
16261
|
+
var SCAN_TEMPLATES = [
|
|
16262
|
+
{
|
|
16263
|
+
id: "p2p-instant-transfer",
|
|
16264
|
+
category: "payment-fraud",
|
|
16265
|
+
title: "P2P and instant transfer abuse",
|
|
16266
|
+
description: "Actors advertising instant peer-to-peer transfers into or out of the brand, a common way to move stolen funds before a hold clears.",
|
|
16267
|
+
// Source rows: 1, 55. The original ("[brand]"~3) was proximity on one
|
|
16268
|
+
// position, a no-op; dropped rather than ported.
|
|
16269
|
+
query: and(
|
|
16270
|
+
or(
|
|
16271
|
+
phrase(BRAND, lit("to"), BRAND),
|
|
16272
|
+
bn(2, "instant"),
|
|
16273
|
+
bn(2, "anyone"),
|
|
16274
|
+
bn(1, "pay"),
|
|
16275
|
+
bn(3, "pay anyone"),
|
|
16276
|
+
bn(2, "p2p"),
|
|
16277
|
+
bn(3, "instant transfer"),
|
|
16278
|
+
bn(3, "receive from anyone"),
|
|
16279
|
+
bn(4, "phone number"),
|
|
16280
|
+
bn(2, "member to member"),
|
|
16281
|
+
nb(3, "send")
|
|
16282
|
+
),
|
|
16283
|
+
notOneOf(word("rate"), word("price"))
|
|
16284
|
+
)
|
|
16285
|
+
},
|
|
16286
|
+
{
|
|
16287
|
+
id: "transfers-ach-direct-debit",
|
|
16288
|
+
category: "payment-fraud",
|
|
16289
|
+
title: "Transfers, ACH and direct debit",
|
|
16290
|
+
description: "Discussion of pushing or pulling funds via ACH, direct debit or bill pay, including chatter about pending and settlement timing.",
|
|
16291
|
+
// Source rows: 6, 8, 18, 41. Row 18 was missing an OR before "Direct Debit".
|
|
16292
|
+
query: or(
|
|
16293
|
+
bn(1, "transfer"),
|
|
16294
|
+
nb(1, "transfer"),
|
|
16295
|
+
bn(5, "ach"),
|
|
16296
|
+
nb(4, "pull"),
|
|
16297
|
+
nb(4, "push"),
|
|
16298
|
+
bn(4, "pending"),
|
|
16299
|
+
bn(4, "settle"),
|
|
16300
|
+
nb(4, "link"),
|
|
16301
|
+
brandWith("billpay", "acctverify"),
|
|
16302
|
+
and(phrase(BRAND), or(phrase(lit("direct debit")), phrase(lit("direct deposit"))))
|
|
16303
|
+
)
|
|
16304
|
+
},
|
|
16305
|
+
{
|
|
16306
|
+
id: "wallet-linking",
|
|
16307
|
+
category: "payment-fraud",
|
|
16308
|
+
title: "Wallet linking and instant funding",
|
|
16309
|
+
description: "Linking the brand to mobile wallets for instant funding, and 'linkable' account trading where a name match is being sold.",
|
|
16310
|
+
// Source rows: 19, 44, 51
|
|
16311
|
+
query: and(
|
|
16312
|
+
or(
|
|
16313
|
+
bn(5, "apple pay"),
|
|
16314
|
+
bn(5, "apple"),
|
|
16315
|
+
bn(3, "apple linkable"),
|
|
16316
|
+
bn(2, "linkable"),
|
|
16317
|
+
bn(2, "linkables"),
|
|
16318
|
+
nb(2, "linkable"),
|
|
16319
|
+
nb(2, "link"),
|
|
16320
|
+
and(phrase(BRAND), phrase(lit("name match")))
|
|
16321
|
+
),
|
|
16322
|
+
notOneOf(word("espn"), word("airtag"))
|
|
16323
|
+
)
|
|
16324
|
+
},
|
|
16325
|
+
{
|
|
16326
|
+
id: "card-data-exposure",
|
|
16327
|
+
category: "payment-fraud",
|
|
16328
|
+
title: "Card data and virtual cards",
|
|
16329
|
+
description: "Brand-issued card details being traded: expiry, CVV, virtual card numbers and card activation.",
|
|
16330
|
+
// Source rows: 43
|
|
16331
|
+
query: and(
|
|
16332
|
+
brandWith("exp", "cvv", "vcc", "debit"),
|
|
16333
|
+
notOneOf(word("checking"), word("limits"))
|
|
16334
|
+
)
|
|
16335
|
+
},
|
|
16336
|
+
{
|
|
16337
|
+
id: "card-loading",
|
|
16338
|
+
category: "payment-fraud",
|
|
16339
|
+
title: "Card and account loading",
|
|
16340
|
+
description: "'Loading' services that push stolen funds onto brand accounts or cards for a cut.",
|
|
16341
|
+
// Source rows: 42
|
|
16342
|
+
query: or(
|
|
16343
|
+
nb(1, "loading"),
|
|
16344
|
+
nb(1, "load"),
|
|
16345
|
+
bn(1, "loads"),
|
|
16346
|
+
bn(1, "loading"),
|
|
16347
|
+
bn(3, "drop"),
|
|
16348
|
+
bn(2, "cash"),
|
|
16349
|
+
and(
|
|
16350
|
+
phrase(BRAND),
|
|
16351
|
+
or(
|
|
16352
|
+
phrase(lit("loading method")),
|
|
16353
|
+
phrase(lit("loading guide")),
|
|
16354
|
+
phrase(lit("loading tut")),
|
|
16355
|
+
phrase(lit("loading tutorial"))
|
|
16356
|
+
)
|
|
16357
|
+
)
|
|
16358
|
+
)
|
|
16359
|
+
},
|
|
16360
|
+
{
|
|
16361
|
+
id: "cross-platform-cashout",
|
|
16362
|
+
category: "payment-fraud",
|
|
16363
|
+
title: "Cross-platform cash-out",
|
|
16364
|
+
description: "Moving funds from the brand into other consumer payment apps to break the trail.",
|
|
16365
|
+
// Source rows: 56
|
|
16366
|
+
query: and(
|
|
16367
|
+
phrase(BRAND),
|
|
16368
|
+
or(
|
|
16369
|
+
phrase(lit("cash app")),
|
|
16370
|
+
word("venmo"),
|
|
16371
|
+
phrase(lit("transfer to paypal")),
|
|
16372
|
+
phrase(lit("visa money transfer"))
|
|
16373
|
+
)
|
|
16374
|
+
)
|
|
16375
|
+
},
|
|
16376
|
+
{
|
|
16377
|
+
id: "crypto-offramp",
|
|
16378
|
+
category: "payment-fraud",
|
|
16379
|
+
title: "Crypto off-ramp",
|
|
16380
|
+
description: "Converting funds held at the brand into cryptocurrency through exchanges and P2P markets.",
|
|
16381
|
+
// Source rows: 63
|
|
16382
|
+
query: and(
|
|
16383
|
+
phrase(BRAND),
|
|
16384
|
+
or(
|
|
16385
|
+
word("crypto"),
|
|
16386
|
+
word("moonpay"),
|
|
16387
|
+
word("switchere"),
|
|
16388
|
+
word("kraken"),
|
|
16389
|
+
word("paxful"),
|
|
16390
|
+
word("noones"),
|
|
16391
|
+
word("coinomi"),
|
|
16392
|
+
word("coinzoom"),
|
|
16393
|
+
word("bitcoin"),
|
|
16394
|
+
word("btc")
|
|
16395
|
+
)
|
|
16396
|
+
)
|
|
16397
|
+
},
|
|
16398
|
+
{
|
|
16399
|
+
id: "mobile-check-deposit",
|
|
16400
|
+
category: "deposit-fraud",
|
|
16401
|
+
title: "Mobile check deposit fraud",
|
|
16402
|
+
description: "Check fraud against mobile deposit, traded under slang including 'glass', 'MCD', 'slips' and 'persy'.",
|
|
16403
|
+
// Source rows: 2, 13, 35, 46
|
|
16404
|
+
industries: [
|
|
16405
|
+
Industry.BANKING,
|
|
16406
|
+
Industry.FINANCIAL_SERVICES,
|
|
16407
|
+
Industry.FINTECH,
|
|
16408
|
+
Industry.PAYMENTS
|
|
16409
|
+
],
|
|
16410
|
+
query: or(
|
|
16411
|
+
bn(5, "checks"),
|
|
16412
|
+
bn(5, "check"),
|
|
16413
|
+
bn(5, "mobile deposit"),
|
|
16414
|
+
nb(5, "mobile deposit"),
|
|
16415
|
+
bn(5, "slip"),
|
|
16416
|
+
bn(5, "slips"),
|
|
16417
|
+
bn(5, "glass"),
|
|
16418
|
+
bn(5, "md"),
|
|
16419
|
+
bn(5, "mcd"),
|
|
16420
|
+
bn(5, "treasury"),
|
|
16421
|
+
nb(5, "treasury"),
|
|
16422
|
+
bn(5, "persy"),
|
|
16423
|
+
bn(5, "deposit limit"),
|
|
16424
|
+
and(phrase(BRAND), or(prefix("stimm"), word("mcd"), phrase(lit("pop on"))))
|
|
16425
|
+
)
|
|
16426
|
+
},
|
|
16427
|
+
{
|
|
16428
|
+
id: "atm-abuse",
|
|
16429
|
+
category: "deposit-fraud",
|
|
16430
|
+
title: "ATM abuse and 'box work'",
|
|
16431
|
+
description: "ATM deposit and withdrawal manipulation, including dispute-driven 'box work' against cash machines.",
|
|
16432
|
+
// Source rows: 9, 47, 57, 70
|
|
16433
|
+
industries: [
|
|
16434
|
+
Industry.BANKING,
|
|
16435
|
+
Industry.FINANCIAL_SERVICES,
|
|
16436
|
+
Industry.FINTECH,
|
|
16437
|
+
Industry.PAYMENTS
|
|
16438
|
+
],
|
|
16439
|
+
query: or(
|
|
16440
|
+
bn(2, "atm"),
|
|
16441
|
+
bn(2, "withdrawal"),
|
|
16442
|
+
and(phrase(BRAND), phrase(lit("box work"))),
|
|
16443
|
+
and(
|
|
16444
|
+
phrase(BRAND),
|
|
16445
|
+
or(
|
|
16446
|
+
phrase(lit("atm deposit")),
|
|
16447
|
+
phrase(lit("atm withdrawal")),
|
|
16448
|
+
phrase(lit("atm withdraw")),
|
|
16449
|
+
phrase(lit("atm limit")),
|
|
16450
|
+
phrase(lit("atm card")),
|
|
16451
|
+
phrase(lit("cash withdrawal fee"))
|
|
16452
|
+
)
|
|
16453
|
+
)
|
|
16454
|
+
)
|
|
16455
|
+
},
|
|
16456
|
+
{
|
|
16457
|
+
id: "retail-cashout-network",
|
|
16458
|
+
category: "deposit-fraud",
|
|
16459
|
+
title: "Retail cash-out network",
|
|
16460
|
+
description: "Cash-out through retail and ATM partner networks, where funds are pulled at a storefront rather than a branch.",
|
|
16461
|
+
// Source rows: 30
|
|
16462
|
+
industries: [
|
|
16463
|
+
Industry.BANKING,
|
|
16464
|
+
Industry.FINANCIAL_SERVICES,
|
|
16465
|
+
Industry.FINTECH,
|
|
16466
|
+
Industry.PAYMENTS
|
|
16467
|
+
],
|
|
16468
|
+
query: or(
|
|
16469
|
+
bn(5, "allpoint"),
|
|
16470
|
+
bn(5, "walgreens"),
|
|
16471
|
+
bn(5, "cvs"),
|
|
16472
|
+
bn(5, "7-eleven"),
|
|
16473
|
+
bn(5, "7eleven"),
|
|
16474
|
+
bn(5, "711"),
|
|
16475
|
+
bn(5, "circle k"),
|
|
16476
|
+
bn(5, "target"),
|
|
16477
|
+
bn(5, "visa plus alliance"),
|
|
16478
|
+
bn(3, "moneypass"),
|
|
16479
|
+
bn(3, "vanilladirect"),
|
|
16480
|
+
bn(3, "vanilla"),
|
|
16481
|
+
bn(3, "dollar general"),
|
|
16482
|
+
bn(3, "dollar tree"),
|
|
16483
|
+
bn(3, "safeway"),
|
|
16484
|
+
bn(3, "walmart"),
|
|
16485
|
+
bn(3, "speedway")
|
|
16486
|
+
)
|
|
16487
|
+
},
|
|
16488
|
+
{
|
|
16489
|
+
id: "otp-bots",
|
|
16490
|
+
category: "account-takeover",
|
|
16491
|
+
title: "OTP bots and 2FA bypass",
|
|
16492
|
+
description: "Automated one-time-passcode interception services targeting the brand's login and step-up flows.",
|
|
16493
|
+
// Source rows: 34
|
|
16494
|
+
query: or(
|
|
16495
|
+
bn(2, "otp"),
|
|
16496
|
+
nb(1, "otp"),
|
|
16497
|
+
phrase(BRAND, lit("otp bot")),
|
|
16498
|
+
bn(2, "2fa"),
|
|
16499
|
+
bn(2, "code"),
|
|
16500
|
+
bn(2, "bypass"),
|
|
16501
|
+
bn(2, "bot"),
|
|
16502
|
+
bn(2, "bots")
|
|
16503
|
+
)
|
|
16504
|
+
},
|
|
16505
|
+
{
|
|
16506
|
+
id: "remote-access-tooling",
|
|
16507
|
+
category: "account-takeover",
|
|
16508
|
+
title: "Remote-access tooling",
|
|
16509
|
+
description: "Legitimate remote-management tools named alongside the brand, the standard toolkit for support-impersonation account takeover.",
|
|
16510
|
+
// Source rows: 29, 64. Truncated by the export; recoverable portion only.
|
|
16511
|
+
query: and(
|
|
16512
|
+
phrase(BRAND),
|
|
16513
|
+
or(
|
|
16514
|
+
word("action1"),
|
|
16515
|
+
phrase(lit("ammy admin")),
|
|
16516
|
+
word("ammyadmin"),
|
|
16517
|
+
word("anydesk"),
|
|
16518
|
+
phrase(lit("any desk")),
|
|
16519
|
+
word("atera"),
|
|
16520
|
+
word("beanywhere"),
|
|
16521
|
+
phrase(lit("chrome remote desktop")),
|
|
16522
|
+
word("connectwise"),
|
|
16523
|
+
word("screenconnect"),
|
|
16524
|
+
word("dameware"),
|
|
16525
|
+
word("domotz"),
|
|
16526
|
+
word("dwservice"),
|
|
16527
|
+
word("fleetdeck"),
|
|
16528
|
+
word("intelliadmin"),
|
|
16529
|
+
phrase(lit("itarian endpoint manager")),
|
|
16530
|
+
phrase(lit("level.io")),
|
|
16531
|
+
word("meshcentral"),
|
|
16532
|
+
word("mremoteng"),
|
|
16533
|
+
phrase(lit("n-able")),
|
|
16534
|
+
word("ngrok"),
|
|
16535
|
+
phrase(lit("pdq deploy")),
|
|
16536
|
+
word("pulseway"),
|
|
16537
|
+
word("realvnc"),
|
|
16538
|
+
phrase(lit("remote utilities")),
|
|
16539
|
+
word("rport")
|
|
16540
|
+
)
|
|
16541
|
+
)
|
|
16542
|
+
},
|
|
16543
|
+
{
|
|
16544
|
+
id: "antidetect-kyc-evasion",
|
|
16545
|
+
category: "account-takeover",
|
|
16546
|
+
title: "Anti-detect and KYC evasion tooling",
|
|
16547
|
+
description: "Fingerprint spoofing, residential proxies and emulators used to defeat the brand's device and identity checks.",
|
|
16548
|
+
// Source row: 40. The original filtered to Telegram OR Dread; DarkOwl's
|
|
16549
|
+
// `source` takes one value, so precision comes from the tooling terms.
|
|
16550
|
+
query: and(
|
|
16551
|
+
phrase(BRAND),
|
|
16552
|
+
or(
|
|
16553
|
+
word("tlo"),
|
|
16554
|
+
word("scamalytics"),
|
|
16555
|
+
word("burner"),
|
|
16556
|
+
prefix("prox"),
|
|
16557
|
+
word("vpn"),
|
|
16558
|
+
word("vps"),
|
|
16559
|
+
word("antidetect"),
|
|
16560
|
+
phrase(lit("anti-detect")),
|
|
16561
|
+
prefix("emulat")
|
|
16562
|
+
)
|
|
16563
|
+
)
|
|
16564
|
+
},
|
|
16565
|
+
{
|
|
16566
|
+
id: "brand-domains-sso",
|
|
16567
|
+
category: "account-takeover",
|
|
16568
|
+
title: "Brand domains and SSO endpoints",
|
|
16569
|
+
description: "The brand's own domains and identity-provider endpoints appearing in credential and access chatter.",
|
|
16570
|
+
// Source row: 31, as proximity not literal hostnames — the index tokenizes
|
|
16571
|
+
// `chime.okta.com`, so a glued literal would never match. Row 23's
|
|
16572
|
+
// "[brand] pass*"~1 is omitted: no wildcards inside a phrase.
|
|
16573
|
+
query: and(
|
|
16574
|
+
or(bn(2, "okta"), bn(2, "login"), bn(2, "portal"), bn(1, "bank")),
|
|
16575
|
+
notOneOf(word("zendesk"))
|
|
16576
|
+
)
|
|
16577
|
+
},
|
|
16578
|
+
{
|
|
16579
|
+
id: "account-opening-abuse",
|
|
16580
|
+
category: "onboarding-abuse",
|
|
16581
|
+
title: "Account opening and self-registration",
|
|
16582
|
+
description: "Bulk or fraudulent account creation against the brand, including 'self-reg' and 'drop' accounts opened on stolen identities.",
|
|
16583
|
+
// Source rows: 5, 17, 54
|
|
16584
|
+
query: or(
|
|
16585
|
+
bn(5, "enroll"),
|
|
16586
|
+
nb(5, "enroll"),
|
|
16587
|
+
bn(5, "open"),
|
|
16588
|
+
nb(5, "open"),
|
|
16589
|
+
bn(5, "drop"),
|
|
16590
|
+
nb(5, "drop"),
|
|
16591
|
+
nb(5, "make"),
|
|
16592
|
+
nb(5, "create"),
|
|
16593
|
+
nb(5, "fresh"),
|
|
16594
|
+
nb(5, "register"),
|
|
16595
|
+
bn(5, "self-reg"),
|
|
16596
|
+
bn(5, "selfreg"),
|
|
16597
|
+
bn(5, "self-registered"),
|
|
16598
|
+
bn(5, "self register"),
|
|
16599
|
+
bn(1, "fullz")
|
|
16600
|
+
)
|
|
16601
|
+
},
|
|
16602
|
+
{
|
|
16603
|
+
id: "identity-documents",
|
|
16604
|
+
category: "onboarding-abuse",
|
|
16605
|
+
title: "Identity documents and fullz",
|
|
16606
|
+
description: "Trade in identity packages and lookup services used to pass onboarding checks. Anchored to the brand at the root, since the source query was brand-independent.",
|
|
16607
|
+
// Source row: 15. Lexicon-only, so the renderer AND-s the anchor on.
|
|
16608
|
+
query: or(
|
|
16609
|
+
word("fullz"),
|
|
16610
|
+
phrase(lit("get pros")),
|
|
16611
|
+
phrase(lit("driver's license")),
|
|
16612
|
+
phrase(lit("tlo bot")),
|
|
16613
|
+
phrase(lit("tlo plug")),
|
|
16614
|
+
phrase(lit("need dl")),
|
|
16615
|
+
phrase(lit("get id"))
|
|
16616
|
+
)
|
|
16617
|
+
},
|
|
16618
|
+
{
|
|
16619
|
+
id: "referral-bonus-abuse",
|
|
16620
|
+
category: "onboarding-abuse",
|
|
16621
|
+
title: "Referral and bonus abuse",
|
|
16622
|
+
description: "Methods for farming the brand's referral bonuses and promotional offers, often paired with fake direct deposits.",
|
|
16623
|
+
// Source rows: 48
|
|
16624
|
+
query: and(
|
|
16625
|
+
or(bn(3, "referral"), bn(3, "bonus"), bn(3, "promotion"), bn(3, "offer")),
|
|
16626
|
+
or(
|
|
16627
|
+
word("bypass"),
|
|
16628
|
+
word("dd"),
|
|
16629
|
+
phrase(lit("direct deposit")),
|
|
16630
|
+
phrase(lit("work around")),
|
|
16631
|
+
word("trick"),
|
|
16632
|
+
word("method"),
|
|
16633
|
+
word("glitch"),
|
|
16634
|
+
word("tutorial"),
|
|
16635
|
+
word("tut"),
|
|
16636
|
+
word("wave"),
|
|
16637
|
+
word("sauce")
|
|
16638
|
+
)
|
|
16639
|
+
)
|
|
16640
|
+
},
|
|
16641
|
+
{
|
|
16642
|
+
id: "insider-recruitment",
|
|
16643
|
+
category: "insider-threat",
|
|
16644
|
+
title: "Insider recruitment",
|
|
16645
|
+
description: "Actors seeking or advertising an employee on the inside ('inny'), the highest-severity signal in this catalog.",
|
|
16646
|
+
// Source rows: 7, 38
|
|
16647
|
+
query: and(
|
|
16648
|
+
or(
|
|
16649
|
+
bn(4, "inny"),
|
|
16650
|
+
bn(4, "insider"),
|
|
16651
|
+
and(
|
|
16652
|
+
phrase(BRAND),
|
|
16653
|
+
or(
|
|
16654
|
+
word("insider"),
|
|
16655
|
+
word("inny"),
|
|
16656
|
+
phrase(lit("in office")),
|
|
16657
|
+
word("employee"),
|
|
16658
|
+
phrase(lit("i work at")),
|
|
16659
|
+
phrase(lit("i am an employee")),
|
|
16660
|
+
phrase(lit("i can get access")),
|
|
16661
|
+
phrase(lit("i have access to")),
|
|
16662
|
+
phrase(lit("employed at")),
|
|
16663
|
+
word("occupation")
|
|
16664
|
+
)
|
|
16665
|
+
)
|
|
16666
|
+
),
|
|
16667
|
+
notOneOf(phrase(lit("welcome to insider chat")))
|
|
16668
|
+
)
|
|
16669
|
+
},
|
|
16670
|
+
{
|
|
16671
|
+
id: "mule-crew-recruitment",
|
|
16672
|
+
category: "insider-threat",
|
|
16673
|
+
title: "Mule and cash-out crew recruitment",
|
|
16674
|
+
description: "Recruitment of account holders to receive and forward funds, priced as a revenue split ('50/50', '60/40').",
|
|
16675
|
+
// Source rows: 39
|
|
16676
|
+
query: or(
|
|
16677
|
+
bn(5, "cl"),
|
|
16678
|
+
bn(5, "mule"),
|
|
16679
|
+
bn(5, "tap in"),
|
|
16680
|
+
bn(5, "50/50"),
|
|
16681
|
+
bn(5, "60/40"),
|
|
16682
|
+
bn(5, "striker")
|
|
16683
|
+
)
|
|
16684
|
+
},
|
|
16685
|
+
{
|
|
16686
|
+
id: "methods-and-tutorials",
|
|
16687
|
+
category: "tradecraft",
|
|
16688
|
+
title: "Methods, 'sauce' and tutorials",
|
|
16689
|
+
description: "Fraud methods being taught or sold against the brand, under the usual slang: sauce, glitch, tut, wave, motion, tap in.",
|
|
16690
|
+
// Source rows: 4, 21, 59
|
|
16691
|
+
query: or(
|
|
16692
|
+
bn(3, "sauce"),
|
|
16693
|
+
bn(3, "method"),
|
|
16694
|
+
bn(3, "guide"),
|
|
16695
|
+
bn(3, "tut"),
|
|
16696
|
+
bn(3, "tutorial"),
|
|
16697
|
+
bn(4, "hack"),
|
|
16698
|
+
bn(4, "glitch"),
|
|
16699
|
+
bn(4, "wave"),
|
|
16700
|
+
bn(4, "motion"),
|
|
16701
|
+
bn(4, "walkthrough"),
|
|
16702
|
+
bn(4, "walk through"),
|
|
16703
|
+
bn(2, "tap in"),
|
|
16704
|
+
bn(2, "tapin"),
|
|
16705
|
+
nb(2, "tapn")
|
|
16706
|
+
)
|
|
16707
|
+
},
|
|
16708
|
+
{
|
|
16709
|
+
id: "hack-leak-chatter",
|
|
16710
|
+
category: "tradecraft",
|
|
16711
|
+
title: "Hack and leak chatter",
|
|
16712
|
+
description: "Claims of having hacked, breached or leaked the brand, whether credible or not.",
|
|
16713
|
+
// Source rows: 28
|
|
16714
|
+
query: or(
|
|
16715
|
+
bn(4, "hack"),
|
|
16716
|
+
bn(4, "glitch"),
|
|
16717
|
+
nb(4, "hacking"),
|
|
16718
|
+
bn(4, "leak"),
|
|
16719
|
+
bn(4, "leaked")
|
|
16720
|
+
)
|
|
16721
|
+
},
|
|
16722
|
+
{
|
|
16723
|
+
id: "support-impersonation",
|
|
16724
|
+
category: "brand-abuse",
|
|
16725
|
+
title: "Support impersonation",
|
|
16726
|
+
description: "Actors impersonating the brand's support or service staff to social-engineer customers.",
|
|
16727
|
+
// Source rows: 36
|
|
16728
|
+
query: or(
|
|
16729
|
+
bn(1, "agent"),
|
|
16730
|
+
bn(1, "support"),
|
|
16731
|
+
bn(1, "service"),
|
|
16732
|
+
bn(1, "customer"),
|
|
16733
|
+
nb(1, "impersonate"),
|
|
16734
|
+
bn(1, "impersonation"),
|
|
16735
|
+
bn(3, "scam"),
|
|
16736
|
+
nb(1, "scam")
|
|
16737
|
+
)
|
|
16738
|
+
},
|
|
16739
|
+
{
|
|
16740
|
+
id: "social-impersonation",
|
|
16741
|
+
category: "brand-abuse",
|
|
16742
|
+
title: "Social account impersonation",
|
|
16743
|
+
description: "The brand discussed alongside social platforms, where fake support and giveaway accounts are staged.",
|
|
16744
|
+
// Source rows: 25
|
|
16745
|
+
query: or(
|
|
16746
|
+
bn(5, "instagram"),
|
|
16747
|
+
bn(5, "insta"),
|
|
16748
|
+
bn(5, "facebook"),
|
|
16749
|
+
bn(5, "twitter"),
|
|
16750
|
+
bn(5, "tiktok")
|
|
16751
|
+
)
|
|
16752
|
+
},
|
|
16753
|
+
{
|
|
16754
|
+
id: "vendor-supply-chain",
|
|
16755
|
+
category: "data-exposure",
|
|
16756
|
+
title: "Vendor and BPO supply chain",
|
|
16757
|
+
description: "Outsourced support and processing vendors named alongside the brand, where a third-party breach exposes brand customer data.",
|
|
16758
|
+
// Source row: 60, truncated by the export. Generic BPO/CX providers; a
|
|
16759
|
+
// per-org vendor list would be materially better.
|
|
16760
|
+
query: and(
|
|
16761
|
+
phrase(BRAND),
|
|
16762
|
+
or(
|
|
16763
|
+
word("zendesk"),
|
|
16764
|
+
word("teleperformance"),
|
|
16765
|
+
word("concentrix"),
|
|
16766
|
+
word("taskus"),
|
|
16767
|
+
word("genpact"),
|
|
16768
|
+
word("ubiquity"),
|
|
16769
|
+
word("hioperator"),
|
|
16770
|
+
word("galileo"),
|
|
16771
|
+
word("fiserv"),
|
|
16772
|
+
phrase(lit("etech global"))
|
|
16773
|
+
)
|
|
16774
|
+
)
|
|
16775
|
+
}
|
|
16776
|
+
];
|
|
16777
|
+
new Map(
|
|
16778
|
+
SCAN_TEMPLATES.map((template) => [template.id, template])
|
|
16779
|
+
);
|
|
16780
|
+
|
|
16119
16781
|
// src/client.ts
|
|
16120
16782
|
function trimTrailingSlashes(url) {
|
|
16121
16783
|
return url.replace(/\/+$/, "");
|