ahs-cti 0.0.2-beta.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.
package/LICENSE ADDED
@@ -0,0 +1,53 @@
1
+ PROPRIETARY SOFTWARE LICENSE AGREEMENT
2
+
3
+ Copyright (c) 2025 CTI SDK Team. All rights reserved.
4
+
5
+ IMPORTANT: READ CAREFULLY BEFORE USING THIS SOFTWARE
6
+
7
+ This software and associated documentation files (the "Software") are proprietary
8
+ and confidential. The Software is licensed, not sold, to you by Call Control SDK
9
+ ("Licensor") under the terms of this license agreement.
10
+
11
+ 1. GRANT OF LICENSE
12
+ Subject to the terms and conditions of this agreement, Licensor hereby grants
13
+ you a limited, non-exclusive, non-transferable license to use the Software
14
+ solely for your internal business purposes.
15
+
16
+ 2. RESTRICTIONS
17
+ You may NOT:
18
+ - Copy, modify, adapt, or create derivative works of the Software
19
+ - Reverse engineer, decompile, disassemble, or attempt to derive source code
20
+ - Distribute, sublicense, rent, lease, or transfer the Software
21
+ - Remove or alter any proprietary notices or labels on the Software
22
+ - Use the Software for any purpose other than as expressly permitted
23
+
24
+ 3. OWNERSHIP
25
+ The Software and all intellectual property rights therein remain the exclusive
26
+ property of Licensor. This license does not grant you any ownership rights.
27
+
28
+ 4. CONFIDENTIALITY
29
+ The Software contains confidential and proprietary information. You agree to:
30
+ - Maintain strict confidentiality
31
+ - Not disclose the Software to any third parties
32
+ - Use reasonable care to protect the Software from unauthorized access
33
+
34
+ 5. TERMINATION
35
+ This license is effective until terminated. Licensor may terminate this
36
+ license immediately if you breach any terms. Upon termination, you must
37
+ destroy all copies of the Software.
38
+
39
+ 6. NO WARRANTY
40
+ THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41
+ IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
42
+ FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
43
+
44
+ 7. LIMITATION OF LIABILITY
45
+ IN NO EVENT SHALL LICENSOR BE LIABLE FOR ANY DAMAGES WHATSOEVER ARISING
46
+ OUT OF THE USE OR INABILITY TO USE THE SOFTWARE.
47
+
48
+ 8. GOVERNING LAW
49
+ This agreement shall be governed by and construed in accordance with the
50
+ laws of [Your Jurisdiction].
51
+
52
+ By using this Software, you acknowledge that you have read this agreement,
53
+ understand it, and agree to be bound by its terms and conditions.
package/LICENSE-ACHALA ADDED
@@ -0,0 +1,80 @@
1
+ SOFTWARE LICENSE AGREEMENT
2
+
3
+ Copyright (c) 2025 CTI SDK Team. All rights reserved.
4
+
5
+ IMPORTANT: READ CAREFULLY BEFORE USING THIS SOFTWARE
6
+
7
+ This software and associated documentation files (the "Software") are proprietary
8
+ and confidential. The Software is licensed, not sold, to you by CTI SDK Team
9
+ ("Licensor") under the terms of this license agreement.
10
+
11
+ 1. GRANT OF LICENSE
12
+ Subject to the terms and conditions of this agreement, Licensor hereby grants
13
+ you a limited, non-exclusive, non-transferable license to use the Software
14
+ solely through authorized API keys and tenant IDs across different platforms
15
+ as specified in your subscription agreement.
16
+
17
+ 2. AUTHORIZED ACCESS REQUIREMENTS
18
+ You may use the Software ONLY when:
19
+ - You possess a valid, authorized API key issued by Licensor
20
+ - You have a valid tenant ID registered with Licensor
21
+ - Your subscription is active and in good standing
22
+ - You are using the Software on authorized platforms only
23
+
24
+ 3. PROHIBITED ACTIVITIES
25
+ You may NOT:
26
+ - Use the Software without valid API key and tenant ID
27
+ - Share, transfer, or distribute your API key or tenant ID
28
+ - Reverse engineer, decompile, or disassemble the Software
29
+ - Create derivative works or modifications
30
+ - Use the Software on unauthorized platforms
31
+ - Exceed the usage limits defined in your subscription
32
+ - Attempt to circumvent API rate limits or security measures
33
+
34
+ 4. API KEY AND TENANT ID MANAGEMENT
35
+ - API keys and tenant IDs are confidential and must be protected
36
+ - You are responsible for maintaining the security of your credentials
37
+ - Report any suspected compromise immediately to Licensor
38
+ - Licensor reserves the right to revoke access at any time
39
+ - Unauthorized use of credentials may result in immediate termination
40
+
41
+ 5. USAGE MONITORING AND COMPLIANCE
42
+ - Licensor may monitor usage patterns and API calls
43
+ - You must comply with all usage limits and restrictions
44
+ - Excessive or suspicious usage may trigger security reviews
45
+ - Non-compliance may result in immediate license termination
46
+
47
+ 6. PLATFORM-SPECIFIC TERMS
48
+ - Each platform may have additional terms and conditions
49
+ - Platform-specific features may require separate authorization
50
+ - Cross-platform data sharing must comply with privacy regulations
51
+ - Third-party integrations require prior written approval
52
+
53
+ 7. OWNERSHIP AND INTELLECTUAL PROPERTY
54
+ The Software and all intellectual property rights remain the exclusive
55
+ property of Licensor. This license does not grant you any ownership rights.
56
+
57
+ 8. CONFIDENTIALITY
58
+ The Software contains confidential and proprietary information. You agree to:
59
+ - Maintain strict confidentiality of all Software components
60
+ - Not disclose API keys, tenant IDs, or Software details to third parties
61
+ - Use reasonable care to protect against unauthorized access
62
+ - Report any security breaches immediately
63
+
64
+ 9. TERMINATION
65
+ This license is effective until terminated. Licensor may terminate this
66
+ license immediately if you breach any terms. Upon termination, you must:
67
+ - Cease all use of the Software immediately
68
+ - Destroy all copies of the Software
69
+ - Return or destroy all API keys and credentials
70
+ - Provide certification of compliance upon request
71
+
72
+ 10. NO WARRANTY
73
+ THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
74
+ IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
75
+ FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
76
+
77
+ By using this Software, you acknowledge that you have read this agreement,
78
+ understand it, and agree to be bound by its terms and conditions.
79
+
80
+ ACHALA LICENSE VERSION 1.0 - Effective Date: October 1, 2025
package/README.md ADDED
@@ -0,0 +1,508 @@
1
+ <div align="center">
2
+
3
+ ## Call Control SDK
4
+
5
+ [![npm version](https://img.shields.io/npm/v/call-control-sdk.svg?color=blue&style=for-the-badge)](https://www.npmjs.com/package/call-control-sdk)
6
+ [![npm downloads](https://img.shields.io/npm/dm/call-control-sdk.svg?color=green&style=for-the-badge)](https://www.npmjs.com/package/call-control-sdk)
7
+ [![bundle size](https://img.shields.io/bundlephobia/minzip/call-control-sdk?color=orange&style=for-the-badge)](https://bundlephobia.com/package/call-control-sdk)
8
+
9
+ **A powerful, lightweight SDK for real-time call management**
10
+
11
+ **🔑AUTHORIZED ACCESS REQUIRED - API Key & Tenant ID🔑**
12
+
13
+ </div>
14
+
15
+ ### ⭐ **License Features**
16
+
17
+ - **API Key Authentication** - Secure access through authorized API keys
18
+ - **Tenant ID Management** - Multi-tenant support with isolated access
19
+ - **Cross-Platform Support** - Use across web, mobile, desktop, and server platforms
20
+ - **Usage Monitoring** - Real-time tracking and compliance monitoring
21
+ - **Flexible Deployment** - Deploy on authorized platforms with proper credentials
22
+
23
+ ### 🚫 **Prohibited Activities**
24
+
25
+ - **No Unauthorized Access** - Cannot use without valid credentials
26
+ - **No Credential Sharing** - API keys and tenant IDs are confidential
27
+ - **No Reverse Engineering** - Cannot decompile or reverse engineer
28
+ - **No Platform Violations** - Must use only on authorized platforms
29
+ - **No Usage Abuse** - Cannot exceed subscription limits
30
+
31
+ ## 📑 Table of Contents
32
+
33
+ - [✨ Key Features](#-key-features)
34
+ - [📦 Installation](#-installation)
35
+ - [🚀 Quick Start](#-quick-start)
36
+ - [1️⃣ Initialize the SDK](#1️⃣-initialize-the-sdk)
37
+ - [2️⃣ Add Call Control Panel](#2️⃣-add-call-control-panel)
38
+ - [3️⃣ Use Call Management Hooks](#3️⃣-use-call-management-hooks)
39
+ - [🔧 Configuration Options](#-configuration-options)
40
+ - [📚 API Reference](#-api-reference)
41
+ - [🔧 Core Functions](#-core-functions)
42
+ - [🪝 React Hooks](#-react-hooks)
43
+ - [📦 Data Types](#-data-types)
44
+ - [🎛 Control Features](#-control-features)
45
+ - [🌍 Browser Support](#-browser-support)
46
+ - [📄 License](#-license)
47
+
48
+ ---
49
+
50
+ ## ✨ Key Features
51
+
52
+ ### 🎯 **Complete Call Control**
53
+
54
+ - Hold/Resume calls
55
+ - Mute/Unmute functionality
56
+ - Agent status management
57
+ - End call with disposition
58
+
59
+ ### 💾 **Smart State Management**
60
+
61
+ - Real-time call timer
62
+ - Persistent state storage
63
+ - Singleton state pattern
64
+ - Cross-component sync
65
+ - TypeScript support
66
+
67
+ ## 📦 Installation
68
+
69
+ ```bash
70
+ npm install call-control-sdk
71
+ ```
72
+
73
+ ### 🔑 Required Dependencies
74
+
75
+ Make sure you have these peer dependencies installed:
76
+
77
+ ```bash
78
+ npm install react react-dom axios @mui/material @mui/icons-material @emotion/react @emotion/styled
79
+ ```
80
+
81
+ ---
82
+
83
+ ## 🚀 Quick Start
84
+
85
+ ### 1️⃣ **Initialize the SDK**
86
+
87
+ First, initialize the SDK at the root of your application:
88
+
89
+ ```tsx
90
+ import { useEffect } from "react";
91
+ import { initSDK } from "call-control-sdk";
92
+
93
+ function App() {
94
+ useEffect(() => {
95
+ try {
96
+ initSDK({
97
+ apiKey: "your-api-key",
98
+ tenantId: "your-tenant-id",
99
+ agentId: "your-agent-id",
100
+ });
101
+ console.log("✅ SDK initialized successfully");
102
+ } catch (error) {
103
+ console.error("❌ SDK initialization failed:", error);
104
+ }
105
+ }, []);
106
+
107
+ return <YourAppContent />;
108
+ }
109
+ ```
110
+
111
+ ### 2️⃣ **Add Call Control Panel**
112
+
113
+ Drop in the draggable call control panel anywhere in your app:
114
+
115
+ ```tsx
116
+ import { CallControlPanel } from "call-control-sdk";
117
+
118
+ export default function AgentDashboard() {
119
+ const handleCallDataChange = (data) => {
120
+ console.log("📞 Call data updated:", data);
121
+ // Handle call data changes (mobileNumber, callReferenceId, agentLoginId)
122
+ };
123
+
124
+ return (
125
+ <div>
126
+ <h1>Agent Dashboard</h1>
127
+ <CallControlPanel onDataChange={handleCallDataChange} />
128
+ </div>
129
+ );
130
+ }
131
+ ```
132
+
133
+ #### 📞 **Get Caller Data (Alternative to onDataChange)**
134
+
135
+ The `useGetCallerData` hook is an **independent alternative** to the `CallControlPanel`'s `onDataChange` prop. It provides the same call data but can be used anywhere in your application without depending on the `CallControlPanel` component.
136
+
137
+ **Key Differences:**
138
+
139
+ - 🔄 **onDataChange**: Requires `CallControlPanel` component, callback-based
140
+ - 🎯 **useGetCallerData**: Independent hook, reactive, can be used anywhere
141
+
142
+ **When to use each:**
143
+
144
+ - Use `onDataChange` when you need the call control UI and want to handle data changes
145
+ - Use `useGetCallerData` when you only need call data without the control panel UI
146
+
147
+ The `useGetCallerData` hook provides reactive access to current call data. It automatically updates when call status changes, new calls arrive, or call information is modified.
148
+
149
+ ```tsx
150
+ import { useGetCallerData } from "call-control-sdk";
151
+
152
+ export default function AgentDashboard() {
153
+ const callerData = useGetCallerData();
154
+
155
+ // Sample data structure returned:
156
+ // {
157
+ // "phone_number": "1234567890",
158
+ // "status": "ONCALL",
159
+ // "callReferenceId": "convox_call_id_123",
160
+ // "agent_id": "agent001",
161
+ // "process_id": "proc001",
162
+ // "process_name": "Sales Process"
163
+ // }
164
+
165
+ return (
166
+ <div>
167
+ <h1>Current Call Information</h1>
168
+ <p>Phone Number: {callerData.phone_number}</p>
169
+ <p>Call Status: {callerData.status}</p>
170
+ <p>Call Reference ID: {callerData.callReferenceId}</p>
171
+ <p>Agent ID: {callerData.agent_id}</p>
172
+ <p>Process: {callerData.process_name}</p>
173
+ </div>
174
+ );
175
+ }
176
+ ```
177
+
178
+ **Example: Using useGetCallerData independently (without CallControlPanel)**
179
+
180
+ ```tsx
181
+ import { useGetCallerData } from "call-control-sdk";
182
+
183
+ // This component can be used anywhere, even without CallControlPanel
184
+ export default function CallStatusWidget() {
185
+ const callerData = useGetCallerData();
186
+
187
+ return (
188
+ <div className="call-status-widget">
189
+ <h3>Current Call Status</h3>
190
+ {callerData.status === "ONCALL" ?
191
+ <div>
192
+ <p>📞 Active Call: {callerData.phone_number}</p>
193
+ <p>Agent: {callerData.agent_id}</p>
194
+ <p>Process: {callerData.process_name}</p>
195
+ </div>
196
+ : <p>No active call</p>}
197
+ </div>
198
+ );
199
+ }
200
+
201
+ // You can use this widget anywhere in your app
202
+ export default function MainApp() {
203
+ return (
204
+ <div>
205
+ <h1>My Application</h1>
206
+ <CallStatusWidget /> {/* Independent component */}
207
+ {/* No CallControlPanel needed here */}
208
+ </div>
209
+ );
210
+ }
211
+ ```
212
+
213
+ **Key Features:**
214
+
215
+ - ✅ **Reactive Updates**: Automatically re-renders when call data changes
216
+ - ✅ **Real-time Data**: Reflects current call state from WebSocket updates
217
+ - ✅ **Type Safety**: Fully typed with TypeScript interfaces
218
+ - ✅ **Complete Data**: Returns all available call information
219
+ - ✅ **Independent**: Works without `CallControlPanel` component
220
+
221
+ **Returned Data Fields:**
222
+
223
+ - `phone_number`: The phone number involved in the call
224
+ - `status`: Current call status (ONCALL, RINGING, WRAPUP, etc.)
225
+ - `callReferenceId`: Unique identifier for the call
226
+ - `agent_id`: ID of the agent handling the call
227
+ - `process_id`: Process identifier for the call
228
+ - `process_name`: Name of the process handling the call
229
+
230
+ ### 3️⃣ **Use Call Management Hooks**
231
+
232
+ #### 🔴 **Start a Call**
233
+
234
+ ```tsx
235
+ import { useClickToCall } from "call-control-sdk";
236
+
237
+ export default function CallButton() {
238
+ const { handleStartCall, isLoading, isSuccess, isError, error } = useClickToCall();
239
+
240
+ const startCall = () => {
241
+ handleStartCall({
242
+ mobileNumber: "1234567890",
243
+ });
244
+ };
245
+
246
+ return (
247
+ <button
248
+ onClick={startCall}
249
+ disabled={isLoading}
250
+ >
251
+ {isLoading ? "🔄 Calling..." : "📞 Start Call"}
252
+ </button>
253
+ );
254
+ }
255
+ ```
256
+
257
+ #### 🔚 **End a Call**
258
+
259
+ ```tsx
260
+ import { useEndCall } from "call-control-sdk";
261
+
262
+ export default function EndCallButton() {
263
+ const { handleEndCall, isLoading, isSuccess, isError, error } = useEndCall();
264
+
265
+ const endCall = () => {
266
+ handleEndCall({
267
+ disposition: "RES", // Call disposition
268
+ });
269
+ };
270
+
271
+ return (
272
+ <button
273
+ onClick={endCall}
274
+ disabled={isLoading}
275
+ >
276
+ {isLoading ? "🔄 Ending..." : "🔚 End Call"}
277
+ </button>
278
+ );
279
+ }
280
+ ```
281
+
282
+ #### 🚪 **Agent Logout**
283
+
284
+ ```tsx
285
+ import { useLogout } from "call-control-sdk";
286
+
287
+ export default function LogoutButton() {
288
+ const { logout, isLoading, isSuccess, isError, error } = useLogout();
289
+
290
+ return (
291
+ <button
292
+ onClick={logout}
293
+ disabled={isLoading}
294
+ >
295
+ {isLoading ? "🔄 Logging out..." : "🚪 Logout"}
296
+ </button>
297
+ );
298
+ }
299
+ ```
300
+
301
+ ### 🔐 Authorization Token
302
+
303
+ get Authorization token for external API call
304
+
305
+ ```tsx
306
+ import { useGetAuthorizationToken } from "call-control-sdk";
307
+
308
+ export default function axios() {
309
+ const token = useGetAuthorizationToken();
310
+
311
+ console.log(token);
312
+ }
313
+ ```
314
+
315
+ ---
316
+
317
+ ## 🔧 Configuration Options
318
+
319
+ Customize the SDK behavior to fit your needs:
320
+
321
+ ```tsx
322
+ initSDK({
323
+ // Required configuration
324
+ apiKey: "your-api-key",
325
+ tenantId: "your-tenant-id",
326
+ agentId: "your-agent-id",
327
+
328
+ // Optional customization
329
+ disableEndCallButton: false, // Hide end call button
330
+ disabledDialButton: false, // Hide dial button
331
+ disableCallTransferButton: false, // Hide transfer button
332
+ disableConferenceButton: false, // Hide conference button
333
+ disableSoftPhone: false, // Hide soft phone iframe
334
+ isDraggable: true, // Enable/disable dragging
335
+
336
+ // Custom styling (Material-UI SxProps)
337
+ disabled: { opacity: 0.5 }, // Disabled button styles
338
+ enabled: { color: "primary" }, // Enabled button styles
339
+ outlined: { border: "1px solid" }, // Outlined button styles
340
+ });
341
+ ```
342
+
343
+ ### 🎨 **Styling Options**
344
+
345
+ | Option | Type | Default | Description |
346
+ | --------------------------- | --------- | ------- | --------------------------------- |
347
+ | `disableEndCallButton` | `boolean` | `false` | Hide the "End Call" button |
348
+ | `disabledDialButton` | `boolean` | `false` | Hide the "Dial" button |
349
+ | `disableCallTransferButton` | `boolean` | `false` | Hide the "Call Transfer" button |
350
+ | `disableConferenceButton` | `boolean` | `false` | Hide the "Conference" button |
351
+ | `disableSoftPhone` | `boolean` | `false` | Hide the embedded soft phone |
352
+ | `isDraggable` | `boolean` | `true` | Enable/disable panel dragging |
353
+ | `disabled` | `SxProps` | - | Custom styles for disabled states |
354
+ | `enabled` | `SxProps` | - | Custom styles for enabled states |
355
+ | `outlined` | `SxProps` | - | Custom styles for outlined states |
356
+
357
+ ---
358
+
359
+ ## 📚 API Reference
360
+
361
+ ### 🔧 **Core Functions**
362
+
363
+ #### `initSDK(config)`
364
+
365
+ Initialize the SDK with your configuration. **Must be called before using any components or hooks.**
366
+
367
+ ```tsx
368
+ initSDK({
369
+ apiKey: string, // ✅ Required - API key for authentication
370
+ tenantId: string, // ✅ Required - Tenant ID for events/authentication
371
+ agentId: string, // ✅ Required - Agent ID for call controls
372
+ // ... plus optional configuration options
373
+ });
374
+ ```
375
+
376
+ #### `CallControlPanel`
377
+
378
+ Draggable control panel component for call management.
379
+
380
+ ```tsx
381
+ <CallControlPanel
382
+ onDataChange={(data) => {
383
+ console.log("Call data updated:", data);
384
+ }}
385
+ />
386
+ ```
387
+
388
+ ### 🪝 **React Hooks**
389
+
390
+ #### `useLogout()`
391
+
392
+ Hook for agent logout functionality.
393
+
394
+ ```tsx
395
+ const { logout, isLoading, isSuccess, isError, error } = useLogout();
396
+
397
+ // Usage:
398
+ logout();
399
+
400
+ // Returns:
401
+ // - logout: () => void - Function to trigger logout
402
+ // - isLoading: boolean - Loading state
403
+ // - isSuccess: boolean - Success state
404
+ // - isError: boolean - Error state
405
+ // - error: any - Error object if failed
406
+ ```
407
+
408
+ #### `useClickToCall()`
409
+
410
+ Hook for initiating calls to mobile numbers.
411
+
412
+ ```tsx
413
+ const { handleStartCall, isLoading, isSuccess, isError, error, data } = useClickToCall();
414
+
415
+ // Usage:
416
+ handleStartCall({ mobileNumber: "1234567890" });
417
+
418
+ // Returns:
419
+ // - handleStartCall: (payload: StartCallPayload) => void
420
+ // - isLoading: boolean - Loading state
421
+ // - isSuccess: boolean - Success state
422
+ // - isError: boolean - Error state
423
+ // - error: any - Error object if failed
424
+ // - data: any - API response on success
425
+ ```
426
+
427
+ #### `useEndCall()`
428
+
429
+ Hook for ending active calls.
430
+
431
+ ```tsx
432
+ const { handleEndCall, isLoading, isSuccess, isError, error, data } = useEndCall();
433
+
434
+ // Usage:
435
+ handleEndCall({ disposition: "RES" });
436
+
437
+ // Returns:
438
+ // - handleEndCall: (payload: EndCallPayload) => void
439
+ // - isLoading: boolean - Loading state
440
+ // - isSuccess: boolean - Success state
441
+ // - isError: boolean - Error state
442
+ // - error: any - Error object if failed
443
+ // - data: any - API response on success
444
+ ```
445
+
446
+ ---
447
+
448
+ ## 📦 **Data Types**
449
+
450
+ ### `StartCallPayload`
451
+
452
+ ```tsx
453
+ interface StartCallPayload {
454
+ mobileNumber?: string; // Mobile number to call
455
+ }
456
+ ```
457
+
458
+ ### `EndCallPayload`
459
+
460
+ ```tsx
461
+ interface EndCallPayload {
462
+ disposition?: string; // Call disposition (default: "RES")
463
+ }
464
+ ```
465
+
466
+ ---
467
+
468
+ ## 🎛 **Control Features**
469
+
470
+ ### 📞 **Call Management**
471
+
472
+ - **Hold/Resume** - Pause and resume active calls
473
+ - **Mute/Unmute** - Control audio during calls
474
+ - **End Call** - Terminate calls with disposition tracking
475
+ - **Agent Status** - Switch between Idle/Break states
476
+
477
+ ### 💾 **State Persistence**
478
+
479
+ - **Call Timer** - Real-time duration tracking
480
+ - **Panel Position** - Remembers draggable panel location
481
+ - **Agent Status** - Maintains current status across sessions
482
+ - **Call State** - Preserves hold/mute states
483
+
484
+ ---
485
+
486
+ ## 🌍 **Browser Support**
487
+
488
+ <div align="left">
489
+
490
+ | Browser | Version | Status |
491
+ | ----------------------------------------------------------------------------- | ------- | ------------ |
492
+ | ![Chrome](https://img.shields.io/badge/Chrome-60%2B-green?logo=google-chrome) | 60+ | ✅ Supported |
493
+ | ![Firefox](https://img.shields.io/badge/Firefox-60%2B-green?logo=firefox) | 60+ | ✅ Supported |
494
+ | ![Safari](https://img.shields.io/badge/Safari-12%2B-green?logo=safari) | 12+ | ✅ Supported |
495
+ | ![Edge](https://img.shields.io/badge/Edge-79%2B-green?logo=microsoft-edge) | 79+ | ✅ Supported |
496
+
497
+ </div>
498
+
499
+ ---
500
+
501
+ ## 📄 **License**
502
+
503
+ <div align="center">
504
+
505
+ ![license](https://img.shields.io/badge/License-Achala-blue?style=for-the-badge)
506
+ ![license](https://img.shields.io/badge/License-Proprietary-red?style=for-the-badge)
507
+
508
+ </div>
Binary file
Binary file