@chainpatrol/sdk 1.9.0 → 1.11.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/dist/index.js CHANGED
@@ -601,45 +601,6 @@ zod.z.object({
601
601
  name: zod.z.string().optional().describe("Asset name"),
602
602
  description: zod.z.string().nullish().optional().describe("Asset description")
603
603
  });
604
- zod.z.object({
605
- slug: zod.z.string(),
606
- assetId: zod.z.number(),
607
- name: zod.z.string().optional(),
608
- description: zod.z.string().optional(),
609
- assetGroupId: zod.z.number().nullable().optional(),
610
- updatedByOrganizationId: zod.z.number().optional()
611
- });
612
- zod.z.object({
613
- content: zod.z.string().min(1, { message: "Content must be at least 3 character" }).max(1e3, { message: "Content must be less than 1000 characters" }),
614
- email: zod.z.string().email(),
615
- description: zod.z.string().optional().default("")
616
- });
617
- zod.z.object({
618
- /** Canonicalization algorithm version the client computed its prefixes with. */
619
- algoVersion: zod.z.number().int().positive(),
620
- /** 4-byte (8-hex-char) prefixes that hit the client's local index. */
621
- prefixes: zod.z.array(zod.z.string().regex(/^[0-9a-f]{8}$/)).min(1).max(200)
622
- }).describe("Blocklist confirm request");
623
- zod.z.object({
624
- /** Full 64-char SHA-256 hashes of blocked expressions, grouped by prefix. */
625
- fullHashes: zod.z.record(zod.z.string(), zod.z.array(zod.z.string()))
626
- }).describe("Blocklist confirm response");
627
- zod.z.void().describe("Blocklist version request");
628
- zod.z.object({
629
- /** Canonicalization algorithm version the artifacts + confirm are built with. */
630
- algoVersion: zod.z.number().int().positive(),
631
- snapshot: zod.z.object({
632
- token: zod.z.string(),
633
- url: zod.z.string().url(),
634
- prefixBytes: zod.z.number().int().positive(),
635
- count: zod.z.number().int().nonnegative()
636
- }),
637
- recent: zod.z.object({
638
- token: zod.z.string(),
639
- url: zod.z.string().url(),
640
- windowSeconds: zod.z.number().int().positive()
641
- })
642
- }).describe("Blocklist version response");
643
604
 
644
605
  // ../../node_modules/luxon/src/errors.js
