@asgard-js/react 0.2.6 → 0.2.7
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 +174 -0
- package/dist/components/chatbot/chatbot-body/conversation-message-renderer.d.ts.map +1 -1
- package/dist/components/chatbot/chatbot.d.ts.map +1 -1
- package/dist/context/asgard-template-context.d.ts +22 -2
- package/dist/context/asgard-template-context.d.ts.map +1 -1
- package/dist/index.js +2040 -2020
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -312,6 +312,7 @@ config: {
|
|
|
312
312
|
- **onTemplateBtnClick?**: `(payload: Record<string, unknown>, eventName: string, raw: string) => void` - Callback for EMIT button actions. See [EMIT Action](#emit-action) section for details.
|
|
313
313
|
- **messageActions?**: `(message: ConversationBotMessage) => MessageActionConfig[]` - Function to define which action buttons to display for each bot message. Returns an array of `{ id: string, label: string }` objects. See [Message Actions](#message-actions) section for details.
|
|
314
314
|
- **onMessageAction?**: `(actionId: string, message: ConversationBotMessage) => void` - Callback when a message action button is clicked. Receives the action ID and the associated bot message.
|
|
315
|
+
- **renderMessageContent?**: `(props: MessageContentRendererProps) => ReactNode` - Custom renderer for message content. Allows customizing how messages are rendered based on message properties. See [Custom Message Renderer](#custom-message-renderer) section for details.
|
|
315
316
|
- **onSseMessage**: `(response: SseResponse, ctx: AsgardServiceContextValue) => void` - Callback function when SSE message is received. It would be helpful if using with the ref to provide some context and conversation data and do some proactively actions like sending messages to the bot.
|
|
316
317
|
- **ref**: `ForwardedRef<ChatbotRef>` - Forwarded ref to access the chatbot instance. It can be used to access the chatbot instance and do some actions like sending messages to the bot. ChatbotRef extends the ref of the chatbot instance and provides some additional methods like `serviceContext.sendMessage` to interact with the chatbot instance.
|
|
317
318
|
|
|
@@ -825,6 +826,179 @@ messageActions={(message) => {
|
|
|
825
826
|
}}
|
|
826
827
|
```
|
|
827
828
|
|
|
829
|
+
<a id="custom-message-renderer"></a>
|
|
830
|
+
<br/>
|
|
831
|
+
|
|
832
|
+
### Custom Message Renderer
|
|
833
|
+
|
|
834
|
+
The `renderMessageContent` prop allows you to customize how messages are rendered based on message type, payload, or other conditions. This is useful for implementing custom message cards, special UI treatments, or integrating with your application's design system.
|
|
835
|
+
|
|
836
|
+
#### MessageContentRendererProps Interface
|
|
837
|
+
|
|
838
|
+
```typescript
|
|
839
|
+
interface MessageContentRendererProps {
|
|
840
|
+
/** The original message object */
|
|
841
|
+
message: ConversationMessage;
|
|
842
|
+
/** Function to render the default message content */
|
|
843
|
+
renderDefaultContent: () => ReactNode;
|
|
844
|
+
/** Container component that wraps custom content with Avatar for bot messages */
|
|
845
|
+
MessageContainer: React.FC<{ children: ReactNode }>;
|
|
846
|
+
}
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
#### Why MessageContainer?
|
|
850
|
+
|
|
851
|
+
When you use `renderMessageContent` to customize rendering, it completely replaces the default Template. This means **Avatar will not display automatically**, because Avatar is part of the default Template.
|
|
852
|
+
|
|
853
|
+
Use `MessageContainer` to wrap your custom content and automatically get:
|
|
854
|
+
|
|
855
|
+
- **Bot messages**: Avatar + timestamp
|
|
856
|
+
- **User messages**: Proper right-aligned styling
|
|
857
|
+
|
|
858
|
+
#### Understanding payload
|
|
859
|
+
|
|
860
|
+
The `payload` is custom data set by the backend Bot Provider when responding to messages. The SDK passes it directly to `renderMessageContent` without modification.
|
|
861
|
+
|
|
862
|
+
**Backend response example (Bot Provider):**
|
|
863
|
+
|
|
864
|
+
```json
|
|
865
|
+
{
|
|
866
|
+
"template": { "type": "text", "text": "Here is your order" },
|
|
867
|
+
"payload": {
|
|
868
|
+
"customType": "order_card",
|
|
869
|
+
"orderId": "#ORD-2024-001234",
|
|
870
|
+
"items": [{ "name": "iPhone 15 Pro", "price": 42900 }]
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
```
|
|
874
|
+
|
|
875
|
+
**Frontend renders based on payload:**
|
|
876
|
+
|
|
877
|
+
```typescript
|
|
878
|
+
const payload = message.message.payload as { customType?: string };
|
|
879
|
+
|
|
880
|
+
if (payload?.customType === 'order_card') {
|
|
881
|
+
return <OrderCard order={payload} />;
|
|
882
|
+
}
|
|
883
|
+
```
|
|
884
|
+
|
|
885
|
+
> **Note:** `customType` is a convention, not a requirement. You can define your own payload structure - just ensure the frontend and backend use the same format.
|
|
886
|
+
|
|
887
|
+
#### Basic Usage
|
|
888
|
+
|
|
889
|
+
```typescript
|
|
890
|
+
import { Chatbot, MessageContentRendererProps } from '@asgard-js/react';
|
|
891
|
+
|
|
892
|
+
<Chatbot
|
|
893
|
+
config={config}
|
|
894
|
+
customChannelId="your-channel-id"
|
|
895
|
+
renderMessageContent={props => {
|
|
896
|
+
const { message, renderDefaultContent, MessageContainer } = props;
|
|
897
|
+
|
|
898
|
+
// Customize bot messages with specific payload types
|
|
899
|
+
if (message.type === 'bot') {
|
|
900
|
+
const payload = message.message.payload as { customType?: string };
|
|
901
|
+
|
|
902
|
+
if (payload?.customType === 'order_card') {
|
|
903
|
+
// Use MessageContainer to wrap custom content with Avatar
|
|
904
|
+
return (
|
|
905
|
+
<MessageContainer>
|
|
906
|
+
<OrderCard order={payload} />
|
|
907
|
+
</MessageContainer>
|
|
908
|
+
);
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
// Use default rendering for all other messages
|
|
913
|
+
return renderDefaultContent();
|
|
914
|
+
}}
|
|
915
|
+
/>;
|
|
916
|
+
```
|
|
917
|
+
|
|
918
|
+
#### Using MessageContainer
|
|
919
|
+
|
|
920
|
+
The `MessageContainer` component is essential for maintaining consistent styling with the default messages:
|
|
921
|
+
|
|
922
|
+
- **For bot messages**: Wraps your content with the bot's Avatar and proper message styling (including timestamp and quick replies)
|
|
923
|
+
- **For user messages**: Applies proper right-aligned styling
|
|
924
|
+
- **For other message types**: Returns children directly
|
|
925
|
+
|
|
926
|
+
**With MessageContainer** (recommended for custom bot messages):
|
|
927
|
+
|
|
928
|
+
```typescript
|
|
929
|
+
renderMessageContent={(props) => {
|
|
930
|
+
const { message, MessageContainer } = props;
|
|
931
|
+
|
|
932
|
+
if (message.type === 'bot' && isCustomMessage(message)) {
|
|
933
|
+
return (
|
|
934
|
+
<MessageContainer>
|
|
935
|
+
<MyCustomComponent data={message.message.payload} />
|
|
936
|
+
</MessageContainer>
|
|
937
|
+
);
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
return props.renderDefaultContent();
|
|
941
|
+
}}
|
|
942
|
+
```
|
|
943
|
+
|
|
944
|
+
**Without MessageContainer** (when you need full control):
|
|
945
|
+
|
|
946
|
+
```typescript
|
|
947
|
+
renderMessageContent={(props) => {
|
|
948
|
+
const { message } = props;
|
|
949
|
+
|
|
950
|
+
if (message.type === 'bot' && isSpecialMessage(message)) {
|
|
951
|
+
// Render completely custom layout without Avatar
|
|
952
|
+
return <FullWidthBanner data={message.message.payload} />;
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
return props.renderDefaultContent();
|
|
956
|
+
}}
|
|
957
|
+
```
|
|
958
|
+
|
|
959
|
+
#### Wrapper Pattern
|
|
960
|
+
|
|
961
|
+
You can also wrap the default content to add additional elements:
|
|
962
|
+
|
|
963
|
+
```typescript
|
|
964
|
+
renderMessageContent={(props) => {
|
|
965
|
+
const { message, renderDefaultContent } = props;
|
|
966
|
+
|
|
967
|
+
return (
|
|
968
|
+
<div className="message-wrapper" data-type={message.type}>
|
|
969
|
+
<div className="timestamp">{new Date().toLocaleTimeString()}</div>
|
|
970
|
+
{renderDefaultContent()}
|
|
971
|
+
<div className="message-footer">
|
|
972
|
+
<span>Type: {message.type}</span>
|
|
973
|
+
</div>
|
|
974
|
+
</div>
|
|
975
|
+
);
|
|
976
|
+
}}
|
|
977
|
+
```
|
|
978
|
+
|
|
979
|
+
#### Custom User Messages
|
|
980
|
+
|
|
981
|
+
You can also customize user messages:
|
|
982
|
+
|
|
983
|
+
```typescript
|
|
984
|
+
renderMessageContent={(props) => {
|
|
985
|
+
const { message, renderDefaultContent, MessageContainer } = props;
|
|
986
|
+
|
|
987
|
+
if (message.type === 'user') {
|
|
988
|
+
return (
|
|
989
|
+
<MessageContainer>
|
|
990
|
+
<div className="custom-user-message">
|
|
991
|
+
<span className="user-badge">YOU</span>
|
|
992
|
+
<div className="user-content">{message.text}</div>
|
|
993
|
+
</div>
|
|
994
|
+
</MessageContainer>
|
|
995
|
+
);
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
return renderDefaultContent();
|
|
999
|
+
}}
|
|
1000
|
+
```
|
|
1001
|
+
|
|
828
1002
|
<a id="development"></a>
|
|
829
1003
|
<br/>
|
|
830
1004
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation-message-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/chatbot/chatbot-body/conversation-message-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"conversation-message-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/chatbot/chatbot-body/conversation-message-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAwB,MAAM,OAAO,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAuB,MAAM,iBAAiB,CAAC;AAoB3E,UAAU,gCAAgC;IACxC,OAAO,EAAE,mBAAmB,CAAC;CAC9B;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,gCAAgC,GAAG,SAAS,CAyF9F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chatbot.d.ts","sourceRoot":"","sources":["../../../src/components/chatbot/chatbot.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4B,SAAS,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAA8B,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AACzG,OAAO,EAEL,yBAAyB,EAEzB,0BAA0B,EAE1B,iCAAiC,EAClC,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAU5C,UAAU,YAAa,SAAQ,0BAA0B;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,SAAS,EAAE,CAAC;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACzC,MAAM,EAAE,YAAY,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACrC,YAAY,CAAC,EAAE,iCAAiC,CAAC,cAAc,CAAC,CAAC;IACjE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3D,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,iBAAiB,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IAG5D,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,WAAW,EAAE,OAAO,CAAC;QAAC,kBAAkB,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CAC7G;AAED,MAAM,WAAW,UAAU;IACzB,cAAc,CAAC,EAAE,yBAAyB,CAAC;CAC5C;AAED,eAAO,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"chatbot.d.ts","sourceRoot":"","sources":["../../../src/components/chatbot/chatbot.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4B,SAAS,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAA8B,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AACzG,OAAO,EAEL,yBAAyB,EAEzB,0BAA0B,EAE1B,iCAAiC,EAClC,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAU5C,UAAU,YAAa,SAAQ,0BAA0B;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,SAAS,EAAE,CAAC;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACzC,MAAM,EAAE,YAAY,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACrC,YAAY,CAAC,EAAE,iCAAiC,CAAC,cAAc,CAAC,CAAC;IACjE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3D,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,iBAAiB,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IAG5D,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,WAAW,EAAE,OAAO,CAAC;QAAC,kBAAkB,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CAC7G;AAED,MAAM,WAAW,UAAU;IACzB,cAAc,CAAC,EAAE,yBAAyB,CAAC;CAC5C;AAED,eAAO,MAAM,OAAO,qGAsLlB,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ConversationBotMessage, ConversationErrorMessage } from '../../../core/src/index.ts';
|
|
2
|
-
import { PropsWithChildren, ReactNode } from 'react';
|
|
1
|
+
import { ConversationBotMessage, ConversationErrorMessage, ConversationMessage } from '../../../core/src/index.ts';
|
|
2
|
+
import { FC, PropsWithChildren, ReactNode } from 'react';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Configuration for a message action button
|
|
@@ -10,6 +10,23 @@ export interface MessageActionConfig {
|
|
|
10
10
|
/** Display label for the action button */
|
|
11
11
|
label: string;
|
|
12
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Props for the MessageContainer component
|
|
15
|
+
*/
|
|
16
|
+
export interface MessageContainerProps {
|
|
17
|
+
children: ReactNode;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Props passed to the custom message content renderer function
|
|
21
|
+
*/
|
|
22
|
+
export interface MessageContentRendererProps {
|
|
23
|
+
/** The original message object */
|
|
24
|
+
message: ConversationMessage;
|
|
25
|
+
/** Function to render the default message content */
|
|
26
|
+
renderDefaultContent: () => ReactNode;
|
|
27
|
+
/** Container component that wraps custom content with Avatar for bot messages */
|
|
28
|
+
MessageContainer: FC<MessageContainerProps>;
|
|
29
|
+
}
|
|
13
30
|
export interface AsgardTemplateContextValue {
|
|
14
31
|
onErrorClick?: (message: ConversationErrorMessage) => void;
|
|
15
32
|
errorMessageRenderer?: (message: ConversationErrorMessage) => ReactNode;
|
|
@@ -19,6 +36,8 @@ export interface AsgardTemplateContextValue {
|
|
|
19
36
|
messageActions?: (message: ConversationBotMessage) => MessageActionConfig[];
|
|
20
37
|
/** Callback when a message action button is clicked */
|
|
21
38
|
onMessageAction?: (actionId: string, message: ConversationBotMessage) => void;
|
|
39
|
+
/** Custom renderer for message content. Allows customizing how messages are rendered based on message properties. */
|
|
40
|
+
renderMessageContent?: (props: MessageContentRendererProps) => ReactNode;
|
|
22
41
|
}
|
|
23
42
|
export declare const AsgardTemplateContext: import('react').Context<AsgardTemplateContextValue>;
|
|
24
43
|
interface AsgardTemplateContextProviderProps extends PropsWithChildren {
|
|
@@ -28,6 +47,7 @@ interface AsgardTemplateContextProviderProps extends PropsWithChildren {
|
|
|
28
47
|
defaultLinkTarget?: '_blank' | '_self' | '_parent' | '_top';
|
|
29
48
|
messageActions?: (message: ConversationBotMessage) => MessageActionConfig[];
|
|
30
49
|
onMessageAction?: (actionId: string, message: ConversationBotMessage) => void;
|
|
50
|
+
renderMessageContent?: (props: MessageContentRendererProps) => ReactNode;
|
|
31
51
|
}
|
|
32
52
|
export declare function AsgardTemplateContextProvider(props: AsgardTemplateContextProviderProps): ReactNode;
|
|
33
53
|
export declare function useAsgardTemplateContext(): AsgardTemplateContextValue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asgard-template-context.d.ts","sourceRoot":"","sources":["../../src/context/asgard-template-context.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,iBAAiB,EAAE,SAAS,EAAuB,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"asgard-template-context.d.ts","sourceRoot":"","sources":["../../src/context/asgard-template-context.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,EAAE,EAAE,iBAAiB,EAAE,SAAS,EAAuB,MAAM,OAAO,CAAC;AAC7F,OAAO,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAExG;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,kCAAkC;IAClC,OAAO,EAAE,mBAAmB,CAAC;IAC7B,qDAAqD;IACrD,oBAAoB,EAAE,MAAM,SAAS,CAAC;IACtC,iFAAiF;IACjF,gBAAgB,EAAE,EAAE,CAAC,qBAAqB,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,0BAA0B;IACzC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,wBAAwB,KAAK,IAAI,CAAC;IAC3D,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,wBAAwB,KAAK,SAAS,CAAC;IACxE,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAChG,iBAAiB,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IAC5D,uEAAuE;IACvE,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,mBAAmB,EAAE,CAAC;IAC5E,uDAAuD;IACvD,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,KAAK,IAAI,CAAC;IAC9E,qHAAqH;IACrH,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,2BAA2B,KAAK,SAAS,CAAC;CAC1E;AAED,eAAO,MAAM,qBAAqB,qDAQhC,CAAC;AAEH,UAAU,kCAAmC,SAAQ,iBAAiB;IACpE,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,wBAAwB,KAAK,IAAI,CAAC;IAC3D,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,wBAAwB,KAAK,SAAS,CAAC;IACxE,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAChG,iBAAiB,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IAC5D,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,mBAAmB,EAAE,CAAC;IAC5E,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,KAAK,IAAI,CAAC;IAC9E,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,2BAA2B,KAAK,SAAS,CAAC;CAC1E;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,kCAAkC,GAAG,SAAS,CAkClG;AAED,wBAAgB,wBAAwB,IAAI,0BAA0B,CAErE"}
|