@ixo/editor 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +345 -0
- package/dist/blocks/index.d.ts +85 -0
- package/dist/blocks/index.d.ts.map +1 -0
- package/dist/blocks/index.js +50 -0
- package/dist/blocks/list/ListBlock.d.ts +59 -0
- package/dist/blocks/list/ListBlock.d.ts.map +1 -0
- package/dist/blocks/list/ListBlock.js +51 -0
- package/dist/blocks/list/ListBlockToolbar.d.ts +9 -0
- package/dist/blocks/list/ListBlockToolbar.d.ts.map +1 -0
- package/dist/blocks/list/ListBlockToolbar.js +26 -0
- package/dist/blocks/list/ListContainer.d.ts +5 -0
- package/dist/blocks/list/ListContainer.d.ts.map +1 -0
- package/dist/blocks/list/ListContainer.js +10 -0
- package/dist/blocks/list/ListGeneralTab.d.ts +11 -0
- package/dist/blocks/list/ListGeneralTab.d.ts.map +1 -0
- package/dist/blocks/list/ListGeneralTab.js +134 -0
- package/dist/blocks/list/ListItem.d.ts +8 -0
- package/dist/blocks/list/ListItem.d.ts.map +1 -0
- package/dist/blocks/list/ListItem.js +24 -0
- package/dist/blocks/list/ListPreviewTab.d.ts +9 -0
- package/dist/blocks/list/ListPreviewTab.d.ts.map +1 -0
- package/dist/blocks/list/ListPreviewTab.js +51 -0
- package/dist/blocks/list/ListSettings.d.ts +3 -0
- package/dist/blocks/list/ListSettings.d.ts.map +1 -0
- package/dist/blocks/list/ListSettings.js +115 -0
- package/dist/blocks/list/ListSettingsTab.d.ts +10 -0
- package/dist/blocks/list/ListSettingsTab.d.ts.map +1 -0
- package/dist/blocks/list/ListSettingsTab.js +64 -0
- package/dist/blocks/list/index.d.ts +3 -0
- package/dist/blocks/list/index.d.ts.map +1 -0
- package/dist/blocks/list/index.js +5 -0
- package/dist/blocks/list/useList.d.ts +5 -0
- package/dist/blocks/list/useList.d.ts.map +1 -0
- package/dist/blocks/list/useList.js +11 -0
- package/dist/blocks/overview/OverviewBlock.d.ts +33 -0
- package/dist/blocks/overview/OverviewBlock.d.ts.map +1 -0
- package/dist/blocks/overview/OverviewBlock.js +34 -0
- package/dist/blocks/overview/OverviewBlockToolbar.d.ts +8 -0
- package/dist/blocks/overview/OverviewBlockToolbar.d.ts.map +1 -0
- package/dist/blocks/overview/OverviewBlockToolbar.js +16 -0
- package/dist/blocks/overview/OverviewGeneralTab.d.ts +11 -0
- package/dist/blocks/overview/OverviewGeneralTab.d.ts.map +1 -0
- package/dist/blocks/overview/OverviewGeneralTab.js +134 -0
- package/dist/blocks/overview/OverviewPreviewTab.d.ts +10 -0
- package/dist/blocks/overview/OverviewPreviewTab.d.ts.map +1 -0
- package/dist/blocks/overview/OverviewPreviewTab.js +30 -0
- package/dist/blocks/overview/OverviewSettings.d.ts +3 -0
- package/dist/blocks/overview/OverviewSettings.d.ts.map +1 -0
- package/dist/blocks/overview/OverviewSettings.js +114 -0
- package/dist/blocks/overview/index.d.ts +3 -0
- package/dist/blocks/overview/index.d.ts.map +1 -0
- package/dist/blocks/overview/index.js +5 -0
- package/dist/blocks/overview/useOverview.d.ts +11 -0
- package/dist/blocks/overview/useOverview.d.ts.map +1 -0
- package/dist/blocks/overview/useOverview.js +61 -0
- package/dist/components/GlobeIcon.d.ts +9 -0
- package/dist/components/GlobeIcon.d.ts.map +1 -0
- package/dist/components/GlobeIcon.js +20 -0
- package/dist/components/IxoEditor.d.ts +14 -0
- package/dist/components/IxoEditor.d.ts.map +1 -0
- package/dist/components/IxoEditor.js +41 -0
- package/dist/components/PenIcon.d.ts +9 -0
- package/dist/components/PenIcon.d.ts.map +1 -0
- package/dist/components/PenIcon.js +20 -0
- package/dist/components/SettingsIcon.d.ts +9 -0
- package/dist/components/SettingsIcon.d.ts.map +1 -0
- package/dist/components/SettingsIcon.js +21 -0
- package/dist/components/SettingsModal/AdvancedTab.d.ts +8 -0
- package/dist/components/SettingsModal/AdvancedTab.d.ts.map +1 -0
- package/dist/components/SettingsModal/AdvancedTab.js +14 -0
- package/dist/components/SettingsModal/DomainPreview.d.ts +7 -0
- package/dist/components/SettingsModal/DomainPreview.d.ts.map +1 -0
- package/dist/components/SettingsModal/DomainPreview.js +22 -0
- package/dist/components/SettingsModal/FeatureASettings.d.ts +3 -0
- package/dist/components/SettingsModal/FeatureASettings.d.ts.map +1 -0
- package/dist/components/SettingsModal/FeatureASettings.js +74 -0
- package/dist/components/SettingsModal/GeneralTab.d.ts +10 -0
- package/dist/components/SettingsModal/GeneralTab.d.ts.map +1 -0
- package/dist/components/SettingsModal/GeneralTab.js +111 -0
- package/dist/components/SettingsModal/PreviewTab.d.ts +8 -0
- package/dist/components/SettingsModal/PreviewTab.d.ts.map +1 -0
- package/dist/components/SettingsModal/PreviewTab.js +14 -0
- package/dist/components/SettingsModal/SettingsModal.d.ts +16 -0
- package/dist/components/SettingsModal/SettingsModal.d.ts.map +1 -0
- package/dist/components/SettingsModal/SettingsModal.js +61 -0
- package/dist/components/SettingsModal/SettingsNavigation.d.ts +15 -0
- package/dist/components/SettingsModal/SettingsNavigation.d.ts.map +1 -0
- package/dist/components/SettingsModal/SettingsNavigation.js +21 -0
- package/dist/components/SettingsModal/index.d.ts +8 -0
- package/dist/components/SettingsModal/index.d.ts.map +1 -0
- package/dist/components/SettingsModal/index.js +17 -0
- package/dist/components/SwitchOption.d.ts +9 -0
- package/dist/components/SwitchOption.d.ts.map +1 -0
- package/dist/components/SwitchOption.js +45 -0
- package/dist/components/icons/ArchiveIcon.d.ts +9 -0
- package/dist/components/icons/ArchiveIcon.d.ts.map +1 -0
- package/dist/components/icons/ArchiveIcon.js +18 -0
- package/dist/components/icons/AudioIcon.d.ts +9 -0
- package/dist/components/icons/AudioIcon.d.ts.map +1 -0
- package/dist/components/icons/AudioIcon.js +17 -0
- package/dist/components/icons/DefaultIcon.d.ts +9 -0
- package/dist/components/icons/DefaultIcon.d.ts.map +1 -0
- package/dist/components/icons/DefaultIcon.js +17 -0
- package/dist/components/icons/DocumentIcon.d.ts +9 -0
- package/dist/components/icons/DocumentIcon.d.ts.map +1 -0
- package/dist/components/icons/DocumentIcon.js +20 -0
- package/dist/components/icons/ImageIcon.d.ts +9 -0
- package/dist/components/icons/ImageIcon.d.ts.map +1 -0
- package/dist/components/icons/ImageIcon.js +18 -0
- package/dist/components/icons/JsonIcon.d.ts +9 -0
- package/dist/components/icons/JsonIcon.d.ts.map +1 -0
- package/dist/components/icons/JsonIcon.js +19 -0
- package/dist/components/icons/PdfIcon.d.ts +9 -0
- package/dist/components/icons/PdfIcon.d.ts.map +1 -0
- package/dist/components/icons/PdfIcon.js +20 -0
- package/dist/components/icons/VideoIcon.d.ts +9 -0
- package/dist/components/icons/VideoIcon.d.ts.map +1 -0
- package/dist/components/icons/VideoIcon.js +17 -0
- package/dist/components/icons/XmlIcon.d.ts +9 -0
- package/dist/components/icons/XmlIcon.d.ts.map +1 -0
- package/dist/components/icons/XmlIcon.js +19 -0
- package/dist/components/icons/index.d.ts +10 -0
- package/dist/components/icons/index.d.ts.map +1 -0
- package/dist/components/icons/index.js +24 -0
- package/dist/components/ui/button.d.ts +11 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/button.js +68 -0
- package/dist/components/ui/card.d.ts +9 -0
- package/dist/components/ui/card.d.ts.map +1 -0
- package/dist/components/ui/card.js +56 -0
- package/dist/components/ui/dialog.d.ts +16 -0
- package/dist/components/ui/dialog.d.ts.map +1 -0
- package/dist/components/ui/dialog.js +85 -0
- package/dist/components/ui/dropdown-menu.d.ts +26 -0
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/components/ui/dropdown-menu.js +110 -0
- package/dist/components/ui/input.d.ts +4 -0
- package/dist/components/ui/input.d.ts.map +1 -0
- package/dist/components/ui/input.js +41 -0
- package/dist/components/ui/label.d.ts +5 -0
- package/dist/components/ui/label.d.ts.map +1 -0
- package/dist/components/ui/label.js +42 -0
- package/dist/components/ui/switch.d.ts +5 -0
- package/dist/components/ui/switch.d.ts.map +1 -0
- package/dist/components/ui/switch.js +44 -0
- package/dist/components/ui/tabs.d.ts +8 -0
- package/dist/components/ui/tabs.d.ts.map +1 -0
- package/dist/components/ui/tabs.js +54 -0
- package/dist/components/ui/toggle-group.d.ts +8 -0
- package/dist/components/ui/toggle-group.d.ts.map +1 -0
- package/dist/components/ui/toggle-group.js +57 -0
- package/dist/components/ui/toggle.d.ts +10 -0
- package/dist/components/ui/toggle.d.ts.map +1 -0
- package/dist/components/ui/toggle.js +62 -0
- package/dist/hooks/useCollaborativeIxoEditor.d.ts +571 -0
- package/dist/hooks/useCollaborativeIxoEditor.d.ts.map +1 -0
- package/dist/hooks/useCollaborativeIxoEditor.js +127 -0
- package/dist/hooks/useCreateIxoEditor.d.ts +568 -0
- package/dist/hooks/useCreateIxoEditor.d.ts.map +1 -0
- package/dist/hooks/useCreateIxoEditor.js +62 -0
- package/dist/hooks/useMatrixProvider.d.ts +13 -0
- package/dist/hooks/useMatrixProvider.d.ts.map +1 -0
- package/dist/hooks/useMatrixProvider.js +147 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/lib/graphql-client.d.ts +27 -0
- package/dist/lib/graphql-client.d.ts.map +1 -0
- package/dist/lib/graphql-client.js +36 -0
- package/dist/lib/graphql-queries.d.ts +31 -0
- package/dist/lib/graphql-queries.d.ts.map +1 -0
- package/dist/lib/graphql-queries.js +40 -0
- package/dist/lib/utils/getMediaTypeIcon.d.ts +20 -0
- package/dist/lib/utils/getMediaTypeIcon.d.ts.map +1 -0
- package/dist/lib/utils/getMediaTypeIcon.js +96 -0
- package/dist/lib/utils/index.d.ts +4 -0
- package/dist/lib/utils/index.d.ts.map +1 -0
- package/dist/lib/utils/index.js +12 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +8 -0
- package/dist/types/Domain.d.ts +18 -0
- package/dist/types/Domain.d.ts.map +1 -0
- package/dist/types/Domain.js +2 -0
- package/dist/types/index.d.ts +77 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/package.json +81 -0
- package/style.css +246 -0
- package/style.css.d.ts +5 -0
package/README.md
ADDED
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
# IXO Editor
|
|
2
|
+
|
|
3
|
+
A custom BlockNote editor wrapper built specifically for the IXO team's needs. This package provides a highly customized rich text editing experience built on top of [BlockNote](https://www.blocknotejs.org/).
|
|
4
|
+
|
|
5
|
+
> **Note**: This package is designed for internal IXO team use and is not intended for public consumption, though it is hosted publicly.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- 🎨 **Custom Theming**: Light and dark theme support with IXO-specific styling
|
|
10
|
+
- 🔧 **Simplified API**: Wrapped BlockNote functionality with sensible defaults
|
|
11
|
+
- 📝 **Rich Text Editing**: Full support for headings, lists, code blocks, tables, and more
|
|
12
|
+
- 🔗 **Custom Blocks**: Built-in custom blocks including dynamic List block for DID data
|
|
13
|
+
- 🖼️ **Media Support**: Image and file upload handling
|
|
14
|
+
- 🎯 **TypeScript**: Full TypeScript support with exported types
|
|
15
|
+
- 🤝 **Collaboration Ready**: Built-in collaboration configuration options
|
|
16
|
+
- 📱 **Responsive**: Mobile-friendly editor experience
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install @ixo/editor
|
|
22
|
+
# or
|
|
23
|
+
yarn add @ixo/editor
|
|
24
|
+
# or
|
|
25
|
+
pnpm add @ixo/editor
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Important: Import Required Styles
|
|
29
|
+
|
|
30
|
+
The IXO Editor requires two CSS imports:
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
// Import BlockNote's shadcn styles
|
|
34
|
+
import '@blocknote/shadcn/style.css';
|
|
35
|
+
|
|
36
|
+
// Import IXO Editor custom styles
|
|
37
|
+
import '@ixo/editor/style.css';
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Note for Next.js users**: Make sure to import these styles in your `_app.tsx` or at the component level where you use the editor.
|
|
41
|
+
|
|
42
|
+
## Quick Start
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
import React from 'react';
|
|
46
|
+
import { useCreateIxoEditor, IxoEditor } from '@ixo/editor';
|
|
47
|
+
import '@blocknote/shadcn/style.css'; // Import BlockNote shadcn styles
|
|
48
|
+
import '@ixo/editor/style.css'; // Import IXO custom styles
|
|
49
|
+
|
|
50
|
+
function MyEditor() {
|
|
51
|
+
const editor = useCreateIxoEditor({
|
|
52
|
+
theme: 'light',
|
|
53
|
+
placeholder: 'Start writing...',
|
|
54
|
+
initialContent: [
|
|
55
|
+
{
|
|
56
|
+
type: 'heading',
|
|
57
|
+
content: 'Welcome to IXO Editor',
|
|
58
|
+
props: { level: 1 }
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
type: 'paragraph',
|
|
62
|
+
content: 'Start typing to create amazing content!'
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
type: 'list',
|
|
66
|
+
props: {
|
|
67
|
+
title: 'Dynamic List',
|
|
68
|
+
did: 'did:example:123',
|
|
69
|
+
fragmentIdentifier: 'sample-data'
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
return <IxoEditor editor={editor} onChange={() => console.log('Content changed')} />;
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## API Reference
|
|
80
|
+
|
|
81
|
+
### `useCreateIxoEditor`
|
|
82
|
+
|
|
83
|
+
The main hook for creating an IXO editor instance.
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
const editor = useCreateIxoEditor(options?: IxoEditorOptions);
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### Options
|
|
90
|
+
|
|
91
|
+
| Option | Type | Default | Description |
|
|
92
|
+
|--------|------|---------|-------------|
|
|
93
|
+
| `theme` | `'light' \| 'dark'` | `'light'` | Editor color theme |
|
|
94
|
+
| `placeholder` | `string` | `'Start typing or press "/" for commands...'` | Placeholder text |
|
|
95
|
+
| `uploadFile` | `(file: File) => Promise<string>` | Data URL converter | File upload handler |
|
|
96
|
+
| `initialContent` | `PartialBlock[]` | `undefined` | Initial editor content |
|
|
97
|
+
| `editable` | `boolean` | `true` | Whether editor is editable |
|
|
98
|
+
| `animations` | `boolean` | `true` | Enable/disable animations |
|
|
99
|
+
| `sideMenu` | `boolean` | `true` | Show side menu (drag handle, plus button) |
|
|
100
|
+
| `slashMenu` | `boolean` | `true` | Enable slash commands menu |
|
|
101
|
+
| `formattingToolbar` | `boolean` | `true` | Show formatting toolbar |
|
|
102
|
+
| `linkToolbar` | `boolean` | `true` | Show link toolbar |
|
|
103
|
+
| `filePanel` | `boolean` | `true` | Show file panel |
|
|
104
|
+
| `tableHandles` | `boolean` | `true` | Show table manipulation handles |
|
|
105
|
+
| `trailingBlock` | `boolean` | `true` | Add trailing paragraph block |
|
|
106
|
+
| `placeholders` | `Record<string, string>` | `{}` | Custom placeholders for blocks |
|
|
107
|
+
| `dictionary` | `Record<string, string>` | `{}` | Custom translations |
|
|
108
|
+
| `collaboration` | `CollaborationConfig` | `undefined` | Collaboration settings |
|
|
109
|
+
|
|
110
|
+
### `IxoEditor` Component
|
|
111
|
+
|
|
112
|
+
The main editor component.
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
<IxoEditor
|
|
116
|
+
editor={editor}
|
|
117
|
+
className="my-custom-class"
|
|
118
|
+
onChange={() => {}}
|
|
119
|
+
onSelectionChange={() => {}}
|
|
120
|
+
/>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
#### Props
|
|
124
|
+
|
|
125
|
+
| Prop | Type | Description |
|
|
126
|
+
|------|------|-------------|
|
|
127
|
+
| `editor` | `BlockNoteEditor \| undefined` | Editor instance from `useCreateIxoEditor` |
|
|
128
|
+
| `className` | `string` | Additional CSS classes |
|
|
129
|
+
| `onChange` | `() => void` | Callback when content changes |
|
|
130
|
+
| `onSelectionChange` | `() => void` | Callback when selection changes |
|
|
131
|
+
| `children` | `React.ReactNode` | Custom child components |
|
|
132
|
+
|
|
133
|
+
## Advanced Usage
|
|
134
|
+
|
|
135
|
+
### Custom File Upload
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
const editor = useCreateIxoEditor({
|
|
139
|
+
uploadFile: async (file: File) => {
|
|
140
|
+
const formData = new FormData();
|
|
141
|
+
formData.append('file', file);
|
|
142
|
+
|
|
143
|
+
const response = await fetch('/api/upload', {
|
|
144
|
+
method: 'POST',
|
|
145
|
+
body: formData,
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const { url } = await response.json();
|
|
149
|
+
return url;
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Collaboration
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
const editor = useCreateIxoEditor({
|
|
158
|
+
collaboration: {
|
|
159
|
+
documentId: 'doc-123',
|
|
160
|
+
websocketUrl: 'wss://collab.example.com',
|
|
161
|
+
user: {
|
|
162
|
+
id: 'user-456',
|
|
163
|
+
name: 'John Doe',
|
|
164
|
+
color: '#FF5733'
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Accessing Editor Content
|
|
171
|
+
|
|
172
|
+
```tsx
|
|
173
|
+
function MyEditor() {
|
|
174
|
+
const editor = useCreateIxoEditor();
|
|
175
|
+
|
|
176
|
+
const handleSave = () => {
|
|
177
|
+
if (editor) {
|
|
178
|
+
const content = editor.document;
|
|
179
|
+
console.log('Editor content:', content);
|
|
180
|
+
// Save content to your backend
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
return (
|
|
185
|
+
<>
|
|
186
|
+
<IxoEditor editor={editor} />
|
|
187
|
+
<button onClick={handleSave}>Save</button>
|
|
188
|
+
</>
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Dark Theme
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
const editor = useCreateIxoEditor({
|
|
197
|
+
theme: 'dark'
|
|
198
|
+
});
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Read-Only Mode
|
|
202
|
+
|
|
203
|
+
```tsx
|
|
204
|
+
const editor = useCreateIxoEditor({
|
|
205
|
+
editable: false,
|
|
206
|
+
sideMenu: false,
|
|
207
|
+
slashMenu: false,
|
|
208
|
+
formattingToolbar: false
|
|
209
|
+
});
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Custom Blocks
|
|
213
|
+
|
|
214
|
+
### List Block
|
|
215
|
+
|
|
216
|
+
The IXO Editor includes a custom List block for displaying dynamic data from DID and fragment identifiers. This block is perfect for displaying data from your GraphQL API.
|
|
217
|
+
|
|
218
|
+
#### Features
|
|
219
|
+
|
|
220
|
+
- **Editable Title**: Click the title to edit it inline
|
|
221
|
+
- **Settings Panel**: Click the gear icon to configure DID and fragment identifier
|
|
222
|
+
- **Dynamic Data**: Ready for integration with your GraphQL API
|
|
223
|
+
- **Responsive Design**: Works on all device sizes
|
|
224
|
+
- **Theme Support**: Automatically adapts to light/dark themes
|
|
225
|
+
|
|
226
|
+
#### Usage
|
|
227
|
+
|
|
228
|
+
The List block can be inserted using the slash menu:
|
|
229
|
+
|
|
230
|
+
1. Type `/list` in the editor
|
|
231
|
+
2. Or type `/` and search for "List", "data", or "dynamic"
|
|
232
|
+
3. Configure the DID and fragment identifier in the settings
|
|
233
|
+
|
|
234
|
+
#### Programmatic Usage
|
|
235
|
+
|
|
236
|
+
```tsx
|
|
237
|
+
// Insert a list block programmatically
|
|
238
|
+
editor.insertBlocks([{
|
|
239
|
+
type: 'list',
|
|
240
|
+
props: {
|
|
241
|
+
title: 'My Data List',
|
|
242
|
+
did: 'did:ixo:entity123',
|
|
243
|
+
fragmentIdentifier: 'claims-data'
|
|
244
|
+
}
|
|
245
|
+
}], editor.getTextCursorPosition().block, 'after');
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
#### Integration with GraphQL
|
|
249
|
+
|
|
250
|
+
Replace the mock data in `ListBlock.tsx` with your actual GraphQL call:
|
|
251
|
+
|
|
252
|
+
```tsx
|
|
253
|
+
// Example integration (replace mockListItems in ListBlock.tsx)
|
|
254
|
+
const { data, loading, error } = useQuery(GET_DATA_BY_DID, {
|
|
255
|
+
variables: {
|
|
256
|
+
did: settings.did,
|
|
257
|
+
fragmentIdentifier: settings.fragmentIdentifier
|
|
258
|
+
},
|
|
259
|
+
skip: !settings.did || !settings.fragmentIdentifier
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
const listItems = data?.items || [];
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Styling
|
|
266
|
+
|
|
267
|
+
The editor comes with default styles, but you can override them using CSS custom properties:
|
|
268
|
+
|
|
269
|
+
```css
|
|
270
|
+
.ixo-editor {
|
|
271
|
+
--bn-colors-editor-background: #f5f5f5;
|
|
272
|
+
--bn-colors-editor-text: #333333;
|
|
273
|
+
--bn-colors-highlight-colors-blue: #0066cc;
|
|
274
|
+
/* ...more custom properties */
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## Development
|
|
279
|
+
|
|
280
|
+
### Building the Package
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
# Install dependencies
|
|
284
|
+
npm install
|
|
285
|
+
|
|
286
|
+
# Build the package
|
|
287
|
+
npm run build
|
|
288
|
+
|
|
289
|
+
# Watch for changes during development
|
|
290
|
+
npm run dev
|
|
291
|
+
|
|
292
|
+
# Type checking
|
|
293
|
+
npm run type-check
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Project Structure
|
|
297
|
+
|
|
298
|
+
```
|
|
299
|
+
ixo-editor/
|
|
300
|
+
├── src/
|
|
301
|
+
│ ├── components/ # React components
|
|
302
|
+
│ │ └── IxoEditor.tsx
|
|
303
|
+
│ ├── hooks/ # Custom hooks
|
|
304
|
+
│ │ └── useCreateIxoEditor.ts
|
|
305
|
+
│ ├── styles/ # CSS styles
|
|
306
|
+
│ │ └── ixo-editor.css
|
|
307
|
+
│ ├── types/ # TypeScript types
|
|
308
|
+
│ │ └── index.ts
|
|
309
|
+
│ └── index.ts # Main entry point
|
|
310
|
+
├── lib/ # Built output (generated)
|
|
311
|
+
├── package.json
|
|
312
|
+
├── tsconfig.json
|
|
313
|
+
└── README.md
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
## Requirements
|
|
317
|
+
|
|
318
|
+
- React 18.0.0 or higher
|
|
319
|
+
- React DOM 18.0.0 or higher
|
|
320
|
+
- Modern browser with ES2020 support
|
|
321
|
+
|
|
322
|
+
## License
|
|
323
|
+
|
|
324
|
+
MIT © IXO Team
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## Internal Notes
|
|
329
|
+
|
|
330
|
+
This package is maintained by the IXO development team. For questions or issues, please contact the team directly through internal channels.
|
|
331
|
+
|
|
332
|
+
### Deployment
|
|
333
|
+
|
|
334
|
+
The package is deployed to npm under the `@ixo/editor` scope. Only team members with appropriate npm permissions can publish new versions.
|
|
335
|
+
|
|
336
|
+
### Version Management
|
|
337
|
+
|
|
338
|
+
Follow semantic versioning:
|
|
339
|
+
- Patch releases (0.0.x): Bug fixes and minor updates
|
|
340
|
+
- Minor releases (0.x.0): New features that are backward compatible
|
|
341
|
+
- Major releases (x.0.0): Breaking changes
|
|
342
|
+
|
|
343
|
+
### Contributing
|
|
344
|
+
|
|
345
|
+
This is an internal package. All contributions should go through the standard IXO development workflow and review process.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { ListBlock } from "./list";
|
|
2
|
+
import { OverviewBlock } from "./overview";
|
|
3
|
+
export { ListBlock, OverviewBlock };
|
|
4
|
+
export type { ListBlockSettings, ListBlockProps } from "./list";
|
|
5
|
+
export type { OverviewBlockSettings, OverviewBlockProps } from "./overview";
|
|
6
|
+
export declare const blockSpecs: {
|
|
7
|
+
list: {
|
|
8
|
+
config: {
|
|
9
|
+
readonly type: "list";
|
|
10
|
+
readonly propSchema: {
|
|
11
|
+
readonly title: {
|
|
12
|
+
readonly default: "";
|
|
13
|
+
};
|
|
14
|
+
readonly did: {
|
|
15
|
+
readonly default: "";
|
|
16
|
+
};
|
|
17
|
+
readonly fragmentIdentifier: {
|
|
18
|
+
readonly default: "";
|
|
19
|
+
};
|
|
20
|
+
readonly listItemType: {
|
|
21
|
+
readonly default: "keyvalue";
|
|
22
|
+
};
|
|
23
|
+
readonly showLinkedResources: {
|
|
24
|
+
readonly default: false;
|
|
25
|
+
};
|
|
26
|
+
readonly showAssetsInCollection: {
|
|
27
|
+
readonly default: false;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
readonly content: "none";
|
|
31
|
+
};
|
|
32
|
+
implementation: import("@blocknote/core").TiptapBlockImplementation<{
|
|
33
|
+
readonly type: "list";
|
|
34
|
+
readonly propSchema: {
|
|
35
|
+
readonly title: {
|
|
36
|
+
readonly default: "";
|
|
37
|
+
};
|
|
38
|
+
readonly did: {
|
|
39
|
+
readonly default: "";
|
|
40
|
+
};
|
|
41
|
+
readonly fragmentIdentifier: {
|
|
42
|
+
readonly default: "";
|
|
43
|
+
};
|
|
44
|
+
readonly listItemType: {
|
|
45
|
+
readonly default: "keyvalue";
|
|
46
|
+
};
|
|
47
|
+
readonly showLinkedResources: {
|
|
48
|
+
readonly default: false;
|
|
49
|
+
};
|
|
50
|
+
readonly showAssetsInCollection: {
|
|
51
|
+
readonly default: false;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
readonly content: "none";
|
|
55
|
+
}, any, import("@blocknote/core").InlineContentSchema, import("@blocknote/core").StyleSchema>;
|
|
56
|
+
};
|
|
57
|
+
overview: {
|
|
58
|
+
config: {
|
|
59
|
+
type: "overview";
|
|
60
|
+
propSchema: {
|
|
61
|
+
did: {
|
|
62
|
+
default: string;
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
content: "inline";
|
|
66
|
+
};
|
|
67
|
+
implementation: import("@blocknote/core").TiptapBlockImplementation<{
|
|
68
|
+
type: "overview";
|
|
69
|
+
propSchema: {
|
|
70
|
+
did: {
|
|
71
|
+
default: string;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
content: "inline";
|
|
75
|
+
}, any, import("@blocknote/core").InlineContentSchema, import("@blocknote/core").StyleSchema>;
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
export declare const getExtraSlashMenuItems: (editor: any) => {
|
|
79
|
+
title: string;
|
|
80
|
+
onItemClick: () => void;
|
|
81
|
+
aliases: string[];
|
|
82
|
+
group: string;
|
|
83
|
+
subtext: string;
|
|
84
|
+
}[];
|
|
85
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/blocks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC;AACpC,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAChE,YAAY,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAG5E,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAGtB,CAAC;AAGF,eAAO,MAAM,sBAAsB,GAAI,QAAQ,GAAG;;;;;;GA2CjD,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getExtraSlashMenuItems = exports.blockSpecs = exports.OverviewBlock = exports.ListBlock = void 0;
|
|
4
|
+
const list_1 = require("./list");
|
|
5
|
+
Object.defineProperty(exports, "ListBlock", { enumerable: true, get: function () { return list_1.ListBlock; } });
|
|
6
|
+
const overview_1 = require("./overview");
|
|
7
|
+
Object.defineProperty(exports, "OverviewBlock", { enumerable: true, get: function () { return overview_1.OverviewBlock; } });
|
|
8
|
+
// Block configuration for easy import
|
|
9
|
+
exports.blockSpecs = {
|
|
10
|
+
list: list_1.ListBlock,
|
|
11
|
+
overview: overview_1.OverviewBlock,
|
|
12
|
+
};
|
|
13
|
+
// Slash menu items configuration
|
|
14
|
+
const getExtraSlashMenuItems = (editor) => [
|
|
15
|
+
{
|
|
16
|
+
title: "List",
|
|
17
|
+
onItemClick: () => {
|
|
18
|
+
editor.insertBlocks([
|
|
19
|
+
{
|
|
20
|
+
type: "list",
|
|
21
|
+
props: {
|
|
22
|
+
title: "",
|
|
23
|
+
did: "",
|
|
24
|
+
fragmentIdentifier: "",
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
], editor.getTextCursorPosition().block, "after");
|
|
28
|
+
},
|
|
29
|
+
aliases: ["list", "data", "dynamic"],
|
|
30
|
+
group: "Domains",
|
|
31
|
+
subtext: "Create a dynamic list from DID data",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
title: "Overview",
|
|
35
|
+
onItemClick: () => {
|
|
36
|
+
editor.insertBlocks([
|
|
37
|
+
{
|
|
38
|
+
type: "overview",
|
|
39
|
+
props: {
|
|
40
|
+
did: "",
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
], editor.getTextCursorPosition().block, "after");
|
|
44
|
+
},
|
|
45
|
+
aliases: ["overview", "overview-block", "data-overview"],
|
|
46
|
+
group: "Domains",
|
|
47
|
+
subtext: "Create an overview from DID data",
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
exports.getExtraSlashMenuItems = getExtraSlashMenuItems;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export interface ListBlockSettings {
|
|
2
|
+
did: string;
|
|
3
|
+
fragmentIdentifier: string;
|
|
4
|
+
}
|
|
5
|
+
export interface ListBlockProps {
|
|
6
|
+
block: any;
|
|
7
|
+
editor: any;
|
|
8
|
+
}
|
|
9
|
+
export declare const ListBlock: {
|
|
10
|
+
config: {
|
|
11
|
+
readonly type: "list";
|
|
12
|
+
readonly propSchema: {
|
|
13
|
+
readonly title: {
|
|
14
|
+
readonly default: "";
|
|
15
|
+
};
|
|
16
|
+
readonly did: {
|
|
17
|
+
readonly default: "";
|
|
18
|
+
};
|
|
19
|
+
readonly fragmentIdentifier: {
|
|
20
|
+
readonly default: "";
|
|
21
|
+
};
|
|
22
|
+
readonly listItemType: {
|
|
23
|
+
readonly default: "keyvalue";
|
|
24
|
+
};
|
|
25
|
+
readonly showLinkedResources: {
|
|
26
|
+
readonly default: false;
|
|
27
|
+
};
|
|
28
|
+
readonly showAssetsInCollection: {
|
|
29
|
+
readonly default: false;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
readonly content: "none";
|
|
33
|
+
};
|
|
34
|
+
implementation: import("@blocknote/core").TiptapBlockImplementation<{
|
|
35
|
+
readonly type: "list";
|
|
36
|
+
readonly propSchema: {
|
|
37
|
+
readonly title: {
|
|
38
|
+
readonly default: "";
|
|
39
|
+
};
|
|
40
|
+
readonly did: {
|
|
41
|
+
readonly default: "";
|
|
42
|
+
};
|
|
43
|
+
readonly fragmentIdentifier: {
|
|
44
|
+
readonly default: "";
|
|
45
|
+
};
|
|
46
|
+
readonly listItemType: {
|
|
47
|
+
readonly default: "keyvalue";
|
|
48
|
+
};
|
|
49
|
+
readonly showLinkedResources: {
|
|
50
|
+
readonly default: false;
|
|
51
|
+
};
|
|
52
|
+
readonly showAssetsInCollection: {
|
|
53
|
+
readonly default: false;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
readonly content: "none";
|
|
57
|
+
}, any, import("@blocknote/core").InlineContentSchema, import("@blocknote/core").StyleSchema>;
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=ListBlock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ListBlock.d.ts","sourceRoot":"","sources":["../../../src/blocks/list/ListBlock.tsx"],"names":[],"mappings":"AAOA,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,GAAG,CAAC;IACX,MAAM,EAAE,GAAG,CAAC;CACb;AA4BD,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BrB,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ListBlock = void 0;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const react_2 = require("@blocknote/react");
|
|
9
|
+
const ListBlockToolbar_1 = __importDefault(require("./ListBlockToolbar"));
|
|
10
|
+
const ListItem_1 = __importDefault(require("./ListItem"));
|
|
11
|
+
const useList_1 = __importDefault(require("./useList"));
|
|
12
|
+
const ListContainer_1 = __importDefault(require("./ListContainer"));
|
|
13
|
+
const ListBlockContent = ({ block, editor }) => {
|
|
14
|
+
const { list, setList } = (0, useList_1.default)();
|
|
15
|
+
return (react_1.default.createElement("div", { style: {
|
|
16
|
+
width: "100%",
|
|
17
|
+
borderRadius: "6px",
|
|
18
|
+
padding: "16px",
|
|
19
|
+
backgroundColor: "#FFFFFF",
|
|
20
|
+
fontFamily: "Inter, Helvetica, Arial, sans-serif",
|
|
21
|
+
} },
|
|
22
|
+
react_1.default.createElement(ListBlockToolbar_1.default, { block: block, editor: editor, setList: setList }),
|
|
23
|
+
react_1.default.createElement("div", { style: { minHeight: "40px" } },
|
|
24
|
+
react_1.default.createElement(ListContainer_1.default, null, list?.map((item, index) => (react_1.default.createElement(ListItem_1.default, { key: index, item: item, index: index })))))));
|
|
25
|
+
};
|
|
26
|
+
exports.ListBlock = (0, react_2.createReactBlockSpec)({
|
|
27
|
+
type: "list",
|
|
28
|
+
propSchema: {
|
|
29
|
+
title: {
|
|
30
|
+
default: "",
|
|
31
|
+
},
|
|
32
|
+
did: {
|
|
33
|
+
default: "",
|
|
34
|
+
},
|
|
35
|
+
fragmentIdentifier: {
|
|
36
|
+
default: "",
|
|
37
|
+
},
|
|
38
|
+
listItemType: {
|
|
39
|
+
default: "keyvalue",
|
|
40
|
+
},
|
|
41
|
+
showLinkedResources: {
|
|
42
|
+
default: false,
|
|
43
|
+
},
|
|
44
|
+
showAssetsInCollection: {
|
|
45
|
+
default: false,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
content: "none",
|
|
49
|
+
}, {
|
|
50
|
+
render: ListBlockContent,
|
|
51
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
interface ListBlockToolbarProps {
|
|
3
|
+
block: any;
|
|
4
|
+
editor: any;
|
|
5
|
+
setList: (list: any[]) => void;
|
|
6
|
+
}
|
|
7
|
+
export default function ListBlockToolbar({ block, editor, setList, }: ListBlockToolbarProps): React.JSX.Element;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=ListBlockToolbar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ListBlockToolbar.d.ts","sourceRoot":"","sources":["../../../src/blocks/list/ListBlockToolbar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,qBAAqB;IAC7B,KAAK,EAAE,GAAG,CAAC;IACX,MAAM,EAAE,GAAG,CAAC;IACZ,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;CAChC;AAED,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EACvC,KAAK,EACL,MAAM,EACN,OAAO,GACR,EAAE,qBAAqB,qBAyBvB"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = ListBlockToolbar;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const ListSettings_1 = require("./ListSettings");
|
|
9
|
+
const input_1 = require("../../components/ui/input");
|
|
10
|
+
function ListBlockToolbar({ block, editor, setList, }) {
|
|
11
|
+
return (react_1.default.createElement("div", { className: "flex justify-between items-center mb-3 pb-2 border-b border-gray-100 dark:border-gray-700" },
|
|
12
|
+
react_1.default.createElement(input_1.Input, { value: block.props.title, placeholder: "New list", className: "font-semibold flex-1 border-0 bg-transparent px-2 py-1 focus-visible:ring-0 focus-visible:ring-offset-0 hover:bg-gray-50 dark:hover:bg-gray-700 focus:bg-gray-50 dark:focus:bg-gray-700 notion-list-title-input", style: {
|
|
13
|
+
color: "#2F2F2F",
|
|
14
|
+
fontFamily: "Inter, Helvetica, Arial, sans-serif",
|
|
15
|
+
fontSize: "14px",
|
|
16
|
+
fontWeight: 600,
|
|
17
|
+
}, onChange: (e) => {
|
|
18
|
+
editor.updateBlock(block, {
|
|
19
|
+
props: {
|
|
20
|
+
...block.props,
|
|
21
|
+
title: e.target.value,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
} }),
|
|
25
|
+
react_1.default.createElement(ListSettings_1.ListSettings, { block: block, editor: editor, setList: setList })));
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ListContainer.d.ts","sourceRoot":"","sources":["../../../src/blocks/list/ListContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EACpC,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,qBAEA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = ListContainer;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
function ListContainer({ children, }) {
|
|
9
|
+
return react_1.default.createElement("div", { className: "flex flex-col gap-2" }, children);
|
|
10
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
interface GeneralTabProps {
|
|
3
|
+
block: any;
|
|
4
|
+
editor: any;
|
|
5
|
+
domainValue: string;
|
|
6
|
+
onDomainChange: (did: string) => void;
|
|
7
|
+
domainProfile: any;
|
|
8
|
+
}
|
|
9
|
+
export declare function ListGeneralTab({ block: _block, editor: _editor, domainValue, onDomainChange, domainProfile, }: GeneralTabProps): React.JSX.Element;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=ListGeneralTab.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ListGeneralTab.d.ts","sourceRoot":"","sources":["../../../src/blocks/list/ListGeneralTab.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAYnD,UAAU,eAAe;IACvB,KAAK,EAAE,GAAG,CAAC;IACX,MAAM,EAAE,GAAG,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,aAAa,EAAE,GAAG,CAAC;CACpB;AAED,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,OAAO,EACf,WAAW,EACX,cAAc,EACd,aAAa,GACd,EAAE,eAAe,qBAsJjB"}
|