645
606
  var LuxonError = class extends Error {
@@ -1313,17 +1274,17 @@ var PolyDateFormatter = class {
1313
1274
  constructor(dt, intl, opts) {
1314
1275
  this.opts = opts;
1315
1276
  this.originalZone = void 0;
1316
- let z56 = void 0;
1277
+ let z64 = void 0;
1317
1278
  if (this.opts.timeZone) {
1318
1279
  this.dt = dt;
1319
1280
  } else if (dt.zone.type === "fixed") {
1320
1281
  const gmtOffset = -1 * (dt.offset / 60);
1321
1282
  const offsetZ = gmtOffset >= 0 ? `Etc/GMT+${gmtOffset}` : `Etc/GMT${gmtOffset}`;
1322
1283
  if (dt.offset !== 0 && IANAZone.create(offsetZ).valid) {
1323
- z56 = offsetZ;
1284
+ z64 = offsetZ;
1324
1285
  this.dt = dt;
1325
1286
  } else {
1326
- z56 = "UTC";
1287
+ z64 = "UTC";
1327
1288
  this.dt = dt.offset === 0 ? dt : dt.setZone("UTC").plus({ minutes: dt.offset });
1328
1289
  this.originalZone = dt.zone;
1329
1290
  }
@@ -1331,14 +1292,14 @@ var PolyDateFormatter = class {
1331
1292
  this.dt = dt;
1332
1293
  } else if (dt.zone.type === "iana") {
1333
1294
  this.dt = dt;
1334
- z56 = dt.zone.name;
1295
+ z64 = dt.zone.name;
1335
1296
  } else {
1336
- z56 = "UTC";
1297
+ z64 = "UTC";
1337
1298
  this.dt = dt.setZone("UTC").plus({ minutes: dt.offset });
1338
1299
  this.originalZone = dt.zone;
1339
1300
  }
1340
1301
  const intlOpts = __spreadValues({}, this.opts);
1341
- intlOpts.timeZone = intlOpts.timeZone || z56;
1302
+ intlOpts.timeZone = intlOpts.timeZone || z64;
1342
1303
  this.dtf = getCachedDTF(intl, intlOpts);
1343
1304
  }
1344
1305
  format() {
@@ -7054,6 +7015,79 @@ function friendlyDateTime(dateTimeish) {
7054
7015
  );
7055
7016
  }
7056
7017
  }
7018
+ var MAX_ASSET_NOTE_LENGTH = 5e3;
7019
+ var assetNoteBodySchema = zod.z.string().trim().min(1, "Note is required").max(MAX_ASSET_NOTE_LENGTH, `Note must be at most ${MAX_ASSET_NOTE_LENGTH} characters`);
7020
+ var assetNoteTimelineAtSchema = zod.z.coerce.date().refine((value) => value.getTime() <= DateTime.now().toUTC().toMillis(), {
7021
+ message: "Timeline date cannot be in the future"
7022
+ });
7023
+ zod.z.object({
7024
+ assetId: zod.z.number().int().positive(),
7025
+ note: assetNoteBodySchema,
7026
+ timelineAt: assetNoteTimelineAtSchema.optional()
7027
+ });
7028
+ zod.z.object({
7029
+ noteId: zod.z.number().int().positive(),
7030
+ note: assetNoteBodySchema,
7031
+ timelineAt: assetNoteTimelineAtSchema.nullish()
7032
+ });
7033
+ zod.z.object({
7034
+ noteId: zod.z.number().int().positive()
7035
+ });
7036
+ var ASSET_TAGS = {
7037
+ ENFORCEMENT_EXHAUSTED: {
7038
+ label: "Enforcement Exhausted",
7039
+ description: "All available enforcement options have been pursued with the relevant providers. The asset remains active due to provider inaction.",
7040
+ colorScheme: "orange"
7041
+ }
7042
+ };
7043
+ var ASSET_TAG_KEYS = Object.keys(ASSET_TAGS);
7044
+ var assetTagKeySchema = zod.z.enum(ASSET_TAG_KEYS);
7045
+ zod.z.object({
7046
+ assetId: zod.z.number().int().positive()
7047
+ });
7048
+ zod.z.object({
7049
+ assetId: zod.z.number().int().positive(),
7050
+ tag: assetTagKeySchema
7051
+ });
7052
+ zod.z.object({
7053
+ slug: zod.z.string(),
7054
+ assetId: zod.z.number(),
7055
+ name: zod.z.string().optional(),
7056
+ description: zod.z.string().optional(),
7057
+ assetGroupId: zod.z.number().nullable().optional(),
7058
+ updatedByOrganizationId: zod.z.number().optional()
7059
+ });
7060
+ zod.z.object({
7061
+ content: zod.z.string().min(1, { message: "Content must be at least 3 character" }).max(1e3, { message: "Content must be less than 1000 characters" }),
7062
+ email: zod.z.string().email(),
7063
+ description: zod.z.string().optional().default("")
7064
+ });
7065
+ zod.z.object({
7066
+ /** Canonicalization algorithm version the client computed its prefixes with. */
7067
+ algoVersion: zod.z.number().int().positive(),
7068
+ /** 4-byte (8-hex-char) prefixes that hit the client's local index. */
7069
+ prefixes: zod.z.array(zod.z.string().regex(/^[0-9a-f]{8}$/)).min(1).max(200)
7070
+ }).describe("Blocklist confirm request");
7071
+ zod.z.object({
7072
+ /** Full 64-char SHA-256 hashes of blocked expressions, grouped by prefix. */
7073
+ fullHashes: zod.z.record(zod.z.string(), zod.z.array(zod.z.string()))
7074
+ }).describe("Blocklist confirm response");
7075
+ zod.z.void().describe("Blocklist version request");
7076
+ zod.z.object({
7077
+ /** Canonicalization algorithm version the artifacts + confirm are built with. */
7078
+ algoVersion: zod.z.number().int().positive(),
7079
+ snapshot: zod.z.object({
7080
+ token: zod.z.string(),
7081
+ url: zod.z.string().url(),
7082
+ prefixBytes: zod.z.number().int().positive(),
7083
+ count: zod.z.number().int().nonnegative()
7084
+ }),
7085
+ recent: zod.z.object({
7086
+ token: zod.z.string(),
7087
+ url: zod.z.string().url(),
7088
+ windowSeconds: zod.z.number().int().positive()
7089
+ })
7090
+ }).describe("Blocklist version response");
7057
7091
 
7058
7092
  // ../../internal/database/src/generated/prisma/enums.ts
7059
7093
  var BrandType = {
@@ -7174,7 +7208,9 @@ var AssetType = {
7174
7208
  FIVE_HUNDRED_PX: "FIVE_HUNDRED_PX",
7175
7209
  LUMA: "LUMA",
7176
7210
  SMARTMONEYMATCH: "SMARTMONEYMATCH",
7177
- APK_GOLD: "APK_GOLD"
7211
+ APK_GOLD: "APK_GOLD",
7212
+ GLASSDOOR: "GLASSDOOR",
7213
+ PUMP_FUN: "PUMP_FUN"
7178
7214
  };
7179
7215
  var LivenessStatus = {
7180
7216
  UNKNOWN: "UNKNOWN",
@@ -7335,8 +7371,23 @@ zod.z.object({
7335
7371
  watchStatus: zod.z.nativeEnum(WatchStatus).optional().describe("The watch status of the asset.")
7336
7372
  }).describe("Check asset response body");
7337
7373
  var assetListInputSchema = zod.z.object({
7338
- /** The type of asset to retrieve. */
7339
- type: zod.z.nativeEnum(AssetType).describe("Asset type"),
7374
+ /**
7375
+ * The type of asset to retrieve. Omitting the key means every asset type,
7376
+ * which lets a bulk consumer sweep the whole blocklist with one cursor
7377
+ * instead of looping all 94 members of `AssetType`.
7378
+ *
7379
+ * An explicit `null` is rejected with a 400 rather than treated as "all
7380
+ * types". Only omission opts into the full sweep, so a client that sends
7381
+ * `type: null` from an uninitialised variable gets a clear error instead of
7382
+ * silently pulling every blocked asset.
7383
+ *
7384
+ * Not `.nullable()`: besides accepting that null, it renders in the
7385
+ * generated MCP tool manifest as a nested `anyOf` containing `{"not": {}}`,
7386
+ * which buries the enum hint telling a model which values are legal.
7387
+ */
7388
+ type: zod.z.nativeEnum(AssetType).optional().describe(
7389
+ "Asset type to retrieve. Omit the field entirely to retrieve assets of every type in a single paginated sweep; an explicit null is rejected."
7390
+ ),
7340
7391
  /** Optional status filter for the assets; defaults to `BLOCKED`. */
7341
7392
  status: zod.z.nativeEnum(AssetStatus).optional().default(AssetStatus.BLOCKED).describe("Status of the assets to retrieve"),
7342
7393
  /**
@@ -7364,7 +7415,8 @@ var assetListInputSchema = zod.z.object({
7364
7415
  }).describe(
7365
7416
  `List asset request body
7366
7417
 
7367
- Defaults to getting all the updates in the last 1 day.
7418
+ With no \`startDate\`, this returns every matching asset regardless of age \u2014 there
7419
+ is no implicit one-day window. Pass \`startDate\` to get a delta instead.
7368
7420
 
7369
7421
  You can also choose a \`startDate\` and \`endDate\` for the range of asset updates, most
7370
7422
  timestamp formats should work, we use [Luxon](https://moment.github.io/luxon/#/parsing)
@@ -7473,6 +7525,8 @@ var ThreatDetectionSourceKey = /* @__PURE__ */ ((ThreatDetectionSourceKey2) => {
7473
7525
  ThreatDetectionSourceKey2["TELEGRAM_CHANNELS_SEARCH_VETRIC"] = "telegram_channels_search_vetric";
7474
7526
  ThreatDetectionSourceKey2["TELEGRAM_USER_SEARCH_VETRIC"] = "telegram_user_search_vetric";
7475
7527
  ThreatDetectionSourceKey2["FACEBOOK_PAGE_SEARCH_VETRIC"] = "facebook_page_search_vetric";
7528
+ ThreatDetectionSourceKey2["FACEBOOK_USER_SEARCH_VETRIC"] = "facebook_user_search_vetric";
7529
+ ThreatDetectionSourceKey2["FACEBOOK_POST_SEARCH_VETRIC"] = "facebook_post_search_vetric";
7476
7530
  ThreatDetectionSourceKey2["INSTAGRAM_ACCOUNT_SEARCH_VETRIC"] = "instagram_account_search_vetric";
7477
7531
  ThreatDetectionSourceKey2["TWITTER_SEARCH_VETRIC"] = "twitter_search_vetric";
7478
7532
  ThreatDetectionSourceKey2["LINKEDIN_PEOPLE_SEARCH_VETRIC"] = "linkedin_people_search_vetric";
@@ -7512,14 +7566,17 @@ var ThreatDetectionSourceKey = /* @__PURE__ */ ((ThreatDetectionSourceKey2) => {
7512
7566
  ThreatDetectionSourceKey2["GROK_USER_SEARCH"] = "grok_user_search";
7513
7567
  ThreatDetectionSourceKey2["GOOGLE_LENS_IMAGE_SEARCH"] = "google_lens_image_search";
7514
7568
  ThreatDetectionSourceKey2["YANDEX_SEARCH"] = "yandex_search";
7569
+ ThreatDetectionSourceKey2["YANDEX_IMAGE_SEARCH"] = "yandex_image_search";
7515
7570
  ThreatDetectionSourceKey2["LINKEDIN_EMPLOYEE_DETECTION"] = "linkedin_employee_detection";
7516
7571
  ThreatDetectionSourceKey2["LINKEDIN_POST_SEARCH"] = "linkedin_post_search";
7517
7572
  ThreatDetectionSourceKey2["LINKEDIN_COMPANY_SEARCH"] = "linkedin_company_search";
7518
7573
  ThreatDetectionSourceKey2["BING_ADS_SEARCH"] = "bing_ads_search";
7519
7574
  ThreatDetectionSourceKey2["TIK_TOK_ADS_SEARCH"] = "tik_tok_ads_search";
7575
+ ThreatDetectionSourceKey2["ADLIBRARY_ADS_SEARCH"] = "adlibrary_ads_search";
7520
7576
  ThreatDetectionSourceKey2["DNSDB"] = "dnsdb";
7521
7577
  ThreatDetectionSourceKey2["DAILY_MOTION_SEARCH"] = "daily_motion_search";
7522
7578
  ThreatDetectionSourceKey2["WATCHLIST"] = "watchlist";
7579
+ ThreatDetectionSourceKey2["GITHUB_SEARCH"] = "github_search";
7523
7580
  return ThreatDetectionSourceKey2;
7524
7581
  })(ThreatDetectionSourceKey || {});
7525
7582
  var ThreatDetectionScope = /* @__PURE__ */ ((ThreatDetectionScope2) => {
@@ -7545,6 +7602,7 @@ var AssetScanEnrichmentType = /* @__PURE__ */ ((AssetScanEnrichmentType2) => {
7545
7602
  AssetScanEnrichmentType2["DNS"] = "dns";
7546
7603
  AssetScanEnrichmentType2["TLS"] = "tls";
7547
7604
  AssetScanEnrichmentType2["TCP"] = "tcp";
7605
+ AssetScanEnrichmentType2["HOSTNAME_FIRST_SEEN"] = "hostname_first_seen";
7548
7606
  AssetScanEnrichmentType2["TWITTER_POST"] = "post";
7549
7607
  AssetScanEnrichmentType2["TWITTER_PROFILE"] = "profile";
7550
7608
  AssetScanEnrichmentType2["TWITTER_FOLLOWERS"] = "twitter_followers";
@@ -7570,12 +7628,17 @@ var AssetScanEnrichmentType = /* @__PURE__ */ ((AssetScanEnrichmentType2) => {
7570
7628
  AssetScanEnrichmentType2["VIMEO_PROFILE"] = "vimeo_profile";
7571
7629
  AssetScanEnrichmentType2["STACKBLITZ_PAGE"] = "stackblitz_page";
7572
7630
  AssetScanEnrichmentType2["LEETCODE_PAGE"] = "leetcode_page";
7631
+ AssetScanEnrichmentType2["TUMBLR_BLOG"] = "tumblr_blog";
7632
+ AssetScanEnrichmentType2["TUMBLR_POST"] = "tumblr_post";
7633
+ AssetScanEnrichmentType2["TUMBLR_COMMUNITY"] = "tumblr_community";
7573
7634
  AssetScanEnrichmentType2["NPM_PACKAGE"] = "npm_package";
7574
7635
  AssetScanEnrichmentType2["PYPI_PACKAGE"] = "pypi_package";
7575
7636
  AssetScanEnrichmentType2["RUST_PACKAGE"] = "rust_package";
7576
7637
  AssetScanEnrichmentType2["LINKEDIN_PROFILE"] = "linkedin_profile";
7638
+ AssetScanEnrichmentType2["PUMP_FUN_TOKEN"] = "pump_fun_token";
7577
7639
  AssetScanEnrichmentType2["META_AD"] = "meta_ad";
7578
7640
  AssetScanEnrichmentType2["GOOGLE_AD"] = "google_ad";
7641
+ AssetScanEnrichmentType2["ADLIBRARY_AD"] = "adlibrary_ad";
7579
7642
  AssetScanEnrichmentType2["CONTRACT_DEPLOYER"] = "contract_deployer";
7580
7643
  return AssetScanEnrichmentType2;
7581
7644
  })(AssetScanEnrichmentType || {});
@@ -7587,6 +7650,8 @@ var AssetScanEnrichmentSource = /* @__PURE__ */ ((AssetScanEnrichmentSource2) =>
7587
7650
  AssetScanEnrichmentSource2["NETWORK"] = "node_js_network";
7588
7651
  AssetScanEnrichmentSource2["EXTENSION"] = "extension";
7589
7652
  AssetScanEnrichmentSource2["PLAYWRIGHT"] = "playwright";
7653
+ AssetScanEnrichmentSource2["CHAINPATROL_BROWSER"] = "chainpatrol_browser";
7654
+ AssetScanEnrichmentSource2["STEEL_BROWSER"] = "steel_browser";
7590
7655
  AssetScanEnrichmentSource2["X_API"] = "x_api";
7591
7656
  AssetScanEnrichmentSource2["SOCIALDATA_API"] = "socialdata_api";
7592
7657
  AssetScanEnrichmentSource2["NEYNAR_API"] = "neynar_api";
@@ -7605,12 +7670,16 @@ var AssetScanEnrichmentSource = /* @__PURE__ */ ((AssetScanEnrichmentSource2) =>
7605
7670
  AssetScanEnrichmentSource2["VIMEO_API"] = "vimeo_api";
7606
7671
  AssetScanEnrichmentSource2["STACKBLITZ_API"] = "stackblitz_api";
7607
7672
  AssetScanEnrichmentSource2["LEETCODE_API"] = "leetcode_api";
7673
+ AssetScanEnrichmentSource2["TUMBLR_API"] = "tumblr_api";
7608
7674
  AssetScanEnrichmentSource2["NPM_REGISTRY_API"] = "npm_registry_api";
7609
7675
  AssetScanEnrichmentSource2["PYPI_REGISTRY_API"] = "pypi_registry_api";
7610
7676
  AssetScanEnrichmentSource2["CRATES_IO_API"] = "crates_io_api";
7611
7677
  AssetScanEnrichmentSource2["APIFY_LINKEDIN_API"] = "apify_linkedin_api";
7678
+ AssetScanEnrichmentSource2["PUMP_FUN_API"] = "pump_fun_api";
7612
7679
  AssetScanEnrichmentSource2["META_ADS_LIBRARY"] = "meta_ads_library";
7680
+ AssetScanEnrichmentSource2["STEEL_META_ADS_LIBRARY"] = "steel_meta_ads_library";
7613
7681
  AssetScanEnrichmentSource2["GOOGLE_ADS_TRANSPARENCY_CENTER"] = "google_ads_transparency_center";
7682
+ AssetScanEnrichmentSource2["ADLIBRARY"] = "adlibrary";
7614
7683
  AssetScanEnrichmentSource2["ETHERSCAN_API"] = "etherscan_api";
7615
7684
  return AssetScanEnrichmentSource2;
7616
7685
  })(AssetScanEnrichmentSource || {});
@@ -7625,6 +7694,7 @@ var ASSET_SCAN_ENRICHMENT_TYPE_LABELS = {
7625
7694
  ["dns" /* DNS */]: "DNS Lookup",
7626
7695
  ["tls" /* TLS */]: "TLS Connection Info",
7627
7696
  ["tcp" /* TCP */]: "TCP Connection Info",
7697
+ ["hostname_first_seen" /* HOSTNAME_FIRST_SEEN */]: "Hostname First Seen",
7628
7698
  // Farcaster
7629
7699
  ["cast" /* FARCASTER_CAST */]: "Farcaster Cast",
7630
7700
  ["farcaster_profile" /* FARCASTER_PROFILE */]: "Farcaster Profile",
@@ -7663,6 +7733,10 @@ var ASSET_SCAN_ENRICHMENT_TYPE_LABELS = {
7663
7733
  ["stackblitz_page" /* STACKBLITZ_PAGE */]: "Stackblitz Page",
7664
7734
  // Leetcode
7665
7735
  ["leetcode_page" /* LEETCODE_PAGE */]: "Leetcode Page",
7736
+ // Tumblr
7737
+ ["tumblr_blog" /* TUMBLR_BLOG */]: "Tumblr Blog",
7738
+ ["tumblr_post" /* TUMBLR_POST */]: "Tumblr Post",
7739
+ ["tumblr_community" /* TUMBLR_COMMUNITY */]: "Tumblr Community",
7666
7740
  // NPM
7667
7741
  ["npm_package" /* NPM_PACKAGE */]: "NPM Package",
7668
7742
  // PyPI
@@ -7671,10 +7745,14 @@ var ASSET_SCAN_ENRICHMENT_TYPE_LABELS = {
7671
7745
  ["rust_package" /* RUST_PACKAGE */]: "Rust Package",
7672
7746
  // LinkedIn
7673
7747
  ["linkedin_profile" /* LINKEDIN_PROFILE */]: "LinkedIn Profile",
7748
+ // Pump.fun
7749
+ ["pump_fun_token" /* PUMP_FUN_TOKEN */]: "Pump.fun Token",
7674
7750
  // Meta Ads
7675
7751
  ["meta_ad" /* META_AD */]: "Meta Ad",
7676
7752
  // Google Ads
7677
7753
  ["google_ad" /* GOOGLE_AD */]: "Google Ad",
7754
+ // Cross-platform ad intelligence
7755
+ ["adlibrary_ad" /* ADLIBRARY_AD */]: "AdLibrary Ad",
7678
7756
  // Crypto / Onchain
7679
7757
  ["contract_deployer" /* CONTRACT_DEPLOYER */]: "Contract Deployer"
7680
7758
  };
@@ -7687,6 +7765,8 @@ var ASSET_SCAN_ENRICHMENT_SOURCE_LABELS = {
7687
7765
  ["node_js_network" /* NETWORK */]: "Network",
7688
7766
  ["extension" /* EXTENSION */]: "Browser Extension",
7689
7767
  ["playwright" /* PLAYWRIGHT */]: "Playwright",
7768
+ ["chainpatrol_browser" /* CHAINPATROL_BROWSER */]: "ChainPatrol Browser",
7769
+ ["steel_browser" /* STEEL_BROWSER */]: "Steel Browser",
7690
7770
  // Twitter
7691
7771
  ["x_api" /* X_API */]: "X API",
7692
7772
  ["socialdata_api" /* SOCIALDATA_API */]: "SocialData API",
@@ -7721,6 +7801,8 @@ var ASSET_SCAN_ENRICHMENT_SOURCE_LABELS = {
7721
7801
  ["stackblitz_api" /* STACKBLITZ_API */]: "Stackblitz API",
7722
7802
  // Leetcode
7723
7803
  ["leetcode_api" /* LEETCODE_API */]: "Leetcode API",
7804
+ // Tumblr
7805
+ ["tumblr_api" /* TUMBLR_API */]: "Tumblr API",
7724
7806
  // NPM
7725
7807
  ["npm_registry_api" /* NPM_REGISTRY_API */]: "NPM Registry API",
7726
7808
  // PyPI
@@ -7729,10 +7811,15 @@ var ASSET_SCAN_ENRICHMENT_SOURCE_LABELS = {
7729
7811
  ["crates_io_api" /* CRATES_IO_API */]: "Crates.io API",
7730
7812
  // LinkedIn
7731
7813
  ["apify_linkedin_api" /* APIFY_LINKEDIN_API */]: "Apify LinkedIn API",
7814
+ // Pump.fun
7815
+ ["pump_fun_api" /* PUMP_FUN_API */]: "Pump.fun API",
7732
7816
  // Meta Ads
7733
7817
  ["meta_ads_library" /* META_ADS_LIBRARY */]: "Meta Ads Library",
7818
+ ["steel_meta_ads_library" /* STEEL_META_ADS_LIBRARY */]: "Steel Meta Ads Library",
7734
7819
  // Google Ads
7735
7820
  ["google_ads_transparency_center" /* GOOGLE_ADS_TRANSPARENCY_CENTER */]: "Google Ads Transparency Center",
7821
+ // Cross-platform ad intelligence
7822
+ ["adlibrary" /* ADLIBRARY */]: "AdLibrary",
7736
7823
  // Crypto / Onchain
7737
7824
  ["etherscan_api" /* ETHERSCAN_API */]: "Etherscan"
7738
7825
  };
@@ -7740,7 +7827,8 @@ var ASSET_SCAN_ENRICHMENT_SOURCE_TO_TYPES = {
7740
7827
  // URL-related sources
7741
7828
  ["urlscan" /* URLSCAN */]: [
7742
7829
  "browser_capture" /* BROWSER_CAPTURE */,
7743
- "geolocation_and_ip" /* GEOLOCATION_AND_IP */
7830
+ "geolocation_and_ip" /* GEOLOCATION_AND_IP */,
7831
+ "hostname_first_seen" /* HOSTNAME_FIRST_SEEN */
7744
7832
  ],
7745
7833
  ["whois" /* WHOIS */]: ["ownership_and_registration" /* OWNERSHIP_AND_REGISTRATION */],
7746
7834
  ["rdap" /* RDAP */]: ["ownership_and_registration" /* OWNERSHIP_AND_REGISTRATION */],
@@ -7765,6 +7853,12 @@ var ASSET_SCAN_ENRICHMENT_SOURCE_TO_TYPES = {
7765
7853
  "bilibili_profile" /* BILIBILI_PROFILE */,
7766
7854
  "telegram_profile" /* TELEGRAM_PROFILE */
7767
7855
  ],
7856
+ // Only the generic page capture: the in-house browser does not (yet) run the
7857
+ // platform-specific scrapes PLAYWRIGHT does above.
7858
+ ["chainpatrol_browser" /* CHAINPATROL_BROWSER */]: [
7859
+ "browser_capture" /* BROWSER_CAPTURE */
7860
+ ],
7861
+ ["steel_browser" /* STEEL_BROWSER */]: ["browser_capture" /* BROWSER_CAPTURE */],
7768
7862
  // Twitter-related sources
7769
7863
  ["x_api" /* X_API */]: [
7770
7864
  "post" /* TWITTER_POST */,
@@ -7824,6 +7918,12 @@ var ASSET_SCAN_ENRICHMENT_SOURCE_TO_TYPES = {
7824
7918
  ["stackblitz_api" /* STACKBLITZ_API */]: ["stackblitz_page" /* STACKBLITZ_PAGE */],
7825
7919
  // Leetcode-related sources
7826
7920
  ["leetcode_api" /* LEETCODE_API */]: ["leetcode_page" /* LEETCODE_PAGE */],
7921
+ // Tumblr-related sources
7922
+ ["tumblr_api" /* TUMBLR_API */]: [
7923
+ "tumblr_blog" /* TUMBLR_BLOG */,
7924
+ "tumblr_post" /* TUMBLR_POST */,
7925
+ "tumblr_community" /* TUMBLR_COMMUNITY */
7926
+ ],
7827
7927
  // NPM-related sources
7828
7928
  ["npm_registry_api" /* NPM_REGISTRY_API */]: ["npm_package" /* NPM_PACKAGE */],
7829
7929
  // PyPI-related sources
@@ -7834,12 +7934,17 @@ var ASSET_SCAN_ENRICHMENT_SOURCE_TO_TYPES = {
7834
7934
  ["apify_linkedin_api" /* APIFY_LINKEDIN_API */]: [
7835
7935
  "linkedin_profile" /* LINKEDIN_PROFILE */
7836
7936
  ],
7937
+ // Pump.fun
7938
+ ["pump_fun_api" /* PUMP_FUN_API */]: ["pump_fun_token" /* PUMP_FUN_TOKEN */],
7837
7939
  // Meta Ads-related sources
7838
7940
  ["meta_ads_library" /* META_ADS_LIBRARY */]: ["meta_ad" /* META_AD */],
7941
+ ["steel_meta_ads_library" /* STEEL_META_ADS_LIBRARY */]: ["meta_ad" /* META_AD */],
7839
7942
  // Google Ads-related sources
7840
7943
  ["google_ads_transparency_center" /* GOOGLE_ADS_TRANSPARENCY_CENTER */]: [
7841
7944
  "google_ad" /* GOOGLE_AD */
7842
7945
  ],
7946
+ // Cross-platform ad intelligence sources
7947
+ ["adlibrary" /* ADLIBRARY */]: ["adlibrary_ad" /* ADLIBRARY_AD */],
7843
7948
  // Crypto / Onchain sources
7844
7949
  ["etherscan_api" /* ETHERSCAN_API */]: ["contract_deployer" /* CONTRACT_DEPLOYER */]
7845
7950
  };
@@ -8040,6 +8145,7 @@ function isDefinedAndNotNull(value) {
8040
8145
  // ../../internal/utils/src/promise.ts
8041
8146
  var promise_exports = {};
8042
8147
  __export(promise_exports, {
8148
+ allSettledWithConcurrency: () => allSettledWithConcurrency,
8043
8149
  isPromiseSettledResultFulfilled: () => isPromiseSettledResultFulfilled,
8044
8150
  isPromiseSettledResultRejected: () => isPromiseSettledResultRejected
8045
8151
  });
@@ -8049,6 +8155,27 @@ function isPromiseSettledResultFulfilled(result) {
8049
8155
  function isPromiseSettledResultRejected(result) {
8050
8156
  return result.status === "rejected";
8051
8157
  }
8158
+ function allSettledWithConcurrency(items, limit, fn5) {
8159
+ return __async(this, null, function* () {
8160
+ const results = new Array(items.length);
8161
+ let next = 0;
8162
+ const worker = () => __async(null, null, function* () {
8163
+ for (; ; ) {
8164
+ const index = next;
8165
+ next += 1;
8166
+ if (index >= items.length) return;
8167
+ try {
8168
+ results[index] = { status: "fulfilled", value: yield fn5(items[index], index) };
8169
+ } catch (reason) {
8170
+ results[index] = { status: "rejected", reason };
8171
+ }
8172
+ }
8173
+ });
8174
+ const workers = Math.max(1, Math.min(Math.floor(limit) || 1, items.length));
8175
+ yield Promise.all(Array.from({ length: workers }, worker));
8176
+ return results;
8177
+ });
8178
+ }
8052
8179
 
8053
8180
  // ../../internal/utils/src/url.ts
8054
8181
  var url_exports = {};
@@ -10803,6 +10930,7 @@ function buildSafePreviewUrl({
10803
10930
  var parse_exports = {};
10804
10931
  __export(parse_exports, {
10805
10932
  parseTerms: () => parseTerms,
10933
+ repairTermsString: () => repairTermsString,
10806
10934
  stringifyTerms: () => stringifyTerms
10807
10935
  });
10808
10936
  function parseTerms(terms, {
@@ -10829,6 +10957,31 @@ function parseTerms(terms, {
10829
10957
  function stringifyTerms(parsedTerms) {
10830
10958
  return parsedTerms.map((term) => term.type === "exact" ? `*${term.value}*` : term.value).join(", ");
10831
10959
  }
10960
+ function repairTermsString(terms) {
10961
+ if (!terms) return terms;
10962
+ const entries = terms.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
10963
+ if (entries.length === 0) return terms;
10964
+ const first = entries[0];
10965
+ const last = entries[entries.length - 1];
10966
+ const isWholeListWrap = entries.length > 1 && first.startsWith("*") && !first.endsWith("*") && last.endsWith("*") && !last.startsWith("*");
10967
+ const hasOneSidedAsterisk = entries.some(
10968
+ (entry) => entry.startsWith("*") !== entry.endsWith("*")
10969
+ );
10970
+ if (!isWholeListWrap && !hasOneSidedAsterisk) return terms;
10971
+ const seen = /* @__PURE__ */ new Set();
10972
+ const repaired = [];
10973
+ for (const entry of entries) {
10974
+ const inner = entry.replace(/^\*+|\*+$/g, "").trim();
10975
+ if (inner.length === 0) continue;
10976
+ const isExact = isWholeListWrap || entry.startsWith("*") && entry.endsWith("*") && entry.length > 2;
10977
+ const formatted = isExact ? `*${inner}*` : inner;
10978
+ const key = formatted.toLowerCase();
10979
+ if (seen.has(key)) continue;
10980
+ seen.add(key);
10981
+ repaired.push(formatted);
10982
+ }
10983
+ return repaired.join(", ");
10984
+ }
10832
10985
 
10833
10986
  // ../../internal/utils/src/brand-pattern.ts
10834
10987
  var brand_pattern_exports = {};
@@ -11474,6 +11627,44 @@ zod.z.object({
11474
11627
  })
11475
11628
  )
11476
11629
  });
11630
+ var DATE_ONLY_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
11631
+ var utcDateSchema = (endOfDay) => zod.z.preprocess((value) => {
11632
+ if (typeof value !== "string") {
11633
+ return value;
11634
+ }
11635
+ const parsed = DateTime.fromISO(value, { zone: "utc" });
11636
+ if (!parsed.isValid) {
11637
+ return new Date(Number.NaN);
11638
+ }
11639
+ return endOfDay && DATE_ONLY_PATTERN.test(value) ? parsed.endOf("day").toJSDate() : parsed.toJSDate();
11640
+ }, zod.z.coerce.date());
11641
+
11642
+ // ../../internal/validation/src/public/metrics/false-positive-rate.ts
11643
+ zod.z.object({
11644
+ slug: zod.z.string().min(1).describe("Organization slug"),
11645
+ startDate: utcDateSchema(false).optional().describe(
11646
+ "Only include assets blocked on or after this date. A date-only value (YYYY-MM-DD) starts at midnight UTC"
11647
+ ),
11648
+ endDate: utcDateSchema(true).optional().describe(
11649
+ "Only include assets blocked 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"
11650
+ ),
11651
+ brandIds: zod.z.array(zod.z.number().int().positive()).optional().describe("Only include assets belonging to these brands"),
11652
+ countryCodes: zod.z.array(zod.z.string().length(2)).optional().describe("Only include assets scanned from these ISO 3166-1 alpha-2 countries")
11653
+ });
11654
+ zod.z.object({
11655
+ byAssetType: zod.z.array(
11656
+ zod.z.object({
11657
+ assetType: zod.z.nativeEnum(AssetType).describe("Asset type that was blocked"),
11658
+ blocked: zod.z.number().describe("Assets of this type blocked within the date range"),
11659
+ falsePositives: zod.z.number().describe("Of those, how many are no longer blocked today"),
11660
+ falsePositiveRate: zod.z.number().nullable().describe(
11661
+ "falsePositives / blocked, 0-1. Null only when nothing was blocked, which cannot happen for a returned row"
11662
+ )
11663
+ })
11664
+ ).describe(
11665
+ "False positive rate, one entry per asset type blocked in the range, descending by number blocked. Asset types with no false positives are included with a rate of 0; asset types with no blocks at all in the range are omitted, since they have no rate to report. The denominator counts block events, not distinct assets, so an asset blocked twice in the range counts twice. Whether a block still stands is read as of now while the range bounds the block itself, so a recent range reads low. An asset's blocked status is global, so a block another organization's report caused to be reversed is counted here too"
11666
+ )
11667
+ });
11477
11668
  zod.z.object({
11478
11669
  slug: zod.z.string().min(1),
11479
11670
  startDate: zod.z.date(),
@@ -11488,8 +11679,8 @@ zod.z.object({
11488
11679
  endDate: zod.z.date()
11489
11680
  })
11490
11681
  });
11491
- var DATE_ONLY_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
11492
- var utcDateSchema = (endOfDay) => zod.z.preprocess((value) => {
11682
+ var DATE_ONLY_PATTERN2 = /^\d{4}-\d{2}-\d{2}$/;
11683
+ var utcDateSchema2 = (endOfDay) => zod.z.preprocess((value) => {
11493
11684
  if (typeof value !== "string") {
11494
11685
  return value;
11495
11686
  }
@@ -11497,7 +11688,7 @@ var utcDateSchema = (endOfDay) => zod.z.preprocess((value) => {
11497
11688
  if (!parsed.isValid) {
11498
11689
  return new Date(Number.NaN);
11499
11690
  }
11500
- return endOfDay && DATE_ONLY_PATTERN.test(value) ? parsed.endOf("day").toJSDate() : parsed.toJSDate();
11691
+ return endOfDay && DATE_ONLY_PATTERN2.test(value) ? parsed.endOf("day").toJSDate() : parsed.toJSDate();
11501
11692
  }, zod.z.coerce.date());
11502
11693
  var funnelCountsSchema = zod.z.object({
11503
11694
  blocked: zod.z.number().int().nonnegative().describe(
@@ -11506,10 +11697,10 @@ var funnelCountsSchema = zod.z.object({
11506
11697
  });
11507
11698
  zod.z.object({
11508
11699
  slug: zod.z.string().min(1).describe("Organization slug"),
11509
- startDate: utcDateSchema(false).describe(
11700
+ startDate: utcDateSchema2(false).describe(
11510
11701
  "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
11702
  ),
11512
- endDate: utcDateSchema(true).describe(
11703
+ endDate: utcDateSchema2(true).describe(
11513
11704
  "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
11705
  ),
11515
11706
  brandIds: zod.z.array(zod.z.number().int().positive()).optional().describe("Only include assets belonging to these brands")
@@ -11563,23 +11754,43 @@ zod.z.object({
11563
11754
  })
11564
11755
  )
11565
11756
  });
11566
- var DATE_ONLY_PATTERN2 = /^\d{4}-\d{2}-\d{2}$/;
11567
- var utcDateSchema2 = (endOfDay) => zod.z.preprocess((value) => {
11568
- if (typeof value !== "string") {
11569
- return value;
11570
- }
11571
- const parsed = DateTime.fromISO(value, { zone: "utc" });
11572
- if (!parsed.isValid) {
11573
- return new Date(Number.NaN);
11574
- }
11575
- return endOfDay && DATE_ONLY_PATTERN2.test(value) ? parsed.endOf("day").toJSDate() : parsed.toJSDate();
11576
- }, zod.z.coerce.date());
11577
11757
  zod.z.object({
11578
11758
  slug: zod.z.string().min(1).describe("Organization slug"),
11579
- startDate: utcDateSchema2(false).optional().describe(
11759
+ startDate: utcDateSchema(false).optional().describe(
11760
+ "Only include takedowns first submitted to a provider on or after this date. A date-only value (YYYY-MM-DD) starts at midnight UTC"
11761
+ ),
11762
+ endDate: utcDateSchema(true).optional().describe(
11763
+ "Only include takedowns first submitted to a provider 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"
11764
+ ),
11765
+ blockLabel: zod.z.string().optional().describe(
11766
+ 'Only include assets blocked with this review label, e.g. "Brand Impersonation", "Employee Impersonation" or "Targeting Org Users"'
11767
+ ),
11768
+ brandType: zod.z.nativeEnum(BrandType).optional().describe("Only include assets belonging to brands of this type"),
11769
+ countryCodes: zod.z.array(zod.z.string().length(2)).optional().describe("Only include assets scanned from these ISO 3166-1 alpha-2 countries"),
11770
+ brandIds: zod.z.array(zod.z.number().int().positive()).optional().describe("Only include assets belonging to these brands")
11771
+ });
11772
+ zod.z.object({
11773
+ byAssetType: zod.z.array(
11774
+ zod.z.object({
11775
+ assetType: zod.z.nativeEnum(AssetType).describe("Asset type the takedowns were filed against"),
11776
+ submitted: zod.z.number().describe("Takedowns whose first submission to a provider fell in the range"),
11777
+ completed: zod.z.number().describe("Of those, how many ended in a takedown"),
11778
+ stillOpen: zod.z.number().describe("Of those, how many have not yet reached an outcome"),
11779
+ successRate: zod.z.number().describe("completed / submitted, 0-1. Still-open takedowns count against it"),
11780
+ resolvedSuccessRate: zod.z.number().nullable().describe(
11781
+ "completed / (submitted - stillOpen), 0-1, or null when nothing has resolved yet. Higher than successRate whenever work is still outstanding"
11782
+ )
11783
+ })
11784
+ ).describe(
11785
+ "Takedown success rate, one entry per asset type, descending by number submitted"
11786
+ )
11787
+ });
11788
+ zod.z.object({
11789
+ slug: zod.z.string().min(1).describe("Organization slug"),
11790
+ startDate: utcDateSchema(false).optional().describe(
11580
11791
  "Only include takedowns completed on or after this date. A date-only value (YYYY-MM-DD) starts at midnight UTC"
11581
11792
  ),
11582
- endDate: utcDateSchema2(true).optional().describe(
11793
+ endDate: utcDateSchema(true).optional().describe(
11583
11794
  "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"
11584
11795
  ),
11585
11796
  blockLabel: zod.z.string().optional().describe(
@@ -11602,6 +11813,46 @@ zod.z.object({
11602
11813
  "Median time from takedown start to completion, one entry per asset type, ascending by median"
11603
11814
  )
11604
11815
  });
11816
+ var TakedownProviderRoleSchema = zod.z.enum([
11817
+ "HOSTING_PROVIDER",
11818
+ "DOMAIN_REGISTRAR",
11819
+ "TLD_REGISTRAR"
11820
+ ]);
11821
+ zod.z.object({
11822
+ slug: zod.z.string().min(1).describe("Organization slug"),
11823
+ startDate: utcDateSchema(false).optional().describe(
11824
+ "Only include takedowns completed on or after this date. A date-only value (YYYY-MM-DD) starts at midnight UTC"
11825
+ ),
11826
+ endDate: utcDateSchema(true).optional().describe(
11827
+ "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"
11828
+ ),
11829
+ roles: zod.z.array(TakedownProviderRoleSchema).optional().describe(
11830
+ "Only break down these provider roles. Omit for every role. A takedown filed against both a host and a registrar is counted once under each"
11831
+ ),
11832
+ blockLabel: zod.z.string().optional().describe(
11833
+ 'Only include assets blocked with this review label, e.g. "Brand Impersonation", "Employee Impersonation" or "Targeting Org Users"'
11834
+ ),
11835
+ brandType: zod.z.nativeEnum(BrandType).optional().describe("Only include assets belonging to brands of this type"),
11836
+ countryCodes: zod.z.array(zod.z.string().length(2)).optional().describe("Only include assets scanned from these ISO 3166-1 alpha-2 countries"),
11837
+ brandIds: zod.z.array(zod.z.number().int().positive()).optional().describe("Only include assets belonging to these brands")
11838
+ });
11839
+ zod.z.object({
11840
+ byProvider: zod.z.array(
11841
+ zod.z.object({
11842
+ providerId: zod.z.number().describe("Takedown provider id"),
11843
+ providerName: zod.z.string().describe("Takedown provider name"),
11844
+ role: TakedownProviderRoleSchema.describe(
11845
+ "Which provider slot of the takedown this median is computed over"
11846
+ ),
11847
+ medianTakedownMinutes: zod.z.number(),
11848
+ medianTakedownHours: zod.z.number(),
11849
+ medianTakedownDays: zod.z.number(),
11850
+ count: zod.z.number().describe("Number of completed takedowns behind the median")
11851
+ })
11852
+ ).describe(
11853
+ "Median time from takedown start to completion, one entry per provider and role, ascending by median"
11854
+ )
11855
+ });
11605
11856
  zod.z.object({
11606
11857
  slug: zod.z.string().min(1).describe("Organization slug"),
11607
11858
  months: zod.z.number().int().min(2).max(36).default(12).describe("Size of the trailing window in whole months, including the current month"),
@@ -11857,6 +12108,13 @@ zod.z.object({
11857
12108
  brands: zod.z.array(brandItemSchema).describe("List of brands")
11858
12109
  }).describe("Successful operation");
11859
12110
  var FILTERABLE_SUBSCRIPTION_STATUSES = [
12111
+ SubscriptionStatus.PROSPECT,
12112
+ SubscriptionStatus.POC,
12113
+ SubscriptionStatus.ACTIVE,
12114
+ SubscriptionStatus.INTEGRATION,
12115
+ SubscriptionStatus.INACTIVE
12116
+ ];
12117
+ [
11860
12118
  SubscriptionStatus.PROSPECT,
11861
12119
  SubscriptionStatus.POC,
11862
12120
  SubscriptionStatus.ACTIVE,
@@ -11891,7 +12149,9 @@ var userOrgsPendingServiceApprovalFilterSchema = zod.z.object({
11891
12149
  }).optional();
11892
12150
  zod.z.object({
11893
12151
  query: zod.z.string().default(""),
11894
- subscriptionStatus: zod.z.array(UserOrgsSubscriptionStatusSchema).min(1).optional(),
12152
+ subscriptionStatus: zod.z.array(UserOrgsSubscriptionStatusSchema).min(1).optional().describe(
12153
+ "Statuses to include. Defaults to the live set (PROSPECT/POC/ACTIVE/INTEGRATION); pass INACTIVE explicitly to see churned organizations."
12154
+ ),
11895
12155
  services: userOrgsServicesFilterObjectSchema.optional(),
11896
12156
  obligatoryAdminApproval: userOrgsObligatoryAdminApprovalFilterSchema,
11897
12157
  pendingServiceApproval: userOrgsPendingServiceApprovalFilterSchema
@@ -12072,7 +12332,7 @@ zod.z.object({
12072
12332
  "Shortcut for 'every org the caller is authorized to read'. Reuses the same filter logic as `/user/orgs`: org-scoped API keys are rejected (they're pinned to one org \u2014 use the default form); user API keys / Bearer sessions resolve to the user's memberships (or every active org for staff). Combine with `subscriptionStatus` and `services` to narrow (e.g. only paying customers with takedowns enabled). The resolved org set is still capped at " + String(ORGANIZATION_METRICS_MAX_SLUGS) + " and a 413 is returned if exceeded. Mutually exclusive with `organizationSlug`, `slugs`, and `brandSlug`."
12073
12333
  ),
12074
12334
  subscriptionStatus: zod.z.array(UserOrgsSubscriptionStatusSchema).min(1).optional().describe(
12075
- "Only meaningful with `allMyOrgs: true`. Defaults to the same set `/user/orgs` uses (ACTIVE/POC/PROSPECT/INTEGRATION \u2014 INACTIVE is always excluded)."
12335
+ "Only meaningful with `allMyOrgs: true`. Defaults to the same set `/user/orgs` uses (ACTIVE/POC/PROSPECT/INTEGRATION); pass INACTIVE explicitly to include churned organizations."
12076
12336
  ),
12077
12337
  services: organizationMetricsServicesFilterSchema.describe(
12078
12338
  "Only meaningful with `allMyOrgs: true`. Same shape as `/user/orgs`'s `services` filter \u2014 every service accepts `{ active }`, and **only `takedowns` additionally accepts `automated`** (the one service where manual-vs-automated changes real platform behavior). E.g. `{ takedowns: { active: true, automated: false } }` for 'orgs with takedowns enabled but automation off'."
@@ -12199,8 +12459,10 @@ var reportCreateInputSchema = zod.z.object({
12199
12459
  ).optional().refine((value) => !value || !isPhoneNumberMissingCountryCode(value), {
12200
12460
  message: PHONE_COUNTRY_CODE_ERROR_MESSAGE
12201
12461
  }),
12202
- /** Optional list of URLs for images to be attached to the report. */
12203
- attachmentUrls: zod.z.array(zod.z.string().url()).optional().describe("URLs of images to attach to the report"),
12462
+ /** Optional list of URLs for files to be attached to the report as evidence. */
12463
+ attachmentUrls: zod.z.array(zod.z.string().url()).optional().describe(
12464
+ "URLs of files to attach to the report as evidence. Any file type, not only images: .eml/.msg messages, PDFs, and documents are all supported. Upload a file to POST /attachment/upload to get a URL, or pass a publicly reachable URL you host yourself."
12465
+ ),
12204
12466
  /** Optional link to the external submission (e.g. Telegram message link) */
12205
12467
  externalSubmissionLink: zod.z.string().url().optional().describe("Link to the external submission (e.g. Telegram message link)"),
12206
12468
  /** Optional user agent string from the reporter's browser */
@@ -12368,6 +12630,38 @@ for parsing the dates.`
12368
12630
  path: ["startDate"]
12369
12631
  }
12370
12632
  );
12633
+ var TakedownProofType = {
12634
+ ProviderEmail: "provider-email"
12635
+ };
12636
+ var takedownProofEmailSchema = zod.z.object({
12637
+ text: zod.z.string().describe(
12638
+ "The provider's reply, verbatim. Plain-text body where the provider sent one, otherwise the raw HTML body \u2014 treat it as untrusted content and escape it before rendering."
12639
+ ),
12640
+ subject: zod.z.string().nullable().describe("Subject line of the provider's reply.")
12641
+ }).nullable().describe(
12642
+ "Present when `type` is `provider-email`, `null` for every other proof type."
12643
+ );
12644
+ var takedownProofSchema = zod.z.object({
12645
+ type: zod.z.nativeEnum(TakedownProofType).describe(
12646
+ "Which kind of evidence this is. Currently only `provider-email`. New types may be added over time \u2014 read `type` before reading any of the type-specific objects below, and treat an unrecognised value as an opaque proof rather than an error."
12647
+ ),
12648
+ source: zod.z.string().nullable().describe(
12649
+ "Who confirmed the takedown, in whatever form that provider identifies itself \u2014 an address such as `abuse@example.com` for `provider-email`."
12650
+ ),
12651
+ confirmedAt: zod.z.date().describe("When the provider confirmed the takedown."),
12652
+ email: takedownProofEmailSchema
12653
+ });
12654
+ var takedownProofsSchema = zod.z.array(takedownProofSchema).describe(
12655
+ `Evidence that this takedown is ours: providers confirming they removed the asset, newest first.
12656
+
12657
+ A takedown filed at several providers can be confirmed by more than one of them, so this is a list. At most 5 are returned per takedown.
12658
+
12659
+ \`type\`, \`source\` and \`confirmedAt\` are present on every entry, so a caller that only needs to show "confirmed by X on date Y" never has to branch on the type. The type-specific object (\`email\`, and others as they are added) carries the underlying evidence.
12660
+
12661
+ Empty unless the takedown is COMPLETED and we hold a confirmation \u2014 which is the common case, because most providers either never reply or reply without confirming they acted. An empty list is not evidence that the asset is still up.
12662
+
12663
+ Requires the \`takedown-proof-api\` feature flag; without it this is always empty.`
12664
+ );
12371
12665
  var takedownItemSchema = zod.z.object({
12372
12666
  id: zod.z.number().describe("Takedown ID"),
12373
12667
  status: zod.z.nativeEnum(TakedownStatus).describe("Takedown status"),
@@ -12417,7 +12711,8 @@ var takedownItemSchema = zod.z.object({
12417
12711
  name: zod.z.string().describe("TLD registrar name (e.g. `Verisign`, `Public Interest Registry`)")
12418
12712
  }).nullable().describe(
12419
12713
  "Top-level-domain registrar assigned to this takedown. `null` when unresolved."
12420
- )
12714
+ ),
12715
+ proofs: takedownProofsSchema
12421
12716
  });
12422
12717
  zod.z.object({
12423
12718
  takedowns: zod.z.array(takedownItemSchema).describe("List of takedowns"),
@@ -12729,6 +13024,141 @@ zod.z.object({
12729
13024
  hiddenMetrics: zod.z.record(zod.z.string(), zod.z.boolean()).default({}),
12730
13025
  overriddenMetrics: zod.z.record(zod.z.string(), zod.z.boolean()).default({})
12731
13026
  });
13027
+ var ONE_PAGER_BUDGETS = {
13028
+ headline: 60,
13029
+ badge: 28,
13030
+ frontLabel: 44,
13031
+ paragraphsMax: 2,
13032
+ heroPhrase: 80,
13033
+ landscapeCaption: 180,
13034
+ xp01Line: 220,
13035
+ screenshotCaption: 48,
13036
+ divergenceLine: 220
13037
+ };
13038
+ var ONE_PAGER_STORED_MAX = {
13039
+ paragraph: 480,
13040
+ paragraph2Lead: 60,
13041
+ heroNarrative: 300
13042
+ };
13043
+ var onePagerFactPayloadSchema = zod.z.object({
13044
+ /** Raw (not defanged) asset contents the prose may reference. */
13045
+ assetContents: zod.z.array(zod.z.string()),
13046
+ /** Every numeric token (as string) the prose is allowed to contain. */
13047
+ numbers: zod.z.array(zod.z.string()),
13048
+ /** ISO dates the prose may reference. */
13049
+ dates: zod.z.array(zod.z.string()),
13050
+ platforms: zod.z.array(zod.z.string()),
13051
+ groupSize: zod.z.number(),
13052
+ takedownCompletedAt: zod.z.string().nullable(),
13053
+ activeSince: zod.z.string().nullable(),
13054
+ // ---- v2 enrichment ----------------------------------------------------
13055
+ // Optional rather than defaulted so rows stored by v1 keep parsing AND the
13056
+ // inferred type stays assignable from a v1-shaped literal.
13057
+ /** How the attacker paid for the surface ("free_subdomain" | ...). */
13058
+ hostingPattern: zod.z.string().nullable().optional(),
13059
+ /** Who surfaced it first ("client_reported" | "proactive"). */
13060
+ sourceKind: zod.z.string().nullable().optional(),
13061
+ /** Prior blocked assets in the same relaunch family. */
13062
+ relaunchCount: zod.z.number().nullable().optional(),
13063
+ /** Earliest sighting, ISO. */
13064
+ firstSeenAt: zod.z.string().nullable().optional(),
13065
+ /**
13066
+ * Pre-computed hours from first sighting to confirmed removal, as a string
13067
+ * so it lands in the same allowlist as `numbers`. The model is forbidden
13068
+ * from doing arithmetic, so every duration it may cite is computed here.
13069
+ */
13070
+ timeToRemovalHrs: zod.z.string().nullable().optional()
13071
+ });
13072
+ var onePagerStorySchema = zod.z.object({
13073
+ archetypeId: zod.z.string(),
13074
+ archetypeCategory: zod.z.string(),
13075
+ /** 1-5 = placed on the page; null = alternate available for swap. */
13076
+ slot: zod.z.number().int().min(1).max(5).nullable(),
13077
+ /** Column layout the story occupies; slot 1 is full-width by convention. */
13078
+ layout: zod.z.enum(["full", "half"]).default("half"),
13079
+ frontLabel: zod.z.string().max(ONE_PAGER_BUDGETS.frontLabel),
13080
+ headline: zod.z.string().max(ONE_PAGER_BUDGETS.headline),
13081
+ /** Compound "10 of 10 removed · 3 hrs". */
13082
+ badge: zod.z.string().max(ONE_PAGER_BUDGETS.badge),
13083
+ paragraphs: zod.z.array(zod.z.string().max(ONE_PAGER_STORED_MAX.paragraph)).min(1).max(ONE_PAGER_BUDGETS.paragraphsMax),
13084
+ /** Bold lead-in shown ahead of the second paragraph. */
13085
+ paragraph2Lead: zod.z.string().max(ONE_PAGER_STORED_MAX.paragraph2Lead).nullable().default(null),
13086
+ /** Defanged, display-ready asset identifiers. */
13087
+ assetList: zod.z.array(zod.z.string()).max(12),
13088
+ /** Story-bank identity for the referenced assets. */
13089
+ assetIds: zod.z.array(zod.z.number()).default([]),
13090
+ screenshotUrls: zod.z.array(zod.z.string()),
13091
+ selectedScreenshotUrls: zod.z.array(zod.z.string()).max(2),
13092
+ /** Parallel to selectedScreenshotUrls. */
13093
+ screenshotCaptions: zod.z.array(zod.z.string().max(ONE_PAGER_BUDGETS.screenshotCaption)).max(2).default([]),
13094
+ /** Manual redact toggle, parallel to selectedScreenshotUrls. */
13095
+ screenshotBlur: zod.z.array(zod.z.boolean()).max(2).default([]),
13096
+ xp01Line: zod.z.string().max(ONE_PAGER_BUDGETS.xp01Line).nullable(),
13097
+ factPayload: onePagerFactPayloadSchema,
13098
+ proseSource: zod.z.enum(["llm", "template"]),
13099
+ /** Cross-period continuation framing. */
13100
+ continuation: zod.z.boolean().default(false),
13101
+ /** Shown in the editor when this story overlaps with a prior period. */
13102
+ priorHeadline: zod.z.string().nullable().default(null)
13103
+ });
13104
+ var onePagerLandscapeRowSchema = zod.z.object({
13105
+ platform: zod.z.string(),
13106
+ count: zod.z.number(),
13107
+ sharePct: zod.z.number()
13108
+ });
13109
+ var onePagerFormDataObjectSchema = zod.z.object({
13110
+ orgName: zod.z.string(),
13111
+ orgSlug: zod.z.string(),
13112
+ periodLabel: zod.z.string(),
13113
+ partnershipLabel: zod.z.string().max(40).default("AN ONGOING PARTNERSHIP"),
13114
+ coverageWindow: zod.z.object({ start: zod.z.string(), end: zod.z.string(), label: zod.z.string(), short: zod.z.boolean() }).nullable().default(null),
13115
+ heroStat: zod.z.object({
13116
+ value: zod.z.string(),
13117
+ phrase: zod.z.string().max(ONE_PAGER_BUDGETS.heroPhrase)
13118
+ }),
13119
+ heroNarrative: zod.z.string().max(ONE_PAGER_STORED_MAX.heroNarrative),
13120
+ /**
13121
+ * Up to 4 rows, but the metric library legitimately returns fewer on a thin
13122
+ * month (a zero-valued metric is excluded outright rather than rendered as
13123
+ * a "0" row), so this is a range, not a fixed length. Below 2 the block
13124
+ * reads as broken rather than short.
13125
+ */
13126
+ metricsRows: zod.z.array(
13127
+ zod.z.object({
13128
+ key: zod.z.string().default("legacy"),
13129
+ label: zod.z.string(),
13130
+ value: zod.z.string()
13131
+ })
13132
+ ).min(2).max(4),
13133
+ landscape: zod.z.object({
13134
+ rows: zod.z.array(onePagerLandscapeRowSchema).max(8),
13135
+ otherCount: zod.z.number().nullable(),
13136
+ otherPlatformsLabel: zod.z.string().nullable(),
13137
+ /** Kept for legacy row parse; caption is preferred going forward. */
13138
+ divergenceLine: zod.z.string().max(ONE_PAGER_BUDGETS.divergenceLine).nullable(),
13139
+ caption: zod.z.string().max(ONE_PAGER_BUDGETS.landscapeCaption).nullable().default(null)
13140
+ }),
13141
+ stories: zod.z.array(onePagerStorySchema).min(1).max(6),
13142
+ footer: zod.z.object({
13143
+ contactName: zod.z.string(),
13144
+ contactLine: zod.z.string(),
13145
+ contactEmail: zod.z.string().default(""),
13146
+ bookingLink: zod.z.string().default(""),
13147
+ ctaLine: zod.z.string().default("Anything your community has flagged, send it over.")
13148
+ }),
13149
+ /** Engine v2 writes 2; absent/older rows default to 1. */
13150
+ schemaVersion: zod.z.number().default(1)
13151
+ });
13152
+ onePagerFormDataObjectSchema.refine(
13153
+ (data) => data.stories.some((s2) => s2.slot !== null),
13154
+ { message: "at least one story must be placed", path: ["stories"] }
13155
+ );
13156
+ var INTERNAL_ORG_SLUGS = [
13157
+ "chainpatrol",
13158
+ "chainpatrol-automation",
13159
+ "mountaintop"
13160
+ ];
13161
+ new Set(INTERNAL_ORG_SLUGS);
12732
13162
  zod.z.object({
12733
13163
  x: zod.z.number().min(0).max(1),
12734
13164
  y: zod.z.number().min(0).max(1),
@@ -13494,20 +13924,20 @@ var convertA98ToXyz65_default = convertA98ToXyz65;
13494
13924
 
13495
13925
  // ../../node_modules/culori/src/a98/convertXyz65ToA98.js
13496
13926
  var gamma = (v) => Math.pow(Math.abs(v), 256 / 563) * Math.sign(v);
13497
- var convertXyz65ToA98 = ({ x, y, z: z56, alpha }) => {
13927
+ var convertXyz65ToA98 = ({ x, y, z: z64, alpha }) => {
13498
13928
  if (x === void 0) x = 0;
13499
13929
  if (y === void 0) y = 0;
13500
- if (z56 === void 0) z56 = 0;
13930
+ if (z64 === void 0) z64 = 0;
13501
13931
  let res = {
13502
13932
  mode: "a98",
13503
13933
  r: gamma(
13504
- x * 2.0415879038107465 - y * 0.5650069742788597 - 0.3447313507783297 * z56
13934
+ x * 2.0415879038107465 - y * 0.5650069742788597 - 0.3447313507783297 * z64
13505
13935
  ),
13506
13936
  g: gamma(
13507
- x * -0.9692436362808798 + y * 1.8759675015077206 + 0.0415550574071756 * z56
13937
+ x * -0.9692436362808798 + y * 1.8759675015077206 + 0.0415550574071756 * z64
13508
13938
  ),
13509
13939
  b: gamma(
13510
- x * 0.0134442806320312 - y * 0.1183623922310184 + 1.0151749943912058 * z56
13940
+ x * 0.0134442806320312 - y * 0.1183623922310184 + 1.0151749943912058 * z64
13511
13941
  )
13512
13942
  };
13513
13943
  if (alpha !== void 0) {
@@ -13574,14 +14004,14 @@ var convertLrgbToRgb = ({ r, g, b, alpha }, mode = "rgb") => {
13574
14004
  var convertLrgbToRgb_default = convertLrgbToRgb;
13575
14005
 
13576
14006
  // ../../node_modules/culori/src/xyz65/convertXyz65ToRgb.js
13577
- var convertXyz65ToRgb = ({ x, y, z: z56, alpha }) => {
14007
+ var convertXyz65ToRgb = ({ x, y, z: z64, alpha }) => {
13578
14008
  if (x === void 0) x = 0;
13579
14009
  if (y === void 0) y = 0;
13580
- if (z56 === void 0) z56 = 0;
14010
+ if (z64 === void 0) z64 = 0;
13581
14011
  let res = convertLrgbToRgb_default({
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
14012
+ r: x * 3.2409699419045226 - y * 1.537383177570094 - 0.4986107602930034 * z64,
14013
+ g: x * -0.9692436362808796 + y * 1.8759675015077204 + 0.0415550574071756 * z64,
14014
+ b: x * 0.0556300796969936 - y * 0.2039769588889765 + 1.0569715142428784 * z64
13585
14015
  });
13586
14016
  if (alpha !== void 0) {
13587
14017
  res.alpha = alpha;
@@ -13831,13 +14261,13 @@ var convertLab65ToRgb_default = convertLab65ToRgb;
13831
14261
 
13832
14262
  // ../../node_modules/culori/src/lab65/convertXyz65ToLab65.js
13833
14263
  var f = (value) => value > e ? Math.cbrt(value) : (k * value + 16) / 116;
13834
- var convertXyz65ToLab65 = ({ x, y, z: z56, alpha }) => {
14264
+ var convertXyz65ToLab65 = ({ x, y, z: z64, alpha }) => {
13835
14265
  if (x === void 0) x = 0;
13836
14266
  if (y === void 0) y = 0;
13837
- if (z56 === void 0) z56 = 0;
14267
+ if (z64 === void 0) z64 = 0;
13838
14268
  let f0 = f(x / D65.X);
13839
14269
  let f1 = f(y / D65.Y);
13840
- let f22 = f(z56 / D65.Z);
14270
+ let f22 = f(z64 / D65.Z);
13841
14271
  let res = {
13842
14272
  mode: "lab65",
13843
14273
  l: 116 * f1 - 16,
@@ -14494,10 +14924,10 @@ var convertItpToXyz65_default = convertItpToXyz65;
14494
14924
 
14495
14925
  // ../../node_modules/culori/src/itp/convertXyz65ToItp.js
14496
14926
  var toAbs = (c2 = 0) => Math.max(c2 * YW, 0);
14497
- var convertXyz65ToItp = ({ x, y, z: z56, alpha }) => {
14927
+ var convertXyz65ToItp = ({ x, y, z: z64, alpha }) => {
14498
14928
  const absX = toAbs(x);
14499
14929
  const absY = toAbs(y);
14500
- const absZ = toAbs(z56);
14930
+ const absZ = toAbs(z64);
14501
14931
  const l2 = transferPqEncode(
14502
14932
  0.3592832590121217 * absX + 0.6976051147779502 * absY - 0.0358915932320289 * absZ
14503
14933
  );
@@ -14555,15 +14985,15 @@ var jabPqEncode = (v) => {
14555
14985
  return Math.pow((C1 + C2 * vn3) / (1 + C3 * vn3), p);
14556
14986
  };
14557
14987
  var abs = (v = 0) => Math.max(v * 203, 0);
14558
- var convertXyz65ToJab = ({ x, y, z: z56, alpha }) => {
14988
+ var convertXyz65ToJab = ({ x, y, z: z64, alpha }) => {
14559
14989
  x = abs(x);
14560
14990
  y = abs(y);
14561
- z56 = abs(z56);
14562
- let xp = 1.15 * x - 0.15 * z56;
14991
+ z64 = abs(z64);
14992
+ let xp = 1.15 * x - 0.15 * z64;
14563
14993
  let yp = 0.66 * y + 0.34 * x;
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);
14994
+ let l2 = jabPqEncode(0.41478972 * xp + 0.579999 * yp + 0.014648 * z64);
14995
+ let m = jabPqEncode(-0.20151 * xp + 1.120649 * yp + 0.0531008 * z64);
14996
+ let s2 = jabPqEncode(-0.0166008 * xp + 0.2648 * yp + 0.6684799 * z64);
14567
14997
  let i = (l2 + m) / 2;
14568
14998
  let res = {
14569
14999
  mode: "jab",
@@ -14749,14 +15179,14 @@ var convertLabToXyz50 = ({ l: l2, a, b, alpha }) => {
14749
15179
  var convertLabToXyz50_default = convertLabToXyz50;
14750
15180
 
14751
15181
  // ../../node_modules/culori/src/xyz50/convertXyz50ToRgb.js
14752
- var convertXyz50ToRgb = ({ x, y, z: z56, alpha }) => {
15182
+ var convertXyz50ToRgb = ({ x, y, z: z64, alpha }) => {
14753
15183
  if (x === void 0) x = 0;
14754
15184
  if (y === void 0) y = 0;
14755
- if (z56 === void 0) z56 = 0;
15185
+ if (z64 === void 0) z64 = 0;
14756
15186
  let res = convertLrgbToRgb_default({
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
15187
+ r: x * 3.1341359569958707 - y * 1.6173863321612538 - 0.4906619460083532 * z64,
15188
+ g: x * -0.978795502912089 + y * 1.916254567259524 + 0.03344273116131949 * z64,
15189
+ b: x * 0.07195537988411677 - y * 0.2289768264158322 + 1.405386058324125 * z64
14760
15190
  });
14761
15191
  if (alpha !== void 0) {
14762
15192
  res.alpha = alpha;
@@ -14787,13 +15217,13 @@ var convertRgbToXyz50_default = convertRgbToXyz50;
14787
15217
 
14788
15218
  // ../../node_modules/culori/src/lab/convertXyz50ToLab.js
14789
15219
  var f2 = (value) => value > e3 ? Math.cbrt(value) : (k3 * value + 16) / 116;
14790
- var convertXyz50ToLab = ({ x, y, z: z56, alpha }) => {
15220
+ var convertXyz50ToLab = ({ x, y, z: z64, alpha }) => {
14791
15221
  if (x === void 0) x = 0;
14792
15222
  if (y === void 0) y = 0;
14793
- if (z56 === void 0) z56 = 0;
15223
+ if (z64 === void 0) z64 = 0;
14794
15224
  let f0 = f2(x / D50.X);
14795
15225
  let f1 = f2(y / D50.Y);
14796
- let f22 = f2(z56 / D50.Z);
15226
+ let f22 = f2(z64 / D50.Z);
14797
15227
  let res = {
14798
15228
  mode: "lab",
14799
15229
  l: 116 * f1 - 16,
@@ -15028,18 +15458,18 @@ var convertLchuvToLuv = ({ l: l2, c: c2, h, alpha }) => {
15028
15458
  var convertLchuvToLuv_default = convertLchuvToLuv;
15029
15459
 
15030
15460
  // ../../node_modules/culori/src/luv/convertXyz50ToLuv.js
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);
15461
+ var u_fn = (x, y, z64) => 4 * x / (x + 15 * y + 3 * z64);
15462
+ var v_fn = (x, y, z64) => 9 * y / (x + 15 * y + 3 * z64);
15033
15463
  var un = u_fn(D50.X, D50.Y, D50.Z);
15034
15464
  var vn = v_fn(D50.X, D50.Y, D50.Z);
15035
15465
  var l_fn = (value) => value <= e3 ? k3 * value : 116 * Math.cbrt(value) - 16;
15036
- var convertXyz50ToLuv = ({ x, y, z: z56, alpha }) => {
15466
+ var convertXyz50ToLuv = ({ x, y, z: z64, alpha }) => {
15037
15467
  if (x === void 0) x = 0;
15038
15468
  if (y === void 0) y = 0;
15039
- if (z56 === void 0) z56 = 0;
15469
+ if (z64 === void 0) z64 = 0;
15040
15470
  let l2 = l_fn(y / D50.Y);
15041
- let u = u_fn(x, y, z56);
15042
- let v = v_fn(x, y, z56);
15471
+ let u = u_fn(x, y, z64);
15472
+ let v = v_fn(x, y, z64);
15043
15473
  if (!isFinite(u) || !isFinite(v)) {
15044
15474
  l2 = u = v = 0;
15045
15475
  } else {
@@ -15060,8 +15490,8 @@ var convertXyz50ToLuv = ({ x, y, z: z56, alpha }) => {
15060
15490
  var convertXyz50ToLuv_default = convertXyz50ToLuv;
15061
15491
 
15062
15492
  // ../../node_modules/culori/src/luv/convertLuvToXyz50.js
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);
15493
+ var u_fn2 = (x, y, z64) => 4 * x / (x + 15 * y + 3 * z64);
15494
+ var v_fn2 = (x, y, z64) => 9 * y / (x + 15 * y + 3 * z64);
15065
15495
  var un2 = u_fn2(D50.X, D50.Y, D50.Z);
15066
15496
  var vn2 = v_fn2(D50.X, D50.Y, D50.Z);
15067
15497
  var convertLuvToXyz50 = ({ l: l2, u, v, alpha }) => {
@@ -15075,8 +15505,8 @@ var convertLuvToXyz50 = ({ l: l2, u, v, alpha }) => {
15075
15505
  let vp = v / (13 * l2) + vn2;
15076
15506
  let y = D50.Y * (l2 <= 8 ? l2 / k3 : Math.pow((l2 + 16) / 116, 3));
15077
15507
  let x = y * (9 * up) / (4 * vp);
15078
- let z56 = y * (12 - 3 * up - 20 * vp) / (4 * vp);
15079
- let res = { mode: "xyz50", x, y, z: z56 };
15508
+ let z64 = y * (12 - 3 * up - 20 * vp) / (4 * vp);
15509
+ let res = { mode: "xyz50", x, y, z: z64 };
15080
15510
  if (alpha !== void 0) {
15081
15511
  res.alpha = alpha;
15082
15512
  }
@@ -15693,15 +16123,15 @@ var convertP3ToXyz65 = (rgb2) => {
15693
16123
  var convertP3ToXyz65_default = convertP3ToXyz65;
15694
16124
 
15695
16125
  // ../../node_modules/culori/src/p3/convertXyz65ToP3.js
15696
- var convertXyz65ToP3 = ({ x, y, z: z56, alpha }) => {
16126
+ var convertXyz65ToP3 = ({ x, y, z: z64, alpha }) => {
15697
16127
  if (x === void 0) x = 0;
15698
16128
  if (y === void 0) y = 0;
15699
- if (z56 === void 0) z56 = 0;
16129
+ if (z64 === void 0) z64 = 0;
15700
16130
  let res = convertLrgbToRgb_default(
15701
16131
  {
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
16132
+ r: x * 2.4934969119414263 - y * 0.9313836179191242 - 0.402710784450717 * z64,
16133
+ g: x * -0.8294889695615749 + y * 1.7626640603183465 + 0.0236246858419436 * z64,
16134
+ b: x * 0.0358458302437845 - y * 0.0761723892680418 + 0.9568845240076871 * z64
15705
16135
  },
15706
16136
  "p3"
15707
16137
  );
@@ -15736,19 +16166,19 @@ var gamma2 = (v) => {
15736
16166
  }
15737
16167
  return 16 * v;
15738
16168
  };
15739
- var convertXyz50ToProphoto = ({ x, y, z: z56, alpha }) => {
16169
+ var convertXyz50ToProphoto = ({ x, y, z: z64, alpha }) => {
15740
16170
  if (x === void 0) x = 0;
15741
16171
  if (y === void 0) y = 0;
15742
- if (z56 === void 0) z56 = 0;
16172
+ if (z64 === void 0) z64 = 0;
15743
16173
  let res = {
15744
16174
  mode: "prophoto",
15745
16175
  r: gamma2(
15746
- x * 1.3457868816471585 - y * 0.2555720873797946 - 0.0511018649755453 * z56
16176
+ x * 1.3457868816471585 - y * 0.2555720873797946 - 0.0511018649755453 * z64
15747
16177
  ),
15748
16178
  g: gamma2(
15749
- x * -0.5446307051249019 + y * 1.5082477428451466 + 0.0205274474364214 * z56
16179
+ x * -0.5446307051249019 + y * 1.5082477428451466 + 0.0205274474364214 * z64
15750
16180
  ),
15751
- b: gamma2(x * 0 + y * 0 + 1.2119675456389452 * z56)
16181
+ b: gamma2(x * 0 + y * 0 + 1.2119675456389452 * z64)
15752
16182
  };
15753
16183
  if (alpha !== void 0) {
15754
16184
  res.alpha = alpha;
@@ -15808,20 +16238,20 @@ var gamma3 = (v) => {
15808
16238
  }
15809
16239
  return 4.5 * v;
15810
16240
  };
15811
- var convertXyz65ToRec2020 = ({ x, y, z: z56, alpha }) => {
16241
+ var convertXyz65ToRec2020 = ({ x, y, z: z64, alpha }) => {
15812
16242
  if (x === void 0) x = 0;
15813
16243
  if (y === void 0) y = 0;
15814
- if (z56 === void 0) z56 = 0;
16244
+ if (z64 === void 0) z64 = 0;
15815
16245
  let res = {
15816
16246
  mode: "rec2020",
15817
16247
  r: gamma3(
15818
- x * 1.7166511879712683 - y * 0.3556707837763925 - 0.2533662813736599 * z56
16248
+ x * 1.7166511879712683 - y * 0.3556707837763925 - 0.2533662813736599 * z64
15819
16249
  ),
15820
16250
  g: gamma3(
15821
- x * -0.6666843518324893 + y * 1.6164812366349395 + 0.0157685458139111 * z56
16251
+ x * -0.6666843518324893 + y * 1.6164812366349395 + 0.0157685458139111 * z64
15822
16252
  ),
15823
16253
  b: gamma3(
15824
- x * 0.0176398574453108 - y * 0.0427706132578085 + 0.9421031212354739 * z56
16254
+ x * 0.0176398574453108 - y * 0.0427706132578085 + 0.9421031212354739 * z64
15825
16255
  )
15826
16256
  };
15827
16257
  if (alpha !== void 0) {
@@ -15974,15 +16404,15 @@ var definition_default26 = definition26;
15974
16404
 
15975
16405
  // ../../node_modules/culori/src/xyz65/convertXyz65ToXyz50.js
15976
16406
  var convertXyz65ToXyz50 = (xyz652) => {
15977
- let { x, y, z: z56, alpha } = xyz652;
16407
+ let { x, y, z: z64, alpha } = xyz652;
15978
16408
  if (x === void 0) x = 0;
15979
16409
  if (y === void 0) y = 0;
15980
- if (z56 === void 0) z56 = 0;
16410
+ if (z64 === void 0) z64 = 0;
15981
16411
  let res = {
15982
16412
  mode: "xyz50",
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
16413
+ x: 1.0479298208405488 * x + 0.0229467933410191 * y - 0.0501922295431356 * z64,
16414
+ y: 0.0296278156881593 * x + 0.990434484573249 * y - 0.0170738250293851 * z64,
16415
+ z: -0.0092430581525912 * x + 0.0150551448965779 * y + 0.7518742899580008 * z64
15986
16416
  };
15987
16417
  if (alpha !== void 0) {
15988
16418
  res.alpha = alpha;
@@ -15993,15 +16423,15 @@ var convertXyz65ToXyz50_default = convertXyz65ToXyz50;
15993
16423
 
15994
16424
  // ../../node_modules/culori/src/xyz65/convertXyz50ToXyz65.js
15995
16425
  var convertXyz50ToXyz65 = (xyz502) => {
15996
- let { x, y, z: z56, alpha } = xyz502;
16426
+ let { x, y, z: z64, alpha } = xyz502;
15997
16427
  if (x === void 0) x = 0;
15998
16428
  if (y === void 0) y = 0;
15999
- if (z56 === void 0) z56 = 0;
16429
+ if (z64 === void 0) z64 = 0;
16000
16430
  let res = {
16001
16431
  mode: "xyz65",
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
16432
+ x: 0.9554734527042182 * x - 0.0230985368742614 * y + 0.0632593086610217 * z64,
16433
+ y: -0.0283697069632081 * x + 1.0099954580058226 * y + 0.021041398966943 * z64,
16434
+ z: 0.0123140016883199 * x - 0.0205076964334779 * y + 1.3303659366080753 * z64
16005
16435
  };
16006
16436
  if (alpha !== void 0) {
16007
16437
  res.alpha = alpha;
@@ -16238,6 +16668,13 @@ function validateTermsString(termsString) {
16238
16668
  };
16239
16669
  }
16240
16670
  } else {
16671
+ if (term.startsWith("*") || term.endsWith("*")) {
16672
+ const inner = term.replace(/^\*+|\*+$/g, "");
16673
+ return {
16674
+ valid: false,
16675
+ error: `Term "${term}" has an unmatched asterisk. Use *${inner}* for exact matching, or ${inner} for loose matching.`
16676
+ };
16677
+ }
16241
16678
  normalizedTerm = term.replace(/\s+/g, "");
16242
16679
  if (normalizedTerm.length < 6) {
16243
16680
  return {
@@ -16835,6 +17272,8 @@ var SCAN_TEMPLATES = [
16835
17272
  new Map(
16836
17273
  SCAN_TEMPLATES.map((template) => [template.id, template])
16837
17274
  );
17275
+ var DARK_WEB_ENTITY_SEARCH_KINDS = ["domain", "email", "crypto"];
17276
+ zod.z.enum(DARK_WEB_ENTITY_SEARCH_KINDS);
16838
17277
 
16839
17278
  // src/client.ts
16840
17279
  function trimTrailingSlashes(url) {