@payloadcms/richtext-lexical 3.79.0 → 3.79.1

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 (66) hide show
  1. package/dist/exports/client/bundled.css +1 -1
  2. package/dist/exports/client/index.js +22 -22
  3. package/dist/exports/client/index.js.map +4 -4
  4. package/dist/features/converters/lexicalToHtml/async/converters/heading.d.ts.map +1 -1
  5. package/dist/features/converters/lexicalToHtml/async/converters/heading.js +3 -1
  6. package/dist/features/converters/lexicalToHtml/async/converters/heading.js.map +1 -1
  7. package/dist/features/converters/lexicalToHtml/async/converters/link.d.ts.map +1 -1
  8. package/dist/features/converters/lexicalToHtml/async/converters/link.js +7 -2
  9. package/dist/features/converters/lexicalToHtml/async/converters/link.js.map +1 -1
  10. package/dist/features/converters/lexicalToHtml/async/converters/list.d.ts.map +1 -1
  11. package/dist/features/converters/lexicalToHtml/async/converters/list.js +5 -1
  12. package/dist/features/converters/lexicalToHtml/async/converters/list.js.map +1 -1
  13. package/dist/features/converters/lexicalToHtml/async/converters/table.d.ts.map +1 -1
  14. package/dist/features/converters/lexicalToHtml/async/converters/table.js +2 -1
  15. package/dist/features/converters/lexicalToHtml/async/converters/table.js.map +1 -1
  16. package/dist/features/converters/lexicalToHtml/async/converters/text.d.ts.map +1 -1
  17. package/dist/features/converters/lexicalToHtml/async/converters/text.js +2 -1
  18. package/dist/features/converters/lexicalToHtml/async/converters/text.js.map +1 -1
  19. package/dist/features/converters/lexicalToHtml/async/converters/upload.d.ts.map +1 -1
  20. package/dist/features/converters/lexicalToHtml/async/converters/upload.js +11 -10
  21. package/dist/features/converters/lexicalToHtml/async/converters/upload.js.map +1 -1
  22. package/dist/features/converters/lexicalToHtml/shared/cssColors.d.ts +5 -0
  23. package/dist/features/converters/lexicalToHtml/shared/cssColors.d.ts.map +1 -0
  24. package/dist/features/converters/lexicalToHtml/shared/cssColors.js +8 -0
  25. package/dist/features/converters/lexicalToHtml/shared/cssColors.js.map +1 -0
  26. package/dist/features/converters/lexicalToHtml/sync/converters/heading.d.ts.map +1 -1
  27. package/dist/features/converters/lexicalToHtml/sync/converters/heading.js +3 -1
  28. package/dist/features/converters/lexicalToHtml/sync/converters/heading.js.map +1 -1
  29. package/dist/features/converters/lexicalToHtml/sync/converters/link.d.ts.map +1 -1
  30. package/dist/features/converters/lexicalToHtml/sync/converters/link.js +7 -2
  31. package/dist/features/converters/lexicalToHtml/sync/converters/link.js.map +1 -1
  32. package/dist/features/converters/lexicalToHtml/sync/converters/list.d.ts.map +1 -1
  33. package/dist/features/converters/lexicalToHtml/sync/converters/list.js +5 -1
  34. package/dist/features/converters/lexicalToHtml/sync/converters/list.js.map +1 -1
  35. package/dist/features/converters/lexicalToHtml/sync/converters/table.d.ts.map +1 -1
  36. package/dist/features/converters/lexicalToHtml/sync/converters/table.js +2 -1
  37. package/dist/features/converters/lexicalToHtml/sync/converters/table.js.map +1 -1
  38. package/dist/features/converters/lexicalToHtml/sync/converters/text.d.ts.map +1 -1
  39. package/dist/features/converters/lexicalToHtml/sync/converters/text.js +2 -1
  40. package/dist/features/converters/lexicalToHtml/sync/converters/text.js.map +1 -1
  41. package/dist/features/converters/lexicalToHtml/sync/converters/upload.d.ts.map +1 -1
  42. package/dist/features/converters/lexicalToHtml/sync/converters/upload.js +11 -10
  43. package/dist/features/converters/lexicalToHtml/sync/converters/upload.js.map +1 -1
  44. package/dist/features/toolbars/fixed/client/Toolbar/index.d.ts.map +1 -1
  45. package/dist/features/toolbars/fixed/client/Toolbar/index.js +84 -141
  46. package/dist/features/toolbars/fixed/client/Toolbar/index.js.map +1 -1
  47. package/dist/features/toolbars/inline/client/Toolbar/index.d.ts.map +1 -1
  48. package/dist/features/toolbars/inline/client/Toolbar/index.js +46 -101
  49. package/dist/features/toolbars/inline/client/Toolbar/index.js.map +1 -1
  50. package/dist/features/toolbars/shared/ToolbarButton/index.d.ts +3 -1
  51. package/dist/features/toolbars/shared/ToolbarButton/index.d.ts.map +1 -1
  52. package/dist/features/toolbars/shared/ToolbarButton/index.js +38 -111
  53. package/dist/features/toolbars/shared/ToolbarButton/index.js.map +1 -1
  54. package/dist/features/toolbars/shared/ToolbarDropdown/index.d.ts +4 -10
  55. package/dist/features/toolbars/shared/ToolbarDropdown/index.d.ts.map +1 -1
  56. package/dist/features/toolbars/shared/ToolbarDropdown/index.js +10 -79
  57. package/dist/features/toolbars/shared/ToolbarDropdown/index.js.map +1 -1
  58. package/dist/features/toolbars/shared/useToolbarStates.d.ts +22 -0
  59. package/dist/features/toolbars/shared/useToolbarStates.d.ts.map +1 -0
  60. package/dist/features/toolbars/shared/useToolbarStates.js +127 -0
  61. package/dist/features/toolbars/shared/useToolbarStates.js.map +1 -0
  62. package/dist/field/Diff/converters/link.d.ts.map +1 -1
  63. package/dist/field/Diff/converters/link.js +7 -2
  64. package/dist/field/Diff/converters/link.js.map +1 -1
  65. package/dist/field/bundled.css +1 -1
  66. package/package.json +6 -6
@@ -2,13 +2,10 @@
2
2
 
3
3
  import { c as _c } from "react/compiler-runtime";
4
4
  import { jsx as _jsx } from "react/jsx-runtime";
