@webinex/chatify 2.0.0-alpha13 → 2.0.0-alpha14

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 (143) hide show
  1. package/dist/{Chatify-CwAfN1wu.js → Chatify-CP2jgo8d.js} +191 -118
  2. package/dist/Chatify-CP2jgo8d.js.map +1 -0
  3. package/dist/Chatify.css +28 -0
  4. package/dist/audit.js +3 -2
  5. package/dist/audit.js.map +1 -1
  6. package/dist/index.js +1 -1
  7. package/dist/types/audit/index.d.ts +17 -15
  8. package/dist/types/ui/Chat/ChatContext.d.ts +2 -0
  9. package/dist/types/ui/Chat/ChatPanel.d.ts +7 -0
  10. package/dist/types/ui/Chat/ChatView.d.ts +4 -2
  11. package/dist/types/ui/ChatGroup/ChatGroupContext.d.ts +4 -1
  12. package/dist/types/ui/ChatGroup/ChatGroupPanel.d.ts +21 -2
  13. package/dist/types/ui/Conversation/Conversation.d.ts +1 -0
  14. package/dist/types/ui/Conversation/ConversationContext.d.ts +1 -0
  15. package/dist/types/ui/Conversation/ConversationHeader.d.ts +4 -1
  16. package/dist/types/ui/localizer.d.ts +4 -1
  17. package/dist/types/ui/useCompact.d.ts +4 -0
  18. package/package.json +81 -81
  19. package/src/audit/AuditChatList.tsx +25 -25
  20. package/src/audit/AuditConversationPanel.tsx +49 -48
  21. package/src/audit/AuditPanel.tsx +76 -76
  22. package/src/audit/AuditPanelCustomizeValue.ts +11 -11
  23. package/src/audit/AuditSearch.tsx +89 -89
  24. package/src/audit/AuditSearchValue.tsx +42 -42
  25. package/src/audit/auditApi.tsx +113 -113
  26. package/src/audit/index.d.ts +18 -18
  27. package/src/audit/index.tsx +28 -28
  28. package/src/audit/styles.scss +72 -72
  29. package/src/core/api/api.ts +675 -675
  30. package/src/core/api/baseApi.ts +38 -38
  31. package/src/core/api/index.ts +1 -1
  32. package/src/core/client.ts +298 -298
  33. package/src/core/constants.ts +1 -1
  34. package/src/core/debounce.ts +90 -90
  35. package/src/core/index.ts +4 -4
  36. package/src/core/types.tsx +182 -182
  37. package/src/index.ts +2 -2
  38. package/src/styles/aside.scss +34 -26
  39. package/src/styles/chat-list.scss +138 -138
  40. package/src/styles/chat.scss +11 -11
  41. package/src/styles/conversation.scss +199 -200
  42. package/src/styles/index.scss +227 -220
  43. package/src/styles/input.scss +148 -148
  44. package/src/styles/keyframes.scss +14 -14
  45. package/src/styles/members.scss +30 -13
  46. package/src/styles/mixins.scss +38 -25
  47. package/src/styles/variables.scss +13 -13
  48. package/src/ui/Chat/ChatContext.tsx +32 -30
  49. package/src/ui/Chat/ChatEditableHeaderName.tsx +63 -63
  50. package/src/ui/Chat/ChatHeaderActions.tsx +19 -19
  51. package/src/ui/Chat/ChatPanel.tsx +46 -30
  52. package/src/ui/Chat/ChatView.tsx +122 -115
  53. package/src/ui/Chat/Members/ChatMembersButton.tsx +9 -9
  54. package/src/ui/Chat/Members/ChatMembersPanel.tsx +128 -112
  55. package/src/ui/Chat/Members/ChatMembersPreview.tsx +25 -25
  56. package/src/ui/Chat/Members/index.ts +13 -13
  57. package/src/ui/Chat/index.ts +6 -6
  58. package/src/ui/ChatGroup/AutoReply/AutoReplyButton.tsx +21 -21
  59. package/src/ui/ChatGroup/AutoReply/AutoReplyForm.tsx +50 -50
  60. package/src/ui/ChatGroup/AutoReply/AutoReplyPanel.tsx +94 -94
  61. package/src/ui/ChatGroup/AutoReply/AutoReplyPeriodInput.tsx +22 -22
  62. package/src/ui/ChatGroup/AutoReply/AutoReplyTextInput.tsx +22 -22
  63. package/src/ui/ChatGroup/AutoReply/index.ts +19 -19
  64. package/src/ui/ChatGroup/ChatGroupContext.tsx +63 -61
  65. package/src/ui/ChatGroup/ChatGroupPanel.tsx +110 -75
  66. package/src/ui/ChatGroup/Create/CreateChatButton.tsx +15 -15
  67. package/src/ui/ChatGroup/Create/CreateChatForm.tsx +36 -36
  68. package/src/ui/ChatGroup/Create/CreateChatMemberInput.tsx +65 -65
  69. package/src/ui/ChatGroup/Create/CreateChatNameInput.tsx +25 -25
  70. package/src/ui/ChatGroup/Create/CreateChatPanel.tsx +45 -45
  71. package/src/ui/ChatGroup/Create/index.ts +19 -19
  72. package/src/ui/ChatGroup/Layout/ChatGroupActions.tsx +15 -15
  73. package/src/ui/ChatGroup/Layout/ChatGroupAside.tsx +12 -12
  74. package/src/ui/ChatGroup/Layout/ChatGroupBody.tsx +17 -10
  75. package/src/ui/ChatGroup/Layout/ChatGroupFooter.tsx +3 -3
  76. package/src/ui/ChatGroup/Layout/ChatGroupHeader.tsx +5 -5
  77. package/src/ui/ChatGroup/Layout/ChatGroupMain.tsx +21 -19
  78. package/src/ui/ChatGroup/Layout/index.ts +22 -22
  79. package/src/ui/ChatGroup/List/ChatListPanel.tsx +28 -28
  80. package/src/ui/ChatGroup/List/index.ts +8 -8
  81. package/src/ui/ChatGroup/index.ts +6 -6
  82. package/src/ui/Chatify.tsx +15 -15
  83. package/src/ui/Conversation/Conversation.tsx +96 -92
  84. package/src/ui/Conversation/ConversationActions.tsx +12 -12
  85. package/src/ui/Conversation/ConversationBody.tsx +28 -28
  86. package/src/ui/Conversation/ConversationContext.ts +31 -30
  87. package/src/ui/Conversation/ConversationHeader.tsx +35 -19
  88. package/src/ui/Conversation/ConversationName.tsx +7 -7
  89. package/src/ui/Conversation/InputBox/InputBox.tsx +126 -126
  90. package/src/ui/Conversation/InputBox/InputBoxFile.tsx +38 -38
  91. package/src/ui/Conversation/InputBox/InputBoxFileList.tsx +21 -21
  92. package/src/ui/Conversation/InputBox/InputFilesBox.tsx +78 -78
  93. package/src/ui/Conversation/InputBox/InputSubmitButtonBox.tsx +26 -26
  94. package/src/ui/Conversation/InputBox/InputTextBox.tsx +63 -61
  95. package/src/ui/Conversation/InputBox/index.ts +23 -23
  96. package/src/ui/Conversation/Message/MessageAuthor.tsx +13 -13
  97. package/src/ui/Conversation/Message/MessageBox.tsx +20 -20
  98. package/src/ui/Conversation/Message/MessageContent.tsx +15 -15
  99. package/src/ui/Conversation/Message/MessageFile.tsx +54 -54
  100. package/src/ui/Conversation/Message/MessageFileList.tsx +14 -14
  101. package/src/ui/Conversation/Message/MessageInfoBox.tsx +28 -28
  102. package/src/ui/Conversation/Message/MessageRow.tsx +28 -28
  103. package/src/ui/Conversation/Message/MessageText.tsx +7 -7
  104. package/src/ui/Conversation/Message/index.ts +28 -28
  105. package/src/ui/Conversation/NextObserver/NextMessagesObserver.tsx +47 -47
  106. package/src/ui/Conversation/NextObserver/index.ts +1 -1
  107. package/src/ui/Conversation/ReadObserver/MessageReadObserver.tsx +49 -49
  108. package/src/ui/Conversation/ReadObserver/index.ts +1 -1
  109. package/src/ui/Conversation/SendingMessage/SendingMessageBox.tsx +16 -16
  110. package/src/ui/Conversation/SendingMessage/SendingMessageContent.tsx +13 -13
  111. package/src/ui/Conversation/SendingMessage/SendingMessageInfoBox.tsx +13 -13
  112. package/src/ui/Conversation/SendingMessage/SendingMessageText.tsx +7 -7
  113. package/src/ui/Conversation/SendingMessage/index.ts +16 -16
  114. package/src/ui/Conversation/SystemMessage/SystemMessageBox.tsx +20 -20
  115. package/src/ui/Conversation/SystemMessage/SystemMessageRow.tsx +28 -28
  116. package/src/ui/Conversation/SystemMessage/index.ts +10 -10
  117. package/src/ui/Conversation/index.ts +13 -13
  118. package/src/ui/Thread/ThreadActions.tsx +22 -22
  119. package/src/ui/Thread/ThreadContext.ts +13 -13
  120. package/src/ui/Thread/ThreadPanel.tsx +128 -127
  121. package/src/ui/Thread/index.tsx +3 -3
  122. package/src/ui/color.ts +20 -20
  123. package/src/ui/common/Avatar.tsx +20 -20
  124. package/src/ui/common/ChatList/ChatList.tsx +83 -84
  125. package/src/ui/common/ChatList/ChatListItemAvatar.tsx +22 -22
  126. package/src/ui/common/ChatList/ChatListItemBox.tsx +32 -32
  127. package/src/ui/common/ChatList/ChatListItemLastMessage.tsx +15 -15
  128. package/src/ui/common/ChatList/ChatListItemLastMessageAuthor.tsx +15 -15
  129. package/src/ui/common/ChatList/ChatListItemLastMessageContent.tsx +21 -21
  130. package/src/ui/common/ChatList/ChatListItemLastMessageSentAt.tsx +22 -22
  131. package/src/ui/common/ChatList/ChatListItemName.tsx +8 -8
  132. package/src/ui/common/ChatList/ChatListItemUnreadCount.tsx +12 -12
  133. package/src/ui/common/ChatList/ChatListValue.ts +9 -9
  134. package/src/ui/common/ChatList/index.ts +32 -32
  135. package/src/ui/common/Icon.tsx +48 -48
  136. package/src/ui/common/MessageSkeleton.tsx +20 -20
  137. package/src/ui/common/index.ts +14 -14
  138. package/src/ui/customize.tsx +51 -51
  139. package/src/ui/index.ts +11 -11
  140. package/src/ui/localizer.tsx +148 -137
  141. package/src/ui/useCompact.tsx +32 -0
  142. package/src/ui/useFormatter.tsx +17 -17
  143. package/dist/Chatify-CwAfN1wu.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Chatify-CP2jgo8d.js","sources":["../src/ui/color.ts","../src/ui/customize.tsx","../src/ui/common/Icon.tsx","../src/ui/Chat/ChatContext.tsx","../src/ui/Chat/Members/ChatMembersButton.tsx","../src/core/constants.ts","../src/core/types.tsx","../src/core/debounce.ts","../src/core/api/baseApi.ts","../src/core/client.ts","../src/core/api/api.ts","../src/ui/common/Avatar.tsx","../src/ui/localizer.tsx","../src/ui/Chat/Members/ChatMembersPanel.tsx","../src/ui/Chat/Members/ChatMembersPreview.tsx","../src/ui/Conversation/InputBox/InputFilesBox.tsx","../src/ui/Conversation/ConversationContext.ts","../src/ui/Conversation/InputBox/InputTextBox.tsx","../src/ui/Conversation/InputBox/InputSubmitButtonBox.tsx","../src/ui/common/MessageSkeleton.tsx","../src/ui/common/ChatList/ChatListItemName.tsx","../src/ui/common/ChatList/ChatListItemUnreadCount.tsx","../src/ui/Conversation/SystemMessage/SystemMessageRow.tsx","../src/ui/Conversation/ReadObserver/MessageReadObserver.tsx","../src/ui/Conversation/SystemMessage/SystemMessageBox.tsx","../src/ui/common/ChatList/ChatListItemLastMessageContent.tsx","../src/ui/common/ChatList/ChatListItemLastMessageAuthor.tsx","../src/ui/common/ChatList/ChatListItemLastMessageSentAt.tsx","../src/ui/common/ChatList/ChatListItemLastMessage.tsx","../src/ui/common/ChatList/ChatListItemAvatar.tsx","../src/ui/common/ChatList/ChatListItemBox.tsx","../src/ui/common/ChatList/ChatList.tsx","../src/ui/useFormatter.tsx","../src/ui/Conversation/InputBox/InputBoxFile.tsx","../src/ui/Conversation/InputBox/InputBoxFileList.tsx","../src/ui/Conversation/InputBox/InputBox.tsx","../src/ui/Conversation/Message/MessageAuthor.tsx","../src/ui/Conversation/Message/MessageText.tsx","../src/ui/Conversation/Message/MessageFile.tsx","../src/ui/Conversation/Message/MessageFileList.tsx","../src/ui/Conversation/Message/MessageContent.tsx","../src/ui/Conversation/Message/MessageInfoBox.tsx","../src/ui/Conversation/Message/MessageRow.tsx","../src/ui/Conversation/Message/MessageBox.tsx","../src/ui/Conversation/NextObserver/NextMessagesObserver.tsx","../src/ui/Conversation/SendingMessage/SendingMessageText.tsx","../src/ui/Conversation/SendingMessage/SendingMessageInfoBox.tsx","../src/ui/Conversation/SendingMessage/SendingMessageContent.tsx","../src/ui/Conversation/SendingMessage/SendingMessageBox.tsx","../src/ui/Conversation/ConversationActions.tsx","../src/ui/Conversation/ConversationBody.tsx","../src/ui/Conversation/ConversationName.tsx","../src/ui/Conversation/ConversationHeader.tsx","../src/ui/Conversation/Conversation.tsx","../src/ui/Chat/ChatEditableHeaderName.tsx","../src/ui/Chat/ChatHeaderActions.tsx","../src/ui/Chat/ChatView.tsx","../src/ui/useCompact.tsx","../src/ui/Chat/ChatPanel.tsx","../src/ui/ChatGroup/ChatGroupContext.tsx","../src/ui/ChatGroup/AutoReply/AutoReplyButton.tsx","../src/ui/ChatGroup/AutoReply/AutoReplyPeriodInput.tsx","../src/ui/ChatGroup/AutoReply/AutoReplyTextInput.tsx","../src/ui/ChatGroup/AutoReply/AutoReplyForm.tsx","../src/ui/ChatGroup/AutoReply/AutoReplyPanel.tsx","../src/ui/ChatGroup/Create/CreateChatNameInput.tsx","../src/ui/ChatGroup/Create/CreateChatMemberInput.tsx","../src/ui/ChatGroup/Create/CreateChatForm.tsx","../src/ui/ChatGroup/Create/CreateChatPanel.tsx","../src/ui/ChatGroup/Create/CreateChatButton.tsx","../src/ui/ChatGroup/Layout/ChatGroupActions.tsx","../src/ui/ChatGroup/List/ChatListPanel.tsx","../src/ui/ChatGroup/Layout/ChatGroupAside.tsx","../src/ui/ChatGroup/Layout/ChatGroupHeader.tsx","../src/ui/ChatGroup/Layout/ChatGroupFooter.tsx","../src/ui/ChatGroup/Layout/ChatGroupMain.tsx","../src/ui/ChatGroup/Layout/ChatGroupBody.tsx","../src/ui/ChatGroup/ChatGroupPanel.tsx","../src/ui/Thread/ThreadContext.ts","../src/ui/Thread/ThreadActions.tsx","../src/ui/Thread/ThreadPanel.tsx","../src/ui/Chatify.tsx"],"sourcesContent":["interface ColorOptions {\r\n saturation?: number;\r\n lightness?: number;\r\n}\r\n\r\nconst DEFAULT_COLOR_OPTIONS: ColorOptions = {\r\n saturation: 100,\r\n lightness: 75,\r\n};\r\n\r\nexport function color(value: string, options: ColorOptions = {}) {\r\n options = Object.assign({}, DEFAULT_COLOR_OPTIONS, options);\r\n\r\n let hash = 0;\r\n for (let i = 0; i < value.length; i++) {\r\n hash = value.charCodeAt(i) + ((hash << 5) - hash);\r\n hash = hash & hash;\r\n }\r\n return `hsl(${hash % 360}, ${options.saturation}%, ${options.lightness}%)`;\r\n}\r\n","import React, { FC, useContext } from 'react';\r\n\r\nexport type Customizable<TComponent extends React.ComponentType<any>> = TComponent & {\r\n Component: TComponent;\r\n key: string;\r\n};\r\n\r\nexport const CustomizeContext = React.createContext<Record<string, any>>(null!);\r\n\r\nexport function useCustomizeContext<TValue>() {\r\n return useContext(CustomizeContext) as TValue;\r\n}\r\n\r\nfunction useCustom<TComponent extends React.ComponentType>(key: string): TComponent | undefined | null {\r\n const value = useContext(CustomizeContext);\r\n return value ? (value[key] as TComponent | null | undefined) : undefined;\r\n}\r\n\r\nexport function useCustomize<TCustom extends Customizable<React.ComponentType<any>>>(custom: TCustom) {\r\n const Custom = useCustom<TCustom['Component']>(custom.key);\r\n\r\n if (Custom == null) {\r\n return null;\r\n }\r\n\r\n return Custom ?? custom.Component;\r\n}\r\n\r\nexport function customize<TComponent extends React.ComponentType<any>>(\r\n key: string,\r\n Component: TComponent,\r\n): TComponent extends React.ComponentType<infer X> ? Customizable<React.ComponentType<X>> : never {\r\n const Result: FC<any> = React.forwardRef<TComponent, any>((props: any, forwardRef) => {\r\n const Custom = useCustom(key);\r\n\r\n if (Custom === null) {\r\n return null;\r\n }\r\n\r\n if (Custom) {\r\n return <Custom {...props} ref={forwardRef} />;\r\n }\r\n\r\n return <Component {...props} ref={forwardRef} />;\r\n });\r\n\r\n Component.displayName = Component.displayName || key;\r\n Result.displayName = 'Customizable.' + Component.displayName;\r\n\r\n return Object.assign(Result, { key, Component }) as any;\r\n}\r\n","import { FC } from 'react';\r\nimport { customize } from '../customize';\r\nimport {\r\n SendOutlined,\r\n PaperClipOutlined,\r\n UserAddOutlined,\r\n UsergroupAddOutlined,\r\n UserDeleteOutlined,\r\n UsergroupDeleteOutlined,\r\n TeamOutlined,\r\n EditOutlined,\r\n CloseOutlined,\r\n EyeInvisibleOutlined,\r\n EyeOutlined,\r\n DeleteOutlined,\r\n DownloadOutlined,\r\n SettingOutlined,\r\n} from '@ant-design/icons';\r\n\r\nexport type IconType = keyof typeof ICONS;\r\n\r\nexport interface IconProps {\r\n type: IconType;\r\n}\r\n\r\nexport const ICONS = {\r\n attach: PaperClipOutlined,\r\n send: SendOutlined,\r\n 'remove-member': UserDeleteOutlined,\r\n 'remove-member-delete-history': UsergroupDeleteOutlined,\r\n 'add-member': UserAddOutlined,\r\n 'add-member-with-history': UsergroupAddOutlined,\r\n members: TeamOutlined,\r\n edit: EditOutlined,\r\n close: CloseOutlined,\r\n chat: TeamOutlined,\r\n watch: EyeOutlined,\r\n unwatch: EyeInvisibleOutlined,\r\n 'delete-file': DeleteOutlined,\r\n 'open-file': DownloadOutlined,\r\n settings: SettingOutlined,\r\n};\r\n\r\nexport const Icon = customize<FC<IconProps>>('Icon', (props) => {\r\n const { type } = props;\r\n const IconComponent = ICONS[type];\r\n return IconComponent ? <IconComponent /> : null;\r\n});\r\n","import React, { PropsWithChildren, useContext, useMemo, useState } from 'react';\r\n\r\nexport interface ChatContext {\r\n id: string;\r\n compact: boolean;\r\n showMembers: boolean;\r\n onShowMembers: (value: boolean) => void;\r\n}\r\n\r\nconst ChatReactContext = React.createContext<ChatContext>(null!);\r\n\r\nexport function useChatContext() {\r\n return useContext(ChatReactContext);\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-redeclare\r\nexport function ChatContext(props: PropsWithChildren<{ id: string; compact: boolean }>) {\r\n const { id, children, compact } = props;\r\n const [showMembers, onShowMembers] = useState(false);\r\n\r\n const value = useMemo<ChatContext>(\r\n () => ({\r\n id,\r\n showMembers,\r\n onShowMembers,\r\n compact,\r\n }),\r\n [id, showMembers, compact],\r\n );\r\n\r\n return <ChatReactContext.Provider value={value}>{children}</ChatReactContext.Provider>;\r\n}\r\n","import { Button } from 'antd';\r\nimport { customize } from '../../customize';\r\nimport { Icon } from '../../common/Icon';\r\nimport { useChatContext } from '../ChatContext';\r\n\r\nexport const ChatMembersButton = customize('ChatMembersButton', () => {\r\n const { showMembers, onShowMembers } = useChatContext();\r\n return <Button onClick={() => onShowMembers(!showMembers)} type=\"link\" icon={<Icon type=\"members\" />} />;\r\n});\r\n","export const SYSTEM_ID = 'chatify::system';\r\n","export interface Optional<TValue> {\r\n hasValue: boolean;\r\n value?: TValue | null;\r\n}\r\n\r\nexport interface File {\r\n name: string;\r\n bytes: number;\r\n ref: string;\r\n}\r\n\r\nexport interface Period {\r\n start: string;\r\n end: string;\r\n}\r\n\r\nexport interface AutoReply {\r\n text: string;\r\n period: Period;\r\n}\r\n\r\nexport interface Account {\r\n id: string;\r\n name: string;\r\n avatar: string;\r\n autoReply: AutoReply | null;\r\n}\r\n\r\nexport interface UpdateAccountRequest {\r\n id: string;\r\n autoReply?: Optional<AutoReply> | null;\r\n name?: Optional<string> | null;\r\n avatar?: Optional<string> | null;\r\n active?: Optional<boolean> | null;\r\n}\r\n\r\nexport interface MessageBase {\r\n id: string;\r\n text: string | null;\r\n files: File[];\r\n sentAt: string;\r\n sentBy: Account;\r\n}\r\n\r\nexport interface ChatMessage extends MessageBase {\r\n chatId: string;\r\n}\r\n\r\nexport interface Chat {\r\n id: string;\r\n name: string;\r\n members: Account[];\r\n active: boolean;\r\n lastReadMessageId: string | null;\r\n}\r\n\r\nexport interface ChatListItem {\r\n id: string;\r\n name: string;\r\n message: ChatMessage;\r\n totalUnreadCount: number;\r\n active: boolean;\r\n lastReadMessageId: string | null;\r\n}\r\n\r\nexport interface SendChatMessageRequest {\r\n chatId: string;\r\n text: string | null;\r\n files: File[];\r\n}\r\n\r\nexport interface MessageBody {\r\n text: string | null;\r\n files: File[];\r\n}\r\n\r\nexport interface AddChatRequest {\r\n name: string;\r\n message?: MessageBody;\r\n members: string[];\r\n}\r\n\r\nexport interface ReadChatMessageRequest {\r\n id: string;\r\n}\r\n\r\nexport interface ReadChatMessageEvent {\r\n chatId: string;\r\n newLastReadMessageId: string;\r\n readCount: number;\r\n}\r\n\r\nexport interface RemoveChatMemberRequest {\r\n chatId: string;\r\n accountId: string;\r\n deleteHistory: boolean;\r\n}\r\n\r\nexport interface AddChatMemberRequest {\r\n chatId: string;\r\n accountId: string;\r\n withHistory: boolean;\r\n}\r\n\r\nexport interface UpdateChatNameRequest {\r\n id: string;\r\n name: string;\r\n}\r\n\r\nexport function chatId(messageId: string) {\r\n return messageId.slice(0, 36);\r\n}\r\n\r\nexport function messageSequencePart(id: string) {\r\n return id.slice(37);\r\n}\r\n\r\nexport interface ThreadWatchListItem {\r\n id: string;\r\n name: string;\r\n createdById: string;\r\n createdAt: string;\r\n archive: boolean;\r\n lastMessage: ThreadMessage | null;\r\n lastReadMessageId: string | null;\r\n}\r\n\r\nexport interface Thread {\r\n id: string;\r\n name: string;\r\n createdBy: Account;\r\n createdAt: string;\r\n archive: boolean;\r\n lastMessageId: string | null;\r\n lastReadMessageId: string | null;\r\n watch: boolean;\r\n}\r\n\r\nexport interface ThreadMessage extends MessageBase {\r\n threadId: string;\r\n}\r\n\r\nexport interface SendThreadMessageRequest {\r\n threadId: string;\r\n body: MessageBody;\r\n}\r\n\r\nexport interface ListSegment<T> {\r\n items: T[];\r\n total: number;\r\n}\r\n\r\nexport type SystemMessageText =\r\n | 'chatify://chat-created'\r\n | 'chatify://member-added'\r\n | 'chatify://member-removed'\r\n | `chatify://chat-name-changed`;\r\n\r\nexport function parseThreadMessageId(messageId: string) {\r\n const [threadId, index] = messageId.split('::', 2);\r\n return [threadId, parseInt(index, 10)] as const;\r\n}\r\n\r\nexport function calcThreadUnreadCount(\r\n thread: Pick<ThreadWatchListItem, 'lastMessage' | 'lastReadMessageId'>,\r\n) {\r\n const lastReadMessageIndex =\r\n thread.lastReadMessageId != null ? parseThreadMessageId(thread.lastReadMessageId)[1] : -1;\r\n\r\n const lastThreadMessageIndex =\r\n thread.lastMessage?.id != null ? parseThreadMessageId(thread.lastMessage?.id)[1] : -1;\r\n\r\n return lastThreadMessageIndex - lastReadMessageIndex;\r\n}\r\n\r\nexport function calcThreadListUnreadCount(\r\n threads: Pick<ThreadWatchListItem, 'lastMessage' | 'lastReadMessageId'>[],\r\n) {\r\n return threads.reduce((prev, thread) => {\r\n return prev + calcThreadUnreadCount(thread);\r\n }, 0);\r\n}\r\n","interface DebounceInternalValue<T> {\r\n value: T;\r\n enqueueTime: number;\r\n}\r\n\r\nexport interface DebounceValue<T> extends DebounceInternalValue<T> {\r\n state: 'enqueued' | 'processing';\r\n}\r\n\r\nexport interface DebounceConfig<T> {\r\n timeout: number;\r\n callback: (value: T) => Promise<any>;\r\n groupBy: (value: T) => string;\r\n compare: (a: T, b: T) => number;\r\n}\r\n\r\nexport class Debounce<T> {\r\n private _enqueued: DebounceInternalValue<T>[] = [];\r\n private _processing: DebounceInternalValue<T>[] = [];\r\n private _timeoutByGroup: Record<string, number> = {};\r\n private _subscribers: ((value: Debounce<T>) => any)[] = [];\r\n\r\n constructor(public config: DebounceConfig<T>) {}\r\n\r\n public get units(): DebounceValue<T>[] {\r\n return [\r\n ...this._enqueued.map((x) => ({ ...x, state: 'enqueued' as const })),\r\n ...this._processing.map((x) => ({ ...x, state: 'processing' as const })),\r\n ];\r\n }\r\n\r\n public subscribe = (callback: (value: Debounce<T>) => any) => {\r\n this._subscribers.push(callback);\r\n return () => {\r\n this._subscribers = this._subscribers.filter((x) => x !== callback);\r\n };\r\n };\r\n\r\n public notify = () => {\r\n this._subscribers.forEach((subscriber) => subscriber(this));\r\n };\r\n\r\n public push(value: T) {\r\n const group = this.config.groupBy(value);\r\n const unit = this._enqueued.find((unit) => this.config.groupBy(unit.value) === group);\r\n\r\n if (!unit) {\r\n this._enqueued.push({ value, enqueueTime: Date.now() });\r\n } else if (this.config.compare(unit.value, value) >= 0) {\r\n unit.value = value;\r\n unit.enqueueTime = Date.now();\r\n }\r\n\r\n this._process(group);\r\n }\r\n\r\n private _process(group: string) {\r\n if (!this._enqueued.some((unit) => this.config.groupBy(unit.value) === group)) {\r\n return;\r\n }\r\n\r\n let timeout = this._timeoutByGroup[group];\r\n timeout && clearTimeout(timeout);\r\n\r\n if (this._processing.some((unit) => this.config.groupBy(unit.value) === group)) {\r\n return;\r\n }\r\n\r\n timeout = setTimeout(() => {\r\n const processing = this._enqueued.find((unit) => this.config.groupBy(unit.value) === group)!;\r\n this._processing.push(processing);\r\n this._enqueued.splice(this._enqueued.indexOf(processing), 1);\r\n this.notify();\r\n\r\n this.config\r\n .callback(processing.value)\r\n .then(() => {\r\n this._processing.splice(this._processing.indexOf(processing), 1);\r\n this.notify();\r\n this._process(group);\r\n })\r\n .catch(() => {\r\n this._processing.splice(this._processing.indexOf(processing), 1);\r\n this.push(processing.value);\r\n });\r\n }, this.config.timeout);\r\n\r\n this._timeoutByGroup[group] = timeout;\r\n }\r\n}\r\n","import { BaseQueryFn, EndpointBuilder, createApi, fakeBaseQuery } from '@reduxjs/toolkit/query/react';\r\nimport { ChatifyClient } from '../client';\r\nimport { Debounce } from '../debounce';\r\nimport { chatId } from '../types';\r\n\r\nexport const DEFAULT_MESSAGE_LIST_TAKE = 20;\r\n\r\nexport const CHAT_MESSAGE_READ_QUEUE = new Debounce<string>({\r\n callback: (id) => __settings.client.readChatMessage({ id }),\r\n compare: (a, b) => -a.localeCompare(b),\r\n groupBy: (id) => chatId(id),\r\n timeout: 500,\r\n});\r\n\r\nexport interface ChatifyApiSettings {\r\n me: () => string;\r\n client: ChatifyClient;\r\n}\r\n\r\nexport const __settings: ChatifyApiSettings = {\r\n me: null!,\r\n client: null!,\r\n};\r\n\r\nconst TAG_TYPES = ['chat', 'account', 'message', 'thread', 'thread-message'] as const;\r\n\r\nexport interface BaseApiEndpointBuilder\r\n extends EndpointBuilder<BaseQueryFn, (typeof TAG_TYPES)[number], 'chatify'> {}\r\n\r\nconst baseApi: ReturnType<typeof createApi<BaseQueryFn, {}, 'chatify', (typeof TAG_TYPES)[number]>> =\r\n createApi({\r\n baseQuery: fakeBaseQuery(),\r\n reducerPath: 'chatify',\r\n tagTypes: TAG_TYPES,\r\n endpoints: (_) => ({}),\r\n });\r\n\r\nexport const __baseApi = baseApi;\r\n","import { AxiosInstance } from 'axios';\r\nimport * as SignalR from '@microsoft/signalr';\r\nimport {\r\n Account,\r\n AddChatRequest,\r\n AddChatMemberRequest,\r\n Chat,\r\n ChatListItem,\r\n ChatMessage,\r\n ReadChatMessageEvent,\r\n ReadChatMessageRequest,\r\n RemoveChatMemberRequest,\r\n SendChatMessageRequest,\r\n UpdateChatNameRequest,\r\n SendThreadMessageRequest,\r\n Thread,\r\n ThreadMessage,\r\n ThreadWatchListItem as ThreadListItem,\r\n UpdateAccountRequest,\r\n} from './types';\r\n\r\nexport interface ChatifySignalRConfig {\r\n hubUri?: string;\r\n accessTokenFactory?: () => Promise<string>;\r\n headersFactory?: () => Promise<Record<string, string>>;\r\n}\r\n\r\nconst DEFAULT_SIGNALR_CONFIG: ChatifySignalRConfig = {\r\n hubUri: '/api/chatify/hub',\r\n headersFactory: () => Promise.resolve({}),\r\n};\r\n\r\nexport interface ChatifyClientConfig {\r\n axios: AxiosInstance;\r\n signalR: ChatifySignalRConfig;\r\n}\r\n\r\nexport const CHATIFY_SIGNALR_METHODS = [\r\n 'chatify://chat-new-message',\r\n 'chatify://chat-created',\r\n 'chatify://chat-message-read',\r\n 'chatify://chat-member-added',\r\n 'chatify://chat-member-removed',\r\n 'chatify://chat-name-changed',\r\n\r\n 'chatify://thread-created',\r\n 'chatify://thread-message-new',\r\n 'chatify://thread-message-read',\r\n 'chatify://thread-watch-added',\r\n 'chatify://thread-watch-removed',\r\n 'chatify://thread-updated',\r\n] as const;\r\n\r\nexport type ChatifySignalRMethod = (typeof CHATIFY_SIGNALR_METHODS)[number];\r\n\r\nexport type ChatifySignalRArgsByMethod = {\r\n 'chatify://chat-new-message': [message: ChatMessage];\r\n 'chatify://chat-created': [chat: ChatListItem];\r\n 'chatify://chat-message-read': [events: ReadChatMessageEvent[]];\r\n 'chatify://chat-member-added': [\r\n chatId: string,\r\n chatName: string,\r\n account: Account,\r\n message: ChatMessage,\r\n withHistory: boolean,\r\n read: boolean,\r\n ];\r\n 'chatify://chat-member-removed': [\r\n chatId: string,\r\n accountId: string,\r\n deleteHistory: boolean,\r\n message: ChatMessage,\r\n read: boolean,\r\n ];\r\n 'chatify://chat-name-changed': [chatId: string, newName: string, message: ChatMessage, read: boolean];\r\n\r\n 'chatify://thread-message-new': [threadId: string, message: ThreadMessage, readForId: string | null];\r\n 'chatify://thread-message-read': [threadId: string, messageId: string];\r\n 'chatify://thread-watch-added': [thread: ThreadListItem];\r\n 'chatify://thread-watch-removed': [id: string];\r\n 'chatify://thread-created': [thread: ThreadListItem, watch: boolean];\r\n 'chatify://thread-updated': [threadId: string, threadName: string];\r\n};\r\n\r\nexport class ChatifyClient {\r\n private _config: ChatifyClientConfig;\r\n private _connection: SignalR.HubConnection = null!;\r\n private _connectionPromise: Promise<SignalR.HubConnection> | null = null!;\r\n private _subscribers: Record<string, ((args: any[]) => void)[]> = {};\r\n private _reconnectSubscribers: Array<() => void> = [];\r\n private _threadConnectionByThreadId = new Map<string, number>();\r\n\r\n constructor(config: ChatifyClientConfig) {\r\n this._config = {\r\n ...config,\r\n signalR: {\r\n ...DEFAULT_SIGNALR_CONFIG,\r\n ...config.signalR,\r\n },\r\n };\r\n }\r\n\r\n public connect = async () => {\r\n if (this._connection) {\r\n return;\r\n }\r\n\r\n if (this._connectionPromise) {\r\n return await this._connectionPromise;\r\n }\r\n\r\n this._connectionPromise = this.createAndStartConnection();\r\n this._connection = await this._connectionPromise;\r\n };\r\n\r\n private createAndStartConnection = async () => {\r\n const headers = await this._config.signalR!.headersFactory!();\r\n\r\n const connection = new SignalR.HubConnectionBuilder()\r\n .withUrl(this._config.signalR!.hubUri!, {\r\n accessTokenFactory: this._config.signalR!.accessTokenFactory\r\n ? this._config.signalR!.accessTokenFactory\r\n : undefined,\r\n headers,\r\n })\r\n .withAutomaticReconnect()\r\n .build();\r\n\r\n CHATIFY_SIGNALR_METHODS.forEach((x) => {\r\n connection.on(x, (...args) => {\r\n this._subscribers[x]?.forEach((s) => {\r\n try {\r\n s(args);\r\n } catch (ex) {\r\n console.error(`Failed to notify subscriber`, ex);\r\n }\r\n });\r\n });\r\n });\r\n\r\n connection.onreconnected(() => this._reconnectSubscribers.forEach((subscriber) => subscriber()));\r\n\r\n await connection.start();\r\n return connection;\r\n };\r\n\r\n public subscribe = <TMethod extends ChatifySignalRMethod>(\r\n method: TMethod,\r\n subscriber: (args: ChatifySignalRArgsByMethod[TMethod]) => void,\r\n ) => {\r\n this.connect().then(() => {\r\n this._subscribers[method] = this._subscribers[method] ?? [];\r\n this._subscribers[method].push(subscriber as any);\r\n });\r\n return () => this._subscribers[method].filter((x) => x !== subscriber);\r\n };\r\n\r\n public subscribeReconnect = (subscriber: () => any) => {\r\n this._reconnectSubscribers.push(subscriber);\r\n return () => this._reconnectSubscribers.filter((x) => x !== subscriber);\r\n };\r\n\r\n public get axios() {\r\n return this._config.axios;\r\n }\r\n\r\n public accounts = async (args: { ids?: string[] }) => {\r\n const searchParams = new URLSearchParams();\r\n\r\n args?.ids?.forEach((id) => {\r\n searchParams.append('ids', encodeURIComponent(id));\r\n });\r\n\r\n const { data } = await this.axios.get<Account[]>(`account?${searchParams.toString()}`);\r\n return data;\r\n };\r\n\r\n public currentUserAccount = async () => {\r\n const { data } = await this.axios.get<Account>('account/me');\r\n return data;\r\n };\r\n\r\n public updateAccount = async (request: UpdateAccountRequest) => {\r\n await this.axios.put(`account/${encodeURIComponent(request.id)}`, request);\r\n };\r\n\r\n public chats = async () => {\r\n const { data } = await this.axios.get<ChatListItem[]>('chat');\r\n return data;\r\n };\r\n\r\n public chat = async (id: string) => {\r\n const { data } = await this.axios.get<Chat>(`chat/${encodeURIComponent(id)}`);\r\n return data;\r\n };\r\n\r\n public addChat = async (args: AddChatRequest) => {\r\n const { data } = await this.axios.post<string>(`chat`, args);\r\n return data;\r\n };\r\n\r\n public chatMessages = async (args: { chatId: string; skip?: number; take?: number }) => {\r\n const { chatId, skip = 0, take = 20 } = args;\r\n const pagingRule = encodeURIComponent(JSON.stringify({ skip, take }));\r\n const { data } = await this.axios.get<ChatMessage[]>(\r\n `chat/${encodeURIComponent(chatId)}/message?pagingRule=${pagingRule}`,\r\n );\r\n return data;\r\n };\r\n\r\n public sendChatMessage = async (request: SendChatMessageRequest) => {\r\n const { chatId, ...rest } = request;\r\n await this.axios.post(`chat/${encodeURIComponent(chatId)}/message`, rest);\r\n };\r\n\r\n public readChatMessage = async (request: ReadChatMessageRequest) => {\r\n await this.axios.put(`chat/message/read`, request);\r\n };\r\n\r\n public removeChatMember = async (request: RemoveChatMemberRequest) => {\r\n await this.axios.delete(`chat/${encodeURIComponent(request.chatId)}/member`, { data: request });\r\n };\r\n\r\n public updateChatName = async (request: UpdateChatNameRequest) => {\r\n await this.axios.put(`chat/${encodeURIComponent(request.id)}/name`, request);\r\n };\r\n\r\n public addChatMember = async (request: AddChatMemberRequest) => {\r\n await this.axios.post(`chat/${encodeURIComponent(request.chatId)}/member`, request);\r\n };\r\n\r\n public sendThreadMessage = async ({ body, threadId }: SendThreadMessageRequest) => {\r\n const { data: id } = await this.axios.post<string>(`thread/${encodeURIComponent(threadId)}/message`, {\r\n body,\r\n });\r\n return id;\r\n };\r\n\r\n public readThreadMessage = async (id: string) => {\r\n await this.axios.put(`thread/message/${encodeURIComponent(id)}/read`);\r\n };\r\n\r\n public watchThreads = async () => {\r\n const { data } = await this.axios.get<ThreadListItem[]>(`thread/watch`);\r\n return data;\r\n };\r\n\r\n public thread = async (id: string) => {\r\n const { data } = await this.axios.get<Thread>(`thread/${encodeURIComponent(id)}`);\r\n return data;\r\n };\r\n\r\n public threadMessages = async ({\r\n threadId,\r\n skip,\r\n take,\r\n }: {\r\n threadId: string;\r\n skip: number;\r\n take: number;\r\n }) => {\r\n const searchParams = new URLSearchParams();\r\n searchParams.append('skip', skip.toString());\r\n searchParams.append('take', take.toString());\r\n const { data } = await this.axios.get<ThreadMessage[]>(\r\n `thread/${encodeURIComponent(threadId)}/message?${searchParams.toString()}`,\r\n );\r\n return data;\r\n };\r\n\r\n public watchThread = async (id: string, watch: boolean) => {\r\n await this.axios.put(`thread/${encodeURIComponent(id)}/watch`, { watch });\r\n };\r\n\r\n public connectToThread = async (id: string) => {\r\n const connectionCount = this._threadConnectionByThreadId.get(id) ?? 0;\r\n this._threadConnectionByThreadId.set(id, connectionCount + 1);\r\n\r\n if (connectionCount === 0) {\r\n this.connect().then(() => this._connection.invoke('ConnectToThread', id));\r\n }\r\n };\r\n\r\n public disconnectFromThread = async (id: string) => {\r\n const connectionCount = this._threadConnectionByThreadId.get(id) ?? 0;\r\n this._threadConnectionByThreadId.set(id, Math.max(0, connectionCount - 1));\r\n\r\n if (connectionCount === 1) {\r\n this.connect().then(() => this._connection.invoke('DisconnectFromThread', id));\r\n }\r\n };\r\n}\r\n\r\nexport function unsubscribe(...subscribers: Array<() => void>) {\r\n const result = () => subscribers.forEach((x) => x());\r\n result.when = (promise: Promise<any>) => promise.then(result);\r\n return result;\r\n}\r\n","import { ChatifyApiSettings, DEFAULT_MESSAGE_LIST_TAKE, __baseApi, __settings } from './baseApi';\r\nimport { useSelector } from 'react-redux';\r\nimport {\r\n Account,\r\n AddChatMemberRequest,\r\n Chat,\r\n ChatListItem,\r\n ChatMessage,\r\n RemoveChatMemberRequest,\r\n SendChatMessageRequest,\r\n SendThreadMessageRequest,\r\n Thread,\r\n ThreadMessage,\r\n ThreadWatchListItem,\r\n UpdateAccountRequest,\r\n calcThreadListUnreadCount,\r\n chatId,\r\n parseThreadMessageId,\r\n} from '../types';\r\nimport { unsubscribe } from '../client';\r\nimport { Debounce, DebounceValue } from '../debounce';\r\nimport { useMemo } from 'react';\r\n\r\nexport interface ChatMessageListResult {\r\n messages: ChatMessage[];\r\n hasMore: boolean;\r\n}\r\n\r\nexport interface ThreadMessageList {\r\n messages: ThreadMessage[];\r\n hasMore: boolean;\r\n}\r\n\r\nconst THREAD_MESSAGE_READ_QUEUE = new Debounce<string>({\r\n callback: (id) => __settings.client.readThreadMessage(id),\r\n compare: (a, b) => -a.localeCompare(b),\r\n groupBy: (id) => parseThreadMessageId(id)[0],\r\n timeout: 500,\r\n});\r\n\r\nconst CHAT_MESSAGE_READ_QUEUE = new Debounce<string>({\r\n callback: (id) => __settings.client.readChatMessage({ id }),\r\n compare: (a, b) => -a.localeCompare(b),\r\n groupBy: (id) => chatId(id),\r\n timeout: 500,\r\n});\r\n\r\nconst __chatifyApi = __baseApi.injectEndpoints({\r\n endpoints: (builder) => ({\r\n // ====================================================\r\n // ============== ACCOUNT ======================\r\n // ====================================================\r\n\r\n getAccountList: builder.query<Account[], { ids?: string[] }>({\r\n queryFn: async (args) => ({ data: await __settings.client.accounts(args) }),\r\n providesTags: ['account'],\r\n }),\r\n\r\n geCurrentUserAccount: builder.query<Account | null, void>({\r\n queryFn: async () => ({ data: await __settings.client.currentUserAccount() }),\r\n providesTags: ['account'],\r\n }),\r\n\r\n updateAccount: builder.mutation<void, UpdateAccountRequest>({\r\n queryFn: async (request) => {\r\n await __settings.client.updateAccount(request);\r\n return { data: null! };\r\n },\r\n invalidatesTags: ['account'],\r\n }),\r\n\r\n // ====================================================\r\n // ================ CHAT =======================\r\n // ====================================================\r\n\r\n getChat: builder.query<Chat, { id: string }>({\r\n queryFn: async ({ id }) => ({ data: await __settings.client.chat(id) }),\r\n providesTags: ['chat', 'account'],\r\n onCacheEntryAdded: async ({ id }, { cacheEntryRemoved, cacheDataLoaded, updateCachedData }) => {\r\n await cacheDataLoaded;\r\n\r\n unsubscribe(\r\n __settings.client.subscribe(\r\n 'chatify://chat-member-added',\r\n ([chatId, _, account, message, , read]) =>\r\n chatId === id &&\r\n updateCachedData((chat) => {\r\n chat.members.push(account);\r\n chat.lastReadMessageId = read ? message.id : chat.lastReadMessageId;\r\n }),\r\n ),\r\n __settings.client.subscribe(\r\n 'chatify://chat-member-removed',\r\n ([chatId, accountId, , message, read]) =>\r\n id === chatId &&\r\n updateCachedData((chat) => {\r\n chat.members = chat.members.filter((x) => x.id !== accountId);\r\n chat.lastReadMessageId = read ? message.id : chat.lastReadMessageId;\r\n }),\r\n ),\r\n __settings.client.subscribe(\r\n 'chatify://chat-name-changed',\r\n ([chatId, newName, message, read]) =>\r\n id === chatId &&\r\n updateCachedData((chat) => {\r\n chat.name = newName;\r\n chat.lastReadMessageId = read ? message.id : chat.lastReadMessageId;\r\n }),\r\n ),\r\n __settings.client.subscribe(\r\n 'chatify://chat-new-message',\r\n ([message]) =>\r\n id === message.chatId &&\r\n updateCachedData((chat) => {\r\n chat.lastReadMessageId =\r\n message.sentBy.id === __settings.me() ? message.id : chat.lastReadMessageId;\r\n }),\r\n ),\r\n __settings.client.subscribe(\r\n 'chatify://chat-message-read',\r\n ([events]) =>\r\n events.find((x) => x.chatId === id) &&\r\n updateCachedData((chat) => {\r\n const event = events.find((x) => x.chatId === id)!;\r\n chat.lastReadMessageId = event.newLastReadMessageId;\r\n }),\r\n ),\r\n ).when(cacheEntryRemoved);\r\n },\r\n }),\r\n\r\n addChat: builder.mutation<string, { name: string; members: string[] }>({\r\n queryFn: async ({ name, members }) => {\r\n const chatId = await __settings.client.addChat({\r\n name,\r\n members,\r\n });\r\n return { data: chatId };\r\n },\r\n }),\r\n\r\n updateChatName: builder.mutation<void, { id: string; name: string }>({\r\n queryFn: async ({ id, name }) => {\r\n await __settings.client.updateChatName({ id, name });\r\n return { data: null! };\r\n },\r\n }),\r\n\r\n // ====================================================\r\n // ============= CHAT LIST =====================\r\n // ====================================================\r\n\r\n getChatList: builder.query<ChatListItem[], void>({\r\n queryFn: async () => ({ data: await __settings.client.chats() }),\r\n providesTags: ['chat', 'account'],\r\n onCacheEntryAdded: async (_, { cacheEntryRemoved, cacheDataLoaded, updateCachedData }) => {\r\n await cacheDataLoaded;\r\n\r\n unsubscribe(\r\n __settings.client.subscribe('chatify://chat-created', ([chat]) =>\r\n updateCachedData((chatList) => {\r\n chatList.push(chat);\r\n }),\r\n ),\r\n\r\n __settings.client.subscribe('chatify://chat-new-message', ([message]) =>\r\n updateCachedData((chatList) => {\r\n const chat = chatList.find((x) => x.id === message.chatId);\r\n\r\n if (!chat) {\r\n return;\r\n }\r\n\r\n chat.message = message;\r\n\r\n if (message.sentBy.id === __settings.me()) {\r\n chat.lastReadMessageId = message.id;\r\n chat.totalUnreadCount = 0;\r\n }\r\n\r\n if (message.sentBy.id !== __settings.me()) {\r\n chat.totalUnreadCount++;\r\n }\r\n }),\r\n ),\r\n __settings.client.subscribe('chatify://chat-message-read', ([events]) =>\r\n updateCachedData((chatList) => {\r\n for (const event of events) {\r\n const chat = chatList.find((x) => x.id === event.chatId);\r\n\r\n if (!chat) {\r\n return;\r\n }\r\n\r\n chat.lastReadMessageId = event.newLastReadMessageId;\r\n chat.totalUnreadCount = chat.totalUnreadCount - event.readCount;\r\n }\r\n }),\r\n ),\r\n __settings.client.subscribe(\r\n 'chatify://chat-member-added',\r\n ([chatId, chatName, account, message, , read]) =>\r\n updateCachedData((chatList) => {\r\n const chat = chatList.find((x) => x.id === chatId);\r\n\r\n if (account.id === __settings.me() && !chat) {\r\n chatList.push({\r\n id: chatId,\r\n name: chatName,\r\n message,\r\n totalUnreadCount: read ? 0 : 1,\r\n active: true,\r\n lastReadMessageId: read ? message.id : null,\r\n });\r\n }\r\n\r\n if (!chat) {\r\n return;\r\n }\r\n\r\n chat.message = message;\r\n chat.active = true;\r\n\r\n if (read) {\r\n chat.totalUnreadCount = 0;\r\n chat.lastReadMessageId = message.id;\r\n } else {\r\n chat.totalUnreadCount++;\r\n }\r\n }),\r\n ),\r\n __settings.client.subscribe(\r\n 'chatify://chat-member-removed',\r\n ([chatId, accountId, deleteHistory, message, read]) =>\r\n updateCachedData((chatList) => {\r\n if (accountId === __settings.me() && deleteHistory) {\r\n return chatList.filter((x) => x.id !== chatId);\r\n }\r\n\r\n const chat = chatList.find((x) => x.id === chatId);\r\n\r\n if (!chat) {\r\n return;\r\n }\r\n\r\n chat.message = message;\r\n\r\n if (accountId === __settings.me()) {\r\n chat.active = false;\r\n }\r\n\r\n if (!read) {\r\n chat.totalUnreadCount++;\r\n } else {\r\n chat.totalUnreadCount = 0;\r\n chat.lastReadMessageId = message.id;\r\n }\r\n }),\r\n ),\r\n __settings.client.subscribe('chatify://chat-name-changed', ([chatId, newName, message, read]) =>\r\n updateCachedData((chatList) => {\r\n const chat = chatList.find((x) => x.id === chatId);\r\n if (!chat) return;\r\n\r\n chat.name = newName;\r\n chat.message = message;\r\n\r\n if (!read) {\r\n chat.totalUnreadCount++;\r\n } else {\r\n chat.totalUnreadCount = 0;\r\n chat.lastReadMessageId = message.id;\r\n }\r\n }),\r\n ),\r\n ).when(cacheEntryRemoved);\r\n },\r\n }),\r\n\r\n // ====================================================\r\n // ============ CHAT MEMBER ====================\r\n // ====================================================\r\n\r\n removeChatMember: builder.mutation<void, RemoveChatMemberRequest>({\r\n queryFn: async (args) => {\r\n await __settings.client.removeChatMember(args);\r\n return { data: null! };\r\n },\r\n }),\r\n\r\n addChatMember: builder.mutation<void, AddChatMemberRequest>({\r\n queryFn: async (args) => {\r\n await __settings.client.addChatMember(args);\r\n return { data: null! };\r\n },\r\n }),\r\n\r\n // ====================================================\r\n // ============ CHAT MESSAGE ===================\r\n // ====================================================\r\n\r\n getChatMessageList: builder.query<ChatMessageListResult, { chatId: string }>({\r\n queryFn: async ({ chatId }) => {\r\n const messages = await __settings.client.chatMessages({\r\n chatId,\r\n skip: 0,\r\n take: DEFAULT_MESSAGE_LIST_TAKE + 1,\r\n });\r\n return {\r\n data: {\r\n messages: messages.slice(0, DEFAULT_MESSAGE_LIST_TAKE),\r\n hasMore: messages.length === DEFAULT_MESSAGE_LIST_TAKE + 1,\r\n },\r\n };\r\n },\r\n providesTags: ['message', 'chat', 'account'],\r\n onCacheEntryAdded: async ({ chatId }, { dispatch, cacheEntryRemoved, cacheDataLoaded }) => {\r\n await cacheDataLoaded;\r\n\r\n unsubscribe(\r\n __settings.client.subscribe('chatify://chat-new-message', ([message]) => {\r\n message.chatId === chatId &&\r\n dispatch(\r\n chatifyApi.util.updateQueryData('getChatMessageList', { chatId }, (draft) => {\r\n draft.messages.unshift(message);\r\n }),\r\n );\r\n }),\r\n\r\n __settings.client.subscribe('chatify://chat-member-added', ([eventChatId, , , message]) => {\r\n eventChatId === chatId &&\r\n dispatch(\r\n chatifyApi.util.updateQueryData('getChatMessageList', { chatId }, (draft) => {\r\n draft.messages.unshift(message);\r\n }),\r\n );\r\n }),\r\n\r\n __settings.client.subscribe('chatify://chat-member-removed', ([eventChatId, , , message]) => {\r\n eventChatId === chatId &&\r\n dispatch(\r\n chatifyApi.util.updateQueryData('getChatMessageList', { chatId }, (draft) => {\r\n draft.messages.unshift(message);\r\n }),\r\n );\r\n }),\r\n\r\n __settings.client.subscribe('chatify://chat-name-changed', ([eventChatId, , message]) => {\r\n eventChatId === chatId &&\r\n dispatch(\r\n chatifyApi.util.updateQueryData('getChatMessageList', { chatId }, (draft) => {\r\n draft.messages.unshift(message);\r\n }),\r\n );\r\n }),\r\n ).when(cacheEntryRemoved);\r\n },\r\n }),\r\n\r\n fetchNextChatMessageList: builder.mutation<void, { chatId: string }>({\r\n queryFn: async ({ chatId }, { getState }) => {\r\n const current = chatifyApi.endpoints.getChatMessageList.select({ chatId })(getState() as any);\r\n const messages = await __settings.client.chatMessages({\r\n chatId,\r\n skip: current.data!.messages.length,\r\n take: DEFAULT_MESSAGE_LIST_TAKE + 1,\r\n });\r\n return {\r\n data: null!,\r\n meta: {\r\n messages: messages.slice(0, DEFAULT_MESSAGE_LIST_TAKE),\r\n hasMore: messages.length === DEFAULT_MESSAGE_LIST_TAKE + 1,\r\n },\r\n };\r\n },\r\n onQueryStarted: async ({ chatId }, { dispatch, queryFulfilled }) => {\r\n const result = await queryFulfilled;\r\n const meta: ChatMessageListResult = result.meta! as any;\r\n\r\n dispatch(\r\n chatifyApi.util.updateQueryData('getChatMessageList', { chatId }, (draft) => {\r\n draft.hasMore = meta.hasMore;\r\n draft.messages.push(...meta!.messages);\r\n }),\r\n );\r\n },\r\n }),\r\n\r\n sendChatMessage: builder.mutation<void, SendChatMessageRequest>({\r\n queryFn: async ({ chatId, text, files }) => {\r\n await __settings.client.sendChatMessage({\r\n chatId,\r\n text,\r\n files,\r\n });\r\n\r\n return { data: null! };\r\n },\r\n }),\r\n\r\n readChatMessage: builder.mutation<void, { id: string }>({\r\n queryFn: async () => {\r\n return { data: null! };\r\n },\r\n onQueryStarted: async ({ id }, { dispatch }) => {\r\n CHAT_MESSAGE_READ_QUEUE.push(id);\r\n dispatch(chatifyApi.endpoints.getChatMessageReadQueue.initiate(undefined, { forceRefetch: true }));\r\n },\r\n }),\r\n\r\n getChatMessageReadQueue: builder.query<DebounceValue<string>[], void>({\r\n queryFn: async () => ({ data: CHAT_MESSAGE_READ_QUEUE.units }),\r\n onCacheEntryAdded: async (_, { dispatch, cacheEntryRemoved }) => {\r\n unsubscribe(\r\n CHAT_MESSAGE_READ_QUEUE.subscribe((value) => {\r\n dispatch(\r\n chatifyApi.util.updateQueryData('getChatMessageReadQueue', undefined, () => value.units),\r\n );\r\n }),\r\n ).when(cacheEntryRemoved);\r\n },\r\n }),\r\n\r\n // ====================================================\r\n // =============== THREAD ======================s\r\n // ====================================================\r\n getWatchThreadList: builder.query<ThreadWatchListItem[], void>({\r\n queryFn: async () => {\r\n const threads = await __settings.client.watchThreads();\r\n return { data: threads };\r\n },\r\n providesTags: ['account', 'thread'],\r\n onCacheEntryAdded: async (_, { cacheEntryRemoved, cacheDataLoaded, updateCachedData }) => {\r\n await cacheDataLoaded;\r\n\r\n unsubscribe(\r\n __settings.client.subscribe(\r\n 'chatify://thread-created',\r\n ([thread, watch]) =>\r\n watch &&\r\n updateCachedData((threads) => {\r\n threads.push(thread);\r\n }),\r\n ),\r\n __settings.client.subscribe('chatify://thread-message-new', ([threadId, message, readForId]) =>\r\n updateCachedData((threads) => {\r\n const thread = threads.find((x) => x.id === threadId);\r\n if (!thread) return;\r\n\r\n thread.lastMessage = message;\r\n\r\n if (readForId === __settings.me()) {\r\n thread.lastReadMessageId = message.id;\r\n }\r\n }),\r\n ),\r\n __settings.client.subscribe('chatify://thread-message-read', ([threadId, messageId]) =>\r\n updateCachedData((threads) => {\r\n const thread = threads.find((x) => x.id === threadId);\r\n if (!thread) return;\r\n\r\n thread.lastReadMessageId = messageId;\r\n }),\r\n ),\r\n __settings.client.subscribe('chatify://thread-watch-added', ([thread]) =>\r\n updateCachedData((threads) => {\r\n threads.push(thread);\r\n }),\r\n ),\r\n __settings.client.subscribe('chatify://thread-watch-removed', ([id]) =>\r\n updateCachedData((threads) => {\r\n const index = threads.findIndex((x) => x.id === id);\r\n if (index !== -1) threads.splice(index, 1);\r\n }),\r\n ),\r\n __settings.client.subscribe('chatify://thread-updated', ([threadId, threadName]) =>\r\n updateCachedData((threads) => {\r\n const thread = threads.find((x) => x.id === threadId);\r\n if (!thread) return;\r\n\r\n thread.name = threadName;\r\n }),\r\n ),\r\n ).when(cacheEntryRemoved);\r\n },\r\n }),\r\n\r\n getThread: builder.query<Thread, { id: string }>({\r\n queryFn: async ({ id }) => {\r\n const threads = await __settings.client.thread(id);\r\n return { data: threads };\r\n },\r\n providesTags: ['account', 'thread'],\r\n onCacheEntryAdded: async ({ id }, { cacheEntryRemoved, cacheDataLoaded, updateCachedData }) => {\r\n await cacheDataLoaded;\r\n\r\n unsubscribe(\r\n __settings.client.subscribe(\r\n 'chatify://thread-message-read',\r\n ([threadId, messageId]) =>\r\n id === threadId &&\r\n updateCachedData((t) => {\r\n t.lastReadMessageId = messageId;\r\n }),\r\n ),\r\n __settings.client.subscribe(\r\n 'chatify://thread-message-new',\r\n ([threadId, message, readForId]) =>\r\n id === threadId &&\r\n updateCachedData((thread) => {\r\n thread.lastMessageId = message.id;\r\n thread.lastReadMessageId =\r\n readForId === __settings.me() ? message.id : thread.lastReadMessageId;\r\n }),\r\n ),\r\n __settings.client.subscribe(\r\n 'chatify://thread-watch-added',\r\n ([threadListItem]) =>\r\n id === threadListItem.id &&\r\n updateCachedData((thread) => {\r\n thread.watch = true;\r\n thread.lastMessageId = threadListItem.lastMessage?.id ?? null;\r\n thread.lastReadMessageId = threadListItem.lastReadMessageId ?? null;\r\n }),\r\n ),\r\n __settings.client.subscribe(\r\n 'chatify://thread-watch-removed',\r\n ([threadId]) =>\r\n id === threadId &&\r\n updateCachedData((thread) => {\r\n thread.watch = false;\r\n }),\r\n ),\r\n __settings.client.subscribe(\r\n 'chatify://thread-updated',\r\n ([threadId, threadName]) =>\r\n id === threadId &&\r\n updateCachedData((thread) => {\r\n thread.name = threadName;\r\n }),\r\n ),\r\n ).when(cacheEntryRemoved);\r\n },\r\n }),\r\n\r\n watchThread: builder.mutation<void, { id: string; watch: boolean }>({\r\n queryFn: async ({ id, watch }) => {\r\n await __settings.client.watchThread(id, watch);\r\n return { data: null! };\r\n },\r\n }),\r\n\r\n // ====================================================\r\n // ============ THREAD MESSAGE =================\r\n // ====================================================\r\n\r\n getThreadMessageList: builder.query<ThreadMessageList, { threadId: string }>({\r\n queryFn: async (args) => {\r\n const requestArgs = {\r\n skip: 0,\r\n take: DEFAULT_MESSAGE_LIST_TAKE + 1,\r\n ...args,\r\n };\r\n const messages = await __settings.client.threadMessages(requestArgs);\r\n return {\r\n data: {\r\n messages: messages.slice(0, DEFAULT_MESSAGE_LIST_TAKE),\r\n hasMore: messages.length === DEFAULT_MESSAGE_LIST_TAKE + 1,\r\n },\r\n };\r\n },\r\n providesTags: ['account', 'thread', 'thread-message'],\r\n onCacheEntryAdded: async ({ threadId }, { cacheEntryRemoved, cacheDataLoaded, updateCachedData }) => {\r\n await cacheDataLoaded;\r\n\r\n unsubscribe(\r\n __settings.client.subscribe('chatify://thread-message-new', ([_threadId, message]) => {\r\n threadId === _threadId &&\r\n updateCachedData((messageList) => {\r\n !messageList.messages.some((x) => x.id === message.id) &&\r\n messageList.messages.unshift(message);\r\n });\r\n }),\r\n ).when(cacheEntryRemoved);\r\n },\r\n }),\r\n\r\n fetchNextThreadMessageList: builder.mutation<void, { threadId: string }>({\r\n queryFn: async ({ threadId }, { getState }) => {\r\n const current = chatifyApi.endpoints.getThreadMessageList.select({ threadId })(getState() as any);\r\n const messages = await __settings.client.threadMessages({\r\n threadId,\r\n skip: current.data!.messages.length,\r\n take: DEFAULT_MESSAGE_LIST_TAKE + 1,\r\n });\r\n return {\r\n data: null!,\r\n meta: {\r\n messages: messages.slice(0, DEFAULT_MESSAGE_LIST_TAKE),\r\n hasMore: messages.length === DEFAULT_MESSAGE_LIST_TAKE + 1,\r\n },\r\n };\r\n },\r\n onQueryStarted: async ({ threadId }, { dispatch, queryFulfilled }) => {\r\n const result = await queryFulfilled;\r\n const meta: ThreadMessageList = result.meta! as any;\r\n\r\n dispatch(\r\n chatifyApi.util.updateQueryData('getThreadMessageList', { threadId }, (draft) => {\r\n draft.hasMore = meta.hasMore;\r\n draft.messages.push(...meta!.messages);\r\n }),\r\n );\r\n },\r\n }),\r\n\r\n sendThreadMessage: builder.mutation<string, SendThreadMessageRequest>({\r\n queryFn: async (args) => {\r\n const id = await __settings.client.sendThreadMessage(args);\r\n return { data: id };\r\n },\r\n }),\r\n\r\n readThreadMessage: builder.mutation<void, { id: string }>({\r\n queryFn: async () => {\r\n return { data: null! };\r\n },\r\n onQueryStarted: async ({ id }, { dispatch }) => {\r\n THREAD_MESSAGE_READ_QUEUE.push(id);\r\n dispatch(chatifyApi.endpoints.getThreadMessageReadQueue.initiate(undefined, { forceRefetch: true }));\r\n },\r\n }),\r\n\r\n getThreadMessageReadQueue: builder.query<DebounceValue<string>[], void>({\r\n queryFn: async () => ({ data: THREAD_MESSAGE_READ_QUEUE.units }),\r\n onCacheEntryAdded: async (_, { dispatch, cacheEntryRemoved }) => {\r\n unsubscribe(\r\n THREAD_MESSAGE_READ_QUEUE.subscribe((value) => {\r\n dispatch(\r\n chatifyApi.util.updateQueryData('getThreadMessageReadQueue', undefined, () => value.units),\r\n );\r\n }),\r\n ).when(cacheEntryRemoved);\r\n },\r\n }),\r\n }),\r\n});\r\n\r\nexport function useChatListItem(id: string | null) {\r\n return useSelector((state: any) =>\r\n id != null\r\n ? __chatifyApi.endpoints.getChatList\r\n .select()(state)\r\n .data?.find((x) => x.id === id)\r\n : null,\r\n );\r\n}\r\n\r\nexport function useUnreadThreadMessageCount() {\r\n const { data: threads, ...state } = chatifyApi.useGetWatchThreadListQuery();\r\n const count = useMemo(() => (threads != null ? calcThreadListUnreadCount(threads) : null), [threads]);\r\n return [count, state] as const;\r\n}\r\n\r\ntype ChatifyApi = typeof __chatifyApi & {\r\n settings: ChatifyApiSettings;\r\n useChatListItem: typeof useChatListItem;\r\n useUnreadThreadMessageCount: typeof useUnreadThreadMessageCount;\r\n};\r\n\r\nexport const chatifyApi: ChatifyApi = Object.assign(__chatifyApi, {\r\n settings: __settings,\r\n useChatListItem,\r\n useUnreadThreadMessageCount,\r\n});\r\n","import { FC, ForwardedRef, forwardRef } from 'react';\r\nimport { Account } from '../../core';\r\nimport { Avatar as AntdAvatar } from 'antd';\r\nimport { customize } from '../customize';\r\n\r\nexport interface AvatarProps {\r\n account: Account;\r\n}\r\n\r\nconst _Avatar: FC<AvatarProps> = forwardRef(\r\n (props: AvatarProps, forwardRef: ForwardedRef<HTMLSpanElement>) => {\r\n const { account } = props;\r\n\r\n return <AntdAvatar ref={forwardRef} src={account.avatar} />;\r\n },\r\n);\r\n\r\n_Avatar.displayName = 'Avatar';\r\n\r\nexport const Avatar = customize('Avatar', _Avatar);\r\n","import dayjs from 'dayjs';\r\nimport React, { useContext } from 'react';\r\nimport { SystemMessageText } from '../core';\r\n\r\nexport interface LocalizerBase {\r\n isToday: (value: string) => boolean;\r\n timestamp: (value: string) => string;\r\n dateTime: (value: string) => string;\r\n system: Record<SystemMessageText, (key: SystemMessageText, payload: any | null) => string>;\r\n message: {\r\n read: () => React.ReactNode;\r\n reading: () => React.ReactNode;\r\n sending: () => React.ReactNode;\r\n };\r\n addChat: {\r\n title: () => React.ReactNode;\r\n name: {\r\n label: () => React.ReactNode;\r\n required: () => string;\r\n max250: () => string;\r\n };\r\n members: {\r\n label: () => React.ReactNode;\r\n required: () => string;\r\n };\r\n submitBtn: () => React.ReactNode;\r\n };\r\n\r\n input: {\r\n placeholder: (type: 'compact' | 'default') => string;\r\n };\r\n\r\n settings: {\r\n members: () => string;\r\n };\r\n\r\n size: {\r\n bytes: (value: number) => string;\r\n kb: (value: number) => string;\r\n mb: (value: number) => string;\r\n };\r\n\r\n chatList: {\r\n topShown: (count: number) => string;\r\n };\r\n\r\n autoReply: {\r\n buttonTitle: () => string;\r\n title: () => React.ReactNode;\r\n period: {\r\n label: () => React.ReactNode;\r\n required: () => string;\r\n format: () => string;\r\n };\r\n text: {\r\n label: () => React.ReactNode;\r\n required: () => string;\r\n };\r\n submitBtn: () => React.ReactNode;\r\n clearBtn: () => React.ReactNode;\r\n };\r\n\r\n members: {\r\n title: (chatName: string) => React.ReactNode;\r\n };\r\n}\r\n\r\nexport interface Localizer extends LocalizerBase {}\r\n\r\nexport const LocalizerContext = React.createContext<Localizer>(null!);\r\n\r\nexport function useLocalizer() {\r\n return useContext(LocalizerContext);\r\n}\r\n\r\nconst base: LocalizerBase = {\r\n isToday: (value: string) => dayjs(value).isSame(dayjs(), 'day'),\r\n timestamp: (value: string) => dayjs(value).format('HH:mm'),\r\n dateTime: (value: string) => dayjs(value).format('DD/MM/YYYY HH:mm'),\r\n message: {\r\n read: () => 'Read',\r\n reading: () => 'Reading...',\r\n sending: () => 'Sending...',\r\n },\r\n addChat: {\r\n title: () => 'Add chat',\r\n name: {\r\n label: () => 'Name',\r\n required: () => `Name is required`,\r\n max250: () => 'Max 250 characters allowed',\r\n },\r\n members: {\r\n label: () => 'Members',\r\n required: () => 'Members is required',\r\n },\r\n submitBtn: () => 'Submit',\r\n },\r\n system: {\r\n 'chatify://chat-created': () => 'Chat created',\r\n 'chatify://member-added': () => 'New member added',\r\n 'chatify://member-removed': () => 'Member removed',\r\n 'chatify://chat-name-changed': (_, { newName }: { newName: string }) =>\r\n `Chat name changed to '${newName}'`,\r\n },\r\n\r\n input: {\r\n placeholder: (type) =>\r\n type === 'default'\r\n ? 'Start typing... (Press Enter to send, and Shift+Enter to start a new line)'\r\n : 'Type a message...',\r\n },\r\n\r\n settings: {\r\n members: () => 'Members',\r\n },\r\n\r\n size: {\r\n bytes: (value: number) =>\r\n `${value.toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: 2 })} bytes`,\r\n kb: (value: number) =>\r\n `${value.toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: 2 })} KB`,\r\n mb: (value: number) =>\r\n `${value.toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: 2 })} MB`,\r\n },\r\n\r\n chatList: {\r\n topShown: (count: number) => `Latest active ${count} chat${count !== 1 ? 's' : ''} shown`,\r\n },\r\n\r\n members: {\r\n title: (chatName: string) => `Members of ${chatName}`,\r\n },\r\n\r\n autoReply: {\r\n buttonTitle: () => 'Auto-reply',\r\n title: () => 'Auto-reply',\r\n period: {\r\n label: () => 'Period',\r\n required: () => 'Please select start and end date',\r\n format: () => 'DD/MM/YYYY',\r\n },\r\n text: { label: () => 'Message', required: () => 'Please enter message' },\r\n submitBtn: () => 'Submit',\r\n clearBtn: () => 'Clear',\r\n },\r\n};\r\n\r\nexport const defaultLocalizer: Localizer = base as unknown as Localizer;\r\n","import { Button, Col, List, Row, Space, Tooltip } from 'antd';\r\nimport { chatifyApi } from '../../../core';\r\nimport { customize } from '../../customize';\r\nimport { useCallback, useMemo } from 'react';\r\nimport { Icon } from '../../common/Icon';\r\nimport { Avatar } from '../../common/Avatar';\r\nimport { useChatContext } from '../ChatContext';\r\nimport { LeftOutlined } from '@ant-design/icons';\r\nimport { useLocalizer } from '@/ui/localizer';\r\n\r\ninterface ChatMemberListItemProps {\r\n id: string;\r\n chatId: string;\r\n}\r\n\r\nfunction useAdd(chatId: string, accountId: string, withHistory: boolean) {\r\n const [add, state] = chatifyApi.useAddChatMemberMutation();\r\n const onAdd = useCallback(\r\n () => add({ chatId, accountId, withHistory }),\r\n [add, chatId, accountId, withHistory],\r\n );\r\n return [onAdd, state] as const;\r\n}\r\n\r\nfunction useRemove(chatId: string, accountId: string, deleteHistory: boolean) {\r\n const [remove, state] = chatifyApi.useRemoveChatMemberMutation();\r\n const onRemove = useCallback(\r\n () => remove({ chatId, accountId, deleteHistory }),\r\n [remove, chatId, accountId, deleteHistory],\r\n );\r\n return [onRemove, state] as const;\r\n}\r\n\r\nconst ChatMemberListItem = customize('ChatMemberListItem', (props: ChatMemberListItemProps) => {\r\n const { chatId } = props;\r\n const { data: chat } = chatifyApi.useGetChatQuery({ id: chatId });\r\n const { data: accounts } = chatifyApi.useGetAccountListQuery({});\r\n const account = accounts!.find((x) => x.id === props.id)!;\r\n const isMember = chat!.members.some((x) => x.id === account.id);\r\n const [onAddWithoutHistory] = useAdd(chatId, account.id, false);\r\n const [onAddWithHistory] = useAdd(chatId, account.id, true);\r\n const [onRemoveKeepHistory] = useRemove(chatId, account.id, false);\r\n const [onRemoveDeleteHistory] = useRemove(chatId, account.id, true);\r\n\r\n return (\r\n <List.Item\r\n className=\"wxchtf-chat-members-list-item\"\r\n actions={\r\n isMember\r\n ? [\r\n <Tooltip key=\"remove\" title=\"Remove (keep history)\">\r\n <Button onClick={onRemoveKeepHistory} type=\"link\" icon={<Icon type=\"remove-member\" />} />\r\n </Tooltip>,\r\n <Tooltip key=\"remove_delete_history\" title=\"Remove (delete history)\">\r\n <Button\r\n onClick={onRemoveDeleteHistory}\r\n type=\"link\"\r\n icon={<Icon type=\"remove-member-delete-history\" />}\r\n />\r\n </Tooltip>,\r\n ]\r\n : [\r\n <Tooltip key=\"add_no_history\" title=\"Add (no history)\">\r\n <Button onClick={onAddWithoutHistory} type=\"link\" icon={<Icon type=\"add-member\" />} />\r\n </Tooltip>,\r\n <Tooltip key=\"add\" title=\"Add (share history)\">\r\n <Button\r\n onClick={onAddWithHistory}\r\n type=\"link\"\r\n icon={<Icon type=\"add-member-with-history\" />}\r\n />\r\n </Tooltip>,\r\n ]\r\n }\r\n >\r\n <Space>\r\n <Avatar account={account} />\r\n <span>{account.name}</span>\r\n </Space>\r\n </List.Item>\r\n );\r\n});\r\n\r\nexport const ChatMembersPanel = customize('ChatMembersPanel', () => {\r\n const { id, compact, onShowMembers } = useChatContext();\r\n const localizer = useLocalizer();\r\n const { data: chat } = chatifyApi.useGetChatQuery({ id });\r\n const { data: accounts } = chatifyApi.useGetAccountListQuery({});\r\n\r\n const ordered = useMemo(\r\n () =>\r\n accounts\r\n ?.slice()\r\n .sort(\r\n (a, b) =>\r\n (chat?.members.some((m) => m.id === a.id) ? -100 : 0) -\r\n (chat?.members.some((m) => m.id === b.id) ? -100 : 0) +\r\n a.name.localeCompare(b.name),\r\n ),\r\n [accounts, chat],\r\n );\r\n\r\n if (!chat?.members || !accounts) {\r\n return null;\r\n }\r\n\r\n return (\r\n <div className=\"wxchtf-chat-members-panel\">\r\n {compact && (\r\n <div className=\"wxchtf-chat-members-panel-header\">\r\n <Row wrap={false} align=\"middle\" gutter={10}>\r\n <Col flex=\"none\">\r\n <Button type=\"text\" icon={<LeftOutlined />} onClick={() => onShowMembers(false)} />\r\n </Col>\r\n <Col>\r\n <span className=\"wxchtf-chat-members-panel-title\">{localizer.members.title(chat.name)}</span>\r\n </Col>\r\n </Row>\r\n </div>\r\n )}\r\n <List\r\n className=\"wxchtf-chat-members-list\"\r\n dataSource={ordered}\r\n renderItem={(item) => <ChatMemberListItem id={item.id} chatId={id} />}\r\n />\r\n </div>\r\n );\r\n});\r\n","import { chatifyApi } from '../../../core';\r\nimport { Tooltip } from 'antd';\r\nimport { customize } from '../../customize';\r\nimport { Avatar as AntdAvatar } from 'antd';\r\nimport { Avatar } from '../../common/Avatar';\r\nimport { useChatContext } from '../ChatContext';\r\n\r\nexport const ChatMembersPreview = customize('ChatMembersPreview', () => {\r\n const { id } = useChatContext();\r\n const { data: chat } = chatifyApi.useGetChatQuery({ id });\r\n\r\n if (!chat?.members) {\r\n return null;\r\n }\r\n\r\n return (\r\n <AntdAvatar.Group max={{ count: 5 }}>\r\n {chat.members.map((x) => (\r\n <Tooltip key={x.id} title={x.name}>\r\n <Avatar account={x} />\r\n </Tooltip>\r\n ))}\r\n </AntdAvatar.Group>\r\n );\r\n});\r\n","import { Button } from 'antd';\r\nimport { customize } from '../../customize';\r\nimport { Icon } from '../../common/Icon';\r\nimport { File } from '../../../core';\r\nimport { useCallback, useEffect, useRef } from 'react';\r\n\r\nexport interface InputFilesBoxProps {\r\n value: File[];\r\n accept?: string;\r\n loading?: boolean;\r\n disabled?: boolean;\r\n onAddedClick?: () => void;\r\n onUpload: (value: globalThis.File[]) => void;\r\n}\r\n\r\nexport const InputFileButton = customize('InputFileButton', (props: InputFilesBoxProps) => {\r\n const { onUpload, onAddedClick, accept, loading, value, disabled } = props;\r\n const inputRef = useRef<HTMLInputElement | null>(null);\r\n const onClick = useCallback(() => inputRef.current?.click(), []);\r\n const countButtonRef = useRef<HTMLButtonElement | null>(null);\r\n\r\n useEffect(() => {\r\n countButtonRef.current?.classList.add('active');\r\n }, [value]);\r\n\r\n const onCountButtonAnimationEnd = useCallback(() => {\r\n countButtonRef.current?.classList.remove('active');\r\n }, []);\r\n\r\n const onInputChange = useCallback(\r\n (e: React.ChangeEvent<HTMLInputElement>) => {\r\n const files = e.target.files;\r\n files && files.length > 0 && onUpload(Array.from(files));\r\n },\r\n [onUpload],\r\n );\r\n\r\n return (\r\n <>\r\n <Button\r\n loading={loading}\r\n onClick={onClick}\r\n type=\"link\"\r\n disabled={disabled}\r\n icon={<Icon type=\"attach\" />}\r\n className=\"wxchtf-add-files-btn\"\r\n />\r\n {value.length > 0 && (\r\n <Button\r\n ref={countButtonRef}\r\n className=\"wxchtf-add-files-added-btn\"\r\n onAnimationIteration={onCountButtonAnimationEnd}\r\n onClick={onAddedClick}\r\n type=\"link\"\r\n disabled={disabled}\r\n icon={<>+{value.length}</>}\r\n />\r\n )}\r\n <input\r\n value=\"\"\r\n accept={accept}\r\n onChange={onInputChange}\r\n ref={inputRef}\r\n type=\"file\"\r\n multiple\r\n style={{ display: 'none' }}\r\n />\r\n </>\r\n );\r\n});\r\n\r\nexport const InputFilesBox = customize('InputFilesBox', (props: InputFilesBoxProps) => {\r\n return (\r\n <div className=\"wxchtf-add-files-box\">\r\n <InputFileButton {...props} />\r\n </div>\r\n );\r\n});\r\n","import React from 'react';\r\nimport { MessageBase, MessageBody } from '../../core';\r\nimport type { Flippo } from '@webinex/flippo';\r\n\r\nexport interface ConversationValue {\r\n id: string;\r\n name: string;\r\n active: boolean;\r\n lastReadMessageId: string | null;\r\n}\r\n\r\nexport interface ConversationContextValue extends ConversationValue {\r\n messages?: MessageBase[];\r\n hasMore?: boolean;\r\n nextLoading: boolean;\r\n noReadTracking?: boolean;\r\n compact: boolean;\r\n\r\n isReading?: (id: string) => boolean;\r\n onNext: () => void;\r\n onSend?: (message: MessageBody) => void;\r\n onRead?: (id: string) => void;\r\n flippo?: Flippo;\r\n onClose?: () => void;\r\n}\r\n\r\nexport const ConversationContext = React.createContext<ConversationContextValue>(undefined!);\r\n\r\nexport function useConversation() {\r\n return React.useContext(ConversationContext);\r\n}\r\n","import { Input } from 'antd';\r\nimport { customize } from '../../customize';\r\nimport { isHotkey } from 'is-hotkey';\r\nimport { RefObject, memo, useCallback } from 'react';\r\nimport { useLocalizer } from '../../localizer';\r\nimport { TextAreaProps } from 'antd/es/input';\r\nimport { useConversation } from '../ConversationContext';\r\n\r\nexport interface TextInputBoxProps {\r\n value: string;\r\n onChange: (value: string) => void;\r\n onSend: (value: string) => void;\r\n disabled?: boolean;\r\n inputRef?: RefObject<HTMLTextAreaElement>;\r\n}\r\n\r\nconst isEnter = isHotkey('enter');\r\nconst isCtrlEnter = isHotkey('ctrl+enter');\r\n\r\nconst AUTO_SIZE: TextAreaProps['autoSize'] = { maxRows: 5, minRows: 1 };\r\n\r\nexport const InputTextBox = customize(\r\n 'InputTextBox',\r\n memo((props: TextInputBoxProps) => {\r\n const { value, onChange, onSend, disabled, inputRef } = props;\r\n const localizer = useLocalizer();\r\n const { compact } = useConversation();\r\n\r\n const onInputChange = useCallback(\r\n (e: React.ChangeEvent<HTMLTextAreaElement>) => onChange(e.target.value),\r\n [onChange],\r\n );\r\n\r\n const onKeyDown = useCallback(\r\n (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\r\n if (disabled) {\r\n e.preventDefault();\r\n return;\r\n }\r\n\r\n if (isEnter(e) || isCtrlEnter(e)) {\r\n e.preventDefault();\r\n onSend(value);\r\n }\r\n },\r\n [onSend, value, disabled],\r\n );\r\n\r\n return (\r\n <div className=\"wxchtf-text-input-box\">\r\n <Input.TextArea\r\n ref={inputRef}\r\n value={value}\r\n onChange={onInputChange}\r\n autoSize={AUTO_SIZE}\r\n className=\"wxchtf-text-input-textarea\"\r\n placeholder={localizer.input.placeholder(compact ? 'compact' : 'default')}\r\n onKeyDown={onKeyDown}\r\n />\r\n </div>\r\n );\r\n }),\r\n);\r\n","import { Button } from 'antd';\r\nimport { customize } from '../../customize';\r\nimport { Icon } from '../../common/Icon';\r\n\r\nexport interface InputSubmitButtonBoxProps {\r\n onSubmit: () => void;\r\n disabled?: boolean;\r\n loading?: boolean;\r\n}\r\n\r\nexport const InputSubmitButtonBox = customize('InputSubmitButtonBox', (props: InputSubmitButtonBoxProps) => {\r\n const { onSubmit, disabled, loading } = props;\r\n\r\n return (\r\n <div className=\"wxchtf-submit-btn-box\">\r\n <Button\r\n onClick={onSubmit}\r\n type=\"link\"\r\n icon={<Icon type=\"send\" />}\r\n className=\"wxchtf-submit-btn\"\r\n disabled={disabled}\r\n loading={loading}\r\n />\r\n </div>\r\n );\r\n});\r\n","import { Skeleton } from 'antd';\r\nimport { customize } from '../customize';\r\n\r\nexport interface MessageSkeletonProps {\r\n count?: number;\r\n}\r\n\r\nexport const MessageSkeleton = customize('MessageSkeleton', (props: MessageSkeletonProps) => {\r\n const { count = 1 } = props;\r\n return (\r\n <>\r\n {Array.from(Array(count)).map((_, index) => (\r\n <div className=\"wxchtf-message-skeleton\" key={index}>\r\n <Skeleton.Avatar className=\"wxchtf-avatar\" active />\r\n <Skeleton.Button active className=\"wxchtf-content\" />\r\n </div>\r\n ))}\r\n </>\r\n );\r\n});\r\n","import { customize } from '../../customize';\r\nimport type { ChatListItemBoxProps } from './ChatListItemBox';\r\n\r\nexport const ChatListItemName = customize('ChatListItemName', (props: ChatListItemBoxProps) => {\r\n const { chat } = props;\r\n\r\n return <div className=\"wxchtf-chat-name\">{chat.name}</div>;\r\n});\r\n","import { customize } from '../../customize';\r\nimport { ChatListItemBoxProps } from './ChatListItemBox';\r\n\r\nexport const ChatListItemUnreadCount = customize('ChatListItemUnreadCount', (props: ChatListItemBoxProps) => {\r\n const { totalUnreadCount: unreadCount } = props.chat;\r\n\r\n if (unreadCount == null || unreadCount <= 0) {\r\n return null;\r\n }\r\n\r\n return <div className=\"wxchtf-unread-count\">{unreadCount}</div>;\r\n});\r\n","import { Ref } from 'react';\r\nimport { customize } from '../../customize';\r\nimport { Localizer, useLocalizer } from '../../localizer';\r\nimport { MessageBase } from '../../../core';\r\n\r\nexport interface SystemMessageRowProps {\r\n message: MessageBase;\r\n containerRef?: Ref<HTMLDivElement>;\r\n}\r\n\r\nexport function formatSystemMessage(localizer: Localizer, text: string): React.ReactNode {\r\n const [key, payload] = text.split('::', 2);\r\n const data = payload ? JSON.parse(payload) : null;\r\n return localizer.system[key as keyof Localizer['system']](key as any, data);\r\n}\r\n\r\nexport const SystemMessageRow = customize('SystemMessageRow', (props: SystemMessageRowProps) => {\r\n const { message, containerRef } = props;\r\n const { text, sentAt } = message;\r\n const localizer = useLocalizer();\r\n\r\n return (\r\n <div ref={containerRef} className=\"wxchtf-system-message\">\r\n <div className=\"wxchtf-text\">{text && formatSystemMessage(localizer, text)}</div>\r\n <div className=\"wxchtf-timestamp\">{localizer.timestamp(sentAt)}</div>\r\n </div>\r\n );\r\n});\r\n","import { FC, RefObject, useEffect, useMemo, useRef } from 'react';\r\nimport { MessageBoxProps } from '../Message';\r\nimport { useConversation } from '../ConversationContext';\r\n\r\nexport interface MessageReadObserverProps extends MessageBoxProps {\r\n messageRef: RefObject<HTMLDivElement | null>;\r\n}\r\nconst Observer: FC<MessageReadObserverProps> = (props) => {\r\n const { message, messageRef } = props;\r\n const { onRead, lastReadMessageId } = useConversation();\r\n const isRead = lastReadMessageId != null && message.id.localeCompare(lastReadMessageId) <= 0;\r\n const readRef = useRef(isRead);\r\n\r\n useEffect(() => {\r\n readRef.current = readRef.current || isRead;\r\n }, [isRead]);\r\n\r\n const observer = useMemo(\r\n () =>\r\n new IntersectionObserver(([entry]) => {\r\n if (entry.isIntersecting && !readRef.current) {\r\n readRef.current = true;\r\n onRead?.(message.id);\r\n }\r\n }),\r\n\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [],\r\n );\r\n\r\n useEffect(() => {\r\n observer.observe(messageRef.current!);\r\n return () => observer.disconnect();\r\n\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [observer]);\r\n\r\n return <></>;\r\n};\r\n\r\nexport function MessageReadObserver(props: MessageReadObserverProps) {\r\n const { noReadTracking } = useConversation();\r\n\r\n if (noReadTracking === true) {\r\n return null;\r\n }\r\n\r\n return <Observer {...props} />;\r\n}\r\n","import { useRef } from 'react';\r\nimport { customize } from '../../customize';\r\nimport { MessageBase } from '../../../core';\r\nimport { SystemMessageRow } from './SystemMessageRow';\r\nimport { MessageReadObserver } from '../ReadObserver';\r\n\r\nexport interface SystemMessageBoxProps {\r\n message: MessageBase;\r\n}\r\n\r\nexport const SystemMessageBox = customize('SystemMessageBox', (props: SystemMessageBoxProps) => {\r\n const ref = useRef<HTMLDivElement | null>(null);\r\n\r\n return (\r\n <>\r\n <MessageReadObserver messageRef={ref} {...props} />\r\n <SystemMessageRow containerRef={ref} {...props} />\r\n </>\r\n );\r\n});\r\n","import { useLocalizer } from '../../localizer';\r\nimport { formatSystemMessage } from '../../Conversation/SystemMessage';\r\nimport { FC } from 'react';\r\nimport { customize } from '../../customize';\r\nimport type { ChatListItemBoxProps } from './ChatListItemBox';\r\n\r\nexport const ChatListItemLastMessageContent = customize<FC<ChatListItemBoxProps>>(\r\n 'ChatListItemLastMessageContent',\r\n (props) => {\r\n const { lastMessage } = props.chat;\r\n const localizer = useLocalizer();\r\n\r\n return (\r\n <div className=\"wxchtf-chat-last-message\">\r\n {lastMessage.sentBy.id === 'chatify::system'\r\n ? lastMessage.text && formatSystemMessage(localizer, lastMessage.text)\r\n : lastMessage.text}\r\n </div>\r\n );\r\n },\r\n);\r\n","import { customize } from '../../customize';\r\nimport type { ChatListItemBoxProps } from './ChatListItemBox';\r\n\r\nexport const ChatListItemLastMessageAuthor = customize(\r\n 'ChatListItemLastMessageAuthor',\r\n (props: ChatListItemBoxProps) => {\r\n const { lastMessage } = props.chat;\r\n\r\n if (lastMessage.sentBy.id === 'chatify::system') {\r\n return null;\r\n }\r\n\r\n return <div className=\"wxchtf-chat-last-author\">{lastMessage.sentBy.name}</div>;\r\n },\r\n);\r\n","import { customize } from '../../customize';\r\nimport { useLocalizer } from '../../localizer';\r\nimport { ChatListItemBoxProps } from './ChatListItemBox';\r\n\r\nexport const ChatListItemLastMessageSentAt = customize(\r\n 'ChatListItemLastMessageSentAt',\r\n (props: ChatListItemBoxProps) => {\r\n const {\r\n chat: {\r\n lastMessage: { sentAt },\r\n },\r\n } = props;\r\n\r\n const localizer = useLocalizer();\r\n\r\n return (\r\n <div className=\"wxchtf-chat-last-sent-at\">\r\n {localizer.isToday(sentAt) ? localizer.timestamp(sentAt) : localizer.dateTime(sentAt)}\r\n </div>\r\n );\r\n },\r\n);\r\n","import { customize } from '../../customize';\r\nimport type { ChatListItemBoxProps } from './ChatListItemBox';\r\nimport { ChatListItemLastMessageContent } from './ChatListItemLastMessageContent';\r\nimport { ChatListItemLastMessageAuthor } from './ChatListItemLastMessageAuthor';\r\nimport { ChatListItemLastMessageSentAt } from './ChatListItemLastMessageSentAt';\r\n\r\nexport const ChatListItemLastMessage = customize('ChatListItemLastMessage', (props: ChatListItemBoxProps) => {\r\n return (\r\n <div className=\"wxchtf-chat-last\">\r\n <ChatListItemLastMessageAuthor {...props} />\r\n <ChatListItemLastMessageContent {...props} />\r\n <ChatListItemLastMessageSentAt {...props} />\r\n </div>\r\n );\r\n});\r\n","import { color } from '../../color';\r\nimport { Icon } from '../../common/Icon';\r\nimport { customize } from '../../customize';\r\nimport type { ChatListItemBoxProps } from './ChatListItemBox';\r\n\r\nexport const ChatListItemAvatar = customize('ChatListItemAvatar', (props: ChatListItemBoxProps) => {\r\n const { id } = props.chat;\r\n\r\n return (\r\n <div\r\n className=\"wxchtf-chat-avatar\"\r\n style={\r\n {\r\n '--background-color': color(id, { lightness: 90 }),\r\n '--color': color(id, { saturation: 60, lightness: 65 }),\r\n } as any\r\n }\r\n >\r\n <Icon type=\"chat\" />\r\n </div>\r\n );\r\n});\r\n","import { customize } from '../../customize';\r\nimport { ChatListItemName } from './ChatListItemName';\r\nimport { ChatListItemUnreadCount } from './ChatListItemUnreadCount';\r\nimport { ChatListItemLastMessage } from './ChatListItemLastMessage';\r\nimport { ChatListItemAvatar } from './ChatListItemAvatar';\r\nimport { ChatListValue } from './ChatListValue';\r\n\r\nexport interface ChatListItemBoxProps {\r\n chat: ChatListValue;\r\n\r\n /**\r\n * If true, do not show read status.\r\n */\r\n noRead?: boolean;\r\n}\r\n\r\nexport const ChatListItemBox = customize('ChatListItemBox', (props: ChatListItemBoxProps) => {\r\n const { noRead = false } = props;\r\n const { lastMessage, lastReadMessageId } = props.chat;\r\n const read = lastReadMessageId != null && lastReadMessageId.localeCompare(lastMessage.id) >= 0;\r\n\r\n return (\r\n <div className={'wxchtf-chat' + (!read && !noRead ? ' --unread' : '')}>\r\n <ChatListItemAvatar {...props} />\r\n <span className=\"wxchtf-chat-info\">\r\n <ChatListItemName {...props} />\r\n <ChatListItemUnreadCount {...props} />\r\n <ChatListItemLastMessage {...props} />\r\n </span>\r\n </div>\r\n );\r\n});\r\n","import { Menu, MenuProps } from 'antd';\r\nimport { useMemo } from 'react';\r\nimport { ChatListItemBox } from './ChatListItemBox';\r\nimport { customize } from '../../customize';\r\nimport { ChatListValue } from './ChatListValue';\r\nimport { useLocalizer } from '../../localizer';\r\nimport { messageSequencePart } from '../../../core';\r\n\r\nexport interface ChatListProps {\r\n className?: string;\r\n items: ChatListValue[];\r\n selected: string | null;\r\n onSelect?: (id: string) => void;\r\n\r\n /**\r\n * If true, do not show read status.\r\n */\r\n noRead?: boolean;\r\n\r\n /**\r\n * If set, shows a message at the bottom indicating that only the top N chats are shown.\r\n */\r\n top?: number;\r\n}\r\n\r\nfunction useOnSelect(props: ChatListProps) {\r\n const { onSelect } = props;\r\n\r\n return useMemo(\r\n () =>\r\n onSelect\r\n ? (info: Parameters<NonNullable<MenuProps['onSelect']>>[0]) => onSelect(info.key as string)\r\n : undefined,\r\n [onSelect],\r\n );\r\n}\r\n\r\nfunction useMenuItems(props: ChatListProps) {\r\n const { items, noRead, top } = props;\r\n const localizer = useLocalizer();\r\n\r\n return useMemo<MenuProps['items']>(() => {\r\n const result = items\r\n ?.slice()\r\n .sort(\r\n (a, b) => -messageSequencePart(a.lastMessage.id).localeCompare(messageSequencePart(b.lastMessage.id)),\r\n )\r\n .map((x) => ({ key: x.id, label: <ChatListItemBox chat={x} noRead={noRead} /> }));\r\n\r\n if (top != null) {\r\n return [\r\n ...result,\r\n {\r\n type: 'item',\r\n key: 'top',\r\n disabled: true,\r\n label: (\r\n <div style={{ textAlign: 'center', cursor: 'text', fontStyle: 'italic' }}>\r\n {localizer.chatList.topShown(top)}\r\n </div>\r\n ),\r\n },\r\n ];\r\n }\r\n\r\n return result;\r\n }, [items, noRead, top, localizer]);\r\n}\r\n\r\nexport const ChatList = customize('ChatList', (props: ChatListProps) => {\r\n const { selected: selectedChatId } = props;\r\n const selected = useMemo(() => (selectedChatId ? [selectedChatId] : []), [selectedChatId]);\r\n const onSelect = useOnSelect(props);\r\n const items = useMenuItems(props);\r\n\r\n return (\r\n <>\r\n {items && (\r\n <Menu className=\"wxchtf-chat-list\" selectedKeys={selected} onSelect={onSelect} items={items} />\r\n )}\r\n </>\r\n );\r\n});\r\n","import { useLocalizer } from './localizer';\r\n\r\nexport function useFormatter() {\r\n const localizer = useLocalizer();\r\n\r\n return {\r\n size: (value: number) => {\r\n if (value < 1024) {\r\n return localizer.size.bytes(value);\r\n } else if (value < 1024 * 1024) {\r\n return localizer.size.kb(value / 1024);\r\n } else {\r\n return localizer.size.mb(value / 1024 / 1024);\r\n }\r\n },\r\n };\r\n}\r\n","import { Button } from 'antd';\r\nimport { File } from '../../../core';\r\nimport { Icon } from '../../common';\r\nimport { useCallback } from 'react';\r\nimport { useFormatter } from '../../useFormatter';\r\nimport { customize } from '../../customize';\r\n\r\nexport interface InputBoxFileProps {\r\n file: File;\r\n disabled?: boolean;\r\n onDelete: (file: File) => void;\r\n}\r\n\r\nexport const InputBoxFile = customize('InputBoxFile', (props: InputBoxFileProps) => {\r\n const { file, disabled, onDelete } = props;\r\n const formatter = useFormatter();\r\n const onDeleteClick = useCallback(() => onDelete(file), [file, onDelete]);\r\n\r\n return (\r\n <div className=\"wxchtf-file\">\r\n <div className=\"wxchtf-file-info\">\r\n <div className=\"wxchtf-file-name\" title={file.name}>\r\n {file.name}\r\n </div>\r\n <div className=\"wxchtf-file-size\">{formatter.size(file.bytes)}</div>\r\n </div>\r\n <div className=\"wxchtf-file-actions\">\r\n <Button\r\n disabled={disabled}\r\n className=\"wxchtf-delete\"\r\n type=\"link\"\r\n icon={<Icon type=\"delete-file\" />}\r\n onClick={onDeleteClick}\r\n />\r\n </div>\r\n </div>\r\n );\r\n});\r\n","import { File } from '../../../core';\r\nimport { customize } from '../../customize';\r\nimport { InputBoxFile } from './InputBoxFile';\r\n\r\nexport interface InputBoxFileListProps {\r\n files: File[];\r\n disabled?: boolean;\r\n onDelete: (file: File) => void;\r\n}\r\n\r\nexport const InputBoxFileList = customize('InputBoxFileList', (props: InputBoxFileListProps) => {\r\n const { files, onDelete, disabled } = props;\r\n\r\n return (\r\n <div className=\"wxchtf-file-list\">\r\n {files.map((file) => (\r\n <InputBoxFile key={file.ref} file={file} onDelete={onDelete} disabled={disabled} />\r\n ))}\r\n </div>\r\n );\r\n});\r\n","import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';\r\nimport { InputFilesBox } from './InputFilesBox';\r\nimport { File } from '../../../core';\r\nimport { InputTextBox } from './InputTextBox';\r\nimport { customize, useCustomizeContext } from '../../customize';\r\nimport { InputSubmitButtonBox } from './InputSubmitButtonBox';\r\nimport { useConversation } from '../ConversationContext';\r\nimport { ConversationCustomizeValue } from '../Conversation';\r\nimport { InputBoxFileList } from './InputBoxFileList';\r\n\r\nfunction useFormState() {\r\n const { onSend } = useConversation();\r\n const [text, setText] = useState('');\r\n const [sending, setSending] = useState(false);\r\n const { onUpload, files, loading, setFiles, showFileBox, onDeleteFile } = useFlippoInputFileBox();\r\n\r\n const onSubmit = useCallback(() => {\r\n if (!onSend) {\r\n return;\r\n }\r\n\r\n const textValue = text.trim().length === 0 ? null : text.trim();\r\n\r\n if ((!textValue && files.length === 0) || loading) {\r\n return;\r\n }\r\n\r\n setSending(true);\r\n Promise.resolve(onSend({ text: textValue, files }))\r\n .finally(() => setSending(false))\r\n .then(() => {\r\n setFiles([]);\r\n setText('');\r\n });\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [text, onSend, files, setFiles, loading]);\r\n\r\n return [onSubmit, { text, setText, files, onUpload, loading, showFileBox, onDeleteFile, sending }] as const;\r\n}\r\n\r\nfunction useFlippoInputFileBox() {\r\n const [loading, setLoading] = useState(false);\r\n const [files, setFiles] = useState<File[]>([]);\r\n const { flippo } = useCustomizeContext<ConversationCustomizeValue>();\r\n\r\n const onUpload = useCallback(\r\n (files: globalThis.File[]) => {\r\n if (!flippo) return;\r\n\r\n setLoading(true);\r\n Promise.all(files.map((file) => flippo.store(file)))\r\n .then((references) =>\r\n setFiles((prev) => [\r\n ...prev,\r\n ...references.map((reference, index) => ({\r\n name: files[index].name,\r\n ref: reference,\r\n bytes: files[index].size,\r\n })),\r\n ]),\r\n )\r\n .finally(() => setLoading(false));\r\n },\r\n [flippo],\r\n );\r\n\r\n const onDeleteFile = useCallback((file: File) => {\r\n setFiles((prev) => prev.filter((f) => f !== file));\r\n }, []);\r\n\r\n return { onUpload, files, loading, setFiles, showFileBox: !!flippo, onDeleteFile };\r\n}\r\n\r\nexport const InputBox = customize('InputBox', () => {\r\n const [onSend, { text, setText, files, loading, onUpload, showFileBox, onDeleteFile, sending }] =\r\n useFormState();\r\n const inputRef = useRef<HTMLTextAreaElement>(null);\r\n const [showFileList, setShowFileList] = useState(false);\r\n const toggleShowFileList = useCallback(() => setShowFileList((prev) => !prev), []);\r\n const prevFilesLength = useRef(files.length);\r\n\r\n useLayoutEffect(() => inputRef.current?.focus(), []);\r\n\r\n useEffect(() => {\r\n if (prevFilesLength.current === 0 && files.length > 0 && !showFileList) {\r\n setShowFileList(true);\r\n }\r\n\r\n prevFilesLength.current = files.length;\r\n\r\n if (files.length === 0 && showFileList) {\r\n setShowFileList(false);\r\n }\r\n }, [files, showFileList]);\r\n\r\n return (\r\n <div className=\"wxchtf-input-form\">\r\n <div className=\"wxchtf-input-box\">\r\n {showFileList && (\r\n <div className=\"wxchtf-file-list-box\">\r\n <InputBoxFileList files={files} onDelete={onDeleteFile} disabled={sending} />\r\n </div>\r\n )}\r\n <div className=\"wxchtf-input-box-row\">\r\n {showFileBox && (\r\n <InputFilesBox\r\n onAddedClick={toggleShowFileList}\r\n onUpload={onUpload}\r\n value={files}\r\n loading={loading}\r\n disabled={sending}\r\n />\r\n )}\r\n <InputTextBox\r\n value={text}\r\n onSend={onSend}\r\n onChange={setText}\r\n disabled={sending}\r\n inputRef={inputRef}\r\n />\r\n <InputSubmitButtonBox onSubmit={onSend} disabled={loading} loading={sending} />\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n});\r\n","import { customize } from '../../customize';\r\nimport { Avatar } from '../../common/Avatar';\r\nimport type { MessageBoxProps } from './MessageBox';\r\n\r\nexport const MessageAuthor = customize('MessageAuthor', (props: MessageBoxProps) => {\r\n const { sentBy } = props.message;\r\n\r\n return (\r\n <div className=\"wxchtf-message-author\">\r\n <Avatar account={sentBy} />\r\n </div>\r\n );\r\n});\r\n","import { customize } from '../../customize';\r\nimport { MessageBoxProps } from './MessageBox';\r\n\r\nexport const MessageText = customize('MessageText', (props: MessageBoxProps) => {\r\n const { text } = props.message;\r\n return <div className=\"wxchtf-message-text\">{text}</div>;\r\n});\r\n","import { Button } from 'antd';\r\nimport { File } from '../../../core';\r\nimport { customize, useCustomizeContext } from '../../customize';\r\nimport { useFormatter } from '../../useFormatter';\r\nimport { Icon } from '../../common';\r\nimport { ConversationCustomizeValue } from '../Conversation';\r\nimport { useCallback, useState } from 'react';\r\n\r\nfunction open(url: string) {\r\n const w = window.open(url, '_blank');\r\n w?.focus();\r\n}\r\n\r\nexport interface MessageFileProps {\r\n file: File;\r\n}\r\n\r\nfunction useOpen(props: MessageFileProps) {\r\n const { file } = props;\r\n const { flippo } = useCustomizeContext<ConversationCustomizeValue>();\r\n const [isOpenFetching, setIsOpenFetching] = useState(false);\r\n\r\n const onOpen = useCallback(\r\n () =>\r\n flippo &&\r\n Promise.resolve(setIsOpenFetching(true))\r\n .then(() => flippo!.getSasUrl(file.ref))\r\n .then(open)\r\n .finally(() => setIsOpenFetching(false)),\r\n [flippo, file.ref],\r\n );\r\n\r\n return [onOpen, { isOpenFetching }] as const;\r\n}\r\n\r\nexport const MessageFile = customize('MessageFile', (props: MessageFileProps) => {\r\n const { file } = props;\r\n const formatter = useFormatter();\r\n const [onOpen, { isOpenFetching }] = useOpen(props);\r\n\r\n return (\r\n <div className=\"wxchtf-file\">\r\n <div className=\"wxchtf-icon\">\r\n <Button loading={isOpenFetching} onClick={onOpen} type=\"link\" icon={<Icon type=\"open-file\" />} />\r\n </div>\r\n <div className=\"wxchtf-file-info\">\r\n <div className=\"wxchtf-name\" title={file.name}>\r\n {file.name}\r\n </div>\r\n <div className=\"wxchtf-size\">{formatter.size(file.bytes)}</div>\r\n </div>\r\n </div>\r\n );\r\n});\r\n","import { customize } from '../../customize';\r\nimport { MessageBoxProps } from './MessageBox';\r\nimport { MessageFile } from './MessageFile';\r\n\r\nexport const MessageFileList = customize('MessageFileList', (props: MessageBoxProps) => {\r\n const { files } = props.message;\r\n return (\r\n <div className=\"wxchtf-file-list\">\r\n {files.map((file) => (\r\n <MessageFile key={file.ref} file={file} />\r\n ))}\r\n </div>\r\n );\r\n});\r\n","import { customize } from '../../customize';\r\nimport { MessageText } from './MessageText';\r\nimport type { MessageBoxProps } from './MessageBox';\r\nimport { MessageFileList } from './MessageFileList';\r\n\r\nexport const MessageContent = customize('MessageContent', (props: MessageBoxProps) => {\r\n const { files, text } = props.message;\r\n\r\n return (\r\n <div className=\"wxchtf-message-content\">\r\n {text && <MessageText {...props} />}\r\n {files.length > 0 && <MessageFileList {...props} />}\r\n </div>\r\n );\r\n});\r\n","import { chatifyApi } from '../../../core';\r\nimport { customize } from '../../customize';\r\nimport { useLocalizer } from '../../localizer';\r\nimport { useConversation } from '../ConversationContext';\r\nimport type { MessageBoxProps } from './MessageBox';\r\n\r\nexport const MessageInfoBox = customize('MessageInfoBox', (props: MessageBoxProps) => {\r\n const { message } = props;\r\n const { id, sentBy, sentAt } = message;\r\n const { lastReadMessageId, isReading, noReadTracking } = useConversation();\r\n const me = chatifyApi.settings.me();\r\n const my = sentBy.id === me;\r\n const localizer = useLocalizer();\r\n const isRead = lastReadMessageId != null && id.localeCompare(lastReadMessageId) <= 0;\r\n const reading = !isRead && isReading?.(id);\r\n\r\n return (\r\n <div className=\"wxchtf-message-info-box\">\r\n {!my && <div className=\"wxchtf-message-author-name\">{sentBy.name},</div>}\r\n <div className=\"wxchtf-message-sent-at\">{localizer.timestamp(sentAt)}</div>\r\n {!my && !noReadTracking && (\r\n <div className=\"wxchtf-message-read-box\">\r\n {reading ? localizer.message.reading() : localizer.message.read()}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n});\r\n","import { Ref } from 'react';\r\nimport { customize } from '../../customize';\r\nimport { MessageAuthor } from './MessageAuthor';\r\nimport { MessageContent } from './MessageContent';\r\nimport { MessageBoxProps } from './MessageBox';\r\nimport { MessageInfoBox } from './MessageInfoBox';\r\nimport { chatifyApi } from '../../../core';\r\n\r\nexport interface MessageRowProps extends MessageBoxProps {\r\n containerRef?: Ref<HTMLDivElement>;\r\n}\r\n\r\nexport const MessageRow = customize('MessageRow', (props: MessageRowProps) => {\r\n const { message, containerRef } = props;\r\n const { sentBy } = message;\r\n const me = chatifyApi.settings.me();\r\n const my = sentBy.id === me;\r\n\r\n return (\r\n <div ref={containerRef} className={'wxchtf-message' + (my ? ' --my' : '')}>\r\n <MessageAuthor {...props} />\r\n <div>\r\n <MessageInfoBox {...props} />\r\n <MessageContent {...props} />\r\n </div>\r\n </div>\r\n );\r\n});\r\n","import { useRef } from 'react';\r\nimport { customize } from '../../customize';\r\nimport { MessageReadObserver } from '../ReadObserver';\r\nimport { MessageRow } from './MessageRow';\r\nimport { MessageBase } from '../../../core';\r\n\r\nexport interface MessageBoxProps {\r\n message: MessageBase;\r\n}\r\n\r\nexport const MessageBox = customize('MessageBox', (props: MessageBoxProps) => {\r\n const ref = useRef<HTMLDivElement | null>(null);\r\n\r\n return (\r\n <>\r\n <MessageReadObserver messageRef={ref} {...props} />\r\n <MessageRow containerRef={ref} {...props} />\r\n </>\r\n );\r\n});\r\n","import { useEffect, useMemo, useRef, useState } from 'react';\r\nimport { MessageSkeleton } from '../../common/MessageSkeleton';\r\n\r\nexport interface NextMessagesObserverProps {\r\n onLoad: () => void;\r\n loading: boolean;\r\n}\r\n\r\nexport function NextMessagesObserver(props: NextMessagesObserverProps) {\r\n const { onLoad, loading } = props;\r\n const [intersecting, setIntersecting] = useState(false);\r\n const ref = useRef<HTMLDivElement | null>(null);\r\n const timerRef = useRef<number>();\r\n\r\n const observer = useMemo(\r\n () =>\r\n new IntersectionObserver(([entry]) => {\r\n if (entry.isIntersecting) {\r\n timerRef.current = window.setTimeout(() => setIntersecting(true), 200);\r\n } else {\r\n clearTimeout(timerRef.current!);\r\n }\r\n }),\r\n [],\r\n );\r\n\r\n useEffect(() => {\r\n observer.observe(ref.current!);\r\n return () => observer.disconnect();\r\n }, [observer]);\r\n\r\n useEffect(() => {\r\n if (!intersecting) {\r\n return;\r\n }\r\n\r\n onLoad();\r\n\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [intersecting]);\r\n\r\n if (loading || intersecting) {\r\n return <MessageSkeleton count={4} />;\r\n }\r\n\r\n return <div className=\"wxchtf-next\" ref={ref} />;\r\n}\r\n","import { customize } from '../../customize';\r\nimport type { SendingMessageBoxProps } from './SendingMessageBox';\r\n\r\nexport const SendingMessageText = customize('SendingMessageText', (props: SendingMessageBoxProps) => {\r\n const { text } = props;\r\n return <div className=\"wxchtf-sending-message-text\">{text}</div>;\r\n});\r\n","import { customize } from '../../customize';\r\nimport { useLocalizer } from '../../localizer';\r\nimport type { SendingMessageBoxProps } from './SendingMessageBox';\r\n\r\nexport const SendingMessageInfoBox = customize('SendingMessageInfoBox', (_: SendingMessageBoxProps) => {\r\n const localizer = useLocalizer();\r\n\r\n return (\r\n <div className=\"wxchtf-sending-message-info-box\">\r\n <div className=\"wxchtf-sending-message-sending-box\">{localizer.message.sending()}</div>\r\n </div>\r\n );\r\n});\r\n","import { customize } from '../../customize';\r\nimport { SendingMessageText } from './SendingMessageText';\r\nimport { SendingMessageInfoBox } from './SendingMessageInfoBox';\r\nimport type { SendingMessageBoxProps } from './SendingMessageBox';\r\n\r\nexport const SendingMessageContent = customize('SendingMessageContent', (props: SendingMessageBoxProps) => {\r\n return (\r\n <div className=\"wxchtf-sending-message-content\">\r\n <SendingMessageText {...props} />\r\n <SendingMessageInfoBox {...props} />\r\n </div>\r\n );\r\n});\r\n","import { File } from '../../../core';\r\nimport { customize } from '../../customize';\r\nimport { SendingMessageContent } from './SendingMessageContent';\r\n\r\nexport interface SendingMessageBoxProps {\r\n text: string;\r\n files: File[];\r\n}\r\n\r\nexport const SendingMessageBox = customize('SendingMessageBox', (props: SendingMessageBoxProps) => {\r\n return (\r\n <div className=\"wxchtf-sending-message\">\r\n <SendingMessageContent {...props} />\r\n </div>\r\n );\r\n});\r\n","import { Button } from 'antd';\r\nimport { customize } from '../customize';\r\nimport { useConversation } from './ConversationContext';\r\nimport { Icon } from '../common';\r\n\r\nexport const ConversationActions = customize('ConversationActions', () => {\r\n const { onClose } = useConversation();\r\n\r\n if (!onClose) return null;\r\n\r\n return <Button onClick={onClose} type=\"link\" icon={<Icon type=\"close\" />} />;\r\n});\r\n","import { MessageBox } from './Message';\r\nimport { NextMessagesObserver } from './NextObserver';\r\nimport { SystemMessageBox } from './SystemMessage';\r\nimport { MessageSkeleton } from '../common/MessageSkeleton';\r\nimport { customize } from '../customize';\r\nimport { SYSTEM_ID } from '../../core';\r\nimport { useConversation } from './ConversationContext';\r\n\r\n// TODO: Add sending message box\r\nexport const ConversationBody = customize('ConversationBody', () => {\r\n const { id, messages = [], hasMore, onNext, nextLoading } = useConversation();\r\n\r\n return (\r\n <div className=\"wxchtf-conversation-body\">\r\n {!messages && <MessageSkeleton count={5} />}\r\n\r\n {messages?.map((x) => {\r\n if (x.sentBy.id === SYSTEM_ID) {\r\n return <SystemMessageBox key={x.id} message={x} />;\r\n }\r\n\r\n return <MessageBox message={x} key={x.id} />;\r\n })}\r\n\r\n {hasMore && <NextMessagesObserver key={messages.length + id} onLoad={onNext} loading={nextLoading} />}\r\n </div>\r\n );\r\n});\r\n","import { customize } from '../customize';\r\nimport { useConversation } from './ConversationContext';\r\n\r\nexport const ConversationName = customize('ConversationName', () => {\r\n const { name } = useConversation();\r\n return <span className=\"wxchtf-conversation-name\">{name}</span>;\r\n});\r\n","import { Button, Col, Row } from 'antd';\r\nimport { customize } from '../customize';\r\nimport { ConversationName } from './ConversationName';\r\nimport { ConversationActions } from './ConversationActions';\r\nimport { LeftOutlined } from '@ant-design/icons';\r\n\r\nexport interface ConversationHeaderProps {\r\n onBackClick?: () => void;\r\n}\r\n\r\nexport const ConversationHeader = customize('ConversationHeader', (props: ConversationHeaderProps) => {\r\n const { onBackClick } = props;\r\n\r\n return (\r\n <div className=\"wxchtf-conversation-header\">\r\n <Row gutter={10}>\r\n {onBackClick && (\r\n <Col flex=\"none\">\r\n <Button type=\"text\" icon={<LeftOutlined />} onClick={onBackClick} />\r\n </Col>\r\n )}\r\n <Col flex=\"auto\">\r\n <Row justify=\"space-between\" align=\"middle\">\r\n <Col>\r\n <ConversationName />\r\n </Col>\r\n <Col className=\"wxchtf-conversation-actions\">\r\n <ConversationActions />\r\n </Col>\r\n </Row>\r\n </Col>\r\n </Row>\r\n </div>\r\n );\r\n});\r\n","import { ConversationHeader } from './ConversationHeader';\r\nimport { ConversationBody } from './ConversationBody';\r\nimport { customize } from '../customize';\r\nimport { ConversationName } from './ConversationName';\r\nimport { ConversationContext, ConversationContextValue, ConversationValue } from './ConversationContext';\r\nimport { useMemo } from 'react';\r\nimport { InputBox, InputBoxCustomizeValue } from './InputBox';\r\nimport { ConversationActions } from './ConversationActions';\r\nimport { MessageCustomizeValue } from './Message';\r\nimport { SendingMessageCustomizeValue } from './SendingMessage';\r\nimport { SystemMessageCustomizeValue } from './SystemMessage';\r\nimport { CommonCustomizeValue } from '../common';\r\nimport type { Flippo } from '@webinex/flippo';\r\n\r\nexport interface ConversationProps extends Omit<ConversationContextValue, keyof ConversationValue> {\r\n value: ConversationValue;\r\n onBackClick?: () => void;\r\n}\r\n\r\nexport interface ConversationCustomizeValue\r\n extends InputBoxCustomizeValue,\r\n MessageCustomizeValue,\r\n SendingMessageCustomizeValue,\r\n SystemMessageCustomizeValue,\r\n CommonCustomizeValue {\r\n ConversationActions?: typeof ConversationActions.Component | null;\r\n ConversationBody?: typeof ConversationBody.Component | null;\r\n ConversationHeader?: typeof ConversationHeader.Component | null;\r\n ConversationName?: typeof ConversationName.Component | null;\r\n flippo?: Flippo;\r\n}\r\n\r\nexport const Conversation = customize('Conversation', (props: ConversationProps) => {\r\n const {\r\n value,\r\n hasMore,\r\n messages,\r\n nextLoading,\r\n onNext,\r\n onRead,\r\n onSend,\r\n isReading,\r\n noReadTracking,\r\n onClose,\r\n compact,\r\n onBackClick,\r\n } = props;\r\n\r\n const { id, active, name, lastReadMessageId } = value;\r\n\r\n const context = useMemo<ConversationContextValue>(\r\n () => ({\r\n id,\r\n name,\r\n active,\r\n lastReadMessageId,\r\n hasMore,\r\n messages,\r\n nextLoading,\r\n onNext,\r\n onRead,\r\n onSend,\r\n isReading,\r\n noReadTracking,\r\n onClose,\r\n compact,\r\n }),\r\n [\r\n id,\r\n name,\r\n active,\r\n onNext,\r\n onRead,\r\n onSend,\r\n hasMore,\r\n messages,\r\n nextLoading,\r\n lastReadMessageId,\r\n isReading,\r\n noReadTracking,\r\n onClose,\r\n ],\r\n );\r\n\r\n return (\r\n <ConversationContext.Provider value={context}>\r\n <div className=\"wxchtf-conversation\">\r\n <div className=\"wxchtf-conversation-main\">\r\n <ConversationHeader onBackClick={onBackClick} />\r\n <ConversationBody />\r\n {active && <InputBox />}\r\n </div>\r\n </div>\r\n </ConversationContext.Provider>\r\n );\r\n});\r\n","import { Input, Tooltip } from 'antd';\r\nimport { chatifyApi } from '../../core';\r\nimport { customize } from '../customize';\r\nimport { useEffect, useState } from 'react';\r\nimport { isHotkey } from 'is-hotkey';\r\nimport { useConversation } from '../Conversation';\r\n\r\nconst isEscape = isHotkey('escape');\r\nconst isEnter = isHotkey('enter');\r\n\r\nfunction useUpdateChatName(id: string, value: string) {\r\n const [updateChatName] = chatifyApi.useUpdateChatNameMutation();\r\n return () => updateChatName({ id, name: value });\r\n}\r\n\r\nexport const ChatEditableHeaderName = customize('ChatEditableHeaderName', () => {\r\n const { id, name, active } = useConversation();\r\n const [editNameValue, setEditNameValue] = useState('');\r\n const [edit, setEdit] = useState(false);\r\n const updateChatName = useUpdateChatName(id, editNameValue);\r\n\r\n useEffect(() => {\r\n if (edit) {\r\n setEditNameValue(name ?? '');\r\n }\r\n }, [edit, name]);\r\n\r\n if (!active) {\r\n return <span className=\"wxchtf-conversation-name\">{name}</span>;\r\n }\r\n\r\n if (edit) {\r\n return (\r\n <Tooltip defaultOpen title=\"Press Enter to save new chat name or Escape to cancel editing\">\r\n <Input\r\n value={editNameValue}\r\n onChange={(e) => setEditNameValue(e.target.value)}\r\n onBlur={() => setEdit(false)}\r\n onKeyDown={(e) => {\r\n if (isEscape(e)) {\r\n setEdit(false);\r\n } else if (isEnter(e)) {\r\n setEdit(false);\r\n\r\n if (editNameValue !== name && editNameValue.trim() !== '') {\r\n updateChatName();\r\n }\r\n }\r\n }}\r\n autoFocus\r\n />\r\n </Tooltip>\r\n );\r\n }\r\n\r\n return (\r\n <Tooltip title=\"Click to edit name...\">\r\n <span className=\"wxchtf-conversation-name --editable\" onClick={() => setEdit(true)}>\r\n {name}\r\n </span>\r\n </Tooltip>\r\n );\r\n});\r\n","import { ChatMembersPreview } from './Members';\r\nimport { ChatMembersButton } from './Members';\r\nimport { customize } from '../customize';\r\nimport { useConversation } from '../Conversation';\r\n\r\nexport const ChatHeaderActions = customize('ChatHeaderActions', () => {\r\n const { active, compact } = useConversation();\r\n\r\n if (!active) {\r\n return null;\r\n }\r\n\r\n return (\r\n <div className=\"wxchtf-chat-members\">\r\n {!compact && <ChatMembersPreview />}\r\n <ChatMembersButton />\r\n </div>\r\n );\r\n});\r\n","import { CustomizeContext, customize, useCustomizeContext } from '../customize';\r\nimport { MessageBody, chatId, chatifyApi } from '../../core';\r\nimport {\r\n Conversation,\r\n ConversationCustomizeValue,\r\n ConversationProps,\r\n ConversationValue,\r\n} from '../Conversation';\r\nimport { useCallback, useMemo } from 'react';\r\nimport { ChatEditableHeaderName } from './ChatEditableHeaderName';\r\nimport { ChatHeaderActions } from './ChatHeaderActions';\r\nimport { ChatMembersCustomizeValue, ChatMembersPanel } from './Members';\r\nimport { ChatContext, useChatContext } from './ChatContext';\r\n\r\nexport interface ChatViewProps {\r\n value: ChatValue;\r\n compact?: boolean;\r\n onBackClick?: () => void;\r\n}\r\n\r\nexport interface ChatValue extends ConversationValue {}\r\n\r\nexport interface ChatViewCustomizeValue extends ConversationCustomizeValue, ChatMembersCustomizeValue {\r\n ChatEditableHeaderName?: typeof ChatEditableHeaderName.Component | null;\r\n ChatHeaderActions?: typeof ChatHeaderActions.Component | null;\r\n ChatView?: typeof ChatView.Component | null;\r\n}\r\n\r\nexport const DEFAULT_CHAT_VIEW_CUSTOMIZE_VALUE: ConversationCustomizeValue = {\r\n ConversationName: () => <ChatEditableHeaderName />,\r\n ConversationActions: () => <ChatHeaderActions />,\r\n};\r\n\r\nfunction useConversation(props: Pick<ChatViewProps, 'value' | 'onBackClick'>) {\r\n const { value: chat, onBackClick } = props;\r\n const { compact } = useChatContext();\r\n const { id, name, active, lastReadMessageId } = chat;\r\n\r\n const { data: messageList } = chatifyApi.useGetChatMessageListQuery({ chatId: id });\r\n const { messages, hasMore } = messageList ?? {};\r\n\r\n const [fetchNext, { isLoading: isFetchNextLoading }] = chatifyApi.useFetchNextChatMessageListMutation();\r\n const onNext = useCallback(() => fetchNext({ chatId: id }), [fetchNext, id]);\r\n\r\n const [read] = chatifyApi.useReadChatMessageMutation();\r\n const onRead = useCallback((id: string) => read({ id }), [read]);\r\n\r\n const [send] = chatifyApi.useSendChatMessageMutation();\r\n const onSend = useCallback((message: MessageBody) => send({ ...message, chatId: id }).unwrap(), [id, send]);\r\n\r\n const { data: readQueue } = chatifyApi.useGetChatMessageReadQueueQuery();\r\n\r\n const conversation = useMemo(() => {\r\n if (!id) {\r\n return null;\r\n }\r\n\r\n const result: ConversationProps = {\r\n value: { id: id!, name: name!, active: active!, lastReadMessageId: lastReadMessageId! },\r\n messages,\r\n hasMore,\r\n onNext,\r\n nextLoading: isFetchNextLoading,\r\n onRead,\r\n onSend,\r\n isReading: (id: string) => readQueue!.some((x) => chatId(x.value) === chatId(id) && id <= x.value),\r\n compact: compact ?? false,\r\n onBackClick,\r\n };\r\n\r\n return result;\r\n }, [\r\n onNext,\r\n onRead,\r\n onSend,\r\n isFetchNextLoading,\r\n id,\r\n name,\r\n active,\r\n messages,\r\n hasMore,\r\n lastReadMessageId,\r\n readQueue,\r\n compact,\r\n onBackClick,\r\n ]);\r\n\r\n return conversation;\r\n}\r\n\r\nfunction Content(props: Pick<ChatViewProps, 'value' | 'onBackClick'>) {\r\n const conversation = useConversation(props);\r\n const { compact, showMembers } = useChatContext();\r\n\r\n if (!conversation) {\r\n return null;\r\n }\r\n\r\n return (\r\n <div className=\"wxchtf-chat\">\r\n {(!compact || !showMembers) && <Conversation {...conversation} />}\r\n {showMembers && <ChatMembersPanel />}\r\n </div>\r\n );\r\n}\r\n\r\nexport const ChatView = customize('ChatView', (props: ChatViewProps) => {\r\n const { value, compact, onBackClick } = props;\r\n const customized = useCustomizeContext();\r\n const customize: ChatViewCustomizeValue = useMemo(\r\n () => ({ ...(customized ?? {}), ...DEFAULT_CHAT_VIEW_CUSTOMIZE_VALUE }),\r\n [customized],\r\n );\r\n\r\n return (\r\n <CustomizeContext.Provider value={customize}>\r\n <ChatContext id={value.id} compact={compact ?? false}>\r\n <Content value={value} onBackClick={onBackClick} />\r\n </ChatContext>\r\n </CustomizeContext.Provider>\r\n );\r\n});\r\n","import { useEffect, useRef, useState } from 'react';\r\n\r\nexport function useCompact(thresholdOrCompact: number | boolean = 768) {\n const ref = useRef<HTMLDivElement>(null);\n const [size, setSize] = useState<{ width: number; height: number }>();\n const automatic = typeof thresholdOrCompact === 'number';\n\n useEffect(() => {\n if (!automatic) {\n setSize(undefined);\n return;\n }\n\n const el = ref.current;\n if (!el) return;\n\n const observer = new ResizeObserver(() => {\n const { width, height } = el.getBoundingClientRect();\n setSize({ width, height });\n });\n\n observer.observe(el);\n return () => observer.disconnect();\n }, [automatic]);\n\r\n if (typeof thresholdOrCompact === 'boolean') {\r\n return [ref, thresholdOrCompact, size] as const;\r\n }\r\n\r\n const compact = size != null ? size.width < thresholdOrCompact : undefined;\r\n return [ref, compact, size] as const;\r\n}\r\n","import { CSSProperties } from 'react';\r\nimport { Localizer, LocalizerContext, defaultLocalizer } from '../localizer';\r\nimport { CustomizeContext } from '../customize';\r\nimport { ChatView, ChatViewCustomizeValue } from './ChatView';\r\nimport { chatifyApi } from '../../core';\r\nimport { useCompact } from '../useCompact';\r\n\r\nexport interface ChatPanelCustomizeValue extends ChatViewCustomizeValue {}\r\n\r\nexport interface ChatPanelProps {\r\n id: string;\r\n className?: string;\r\n style?: CSSProperties;\r\n localizer?: Localizer;\r\n customize?: ChatPanelCustomizeValue;\r\n\r\n /**\r\n * If true, the chat panel will be displayed in compact mode.\r\n * If a number is provided, the chat panel will be displayed in compact mode if its width is less than the provided number of pixels.\r\n *\r\n * @default 768\r\n */\r\n compact?: boolean | number;\r\n}\r\n\r\nexport function ChatPanel(props: ChatPanelProps) {\r\n const { id, className = '', customize, localizer = defaultLocalizer, style, compact: compactProp } = props;\r\n const { data: chat } = chatifyApi.useGetChatQuery({ id });\r\n const [ref, compact] = useCompact(compactProp);\r\n\r\n return (\r\n <div\r\n className={['wxchtf-chatify', 'wxchtf-chat-panel', compact && '--compact', className]\r\n .filter(Boolean)\r\n .join(' ')}\r\n style={style}\r\n ref={ref}\r\n >\r\n <LocalizerContext.Provider value={localizer}>\r\n <CustomizeContext.Provider value={customize as any}>\r\n {chat && <ChatView value={chat} key={id} compact={compact} />}\r\n </CustomizeContext.Provider>\r\n </LocalizerContext.Provider>\r\n </div>\r\n );\r\n}\r\n","import React, { PropsWithChildren, useContext, useMemo, useState } from 'react';\r\n\r\nexport interface ChatGroupContext {\r\n view: 'chat' | 'new-chat' | 'auto-reply' | null;\r\n chatId: string | null;\r\n showMembers: boolean;\r\n compact: boolean;\r\n\r\n none(): void;\r\n openChat(chatId: string): void;\r\n toggleNewChat(): void;\r\n toggleMembers(): void;\r\n toggleAutoReply(): void;\r\n}\r\n\r\nconst ChatGroupReactContext = React.createContext<ChatGroupContext>(null!);\r\n\r\nexport function useChatGroupContext() {\r\n return useContext(ChatGroupReactContext);\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-redeclare\r\nexport function ChatGroupContext(props: PropsWithChildren<{ compact: boolean }>) {\r\n const { children, compact } = props;\r\n const [state, setState] = useState<Pick<ChatGroupContext, 'view' | 'chatId' | 'showMembers'>>({\r\n chatId: null,\r\n view: null,\r\n showMembers: false,\r\n });\r\n\r\n const value = useMemo<ChatGroupContext>(\r\n () => ({\r\n ...state,\r\n compact,\r\n openChat: (chatId: string) => setState((prev) => ({ ...prev, view: 'chat', chatId })),\r\n none: () => setState((prev) => ({ ...prev, view: null, chatId: null })),\r\n toggleMembers: () => setState((prev) => ({ ...prev, showMembers: !prev.showMembers })),\r\n toggleNewChat: () =>\r\n setState((prev) => {\r\n if (prev.view === 'new-chat' && !prev.chatId) {\r\n return { ...prev, view: null };\r\n } else if (prev.view === 'new-chat' && prev.chatId) {\r\n return { ...prev, view: 'chat' };\r\n } else {\r\n return { ...prev, view: 'new-chat' };\r\n }\r\n }),\r\n toggleAutoReply: () =>\r\n setState((prev) => {\r\n if (prev.view === 'auto-reply' && prev.chatId) {\r\n return { ...prev, view: 'chat' };\r\n } else if (prev.view === 'auto-reply' && !prev.chatId) {\r\n return { ...prev, view: null };\r\n } else {\r\n return { ...prev, view: 'auto-reply' };\r\n }\r\n }),\r\n }),\r\n [state, compact],\r\n );\r\n\r\n return <ChatGroupReactContext.Provider value={value}>{children}</ChatGroupReactContext.Provider>;\r\n}\r\n","import { Button } from 'antd';\r\nimport { customize } from '../../customize';\r\nimport { useChatGroupContext } from '../ChatGroupContext';\r\nimport { useLocalizer } from '../../localizer';\r\nimport { Icon } from '../../common/Icon';\r\n\r\nexport const AutoReplyButton = customize('AutoReplyButton', () => {\r\n const { toggleAutoReply } = useChatGroupContext();\r\n const localizer = useLocalizer();\r\n const titleText = localizer.autoReply.buttonTitle();\r\n\r\n return (\r\n <Button\r\n className=\"wxchtf-add-btn-settings\"\r\n onClick={toggleAutoReply}\r\n icon={<Icon type=\"settings\" />}\r\n title={titleText}\r\n aria-label={titleText}\r\n />\r\n );\r\n});\r\n","import { DatePicker, Form } from 'antd';\r\nimport { customize } from '../../customize';\r\nimport { useLocalizer } from '../../localizer';\r\n\r\nexport interface AutoReplyPeriodInputProps {\r\n name: string;\r\n}\r\n\r\nexport const AutoReplyPeriodInput = customize('AutoReplyPeriodInput', (props: AutoReplyPeriodInputProps) => {\r\n const { name } = props;\r\n const localizer = useLocalizer();\r\n\r\n return (\r\n <Form.Item\r\n label={localizer.autoReply.period.label()}\r\n name={name}\r\n rules={[{ required: true, message: localizer.autoReply.period.required() }]}\r\n >\r\n <DatePicker.RangePicker format={localizer.autoReply.period.format()} />\r\n </Form.Item>\r\n );\r\n});\r\n","import { Form, Input } from 'antd';\r\nimport { customize } from '../../customize';\r\nimport { useLocalizer } from '../../localizer';\r\n\r\nexport interface AutoReplyTextInputProps {\r\n name: string;\r\n}\r\n\r\nexport const AutoReplyTextInput = customize('AutoReplyTextInput', (props: AutoReplyTextInputProps) => {\r\n const { name } = props;\r\n const localizer = useLocalizer();\r\n\r\n return (\r\n <Form.Item\r\n label={localizer.autoReply.text.label()}\r\n name={name}\r\n rules={[{ required: true, message: localizer.autoReply.text.required() }]}\r\n >\r\n <Input.TextArea rows={4} />\r\n </Form.Item>\r\n );\r\n});\r\n","import { Button, Form } from 'antd';\r\nimport { Dayjs } from 'dayjs';\r\nimport { customize } from '../../customize';\r\nimport { useLocalizer } from '../../localizer';\r\nimport { AutoReplyPeriodInput } from './AutoReplyPeriodInput';\r\nimport { AutoReplyTextInput } from './AutoReplyTextInput';\r\nimport { useEffect } from 'react';\r\n\r\nexport interface AutoReplyFormValue {\r\n period: [Dayjs, Dayjs];\r\n text: string;\r\n}\r\n\r\nexport interface AutoReplyFormProps {\r\n value: AutoReplyFormValue;\r\n onSubmit: (value: AutoReplyFormValue) => void;\r\n busy?: boolean;\r\n}\r\n\r\nexport const AUTO_REPLY_FORM_INITIAL_VALUE: AutoReplyFormValue = {\r\n period: [] as unknown as [Dayjs, Dayjs],\r\n text: '',\r\n};\r\n\r\nexport const AutoReplyForm = customize('AutoReplyForm', (props: AutoReplyFormProps) => {\r\n const { value, busy = false, onSubmit } = props;\r\n const localizer = useLocalizer();\r\n\r\n const [form] = Form.useForm<AutoReplyFormValue>();\r\n\r\n useEffect(() => {\r\n form.setFieldsValue(value);\r\n }, [value, form]);\r\n\r\n return (\r\n <Form<AutoReplyFormValue>\r\n form={form}\r\n layout=\"vertical\"\r\n onFinish={onSubmit}\r\n disabled={busy}\r\n initialValues={value}\r\n >\r\n <AutoReplyPeriodInput name=\"period\" />\r\n <AutoReplyTextInput name=\"text\" />\r\n <Button loading={busy} type=\"primary\" block htmlType=\"submit\">\r\n {localizer.autoReply.submitBtn()}\r\n </Button>\r\n </Form>\r\n );\r\n});\r\n","import dayjs from 'dayjs';\r\nimport { useCallback, useMemo } from 'react';\r\nimport { Button } from 'antd';\r\nimport { customize } from '../../customize';\r\nimport { useLocalizer } from '../../localizer';\r\nimport { useChatGroupContext } from '../ChatGroupContext';\r\nimport { Icon } from '../../common/Icon';\r\nimport { AutoReply } from '../../../core';\r\nimport { chatifyApi } from '../../../core';\r\nimport { AUTO_REPLY_FORM_INITIAL_VALUE, AutoReplyForm, AutoReplyFormValue } from './AutoReplyForm';\r\n\r\nfunction mapToFormValue(autoReply?: AutoReply | null): AutoReplyFormValue {\r\n if (!autoReply) {\r\n return AUTO_REPLY_FORM_INITIAL_VALUE;\r\n }\r\n\r\n return {\r\n period: [dayjs(autoReply.period.start), dayjs(autoReply.period.end)],\r\n text: autoReply.text,\r\n };\r\n}\r\n\r\nfunction useValue() {\r\n const { data: me } = chatifyApi.useGeCurrentUserAccountQuery();\r\n\r\n const value = useMemo<AutoReplyFormValue>(() => {\r\n return mapToFormValue(me?.autoReply);\r\n }, [me]);\r\n\r\n return value;\r\n}\r\n\r\nfunction useAutoReplyActions() {\r\n const meId = chatifyApi.settings.me();\r\n const [updateAccount, { isLoading }] = chatifyApi.useUpdateAccountMutation();\r\n\r\n const onSubmit = useCallback(\r\n (value: AutoReplyFormValue) =>\r\n updateAccount({\r\n id: meId,\r\n autoReply: {\r\n hasValue: true,\r\n value: {\r\n text: value.text,\r\n period: {\r\n start: value.period[0].toISOString(),\r\n end: value.period[1].toISOString(),\r\n },\r\n },\r\n },\r\n }).unwrap(),\r\n [updateAccount, meId],\r\n );\r\n\r\n const onClear = useCallback(\r\n () =>\r\n updateAccount({\r\n id: meId,\r\n autoReply: {\r\n hasValue: true,\r\n value: null,\r\n },\r\n }).unwrap(),\r\n [updateAccount, meId],\r\n );\r\n\r\n return [onSubmit, isLoading, onClear] as const;\r\n}\r\n\r\nexport const AutoReplyPanel = customize('AutoReplyPanel', () => {\r\n const localizer = useLocalizer();\r\n const { toggleAutoReply } = useChatGroupContext();\r\n const value = useValue();\r\n const [onSubmit, submitting, onClear] = useAutoReplyActions();\r\n\r\n return (\r\n <div className=\"wxchtf-auto-reply-panel\">\r\n <Button\r\n onClick={toggleAutoReply}\r\n className=\"wxchtf-auto-reply-panel-close\"\r\n type=\"link\"\r\n icon={<Icon type=\"close\" />}\r\n />\r\n <div className=\"wxchtf-auto-reply-panel-header\">\r\n <h3>{localizer.autoReply.title()}</h3>\r\n <Button type=\"link\" onClick={onClear} disabled={submitting} className=\"wxchtf-auto-reply-panel-clear\">\r\n {localizer.autoReply.clearBtn()}\r\n </Button>\r\n </div>\r\n\r\n <AutoReplyForm value={value} busy={submitting ?? false} onSubmit={onSubmit} />\r\n </div>\r\n );\r\n});\r\n","import { Form, Input } from 'antd';\r\nimport { customize } from '../../customize';\r\nimport { useLocalizer } from '../../localizer';\r\n\r\nexport interface CreateChatNameInputProps {\r\n name: string;\r\n}\r\n\r\nexport const CreateChatNameInput = customize('CreateChatNameInput', (props: CreateChatNameInputProps) => {\r\n const { name } = props;\r\n const localizer = useLocalizer();\r\n\r\n return (\r\n <Form.Item\r\n name={name}\r\n label={localizer.addChat.name.label()}\r\n rules={[\r\n { required: true, message: localizer.addChat.name.required() },\r\n { max: 250, message: localizer.addChat.name.max250() },\r\n ]}\r\n >\r\n <Input />\r\n </Form.Item>\r\n );\r\n});\r\n","import { useMemo } from 'react';\r\nimport { chatifyApi } from '../../../core';\r\nimport { customize } from '../../customize';\r\nimport { Checkbox, Form, List } from 'antd';\r\nimport { useLocalizer } from '../../localizer';\r\nimport { Avatar } from '../../common/Avatar';\r\n\r\nexport interface CreateChatMemberInputProps {\r\n name: string;\r\n}\r\n\r\ninterface CheckboxListProps {\r\n value?: string[];\r\n onChange?: (value: string[]) => void;\r\n}\r\n\r\nfunction CheckboxList(props: CheckboxListProps) {\r\n const { value, onChange } = props;\r\n const { data: accounts, isFetching } = chatifyApi.useGetAccountListQuery({});\r\n const me = chatifyApi.settings.me();\r\n const dataSource = useMemo(() => accounts?.filter((x) => x.id !== me) ?? [], [accounts, me]);\r\n\r\n return (\r\n <List\r\n rowKey=\"id\"\r\n className=\"wxchtf-create-chat-member-input-list\"\r\n loading={isFetching}\r\n dataSource={dataSource}\r\n renderItem={(x) => {\r\n const checked = value!.includes(x.id);\r\n\r\n return (\r\n <List.Item className={checked ? '--selected' : ''}>\r\n <Checkbox\r\n checked={checked}\r\n onChange={() =>\r\n onChange!(value!.includes(x.id) ? value!.filter((y) => y !== x.id) : [...value!, x.id])\r\n }\r\n >\r\n <List.Item.Meta avatar={<Avatar account={x} />} title={x.name} />\r\n </Checkbox>\r\n </List.Item>\r\n );\r\n }}\r\n />\r\n );\r\n}\r\n\r\nexport const CreateChatMemberInput = customize(\r\n 'CreateChatMemberInput',\r\n (props: CreateChatMemberInputProps) => {\r\n const { name } = props;\r\n const localizer = useLocalizer();\r\n\r\n return (\r\n <Form.Item\r\n label={localizer.addChat.members.label()}\r\n rules={[{ required: true, message: localizer.addChat.members.required() }]}\r\n name={name}\r\n >\r\n <CheckboxList />\r\n </Form.Item>\r\n );\r\n },\r\n);\r\n","import { Button, Form } from 'antd';\r\nimport { customize } from '../../customize';\r\nimport { CreateChatNameInput } from './CreateChatNameInput';\r\nimport { CreateChatMemberInput } from './CreateChatMemberInput';\r\nimport { useLocalizer } from '../../localizer';\r\n\r\nexport interface CreateChatFormValue {\r\n name: string;\r\n members: string[];\r\n}\r\n\r\nexport interface CreateChatFormProps {\r\n value?: CreateChatFormValue;\r\n onSubmit: (value: CreateChatFormValue) => void;\r\n busy?: boolean;\r\n}\r\n\r\nconst INITIAL_VALUE: CreateChatFormValue = {\r\n name: '',\r\n members: [],\r\n};\r\n\r\nexport const CreateChatForm = customize('CreateChatForm', (props: CreateChatFormProps) => {\r\n const { value = INITIAL_VALUE, onSubmit, busy = false } = props;\r\n const localizer = useLocalizer();\r\n\r\n return (\r\n <Form onFinish={onSubmit} layout=\"vertical\" disabled={busy} initialValues={value}>\r\n <CreateChatNameInput name=\"name\" />\r\n <CreateChatMemberInput name=\"members\" />\r\n <Button loading={busy} type=\"primary\" block htmlType=\"submit\">\r\n {localizer.addChat.submitBtn()}\r\n </Button>\r\n </Form>\r\n );\r\n});\r\n","import { chatifyApi } from '../../../core';\r\nimport { useCallback } from 'react';\r\nimport { useLocalizer } from '../../localizer';\r\nimport { CreateChatForm, CreateChatFormValue } from './CreateChatForm';\r\nimport { customize } from '../../customize';\r\nimport { Button } from 'antd';\r\nimport { Icon } from '../../common/Icon';\r\nimport { useChatGroupContext } from '../ChatGroupContext';\r\n\r\nfunction useSubmit() {\r\n const [add, { isLoading }] = chatifyApi.useAddChatMutation();\r\n const { openChat } = useChatGroupContext();\r\n\r\n const onSubmit = useCallback(\r\n (value: CreateChatFormValue) =>\r\n add({\r\n name: value.name,\r\n members: value.members,\r\n })\r\n .unwrap()\r\n .then((id) => openChat(id)),\r\n [add, openChat],\r\n );\r\n\r\n return [onSubmit, isLoading] as const;\r\n}\r\n\r\nexport const CreateChatPanel = customize('CreateChatPanel', () => {\r\n const localizer = useLocalizer();\r\n const [onSubmit, submitting] = useSubmit();\r\n const { toggleNewChat } = useChatGroupContext();\r\n\r\n return (\r\n <div className=\"wxchtf-create-chat-panel\">\r\n <Button\r\n onClick={() => toggleNewChat()}\r\n className=\"wxchtf-create-chat-panel-close\"\r\n type=\"link\"\r\n icon={<Icon type=\"close\" />}\r\n />\r\n <h3>{localizer.addChat.title()}</h3>\r\n <CreateChatForm busy={submitting ?? false} onSubmit={onSubmit} />\r\n </div>\r\n );\r\n});\r\n","import { Button } from 'antd';\r\nimport { customize } from '../../customize';\r\nimport { useChatGroupContext } from '../ChatGroupContext';\r\n\r\nexport const CreateChatButton = customize('CreateChatButton', () => {\r\n const { toggleNewChat } = useChatGroupContext();\r\n\r\n return (\r\n <span className=\"wxchtf-add-btn-wrapper\">\r\n <Button className=\"wxchtf-add-btn\" onClick={toggleNewChat} icon=\"+\">\r\n Add chat\r\n </Button>\r\n </span>\r\n );\r\n});\r\n","import { Space } from 'antd';\r\nimport { CreateChatButton } from '../Create';\r\nimport { AutoReplyButton } from '../AutoReply/AutoReplyButton';\r\nimport { customize } from '../../customize';\r\n\r\nexport const ChatGroupActions = customize('ChatGroupActions', () => {\r\n return (\r\n <span className=\"wxchtf-add-btn-wrapper\">\r\n <Space.Compact className=\"wxchtf-add-btn-group\">\r\n <CreateChatButton />\r\n <AutoReplyButton />\r\n </Space.Compact>\r\n </span>\r\n );\r\n});\r\n","import { useMemo } from 'react';\r\nimport { chatifyApi } from '../../../core';\r\nimport { customize } from '../../customize';\r\nimport { useChatGroupContext } from '../ChatGroupContext';\r\nimport { ChatListValue, ChatList } from '../../common';\r\n\r\nfunction useData() {\r\n const { data: chats } = chatifyApi.useGetChatListQuery();\r\n return useMemo(\r\n () =>\r\n chats?.map(\r\n (x): ChatListValue => ({\r\n id: x.id,\r\n name: x.name,\r\n lastMessage: x.message,\r\n lastReadMessageId: x.lastReadMessageId,\r\n }),\r\n ) ?? [],\r\n [chats],\r\n );\r\n}\r\n\r\nexport const ChatListPanel = customize('ChatListPanel', () => {\r\n const { chatId, openChat } = useChatGroupContext();\r\n const data = useData();\r\n\r\n return <ChatList items={data} selected={chatId} onSelect={openChat} />;\r\n});\r\n","import { customize } from '../../customize';\r\nimport { ChatListPanel } from '../List';\r\nimport { ChatGroupActions } from './ChatGroupActions';\r\n\r\nexport const ChatGroupAside = customize('ChatGroupAside', () => {\r\n return (\r\n <div className=\"wxchtf-aside\">\r\n <ChatGroupActions />\r\n <ChatListPanel />\r\n </div>\r\n );\r\n});\r\n","import { customize } from '../../customize';\r\n\r\nexport const ChatGroupHeader = customize('ChatGroupHeader', () => {\r\n return <div className=\"wxchtf-header\"></div>;\r\n});\r\n","import { customize } from '../../customize';\r\n\r\nexport const ChatGroupFooter = customize('ChatGroupFooter', () => <div className=\"wxchtf-footer\"></div>);\r\n","import { customize } from '../../customize';\r\nimport { CreateChatPanel } from '../Create';\r\nimport { ChatView } from '../../Chat';\r\nimport { useChatGroupContext } from '../ChatGroupContext';\r\nimport { chatifyApi } from '../../../core';\r\nimport { AutoReplyPanel } from '../AutoReply';\r\n\r\nexport const ChatGroupMain = customize('ChatGroupMain', () => {\r\n const { chatId, view, compact, none } = useChatGroupContext();\r\n const chat = chatifyApi.useChatListItem(chatId);\r\n\r\n return (\r\n <div className=\"wxchtf-main\">\r\n {view === 'chat' && chat && (\r\n <ChatView value={chat} key={chatId} compact={compact} onBackClick={compact ? none : undefined} />\r\n )}\r\n {view === 'new-chat' && <CreateChatPanel />}\r\n {view === 'auto-reply' && <AutoReplyPanel />}\r\n </div>\r\n );\r\n});\r\n","import { customize } from '../../customize';\r\nimport { useChatGroupContext } from '../ChatGroupContext';\r\nimport { ChatGroupAside } from './ChatGroupAside';\r\nimport { ChatGroupMain } from './ChatGroupMain';\r\n\r\nexport const ChatGroupBody = customize('ChatGroupBody', () => {\r\n const { compact, view } = useChatGroupContext();\r\n const isAsideShown = !compact || !view;\r\n const isMainShown = !compact || view;\r\n\r\n return (\r\n <div className=\"wxchtf-body\">\r\n {isAsideShown && <ChatGroupAside />}\r\n {isMainShown && <ChatGroupMain />}\r\n </div>\r\n );\r\n});\r\n","import { CSSProperties, FC, useEffect, useMemo, useRef } from 'react';\r\nimport { Localizer, LocalizerContext, defaultLocalizer } from '../localizer';\r\nimport { CreateChatPanelCustomizeValue } from './Create';\r\nimport { ChatGroupBody, ChatGroupFooter, ChatGroupHeader, ChatGroupLayoutCustomizeValue } from './Layout';\r\nimport { ChatListPanelCustomizeValue } from './List';\r\nimport { ChatGroupContext, useChatGroupContext } from './ChatGroupContext';\r\nimport { chatifyApi } from '../../core';\r\nimport { CustomizeContext } from '../customize';\r\nimport { ChatViewCustomizeValue } from '../Chat';\r\nimport { AutoReplyCustomizeValue } from './AutoReply';\r\nimport { useCompact } from '../useCompact';\r\n\r\nexport interface ChatGroupCustomizeValue\r\n extends ChatViewCustomizeValue,\r\n AutoReplyCustomizeValue,\r\n CreateChatPanelCustomizeValue,\r\n ChatListPanelCustomizeValue,\r\n ChatGroupLayoutCustomizeValue {}\r\n\r\nexport interface ChatGroupPanelProps {\r\n /**\r\n * Class name to be applied to the chat group panel container.\r\n */\r\n className?: string;\r\n\r\n /**\r\n * Style to be applied to the chat group panel container.\r\n */\r\n style?: CSSProperties;\r\n\r\n /**\r\n * Localizer to be used for the chat group panel. If not provided, the default localizer will be used.\r\n */\r\n localizer?: Localizer;\r\n\r\n /**\r\n * Chat group panel components customization. If not provided, the default customization will be used.\r\n */\r\n customize?: ChatGroupCustomizeValue;\r\n\r\n /**\r\n * If true, the chat group panel will be displayed in compact mode.\r\n * If a number is provided, the chat group panel will be displayed in compact mode if its width is less than the provided number of pixels.\r\n *\r\n * @default 768\r\n */\r\n compact?: boolean | number;\r\n}\r\n\r\ninterface ContentProps extends Pick<ChatGroupPanelProps, 'className' | 'style'> {\r\n containerRef: React.RefObject<HTMLDivElement>;\r\n}\r\n\r\nfunction Content(props: ContentProps) {\r\n const { className = '', style, containerRef } = props;\r\n const { data: chats } = chatifyApi.useGetChatListQuery();\r\n const { openChat, none, chatId, compact } = useChatGroupContext();\r\n const openFirstChatRef = useRef(false);\r\n\r\n useEffect(() => {\r\n if (chats && chatId && !chats.some((x) => x.id === chatId)) {\r\n chats.length ? openChat(chats[0].id) : none();\r\n }\r\n\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [chats, chatId]);\r\n\r\n useEffect(() => {\r\n if (chats && !openFirstChatRef.current && !compact) {\r\n openFirstChatRef.current = true;\r\n chats.length && openChat(chats[0].id);\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [chats, compact]);\r\n\r\n return (\r\n <div\r\n className={['wxchtf-chatify', 'wxchtf-chat-group', compact && '--compact', className]\r\n .filter(Boolean)\r\n .join(' ')}\r\n style={style}\r\n ref={containerRef}\r\n >\r\n <ChatGroupHeader />\r\n <ChatGroupBody />\r\n <ChatGroupFooter />\r\n </div>\r\n );\r\n}\r\n\r\nconst DEFAULT_CUSTOMIZE: ChatGroupCustomizeValue = {\r\n ChatGroupHeader: null,\r\n ChatGroupFooter: null,\r\n};\r\n\r\nexport const ChatGroupPanel: FC<ChatGroupPanelProps> = (props) => {\r\n const { localizer = defaultLocalizer, customize = DEFAULT_CUSTOMIZE, compact: compactProp } = props;\r\n const customizeValue = useMemo(() => Object.assign({}, DEFAULT_CUSTOMIZE, customize), [customize]);\r\n const [containerRef, compact] = useCompact(compactProp);\r\n\r\n return (\r\n <LocalizerContext.Provider value={localizer}>\r\n <CustomizeContext.Provider value={customizeValue as any}>\r\n <ChatGroupContext compact={compact ?? true}>\r\n <Content {...props} containerRef={containerRef} />\r\n </ChatGroupContext>\r\n </CustomizeContext.Provider>\r\n </LocalizerContext.Provider>\r\n );\r\n};\r\n","import React from 'react';\r\n\r\nexport interface ThreadContextValue {\r\n id: string;\r\n watch: boolean;\r\n onWatch: (value: boolean) => void;\r\n}\r\n\r\nexport const ThreadContext = React.createContext<ThreadContextValue>(null!);\r\n\r\nexport function useThreadContext() {\r\n return React.useContext(ThreadContext);\r\n}\r\n","import { Button, Tooltip } from 'antd';\r\nimport { customize } from '../customize';\r\nimport { useThreadContext } from './ThreadContext';\r\nimport { Icon } from '../common/Icon';\r\n\r\nexport const ThreadActions = customize('ThreadActions', () => {\r\n const { watch, onWatch } = useThreadContext();\r\n\r\n if (!watch) {\r\n return (\r\n <Tooltip title=\"Watch thread\">\r\n <Button type=\"link\" icon={<Icon type=\"watch\" />} onClick={() => onWatch(true)} />\r\n </Tooltip>\r\n );\r\n }\r\n\r\n return (\r\n <Tooltip title=\"Unwatch thread\">\r\n <Button type=\"link\" icon={<Icon type=\"unwatch\" />} onClick={() => onWatch(false)} />\r\n </Tooltip>\r\n );\r\n});\r\n","import { useCallback, useEffect, useMemo } from 'react';\r\nimport { MessageBody, chatifyApi, parseThreadMessageId } from '../../core';\r\nimport { Conversation, ConversationCustomizeValue, ConversationProps } from '../Conversation';\r\nimport { ThreadContext, ThreadContextValue } from './ThreadContext';\r\nimport { Localizer, LocalizerContext, defaultLocalizer } from '../localizer';\r\nimport { CustomizeContext } from '../customize';\r\nimport { ThreadActions } from './ThreadActions';\r\nimport { CommonCustomizeValue } from '../common';\r\n\r\nexport interface ThreadCustomizeValue extends ConversationCustomizeValue, CommonCustomizeValue {\r\n ThreadActions?: typeof ThreadActions.Component | null;\r\n}\r\n\r\nexport interface ThreadPanelProps {\r\n threadId: string;\r\n className?: string;\r\n customize?: ThreadCustomizeValue;\r\n localizer?: Localizer;\r\n}\r\n\r\nfunction usePanelState(props: ThreadPanelProps) {\r\n const { threadId } = props;\r\n const { data: thread } = chatifyApi.useGetThreadQuery({ id: threadId });\r\n const { data: messageList } = chatifyApi.useGetThreadMessageListQuery({ threadId });\r\n const { id, name, archive, lastReadMessageId, watch } = thread ?? {};\r\n const { messages, hasMore } = messageList ?? {};\r\n\r\n const [read] = chatifyApi.useReadThreadMessageMutation();\r\n const onRead = useCallback((id: string) => read({ id }), [read]);\r\n\r\n const [fetchNext, { isLoading: isFetchNextLoading }] = chatifyApi.useFetchNextThreadMessageListMutation();\r\n const onNext = useCallback(() => fetchNext({ threadId }), [fetchNext, threadId]);\r\n\r\n const [send] = chatifyApi.useSendThreadMessageMutation();\r\n const onSend = useCallback(\r\n (message: MessageBody) => send({ body: message, threadId }).unwrap(),\r\n [threadId, send],\r\n );\r\n\r\n const { data: readQueue } = chatifyApi.useGetThreadMessageReadQueueQuery();\r\n\r\n const conversation = useMemo(() => {\r\n if (!id) {\r\n return null;\r\n }\r\n\r\n const result: ConversationProps = {\r\n value: { id: id!, name: name!, active: !archive, lastReadMessageId: lastReadMessageId ?? null },\r\n messages,\r\n hasMore,\r\n onNext,\r\n nextLoading: isFetchNextLoading,\r\n onRead,\r\n onSend,\r\n noReadTracking: !watch,\r\n compact: false,\r\n isReading: (id: string) =>\r\n readQueue!.some(\r\n (unit) => parseThreadMessageId(unit.value)[0] === parseThreadMessageId(id)[0] && id <= unit.value,\r\n ),\r\n };\r\n\r\n return result;\r\n }, [\r\n onNext,\r\n onRead,\r\n onSend,\r\n isFetchNextLoading,\r\n id,\r\n name,\r\n archive,\r\n messages,\r\n hasMore,\r\n lastReadMessageId,\r\n readQueue,\r\n watch,\r\n ]);\r\n\r\n const [watchThread] = chatifyApi.useWatchThreadMutation();\r\n\r\n const threadContext = useMemo<ThreadContextValue | null>(\r\n () =>\r\n thread\r\n ? {\r\n id: thread.id,\r\n watch: thread.watch,\r\n onWatch: (value) => watchThread({ id: thread.id, watch: value }).unwrap(),\r\n }\r\n : null,\r\n [thread, watchThread],\r\n );\r\n\r\n return [conversation, threadContext] as const;\r\n}\r\n\r\nconst DEFAULT_CUSTOMIZE: ThreadCustomizeValue = {\r\n ConversationActions: () => <ThreadActions />,\r\n};\r\n\r\nexport function ThreadPanel(props: ThreadPanelProps) {\r\n const { threadId, customize, localizer = defaultLocalizer, className = '' } = props;\r\n const [conversation, threadContext] = usePanelState(props);\r\n const customizeMergeValue = useMemo(() => ({ ...DEFAULT_CUSTOMIZE, ...customize }), [customize]);\r\n\r\n useEffect(() => {\r\n chatifyApi.settings.client.connectToThread(threadId);\r\n\r\n return () => {\r\n chatifyApi.settings.client.disconnectFromThread(threadId);\r\n };\r\n }, [threadId]);\r\n\r\n if (!conversation || !threadContext) {\r\n return null;\r\n }\r\n\r\n return (\r\n <LocalizerContext.Provider value={localizer}>\r\n <ThreadContext.Provider value={threadContext}>\r\n <CustomizeContext.Provider value={customizeMergeValue as any}>\r\n <div className={`wxchtf-chatify wxchtf-thread ${className}`}>\r\n {conversation && <Conversation {...conversation} />}\r\n </div>\r\n </CustomizeContext.Provider>\r\n </ThreadContext.Provider>\r\n </LocalizerContext.Provider>\r\n );\r\n}\r\n","import { ChatPanel } from './Chat';\r\nimport { ChatGroupPanel } from './ChatGroup';\r\nimport { ThreadPanel } from './Thread';\r\n\r\nexport interface ChatifyType {\r\n Thread: typeof ThreadPanel;\r\n ChatGroup: typeof ChatGroupPanel;\r\n Chat: typeof ChatPanel;\r\n}\r\n\r\nexport const Chatify = {\r\n Thread: ThreadPanel,\r\n ChatGroup: ChatGroupPanel,\r\n Chat: ChatPanel,\r\n} as unknown as ChatifyType;\r\n"],"names":["forwardRef","unit","chatId","AntdAvatar","useConversation","isEnter","files","id","Content","customize","DEFAULT_CUSTOMIZE"],"mappings":";;;;;;;;;;;;AAKA,MAAM,wBAAsC;AAAA,EAC1C,YAAY;AAAA,EACZ,WAAW;AACb;AAEO,SAAS,MAAM,OAAe,UAAwB,IAAI;AAC/D,YAAU,OAAO,OAAO,CAAA,GAAI,uBAAuB,OAAO;AAE1D,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,WAAO,MAAM,WAAW,CAAC,MAAM,QAAQ,KAAK;AAC5C,WAAO,OAAO;AAAA,EAChB;AACA,SAAO,OAAO,OAAO,GAAG,KAAK,QAAQ,UAAU,MAAM,QAAQ,SAAS;AACxE;ACZO,MAAM,mBAAmB,MAAM,cAAmC,IAAK;AAEvE,SAAS,sBAA8B;AAC5C,SAAO,WAAW,gBAAgB;AACpC;AAEA,SAAS,UAAkD,KAA4C;AACrG,QAAM,QAAQ,WAAW,gBAAgB;AACzC,SAAO,QAAS,MAAM,GAAG,IAAsC;AACjE;AAEO,SAAS,aAAqE,QAAiB;AACpG,QAAM,SAAS,UAAgC,OAAO,GAAG;AAEzD,MAAI,UAAU,MAAM;AAClB,WAAO;AAAA,EACT;AAEA,SAAO,UAAU,OAAO;AAC1B;AAEO,SAAS,UACd,KACA,WACgG;AAChG,QAAM,SAAkB,MAAM,WAA4B,CAAC,OAAYA,gBAAe;AACpF,UAAM,SAAS,UAAU,GAAG;AAE5B,QAAI,WAAW,MAAM;AACnB,aAAO;AAAA,IACT;AAEA,QAAI,QAAQ;AACV,aAAO,oBAAC,QAAA,EAAQ,GAAG,OAAO,KAAKA,aAAY;AAAA,IAC7C;AAEA,WAAO,oBAAC,WAAA,EAAW,GAAG,OAAO,KAAKA,aAAY;AAAA,EAChD,CAAC;AAED,YAAU,cAAc,UAAU,eAAe;AACjD,SAAO,cAAc,kBAAkB,UAAU;AAEjD,SAAO,OAAO,OAAO,QAAQ,EAAE,KAAK,WAAW;AACjD;ACzBO,MAAM,QAAQ;AAAA,EACnB,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,iBAAiB;AAAA,EACjB,gCAAgC;AAAA,EAChC,cAAc;AAAA,EACd,2BAA2B;AAAA,EAC3B,SAAS;AAAA,EACT,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA,EACN,OAAO;AAAA,EACP,SAAS;AAAA,EACT,eAAe;AAAA,EACf,aAAa;AAAA,EACb,UAAU;AACZ;AAEO,MAAM,OAAO,UAAyB,QAAQ,CAAC,UAAU;AAC9D,QAAM,EAAE,SAAS;AACjB,QAAM,gBAAgB,MAAM,IAAI;AAChC,SAAO,gBAAgB,oBAAC,eAAA,CAAA,CAAc,IAAK;AAC7C,CAAC;ACtCD,MAAM,mBAAmB,MAAM,cAA2B,IAAK;AAExD,SAAS,iBAAiB;AAC/B,SAAO,WAAW,gBAAgB;AACpC;AAGO,SAAS,YAAY,OAA4D;AACtF,QAAM,EAAE,IAAI,UAAU,QAAA,IAAY;AAClC,QAAM,CAAC,aAAa,aAAa,IAAI,SAAS,KAAK;AAEnD,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,IAEF,CAAC,IAAI,aAAa,OAAO;AAAA,EAAA;AAG3B,SAAO,oBAAC,iBAAiB,UAAjB,EAA0B,OAAe,SAAA,CAAS;AAC5D;AC1BO,MAAM,oBAAoB,UAAU,qBAAqB,MAAM;AACpE,QAAM,EAAE,aAAa,cAAA,IAAkB,eAAA;AACvC,SAAO,oBAAC,QAAA,EAAO,SAAS,MAAM,cAAc,CAAC,WAAW,GAAG,MAAK,QAAO,MAAM,oBAAC,MAAA,EAAK,MAAK,WAAU,GAAI;AACxG,CAAC;ACRM,MAAM,YAAY;AC6GlB,SAAS,OAAO,WAAmB;AACxC,SAAO,UAAU,MAAM,GAAG,EAAE;AAC9B;AAEO,SAAS,oBAAoB,IAAY;AAC9C,SAAO,GAAG,MAAM,EAAE;AACpB;AA2CO,SAAS,qBAAqB,WAAmB;AACtD,QAAM,CAAC,UAAU,KAAK,IAAI,UAAU,MAAM,MAAM,CAAC;AACjD,SAAO,CAAC,UAAU,SAAS,OAAO,EAAE,CAAC;AACvC;AAEO,SAAS,sBACd,QACA;;AACA,QAAM,uBACJ,OAAO,qBAAqB,OAAO,qBAAqB,OAAO,iBAAiB,EAAE,CAAC,IAAI;AAEzF,QAAM,2BACJ,YAAO,gBAAP,mBAAoB,OAAM,OAAO,sBAAqB,YAAO,gBAAP,mBAAoB,EAAE,EAAE,CAAC,IAAI;AAErF,SAAO,yBAAyB;AAClC;AAEO,SAAS,0BACd,SACA;AACA,SAAO,QAAQ,OAAO,CAAC,MAAM,WAAW;AACtC,WAAO,OAAO,sBAAsB,MAAM;AAAA,EAC5C,GAAG,CAAC;AACN;ACrKO,MAAM,SAAY;AAAA,EAMvB,YAAmB,QAA2B;AALtC,qCAAwC,CAAA;AACxC,uCAA0C,CAAA;AAC1C,2CAA0C,CAAA;AAC1C,wCAAgD,CAAA;AAWjD,qCAAY,CAAC,aAA0C;AAC5D,WAAK,aAAa,KAAK,QAAQ;AAC/B,aAAO,MAAM;AACX,aAAK,eAAe,KAAK,aAAa,OAAO,CAAC,MAAM,MAAM,QAAQ;AAAA,MACpE;AAAA,IACF;AAEO,kCAAS,MAAM;AACpB,WAAK,aAAa,QAAQ,CAAC,eAAe,WAAW,IAAI,CAAC;AAAA,IAC5D;AAlBmB,SAAA,SAAA;AAAA,EAA4B;AAAA,EAE/C,IAAW,QAA4B;AACrC,WAAO;AAAA,MACL,GAAG,KAAK,UAAU,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,WAAA,EAAsB;AAAA,MACnE,GAAG,KAAK,YAAY,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,eAAwB;AAAA,IAAA;AAAA,EAE3E;AAAA,EAaO,KAAK,OAAU;AACpB,UAAM,QAAQ,KAAK,OAAO,QAAQ,KAAK;AACvC,UAAM,OAAO,KAAK,UAAU,KAAK,CAACC,UAAS,KAAK,OAAO,QAAQA,MAAK,KAAK,MAAM,KAAK;AAEpF,QAAI,CAAC,MAAM;AACT,WAAK,UAAU,KAAK,EAAE,OAAO,aAAa,KAAK,IAAA,GAAO;AAAA,IACxD,WAAW,KAAK,OAAO,QAAQ,KAAK,OAAO,KAAK,KAAK,GAAG;AACtD,WAAK,QAAQ;AACb,WAAK,cAAc,KAAK,IAAA;AAAA,IAC1B;AAEA,SAAK,SAAS,KAAK;AAAA,EACrB;AAAA,EAEQ,SAAS,OAAe;AAC9B,QAAI,CAAC,KAAK,UAAU,KAAK,CAAC,SAAS,KAAK,OAAO,QAAQ,KAAK,KAAK,MAAM,KAAK,GAAG;AAC7E;AAAA,IACF;AAEA,QAAI,UAAU,KAAK,gBAAgB,KAAK;AACxC,eAAW,aAAa,OAAO;AAE/B,QAAI,KAAK,YAAY,KAAK,CAAC,SAAS,KAAK,OAAO,QAAQ,KAAK,KAAK,MAAM,KAAK,GAAG;AAC9E;AAAA,IACF;AAEA,cAAU,WAAW,MAAM;AACzB,YAAM,aAAa,KAAK,UAAU,KAAK,CAAC,SAAS,KAAK,OAAO,QAAQ,KAAK,KAAK,MAAM,KAAK;AAC1F,WAAK,YAAY,KAAK,UAAU;AAChC,WAAK,UAAU,OAAO,KAAK,UAAU,QAAQ,UAAU,GAAG,CAAC;AAC3D,WAAK,OAAA;AAEL,WAAK,OACF,SAAS,WAAW,KAAK,EACzB,KAAK,MAAM;AACV,aAAK,YAAY,OAAO,KAAK,YAAY,QAAQ,UAAU,GAAG,CAAC;AAC/D,aAAK,OAAA;AACL,aAAK,SAAS,KAAK;AAAA,MACrB,CAAC,EACA,MAAM,MAAM;AACX,aAAK,YAAY,OAAO,KAAK,YAAY,QAAQ,UAAU,GAAG,CAAC;AAC/D,aAAK,KAAK,WAAW,KAAK;AAAA,MAC5B,CAAC;AAAA,IACL,GAAG,KAAK,OAAO,OAAO;AAEtB,SAAK,gBAAgB,KAAK,IAAI;AAAA,EAChC;AACF;ACpFO,MAAM,4BAA4B;AAclC,MAAM,aAAiC;AAAA,EAC5C,IAAI;AAAA,EACJ,QAAQ;AACV;AAEA,MAAM,YAAY,CAAC,QAAQ,WAAW,WAAW,UAAU,gBAAgB;AAK3E,MAAM,UACJ,UAAU;AAAA,EACR,WAAW,cAAA;AAAA,EACX,aAAa;AAAA,EACb,UAAU;AAAA,EACV,WAAW,CAAC,OAAO,CAAA;AACrB,CAAC;AAEI,MAAM,YAAY;ACVzB,MAAM,yBAA+C;AAAA,EACnD,QAAQ;AAAA,EACR,gBAAgB,MAAM,QAAQ,QAAQ,CAAA,CAAE;AAC1C;AAOO,MAAM,0BAA0B;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAiCO,MAAM,cAAc;AAAA,EAQzB,YAAY,QAA6B;AAPjC;AACA,uCAAqC;AACrC,8CAA4D;AAC5D,wCAA0D,CAAA;AAC1D,iDAA2C,CAAA;AAC3C,2EAAkC,IAAA;AAYnC,mCAAU,YAAY;AAC3B,UAAI,KAAK,aAAa;AACpB;AAAA,MACF;AAEA,UAAI,KAAK,oBAAoB;AAC3B,eAAO,MAAM,KAAK;AAAA,MACpB;AAEA,WAAK,qBAAqB,KAAK,yBAAA;AAC/B,WAAK,cAAc,MAAM,KAAK;AAAA,IAChC;AAEQ,oDAA2B,YAAY;AAC7C,YAAM,UAAU,MAAM,KAAK,QAAQ,QAAS,eAAA;AAE5C,YAAM,aAAa,IAAI,QAAQ,qBAAA,EAC5B,QAAQ,KAAK,QAAQ,QAAS,QAAS;AAAA,QACtC,oBAAoB,KAAK,QAAQ,QAAS,qBACtC,KAAK,QAAQ,QAAS,qBACtB;AAAA,QACJ;AAAA,MAAA,CACD,EACA,uBAAA,EACA,MAAA;AAEH,8BAAwB,QAAQ,CAAC,MAAM;AACrC,mBAAW,GAAG,GAAG,IAAI,SAAS;;AAC5B,qBAAK,aAAa,CAAC,MAAnB,mBAAsB,QAAQ,CAAC,MAAM;AACnC,gBAAI;AACF,gBAAE,IAAI;AAAA,YACR,SAAS,IAAI;AACX,sBAAQ,MAAM,+BAA+B,EAAE;AAAA,YACjD;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAED,iBAAW,cAAc,MAAM,KAAK,sBAAsB,QAAQ,CAAC,eAAe,WAAA,CAAY,CAAC;AAE/F,YAAM,WAAW,MAAA;AACjB,aAAO;AAAA,IACT;AAEO,qCAAY,CACjB,QACA,eACG;AACH,WAAK,UAAU,KAAK,MAAM;AACxB,aAAK,aAAa,MAAM,IAAI,KAAK,aAAa,MAAM,KAAK,CAAA;AACzD,aAAK,aAAa,MAAM,EAAE,KAAK,UAAiB;AAAA,MAClD,CAAC;AACD,aAAO,MAAM,KAAK,aAAa,MAAM,EAAE,OAAO,CAAC,MAAM,MAAM,UAAU;AAAA,IACvE;AAEO,8CAAqB,CAAC,eAA0B;AACrD,WAAK,sBAAsB,KAAK,UAAU;AAC1C,aAAO,MAAM,KAAK,sBAAsB,OAAO,CAAC,MAAM,MAAM,UAAU;AAAA,IACxE;AAMO,oCAAW,OAAO,SAA6B;;AACpD,YAAM,eAAe,IAAI,gBAAA;AAEzB,yCAAM,QAAN,mBAAW,QAAQ,CAAC,OAAO;AACzB,qBAAa,OAAO,OAAO,mBAAmB,EAAE,CAAC;AAAA,MACnD;AAEA,YAAM,EAAE,KAAA,IAAS,MAAM,KAAK,MAAM,IAAe,WAAW,aAAa,SAAA,CAAU,EAAE;AACrF,aAAO;AAAA,IACT;AAEO,8CAAqB,YAAY;AACtC,YAAM,EAAE,KAAA,IAAS,MAAM,KAAK,MAAM,IAAa,YAAY;AAC3D,aAAO;AAAA,IACT;AAEO,yCAAgB,OAAO,YAAkC;AAC9D,YAAM,KAAK,MAAM,IAAI,WAAW,mBAAmB,QAAQ,EAAE,CAAC,IAAI,OAAO;AAAA,IAC3E;AAEO,iCAAQ,YAAY;AACzB,YAAM,EAAE,KAAA,IAAS,MAAM,KAAK,MAAM,IAAoB,MAAM;AAC5D,aAAO;AAAA,IACT;AAEO,gCAAO,OAAO,OAAe;AAClC,YAAM,EAAE,KAAA,IAAS,MAAM,KAAK,MAAM,IAAU,QAAQ,mBAAmB,EAAE,CAAC,EAAE;AAC5E,aAAO;AAAA,IACT;AAEO,mCAAU,OAAO,SAAyB;AAC/C,YAAM,EAAE,SAAS,MAAM,KAAK,MAAM,KAAa,QAAQ,IAAI;AAC3D,aAAO;AAAA,IACT;AAEO,wCAAe,OAAO,SAA2D;AACtF,YAAM,EAAE,QAAAC,SAAQ,OAAO,GAAG,OAAO,OAAO;AACxC,YAAM,aAAa,mBAAmB,KAAK,UAAU,EAAE,MAAM,KAAA,CAAM,CAAC;AACpE,YAAM,EAAE,KAAA,IAAS,MAAM,KAAK,MAAM;AAAA,QAChC,QAAQ,mBAAmBA,OAAM,CAAC,uBAAuB,UAAU;AAAA,MAAA;AAErE,aAAO;AAAA,IACT;AAEO,2CAAkB,OAAO,YAAoC;AAClE,YAAM,EAAE,QAAAA,SAAQ,GAAG,KAAA,IAAS;AAC5B,YAAM,KAAK,MAAM,KAAK,QAAQ,mBAAmBA,OAAM,CAAC,YAAY,IAAI;AAAA,IAC1E;AAEO,2CAAkB,OAAO,YAAoC;AAClE,YAAM,KAAK,MAAM,IAAI,qBAAqB,OAAO;AAAA,IACnD;AAEO,4CAAmB,OAAO,YAAqC;AACpE,YAAM,KAAK,MAAM,OAAO,QAAQ,mBAAmB,QAAQ,MAAM,CAAC,WAAW,EAAE,MAAM,QAAA,CAAS;AAAA,IAChG;AAEO,0CAAiB,OAAO,YAAmC;AAChE,YAAM,KAAK,MAAM,IAAI,QAAQ,mBAAmB,QAAQ,EAAE,CAAC,SAAS,OAAO;AAAA,IAC7E;AAEO,yCAAgB,OAAO,YAAkC;AAC9D,YAAM,KAAK,MAAM,KAAK,QAAQ,mBAAmB,QAAQ,MAAM,CAAC,WAAW,OAAO;AAAA,IACpF;AAEO,6CAAoB,OAAO,EAAE,MAAM,eAAyC;AACjF,YAAM,EAAE,MAAM,OAAO,MAAM,KAAK,MAAM,KAAa,UAAU,mBAAmB,QAAQ,CAAC,YAAY;AAAA,QACnG;AAAA,MAAA,CACD;AACD,aAAO;AAAA,IACT;AAEO,6CAAoB,OAAO,OAAe;AAC/C,YAAM,KAAK,MAAM,IAAI,kBAAkB,mBAAmB,EAAE,CAAC,OAAO;AAAA,IACtE;AAEO,wCAAe,YAAY;AAChC,YAAM,EAAE,KAAA,IAAS,MAAM,KAAK,MAAM,IAAsB,cAAc;AACtE,aAAO;AAAA,IACT;AAEO,kCAAS,OAAO,OAAe;AACpC,YAAM,EAAE,KAAA,IAAS,MAAM,KAAK,MAAM,IAAY,UAAU,mBAAmB,EAAE,CAAC,EAAE;AAChF,aAAO;AAAA,IACT;AAEO,0CAAiB,OAAO;AAAA,MAC7B;AAAA,MACA;AAAA,MACA;AAAA,IAAA,MAKI;AACJ,YAAM,eAAe,IAAI,gBAAA;AACzB,mBAAa,OAAO,QAAQ,KAAK,SAAA,CAAU;AAC3C,mBAAa,OAAO,QAAQ,KAAK,SAAA,CAAU;AAC3C,YAAM,EAAE,KAAA,IAAS,MAAM,KAAK,MAAM;AAAA,QAChC,UAAU,mBAAmB,QAAQ,CAAC,YAAY,aAAa,UAAU;AAAA,MAAA;AAE3E,aAAO;AAAA,IACT;AAEO,uCAAc,OAAO,IAAY,UAAmB;AACzD,YAAM,KAAK,MAAM,IAAI,UAAU,mBAAmB,EAAE,CAAC,UAAU,EAAE,MAAA,CAAO;AAAA,IAC1E;AAEO,2CAAkB,OAAO,OAAe;AAC7C,YAAM,kBAAkB,KAAK,4BAA4B,IAAI,EAAE,KAAK;AACpE,WAAK,4BAA4B,IAAI,IAAI,kBAAkB,CAAC;AAE5D,UAAI,oBAAoB,GAAG;AACzB,aAAK,UAAU,KAAK,MAAM,KAAK,YAAY,OAAO,mBAAmB,EAAE,CAAC;AAAA,MAC1E;AAAA,IACF;AAEO,gDAAuB,OAAO,OAAe;AAClD,YAAM,kBAAkB,KAAK,4BAA4B,IAAI,EAAE,KAAK;AACpE,WAAK,4BAA4B,IAAI,IAAI,KAAK,IAAI,GAAG,kBAAkB,CAAC,CAAC;AAEzE,UAAI,oBAAoB,GAAG;AACzB,aAAK,UAAU,KAAK,MAAM,KAAK,YAAY,OAAO,wBAAwB,EAAE,CAAC;AAAA,MAC/E;AAAA,IACF;AArME,SAAK,UAAU;AAAA,MACb,GAAG;AAAA,MACH,SAAS;AAAA,QACP,GAAG;AAAA,QACH,GAAG,OAAO;AAAA,MAAA;AAAA,IACZ;AAAA,EAEJ;AAAA,EA8DA,IAAW,QAAQ;AACjB,WAAO,KAAK,QAAQ;AAAA,EACtB;AA+HF;AAEO,SAAS,eAAe,aAAgC;AAC7D,QAAM,SAAS,MAAM,YAAY,QAAQ,CAAC,MAAM,GAAG;AACnD,SAAO,OAAO,CAAC,YAA0B,QAAQ,KAAK,MAAM;AAC5D,SAAO;AACT;ACxQA,MAAM,4BAA4B,IAAI,SAAiB;AAAA,EACrD,UAAU,CAAC,OAAO,WAAW,OAAO,kBAAkB,EAAE;AAAA,EACxD,SAAS,CAAC,GAAG,MAAM,CAAC,EAAE,cAAc,CAAC;AAAA,EACrC,SAAS,CAAC,OAAO,qBAAqB,EAAE,EAAE,CAAC;AAAA,EAC3C,SAAS;AACX,CAAC;AAED,MAAM,0BAA0B,IAAI,SAAiB;AAAA,EACnD,UAAU,CAAC,OAAO,WAAW,OAAO,gBAAgB,EAAE,IAAI;AAAA,EAC1D,SAAS,CAAC,GAAG,MAAM,CAAC,EAAE,cAAc,CAAC;AAAA,EACrC,SAAS,CAAC,OAAO,OAAO,EAAE;AAAA,EAC1B,SAAS;AACX,CAAC;AAED,MAAM,eAAe,UAAU,gBAAgB;AAAA,EAC7C,WAAW,CAAC,aAAa;AAAA;AAAA;AAAA;AAAA,IAKvB,gBAAgB,QAAQ,MAAqC;AAAA,MAC3D,SAAS,OAAO,UAAU,EAAE,MAAM,MAAM,WAAW,OAAO,SAAS,IAAI;MACvE,cAAc,CAAC,SAAS;AAAA,IAAA,CACzB;AAAA,IAED,sBAAsB,QAAQ,MAA4B;AAAA,MACxD,SAAS,aAAa,EAAE,MAAM,MAAM,WAAW,OAAO;MACtD,cAAc,CAAC,SAAS;AAAA,IAAA,CACzB;AAAA,IAED,eAAe,QAAQ,SAAqC;AAAA,MAC1D,SAAS,OAAO,YAAY;AAC1B,cAAM,WAAW,OAAO,cAAc,OAAO;AAC7C,eAAO,EAAE,MAAM,KAAA;AAAA,MACjB;AAAA,MACA,iBAAiB,CAAC,SAAS;AAAA,IAAA,CAC5B;AAAA;AAAA;AAAA;AAAA,IAMD,SAAS,QAAQ,MAA4B;AAAA,MAC3C,SAAS,OAAO,EAAE,GAAA,OAAU,EAAE,MAAM,MAAM,WAAW,OAAO,KAAK,EAAE;MACnE,cAAc,CAAC,QAAQ,SAAS;AAAA,MAChC,mBAAmB,OAAO,EAAE,GAAA,GAAM,EAAE,mBAAmB,iBAAiB,uBAAuB;AAC7F,cAAM;AAEN;AAAA,UACE,WAAW,OAAO;AAAA,YAChB;AAAA,YACA,CAAC,CAACA,SAAQ,GAAG,SAAS,SAAA,EAAW,IAAI,MACnCA,YAAW,MACX,iBAAiB,CAAC,SAAS;AACzB,mBAAK,QAAQ,KAAK,OAAO;AACzB,mBAAK,oBAAoB,OAAO,QAAQ,KAAK,KAAK;AAAA,YACpD,CAAC;AAAA,UAAA;AAAA,UAEL,WAAW,OAAO;AAAA,YAChB;AAAA,YACA,CAAC,CAACA,SAAQ,WAAA,EAAa,SAAS,IAAI,MAClC,OAAOA,WACP,iBAAiB,CAAC,SAAS;AACzB,mBAAK,UAAU,KAAK,QAAQ,OAAO,CAAC,MAAM,EAAE,OAAO,SAAS;AAC5D,mBAAK,oBAAoB,OAAO,QAAQ,KAAK,KAAK;AAAA,YACpD,CAAC;AAAA,UAAA;AAAA,UAEL,WAAW,OAAO;AAAA,YAChB;AAAA,YACA,CAAC,CAACA,SAAQ,SAAS,SAAS,IAAI,MAC9B,OAAOA,WACP,iBAAiB,CAAC,SAAS;AACzB,mBAAK,OAAO;AACZ,mBAAK,oBAAoB,OAAO,QAAQ,KAAK,KAAK;AAAA,YACpD,CAAC;AAAA,UAAA;AAAA,UAEL,WAAW,OAAO;AAAA,YAChB;AAAA,YACA,CAAC,CAAC,OAAO,MACP,OAAO,QAAQ,UACf,iBAAiB,CAAC,SAAS;AACzB,mBAAK,oBACH,QAAQ,OAAO,OAAO,WAAW,OAAO,QAAQ,KAAK,KAAK;AAAA,YAC9D,CAAC;AAAA,UAAA;AAAA,UAEL,WAAW,OAAO;AAAA,YAChB;AAAA,YACA,CAAC,CAAC,MAAM,MACN,OAAO,KAAK,CAAC,MAAM,EAAE,WAAW,EAAE,KAClC,iBAAiB,CAAC,SAAS;AACzB,oBAAM,QAAQ,OAAO,KAAK,CAAC,MAAM,EAAE,WAAW,EAAE;AAChD,mBAAK,oBAAoB,MAAM;AAAA,YACjC,CAAC;AAAA,UAAA;AAAA,QACL,EACA,KAAK,iBAAiB;AAAA,MAC1B;AAAA,IAAA,CACD;AAAA,IAED,SAAS,QAAQ,SAAsD;AAAA,MACrE,SAAS,OAAO,EAAE,MAAM,cAAc;AACpC,cAAMA,UAAS,MAAM,WAAW,OAAO,QAAQ;AAAA,UAC7C;AAAA,UACA;AAAA,QAAA,CACD;AACD,eAAO,EAAE,MAAMA,QAAAA;AAAAA,MACjB;AAAA,IAAA,CACD;AAAA,IAED,gBAAgB,QAAQ,SAA6C;AAAA,MACnE,SAAS,OAAO,EAAE,IAAI,WAAW;AAC/B,cAAM,WAAW,OAAO,eAAe,EAAE,IAAI,MAAM;AACnD,eAAO,EAAE,MAAM,KAAA;AAAA,MACjB;AAAA,IAAA,CACD;AAAA;AAAA;AAAA;AAAA,IAMD,aAAa,QAAQ,MAA4B;AAAA,MAC/C,SAAS,aAAa,EAAE,MAAM,MAAM,WAAW,OAAO;MACtD,cAAc,CAAC,QAAQ,SAAS;AAAA,MAChC,mBAAmB,OAAO,GAAG,EAAE,mBAAmB,iBAAiB,uBAAuB;AACxF,cAAM;AAEN;AAAA,UACE,WAAW,OAAO;AAAA,YAAU;AAAA,YAA0B,CAAC,CAAC,IAAI,MAC1D,iBAAiB,CAAC,aAAa;AAC7B,uBAAS,KAAK,IAAI;AAAA,YACpB,CAAC;AAAA,UAAA;AAAA,UAGH,WAAW,OAAO;AAAA,YAAU;AAAA,YAA8B,CAAC,CAAC,OAAO,MACjE,iBAAiB,CAAC,aAAa;AAC7B,oBAAM,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ,MAAM;AAEzD,kBAAI,CAAC,MAAM;AACT;AAAA,cACF;AAEA,mBAAK,UAAU;AAEf,kBAAI,QAAQ,OAAO,OAAO,WAAW,MAAM;AACzC,qBAAK,oBAAoB,QAAQ;AACjC,qBAAK,mBAAmB;AAAA,cAC1B;AAEA,kBAAI,QAAQ,OAAO,OAAO,WAAW,MAAM;AACzC,qBAAK;AAAA,cACP;AAAA,YACF,CAAC;AAAA,UAAA;AAAA,UAEH,WAAW,OAAO;AAAA,YAAU;AAAA,YAA+B,CAAC,CAAC,MAAM,MACjE,iBAAiB,CAAC,aAAa;AAC7B,yBAAW,SAAS,QAAQ;AAC1B,sBAAM,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,MAAM;AAEvD,oBAAI,CAAC,MAAM;AACT;AAAA,gBACF;AAEA,qBAAK,oBAAoB,MAAM;AAC/B,qBAAK,mBAAmB,KAAK,mBAAmB,MAAM;AAAA,cACxD;AAAA,YACF,CAAC;AAAA,UAAA;AAAA,UAEH,WAAW,OAAO;AAAA,YAChB;AAAA,YACA,CAAC,CAACA,SAAQ,UAAU,SAAS,SAAA,EAAW,IAAI,MAC1C,iBAAiB,CAAC,aAAa;AAC7B,oBAAM,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAOA,OAAM;AAEjD,kBAAI,QAAQ,OAAO,WAAW,GAAA,KAAQ,CAAC,MAAM;AAC3C,yBAAS,KAAK;AAAA,kBACZ,IAAIA;AAAAA,kBACJ,MAAM;AAAA,kBACN;AAAA,kBACA,kBAAkB,OAAO,IAAI;AAAA,kBAC7B,QAAQ;AAAA,kBACR,mBAAmB,OAAO,QAAQ,KAAK;AAAA,gBAAA,CACxC;AAAA,cACH;AAEA,kBAAI,CAAC,MAAM;AACT;AAAA,cACF;AAEA,mBAAK,UAAU;AACf,mBAAK,SAAS;AAEd,kBAAI,MAAM;AACR,qBAAK,mBAAmB;AACxB,qBAAK,oBAAoB,QAAQ;AAAA,cACnC,OAAO;AACL,qBAAK;AAAA,cACP;AAAA,YACF,CAAC;AAAA,UAAA;AAAA,UAEL,WAAW,OAAO;AAAA,YAChB;AAAA,YACA,CAAC,CAACA,SAAQ,WAAW,eAAe,SAAS,IAAI,MAC/C,iBAAiB,CAAC,aAAa;AAC7B,kBAAI,cAAc,WAAW,GAAA,KAAQ,eAAe;AAClD,uBAAO,SAAS,OAAO,CAAC,MAAM,EAAE,OAAOA,OAAM;AAAA,cAC/C;AAEA,oBAAM,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAOA,OAAM;AAEjD,kBAAI,CAAC,MAAM;AACT;AAAA,cACF;AAEA,mBAAK,UAAU;AAEf,kBAAI,cAAc,WAAW,MAAM;AACjC,qBAAK,SAAS;AAAA,cAChB;AAEA,kBAAI,CAAC,MAAM;AACT,qBAAK;AAAA,cACP,OAAO;AACL,qBAAK,mBAAmB;AACxB,qBAAK,oBAAoB,QAAQ;AAAA,cACnC;AAAA,YACF,CAAC;AAAA,UAAA;AAAA,UAEL,WAAW,OAAO;AAAA,YAAU;AAAA,YAA+B,CAAC,CAACA,SAAQ,SAAS,SAAS,IAAI,MACzF,iBAAiB,CAAC,aAAa;AAC7B,oBAAM,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAOA,OAAM;AACjD,kBAAI,CAAC,KAAM;AAEX,mBAAK,OAAO;AACZ,mBAAK,UAAU;AAEf,kBAAI,CAAC,MAAM;AACT,qBAAK;AAAA,cACP,OAAO;AACL,qBAAK,mBAAmB;AACxB,qBAAK,oBAAoB,QAAQ;AAAA,cACnC;AAAA,YACF,CAAC;AAAA,UAAA;AAAA,QACH,EACA,KAAK,iBAAiB;AAAA,MAC1B;AAAA,IAAA,CACD;AAAA;AAAA;AAAA;AAAA,IAMD,kBAAkB,QAAQ,SAAwC;AAAA,MAChE,SAAS,OAAO,SAAS;AACvB,cAAM,WAAW,OAAO,iBAAiB,IAAI;AAC7C,eAAO,EAAE,MAAM,KAAA;AAAA,MACjB;AAAA,IAAA,CACD;AAAA,IAED,eAAe,QAAQ,SAAqC;AAAA,MAC1D,SAAS,OAAO,SAAS;AACvB,cAAM,WAAW,OAAO,cAAc,IAAI;AAC1C,eAAO,EAAE,MAAM,KAAA;AAAA,MACjB;AAAA,IAAA,CACD;AAAA;AAAA;AAAA;AAAA,IAMD,oBAAoB,QAAQ,MAAiD;AAAA,MAC3E,SAAS,OAAO,EAAE,QAAAA,cAAa;AAC7B,cAAM,WAAW,MAAM,WAAW,OAAO,aAAa;AAAA,UACpD,QAAAA;AAAAA,UACA,MAAM;AAAA,UACN,MAAM,4BAA4B;AAAA,QAAA,CACnC;AACD,eAAO;AAAA,UACL,MAAM;AAAA,YACJ,UAAU,SAAS,MAAM,GAAG,yBAAyB;AAAA,YACrD,SAAS,SAAS,WAAW,4BAA4B;AAAA,UAAA;AAAA,QAC3D;AAAA,MAEJ;AAAA,MACA,cAAc,CAAC,WAAW,QAAQ,SAAS;AAAA,MAC3C,mBAAmB,OAAO,EAAE,QAAAA,QAAAA,GAAU,EAAE,UAAU,mBAAmB,sBAAsB;AACzF,cAAM;AAEN;AAAA,UACE,WAAW,OAAO,UAAU,8BAA8B,CAAC,CAAC,OAAO,MAAM;AACvE,oBAAQ,WAAWA,WACjB;AAAA,cACE,WAAW,KAAK,gBAAgB,sBAAsB,EAAE,QAAAA,QAAAA,GAAU,CAAC,UAAU;AAC3E,sBAAM,SAAS,QAAQ,OAAO;AAAA,cAChC,CAAC;AAAA,YAAA;AAAA,UAEP,CAAC;AAAA,UAED,WAAW,OAAO,UAAU,+BAA+B,CAAC,CAAC,aAAA,EAAA,EAAiB,OAAO,MAAM;AACzF,4BAAgBA,WACd;AAAA,cACE,WAAW,KAAK,gBAAgB,sBAAsB,EAAE,QAAAA,QAAAA,GAAU,CAAC,UAAU;AAC3E,sBAAM,SAAS,QAAQ,OAAO;AAAA,cAChC,CAAC;AAAA,YAAA;AAAA,UAEP,CAAC;AAAA,UAED,WAAW,OAAO,UAAU,iCAAiC,CAAC,CAAC,aAAA,EAAA,EAAiB,OAAO,MAAM;AAC3F,4BAAgBA,WACd;AAAA,cACE,WAAW,KAAK,gBAAgB,sBAAsB,EAAE,QAAAA,QAAAA,GAAU,CAAC,UAAU;AAC3E,sBAAM,SAAS,QAAQ,OAAO;AAAA,cAChC,CAAC;AAAA,YAAA;AAAA,UAEP,CAAC;AAAA,UAED,WAAW,OAAO,UAAU,+BAA+B,CAAC,CAAC,aAAA,EAAe,OAAO,MAAM;AACvF,4BAAgBA,WACd;AAAA,cACE,WAAW,KAAK,gBAAgB,sBAAsB,EAAE,QAAAA,QAAAA,GAAU,CAAC,UAAU;AAC3E,sBAAM,SAAS,QAAQ,OAAO;AAAA,cAChC,CAAC;AAAA,YAAA;AAAA,UAEP,CAAC;AAAA,QAAA,EACD,KAAK,iBAAiB;AAAA,MAC1B;AAAA,IAAA,CACD;AAAA,IAED,0BAA0B,QAAQ,SAAmC;AAAA,MACnE,SAAS,OAAO,EAAE,QAAAA,WAAU,EAAE,eAAe;AAC3C,cAAM,UAAU,WAAW,UAAU,mBAAmB,OAAO,EAAE,QAAAA,QAAAA,CAAQ,EAAE,UAAiB;AAC5F,cAAM,WAAW,MAAM,WAAW,OAAO,aAAa;AAAA,UACpD,QAAAA;AAAAA,UACA,MAAM,QAAQ,KAAM,SAAS;AAAA,UAC7B,MAAM,4BAA4B;AAAA,QAAA,CACnC;AACD,eAAO;AAAA,UACL,MAAM;AAAA,UACN,MAAM;AAAA,YACJ,UAAU,SAAS,MAAM,GAAG,yBAAyB;AAAA,YACrD,SAAS,SAAS,WAAW,4BAA4B;AAAA,UAAA;AAAA,QAC3D;AAAA,MAEJ;AAAA,MACA,gBAAgB,OAAO,EAAE,QAAAA,WAAU,EAAE,UAAU,qBAAqB;AAClE,cAAM,SAAS,MAAM;AACrB,cAAM,OAA8B,OAAO;AAE3C;AAAA,UACE,WAAW,KAAK,gBAAgB,sBAAsB,EAAE,QAAAA,QAAAA,GAAU,CAAC,UAAU;AAC3E,kBAAM,UAAU,KAAK;AACrB,kBAAM,SAAS,KAAK,GAAG,KAAM,QAAQ;AAAA,UACvC,CAAC;AAAA,QAAA;AAAA,MAEL;AAAA,IAAA,CACD;AAAA,IAED,iBAAiB,QAAQ,SAAuC;AAAA,MAC9D,SAAS,OAAO,EAAE,QAAAA,SAAQ,MAAM,YAAY;AAC1C,cAAM,WAAW,OAAO,gBAAgB;AAAA,UACtC,QAAAA;AAAAA,UACA;AAAA,UACA;AAAA,QAAA,CACD;AAED,eAAO,EAAE,MAAM,KAAA;AAAA,MACjB;AAAA,IAAA,CACD;AAAA,IAED,iBAAiB,QAAQ,SAA+B;AAAA,MACtD,SAAS,YAAY;AACnB,eAAO,EAAE,MAAM,KAAA;AAAA,MACjB;AAAA,MACA,gBAAgB,OAAO,EAAE,MAAM,EAAE,eAAe;AAC9C,gCAAwB,KAAK,EAAE;AAC/B,iBAAS,WAAW,UAAU,wBAAwB,SAAS,QAAW,EAAE,cAAc,KAAA,CAAM,CAAC;AAAA,MACnG;AAAA,IAAA,CACD;AAAA,IAED,yBAAyB,QAAQ,MAAqC;AAAA,MACpE,SAAS,aAAa,EAAE,MAAM,wBAAwB,MAAA;AAAA,MACtD,mBAAmB,OAAO,GAAG,EAAE,UAAU,wBAAwB;AAC/D;AAAA,UACE,wBAAwB,UAAU,CAAC,UAAU;AAC3C;AAAA,cACE,WAAW,KAAK,gBAAgB,2BAA2B,QAAW,MAAM,MAAM,KAAK;AAAA,YAAA;AAAA,UAE3F,CAAC;AAAA,QAAA,EACD,KAAK,iBAAiB;AAAA,MAC1B;AAAA,IAAA,CACD;AAAA;AAAA;AAAA;AAAA,IAKD,oBAAoB,QAAQ,MAAmC;AAAA,MAC7D,SAAS,YAAY;AACnB,cAAM,UAAU,MAAM,WAAW,OAAO,aAAA;AACxC,eAAO,EAAE,MAAM,QAAA;AAAA,MACjB;AAAA,MACA,cAAc,CAAC,WAAW,QAAQ;AAAA,MAClC,mBAAmB,OAAO,GAAG,EAAE,mBAAmB,iBAAiB,uBAAuB;AACxF,cAAM;AAEN;AAAA,UACE,WAAW,OAAO;AAAA,YAChB;AAAA,YACA,CAAC,CAAC,QAAQ,KAAK,MACb,SACA,iBAAiB,CAAC,YAAY;AAC5B,sBAAQ,KAAK,MAAM;AAAA,YACrB,CAAC;AAAA,UAAA;AAAA,UAEL,WAAW,OAAO;AAAA,YAAU;AAAA,YAAgC,CAAC,CAAC,UAAU,SAAS,SAAS,MACxF,iBAAiB,CAAC,YAAY;AAC5B,oBAAM,SAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ;AACpD,kBAAI,CAAC,OAAQ;AAEb,qBAAO,cAAc;AAErB,kBAAI,cAAc,WAAW,MAAM;AACjC,uBAAO,oBAAoB,QAAQ;AAAA,cACrC;AAAA,YACF,CAAC;AAAA,UAAA;AAAA,UAEH,WAAW,OAAO;AAAA,YAAU;AAAA,YAAiC,CAAC,CAAC,UAAU,SAAS,MAChF,iBAAiB,CAAC,YAAY;AAC5B,oBAAM,SAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ;AACpD,kBAAI,CAAC,OAAQ;AAEb,qBAAO,oBAAoB;AAAA,YAC7B,CAAC;AAAA,UAAA;AAAA,UAEH,WAAW,OAAO;AAAA,YAAU;AAAA,YAAgC,CAAC,CAAC,MAAM,MAClE,iBAAiB,CAAC,YAAY;AAC5B,sBAAQ,KAAK,MAAM;AAAA,YACrB,CAAC;AAAA,UAAA;AAAA,UAEH,WAAW,OAAO;AAAA,YAAU;AAAA,YAAkC,CAAC,CAAC,EAAE,MAChE,iBAAiB,CAAC,YAAY;AAC5B,oBAAM,QAAQ,QAAQ,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE;AAClD,kBAAI,UAAU,GAAI,SAAQ,OAAO,OAAO,CAAC;AAAA,YAC3C,CAAC;AAAA,UAAA;AAAA,UAEH,WAAW,OAAO;AAAA,YAAU;AAAA,YAA4B,CAAC,CAAC,UAAU,UAAU,MAC5E,iBAAiB,CAAC,YAAY;AAC5B,oBAAM,SAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ;AACpD,kBAAI,CAAC,OAAQ;AAEb,qBAAO,OAAO;AAAA,YAChB,CAAC;AAAA,UAAA;AAAA,QACH,EACA,KAAK,iBAAiB;AAAA,MAC1B;AAAA,IAAA,CACD;AAAA,IAED,WAAW,QAAQ,MAA8B;AAAA,MAC/C,SAAS,OAAO,EAAE,SAAS;AACzB,cAAM,UAAU,MAAM,WAAW,OAAO,OAAO,EAAE;AACjD,eAAO,EAAE,MAAM,QAAA;AAAA,MACjB;AAAA,MACA,cAAc,CAAC,WAAW,QAAQ;AAAA,MAClC,mBAAmB,OAAO,EAAE,GAAA,GAAM,EAAE,mBAAmB,iBAAiB,uBAAuB;AAC7F,cAAM;AAEN;AAAA,UACE,WAAW,OAAO;AAAA,YAChB;AAAA,YACA,CAAC,CAAC,UAAU,SAAS,MACnB,OAAO,YACP,iBAAiB,CAAC,MAAM;AACtB,gBAAE,oBAAoB;AAAA,YACxB,CAAC;AAAA,UAAA;AAAA,UAEL,WAAW,OAAO;AAAA,YAChB;AAAA,YACA,CAAC,CAAC,UAAU,SAAS,SAAS,MAC5B,OAAO,YACP,iBAAiB,CAAC,WAAW;AAC3B,qBAAO,gBAAgB,QAAQ;AAC/B,qBAAO,oBACL,cAAc,WAAW,OAAO,QAAQ,KAAK,OAAO;AAAA,YACxD,CAAC;AAAA,UAAA;AAAA,UAEL,WAAW,OAAO;AAAA,YAChB;AAAA,YACA,CAAC,CAAC,cAAc,MACd,OAAO,eAAe,MACtB,iBAAiB,CAAC,WAAW;;AAC3B,qBAAO,QAAQ;AACf,qBAAO,kBAAgB,oBAAe,gBAAf,mBAA4B,OAAM;AACzD,qBAAO,oBAAoB,eAAe,qBAAqB;AAAA,YACjE,CAAC;AAAA,UAAA;AAAA,UAEL,WAAW,OAAO;AAAA,YAChB;AAAA,YACA,CAAC,CAAC,QAAQ,MACR,OAAO,YACP,iBAAiB,CAAC,WAAW;AAC3B,qBAAO,QAAQ;AAAA,YACjB,CAAC;AAAA,UAAA;AAAA,UAEL,WAAW,OAAO;AAAA,YAChB;AAAA,YACA,CAAC,CAAC,UAAU,UAAU,MACpB,OAAO,YACP,iBAAiB,CAAC,WAAW;AAC3B,qBAAO,OAAO;AAAA,YAChB,CAAC;AAAA,UAAA;AAAA,QACL,EACA,KAAK,iBAAiB;AAAA,MAC1B;AAAA,IAAA,CACD;AAAA,IAED,aAAa,QAAQ,SAA+C;AAAA,MAClE,SAAS,OAAO,EAAE,IAAI,YAAY;AAChC,cAAM,WAAW,OAAO,YAAY,IAAI,KAAK;AAC7C,eAAO,EAAE,MAAM,KAAA;AAAA,MACjB;AAAA,IAAA,CACD;AAAA;AAAA;AAAA;AAAA,IAMD,sBAAsB,QAAQ,MAA+C;AAAA,MAC3E,SAAS,OAAO,SAAS;AACvB,cAAM,cAAc;AAAA,UAClB,MAAM;AAAA,UACN,MAAM,4BAA4B;AAAA,UAClC,GAAG;AAAA,QAAA;AAEL,cAAM,WAAW,MAAM,WAAW,OAAO,eAAe,WAAW;AACnE,eAAO;AAAA,UACL,MAAM;AAAA,YACJ,UAAU,SAAS,MAAM,GAAG,yBAAyB;AAAA,YACrD,SAAS,SAAS,WAAW,4BAA4B;AAAA,UAAA;AAAA,QAC3D;AAAA,MAEJ;AAAA,MACA,cAAc,CAAC,WAAW,UAAU,gBAAgB;AAAA,MACpD,mBAAmB,OAAO,EAAE,SAAA,GAAY,EAAE,mBAAmB,iBAAiB,uBAAuB;AACnG,cAAM;AAEN;AAAA,UACE,WAAW,OAAO,UAAU,gCAAgC,CAAC,CAAC,WAAW,OAAO,MAAM;AACpF,yBAAa,aACX,iBAAiB,CAAC,gBAAgB;AAChC,eAAC,YAAY,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ,EAAE,KACnD,YAAY,SAAS,QAAQ,OAAO;AAAA,YACxC,CAAC;AAAA,UACL,CAAC;AAAA,QAAA,EACD,KAAK,iBAAiB;AAAA,MAC1B;AAAA,IAAA,CACD;AAAA,IAED,4BAA4B,QAAQ,SAAqC;AAAA,MACvE,SAAS,OAAO,EAAE,YAAY,EAAE,eAAe;AAC7C,cAAM,UAAU,WAAW,UAAU,qBAAqB,OAAO,EAAE,SAAA,CAAU,EAAE,UAAiB;AAChG,cAAM,WAAW,MAAM,WAAW,OAAO,eAAe;AAAA,UACtD;AAAA,UACA,MAAM,QAAQ,KAAM,SAAS;AAAA,UAC7B,MAAM,4BAA4B;AAAA,QAAA,CACnC;AACD,eAAO;AAAA,UACL,MAAM;AAAA,UACN,MAAM;AAAA,YACJ,UAAU,SAAS,MAAM,GAAG,yBAAyB;AAAA,YACrD,SAAS,SAAS,WAAW,4BAA4B;AAAA,UAAA;AAAA,QAC3D;AAAA,MAEJ;AAAA,MACA,gBAAgB,OAAO,EAAE,SAAA,GAAY,EAAE,UAAU,qBAAqB;AACpE,cAAM,SAAS,MAAM;AACrB,cAAM,OAA0B,OAAO;AAEvC;AAAA,UACE,WAAW,KAAK,gBAAgB,wBAAwB,EAAE,SAAA,GAAY,CAAC,UAAU;AAC/E,kBAAM,UAAU,KAAK;AACrB,kBAAM,SAAS,KAAK,GAAG,KAAM,QAAQ;AAAA,UACvC,CAAC;AAAA,QAAA;AAAA,MAEL;AAAA,IAAA,CACD;AAAA,IAED,mBAAmB,QAAQ,SAA2C;AAAA,MACpE,SAAS,OAAO,SAAS;AACvB,cAAM,KAAK,MAAM,WAAW,OAAO,kBAAkB,IAAI;AACzD,eAAO,EAAE,MAAM,GAAA;AAAA,MACjB;AAAA,IAAA,CACD;AAAA,IAED,mBAAmB,QAAQ,SAA+B;AAAA,MACxD,SAAS,YAAY;AACnB,eAAO,EAAE,MAAM,KAAA;AAAA,MACjB;AAAA,MACA,gBAAgB,OAAO,EAAE,MAAM,EAAE,eAAe;AAC9C,kCAA0B,KAAK,EAAE;AACjC,iBAAS,WAAW,UAAU,0BAA0B,SAAS,QAAW,EAAE,cAAc,KAAA,CAAM,CAAC;AAAA,MACrG;AAAA,IAAA,CACD;AAAA,IAED,2BAA2B,QAAQ,MAAqC;AAAA,MACtE,SAAS,aAAa,EAAE,MAAM,0BAA0B,MAAA;AAAA,MACxD,mBAAmB,OAAO,GAAG,EAAE,UAAU,wBAAwB;AAC/D;AAAA,UACE,0BAA0B,UAAU,CAAC,UAAU;AAC7C;AAAA,cACE,WAAW,KAAK,gBAAgB,6BAA6B,QAAW,MAAM,MAAM,KAAK;AAAA,YAAA;AAAA,UAE7F,CAAC;AAAA,QAAA,EACD,KAAK,iBAAiB;AAAA,MAC1B;AAAA,IAAA,CACD;AAAA,EAAA;AAEL,CAAC;AAEM,SAAS,gBAAgB,IAAmB;AACjD,SAAO;AAAA,IAAY,CAAC,UAAA;;AAClB,mBAAM,QACF,kBAAa,UAAU,YACpB,OAAA,EAAS,KAAK,EACd,SAFH,mBAES,KAAK,CAAC,MAAM,EAAE,OAAO,MAC9B;AAAA;AAAA,EAAA;AAER;AAEO,SAAS,8BAA8B;AAC5C,QAAM,EAAE,MAAM,SAAS,GAAG,MAAA,IAAU,WAAW,2BAAA;AAC/C,QAAM,QAAQ,QAAQ,MAAO,WAAW,OAAO,0BAA0B,OAAO,IAAI,MAAO,CAAC,OAAO,CAAC;AACpG,SAAO,CAAC,OAAO,KAAK;AACtB;AAQO,MAAM,aAAyB,OAAO,OAAO,cAAc;AAAA,EAChE,UAAU;AAAA,EACV;AAAA,EACA;AACF,CAAC;ACzpBD,MAAM,UAA2B;AAAA,EAC/B,CAAC,OAAoBF,gBAA8C;AACjE,UAAM,EAAE,YAAY;AAEpB,+BAAQG,UAAA,EAAW,KAAKH,aAAY,KAAK,QAAQ,QAAQ;AAAA,EAC3D;AACF;AAEA,QAAQ,cAAc;AAEf,MAAM,SAAS,UAAU,UAAU,OAAO;ACkD1C,MAAM,mBAAmB,MAAM,cAAyB,IAAK;AAE7D,SAAS,eAAe;AAC7B,SAAO,WAAW,gBAAgB;AACpC;AAEA,MAAM,OAAsB;AAAA,EAC1B,SAAS,CAAC,UAAkB,MAAM,KAAK,EAAE,OAAO,MAAA,GAAS,KAAK;AAAA,EAC9D,WAAW,CAAC,UAAkB,MAAM,KAAK,EAAE,OAAO,OAAO;AAAA,EACzD,UAAU,CAAC,UAAkB,MAAM,KAAK,EAAE,OAAO,kBAAkB;AAAA,EACnE,SAAS;AAAA,IACP,MAAM,MAAM;AAAA,IACZ,SAAS,MAAM;AAAA,IACf,SAAS,MAAM;AAAA,EAAA;AAAA,EAEjB,SAAS;AAAA,IACP,OAAO,MAAM;AAAA,IACb,MAAM;AAAA,MACJ,OAAO,MAAM;AAAA,MACb,UAAU,MAAM;AAAA,MAChB,QAAQ,MAAM;AAAA,IAAA;AAAA,IAEhB,SAAS;AAAA,MACP,OAAO,MAAM;AAAA,MACb,UAAU,MAAM;AAAA,IAAA;AAAA,IAElB,WAAW,MAAM;AAAA,EAAA;AAAA,EAEnB,QAAQ;AAAA,IACN,0BAA0B,MAAM;AAAA,IAChC,0BAA0B,MAAM;AAAA,IAChC,4BAA4B,MAAM;AAAA,IAClC,+BAA+B,CAAC,GAAG,EAAE,QAAA,MACnC,yBAAyB,OAAO;AAAA,EAAA;AAAA,EAGpC,OAAO;AAAA,IACL,aAAa,CAAC,SACZ,SAAS,YACL,+EACA;AAAA,EAAA;AAAA,EAGR,UAAU;AAAA,IACR,SAAS,MAAM;AAAA,EAAA;AAAA,EAGjB,MAAM;AAAA,IACJ,OAAO,CAAC,UACN,GAAG,MAAM,eAAe,QAAW,EAAE,uBAAuB,GAAG,uBAAuB,EAAA,CAAG,CAAC;AAAA,IAC5F,IAAI,CAAC,UACH,GAAG,MAAM,eAAe,QAAW,EAAE,uBAAuB,GAAG,uBAAuB,EAAA,CAAG,CAAC;AAAA,IAC5F,IAAI,CAAC,UACH,GAAG,MAAM,eAAe,QAAW,EAAE,uBAAuB,GAAG,uBAAuB,EAAA,CAAG,CAAC;AAAA,EAAA;AAAA,EAG9F,UAAU;AAAA,IACR,UAAU,CAAC,UAAkB,iBAAiB,KAAK,QAAQ,UAAU,IAAI,MAAM,EAAE;AAAA,EAAA;AAAA,EAGnF,SAAS;AAAA,IACP,OAAO,CAAC,aAAqB,cAAc,QAAQ;AAAA,EAAA;AAAA,EAGrD,WAAW;AAAA,IACT,aAAa,MAAM;AAAA,IACnB,OAAO,MAAM;AAAA,IACb,QAAQ;AAAA,MACN,OAAO,MAAM;AAAA,MACb,UAAU,MAAM;AAAA,MAChB,QAAQ,MAAM;AAAA,IAAA;AAAA,IAEhB,MAAM,EAAE,OAAO,MAAM,WAAW,UAAU,MAAM,uBAAA;AAAA,IAChD,WAAW,MAAM;AAAA,IACjB,UAAU,MAAM;AAAA,EAAA;AAEpB;AAEO,MAAM,mBAA8B;ACpI3C,SAAS,OAAOE,SAAgB,WAAmB,aAAsB;AACvE,QAAM,CAAC,KAAK,KAAK,IAAI,WAAW,yBAAA;AAChC,QAAM,QAAQ;AAAA,IACZ,MAAM,IAAI,EAAE,QAAAA,SAAQ,WAAW,aAAa;AAAA,IAC5C,CAAC,KAAKA,SAAQ,WAAW,WAAW;AAAA,EAAA;AAEtC,SAAO,CAAC,OAAO,KAAK;AACtB;AAEA,SAAS,UAAUA,SAAgB,WAAmB,eAAwB;AAC5E,QAAM,CAAC,QAAQ,KAAK,IAAI,WAAW,4BAAA;AACnC,QAAM,WAAW;AAAA,IACf,MAAM,OAAO,EAAE,QAAAA,SAAQ,WAAW,eAAe;AAAA,IACjD,CAAC,QAAQA,SAAQ,WAAW,aAAa;AAAA,EAAA;AAE3C,SAAO,CAAC,UAAU,KAAK;AACzB;AAEA,MAAM,qBAAqB,UAAU,sBAAsB,CAAC,UAAmC;AAC7F,QAAM,EAAE,QAAAA,YAAW;AACnB,QAAM,EAAE,MAAM,SAAS,WAAW,gBAAgB,EAAE,IAAIA,SAAQ;AAChE,QAAM,EAAE,MAAM,SAAA,IAAa,WAAW,uBAAuB,CAAA,CAAE;AAC/D,QAAM,UAAU,SAAU,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,EAAE;AACvD,QAAM,WAAW,KAAM,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ,EAAE;AAC9D,QAAM,CAAC,mBAAmB,IAAI,OAAOA,SAAQ,QAAQ,IAAI,KAAK;AAC9D,QAAM,CAAC,gBAAgB,IAAI,OAAOA,SAAQ,QAAQ,IAAI,IAAI;AAC1D,QAAM,CAAC,mBAAmB,IAAI,UAAUA,SAAQ,QAAQ,IAAI,KAAK;AACjE,QAAM,CAAC,qBAAqB,IAAI,UAAUA,SAAQ,QAAQ,IAAI,IAAI;AAElE,SACE;AAAA,IAAC,KAAK;AAAA,IAAL;AAAA,MACC,WAAU;AAAA,MACV,SACE,WACI;AAAA,4BACG,SAAA,EAAqB,OAAM,yBAC1B,UAAA,oBAAC,UAAO,SAAS,qBAAqB,MAAK,QAAO,MAAM,oBAAC,MAAA,EAAK,MAAK,iBAAgB,EAAA,CAAI,KAD5E,QAEb;AAAA,QACA,oBAAC,SAAA,EAAoC,OAAM,2BACzC,UAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS;AAAA,YACT,MAAK;AAAA,YACL,MAAM,oBAAC,MAAA,EAAK,MAAK,+BAAA,CAA+B;AAAA,UAAA;AAAA,QAAA,KAJvC,uBAMb;AAAA,MAAA,IAEF;AAAA,4BACG,SAAA,EAA6B,OAAM,oBAClC,UAAA,oBAAC,UAAO,SAAS,qBAAqB,MAAK,QAAO,MAAM,oBAAC,MAAA,EAAK,MAAK,cAAa,EAAA,CAAI,KADzE,gBAEb;AAAA,QACA,oBAAC,SAAA,EAAkB,OAAM,uBACvB,UAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS;AAAA,YACT,MAAK;AAAA,YACL,MAAM,oBAAC,MAAA,EAAK,MAAK,0BAAA,CAA0B;AAAA,UAAA;AAAA,QAAA,KAJlC,KAMb;AAAA,MAAA;AAAA,MAIR,+BAAC,OAAA,EACC,UAAA;AAAA,QAAA,oBAAC,UAAO,SAAkB;AAAA,QAC1B,oBAAC,QAAA,EAAM,UAAA,QAAQ,KAAA,CAAK;AAAA,MAAA,EAAA,CACtB;AAAA,IAAA;AAAA,EAAA;AAGN,CAAC;AAEM,MAAM,mBAAmB,UAAU,oBAAoB,MAAM;AAClE,QAAM,EAAE,IAAI,SAAS,cAAA,IAAkB,eAAA;AACvC,QAAM,YAAY,aAAA;AAClB,QAAM,EAAE,MAAM,KAAA,IAAS,WAAW,gBAAgB,EAAE,IAAI;AACxD,QAAM,EAAE,MAAM,SAAA,IAAa,WAAW,uBAAuB,CAAA,CAAE;AAE/D,QAAM,UAAU;AAAA,IACd,MACE,qCACI,QACD;AAAA,MACC,CAAC,GAAG,QACD,6BAAM,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAM,OAAO,OAClD,6BAAM,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAM,OAAO,KACnD,EAAE,KAAK,cAAc,EAAE,IAAI;AAAA;AAAA,IAEnC,CAAC,UAAU,IAAI;AAAA,EAAA;AAGjB,MAAI,EAAC,6BAAM,YAAW,CAAC,UAAU;AAC/B,WAAO;AAAA,EACT;AAEA,SACE,qBAAC,OAAA,EAAI,WAAU,6BACZ,UAAA;AAAA,IAAA,WACC,oBAAC,OAAA,EAAI,WAAU,oCACb,UAAA,qBAAC,KAAA,EAAI,MAAM,OAAO,OAAM,UAAS,QAAQ,IACvC,UAAA;AAAA,MAAA,oBAAC,OAAI,MAAK,QACR,UAAA,oBAAC,QAAA,EAAO,MAAK,QAAO,MAAM,oBAAC,cAAA,CAAA,CAAa,GAAI,SAAS,MAAM,cAAc,KAAK,GAAG,GACnF;AAAA,MACA,oBAAC,KAAA,EACC,UAAA,oBAAC,QAAA,EAAK,WAAU,mCAAmC,UAAA,UAAU,QAAQ,MAAM,KAAK,IAAI,EAAA,CAAE,EAAA,CACxF;AAAA,IAAA,EAAA,CACF,EAAA,CACF;AAAA,IAEF;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,YAAY;AAAA,QACZ,YAAY,CAAC,SAAS,oBAAC,sBAAmB,IAAI,KAAK,IAAI,QAAQ,GAAA,CAAI;AAAA,MAAA;AAAA,IAAA;AAAA,EACrE,GACF;AAEJ,CAAC;ACxHM,MAAM,qBAAqB,UAAU,sBAAsB,MAAM;AACtE,QAAM,EAAE,GAAA,IAAO,eAAA;AACf,QAAM,EAAE,MAAM,KAAA,IAAS,WAAW,gBAAgB,EAAE,IAAI;AAExD,MAAI,EAAC,6BAAM,UAAS;AAClB,WAAO;AAAA,EACT;AAEA,SACE,oBAACC,SAAW,OAAX,EAAiB,KAAK,EAAE,OAAO,EAAA,GAC7B,UAAA,KAAK,QAAQ,IAAI,CAAC,MACjB,oBAAC,SAAA,EAAmB,OAAO,EAAE,MAC3B,UAAA,oBAAC,QAAA,EAAO,SAAS,EAAA,CAAG,EAAA,GADR,EAAE,EAEhB,CACD,EAAA,CACH;AAEJ,CAAC;ACTM,MAAM,kBAAkB,UAAU,mBAAmB,CAAC,UAA8B;AACzF,QAAM,EAAE,UAAU,cAAc,QAAQ,SAAS,OAAO,aAAa;AACrE,QAAM,WAAW,OAAgC,IAAI;AACrD,QAAM,UAAU,YAAY,MAAA;;AAAM,0BAAS,YAAT,mBAAkB;AAAA,KAAS,EAAE;AAC/D,QAAM,iBAAiB,OAAiC,IAAI;AAE5D,YAAU,MAAM;;AACd,yBAAe,YAAf,mBAAwB,UAAU,IAAI;AAAA,EACxC,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,4BAA4B,YAAY,MAAM;;AAClD,yBAAe,YAAf,mBAAwB,UAAU,OAAO;AAAA,EAC3C,GAAG,CAAA,CAAE;AAEL,QAAM,gBAAgB;AAAA,IACpB,CAAC,MAA2C;AAC1C,YAAM,QAAQ,EAAE,OAAO;AACvB,eAAS,MAAM,SAAS,KAAK,SAAS,MAAM,KAAK,KAAK,CAAC;AAAA,IACzD;AAAA,IACA,CAAC,QAAQ;AAAA,EAAA;AAGX,SACE,qBAAA,UAAA,EACE,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,MAAK;AAAA,QACL;AAAA,QACA,MAAM,oBAAC,MAAA,EAAK,MAAK,SAAA,CAAS;AAAA,QAC1B,WAAU;AAAA,MAAA;AAAA,IAAA;AAAA,IAEX,MAAM,SAAS,KACd;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAK;AAAA,QACL,WAAU;AAAA,QACV,sBAAsB;AAAA,QACtB,SAAS;AAAA,QACT,MAAK;AAAA,QACL;AAAA,QACA,MAAM,qBAAA,UAAA,EAAE,UAAA;AAAA,UAAA;AAAA,UAAE,MAAM;AAAA,QAAA,EAAA,CAAO;AAAA,MAAA;AAAA,IAAA;AAAA,IAG3B;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,OAAM;AAAA,QACN;AAAA,QACA,UAAU;AAAA,QACV,KAAK;AAAA,QACL,MAAK;AAAA,QACL,UAAQ;AAAA,QACR,OAAO,EAAE,SAAS,OAAA;AAAA,MAAO;AAAA,IAAA;AAAA,EAC3B,GACF;AAEJ,CAAC;AAEM,MAAM,gBAAgB,UAAU,iBAAiB,CAAC,UAA8B;AACrF,SACE,oBAAC,SAAI,WAAU,wBACb,8BAAC,iBAAA,EAAiB,GAAG,OAAO,EAAA,CAC9B;AAEJ,CAAC;ACnDM,MAAM,sBAAsB,MAAM,cAAwC,MAAU;AAEpF,SAASC,oBAAkB;AAChC,SAAO,MAAM,WAAW,mBAAmB;AAC7C;ACdA,MAAMC,YAAU,SAAS,OAAO;AAChC,MAAM,cAAc,SAAS,YAAY;AAEzC,MAAM,YAAuC,EAAE,SAAS,GAAG,SAAS,EAAA;AAE7D,MAAM,eAAe;AAAA,EAC1B;AAAA,EACA,KAAK,CAAC,UAA6B;AACjC,UAAM,EAAE,OAAO,UAAU,QAAQ,UAAU,aAAa;AACxD,UAAM,YAAY,aAAA;AAClB,UAAM,EAAE,QAAA,IAAYD,kBAAA;AAEpB,UAAM,gBAAgB;AAAA,MACpB,CAAC,MAA8C,SAAS,EAAE,OAAO,KAAK;AAAA,MACtE,CAAC,QAAQ;AAAA,IAAA;AAGX,UAAM,YAAY;AAAA,MAChB,CAAC,MAAgD;AAC/C,YAAI,UAAU;AACZ,YAAE,eAAA;AACF;AAAA,QACF;AAEA,YAAIC,UAAQ,CAAC,KAAK,YAAY,CAAC,GAAG;AAChC,YAAE,eAAA;AACF,iBAAO,KAAK;AAAA,QACd;AAAA,MACF;AAAA,MACA,CAAC,QAAQ,OAAO,QAAQ;AAAA,IAAA;AAG1B,WACE,oBAAC,OAAA,EAAI,WAAU,yBACb,UAAA;AAAA,MAAC,MAAM;AAAA,MAAN;AAAA,QACC,KAAK;AAAA,QACL;AAAA,QACA,UAAU;AAAA,QACV,UAAU;AAAA,QACV,WAAU;AAAA,QACV,aAAa,UAAU,MAAM,YAAY,UAAU,YAAY,SAAS;AAAA,QACxE;AAAA,MAAA;AAAA,IAAA,GAEJ;AAAA,EAEJ,CAAC;AACH;ACpDO,MAAM,uBAAuB,UAAU,wBAAwB,CAAC,UAAqC;AAC1G,QAAM,EAAE,UAAU,UAAU,QAAA,IAAY;AAExC,SACE,oBAAC,OAAA,EAAI,WAAU,yBACb,UAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,SAAS;AAAA,MACT,MAAK;AAAA,MACL,MAAM,oBAAC,MAAA,EAAK,MAAK,OAAA,CAAO;AAAA,MACxB,WAAU;AAAA,MACV;AAAA,MACA;AAAA,IAAA;AAAA,EAAA,GAEJ;AAEJ,CAAC;AClBM,MAAM,kBAAkB,UAAU,mBAAmB,CAAC,UAAgC;AAC3F,QAAM,EAAE,QAAQ,EAAA,IAAM;AACtB,SACE,oBAAA,UAAA,EACG,UAAA,MAAM,KAAK,MAAM,KAAK,CAAC,EAAE,IAAI,CAAC,GAAG,UAChC,qBAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,IAAA,oBAAC,SAAS,QAAT,EAAgB,WAAU,iBAAgB,QAAM,MAAC;AAAA,wBACjD,SAAS,QAAT,EAAgB,QAAM,MAAC,WAAU,iBAAA,CAAiB;AAAA,EAAA,KAFP,KAG9C,CACD,GACH;AAEJ,CAAC;AChBM,MAAM,mBAAmB,UAAU,oBAAoB,CAAC,UAAgC;AAC7F,QAAM,EAAE,SAAS;AAEjB,SAAO,oBAAC,OAAA,EAAI,WAAU,oBAAoB,eAAK,MAAK;AACtD,CAAC;ACJM,MAAM,0BAA0B,UAAU,2BAA2B,CAAC,UAAgC;AAC3G,QAAM,EAAE,kBAAkB,YAAA,IAAgB,MAAM;AAEhD,MAAI,eAAe,QAAQ,eAAe,GAAG;AAC3C,WAAO;AAAA,EACT;AAEA,SAAO,oBAAC,OAAA,EAAI,WAAU,uBAAuB,UAAA,aAAY;AAC3D,CAAC;ACDM,SAAS,oBAAoB,WAAsB,MAA+B;AACvF,QAAM,CAAC,KAAK,OAAO,IAAI,KAAK,MAAM,MAAM,CAAC;AACzC,QAAM,OAAO,UAAU,KAAK,MAAM,OAAO,IAAI;AAC7C,SAAO,UAAU,OAAO,GAAgC,EAAE,KAAY,IAAI;AAC5E;AAEO,MAAM,mBAAmB,UAAU,oBAAoB,CAAC,UAAiC;AAC9F,QAAM,EAAE,SAAS,aAAA,IAAiB;AAClC,QAAM,EAAE,MAAM,OAAA,IAAW;AACzB,QAAM,YAAY,aAAA;AAElB,SACE,qBAAC,OAAA,EAAI,KAAK,cAAc,WAAU,yBAChC,UAAA;AAAA,IAAA,oBAAC,SAAI,WAAU,eAAe,kBAAQ,oBAAoB,WAAW,IAAI,GAAE;AAAA,wBAC1E,OAAA,EAAI,WAAU,oBAAoB,UAAA,UAAU,UAAU,MAAM,EAAA,CAAE;AAAA,EAAA,GACjE;AAEJ,CAAC;ACpBD,MAAM,WAAyC,CAAC,UAAU;AACxD,QAAM,EAAE,SAAS,WAAA,IAAe;AAChC,QAAM,EAAE,QAAQ,kBAAA,IAAsBD,kBAAA;AACtC,QAAM,SAAS,qBAAqB,QAAQ,QAAQ,GAAG,cAAc,iBAAiB,KAAK;AAC3F,QAAM,UAAU,OAAO,MAAM;AAE7B,YAAU,MAAM;AACd,YAAQ,UAAU,QAAQ,WAAW;AAAA,EACvC,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,WAAW;AAAA,IACf,MACE,IAAI,qBAAqB,CAAC,CAAC,KAAK,MAAM;AACpC,UAAI,MAAM,kBAAkB,CAAC,QAAQ,SAAS;AAC5C,gBAAQ,UAAU;AAClB,yCAAS,QAAQ;AAAA,MACnB;AAAA,IACF,CAAC;AAAA;AAAA,IAGH,CAAA;AAAA,EAAC;AAGH,YAAU,MAAM;AACd,aAAS,QAAQ,WAAW,OAAQ;AACpC,WAAO,MAAM,SAAS,WAAA;AAAA,EAGxB,GAAG,CAAC,QAAQ,CAAC;AAEb,SAAO,oBAAA,UAAA,EAAE;AACX;AAEO,SAAS,oBAAoB,OAAiC;AACnE,QAAM,EAAE,eAAA,IAAmBA,kBAAA;AAE3B,MAAI,mBAAmB,MAAM;AAC3B,WAAO;AAAA,EACT;AAEA,SAAO,oBAAC,UAAA,EAAU,GAAG,MAAA,CAAO;AAC9B;ACtCO,MAAM,mBAAmB,UAAU,oBAAoB,CAAC,UAAiC;AAC9F,QAAM,MAAM,OAA8B,IAAI;AAE9C,SACE,qBAAA,UAAA,EACE,UAAA;AAAA,IAAA,oBAAC,qBAAA,EAAoB,YAAY,KAAM,GAAG,MAAA,CAAO;AAAA,IACjD,oBAAC,kBAAA,EAAiB,cAAc,KAAM,GAAG,MAAA,CAAO;AAAA,EAAA,GAClD;AAEJ,CAAC;ACbM,MAAM,iCAAiC;AAAA,EAC5C;AAAA,EACA,CAAC,UAAU;AACT,UAAM,EAAE,gBAAgB,MAAM;AAC9B,UAAM,YAAY,aAAA;AAElB,+BACG,OAAA,EAAI,WAAU,4BACZ,UAAA,YAAY,OAAO,OAAO,oBACvB,YAAY,QAAQ,oBAAoB,WAAW,YAAY,IAAI,IACnE,YAAY,MAClB;AAAA,EAEJ;AACF;ACjBO,MAAM,gCAAgC;AAAA,EAC3C;AAAA,EACA,CAAC,UAAgC;AAC/B,UAAM,EAAE,gBAAgB,MAAM;AAE9B,QAAI,YAAY,OAAO,OAAO,mBAAmB;AAC/C,aAAO;AAAA,IACT;AAEA,+BAAQ,OAAA,EAAI,WAAU,2BAA2B,UAAA,YAAY,OAAO,MAAK;AAAA,EAC3E;AACF;ACVO,MAAM,gCAAgC;AAAA,EAC3C;AAAA,EACA,CAAC,UAAgC;AAC/B,UAAM;AAAA,MACJ,MAAM;AAAA,QACJ,aAAa,EAAE,OAAA;AAAA,MAAO;AAAA,IACxB,IACE;AAEJ,UAAM,YAAY,aAAA;AAElB,WACE,oBAAC,OAAA,EAAI,WAAU,4BACZ,oBAAU,QAAQ,MAAM,IAAI,UAAU,UAAU,MAAM,IAAI,UAAU,SAAS,MAAM,GACtF;AAAA,EAEJ;AACF;ACfO,MAAM,0BAA0B,UAAU,2BAA2B,CAAC,UAAgC;AAC3G,SACE,qBAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,IAAA,oBAAC,+BAAA,EAA+B,GAAG,OAAO;AAAA,IAC1C,oBAAC,gCAAA,EAAgC,GAAG,OAAO;AAAA,IAC3C,oBAAC,+BAAA,EAA+B,GAAG,MAAA,CAAO;AAAA,EAAA,GAC5C;AAEJ,CAAC;ACTM,MAAM,qBAAqB,UAAU,sBAAsB,CAAC,UAAgC;AACjG,QAAM,EAAE,OAAO,MAAM;AAErB,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,OACE;AAAA,QACE,sBAAsB,MAAM,IAAI,EAAE,WAAW,IAAI;AAAA,QACjD,WAAW,MAAM,IAAI,EAAE,YAAY,IAAI,WAAW,IAAI;AAAA,MAAA;AAAA,MAI1D,UAAA,oBAAC,MAAA,EAAK,MAAK,OAAA,CAAO;AAAA,IAAA;AAAA,EAAA;AAGxB,CAAC;ACLM,MAAM,kBAAkB,UAAU,mBAAmB,CAAC,UAAgC;AAC3F,QAAM,EAAE,SAAS,MAAA,IAAU;AAC3B,QAAM,EAAE,aAAa,kBAAA,IAAsB,MAAM;AACjD,QAAM,OAAO,qBAAqB,QAAQ,kBAAkB,cAAc,YAAY,EAAE,KAAK;AAE7F,SACE,qBAAC,SAAI,WAAW,iBAAiB,CAAC,QAAQ,CAAC,SAAS,cAAc,KAChE,UAAA;AAAA,IAAA,oBAAC,oBAAA,EAAoB,GAAG,OAAO;AAAA,IAC/B,qBAAC,QAAA,EAAK,WAAU,oBACd,UAAA;AAAA,MAAA,oBAAC,kBAAA,EAAkB,GAAG,OAAO;AAAA,MAC7B,oBAAC,yBAAA,EAAyB,GAAG,OAAO;AAAA,MACpC,oBAAC,yBAAA,EAAyB,GAAG,MAAA,CAAO;AAAA,IAAA,EAAA,CACtC;AAAA,EAAA,GACF;AAEJ,CAAC;ACND,SAAS,YAAY,OAAsB;AACzC,QAAM,EAAE,aAAa;AAErB,SAAO;AAAA,IACL,MACE,WACI,CAAC,SAA4D,SAAS,KAAK,GAAa,IACxF;AAAA,IACN,CAAC,QAAQ;AAAA,EAAA;AAEb;AAEA,SAAS,aAAa,OAAsB;AAC1C,QAAM,EAAE,OAAO,QAAQ,IAAA,IAAQ;AAC/B,QAAM,YAAY,aAAA;AAElB,SAAO,QAA4B,MAAM;AACvC,UAAM,SAAS,+BACX,QACD;AAAA,MACC,CAAC,GAAG,MAAM,CAAC,oBAAoB,EAAE,YAAY,EAAE,EAAE,cAAc,oBAAoB,EAAE,YAAY,EAAE,CAAC;AAAA,MAErG,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,2BAAQ,iBAAA,EAAgB,MAAM,GAAG,OAAA,CAAgB;AAE7E,QAAI,OAAO,MAAM;AACf,aAAO;AAAA,QACL,GAAG;AAAA,QACH;AAAA,UACE,MAAM;AAAA,UACN,KAAK;AAAA,UACL,UAAU;AAAA,UACV,OACE,oBAAC,OAAA,EAAI,OAAO,EAAE,WAAW,UAAU,QAAQ,QAAQ,WAAW,YAC3D,UAAA,UAAU,SAAS,SAAS,GAAG,EAAA,CAClC;AAAA,QAAA;AAAA,MAEJ;AAAA,IAEJ;AAEA,WAAO;AAAA,EACT,GAAG,CAAC,OAAO,QAAQ,KAAK,SAAS,CAAC;AACpC;AAEO,MAAM,WAAW,UAAU,YAAY,CAAC,UAAyB;AACtE,QAAM,EAAE,UAAU,eAAA,IAAmB;AACrC,QAAM,WAAW,QAAQ,MAAO,iBAAiB,CAAC,cAAc,IAAI,CAAA,GAAK,CAAC,cAAc,CAAC;AACzF,QAAM,WAAW,YAAY,KAAK;AAClC,QAAM,QAAQ,aAAa,KAAK;AAEhC,SACE,oBAAA,UAAA,EACG,UAAA,SACC,oBAAC,MAAA,EAAK,WAAU,oBAAmB,cAAc,UAAU,UAAoB,MAAA,CAAc,GAEjG;AAEJ,CAAC;AChFM,SAAS,eAAe;AAC7B,QAAM,YAAY,aAAA;AAElB,SAAO;AAAA,IACL,MAAM,CAAC,UAAkB;AACvB,UAAI,QAAQ,MAAM;AAChB,eAAO,UAAU,KAAK,MAAM,KAAK;AAAA,MACnC,WAAW,QAAQ,OAAO,MAAM;AAC9B,eAAO,UAAU,KAAK,GAAG,QAAQ,IAAI;AAAA,MACvC,OAAO;AACL,eAAO,UAAU,KAAK,GAAG,QAAQ,OAAO,IAAI;AAAA,MAC9C;AAAA,IACF;AAAA,EAAA;AAEJ;ACHO,MAAM,eAAe,UAAU,gBAAgB,CAAC,UAA6B;AAClF,QAAM,EAAE,MAAM,UAAU,SAAA,IAAa;AACrC,QAAM,YAAY,aAAA;AAClB,QAAM,gBAAgB,YAAY,MAAM,SAAS,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC;AAExE,SACE,qBAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,IAAA,qBAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,MAAA,oBAAC,SAAI,WAAU,oBAAmB,OAAO,KAAK,MAC3C,eAAK,KAAA,CACR;AAAA,MACA,oBAAC,SAAI,WAAU,oBAAoB,oBAAU,KAAK,KAAK,KAAK,EAAA,CAAE;AAAA,IAAA,GAChE;AAAA,IACA,oBAAC,OAAA,EAAI,WAAU,uBACb,UAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAU;AAAA,QACV,MAAK;AAAA,QACL,MAAM,oBAAC,MAAA,EAAK,MAAK,cAAA,CAAc;AAAA,QAC/B,SAAS;AAAA,MAAA;AAAA,IAAA,EACX,CACF;AAAA,EAAA,GACF;AAEJ,CAAC;AC3BM,MAAM,mBAAmB,UAAU,oBAAoB,CAAC,UAAiC;AAC9F,QAAM,EAAE,OAAO,UAAU,SAAA,IAAa;AAEtC,6BACG,OAAA,EAAI,WAAU,oBACZ,UAAA,MAAM,IAAI,CAAC,SACV,oBAAC,cAAA,EAA4B,MAAY,UAAoB,SAAA,GAA1C,KAAK,GAAyD,CAClF,GACH;AAEJ,CAAC;ACVD,SAAS,eAAe;AACtB,QAAM,EAAE,OAAA,IAAWA,kBAAA;AACnB,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,EAAE;AACnC,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAC5C,QAAM,EAAE,UAAU,OAAO,SAAS,UAAU,aAAa,aAAA,IAAiB,sBAAA;AAE1E,QAAM,WAAW,YAAY,MAAM;AACjC,QAAI,CAAC,QAAQ;AACX;AAAA,IACF;AAEA,UAAM,YAAY,KAAK,KAAA,EAAO,WAAW,IAAI,OAAO,KAAK,KAAA;AAEzD,QAAK,CAAC,aAAa,MAAM,WAAW,KAAM,SAAS;AACjD;AAAA,IACF;AAEA,eAAW,IAAI;AACf,YAAQ,QAAQ,OAAO,EAAE,MAAM,WAAW,OAAO,CAAC,EAC/C,QAAQ,MAAM,WAAW,KAAK,CAAC,EAC/B,KAAK,MAAM;AACV,eAAS,CAAA,CAAE;AACX,cAAQ,EAAE;AAAA,IACZ,CAAC;AAAA,EAEL,GAAG,CAAC,MAAM,QAAQ,OAAO,UAAU,OAAO,CAAC;AAE3C,SAAO,CAAC,UAAU,EAAE,MAAM,SAAS,OAAO,UAAU,SAAS,aAAa,cAAc,QAAA,CAAS;AACnG;AAEA,SAAS,wBAAwB;AAC/B,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAC5C,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAiB,CAAA,CAAE;AAC7C,QAAM,EAAE,OAAA,IAAW,oBAAA;AAEnB,QAAM,WAAW;AAAA,IACf,CAACE,WAA6B;AAC5B,UAAI,CAAC,OAAQ;AAEb,iBAAW,IAAI;AACf,cAAQ,IAAIA,OAAM,IAAI,CAAC,SAAS,OAAO,MAAM,IAAI,CAAC,CAAC,EAChD;AAAA,QAAK,CAAC,eACL,SAAS,CAAC,SAAS;AAAA,UACjB,GAAG;AAAA,UACH,GAAG,WAAW,IAAI,CAAC,WAAW,WAAW;AAAA,YACvC,MAAMA,OAAM,KAAK,EAAE;AAAA,YACnB,KAAK;AAAA,YACL,OAAOA,OAAM,KAAK,EAAE;AAAA,UAAA,EACpB;AAAA,QAAA,CACH;AAAA,MAAA,EAEF,QAAQ,MAAM,WAAW,KAAK,CAAC;AAAA,IACpC;AAAA,IACA,CAAC,MAAM;AAAA,EAAA;AAGT,QAAM,eAAe,YAAY,CAAC,SAAe;AAC/C,aAAS,CAAC,SAAS,KAAK,OAAO,CAAC,MAAM,MAAM,IAAI,CAAC;AAAA,EACnD,GAAG,CAAA,CAAE;AAEL,SAAO,EAAE,UAAU,OAAO,SAAS,UAAU,aAAa,CAAC,CAAC,QAAQ,aAAA;AACtE;AAEO,MAAM,WAAW,UAAU,YAAY,MAAM;AAClD,QAAM,CAAC,QAAQ,EAAE,MAAM,SAAS,OAAO,SAAS,UAAU,aAAa,cAAc,QAAA,CAAS,IAC5F,aAAA;AACF,QAAM,WAAW,OAA4B,IAAI;AACjD,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,KAAK;AACtD,QAAM,qBAAqB,YAAY,MAAM,gBAAgB,CAAC,SAAS,CAAC,IAAI,GAAG,EAAE;AACjF,QAAM,kBAAkB,OAAO,MAAM,MAAM;AAE3C,kBAAgB,MAAA;;AAAM,0BAAS,YAAT,mBAAkB;AAAA,KAAS,CAAA,CAAE;AAEnD,YAAU,MAAM;AACd,QAAI,gBAAgB,YAAY,KAAK,MAAM,SAAS,KAAK,CAAC,cAAc;AACtE,sBAAgB,IAAI;AAAA,IACtB;AAEA,oBAAgB,UAAU,MAAM;AAEhC,QAAI,MAAM,WAAW,KAAK,cAAc;AACtC,sBAAgB,KAAK;AAAA,IACvB;AAAA,EACF,GAAG,CAAC,OAAO,YAAY,CAAC;AAExB,6BACG,OAAA,EAAI,WAAU,qBACb,UAAA,qBAAC,OAAA,EAAI,WAAU,oBACZ,UAAA;AAAA,IAAA,gBACC,oBAAC,OAAA,EAAI,WAAU,wBACb,UAAA,oBAAC,kBAAA,EAAiB,OAAc,UAAU,cAAc,UAAU,QAAA,CAAS,GAC7E;AAAA,IAEF,qBAAC,OAAA,EAAI,WAAU,wBACZ,UAAA;AAAA,MAAA,eACC;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,cAAc;AAAA,UACd;AAAA,UACA,OAAO;AAAA,UACP;AAAA,UACA,UAAU;AAAA,QAAA;AAAA,MAAA;AAAA,MAGd;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAO;AAAA,UACP;AAAA,UACA,UAAU;AAAA,UACV,UAAU;AAAA,UACV;AAAA,QAAA;AAAA,MAAA;AAAA,0BAED,sBAAA,EAAqB,UAAU,QAAQ,UAAU,SAAS,SAAS,QAAA,CAAS;AAAA,IAAA,EAAA,CAC/E;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ,CAAC;ACzHM,MAAM,gBAAgB,UAAU,iBAAiB,CAAC,UAA2B;AAClF,QAAM,EAAE,WAAW,MAAM;AAEzB,SACE,oBAAC,SAAI,WAAU,yBACb,8BAAC,QAAA,EAAO,SAAS,QAAQ,EAAA,CAC3B;AAEJ,CAAC;ACTM,MAAM,cAAc,UAAU,eAAe,CAAC,UAA2B;AAC9E,QAAM,EAAE,SAAS,MAAM;AACvB,SAAO,oBAAC,OAAA,EAAI,WAAU,uBAAuB,UAAA,MAAK;AACpD,CAAC;ACED,SAAS,KAAK,KAAa;AACzB,QAAM,IAAI,OAAO,KAAK,KAAK,QAAQ;AACnC,yBAAG;AACL;AAMA,SAAS,QAAQ,OAAyB;AACxC,QAAM,EAAE,SAAS;AACjB,QAAM,EAAE,OAAA,IAAW,oBAAA;AACnB,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAS,KAAK;AAE1D,QAAM,SAAS;AAAA,IACb,MACE,UACA,QAAQ,QAAQ,kBAAkB,IAAI,CAAC,EACpC,KAAK,MAAM,OAAQ,UAAU,KAAK,GAAG,CAAC,EACtC,KAAK,IAAI,EACT,QAAQ,MAAM,kBAAkB,KAAK,CAAC;AAAA,IAC3C,CAAC,QAAQ,KAAK,GAAG;AAAA,EAAA;AAGnB,SAAO,CAAC,QAAQ,EAAE,gBAAgB;AACpC;AAEO,MAAM,cAAc,UAAU,eAAe,CAAC,UAA4B;AAC/E,QAAM,EAAE,SAAS;AACjB,QAAM,YAAY,aAAA;AAClB,QAAM,CAAC,QAAQ,EAAE,gBAAgB,IAAI,QAAQ,KAAK;AAElD,SACE,qBAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,IAAA,oBAAC,SAAI,WAAU,eACb,UAAA,oBAAC,QAAA,EAAO,SAAS,gBAAgB,SAAS,QAAQ,MAAK,QAAO,MAAM,oBAAC,QAAK,MAAK,YAAA,CAAY,GAAI,GACjG;AAAA,IACA,qBAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,MAAA,oBAAC,SAAI,WAAU,eAAc,OAAO,KAAK,MACtC,eAAK,KAAA,CACR;AAAA,MACA,oBAAC,SAAI,WAAU,eAAe,oBAAU,KAAK,KAAK,KAAK,EAAA,CAAE;AAAA,IAAA,EAAA,CAC3D;AAAA,EAAA,GACF;AAEJ,CAAC;ACjDM,MAAM,kBAAkB,UAAU,mBAAmB,CAAC,UAA2B;AACtF,QAAM,EAAE,UAAU,MAAM;AACxB,SACE,oBAAC,OAAA,EAAI,WAAU,oBACZ,gBAAM,IAAI,CAAC,SACV,oBAAC,aAAA,EAA2B,KAAA,GAAV,KAAK,GAAiB,CACzC,GACH;AAEJ,CAAC;ACRM,MAAM,iBAAiB,UAAU,kBAAkB,CAAC,UAA2B;AACpF,QAAM,EAAE,OAAO,KAAA,IAAS,MAAM;AAE9B,SACE,qBAAC,OAAA,EAAI,WAAU,0BACZ,UAAA;AAAA,IAAA,QAAQ,oBAAC,aAAA,EAAa,GAAG,MAAA,CAAO;AAAA,IAChC,MAAM,SAAS,KAAK,oBAAC,iBAAA,EAAiB,GAAG,MAAA,CAAO;AAAA,EAAA,GACnD;AAEJ,CAAC;ACRM,MAAM,iBAAiB,UAAU,kBAAkB,CAAC,UAA2B;AACpF,QAAM,EAAE,YAAY;AACpB,QAAM,EAAE,IAAI,QAAQ,OAAA,IAAW;AAC/B,QAAM,EAAE,mBAAmB,WAAW,eAAA,IAAmBF,kBAAA;AACzD,QAAM,KAAK,WAAW,SAAS,GAAA;AAC/B,QAAM,KAAK,OAAO,OAAO;AACzB,QAAM,YAAY,aAAA;AAClB,QAAM,SAAS,qBAAqB,QAAQ,GAAG,cAAc,iBAAiB,KAAK;AACnF,QAAM,UAAU,CAAC,WAAU,uCAAY;AAEvC,SACE,qBAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,IAAA,CAAC,MAAM,qBAAC,OAAA,EAAI,WAAU,8BAA8B,UAAA;AAAA,MAAA,OAAO;AAAA,MAAK;AAAA,IAAA,GAAC;AAAA,wBACjE,OAAA,EAAI,WAAU,0BAA0B,UAAA,UAAU,UAAU,MAAM,GAAE;AAAA,IACpE,CAAC,MAAM,CAAC,kBACP,oBAAC,SAAI,WAAU,2BACZ,UAAA,UAAU,UAAU,QAAQ,QAAA,IAAY,UAAU,QAAQ,OAAK,CAClE;AAAA,EAAA,GAEJ;AAEJ,CAAC;ACfM,MAAM,aAAa,UAAU,cAAc,CAAC,UAA2B;AAC5E,QAAM,EAAE,SAAS,aAAA,IAAiB;AAClC,QAAM,EAAE,WAAW;AACnB,QAAM,KAAK,WAAW,SAAS,GAAA;AAC/B,QAAM,KAAK,OAAO,OAAO;AAEzB,SACE,qBAAC,SAAI,KAAK,cAAc,WAAW,oBAAoB,KAAK,UAAU,KACpE,UAAA;AAAA,IAAA,oBAAC,eAAA,EAAe,GAAG,OAAO;AAAA,yBACzB,OAAA,EACC,UAAA;AAAA,MAAA,oBAAC,gBAAA,EAAgB,GAAG,OAAO;AAAA,MAC3B,oBAAC,gBAAA,EAAgB,GAAG,MAAA,CAAO;AAAA,IAAA,EAAA,CAC7B;AAAA,EAAA,GACF;AAEJ,CAAC;ACjBM,MAAM,aAAa,UAAU,cAAc,CAAC,UAA2B;AAC5E,QAAM,MAAM,OAA8B,IAAI;AAE9C,SACE,qBAAA,UAAA,EACE,UAAA;AAAA,IAAA,oBAAC,qBAAA,EAAoB,YAAY,KAAM,GAAG,MAAA,CAAO;AAAA,IACjD,oBAAC,YAAA,EAAW,cAAc,KAAM,GAAG,MAAA,CAAO;AAAA,EAAA,GAC5C;AAEJ,CAAC;ACXM,SAAS,qBAAqB,OAAkC;AACrE,QAAM,EAAE,QAAQ,QAAA,IAAY;AAC5B,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,KAAK;AACtD,QAAM,MAAM,OAA8B,IAAI;AAC9C,QAAM,WAAW,OAAA;AAEjB,QAAM,WAAW;AAAA,IACf,MACE,IAAI,qBAAqB,CAAC,CAAC,KAAK,MAAM;AACpC,UAAI,MAAM,gBAAgB;AACxB,iBAAS,UAAU,OAAO,WAAW,MAAM,gBAAgB,IAAI,GAAG,GAAG;AAAA,MACvE,OAAO;AACL,qBAAa,SAAS,OAAQ;AAAA,MAChC;AAAA,IACF,CAAC;AAAA,IACH,CAAA;AAAA,EAAC;AAGH,YAAU,MAAM;AACd,aAAS,QAAQ,IAAI,OAAQ;AAC7B,WAAO,MAAM,SAAS,WAAA;AAAA,EACxB,GAAG,CAAC,QAAQ,CAAC;AAEb,YAAU,MAAM;AACd,QAAI,CAAC,cAAc;AACjB;AAAA,IACF;AAEA,WAAA;AAAA,EAGF,GAAG,CAAC,YAAY,CAAC;AAEjB,MAAI,WAAW,cAAc;AAC3B,WAAO,oBAAC,iBAAA,EAAgB,OAAO,EAAA,CAAG;AAAA,EACpC;AAEA,SAAO,oBAAC,OAAA,EAAI,WAAU,eAAc,IAAA,CAAU;AAChD;AC3CO,MAAM,qBAAqB,UAAU,sBAAsB,CAAC,UAAkC;AACnG,QAAM,EAAE,SAAS;AACjB,SAAO,oBAAC,OAAA,EAAI,WAAU,+BAA+B,UAAA,MAAK;AAC5D,CAAC;ACFM,MAAM,wBAAwB,UAAU,yBAAyB,CAAC,MAA8B;AACrG,QAAM,YAAY,aAAA;AAElB,SACE,oBAAC,OAAA,EAAI,WAAU,mCACb,UAAA,oBAAC,OAAA,EAAI,WAAU,sCAAsC,UAAA,UAAU,QAAQ,QAAA,EAAQ,CAAE,GACnF;AAEJ,CAAC;ACPM,MAAM,wBAAwB,UAAU,yBAAyB,CAAC,UAAkC;AACzG,SACE,qBAAC,OAAA,EAAI,WAAU,kCACb,UAAA;AAAA,IAAA,oBAAC,oBAAA,EAAoB,GAAG,OAAO;AAAA,IAC/B,oBAAC,uBAAA,EAAuB,GAAG,MAAA,CAAO;AAAA,EAAA,GACpC;AAEJ,CAAC;ACHM,MAAM,oBAAoB,UAAU,qBAAqB,CAAC,UAAkC;AACjG,SACE,oBAAC,SAAI,WAAU,0BACb,8BAAC,uBAAA,EAAuB,GAAG,OAAO,EAAA,CACpC;AAEJ,CAAC;ACVM,MAAM,sBAAsB,UAAU,uBAAuB,MAAM;AACxE,QAAM,EAAE,QAAA,IAAYA,kBAAA;AAEpB,MAAI,CAAC,QAAS,QAAO;AAErB,SAAO,oBAAC,QAAA,EAAO,SAAS,SAAS,MAAK,QAAO,MAAM,oBAAC,MAAA,EAAK,MAAK,QAAA,CAAQ,EAAA,CAAI;AAC5E,CAAC;ACFM,MAAM,mBAAmB,UAAU,oBAAoB,MAAM;AAClE,QAAM,EAAE,IAAI,WAAW,CAAA,GAAI,SAAS,QAAQ,YAAA,IAAgBA,kBAAA;AAE5D,SACE,qBAAC,OAAA,EAAI,WAAU,4BACZ,UAAA;AAAA,IAAA,CAAC,YAAY,oBAAC,iBAAA,EAAgB,OAAO,EAAA,CAAG;AAAA,IAExC,qCAAU,IAAI,CAAC,MAAM;AACpB,UAAI,EAAE,OAAO,OAAO,WAAW;AAC7B,eAAO,oBAAC,kBAAA,EAA4B,SAAS,EAAA,GAAf,EAAE,EAAgB;AAAA,MAClD;AAEA,aAAO,oBAAC,YAAA,EAAW,SAAS,EAAA,GAAQ,EAAE,EAAI;AAAA,IAC5C;AAAA,IAEC,+BAAY,sBAAA,EAAgD,QAAQ,QAAQ,SAAS,YAAA,GAA/C,SAAS,SAAS,EAA0C;AAAA,EAAA,GACrG;AAEJ,CAAC;ACxBM,MAAM,mBAAmB,UAAU,oBAAoB,MAAM;AAClE,QAAM,EAAE,KAAA,IAASA,kBAAA;AACjB,SAAO,oBAAC,QAAA,EAAK,WAAU,4BAA4B,UAAA,MAAK;AAC1D,CAAC;ACIM,MAAM,qBAAqB,UAAU,sBAAsB,CAAC,UAAmC;AACpG,QAAM,EAAE,gBAAgB;AAExB,6BACG,OAAA,EAAI,WAAU,8BACb,UAAA,qBAAC,KAAA,EAAI,QAAQ,IACV,UAAA;AAAA,IAAA,eACC,oBAAC,KAAA,EAAI,MAAK,QACR,8BAAC,QAAA,EAAO,MAAK,QAAO,MAAM,oBAAC,cAAA,CAAA,CAAa,GAAI,SAAS,aAAa,GACpE;AAAA,IAEF,oBAAC,OAAI,MAAK,QACR,+BAAC,KAAA,EAAI,SAAQ,iBAAgB,OAAM,UACjC,UAAA;AAAA,MAAA,oBAAC,KAAA,EACC,UAAA,oBAAC,kBAAA,CAAA,CAAiB,GACpB;AAAA,0BACC,KAAA,EAAI,WAAU,+BACb,UAAA,oBAAC,uBAAoB,EAAA,CACvB;AAAA,IAAA,EAAA,CACF,EAAA,CACF;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ,CAAC;ACFM,MAAM,eAAe,UAAU,gBAAgB,CAAC,UAA6B;AAClF,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACE;AAEJ,QAAM,EAAE,IAAI,QAAQ,MAAM,sBAAsB;AAEhD,QAAM,UAAU;AAAA,IACd,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,IAEF;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EACF;AAGF,SACE,oBAAC,oBAAoB,UAApB,EAA6B,OAAO,SACnC,UAAA,oBAAC,OAAA,EAAI,WAAU,uBACb,UAAA,qBAAC,OAAA,EAAI,WAAU,4BACb,UAAA;AAAA,IAAA,oBAAC,sBAAmB,aAA0B;AAAA,wBAC7C,kBAAA,EAAiB;AAAA,IACjB,8BAAW,UAAA,CAAA,CAAS;AAAA,EAAA,EAAA,CACvB,GACF,GACF;AAEJ,CAAC;ACxFD,MAAM,WAAW,SAAS,QAAQ;AAClC,MAAM,UAAU,SAAS,OAAO;AAEhC,SAAS,kBAAkB,IAAY,OAAe;AACpD,QAAM,CAAC,cAAc,IAAI,WAAW,0BAAA;AACpC,SAAO,MAAM,eAAe,EAAE,IAAI,MAAM,OAAO;AACjD;AAEO,MAAM,yBAAyB,UAAU,0BAA0B,MAAM;AAC9E,QAAM,EAAE,IAAI,MAAM,OAAA,IAAWA,kBAAA;AAC7B,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS,EAAE;AACrD,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,iBAAiB,kBAAkB,IAAI,aAAa;AAE1D,YAAU,MAAM;AACd,QAAI,MAAM;AACR,uBAAiB,QAAQ,EAAE;AAAA,IAC7B;AAAA,EACF,GAAG,CAAC,MAAM,IAAI,CAAC;AAEf,MAAI,CAAC,QAAQ;AACX,WAAO,oBAAC,QAAA,EAAK,WAAU,4BAA4B,UAAA,MAAK;AAAA,EAC1D;AAEA,MAAI,MAAM;AACR,WACE,oBAAC,SAAA,EAAQ,aAAW,MAAC,OAAM,iEACzB,UAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,OAAO;AAAA,QACP,UAAU,CAAC,MAAM,iBAAiB,EAAE,OAAO,KAAK;AAAA,QAChD,QAAQ,MAAM,QAAQ,KAAK;AAAA,QAC3B,WAAW,CAAC,MAAM;AAChB,cAAI,SAAS,CAAC,GAAG;AACf,oBAAQ,KAAK;AAAA,UACf,WAAW,QAAQ,CAAC,GAAG;AACrB,oBAAQ,KAAK;AAEb,gBAAI,kBAAkB,QAAQ,cAAc,KAAA,MAAW,IAAI;AACzD,6BAAA;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA,WAAS;AAAA,MAAA;AAAA,IAAA,GAEb;AAAA,EAEJ;AAEA,SACE,oBAAC,SAAA,EAAQ,OAAM,yBACb,8BAAC,QAAA,EAAK,WAAU,uCAAsC,SAAS,MAAM,QAAQ,IAAI,GAC9E,gBACH,GACF;AAEJ,CAAC;ACzDM,MAAM,oBAAoB,UAAU,qBAAqB,MAAM;AACpE,QAAM,EAAE,QAAQ,QAAA,IAAYA,kBAAA;AAE5B,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,SACE,qBAAC,OAAA,EAAI,WAAU,uBACZ,UAAA;AAAA,IAAA,CAAC,+BAAY,oBAAA,EAAmB;AAAA,wBAChC,mBAAA,CAAA,CAAkB;AAAA,EAAA,GACrB;AAEJ,CAAC;ACUM,MAAM,oCAAgE;AAAA,EAC3E,kBAAkB,MAAM,oBAAC,wBAAA,EAAuB;AAAA,EAChD,qBAAqB,MAAM,oBAAC,mBAAA,CAAA,CAAkB;AAChD;AAEA,SAAS,gBAAgB,OAAqD;AAC5E,QAAM,EAAE,OAAO,MAAM,YAAA,IAAgB;AACrC,QAAM,EAAE,QAAA,IAAY,eAAA;AACpB,QAAM,EAAE,IAAI,MAAM,QAAQ,sBAAsB;AAEhD,QAAM,EAAE,MAAM,gBAAgB,WAAW,2BAA2B,EAAE,QAAQ,IAAI;AAClF,QAAM,EAAE,UAAU,QAAA,IAAY,eAAe,CAAA;AAE7C,QAAM,CAAC,WAAW,EAAE,WAAW,oBAAoB,IAAI,WAAW,oCAAA;AAClE,QAAM,SAAS,YAAY,MAAM,UAAU,EAAE,QAAQ,GAAA,CAAI,GAAG,CAAC,WAAW,EAAE,CAAC;AAE3E,QAAM,CAAC,IAAI,IAAI,WAAW,2BAAA;AAC1B,QAAM,SAAS,YAAY,CAACG,QAAe,KAAK,EAAE,IAAAA,IAAAA,CAAI,GAAG,CAAC,IAAI,CAAC;AAE/D,QAAM,CAAC,IAAI,IAAI,WAAW,2BAAA;AAC1B,QAAM,SAAS,YAAY,CAAC,YAAyB,KAAK,EAAE,GAAG,SAAS,QAAQ,GAAA,CAAI,EAAE,OAAA,GAAU,CAAC,IAAI,IAAI,CAAC;AAE1G,QAAM,EAAE,MAAM,cAAc,WAAW,gCAAA;AAEvC,QAAM,eAAe,QAAQ,MAAM;AACjC,QAAI,CAAC,IAAI;AACP,aAAO;AAAA,IACT;AAEA,UAAM,SAA4B;AAAA,MAChC,OAAO,EAAE,IAAS,MAAa,QAAiB,kBAAA;AAAA,MAChD;AAAA,MACA;AAAA,MACA;AAAA,MACA,aAAa;AAAA,MACb;AAAA,MACA;AAAA,MACA,WAAW,CAACA,QAAe,UAAW,KAAK,CAAC,MAAM,OAAO,EAAE,KAAK,MAAM,OAAOA,GAAE,KAAKA,OAAM,EAAE,KAAK;AAAA,MACjG,SAAS,WAAW;AAAA,MACpB;AAAA,IAAA;AAGF,WAAO;AAAA,EACT,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,CACD;AAED,SAAO;AACT;AAEA,SAASC,UAAQ,OAAqD;AACpE,QAAM,eAAe,gBAAgB,KAAK;AAC1C,QAAM,EAAE,SAAS,YAAA,IAAgB,eAAA;AAEjC,MAAI,CAAC,cAAc;AACjB,WAAO;AAAA,EACT;AAEA,SACE,qBAAC,OAAA,EAAI,WAAU,eACX,UAAA;AAAA,KAAA,CAAC,WAAW,CAAC,gBAAgB,oBAAC,cAAA,EAAc,GAAG,cAAc;AAAA,IAC9D,mCAAgB,kBAAA,CAAA,CAAiB;AAAA,EAAA,GACpC;AAEJ;AAEO,MAAM,WAAW,UAAU,YAAY,CAAC,UAAyB;AACtE,QAAM,EAAE,OAAO,SAAS,YAAA,IAAgB;AACxC,QAAM,aAAa,oBAAA;AACnB,QAAMC,aAAoC;AAAA,IACxC,OAAO,EAAE,GAAI,cAAc,IAAK,GAAG,kCAAA;AAAA,IACnC,CAAC,UAAU;AAAA,EAAA;AAGb,6BACG,iBAAiB,UAAjB,EAA0B,OAAOA,YAChC,8BAAC,aAAA,EAAY,IAAI,MAAM,IAAI,SAAS,WAAW,OAC7C,UAAA,oBAACD,aAAQ,OAAc,aAA0B,GACnD,EAAA,CACF;AAEJ,CAAC;ACvHM,SAAS,WAAW,qBAAuC,KAAK;AACrE,QAAM,MAAM,OAAuB,IAAI;AACvC,QAAM,CAAC,MAAM,OAAO,IAAI,SAAA;AACxB,QAAM,YAAY,OAAO,uBAAuB;AAEhD,YAAU,MAAM;AACd,QAAI,CAAC,WAAW;AACd,cAAQ,MAAS;AACjB;AAAA,IACF;AAEA,UAAM,KAAK,IAAI;AACf,QAAI,CAAC,GAAI;AAET,UAAM,WAAW,IAAI,eAAe,MAAM;AACxC,YAAM,EAAE,OAAO,WAAW,GAAG,sBAAA;AAC7B,cAAQ,EAAE,OAAO,QAAQ;AAAA,IAC3B,CAAC;AAED,aAAS,QAAQ,EAAE;AACnB,WAAO,MAAM,SAAS,WAAA;AAAA,EACxB,GAAG,CAAC,SAAS,CAAC;AAEd,MAAI,OAAO,uBAAuB,WAAW;AAC3C,WAAO,CAAC,KAAK,oBAAoB,IAAI;AAAA,EACvC;AAEA,QAAM,UAAU,QAAQ,OAAO,KAAK,QAAQ,qBAAqB;AACjE,SAAO,CAAC,KAAK,SAAS,IAAI;AAC5B;ACNO,SAAS,UAAU,OAAuB;AAC/C,QAAM,EAAE,IAAI,YAAY,IAAI,WAAAC,YAAW,YAAY,kBAAkB,OAAO,SAAS,YAAA,IAAgB;AACrG,QAAM,EAAE,MAAM,KAAA,IAAS,WAAW,gBAAgB,EAAE,IAAI;AACxD,QAAM,CAAC,KAAK,OAAO,IAAI,WAAW,WAAW;AAE7C,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW,CAAC,kBAAkB,qBAAqB,WAAW,aAAa,SAAS,EACjF,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,MACX;AAAA,MACA;AAAA,MAEA,UAAA,oBAAC,iBAAiB,UAAjB,EAA0B,OAAO,WAChC,UAAA,oBAAC,iBAAiB,UAAjB,EAA0B,OAAOA,YAC/B,UAAA,4BAAS,UAAA,EAAS,OAAO,MAAe,QAAA,GAAJ,EAAsB,GAC7D,EAAA,CACF;AAAA,IAAA;AAAA,EAAA;AAGN;AC9BA,MAAM,wBAAwB,MAAM,cAAgC,IAAK;AAElE,SAAS,sBAAsB;AACpC,SAAO,WAAW,qBAAqB;AACzC;AAGO,SAAS,iBAAiB,OAAgD;AAC/E,QAAM,EAAE,UAAU,QAAA,IAAY;AAC9B,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAoE;AAAA,IAC5F,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,aAAa;AAAA,EAAA,CACd;AAED,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,MACL,GAAG;AAAA,MACH;AAAA,MACA,UAAU,CAACP,YAAmB,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,MAAM,QAAQ,QAAAA,QAAA,EAAS;AAAA,MACpF,MAAM,MAAM,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,MAAM,MAAM,QAAQ,KAAA,EAAO;AAAA,MACtE,eAAe,MAAM,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,aAAa,CAAC,KAAK,YAAA,EAAc;AAAA,MACrF,eAAe,MACb,SAAS,CAAC,SAAS;AACjB,YAAI,KAAK,SAAS,cAAc,CAAC,KAAK,QAAQ;AAC5C,iBAAO,EAAE,GAAG,MAAM,MAAM,KAAA;AAAA,QAC1B,WAAW,KAAK,SAAS,cAAc,KAAK,QAAQ;AAClD,iBAAO,EAAE,GAAG,MAAM,MAAM,OAAA;AAAA,QAC1B,OAAO;AACL,iBAAO,EAAE,GAAG,MAAM,MAAM,WAAA;AAAA,QAC1B;AAAA,MACF,CAAC;AAAA,MACH,iBAAiB,MACf,SAAS,CAAC,SAAS;AACjB,YAAI,KAAK,SAAS,gBAAgB,KAAK,QAAQ;AAC7C,iBAAO,EAAE,GAAG,MAAM,MAAM,OAAA;AAAA,QAC1B,WAAW,KAAK,SAAS,gBAAgB,CAAC,KAAK,QAAQ;AACrD,iBAAO,EAAE,GAAG,MAAM,MAAM,KAAA;AAAA,QAC1B,OAAO;AACL,iBAAO,EAAE,GAAG,MAAM,MAAM,aAAA;AAAA,QAC1B;AAAA,MACF,CAAC;AAAA,IAAA;AAAA,IAEL,CAAC,OAAO,OAAO;AAAA,EAAA;AAGjB,SAAO,oBAAC,sBAAsB,UAAtB,EAA+B,OAAe,SAAA,CAAS;AACjE;ACxDO,MAAM,kBAAkB,UAAU,mBAAmB,MAAM;AAChE,QAAM,EAAE,gBAAA,IAAoB,oBAAA;AAC5B,QAAM,YAAY,aAAA;AAClB,QAAM,YAAY,UAAU,UAAU,YAAA;AAEtC,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,SAAS;AAAA,MACT,MAAM,oBAAC,MAAA,EAAK,MAAK,WAAA,CAAW;AAAA,MAC5B,OAAO;AAAA,MACP,cAAY;AAAA,IAAA;AAAA,EAAA;AAGlB,CAAC;ACZM,MAAM,uBAAuB,UAAU,wBAAwB,CAAC,UAAqC;AAC1G,QAAM,EAAE,SAAS;AACjB,QAAM,YAAY,aAAA;AAElB,SACE;AAAA,IAAC,KAAK;AAAA,IAAL;AAAA,MACC,OAAO,UAAU,UAAU,OAAO,MAAA;AAAA,MAClC;AAAA,MACA,OAAO,CAAC,EAAE,UAAU,MAAM,SAAS,UAAU,UAAU,OAAO,SAAA,GAAY;AAAA,MAE1E,UAAA,oBAAC,WAAW,aAAX,EAAuB,QAAQ,UAAU,UAAU,OAAO,SAAO,CAAG;AAAA,IAAA;AAAA,EAAA;AAG3E,CAAC;ACbM,MAAM,qBAAqB,UAAU,sBAAsB,CAAC,UAAmC;AACpG,QAAM,EAAE,SAAS;AACjB,QAAM,YAAY,aAAA;AAElB,SACE;AAAA,IAAC,KAAK;AAAA,IAAL;AAAA,MACC,OAAO,UAAU,UAAU,KAAK,MAAA;AAAA,MAChC;AAAA,MACA,OAAO,CAAC,EAAE,UAAU,MAAM,SAAS,UAAU,UAAU,KAAK,SAAA,GAAY;AAAA,MAExE,UAAA,oBAAC,MAAM,UAAN,EAAe,MAAM,EAAA,CAAG;AAAA,IAAA;AAAA,EAAA;AAG/B,CAAC;ACFM,MAAM,gCAAoD;AAAA,EAC/D,QAAQ,CAAA;AAAA,EACR,MAAM;AACR;AAEO,MAAM,gBAAgB,UAAU,iBAAiB,CAAC,UAA8B;AACrF,QAAM,EAAE,OAAO,OAAO,OAAO,aAAa;AAC1C,QAAM,YAAY,aAAA;AAElB,QAAM,CAAC,IAAI,IAAI,KAAK,QAAA;AAEpB,YAAU,MAAM;AACd,SAAK,eAAe,KAAK;AAAA,EAC3B,GAAG,CAAC,OAAO,IAAI,CAAC;AAEhB,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,QAAO;AAAA,MACP,UAAU;AAAA,MACV,UAAU;AAAA,MACV,eAAe;AAAA,MAEf,UAAA;AAAA,QAAA,oBAAC,sBAAA,EAAqB,MAAK,SAAA,CAAS;AAAA,QACpC,oBAAC,oBAAA,EAAmB,MAAK,OAAA,CAAO;AAAA,QAChC,oBAAC,QAAA,EAAO,SAAS,MAAM,MAAK,WAAU,OAAK,MAAC,UAAS,UAClD,UAAA,UAAU,UAAU,YAAU,CACjC;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN,CAAC;ACtCD,SAAS,eAAe,WAAkD;AACxE,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,QAAQ,CAAC,MAAM,UAAU,OAAO,KAAK,GAAG,MAAM,UAAU,OAAO,GAAG,CAAC;AAAA,IACnE,MAAM,UAAU;AAAA,EAAA;AAEpB;AAEA,SAAS,WAAW;AAClB,QAAM,EAAE,MAAM,OAAO,WAAW,6BAAA;AAEhC,QAAM,QAAQ,QAA4B,MAAM;AAC9C,WAAO,eAAe,yBAAI,SAAS;AAAA,EACrC,GAAG,CAAC,EAAE,CAAC;AAEP,SAAO;AACT;AAEA,SAAS,sBAAsB;AAC7B,QAAM,OAAO,WAAW,SAAS,GAAA;AACjC,QAAM,CAAC,eAAe,EAAE,WAAW,IAAI,WAAW,yBAAA;AAElD,QAAM,WAAW;AAAA,IACf,CAAC,UACC,cAAc;AAAA,MACZ,IAAI;AAAA,MACJ,WAAW;AAAA,QACT,UAAU;AAAA,QACV,OAAO;AAAA,UACL,MAAM,MAAM;AAAA,UACZ,QAAQ;AAAA,YACN,OAAO,MAAM,OAAO,CAAC,EAAE,YAAA;AAAA,YACvB,KAAK,MAAM,OAAO,CAAC,EAAE,YAAA;AAAA,UAAY;AAAA,QACnC;AAAA,MACF;AAAA,IACF,CACD,EAAE,OAAA;AAAA,IACL,CAAC,eAAe,IAAI;AAAA,EAAA;AAGtB,QAAM,UAAU;AAAA,IACd,MACE,cAAc;AAAA,MACZ,IAAI;AAAA,MACJ,WAAW;AAAA,QACT,UAAU;AAAA,QACV,OAAO;AAAA,MAAA;AAAA,IACT,CACD,EAAE,OAAA;AAAA,IACL,CAAC,eAAe,IAAI;AAAA,EAAA;AAGtB,SAAO,CAAC,UAAU,WAAW,OAAO;AACtC;AAEO,MAAM,iBAAiB,UAAU,kBAAkB,MAAM;AAC9D,QAAM,YAAY,aAAA;AAClB,QAAM,EAAE,gBAAA,IAAoB,oBAAA;AAC5B,QAAM,QAAQ,SAAA;AACd,QAAM,CAAC,UAAU,YAAY,OAAO,IAAI,oBAAA;AAExC,SACE,qBAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAAS;AAAA,QACT,WAAU;AAAA,QACV,MAAK;AAAA,QACL,MAAM,oBAAC,MAAA,EAAK,MAAK,QAAA,CAAQ;AAAA,MAAA;AAAA,IAAA;AAAA,IAE3B,qBAAC,OAAA,EAAI,WAAU,kCACb,UAAA;AAAA,MAAA,oBAAC,MAAA,EAAI,UAAA,UAAU,UAAU,MAAA,GAAQ;AAAA,MACjC,oBAAC,QAAA,EAAO,MAAK,QAAO,SAAS,SAAS,UAAU,YAAY,WAAU,iCACnE,UAAA,UAAU,UAAU,WAAS,CAChC;AAAA,IAAA,GACF;AAAA,wBAEC,eAAA,EAAc,OAAc,MAAM,cAAc,OAAO,SAAA,CAAoB;AAAA,EAAA,GAC9E;AAEJ,CAAC;ACrFM,MAAM,sBAAsB,UAAU,uBAAuB,CAAC,UAAoC;AACvG,QAAM,EAAE,SAAS;AACjB,QAAM,YAAY,aAAA;AAElB,SACE;AAAA,IAAC,KAAK;AAAA,IAAL;AAAA,MACC;AAAA,MACA,OAAO,UAAU,QAAQ,KAAK,MAAA;AAAA,MAC9B,OAAO;AAAA,QACL,EAAE,UAAU,MAAM,SAAS,UAAU,QAAQ,KAAK,WAAS;AAAA,QAC3D,EAAE,KAAK,KAAK,SAAS,UAAU,QAAQ,KAAK,SAAO;AAAA,MAAE;AAAA,MAGvD,8BAAC,OAAA,CAAA,CAAM;AAAA,IAAA;AAAA,EAAA;AAGb,CAAC;ACRD,SAAS,aAAa,OAA0B;AAC9C,QAAM,EAAE,OAAO,SAAA,IAAa;AAC5B,QAAM,EAAE,MAAM,UAAU,WAAA,IAAe,WAAW,uBAAuB,EAAE;AAC3E,QAAM,KAAK,WAAW,SAAS,GAAA;AAC/B,QAAM,aAAa,QAAQ,OAAM,qCAAU,OAAO,CAAC,MAAM,EAAE,OAAO,QAAO,CAAA,GAAI,CAAC,UAAU,EAAE,CAAC;AAE3F,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,QAAO;AAAA,MACP,WAAU;AAAA,MACV,SAAS;AAAA,MACT;AAAA,MACA,YAAY,CAAC,MAAM;AACjB,cAAM,UAAU,MAAO,SAAS,EAAE,EAAE;AAEpC,mCACG,KAAK,MAAL,EAAU,WAAW,UAAU,eAAe,IAC7C,UAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC;AAAA,YACA,UAAU,MACR,SAAU,MAAO,SAAS,EAAE,EAAE,IAAI,MAAO,OAAO,CAAC,MAAM,MAAM,EAAE,EAAE,IAAI,CAAC,GAAG,OAAQ,EAAE,EAAE,CAAC;AAAA,YAGxF,UAAA,oBAAC,KAAK,KAAK,MAAV,EAAe,QAAQ,oBAAC,QAAA,EAAO,SAAS,EAAA,CAAG,GAAI,OAAO,EAAE,KAAA,CAAM;AAAA,UAAA;AAAA,QAAA,GAEnE;AAAA,MAEJ;AAAA,IAAA;AAAA,EAAA;AAGN;AAEO,MAAM,wBAAwB;AAAA,EACnC;AAAA,EACA,CAAC,UAAsC;AACrC,UAAM,EAAE,SAAS;AACjB,UAAM,YAAY,aAAA;AAElB,WACE;AAAA,MAAC,KAAK;AAAA,MAAL;AAAA,QACC,OAAO,UAAU,QAAQ,QAAQ,MAAA;AAAA,QACjC,OAAO,CAAC,EAAE,UAAU,MAAM,SAAS,UAAU,QAAQ,QAAQ,SAAA,GAAY;AAAA,QACzE;AAAA,QAEA,8BAAC,cAAA,CAAA,CAAa;AAAA,MAAA;AAAA,IAAA;AAAA,EAGpB;AACF;AC/CA,MAAM,gBAAqC;AAAA,EACzC,MAAM;AAAA,EACN,SAAS,CAAA;AACX;AAEO,MAAM,iBAAiB,UAAU,kBAAkB,CAAC,UAA+B;AACxF,QAAM,EAAE,QAAQ,eAAe,UAAU,OAAO,UAAU;AAC1D,QAAM,YAAY,aAAA;AAElB,SACE,qBAAC,QAAK,UAAU,UAAU,QAAO,YAAW,UAAU,MAAM,eAAe,OACzE,UAAA;AAAA,IAAA,oBAAC,qBAAA,EAAoB,MAAK,OAAA,CAAO;AAAA,IACjC,oBAAC,uBAAA,EAAsB,MAAK,UAAA,CAAU;AAAA,IACtC,oBAAC,QAAA,EAAO,SAAS,MAAM,MAAK,WAAU,OAAK,MAAC,UAAS,UAClD,UAAA,UAAU,QAAQ,YAAU,CAC/B;AAAA,EAAA,GACF;AAEJ,CAAC;AC1BD,SAAS,YAAY;AACnB,QAAM,CAAC,KAAK,EAAE,WAAW,IAAI,WAAW,mBAAA;AACxC,QAAM,EAAE,SAAA,IAAa,oBAAA;AAErB,QAAM,WAAW;AAAA,IACf,CAAC,UACC,IAAI;AAAA,MACF,MAAM,MAAM;AAAA,MACZ,SAAS,MAAM;AAAA,IAAA,CAChB,EACE,OAAA,EACA,KAAK,CAAC,OAAO,SAAS,EAAE,CAAC;AAAA,IAC9B,CAAC,KAAK,QAAQ;AAAA,EAAA;AAGhB,SAAO,CAAC,UAAU,SAAS;AAC7B;AAEO,MAAM,kBAAkB,UAAU,mBAAmB,MAAM;AAChE,QAAM,YAAY,aAAA;AAClB,QAAM,CAAC,UAAU,UAAU,IAAI,UAAA;AAC/B,QAAM,EAAE,cAAA,IAAkB,oBAAA;AAE1B,SACE,qBAAC,OAAA,EAAI,WAAU,4BACb,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAAS,MAAM,cAAA;AAAA,QACf,WAAU;AAAA,QACV,MAAK;AAAA,QACL,MAAM,oBAAC,MAAA,EAAK,MAAK,QAAA,CAAQ;AAAA,MAAA;AAAA,IAAA;AAAA,IAE3B,oBAAC,MAAA,EAAI,UAAA,UAAU,QAAQ,SAAQ;AAAA,IAC/B,oBAAC,gBAAA,EAAe,MAAM,cAAc,OAAO,SAAA,CAAoB;AAAA,EAAA,GACjE;AAEJ,CAAC;ACxCM,MAAM,mBAAmB,UAAU,oBAAoB,MAAM;AAClE,QAAM,EAAE,cAAA,IAAkB,oBAAA;AAE1B,SACE,oBAAC,QAAA,EAAK,WAAU,0BACd,UAAA,oBAAC,QAAA,EAAO,WAAU,kBAAiB,SAAS,eAAe,MAAK,KAAI,sBAEpE,GACF;AAEJ,CAAC;ACTM,MAAM,mBAAmB,UAAU,oBAAoB,MAAM;AAClE,SACE,oBAAC,UAAK,WAAU,0BACd,+BAAC,MAAM,SAAN,EAAc,WAAU,wBACvB,UAAA;AAAA,IAAA,oBAAC,kBAAA,EAAiB;AAAA,wBACjB,iBAAA,CAAA,CAAgB;AAAA,EAAA,EAAA,CACnB,EAAA,CACF;AAEJ,CAAC;ACRD,SAAS,UAAU;AACjB,QAAM,EAAE,MAAM,UAAU,WAAW,oBAAA;AACnC,SAAO;AAAA,IACL,OACE,+BAAO;AAAA,MACL,CAAC,OAAsB;AAAA,QACrB,IAAI,EAAE;AAAA,QACN,MAAM,EAAE;AAAA,QACR,aAAa,EAAE;AAAA,QACf,mBAAmB,EAAE;AAAA,MAAA;AAAA,UAEpB,CAAA;AAAA,IACP,CAAC,KAAK;AAAA,EAAA;AAEV;AAEO,MAAM,gBAAgB,UAAU,iBAAiB,MAAM;AAC5D,QAAM,EAAE,QAAAA,SAAQ,SAAA,IAAa,oBAAA;AAC7B,QAAM,OAAO,QAAA;AAEb,6BAAQ,UAAA,EAAS,OAAO,MAAM,UAAUA,SAAQ,UAAU,UAAU;AACtE,CAAC;ACvBM,MAAM,iBAAiB,UAAU,kBAAkB,MAAM;AAC9D,SACE,qBAAC,OAAA,EAAI,WAAU,gBACb,UAAA;AAAA,IAAA,oBAAC,kBAAA,EAAiB;AAAA,wBACjB,eAAA,CAAA,CAAc;AAAA,EAAA,GACjB;AAEJ,CAAC;ACTM,MAAM,kBAAkB,UAAU,mBAAmB,MAAM;AAChE,SAAO,oBAAC,OAAA,EAAI,WAAU,gBAAA,CAAgB;AACxC,CAAC;ACFM,MAAM,kBAAkB,UAAU,mBAAmB,0BAAO,OAAA,EAAI,WAAU,iBAAgB,CAAM;ACKhG,MAAM,gBAAgB,UAAU,iBAAiB,MAAM;AAC5D,QAAM,EAAE,QAAAA,SAAQ,MAAM,SAAS,KAAA,IAAS,oBAAA;AACxC,QAAM,OAAO,WAAW,gBAAgBA,OAAM;AAE9C,SACE,qBAAC,OAAA,EAAI,WAAU,eACZ,UAAA;AAAA,IAAA,SAAS,UAAU,QAClB,oBAAC,UAAA,EAAS,OAAO,MAAmB,SAAkB,aAAa,UAAU,OAAO,OAAA,GAAxDA,OAAmE;AAAA,IAEhG,SAAS,cAAc,oBAAC,iBAAA,CAAA,CAAgB;AAAA,IACxC,SAAS,gBAAgB,oBAAC,gBAAA,CAAA,CAAe;AAAA,EAAA,GAC5C;AAEJ,CAAC;ACfM,MAAM,gBAAgB,UAAU,iBAAiB,MAAM;AAC5D,QAAM,EAAE,SAAS,KAAA,IAAS,oBAAA;AAC1B,QAAM,eAAe,CAAC,WAAW,CAAC;AAClC,QAAM,cAAc,CAAC,WAAW;AAEhC,SACE,qBAAC,OAAA,EAAI,WAAU,eACZ,UAAA;AAAA,IAAA,oCAAiB,gBAAA,EAAe;AAAA,IAChC,mCAAgB,eAAA,CAAA,CAAc;AAAA,EAAA,GACjC;AAEJ,CAAC;ACqCD,SAAS,QAAQ,OAAqB;AACpC,QAAM,EAAE,YAAY,IAAI,OAAO,iBAAiB;AAChD,QAAM,EAAE,MAAM,UAAU,WAAW,oBAAA;AACnC,QAAM,EAAE,UAAU,MAAM,QAAAA,SAAQ,QAAA,IAAY,oBAAA;AAC5C,QAAM,mBAAmB,OAAO,KAAK;AAErC,YAAU,MAAM;AACd,QAAI,SAASA,WAAU,CAAC,MAAM,KAAK,CAAC,MAAM,EAAE,OAAOA,OAAM,GAAG;AAC1D,YAAM,SAAS,SAAS,MAAM,CAAC,EAAE,EAAE,IAAI,KAAA;AAAA,IACzC;AAAA,EAGF,GAAG,CAAC,OAAOA,OAAM,CAAC;AAElB,YAAU,MAAM;AACd,QAAI,SAAS,CAAC,iBAAiB,WAAW,CAAC,SAAS;AAClD,uBAAiB,UAAU;AAC3B,YAAM,UAAU,SAAS,MAAM,CAAC,EAAE,EAAE;AAAA,IACtC;AAAA,EAEF,GAAG,CAAC,OAAO,OAAO,CAAC;AAEnB,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW,CAAC,kBAAkB,qBAAqB,WAAW,aAAa,SAAS,EACjF,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,MACX;AAAA,MACA,KAAK;AAAA,MAEL,UAAA;AAAA,QAAA,oBAAC,iBAAA,EAAgB;AAAA,4BAChB,eAAA,EAAc;AAAA,4BACd,iBAAA,CAAA,CAAgB;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGvB;AAEA,MAAMQ,sBAA6C;AAAA,EACjD,iBAAiB;AAAA,EACjB,iBAAiB;AACnB;AAEO,MAAM,iBAA0C,CAAC,UAAU;AAChE,QAAM,EAAE,YAAY,kBAAkB,WAAAD,aAAYC,qBAAmB,SAAS,gBAAgB;AAC9F,QAAM,iBAAiB,QAAQ,MAAM,OAAO,OAAO,IAAIA,qBAAmBD,UAAS,GAAG,CAACA,UAAS,CAAC;AACjG,QAAM,CAAC,cAAc,OAAO,IAAI,WAAW,WAAW;AAEtD,SACE,oBAAC,iBAAiB,UAAjB,EAA0B,OAAO,WAChC,UAAA,oBAAC,iBAAiB,UAAjB,EAA0B,OAAO,gBAChC,8BAAC,kBAAA,EAAiB,SAAS,WAAW,MACpC,UAAA,oBAAC,SAAA,EAAS,GAAG,OAAO,aAAA,CAA4B,EAAA,CAClD,EAAA,CACF,EAAA,CACF;AAEJ;ACrGO,MAAM,gBAAgB,MAAM,cAAkC,IAAK;AAEnE,SAAS,mBAAmB;AACjC,SAAO,MAAM,WAAW,aAAa;AACvC;ACPO,MAAM,gBAAgB,UAAU,iBAAiB,MAAM;AAC5D,QAAM,EAAE,OAAO,QAAA,IAAY,iBAAA;AAE3B,MAAI,CAAC,OAAO;AACV,+BACG,SAAA,EAAQ,OAAM,gBACb,UAAA,oBAAC,QAAA,EAAO,MAAK,QAAO,0BAAO,MAAA,EAAK,MAAK,SAAQ,GAAI,SAAS,MAAM,QAAQ,IAAI,GAAG,GACjF;AAAA,EAEJ;AAEA,6BACG,SAAA,EAAQ,OAAM,kBACb,UAAA,oBAAC,QAAA,EAAO,MAAK,QAAO,0BAAO,MAAA,EAAK,MAAK,WAAU,GAAI,SAAS,MAAM,QAAQ,KAAK,GAAG,GACpF;AAEJ,CAAC;ACDD,SAAS,cAAc,OAAyB;AAC9C,QAAM,EAAE,aAAa;AACrB,QAAM,EAAE,MAAM,WAAW,WAAW,kBAAkB,EAAE,IAAI,UAAU;AACtE,QAAM,EAAE,MAAM,YAAA,IAAgB,WAAW,6BAA6B,EAAE,UAAU;AAClF,QAAM,EAAE,IAAI,MAAM,SAAS,mBAAmB,MAAA,IAAU,UAAU,CAAA;AAClE,QAAM,EAAE,UAAU,QAAA,IAAY,eAAe,CAAA;AAE7C,QAAM,CAAC,IAAI,IAAI,WAAW,6BAAA;AAC1B,QAAM,SAAS,YAAY,CAACF,QAAe,KAAK,EAAE,IAAAA,IAAAA,CAAI,GAAG,CAAC,IAAI,CAAC;AAE/D,QAAM,CAAC,WAAW,EAAE,WAAW,oBAAoB,IAAI,WAAW,sCAAA;AAClE,QAAM,SAAS,YAAY,MAAM,UAAU,EAAE,SAAA,CAAU,GAAG,CAAC,WAAW,QAAQ,CAAC;AAE/E,QAAM,CAAC,IAAI,IAAI,WAAW,6BAAA;AAC1B,QAAM,SAAS;AAAA,IACb,CAAC,YAAyB,KAAK,EAAE,MAAM,SAAS,SAAA,CAAU,EAAE,OAAA;AAAA,IAC5D,CAAC,UAAU,IAAI;AAAA,EAAA;AAGjB,QAAM,EAAE,MAAM,cAAc,WAAW,kCAAA;AAEvC,QAAM,eAAe,QAAQ,MAAM;AACjC,QAAI,CAAC,IAAI;AACP,aAAO;AAAA,IACT;AAEA,UAAM,SAA4B;AAAA,MAChC,OAAO,EAAE,IAAS,MAAa,QAAQ,CAAC,SAAS,mBAAmB,qBAAqB,KAAA;AAAA,MACzF;AAAA,MACA;AAAA,MACA;AAAA,MACA,aAAa;AAAA,MACb;AAAA,MACA;AAAA,MACA,gBAAgB,CAAC;AAAA,MACjB,SAAS;AAAA,MACT,WAAW,CAACA,QACV,UAAW;AAAA,QACT,CAAC,SAAS,qBAAqB,KAAK,KAAK,EAAE,CAAC,MAAM,qBAAqBA,GAAE,EAAE,CAAC,KAAKA,OAAM,KAAK;AAAA,MAAA;AAAA,IAC9F;AAGJ,WAAO;AAAA,EACT,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,CACD;AAED,QAAM,CAAC,WAAW,IAAI,WAAW,uBAAA;AAEjC,QAAM,gBAAgB;AAAA,IACpB,MACE,SACI;AAAA,MACE,IAAI,OAAO;AAAA,MACX,OAAO,OAAO;AAAA,MACd,SAAS,CAAC,UAAU,YAAY,EAAE,IAAI,OAAO,IAAI,OAAO,MAAA,CAAO,EAAE,OAAA;AAAA,IAAO,IAE1E;AAAA,IACN,CAAC,QAAQ,WAAW;AAAA,EAAA;AAGtB,SAAO,CAAC,cAAc,aAAa;AACrC;AAEA,MAAM,oBAA0C;AAAA,EAC9C,qBAAqB,MAAM,oBAAC,eAAA,CAAA,CAAc;AAC5C;AAEO,SAAS,YAAY,OAAyB;AACnD,QAAM,EAAE,UAAU,WAAAE,YAAW,YAAY,kBAAkB,YAAY,OAAO;AAC9E,QAAM,CAAC,cAAc,aAAa,IAAI,cAAc,KAAK;AACzD,QAAM,sBAAsB,QAAQ,OAAO,EAAE,GAAG,mBAAmB,GAAGA,WAAA,IAAc,CAACA,UAAS,CAAC;AAE/F,YAAU,MAAM;AACd,eAAW,SAAS,OAAO,gBAAgB,QAAQ;AAEnD,WAAO,MAAM;AACX,iBAAW,SAAS,OAAO,qBAAqB,QAAQ;AAAA,IAC1D;AAAA,EACF,GAAG,CAAC,QAAQ,CAAC;AAEb,MAAI,CAAC,gBAAgB,CAAC,eAAe;AACnC,WAAO;AAAA,EACT;AAEA,SACE,oBAAC,iBAAiB,UAAjB,EAA0B,OAAO,WAChC,UAAA,oBAAC,cAAc,UAAd,EAAuB,OAAO,eAC7B,UAAA,oBAAC,iBAAiB,UAAjB,EAA0B,OAAO,qBAChC,UAAA,oBAAC,OAAA,EAAI,WAAW,gCAAgC,SAAS,IACtD,UAAA,gBAAgB,oBAAC,cAAA,EAAc,GAAG,aAAA,CAAc,EAAA,CACnD,EAAA,CACF,GACF,GACF;AAEJ;ACrHO,MAAM,UAAU;AAAA,EACrB,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,MAAM;AACR;"}
package/dist/Chatify.css CHANGED
@@ -10,6 +10,12 @@
10
10
  opacity: 1;
11
11
  }
