dsh-book-reader 0.0.0-stage → 0.1.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/CHANGELOG.md +60 -0
- package/LICENSE +21 -0
- package/README.md +100 -2
- package/SKILL.md +96 -0
- package/cordis.patch.yml +30 -0
- package/icon.svg +13 -0
- package/lib/client.js +1773 -0
- package/lib/core/README.md +299 -0
- package/lib/core/pdf.js +962 -0
- package/lib/core/render.js +351 -0
- package/lib/core/tokens.js +116 -0
- package/lib/index.js +1850 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +83 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
|
|
5
|
+
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [0.1.1] — 2026-10-18
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Simplified, feature-focused README (English + 中文) that leads with what the
|
|
12
|
+
plugin does instead of full internals documentation.
|
|
13
|
+
- The automatic reading-position hint is now sent **at most once per turn**, and
|
|
14
|
+
only when the page changed. The per-step guard and the 3-minute default
|
|
15
|
+
throttle are gone: `autoShareMinSteps` was removed and
|
|
16
|
+
`autoShareMinIntervalMs` now defaults to `0` (optional extra throttle).
|
|
17
|
+
- Repository, homepage, and issue links now point to
|
|
18
|
+
`github.com/Strepsiades2/dsh-book-reader`.
|
|
19
|
+
|
|
20
|
+
### Removed
|
|
21
|
+
|
|
22
|
+
- The `pdf_current_page` tool. The per-turn position hint (or a page reference
|
|
23
|
+
you insert yourself) now covers “which page am I on”, leaving three tools:
|
|
24
|
+
`pdf_info`, `pdf_search`, and `pdf_read_pages`.
|
|
25
|
+
- The toolbar's manual “insert current page reference” (↗) button. The
|
|
26
|
+
automatic per-turn position hint already tells the model the current page, so
|
|
27
|
+
the button was redundant. The search panel's per-result “→ AI” insertion
|
|
28
|
+
remains.
|
|
29
|
+
|
|
30
|
+
## [0.1.0] — 2026-10-18
|
|
31
|
+
|
|
32
|
+
First public release.
|
|
33
|
+
|
|
34
|
+
### Added
|
|
35
|
+
|
|
36
|
+
- Toolbar controls on DSH's official PDF preview: previous/next page, printed
|
|
37
|
+
and physical page readout with a jump box, full-text search panel
|
|
38
|
+
(`Cmd/Ctrl+Shift+F`), share-page reference insertion, and an AI reading-position
|
|
39
|
+
toggle.
|
|
40
|
+
- Hover explanations for every toolbar control, in the active DSH UI language
|
|
41
|
+
(English and Simplified Chinese).
|
|
42
|
+
- Four model-facing tools: `pdf_info` (page map and outline), `pdf_search`
|
|
43
|
+
(literal full-text search), `pdf_read_pages` (text first, optional page
|
|
44
|
+
images), and `pdf_current_page` (what the user is reading).
|
|
45
|
+
- Per-turn reading-position injection behind `agent/pre-step`, debounced and
|
|
46
|
+
rate-limited.
|
|
47
|
+
- Local JSON routes for the browser half, loopback-only and restricted by
|
|
48
|
+
`routeAllowedRoots` / the session workspace by default.
|
|
49
|
+
- Bundle display metadata: localized title/description and an SVG icon for the
|
|
50
|
+
DSH Plugins page.
|
|
51
|
+
|
|
52
|
+
### Notes
|
|
53
|
+
|
|
54
|
+
- Depends on the official preview's private DOM markers; DSH upgrades may change
|
|
55
|
+
them.
|
|
56
|
+
- `pdfjs-dist` is pinned to `6.3.289` to match the host process.
|
|
57
|
+
- MIT licensed.
|
|
58
|
+
|
|
59
|
+
[0.1.1]: https://github.com/Strepsiades2/dsh-book-reader/releases/tag/v0.1.1
|
|
60
|
+
[0.1.0]: https://github.com/Strepsiades2/dsh-book-reader/releases/tag/v0.1.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 the dsh-book-reader authors
|
|
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.
|
package/README.md
CHANGED
|
@@ -1,3 +1,101 @@
|
|
|
1
|
-
#
|
|
1
|
+
# dsh-book-reader
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Read books and papers in DSH: a reading toolbar on the official PDF preview, plus three PDF tools for the model.
|
|
4
|
+
|
|
5
|
+
**English** | [中文](#中文说明)
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
**Reading toolbar** — appears only on `.pdf` previews in the right sidebar; the stock previewer (zoom, selection, reload) is untouched.
|
|
10
|
+
|
|
11
|
+
- Previous/next page, a page readout that follows scrolling, and a jump box that accepts printed page numbers (or `p152` for PDF page 152).
|
|
12
|
+
- Full-text search panel (`Cmd/Ctrl+Shift+F`): click a result to jump there, or insert its page reference into the chat.
|
|
13
|
+
- **AI position hint** (on by default): before a turn starts, the model may receive one short line with the page you are reading — at most once per turn, and only when the page changed since the last hint. Turn it off if you do not want the model to know your page automatically.
|
|
14
|
+
- Every control has a hover/focus explanation in English or Chinese, following the DSH UI language.
|
|
15
|
+
|
|
16
|
+
**Model tools** — the model can look up the page map, search the text, or read chosen pages (as text or as page images) when you ask about a PDF.
|
|
17
|
+
|
|
18
|
+
| Tool | What it does |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| `pdf_info` | Page count, printed↔physical page offset, outline/TOC. Text only. |
|
|
21
|
+
| `pdf_search` | Literal full-text search; returns page numbers and snippets. |
|
|
22
|
+
| `pdf_read_pages` | Text of chosen pages, optionally as images (`include_image: false` for text only; images cost ~350–1024 tokens/page). |
|
|
23
|
+
|
|
24
|
+
Typical loop: `pdf_info` → `pdf_search` → `pdf_read_pages` (text) → images only for formulas, diagrams, or tables.
|
|
25
|
+
|
|
26
|
+
## Install
|
|
27
|
+
|
|
28
|
+
- **From npm**: DSH **Plugins → Add plugin** → `dsh-book-reader` (or pin `dsh-book-reader@0.1.1`), or `dsh plugin add dsh-book-reader`.
|
|
29
|
+
- A fresh install applies live (this profile has HMR); **upgrading a plugin that is already loaded needs a DSH restart** to load the new code.
|
|
30
|
+
- **Optional skill** (gives the model the built-in PDF reading guide): symlink the package into the workspace:
|
|
31
|
+
```sh
|
|
32
|
+
ln -sfn "<installed package dir>" "<workspace>/.dsh/skills/pdf-reader"
|
|
33
|
+
```
|
|
34
|
+
- **Local checkout**: `dsh plugin add "/abs/path/to/dsh-book-reader"`; keep the checkout and its `node_modules/` in place.
|
|
35
|
+
|
|
36
|
+
## Configuration
|
|
37
|
+
|
|
38
|
+
Every option is optional and the defaults are safe. Common ones: `maxPagesPerCall` (default 4), `defaultScale` (2.5), `autoShare` (automatic position hint), `allowOutsideWorkspace` (tools stay inside the session workspace by default), `routeAllowedRoots` (restrict the local HTTP routes). The full list with defaults is commented in [`cordis.patch.yml`](cordis.patch.yml).
|
|
39
|
+
|
|
40
|
+
## Notes
|
|
41
|
+
|
|
42
|
+
- HTTP routes are loopback-only and unauthenticated; the tools are workspace-scoped by default. Other local preview plugins make the same tradeoff.
|
|
43
|
+
- Works only with the official PDF preview: it relies on that preview's DOM markers, which a DSH upgrade may change.
|
|
44
|
+
- Scanned PDFs have no text layer — there is no OCR, so only page images help.
|
|
45
|
+
- `pdfjs-dist` is pinned to `6.3.289` to match the host process.
|
|
46
|
+
|
|
47
|
+
## More
|
|
48
|
+
|
|
49
|
+
- [`SKILL.md`](SKILL.md) — model-facing guide: costs, page numbering, pitfalls.
|
|
50
|
+
- [`CHANGELOG.md`](CHANGELOG.md) · [`LICENSE`](LICENSE) (MIT)
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 中文说明
|
|
55
|
+
|
|
56
|
+
在 DSH 里读 PDF 书和论文:官方 PDF 预览上加一条读书工具栏,外加三个 PDF 工具给模型。
|
|
57
|
+
|
|
58
|
+
### 功能
|
|
59
|
+
|
|
60
|
+
**阅读工具栏** —— 只在右侧栏的 `.pdf` 预览上出现;不替换官方预览器(缩放、选中、刷新都保持原样)。
|
|
61
|
+
|
|
62
|
+
- 上一页/下一页、随滚动更新的页码读数、跳页框(输入印刷页码,或 `p152` 表示 PDF 第 152 页)。
|
|
63
|
+
- 全文搜索面板(`Cmd/Ctrl+Shift+F`):点结果跳页,或把该页引用插入对话框。
|
|
64
|
+
- **AI 位置提示**(默认开):每轮对话开始时,模型可能收到一行“你正在看第 N 页”的短提示 —— 每轮最多一次,且页码变了才发。关掉后,模型不会自动知道你在哪页。
|
|
65
|
+
- 每个控件都有 hover / 键盘聚焦提示,跟随 DSH 界面语言(中文或英文)。
|
|
66
|
+
|
|
67
|
+
**模型工具** —— 默认只花文本 token,图片是按需付的钱。
|
|
68
|
+
|
|
69
|
+
| 工具 | 作用 |
|
|
70
|
+
| --- | --- |
|
|
71
|
+
| `pdf_info` | 页数、印刷页↔物理页偏移、目录/TOC;纯文本。 |
|
|
72
|
+
| `pdf_search` | 字面全文搜索;返回页码和摘要。 |
|
|
73
|
+
| `pdf_read_pages` | 选中页的文本,也可返回页面图片(`include_image: false` 只取文本;图片约 350–1024 token/页)。 |
|
|
74
|
+
|
|
75
|
+
典型流程:`pdf_info` → `pdf_search` → `pdf_read_pages`(文本)→ 只有公式、图表、表格才看图。
|
|
76
|
+
|
|
77
|
+
### 安装
|
|
78
|
+
|
|
79
|
+
- **从 npm 安装**:DSH **Plugins → Add plugin** → 输入 `dsh-book-reader`(或锁定版本 `dsh-book-reader@0.1.1`),或命令行 `dsh plugin add dsh-book-reader`。
|
|
80
|
+
- 全新安装即时生效(本 profile 已启用 HMR);**升级已加载的插件需要完整重启 DSH** 才能加载新代码。
|
|
81
|
+
- **可选 skill**(给模型一份内置的 PDF 阅读指南):把包目录软链到工作区:
|
|
82
|
+
```sh
|
|
83
|
+
ln -sfn "<已安装的包目录>" "<workspace>/.dsh/skills/pdf-reader"
|
|
84
|
+
```
|
|
85
|
+
- **本地开发**:`dsh plugin add "/abs/path/to/dsh-book-reader"`;源码目录和 `node_modules/` 必须留在原处。
|
|
86
|
+
|
|
87
|
+
### 配置
|
|
88
|
+
|
|
89
|
+
全部可选,默认值即安全值。常用:`maxPagesPerCall`(默认 4)、`defaultScale`(2.5)、`autoShare`(自动位置提示)、`allowOutsideWorkspace`(工具默认只读会话工作区)、`routeAllowedRoots`(限制本地 HTTP 路由)。完整键和默认值见 [`cordis.patch.yml`](cordis.patch.yml) 注释。
|
|
90
|
+
|
|
91
|
+
### 说明
|
|
92
|
+
|
|
93
|
+
- HTTP 路由只认回环地址且无鉴权;工具默认只在工作区内。其他本地预览插件也是同样的权衡。
|
|
94
|
+
- 只支持官方 PDF 预览(依赖它的私有 DOM 标记,DSH 升级可能失效)。
|
|
95
|
+
- 扫描件没有文本层,**没有 OCR**,只能看图。
|
|
96
|
+
- `pdfjs-dist` 锁定 `6.3.289`,以和宿主进程保持一致。
|
|
97
|
+
|
|
98
|
+
### 更多
|
|
99
|
+
|
|
100
|
+
- [`SKILL.md`](SKILL.md) —— 模型使用手册:成本、页码、常见陷阱。
|
|
101
|
+
- [`CHANGELOG.md`](CHANGELOG.md) · [`LICENSE`](LICENSE)(MIT)
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pdf-reader
|
|
3
|
+
description: 'Read a PDF (book, paper, manual) cheaply and accurately with the dsh-book-reader tools: page map/TOC, literal full-text search, then selective page reads (text first, images only when typography matters). Use whenever the user asks about specific pages, a section, a theorem, a figure, or "this page" in a PDF.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Reading a PDF with `dsh-book-reader`
|
|
7
|
+
|
|
8
|
+
Three tools, two cost tiers. **The default is text.** Images are a deliberate
|
|
9
|
+
expense, not the first move.
|
|
10
|
+
|
|
11
|
+
| Tool | Cost | Use for |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| `pdf_info` | ~0 (text) | page count, printed↔physical offset, outline/TOC |
|
|
14
|
+
| `pdf_search` | ~0 (text) | locating a phrase, theorem number, or figure caption |
|
|
15
|
+
| `pdf_read_pages` + `include_image:false` | ~0 (text, per page) | prose, theorem statements, exercise text |
|
|
16
|
+
| `pdf_read_pages` (images on) | **~350–1024 tokens/page** | formulas, diagrams, tables, layout |
|
|
17
|
+
|
|
18
|
+
## Default loop (text-first)
|
|
19
|
+
|
|
20
|
+
1. `pdf_info` once per document → note `printedOffset` and the outline. Never
|
|
21
|
+
hardcode an offset; it is detected (`printed = pdf − printedOffset`).
|
|
22
|
+
2. `pdf_search` for a distinctive phrase → page numbers.
|
|
23
|
+
3. `pdf_read_pages` with **`include_image:false`** to read those pages as text.
|
|
24
|
+
4. Only if the text is ambiguous or the question is about typography (a formula,
|
|
25
|
+
a diagram, a table) → call again with images on, and crop.
|
|
26
|
+
|
|
27
|
+
## When images are worth it
|
|
28
|
+
|
|
29
|
+
- The question is about a **formula's exact form**, a **matrix layout**, a
|
|
30
|
+
**diagram**, or **which theorem box** a sentence is in.
|
|
31
|
+
- Extracted text is known to garble math: `P_{n−1}(C)` becomes `𝒫 𝑛 − 1(𝐂)`,
|
|
32
|
+
subscripts flatten, fractions collapse, theorem numbers split across lines.
|
|
33
|
+
- Prefer `crop` (`"0,0,1,0.55"` = top 55%) and `image_quality:"cheap"` (1.5×,
|
|
34
|
+
~350 tokens) unless dense subscripts need `scale:3`.
|
|
35
|
+
|
|
36
|
+
## Token economics (DeepSeek vision billing)
|
|
37
|
+
|
|
38
|
+
Each image is projected onto a 14 px patch grid, downsampled 3:1, and **capped at
|
|
39
|
+
1024 tokens**. For a 6×9 in book page:
|
|
40
|
+
|
|
41
|
+
| Render | Pixels | Tokens |
|
|
42
|
+
| --- | --- | --- |
|
|
43
|
+
| 1.5× (`image_quality:"cheap"`) | 563×954 | **347** |
|
|
44
|
+
| **2.5× (default)** | 938×1590 | **914** |
|
|
45
|
+
| 3× | 1125×1908 | 1002 (capped — no gain above ~2.7×) |
|
|
46
|
+
|
|
47
|
+
- Hard cap `maxPagesPerCall` (default **4**) is enforced before rendering.
|
|
48
|
+
- `pdf_read_pages` returns `imageTokens` and per-page `tokens`; check them.
|
|
49
|
+
- Images stay in the conversation and are re-billed on later turns. **Read once,
|
|
50
|
+
then answer in text.**
|
|
51
|
+
- Never request `scale` above 3: the provider downscales to the same grid anyway.
|
|
52
|
+
|
|
53
|
+
## Page numbering
|
|
54
|
+
|
|
55
|
+
`pdf_info` returns `printedOffset` with `physical = printed + printedOffset`.
|
|
56
|
+
Tools accept either numbering; **printed is the default when detectable**.
|
|
57
|
+
Roman-numeral front matter has no numeric printed page — use
|
|
58
|
+
`page_numbers:"pdf"`. Say which numbering you mean when it is ambiguous.
|
|
59
|
+
|
|
60
|
+
## The injected reading position
|
|
61
|
+
|
|
62
|
+
At most one short line per turn may arrive as a user message, e.g.
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
[dsh-pdf-reader] 正在阅读《book》printed 132 (PDF 152) · Chapter 5 › 5B
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
It is a **position marker only**. The model decides whether to read anything.
|
|
69
|
+
Do not read a page just because the marker exists; read it when the question
|
|
70
|
+
needs it, and prefer `include_image:false` first.
|
|
71
|
+
|
|
72
|
+
## Pitfalls
|
|
73
|
+
|
|
74
|
+
- **Scanned PDFs** have no text layer: `pdf_search` finds nothing and
|
|
75
|
+
`include_image:false` returns `textUnavailable`. Only images help.
|
|
76
|
+
- Errors are coded: `PDF_NOT_FOUND`, `PDF_NOT_FILE`, `PDF_ENCRYPTED`,
|
|
77
|
+
`PDF_CORRUPT`, `PDF_READER_INVALID_PAGE`, `PDF_READER_INVALID_SCALE`,
|
|
78
|
+
`PDF_RENDER_TIMEOUT`, `PDF_PAGE_TOO_LARGE`, `PDF_OUTSIDE_WORKSPACE`.
|
|
79
|
+
- **Tools are workspace-scoped by default.** Pass a path inside the session
|
|
80
|
+
working directory; anything outside fails with `PDF_OUTSIDE_WORKSPACE` unless
|
|
81
|
+
the user set `allowOutsideWorkspace: true`.
|
|
82
|
+
- `pdf_info` also reports `title`, `author`, `fileSizeBytes`, `pageSize` and
|
|
83
|
+
`textCoverage` (`isLikelyScanned`). Check `textCoverage.isLikelyScanned`
|
|
84
|
+
*before* searching: a scanned PDF has no text layer, so go straight to images.
|
|
85
|
+
- Search is literal: it does not unfold hyphenation and is not a regex engine.
|
|
86
|
+
- Page numbers are 1-based; relative paths resolve against the session directory.
|
|
87
|
+
- No annotation/note features: this plugin reads and renders only.
|
|
88
|
+
|
|
89
|
+
## Fallback (plugin disabled)
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
node -e "import('./lib/core/render.js').then(async m=>{const r=await m.renderPageToPng('<abs pdf>',344,{scale:2.5});require('fs').writeFileSync('/tmp/p344.png',r.buffer);console.log(r.width+'x'+r.height)})"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
then `read_image('/tmp/p344.png')`. Slower, bypasses the attachment cache —
|
|
96
|
+
prefer the tools.
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# dsh-book-reader bundle patch: mount the plugin into the active profile.
|
|
2
|
+
# Host half: pdf_info / pdf_search / pdf_read_pages tools,
|
|
3
|
+
# /dsh-book-reader/* routes, and a minimal per-turn reading-position
|
|
4
|
+
# line injected through agent/pre-step.
|
|
5
|
+
# Browser half: page readout, jump, search panel, and share-to-chat on top of
|
|
6
|
+
# the official PDF preview's document-header slot.
|
|
7
|
+
#
|
|
8
|
+
# All config keys are optional. The defaults shown are the shipped behavior.
|
|
9
|
+
- insert:
|
|
10
|
+
- id: pdf-reader
|
|
11
|
+
name: 'dsh-book-reader'
|
|
12
|
+
# config:
|
|
13
|
+
# enabled: true
|
|
14
|
+
# autoShare: true # false stops position hints
|
|
15
|
+
# autoShareSection: true # include the outline section in the line
|
|
16
|
+
# autoShareMinIntervalMs: 0 # optional: min ms between hints (0 = no time throttle)
|
|
17
|
+
# autoSharePageDelta: 1 # require a page change before another hint
|
|
18
|
+
# autoShareMaxAgeMs: 0 # 0 = no age limit on a reported position
|
|
19
|
+
# allowOutsideWorkspace: false # tools may only read inside the session cwd
|
|
20
|
+
# routeAllowedRoots: [] # extra dirs the HTTP routes may serve; [] = any
|
|
21
|
+
# maxPagesPerCall: 4 # hard cap per pdf_read_pages call
|
|
22
|
+
# defaultScale: 2.5 # ~180 DPI; never useful above ~2.7
|
|
23
|
+
# maxTextCharsPerPage: 1200 # text kept per page (0 disables)
|
|
24
|
+
# maxSearchResults: 100
|
|
25
|
+
# maxOutlineEntries: 500
|
|
26
|
+
# maxLabels: 0 # 0 = omit page labels (cheapest)
|
|
27
|
+
# outlineDepth: 1 # 0=chapters, 1=sections, 2=subsections
|
|
28
|
+
# debugCost: false # append JSON cost lines to .debug-cost.log
|
|
29
|
+
# debug: false # include error detail in HTTP 500 bodies
|
|
30
|
+
# maxFileBytes: 268435456 # 256 MiB
|
package/icon.svg
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Book Reader">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
|
|
4
|
+
<stop offset="0" stop-color="#4c6ef5"/>
|
|
5
|
+
<stop offset="1" stop-color="#364fc7"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
</defs>
|
|
8
|
+
<rect x="3" y="3" width="58" height="58" rx="14" fill="url(#bg)"/>
|
|
9
|
+
<path d="M12 21.5c6.5-3.6 13-3.6 20 0v23c-7-3.2-13.5-3.2-20 0z" fill="#f8f9fa"/>
|
|
10
|
+
<path d="M52 21.5c-6.5-3.6-13-3.6-20 0v23c7-3.2 13.5-3.2 20 0z" fill="#e9ecef"/>
|
|
11
|
+
<path d="M32 21.5v23" fill="none" stroke="#adb5bd" stroke-width="1.6" stroke-linecap="round"/>
|
|
12
|
+
<path d="M38.5 17.5h6v13l-3-2.4-3 2.4z" fill="#ffd43b"/>
|
|
13
|
+
</svg>
|