@opengeni/react 7.4.0-canary.36844267522001 → 7.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -10
- package/dist/artifacts-document.js +2 -3
- package/dist/artifacts-presentation.js +2 -3
- package/dist/artifacts-spreadsheet.js +2 -2
- package/dist/artifacts.d.ts +0 -1
- package/dist/artifacts.js +1402 -505
- package/dist/artifacts.js.map +1 -1
- package/dist/{browser-viewer-AJO7LMVE.js → browser-viewer-2E6R2Y4W.js} +2 -2
- package/dist/{chunk-WUISZ3WU.js → chunk-3E2AITTZ.js} +28 -32
- package/dist/{chunk-WUISZ3WU.js.map → chunk-3E2AITTZ.js.map} +1 -1
- package/dist/{chunk-Y2PRMYLC.js → chunk-DUEBTL3N.js} +3 -4
- package/dist/{chunk-Y2PRMYLC.js.map → chunk-DUEBTL3N.js.map} +1 -1
- package/dist/{chunk-7UAMYXJY.js → chunk-KNDIXZN6.js} +18 -25
- package/dist/{chunk-7UAMYXJY.js.map → chunk-KNDIXZN6.js.map} +1 -1
- package/dist/{chunk-XVYRQ4PK.js → chunk-L4OSXQ6H.js} +116 -277
- package/dist/chunk-L4OSXQ6H.js.map +1 -0
- package/dist/{chunk-7B44WVGH.js → chunk-S5JQ4R22.js} +12 -31
- package/dist/chunk-S5JQ4R22.js.map +1 -0
- package/dist/{chunk-A4UJB2MM.js → chunk-SEEVCT36.js} +2 -2
- package/dist/chunk-UGMKPUEM.js +299 -0
- package/dist/chunk-UGMKPUEM.js.map +1 -0
- package/dist/{chunk-OQVBTOBJ.js → chunk-USXVQACU.js} +3 -3
- package/dist/{chunk-ASCSKOWU.js → chunk-V2ABIVYJ.js} +3 -50
- package/dist/chunk-V2ABIVYJ.js.map +1 -0
- package/dist/{chunk-UQUR5WG5.js → chunk-X4HIN6TV.js} +157 -66
- package/dist/chunk-X4HIN6TV.js.map +1 -0
- package/dist/{chunk-QLG6W33X.js → chunk-XEJEOAOV.js} +35 -46
- package/dist/chunk-XEJEOAOV.js.map +1 -0
- package/dist/components/artifacts/editable-artifact-ui.d.ts +1 -2
- package/dist/components/artifacts/index.d.ts +0 -7
- package/dist/components/message-timeline.d.ts +1 -7
- package/dist/components/open-geni-links.d.ts +0 -16
- package/dist/components/session-conversation.d.ts +1 -13
- package/dist/{computer-viewer-NB6O6BTV.js → computer-viewer-WMJE6OA3.js} +2 -2
- package/dist/connect.js +1 -2
- package/dist/connect.js.map +1 -1
- package/dist/hooks/latest-question.d.ts +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.js +12 -22
- package/dist/index.js.map +1 -1
- package/dist/interaction.js +2 -2
- package/dist/{latest-question-3HGQUI2E.js → latest-question-QB4EUCW5.js} +2 -2
- package/dist/{markdown-table-layout-QXSLK4BY.js → markdown-table-layout-PFUEZ2U4.js} +5 -37
- package/dist/markdown-table-layout-PFUEZ2U4.js.map +1 -0
- package/dist/session-ui.d.ts +2 -3
- package/dist/session-ui.js +9 -18
- package/dist/session-ui.js.map +1 -1
- package/dist/session.js +2 -2
- package/dist/sites.js +289 -4
- package/dist/sites.js.map +1 -1
- package/package.json +3 -3
- package/src/artifacts.ts +0 -37
- package/src/components/artifacts/editable-artifact-ui.tsx +1 -3
- package/src/components/artifacts/editable-artifact-workbench.tsx +2 -5
- package/src/components/artifacts/editable-document.tsx +36 -34
- package/src/components/artifacts/editable-presentation.tsx +16 -21
- package/src/components/artifacts/index.ts +0 -41
- package/src/components/browser-viewer.tsx +20 -59
- package/src/components/computer-viewer.tsx +23 -51
- package/src/components/markdown-table-layout.ts +5 -49
- package/src/components/markdown.tsx +2 -5
- package/src/components/message-timeline.tsx +7 -59
- package/src/components/open-geni-links.tsx +0 -24
- package/src/components/session-conversation.tsx +20 -120
- package/src/index.ts +0 -7
- package/src/session-ui.ts +0 -7
- package/src/timeline/projection.ts +4 -54
- package/styles/compiled.css +0 -220
- package/dist/chat-interactive-block-VAGABN7J.js +0 -11
- package/dist/chunk-5CVXZA3Y.js +0 -292
- package/dist/chunk-5CVXZA3Y.js.map +0 -1
- package/dist/chunk-7B44WVGH.js.map +0 -1
- package/dist/chunk-ASCSKOWU.js.map +0 -1
- package/dist/chunk-QLG6W33X.js.map +0 -1
- package/dist/chunk-RAIQYITC.js +0 -1772
- package/dist/chunk-RAIQYITC.js.map +0 -1
- package/dist/chunk-SCOTPE2I.js +0 -589
- package/dist/chunk-SCOTPE2I.js.map +0 -1
- package/dist/chunk-UQUR5WG5.js.map +0 -1
- package/dist/chunk-WEHMPOXK.js +0 -39
- package/dist/chunk-WEHMPOXK.js.map +0 -1
- package/dist/chunk-XCHWDJ22.js +0 -107
- package/dist/chunk-XCHWDJ22.js.map +0 -1
- package/dist/chunk-XVYRQ4PK.js.map +0 -1
- package/dist/components/artifacts/artifact-chrome.d.ts +0 -120
- package/dist/components/artifacts/artifact-sandbox.d.ts +0 -27
- package/dist/components/artifacts/chat-interactive-block.d.ts +0 -29
- package/dist/components/artifacts/deferred-chat-media.d.ts +0 -15
- package/dist/components/artifacts/editable-artifact-view.d.ts +0 -46
- package/dist/components/artifacts/latest-task-runner.d.ts +0 -15
- package/dist/components/artifacts/session-artifact-viewer.d.ts +0 -39
- package/dist/components/artifacts/site-view.d.ts +0 -23
- package/dist/components/timeline-pill-geometry.d.ts +0 -6
- package/dist/components/timeline-pill-placement.d.ts +0 -18
- package/dist/computer-viewer-NB6O6BTV.js.map +0 -1
- package/dist/markdown-table-layout-QXSLK4BY.js.map +0 -1
- package/dist/timeline-pill-geometry-2G6EK47V.js +0 -73
- package/dist/timeline-pill-geometry-2G6EK47V.js.map +0 -1
- package/src/components/artifacts/artifact-chrome.tsx +0 -413
- package/src/components/artifacts/artifact-sandbox.tsx +0 -185
- package/src/components/artifacts/chat-interactive-block.tsx +0 -260
- package/src/components/artifacts/deferred-chat-media.tsx +0 -67
- package/src/components/artifacts/editable-artifact-view.tsx +0 -187
- package/src/components/artifacts/latest-task-runner.ts +0 -49
- package/src/components/artifacts/session-artifact-viewer.tsx +0 -376
- package/src/components/artifacts/site-view.tsx +0 -116
- package/src/components/timeline-pill-geometry.ts +0 -112
- package/src/components/timeline-pill-placement.ts +0 -81
- /package/dist/{browser-viewer-AJO7LMVE.js.map → browser-viewer-2E6R2Y4W.js.map} +0 -0
- /package/dist/{chunk-A4UJB2MM.js.map → chunk-SEEVCT36.js.map} +0 -0
- /package/dist/{chunk-OQVBTOBJ.js.map → chunk-USXVQACU.js.map} +0 -0
- /package/dist/{chat-interactive-block-VAGABN7J.js.map → computer-viewer-WMJE6OA3.js.map} +0 -0
- /package/dist/{latest-question-3HGQUI2E.js.map → latest-question-QB4EUCW5.js.map} +0 -0
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import { type ComponentProps, type ReactNode } from "react";
|
|
2
|
-
/**
|
|
3
|
-
* Shared chrome for artifact surfaces: the OpenGeni console and embedding hosts
|
|
4
|
-
* render the same header, controls, and load states. Class names use the
|
|
5
|
-
* package theme aliases, so the console's own Tailwind build and the compiled
|
|
6
|
-
* `.og-root` stylesheet resolve them identically.
|
|
7
|
-
*/
|
|
8
|
-
export type ArtifactKind = "document" | "spreadsheet" | "presentation" | "site" | "image" | "file";
|
|
9
|
-
declare const BUTTON_VARIANT: {
|
|
10
|
-
readonly ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50";
|
|
11
|
-
readonly outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-border dark:bg-input/30 dark:hover:bg-input/50";
|
|
12
|
-
};
|
|
13
|
-
declare const BUTTON_SIZE: {
|
|
14
|
-
readonly sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5";
|
|
15
|
-
readonly icon: "size-9";
|
|
16
|
-
readonly "icon-sm": "size-8";
|
|
17
|
-
};
|
|
18
|
-
export declare function ArtifactButton({ variant, size, className, type, ...props }: ComponentProps<"button"> & {
|
|
19
|
-
variant?: keyof typeof BUTTON_VARIANT;
|
|
20
|
-
size?: keyof typeof BUTTON_SIZE;
|
|
21
|
-
}): import("react").JSX.Element;
|
|
22
|
-
export declare function ArtifactBadge({ className, ...props }: ComponentProps<"span">): import("react").JSX.Element;
|
|
23
|
-
export declare const ArtifactSelect: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").SelectHTMLAttributes<HTMLSelectElement>, HTMLSelectElement>, "ref"> & import("react").RefAttributes<HTMLSelectElement>>;
|
|
24
|
-
export declare function artifactKindIcon(kind: ArtifactKind): ReactNode;
|
|
25
|
-
export declare function artifactKindSubtitle(kind: ArtifactKind): string;
|
|
26
|
-
type LoadErrorCopy = Readonly<Record<"unavailable" | "invalid" | "transient", {
|
|
27
|
-
title: string;
|
|
28
|
-
message: string;
|
|
29
|
-
}>>;
|
|
30
|
-
/**
|
|
31
|
-
* Every user-facing string in the artifact surfaces (inline Site preview, Site
|
|
32
|
-
* frame, viewer header and states). Hosts translate by passing a partial
|
|
33
|
-
* `labels` object; unspecified keys keep the English defaults.
|
|
34
|
-
*/
|
|
35
|
-
export type ArtifactLabels = Readonly<{
|
|
36
|
-
back: string;
|
|
37
|
-
close: string;
|
|
38
|
-
/** Header title and loading copy until an artifact's title is known. */
|
|
39
|
-
opening: string;
|
|
40
|
-
/** Header title when an artifact cannot be opened. */
|
|
41
|
-
artifact: string;
|
|
42
|
-
startingEditor: string;
|
|
43
|
-
kindSubtitle: (kind: ArtifactKind) => string;
|
|
44
|
-
live: string;
|
|
45
|
-
reloadSite: string;
|
|
46
|
-
openFullScreen: string;
|
|
47
|
-
editWithAgent: string;
|
|
48
|
-
editShort: string;
|
|
49
|
-
preview: string;
|
|
50
|
-
loadPreview: string;
|
|
51
|
-
loadSitePreview: string;
|
|
52
|
-
siteVersion: string;
|
|
53
|
-
savedVersion: string;
|
|
54
|
-
version: (revision: number) => string;
|
|
55
|
-
openSite: string;
|
|
56
|
-
loadingSite: string;
|
|
57
|
-
siteArchived: string;
|
|
58
|
-
siteUnpublished: string;
|
|
59
|
-
siteReferenceInvalid: string;
|
|
60
|
-
siteLoadFailed: string;
|
|
61
|
-
retry: string;
|
|
62
|
-
tryAgain: string;
|
|
63
|
-
toolCount: (count: number) => string;
|
|
64
|
-
toolsAvailable: (count: number) => string;
|
|
65
|
-
sourceFileCount: (count: number) => string;
|
|
66
|
-
viewingDisabled: {
|
|
67
|
-
title: string;
|
|
68
|
-
message: string;
|
|
69
|
-
};
|
|
70
|
-
editorsMissing: {
|
|
71
|
-
title: string;
|
|
72
|
-
message: string;
|
|
73
|
-
};
|
|
74
|
-
siteErrors: LoadErrorCopy;
|
|
75
|
-
editableErrors: LoadErrorCopy;
|
|
76
|
-
reference: (id: string) => string;
|
|
77
|
-
}>;
|
|
78
|
-
export declare const DEFAULT_ARTIFACT_LABELS: ArtifactLabels;
|
|
79
|
-
/** Translate every artifact surface below; nested providers override outer ones. */
|
|
80
|
-
export declare function ArtifactLabelsProvider({ labels, children, }: {
|
|
81
|
-
labels: Partial<ArtifactLabels> | undefined;
|
|
82
|
-
children: ReactNode;
|
|
83
|
-
}): import("react").JSX.Element;
|
|
84
|
-
export declare function useArtifactLabels(): ArtifactLabels;
|
|
85
|
-
/**
|
|
86
|
-
* One artifact header: optional Back, the kind tile, title (or a host-supplied
|
|
87
|
-
* title control), trailing actions, and optional Close. The console dock and
|
|
88
|
-
* embedded viewers share it.
|
|
89
|
-
*/
|
|
90
|
-
export declare function ArtifactViewerHeader({ kind, title, subtitle, titleSlot, onBack, backLabel, actions, onClose, closeLabel, }: Readonly<{
|
|
91
|
-
/** `null` while the host does not know the modality yet. */
|
|
92
|
-
kind: ArtifactKind | null;
|
|
93
|
-
title: string;
|
|
94
|
-
subtitle?: string | undefined;
|
|
95
|
-
/** Replaces the title text, for example with a picker. */
|
|
96
|
-
titleSlot?: ReactNode;
|
|
97
|
-
onBack?: (() => void) | undefined;
|
|
98
|
-
backLabel?: string | undefined;
|
|
99
|
-
actions?: ReactNode;
|
|
100
|
-
onClose?: (() => void) | undefined;
|
|
101
|
-
closeLabel?: string | undefined;
|
|
102
|
-
}>): import("react").JSX.Element;
|
|
103
|
-
export declare function ArtifactLoading({ label }: {
|
|
104
|
-
label: string;
|
|
105
|
-
}): import("react").JSX.Element;
|
|
106
|
-
export declare function ArtifactProblem({ view, onRetry, }: {
|
|
107
|
-
view: ArtifactLoadErrorView;
|
|
108
|
-
onRetry?: (() => void) | undefined;
|
|
109
|
-
}): import("react").JSX.Element;
|
|
110
|
-
export type ArtifactLoadErrorKind = "site" | "editable";
|
|
111
|
-
export type ArtifactLoadErrorView = Readonly<{
|
|
112
|
-
title: string;
|
|
113
|
-
message: string;
|
|
114
|
-
retryable: boolean;
|
|
115
|
-
correlationId?: string;
|
|
116
|
-
}>;
|
|
117
|
-
/** Site/editor load copy. Never surfaces raw OpenGeni API status text. */
|
|
118
|
-
export declare function artifactLoadErrorView(error: unknown, kind: ArtifactLoadErrorKind, labels?: ArtifactLabels): ArtifactLoadErrorView;
|
|
119
|
-
export declare function artifactLoadErrorMessage(view: ArtifactLoadErrorView, labels?: ArtifactLabels): string;
|
|
120
|
-
export {};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { type ReactNode } from "react";
|
|
2
|
-
import { type PublishedHtmlArtifactToolBridge } from "./published-html-artifact-frame.js";
|
|
3
|
-
export type ArtifactSandboxProps = {
|
|
4
|
-
html: string;
|
|
5
|
-
height?: number | undefined;
|
|
6
|
-
autoHeight?: boolean | undefined;
|
|
7
|
-
theme?: "light" | "dark" | undefined;
|
|
8
|
-
headerControls?: ReactNode | undefined;
|
|
9
|
-
title: string;
|
|
10
|
-
/** Hide the visible title/icon while retaining the accessible iframe title. */
|
|
11
|
-
showTitle?: boolean | undefined;
|
|
12
|
-
showLiveStatus?: boolean | undefined;
|
|
13
|
-
versionLabel?: string | undefined;
|
|
14
|
-
className?: string | undefined;
|
|
15
|
-
editDisabled?: boolean | undefined;
|
|
16
|
-
onEdit?: (() => void) | undefined;
|
|
17
|
-
toolBridge?: PublishedHtmlArtifactToolBridge | undefined;
|
|
18
|
-
connectedToolCount?: number | undefined;
|
|
19
|
-
sourceFileCount?: number | undefined;
|
|
20
|
-
fill?: boolean | undefined;
|
|
21
|
-
};
|
|
22
|
-
/**
|
|
23
|
-
* The Site/preview frame chrome shared by the console and embedding hosts:
|
|
24
|
-
* title, version and tool badges, live status, reload, and a full-screen mode
|
|
25
|
-
* that escapes the host's scroll containers through the modal top layer.
|
|
26
|
-
*/
|
|
27
|
-
export declare function ArtifactSandbox(props: ArtifactSandboxProps): import("react").JSX.Element;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { OpenGeniClient, ToolGatewayIdentity } from "@opengeni/sdk";
|
|
2
|
-
import { type ArtifactLabels } from "./artifact-chrome.js";
|
|
3
|
-
import type { PublishedHtmlArtifactToolBridge } from "./published-html-artifact-frame.js";
|
|
4
|
-
/** Reads a Site needs to render; the console client, the SDK client, or a proxy. */
|
|
5
|
-
export type SiteSnapshotClient = Pick<OpenGeniClient, "getWorkspaceArtifact" | "getWorkspaceArtifactHtml"> & Partial<Pick<OpenGeniClient, "getWorkspaceArtifactContent">>;
|
|
6
|
-
/** The exact saved Site a tool bridge is pinned to (absent for inline HTML). */
|
|
7
|
-
export type SiteToolScope = {
|
|
8
|
-
artifactId: string;
|
|
9
|
-
siteVersionId: string;
|
|
10
|
-
requestedTools: readonly ToolGatewayIdentity[];
|
|
11
|
-
};
|
|
12
|
-
/** Host-owned Site API access. Omit it and Sites render without workspace tools. */
|
|
13
|
-
export type SiteToolBridgeFactory = (site?: SiteToolScope) => PublishedHtmlArtifactToolBridge | undefined;
|
|
14
|
-
export type ChatInteractiveBlockProps = {
|
|
15
|
-
workspaceId: string;
|
|
16
|
-
kind: "html" | "site";
|
|
17
|
-
content: string;
|
|
18
|
-
client: SiteSnapshotClient;
|
|
19
|
-
toolBridge?: SiteToolBridgeFactory | undefined;
|
|
20
|
-
theme?: "light" | "dark" | undefined;
|
|
21
|
-
/** Translations for the preview's copy; defaults to English. */
|
|
22
|
-
labels?: Partial<ArtifactLabels> | undefined;
|
|
23
|
-
};
|
|
24
|
-
/**
|
|
25
|
-
* Inline preview for an assistant `opengeni-html` or `opengeni-site` fence, as
|
|
26
|
-
* the OpenGeni console renders it. "Open Site" goes through the nearest
|
|
27
|
-
* `resolveLink`, so a host decides where a Site opens.
|
|
28
|
-
*/
|
|
29
|
-
export declare function ChatInteractiveBlock({ labels, ...props }: ChatInteractiveBlockProps): import("react").JSX.Element;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { type ReactNode } from "react";
|
|
2
|
-
/**
|
|
3
|
-
* Reserve the chat slot before starting expensive media work. Activation is
|
|
4
|
-
* one-way: scrolling away must not discard an interactive preview's state.
|
|
5
|
-
* The timeline parks at its initial tip in layout effects before this observer
|
|
6
|
-
* is attached, so historical previews above the entry viewport stay dormant.
|
|
7
|
-
*/
|
|
8
|
-
export declare function DeferredChatMedia({ children, height, label, actionLabel, }: {
|
|
9
|
-
children: ReactNode;
|
|
10
|
-
height: number;
|
|
11
|
-
/** What is loading, as in "Load {label}". */
|
|
12
|
-
label?: string | undefined;
|
|
13
|
-
/** The complete (translated) activation label; overrides `label`. */
|
|
14
|
-
actionLabel?: string | undefined;
|
|
15
|
-
}): import("react").JSX.Element;
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import type { EditableArtifactResource } from "@opengeni/sdk/artifacts";
|
|
2
|
-
import { type CreateBrowserEditableArtifactSessionOptions, type EditableArtifactBrowserRuntime, type EditableArtifactCacheAuthority } from "@opengeni/sdk/editable-artifacts";
|
|
3
|
-
import { type ArtifactLoadErrorView } from "./artifact-chrome.js";
|
|
4
|
-
/**
|
|
5
|
-
* The browser kernels an editor needs, one per modality, plus the host-built
|
|
6
|
-
* Worker URL (for Vite: `@opengeni/sdk/editable-artifacts/worker?worker&url`).
|
|
7
|
-
* Kernels come from `@opengeni/artifact-kernel-wasm-{document,spreadsheet,presentation}`.
|
|
8
|
-
*/
|
|
9
|
-
export type EditableArtifactRuntimes = Readonly<{
|
|
10
|
-
document: Omit<EditableArtifactBrowserRuntime, "workerUrl" | "workerFactory">;
|
|
11
|
-
spreadsheet: Omit<EditableArtifactBrowserRuntime, "workerUrl" | "workerFactory">;
|
|
12
|
-
presentation: Omit<EditableArtifactBrowserRuntime, "workerUrl" | "workerFactory">;
|
|
13
|
-
workerUrl: string;
|
|
14
|
-
applicationOrigin?: string | undefined;
|
|
15
|
-
/** Loopback development only. */
|
|
16
|
-
allowInsecureDevelopmentAssets?: boolean | undefined;
|
|
17
|
-
}>;
|
|
18
|
-
/** Everything needed to open one artifact for the current principal. */
|
|
19
|
-
export type OpenedEditableArtifact = Readonly<{
|
|
20
|
-
artifact: EditableArtifactResource;
|
|
21
|
-
authority: EditableArtifactCacheAuthority;
|
|
22
|
-
replicaId: string;
|
|
23
|
-
}>;
|
|
24
|
-
export type EditableArtifactViewProps = Readonly<{
|
|
25
|
-
/** Absolute API (or session proxy) base the live transport talks to. */
|
|
26
|
-
baseUrl: URL;
|
|
27
|
-
workspaceId: string;
|
|
28
|
-
artifactId: string;
|
|
29
|
-
/** Resolve metadata, cache authority, and replica; called again on retry. */
|
|
30
|
-
open: (signal: AbortSignal) => Promise<OpenedEditableArtifact>;
|
|
31
|
-
runtimes: EditableArtifactRuntimes;
|
|
32
|
-
transport?: CreateBrowserEditableArtifactSessionOptions["transport"];
|
|
33
|
-
/** Show the editor's own title header (hosts with their own header hide it). */
|
|
34
|
-
showHeader?: boolean | undefined;
|
|
35
|
-
/** Re-open when this changes (for example the host's credential version). */
|
|
36
|
-
authorityKey?: string | undefined;
|
|
37
|
-
describeError?: ((error: unknown) => ArtifactLoadErrorView) | undefined;
|
|
38
|
-
onTitle?: ((title: string) => void) | undefined;
|
|
39
|
-
/** Loading copy; defaults to the `opening` label. */
|
|
40
|
-
loadingLabel?: string | undefined;
|
|
41
|
-
}>;
|
|
42
|
-
/**
|
|
43
|
-
* One editable document, spreadsheet, or presentation with its first-party
|
|
44
|
-
* editor. The console dock/page and embedding hosts supply only data access.
|
|
45
|
-
*/
|
|
46
|
-
export declare function EditableArtifactView({ baseUrl, workspaceId, artifactId, open, runtimes, transport, showHeader, authorityKey, describeError, onTitle, loadingLabel, }: EditableArtifactViewProps): import("react").JSX.Element;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Runs one task at a time; a task scheduled while another runs replaces any
|
|
3
|
-
* task still waiting, so only the newest request starts next. Editors use it
|
|
4
|
-
* for projection loads: replaying a long history emits one revision per
|
|
5
|
-
* committed transaction, and composing a projection for each of them at once
|
|
6
|
-
* would overrun the artifact Worker's bounded request queue.
|
|
7
|
-
*/
|
|
8
|
-
export declare function createLatestTaskRunner(): (task: () => Promise<void>) => void;
|
|
9
|
-
/**
|
|
10
|
-
* One runner per artifact session. A composition still pending on a replaced
|
|
11
|
-
* session (for example one whose Worker stopped answering) must never hold up
|
|
12
|
-
* the next session's first load, so the runner is scoped to the session object
|
|
13
|
-
* rather than to the component.
|
|
14
|
-
*/
|
|
15
|
-
export declare function useLatestTaskRunner(session: object): (task: () => Promise<void>) => void;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { type ClientOverride } from "../../session-context.js";
|
|
2
|
-
import { type ArtifactLabels } from "./artifact-chrome.js";
|
|
3
|
-
import { type EditableArtifactRuntimes } from "./editable-artifact-view.js";
|
|
4
|
-
import type { SiteToolBridgeFactory } from "./chat-interactive-block.js";
|
|
5
|
-
/** An artifact opened from a session: the targets agent links and Site previews name. */
|
|
6
|
-
export type SessionArtifactTarget = Readonly<{
|
|
7
|
-
kind: "editable-artifact";
|
|
8
|
-
artifactId: string;
|
|
9
|
-
title?: string | undefined;
|
|
10
|
-
} | {
|
|
11
|
-
kind: "site";
|
|
12
|
-
artifactId: string;
|
|
13
|
-
title?: string | undefined;
|
|
14
|
-
}>;
|
|
15
|
-
/** Every string the viewer shows, including its Site frame and states. */
|
|
16
|
-
export type SessionArtifactViewerLabels = Partial<ArtifactLabels>;
|
|
17
|
-
export type SessionArtifactViewerProps = ClientOverride & Readonly<{
|
|
18
|
-
/** The conversation the artifact belongs to; the proxy only serves its artifacts. */
|
|
19
|
-
sessionId: string;
|
|
20
|
-
target: SessionArtifactTarget;
|
|
21
|
-
onClose: () => void;
|
|
22
|
-
/** Show a Back control, for example to return to the conversation on phones. */
|
|
23
|
-
onBack?: (() => void) | undefined;
|
|
24
|
-
/** Browser kernels and Worker for documents, spreadsheets, and presentations. */
|
|
25
|
-
editableRuntimes?: EditableArtifactRuntimes | undefined;
|
|
26
|
-
theme?: "light" | "dark" | undefined;
|
|
27
|
-
/** Host-owned Site API access; omit it and Sites render without workspace tools. */
|
|
28
|
-
siteToolBridge?: SiteToolBridgeFactory | undefined;
|
|
29
|
-
labels?: SessionArtifactViewerLabels | undefined;
|
|
30
|
-
className?: string | undefined;
|
|
31
|
-
}>;
|
|
32
|
-
/**
|
|
33
|
-
* A host-mountable viewer for one editable artifact or Site from a session,
|
|
34
|
-
* with its own header (title, Back, Close). Mount it in any sized container
|
|
35
|
-
* (a side panel, a sheet); it fills it. Data flows through the provider's
|
|
36
|
-
* client and `createSessionProxyHandler({ artifacts: true })`, scoped to
|
|
37
|
-
* `sessionId`.
|
|
38
|
-
*/
|
|
39
|
-
export declare function SessionArtifactViewer({ labels, ...props }: SessionArtifactViewerProps): import("react").JSX.Element;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { SiteSnapshotClient, SiteToolBridgeFactory } from "./chat-interactive-block.js";
|
|
2
|
-
export type SiteViewProps = {
|
|
3
|
-
client: SiteSnapshotClient;
|
|
4
|
-
workspaceId: string;
|
|
5
|
-
siteId: string;
|
|
6
|
-
/** Host-owned Site API access. Omit it and the Site renders without workspace tools. */
|
|
7
|
-
toolBridge?: SiteToolBridgeFactory | undefined;
|
|
8
|
-
theme?: "light" | "dark" | undefined;
|
|
9
|
-
/** Shown instead of the archived notice; the console links to its full page. */
|
|
10
|
-
archivedMessage?: string | undefined;
|
|
11
|
-
/** Show the Site title in the frame bar; hide it under a host header that already does. */
|
|
12
|
-
showTitle?: boolean | undefined;
|
|
13
|
-
/** Loading copy; defaults to "Loading Site…". */
|
|
14
|
-
loadingLabel?: string | undefined;
|
|
15
|
-
/** Called with the loaded title, for a host header. */
|
|
16
|
-
onTitle?: ((title: string) => void) | undefined;
|
|
17
|
-
className?: string | undefined;
|
|
18
|
-
};
|
|
19
|
-
/**
|
|
20
|
-
* A published Site filling its container: the console's session dock and an
|
|
21
|
-
* embedding host's artifact viewer render the same view.
|
|
22
|
-
*/
|
|
23
|
-
export declare function SiteView({ client, workspaceId, siteId, toolBridge, theme, archivedMessage, showTitle, loadingLabel, onTitle, className, }: SiteViewProps): import("react").JSX.Element;
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { TimelinePillPlacement } from "./timeline-pill-placement.js";
|
|
2
|
-
/**
|
|
3
|
-
* Hit-testing for useTimelinePillPlacement, loaded only once a pill shows so it
|
|
4
|
-
* stays out of a session's first load.
|
|
5
|
-
*/
|
|
6
|
-
export declare function choosePlacement(pill: HTMLElement, frame: HTMLElement, scroller: HTMLElement, preference: readonly TimelinePillPlacement[], current: TimelinePillPlacement): TimelinePillPlacement;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { type RefObject } from "react";
|
|
2
|
-
/** Where a floating timeline pill sits along its edge of the conversation. */
|
|
3
|
-
export type TimelinePillPlacement = "start" | "center" | "end";
|
|
4
|
-
/**
|
|
5
|
-
* Floating pills (Jump to latest, Latest question) sit over the scrolling
|
|
6
|
-
* conversation. Slide one sideways, never up or down, when its spot would cover
|
|
7
|
-
* a control: a link, a button, or the label and chevron of a full-width row
|
|
8
|
-
* such as the active turn's "Working" header. Plain prose may sit under a pill;
|
|
9
|
-
* controls may not. Only the pill moves — the scroller's size, padding, and
|
|
10
|
-
* scroll position never change — so timeline anchoring stays untouched.
|
|
11
|
-
*/
|
|
12
|
-
export declare function useTimelinePillPlacement({ pillRef, scrollerRef, active, preference, }: {
|
|
13
|
-
pillRef: RefObject<HTMLElement | null>;
|
|
14
|
-
scrollerRef: RefObject<HTMLElement | null>;
|
|
15
|
-
active: boolean;
|
|
16
|
-
/** Placements in order of preference; the first is the resting position. */
|
|
17
|
-
preference: readonly TimelinePillPlacement[];
|
|
18
|
-
}): TimelinePillPlacement;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/markdown-table-layout.ts"],"sourcesContent":["export function markdownTableWidth({\n columnLeft,\n columnWidth,\n contentLeft,\n contentRight,\n preferredWidth,\n}: {\n columnLeft: number;\n columnWidth: number;\n contentLeft: number;\n contentRight: number;\n preferredWidth: number;\n}): number {\n const center = columnLeft + columnWidth / 2;\n const available = 2 * Math.min(center - contentLeft, contentRight - center);\n return Math.max(columnWidth, Math.min(preferredWidth, available));\n}\n\nfunction measurementCopy(source: Node, document: Document): Node {\n if (source.nodeType === Node.ELEMENT_NODE) {\n const element = source as Element;\n // Inert prevents focus, not custom-element construction, media loading or\n // embedded browsing contexts. Do not clone those host-rendered surfaces.\n if (\n element.localName.includes(\"-\") ||\n [\"iframe\", \"object\", \"embed\", \"video\", \"audio\", \"canvas\", \"script\"].includes(\n element.localName,\n )\n ) {\n const bounds = element.getBoundingClientRect();\n const placeholder = document.createElement(\"span\");\n placeholder.style.display = \"inline-block\";\n placeholder.style.width = `${bounds.width}px`;\n placeholder.style.height = `${bounds.height}px`;\n return placeholder;\n }\n }\n const copy = document.importNode(source, false);\n if (copy.nodeType === Node.ELEMENT_NODE) {\n const element = copy as Element;\n element.removeAttribute(\"id\");\n for (const attribute of [...element.attributes]) {\n if (attribute.name.startsWith(\"on\")) element.removeAttribute(attribute.name);\n }\n }\n for (const child of source.childNodes) copy.appendChild(measurementCopy(child, document));\n return copy;\n}\n\n/** Loaded only for assistant tables. Keep prose and nested scroll owners intact. */\nexport function observeMarkdownTableLayout(wrapper: HTMLDivElement, table: HTMLTableElement) {\n const body = wrapper.parentElement;\n const scroller = body\n ?.closest(\"[data-og-wide-table-message]\")\n ?.closest<HTMLElement>(\"[data-og-timeline-scroller]\");\n if (!body?.classList.contains(\"og-markdown-body\") || !scroller) return;\n\n // Build the static copy without a browsing context before inserting its probe.\n const measurementDocument = table.ownerDocument.implementation.createHTMLDocument(\"\");\n let width: number | null = null;\n const reset = () => {\n width = null;\n wrapper.style.width = \"\";\n wrapper.style.maxWidth = \"\";\n wrapper.style.marginInline = \"\";\n };\n const measure = () => {\n // Intermediate clipped/scrollable surfaces own their own content bounds.\n for (\n let ancestor: HTMLElement | null = body;\n ancestor && ancestor !== scroller;\n ancestor = ancestor.parentElement\n ) {\n if (getComputedStyle(ancestor).overflowX !== \"visible\") {\n reset();\n return;\n }\n }\n const column = body.getBoundingClientRect();\n const panel = scroller.getBoundingClientRect();\n const panelStyle = getComputedStyle(scroller);\n const left = panel.left + scroller.clientLeft + parseFloat(panelStyle.paddingLeft);\n const right =\n panel.left + scroller.clientLeft + scroller.clientWidth - parseFloat(panelStyle.paddingRight);\n\n // Even a temporary max-content width on the live table changes its height\n // during forced layout. Browser scroll anchoring can retain that displacement\n // after the width is restored. Measure a copy without touching live geometry.\n const probe = table.ownerDocument.createElement(\"div\");\n probe.setAttribute(\"aria-hidden\", \"true\");\n probe.inert = true;\n // A zero-sized, contained box cannot extend the scroller's overflow area,\n // including inside transformed ancestors. Keep the same inherited styling.\n probe.style.cssText =\n \"position:absolute;width:0;height:0;overflow:hidden;contain:layout size paint;visibility:hidden;pointer-events:none\";\n const copy = measurementCopy(table, measurementDocument) as HTMLTableElement;\n copy.style.width = \"max-content\";\n probe.append(copy);\n let preferred: number;\n try {\n table.parentElement!.append(probe);\n preferred = copy.getBoundingClientRect().width;\n } finally {\n probe.remove();\n }\n const next = markdownTableWidth({\n columnLeft: column.left,\n columnWidth: column.width,\n contentLeft: left,\n contentRight: right,\n preferredWidth: preferred,\n });\n if (width !== null && Math.abs(width - next) < 0.5) return;\n width = next;\n wrapper.style.width = `${width}px`;\n wrapper.style.maxWidth = \"none\";\n wrapper.style.marginInline = `calc((100% - ${width}px) / 2)`;\n };\n\n measure();\n const observer = typeof ResizeObserver === \"undefined\" ? undefined : new ResizeObserver(measure);\n observer?.observe(scroller);\n observer?.observe(body);\n observer?.observe(table);\n return {\n measure,\n disconnect: () => {\n observer?.disconnect();\n reset();\n },\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
// src/components/timeline-pill-geometry.ts
|
|
2
|
-
var INTERACTIVE = 'a[href], button, input, select, textarea, summary, [role="button"], [role="link"], [role="menuitem"], [role="tab"], [role="switch"], [role="checkbox"], [contenteditable="true"]';
|
|
3
|
-
var ROW_WIDTH_RATIO = 0.8;
|
|
4
|
-
function choosePlacement(pill, frame, scroller, preference, current) {
|
|
5
|
-
const pillRect = pill.getBoundingClientRect();
|
|
6
|
-
const frameRect = frame.getBoundingClientRect();
|
|
7
|
-
const view = scroller.getBoundingClientRect();
|
|
8
|
-
if (pillRect.width === 0 || view.width === 0) return current;
|
|
9
|
-
const inset = Math.max(0, pillRect.left - frameRect.left, frameRect.right - pillRect.right);
|
|
10
|
-
const gutter = Math.min(inset, parseFloat(getComputedStyle(scroller).paddingLeft) || 16);
|
|
11
|
-
const left = (placement) => placement === "start" ? frameRect.left + gutter : placement === "end" ? frameRect.right - gutter - pillRect.width : frameRect.left + (frameRect.width - pillRect.width) / 2;
|
|
12
|
-
const collisions = (placement) => countCollisions(
|
|
13
|
-
pill,
|
|
14
|
-
scroller,
|
|
15
|
-
view,
|
|
16
|
-
left(placement),
|
|
17
|
-
pillRect.top,
|
|
18
|
-
pillRect.width,
|
|
19
|
-
pillRect.height
|
|
20
|
-
);
|
|
21
|
-
if (collisions(current) === 0) return current;
|
|
22
|
-
let best = current;
|
|
23
|
-
let fewest = Number.POSITIVE_INFINITY;
|
|
24
|
-
for (const candidate of preference) {
|
|
25
|
-
const count = candidate === current ? collisions(current) : collisions(candidate);
|
|
26
|
-
if (count === 0) return candidate;
|
|
27
|
-
if (count < fewest) {
|
|
28
|
-
fewest = count;
|
|
29
|
-
best = candidate;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return best;
|
|
33
|
-
}
|
|
34
|
-
function countCollisions(pill, scroller, view, left, top, width, height) {
|
|
35
|
-
const document = scroller.ownerDocument;
|
|
36
|
-
let count = 0;
|
|
37
|
-
for (const fx of [0.06, 0.3, 0.5, 0.7, 0.94]) {
|
|
38
|
-
for (const fy of [0.2, 0.5, 0.8]) {
|
|
39
|
-
const x = left + width * fx;
|
|
40
|
-
const y = top + height * fy;
|
|
41
|
-
if (x < view.left || x > view.right || y < view.top || y > view.bottom) continue;
|
|
42
|
-
if (coversControl(document.elementsFromPoint(x, y), pill, scroller, view, x, y)) count += 1;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return count;
|
|
46
|
-
}
|
|
47
|
-
function coversControl(stack, pill, scroller, view, x, y) {
|
|
48
|
-
for (const element of stack) {
|
|
49
|
-
if (pill.contains(element)) continue;
|
|
50
|
-
if (!scroller.contains(element) || element === scroller) return false;
|
|
51
|
-
const control = element.closest(INTERACTIVE);
|
|
52
|
-
if (!control || !scroller.contains(control)) return false;
|
|
53
|
-
if (control.getBoundingClientRect().width < view.width * ROW_WIDTH_RATIO) return true;
|
|
54
|
-
if (element.closest("svg, img, canvas, video")) return true;
|
|
55
|
-
return textUnderPoint(element, x, y);
|
|
56
|
-
}
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
function textUnderPoint(element, x, y) {
|
|
60
|
-
const range = element.ownerDocument.createRange();
|
|
61
|
-
for (const node of element.childNodes) {
|
|
62
|
-
if (node.nodeType !== Node.TEXT_NODE || !node.textContent?.trim()) continue;
|
|
63
|
-
range.selectNodeContents(node);
|
|
64
|
-
for (const rect of range.getClientRects()) {
|
|
65
|
-
if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) return true;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
export {
|
|
71
|
-
choosePlacement
|
|
72
|
-
};
|
|
73
|
-
//# sourceMappingURL=timeline-pill-geometry-2G6EK47V.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/timeline-pill-geometry.ts"],"sourcesContent":["import type { TimelinePillPlacement } from \"./timeline-pill-placement\";\n\nconst INTERACTIVE =\n 'a[href], button, input, select, textarea, summary, [role=\"button\"], [role=\"link\"], [role=\"menuitem\"], [role=\"tab\"], [role=\"switch\"], [role=\"checkbox\"], [contenteditable=\"true\"]';\n\n/** A control this wide is a row (a disclosure header); only what it draws counts. */\nconst ROW_WIDTH_RATIO = 0.8;\n\n/**\n * Hit-testing for useTimelinePillPlacement, loaded only once a pill shows so it\n * stays out of a session's first load.\n */\nexport function choosePlacement(\n pill: HTMLElement,\n frame: HTMLElement,\n scroller: HTMLElement,\n preference: readonly TimelinePillPlacement[],\n current: TimelinePillPlacement,\n): TimelinePillPlacement {\n const pillRect = pill.getBoundingClientRect();\n const frameRect = frame.getBoundingClientRect();\n const view = scroller.getBoundingClientRect();\n if (pillRect.width === 0 || view.width === 0) return current;\n const inset = Math.max(0, pillRect.left - frameRect.left, frameRect.right - pillRect.right);\n const gutter = Math.min(inset, parseFloat(getComputedStyle(scroller).paddingLeft) || 16);\n const left = (placement: TimelinePillPlacement) =>\n placement === \"start\"\n ? frameRect.left + gutter\n : placement === \"end\"\n ? frameRect.right - gutter - pillRect.width\n : frameRect.left + (frameRect.width - pillRect.width) / 2;\n const collisions = (placement: TimelinePillPlacement) =>\n countCollisions(\n pill,\n scroller,\n view,\n left(placement),\n pillRect.top,\n pillRect.width,\n pillRect.height,\n );\n // Stay put while the current spot is clear, so the pill does not wander.\n if (collisions(current) === 0) return current;\n let best = current;\n let fewest = Number.POSITIVE_INFINITY;\n for (const candidate of preference) {\n const count = candidate === current ? collisions(current) : collisions(candidate);\n if (count === 0) return candidate;\n if (count < fewest) {\n fewest = count;\n best = candidate;\n }\n }\n return best;\n}\n\nfunction countCollisions(\n pill: HTMLElement,\n scroller: HTMLElement,\n view: DOMRect,\n left: number,\n top: number,\n width: number,\n height: number,\n): number {\n const document = scroller.ownerDocument;\n let count = 0;\n for (const fx of [0.06, 0.3, 0.5, 0.7, 0.94]) {\n for (const fy of [0.2, 0.5, 0.8]) {\n const x = left + width * fx;\n const y = top + height * fy;\n if (x < view.left || x > view.right || y < view.top || y > view.bottom) continue;\n if (coversControl(document.elementsFromPoint(x, y), pill, scroller, view, x, y)) count += 1;\n }\n }\n return count;\n}\n\nfunction coversControl(\n stack: Element[],\n pill: HTMLElement,\n scroller: HTMLElement,\n view: DOMRect,\n x: number,\n y: number,\n): boolean {\n for (const element of stack) {\n if (pill.contains(element)) continue;\n if (!scroller.contains(element) || element === scroller) return false;\n const control = element.closest(INTERACTIVE);\n if (!control || !scroller.contains(control)) return false;\n // A compact control (a link, an icon button) is covered anywhere on its box.\n if (control.getBoundingClientRect().width < view.width * ROW_WIDTH_RATIO) return true;\n // A full-width row (a disclosure header) only where it draws something: an\n // icon or the glyphs of its label, never its empty background.\n if (element.closest(\"svg, img, canvas, video\")) return true;\n return textUnderPoint(element, x, y);\n }\n return false;\n}\n\nfunction textUnderPoint(element: Element, x: number, y: number): boolean {\n const range = element.ownerDocument.createRange();\n for (const node of element.childNodes) {\n if (node.nodeType !== Node.TEXT_NODE || !node.textContent?.trim()) continue;\n range.selectNodeContents(node);\n for (const rect of range.getClientRects()) {\n if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) return true;\n }\n }\n return false;\n}\n"],"mappings":";AAEA,IAAM,cACJ;AAGF,IAAM,kBAAkB;AAMjB,SAAS,gBACd,MACA,OACA,UACA,YACA,SACuB;AACvB,QAAM,WAAW,KAAK,sBAAsB;AAC5C,QAAM,YAAY,MAAM,sBAAsB;AAC9C,QAAM,OAAO,SAAS,sBAAsB;AAC5C,MAAI,SAAS,UAAU,KAAK,KAAK,UAAU,EAAG,QAAO;AACrD,QAAM,QAAQ,KAAK,IAAI,GAAG,SAAS,OAAO,UAAU,MAAM,UAAU,QAAQ,SAAS,KAAK;AAC1F,QAAM,SAAS,KAAK,IAAI,OAAO,WAAW,iBAAiB,QAAQ,EAAE,WAAW,KAAK,EAAE;AACvF,QAAM,OAAO,CAAC,cACZ,cAAc,UACV,UAAU,OAAO,SACjB,cAAc,QACZ,UAAU,QAAQ,SAAS,SAAS,QACpC,UAAU,QAAQ,UAAU,QAAQ,SAAS,SAAS;AAC9D,QAAM,aAAa,CAAC,cAClB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAK,SAAS;AAAA,IACd,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,EACX;AAEF,MAAI,WAAW,OAAO,MAAM,EAAG,QAAO;AACtC,MAAI,OAAO;AACX,MAAI,SAAS,OAAO;AACpB,aAAW,aAAa,YAAY;AAClC,UAAM,QAAQ,cAAc,UAAU,WAAW,OAAO,IAAI,WAAW,SAAS;AAChF,QAAI,UAAU,EAAG,QAAO;AACxB,QAAI,QAAQ,QAAQ;AAClB,eAAS;AACT,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,gBACP,MACA,UACA,MACA,MACA,KACA,OACA,QACQ;AACR,QAAM,WAAW,SAAS;AAC1B,MAAI,QAAQ;AACZ,aAAW,MAAM,CAAC,MAAM,KAAK,KAAK,KAAK,IAAI,GAAG;AAC5C,eAAW,MAAM,CAAC,KAAK,KAAK,GAAG,GAAG;AAChC,YAAM,IAAI,OAAO,QAAQ;AACzB,YAAM,IAAI,MAAM,SAAS;AACzB,UAAI,IAAI,KAAK,QAAQ,IAAI,KAAK,SAAS,IAAI,KAAK,OAAO,IAAI,KAAK,OAAQ;AACxE,UAAI,cAAc,SAAS,kBAAkB,GAAG,CAAC,GAAG,MAAM,UAAU,MAAM,GAAG,CAAC,EAAG,UAAS;AAAA,IAC5F;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,cACP,OACA,MACA,UACA,MACA,GACA,GACS;AACT,aAAW,WAAW,OAAO;AAC3B,QAAI,KAAK,SAAS,OAAO,EAAG;AAC5B,QAAI,CAAC,SAAS,SAAS,OAAO,KAAK,YAAY,SAAU,QAAO;AAChE,UAAM,UAAU,QAAQ,QAAQ,WAAW;AAC3C,QAAI,CAAC,WAAW,CAAC,SAAS,SAAS,OAAO,EAAG,QAAO;AAEpD,QAAI,QAAQ,sBAAsB,EAAE,QAAQ,KAAK,QAAQ,gBAAiB,QAAO;AAGjF,QAAI,QAAQ,QAAQ,yBAAyB,EAAG,QAAO;AACvD,WAAO,eAAe,SAAS,GAAG,CAAC;AAAA,EACrC;AACA,SAAO;AACT;AAEA,SAAS,eAAe,SAAkB,GAAW,GAAoB;AACvE,QAAM,QAAQ,QAAQ,cAAc,YAAY;AAChD,aAAW,QAAQ,QAAQ,YAAY;AACrC,QAAI,KAAK,aAAa,KAAK,aAAa,CAAC,KAAK,aAAa,KAAK,EAAG;AACnE,UAAM,mBAAmB,IAAI;AAC7B,eAAW,QAAQ,MAAM,eAAe,GAAG;AACzC,UAAI,KAAK,KAAK,QAAQ,KAAK,KAAK,SAAS,KAAK,KAAK,OAAO,KAAK,KAAK,OAAQ,QAAO;AAAA,IACrF;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
|