@cogenta/render 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/astro/integration.d.ts +57 -0
- package/dist/astro/integration.d.ts.map +1 -0
- package/dist/astro/integration.js +72 -0
- package/dist/astro/integration.js.map +1 -0
- package/dist/build/index.d.ts +7 -0
- package/dist/build/index.d.ts.map +1 -0
- package/dist/build/index.js +7 -0
- package/dist/build/index.js.map +1 -0
- package/dist/build/integration.d.ts +25 -0
- package/dist/build/integration.d.ts.map +1 -0
- package/dist/build/integration.js +41 -0
- package/dist/build/integration.js.map +1 -0
- package/dist/build/plan.d.ts +41 -0
- package/dist/build/plan.d.ts.map +1 -0
- package/dist/build/plan.js +48 -0
- package/dist/build/plan.js.map +1 -0
- package/dist/build/refusal.d.ts +14 -0
- package/dist/build/refusal.d.ts.map +1 -0
- package/dist/build/refusal.js +110 -0
- package/dist/build/refusal.js.map +1 -0
- package/dist/build/requirements.d.ts +59 -0
- package/dist/build/requirements.d.ts.map +1 -0
- package/dist/build/requirements.js +74 -0
- package/dist/build/requirements.js.map +1 -0
- package/dist/build/run-build.d.ts +43 -0
- package/dist/build/run-build.d.ts.map +1 -0
- package/dist/build/run-build.js +73 -0
- package/dist/build/run-build.js.map +1 -0
- package/dist/build/targets.d.ts +47 -0
- package/dist/build/targets.d.ts.map +1 -0
- package/dist/build/targets.js +69 -0
- package/dist/build/targets.js.map +1 -0
- package/dist/cache/index.d.ts +7 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +4 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/page-cache.d.ts +64 -0
- package/dist/cache/page-cache.d.ts.map +1 -0
- package/dist/cache/page-cache.js +128 -0
- package/dist/cache/page-cache.js.map +1 -0
- package/dist/cache/recorder.d.ts +49 -0
- package/dist/cache/recorder.d.ts.map +1 -0
- package/dist/cache/recorder.js +77 -0
- package/dist/cache/recorder.js.map +1 -0
- package/dist/cache/tags.d.ts +55 -0
- package/dist/cache/tags.d.ts.map +1 -0
- package/dist/cache/tags.js +62 -0
- package/dist/cache/tags.js.map +1 -0
- package/dist/config.d.ts +48 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +44 -0
- package/dist/config.js.map +1 -0
- package/dist/content/client.d.ts +35 -0
- package/dist/content/client.d.ts.map +1 -0
- package/dist/content/client.js +155 -0
- package/dist/content/client.js.map +1 -0
- package/dist/content/types.d.ts +104 -0
- package/dist/content/types.d.ts.map +1 -0
- package/dist/content/types.js +16 -0
- package/dist/content/types.js.map +1 -0
- package/dist/context/render-context.d.ts +31 -0
- package/dist/context/render-context.d.ts.map +1 -0
- package/dist/context/render-context.js +152 -0
- package/dist/context/render-context.js.map +1 -0
- package/dist/context/types.d.ts +49 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/context/types.js +2 -0
- package/dist/context/types.js.map +1 -0
- package/dist/images/errors.d.ts +20 -0
- package/dist/images/errors.d.ts.map +1 -0
- package/dist/images/errors.js +58 -0
- package/dist/images/errors.js.map +1 -0
- package/dist/images/format.d.ts +18 -0
- package/dist/images/format.d.ts.map +1 -0
- package/dist/images/format.js +34 -0
- package/dist/images/format.js.map +1 -0
- package/dist/images/geometry.d.ts +46 -0
- package/dist/images/geometry.d.ts.map +1 -0
- package/dist/images/geometry.js +127 -0
- package/dist/images/geometry.js.map +1 -0
- package/dist/images/index.d.ts +29 -0
- package/dist/images/index.d.ts.map +1 -0
- package/dist/images/index.js +30 -0
- package/dist/images/index.js.map +1 -0
- package/dist/images/pipeline.d.ts +51 -0
- package/dist/images/pipeline.d.ts.map +1 -0
- package/dist/images/pipeline.js +105 -0
- package/dist/images/pipeline.js.map +1 -0
- package/dist/images/sharp.d.ts +57 -0
- package/dist/images/sharp.d.ts.map +1 -0
- package/dist/images/sharp.js +139 -0
- package/dist/images/sharp.js.map +1 -0
- package/dist/images/srcset.d.ts +33 -0
- package/dist/images/srcset.d.ts.map +1 -0
- package/dist/images/srcset.js +94 -0
- package/dist/images/srcset.js.map +1 -0
- package/dist/images/store.d.ts +32 -0
- package/dist/images/store.d.ts.map +1 -0
- package/dist/images/store.js +54 -0
- package/dist/images/store.js.map +1 -0
- package/dist/images/types.d.ts +128 -0
- package/dist/images/types.d.ts.map +1 -0
- package/dist/images/types.js +22 -0
- package/dist/images/types.js.map +1 -0
- package/dist/images/wasm.d.ts +43 -0
- package/dist/images/wasm.d.ts.map +1 -0
- package/dist/images/wasm.js +128 -0
- package/dist/images/wasm.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/pwa/build.d.ts +39 -0
- package/dist/pwa/build.d.ts.map +1 -0
- package/dist/pwa/build.js +38 -0
- package/dist/pwa/build.js.map +1 -0
- package/dist/pwa/client.d.ts +90 -0
- package/dist/pwa/client.d.ts.map +1 -0
- package/dist/pwa/client.js +76 -0
- package/dist/pwa/client.js.map +1 -0
- package/dist/pwa/index.d.ts +29 -0
- package/dist/pwa/index.d.ts.map +1 -0
- package/dist/pwa/index.js +22 -0
- package/dist/pwa/index.js.map +1 -0
- package/dist/pwa/manifest.d.ts +69 -0
- package/dist/pwa/manifest.d.ts.map +1 -0
- package/dist/pwa/manifest.js +108 -0
- package/dist/pwa/manifest.js.map +1 -0
- package/dist/pwa/offline.d.ts +44 -0
- package/dist/pwa/offline.d.ts.map +1 -0
- package/dist/pwa/offline.js +94 -0
- package/dist/pwa/offline.js.map +1 -0
- package/dist/pwa/service-worker.d.ts +71 -0
- package/dist/pwa/service-worker.d.ts.map +1 -0
- package/dist/pwa/service-worker.js +119 -0
- package/dist/pwa/service-worker.js.map +1 -0
- package/dist/pwa/strategy.d.ts +36 -0
- package/dist/pwa/strategy.d.ts.map +1 -0
- package/dist/pwa/strategy.js +180 -0
- package/dist/pwa/strategy.js.map +1 -0
- package/dist/pwa/sw-runtime.d.ts +109 -0
- package/dist/pwa/sw-runtime.d.ts.map +1 -0
- package/dist/pwa/sw-runtime.js +214 -0
- package/dist/pwa/sw-runtime.js.map +1 -0
- package/dist/pwa/types.d.ts +107 -0
- package/dist/pwa/types.d.ts.map +1 -0
- package/dist/pwa/types.js +18 -0
- package/dist/pwa/types.js.map +1 -0
- package/dist/pwa/version.d.ts +45 -0
- package/dist/pwa/version.d.ts.map +1 -0
- package/dist/pwa/version.js +89 -0
- package/dist/pwa/version.js.map +1 -0
- package/dist/skin/color.d.ts +50 -0
- package/dist/skin/color.d.ts.map +1 -0
- package/dist/skin/color.js +176 -0
- package/dist/skin/color.js.map +1 -0
- package/dist/skin/css.d.ts +19 -0
- package/dist/skin/css.d.ts.map +1 -0
- package/dist/skin/css.js +69 -0
- package/dist/skin/css.js.map +1 -0
- package/dist/skin/errors.d.ts +22 -0
- package/dist/skin/errors.d.ts.map +1 -0
- package/dist/skin/errors.js +59 -0
- package/dist/skin/errors.js.map +1 -0
- package/dist/skin/index.d.ts +15 -0
- package/dist/skin/index.d.ts.map +1 -0
- package/dist/skin/index.js +11 -0
- package/dist/skin/index.js.map +1 -0
- package/dist/skin/sheet.d.ts +42 -0
- package/dist/skin/sheet.d.ts.map +1 -0
- package/dist/skin/sheet.js +36 -0
- package/dist/skin/sheet.js.map +1 -0
- package/dist/skin/tokens.d.ts +90 -0
- package/dist/skin/tokens.d.ts.map +1 -0
- package/dist/skin/tokens.js +56 -0
- package/dist/skin/tokens.js.map +1 -0
- package/dist/skin/validate.d.ts +14 -0
- package/dist/skin/validate.d.ts.map +1 -0
- package/dist/skin/validate.js +272 -0
- package/dist/skin/validate.js.map +1 -0
- package/dist/theme/load-theme.d.ts +37 -0
- package/dist/theme/load-theme.d.ts.map +1 -0
- package/dist/theme/load-theme.js +102 -0
- package/dist/theme/load-theme.js.map +1 -0
- package/dist/theme/manifest.d.ts +48 -0
- package/dist/theme/manifest.d.ts.map +1 -0
- package/dist/theme/manifest.js +36 -0
- package/dist/theme/manifest.js.map +1 -0
- package/dist/theme/verify/forbidden.d.ts +39 -0
- package/dist/theme/verify/forbidden.d.ts.map +1 -0
- package/dist/theme/verify/forbidden.js +107 -0
- package/dist/theme/verify/forbidden.js.map +1 -0
- package/dist/theme/verify/scan-file.d.ts +15 -0
- package/dist/theme/verify/scan-file.d.ts.map +1 -0
- package/dist/theme/verify/scan-file.js +151 -0
- package/dist/theme/verify/scan-file.js.map +1 -0
- package/dist/theme/verify/scanner.d.ts +52 -0
- package/dist/theme/verify/scanner.d.ts.map +1 -0
- package/dist/theme/verify/scanner.js +304 -0
- package/dist/theme/verify/scanner.js.map +1 -0
- package/dist/theme/verify/verify-theme.d.ts +44 -0
- package/dist/theme/verify/verify-theme.d.ts.map +1 -0
- package/dist/theme/verify/verify-theme.js +179 -0
- package/dist/theme/verify/verify-theme.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { chooseStrategy } from './strategy.js';
|
|
2
|
+
import { serviceWorkerMain, tombstoneMain } from './sw-runtime.js';
|
|
3
|
+
import { cacheNameFor, cachesToPurge } from './version.js';
|
|
4
|
+
/**
|
|
5
|
+
* Generation of the service worker script.
|
|
6
|
+
*
|
|
7
|
+
* ## The update strategy, stated in full
|
|
8
|
+
*
|
|
9
|
+
* `skipWaiting()` and `clients.claim()` are two calls; the strategy is the four
|
|
10
|
+
* properties that make those two calls safe.
|
|
11
|
+
*
|
|
12
|
+
* **1. Every generation owns its caches.** Cache names embed a version derived
|
|
13
|
+
* from the offline page, the precache list and the route table
|
|
14
|
+
* (`computeCacheVersion`). A new deploy therefore writes into new caches and
|
|
15
|
+
* cannot mix generations, which is what makes immediate activation safe: there
|
|
16
|
+
* is no window in which half the entries are old.
|
|
17
|
+
*
|
|
18
|
+
* **2. Activation purges the previous generations.** `cachesToPurge` returns
|
|
19
|
+
* every cache of ours whose version is not the current one, and activation
|
|
20
|
+
* deletes them before claiming clients. Storage does not accumulate one
|
|
21
|
+
* generation per deploy, and — the part that matters — yesterday's HTML is
|
|
22
|
+
* *gone*, not merely lower priority.
|
|
23
|
+
*
|
|
24
|
+
* **3. Documents are never served from cache while the network works.** Even a
|
|
25
|
+
* worker that somehow survived a bad deploy cannot pin an old page: the
|
|
26
|
+
* document strategy is network-first, so the cache answers only when the
|
|
27
|
+
* network has already failed. This is the property that keeps a mistake
|
|
28
|
+
* recoverable by deploying a fix, rather than requiring every visitor to clear
|
|
29
|
+
* their site data.
|
|
30
|
+
*
|
|
31
|
+
* **4. There is an exit.** The worker answers a message by purging every cache
|
|
32
|
+
* it owns and calling `registration.unregister()` — that is the admin's "clear
|
|
33
|
+
* client cache" button. For clients we can no longer run code on,
|
|
34
|
+
* `renderTombstoneServiceWorker` produces a worker that unregisters itself on
|
|
35
|
+
* activation; deploying it at the same URL removes the PWA from every browser
|
|
36
|
+
* that re-fetches the script, which browsers do at least daily.
|
|
37
|
+
*
|
|
38
|
+
* ## What is deliberately *not* done
|
|
39
|
+
*
|
|
40
|
+
* The worker does not reload open pages when it activates. A forced reload
|
|
41
|
+
* destroys scroll position, half-typed comments and video playback, and it
|
|
42
|
+
* turns one bad deploy into a reload loop. It posts `cogenta:activated`
|
|
43
|
+
* instead, and the page decides — the registration helper in `client.ts` turns
|
|
44
|
+
* that into an "a new version is available" prompt.
|
|
45
|
+
*
|
|
46
|
+
* The worker is a *classic* script, not an ES module: module workers are still
|
|
47
|
+
* unevenly supported, and there is nothing to import — the script is
|
|
48
|
+
* self-contained by construction.
|
|
49
|
+
*/
|
|
50
|
+
/**
|
|
51
|
+
* Headers the server must send for the service worker script.
|
|
52
|
+
*
|
|
53
|
+
* This is not decoration. A worker script cached by the HTTP cache for a year
|
|
54
|
+
* is the canonical unkillable zombie: the browser's daily update check reads
|
|
55
|
+
* the stale copy from disk, sees no change, and keeps the old worker alive —
|
|
56
|
+
* including after the tombstone has been deployed. `no-cache` (revalidate, do
|
|
57
|
+
* not blindly reuse) is the minimum, and the scope header lets the script live
|
|
58
|
+
* anywhere while controlling the whole origin.
|
|
59
|
+
*/
|
|
60
|
+
export const SERVICE_WORKER_HEADERS = {
|
|
61
|
+
'cache-control': 'no-cache, max-age=0, must-revalidate',
|
|
62
|
+
'content-type': 'text/javascript; charset=utf-8',
|
|
63
|
+
'service-worker-allowed': '/',
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* `Function.prototype.toString` returns the source of the function itself; the
|
|
67
|
+
* `export` keyword is a separate declaration in the module grammar. Stripping
|
|
68
|
+
* it anyway costs one line and removes a dependency on that detail of whichever
|
|
69
|
+
* engine ran `tsc`.
|
|
70
|
+
*/
|
|
71
|
+
function sourceOf(fn) {
|
|
72
|
+
return String(fn).replace(/^export\s+/, '');
|
|
73
|
+
}
|
|
74
|
+
const BANNER = [
|
|
75
|
+
'/*',
|
|
76
|
+
' * Generated by @cogenta/render. Do not edit: this file is rewritten on every',
|
|
77
|
+
' * build, and its content determines the cache generation.',
|
|
78
|
+
' *',
|
|
79
|
+
' * Serve it with `cache-control: no-cache` (see SERVICE_WORKER_HEADERS). A',
|
|
80
|
+
' * worker script held in the HTTP cache cannot be updated or removed.',
|
|
81
|
+
' */',
|
|
82
|
+
].join('\n');
|
|
83
|
+
function scriptFor(body) {
|
|
84
|
+
return `${BANNER}\n${body}\n`;
|
|
85
|
+
}
|
|
86
|
+
export function renderServiceWorker(config) {
|
|
87
|
+
// Pretty-printed on purpose: this file is the first thing anyone reads when a
|
|
88
|
+
// browser is serving something unexpected, and a minified route table is
|
|
89
|
+
// unreadable at exactly that moment.
|
|
90
|
+
const configLiteral = JSON.stringify(config, null, 2);
|
|
91
|
+
return scriptFor([
|
|
92
|
+
`const COGENTA_PWA_CONFIG = ${configLiteral}\n`,
|
|
93
|
+
sourceOf(cacheNameFor),
|
|
94
|
+
sourceOf(cachesToPurge),
|
|
95
|
+
sourceOf(chooseStrategy),
|
|
96
|
+
sourceOf(serviceWorkerMain),
|
|
97
|
+
'',
|
|
98
|
+
'serviceWorkerMain(self, COGENTA_PWA_CONFIG)',
|
|
99
|
+
].join('\n\n'));
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* The kill switch, as a deployable artefact.
|
|
103
|
+
*
|
|
104
|
+
* Deploy this at the URL the real worker was served from. It caches nothing,
|
|
105
|
+
* intercepts nothing, deletes every cache under `cachePrefix` and unregisters
|
|
106
|
+
* itself. Keep it deployed for at least one update cycle — twenty-four hours
|
|
107
|
+
* covers browsers that only check the script once a day — before removing the
|
|
108
|
+
* route entirely, because a 404 on the worker URL also unregisters the worker
|
|
109
|
+
* but tells the caches nothing.
|
|
110
|
+
*/
|
|
111
|
+
export function renderTombstoneServiceWorker(cachePrefix) {
|
|
112
|
+
return scriptFor([
|
|
113
|
+
`const COGENTA_CACHE_PREFIX = ${JSON.stringify(cachePrefix)}\n`,
|
|
114
|
+
sourceOf(tombstoneMain),
|
|
115
|
+
'',
|
|
116
|
+
'tombstoneMain(self, COGENTA_CACHE_PREFIX)',
|
|
117
|
+
].join('\n\n'));
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=service-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-worker.js","sourceRoot":"","sources":["../../src/pwa/service-worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAElE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAqC;IACtE,eAAe,EAAE,sCAAsC;IACvD,cAAc,EAAE,gCAAgC;IAChD,wBAAwB,EAAE,GAAG;CAC9B,CAAA;AAED;;;;;GAKG;AACH,SAAS,QAAQ,CAAC,EAAiC;IACjD,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAA;AAC7C,CAAC;AAED,MAAM,MAAM,GAAG;IACb,IAAI;IACJ,+EAA+E;IAC/E,4DAA4D;IAC5D,IAAI;IACJ,4EAA4E;IAC5E,uEAAuE;IACvE,KAAK;CACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAEZ,SAAS,SAAS,CAAC,IAAY;IAC7B,OAAO,GAAG,MAAM,KAAK,IAAI,IAAI,CAAA;AAC/B,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAiB;IACnD,8EAA8E;IAC9E,yEAAyE;IACzE,qCAAqC;IACrC,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;IAErD,OAAO,SAAS,CACd;QACE,8BAA8B,aAAa,IAAI;QAC/C,QAAQ,CAAC,YAAY,CAAC;QACtB,QAAQ,CAAC,aAAa,CAAC;QACvB,QAAQ,CAAC,cAAc,CAAC;QACxB,QAAQ,CAAC,iBAAiB,CAAC;QAC3B,EAAE;QACF,6CAA6C;KAC9C,CAAC,IAAI,CAAC,MAAM,CAAC,CACf,CAAA;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,4BAA4B,CAAC,WAAmB;IAC9D,OAAO,SAAS,CACd;QACE,gCAAgC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI;QAC/D,QAAQ,CAAC,aAAa,CAAC;QACvB,EAAE;QACF,2CAA2C;KAC5C,CAAC,IAAI,CAAC,MAAM,CAAC,CACf,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { RequestDescriptor, RouteRule, StrategyDecision } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Which strategy answers which request, and why.
|
|
4
|
+
*
|
|
5
|
+
* The rule that governs every choice below: **a resource may be served from
|
|
6
|
+
* cache without revalidation only when its URL changes whenever its content
|
|
7
|
+
* changes.** Fingerprinted assets satisfy that. Nothing else on a CMS-driven
|
|
8
|
+
* site does — an author republishes an article at the same URL, replaces an
|
|
9
|
+
* image at the same path, fixes a typo in a JSON feed. Serving those cache-first
|
|
10
|
+
* is exactly the "stale content forever" failure the L3 spec warns about.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* A URL is treated as immutable when it lives under Astro's hashed asset
|
|
14
|
+
* directory or carries a content hash in its filename. Both forms change on
|
|
15
|
+
* every content change, which is the entire justification for cache-first.
|
|
16
|
+
*/
|
|
17
|
+
export declare const IMMUTABLE_ASSET_PATTERN = "(^/_astro/)|(\\.[0-9a-f]{8,}\\.[a-z0-9]+(?:$|\\?))";
|
|
18
|
+
/**
|
|
19
|
+
* The default route table, in priority order. Each rule states its bucket, so
|
|
20
|
+
* caches stay separable, and its cap, so no bucket can grow without bound.
|
|
21
|
+
*/
|
|
22
|
+
export declare const DEFAULT_ROUTES: readonly RouteRule[];
|
|
23
|
+
/**
|
|
24
|
+
* Picks the strategy for one request.
|
|
25
|
+
*
|
|
26
|
+
* Pure, total, and free of any reference to module scope — this function is
|
|
27
|
+
* inlined verbatim into the generated service worker (see `runtime-source.ts`)
|
|
28
|
+
* so that the behaviour under test and the behaviour shipped are the same text.
|
|
29
|
+
*
|
|
30
|
+
* The bypasses come first and are deliberately generous. Every one of them is a
|
|
31
|
+
* case where storing a response would produce a wrong answer later, and a
|
|
32
|
+
* service worker that returns a wrong answer is worse than no service worker:
|
|
33
|
+
* it is a wrong answer nobody can reproduce without clearing site data.
|
|
34
|
+
*/
|
|
35
|
+
export declare function chooseStrategy(request: RequestDescriptor, routes: readonly RouteRule[]): StrategyDecision;
|
|
36
|
+
//# sourceMappingURL=strategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strategy.d.ts","sourceRoot":"","sources":["../../src/pwa/strategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAEhF;;;;;;;;;GASG;AAEH;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,uDAAuD,CAAA;AAE3F;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,SAAS,EAuF9C,CAAA;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,iBAAiB,EAC1B,MAAM,EAAE,SAAS,SAAS,EAAE,GAC3B,gBAAgB,CA6DlB"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which strategy answers which request, and why.
|
|
3
|
+
*
|
|
4
|
+
* The rule that governs every choice below: **a resource may be served from
|
|
5
|
+
* cache without revalidation only when its URL changes whenever its content
|
|
6
|
+
* changes.** Fingerprinted assets satisfy that. Nothing else on a CMS-driven
|
|
7
|
+
* site does — an author republishes an article at the same URL, replaces an
|
|
8
|
+
* image at the same path, fixes a typo in a JSON feed. Serving those cache-first
|
|
9
|
+
* is exactly the "stale content forever" failure the L3 spec warns about.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* A URL is treated as immutable when it lives under Astro's hashed asset
|
|
13
|
+
* directory or carries a content hash in its filename. Both forms change on
|
|
14
|
+
* every content change, which is the entire justification for cache-first.
|
|
15
|
+
*/
|
|
16
|
+
export const IMMUTABLE_ASSET_PATTERN = '(^/_astro/)|(\\.[0-9a-f]{8,}\\.[a-z0-9]+(?:$|\\?))';
|
|
17
|
+
/**
|
|
18
|
+
* The default route table, in priority order. Each rule states its bucket, so
|
|
19
|
+
* caches stay separable, and its cap, so no bucket can grow without bound.
|
|
20
|
+
*/
|
|
21
|
+
export const DEFAULT_ROUTES = [
|
|
22
|
+
{
|
|
23
|
+
// HTML is the index of everything else: it names the asset URLs, the nav,
|
|
24
|
+
// the current article. Stale HTML points at assets a purge has already
|
|
25
|
+
// deleted, so a cache-first document is both wrong and broken. Network
|
|
26
|
+
// first, with a short timeout so a captive portal or a dead mobile leg
|
|
27
|
+
// falls back to the last copy instead of hanging on a white screen.
|
|
28
|
+
id: 'documents',
|
|
29
|
+
destinations: ['document'],
|
|
30
|
+
pattern: null,
|
|
31
|
+
crossOrigin: false,
|
|
32
|
+
strategy: 'network-first',
|
|
33
|
+
bucket: 'documents',
|
|
34
|
+
maxEntries: 50,
|
|
35
|
+
networkTimeoutMs: 3000,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
// Fingerprinted assets. The URL is a content hash, so the cached body can
|
|
39
|
+
// never be wrong; revalidating it would only cost a round trip. This is the
|
|
40
|
+
// one and only place cache-first is safe, and it is where the offline win
|
|
41
|
+
// actually comes from.
|
|
42
|
+
id: 'immutable-assets',
|
|
43
|
+
destinations: ['script', 'style', 'font', 'worker'],
|
|
44
|
+
pattern: IMMUTABLE_ASSET_PATTERN,
|
|
45
|
+
crossOrigin: false,
|
|
46
|
+
strategy: 'cache-first',
|
|
47
|
+
bucket: 'assets',
|
|
48
|
+
maxEntries: 200,
|
|
49
|
+
networkTimeoutMs: null,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
// Scripts, stylesheets and fonts served from a stable URL. The body can
|
|
53
|
+
// change under that URL, so cache-first would pin an old build; but they
|
|
54
|
+
// are render-blocking, so network-first would cost a round trip on every
|
|
55
|
+
// page. Stale-while-revalidate is the honest middle: fast now, correct on
|
|
56
|
+
// the next navigation.
|
|
57
|
+
id: 'mutable-assets',
|
|
58
|
+
destinations: ['script', 'style', 'font'],
|
|
59
|
+
pattern: null,
|
|
60
|
+
crossOrigin: false,
|
|
61
|
+
strategy: 'stale-while-revalidate',
|
|
62
|
+
bucket: 'assets',
|
|
63
|
+
maxEntries: 60,
|
|
64
|
+
networkTimeoutMs: null,
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
// Images are large, replaceable at the same path by an editor, and never
|
|
68
|
+
// load-bearing for correctness: one page view showing yesterday's crop is a
|
|
69
|
+
// cosmetic defect, not a wrong answer. Capped, because an image cache is
|
|
70
|
+
// the one that fills a phone.
|
|
71
|
+
id: 'images',
|
|
72
|
+
destinations: ['image'],
|
|
73
|
+
pattern: null,
|
|
74
|
+
crossOrigin: false,
|
|
75
|
+
strategy: 'stale-while-revalidate',
|
|
76
|
+
bucket: 'images',
|
|
77
|
+
maxEntries: 80,
|
|
78
|
+
networkTimeoutMs: null,
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
// API data. Never stale-while-revalidate: JSON drives what the interface
|
|
82
|
+
// asserts, and rendering last week's data as if it were current is the
|
|
83
|
+
// failure mode users report as "the site is lying". Network first, cached
|
|
84
|
+
// only so that an offline reader still sees the last state they had, with
|
|
85
|
+
// a longer timeout than documents because a list endpoint is legitimately
|
|
86
|
+
// slower than a page.
|
|
87
|
+
id: 'api-data',
|
|
88
|
+
destinations: ['', 'empty'],
|
|
89
|
+
pattern: '^/api/',
|
|
90
|
+
crossOrigin: false,
|
|
91
|
+
strategy: 'network-first',
|
|
92
|
+
bucket: 'data',
|
|
93
|
+
maxEntries: 40,
|
|
94
|
+
networkTimeoutMs: 4000,
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
// The manifest itself. Rarely changes, tiny, and needed for the install
|
|
98
|
+
// prompt to appear offline.
|
|
99
|
+
id: 'manifest',
|
|
100
|
+
destinations: ['manifest'],
|
|
101
|
+
pattern: null,
|
|
102
|
+
crossOrigin: false,
|
|
103
|
+
strategy: 'stale-while-revalidate',
|
|
104
|
+
bucket: 'assets',
|
|
105
|
+
maxEntries: 5,
|
|
106
|
+
networkTimeoutMs: null,
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
/**
|
|
110
|
+
* Picks the strategy for one request.
|
|
111
|
+
*
|
|
112
|
+
* Pure, total, and free of any reference to module scope — this function is
|
|
113
|
+
* inlined verbatim into the generated service worker (see `runtime-source.ts`)
|
|
114
|
+
* so that the behaviour under test and the behaviour shipped are the same text.
|
|
115
|
+
*
|
|
116
|
+
* The bypasses come first and are deliberately generous. Every one of them is a
|
|
117
|
+
* case where storing a response would produce a wrong answer later, and a
|
|
118
|
+
* service worker that returns a wrong answer is worse than no service worker:
|
|
119
|
+
* it is a wrong answer nobody can reproduce without clearing site data.
|
|
120
|
+
*/
|
|
121
|
+
export function chooseStrategy(request, routes) {
|
|
122
|
+
const bypass = (reason) => ({
|
|
123
|
+
strategy: 'network-only',
|
|
124
|
+
bucket: 'documents',
|
|
125
|
+
maxEntries: null,
|
|
126
|
+
networkTimeoutMs: null,
|
|
127
|
+
ruleId: 'bypass',
|
|
128
|
+
reason,
|
|
129
|
+
});
|
|
130
|
+
// The Cache API only keys on GET. A POST answered from a cache would be a
|
|
131
|
+
// silent correctness bug, and a POST *stored* in one would be a data leak.
|
|
132
|
+
if (request.method !== 'GET')
|
|
133
|
+
return bypass(`method ${request.method} is not cacheable`);
|
|
134
|
+
// The caller explicitly asked to skip caches: a hard reload, or a fetch with
|
|
135
|
+
// `cache: 'no-store'`. Overruling that is how a service worker earns its
|
|
136
|
+
// reputation for being impossible to bypass.
|
|
137
|
+
if (request.cacheMode === 'no-store' || request.cacheMode === 'reload') {
|
|
138
|
+
return bypass(`request cache mode ${request.cacheMode} forbids caching`);
|
|
139
|
+
}
|
|
140
|
+
// A ranged response is a fragment. Storing it and later matching a full
|
|
141
|
+
// request against it hands back a truncated body — the classic broken-video
|
|
142
|
+
// bug.
|
|
143
|
+
if (request.hasRange)
|
|
144
|
+
return bypass('ranged request has a partial body');
|
|
145
|
+
let pathAndQuery;
|
|
146
|
+
let sameOrigin;
|
|
147
|
+
try {
|
|
148
|
+
const parsed = new URL(request.url);
|
|
149
|
+
sameOrigin = parsed.origin === request.origin;
|
|
150
|
+
pathAndQuery = parsed.pathname + parsed.search;
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
return bypass('request url could not be parsed');
|
|
154
|
+
}
|
|
155
|
+
// A navigation is a document even when the destination field is empty, which
|
|
156
|
+
// it is on some engines for the very first request of a page.
|
|
157
|
+
const destination = request.mode === 'navigate' ? 'document' : request.destination;
|
|
158
|
+
for (const rule of routes) {
|
|
159
|
+
if (!sameOrigin && !rule.crossOrigin)
|
|
160
|
+
continue;
|
|
161
|
+
if (rule.destinations.length > 0 && !rule.destinations.includes(destination))
|
|
162
|
+
continue;
|
|
163
|
+
if (rule.pattern !== null && !new RegExp(rule.pattern).test(pathAndQuery))
|
|
164
|
+
continue;
|
|
165
|
+
return {
|
|
166
|
+
strategy: rule.strategy,
|
|
167
|
+
bucket: rule.bucket,
|
|
168
|
+
maxEntries: rule.maxEntries,
|
|
169
|
+
networkTimeoutMs: rule.networkTimeoutMs,
|
|
170
|
+
ruleId: rule.id,
|
|
171
|
+
reason: `matched rule ${rule.id}`,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
// No rule claimed it, so we do not touch it. Defaulting to a cache here would
|
|
175
|
+
// mean the service worker quietly takes ownership of resources nobody
|
|
176
|
+
// reasoned about, including opaque cross-origin responses whose status it
|
|
177
|
+
// cannot even read.
|
|
178
|
+
return bypass(sameOrigin ? `no rule matches destination "${destination}"` : 'cross-origin request');
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strategy.js","sourceRoot":"","sources":["../../src/pwa/strategy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type { PwaConfig } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* The service worker runtime, written as ordinary TypeScript.
|
|
4
|
+
*
|
|
5
|
+
* It is never *imported* by a browser: `renderServiceWorker` inlines the source
|
|
6
|
+
* text of these functions into the script it generates. That indirection buys
|
|
7
|
+
* three things a hand-written string template cannot. The runtime is
|
|
8
|
+
* type-checked and linted like the rest of the package. The routing decision
|
|
9
|
+
* shipped to browsers is character-for-character the function the unit tests
|
|
10
|
+
* exercise, so the two cannot drift. And there is no bundler in the loop, which
|
|
11
|
+
* matters because a service worker must be one self-contained file served from
|
|
12
|
+
* the site root.
|
|
13
|
+
*
|
|
14
|
+
* The constraint that comes with it: **nothing in this file may reference
|
|
15
|
+
* module scope.** Only the parameters, and the three helpers that are inlined
|
|
16
|
+
* alongside (`chooseStrategy`, `cacheNameFor`, `cachesToPurge`). A test asserts
|
|
17
|
+
* that the generated script defines each of them.
|
|
18
|
+
*
|
|
19
|
+
* The scope is typed against the minimal interfaces below rather than
|
|
20
|
+
* `lib.webworker`: the package compiles with `lib: ES2023`, and a narrow
|
|
21
|
+
* hand-written surface documents exactly which browser APIs the worker is
|
|
22
|
+
* allowed to touch.
|
|
23
|
+
*/
|
|
24
|
+
export interface ExtendableEventLike {
|
|
25
|
+
waitUntil(promise: Promise<unknown>): void;
|
|
26
|
+
}
|
|
27
|
+
export interface HeadersLike {
|
|
28
|
+
has(name: string): boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface RequestLike {
|
|
31
|
+
readonly method: string;
|
|
32
|
+
readonly url: string;
|
|
33
|
+
readonly destination: string;
|
|
34
|
+
readonly mode: string;
|
|
35
|
+
readonly cache: string;
|
|
36
|
+
readonly headers: HeadersLike;
|
|
37
|
+
}
|
|
38
|
+
export interface ResponseLike {
|
|
39
|
+
readonly ok: boolean;
|
|
40
|
+
readonly status: number;
|
|
41
|
+
clone(): ResponseLike;
|
|
42
|
+
}
|
|
43
|
+
export interface FetchEventLike extends ExtendableEventLike {
|
|
44
|
+
readonly request: RequestLike;
|
|
45
|
+
respondWith(response: Promise<ResponseLike>): void;
|
|
46
|
+
}
|
|
47
|
+
export interface MessageEventLike extends ExtendableEventLike {
|
|
48
|
+
readonly data: unknown;
|
|
49
|
+
}
|
|
50
|
+
export interface CacheLike {
|
|
51
|
+
match(request: RequestLike | string): Promise<ResponseLike | undefined>;
|
|
52
|
+
put(request: RequestLike | string, response: ResponseLike): Promise<void>;
|
|
53
|
+
addAll(urls: readonly string[]): Promise<void>;
|
|
54
|
+
keys(): Promise<readonly RequestLike[]>;
|
|
55
|
+
delete(request: RequestLike | string): Promise<boolean>;
|
|
56
|
+
}
|
|
57
|
+
export interface CacheStorageLike {
|
|
58
|
+
open(name: string): Promise<CacheLike>;
|
|
59
|
+
keys(): Promise<string[]>;
|
|
60
|
+
delete(name: string): Promise<boolean>;
|
|
61
|
+
}
|
|
62
|
+
export interface WindowClientLike {
|
|
63
|
+
postMessage(message: unknown): void;
|
|
64
|
+
}
|
|
65
|
+
export interface ClientsLike {
|
|
66
|
+
claim(): Promise<void>;
|
|
67
|
+
matchAll(options: {
|
|
68
|
+
type: 'window';
|
|
69
|
+
}): Promise<readonly WindowClientLike[]>;
|
|
70
|
+
}
|
|
71
|
+
export interface ResponseInitLike {
|
|
72
|
+
readonly status?: number;
|
|
73
|
+
readonly headers?: Record<string, string>;
|
|
74
|
+
}
|
|
75
|
+
export interface ServiceWorkerScope {
|
|
76
|
+
addEventListener(type: 'install' | 'activate', handler: (event: ExtendableEventLike) => void): void;
|
|
77
|
+
addEventListener(type: 'fetch', handler: (event: FetchEventLike) => void): void;
|
|
78
|
+
addEventListener(type: 'message', handler: (event: MessageEventLike) => void): void;
|
|
79
|
+
readonly caches: CacheStorageLike;
|
|
80
|
+
readonly clients: ClientsLike;
|
|
81
|
+
readonly registration: {
|
|
82
|
+
unregister(): Promise<boolean>;
|
|
83
|
+
};
|
|
84
|
+
readonly location: {
|
|
85
|
+
readonly origin: string;
|
|
86
|
+
};
|
|
87
|
+
readonly Response: new (body: string | null, init?: ResponseInitLike) => ResponseLike;
|
|
88
|
+
fetch(request: RequestLike): Promise<ResponseLike>;
|
|
89
|
+
skipWaiting(): Promise<void>;
|
|
90
|
+
setTimeout(handler: () => void, ms: number): unknown;
|
|
91
|
+
}
|
|
92
|
+
/** Messages the page may send the worker. Part of the public PWA contract. */
|
|
93
|
+
export declare const SW_MESSAGE_PURGE = "cogenta:purge";
|
|
94
|
+
export declare const SW_MESSAGE_UNREGISTER = "cogenta:unregister";
|
|
95
|
+
export declare const SW_MESSAGE_ACTIVATED = "cogenta:activated";
|
|
96
|
+
export declare const SW_MESSAGE_UNREGISTERED = "cogenta:unregistered";
|
|
97
|
+
export declare function serviceWorkerMain(scope: ServiceWorkerScope, config: PwaConfig): void;
|
|
98
|
+
/**
|
|
99
|
+
* The tombstone worker.
|
|
100
|
+
*
|
|
101
|
+
* Deployed at the *same URL* as the real worker when the PWA has to be turned
|
|
102
|
+
* off. It registers no fetch handler, empties every cache the site owns and
|
|
103
|
+
* unregisters itself. Browsers re-fetch a service worker script at least every
|
|
104
|
+
* 24 hours, so shipping this file is the only mechanism that reaches clients we
|
|
105
|
+
* can no longer run code on — which is precisely the situation the "zombie
|
|
106
|
+
* worker" incident describes.
|
|
107
|
+
*/
|
|
108
|
+
export declare function tombstoneMain(scope: ServiceWorkerScope, cachePrefix: string): void;
|
|
109
|
+
//# sourceMappingURL=sw-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sw-runtime.d.ts","sourceRoot":"","sources":["../../src/pwa/sw-runtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAuC,MAAM,YAAY,CAAA;AAGhF;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAA;CAC3C;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;CAC9B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,KAAK,IAAI,YAAY,CAAA;CACtB;AAED,MAAM,WAAW,cAAe,SAAQ,mBAAmB;IACzD,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,CAAA;CACnD;AAED,MAAM,WAAW,gBAAiB,SAAQ,mBAAmB;IAC3D,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CACvB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAAA;IACvE,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACzE,MAAM,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9C,IAAI,IAAI,OAAO,CAAC,SAAS,WAAW,EAAE,CAAC,CAAA;IACvC,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACxD;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;IACtC,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IACzB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACvC;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;CACpC;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,QAAQ,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,gBAAgB,EAAE,CAAC,CAAA;CAC5E;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC1C;AAED,MAAM,WAAW,kBAAkB;IACjC,gBAAgB,CACd,IAAI,EAAE,SAAS,GAAG,UAAU,EAC5B,OAAO,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,GAC5C,IAAI,CAAA;IACP,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,GAAG,IAAI,CAAA;IAC/E,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,GAAG,IAAI,CAAA;IACnF,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAA;IACjC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,QAAQ,CAAC,YAAY,EAAE;QAAE,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,CAAA;IACzD,QAAQ,CAAC,QAAQ,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IAC9C,QAAQ,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,CAAC,EAAE,gBAAgB,KAAK,YAAY,CAAA;IACrF,KAAK,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IAClD,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5B,UAAU,CAAC,OAAO,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAA;CACrD;AAED,8EAA8E;AAC9E,eAAO,MAAM,gBAAgB,kBAAkB,CAAA;AAC/C,eAAO,MAAM,qBAAqB,uBAAuB,CAAA;AACzD,eAAO,MAAM,oBAAoB,sBAAsB,CAAA;AACvD,eAAO,MAAM,uBAAuB,yBAAyB,CAAA;AAE7D,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAiNpF;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAoBlF"}
|