osi-cards-lib 1.5.2 → 1.5.4
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 +819 -14
- package/fesm2022/osi-cards-lib.mjs +21253 -12686
- package/index.d.ts +5240 -2510
- package/package.json +1 -1
- package/styles/_components.scss +6 -27
- package/styles/_index.scss +28 -0
- package/styles/_osi-cards-mixins.scss +430 -0
- package/styles/_osi-cards-tokens.scss +327 -0
- package/styles/_styles-scoped.scss +23 -44
- package/styles/_styles-standalone.scss +1564 -1195
- package/styles/bundles/_ai-card.scss +29 -56
- package/styles/bundles/_all.scss +4 -25
- package/styles/bundles/_base.scss +5 -6
- package/styles/bundles/_card-skeleton.scss +5 -0
- package/styles/bundles/_index.scss +6 -13
- package/styles/bundles/_sections.scss +2 -29
- package/styles/bundles/_tokens-only.scss +5 -0
- package/styles/bundles/ai-card.css +1 -1
- package/styles/bundles/ai-card.expanded.css +8175 -20768
- package/styles/bundles/all.css +1 -1
- package/styles/bundles/all.expanded.css +5067 -18374
- package/styles/bundles/base.css +1 -1
- package/styles/bundles/base.expanded.css +5562 -2460
- package/styles/bundles/sections.css +2 -0
- package/styles/bundles/sections.expanded.css +8458 -0
- package/styles/components/_ai-card-renderer.scss +5 -0
- package/styles/components/_badges.scss +5 -0
- package/styles/components/_hero-card.scss +5 -0
- package/styles/components/_image-fallback.scss +5 -0
- package/styles/components/cards/_ai-card.scss +91 -148
- package/styles/components/sections/_all-sections.generated.scss +41 -0
- package/styles/components/sections/_all-sections.scss +1079 -0
- package/styles/components/sections/_balanced-compact-system.scss +187 -0
- package/styles/components/sections/_compact-mixins.scss +181 -0
- package/styles/components/sections/_component-mixins.scss +454 -0
- package/styles/components/sections/_design-system.scss +351 -380
- package/styles/components/sections/_design-tokens.scss +301 -0
- package/styles/components/sections/_enhanced-design-variables.scss +148 -0
- package/styles/components/sections/_master-compact-system.scss +295 -0
- package/styles/components/sections/_master-dense-system.scss +237 -0
- package/styles/components/sections/_minimalistic-design.scss +269 -0
- package/styles/components/sections/_modern-effects.scss +412 -0
- package/styles/components/sections/_modern-sections.scss +336 -0
- package/styles/components/sections/_perfect-system.scss +205 -0
- package/styles/components/sections/_section-shell.scss +27 -123
- package/styles/components/sections/_section-types.generated.scss +27 -34
- package/styles/components/sections/_sections-all.scss +25 -0
- package/styles/components/sections/_sections-base.scss +161 -208
- package/styles/components/sections/_typography-system.scss +322 -0
- package/styles/components/sections/_ultra-compact-tokens.scss +352 -0
- package/styles/components/sections/_unified-section-style.scss +158 -0
- package/styles/components/sections/_utility-classes.scss +270 -0
- package/styles/components/sections/_visual-effects-library.scss +355 -0
- package/styles/core/_surface-layers.scss +9 -12
- package/styles/critical.scss +356 -0
- package/styles/design-system/_compact-theme.scss +160 -0
- package/styles/design-system/_section-base.scss +395 -0
- package/styles/design-system/_tokens.scss +238 -0
- package/styles/design-system/_unified-sections.scss +216 -0
- package/styles/layout/_feature-grid.scss +5 -0
- package/styles/layout/_masonry.scss +313 -37
- package/styles/micro-interactions.scss +5 -0
- package/styles/mixins/_section-mixins.scss +279 -0
- package/styles/non-critical.scss +641 -0
- package/styles/osi-cards-scoped.css +1 -1
- package/styles/osi-cards-scoped.expanded.css +4971 -17744
- package/styles/osi-cards-standalone.css +1 -1
- package/styles/osi-cards-standalone.expanded.css +5051 -17804
- package/styles/osi-cards-tokens.css +1 -1
- package/styles/osi-cards-tokens.expanded.css +193 -195
- package/styles/osi-cards.css +1 -1
- package/styles/osi-cards.expanded.css +4915 -17691
- package/styles/reset/_framework-reset.scss +5 -0
- package/styles/responsive.scss +5 -0
- package/styles/tokens/_master.scss +131 -127
- package/styles/_design-tokens.scss +0 -349
- package/styles/bundles/_section-analytics.scss +0 -10
- package/styles/bundles/_section-chart.scss +0 -10
- package/styles/bundles/_section-contact.scss +0 -11
- package/styles/bundles/_section-list.scss +0 -10
- package/styles/bundles/_section-news.scss +0 -10
- package/styles/bundles/_section-overview.scss +0 -10
- package/styles/bundles/section-analytics.css +0 -2
- package/styles/bundles/section-news.css +0 -2
- package/styles/bundles/section-overview.css +0 -2
- package/styles/components/sections/_analytics.scss +0 -288
- package/styles/components/sections/_brand-colors.scss +0 -259
- package/styles/components/sections/_chart.scss +0 -296
- package/styles/components/sections/_contact.scss +0 -265
- package/styles/components/sections/_event.scss +0 -285
- package/styles/components/sections/_fallback.scss +0 -175
- package/styles/components/sections/_financials.scss +0 -264
- package/styles/components/sections/_global-enforcement.scss +0 -757
- package/styles/components/sections/_info.scss +0 -230
- package/styles/components/sections/_list.scss +0 -260
- package/styles/components/sections/_map.scss +0 -208
- package/styles/components/sections/_network.scss +0 -122
- package/styles/components/sections/_news.scss +0 -98
- package/styles/components/sections/_overview.scss +0 -165
- package/styles/components/sections/_product.scss +0 -950
- package/styles/components/sections/_quotation.scss +0 -137
- package/styles/components/sections/_section-types.scss +0 -348
- package/styles/components/sections/_social-media.scss +0 -94
- package/styles/components/sections/_solutions.scss +0 -220
- package/styles/components/sections/_text-reference.scss +0 -141
- package/styles/components/sections/_unified-cards.scss +0 -124
- package/styles/core/_animations-shadow.scss +0 -763
- package/styles/core/_tokens-source.scss +0 -16
package/README.md
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
#
|
|
1
|
+
# OSI Cards Library
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A comprehensive Angular library for rendering AI-generated cards with rich section types, streaming support, and complete CSS encapsulation.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **17+ Section Types** - Info, Analytics, Chart, List, Contact, Network, Map, Event, Product, Solutions, Financials, and more
|
|
8
|
+
- **CSS Encapsulation** - Shadow DOM isolation with CSS Layers for easy style overrides
|
|
9
|
+
- **Streaming Support** - Progressive card rendering with LLM-style streaming simulation
|
|
10
|
+
- **Theme System** - Built-in themes (day/night) with full customization via CSS custom properties
|
|
11
|
+
- **Plugin Architecture** - Extend with custom section types
|
|
12
|
+
- **Accessibility** - WCAG compliant with keyboard navigation and screen reader support
|
|
13
|
+
- **Performance** - OnPush change detection, virtual scrolling, and optimized rendering
|
|
4
14
|
|
|
5
15
|
## Installation
|
|
6
16
|
|
|
@@ -8,39 +18,834 @@ Standalone OSI Cards library for Angular applications with CSS Layer support for
|
|
|
8
18
|
npm install osi-cards-lib
|
|
9
19
|
```
|
|
10
20
|
|
|
21
|
+
### Peer Dependencies
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @angular/common@^20.0.0 @angular/core@^20.0.0 @angular/animations@^20.0.0 @angular/platform-browser@^20.0.0 lucide-angular@^0.548.0 rxjs@~7.8.0
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Optional Dependencies (for charts and maps)
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install chart.js leaflet
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
11
35
|
## Quick Start
|
|
12
36
|
|
|
37
|
+
### Step 1: Configure Providers (Required)
|
|
38
|
+
|
|
39
|
+
In your `app.config.ts`:
|
|
40
|
+
|
|
13
41
|
```typescript
|
|
14
|
-
import {
|
|
42
|
+
import { ApplicationConfig } from '@angular/core';
|
|
43
|
+
import { provideOSICards } from 'osi-cards-lib';
|
|
44
|
+
|
|
45
|
+
export const appConfig: ApplicationConfig = {
|
|
46
|
+
providers: [
|
|
47
|
+
provideOSICards(), // Required for animations and library functionality
|
|
48
|
+
// ... your other providers
|
|
49
|
+
]
|
|
50
|
+
};
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Step 2: Import Styles
|
|
54
|
+
|
|
55
|
+
In your `src/styles.scss`:
|
|
56
|
+
|
|
57
|
+
```scss
|
|
58
|
+
@import 'osi-cards-lib/styles/_styles';
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Step 3: Use the Component
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Integration: Streaming vs Static
|
|
66
|
+
|
|
67
|
+
### Option A: Static Card (No Streaming)
|
|
68
|
+
|
|
69
|
+
Use this when you already have the card data and don't need loading animations.
|
|
70
|
+
|
|
71
|
+
**TypeScript:**
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import { Component } from '@angular/core';
|
|
75
|
+
import { OsiCardsContainerComponent, AICardRendererComponent, AICardConfig } from 'osi-cards-lib';
|
|
15
76
|
|
|
16
77
|
@Component({
|
|
17
|
-
selector: 'app-
|
|
78
|
+
selector: 'app-static-card',
|
|
18
79
|
standalone: true,
|
|
19
|
-
imports: [AICardRendererComponent],
|
|
20
|
-
|
|
21
|
-
<app-ai-card-renderer [cardConfig]="card"></app-ai-card-renderer>
|
|
22
|
-
`
|
|
80
|
+
imports: [OsiCardsContainerComponent, AICardRendererComponent],
|
|
81
|
+
templateUrl: './static-card.component.html'
|
|
23
82
|
})
|
|
24
|
-
export class
|
|
83
|
+
export class StaticCardComponent {
|
|
84
|
+
cardTheme: 'day' | 'night' = 'day';
|
|
85
|
+
|
|
25
86
|
card: AICardConfig = {
|
|
26
|
-
cardTitle: '
|
|
87
|
+
cardTitle: 'Company Profile',
|
|
27
88
|
sections: [
|
|
28
89
|
{
|
|
29
|
-
title: '
|
|
90
|
+
title: 'Overview',
|
|
30
91
|
type: 'info',
|
|
31
92
|
fields: [
|
|
32
|
-
{ label: '
|
|
93
|
+
{ label: 'Industry', value: 'Technology' },
|
|
94
|
+
{ label: 'Employees', value: '500+' }
|
|
95
|
+
]
|
|
96
|
+
}
|
|
97
|
+
]
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
onCardAction(event: { action: string; card: AICardConfig }): void {
|
|
101
|
+
console.log('Action:', event);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**HTML:**
|
|
107
|
+
|
|
108
|
+
```html
|
|
109
|
+
<osi-cards-container [theme]="cardTheme">
|
|
110
|
+
<app-ai-card-renderer
|
|
111
|
+
[cardConfig]="card"
|
|
112
|
+
[streamingStage]="'complete'"
|
|
113
|
+
[showLoadingByDefault]="false"
|
|
114
|
+
(cardInteraction)="onCardAction($event)">
|
|
115
|
+
</app-ai-card-renderer>
|
|
116
|
+
</osi-cards-container>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Key Settings:**
|
|
120
|
+
- `[streamingStage]="'complete'"` → Card is fully loaded
|
|
121
|
+
- `[showLoadingByDefault]="false"` → No loading spinner
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
### Option B: With Streaming (AI/LLM Integration)
|
|
126
|
+
|
|
127
|
+
Use this when generating cards progressively from an AI service.
|
|
128
|
+
|
|
129
|
+
**TypeScript:**
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
import { Component } from '@angular/core';
|
|
133
|
+
import { OsiCardsContainerComponent, AICardRendererComponent, AICardConfig, StreamingStage } from 'osi-cards-lib';
|
|
134
|
+
|
|
135
|
+
@Component({
|
|
136
|
+
selector: 'app-streaming-card',
|
|
137
|
+
standalone: true,
|
|
138
|
+
imports: [OsiCardsContainerComponent, AICardRendererComponent],
|
|
139
|
+
templateUrl: './streaming-card.component.html'
|
|
140
|
+
})
|
|
141
|
+
export class StreamingCardComponent {
|
|
142
|
+
cardTheme: 'day' | 'night' = 'day';
|
|
143
|
+
|
|
144
|
+
// Streaming state
|
|
145
|
+
card: AICardConfig | undefined;
|
|
146
|
+
isStreaming = false;
|
|
147
|
+
streamingStage: StreamingStage = 'idle';
|
|
148
|
+
streamingProgress = 0;
|
|
149
|
+
|
|
150
|
+
// Custom loading messages (optional)
|
|
151
|
+
loadingMessages = [
|
|
152
|
+
'Analyzing data...',
|
|
153
|
+
'Processing request...',
|
|
154
|
+
'Generating insights...'
|
|
155
|
+
];
|
|
156
|
+
|
|
157
|
+
async generateCard(): Promise<void> {
|
|
158
|
+
// Start streaming
|
|
159
|
+
this.card = undefined;
|
|
160
|
+
this.isStreaming = true;
|
|
161
|
+
this.streamingStage = 'thinking';
|
|
162
|
+
this.streamingProgress = 0;
|
|
163
|
+
|
|
164
|
+
// Simulate AI thinking phase
|
|
165
|
+
await this.delay(2000);
|
|
166
|
+
|
|
167
|
+
// Start streaming content
|
|
168
|
+
this.streamingStage = 'streaming';
|
|
169
|
+
this.streamingProgress = 0.2;
|
|
170
|
+
|
|
171
|
+
// Progressive card building (simulate chunks from AI)
|
|
172
|
+
this.card = { cardTitle: 'Analysis Results', sections: [] };
|
|
173
|
+
|
|
174
|
+
await this.delay(800);
|
|
175
|
+
this.streamingProgress = 0.5;
|
|
176
|
+
this.card.sections.push({
|
|
177
|
+
title: 'Summary',
|
|
178
|
+
type: 'info',
|
|
179
|
+
fields: [{ label: 'Status', value: 'Processing...' }]
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
await this.delay(800);
|
|
183
|
+
this.streamingProgress = 0.8;
|
|
184
|
+
this.card.sections.push({
|
|
185
|
+
title: 'Metrics',
|
|
186
|
+
type: 'analytics',
|
|
187
|
+
fields: [{ label: 'Score', value: '92%', trend: 'up' }]
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
await this.delay(500);
|
|
191
|
+
|
|
192
|
+
// Complete
|
|
193
|
+
this.streamingProgress = 1;
|
|
194
|
+
this.streamingStage = 'complete';
|
|
195
|
+
this.isStreaming = false;
|
|
196
|
+
|
|
197
|
+
// Final card state
|
|
198
|
+
this.card.sections[0].fields = [{ label: 'Status', value: 'Complete' }];
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
private delay(ms: number): Promise<void> {
|
|
202
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
onCardAction(event: { action: string; card: AICardConfig }): void {
|
|
206
|
+
console.log('Action:', event);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**HTML:**
|
|
212
|
+
|
|
213
|
+
```html
|
|
214
|
+
<button (click)="generateCard()" [disabled]="isStreaming">
|
|
215
|
+
{{ isStreaming ? 'Generating...' : 'Generate Card' }}
|
|
216
|
+
</button>
|
|
217
|
+
|
|
218
|
+
<osi-cards-container [theme]="cardTheme">
|
|
219
|
+
<app-ai-card-renderer
|
|
220
|
+
[cardConfig]="card"
|
|
221
|
+
[isStreaming]="isStreaming"
|
|
222
|
+
[streamingStage]="streamingStage"
|
|
223
|
+
[streamingProgress]="streamingProgress"
|
|
224
|
+
[showLoadingByDefault]="true"
|
|
225
|
+
[loadingMessages]="loadingMessages"
|
|
226
|
+
[loadingTitle]="'AI Analysis'"
|
|
227
|
+
(cardInteraction)="onCardAction($event)">
|
|
228
|
+
</app-ai-card-renderer>
|
|
229
|
+
</osi-cards-container>
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**Key Settings:**
|
|
233
|
+
- `[isStreaming]="isStreaming"` → Controls streaming animation
|
|
234
|
+
- `[streamingStage]="streamingStage"` → `'idle'` | `'thinking'` | `'streaming'` | `'complete'`
|
|
235
|
+
- `[streamingProgress]="streamingProgress"` → Progress bar (0-1)
|
|
236
|
+
- `[showLoadingByDefault]="true"` → Shows loading when no card data
|
|
237
|
+
- `[loadingMessages]` → Custom messages during loading
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
### Comparison Table
|
|
242
|
+
|
|
243
|
+
| Feature | Static Card | Streaming Card |
|
|
244
|
+
|---------|-------------|----------------|
|
|
245
|
+
| `[cardConfig]` | Always provided | Starts `undefined`, built progressively |
|
|
246
|
+
| `[streamingStage]` | `'complete'` | `'idle'` → `'thinking'` → `'streaming'` → `'complete'` |
|
|
247
|
+
| `[showLoadingByDefault]` | `false` | `true` |
|
|
248
|
+
| `[isStreaming]` | Not needed | `true` during generation |
|
|
249
|
+
| `[streamingProgress]` | Not needed | `0` to `1` |
|
|
250
|
+
| Loading animation | None | Shows animated loading state |
|
|
251
|
+
| Use case | Pre-loaded data | AI/LLM generation |
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## Using Container + Renderer Pattern (Recommended for Lists)
|
|
256
|
+
|
|
257
|
+
When displaying cards in lists or needing more control, use `osi-cards-container` with `app-ai-card-renderer`:
|
|
258
|
+
|
|
259
|
+
### TypeScript
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
import { Component } from '@angular/core';
|
|
263
|
+
import {
|
|
264
|
+
OsiCardsContainerComponent,
|
|
265
|
+
AICardRendererComponent,
|
|
266
|
+
AICardConfig
|
|
267
|
+
} from 'osi-cards-lib';
|
|
268
|
+
|
|
269
|
+
@Component({
|
|
270
|
+
selector: 'app-card-list',
|
|
271
|
+
standalone: true,
|
|
272
|
+
imports: [OsiCardsContainerComponent, AICardRendererComponent],
|
|
273
|
+
templateUrl: './card-list.component.html'
|
|
274
|
+
})
|
|
275
|
+
export class CardListComponent {
|
|
276
|
+
cardTheme: 'day' | 'night' = 'day';
|
|
277
|
+
cardContainerWidth = 600; // Optional: explicit width
|
|
278
|
+
|
|
279
|
+
cards: { id: string; card: AICardConfig }[] = [
|
|
280
|
+
{
|
|
281
|
+
id: '1',
|
|
282
|
+
card: {
|
|
283
|
+
cardTitle: 'Card 1',
|
|
284
|
+
sections: [{ title: 'Info', type: 'info', fields: [{ label: 'Status', value: 'Active' }] }]
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
id: '2',
|
|
289
|
+
card: {
|
|
290
|
+
cardTitle: 'Card 2',
|
|
291
|
+
sections: [{ title: 'Info', type: 'info', fields: [{ label: 'Status', value: 'Pending' }] }]
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
];
|
|
295
|
+
|
|
296
|
+
onCardActionClick(event: { action: string; card: AICardConfig }): void {
|
|
297
|
+
console.log('Action clicked:', event);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### HTML
|
|
303
|
+
|
|
304
|
+
```html
|
|
305
|
+
<!-- Loop through cards -->
|
|
306
|
+
@for (item of cards; track item.id) {
|
|
307
|
+
<osi-cards-container [theme]="cardTheme">
|
|
308
|
+
<app-ai-card-renderer
|
|
309
|
+
[cardConfig]="item.card"
|
|
310
|
+
[containerWidth]="cardContainerWidth"
|
|
311
|
+
[streamingStage]="'complete'"
|
|
312
|
+
[showLoadingByDefault]="false"
|
|
313
|
+
(cardInteraction)="onCardActionClick($event)">
|
|
314
|
+
</app-ai-card-renderer>
|
|
315
|
+
</osi-cards-container>
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Why Use This Pattern?
|
|
320
|
+
|
|
321
|
+
- **Theme at container level** - Apply theme once for all nested cards
|
|
322
|
+
- **CSS isolation** - Container provides style boundaries
|
|
323
|
+
- **Explicit control** - Fine-grained control over each card's behavior
|
|
324
|
+
- **No loading state** - `[showLoadingByDefault]="false"` for static data
|
|
325
|
+
- **Complete stage** - `[streamingStage]="'complete'"` marks card as fully loaded
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## Using AICardRendererComponent (Lower-Level API)
|
|
330
|
+
|
|
331
|
+
For more control, use `AICardRendererComponent` directly:
|
|
332
|
+
|
|
333
|
+
### TypeScript
|
|
334
|
+
|
|
335
|
+
```typescript
|
|
336
|
+
import { Component } from '@angular/core';
|
|
337
|
+
import { AICardRendererComponent, AICardConfig, CardFieldInteractionEvent } from 'osi-cards-lib';
|
|
338
|
+
|
|
339
|
+
@Component({
|
|
340
|
+
selector: 'app-card-demo',
|
|
341
|
+
standalone: true,
|
|
342
|
+
imports: [AICardRendererComponent],
|
|
343
|
+
templateUrl: './card-demo.component.html'
|
|
344
|
+
})
|
|
345
|
+
export class CardDemoComponent {
|
|
346
|
+
card: AICardConfig = {
|
|
347
|
+
cardTitle: 'My Card',
|
|
348
|
+
sections: [
|
|
349
|
+
{
|
|
350
|
+
title: 'Overview',
|
|
351
|
+
type: 'overview',
|
|
352
|
+
fields: [
|
|
353
|
+
{ label: 'Status', value: 'Active' },
|
|
354
|
+
{ label: 'Type', value: 'Premium' }
|
|
33
355
|
]
|
|
34
356
|
}
|
|
35
357
|
]
|
|
36
358
|
};
|
|
359
|
+
|
|
360
|
+
onFieldClick(event: CardFieldInteractionEvent): void {
|
|
361
|
+
console.log('Field clicked:', event);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
onAgentAction(event: any): void {
|
|
365
|
+
console.log('Agent action triggered:', event);
|
|
366
|
+
}
|
|
37
367
|
}
|
|
38
368
|
```
|
|
39
369
|
|
|
370
|
+
### HTML
|
|
371
|
+
|
|
372
|
+
```html
|
|
373
|
+
<app-ai-card-renderer
|
|
374
|
+
[cardConfig]="card"
|
|
375
|
+
[tiltEnabled]="true"
|
|
376
|
+
(fieldInteraction)="onFieldClick($event)"
|
|
377
|
+
(agentAction)="onAgentAction($event)">
|
|
378
|
+
</app-ai-card-renderer>
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## Usage With Streaming
|
|
384
|
+
|
|
385
|
+
For AI/LLM streaming scenarios:
|
|
386
|
+
|
|
387
|
+
### TypeScript
|
|
388
|
+
|
|
389
|
+
```typescript
|
|
390
|
+
import { Component } from '@angular/core';
|
|
391
|
+
import { OsiCardsComponent, AICardConfig, StreamingStage } from 'osi-cards-lib';
|
|
392
|
+
|
|
393
|
+
@Component({
|
|
394
|
+
selector: 'app-streaming-demo',
|
|
395
|
+
standalone: true,
|
|
396
|
+
imports: [OsiCardsComponent],
|
|
397
|
+
templateUrl: './streaming-demo.component.html'
|
|
398
|
+
})
|
|
399
|
+
export class StreamingDemoComponent {
|
|
400
|
+
card: AICardConfig | undefined;
|
|
401
|
+
isStreaming = false;
|
|
402
|
+
streamingStage: StreamingStage = 'idle';
|
|
403
|
+
streamingProgress = 0;
|
|
404
|
+
|
|
405
|
+
// Custom loading messages (optional)
|
|
406
|
+
loadingMessages = [
|
|
407
|
+
'Analyzing data...',
|
|
408
|
+
'Processing results...',
|
|
409
|
+
'Almost there...'
|
|
410
|
+
];
|
|
411
|
+
|
|
412
|
+
startStreaming(): void {
|
|
413
|
+
this.isStreaming = true;
|
|
414
|
+
this.streamingStage = 'thinking';
|
|
415
|
+
|
|
416
|
+
// Simulate streaming - in real app, this comes from your AI service
|
|
417
|
+
setTimeout(() => {
|
|
418
|
+
this.streamingStage = 'streaming';
|
|
419
|
+
this.simulateCardStreaming();
|
|
420
|
+
}, 2000);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
private simulateCardStreaming(): void {
|
|
424
|
+
// Progressively build card
|
|
425
|
+
this.streamingProgress = 0.3;
|
|
426
|
+
this.card = {
|
|
427
|
+
cardTitle: 'Generating...',
|
|
428
|
+
sections: []
|
|
429
|
+
};
|
|
430
|
+
|
|
431
|
+
setTimeout(() => {
|
|
432
|
+
this.streamingProgress = 0.7;
|
|
433
|
+
this.card = {
|
|
434
|
+
cardTitle: 'Analysis Results',
|
|
435
|
+
sections: [
|
|
436
|
+
{ title: 'Summary', type: 'info', fields: [{ label: 'Status', value: 'Processing' }] }
|
|
437
|
+
]
|
|
438
|
+
};
|
|
439
|
+
}, 1000);
|
|
440
|
+
|
|
441
|
+
setTimeout(() => {
|
|
442
|
+
this.streamingProgress = 1;
|
|
443
|
+
this.streamingStage = 'complete';
|
|
444
|
+
this.isStreaming = false;
|
|
445
|
+
this.card = {
|
|
446
|
+
cardTitle: 'Analysis Results',
|
|
447
|
+
sections: [
|
|
448
|
+
{ title: 'Summary', type: 'info', fields: [{ label: 'Status', value: 'Complete' }] },
|
|
449
|
+
{ title: 'Metrics', type: 'analytics', fields: [{ label: 'Score', value: '95%' }] }
|
|
450
|
+
]
|
|
451
|
+
};
|
|
452
|
+
}, 2000);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
### HTML
|
|
458
|
+
|
|
459
|
+
```html
|
|
460
|
+
<button (click)="startStreaming()">Start Analysis</button>
|
|
461
|
+
|
|
462
|
+
<osi-cards
|
|
463
|
+
[card]="card"
|
|
464
|
+
[isStreaming]="isStreaming"
|
|
465
|
+
[streamingStage]="streamingStage"
|
|
466
|
+
[streamingProgress]="streamingProgress"
|
|
467
|
+
[loadingMessages]="loadingMessages"
|
|
468
|
+
[loadingTitle]="'Analyzing...'"
|
|
469
|
+
[showLoadingByDefault]="true">
|
|
470
|
+
</osi-cards>
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
---
|
|
474
|
+
|
|
475
|
+
## Theme Configuration
|
|
476
|
+
|
|
477
|
+
**Theme is NOT mandatory.** Cards default to `'day'` (light theme).
|
|
478
|
+
|
|
479
|
+
### Per-Component Theme
|
|
480
|
+
|
|
481
|
+
```html
|
|
482
|
+
<!-- Light theme (default) -->
|
|
483
|
+
<osi-cards [card]="card"></osi-cards>
|
|
484
|
+
|
|
485
|
+
<!-- Explicit light theme -->
|
|
486
|
+
<osi-cards [card]="card" [theme]="'day'"></osi-cards>
|
|
487
|
+
|
|
488
|
+
<!-- Dark theme -->
|
|
489
|
+
<osi-cards [card]="card" [theme]="'night'"></osi-cards>
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
### Global Theme via Provider
|
|
493
|
+
|
|
494
|
+
```typescript
|
|
495
|
+
import { ApplicationConfig } from '@angular/core';
|
|
496
|
+
import { provideOSICards } from 'osi-cards-lib';
|
|
497
|
+
|
|
498
|
+
export const appConfig: ApplicationConfig = {
|
|
499
|
+
providers: [
|
|
500
|
+
provideOSICards({
|
|
501
|
+
defaultTheme: 'night' // Set global default theme
|
|
502
|
+
})
|
|
503
|
+
]
|
|
504
|
+
};
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
### Dynamic Theme Switching
|
|
508
|
+
|
|
509
|
+
```typescript
|
|
510
|
+
import { Component, inject } from '@angular/core';
|
|
511
|
+
import { ThemeService } from 'osi-cards-lib';
|
|
512
|
+
|
|
513
|
+
@Component({...})
|
|
514
|
+
export class MyComponent {
|
|
515
|
+
private themeService = inject(ThemeService);
|
|
516
|
+
|
|
517
|
+
toggleTheme(): void {
|
|
518
|
+
this.themeService.toggleTheme();
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
setDarkTheme(): void {
|
|
522
|
+
this.themeService.setTheme('dark');
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
followSystem(): void {
|
|
526
|
+
this.themeService.setTheme('system');
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
---
|
|
532
|
+
|
|
533
|
+
## Complete Example
|
|
534
|
+
|
|
535
|
+
### `app.config.ts`
|
|
536
|
+
|
|
537
|
+
```typescript
|
|
538
|
+
import { ApplicationConfig } from '@angular/core';
|
|
539
|
+
import { provideRouter } from '@angular/router';
|
|
540
|
+
import { provideOSICards } from 'osi-cards-lib';
|
|
541
|
+
|
|
542
|
+
export const appConfig: ApplicationConfig = {
|
|
543
|
+
providers: [
|
|
544
|
+
provideOSICards(), // Enable library with animations
|
|
545
|
+
provideRouter([])
|
|
546
|
+
]
|
|
547
|
+
};
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
### `styles.scss`
|
|
551
|
+
|
|
552
|
+
```scss
|
|
553
|
+
@import 'osi-cards-lib/styles/_styles';
|
|
554
|
+
|
|
555
|
+
// Optional: Override theme variables
|
|
556
|
+
:root {
|
|
557
|
+
--osi-card-accent: #6366f1;
|
|
558
|
+
}
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
### `card-page.component.ts`
|
|
562
|
+
|
|
563
|
+
```typescript
|
|
564
|
+
import { Component } from '@angular/core';
|
|
565
|
+
import { OsiCardsComponent, AICardConfig, CardFieldInteractionEvent } from 'osi-cards-lib';
|
|
566
|
+
|
|
567
|
+
@Component({
|
|
568
|
+
selector: 'app-card-page',
|
|
569
|
+
standalone: true,
|
|
570
|
+
imports: [OsiCardsComponent],
|
|
571
|
+
template: `
|
|
572
|
+
<div class="page-container">
|
|
573
|
+
<h1>Company Profile</h1>
|
|
574
|
+
|
|
575
|
+
<osi-cards
|
|
576
|
+
[card]="companyCard"
|
|
577
|
+
[tiltEnabled]="true"
|
|
578
|
+
(fieldClick)="handleFieldClick($event)"
|
|
579
|
+
(actionClick)="handleAction($event)">
|
|
580
|
+
</osi-cards>
|
|
581
|
+
</div>
|
|
582
|
+
`,
|
|
583
|
+
styles: [`
|
|
584
|
+
.page-container {
|
|
585
|
+
max-width: 900px;
|
|
586
|
+
margin: 0 auto;
|
|
587
|
+
padding: 2rem;
|
|
588
|
+
}
|
|
589
|
+
`]
|
|
590
|
+
})
|
|
591
|
+
export class CardPageComponent {
|
|
592
|
+
companyCard: AICardConfig = {
|
|
593
|
+
cardTitle: 'Acme Corporation',
|
|
594
|
+
cardSubtitle: 'Global Technology Leader',
|
|
595
|
+
sections: [
|
|
596
|
+
{
|
|
597
|
+
title: 'Company Overview',
|
|
598
|
+
type: 'overview',
|
|
599
|
+
fields: [
|
|
600
|
+
{ label: 'Industry', value: 'Enterprise Software' },
|
|
601
|
+
{ label: 'Founded', value: '2010' },
|
|
602
|
+
{ label: 'Headquarters', value: 'San Francisco, CA' },
|
|
603
|
+
{ label: 'Employees', value: '2,500+' }
|
|
604
|
+
]
|
|
605
|
+
},
|
|
606
|
+
{
|
|
607
|
+
title: 'Key Metrics',
|
|
608
|
+
type: 'analytics',
|
|
609
|
+
fields: [
|
|
610
|
+
{ label: 'Annual Revenue', value: '$150M', trend: 'up', change: 25 },
|
|
611
|
+
{ label: 'Market Share', value: '18%', trend: 'up', change: 3 },
|
|
612
|
+
{ label: 'Customer Growth', value: '+340', trend: 'up' },
|
|
613
|
+
{ label: 'NPS Score', value: '72', trend: 'stable' }
|
|
614
|
+
]
|
|
615
|
+
},
|
|
616
|
+
{
|
|
617
|
+
title: 'Leadership Team',
|
|
618
|
+
type: 'contact-card',
|
|
619
|
+
fields: [
|
|
620
|
+
{ name: 'Jane Smith', role: 'CEO', email: 'jane@acme.com' },
|
|
621
|
+
{ name: 'John Doe', role: 'CTO', email: 'john@acme.com' }
|
|
622
|
+
]
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
title: 'Products & Services',
|
|
626
|
+
type: 'list',
|
|
627
|
+
items: [
|
|
628
|
+
{ title: 'Enterprise Platform', description: 'Core business solution' },
|
|
629
|
+
{ title: 'Analytics Suite', description: 'Data insights and reporting' },
|
|
630
|
+
{ title: 'Integration Hub', description: 'Connect your tools' }
|
|
631
|
+
]
|
|
632
|
+
}
|
|
633
|
+
],
|
|
634
|
+
actions: [
|
|
635
|
+
{ type: 'website', label: 'Visit Website', variant: 'primary', url: 'https://acme.com' },
|
|
636
|
+
{ type: 'mail', label: 'Contact Sales', variant: 'outline', email: { contact: { email: 'sales@acme.com' }, subject: 'Inquiry' } },
|
|
637
|
+
{ type: 'agent', label: 'Ask AI Assistant', variant: 'ghost', agentId: 'sales-bot' }
|
|
638
|
+
]
|
|
639
|
+
};
|
|
640
|
+
|
|
641
|
+
handleFieldClick(event: CardFieldInteractionEvent): void {
|
|
642
|
+
console.log('Field clicked:', event);
|
|
643
|
+
// Handle field interactions
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
handleAction(event: { action: string; card: AICardConfig }): void {
|
|
647
|
+
console.log('Action clicked:', event);
|
|
648
|
+
// Handle action button clicks
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
---
|
|
654
|
+
|
|
655
|
+
## Component API Reference
|
|
656
|
+
|
|
657
|
+
### OsiCardsComponent (`<osi-cards>`)
|
|
658
|
+
|
|
659
|
+
High-level wrapper component with simplified API.
|
|
660
|
+
|
|
661
|
+
**Inputs:**
|
|
662
|
+
|
|
663
|
+
| Input | Type | Default | Required | Description |
|
|
664
|
+
|-------|------|---------|----------|-------------|
|
|
665
|
+
| `card` | `AICardConfig` | `undefined` | No | The card configuration to render |
|
|
666
|
+
| `theme` | `'day' \| 'night'` | `'day'` | No | Theme to apply |
|
|
667
|
+
| `fullscreen` | `boolean` | `false` | No | Display in fullscreen mode |
|
|
668
|
+
| `tiltEnabled` | `boolean` | `true` | No | Enable 3D tilt effect on hover |
|
|
669
|
+
| `containerWidth` | `number` | auto | No | Explicit container width for layout |
|
|
670
|
+
| `isStreaming` | `boolean` | `false` | No | Whether streaming is active |
|
|
671
|
+
| `streamingStage` | `StreamingStage` | `undefined` | No | Current streaming stage |
|
|
672
|
+
| `streamingProgress` | `number` | `0` | No | Streaming progress (0-1) |
|
|
673
|
+
| `showLoadingByDefault` | `boolean` | `true` | No | Show loading state when no card |
|
|
674
|
+
| `loadingMessages` | `string[]` | defaults | No | Custom loading messages |
|
|
675
|
+
| `loadingTitle` | `string` | `'Creating OSI Card'` | No | Loading state title |
|
|
676
|
+
|
|
677
|
+
**Outputs:**
|
|
678
|
+
|
|
679
|
+
| Output | Type | Description |
|
|
680
|
+
|--------|------|-------------|
|
|
681
|
+
| `fieldClick` | `CardFieldInteractionEvent` | Emitted when a field is clicked |
|
|
682
|
+
| `actionClick` | `{ action: string; card: AICardConfig }` | Emitted when an action button is clicked |
|
|
683
|
+
| `fullscreenChange` | `boolean` | Emitted when fullscreen is toggled |
|
|
684
|
+
| `agentAction` | `{ action, card, agentId?, context? }` | Emitted for agent-type actions |
|
|
685
|
+
| `questionAction` | `{ action, card, question? }` | Emitted for question-type actions |
|
|
686
|
+
| `export` | `void` | Emitted when export is requested |
|
|
687
|
+
|
|
688
|
+
---
|
|
689
|
+
|
|
690
|
+
### OsiCardsContainerComponent (`<osi-cards-container>`)
|
|
691
|
+
|
|
692
|
+
Container wrapper for theme and CSS isolation.
|
|
693
|
+
|
|
694
|
+
**Inputs:**
|
|
695
|
+
|
|
696
|
+
| Input | Type | Default | Required | Description |
|
|
697
|
+
|-------|------|---------|----------|-------------|
|
|
698
|
+
| `theme` | `'day' \| 'night'` | `'day'` | No | Theme to apply to container |
|
|
699
|
+
| `strictIsolation` | `boolean` | `false` | No | Enable strict CSS containment |
|
|
700
|
+
|
|
701
|
+
**Usage:**
|
|
702
|
+
|
|
703
|
+
```html
|
|
704
|
+
<osi-cards-container [theme]="'night'">
|
|
705
|
+
<app-ai-card-renderer [cardConfig]="card"></app-ai-card-renderer>
|
|
706
|
+
</osi-cards-container>
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
---
|
|
710
|
+
|
|
711
|
+
### AICardRendererComponent (`<app-ai-card-renderer>`)
|
|
712
|
+
|
|
713
|
+
Core rendering component with full control.
|
|
714
|
+
|
|
715
|
+
**Inputs:**
|
|
716
|
+
|
|
717
|
+
| Input | Type | Default | Required | Description |
|
|
718
|
+
|-------|------|---------|----------|-------------|
|
|
719
|
+
| `cardConfig` | `AICardConfig` | `undefined` | No | The card configuration |
|
|
720
|
+
| `isFullscreen` | `boolean` | `false` | No | Fullscreen mode |
|
|
721
|
+
| `tiltEnabled` | `boolean` | `true` | No | Enable 3D tilt effect |
|
|
722
|
+
| `streamingStage` | `StreamingStage` | `undefined` | No | `'idle'` \| `'thinking'` \| `'streaming'` \| `'complete'` |
|
|
723
|
+
| `streamingProgress` | `number` | `undefined` | No | Progress 0-1 |
|
|
724
|
+
| `isStreaming` | `boolean` | `false` | No | Streaming animation state |
|
|
725
|
+
| `showLoadingByDefault` | `boolean` | `true` | No | Show loading when no data |
|
|
726
|
+
| `containerWidth` | `number` | auto | No | Explicit width for masonry |
|
|
727
|
+
| `loadingMessages` | `string[]` | defaults | No | Custom loading messages |
|
|
728
|
+
| `loadingTitle` | `string` | `'Creating OSI Card'` | No | Loading title |
|
|
729
|
+
| `updateSource` | `'stream' \| 'liveEdit'` | `'stream'` | No | Update source mode |
|
|
730
|
+
|
|
731
|
+
**Outputs:**
|
|
732
|
+
|
|
733
|
+
| Output | Type | Description |
|
|
734
|
+
|--------|------|-------------|
|
|
735
|
+
| `fieldInteraction` | `CardFieldInteractionEvent` | Field clicked |
|
|
736
|
+
| `cardInteraction` | `{ action: string; card: AICardConfig }` | Action button clicked |
|
|
737
|
+
| `fullscreenToggle` | `boolean` | Fullscreen toggled |
|
|
738
|
+
| `agentAction` | `{ action, card, agentId?, context? }` | Agent action |
|
|
739
|
+
| `questionAction` | `{ action, card, question? }` | Question action |
|
|
740
|
+
| `export` | `void` | Export requested |
|
|
741
|
+
|
|
742
|
+
**Minimal Usage (Static Card, No Loading):**
|
|
743
|
+
|
|
744
|
+
```html
|
|
745
|
+
<app-ai-card-renderer
|
|
746
|
+
[cardConfig]="card"
|
|
747
|
+
[streamingStage]="'complete'"
|
|
748
|
+
[showLoadingByDefault]="false">
|
|
749
|
+
</app-ai-card-renderer>
|
|
750
|
+
```
|
|
751
|
+
|
|
752
|
+
---
|
|
753
|
+
|
|
754
|
+
## Section Types
|
|
755
|
+
|
|
756
|
+
| Type | Description | Data Property |
|
|
757
|
+
|------|-------------|---------------|
|
|
758
|
+
| `info` | General information fields | `fields` |
|
|
759
|
+
| `overview` | Summary/overview section | `fields` |
|
|
760
|
+
| `analytics` | KPIs and metrics with trends | `fields` |
|
|
761
|
+
| `chart` | Charts (bar, line, pie, doughnut) | `chartData` or `fields` |
|
|
762
|
+
| `list` | Lists with items | `items` |
|
|
763
|
+
| `contact-card` | Contact information | `fields` |
|
|
764
|
+
| `network-card` | Professional network | `items` |
|
|
765
|
+
| `map` | Geographic locations | `fields` or `items` |
|
|
766
|
+
| `event` | Timeline/events | `items` |
|
|
767
|
+
| `product` | Product listings | `items` |
|
|
768
|
+
| `solutions` | Solutions/services | `items` |
|
|
769
|
+
| `financials` | Financial data | `fields` |
|
|
770
|
+
| `quotation` | Quotes/testimonials | `fields` |
|
|
771
|
+
| `text-reference` | Citations/references | `fields` |
|
|
772
|
+
| `brand-colors` | Color palettes | `items` |
|
|
773
|
+
| `news` | News articles | `items` |
|
|
774
|
+
| `social-media` | Social profiles | `items` |
|
|
775
|
+
|
|
776
|
+
---
|
|
777
|
+
|
|
778
|
+
## Card Presets
|
|
779
|
+
|
|
780
|
+
Quickly create common card types:
|
|
781
|
+
|
|
782
|
+
```typescript
|
|
783
|
+
import { PresetFactory } from 'osi-cards-lib';
|
|
784
|
+
|
|
785
|
+
// Company card
|
|
786
|
+
const companyCard = PresetFactory.createCompany({
|
|
787
|
+
name: 'Acme Corp',
|
|
788
|
+
industry: 'Technology',
|
|
789
|
+
employees: '500+',
|
|
790
|
+
websiteUrl: 'https://acme.com'
|
|
791
|
+
});
|
|
792
|
+
|
|
793
|
+
// Analytics dashboard
|
|
794
|
+
const analyticsCard = PresetFactory.createAnalytics({
|
|
795
|
+
title: 'Sales Performance',
|
|
796
|
+
kpis: [
|
|
797
|
+
{ label: 'Revenue', value: '$1.2M', percentage: 105, trend: 'up' }
|
|
798
|
+
]
|
|
799
|
+
});
|
|
800
|
+
|
|
801
|
+
// Contact card
|
|
802
|
+
const contactCard = PresetFactory.createContact({
|
|
803
|
+
name: 'John Doe',
|
|
804
|
+
email: 'john@example.com'
|
|
805
|
+
});
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
---
|
|
809
|
+
|
|
810
|
+
## Troubleshooting
|
|
811
|
+
|
|
812
|
+
### Animations not working
|
|
813
|
+
|
|
814
|
+
Ensure you've added `provideOSICards()` to your `app.config.ts`:
|
|
815
|
+
|
|
816
|
+
```typescript
|
|
817
|
+
providers: [
|
|
818
|
+
provideOSICards() // Required!
|
|
819
|
+
]
|
|
820
|
+
```
|
|
821
|
+
|
|
822
|
+
### Styles not loading
|
|
823
|
+
|
|
824
|
+
Import styles in your `styles.scss`:
|
|
825
|
+
|
|
826
|
+
```scss
|
|
827
|
+
@import 'osi-cards-lib/styles/_styles';
|
|
828
|
+
```
|
|
829
|
+
|
|
830
|
+
### Icons not showing
|
|
831
|
+
|
|
832
|
+
Ensure `lucide-angular` is installed:
|
|
833
|
+
|
|
834
|
+
```bash
|
|
835
|
+
npm install lucide-angular@^0.548.0
|
|
836
|
+
```
|
|
837
|
+
|
|
838
|
+
---
|
|
839
|
+
|
|
40
840
|
## Documentation
|
|
41
841
|
|
|
42
|
-
|
|
842
|
+
- [Detailed Usage Guide](./USAGE.md)
|
|
843
|
+
- [Import Examples](./IMPORT_EXAMPLE.md)
|
|
844
|
+
|
|
845
|
+
## License
|
|
846
|
+
|
|
847
|
+
MIT
|
|
43
848
|
|
|
44
849
|
## Version
|
|
45
850
|
|
|
46
|
-
1.
|
|
851
|
+
1.5.3
|