@konfeature/ap-email-guessr 0.1.7 → 0.1.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@konfeature/ap-email-guessr",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Activepieces piece that finds a person's email from their name and company domain — free Microsoft 365 account checks plus no2bounce verification, with early-stop to minimize credits.",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -6,5 +6,7 @@ export declare const findEmailAction: import("@activepieces/pieces-framework").I
6
6
  maxChecks: import("@activepieces/pieces-framework").NumberProperty<false>;
7
7
  useO365: import("@activepieces/pieces-framework").CheckboxProperty<false>;
8
8
  timeout: import("@activepieces/pieces-framework").NumberProperty<false>;
9
+ useCache: import("@activepieces/pieces-framework").CheckboxProperty<false>;
10
+ cacheTtlDays: import("@activepieces/pieces-framework").NumberProperty<false>;
9
11
  }>;
10
12
  //# sourceMappingURL=find-email.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"find-email.d.ts","sourceRoot":"","sources":["../../../../src/lib/actions/find-email.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,eAAe;;;;;;;;EAmG1B,CAAC"}
1
+ {"version":3,"file":"find-email.d.ts","sourceRoot":"","sources":["../../../../src/lib/actions/find-email.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,eAAe;;;;;;;;;;EA4H1B,CAAC"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.findEmailAction = void 0;
4
4
  const pieces_framework_1 = require("@activepieces/pieces-framework");
5
5
  const auth_1 = require("../common/auth");
6
+ const domain_cache_1 = require("../common/domain-cache");
6
7
  const find_person_1 = require("../common/find-person");
7
8
  const no2bounce_verifier_1 = require("../common/verifiers/no2bounce-verifier");
8
9
  exports.findEmailAction = (0, pieces_framework_1.createAction)({
@@ -54,12 +55,32 @@ exports.findEmailAction = (0, pieces_framework_1.createAction)({
54
55
  required: false,
55
56
  defaultValue: 15,
56
57
  }),
58
+ useCache: pieces_framework_1.Property.Checkbox({
59
+ displayName: "Use Domain Cache",
60
+ description: "Remember per-domain learnings across runs (dead/catch-all domains and the winning naming pattern) to cut redundant no2bounce credits. Stored in the project store.",
61
+ required: false,
62
+ defaultValue: true,
63
+ }),
64
+ cacheTtlDays: pieces_framework_1.Property.Number({
65
+ displayName: "Cache TTL (days)",
66
+ description: "How long a domain's cached learnings stay valid before they are refreshed. 0 disables expiry. Default 30.",
67
+ required: false,
68
+ defaultValue: 30,
69
+ }),
57
70
  },
58
71
  async run(context) {
59
72
  const { firstName, lastName, domain, patternSet, maxChecks, useO365 } = context.propsValue;
60
73
  const timeoutSeconds = context.propsValue.timeout ?? 15;
61
74
  const timeoutMs = Math.min(Math.max(Number(timeoutSeconds) || 15, 1), 120) * 1000;
62
75
  const token = (0, auth_1.readSecretText)(context.auth);
76
+ const useCache = context.propsValue.useCache ?? true;
77
+ const ttlDays = context.propsValue.cacheTtlDays;
78
+ const ttlMs = ttlDays != null && Number(ttlDays) >= 0
79
+ ? Number(ttlDays) * 24 * 60 * 60 * 1000
80
+ : domain_cache_1.DEFAULT_CACHE_TTL_MS;
81
+ const cache = useCache
82
+ ? (0, domain_cache_1.createStoreDomainCache)(context.store, ttlMs)
83
+ : undefined;
63
84
  const result = await (0, find_person_1.findPersonEmail)(firstName, lastName, domain, {
64
85
  patternSet: patternSet ?? "common",
65
86
  maxChecks: maxChecks != null ? Math.max(1, Number(maxChecks)) : undefined,
@@ -67,6 +88,7 @@ exports.findEmailAction = (0, pieces_framework_1.createAction)({
67
88
  timeoutMs,
68
89
  useO365: useO365 ?? true,
69
90
  no2bounceToken: token,
91
+ cache,
70
92
  }).catch((error) => {
71
93
  if (error instanceof no2bounce_verifier_1.No2BounceAuthError) {
72
94
  throw new Error(`no2bounce rejected the API token — check the connection's API key (it may be invalid, expired, or have trailing whitespace). ${error.message}`);
@@ -1 +1 @@
1
- {"version":3,"file":"find-email.js","sourceRoot":"","sources":["../../../../src/lib/actions/find-email.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"find-email.js","sourceRoot":"","sources":["../../../../src/lib/actions/find-email.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Per-domain memory — the credit-saving cache.
3
+ *
4
+ * Verification cost is dominated by no2bounce credits (1/email, no refund).
5
+ * Most of that spend is redundant across people on the *same* domain: the
6
+ * domain's mail routing never changes between two lookups, the domain is either
7
+ * accept-all for everyone or no one, and a company almost always uses a single
8
+ * naming convention. So once we learn those facts for a domain we can reuse
9
+ * them and stop paying to rediscover them:
10
+ *
11
+ * - `dead` → null/no MX. Future lookups short-circuit to `invalid` with no
12
+ * DNS round-trip and zero credits.
13
+ * - `catchAll` → the domain accepts everything. No mailbox can be confirmed, so
14
+ * future lookups return `catch_all` immediately for zero credits
15
+ * instead of spending one to rediscover the accept-all signal.
16
+ * - `routing` → the resolved provider / O365 namespace / chosen verifier, so
17
+ * we skip the MX + getuserrealm round-trips (latency + throttle).
18
+ * - `patternId`→ the naming convention that produced a real hit (e.g.
19
+ * `first.last`, `flast`). The next person on that domain has that
20
+ * exact pattern moved to the front, so the single first probe is
21
+ * the likely hit: one credit instead of a whole round.
22
+ *
23
+ * The interface is deliberately storage-agnostic (a plain get/set keyed by
24
+ * domain) so the search logic stays pure and unit-testable; the Activepieces
25
+ * `Store` adapter lives at the bottom of this file.
26
+ */
27
+ import { Store } from "@activepieces/pieces-framework";
28
+ import type { O365Namespace } from "./providers/o365";
29
+ export interface DomainRouting {
30
+ providerId: string;
31
+ microsoftBacked: boolean;
32
+ namespace: O365Namespace;
33
+ verifierUsed: string;
34
+ }
35
+ export interface DomainMemory {
36
+ /** null/no MX — the domain cannot receive mail. */
37
+ dead?: boolean;
38
+ /** Reason string carried over to the short-circuited result. */
39
+ deadReason?: string;
40
+ /** The domain accepts everything; no individual mailbox is confirmable. */
41
+ catchAll?: boolean;
42
+ /** Resolved routing, so DNS + realm lookups can be skipped. */
43
+ routing?: DomainRouting;
44
+ /** Learned winning pattern id (primary patterns only). */
45
+ patternId?: string;
46
+ /** Epoch ms of the last write, used for TTL expiry. */
47
+ updatedAt: number;
48
+ }
49
+ export interface DomainCache {
50
+ get(domain: string): Promise<DomainMemory | null>;
51
+ set(domain: string, memory: DomainMemory): Promise<void>;
52
+ }
53
+ /** 30 days. Routing and naming conventions drift rarely; refresh occasionally. */
54
+ export declare const DEFAULT_CACHE_TTL_MS: number;
55
+ /**
56
+ * Back the domain cache with the Activepieces project store, so learnings are
57
+ * shared across every flow run in the project. A `ttlMs` of 0 disables expiry.
58
+ */
59
+ export declare function createStoreDomainCache(store: Store, ttlMs?: number): DomainCache;
60
+ //# sourceMappingURL=domain-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain-cache.d.ts","sourceRoot":"","sources":["../../../../src/lib/common/domain-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,KAAK,EAAc,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,WAAW,aAAa;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,aAAa,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IACzB,mDAAmD;IACnD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IACxB,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAClD,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5D;AAED,kFAAkF;AAClF,eAAO,MAAM,oBAAoB,QAA2B,CAAC;AAI7D;;;GAGG;AACH,wBAAgB,sBAAsB,CAClC,KAAK,EAAE,KAAK,EACZ,KAAK,GAAE,MAA6B,GACrC,WAAW,CAoBb"}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ /**
3
+ * Per-domain memory — the credit-saving cache.
4
+ *
5
+ * Verification cost is dominated by no2bounce credits (1/email, no refund).
6
+ * Most of that spend is redundant across people on the *same* domain: the
7
+ * domain's mail routing never changes between two lookups, the domain is either
8
+ * accept-all for everyone or no one, and a company almost always uses a single
9
+ * naming convention. So once we learn those facts for a domain we can reuse
10
+ * them and stop paying to rediscover them:
11
+ *
12
+ * - `dead` → null/no MX. Future lookups short-circuit to `invalid` with no
13
+ * DNS round-trip and zero credits.
14
+ * - `catchAll` → the domain accepts everything. No mailbox can be confirmed, so
15
+ * future lookups return `catch_all` immediately for zero credits
16
+ * instead of spending one to rediscover the accept-all signal.
17
+ * - `routing` → the resolved provider / O365 namespace / chosen verifier, so
18
+ * we skip the MX + getuserrealm round-trips (latency + throttle).
19
+ * - `patternId`→ the naming convention that produced a real hit (e.g.
20
+ * `first.last`, `flast`). The next person on that domain has that
21
+ * exact pattern moved to the front, so the single first probe is
22
+ * the likely hit: one credit instead of a whole round.
23
+ *
24
+ * The interface is deliberately storage-agnostic (a plain get/set keyed by
25
+ * domain) so the search logic stays pure and unit-testable; the Activepieces
26
+ * `Store` adapter lives at the bottom of this file.
27
+ */
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.DEFAULT_CACHE_TTL_MS = void 0;
30
+ exports.createStoreDomainCache = createStoreDomainCache;
31
+ const pieces_framework_1 = require("@activepieces/pieces-framework");
32
+ /** 30 days. Routing and naming conventions drift rarely; refresh occasionally. */
33
+ exports.DEFAULT_CACHE_TTL_MS = 30 * 24 * 60 * 60 * 1000;
34
+ const KEY_PREFIX = "domain-memory:";
35
+ /**
36
+ * Back the domain cache with the Activepieces project store, so learnings are
37
+ * shared across every flow run in the project. A `ttlMs` of 0 disables expiry.
38
+ */
39
+ function createStoreDomainCache(store, ttlMs = exports.DEFAULT_CACHE_TTL_MS) {
40
+ const key = (domain) => `${KEY_PREFIX}${domain}`;
41
+ return {
42
+ async get(domain) {
43
+ const memory = await store.get(key(domain), pieces_framework_1.StoreScope.PROJECT);
44
+ if (!memory) {
45
+ return null;
46
+ }
47
+ if (ttlMs > 0 && Date.now() - (memory.updatedAt ?? 0) > ttlMs) {
48
+ return null;
49
+ }
50
+ return memory;
51
+ },
52
+ async set(domain, memory) {
53
+ await store.put(key(domain), memory, pieces_framework_1.StoreScope.PROJECT);
54
+ },
55
+ };
56
+ }
57
+ //# sourceMappingURL=domain-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain-cache.js","sourceRoot":"","sources":["../../../../src/lib/common/domain-cache.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;;;AAyCH,wDAuBC;AA9DD,qEAAmE;AA8BnE,kFAAkF;AACrE,QAAA,oBAAoB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAE7D,MAAM,UAAU,GAAG,gBAAgB,CAAC;AAEpC;;;GAGG;AACH,SAAgB,sBAAsB,CAClC,KAAY,EACZ,QAAgB,4BAAoB;IAEpC,MAAM,GAAG,GAAG,CAAC,MAAc,EAAU,EAAE,CAAC,GAAG,UAAU,GAAG,MAAM,EAAE,CAAC;IACjE,OAAO;QACH,KAAK,CAAC,GAAG,CAAC,MAAM;YACZ,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,GAAG,CAC1B,GAAG,CAAC,MAAM,CAAC,EACX,6BAAU,CAAC,OAAO,CACrB,CAAC;YACF,IAAI,CAAC,MAAM,EAAE,CAAC;gBACV,OAAO,IAAI,CAAC;YAChB,CAAC;YACD,IAAI,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC;gBAC5D,OAAO,IAAI,CAAC;YAChB,CAAC;YACD,OAAO,MAAM,CAAC;QAClB,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM;YACpB,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,6BAAU,CAAC,OAAO,CAAC,CAAC;QAC7D,CAAC;KACJ,CAAC;AACN,CAAC"}
@@ -8,6 +8,7 @@
8
8
  * "Managed realm but Google/Zoho MX" exclusion is the louyetu.fr false-negative
9
9
  * fix: a leftover Azure AD tenant must not be trusted as Microsoft mail.
10
10
  */
11
+ import type { DomainCache } from "./domain-cache";
11
12
  import { type FindEmailResult } from "./find-email";
12
13
  import { type PatternSet } from "./patterns";
13
14
  export interface FindPersonOptions {
@@ -19,6 +20,8 @@ export interface FindPersonOptions {
19
20
  timeoutMs: number;
20
21
  useO365: boolean;
21
22
  no2bounceToken?: string;
23
+ /** Optional per-domain memory; skips redundant work and credits. */
24
+ cache?: DomainCache;
22
25
  }
23
26
  export interface FindPersonResult extends FindEmailResult {
24
27
  reason: string;
@@ -1 +1 @@
1
- {"version":3,"file":"find-person.d.ts","sourceRoot":"","sources":["../../../../src/lib/common/find-person.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAO/D,OAAO,EAAE,KAAK,UAAU,EAA4C,MAAM,YAAY,CAAC;AAOvF,MAAM,WAAW,iBAAiB;IAC9B,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;CAChC;AA2BD,wBAAsB,eAAe,CACjC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,iBAAiB,GAC3B,OAAO,CAAC,gBAAgB,CAAC,CA6E3B"}
1
+ {"version":3,"file":"find-person.d.ts","sourceRoot":"","sources":["../../../../src/lib/common/find-person.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,WAAW,EAA+B,MAAM,gBAAgB,CAAC;AAE/E,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAO/D,OAAO,EAEH,KAAK,UAAU,EAIlB,MAAM,YAAY,CAAC;AAOpB,MAAM,WAAW,iBAAiB;IAC9B,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oEAAoE;IACpE,KAAK,CAAC,EAAE,WAAW,CAAC;CACvB;AAED,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;CAChC;AA2BD,wBAAsB,eAAe,CACjC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,iBAAiB,GAC3B,OAAO,CAAC,gBAAgB,CAAC,CAmH3B"}
@@ -37,42 +37,57 @@ function earlyExit(candidatesConsidered, domain, mxProvider, verdict, confidence
37
37
  };
38
38
  }
39
39
  async function findPersonEmail(firstName, lastName, domain, options) {
40
- const candidates = (0, patterns_1.generateEmailCandidates)({
40
+ const cleanDomain = (0, patterns_1.normalizeDomain)(domain);
41
+ const cache = options.cache;
42
+ const memory = cache ? await cache.get(cleanDomain) : null;
43
+ const candidateMeta = (0, patterns_1.generateCandidates)({
41
44
  firstName,
42
45
  lastName,
43
46
  domain,
44
47
  patternSet: options.patternSet,
45
48
  maxVariants: options.maxVariants,
49
+ // Reuse the domain's learned naming convention so the first probe hits.
50
+ preferPatternId: memory?.patternId,
46
51
  });
47
- const cleanDomain = (0, patterns_1.normalizeDomain)(domain);
52
+ const candidates = candidateMeta.map((c) => c.email);
48
53
  if (candidates.length === 0) {
49
54
  return earlyExit(0, cleanDomain, "none", "invalid", 0.03, "no_candidates");
50
55
  }
51
- const routing = await (0, dns_1.resolveMail)(cleanDomain);
52
- const provider = (0, mx_fingerprint_1.fingerprintMx)(routing.hosts);
53
- if (routing.nullMx) {
54
- return earlyExit(candidates.length, cleanDomain, provider.id, "invalid", 0.02, "null_mx");
56
+ // Cache hit: the domain can't receive mail. No DNS, no credits.
57
+ if (memory?.dead) {
58
+ return earlyExit(candidates.length, cleanDomain, memory.routing?.providerId ?? "none", "invalid", 0.02, `cached_${memory.deadReason ?? "dead"}`);
55
59
  }
56
- if (routing.hosts.length === 0) {
57
- return earlyExit(candidates.length, cleanDomain, provider.id, "invalid", 0.03, "no_mx_record");
60
+ // Cache hit: the domain is accept-all. No mailbox is confirmable, so don't
61
+ // spend a credit rediscovering that — return catch_all straight away.
62
+ if (memory?.catchAll) {
63
+ return {
64
+ found: false,
65
+ email: null,
66
+ verdict: "catch_all",
67
+ confidence: 0.5,
68
+ catchAll: true,
69
+ candidatesChecked: 0,
70
+ creditsUsed: 0,
71
+ attempts: [],
72
+ reason: "cached_catch_all",
73
+ domain: cleanDomain,
74
+ mxProvider: memory.routing?.providerId ?? "unknown",
75
+ verifierUsed: "cache",
76
+ candidatesConsidered: candidates.length,
77
+ };
58
78
  }
59
- const consumer = (0, o365_1.isMicrosoftConsumerDomain)(cleanDomain);
60
- let namespace = null;
61
- let microsoftBacked = consumer || provider.microsoftBacked;
62
- // Only spend a realm lookup on ambiguous MX (not obviously Microsoft, not a
63
- // known foreign mailbox host) — that's where O365-behind-a-gateway hides.
64
- if (options.useO365 &&
65
- !microsoftBacked &&
66
- !(0, mx_fingerprint_1.hostsNonMicrosoftMailboxes)(provider)) {
67
- namespace = await (0, o365_1.getUserRealm)(cleanDomain, options.timeoutMs);
68
- if (namespace === "Managed") {
69
- microsoftBacked = true;
70
- }
79
+ const routing = await resolveRouting(cleanDomain, options, memory);
80
+ if (routing.kind === "dead") {
81
+ await persist(cache, cleanDomain, memory, {
82
+ dead: true,
83
+ deadReason: routing.reason,
84
+ });
85
+ return earlyExit(candidates.length, cleanDomain, routing.providerId, "invalid", routing.reason === "null_mx" ? 0.02 : 0.03, routing.reason);
71
86
  }
72
87
  let verifier;
73
88
  let verifierUsed;
74
- if (options.useO365 && microsoftBacked) {
75
- verifier = (0, o365_verifier_1.createO365Verifier)(namespace ?? "Managed", true, options.timeoutMs);
89
+ if (options.useO365 && routing.microsoftBacked) {
90
+ verifier = (0, o365_verifier_1.createO365Verifier)(routing.namespace ?? "Managed", true, options.timeoutMs);
76
91
  verifierUsed = "o365";
77
92
  }
78
93
  else if (options.no2bounceToken) {
@@ -83,20 +98,87 @@ async function findPersonEmail(firstName, lastName, domain, options) {
83
98
  verifierUsed = "no2bounce";
84
99
  }
85
100
  else {
86
- return earlyExit(candidates.length, cleanDomain, provider.id, "unknown", 0.5, "no2bounce_token_required");
101
+ return earlyExit(candidates.length, cleanDomain, routing.providerId, "unknown", 0.5, "no2bounce_token_required");
87
102
  }
88
103
  const result = await (0, find_email_1.findEmail)(candidates, verifier, {
89
104
  maxChecks: options.maxChecks,
90
105
  stopOnFirstHit: options.stopOnFirstHit,
91
106
  batchSize: verifierUsed === "no2bounce" ? NO2BOUNCE_BATCH_SIZE : 1,
92
107
  });
108
+ await learn(cache, cleanDomain, memory, result, candidateMeta, {
109
+ providerId: routing.providerId,
110
+ microsoftBacked: routing.microsoftBacked,
111
+ namespace: routing.namespace,
112
+ verifierUsed,
113
+ });
93
114
  return {
94
115
  ...result,
95
116
  reason: `${verifierUsed}_${result.verdict}`,
96
117
  domain: cleanDomain,
97
- mxProvider: provider.id,
118
+ mxProvider: routing.providerId,
98
119
  verifierUsed,
99
120
  candidatesConsidered: candidates.length,
100
121
  };
101
122
  }
123
+ /**
124
+ * Resolve mail routing for a domain, reusing a cached decision when present so
125
+ * the MX + getuserrealm round-trips (and their throttling) are skipped.
126
+ */
127
+ async function resolveRouting(cleanDomain, options, memory) {
128
+ if (memory?.routing) {
129
+ return {
130
+ kind: "live",
131
+ providerId: memory.routing.providerId,
132
+ microsoftBacked: memory.routing.microsoftBacked,
133
+ namespace: memory.routing.namespace,
134
+ };
135
+ }
136
+ const routing = await (0, dns_1.resolveMail)(cleanDomain);
137
+ const provider = (0, mx_fingerprint_1.fingerprintMx)(routing.hosts);
138
+ if (routing.nullMx) {
139
+ return { kind: "dead", providerId: provider.id, reason: "null_mx" };
140
+ }
141
+ if (routing.hosts.length === 0) {
142
+ return { kind: "dead", providerId: provider.id, reason: "no_mx_record" };
143
+ }
144
+ let namespace = null;
145
+ let microsoftBacked = (0, o365_1.isMicrosoftConsumerDomain)(cleanDomain) || provider.microsoftBacked;
146
+ // Only spend a realm lookup on ambiguous MX (not obviously Microsoft, not a
147
+ // known foreign mailbox host) — that's where O365-behind-a-gateway hides.
148
+ if (options.useO365 &&
149
+ !microsoftBacked &&
150
+ !(0, mx_fingerprint_1.hostsNonMicrosoftMailboxes)(provider)) {
151
+ namespace = await (0, o365_1.getUserRealm)(cleanDomain, options.timeoutMs);
152
+ if (namespace === "Managed") {
153
+ microsoftBacked = true;
154
+ }
155
+ }
156
+ return { kind: "live", providerId: provider.id, microsoftBacked, namespace };
157
+ }
158
+ async function persist(cache, domain, prior, patch) {
159
+ if (!cache) {
160
+ return;
161
+ }
162
+ await cache.set(domain, { ...prior, ...patch, updatedAt: Date.now() });
163
+ }
164
+ /** Record what this run taught us about the domain (routing, catch-all, pattern). */
165
+ async function learn(cache, domain, prior, result, candidateMeta, routing) {
166
+ if (!cache) {
167
+ return;
168
+ }
169
+ const patch = { routing };
170
+ if (result.found && result.email) {
171
+ // A real hit pins the domain's naming convention. We keep probing such
172
+ // domains even when the hit is accept-all (it still yields a probable
173
+ // address), so we record the pattern rather than flagging catch_all.
174
+ const hit = candidateMeta.find((c) => c.email === result.email);
175
+ if (hit && (0, patterns_1.isLearnablePatternId)(hit.patternId)) {
176
+ patch.patternId = hit.patternId;
177
+ }
178
+ }
179
+ else if (result.verdict === "catch_all") {
180
+ patch.catchAll = true;
181
+ }
182
+ await persist(cache, domain, prior, patch);
183
+ }
102
184
  //# sourceMappingURL=find-person.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"find-person.js","sourceRoot":"","sources":["../../../../src/lib/common/find-person.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"find-person.js","sourceRoot":"","sources":["../../../../src/lib/common/find-person.ts"],"names":[],"mappings":"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"}
@@ -28,7 +28,31 @@ export interface GenerateEmailsParams {
28
28
  patternSet?: PatternSet;
29
29
  /** Hard cap on candidates returned, applied after ordering. */
30
30
  maxVariants?: number;
31
+ /**
32
+ * A previously-learned winning pattern id for this domain. When supplied,
33
+ * the candidate produced by that pattern is moved to the front so the
34
+ * single first probe is most likely to hit (one credit instead of a round).
35
+ */
36
+ preferPatternId?: string;
31
37
  }
38
+ /** A generated candidate plus the id of the pattern that produced it. */
39
+ export interface EmailCandidate {
40
+ email: string;
41
+ local: string;
42
+ patternId: string;
43
+ }
44
+ /**
45
+ * True when a pattern id generalizes across people on the same domain (the
46
+ * primary block). Compound/standalone variants depend on the specific name, so
47
+ * they are not cached as a domain's naming convention.
48
+ */
49
+ export declare function isLearnablePatternId(id: string | undefined): boolean;
50
+ /**
51
+ * Generate de-duplicated candidates (with their pattern ids) ordered by
52
+ * likelihood. Returns an empty array when the domain or both name parts are
53
+ * missing. `generateEmailCandidates` wraps this for the string-only callers.
54
+ */
55
+ export declare function generateCandidates(params: GenerateEmailsParams): EmailCandidate[];
32
56
  /**
33
57
  * Generate a de-duplicated list of candidate emails ordered by likelihood.
34
58
  * Returns an empty array when the domain or both name parts are missing.
@@ -1 +1 @@
1
- {"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../../../src/lib/common/patterns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAeH,uDAAuD;AACvD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIvD;AAED,sEAAsE;AACtE,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQrD;AAED,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE1C,MAAM,WAAW,oBAAoB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAyFD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,EAAE,CAmF9E"}
1
+ {"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../../../src/lib/common/patterns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAeH,uDAAuD;AACvD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIvD;AAED,sEAAsE;AACtE,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQrD;AAED,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE1C,MAAM,WAAW,oBAAoB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,yEAAyE;AACzE,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACrB;AAQD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAOpE;AAmGD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAC9B,MAAM,EAAE,oBAAoB,GAC7B,cAAc,EAAE,CAkGlB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,EAAE,CAE9E"}
@@ -19,6 +19,8 @@
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
20
  exports.normalizeNamePart = normalizeNamePart;
21
21
  exports.normalizeDomain = normalizeDomain;
22
+ exports.isLearnablePatternId = isLearnablePatternId;
23
+ exports.generateCandidates = generateCandidates;
22
24
  exports.generateEmailCandidates = generateEmailCandidates;
23
25
  function stripDiacritics(input) {
24
26
  let result = "";
@@ -48,6 +50,22 @@ function normalizeDomain(value) {
48
50
  .replace(/\/.*$/, "")
49
51
  .replace(/\s+/g, "");
50
52
  }
53
+ // Sentinel ids for candidates produced outside the primary block. These are
54
+ // name/compound-specific, so they are never learned or preferred across people.
55
+ const ALT_ID = "alt";
56
+ const SURNAME_ID = "surname";
57
+ const GIVEN_ID = "given";
58
+ /**
59
+ * True when a pattern id generalizes across people on the same domain (the
60
+ * primary block). Compound/standalone variants depend on the specific name, so
61
+ * they are not cached as a domain's naming convention.
62
+ */
63
+ function isLearnablePatternId(id) {
64
+ return (id !== undefined &&
65
+ id !== ALT_ID &&
66
+ id !== SURNAME_ID &&
67
+ id !== GIVEN_ID);
68
+ }
51
69
  const LOCAL_PART_REGEX = /^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$/;
52
70
  /** Leading patterns that cover the large majority of real corporate addresses. */
53
71
  const COMMON_LIMIT = 10;
@@ -80,31 +98,27 @@ function coreSurname(tokens) {
80
98
  }
81
99
  return tokens.slice(i);
82
100
  }
83
- // Ordered by approximate real-world B2B frequency (most common first). Each
84
- // trailing comment names the produced local-part so the terse builders stay
85
- // readable. This order drives how many paid verifications an early-stop search
86
- // performs, so changing it changes credit cost.
87
101
  const PATTERNS = [
88
- (p) => join(p.first, ".", p.last), // first.last
89
- (p) => join(p.fi, "", p.last), // flast
90
- (p) => p.first, // first
91
- (p) => join(p.first, "", p.last), // firstlast
92
- (p) => join(p.first, "_", p.last), // first_last
93
- (p) => join(p.fi, ".", p.last), // f.last
94
- (p) => join(p.first, "-", p.last), // first-last
95
- (p) => p.last, // last
96
- (p) => join(p.last, ".", p.first), // last.first
97
- (p) => join(p.first, "", p.li), // firstl
98
- (p) => join(p.fi, "", p.li), // fl
99
- (p) => join(p.last, "", p.first), // lastfirst
100
- (p) => join(p.last, "_", p.first), // last_first
101
- (p) => join(p.last, "-", p.first), // last-first
102
- (p) => join(p.fi, "_", p.last), // f_last
103
- (p) => join(p.fi, "-", p.last), // f-last
104
- (p) => join(p.last, "", p.fi), // lastf
105
- (p) => join(p.last, ".", p.fi), // last.f
106
- (p) => join(p.li, "", p.fi), // lf
107
- (p) => join(p.first, ".", p.li), // first.l
102
+ { id: "first.last", build: (p) => join(p.first, ".", p.last) },
103
+ { id: "flast", build: (p) => join(p.fi, "", p.last) },
104
+ { id: "first", build: (p) => p.first },
105
+ { id: "firstlast", build: (p) => join(p.first, "", p.last) },
106
+ { id: "first_last", build: (p) => join(p.first, "_", p.last) },
107
+ { id: "f.last", build: (p) => join(p.fi, ".", p.last) },
108
+ { id: "first-last", build: (p) => join(p.first, "-", p.last) },
109
+ { id: "last", build: (p) => p.last },
110
+ { id: "last.first", build: (p) => join(p.last, ".", p.first) },
111
+ { id: "firstl", build: (p) => join(p.first, "", p.li) },
112
+ { id: "fl", build: (p) => join(p.fi, "", p.li) },
113
+ { id: "lastfirst", build: (p) => join(p.last, "", p.first) },
114
+ { id: "last_first", build: (p) => join(p.last, "_", p.first) },
115
+ { id: "last-first", build: (p) => join(p.last, "-", p.first) },
116
+ { id: "f_last", build: (p) => join(p.fi, "_", p.last) },
117
+ { id: "f-last", build: (p) => join(p.fi, "-", p.last) },
118
+ { id: "lastf", build: (p) => join(p.last, "", p.fi) },
119
+ { id: "last.f", build: (p) => join(p.last, ".", p.fi) },
120
+ { id: "lf", build: (p) => join(p.li, "", p.fi) },
121
+ { id: "first.l", build: (p) => join(p.first, ".", p.li) },
108
122
  ];
109
123
  // Applied to every alternate (first-form, last-form) combination to widen the
110
124
  // "all" set. Kept to the formats that actually appear in the wild so compound
@@ -119,10 +133,11 @@ const ALT_PATTERNS = [
119
133
  (f, l) => join(l, ".", f), // last.first
120
134
  ];
121
135
  /**
122
- * Generate a de-duplicated list of candidate emails ordered by likelihood.
123
- * Returns an empty array when the domain or both name parts are missing.
136
+ * Generate de-duplicated candidates (with their pattern ids) ordered by
137
+ * likelihood. Returns an empty array when the domain or both name parts are
138
+ * missing. `generateEmailCandidates` wraps this for the string-only callers.
124
139
  */
125
- function generateEmailCandidates(params) {
140
+ function generateCandidates(params) {
126
141
  const firstTokens = tokenize(params.firstName);
127
142
  const lastTokens = tokenize(params.lastName);
128
143
  const domain = normalizeDomain(params.domain);
@@ -154,10 +169,10 @@ function generateEmailCandidates(params) {
154
169
  fi: (firstPrimary || firstJoined).charAt(0),
155
170
  li: (lastMain || lastJoined).charAt(0),
156
171
  };
157
- const locals = [];
172
+ const raw = [];
158
173
  // Primary block — unchanged historical ordering, the slice "common" sees.
159
- for (const build of PATTERNS) {
160
- locals.push(build(primary));
174
+ for (const pattern of PATTERNS) {
175
+ raw.push({ local: pattern.build(primary), patternId: pattern.id });
161
176
  }
162
177
  // Alternate block — compound coverage, grouped by pattern so the dominant
163
178
  // first.last spread across name-forms lands ahead of rarer shapes.
@@ -167,30 +182,48 @@ function generateEmailCandidates(params) {
167
182
  if (f === firstJoined && l === lastJoined) {
168
183
  continue; // already produced by the primary block
169
184
  }
170
- locals.push(build(f, l));
185
+ raw.push({ local: build(f, l), patternId: ALT_ID });
171
186
  }
172
187
  }
173
188
  }
174
189
  // Standalone surname / given-name tokens (berg@, garcia@, jean@).
175
190
  for (const l of lastForms) {
176
- locals.push(l);
191
+ raw.push({ local: l, patternId: SURNAME_ID });
177
192
  }
178
193
  for (const f of firstForms) {
179
- locals.push(f);
194
+ raw.push({ local: f, patternId: GIVEN_ID });
180
195
  }
196
+ // A learned winning pattern for this domain jumps to the front (stable
197
+ // otherwise) so it becomes the single first probe.
198
+ const prioritized = params.preferPatternId !== undefined
199
+ ? [
200
+ ...raw.filter((c) => c.patternId === params.preferPatternId),
201
+ ...raw.filter((c) => c.patternId !== params.preferPatternId),
202
+ ]
203
+ : raw;
181
204
  const seen = new Set();
182
205
  const ordered = [];
183
- for (const local of locals) {
206
+ for (const candidate of prioritized) {
207
+ const { local } = candidate;
184
208
  if (!local || seen.has(local) || !LOCAL_PART_REGEX.test(local)) {
185
209
  continue;
186
210
  }
187
211
  seen.add(local);
188
- ordered.push(local);
212
+ ordered.push(candidate);
189
213
  }
190
214
  const limit = params.maxVariants ??
191
215
  (params.patternSet === "common" ? COMMON_LIMIT : ordered.length);
192
- return ordered
193
- .slice(0, Math.max(0, limit))
194
- .map((local) => `${local}@${domain}`);
216
+ return ordered.slice(0, Math.max(0, limit)).map(({ local, patternId }) => ({
217
+ email: `${local}@${domain}`,
218
+ local,
219
+ patternId,
220
+ }));
221
+ }
222
+ /**
223
+ * Generate a de-duplicated list of candidate emails ordered by likelihood.
224
+ * Returns an empty array when the domain or both name parts are missing.
225
+ */
226
+ function generateEmailCandidates(params) {
227
+ return generateCandidates(params).map((c) => c.email);
195
228
  }
196
229
  //# sourceMappingURL=patterns.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../../../src/lib/common/patterns.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../../../src/lib/common/patterns.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;GAgBG;;AAgBH,8CAIC;AAGD,0CAQC;AAsCD,oDAOC;AAwGD,gDAoGC;AAMD,0DAEC;AA9RD,SAAS,eAAe,CAAC,KAAa;IAClC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACtC,oDAAoD;QACpD,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;YACnC,SAAS;QACb,CAAC;QACD,MAAM,IAAI,IAAI,CAAC;IACnB,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,uDAAuD;AACvD,SAAgB,iBAAiB,CAAC,KAAa;IAC3C,OAAO,eAAe,CAAC,KAAK,IAAI,EAAE,CAAC;SAC9B,WAAW,EAAE;SACb,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;AACnC,CAAC;AAED,sEAAsE;AACtE,SAAgB,eAAe,CAAC,KAAa;IACzC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;SACf,IAAI,EAAE;SACN,WAAW,EAAE;SACb,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;SAC3B,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;SACjB,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;SACpB,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAC7B,CAAC;AA2BD,4EAA4E;AAC5E,gFAAgF;AAChF,MAAM,MAAM,GAAG,KAAK,CAAC;AACrB,MAAM,UAAU,GAAG,SAAS,CAAC;AAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC;AAEzB;;;;GAIG;AACH,SAAgB,oBAAoB,CAAC,EAAsB;IACvD,OAAO,CACH,EAAE,KAAK,SAAS;QAChB,EAAE,KAAK,MAAM;QACb,EAAE,KAAK,UAAU;QACjB,EAAE,KAAK,QAAQ,CAClB,CAAC;AACN,CAAC;AASD,MAAM,gBAAgB,GAAG,mCAAmC,CAAC;AAE7D,kFAAkF;AAClF,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB;;;;GAIG;AACH,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAC9B,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK;IAC1E,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG;CAC/E,CAAC,CAAC;AAEH,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,GAAW,EAAE,CAAS,EAAU,EAAE,CACvD,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAEnC,MAAM,IAAI,GAAG,CAAC,MAAgB,EAAY,EAAE,CAAC;IACzC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;CACrC,CAAC;AAEF,mFAAmF;AACnF,SAAS,QAAQ,CAAC,KAAa;IAC3B,OAAO,eAAe,CAAC,KAAK,IAAI,EAAE,CAAC;SAC9B,WAAW,EAAE;SACb,KAAK,CAAC,UAAU,CAAC;SACjB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;SAC/C,MAAM,CAAC,OAAO,CAAC,CAAC;AACzB,CAAC;AAED,sEAAsE;AACtE,SAAS,WAAW,CAAC,MAAgB;IACjC,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,CAAC,EAAE,CAAC;IACR,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC3B,CAAC;AAWD,MAAM,QAAQ,GAAc;IACxB,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE;IAC9D,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE;IACrD,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE;IACtC,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE;IAC5D,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE;IAC9D,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE;IACvD,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE;IAC9D,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE;IACpC,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE;IAC9D,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE;IACvD,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE;IAChD,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE;IAC5D,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE;IAC9D,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE;IAC9D,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE;IACvD,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE;IACvD,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE;IACrD,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE;IACvD,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE;IAChD,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE;CAC5D,CAAC;AAEF,8EAA8E;AAC9E,8EAA8E;AAC9E,kCAAkC;AAClC,MAAM,YAAY,GAAyC;IACvD,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,wBAAwB;IACnD,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU;IAC9C,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,wBAAwB;IAClD,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,wBAAwB;IACnD,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,wBAAwB;IACnD,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW;IAChD,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,wBAAwB;CACtD,CAAC;AAOF;;;;GAIG;AACH,SAAgB,kBAAkB,CAC9B,MAA4B;IAE5B,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC/C,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAE9C,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEvC,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,WAAW,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3C,OAAO,EAAE,CAAC;IACd,CAAC;IAED,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;IACzC,MAAM,YAAY,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1C,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAErD,6EAA6E;IAC7E,yEAAyE;IACzE,8EAA8E;IAC9E,MAAM,UAAU,GAAG,IAAI,CAAC;QACpB,WAAW;QACX,YAAY;QACZ,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;KAC7E,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,IAAI,CAAC;QACnB,UAAU;QACV,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACjB,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE;QACjB,QAAQ;KACX,CAAC,CAAC;IAEH,MAAM,OAAO,GAAc;QACvB,KAAK,EAAE,WAAW;QAClB,IAAI,EAAE,UAAU;QAChB,EAAE,EAAE,CAAC,YAAY,IAAI,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3C,EAAE,EAAE,CAAC,QAAQ,IAAI,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;KACzC,CAAC;IAEF,MAAM,GAAG,GAAmB,EAAE,CAAC;IAE/B,0EAA0E;IAC1E,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC7B,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,0EAA0E;IAC1E,mEAAmE;IACnE,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;QAC/B,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;YACzB,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;gBACxB,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,KAAK,UAAU,EAAE,CAAC;oBACxC,SAAS,CAAC,wCAAwC;gBACtD,CAAC;gBACD,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;YACxD,CAAC;QACL,CAAC;IACL,CAAC;IAED,kEAAkE;IAClE,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QACxB,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC;IAClD,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QACzB,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,uEAAuE;IACvE,mDAAmD;IACnD,MAAM,WAAW,GACb,MAAM,CAAC,eAAe,KAAK,SAAS;QAChC,CAAC,CAAC;YACI,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,MAAM,CAAC,eAAe,CAAC;YAC5D,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,MAAM,CAAC,eAAe,CAAC;SAC/D;QACH,CAAC,CAAC,GAAG,CAAC;IAEd,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,OAAO,GAAmB,EAAE,CAAC;IACnC,KAAK,MAAM,SAAS,IAAI,WAAW,EAAE,CAAC;QAClC,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7D,SAAS;QACb,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAChB,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC5B,CAAC;IAED,MAAM,KAAK,GACP,MAAM,CAAC,WAAW;QAClB,CAAC,MAAM,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAErE,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAC3C,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAkB,EAAE,CAAC,CAAC;QACvC,KAAK,EAAE,GAAG,KAAK,IAAI,MAAM,EAAE;QAC3B,KAAK;QACL,SAAS;KACZ,CAAC,CACL,CAAC;AACN,CAAC;AAED;;;GAGG;AACH,SAAgB,uBAAuB,CAAC,MAA4B;IAChE,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AAC1D,CAAC"}