content-moderation-sdk 0.0.1 → 0.1.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.
Files changed (54) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +275 -0
  3. package/content-moderation-sdk.jpg +0 -0
  4. package/dist/azure.d.ts +38 -0
  5. package/dist/azure.d.ts.map +1 -0
  6. package/dist/azure.js +114 -0
  7. package/dist/azure.js.map +1 -0
  8. package/dist/core.d.ts +3 -0
  9. package/dist/core.d.ts.map +1 -0
  10. package/dist/core.js +313 -0
  11. package/dist/core.js.map +1 -0
  12. package/dist/errors.d.ts +41 -0
  13. package/dist/errors.d.ts.map +1 -0
  14. package/dist/errors.js +77 -0
  15. package/dist/errors.js.map +1 -0
  16. package/dist/http.d.ts +9 -0
  17. package/dist/http.d.ts.map +1 -0
  18. package/dist/http.js +87 -0
  19. package/dist/http.js.map +1 -0
  20. package/dist/index.d.ts +4 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +3 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/mistral.d.ts +23 -0
  25. package/dist/mistral.d.ts.map +1 -0
  26. package/dist/mistral.js +81 -0
  27. package/dist/mistral.js.map +1 -0
  28. package/dist/openai.d.ts +28 -0
  29. package/dist/openai.d.ts.map +1 -0
  30. package/dist/openai.js +105 -0
  31. package/dist/openai.js.map +1 -0
  32. package/dist/testing.d.ts +18 -0
  33. package/dist/testing.d.ts.map +1 -0
  34. package/dist/testing.js +44 -0
  35. package/dist/testing.js.map +1 -0
  36. package/dist/types.d.ts +164 -0
  37. package/dist/types.d.ts.map +1 -0
  38. package/dist/types.js +2 -0
  39. package/dist/types.js.map +1 -0
  40. package/dist/utils.d.ts +26 -0
  41. package/dist/utils.d.ts.map +1 -0
  42. package/dist/utils.js +229 -0
  43. package/dist/utils.js.map +1 -0
  44. package/package.json +76 -1
  45. package/src/azure.ts +191 -0
  46. package/src/core.ts +440 -0
  47. package/src/errors.ts +109 -0
  48. package/src/http.ts +94 -0
  49. package/src/index.ts +43 -0
  50. package/src/mistral.ts +124 -0
  51. package/src/openai.ts +162 -0
  52. package/src/testing.ts +85 -0
  53. package/src/types.ts +241 -0
  54. package/src/utils.ts +281 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 sophisticatedalterego
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,275 @@
1
+ <p align="center">
2
+ <img alt="Content Moderation SDK — Moderate text, images, and conversations without provider lock-in" src="./content-moderation-sdk.jpg" width="820" />
3
+ </p>
4
+
5
+ One TypeScript SDK for moderating text, images, and conversations without coupling application code to one provider.
6
+
7
+ - Swappable OpenAI, Azure AI Content Safety, and Mistral adapters
8
+ - Provider-native category names, decisions, scores, severities, and raw responses
9
+ - Fail-fast capability validation across the complete fallback route
10
+ - Retries inside one adapter and fallback across adapters
11
+ - Typed lifecycle hooks and test adapters
12
+ - No runtime dependencies, telemetry, persistence, or content logging
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ npm install content-moderation-sdk
18
+ ```
19
+
20
+ The SDK is server-side only and supports Node.js 20+ and Bun 1.1+. The package is ESM-only. Keep provider API keys out of browser code.
21
+
22
+ ## Quickstart
23
+
24
+ ```ts
25
+ import { createModerationClient } from "content-moderation-sdk";
26
+ import { openai } from "content-moderation-sdk/openai";
27
+
28
+ const moderation = createModerationClient({
29
+ adapters: [
30
+ openai({
31
+ apiKey: process.env.OPENAI_API_KEY!,
32
+ }),
33
+ ],
34
+ });
35
+
36
+ const result = await moderation.moderate({
37
+ type: "text",
38
+ text: "Content supplied by a user",
39
+ });
40
+
41
+ if (result.flagged) {
42
+ console.log(result.categories);
43
+ }
44
+ ```
45
+
46
+ ## Inputs
47
+
48
+ One `moderate()` call handles one unit: text, an image, or a text-only
49
+ conversation.
50
+
51
+ ### Text
52
+
53
+ ```ts
54
+ await moderation.moderate({
55
+ type: "text",
56
+ text: "A forum post",
57
+ });
58
+ ```
59
+
60
+ ### Images
61
+
62
+ Images can be a public HTTP(S) URL, base64, or bytes:
63
+
64
+ ```ts
65
+ await moderation.moderate({
66
+ type: "image",
67
+ source: {
68
+ type: "url",
69
+ url: "https://example.com/upload.png",
70
+ },
71
+ });
72
+
73
+ await moderation.moderate({
74
+ type: "image",
75
+ source: {
76
+ type: "bytes",
77
+ data: imageBytes,
78
+ mediaType: "image/png",
79
+ },
80
+ });
81
+ ```
82
+
83
+ OpenAI and Azure support images. Mistral does not, so a fallback route containing
84
+ Mistral is invalid for image input and fails before any provider is called.
85
+
86
+ ### Conversations
87
+
88
+ ```ts
89
+ await moderation.moderate({
90
+ type: "conversation",
91
+ messages: [
92
+ { role: "system", content: "You are a support assistant." },
93
+ { role: "user", content: "The user's prompt" },
94
+ { role: "assistant", content: "The assistant's response" },
95
+ ],
96
+ });
97
+ ```
98
+
99
+ Mistral receives structured conversations natively. OpenAI and Azure receive a
100
+ deterministic JSON serialization of the messages as text. Results expose
101
+ `mode: "native" | "flattened"` so this transformation is never hidden.
102
+
103
+ ## Adapters
104
+
105
+ | Adapter | Text | Image | Conversation |
106
+ | ----------------------- | ------ | ------------------------------- | ------------ |
107
+ | OpenAI | Native | Native with `omni-moderation-*` | Flattened |
108
+ | Azure AI Content Safety | Native | Native | Flattened |
109
+ | Mistral | Native | Unsupported | Native |
110
+
111
+ ```ts
112
+ import { azure } from "content-moderation-sdk/azure";
113
+ import { mistral } from "content-moderation-sdk/mistral";
114
+
115
+ const moderation = createModerationClient({
116
+ adapters: [
117
+ azure({
118
+ endpoint: process.env.AZURE_CONTENT_SAFETY_ENDPOINT!,
119
+ apiKey: process.env.AZURE_CONTENT_SAFETY_KEY!,
120
+ threshold: 4,
121
+ }),
122
+ mistral({
123
+ apiKey: process.env.MISTRAL_API_KEY!,
124
+ }),
125
+ ],
126
+ });
127
+ ```
128
+
129
+ Azure uses four severity levels and flags a category at severity 4 or above by
130
+ default. Configure `threshold: 2 | 4 | 6` for a different policy. OpenAI uses
131
+ its top-level provider decision; Mistral is flagged when any native category is
132
+ flagged.
133
+
134
+ ## Results
135
+
136
+ ```ts
137
+ type ModerationResult = {
138
+ adapter: string;
139
+ flagged: boolean;
140
+ inputType: "text" | "image" | "conversation";
141
+ mode: "native" | "flattened";
142
+ categories: Record<
143
+ string,
144
+ {
145
+ flagged: boolean | null;
146
+ score?: number;
147
+ severity?: { value: number; max: number };
148
+ inputTypes?: ("text" | "image")[];
149
+ }
150
+ >;
151
+ id?: string;
152
+ model?: string;
153
+ raw?: unknown;
154
+ };
155
+ ```
156
+
157
+ Category keys and numeric values remain provider-native. A probability-like
158
+ score from one provider is not comparable to an Azure severity or another
159
+ provider's score. Use `raw` when provider-specific response fields matter.
160
+
161
+ ## Validation, retries, and fallback
162
+
163
+ `validate()` runs common, capability, and adapter-specific checks for every
164
+ candidate route without sending content:
165
+
166
+ ```ts
167
+ await moderation.validate(input, {
168
+ adapter: "openai",
169
+ fallback: { adapters: ["azure"] },
170
+ });
171
+ ```
172
+
173
+ Retries stay on the current adapter. Fallback begins after that adapter reaches
174
+ a terminal error:
175
+
176
+ ```ts
177
+ const moderation = createModerationClient({
178
+ adapters: [primary, backup],
179
+ retry: {
180
+ maxAttempts: 3,
181
+ },
182
+ fallback: {
183
+ adapters: ["backup"],
184
+ shouldFallback(error) {
185
+ return error.status !== 401;
186
+ },
187
+ },
188
+ });
189
+ ```
190
+
191
+ The default is one attempt and no fallback. Provider calls can still be billed
192
+ when a response is lost, so use `shouldFallback` when duplicate cost matters.
193
+ An `AbortSignal` stops the active request, retry backoff, and later fallbacks.
194
+
195
+ ## Errors
196
+
197
+ All SDK errors extend `ModerationSdkError` and expose `code`, `retryable`, and,
198
+ when available, `adapter`, `status`, and `details`. They serialize to actionable
199
+ JSON, including the error message, while omitting stack traces and causes:
200
+
201
+ ```ts
202
+ import { ModerationSdkError } from "content-moderation-sdk";
203
+
204
+ try {
205
+ return Response.json(await moderation.moderate(input));
206
+ } catch (error) {
207
+ if (error instanceof ModerationSdkError) {
208
+ return Response.json(error, {
209
+ status: error.code === "validation_error" ? 400 : (error.status ?? 500),
210
+ });
211
+ }
212
+ throw error;
213
+ }
214
+ ```
215
+
216
+ ## Batches
217
+
218
+ `moderateMany()` runs sequentially and returns one ordered settled result per
219
+ item:
220
+
221
+ ```ts
222
+ const results = await moderation.moderateMany([
223
+ { input: { type: "text", text: "First" } },
224
+ { input: { type: "text", text: "Second" } },
225
+ ]);
226
+ ```
227
+
228
+ ## Custom adapters
229
+
230
+ Adapters are plain objects with declared capabilities:
231
+
232
+ ```ts
233
+ import type { ModerationAdapter } from "content-moderation-sdk";
234
+
235
+ const custom: ModerationAdapter<"custom"> = {
236
+ name: "custom",
237
+ capabilities: {
238
+ text: true,
239
+ image: false,
240
+ conversation: "flattened",
241
+ },
242
+ async moderate(input, context) {
243
+ // Forward context.signal to network work.
244
+ return {
245
+ adapter: "custom",
246
+ flagged: false,
247
+ categories: {},
248
+ };
249
+ },
250
+ };
251
+ ```
252
+
253
+ `validate`, when implemented, must be deterministic and perform no network
254
+ work. The client calls it for every candidate before the first moderation
255
+ request.
256
+
257
+ ## Testing
258
+
259
+ ```ts
260
+ import { memoryAdapter } from "content-moderation-sdk/testing";
261
+
262
+ const memory = memoryAdapter();
263
+ const moderation = createModerationClient({ adapters: [memory] });
264
+
265
+ await moderation.moderate({ type: "text", text: "test input" });
266
+ expect(memory.raw?.requests).toHaveLength(1);
267
+ ```
268
+
269
+ `memoryAdapter` stores inputs intentionally for assertions. Production
270
+ adapters do not store input. `failingAdapter` is also available for retry and
271
+ fallback tests.
272
+
273
+ ## License
274
+
275
+ MIT
Binary file
@@ -0,0 +1,38 @@
1
+ import type { ModerationAdapter } from "./types.js";
2
+ export type AzureModerationCategory = "Hate" | "SelfHarm" | "Sexual" | "Violence";
3
+ export type AzureSeverityThreshold = 2 | 4 | 6;
4
+ export type AzureCategoryAnalysis = {
5
+ category: AzureModerationCategory | (string & {});
6
+ severity: number;
7
+ };
8
+ export type AzureBlocklistMatch = {
9
+ blocklistName: string;
10
+ blocklistItemId: string;
11
+ blocklistItemText: string;
12
+ };
13
+ export type AzureTextModerationResponse = {
14
+ categoriesAnalysis: AzureCategoryAnalysis[];
15
+ blocklistsMatch?: AzureBlocklistMatch[];
16
+ };
17
+ export type AzureImageModerationResponse = {
18
+ categoriesAnalysis: AzureCategoryAnalysis[];
19
+ };
20
+ export type AzureModerationResponse = AzureTextModerationResponse | AzureImageModerationResponse;
21
+ export type AzureOptions = {
22
+ endpoint: string;
23
+ apiKey: string;
24
+ apiVersion?: string;
25
+ threshold?: AzureSeverityThreshold;
26
+ categories?: readonly AzureModerationCategory[];
27
+ blocklistNames?: readonly string[];
28
+ haltOnBlocklistHit?: boolean;
29
+ headers?: Readonly<Record<string, string>>;
30
+ fetch?: typeof fetch;
31
+ };
32
+ export type AzureAdapter = ModerationAdapter<"azure", {
33
+ endpoint: string;
34
+ apiVersion: string;
35
+ threshold: AzureSeverityThreshold;
36
+ }, AzureModerationResponse>;
37
+ export declare function azure(options: AzureOptions): AzureAdapter;
38
+ //# sourceMappingURL=azure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"azure.d.ts","sourceRoot":"","sources":["../src/azure.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,iBAAiB,EAIlB,MAAM,YAAY,CAAC;AAMpB,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAC;AAClF,MAAM,MAAM,sBAAsB,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAE/C,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,uBAAuB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IAClD,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,kBAAkB,EAAE,qBAAqB,EAAE,CAAC;IAC5C,eAAe,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,kBAAkB,EAAE,qBAAqB,EAAE,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,2BAA2B,GAAG,4BAA4B,CAAC;AAEjG,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,sBAAsB,CAAC;IACnC,UAAU,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAC;IAChD,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3C,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,iBAAiB,CAC1C,OAAO,EACP;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,sBAAsB,CAAA;CAAE,EAC3E,uBAAuB,CACxB,CAAC;AAEF,wBAAgB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,YAAY,CA6FzD"}
package/dist/azure.js ADDED
@@ -0,0 +1,114 @@
1
+ import { ModerationAdapterError, ModerationValidationError } from "./errors.js";
2
+ import { requestJson } from "./http.js";
3
+ import { imageSourceByteLength, imageSourceToBase64, normalizeHttpEndpoint } from "./utils.js";
4
+ const AZURE_MAX_TEXT_CODE_POINTS = 10_000;
5
+ const AZURE_MAX_IMAGE_BYTES = 4 * 1024 * 1024;
6
+ export function azure(options) {
7
+ const endpoint = normalizeHttpEndpoint(options.endpoint, "Azure endpoint");
8
+ if (typeof options.apiKey !== "string" || options.apiKey.trim().length === 0) {
9
+ throw new ModerationValidationError("Azure apiKey is required.");
10
+ }
11
+ const apiVersion = options.apiVersion ?? "2024-09-01";
12
+ const threshold = options.threshold ?? 4;
13
+ if (typeof apiVersion !== "string" || apiVersion.trim().length === 0) {
14
+ throw new ModerationValidationError("Azure apiVersion must be a non-empty string.");
15
+ }
16
+ if (threshold !== 2 && threshold !== 4 && threshold !== 6) {
17
+ throw new ModerationValidationError("Azure threshold must be 2, 4, or 6.");
18
+ }
19
+ const fetcher = options.fetch ?? fetch;
20
+ return {
21
+ name: "azure",
22
+ capabilities: {
23
+ text: true,
24
+ image: true,
25
+ conversation: "flattened",
26
+ },
27
+ raw: { endpoint, apiVersion, threshold },
28
+ validate(input) {
29
+ if (input.type === "text" && [...input.text].length > AZURE_MAX_TEXT_CODE_POINTS) {
30
+ throw new ModerationValidationError(`Azure text input cannot exceed ${AZURE_MAX_TEXT_CODE_POINTS} Unicode code points.`, { adapter: "azure", limit: AZURE_MAX_TEXT_CODE_POINTS });
31
+ }
32
+ if (input.type === "image") {
33
+ const bytes = imageSourceByteLength(input.source);
34
+ if (bytes !== undefined && bytes > AZURE_MAX_IMAGE_BYTES) {
35
+ throw new ModerationValidationError("Azure image input cannot exceed 4 MB.", {
36
+ adapter: "azure",
37
+ limit: AZURE_MAX_IMAGE_BYTES,
38
+ actual: bytes,
39
+ });
40
+ }
41
+ }
42
+ },
43
+ async moderate(input, context) {
44
+ if (input.type === "conversation") {
45
+ throw new ModerationValidationError("Azure receives conversations through the client's flattened text path.");
46
+ }
47
+ const isText = input.type === "text";
48
+ const body = await requestJson({
49
+ adapter: "azure",
50
+ provider: "Azure AI Content Safety",
51
+ fetcher,
52
+ url: `${endpoint}/contentsafety/${isText ? "text" : "image"}:analyze?api-version=${encodeURIComponent(apiVersion)}`,
53
+ init: {
54
+ method: "POST",
55
+ signal: context.signal,
56
+ headers: {
57
+ "Ocp-Apim-Subscription-Key": options.apiKey,
58
+ "Content-Type": "application/json",
59
+ ...options.headers,
60
+ },
61
+ body: JSON.stringify(isText ? textPayload(input, options) : await imagePayload(input, options)),
62
+ },
63
+ });
64
+ if (!Array.isArray(body.categoriesAnalysis)) {
65
+ throw new ModerationAdapterError("Azure returned an invalid moderation response.", {
66
+ adapter: "azure",
67
+ code: "invalid_response",
68
+ details: body,
69
+ });
70
+ }
71
+ const categories = toCategoryAssessments(body.categoriesAnalysis, threshold);
72
+ const blocklistsMatch = "blocklistsMatch" in body && Array.isArray(body.blocklistsMatch)
73
+ ? body.blocklistsMatch
74
+ : [];
75
+ return {
76
+ adapter: "azure",
77
+ flagged: blocklistsMatch.length > 0 ||
78
+ Object.values(categories).some((category) => category.flagged === true),
79
+ categories,
80
+ raw: body,
81
+ };
82
+ },
83
+ };
84
+ }
85
+ function textPayload(input, options) {
86
+ return {
87
+ text: input.text,
88
+ outputType: "FourSeverityLevels",
89
+ ...(options.categories ? { categories: options.categories } : {}),
90
+ ...(options.blocklistNames ? { blocklistNames: options.blocklistNames } : {}),
91
+ ...(options.haltOnBlocklistHit !== undefined
92
+ ? { haltOnBlocklistHit: options.haltOnBlocklistHit }
93
+ : {}),
94
+ };
95
+ }
96
+ async function imagePayload(input, options) {
97
+ return {
98
+ image: input.source.type === "url"
99
+ ? { blobUrl: input.source.url }
100
+ : { content: await imageSourceToBase64(input.source) },
101
+ outputType: "FourSeverityLevels",
102
+ ...(options.categories ? { categories: options.categories } : {}),
103
+ };
104
+ }
105
+ function toCategoryAssessments(analyses, threshold) {
106
+ return Object.fromEntries(analyses.map(({ category, severity }) => [
107
+ category,
108
+ {
109
+ flagged: severity >= threshold,
110
+ severity: { value: severity, max: 6 },
111
+ },
112
+ ]));
113
+ }
114
+ //# sourceMappingURL=azure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"azure.js","sourceRoot":"","sources":["../src/azure.ts"],"names":[],"mappings":"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"}
package/dist/core.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { ModerationAdapter, ModerationClient, ModerationClientOptions } from "./types.js";
2
+ export declare function createModerationClient<const TAdapters extends readonly ModerationAdapter[]>(options: ModerationClientOptions<TAdapters>): ModerationClient<TAdapters>;
3
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAEV,iBAAiB,EAEjB,gBAAgB,EAChB,uBAAuB,EAYxB,MAAM,YAAY,CAAC;AA6BpB,wBAAgB,sBAAsB,CAAC,KAAK,CAAC,SAAS,SAAS,SAAS,iBAAiB,EAAE,EACzF,OAAO,EAAE,uBAAuB,CAAC,SAAS,CAAC,GAC1C,gBAAgB,CAAC,SAAS,CAAC,CA0J7B"}