@chainpatrol/sdk 1.8.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 +6 -0
- package/dist/api/index.d.mts +3 -1
- package/dist/api/index.d.ts +3 -1
- package/dist/api/index.js +2 -0
- package/dist/api/index.js.map +1 -1
- package/dist/api/index.mjs +2 -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 +689 -76
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +689 -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(
|
|
@@ -11993,7 +12037,9 @@ var organizationMetricsIncludeFieldSchema = zod.z.enum([
|
|
|
11993
12037
|
"newThreats",
|
|
11994
12038
|
"threatsWatchlisted",
|
|
11995
12039
|
"takedownsFiled",
|
|
12040
|
+
"takedownsInProgress",
|
|
11996
12041
|
"takedownsCompleted",
|
|
12042
|
+
"takedownsCancelled",
|
|
11997
12043
|
"domainThreats",
|
|
11998
12044
|
"twitterThreats",
|
|
11999
12045
|
"telegramThreats",
|
|
@@ -12035,7 +12081,7 @@ zod.z.object({
|
|
|
12035
12081
|
startDate: zod.z.coerce.date().optional(),
|
|
12036
12082
|
endDate: zod.z.coerce.date().optional(),
|
|
12037
12083
|
include: zod.z.array(organizationMetricsIncludeFieldSchema).optional().describe(
|
|
12038
|
-
"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."
|
|
12039
12085
|
)
|
|
12040
12086
|
}).refine(
|
|
12041
12087
|
(value) => {
|
|
@@ -12063,7 +12109,9 @@ var metricsObjectSchema = zod.z.object({
|
|
|
12063
12109
|
newThreats: metricValue,
|
|
12064
12110
|
threatsWatchlisted: metricValue,
|
|
12065
12111
|
takedownsFiled: metricValue,
|
|
12112
|
+
takedownsInProgress: metricValue,
|
|
12066
12113
|
takedownsCompleted: metricValue,
|
|
12114
|
+
takedownsCancelled: metricValue,
|
|
12067
12115
|
domainThreats: metricValue,
|
|
12068
12116
|
twitterThreats: metricValue,
|
|
12069
12117
|
telegramThreats: metricValue,
|
|
@@ -13446,20 +13494,20 @@ var convertA98ToXyz65_default = convertA98ToXyz65;
|
|
|
13446
13494
|
|
|
13447
13495
|
// ../../node_modules/culori/src/a98/convertXyz65ToA98.js
|
|
13448
13496
|
var gamma = (v) => Math.pow(Math.abs(v), 256 / 563) * Math.sign(v);
|
|
13449
|
-
var convertXyz65ToA98 = ({ x, y, z:
|
|
13497
|
+
var convertXyz65ToA98 = ({ x, y, z: z56, alpha }) => {
|
|
13450
13498
|
if (x === void 0) x = 0;
|
|
13451
13499
|
if (y === void 0) y = 0;
|
|
13452
|
-
if (
|
|
13500
|
+
if (z56 === void 0) z56 = 0;
|
|
13453
13501
|
let res = {
|
|
13454
13502
|
mode: "a98",
|
|
13455
13503
|
r: gamma(
|
|
13456
|
-
x * 2.0415879038107465 - y * 0.5650069742788597 - 0.3447313507783297 *
|
|
13504
|
+
x * 2.0415879038107465 - y * 0.5650069742788597 - 0.3447313507783297 * z56
|
|
13457
13505
|
),
|
|
13458
13506
|
g: gamma(
|
|
13459
|
-
x * -0.9692436362808798 + y * 1.8759675015077206 + 0.0415550574071756 *
|
|
13507
|
+
x * -0.9692436362808798 + y * 1.8759675015077206 + 0.0415550574071756 * z56
|
|
13460
13508
|
),
|
|
13461
13509
|
b: gamma(
|
|
13462
|
-
x * 0.0134442806320312 - y * 0.1183623922310184 + 1.0151749943912058 *
|
|
13510
|
+
x * 0.0134442806320312 - y * 0.1183623922310184 + 1.0151749943912058 * z56
|
|
13463
13511
|
)
|
|
13464
13512
|
};
|
|
13465
13513
|
if (alpha !== void 0) {
|
|
@@ -13526,14 +13574,14 @@ var convertLrgbToRgb = ({ r, g, b, alpha }, mode = "rgb") => {
|
|
|
13526
13574
|
var convertLrgbToRgb_default = convertLrgbToRgb;
|
|
13527
13575
|
|
|
13528
13576
|
// ../../node_modules/culori/src/xyz65/convertXyz65ToRgb.js
|
|
13529
|
-
var convertXyz65ToRgb = ({ x, y, z:
|
|
13577
|
+
var convertXyz65ToRgb = ({ x, y, z: z56, alpha }) => {
|
|
13530
13578
|
if (x === void 0) x = 0;
|
|
13531
13579
|
if (y === void 0) y = 0;
|
|
13532
|
-
if (
|
|
13580
|
+
if (z56 === void 0) z56 = 0;
|
|
13533
13581
|
let res = convertLrgbToRgb_default({
|
|
13534
|
-
r: x * 3.2409699419045226 - y * 1.537383177570094 - 0.4986107602930034 *
|
|
13535
|
-
g: x * -0.9692436362808796 + y * 1.8759675015077204 + 0.0415550574071756 *
|
|
13536
|
-
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
|
|
13537
13585
|
});
|
|
13538
13586
|
if (alpha !== void 0) {
|
|
13539
13587
|
res.alpha = alpha;
|
|
@@ -13783,13 +13831,13 @@ var convertLab65ToRgb_default = convertLab65ToRgb;
|
|
|
13783
13831
|
|
|
13784
13832
|
// ../../node_modules/culori/src/lab65/convertXyz65ToLab65.js
|
|
13785
13833
|
var f = (value) => value > e ? Math.cbrt(value) : (k * value + 16) / 116;
|
|
13786
|
-
var convertXyz65ToLab65 = ({ x, y, z:
|
|
13834
|
+
var convertXyz65ToLab65 = ({ x, y, z: z56, alpha }) => {
|
|
13787
13835
|
if (x === void 0) x = 0;
|
|
13788
13836
|
if (y === void 0) y = 0;
|
|
13789
|
-
if (
|
|
13837
|
+
if (z56 === void 0) z56 = 0;
|
|
13790
13838
|
let f0 = f(x / D65.X);
|
|
13791
13839
|
let f1 = f(y / D65.Y);
|
|
13792
|
-
let f22 = f(
|
|
13840
|
+
let f22 = f(z56 / D65.Z);
|
|
13793
13841
|
let res = {
|
|
13794
13842
|
mode: "lab65",
|
|
13795
13843
|
l: 116 * f1 - 16,
|
|
@@ -14446,10 +14494,10 @@ var convertItpToXyz65_default = convertItpToXyz65;
|
|
|
14446
14494
|
|
|
14447
14495
|
// ../../node_modules/culori/src/itp/convertXyz65ToItp.js
|
|
14448
14496
|
var toAbs = (c2 = 0) => Math.max(c2 * YW, 0);
|
|
14449
|
-
var convertXyz65ToItp = ({ x, y, z:
|
|
14497
|
+
var convertXyz65ToItp = ({ x, y, z: z56, alpha }) => {
|
|
14450
14498
|
const absX = toAbs(x);
|
|
14451
14499
|
const absY = toAbs(y);
|
|
14452
|
-
const absZ = toAbs(
|
|
14500
|
+
const absZ = toAbs(z56);
|
|
14453
14501
|
const l2 = transferPqEncode(
|
|
14454
14502
|
0.3592832590121217 * absX + 0.6976051147779502 * absY - 0.0358915932320289 * absZ
|
|
14455
14503
|
);
|
|
@@ -14507,15 +14555,15 @@ var jabPqEncode = (v) => {
|
|
|
14507
14555
|
return Math.pow((C1 + C2 * vn3) / (1 + C3 * vn3), p);
|
|
14508
14556
|
};
|
|
14509
14557
|
var abs = (v = 0) => Math.max(v * 203, 0);
|
|
14510
|
-
var convertXyz65ToJab = ({ x, y, z:
|
|
14558
|
+
var convertXyz65ToJab = ({ x, y, z: z56, alpha }) => {
|
|
14511
14559
|
x = abs(x);
|
|
14512
14560
|
y = abs(y);
|
|
14513
|
-
|
|
14514
|
-
let xp = 1.15 * x - 0.15 *
|
|
14561
|
+
z56 = abs(z56);
|
|
14562
|
+
let xp = 1.15 * x - 0.15 * z56;
|
|
14515
14563
|
let yp = 0.66 * y + 0.34 * x;
|
|
14516
|
-
let l2 = jabPqEncode(0.41478972 * xp + 0.579999 * yp + 0.014648 *
|
|
14517
|
-
let m = jabPqEncode(-0.20151 * xp + 1.120649 * yp + 0.0531008 *
|
|
14518
|
-
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);
|
|
14519
14567
|
let i = (l2 + m) / 2;
|
|
14520
14568
|
let res = {
|
|
14521
14569
|
mode: "jab",
|
|
@@ -14701,14 +14749,14 @@ var convertLabToXyz50 = ({ l: l2, a, b, alpha }) => {
|
|
|
14701
14749
|
var convertLabToXyz50_default = convertLabToXyz50;
|
|
14702
14750
|
|
|
14703
14751
|
// ../../node_modules/culori/src/xyz50/convertXyz50ToRgb.js
|
|
14704
|
-
var convertXyz50ToRgb = ({ x, y, z:
|
|
14752
|
+
var convertXyz50ToRgb = ({ x, y, z: z56, alpha }) => {
|
|
14705
14753
|
if (x === void 0) x = 0;
|
|
14706
14754
|
if (y === void 0) y = 0;
|
|
14707
|
-
if (
|
|
14755
|
+
if (z56 === void 0) z56 = 0;
|
|
14708
14756
|
let res = convertLrgbToRgb_default({
|
|
14709
|
-
r: x * 3.1341359569958707 - y * 1.6173863321612538 - 0.4906619460083532 *
|
|
14710
|
-
g: x * -0.978795502912089 + y * 1.916254567259524 + 0.03344273116131949 *
|
|
14711
|
-
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
|
|
14712
14760
|
});
|
|
14713
14761
|
if (alpha !== void 0) {
|
|
14714
14762
|
res.alpha = alpha;
|
|
@@ -14739,13 +14787,13 @@ var convertRgbToXyz50_default = convertRgbToXyz50;
|
|
|
14739
14787
|
|
|
14740
14788
|
// ../../node_modules/culori/src/lab/convertXyz50ToLab.js
|
|
14741
14789
|
var f2 = (value) => value > e3 ? Math.cbrt(value) : (k3 * value + 16) / 116;
|
|
14742
|
-
var convertXyz50ToLab = ({ x, y, z:
|
|
14790
|
+
var convertXyz50ToLab = ({ x, y, z: z56, alpha }) => {
|
|
14743
14791
|
if (x === void 0) x = 0;
|
|
14744
14792
|
if (y === void 0) y = 0;
|
|
14745
|
-
if (
|
|
14793
|
+
if (z56 === void 0) z56 = 0;
|
|
14746
14794
|
let f0 = f2(x / D50.X);
|
|
14747
14795
|
let f1 = f2(y / D50.Y);
|
|
14748
|
-
let f22 = f2(
|
|
14796
|
+
let f22 = f2(z56 / D50.Z);
|
|
14749
14797
|
let res = {
|
|
14750
14798
|
mode: "lab",
|
|
14751
14799
|
l: 116 * f1 - 16,
|
|
@@ -14980,18 +15028,18 @@ var convertLchuvToLuv = ({ l: l2, c: c2, h, alpha }) => {
|
|
|
14980
15028
|
var convertLchuvToLuv_default = convertLchuvToLuv;
|
|
14981
15029
|
|
|
14982
15030
|
// ../../node_modules/culori/src/luv/convertXyz50ToLuv.js
|
|
14983
|
-
var u_fn = (x, y,
|
|
14984
|
-
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);
|
|
14985
15033
|
var un = u_fn(D50.X, D50.Y, D50.Z);
|
|
14986
15034
|
var vn = v_fn(D50.X, D50.Y, D50.Z);
|
|
14987
15035
|
var l_fn = (value) => value <= e3 ? k3 * value : 116 * Math.cbrt(value) - 16;
|
|
14988
|
-
var convertXyz50ToLuv = ({ x, y, z:
|
|
15036
|
+
var convertXyz50ToLuv = ({ x, y, z: z56, alpha }) => {
|
|
14989
15037
|
if (x === void 0) x = 0;
|
|
14990
15038
|
if (y === void 0) y = 0;
|
|
14991
|
-
if (
|
|
15039
|
+
if (z56 === void 0) z56 = 0;
|
|
14992
15040
|
let l2 = l_fn(y / D50.Y);
|
|
14993
|
-
let u = u_fn(x, y,
|
|
14994
|
-
let v = v_fn(x, y,
|
|
15041
|
+
let u = u_fn(x, y, z56);
|
|
15042
|
+
let v = v_fn(x, y, z56);
|
|
14995
15043
|
if (!isFinite(u) || !isFinite(v)) {
|
|
14996
15044
|
l2 = u = v = 0;
|
|
14997
15045
|
} else {
|
|
@@ -15012,8 +15060,8 @@ var convertXyz50ToLuv = ({ x, y, z: z55, alpha }) => {
|
|
|
15012
15060
|
var convertXyz50ToLuv_default = convertXyz50ToLuv;
|
|
15013
15061
|
|
|
15014
15062
|
// ../../node_modules/culori/src/luv/convertLuvToXyz50.js
|
|
15015
|
-
var u_fn2 = (x, y,
|
|
15016
|
-
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);
|
|
15017
15065
|
var un2 = u_fn2(D50.X, D50.Y, D50.Z);
|
|
15018
15066
|
var vn2 = v_fn2(D50.X, D50.Y, D50.Z);
|
|
15019
15067
|
var convertLuvToXyz50 = ({ l: l2, u, v, alpha }) => {
|
|
@@ -15027,8 +15075,8 @@ var convertLuvToXyz50 = ({ l: l2, u, v, alpha }) => {
|
|
|
15027
15075
|
let vp = v / (13 * l2) + vn2;
|
|
15028
15076
|
let y = D50.Y * (l2 <= 8 ? l2 / k3 : Math.pow((l2 + 16) / 116, 3));
|
|
15029
15077
|
let x = y * (9 * up) / (4 * vp);
|
|
15030
|
-
let
|
|
15031
|
-
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 };
|
|
15032
15080
|
if (alpha !== void 0) {
|
|
15033
15081
|
res.alpha = alpha;
|
|
15034
15082
|
}
|
|
@@ -15645,15 +15693,15 @@ var convertP3ToXyz65 = (rgb2) => {
|
|
|
15645
15693
|
var convertP3ToXyz65_default = convertP3ToXyz65;
|
|
15646
15694
|
|
|
15647
15695
|
// ../../node_modules/culori/src/p3/convertXyz65ToP3.js
|
|
15648
|
-
var convertXyz65ToP3 = ({ x, y, z:
|
|
15696
|
+
var convertXyz65ToP3 = ({ x, y, z: z56, alpha }) => {
|
|
15649
15697
|
if (x === void 0) x = 0;
|
|
15650
15698
|
if (y === void 0) y = 0;
|
|
15651
|
-
if (
|
|
15699
|
+
if (z56 === void 0) z56 = 0;
|
|
15652
15700
|
let res = convertLrgbToRgb_default(
|
|
15653
15701
|
{
|
|
15654
|
-
r: x * 2.4934969119414263 - y * 0.9313836179191242 - 0.402710784450717 *
|
|
15655
|
-
g: x * -0.8294889695615749 + y * 1.7626640603183465 + 0.0236246858419436 *
|
|
15656
|
-
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
|
|
15657
15705
|
},
|
|
15658
15706
|
"p3"
|
|
15659
15707
|
);
|
|
@@ -15688,19 +15736,19 @@ var gamma2 = (v) => {
|
|
|
15688
15736
|
}
|
|
15689
15737
|
return 16 * v;
|
|
15690
15738
|
};
|
|
15691
|
-
var convertXyz50ToProphoto = ({ x, y, z:
|
|
15739
|
+
var convertXyz50ToProphoto = ({ x, y, z: z56, alpha }) => {
|
|
15692
15740
|
if (x === void 0) x = 0;
|
|
15693
15741
|
if (y === void 0) y = 0;
|
|
15694
|
-
if (
|
|
15742
|
+
if (z56 === void 0) z56 = 0;
|
|
15695
15743
|
let res = {
|
|
15696
15744
|
mode: "prophoto",
|
|
15697
15745
|
r: gamma2(
|
|
15698
|
-
x * 1.3457868816471585 - y * 0.2555720873797946 - 0.0511018649755453 *
|
|
15746
|
+
x * 1.3457868816471585 - y * 0.2555720873797946 - 0.0511018649755453 * z56
|
|
15699
15747
|
),
|
|
15700
15748
|
g: gamma2(
|
|
15701
|
-
x * -0.5446307051249019 + y * 1.5082477428451466 + 0.0205274474364214 *
|
|
15749
|
+
x * -0.5446307051249019 + y * 1.5082477428451466 + 0.0205274474364214 * z56
|
|
15702
15750
|
),
|
|
15703
|
-
b: gamma2(x * 0 + y * 0 + 1.2119675456389452 *
|
|
15751
|
+
b: gamma2(x * 0 + y * 0 + 1.2119675456389452 * z56)
|
|
15704
15752
|
};
|
|
15705
15753
|
if (alpha !== void 0) {
|
|
15706
15754
|
res.alpha = alpha;
|
|
@@ -15760,20 +15808,20 @@ var gamma3 = (v) => {
|
|
|
15760
15808
|
}
|
|
15761
15809
|
return 4.5 * v;
|
|
15762
15810
|
};
|
|
15763
|
-
var convertXyz65ToRec2020 = ({ x, y, z:
|
|
15811
|
+
var convertXyz65ToRec2020 = ({ x, y, z: z56, alpha }) => {
|
|
15764
15812
|
if (x === void 0) x = 0;
|
|
15765
15813
|
if (y === void 0) y = 0;
|
|
15766
|
-
if (
|
|
15814
|
+
if (z56 === void 0) z56 = 0;
|
|
15767
15815
|
let res = {
|
|
15768
15816
|
mode: "rec2020",
|
|
15769
15817
|
r: gamma3(
|
|
15770
|
-
x * 1.7166511879712683 - y * 0.3556707837763925 - 0.2533662813736599 *
|
|
15818
|
+
x * 1.7166511879712683 - y * 0.3556707837763925 - 0.2533662813736599 * z56
|
|
15771
15819
|
),
|
|
15772
15820
|
g: gamma3(
|
|
15773
|
-
x * -0.6666843518324893 + y * 1.6164812366349395 + 0.0157685458139111 *
|
|
15821
|
+
x * -0.6666843518324893 + y * 1.6164812366349395 + 0.0157685458139111 * z56
|
|
15774
15822
|
),
|
|
15775
15823
|
b: gamma3(
|
|
15776
|
-
x * 0.0176398574453108 - y * 0.0427706132578085 + 0.9421031212354739 *
|
|
15824
|
+
x * 0.0176398574453108 - y * 0.0427706132578085 + 0.9421031212354739 * z56
|
|
15777
15825
|
)
|
|
15778
15826
|
};
|
|
15779
15827
|
if (alpha !== void 0) {
|
|
@@ -15926,15 +15974,15 @@ var definition_default26 = definition26;
|
|
|
15926
15974
|
|
|
15927
15975
|
// ../../node_modules/culori/src/xyz65/convertXyz65ToXyz50.js
|
|
15928
15976
|
var convertXyz65ToXyz50 = (xyz652) => {
|
|
15929
|
-
let { x, y, z:
|
|
15977
|
+
let { x, y, z: z56, alpha } = xyz652;
|
|
15930
15978
|
if (x === void 0) x = 0;
|
|
15931
15979
|
if (y === void 0) y = 0;
|
|
15932
|
-
if (
|
|
15980
|
+
if (z56 === void 0) z56 = 0;
|
|
15933
15981
|
let res = {
|
|
15934
15982
|
mode: "xyz50",
|
|
15935
|
-
x: 1.0479298208405488 * x + 0.0229467933410191 * y - 0.0501922295431356 *
|
|
15936
|
-
y: 0.0296278156881593 * x + 0.990434484573249 * y - 0.0170738250293851 *
|
|
15937
|
-
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
|
|
15938
15986
|
};
|
|
15939
15987
|
if (alpha !== void 0) {
|
|
15940
15988
|
res.alpha = alpha;
|
|
@@ -15945,15 +15993,15 @@ var convertXyz65ToXyz50_default = convertXyz65ToXyz50;
|
|
|
15945
15993
|
|
|
15946
15994
|
// ../../node_modules/culori/src/xyz65/convertXyz50ToXyz65.js
|
|
15947
15995
|
var convertXyz50ToXyz65 = (xyz502) => {
|
|
15948
|
-
let { x, y, z:
|
|
15996
|
+
let { x, y, z: z56, alpha } = xyz502;
|
|
15949
15997
|
if (x === void 0) x = 0;
|
|
15950
15998
|
if (y === void 0) y = 0;
|
|
15951
|
-
if (
|
|
15999
|
+
if (z56 === void 0) z56 = 0;
|
|
15952
16000
|
let res = {
|
|
15953
16001
|
mode: "xyz65",
|
|
15954
|
-
x: 0.9554734527042182 * x - 0.0230985368742614 * y + 0.0632593086610217 *
|
|
15955
|
-
y: -0.0283697069632081 * x + 1.0099954580058226 * y + 0.021041398966943 *
|
|
15956
|
-
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
|
|
15957
16005
|
};
|
|
15958
16006
|
if (alpha !== void 0) {
|
|
15959
16007
|
res.alpha = alpha;
|
|
@@ -16223,6 +16271,571 @@ zod.z.string().optional().nullable().transform((value) => {
|
|
|
16223
16271
|
}
|
|
16224
16272
|
);
|
|
16225
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
|
+
|
|
16226
16839
|
// src/client.ts
|
|
16227
16840
|
function trimTrailingSlashes(url) {
|
|
16228
16841
|
return url.replace(/\/+$/, "");
|