@tuteliq/mcp 3.2.4 → 3.2.6

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/server.js CHANGED
@@ -34,7 +34,7 @@ app.post('/messages', (req, res) => {
34
34
  });
35
35
  });
36
36
  app.get('/health', (_req, res) => {
37
- res.json({ status: 'ok', version: '3.2.0' });
37
+ res.json({ status: 'ok', version: '3.2.5' });
38
38
  });
39
39
  const server = app.listen(port, () => {
40
40
  console.error(`Tuteliq MCP server running on http://localhost:${port}`);
package/dist/src/index.js CHANGED
@@ -16,7 +16,7 @@ export function createServer(apiKey) {
16
16
  const client = new Tuteliq(key);
17
17
  const server = new McpServer({
18
18
  name: 'tuteliq-mcp',
19
- version: '3.2.0',
19
+ version: '3.2.5',
20
20
  });
21
21
  // Register all tool groups
22
22
  registerDetectionTools(server, client);
@@ -1 +1 @@
1
- {"version":3,"file":"analysis.d.ts","sourceRoot":"","sources":["../../../src/tools/analysis.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,cAAc,CAAC;AAkB1D,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CA0M9E"}
1
+ {"version":3,"file":"analysis.d.ts","sourceRoot":"","sources":["../../../src/tools/analysis.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,cAAc,CAAC;AAkC1D,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAkO9E"}
@@ -13,6 +13,21 @@ const MULTI_WIDGET_URI = 'ui://tuteliq/multi-result.html';
13
13
  function loadWidget(name) {
14
14
  return readFileSync(resolve(__dirname, '../../../dist-ui', name), 'utf-8');
15
15
  }
16
+ function handleTierError(err, toolName, featureLabel) {
17
+ if (err?.status === 403 || err?.response?.status === 403) {
18
+ const upsellResult = {
19
+ error: 'tier_restricted',
20
+ tier_restricted: true,
21
+ upgrade: true,
22
+ message: `Your current plan does not include ${featureLabel.toLowerCase()}. Upgrade your plan or purchase additional credits to unlock this feature.`,
23
+ };
24
+ return {
25
+ structuredContent: { toolName, result: upsellResult, branding: { appName: 'Tuteliq' } },
26
+ content: [{ type: 'text', text: `\u26A0\uFE0F ${upsellResult.message}\n\nUpgrade at: https://tuteliq.ai/dashboard` }],
27
+ };
28
+ }
29
+ return null;
30
+ }
16
31
  export function registerAnalysisTools(server, client) {
17
32
  const resources = [
18
33
  { uri: EMOTIONS_WIDGET_URI, file: 'emotions-result.html' },
@@ -44,13 +59,14 @@ export function registerAnalysisTools(server, client) {
44
59
  'openai/toolInvocation/invoked': 'Emotion analysis complete.',
45
60
  },
46
61
  }, async ({ content }) => {
47
- const result = await client.analyzeEmotions({ content });
48
- const emoji = trendEmoji[result.trend] || '\u27A1\uFE0F';
49
- const emotionScoresList = Object.entries(result.emotion_scores)
50
- .sort((a, b) => b[1] - a[1])
51
- .map(([emotion, score]) => `- ${emotion}: ${(score * 100).toFixed(0)}%`)
52
- .join('\n');
53
- const text = `## Emotion Analysis
62
+ try {
63
+ const result = await client.analyzeEmotions({ content });
64
+ const emoji = trendEmoji[result.trend] || '\u27A1\uFE0F';
65
+ const emotionScoresList = Object.entries(result.emotion_scores)
66
+ .sort((a, b) => b[1] - a[1])
67
+ .map(([emotion, score]) => `- ${emotion}: ${(score * 100).toFixed(0)}%`)
68
+ .join('\n');
69
+ const text = `## Emotion Analysis
54
70
 
55
71
  **Dominant Emotions:** ${result.dominant_emotions.join(', ')}
56
72
  **Trend:** ${emoji} ${result.trend.charAt(0).toUpperCase() + result.trend.slice(1)}
@@ -63,10 +79,17 @@ ${result.summary}
63
79
 
64
80
  ### Recommended Follow-up
65
81
  ${result.recommended_followup}`;
66
- return {
67
- structuredContent: { toolName: 'analyze_emotions', result, branding: { appName: 'Tuteliq' } },
68
- content: [{ type: 'text', text }],
69
- };
82
+ return {
83
+ structuredContent: { toolName: 'analyze_emotions', result, branding: { appName: 'Tuteliq' } },
84
+ content: [{ type: 'text', text }],
85
+ };
86
+ }
87
+ catch (err) {
88
+ const upsell = handleTierError(err, 'analyze_emotions', 'Emotion Analysis');
89
+ if (upsell)
90
+ return upsell;
91
+ throw err;
92
+ }
70
93
  });
71
94
  // ── get_action_plan ────────────────────────────────────────────────────────
72
95
  registerAppTool(server, 'get_action_plan', {
@@ -86,8 +109,9 @@ ${result.recommended_followup}`;
86
109
  'openai/toolInvocation/invoked': 'Action plan ready.',
87
110
  },
88
111
  }, async ({ situation, childAge, audience, severity }) => {
89
- const result = await client.getActionPlan({ situation, childAge, audience, severity });
90
- const text = `## Action Plan
112
+ try {
113
+ const result = await client.getActionPlan({ situation, childAge, audience, severity });
114
+ const text = `## Action Plan
91
115
 
92
116
  **Audience:** ${result.audience}
93
117
  **Tone:** ${result.tone}
@@ -95,10 +119,17 @@ ${result.reading_level ? `**Reading Level:** ${result.reading_level}` : ''}
95
119
 
96
120
  ### Steps
97
121
  ${result.steps.map((step, i) => `${i + 1}. ${step}`).join('\n')}`;
98
- return {
99
- structuredContent: { toolName: 'get_action_plan', result, branding: { appName: 'Tuteliq' } },
100
- content: [{ type: 'text', text }],
101
- };
122
+ return {
123
+ structuredContent: { toolName: 'get_action_plan', result, branding: { appName: 'Tuteliq' } },
124
+ content: [{ type: 'text', text }],
125
+ };
126
+ }
127
+ catch (err) {
128
+ const upsell = handleTierError(err, 'get_action_plan', 'Action Plan');
129
+ if (upsell)
130
+ return upsell;
131
+ throw err;
132
+ }
102
133
  });
103
134
  // ── generate_report ────────────────────────────────────────────────────────
104
135
  registerAppTool(server, 'generate_report', {
@@ -120,13 +151,14 @@ ${result.steps.map((step, i) => `${i + 1}. ${step}`).join('\n')}`;
120
151
  'openai/toolInvocation/invoked': 'Incident report ready.',
121
152
  },
122
153
  }, async ({ messages, childAge, incidentType }) => {
123
- const result = await client.generateReport({
124
- messages,
125
- childAge,
126
- incident: incidentType ? { type: incidentType } : undefined,
127
- });
128
- const emoji = riskEmoji[result.risk_level] || '\u26AA';
129
- const text = `## \u{1F4CB} Incident Report
154
+ try {
155
+ const result = await client.generateReport({
156
+ messages,
157
+ childAge,
158
+ incident: incidentType ? { type: incidentType } : undefined,
159
+ });
160
+ const emoji = riskEmoji[result.risk_level] || '\u26AA';
161
+ const text = `## \u{1F4CB} Incident Report
130
162
 
131
163
  **Risk Level:** ${emoji} ${result.risk_level.charAt(0).toUpperCase() + result.risk_level.slice(1)}
132
164
 
@@ -138,10 +170,17 @@ ${result.categories.map(c => `- ${c}`).join('\n')}
138
170
 
139
171
  ### Recommended Next Steps
140
172
  ${result.recommended_next_steps.map((step, i) => `${i + 1}. ${step}`).join('\n')}`;
141
- return {
142
- structuredContent: { toolName: 'generate_report', result, branding: { appName: 'Tuteliq' } },
143
- content: [{ type: 'text', text }],
144
- };
173
+ return {
174
+ structuredContent: { toolName: 'generate_report', result, branding: { appName: 'Tuteliq' } },
175
+ content: [{ type: 'text', text }],
176
+ };
177
+ }
178
+ catch (err) {
179
+ const upsell = handleTierError(err, 'generate_report', 'Report Generation');
180
+ if (upsell)
181
+ return upsell;
182
+ throw err;
183
+ }
145
184
  });
146
185
  // ── analyse_multi ──────────────────────────────────────────────────────────
147
186
  registerAppTool(server, 'analyse_multi', {
@@ -163,17 +202,25 @@ ${result.recommended_next_steps.map((step, i) => `${i + 1}. ${step}`).join('\n')
163
202
  'openai/toolInvocation/invoked': 'Multi-endpoint analysis complete.',
164
203
  },
165
204
  }, async ({ content, endpoints, context, include_evidence, external_id, customer_id }) => {
166
- const result = await client.analyseMulti({
167
- content,
168
- detections: endpoints,
169
- context: context,
170
- includeEvidence: include_evidence,
171
- external_id,
172
- customer_id,
173
- });
174
- return {
175
- structuredContent: { toolName: 'analyse_multi', result, branding: { appName: 'Tuteliq' } },
176
- content: [{ type: 'text', text: formatMultiResult(result) }],
177
- };
205
+ try {
206
+ const result = await client.analyseMulti({
207
+ content,
208
+ detections: endpoints,
209
+ context: context,
210
+ includeEvidence: include_evidence,
211
+ external_id,
212
+ customer_id,
213
+ });
214
+ return {
215
+ structuredContent: { toolName: 'analyse_multi', result, branding: { appName: 'Tuteliq' } },
216
+ content: [{ type: 'text', text: formatMultiResult(result) }],
217
+ };
218
+ }
219
+ catch (err) {
220
+ const upsell = handleTierError(err, 'analyse_multi', 'Multi-Endpoint Analysis');
221
+ if (upsell)
222
+ return upsell;
223
+ throw err;
224
+ }
178
225
  });
179
226
  }
@@ -1 +1 @@
1
- {"version":3,"file":"detection.d.ts","sourceRoot":"","sources":["../../../src/tools/detection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AA6B5C,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAuL/E"}
1
+ {"version":3,"file":"detection.d.ts","sourceRoot":"","sources":["../../../src/tools/detection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AA6C5C,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CA+M/E"}
@@ -10,6 +10,21 @@ const DETECTION_WIDGET_URI = 'ui://tuteliq/detection-result.html';
10
10
  function loadWidget(name) {
11
11
  return readFileSync(resolve(__dirname, '../../../dist-ui', name), 'utf-8');
12
12
  }
13
+ function handleTierError(err, toolName, featureLabel) {
14
+ if (err?.status === 403 || err?.response?.status === 403) {
15
+ const upsellResult = {
16
+ error: 'tier_restricted',
17
+ tier_restricted: true,
18
+ upgrade: true,
19
+ message: `Your current plan does not include ${featureLabel.toLowerCase()}. Upgrade your plan or purchase additional credits to unlock this feature.`,
20
+ };
21
+ return {
22
+ structuredContent: { toolName, result: upsellResult, branding: { appName: 'Tuteliq' } },
23
+ content: [{ type: 'text', text: `\u26A0\uFE0F ${upsellResult.message}\n\nUpgrade at: https://tuteliq.ai/dashboard` }],
24
+ };
25
+ }
26
+ return null;
27
+ }
13
28
  const contextSchema = z.object({
14
29
  language: z.string().optional(),
15
30
  ageGroup: z.string().optional(),
@@ -42,12 +57,13 @@ export function registerDetectionTools(server, client) {
42
57
  },
43
58
  _meta: uiMeta('Shows bullying detection results with risk indicators', 'Analyzing content for bullying...', 'Bullying analysis complete.'),
44
59
  }, async ({ content, context }) => {
45
- const result = await client.detectBullying({
46
- content,
47
- context: context,
48
- });
49
- const emoji = severityEmoji[result.severity] || '\u26AA';
50
- const text = `## ${result.is_bullying ? '\u26A0\uFE0F Bullying Detected' : '\u2705 No Bullying Detected'}
60
+ try {
61
+ const result = await client.detectBullying({
62
+ content,
63
+ context: context,
64
+ });
65
+ const emoji = severityEmoji[result.severity] || '\u26AA';
66
+ const text = `## ${result.is_bullying ? '\u26A0\uFE0F Bullying Detected' : '\u2705 No Bullying Detected'}
51
67
 
52
68
  **Severity:** ${emoji} ${result.severity.charAt(0).toUpperCase() + result.severity.slice(1)}
53
69
  **Confidence:** ${(result.confidence * 100).toFixed(0)}%
@@ -60,10 +76,17 @@ ${result.rationale}
60
76
 
61
77
  ### Recommended Action
62
78
  \`${result.recommended_action}\``;
63
- return {
64
- structuredContent: { toolName: 'detect_bullying', result, branding: { appName: 'Tuteliq' } },
65
- content: [{ type: 'text', text }],
66
- };
79
+ return {
80
+ structuredContent: { toolName: 'detect_bullying', result, branding: { appName: 'Tuteliq' } },
81
+ content: [{ type: 'text', text }],
82
+ };
83
+ }
84
+ catch (err) {
85
+ const upsell = handleTierError(err, 'detect_bullying', 'Bullying Detection');
86
+ if (upsell)
87
+ return upsell;
88
+ throw err;
89
+ }
67
90
  });
68
91
  // ── detect_grooming ────────────────────────────────────────────────────────
69
92
  registerAppTool(server, 'detect_grooming', {
@@ -79,12 +102,13 @@ ${result.rationale}
79
102
  },
80
103
  _meta: uiMeta('Shows grooming detection results with risk indicators', 'Analyzing conversation for grooming patterns...', 'Grooming analysis complete.'),
81
104
  }, async ({ messages, childAge }) => {
82
- const result = await client.detectGrooming({
83
- messages,
84
- childAge,
85
- });
86
- const emoji = riskEmoji[result.grooming_risk] || '\u26AA';
87
- const text = `## ${result.grooming_risk === 'none' ? '\u2705 No Grooming Detected' : '\u26A0\uFE0F Grooming Risk Detected'}
105
+ try {
106
+ const result = await client.detectGrooming({
107
+ messages,
108
+ childAge,
109
+ });
110
+ const emoji = riskEmoji[result.grooming_risk] || '\u26AA';
111
+ const text = `## ${result.grooming_risk === 'none' ? '\u2705 No Grooming Detected' : '\u26A0\uFE0F Grooming Risk Detected'}
88
112
 
89
113
  **Risk Level:** ${emoji} ${result.grooming_risk.charAt(0).toUpperCase() + result.grooming_risk.slice(1)}
90
114
  **Confidence:** ${(result.confidence * 100).toFixed(0)}%
@@ -97,10 +121,17 @@ ${result.rationale}
97
121
 
98
122
  ### Recommended Action
99
123
  \`${result.recommended_action}\``;
100
- return {
101
- structuredContent: { toolName: 'detect_grooming', result, branding: { appName: 'Tuteliq' } },
102
- content: [{ type: 'text', text }],
103
- };
124
+ return {
125
+ structuredContent: { toolName: 'detect_grooming', result, branding: { appName: 'Tuteliq' } },
126
+ content: [{ type: 'text', text }],
127
+ };
128
+ }
129
+ catch (err) {
130
+ const upsell = handleTierError(err, 'detect_grooming', 'Grooming Detection');
131
+ if (upsell)
132
+ return upsell;
133
+ throw err;
134
+ }
104
135
  });
