@dudousxd/nestjs-agent-react 0.32.0 → 0.34.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.
Files changed (44) hide show
  1. package/README.md +7 -0
  2. package/dist/{client-C7eu9WMJ.d.cts → client-BdHUuqy-.d.cts} +36 -1
  3. package/dist/{client-C7eu9WMJ.d.ts → client-BdHUuqy-.d.ts} +36 -1
  4. package/dist/{generative-ui-VTZ1EADD.d.cts → generative-ui-CyHY8Lh1.d.cts} +32 -101
  5. package/dist/{generative-ui-VTZ1EADD.d.ts → generative-ui-DdUZPCXX.d.ts} +32 -101
  6. package/dist/genui-json-render.cjs +51 -8
  7. package/dist/genui-json-render.cjs.map +1 -1
  8. package/dist/genui-json-render.d.cts +2 -1
  9. package/dist/genui-json-render.d.ts +2 -1
  10. package/dist/genui-json-render.js +51 -8
  11. package/dist/genui-json-render.js.map +1 -1
  12. package/dist/genui-server-playwright.cjs +199 -0
  13. package/dist/genui-server-playwright.cjs.map +1 -0
  14. package/dist/genui-server-playwright.d.cts +18 -0
  15. package/dist/genui-server-playwright.d.ts +18 -0
  16. package/dist/genui-server-playwright.js +162 -0
  17. package/dist/genui-server-playwright.js.map +1 -0
  18. package/dist/genui-server.cjs +188 -0
  19. package/dist/genui-server.cjs.map +1 -0
  20. package/dist/genui-server.d.cts +36 -0
  21. package/dist/genui-server.d.ts +36 -0
  22. package/dist/genui-server.js +163 -0
  23. package/dist/genui-server.js.map +1 -0
  24. package/dist/genui.cjs +127 -8
  25. package/dist/genui.cjs.map +1 -1
  26. package/dist/genui.d.cts +5 -2
  27. package/dist/genui.d.ts +5 -2
  28. package/dist/genui.js +128 -8
  29. package/dist/genui.js.map +1 -1
  30. package/dist/index.cjs +559 -123
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.cts +35 -10
  33. package/dist/index.d.ts +35 -10
  34. package/dist/index.js +552 -120
  35. package/dist/index.js.map +1 -1
  36. package/dist/media.cjs.map +1 -1
  37. package/dist/media.d.cts +1 -1
  38. package/dist/media.d.ts +1 -1
  39. package/dist/media.js.map +1 -1
  40. package/dist/react-registry-Di4IVrw-.d.cts +25 -0
  41. package/dist/react-registry-z9GFbTm9.d.ts +25 -0
  42. package/dist/types-DZtFsWec.d.cts +99 -0
  43. package/dist/types-DZtFsWec.d.ts +99 -0
  44. package/package.json +35 -5
