@risalabs_frontend_org/oasis-ui-kit 0.1.0 → 0.3.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 +510 -14
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/src/components/button/button.d.ts +1 -0
- package/dist/src/components/toast/toast.d.ts +5 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,25 +1,521 @@
|
|
|
1
|
-
# RISA Oasis
|
|
1
|
+
# RISA Oasis UI Kit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A comprehensive React UI component library built with TypeScript and SCSS, featuring 25+ production-ready components for building modern web applications.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Installation
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
```bash
|
|
8
|
+
npm install @risalabs_frontend_org/oasis-ui-kit
|
|
9
|
+
```
|
|
8
10
|
|
|
9
|
-
##
|
|
11
|
+
## ⚠️ Important Notes
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
- **DO NOT** increase build number in `package.json`
|
|
14
|
+
- **DO NOT** publish manually - the CI/CD pipeline handles publishing
|
|
12
15
|
|
|
13
|
-
|
|
16
|
+
---
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
## Development
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
Open [http://localhost:6006](http://localhost:6006) to view it in the browser.
|
|
20
|
+
### Prerequisites
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
- Node.js (v18 or higher recommended)
|
|
23
|
+
- npm
|
|
22
24
|
|
|
23
|
-
###
|
|
25
|
+
### Getting Started
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
```bash
|
|
28
|
+
# Install dependencies
|
|
29
|
+
npm install
|
|
30
|
+
|
|
31
|
+
# Start Storybook development server
|
|
32
|
+
npm run storybook
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Open [http://localhost:6006](http://localhost:6006) to view the component library in your browser.
|
|
36
|
+
|
|
37
|
+
### Available Scripts
|
|
38
|
+
|
|
39
|
+
| Command | Description |
|
|
40
|
+
|---------|-------------|
|
|
41
|
+
| `npm run storybook` | Start Storybook dev server on port 6006 |
|
|
42
|
+
| `npm run build-storybook` | Build static Storybook site |
|
|
43
|
+
| `npm run build` | Build the library for production |
|
|
44
|
+
| `npm run test` | Run unit tests with Jest |
|
|
45
|
+
| `npm run chromatic` | Run visual regression tests with Chromatic |
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Components
|
|
50
|
+
|
|
51
|
+
### Form Controls
|
|
52
|
+
|
|
53
|
+
#### `Button`
|
|
54
|
+
A versatile button component with multiple variants and sizes.
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
import { Button } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
58
|
+
|
|
59
|
+
<Button
|
|
60
|
+
buttonType="primary" // "primary" | "secondary" | "tertiary" | "danger"
|
|
61
|
+
size="medium" // "small" | "medium" | "large"
|
|
62
|
+
disabled={false}
|
|
63
|
+
onClick={() => {}}
|
|
64
|
+
>
|
|
65
|
+
Click Me
|
|
66
|
+
</Button>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
#### `ButtonWithDropdown`
|
|
70
|
+
A split button with dropdown menu functionality.
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
import { ButtonWithDropdown } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
74
|
+
|
|
75
|
+
<ButtonWithDropdown
|
|
76
|
+
buttonType="primary"
|
|
77
|
+
size="medium"
|
|
78
|
+
disabled={false}
|
|
79
|
+
menuData={[
|
|
80
|
+
{ label: 'Option 1', onClick: (item) => console.log(item) },
|
|
81
|
+
{ label: 'Option 2', onClick: (item) => console.log(item), color: '#ff0000' }
|
|
82
|
+
]}
|
|
83
|
+
alwaysOpenDropdown={false} // If false, content and chevron act independently
|
|
84
|
+
onButtonClick={() => {}} // Called when content area is clicked (split mode)
|
|
85
|
+
>
|
|
86
|
+
Actions
|
|
87
|
+
</ButtonWithDropdown>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
#### `TextInput`
|
|
91
|
+
A flexible text input with label, validation, formatting, and password visibility toggle.
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
import { TextInput } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
95
|
+
|
|
96
|
+
<TextInput
|
|
97
|
+
id="username"
|
|
98
|
+
label="Username"
|
|
99
|
+
placeholder="Enter username"
|
|
100
|
+
required={true}
|
|
101
|
+
type="text" // "text" | "number"
|
|
102
|
+
textHidden={false} // Enable password mode
|
|
103
|
+
error="Invalid username"
|
|
104
|
+
onChange={(data) => console.log(data)}
|
|
105
|
+
onBlur={(data) => console.log(data)}
|
|
106
|
+
formatInput={(value) => value.toUpperCase()} // Custom formatting
|
|
107
|
+
/>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
#### `Select`
|
|
111
|
+
A custom dropdown select component with search and validation.
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
import { Select } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
115
|
+
|
|
116
|
+
<Select
|
|
117
|
+
id="country"
|
|
118
|
+
label="Country"
|
|
119
|
+
placeholder="Select a country"
|
|
120
|
+
options={[
|
|
121
|
+
{ value: 'us', label: 'United States' },
|
|
122
|
+
{ value: 'uk', label: 'United Kingdom' }
|
|
123
|
+
]}
|
|
124
|
+
required={true}
|
|
125
|
+
onOptionChange={(data) => console.log(data)}
|
|
126
|
+
/>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
#### `CheckBox`
|
|
130
|
+
A styled checkbox component.
|
|
131
|
+
|
|
132
|
+
```tsx
|
|
133
|
+
import { CheckBox } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
134
|
+
|
|
135
|
+
<CheckBox
|
|
136
|
+
id="terms"
|
|
137
|
+
label="I agree to the terms"
|
|
138
|
+
defaultValue={false}
|
|
139
|
+
isDisabled={false}
|
|
140
|
+
onCheckBoxValueChange={(data) => console.log(data)}
|
|
141
|
+
/>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
#### `Toggle` & `ToggleSwitch`
|
|
145
|
+
Toggle switch components for boolean settings.
|
|
146
|
+
|
|
147
|
+
```tsx
|
|
148
|
+
import { Toggle, ToggleSwitch } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
149
|
+
|
|
150
|
+
// Toggle with label
|
|
151
|
+
<Toggle
|
|
152
|
+
id="notifications"
|
|
153
|
+
label="Enable Notifications"
|
|
154
|
+
defaultValue={true}
|
|
155
|
+
onChange={(data) => console.log(data)}
|
|
156
|
+
/>
|
|
157
|
+
|
|
158
|
+
// Standalone toggle switch
|
|
159
|
+
<ToggleSwitch
|
|
160
|
+
id="darkMode"
|
|
161
|
+
defaultChecked={false}
|
|
162
|
+
onChangeEmit={(data) => console.log(data)}
|
|
163
|
+
/>
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Date & Time Components
|
|
167
|
+
|
|
168
|
+
#### `DateInput`
|
|
169
|
+
A date input with custom format support using moment.js.
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
import { DateInput } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
173
|
+
|
|
174
|
+
<DateInput
|
|
175
|
+
id="birthdate"
|
|
176
|
+
label="Date of Birth"
|
|
177
|
+
placeholder="Select date"
|
|
178
|
+
format="DD/MM/YYYY" // Custom display format
|
|
179
|
+
required={true}
|
|
180
|
+
onChange={(data) => console.log(data)}
|
|
181
|
+
onBlur={(data) => console.log(data)}
|
|
182
|
+
/>
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
#### `DatePicker`
|
|
186
|
+
A calendar-based date picker component.
|
|
187
|
+
|
|
188
|
+
```tsx
|
|
189
|
+
import { DatePicker } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
190
|
+
|
|
191
|
+
<DatePicker
|
|
192
|
+
initialDate={new Date()}
|
|
193
|
+
onDateChange={(date) => console.log(date)}
|
|
194
|
+
/>
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
#### `DateRangeCalendar`
|
|
198
|
+
A calendar for selecting date ranges with month/year selectors.
|
|
199
|
+
|
|
200
|
+
```tsx
|
|
201
|
+
import { DateRangeCalendar } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
202
|
+
|
|
203
|
+
<DateRangeCalendar
|
|
204
|
+
initialStartDate={new Date()}
|
|
205
|
+
initialEndDate={new Date()}
|
|
206
|
+
onDateRangeChange={(startDate, endDate) => console.log(startDate, endDate)}
|
|
207
|
+
resetSelection={false}
|
|
208
|
+
/>
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
#### `TimeDue`
|
|
212
|
+
Component for displaying time-related information.
|
|
213
|
+
|
|
214
|
+
```tsx
|
|
215
|
+
import { TimeDue } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
216
|
+
|
|
217
|
+
<TimeDue {...props} />
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### File Handling
|
|
221
|
+
|
|
222
|
+
#### `FileUpload`
|
|
223
|
+
A file upload component with preview and delete functionality.
|
|
224
|
+
|
|
225
|
+
```tsx
|
|
226
|
+
import { FileUpload } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
227
|
+
|
|
228
|
+
<FileUpload
|
|
229
|
+
id="documents"
|
|
230
|
+
deleteUploadedFile={() => {}}
|
|
231
|
+
/>
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
#### `AttachmentCard`
|
|
235
|
+
Display uploaded files with upload progress indicator.
|
|
236
|
+
|
|
237
|
+
```tsx
|
|
238
|
+
import { AttachmentCard } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
239
|
+
|
|
240
|
+
<AttachmentCard
|
|
241
|
+
title="document.pdf"
|
|
242
|
+
isUploading={true}
|
|
243
|
+
uploadProgress={65}
|
|
244
|
+
onDelete={() => {}}
|
|
245
|
+
/>
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
#### `UploadedFileBanner`
|
|
249
|
+
Banner display for uploaded files.
|
|
250
|
+
|
|
251
|
+
```tsx
|
|
252
|
+
import { UploadedFileBanner } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
253
|
+
|
|
254
|
+
<UploadedFileBanner {...props} />
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Navigation
|
|
258
|
+
|
|
259
|
+
#### `SideNavigation`
|
|
260
|
+
A vertical side navigation with tab-style content switching.
|
|
261
|
+
|
|
262
|
+
```tsx
|
|
263
|
+
import { SideNavigation } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
264
|
+
|
|
265
|
+
<SideNavigation
|
|
266
|
+
sideTabContent={[
|
|
267
|
+
{ id: 'profile', label: 'Profile', sideNavContent: ProfileComponent },
|
|
268
|
+
{ id: 'settings', label: 'Settings', sideNavContent: SettingsComponent }
|
|
269
|
+
]}
|
|
270
|
+
/>
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
#### `TabContainer` & `SingleTab`
|
|
274
|
+
Horizontal tab navigation components.
|
|
275
|
+
|
|
276
|
+
```tsx
|
|
277
|
+
import { TabContainer, SingleTab } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
278
|
+
|
|
279
|
+
<TabContainer {...props} />
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
#### `Pagination`
|
|
283
|
+
A pagination control with prev/next buttons.
|
|
284
|
+
|
|
285
|
+
```tsx
|
|
286
|
+
import { Pagination } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
287
|
+
|
|
288
|
+
<Pagination
|
|
289
|
+
currentPage={1}
|
|
290
|
+
totalPages={10}
|
|
291
|
+
onPrevious={() => {}}
|
|
292
|
+
onNext={() => {}}
|
|
293
|
+
disabled={false}
|
|
294
|
+
/>
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
#### `Stepper`
|
|
298
|
+
A vertical stepper for multi-step processes.
|
|
299
|
+
|
|
300
|
+
```tsx
|
|
301
|
+
import { Stepper } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
302
|
+
|
|
303
|
+
<Stepper
|
|
304
|
+
id={0}
|
|
305
|
+
currentActiveIndex={1}
|
|
306
|
+
label="Step 1: Personal Info"
|
|
307
|
+
stepperText="1"
|
|
308
|
+
showDashedLine={true}
|
|
309
|
+
/>
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Feedback & Overlays
|
|
313
|
+
|
|
314
|
+
#### `Modal`
|
|
315
|
+
A customizable modal dialog with header, body, and footer.
|
|
316
|
+
|
|
317
|
+
```tsx
|
|
318
|
+
import { Modal, openModal, closeModal } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
319
|
+
|
|
320
|
+
<Modal
|
|
321
|
+
dialogId="myModal"
|
|
322
|
+
title="Confirm Action"
|
|
323
|
+
saveButtonText="Confirm"
|
|
324
|
+
cancelText="Cancel"
|
|
325
|
+
onSave={() => {}}
|
|
326
|
+
onCancel={() => {}}
|
|
327
|
+
onClose={() => {}}
|
|
328
|
+
showSingleButton={false}
|
|
329
|
+
hideFooter={false}
|
|
330
|
+
disableSave={false}
|
|
331
|
+
>
|
|
332
|
+
<p>Are you sure you want to continue?</p>
|
|
333
|
+
</Modal>
|
|
334
|
+
|
|
335
|
+
// Control modal visibility
|
|
336
|
+
openModal('myModal');
|
|
337
|
+
closeModal('myModal');
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
#### `Toast`
|
|
341
|
+
Notification toast for success/error messages.
|
|
342
|
+
|
|
343
|
+
```tsx
|
|
344
|
+
import { Toast, controlToastState } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
345
|
+
|
|
346
|
+
<Toast
|
|
347
|
+
id="successToast"
|
|
348
|
+
type="success" // "success" | "error"
|
|
349
|
+
header="Success!"
|
|
350
|
+
message="Your changes have been saved."
|
|
351
|
+
/>
|
|
352
|
+
|
|
353
|
+
// Show toast
|
|
354
|
+
controlToastState('successToast', true);
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
#### `InfoIconWithTooltip`
|
|
358
|
+
An info icon with popover tooltip.
|
|
359
|
+
|
|
360
|
+
```tsx
|
|
361
|
+
import { InfoIconWithTooltip } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
362
|
+
|
|
363
|
+
<InfoIconWithTooltip
|
|
364
|
+
content={<p>This is helpful information</p>}
|
|
365
|
+
directionToDisplay="bottom" // "left" | "right" | "top" | "bottom"
|
|
366
|
+
maxWidth={20} // in rem
|
|
367
|
+
maxHeight={10} // in rem
|
|
368
|
+
/>
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### Layout & Display
|
|
372
|
+
|
|
373
|
+
#### `HeaderCard`
|
|
374
|
+
A card component for headers/titles.
|
|
375
|
+
|
|
376
|
+
```tsx
|
|
377
|
+
import { HeaderCard } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
378
|
+
|
|
379
|
+
<HeaderCard {...props} />
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
#### `Footer`
|
|
383
|
+
A footer component.
|
|
384
|
+
|
|
385
|
+
```tsx
|
|
386
|
+
import { Footer } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
387
|
+
|
|
388
|
+
<Footer {...props} />
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
#### `NotificationCard`
|
|
392
|
+
A card for displaying notifications.
|
|
393
|
+
|
|
394
|
+
```tsx
|
|
395
|
+
import { NotificationCard } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
396
|
+
|
|
397
|
+
<NotificationCard {...props} />
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
#### `StatusText`
|
|
401
|
+
Display status text with styling.
|
|
402
|
+
|
|
403
|
+
```tsx
|
|
404
|
+
import { StatusText } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
405
|
+
|
|
406
|
+
<StatusText {...props} />
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
#### `ProfileButton`
|
|
410
|
+
A user profile button with avatar and dropdown indicator.
|
|
411
|
+
|
|
412
|
+
```tsx
|
|
413
|
+
import { ProfileButton } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
414
|
+
|
|
415
|
+
<ProfileButton
|
|
416
|
+
name="John Doe"
|
|
417
|
+
initials="JD"
|
|
418
|
+
imageUrl="/avatar.jpg" // Optional: use image instead of initials
|
|
419
|
+
avatarBackgroundColor="#007028"
|
|
420
|
+
onClick={() => {}}
|
|
421
|
+
/>
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
### Loaders
|
|
425
|
+
|
|
426
|
+
#### `SpinningLoader`
|
|
427
|
+
A simple spinning loading indicator.
|
|
428
|
+
|
|
429
|
+
```tsx
|
|
430
|
+
import { SpinningLoader } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
431
|
+
|
|
432
|
+
<SpinningLoader />
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
#### `ProgressLoaderWithText`
|
|
436
|
+
A loader with text description.
|
|
437
|
+
|
|
438
|
+
```tsx
|
|
439
|
+
import { ProgressLoaderWithText } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
440
|
+
|
|
441
|
+
<ProgressLoaderWithText {...props} />
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### Search
|
|
445
|
+
|
|
446
|
+
#### `SearchComponent`
|
|
447
|
+
A search input with button.
|
|
448
|
+
|
|
449
|
+
```tsx
|
|
450
|
+
import { SearchComponent } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
451
|
+
|
|
452
|
+
<SearchComponent
|
|
453
|
+
placeholder="Search..."
|
|
454
|
+
onSearch={(query) => console.log(query)}
|
|
455
|
+
/>
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
---
|
|
459
|
+
|
|
460
|
+
## Types & Utilities
|
|
461
|
+
|
|
462
|
+
The library exports a comprehensive color palette and types:
|
|
463
|
+
|
|
464
|
+
```tsx
|
|
465
|
+
import { Colors, productWidgetColors, WidgetType } from '@risalabs_frontend_org/oasis-ui-kit';
|
|
466
|
+
|
|
467
|
+
// Color palette includes:
|
|
468
|
+
// - Primary Green (primaryGreen1-11)
|
|
469
|
+
// - Primary Gray (primaryGray1-16)
|
|
470
|
+
// - Secondary Purple, Yellow, Orange
|
|
471
|
+
// - Tertiary Red, Magenta, Cyan, Lime, Blue
|
|
472
|
+
// - Grayscale Black
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
---
|
|
476
|
+
|
|
477
|
+
## Tech Stack
|
|
478
|
+
|
|
479
|
+
- **React** 18.x
|
|
480
|
+
- **TypeScript** 5.x
|
|
481
|
+
- **SCSS** for styling
|
|
482
|
+
- **Storybook** 7.x for component documentation
|
|
483
|
+
- **Jest** + React Testing Library for testing
|
|
484
|
+
- **Webpack** for bundling
|
|
485
|
+
- **Moment.js** & **date-fns** for date handling
|
|
486
|
+
- **Ant Design Icons** for icons
|
|
487
|
+
- **React Feather** for additional icons
|
|
488
|
+
|
|
489
|
+
---
|
|
490
|
+
|
|
491
|
+
## Project Structure
|
|
492
|
+
|
|
493
|
+
```
|
|
494
|
+
oasis-ui/
|
|
495
|
+
├── src/
|
|
496
|
+
│ ├── components/ # All UI components
|
|
497
|
+
│ ├── shared/ # Shared styles, types, and utilities
|
|
498
|
+
│ ├── stories/ # Additional Storybook stories
|
|
499
|
+
│ └── SVG/ # SVG icon components
|
|
500
|
+
├── stories/ # Main Storybook stories
|
|
501
|
+
├── public/
|
|
502
|
+
│ └── icons/ # Static SVG icons
|
|
503
|
+
├── index.ts # Main entry point (exports)
|
|
504
|
+
└── index.d.ts # TypeScript declarations
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
---
|
|
508
|
+
|
|
509
|
+
## Contributing
|
|
510
|
+
|
|
511
|
+
1. Create a feature branch from `main`
|
|
512
|
+
2. Make your changes
|
|
513
|
+
3. Add/update Storybook stories for your components
|
|
514
|
+
4. Add/update unit tests
|
|
515
|
+
5. Submit a pull request
|
|
516
|
+
|
|
517
|
+
---
|
|
518
|
+
|
|
519
|
+
## License
|
|
520
|
+
|
|
521
|
+
Proprietary - RISA Labs
|