@shware/analytics 10.0.0 → 10.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tanstack/middleware.cjs +13 -1
- package/dist/tanstack/middleware.cjs.map +1 -1
- package/dist/tanstack/middleware.d.cts +5 -3
- package/dist/tanstack/middleware.d.cts.map +1 -1
- package/dist/tanstack/middleware.d.mts +5 -3
- package/dist/tanstack/middleware.d.mts.map +1 -1
- package/dist/tanstack/middleware.mjs +13 -1
- package/dist/tanstack/middleware.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -3,6 +3,18 @@ const require_click_id_index = require("../click-id/index.cjs");
|
|
|
3
3
|
let _tanstack_react_start = require("@tanstack/react-start");
|
|
4
4
|
//#region src/tanstack/middleware.ts
|
|
5
5
|
/**
|
|
6
|
+
* Whether a response could be stored by a shared cache (a CDN) under its `Cache-Control`. One
|
|
7
|
+
* that is `private` or `no-store` already cannot, so a per-user `Set-Cookie` on it is safe as it
|
|
8
|
+
* is, and its own caching is kept — the gtag.js loader served through a first-party Google Tag
|
|
9
|
+
* Gateway (`private, max-age=…`) stays in the browser cache, where a browser never replays a
|
|
10
|
+
* `Set-Cookie`. Anything else — `public`, `s-maxage`, no header at all — might be shared, and is
|
|
11
|
+
* made uncacheable.
|
|
12
|
+
*/
|
|
13
|
+
function sharedCacheable(value) {
|
|
14
|
+
if (!value) return true;
|
|
15
|
+
return !value.toLowerCase().split(",").map((directive) => directive.trim()).some((directive) => directive === "private" || directive.startsWith("private=") || directive === "no-store");
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
6
18
|
* TanStack Start request middleware that persists the ad platforms' first-party cookies on the
|
|
7
19
|
* document response: `_fbc`, `_fbp`, `_gcl_aw` / `_gcl_gb`, `_rdt_cid`, `_rdt_uuid`,
|
|
8
20
|
* `_uetmsclkid`, `__oppref` and `__obref`.
|
|
@@ -43,7 +55,7 @@ function createClickIdMiddleware(options) {
|
|
|
43
55
|
});
|
|
44
56
|
if (cookies.length > 0) {
|
|
45
57
|
for (const header of require_click_id_index.toSetCookieHeaders(cookies)) result.response.headers.append("set-cookie", header);
|
|
46
|
-
if (cacheControl !== false) result.response.headers.set("cache-control", cacheControl);
|
|
58
|
+
if (cacheControl !== false && sharedCacheable(result.response.headers.get("cache-control"))) result.response.headers.set("cache-control", cacheControl);
|
|
47
59
|
}
|
|
48
60
|
return result;
|
|
49
61
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.cjs","names":["createMiddleware","resolveClickIdCookies","toSetCookieHeaders"],"sources":["../../src/tanstack/middleware.ts"],"sourcesContent":["import { createMiddleware } from '@tanstack/react-start';\nimport { resolveClickIdCookies, toSetCookieHeaders } from '../click-id/index';\n\nexport interface ClickIdMiddlewareOptions {\n /**\n * `Domain` attribute for the cookies: the site's registrable domain, e.g. `.shware.io`, where the\n * pixels write theirs. Required — set it in production; `null` (host-only) is for `localhost`.\n * See `ResolveClickIdCookiesInput.domain`.\n */\n domain: string | null;\n /** `Secure` attribute, default true. Set false only for local http testing. */\n secure?: boolean;\n /** subdomainIndex for a freshly built `_fbc` (com=0, example.com=1, www.example.com=2). Default 1. */\n subdomainIndex?: number;\n /**\n * Re-issue the stored click and browser ids on every request as an ITP self-heal: the pixels\n * rewrite them through `document.cookie`, which Safari caps at 7 days (24 hours on an\n * ad-decorated landing), and the re-issue restores the long-lived HTTP cookie. On by default.\n * Note it attaches a per-user `Set-Cookie` — and thus `no-store` — to every page response of a\n * visitor carrying one; set false to keep those pages CDN-cacheable. See\n * {@link resolveClickIdCookies}.\n */\n refresh?: boolean;\n /**\n *
|
|
1
|
+
{"version":3,"file":"middleware.cjs","names":["createMiddleware","resolveClickIdCookies","toSetCookieHeaders"],"sources":["../../src/tanstack/middleware.ts"],"sourcesContent":["import { createMiddleware } from '@tanstack/react-start';\nimport { resolveClickIdCookies, toSetCookieHeaders } from '../click-id/index';\n\nexport interface ClickIdMiddlewareOptions {\n /**\n * `Domain` attribute for the cookies: the site's registrable domain, e.g. `.shware.io`, where the\n * pixels write theirs. Required — set it in production; `null` (host-only) is for `localhost`.\n * See `ResolveClickIdCookiesInput.domain`.\n */\n domain: string | null;\n /** `Secure` attribute, default true. Set false only for local http testing. */\n secure?: boolean;\n /** subdomainIndex for a freshly built `_fbc` (com=0, example.com=1, www.example.com=2). Default 1. */\n subdomainIndex?: number;\n /**\n * Re-issue the stored click and browser ids on every request as an ITP self-heal: the pixels\n * rewrite them through `document.cookie`, which Safari caps at 7 days (24 hours on an\n * ad-decorated landing), and the re-issue restores the long-lived HTTP cookie. On by default.\n * Note it attaches a per-user `Set-Cookie` — and thus `no-store` — to every page response of a\n * visitor carrying one; set false to keep those pages CDN-cacheable. See\n * {@link resolveClickIdCookies}.\n */\n refresh?: boolean;\n /**\n * The `Cache-Control` for a response we attach cookies to when it could otherwise be stored by a\n * shared cache (default `private, no-store`): a per-user `Set-Cookie` must never end up on a\n * shared-cache entry, or one visitor's `_fbc` would be served to everyone. A response already\n * `private` or `no-store` keeps its own. Only set this false if you guarantee these responses\n * are never cached.\n */\n cacheControl?: string | false;\n /**\n * Consent gate. Return false to skip setting cookies for this request (e.g. before the visitor has\n * granted consent where required). Runs per request with the incoming `Request`.\n */\n shouldPersist?: (request: Request) => boolean;\n}\n\n/**\n * Whether a response could be stored by a shared cache (a CDN) under its `Cache-Control`. One\n * that is `private` or `no-store` already cannot, so a per-user `Set-Cookie` on it is safe as it\n * is, and its own caching is kept — the gtag.js loader served through a first-party Google Tag\n * Gateway (`private, max-age=…`) stays in the browser cache, where a browser never replays a\n * `Set-Cookie`. Anything else — `public`, `s-maxage`, no header at all — might be shared, and is\n * made uncacheable.\n */\nfunction sharedCacheable(value: string | null): boolean {\n if (!value) return true;\n const directives = value\n .toLowerCase()\n .split(',')\n .map((directive) => directive.trim());\n return !directives.some(\n (directive) =>\n directive === 'private' || directive.startsWith('private=') || directive === 'no-store'\n );\n}\n\n/**\n * TanStack Start request middleware that persists the ad platforms' first-party cookies on the\n * document response: `_fbc`, `_fbp`, `_gcl_aw` / `_gcl_gb`, `_rdt_cid`, `_rdt_uuid`,\n * `_uetmsclkid`, `__oppref` and `__obref`.\n *\n * Setting `_fbc` here — on the top document via an HTTP `Set-Cookie` header, before any client JS\n * runs — is what Meta officially recommends and the only reliable way to keep the cookie alive for\n * 90 days in Safari: ITP caps JavaScript-set cookies on a fbclid-decorated landing page to 24\n * hours, and a document response is never classified as CNAME/IP cloaking (it is the reference the\n * browser measures cloaking against).\n *\n * Register it as a global request middleware:\n * ```ts\n * // start.ts\n * import { createStart } from '@tanstack/react-start'\n * import { createClickIdMiddleware } from '@shware/analytics/tanstack'\n * const clickIdMiddleware = createClickIdMiddleware({\n * domain: import.meta.env.DEV ? null : '.example.com',\n * secure: !import.meta.env.DEV,\n * })\n * export const startInstance = createStart(() => ({ requestMiddleware: [clickIdMiddleware] }))\n * ```\n *\n * reference: https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/fbp-and-fbc\n */\nexport function createClickIdMiddleware(options: ClickIdMiddlewareOptions) {\n const { cacheControl = 'private, no-store' } = options;\n\n return createMiddleware({ type: 'request' }).server(async ({ request, next, handlerType }) => {\n const result = await next();\n\n // Skip serverFn RPC responses. 'router' covers SSR document requests *and* custom server\n // routes (API endpoints) — those also get cookies when the URL carries a click id.\n if (handlerType !== 'router') return result;\n if (options.shouldPersist && !options.shouldPersist(request)) return result;\n\n const { cookies } = resolveClickIdCookies({\n url: request.url,\n cookieHeader: request.headers.get('cookie'),\n domain: options.domain,\n secure: options.secure,\n subdomainIndex: options.subdomainIndex,\n refresh: options.refresh ?? true,\n });\n\n if (cookies.length > 0) {\n for (const header of toSetCookieHeaders(cookies)) {\n result.response.headers.append('set-cookie', header);\n }\n if (cacheControl !== false && sharedCacheable(result.response.headers.get('cache-control'))) {\n result.response.headers.set('cache-control', cacheControl);\n }\n }\n\n return result;\n });\n}\n"],"mappings":";;;;;;;;;;;;AA8CA,SAAS,gBAAgB,OAA+B;CACtD,IAAI,CAAC,OAAO,OAAO;CAKnB,OAAO,CAJY,MAChB,YAAY,CAAC,CACb,MAAM,GAAG,CAAC,CACV,KAAK,cAAc,UAAU,KAAK,CACpB,CAAC,CAAC,MAChB,cACC,cAAc,aAAa,UAAU,WAAW,UAAU,KAAK,cAAc,UACjF;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,SAAgB,wBAAwB,SAAmC;CACzE,MAAM,EAAE,eAAe,wBAAwB;CAE/C,QAAA,GAAOA,sBAAAA,iBAAAA,CAAiB,EAAE,MAAM,UAAU,CAAC,CAAC,CAAC,OAAO,OAAO,EAAE,SAAS,MAAM,kBAAkB;EAC5F,MAAM,SAAS,MAAM,KAAK;EAI1B,IAAI,gBAAgB,UAAU,OAAO;EACrC,IAAI,QAAQ,iBAAiB,CAAC,QAAQ,cAAc,OAAO,GAAG,OAAO;EAErE,MAAM,EAAE,YAAYC,uBAAAA,sBAAsB;GACxC,KAAK,QAAQ;GACb,cAAc,QAAQ,QAAQ,IAAI,QAAQ;GAC1C,QAAQ,QAAQ;GAChB,QAAQ,QAAQ;GAChB,gBAAgB,QAAQ;GACxB,SAAS,QAAQ,WAAW;EAC9B,CAAC;EAED,IAAI,QAAQ,SAAS,GAAG;GACtB,KAAK,MAAM,UAAUC,uBAAAA,mBAAmB,OAAO,GAC7C,OAAO,SAAS,QAAQ,OAAO,cAAc,MAAM;GAErD,IAAI,iBAAiB,SAAS,gBAAgB,OAAO,SAAS,QAAQ,IAAI,eAAe,CAAC,GACxF,OAAO,SAAS,QAAQ,IAAI,iBAAiB,YAAY;EAE7D;EAEA,OAAO;CACT,CAAC;AACH"}
|
|
@@ -20,9 +20,11 @@ export interface ClickIdMiddlewareOptions {
|
|
|
20
20
|
*/
|
|
21
21
|
refresh?: boolean;
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
23
|
+
* The `Cache-Control` for a response we attach cookies to when it could otherwise be stored by a
|
|
24
|
+
* shared cache (default `private, no-store`): a per-user `Set-Cookie` must never end up on a
|
|
25
|
+
* shared-cache entry, or one visitor's `_fbc` would be served to everyone. A response already
|
|
26
|
+
* `private` or `no-store` keeps its own. Only set this false if you guarantee these responses
|
|
27
|
+
* are never cached.
|
|
26
28
|
*/
|
|
27
29
|
cacheControl?: string | false;
|
|
28
30
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.d.cts","names":[],"sources":["../../src/tanstack/middleware.ts"],"mappings":";iBAGiB;;;;;;EAMf;;EAEA;;EAEA;;;;;;;;;EASA
|
|
1
|
+
{"version":3,"file":"middleware.d.cts","names":[],"sources":["../../src/tanstack/middleware.ts"],"mappings":";iBAGiB;;;;;;EAMf;;EAEA;;EAEA;;;;;;;;;EASA;;;;;;;;EAQA;;;;;EAKA,iBAAiB,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAgDZ,wBAAwB,SAAS,2DAAwB"}
|
|
@@ -20,9 +20,11 @@ export interface ClickIdMiddlewareOptions {
|
|
|
20
20
|
*/
|
|
21
21
|
refresh?: boolean;
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
23
|
+
* The `Cache-Control` for a response we attach cookies to when it could otherwise be stored by a
|
|
24
|
+
* shared cache (default `private, no-store`): a per-user `Set-Cookie` must never end up on a
|
|
25
|
+
* shared-cache entry, or one visitor's `_fbc` would be served to everyone. A response already
|
|
26
|
+
* `private` or `no-store` keeps its own. Only set this false if you guarantee these responses
|
|
27
|
+
* are never cached.
|
|
26
28
|
*/
|
|
27
29
|
cacheControl?: string | false;
|
|
28
30
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.d.mts","names":[],"sources":["../../src/tanstack/middleware.ts"],"mappings":";iBAGiB;;;;;;EAMf;;EAEA;;EAEA;;;;;;;;;EASA
|
|
1
|
+
{"version":3,"file":"middleware.d.mts","names":[],"sources":["../../src/tanstack/middleware.ts"],"mappings":";iBAGiB;;;;;;EAMf;;EAEA;;EAEA;;;;;;;;;EASA;;;;;;;;EAQA;;;;;EAKA,iBAAiB,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAgDZ,wBAAwB,SAAS,2DAAwB"}
|
|
@@ -2,6 +2,18 @@ import { resolveClickIdCookies, toSetCookieHeaders } from "../click-id/index.mjs
|
|
|
2
2
|
import { createMiddleware } from "@tanstack/react-start";
|
|
3
3
|
//#region src/tanstack/middleware.ts
|
|
4
4
|
/**
|
|
5
|
+
* Whether a response could be stored by a shared cache (a CDN) under its `Cache-Control`. One
|
|
6
|
+
* that is `private` or `no-store` already cannot, so a per-user `Set-Cookie` on it is safe as it
|
|
7
|
+
* is, and its own caching is kept — the gtag.js loader served through a first-party Google Tag
|
|
8
|
+
* Gateway (`private, max-age=…`) stays in the browser cache, where a browser never replays a
|
|
9
|
+
* `Set-Cookie`. Anything else — `public`, `s-maxage`, no header at all — might be shared, and is
|
|
10
|
+
* made uncacheable.
|
|
11
|
+
*/
|
|
12
|
+
function sharedCacheable(value) {
|
|
13
|
+
if (!value) return true;
|
|
14
|
+
return !value.toLowerCase().split(",").map((directive) => directive.trim()).some((directive) => directive === "private" || directive.startsWith("private=") || directive === "no-store");
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
5
17
|
* TanStack Start request middleware that persists the ad platforms' first-party cookies on the
|
|
6
18
|
* document response: `_fbc`, `_fbp`, `_gcl_aw` / `_gcl_gb`, `_rdt_cid`, `_rdt_uuid`,
|
|
7
19
|
* `_uetmsclkid`, `__oppref` and `__obref`.
|
|
@@ -42,7 +54,7 @@ function createClickIdMiddleware(options) {
|
|
|
42
54
|
});
|
|
43
55
|
if (cookies.length > 0) {
|
|
44
56
|
for (const header of toSetCookieHeaders(cookies)) result.response.headers.append("set-cookie", header);
|
|
45
|
-
if (cacheControl !== false) result.response.headers.set("cache-control", cacheControl);
|
|
57
|
+
if (cacheControl !== false && sharedCacheable(result.response.headers.get("cache-control"))) result.response.headers.set("cache-control", cacheControl);
|
|
46
58
|
}
|
|
47
59
|
return result;
|
|
48
60
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.mjs","names":[],"sources":["../../src/tanstack/middleware.ts"],"sourcesContent":["import { createMiddleware } from '@tanstack/react-start';\nimport { resolveClickIdCookies, toSetCookieHeaders } from '../click-id/index';\n\nexport interface ClickIdMiddlewareOptions {\n /**\n * `Domain` attribute for the cookies: the site's registrable domain, e.g. `.shware.io`, where the\n * pixels write theirs. Required — set it in production; `null` (host-only) is for `localhost`.\n * See `ResolveClickIdCookiesInput.domain`.\n */\n domain: string | null;\n /** `Secure` attribute, default true. Set false only for local http testing. */\n secure?: boolean;\n /** subdomainIndex for a freshly built `_fbc` (com=0, example.com=1, www.example.com=2). Default 1. */\n subdomainIndex?: number;\n /**\n * Re-issue the stored click and browser ids on every request as an ITP self-heal: the pixels\n * rewrite them through `document.cookie`, which Safari caps at 7 days (24 hours on an\n * ad-decorated landing), and the re-issue restores the long-lived HTTP cookie. On by default.\n * Note it attaches a per-user `Set-Cookie` — and thus `no-store` — to every page response of a\n * visitor carrying one; set false to keep those pages CDN-cacheable. See\n * {@link resolveClickIdCookies}.\n */\n refresh?: boolean;\n /**\n *
|
|
1
|
+
{"version":3,"file":"middleware.mjs","names":[],"sources":["../../src/tanstack/middleware.ts"],"sourcesContent":["import { createMiddleware } from '@tanstack/react-start';\nimport { resolveClickIdCookies, toSetCookieHeaders } from '../click-id/index';\n\nexport interface ClickIdMiddlewareOptions {\n /**\n * `Domain` attribute for the cookies: the site's registrable domain, e.g. `.shware.io`, where the\n * pixels write theirs. Required — set it in production; `null` (host-only) is for `localhost`.\n * See `ResolveClickIdCookiesInput.domain`.\n */\n domain: string | null;\n /** `Secure` attribute, default true. Set false only for local http testing. */\n secure?: boolean;\n /** subdomainIndex for a freshly built `_fbc` (com=0, example.com=1, www.example.com=2). Default 1. */\n subdomainIndex?: number;\n /**\n * Re-issue the stored click and browser ids on every request as an ITP self-heal: the pixels\n * rewrite them through `document.cookie`, which Safari caps at 7 days (24 hours on an\n * ad-decorated landing), and the re-issue restores the long-lived HTTP cookie. On by default.\n * Note it attaches a per-user `Set-Cookie` — and thus `no-store` — to every page response of a\n * visitor carrying one; set false to keep those pages CDN-cacheable. See\n * {@link resolveClickIdCookies}.\n */\n refresh?: boolean;\n /**\n * The `Cache-Control` for a response we attach cookies to when it could otherwise be stored by a\n * shared cache (default `private, no-store`): a per-user `Set-Cookie` must never end up on a\n * shared-cache entry, or one visitor's `_fbc` would be served to everyone. A response already\n * `private` or `no-store` keeps its own. Only set this false if you guarantee these responses\n * are never cached.\n */\n cacheControl?: string | false;\n /**\n * Consent gate. Return false to skip setting cookies for this request (e.g. before the visitor has\n * granted consent where required). Runs per request with the incoming `Request`.\n */\n shouldPersist?: (request: Request) => boolean;\n}\n\n/**\n * Whether a response could be stored by a shared cache (a CDN) under its `Cache-Control`. One\n * that is `private` or `no-store` already cannot, so a per-user `Set-Cookie` on it is safe as it\n * is, and its own caching is kept — the gtag.js loader served through a first-party Google Tag\n * Gateway (`private, max-age=…`) stays in the browser cache, where a browser never replays a\n * `Set-Cookie`. Anything else — `public`, `s-maxage`, no header at all — might be shared, and is\n * made uncacheable.\n */\nfunction sharedCacheable(value: string | null): boolean {\n if (!value) return true;\n const directives = value\n .toLowerCase()\n .split(',')\n .map((directive) => directive.trim());\n return !directives.some(\n (directive) =>\n directive === 'private' || directive.startsWith('private=') || directive === 'no-store'\n );\n}\n\n/**\n * TanStack Start request middleware that persists the ad platforms' first-party cookies on the\n * document response: `_fbc`, `_fbp`, `_gcl_aw` / `_gcl_gb`, `_rdt_cid`, `_rdt_uuid`,\n * `_uetmsclkid`, `__oppref` and `__obref`.\n *\n * Setting `_fbc` here — on the top document via an HTTP `Set-Cookie` header, before any client JS\n * runs — is what Meta officially recommends and the only reliable way to keep the cookie alive for\n * 90 days in Safari: ITP caps JavaScript-set cookies on a fbclid-decorated landing page to 24\n * hours, and a document response is never classified as CNAME/IP cloaking (it is the reference the\n * browser measures cloaking against).\n *\n * Register it as a global request middleware:\n * ```ts\n * // start.ts\n * import { createStart } from '@tanstack/react-start'\n * import { createClickIdMiddleware } from '@shware/analytics/tanstack'\n * const clickIdMiddleware = createClickIdMiddleware({\n * domain: import.meta.env.DEV ? null : '.example.com',\n * secure: !import.meta.env.DEV,\n * })\n * export const startInstance = createStart(() => ({ requestMiddleware: [clickIdMiddleware] }))\n * ```\n *\n * reference: https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/fbp-and-fbc\n */\nexport function createClickIdMiddleware(options: ClickIdMiddlewareOptions) {\n const { cacheControl = 'private, no-store' } = options;\n\n return createMiddleware({ type: 'request' }).server(async ({ request, next, handlerType }) => {\n const result = await next();\n\n // Skip serverFn RPC responses. 'router' covers SSR document requests *and* custom server\n // routes (API endpoints) — those also get cookies when the URL carries a click id.\n if (handlerType !== 'router') return result;\n if (options.shouldPersist && !options.shouldPersist(request)) return result;\n\n const { cookies } = resolveClickIdCookies({\n url: request.url,\n cookieHeader: request.headers.get('cookie'),\n domain: options.domain,\n secure: options.secure,\n subdomainIndex: options.subdomainIndex,\n refresh: options.refresh ?? true,\n });\n\n if (cookies.length > 0) {\n for (const header of toSetCookieHeaders(cookies)) {\n result.response.headers.append('set-cookie', header);\n }\n if (cacheControl !== false && sharedCacheable(result.response.headers.get('cache-control'))) {\n result.response.headers.set('cache-control', cacheControl);\n }\n }\n\n return result;\n });\n}\n"],"mappings":";;;;;;;;;;;AA8CA,SAAS,gBAAgB,OAA+B;CACtD,IAAI,CAAC,OAAO,OAAO;CAKnB,OAAO,CAJY,MAChB,YAAY,CAAC,CACb,MAAM,GAAG,CAAC,CACV,KAAK,cAAc,UAAU,KAAK,CACpB,CAAC,CAAC,MAChB,cACC,cAAc,aAAa,UAAU,WAAW,UAAU,KAAK,cAAc,UACjF;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,SAAgB,wBAAwB,SAAmC;CACzE,MAAM,EAAE,eAAe,wBAAwB;CAE/C,OAAO,iBAAiB,EAAE,MAAM,UAAU,CAAC,CAAC,CAAC,OAAO,OAAO,EAAE,SAAS,MAAM,kBAAkB;EAC5F,MAAM,SAAS,MAAM,KAAK;EAI1B,IAAI,gBAAgB,UAAU,OAAO;EACrC,IAAI,QAAQ,iBAAiB,CAAC,QAAQ,cAAc,OAAO,GAAG,OAAO;EAErE,MAAM,EAAE,YAAY,sBAAsB;GACxC,KAAK,QAAQ;GACb,cAAc,QAAQ,QAAQ,IAAI,QAAQ;GAC1C,QAAQ,QAAQ;GAChB,QAAQ,QAAQ;GAChB,gBAAgB,QAAQ;GACxB,SAAS,QAAQ,WAAW;EAC9B,CAAC;EAED,IAAI,QAAQ,SAAS,GAAG;GACtB,KAAK,MAAM,UAAU,mBAAmB,OAAO,GAC7C,OAAO,SAAS,QAAQ,OAAO,cAAc,MAAM;GAErD,IAAI,iBAAiB,SAAS,gBAAgB,OAAO,SAAS,QAAQ,IAAI,eAAe,CAAC,GACxF,OAAO,SAAS,QAAQ,IAAI,iBAAiB,YAAY;EAE7D;EAEA,OAAO;CACT,CAAC;AACH"}
|