tool-schema 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/index.cjs ADDED
@@ -0,0 +1,596 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ lintToolSchema: () => lintToolSchema,
24
+ toTool: () => toTool,
25
+ toToolSchema: () => toToolSchema
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+
29
+ // src/util.ts
30
+ var Warnings = class {
31
+ list = [];
32
+ lossy = false;
33
+ add(path, code, message, lossy = true) {
34
+ this.list.push({ path, code, message });
35
+ if (lossy) this.lossy = true;
36
+ }
37
+ };
38
+ function isPlainObject(value) {
39
+ return typeof value === "object" && value !== null && !Array.isArray(value);
40
+ }
41
+ function clone(value) {
42
+ return structuredClone(value);
43
+ }
44
+ function typesOf(schema) {
45
+ if (typeof schema.type === "string") return [schema.type];
46
+ if (Array.isArray(schema.type)) return schema.type.filter((t) => typeof t === "string");
47
+ return [];
48
+ }
49
+ function isObjectSchema(schema) {
50
+ const types = typesOf(schema);
51
+ if (types.includes("object")) return true;
52
+ if (types.length > 0) return false;
53
+ return isPlainObject(schema.properties) || schema.additionalProperties !== void 0;
54
+ }
55
+ function makeNullable(schema) {
56
+ if (typeof schema.type === "string") {
57
+ if (schema.type === "null") return schema;
58
+ return { ...schema, type: [schema.type, "null"] };
59
+ }
60
+ if (Array.isArray(schema.type)) {
61
+ if (schema.type.includes("null")) return schema;
62
+ return { ...schema, type: [...schema.type, "null"] };
63
+ }
64
+ if (Array.isArray(schema.anyOf)) {
65
+ if (schema.anyOf.some((b) => typesOf(b).includes("null"))) return schema;
66
+ return { ...schema, anyOf: [...schema.anyOf, { type: "null" }] };
67
+ }
68
+ return { anyOf: [schema, { type: "null" }] };
69
+ }
70
+ function dereference(root, warnings) {
71
+ const defs = {
72
+ ...isPlainObject(root.definitions) ? root.definitions : {},
73
+ ...isPlainObject(root.$defs) ? root.$defs : {}
74
+ };
75
+ const resolve = (ref) => {
76
+ const m = /^#\/(?:\$defs|definitions)\/(.+)$/.exec(ref);
77
+ if (!m) return void 0;
78
+ const key = decodeURIComponent(m[1].replace(/~1/g, "/").replace(/~0/g, "~"));
79
+ return defs[key];
80
+ };
81
+ const walk = (node, path, seen) => {
82
+ if (!isPlainObject(node)) return node;
83
+ if (typeof node.$ref === "string") {
84
+ const ref = node.$ref;
85
+ const target = resolve(ref);
86
+ if (!target) return node;
87
+ if (seen.has(ref)) {
88
+ warnings.add(path, "recursive-ref", `Recursive $ref '${ref}' cannot be inlined; replaced with an open schema.`);
89
+ return {};
90
+ }
91
+ const { $ref: _drop, ...rest } = node;
92
+ void _drop;
93
+ warnings.add(path, "inlined-ref", `Inlined $ref '${ref}'.`, false);
94
+ const merged = { ...clone(target), ...rest };
95
+ return walk(merged, path, /* @__PURE__ */ new Set([...seen, ref]));
96
+ }
97
+ return mapChildren(node, path, (child, childPath) => walk(child, childPath, seen));
98
+ };
99
+ const out = walk(clone(root), "#", /* @__PURE__ */ new Set());
100
+ delete out.$defs;
101
+ delete out.definitions;
102
+ return out;
103
+ }
104
+ function mapChildren(node, path, fn) {
105
+ const out = { ...node };
106
+ if (isPlainObject(out.properties)) {
107
+ const props = {};
108
+ for (const [k, v] of Object.entries(out.properties)) {
109
+ props[k] = fn(v, `${path}/properties/${k}`);
110
+ }
111
+ out.properties = props;
112
+ }
113
+ if (Array.isArray(out.items)) {
114
+ out.items = out.items.map((it, i) => fn(it, `${path}/items/${i}`));
115
+ } else if (isPlainObject(out.items)) {
116
+ out.items = fn(out.items, `${path}/items`);
117
+ }
118
+ if (isPlainObject(out.additionalProperties)) {
119
+ out.additionalProperties = fn(out.additionalProperties, `${path}/additionalProperties`);
120
+ }
121
+ for (const key of ["anyOf", "oneOf", "allOf"]) {
122
+ const arr = out[key];
123
+ if (Array.isArray(arr)) {
124
+ out[key] = arr.map((b, i) => fn(b, `${path}/${key}/${i}`));
125
+ }
126
+ }
127
+ if (isPlainObject(out.not)) out.not = fn(out.not, `${path}/not`);
128
+ for (const key of ["if", "then", "else"]) {
129
+ if (isPlainObject(out[key])) out[key] = fn(out[key], `${path}/${key}`);
130
+ }
131
+ if (isPlainObject(out.patternProperties)) {
132
+ const pp = {};
133
+ for (const [k, v] of Object.entries(out.patternProperties)) {
134
+ pp[k] = fn(v, `${path}/patternProperties/${k}`);
135
+ }
136
+ out.patternProperties = pp;
137
+ }
138
+ for (const key of ["$defs", "definitions", "dependentSchemas"]) {
139
+ const map = out[key];
140
+ if (isPlainObject(map)) {
141
+ const next = {};
142
+ for (const [k, v] of Object.entries(map)) {
143
+ next[k] = fn(v, `${path}/${key}/${k}`);
144
+ }
145
+ out[key] = next;
146
+ }
147
+ }
148
+ return out;
149
+ }
150
+ function ensureObjectRoot(schema, warnings, target) {
151
+ if (isObjectSchema(schema)) {
152
+ if (typesOf(schema).length === 0) return { type: "object", ...schema };
153
+ return schema;
154
+ }
155
+ warnings.add(
156
+ "#",
157
+ "root-not-object",
158
+ `${target} requires the root schema to be an object; wrapped the schema under a 'value' property.`
159
+ );
160
+ return {
161
+ type: "object",
162
+ properties: { value: schema },
163
+ required: ["value"]
164
+ };
165
+ }
166
+
167
+ // src/targets/openai.ts
168
+ var FORMAT_WHITELIST = /* @__PURE__ */ new Set([
169
+ "date-time",
170
+ "time",
171
+ "date",
172
+ "duration",
173
+ "email",
174
+ "hostname",
175
+ "ipv4",
176
+ "ipv6",
177
+ "uuid"
178
+ ]);
179
+ var UNSUPPORTED = [
180
+ "not",
181
+ "if",
182
+ "then",
183
+ "else",
184
+ "dependentRequired",
185
+ "dependentSchemas",
186
+ "patternProperties",
187
+ "unevaluatedProperties"
188
+ ];
189
+ var MAX_PROPERTIES = 5e3;
190
+ var MAX_DEPTH = 10;
191
+ var MAX_ENUM_VALUES = 1e3;
192
+ function toOpenAI(input) {
193
+ const warnings = new Warnings();
194
+ const schema = ensureObjectRoot(clone(input), warnings, "OpenAI");
195
+ return { schema, warnings: warnings.list, lossy: warnings.lossy };
196
+ }
197
+ function toOpenAIStrict(input) {
198
+ const warnings = new Warnings();
199
+ const transform = (node, path) => {
200
+ if (!isPlainObject(node)) return node;
201
+ let s = { ...node };
202
+ if (Array.isArray(s.allOf)) {
203
+ s = mergeAllOf(s, path, warnings);
204
+ }
205
+ for (const kw of UNSUPPORTED) {
206
+ if (kw in s) {
207
+ delete s[kw];
208
+ warnings.add(path, "stripped-keyword", `'${kw}' is not supported in OpenAI strict mode; removed.`);
209
+ }
210
+ }
211
+ if (typeof s.format === "string" && !FORMAT_WHITELIST.has(s.format)) {
212
+ warnings.add(
213
+ `${path}/format`,
214
+ "unsupported-format",
215
+ `format '${s.format}' is not in OpenAI's whitelist; removed.`
216
+ );
217
+ delete s.format;
218
+ }
219
+ s = mapChildren(s, path, transform);
220
+ if (isObjectSchema(s) && isPlainObject(s.properties)) {
221
+ const props = s.properties;
222
+ const originalRequired = new Set(Array.isArray(s.required) ? s.required : []);
223
+ const nextProps = {};
224
+ for (const key of Object.keys(props)) {
225
+ let child = props[key];
226
+ if (!originalRequired.has(key)) {
227
+ child = makeNullable(child);
228
+ warnings.add(
229
+ `${path}/properties/${key}`,
230
+ "forced-required",
231
+ `Optional property '${key}' was made required and nullable for OpenAI strict mode.`
232
+ );
233
+ }
234
+ nextProps[key] = child;
235
+ }
236
+ s.properties = nextProps;
237
+ s.required = Object.keys(nextProps);
238
+ if (s.additionalProperties !== false) {
239
+ warnings.add(
240
+ path,
241
+ "forced-additional-properties",
242
+ "Set 'additionalProperties: false' as required by strict mode.",
243
+ false
244
+ );
245
+ }
246
+ s.additionalProperties = false;
247
+ } else if (isObjectSchema(s)) {
248
+ if (s.additionalProperties !== false) {
249
+ warnings.add(
250
+ path,
251
+ "forced-additional-properties",
252
+ "Set 'additionalProperties: false' on a property-less object.",
253
+ false
254
+ );
255
+ }
256
+ s.additionalProperties = false;
257
+ }
258
+ return s;
259
+ };
260
+ const schema = ensureObjectRoot(transform(clone(input), "#"), warnings, "OpenAI strict mode");
261
+ checkLimits(schema, warnings);
262
+ return { schema, warnings: warnings.list, lossy: warnings.lossy };
263
+ }
264
+ function mergeAllOf(node, path, warnings) {
265
+ const parts = node.allOf;
266
+ const { allOf: _drop, ...base } = node;
267
+ void _drop;
268
+ const merged = { ...base };
269
+ const props = isPlainObject(merged.properties) ? { ...merged.properties } : {};
270
+ const required = new Set(Array.isArray(merged.required) ? merged.required : []);
271
+ for (const part of parts) {
272
+ if (!isPlainObject(part)) continue;
273
+ if (isPlainObject(part.properties)) {
274
+ Object.assign(props, part.properties);
275
+ }
276
+ if (Array.isArray(part.required)) {
277
+ for (const r of part.required) required.add(r);
278
+ }
279
+ if (part.type && !merged.type) merged.type = part.type;
280
+ }
281
+ if (Object.keys(props).length > 0) merged.properties = props;
282
+ if (required.size > 0) merged.required = [...required];
283
+ if (!merged.type && (merged.properties || isObjectSchema(merged))) merged.type = "object";
284
+ warnings.add(path, "merged-allof", "Merged 'allOf' subschemas into the parent (unsupported in strict mode).");
285
+ return merged;
286
+ }
287
+ function checkLimits(schema, warnings) {
288
+ let propertyCount = 0;
289
+ let maxDepth = 0;
290
+ const visit = (node, depth) => {
291
+ if (!isPlainObject(node)) return;
292
+ maxDepth = Math.max(maxDepth, depth);
293
+ if (isPlainObject(node.properties)) {
294
+ const keys = Object.keys(node.properties);
295
+ propertyCount += keys.length;
296
+ }
297
+ if (Array.isArray(node.enum) && node.enum.length > MAX_ENUM_VALUES) {
298
+ warnings.add(
299
+ "#",
300
+ "limit-exceeded",
301
+ `An enum has ${node.enum.length} values; OpenAI allows at most ${MAX_ENUM_VALUES}.`,
302
+ false
303
+ );
304
+ }
305
+ const children = collectChildren(node);
306
+ for (const c of children) visit(c, depth + 1);
307
+ };
308
+ visit(schema, 0);
309
+ if (propertyCount > MAX_PROPERTIES) {
310
+ warnings.add(
311
+ "#",
312
+ "limit-exceeded",
313
+ `Schema has ${propertyCount} object properties; OpenAI allows at most ${MAX_PROPERTIES}.`,
314
+ false
315
+ );
316
+ }
317
+ if (maxDepth > MAX_DEPTH) {
318
+ warnings.add(
319
+ "#",
320
+ "limit-exceeded",
321
+ `Schema nests ${maxDepth} levels deep; OpenAI allows at most ${MAX_DEPTH}.`,
322
+ false
323
+ );
324
+ }
325
+ }
326
+ function collectChildren(node) {
327
+ const out = [];
328
+ if (isPlainObject(node.properties)) out.push(...Object.values(node.properties));
329
+ if (Array.isArray(node.items)) out.push(...node.items);
330
+ else if (isPlainObject(node.items)) out.push(node.items);
331
+ for (const key of ["anyOf", "oneOf", "allOf"]) {
332
+ const arr = node[key];
333
+ if (Array.isArray(arr)) out.push(...arr);
334
+ }
335
+ if (isPlainObject(node.$defs)) out.push(...Object.values(node.$defs));
336
+ return out.filter(isPlainObject);
337
+ }
338
+
339
+ // src/targets/anthropic.ts
340
+ function toAnthropic(input) {
341
+ const warnings = new Warnings();
342
+ const schema = ensureObjectRoot(clone(input), warnings, "Anthropic");
343
+ return { schema, warnings: warnings.list, lossy: warnings.lossy };
344
+ }
345
+
346
+ // src/targets/gemini.ts
347
+ var STRIP = [
348
+ "$schema",
349
+ "$id",
350
+ "$anchor",
351
+ "$ref",
352
+ "oneOf",
353
+ "allOf",
354
+ "not",
355
+ "if",
356
+ "then",
357
+ "else",
358
+ "additionalProperties",
359
+ "patternProperties",
360
+ "unevaluatedProperties",
361
+ "const",
362
+ "dependentRequired",
363
+ "dependentSchemas",
364
+ "multipleOf",
365
+ "exclusiveMinimum",
366
+ "exclusiveMaximum",
367
+ "uniqueItems",
368
+ "contentEncoding",
369
+ "contentMediaType",
370
+ "$defs",
371
+ "definitions"
372
+ ];
373
+ var TYPE_UPPER = {
374
+ string: "STRING",
375
+ number: "NUMBER",
376
+ integer: "INTEGER",
377
+ boolean: "BOOLEAN",
378
+ array: "ARRAY",
379
+ object: "OBJECT",
380
+ null: "NULL"
381
+ };
382
+ function toGemini(input, options = {}) {
383
+ const warnings = new Warnings();
384
+ const dereferenced = dereference(clone(input), warnings);
385
+ const transform = (node, path) => {
386
+ if (!isPlainObject(node)) return node;
387
+ let s = { ...node };
388
+ for (const kw of STRIP) {
389
+ if (kw in s) {
390
+ delete s[kw];
391
+ warnings.add(path, "stripped-keyword", `'${kw}' is not supported by Gemini (route A); removed.`);
392
+ }
393
+ }
394
+ s = collapseNullableUnion(s, path, warnings);
395
+ s = mapChildren(s, path, transform);
396
+ s = collapseAnyOf(s, path, warnings);
397
+ coerceEnum(s, path, warnings);
398
+ return s;
399
+ };
400
+ let schema = ensureObjectRoot(transform(dereferenced, "#"), warnings, "Gemini");
401
+ if (options.uppercaseTypes) schema = uppercaseTypes(schema);
402
+ return { schema, warnings: warnings.list, lossy: warnings.lossy };
403
+ }
404
+ function uppercaseTypes(node) {
405
+ if (!isPlainObject(node)) return node;
406
+ const out = { ...node };
407
+ if (typeof out.type === "string") {
408
+ out.type = TYPE_UPPER[out.type] ?? out.type;
409
+ } else if (Array.isArray(out.type)) {
410
+ out.type = out.type.map((t) => TYPE_UPPER[t] ?? t);
411
+ }
412
+ return mapChildren(out, "#", (child) => uppercaseTypes(child));
413
+ }
414
+ function toGeminiJsonSchema(input) {
415
+ const warnings = new Warnings();
416
+ const schema = ensureObjectRoot(clone(input), warnings, "Gemini (parametersJsonSchema)");
417
+ return { schema, warnings: warnings.list, lossy: warnings.lossy };
418
+ }
419
+ function collapseNullableUnion(node, path, warnings) {
420
+ if (!Array.isArray(node.type)) return node;
421
+ const nonNull = node.type.filter((t) => t !== "null");
422
+ const hadNull = node.type.includes("null");
423
+ const out = { ...node };
424
+ if (nonNull.length === 0) {
425
+ out.type = "string";
426
+ } else {
427
+ out.type = nonNull[0];
428
+ if (nonNull.length > 1) {
429
+ warnings.add(
430
+ path,
431
+ "union-types",
432
+ `Gemini cannot express a union of types [${nonNull.join(", ")}]; kept '${nonNull[0]}'.`
433
+ );
434
+ }
435
+ }
436
+ if (hadNull) {
437
+ out.nullable = true;
438
+ warnings.add(path, "collapsed-nullable", "Converted nullable type union into 'nullable: true'.", false);
439
+ }
440
+ return out;
441
+ }
442
+ function collapseAnyOf(node, path, warnings) {
443
+ if (!Array.isArray(node.anyOf)) return node;
444
+ const branches = node.anyOf;
445
+ const nonNull = branches.filter((b) => !(typesOf(b).length === 1 && typesOf(b)[0] === "null"));
446
+ const hadNull = nonNull.length !== branches.length;
447
+ const out = { ...node };
448
+ if (hadNull) {
449
+ out.nullable = true;
450
+ warnings.add(path, "collapsed-nullable", "Converted an anyOf null branch into 'nullable: true'.", false);
451
+ }
452
+ if (nonNull.length === 0) {
453
+ delete out.anyOf;
454
+ if (!out.type) out.type = "string";
455
+ } else if (nonNull.length === 1) {
456
+ delete out.anyOf;
457
+ const branch = nonNull[0];
458
+ for (const [k, v] of Object.entries(branch)) {
459
+ if (k === "description" && out.description) continue;
460
+ out[k] = v;
461
+ }
462
+ } else {
463
+ out.anyOf = nonNull;
464
+ }
465
+ return out;
466
+ }
467
+ function coerceEnum(node, path, warnings) {
468
+ if (!Array.isArray(node.enum)) return;
469
+ const allStrings = node.enum.every((v) => typeof v === "string");
470
+ if (!allStrings) {
471
+ node.enum = node.enum.map((v) => String(v));
472
+ warnings.add(`${path}/enum`, "enum-coerced", "Gemini enum values must be strings; coerced non string values.");
473
+ }
474
+ if (!node.type) node.type = "string";
475
+ }
476
+
477
+ // src/targets/mcp.ts
478
+ function toMcp(input) {
479
+ const warnings = new Warnings();
480
+ const schema = ensureObjectRoot(clone(input), warnings, "MCP");
481
+ return { schema, warnings: warnings.list, lossy: warnings.lossy };
482
+ }
483
+
484
+ // src/transform.ts
485
+ var EMPTY_OBJECT_SCHEMA = { type: "object", properties: {} };
486
+ function toToolSchema(schema, options = {}) {
487
+ const target = options.target ?? "openai";
488
+ switch (target) {
489
+ case "openai":
490
+ return toOpenAI(schema);
491
+ case "openai-strict":
492
+ return toOpenAIStrict(schema);
493
+ case "anthropic":
494
+ return toAnthropic(schema);
495
+ case "gemini":
496
+ return toGemini(schema, { uppercaseTypes: options.geminiUppercaseTypes });
497
+ case "gemini-jsonschema":
498
+ return toGeminiJsonSchema(schema);
499
+ case "mcp":
500
+ return toMcp(schema);
501
+ default:
502
+ throw new Error(`Unknown target: ${String(target)}`);
503
+ }
504
+ }
505
+ function toTool(def, options = {}) {
506
+ const target = options.target ?? "openai";
507
+ const result = toToolSchema(def.schema ?? EMPTY_OBJECT_SCHEMA, options);
508
+ const warnings = [...result.warnings];
509
+ validateName(def.name, target, warnings);
510
+ const tool = buildTool(def, result.schema, target, options);
511
+ return { tool, warnings, lossy: result.lossy };
512
+ }
513
+ function lintToolSchema(schema, options = {}) {
514
+ const { warnings } = toToolSchema(schema, options);
515
+ return { ok: warnings.length === 0, issues: warnings };
516
+ }
517
+ function buildTool(def, schema, target, options) {
518
+ const { name, description } = def;
519
+ switch (target) {
520
+ case "openai":
521
+ case "openai-strict": {
522
+ const strict = target === "openai-strict";
523
+ if (options.openaiResponses) {
524
+ return {
525
+ type: "function",
526
+ name,
527
+ ...description ? { description } : {},
528
+ parameters: schema,
529
+ ...strict ? { strict: true } : {}
530
+ };
531
+ }
532
+ return {
533
+ type: "function",
534
+ function: {
535
+ name,
536
+ ...description ? { description } : {},
537
+ parameters: schema,
538
+ ...strict ? { strict: true } : {}
539
+ }
540
+ };
541
+ }
542
+ case "anthropic":
543
+ return {
544
+ name,
545
+ ...description ? { description } : {},
546
+ input_schema: schema,
547
+ ...options.anthropicStrict ? { strict: true } : {}
548
+ };
549
+ case "gemini":
550
+ return {
551
+ name,
552
+ ...description ? { description } : {},
553
+ parameters: schema
554
+ };
555
+ case "gemini-jsonschema":
556
+ return {
557
+ name,
558
+ ...description ? { description } : {},
559
+ parametersJsonSchema: schema
560
+ };
561
+ case "mcp":
562
+ return {
563
+ name,
564
+ ...description ? { description } : {},
565
+ inputSchema: schema,
566
+ ...def.annotations ? { annotations: def.annotations } : {}
567
+ };
568
+ default:
569
+ throw new Error(`Unknown target: ${String(target)}`);
570
+ }
571
+ }
572
+ var NAME_RULES = {
573
+ openai: { pattern: /^[a-zA-Z0-9_-]{1,64}$/, label: "OpenAI (letters, digits, _ and -, max 64)" },
574
+ "openai-strict": { pattern: /^[a-zA-Z0-9_-]{1,64}$/, label: "OpenAI (letters, digits, _ and -, max 64)" },
575
+ anthropic: { pattern: /^[a-zA-Z0-9_-]{1,64}$/, label: "Anthropic (letters, digits, _ and -, max 64)" },
576
+ gemini: { pattern: /^[a-zA-Z0-9_:.-]{1,128}$/, label: "Gemini (letters, digits, _ : . -, max 128)" },
577
+ "gemini-jsonschema": { pattern: /^[a-zA-Z0-9_:.-]{1,128}$/, label: "Gemini (letters, digits, _ : . -, max 128)" },
578
+ mcp: { pattern: /^[a-zA-Z0-9_-]{1,128}$/, label: "MCP (letters, digits, _ and -)" }
579
+ };
580
+ function validateName(name, target, warnings) {
581
+ const rule = NAME_RULES[target];
582
+ if (!rule.pattern.test(name)) {
583
+ warnings.push({
584
+ path: "#/name",
585
+ code: "invalid-name",
586
+ message: `Tool name '${name}' does not match the ${rule.label} naming rule.`
587
+ });
588
+ }
589
+ }
590
+ // Annotate the CommonJS export names for ESM import in node:
591
+ 0 && (module.exports = {
592
+ lintToolSchema,
593
+ toTool,
594
+ toToolSchema
595
+ });
596
+ //# sourceMappingURL=index.cjs.map