devobin 1.0.0__py3-none-any.whl

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.
Files changed (47) hide show
  1. devobin/__init__.py +4 -0
  2. devobin/app.py +42 -0
  3. devobin/cli/__init__.py +1 -0
  4. devobin/cli/chat.py +831 -0
  5. devobin/cli/commands.py +362 -0
  6. devobin/cli/slash_menu.py +74 -0
  7. devobin/cli/terminal.py +155 -0
  8. devobin/cli/ui.py +129 -0
  9. devobin/config/__init__.py +1 -0
  10. devobin/config/settings.py +124 -0
  11. devobin/core/__init__.py +1 -0
  12. devobin/core/analyzer.py +166 -0
  13. devobin/core/executor.py +244 -0
  14. devobin/core/memory.py +78 -0
  15. devobin/core/optimizer.py +106 -0
  16. devobin/core/prompt_builder.py +513 -0
  17. devobin/core/researcher.py +283 -0
  18. devobin/core/rtl.py +93 -0
  19. devobin/core/scanner.py +206 -0
  20. devobin/core/tools.py +283 -0
  21. devobin/core/validator.py +235 -0
  22. devobin/main.py +33 -0
  23. devobin/output/__init__.py +1 -0
  24. devobin/providers/__init__.py +85 -0
  25. devobin/providers/anthropic_provider.py +72 -0
  26. devobin/providers/google_provider.py +90 -0
  27. devobin/providers/ollama_provider.py +81 -0
  28. devobin/providers/openai_provider.py +102 -0
  29. devobin/storage/__init__.py +1 -0
  30. devobin/storage/database.py +207 -0
  31. devobin/ui/__init__.py +1 -0
  32. devobin/ui/ask_modal.py +96 -0
  33. devobin/ui/chat_screen.py +1029 -0
  34. devobin/ui/command_palette.py +131 -0
  35. devobin/ui/connect_modal.py +166 -0
  36. devobin/ui/export_modal.py +159 -0
  37. devobin/ui/history_modal.py +137 -0
  38. devobin/ui/memory_modal.py +88 -0
  39. devobin/ui/model_modal.py +143 -0
  40. devobin/ui/permission_modal.py +92 -0
  41. devobin/ui/project_modal.py +133 -0
  42. devobin/ui/settings_modal.py +89 -0
  43. devobin-1.0.0.dist-info/METADATA +364 -0
  44. devobin-1.0.0.dist-info/RECORD +47 -0
  45. devobin-1.0.0.dist-info/WHEEL +4 -0
  46. devobin-1.0.0.dist-info/entry_points.txt +2 -0
  47. devobin-1.0.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,364 @@