105
136
  // ── detect_unsafe ──────────────────────────────────────────────────────────
106
137
  registerAppTool(server, 'detect_unsafe', {
@@ -113,12 +144,13 @@ ${result.rationale}
113
144
  },
114
145
  _meta: uiMeta('Shows unsafe content detection results', 'Analyzing content for safety concerns...', 'Safety analysis complete.'),
115
146
  }, async ({ content, context }) => {
116
- const result = await client.detectUnsafe({
117
- content,
118
- context: context,
119
- });
120
- const emoji = severityEmoji[result.severity] || '\u26AA';
121
- const text = `## ${result.unsafe ? '\u26A0\uFE0F Unsafe Content Detected' : '\u2705 Content is Safe'}
147
+ try {
148
+ const result = await client.detectUnsafe({
149
+ content,
150
+ context: context,
151
+ });
152
+ const emoji = severityEmoji[result.severity] || '\u26AA';
153
+ const text = `## ${result.unsafe ? '\u26A0\uFE0F Unsafe Content Detected' : '\u2705 Content is Safe'}
122
154
 
123
155
  **Severity:** ${emoji} ${result.severity.charAt(0).toUpperCase() + result.severity.slice(1)}
124
156
  **Confidence:** ${(result.confidence * 100).toFixed(0)}%
@@ -131,10 +163,17 @@ ${result.rationale}
131
163
 
132
164
  ### Recommended Action
133
165
  \`${result.recommended_action}\``;
134
- return {
135
- structuredContent: { toolName: 'detect_unsafe', result, branding: { appName: 'Tuteliq' } },
136
- content: [{ type: 'text', text }],
137
- };
166
+ return {
167
+ structuredContent: { toolName: 'detect_unsafe', result, branding: { appName: 'Tuteliq' } },
168
+ content: [{ type: 'text', text }],
169
+ };
170
+ }
171
+ catch (err) {
172
+ const upsell = handleTierError(err, 'detect_unsafe', 'Unsafe Content Detection');
173
+ if (upsell)
174
+ return upsell;
175
+ throw err;
176
+ }
138
177
  });
