@yuktishaalaa/yuktai 5.1.0 → 5.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 +216 -12
- package/dist/index.js +50 -50
- package/dist/index.mjs +21 -21
- package/dist/renderer.global.js +16 -16
- package/package.json +31 -8
- package/vanilla/README.md +162 -0
- package/vanilla/index.js +6801 -0
- package/vanilla/index.min.js +542 -0
package/README.md
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
# @yuktishaalaa/yuktai
|
|
2
2
|
|
|
3
|
-
> Universal
|
|
3
|
+
> Universal accessibility, AI and data toolkit for Next.js, React **and plain HTML**. One install (or one script tag) brings WCAG 2.2 auto-fix, in-browser RAG, an AI agent, code generation, an accessible data grid with Agentic AI + WebMCP, and an agentic toolkit that audits, explains and fixes pages and answers questions about your data. Zero API keys, zero cost, works offline.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@yuktishaalaa/yuktai)
|
|
6
6
|
[](https://www.npmjs.com/package/@yuktishaalaa/yuktai)
|
|
7
|
-
[](./LICENSE)
|
|
8
8
|
[](https://nodejs.org)
|
|
9
9
|
[](https://nextjs.org)
|
|
10
|
+
[](https://hub.xerj.org/contributors/sandeepmiriyala03)
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
Built in free time by [Sandeep Miriyala](https://github.com/sandeepmiriyala03).
|
|
12
13
|
|
|
13
14
|
**Live demos:**
|
|
14
15
|
- Staff directory: https://aksharatantra.miriyala.in/staffdirectory
|
|
@@ -28,7 +29,7 @@ So I built yuktai, one weekend and one late night at a time.
|
|
|
28
29
|
|
|
29
30
|
## What's inside
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
Six modules ship in a single npm package, for React/Next.js and, since v5.3, for plain HTML pages with one script tag:
|
|
32
33
|
|
|
33
34
|
| Module | Features | What it does |
|
|
34
35
|
|---|---|---|
|
|
@@ -37,6 +38,180 @@ Five modules ship in a single npm package:
|
|
|
37
38
|
| **3. In-Tab RAG** | 11 | Ask questions about any page, offline, no API |
|
|
38
39
|
| **4. Autonomous AI Agent** | 13 | Natural-language browser guidance |
|
|
39
40
|
| **5. Vibe Coder** | 19 | Generate full Next.js projects from plain English |
|
|
41
|
+
| **6. Agentic AI Toolkit** | 10 | Accessibility copilot, QA reports, form and design review, smart grid queries, BI answers, multi-step tasks, voice settings |
|
|
42
|
+
| **Vanilla JS build** 🆕 | All | Every module above for plain HTML, CSS and JavaScript: no React, no build step |
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## What's new in v5.3: Vanilla JS (plain HTML)
|
|
47
|
+
|
|
48
|
+
All of yuktai now works on any HTML page, without React or a build step. The vanilla build is bundled from the same source as the npm package, so a question gets the same answer in React and in plain HTML.
|
|
49
|
+
|
|
50
|
+
```html
|
|
51
|
+
<script>
|
|
52
|
+
window.YUKTAI_CONFIG = { position: "right", showPageTools: true } // optional
|
|
53
|
+
</script>
|
|
54
|
+
<script src="https://cdn.jsdelivr.net/npm/@yuktishaalaa/yuktai@5.3.0/vanilla/index.min.js"></script>
|
|
55
|
+
|
|
56
|
+
<div id="staff"></div>
|
|
57
|
+
<script>
|
|
58
|
+
const grid = yuktai.renderGrid("#staff", {
|
|
59
|
+
data: rows,
|
|
60
|
+
rowKey: "id",
|
|
61
|
+
columns: [
|
|
62
|
+
{ key: "name", label: "Name" },
|
|
63
|
+
{ key: "salary", label: "Salary", type: "number" },
|
|
64
|
+
{ key: "joined", label: "Joined", type: "date" },
|
|
65
|
+
],
|
|
66
|
+
agentic: true, // question bar: "salary over 1 lakh", "average salary by department"
|
|
67
|
+
ai: true, // assistant: custom rules, phrases, grid tools, voice input
|
|
68
|
+
locale: "en-IN", // or "te-IN" for Telugu UI and messages
|
|
69
|
+
webmcp: true,
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
await grid.ask("salary over 1 lakh in Hyderabad")
|
|
73
|
+
yuktai.mountAgenticPanel("#tools", { defaultTab: "qa" }) // Copilot, QA, Forms, Design, Ask, Voice
|
|
74
|
+
</script>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
| React / Next.js | Vanilla JS |
|
|
78
|
+
|---|---|
|
|
79
|
+
| `<YuktaiGrid>` | `yuktai.renderGrid(container, options)` |
|
|
80
|
+
| `useAgenticGrid` + `<AgenticGridBar>` | `yuktai.createAgenticGrid()` + `yuktai.mountAgenticGridBar()`, or `agentic: true` |
|
|
81
|
+
| `useYuktaiGridAgent` | `yuktai.createGridAgent()` |
|
|
82
|
+
| `<YuktaiGridWebMCP>` | `yuktai.registerWebMCP()`, or `webmcp: true` |
|
|
83
|
+
| `<AgenticPanel>` | `yuktai.mountAgenticPanel()` |
|
|
84
|
+
| `<YuktAIWrapper>` | Automatic floating ♿ button (and 🛠 page tools with `showPageTools: true`) |
|
|
85
|
+
| Every function (`runQaAudit`, `askInsight`, `parseAmount`, …) | Same names on `window.yuktai` |
|
|
86
|
+
|
|
87
|
+
**Grid features in the vanilla build:**
|
|
88
|
+
- search, sort, page-size switching, row selection and CSV export (Excel-safe)
|
|
89
|
+
- table, card or auto view; 5 WCAG themes; Telugu UI
|
|
90
|
+
- loading and empty states; row highlighting that scrolls to the row
|
|
91
|
+
- ARIA grid keyboard navigation: arrow keys, Home/End, Page Up/Down, Space to select, Enter to open
|
|
92
|
+
|
|
93
|
+
**Tested** in Chromium: 37 end-to-end checks pass, with axe-core reporting 0 violations and no console errors. Open `vanilla/index.html` in the repo for a demo of every feature, including a Telugu grid. Full API: [`vanilla/README.md`](./vanilla/README.md).
|
|
94
|
+
|
|
95
|
+
### Accessibility engine fixes in v5.3 (React and vanilla)
|
|
96
|
+
|
|
97
|
+
- Auto-fix no longer adds an `aria-label` to form fields that already have a `<label>`. Before this, it replaced the name that screen readers announce.
|
|
98
|
+
- Buttons and links hidden at scan time are no longer labelled "button" or "link".
|
|
99
|
+
- `<header>` and `<footer>` inside sections and dialogs no longer become page-level banner and contentinfo landmarks.
|
|
100
|
+
- The fix count only includes fixes that were actually applied.
|
|
101
|
+
- Visual alert colours now meet a 4.5:1 contrast ratio.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## What's new in v5.2: Agentic AI Toolkit
|
|
106
|
+
|
|
107
|
+
Ten agentic features, all running in the browser. No API keys, and no page or grid data leaves the device unless you plug in your own model through a `generate` or `summarize` hook.
|
|
108
|
+
|
|
109
|
+
| # | Feature | What it does | Main export |
|
|
110
|
+
|---|---|---|---|
|
|
111
|
+
| 1 | Accessibility Copilot | Watches the page live, explains each issue in plain English, applies safe fixes and undoes them | `createA11yCopilot` |
|
|
112
|
+
| 2 | Page Understanding | Answers "What does this page do?" and "Which form fields are missing labels?" | `analyzePage`, `askAboutPage` |
|
|
113
|
+
| 3 | Smart Data Grid | Turns "overdue and over ₹10,000" into real filters, finds unusual rows, summarises data | `runGridQuery`, `detectAnomalies`, `summarizeRows` |
|
|
114
|
+
| 4 | Voice Accessibility | "Turn on high contrast", "bigger text", "next row", plus Telugu phrases like "పెద్ద అక్షరాలు" | `createVoiceA11yController` |
|
|
115
|
+
| 5 | QA Tester | 15 checks with WCAG references, a score, pass/fail, and a Markdown or JSON report | `runQaAudit`, `auditToMarkdown` |
|
|
116
|
+
| 6 | Forms Agent | Reviews labels, autocomplete, error messages and senior-friendliness | `reviewForms` |
|
|
117
|
+
| 7 | Page + Data RAG | Answers from page text and grid rows, Telugu-aware, offline | `createContextIndex` |
|
|
118
|
+
| 8 | Multi-Step Tasks | "Show overdue, highlight the errors, then summarise what changed" | `runTasks` |
|
|
119
|
+
| 9 | BI Copilot | "Which region had the highest drop in conversion this week?" | `askInsight`, `comparePeriods` |
|
|
120
|
+
| 10 | Design Review | Hierarchy, readability, focus states, clutter, consistency | `reviewDesign` |
|
|
121
|
+
|
|
122
|
+
### Page tools in one panel
|
|
123
|
+
|
|
124
|
+
```tsx
|
|
125
|
+
"use client";
|
|
126
|
+
import { AgenticPanel } from "@yuktishaalaa/yuktai";
|
|
127
|
+
|
|
128
|
+
export default function A11yTools() {
|
|
129
|
+
return <AgenticPanel defaultTab="copilot" voiceLang="en-IN" />;
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Tabs: **Copilot**, **QA report**, **Forms**, **Design**, **Ask page**, **Voice**. The panel marks itself with `data-yuktai-panel`, so it never audits its own UI.
|
|
134
|
+
|
|
135
|
+
### Ask your grid
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
"use client";
|
|
139
|
+
import { YuktaiGrid, useAgenticGrid, AgenticGridBar } from "@yuktishaalaa/yuktai";
|
|
140
|
+
|
|
141
|
+
const columns = [
|
|
142
|
+
{ key: "name", label: "Customer" },
|
|
143
|
+
{ key: "status", label: "Status" },
|
|
144
|
+
{ key: "region", label: "Region" },
|
|
145
|
+
{ key: "balance", label: "Balance", type: "number" as const },
|
|
146
|
+
{ key: "dueDate", label: "Due date", type: "date" as const },
|
|
147
|
+
];
|
|
148
|
+
|
|
149
|
+
export default function Customers({ rows }: { rows: Customer[] }) {
|
|
150
|
+
const grid = useAgenticGrid({ data: rows, columns, rowKey: "id" });
|
|
151
|
+
|
|
152
|
+
return (
|
|
153
|
+
<>
|
|
154
|
+
<AgenticGridBar
|
|
155
|
+
grid={grid}
|
|
156
|
+
examples={[
|
|
157
|
+
"overdue and over ₹10,000",
|
|
158
|
+
"anything unusual?",
|
|
159
|
+
"total balance by region",
|
|
160
|
+
"show overdue, then sort by balance desc, then summarize what changed",
|
|
161
|
+
]}
|
|
162
|
+
/>
|
|
163
|
+
<YuktaiGrid
|
|
164
|
+
data={grid.gridData}
|
|
165
|
+
columns={columns}
|
|
166
|
+
rowKey="id"
|
|
167
|
+
highlightIds={grid.highlightIds}
|
|
168
|
+
autoScrollToHighlight
|
|
169
|
+
/>
|
|
170
|
+
</>
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
`grid.ask(text)` picks the right tool for the question:
|
|
176
|
+
|
|
177
|
+
| Question type | Example | Handled by |
|
|
178
|
+
|---|---|---|
|
|
179
|
+
| Filters and lookups | "customer starting with A and balance between 1k and 9k" | Smart grid query |
|
|
180
|
+
| Unusual data | "anything unusual?" | Outliers and duplicate rows |
|
|
181
|
+
| Group and period questions | "which region had the highest drop in conversion this week?" | BI copilot |
|
|
182
|
+
| Several steps | "show overdue, then highlight errors, then summarise" | Task runner, with a before/after report |
|
|
183
|
+
|
|
184
|
+
Amounts like `₹10,000`, `10k`, `1.5 lakh` and `2 crore` are understood.
|
|
185
|
+
|
|
186
|
+
### Use the functions directly
|
|
187
|
+
|
|
188
|
+
```ts
|
|
189
|
+
import { runQaAudit, auditToMarkdown, askInsight, runGridQuery } from "@yuktishaalaa/yuktai";
|
|
190
|
+
|
|
191
|
+
// In the browser: accessibility QA report
|
|
192
|
+
const report = runQaAudit();
|
|
193
|
+
console.log(report.score, report.passed);
|
|
194
|
+
const md = auditToMarkdown(report); // attach to a ticket or PR
|
|
195
|
+
|
|
196
|
+
// Anywhere: data questions
|
|
197
|
+
askInsight("which region had the highest drop in conversion this week", rows, columns).answer;
|
|
198
|
+
runGridQuery("overdue and over 10k", { data: rows, columns }).ids;
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Plug in your own model (optional)
|
|
202
|
+
|
|
203
|
+
Everything works offline with rules and keyword search. To get model-written answers, pass a `generate` hook, for example Gemini Nano or your own API:
|
|
204
|
+
|
|
205
|
+
```tsx
|
|
206
|
+
<AgenticPanel generate={async (question, context) => myModel(question, context)} />
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Honest limits
|
|
210
|
+
|
|
211
|
+
- Questions are understood with rules, not a language model, so unusual phrasing may need rewording. The parser returns `notes` explaining any assumption it made.
|
|
212
|
+
- The QA and design checks are automatic heuristics. They catch common problems but don't replace testing with real users and assistive technology.
|
|
213
|
+
- Smart grid queries, page answers and BI answers are in English today. Telugu and Hindi data questions are not parsed yet; use `customRules` with your own phrases for them.
|
|
214
|
+
- Voice accessibility commands understand English and Telugu, not yet Hindi or other languages.
|
|
40
215
|
|
|
41
216
|
---
|
|
42
217
|
|
|
@@ -59,7 +234,7 @@ Five modules ship in a single npm package:
|
|
|
59
234
|
|
|
60
235
|
| Device | Browser | Core features | AI engine |
|
|
61
236
|
|---|---|---|---|
|
|
62
|
-
| 🖥 Desktop | Chrome 147+ | ✅ All | Gemini Nano |
|
|
237
|
+
| 🖥 Desktop | Chrome 147+ (needed only for Gemini Nano) | ✅ All | Gemini Nano |
|
|
63
238
|
| 🖥 Desktop | Firefox / Edge / Safari | ✅ All | Transformers.js |
|
|
64
239
|
| 📱 Android | Chrome Mobile | ✅ All | Transformers.js |
|
|
65
240
|
| 📱 iOS | Safari Mobile | ✅ All | Transformers.js |
|
|
@@ -90,7 +265,13 @@ yarn add @yuktishaalaa/yuktai
|
|
|
90
265
|
pnpm add @yuktishaalaa/yuktai
|
|
91
266
|
```
|
|
92
267
|
|
|
93
|
-
|
|
268
|
+
**Plain HTML (no install)**
|
|
269
|
+
|
|
270
|
+
```html
|
|
271
|
+
<script src="https://cdn.jsdelivr.net/npm/@yuktishaalaa/yuktai@5.3.0/vanilla/index.min.js"></script>
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Requirements: Node.js 18+, npm 8+, Next.js 13+ (React builds only; the vanilla build needs only a browser).
|
|
94
275
|
|
|
95
276
|
---
|
|
96
277
|
|
|
@@ -160,6 +341,8 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
|
|
160
341
|
|
|
161
342
|
That's it. Floating buttons appear on every page: ♿ opens the accessibility panel, 💬 opens "Ask this page", and the agent button opens the AI agent.
|
|
162
343
|
|
|
344
|
+
To add the v5.2 agentic tools, place `<AgenticPanel />` or `useAgenticGrid` in any client component (see [What's new in v5.2](#whats-new-in-v52-agentic-ai-toolkit)).
|
|
345
|
+
|
|
163
346
|
### Wrapper props
|
|
164
347
|
|
|
165
348
|
| Prop | Type | Default | Description |
|
|
@@ -278,6 +461,7 @@ export default function EmployeesPage() {
|
|
|
278
461
|
- Keyboard navigation, ARIA grid semantics, 44×44 targets
|
|
279
462
|
- English and Telugu UI
|
|
280
463
|
- Embedded Grid AI Assistant with voice and chat
|
|
464
|
+
- **New in v5.2:** compound natural-language questions, anomaly detection and BI answers through `useAgenticGrid`
|
|
281
465
|
|
|
282
466
|
### Grid AI Assistant
|
|
283
467
|
|
|
@@ -290,7 +474,7 @@ Runs embedded in the grid or as a standalone component. Intent parsing runs loca
|
|
|
290
474
|
onSearch={handleSearch}
|
|
291
475
|
onSort={handleSort}
|
|
292
476
|
language="te-IN" // AI UI and responses: en-US | te-IN
|
|
293
|
-
inputLanguage="te-IN" // voice input: en-US
|
|
477
|
+
inputLanguage="te-IN" // voice input: en-IN, en-US or any of the 22 Indian languages
|
|
294
478
|
embedded
|
|
295
479
|
/>
|
|
296
480
|
```
|
|
@@ -485,6 +669,8 @@ Retrieval-Augmented Generation running entirely in the browser. It extracts text
|
|
|
485
669
|
|
|
486
670
|
**What I learned:** Transformers.js kept crashing on iOS Safari with out-of-memory errors. Quantization (same model, 75% smaller) fixed it. DistilBERT gave short, useless spans; `flan-t5-small` gives real sentences.
|
|
487
671
|
|
|
672
|
+
**New in v5.2:** `createContextIndex` also searches grid rows (including rows on other pages of the grid) and your own documents, with keyword search that handles Telugu and Hindi script correctly.
|
|
673
|
+
|
|
488
674
|
---
|
|
489
675
|
|
|
490
676
|
## Module 4: Autonomous AI Agent
|
|
@@ -514,6 +700,19 @@ No AI writes the code. It's pure template engineering.
|
|
|
514
700
|
|
|
515
701
|
---
|
|
516
702
|
|
|
703
|
+
## Module 6: Agentic AI Toolkit 🆕
|
|
704
|
+
|
|
705
|
+
The ten v5.2 features, described in detail in [What's new in v5.2](#whats-new-in-v52-agentic-ai-toolkit).
|
|
706
|
+
|
|
707
|
+
- **Copilot and QA:** 15 WCAG checks, plain-English explanations, safe fixes with undo, downloadable reports
|
|
708
|
+
- **Forms and design review:** labels, autocomplete, error messages, focus states, hierarchy, clutter, senior-friendly tips
|
|
709
|
+
- **Data:** compound grid questions, outliers and duplicates, group-by, period comparison, trends
|
|
710
|
+
- **Automation:** multi-step instructions with a before/after summary
|
|
711
|
+
- **Voice:** accessibility settings and grid row navigation by voice, in English and Telugu
|
|
712
|
+
- **React:** `AgenticPanel`, `AgenticGridBar`, `useAgenticGrid`
|
|
713
|
+
|
|
714
|
+
---
|
|
715
|
+
|
|
517
716
|
## Gemini Nano setup (desktop Chrome, one time)
|
|
518
717
|
|
|
519
718
|
Needed only for Gemini Nano features on desktop Chrome. Mobile and other browsers use Transformers.js automatically.
|
|
@@ -556,9 +755,10 @@ Props: `size` (default 20), `color` (default `currentColor`), `strokeWidth` (def
|
|
|
556
755
|
|
|
557
756
|
- **Zero API keys, zero cost, zero telemetry.** Everything runs in the browser.
|
|
558
757
|
- **Zero injected ids.** Injected nodes are tracked by JavaScript references, so they never collide with your app's ids.
|
|
559
|
-
- **Zero framework lock-in.** `core/renderer.ts` has no framework imports.
|
|
758
|
+
- **Zero framework lock-in.** `core/renderer.ts` has no framework imports, and the vanilla build runs on any HTML page.
|
|
560
759
|
- **Never reads its own UI.** Panels are marked with `data-yuktai-panel`.
|
|
561
760
|
- **SSR safe.** No `window` errors on the server.
|
|
761
|
+
- **Every automatic fix can be undone.** The v5.2 copilot records each change it makes.
|
|
562
762
|
- **Honest limits.** Client-side pagination is for a few thousand rows; use server-side beyond that.
|
|
563
763
|
|
|
564
764
|
---
|
|
@@ -568,6 +768,7 @@ Props: `size` (default 20), `color` (default `currentColor`), `strokeWidth` (def
|
|
|
568
768
|
| | Supported |
|
|
569
769
|
|---|---|
|
|
570
770
|
| Next.js | 13, 14, 15, 16 |
|
|
771
|
+
| Plain HTML | Any page, one script tag (vanilla build) |
|
|
571
772
|
| React | 17, 18, 19 (19 needs `--legacy-peer-deps`) |
|
|
572
773
|
| Node.js | 18+ |
|
|
573
774
|
| Browsers | Chrome 90+, Firefox 90+, Safari 15+, Edge 90+, Samsung Internet 14+ |
|
|
@@ -576,8 +777,10 @@ Props: `size` (default 20), `color` (default `currentColor`), `strokeWidth` (def
|
|
|
576
777
|
|
|
577
778
|
## Roadmap
|
|
578
779
|
|
|
780
|
+
- **Shipped (v5.3):** Vanilla JS build of every module for plain HTML pages, plus accessibility engine fixes
|
|
781
|
+
- **Shipped (v5.2):** Agentic AI Toolkit: accessibility copilot, QA reports, form and design review, smart grid queries, BI answers, multi-step tasks, page + data RAG, voice accessibility commands
|
|
579
782
|
- **Shipped (v4.6.4):** YuktaiGrid Agentic AI + WebMCP, embedded Grid AI Assistant, English/Telugu UI, page-size switching, icon polish
|
|
580
|
-
- **Next:**
|
|
783
|
+
- **Next:** expose the v5.2 agentic tools through WebMCP, more Grid Agent tools, multilingual RAG (Telugu, Hindi, Tamil, Bengali)
|
|
581
784
|
- **Later:** RTL support, richer browser-native AI, multimodal grid experiences
|
|
582
785
|
|
|
583
786
|
---
|
|
@@ -594,13 +797,14 @@ Issues and pull requests are welcome at [github.com/sandeepmiriyala03/yuktai](ht
|
|
|
594
797
|
- GitHub: [sandeepmiriyala03/yuktai](https://github.com/sandeepmiriyala03/yuktai)
|
|
595
798
|
- Demo: [aksharatantra.miriyala.in/staffdirectory](https://aksharatantra.miriyala.in/staffdirectory)
|
|
596
799
|
- Showcase: [ratnalabala.vercel.app](https://ratnalabala.vercel.app/poems?view=grid)
|
|
800
|
+
- Vanilla JS (CDN): [cdn.jsdelivr.net/npm/@yuktishaalaa/yuktai/vanilla/index.min.js](https://cdn.jsdelivr.net/npm/@yuktishaalaa/yuktai/vanilla/index.min.js)
|
|
597
801
|
|
|
598
802
|
---
|
|
599
803
|
|
|
600
804
|
## License
|
|
601
805
|
|
|
602
|
-
|
|
806
|
+
GPL-3.0 © Sandeep Miriyala, [Yuktishaalaa AI Lab](https://github.com/sandeepmiriyala03)
|
|
603
807
|
|
|
604
|
-
Built in free time
|
|
808
|
+
Built in free time. AI coding assistants (Claude, GPT and Gemini) helped me learn, and helped write and test parts of the code. Every design decision, review and release is mine.
|
|
605
809
|
|
|
606
|
-
**Free forever. Open source. Built for every user.**
|
|
810
|
+
**Free forever. Open source. Built for every user.**
|