iflow2api 1.4.7__tar.gz

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 (48) hide show
  1. iflow2api-1.4.7/.dockerignore +55 -0
  2. iflow2api-1.4.7/.github/workflows/build.yml +305 -0
  3. iflow2api-1.4.7/.gitignore +45 -0
  4. iflow2api-1.4.7/.python-version +1 -0
  5. iflow2api-1.4.7/CLAUDE.md +104 -0
  6. iflow2api-1.4.7/Dockerfile +66 -0
  7. iflow2api-1.4.7/LICENSE +21 -0
  8. iflow2api-1.4.7/PKG-INFO +495 -0
  9. iflow2api-1.4.7/README.md +457 -0
  10. iflow2api-1.4.7/README_EN.md +455 -0
  11. iflow2api-1.4.7/docker-compose.yml +47 -0
  12. iflow2api-1.4.7/docs/DOCKER.md +212 -0
  13. iflow2api-1.4.7/flet_build.py +79 -0
  14. iflow2api-1.4.7/iflow2api/__init__.py +3 -0
  15. iflow2api-1.4.7/iflow2api/__main__.py +6 -0
  16. iflow2api-1.4.7/iflow2api/admin/__init__.py +13 -0
  17. iflow2api-1.4.7/iflow2api/admin/auth.py +309 -0
  18. iflow2api-1.4.7/iflow2api/admin/routes.py +701 -0
  19. iflow2api-1.4.7/iflow2api/admin/static/css/style.css +644 -0
  20. iflow2api-1.4.7/iflow2api/admin/static/index.html +423 -0
  21. iflow2api-1.4.7/iflow2api/admin/static/js/app.js +703 -0
  22. iflow2api-1.4.7/iflow2api/admin/websocket.py +94 -0
  23. iflow2api-1.4.7/iflow2api/app.py +1675 -0
  24. iflow2api-1.4.7/iflow2api/autostart.py +242 -0
  25. iflow2api-1.4.7/iflow2api/config.py +177 -0
  26. iflow2api-1.4.7/iflow2api/crypto.py +381 -0
  27. iflow2api-1.4.7/iflow2api/gui.py +1058 -0
  28. iflow2api-1.4.7/iflow2api/i18n.py +120 -0
  29. iflow2api-1.4.7/iflow2api/instances.py +418 -0
  30. iflow2api-1.4.7/iflow2api/locales/en.json +114 -0
  31. iflow2api-1.4.7/iflow2api/locales/zh.json +114 -0
  32. iflow2api-1.4.7/iflow2api/main.py +6 -0
  33. iflow2api-1.4.7/iflow2api/oauth.py +209 -0
  34. iflow2api-1.4.7/iflow2api/oauth_login.py +154 -0
  35. iflow2api-1.4.7/iflow2api/proxy.py +642 -0
  36. iflow2api-1.4.7/iflow2api/ratelimit.py +291 -0
  37. iflow2api-1.4.7/iflow2api/server.py +152 -0
  38. iflow2api-1.4.7/iflow2api/settings.py +279 -0
  39. iflow2api-1.4.7/iflow2api/token_refresher.py +213 -0
  40. iflow2api-1.4.7/iflow2api/tray.py +210 -0
  41. iflow2api-1.4.7/iflow2api/updater.py +191 -0
  42. iflow2api-1.4.7/iflow2api/version.py +255 -0
  43. iflow2api-1.4.7/iflow2api/vision.py +459 -0
  44. iflow2api-1.4.7/iflow2api/web_server.py +340 -0
  45. iflow2api-1.4.7/main.py +11 -0
  46. iflow2api-1.4.7/pyproject.toml +71 -0
  47. iflow2api-1.4.7/uv.lock +1511 -0
  48. iflow2api-1.4.7/webui-settings.png +0 -0