12
12
  }
13
+ .wxchtf-chat-group.--compact .wxchtf-aside {
14
+ width: 100%;
15
+ border-top-right-radius: 24px;
16
+ border-bottom-right-radius: 24px;
17
+ }
18
+
13
19
  .wxchtf-aside {
14
20
  flex: none;
15
21
  display: flex;
@@ -183,6 +189,11 @@
183
189
  font-size: 0.8rem;
184
190
  }
185
191
 
192
+ .wxchtf-chatify.--compact .wxchtf-chat-members-panel {
193
+ width: 100%;
194
+ box-shadow: none;
195
+ }
196
+
186
197
  .wxchtf-chatify .wxchtf-chat-members-panel {
187
198
  min-width: 300px;
188
199
  box-shadow: -4px 0px 20px -5px rgba(12, 217, 226, 0.0784313725), -2px 1px 12px rgba(0, 110, 114, 0.0588235294);
@@ -191,6 +202,16 @@
191
202
  padding-inline: 1rem;
192
203
  border-block-end: none;
193
204
  }
205
+ .wxchtf-chatify .wxchtf-chat-members-panel .wxchtf-chat-members-panel-header {
206
+ padding: 15px 20px;
207
+ line-height: 24px;
208
+ z-index: 2;
209
+ box-shadow: 0px 2px 4px 0px rgba(88, 99, 107, 0.04), 0px 1px 9px -1px rgba(88, 99, 107, 0.04), 0px 1px 2px 0px rgba(88, 99, 107, 0.06);
210
+ }
211
+ .wxchtf-chatify .wxchtf-chat-members-panel .wxchtf-chat-members-panel-header .wxchtf-chat-members-panel-title {
212
+ font-weight: 600;
213
+ font-size: 16px;
214
+ }
194
215
 
