bitfab 0.14.0 → 0.16.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/{chunk-RMQX546G.js → chunk-53G5GR7B.js} +369 -12
- package/dist/chunk-53G5GR7B.js.map +1 -0
- package/dist/chunk-QT7HWOKU.js +131 -0
- package/dist/chunk-QT7HWOKU.js.map +1 -0
- package/dist/index.cjs +414 -394
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +41 -2
- package/dist/index.d.ts +41 -2
- package/dist/index.js +6 -6
- package/dist/node.cjs +414 -394
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +5 -5
- package/dist/{replay-LNP2K3DN.js → replay-WIBKB3BK.js} +52 -17
- package/dist/replay-WIBKB3BK.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-OW2EJK7T.js +0 -470
- package/dist/chunk-OW2EJK7T.js.map +0 -1
- package/dist/chunk-RMQX546G.js.map +0 -1
- package/dist/replay-LNP2K3DN.js.map +0 -1
|
@@ -1,14 +1,350 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BitfabError,
|
|
3
|
-
DEFAULT_SERVICE_URL,
|
|
4
|
-
HttpClient,
|
|
5
3
|
asyncStorageReady,
|
|
6
4
|
createAsyncLocalStorage,
|
|
7
5
|
deserializeValue,
|
|
8
6
|
getReplayContext,
|
|
9
7
|
isAsyncStorageInitDone,
|
|
10
8
|
serializeValue
|
|
11
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-QT7HWOKU.js";
|
|
10
|
+
|
|
11
|
+
// src/version.generated.ts
|
|
12
|
+
var __version__ = "0.16.0";
|
|
13
|
+
|
|
14
|
+
// src/constants.ts
|
|
15
|
+
var DEFAULT_SERVICE_URL = "https://bitfab.ai";
|
|
16
|
+
|
|
17
|
+
// src/http.ts
|
|
18
|
+
var pendingTracePromises = /* @__PURE__ */ new Set();
|
|
19
|
+
function awaitOnExit(promise) {
|
|
20
|
+
pendingTracePromises.add(promise);
|
|
21
|
+
void promise.finally(() => {
|
|
22
|
+
pendingTracePromises.delete(promise);
|
|
23
|
+
}).catch(() => {
|
|
24
|
+
});
|
|
25
|
+
return promise;
|
|
26
|
+
}
|
|
27
|
+
async function flushTraces(timeoutMs = 5e3) {
|
|
28
|
+
if (pendingTracePromises.size === 0) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
await Promise.race([
|
|
32
|
+
Promise.allSettled(Array.from(pendingTracePromises)),
|
|
33
|
+
new Promise((resolve) => setTimeout(resolve, timeoutMs))
|
|
34
|
+
]);
|
|
35
|
+
}
|
|
36
|
+
if (typeof process !== "undefined" && process.versions != null && process.versions.node != null) {
|
|
37
|
+
let isFlushing = false;
|
|
38
|
+
process.on("beforeExit", () => {
|
|
39
|
+
if (pendingTracePromises.size > 0 && !isFlushing) {
|
|
40
|
+
isFlushing = true;
|
|
41
|
+
Promise.allSettled(
|
|
42
|
+
Array.from(pendingTracePromises).map(
|
|
43
|
+
(p) => p.catch(() => {
|
|
44
|
+
})
|
|
45
|
+
)
|
|
46
|
+
).then(() => {
|
|
47
|
+
isFlushing = false;
|
|
48
|
+
}).catch(() => {
|
|
49
|
+
isFlushing = false;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
var HttpClient = class {
|
|
55
|
+
constructor(config) {
|
|
56
|
+
this.apiKey = config.apiKey;
|
|
57
|
+
this.serviceUrl = config.serviceUrl;
|
|
58
|
+
this.timeout = config.timeout ?? 12e4;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Make an HTTP request to the Bitfab API. Defaults to POST; pass
|
|
62
|
+
* `options.method` to use a different verb (e.g. "PATCH").
|
|
63
|
+
*
|
|
64
|
+
* @param endpoint - The API endpoint (without base URL)
|
|
65
|
+
* @param payload - The request body
|
|
66
|
+
* @param options - Optional request options
|
|
67
|
+
* @returns The parsed JSON response
|
|
68
|
+
* @throws {BitfabError} If the request fails
|
|
69
|
+
*/
|
|
70
|
+
async request(endpoint, payload, options) {
|
|
71
|
+
const url = `${this.serviceUrl}${endpoint}`;
|
|
72
|
+
const timeout = options?.timeout ?? this.timeout;
|
|
73
|
+
const method = options?.method ?? "POST";
|
|
74
|
+
const controller = new AbortController();
|
|
75
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
76
|
+
let body;
|
|
77
|
+
let serializationError;
|
|
78
|
+
try {
|
|
79
|
+
body = JSON.stringify(payload);
|
|
80
|
+
} catch (error) {
|
|
81
|
+
serializationError = error instanceof Error ? error.message : String(error);
|
|
82
|
+
body = JSON.stringify({
|
|
83
|
+
...Object.fromEntries(
|
|
84
|
+
Object.entries(payload).filter(
|
|
85
|
+
([, v]) => typeof v === "string" || typeof v === "number"
|
|
86
|
+
)
|
|
87
|
+
),
|
|
88
|
+
rawSpan: {},
|
|
89
|
+
errors: [
|
|
90
|
+
{ source: "sdk", step: "json_serialize", error: serializationError }
|
|
91
|
+
]
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
const response = await fetch(url, {
|
|
96
|
+
method,
|
|
97
|
+
headers: {
|
|
98
|
+
"Content-Type": "application/json",
|
|
99
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
100
|
+
},
|
|
101
|
+
body,
|
|
102
|
+
signal: controller.signal
|
|
103
|
+
});
|
|
104
|
+
if (!response.ok) {
|
|
105
|
+
const errorText = await response.text();
|
|
106
|
+
throw new BitfabError(
|
|
107
|
+
`HTTP ${response.status}: ${errorText.slice(0, 500)}`
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
const result = await response.json();
|
|
111
|
+
if (result.error) {
|
|
112
|
+
if (result.url) {
|
|
113
|
+
throw new BitfabError(
|
|
114
|
+
`${result.error} Configure it at: ${this.serviceUrl}${result.url}`,
|
|
115
|
+
result.url
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
throw new BitfabError(result.error);
|
|
119
|
+
}
|
|
120
|
+
return result;
|
|
121
|
+
} catch (error) {
|
|
122
|
+
if (error instanceof BitfabError) {
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
125
|
+
if (error instanceof Error) {
|
|
126
|
+
if (error.name === "AbortError") {
|
|
127
|
+
throw new BitfabError(`Request timed out after ${timeout}ms`);
|
|
128
|
+
}
|
|
129
|
+
throw new BitfabError(error.message);
|
|
130
|
+
}
|
|
131
|
+
throw new BitfabError("Unknown error occurred");
|
|
132
|
+
} finally {
|
|
133
|
+
clearTimeout(timeoutId);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Look up a function by name.
|
|
138
|
+
* Blocks until complete - needed for function execution.
|
|
139
|
+
*/
|
|
140
|
+
async lookupFunction(name) {
|
|
141
|
+
return this.request("/api/sdk/functions/lookup", { name });
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Send an internal trace (from BAML execution).
|
|
145
|
+
* Fire-and-forget with awaitOnExit - doesn't block the caller.
|
|
146
|
+
*/
|
|
147
|
+
sendInternalTrace(functionId, payload) {
|
|
148
|
+
void awaitOnExit(
|
|
149
|
+
this.request(`/api/sdk/functions/${functionId}/traces`, {
|
|
150
|
+
...payload,
|
|
151
|
+
sdkVersion: __version__
|
|
152
|
+
})
|
|
153
|
+
).catch((error) => {
|
|
154
|
+
try {
|
|
155
|
+
console.error("Bitfab: Failed to create trace:", error);
|
|
156
|
+
} catch {
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Send an external span (from withSpan wrapper or OpenAI tracing).
|
|
162
|
+
* Fire-and-forget with awaitOnExit - doesn't block the caller.
|
|
163
|
+
* Returns the tracked promise so callers can optionally await it.
|
|
164
|
+
*/
|
|
165
|
+
sendExternalSpan(payload) {
|
|
166
|
+
return awaitOnExit(
|
|
167
|
+
this.request("/api/sdk/externalSpans", {
|
|
168
|
+
...payload,
|
|
169
|
+
sdkVersion: __version__
|
|
170
|
+
})
|
|
171
|
+
).catch((error) => {
|
|
172
|
+
try {
|
|
173
|
+
console.error("Bitfab: Failed to create external span:", error);
|
|
174
|
+
} catch {
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Send an external trace (from OpenAI tracing).
|
|
180
|
+
* Fire-and-forget with awaitOnExit - doesn't block the caller.
|
|
181
|
+
* Returns the tracked promise so callers can optionally await it
|
|
182
|
+
* (the replay path does, so trace completions are persisted before
|
|
183
|
+
* `completeReplay` builds the trace-ID mapping).
|
|
184
|
+
*/
|
|
185
|
+
sendExternalTrace(payload) {
|
|
186
|
+
return awaitOnExit(
|
|
187
|
+
this.request("/api/sdk/externalTraces", {
|
|
188
|
+
...payload,
|
|
189
|
+
sdkVersion: __version__
|
|
190
|
+
})
|
|
191
|
+
).catch((error) => {
|
|
192
|
+
try {
|
|
193
|
+
console.error("Bitfab: Failed to create external trace:", error);
|
|
194
|
+
} catch {
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Partial update of an existing external trace identified by sourceTraceId.
|
|
200
|
+
* Used by the detached `client.getTrace(id)` handle. Fire-and-forget;
|
|
201
|
+
* returns a tracked promise that callers may optionally await.
|
|
202
|
+
*/
|
|
203
|
+
patchTrace(sourceTraceId, payload) {
|
|
204
|
+
const endpoint = `/api/sdk/externalTraces/${encodeURIComponent(sourceTraceId)}`;
|
|
205
|
+
return awaitOnExit(
|
|
206
|
+
this.request(endpoint, payload, { method: "PATCH" })
|
|
207
|
+
).catch((error) => {
|
|
208
|
+
try {
|
|
209
|
+
console.error("Bitfab: Failed to patch trace:", error);
|
|
210
|
+
} catch {
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Start a replay session by fetching historical traces.
|
|
216
|
+
* Blocking call — creates a test run and returns lightweight item references.
|
|
217
|
+
*/
|
|
218
|
+
async startReplay(traceFunctionKey, limit, traceIds, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId) {
|
|
219
|
+
const payload = { traceFunctionKey };
|
|
220
|
+
if (limit !== void 0) {
|
|
221
|
+
payload.limit = limit;
|
|
222
|
+
}
|
|
223
|
+
if (traceIds) {
|
|
224
|
+
payload.traceIds = traceIds;
|
|
225
|
+
}
|
|
226
|
+
if (codeChangeDescription !== void 0) {
|
|
227
|
+
payload.codeChangeDescription = codeChangeDescription;
|
|
228
|
+
}
|
|
229
|
+
if (codeChangeFiles !== void 0) {
|
|
230
|
+
payload.codeChangeFiles = codeChangeFiles;
|
|
231
|
+
}
|
|
232
|
+
if (includeDbBranchLease) {
|
|
233
|
+
payload.includeDbBranchLease = true;
|
|
234
|
+
}
|
|
235
|
+
if (experimentGroupId !== void 0) {
|
|
236
|
+
payload.experimentGroupId = experimentGroupId;
|
|
237
|
+
}
|
|
238
|
+
const timeout = includeDbBranchLease ? 18e4 : 3e4;
|
|
239
|
+
return this.request("/api/sdk/replay/start", payload, {
|
|
240
|
+
timeout
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Fetch an external span by ID.
|
|
245
|
+
* Blocking GET request.
|
|
246
|
+
*/
|
|
247
|
+
async getExternalSpan(spanId) {
|
|
248
|
+
const url = `${this.serviceUrl}/api/sdk/externalSpans/${spanId}`;
|
|
249
|
+
const controller = new AbortController();
|
|
250
|
+
const timeoutId = setTimeout(() => controller.abort(), 3e4);
|
|
251
|
+
try {
|
|
252
|
+
const response = await fetch(url, {
|
|
253
|
+
method: "GET",
|
|
254
|
+
headers: { Authorization: `Bearer ${this.apiKey}` },
|
|
255
|
+
signal: controller.signal
|
|
256
|
+
});
|
|
257
|
+
if (!response.ok) {
|
|
258
|
+
const errorText = await response.text();
|
|
259
|
+
throw new BitfabError(
|
|
260
|
+
`HTTP ${response.status}: ${errorText.slice(0, 500)}`
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
return await response.json();
|
|
264
|
+
} catch (error) {
|
|
265
|
+
if (error instanceof BitfabError) {
|
|
266
|
+
throw error;
|
|
267
|
+
}
|
|
268
|
+
if (error instanceof Error) {
|
|
269
|
+
if (error.name === "AbortError") {
|
|
270
|
+
throw new BitfabError("Request timed out after 30000ms");
|
|
271
|
+
}
|
|
272
|
+
throw new BitfabError(error.message);
|
|
273
|
+
}
|
|
274
|
+
throw new BitfabError("Unknown error occurred");
|
|
275
|
+
} finally {
|
|
276
|
+
clearTimeout(timeoutId);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Fetch the span tree for a root span.
|
|
281
|
+
* Blocking GET request.
|
|
282
|
+
*/
|
|
283
|
+
async getSpanTree(externalSpanId) {
|
|
284
|
+
const url = `${this.serviceUrl}/api/sdk/replay/spanTree/${externalSpanId}`;
|
|
285
|
+
const controller = new AbortController();
|
|
286
|
+
const timeoutId = setTimeout(() => controller.abort(), 3e4);
|
|
287
|
+
try {
|
|
288
|
+
const response = await fetch(url, {
|
|
289
|
+
method: "GET",
|
|
290
|
+
headers: { Authorization: `Bearer ${this.apiKey}` },
|
|
291
|
+
signal: controller.signal
|
|
292
|
+
});
|
|
293
|
+
if (!response.ok) {
|
|
294
|
+
const errorText = await response.text();
|
|
295
|
+
throw new BitfabError(
|
|
296
|
+
`HTTP ${response.status}: ${errorText.slice(0, 500)}`
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
return await response.json();
|
|
300
|
+
} catch (error) {
|
|
301
|
+
if (error instanceof BitfabError) {
|
|
302
|
+
throw error;
|
|
303
|
+
}
|
|
304
|
+
if (error instanceof Error) {
|
|
305
|
+
if (error.name === "AbortError") {
|
|
306
|
+
throw new BitfabError("Request timed out after 30000ms");
|
|
307
|
+
}
|
|
308
|
+
throw new BitfabError(error.message);
|
|
309
|
+
}
|
|
310
|
+
throw new BitfabError("Unknown error occurred");
|
|
311
|
+
} finally {
|
|
312
|
+
clearTimeout(timeoutId);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Mark a replay test run as completed.
|
|
317
|
+
* Blocking call.
|
|
318
|
+
*/
|
|
319
|
+
async completeReplay(testRunId) {
|
|
320
|
+
return this.request(
|
|
321
|
+
"/api/sdk/replay/complete",
|
|
322
|
+
{ testRunId },
|
|
323
|
+
{ timeout: 3e4 }
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Ask the server to materialize a per-trace DB branch lease from a
|
|
328
|
+
* captured `dbSnapshotRef`. Blocking — the resolver creates a Neon
|
|
329
|
+
* snapshot + preview branch and polls operations to readiness, which
|
|
330
|
+
* can take seconds.
|
|
331
|
+
*/
|
|
332
|
+
async resolveDbBranchLease(testRunId, traceId, dbSnapshotRef) {
|
|
333
|
+
return this.request(
|
|
334
|
+
"/api/sdk/replay/resolveDbBranchLease",
|
|
335
|
+
{ testRunId, traceId, dbSnapshotRef },
|
|
336
|
+
{ timeout: 9e4 }
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
/** Release a previously-resolved DB branch by deleting its Neon branch. Idempotent server-side. */
|
|
340
|
+
async releaseDbBranchLease(neonBranchId) {
|
|
341
|
+
await this.request(
|
|
342
|
+
"/api/sdk/replay/releaseDbBranchLease",
|
|
343
|
+
{ neonBranchId },
|
|
344
|
+
{ timeout: 3e4 }
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
};
|
|
12
348
|
|
|
13
349
|
// src/claudeAgentSdk.ts
|
|
14
350
|
function nowIso() {
|
|
@@ -2162,9 +2498,18 @@ var Bitfab = class {
|
|
|
2162
2498
|
spanType: options.type ?? "custom"
|
|
2163
2499
|
};
|
|
2164
2500
|
const sendSpan = async (params) => {
|
|
2501
|
+
const replayCtx = getReplayContext();
|
|
2502
|
+
const persistenceCollector = isRootSpan ? replayCtx?.pendingPersistence : void 0;
|
|
2503
|
+
let resolvePersistence;
|
|
2504
|
+
if (persistenceCollector) {
|
|
2505
|
+
persistenceCollector.push(
|
|
2506
|
+
new Promise((resolve) => {
|
|
2507
|
+
resolvePersistence = resolve;
|
|
2508
|
+
})
|
|
2509
|
+
);
|
|
2510
|
+
}
|
|
2165
2511
|
try {
|
|
2166
2512
|
const endedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2167
|
-
const replayCtx = getReplayContext();
|
|
2168
2513
|
const spanPromise = self.sendWrapperSpan({
|
|
2169
2514
|
...baseSpanParams,
|
|
2170
2515
|
...params,
|
|
@@ -2179,13 +2524,17 @@ var Bitfab = class {
|
|
|
2179
2524
|
if (isRootSpan) {
|
|
2180
2525
|
const pending = pendingSpanPromises.get(traceId) ?? [];
|
|
2181
2526
|
pending.push(spanPromise);
|
|
2182
|
-
|
|
2183
|
-
Promise.allSettled(pending)
|
|
2184
|
-
|
|
2185
|
-
|
|
2527
|
+
if (persistenceCollector) {
|
|
2528
|
+
await Promise.allSettled(pending);
|
|
2529
|
+
} else {
|
|
2530
|
+
await Promise.race([
|
|
2531
|
+
Promise.allSettled(pending),
|
|
2532
|
+
new Promise((resolve) => setTimeout(resolve, 5e3))
|
|
2533
|
+
]);
|
|
2534
|
+
}
|
|
2186
2535
|
pendingSpanPromises.delete(traceId);
|
|
2187
2536
|
const traceState = activeTraceStates.get(traceId);
|
|
2188
|
-
self.sendTraceCompletion({
|
|
2537
|
+
const completionPromise = self.sendTraceCompletion({
|
|
2189
2538
|
traceFunctionKey,
|
|
2190
2539
|
traceId,
|
|
2191
2540
|
startedAt: traceState?.startedAt ?? startedAt,
|
|
@@ -2198,6 +2547,9 @@ var Bitfab = class {
|
|
|
2198
2547
|
dbSnapshotRef: traceState?.dbSnapshotRef
|
|
2199
2548
|
});
|
|
2200
2549
|
activeTraceStates.delete(traceId);
|
|
2550
|
+
if (persistenceCollector) {
|
|
2551
|
+
await completionPromise;
|
|
2552
|
+
}
|
|
2201
2553
|
} else {
|
|
2202
2554
|
const pending = pendingSpanPromises.get(traceId);
|
|
2203
2555
|
if (pending) {
|
|
@@ -2207,6 +2559,8 @@ var Bitfab = class {
|
|
|
2207
2559
|
}
|
|
2208
2560
|
}
|
|
2209
2561
|
} catch {
|
|
2562
|
+
} finally {
|
|
2563
|
+
resolvePersistence?.();
|
|
2210
2564
|
}
|
|
2211
2565
|
};
|
|
2212
2566
|
const replayCtxForMock = getReplayContext();
|
|
@@ -2359,7 +2713,7 @@ var Bitfab = class {
|
|
|
2359
2713
|
if (params.dbSnapshotRef) {
|
|
2360
2714
|
rawTrace.db_snapshot_ref = params.dbSnapshotRef;
|
|
2361
2715
|
}
|
|
2362
|
-
this.httpClient.sendExternalTrace({
|
|
2716
|
+
return this.httpClient.sendExternalTrace({
|
|
2363
2717
|
type: "sdk-function",
|
|
2364
2718
|
source: "typescript-sdk-function",
|
|
2365
2719
|
traceFunctionKey: params.traceFunctionKey,
|
|
@@ -2439,7 +2793,7 @@ var Bitfab = class {
|
|
|
2439
2793
|
* @returns ReplayResult with items, testRunId, and testRunUrl
|
|
2440
2794
|
*/
|
|
2441
2795
|
async replay(traceFunctionKey, fn, options) {
|
|
2442
|
-
const { replay: doReplay } = await import("./replay-
|
|
2796
|
+
const { replay: doReplay } = await import("./replay-WIBKB3BK.js");
|
|
2443
2797
|
return doReplay(
|
|
2444
2798
|
this.httpClient,
|
|
2445
2799
|
this.serviceUrl,
|
|
@@ -2505,6 +2859,9 @@ var BitfabFunction = class {
|
|
|
2505
2859
|
};
|
|
2506
2860
|
|
|
2507
2861
|
export {
|
|
2862
|
+
__version__,
|
|
2863
|
+
DEFAULT_SERVICE_URL,
|
|
2864
|
+
flushTraces,
|
|
2508
2865
|
BitfabClaudeAgentHandler,
|
|
2509
2866
|
SUPPORTED_PROVIDERS,
|
|
2510
2867
|
BitfabLangGraphCallbackHandler,
|
|
@@ -2515,4 +2872,4 @@ export {
|
|
|
2515
2872
|
Bitfab,
|
|
2516
2873
|
BitfabFunction
|
|
2517
2874
|
};
|
|
2518
|
-
//# sourceMappingURL=chunk-
|
|
2875
|
+
//# sourceMappingURL=chunk-53G5GR7B.js.map
|