@@ -0,0 +1,55 @@
1
+ # Git
2
+ .git
3
+ .gitignore
4
+
5
+ # Python
6
+ __pycache__
7
+ *.py[cod]
8
+ *$py.class
9
+ *.so
10
+ .Python
11
+ .venv
12
+ venv/
13
+ ENV/
14
+
15
+ # IDE
16
+ .idea/
17
+ .vscode/
18
+ *.swp
19
+ *.swo
20
+
21
+ # Testing
22
+ .pytest_cache/
23
+ .coverage
24
+ htmlcov/
25
+ .tox/
26
+ .nox/
27
+
28
+ # Build artifacts
29
+ dist/
30
+ build/
31
+ *.egg-info/
32
+ *.egg
33
+ .eggs/
34
+
35
+ # Ruff
36
+ .ruff_cache/
37
+
38
+ # Documentation
39
+ docs/
40
+ # 保留 README.md(构建需要)
41
+ # *.md
42
+
43
+ # Development files
44
+ .github/
45
+ .python-version
46
+ CLAUDE.md
47
+ TODO.md
48
+
49
+ # Build scripts
50
+ build.py
51
+
52
+ # Misc
53
+ nul
54
+ *.log
55
+ *.tmp
@@ -0,0 +1,305 @@
1
+ name: Build
2
+
3
+ on:
4
+ push:
5
+ branches: ['**']
6
+ tags:
7
+ - 'v*'
8
+ pull_request:
9
+ branches: [main]
10
+ workflow_dispatch:
11
+
12
+ permissions:
13
+ contents: write
14
+
15
+ jobs:
16
+ # 版本验证作业
17
+ verify-version:
18
+ runs-on: ubuntu-latest
19
+ outputs:
20
+ version: ${{ steps.get-version.outputs.version }}
21
+
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+
25
+ - name: Get version from pyproject.toml
26
+ id: get-version
27
+ run: |
28
+ VERSION=$(grep -oP '^version\s*=\s*"\K[^"]+' pyproject.toml)
29
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
30
+ echo "pyproject.toml version: $VERSION"
31
+
32
+ - name: Get version from version.py
33
+ id: get-version-py
34
+ run: |
35
+ VERSION_PY=$(grep -oP '^__version__\s*=\s*"\K[^"]+' iflow2api/version.py)
36
+ echo "version_py=$VERSION_PY" >> $GITHUB_OUTPUT
37
+ echo "version.py version: $VERSION_PY"
38
+
39
+ - name: Verify version consistency
40
+ run: |
41
+ PYPROJECT_VERSION="${{ steps.get-version.outputs.version }}"
42
+ VERSION_PY="${{ steps.get-version-py.outputs.version_py }}"
43
+
44
+ if [ "$PYPROJECT_VERSION" != "$VERSION_PY" ]; then
45
+ echo "::error::Version mismatch! pyproject.toml: $PYPROJECT_VERSION, version.py: $VERSION_PY"
46
+ exit 1
47
+ fi
48
+ echo "✓ Version consistency check passed: $PYPROJECT_VERSION"
49
+
50
+ - name: Verify tag version matches pyproject.toml
51
+ if: startsWith(github.ref, 'refs/tags/v')
52
+ run: |
53
+ PYPROJECT_VERSION="${{ steps.get-version.outputs.version }}"
54
+ TAG_VERSION="${GITHUB_REF#refs/tags/v}"
55
+
56
+ if [ "$PYPROJECT_VERSION" != "$TAG_VERSION" ]; then
57
+ echo "::error::Tag version ($TAG_VERSION) does not match pyproject.toml version ($PYPROJECT_VERSION)"
58
+ exit 1
59
+ fi
60
+ echo "✓ Tag version matches pyproject.toml: $TAG_VERSION"
61
+
62
+ build:
63
+ needs: verify-version
64
+ strategy:
65
+ matrix:
66
+ include:
67
+ - os: windows-latest
68
+ platform: windows
69
+ artifact: iflow2api.exe
70
+ - os: macos-latest
71
+ platform: macos
72
+ artifact: iflow2api.app
73
+ - os: ubuntu-latest
74
+ platform: linux
75
+ artifact: iflow2api
76
+
77
+ runs-on: ${{ matrix.os }}
78
+
79
+ steps:
80
+ - uses: actions/checkout@v4
81
+
82
+ - name: Set up Python
83
+ uses: actions/setup-python@v5
84
+ with:
85
+ python-version: '3.12'
86
+
87
+ - name: Install dependencies
88
+ run: |
89
+ python -m pip install --upgrade pip
90
+ pip install flet pystray Pillow
91
+
92
+ - name: Install Linux dependencies
93
+ if: matrix.os == 'ubuntu-latest'
94
+ run: |
95
+ sudo apt-get update
96
+ sudo apt-get install -y libgtk-3-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libmpv-dev ninja-build clang python3-gi gir1.2-appindicator3-0.1
97
+
98
+ - name: Build with Flet
99
+ env:
100
+ PYTHONIOENCODING: utf-8
101
+ PYTHONUTF8: 1
102
+ shell: bash
103
+ run: |
104
+ echo "y" | flet build ${{ matrix.platform }} --project iflow2api --product iflow2api
105
+
106
+ - name: Fix macOS executable permissions
107
+ if: matrix.os == 'macos-latest'
108
+ run: |
109
+ chmod +x build/macos/iflow2api.app/Contents/MacOS/iflow2api
110
+
111
+ - name: Upload artifact
112
+ uses: actions/upload-artifact@v4
113
+ with:
114
+ name: iflow2api-${{ matrix.platform }}
115
+ path: build/${{ matrix.platform }}/
116
+
117
+ # Docker 构建和发布(滚动发布策略)
118
+ # - main 分支推送 -> edge 标签(开发版)
119
+ # - v* 标签推送 -> 版本号标签 + latest(正式版)
120
+ docker:
121
+ needs: verify-version
122
+ runs-on: ubuntu-latest
123
+ environment: DOCKERHUB
124
+ permissions:
125
+ contents: read
126
+ packages: write
127
+
128
+ steps:
129
+ - uses: actions/checkout@v4
130
+
131
+ - name: Set up QEMU
132
+ uses: docker/setup-qemu-action@v3
133
+
134
+ - name: Set up Docker Buildx
135
+ uses: docker/setup-buildx-action@v3
136
+
137
+ - name: Login to Docker Hub
138
+ if: github.event_name != 'pull_request'
139
+ uses: docker/login-action@v3
140
+ with:
141
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
142
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
143
+
144
+ - name: Login to GitHub Container Registry
145
+ if: github.event_name != 'pull_request'
146
+ uses: docker/login-action@v3
147
+ with:
148
+ registry: ghcr.io
149
+ username: ${{ github.actor }}
150
+ password: ${{ secrets.GITHUB_TOKEN }}
151
+
152
+ - name: Extract metadata for edge
153
+ id: meta-edge
154
+ if: github.ref == 'refs/heads/main'
155
+ uses: docker/metadata-action@v5
156
+ with:
157
+ images: |
158
+ ${{ secrets.DOCKERHUB_USERNAME }}/iflow2api
159
+ ghcr.io/${{ github.repository }}
160
+ tags: |
161
+ type=raw,value=edge
162
+
163
+ - name: Extract metadata for release
164
+ id: meta-release
165
+ if: startsWith(github.ref, 'refs/tags/v')
166
+ uses: docker/metadata-action@v5
167
+ with:
168
+ images: |
169
+ ${{ secrets.DOCKERHUB_USERNAME }}/iflow2api
170
+ ghcr.io/${{ github.repository }}
171
+ # 标签策略:
172
+ # - v1.1.5 -> 1.1.5, 1.1, latest
173
+ # - v1.0.5 -> 1.0.5, 1.0
174
+ # - v2.0.0 -> 2.0.0, 2.0, latest
175
+ flavor: |
176
+ latest=auto
177
+ tags: |
178
+ type=semver,pattern={{version}}
179
+ type=semver,pattern={{major}}.{{minor}}
180
+
181
+ - name: Build and push (edge)
182
+ if: github.ref == 'refs/heads/main'
183
+ uses: docker/build-push-action@v5
184
+ with:
185
+ context: .
186
+ platforms: linux/amd64,linux/arm64
187
+ push: true
188
+ tags: ${{ steps.meta-edge.outputs.tags }}
189
+ labels: ${{ steps.meta-edge.outputs.labels }}
190
+ cache-from: type=gha
191
+ cache-to: type=gha,mode=max
192
+
193
+ - name: Build and push (release)
194
+ if: startsWith(github.ref, 'refs/tags/v')
195
+ uses: docker/build-push-action@v5
196
+ with:
197
+ context: .
198
+ platforms: linux/amd64,linux/arm64
199
+ push: true
200
+ tags: ${{ steps.meta-release.outputs.tags }}
201
+ labels: ${{ steps.meta-release.outputs.labels }}
202
+ cache-from: type=gha
203
+ cache-to: type=gha,mode=max
204
+
205
+ # PyPI 包构建
206
+ build-pypi:
207
+ needs: verify-version
208
+ runs-on: ubuntu-latest
209
+ steps:
210
+ - uses: actions/checkout@v4
211
+
212
+ - name: Set up Python
213
+ uses: actions/setup-python@v5
214
+ with:
215
+ python-version: '3.11'
216
+
217
+ - name: Install build tools and dependencies
218
+ run: |
219
+ python -m pip install --upgrade pip
220
+ pip install build twine
221
+ pip install flet pystray Pillow
222
+
223
+ - name: Build package
224
+ run: python -m build
225
+
226
+ - name: Check package
227
+ run: python -m twine check dist/*
228
+
229
+ - name: Upload build artifacts
230
+ uses: actions/upload-artifact@v4
231
+ with:
232
+ name: pypi-packages
233
+ path: dist/
234
+ retention-days: 1
235
+
236
+ # 发布到 TestPyPI(每次推送都执行)
237
+ publish-testpypi:
238
+ needs: build-pypi
239
+ runs-on: ubuntu-latest
240
+ environment: DOCKERHUB
241
+ permissions:
242
+ id-token: write
243
+ steps:
244
+ - name: Download build artifacts
245
+ uses: actions/download-artifact@v4
246
+ with:
247
+ name: pypi-packages
248
+ path: dist/
249
+
250
+ - name: Publish to TestPyPI
251
+ uses: pypa/gh-action-pypi-publish@release/v1
252
+ with:
253
+ repository-url: https://test.pypi.org/legacy/
254
+ password: ${{ secrets.TEST_PYPI_API_KEY }}
255
+ skip-existing: true
256
+
257
+ # 发布到正式 PyPI(仅 tag 触发)
258
+ publish-pypi:
259
+ needs: [verify-version, build-pypi]
260
+ runs-on: ubuntu-latest
261
+ if: startsWith(github.ref, 'refs/tags/v')
262
+ environment: DOCKERHUB
263
+ permissions:
264
+ id-token: write
265
+ steps:
266
+ - name: Download build artifacts
267
+ uses: actions/download-artifact@v4
268
+ with:
269
+ name: pypi-packages
270
+ path: dist/
271
+
272
+ - name: Publish to PyPI
273
+ uses: pypa/gh-action-pypi-publish@release/v1
274
+ with:
275
+ password: ${{ secrets.PYPI_API_KEY }}
276
+
277
+ release:
278
+ needs: [verify-version, build, docker, publish-pypi]
279
+ runs-on: ubuntu-latest
280
+ if: startsWith(github.ref, 'refs/tags/v')
281
+
282
+ steps:
283
+ - name: Download all artifacts
284
+ uses: actions/download-artifact@v4
285
+ with:
286
+ path: artifacts
287
+
288
+ - name: Create archives
289
+ run: |
290
+ cd artifacts
291
+ zip -r iflow2api-windows.zip iflow2api-windows/
292
+ tar -czvf iflow2api-macos.tar.gz iflow2api-macos/
293
+ tar -czvf iflow2api-linux.tar.gz iflow2api-linux/
294
+
295
+ - name: Create Release
296
+ uses: softprops/action-gh-release@v1
297
+ with:
298
+ files: |
299
+ artifacts/iflow2api-windows.zip
300
+ artifacts/iflow2api-macos.tar.gz
301
+ artifacts/iflow2api-linux.tar.gz
302
+ artifacts/pypi-packages/*
303
+ generate_release_notes: true
304
+ env:
305
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,45 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ *.spec
11
+ downloads/
12
+ eggs/
13
+ .eggs/
14
+ lib/
15
+ lib64/
16
+ parts/
17
+ sdist/
18
+ var/
19
+ wheels/
20
+ *.egg-info/
21
+ .installed.cfg
22
+ *.egg
23
+
24
+ # Virtual environments
25
+ .venv/
26
+ venv/
27
+ ENV/
28
+
29
+ # IDE
30
+ .idea/
31
+ .vscode/
32
+ *.swp
33
+ *.swo
34
+
35
+ # Claude
36
+ .claude/
37
+
38
+ # OS
39
+ .DS_Store
40
+ Thumbs.db
41
+
42
+ # Misc
43
+ nul
44
+ *.log
45
+ TODO.md
@@ -0,0 +1 @@
1
+ 3.13
@@ -0,0 +1,104 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ **iflow2api** 是一个将 iFlow CLI 的 AI 服务暴露为 OpenAI 兼容 API 的代理服务。
8
+
9
+ 核心功能:
10
+ - 自动读取 iFlow 配置文件 (`~/.iflow/settings.json`)
11
+ - 通过特殊 User-Agent (`iFlow-Cli`) 解锁 iFlow CLI 专属模型
12
+ - 提供 OpenAI 兼容的 API 端点
13
+ - 内置 GUI OAuth 登录界面,无需安装 iFlow CLI
14
+ - 支持 OAuth token 自动刷新
15
+
16
+ ## Build & Run Commands
17
+
18
+ ### 环境设置(推荐使用 uv)
19
+
20
+ ```bash
21
+ # 安装 uv (如果未安装)
22
+ curl -LsSf https://astral.sh/uv/install.sh | sh
23
+
24
+ # 创建虚拟环境(自动识别 .python-version)
25
+ uv venv
26
+
27
+ # 安装项目依赖
28
+ uv sync
29
+
30
+ # 激活虚拟环境(可选,uv run 会自动使用)
31
+ source .venv/bin/activate # Linux/Mac
32
+ # 或 .venv\Scripts\activate # Windows
33
+ ```
34
+
35
+ ### 运行服务
36
+
37
+ ```bash
38
+ # 使用 uv 运行(推荐)
39
+ uv run python -m iflow2api
40
+
41
+ # 或激活虚拟环境后直接运行
42
+ python -m iflow2api
43
+
44
+ # 或指定端口
45
+ uv run python -c "import uvicorn; from iflow2api.app import app; uvicorn.run(app, host='0.0.0.0', port=8001)"
46
+
47
+ # 测试
48
+ curl http://localhost:8001/health
49
+ curl http://localhost:8001/v1/models
50
+ curl http://localhost:8001/v1/chat/completions -H "Content-Type: application/json" \
51
+ -d '{"model":"glm-4.7","messages":[{"role":"user","content":"hi"}]}'
52
+ ```
53
+
54
+ ## Architecture
55
+
56
+ ```
57
+ iflow2api/
58
+ ├── __init__.py # 包初始化
59
+ ├── __main__.py # CLI 入口
60
+ ├── main.py # 主入口
61
+ ├── config.py # iFlow 配置读取器 (从 ~/.iflow/settings.json)
62
+ ├── proxy.py # API 代理 (添加 user-agent: iFlow-Cli header)
63
+ ├── app.py # FastAPI 应用 (OpenAI 兼容端点)
64
+ ├── oauth.py # OAuth 认证逻辑
65
+ ├── oauth_login.py # OAuth 登录处理器
66
+ ├── token_refresher.py # OAuth token 自动刷新
67
+ ├── settings.py # 应用配置管理
68
+ └── gui.py # GUI 界面
69
+ ```
70
+
71
+ ## Key Implementation Details
72
+
73
+ ### 解锁 iFlow CLI 专属模型
74
+
75
+ iFlow API 通过 User-Agent header 区分普通 API 调用和 CLI 调用:
76
+ - 普通调用:只能使用 glm-4.6 等基础模型
77
+ - CLI 调用 (`user-agent: iFlow-Cli`):可使用 glm-4.7, deepseek-r1, kimi-k2 等高级模型
78
+
79
+ ### 配置文件位置
80
+
81
+ - Windows: `C:\Users\<user>\.iflow\settings.json`
82
+ - Linux/Mac: `~/.iflow/settings.json`
83
+
84
+ 关键字段:
85
+ - `apiKey`: API 密钥
86
+ - `baseUrl`: API 端点 (默认 https://apis.iflow.cn/v1)
87
+ - `selectedAuthType`: 认证类型 (oauth-iflow, api-key, openai-compatible)
88
+
89
+ ## API Endpoints
90
+
91
+ | 端点 | 方法 | 说明 |
92
+ |------|------|------|
93
+ | `/health` | GET | 健康检查 |
94
+ | `/v1/models` | GET | 获取可用模型列表 |
95
+ | `/v1/chat/completions` | POST | Chat Completions API |
96
+ | `/models` | GET | 兼容端点 |
97
+ | `/chat/completions` | POST | 兼容端点 |
98
+
99
+ ## Dependencies
100
+
101
+ - FastAPI: Web 框架
102
+ - uvicorn: ASGI 服务器
103
+ - httpx: 异步 HTTP 客户端
104
+ - pydantic: 数据验证
@@ -0,0 +1,66 @@
1
+ # iFlow2API Dockerfile
2
+ # 多阶段构建,优化镜像大小
3
+
4
+ # 阶段1: 构建阶段
5
+ FROM python:3.12-slim AS builder
6
+
7
+ # 安装构���依赖
8
+ RUN apt-get update && apt-get install -y --no-install-recommends \
9
+ build-essential \
10
+ && rm -rf /var/lib/apt/lists/*
11
+
12
+ # 安装 uv 包管理器
13
+ RUN pip install uv
14
+
15
+ # 设置工作目录
16
+ WORKDIR /app
17
+
18
+ # 复制依赖文件和 README(pyproject.toml 需要)
19
+ COPY pyproject.toml uv.lock README.md ./
20
+
21
+ # 使用 uv 安装依赖到虚拟环境
22
+ RUN uv venv /opt/venv
23
+ ENV VIRTUAL_ENV=/opt/venv
24
+ ENV PATH="/opt/venv/bin:$PATH"
25
+ # 使用 uv sync 从 lock 文件安装依赖,--active 使用已存在的虚拟环境
26
+ RUN uv sync --frozen --no-dev --active
27
+
28
+ # 阶段2: 运行阶段
29
+ FROM python:3.12-slim
30
+
31
+ # 安装运行时依赖
32
+ RUN apt-get update && apt-get install -y --no-install-recommends \
33
+ curl \
34
+ && rm -rf /var/lib/apt/lists/*
35
+
36
+ # 从构建阶段复制虚拟环境
37
+ COPY --from=builder /opt/venv /opt/venv
38
+ ENV PATH="/opt/venv/bin:$PATH"
39
+
40
+ # 创建非 root 用户
41
+ RUN useradd --create-home --shell /bin/bash appuser
42
+
43
+ # 设置工作目录
44
+ WORKDIR /app
45
+
46
+ # 复制应用代码
47
+ COPY --chown=appuser:appuser . .
48
+
49
+ # 切换到非 root 用户
50
+ USER appuser
51
+
52
+ # 设置环境变量
53
+ ENV PYTHONUNBUFFERED=1
54
+ ENV PYTHONDONTWRITEBYTECODE=1
55
+ ENV HOST=0.0.0.0
56
+ ENV PORT=28000
57
+
58
+ # 暴露端口
59
+ EXPOSE 28000
60
+
61
+ # 健康检查
62
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
63
+ CMD curl -f http://localhost:28000/health || exit 1
64
+
65
+ # 启动命令
66
+ CMD ["python", "-m", "iflow2api.main"]
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kuang
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.