package/dist/genui.js CHANGED
@@ -39,6 +39,10 @@ function toGenerativeUIItem(part) {
39
39
  return {
40
40
  id,
41
41
  component: source.component,
42
+ ...isRecord(source.componentVersions) && Object.values(source.componentVersions).every(
43
+ (version) => typeof version === "number" && Number.isSafeInteger(version) && version > 0
44
+ ) ? { componentVersions: { ...source.componentVersions } } : {},
45
+ ...typeof source.fallbackText === "string" ? { fallbackText: source.fallbackText } : {},
42
46
  props: isRecord(source.props) ? source.props : {},
43
47
  version: typeof source.version === "number" ? source.version : null,
44
48
  toolCallId: typeof source.toolCallId === "string" ? source.toolCallId : null
@@ -144,20 +148,29 @@ function useValidatedProps(catalog, name, props) {
144
148
  function useGenerativeUIState(part, options, fallbackTree) {
145
149
  const item = useMemo(() => toGenerativeUIItem(part), [part]);
146
150
  const name = item?.component ?? "";
151
+ const definition = options.catalog?.get?.(name);
152
+ const incompatible = item?.fallbackText !== void 0 && item.version !== null && definition !== void 0 && item.version !== (definition.version ?? 1);
147
153
  const resolution = useResolvedComponent(
148
154
  name,
149
155
  item?.version ?? null,
150
- options.registry,
156
+ incompatible ? {} : options.registry,
151
157
  item === null ? void 0 : options.resolveComponent,
152
158
  fallbackTree
153
159
  );
154
160
  const empty = useMemo(() => ({}), []);
155
161
  const validation = useValidatedProps(
156
- item === null || name === GENUI_TREE_COMPONENT ? void 0 : options.catalog,
162
+ item === null || name === GENUI_TREE_COMPONENT || incompatible ? void 0 : options.catalog,
157
163
  name,
158
164
  item?.props ?? empty
159
165
  );
160
166
  if (item === null) return null;
167
+ if (name === GENUI_TREE_COMPONENT && item.fallbackText !== void 0 && (!isRecord(item.props.root) || typeof item.props.root.type !== "string"))
168
+ return {
169
+ status: "problem",
170
+ reason: "invalid",
171
+ item,
172
+ issues: [{ path: ["root"], message: "Invalid UI tree root" }]
173
+ };
161
174
  if (resolution.status === "loading") return { status: "loading", item };
162
175
  if (resolution.status === "unknown") return { status: "problem", reason: "unknown", item };
163
176
  if (resolution.status === "error") {
@@ -175,7 +188,8 @@ import { jsx } from "react/jsx-runtime";
175
188
  var TreeScopeContext = createContext2(null);
176
189
  function renderFallback(fallback, problem) {
177
190
  if (typeof fallback === "function") return fallback(problem);
178
- return fallback ?? null;
191
+ if (fallback !== void 0) return fallback;
192
+ return problem.item.fallbackText !== void 0 ? /* @__PURE__ */ jsx("span", { style: { whiteSpace: "pre-wrap" }, children: problem.item.fallbackText }) : null;
179
193
  }
180
194
  var ItemBoundary = class extends Component {
181
195
  state = { error: void 0, failed: false };
@@ -207,28 +221,42 @@ function nodeItem(node, id) {
207
221
  function TreeNode({ node, id }) {
208
222
  const scope = useContext2(TreeScopeContext);
209
223
  const item = useMemo2(() => nodeItem(node, id), [node, id]);
224
+ const storedVersion = scope?.componentVersions?.[node.type];
225
+ const definition = scope?.options.catalog?.get?.(node.type);
226
+ const incompatible = storedVersion !== void 0 && definition !== void 0 && storedVersion !== (definition.version ?? 1);
210
227
  const resolution = useResolvedComponent(
211
228
  node.type,
212
- null,
213
- scope?.options.registry ?? {},
229
+ storedVersion ?? null,
230
+ incompatible ? {} : scope?.options.registry ?? {},
214
231
  scope?.options.resolveComponent
215
232
  );
216
- const validation = useValidatedProps(scope?.options.catalog, node.type, item.props);
233
+ const validation = useValidatedProps(
234
+ incompatible ? void 0 : scope?.options.catalog,
235
+ node.type,
236
+ item.props
237
+ );
217
238
  if (scope === null) return null;
218
239
  if (resolution.status === "loading" || validation.status === "pending") return scope.loading;
219
240
  if (resolution.status === "unknown") {
241
+ if (scope.fallback === void 0 && scope.fallbackText !== void 0)
242
+ throw new Error("Unknown tree component");
220
243
  return renderFallback(scope.fallback, { reason: "unknown", item });
221
244
  }
222
245
  if (resolution.status === "error") {
246
+ if (scope.fallback === void 0 && scope.fallbackText !== void 0) throw resolution.error;
223
247
  return renderFallback(scope.fallback, { reason: "error", item, error: resolution.error });
224
248
  }
225
249
  if (validation.status === "invalid") {
250
+ if (scope.fallback === void 0 && scope.fallbackText !== void 0)
251
+ throw new Error("Invalid tree component");
226
252
  return renderFallback(scope.fallback, { reason: "invalid", item, issues: validation.issues });
227
253
  }
228
254
  const Renderer = resolution.Component;
229
255
  const children = Array.isArray(node.children) ? node.children : [];
230
256
  return /* @__PURE__ */ jsx(Renderer, { ...validation.props, children: children.length > 0 ? children.map((child, index) => {
231
257
  const childId = `${id}.${index}`;
258
+ if (scope.fallback === void 0 && scope.fallbackText !== void 0)
259
+ return /* @__PURE__ */ jsx(TreeNode, { node: child, id: childId }, childId);
232
260
  return /* @__PURE__ */ jsx(
233
261
  ItemBoundary,
234
262
  {
@@ -250,6 +278,8 @@ function GenerativeUIScope({
250
278
  catalog,
251
279
  resolveComponent,
252
280
  fallback,
281
+ fallbackText,
282
+ componentVersions,
253
283
  loading = null,
254
284
  onError,
255
285
  children
@@ -262,10 +292,21 @@ function GenerativeUIScope({
262
292
  ...resolveComponent !== void 0 ? { resolveComponent } : {}
263
293
  },
264
294
  fallback,
295
+ ...componentVersions !== void 0 ? { componentVersions } : {},
296
+ ...fallbackText !== void 0 ? { fallbackText } : {},
265
297
  loading,
266
298
  onError
267
299
  }),
268
- [registry, catalog, resolveComponent, fallback, loading, onError]
300
+ [
301
+ registry,
302
+ catalog,
303
+ resolveComponent,
304
+ fallback,
305
+ fallbackText,
306
+ componentVersions,
307
+ loading,
308
+ onError
309
+ ]
269
310
  );
270
311
  return /* @__PURE__ */ jsx(TreeScopeContext.Provider, { value: scope, children });
271
312
  }
@@ -332,7 +373,7 @@ function GenerativeUI({
332
373
  onError: ownOnError
333
374
  }) {
334
375
  const provided = useContext2(GenuiContext);
335
- const fallback = ownFallback ?? provided?.fallback;
376
+ const fallback = ownFallback !== void 0 ? ownFallback : provided?.fallback;
336
377
  const loading = ownLoading ?? provided?.loading ?? null;
337
378
  const onError = ownOnError ?? provided?.onError;
338
379
  const options = useMergedOptions({
@@ -357,6 +398,8 @@ function GenerativeUI({
357
398
  GenerativeUIScope,
358
399
  {
359
400
  ...options,
401
+ ...state.item.componentVersions !== void 0 ? { componentVersions: state.item.componentVersions } : {},
402
+ ...state.item.fallbackText !== void 0 ? { fallbackText: state.item.fallbackText } : {},
360
403
  fallback,
361
404
  loading,
362
405
  ...onError !== void 0 ? { onError } : {},
@@ -364,12 +407,89 @@ function GenerativeUI({
364
407
  }
365
408
  );
366
409
  }
410
+
411
+ // src/genui/react-registry.ts
412
+ import {
413
+ createComponentRegistry
414
+ } from "@dudousxd/nestjs-agent-core/genui";
415
+ import { createElement } from "react";
416
+ function createReactComponentRegistry(options) {
417
+ const registry = createComponentRegistry(options);
418
+ const components = /* @__PURE__ */ Object.create(null);
419
+ const texts = /* @__PURE__ */ new Map();
420
+ const paginators = /* @__PURE__ */ new Map();
421
+ const adapter = {
422
+ get catalog() {
423
+ return registry.catalog;
424
+ },
425
+ get manifest() {
426
+ return registry.manifest;
427
+ },
428
+ get components() {
429
+ return { ...components };
430
+ },
431
+ prepare: (presentation) => registry.prepare({ ...presentation, props: presentation.props }),
432
+ render: (presentation, channel) => registry.render(
433
+ { ...presentation, props: presentation.props },
434
+ channel
435
+ ),
436
+ register(definition, renderers) {
437
+ const ReactComponent = renderers.react;
438
+ registry.register(definition, {
439
+ ...ReactComponent ? { react: (props) => createElement(ReactComponent, props) } : {},
440
+ ...renderers.text ? { text: renderers.text } : {}
441
+ });
442
+ if (renderers.react) components[definition.name] = renderers.react;
443
+ if (renderers.text) {
444
+ const text = renderers.text;
445
+ texts.set(definition.name, (props) => text(props));
446
+ }
447
+ if (renderers.paginate) {
448
+ const paginate = renderers.paginate;
449
+ paginators.set(
450
+ definition.name,
451
+ async (props, size) => await paginate(props, size)
452
+ );
453
+ }
454
+ return adapter;
455
+ },
456
+ async renderPages(presentation, size) {
457
+ const pages = await adapter.paginate(presentation, size);
458
+ return Promise.all(
459
+ pages.map(async (page) => {
460
+ const ReactComponent = components[page.component];
461
+ if (ReactComponent) return createElement(ReactComponent, page.props);
462
+ return texts.get(page.component)?.(page.props) ?? page.fallbackText;
463
+ })
464
+ );
465
+ },
466
+ async paginate(presentation, size) {
467
+ if (!Number.isInteger(size) || size < 1 || size > 500)
468
+ throw new RangeError("genui: rowsPerPage must be 1\u2013500");
469
+ const prepared = await registry.prepare({
470
+ ...presentation,
471
+ props: presentation.props
472
+ });
473
+ const custom = paginators.get(prepared.component);
474
+ const rows = prepared.props.rows;
475
+ const pages = custom ? await custom(prepared.props, size) : prepared.component === "DataTable" && Array.isArray(rows) && rows.length > size ? Array.from({ length: Math.ceil(rows.length / size) }, (_, index) => ({
476
+ ...prepared.props,
477
+ rows: rows.slice(index * size, (index + 1) * size)
478
+ })) : [prepared.props];
479
+ if (!pages.length || pages.length > 100)
480
+ throw new RangeError("genui: capture requires 1\u2013100 pages");
481
+ return Promise.all(pages.map((props) => registry.prepare({ ...prepared, props })));
482
+ }
483
+ };
484
+ return adapter;
485
+ }
367
486
  export {
368
487
  GENUI_TREE_COMPONENT,
369
488
  GenerativeUI,
370
489
  GenerativeUIScope,
371
490
  GenuiProvider,
372
491
  GenuiTree,
492
+ createReactComponentRegistry,
373
493
  toGenerativeUIItem,
374
494
  useGenerativeUI,
375
495
  useGenuiProvider
package/dist/genui.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/genui/generative-ui.tsx","../src/components/ambient-ui.ts","../src/genui/use-generative-ui.ts","../src/genui/types.ts"],"sourcesContent":["import {\n Component,\n type Context,\n type ErrorInfo,\n type ReactNode,\n createContext,\n useCallback,\n useContext,\n useMemo,\n} from 'react';\nimport { AmbientRenderUiContext, sharedContext } from '../components/ambient-ui.js';\nimport type { TranscriptUiBlock } from '../transcript/model.js';\nimport type {\n GenerativeUIElement,\n GenerativeUIItem,\n GenerativeUIOptions,\n GenerativeUIProblem,\n GenerativeUIState,\n GenuiRegistry,\n GenuiRenderer,\n} from './types.js';\nimport {\n useGenerativeUIState,\n useResolvedComponent,\n useValidatedProps,\n} from './use-generative-ui.js';\n\n/** What to draw instead of a component that did not render. Default: nothing. */\nexport type GenerativeUIFallback = ReactNode | ((problem: GenerativeUIProblem) => ReactNode);\n\ninterface TreeScope {\n options: GenerativeUIOptions;\n fallback: GenerativeUIFallback | undefined;\n loading: ReactNode;\n onError: ((error: unknown, item: GenerativeUIItem) => void) | undefined;\n}\n\nconst TreeScopeContext = createContext<TreeScope | null>(null);\n\nfunction renderFallback(fallback: GenerativeUIFallback | undefined, problem: GenerativeUIProblem) {\n if (typeof fallback === 'function') return fallback(problem);\n return fallback ?? null;\n}\n\ninterface BoundaryProps {\n item: GenerativeUIItem;\n fallback: GenerativeUIFallback | undefined;\n onError: ((error: unknown, item: GenerativeUIItem) => void) | undefined;\n children: ReactNode;\n}\n\n/** One failing renderer takes down its own item, never the message around it. */\nclass ItemBoundary extends Component<BoundaryProps, { error: unknown; failed: boolean }> {\n override state = { error: undefined as unknown, failed: false };\n\n static getDerivedStateFromError(error: unknown) {\n return { error, failed: true };\n }\n\n override componentDidCatch(error: unknown, _info: ErrorInfo) {\n this.props.onError?.(error, this.props.item);\n }\n\n override componentDidUpdate(previous: BoundaryProps) {\n // New props for the same item (a streamed update) get a fresh chance to render.\n if (this.state.failed && previous.item !== this.props.item) {\n this.setState({ error: undefined, failed: false });\n }\n }\n\n override render() {\n if (this.state.failed) {\n return renderFallback(this.props.fallback, {\n reason: 'error',\n item: this.props.item,\n error: this.state.error,\n });\n }\n return this.props.children;\n }\n}\n\nfunction nodeItem(node: GenerativeUIElement, id: string): GenerativeUIItem {\n return { id, component: node.type, props: node.props ?? {}, version: null, toolCallId: null };\n}\n\n/** One tree node: resolved and validated like a top-level item, children rendered as its `children`. */\nfunction TreeNode({ node, id }: { node: GenerativeUIElement; id: string }) {\n const scope = useContext(TreeScopeContext);\n const item = useMemo(() => nodeItem(node, id), [node, id]);\n const resolution = useResolvedComponent(\n node.type,\n null,\n scope?.options.registry ?? {},\n scope?.options.resolveComponent,\n );\n const validation = useValidatedProps(scope?.options.catalog, node.type, item.props);\n if (scope === null) return null;\n if (resolution.status === 'loading' || validation.status === 'pending') return scope.loading;\n if (resolution.status === 'unknown') {\n return renderFallback(scope.fallback, { reason: 'unknown', item });\n }\n if (resolution.status === 'error') {\n return renderFallback(scope.fallback, { reason: 'error', item, error: resolution.error });\n }\n if (validation.status === 'invalid') {\n return renderFallback(scope.fallback, { reason: 'invalid', item, issues: validation.issues });\n }\n const Renderer = resolution.Component;\n const children = Array.isArray(node.children) ? node.children : [];\n return (\n <Renderer {...validation.props}>\n {children.length > 0\n ? children.map((child, index) => {\n const childId = `${id}.${index}`;\n return (\n <ItemBoundary\n key={childId}\n item={nodeItem(child, childId)}\n fallback={scope.fallback}\n onError={scope.onError}\n >\n <TreeNode node={child} id={childId} />\n </ItemBoundary>\n );\n })\n : undefined}\n </Renderer>\n );\n}\n\n/**\n * Renders a `genui:tree` frame's `{ root }` node by node through the same registry, catalog and\n * resolver as top-level components. Used automatically for tree frames unless a `treeRenderer`\n * (e.g. the json-render one) or a registry entry for `genui:tree` takes over.\n */\nexport function GenuiTree({ root }: { root?: GenerativeUIElement }) {\n if (root === undefined || root === null || typeof root.type !== 'string') return null;\n return <TreeNode node={root} id=\"root\" />;\n}\n\nexport interface GenerativeUIScopeProps extends GenerativeUIOptions {\n fallback?: GenerativeUIFallback;\n loading?: ReactNode;\n onError?: (error: unknown, item: GenerativeUIItem) => void;\n children?: ReactNode;\n}\n\n/**\n * The registry, catalog and fallbacks tree nodes render with. `<GenerativeUI>` provides it; wrap\n * your own chrome in it when you draw `useGenerativeUI`'s `Component` yourself and it may be a tree.\n */\nexport function GenerativeUIScope({\n registry,\n catalog,\n resolveComponent,\n fallback,\n loading = null,\n onError,\n children,\n}: GenerativeUIScopeProps) {\n const scope = useMemo<TreeScope>(\n () => ({\n options: {\n registry,\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n },\n fallback,\n loading,\n onError,\n }),\n [registry, catalog, resolveComponent, fallback, loading, onError],\n );\n return <TreeScopeContext.Provider value={scope}>{children}</TreeScopeContext.Provider>;\n}\n\n/** What `<GenuiProvider>` hands every `<GenerativeUI>` / `useGenerativeUI` below it. */\nexport interface GenuiProviderValue extends Partial<GenerativeUIOptions> {\n fallback?: GenerativeUIFallback;\n loading?: ReactNode;\n onError?: (error: unknown, item: GenerativeUIItem) => void;\n}\n\n// Shared by key: `/genui` and `/genui/json-render` are separate bundles, and a provider from one\n// must reach a `<GenerativeUI>` from the other.\nconst GenuiContext: Context<GenuiProviderValue | null> = sharedContext<GenuiProviderValue>(\n '@dudousxd/nestjs-agent-react:genui-provider',\n);\n\n/** The enclosing `<GenuiProvider>`'s settings, or `null` outside one. */\nexport function useGenuiProvider(): GenuiProviderValue | null {\n return useContext(GenuiContext);\n}\n\nexport interface GenuiProviderProps extends GenuiProviderValue {\n children?: ReactNode;\n}\n\n/**\n * Set generative UI up once, at the app root: the registry of your renderers, the catalog to\n * validate against, a resolver for components the registry lacks, and what to draw when one does\n * not render. Every `<GenerativeUI>` below reads it (its own props still win), and `MessageItem` /\n * `MessageList` draw pushed components with it — no `renderUi` per message.\n *\n * ```tsx\n * <GenuiProvider registry={registry} catalog={catalog} fallback={({ item }) => <Unknown name={item.component} />}>\n * <App />\n * </GenuiProvider>\n * ```\n */\nexport function GenuiProvider({\n registry,\n catalog,\n resolveComponent,\n treeRenderer,\n fallback,\n loading,\n onError,\n children,\n}: GenuiProviderProps) {\n const value = useMemo<GenuiProviderValue>(\n () => ({\n ...(registry !== undefined ? { registry } : {}),\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n ...(treeRenderer !== undefined ? { treeRenderer } : {}),\n ...(fallback !== undefined ? { fallback } : {}),\n ...(loading !== undefined ? { loading } : {}),\n ...(onError !== undefined ? { onError } : {}),\n }),\n [registry, catalog, resolveComponent, treeRenderer, fallback, loading, onError],\n );\n const renderUi = useCallback((block: TranscriptUiBlock) => <GenerativeUI part={block} />, []);\n return (\n <GenuiContext.Provider value={value}>\n <AmbientRenderUiContext.Provider value={renderUi}>{children}</AmbientRenderUiContext.Provider>\n </GenuiContext.Provider>\n );\n}\n\nconst NO_REGISTRY: GenuiRegistry = {};\n\n/** Provider settings overlaid with explicit ones (explicit wins), memoized on their parts. */\nfunction useMergedOptions(own: Partial<GenerativeUIOptions>): GenerativeUIOptions {\n const provided = useContext(GenuiContext);\n const registry = own.registry ?? provided?.registry ?? NO_REGISTRY;\n const catalog = own.catalog ?? provided?.catalog;\n const resolveComponent = own.resolveComponent ?? provided?.resolveComponent;\n const treeRenderer = own.treeRenderer ?? provided?.treeRenderer;\n return useMemo(\n () => ({\n registry,\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n ...(treeRenderer !== undefined ? { treeRenderer } : {}),\n }),\n [registry, catalog, resolveComponent, treeRenderer],\n );\n}\n\n/**\n * The headless half of {@link GenerativeUI}: what to draw for one pushed component, or `null` when\n * `part` is not one. Options default to the enclosing `<GenuiProvider>`'s.\n */\nexport function useGenerativeUI(\n part: unknown,\n options: Partial<GenerativeUIOptions> = {},\n): GenerativeUIState | null {\n const merged = useMergedOptions(options);\n return useGenerativeUIState(part, merged, merged.treeRenderer ?? (GenuiTree as GenuiRenderer));\n}\n\nexport interface GenerativeUIProps extends Partial<GenerativeUIOptions> {\n /** A transcript `ui` block, a `data-ui` message part, or a stored `{ id, component, props, version? }`. */\n part: TranscriptUiBlock | GenerativeUIItem | unknown;\n /** Drawn for an unknown component, invalid props, or a renderer that threw. Default: the provider's, else nothing. */\n fallback?: GenerativeUIFallback;\n /** Drawn while a resolver or an async validation is pending. Default: the provider's, else nothing. */\n loading?: ReactNode;\n /** A renderer threw (the item shows `fallback`). */\n onError?: (error: unknown, item: GenerativeUIItem) => void;\n}\n\n/**\n * Draws one server-pushed component with the app's own renderer. Headless: it adds no element and\n * no style of its own — only what the registry's component renders (and whatever `fallback` /\n * `loading` you pass). Everything but `part` defaults to the enclosing `<GenuiProvider>`.\n *\n * ```tsx\n * <GenerativeUI part={block} />\n * ```\n */\nexport function GenerativeUI({\n part,\n registry,\n catalog,\n resolveComponent,\n treeRenderer,\n fallback: ownFallback,\n loading: ownLoading,\n onError: ownOnError,\n}: GenerativeUIProps) {\n const provided = useContext(GenuiContext);\n const fallback = ownFallback ?? provided?.fallback;\n const loading = ownLoading ?? provided?.loading ?? null;\n const onError = ownOnError ?? provided?.onError;\n const options = useMergedOptions({\n ...(registry !== undefined ? { registry } : {}),\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n ...(treeRenderer !== undefined ? { treeRenderer } : {}),\n });\n const state = useGenerativeUIState(\n part,\n options,\n options.treeRenderer ?? (GenuiTree as GenuiRenderer),\n );\n if (state === null) return null;\n if (state.status === 'loading') return loading;\n if (state.status === 'problem') {\n const { status: _status, ...problem } = state;\n return renderFallback(fallback, problem);\n }\n const Renderer = state.Component;\n return (\n <GenerativeUIScope\n {...options}\n fallback={fallback}\n loading={loading}\n {...(onError !== undefined ? { onError } : {})}\n >\n <ItemBoundary item={state.item} fallback={fallback} onError={onError}>\n <Renderer {...state.props} />\n </ItemBoundary>\n </GenerativeUIScope>\n );\n}\n","import { type Context, type ReactNode, createContext, useContext } from 'react';\nimport type { TranscriptUiBlock } from '../transcript/model.js';\n\n/** Draws a server-pushed component block. */\nexport type AmbientRenderUi = (block: TranscriptUiBlock) => ReactNode;\n\n/**\n * A context stored on `globalThis` under a registered symbol. Each entry point (`.`, `/genui`,\n * `/genui/json-render`) is its own bundle with its own copy of every module, so a context one entry\n * provides and another reads has to be found by key, not by module identity.\n */\nexport function sharedContext<T>(key: string): Context<T | null> {\n const symbol = Symbol.for(key);\n const holder = globalThis as Record<symbol, Context<T | null> | undefined>;\n const existing = holder[symbol];\n if (existing !== undefined) return existing;\n const created = createContext<T | null>(null);\n holder[symbol] = created;\n return created;\n}\n\n/**\n * How pushed components are drawn when no `renderUi` is passed — set by `<GenuiProvider>` (the\n * `/genui` subpath) and read by `MessageItem`.\n */\nexport const AmbientRenderUiContext: Context<AmbientRenderUi | null> =\n sharedContext<AmbientRenderUi>('@dudousxd/nestjs-agent-react:ambient-render-ui');\n\n/**\n * The renderer `<GenuiProvider>` installed for pushed components, or `null` outside one. For a\n * custom transcript built on `useTranscriptItem`: draw a `ui` block with it and you get what\n * `MessageItem` draws.\n */\nexport function useAmbientRenderUi(): AmbientRenderUi | null {\n return useContext(AmbientRenderUiContext);\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport {\n GENUI_TREE_COMPONENT,\n type GenerativeUIItem,\n type GenerativeUIOptions,\n type GenerativeUIState,\n type GenuiCatalogLike,\n type GenuiIssueLike,\n type GenuiRegistry,\n type GenuiRenderer,\n type ResolveComponent,\n} from './types.js';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Normalize whatever carries a pushed component: a transcript `ui` block, a `data-ui` message part\n * (`{ type: 'data-ui', id, data }`), a stored `{ id, component, props, version? }` entry. `null` for\n * anything else.\n */\nexport function toGenerativeUIItem(part: unknown): GenerativeUIItem | null {\n if (!isRecord(part)) return null;\n const source = part.type === 'data-ui' && isRecord(part.data) ? part.data : part;\n if (typeof source.component !== 'string') return null;\n const id =\n typeof source.id === 'string' ? source.id : typeof part.id === 'string' ? part.id : null;\n if (id === null) return null;\n return {\n id,\n component: source.component,\n props: isRecord(source.props) ? source.props : {},\n version: typeof source.version === 'number' ? source.version : null,\n toolCallId: typeof source.toolCallId === 'string' ? source.toolCallId : null,\n };\n}\n\ntype Resolution =\n | { status: 'ready'; Component: GenuiRenderer }\n | { status: 'loading' }\n | { status: 'unknown' }\n | { status: 'error'; error: unknown };\n\ninterface CacheEntry {\n resolution: Resolution;\n settled: Promise<void> | null;\n}\n\nconst resolverCaches = new WeakMap<ResolveComponent, Map<string, CacheEntry>>();\n\nfunction resolveCached(\n resolve: ResolveComponent,\n name: string,\n version: number | null,\n): CacheEntry {\n let cache = resolverCaches.get(resolve);\n if (cache === undefined) {\n cache = new Map();\n resolverCaches.set(resolve, cache);\n }\n const key = `${name}@${version ?? ''}`;\n const hit = cache.get(key);\n if (hit !== undefined) return hit;\n let entry: CacheEntry;\n try {\n const result = resolve(name, version);\n if (result instanceof Promise) {\n entry = { resolution: { status: 'loading' }, settled: null };\n entry.settled = result.then(\n (Component) => {\n entry.resolution = Component ? { status: 'ready', Component } : { status: 'unknown' };\n },\n (error: unknown) => {\n entry.resolution = { status: 'error', error };\n },\n );\n } else {\n entry = {\n resolution: result ? { status: 'ready', Component: result } : { status: 'unknown' },\n settled: null,\n };\n }\n } catch (error) {\n entry = { resolution: { status: 'error', error }, settled: null };\n }\n cache.set(key, entry);\n return entry;\n}\n\n/**\n * Which renderer draws `name`: the registry first, then `resolveComponent` (cached; async results\n * re-render the caller when they land). `fallbackTree` answers the tree component when the\n * registry does not override it.\n */\nexport function useResolvedComponent(\n name: string,\n version: number | null,\n registry: GenuiRegistry,\n resolve: ResolveComponent | undefined,\n fallbackTree?: GenuiRenderer,\n): Resolution {\n const [, setTick] = useState(0);\n const own = registry[name];\n const entry =\n own !== undefined || resolve === undefined ? null : resolveCached(resolve, name, version);\n const pending = entry?.resolution.status === 'loading' ? entry.settled : null;\n useEffect(() => {\n if (pending === null) return;\n let live = true;\n void pending.then(() => {\n if (live) setTick((tick) => tick + 1);\n });\n return () => {\n live = false;\n };\n }, [pending]);\n if (own !== undefined) return { status: 'ready', Component: own };\n if (entry !== null && entry.resolution.status !== 'unknown') return entry.resolution;\n if (name === GENUI_TREE_COMPONENT && fallbackTree !== undefined) {\n return { status: 'ready', Component: fallbackTree };\n }\n return { status: 'unknown' };\n}\n\ntype Validation =\n | { status: 'ok'; props: Record<string, unknown> }\n | { status: 'pending' }\n | { status: 'invalid'; issues: GenuiIssueLike[] };\n\n/**\n * Props checked against the catalog: synchronously when the catalog can (`validateSync`), else\n * after the async check settles. A component the catalog does not know passes through unchecked.\n */\nexport function useValidatedProps(\n catalog: GenuiCatalogLike | undefined,\n name: string,\n props: Record<string, unknown>,\n): Validation {\n const checked = catalog?.has(name) === true;\n const immediate = useMemo<Validation | null>(() => {\n if (!checked || catalog === undefined) return { status: 'ok', props };\n const result = catalog.validateSync?.(name, props);\n if (result === undefined) return null;\n return result.ok\n ? { status: 'ok', props: result.value }\n : { status: 'invalid', issues: result.issues };\n }, [checked, catalog, name, props]);\n const [late, setLate] = useState<{ props: Record<string, unknown>; result: Validation } | null>(\n null,\n );\n useEffect(() => {\n if (immediate !== null || catalog === undefined) return;\n let live = true;\n catalog.validate(name, props).then(\n (result) => {\n if (!live) return;\n setLate({\n props,\n result: result.ok\n ? { status: 'ok', props: result.value }\n : { status: 'invalid', issues: result.issues },\n });\n },\n (error: unknown) => {\n if (!live) return;\n setLate({\n props,\n result: {\n status: 'invalid',\n issues: [{ path: [], message: error instanceof Error ? error.message : String(error) }],\n },\n });\n },\n );\n return () => {\n live = false;\n };\n }, [immediate, catalog, name, props]);\n if (immediate !== null) return immediate;\n return late !== null && late.props === props ? late.result : { status: 'pending' };\n}\n\n/** {@link import('./generative-ui.js').useGenerativeUI}, with the tree renderer handed in (avoids an import cycle). */\nexport function useGenerativeUIState(\n part: unknown,\n options: GenerativeUIOptions,\n fallbackTree: GenuiRenderer | undefined,\n): GenerativeUIState | null {\n const item = useMemo(() => toGenerativeUIItem(part), [part]);\n const name = item?.component ?? '';\n const resolution = useResolvedComponent(\n name,\n item?.version ?? null,\n options.registry,\n item === null ? undefined : options.resolveComponent,\n fallbackTree,\n );\n const empty = useMemo<Record<string, unknown>>(() => ({}), []);\n // A tree is validated node by node as it renders, not as one component.\n const validation = useValidatedProps(\n item === null || name === GENUI_TREE_COMPONENT ? undefined : options.catalog,\n name,\n item?.props ?? empty,\n );\n if (item === null) return null;\n if (resolution.status === 'loading') return { status: 'loading', item };\n if (resolution.status === 'unknown') return { status: 'problem', reason: 'unknown', item };\n if (resolution.status === 'error') {\n return { status: 'problem', reason: 'error', item, error: resolution.error };\n }\n if (validation.status === 'pending') return { status: 'loading', item };\n if (validation.status === 'invalid') {\n return { status: 'problem', reason: 'invalid', item, issues: validation.issues };\n }\n return { status: 'ready', item, Component: resolution.Component, props: validation.props };\n}\n","import type { ComponentType, ReactNode } from 'react';\n\n/** The `ui` frame component a composed tree is pushed under (`GENUI_TREE_COMPONENT` of `@dudousxd/nestjs-agent-core/genui`). */\nexport const GENUI_TREE_COMPONENT = 'genui:tree';\n\n/** One pushed component, normalized from whatever carried it (a transcript block, a `data-ui` part, a stored entry). */\nexport interface GenerativeUIItem {\n id: string;\n component: string;\n props: Record<string, unknown>;\n version: number | null;\n toolCallId: string | null;\n}\n\n/** A node of a composed tree (`genui:tree` frames): `{ type, props, children? }`. */\nexport interface GenerativeUIElement {\n type: string;\n props: Record<string, unknown>;\n children?: GenerativeUIElement[];\n}\n\n/**\n * An app's renderer for one component: it receives the component's props spread, plus `children`\n * when it is a layout node in a tree. Any React component — the library never styles anything.\n */\nexport type GenuiRenderer<P = any> = ComponentType<P & { children?: ReactNode }>;\n\n/** Component name → the app's renderer. */\nexport type GenuiRegistry = Record<string, GenuiRenderer>;\n\n/**\n * Resolve a component the registry does not have — typically a tenant's own component, fetched for\n * the exact `version` a message was rendered with. Return `null`/`undefined` for \"no such\n * component\". May be async; results are cached per resolver, name and version.\n */\nexport type ResolveComponent = (\n name: string,\n version: number | null,\n) => GenuiRenderer | null | undefined | Promise<GenuiRenderer | null | undefined>;\n\nexport interface GenuiIssueLike {\n path: (string | number)[];\n message: string;\n}\n\ntype ValidationLike =\n | { ok: true; value: Record<string, unknown> }\n | { ok: false; issues: GenuiIssueLike[] };\n\n/**\n * What the renderer needs from a catalog to validate props before drawing them. A `Catalog` from\n * `@dudousxd/nestjs-agent-core/genui` satisfies it; declared structurally so any catalog-shaped\n * object does too.\n */\nexport interface GenuiCatalogLike {\n has(name: string): boolean;\n validate(name: string, props: unknown): Promise<ValidationLike>;\n validateSync?(name: string, props: unknown): ValidationLike | undefined;\n}\n\nexport interface GenerativeUIOptions {\n registry: GenuiRegistry;\n /** Validate props against it before rendering. Components the catalog does not know render unvalidated. */\n catalog?: GenuiCatalogLike;\n resolveComponent?: ResolveComponent;\n /**\n * Draws a composed tree frame (`genui:tree`) whole — e.g. through json-render (see the\n * `/genui/json-render` subpath's `GenuiProvider`). Omitted → trees render node by node through\n * `registry`.\n */\n treeRenderer?: GenuiRenderer<{ root?: GenerativeUIElement }>;\n}\n\n/** Why an item did not render. */\nexport type GenerativeUIProblem =\n | { reason: 'unknown'; item: GenerativeUIItem }\n | { reason: 'invalid'; item: GenerativeUIItem; issues: GenuiIssueLike[] }\n | { reason: 'error'; item: GenerativeUIItem; error: unknown };\n\nexport type GenerativeUIState =\n | {\n status: 'ready';\n item: GenerativeUIItem;\n Component: GenuiRenderer;\n props: Record<string, unknown>;\n }\n | { status: 'loading'; item: GenerativeUIItem }\n | ({ status: 'problem' } & GenerativeUIProblem);\n"],"mappings":"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","names":["createContext","useContext","useMemo","Component","createContext","useContext","useMemo"]}
1
+ {"version":3,"sources":["../src/genui/generative-ui.tsx","../src/components/ambient-ui.ts","../src/genui/use-generative-ui.ts","../src/genui/types.ts","../src/genui/react-registry.ts"],"sourcesContent":["import {\n Component,\n type Context,\n type ErrorInfo,\n type ReactNode,\n createContext,\n useCallback,\n useContext,\n useMemo,\n} from 'react';\nimport { AmbientRenderUiContext, sharedContext } from '../components/ambient-ui.js';\nimport type { TranscriptUiBlock } from '../transcript/model.js';\nimport type {\n GenerativeUIElement,\n GenerativeUIItem,\n GenerativeUIOptions,\n GenerativeUIProblem,\n GenerativeUIState,\n GenuiRegistry,\n GenuiRenderer,\n} from './types.js';\nimport {\n useGenerativeUIState,\n useResolvedComponent,\n useValidatedProps,\n} from './use-generative-ui.js';\n\n/** What to draw instead of a component that did not render. Default: nothing. */\nexport type GenerativeUIFallback = ReactNode | ((problem: GenerativeUIProblem) => ReactNode);\n\ninterface TreeScope {\n fallbackText?: string;\n componentVersions?: Record<string, number>;\n options: GenerativeUIOptions;\n fallback: GenerativeUIFallback | undefined;\n loading: ReactNode;\n onError: ((error: unknown, item: GenerativeUIItem) => void) | undefined;\n}\n\nconst TreeScopeContext = createContext<TreeScope | null>(null);\n\nfunction renderFallback(fallback: GenerativeUIFallback | undefined, problem: GenerativeUIProblem) {\n if (typeof fallback === 'function') return fallback(problem);\n if (fallback !== undefined) return fallback;\n return problem.item.fallbackText !== undefined ? (\n <span style={{ whiteSpace: 'pre-wrap' }}>{problem.item.fallbackText}</span>\n ) : null;\n}\n\ninterface BoundaryProps {\n item: GenerativeUIItem;\n fallback: GenerativeUIFallback | undefined;\n onError: ((error: unknown, item: GenerativeUIItem) => void) | undefined;\n children: ReactNode;\n}\n\n/** One failing renderer takes down its own item, never the message around it. */\nclass ItemBoundary extends Component<BoundaryProps, { error: unknown; failed: boolean }> {\n override state = { error: undefined as unknown, failed: false };\n\n static getDerivedStateFromError(error: unknown) {\n return { error, failed: true };\n }\n\n override componentDidCatch(error: unknown, _info: ErrorInfo) {\n this.props.onError?.(error, this.props.item);\n }\n\n override componentDidUpdate(previous: BoundaryProps) {\n // New props for the same item (a streamed update) get a fresh chance to render.\n if (this.state.failed && previous.item !== this.props.item) {\n this.setState({ error: undefined, failed: false });\n }\n }\n\n override render() {\n if (this.state.failed) {\n return renderFallback(this.props.fallback, {\n reason: 'error',\n item: this.props.item,\n error: this.state.error,\n });\n }\n return this.props.children;\n }\n}\n\nfunction nodeItem(node: GenerativeUIElement, id: string): GenerativeUIItem {\n return { id, component: node.type, props: node.props ?? {}, version: null, toolCallId: null };\n}\n\n/** One tree node: resolved and validated like a top-level item, children rendered as its `children`. */\nfunction TreeNode({ node, id }: { node: GenerativeUIElement; id: string }) {\n const scope = useContext(TreeScopeContext);\n const item = useMemo(() => nodeItem(node, id), [node, id]);\n const storedVersion = scope?.componentVersions?.[node.type];\n const definition = scope?.options.catalog?.get?.(node.type);\n const incompatible =\n storedVersion !== undefined &&\n definition !== undefined &&\n storedVersion !== (definition.version ?? 1);\n const resolution = useResolvedComponent(\n node.type,\n storedVersion ?? null,\n incompatible ? {} : (scope?.options.registry ?? {}),\n scope?.options.resolveComponent,\n );\n const validation = useValidatedProps(\n incompatible ? undefined : scope?.options.catalog,\n node.type,\n item.props,\n );\n if (scope === null) return null;\n if (resolution.status === 'loading' || validation.status === 'pending') return scope.loading;\n if (resolution.status === 'unknown') {\n if (scope.fallback === undefined && scope.fallbackText !== undefined)\n throw new Error('Unknown tree component');\n return renderFallback(scope.fallback, { reason: 'unknown', item });\n }\n if (resolution.status === 'error') {\n if (scope.fallback === undefined && scope.fallbackText !== undefined) throw resolution.error;\n return renderFallback(scope.fallback, { reason: 'error', item, error: resolution.error });\n }\n if (validation.status === 'invalid') {\n if (scope.fallback === undefined && scope.fallbackText !== undefined)\n throw new Error('Invalid tree component');\n return renderFallback(scope.fallback, { reason: 'invalid', item, issues: validation.issues });\n }\n const Renderer = resolution.Component;\n const children = Array.isArray(node.children) ? node.children : [];\n return (\n <Renderer {...validation.props}>\n {children.length > 0\n ? children.map((child, index) => {\n const childId = `${id}.${index}`;\n if (scope.fallback === undefined && scope.fallbackText !== undefined)\n return <TreeNode key={childId} node={child} id={childId} />;\n return (\n <ItemBoundary\n key={childId}\n item={nodeItem(child, childId)}\n fallback={scope.fallback}\n onError={scope.onError}\n >\n <TreeNode node={child} id={childId} />\n </ItemBoundary>\n );\n })\n : undefined}\n </Renderer>\n );\n}\n\n/**\n * Renders a `genui:tree` frame's `{ root }` node by node through the same registry, catalog and\n * resolver as top-level components. Used automatically for tree frames unless a `treeRenderer`\n * (e.g. the json-render one) or a registry entry for `genui:tree` takes over.\n */\nexport function GenuiTree({ root }: { root?: GenerativeUIElement }) {\n if (root === undefined || root === null || typeof root.type !== 'string') return null;\n return <TreeNode node={root} id=\"root\" />;\n}\n\nexport interface GenerativeUIScopeProps extends GenerativeUIOptions {\n fallbackText?: string;\n componentVersions?: Record<string, number>;\n fallback?: GenerativeUIFallback;\n loading?: ReactNode;\n onError?: (error: unknown, item: GenerativeUIItem) => void;\n children?: ReactNode;\n}\n\n/**\n * The registry, catalog and fallbacks tree nodes render with. `<GenerativeUI>` provides it; wrap\n * your own chrome in it when you draw `useGenerativeUI`'s `Component` yourself and it may be a tree.\n */\nexport function GenerativeUIScope({\n registry,\n catalog,\n resolveComponent,\n fallback,\n fallbackText,\n componentVersions,\n loading = null,\n onError,\n children,\n}: GenerativeUIScopeProps) {\n const scope = useMemo<TreeScope>(\n () => ({\n options: {\n registry,\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n },\n fallback,\n ...(componentVersions !== undefined ? { componentVersions } : {}),\n ...(fallbackText !== undefined ? { fallbackText } : {}),\n loading,\n onError,\n }),\n [\n registry,\n catalog,\n resolveComponent,\n fallback,\n fallbackText,\n componentVersions,\n loading,\n onError,\n ],\n );\n return <TreeScopeContext.Provider value={scope}>{children}</TreeScopeContext.Provider>;\n}\n\n/** What `<GenuiProvider>` hands every `<GenerativeUI>` / `useGenerativeUI` below it. */\nexport interface GenuiProviderValue extends Partial<GenerativeUIOptions> {\n fallback?: GenerativeUIFallback;\n loading?: ReactNode;\n onError?: (error: unknown, item: GenerativeUIItem) => void;\n}\n\n// Shared by key: `/genui` and `/genui/json-render` are separate bundles, and a provider from one\n// must reach a `<GenerativeUI>` from the other.\nconst GenuiContext: Context<GenuiProviderValue | null> = sharedContext<GenuiProviderValue>(\n '@dudousxd/nestjs-agent-react:genui-provider',\n);\n\n/** The enclosing `<GenuiProvider>`'s settings, or `null` outside one. */\nexport function useGenuiProvider(): GenuiProviderValue | null {\n return useContext(GenuiContext);\n}\n\nexport interface GenuiProviderProps extends GenuiProviderValue {\n children?: ReactNode;\n}\n\n/**\n * Set generative UI up once, at the app root: the registry of your renderers, the catalog to\n * validate against, a resolver for components the registry lacks, and what to draw when one does\n * not render. Every `<GenerativeUI>` below reads it (its own props still win), and `MessageItem` /\n * `MessageList` draw pushed components with it — no `renderUi` per message.\n *\n * ```tsx\n * <GenuiProvider registry={registry} catalog={catalog} fallback={({ item }) => <Unknown name={item.component} />}>\n * <App />\n * </GenuiProvider>\n * ```\n */\nexport function GenuiProvider({\n registry,\n catalog,\n resolveComponent,\n treeRenderer,\n fallback,\n loading,\n onError,\n children,\n}: GenuiProviderProps) {\n const value = useMemo<GenuiProviderValue>(\n () => ({\n ...(registry !== undefined ? { registry } : {}),\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n ...(treeRenderer !== undefined ? { treeRenderer } : {}),\n ...(fallback !== undefined ? { fallback } : {}),\n ...(loading !== undefined ? { loading } : {}),\n ...(onError !== undefined ? { onError } : {}),\n }),\n [registry, catalog, resolveComponent, treeRenderer, fallback, loading, onError],\n );\n const renderUi = useCallback((block: TranscriptUiBlock) => <GenerativeUI part={block} />, []);\n return (\n <GenuiContext.Provider value={value}>\n <AmbientRenderUiContext.Provider value={renderUi}>{children}</AmbientRenderUiContext.Provider>\n </GenuiContext.Provider>\n );\n}\n\nconst NO_REGISTRY: GenuiRegistry = {};\n\n/** Provider settings overlaid with explicit ones (explicit wins), memoized on their parts. */\nfunction useMergedOptions(own: Partial<GenerativeUIOptions>): GenerativeUIOptions {\n const provided = useContext(GenuiContext);\n const registry = own.registry ?? provided?.registry ?? NO_REGISTRY;\n const catalog = own.catalog ?? provided?.catalog;\n const resolveComponent = own.resolveComponent ?? provided?.resolveComponent;\n const treeRenderer = own.treeRenderer ?? provided?.treeRenderer;\n return useMemo(\n () => ({\n registry,\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n ...(treeRenderer !== undefined ? { treeRenderer } : {}),\n }),\n [registry, catalog, resolveComponent, treeRenderer],\n );\n}\n\n/**\n * The headless half of {@link GenerativeUI}: what to draw for one pushed component, or `null` when\n * `part` is not one. Options default to the enclosing `<GenuiProvider>`'s.\n */\nexport function useGenerativeUI(\n part: unknown,\n options: Partial<GenerativeUIOptions> = {},\n): GenerativeUIState | null {\n const merged = useMergedOptions(options);\n return useGenerativeUIState(part, merged, merged.treeRenderer ?? (GenuiTree as GenuiRenderer));\n}\n\nexport interface GenerativeUIProps extends Partial<GenerativeUIOptions> {\n /** A transcript `ui` block, a `data-ui` message part, or a stored `{ id, component, props, version? }`. */\n part: TranscriptUiBlock | GenerativeUIItem | unknown;\n /** Drawn for an unknown component, invalid props, or a renderer that threw. Default: the provider's, then the item's persisted text. */\n fallback?: GenerativeUIFallback;\n /** Drawn while a resolver or an async validation is pending. Default: the provider's, else nothing. */\n loading?: ReactNode;\n /** A renderer threw (the item shows `fallback`). */\n onError?: (error: unknown, item: GenerativeUIItem) => void;\n}\n\n/**\n * Draws one server-pushed component with the app's own renderer. Headless: it adds no element and\n * no style of its own — only what the registry's component renders (and whatever `fallback` /\n * `loading` you pass). Everything but `part` defaults to the enclosing `<GenuiProvider>`.\n *\n * ```tsx\n * <GenerativeUI part={block} />\n * ```\n */\nexport function GenerativeUI({\n part,\n registry,\n catalog,\n resolveComponent,\n treeRenderer,\n fallback: ownFallback,\n loading: ownLoading,\n onError: ownOnError,\n}: GenerativeUIProps) {\n const provided = useContext(GenuiContext);\n const fallback = ownFallback !== undefined ? ownFallback : provided?.fallback;\n const loading = ownLoading ?? provided?.loading ?? null;\n const onError = ownOnError ?? provided?.onError;\n const options = useMergedOptions({\n ...(registry !== undefined ? { registry } : {}),\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n ...(treeRenderer !== undefined ? { treeRenderer } : {}),\n });\n const state = useGenerativeUIState(\n part,\n options,\n options.treeRenderer ?? (GenuiTree as GenuiRenderer),\n );\n if (state === null) return null;\n if (state.status === 'loading') return loading;\n if (state.status === 'problem') {\n const { status: _status, ...problem } = state;\n return renderFallback(fallback, problem);\n }\n const Renderer = state.Component;\n return (\n <GenerativeUIScope\n {...options}\n {...(state.item.componentVersions !== undefined\n ? { componentVersions: state.item.componentVersions }\n : {})}\n {...(state.item.fallbackText !== undefined ? { fallbackText: state.item.fallbackText } : {})}\n fallback={fallback}\n loading={loading}\n {...(onError !== undefined ? { onError } : {})}\n >\n <ItemBoundary item={state.item} fallback={fallback} onError={onError}>\n <Renderer {...state.props} />\n </ItemBoundary>\n </GenerativeUIScope>\n );\n}\n","import { type Context, type ReactNode, createContext, useContext } from 'react';\nimport type { TranscriptUiBlock } from '../transcript/model.js';\n\n/** Draws a server-pushed component block. */\nexport type AmbientRenderUi = (block: TranscriptUiBlock) => ReactNode;\n\n/**\n * A context stored on `globalThis` under a registered symbol. Each entry point (`.`, `/genui`,\n * `/genui/json-render`) is its own bundle with its own copy of every module, so a context one entry\n * provides and another reads has to be found by key, not by module identity.\n */\nexport function sharedContext<T>(key: string): Context<T | null> {\n const symbol = Symbol.for(key);\n const holder = globalThis as Record<symbol, Context<T | null> | undefined>;\n const existing = holder[symbol];\n if (existing !== undefined) return existing;\n const created = createContext<T | null>(null);\n holder[symbol] = created;\n return created;\n}\n\n/**\n * How pushed components are drawn when no `renderUi` is passed — set by `<GenuiProvider>` (the\n * `/genui` subpath) and read by `MessageItem`.\n */\nexport const AmbientRenderUiContext: Context<AmbientRenderUi | null> =\n sharedContext<AmbientRenderUi>('@dudousxd/nestjs-agent-react:ambient-render-ui');\n\n/**\n * The renderer `<GenuiProvider>` installed for pushed components, or `null` outside one. For a\n * custom transcript built on `useTranscriptItem`: draw a `ui` block with it and you get what\n * `MessageItem` draws.\n */\nexport function useAmbientRenderUi(): AmbientRenderUi | null {\n return useContext(AmbientRenderUiContext);\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport {\n GENUI_TREE_COMPONENT,\n type GenerativeUIItem,\n type GenerativeUIOptions,\n type GenerativeUIState,\n type GenuiCatalogLike,\n type GenuiIssueLike,\n type GenuiRegistry,\n type GenuiRenderer,\n type ResolveComponent,\n} from './types.js';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Normalize whatever carries a pushed component: a transcript `ui` block, a `data-ui` message part\n * (`{ type: 'data-ui', id, data }`), a stored `{ id, component, props, version? }` entry. `null` for\n * anything else.\n */\nexport function toGenerativeUIItem(part: unknown): GenerativeUIItem | null {\n if (!isRecord(part)) return null;\n const source = part.type === 'data-ui' && isRecord(part.data) ? part.data : part;\n if (typeof source.component !== 'string') return null;\n const id =\n typeof source.id === 'string' ? source.id : typeof part.id === 'string' ? part.id : null;\n if (id === null) return null;\n return {\n id,\n component: source.component,\n ...(isRecord(source.componentVersions) &&\n Object.values(source.componentVersions).every(\n (version) => typeof version === 'number' && Number.isSafeInteger(version) && version > 0,\n )\n ? { componentVersions: { ...source.componentVersions } as Record<string, number> }\n : {}),\n ...(typeof source.fallbackText === 'string' ? { fallbackText: source.fallbackText } : {}),\n props: isRecord(source.props) ? source.props : {},\n version: typeof source.version === 'number' ? source.version : null,\n toolCallId: typeof source.toolCallId === 'string' ? source.toolCallId : null,\n };\n}\n\ntype Resolution =\n | { status: 'ready'; Component: GenuiRenderer }\n | { status: 'loading' }\n | { status: 'unknown' }\n | { status: 'error'; error: unknown };\n\ninterface CacheEntry {\n resolution: Resolution;\n settled: Promise<void> | null;\n}\n\nconst resolverCaches = new WeakMap<ResolveComponent, Map<string, CacheEntry>>();\n\nfunction resolveCached(\n resolve: ResolveComponent,\n name: string,\n version: number | null,\n): CacheEntry {\n let cache = resolverCaches.get(resolve);\n if (cache === undefined) {\n cache = new Map();\n resolverCaches.set(resolve, cache);\n }\n const key = `${name}@${version ?? ''}`;\n const hit = cache.get(key);\n if (hit !== undefined) return hit;\n let entry: CacheEntry;\n try {\n const result = resolve(name, version);\n if (result instanceof Promise) {\n entry = { resolution: { status: 'loading' }, settled: null };\n entry.settled = result.then(\n (Component) => {\n entry.resolution = Component ? { status: 'ready', Component } : { status: 'unknown' };\n },\n (error: unknown) => {\n entry.resolution = { status: 'error', error };\n },\n );\n } else {\n entry = {\n resolution: result ? { status: 'ready', Component: result } : { status: 'unknown' },\n settled: null,\n };\n }\n } catch (error) {\n entry = { resolution: { status: 'error', error }, settled: null };\n }\n cache.set(key, entry);\n return entry;\n}\n\n/**\n * Which renderer draws `name`: the registry first, then `resolveComponent` (cached; async results\n * re-render the caller when they land). `fallbackTree` answers the tree component when the\n * registry does not override it.\n */\nexport function useResolvedComponent(\n name: string,\n version: number | null,\n registry: GenuiRegistry,\n resolve: ResolveComponent | undefined,\n fallbackTree?: GenuiRenderer,\n): Resolution {\n const [, setTick] = useState(0);\n const own = registry[name];\n const entry =\n own !== undefined || resolve === undefined ? null : resolveCached(resolve, name, version);\n const pending = entry?.resolution.status === 'loading' ? entry.settled : null;\n useEffect(() => {\n if (pending === null) return;\n let live = true;\n void pending.then(() => {\n if (live) setTick((tick) => tick + 1);\n });\n return () => {\n live = false;\n };\n }, [pending]);\n if (own !== undefined) return { status: 'ready', Component: own };\n if (entry !== null && entry.resolution.status !== 'unknown') return entry.resolution;\n if (name === GENUI_TREE_COMPONENT && fallbackTree !== undefined) {\n return { status: 'ready', Component: fallbackTree };\n }\n return { status: 'unknown' };\n}\n\ntype Validation =\n | { status: 'ok'; props: Record<string, unknown> }\n | { status: 'pending' }\n | { status: 'invalid'; issues: GenuiIssueLike[] };\n\n/**\n * Props checked against the catalog: synchronously when the catalog can (`validateSync`), else\n * after the async check settles. A component the catalog does not know passes through unchecked.\n */\nexport function useValidatedProps(\n catalog: GenuiCatalogLike | undefined,\n name: string,\n props: Record<string, unknown>,\n): Validation {\n const checked = catalog?.has(name) === true;\n const immediate = useMemo<Validation | null>(() => {\n if (!checked || catalog === undefined) return { status: 'ok', props };\n const result = catalog.validateSync?.(name, props);\n if (result === undefined) return null;\n return result.ok\n ? { status: 'ok', props: result.value }\n : { status: 'invalid', issues: result.issues };\n }, [checked, catalog, name, props]);\n const [late, setLate] = useState<{ props: Record<string, unknown>; result: Validation } | null>(\n null,\n );\n useEffect(() => {\n if (immediate !== null || catalog === undefined) return;\n let live = true;\n catalog.validate(name, props).then(\n (result) => {\n if (!live) return;\n setLate({\n props,\n result: result.ok\n ? { status: 'ok', props: result.value }\n : { status: 'invalid', issues: result.issues },\n });\n },\n (error: unknown) => {\n if (!live) return;\n setLate({\n props,\n result: {\n status: 'invalid',\n issues: [{ path: [], message: error instanceof Error ? error.message : String(error) }],\n },\n });\n },\n );\n return () => {\n live = false;\n };\n }, [immediate, catalog, name, props]);\n if (immediate !== null) return immediate;\n return late !== null && late.props === props ? late.result : { status: 'pending' };\n}\n\n/** {@link import('./generative-ui.js').useGenerativeUI}, with the tree renderer handed in (avoids an import cycle). */\nexport function useGenerativeUIState(\n part: unknown,\n options: GenerativeUIOptions,\n fallbackTree: GenuiRenderer | undefined,\n): GenerativeUIState | null {\n const item = useMemo(() => toGenerativeUIItem(part), [part]);\n const name = item?.component ?? '';\n const definition = options.catalog?.get?.(name);\n const incompatible =\n item?.fallbackText !== undefined &&\n item.version !== null &&\n definition !== undefined &&\n item.version !== (definition.version ?? 1);\n const resolution = useResolvedComponent(\n name,\n item?.version ?? null,\n incompatible ? {} : options.registry,\n item === null ? undefined : options.resolveComponent,\n fallbackTree,\n );\n const empty = useMemo<Record<string, unknown>>(() => ({}), []);\n // A tree is validated node by node as it renders, not as one component.\n const validation = useValidatedProps(\n item === null || name === GENUI_TREE_COMPONENT || incompatible ? undefined : options.catalog,\n name,\n item?.props ?? empty,\n );\n if (item === null) return null;\n if (\n name === GENUI_TREE_COMPONENT &&\n item.fallbackText !== undefined &&\n (!isRecord(item.props.root) || typeof item.props.root.type !== 'string')\n )\n return {\n status: 'problem',\n reason: 'invalid',\n item,\n issues: [{ path: ['root'], message: 'Invalid UI tree root' }],\n };\n if (resolution.status === 'loading') return { status: 'loading', item };\n if (resolution.status === 'unknown') return { status: 'problem', reason: 'unknown', item };\n if (resolution.status === 'error') {\n return { status: 'problem', reason: 'error', item, error: resolution.error };\n }\n if (validation.status === 'pending') return { status: 'loading', item };\n if (validation.status === 'invalid') {\n return { status: 'problem', reason: 'invalid', item, issues: validation.issues };\n }\n return { status: 'ready', item, Component: resolution.Component, props: validation.props };\n}\n","import type { ComponentType, ReactNode } from 'react';\n\n/** The `ui` frame component a composed tree is pushed under (`GENUI_TREE_COMPONENT` of `@dudousxd/nestjs-agent-core/genui`). */\nexport const GENUI_TREE_COMPONENT = 'genui:tree';\n\n/** One pushed component, normalized from whatever carried it (a transcript block, a `data-ui` part, a stored entry). */\nexport interface GenerativeUIItem {\n fallbackText?: string;\n componentVersions?: Record<string, number>;\n id: string;\n component: string;\n props: Record<string, unknown>;\n version: number | null;\n toolCallId: string | null;\n}\n\n/** A node of a composed tree (`genui:tree` frames): `{ type, props, children? }`. */\nexport interface GenerativeUIElement {\n type: string;\n props: Record<string, unknown>;\n children?: GenerativeUIElement[];\n}\n\n/**\n * An app's renderer for one component: it receives the component's props spread, plus `children`\n * when it is a layout node in a tree. Any React component — the library never styles anything.\n */\nexport type GenuiRenderer<P = any> = ComponentType<P & { children?: ReactNode }>;\n\n/** Component name → the app's renderer. */\nexport type GenuiRegistry = Record<string, GenuiRenderer>;\n\n/**\n * Resolve a component the registry does not have — typically a tenant's own component, fetched for\n * the exact `version` a message was rendered with. Return `null`/`undefined` for \"no such\n * component\". May be async; results are cached per resolver, name and version.\n */\nexport type ResolveComponent = (\n name: string,\n version: number | null,\n) => GenuiRenderer | null | undefined | Promise<GenuiRenderer | null | undefined>;\n\nexport interface GenuiIssueLike {\n path: (string | number)[];\n message: string;\n}\n\ntype ValidationLike =\n | { ok: true; value: Record<string, unknown> }\n | { ok: false; issues: GenuiIssueLike[] };\n\n/**\n * What the renderer needs from a catalog to validate props before drawing them. A `Catalog` from\n * `@dudousxd/nestjs-agent-core/genui` satisfies it; declared structurally so any catalog-shaped\n * object does too.\n */\nexport interface GenuiCatalogLike {\n get?(name: string): { version?: number } | undefined;\n has(name: string): boolean;\n validate(name: string, props: unknown): Promise<ValidationLike>;\n validateSync?(name: string, props: unknown): ValidationLike | undefined;\n}\n\nexport interface GenerativeUIOptions {\n registry: GenuiRegistry;\n /** Validate props against it before rendering. Components the catalog does not know render unvalidated. */\n catalog?: GenuiCatalogLike;\n resolveComponent?: ResolveComponent;\n /**\n * Draws a composed tree frame (`genui:tree`) whole — e.g. through json-render (see the\n * `/genui/json-render` subpath's `GenuiProvider`). Omitted → trees render node by node through\n * `registry`.\n */\n treeRenderer?: GenuiRenderer<{ root?: GenerativeUIElement }>;\n}\n\n/** Why an item did not render. */\nexport type GenerativeUIProblem =\n | { reason: 'unknown'; item: GenerativeUIItem }\n | { reason: 'invalid'; item: GenerativeUIItem; issues: GenuiIssueLike[] }\n | { reason: 'error'; item: GenerativeUIItem; error: unknown };\n\nexport type GenerativeUIState =\n | {\n status: 'ready';\n item: GenerativeUIItem;\n Component: GenuiRenderer;\n props: Record<string, unknown>;\n }\n | { status: 'loading'; item: GenerativeUIItem }\n | ({ status: 'problem' } & GenerativeUIProblem);\n","import {\n type CatalogOptions,\n type ComponentDefinition,\n type ComponentPresentation,\n createComponentRegistry,\n} from '@dudousxd/nestjs-agent-core/genui';\nimport { type ComponentType, type ReactNode, createElement } from 'react';\nimport type { GenuiRegistry } from './types.js';\n\nexport interface ReactComponentRenderers<P extends object> {\n react?: ComponentType<P>;\n text?: (props: P) => string | Promise<string>;\n /** Return each page's complete props. Each page is validated again before SSR. */\n paginate?: (props: P, rowsPerPage: number) => readonly P[] | Promise<readonly P[]>;\n}\n\n/** App-scoped registry shared by GenuiProvider and static server rendering. */\nexport function createReactComponentRegistry(options?: CatalogOptions) {\n const registry = createComponentRegistry(options);\n const components: GenuiRegistry = Object.create(null);\n const texts = new Map<string, (props: Record<string, unknown>) => string | Promise<string>>();\n const paginators = new Map<\n string,\n (props: Record<string, unknown>, size: number) => Promise<readonly Record<string, unknown>[]>\n >();\n const adapter = {\n get catalog() {\n return registry.catalog;\n },\n get manifest() {\n return registry.manifest;\n },\n get components(): GenuiRegistry {\n return { ...components };\n },\n prepare: (presentation: ComponentPresentation<object>) =>\n registry.prepare({ ...presentation, props: presentation.props as Record<string, unknown> }),\n render: (presentation: ComponentPresentation<object>, channel: string) =>\n registry.render(\n { ...presentation, props: presentation.props as Record<string, unknown> },\n channel,\n ),\n register<P extends object>(\n definition: ComponentDefinition<P>,\n renderers: ReactComponentRenderers<P>,\n ) {\n const ReactComponent = renderers.react;\n registry.register(definition, {\n ...(ReactComponent ? { react: (props: P) => createElement(ReactComponent, props) } : {}),\n ...(renderers.text ? { text: renderers.text } : {}),\n });\n if (renderers.react) components[definition.name] = renderers.react;\n if (renderers.text) {\n const text = renderers.text;\n texts.set(definition.name, (props) => text(props as P));\n }\n if (renderers.paginate) {\n const paginate = renderers.paginate;\n paginators.set(\n definition.name,\n async (props, size) =>\n (await paginate(props as P, size)) as readonly Record<string, unknown>[],\n );\n }\n return adapter;\n },\n async renderPages(\n presentation: ComponentPresentation<object>,\n size: number,\n ): Promise<ReactNode[]> {\n const pages = await adapter.paginate(presentation, size);\n return Promise.all(\n pages.map(async (page) => {\n const ReactComponent = components[page.component];\n if (ReactComponent) return createElement(ReactComponent, page.props);\n return texts.get(page.component)?.(page.props) ?? page.fallbackText;\n }),\n );\n },\n async paginate(\n presentation: ComponentPresentation<object>,\n size: number,\n ): Promise<ComponentPresentation[]> {\n if (!Number.isInteger(size) || size < 1 || size > 500)\n throw new RangeError('genui: rowsPerPage must be 1–500');\n const prepared = await registry.prepare({\n ...presentation,\n props: presentation.props as Record<string, unknown>,\n });\n const custom = paginators.get(prepared.component);\n const rows = prepared.props.rows;\n const pages = custom\n ? await custom(prepared.props, size)\n : prepared.component === 'DataTable' && Array.isArray(rows) && rows.length > size\n ? Array.from({ length: Math.ceil(rows.length / size) }, (_, index) => ({\n ...prepared.props,\n rows: rows.slice(index * size, (index + 1) * size),\n }))\n : [prepared.props];\n if (!pages.length || pages.length > 100)\n throw new RangeError('genui: capture requires 1–100 pages');\n return Promise.all(pages.map((props) => registry.prepare({ ...prepared, props })));\n },\n };\n return adapter;\n}\nexport type ReactComponentRegistry = ReturnType<typeof createReactComponentRegistry>;\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EAIA,iBAAAA;AAAA,EACA;AAAA,EACA,cAAAC;AAAA,EACA,WAAAC;AAAA,OACK;;;ACTP,SAAuC,eAAe,kBAAkB;AAWjE,SAAS,cAAiB,KAAgC;AAC/D,QAAM,SAAS,OAAO,IAAI,GAAG;AAC7B,QAAM,SAAS;AACf,QAAM,WAAW,OAAO,MAAM;AAC9B,MAAI,aAAa,OAAW,QAAO;AACnC,QAAM,UAAU,cAAwB,IAAI;AAC5C,SAAO,MAAM,IAAI;AACjB,SAAO;AACT;AAMO,IAAM,yBACX,cAA+B,gDAAgD;;;AC1BjF,SAAS,WAAW,SAAS,gBAAgB;;;ACGtC,IAAM,uBAAuB;;;ADUpC,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAOO,SAAS,mBAAmB,MAAwC;AACzE,MAAI,CAAC,SAAS,IAAI,EAAG,QAAO;AAC5B,QAAM,SAAS,KAAK,SAAS,aAAa,SAAS,KAAK,IAAI,IAAI,KAAK,OAAO;AAC5E,MAAI,OAAO,OAAO,cAAc,SAAU,QAAO;AACjD,QAAM,KACJ,OAAO,OAAO,OAAO,WAAW,OAAO,KAAK,OAAO,KAAK,OAAO,WAAW,KAAK,KAAK;AACtF,MAAI,OAAO,KAAM,QAAO;AACxB,SAAO;AAAA,IACL;AAAA,IACA,WAAW,OAAO;AAAA,IAClB,GAAI,SAAS,OAAO,iBAAiB,KACrC,OAAO,OAAO,OAAO,iBAAiB,EAAE;AAAA,MACtC,CAAC,YAAY,OAAO,YAAY,YAAY,OAAO,cAAc,OAAO,KAAK,UAAU;AAAA,IACzF,IACI,EAAE,mBAAmB,EAAE,GAAG,OAAO,kBAAkB,EAA4B,IAC/E,CAAC;AAAA,IACL,GAAI,OAAO,OAAO,iBAAiB,WAAW,EAAE,cAAc,OAAO,aAAa,IAAI,CAAC;AAAA,IACvF,OAAO,SAAS,OAAO,KAAK,IAAI,OAAO,QAAQ,CAAC;AAAA,IAChD,SAAS,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU;AAAA,IAC/D,YAAY,OAAO,OAAO,eAAe,WAAW,OAAO,aAAa;AAAA,EAC1E;AACF;AAaA,IAAM,iBAAiB,oBAAI,QAAmD;AAE9E,SAAS,cACP,SACA,MACA,SACY;AACZ,MAAI,QAAQ,eAAe,IAAI,OAAO;AACtC,MAAI,UAAU,QAAW;AACvB,YAAQ,oBAAI,IAAI;AAChB,mBAAe,IAAI,SAAS,KAAK;AAAA,EACnC;AACA,QAAM,MAAM,GAAG,IAAI,IAAI,WAAW,EAAE;AACpC,QAAM,MAAM,MAAM,IAAI,GAAG;AACzB,MAAI,QAAQ,OAAW,QAAO;AAC9B,MAAI;AACJ,MAAI;AACF,UAAM,SAAS,QAAQ,MAAM,OAAO;AACpC,QAAI,kBAAkB,SAAS;AAC7B,cAAQ,EAAE,YAAY,EAAE,QAAQ,UAAU,GAAG,SAAS,KAAK;AAC3D,YAAM,UAAU,OAAO;AAAA,QACrB,CAACC,eAAc;AACb,gBAAM,aAAaA,aAAY,EAAE,QAAQ,SAAS,WAAAA,WAAU,IAAI,EAAE,QAAQ,UAAU;AAAA,QACtF;AAAA,QACA,CAAC,UAAmB;AAClB,gBAAM,aAAa,EAAE,QAAQ,SAAS,MAAM;AAAA,QAC9C;AAAA,MACF;AAAA,IACF,OAAO;AACL,cAAQ;AAAA,QACN,YAAY,SAAS,EAAE,QAAQ,SAAS,WAAW,OAAO,IAAI,EAAE,QAAQ,UAAU;AAAA,QAClF,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,EAAE,YAAY,EAAE,QAAQ,SAAS,MAAM,GAAG,SAAS,KAAK;AAAA,EAClE;AACA,QAAM,IAAI,KAAK,KAAK;AACpB,SAAO;AACT;AAOO,SAAS,qBACd,MACA,SACA,UACA,SACA,cACY;AACZ,QAAM,CAAC,EAAE,OAAO,IAAI,SAAS,CAAC;AAC9B,QAAM,MAAM,SAAS,IAAI;AACzB,QAAM,QACJ,QAAQ,UAAa,YAAY,SAAY,OAAO,cAAc,SAAS,MAAM,OAAO;AAC1F,QAAM,UAAU,OAAO,WAAW,WAAW,YAAY,MAAM,UAAU;AACzE,YAAU,MAAM;AACd,QAAI,YAAY,KAAM;AACtB,QAAI,OAAO;AACX,SAAK,QAAQ,KAAK,MAAM;AACtB,UAAI,KAAM,SAAQ,CAAC,SAAS,OAAO,CAAC;AAAA,IACtC,CAAC;AACD,WAAO,MAAM;AACX,aAAO;AAAA,IACT;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AACZ,MAAI,QAAQ,OAAW,QAAO,EAAE,QAAQ,SAAS,WAAW,IAAI;AAChE,MAAI,UAAU,QAAQ,MAAM,WAAW,WAAW,UAAW,QAAO,MAAM;AAC1E,MAAI,SAAS,wBAAwB,iBAAiB,QAAW;AAC/D,WAAO,EAAE,QAAQ,SAAS,WAAW,aAAa;AAAA,EACpD;AACA,SAAO,EAAE,QAAQ,UAAU;AAC7B;AAWO,SAAS,kBACd,SACA,MACA,OACY;AACZ,QAAM,UAAU,SAAS,IAAI,IAAI,MAAM;AACvC,QAAM,YAAY,QAA2B,MAAM;AACjD,QAAI,CAAC,WAAW,YAAY,OAAW,QAAO,EAAE,QAAQ,MAAM,MAAM;AACpE,UAAM,SAAS,QAAQ,eAAe,MAAM,KAAK;AACjD,QAAI,WAAW,OAAW,QAAO;AACjC,WAAO,OAAO,KACV,EAAE,QAAQ,MAAM,OAAO,OAAO,MAAM,IACpC,EAAE,QAAQ,WAAW,QAAQ,OAAO,OAAO;AAAA,EACjD,GAAG,CAAC,SAAS,SAAS,MAAM,KAAK,CAAC;AAClC,QAAM,CAAC,MAAM,OAAO,IAAI;AAAA,IACtB;AAAA,EACF;AACA,YAAU,MAAM;AACd,QAAI,cAAc,QAAQ,YAAY,OAAW;AACjD,QAAI,OAAO;AACX,YAAQ,SAAS,MAAM,KAAK,EAAE;AAAA,MAC5B,CAAC,WAAW;AACV,YAAI,CAAC,KAAM;AACX,gBAAQ;AAAA,UACN;AAAA,UACA,QAAQ,OAAO,KACX,EAAE,QAAQ,MAAM,OAAO,OAAO,MAAM,IACpC,EAAE,QAAQ,WAAW,QAAQ,OAAO,OAAO;AAAA,QACjD,CAAC;AAAA,MACH;AAAA,MACA,CAAC,UAAmB;AAClB,YAAI,CAAC,KAAM;AACX,gBAAQ;AAAA,UACN;AAAA,UACA,QAAQ;AAAA,YACN,QAAQ;AAAA,YACR,QAAQ,CAAC,EAAE,MAAM,CAAC,GAAG,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,CAAC;AAAA,UACxF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AACA,WAAO,MAAM;AACX,aAAO;AAAA,IACT;AAAA,EACF,GAAG,CAAC,WAAW,SAAS,MAAM,KAAK,CAAC;AACpC,MAAI,cAAc,KAAM,QAAO;AAC/B,SAAO,SAAS,QAAQ,KAAK,UAAU,QAAQ,KAAK,SAAS,EAAE,QAAQ,UAAU;AACnF;AAGO,SAAS,qBACd,MACA,SACA,cAC0B;AAC1B,QAAM,OAAO,QAAQ,MAAM,mBAAmB,IAAI,GAAG,CAAC,IAAI,CAAC;AAC3D,QAAM,OAAO,MAAM,aAAa;AAChC,QAAM,aAAa,QAAQ,SAAS,MAAM,IAAI;AAC9C,QAAM,eACJ,MAAM,iBAAiB,UACvB,KAAK,YAAY,QACjB,eAAe,UACf,KAAK,aAAa,WAAW,WAAW;AAC1C,QAAM,aAAa;AAAA,IACjB;AAAA,IACA,MAAM,WAAW;AAAA,IACjB,eAAe,CAAC,IAAI,QAAQ;AAAA,IAC5B,SAAS,OAAO,SAAY,QAAQ;AAAA,IACpC;AAAA,EACF;AACA,QAAM,QAAQ,QAAiC,OAAO,CAAC,IAAI,CAAC,CAAC;AAE7D,QAAM,aAAa;AAAA,IACjB,SAAS,QAAQ,SAAS,wBAAwB,eAAe,SAAY,QAAQ;AAAA,IACrF;AAAA,IACA,MAAM,SAAS;AAAA,EACjB;AACA,MAAI,SAAS,KAAM,QAAO;AAC1B,MACE,SAAS,wBACT,KAAK,iBAAiB,WACrB,CAAC,SAAS,KAAK,MAAM,IAAI,KAAK,OAAO,KAAK,MAAM,KAAK,SAAS;AAE/D,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR;AAAA,MACA,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,SAAS,uBAAuB,CAAC;AAAA,IAC9D;AACF,MAAI,WAAW,WAAW,UAAW,QAAO,EAAE,QAAQ,WAAW,KAAK;AACtE,MAAI,WAAW,WAAW,UAAW,QAAO,EAAE,QAAQ,WAAW,QAAQ,WAAW,KAAK;AACzF,MAAI,WAAW,WAAW,SAAS;AACjC,WAAO,EAAE,QAAQ,WAAW,QAAQ,SAAS,MAAM,OAAO,WAAW,MAAM;AAAA,EAC7E;AACA,MAAI,WAAW,WAAW,UAAW,QAAO,EAAE,QAAQ,WAAW,KAAK;AACtE,MAAI,WAAW,WAAW,WAAW;AACnC,WAAO,EAAE,QAAQ,WAAW,QAAQ,WAAW,MAAM,QAAQ,WAAW,OAAO;AAAA,EACjF;AACA,SAAO,EAAE,QAAQ,SAAS,MAAM,WAAW,WAAW,WAAW,OAAO,WAAW,MAAM;AAC3F;;;AFnMI;AANJ,IAAM,mBAAmBC,eAAgC,IAAI;AAE7D,SAAS,eAAe,UAA4C,SAA8B;AAChG,MAAI,OAAO,aAAa,WAAY,QAAO,SAAS,OAAO;AAC3D,MAAI,aAAa,OAAW,QAAO;AACnC,SAAO,QAAQ,KAAK,iBAAiB,SACnC,oBAAC,UAAK,OAAO,EAAE,YAAY,WAAW,GAAI,kBAAQ,KAAK,cAAa,IAClE;AACN;AAUA,IAAM,eAAN,cAA2B,UAA8D;AAAA,EAC9E,QAAQ,EAAE,OAAO,QAAsB,QAAQ,MAAM;AAAA,EAE9D,OAAO,yBAAyB,OAAgB;AAC9C,WAAO,EAAE,OAAO,QAAQ,KAAK;AAAA,EAC/B;AAAA,EAES,kBAAkB,OAAgB,OAAkB;AAC3D,SAAK,MAAM,UAAU,OAAO,KAAK,MAAM,IAAI;AAAA,EAC7C;AAAA,EAES,mBAAmB,UAAyB;AAEnD,QAAI,KAAK,MAAM,UAAU,SAAS,SAAS,KAAK,MAAM,MAAM;AAC1D,WAAK,SAAS,EAAE,OAAO,QAAW,QAAQ,MAAM,CAAC;AAAA,IACnD;AAAA,EACF;AAAA,EAES,SAAS;AAChB,QAAI,KAAK,MAAM,QAAQ;AACrB,aAAO,eAAe,KAAK,MAAM,UAAU;AAAA,QACzC,QAAQ;AAAA,QACR,MAAM,KAAK,MAAM;AAAA,QACjB,OAAO,KAAK,MAAM;AAAA,MACpB,CAAC;AAAA,IACH;AACA,WAAO,KAAK,MAAM;AAAA,EACpB;AACF;AAEA,SAAS,SAAS,MAA2B,IAA8B;AACzE,SAAO,EAAE,IAAI,WAAW,KAAK,MAAM,OAAO,KAAK,SAAS,CAAC,GAAG,SAAS,MAAM,YAAY,KAAK;AAC9F;AAGA,SAAS,SAAS,EAAE,MAAM,GAAG,GAA8C;AACzE,QAAM,QAAQC,YAAW,gBAAgB;AACzC,QAAM,OAAOC,SAAQ,MAAM,SAAS,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;AACzD,QAAM,gBAAgB,OAAO,oBAAoB,KAAK,IAAI;AAC1D,QAAM,aAAa,OAAO,QAAQ,SAAS,MAAM,KAAK,IAAI;AAC1D,QAAM,eACJ,kBAAkB,UAClB,eAAe,UACf,mBAAmB,WAAW,WAAW;AAC3C,QAAM,aAAa;AAAA,IACjB,KAAK;AAAA,IACL,iBAAiB;AAAA,IACjB,eAAe,CAAC,IAAK,OAAO,QAAQ,YAAY,CAAC;AAAA,IACjD,OAAO,QAAQ;AAAA,EACjB;AACA,QAAM,aAAa;AAAA,IACjB,eAAe,SAAY,OAAO,QAAQ;AAAA,IAC1C,KAAK;AAAA,IACL,KAAK;AAAA,EACP;AACA,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,WAAW,WAAW,aAAa,WAAW,WAAW,UAAW,QAAO,MAAM;AACrF,MAAI,WAAW,WAAW,WAAW;AACnC,QAAI,MAAM,aAAa,UAAa,MAAM,iBAAiB;AACzD,YAAM,IAAI,MAAM,wBAAwB;AAC1C,WAAO,eAAe,MAAM,UAAU,EAAE,QAAQ,WAAW,KAAK,CAAC;AAAA,EACnE;AACA,MAAI,WAAW,WAAW,SAAS;AACjC,QAAI,MAAM,aAAa,UAAa,MAAM,iBAAiB,OAAW,OAAM,WAAW;AACvF,WAAO,eAAe,MAAM,UAAU,EAAE,QAAQ,SAAS,MAAM,OAAO,WAAW,MAAM,CAAC;AAAA,EAC1F;AACA,MAAI,WAAW,WAAW,WAAW;AACnC,QAAI,MAAM,aAAa,UAAa,MAAM,iBAAiB;AACzD,YAAM,IAAI,MAAM,wBAAwB;AAC1C,WAAO,eAAe,MAAM,UAAU,EAAE,QAAQ,WAAW,MAAM,QAAQ,WAAW,OAAO,CAAC;AAAA,EAC9F;AACA,QAAM,WAAW,WAAW;AAC5B,QAAM,WAAW,MAAM,QAAQ,KAAK,QAAQ,IAAI,KAAK,WAAW,CAAC;AACjE,SACE,oBAAC,YAAU,GAAG,WAAW,OACtB,mBAAS,SAAS,IACf,SAAS,IAAI,CAAC,OAAO,UAAU;AAC7B,UAAM,UAAU,GAAG,EAAE,IAAI,KAAK;AAC9B,QAAI,MAAM,aAAa,UAAa,MAAM,iBAAiB;AACzD,aAAO,oBAAC,YAAuB,MAAM,OAAO,IAAI,WAA1B,OAAmC;AAC3D,WACE;AAAA,MAAC;AAAA;AAAA,QAEC,MAAM,SAAS,OAAO,OAAO;AAAA,QAC7B,UAAU,MAAM;AAAA,QAChB,SAAS,MAAM;AAAA,QAEf,8BAAC,YAAS,MAAM,OAAO,IAAI,SAAS;AAAA;AAAA,MAL/B;AAAA,IAMP;AAAA,EAEJ,CAAC,IACD,QACN;AAEJ;AAOO,SAAS,UAAU,EAAE,KAAK,GAAmC;AAClE,MAAI,SAAS,UAAa,SAAS,QAAQ,OAAO,KAAK,SAAS,SAAU,QAAO;AACjF,SAAO,oBAAC,YAAS,MAAM,MAAM,IAAG,QAAO;AACzC;AAeO,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AACF,GAA2B;AACzB,QAAM,QAAQA;AAAA,IACZ,OAAO;AAAA,MACL,SAAS;AAAA,QACP;AAAA,QACA,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,QAC3C,GAAI,qBAAqB,SAAY,EAAE,iBAAiB,IAAI,CAAC;AAAA,MAC/D;AAAA,MACA;AAAA,MACA,GAAI,sBAAsB,SAAY,EAAE,kBAAkB,IAAI,CAAC;AAAA,MAC/D,GAAI,iBAAiB,SAAY,EAAE,aAAa,IAAI,CAAC;AAAA,MACrD;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAO,oBAAC,iBAAiB,UAAjB,EAA0B,OAAO,OAAQ,UAAS;AAC5D;AAWA,IAAM,eAAmD;AAAA,EACvD;AACF;AAGO,SAAS,mBAA8C;AAC5D,SAAOD,YAAW,YAAY;AAChC;AAkBO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAuB;AACrB,QAAM,QAAQC;AAAA,IACZ,OAAO;AAAA,MACL,GAAI,aAAa,SAAY,EAAE,SAAS,IAAI,CAAC;AAAA,MAC7C,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,MAC3C,GAAI,qBAAqB,SAAY,EAAE,iBAAiB,IAAI,CAAC;AAAA,MAC7D,GAAI,iBAAiB,SAAY,EAAE,aAAa,IAAI,CAAC;AAAA,MACrD,GAAI,aAAa,SAAY,EAAE,SAAS,IAAI,CAAC;AAAA,MAC7C,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,MAC3C,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC7C;AAAA,IACA,CAAC,UAAU,SAAS,kBAAkB,cAAc,UAAU,SAAS,OAAO;AAAA,EAChF;AACA,QAAM,WAAW,YAAY,CAAC,UAA6B,oBAAC,gBAAa,MAAM,OAAO,GAAI,CAAC,CAAC;AAC5F,SACE,oBAAC,aAAa,UAAb,EAAsB,OACrB,8BAAC,uBAAuB,UAAvB,EAAgC,OAAO,UAAW,UAAS,GAC9D;AAEJ;AAEA,IAAM,cAA6B,CAAC;AAGpC,SAAS,iBAAiB,KAAwD;AAChF,QAAM,WAAWD,YAAW,YAAY;AACxC,QAAM,WAAW,IAAI,YAAY,UAAU,YAAY;AACvD,QAAM,UAAU,IAAI,WAAW,UAAU;AACzC,QAAM,mBAAmB,IAAI,oBAAoB,UAAU;AAC3D,QAAM,eAAe,IAAI,gBAAgB,UAAU;AACnD,SAAOC;AAAA,IACL,OAAO;AAAA,MACL;AAAA,MACA,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,MAC3C,GAAI,qBAAqB,SAAY,EAAE,iBAAiB,IAAI,CAAC;AAAA,MAC7D,GAAI,iBAAiB,SAAY,EAAE,aAAa,IAAI,CAAC;AAAA,IACvD;AAAA,IACA,CAAC,UAAU,SAAS,kBAAkB,YAAY;AAAA,EACpD;AACF;AAMO,SAAS,gBACd,MACA,UAAwC,CAAC,GACf;AAC1B,QAAM,SAAS,iBAAiB,OAAO;AACvC,SAAO,qBAAqB,MAAM,QAAQ,OAAO,gBAAiB,SAA2B;AAC/F;AAsBO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,SAAS;AAAA,EACT,SAAS;AACX,GAAsB;AACpB,QAAM,WAAWD,YAAW,YAAY;AACxC,QAAM,WAAW,gBAAgB,SAAY,cAAc,UAAU;AACrE,QAAM,UAAU,cAAc,UAAU,WAAW;AACnD,QAAM,UAAU,cAAc,UAAU;AACxC,QAAM,UAAU,iBAAiB;AAAA,IAC/B,GAAI,aAAa,SAAY,EAAE,SAAS,IAAI,CAAC;AAAA,IAC7C,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC3C,GAAI,qBAAqB,SAAY,EAAE,iBAAiB,IAAI,CAAC;AAAA,IAC7D,GAAI,iBAAiB,SAAY,EAAE,aAAa,IAAI,CAAC;AAAA,EACvD,CAAC;AACD,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA,QAAQ,gBAAiB;AAAA,EAC3B;AACA,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,MAAM,WAAW,UAAW,QAAO;AACvC,MAAI,MAAM,WAAW,WAAW;AAC9B,UAAM,EAAE,QAAQ,SAAS,GAAG,QAAQ,IAAI;AACxC,WAAO,eAAe,UAAU,OAAO;AAAA,EACzC;AACA,QAAM,WAAW,MAAM;AACvB,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACH,GAAI,MAAM,KAAK,sBAAsB,SAClC,EAAE,mBAAmB,MAAM,KAAK,kBAAkB,IAClD,CAAC;AAAA,MACJ,GAAI,MAAM,KAAK,iBAAiB,SAAY,EAAE,cAAc,MAAM,KAAK,aAAa,IAAI,CAAC;AAAA,MAC1F;AAAA,MACA;AAAA,MACC,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,MAE5C,8BAAC,gBAAa,MAAM,MAAM,MAAM,UAAoB,SAClD,8BAAC,YAAU,GAAG,MAAM,OAAO,GAC7B;AAAA;AAAA,EACF;AAEJ;;;AI1XA;AAAA,EAIE;AAAA,OACK;AACP,SAA6C,qBAAqB;AAW3D,SAAS,6BAA6B,SAA0B;AACrE,QAAM,WAAW,wBAAwB,OAAO;AAChD,QAAM,aAA4B,uBAAO,OAAO,IAAI;AACpD,QAAM,QAAQ,oBAAI,IAA0E;AAC5F,QAAM,aAAa,oBAAI,IAGrB;AACF,QAAM,UAAU;AAAA,IACd,IAAI,UAAU;AACZ,aAAO,SAAS;AAAA,IAClB;AAAA,IACA,IAAI,WAAW;AACb,aAAO,SAAS;AAAA,IAClB;AAAA,IACA,IAAI,aAA4B;AAC9B,aAAO,EAAE,GAAG,WAAW;AAAA,IACzB;AAAA,IACA,SAAS,CAAC,iBACR,SAAS,QAAQ,EAAE,GAAG,cAAc,OAAO,aAAa,MAAiC,CAAC;AAAA,IAC5F,QAAQ,CAAC,cAA6C,YACpD,SAAS;AAAA,MACP,EAAE,GAAG,cAAc,OAAO,aAAa,MAAiC;AAAA,MACxE;AAAA,IACF;AAAA,IACF,SACE,YACA,WACA;AACA,YAAM,iBAAiB,UAAU;AACjC,eAAS,SAAS,YAAY;AAAA,QAC5B,GAAI,iBAAiB,EAAE,OAAO,CAAC,UAAa,cAAc,gBAAgB,KAAK,EAAE,IAAI,CAAC;AAAA,QACtF,GAAI,UAAU,OAAO,EAAE,MAAM,UAAU,KAAK,IAAI,CAAC;AAAA,MACnD,CAAC;AACD,UAAI,UAAU,MAAO,YAAW,WAAW,IAAI,IAAI,UAAU;AAC7D,UAAI,UAAU,MAAM;AAClB,cAAM,OAAO,UAAU;AACvB,cAAM,IAAI,WAAW,MAAM,CAAC,UAAU,KAAK,KAAU,CAAC;AAAA,MACxD;AACA,UAAI,UAAU,UAAU;AACtB,cAAM,WAAW,UAAU;AAC3B,mBAAW;AAAA,UACT,WAAW;AAAA,UACX,OAAO,OAAO,SACX,MAAM,SAAS,OAAY,IAAI;AAAA,QACpC;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,IACA,MAAM,YACJ,cACA,MACsB;AACtB,YAAM,QAAQ,MAAM,QAAQ,SAAS,cAAc,IAAI;AACvD,aAAO,QAAQ;AAAA,QACb,MAAM,IAAI,OAAO,SAAS;AACxB,gBAAM,iBAAiB,WAAW,KAAK,SAAS;AAChD,cAAI,eAAgB,QAAO,cAAc,gBAAgB,KAAK,KAAK;AACnE,iBAAO,MAAM,IAAI,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK,KAAK;AAAA,QACzD,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA,MAAM,SACJ,cACA,MACkC;AAClC,UAAI,CAAC,OAAO,UAAU,IAAI,KAAK,OAAO,KAAK,OAAO;AAChD,cAAM,IAAI,WAAW,uCAAkC;AACzD,YAAM,WAAW,MAAM,SAAS,QAAQ;AAAA,QACtC,GAAG;AAAA,QACH,OAAO,aAAa;AAAA,MACtB,CAAC;AACD,YAAM,SAAS,WAAW,IAAI,SAAS,SAAS;AAChD,YAAM,OAAO,SAAS,MAAM;AAC5B,YAAM,QAAQ,SACV,MAAM,OAAO,SAAS,OAAO,IAAI,IACjC,SAAS,cAAc,eAAe,MAAM,QAAQ,IAAI,KAAK,KAAK,SAAS,OACzE,MAAM,KAAK,EAAE,QAAQ,KAAK,KAAK,KAAK,SAAS,IAAI,EAAE,GAAG,CAAC,GAAG,WAAW;AAAA,QACnE,GAAG,SAAS;AAAA,QACZ,MAAM,KAAK,MAAM,QAAQ,OAAO,QAAQ,KAAK,IAAI;AAAA,MACnD,EAAE,IACF,CAAC,SAAS,KAAK;AACrB,UAAI,CAAC,MAAM,UAAU,MAAM,SAAS;AAClC,cAAM,IAAI,WAAW,0CAAqC;AAC5D,aAAO,QAAQ,IAAI,MAAM,IAAI,CAAC,UAAU,SAAS,QAAQ,EAAE,GAAG,UAAU,MAAM,CAAC,CAAC,CAAC;AAAA,IACnF;AAAA,EACF;AACA,SAAO;AACT;","names":["createContext","useContext","useMemo","Component","createContext","useContext","useMemo"]}