Full Code of Kenshin/simpread for AI

master d6534a7d67ab cached
137 files
1.2 MB
361.1k tokens
933 symbols
1 requests
Download .txt
Showing preview only (1,330K chars total). Download the full file or copy to clipboard to get everything.
Repository: Kenshin/simpread
Branch: master
Commit: d6534a7d67ab
Files: 137
Total size: 1.2 MB

Directory structure:
gitextract_l14w1v5n/

├── .github/
│   └── ISSUE_TEMPLATE/
│       ├── bug_report.yaml
│       ├── config.yml
│       ├── feature_request.yml
│       ├── new_site.yml
│       └── yinxiang_code.yml
├── .gitignore
├── LICENSE
├── README.md
├── ext/
│   ├── background.js
│   ├── contentscripts.js
│   └── manifest.json
├── npmw.cmd
├── package.json
├── src/
│   ├── _locales/
│   │   ├── en/
│   │   │   └── messages.json
│   │   ├── zh_CN/
│   │   │   └── messages.json
│   │   └── zh_TW/
│   │       └── messages.json
│   ├── assets/
│   │   └── css/
│   │       ├── options_custom.css
│   │       ├── options_notice.css
│   │       ├── options_page.css
│   │       ├── options_sitemgr.css
│   │       ├── setting.css
│   │       ├── simpread.css
│   │       ├── theme_common.css
│   │       ├── theme_dark.css
│   │       ├── theme_engwrite.css
│   │       ├── theme_github.css
│   │       ├── theme_gothic.css
│   │       ├── theme_mobile.css
│   │       ├── theme_monospace.css
│   │       ├── theme_newsprint.css
│   │       ├── theme_night.css
│   │       ├── theme_octopress.css
│   │       └── theme_pixyii.css
│   ├── background.js
│   ├── contentscripts.js
│   ├── focus/
│   │   ├── controlbar.jsx
│   │   └── focus.js
│   ├── ga.js
│   ├── help_tips.json
│   ├── manifest.json
│   ├── module/
│   │   ├── about.jsx
│   │   ├── account.jsx
│   │   ├── actionbar.jsx
│   │   ├── authorize.jsx
│   │   ├── common/
│   │   │   ├── editor.jsx
│   │   │   ├── exclude.jsx
│   │   │   ├── include.jsx
│   │   │   ├── name.jsx
│   │   │   ├── shortcuts.jsx
│   │   │   ├── theme.jsx
│   │   │   └── url.jsx
│   │   ├── common.jsx
│   │   ├── enhancesite.jsx
│   │   ├── feedback.jsx
│   │   ├── focus.jsx
│   │   ├── guide.jsx
│   │   ├── keyboard.js
│   │   ├── labs.jsx
│   │   ├── notice.jsx
│   │   ├── pluginbar.jsx
│   │   ├── plugins.jsx
│   │   ├── read.jsx
│   │   ├── setting.jsx
│   │   ├── sharecard.jsx
│   │   ├── sitebar.jsx
│   │   ├── siteeditor.jsx
│   │   ├── sites.jsx
│   │   ├── unrdist.jsx
│   │   ├── urlscheme.jsx
│   │   └── welcome.jsx
│   ├── options/
│   │   ├── corb.html
│   │   ├── corb.js
│   │   ├── custom.html
│   │   ├── custom.js
│   │   ├── notice.html
│   │   ├── notice.js
│   │   ├── options.html
│   │   ├── options.js
│   │   ├── sitemgr.html
│   │   └── sitemgr.js
│   ├── read/
│   │   ├── controlbar.jsx
│   │   ├── progressbar.jsx
│   │   ├── read.jsx
│   │   ├── special.jsx
│   │   └── toc.jsx
│   ├── service/
│   │   ├── browser.js
│   │   ├── config.js
│   │   ├── export.js
│   │   ├── highlight.js
│   │   ├── local.js
│   │   ├── menu.js
│   │   ├── message.js
│   │   ├── offline.js
│   │   ├── output.js
│   │   ├── permission.js
│   │   ├── runtime.js
│   │   ├── snapshot.js
│   │   ├── storage.js
│   │   ├── stylesheet.js
│   │   ├── theme.js
│   │   ├── tips.js
│   │   ├── util.js
│   │   ├── version.js
│   │   └── watch.js
│   ├── vender/
│   │   ├── carousel/
│   │   │   ├── carousel.css
│   │   │   └── carousel.js
│   │   ├── instapaper.js
│   │   ├── mduikit/
│   │   │   ├── autocomplete.jsx
│   │   │   ├── button.jsx
│   │   │   ├── dialog.jsx
│   │   │   ├── dropdown.jsx
│   │   │   ├── fab.jsx
│   │   │   ├── fap.jsx
│   │   │   ├── list.jsx
│   │   │   ├── mduikit.css
│   │   │   ├── mintooltip.css
│   │   │   ├── progress.jsx
│   │   │   ├── selectfield.jsx
│   │   │   ├── sidebar.jsx
│   │   │   ├── slider.jsx
│   │   │   ├── statebutton.jsx
│   │   │   ├── switch.jsx
│   │   │   ├── tabs.jsx
│   │   │   ├── textfield.jsx
│   │   │   ├── tooltip.jsx
│   │   │   └── waves.js
│   │   ├── notify/
│   │   │   ├── notify.css
│   │   │   └── notify.js
│   │   ├── sha1.js
│   │   ├── turndown/
│   │   │   ├── turndown-plugin-gfm.js
│   │   │   └── turndown.js
│   │   ├── waves/
│   │   │   └── waves.js
│   │   ├── webdav.js
│   │   └── wiz.js
│   └── website_list.json
├── webpack.config.ext.js
└── webpack.config.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yaml
================================================
name: 🐛 提交 Bug
description: 请提交你的 Bug
body:
  - type: markdown
    attributes:
      value: |
        谢谢帮忙提交 Bug 这会让简悦变得更好。
  - type: textarea
    id: what-happened
    attributes:
      label: 描述这个错误
      description: 请尽量详细描述你的错误
    validations:
      required: true
  - type: textarea
    id: repro-steps
    attributes:
      label: 复现步骤
      description: 请尽量用清晰的步骤(哪怕比较多)的描述你的问题,最好可以的话,请截图或者视频说明。
      placeholder: |
        1. 步骤1
        2. 步骤2
        3. 步骤3
    validations:
      required: true
  - type: textarea
    id: others
    attributes:
      label: 其他相关说明
      description: 如果有需要,可以在这里继续说明
    validations:
      required: false
  - type: input
    id: os
    attributes:
      label: 操作系统
      placeholder: macOS
    validations:
      required: true
  - type: input
    id: browser
    attributes:
      label: 浏览器
      placeholder: 请说明浏览器以及尽量说明浏览器版本
    validations:
      required: true
  - type: input
    id: website
    attributes:
      label: 发生问题的网址
      placeholder: 如果任意网站均可的话,请随便留下一个你遇到问题的地址
    validations:
      required: true


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
  - name: 🆘 当升级 Chrome 后无法使用简悦的解决方案
    url: https://www.yuque.com/kenshin/simpread/fxszlhpp1iht441s
    about: |
      当 Chrome 应用商店提示【此扩展程序未遵循 Chrome 扩展程序的最佳实践,因此已无法再使用】的解决方案
  - name: 📮 订阅中心
    url: https://simpread.pro/subscribe
    about: |
      我每周都会推 3 ~ 4 篇关于简悦的新功能、联动等内容,建议简悦用户(尤其是经常使用简悦高级功能的用户)订阅【发布汇总】。
  - name: 📚 简悦手册
    url: https://www.yuque.com/kenshin/simpread/
    about: |
      简悦的阅读模式相关功能是不需要设置的。
      如果你使用了更高级的功能,如:同步助手,或者你是 Obsidian / Logseq 等双链笔记用户,或者你本地快照等功能的话,则需要配置。
      简悦官方已经准备好了相关的教程。
  - name: 📦 配置库(强烈建议双链笔记用户使用此方式)
    url: https://www.yuque.com/kenshin/simpread/ds8zk0
    about: |
      这是简悦官方推出的免配置包方案,包括:Notion / Obsidian / Logseq 等用法。
  - name: 📗 Notion 配置库
    url: https://www.yuque.com/kenshin/simpread/mwda8s
    about: |
      通过简悦导入到 Notion 的内容包括:Notion 图床、题图、Favicon、标签等诸多功能。
  - name: 📘 Obsidian 配置库
    url: https://www.yuque.com/kenshin/simpread/psugef
    about: |
      简悦与 Obsidian 的联动可以将简悦的标注系统内置到 Obsidian 中。
  - name: 🖥 如何配置同步助手
    url: https://www.yuque.com/kenshin/simpread/pwpnsx
    about: |
      同步助手相当于一个基于用户系统的服务器,可以实现诸多高级功能(如果你只是阅读模式用户,不需要这些)
  - name: 💾 如何配置本地快照系统
    url: https://www.yuque.com/kenshin/simpread/wkswh7
    about: |
      简悦最大的优势在于:用户拥有全部的数据所有权,只需要简单的几步就能实现一个基于本地的快照系统。
  - name: 📓 一站式教程
    url: https://www.yuque.com/kenshin/simpread/pn4bbg
    about: |
      如果不需要配置库方案的话,也可以直接查看 Notion / Obsidian / Logseq 的一站式教程,适合喜欢更灵活方案的用户。
  - name: 👤 高级账户相关功能
    url: https://www.yuque.com/kenshin/simpread/xs0gp0
    about: |
      这是简悦的高级账户相关操作,基本上你出现的问题大部分都可以通过此方式解决。
  - name: 🔒 首次绑定高级账户仍出现带🔒的问题
    url: https://www.yuque.com/kenshin/simpread/xs0gp0
    about: |
      首次升级为高级账户后,请重启浏览器,如果没有重启的话,请使用此链接解决。
  - name: 1️⃣ 如何找回丢失的 UID (高级账户资格)
    url: https://www.yuque.com/kenshin/simpread/bvcunx
    about: |
      如果不小心丢失了 UID 请通过此教程找回。
  - name: 2️⃣ 找回 UID 后如何恢复高级账户资格
    url: https://www.yuque.com/kenshin/simpread/pkq3d1
    about: |
      找回 UID 后可使用此教程恢复你的高级账户资格。
  - name: 3️⃣ 在哪里可以重新找到 License(兑换码)
    url: https://www.yuque.com/kenshin/simpread/hgvw56
    about: |
      找回 UID 前需要知道你的 License,一般来说当升级高级账户后会自动下载含有高级账户 UID 与 License 到本地。
  - name: 📗 Notion 相关问题
    url: https://www.yuque.com/kenshin/simpread/wwk65u
    about: |
      如:无法授权到 Notion,使用导入到 Notion 辅助增强插件失败等常规性问题。
  - name: 🆘 无法打开简悦的选项页或稍后读
    url: https://www.yuque.com/kenshin/simpread/lwuterg3u83sq0b2
    about: |
      如:一般来说只有使用了同步助手后才会遇到此类问题,可通过此链接解决。


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.yml
================================================
name: ✨ 功能建议或改善
description: 你的建议会让简悦变得更好
body:
  - type: markdown
    attributes:
      value: |
        你的每个想法都是对简悦最大的支持,简悦 60% 的功能都来自用户的简悦。
  - type: textarea
    id: feature
    attributes:
      label: 请描述你的建议或任何内容
      description: 如有可能请详细说明它
    validations:
      required: true
  - type: textarea
    id: context
    attributes:
      label: 补充说明
      description: 如有可能请说明下这个建议具体使用场景(或如果有这个功能后,会改善你的什么流程?


================================================
FILE: .github/ISSUE_TEMPLATE/new_site.yml
================================================
name: 🔗 新站适配
description: 提交需要适配的站点
labels: ["new site"]
body:
  - type: markdown
    attributes:
      value: |
        大部分网页都可以正常使用简悦的阅读模式,简悦官方收录的新站具有大众类型的网站。
  - type: textarea
    id: website
    attributes:
      label: 需要适配的新站
      placeholder: 请输入这个站点的 URL,如果这个站的规则比较多,请多帮忙提供一些 URL 作为参考
    validations:
      required: true
  - type: textarea
    id: what-happened
    attributes:
      label: 有需要请描述这个站的性质
      description: 尤其是英文类型的网站,我需要判断这个站是否具有适配的必要。
    validations:
      required: false


================================================
FILE: .github/ISSUE_TEMPLATE/yinxiang_code.yml
================================================
name: 🚑 印象笔记或代码高亮问题
description: 关于印象笔记或代码高亮的集中反馈渠道
body:
  - type: markdown
    attributes:
      value: |
        谢谢帮忙提交 Bug 这会让简悦变得更好。
  - type: dropdown
    id: browsers
    attributes:
      label: 请选择
      multiple: false
      options:
        - 印象笔记
        - 代码高亮
  - type: input
    id: website
    attributes:
      label: 发生问题的网址
      placeholder: 如果任意网站均可的话,请随便留下一个你遇到问题的地址
    validations:
      required: true


================================================
FILE: .gitignore
================================================
# for common
node_modules/**
publish/**
.vscode/**

# for chrome
src/bundle/**

# for firefox
ext/website_list.json
ext/bundle/**
ext/focus/**
ext/read/**
ext/module/**
ext/options/**
ext/assets/**
ext/_locales/**

# for mac
**/.DS_Store


================================================
FILE: LICENSE
================================================
                    GNU GENERAL PUBLIC LICENSE
                       Version 3, 29 June 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU General Public License is a free, copyleft license for
software and other kinds of works.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.  We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors.  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights.  Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received.  You must make sure that they, too, receive
or can get the source code.  And you must show them these terms so they
know their rights.

  Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.

  For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software.  For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.

  Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so.  This is fundamentally incompatible with the aim of
protecting users' freedom to change the software.  The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable.  Therefore, we
have designed this version of the GPL to prohibit the practice for those
products.  If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.

  Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary.  To prevent this, the GPL assures that
patents cannot be used to render the program non-free.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Use with the GNU Affero General Public License.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    {one line to give the program's name and a brief idea of what it does.}
    Copyright (C) {year}  {name of author}

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:

    {simpread}  Copyright (C) {2017~2020}  {Wang lei}
    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.

  The GNU General Public License does not permit incorporating your program
into proprietary programs.  If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library.  If this is what you want to do, use the GNU Lesser General
Public License instead of this License.  But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

================================================
FILE: README.md
================================================
<p align="center"><img src="http://sr.ksria.cn/logo%20bigger.png" /></p>
<h1 align="center">简悦<sup>1.0</sup> - SimpRead</h1>
<p align="center">让你瞬间进入沉浸式阅读的扩展,还原阅读的本质,提升你的阅读体验。</p>
<p align="center">为了达到完美的阅读模式这个小目标 ,我适配了 <a target="_blank" href="https://simpread.ksria.cn/sites/">数百种类型</a> 的网站,因此诞生了简悦。</p>
<p align="center">
   <a href="https://github.com/kenshin/simpread/releases"><img src="https://img.shields.io/badge/lastest_version-2.2.0-blue.svg"></a>
   <a target="_blank" href="http://ksria.com/simpread"><img src="https://img.shields.io/badge/website-_simpread.ksria.com-1DBA90.svg"></a>
   <a target="_blank" href="https://chrome.google.com/webstore/detail/simpread-reader-view/ijllcpnolfcooahcekpamkbidhejabll"><img src="https://badgen.net/chrome-web-store/stars/ijllcpnolfcooahcekpamkbidhejabll?icon=chrome&color=0f9d58"></a>
</p>
<p align="center">
   <a target="_blank" href="https://chrome.google.com/webstore/detail/%E7%AE%80%E6%82%A6-simpread/ijllcpnolfcooahcekpamkbidhejabll"><img src="https://img.shields.io/badge/download-_chrome_webstore-brightgreen.svg"></a>
   <a href="http://ksria.com/simpread/crx/2.2.0/simpread.crx"><img src="https://img.shields.io/badge/download-_crx-0294b9.png"></a>
   <a target="_blank" href="https://greasyfork.org/zh-CN/scripts/39998"><img src="https://s1.ax1x.com/2020/07/25/UzMUSS.png"></a>
   <a target="_blank" href="https://xteko.com/redir?url=http://sr.ksria.cn/jsbox/simpread-1.0.3.box?202010231502&name=%E7%AE%80%E6%82%A6"><img src="https://s1.ax1x.com/2020/07/25/UzMHfK.png"></a>
</p>
<h1 align="center">简悦<sup>2.0</sup> - 真正成为你的生产力工具</h1>
<h3 align="center">阅读模式 + 剪藏 + 标注 + 稍后读 = 做你的知识管理粘合剂</h3>

***

## 目录

* [下载](#马上使用)

* [入门指南](#入门指南)

* [主要功能一览](#主要功能一览)

* [全部功能](#全部功能)

* [如何使用](#如何使用)

* [简悦各平台版本之间的差异](#简悦各平台版本之间的差异)

* [截图](#截图)

* [投票](#投票)

* [相关链接](#相关链接)

* [贡献者](#感谢)

* [协作开发](#协作开发)

* [开源列表](#简悦的诞生离不开它们)

* [许可](#许可)

***

## 马上使用
* [Chrome 应用商店](https://chrome.google.com/webstore/detail/%E7%AE%80%E6%82%A6-simpread/ijllcpnolfcooahcekpamkbidhejabll) 或者 [离线下载](http://ksria.com/simpread/crx/2.0.0/simpread.crx)

* [支持 UserScript 的浏览器](https://greasyfork.org/zh-CN/scripts/39998) 如:Apple Safari · Microsoft Edge · Opera · Dolphin 详细 [请看这里](https://github.com/Kenshin/simpread-little)

* [iPhone / iPad 版](https://xteko.com/redir?url=http://sr.ksria.cn/jsbox/simpread-1.0.0.box?201805251238&name=%E7%AE%80%E6%82%A6) 详细 [请看这里](http://ksria.com/simpread/docs/#/JSBox)

* [Android 版](http://ksria.com/simpread/docs/#/Android) 详细 [请看这里](http://ksria.com/simpread/docs/#/Android)

## 入门指南

* 喜欢简悦,但不会用,对新手极度舒适的 [新手入门](http://ksria.com/simpread/guide)

* 参与讨论请加入 [Telegram 群](https://t.me/simpread)

* 想知道简悦的高级玩法,请看简悦的 [文档中心](http://ksria.com/simpread/docs/#) [知识库](https://github.com/Kenshin/simpread/discussions/categories/服务) 与 [帮助中心](https://simpread.pro/help)

* 更多联系方式请看 [相关链接](#相关链接)

## 主要功能一览

#### 阅读模式

- [聚焦模式](http://ksria.com/simpread/docs/#/聚焦模式)  

  > 不改变当前页面的结构,仅仅高亮需要阅读的部分,不分散用户的注意力;适合 `临时阅读` 或者 `未适配阅读模式` 的网站

- [阅读模式](http://ksria.com/simpread/docs/#/阅读模式) ![important](https://s1.ax1x.com/2020/07/25/UzKr8O.png)

  > 简悦 **原创** 功能,逐一适配了 [数百种类型](https://simpread.ksria.cn/sites/) 的网站,自动提取 `标题` `描述` `正文` `媒体资源( 图片/ 视频 )` 等,生成 `符合中文阅读` 的页面

  * 支持 [自动生成目录](http://ksria.com/simpread/docs/#/目录)  

  * 支持 [论坛类页面及分页](http://ksria.com/simpread/docs/#/论坛类页面及分页) 如:知乎 · 百度贴吧等

  * 支持 [代码段的高亮](https://github.com/Kenshin/simpread/issues/500),包含了大部分常见的网站

  * 支持 **本地 HTML** · [TXT 阅读器](http://ksria.com/simpread/docs/#/TXT-阅读器) · 支持 [LaTeX 解析](http://ksria.com/simpread/docs/#/LaTeX-阅读器) · [Markdown 阅读器](http://ksria.com/simpread/docs/#/Markdown-阅读器) 

  * 适配了一些 [常见的科研期刊类网站](https://github.com/Kenshin/simpread/discussions/2103)

  * 更符合 `中文阅读` 习惯的设置,包括:`字间距` `行间距` 等 以及 `自定义 CSS` ,详细请看 [自定义样式](http://ksria.com/simpread/docs/#/自定义样式)

- [手动模式](http://ksria.com/simpread/docs/#/手动框选)

  > 将页面内容内容均可生成 聚焦模式 or 阅读模式

#### 丰富的导出功能 ![important](https://s1.ax1x.com/2020/07/25/UzKr8O.png)

  > 借助于简悦的阅读模式优化整理,导入到各种生产力的工具的会比其原生剪辑工具 **更具有优势**,关于这部份内容 [请看这里](http://ksria.com/simpread/docs/#/服务) 。

  - 导出 `Markdown` · `HTML` · `PNG` · [PDF](http://ksria.com/simpread/docs/#/发送到-Epub) · [Epub](http://ksria.com/simpread/docs/#/发送到-Epub) · [离线 HTML](http://ksria.com/simpread/docs/#/离线HTML) · `复制 Markdown 到剪切板` · [Textbundle](http://ksria.com/simpread/docs/#/Textbundle) · [Markdeep](http://ksria.com/simpread/docs/#/定制化导出?id=markdeep) 甚至 [任意格式均可导出](http://ksria.com/simpread/docs/#/定制化导出?id=自定义导出)

  - 发送阅读模式优化后的页面到 `Kindle`,详细配置 [请看这里](http://ksria.com/simpread/docs/#/发送到-Kindle)

  - 导出到 `Pocket` · `Instapaper` 的功能,包括:`当前页面的链接` 

  - 导出到生产力工具,包括:`语雀` · [坚果云](http://ksria.com/simpread/docs/#/坚果云) · flomo · [有道云笔记](http://ksria.com/simpread/docs/#/有道云笔记) · [专注笔记](http://ksria.com/simpread/docs/#/专注笔记) · [为知笔记](http://ksria.com/simpread/docs/#/为知笔记) · [Joplin](http://ksria.com/simpread/docs/#/Joplin) · `Dropbox` · [Github](http://ksria.com/simpread/docs/#/Github) · [Notion](http://ksria.com/simpread/docs/#/Notion) · `Onenote` · `Google Drive` · `印象笔记 / Evernote`,详细请看 [导出到生产力](http://ksria.com/simpread/docs/#/导出到生产力工具)

  - 定制化导出,可以方便导入到 Obsidian · Roam Research · Logseq 等双链笔记,更多说明及用法 [请看这里](https://github.com/Kenshin/simpread/discussions/2085)。

  - 支持 [Webhooks](http://ksria.com/simpread/docs/#/%E5%AE%9A%E5%88%B6%E5%8C%96%E5%AF%BC%E5%87%BA?id=webhook)

  - 将多种符合整合在一起的 [自动化方案](http://ksria.com/simpread/docs/#/自动化),可以理解为 **简悦的 IFTTT**。

#### 标注系统 ![new](https://s1.ax1x.com/2020/07/25/UzKubn.png) ![important](https://s1.ax1x.com/2020/07/25/UzKr8O.png)

> **[标注系统](http://ksria.com/simpread/docs/#/标注)** 是简悦 2.0 最重要的一个功能,借用此功能,可以让简悦真正你的成为生产力工具。

<img src="http://sr.ksria.cn/welcome-annoate.webp" />

> 在 1.0.0 版上线之初就已经构想了此功能,所以在构筑此功能时,加入了很多只有 **简悦 · 标注** 才具有的功能。

- 五种标注颜色

- 四种标注样式

- 自动识别 **文字** · **图片** · **代码段**

- **无限层级** 的标签系统

- 每个标签均支持备注与标签系统

- 结合简悦强大的发送到生产力工具的功能,可将当前标注发送到简悦支持的各种生产力工具

- 连续标注

- [浮动标注栏](http://ksria.com/simpread/docs/#/标注?id=浮动工具栏)

- [标注侧栏](http://ksria.com/simpread/docs/#/标注?id=标注侧栏)

> 如何使用以及详细内容 [请看这里](http://ksria.com/simpread/docs/#/标注)

#### 稍后读 ![new](https://s1.ax1x.com/2020/07/25/UzKubn.png) ![important](https://s1.ax1x.com/2020/07/25/UzKr8O.png)

> 简悦 2.0 启用了全新的 **[稍后读 2.0](http://ksria.com/simpread/docs/#/稍后读)**, 相比较之前的版本,此版本的稍后读算做是一个真正意义的稍后读。

<img src="https://s1.ax1x.com/2020/07/21/UI4Jlq.png" width="400"/> <img src="https://s1.ax1x.com/2020/07/21/UI4qnf.png" width="400"/>

> 简悦的稍后读借鉴了 ZK 笔记法的一些特点,专门针对信息的整合增加了如下一些新功能:

- [**双向链接**](http://ksria.com/simpread/docs/#/双向链接)
- [**知识图谱**](http://ksria.com/simpread/docs/#/双向链接?id=图谱)
- [**Mindmap**](http://ksria.com/simpread/docs/#/稍后读?id=Mindmap)
- **多种信息展示方式(布局)**:[Evergreen](http://ksria.com/simpread/docs/#/稍后读-多种布局?id=Evergreen) · [Workflowy](http://ksria.com/simpread/docs/#/稍后读-多种布局?id=Workflowy) · [Kanban](http://ksria.com/simpread/docs/#/稍后读-多种布局?id=Kanban)
- [**读取本地 HTML**](https://github.com/Kenshin/simpread/discussions/2146)

![知识图谱](https://z3.ax1x.com/2021/05/16/ggmmSf.gif)

![Evergree Notes](https://z3.ax1x.com/2021/05/17/g2IHyQ.gif)

#### 同步助手 ![new](https://s1.ax1x.com/2020/07/25/UzKubn.png) ![important](https://s1.ax1x.com/2020/07/25/UzKr8O.png)

![](https://z3.ax1x.com/2021/05/19/g4vN9S.png)

> [简悦 · 同步助手](http://ksria.com/simpread/docs/#/Sync) 是 **随着简悦 2.1.0 发布的一个全新的 Desktop App**,用于对简悦已知功能的补充,以及会 **持续提供更多** 的可玩性,包括:

1. **[自动同步](http://ksria.com/simpread/docs/#/自动同步)**
2. **小书签**
3. 导出到文件 **本地的任意位置**
4. **原生 PDF · Epub** 导出
5. **直接发送到你的 Kindle**
6. 内置解析
7. **邮件发送**

同步助手的 Logo 自于社区用户 [Shawn](https://shawnan.design/) 的设计。

#### 插件系统 ![important](https://s1.ax1x.com/2020/07/25/UzKr8O.png)

  > 使用 JavaScript 编写基于 `简悦` 的插件了,请看 [插件中心](https://simpread.ksria.cn/plugins/)

## 全部功能

<details>
  <img src="http://sr.ksria.cn/feature%202.0.0.png?20200723423423">
</details>

## 截图
![简单阅读,愉悦心情!](http://sr.ksria.cn/welcome-readme-1.png)

<details><summary>更多截图</summary>
  <img src="http://sr.ksria.cn/welcome-readme-2.png"/>
  <img src="http://sr.ksria.cn/welcome-readme-3.png"/>
  <img src="http://sr.ksria.cn/welcome-readme-4.png"/>

  <img src="https://s1.ax1x.com/2020/07/25/UzuGnA.png"/>
  <img src="https://s1.ax1x.com/2020/07/25/UzuY7t.png"/>
  <img src="https://s1.ax1x.com/2020/07/25/Uzul1e.png"/>
  <img src="https://s1.ax1x.com/2020/07/25/Uzu16H.png"/>
  <img src="https://s1.ax1x.com/2020/07/25/Uzu3Xd.png"/>
  <img src="https://s1.ax1x.com/2020/07/25/UzuQpD.png"/>
  <img src="https://s1.ax1x.com/2020/07/25/UzuKfO.png"/>

  <img src="https://i.loli.net/2019/06/26/5d12e86b976f450493.png"/>
  <img src="https://i.loli.net/2019/06/26/5d12e86bd9d6844696.png"/>
  <img src="https://i.loli.net/2019/06/26/5d12e86bde78615339.png"/>
  <img src="https://i.loli.net/2019/06/26/5d12e86c9468188114.png"/>
</details>

## 如何使用

> 简悦虽然拥有众多功能,但它支持 **开箱即用**,新手(不想折腾党)来说,只需要看懂下面两种操作即可。

### 阅读模式

> `简悦`会自动检测当前页面是否已经适配,如适配则在浏览器右上角显示 ![Imgur](http://i.imgur.com/dyROEBi.png) ,使用以下三种方式启动:

- 点击浏览器右上角 `红色icon`;

- 右键选择 `简悦 - SimpRead` → `阅读模式`;

- 快捷键;_默认为 双击 <kbd>A</kbd>_

- 简悦支持自动进入阅读模式,详细请看 [自动进入阅读模式](http://ksria.com/simpread/docs/#/自动进入阅读模式)

### 聚焦模式

> `聚焦模式` 会自动获取当前鼠标所在的段落并高亮,适合任意页面。

- 在需要高亮的区域,右键选择 `简悦 - SimpRead` → `聚焦模式`;

- 快捷键;_默认为 <kbd>A</kbd> <kbd>S</kbd>_

### 标注模式

> 通过鼠标按下 → 移动 的方式将会产生一个标注,更多细节 [请看这里](http://ksria.com/simpread/docs/#/标注?id=如何使用)

### 稍后读

> 在任意界面可以使用 **标注模式产生一条标注** 或 **快捷键** 方式将当前页面加入,更多细节 [请看这里](http://ksria.com/simpread/docs/#/稍后读)

- 快捷键;_默认为 <kbd>D</kbd> <kbd>D</kbd>_

## 简悦各平台版本之间的差异

> 包括:Chrome / Firefox / 轻阅版(UserScript)/ JSBox ,请访问 [简悦 · 新闻页](https://www.notion.so/9c109ec145134297ab461f5b52dbadc7?v=ce94e37d8a794cfbbd39bf9dfaf9017a)

## 投票
简悦是一个免费并开源的项目。如果觉得不错,请给我 [投票](https://chrome.google.com/webstore/detail/%E7%AE%80%E6%82%A6-simpread/ijllcpnolfcooahcekpamkbidhejabll/reviews) 。这样让更多人了解并受用与 `简悦` 带来的便利,你的认可是对我最大的鼓励。

## 相关链接
* [更新日志](http://ksria.com/simpread/changelog.html)

* [帮助中心](http://ksria.com/simpread/docs/#)

* [新手入门](http://ksria.com/simpread/guide)

* [常见问题](http://ksria.com/simpread/docs/#/FAQ)

* [反馈](https://github.com/kenshin/simpread/issues)

* [联系](http://kenshin.wang) · [邮件](kenshin@ksria.com) · [微博](http://weibo.com/23784148) · [Telegram 群](https://t.me/simpread)

## 感谢

[ksky521](https://github.com/ksky521) · [airycanon](https://github.com/airycanon) · [mikelei8291](https://github.com/mikelei8291) · [chenhbc](https://github.com/chenhbc) · [Nihility](https://github.com/NihilityT) · [WangLeto](https://github.com/WangLeto) · [SevenSteven](https://github.com/Seven-Steven) · [Leo](https://github.com/clinyong) · [Jonas · Gao](https://github.com/JonasGao) · [Cologler](https://github.com/Cologler) · [bgh](https://github.com/bldght) · [Ronglong Pu](https://github.com/PuRonglong) · [zqjimlove](https://github.com/zqjimlove) · [javalover123](https://github.com/javalover123) · [1095533987](https://github.com/1095533987)

## 协作开发

> Pull requests 方式:

* 请务必从 **develop** 分支开始;( **注意:非 develop 分支的 pr 将不会被合并** )

* Pull requests

* 如果需要合并的话,合并后我会通知你;(在下个版本发布时一起发布)

## 简悦的诞生离不开它们
<http://ksria.com/simpread/docs/#/开源列表>

## 许可

> 简悦 1.x(截至到 1.1.4.6205)是开源版本,2.x 为闭源版本,且仅闭源了 **标注** 与 **稍后读** 相关功能。

[![license-badge]][license-link]

<!-- Link -->
[www-badge]:        https://img.shields.io/badge/website-_simpread.ksria.com-1DBA90.svg
[www-link]:         http://ksria.com/simpread
[version-badge]:    https://img.shields.io/badge/lastest_version-2.0.0-blue.svg
[version-link]:     https://github.com/kenshin/simpread/releases
[chrome-badge]:     https://img.shields.io/badge/download-_chrome_webstore-brightgreen.svg
[chrome-link]:      https://chrome.google.com/webstore/detail/%E7%AE%80%E6%82%A6-simpread/ijllcpnolfcooahcekpamkbidhejabll
[offline-badge]:    https://img.shields.io/badge/download-_crx-brightgreen.svg
[offline-link]:     http://ksria.com/simpread/crx/2.0.0/simpread.crx
[license-badge]:    https://img.shields.io/badge/license-GPL-blue
[license-link]:     https://opensource.org/licenses/gpl-license


================================================
FILE: ext/background.js
================================================
console.log( "=== simpread background load ===" )

import local       from 'local';
import { storage } from 'storage';
import * as msg    from 'message';
import {browser}   from 'browser';
import * as ver    from 'version';
import * as menu   from 'menu';
import * as watch  from 'watch';

import PureRead    from 'puread';

/**
 * Sevice: storage Get data form chrome storage
 */
storage.Read( () => {
    storage.puread = new PureRead( storage.sites );
    if ( local.Firstload() ) {
        local.Version( ver.version );
        browser.tabs.create({ url: browser.extension.getURL( "options/options.html#firstload?ver=" + ver.version ) });
    }
    else {
       !local.Count() && storage.GetRemote( "remote", ( result, error ) => {
            if ( !error ) {
                storage.pr.Addsites( result );
                storage.Writesite( storage.pr.sites, getNewsitesHandler );
            }
        });
        ver.version != storage.version && storage.GetRemote( "local", ( result, error ) => {
            storage.pr.Addsites( result );
            storage.Writesite( storage.pr.sites, () => {
                ver.version != storage.version &&
                storage.Fix( storage.read.sites, storage.version, ver.version, storage.focus.sites );
                ver.version != storage.version && storage.Write( () => {
                        local.Version( ver.version );
                        browser.tabs.create({ url: browser.extension.getURL( "options/options.html#update?ver=" + ver.version ) });
                }, ver.Verify( storage.version, storage.simpread ) );
                getNewsitesHandler( result );
            });
        });
        // only firefox and only usage 1.1.0.3024
        //if ( ver.version == storage.version && ver.sub_ver == "3024" && !localStorage["bg-3024"] ) {
        //    browser.tabs.create({ url: browser.extension.getURL( "options/options.html#firstload?ver=" + ver.version ) });
        //    localStorage["bg-3024"] = ver.sub_ver;
        //}
    }
    menu.CreateAll();
});

/**
 * Get newsites handler
 * @param {object} count: update site cou
 */
function getNewsitesHandler( result ) {
    watch.Push( "site", true );
}

/**
 * Listen menu event handler
 */
menu.OnClicked( ( info, tab ) => {
    console.log( "background contentmenu Listener", info, tab );
    if ( info.menuItemId == "link" ) {
        info.linkUrl && browser.tabs.create({ url: info.linkUrl + "?simpread_mode=read" });
    } else if ( info.menuItemId == "list" ) {
        browser.tabs.create({ url: browser.extension.getURL( "options/options.html#later" ) });
    } else {
        if ( !tab.url.startsWith( "moz-extension://" ) ) browser.tabs.sendMessage( tab.id, msg.Add(info.menuItemId));
    }
});

/**
 * Listen runtime message, include: `shortcuts` `browser_action`
 */
browser.runtime.onMessage.addListener( function( request, sender, sendResponse ) {
    console.log( "background runtime Listener", request );
    switch ( request.type ) {
        case msg.MESSAGE_ACTION.shortcuts:
            getCurTab( { url: request.value.url }, tabs => {
                browser.tabs.sendMessage( tabs[0].id, msg.Add( msg.MESSAGE_ACTION.shortcuts ));
            });
            break;
        case msg.MESSAGE_ACTION.browser_action:
            getCurTab( { url: request.value.url }, tabs => {
                if ( tabs && tabs.length > 0 && tabs[0].url == request.value.url ) {
                    setMenuAndIcon( tabs[0].id, request.value.code );
                } else console.error( request );
            });
            break;
        case msg.MESSAGE_ACTION.new_tab:
            browser.tabs.create({ url: request.value.url });
            break;
        case msg.MESSAGE_ACTION.menu:
            const { id, value } = request.value;
            // hack code refresh options menu changed, and not saved storage
            storage.option.menu[id] = value;
            value === true ? menu.Create( id ) : menu.Remove( id );
            break;
        case msg.MESSAGE_ACTION.updated:
            watch.Push( request.value.type, request.value.value );
            break;
        case msg.MESSAGE_ACTION.save_verify:
            sendResponse( watch.Lock( request.value.url ));
            break;
        case msg.MESSAGE_ACTION.auth:
            browser.tabs.create({ url: browser.extension.getURL( "options/options.html#labs?auth=" + request.value.name.toLowerCase() ) });
            break;
        case msg.MESSAGE_ACTION.update_site:
            getCurTab({ active: true, url: request.value.url }, tabs => {
                tabs.length > 0 && ( upTabId = tabs[0].id );
                browser.tabs.create({ url: browser.extension.getURL( "options/options.html#sites?update=" + encodeURI( JSON.stringify( request.value.site ))) });
            });
            break;
        case msg.MESSAGE_ACTION.save_site:
            browser.tabs.create({ url: browser.extension.getURL( "options/options.html#sites?pending=" + encodeURI( JSON.stringify( request.value ))) });
            break;
        case msg.MESSAGE_ACTION.temp_site:
            browser.tabs.create({ url: browser.extension.getURL( "options/options.html#sites?temp=" + encodeURI( JSON.stringify( request.value ))) });
            break;
        case msg.MESSAGE_ACTION.auth_success:
            getCurTab( { url: request.value.url }, tabs => {
                if ( tabs && tabs.length > 0 ) {
                    browser.tabs.remove( tabs[0].id );
                    getCurTab( { "active": true }, tabs => {
                        tabs.forEach( tab => browser.tabs.sendMessage( tab.id, msg.Add( msg.MESSAGE_ACTION.export, {type: request.value.name.toLowerCase()} )) );
                    });
                }
            });
            break;
        case msg.MESSAGE_ACTION.track:
            tracked( request.value );
            break;
        }
});

/**
 * Listen chrome tab active message, include: `tab_selected`
 */
browser.tabs.onActivated.addListener( function( active ) {
    getCurTab( { "active": true, "currentWindow": true }, tabs => {
        if ( tabs && tabs.length > 0 && tabs[0].status == "complete" ) {
            console.log( "background tabs Listener:active", active );
            if ( tabs && tabs.length > 0 && !tabs[0].url.startsWith( "moz-extension://" ) ) {
                browser.tabs.sendMessage( tabs[0].id, msg.Add( msg.MESSAGE_ACTION.tab_selected, { is_update: false } ));
            } else {
                setMenuAndIcon( tabs[0].id, -1 );
            }
        } else console.error( "onActivated.addListener error" );
    });
});

/**
 * Listen chrome tab update message, include: `tab_selected`
 */
browser.tabs.onUpdated.addListener( function( tabId, changeInfo, tab ) {
    watch.Pull( tabId );
    if ( changeInfo.status == "complete" ) {
        console.log( "background tabs Listener:update", tabId, changeInfo, tab );

        if ( tab.url.startsWith( "http://ksria.com/simpread/auth.html" )) {
            const url = tab.url.replace( "http://ksria.com/simpread/auth.html?id=", "" ),
                  id  = url.includes( "#" ) || url.includes( "&" ) ? url.substr( 0, url.search( /\S(#|&)/ ) + 1 ) : url ;
            browser.tabs.query( {}, tabs => {
                const opts = tabs.find( tab => tab.url.includes( browser.extension.getURL( "options/options.html" ) ));
                if ( opts ) {
                    browser.tabs.sendMessage( opts.id, msg.Add( msg.MESSAGE_ACTION.redirect_uri, { uri: tab.url, id } ));
                    browser.tabs.remove( tabId );
                }
            });
        } else if ( tab.url.startsWith( "https://simpread.ksria.cn/plugins/install/" )) {
            const url = tab.url.replace( "https://simpread.ksria.cn/plugins/install/", "" );
            browser.tabs.create({ url: browser.extension.getURL( "options/options.html#plugins?install=" + encodeURIComponent(url) ) });
            browser.tabs.remove( tabId );
        } else if ( tab.url.startsWith( "https://simpread.ksria.cn/sites/install/" )) {
            const url = tab.url.replace( "https://simpread.ksria.cn/sites/install/", "" );
            browser.tabs.create({ url: browser.extension.getURL( "options/options.html#sites?install=" + encodeURIComponent(url) ) });
            browser.tabs.remove( tabId );
        } else if ( tab.url == browser.runtime.getURL( "options/options.html#sites?update=success" ) ) {
            browser.tabs.remove( tabId );
            upTabId > 0 && chrome.tabs.reload( upTabId, () => { upTabId == -1; });
        } else if ( tab.url == browser.runtime.getURL( "options/options.html#sites?update=failed" ) ) {
            browser.tabs.remove( tabId );
        } else if ( tab.url == browser.runtime.getURL( "options/options.html#sites?update=complete" ) ) {
            browser.tabs.remove( tabId );
        } else if ( tab.url == browser.runtime.getURL( "options/options.html#sites?update=pending" ) ) {
            browser.tabs.remove( tabId );
            upTabId > 0 && browser.tabs.sendMessage( upTabId, msg.Add( msg.MESSAGE_ACTION.pending_site ));
            upTabId == -1;
        }

        if ( !tab.url.startsWith( "moz-extension://" ) ) {
            browser.tabs.sendMessage( tabId, msg.Add( msg.MESSAGE_ACTION.tab_selected, { is_update: true } ));
            storage.ReadAsync( ( simpread, secret, plugins ) => {
                browser.tabs.sendMessage( tabId, msg.Add( msg.MESSAGE_ACTION.storage, { simpread, secret, plugins } ));
            });
        } else {
            setMenuAndIcon( tab.id, -1 );
        }
    }
});

/**
 * Listen chrome tab remove message
 */
browser.tabs.onRemoved.addListener( tabId => watch.Pull( tabId ));

/**
 * Listen chrome page, include: `read`
 */
browser.pageAction.onClicked.addListener( function( tab ) {
    browser.tabs.sendMessage( tab.id, msg.Add( msg.MESSAGE_ACTION.browser_click ));
});

/**
 * Get current tab object
 * 
 * @param {object}   query
 * @param {function} callback
 */
function getCurTab( query, callback ) {
    if ( query.url && query.url.includes( "#" ) ) {
        browser.tabs.query( {}, tabs => callback( tabs.filter( tab => tab.url == query.url && tab.active ) ) );
    } else browser.tabs.query( query, function( tabs ) { callback( tabs ); });
}

/**
 * Set page action icon and context menu
 * 
 * @param {int} tab.id
 * @param {int} -1: disable icon;
 */
function setMenuAndIcon( id, code ) {
    let icon = "";
    if ( code == -1 ) {
        menu.Update( "tempread" );
        browser.pageAction.setTitle({ tabId: id, title: "简悦 - 当前页面未适配阅读模式,点击进入临时阅读模式"});
    } else {
        icon = "-enable";
        storage.option.menu.read === true && menu.Create( "read" );
        menu.Update( "read" );
        browser.pageAction.setTitle({ tabId: id, title: "简悦 - 当前页面已适配阅读模式"});
    }
    browser.pageAction.show( id );
    browser.pageAction.setIcon({ tabId: id, path: browser.extension.getURL( `assets/images/icon16${icon}.png` ) });
}

/**
 * Listen browser page action
 */
browser.browserAction.onClicked.addListener( () => browser.runtime.openOptionsPage() );

/**
 * Track
 * 
 * @param {object} google analytics track object
 */
function tracked({ eventCategory, eventAction, eventLabel }) {
    console.log( "current track is", eventCategory, eventAction, eventLabel )
    ga( 'send', {
        hitType      : 'event',
        eventCategory,
        eventAction,
        eventLabel
    });
}

/**
 * Google analytics
 */
analytics();
function analytics() {
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
    ga('create', 'UA-405976-12', 'auto');
    ga('send', 'pageview');
}

================================================
FILE: ext/contentscripts.js
================================================
console.log( "=== simpread contentscripts load ===" )

import './assets/css/simpread.css';
import './assets/css/option.css';
import 'notify_css';

import Velocity  from 'velocity';
import Notify    from 'notify';

import {focus}   from 'focus';
import * as read from 'read';
import * as modals from 'modals';
import * as kbd  from 'keyboard';

import * as util from 'util';
import { storage, STORAGE_MODE as mode } from 'storage';
import * as msg  from 'message';
import {browser} from 'browser';
import * as watch from 'watch';

import PureRead  from 'puread';
import * as puplugin from 'puplugin';

let pr,                           // pure read object
    is_blacklist = false,
    storage_load = false,         // only usage firefox on windows
    current_url  = location.href; // current page url ( when changed page changed )

$.fn.sreffect = $.fn.velocity == undefined ? $.fn.animate : $.fn.velocity; // hack code for firefox

/**
 * Sevice: storage Get data form chrome storage
 */
/*
storage.Read( () => {
    if ( blacklist() ) {
        $( "style" ).map( ( idx, item ) => {
            if ( item.innerText.includes( "simpread"        ) || 
                 item.innerText.includes( "sr-opt-focus"    ) || 
                 item.innerText.includes( "sr-rd-theme"     ) || 
                 item.innerText.includes( "notify-gp"       ) || 
                 item.innerText.includes( "md-waves-effect" )
            ) {
                $(item).remove();
            }
        });
    } else {
        bindShortcuts();
        autoOpen();
    }
});
*/

/**
 * Blacklist
 * 
 * @return {boolean} true: is blacklist; false: is't blacklist
 */
function blacklist() {
    for ( const item of storage.option.blacklist ) {
        if ( !item.startsWith( "http" ) ) {
            if ( location.hostname.includes( item ) ) {
                is_blacklist = true;
                break;
            }
        } else {
            if ( location.href == item ) {
                is_blacklist = true;
                break;
            }
        }
    }
    console.log( "current site is blacklist", is_blacklist )
    return is_blacklist;
}

/**
 * Listen runtime message, include: `focus` `read` `shortcuts` `tab_selected`
 */
browser.runtime.onMessage.addListener( function( request, sender, sendResponse ) {
    console.log( "contentscripts runtime Listener", request );
    if ( is_blacklist ) return;
    switch ( request.type ) {
        case msg.MESSAGE_ACTION.focus_mode:
            if ( storage.option.br_exit ) focus.Exist( false ) ? focus.Exit() : focusMode();
            else focusMode();
            break;
        case msg.MESSAGE_ACTION.shortcuts:
            bindShortcuts();
            break;
        case msg.MESSAGE_ACTION.tab_selected:
            browserAction( request.value.is_update );
            break;
        case msg.MESSAGE_ACTION.read_mode:
        case msg.MESSAGE_ACTION.browser_click:
            watch.Verify( ( state, result ) => {
                if ( state ) {
                    console.log( "watch.Lock()", result );
                    new Notify().Render( "配置文件已更新,刷新当前页面后才能生效。", "刷新", ()=>window.location.reload() );
                } else {
                     if ( storage.option.br_exit ) {
                        modals.Exist()  && modals.Exit();
                        !modals.Exist() && read.Exist( false ) ? read.Exit() : readMode();
                     }
                     else readMode();
                }
            });
            break;
        case msg.MESSAGE_ACTION.storage:
            if ( storage_load ) return;
            storage.WriteAsync( request.value.simpread, request.value.secret, request.value.plugins );
            if ( blacklist() ) {
                $( "style" ).map( ( idx, item ) => {
                    if ( item.innerText.includes( "simpread"        ) || 
                         item.innerText.includes( "sr-opt-focus"    ) || 
                         item.innerText.includes( "sr-rd-theme"     ) || 
                         item.innerText.includes( "notify-gp"       ) || 
                         item.innerText.includes( "md-waves-effect" )
                    ) {
                        $(item).remove();
                    }
                });
            } else {
                bindShortcuts();
                autoOpen();
            }
            browserAction( false );
            storage_load = true;
            break;
        case msg.MESSAGE_ACTION.pending_site:
            new Notify().Render({ content: "是否提交,以便更好的适配此页面?", action: "是的", cancel: "取消", callback: type => {
                if ( type == "cancel" ) return;
                browser.runtime.sendMessage( msg.Add( msg.MESSAGE_ACTION.save_site, { url: location.href, site: storage.pr.current.site, uid: storage.user.uid, type: "failed" }));
            }});
            localStorage.removeItem( "sr-update-site" );
            break;
    }
});

/**
 * Keyboard event handler
 */
function bindShortcuts() {
    kbd.Bind( [ storage.focus.shortcuts.toLowerCase() ], focusMode );
    kbd.Bind( [ storage.read.shortcuts.toLowerCase()  ], readMode  );
    kbd.ListenESC( combo => {
        if ( combo == "esc" && storage.option.esc ) {
            modals.Exist()  && modals.Exit();
            !modals.Exist() && focus.Exist() && focus.Exit();
            !modals.Exist() && read.Exist()  && read.Exit();
        }
    });
}

/**
 * Focus mode
 */
function focusMode() {
    console.log( "=== simpread focus mode active ===" )

    if ( !entry( focus, read, "阅读", "聚焦" )) return;

    watch.Verify( ( state, result ) => {
        if ( state ) {
            console.log( "watch.Lock()", result );
            new Notify().Render( "配置文件已更新,刷新当前页面后才能生效。", "刷新", ()=>window.location.reload() );
        } else {
            getCurrent( mode.focus );
            if ( storage.current.site.name.startsWith( "txtread:" ) ) {
                new Notify().Render( "当前为 <a href='http://ksria.com/simpread/docs/#/TXT-阅读器' target='_blank'>TXT 阅读器模式</a>,并不能使用设定功能。" )
                return;
            }
            if ( pr.state == "temp" && pr.dom ) {
                focus.Render( $(pr.dom), storage.current.bgcolor );
            } else {
                focus.GetFocus( pr.Include(), storage.current.site.include ).done( result => {
                    storage.pr.state == "none" && pr.TempMode( mode.focus, result[0] );
                    focus.Render( result, storage.current.bgcolor );
                }).fail( () => {
                    new Notify().Render( 2, "当前并未获取任何正文,请重新选取。" );
                });
            }
        }
    });
}

/**
 * Read mode
 */
function readMode() {
    console.log( "=== simpread read mode active ===" )

    if ( !entry( read, focus, "聚焦", "阅读" )) return;

    watch.Verify( ( state, result ) => {
        if ( state ) {
            console.log( "watch.Lock()", result );
            new Notify().Render( "配置文件已更新,刷新当前页面后才能生效。", "刷新", ()=>window.location.reload() );
        } else {
            getCurrent( mode.read );
            if ( storage.current.site.name != "" ) {
                read.Render();
            } else if ( pr.state == "temp" && pr.dom ) {
                read.Render();
            } else {
                new Notify().Render( "当前并未适配阅读模式,请移动鼠标手动生成 <a href='http://ksria.com/simpread/docs/#/临时阅读模式' target='_blank' >临时阅读模式</a>。" );
                read.Highlight().done( dom => {
                    pr.TempMode( mode.read, dom );
                    read.Render();
                });
            }
        }
    });
}

/**
 * Auto open read mode
 */
function autoOpen() {
    getCurrent( mode.read );
    if   ( window.location.href.includes( "simpread_mode=read"     ) ||
         ( storage.current.auto && util.Exclusion(  puplugin.Plugin( "minimatch" ), storage.current )) ||
         ( !storage.current.auto && util.Whitelist( puplugin.Plugin( "minimatch" ), storage.current ))
        ) {
        switch ( storage.current.site.name ) {
            case "my.oschina.net":
            case "36kr.com":
            case "chiphell.com":
            case "question.zhihu.com":
                $( () => readMode() );
                break;
            case "post.juejin.im":
            case "entry.juejin.im":
                setTimeout( ()=>readMode(), 2500 );
                break;
            case "kancloud.cn":
            case "sspai.com":
                setTimeout( ()=>readMode(), 1000 );
                break;
            default:
                pr.state == "adapter" && readMode();
                break;
        }
    }
}

/**
 * Focus and Read mode entry
 * 
 * @param  {object}  current mode object
 * @param  {object}  other   mode object
 * @param  {array}   render str
 * @return {boolean} true:continue; false: return
 */
function entry( current, other, ...str ) {
    if ( other.Exist(false) ) {
        new Notify().Render( `请先退出${str[0]}模式,才能进入${str[1]}模式。` );
        return false;
    }
    if ( current.Exist(true) ) return false;
    return true;
}

/**
 * Get storage.current
 * 
 * @param {string} value is mode.focus or mode.read or undefined
 */
function getCurrent( mode ) {
    if ( mode && storage.VerifyCur( mode ) ) {
        ( !pr || !pr.Exist() ) && pRead();
        storage.Getcur( mode, pr.current.site );
    }
}

/**
 * Browser action
 * 
 * @param {boolean} when set icon is_update = true
 */
function browserAction( is_update ) {
    if ( is_update && current_url != location.href ) {
        current_url = location.href;
        autoOpen();
    }
    browser.runtime.sendMessage( msg.Add( msg.MESSAGE_ACTION.browser_action, { code: storage.current.site.name == "" ? -1 : 0 , url: window.location.href } ));
}

/** 
 * Pure Read
*/
function pRead() {
    pr = new PureRead( storage.sites );
    pr.AddPlugin( puplugin.Plugin() );
    pr.Getsites();
    storage.puread = pr;
    console.log( "current puread object is   ", pr )
}


================================================
FILE: ext/manifest.json
================================================
{
  "name"            : "__MSG_extension_name__",
  "default_locale"  : "zh_CN",
  "version"         : "1.1.2.1025",
  "short_name"      : "SimpRead",
  "description"     : "__MSG_ext_extension_desc__",
  "homepage_url"    : "http://ksria.com/simpread",
  "author"          : "Kenshin Wang <kenshin@ksria.com>",
  "icons" : {
    "16"            : "assets/images/icon16.png",
    "48"            : "assets/images/icon48.png",
    "128"           : "assets/images/icon128.png"
  },
  "permissions"     : [
    "contextMenus",
    "tabs",
    "storage",
    "downloads",
    "<all_urls>"
  ],
  "background": {
    "scripts"       : [ "/bundle/common.js", "/bundle/background.js" ]
  },
  "content_scripts" : [
    {
      "matches"     : [ "http://*/*", "https://*/*", "file:///*/*.txt" ],
      "exclude_matches": [ "http://localhost/*", "https://simpread.herokuapp.com/view/*" ],
      "js"          : [
        "/bundle/common.js",
        "/bundle/vendors.js",
        "/bundle/contentscripts.js"
       ],
      "run_at"      : "document_end"
    }
  ],
  "browser_action"  : {
    "browser_style" : true,
    "default_title" : "简悦 - 打开选项页",
    "default_icon"  : {
      "16"          : "assets/images/icon48.png"
    }
  },
  "page_action"     : {
    "browser_style" : true,
    "default_icon"  : {
      "16"          : "assets/images/icon16.png"
    }
  },
  "options_ui": {
    "page": "options/options.html",
    "open_in_tab": true
  },
  "web_accessible_resources": [
    "/assets/images/*",
    "website_list.json"
  ],
  "content_security_policy" : "script-src 'self' https://www.google-analytics.com; object-src 'self'",
  "manifest_version": 2
}


================================================
FILE: npmw.cmd
================================================
::===========================================================
:: SimpRead : SimpRead development/publish environment
:: HOST     : https://github.com/kenshin/simpread
:: Author   : Kenshin<kenshin@ksria.com>
:: Version  : 0.0.1
::===========================================================

@echo off

::===========================================================
:: Initialize
::===========================================================
if "%1" == "run" (
    if "%2" == "develop" (
         goto develop
    ) else if "%2" == "publish"  (
        goto publish
    ) else (
        @echo npmw noly support command: `npmw run develop` and `npmw run publish`.
        goto quit
    )
) else (
    @echo npmw noly support command: `npmw run develop` and `npmw run publish`.
    goto quit
)

::===========================================================
:: develop : Development environment
::===========================================================
:develop
@echo webpack --devtool=source-map --progress --colors --watch
set NODE_ENV=development
webpack --devtool=source-map --progress --colors --watch
goto quit

::===========================================================
:: publish : Production environment
::===========================================================
:publish
@echo webpack -p --progress --colors
set NODE_ENV=production
webpack -p --progress --colors
goto quit

::===========================================================
:: quit : Quit batch script.
::===========================================================
:quit
@echo npmw batch quit.
exit /b 0


================================================
FILE: package.json
================================================
{
  "name": "simpread_project_workflow",
  "version": "1.0.0",
  "description": "SimpRead develop/deploy",
  "author": "Kenshin Wang <kenshin@ksria.com>",
  "license": "MIT",
  "homepage": "http://ksria.com/simpread",
  "repository": {
    "type": "git",
    "url": "git://github.com/kenshin/simpread.git"
  },
  "bugs": {
    "url": "https://github.com/kenshin/simpread/issues",
    "email": "kenshin@ksria.com"
  },
  "engines": {
    "node": ">= 0.10.0"
  },
  "scripts": {
    "develop": "cross-env NODE_ENV=development webpack --devtool=eval-source-map --progress --colors --watch",
    "publish": "cross-env NODE_ENV=production  webpack -p --progress --colors",
    "ext_dev": "cross-env NODE_ENV=development webpack --devtool=source-map --progress --colors --watch --config webpack.config.ext.js",
    "ext_pub": "cross-env NODE_ENV=production  webpack -p --progress --color --config webpack.config.ext.js",
    "server": "webpack-dev-server --hot --progress --colors"
  },
  "devDependencies": {
    "autoprefixer": "^6.7.7",
    "babel-core": "^6.21.0",
    "babel-loader": "^6.2.10",
    "babel-polyfill": "^6.20.0",
    "babel-preset-es2015": "^6.18.0",
    "babel-preset-react": "^6.16.0",
    "babel-preset-stage-0": "^6.16.0",
    "cross-env": "^5.1.4",
    "css-loader": "^0.26.1",
    "epub-press-js": "^0.5.2",
    "expose-loader": "^0.7.1",
    "file-loader": "^0.9.0",
    "minimatch": "^3.0.4",
    "nanoid": "1.0.3",
    "postcss-cssnext": "^2.10.0",
    "postcss-loader": "^1.3.3",
    "react": "^0.14.8",
    "react-dom": "^0.14.8",
    "style-loader": "^0.13.1",
    "to-markdown": "^3.0.4",
    "url-loader": "^0.5.7",
    "webpack": "^1.14.0",
    "webpack-dev-server": "^1.16.2"
  },
  "dependencies": {
    "clean-webpack-plugin": "^0.1.14",
    "copy-webpack-plugin": "^4.0.1"
  }
}


================================================
FILE: src/_locales/en/messages.json
================================================
{
    "extension_name": {
        "message": "SimpRead - Reader View",
        "description": "similar to Safari reading mode, read mode, reader view module, named simpread."
    },

    "extension_desc": {
        "message": "Immersion-reading mode of Chrome extensions, similar to Safari read mode.",
        "description": "similar to Safari reading mode, read mode, reader view module, named simpread."
    },

    "ext_extension_desc": {
        "message": "Immersion-reading mode of extensions, similar to Safari read mode.",
        "description": "similar to Safari reading mode, read mode, reader view module, named simpread."
    }

}

================================================
FILE: src/_locales/zh_CN/messages.json
================================================
{
    "extension_name": {
        "message": "简悦 - SimpRead",
        "description": "类似 Safari 阅读模式的 Chrome 扩展,阅读模式,阅读器,阅读,命名为 简悦,即:简单阅读,愉悦心情之意。"
    },

    "extension_desc": {
        "message": "让你瞬间进入沉浸式阅读的 Chrome 扩展,类似 Safari 的阅读模式。",
        "description": "类似 Safari 阅读模式的 Chrome 扩展,阅读模式,阅读器,阅读,命名为 简悦,即:简单阅读,愉悦心情之意。"
    },

    "ext_extension_desc": {
        "message": "让你瞬间进入沉浸式阅读的扩展,Chrome 好评率超过 99% 的阅读模式现已来到 Firefox。",
        "description": "类似 Safari 阅读模式的扩展,阅读模式,阅读器,阅读,命名为 简悦,即:简单阅读,愉悦心情之意。"
    }

}

================================================
FILE: src/_locales/zh_TW/messages.json
================================================
{
    "extension_name": {
        "message": "簡悅 - SimpRead",
        "description": "類似 Safari 閱讀模式的 Chrome 擴展,閱讀模式,閱讀器,閱讀,命名為 簡悅,即:簡單閱讀,愉悅心情之意。"
    },

    "extension_desc": {
        "message": "讓你瞬間進入沉浸式閱讀的 Chrome 擴展,提供與 Safari 類似的 read mode。",
        "description": "類似 Safari 閱讀模式的 Chrome 擴展,閱讀模式,閱讀器,閱讀,命名為 簡悅,即:簡單閱讀,愉悅心情之意。"
    },

    "ext_extension_desc": {
        "message": "讓你瞬間進入沉浸式閱讀的擴展,Chrome 好評率超過 99% 的閱讀模式現已來到 Firefox。",
        "description": "類似 Safari 閱讀模式的擴展,閱讀模式,閱讀器,閱讀,命名為 簡悅,即:簡單閱讀,愉悅心情之意。"
    }

}

================================================
FILE: src/assets/css/options_custom.css
================================================

.header {
    background-color: rgb(63, 81, 181);
    opacity: 1;
    visibility: visible;
}

.custom {
    position: relative;

    display: flex;
    flex-flow: row;

    top: 65px;
}

.custom .property {
    margin: 20px;
    width: 450px;
}

.custom .property h1 {
    margin-bottom: 20px;
    font-size: 17px;
}

.custom .property group {
    display: block;
}

.custom .property group:not(:last-child) {
    margin-bottom: 25px;
}

.custom .preview {
    display: flex;
    justify-content: center;

    margin: 20px 20px 0 0;
    width: 100%;

    box-shadow: 0 2px 5px rgba(0, 0, 0, .26);
}

================================================
FILE: src/assets/css/options_notice.css
================================================
.header {
    background-color: #16666f;
    opacity: 1;
    visibility: visible;
}

.notice {
    margin-top: 65px;
    width: 100%;
}

.notice notice {
    display: flex;
    flex-direction: row;

    width: 100%;
}

notice .loading,
notice .failed {
    position: fixed;

    top: 0;
    left: 0;

    display: flex;
    justify-content: center;
    align-items: center;

    width: 100%;
    height: 100%;

    background-color: #fff;
}

notice .loading svg {
    transform: scale(.8);
}

notice .failed {
    flex-direction: column;
}

notice .failed span {
    color: #9b9b9b;
    font-size: 2.5rem;
}

notice .list {
    margin: 20px 20px 0;
    width: 300px;
    min-height: 589px;
}

notice .list.controlbar {
    min-height: initial;
}

notice .detail {
    display: flex;
    justify-content: center;

    margin: 20px 20px 0 0;
    padding: 39px 24px 0px;

    width: 100%;
    background-color: #fff;
    border-radius: 2px;
    box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
}

notice .detail img {
    width: 60%;
}

notice .detail .empty {
    display: flex;
    justify-content: center;
    flex-direction: column;
    align-items: center;

    padding-bottom: 39px;
    min-height: 550px;

    color: #9b9b9b;
    font-size: 2.6rem;
    font-weight: 400;
}

notice .detail .empty .icon {
    width: 80px;
    height: 80px;
    background-position: center;
    background-repeat: no-repeat;
    background-image: url( data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAQAAAD9CzEMAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAHdElNRQfhBA0LLBOn/NkLAAABtklEQVRYw+2YPyxDURTGf5WOGCwiETH7s4kaDJo2FokYMBglZ66lOtGEqWIQm9zdoJouGERIEwNlE4NE4i0iBoO0CxIMvW1f26evvJY86Tfdc3LP99137vvuTa6HqlAwzxI9X064ISrxagweE5mfOXp18CHjoCDJFHbYlBCAOiywGWzLSYmAauUIn6koI+2g/Bzb0gMMyDWoZ9pNuTQByUKLbkSyhD6PyZroYcwiN0xSoQUYJGhZ+FKjwKtlNsggeAEIFJIbnJqm7BKpSeAIgHkdjbKgRwGucgIdOrEuYXOdXKo1Fm3pF+QOQBI6Tqg3wnleb8nUVHmtRNQBQueX5AZbclmRTVFYqBcbSKpS9jtocVLcFGgK/I6AhQ/UEPHCsf09GMyU287KaBc/Xm4vF+YbBv5oDzYd8FXUWrRIQoQa+wV1hfsFmj6whTt9IPvFRv3L39Q51AR7AKzKctMHtnCnD2wE6oAbpgF4bJCA3HKbH7vcaCsSdf9ZVCrQVyfW/uIwtwdZHcXUEzuSccKt2pglpoOsfkpQPs4a0p8ROc+1KI3RAHqDdPExpIv78nPQId7plgf4BCjPbVayklPeAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTA0LTEzVDExOjQ0OjE5KzA4OjAwPYuVdQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wNC0xM1QxMTo0NDoxOSswODowMEzWLckAAAAASUVORK5CYII= );
}

notice .detail .preview {
    width: 100%;
}

notice .detail .preview .title {
    margin-bottom: 20px;

    font-family: PingFang SC,Hiragino Sans GB,Microsoft Yahei,WenQuanYi Micro Hei,sans-serif;
    font-size: 3.4rem;
    font-weight: 400;
    line-height: 1.2;

    overflow: hidden;
    text-overflow: ellipsis;
    text-rendering: optimizelegibility;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
}

notice .detail .preview .desc {
    margin-bottom: 20px;
    padding-bottom: 20px;

    border-bottom: 1px solid #E0E0E0;
}

notice .detail .preview blockquote {
    border-left: 5px solid rgb(122, 122, 122);
    color: rgb(85, 85, 85);
    margin: 0;
    padding: 0 0 0 10px;
}

notice .detail .preview pre {
    white-space: pre-wrap;
    word-wrap: break-word;
}

notice .list {
    background-color: #fff;
    border-radius: 2px;
    box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
}

notice list {
    display: flex!important;
    flex-direction: column;

    padding: 16px;
    min-height: 72px;

    border-bottom: 1px solid #E0E0E0;
    transition : all 1s cubic-bezier(0.23, 1, 0.32, 1) 0ms;
}

notice list:hover {
    background-color: #f5f5f5;
    transition : all 1s cubic-bezier(0.23, 1, 0.32, 1) 0ms;
}

notice list:hover .meta {
    opacity: 1;
}

notice list.active {
    opacity: .5;
}

notice list.selected {
    background-color: #e1f5fe;
    border-left: 4px solid #29b6f6;
}

notice list.active .title {
    text-decoration: line-through;
}

notice list .title {
    margin-bottom: 4px;
    padding-right: 25px;

    font-size: 1.5rem;
    font-weight: 500;
    text-overflow: ellipsis;
    white-space: nowrap;
    overflow: hidden;
}

notice list .category,
notice .detail .preview .category {
    margin-right: 4px;
    padding: 2px 7px;
    padding: 2px 4px;

    color: #fff;

    font-weight: 400;
    font-size: 0.8rem;
    border-radius: 2px;
}

notice list .meta {
    position: absolute;
    right: 0;
    opacity: 0;
    transition : all 1s cubic-bezier(0.23, 1, 0.32, 1) 0ms;
}

notice .date {
    color: #9e9e9e;
}

================================================
FILE: src/assets/css/options_page.css
================================================
/**
 * Options page style
 */

:root {
  --text-color: #333;
  --secondary-color: color(#333 alpha(-30%));
  --background-color: #fff;
  --width: 835px;
}

* {
    box-sizing: border-box;
}

html {
    font: 300 16px/1.8 -apple-system, PingFang SC, Microsoft Yahei, Lantinghei SC, Hiragino Sans GB, Microsoft Sans Serif, WenQuanYi Micro Hei, sans-serif;
    font-size: 62.5%;

    color: var(--text-color);
    background: var(--background-color);

    text-rendering: optimizelegibility;
    -webkit-text-size-adjust: 100%;
    -webkit-font-smoothing: antialiased;
}

body {
    margin: 0;
    padding: 0;

    background-color: #fafafa;
}

a {
    color: #4285f4;
    text-decoration: none;
}

input, textarea {
    font-family: Raleway, Menlo, "Dank Mono", Inconsolata, "Operator Mono", Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", "Courier New", Courier, monospace!important;
}

.loadingbar {
    position: fixed;
    top: 0;
    left: 0;

    display: flex;
    justify-content: center;
    align-items: center;

    height: 100%;
    width: 100%;

    background-color: #fafafa;

    z-index: 200;
}

.animated {
    animation-duration: 1s;
    animation-fill-mode: both;
    animation-iteration-count: infinite;
}

.heartBeat {
    animation-name: heartBeat;
    animation-duration: 1.3s;
    animation-timing-function: ease-in-out;
}

@keyframes heartBeat {
    0% {
        transform: scale(1);
    }

    14% {
        transform: scale(1.3);
    }

    28% {
        transform: scale(1);
    }

    42% {
        transform: scale(1.3);
    }

    70% {
        transform: scale(1);
    }
}

.topnav {
    position: fixed;
    z-index: 200;
    left: 12px;
    top: 12px;
}

.header {
    display: flex;
    align-items: center;

    position: fixed;

    top: 0;
    left: 0;

    width: 100%;
    height: 65px;

    background-color: black;

    box-shadow: 0 2px 5px rgba(0,0,0,.26);

    opacity: 0;
    transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;

    z-index: 1000;
}

.header .nav,
.header .title {
    margin-left: 12px;
}

.header .title {
    color: var(--background-color);

    height: 48px;

    font-size: 2rem;
    font-weight: 700;

    line-height: 48px;
}

.top {
    position: fixed;
    top: 0;
    left: 0;

    width: 100%;
    height: 249px;

    background-color: #2196f3;

    overflow: hidden;

    transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;
}

.main {
    position: relative;

    top: 200px;

    margin: 0 auto;
    margin-bottom: 24px;
    padding: 0;

    max-width: var(--width);
    width: var(--width);

    background-color: var(--background-color);

    text-align: center;

    border-radius: 2px;
    box-shadow: 0 0 2px rgba(0,0,0,0.12), 0 2px 2px rgba(0,0,0,0.26);
}

.tabscontainer {
    width: 100%;

    color: inherit;
}

.tabscontainer section {
    display: -webkit-flex;
    flex-direction:column;
    align-items: center;

    padding: 50px;

    overflow-y: auto;
    box-sizing: border-box;
}

.bottom {
    display: flex;
    justify-content: center;
    align-items: center;

    margin: 80px auto 0;
    padding: 200px 0 50px 0;

    max-width: var(--width);
    width: var(--width);

    color: var(--secondary-color);
    font-size: 1.3rem;

    opacity: 1;
    transition: all .25s ease-out;
}

.welcome {
    display: flex;
    justify-content: center;
    align-items: center;

    position: fixed;
    
    top: 0;
    left: 0;

    width: 100%;
    height: 100%;

    background-color: rgba( 51, 51, 51, .8 );

    z-index: 3;
}

.dividers {
    margin: 10px 0;
    width: 100%;
    border-bottom: 1px solid rgba(0,0,0,.12);
}

/**
 *  Labs style
 */
.lab {
    /*margin-bottom: 20px;*/
    padding: 10px;

    width: 100%;

    background-color: #fff;
    border-radius: 2px;

    box-shadow: 0 1px 3px rgba(0,0,0,0.12);
    /*border: 1.1px solid #e7e7e7;*/
}

.main_labs {
    background: transparent;
    box-shadow: none;
}

#labs .label {
    height: 56px;
    line-height: 56px;

    color: #616161;
    text-align: left;

    font-size: 1.5rem;
    font-weight: 700;

    /*border-bottom: 1px solid rgba(0, 0, 0, .12);*/
}

#labs .sublabel {
    display: -webkit-box;
    flex-shrink: 1;

    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;

    overflow: hidden;

    text-overflow: ellipsis;
    text-align: left;

    color: rgba( 51, 51, 51, .54 );
}

#labs .more {
    width: 100%;
    /*height: 37px;*/

    font-size: 1.4rem;
    font-weight: 400;

    text-align: left;
    /*line-height: 37px;*/

    user-select: none;
}

#labs .more .desc {
    color: #757575;
    font-size: 1rem;
}

#labs .more .arrow {
    display: block;
    position: absolute;

    right: 22px;
    bottom: 22px;

    width: 24px;
    height: 24px;
    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////ExMS2tra/v7/Dw8O8vLzCwsK5ubnCwsK6urq+vr68vLy9vb29vb28vLy9vb29vb29vb29vb29vb29vb29vb29vb2+vr6+vr69vb29vb29vb2oiyseAAAAHHRSTlMAAQ0OEBETFRYZGkpMg8rLzM7R0tPW19je4uTlotOuxwAAAAFiS0dEAf8CLd4AAAB1SURBVCjPrdLHDoAgEATQUbH33vb/v1PEEnVXT85pM48QCAC/JhloC3AOJiO9wDms8UoZdN9KEHZUuAKEPeUuOGw9h0j36nqPHVi/g19RE9y3NoNenylwcGqqfQiANFMQwbIhAz/lB0z0yHg81Hzvp/jfj7AA4P8P+rUn4dEAAAAASUVORK5CYII=);
    background-position: center;
    background-repeat: no-repeat;
}

/**
 * Plugins & sites Card
 */

cards {
    display: flex;
    flex-flow: row wrap;
}

card {
    display: flex;
    flex-direction: column;

    margin: 6px;

    width: 259px;

    color: rgba(51, 51, 51, .87);
    background-color: #fff;

    border-radius: 2px;
    box-shadow: 0 3px 1px -2px rgba(0,0,0,.2), 0 2px 2px 0 rgba(0,0,0,.14), 0 1px 5px 0 rgba(0,0,0,.12);

    transition: all .25s ease-out;
}

card:hover {
    box-shadow: 0 10px 20px 0 rgba(168,182,191,0.6);
    transform: translateY(-1px);
}

card-header {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;

    width: 100%;
    height: 196px;

    background-color: #40C4FF;
}

card-header title {
    display: block;

    font-size: 30px;
    font-weight: 500;

    line-height: 30px;
}

card-header icon {
    display: block;

    width: 100px;
    height: 100px;

    font-size: 80px;
}

card-content {
    display: flex;
    flex-direction: column;
    align-items: flex-start;

    width: 100%;
    height: 134px;

    padding: 16px;
}

card-content title {
    display: block;

    font-size: 20px;
    font-weight: 500;

    height: 32px;
    line-height: 32px;
}

card-content desc {
    display: block;

    font-size: 14px;
    font-weight: 500;

    height: 22px;
    line-height: 22px;
}

card-content note {
    display: block;

    margin-top: 16px;

    text-align: left;
    font-size: 14px;
    font-weight: 400;

    line-height: 20px;
}

card-footer {
    display: flex;
    align-items: flex-end;
    justify-content: flex-end;

    width: 100%;
    height: 52px;
}

card-footer i {
    font-size: 16px;
}

card-empty {
    width: 100%;
    padding: 50px;
}

card-empty a {
    color: #9b9b9b;

    font-size: 30px;
    font-weight: 500;
}

/**
 * Account
 */
.avatar {
    margin: 10px;
    padding: 5px;

    width: 100px;
    height: 100px;
    line-height: 80px;

    font-size: 50px;
    font-weight: bold;

    color: #fff;
    background-color: rgb(111, 122, 155);

    border-radius: 50%;
    border: 5px solid #fff;
    box-shadow: 0 10px 20px 0 rgba(168,182,191,0.6);
}

/**
 * Notice bubbles
 */
 .bubbles {
    position: fixed!important;
    bottom: 20px;

    display: flex;
    justify-content: center;
    align-content: center;

    padding: 10px;

    width: 55px;
    height: 56px;

    border-radius: 50%;

    box-shadow: 0 2px 6px 0 rgba(0,0,0,.4);

    cursor: pointer;
    transition: all 500ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;
    overflow: initial;
}

.bubbles.notice {
    right: 164px;
    background-color: #16666f;
}

.bubbles.notice:hover {
    background-color: rgba(22, 102, 111, .8);
}

.bubbles i {
    display: flex;
    justify-content: center;
    align-items: center;
}

.bubbles em {
    position: absolute;
    top: 6px;
    right: 11px;

    width: 18px;
    height: 18px;
    line-height: 18px;

    color: #fff;
    background-color: #e54545;

    font-weight: bold;
    text-align: center;
    font-style: initial;
    border-radius: 50%;
}

.bubbles em.init {
    line-height: 9px;
}

.bubbles.effect {
    animation-name: popup;
    animation-duration: 1s;
}

/**
 * Help bubbles
 */
.bubbles.help {
    right: 94px;
    background-color: #607D8B;
}

.help:hover {
    background-color: rgba(96, 125, 139, .8);
}

@keyframes popup {
    0% {
        opacity: 0;
        -webkit-transform: translateY(20px);
        transform: translateY(20px)
    }

    100% {
        opacity: 1;
        -webkit-transform: translateY(0);
        transform: translateY(0)
    }
}

@keyframes popdown {
    0% {
        opacity: 0;
        transform: translateY(-20px)
    }

    100% {
        opacity: 1;
        transform: translateY(0)
    }
}

@keyframes popclose {
    0% {
        opacity: 1;
        transform: translateY(0px)
    }

    100% {
        opacity: 0;
        transform: translateY(20px)
    }
}

/**
 * Guide
 */
.guide-bg {
    position: fixed;
    right: 10px;
    bottom: 90px;

    animation-name: popup;
    animation-duration: 1s;

    z-index: 2147483647;
}

.guide {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-content: center;

    width: 350px;
    height: 400px;

    background-color: #F5F6F6;

    border-radius: 2px;
    box-shadow: 0 0 2px rgba(0, 0, 0, .12), 0 2px 2px rgba(0, 0, 0, .26);

    overflow-x: hidden;
    overflow-y: auto;
}

.guide .title,
.guide .subtitle {
    height: 48px;
    line-height: 48px;

    color: #fff;
    background-color: #26d07c;

    font-size: 17px;
    text-align: center;

    border-top-left-radius: 2px;
    border-top-right-radius: 2px;
}

.guide .title {
    position: absolute;

    left: 0;
    right: 15px;

    display: flex;
    justify-content: center;
    font-weight: bold;

    z-index: 2;
}

.guide .title span {
    animation: .1s reverse fadein,235ms cubic-bezier(.4,0,.2,1) popdown;
}

.guide .subtitle {
    display: flex;
    justify-content: center;
    align-items: flex-start;

    margin-top: 48px;

    min-height: 55px;
    line-height: initial;

    font-size: 15px;
}

.guide .loading {
    display: flex;
    justify-content: center;
    align-items: center;

    margin-bottom: 20px;

    font-weight: 500;
    font-size: 13px;

    transition : opacity 1s cubic-bezier(0.23, 1, 0.32, 1) 0ms;
}

.guide .loading span {
    padding: 5px;
}

.guide .group {
    margin-top: -30px;
    padding: 10px;
}

guid-card {
    display: flex;

    margin-bottom: 10px;
    padding: 20px;

    width: 100%;

    background-color: #ffffff;

    border-radius: 4px;
    box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(193, 203, 212, 0.7) 0px 0px 0px 1px inset, rgb(193, 203, 212) 0px -1px 0px 0px inset;
    transition: all 550ms cubic-bezier(0.23, 1, 0.32, 1) 0s;

    cursor: pointer;
}

guid-card:hover {
    box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(193, 203, 212, 0.7) 0px 0px 0px 1px inset, rgb(193, 203, 212) 0px -1px 0px 0px inset;
    transform: translate(0px, -2px);
}

guid-card-tips span {
    margin-left: 5px;
    font-size: 14px;
    color: #0B242F;
}

.guide hr {
    margin: 0;
    border: 0;

    text-align: center;
    overflow: visible;
}

.guide hr:before {
    content: '...';

    position: relative;
    top: -10px;

    display: inline-block;

    margin-left: .6em;

    color: rgba(0,0,0,.68);

    font-family: medium-content-slab-serif-font,Georgia,Cambria,"Times New Roman",Times,serif;
    font-weight: 400;
    font-style: italic;
    font-size: 30px;
    letter-spacing: .6em;
}

/**
 * Feedback bubbles
 */
.bubbles.feedback {
    right: 24px;
    background-color: #fb7756;
}

.feedback:hover {
    background-color: rgba(251, 119, 86, .8);
}

/**
 * URL Scheme source form simpread.css
 */

.simpread-urlscheme,
.simpread-feedback {
    position: fixed;
    right: 20px;
    bottom: 20px;

    z-index: 2147483646;
}

simpread-urlscheme,
simpread-feedback {
    display: flex;
    justify-content: center;
    align-items: flex-start;
    flex-direction: column;

    padding: 20px 20px 0;

    width: 500px;

    color: rgba(51, 51, 51, .87);
    background-color: #fff;
    border-radius: 3px;

    box-shadow: rgba(0, 0, 0, 0.12) 0px 0px 2px, rgba(0, 0, 0, 0.26) 0px 2px 2px;
    overflow: hidden;

    transform-origin: bottom;
    transition: all .6s ease;
}

simpread-urlscheme *,
simpread-feedback * {
    font-size: 12px!important;
    box-sizing: border-box;
}

simpread-urlscheme.active,
simpread-feedback.active {
    animation-name: srFadeInUp;
    animation-duration: 450ms;
    animation-fill-mode: both;
}

simpread-urlscheme.hide,
simpread-feedback.hide {
    animation-name: srFadeInDown;
    animation-duration: 450ms;
    animation-fill-mode: both;
}

simpread-urlscheme sr-urls-label,
simpread-feedback sr-fb-label {
    width: 100%;
}

simpread-urlscheme sr-urls-head,
simpread-feedback sr-fb-head {
    display: flex;
    align-items: center;
    flex-direction: row;

    margin-bottom: 5px;
    width: 100%;
}

simpread-urlscheme sr-urls-content,
simpread-feedback sr-fb-content {
    margin-bottom: 5px;
    width: 100%;
}

simpread-urlscheme sr-urls-footer,
simpread-feedback sr-urls-footer {
    display: flex;
    justify-content: flex-end;
    width: 100%;
}

simpread-urlscheme sr-urls-a,
simpread-feedback sr-fb-a {
    color: #2163f7;
    cursor: pointer;
}

simpread-urlscheme text-field-state,
simpread-feedback text-field-state {
    border-top: none rgba(34, 101, 247, 0.8)!important;
    border-left: none rgba(34, 101, 247, 0.8)!important;
    border-right: none rgba(34, 101, 247, 0.8)!important;
    border-bottom: 2px solid rgba(34, 101, 247, 0.8)!important;
}

simpread-urlscheme switch,
simpread-feedback switch {
    margin-top: 0!important;
}

@keyframes srFadeInUp {
    from {
        opacity: 0;
        transform: translateY(100px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes srFadeInDown {
    from {
        opacity: 1;
        transform: translateY(0);
    }

    to {
        opacity: 0;
        transform: translateY(100px);
    }
}

/**
 * Feeback
 */

simpread-feedback sr-fb-head {
    font-weight: bold;
}

simpread-feedback sr-fb-content {
    display: flex;
    flex-direction: column;
}

simpread-feedback sr-fb-footer {
    display: flex;
    flex-direction: row;
    justify-content: flex-end;

    width: 100%;
}

/**
 * Feeback: stars
 */

simpread-feedback sr-close {
    position: absolute;
    right: 20px;
    cursor: pointer;
    transition: all 1000ms cubic-bezier(0.23, 1, 0.32, 1) 100ms;
    z-index: 200;
}

simpread-feedback sr-close:hover {
    transform: rotate(-15deg) scale(1.3);
}

simpread-feedback sr-stars {
    display: flex;
    flex-direction: row;
    justify-content: center;

    margin-top: 10px;
}

simpread-feedback sr-stars {
    display: flex;
    flex-direction: row;
    justify-content: center;

    margin-top: 10px;
}

simpread-feedback sr-stars i {
    margin-right: 10px;
    cursor: pointer;
}

simpread-feedback sr-stars i svg {
    transition: all 1000ms cubic-bezier(0.23, 1, 0.32, 1) 100ms;
}

simpread-feedback sr-stars i svg:hover {
    transform: rotate(-15deg) scale(1.3);
}

simpread-feedback sr-stars i.active svg {
    transform: rotate(0) scale(1);
}

simpread-feedback sr-emojis {
    display: block;
    height: 100px;
    overflow: hidden;
}

simpread-feedback sr-emoji {
    display: flex;
    flex-direction: column;
    align-items: center;
    transition: .3s;
}

simpread-feedback sr-emoji > svg {
    margin: 15px 0;
    width: 70px;
    height: 70px;
    flex-shrink: 0;
}

simpread-feedback sr-stars-footer {
    display: flex;
    justify-content: center;
    margin: 10px 0 20px 0;
}

================================================
FILE: src/assets/css/options_sitemgr.css
================================================

.hide {
    display: none;
}

.row {
    display: flex;
    flex-direction: row;
}

.space {
    width: 30px;
}

.box-large {
    padding-top:30px;
}

.header {
    background-color: #8BC34A;
}

.editor {
    width: 100%;
    padding-right: 20px;
}

.box {
    margin-top: 20px;
    margin-bottom: 25px;
    padding: 10px;

    width: 100%;

    background-color: #fff;

    border-radius: 2px;
    box-shadow: 0 1px 3px 0 rgba(0,0,0,.2), 0 1px 1px 0 rgba(0,0,0,.14), 0 2px 1px -1px rgba(0,0,0,.12);
}

.custom .preview {
    display: block;
    width: 100%;
    padding: 39px 24px 0px;
    background-color: #fff;
}

.custom .preview .empty {
    display: flex;
    justify-content: center;
    flex-direction: column;
    align-items: center;

    padding-top: 50px;
    min-height: 550px;

    color: #9b9b9b;
    font-size: 3.2rem;
}

.custom .preview .empty .icon {
    width: 80px;
    height: 80px;
    background-position: center;
    background-repeat: no-repeat;
    background-image: url( data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAQAAAD9CzEMAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAHdElNRQfhBA0LLBOn/NkLAAABtklEQVRYw+2YPyxDURTGf5WOGCwiETH7s4kaDJo2FokYMBglZ66lOtGEqWIQm9zdoJouGERIEwNlE4NE4i0iBoO0CxIMvW1f26evvJY86Tfdc3LP99137vvuTa6HqlAwzxI9X064ISrxagweE5mfOXp18CHjoCDJFHbYlBCAOiywGWzLSYmAauUIn6koI+2g/Bzb0gMMyDWoZ9pNuTQByUKLbkSyhD6PyZroYcwiN0xSoQUYJGhZ+FKjwKtlNsggeAEIFJIbnJqm7BKpSeAIgHkdjbKgRwGucgIdOrEuYXOdXKo1Fm3pF+QOQBI6Tqg3wnleb8nUVHmtRNQBQueX5AZbclmRTVFYqBcbSKpS9jtocVLcFGgK/I6AhQ/UEPHCsf09GMyU287KaBc/Xm4vF+YbBv5oDzYd8FXUWrRIQoQa+wV1hfsFmj6whTt9IPvFRv3L39Q51AR7AKzKctMHtnCnD2wE6oAbpgF4bJCA3HKbH7vcaCsSdf9ZVCrQVyfW/uIwtwdZHcXUEzuSccKt2pglpoOsfkpQPs4a0p8ROc+1KI3RAHqDdPExpIv78nPQId7plgf4BCjPbVayklPeAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTA0LTEzVDExOjQ0OjE5KzA4OjAwPYuVdQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wNC0xM1QxMTo0NDoxOSswODowMEzWLckAAAAASUVORK5CYII= );
}

================================================
FILE: src/assets/css/setting.css
================================================

/**
 *  Setting: Focus/Read setting dailog
*/

sr-opt-focus,
sr-opt-read {
    display: -webkit-flex;
    flex-direction:column;

    width: 100%;
}

sr-opt-gp {
    display: -webkit-flex;
    position: relative;

    flex-flow:row nowrap;
    justify-content:flex-start;

    width: 100%;
    margin-bottom: 25px;

    font-size: 15px;
}

sr-opt-gp textarea, sr-opt-gp input {
    font-family: Inconsolata, "Operator Mono", Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", "Courier New", Courier, monospace!important;
}

sr-opt-gp sr-opt-label {
    display: block;
    position: absolute;

    margin: -8px 0 0 0;

    font-size: 14px;
    font-weight: bold;

    color: rgba(0, 137, 123, .8);

    user-select: none;
    pointer-events: none;

    transform: scale(0.75) translate( 0px, -8px );
    transform-origin: left top 0px;
}

sr-opt-themes {
    display: -webkit-flex;
    flex-flow:row nowrap;
    justify-content:space-between;

    width: 100%;
    /*height: 100%;*/

    margin: 8px 0 17px;
    padding: 0;
}

sr-opt-theme {
    width: 40px;
    height: 20px;

    cursor: pointer;
    list-style: none;

    border-radius: 3px;
    border: 1px solid #212121;
    box-sizing: border-box;

    opacity: 1;
    transition: all 500ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;
}

sr-opt-theme:hover {
    transform: translateY(-1px);
    box-shadow: 0 5px 10px rgba(0,0,0,.2);
}

sr-opt-theme:not(:first-child) {
    margin-left: 5px;
}

sr-opt-theme[sr-type="active"] {
    box-shadow: 0 5px 10px rgba(0,0,0,.2);
    border: none;
}


================================================
FILE: src/assets/css/simpread.css
================================================
/**
 * SimpRead: Read mode
 */

.simpread-font {
    font: 300 16px/1.8 -apple-system, PingFang SC, Microsoft Yahei, Lantinghei SC, Hiragino Sans GB, Microsoft Sans Serif, WenQuanYi Micro Hei, sans-serif;

    color:#333;

    text-rendering: optimizelegibility;
    -webkit-text-size-adjust: 100%;
    -webkit-font-smoothing: antialiased;
}

.simpread-hidden {
    display: none;
}

/**
 *  Read: background( root ) style
 */
 .simpread-read-root {
    display: -webkit-flex;
    justify-content:center;
    align-items:center;

    position: relative;
    margin: 0;

    top: -1000px;
    left: 0;

    width: 100%;

    z-index: 2147483646;

    overflow-x: hidden;
    opacity: 0;
    transition: all 1000ms cubic-bezier(0.23, 1, 0.32, 1) 100ms;
}

.simpread-read-root-show {
    top: 0;
}

.simpread-read-root-hide {
    top: 1000px;
}

/**
 * Read: Read mode style
 */
sr-read {
    display: -webkit-flex;
    flex-flow:column nowrap;

    margin: 20px 20%;

    min-width: 400px;
    min-height: 400px;

    text-align: center;
}

read-process {
    position: fixed;

    top: 0;
    left: 0;

    height: 3px;
    width: 100%;

    background-color: #64B5F6;
    transition: width 2s;
    z-index: 20000;
}

sr-rd-content-error {
    display: block;
    position: relative;

    margin: 0px;
    margin-bottom: 30px;
    padding: 25px;

    background-color: rgba(0,0,0,0.05);
}

sr-rd-footer {
    display: flex;
    flex-direction: column;

    font-size: 14px;
}

sr-rd-footer-group {
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
}

sr-rd-footer-line {
    width: 100%;
    border-top: 1px solid #E0E0E0;
}

sr-rd-footer-text {
    min-width: 150px;
}

sr-rd-footer-copywrite {
    margin: 10px 0 0 0;
    color: inherit;
}

sr-rd-footer-copywrite abbr {
    font-variant: normal;
    text-decoration: none;
    /*border-bottom: 1px dotted;*/
}

sr-rd-footer-copywrite .second {
    margin: 10px 0;
}

sr-rd-footer-copywrite .third a:hover {
    border: none!important;
}

sr-rd-footer-copywrite .third a:first-child {
    margin-right: 50px;
}

sr-rd-footer-copywrite .sr-icon {
    display: inline-flex;
    justify-content: center;
    align-items: center;

    width: 33px;
    height: 33px;

    opacity: .8;

    transition: opacity .5s ease;
    cursor: pointer;
}

sr-rd-footer-copywrite .sr-icon:hover {
    opacity: 1;
}

sr-rd-footer-copywrite a,
sr-rd-footer-copywrite a:link,
sr-rd-footer-copywrite a:visited {
    margin: 0;
    padding: 0;

    color: inherit;
    background-color: transparent;

    font-size: inherit!important;
    line-height: initial;
    text-decoration: none;
    vertical-align: initial;

    border: none!important;
    /*border-bottom: 1px dotted!important;*/

    box-sizing: border-box;
}

sr-rd-footer-copywrite a:hover,
sr-rd-footer-copywrite a:focus,
sr-rd-footer a:active {
    color: inherit;
    text-decoration: none;
    border-bottom: 1px dotted!important;
}

/**
 * Special blocks
 */
.simpread-blocks {
    text-decoration: none!important;
}

.simpread-blocks * {
    margin: 0;
}

.simpread-blocks a {
    padding: 0;
    text-decoration: none!important;
}

.simpread-blocks img {
    margin: 0;
    padding: 0;
    border: 0;
    background: transparent;
    box-shadow: none;
}

/**
 *  Focus: Background( root ) style
 */
.simpread-focus-root {
    display: block;
    position: fixed;

    top: 0;
    left: 0;
    right: 0;
    bottom: 0;

    background-color: rgba( 235, 235, 235, 0.9 );
    z-index: 2147483645;

    opacity: 0;
    transition : opacity 1s cubic-bezier(0.23, 1, 0.32, 1) 0ms;
}

.simpread-focus-highlight {
    position: relative;

    box-shadow: 0 0 0 20px #fff;
    background-color: #fff;

    overflow: visible;
    z-index: 2147483646;
}

.sr-controlbar-bg sr-rd-crlbar {
    z-index: 2147483647;
}

.sr-controlbar-bg sr-rd-crlbar fab {
    z-index: 2147483647;
}

/**
 * Controlbar: focus mode and read mode
 */
sr-rd-crlbar.controlbar {
    position: fixed;

    right: 0;
    bottom: 0;

    width: 100px;
    height: 100%;

    opacity: 0;
    transition: opacity .5s ease;
}

sr-rd-crlbar.controlbar:hover {
    opacity: 1;
}

/**
 * Golbal
*/
@media all and ( max-height: 620px ) {

    fab {
        zoom: .8;
    }

}

@media all and ( max-height: 783px ) {

    dialog-gp dialog-content {
        max-height: 580px;
    }

    dialog-gp dialog-footer {
        border-top: 1px solid rgba(224, 224, 224, 1);
    }

}

/**
 * Highlight
 */
.simpread-highlight-selector {
    background-color: #fafafa !important;
    outline: 3px dashed #1976d2 !important;
    opacity: .8 !important;
    cursor: pointer !important;
    transition: opacity .5s ease !important;
}

.simpread-highlight-controlbar {
    position: relative !important;
    background-color: #fafafa !important;
    outline: 3px dashed #1976d2 !important;
    opacity: .8 !important;
    transition: opacity .5s ease !important;
}

simpread-highlight,
sr-snapshot-ctlbar {
    position: fixed;

    top: 0;
    left: 0;
    right: 0;

    display: flex;
    justify-content: center;
    align-items: center;

    padding: 15px;

    height: 50px;

    background-color: rgba(50, 50, 50, .9);
    box-shadow: 0 2px 5px rgba(0, 0, 0, .26);

    box-sizing: border-box;
    z-index: 2147483640;
}

sr-highlight-ctl {
    display: flex;
    justify-content: center;
    align-items: center;

    margin: 0 5px;

    width: 50px;
    height: 20px;

    color: #fff;
    background-color: #1976d2;

    border-radius: 4px;
    box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0,0,0,.12);
    cursor: pointer;
}

/**
 * TOC
 */
toc-bg {
    position: fixed;
    left: 0;
    top: 0;
    width: 50px;
    height: 200px;

    font-size: initial;
}

toc-bg:hover {
    z-index: 3;
}

.toc-bg-hidden {
    opacity: 0;
    transition: opacity .5s ease;
}

.toc-bg-hidden:hover {
    opacity: 1;
    z-index: 3;
}

.toc-bg-hidden:hover toc {
    width: 180px;
}

toc * {
    all: unset;
}

toc {
    position: fixed;
    left: 0;
    top: 100px;

    display: flex;
    flex-direction: column;
    align-items: flex-start;

    padding: 10px;

    width: 0;
    max-width: 200px;
    max-height: 500px;

    overflow-x: hidden;
    overflow-y: hidden;
    cursor: pointer;
    border: 1px solid rgba(158, 158, 158, 0.22);
    transition: width .5s;
}

toc:hover {
    overflow-y: auto;
}

toc::-webkit-scrollbar {
    width: 3px;
}

toc::-webkit-scrollbar-thumb {
    border-radius: 10px;
    background-color: rgba(139,137,134,0.5);
}


toc outline {
    position: relative;
    display: -webkit-box;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
    overflow: hidden;
    text-overflow: ellipsis;

    padding: 2px 0;
    min-height: 21px;

    line-height: 21px;
    text-align: left;
}

toc outline a,
toc outline a:active,
toc outline a:visited,
toc outline a:focus
{
    display: block;

    width: 100%;

    color: inherit;
    font-size: 11px;
    text-decoration: none!important;

    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

toc outline a:hover {
    font-weight: bold!important;
}

toc outline a.toc-outline-theme-dark,
toc outline a.toc-outline-theme-night {
    color: #fff!important;
}

.toc-level-h1 {
    padding-left: 5px;
}
.toc-level-h2 {
    padding-left: 15px;
}
.toc-level-h3 {
    padding-left: 25px;
}
.toc-level-h4 {
    padding-left: 35px;
}

.toc-outline-active {
    border-left: 2px solid rgb(244, 67, 54);
}

toc outline active {
    position: absolute;

    left: 0;
    top: 0;
    bottom: 0;

    padding: 0 0 0 3px;

    border-left: 2px solid #e8e8e8;

}

/**
 * Keyboard
 */

sr-kbd {
    background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgb(255, 247, 133)), to(rgb(255, 197, 66)));
    border-width: 1px;
    border-style: solid;
    border-color: rgb(227, 190, 35);
    border-image: initial;

    position: absolute;
    left: 0;
    padding: 1px 3px 0px;

    font-size: 11px!important;
    font-weight: bold;
    box-shadow: rgba(0, 0, 0, 0.3) 0px 3px 7px 0px;
    overflow: hidden;
    border-radius: 3px;
}

.sr-kbd-a {
    position: relative;
}

kbd-mapping {
    position: fixed;
    left: 5px;
    bottom: 5px;

    display: flex;
    flex-direction: column;
    flex-flow: row;

    width: 500px;
    height: 625px;

    background-color: #fff;

    border: 1px solid rgba(158, 158, 158, .22);
    box-shadow: 0 2px 5px rgba(0,0,0,.26);
    border-radius: 3px;
}

kbd-maps {
    display: flex;
    flex-flow: column wrap;
    margin-top: 40px;
}

kbd-mapping kbd-map-title {
    position: absolute;
    margin: 5px 0;
    width: 100%;
    font-size: 14px;
    font-weight: bold;
}

kbd-maps-group {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
}

kbd-maps-title {
    margin: 5px 0;
    padding-left: 53px;

    font-size: 12px;
    font-weight: bold;
}

kbd-map kbd {
    display: inline-block;
    padding: 3px 5px;
    font-size: 11px;
    line-height: 10px;
    color: #444d56;
    vertical-align: middle;
    background-color: #fafbfc;
    border: solid 1px #c6cbd1;
    border-bottom-color: #959da5;
    border-radius: 3px;
    box-shadow: inset 0 -1px 0 #959da5;
}

kbd-map kbd-name {
    display: inline-block;
    text-align: right;

    width: 50px;
}

kbd-map kbd-desc {
    padding-left: 3px;
}

/**
 * Share card
 */

sharecard-bg {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;

    display: flex;
    justify-content: center;
    align-items: center;

    background-color: rgba(0, 0, 0, .4);

    z-index: 2147483647;
}

sharecard {
    display: flex;
    flex-direction: column;

    max-width: 450px;

    background-color: rgb(100, 181, 246);
}

sharecard-head {
    display: flex;
    flex-direction: column;

    margin: 25px;

    color: #fff;

    border-radius: 10px;
    box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.15);
}

sharecard-card {
    display: flex;
    flex-direction: column;
}

sharecard-top {
    display: flex;
    align-items: center;
    justify-content: center;

    padding-right: 5px;

    height: 65px;
    background-color: #fff;

    color: #878787;
    font-size: 25px;
    font-weight: 500;

    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
}

sharecard-top span.logos {
    display: block;

    width: 48px;
    height: 48px;

    margin: 5px;

    background-repeat: no-repeat;
    background-position: 50%;
    background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAABU1BMVEUAAAAnNJMnNZI3Q5onNJInNJMnNJInNJMnNJI8SJ0tOZY/S55EUKAoNJI6RpwoNJNIU6InNJInNJImNJI7SJwmNJJ2fLUiMJFKVaNCTJ9faK1HUaJOWKVSXaUnNJNYY6pye7cmM5JXYKhwebMjMI8mL4719fW9vb0oNZP/UlLz8/QqN5TAwMAnNJPv7+/Pz8/q6+/p6enNzc3Kysry8vMsOJXc3env7/LU1uXo29vR0dHOzs7ExMTwjo73bW37XV3Aj1TCYELl5u3n5+fW2Obn6O7f4OrZ2+g0QJkxPpgvO5bh4uvS1OTP0ePCwsJQW6ZLVqTs7fHd3d3V1dXqv79VX6lET6A1TIxXUIBSgHxWQnpelHf+WVnopkXqbC7j5Ozi4uLDw8NGUaFATJ9SgH3r6+vGyd7BxNva2trX19ejqM2gpczHx8dze7Zha67Z2dlTgH1aXQeSAAAAJnRSTlMA6ff+497Y8NL+/fv49P379sqab/BeOiX06tzVy8m/tKqpalA7G6oKj0EAAAJlSURBVEjHndNXWxpBFIDhcS2ICRLAkt4Dx4WhLk0E6R0MYoIISrWX5P9f5cwSIRC2+T1czMV5n2FnZwn2eWONUqCAv3H2Uf5Ra1hx4+0WEXtDQW0fCPYJ1EffEfIV4CSROAE4jsePoTFsNmTJF/IeIHF2lgCIn57GodlqDWXBK7IwBYatVlMWFAildPKX7I3m74Z9fsCiQChoimoFQAz04Ad2gH1n9fv9n9hgMNDr9euLWD6fLxQKxaLfb7dTSlahbFVdEPwIQtrAihZQgyKCtCagbQe3xh0QFMgy5MR11+ewYY5/qlZ7vT2xu93ULKjbFLpiUxnIIwjgKmVTLDUFXMrAi2NJWCRLIthTBo4xyOLKpwyqU6CuDCI41hFBCVdOhyLw4FgJ1skCAiyl9BSHbCorgo6VJXTru5hrVCQS8Yr5xLzX59YJSFpVFwD9U0BGC3hGdFpATgRupTGe9R9I1b1ePBvXKDyvq/O/44LT4/E4BUbSCAwj8Evq6HlnOBprx6JhJz8Gktc7xeaP9ndY+0coQvCccFBD4JW60UIY50ciLOAODAQRVOeCHm4Q3Xks6uRDY+CQ+AR4T2wMYh6+jMCIQOp78CFoj0H7EQgIuhI3dGaHCrwgADwCPjJvA372GRigCJg49FUdk3D87pq3zp4SA5zc1Zh9DxfwkpjgUg5Mv+lbeE3McC8Lpu7SA3wk2xzcqL2tN5DfIsQC8HB7UamUy6FQOpTO5QKBQDZbKnWSyUzGjdWCwaDA8+7Le4BNgm3qQGWchYh9s5hNq6wVbBlbwhZYOp3OYOA4zmgEypnM2zj8ByIdedKrH8vDAAAAAElFTkSuQmCC");

    zoom: .8;
}

sharecard-content {
    padding: 15px;

    max-height: 500px;

    font-size: 20px;
    text-align: justify;

    background-color: rgb(33, 150, 243);

    overflow-x: hidden;
    overflow-y: auto;
}

sharecard-via {
    padding: 10px;
    font-size: 10px;

    background-color: rgb(33, 150, 243);
}

sharecard-footer {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;

    padding-right: 5px;

    height: 100px;
    background-color: #fff;

    color: #878787;
    font-size: 15px;
    font-weight: 500;

    border-bottom-left-radius: 10px;
    border-bottom-right-radius: 10px;
}

sharecard-footer div {
    display: flex;
    align-items: center;
}

sharecard-footer span.qrcode {
    display: block;

    width: 100px;
    height: 100px;

    margin: 5px;

    background-repeat: no-repeat;
    background-position: 50%;
    background-image: url("data:image/png;base64,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");
}

sharecard-control {
    display: flex;
    flex-direction: row;
    align-items: center;

    padding: 0 19px;

    height: 80px;
    background-color: #fff;
}

/**
 * Snapshot
 */

simpread-snapshot {
    position: fixed;
    left: 0;
    top: 0;

    width: 100%;
    height: 100%;

    cursor: move;
    z-index: 2147483645;
}

sr-mask {
    position: fixed;
    left: 0;
    top: 0;
    background-color: rgba(0, 0, 0, .1);
}

/**
 * URL Scheme
 */

.simpread-urlscheme,
.simpread-feedback {
    position: fixed;
    right: 20px;
    bottom: 20px;

    z-index: 2147483646;
}

simpread-urlscheme,
simpread-feedback {
    display: flex;
    justify-content: center;
    align-items: flex-start;
    flex-direction: column;

    padding: 20px 20px 0;

    width: 500px;

    color: rgba(51, 51, 51, .87);
    background-color: #fff;
    border-radius: 3px;

    box-shadow: rgba(0, 0, 0, 0.12) 0px 0px 2px, rgba(0, 0, 0, 0.26) 0px 2px 2px;
    overflow: hidden;

    transform-origin: bottom;
    transition: all .6s ease;
}

simpread-urlscheme *,
simpread-feedback * {
    font-size: 12px!important;
    box-sizing: border-box;
}

simpread-urlscheme.active,
simpread-feedback.active {
    animation-name: srFadeInUp;
    animation-duration: 450ms;
    animation-fill-mode: both;
}

simpread-urlscheme.hide,
simpread-feedback.hide {
    animation-name: srFadeInDown;
    animation-duration: 450ms;
    animation-fill-mode: both;
}

simpread-urlscheme sr-urls-label,
simpread-feedback sr-fb-label {
    width: 100%;
}

simpread-urlscheme sr-urls-head,
simpread-feedback sr-fb-head {
    display: flex;
    align-items: center;
    flex-direction: row;

    margin-bottom: 5px;
    width: 100%;
}

simpread-urlscheme sr-urls-content,
simpread-feedback sr-fb-content {
    margin-bottom: 5px;
    width: 100%;
}

simpread-urlscheme sr-urls-footer,
simpread-feedback sr-urls-footer {
    display: flex;
    justify-content: flex-end;
    width: 100%;
}

simpread-urlscheme sr-urls-a,
simpread-feedback sr-fb-a {
    color: #2163f7;
    cursor: pointer;
}

simpread-urlscheme text-field-state,
simpread-feedback text-field-state {
    border-top: none rgba(34, 101, 247, 0.8)!important;
    border-left: none rgba(34, 101, 247, 0.8)!important;
    border-right: none rgba(34, 101, 247, 0.8)!important;
    border-bottom: 2px solid rgba(34, 101, 247, 0.8)!important;
}

simpread-urlscheme switch,
simpread-feedback switch {
    margin-top: 0!important;
}

@keyframes srFadeInUp {
    from {
        opacity: 0;
        transform: translateY(100px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes srFadeInDown {
    from {
        opacity: 1;
        transform: translateY(0);
    }

    to {
        opacity: 0;
        transform: translateY(100px);
    }
}

/**
 * Feeback
 */

simpread-feedback sr-fb-head {
    font-weight: bold;
}

simpread-feedback sr-fb-content {
    display: flex;
    flex-direction: column;
}

simpread-feedback sr-fb-footer {
    display: flex;
    flex-direction: row;
    justify-content: flex-end;

    width: 100%;
}

/**
 * Feeback: stars
 */

 simpread-feedback sr-close {
    position: absolute;
    right: 20px;
    cursor: pointer;
    transition: all 1000ms cubic-bezier(0.23, 1, 0.32, 1) 100ms;
    z-index: 200;
}

simpread-feedback sr-close:hover {
    transform: rotate(-15deg) scale(1.3);
}

simpread-feedback sr-stars {
    display: flex;
    flex-direction: row;
    justify-content: center;

    margin-top: 10px;
}

simpread-feedback sr-stars {
    display: flex;
    flex-direction: row;
    justify-content: center;

    margin-top: 10px;
}

simpread-feedback sr-stars i {
    margin-right: 10px;
    cursor: pointer;
}

simpread-feedback sr-stars i svg {
    transition: all 1000ms cubic-bezier(0.23, 1, 0.32, 1) 100ms;
}

simpread-feedback sr-stars i svg:hover {
    transform: rotate(-15deg) scale(1.3);
}

simpread-feedback sr-stars i.active svg {
    transform: rotate(0) scale(1);
}

simpread-feedback sr-emojis {
    display: block;
    height: 100px;
    overflow: hidden;
}

simpread-feedback sr-emoji {
    display: flex;
    flex-direction: column;
    align-items: center;
    transition: .3s;
}

simpread-feedback sr-emoji > svg {
    margin: 15px 0;
    width: 70px;
    height: 70px;
    flex-shrink: 0;
}

simpread-feedback sr-stars-footer {
    display: flex;
    justify-content: center;
    margin: 10px 0 20px 0;
}

================================================
FILE: src/assets/css/theme_common.css
================================================
/**
 * Common style, include:
 * .simpread-theme-root
 * sr-rd-title, sr-rd-desc, sr-rd-content, p, div, a, img, pre, code, sr-blockquote, ul ol
 */
 
.simpread-theme-root {
    font-size: 62.5%!important;
}

sr-rd-title, sr-rd-desc, sr-rd-content {
    width: 100%;
}

sr-rd-title {
    display: -webkit-box;
    margin: 1em 0px 0.5em;
    overflow : hidden;
    text-overflow: ellipsis;
    text-rendering: optimizelegibility;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
}

sr-rd-content {
    text-align: left;
    word-break: break-word;
}

sr-rd-desc {
    text-align: justify;
    line-height: 2.4;
    margin: 0 0 1.2em 0;
}

sr-rd-content {
    font-size: 1.6rem;
    line-height: 1.6;
}

sr-rd-content p,
sr-rd-content div {
    display: block;
    float: inherit;
    line-height: 1.6;
    font-size: 1.6rem;
}

sr-rd-content p,
sr-rd-content div,
sr-rd-content pre,
sr-rd-content sr-blockquote {
    margin: 0 0 1.2em 0;
    word-break: break-word;
    /*
    word-wrap: break-word;
    white-space: pre-wrap;
    */
}

sr-rd-content a {
    padding: 0 5px;
    vertical-align: initial;
}

sr-rd-content a, sr-rd-content a:link {
    color: inherit;
    font-size: inherit;
    font-weight: inherit;
    border:none;
}

sr-rd-content a:hover {
    background: transparent;
}

sr-rd-content img {
    margin: 10px;
    padding: 5px;

    max-width: 100%;

    background: #fff;
    border: 1px solid #bbb;
    box-shadow: 1px 1px 3px #d4d4d4;
}

sr-rd-content figcaption {
    text-align: center;
    font-size: 14px;
}

sr-rd-content sr-blockquote {
    display: block;
    position: relative;
    padding: 15px 25px;
    text-align: left;
    line-height: inherit;
}

sr-rd-content sr-blockquote:before {
    position: absolute;
}

sr-rd-content sr-blockquote * {
    margin: 0;
    font-size: inherit;
}

sr-rd-content table {
    width: 100%;
    margin: 0 0 1.2em 0;
    word-break: keep-all;
    word-break:normal;
    overflow: auto;
    border: none;
}

sr-rd-content table th, sr-rd-content table td {
    border: none;
}

sr-rd-content ul, sr-rd-content ol {
    margin: 0;
    padding: 0;
}

sr-rd-content ul {
    margin: 0 0 1.2em 0;
    margin-left: 1.3em;
    padding: 0;
    list-style: disc;
}

sr-rd-content ol {
    list-style: decimal;
    margin-left: 1.3em;
}

sr-rd-content ul li, sr-rd-content ol li {
    font-size: inherit;
    list-style: disc;
    margin: 0 0 1.2em 0;
}

sr-rd-content ul li *, sr-rd-content ol li * {
    margin: 0;
    text-align: initial;
}

sr-rd-content li ul, sr-rd-content li ol {
    margin-bottom: 0.8em;
    margin-left: 2em;
}

sr-rd-content li ul {
    list-style: circle;
}

sr-rd-content pre {
    font-family: Consolas, Monaco, 'Andale Mono', "Source Code Pro", "Liberation Mono", Courier, monospace;

    display: block;

    padding: 15px;

    font-size: 1.1rem;
    line-height: 1.5;

    word-break: break-all;
    word-wrap: break-word;
    white-space: pre;

    overflow: auto;
}

sr-rd-content pre div {
    font-size: 1.1rem;
}

sr-rd-content pre * {
    font-size: 1.1rem;
}

sr-rd-content pre,
sr-rd-content li pre code,
sr-rd-content p pre code {
    background-color: transparent;
    border: none;
}

sr-rd-content pre code {
    margin: 0;
    padding: 0;
    font-size: 1.1rem;
}

sr-rd-content pre code * {
    font-size: 1.1rem;
}

sr-rd-content pre p {
    margin: 0;
    padding: 0;
    color: inherit;
    font-size: inherit;
    line-height: inherit;
}

sr-rd-content li code,
sr-rd-content p code {
    margin: 0 4px;
    padding: 2px 4px;
    font-size: 1.1rem;
}

sr-rd-content mark {
    margin: 0 5px;
    padding: 2px;

    background: #fffdd1;
    border-bottom: 1px solid #ffedce;
}

.sr-rd-content-img {
    width: 90%;
    height: auto;
}

.sr-rd-content-img-load {
    width: 48px;
    height: 48px;
    margin: 0;
    padding: 0;
    border-style: none;
    border-width: 0;
    background-repeat: no-repeat;
    background-image: url( "../images/loading.gif" );
}

.sr-rd-content-center {
    text-align: center;
    display: -webkit-box;
    -webkit-box-align: center;
    -webkit-box-pack: center;
    -webkit-box-orient: vertical;
}

.sr-rd-content-center-small {
    display: inline-flex;
}

.sr-rd-content-center-small img {
    margin: 0;
    padding: 0;
    border: 0;
    box-shadow: none;
}

.sr-rd-content-nobeautify {
    margin: 0;
    padding: 0;
    border: 0;
    box-shadow: 0 0 0;
}

sr-rd-mult {
    display: flex;
    flex-direction: row;

    margin: 0 0 16px 0;
    padding: 16px 0 24px;

    width: 100%;

    background-color: #fff;

    border-radius: 4px;
    box-shadow: 0px 1px 2px 0px rgba(60,64,67,0.3), 0px 2px 6px 2px rgba(60,64,67,0.15);
}

sr-rd-mult:hover {
    transition: all 450ms 0ms;
    box-shadow: 1px 1px 8px rgba(0, 0, 0, .16);
}

sr-rd-mult sr-rd-mult-content {
    display: flex;
    flex-direction: column;

    padding: 0 16px 0;
    overflow: auto;
}

sr-rd-mult sr-rd-mult-avatar {
    display: flex;
    flex-direction: column;
    align-items: center;

    margin: 0 15px;
}

sr-rd-mult sr-rd-mult-avatar span {
    display: -webkit-box;

    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;

    max-width: 75px;

    overflow: hidden;
    text-overflow: ellipsis;
    text-align: left;

    font-size: 1rem;
}

sr-rd-mult sr-rd-mult-avatar img {
    margin-bottom: 0;

    max-width: 50px;
    max-height: 50px;
    width: 50px;
    height: 50px;

    border-radius: 50%;
}

sr-rd-mult sr-rd-mult-avatar .sr-rd-content-center {
    margin: 0;
}

sr-page {
    display: flex;
    flex-direction: row;
    justify-content: space-between;

    width: 100%;
}

================================================
FILE: src/assets/css/theme_dark.css
================================================
sr-rd-theme-dark{display:none;}

/**
 * Dark style
 */

/**
 * Common style, include: h1 ~ h6; ol ul; code pre; table; sr-blockquote
 */

sr-rd-content h1,sr-rd-content h2,sr-rd-content h3,sr-rd-content h4,sr-rd-content h5,sr-rd-content h6{font-weight:700;color:#dbdbfd}sr-rd-content h1{font-size:3rem}sr-rd-content h2{font-size:2.8rem}sr-rd-content h3{font-size:2.5rem}sr-rd-content h4,sr-rd-content h5,sr-rd-content h6{color:#549ad8}sr-rd-content h5{font-size:2rem}sr-rd-content h6{font-size:1.8rem}
sr-rd-content strong {color: #ffffc5;} sr-rd-content em {color: #c885f5;}
sr-rd-content table{width:100%;line-height:1.6rem;border-collapse:collapse;border-spacing:0;empty-cells:show;border:1px solid #cbcbcb}sr-rd-content thead{background-color:#263238;color:#f5f5f5;text-align:left;vertical-align:bottom}sr-rd-content table td,sr-rd-content table th{border-left:1px solid #cbcbcb;border-width:0 0 0 1px;margin:0;overflow:visible;padding:.5em 1em}
sr-rd-content sr-blockquote {
    background-color: rgba(128, 128, 128, 0.05);
    border-top-right-radius: 5px;
    border-bottom-right-radius: 5px;
    border-left: 8px solid #979797;
    color: rgb(235, 235, 235);
}

/**
 * Custom style, include: background; title; desc; sr-rd-content; p,div; a; pre
 */

.simpread-theme-root, .simpread-multi-root {
    color: rgb(235, 235, 235);
    background: rgb(34, 34, 34);
}

sr-rd-title {
    padding-bottom: .3em;
    font-size: 2.8rem;
    font-weight: bold;
    line-height: 1.2;
    color: #dbdbfd;
    border-bottom: 1px solid #eee;
}

sr-rd-desc {
    margin: 20px;
    margin-left: 0;
    padding: 5px 20px;
    font-size: 1.8rem;
    background-color: rgba(128, 128, 128, 0.05);
    color: rgb(235, 235, 235);
    border-top-right-radius: 5px;
    border-bottom-right-radius: 5px;
    border-left: 8px solid #979797;
}

sr-rd-content {
    line-height: 1.7;
    color: rgb(235, 235, 235);
}

sr-rd-content *,
sr-rd-content p,
sr-rd-content div {
    color: rgb(235, 235, 235);
    line-height: 1.7;
}

sr-rd-content a,
sr-rd-content a:link {
    color: #8ac9ff;
    text-decoration: underline;
}

sr-rd-content a:hover,
sr-rd-content a:focus,
sr-rd-content a:active {
    background-color: #2a6496;
    color: white;
    text-decoration: none;
}

sr-rd-content pre {
    color: #e9eded;
    background-color: #263238;
}

sr-rd-content li code,
sr-rd-content p code {
    color: #caca16;
    background-color: transparent;
}

/**
 * Multiple page
 */
sr-rd-mult {
    background-color: rgba(128, 128, 128, 0.1);
}

================================================
FILE: src/assets/css/theme_engwrite.css
================================================
sr-rd-theme-engwrite{display:none;}

/**
 * EngWrite style
 */

/**
 * Common style, include: h1 ~ h6; ol ul; code pre; table; sr-blockquote
 */

sr-rd-content h1,sr-rd-content h2,sr-rd-content h3,sr-rd-content h4,sr-rd-content h5,sr-rd-content h6{margin:20px 0 10px;padding:0;font-weight:500;-webkit-font-smoothing:antialiased}sr-rd-content h1{font-weight:300;text-align:center;font-size:2.8rem;color:#933d3f}sr-rd-content h2{font-size:2.4rem;border-bottom:1px solid #ccc;color:#000}sr-rd-content h3{font-size:1.8rem}sr-rd-content h4,sr-rd-content h5{font-size:1.6rem}sr-rd-content h6{color:#777;font-size:1.6rem}
sr-rd-content ul,sr-rd-content ol{padding-left:30px}sr-rd-content ul li>:first-child,sr-rd-content ol li>:first-child,sr-rd-content ul li ul:first-of-type,sr-rd-content ol li ol:first-of-type,sr-rd-content ul li ol:first-of-type,sr-rd-content ol li ul:first-of-type{margin-top:0}sr-rd-content ul ul,sr-rd-content ul ol,sr-rd-content ol ol,sr-rd-content ol ul{margin-bottom:0}
sr-rd-content table th{font-weight:bold}sr-rd-content table th,sr-rd-content table td{border:1px solid #ccc;padding:6px 13px}sr-rd-content table tr{border-top:1px solid #ccc;background-color:#fff}sr-rd-content table tr:nth-child(2n){background-color:#f8f8f8}
sr-rd-content sr-blockquote {
    text-align: left;
    border-top: 1px dotted #cdc7bc;
    border-bottom: 1px dotted #cdc7bc;
    background-color: #f8edda;
    color: #777
}

sr-blockquote >:first-child {
    margin-top: 0
}

sr-blockquote >:last-child {
    margin-bottom: 0
}

/**
 * Custom style, include: background; title; desc; sr-rd-content; p,div; a; pre
 */

.simpread-theme-root, .simpread-multi-root {
    background-color: rgb(252, 245, 237);
    color: rgb(51, 51, 51);
}

sr-rd-title {
    font-weight: 300;
    text-align: center;
    font-size: 2.8rem;
    color: rgb(147, 61, 63);
}

sr-rd-desc {
    padding: 10px;
    background-color: rgb(248, 237, 218);
    color: rgb(119, 119, 119);
    font-size: 2rem;
    text-align: center;
    border-top: 1px dotted rgb(205, 199, 188);
    border-bottom: 1px dotted rgb(205, 199, 188);
}

sr-rd-content {
    color: rgb(51, 51, 51);
    padding: 20px 0;
    margin: 0px auto;
    line-height: 1.8;
}

sr-rd-content *,
sr-rd-content p,
sr-rd-content div {
    color: rgb(51, 51, 51);
    line-height: 1.8;
}

sr-rd-content a,
sr-rd-content a:link {
    color: rgb(174, 55, 55);
    text-decoration: none;
}

sr-rd-content a:hover,
sr-rd-content a:focus,
sr-rd-content a:active {
    text-decoration: underline;
}

sr-rd-content pre {
    background-color: transparent;
    border: 1px solid rgb(204, 204, 204);
    border-radius: 3px;
}

sr-rd-content li code,
sr-rd-content p code {
    border: 1px solid rgb(234, 234, 234);
    background-color: rgb(244, 236, 227);
    border-radius: 3px;
}

/**
 * Multiple page
 */
sr-rd-mult {
    background-color: rgb(248, 237, 218);
}

================================================
FILE: src/assets/css/theme_github.css
================================================
sr-rd-theme-github{display:none;}

/**
 * Github style
 */

/**
 * Common style, include: h1 ~ h6; ol ul; code pre; table; sr-blockquote
 */

sr-rd-content h1,sr-rd-content h2,sr-rd-content h3,sr-rd-content h4,sr-rd-content h5,sr-rd-content h6{position:relative;margin-top:1em;margin-bottom:1pc;font-weight:700;line-height:1.4;text-align:left;color:#363636}sr-rd-content h1{padding-bottom:.3em;font-size:3.6rem;line-height:1.2}sr-rd-content h2{padding-bottom:.3em;font-size:2.8rem;line-height:1.225}sr-rd-content h3{font-size:2.4rem;line-height:1.43}sr-rd-content h4{font-size:2rem}sr-rd-content h5{font-size:1.6rem}sr-rd-content h6{font-size:1.6rem;color:#777}
sr-rd-content ul,sr-rd-content ol{list-style-type: disc;padding:0;padding-left:2em;}sr-rd-content ol ol,sr-rd-content ul ol{list-style-type:lower-roman}sr-rd-content ul ul ol,sr-rd-content ul ol ol,sr-rd-content ol ul ol,sr-rd-content ol ol ol{list-style-type:lower-alpha}
sr-rd-content table{width:100%;overflow:auto;word-break:normal;word-break:keep-all}sr-rd-content table th{font-weight:bold}sr-rd-content table th,sr-rd-content table td{padding:6px 13px;border:1px solid #ddd}sr-rd-content table tr{background-color:#fff;border-top:1px solid #ccc}sr-rd-content table tr:nth-child(2n){background-color:#f8f8f8}
sr-rd-content sr-blockquote {
    border-left: 4px solid #ddd;
}

/**
 * Custom style, include: background; title; desc; sr-rd-content; p,div; a; pre
 */

.simpread-theme-root {
    background-color: #fff;
    color:#333;
}

sr-rd-title {
    font-family: "PT Sans","SF UI Display", ".PingFang SC","PingFang SC", "Neue Haas Grotesk Text Pro", "Arial Nova", "Segoe UI", "Microsoft YaHei", "Microsoft JhengHei", "Helvetica Neue", "Source Han Sans SC", "Noto Sans CJK SC", "Source Han Sans CN", "Noto Sans SC", "Source Han Sans TC", "Noto Sans CJK TC", "Hiragino Sans GB", sans-serif;

    font-size: 3.4rem;
    font-weight: 700;
    line-height: 1.3;
}

sr-rd-desc {
    position: relative;
    margin: 0px;
    margin-bottom: 30px;
    padding: 25px;
    padding-left: 56px;
    font-size: 1.8rem;
    color: #777;
    background-color: rgba(0,0,0,0.05);
}

sr-rd-desc:before {
    content: '“';
    position: absolute;
    top: -9px;
    left: 16px;
    font-size: 80px;
    font-family: "Arial";
    color: rgba(0,0,0,0.15);
}

sr-rd-content {
    color: #363636;
    font-weight: 400;
    line-height: 1.8;
}

sr-rd-content *,
sr-rd-content p,
sr-rd-content div {
    color: #363636;
    font-weight: 400;
    line-height: 1.8;
}

sr-rd-content a,
sr-rd-content a:link {
    color: #4183c4;
    text-decoration: none;
}

sr-rd-content a:hover,
sr-rd-content a:focus,
sr-rd-content a:active {
    color: #4183c4;
    text-decoration: underline;
}

sr-rd-content pre {
    background-color: #f7f7f7;
    border-radius: 3px;
}

sr-rd-content li code,
sr-rd-content p code {
    background-color: rgba(0,0,0,0.04);
    border-radius: 3px;
}

/**
 * Multiple page
 */

.simpread-multi-root {
    background: #F8F9FA;
}

================================================
FILE: src/assets/css/theme_gothic.css
================================================
sr-rd-theme-gothic{display:none;}

/**
 * Gothic style
 */

/**
 * Common style, include: h1 ~ h6; ol ul; code pre; table; sr-blockquote
 */

sr-rd-content h1{line-height:4rem;margin:4rem 0 1.75rem;padding:20px 30px}sr-rd-content h1,sr-rd-content h2{font-weight:400;text-align:center;text-transform:uppercase}sr-rd-content h2{line-height:3rem;margin:3rem 0 1.9375rem;padding:0 30px}sr-rd-content h3,sr-rd-content h4,sr-rd-content h5{font-weight:400}sr-rd-content h6{font-weight:700}sr-rd-content h1{font-size:3.6rem}sr-rd-content h2{font-size:3.2rem}sr-rd-content h3{font-size:2.5rem}sr-rd-content h4{font-size:2.2rem}sr-rd-content h5{font-size:1.9rem}sr-rd-content h6{font-size:1.7rem}sr-rd-content h1,sr-rd-content h2,sr-rd-content h3,sr-rd-content h4,sr-rd-content h5,sr-rd-content h6{margin-top:1.2em;margin-bottom:0.6em;color:#111}
sr-rd-content ol,sr-rd-content ul{list-style-type:disc}sr-rd-content ul, sr-rd-content ol{margin-left:3em}sr-rd-content ol ol,sr-rd-content ul ol{list-style-type:lower-roman}sr-rd-content ol ol ol,sr-rd-content ol ul ol,sr-rd-content ul ol ol,sr-rd-content ul ul ol{list-style-type:lower-alpha}
sr-rd-content table{margin-bottom:20px}sr-rd-content table th,sr-rd-content table td{padding:8px;line-height:1.25rem;vertical-align:top;border-top:1px solid #ddd}sr-rd-content table th{font-weight:bold}sr-rd-content table thead th{vertical-align:bottom}sr-rd-content table caption+thead tr:first-child th,sr-rd-content table caption+thead tr:first-child td,sr-rd-content table colgroup+thead tr:first-child th,sr-rd-content table colgroup+thead tr:first-child td,sr-rd-content table thead:first-child tr:first-child th,sr-rd-content table thead:first-child tr:first-child td{border-top:0}sr-rd-content table tbody+tbody{border-top:2px solid #ddd}
sr-rd-content sr-blockquote {
    margin: 0 0 1.11111rem;
    padding: 0.5rem 1.11111rem 0 1.05556rem;
    border-left: 1px solid gray;
}
sr-rd-content sr-blockquote,
sr-rd-content sr-blockquote p {
    line-height: 2;
    color: #6f6f6f;
}

/**
 * Custom style, include: background; title; desc; sr-rd-content; p,div; a; pre
 */

.simpread-theme-root, .simpread-multi-root {
    background: rgb(252, 252, 252);
    color: #333;
}

sr-rd-title {
    font-weight: normal;
    line-height: 4rem;
    text-align: center;
    text-transform: uppercase;

    color: rgb(17, 17, 17);
    font-size: 3.2rem;
}

sr-rd-desc {
    margin: 0px 0px 1.11111rem;
    padding: 0.5rem 1.11111rem 0px 1.05556rem;

    font-size: 2rem;
    line-height: 2;
    color: rgb(111, 111, 111);

    border-left: 1px solid gray;
}

sr-rd-content {
    font-weight: 400;
    color: #333;
}

sr-rd-content *,
sr-rd-content p,
sr-rd-content div {
    color: #333;
}

sr-rd-content a,
sr-rd-content a:link {
    color: rgb(153, 0, 0);
    text-decoration: none;
}

sr-rd-content a:hover,
sr-rd-content a:focus,
sr-rd-content a:active {
    color: rgb(153, 0, 0);
    text-decoration: underline;
}

sr-rd-content pre {
    background-color: transparent;
    border: 1px solid rgb(204, 204, 204);
}

sr-rd-content li code,
sr-rd-content p code {
    background-color: transparent;
    border: 1px solid rgb(204, 204, 204);
}

/**
 * Multiple page
 */
sr-rd-mult {
    background-color: #f2f2f2;
}

================================================
FILE: src/assets/css/theme_mobile.css
================================================
/**
 * Mobile media
 */
@media (pointer:coarse) {
    sr-read {
        margin: 20px 5%!important;
        min-width: initial!important;
        max-width: 90%!important;
    }

    sr-rd-title {
        margin-top: 0;
        font-size: 2.7rem;
    }

    sr-rd-desc,
    sr-rd-content sr-blockquote {
        margin: 10 0!important;
        padding: 0 0 0 10px !important;
        width: 90%;

        font-size: 1.8rem;
        font-style: normal;
        line-height: 1.7;
        text-align: justify;
    }

    sr-rd-content {
        font-size: 1.75rem;
        font-weight: 300;
    }

    sr-rd-content figure {
        margin: 0;
        padding: 0;
        text-align: center;
    }

    sr-rd-content a, sr-rd-content a:link {
          font-size: inherit;
    }

    sr-rd-content li code, sr-rd-content p code {
          font-size: inherit;
    }

    sr-rd-footer {
          margin-top: 20px;
    }

    sr-blockquote, sr-blockquote * {
          margin: 5px !important;
          padding: 5px !important;
    }

    sr-rd-title, sr-rd-content h1, sr-rd-content h2, sr-rd-content h3, sr-rd-content h4, sr-rd-content h5, sr-rd-content h6 {
        font-family: PingFang SC, Verdana, Helvetica Neue, Microsoft Yahei, Hiragino Sans GB, Microsoft Sans Serif, WenQuanYi Micro Hei, sans-serif;
        color: #000;
        font-weight: 100;
        line-height: 1.35;
    }

    sr-rd-content h1, sr-rd-content h2, sr-rd-content h3, sr-rd-content h4, sr-rd-content h5, sr-rd-content h6,
    sr-rd-content-h1, sr-rd-content-h2, sr-rd-content-h3, sr-rd-content-h4, sr-rd-content-h5, sr-rd-content-h6 {
      margin-top: 1.2em;
      margin-bottom: 0.6em;
      line-height: 1.35;
    }

    sr-rd-content h1, sr-rd-content-h1 {
      font-size: 1.8em;
    }

    sr-rd-content h2, sr-rd-content-h2 {
      font-size: 1.6em;
    }

    sr-rd-content h3, sr-rd-content-h3 {
      font-size: 1.4em;
    }

    sr-rd-content h4, sr-rd-content-h4 {
      font-size: 1.2em;
    }

    sr-rd-content h5, sr-rd-content h6, sr-rd-content-h5, sr-rd-content-h6 {
      font-size: 1.2em;
    }

    sr-rd-content ul, sr-rd-content-ul {
        margin-left: 1.3em!important;
        list-style: disc;
    }

    sr-rd-content ol, sr-rd-content-ol {
        list-style: decimal;
        margin-left: 1.9em!important;
    }

    sr-rd-content li ul, sr-rd-content li ol, sr-rd-content-ul ul, sr-rd-content-ul ol, sr-rd-content-ol ul, sr-rd-content-ol ol {
        margin-bottom: 0.8em;
        margin-left: 2em!important;;
    }

    sr-rd-content img {
        margin: 0;
        padding: 0;
        border: 0;
        max-width: 100%!important;
        height: auto;
        box-shadow: 0 20px 20px -10px rgba(0,0,0,0.1);
    }

    sr-rd-mult {
        min-width: initial;
        background-color: #fff;
        box-shadow: 0 1px 6px rgba(32, 33, 36, 0.28);
        border-radius: 8px;
    }

    sr-rd-mult sr-rd-mult-avatar div {
        margin: 0;
    }

    sr-rd-mult sr-rd-mult-avatar .sr-rd-content-center-small {
        margin: 7px 0!important;
    }

    sr-rd-mult sr-rd-mult-avatar span {
        display: block;
    }

    sr-rd-mult sr-rd-mult-content {
        padding-left: 0;
    }

    /**
    * iPad pro 12 and below
    */
    @media only screen and (max-device-width: 1024px) {
        html.simpread-theme-root, .simpread-theme-root {
            font-size: 80%!important;
        }

        sr-rd-mult sr-rd-mult-avatar img {
            width: 50px;
            height: 50px;
            min-width: 50px;
            min-height: 50px;
        }
    }

    /**
    * iPhone XS Max and below
    */
    @media only screen and (max-device-width: 414px) {
        html.simpread-theme-root, .simpread-theme-root {
            font-size: 70%!important;
        }

        sr-rd-mult sr-rd-mult-avatar img {
            width: 30px;
            height: 30px;
            min-width: 30px;
            min-height: 30px;
        }
    }

    /**
    * iPhone SE and below
    */
    @media only screen and (max-device-width: 320px) {
        html.simpread-theme-root, .simpread-theme-root {
            font-size: 90%!important;
        }

        sr-rd-content p {
            margin-bottom: .5em;
        }
    }
}


================================================
FILE: src/assets/css/theme_monospace.css
================================================
sr-rd-theme-monospace{display:none;}

/**
 * Monospace style
 */

/**
 * Common style, include: h1 ~ h6; ol ul; code pre; table; sr-blockquote
 */

sr-rd-content h1,sr-rd-content h2,sr-rd-content h3,sr-rd-content h4,sr-rd-content h5,sr-rd-content h6{font-weight:700;color:#6363ac}sr-rd-content h1{font-size:2.2rem}sr-rd-content h2{font-size:2rem}sr-rd-content h3{font-size:1.8rem}sr-rd-content h4{font-size:1.6rem}sr-rd-content h5{font-size:1.4rem}sr-rd-content h6{font-size:1.3rem}
sr-rd-content strong{color:#b5302e}sr-rd-content em{font-style:italic;color:#400469}
sr-rd-content ol,sr-rd-content ul{list-style-type:none}sr-rd-content ol li,sr-rd-content ul li{margin:0}
sr-rd-content table{line-height:1.6rem;border-collapse:collapse;border-spacing:0;empty-cells:show;border:1px solid #cbcbcb}sr-rd-content thead{background-color:#e0e0e0;color:#000;text-align:left;vertical-align:bottom}sr-rd-content td,sr-rd-content th{border-left:1px solid #cbcbcb;border-width:0 0 0 1px;margin:0;overflow:visible;padding:.5em 1em}
sr-rd-content sr-blockquote {
    background-color: rgba(128, 128, 128, 0.05);
    border-top-right-radius: 5px;
    border-bottom-right-radius: 5px;
    border-left: 8px solid #979797;
    line-height: 2;
}

sr-rd-content sr-blockquote * {
    line-height: inherit;
}

/**
 * Custom style, include: background; title; desc; sr-rd-content; p,div; a; pre
 */

.simpread-theme-root {
    color: #333333;
    background: white;
}

sr-rd-title {
    font-size: 2.8rem;
    line-height: 1.2;
    font-weight: bold;
    color: #6363ac;
}

sr-rd-desc {
    padding: 10px;
    background-color: rgba(128, 128, 128, 0.05);
    font-size: 1.8rem;
    text-align: center;
    border-top-right-radius: 5px;
    border-bottom-right-radius: 5px;
    border-left: 8px solid #979797;
}

sr-rd-content {
    color: #333333;
    line-height: 1.7;
}

sr-rd-content *,
sr-rd-content p,
sr-rd-content div {
    line-height: 1.7;
}

sr-rd-content a,
sr-rd-content a:link {
    color: #005dad;
    text-decoration: underline;
}

sr-rd-content a:hover,
sr-rd-content a:focus,
sr-rd-content a:active {
    color: white;
    background-color: #2a6496;
    text-decoration: none;
}

sr-rd-content pre {
    color: #e9eded;
    background-color: #263238;
}

sr-rd-content li code,
sr-rd-content p code {
    color: #949415;
    background-color: transparent;
}

/**
 * Multiple page
 */

.simpread-multi-root {
    background: #F8F9FA;
}

================================================
FILE: src/assets/css/theme_newsprint.css
================================================
sr-rd-theme-newsprint{display:none;}

/**
 * Newsprint style
 */

/**
 * Common style, include: h1 ~ h6; ol ul; code pre; table; sr-blockquote
 */

sr-rd-content h1,sr-rd-content h2,sr-rd-content h3,sr-rd-content h4,sr-rd-content h5,sr-rd-content h6{font-weight:700}sr-rd-content h1{font-size:3rem;line-height:1.6em;margin-top:2em}sr-rd-content h2,sr-rd-content h3{font-size:2rem;line-height:1.15;margin-top:2.285714em;margin-bottom:1.15em}sr-rd-content h3{font-weight:400}sr-rd-content h4{font-size:1.8rem;margin-top:2.67em}sr-rd-content h5,sr-rd-content h6{font-size:1.6rem}sr-rd-content h1{border-bottom:1px solid;margin-bottom:1.875em;padding-bottom:.8125em}
sr-rd-content ul, sr-rd-content ol{margin:0 0 1.5em 1.5em}sr-rd-content ol li{list-style-type:decimal;list-style-position:outside}sr-rd-content ul li{list-style-type:disc;list-style-position:outside}
sr-rd-content table{width:100%;margin-bottom:1.5em;font-size:1.6rem;}sr-rd-content thead th,tfoot th{padding:.25em .25em .25em .4em;text-transform:uppercase}sr-rd-content th{text-align:left}sr-rd-content td{vertical-align:top;padding:.25em .25em .25em .4em}sr-rd-content thead{background-color:#dadada}sr-rd-content tr:nth-child(2n){background:#e8e7e7;}
sr-rd-content sr-blockquote {
    padding: 10px 15px;
    border-left-style: solid;
    border-left-width: 10px;
    border-color: #D6DBDF;
    background: none repeat scroll 0 0 rgba(102,128,153,.05);
    text-align: left;
}

sr-rd-content sr-blockquote:before {
    content: '';
}

/**
 * Custom style, include: background; title; desc; sr-rd-content; p,div; a; pre
 */

.simpread-theme-root, .simpread-multi-root {
    background-color: #f3f2ee;
    color: #2C3E50;
}

sr-rd-title {
    font-family: PingFang SC,Hiragino Sans GB,Microsoft Yahei,WenQuanYi Micro Hei,sans-serif;

    line-height: 1.5;
    font-weight: 500;
    font-size: 3rem;

    color: #0077bb;
    border-bottom: 1px solid;

    margin-bottom: 1.875em;
    padding-bottom: .8125em;
}

sr-rd-desc {
    color: rgba(102,128,153,0.6);
    background-color: rgba(102,128,153,0.075);
    border-radius: 4px;

    margin-bottom: 1em;
    padding: 15px;

    font-size: 2rem;
    line-height: 1.5;
    text-align: center;
}

sr-rd-content {
    line-height: 1.8;
    color: #2C3E50;
}

sr-rd-content *,
sr-rd-content p,
sr-rd-content div {
    color: #2C3E50;
    line-height: 1.8;
}

sr-rd-content a,
sr-rd-content a:link {
    color: #08c;
    text-decoration: none;
}

sr-rd-content a:hover,
sr-rd-content a:focus,
sr-rd-content a:active {
    color: #5BA4E5;
}

sr-rd-content pre {
    background-color: rgb(218, 218, 218);
}

sr-rd-content li code,
sr-rd-content p code {
    background-color: rgb(218, 218, 218);
}

/**
 * Multiple page
 */
sr-rd-mult {
    background-color: rgba(102,128,153,0.075);
}

================================================
FILE: src/assets/css/theme_night.css
================================================
sr-rd-theme-night{display:none;}

/**
 * Night style
 */

/**
 * Common style, include: h1 ~ h6; ol ul; code pre; table; sr-blockquote
 */

sr-rd-content h1{margin-top:2em}sr-rd-content h1,sr-rd-content h2,sr-rd-content h3,sr-rd-content h4,sr-rd-content h5,sr-rd-content h6{color:#dedede}sr-rd-content h1,sr-rd-content h2,sr-rd-content h3,sr-rd-content h4,sr-rd-content h5,sr-rd-content h6{font-weight:400;clear:both;-ms-word-wrap:break-word;word-wrap:break-word;margin:0;padding:0}sr-rd-content h1{font-size:3.6rem;line-height:4rem;margin-bottom:2.4rem;letter-spacing:-1.5px}sr-rd-content h2{font-size:2.4rem;line-height:3rem}sr-rd-content h2,sr-rd-content h3{margin-bottom:2.4rem;letter-spacing:-1px}sr-rd-content h3{font-size:1.8rem;line-height:2.4rem}sr-rd-content h4{font-size:1.6rem;line-height:2.2rem;margin-bottom:2.4rem}sr-rd-content h5{font-size:1rem;line-height:1.25rem;margin-bottom:1.5rem}sr-rd-content h6{font-size:1.6rem;line-height:1.6rem;margin-bottom:.75rem;font-weight:700}
sr-rd-content ul,sr-rd-content ol{padding:0 0 0 1.875rem}sr-rd-content ul{list-style:square}sr-rd-content ol{list-style:decimal}sr-rd-content ul ul,sr-rd-content ol ol,sr-rd-content ul ol,sr-rd-content ol ul{margin:0}sr-rd-content li div{padding-top:0}sr-rd-content li p,sr-rd-content li{margin:0;position:relative}
sr-rd-content table{margin-top:0;margin-bottom:1.5rem;border-collapse:collapse;border-spacing:0;page-break-inside:auto;text-align:left}sr-rd-content table a{color:#dedede}sr-rd-content thead{display:table-header-group}sr-rd-content table td,sr-rd-content table th{border:1px solid #474d54}
sr-rd-content sr-blockquote {
    margin: 0 0 1.875rem 1.875rem;
    border-left: solid 2px #474d54;
    padding-left: 30px;
    margin-top: 35px;
    line-height: 2;
}

/**
 * Custom style, include: background; title; desc; sr-rd-content; p,div; a; pre
 */

.simpread-theme-root, .simpread-multi-root {
    background: rgb(54, 59, 64);
    color: #b8bfc6;
}

sr-rd-title {
    color: #DEDEDE;
    font-size: 3.15rem;
    line-height: 3.5rem;
    letter-spacing: -1.5px;
}

sr-rd-desc {
    margin: 35px;
    margin-left: 0;
    padding-left: 1.875rem;
    font-size: 2rem;
    line-height: 2;
    color: #b8bfc6;
    border-left: solid 2px #474d54;
}

sr-rd-content {
    color: #b8bfc6;
}

sr-rd-content *,
sr-rd-content p,
sr-rd-content div {
    color: #b8bfc6;
    margin-top: 0;
    line-height: 2;
}

sr-rd-content a,
sr-rd-content a:link {
    color: #e0e0e0;
    text-decoration: underline;
    transition: all .2s ease-in-out;
}

sr-rd-content a:hover,
sr-rd-content a:focus,
sr-rd-content a:active {
    color: #fff;
}

sr-rd-content pre {
    background-color: transparent;
    border: 1px solid;
}

sr-rd-content li code,
sr-rd-content p code {
    background: rgba(0, 0, 0, 0.05);
}

/**
 * Multiple page
 */
sr-rd-mult {
    background-color: #2d3034;
}

================================================
FILE: src/assets/css/theme_octopress.css
================================================
sr-rd-theme-octopress{display:none;}

/**
 * Octopress style
 */

/**
 * Common style, include: h1 ~ h6; ol ul; code pre; table; sr-blockquote
 */

sr-rd-content h1{font-size:3.52rem;line-height:1.92rem}sr-rd-content h1,sr-rd-content h2,sr-rd-content h3,sr-rd-content h4,sr-rd-content h5,sr-rd-content h6{text-rendering:optimizelegibility;margin-bottom:1.3rem;font-weight:700}sr-rd-content h2{font-size:2.4rem}sr-rd-content h3{font-size:2.08rem}sr-rd-content h4{font-size:1.8rem}sr-rd-content h5,sr-rd-content h6{font-size:1.6rem}sr-rd-content h1,sr-rd-content h2{padding-top:1.7rem;padding-bottom:1.2rem;background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAABCAYAAACsXeyTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAFUlEQVQIHWNIS0sr/v//PwMMDzY+ADqMahlW4J91AAAAAElFTkSuQmCC') bottom left repeat-x}sr-rd-content h2{padding-top:1.3rem;padding-bottom:0}
sr-rd-content ul{list-style-type:disc}sr-rd-content ul ul{list-style-type:circle;margin-bottom:0}sr-rd-content ul ul ul{list-style-type:square;margin-bottom:0}sr-rd-content ol{list-style-type:decimal}sr-rd-content ol ol{list-style-type:lower-alpha;margin-bottom:0}sr-rd-content ol ol ol{list-style-type:lower-roman;margin-bottom:0}sr-rd-content ul,sr-rd-content ul ul,sr-rd-content ul ol,sr-rd-content ol,sr-rd-content ol ul,sr-rd-content ol ol{margin-left:1.3em}sr-rd-content ul ul,sr-rd-content ul ol,sr-rd-content ol ul,sr-rd-content ol ol{margin-bottom:0}
sr-rd-content table{width:100%;overflow:auto;word-break:normal;word-break:keep-all}sr-rd-content table th{font-weight:bold}sr-rd-content table th,sr-rd-content table td{padding:6px 13px;border:1px solid #ddd}sr-rd-content table tr{background-color:#fff;border-top:1px solid #ccc}sr-rd-content table tr:nth-child(2n){background-color:#f8f8f8}
sr-rd-content sr-blockquote {
    font-style: italic;
    font-size: inherit;
    line-height: 2;
    padding-left: 1em;
    border-left: 4px solid rgba(170,170,170,0.5);
}

/**
 * Custom style, include: background; title; desc; sr-rd-content; p,div; a; pre
 */

.simpread-theme-root, .simpread-multi-root {
    background: #f8f8f8 url('data:image/png;base64,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') top left;
    color: #333;
}

sr-rd-title {
    font-size: 3.52rem;
    line-height: 4rem;
    font-weight: bold;
    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAABCAYAAACsXeyTAAAACXBIW…sTAAALEwEAmpwYAAAAFUlEQVQIHWNIS0sr/v//PwMMDzY+ADqMahlW4J91AAAAAElFTkSuQmCC) bottom left repeat-x;
}

sr-rd-desc {
    font-style: italic;
    font-size: 1.92rem;
    line-height: 2;
    padding-left: 1em;
    border-left: 4px solid rgba(170,170,170,0.5);
}

sr-rd-content {
    line-height: 2;
    color: #333;
    margin: 0 auto;
    padding: 1em 0;
}

sr-rd-content *,
sr-rd-content p,
sr-rd-content div {
    line-height: 2;
    color: #333;
}

sr-rd-content a,
sr-rd-content a:link {
    color: #1863a1;
    text-decoration: underline;
}

sr-rd-content a:hover,
sr-rd-content a:focus,
sr-rd-content a:active {
    color: #0181eb;
    text-decoration: underline;
}

sr-rd-content pre {
    color: #586e75;
    background-color: #fdf6e3;
    border-radius: 0.4em;
    border: 1px solid #e7dec3;
}

sr-rd-content li code,
sr-rd-content p code {
    color: #555;
    background-color: transparent;
    border: 1px solid #ddd;
}

/**
 * Multiple page
 */
sr-rd-mult {
    background-color: #ededed;
}

================================================
FILE: src/assets/css/theme_pixyii.css
================================================
sr-rd-theme-pixyii{display:none;}

/**
 * Pixyii style
 */

/**
 * Common style, include: h1 ~ h6; ol ul; code pre; table; sr-blockquote
 */

sr-rd-content h1,sr-rd-content h1 *,sr-rd-content h2,sr-rd-content h2 *,sr-rd-content h3,sr-rd-content h3 *,sr-rd-content h4,sr-rd-content h4 *,sr-rd-content h5,sr-rd-content h5 *,sr-rd-content h6,sr-rd-content h6 *{color:inherit;font-weight:900;line-height:1.2;margin:1em 0 1em}sr-rd-content h1,sr-rd-content h1 *{font-size:3.92rem}sr-rd-content h2,sr-rd-content h2 *{font-size:3.64rem}sr-rd-content h3,sr-rd-content h3 *{font-size:2.275rem}sr-rd-content h4,sr-rd-content h4 *{font-size:1.82rem}sr-rd-content h5,sr-rd-content h5 *,sr-rd-content h6,sr-rd-content h6 *{font-size:1.573rem}
sr-rd-content ol,sr-rd-content ul{font-size:1.75rem;line-height:1.5rem}sr-rd-content li{font-size:1.575rem;line-height:1.8;margin:0;position:relative}
sr-rd-content table{width:100%;font-size:1.575rem}sr-rd-content table>thead>tr>th,sr-rd-content table>thead>tr>td,sr-rd-content table>tbody>tr>th,sr-rd-content table>tbody>tr>td,sr-rd-content table>tfoot>tr>th,sr-rd-content table>tfoot>tr>td{padding:12px;line-height:1.2;vertical-align:top;border-top:1px solid #333}sr-rd-content table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #333}sr-rd-content table>caption+thead>tr:first-child>th,sr-rd-content table>caption+thead>tr:first-child>td,sr-rd-content table>colgroup+thead>tr:first-child>th,sr-rd-content table>colgroup+thead>tr:first-child>td,sr-rd-content table>thead:first-child>tr:first-child>th,sr-rd-content table>thead:first-child>tr:first-child>td{border-top:0}sr-rd-content table>tbody+tbody{border-top:2px solid #333}
sr-rd-content sr-blockquote {
    margin: 1rem 0px;
    padding: 1.33em;
    font-style: italic;
    border-left: 5px solid rgb(122, 122, 122);
    color: rgb(85, 85, 85);
}

/**
 * Custom style, include: background; title; desc; sr-rd-content; p,div; a; pre
 */

.simpread-theme-root {
    background-color: rgb(255, 255, 255);
    color: rgb(85, 85, 85);
}

sr-rd-title {
    font-family: PingFang SC,Hiragino Sans GB,Microsoft Yahei,WenQuanYi Micro Hei,sans-serif;
    font-size: 4.2rem;
    font-weight: 900;
    line-height: 1.2;
}

sr-rd-desc {
    margin: 1rem 0px;
    padding: 1.33em;
    font-style: italic;
    font-size: 2rem;
    line-height: 2;
    border-left: 5px solid rgb(122, 122, 122);
    color: rgb(85, 85, 85);
}

sr-rd-content {
    font-size: 2.1rem;
    line-height: 1.8;
    font-weight: 400;
    color: rgb(85, 85, 85);
}

sr-rd-content *,
sr-rd-content p,
sr-rd-content div {
    color: rgb(85, 85, 85);
    font-size: 1.75rem;
    line-height: 1.8;
    font-weight: 300;
}

sr-rd-content strong {
    font-weight: 400;
}

sr-rd-content a,
sr-rd-content a:link {
    color: rgb(70, 63, 92);
    text-decoration: underline;
}

sr-rd-content a:hover,
sr-rd-content a:focus,
sr-rd-content a:active {
    color: rgb(70, 63, 92);
    text-decoration: underline;
}

sr-rd-content sr-blockquote code {
    font-size: inherit;
}

sr-rd-content pre {
    color: rgb(122, 122, 122);
    background-color: transparent;
    border: 1px solid rgb(122, 122, 122);
}

sr-rd-content li code,
sr-rd-content p code {
    color: rgb(122, 122, 122);
    background-color: transparent;
}

/**
 * Multiple page
 */

 .simpread-multi-root {
    background: #F8F9FA;
}

================================================
FILE: src/background.js
================================================
console.log( "=== simpread background load ===" )

import local       from 'local';
import { storage } from 'storage';
import * as msg    from 'message';
import {browser}   from 'browser';
import * as ver    from 'version';
import * as menu   from 'menu';
import * as watch  from 'watch';
import * as WebDAV from 'webdav';
import * as permission
                   from 'permission';
import * as tips   from 'tips';
import PureRead    from 'puread';

// global update site tab id
let upTabId = -1;

/**
 * Sevice: storage Get data form chrome storage
 */
storage.Read( () => {
    storage.puread = new PureRead( storage.sites );
    if ( local.Firstload() ) {
        local.Version( ver.version );
        browser.tabs.create({ url: browser.extension.getURL( "options/options.html#firstload?ver=" + ver.version ) });
    }
    else {
       !local.Count() && storage.GetRemote( "remote", ( result, error ) => {
            if ( !error ) {
                storage.pr.Addsites( result );
                storage.Writesite( storage.pr.sites, getNewsitesHandler );
            }
        });
        ver.version != storage.version && storage.GetRemote( "local", ( result, error ) => {
            storage.pr.Addsites( result );
            storage.Writesite( storage.pr.sites, () => {
                ver.version != storage.version &&
                storage.Fix( storage.read.sites, storage.version, ver.version, storage.focus.sites );
                ver.version != storage.version && storage.Write( () => {
                        local.Version( ver.version );
                        browser.tabs.create({ url: browser.extension.getURL( "options/options.html#update?ver=" + ver.version ) });
                }, ver.Verify( storage.version, storage.simpread ) );
                getNewsitesHandler( result );
            });
        });
        ver.version == storage.version && ver.patch != storage.patch &&
            storage.Write(()=> {
                // when x.x.x.yyyy is silent update
                //browser.tabs.create({ url: browser.extension.getURL( "options/options.html#update?patch=" + ver.patch ) });
                //localStorage.setItem( "simpread-patch-update", true );
                local.Patch( "add", true );
            }, ver.FixSubver( ver.patch, storage.simpread ));
    }
    menu.CreateAll();
    setTimeout( ()=>uninstall(), 100 );
});

/**
 * Get newsites handler
 * @param {object} count: update site cou
 */
function getNewsitesHandler( result ) {
    watch.Push( "site", true );
}

/**
 * Listen menu event handler
 */
menu.OnClicked( ( info, tab ) => {
    console.log( "background contentmenu Listener", info, tab );
    tracked({ eventCategory: "menu", eventAction: "menu", eventValue: info.menuItemId });
    if ( info.menuItemId == "link" ) {
        info.linkUrl && browser.tabs.create({ url: info.linkUrl + "?simpread_mode=read" });
    } else if ( info.menuItemId == "list" ) {
        browser.tabs.create({ url: browser.extension.getURL( "options/options.html#later" ) });
    } else if ( info.menuItemId == "whitelist" ) {
        browser.tabs.sendMessage( tab.id, msg.Add( msg.MESSAGE_ACTION.menu_whitelist, {url: info.pageUrl } ));
    } else if ( info.menuItemId == "exclusion" ) {
        browser.tabs.sendMessage( tab.id, msg.Add( msg.MESSAGE_ACTION.menu_exclusion, {url: info.pageUrl } ));
    } else if ( info.menuItemId == "blacklist" ) {
        browser.tabs.sendMessage( tab.id, msg.Add( msg.MESSAGE_ACTION.menu_blacklist, {url: info.pageUrl } ));
    } else if ( info.menuItemId == "unrdist" ) {
        browser.tabs.sendMessage( tab.id, msg.Add( msg.MESSAGE_ACTION.menu_unrdist, {url: info.pageUrl } ));
    } else if ( info.menuItemId == "lazyload" ) {
        browser.tabs.sendMessage( tab.id, msg.Add( msg.MESSAGE_ACTION.menu_lazyload, {url: info.pageUrl } ));
    } else {
        if ( !tab.url.startsWith( "chrome://" ) ) browser.tabs.sendMessage( tab.id, msg.Add(info.menuItemId));
    }
});

/**
 * Listen runtime message, include: `corb`
 */
browser.runtime.onMessage.addListener( function( request, sender, sendResponse ) {
    if ( request.type == msg.MESSAGE_ACTION.CORB ) {
        $.ajax( request.value.settings )
            .done( result => {
                sendResponse({ done: result });
            })
            .fail( ( jqXHR, textStatus, errorThrown ) => {
                sendResponse({ fail: { jqXHR, textStatus, errorThrown }});
            });
    }
    return true;
});

/**
 * Listen runtime message, include: `jianguo`
 */
browser.runtime.onMessage.addListener( function( request, sender, sendResponse ) {
    if ( request.type == msg.MESSAGE_ACTION.jianguo ) {
        const { url, user, password, method } = request.value;
        const dav = new WebDAV.Fs( url, user, password );
        if ( method.type == "folder" ) {
            dav.dir( method.root ).mkdir( result => {
                dav.dir( method.root + "/" + method.folder ).mkdir( result => {
                    sendResponse({ done: result, status: result.status });
                });
            })
        } else if ( method.type == "file" ) {
            dav.file( method.path ).write( method.content, result => {
                sendResponse({ done: result, status: result.status });
            });
        } else if ( method.type == "read" ) {
            dav.file( method.path ).read( result => {
                sendResponse({ done: result.response, status: result.status });
            });
        }
    }
    //return true;
});

/**
 * Listen runtime message, include: `webdav`
 */
browser.runtime.onMessage.addListener( function( request, sender, sendResponse ) {
    if ( request.type == msg.MESSAGE_ACTION.WebDAV ) {
        const { url, user, password, method } = request.value;
        const dav = new WebDAV.Fs( url, user, password );
        if ( method.type == "folder" ) {
            dav.dir( method.root ).mkdir( result => {
                sendResponse({ done: result, status: result.status });
            })
        } else if ( method.type == "file" ) {
            dav.file( method.root + "/" + method.name ).write( method.content, result => {
                sendResponse({ done: result, status: result.status });
            });
        }
    }
    //return true;
});

/**
 * Listen runtime message, include: `download`, `base64` && `permission`
 */
browser.runtime.onMessage.addListener( function( request, sender, sendResponse ) {
    if ( request.type == msg.MESSAGE_ACTION.download ) {
        const { data, name } = request.value;
        const blob = new Blob([data], {
            type: "html/plain;charset=utf-8"
        });
        const url = URL.createObjectURL(blob);
        browser.downloads.download({
            url     : url,
            filename: name.replace( /[|]/ig, "" ),
        }, downloadId => {
            sendResponse({ done: downloadId });
       
Download .txt
gitextract_l14w1v5n/

├── .github/
│   └── ISSUE_TEMPLATE/
│       ├── bug_report.yaml
│       ├── config.yml
│       ├── feature_request.yml
│       ├── new_site.yml
│       └── yinxiang_code.yml
├── .gitignore
├── LICENSE
├── README.md
├── ext/
│   ├── background.js
│   ├── contentscripts.js
│   └── manifest.json
├── npmw.cmd
├── package.json
├── src/
│   ├── _locales/
│   │   ├── en/
│   │   │   └── messages.json
│   │   ├── zh_CN/
│   │   │   └── messages.json
│   │   └── zh_TW/
│   │       └── messages.json
│   ├── assets/
│   │   └── css/
│   │       ├── options_custom.css
│   │       ├── options_notice.css
│   │       ├── options_page.css
│   │       ├── options_sitemgr.css
│   │       ├── setting.css
│   │       ├── simpread.css
│   │       ├── theme_common.css
│   │       ├── theme_dark.css
│   │       ├── theme_engwrite.css
│   │       ├── theme_github.css
│   │       ├── theme_gothic.css
│   │       ├── theme_mobile.css
│   │       ├── theme_monospace.css
│   │       ├── theme_newsprint.css
│   │       ├── theme_night.css
│   │       ├── theme_octopress.css
│   │       └── theme_pixyii.css
│   ├── background.js
│   ├── contentscripts.js
│   ├── focus/
│   │   ├── controlbar.jsx
│   │   └── focus.js
│   ├── ga.js
│   ├── help_tips.json
│   ├── manifest.json
│   ├── module/
│   │   ├── about.jsx
│   │   ├── account.jsx
│   │   ├── actionbar.jsx
│   │   ├── authorize.jsx
│   │   ├── common/
│   │   │   ├── editor.jsx
│   │   │   ├── exclude.jsx
│   │   │   ├── include.jsx
│   │   │   ├── name.jsx
│   │   │   ├── shortcuts.jsx
│   │   │   ├── theme.jsx
│   │   │   └── url.jsx
│   │   ├── common.jsx
│   │   ├── enhancesite.jsx
│   │   ├── feedback.jsx
│   │   ├── focus.jsx
│   │   ├── guide.jsx
│   │   ├── keyboard.js
│   │   ├── labs.jsx
│   │   ├── notice.jsx
│   │   ├── pluginbar.jsx
│   │   ├── plugins.jsx
│   │   ├── read.jsx
│   │   ├── setting.jsx
│   │   ├── sharecard.jsx
│   │   ├── sitebar.jsx
│   │   ├── siteeditor.jsx
│   │   ├── sites.jsx
│   │   ├── unrdist.jsx
│   │   ├── urlscheme.jsx
│   │   └── welcome.jsx
│   ├── options/
│   │   ├── corb.html
│   │   ├── corb.js
│   │   ├── custom.html
│   │   ├── custom.js
│   │   ├── notice.html
│   │   ├── notice.js
│   │   ├── options.html
│   │   ├── options.js
│   │   ├── sitemgr.html
│   │   └── sitemgr.js
│   ├── read/
│   │   ├── controlbar.jsx
│   │   ├── progressbar.jsx
│   │   ├── read.jsx
│   │   ├── special.jsx
│   │   └── toc.jsx
│   ├── service/
│   │   ├── browser.js
│   │   ├── config.js
│   │   ├── export.js
│   │   ├── highlight.js
│   │   ├── local.js
│   │   ├── menu.js
│   │   ├── message.js
│   │   ├── offline.js
│   │   ├── output.js
│   │   ├── permission.js
│   │   ├── runtime.js
│   │   ├── snapshot.js
│   │   ├── storage.js
│   │   ├── stylesheet.js
│   │   ├── theme.js
│   │   ├── tips.js
│   │   ├── util.js
│   │   ├── version.js
│   │   └── watch.js
│   ├── vender/
│   │   ├── carousel/
│   │   │   ├── carousel.css
│   │   │   └── carousel.js
│   │   ├── instapaper.js
│   │   ├── mduikit/
│   │   │   ├── autocomplete.jsx
│   │   │   ├── button.jsx
│   │   │   ├── dialog.jsx
│   │   │   ├── dropdown.jsx
│   │   │   ├── fab.jsx
│   │   │   ├── fap.jsx
│   │   │   ├── list.jsx
│   │   │   ├── mduikit.css
│   │   │   ├── mintooltip.css
│   │   │   ├── progress.jsx
│   │   │   ├── selectfield.jsx
│   │   │   ├── sidebar.jsx
│   │   │   ├── slider.jsx
│   │   │   ├── statebutton.jsx
│   │   │   ├── switch.jsx
│   │   │   ├── tabs.jsx
│   │   │   ├── textfield.jsx
│   │   │   ├── tooltip.jsx
│   │   │   └── waves.js
│   │   ├── notify/
│   │   │   ├── notify.css
│   │   │   └── notify.js
│   │   ├── sha1.js
│   │   ├── turndown/
│   │   │   ├── turndown-plugin-gfm.js
│   │   │   └── turndown.js
│   │   ├── waves/
│   │   │   └── waves.js
│   │   ├── webdav.js
│   │   └── wiz.js
│   └── website_list.json
├── webpack.config.ext.js
└── webpack.config.js
Download .txt
SYMBOL INDEX (933 symbols across 88 files)

FILE: ext/background.js
  function getNewsitesHandler (line 54) | function getNewsitesHandler( result ) {
  function getCurTab (line 220) | function getCurTab( query, callback ) {
  function setMenuAndIcon (line 232) | function setMenuAndIcon( id, code ) {
  function tracked (line 257) | function tracked({ eventCategory, eventAction, eventLabel }) {
  function analytics (line 271) | function analytics() {

FILE: ext/contentscripts.js
  function blacklist (line 59) | function blacklist() {
  function bindShortcuts (line 143) | function bindShortcuts() {
  function focusMode (line 158) | function focusMode() {
  function readMode (line 190) | function readMode() {
  function autoOpen (line 219) | function autoOpen() {
  function entry (line 255) | function entry( current, other, ...str ) {
  function getCurrent (line 269) | function getCurrent( mode ) {
  function browserAction (line 281) | function browserAction( is_update ) {
  function pRead (line 292) | function pRead() {

FILE: src/background.js
  function getNewsitesHandler (line 63) | function getNewsitesHandler( result ) {
  function getCurTab (line 388) | function getCurTab( query, callback ) {
  function setMenuAndIcon (line 400) | function setMenuAndIcon( id, code ) {
  function tracked (line 419) | function tracked({ eventCategory, eventAction, eventValue }) {
  function uninstall (line 427) | function uninstall() {

FILE: src/contentscripts.js
  function blacklist (line 59) | function blacklist() {
  function isLazyload (line 71) | function isLazyload() {
  function bindShortcuts (line 160) | function bindShortcuts() {
  function focusMode (line 175) | function focusMode() {
  function readMode (line 207) | function readMode() {
  function autoOpen (line 246) | function autoOpen() {
  function entry (line 287) | function entry( current, other, ...str ) {
  function getCurrent (line 301) | function getCurrent( mode ) {
  function browserAction (line 313) | function browserAction( is_update ) {
  function pRead (line 324) | function pRead() {

FILE: src/focus/controlbar.jsx
  class FControl (line 24) | class FControl extends React.Component {
    method componentDidMount (line 26) | componentDidMount() {
    method onClose (line 36) | onClose() {
    method onAction (line 43) | onAction( event, type ) {
    method componentWillMount (line 92) | componentWillMount() {
    method componentWillUnmount (line 99) | componentWillUnmount() {
    method render (line 104) | render() {
  function Render (line 122) | function Render( root, finder, cb ) {
  function getRoot (line 134) | function getRoot() {

FILE: src/focus/focus.js
  function Focus (line 26) | function Focus() { this.$target = null; }
  function includeStyle (line 178) | function includeStyle( $target, style, cls, type ) {
  function excludeStyle (line 199) | function excludeStyle( $target, type ) {
  function fixFocus (line 212) | function fixFocus( $focus ) {

FILE: src/module/about.jsx
  class About (line 68) | class About extends React.Component {
    method render (line 70) | render() {

FILE: src/module/account.jsx
  class AccountOpt (line 11) | class AccountOpt extends React.Component {
    method onChangeName (line 24) | onChangeName( event ) {
    method onChangeEmail (line 32) | onChangeEmail( event ) {
    method onChangeContact (line 40) | onChangeContact( event ) {
    method componentWillMount (line 44) | componentWillMount() {
    method stat (line 56) | stat() {
    method save (line 68) | save() {
    method render (line 92) | render() {

FILE: src/module/actionbar.jsx
  class Actionbar (line 13) | class Actionbar extends React.Component {
    method constructor (line 24) | constructor( props ) {
    method render (line 28) | render() {

FILE: src/module/authorize.jsx
  class Auth (line 16) | class Auth extends React.Component {
    method onChange (line 47) | onChange( state, value, flag ) {
    method save (line 290) | save( state, value ) {
    method linnkOnChange (line 305) | linnkOnChange( state, value ) {
    method instapaperOnChange (line 309) | instapaperOnChange( state, value ) {
    method jianguoOnChange (line 313) | jianguoOnChange( state, value ) {
    method weizhiOnChange (line 317) | weizhiOnChange( state, value ) {
    method webdavOnChange (line 321) | webdavOnChange() {
    method notionChange (line 326) | notionChange() {
    method youdaoChange (line 339) | youdaoChange() {
    method webdavAuth (line 355) | webdavAuth() {
    method componentWillReceiveProps (line 375) | componentWillReceiveProps( nextProps ) {
    method componentDidMount (line 379) | componentDidMount() {
    method render (line 388) | render() {

FILE: src/module/common.jsx
  class CommonOpt (line 15) | class CommonOpt extends React.Component {
    method sync (line 25) | sync() {
    method import (line 133) | import() {
    method export (line 190) | export() {
    method oldnewsites (line 199) | oldnewsites() {
    method newsites (line 207) | newsites() {
    method clear (line 223) | clear() {
    method importsecret (line 240) | importsecret( state, secret, callback ) {
    method componentDidMount (line 246) | componentDidMount() {
    method render (line 257) | render() {

FILE: src/module/common/editor.jsx
  class Editor (line 19) | class Editor extends React.Component {
    method changeName (line 30) | changeName( value, code ) {
    method changeURL (line 36) | changeURL( value, code ) {
    method changeTitle (line 42) | changeTitle( event ) {
    method changeDesc (line 59) | changeDesc( event ) {
    method changeInclude (line 72) | changeInclude( value, code ) {
    method changeExclude (line 78) | changeExclude( value, code ) {
    method changeAvatar (line 84) | changeAvatar( idx, type, value ) {
    method changePaging (line 97) | changePaging( idx, type, value ) {
    method changeCSS (line 110) | changeCSS( event ) {
    method render (line 115) | render() {

FILE: src/module/common/exclude.jsx
  class Exclude (line 6) | class Exclude extends React.Component {
    method changeExclude (line 20) | changeExclude( event ) {
    method render (line 30) | render() {
  function getExclude (line 70) | function getExclude( htmls ) {

FILE: src/module/common/include.jsx
  class Include (line 6) | class Include extends React.Component {
    method changeInclude (line 22) | changeInclude( event ) {
    method render (line 37) | render() {

FILE: src/module/common/name.jsx
  class Name (line 9) | class Name extends React.Component {
    method changeName (line 15) | changeName( event ) {
    method render (line 35) | render() {

FILE: src/module/common/shortcuts.jsx
  class Shortcuts (line 7) | class Shortcuts extends React.Component {
    method changeShortcuts (line 15) | changeShortcuts( event ) {
    method componentDidMount (line 39) | componentDidMount() {
    method render (line 44) | render() {
  function updateShortcuts (line 64) | function updateShortcuts( id ) {
  function verifyShortkey (line 91) | function verifyShortkey( key ) {
  function fixKey (line 105) | function fixKey( event ) {

FILE: src/module/common/theme.jsx
  class ThemeSel (line 3) | class ThemeSel extends React.Component {
    method changeBgColor (line 5) | changeBgColor( event ) {
    method componentDidMount (line 21) | componentDidMount() {
    method render (line 25) | render() {
  function setBgThemeStyle (line 40) | function setBgThemeStyle( theme ) {

FILE: src/module/common/url.jsx
  class URL (line 7) | class URL extends React.Component {
    method changeURL (line 21) | changeURL( event ) {
    method render (line 43) | render() {

FILE: src/module/enhancesite.jsx
  function loadingState (line 22) | function loadingState( state, str ) {
  function getService (line 47) | function getService( method ) {
  function fail (line 58) | function fail( xhr, textStatus, error ) {
  function getSites (line 68) | function getSites( sites ) {
  function editorEmptyRender (line 80) | function editorEmptyRender() {
  function siteinfoEmptyRender (line 87) | function siteinfoEmptyRender() {
  function siteinfoRender (line 94) | function siteinfoRender() {
  function sitesRender (line 106) | function sitesRender() {
  class Sites (line 117) | class Sites extends React.Component {
    method onChange (line 119) | onChange( value, name ) {
    method render (line 138) | render() {
  class SiteInfo (line 148) | class SiteInfo extends React.Component {
    method onChange (line 150) | onChange( id, event ) {
    method onDropdownChange (line 154) | onDropdownChange( value ) {
    method render (line 158) | render() {
  class Import (line 205) | class Import extends React.Component {
    method onSecretChange (line 211) | onSecretChange( event ) {
    method login (line 215) | login() {
    method getSites (line 235) | getSites( uid, id ) {
    method insert (line 254) | insert( method, site ) {
    method delete (line 283) | delete( id ) {
    method update (line 304) | update() {
    method remove (line 354) | remove() {
    method permit (line 369) | permit() {
    method logout (line 399) | logout() {
    method render (line 403) | render() {

FILE: src/module/feedback.jsx
  class Feedback (line 10) | class Feedback extends React.Component {
    method onStarClick (line 38) | onStarClick( idx ) {
    method onStarHover (line 49) | onStarHover( idx ) {
    method onRateClick (line 53) | onRateClick() {
    method onURLChange (line 62) | onURLChange( event ) {
    method onAnonymousChange (line 66) | onAnonymousChange( value ) {
    method onChangeMode (line 70) | onChangeMode( mode ) {
    method onClose (line 74) | onClose() {
    method onSubmitClick (line 83) | onSubmitClick() {
    method onGithubClick (line 87) | onGithubClick() {
    method onTucaoClick (line 125) | onTucaoClick() {
    method render (line 145) | render() {
  function Render (line 232) | function Render( version, user, rate = false ) {

FILE: src/module/focus.jsx
  class FocusOpt (line 11) | class FocusOpt extends React.Component {
    method changeBgColor (line 13) | changeBgColor( bgcolor, $target ) {
    method changeOpacity (line 19) | changeOpacity( value ) {
    method changeShortcuts (line 26) | changeShortcuts( shortcuts ) {
    method render (line 31) | render() {

FILE: src/module/guide.jsx
  class Guide (line 10) | class Guide extends React.Component {
    method onClick (line 24) | onClick( event, idx, url, detail ) {
    method onLoadingClick (line 47) | onLoadingClick() {
    method componentWillMount (line 68) | componentWillMount() {
    method componentDidUpdate (line 74) | componentDidUpdate() {
    method componentDidMount (line 78) | componentDidMount() {
    method render (line 92) | render() {
  function start (line 123) | function start( id, verify = true, detail = {} ) {

FILE: src/module/keyboard.js
  function render (line 18) | function render( $target ) {
  function task (line 41) | function task( key ) {
  function listenESC (line 52) | function listenESC( callback ) {
  function listen (line 68) | function listen( callback ) {
  function bind (line 106) | function bind( combo, callback ) {
  function openLink (line 126) | function openLink() {
  function openLinkEventHander (line 139) | function openLinkEventHander( event ) {
  function removeOpenLink (line 171) | function removeOpenLink() {
  function openLinkExist (line 178) | function openLinkExist() {
  function keyboradmap (line 186) | function keyboradmap() {
  function removeHelp (line 219) | function removeHelp() {
  function helpExist (line 223) | function helpExist() {

FILE: src/module/labs.jsx
  class LabsOpt (line 13) | class LabsOpt extends React.Component {
    method onChange (line 28) | onChange( value, model, state, child ) {
    method changeExclusion (line 42) | changeExclusion( event ) {
    method changeWhitelist (line 47) | changeWhitelist( event ) {
    method changeLazyload (line 52) | changeLazyload( event ) {
    method tocState (line 57) | tocState( value ) {
    method cleanupState (line 61) | cleanupState( value ) {
    method lazyloadState (line 65) | lazyloadState( value ) {
    method exclusionState (line 69) | exclusionState( value ) {
    method blacklist (line 74) | blacklist( event ) {
    method componentDidMount (line 79) | componentDidMount() {
    method onClick (line 86) | onClick( state ) {
    method render (line 91) | render() {

FILE: src/module/notice.jsx
  class Notice (line 23) | class Notice extends React.Component {
    method onClick (line 44) | onClick( event, id ) {
    method onReadallClick (line 61) | onReadallClick() {
    method onLoadmoreClick (line 72) | onLoadmoreClick() {
    method componentWillMount (line 76) | componentWillMount() {
    method componentDidMount (line 95) | componentDidMount() {
    method render (line 99) | render() {
  class List (line 151) | class List extends React.Component {
    method onClick (line 163) | onClick( event, id ) {
    method onActive (line 169) | onActive( event, id ) {
    method render (line 175) | render() {

FILE: src/module/pluginbar.jsx
  class Pluginbar (line 7) | class Pluginbar extends React.Component {
    method getCategory (line 15) | getCategory() {
    method enable (line 27) | enable( id ) {
    method componentWillMount (line 39) | componentWillMount() {
    method render (line 46) | render() {

FILE: src/module/plugins.jsx
  class Card (line 12) | class Card extends React.Component {
    method update (line 22) | update() {
    method delete (line 35) | delete() {
    method enable (line 44) | enable() {
    method addmore (line 49) | addmore() {
    method render (line 53) | render() {
  class Cards (line 95) | class Cards extends React.Component {
    method render (line 106) | render() {
  class PluginsOpt (line 118) | class PluginsOpt extends React.Component {
    method writecb (line 124) | writecb() {
    method install (line 128) | install() {
    method clear (line 159) | clear() {
    method addmore (line 174) | addmore() {
    method update (line 178) | update() {
    method import (line 205) | import() {
    method onChange (line 234) | onChange( type ) {
    method componentWillMount (line 244) | componentWillMount() {
    method render (line 254) | render() {

FILE: src/module/read.jsx
  class ReadOpt (line 22) | class ReadOpt extends React.Component {
    method parse (line 24) | parse( value ) {
    method changeBgColor (line 29) | changeBgColor( theme ) {
    method changeShortcuts (line 36) | changeShortcuts( shortcuts ) {
    method changeFontfamily (line 42) | changeFontfamily( name, value ) {
    method changeFontsize (line 53) | changeFontsize( value ) {
    method changeLayout (line 60) | changeLayout( value ) {
    method changeStyle (line 67) | changeStyle( value, type ) {
    method render (line 78) | render() {

FILE: src/module/setting.jsx
  class Modals (line 26) | class Modals extends React.Component {
    method close (line 29) | close( restore = rollback() ) {
    method save (line 34) | save() {
    method siteeditor (line 50) | siteeditor() {
    method constructor (line 55) | constructor( props ) {
    method componentDidMount (line 59) | componentDidMount() {
    method render (line 64) | render() {
  function rollback (line 87) | function rollback() {
  function Render (line 104) | function Render( cb ) {
  function Exist (line 115) | function Exist() {
  function Exit (line 122) | function Exit() {

FILE: src/module/sharecard.jsx
  class ShareCard (line 8) | class ShareCard extends React.Component {
    method download (line 10) | download() {
    method exit (line 17) | exit() {
    method componentWillUnmount (line 21) | componentWillUnmount() {
    method render (line 25) | render() {
  function Render (line 53) | function Render( root, title, txt ) {

FILE: src/module/sitebar.jsx
  class Sitebar (line 8) | class Sitebar extends React.Component {
    method active (line 34) | active( obj ) {
    method componentWillMount (line 56) | componentWillMount() {
    method render (line 69) | render() {

FILE: src/module/siteeditor.jsx
  class SiteEditor (line 23) | class SiteEditor extends React.Component {
    method close (line 25) | close() {
    method action (line 29) | action( type ) {
    method delete (line 40) | delete() {
    method save (line 57) | save() {
    method submit (line 85) | submit() {
    method componentDidMount (line 91) | componentDidMount() {
    method render (line 96) | render() {
  function Render (line 126) | function Render() {
  function Exist (line 144) | function Exist() {
  function Exit (line 151) | function Exit() {

FILE: src/module/sites.jsx
  class Card (line 12) | class Card extends React.Component {
    method update (line 22) | update() {
    method delete (line 26) | delete() {
    method addmore (line 41) | addmore() {
    method render (line 45) | render() {
  class Cards (line 76) | class Cards extends React.Component {
    method onChange (line 86) | onChange( type ) {
    method render (line 92) | render() {
  class SitesOpts (line 104) | class SitesOpts extends React.Component {
    method newsites (line 106) | newsites() {
    method onClick (line 123) | onClick( state ) {
    method changeOrigins (line 127) | changeOrigins() {
    method origins (line 133) | origins( type ) {
    method onChange (line 185) | onChange( type ) {
    method clear (line 189) | clear() {
    method addmore (line 206) | addmore() {
    method install (line 210) | install() {
    method update (line 257) | update() {
    method pending (line 288) | pending() {
    method temp (line 303) | temp() {
    method componentWillMount (line 318) | componentWillMount() {
    method render (line 325) | render() {

FILE: src/module/unrdist.jsx
  class Unrdist (line 33) | class Unrdist extends React.Component {
    method onAction (line 61) | onAction( event, ...rests ) {
    method onClick (line 93) | onClick() {
    method render (line 98) | render() {

FILE: src/module/urlscheme.jsx
  method onDropdownChange (line 37) | onDropdownChange( value ) {
  method onURLChange (line 41) | onURLChange( event ) {
  method onOpenedChange (line 58) | onOpenedChange( value ) {
  method onClose (line 62) | onClose() {
  method onSave (line 71) | onSave() {

FILE: src/module/welcome.jsx
  class Welcome (line 100) | class Welcome extends React.Component {
    method prevClick (line 107) | prevClick() {
    method nextClick (line 111) | nextClick() {
    method closeClick (line 117) | closeClick() {
    method carousel (line 122) | carousel() {
    method componentDidMount (line 130) | componentDidMount() {
    method componentWillUnmount (line 155) | componentWillUnmount() {
    method render (line 159) | render() {
  function exit (line 364) | function exit() {
  function Render (line 377) | function Render( root, first, version ) {

FILE: src/options/custom.js
  function navRender (line 50) | function navRender() {
  function setPreviewStyle (line 61) | function setPreviewStyle() {
  function propertyRender (line 72) | function propertyRender() {

FILE: src/options/notice.js
  function navRender (line 35) | function navRender() {
  function noticeRender (line 46) | function noticeRender() {

FILE: src/options/options.js
  function tabChange (line 104) | function tabChange( idx ) {
  function loadingRender (line 134) | function loadingRender() {
  function pRead (line 148) | function pRead() {
  function updateData (line 157) | function updateData() {
  function hashnotify (line 169) | function hashnotify() {
  function vernotify (line 195) | function vernotify( first ) {
  function firstLoad (line 231) | function firstLoad( first ) {
  function welcomeRender (line 249) | function welcomeRender( first, version ) {
  function mainRender (line 258) | function mainRender( idx ) {
  function tabsRender (line 270) | function tabsRender( color ) {
  function navRender (line 339) | function navRender() {
  function sidebarRender (line 351) | function sidebarRender() {
  function noticeRender (line 379) | function noticeRender() {
  function helpRender (line 417) | function helpRender() {
  function feedbackRender (line 445) | function feedbackRender() {

FILE: src/options/sitemgr.js
  function changeSiteinfo (line 59) | function changeSiteinfo( info ) {
  function navRender (line 69) | function navRender() {
  function controlbarRender (line 80) | function controlbarRender() {
  function siteeditorRender (line 201) | function siteeditorRender( url, site, type, info ) {
  function formatsites (line 222) | function formatsites( sites ) {
  function verify (line 233) | function verify() {

FILE: src/read/controlbar.jsx
  class ReadCtlbar (line 35) | class ReadCtlbar extends React.Component {
    method verify (line 41) | verify( type ) {
    method componentDidMount (line 47) | componentDidMount() {
    method onAction (line 63) | onAction( event, type ) {
    method onChange (line 128) | onChange( type, custom ) {
    method onPop (line 135) | onPop( type ) {
    method componentWillMount (line 139) | componentWillMount() {
    method constructor (line 201) | constructor( props ) {
    method render (line 205) | render() {

FILE: src/read/progressbar.jsx
  class ProcessBar (line 3) | class ProcessBar extends React.Component {
    method componentDidMount (line 14) | componentDidMount() {
    method componentWillUnmount (line 20) | componentWillUnmount() {
    method scrollEventHandle (line 24) | scrollEventHandle() {
    method render (line 29) | render() {

FILE: src/read/read.jsx
  class Read (line 59) | class Read extends React.Component {
    method verifyContent (line 61) | verifyContent() {
    method componentWillMount (line 103) | componentWillMount() {
    method componentDidMount (line 113) | async componentDidMount() {
    method componentWillUnmount (line 160) | componentWillUnmount() {
    method onAction (line 179) | onAction( type, value, custom ) {
    method exit (line 243) | exit() {
    method render (line 247) | render() {
  function Render (line 278) | function Render( callMathjax = true ) {
  function Highlight (line 294) | function Highlight() {
  function Exist (line 308) | function Exist( action ) {
  function Exit (line 320) | function Exit() {
  function mathJaxMode (line 332) | function mathJaxMode() {
  function getReadRoot (line 363) | function getReadRoot() {
  function excludes (line 376) | function excludes( $target, exclude ) {
  function loadPlugins (line 386) | function loadPlugins( state ) {

FILE: src/read/special.jsx
  class Multiple (line 9) | class Multiple extends React.Component {
    method render (line 16) | render() {
  class Paging (line 45) | class Paging extends React.Component {
    method onClick (line 56) | onClick( state ) {
    method componentDidMount (line 60) | componentDidMount() {
    method render (line 66) | render() {

FILE: src/read/toc.jsx
  class TOC (line 5) | class TOC extends React.Component {
    method onClick (line 7) | onClick( event ) {
    method componentDidMount (line 33) | componentDidMount() {
    method render (line 71) | render() {
  function Render (line 97) | function Render( root, $target, theme, hidden ) {

FILE: src/service/browser.js
  class Browser (line 21) | class Browser {
    method adapter (line 28) | get adapter() {
    method type (line 44) | get type() {
    method constructor (line 48) | constructor( type ) {
    method isFirefox (line 57) | isFirefox() {

FILE: src/service/export.js
  function png (line 22) | function png( element, name, callback ) {
  function pdf (line 36) | function pdf() {
  function markdown (line 47) | function markdown( data, name, callback ) {
  function epub (line 69) | function epub( data, url, title, desc, callback ) {
  function download (line 96) | function download( data, name ) {
  function prueDownload (line 108) | function prueDownload( data, name ) {
  function unlink (line 124) | function unlink( id ) {
  class Dropbox (line 148) | class Dropbox {
    method id (line 150) | get id()   { return "dropbox"; }
    method name (line 151) | get name() { return name( this.id ); }
    method client_id (line 153) | get client_id() {
    method redirect_uri (line 157) | get redirect_uri() {
    method config_name (line 161) | get config_name() {
    method New (line 165) | New() {
    method Auth (line 171) | Auth() {
    method Accesstoken (line 176) | Accesstoken( url ) {
    method Exist (line 183) | Exist( name, callback ) {
    method Read (line 205) | Read( name, callback ) {
    method Write (line 224) | Write( name, data, callback, path = "" ) {
  class Pocket (line 261) | class Pocket {
    method id (line 263) | get id()   { return "pocket"; }
    method name (line 264) | get name() { return name( this.id ); }
    method consumer_key (line 266) | get consumer_key() {
    method redirect_uri (line 270) | get redirect_uri() {
    method header (line 274) | get header() {
    method New (line 281) | New() {
    method Request (line 289) | Request( callback ) {
    method Login (line 308) | Login( code ) {
    method Accesstoken (line 314) | Accesstoken( url ) {
    method Auth (line 318) | Auth( callback ) {
    method Add (line 341) | Add( url, title, callback ) {
  class Ins (line 370) | class Ins {
    method id (line 372) | get id()   { return "instapaper"; }
    method name (line 373) | get name() { return name( this.id ); }
    method constructor (line 374) | constructor() {
    method consumer_key (line 380) | get consumer_key() {
    method consumer_secret (line 384) | get consumer_secret() {
    method Login (line 388) | Login( username, password, callback ) {
    method Add (line 401) | Add( url, title, description, callback ) {
  class Linnk (line 419) | class Linnk {
    method id (line 421) | get id()   { return "linnk"; }
    method name (line 422) | get name() { return name( this.id ); }
    method constructor (line 423) | constructor() {
    method error_code (line 429) | get error_code() {
    method tags (line 439) | get tags() {
    method Login (line 443) | Login( username, password, callback ) {
    method Add (line 462) | Add( url, title, callback ) {
    method Groups (line 485) | Groups( callback ) {
    method GetGroup (line 501) | GetGroup( name, target ) {
    method NewGroup (line 507) | NewGroup( name, callback ) {
    method GetSafeGroup (line 521) | GetSafeGroup( name, callback ) {
  class Evernote (line 539) | class Evernote {
    method id (line 541) | get id()   { return this.env.toLowerCase(); }
    method name (line 542) | get name() { return name( this.env ); }
    method constructor (line 544) | constructor() {
    method host (line 553) | get host() {
    method server (line 561) | get server() {
    method china (line 566) | get china() {
    method headers (line 570) | get headers() {
    method New (line 578) | New() {
    method RequestToken (line 587) | RequestToken( callback ) {
    method Accesstoken (line 608) | Accesstoken( url ) {
    method Auth (line 616) | Auth( callback ) {
    method Add (line 642) | Add( title, content, callback ) {
  class Onenote (line 670) | class Onenote {
    method id (line 672) | get id()   { return "onenote"; }
    method name (line 673) | get name() { return name( this.id ); }
    method client_id (line 675) | get client_id() {
    method client_secret (line 679) | get client_secret() {
    method redirect_uri (line 683) | get redirect_uri() {
    method scopes (line 688) | get scopes() {
    method New (line 692) | New() {
    method Wrapper (line 699) | Wrapper( url, title, content ) {
    method Login (line 717) | Login() {
    method Accesstoken (line 732) | Accesstoken( url ) {
    method Auth (line 742) | Auth( callback ) {
    method Add (line 769) | Add( html, callback ) {
  class GDrive (line 794) | class GDrive {
    method id (line 796) | get id()   { return "gdrive"; }
    method name (line 797) | get name() { return name( this.id ); }
    method client_id (line 799) | get client_id() {
    method redirect_uri (line 803) | get redirect_uri() {
    method scope (line 807) | get scope() {
    method folder (line 811) | get folder() {
    method header (line 818) | get header() {
    method errors (line 825) | get errors() {
    method boundary (line 833) | get boundary() {
    method New (line 837) | New() {
    method Login (line 844) | Login() {
    method Accesstoken (line 861) | Accesstoken( url ) {
    method Auth (line 868) | Auth( callback ) {
    method CreateFolder (line 882) | CreateFolder( callback ) {
    method CreateFile (line 901) | CreateFile( name, content ) {
    method Add (line 927) | Add( type, callback, content ) {
  class Jianguo (line 956) | class Jianguo {
    method id (line 958) | get id()   { return "jianguo"; }
    method name (line 959) | get name() { return name( this.id ); }
    method url (line 961) | get url() {
    method root (line 965) | get root() {
    method folder (line 969) | get folder() {
    method config_name (line 973) | get config_name() {
    method Auth (line 977) | Auth( user, password, callback ) {
    method Add (line 990) | Add( user, password, path, content, callback ) {
    method Read (line 1003) | Read( user, password, name, callback ) {
  class WebDAV (line 1022) | class WebDAV {
    method id (line 1024) | get id()   { return "webdav"; }
    method name (line 1025) | get name() { return name( this.id ); }
    method root (line 1027) | get root() {
    method Auth (line 1031) | Auth( url, user, password, callback ) {
    method Add (line 1043) | Add( url, user, password, name, content, callback ) {
  class Yuque (line 1063) | class Yuque {
    method id (line 1065) | get id()   { return "yuque"; }
    method name (line 1066) | get name() { return name( this.id ); }
    method client_id (line 1068) | get client_id() {
    method client_secret (line 1072) | get client_secret() {
    method redirect_uri (line 1076) | get redirect_uri() {
    method scopes (line 1081) | get scopes() {
    method New (line 1085) | New() {
    method Login (line 1095) | Login() {
    method Accesstoken (line 1111) | Accesstoken( url ) {
    method Auth (line 1121) | Auth( callback ) {
    method GetUser (line 1146) | GetUser( callback ) {
    method GetRepos (line 1164) | GetRepos( callback ) {
    method CreateRepo (line 1186) | CreateRepo( callback ) {
    method Add (line 1212) | Add( title, body, callback ) {
  class Notion (line 1242) | class Notion {
    method id (line 1244) | get id()   { return "notion"; }
    method name (line 1245) | get name() { return name( this.id ); }
    method url (line 1247) | get url() {
    method hasWriteRule (line 1251) | hasWriteRule(role){
    method getBlockName (line 1255) | getBlockName(titleArray){
    method UUID (line 1262) | UUID() {
    method getBlocks (line 1267) | getBlocks( result ) {
    method getFirstBlock (line 1355) | getFirstBlock( result ) {
    method Auth (line 1368) | Auth( callback ) {
    method MathImages (line 1402) | MathImages( content ) {
    method DonwloadOriginImage (line 1417) | DonwloadOriginImage( url ) {
    method UploadOriginImage (line 1430) | UploadOriginImage({ type, size, url }) {
    method UploadImages (line 1454) | async UploadImages( content ) {
    method Add (line 1500) | async Add( title, content, callback ) {
    method TempFile (line 1522) | TempFile( parentId, title, callback ) {
    method GetFileUrl (line 1627) | GetFileUrl( name, callback, option = { bucket: 'temporary', contentTyp...
    method WriteFile (line 1642) | WriteFile( url, content, callback ) {
    method ImportFile (line 1659) | ImportFile( url, name, documentId, callback ) {
    method GetCollectionData (line 1698) | GetCollectionData( callback ) {
    method AddCollectionUrlSchema (line 1715) | AddCollectionUrlSchema( collection, callback ) {
    method CheckQueueTask (line 1772) | CheckQueueTask( taskId, callback ) {
    method SetProperties (line 1795) | SetProperties( documentId, callback ) {
    method Save (line 1815) | Save( storage ) {
  class Youdao (line 1828) | class Youdao {
    method id (line 1830) | get id()   { return "youdao"; }
    method name (line 1831) | get name() { return name( this.id ); }
    method url (line 1833) | get url() {
    method permissions (line 1837) | get permissions() {
    method UUID (line 1844) | UUID() {
    method Cookies (line 1849) | Cookies( callback ) {
    method Auth (line 1858) | Auth( callback ) {
    method Add (line 1891) | Add( title, content, callback ) {
  class Wiz (line 1927) | class Wiz {
    method id (line 1929) | get id()   { return "weizhi"; }
    method name (line 1930) | get name() { return name( this.id ); }
    method tag (line 1932) | get tag() {
    method category (line 1936) | get category() {
    method Auth (line 1940) | Auth( user, password, callback ) {
    method Add (line 1962) | Add( url, title, content, callback ) {
  class Kindle (line 1998) | class Kindle {
    method constructor (line 2000) | constructor() {
    method host (line 2004) | get host() {
    method server (line 2009) | get server() {
    method Read (line 2013) | Read( url, title, desc, content, style, callback ) {
    method Temp (line 2035) | Temp() {
    method Send (line 2041) | Send() {
  function name (line 2054) | function name( type ) {
  function mdWrapper (line 2082) | function mdWrapper( content, name, notify ) {
  function md2HTML (line 2096) | function md2HTML( content ) {
  function serviceCallback (line 2114) | function serviceCallback( result, error, name, type, notify ) {
  function verifyService (line 2135) | function verifyService( storage, service, type, name, notify, auto = tru...

FILE: src/service/highlight.js
  function start (line 10) | function start() {
  function multi (line 48) | function multi( callback ) {
  function annotate (line 77) | function annotate() {
  function controlbar (line 103) | function controlbar( dom ) {

FILE: src/service/local.js
  constant NAMES (line 3) | const id    = "simpread",
  constant MAX_COUNT (line 3) | const id    = "simpread",
  class Local (line 19) | class Local {
    method curcount (line 21) | get curcount() {
    method Count (line 30) | Count() {
    method Firstload (line 47) | Firstload() {
    method Version (line 62) | Version( version ) {
    method Patch (line 71) | Patch( state, value ) {
  function get (line 84) | function get( key ) {
  function set (line 94) | function set( key, value ) {
  function remove (line 103) | function remove( key ) {

FILE: src/service/menu.js
  function onClicked (line 42) | function onClicked( callback ) {
  function createAll (line 49) | function createAll() {
  function create (line 90) | function create( type ) {
  function remove (line 106) | function remove( type ) {
  function update (line 122) | function update( type ) {
  function refresh (line 134) | function refresh( cur ) {

FILE: src/service/message.js
  function add (line 67) | function add( type, value = {} ) {

FILE: src/service/offline.js
  function HTML (line 18) | function HTML( title, desc, content, styles ) {
  function Markdown (line 81) | function Markdown( content, callback ) {
  function getImages (line 106) | function getImages( callback ) {
  function serialConvert (line 128) | function serialConvert( url ) {
  function setBase64 (line 154) | function setBase64( url, uri ) {
  function toBase64 (line 170) | function toBase64( url, callback ) {
  function restoreImg (line 191) | function restoreImg() {

FILE: src/service/output.js
  function action (line 27) | function action( type, title, desc, content ) {
  function corbLoader (line 424) | function corbLoader( state, callback ) {

FILE: src/service/permission.js
  function Get (line 4) | function Get( permissions, callback ) {
  function Remove (line 12) | function Remove( permissions, callback ) {

FILE: src/service/runtime.js
  function generateID (line 17) | function generateID( type ) {
  function install (line 39) | function install( id, url, callback ) {
  function dispatch (line 54) | function dispatch( type, value ) {
  function exec (line 65) | function exec( state, site, plugin ) {
  function func (line 83) | function func( source ) {
  function Storage (line 104) | function Storage( id, data, callback ) {
  function Controlbar (line 122) | function Controlbar( type, callback ) {
  function Save (line 137) | function Save( data, callback ) {
  function addStyle (line 158) | function addStyle( str ) {
  function addTrigger (line 167) | function addTrigger( str ) {
  function testPlugin (line 193) | function testPlugin( style, plugin, trigger ) {

FILE: src/service/snapshot.js
  function start (line 5) | function start() {
  function remove (line 34) | function remove() {
  function controlbar (line 38) | function controlbar() {

FILE: src/service/storage.js
  class Storage (line 277) | class Storage {
    method option (line 284) | get option() {
    method focus (line 293) | get focus() {
    method read (line 302) | get read() {
    method current (line 311) | get current() {
    method unrdist (line 331) | get unrdist() {
    method notice (line 340) | get notice() {
    method version (line 349) | get version() {
    method patch (line 358) | get patch() {
    method simpread (line 367) | get simpread() {
    method statistics (line 376) | get statistics() {
    method user (line 385) | get user() {
    method secret (line 394) | get secret() {
    method plugins (line 403) | get plugins() {
    method sites (line 412) | get sites() {
    method websites (line 426) | get websites() {
    method puread (line 435) | set puread( value ) {
    method puread (line 444) | get puread() {
    method service (line 453) | get service() {
    method notice_service (line 463) | get notice_service() {
    method help_service (line 475) | get help_service() {
    method Read (line 484) | Read( callback ) {
    method ReadAsync (line 505) | ReadAsync( callback ) {
    method WriteAsync (line 539) | WriteAsync( simp, sec, plugs ) {
    method Write (line 558) | Write( callback, new_val = undefined ) {
    method Writesite (line 569) | Writesite( sites, callback ) {
    method Getcur (line 577) | Getcur( key, site ) {
    method Setcur (line 592) | Setcur( key ) {
    method VerifyCur (line 602) | VerifyCur( type ) {
    method Compare (line 614) | Compare( type ) {
    method GetRemote (line 637) | async GetRemote( type, callback ) {
    method Statistics (line 674) | Statistics( type, service, state = "write" ) {
    method UnRead (line 722) | UnRead( type, args, callback, state = "write" ) {
    method Verify (line 773) | Verify( data = undefined ) {
    method Safe (line 820) | Safe( callback, data ) {
    method Notice (line 855) | Notice( callback, data ) {
    method Plugins (line 879) | Plugins( callback, data ) {
    method Export (line 900) | Export() {
    method Restore (line 921) | Restore( key ) {
    method Clear (line 932) | Clear( state, callback ) {
    method Fix (line 944) | Fix( target, curver, newver, source ) {
  function swap (line 980) | function swap( source, target ) {
  function clone (line 995) | function clone( target ) {
  function save (line 1005) | function save( callback, no_update ) {
  function now (line 1021) | function now() {
  function getURI (line 1032) | function getURI() {

FILE: src/service/stylesheet.js
  function iconPath (line 16) | function iconPath( name ) {
  function getColor (line 26) | function getColor( value ) {
  function backgroundColor (line 42) | function backgroundColor( bgcolor, opacity ) {
  function opacity (line 55) | function opacity( opacity ) {
  function fontFamily (line 72) | function fontFamily( family ) {
  function fontSize (line 81) | function fontSize( value ) {
  function layout (line 94) | function layout( width ) {
  function custom (line 104) | function custom( type, props ) {
  function css (line 145) | function css( type, styles ) {
  function siteCSS (line 159) | function siteCSS( styles ) {
  function preview (line 170) | function preview( styles ) {
  function vfyCustom (line 183) | function vfyCustom( type, styles ) {
  function getCustomCSS (line 200) | function getCustomCSS() {
  function specialCSS (line 214) | function specialCSS( mathjax, callback ) {

FILE: src/service/theme.js
  class Theme (line 26) | class Theme {
    method colors (line 33) | get colors() {
    method names (line 42) | get names() {
    method theme (line 51) | get theme() {
    method Change (line 60) | Change( theme ) {
    method Get (line 69) | Get( theme ) {
    method GetAll (line 73) | GetAll() {
    method constructor (line 77) | constructor() {
  function findThemeStyle (line 90) | function findThemeStyle( callback ) {
  function tocTheme (line 113) | function tocTheme( theme ) {

FILE: src/service/tips.js
  function Render (line 12) | function Render( plugins ) {
  function Help (line 49) | function Help( statistics ) {
  function Verify (line 64) | function Verify( id, callback ) {
  function Done (line 76) | function Done( id ) {

FILE: src/service/util.js
  function verifyHtml (line 12) | function verifyHtml( html ) {
  function specTest (line 36) | function specTest( content ) {
  function html2enml (line 48) | function html2enml( html, url ) {
  function md2enml (line 121) | function md2enml( result ) {
  function multi2enml (line 134) | function multi2enml( str ) {
  function clearMD (line 148) | function clearMD( str, header = true ) {
  function clearHTML (line 165) | function clearHTML( str ) {
  function exclusion (line 186) | function exclusion( minimatch, data ) {
  function whitelist (line 204) | function whitelist( minimatch, data ) {
  function blacklist (line 222) | function blacklist( minimatch, data ) {
  function lazyload (line 239) | function lazyload( minimatch, data ) {
  function getPageInfo (line 254) | function getPageInfo() {

FILE: src/service/version.js
  function Verify (line 339) | function Verify( curver, data ) {
  function Incompatible (line 503) | function Incompatible( ver, data ) {
  function Notify2 (line 524) | function Notify2( first, type, ver ) {
  function SilentUpdate (line 534) | function SilentUpdate() {
  function Compare (line 545) | function Compare( target ) {
  function FixSubver (line 564) | function FixSubver( patch, target ) {
  function VerifyPlugins (line 583) | function VerifyPlugins( option ) {

FILE: src/service/watch.js
  function message (line 19) | function message( type, value ) {
  function push (line 29) | function push( type, value ) {
  function pull (line 38) | function pull( tabid ) {
  function lock (line 48) | function lock( url ) {
  function verify (line 67) | function verify( callback ) {
  function getCurAllTabs (line 79) | function getCurAllTabs( type ) {

FILE: src/vender/carousel/carousel.js
  function setupEvents (line 113) | function setupEvents() {
  function xpos (line 126) | function xpos(e) {
  function ypos (line 136) | function ypos(e) {
  function wrap (line 146) | function wrap(x) {
  function scroll (line 150) | function scroll(x) {
  function track (line 279) | function track() {
  function autoScroll (line 292) | function autoScroll() {
  function click (line 307) | function click(e) {
  function cycleTo (line 327) | function cycleTo(n) {
  function tap (line 349) | function tap(e) {
  function drag (line 364) | function drag(e) {
  function release (line 399) | function release(e) {

FILE: src/vender/instapaper.js
  class Instapaper (line 10) | class Instapaper {
    method generateNonce (line 17) | generateNonce() {
    method getUTCtimestamp (line 29) | getUTCtimestamp() {
    method authTemplate (line 35) | authTemplate(req) {
    method sigBaseTemplate (line 47) | sigBaseTemplate(req) {
    method makeSigningKey (line 75) | makeSigningKey() {
    method makeSignature (line 86) | makeSignature(req) {
    method makeRequestObject (line 94) | makeRequestObject(options) {
    method request (line 112) | request(options) {
    method requestToken (line 140) | requestToken(user, password) {
    method verifyCredentials (line 178) | verifyCredentials() {
    method bookmarkList (line 189) | bookmarkList() {
    method add (line 195) | add( url, title, description ) {

FILE: src/vender/mduikit/autocomplete.jsx
  class ListView (line 212) | class ListView extends React.Component {
    method onMouseOver (line 229) | onMouseOver( event ) {
    method onClick (line 237) | onClick( event ) {
    method render (line 241) | render() {
  class AC (line 288) | class AC extends React.Component {
    method onTextKeyDown (line 332) | onTextKeyDown( event ) {
    method onTextChangeFocus (line 363) | onTextChangeFocus( event ) {
    method onTextChangeBlur (line 372) | onTextChangeBlur( event ) {
    method onTextChange (line 381) | onTextChange( event ) {
    method onDropdownClick (line 392) | onDropdownClick( event ) {
    method onDropdownChange (line 402) | onDropdownChange( name, value ) {
    method filter (line 409) | filter( value ) {
    method componentDidMount (line 415) | componentDidMount() {
    method render (line 419) | render() {

FILE: src/vender/mduikit/button.jsx
  class Button (line 163) | class Button extends React.Component {
    method onMouseOver (line 214) | onMouseOver() {
    method onMouseOut (line 219) | onMouseOut() {
    method onClick (line 225) | onClick( event ) {
    method componentWillMount (line 229) | componentWillMount() {
    method render (line 235) | render() {

FILE: src/vender/mduikit/dialog.jsx
  class Dialog (line 93) | class Dialog extends React.Component {
    method componentDidMount (line 105) | componentDidMount() {
    method componentWillUnmount (line 113) | componentWillUnmount() {
    method render (line 117) | render() {
  function getRoot (line 154) | function getRoot( $target, cls ) {
  function Open (line 168) | function Open( reactDom, cls, $target = $("html") ) {
  function Close (line 175) | function Close() {
  function Popup (line 191) | function Popup( clsjq ) {

FILE: src/vender/mduikit/dropdown.jsx
  class ListView (line 192) | class ListView extends React.Component {
    method onMouseOver (line 209) | onMouseOver( event ) {
    method onClick (line 217) | onClick( event ) {
    method render (line 223) | render() {
  class Dropdown (line 263) | class Dropdown extends React.Component {
    method onClick (line 288) | onClick() {
    method bgOnClick (line 293) | bgOnClick() {
    method onChange (line 298) | onChange( value, name ) {
    method render (line 307) | render() {

FILE: src/vender/mduikit/fab.jsx
  class Fab (line 223) | class Fab extends React.Component {
    method btnClickHandler (line 247) | btnClickHandler( event ) {
    method btnMouseOverHandler (line 252) | btnMouseOverHandler( event ) {
    method btnMouseOutHandler (line 268) | btnMouseOutHandler( event ) {
    method fabMouseOutHandler (line 281) | fabMouseOutHandler( event ) {
    method liMouseLeaveHandler (line 287) | liMouseLeaveHandler( event ) {
    method componentWillMount (line 297) | componentWillMount() {
    method componentDidMount (line 310) | componentDidMount() {
    method componentWillUnmount (line 324) | componentWillUnmount() {
    method render (line 331) | render() {

FILE: src/vender/mduikit/fap.jsx
  class Panel (line 213) | class Panel extends React.Component {
    method onTabChange (line 232) | onTabChange( event ) {
    method autoHeight (line 257) | autoHeight() {
    method offsetHeight (line 269) | offsetHeight() {
    method componentDidMount (line 279) | componentDidMount() {
    method componentWillUnmount (line 286) | componentWillUnmount() {
    method render (line 290) | render() {
  class Fap (line 397) | class Fap extends React.Component {
    method btnClickHandler (line 436) | btnClickHandler( event ) {
    method btnMouseOverHandler (line 441) | btnMouseOverHandler( event ) {
    method btnMouseOutHandler (line 453) | btnMouseOutHandler( event ) {
    method panelBgEventHandler (line 463) | panelBgEventHandler( event ) {
    method panelRender (line 476) | panelRender( $panelbg ) {
    method onPop (line 484) | onPop( type ) {
    method render (line 488) | render() {

FILE: src/vender/mduikit/list.jsx
  class List (line 406) | class List extends React.Component {
    method acIconOnClick (line 447) | acIconOnClick( event ) {
    method acBgOnClick (line 453) | acBgOnClick( event ) {
    method acItemOnClick (line 460) | acItemOnClick( event, data ) {
    method acItemMouseOver (line 471) | acItemMouseOver( event ) {
    method priOnClick (line 481) | priOnClick( event, data ) {
    method secOnClick (line 485) | secOnClick( event, data ) {
    method render (line 489) | render() {

FILE: src/vender/mduikit/progress.jsx
  class Progress (line 28) | class Progress extends React.Component {
    method componentDidMount (line 45) | componentDidMount() {
    method shouldComponentUpdate (line 57) | shouldComponentUpdate() {
    method componentWillUnmount (line 64) | componentWillUnmount() {
    method render (line 68) | render() {

FILE: src/vender/mduikit/selectfield.jsx
  class ListView (line 270) | class ListView extends React.Component {
    method onMouseOver (line 287) | onMouseOver( event ) {
    method onClick (line 295) | onClick( event ) {
    method render (line 301) | render() {
  class SelectField (line 344) | class SelectField extends React.Component {
    method onClick (line 377) | onClick() {
    method bgOnClick (line 382) | bgOnClick() {
    method onChange (line 387) | onChange( value, name ) {
    method componentDidMount (line 396) | componentDidMount() {
    method render (line 403) | render() {

FILE: src/vender/mduikit/sidebar.jsx
  class Sidebar (line 291) | class Sidebar extends React.Component {
    method onClick (line 335) | onClick( event ) {
    method liOnClick (line 345) | liOnClick( event ) {
    method maskOnClick (line 378) | maskOnClick( event ) {
    method render (line 393) | render() {
  function Open (line 474) | function Open() {
  function tocRender (line 489) | function tocRender() {
  function activeRender (line 529) | function activeRender() {

FILE: src/vender/mduikit/slider.jsx
  class Slider (line 247) | class Slider extends React.Component {
    method lineWidth (line 291) | lineWidth( value ) {
    method onTextChangeFocus (line 297) | onTextChangeFocus( event ) {
    method onTextChangeBlur (line 304) | onTextChangeBlur( event ) {
    method onTextChange (line 311) | onTextChange( event ) {
    method onMouseUp (line 337) | onMouseUp( event ) {
    method onChange (line 343) | onChange( event ) {
    method componentWillMount (line 352) | componentWillMount() {
    method componentDidMount (line 357) | componentDidMount() {
    method render (line 364) | render() {

FILE: src/vender/mduikit/statebutton.jsx
  class SVG (line 243) | class SVG extends React.Component {
    method componentWillMount (line 260) | componentWillMount() {
    method render (line 265) | render() {
  class StateButton (line 312) | class StateButton extends React.Component {
    method changeStateStyle (line 382) | changeStateStyle() {
    method changeState (line 399) | changeState( state ) {
    method onMouseOver (line 405) | onMouseOver() {
    method onMouseOut (line 414) | onMouseOut() {
    method onClick (line 419) | onClick( event ) {
    method componentWillMount (line 424) | componentWillMount() {
    method render (line 430) | render() {

FILE: src/vender/mduikit/switch.jsx
  class Switch (line 174) | class Switch extends React.Component {
    method onClick (line 213) | onClick() {
    method componentWillReceiveProps (line 220) | componentWillReceiveProps( nextProps ) {
    method render (line 224) | render() {

FILE: src/vender/mduikit/tabs.jsx
  class Tabs (line 227) | class Tabs extends React.Component {
    method componentWillUnmount (line 256) | componentWillUnmount() {
    method tabLabelOnClick (line 260) | tabLabelOnClick( event ) {
    method render (line 298) | render() {

FILE: src/vender/mduikit/textfield.jsx
  class TextField (line 215) | class TextField extends React.Component {
    method changeFocus (line 250) | changeFocus() {
    method changeBlur (line 255) | changeBlur() {
    method change (line 266) | change( event ) {
    method changeKeyDown (line 270) | changeKeyDown( event ) {
    method componentWillUpdate (line 274) | componentWillUpdate( nextProps ) {
    method componentWillMount (line 290) | componentWillMount() {
    method componentDidMount (line 309) | componentDidMount() {
    method render (line 313) | render() {
  function setjQueryObj (line 357) | function setjQueryObj( obj ) {
  function changeState (line 370) | function changeState( style, errortext ) {

FILE: src/vender/mduikit/tooltip.jsx
  class ToolTip (line 97) | class ToolTip extends React.Component {
    method onMouseEnter (line 119) | onMouseEnter() {
    method onMouseLeave (line 194) | onMouseLeave() {
    method onScroll (line 214) | onScroll() {
    method componentDidMount (line 220) | componentDidMount() {
    method componentWillUnmount (line 226) | componentWillUnmount() {
    method render (line 232) | render() {
  function Render (line 253) | function Render( root, id, is_mini = true ) {
  function Exit (line 282) | function Exit( root, id ) {
  function getTooltipRoot (line 297) | function getTooltipRoot( $root, id ) {

FILE: src/vender/mduikit/waves.js
  function Render (line 33) | function Render( options ) {

FILE: src/vender/notify/notify.js
  function Notify (line 289) | function Notify() {

FILE: src/vender/sha1.js
  function n (line 12) | function n(c,b,f){var a=0,d=[0],e="",g=null,e=f||"UTF8";if("UTF8"!==e&&"...
  function x (line 15) | function x(c,b){var f=[],a,d=[],e=0,g,k,q;if("UTF8"===b)for(g=0;g<c.leng...
  function w (line 16) | function w(c){var b=[],f=c.length,a,d,e;if(0!==
  function z (line 17) | function z(c){var b=[],f,a,d;for(a=0;a<c.length;a+=1)f=c.charCodeAt(a),d...
  function y (line 17) | function y(c){var b=[],f=0,a,d,e,g,k;if(-1===c.search(/^[a-zA-Z0-9=+\/]+...
  function A (line 18) | function A(c,b){var f="",a=4*c.length,d,e;for(d=0;d<a;d+=1)e=c[d>>>2]>>>...
  function B (line 19) | function B(c,b){var f="",a=4*c.length,d,e,g;for(d=0;d<a;d+=3)for(g=d+1>>...
  function C (line 19) | function C(c){var b="",f=4*c.length,a,d;for(a=0;a<f;a+=1)d=c[a>>>2]>>>
  function D (line 20) | function D(c){var b={outputUpper:!1,b64Pad:"="};try{c.hasOwnProperty("ou...
  function r (line 20) | function r(c,b){return c<<b|c>>>32-b}
  function t (line 20) | function t(c,b){var f=(c&65535)+(b&65535);return((c>>>16)+(b>>>16)+(f>>>...
  function v (line 21) | function v(c,b,f,a,d){var e=(c&65535)+(b&65535)+(f&65535)+(a&65535)+(d&6...
  function u (line 21) | function u(c,b){var f=[],a,d,e,g,k,q,n,l,u,h=[1732584193,4023233417,2562...

FILE: src/vender/turndown/turndown-plugin-gfm.js
  function highlightedCodeBlock (line 6) | function highlightedCodeBlock (turndownService) {
  function strikethrough (line 30) | function strikethrough (turndownService) {
  function isHeadingRow (line 98) | function isHeadingRow (tr) {
  function isFirstTbody (line 110) | function isFirstTbody (element) {
  function cell (line 123) | function cell (content, node) {
  function tables (line 130) | function tables (turndownService) {
  function taskListItems (line 137) | function taskListItems (turndownService) {
  function gfm (line 148) | function gfm (turndownService) {

FILE: src/vender/turndown/turndown.js
  function extend (line 4) | function extend (destination) {
  function repeat (line 14) | function repeat (character, count) {
  function isBlock (line 27) | function isBlock (node) {
  function isVoid (line 36) | function isVoid (node) {
  function hasVoid (line 41) | function hasVoid (node) {
  function Rules (line 294) | function Rules (options) {
  function findRule (line 350) | function findRule (rules, node, options) {
  function filterValue (line 358) | function filterValue (rule, node, options) {
  function collapseWhitespace (line 403) | function collapseWhitespace (options) {
  function remove (line 475) | function remove (node) {
  function next (line 492) | function next (prev, current, isPre) {
  function canParseHTMLNatively (line 510) | function canParseHTMLNatively () {
  function createHTMLParser (line 526) | function createHTMLParser () {
  function shouldUseActiveX (line 552) | function shouldUseActiveX () {
  function RootNode (line 564) | function RootNode (input) {
  function htmlParser (line 588) | function htmlParser () {
  function Node (line 593) | function Node (node) {
  function isBlank (line 601) | function isBlank (node) {
  function flankingWhitespace (line 610) | function flankingWhitespace (node) {
  function isFlankedByWhitespace (line 629) | function isFlankedByWhitespace (side, node) {
  function TurndownService (line 672) | function TurndownService (options) {
  function process (line 805) | function process (parentNode) {
  function postProcess (line 829) | function postProcess (output) {
  function replacementForNode (line 848) | function replacementForNode (node) {
  function separatingNewlines (line 869) | function separatingNewlines (output, replacement) {
  function join (line 878) | function join (string1, string2) {
  function canConvert (line 896) | function canConvert (input) {

FILE: src/vender/waves/waves.js
  function isWindow (line 41) | function isWindow(obj) {
  function getWindow (line 45) | function getWindow(elem) {
  function isObject (line 49) | function isObject(value) {
  function isDOMNode (line 54) | function isDOMNode(obj) {
  function getWavesElements (line 58) | function getWavesElements(nodes) {
  function offset (line 72) | function offset(elem) {
  function convertStyle (line 89) | function convertStyle(styleObj) {
  function removeRipple (line 250) | function removeRipple(e, el, ripple) {
  function getWavesEffectElement (line 357) | function getWavesEffectElement(e) {
  function showEffect (line 380) | function showEffect(e) {

FILE: src/vender/wiz.js
  function getParams (line 80) | function getParams( url, title, htmlStr ) {
  function getInfos (line 105) | function getInfos( info, access_token ) {
Condensed preview — 137 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,394K chars).
[
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yaml",
    "chars": 1069,
    "preview": "name: 🐛 提交 Bug\ndescription: 请提交你的 Bug\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        谢谢帮忙提交 Bug 这会让简悦变得"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 2465,
    "preview": "blank_issues_enabled: false\ncontact_links:\n  - name: 🆘 当升级 Chrome 后无法使用简悦的解决方案\n    url: https://www.yuque.com/kenshin/si"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.yml",
    "chars": 416,
    "preview": "name: ✨ 功能建议或改善\ndescription: 你的建议会让简悦变得更好\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        你的每个想法都是对简悦最大的"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/new_site.yml",
    "chars": 504,
    "preview": "name: 🔗 新站适配\ndescription: 提交需要适配的站点\nlabels: [\"new site\"]\nbody:\n  - type: markdown\n    attributes:\n      value: |\n       "
  },
  {
    "path": ".github/ISSUE_TEMPLATE/yinxiang_code.yml",
    "chars": 427,
    "preview": "name: 🚑 印象笔记或代码高亮问题\ndescription: 关于印象笔记或代码高亮的集中反馈渠道\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        谢谢帮忙"
  },
  {
    "path": ".gitignore",
    "chars": 258,
    "preview": "# for common\r\nnode_modules/**\r\npublish/**\r\n.vscode/**\r\n\r\n# for chrome\r\nsrc/bundle/**\r\n\r\n# for firefox\r\next/website_list."
  },
  {
    "path": "LICENSE",
    "chars": 35146,
    "preview": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
  },
  {
    "path": "README.md",
    "chars": 11932,
    "preview": "<p align=\"center\"><img src=\"http://sr.ksria.cn/logo%20bigger.png\" /></p>\n<h1 align=\"center\">简悦<sup>1.0</sup> - SimpRead<"
  },
  {
    "path": "ext/background.js",
    "chars": 12136,
    "preview": "console.log( \"=== simpread background load ===\" )\r\n\r\nimport local       from 'local';\r\nimport { storage } from 'storage'"
  },
  {
    "path": "ext/contentscripts.js",
    "chars": 10197,
    "preview": "console.log( \"=== simpread contentscripts load ===\" )\r\n\r\nimport './assets/css/simpread.css';\r\nimport './assets/css/optio"
  },
  {
    "path": "ext/manifest.json",
    "chars": 1722,
    "preview": "{\r\n  \"name\"            : \"__MSG_extension_name__\",\r\n  \"default_locale\"  : \"zh_CN\",\r\n  \"version\"         : \"1.1.2.1025\",\r"
  },
  {
    "path": "npmw.cmd",
    "chars": 1631,
    "preview": "::===========================================================\r\n:: SimpRead : SimpRead development/publish environment\r\n:"
  },
  {
    "path": "package.json",
    "chars": 1812,
    "preview": "{\n  \"name\": \"simpread_project_workflow\",\n  \"version\": \"1.0.0\",\n  \"description\": \"SimpRead develop/deploy\",\n  \"author\": \""
  },
  {
    "path": "src/_locales/en/messages.json",
    "chars": 660,
    "preview": "{\r\n    \"extension_name\": {\r\n        \"message\": \"SimpRead - Reader View\",\r\n        \"description\": \"similar to Safari read"
  },
  {
    "path": "src/_locales/zh_CN/messages.json",
    "chars": 536,
    "preview": "{\r\n    \"extension_name\": {\r\n        \"message\": \"简悦 - SimpRead\",\r\n        \"description\": \"类似 Safari 阅读模式的 Chrome 扩展,阅读模式,"
  },
  {
    "path": "src/_locales/zh_TW/messages.json",
    "chars": 545,
    "preview": "{\r\n    \"extension_name\": {\r\n        \"message\": \"簡悅 - SimpRead\",\r\n        \"description\": \"類似 Safari 閱讀模式的 Chrome 擴展,閱讀模式,"
  },
  {
    "path": "src/assets/css/options_custom.css",
    "chars": 599,
    "preview": "\n.header {\n    background-color: rgb(63, 81, 181);\n    opacity: 1;\n    visibility: visible;\n}\n\n.custom {\n    position: r"
  },
  {
    "path": "src/assets/css/options_notice.css",
    "chars": 4513,
    "preview": ".header {\n    background-color: #16666f;\n    opacity: 1;\n    visibility: visible;\n}\n\n.notice {\n    margin-top: 65px;\n   "
  },
  {
    "path": "src/assets/css/options_page.css",
    "chars": 17118,
    "preview": "/**\r\n * Options page style\r\n */\r\n\r\n:root {\r\n  --text-color: #333;\r\n  --secondary-color: color(#333 alpha(-30%));\r\n  --ba"
  },
  {
    "path": "src/assets/css/options_sitemgr.css",
    "chars": 2010,
    "preview": "\r\n.hide {\r\n    display: none;\r\n}\r\n\r\n.row {\r\n    display: flex;\r\n    flex-direction: row;\r\n}\r\n\r\n.space {\r\n    width: 30px"
  },
  {
    "path": "src/assets/css/setting.css",
    "chars": 1662,
    "preview": "\n/**\n *  Setting: Focus/Read setting dailog\n*/\n\nsr-opt-focus,\nsr-opt-read {\n    display: -webkit-flex;\n    flex-directio"
  },
  {
    "path": "src/assets/css/simpread.css",
    "chars": 20687,
    "preview": "/**\r\n * SimpRead: Read mode\r\n */\r\n\r\n.simpread-font {\r\n    font: 300 16px/1.8 -apple-system, PingFang SC, Microsoft Yahei"
  },
  {
    "path": "src/assets/css/theme_common.css",
    "chars": 5977,
    "preview": "/**\r\n * Common style, include:\r\n * .simpread-theme-root\r\n * sr-rd-title, sr-rd-desc, sr-rd-content, p, div, a, img, pre,"
  },
  {
    "path": "src/assets/css/theme_dark.css",
    "chars": 2516,
    "preview": "sr-rd-theme-dark{display:none;}\n\n/**\n * Dark style\n */\n\n/**\n * Common style, include: h1 ~ h6; ol ul; code pre; table; s"
  },
  {
    "path": "src/assets/css/theme_engwrite.css",
    "chars": 2889,
    "preview": "sr-rd-theme-engwrite{display:none;}\n\n/**\n * EngWrite style\n */\n\n/**\n * Common style, include: h1 ~ h6; ol ul; code pre; "
  },
  {
    "path": "src/assets/css/theme_github.css",
    "chars": 2993,
    "preview": "sr-rd-theme-github{display:none;}\n\n/**\n * Github style\n */\n\n/**\n * Common style, include: h1 ~ h6; ol ul; code pre; tabl"
  },
  {
    "path": "src/assets/css/theme_gothic.css",
    "chars": 3337,
    "preview": "sr-rd-theme-gothic{display:none;}\r\n\r\n/**\r\n * Gothic style\r\n */\r\n\r\n/**\r\n * Common style, include: h1 ~ h6; ol ul; code pr"
  },
  {
    "path": "src/assets/css/theme_mobile.css",
    "chars": 4228,
    "preview": "/**\n * Mobile media\n */\n@media (pointer:coarse) {\n    sr-read {\n        margin: 20px 5%!important;\n        min-width: in"
  },
  {
    "path": "src/assets/css/theme_monospace.css",
    "chars": 2430,
    "preview": "sr-rd-theme-monospace{display:none;}\n\n/**\n * Monospace style\n */\n\n/**\n * Common style, include: h1 ~ h6; ol ul; code pre"
  },
  {
    "path": "src/assets/css/theme_newsprint.css",
    "chars": 2791,
    "preview": "sr-rd-theme-newsprint{display:none;}\n\n/**\n * Newsprint style\n */\n\n/**\n * Common style, include: h1 ~ h6; ol ul; code pre"
  },
  {
    "path": "src/assets/css/theme_night.css",
    "chars": 2867,
    "preview": "sr-rd-theme-night{display:none;}\n\n/**\n * Night style\n */\n\n/**\n * Common style, include: h1 ~ h6; ol ul; code pre; table;"
  },
  {
    "path": "src/assets/css/theme_octopress.css",
    "chars": 26982,
    "preview": "sr-rd-theme-octopress{display:none;}\n\n/**\n * Octopress style\n */\n\n/**\n * Common style, include: h1 ~ h6; ol ul; code pre"
  },
  {
    "path": "src/assets/css/theme_pixyii.css",
    "chars": 3347,
    "preview": "sr-rd-theme-pixyii{display:none;}\n\n/**\n * Pixyii style\n */\n\n/**\n * Common style, include: h1 ~ h6; ol ul; code pre; tabl"
  },
  {
    "path": "src/background.js",
    "chars": 18443,
    "preview": "console.log( \"=== simpread background load ===\" )\r\n\r\nimport local       from 'local';\r\nimport { storage } from 'storage'"
  },
  {
    "path": "src/contentscripts.js",
    "chars": 12477,
    "preview": "console.log( \"=== simpread contentscripts load ===\" )\r\n\r\nimport './assets/css/simpread.css';\r\nimport './assets/css/setti"
  },
  {
    "path": "src/focus/controlbar.jsx",
    "chars": 4879,
    "preview": "console.log( \"=== simpread focus controlbar load ===\" )\n\nimport * as setting   from 'setting';\nimport * as se        fro"
  },
  {
    "path": "src/focus/focus.js",
    "chars": 7408,
    "preview": "console.log( \"=== simpread focus load ===\" );\n\nvar storage  = require( \"storage\" ).storage,\n    util     = require( \"uti"
  },
  {
    "path": "src/ga.js",
    "chars": 661,
    "preview": "\n/**\n * Track using the asynchronous tracking API.\n *\n * See http://code.google.com/apis/analytics/docs/tracking/asyncTr"
  },
  {
    "path": "src/help_tips.json",
    "chars": 1905,
    "preview": "{\n    \"tips\": [\n        {\n            \"idx\": 0,\n            \"name\": \"文档中心\",\n            \"icon\": \"<i class=\\\"fas fa-info-"
  },
  {
    "path": "src/manifest.json",
    "chars": 1710,
    "preview": "{\r\n  \"name\"            : \"__MSG_extension_name__\",\r\n  \"default_locale\"  : \"en\",\r\n  \"version\"         : \"1.1.4.6025\",\r\n  "
  },
  {
    "path": "src/module/about.jsx",
    "chars": 19939,
    "preview": "console.log( \"===== simpread option about load =====\" )\r\n\r\nimport {br,browser} from 'browser';\r\n\r\nconst style = {\r\n\r\n   "
  },
  {
    "path": "src/module/account.jsx",
    "chars": 6527,
    "preview": "console.log( \"===== simpread option account load =====\" )\n\nimport {storage} from 'storage';\nimport * as ss   from 'style"
  },
  {
    "path": "src/module/actionbar.jsx",
    "chars": 1685,
    "preview": "console.log( \"=== simpread action bar load ===\" )\r\n\r\nimport * as ss     from 'stylesheet';\r\n\r\nimport Button      from 'b"
  },
  {
    "path": "src/module/authorize.jsx",
    "chars": 34690,
    "preview": "console.log( \"===== simpread option labs:Authorize load =====\" )\r\n\r\nimport {storage} from 'storage';\r\nimport * as exp  f"
  },
  {
    "path": "src/module/common/editor.jsx",
    "chars": 8048,
    "preview": "console.log( \"===== simpread option editor load =====\" )\r\n\r\nimport { verifyHtml } from 'util';\r\n\r\nimport TextField      "
  },
  {
    "path": "src/module/common/exclude.jsx",
    "chars": 2303,
    "preview": "console.log( \"===== simpread option common: exclude =====\" )\r\n\r\nimport { verifyHtml } from 'util';\r\nimport TextField    "
  },
  {
    "path": "src/module/common/include.jsx",
    "chars": 1339,
    "preview": "console.log( \"===== simpread option common: Include =====\" )\r\n\r\nimport { verifyHtml } from 'util';\r\nimport TextField    "
  },
  {
    "path": "src/module/common/name.jsx",
    "chars": 1205,
    "preview": "console.log( \"===== simpread option common: Name =====\" )\n\nimport { storage } from 'storage';\n\nimport TextField   from '"
  },
  {
    "path": "src/module/common/shortcuts.jsx",
    "chars": 3533,
    "preview": "console.log( \"===== simpread option common: Shortcuts =====\" )\r\n\r\nimport TextField from 'textfield';\r\n\r\nlet [ shortcuts,"
  },
  {
    "path": "src/module/common/theme.jsx",
    "chars": 1686,
    "preview": "console.log( \"===== simpread option common: ThemeSel =====\" )\r\n\r\nexport default class ThemeSel extends React.Component {"
  },
  {
    "path": "src/module/common/url.jsx",
    "chars": 1749,
    "preview": "console.log( \"===== simpread option common: URL =====\" )\n\nimport * as puplugin from 'puplugin';\n\nimport TextField from '"
  },
  {
    "path": "src/module/common.jsx",
    "chars": 14982,
    "preview": "console.log( \"===== simpread option common load =====\" )\r\n\r\nimport Button      from 'button';\r\nimport Notify      from '"
  },
  {
    "path": "src/module/enhancesite.jsx",
    "chars": 16104,
    "preview": "console.log( \"===== simpread option enhancesite load =====\" )\n\nimport TextField   from 'textfield';\nimport Button      f"
  },
  {
    "path": "src/module/feedback.jsx",
    "chars": 20616,
    "preview": "console.log( \"===== simpread feedback load =====\" )\n\nimport Switch    from 'switch';\nimport TextField from 'textfield';\n"
  },
  {
    "path": "src/module/focus.jsx",
    "chars": 2044,
    "preview": "console.log( \"===== simpread option focus mode load =====\" )\r\n\r\nimport ThemeSel  from 'themesel';\r\nimport Shortcuts from"
  },
  {
    "path": "src/module/guide.jsx",
    "chars": 6203,
    "preview": "console.log( \"===== simpread option guide load =====\" )\r\n\r\nimport intro              from 'intro';\r\n\r\nimport {browser}  "
  },
  {
    "path": "src/module/keyboard.js",
    "chars": 7481,
    "preview": "console.log( \"=== simpread keyboard ===\" )\n\nimport Mousetrap   from 'mousetrap';\n\nimport {browser}   from 'browser';\nimp"
  },
  {
    "path": "src/module/labs.jsx",
    "chars": 21754,
    "preview": "console.log( \"===== simpread option labs load =====\" )\n\nimport {browser} from 'browser';\nimport * as menu from 'menu';\ni"
  },
  {
    "path": "src/module/notice.jsx",
    "chars": 10280,
    "preview": "console.log( \"=== simpread notice load ===\" )\n\nimport {storage}     from 'storage';\nimport th            from 'theme';\ni"
  },
  {
    "path": "src/module/pluginbar.jsx",
    "chars": 2802,
    "preview": "console.log( \"=== simpread plugin bar load ===\" )\n\nimport {storage} from 'storage';\n\nimport Button    from 'button';\n\nex"
  },
  {
    "path": "src/module/plugins.jsx",
    "chars": 13629,
    "preview": "console.log( \"===== simpread option plugins load =====\" )\n\nimport {storage} from 'storage';\nimport * as run  from 'runti"
  },
  {
    "path": "src/module/read.jsx",
    "chars": 5755,
    "preview": "console.log( \"===== simpread option read mode load =====\" )\n\nimport th             from 'theme';\nimport * as ss        f"
  },
  {
    "path": "src/module/setting.jsx",
    "chars": 3718,
    "preview": "console.log( \"=== simpread option setting ===\" )\r\n\r\nimport FocusOpt     from 'focusopt';\r\nimport ReadOpt      from 'read"
  },
  {
    "path": "src/module/sharecard.jsx",
    "chars": 2374,
    "preview": "console.log( \"=== simpread share card load ===\" )\r\n\r\nimport * as exp from 'export';\r\nimport * as ss  from 'stylesheet';\r"
  },
  {
    "path": "src/module/sitebar.jsx",
    "chars": 3587,
    "preview": "console.log( \"=== simpread site bar load ===\" )\n\nimport {storage} from 'storage';\nimport * as watch from 'watch';\n\nimpor"
  },
  {
    "path": "src/module/siteeditor.jsx",
    "chars": 6102,
    "preview": "console.log( \"=== simpread option siteeditor load ===\" )\r\n\r\nimport { storage }  from 'storage';\r\nimport * as watch   fro"
  },
  {
    "path": "src/module/sites.jsx",
    "chars": 18681,
    "preview": "console.log( \"===== simpread option sites load =====\" )\n\nimport {storage}  from 'storage';\nimport {browser}  from 'brows"
  },
  {
    "path": "src/module/unrdist.jsx",
    "chars": 6090,
    "preview": "console.log( \"===== simpread option unread list load =====\" )\n\nimport List      from 'list';\nimport Button    from 'butt"
  },
  {
    "path": "src/module/urlscheme.jsx",
    "chars": 4452,
    "preview": "console.log( \"===== simpread url scheme load =====\" )\n\nimport Switch    from 'switch';\nimport TextField from 'textfield'"
  },
  {
    "path": "src/module/welcome.jsx",
    "chars": 19088,
    "preview": "console.log( \"===== simpread option welcome page load =====\" )\n\nimport 'carous_css';\nimport 'carousel';\n\nimport Button  "
  },
  {
    "path": "src/options/corb.html",
    "chars": 145,
    "preview": "<html>\n<script src=\"../bundle/common.js\"></script>\n<script src=\"../bundle/vendors.js\"></script>\n<script src=\"../bundle/c"
  },
  {
    "path": "src/options/corb.js",
    "chars": 2822,
    "preview": "\nimport axios      from 'axios';\n\nimport {browser}  from 'browser';\nimport * as msg   from 'message';\n\n/**\n * Listen run"
  },
  {
    "path": "src/options/custom.html",
    "chars": 4671,
    "preview": "<html>\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    "
  },
  {
    "path": "src/options/custom.js",
    "chars": 15864,
    "preview": "console.log( \"==== simpread options page: custom load ====\" )\n\nimport '../assets/css/simpread.css';\nimport '../assets/cs"
  },
  {
    "path": "src/options/notice.html",
    "chars": 816,
    "preview": "<html>\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    "
  },
  {
    "path": "src/options/notice.js",
    "chars": 1412,
    "preview": "console.log( \"==== simpread options page: notice load ====\" )\n\nimport '../assets/css/simpread.css';\nimport '../assets/cs"
  },
  {
    "path": "src/options/options.html",
    "chars": 1346,
    "preview": "<html>\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n"
  },
  {
    "path": "src/options/options.js",
    "chars": 21763,
    "preview": "console.log( \"==== simpread options page load ====\" )\r\n\r\nimport '../assets/css/options_page.css';\r\nimport '../assets/css"
  },
  {
    "path": "src/options/sitemgr.html",
    "chars": 1363,
    "preview": "<html>\r\n    <head>\r\n        <meta charset=\"UTF-8\">\r\n        <meta name=\"viewport\" content=\"width=device-width, initial-s"
  },
  {
    "path": "src/options/sitemgr.js",
    "chars": 10766,
    "preview": "console.log( \"==== simpread options page: sitemanager load ====\" )\r\n\r\nimport '../assets/css/simpread.css';\r\nimport '../a"
  },
  {
    "path": "src/read/controlbar.jsx",
    "chars": 9919,
    "preview": "console.log( \"=== simpread read controlbar load ===\" )\n\nimport * as ss     from 'stylesheet';\nimport {browser,br}from 'b"
  },
  {
    "path": "src/read/progressbar.jsx",
    "chars": 1049,
    "preview": "console.log( \"==== simpread read component: ProcessBar ====\" )\n\nexport default class ProcessBar extends React.Component "
  },
  {
    "path": "src/read/read.jsx",
    "chars": 17105,
    "preview": "console.log( \"=== simpread read load ===\" )\n\nimport ProgressBar        from 'schedule';\nimport * as spec          from '"
  },
  {
    "path": "src/read/special.jsx",
    "chars": 3627,
    "preview": "console.log( \"=== simpread read: special load ===\" )\r\n\r\nimport Button    from 'button';\r\n\r\nimport * as kbd  from 'keyboa"
  },
  {
    "path": "src/read/toc.jsx",
    "chars": 4096,
    "preview": "console.log( \"=== simpread read toc load ===\" )\n\nlet is_click = false;\n\nclass TOC extends React.Component {\n\n    onClick"
  },
  {
    "path": "src/service/browser.js",
    "chars": 1306,
    "preview": "console.log( \"=== simpread browser load ===\" )\r\n\r\nconst mode = {\r\n    chrome : \"chrome\",\r\n    sogou  : \"sogouExplorer\",\r"
  },
  {
    "path": "src/service/config.js",
    "chars": 21280,
    "preview": "console.log( \"=== simpread config load ===\" )\n\nimport * as ss from 'stylesheet';\n\nconst keyboard = {\n    \"控制栏 - 导出\" : {\n"
  },
  {
    "path": "src/service/export.js",
    "chars": 72572,
    "preview": "console.log( \"=== simpread export load ===\" )\n\nimport domtoimage from 'dom2image';\nimport FileSaver  from 'filesaver';\ni"
  },
  {
    "path": "src/service/highlight.js",
    "chars": 8243,
    "preview": "console.log( \"=== simpread highlight load ===\" )\r\n\r\nconst highlight_class = \"simpread-highlight-selector\";\r\n\r\n/**\r\n * Hi"
  },
  {
    "path": "src/service/local.js",
    "chars": 2121,
    "preview": "console.log( \"=== simpread local load ===\" )\n\nconst id    = \"simpread\",\n      NAMES = {\n        VER   : \"version\",\n     "
  },
  {
    "path": "src/service/menu.js",
    "chars": 4657,
    "preview": "console.log( \"=== simpread menu load ===\" )\n\nimport {storage} from 'storage';\nimport {browser} from 'browser';\nimport * "
  },
  {
    "path": "src/service/message.js",
    "chars": 2050,
    "preview": "console.log( \"=== simpread message load ===\" )\r\n\r\nconst action = {\r\n    focus_mode     : \"focus\",\r\n    read_mode      : "
  },
  {
    "path": "src/service/offline.js",
    "chars": 7761,
    "preview": "console.log( \"=== simpread offline load ===\" )\n\nimport {browser}   from 'browser';\nimport * as msg    from 'message';\n\nl"
  },
  {
    "path": "src/service/output.js",
    "chars": 23995,
    "preview": "console.log( \"=== simpread output load ===\" )\r\n\r\nimport * as util   from 'util';\r\nimport * as exp    from 'export';\r\nimp"
  },
  {
    "path": "src/service/permission.js",
    "chars": 514,
    "preview": "\nimport {browser} from 'browser';\n\nfunction Get( permissions, callback ) {\n    browser.permissions.contains({ permission"
  },
  {
    "path": "src/service/runtime.js",
    "chars": 6302,
    "preview": "console.log( \"=== simpread runtime load ===\" )\n\nimport nanoid           from 'nanoid';\n\nimport {browser}        from 'br"
  },
  {
    "path": "src/service/snapshot.js",
    "chars": 4284,
    "preview": "console.log( \"=== simpread snapshot load ===\" )\n\nlet dtd, startPos, endPos, dragStart = false, position;\n\nfunction start"
  },
  {
    "path": "src/service/storage.js",
    "chars": 31462,
    "preview": "console.log( \"=== simpread storage load ===\" )\r\n\r\nimport \"babel-polyfill\";\r\n\r\nimport {browser, br}  from 'browser';\r\nimp"
  },
  {
    "path": "src/service/stylesheet.js",
    "chars": 6830,
    "preview": "console.log( \"=== simpread stylesheet load ===\" )\n\n/**\n * Clone from puread/plugin/stylesheet.js except iconPath\n */\n\nim"
  },
  {
    "path": "src/service/theme.js",
    "chars": 3064,
    "preview": "console.log( \"=== simpread theme load ===\" )\r\n\r\nconst names  = [ \"github\", \"newsprint\", \"gothic\", \"engwrite\", \"octopress"
  },
  {
    "path": "src/service/tips.js",
    "chars": 2876,
    "preview": "console.log( \"=== simpread tips load ===\" )\n\nimport Notify      from 'notify';\nimport * as msg    from 'message';\nimport"
  },
  {
    "path": "src/service/util.js",
    "chars": 11788,
    "preview": "console.log( \"=== simpread util load ===\" )\n\n/**\n * Verify html from puread/util verifyHtml()\n * \n * @param  {string} in"
  },
  {
    "path": "src/service/version.js",
    "chars": 26567,
    "preview": "console.log( \"=== simpread version load ===\" )\r\n\r\nimport {browser} from 'browser';\r\n\r\n/**\r\n * Manifest.json version\r\n */"
  },
  {
    "path": "src/service/watch.js",
    "chars": 2238,
    "preview": "console.log( \"=== simpread watch load ===\" )\n\nimport * as msg    from 'message';\nimport {br,browser}from 'browser';\n\ncon"
  },
  {
    "path": "src/vender/carousel/carousel.css",
    "chars": 1479,
    "preview": "/*\n * Carousel\n * http://materializecss.com/carousel.html\n * \n * https://github.com/Dogfalo/materialize/blob/master/LICE"
  },
  {
    "path": "src/vender/carousel/carousel.js",
    "chars": 16208,
    "preview": "/*\n * Carousel\n * http://materializecss.com/carousel.html\n * \n * https://github.com/Dogfalo/materialize/blob/master/LICE"
  },
  {
    "path": "src/vender/instapaper.js",
    "chars": 7733,
    "preview": "// Instapaper xAuth API for client side JS. Depends on cross-domain requests.\n// Reference: <http://www.instapaper.com/a"
  },
  {
    "path": "src/vender/mduikit/autocomplete.jsx",
    "chars": 15345,
    "preview": "/*!\n * React Material Design: AutoComplete\n * \n * @version : 0.0.1\n * @update  : 2018/04/23\n * @homepage: https://github"
  },
  {
    "path": "src/vender/mduikit/button.jsx",
    "chars": 9243,
    "preview": "/*!\n * React Material Design: Button\n * \n * @version : 0.0.4.1231\n * @update  : 2019/12/31\n * @homepage: https://github."
  },
  {
    "path": "src/vender/mduikit/dialog.jsx",
    "chars": 4814,
    "preview": "/*!\r\n * React Material Design: Dialog\r\n * \r\n * @version : 0.0.3\r\n * @update  : 2018/03/15\r\n * @homepage: https://github."
  },
  {
    "path": "src/vender/mduikit/dropdown.jsx",
    "chars": 9873,
    "preview": "/*!\n * React Material Design: Dropdown\n * \n * @version : 0.0.3\n * @update  : 2018/06/27\n * @homepage: https://github.com"
  },
  {
    "path": "src/vender/mduikit/fab.jsx",
    "chars": 13593,
    "preview": "/*!\n * React Material Design: FAB( Floating Action Button )\n * \n * @version : 0.0.3.0109\n * @update  : 2020/01/09\n * @ho"
  },
  {
    "path": "src/vender/mduikit/fap.jsx",
    "chars": 17164,
    "preview": "/*!\n * React Material Design: FAP( Floating Action Panel )\n * \n * @version : 0.0.1.1231\n * @update  : 2018/04/19\n * @hom"
  },
  {
    "path": "src/vender/mduikit/list.jsx",
    "chars": 15854,
    "preview": "/*!\n * React Material Design: List\n * \n * @version : 0.0.3.0116\n * @update  : 2020/01/16\n * @homepage: https://github.co"
  },
  {
    "path": "src/vender/mduikit/mduikit.css",
    "chars": 2801,
    "preview": "/*!\n * React Material Design Style\n * \n * @version : 0.0.1\n * @update  : 2019/12/29\n * @homepage: https://github.com/ken"
  },
  {
    "path": "src/vender/mduikit/mintooltip.css",
    "chars": 8430,
    "preview": "/**\n * From https://kazzkiq.github.io/balloon.css/\n */\n:root{--balloon-color: rgba(16,16,16,0.95);--balloon-font-size: 1"
  },
  {
    "path": "src/vender/mduikit/progress.jsx",
    "chars": 2311,
    "preview": "/*!\r\n * React Material Design: Progress\r\n * \r\n * @version : 0.0.1\r\n * @update  : 2017/05/10\r\n * @homepage: https://githu"
  },
  {
    "path": "src/vender/mduikit/selectfield.jsx",
    "chars": 13838,
    "preview": "/*!\r\n * React Material Design: SelectField\r\n * \r\n * @version : 0.0.3\r\n * @update  : 2018/04/26\r\n * @homepage: https://gi"
  },
  {
    "path": "src/vender/mduikit/sidebar.jsx",
    "chars": 17597,
    "preview": "/*!\n * React Material Design: Sidebar\n * \n * @version : 0.0.4.0104\n * @update  : 2019/12/30\n * @homepage: https://github"
  },
  {
    "path": "src/vender/mduikit/slider.jsx",
    "chars": 14019,
    "preview": "/*!\r\n * React Material Design: Slider\r\n * \r\n * @version : 0.0.2\r\n * @update  : 2018/06/05\r\n * @homepage: https://github."
  },
  {
    "path": "src/vender/mduikit/statebutton.jsx",
    "chars": 17307,
    "preview": "/*!\n * React Material Design: StateButton\n * \n * @version : 0.0.2\n * @update  : 2018/06/27\n * @homepage: https://github."
  },
  {
    "path": "src/vender/mduikit/switch.jsx",
    "chars": 7624,
    "preview": "/*!\n * React Material Design: Switch\n * \n * @version : 0.0.3\n * @update  : 2018/04/26\n * @homepage: https://github.com/k"
  },
  {
    "path": "src/vender/mduikit/tabs.jsx",
    "chars": 10582,
    "preview": "/*!\n * React Material Design: Tabs\n * \n * @version : 0.0.3\n * @update  : 2018/04/26\n * @homepage: https://github.com/ken"
  },
  {
    "path": "src/vender/mduikit/textfield.jsx",
    "chars": 11280,
    "preview": "/*!\n * React Material Design: TextField\n * \n * @version : 0.0.3\n * @update  : 2018/06/27\n * @homepage: https://github.co"
  },
  {
    "path": "src/vender/mduikit/tooltip.jsx",
    "chars": 10321,
    "preview": "/*!\r\n * React Material Design: Tooltip\r\n * \r\n * @version : 0.0.3\r\n * @update  : 2019/12/31\r\n * @homepage: https://github"
  },
  {
    "path": "src/vender/mduikit/waves.js",
    "chars": 944,
    "preview": "/*!\r\n * React Material Design: Waves\r\n * \r\n * @version : 0.0.1\r\n * @update  : 2017/04/19\r\n * @homepage: https://github.c"
  },
  {
    "path": "src/vender/notify/notify.css",
    "chars": 6931,
    "preview": "\n/*\n* Notify Group\n*/\nnotify-gp {\n    font: 300 14px -apple-system, PingFang SC, Microsoft Yahei, Lantinghei SC, Hiragin"
  },
  {
    "path": "src/vender/notify/notify.js",
    "chars": 16848,
    "preview": "\"use strict\";\r\n\r\n/*\r\n* Options:\r\n* - title   ( string, optional, if value is \"\" not show.)\r\n*\r\n* - content ( string, req"
  },
  {
    "path": "src/vender/sha1.js",
    "chars": 5914,
    "preview": "/*\n A JavaScript implementation of the SHA family of hashes, as\n defined in FIPS PUB 180-2 as well as the corresponding "
  },
  {
    "path": "src/vender/turndown/turndown-plugin-gfm.js",
    "chars": 4227,
    "preview": "var turndownPluginGfm = (function (exports) {\n'use strict';\n\nvar highlightRegExp = /highlight-(?:text|source)-([a-z0-9]+"
  },
  {
    "path": "src/vender/turndown/turndown.js",
    "chars": 23193,
    "preview": "var TurndownService = (function () {\n'use strict';\n\nfunction extend (destination) {\n  for (var i = 1; i < arguments.leng"
  },
  {
    "path": "src/vender/waves/waves.js",
    "chars": 18265,
    "preview": "/*!\n * Waves v0.7.5\n * http://fian.my.id/Waves\n *\n * Copyright 2014-2016 Alfiana E. Sibuea and other contributors\n * Rel"
  },
  {
    "path": "src/vender/webdav.js",
    "chars": 5064,
    "preview": "/* A simple WebDav implementation in JavaScript\n   https://github.com/aslakhellesoy/webdavjs @license MIT\n*/\nvar WebDAV "
  },
  {
    "path": "src/vender/wiz.js",
    "chars": 4025,
    "preview": "/**\n * Soure from https://github.com/xcffl/WizWebClipperWE\n */\n\nvar Base64 = {\n    // private property\n    _keyStr : \"AB"
  },
  {
    "path": "src/website_list.json",
    "chars": 130386,
    "preview": "{\r\n    \"sites\"  : [{\r\n        \"name\"    : \"cnbeta.com\",\r\n        \"url\"     : \"http*://*.cnbeta.com/articles/*/*\",\r\n     "
  },
  {
    "path": "webpack.config.ext.js",
    "chars": 11398,
    "preview": "\nconst webpack = require( 'webpack' ),\n    plugins = [\n\n      // public reqire( xxx )\n      new webpack.ProvidePlugin({\n"
  },
  {
    "path": "webpack.config.js",
    "chars": 12171,
    "preview": "\nconst webpack = require( 'webpack' ),\n    plugins = [\n\n      // public reqire( xxx )\n      new webpack.ProvidePlugin({\n"
  }
]

About this extraction

This page contains the full source code of the Kenshin/simpread GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 137 files (1.2 MB), approximately 361.1k tokens, and a symbol index with 933 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!