@frontmcp/uipack 1.8.0 → 1.8.2

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.
@@ -1283,14 +1283,16 @@ function isNpmShellSource(source) {
1283
1283
  }
1284
1284
 
1285
1285
  // libs/uipack/src/shell/custom-shell-applier.ts
1286
+ var PLACEHOLDER_PATTERN = new RegExp(`\\{\\{(${SHELL_PLACEHOLDER_NAMES.join("|")})\\}\\}`, "g");
1287
+ var VALUE_KEYS = {
1288
+ CSP: "csp",
1289
+ DATA: "data",
1290
+ BRIDGE: "bridge",
1291
+ CONTENT: "content",
1292
+ TITLE: "title"
1293
+ };
1286
1294
  function applyShellTemplate(template, values) {
1287
- let result = template;
1288
- result = result.replaceAll(SHELL_PLACEHOLDERS.CSP, values.csp);
1289
- result = result.replaceAll(SHELL_PLACEHOLDERS.DATA, values.data);
1290
- result = result.replaceAll(SHELL_PLACEHOLDERS.BRIDGE, values.bridge);
1291
- result = result.replaceAll(SHELL_PLACEHOLDERS.CONTENT, values.content);
1292
- result = result.replaceAll(SHELL_PLACEHOLDERS.TITLE, values.title);
1293
- return result;
1295
+ return template.replace(PLACEHOLDER_PATTERN, (_token, name) => values[VALUE_KEYS[name]]);
1294
1296
  }
1295
1297
 
1296
1298
  // libs/uipack/src/shell/custom-shell-validator.ts
@@ -1317,8 +1319,9 @@ function escapeHtml(str) {
1317
1319
  const s = String(str);
1318
1320
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
1319
1321
  }
