@patchstack/connect 0.5.6 → 0.5.7

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.
@@ -0,0 +1,295 @@
1
+ // src/protect/safe-origin.js
2
+ function isSafeOrigin(value) {
3
+ try {
4
+ const u = new URL(value);
5
+ if (u.protocol === "https:") return true;
6
+ return u.protocol === "http:" && (u.hostname === "localhost" || u.hostname === "127.0.0.1" || u.hostname === "[::1]" || u.hostname === "::1");
7
+ } catch {
8
+ return false;
9
+ }
10
+ }
11
+ function safeBaseUrl(candidate, fallback, label) {
12
+ if (typeof candidate !== "string" || candidate === "") return fallback;
13
+ if (isSafeOrigin(candidate)) return candidate;
14
+ warnOnce(label, `[patchstack] ignoring unsafe ${label} override (${candidate}): must be https (or localhost). Using the default.`);
15
+ return fallback;
16
+ }
17
+ var warned = /* @__PURE__ */ new Set();
18
+ function warnOnce(key, message) {
19
+ if (warned.has(key)) return;
20
+ warned.add(key);
21
+ console.warn(message);
22
+ }
23
+
24
+ // src/types.ts
25
+ var PatchstackError = class extends Error {
26
+ constructor(message, code, cause) {
27
+ super(message);
28
+ this.code = code;
29
+ this.cause = cause;
30
+ this.name = "PatchstackError";
31
+ }
32
+ code;
33
+ cause;
34
+ /**
35
+ * For a `VALIDATION_ERROR`, the request fields the server refused, as it named them. Read from the
36
+ * structured `errors` object a validation response carries, so a caller deciding what to do about a
37
+ * refusal keys on the field rather than on the wording of a sentence.
38
+ */
39
+ fields = [];
40
+ };
41
+
42
+ // src/endpoint-policy.ts
43
+ function assertConnectableEndpoint(config, target = config.endpoint) {
44
+ if (config.endpointTrusted === false) {
45
+ throw new PatchstackError(
46
+ "The custom endpoint in .patchstackrc.json must be confirmed with --endpoint or PATCHSTACK_ENDPOINT before it can be used.",
47
+ "CONFIG_INVALID"
48
+ );
49
+ }
50
+ if (safeRemoteUrl(config.endpoint) === null) {
51
+ throw new PatchstackError(
52
+ "Patchstack endpoints must use HTTPS, except for localhost development endpoints.",
53
+ "CONFIG_INVALID"
54
+ );
55
+ }
56
+ let endpointOrigin;
57
+ let targetOrigin;
58
+ try {
59
+ endpointOrigin = new URL(config.endpoint).origin;
60
+ targetOrigin = new URL(target).origin;
61
+ } catch (cause) {
62
+ throw new PatchstackError("The configured Patchstack endpoint is not a valid URL.", "CONFIG_INVALID", cause);
63
+ }
64
+ if (safeRemoteUrl(target) === null || targetOrigin !== endpointOrigin) {
65
+ throw new PatchstackError(
66
+ "A Patchstack request resolved outside the configured endpoint origin.",
67
+ "CONFIG_INVALID"
68
+ );
69
+ }
70
+ }
71
+ function safeRemoteUrl(value) {
72
+ if (typeof value !== "string" || value.length === 0 || value.length > 2048) return null;
73
+ try {
74
+ const parsed = new URL(value);
75
+ if (!isSafeOrigin(parsed.toString()) || parsed.username !== "" || parsed.password !== "") return null;
76
+ return parsed.toString();
77
+ } catch {
78
+ return null;
79
+ }
80
+ }
81
+ function safeDisplayString(value, maxLength = 512) {
82
+ if (typeof value !== "string") return null;
83
+ const clean = value.replace(/\u001b(?:\[[0-?]*[ -/]*[@-~]|\][^\u0007]*(?:\u0007|\u001b\\))/g, "").replace(/[\u0000-\u001f\u007f-\u009f]/g, " ").replace(/\s+/g, " ").trim();
84
+ if (clean.length === 0) return null;
85
+ return clean.slice(0, maxLength);
86
+ }
87
+ function isCanonicalUuid(value) {
88
+ return typeof value === "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
89
+ }
90
+ function isCredential(value) {
91
+ if (typeof value !== "string" || value.length === 0 || value.length > 4096) return false;
92
+ for (let i = 0; i < value.length; i += 1) {
93
+ const code = value.charCodeAt(i);
94
+ if (code < 33 || code > 126) return false;
95
+ }
96
+ const separator = value.lastIndexOf("-");
97
+ return separator > 0 && separator < value.length - 1 && /^\d+$/.test(value.slice(separator + 1));
98
+ }
99
+ function isHeaderValue(value, maxLength = 8192) {
100
+ if (typeof value !== "string" || value.length === 0 || value.length > maxLength) return false;
101
+ for (let i = 0; i < value.length; i += 1) {
102
+ const code = value.charCodeAt(i);
103
+ if (code < 33 || code > 126) return false;
104
+ }
105
+ return true;
106
+ }
107
+
108
+ // src/bounded-response.ts
109
+ var MAX_CONTROL_RESPONSE_BYTES = 256 * 1024;
110
+ async function readBoundedText(response, maxBytes = MAX_CONTROL_RESPONSE_BYTES) {
111
+ const stated = Number(response.headers?.get?.("content-length"));
112
+ if (Number.isFinite(stated) && stated > maxBytes) {
113
+ void response.body?.cancel().catch(() => {
114
+ });
115
+ throw new Error(`response exceeds ${maxBytes} bytes`);
116
+ }
117
+ const stream = response.body;
118
+ if (stream === null || typeof stream.getReader !== "function") {
119
+ if (stated === 0) return "";
120
+ throw new Error("response body cannot be read with a size bound");
121
+ }
122
+ const reader = stream.getReader();
123
+ const chunks = [];
124
+ let total = 0;
125
+ try {
126
+ for (; ; ) {
127
+ const { done, value } = await reader.read();
128
+ if (done) break;
129
+ total += value.byteLength;
130
+ if (total > maxBytes) {
131
+ void reader.cancel().catch(() => {
132
+ });
133
+ throw new Error(`response exceeds ${maxBytes} bytes`);
134
+ }
135
+ chunks.push(value);
136
+ }
137
+ } finally {
138
+ reader.releaseLock();
139
+ }
140
+ const bytes = new Uint8Array(total);
141
+ let offset = 0;
142
+ for (const chunk of chunks) {
143
+ bytes.set(chunk, offset);
144
+ offset += chunk.byteLength;
145
+ }
146
+ return new TextDecoder().decode(bytes);
147
+ }
148
+ async function readBoundedJson(response, maxBytes = MAX_CONTROL_RESPONSE_BYTES) {
149
+ const text = await readBoundedText(response, maxBytes);
150
+ return JSON.parse(text);
151
+ }
152
+
153
+ // src/pulse-token.ts
154
+ var TOKEN_SKEW_MS = 6e4;
155
+ function buildTokenUrl(manifestEndpoint) {
156
+ const url = new URL(manifestEndpoint);
157
+ const path = url.pathname.replace(/\/$/, "");
158
+ url.pathname = path.endsWith("/manifest") ? `${path.slice(0, -"/manifest".length)}/token` : "/monitor/pulse/token";
159
+ url.search = "";
160
+ url.hash = "";
161
+ return url.toString();
162
+ }
163
+ function parsePulseAuth(credential) {
164
+ const index = credential.lastIndexOf("-");
165
+ if (index <= 0 || index === credential.length - 1) return null;
166
+ const clientId = credential.slice(index + 1);
167
+ if (!/^\d+$/.test(clientId)) return null;
168
+ return { clientId, clientSecret: credential.slice(0, index) };
169
+ }
170
+ var cached = /* @__PURE__ */ new Map();
171
+ var inflight = /* @__PURE__ */ new Map();
172
+ function cacheKey(tokenUrl, credential) {
173
+ return `${tokenUrl}
174
+ ${credential}`;
175
+ }
176
+ function clearPulseToken(config) {
177
+ if (!config || typeof config.pulseAuth !== "string") {
178
+ cached.clear();
179
+ inflight.clear();
180
+ return;
181
+ }
182
+ try {
183
+ const key = cacheKey(buildTokenUrl(config.endpoint), config.pulseAuth);
184
+ cached.delete(key);
185
+ inflight.delete(key);
186
+ } catch {
187
+ }
188
+ }
189
+ async function getPulseToken(config, fetchImpl = fetch) {
190
+ if (typeof config.pulseAuth !== "string" || config.pulseAuth.length === 0) return null;
191
+ if (config.endpointTrusted === false) return null;
192
+ let tokenUrl;
193
+ try {
194
+ tokenUrl = buildTokenUrl(config.endpoint);
195
+ } catch {
196
+ return null;
197
+ }
198
+ if (!isSafeOrigin(tokenUrl)) return null;
199
+ const key = cacheKey(tokenUrl, config.pulseAuth);
200
+ const existing = cached.get(key);
201
+ if (existing !== void 0 && Date.now() < existing.expiresAt - TOKEN_SKEW_MS) {
202
+ return existing.token;
203
+ }
204
+ const pending = inflight.get(key);
205
+ if (pending !== void 0) return pending;
206
+ const credentials = parsePulseAuth(config.pulseAuth);
207
+ if (credentials === null) return null;
208
+ let exchange;
209
+ exchange = (async () => {
210
+ try {
211
+ const response = await fetchImpl(tokenUrl, {
212
+ method: "POST",
213
+ headers: {
214
+ "Content-Type": "application/json",
215
+ Accept: "application/json",
216
+ "User-Agent": "@patchstack/connect"
217
+ },
218
+ body: JSON.stringify({
219
+ grant_type: "client_credentials",
220
+ client_id: credentials.clientId,
221
+ client_secret: credentials.clientSecret
222
+ }),
223
+ signal: AbortSignal.timeout(config.timeoutMs)
224
+ });
225
+ if (!response.ok) return null;
226
+ const body = await readBoundedJson(response);
227
+ if (!isHeaderValue(body.access_token)) return null;
228
+ const expiresIn = Number(body.expires_in);
229
+ const ttlMs = Number.isFinite(expiresIn) && expiresIn > 0 ? expiresIn * 1e3 : 36e5;
230
+ cached.set(key, { token: body.access_token, expiresAt: Date.now() + ttlMs });
231
+ return body.access_token;
232
+ } catch {
233
+ return null;
234
+ } finally {
235
+ if (inflight.get(key) === exchange) inflight.delete(key);
236
+ }
237
+ })();
238
+ inflight.set(key, exchange);
239
+ return exchange;
240
+ }
241
+ async function pulseAuthHeader(config, fetchImpl = fetch) {
242
+ const token = await getPulseToken(config, fetchImpl);
243
+ return token === null ? {} : { Authorization: `Bearer ${token}` };
244
+ }
245
+ async function pulseFetch(config, url, init, fetchImpl = fetch) {
246
+ assertConnectableEndpoint(config, url);
247
+ const send = async () => {
248
+ const auth = await pulseAuthHeader(config, fetchImpl);
249
+ const response = await fetchImpl(url, {
250
+ ...init,
251
+ headers: { ...init.headers, ...auth }
252
+ });
253
+ return { response, authenticated: auth.Authorization !== void 0 };
254
+ };
255
+ const first = await send();
256
+ if (first.response.status === 401 && first.authenticated) {
257
+ clearPulseToken(config);
258
+ return (await send()).response;
259
+ }
260
+ return first.response;
261
+ }
262
+
263
+ // src/build-id.ts
264
+ var BUILD_ID = /^[0-9a-f]{64}$/i;
265
+ function canonicalBuildId(value) {
266
+ if (typeof value !== "string") return null;
267
+ const trimmed = value.trim();
268
+ return BUILD_ID.test(trimmed) ? trimmed.toLowerCase() : null;
269
+ }
270
+ var BUILD_STAMP_KEY = "_patchstack";
271
+ function readBuildStamp(bundle) {
272
+ if (bundle === null || typeof bundle !== "object") return null;
273
+ const namespace = bundle[BUILD_STAMP_KEY];
274
+ if (namespace === null || typeof namespace !== "object") return null;
275
+ return canonicalBuildId(namespace.build_id);
276
+ }
277
+
278
+ export {
279
+ isSafeOrigin,
280
+ safeBaseUrl,
281
+ PatchstackError,
282
+ assertConnectableEndpoint,
283
+ safeRemoteUrl,
284
+ safeDisplayString,
285
+ isCanonicalUuid,
286
+ isCredential,
287
+ isHeaderValue,
288
+ readBoundedText,
289
+ readBoundedJson,
290
+ pulseAuthHeader,
291
+ pulseFetch,
292
+ canonicalBuildId,
293
+ readBuildStamp
294
+ };
295
+ //# sourceMappingURL=chunk-2K5SHFUM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/protect/safe-origin.js","../src/types.ts","../src/endpoint-policy.ts","../src/bounded-response.ts","../src/pulse-token.ts","../src/build-id.ts"],"mappings":";AAKO,SAAS,aAAa,OAAO;AAClC,MAAI;AACF,UAAM,IAAI,IAAI,IAAI,KAAK;AACvB,QAAI,EAAE,aAAa,SAAU,QAAO;AACpC,WAAO,EAAE,aAAa,YAAY,EAAE,aAAa,eAAe,EAAE,aAAa,eAAe,EAAE,aAAa,WAAW,EAAE,aAAa;AAAA,EACzI,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAMO,SAAS,YAAY,WAAW,UAAU,OAAO;AACtD,MAAI,OAAO,cAAc,YAAY,cAAc,GAAI,QAAO;AAC9D,MAAI,aAAa,SAAS,EAAG,QAAO;AACpC,WAAS,OAAO,gCAAgC,KAAK,cAAc,SAAS,qDAAqD;AACjI,SAAO;AACT;AAEA,IAAM,SAAS,oBAAI,IAAI;AACvB,SAAS,SAAS,KAAK,SAAS;AAC9B,MAAI,OAAO,IAAI,GAAG,EAAG;AACrB,SAAO,IAAI,GAAG;AAEd,UAAQ,KAAK,OAAO;AACtB;;;ACgGO,IAAM,kBAAN,cAA8B,MAAM;AAAA,EAQzC,YACE,SACgB,MAYA,OAChB;AACA,UAAM,OAAO;AAdG;AAYA;AAGhB,SAAK,OAAO;AAAA,EACd;AAAA,EAhBkB;AAAA,EAYA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAhBX,SAA4B,CAAC;AAqBtC;;;ACvJO,SAAS,0BAA0B,QAAgB,SAAS,OAAO,UAAgB;AACxF,MAAI,OAAO,oBAAoB,OAAO;AACpC,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI,cAAc,OAAO,QAAQ,MAAM,MAAM;AAC3C,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,MAAI;AACJ,MAAI;AACJ,MAAI;AACF,qBAAiB,IAAI,IAAI,OAAO,QAAQ,EAAE;AAC1C,mBAAe,IAAI,IAAI,MAAM,EAAE;AAAA,EACjC,SAAS,OAAO;AACd,UAAM,IAAI,gBAAgB,0DAA0D,kBAAkB,KAAK;AAAA,EAC7G;AACA,MAAI,cAAc,MAAM,MAAM,QAAQ,iBAAiB,gBAAgB;AACrE,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAGO,SAAS,cAAc,OAA+B;AAC3D,MAAI,OAAO,UAAU,YAAY,MAAM,WAAW,KAAK,MAAM,SAAS,KAAO,QAAO;AACpF,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,KAAK;AAC5B,QAAI,CAAC,aAAa,OAAO,SAAS,CAAC,KAAK,OAAO,aAAa,MAAM,OAAO,aAAa,GAAI,QAAO;AACjG,WAAO,OAAO,SAAS;AAAA,EACzB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,kBAAkB,OAAgB,YAAY,KAAoB;AAChF,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,QAAQ,MACX,QAAQ,kEAAkE,EAAE,EAC5E,QAAQ,iCAAiC,GAAG,EAC5C,QAAQ,QAAQ,GAAG,EACnB,KAAK;AACR,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,SAAO,MAAM,MAAM,GAAG,SAAS;AACjC;AAEO,SAAS,gBAAgB,OAAiC;AAC/D,SACE,OAAO,UAAU,YACjB,kEAAkE,KAAK,KAAK;AAEhF;AAEO,SAAS,aAAa,OAAiC;AAC5D,MAAI,OAAO,UAAU,YAAY,MAAM,WAAW,KAAK,MAAM,SAAS,KAAO,QAAO;AACpF,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,GAAG;AACxC,UAAM,OAAO,MAAM,WAAW,CAAC;AAC/B,QAAI,OAAO,MAAQ,OAAO,IAAM,QAAO;AAAA,EACzC;AACA,QAAM,YAAY,MAAM,YAAY,GAAG;AACvC,SAAO,YAAY,KAAK,YAAY,MAAM,SAAS,KAAK,QAAQ,KAAK,MAAM,MAAM,YAAY,CAAC,CAAC;AACjG;AAEO,SAAS,cAAc,OAAgB,YAAY,MAAwB;AAChF,MAAI,OAAO,UAAU,YAAY,MAAM,WAAW,KAAK,MAAM,SAAS,UAAW,QAAO;AACxF,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,GAAG;AACxC,UAAM,OAAO,MAAM,WAAW,CAAC;AAC/B,QAAI,OAAO,MAAQ,OAAO,IAAM,QAAO;AAAA,EACzC;AACA,SAAO;AACT;;;AClFO,IAAM,6BAA6B,MAAM;AAGhD,eAAsB,gBACpB,UACA,WAAW,4BACM;AACjB,QAAM,SAAS,OAAO,SAAS,SAAS,MAAM,gBAAgB,CAAC;AAC/D,MAAI,OAAO,SAAS,MAAM,KAAK,SAAS,UAAU;AAChD,SAAK,SAAS,MAAM,OAAO,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAC3C,UAAM,IAAI,MAAM,oBAAoB,QAAQ,QAAQ;AAAA,EACtD;AAEA,QAAM,SAAS,SAAS;AACxB,MAAI,WAAW,QAAQ,OAAO,OAAO,cAAc,YAAY;AAC7D,QAAI,WAAW,EAAG,QAAO;AACzB,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AAEA,QAAM,SAAS,OAAO,UAAU;AAChC,QAAM,SAAuB,CAAC;AAC9B,MAAI,QAAQ;AACZ,MAAI;AACF,eAAS;AACP,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AACV,eAAS,MAAM;AACf,UAAI,QAAQ,UAAU;AACpB,aAAK,OAAO,OAAO,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AACnC,cAAM,IAAI,MAAM,oBAAoB,QAAQ,QAAQ;AAAA,MACtD;AACA,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA,EACF,UAAE;AACA,WAAO,YAAY;AAAA,EACrB;AAEA,QAAM,QAAQ,IAAI,WAAW,KAAK;AAClC,MAAI,SAAS;AACb,aAAW,SAAS,QAAQ;AAC1B,UAAM,IAAI,OAAO,MAAM;AACvB,cAAU,MAAM;AAAA,EAClB;AACA,SAAO,IAAI,YAAY,EAAE,OAAO,KAAK;AACvC;AAEA,eAAsB,gBACpB,UACA,WAAW,4BACO;AAClB,QAAM,OAAO,MAAM,gBAAgB,UAAU,QAAQ;AACrD,SAAO,KAAK,MAAM,IAAI;AACxB;;;ACvCA,IAAM,gBAAgB;AAGf,SAAS,cAAc,kBAAkC;AAC9D,QAAM,MAAM,IAAI,IAAI,gBAAgB;AACpC,QAAM,OAAO,IAAI,SAAS,QAAQ,OAAO,EAAE;AAC3C,MAAI,WAAW,KAAK,SAAS,WAAW,IACpC,GAAG,KAAK,MAAM,GAAG,CAAC,YAAY,MAAM,CAAC,WACrC;AACJ,MAAI,SAAS;AACb,MAAI,OAAO;AACX,SAAO,IAAI,SAAS;AACtB;AAGO,SAAS,eAAe,YAAuE;AACpG,QAAM,QAAQ,WAAW,YAAY,GAAG;AACxC,MAAI,SAAS,KAAK,UAAU,WAAW,SAAS,EAAG,QAAO;AAE1D,QAAM,WAAW,WAAW,MAAM,QAAQ,CAAC;AAC3C,MAAI,CAAC,QAAQ,KAAK,QAAQ,EAAG,QAAO;AAEpC,SAAO,EAAE,UAAU,cAAc,WAAW,MAAM,GAAG,KAAK,EAAE;AAC9D;AAEA,IAAM,SAAS,oBAAI,IAAkD;AACrE,IAAM,WAAW,oBAAI,IAAoC;AAEzD,SAAS,SAAS,UAAkB,YAA4B;AAC9D,SAAO,GAAG,QAAQ;AAAA,EAAK,UAAU;AACnC;AAGO,SAAS,gBAAgB,QAAuB;AACrD,MAAI,CAAC,UAAU,OAAO,OAAO,cAAc,UAAU;AACnD,WAAO,MAAM;AACb,aAAS,MAAM;AACf;AAAA,EACF;AAEA,MAAI;AACF,UAAM,MAAM,SAAS,cAAc,OAAO,QAAQ,GAAG,OAAO,SAAS;AACrE,WAAO,OAAO,GAAG;AACjB,aAAS,OAAO,GAAG;AAAA,EACrB,QAAQ;AAAA,EAER;AACF;AAWA,eAAsB,cACpB,QACA,YAA0B,OACF;AAGxB,MAAI,OAAO,OAAO,cAAc,YAAY,OAAO,UAAU,WAAW,EAAG,QAAO;AAClF,MAAI,OAAO,oBAAoB,MAAO,QAAO;AAE7C,MAAI;AACJ,MAAI;AACF,eAAW,cAAc,OAAO,QAAQ;AAAA,EAC1C,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI,CAAC,aAAa,QAAQ,EAAG,QAAO;AAEpC,QAAM,MAAM,SAAS,UAAU,OAAO,SAAS;AAC/C,QAAM,WAAW,OAAO,IAAI,GAAG;AAE/B,MAAI,aAAa,UAAa,KAAK,IAAI,IAAI,SAAS,YAAY,eAAe;AAC7E,WAAO,SAAS;AAAA,EAClB;AACA,QAAM,UAAU,SAAS,IAAI,GAAG;AAChC,MAAI,YAAY,OAAW,QAAO;AAElC,QAAM,cAAc,eAAe,OAAO,SAAS;AACnD,MAAI,gBAAgB,KAAM,QAAO;AAEjC,MAAI;AACJ,cAAY,YAAY;AACtB,QAAI;AACF,YAAM,WAAW,MAAM,UAAU,UAAU;AAAA,QACzC,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,QAAQ;AAAA,UACR,cAAc;AAAA,QAChB;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,YAAY;AAAA,UACZ,WAAW,YAAY;AAAA,UACvB,eAAe,YAAY;AAAA,QAC7B,CAAC;AAAA,QACD,QAAQ,YAAY,QAAQ,OAAO,SAAS;AAAA,MAC9C,CAAC;AAED,UAAI,CAAC,SAAS,GAAI,QAAO;AAEzB,YAAM,OAAQ,MAAM,gBAAgB,QAAQ;AAC5C,UAAI,CAAC,cAAc,KAAK,YAAY,EAAG,QAAO;AAE9C,YAAM,YAAY,OAAO,KAAK,UAAU;AACxC,YAAM,QAAQ,OAAO,SAAS,SAAS,KAAK,YAAY,IAAI,YAAY,MAAO;AAC/E,aAAO,IAAI,KAAK,EAAE,OAAO,KAAK,cAAc,WAAW,KAAK,IAAI,IAAI,MAAM,CAAC;AAE3E,aAAO,KAAK;AAAA,IACd,QAAQ;AACN,aAAO;AAAA,IACT,UAAE;AACA,UAAI,SAAS,IAAI,GAAG,MAAM,SAAU,UAAS,OAAO,GAAG;AAAA,IACzD;AAAA,EACF,GAAG;AACH,WAAS,IAAI,KAAK,QAAQ;AAE1B,SAAO;AACT;AAMA,eAAsB,gBACpB,QACA,YAA0B,OACO;AACjC,QAAM,QAAQ,MAAM,cAAc,QAAQ,SAAS;AACnD,SAAO,UAAU,OAAO,CAAC,IAAI,EAAE,eAAe,UAAU,KAAK,GAAG;AAClE;AAcA,eAAsB,WACpB,QACA,KACA,MACA,YAA0B,OACP;AACnB,4BAA0B,QAAQ,GAAG;AAErC,QAAM,OAAO,YAAY;AACvB,UAAM,OAAO,MAAM,gBAAgB,QAAQ,SAAS;AACpD,UAAM,WAAW,MAAM,UAAU,KAAK;AAAA,MACpC,GAAG;AAAA,MACH,SAAS,EAAE,GAAI,KAAK,SAAgD,GAAG,KAAK;AAAA,IAC9E,CAAC;AAED,WAAO,EAAE,UAAU,eAAe,KAAK,kBAAkB,OAAU;AAAA,EACrE;AAEA,QAAM,QAAQ,MAAM,KAAK;AAIzB,MAAI,MAAM,SAAS,WAAW,OAAO,MAAM,eAAe;AACxD,oBAAgB,MAAM;AAEtB,YAAQ,MAAM,KAAK,GAAG;AAAA,EACxB;AAEA,SAAO,MAAM;AACf;;;AC/KA,IAAM,WAAW;AAWV,SAAS,iBAAiB,OAA+B;AAC9D,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,UAAU,MAAM,KAAK;AAE3B,SAAO,SAAS,KAAK,OAAO,IAAI,QAAQ,YAAY,IAAI;AAC1D;AASO,IAAM,kBAAkB;AASxB,SAAS,eAAe,QAAgC;AAC7D,MAAI,WAAW,QAAQ,OAAO,WAAW,SAAU,QAAO;AAC1D,QAAM,YAAa,OAAmC,eAAe;AACrE,MAAI,cAAc,QAAQ,OAAO,cAAc,SAAU,QAAO;AAEhE,SAAO,iBAAkB,UAAsC,QAAQ;AACzE;","names":[]}