@jmus/underrated-fetch 1.0.7 → 1.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/README.md +37 -15
- package/dist/underrated-fetch.d.ts.map +1 -1
- package/dist/underrated-fetch.js +31 -12
- package/dist/underrated-fetch.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
[](https://www.npmjs.com/package/@jmus/underrated-fetch)
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
|
|
8
|
-
|
|
9
8
|
A simple **Node.js** wrapper around `fetch` that adds **TTL-based caching** for **JSON REST APIs**.
|
|
10
9
|
|
|
11
10
|
Designed to reduce redundant outbound requests and avoid rate limits when calling external APIs.
|
|
@@ -42,6 +41,7 @@ flowchart LR
|
|
|
42
41
|
## Why?
|
|
43
42
|
|
|
44
43
|
External APIs often have:
|
|
44
|
+
|
|
45
45
|
- Rate limits
|
|
46
46
|
- Latency
|
|
47
47
|
- Usage quotas
|
|
@@ -58,6 +58,7 @@ If your app repeatedly calls the same endpoint, `underrated-fetch` caches respon
|
|
|
58
58
|
- ✅ Built-in in-memory LRU cache
|
|
59
59
|
- ✅ Pluggable cache stores (Redis, DB, etc.)
|
|
60
60
|
- ✅ Cache hit / miss hooks for metrics
|
|
61
|
+
- ✅ Request deduplication for concurrent requests
|
|
61
62
|
|
|
62
63
|
---
|
|
63
64
|
|
|
@@ -89,13 +90,13 @@ npm install underrated-fetch
|
|
|
89
90
|
## Quick Start
|
|
90
91
|
|
|
91
92
|
```ts
|
|
92
|
-
import { createCachedFetch } from
|
|
93
|
+
import { createCachedFetch } from "underrated-fetch";
|
|
93
94
|
|
|
94
95
|
const cachedFetch = createCachedFetch({ timeToLive: 60_000 });
|
|
95
96
|
|
|
96
97
|
// Works like fetch, but cached
|
|
97
|
-
const user = await cachedFetch(
|
|
98
|
-
const same = await cachedFetch(
|
|
98
|
+
const user = await cachedFetch("https://api.example.com/users/123");
|
|
99
|
+
const same = await cachedFetch("https://api.example.com/users/123"); // cache hit
|
|
99
100
|
```
|
|
100
101
|
|
|
101
102
|
Cache keys are automatically derived from the URL path and query:
|
|
@@ -115,12 +116,12 @@ Creates a cached fetch function.
|
|
|
115
116
|
|
|
116
117
|
```ts
|
|
117
118
|
const cachedFetch = createCachedFetch({
|
|
118
|
-
timeToLive: 60_000,
|
|
119
|
-
store: customStore,
|
|
119
|
+
timeToLive: 60_000, // Required: default TTL (ms)
|
|
120
|
+
store: customStore, // Optional: custom cache store
|
|
120
121
|
memoryStoreOptions: { maxSize: 5000 }, // Optional: configure memory store
|
|
121
|
-
shouldCache: (data) => true,
|
|
122
|
-
onHitCallback: (key) => {},
|
|
123
|
-
onMissCallback: (key) => {},
|
|
122
|
+
shouldCache: (data) => true, // Optional: conditionally cache
|
|
123
|
+
onHitCallback: (key) => {}, // Optional: called on cache hit
|
|
124
|
+
onMissCallback: (key) => {}, // Optional: called on cache miss
|
|
124
125
|
});
|
|
125
126
|
```
|
|
126
127
|
|
|
@@ -129,8 +130,8 @@ const cachedFetch = createCachedFetch({
|
|
|
129
130
|
### Per-request TTL
|
|
130
131
|
|
|
131
132
|
```ts
|
|
132
|
-
await cachedFetch(
|
|
133
|
-
await cachedFetch(
|
|
133
|
+
await cachedFetch("https://api.example.com/data"); // default TTL
|
|
134
|
+
await cachedFetch("https://api.example.com/live", { timeToLive: 5_000 });
|
|
134
135
|
```
|
|
135
136
|
|
|
136
137
|
---
|
|
@@ -189,7 +190,7 @@ See `examples/redis-store.ts` for a complete Redis implementation.
|
|
|
189
190
|
```ts
|
|
190
191
|
const cachedFetch = createCachedFetch({
|
|
191
192
|
timeToLive: 60_000,
|
|
192
|
-
shouldCache: (data) => data.status ===
|
|
193
|
+
shouldCache: (data) => data.status === "success",
|
|
193
194
|
});
|
|
194
195
|
```
|
|
195
196
|
|
|
@@ -200,18 +201,38 @@ const cachedFetch = createCachedFetch({
|
|
|
200
201
|
```ts
|
|
201
202
|
const cachedFetch = createCachedFetch({
|
|
202
203
|
timeToLive: 60_000,
|
|
203
|
-
onHitCallback: () => metrics.increment(
|
|
204
|
-
onMissCallback: () => metrics.increment(
|
|
204
|
+
onHitCallback: () => metrics.increment("cache.hit"),
|
|
205
|
+
onMissCallback: () => metrics.increment("cache.miss"),
|
|
205
206
|
});
|
|
206
207
|
```
|
|
207
208
|
|
|
208
209
|
---
|
|
209
210
|
|
|
211
|
+
## Concurrent Request Deduplication
|
|
212
|
+
|
|
213
|
+
When multiple requests for the same URL happen simultaneously (before any complete), `underrated-fetch` automatically deduplicates them to a single network call. All requests share the same promise and receive the same response.
|
|
214
|
+
|
|
215
|
+
```ts
|
|
216
|
+
// All 5 requests share a single fetch call
|
|
217
|
+
const promises = await Promise.all([
|
|
218
|
+
cachedFetch("https://api.example.com/users/123"),
|
|
219
|
+
cachedFetch("https://api.example.com/users/123"),
|
|
220
|
+
cachedFetch("https://api.example.com/users/123"),
|
|
221
|
+
cachedFetch("https://api.example.com/users/123"),
|
|
222
|
+
cachedFetch("https://api.example.com/users/123"),
|
|
223
|
+
]);
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
This prevents redundant network calls when multiple parts of your application request the same data at the same time, further reducing rate-limit pressure and improving performance.
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
210
230
|
## Security
|
|
211
231
|
|
|
212
232
|
⚠️ Cached data is **not encrypted**.
|
|
213
233
|
|
|
214
234
|
Do **not** cache:
|
|
235
|
+
|
|
215
236
|
- API keys or authentication tokens
|
|
216
237
|
- Passwords or credentials
|
|
217
238
|
- Personally identifiable information (PII)
|
|
@@ -221,6 +242,7 @@ Do **not** cache:
|
|
|
221
242
|
## When should I use this?
|
|
222
243
|
|
|
223
244
|
Use `underrated-fetch` if you:
|
|
245
|
+
|
|
224
246
|
- Call third-party REST APIs from Node.js
|
|
225
247
|
- Want simple, predictable caching
|
|
226
248
|
- Need to reduce rate-limit pressure
|
|
@@ -237,4 +259,4 @@ Use `underrated-fetch` if you:
|
|
|
237
259
|
|
|
238
260
|
## License
|
|
239
261
|
|
|
240
|
-
MIT
|
|
262
|
+
MIT
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"underrated-fetch.d.ts","sourceRoot":"","sources":["../src/underrated-fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAG7E;;;GAGG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAE1D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAO1E;AAYD;;;;GAIG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC,GAAG,OAAO;IAC7C,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAC;IAEnB,oDAAoD;IACpD,KAAK,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IAEtB,0EAA0E;IAC1E,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAE3C,sEAAsE;IACtE,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;IAEnC,0BAA0B;IAC1B,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAEtC,2BAA2B;IAC3B,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED;;;GAGG;AACH,MAAM,WAAW,YAAa,SAAQ,WAAW;IAC/C,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,GAAG,OAAO,EAC3C,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC7B,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"underrated-fetch.d.ts","sourceRoot":"","sources":["../src/underrated-fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAG7E;;;GAGG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAE1D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAO1E;AAYD;;;;GAIG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC,GAAG,OAAO;IAC7C,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAC;IAEnB,oDAAoD;IACpD,KAAK,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IAEtB,0EAA0E;IAC1E,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAE3C,sEAAsE;IACtE,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;IAEnC,0BAA0B;IAC1B,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAEtC,2BAA2B;IAC3B,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED;;;GAGG;AACH,MAAM,WAAW,YAAa,SAAQ,WAAW;IAC/C,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,GAAG,OAAO,EAC3C,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC7B,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC,CAAC,CAkIlD"}
|
package/dist/underrated-fetch.js
CHANGED
|
@@ -49,6 +49,8 @@ export function createCachedFetch(options) {
|
|
|
49
49
|
const { timeToLive: defaultTimeToLive, store: providedStore, memoryStoreOptions, shouldCache, onHitCallback, onMissCallback, } = options;
|
|
50
50
|
validateTimeToLive(defaultTimeToLive);
|
|
51
51
|
const store = providedStore ?? createMemoryStore(memoryStoreOptions);
|
|
52
|
+
// Map to track in-flight requests for deduplication
|
|
53
|
+
const inFlightRequests = new Map();
|
|
52
54
|
/**
|
|
53
55
|
* Generate cache key from URL.
|
|
54
56
|
* Uses pathname + search params (excludes domain).
|
|
@@ -113,21 +115,38 @@ export function createCachedFetch(options) {
|
|
|
113
115
|
}
|
|
114
116
|
return entry.value;
|
|
115
117
|
}
|
|
116
|
-
//
|
|
118
|
+
// Check if there's already an in-flight request for this key
|
|
119
|
+
const inFlightPromise = inFlightRequests.get(key);
|
|
120
|
+
if (inFlightPromise) {
|
|
121
|
+
return inFlightPromise;
|
|
122
|
+
}
|
|
123
|
+
// Cache miss - create new fetch request
|
|
117
124
|
if (onMissCallback) {
|
|
118
125
|
onMissCallback(key);
|
|
119
126
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
127
|
+
// Create the fetch promise and store it in the in-flight map
|
|
128
|
+
const fetchPromise = (async () => {
|
|
129
|
+
try {
|
|
130
|
+
const response = await fetch(url, fetchInit);
|
|
131
|
+
if (!response.ok) {
|
|
132
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
133
|
+
}
|
|
134
|
+
const data = await parseJSON(response);
|
|
135
|
+
// Check if result should be cached
|
|
136
|
+
const shouldCacheResult = shouldCache ? shouldCache(data) : true;
|
|
137
|
+
if (shouldCacheResult) {
|
|
138
|
+
await store.set(key, createEntry(data, timeToLive));
|
|
139
|
+
}
|
|
140
|
+
return data;
|
|
141
|
+
}
|
|
142
|
+
finally {
|
|
143
|
+
// Clean up in-flight map entry after completion (success or failure)
|
|
144
|
+
inFlightRequests.delete(key);
|
|
145
|
+
}
|
|
146
|
+
})();
|
|
147
|
+
// Store the promise in the in-flight map
|
|
148
|
+
inFlightRequests.set(key, fetchPromise);
|
|
149
|
+
return fetchPromise;
|
|
131
150
|
}
|
|
132
151
|
return cachedFetch;
|
|
133
152
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"underrated-fetch.js","sourceRoot":"","sources":["../src/underrated-fetch.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"underrated-fetch.js","sourceRoot":"","sources":["../src/underrated-fetch.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAI,KAAoB;IAC/C,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAI,KAAQ,EAAE,UAAkB;IACzD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,OAAO;QACL,KAAK;QACL,SAAS,EAAE,GAAG;QACd,SAAS,EAAE,GAAG,GAAG,UAAU;KAC5B,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,kBAAkB,CAAC,KAAa,EAAE,OAAO,GAAG,YAAY;IAC/D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO,mCAAmC,CAAC,CAAC;IACjE,CAAC;AACH,CAAC;AAoCD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAA8B;IAE9B,MAAM,EACJ,UAAU,EAAE,iBAAiB,EAC7B,KAAK,EAAE,aAAa,EACpB,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,cAAc,GACf,GAAG,OAAO,CAAC;IAEZ,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;IAEtC,MAAM,KAAK,GAAkB,aAAa,IAAI,iBAAiB,CAAI,kBAAkB,CAAC,CAAC;IAEvF,oDAAoD;IACpD,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAsB,CAAC;IAEvD;;;OAGG;IACH,SAAS,WAAW,CAAC,GAAW;QAC9B,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,OAAO,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,KAAK,UAAU,SAAS,CAAC,QAAkB;QACzC,IAAI,CAAC;YACH,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAO,CAAC;QACpC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,SAAS,CAAC;YACtE,MAAM,IAAI,KAAK,CACb,gDAAgD,WAAW,IAAI;gBAC/D,6CAA6C;gBAC7C,mBAAmB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC5E,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,UAAU,aAAa,CAAC,GAAW;QACtC,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAC7B,IAAI,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACrB,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACxB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,KAAK,UAAU,WAAW,CAAC,GAAW,EAAE,IAAmB;QACzD,4DAA4D;QAC5D,MAAM,EAAE,UAAU,EAAE,iBAAiB,EAAE,GAAG,SAAS,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC;QACnE,MAAM,UAAU,GAAG,iBAAiB,IAAI,iBAAiB,CAAC;QAE1D,uCAAuC;QACvC,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;YACpC,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;QACxC,CAAC;QAED,0BAA0B;QAC1B,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,KAAK,CAAC;QACxD,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;YACrB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;YAC7C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;YACrE,CAAC;YACD,OAAO,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC7B,CAAC;QAED,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAE7B,cAAc;QACd,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,aAAa,EAAE,CAAC;gBAClB,aAAa,CAAC,GAAG,CAAC,CAAC;YACrB,CAAC;YACD,OAAO,KAAK,CAAC,KAAK,CAAC;QACrB,CAAC;QAED,6DAA6D;QAC7D,MAAM,eAAe,GAAG,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClD,IAAI,eAAe,EAAE,CAAC;YACpB,OAAO,eAAe,CAAC;QACzB,CAAC;QAED,wCAAwC;QACxC,IAAI,cAAc,EAAE,CAAC;YACnB,cAAc,CAAC,GAAG,CAAC,CAAC;QACtB,CAAC;QAED,6DAA6D;QAC7D,MAAM,YAAY,GAAG,CAAC,KAAK,IAAgB,EAAE;YAC3C,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;gBAC7C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;oBACjB,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;gBACrE,CAAC;gBAED,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAC;gBAEvC,mCAAmC;gBACnC,MAAM,iBAAiB,GAAG,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;gBACjE,IAAI,iBAAiB,EAAE,CAAC;oBACtB,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;gBACtD,CAAC;gBAED,OAAO,IAAI,CAAC;YACd,CAAC;oBAAS,CAAC;gBACT,qEAAqE;gBACrE,gBAAgB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;QAEL,yCAAyC;QACzC,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QAExC,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC"}
|