1
+ Metadata-Version: 2.4
2
+ Name: devobin
3
+ Version: 1.0.0
4
+ Summary: AI Engineering Context Compiler and Prompt Architect CLI — reads your code, builds the perfect prompt
5
+ Project-URL: Homepage, https://github.com/mobinhasanghasemi/devobin
6
+ Project-URL: Repository, https://github.com/mobinhasanghasemi/devobin
7
+ Project-URL: Issues, https://github.com/mobinhasanghasemi/devobin/issues
8
+ Author-email: Mobin Hasanghasemi <mobin@devobin.ai>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: ai,claude,cli,codex,coding-agent,context-compilation,cursor,developer-tools,prompt-engineering
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Topic :: Software Development :: Code Generators
21
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
22
+ Classifier: Topic :: Software Development :: Quality Assurance
23
+ Requires-Python: >=3.12
24
+ Requires-Dist: aiofiles>=23.2.0
25
+ Requires-Dist: anthropic>=0.18.0
26
+ Requires-Dist: arabic-reshaper>=3.0.0
27
+ Requires-Dist: google-genai>=1.0.0
28
+ Requires-Dist: httpx>=0.27.0
29
+ Requires-Dist: openai>=1.10.0
30
+ Requires-Dist: platformdirs>=4.2.0
31
+ Requires-Dist: pydantic-settings>=2.1.0
32
+ Requires-Dist: pydantic>=2.5.0
33
+ Requires-Dist: python-bidi>=0.6.0
34
+ Requires-Dist: rich>=13.7.0
35
+ Requires-Dist: textual>=0.40.0
36
+ Requires-Dist: typer>=0.12.0
37
+ Provides-Extra: dev
38
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
39
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
40
+ Requires-Dist: ruff>=0.2.0; extra == 'dev'
41
+ Description-Content-Type: text/markdown
42
+
43
+ <div dir="ltr">
44
+
45
+ # DevObin AI
46
+
47
+ > **AI Engineering Context Compiler & Prompt Architect**
48
+
49
+ DevObin is a CLI-based prompt engineering system that autonomously reads your project code and produces customized engineering prompts for AI coding agents. It does NOT write code — it crafts the perfect prompt so Codex, Claude, Cursor, or any AI agent builds exactly what you need.
50
+
51
+ ---
52
+
53
+ ## What DevObin Does
54
+
55
+ ```
56
+ You: "Add caching to my provider calls"
57
+
58
+
59
+ DevObin scans your project → reads your actual code → understands your architecture
60
+
61
+
62
+ DevObin writes: caching_feature_prompt.md (in your directory)
63
+
64
+
65
+ Give the file to Codex/Claude/Cursor → they implement it perfectly
66
+ ```
67
+
68
+ **Key difference:** DevObin reads YOUR code and produces a prompt based on YOUR actual architecture — not a generic template.
69
+
70
+ ---
71
+
72
+ ## Installation
73
+
74
+ ```bash
75
+ pip install devobin
76
+ ```
77
+
78
+ Or from source:
79
+
80
+ ```bash
81
+ git clone https://github.com/mobinhasanghasemi/devobin.git
82
+ cd devobin
83
+ pip install -e .
84
+ ```
85
+
86
+ ---
87
+
88
+ ## Quick Start
89
+
90
+ ### 1. Launch DevObin
91
+
92
+ ```bash
93
+ cd your-project/
94
+ devobin
95
+ ```
96
+
97
+ ### 2. Connect an AI Provider
98
+
99
+ ```
100
+ > /connect
101
+ ```
102
+
103
+ | Provider | Key Format | Example Model |
104
+ |----------|-----------|---------------|
105
+ | OpenAI | `sk-...` | `gpt-4o` |
106
+ | Anthropic | `sk-ant-...` | `claude-sonnet-4-20250514` |
107
+ | Google | `AIza...` | `gemini-2.0-flash` |
108
+ | Ollama | (no key) | `llama3` |
109
+
110
+ ### 3. Describe What You Want
111
+
112
+ ```
113
+ > Add a caching layer to the provider calls
114
+ ```
115
+
116
+ ### 4. DevObin Does Everything
117
+
118
+ 1. **Scans** your workspace automatically
119
+ 2. **Asks permission** to read your files
120
+ 3. **Reads** every important source file
121
+ 4. **Understands** your real architecture
122
+ 5. **Writes** the prompt file to your directory
123
+ 6. **Tells you** "Created: caching_prompt.md"
124
+
125
+ **You never type /export.** DevObin creates the file itself.
126
+
127
+ ### 5. Give the File to a Coding Agent
128
+
129
+ ```bash
130
+ # The file is in your current directory
131
+ cat caching_prompt.md
132
+
133
+ # Give it to Codex, Claude, Cursor, or any AI agent
134
+ ```
135
+
136
+ ---
137
+
138
+ ## How It Works
139
+
140
+ ### Agent System
141
+
142
+ DevObin has an autonomous agent that explores your codebase using tools:
143
+
144
+ | Tool | What It Does |
145
+ |------|-------------|
146
+ | `[TOOL:glob:**/*.py]` | Find files by pattern |
147
+ | `[TOOL:grep:regex]` | Search file contents |
148
+ | `[TOOL:read:path]` | Read a file completely |
149
+ | `[TOOL:ls:path]` | List directory contents |
150
+ | `[TOOL:write:name.md]` | Create the prompt file |
151
+
152
+ The agent runs up to **10 rounds** of tool calls to thoroughly understand your project before producing the prompt.
153
+
154
+ ### Permission System
155
+
156
+ Before reading your files, DevObin asks permission:
157
+
158
+ ```
159
+ ┌─ File Access Permission ─────────────┐
160
+ │ DevObin found 44 files. │
161
+ │ Allow file access? │
162
+ │ │
163
+ │ [Yes — Read All Files] │
164
+ │ [Ask Before Each File] │
165
+ │ [No — Skip File Reading] │
166
+ └────────────────────────────────────┘
167
+ ```
168
+
169
+ ### Grounding Check
170
+
171
+ After generating the prompt, DevObin verifies it doesn't hallucinate technologies:
172
+
173
+ - If your project has NO database → prompt won't mention PostgreSQL
174
+ - If your project has NO Dockerfile → prompt won't mention Docker
175
+ - If your project has NO frontend → prompt won't mention React
176
+
177
+ If hallucinations are detected, DevObin automatically rewrites the prompt.
178
+
179
+ ### Session-Based History
180
+
181
+ Each chat conversation is stored separately:
182
+
183
+ ```
184
+ .devobin/projects/myproject/sessions/
185
+ ├── 2026-07-14T10-30-00.json
186
+ ├── 2026-07-14T11-15-00.json
187
+ └── 2026-07-14T14-00-00.json
188
+ ```
189
+
190
+ Use `/history` to browse past sessions.
191
+
192
+ ---
193
+
194
+ ## Commands
195
+
196
+ ### Chat Commands
197
+
198
+ | Command | Description |
199
+ |---------|-------------|
200
+ | `/connect` | Set up an AI provider |
201
+ | `/model <name>` | Switch model |
202
+ | `/project create <name>` | Create project |
203
+ | `/project switch <name>` | Switch project |
204
+ | `/project list` | List projects |
205
+ | `/scan` | Re-scan workspace |
206
+ | `/history` | View past sessions |
207
+ | `/memory` | View saved memories |
208
+ | `/export [name]` | Manual export (rarely needed) |
209
+ | `/settings` | Show settings |
210
+ | `/clear` | Clear current chat |
211
+ | `/help` | Command palette |
212
+
213
+ ### Shell Commands
214
+
215
+ | Command | Description |
216
+ |---------|-------------|
217
+ | `/run <cmd>` | Execute shell command |
218
+ | `/read <file>` | Read file |
219
+ | `/ls [path]` | List directory |
220
+ | `/git <args>` | Git commands |
221
+ | `/pip <args>` | Pip commands |
222
+ | `/python <args>` | Run Python |
223
+
224
+ ### Keyboard Shortcuts
225
+
226
+ | Shortcut | Action |
227
+ |----------|--------|
228
+ | `Ctrl+K` | Command palette |
229
+ | `Ctrl+L` | Clear chat |
230
+ | `Ctrl+Q` | Quit |
231
+ | `/` alone | Command palette |
232
+
233
+ ---
234
+
235
+ ## Example Session
236
+
237
+ ```
238
+ $ cd my-python-project
239
+ $ devobin
240
+
241
+ > /connect
242
+ [Select: openai, enter API key, select gpt-4o]
243
+
244
+ > بچین کدها رو و یه پرامپت مهندسی شده بساز
245
+
246
+ [Scanning workspace... 44 files found]
247
+ [Permission: Read All Files]
248
+ [Reading files... (round 1)]
249
+ [Reading files... (round 2)]
250
+ [Reading files... (round 3)]
251
+ [Creating prompt file... (round 4)]
252
+ Created: my_feature_prompt.md
253
+
254
+ > یه caching اضافه کن
255
+
256
+ [Reading files... (round 1)]
257
+ [Reading existing prompt... (round 2)]
258
+ [Updating prompt file... (round 3)]
259
+ Updated: my_feature_prompt.md
260
+ ```
261
+
262
+ ---
263
+
264
+ ## Architecture
265
+
266
+ ```
267
+ devobin/
268
+ ├── main.py # Typer CLI entry
269
+ ├── app.py # Textual TUI app
270
+ ├── core/
271
+ │ ├── scanner.py # Workspace scanner
272
+ │ ├── tools.py # Agent tools (glob/grep/read/ls/write)
273
+ │ ├── validator.py # Output + grounding validation
274
+ │ ├── prompt_builder.py # Template-based prompts (fallback)
275
+ │ ├── analyzer.py # Tech detection
276
+ │ ├── researcher.py # Knowledge base
277
+ │ ├── memory.py # Cross-session memory
278
+ │ ├── optimizer.py # Token compression
279
+ │ └── executor.py # Shell & file ops
280
+ ├── providers/
281
+ │ ├── __init__.py # Provider registry
282
+ │ ├── openai_provider.py
283
+ │ ├── anthropic_provider.py
284
+ │ ├── google_provider.py
285
+ │ └── ollama_provider.py
286
+ ├── ui/
287
+ │ ├── chat_screen.py # Main screen + agent loop
288
+ │ ├── export_modal.py # Export dialog
289
+ │ ├── ask_modal.py # Question dialog
290
+ │ ├── permission_modal.py # Permission dialog
291
+ │ ├── history_modal.py # Session history
292
+ │ └── command_palette.py
293
+ ├── config/
294
+ │ └── settings.py # Config + local_data_dir()
295
+ └── storage/
296
+ └── database.py # .devobin/ + sessions
297
+ ```
298
+
299
+ ---
300
+
301
+ ## Configuration
302
+
303
+ ### Platform Config (providers, settings)
304
+
305
+ | Platform | Location |
306
+ |----------|----------|
307
+ | Windows | `%APPDATA%/devobin/` |
308
+ | Linux | `~/.config/devobin/` |
309
+ | macOS | `~/Library/Application Support/devobin/` |
310
+
311
+ ### Project Data (history, memory)
312
+
313
+ Stored in `.devobin/` inside your project directory:
314
+
315
+ ```
316
+ your-project/
317
+ ├── .devobin/
318
+ │ └── projects/
319
+ │ └── myproject/
320
+ │ ├── memory.json
321
+ │ ├── meta.json
322
+ │ └── sessions/
323
+ │ ├── 2026-07-14T10-30-00.json
324
+ │ └── 2026-07-14T11-15-00.json
325
+ ├── src/
326
+ │ └── ...
327
+ └── caching_prompt.md ← DevObin created this
328
+ ```
329
+
330
+ ---
331
+
332
+ ## Security
333
+
334
+ - API keys stored locally, never sent anywhere except the provider
335
+ - Tool `write` only allows `.md` files (no code execution)
336
+ - Directory traversal blocked
337
+ - File access requires explicit user permission
338
+ - Grounding check prevents hallucinated technology suggestions
339
+
340
+ ---
341
+
342
+ ## Dependencies
343
+
344
+ - Python ≥ 3.12
345
+ - Typer (CLI)
346
+ - Textual (TUI)
347
+ - Rich (rendering)
348
+ - openai / anthropic / google-genai (AI providers)
349
+ - httpx (HTTP client)
350
+ - platformdirs (config paths)
351
+ - arabic-reshaper + python-bidi (RTL support)
352
+
353
+ ---
354
+
355
+ ## License
356
+
357
+ MIT License
358
+
359
+ ## Author
360
+
361
+ **Mobin Hasanghasemi**
362
+ - GitHub: [github.com/mobinhasanghasemi](https://github.com/mobinhasanghasemi)
363
+
364
+ </div>
@@ -0,0 +1,47 @@
1
+ devobin/__init__.py,sha256=YjUkv0KxR0sxxj-0ysvIDPFyuH6aNxDoG9tYY2Pbrvc,125
2
+ devobin/app.py,sha256=yTciS9ilhWXglkQnfe7WMqB-NmvjzjgJhMTJRfSVPEg,855
3
+ devobin/main.py,sha256=1jhwSTUMJyGWReTWe2BYukZR4UHkfCXRXi4-kzawKek,840
4
+ devobin/cli/__init__.py,sha256=iGXvJhmfACDqR543o2tHmSOo8dbAzxDagfC3gtgqnXk,27
5
+ devobin/cli/chat.py,sha256=jj7hgPilkKQhvWQptii1FeCwbWUzo9Ulm_k8Oysibxg,31593
6
+ devobin/cli/commands.py,sha256=KKE6-n0rdd8rDU54j4rCMCRQxWhgJH1xN8acdOrM1mk,11867
7
+ devobin/cli/slash_menu.py,sha256=GZJUXKd0cPwCI_B0EW1s1x--7hij8wM7I2HJbK_tvVY,1971
8
+ devobin/cli/terminal.py,sha256=WuIc-C0X4zsU-OrRKDAnpaCvLNYyiTa-cfeVaPobYOw,5693
9
+ devobin/cli/ui.py,sha256=rNax2gzoamCrnirFf6eSd8RT3L0Dqqx0kpxz8sJLEH0,3828
10
+ devobin/config/__init__.py,sha256=lKAyw6o0UPXPyZtHbct4-UTSa67CX6vrLEwqU5uZlnc,30
11
+ devobin/config/settings.py,sha256=SwBpSfmzf3wPW8tMabaD8kh0ARR6C2YcQac-jaQt4js,4134
12
+ devobin/core/__init__.py,sha256=-vM6pRScYrjYz9hPFnKZp6Il6OL9_nTREOo0LSPruOM,28
13
+ devobin/core/analyzer.py,sha256=Uci1DnaWfYlgu_wMYle1E7M0ZqPP-XKFE8egt7xgmag,7848
14
+ devobin/core/executor.py,sha256=bEbYxOhJjbbsJbbnkR4B-iYbLU1CfMcY7_Z4SiCd_A4,8551
15
+ devobin/core/memory.py,sha256=5zCTzCVjZCwazIGDiD6Zpk34BFQNdAZ9r8oEKWwVS-g,3390
16
+ devobin/core/optimizer.py,sha256=olnllOSc8x76ho1L9wlC1x1FuSI6H3OMC7HiWPJvZPk,3177
17
+ devobin/core/prompt_builder.py,sha256=6f2QmYE2iS2fl_zFP82fg6ywpkFvfvptAe_9A9jTkvI,22693
18
+ devobin/core/researcher.py,sha256=2bNrsGfFHb37ABEpmE0bDpcxgk3g7to1lxq6GMze1zw,12540
19
+ devobin/core/rtl.py,sha256=vJ1v6SPLPzs3d2KoJMyO-8plQ6a2Cnosi0j4MIV6KgM,2615
20
+ devobin/core/scanner.py,sha256=xg36tJU4YfFuICr-FiqMVT5Zc7JzvL88w5CvKA1tN-Y,7496
21
+ devobin/core/tools.py,sha256=EiLy7arBgPp0HG7G5-SSuJYeOys3H-o0qYWf4wpDqiQ,11115
22
+ devobin/core/validator.py,sha256=P0qrUi7QwB4rtBM70fudmp7j05hnZB4bV4HQyN6jqCQ,8167
23
+ devobin/output/__init__.py,sha256=BxuchUlsC1eveO7X9YrjDd7eVF2TKX8XYV16LORMAmA,30
24
+ devobin/providers/__init__.py,sha256=6M_BNaXOuJdu0JhQ2Avo8kXqwpjRfyHofxbPwp0jnW0,2643
25
+ devobin/providers/anthropic_provider.py,sha256=IE0bhotNHmdsRAMNscFq76jlmhl38ZbYIT3lLHKhQ1I,2043
26
+ devobin/providers/google_provider.py,sha256=hlxQA5f0Rtx7aIz4BWBJOj7EfXhcG-DSjI_nGIv6otY,2858
27
+ devobin/providers/ollama_provider.py,sha256=QfAVtW9r7F339Yjg-4BcTFUuY5nhMuO5LSNR3i6VjbI,2562
28
+ devobin/providers/openai_provider.py,sha256=vYQqQKAgPVdP2Ed_8ep0UdpndNB_PbAaNIYaI4i7krQ,3179
29
+ devobin/storage/__init__.py,sha256=CCPB9nxM9mZ2mWQoh86RgrQZ_Nw1b1xUhxxjDe19tQ8,31
30
+ devobin/storage/database.py,sha256=x2RGzC8z-UqMEA0wxW7k1SQE_BQZk4zCYfM2fdUuJcQ,7837
31
+ devobin/ui/__init__.py,sha256=QhLE3PlkEauq79-Zqao5ICkAXp6Kh7EgNEyM-dNtj9g,26
32
+ devobin/ui/ask_modal.py,sha256=liH6U64ha3ApPm7AV2_8zoUXUi3KwBWgm8h-a1fDCbc,2699
33
+ devobin/ui/chat_screen.py,sha256=Azb0yGbnnkwSEIu3_PLreMkJZzyOOp-Y9knJWzL0rjc,42573
34
+ devobin/ui/command_palette.py,sha256=Pppb8VlsAYqSBXzowSocGr-JCTcLCuWmQcm7Nv8BLx4,4319
35
+ devobin/ui/connect_modal.py,sha256=ICG_2VwlyMbvhjys78osmJH1T1Gl6Xn8d3S4LX-c-Q8,5085
36
+ devobin/ui/export_modal.py,sha256=pMRfdwPDvNdQqapbT3jX1GYMrUuBaYLwE6M2xe1BZXg,5248
37
+ devobin/ui/history_modal.py,sha256=Xa86Tq523jEWGE1Pd03UBWGmDHOtPHiR3w62OIUPiCo,4222
38
+ devobin/ui/memory_modal.py,sha256=_kTT0U-7_9sR9IbCGsUMKgGszwsh4u5zgx8AQQyUsPM,2295
39
+ devobin/ui/model_modal.py,sha256=MOL9t8HD1iysAH_L9uokcGWr2tPeVGosHN2VpNU-rUg,4511
40
+ devobin/ui/permission_modal.py,sha256=zo85dAw_11EJ3TOVTl3OS2VEpxhJ9aEDZ6Pc3cnEqXw,2672
41
+ devobin/ui/project_modal.py,sha256=wY93Iqazkvm8Cba9UZynjxoBuiQAvqoQT-sF3pIBtxA,4072
42
+ devobin/ui/settings_modal.py,sha256=25vmfVsNHtx74kbh_B9CRP4ydCcKOTBgrHAtyNJ4lgw,2299
43
+ devobin-1.0.0.dist-info/METADATA,sha256=Gce4vlvQV7Djlt7BtUru-w9mJSgzqMDB2nwytGHPqrE,9906
44
+ devobin-1.0.0.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
45
+ devobin-1.0.0.dist-info/entry_points.txt,sha256=uJzz0HzyVCrr_udp836p_b7otEXSd37_iBAhzeCn2CA,45
46
+ devobin-1.0.0.dist-info/licenses/LICENSE,sha256=_AItAgR8WDoSrZNNdwGWh9BoK58lKVJxomCC4CPRlak,1069
47
+ devobin-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.31.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ devobin = devobin.main:app
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 DevObin Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.