{"version":3,"file":"Comment.mjs","sources":["../../src/components/Comment.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n  type CommentData,\n  type CommentReaction as CommentReactionData,\n  kInternal,\n} from \"@liveblocks/core\";\nimport {\n  useRoomContextBundle,\n  useSharedContextBundle,\n} from \"@liveblocks/react\";\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\";\nimport type {\n  ComponentPropsWithoutRef,\n  FormEvent,\n  MouseEvent,\n  ReactNode,\n  SyntheticEvent,\n} from \"react\";\nimport React, {\n  forwardRef,\n  useCallback,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\";\n\nimport { CheckIcon } from \"../icons/Check\";\nimport { CrossIcon } from \"../icons/Cross\";\nimport { DeleteIcon } from \"../icons/Delete\";\nimport { EditIcon } from \"../icons/Edit\";\nimport { EllipsisIcon } from \"../icons/Ellipsis\";\nimport { EmojiAddIcon } from \"../icons/EmojiAdd\";\nimport type {\n  CommentOverrides,\n  ComposerOverrides,\n  GlobalOverrides,\n} from \"../overrides\";\nimport { useOverrides } from \"../overrides\";\nimport type { ComposerSubmitComment } from \"../primitives\";\nimport * as CommentPrimitive from \"../primitives/Comment\";\nimport type {\n  CommentBodyLinkProps,\n  CommentBodyMentionProps,\n  CommentLinkProps,\n  CommentMentionProps,\n} from \"../primitives/Comment/types\";\nimport * as ComposerPrimitive from \"../primitives/Composer\";\nimport { Timestamp } from \"../primitives/Timestamp\";\nimport { MENTION_CHARACTER } from \"../slate/plugins/mentions\";\nimport { classNames } from \"../utils/class-names\";\nimport { useRefs } from \"../utils/use-refs\";\nimport { useVisibleCallback } from \"../utils/use-visible\";\nimport { Composer } from \"./Composer\";\nimport { Avatar } from \"./internal/Avatar\";\nimport { Button } from \"./internal/Button\";\nimport { Dropdown, DropdownItem, DropdownTrigger } from \"./internal/Dropdown\";\nimport { Emoji } from \"./internal/Emoji\";\nimport { EmojiPicker, EmojiPickerTrigger } from \"./internal/EmojiPicker\";\nimport { List } from \"./internal/List\";\nimport {\n  ShortcutTooltip,\n  ShortcutTooltipKey,\n  Tooltip,\n  TooltipProvider,\n} from \"./internal/Tooltip\";\nimport { User } from \"./internal/User\";\n\nconst REACTIONS_TRUNCATE = 5;\n\nexport interface CommentProps extends ComponentPropsWithoutRef<\"div\"> {\n  /**\n   * The comment to display.\n   */\n  comment: CommentData;\n\n  /**\n   * How to show or hide the actions.\n   */\n  showActions?: boolean | \"hover\";\n\n  /**\n   * Whether to show the comment if it was deleted. If set to `false`, it will render deleted comments as `null`.\n   */\n  showDeleted?: boolean;\n\n  /**\n   * Whether to show reactions.\n   */\n  showReactions?: boolean;\n\n  /**\n   * Whether to indent the comment's content.\n   */\n  indentContent?: boolean;\n\n  /**\n   * The event handler called when the comment is edited.\n   */\n  onCommentEdit?: (comment: CommentData) => void;\n\n  /**\n   * The event handler called when the comment is deleted.\n   */\n  onCommentDelete?: (comment: CommentData) => void;\n\n  /**\n   * The event handler called when clicking on the author.\n   */\n  onAuthorClick?: (userId: string, event: MouseEvent<HTMLElement>) => void;\n\n  /**\n   * The event handler called when clicking on a mention.\n   */\n  onMentionClick?: (userId: string, event: MouseEvent<HTMLElement>) => void;\n\n  /**\n   * Override the component's strings.\n   */\n  overrides?: Partial<GlobalOverrides & CommentOverrides & ComposerOverrides>;\n\n  /**\n   * @internal\n   */\n  markThreadAsReadWhenVisible?: string;\n\n  /**\n   * @internal\n   */\n  additionalActions?: ReactNode;\n\n  /**\n   * @internal\n   */\n  additionalActionsClassName?: string;\n}\n\ninterface CommentReactionButtonProps\n  extends ComponentPropsWithoutRef<typeof Button> {\n  reaction: CommentReactionData;\n  overrides?: Partial<GlobalOverrides & CommentOverrides>;\n}\n\ninterface CommentReactionProps extends ComponentPropsWithoutRef<\"button\"> {\n  comment: CommentData;\n  reaction: CommentReactionData;\n  overrides?: Partial<GlobalOverrides & CommentOverrides>;\n}\n\ntype CommentNonInteractiveReactionProps = Omit<CommentReactionProps, \"comment\">;\n\nexport function CommentMention({\n  userId,\n  className,\n  ...props\n}: CommentBodyMentionProps & CommentMentionProps) {\n  const {\n    [kInternal]: { useCurrentUserId },\n  } = useSharedContextBundle();\n  const currentId = useCurrentUserId();\n\n  return (\n    <CommentPrimitive.Mention\n      className={classNames(\"lb-comment-mention\", className)}\n      data-self={userId === currentId ? \"\" : undefined}\n      {...props}\n    >\n      {MENTION_CHARACTER}\n      <User userId={userId} />\n    </CommentPrimitive.Mention>\n  );\n}\n\nexport function CommentLink({\n  href,\n  children,\n  className,\n  ...props\n}: CommentBodyLinkProps & CommentLinkProps) {\n  return (\n    <CommentPrimitive.Link\n      className={classNames(\"lb-comment-link\", className)}\n      href={href}\n      {...props}\n    >\n      {children}\n    </CommentPrimitive.Link>\n  );\n}\n\nexport function CommentNonInteractiveLink({\n  href: _href,\n  children,\n  className,\n  ...props\n}: CommentBodyLinkProps & CommentLinkProps) {\n  return (\n    <span className={classNames(\"lb-comment-link\", className)} {...props}>\n      {children}\n    </span>\n  );\n}\n\nconst CommentReactionButton = forwardRef<\n  HTMLButtonElement,\n  CommentReactionButtonProps\n>(({ reaction, overrides, className, ...props }, forwardedRef) => {\n  const $ = useOverrides(overrides);\n  return (\n    <Button\n      className={classNames(\"lb-comment-reaction\", className)}\n      variant=\"outline\"\n      aria-label={$.COMMENT_REACTION_DESCRIPTION(\n        reaction.emoji,\n        reaction.users.length\n      )}\n      {...props}\n      ref={forwardedRef}\n    >\n      <Emoji className=\"lb-comment-reaction-emoji\" emoji={reaction.emoji} />\n      <span className=\"lb-comment-reaction-count\">{reaction.users.length}</span>\n    </Button>\n  );\n});\n\nexport const CommentReaction = forwardRef<\n  HTMLButtonElement,\n  CommentReactionProps\n>(({ comment, reaction, overrides, disabled, ...props }, forwardedRef) => {\n  const { useAddReaction, useRemoveReaction } = useRoomContextBundle();\n  const addReaction = useAddReaction();\n  const removeReaction = useRemoveReaction();\n  const {\n    [kInternal]: { useCurrentUserId },\n  } = useSharedContextBundle();\n  const currentId = useCurrentUserId();\n  const isActive = useMemo(() => {\n    return reaction.users.some((users) => users.id === currentId);\n  }, [currentId, reaction]);\n  const $ = useOverrides(overrides);\n  const tooltipContent = useMemo(\n    () => (\n      <span>\n        {$.COMMENT_REACTION_LIST(\n          <List\n            values={reaction.users.map((users, index) => (\n              <User\n                key={users.id}\n                userId={users.id}\n                capitalize={index === 0}\n                replaceSelf\n              />\n            ))}\n            formatRemaining={$.LIST_REMAINING_USERS}\n            truncate={REACTIONS_TRUNCATE}\n          />,\n          reaction.emoji,\n          reaction.users.length\n        )}\n      </span>\n    ),\n    [$, reaction]\n  );\n\n  const handlePressedChange = useCallback(\n    (isPressed: boolean) => {\n      if (isPressed) {\n        addReaction({\n          threadId: comment.threadId,\n          commentId: comment.id,\n          emoji: reaction.emoji,\n        });\n      } else {\n        removeReaction({\n          threadId: comment.threadId,\n          commentId: comment.id,\n          emoji: reaction.emoji,\n        });\n      }\n    },\n    [addReaction, comment.threadId, comment.id, reaction.emoji, removeReaction]\n  );\n\n  return (\n    <Tooltip\n      content={tooltipContent}\n      multiline\n      className=\"lb-comment-reaction-tooltip\"\n    >\n      <TogglePrimitive.Root\n        asChild\n        pressed={isActive}\n        onPressedChange={handlePressedChange}\n        disabled={disabled}\n        ref={forwardedRef}\n      >\n        <CommentReactionButton\n          data-self={isActive ? \"\" : undefined}\n          reaction={reaction}\n          overrides={overrides}\n          {...props}\n        />\n      </TogglePrimitive.Root>\n    </Tooltip>\n  );\n});\n\nexport const CommentNonInteractiveReaction = forwardRef<\n  HTMLButtonElement,\n  CommentNonInteractiveReactionProps\n>(({ reaction, overrides, ...props }, forwardedRef) => {\n  const {\n    [kInternal]: { useCurrentUserId },\n  } = useSharedContextBundle();\n  const currentId = useCurrentUserId();\n  const isActive = useMemo(() => {\n    return reaction.users.some((users) => users.id === currentId);\n  }, [currentId, reaction]);\n\n  return (\n    <CommentReactionButton\n      disableable={false}\n      data-self={isActive ? \"\" : undefined}\n      reaction={reaction}\n      overrides={overrides}\n      {...props}\n      ref={forwardedRef}\n    />\n  );\n});\n\n/**\n * Displays a single comment.\n *\n * @example\n * <>\n *   {thread.comments.map((comment) => (\n *     <Comment key={comment.id} comment={comment} />\n *   ))}\n * </>\n */\nexport const Comment = forwardRef<HTMLDivElement, CommentProps>(\n  (\n    {\n      comment,\n      indentContent = true,\n      showDeleted,\n      showActions = \"hover\",\n      showReactions = true,\n      onAuthorClick,\n      onMentionClick,\n      onCommentEdit,\n      onCommentDelete,\n      overrides,\n      className,\n      additionalActions,\n      additionalActionsClassName,\n      markThreadAsReadWhenVisible,\n      ...props\n    },\n    forwardedRef\n  ) => {\n    const {\n      useDeleteComment,\n      useEditComment,\n      useAddReaction,\n      useRemoveReaction,\n      useMarkThreadAsRead,\n      useSelf,\n    } = useRoomContextBundle();\n    const ref = useRef<HTMLDivElement>(null);\n    const mergedRefs = useRefs(forwardedRef, ref);\n    const self = useSelf();\n    const deleteComment = useDeleteComment();\n    const editComment = useEditComment();\n    const addReaction = useAddReaction();\n    const removeReaction = useRemoveReaction();\n    const markThreadAsRead = useMarkThreadAsRead();\n    const $ = useOverrides(overrides);\n    const [isEditing, setEditing] = useState(false);\n    const [isTarget, setTarget] = useState(false);\n    const [isMoreActionOpen, setMoreActionOpen] = useState(false);\n    const [isReactionActionOpen, setReactionActionOpen] = useState(false);\n\n    const markVisibleThreadAsRead = useCallback(() => {\n      if (markThreadAsReadWhenVisible) {\n        markThreadAsRead(markThreadAsReadWhenVisible);\n      }\n    }, [markThreadAsRead, markThreadAsReadWhenVisible]);\n\n    useVisibleCallback(ref, markVisibleThreadAsRead, {\n      enabled: Boolean(markThreadAsReadWhenVisible),\n    });\n\n    const stopPropagation = useCallback((event: SyntheticEvent) => {\n      event.stopPropagation();\n    }, []);\n\n    const handleEdit = useCallback(() => {\n      setEditing(true);\n    }, []);\n\n    const handleEditCancel = useCallback(\n      (event: MouseEvent<HTMLButtonElement>) => {\n        event.stopPropagation();\n        setEditing(false);\n      },\n      []\n    );\n\n    const handleEditSubmit = useCallback(\n      ({ body }: ComposerSubmitComment, event: FormEvent<HTMLFormElement>) => {\n        // TODO: Add a way to preventDefault from within this callback, to override the default behavior (e.g. showing a confirmation dialog)\n        onCommentEdit?.(comment);\n\n        event.preventDefault();\n        setEditing(false);\n        editComment({\n          commentId: comment.id,\n          threadId: comment.threadId,\n          body,\n        });\n      },\n      [comment, editComment, onCommentEdit]\n    );\n\n    const handleDelete = useCallback(() => {\n      // TODO: Add a way to preventDefault from within this callback, to override the default behavior (e.g. showing a confirmation dialog)\n      onCommentDelete?.(comment);\n\n      deleteComment({\n        commentId: comment.id,\n        threadId: comment.threadId,\n      });\n    }, [comment, deleteComment, onCommentDelete]);\n\n    const handleAuthorClick = useCallback(\n      (event: MouseEvent<HTMLElement>) => {\n        onAuthorClick?.(comment.userId, event);\n      },\n      [comment.userId, onAuthorClick]\n    );\n\n    const handleReactionSelect = useCallback(\n      (emoji: string) => {\n        const reactionIndex = comment.reactions.findIndex(\n          (reaction) => reaction.emoji === emoji\n        );\n\n        if (\n          reactionIndex >= 0 &&\n          self?.id &&\n          comment.reactions[reactionIndex].users.some(\n            (user) => user.id === self?.id\n          )\n        ) {\n          removeReaction({\n            threadId: comment.threadId,\n            commentId: comment.id,\n            emoji,\n          });\n        } else {\n          addReaction({\n            threadId: comment.threadId,\n            commentId: comment.id,\n            emoji,\n          });\n        }\n      },\n      [\n        addReaction,\n        comment.id,\n        comment.reactions,\n        comment.threadId,\n        removeReaction,\n        self?.id,\n      ]\n    );\n\n    useEffect(() => {\n      const isWindowDefined = typeof window !== \"undefined\";\n      if (!isWindowDefined) return;\n\n      const hash = window.location.hash;\n      const commentId = hash.slice(1);\n\n      if (commentId === comment.id) {\n        setTarget(true);\n      }\n    }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n    if (!showDeleted && !comment.body) {\n      return null;\n    }\n\n    return (\n      <TooltipProvider>\n        <div\n          id={comment.id}\n          className={classNames(\n            \"lb-root lb-comment\",\n            indentContent && \"lb-comment:indent-content\",\n            showActions === \"hover\" && \"lb-comment:show-actions-hover\",\n            (isMoreActionOpen || isReactionActionOpen) &&\n              \"lb-comment:action-open\",\n            className\n          )}\n          data-deleted={!comment.body ? \"\" : undefined}\n          data-editing={isEditing ? \"\" : undefined}\n          // In some cases, `:target` doesn't work as expected so we also define it manually.\n          data-target={isTarget ? \"\" : undefined}\n          dir={$.dir}\n          {...props}\n          ref={mergedRefs}\n        >\n          <div className=\"lb-comment-header\">\n            <div className=\"lb-comment-details\">\n              <Avatar\n                className=\"lb-comment-avatar\"\n                userId={comment.userId}\n                onClick={handleAuthorClick}\n              />\n              <span className=\"lb-comment-details-labels\">\n                <User\n                  className=\"lb-comment-author\"\n                  userId={comment.userId}\n                  onClick={handleAuthorClick}\n                />\n                <span className=\"lb-comment-date\">\n                  <Timestamp\n                    locale={$.locale}\n                    date={comment.createdAt}\n                    className=\"lb-comment-date-created\"\n                  />\n                  {comment.editedAt && comment.body && (\n                    <>\n                      {\" \"}\n                      <span className=\"lb-comment-date-edited\">\n                        {$.COMMENT_EDITED}\n                      </span>\n                    </>\n                  )}\n                </span>\n              </span>\n            </div>\n            {showActions && !isEditing && (\n              <div\n                className={classNames(\n                  \"lb-comment-actions\",\n                  additionalActionsClassName\n                )}\n              >\n                {additionalActions ?? null}\n                {showReactions && (\n                  <EmojiPicker\n                    onEmojiSelect={handleReactionSelect}\n                    onOpenChange={setReactionActionOpen}\n                  >\n                    <Tooltip content={$.COMMENT_ADD_REACTION}>\n                      <EmojiPickerTrigger asChild>\n                        <Button\n                          className=\"lb-comment-action\"\n                          onClick={stopPropagation}\n                          aria-label={$.COMMENT_ADD_REACTION}\n                        >\n                          <EmojiAddIcon className=\"lb-button-icon\" />\n                        </Button>\n                      </EmojiPickerTrigger>\n                    </Tooltip>\n                  </EmojiPicker>\n                )}\n                {comment.userId === self?.id && (\n                  <Dropdown\n                    open={isMoreActionOpen}\n                    onOpenChange={setMoreActionOpen}\n                    align=\"end\"\n                    content={\n                      <>\n                        <DropdownItem\n                          onSelect={handleEdit}\n                          onClick={stopPropagation}\n                        >\n                          <EditIcon className=\"lb-dropdown-item-icon\" />\n                          {$.COMMENT_EDIT}\n                        </DropdownItem>\n                        <DropdownItem\n                          onSelect={handleDelete}\n                          onClick={stopPropagation}\n                        >\n                          <DeleteIcon className=\"lb-dropdown-item-icon\" />\n                          {$.COMMENT_DELETE}\n                        </DropdownItem>\n                      </>\n                    }\n                  >\n                    <Tooltip content={$.COMMENT_MORE}>\n                      <DropdownTrigger asChild>\n                        <Button\n                          className=\"lb-comment-action\"\n                          disabled={!comment.body}\n                          onClick={stopPropagation}\n                          aria-label={$.COMMENT_MORE}\n                        >\n                          <EllipsisIcon className=\"lb-button-icon\" />\n                        </Button>\n                      </DropdownTrigger>\n                    </Tooltip>\n                  </Dropdown>\n                )}\n              </div>\n            )}\n          </div>\n          <div className=\"lb-comment-content\">\n            {isEditing ? (\n              <Composer\n                className=\"lb-comment-composer\"\n                onComposerSubmit={handleEditSubmit}\n                defaultValue={comment.body}\n                autoFocus\n                showAttribution={false}\n                actions={\n                  <>\n                    <Tooltip\n                      content={$.COMMENT_EDIT_COMPOSER_CANCEL}\n                      aria-label={$.COMMENT_EDIT_COMPOSER_CANCEL}\n                    >\n                      <Button\n                        className=\"lb-composer-action\"\n                        onClick={handleEditCancel}\n                      >\n                        <CrossIcon className=\"lb-button-icon\" />\n                      </Button>\n                    </Tooltip>\n                    <ShortcutTooltip\n                      content={$.COMMENT_EDIT_COMPOSER_SAVE}\n                      shortcut={<ShortcutTooltipKey name=\"enter\" />}\n                    >\n                      <ComposerPrimitive.Submit asChild>\n                        <Button\n                          variant=\"primary\"\n                          className=\"lb-composer-action\"\n                          onClick={stopPropagation}\n                          aria-label={$.COMMENT_EDIT_COMPOSER_SAVE}\n                        >\n                          <CheckIcon className=\"lb-button-icon\" />\n                        </Button>\n                      </ComposerPrimitive.Submit>\n                    </ShortcutTooltip>\n                  </>\n                }\n                overrides={{\n                  COMPOSER_PLACEHOLDER: $.COMMENT_EDIT_COMPOSER_PLACEHOLDER,\n                }}\n              />\n            ) : comment.body ? (\n              <>\n                <CommentPrimitive.Body\n                  className=\"lb-comment-body\"\n                  body={comment.body}\n                  components={{\n                    Mention: ({ userId }) => (\n                      <CommentMention\n                        userId={userId}\n                        onClick={(event) => onMentionClick?.(userId, event)}\n                      />\n                    ),\n                    Link: CommentLink,\n                  }}\n                />\n                {showReactions && comment.reactions.length > 0 && (\n                  <div className=\"lb-comment-reactions\">\n                    {comment.reactions.map((reaction) => (\n                      <CommentReaction\n                        key={reaction.emoji}\n                        comment={comment}\n                        reaction={reaction}\n                        overrides={overrides}\n                      />\n                    ))}\n                    <EmojiPicker onEmojiSelect={handleReactionSelect}>\n                      <Tooltip content={$.COMMENT_ADD_REACTION}>\n                        <EmojiPickerTrigger asChild>\n                          <Button\n                            className=\"lb-comment-reaction lb-comment-reaction-add\"\n                            variant=\"outline\"\n                            onClick={stopPropagation}\n                            aria-label={$.COMMENT_ADD_REACTION}\n                          >\n                            <EmojiAddIcon className=\"lb-button-icon\" />\n                          </Button>\n                        </EmojiPickerTrigger>\n                      </Tooltip>\n                    </EmojiPicker>\n                  </div>\n                )}\n              </>\n            ) : (\n              <div className=\"lb-comment-body\">\n                <p className=\"lb-comment-deleted\">{$.COMMENT_DELETED}</p>\n              </div>\n            )}\n          </div>\n        </div>\n      </TooltipProvider>\n    );\n  }\n);\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqEA;AAmFO;AAAwB;AAC7B;AACA;AAEF;AACE;AAAM;AAC4B;AAElC;AAEA;AACG;AACsD;AACd;AACnC;AAGH;AAAK;AAGZ;AAEO;AAAqB;AAC1B;AACA;AACA;AAEF;AACE;AACG;AACmD;AAClD;AACI;AAKV;AAEO;AAAmC;AAClC;AACN;AACA;AAEF;AACE;AACG;AAAuD;AAAO;AAInE;AAEA;AAIE;AACA;AACG;AACuD;AAC9C;AACM;AACH;AACM;AACjB;AACI;AACC;AAEJ;AAAgB;AAA4C;AAC5D;AAAe;AAGtB;AAEa;AAIX;AACA;AACA;AACA;AAAM;AAC4B;AAElC;AACA;AACE;AAA4D;AAE9D;AACA;AAAuB;AAGd;AACA;AAEI;AACY;AACG;AACQ;AACX;AAEd;AACkB;AACT;AACZ;AACS;AACM;AAEnB;AAEU;AAGd;AAA4B;AAExB;AACE;AAAY;AACQ;AACC;AACH;AACjB;AAED;AAAe;AACK;AACC;AACH;AACjB;AACH;AACF;AAC0E;AAG5E;AACG;AACU;AACA;AACC;AAET;AACQ;AACE;AACQ;AACjB;AACK;AAEJ;AAC4B;AAC3B;AACA;AACI;AAKd;AAEa;AAIX;AAAM;AAC4B;AAElC;AACA;AACE;AAA4D;AAG9D;AACG;AACc;AACc;AAC3B;AACA;AACI;AACC;AAGX;AAYO;AAAgB;AAEnB;AACE;AACgB;AAChB;AACc;AACE;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACG;AAIL;AAAM;AACJ;AACA;AACA;AACA;AACA;AACA;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACE;AACE;AAA4C;AAC9C;AAGF;AAAiD;AACH;AAG9C;AACE;AAAsB;AAGxB;AACE;AAAe;AAGjB;AAAyB;AAErB;AACA;AAAgB;AAClB;AACC;AAGH;AAAyB;AAGrB;AAEA;AACA;AACA;AAAY;AACS;AACD;AAClB;AACD;AACH;AACoC;AAGtC;AAEE;AAEA;AAAc;AACO;AACD;AACnB;AAGH;AAA0B;AAEtB;AAAqC;AACvC;AAC8B;AAGhC;AAA6B;AAEzB;AAAwC;AACL;AAGnC;AAGyC;AACT;AAG9B;AAAe;AACK;AACC;AACnB;AACD;AAED;AAAY;AACQ;AACC;AACnB;AACD;AACH;AACF;AACA;AACE;AACQ;AACA;AACA;AACR;AACM;AACR;AAGF;AACE;AACA;AAAsB;AAEtB;AACA;AAEA;AACE;AAAc;AAChB;AAGF;AACE;AAAO;AAGT;AAEK;AACa;AACD;AACT;AACiB;AACU;AAEzB;AACF;AACF;AACmC;AACJ;AAEF;AACtB;AACH;AACC;AAEJ;AAAc;AACZ;AAAc;AACZ;AACW;AACM;AACP;AAEV;AAAe;AACb;AACW;AACM;AACP;AAEV;AAAe;AACb;AACW;AACI;AACJ;AAKP;AAAe;AASvB;AACY;AACT;AACA;AACF;AAIG;AACgB;AACD;AAEb;AAAmB;AACjB;AAA0B;AACxB;AACW;AACD;AACK;AAEb;AAAuB;AAO/B;AACO;AACQ;AACR;AAGD;AACW;AACD;AAER;AAAmB;AAGrB;AACW;AACD;AAER;AAAqB;AAG1B;AAGD;AAAmB;AACjB;AAAuB;AACrB;AACW;AACS;AACV;AACK;AAEb;AAAuB;AASvC;AAAc;AAEV;AACW;AACQ;AACI;AACb;AACQ;AAGZ;AACY;AACG;AAEb;AACW;AACD;AAER;AAAoB;AAGxB;AACY;AACA;AAAwB;AAAQ;AAE1C;AAAgC;AAC9B;AACS;AACE;AACD;AACK;AAEb;AAAoB;AAI7B;AAES;AACe;AAC1B;AAIC;AACW;AACI;AACF;AAEP;AACC;AACkD;AACpD;AAEI;AACR;AAGC;AAAc;AAEV;AACe;AACd;AACA;AACA;AAGH;AAA2B;AACzB;AAAmB;AACjB;AAA0B;AACxB;AACW;AACF;AACC;AACK;AAEb;AAAuB;AASrC;AAAc;AACZ;AAAY;AAKvB;AAGN;;"}