open-local-audit 0.67.0 → 0.68.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/README.md +13 -1
- package/dist/cli.js +21 -2
- package/dist/cli.js.map +1 -1
- package/dist/discovery-location.d.ts +13 -0
- package/dist/discovery-location.js +99 -0
- package/dist/discovery-location.js.map +1 -0
- package/dist/discovery-runner.d.ts +26 -0
- package/dist/discovery-runner.js +70 -6
- package/dist/discovery-runner.js.map +1 -1
- package/dist/discovery.d.ts +15 -3
- package/dist/discovery.js +56 -12
- package/dist/discovery.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/overture.d.ts +13 -0
- package/dist/overture.js +319 -0
- package/dist/overture.js.map +1 -0
- package/dist/schema.d.ts +19 -4
- package/dist/schema.js +6 -1
- package/dist/schema.js.map +1 -1
- package/dist/website-enrichment.d.ts +21 -0
- package/dist/website-enrichment.js +400 -0
- package/dist/website-enrichment.js.map +1 -0
- package/dist/workflow-config.d.ts +46 -1
- package/dist/workflow-config.js +17 -1
- package/dist/workflow-config.js.map +1 -1
- package/dist/workflow-plan.d.ts +1 -1
- package/dist/workflow-plan.js +4 -1
- package/dist/workflow-plan.js.map +1 -1
- package/dist/workflow-preflight.d.ts +1 -1
- package/dist/workflow-preflight.js +2 -2
- package/dist/workflow-preflight.js.map +1 -1
- package/dist/workflow.js +2 -1
- package/dist/workflow.js.map +1 -1
- package/docs/architecture/workflow-command.md +1 -1
- package/docs/guides/free-discovery.md +87 -0
- package/package.json +10 -4
package/dist/overture.js
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import { isIP } from "node:net";
|
|
2
|
+
import { DuckDBInstance } from "@duckdb/node-api";
|
|
3
|
+
import { maximumDiscoveryBboxSpan } from "./discovery-location.js";
|
|
4
|
+
const overtureStacUrl = "https://stac.overturemaps.org/catalog.json";
|
|
5
|
+
const overturePlacesGuideUrl = "https://docs.overturemaps.org/guides/places/";
|
|
6
|
+
const overtureS3BaseUrl = "s3://overturemaps-us-west-2/release";
|
|
7
|
+
const defaultLimit = 25;
|
|
8
|
+
const maximumLimit = 100;
|
|
9
|
+
const defaultTimeoutMs = 90_000;
|
|
10
|
+
const minimumConfidence = 0.5;
|
|
11
|
+
const releasePattern = /^\d{4}-\d{2}-\d{2}\.\d+$/;
|
|
12
|
+
const categoryPattern = /^[a-z][a-z0-9_]{0,80}$/;
|
|
13
|
+
const socialProfileHosts = ["facebook.com", "instagram.com", "linkedin.com", "x.com", "twitter.com", "tiktok.com", "youtube.com", "wa.me", "whatsapp.com"];
|
|
14
|
+
const shortLinkHosts = ["fbf.bz", "fb.me", "bit.ly", "tinyurl.com", "t.co", "goo.gl", "maps.app.goo.gl", "linktr.ee"];
|
|
15
|
+
export const overtureCategoryMappings = {
|
|
16
|
+
dental: ["dentist", "dental_clinic"],
|
|
17
|
+
restaurant: ["restaurant"],
|
|
18
|
+
beauty: ["beauty_salon", "hair_salon", "nail_salon", "spa"],
|
|
19
|
+
hotel: ["hotel", "motel", "resort_hotel"],
|
|
20
|
+
gym: ["gym", "fitness_center"]
|
|
21
|
+
};
|
|
22
|
+
function stringOrUndefined(value) {
|
|
23
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
24
|
+
}
|
|
25
|
+
function stringList(value) {
|
|
26
|
+
return Array.isArray(value)
|
|
27
|
+
? value.map(stringOrUndefined).filter((item) => item !== undefined)
|
|
28
|
+
: [];
|
|
29
|
+
}
|
|
30
|
+
function numberOrUndefined(value) {
|
|
31
|
+
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
32
|
+
}
|
|
33
|
+
function isPublicHttpUrl(value) {
|
|
34
|
+
try {
|
|
35
|
+
const url = new URL(value);
|
|
36
|
+
const host = url.hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
37
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
if (url.username || url.password || host === "localhost" || host.endsWith(".localhost")) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
if (isIP(host) === 4) {
|
|
44
|
+
const octets = host.split(".").map(Number);
|
|
45
|
+
return !(octets[0] === 0 ||
|
|
46
|
+
octets[0] === 10 ||
|
|
47
|
+
octets[0] === 127 ||
|
|
48
|
+
(octets[0] === 169 && octets[1] === 254) ||
|
|
49
|
+
(octets[0] === 172 && octets[1] >= 16 && octets[1] <= 31) ||
|
|
50
|
+
(octets[0] === 192 && octets[1] === 168));
|
|
51
|
+
}
|
|
52
|
+
if (isIP(host) === 6) {
|
|
53
|
+
const mappedIpv4 = host.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/i)?.[1];
|
|
54
|
+
return !(host === "::1" ||
|
|
55
|
+
host.startsWith("fc") ||
|
|
56
|
+
host.startsWith("fd") ||
|
|
57
|
+
host.startsWith("fe80:") ||
|
|
58
|
+
(mappedIpv4 !== undefined && !isPublicHttpUrl(`http://${mappedIpv4}`)));
|
|
59
|
+
}
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function firstPublicHttpUrl(value) {
|
|
67
|
+
const website = stringList(value).find((url) => isPublicHttpUrl(url) && !hasHost(url, socialProfileHosts) && !hasHost(url, shortLinkHosts));
|
|
68
|
+
return website ? new URL(website).toString() : undefined;
|
|
69
|
+
}
|
|
70
|
+
function hasHost(value, hosts) {
|
|
71
|
+
try {
|
|
72
|
+
const host = new URL(value).hostname.toLowerCase();
|
|
73
|
+
return hosts.some((entry) => host === entry || host.endsWith(`.${entry}`));
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function sourceItems(value) {
|
|
80
|
+
return Array.isArray(value) ? value.filter((item) => typeof item === "object" && item !== null) : [];
|
|
81
|
+
}
|
|
82
|
+
function sourceUrl(item) {
|
|
83
|
+
const provider = stringOrUndefined(item.provider)?.toLowerCase();
|
|
84
|
+
const recordId = stringOrUndefined(item.record_id);
|
|
85
|
+
if ((provider === "meta" || provider === "facebook") && recordId && /^\d+$/.test(recordId)) {
|
|
86
|
+
return `https://www.facebook.com/${recordId}`;
|
|
87
|
+
}
|
|
88
|
+
if (provider === "osm" && recordId) {
|
|
89
|
+
const match = recordId.match(/^([nwr])(\d+)(?:@\d+)?$/);
|
|
90
|
+
if (match) {
|
|
91
|
+
const type = match[1] === "n" ? "node" : match[1] === "w" ? "way" : "relation";
|
|
92
|
+
return `https://www.openstreetmap.org/${type}/${match[2]}`;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const resource = stringOrUndefined(item.resource);
|
|
96
|
+
return resource && isPublicHttpUrl(resource) ? new URL(resource).toString() : undefined;
|
|
97
|
+
}
|
|
98
|
+
function sourceProvenance(items) {
|
|
99
|
+
return items.map((item) => {
|
|
100
|
+
const entry = {};
|
|
101
|
+
const fields = [
|
|
102
|
+
["provider", item.provider],
|
|
103
|
+
["dataset", item.dataset],
|
|
104
|
+
["license", item.license],
|
|
105
|
+
["recordId", item.record_id],
|
|
106
|
+
["resource", item.resource],
|
|
107
|
+
["version", item.version],
|
|
108
|
+
["updateTime", item.update_time]
|
|
109
|
+
];
|
|
110
|
+
for (const [name, value] of fields) {
|
|
111
|
+
const normalized = stringOrUndefined(value);
|
|
112
|
+
if (normalized) {
|
|
113
|
+
entry[name] = normalized;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return entry;
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
function validateBoundingBox(bbox) {
|
|
120
|
+
const [west, south, east, north] = bbox;
|
|
121
|
+
if (![west, south, east, north].every(Number.isFinite)) {
|
|
122
|
+
throw new Error("Bounding box coordinates must be finite numbers");
|
|
123
|
+
}
|
|
124
|
+
if (west < -180 || east > 180 || south < -90 || north > 90) {
|
|
125
|
+
throw new Error("Bounding box coordinates are outside WGS84 limits");
|
|
126
|
+
}
|
|
127
|
+
if (west >= east || south >= north) {
|
|
128
|
+
throw new Error("Bounding box must have west < east and south < north");
|
|
129
|
+
}
|
|
130
|
+
if (east - west > maximumDiscoveryBboxSpan || north - south > maximumDiscoveryBboxSpan) {
|
|
131
|
+
throw new Error(`Bounding box must span at most ${maximumDiscoveryBboxSpan} degrees per axis`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function resolveCategories(category) {
|
|
135
|
+
const normalized = category.trim().toLowerCase();
|
|
136
|
+
if (!categoryPattern.test(normalized)) {
|
|
137
|
+
throw new Error("Unsupported Overture category");
|
|
138
|
+
}
|
|
139
|
+
return overtureCategoryMappings[normalized] ?? [normalized];
|
|
140
|
+
}
|
|
141
|
+
function normalizeLimit(limit) {
|
|
142
|
+
if (limit === undefined) {
|
|
143
|
+
return defaultLimit;
|
|
144
|
+
}
|
|
145
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > maximumLimit) {
|
|
146
|
+
throw new Error(`Overture limit must be an integer between 1 and ${maximumLimit}`);
|
|
147
|
+
}
|
|
148
|
+
return limit;
|
|
149
|
+
}
|
|
150
|
+
function normalizeTimeout(timeoutMs) {
|
|
151
|
+
if (timeoutMs === undefined) {
|
|
152
|
+
return defaultTimeoutMs;
|
|
153
|
+
}
|
|
154
|
+
if (!Number.isInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 120_000) {
|
|
155
|
+
throw new Error("Overture timeout must be an integer between 1 and 120000ms");
|
|
156
|
+
}
|
|
157
|
+
return timeoutMs;
|
|
158
|
+
}
|
|
159
|
+
function validateRelease(release) {
|
|
160
|
+
if (!releasePattern.test(release)) {
|
|
161
|
+
throw new Error("Invalid Overture release");
|
|
162
|
+
}
|
|
163
|
+
return release;
|
|
164
|
+
}
|
|
165
|
+
async function fetchLatestRelease(timeoutMs) {
|
|
166
|
+
let response;
|
|
167
|
+
try {
|
|
168
|
+
response = await fetch(overtureStacUrl, { signal: AbortSignal.timeout(timeoutMs) });
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
throw new Error(`Unable to retrieve the current Overture release: ${error instanceof Error ? error.message : String(error)}`);
|
|
172
|
+
}
|
|
173
|
+
if (!response.ok) {
|
|
174
|
+
throw new Error(`Unable to retrieve the current Overture release: STAC returned HTTP ${response.status}`);
|
|
175
|
+
}
|
|
176
|
+
const body = await response.json();
|
|
177
|
+
const release = typeof body === "object" && body !== null ? body.latest : undefined;
|
|
178
|
+
return validateRelease(stringOrUndefined(release) ?? "");
|
|
179
|
+
}
|
|
180
|
+
function categorySql(categories) {
|
|
181
|
+
return categories.map((category) => `'${category}'`).join(", ");
|
|
182
|
+
}
|
|
183
|
+
function buildQuery(release, categories) {
|
|
184
|
+
const source = `${overtureS3BaseUrl}/${release}/theme=places/type=place/*`;
|
|
185
|
+
return `
|
|
186
|
+
SELECT
|
|
187
|
+
id,
|
|
188
|
+
names.primary AS label,
|
|
189
|
+
addresses[1].freeform AS address,
|
|
190
|
+
addresses[1].country AS country,
|
|
191
|
+
addresses[1].locality AS locality,
|
|
192
|
+
addresses[1].region AS region,
|
|
193
|
+
bbox.ymin AS latitude,
|
|
194
|
+
bbox.xmin AS longitude,
|
|
195
|
+
websites,
|
|
196
|
+
phones,
|
|
197
|
+
emails,
|
|
198
|
+
socials,
|
|
199
|
+
sources,
|
|
200
|
+
confidence,
|
|
201
|
+
operating_status
|
|
202
|
+
FROM read_parquet('${source}')
|
|
203
|
+
WHERE bbox.xmin BETWEEN $west AND $east
|
|
204
|
+
AND bbox.ymin BETWEEN $south AND $north
|
|
205
|
+
AND (
|
|
206
|
+
taxonomy.primary IN (${categorySql(categories)})
|
|
207
|
+
OR list_has_any(taxonomy.hierarchy, [${categorySql(categories)}])
|
|
208
|
+
)
|
|
209
|
+
AND (confidence IS NULL OR confidence >= ${minimumConfidence})
|
|
210
|
+
AND (operating_status IS NULL OR lower(operating_status) <> 'closed_permanently')
|
|
211
|
+
ORDER BY id ASC
|
|
212
|
+
LIMIT $limit
|
|
213
|
+
`;
|
|
214
|
+
}
|
|
215
|
+
async function runWithinDeadline(operation, connection, deadline, timeoutMs) {
|
|
216
|
+
const settledOperation = Promise.resolve(operation);
|
|
217
|
+
const remainingMs = deadline - Date.now();
|
|
218
|
+
const timeoutError = new Error(`Overture query timed out after ${timeoutMs}ms`);
|
|
219
|
+
if (remainingMs <= 0) {
|
|
220
|
+
connection.interrupt();
|
|
221
|
+
void settledOperation.catch(() => undefined);
|
|
222
|
+
throw timeoutError;
|
|
223
|
+
}
|
|
224
|
+
let timer;
|
|
225
|
+
let timedOut = false;
|
|
226
|
+
try {
|
|
227
|
+
return await Promise.race([
|
|
228
|
+
settledOperation,
|
|
229
|
+
new Promise((_resolve, reject) => {
|
|
230
|
+
timer = setTimeout(() => {
|
|
231
|
+
timedOut = true;
|
|
232
|
+
reject(timeoutError);
|
|
233
|
+
queueMicrotask(() => connection.interrupt());
|
|
234
|
+
}, remainingMs);
|
|
235
|
+
})
|
|
236
|
+
]);
|
|
237
|
+
}
|
|
238
|
+
finally {
|
|
239
|
+
if (timer) {
|
|
240
|
+
clearTimeout(timer);
|
|
241
|
+
}
|
|
242
|
+
if (timedOut) {
|
|
243
|
+
void settledOperation.catch(() => undefined);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
function mapCandidate(row, category, defaultProfile, release, retrievedAt) {
|
|
248
|
+
const sourceId = stringOrUndefined(row.id);
|
|
249
|
+
if (!sourceId) {
|
|
250
|
+
return undefined;
|
|
251
|
+
}
|
|
252
|
+
const sources = sourceItems(row.sources);
|
|
253
|
+
const sourceUrls = [...new Set(sources.map(sourceUrl).filter((url) => url !== undefined))];
|
|
254
|
+
const candidate = {
|
|
255
|
+
source: "overture",
|
|
256
|
+
sourceId,
|
|
257
|
+
label: stringOrUndefined(row.label),
|
|
258
|
+
segment: category,
|
|
259
|
+
profile: defaultProfile,
|
|
260
|
+
sourceMetadata: {
|
|
261
|
+
address: stringOrUndefined(row.address),
|
|
262
|
+
country: stringOrUndefined(row.country),
|
|
263
|
+
locality: stringOrUndefined(row.locality),
|
|
264
|
+
region: stringOrUndefined(row.region),
|
|
265
|
+
latitude: numberOrUndefined(row.latitude),
|
|
266
|
+
longitude: numberOrUndefined(row.longitude),
|
|
267
|
+
phones: stringList(row.phones),
|
|
268
|
+
emails: stringList(row.emails),
|
|
269
|
+
socials: [...new Set([...stringList(row.socials).filter(isPublicHttpUrl), ...stringList(row.websites).filter((url) => isPublicHttpUrl(url) && hasHost(url, socialProfileHosts))])],
|
|
270
|
+
confidence: numberOrUndefined(row.confidence),
|
|
271
|
+
operatingStatus: stringOrUndefined(row.operating_status),
|
|
272
|
+
datasetRelease: release,
|
|
273
|
+
sourceUrl: sourceUrls[0] ?? overturePlacesGuideUrl,
|
|
274
|
+
sourceUrls,
|
|
275
|
+
sourceProvenance: sourceProvenance(sources),
|
|
276
|
+
retrievedAt
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
const websiteUri = firstPublicHttpUrl(row.websites);
|
|
280
|
+
return websiteUri ? { ...candidate, websiteUri } : candidate;
|
|
281
|
+
}
|
|
282
|
+
export async function fetchOvertureCandidates(options) {
|
|
283
|
+
validateBoundingBox(options.bbox);
|
|
284
|
+
const categories = resolveCategories(options.category);
|
|
285
|
+
const limit = normalizeLimit(options.limit);
|
|
286
|
+
const timeoutMs = normalizeTimeout(options.timeoutMs);
|
|
287
|
+
const deadline = Date.now() + timeoutMs;
|
|
288
|
+
const release = options.release ? validateRelease(options.release) : await fetchLatestRelease(Math.max(1, deadline - Date.now()));
|
|
289
|
+
const [west, south, east, north] = options.bbox;
|
|
290
|
+
const instance = await DuckDBInstance.create(":memory:", { threads: "2", memory_limit: "256MB" });
|
|
291
|
+
let connection;
|
|
292
|
+
try {
|
|
293
|
+
connection = await instance.connect();
|
|
294
|
+
await runWithinDeadline(connection.run("INSTALL httpfs"), connection, deadline, timeoutMs);
|
|
295
|
+
await runWithinDeadline(connection.run("LOAD httpfs"), connection, deadline, timeoutMs);
|
|
296
|
+
await runWithinDeadline(connection.run("SET http_timeout=15"), connection, deadline, timeoutMs);
|
|
297
|
+
await runWithinDeadline(connection.run("SET http_retries=1"), connection, deadline, timeoutMs);
|
|
298
|
+
await runWithinDeadline(connection.run("SET s3_region='us-west-2'"), connection, deadline, timeoutMs);
|
|
299
|
+
const reader = await runWithinDeadline(connection.runAndReadAll(buildQuery(release, categories), { west, south, east, north, limit }), connection, deadline, timeoutMs);
|
|
300
|
+
const retrievedAt = new Date().toISOString();
|
|
301
|
+
const candidates = reader
|
|
302
|
+
.getRowObjectsJS()
|
|
303
|
+
.map((row) => mapCandidate(row, options.category.trim().toLowerCase(), options.defaultProfile, release, retrievedAt))
|
|
304
|
+
.filter((candidate) => candidate !== undefined)
|
|
305
|
+
.filter((candidate) => {
|
|
306
|
+
const metadata = candidate.sourceMetadata ?? {};
|
|
307
|
+
const confidence = numberOrUndefined(metadata.confidence);
|
|
308
|
+
const operatingStatus = stringOrUndefined(metadata.operatingStatus)?.toLowerCase();
|
|
309
|
+
return operatingStatus !== "closed_permanently" && (confidence === undefined || confidence >= minimumConfidence);
|
|
310
|
+
})
|
|
311
|
+
.sort((left, right) => left.sourceId.localeCompare(right.sourceId));
|
|
312
|
+
return candidates.filter((candidate, index) => index === 0 || candidate.sourceId !== candidates[index - 1]?.sourceId);
|
|
313
|
+
}
|
|
314
|
+
finally {
|
|
315
|
+
connection?.closeSync();
|
|
316
|
+
instance.closeSync();
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
//# sourceMappingURL=overture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overture.js","sourceRoot":"","sources":["../src/overture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,cAAc,EAAkD,MAAM,kBAAkB,CAAC;AAGlG,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAanE,MAAM,eAAe,GAAG,4CAA4C,CAAC;AACrE,MAAM,sBAAsB,GAAG,8CAA8C,CAAC;AAC9E,MAAM,iBAAiB,GAAG,qCAAqC,CAAC;AAChE,MAAM,YAAY,GAAG,EAAE,CAAC;AACxB,MAAM,YAAY,GAAG,GAAG,CAAC;AACzB,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAChC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAC9B,MAAM,cAAc,GAAG,0BAA0B,CAAC;AAClD,MAAM,eAAe,GAAG,wBAAwB,CAAC;AACjD,MAAM,kBAAkB,GAAG,CAAC,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;AAC3J,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,EAAE,WAAW,CAAC,CAAC;AAEtH,MAAM,CAAC,MAAM,wBAAwB,GAAgD;IACnF,MAAM,EAAE,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,UAAU,EAAE,CAAC,YAAY,CAAC;IAC1B,MAAM,EAAE,CAAC,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,CAAC;IAC3D,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC;IACzC,GAAG,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC;CAC/B,CAAC;AA8BF,SAAS,iBAAiB,CAAC,KAAc;IACvC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9E,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACzB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC;QACnF,CAAC,CAAC,EAAE,CAAC;AACT,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc;IACvC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACjF,CAAC;AAED,SAAS,eAAe,CAAC,KAAa;IACpC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAChE,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1D,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACxF,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACrB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC3C,OAAO,CAAC,CACN,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;gBACf,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE;gBAChB,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG;gBACjB,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC;gBACxC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBACzD,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CACzC,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACrB,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,gCAAgC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACrE,OAAO,CAAC,CACN,IAAI,KAAK,KAAK;gBACd,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;gBACrB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;gBACrB,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;gBACxB,CAAC,UAAU,KAAK,SAAS,IAAI,CAAC,eAAe,CAAC,UAAU,UAAU,EAAE,CAAC,CAAC,CACvE,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAc;IACxC,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC;IAC5I,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3D,CAAC;AAED,SAAS,OAAO,CAAC,KAAa,EAAE,KAAwB;IACtD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QACnD,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC;IAC7E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAA8B,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACnI,CAAC;AAED,SAAS,SAAS,CAAC,IAAwB;IACzC,MAAM,QAAQ,GAAG,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACjE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACnD,IAAI,CAAC,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,UAAU,CAAC,IAAI,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3F,OAAO,4BAA4B,QAAQ,EAAE,CAAC;IAChD,CAAC;IACD,IAAI,QAAQ,KAAK,KAAK,IAAI,QAAQ,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACxD,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC;YAC/E,OAAO,iCAAiC,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,CAAC;IACH,CAAC;IACD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClD,OAAO,QAAQ,IAAI,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC1F,CAAC;AAED,SAAS,gBAAgB,CAAC,KAA2B;IACnD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACxB,MAAM,KAAK,GAA2B,EAAE,CAAC;QACzC,MAAM,MAAM,GAA6B;YACvC,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC;YAC3B,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC;YACzB,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC;YACzB,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC;YAC5B,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC;YAC3B,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC;YACzB,CAAC,YAAY,EAAE,IAAI,CAAC,WAAW,CAAC;SACjC,CAAC;QACF,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;YACnC,MAAM,UAAU,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;YAC5C,IAAI,UAAU,EAAE,CAAC;gBACf,KAAK,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC;YAC3B,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAiB;IAC5C,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC;IACxC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IACD,IAAI,IAAI,GAAG,CAAC,GAAG,IAAI,IAAI,GAAG,GAAG,IAAI,KAAK,GAAG,CAAC,EAAE,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,IAAI,GAAG,IAAI,GAAG,wBAAwB,IAAI,KAAK,GAAG,KAAK,GAAG,wBAAwB,EAAE,CAAC;QACvF,MAAM,IAAI,KAAK,CAAC,kCAAkC,wBAAwB,mBAAmB,CAAC,CAAC;IACjG,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,QAAgB;IACzC,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACjD,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,wBAAwB,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,cAAc,CAAC,KAAyB;IAC/C,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,YAAY,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,mDAAmD,YAAY,EAAE,CAAC,CAAC;IACrF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,gBAAgB,CAAC,SAA6B;IACrD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,CAAC,IAAI,SAAS,GAAG,OAAO,EAAE,CAAC;QACzE,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,eAAe,CAAC,OAAe;IACtC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,SAAiB;IACjD,IAAI,QAAkB,CAAC;IACvB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,KAAK,CAAC,eAAe,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACtF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,oDAAoD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAChI,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,uEAAuE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5G,CAAC;IACD,MAAM,IAAI,GAAY,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC5C,MAAM,OAAO,GAAG,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC,CAAE,IAA6B,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9G,OAAO,eAAe,CAAC,iBAAiB,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,WAAW,CAAC,UAA6B;IAChD,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,UAAU,CAAC,OAAe,EAAE,UAA6B;IAChE,MAAM,MAAM,GAAG,GAAG,iBAAiB,IAAI,OAAO,4BAA4B,CAAC;IAC3E,OAAO;;;;;;;;;;;;;;;;;yBAiBgB,MAAM;;;;+BAIA,WAAW,CAAC,UAAU,CAAC;+CACP,WAAW,CAAC,UAAU,CAAC;;iDAErB,iBAAiB;;;;GAI/D,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,iBAAiB,CAC9B,SAAqB,EACrB,UAA4B,EAC5B,QAAgB,EAChB,SAAiB;IAEjB,MAAM,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,WAAW,GAAG,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC1C,MAAM,YAAY,GAAG,IAAI,KAAK,CAAC,kCAAkC,SAAS,IAAI,CAAC,CAAC;IAChF,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;QACrB,UAAU,CAAC,SAAS,EAAE,CAAC;QACvB,KAAK,gBAAgB,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC7C,MAAM,YAAY,CAAC;IACrB,CAAC;IACD,IAAI,KAAiC,CAAC;IACtC,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC;YACxB,gBAAgB;YAChB,IAAI,OAAO,CAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE;gBACtC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;oBACtB,QAAQ,GAAG,IAAI,CAAC;oBAChB,MAAM,CAAC,YAAY,CAAC,CAAC;oBACrB,cAAc,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC,CAAC;gBAC/C,CAAC,EAAE,WAAW,CAAC,CAAC;YAClB,CAAC,CAAC;SACH,CAAC,CAAC;IACL,CAAC;YAAS,CAAC;QACT,IAAI,KAAK,EAAE,CAAC;YACV,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;QACD,IAAI,QAAQ,EAAE,CAAC;YACb,KAAK,gBAAgB,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CACnB,GAAqB,EACrB,QAAgB,EAChB,cAAwC,EACxC,OAAe,EACf,WAAmB;IAEnB,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC3C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAiB,EAAE,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC;IAC1G,MAAM,SAAS,GAAmB;QAChC,MAAM,EAAE,UAAU;QAClB,QAAQ;QACR,KAAK,EAAE,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC;QACnC,OAAO,EAAE,QAAQ;QACjB,OAAO,EAAE,cAAc;QACvB,cAAc,EAAE;YACd,OAAO,EAAE,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC;YACvC,OAAO,EAAE,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC;YACvC,QAAQ,EAAE,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC;YACzC,MAAM,EAAE,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC;YACrC,QAAQ,EAAE,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC;YACzC,SAAS,EAAE,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC;YAC3C,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC;YAC9B,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC;YAC9B,OAAO,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;YAClL,UAAU,EAAE,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC;YAC7C,eAAe,EAAE,iBAAiB,CAAC,GAAG,CAAC,gBAAgB,CAAC;YACxD,cAAc,EAAE,OAAO;YACvB,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,sBAAsB;YAClD,UAAU;YACV,gBAAgB,EAAE,gBAAgB,CAAC,OAAO,CAAC;YAC3C,WAAW;SACZ;KACF,CAAC;IACF,MAAM,UAAU,GAAG,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACpD,OAAO,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC/D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,OAAuC;IACnF,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,gBAAgB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IACxC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAClI,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAChD,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,CAAC;IAClG,IAAI,UAAwC,CAAC;IAE7C,IAAI,CAAC;QACH,UAAU,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC;QACtC,MAAM,iBAAiB,CAAC,UAAU,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC3F,MAAM,iBAAiB,CAAC,UAAU,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;QACxF,MAAM,iBAAiB,CAAC,UAAU,CAAC,GAAG,CAAC,qBAAqB,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;QAChG,MAAM,iBAAiB,CAAC,UAAU,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC/F,MAAM,iBAAiB,CAAC,UAAU,CAAC,GAAG,CAAC,2BAA2B,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;QACtG,MAAM,MAAM,GAAuB,MAAM,iBAAiB,CACxD,UAAU,CAAC,aAAa,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAC9F,UAAU,EACV,QAAQ,EACR,SAAS,CACV,CAAC;QACF,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC7C,MAAM,UAAU,GAAG,MAAM;aACtB,eAAe,EAAE;aACjB,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,GAAuB,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC,cAAc,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;aACxI,MAAM,CAAC,CAAC,SAAS,EAA+B,EAAE,CAAC,SAAS,KAAK,SAAS,CAAC;aAC3E,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE;YACpB,MAAM,QAAQ,GAAG,SAAS,CAAC,cAAc,IAAI,EAAE,CAAC;YAChD,MAAM,UAAU,GAAG,iBAAiB,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YAC1D,MAAM,eAAe,GAAG,iBAAiB,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,WAAW,EAAE,CAAC;YACnF,OAAO,eAAe,KAAK,oBAAoB,IAAI,CAAC,UAAU,KAAK,SAAS,IAAI,UAAU,IAAI,iBAAiB,CAAC,CAAC;QACnH,CAAC,CAAC;aACD,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,QAAS,CAAC,aAAa,CAAC,KAAK,CAAC,QAAS,CAAC,CAAC,CAAC;QACxE,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,IAAI,SAAS,CAAC,QAAQ,KAAK,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACxH,CAAC;YAAS,CAAC;QACT,UAAU,EAAE,SAAS,EAAE,CAAC;QACxB,QAAQ,CAAC,SAAS,EAAE,CAAC;IACvB,CAAC;AACH,CAAC"}
|
package/dist/schema.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export declare const failOnSchema: z.ZodEnum<["none", "high", "medium", "low"]>;
|
|
|
5
5
|
export declare const batchIndexSortSchema: z.ZodEnum<["score-asc", "severity-desc"]>;
|
|
6
6
|
export declare const exportPresetSchema: z.ZodEnum<["standard", "crm"]>;
|
|
7
7
|
export declare const auditProfileSchema: z.ZodEnum<["generic", "dental", "beauty", "restaurant", "contractor", "lawyer", "clinic", "gym", "hotel", "auto-service"]>;
|
|
8
|
-
export declare const discoveryProviderSchema: z.ZodEnum<["manual-csv", "google-places"]>;
|
|
8
|
+
export declare const discoveryProviderSchema: z.ZodEnum<["manual-csv", "google-places", "overture"]>;
|
|
9
9
|
export declare const cliOptionsSchema: z.ZodObject<{
|
|
10
10
|
format: z.ZodDefault<z.ZodEnum<["json", "markdown", "html", "pdf", "all"]>>;
|
|
11
11
|
out: z.ZodOptional<z.ZodString>;
|
|
@@ -23,7 +23,12 @@ export declare const cliOptionsSchema: z.ZodObject<{
|
|
|
23
23
|
profile: z.ZodDefault<z.ZodEnum<["generic", "dental", "beauty", "restaurant", "contractor", "lawyer", "clinic", "gym", "hotel", "auto-service"]>>;
|
|
24
24
|
exportCsv: z.ZodOptional<z.ZodString>;
|
|
25
25
|
exportPreset: z.ZodDefault<z.ZodEnum<["standard", "crm"]>>;
|
|
26
|
-
provider: z.ZodDefault<z.ZodEnum<["manual-csv", "google-places"]>>;
|
|
26
|
+
provider: z.ZodDefault<z.ZodEnum<["manual-csv", "google-places", "overture"]>>;
|
|
27
|
+
city: z.ZodOptional<z.ZodString>;
|
|
28
|
+
country: z.ZodOptional<z.ZodString>;
|
|
29
|
+
bbox: z.ZodOptional<z.ZodString>;
|
|
30
|
+
radiusKm: z.ZodDefault<z.ZodNumber>;
|
|
31
|
+
release: z.ZodOptional<z.ZodString>;
|
|
27
32
|
dryRun: z.ZodDefault<z.ZodBoolean>;
|
|
28
33
|
limit: z.ZodDefault<z.ZodNumber>;
|
|
29
34
|
maxAudits: z.ZodOptional<z.ZodNumber>;
|
|
@@ -53,7 +58,8 @@ export declare const cliOptionsSchema: z.ZodObject<{
|
|
|
53
58
|
format: "html" | "json" | "markdown" | "pdf" | "all";
|
|
54
59
|
concurrency: number;
|
|
55
60
|
exportPreset: "standard" | "crm";
|
|
56
|
-
provider: "manual-csv" | "google-places";
|
|
61
|
+
provider: "manual-csv" | "google-places" | "overture";
|
|
62
|
+
radiusKm: number;
|
|
57
63
|
dryRun: boolean;
|
|
58
64
|
limit: number;
|
|
59
65
|
timeout: number;
|
|
@@ -70,6 +76,10 @@ export declare const cliOptionsSchema: z.ZodObject<{
|
|
|
70
76
|
auditStatus?: string | undefined;
|
|
71
77
|
hasWebsite?: string | undefined;
|
|
72
78
|
exportCsv?: string | undefined;
|
|
79
|
+
city?: string | undefined;
|
|
80
|
+
country?: string | undefined;
|
|
81
|
+
bbox?: string | undefined;
|
|
82
|
+
release?: string | undefined;
|
|
73
83
|
maxAudits?: number | undefined;
|
|
74
84
|
summaryJson?: string | undefined;
|
|
75
85
|
suppressionList?: string | undefined;
|
|
@@ -100,7 +110,12 @@ export declare const cliOptionsSchema: z.ZodObject<{
|
|
|
100
110
|
concurrency?: number | undefined;
|
|
101
111
|
exportCsv?: string | undefined;
|
|
102
112
|
exportPreset?: "standard" | "crm" | undefined;
|
|
103
|
-
provider?: "manual-csv" | "google-places" | undefined;
|
|
113
|
+
provider?: "manual-csv" | "google-places" | "overture" | undefined;
|
|
114
|
+
city?: string | undefined;
|
|
115
|
+
country?: string | undefined;
|
|
116
|
+
bbox?: string | undefined;
|
|
117
|
+
radiusKm?: number | undefined;
|
|
118
|
+
release?: string | undefined;
|
|
104
119
|
dryRun?: boolean | undefined;
|
|
105
120
|
limit?: number | undefined;
|
|
106
121
|
maxAudits?: number | undefined;
|
package/dist/schema.js
CHANGED
|
@@ -29,7 +29,7 @@ export const auditProfileSchema = z.enum([
|
|
|
29
29
|
"hotel",
|
|
30
30
|
"auto-service"
|
|
31
31
|
]);
|
|
32
|
-
export const discoveryProviderSchema = z.enum(["manual-csv", "google-places"]);
|
|
32
|
+
export const discoveryProviderSchema = z.enum(["manual-csv", "google-places", "overture"]);
|
|
33
33
|
export const cliOptionsSchema = z.object({
|
|
34
34
|
format: outputFormatSchema.default("markdown"),
|
|
35
35
|
out: z.string().optional(),
|
|
@@ -48,6 +48,11 @@ export const cliOptionsSchema = z.object({
|
|
|
48
48
|
exportCsv: z.string().optional(),
|
|
49
49
|
exportPreset: exportPresetSchema.default("standard"),
|
|
50
50
|
provider: discoveryProviderSchema.default("manual-csv"),
|
|
51
|
+
city: z.string().trim().min(1).optional(),
|
|
52
|
+
country: z.string().trim().regex(/^[A-Za-z]{2}$/).optional(),
|
|
53
|
+
bbox: z.string().trim().min(1).optional(),
|
|
54
|
+
radiusKm: z.coerce.number().positive().max(50).default(10),
|
|
55
|
+
release: z.string().regex(/^\d{4}-\d{2}-\d{2}\.\d+$/).optional(),
|
|
51
56
|
dryRun: z.boolean().default(false),
|
|
52
57
|
limit: z.coerce.number().int().positive().default(10),
|
|
53
58
|
maxAudits: z.coerce.number().int().min(0).optional(),
|
package/dist/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC;KAC5B,MAAM,EAAE;KACR,IAAI,EAAE;KACN,GAAG,CAAC,CAAC,EAAE,iBAAiB,CAAC;KACzB,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;IACnB,IAAI,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,WAAW,KAAK,EAAE,CAAC;AAC5B,CAAC,CAAC;KACD,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;KAC7D,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;IAC9C,OAAO,EAAE,wCAAwC;CAClD,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AACrF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;AACtE,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC,CAAC;AAC3E,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;AAC9D,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,IAAI,CAAC;IACvC,SAAS;IACT,QAAQ;IACR,QAAQ;IACR,YAAY;IACZ,YAAY;IACZ,QAAQ;IACR,QAAQ;IACR,KAAK;IACL,OAAO;IACP,cAAc;CACf,CAAC,CAAC;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { PageSnapshot, PublicContact } from "./types.js";
|
|
2
|
+
type Resolver = (hostname: string) => Promise<string[]>;
|
|
3
|
+
export interface WebsiteEnrichmentResult {
|
|
4
|
+
status: "success" | "blocked" | "failed";
|
|
5
|
+
snapshot?: PageSnapshot;
|
|
6
|
+
contact?: PublicContact;
|
|
7
|
+
sourceUrls: string[];
|
|
8
|
+
pagesFetched: number;
|
|
9
|
+
durationMs: number;
|
|
10
|
+
error?: string;
|
|
11
|
+
warnings?: string[];
|
|
12
|
+
}
|
|
13
|
+
export interface WebsiteEnrichmentOptions {
|
|
14
|
+
timeoutMs?: number;
|
|
15
|
+
maxPages?: number;
|
|
16
|
+
fetch?: typeof fetch;
|
|
17
|
+
/** Test seam for deterministic DNS checks. Production uses Node's resolver. */
|
|
18
|
+
resolve?: Resolver;
|
|
19
|
+
}
|
|
20
|
+
export declare function enrichWebsite(url: string, options?: WebsiteEnrichmentOptions): Promise<WebsiteEnrichmentResult>;
|
|
21
|
+
export {};
|