139
178
  // ── analyze (quick combined) ───────────────────────────────────────────────
140
179
  registerAppTool(server, 'analyze', {
@@ -147,9 +186,10 @@ ${result.rationale}
147
186
  },
148
187
  _meta: uiMeta('Shows combined safety analysis results', 'Running safety analysis...', 'Safety analysis complete.'),
149
188
  }, async ({ content, include }) => {
150
- const result = await client.analyze({ content, include });
151
- const emoji = riskEmoji[result.risk_level] || '\u26AA';
152
- const text = `## Safety Analysis Results
189
+ try {
190
+ const result = await client.analyze({ content, include });
191
+ const emoji = riskEmoji[result.risk_level] || '\u26AA';
192
+ const text = `## Safety Analysis Results
153
193
 
154
194
  **Overall Risk:** ${emoji} ${result.risk_level.charAt(0).toUpperCase() + result.risk_level.slice(1)}
155
195
  **Risk Score:** ${(result.risk_score * 100).toFixed(0)}%
@@ -162,9 +202,16 @@ ${result.summary}
162
202
 
163
203
  ---
164
204
  ${result.bullying ? `\n**Bullying Check:** ${result.bullying.is_bullying ? '\u26A0\uFE0F Detected' : '\u2705 Clear'}\n` : ''}${result.unsafe ? `\n**Unsafe Content:** ${result.unsafe.unsafe ? '\u26A0\uFE0F Detected' : '\u2705 Clear'}\n` : ''}`;
165
- return {
166
- structuredContent: { toolName: 'analyze', result, branding: { appName: 'Tuteliq' } },
167
- content: [{ type: 'text', text }],
168
- };
205
+ return {
206
+ structuredContent: { toolName: 'analyze', result, branding: { appName: 'Tuteliq' } },
207
+ content: [{ type: 'text', text }],
208
+ };
209
+ }
210
+ catch (err) {
211
+ const upsell = handleTierError(err, 'analyze', 'Safety Analysis');
212
+ if (upsell)
213
+ return upsell;
214
+ throw err;
215
+ }
169
216
  });
170
217
  }
@@ -1 +1 @@
1
- {"version":3,"file":"fraud.d.ts","sourceRoot":"","sources":["../../../src/tools/fraud.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,cAAc,CAAC;AAyF1D,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAkC3E"}
1
+ {"version":3,"file":"fraud.d.ts","sourceRoot":"","sources":["../../../src/tools/fraud.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,cAAc,CAAC;AAyF1D,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAkD3E"}
@@ -89,18 +89,35 @@ export function registerFraudTools(server, client) {
89
89
  'openai/toolInvocation/invoked': tool.invoked,
90
90
  },
91
91
  }, async ({ content, context, include_evidence, external_id, customer_id }) => {
92
- const fn = client[tool.method].bind(client);
93
- const result = await fn({
94
- content,
95
- context: context,
96
- includeEvidence: include_evidence,
97
- external_id,
98
- customer_id,
99
- });
100
- return {
101
- structuredContent: { toolName: tool.name, result, branding: { appName: 'Tuteliq' } },
102
- content: [{ type: 'text', text: formatDetectionResult(result) }],
103
- };
92
+ try {
93
+ const fn = client[tool.method].bind(client);
94
+ const result = await fn({
95
+ content,
96
+ context: context,
97
+ includeEvidence: include_evidence,
98
+ external_id,
99
+ customer_id,
100
+ });
101
+ return {
102
+ structuredContent: { toolName: tool.name, result, branding: { appName: 'Tuteliq' } },
103
+ content: [{ type: 'text', text: formatDetectionResult(result) }],
104
+ };
105
+ }
106
+ catch (err) {
107
+ if (err?.status === 403 || err?.response?.status === 403) {
108
+ const upsellResult = {
109
+ error: 'tier_restricted',
110
+ tier_restricted: true,
111
+ upgrade: true,
112
+ message: `Your current plan does not include ${tool.title.toLowerCase()}. Upgrade your plan or purchase additional credits to unlock this feature.`,
113
+ };
114
+ return {
115
+ structuredContent: { toolName: tool.name, result: upsellResult, branding: { appName: 'Tuteliq' } },
116
+ content: [{ type: 'text', text: `⚠️ ${upsellResult.message}\n\nUpgrade at: https://tuteliq.ai/dashboard` }],
117
+ };
118
+ }
119
+ throw err;
120
+ }
104
121
  });
105
122
  }
106
123
  }
@@ -1 +1 @@
1
- {"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../../src/tools/media.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAmB5C,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CA+L3E"}
1
+ {"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../../src/tools/media.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAmC5C,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAiN3E"}