1320
- function escapeScriptClose(jsonString) {
1321
- return jsonString.replace(/<\//g, "<\\/");
1322
+ var SCRIPT_UNSAFE_CHARACTERS = /[<>&\u2028\u2029]/g;
1323
+ function toUnicodeEscape(character) {
1324
+ return `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`;
1322
1325
  }
1323
1326
  function safeJsonForScript(value) {
1324
1327
  if (value === void 0) {
@@ -1334,12 +1337,35 @@ function safeJsonForScript(value) {
1334
1337
  if (jsonString === void 0) {
1335
1338
  return "null";
1336
1339
  }
1337
- return escapeScriptClose(jsonString);
1340
+ return jsonString.replace(SCRIPT_UNSAFE_CHARACTERS, toUnicodeEscape);
1338
1341
  } catch {
1339
1342
  return '{"error":"Value could not be serialized"}';
1340
1343
  }
1341
1344
  }
1342
1345
 
1346
+ // libs/uipack/src/shell/trusted-html.ts
1347
+ var TRUSTED_HTML = /* @__PURE__ */ Symbol.for("@frontmcp/uipack/trusted-html");
1348
+ function trustedHtml(markup) {
1349
+ const value = String(markup);
1350
+ return Object.freeze({ [TRUSTED_HTML]: value, toString: () => value });
1351
+ }
1352
+ function isTrustedHtml(value) {
1353
+ return typeof value === "object" && value !== null && typeof value[TRUSTED_HTML] === "string";
1354
+ }
1355
+ function interpolate(value) {
1356
+ if (isTrustedHtml(value)) return value[TRUSTED_HTML];
1357
+ if (Array.isArray(value)) return value.map(interpolate).join("");
1358
+ if (value === false) return "";
1359
+ return escapeHtml(value);
1360
+ }
1361
+ function html(strings, ...values) {
1362
+ let markup = strings[0];
1363
+ for (let index = 0; index < values.length; index++) {
1364
+ markup += interpolate(values[index]) + strings[index + 1];
1365
+ }
1366
+ return trustedHtml(markup);
1367
+ }
1368
+
1343
1369
  // libs/uipack/src/shell/data-injector.ts
1344
1370
  function hasSizing(sizing) {
1345
1371
  if (!sizing) return false;
@@ -1393,9 +1419,9 @@ function createTemplateHelpers() {
1393
1419
  uniqueId: (prefix = "mcp") => {
1394
1420
  return `${prefix}-${++_uniqueIdCounter}`;
1395
1421
  },
1396
- jsonEmbed: (data) => {
1397
- return escapeScriptClose(JSON.stringify(data));
1398
- }
1422
+ jsonEmbed: (data) => safeJsonForScript(data),
1423
+ html,
1424
+ trustedHtml
1399
1425
  };
1400
1426
  }
1401
1427
 
@@ -1473,12 +1499,12 @@ function buildShell(content, config) {
1473
1499
  sizing
1474
1500
  });
1475
1501
  if (!withShell) {
1476
- const html2 = `${dataScript}
1502
+ const html3 = `${dataScript}
1477
1503
  ${content}`;
1478
1504
  return {
1479
- html: html2,
1480
- hash: simpleHash(html2),
1481
- size: Buffer.byteLength(html2, "utf-8")
1505
+ html: html3,
1506
+ hash: simpleHash(html3),
1507
+ size: Buffer.byteLength(html3, "utf-8")
1482
1508
  };
1483
1509
  }
1484
1510
  if (customShell) {
@@ -1511,7 +1537,7 @@ ${content}`;
1511
1537
  const bridgeScript = generateBridgeIIFE({ minify: true });
1512
1538
  headParts.push(`<script>${bridgeScript}</script>`);
1513
1539
  }
1514
- const html = `<!DOCTYPE html>
1540
+ const html2 = `<!DOCTYPE html>
1515
1541
  <html lang="en">
1516
1542
  <head>
1517
1543
  ${headParts.map((p) => ` ${p}`).join("\n")}
@@ -1521,9 +1547,9 @@ ${content}
1521
1547
  </body>
1522
1548
  </html>`;
1523
1549
  return {
1524
- html,
1525
- hash: simpleHash(html),
1526
- size: Buffer.byteLength(html, "utf-8")
1550
+ html: html2,
1551
+ hash: simpleHash(html2),
1552
+ size: Buffer.byteLength(html2, "utf-8")
1527
1553
  };
1528
1554
  }
1529
1555
  function buildCustomShell(content, customShell, ctx) {
@@ -1556,7 +1582,7 @@ ${sizingStyle}` : dataScript;
1556
1582
  const bridgeScript = generateBridgeIIFE({ minify: true });
1557
1583
  bridgeHtml = `<script>${bridgeScript}</script>`;
1558
1584
  }
1559
- const html = applyShellTemplate(template, {
1585
+ const html2 = applyShellTemplate(template, {
1560
1586
  csp: cspTag,
1561
1587
  data: dataWithSizing,
1562
1588
  bridge: bridgeHtml,
@@ -1564,9 +1590,9 @@ ${sizingStyle}` : dataScript;
1564
1590
  title: ctx.title ? escapeHtmlForTag(ctx.title) : ""
1565
1591
  });
1566
1592
  return {
1567
- html,
1568
- hash: simpleHash(html),
1569
- size: Buffer.byteLength(html, "utf-8")
1593
+ html: html2,
1594
+ hash: simpleHash(html2),
1595
+ size: Buffer.byteLength(html2, "utf-8")
1570
1596
  };
1571
1597
  }
1572
1598
  function simpleHash(str) {
@@ -1707,11 +1733,14 @@ export {
1707
1733
  clearShellTemplateCache,
1708
1734
  createTemplateHelpers,
1709
1735
  hasSizing,
1736
+ html,
1710
1737
  isInlineShellSource,
1711
1738
  isNpmShellSource,
1739
+ isTrustedHtml,
1712
1740
  isUrlShellSource,
1713
1741
  resolveShellTemplate,
1714
1742
  sanitizeCSPDomains,
1743
+ trustedHtml,
1715
1744
  validateCSPDomain,
1716
1745
  validateShellTemplate
1717
1746
  };
@@ -33,6 +33,10 @@ function escapeJsString(str) {
33
33
  function escapeScriptClose(jsonString) {
34
34
  return jsonString.replace(/<\//g, "<\\/");
35
35
  }
36
+ var SCRIPT_UNSAFE_CHARACTERS = /[<>&\u2028\u2029]/g;
37
+ function toUnicodeEscape(character) {
38
+ return `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`;
39
+ }
36
40
  function safeJsonForScript(value) {
37
41
  if (value === void 0) {
38
42
  return "null";
@@ -47,7 +51,7 @@ function safeJsonForScript(value) {
47
51
  if (jsonString === void 0) {
48
52
  return "null";
49
53
  }
50
- return escapeScriptClose(jsonString);
54
+ return jsonString.replace(SCRIPT_UNSAFE_CHARACTERS, toUnicodeEscape);
51
55
  } catch {
52
56
  return '{"error":"Value could not be serialized"}';
53
57
  }
package/index.d.ts CHANGED
@@ -17,7 +17,7 @@ export * from './utils';
17
17
  export { generateBridgeIIFE, generatePlatformBundle, UNIVERSAL_BRIDGE_SCRIPT, BRIDGE_SCRIPT_TAGS, type IIFEGeneratorOptions, } from './bridge-runtime';
18
18
  export { type TypeFetchResult, type TypeFetchError, type TypeFetchErrorCode, type TypeFetchBatchRequest, type TypeFetchBatchResult, type TypeCacheEntry, type TypeCacheStats, type DtsImport, type DtsParseResult, type TypeFetcherOptions, type PackageResolution, DEFAULT_TYPE_FETCHER_OPTIONS, TYPE_CACHE_PREFIX, DEFAULT_TYPE_CACHE_TTL, type TypeCacheAdapter, type TypeCacheOptions, DEFAULT_CACHE_OPTIONS as DEFAULT_TYPE_CACHE_OPTIONS, MemoryTypeCache, globalTypeCache, parseDtsImports, isRelativeImport, getPackageFromSpecifier, getSubpathFromSpecifier, parseImportStatement, combineDtsContents, TypeFetcher, createTypeFetcher, } from './typings';
19
19
  export * from './resolver';
20
- export { type ShellConfig, type ShellResult, type CSPConfig, type ShellMountDescriptor, type ShellDataInjectionDescriptor, buildShell, DEFAULT_CDN_DOMAINS, DEFAULT_CSP_DIRECTIVES, RESTRICTIVE_CSP_DIRECTIVES, buildCSPDirectives, buildCSPMetaTag, validateCSPDomain, sanitizeCSPDomains, buildDataInjectionScript, buildCustomDataInjectionScript, createTemplateHelpers, type ShellPlaceholderName, type InlineShellSource, type UrlShellSource, type NpmShellSource, type CustomShellSource, type ShellTemplateValidation, type ResolvedShellTemplate, type ShellPlaceholderValues, type ResolveShellOptions, SHELL_PLACEHOLDER_NAMES, SHELL_PLACEHOLDERS, REQUIRED_PLACEHOLDERS, OPTIONAL_PLACEHOLDERS, isInlineShellSource, isUrlShellSource, isNpmShellSource, validateShellTemplate, applyShellTemplate, resolveShellTemplate, clearShellTemplateCache, } from './shell';
20
+ export { type ShellConfig, type ShellResult, type CSPConfig, type ShellMountDescriptor, type ShellDataInjectionDescriptor, buildShell, DEFAULT_CDN_DOMAINS, DEFAULT_CSP_DIRECTIVES, RESTRICTIVE_CSP_DIRECTIVES, buildCSPDirectives, buildCSPMetaTag, validateCSPDomain, sanitizeCSPDomains, buildDataInjectionScript, buildCustomDataInjectionScript, createTemplateHelpers, html, trustedHtml, isTrustedHtml, type TrustedHtml, type ShellPlaceholderName, type InlineShellSource, type UrlShellSource, type NpmShellSource, type CustomShellSource, type ShellTemplateValidation, type ResolvedShellTemplate, type ShellPlaceholderValues, type ResolveShellOptions, SHELL_PLACEHOLDER_NAMES, SHELL_PLACEHOLDERS, REQUIRED_PLACEHOLDERS, OPTIONAL_PLACEHOLDERS, isInlineShellSource, isUrlShellSource, isNpmShellSource, validateShellTemplate, applyShellTemplate, resolveShellTemplate, clearShellTemplateCache, } from './shell';
21
21
  export * from './component';
22
22
  export * from './adapters';
23
23
  //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,cAAc,SAAS,CAAC;AAKxB,cAAc,SAAS,CAAC;AAKxB,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,KAAK,oBAAoB,GAC1B,MAAM,kBAAkB,CAAC;AAK1B,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,4BAA4B,EAC5B,iBAAiB,EACjB,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,qBAAqB,IAAI,0BAA0B,EACnD,eAAe,EACf,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EAClB,WAAW,EACX,iBAAiB,GAClB,MAAM,WAAW,CAAC;AAKnB,cAAc,YAAY,CAAC;AAM3B,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,UAAU,EACV,mBAAmB,EACnB,sBAAsB,EACtB,0BAA0B,EAC1B,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,8BAA8B,EAC9B,qBAAqB,EAErB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,SAAS,CAAC;AAKjB,cAAc,aAAa,CAAC;AAK5B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,cAAc,SAAS,CAAC;AAKxB,cAAc,SAAS,CAAC;AAKxB,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,KAAK,oBAAoB,GAC1B,MAAM,kBAAkB,CAAC;AAK1B,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,4BAA4B,EAC5B,iBAAiB,EACjB,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,qBAAqB,IAAI,0BAA0B,EACnD,eAAe,EACf,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EAClB,WAAW,EACX,iBAAiB,GAClB,MAAM,WAAW,CAAC;AAKnB,cAAc,YAAY,CAAC;AAM3B,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,UAAU,EACV,mBAAmB,EACnB,sBAAsB,EACtB,0BAA0B,EAC1B,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,8BAA8B,EAC9B,qBAAqB,EAErB,IAAI,EACJ,WAAW,EACX,aAAa,EACb,KAAK,WAAW,EAEhB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,SAAS,CAAC;AAKjB,cAAc,aAAa,CAAC;AAK5B,cAAc,YAAY,CAAC"}
package/index.js CHANGED
@@ -84,6 +84,7 @@ __export(index_exports, {
84
84
  getRegisteredPackages: () => getRegisteredPackages,
85
85
  getSubpathFromSpecifier: () => getSubpathFromSpecifier,
86
86
  globalTypeCache: () => globalTypeCache,
87
+ html: () => html,
87
88
  isBundlingMode: () => isBundlingMode,
88
89
  isDisplayMode: () => isDisplayMode,
89
90
  isFileSource: () => isFileSource,
@@ -96,6 +97,7 @@ __export(index_exports, {
96
97
  isPackageRegistered: () => isPackageRegistered,
97
98
  isRelativeImport: () => isRelativeImport,
98
99
  isResourceMode: () => isResourceMode,
100
+ isTrustedHtml: () => isTrustedHtml,
99
101
  isUIRenderFailure: () => isUIRenderFailure,
100
102
  isUIType: () => isUIType,
101
103
  isUrlShellSource: () => isUrlShellSource,
@@ -115,6 +117,7 @@ __export(index_exports, {
115
117
  safeStringify: () => safeStringify,
116
118
  sanitizeCSPDomains: () => sanitizeCSPDomains,
117
119
  transpileReactSource: () => transpileReactSource,
120
+ trustedHtml: () => trustedHtml,
118
121
  validateCSPDomain: () => validateCSPDomain,
119
122
  validateImportMap: () => validateImportMap,
120
123
  validateShellTemplate: () => validateShellTemplate,
@@ -224,6 +227,10 @@ function escapeJsString(str) {
224
227
  function escapeScriptClose(jsonString) {
225
228
  return jsonString.replace(/<\//g, "<\\/");
226
229
  }
230
+ var SCRIPT_UNSAFE_CHARACTERS = /[<>&\u2028\u2029]/g;
231
+ function toUnicodeEscape(character) {
232
+ return `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`;
233
+ }
227
234
  function safeJsonForScript(value) {
228
235
  if (value === void 0) {
229
236
  return "null";
@@ -238,7 +245,7 @@ function safeJsonForScript(value) {
238
245
  if (jsonString === void 0) {
239
246
  return "null";
240
247
  }
241
- return escapeScriptClose(jsonString);
248
+ return jsonString.replace(SCRIPT_UNSAFE_CHARACTERS, toUnicodeEscape);
242
249
  } catch {
243
250
  return '{"error":"Value could not be serialized"}';
244
251
  }
@@ -3002,14 +3009,16 @@ function isNpmShellSource(source) {
3002
3009
  }
3003
3010
 
3004
3011
  // libs/uipack/src/shell/custom-shell-applier.ts
3012
+ var PLACEHOLDER_PATTERN = new RegExp(`\\{\\{(${SHELL_PLACEHOLDER_NAMES.join("|")})\\}\\}`, "g");
3013
+ var VALUE_KEYS = {
3014
+ CSP: "csp",
3015
+ DATA: "data",
3016
+ BRIDGE: "bridge",
3017
+ CONTENT: "content",
3018
+ TITLE: "title"
3019
+ };
3005
3020
  function applyShellTemplate(template, values) {
3006
- let result = template;
3007
- result = result.replaceAll(SHELL_PLACEHOLDERS.CSP, values.csp);
3008
- result = result.replaceAll(SHELL_PLACEHOLDERS.DATA, values.data);
3009
- result = result.replaceAll(SHELL_PLACEHOLDERS.BRIDGE, values.bridge);
3010
- result = result.replaceAll(SHELL_PLACEHOLDERS.CONTENT, values.content);
3011
- result = result.replaceAll(SHELL_PLACEHOLDERS.TITLE, values.title);
3012
- return result;
3021
+ return template.replace(PLACEHOLDER_PATTERN, (_token, name) => values[VALUE_KEYS[name]]);
3013
3022
  }
3014
3023
 
3015
3024
  // libs/uipack/src/shell/custom-shell-validator.ts
@@ -3028,6 +3037,29 @@ function validateShellTemplate(template) {
3028
3037
  };
3029
3038
  }
3030
3039
 
3040
+ // libs/uipack/src/shell/trusted-html.ts
3041
+ var TRUSTED_HTML = /* @__PURE__ */ Symbol.for("@frontmcp/uipack/trusted-html");
3042
+ function trustedHtml(markup) {
3043
+ const value = String(markup);
3044
+ return Object.freeze({ [TRUSTED_HTML]: value, toString: () => value });
3045
+ }
3046
+ function isTrustedHtml(value) {
3047
+ return typeof value === "object" && value !== null && typeof value[TRUSTED_HTML] === "string";
3048
+ }
3049
+ function interpolate(value) {
3050
+ if (isTrustedHtml(value)) return value[TRUSTED_HTML];
3051
+ if (Array.isArray(value)) return value.map(interpolate).join("");
3052
+ if (value === false) return "";
3053
+ return escapeHtml(value);
3054
+ }
3055
+ function html(strings, ...values) {
3056
+ let markup = strings[0];
3057
+ for (let index = 0; index < values.length; index++) {
3058
+ markup += interpolate(values[index]) + strings[index + 1];
3059
+ }
3060
+ return trustedHtml(markup);
3061
+ }
3062
+
3031
3063
  // libs/uipack/src/shell/data-injector.ts
3032
3064
  function hasSizing(sizing) {
3033
3065
  if (!sizing) return false;
@@ -3081,9 +3113,9 @@ function createTemplateHelpers() {
3081
3113
  uniqueId: (prefix = "mcp") => {
3082
3114
  return `${prefix}-${++_uniqueIdCounter}`;
3083
3115
  },
3084
- jsonEmbed: (data) => {
3085
- return escapeScriptClose(JSON.stringify(data));
3086
- }
3116
+ jsonEmbed: (data) => safeJsonForScript(data),
3117
+ html,
3118
+ trustedHtml
3087
3119
  };
3088
3120
  }
3089
3121
 
@@ -3161,12 +3193,12 @@ function buildShell(content, config) {
3161
3193
  sizing
3162
3194
  });
3163
3195
  if (!withShell) {
3164
- const html2 = `${dataScript}
3196
+ const html3 = `${dataScript}
3165
3197
  ${content}`;
3166
3198
  return {
3167
- html: html2,
3168
- hash: simpleHash(html2),
3169
- size: Buffer.byteLength(html2, "utf-8")
3199
+ html: html3,
3200
+ hash: simpleHash(html3),
3201
+ size: Buffer.byteLength(html3, "utf-8")
3170
3202
  };
3171
3203
  }
3172
3204
  if (customShell) {
@@ -3199,7 +3231,7 @@ ${content}`;
3199
3231
  const bridgeScript = generateBridgeIIFE({ minify: true });
3200
3232
  headParts.push(`<script>${bridgeScript}</script>`);
3201
3233
  }
3202
- const html = `<!DOCTYPE html>
3234
+ const html2 = `<!DOCTYPE html>
3203
3235
  <html lang="en">
3204
3236
  <head>
3205
3237
  ${headParts.map((p) => ` ${p}`).join("\n")}
@@ -3209,9 +3241,9 @@ ${content}
3209
3241
  </body>
3210
3242
  </html>`;
3211
3243
  return {
3212
- html,
3213
- hash: simpleHash(html),
3214
- size: Buffer.byteLength(html, "utf-8")
3244
+ html: html2,
3245
+ hash: simpleHash(html2),
3246
+ size: Buffer.byteLength(html2, "utf-8")
3215
3247
  };
3216
3248
  }
3217
3249
  function buildCustomShell(content, customShell, ctx) {
@@ -3244,7 +3276,7 @@ ${sizingStyle}` : dataScript;
3244
3276
  const bridgeScript = generateBridgeIIFE({ minify: true });
3245
3277
  bridgeHtml = `<script>${bridgeScript}</script>`;
3246
3278
  }
3247
- const html = applyShellTemplate(template, {
3279
+ const html2 = applyShellTemplate(template, {
3248
3280
  csp: cspTag,
3249
3281
  data: dataWithSizing,
3250
3282
  bridge: bridgeHtml,
@@ -3252,9 +3284,9 @@ ${sizingStyle}` : dataScript;
3252
3284
  title: ctx.title ? escapeHtmlForTag(ctx.title) : ""
3253
3285
  });
3254
3286
  return {
3255
- html,
3256
- hash: simpleHash(html),
3257
- size: Buffer.byteLength(html, "utf-8")
3287
+ html: html2,
3288
+ hash: simpleHash(html2),
3289
+ size: Buffer.byteLength(html2, "utf-8")
3258
3290
  };
3259
3291
  }
3260
3292
  function simpleHash(str) {
@@ -3661,10 +3693,10 @@ function resolveFileSource(source, options = {}) {
3661
3693
  };
3662
3694
  }
3663
3695
  function resolveFunctionSource(source, input, output) {
3664
- const html = source(input, output);
3696
+ const html2 = source(input, output);
3665
3697
  return {
3666
3698
  mode: "inline",
3667
- html,
3699
+ html: html2,
3668
3700
  exportName: "default",
3669
3701
  meta: { mcpAware: false, renderer: "html" },
3670
3702
  peerDependencies: []
@@ -3938,6 +3970,7 @@ var MERMAID_PREFIXES = [
3938
3970
  "xychart"
3939
3971
  ];
3940
3972
  var PDF_MAGIC = "JVBERi";
3973
+ var BASE64_PATTERN = /^[A-Za-z0-9+/=\r\n]+$/;
3941
3974
  function detectContentType(value) {
3942
3975
  if (value === null || value === void 0) {
3943
3976
  return "text";
@@ -3952,7 +3985,7 @@ function detectContentType(value) {
3952
3985
  if (typeof value === "string") {
3953
3986
  const trimmed = value.trimStart();
3954
3987
  if (trimmed.startsWith(PDF_MAGIC)) {
3955
- return "pdf";
3988
+ return BASE64_PATTERN.test(trimmed.trimEnd()) ? "pdf" : "text";
3956
3989
  }
3957
3990
  for (const prefix of MERMAID_PREFIXES) {
3958
3991
  if (trimmed.startsWith(prefix)) {
@@ -4014,7 +4047,7 @@ function buildPdfHtml(base64) {
4014
4047
  import * as pdfjsLib from 'https://esm.sh/pdfjs-dist@4/build/pdf.min.mjs';
4015
4048
  pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://esm.sh/pdfjs-dist@4/build/pdf.worker.min.mjs';
4016
4049
 
4017
- const base64 = ${JSON.stringify(base64)};
4050
+ const base64 = ${safeJsonForScript(base64)};
4018
4051
  const binaryStr = atob(base64);
4019
4052
  const bytes = new Uint8Array(binaryStr.length);
4020
4053
  for (let i = 0; i < binaryStr.length; i++) bytes[i] = binaryStr.charCodeAt(i);
@@ -4109,6 +4142,30 @@ function buildCspConfig(resolver) {
4109
4142
  }
4110
4143
  return { resourceDomains: cspResourceDomains, connectDomains: cspConnectDomains };
4111
4144
  }
4145
+ var STRING_RESULT_DOCS = "https://docs.agentfront.dev/frontmcp/guides/building-tool-ui#trusted-markup";
4146
+ var noticedStringResultTools = /* @__PURE__ */ new Set();
4147
+ function noticeStringResult(toolName, logger) {
4148
+ if (noticedStringResultTools.has(toolName)) return;
4149
+ noticedStringResultTools.add(toolName);
4150
+ logger.warn(
4151
+ `[frontmcp] The UI template of tool "${toolName}" returned a plain string containing markup, which is rendered as HTML. FrontMCP 1.9 will HTML-escape plain string results by default. Build the markup with ctx.helpers.html\`\u2026\` (interpolated values are escaped) or wrap safe markup with ctx.helpers.trustedHtml(), then set ui.escapeStringResults: true (or escapeStringResults: false to keep the current behaviour without this notice). See ${STRING_RESULT_DOCS}`
4152
+ );
4153
+ }
4154
+ function renderUnwrappedResult(rawResult, options) {
4155
+ if (isTrustedHtml(rawResult)) {
4156
+ return String(rawResult);
4157
+ }
4158
+ if (typeof rawResult !== "string") {
4159
+ return `<pre>${escapeHtml(JSON.stringify(rawResult, null, 2))}</pre>`;
4160
+ }
4161
+ if (detectContentType(rawResult) !== "html" || options.escapeStringResults === true) {
4162
+ return escapeHtml(rawResult);
4163
+ }
4164
+ if (options.escapeStringResults === void 0) {
4165
+ noticeStringResult(options.toolName, options.logger ?? console);
4166
+ }
4167
+ return rawResult;
4168
+ }
4112
4169
  function renderToolTemplate(options) {
4113
4170
  const { toolName, input, output, template, resolver, platformType, sizing } = options;
4114
4171
  const uiType = detectUIType(template);
@@ -4121,7 +4178,7 @@ function renderToolTemplate(options) {
4121
4178
  resolver,
4122
4179
  sizing
4123
4180
  };
4124
- let html;
4181
+ let html2;
4125
4182
  let hash = "";
4126
4183
  let size = 0;
4127
4184
  if (typeof template === "object" && template !== null && "file" in template) {
@@ -4130,44 +4187,43 @@ function renderToolTemplate(options) {
4130
4187
  { source: template, inlineReact: resourceMode === "inline" },
4131
4188
  { ...shellConfig, csp: cspConfig }
4132
4189
  );
4133
- html = result.html;
4190
+ html2 = result.html;
4134
4191
  hash = result.hash;
4135
4192
  size = result.size;
4136
4193
  } else if (typeof template === "function") {
4137
4194
  if (uiType === "react") {
4138
4195
  const shellResult = buildShell('<div id="root"></div>', shellConfig);
4139
- html = shellResult.html;
4196
+ html2 = shellResult.html;
4140
4197
  hash = shellResult.hash;
4141
4198
  size = shellResult.size;
4142
4199
  } else {
4143
4200
  const helpers = createTemplateHelpers();
4144
4201
  const ctx = { input, output, helpers };
4145
4202
  const rawResult = template(ctx);
4146
- const wrapped = wrapDetectedContent(rawResult);
4203
+ const wrapped = isTrustedHtml(rawResult) ? void 0 : wrapDetectedContent(rawResult);
4147
4204
  if (wrapped) {
4148
- html = wrapped;
4205
+ html2 = wrapped;
4149
4206
  } else {
4150
- const textContent = typeof rawResult === "string" ? rawResult : `<pre>${JSON.stringify(rawResult, null, 2)}</pre>`;
4151
- const shellResult = buildShell(textContent, shellConfig);
4152
- html = shellResult.html;
4207
+ const shellResult = buildShell(renderUnwrappedResult(rawResult, options), shellConfig);
4208
+ html2 = shellResult.html;
4153
4209
  hash = shellResult.hash;
4154
4210
  size = shellResult.size;
4155
4211
  }
4156
4212
  }
4157
4213
  } else if (typeof template === "string") {
4158
4214
  const shellResult = buildShell(template, shellConfig);
4159
- html = shellResult.html;
4215
+ html2 = shellResult.html;
4160
4216
  hash = shellResult.hash;
4161
4217
  size = shellResult.size;
4162
4218
  } else {
4163
4219
  const shellResult = buildShell('<div id="root"></div>', shellConfig);
4164
- html = shellResult.html;
4220
+ html2 = shellResult.html;
4165
4221
  hash = shellResult.hash;
4166
4222
  size = shellResult.size;
4167
4223
  }
4168
4224
  const htmlKey = "ui/html";
4169
4225
  const meta = {
4170
- [htmlKey]: html,
4226
+ [htmlKey]: html2,
4171
4227
  "ui/type": uiType,
4172
4228
  "ui/mimeType": MCP_APPS_MIME_TYPE
4173
4229
  };
@@ -4178,10 +4234,10 @@ function renderToolTemplate(options) {
4178
4234
  if (sizing.aspectRatio !== void 0) meta["ui/aspectRatio"] = sizing.aspectRatio;
4179
4235
  }
4180
4236
  return {
4181
- html,
4237
+ html: html2,
4182
4238
  uiType,
4183
4239
  hash,
4184
- size: size || Buffer.byteLength(html, "utf8"),
4240
+ size: size || Buffer.byteLength(html2, "utf8"),
4185
4241
  meta
4186
4242
  };
4187
4243
  }
@@ -4325,6 +4381,7 @@ function buildCDNInfoForUIType(uiType) {
4325
4381
  getRegisteredPackages,
4326
4382
  getSubpathFromSpecifier,
4327
4383
  globalTypeCache,
4384
+ html,
4328
4385
  isBundlingMode,
4329
4386
  isDisplayMode,
4330
4387
  isFileSource,
@@ -4337,6 +4394,7 @@ function buildCDNInfoForUIType(uiType) {
4337
4394
  isPackageRegistered,
4338
4395
  isRelativeImport,
4339
4396
  isResourceMode,
4397
+ isTrustedHtml,
4340
4398
  isUIRenderFailure,
4341
4399
  isUIType,
4342
4400
  isUrlShellSource,
@@ -4356,6 +4414,7 @@ function buildCDNInfoForUIType(uiType) {
4356
4414
  safeStringify,
4357
4415
  sanitizeCSPDomains,
4358
4416
  transpileReactSource,
4417
+ trustedHtml,
4359
4418
  validateCSPDomain,
4360
4419
  validateImportMap,
4361
4420
  validateShellTemplate,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontmcp/uipack",
3
- "version": "1.8.0",
3
+ "version": "1.8.2",
4
4
  "description": "FrontMCP UIpack - HTML shell builder, pluggable import resolver, and NPM component loader for MCP UI (React-free core)",
5
5
  "author": "AgentFront <info@agentfront.dev>",
6
6
  "homepage": "https://docs.agentfront.dev",
@@ -61,6 +61,6 @@
61
61
  "typescript": "^5.9.3"
62
62
  },
63
63
  "peerDependencies": {
64
- "@frontmcp/lazy-zod": "1.8.0"
64
+ "@frontmcp/lazy-zod": "1.8.2"
65
65
  }
66
66
  }
@@ -4,18 +4,19 @@
4
4
  * Replaces placeholder tokens in a custom shell template with
5
5
  * the generated fragment values (CSP, data script, bridge, content, title).
6
6
  *
7
- * Uses sequential `replaceAll` — injected content is NOT re-scanned,
8
- * so `{{CSP}}` inside user content is safe.
7
+ * All placeholders are replaced in a single pass over the template, so an
8
+ * inserted value is never re-scanned for placeholders.
9
9
  *
10
10
  * @packageDocumentation
11
11
  */
12
- import type { ShellPlaceholderValues } from './custom-shell-types';
12
+ import { type ShellPlaceholderValues } from './custom-shell-types';
13
13
  /**
14
14
  * Apply placeholder values to a custom shell template.
15
15
  *
16
- * Each `{{PLACEHOLDER}}` token is replaced with the corresponding value.
17
- * Replacement is single-pass per token — values injected for one placeholder
18
- * are not re-scanned for other placeholders.
16
+ * Each `{{PLACEHOLDER}}` token is replaced with the corresponding value, verbatim.
17
+ * Values carry tool input and output (GHSA-rhr9-vhpf-jqp7), so they are inserted by a
18
+ * function replacer: a value is never re-scanned for other placeholders, and `$&`, `$'`
19
+ * or `` $` `` inside it are not expanded.
19
20
  *
20
21
  * @param template - The shell template with `{{PLACEHOLDER}}` tokens
21
22
  * @param values - The values to inject for each placeholder
@@ -1 +1 @@
1
- {"version":3,"file":"custom-shell-applier.d.ts","sourceRoot":"","sources":["../../src/shell/custom-shell-applier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAEnE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB,GAAG,MAAM,CAU3F"}
1
+ {"version":3,"file":"custom-shell-applier.d.ts","sourceRoot":"","sources":["../../src/shell/custom-shell-applier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAsD,KAAK,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAYvH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB,GAAG,MAAM,CAE3F"}
@@ -6,6 +6,7 @@
6
6
  *
7
7
  * @packageDocumentation
8
8
  */
9
+ import { type TrustedHtml } from './trusted-html';
9
10
  import type { WidgetSizing } from './types';
10
11
  /**
11
12
  * Whether a sizing config carries any value worth injecting/applying.
@@ -58,6 +59,10 @@ export interface TemplateHelpers {
58
59
  uniqueId: (prefix?: string) => string;
59
60
  /** Safely embed JSON data in HTML */
60
61
  jsonEmbed: (data: unknown) => string;
62
+ /** Tagged template building trusted markup; interpolated values are escaped unless trusted */
63
+ html: (strings: TemplateStringsArray, ...values: unknown[]) => TrustedHtml;
64
+ /** Mark already-safe markup as trusted so it renders as HTML */
65
+ trustedHtml: (markup: string) => TrustedHtml;
61
66
  }
62
67
  /**
63
68
  * Create template helper functions.
@@ -1 +1 @@
1
- {"version":3,"file":"data-injector.d.ts","sourceRoot":"","sources":["../../src/shell/data-injector.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM,IAAI,YAAY,CASvE;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB,GAAG,MAAM,CAgBT;AAED;;;;;;;;;GASG;AACH,wBAAgB,8BAA8B,CAAC,UAAU,EAAE;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,CAeT;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,oDAAoD;IACpD,UAAU,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;IACrC,gCAAgC;IAChC,UAAU,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7D,kCAAkC;IAClC,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC9D,4CAA4C;IAC5C,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,qCAAqC;IACrC,SAAS,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM,CAAC;CACtC;AAID;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,CA6BvD"}
1
+ {"version":3,"file":"data-injector.d.ts","sourceRoot":"","sources":["../../src/shell/data-injector.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM,IAAI,YAAY,CASvE;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB,GAAG,MAAM,CAgBT;AAED;;;;;;;;;GASG;AACH,wBAAgB,8BAA8B,CAAC,UAAU,EAAE;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,CAeT;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,oDAAoD;IACpD,UAAU,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;IACrC,gCAAgC;IAChC,UAAU,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7D,kCAAkC;IAClC,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC9D,4CAA4C;IAC5C,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,qCAAqC;IACrC,SAAS,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM,CAAC;IACrC,8FAA8F;IAC9F,IAAI,EAAE,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,KAAK,WAAW,CAAC;IAC3E,gEAAgE;IAChE,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,WAAW,CAAC;CAC9C;AAID;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,CA+BvD"}
package/shell/index.d.ts CHANGED
@@ -11,6 +11,7 @@ export { buildShell } from './builder';
11
11
  export { buildSizingStyleTag } from './sizing-css';
12
12
  export { DEFAULT_CDN_DOMAINS, DEFAULT_CSP_DIRECTIVES, RESTRICTIVE_CSP_DIRECTIVES, buildCSPDirectives, buildCSPMetaTag, validateCSPDomain, sanitizeCSPDomains, } from './csp';
13
13
  export { buildDataInjectionScript, buildCustomDataInjectionScript, createTemplateHelpers, hasSizing, type TemplateHelpers, } from './data-injector';
14
+ export { html, trustedHtml, isTrustedHtml, type TrustedHtml } from './trusted-html';
14
15
  export type { ShellPlaceholderName, InlineShellSource, UrlShellSource, NpmShellSource, CustomShellSource, ShellTemplateValidation, ResolvedShellTemplate, ShellPlaceholderValues, } from './custom-shell-types';
15
16
  export { SHELL_PLACEHOLDER_NAMES, SHELL_PLACEHOLDERS, REQUIRED_PLACEHOLDERS, OPTIONAL_PLACEHOLDERS, isInlineShellSource, isUrlShellSource, isNpmShellSource, } from './custom-shell-types';
16
17
  export { validateShellTemplate } from './custom-shell-validator';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/shell/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,YAAY,EACV,WAAW,EACX,WAAW,EACX,SAAS,EACT,YAAY,EACZ,oBAAoB,EACpB,4BAA4B,GAC7B,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAGvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAGnD,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,0BAA0B,EAC1B,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,OAAO,CAAC;AAGf,OAAO,EACL,wBAAwB,EACxB,8BAA8B,EAC9B,qBAAqB,EACrB,SAAS,EACT,KAAK,eAAe,GACrB,MAAM,iBAAiB,CAAC;AAGzB,YAAY,EACV,oBAAoB,EACpB,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAGjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAG5D,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACxF,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/shell/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,YAAY,EACV,WAAW,EACX,WAAW,EACX,SAAS,EACT,YAAY,EACZ,oBAAoB,EACpB,4BAA4B,GAC7B,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAGvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAGnD,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,0BAA0B,EAC1B,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,OAAO,CAAC;AAGf,OAAO,EACL,wBAAwB,EACxB,8BAA8B,EAC9B,qBAAqB,EACrB,SAAS,EACT,KAAK,eAAe,GACrB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGpF,YAAY,EACV,oBAAoB,EACpB,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAGjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAG5D,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACxF,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC"}