5
- import React, { useCallback, useDeferredValue, useEffect, useMemo } from 'react';
5
+ import React, { useMemo } from 'react';
6
6
  const baseClass = 'toolbar-popup__dropdown';
7
- import { mergeRegister } from '@lexical/utils';
8
7
  import { useTranslation } from '@payloadcms/ui';
9
- import { $getSelection } from 'lexical';
10
8
  import { useEditorConfigContext } from '../../../../lexical/config/client/EditorConfigProvider.js';
11
- import { useRunDeprioritized } from '../../../../utilities/useRunDeprioritized.js';
12
9
  import { DropDown, DropDownItem } from './DropDown.js';
13
10
  const ToolbarItem = t0 => {
14
11
  const $ = _c(14);
@@ -98,94 +95,28 @@ export const ToolbarDropdown = ({
98
95
  classNames,
99
96
  editor,
100
97
  group,
98
+ groupState,
101
99
  Icon,
102
100
  itemsContainerClassNames,
103
- label,
104
- maxActiveItems,
105
- onActiveChange
101
+ label
106
102
  }) => {
107
- const [toolbarState, setToolbarState] = React.useState({
108
- activeItemKeys: [],
109
- enabledGroup: true,
110
- enabledItemKeys: []
111
- });
112
- const deferredToolbarState = useDeferredValue(toolbarState);
113
- const editorConfigContext = useEditorConfigContext();
114
103
  const {
115
104
  items,
116
105
  key: groupKey
117
106
  } = group;
118
- const runDeprioritized = useRunDeprioritized();
119
- const updateStates = useCallback(() => {
120
- editor.getEditorState().read(() => {
121
- const selection = $getSelection();
122
- if (!selection) {
123
- return;
124
- }
125
- const _activeItemKeys = [];
126
- const _activeItems = [];
127
- const _enabledItemKeys = [];
128
- for (const item of items) {
129
- if (item.isActive && (!maxActiveItems || _activeItemKeys.length < maxActiveItems)) {
130
- const isActive = item.isActive({
131
- editor,
132
- editorConfigContext,
133
- selection
134
- });
135
- if (isActive) {
136
- _activeItemKeys.push(item.key);
137
- _activeItems.push(item);
138
- }
139
- }
140
- if (item.isEnabled) {
141
- const isEnabled = item.isEnabled({
142
- editor,
143
- editorConfigContext,
144
- selection
145
- });
146
- if (isEnabled) {
147
- _enabledItemKeys.push(item.key);
148
- }
149
- } else {
150
- _enabledItemKeys.push(item.key);
151
- }
152
- }
153
- setToolbarState({
154
- activeItemKeys: _activeItemKeys,
155
- enabledGroup: group.isEnabled ? group.isEnabled({
156
- editor,
157
- editorConfigContext,
158
- selection
159
- }) : true,
160
- enabledItemKeys: _enabledItemKeys
161
- });
162
- if (onActiveChange) {
163
- onActiveChange({
164
- activeItems: _activeItems
165
- });
166
- }
167
- });
168
- }, [editor, editorConfigContext, group, items, maxActiveItems, onActiveChange]);
169
- useEffect(() => {
170
- // Run on mount in order to update states when dropdown is opened
171
- void runDeprioritized(updateStates);
172
- return mergeRegister(editor.registerUpdateListener(async () => {
173
- await runDeprioritized(updateStates);
174
- }));
175
- }, [editor, runDeprioritized, updateStates]);
176
107
  const renderedItems = useMemo(() => {
177
- return items?.length ? items.map(item_0 => /*#__PURE__*/_jsx(MemoToolbarItem, {
178
- active: deferredToolbarState.activeItemKeys.includes(item_0.key),
108
+ return items?.length ? items.map(item => /*#__PURE__*/_jsx(MemoToolbarItem, {
109
+ active: groupState.activeItemKeys.includes(item.key),
179
110
  anchorElem: anchorElem,
180
111
  editor: editor,
181
- enabled: deferredToolbarState.enabledItemKeys.includes(item_0.key),
182
- item: item_0
183
- }, item_0.key)) : null;
184
- }, [items, deferredToolbarState, anchorElem, editor]);
112
+ enabled: groupState.enabledItemKeys.includes(item.key),
113
+ item: item
114
+ }, item.key)) : null;
115
+ }, [items, groupState.activeItemKeys, groupState.enabledItemKeys, anchorElem, editor]);
185
116
  return /*#__PURE__*/_jsx(DropDown, {
186
117
  buttonAriaLabel: `${groupKey} dropdown`,
187
118
  buttonClassName: [baseClass, `${baseClass}-${groupKey}`, ...(classNames || [])].filter(Boolean).join(' '),
188
- disabled: !deferredToolbarState.enabledGroup,
119
+ disabled: !groupState.enabledGroup,
189
120
  dropdownKey: groupKey,
190
121
  Icon: Icon,
191
122
  itemsContainerClassNames: [`${baseClass}-items`, ...(itemsContainerClassNames || [])],
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["c","_c","React","useCallback","useDeferredValue","useEffect","useMemo","baseClass","mergeRegister","useTranslation","$getSelection","useEditorConfigContext","useRunDeprioritized","DropDown","DropDownItem","ToolbarItem","t0","$","active","anchorElem","editor","enabled","item","i18n","fieldProps","t1","featureClientSchemaMap","schemaPath","Component","t2","_jsx","key","title","croppedTitle","label","length","substring","Icon","ChildComponent","undefined","itemKey","tooltip","children","className","MemoToolbarItem","memo","ToolbarDropdown","classNames","group","itemsContainerClassNames","maxActiveItems","onActiveChange","toolbarState","setToolbarState","useState","activeItemKeys","enabledGroup","enabledItemKeys","deferredToolbarState","editorConfigContext","items","groupKey","runDeprioritized","updateStates","getEditorState","read","selection","_activeItemKeys","_activeItems","_enabledItemKeys","isActive","push","isEnabled","activeItems","registerUpdateListener","renderedItems","map","includes","buttonAriaLabel","buttonClassName","filter","Boolean","join","disabled","dropdownKey"],"sources":["../../../../../src/features/toolbars/shared/ToolbarDropdown/index.tsx"],"sourcesContent":["'use client'\nimport React, { useCallback, useDeferredValue, useEffect, useMemo } from 'react'\n\nconst baseClass = 'toolbar-popup__dropdown'\n\nimport type { LexicalEditor } from 'lexical'\n\nimport { mergeRegister } from '@lexical/utils'\nimport { useTranslation } from '@payloadcms/ui'\nimport { $getSelection } from 'lexical'\n\nimport type { ToolbarDropdownGroup, ToolbarGroupItem } from '../../types.js'\n\nimport { useEditorConfigContext } from '../../../../lexical/config/client/EditorConfigProvider.js'\nimport { useRunDeprioritized } from '../../../../utilities/useRunDeprioritized.js'\nimport './index.scss'\nimport { DropDown, DropDownItem } from './DropDown.js'\n\nconst ToolbarItem = ({\n active,\n anchorElem,\n editor,\n enabled,\n item,\n}: {\n active?: boolean\n anchorElem: HTMLElement\n editor: LexicalEditor\n enabled?: boolean\n item: ToolbarGroupItem\n}) => {\n const { i18n } = useTranslation<{}, string>()\n const {\n fieldProps: { featureClientSchemaMap, schemaPath },\n } = useEditorConfigContext()\n\n if (item.Component) {\n return (\n item?.Component && (\n <item.Component\n active={active}\n anchorElem={anchorElem}\n editor={editor}\n enabled={enabled}\n item={item}\n key={item.key}\n />\n )\n )\n }\n\n let title = item.key\n let croppedTitle = item.key\n if (item.label) {\n title =\n typeof item.label === 'function'\n ? item.label({ featureClientSchemaMap, i18n, schemaPath })\n : item.label\n }\n // Crop title to max. 25 characters\n if (title.length > 25) {\n croppedTitle = title.substring(0, 25) + '...'\n } else {\n croppedTitle = title\n }\n\n return (\n <DropDownItem\n active={active}\n editor={editor}\n enabled={enabled}\n Icon={item?.ChildComponent ? <item.ChildComponent /> : undefined}\n item={item}\n itemKey={item.key}\n key={item.key}\n tooltip={title}\n >\n <span className=\"text\">{croppedTitle}</span>\n </DropDownItem>\n )\n}\n\nconst MemoToolbarItem = React.memo(ToolbarItem)\n\nexport const ToolbarDropdown = ({\n anchorElem,\n classNames,\n editor,\n group,\n Icon,\n itemsContainerClassNames,\n label,\n maxActiveItems,\n onActiveChange,\n}: {\n anchorElem: HTMLElement\n classNames?: string[]\n editor: LexicalEditor\n group: ToolbarDropdownGroup\n Icon?: React.FC\n itemsContainerClassNames?: string[]\n label?: string\n /**\n * Maximum number of active items allowed. This is a performance optimization to prevent\n * unnecessary item active checks when the maximum number of active items is reached.\n */\n maxActiveItems?: number\n onActiveChange?: ({ activeItems }: { activeItems: ToolbarGroupItem[] }) => void\n}) => {\n const [toolbarState, setToolbarState] = React.useState<{\n activeItemKeys: string[]\n enabledGroup: boolean\n enabledItemKeys: string[]\n }>({\n activeItemKeys: [],\n enabledGroup: true,\n enabledItemKeys: [],\n })\n const deferredToolbarState = useDeferredValue(toolbarState)\n\n const editorConfigContext = useEditorConfigContext()\n const { items, key: groupKey } = group\n\n const runDeprioritized = useRunDeprioritized()\n\n const updateStates = useCallback(() => {\n editor.getEditorState().read(() => {\n const selection = $getSelection()\n if (!selection) {\n return\n }\n\n const _activeItemKeys: string[] = []\n const _activeItems: ToolbarGroupItem[] = []\n const _enabledItemKeys: string[] = []\n\n for (const item of items) {\n if (item.isActive && (!maxActiveItems || _activeItemKeys.length < maxActiveItems)) {\n const isActive = item.isActive({ editor, editorConfigContext, selection })\n if (isActive) {\n _activeItemKeys.push(item.key)\n _activeItems.push(item)\n }\n }\n if (item.isEnabled) {\n const isEnabled = item.isEnabled({ editor, editorConfigContext, selection })\n if (isEnabled) {\n _enabledItemKeys.push(item.key)\n }\n } else {\n _enabledItemKeys.push(item.key)\n }\n }\n\n setToolbarState({\n activeItemKeys: _activeItemKeys,\n enabledGroup: group.isEnabled\n ? group.isEnabled({ editor, editorConfigContext, selection })\n : true,\n enabledItemKeys: _enabledItemKeys,\n })\n\n if (onActiveChange) {\n onActiveChange({ activeItems: _activeItems })\n }\n })\n }, [editor, editorConfigContext, group, items, maxActiveItems, onActiveChange])\n\n useEffect(() => {\n // Run on mount in order to update states when dropdown is opened\n void runDeprioritized(updateStates)\n\n return mergeRegister(\n editor.registerUpdateListener(async () => {\n await runDeprioritized(updateStates)\n }),\n )\n }, [editor, runDeprioritized, updateStates])\n\n const renderedItems = useMemo(() => {\n return items?.length\n ? items.map((item) => (\n <MemoToolbarItem\n active={deferredToolbarState.activeItemKeys.includes(item.key)}\n anchorElem={anchorElem}\n editor={editor}\n enabled={deferredToolbarState.enabledItemKeys.includes(item.key)}\n item={item}\n key={item.key}\n />\n ))\n : null\n }, [items, deferredToolbarState, anchorElem, editor])\n\n return (\n <DropDown\n buttonAriaLabel={`${groupKey} dropdown`}\n buttonClassName={[baseClass, `${baseClass}-${groupKey}`, ...(classNames || [])]\n .filter(Boolean)\n .join(' ')}\n disabled={!deferredToolbarState.enabledGroup}\n dropdownKey={groupKey}\n Icon={Icon}\n itemsContainerClassNames={[`${baseClass}-items`, ...(itemsContainerClassNames || [])]}\n key={groupKey}\n label={label}\n >\n {renderedItems}\n </DropDown>\n )\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["c","_c","React","useMemo","baseClass","useTranslation","useEditorConfigContext","DropDown","DropDownItem","ToolbarItem","t0","$","active","anchorElem","editor","enabled","item","i18n","fieldProps","t1","featureClientSchemaMap","schemaPath","Component","t2","_jsx","key","title","croppedTitle","label","length","substring","Icon","ChildComponent","undefined","itemKey","tooltip","children","className","MemoToolbarItem","memo","ToolbarDropdown","classNames","group","groupState","itemsContainerClassNames","items","groupKey","renderedItems","map","activeItemKeys","includes","enabledItemKeys","buttonAriaLabel","buttonClassName","filter","Boolean","join","disabled","enabledGroup","dropdownKey"],"sources":["../../../../../src/features/toolbars/shared/ToolbarDropdown/index.tsx"],"sourcesContent":["'use client'\nimport React, { useMemo } from 'react'\n\nconst baseClass = 'toolbar-popup__dropdown'\n\nimport type { LexicalEditor } from 'lexical'\n\nimport { useTranslation } from '@payloadcms/ui'\n\nimport type { ToolbarDropdownGroup, ToolbarGroupItem } from '../../types.js'\nimport type { ToolbarGroupState } from '../useToolbarStates.js'\n\nimport { useEditorConfigContext } from '../../../../lexical/config/client/EditorConfigProvider.js'\nimport './index.scss'\nimport { DropDown, DropDownItem } from './DropDown.js'\n\nconst ToolbarItem = ({\n active,\n anchorElem,\n editor,\n enabled,\n item,\n}: {\n active?: boolean\n anchorElem: HTMLElement\n editor: LexicalEditor\n enabled?: boolean\n item: ToolbarGroupItem\n}) => {\n const { i18n } = useTranslation<{}, string>()\n const {\n fieldProps: { featureClientSchemaMap, schemaPath },\n } = useEditorConfigContext()\n\n if (item.Component) {\n return (\n item?.Component && (\n <item.Component\n active={active}\n anchorElem={anchorElem}\n editor={editor}\n enabled={enabled}\n item={item}\n key={item.key}\n />\n )\n )\n }\n\n let title = item.key\n let croppedTitle = item.key\n if (item.label) {\n title =\n typeof item.label === 'function'\n ? item.label({ featureClientSchemaMap, i18n, schemaPath })\n : item.label\n }\n if (title.length > 25) {\n croppedTitle = title.substring(0, 25) + '...'\n } else {\n croppedTitle = title\n }\n\n return (\n <DropDownItem\n active={active}\n editor={editor}\n enabled={enabled}\n Icon={item?.ChildComponent ? <item.ChildComponent /> : undefined}\n item={item}\n itemKey={item.key}\n key={item.key}\n tooltip={title}\n >\n <span className=\"text\">{croppedTitle}</span>\n </DropDownItem>\n )\n}\n\nconst MemoToolbarItem = React.memo(ToolbarItem)\n\nexport const ToolbarDropdown = ({\n anchorElem,\n classNames,\n editor,\n group,\n groupState,\n Icon,\n itemsContainerClassNames,\n label,\n}: {\n anchorElem: HTMLElement\n classNames?: string[]\n editor: LexicalEditor\n group: ToolbarDropdownGroup\n groupState: ToolbarGroupState\n Icon?: React.FC\n itemsContainerClassNames?: string[]\n label?: string\n}) => {\n const { items, key: groupKey } = group\n\n const renderedItems = useMemo(() => {\n return items?.length\n ? items.map((item) => (\n <MemoToolbarItem\n active={groupState.activeItemKeys.includes(item.key)}\n anchorElem={anchorElem}\n editor={editor}\n enabled={groupState.enabledItemKeys.includes(item.key)}\n item={item}\n key={item.key}\n />\n ))\n : null\n }, [items, groupState.activeItemKeys, groupState.enabledItemKeys, anchorElem, editor])\n\n return (\n <DropDown\n buttonAriaLabel={`${groupKey} dropdown`}\n buttonClassName={[baseClass, `${baseClass}-${groupKey}`, ...(classNames || [])]\n .filter(Boolean)\n .join(' ')}\n disabled={!groupState.enabledGroup}\n dropdownKey={groupKey}\n Icon={Icon}\n itemsContainerClassNames={[`${baseClass}-items`, ...(itemsContainerClassNames || [])]}\n key={groupKey}\n label={label}\n >\n {renderedItems}\n </DropDown>\n )\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,22 @@
1
+ import type { LexicalEditor } from 'lexical';
2
+ import type { ToolbarGroup, ToolbarGroupItem } from '../types.js';
3
+ export interface ToolbarItemState {
4
+ active: boolean;
5
+ enabled: boolean;
6
+ }
7
+ export interface ToolbarGroupState {
8
+ activeItemKeys: string[];
9
+ activeItems: ToolbarGroupItem[];
10
+ enabledGroup: boolean;
11
+ enabledItemKeys: string[];
12
+ }
13
+ export interface ToolbarStates {
14
+ groupStates: Map<string, ToolbarGroupState>;
15
+ itemStates: Map<string, ToolbarItemState>;
16
+ }
17
+ /**
18
+ * Subscribes once to `editor.registerUpdateListener` and computes
19
+ * isActive / isEnabled for every toolbar item in a read.
20
+ */
21
+ export declare function useToolbarStates(editor: LexicalEditor, groups: ToolbarGroup[] | undefined): ToolbarStates;
22
+ //# sourceMappingURL=useToolbarStates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useToolbarStates.d.ts","sourceRoot":"","sources":["../../../../src/features/toolbars/shared/useToolbarStates.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAM5C,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAKjE,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,WAAW,EAAE,gBAAgB,EAAE,CAAA;IAC/B,YAAY,EAAE,OAAO,CAAA;IACrB,eAAe,EAAE,MAAM,EAAE,CAAA;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;IAC3C,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;CAC1C;AAgCD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,YAAY,EAAE,GAAG,SAAS,GACjC,aAAa,CAyFf"}
@@ -0,0 +1,127 @@
1
+ 'use client';
2
+
3
+ import { mergeRegister } from '@lexical/utils';
4
+ import { $getSelection } from 'lexical';
5
+ import { useCallback, useDeferredValue, useEffect, useRef, useState } from 'react';
6
+ import { useEditorConfigContext } from '../../../lexical/config/client/EditorConfigProvider.js';
7
+ import { useRunDeprioritized } from '../../../utilities/useRunDeprioritized.js';
8
+ /**
9
+ * Build default states where every item is enabled and nothing is active.
10
+ * Used as the initial value so toolbar groups render immediately on mount
11
+ * instead of waiting for the first updateStates call.
12
+ */
13
+ function buildDefaultStates(groups) {
14
+ const itemStates = new Map();
15
+ const groupStates = new Map();
16
+ if (!groups?.length) {
17
+ return {
18
+ groupStates,
19
+ itemStates
20
+ };
21
+ }
22
+ for (const group of groups) {
23
+ const enabledItemKeys = [];
24
+ for (const item of group.items) {
25
+ itemStates.set(item.key, {
26
+ active: false,
27
+ enabled: true
28
+ });
29
+ enabledItemKeys.push(item.key);
30
+ }
31
+ groupStates.set(group.key, {
32
+ activeItemKeys: [],
33
+ activeItems: [],
34
+ enabledGroup: true,
35
+ enabledItemKeys
36
+ });
37
+ }
38
+ return {
39
+ groupStates,
40
+ itemStates
41
+ };
42
+ }
43
+ /**
44
+ * Subscribes once to `editor.registerUpdateListener` and computes
45
+ * isActive / isEnabled for every toolbar item in a read.
46
+ */
47
+ export function useToolbarStates(editor, groups) {
48
+ const [states, setStates] = useState(() => buildDefaultStates(groups));
49
+ const deferredStates = useDeferredValue(states);
50
+ const editorConfigContext = useEditorConfigContext();
51
+ const editorConfigContextRef = useRef(editorConfigContext);
52
+ editorConfigContextRef.current = editorConfigContext;
53
+ const groupsRef = useRef(groups);
54
+ groupsRef.current = groups;
55
+ const runDeprioritized = useRunDeprioritized();
56
+ const updateStates = useCallback(() => {
57
+ editor.getEditorState().read(() => {
58
+ const selection = $getSelection();
59
+ if (!selection) {
60
+ return;
61
+ }
62
+ const currentGroups = groupsRef.current;
63
+ if (!currentGroups?.length) {
64
+ return;
65
+ }
66
+ const ctx = editorConfigContextRef.current;
67
+ const newItemStates = new Map();
68
+ const newGroupStates = new Map();
69
+ for (const group of currentGroups) {
70
+ const activeItemKeys = [];
71
+ const activeItems = [];
72
+ const enabledItemKeys = [];
73
+ const maxActive = group.type === 'dropdown' ? group.maxActiveItems ?? 1 : undefined;
74
+ for (const item of group.items) {
75
+ const isActive = item.isActive ? (!maxActive || activeItemKeys.length < maxActive) && item.isActive({
76
+ editor,
77
+ editorConfigContext: ctx,
78
+ selection
79
+ }) : false;
80
+ const isEnabled = item.isEnabled ? item.isEnabled({
81
+ editor,
82
+ editorConfigContext: ctx,
83
+ selection
84
+ }) : true;
85
+ if (isActive) {
86
+ activeItemKeys.push(item.key);
87
+ activeItems.push(item);
88
+ }
89
+ if (isEnabled) {
90
+ enabledItemKeys.push(item.key);
91
+ }
92
+ newItemStates.set(item.key, {
93
+ active: isActive,
94
+ enabled: isEnabled
95
+ });
96
+ }
97
+ const enabledGroup = group.type === 'dropdown' && group.isEnabled ? group.isEnabled({
98
+ editor,
99
+ editorConfigContext: ctx,
100
+ selection
101
+ }) : true;
102
+ newGroupStates.set(group.key, {
103
+ activeItemKeys,
104
+ activeItems,
105
+ enabledGroup,
106
+ enabledItemKeys
107
+ });
108
+ }
109
+ setStates({
110
+ groupStates: newGroupStates,
111
+ itemStates: newItemStates
112
+ });
113
+ });
114
+ }, [editor]);
115
+ useEffect(() => {
116
+ void runDeprioritized(updateStates);
117
+ const listener = () => runDeprioritized(updateStates);
118
+ const cleanup = mergeRegister(editor.registerUpdateListener(listener));
119
+ document.addEventListener('mouseup', listener);
120
+ return () => {
121
+ cleanup();
122
+ document.removeEventListener('mouseup', listener);
123
+ };
124
+ }, [editor, runDeprioritized, updateStates]);
125
+ return deferredStates;
126
+ }
127
+ //# sourceMappingURL=useToolbarStates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useToolbarStates.js","names":["mergeRegister","$getSelection","useCallback","useDeferredValue","useEffect","useRef","useState","useEditorConfigContext","useRunDeprioritized","buildDefaultStates","groups","itemStates","Map","groupStates","length","group","enabledItemKeys","item","items","set","key","active","enabled","push","activeItemKeys","activeItems","enabledGroup","useToolbarStates","editor","states","setStates","deferredStates","editorConfigContext","editorConfigContextRef","current","groupsRef","runDeprioritized","updateStates","getEditorState","read","selection","currentGroups","ctx","newItemStates","newGroupStates","maxActive","type","maxActiveItems","undefined","isActive","isEnabled","listener","cleanup","registerUpdateListener","document","addEventListener","removeEventListener"],"sources":["../../../../src/features/toolbars/shared/useToolbarStates.ts"],"sourcesContent":["'use client'\nimport type { LexicalEditor } from 'lexical'\n\nimport { mergeRegister } from '@lexical/utils'\nimport { $getSelection } from 'lexical'\nimport { useCallback, useDeferredValue, useEffect, useRef, useState } from 'react'\n\nimport type { ToolbarGroup, ToolbarGroupItem } from '../types.js'\n\nimport { useEditorConfigContext } from '../../../lexical/config/client/EditorConfigProvider.js'\nimport { useRunDeprioritized } from '../../../utilities/useRunDeprioritized.js'\n\nexport interface ToolbarItemState {\n active: boolean\n enabled: boolean\n}\n\nexport interface ToolbarGroupState {\n activeItemKeys: string[]\n activeItems: ToolbarGroupItem[]\n enabledGroup: boolean\n enabledItemKeys: string[]\n}\n\nexport interface ToolbarStates {\n groupStates: Map<string, ToolbarGroupState>\n itemStates: Map<string, ToolbarItemState>\n}\n\n/**\n * Build default states where every item is enabled and nothing is active.\n * Used as the initial value so toolbar groups render immediately on mount\n * instead of waiting for the first updateStates call.\n */\nfunction buildDefaultStates(groups: ToolbarGroup[] | undefined): ToolbarStates {\n const itemStates = new Map<string, ToolbarItemState>()\n const groupStates = new Map<string, ToolbarGroupState>()\n\n if (!groups?.length) {\n return { groupStates, itemStates }\n }\n\n for (const group of groups) {\n const enabledItemKeys: string[] = []\n for (const item of group.items) {\n itemStates.set(item.key, { active: false, enabled: true })\n enabledItemKeys.push(item.key)\n }\n groupStates.set(group.key, {\n activeItemKeys: [],\n activeItems: [],\n enabledGroup: true,\n enabledItemKeys,\n })\n }\n\n return { groupStates, itemStates }\n}\n\n/**\n * Subscribes once to `editor.registerUpdateListener` and computes\n * isActive / isEnabled for every toolbar item in a read.\n */\nexport function useToolbarStates(\n editor: LexicalEditor,\n groups: ToolbarGroup[] | undefined,\n): ToolbarStates {\n const [states, setStates] = useState<ToolbarStates>(() => buildDefaultStates(groups))\n const deferredStates = useDeferredValue(states)\n\n const editorConfigContext = useEditorConfigContext()\n const editorConfigContextRef = useRef(editorConfigContext)\n editorConfigContextRef.current = editorConfigContext\n\n const groupsRef = useRef(groups)\n groupsRef.current = groups\n\n const runDeprioritized = useRunDeprioritized()\n\n const updateStates = useCallback(() => {\n editor.getEditorState().read(() => {\n const selection = $getSelection()\n if (!selection) {\n return\n }\n\n const currentGroups = groupsRef.current\n if (!currentGroups?.length) {\n return\n }\n\n const ctx = editorConfigContextRef.current\n const newItemStates = new Map<string, ToolbarItemState>()\n const newGroupStates = new Map<string, ToolbarGroupState>()\n\n for (const group of currentGroups) {\n const activeItemKeys: string[] = []\n const activeItems: ToolbarGroupItem[] = []\n const enabledItemKeys: string[] = []\n\n const maxActive = group.type === 'dropdown' ? (group.maxActiveItems ?? 1) : undefined\n\n for (const item of group.items) {\n const isActive = item.isActive\n ? (!maxActive || activeItemKeys.length < maxActive) &&\n item.isActive({ editor, editorConfigContext: ctx, selection })\n : false\n\n const isEnabled = item.isEnabled\n ? item.isEnabled({ editor, editorConfigContext: ctx, selection })\n : true\n\n if (isActive) {\n activeItemKeys.push(item.key)\n activeItems.push(item)\n }\n if (isEnabled) {\n enabledItemKeys.push(item.key)\n }\n\n newItemStates.set(item.key, { active: isActive, enabled: isEnabled })\n }\n\n const enabledGroup =\n group.type === 'dropdown' && group.isEnabled\n ? group.isEnabled({ editor, editorConfigContext: ctx, selection })\n : true\n\n newGroupStates.set(group.key, {\n activeItemKeys,\n activeItems,\n enabledGroup,\n enabledItemKeys,\n })\n }\n\n setStates({ groupStates: newGroupStates, itemStates: newItemStates })\n })\n }, [editor])\n\n useEffect(() => {\n void runDeprioritized(updateStates)\n\n const listener = () => runDeprioritized(updateStates)\n\n const cleanup = mergeRegister(editor.registerUpdateListener(listener))\n document.addEventListener('mouseup', listener)\n\n return () => {\n cleanup()\n document.removeEventListener('mouseup', listener)\n }\n }, [editor, runDeprioritized, updateStates])\n\n return deferredStates\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../../../src/field/Diff/converters/link.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,mBAAmB,EACnB,cAAc,EACf,MAAM,2DAA2D,CAAA;AAClE,OAAO,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAEvF,eAAO,MAAM,0BAA0B,EAAE,CAAC,IAAI,EAAE;IAC9C,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE;QACzB,QAAQ,EAAE,kBAAkB,CAAA;QAC5B,QAAQ,CAAC,EAAE,cAAc,CAAA;KAC1B,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAA;CAC/B,KAAK,mBAAmB,CAAC,sBAAsB,GAAG,kBAAkB,CA6CnE,CAAA"}
1
+ {"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../../../src/field/Diff/converters/link.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,mBAAmB,EACnB,cAAc,EACf,MAAM,2DAA2D,CAAA;AAClE,OAAO,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAEvF,eAAO,MAAM,0BAA0B,EAAE,CAAC,IAAI,EAAE;IAC9C,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE;QACzB,QAAQ,EAAE,kBAAkB,CAAA;QAC5B,QAAQ,CAAC,EAAE,cAAc,CAAA;KAC1B,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAA;CAC/B,KAAK,mBAAmB,CAAC,sBAAsB,GAAG,kBAAkB,CAkDnE,CAAA"}
@@ -1,4 +1,6 @@
1
1
  import { createHash } from 'crypto';
2
+ import escapeHTML from 'escape-html';
3
+ import { sanitizeUrl } from 'payload/shared';
2
4
  export const LinkDiffHTMLConverterAsync = ({
3
5
  internalDocToHref
4
6
  }) => ({
@@ -12,7 +14,8 @@ export const LinkDiffHTMLConverterAsync = ({
12
14
  })).join('');
13
15
  // hash fields to ensure they are diffed if they change
14
16
  const nodeFieldsHash = createHash('sha256').update(JSON.stringify(node.fields)).digest('hex');
15
- return `<a${providedStyleTag} data-fields-hash="${nodeFieldsHash}" data-enable-match="true" href="${node.fields.url}"${node.fields.newTab ? ' rel="noopener noreferrer" target="_blank"' : ''}>
17
+ const href = escapeHTML(sanitizeUrl(node.fields.url ?? ''));
18
+ return `<a${providedStyleTag} data-fields-hash="${nodeFieldsHash}" data-enable-match="true" href="${href}"${node.fields.newTab ? ' rel="noopener noreferrer" target="_blank"' : ''}>
16
19
  ${children}
17
20
  </a>`;
18
21
  },
@@ -33,13 +36,15 @@ export const LinkDiffHTMLConverterAsync = ({
33
36
  populate
34
37
  });
35
38
  } else {
39
+ // eslint-disable-next-line no-console
36
40
  console.error('Lexical => HTML converter: Link converter: found internal link, but internalDocToHref is not provided');
37
41
  href = '#'; // fallback
38
42
  }
39
43
  }
40
44
  // hash fields to ensure they are diffed if they change
41
45
  const nodeFieldsHash = createHash('sha256').update(JSON.stringify(node.fields ?? {})).digest('hex');
42
- return `<a${providedStyleTag} data-fields-hash="${nodeFieldsHash}" data-enable-match="true" href="${href}"${node.fields.newTab ? ' rel="noopener noreferrer" target="_blank"' : ''}>
46
+ const safeHref = escapeHTML(sanitizeUrl(href));
47
+ return `<a${providedStyleTag} data-fields-hash="${nodeFieldsHash}" data-enable-match="true" href="${safeHref}"${node.fields.newTab ? ' rel="noopener noreferrer" target="_blank"' : ''}>
43
48
  ${children}
44
49
  </a>`;
45
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"link.js","names":["createHash","LinkDiffHTMLConverterAsync","internalDocToHref","autolink","node","nodesToHTML","providedStyleTag","children","nodes","join","nodeFieldsHash","update","JSON","stringify","fields","digest","url","newTab","link","populate","href","linkType","linkNode","console","error"],"sources":["../../../../src/field/Diff/converters/link.ts"],"sourcesContent":["import { createHash } from 'crypto'\n\nimport type {\n HTMLConvertersAsync,\n HTMLPopulateFn,\n} from '../../../features/converters/lexicalToHtml/async/types.js'\nimport type { SerializedAutoLinkNode, SerializedLinkNode } from '../../../nodeTypes.js'\n\nexport const LinkDiffHTMLConverterAsync: (args: {\n internalDocToHref?: (args: {\n linkNode: SerializedLinkNode\n populate?: HTMLPopulateFn\n }) => Promise<string> | string\n}) => HTMLConvertersAsync<SerializedAutoLinkNode | SerializedLinkNode> = ({\n internalDocToHref,\n}) => ({\n autolink: async ({ node, nodesToHTML, providedStyleTag }) => {\n const children = (\n await nodesToHTML({\n nodes: node.children,\n })\n ).join('')\n\n // hash fields to ensure they are diffed if they change\n const nodeFieldsHash = createHash('sha256').update(JSON.stringify(node.fields)).digest('hex')\n\n return `<a${providedStyleTag} data-fields-hash=\"${nodeFieldsHash}\" data-enable-match=\"true\" href=\"${node.fields.url}\"${node.fields.newTab ? ' rel=\"noopener noreferrer\" target=\"_blank\"' : ''}>\n ${children}\n </a>`\n },\n link: async ({ node, nodesToHTML, populate, providedStyleTag }) => {\n const children = (\n await nodesToHTML({\n nodes: node.children,\n })\n ).join('')\n\n let href: string = node.fields.url ?? ''\n if (node.fields.linkType === 'internal') {\n if (internalDocToHref) {\n href = await internalDocToHref({ linkNode: node, populate })\n } else {\n console.error(\n 'Lexical => HTML converter: Link converter: found internal link, but internalDocToHref is not provided',\n )\n href = '#' // fallback\n }\n }\n\n // hash fields to ensure they are diffed if they change\n const nodeFieldsHash = createHash('sha256')\n .update(JSON.stringify(node.fields ?? {}))\n .digest('hex')\n\n return `<a${providedStyleTag} data-fields-hash=\"${nodeFieldsHash}\" data-enable-match=\"true\" href=\"${href}\"${node.fields.newTab ? ' rel=\"noopener noreferrer\" target=\"_blank\"' : ''}>\n ${children}\n </a>`\n },\n})\n"],"mappings":"AAAA,SAASA,UAAU,QAAQ;AAQ3B,OAAO,MAAMC,0BAAA,GAK4DA,CAAC;EACxEC;AAAiB,CAClB,MAAM;EACLC,QAAA,EAAU,MAAAA,CAAO;IAAEC,IAAI;IAAEC,WAAW;IAAEC;EAAgB,CAAE;IACtD,MAAMC,QAAA,GAAW,CACf,MAAMF,WAAA,CAAY;MAChBG,KAAA,EAAOJ,IAAA,CAAKG;IACd,EAAC,EACDE,IAAI,CAAC;IAEP;IACA,MAAMC,cAAA,GAAiBV,UAAA,CAAW,UAAUW,MAAM,CAACC,IAAA,CAAKC,SAAS,CAACT,IAAA,CAAKU,MAAM,GAAGC,MAAM,CAAC;IAEvF,OAAO,KAAKT,gBAAA,sBAAsCI,cAAA,oCAAkDN,IAAA,CAAKU,MAAM,CAACE,GAAG,IAAIZ,IAAA,CAAKU,MAAM,CAACG,MAAM,GAAG,+CAA+C;UACrLV,QAAA;WACC;EACT;EACAW,IAAA,EAAM,MAAAA,CAAO;IAAEd,IAAI;IAAEC,WAAW;IAAEc,QAAQ;IAAEb;EAAgB,CAAE;IAC5D,MAAMC,QAAA,GAAW,CACf,MAAMF,WAAA,CAAY;MAChBG,KAAA,EAAOJ,IAAA,CAAKG;IACd,EAAC,EACDE,IAAI,CAAC;IAEP,IAAIW,IAAA,GAAehB,IAAA,CAAKU,MAAM,CAACE,GAAG,IAAI;IACtC,IAAIZ,IAAA,CAAKU,MAAM,CAACO,QAAQ,KAAK,YAAY;MACvC,IAAInB,iBAAA,EAAmB;QACrBkB,IAAA,GAAO,MAAMlB,iBAAA,CAAkB;UAAEoB,QAAA,EAAUlB,IAAA;UAAMe;QAAS;MAC5D,OAAO;QACLI,OAAA,CAAQC,KAAK,CACX;QAEFJ,IAAA,GAAO,KAAI;MACb;IACF;IAEA;IACA,MAAMV,cAAA,GAAiBV,UAAA,CAAW,UAC/BW,MAAM,CAACC,IAAA,CAAKC,SAAS,CAACT,IAAA,CAAKU,MAAM,IAAI,CAAC,IACtCC,MAAM,CAAC;IAEV,OAAO,KAAKT,gBAAA,sBAAsCI,cAAA,oCAAkDU,IAAA,IAAQhB,IAAA,CAAKU,MAAM,CAACG,MAAM,GAAG,+CAA+C;UAC1KV,QAAA;WACC;EACT;AACF","ignoreList":[]}
1
+ {"version":3,"file":"link.js","names":["createHash","escapeHTML","sanitizeUrl","LinkDiffHTMLConverterAsync","internalDocToHref","autolink","node","nodesToHTML","providedStyleTag","children","nodes","join","nodeFieldsHash","update","JSON","stringify","fields","digest","href","url","newTab","link","populate","linkType","linkNode","console","error","safeHref"],"sources":["../../../../src/field/Diff/converters/link.ts"],"sourcesContent":["import { createHash } from 'crypto'\nimport escapeHTML from 'escape-html'\nimport { sanitizeUrl } from 'payload/shared'\n\nimport type {\n HTMLConvertersAsync,\n HTMLPopulateFn,\n} from '../../../features/converters/lexicalToHtml/async/types.js'\nimport type { SerializedAutoLinkNode, SerializedLinkNode } from '../../../nodeTypes.js'\n\nexport const LinkDiffHTMLConverterAsync: (args: {\n internalDocToHref?: (args: {\n linkNode: SerializedLinkNode\n populate?: HTMLPopulateFn\n }) => Promise<string> | string\n}) => HTMLConvertersAsync<SerializedAutoLinkNode | SerializedLinkNode> = ({\n internalDocToHref,\n}) => ({\n autolink: async ({ node, nodesToHTML, providedStyleTag }) => {\n const children = (\n await nodesToHTML({\n nodes: node.children,\n })\n ).join('')\n\n // hash fields to ensure they are diffed if they change\n const nodeFieldsHash = createHash('sha256').update(JSON.stringify(node.fields)).digest('hex')\n\n const href = escapeHTML(sanitizeUrl(node.fields.url ?? ''))\n\n return `<a${providedStyleTag} data-fields-hash=\"${nodeFieldsHash}\" data-enable-match=\"true\" href=\"${href}\"${node.fields.newTab ? ' rel=\"noopener noreferrer\" target=\"_blank\"' : ''}>\n ${children}\n </a>`\n },\n link: async ({ node, nodesToHTML, populate, providedStyleTag }) => {\n const children = (\n await nodesToHTML({\n nodes: node.children,\n })\n ).join('')\n\n let href: string = node.fields.url ?? ''\n if (node.fields.linkType === 'internal') {\n if (internalDocToHref) {\n href = await internalDocToHref({ linkNode: node, populate })\n } else {\n // eslint-disable-next-line no-console\n console.error(\n 'Lexical => HTML converter: Link converter: found internal link, but internalDocToHref is not provided',\n )\n href = '#' // fallback\n }\n }\n\n // hash fields to ensure they are diffed if they change\n const nodeFieldsHash = createHash('sha256')\n .update(JSON.stringify(node.fields ?? {}))\n .digest('hex')\n\n const safeHref = escapeHTML(sanitizeUrl(href))\n\n return `<a${providedStyleTag} data-fields-hash=\"${nodeFieldsHash}\" data-enable-match=\"true\" href=\"${safeHref}\"${node.fields.newTab ? ' rel=\"noopener noreferrer\" target=\"_blank\"' : ''}>\n ${children}\n </a>`\n },\n})\n"],"mappings":"AAAA,SAASA,UAAU,QAAQ;AAC3B,OAAOC,UAAA,MAAgB;AACvB,SAASC,WAAW,QAAQ;AAQ5B,OAAO,MAAMC,0BAAA,GAK4DA,CAAC;EACxEC;AAAiB,CAClB,MAAM;EACLC,QAAA,EAAU,MAAAA,CAAO;IAAEC,IAAI;IAAEC,WAAW;IAAEC;EAAgB,CAAE;IACtD,MAAMC,QAAA,GAAW,CACf,MAAMF,WAAA,CAAY;MAChBG,KAAA,EAAOJ,IAAA,CAAKG;IACd,EAAC,EACDE,IAAI,CAAC;IAEP;IACA,MAAMC,cAAA,GAAiBZ,UAAA,CAAW,UAAUa,MAAM,CAACC,IAAA,CAAKC,SAAS,CAACT,IAAA,CAAKU,MAAM,GAAGC,MAAM,CAAC;IAEvF,MAAMC,IAAA,GAAOjB,UAAA,CAAWC,WAAA,CAAYI,IAAA,CAAKU,MAAM,CAACG,GAAG,IAAI;IAEvD,OAAO,KAAKX,gBAAA,sBAAsCI,cAAA,oCAAkDM,IAAA,IAAQZ,IAAA,CAAKU,MAAM,CAACI,MAAM,GAAG,+CAA+C;UAC1KX,QAAA;WACC;EACT;EACAY,IAAA,EAAM,MAAAA,CAAO;IAAEf,IAAI;IAAEC,WAAW;IAAEe,QAAQ;IAAEd;EAAgB,CAAE;IAC5D,MAAMC,QAAA,GAAW,CACf,MAAMF,WAAA,CAAY;MAChBG,KAAA,EAAOJ,IAAA,CAAKG;IACd,EAAC,EACDE,IAAI,CAAC;IAEP,IAAIO,IAAA,GAAeZ,IAAA,CAAKU,MAAM,CAACG,GAAG,IAAI;IACtC,IAAIb,IAAA,CAAKU,MAAM,CAACO,QAAQ,KAAK,YAAY;MACvC,IAAInB,iBAAA,EAAmB;QACrBc,IAAA,GAAO,MAAMd,iBAAA,CAAkB;UAAEoB,QAAA,EAAUlB,IAAA;UAAMgB;QAAS;MAC5D,OAAO;QACL;QACAG,OAAA,CAAQC,KAAK,CACX;QAEFR,IAAA,GAAO,KAAI;MACb;IACF;IAEA;IACA,MAAMN,cAAA,GAAiBZ,UAAA,CAAW,UAC/Ba,MAAM,CAACC,IAAA,CAAKC,SAAS,CAACT,IAAA,CAAKU,MAAM,IAAI,CAAC,IACtCC,MAAM,CAAC;IAEV,MAAMU,QAAA,GAAW1B,UAAA,CAAWC,WAAA,CAAYgB,IAAA;IAExC,OAAO,KAAKV,gBAAA,sBAAsCI,cAAA,oCAAkDe,QAAA,IAAYrB,IAAA,CAAKU,MAAM,CAACI,MAAM,GAAG,+CAA+C;UAC9KX,QAAA;WACC;EACT;AACF","ignoreList":[]}