195
216
  .wxchtf-chat-list.ant-menu {
196
217
  flex: 1 1 auto;
@@ -332,6 +353,8 @@
332
353
  line-height: 24px;
333
354
  z-index: 2;
334
355
  box-shadow: 0px 2px 4px 0px rgba(88, 99, 107, 0.04), 0px 1px 9px -1px rgba(88, 99, 107, 0.04), 0px 1px 2px 0px rgba(88, 99, 107, 0.06);
356
+ border-top-left-radius: 24px;
357
+ border-top-right-radius: 24px;
335
358
  }
336
359
  .wxchtf-conversation .wxchtf-conversation-main .wxchtf-conversation-header .wxchtf-conversation-name {
337
360
  font-weight: 600;
@@ -635,6 +658,11 @@
635
658
  border-left: 1px solid rgba(0, 0, 0, 0.06);
636
659
  }
637
660
 
661
+ .wxchtf-chat-group.--compact .wxchtf-main {
662
+ border-top-left-radius: 24px;
663
+ border-bottom-left-radius: 24px;
664
+ }
665
+
638
666
  .wxchtf-main {
639
667
  flex: auto;
640
668
  display: flex;
package/dist/audit.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { Select, Skeleton, Empty, Space } from "antd";
3
3
  import classNames from "classnames";
4
- import { b as customize, aG as chatifyApi, e as useLocalizer, ap as ChatList, ag as Conversation, f as defaultLocalizer, C as CustomizeContext, L as LocalizerContext, d as Chatify, al as Avatar } from "./Chatify-CwAfN1wu.js";
4
+ import { b as customize, aG as chatifyApi, e as useLocalizer, ap as ChatList, ag as Conversation, f as defaultLocalizer, C as CustomizeContext, L as LocalizerContext, d as Chatify, al as Avatar } from "./Chatify-CP2jgo8d.js";
5
5
  import "@microsoft/signalr";
6
6
  import { useState, useEffect, useMemo, useCallback } from "react";
7
7
  import './audit.css';const MEMBER_PREFIX = "member://";
@@ -172,7 +172,8 @@ const AuditConversationPanel = customize(
172
172
  hasMore: !isFetchingNextPage && hasNextPage,
173
173
  messages,
174
174
  noReadTracking: true,
175
- onClose
175
+ onClose,
176
+ compact: false
176
177
  }
177
178
  );
178
179
  }