@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.js
CHANGED
|
@@ -1313,17 +1313,17 @@ var PolyDateFormatter = class {
|
|
|
1313
1313
|
constructor(dt, intl, opts) {
|
|
1314
1314
|
this.opts = opts;
|
|
1315
1315
|
this.originalZone = void 0;
|
|
1316
|
-
let
|
|
1316
|
+
let z56 = void 0;
|
|
1317
1317
|
if (this.opts.timeZone) {
|
|
1318
1318
|
this.dt = dt;
|
|
1319
1319
|
} else if (dt.zone.type === "fixed") {
|
|
1320
1320
|
const gmtOffset = -1 * (dt.offset / 60);
|
|
1321
1321
|
const offsetZ = gmtOffset >= 0 ? `Etc/GMT+${gmtOffset}` : `Etc/GMT${gmtOffset}`;
|
|
1322
1322
|
if (dt.offset !== 0 && IANAZone.create(offsetZ).valid) {
|
|
1323
|
-
|
|
1323
|
+
z56 = offsetZ;
|
|
1324
1324
|
this.dt = dt;
|
|
1325
1325
|
} else {
|
|
1326
|
-
|
|
1326
|
+
z56 = "UTC";
|
|
1327
1327
|
this.dt = dt.offset === 0 ? dt : dt.setZone("UTC").plus({ minutes: dt.offset });
|
|
1328
1328
|
this.originalZone = dt.zone;
|
|
1329
1329
|
}
|
|
@@ -1331,14 +1331,14 @@ var PolyDateFormatter = class {
|
|
|
1331
1331
|
this.dt = dt;
|
|
1332
1332
|
} else if (dt.zone.type === "iana") {
|
|
1333
1333
|
this.dt = dt;
|
|
1334
|
-
|
|
1334
|
+
z56 = dt.zone.name;
|
|
1335
1335
|
} else {
|
|
1336
|
-
|
|
1336
|
+
z56 = "UTC";
|
|
1337
1337
|
this.dt = dt.setZone("UTC").plus({ minutes: dt.offset });
|
|
1338
1338
|
this.originalZone = dt.zone;
|
|
1339
1339
|
}
|
|
1340
1340
|
const intlOpts = __spreadValues({}, this.opts);
|
|
1341
|
-
intlOpts.timeZone = intlOpts.timeZone ||
|
|
1341
|
+
intlOpts.timeZone = intlOpts.timeZone || z56;
|
|
1342
1342
|
this.dtf = getCachedDTF(intl, intlOpts);
|
|
1343
1343
|
}
|
|
1344
1344
|
format() {
|
|
@@ -11488,6 +11488,50 @@ zod.z.object({
|
|
|
11488
11488
|
endDate: zod.z.date()
|
|
11489
11489
|
})
|
|
11490
11490
|
});
|
|
11491
|
+
var DATE_ONLY_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
|
|
11492
|
+
var utcDateSchema = (endOfDay) => zod.z.preprocess((value) => {
|
|
11493
|
+
if (typeof value !== "string") {
|
|
11494
|
+
return value;
|
|
11495
|
+
}
|
|
11496
|
+
const parsed = DateTime.fromISO(value, { zone: "utc" });
|
|
11497
|
+
if (!parsed.isValid) {
|
|
11498
|
+
return new Date(Number.NaN);
|
|
11499
|
+
}
|
|
11500
|
+
return endOfDay && DATE_ONLY_PATTERN.test(value) ? parsed.endOf("day").toJSDate() : parsed.toJSDate();
|
|
11501
|
+
}, zod.z.coerce.date());
|
|
11502
|
+
var funnelCountsSchema = zod.z.object({
|
|
11503
|
+
blocked: zod.z.number().int().nonnegative().describe(
|
|
11504
|
+
"Distinct assets whose earliest report for this org falls in the range and whose current status or pending status is BLOCKED"
|
|
11505
|
+
)
|
|
11506
|
+
});
|
|
11507
|
+
zod.z.object({
|
|
11508
|
+
slug: zod.z.string().min(1).describe("Organization slug"),
|
|
11509
|
+
startDate: utcDateSchema(false).describe(
|
|
11510
|
+
"Only include assets whose earliest report was created on or after this date. A date-only value (YYYY-MM-DD) starts at midnight UTC"
|
|
11511
|
+
),
|
|
11512
|
+
endDate: utcDateSchema(true).describe(
|
|
11513
|
+
"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"
|
|
11514
|
+
),
|
|
11515
|
+
brandIds: zod.z.array(zod.z.number().int().positive()).optional().describe("Only include assets belonging to these brands")
|
|
11516
|
+
}).refine((input) => input.startDate.getTime() <= input.endDate.getTime(), {
|
|
11517
|
+
message: "startDate must be on or before endDate",
|
|
11518
|
+
path: ["startDate"]
|
|
11519
|
+
});
|
|
11520
|
+
zod.z.object({
|
|
11521
|
+
range: zod.z.object({
|
|
11522
|
+
startDate: zod.z.date(),
|
|
11523
|
+
endDate: zod.z.date()
|
|
11524
|
+
}),
|
|
11525
|
+
customer: funnelCountsSchema.describe(
|
|
11526
|
+
"Currently blocked assets first reported by the customer (reportedByCustomer, external reporter, or customer-role user)"
|
|
11527
|
+
),
|
|
11528
|
+
chainpatrol: funnelCountsSchema.describe(
|
|
11529
|
+
"Currently blocked assets first reported by ChainPatrol staff or automation. Staff and automation are collapsed together."
|
|
11530
|
+
),
|
|
11531
|
+
totals: funnelCountsSchema.describe(
|
|
11532
|
+
"customer + chainpatrol. This is a first-report blocked cohort and does not equal metrics/found, which counts assets by blockedAt."
|
|
11533
|
+
)
|
|
11534
|
+
});
|
|
11491
11535
|
zod.z.object({
|
|
11492
11536
|
slug: zod.z.string().min(1),
|
|
11493
11537
|
startDate: zod.z.date().optional(),
|
|
@@ -11519,8 +11563,8 @@ zod.z.object({
|
|
|
11519
11563
|
})
|
|
11520
11564
|
)
|
|
11521
11565
|
});
|
|
11522
|
-
var
|
|
11523
|
-
var
|
|
11566
|
+
var DATE_ONLY_PATTERN2 = /^\d{4}-\d{2}-\d{2}$/;
|
|
11567
|
+
var utcDateSchema2 = (endOfDay) => zod.z.preprocess((value) => {
|
|
11524
11568
|
if (typeof value !== "string") {
|
|
11525
11569
|
return value;
|
|
11526
11570
|
}
|
|
@@ -11528,14 +11572,14 @@ var utcDateSchema = (endOfDay) => zod.z.preprocess((value) => {
|
|
|
11528
11572
|
if (!parsed.isValid) {
|
|
11529
11573
|
return new Date(Number.NaN);
|
|
11530
11574
|
}
|
|
11531
|
-
return endOfDay &&
|
|
11575
|
+
return endOfDay && DATE_ONLY_PATTERN2.test(value) ? parsed.endOf("day").toJSDate() : parsed.toJSDate();
|
|
11532
11576
|
}, zod.z.coerce.date());
|
|
11533
11577
|
zod.z.object({
|
|
11534
11578
|
slug: zod.z.string().min(1).describe("Organization slug"),
|
|
11535
|
-
startDate:
|
|
11579
|
+
startDate: utcDateSchema2(false).optional().describe(
|
|
11536
11580
|
"Only include takedowns completed on or after this date. A date-only value (YYYY-MM-DD) starts at midnight UTC"
|
|
11537
11581
|
),
|
|
11538
|
-
endDate:
|
|
11582
|
+
endDate: utcDateSchema2(true).optional().describe(
|
|
11539
11583
|
"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"
|
|
11540
11584
|
),
|
|
11541
11585
|
blockLabel: zod.z.string().optional().describe(
|
|
@@ -11558,6 +11602,55 @@ zod.z.object({
|
|
|
11558
11602
|
"Median time from takedown start to completion, one entry per asset type, ascending by median"
|
|
11559
11603
|
)
|
|
11560
11604
|
});
|
|
11605
|
+
zod.z.object({
|
|
11606
|
+
slug: zod.z.string().min(1).describe("Organization slug"),
|
|
11607
|
+
months: zod.z.number().int().min(2).max(36).default(12).describe("Size of the trailing window in whole months, including the current month"),
|
|
11608
|
+
assetTypes: zod.z.array(zod.z.nativeEnum(AssetType)).max(5).optional().describe(
|
|
11609
|
+
"Break the trend down by these asset types, one series each. Omit for a single series pooled across every asset type"
|
|
11610
|
+
),
|
|
11611
|
+
blockLabel: zod.z.string().optional().describe(
|
|
11612
|
+
'Only include assets blocked with this review label, e.g. "Brand Impersonation", "Employee Impersonation" or "Targeting Org Users"'
|
|
11613
|
+
),
|
|
11614
|
+
brandType: zod.z.nativeEnum(BrandType).optional().describe("Only include assets belonging to brands of this type"),
|
|
11615
|
+
countryCodes: zod.z.array(zod.z.string().length(2)).optional().describe("Only include assets scanned from these ISO 3166-1 alpha-2 countries"),
|
|
11616
|
+
brandIds: zod.z.array(zod.z.number().int().positive()).optional().describe("Only include assets belonging to these brands")
|
|
11617
|
+
});
|
|
11618
|
+
var MetricsTakedownTimeTrendPointSchema = zod.z.object({
|
|
11619
|
+
period: zod.z.string().describe("Month the takedowns completed in, as a yyyy-MM key"),
|
|
11620
|
+
medianTakedownMinutes: zod.z.number().nullable().describe("Null when no takedowns completed in this month"),
|
|
11621
|
+
medianTakedownHours: zod.z.number().nullable(),
|
|
11622
|
+
medianTakedownDays: zod.z.number().nullable(),
|
|
11623
|
+
count: zod.z.number().describe("Number of completed takedowns behind the median")
|
|
11624
|
+
});
|
|
11625
|
+
var MetricsTakedownTimeTrendChangeSchema = zod.z.object({
|
|
11626
|
+
latest: MetricsTakedownTimeTrendPointSchema.nullable().describe(
|
|
11627
|
+
"Most recent month in the window that had completed takedowns"
|
|
11628
|
+
),
|
|
11629
|
+
previous: MetricsTakedownTimeTrendPointSchema.nullable().describe(
|
|
11630
|
+
"Month with completed takedowns immediately before `latest`, skipping empty months"
|
|
11631
|
+
),
|
|
11632
|
+
percentChange: zod.z.number().nullable().describe(
|
|
11633
|
+
"Change in the median from `previous` to `latest`, as a percentage. Negative means takedowns got faster. Null when there is no comparable earlier month"
|
|
11634
|
+
),
|
|
11635
|
+
direction: zod.z.enum(["improved", "worsened", "unchanged"]).nullable().describe("Sign of `percentChange`, read as lower-is-better. Null when it is null")
|
|
11636
|
+
});
|
|
11637
|
+
zod.z.object({
|
|
11638
|
+
months: zod.z.number().describe("Size of the trailing window that was used"),
|
|
11639
|
+
periods: zod.z.array(zod.z.string()).describe("Every yyyy-MM key in the window, oldest first"),
|
|
11640
|
+
series: zod.z.array(
|
|
11641
|
+
zod.z.object({
|
|
11642
|
+
assetType: zod.z.nativeEnum(AssetType).nullable().describe("Null for the series pooled across every asset type"),
|
|
11643
|
+
points: zod.z.array(MetricsTakedownTimeTrendPointSchema).describe(
|
|
11644
|
+
"One point per month in the window, oldest first. Months with no completed takedowns carry a null median"
|
|
11645
|
+
),
|
|
11646
|
+
change: MetricsTakedownTimeTrendChangeSchema.describe(
|
|
11647
|
+
"Month-over-month comparison for this series"
|
|
11648
|
+
)
|
|
11649
|
+
})
|
|
11650
|
+
).describe(
|
|
11651
|
+
"One series per requested asset type, in the order requested, or a single pooled series when no asset types were given"
|
|
11652
|
+
)
|
|
11653
|
+
});
|
|
11561
11654
|
zod.z.object({
|
|
11562
11655
|
slug: zod.z.string().optional().describe(
|
|
11563
11656
|
"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."
|
|
@@ -11944,7 +12037,9 @@ var organizationMetricsIncludeFieldSchema = zod.z.enum([
|
|
|
11944
12037
|
"newThreats",
|
|
11945
12038
|
"threatsWatchlisted",
|
|
11946
12039
|
"takedownsFiled",
|
|
12040
|
+
"takedownsInProgress",
|
|
11947
12041
|
"takedownsCompleted",
|
|
12042
|
+
"takedownsCancelled",
|
|
11948
12043
|
"domainThreats",
|
|
11949
12044
|
"twitterThreats",
|
|
11950
12045
|
"telegramThreats",
|
|
@@ -11986,7 +12081,7 @@ zod.z.object({
|
|
|
11986
12081
|
startDate: zod.z.coerce.date().optional(),
|
|
11987
12082
|
endDate: zod.z.coerce.date().optional(),
|
|
11988
12083
|
include: zod.z.array(organizationMetricsIncludeFieldSchema).optional().describe(
|
|
11989
|
-
"Subset of metrics to compute. When omitted or empty, every metric is computed (legacy behavior). Each value in `include` costs roughly one
|
|
12084
|
+
"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."
|
|
11990
12085
|
)
|
|
11991
12086
|
}).refine(
|
|
11992
12087
|
(value) => {
|
|
@@ -12014,7 +12109,9 @@ var metricsObjectSchema = zod.z.object({
|
|
|
12014
12109
|
newThreats: metricValue,
|
|
12015
12110
|
threatsWatchlisted: metricValue,
|
|
12016
12111
|
takedownsFiled: metricValue,
|
|
12112
|
+
takedownsInProgress: metricValue,
|
|
12017
12113
|
takedownsCompleted: metricValue,
|
|
12114
|
+
takedownsCancelled: metricValue,
|
|
12018
12115
|
domainThreats: metricValue,
|
|
12019
12116
|
twitterThreats: metricValue,
|
|
12020
12117
|
telegramThreats: metricValue,
|
|
@@ -13397,20 +13494,20 @@ var convertA98ToXyz65_default = convertA98ToXyz65;
|
|
|
13397
13494
|
|
|
13398
13495
|
// ../../node_modules/culori/src/a98/convertXyz65ToA98.js
|
|
13399
13496
|
var gamma = (v) => Math.pow(Math.abs(v), 256 / 563) * Math.sign(v);
|
|
13400
|
-
var convertXyz65ToA98 = ({ x, y, z:
|
|
13497
|
+
var convertXyz65ToA98 = ({ x, y, z: z56, alpha }) => {
|
|
13401
13498
|
if (x === void 0) x = 0;
|
|
13402
13499
|
if (y === void 0) y = 0;
|
|
13403
|
-
if (
|
|
13500
|
+
if (z56 === void 0) z56 = 0;
|
|
13404
13501
|
let res = {
|
|
13405
13502
|
mode: "a98",
|
|
13406
13503
|
r: gamma(
|
|
13407
|
-
x * 2.0415879038107465 - y * 0.5650069742788597 - 0.3447313507783297 *
|
|
13504
|
+
x * 2.0415879038107465 - y * 0.5650069742788597 - 0.3447313507783297 * z56
|
|
13408
13505
|
),
|
|
13409
13506
|
g: gamma(
|
|
13410
|
-
x * -0.9692436362808798 + y * 1.8759675015077206 + 0.0415550574071756 *
|
|
13507
|
+
x * -0.9692436362808798 + y * 1.8759675015077206 + 0.0415550574071756 * z56
|
|
13411
13508
|
),
|
|
13412
13509
|
b: gamma(
|
|
13413
|
-
x * 0.0134442806320312 - y * 0.1183623922310184 + 1.0151749943912058 *
|
|
13510
|
+
x * 0.0134442806320312 - y * 0.1183623922310184 + 1.0151749943912058 * z56
|
|
13414
13511
|
)
|
|
13415
13512
|
};
|
|
13416
13513
|
if (alpha !== void 0) {
|
|
@@ -13477,14 +13574,14 @@ var convertLrgbToRgb = ({ r, g, b, alpha }, mode = "rgb") => {
|
|
|
13477
13574
|
var convertLrgbToRgb_default = convertLrgbToRgb;
|
|
13478
13575
|
|
|
13479
13576
|
// ../../node_modules/culori/src/xyz65/convertXyz65ToRgb.js
|
|
13480
|
-
var convertXyz65ToRgb = ({ x, y, z:
|
|
13577
|
+
var convertXyz65ToRgb = ({ x, y, z: z56, alpha }) => {
|
|
13481
13578
|
if (x === void 0) x = 0;
|
|
13482
13579
|
if (y === void 0) y = 0;
|
|
13483
|
-
if (
|
|
13580
|
+
if (z56 === void 0) z56 = 0;
|
|
13484
13581
|
let res = convertLrgbToRgb_default({
|
|
13485
|
-
r: x * 3.2409699419045226 - y * 1.537383177570094 - 0.4986107602930034 *
|
|
13486
|
-
g: x * -0.9692436362808796 + y * 1.8759675015077204 + 0.0415550574071756 *
|
|
13487
|
-
b: x * 0.0556300796969936 - y * 0.2039769588889765 + 1.0569715142428784 *
|
|
13582
|
+
r: x * 3.2409699419045226 - y * 1.537383177570094 - 0.4986107602930034 * z56,
|
|
13583
|
+
g: x * -0.9692436362808796 + y * 1.8759675015077204 + 0.0415550574071756 * z56,
|
|
13584
|
+
b: x * 0.0556300796969936 - y * 0.2039769588889765 + 1.0569715142428784 * z56
|
|
13488
13585
|
});
|
|
13489
13586
|
if (alpha !== void 0) {
|
|
13490
13587
|
res.alpha = alpha;
|
|
@@ -13734,13 +13831,13 @@ var convertLab65ToRgb_default = convertLab65ToRgb;
|
|
|
13734
13831
|
|
|
13735
13832
|
// ../../node_modules/culori/src/lab65/convertXyz65ToLab65.js
|
|
13736
13833
|
var f = (value) => value > e ? Math.cbrt(value) : (k * value + 16) / 116;
|
|
13737
|
-
var convertXyz65ToLab65 = ({ x, y, z:
|
|
13834
|
+
var convertXyz65ToLab65 = ({ x, y, z: z56, alpha }) => {
|
|
13738
13835
|
if (x === void 0) x = 0;
|
|
13739
13836
|
if (y === void 0) y = 0;
|
|
13740
|
-
if (
|
|
13837
|
+
if (z56 === void 0) z56 = 0;
|
|
13741
13838
|
let f0 = f(x / D65.X);
|
|
13742
13839
|
let f1 = f(y / D65.Y);
|
|
13743
|
-
let f22 = f(
|
|
13840
|
+
let f22 = f(z56 / D65.Z);
|
|
13744
13841
|
let res = {
|
|
13745
13842
|
mode: "lab65",
|
|
13746
13843
|
l: 116 * f1 - 16,
|
|
@@ -14397,10 +14494,10 @@ var convertItpToXyz65_default = convertItpToXyz65;
|
|
|
14397
14494
|
|
|
14398
14495
|
// ../../node_modules/culori/src/itp/convertXyz65ToItp.js
|
|
14399
14496
|
var toAbs = (c2 = 0) => Math.max(c2 * YW, 0);
|
|
14400
|
-
var convertXyz65ToItp = ({ x, y, z:
|
|
14497
|
+
var convertXyz65ToItp = ({ x, y, z: z56, alpha }) => {
|
|
14401
14498
|
const absX = toAbs(x);
|
|
14402
14499
|
const absY = toAbs(y);
|
|
14403
|
-
const absZ = toAbs(
|
|
14500
|
+
const absZ = toAbs(z56);
|
|
14404
14501
|
const l2 = transferPqEncode(
|
|
14405
14502
|
0.3592832590121217 * absX + 0.6976051147779502 * absY - 0.0358915932320289 * absZ
|
|
14406
14503
|
);
|
|
@@ -14458,15 +14555,15 @@ var jabPqEncode = (v) => {
|
|
|
14458
14555
|
return Math.pow((C1 + C2 * vn3) / (1 + C3 * vn3), p);
|
|
14459
14556
|
};
|
|
14460
14557
|
var abs = (v = 0) => Math.max(v * 203, 0);
|
|
14461
|
-
var convertXyz65ToJab = ({ x, y, z:
|
|
14558
|
+
var convertXyz65ToJab = ({ x, y, z: z56, alpha }) => {
|
|
14462
14559
|
x = abs(x);
|
|
14463
14560
|
y = abs(y);
|
|
14464
|
-
|
|
14465
|
-
let xp = 1.15 * x - 0.15 *
|
|
14561
|
+
z56 = abs(z56);
|
|
14562
|
+
let xp = 1.15 * x - 0.15 * z56;
|
|
14466
14563
|
let yp = 0.66 * y + 0.34 * x;
|
|
14467
|
-
let l2 = jabPqEncode(0.41478972 * xp + 0.579999 * yp + 0.014648 *
|
|
14468
|
-
let m = jabPqEncode(-0.20151 * xp + 1.120649 * yp + 0.0531008 *
|
|
14469
|
-
let s2 = jabPqEncode(-0.0166008 * xp + 0.2648 * yp + 0.6684799 *
|
|
14564
|
+
let l2 = jabPqEncode(0.41478972 * xp + 0.579999 * yp + 0.014648 * z56);
|
|
14565
|
+
let m = jabPqEncode(-0.20151 * xp + 1.120649 * yp + 0.0531008 * z56);
|
|
14566
|
+
let s2 = jabPqEncode(-0.0166008 * xp + 0.2648 * yp + 0.6684799 * z56);
|
|
14470
14567
|
let i = (l2 + m) / 2;
|
|
14471
14568
|
let res = {
|
|
14472
14569
|
mode: "jab",
|
|
@@ -14652,14 +14749,14 @@ var convertLabToXyz50 = ({ l: l2, a, b, alpha }) => {
|
|
|
14652
14749
|
var convertLabToXyz50_default = convertLabToXyz50;
|
|
14653
14750
|
|
|
14654
14751
|
// ../../node_modules/culori/src/xyz50/convertXyz50ToRgb.js
|
|
14655
|
-
var convertXyz50ToRgb = ({ x, y, z:
|
|
14752
|
+
var convertXyz50ToRgb = ({ x, y, z: z56, alpha }) => {
|
|
14656
14753
|
if (x === void 0) x = 0;
|
|
14657
14754
|
if (y === void 0) y = 0;
|
|
14658
|
-
if (
|
|
14755
|
+
if (z56 === void 0) z56 = 0;
|
|
14659
14756
|
let res = convertLrgbToRgb_default({
|
|
14660
|
-
r: x * 3.1341359569958707 - y * 1.6173863321612538 - 0.4906619460083532 *
|
|
14661
|
-
g: x * -0.978795502912089 + y * 1.916254567259524 + 0.03344273116131949 *
|
|
14662
|
-
b: x * 0.07195537988411677 - y * 0.2289768264158322 + 1.405386058324125 *
|
|
14757
|
+
r: x * 3.1341359569958707 - y * 1.6173863321612538 - 0.4906619460083532 * z56,
|
|
14758
|
+
g: x * -0.978795502912089 + y * 1.916254567259524 + 0.03344273116131949 * z56,
|
|
14759
|
+
b: x * 0.07195537988411677 - y * 0.2289768264158322 + 1.405386058324125 * z56
|
|
14663
14760
|
});
|
|
14664
14761
|
if (alpha !== void 0) {
|
|
14665
14762
|
res.alpha = alpha;
|
|
@@ -14690,13 +14787,13 @@ var convertRgbToXyz50_default = convertRgbToXyz50;
|
|
|
14690
14787
|
|
|
14691
14788
|
// ../../node_modules/culori/src/lab/convertXyz50ToLab.js
|
|
14692
14789
|
var f2 = (value) => value > e3 ? Math.cbrt(value) : (k3 * value + 16) / 116;
|
|
14693
|
-
var convertXyz50ToLab = ({ x, y, z:
|
|
14790
|
+
var convertXyz50ToLab = ({ x, y, z: z56, alpha }) => {
|
|
14694
14791
|
if (x === void 0) x = 0;
|
|
14695
14792
|
if (y === void 0) y = 0;
|
|
14696
|
-
if (
|
|
14793
|
+
if (z56 === void 0) z56 = 0;
|
|
14697
14794
|
let f0 = f2(x / D50.X);
|
|
14698
14795
|
let f1 = f2(y / D50.Y);
|
|
14699
|
-
let f22 = f2(
|
|
14796
|
+
let f22 = f2(z56 / D50.Z);
|
|
14700
14797
|
let res = {
|
|
14701
14798
|
mode: "lab",
|
|
14702
14799
|
l: 116 * f1 - 16,
|
|
@@ -14931,18 +15028,18 @@ var convertLchuvToLuv = ({ l: l2, c: c2, h, alpha }) => {
|
|
|
14931
15028
|
var convertLchuvToLuv_default = convertLchuvToLuv;
|
|
14932
15029
|
|
|
14933
15030
|
// ../../node_modules/culori/src/luv/convertXyz50ToLuv.js
|
|
14934
|
-
var u_fn = (x, y,
|
|
14935
|
-
var v_fn = (x, y,
|
|
15031
|
+
var u_fn = (x, y, z56) => 4 * x / (x + 15 * y + 3 * z56);
|
|
15032
|
+
var v_fn = (x, y, z56) => 9 * y / (x + 15 * y + 3 * z56);
|
|
14936
15033
|
var un = u_fn(D50.X, D50.Y, D50.Z);
|
|
14937
15034
|
var vn = v_fn(D50.X, D50.Y, D50.Z);
|
|
14938
15035
|
var l_fn = (value) => value <= e3 ? k3 * value : 116 * Math.cbrt(value) - 16;
|
|
14939
|
-
var convertXyz50ToLuv = ({ x, y, z:
|
|
15036
|
+
var convertXyz50ToLuv = ({ x, y, z: z56, alpha }) => {
|
|
14940
15037
|
if (x === void 0) x = 0;
|
|
14941
15038
|
if (y === void 0) y = 0;
|
|
14942
|
-
if (
|
|
15039
|
+
if (z56 === void 0) z56 = 0;
|
|
14943
15040
|
let l2 = l_fn(y / D50.Y);
|
|
14944
|
-
let u = u_fn(x, y,
|
|
14945
|
-
let v = v_fn(x, y,
|
|
15041
|
+
let u = u_fn(x, y, z56);
|
|
15042
|
+
let v = v_fn(x, y, z56);
|
|
14946
15043
|
if (!isFinite(u) || !isFinite(v)) {
|
|
14947
15044
|
l2 = u = v = 0;
|
|
14948
15045
|
} else {
|
|
@@ -14963,8 +15060,8 @@ var convertXyz50ToLuv = ({ x, y, z: z54, alpha }) => {
|
|
|
14963
15060
|
var convertXyz50ToLuv_default = convertXyz50ToLuv;
|
|
14964
15061
|
|
|
14965
15062
|
// ../../node_modules/culori/src/luv/convertLuvToXyz50.js
|
|
14966
|
-
var u_fn2 = (x, y,
|
|
14967
|
-
var v_fn2 = (x, y,
|
|
15063
|
+
var u_fn2 = (x, y, z56) => 4 * x / (x + 15 * y + 3 * z56);
|
|
15064
|
+
var v_fn2 = (x, y, z56) => 9 * y / (x + 15 * y + 3 * z56);
|
|
14968
15065
|
var un2 = u_fn2(D50.X, D50.Y, D50.Z);
|
|
14969
15066
|
var vn2 = v_fn2(D50.X, D50.Y, D50.Z);
|
|
14970
15067
|
var convertLuvToXyz50 = ({ l: l2, u, v, alpha }) => {
|
|
@@ -14978,8 +15075,8 @@ var convertLuvToXyz50 = ({ l: l2, u, v, alpha }) => {
|
|
|
14978
15075
|
let vp = v / (13 * l2) + vn2;
|
|
14979
15076
|
let y = D50.Y * (l2 <= 8 ? l2 / k3 : Math.pow((l2 + 16) / 116, 3));
|
|
14980
15077
|
let x = y * (9 * up) / (4 * vp);
|
|
14981
|
-
let
|
|
14982
|
-
let res = { mode: "xyz50", x, y, z:
|
|
15078
|
+
let z56 = y * (12 - 3 * up - 20 * vp) / (4 * vp);
|
|
15079
|
+
let res = { mode: "xyz50", x, y, z: z56 };
|
|
14983
15080
|
if (alpha !== void 0) {
|
|
14984
15081
|
res.alpha = alpha;
|
|
14985
15082
|
}
|
|
@@ -15596,15 +15693,15 @@ var convertP3ToXyz65 = (rgb2) => {
|
|
|
15596
15693
|
var convertP3ToXyz65_default = convertP3ToXyz65;
|
|
15597
15694
|
|
|
15598
15695
|
// ../../node_modules/culori/src/p3/convertXyz65ToP3.js
|
|
15599
|
-
var convertXyz65ToP3 = ({ x, y, z:
|
|
15696
|
+
var convertXyz65ToP3 = ({ x, y, z: z56, alpha }) => {
|
|
15600
15697
|
if (x === void 0) x = 0;
|
|
15601
15698
|
if (y === void 0) y = 0;
|
|
15602
|
-
if (
|
|
15699
|
+
if (z56 === void 0) z56 = 0;
|
|
15603
15700
|
let res = convertLrgbToRgb_default(
|
|
15604
15701
|
{
|
|
15605
|
-
r: x * 2.4934969119414263 - y * 0.9313836179191242 - 0.402710784450717 *
|
|
15606
|
-
g: x * -0.8294889695615749 + y * 1.7626640603183465 + 0.0236246858419436 *
|
|
15607
|
-
b: x * 0.0358458302437845 - y * 0.0761723892680418 + 0.9568845240076871 *
|
|
15702
|
+
r: x * 2.4934969119414263 - y * 0.9313836179191242 - 0.402710784450717 * z56,
|
|
15703
|
+
g: x * -0.8294889695615749 + y * 1.7626640603183465 + 0.0236246858419436 * z56,
|
|
15704
|
+
b: x * 0.0358458302437845 - y * 0.0761723892680418 + 0.9568845240076871 * z56
|
|
15608
15705
|
},
|
|
15609
15706
|
"p3"
|
|
15610
15707
|
);
|
|
@@ -15639,19 +15736,19 @@ var gamma2 = (v) => {
|
|
|
15639
15736
|
}
|
|
15640
15737
|
return 16 * v;
|
|
15641
15738
|
};
|
|
15642
|
-
var convertXyz50ToProphoto = ({ x, y, z:
|
|
15739
|
+
var convertXyz50ToProphoto = ({ x, y, z: z56, alpha }) => {
|
|
15643
15740
|
if (x === void 0) x = 0;
|
|
15644
15741
|
if (y === void 0) y = 0;
|
|
15645
|
-
if (
|
|
15742
|
+
if (z56 === void 0) z56 = 0;
|
|
15646
15743
|
let res = {
|
|
15647
15744
|
mode: "prophoto",
|
|
15648
15745
|
r: gamma2(
|
|
15649
|
-
x * 1.3457868816471585 - y * 0.2555720873797946 - 0.0511018649755453 *
|
|
15746
|
+
x * 1.3457868816471585 - y * 0.2555720873797946 - 0.0511018649755453 * z56
|
|
15650
15747
|
),
|
|
15651
15748
|
g: gamma2(
|
|
15652
|
-
x * -0.5446307051249019 + y * 1.5082477428451466 + 0.0205274474364214 *
|
|
15749
|
+
x * -0.5446307051249019 + y * 1.5082477428451466 + 0.0205274474364214 * z56
|
|
15653
15750
|
),
|
|
15654
|
-
b: gamma2(x * 0 + y * 0 + 1.2119675456389452 *
|
|
15751
|
+
b: gamma2(x * 0 + y * 0 + 1.2119675456389452 * z56)
|
|
15655
15752
|
};
|
|
15656
15753
|
if (alpha !== void 0) {
|
|
15657
15754
|
res.alpha = alpha;
|
|
@@ -15711,20 +15808,20 @@ var gamma3 = (v) => {
|
|
|
15711
15808
|
}
|
|
15712
15809
|
return 4.5 * v;
|
|
15713
15810
|
};
|
|
15714
|
-
var convertXyz65ToRec2020 = ({ x, y, z:
|
|
15811
|
+
var convertXyz65ToRec2020 = ({ x, y, z: z56, alpha }) => {
|
|
15715
15812
|
if (x === void 0) x = 0;
|
|
15716
15813
|
if (y === void 0) y = 0;
|
|
15717
|
-
if (
|
|
15814
|
+
if (z56 === void 0) z56 = 0;
|
|
15718
15815
|
let res = {
|
|
15719
15816
|
mode: "rec2020",
|
|
15720
15817
|
r: gamma3(
|
|
15721
|
-
x * 1.7166511879712683 - y * 0.3556707837763925 - 0.2533662813736599 *
|
|
15818
|
+
x * 1.7166511879712683 - y * 0.3556707837763925 - 0.2533662813736599 * z56
|
|
15722
15819
|
),
|
|
15723
15820
|
g: gamma3(
|
|
15724
|
-
x * -0.6666843518324893 + y * 1.6164812366349395 + 0.0157685458139111 *
|
|
15821
|
+
x * -0.6666843518324893 + y * 1.6164812366349395 + 0.0157685458139111 * z56
|
|
15725
15822
|
),
|
|
15726
15823
|
b: gamma3(
|
|
15727
|
-
x * 0.0176398574453108 - y * 0.0427706132578085 + 0.9421031212354739 *
|
|
15824
|
+
x * 0.0176398574453108 - y * 0.0427706132578085 + 0.9421031212354739 * z56
|
|
15728
15825
|
)
|
|
15729
15826
|
};
|
|
15730
15827
|
if (alpha !== void 0) {
|
|
@@ -15877,15 +15974,15 @@ var definition_default26 = definition26;
|
|
|
15877
15974
|
|
|
15878
15975
|
// ../../node_modules/culori/src/xyz65/convertXyz65ToXyz50.js
|
|
15879
15976
|
var convertXyz65ToXyz50 = (xyz652) => {
|
|
15880
|
-
let { x, y, z:
|
|
15977
|
+
let { x, y, z: z56, alpha } = xyz652;
|
|
15881
15978
|
if (x === void 0) x = 0;
|
|
15882
15979
|
if (y === void 0) y = 0;
|
|
15883
|
-
if (
|
|
15980
|
+
if (z56 === void 0) z56 = 0;
|
|
15884
15981
|
let res = {
|
|
15885
15982
|
mode: "xyz50",
|
|
15886
|
-
x: 1.0479298208405488 * x + 0.0229467933410191 * y - 0.0501922295431356 *
|
|
15887
|
-
y: 0.0296278156881593 * x + 0.990434484573249 * y - 0.0170738250293851 *
|
|
15888
|
-
z: -0.0092430581525912 * x + 0.0150551448965779 * y + 0.7518742899580008 *
|
|
15983
|
+
x: 1.0479298208405488 * x + 0.0229467933410191 * y - 0.0501922295431356 * z56,
|
|
15984
|
+
y: 0.0296278156881593 * x + 0.990434484573249 * y - 0.0170738250293851 * z56,
|
|
15985
|
+
z: -0.0092430581525912 * x + 0.0150551448965779 * y + 0.7518742899580008 * z56
|
|
15889
15986
|
};
|
|
15890
15987
|
if (alpha !== void 0) {
|
|
15891
15988
|
res.alpha = alpha;
|
|
@@ -15896,15 +15993,15 @@ var convertXyz65ToXyz50_default = convertXyz65ToXyz50;
|
|
|
15896
15993
|
|
|
15897
15994
|
// ../../node_modules/culori/src/xyz65/convertXyz50ToXyz65.js
|
|
15898
15995
|
var convertXyz50ToXyz65 = (xyz502) => {
|
|
15899
|
-
let { x, y, z:
|
|
15996
|
+
let { x, y, z: z56, alpha } = xyz502;
|
|
15900
15997
|
if (x === void 0) x = 0;
|
|
15901
15998
|
if (y === void 0) y = 0;
|
|
15902
|
-
if (
|
|
15999
|
+
if (z56 === void 0) z56 = 0;
|
|
15903
16000
|
let res = {
|
|
15904
16001
|
mode: "xyz65",
|
|
15905
|
-
x: 0.9554734527042182 * x - 0.0230985368742614 * y + 0.0632593086610217 *
|
|
15906
|
-
y: -0.0283697069632081 * x + 1.0099954580058226 * y + 0.021041398966943 *
|
|
15907
|
-
z: 0.0123140016883199 * x - 0.0205076964334779 * y + 1.3303659366080753 *
|
|
16002
|
+
x: 0.9554734527042182 * x - 0.0230985368742614 * y + 0.0632593086610217 * z56,
|
|
16003
|
+
y: -0.0283697069632081 * x + 1.0099954580058226 * y + 0.021041398966943 * z56,
|
|
16004
|
+
z: 0.0123140016883199 * x - 0.0205076964334779 * y + 1.3303659366080753 * z56
|
|
15908
16005
|
};
|
|
15909
16006
|
if (alpha !== void 0) {
|
|
15910
16007
|
res.alpha = alpha;
|
|
@@ -16174,6 +16271,571 @@ zod.z.string().optional().nullable().transform((value) => {
|
|
|
16174
16271
|
}
|
|
16175
16272
|
);
|
|
16176
16273
|
|
|
16274
|
+
// ../../internal/utils/src/industry.ts
|
|
16275
|
+
var Industry = {
|
|
16276
|
+
// Finance
|
|
16277
|
+
BANKING: "banking",
|
|
16278
|
+
FINANCIAL_SERVICES: "financial_services",
|
|
16279
|
+
FINTECH: "fintech",
|
|
16280
|
+
PAYMENTS: "payments"};
|
|
16281
|
+
|
|
16282
|
+
// ../../internal/validation/src/dark-web/templates.ts
|
|
16283
|
+
var BRAND = { kind: "brand" };
|
|
16284
|
+
var lit = (value) => ({ kind: "literal", value });
|
|
16285
|
+
var phrase = (...tokens) => ({ type: "phrase", tokens });
|
|
16286
|
+
var bn = (slop, ...words) => ({
|
|
16287
|
+
type: "phrase",
|
|
16288
|
+
tokens: [BRAND, ...words.map(lit)],
|
|
16289
|
+
slop
|
|
16290
|
+
});
|
|
16291
|
+
var nb = (slop, ...words) => ({
|
|
16292
|
+
type: "phrase",
|
|
16293
|
+
tokens: [...words.map(lit), BRAND],
|
|
16294
|
+
slop
|
|
16295
|
+
});
|
|
16296
|
+
var word = (value) => ({ type: "term", value, match: "word" });
|
|
16297
|
+
var prefix = (value) => ({
|
|
16298
|
+
type: "term",
|
|
16299
|
+
value,
|
|
16300
|
+
match: "prefix"
|
|
16301
|
+
});
|
|
16302
|
+
var or = (...children) => ({
|
|
16303
|
+
type: "group",
|
|
16304
|
+
op: "OR",
|
|
16305
|
+
children
|
|
16306
|
+
});
|
|
16307
|
+
var and = (...children) => ({
|
|
16308
|
+
type: "group",
|
|
16309
|
+
op: "AND",
|
|
16310
|
+
children
|
|
16311
|
+
});
|
|
16312
|
+
var notOneOf = (...children) => ({
|
|
16313
|
+
type: "group",
|
|
16314
|
+
op: "OR",
|
|
16315
|
+
children,
|
|
16316
|
+
negated: true
|
|
16317
|
+
});
|
|
16318
|
+
var brandWith = (...values) => and(phrase(BRAND), or(...values.map(word)));
|
|
16319
|
+
var SCAN_TEMPLATES = [
|
|
16320
|
+
{
|
|
16321
|
+
id: "p2p-instant-transfer",
|
|
16322
|
+
category: "payment-fraud",
|
|
16323
|
+
title: "P2P and instant transfer abuse",
|
|
16324
|
+
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.",
|
|
16325
|
+
// Source rows: 1, 55. The original ("[brand]"~3) was proximity on one
|
|
16326
|
+
// position, a no-op; dropped rather than ported.
|
|
16327
|
+
query: and(
|
|
16328
|
+
or(
|
|
16329
|
+
phrase(BRAND, lit("to"), BRAND),
|
|
16330
|
+
bn(2, "instant"),
|
|
16331
|
+
bn(2, "anyone"),
|
|
16332
|
+
bn(1, "pay"),
|
|
16333
|
+
bn(3, "pay anyone"),
|
|
16334
|
+
bn(2, "p2p"),
|
|
16335
|
+
bn(3, "instant transfer"),
|
|
16336
|
+
bn(3, "receive from anyone"),
|
|
16337
|
+
bn(4, "phone number"),
|
|
16338
|
+
bn(2, "member to member"),
|
|
16339
|
+
nb(3, "send")
|
|
16340
|
+
),
|
|
16341
|
+
notOneOf(word("rate"), word("price"))
|
|
16342
|
+
)
|
|
16343
|
+
},
|
|
16344
|
+
{
|
|
16345
|
+
id: "transfers-ach-direct-debit",
|
|
16346
|
+
category: "payment-fraud",
|
|
16347
|
+
title: "Transfers, ACH and direct debit",
|
|
16348
|
+
description: "Discussion of pushing or pulling funds via ACH, direct debit or bill pay, including chatter about pending and settlement timing.",
|
|
16349
|
+
// Source rows: 6, 8, 18, 41. Row 18 was missing an OR before "Direct Debit".
|
|
16350
|
+
query: or(
|
|
16351
|
+
bn(1, "transfer"),
|
|
16352
|
+
nb(1, "transfer"),
|
|
16353
|
+
bn(5, "ach"),
|
|
16354
|
+
nb(4, "pull"),
|
|
16355
|
+
nb(4, "push"),
|
|
16356
|
+
bn(4, "pending"),
|
|
16357
|
+
bn(4, "settle"),
|
|
16358
|
+
nb(4, "link"),
|
|
16359
|
+
brandWith("billpay", "acctverify"),
|
|
16360
|
+
and(phrase(BRAND), or(phrase(lit("direct debit")), phrase(lit("direct deposit"))))
|
|
16361
|
+
)
|
|
16362
|
+
},
|
|
16363
|
+
{
|
|
16364
|
+
id: "wallet-linking",
|
|
16365
|
+
category: "payment-fraud",
|
|
16366
|
+
title: "Wallet linking and instant funding",
|
|
16367
|
+
description: "Linking the brand to mobile wallets for instant funding, and 'linkable' account trading where a name match is being sold.",
|
|
16368
|
+
// Source rows: 19, 44, 51
|
|
16369
|
+
query: and(
|
|
16370
|
+
or(
|
|
16371
|
+
bn(5, "apple pay"),
|
|
16372
|
+
bn(5, "apple"),
|
|
16373
|
+
bn(3, "apple linkable"),
|
|
16374
|
+
bn(2, "linkable"),
|
|
16375
|
+
bn(2, "linkables"),
|
|
16376
|
+
nb(2, "linkable"),
|
|
16377
|
+
nb(2, "link"),
|
|
16378
|
+
and(phrase(BRAND), phrase(lit("name match")))
|
|
16379
|
+
),
|
|
16380
|
+
notOneOf(word("espn"), word("airtag"))
|
|
16381
|
+
)
|
|
16382
|
+
},
|
|
16383
|
+
{
|
|
16384
|
+
id: "card-data-exposure",
|
|
16385
|
+
category: "payment-fraud",
|
|
16386
|
+
title: "Card data and virtual cards",
|
|
16387
|
+
description: "Brand-issued card details being traded: expiry, CVV, virtual card numbers and card activation.",
|
|
16388
|
+
// Source rows: 43
|
|
16389
|
+
query: and(
|
|
16390
|
+
brandWith("exp", "cvv", "vcc", "debit"),
|
|
16391
|
+
notOneOf(word("checking"), word("limits"))
|
|
16392
|
+
)
|
|
16393
|
+
},
|
|
16394
|
+
{
|
|
16395
|
+
id: "card-loading",
|
|
16396
|
+
category: "payment-fraud",
|
|
16397
|
+
title: "Card and account loading",
|
|
16398
|
+
description: "'Loading' services that push stolen funds onto brand accounts or cards for a cut.",
|
|
16399
|
+
// Source rows: 42
|
|
16400
|
+
query: or(
|
|
16401
|
+
nb(1, "loading"),
|
|
16402
|
+
nb(1, "load"),
|
|
16403
|
+
bn(1, "loads"),
|
|
16404
|
+
bn(1, "loading"),
|
|
16405
|
+
bn(3, "drop"),
|
|
16406
|
+
bn(2, "cash"),
|
|
16407
|
+
and(
|
|
16408
|
+
phrase(BRAND),
|
|
16409
|
+
or(
|
|
16410
|
+
phrase(lit("loading method")),
|
|
16411
|
+
phrase(lit("loading guide")),
|
|
16412
|
+
phrase(lit("loading tut")),
|
|
16413
|
+
phrase(lit("loading tutorial"))
|
|
16414
|
+
)
|
|
16415
|
+
)
|
|
16416
|
+
)
|
|
16417
|
+
},
|
|
16418
|
+
{
|
|
16419
|
+
id: "cross-platform-cashout",
|
|
16420
|
+
category: "payment-fraud",
|
|
16421
|
+
title: "Cross-platform cash-out",
|
|
16422
|
+
description: "Moving funds from the brand into other consumer payment apps to break the trail.",
|
|
16423
|
+
// Source rows: 56
|
|
16424
|
+
query: and(
|
|
16425
|
+
phrase(BRAND),
|
|
16426
|
+
or(
|
|
16427
|
+
phrase(lit("cash app")),
|
|
16428
|
+
word("venmo"),
|
|
16429
|
+
phrase(lit("transfer to paypal")),
|
|
16430
|
+
phrase(lit("visa money transfer"))
|
|
16431
|
+
)
|
|
16432
|
+
)
|
|
16433
|
+
},
|
|
16434
|
+
{
|
|
16435
|
+
id: "crypto-offramp",
|
|
16436
|
+
category: "payment-fraud",
|
|
16437
|
+
title: "Crypto off-ramp",
|
|
16438
|
+
description: "Converting funds held at the brand into cryptocurrency through exchanges and P2P markets.",
|
|
16439
|
+
// Source rows: 63
|
|
16440
|
+
query: and(
|
|
16441
|
+
phrase(BRAND),
|
|
16442
|
+
or(
|
|
16443
|
+
word("crypto"),
|
|
16444
|
+
word("moonpay"),
|
|
16445
|
+
word("switchere"),
|
|
16446
|
+
word("kraken"),
|
|
16447
|
+
word("paxful"),
|
|
16448
|
+
word("noones"),
|
|
16449
|
+
word("coinomi"),
|
|
16450
|
+
word("coinzoom"),
|
|
16451
|
+
word("bitcoin"),
|
|
16452
|
+
word("btc")
|
|
16453
|
+
)
|
|
16454
|
+
)
|
|
16455
|
+
},
|
|
16456
|
+
{
|
|
16457
|
+
id: "mobile-check-deposit",
|
|
16458
|
+
category: "deposit-fraud",
|
|
16459
|
+
title: "Mobile check deposit fraud",
|
|
16460
|
+
description: "Check fraud against mobile deposit, traded under slang including 'glass', 'MCD', 'slips' and 'persy'.",
|
|
16461
|
+
// Source rows: 2, 13, 35, 46
|
|
16462
|
+
industries: [
|
|
16463
|
+
Industry.BANKING,
|
|
16464
|
+
Industry.FINANCIAL_SERVICES,
|
|
16465
|
+
Industry.FINTECH,
|
|
16466
|
+
Industry.PAYMENTS
|
|
16467
|
+
],
|
|
16468
|
+
query: or(
|
|
16469
|
+
bn(5, "checks"),
|
|
16470
|
+
bn(5, "check"),
|
|
16471
|
+
bn(5, "mobile deposit"),
|
|
16472
|
+
nb(5, "mobile deposit"),
|
|
16473
|
+
bn(5, "slip"),
|
|
16474
|
+
bn(5, "slips"),
|
|
16475
|
+
bn(5, "glass"),
|
|
16476
|
+
bn(5, "md"),
|
|
16477
|
+
bn(5, "mcd"),
|
|
16478
|
+
bn(5, "treasury"),
|
|
16479
|
+
nb(5, "treasury"),
|
|
16480
|
+
bn(5, "persy"),
|
|
16481
|
+
bn(5, "deposit limit"),
|
|
16482
|
+
and(phrase(BRAND), or(prefix("stimm"), word("mcd"), phrase(lit("pop on"))))
|
|
16483
|
+
)
|
|
16484
|
+
},
|
|
16485
|
+
{
|
|
16486
|
+
id: "atm-abuse",
|
|
16487
|
+
category: "deposit-fraud",
|
|
16488
|
+
title: "ATM abuse and 'box work'",
|
|
16489
|
+
description: "ATM deposit and withdrawal manipulation, including dispute-driven 'box work' against cash machines.",
|
|
16490
|
+
// Source rows: 9, 47, 57, 70
|
|
16491
|
+
industries: [
|
|
16492
|
+
Industry.BANKING,
|
|
16493
|
+
Industry.FINANCIAL_SERVICES,
|
|
16494
|
+
Industry.FINTECH,
|
|
16495
|
+
Industry.PAYMENTS
|
|
16496
|
+
],
|
|
16497
|
+
query: or(
|
|
16498
|
+
bn(2, "atm"),
|
|
16499
|
+
bn(2, "withdrawal"),
|
|
16500
|
+
and(phrase(BRAND), phrase(lit("box work"))),
|
|
16501
|
+
and(
|
|
16502
|
+
phrase(BRAND),
|
|
16503
|
+
or(
|
|
16504
|
+
phrase(lit("atm deposit")),
|
|
16505
|
+
phrase(lit("atm withdrawal")),
|
|
16506
|
+
phrase(lit("atm withdraw")),
|
|
16507
|
+
phrase(lit("atm limit")),
|
|
16508
|
+
phrase(lit("atm card")),
|
|
16509
|
+
phrase(lit("cash withdrawal fee"))
|
|
16510
|
+
)
|
|
16511
|
+
)
|
|
16512
|
+
)
|
|
16513
|
+
},
|
|
16514
|
+
{
|
|
16515
|
+
id: "retail-cashout-network",
|
|
16516
|
+
category: "deposit-fraud",
|
|
16517
|
+
title: "Retail cash-out network",
|
|
16518
|
+
description: "Cash-out through retail and ATM partner networks, where funds are pulled at a storefront rather than a branch.",
|
|
16519
|
+
// Source rows: 30
|
|
16520
|
+
industries: [
|
|
16521
|
+
Industry.BANKING,
|
|
16522
|
+
Industry.FINANCIAL_SERVICES,
|
|
16523
|
+
Industry.FINTECH,
|
|
16524
|
+
Industry.PAYMENTS
|
|
16525
|
+
],
|
|
16526
|
+
query: or(
|
|
16527
|
+
bn(5, "allpoint"),
|
|
16528
|
+
bn(5, "walgreens"),
|
|
16529
|
+
bn(5, "cvs"),
|
|
16530
|
+
bn(5, "7-eleven"),
|
|
16531
|
+
bn(5, "7eleven"),
|
|
16532
|
+
bn(5, "711"),
|
|
16533
|
+
bn(5, "circle k"),
|
|
16534
|
+
bn(5, "target"),
|
|
16535
|
+
bn(5, "visa plus alliance"),
|
|
16536
|
+
bn(3, "moneypass"),
|
|
16537
|
+
bn(3, "vanilladirect"),
|
|
16538
|
+
bn(3, "vanilla"),
|
|
16539
|
+
bn(3, "dollar general"),
|
|
16540
|
+
bn(3, "dollar tree"),
|
|
16541
|
+
bn(3, "safeway"),
|
|
16542
|
+
bn(3, "walmart"),
|
|
16543
|
+
bn(3, "speedway")
|
|
16544
|
+
)
|
|
16545
|
+
},
|
|
16546
|
+
{
|
|
16547
|
+
id: "otp-bots",
|
|
16548
|
+
category: "account-takeover",
|
|
16549
|
+
title: "OTP bots and 2FA bypass",
|
|
16550
|
+
description: "Automated one-time-passcode interception services targeting the brand's login and step-up flows.",
|
|
16551
|
+
// Source rows: 34
|
|
16552
|
+
query: or(
|
|
16553
|
+
bn(2, "otp"),
|
|
16554
|
+
nb(1, "otp"),
|
|
16555
|
+
phrase(BRAND, lit("otp bot")),
|
|
16556
|
+
bn(2, "2fa"),
|
|
16557
|
+
bn(2, "code"),
|
|
16558
|
+
bn(2, "bypass"),
|
|
16559
|
+
bn(2, "bot"),
|
|
16560
|
+
bn(2, "bots")
|
|
16561
|
+
)
|
|
16562
|
+
},
|
|
16563
|
+
{
|
|
16564
|
+
id: "remote-access-tooling",
|
|
16565
|
+
category: "account-takeover",
|
|
16566
|
+
title: "Remote-access tooling",
|
|
16567
|
+
description: "Legitimate remote-management tools named alongside the brand, the standard toolkit for support-impersonation account takeover.",
|
|
16568
|
+
// Source rows: 29, 64. Truncated by the export; recoverable portion only.
|
|
16569
|
+
query: and(
|
|
16570
|
+
phrase(BRAND),
|
|
16571
|
+
or(
|
|
16572
|
+
word("action1"),
|
|
16573
|
+
phrase(lit("ammy admin")),
|
|
16574
|
+
word("ammyadmin"),
|
|
16575
|
+
word("anydesk"),
|
|
16576
|
+
phrase(lit("any desk")),
|
|
16577
|
+
word("atera"),
|
|
16578
|
+
word("beanywhere"),
|
|
16579
|
+
phrase(lit("chrome remote desktop")),
|
|
16580
|
+
word("connectwise"),
|
|
16581
|
+
word("screenconnect"),
|
|
16582
|
+
word("dameware"),
|
|
16583
|
+
word("domotz"),
|
|
16584
|
+
word("dwservice"),
|
|
16585
|
+
word("fleetdeck"),
|
|
16586
|
+
word("intelliadmin"),
|
|
16587
|
+
phrase(lit("itarian endpoint manager")),
|
|
16588
|
+
phrase(lit("level.io")),
|
|
16589
|
+
word("meshcentral"),
|
|
16590
|
+
word("mremoteng"),
|
|
16591
|
+
phrase(lit("n-able")),
|
|
16592
|
+
word("ngrok"),
|
|
16593
|
+
phrase(lit("pdq deploy")),
|
|
16594
|
+
word("pulseway"),
|
|
16595
|
+
word("realvnc"),
|
|
16596
|
+
phrase(lit("remote utilities")),
|
|
16597
|
+
word("rport")
|
|
16598
|
+
)
|
|
16599
|
+
)
|
|
16600
|
+
},
|
|
16601
|
+
{
|
|
16602
|
+
id: "antidetect-kyc-evasion",
|
|
16603
|
+
category: "account-takeover",
|
|
16604
|
+
title: "Anti-detect and KYC evasion tooling",
|
|
16605
|
+
description: "Fingerprint spoofing, residential proxies and emulators used to defeat the brand's device and identity checks.",
|
|
16606
|
+
// Source row: 40. The original filtered to Telegram OR Dread; DarkOwl's
|
|
16607
|
+
// `source` takes one value, so precision comes from the tooling terms.
|
|
16608
|
+
query: and(
|
|
16609
|
+
phrase(BRAND),
|
|
16610
|
+
or(
|
|
16611
|
+
word("tlo"),
|
|
16612
|
+
word("scamalytics"),
|
|
16613
|
+
word("burner"),
|
|
16614
|
+
prefix("prox"),
|
|
16615
|
+
word("vpn"),
|
|
16616
|
+
word("vps"),
|
|
16617
|
+
word("antidetect"),
|
|
16618
|
+
phrase(lit("anti-detect")),
|
|
16619
|
+
prefix("emulat")
|
|
16620
|
+
)
|
|
16621
|
+
)
|
|
16622
|
+
},
|
|
16623
|
+
{
|
|
16624
|
+
id: "brand-domains-sso",
|
|
16625
|
+
category: "account-takeover",
|
|
16626
|
+
title: "Brand domains and SSO endpoints",
|
|
16627
|
+
description: "The brand's own domains and identity-provider endpoints appearing in credential and access chatter.",
|
|
16628
|
+
// Source row: 31, as proximity not literal hostnames — the index tokenizes
|
|
16629
|
+
// `chime.okta.com`, so a glued literal would never match. Row 23's
|
|
16630
|
+
// "[brand] pass*"~1 is omitted: no wildcards inside a phrase.
|
|
16631
|
+
query: and(
|
|
16632
|
+
or(bn(2, "okta"), bn(2, "login"), bn(2, "portal"), bn(1, "bank")),
|
|
16633
|
+
notOneOf(word("zendesk"))
|
|
16634
|
+
)
|
|
16635
|
+
},
|
|
16636
|
+
{
|
|
16637
|
+
id: "account-opening-abuse",
|
|
16638
|
+
category: "onboarding-abuse",
|
|
16639
|
+
title: "Account opening and self-registration",
|
|
16640
|
+
description: "Bulk or fraudulent account creation against the brand, including 'self-reg' and 'drop' accounts opened on stolen identities.",
|
|
16641
|
+
// Source rows: 5, 17, 54
|
|
16642
|
+
query: or(
|
|
16643
|
+
bn(5, "enroll"),
|
|
16644
|
+
nb(5, "enroll"),
|
|
16645
|
+
bn(5, "open"),
|
|
16646
|
+
nb(5, "open"),
|
|
16647
|
+
bn(5, "drop"),
|
|
16648
|
+
nb(5, "drop"),
|
|
16649
|
+
nb(5, "make"),
|
|
16650
|
+
nb(5, "create"),
|
|
16651
|
+
nb(5, "fresh"),
|
|
16652
|
+
nb(5, "register"),
|
|
16653
|
+
bn(5, "self-reg"),
|
|
16654
|
+
bn(5, "selfreg"),
|
|
16655
|
+
bn(5, "self-registered"),
|
|
16656
|
+
bn(5, "self register"),
|
|
16657
|
+
bn(1, "fullz")
|
|
16658
|
+
)
|
|
16659
|
+
},
|
|
16660
|
+
{
|
|
16661
|
+
id: "identity-documents",
|
|
16662
|
+
category: "onboarding-abuse",
|
|
16663
|
+
title: "Identity documents and fullz",
|
|
16664
|
+
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.",
|
|
16665
|
+
// Source row: 15. Lexicon-only, so the renderer AND-s the anchor on.
|
|
16666
|
+
query: or(
|
|
16667
|
+
word("fullz"),
|
|
16668
|
+
phrase(lit("get pros")),
|
|
16669
|
+
phrase(lit("driver's license")),
|
|
16670
|
+
phrase(lit("tlo bot")),
|
|
16671
|
+
phrase(lit("tlo plug")),
|
|
16672
|
+
phrase(lit("need dl")),
|
|
16673
|
+
phrase(lit("get id"))
|
|
16674
|
+
)
|
|
16675
|
+
},
|
|
16676
|
+
{
|
|
16677
|
+
id: "referral-bonus-abuse",
|
|
16678
|
+
category: "onboarding-abuse",
|
|
16679
|
+
title: "Referral and bonus abuse",
|
|
16680
|
+
description: "Methods for farming the brand's referral bonuses and promotional offers, often paired with fake direct deposits.",
|
|
16681
|
+
// Source rows: 48
|
|
16682
|
+
query: and(
|
|
16683
|
+
or(bn(3, "referral"), bn(3, "bonus"), bn(3, "promotion"), bn(3, "offer")),
|
|
16684
|
+
or(
|
|
16685
|
+
word("bypass"),
|
|
16686
|
+
word("dd"),
|
|
16687
|
+
phrase(lit("direct deposit")),
|
|
16688
|
+
phrase(lit("work around")),
|
|
16689
|
+
word("trick"),
|
|
16690
|
+
word("method"),
|
|
16691
|
+
word("glitch"),
|
|
16692
|
+
word("tutorial"),
|
|
16693
|
+
word("tut"),
|
|
16694
|
+
word("wave"),
|
|
16695
|
+
word("sauce")
|
|
16696
|
+
)
|
|
16697
|
+
)
|
|
16698
|
+
},
|
|
16699
|
+
{
|
|
16700
|
+
id: "insider-recruitment",
|
|
16701
|
+
category: "insider-threat",
|
|
16702
|
+
title: "Insider recruitment",
|
|
16703
|
+
description: "Actors seeking or advertising an employee on the inside ('inny'), the highest-severity signal in this catalog.",
|
|
16704
|
+
// Source rows: 7, 38
|
|
16705
|
+
query: and(
|
|
16706
|
+
or(
|
|
16707
|
+
bn(4, "inny"),
|
|
16708
|
+
bn(4, "insider"),
|
|
16709
|
+
and(
|
|
16710
|
+
phrase(BRAND),
|
|
16711
|
+
or(
|
|
16712
|
+
word("insider"),
|
|
16713
|
+
word("inny"),
|
|
16714
|
+
phrase(lit("in office")),
|
|
16715
|
+
word("employee"),
|
|
16716
|
+
phrase(lit("i work at")),
|
|
16717
|
+
phrase(lit("i am an employee")),
|
|
16718
|
+
phrase(lit("i can get access")),
|
|
16719
|
+
phrase(lit("i have access to")),
|
|
16720
|
+
phrase(lit("employed at")),
|
|
16721
|
+
word("occupation")
|
|
16722
|
+
)
|
|
16723
|
+
)
|
|
16724
|
+
),
|
|
16725
|
+
notOneOf(phrase(lit("welcome to insider chat")))
|
|
16726
|
+
)
|
|
16727
|
+
},
|
|
16728
|
+
{
|
|
16729
|
+
id: "mule-crew-recruitment",
|
|
16730
|
+
category: "insider-threat",
|
|
16731
|
+
title: "Mule and cash-out crew recruitment",
|
|
16732
|
+
description: "Recruitment of account holders to receive and forward funds, priced as a revenue split ('50/50', '60/40').",
|
|
16733
|
+
// Source rows: 39
|
|
16734
|
+
query: or(
|
|
16735
|
+
bn(5, "cl"),
|
|
16736
|
+
bn(5, "mule"),
|
|
16737
|
+
bn(5, "tap in"),
|
|
16738
|
+
bn(5, "50/50"),
|
|
16739
|
+
bn(5, "60/40"),
|
|
16740
|
+
bn(5, "striker")
|
|
16741
|
+
)
|
|
16742
|
+
},
|
|
16743
|
+
{
|
|
16744
|
+
id: "methods-and-tutorials",
|
|
16745
|
+
category: "tradecraft",
|
|
16746
|
+
title: "Methods, 'sauce' and tutorials",
|
|
16747
|
+
description: "Fraud methods being taught or sold against the brand, under the usual slang: sauce, glitch, tut, wave, motion, tap in.",
|
|
16748
|
+
// Source rows: 4, 21, 59
|
|
16749
|
+
query: or(
|
|
16750
|
+
bn(3, "sauce"),
|
|
16751
|
+
bn(3, "method"),
|
|
16752
|
+
bn(3, "guide"),
|
|
16753
|
+
bn(3, "tut"),
|
|
16754
|
+
bn(3, "tutorial"),
|
|
16755
|
+
bn(4, "hack"),
|
|
16756
|
+
bn(4, "glitch"),
|
|
16757
|
+
bn(4, "wave"),
|
|
16758
|
+
bn(4, "motion"),
|
|
16759
|
+
bn(4, "walkthrough"),
|
|
16760
|
+
bn(4, "walk through"),
|
|
16761
|
+
bn(2, "tap in"),
|
|
16762
|
+
bn(2, "tapin"),
|
|
16763
|
+
nb(2, "tapn")
|
|
16764
|
+
)
|
|
16765
|
+
},
|
|
16766
|
+
{
|
|
16767
|
+
id: "hack-leak-chatter",
|
|
16768
|
+
category: "tradecraft",
|
|
16769
|
+
title: "Hack and leak chatter",
|
|
16770
|
+
description: "Claims of having hacked, breached or leaked the brand, whether credible or not.",
|
|
16771
|
+
// Source rows: 28
|
|
16772
|
+
query: or(
|
|
16773
|
+
bn(4, "hack"),
|
|
16774
|
+
bn(4, "glitch"),
|
|
16775
|
+
nb(4, "hacking"),
|
|
16776
|
+
bn(4, "leak"),
|
|
16777
|
+
bn(4, "leaked")
|
|
16778
|
+
)
|
|
16779
|
+
},
|
|
16780
|
+
{
|
|
16781
|
+
id: "support-impersonation",
|
|
16782
|
+
category: "brand-abuse",
|
|
16783
|
+
title: "Support impersonation",
|
|
16784
|
+
description: "Actors impersonating the brand's support or service staff to social-engineer customers.",
|
|
16785
|
+
// Source rows: 36
|
|
16786
|
+
query: or(
|
|
16787
|
+
bn(1, "agent"),
|
|
16788
|
+
bn(1, "support"),
|
|
16789
|
+
bn(1, "service"),
|
|
16790
|
+
bn(1, "customer"),
|
|
16791
|
+
nb(1, "impersonate"),
|
|
16792
|
+
bn(1, "impersonation"),
|
|
16793
|
+
bn(3, "scam"),
|
|
16794
|
+
nb(1, "scam")
|
|
16795
|
+
)
|
|
16796
|
+
},
|
|
16797
|
+
{
|
|
16798
|
+
id: "social-impersonation",
|
|
16799
|
+
category: "brand-abuse",
|
|
16800
|
+
title: "Social account impersonation",
|
|
16801
|
+
description: "The brand discussed alongside social platforms, where fake support and giveaway accounts are staged.",
|
|
16802
|
+
// Source rows: 25
|
|
16803
|
+
query: or(
|
|
16804
|
+
bn(5, "instagram"),
|
|
16805
|
+
bn(5, "insta"),
|
|
16806
|
+
bn(5, "facebook"),
|
|
16807
|
+
bn(5, "twitter"),
|
|
16808
|
+
bn(5, "tiktok")
|
|
16809
|
+
)
|
|
16810
|
+
},
|
|
16811
|
+
{
|
|
16812
|
+
id: "vendor-supply-chain",
|
|
16813
|
+
category: "data-exposure",
|
|
16814
|
+
title: "Vendor and BPO supply chain",
|
|
16815
|
+
description: "Outsourced support and processing vendors named alongside the brand, where a third-party breach exposes brand customer data.",
|
|
16816
|
+
// Source row: 60, truncated by the export. Generic BPO/CX providers; a
|
|
16817
|
+
// per-org vendor list would be materially better.
|
|
16818
|
+
query: and(
|
|
16819
|
+
phrase(BRAND),
|
|
16820
|
+
or(
|
|
16821
|
+
word("zendesk"),
|
|
16822
|
+
word("teleperformance"),
|
|
16823
|
+
word("concentrix"),
|
|
16824
|
+
word("taskus"),
|
|
16825
|
+
word("genpact"),
|
|
16826
|
+
word("ubiquity"),
|
|
16827
|
+
word("hioperator"),
|
|
16828
|
+
word("galileo"),
|
|
16829
|
+
word("fiserv"),
|
|
16830
|
+
phrase(lit("etech global"))
|
|
16831
|
+
)
|
|
16832
|
+
)
|
|
16833
|
+
}
|
|
16834
|
+
];
|
|
16835
|
+
new Map(
|
|
16836
|
+
SCAN_TEMPLATES.map((template) => [template.id, template])
|
|
16837
|
+
);
|
|
16838
|
+
|
|
16177
16839
|
// src/client.ts
|
|
16178
16840
|
function trimTrailingSlashes(url) {
|
|
16179
16841
|
return url.replace(/\/+$/, "");
|