diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml deleted file mode 100644 index 645d11d1..00000000 --- a/.github/workflows/pages.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: Pages - -on: - push: - branches: - - dev # default branch - -jobs: - pages: - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - uses: actions/checkout@v2 - - name: Use Node.js 18.x - uses: actions/setup-node@v2 - with: - node-version: "18" - - name: Cache NPM dependencies - uses: actions/cache@v2 - with: - path: node_modules - key: ${{ runner.OS }}-npm-cache - restore-keys: | - ${{ runner.OS }}-npm-cache - - name: Update - run: git submodule update --init --recursive - - name: Install Dependencies - run: npm install - - name: Build - run: npm run build - - name: page deploy - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - force_orphan: true - publish_branch: master - publish_dir: ./public - - name: ssh deploy - uses: easingthemes/ssh-deploy@v5.0.3 - with: - SSH_PRIVATE_KEY: ${{ secrets.REMOTE_PRIVATE_KEY }} - REMOTE_HOST: ${{ secrets.REMOTE_HOST }} - REMOTE_USER: ${{ secrets.REMOTE_USER }} - SOURCE: "public/*" - TARGET: ${{ secrets.REMOTE_TARGET }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index cbcb0f70..da7435ae 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,5 @@ db.json *.log node_modules/ public/ -tmp/ .deploy*/ package-lock.json diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 7204821c..00000000 --- a/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "themes/anzhiyu"] - path = themes/anzhiyu - url = https://github.com/anzhiyu-c/hexo-theme-anzhiyu.git - branch = 1.6.12 diff --git a/README.md b/README.md index f81cba59..1ca8d9d7 100644 --- a/README.md +++ b/README.md @@ -1,61 +1,3 @@ -# 博客项目 +# PyQt5 Doc -https://pyqt5.com - -## 微信博客小程序 - - - -## 提交文章说明 - -1. 先 fork 本项目 或者 作为协作者加入本项目 -2. 在 [source/_posts](source/_posts) 目录中编写文章 -3. 图片文件放到[source/images](source/images),在文章中使用的时候 `![xx](/images/xx.png)` -4. 其它文件放到[source/files](source/files),在文章中使用的时候 `[xx](/files/xx.zip)` -5. 文章格式见下面 -6. 提交代码 - -## 文章格式 - -1. 文件名必须为英文,且小于50字符 -2. 内容开头格式如下 -``` ---- -author: Irony -title: PyQtClient例子客户端 -date: 2019-02-02 15:15:06 -top: 1 -tags: - - Example -categories: 随笔 ---- - -文章内容简介,注意!!!下面的``一定要加上 - - -这里是正文内容 -``` - -直接复制上面内容到新建的文档中,修改编辑 - -## 字段说明 - -| 字段 | 说明 | -| :------:| :------: | -| author | 作者名字 | -| title | 中文标题 | -| date | 文章日期 | -| top | 排序 (默认为1)| -| tags | 文章标签(可以多个) | -| categories | 文章分类(只能一个) | - -## 注意 - -tags可以是多个,yaml语法要注意格式对齐,比如: -``` -tags: - - PyQt - - 动画 -``` - -目前常用的categories有:随笔,教程,例子,笔记 +https://doc.pyqt5.com diff --git a/_config.anzhiyu.yml b/_config.anzhiyu.yml deleted file mode 100644 index ed69ed3e..00000000 --- a/_config.anzhiyu.yml +++ /dev/null @@ -1,1282 +0,0 @@ -menu: - 文章: - 隧道: /archives/ || anzhiyu-icon-box-archive - 分类: /categories/ || anzhiyu-icon-shapes - 标签: /tags/ || anzhiyu-icon-tags - - 友链: - 友人帐: /link/ || anzhiyu-icon-link - 朋友圈: /fcircle/ || anzhiyu-icon-artstation - 留言板: /comments/ || anzhiyu-icon-envelope - - 我的: - 音乐馆: /music/ || anzhiyu-icon-music - 追番页: /bangumis/ || anzhiyu-icon-bilibili - 相册集: /album/ || anzhiyu-icon-images - 小空调: /air-conditioner/ || anzhiyu-icon-fan - - 关于: - 关于本人: /about/ || anzhiyu-icon-paper-plane - 闲言碎语: /essay/ || anzhiyu-icon-lightbulb - 随便逛逛: javascript:toRandomPost() || anzhiyu-icon-shoe-prints1 - -# nav相关配置 -nav: - enable: true - travelling: true - clock: true - menu: - - title: 项目 - item: - - name: PyQt - link: https://github.com/PyQt5/PyQt - icon: favicon.ico - -# mourn (哀悼日,指定日期网站简单变灰,不包括滚动条) -# 注意: 仅网站首页变灰,其他页面正常显示 -mourn: - enable: false - days: [4-5, 5-12, 7-7, 9-18, 12-13] - -# Code Blocks (代码相关) -# -------------------------------------- - -highlight_theme: light # darker / pale night / light / ocean / mac / mac light / false -highlight_copy: true # copy button -highlight_lang: true # show the code language -highlight_shrink: false # true: shrink the code blocks / false: expand the code blocks | none: expand code blocks and hide the button -highlight_height_limit: 330 # unit: px -code_word_wrap: true - -# copy settings -# copyright: Add the copyright information after copied content (複制的内容后面加上版权信息) -# copy: enable 复制后弹窗提示版权信息 -copy: - enable: true - copyright: - enable: false - limit_count: 50 - -# social settings (社交图标设置) -# formal: -# name: link || icon -social: - Github: https://github.com/PyQt5 || anzhiyu-icon-github - # BiliBili: https://space.bilibili.com/372204786 || anzhiyu-icon-bilibili - -# 作者卡片 状态 -author_status: - enable: false - # 可以是任何图片,建议放表情包或者emoji图片,效果都很好,[表情包速查](https://emotion.xiaokang.me/) - statusImg: "https://bu.dusays.com/2023/08/24/64e6ce9c507bb.png" - skills: - # - 🤖️ 数码科技爱好者 - # - 🔍 分享与热心帮助 - # - 🏠 智能家居小能手 - - 🔨 设计开发一条龙 - - 🤝 专修交互与设计 - - 🏃 脚踏实地行动派 - - 🧱 团队小组发动机 - - 💢 壮汉人狠话不多 - -# search (搜索) -# see https://blog.anheyu.com/posts/c27d.html#搜索系统 -# -------------------------------------- - -# Algolia search -algolia_search: - enable: false - hits: - per_page: 6 - tags: - # - 前端 - # - Hexo - -# Docsearch -# Apply and Docs: see https://docsearch.algolia.com/ -# Crawler Admin Console: see https://crawler.algolia.com/ -# Settings: https://www.algolia.com/ -docsearch: - enable: false - appId: # see email - apiKey: # see email - indexName: # see email - option: - -# Local search -local_search: - enable: false - preload: true - CDN: - -# Math (数学) -# -------------------------------------- -# About the per_page -# if you set it to true, it will load mathjax/katex script in each page (true 表示每一页都加载js) -# if you set it to false, it will load mathjax/katex script according to your setting (add the 'mathjax: true' in page's front-matter) -# (false 需要时加载,须在使用的 Markdown Front-matter 加上 mathjax: true) - -# MathJax -mathjax: - enable: false - per_page: false - -# KaTeX -katex: - enable: false - per_page: false - hide_scrollbar: true - -# Image (图片设置) -# -------------------------------------- - -# Favicon(网站图标) -favicon: /favicon.ico - -# Avatar (头像) -avatar: - img: https://bu.dusays.com/2023/04/27/64496e511b09c.jpg - effect: false - -# Disable all banner image -disable_top_img: false - -# The banner image of home page -index_img: false # "background: url() top / cover no-repeat" - -# If the banner of page not setting, it will show the top_img -default_top_img: false - -cover: - # display the cover or not (是否显示文章封面) - index_enable: true - aside_enable: true - archives_enable: true - # the position of cover in home page (封面显示的位置) - # left/right/both - position: left - # When cover is not set, the default cover is displayed (当没有设置cover时,默认的封面显示) - default_cover: - # - /img/default_cover.jpg - -# Replace Broken Images (替换无法显示的图片) -error_img: - flink: /img/friend_404.gif - post_page: /img/404.jpg - -# A simple 404 page -error_404: - enable: true - subtitle: "页面没有找到" - background: - -post_meta: - page: # Home Page - date_type: created # created or updated or both 主页文章日期是创建日或者更新日或都显示 - date_format: simple # date/relative/simple 显示日期还是相对日期 或者 简单日期 - categories: true # true or false 主页是否显示分类 - tags: true # true or false 主页是否显示标籤 - label: false # true or false 显示描述性文字 - post: - date_type: both # created or updated or both 文章页日期是创建日或者更新日或都显示 - date_format: date # date/relative 显示日期还是相对日期 - categories: true # true or false 文章页是否显示分类 - tags: true # true or false 文章页是否显示标籤 - label: true # true or false 显示描述性文字 - unread: false # true or false 文章未读功能 - -# 主色调相关配置 -mainTone: - enable: false # true or false 文章是否启用获取图片主色调 - mode: api # cdn/api/both cdn模式为图片url+imageAve参数获取主色调,api模式为请求API获取主色调,both模式会先请求cdn参数,无法获取的情况下将请求API获取,可以在文章内配置main_color: '#3e5658',使用十六进制颜色,则不会请求both/cdn/api获取主色调,而是直接使用配置的颜色 - # 项目地址:https://github.com/anzhiyu-c/img2color-go - api: https://img2color-go.vercel.app/api?img= # mode为api时可填写 - cover_change: true # 整篇文章跟随cover修改主色调 - -# wordcount (字数统计) -# see https://blog.anheyu.com/posts/c27d.html#字数统计 -wordcount: - enable: false - post_wordcount: true - min2read: true - total_wordcount: true - -# Display the article introduction on homepage -# 1: description -# 2: both (if the description exists, it will show description, or show the auto_excerpt) -# 3: auto_excerpt (default) -# false: do not show the article introduction -index_post_content: - method: 3 - length: 500 # if you set method to 2 or 3, the length need to config - -# anchor -# when you scroll in post, the URL will update according to header id. -anchor: false - -# Post -# -------------------------------------- - -# toc (目录) -toc: - post: true - page: false - number: true - expand: false - style_simple: false # for post - -post_copyright: - enable: true - decode: false - author_href: - location: 成都 - license: CC BY-NC-SA 4.0 - license_url: https://creativecommons.org/licenses/by-nc-sa/4.0/ - avatarSinks: false # hover时头像下沉 - copyright_author_img_back: - copyright_author_img_front: - copyright_author_link: / - -# Sponsor/reward -reward: - enable: true - QR_code: - - img: images/weixin.png - link: - text: 微信 - - img: images/zhifubao.png - link: - text: 支付宝 - -# Post edit -# Easily browse and edit blog source code online. -post_edit: # 目前仅可选择一个平台在线编辑 - enable: true - # github: https://github.com/user-name/repo-name/edit/branch-name/subdirectory-name/ - # For example: https://github.com/jerryc127/butterfly.js.org/edit/main/source/ - github: https://github.com/PyQt5/pyqt5.github.io/edit/dev/source/_posts/ - - # yuque: https://www.yuque.com/user-name/repo-name/ - # 示例: https://www.yuque.com/yuque/yuque/ - # 你需要在语雀文章 Front Matter 添加参数 id 并确保其唯一性(例如 “id: yuque”, “id: 01”) - yuque: false - -# Related Articles -related_post: - enable: true - limit: 6 # Number of posts displayed - date_type: created # or created or updated 文章日期显示创建日或者更新日 - -# figcaption (图片描述文字) -photofigcaption: false - -# post_pagination (分页) -# value: 1 || 2 || 3 || 4 || false -# 1: The 'next post' will link to old post -# 2: The 'next post' will link to new post -# 3: 只有下一篇,并且只在文章滚动到评论区时显示下一篇文章(旧文章) -# 4: 只有下一篇,并且只在文章滚动到评论区时显示下一篇文章(旧文章) 显示图片cover -# false: disable pagination -post_pagination: 2 - -# Displays outdated notice for a post (文章过期提醒) -noticeOutdate: - enable: false - style: flat # style: simple/flat - limit_day: 365 # When will it be shown - position: top # position: top/bottom - message_prev: It has been - message_next: days since the last update, the content of the article may be outdated. - -# Share System (分享功能) -# -------------------------------------- - -# Share.js -# https://github.com/overtrue/share.js -sharejs: - enable: true - sites: facebook,twitter,wechat,weibo,qq - -# AddToAny -# https://www.addtoany.com/ -addtoany: - enable: false - item: facebook,twitter,wechat,sina_weibo,email,copy_link - -# Comments System -# -------------------------------------- - -comments: - # Up to two comments system, the first will be shown as default - # Choose: Valine/Waline/Twikoo/Artalk - use: # Twikoo/Waline - text: true # Display the comment name next to the button - # lazyload: The comment system will be load when comment element enters the browser's viewport. - # If you set it to true, the comment count will be invalid - lazyload: false - count: false # Display comment count in post's top_img - card_post_count: false # Display comment count in Home Page - -# valine -# https://valine.js.org -valine: - appId: xxxxx # leancloud application app id - appKey: xxxxx # leancloud application app key - pageSize: 10 # comment list page size - avatar: mp # gravatar style https://valine.js.org/#/avatar - lang: zh-CN # i18n: zh-CN/zh-TW/en/ja - placeholder: 填写QQ邮箱就会使用QQ头像喔~. # valine comment input placeholder (like: Please leave your footprints) - guest_info: nick,mail,link # valine comment header info (nick/mail/link) - recordIP: false # Record reviewer IP - serverURLs: # This configuration is suitable for domestic custom domain name users, overseas version will be automatically detected (no need to manually fill in) - bg: /img/comment_bg.png # valine background - emojiCDN: //i0.hdslb.com/bfs/emote/ # emoji CDN - enableQQ: true # enable the Nickname box to automatically get QQ Nickname and QQ Avatar - requiredFields: nick,mail # required fields (nick/mail) - visitor: false - master: - - xxxxx - friends: - - xxxxxx - tagMeta: "博主,小伙伴,访客" - option: - -# waline - A simple comment system with backend support fork from Valine -# https://waline.js.org/ -waline: - serverURL: # Waline server address url - bg: # waline background - pageview: false - meta: false # 归属地, 操作系统 前是否显示图标 - imageUploader: true # 是否启用图片上传功能,默认开启,限制为 128kb 的 base64 图片 - # 以下为可选配置,后续若有新增/修改配置参数可在此自行添加/修改 - option: - -# Twikoo -# https://github.com/imaegoo/twikoo -twikoo: - envId: - region: - visitor: false - option: - -# Artalk -# https://artalk.js.org/guide/frontend/config.html -artalk: - server: - site: - visitor: false - option: - -# Chat Services -# -------------------------------------- - -# Chat Button [recommend] -# It will create a button in the bottom right corner of website, and hide the origin button -chat_btn: false - -# The origin chat button is displayed when scrolling up, and the button is hidden when scrolling down -chat_hide_show: false - -# chatra -# https://chatra.io/ -chatra: - enable: false - id: - -# tidio -# https://www.tidio.com/ -tidio: - enable: false - public_key: - -# daovoice -# http://daovoice.io/ -daovoice: - enable: false - app_id: - -# crisp -# https://crisp.chat/en/ -crisp: - enable: false - website_id: - -# Footer Settings -# -------------------------------------- -footer: - owner: - enable: true - since: 2018 - custom_text: - runtime: - enable: true - launch_time: 01/01/2018 00:00:00 # 网站上线时间 - work_img: https://npm.elemecdn.com/anzhiyu-blog@2.0.4/img/badge/安知鱼-上班摸鱼中.svg - work_description: 距离月入30k也就还差一个大佬带我~ - offduty_img: https://npm.elemecdn.com/anzhiyu-blog@2.0.4/img/badge/安知鱼-下班啦.svg - offduty_description: 下班了就该开开心心的玩耍,嘿嘿~ - # 徽标部分配置项 https://shields.io/ - # https://img.shields.io/badge/CDN-jsDelivr-orange?style=flat&logo=jsDelivr - bdageitem: - enable: true - list: - - link: https://hexo.io/ #徽标指向网站链接 - shields: https://npm.elemecdn.com/anzhiyu-blog@2.1.5/img/badge/Frame-Hexo.svg #徽标API - message: 博客框架为Hexo_v5.4.0 #徽标提示语 - - link: https://blog.anheyu.com/ - shields: https://npm.elemecdn.com/anzhiyu-theme-static@1.0.9/img/Theme-AnZhiYu-2E67D3.svg - message: 本站使用AnZhiYu主题 - # - link: https://www.dogecloud.com/ - # shields: https://npm.elemecdn.com/anzhiyu-blog@2.2.0/img/badge/CDN-多吉云-3693F3.svg - # message: 本站使用多吉云为静态资源提供CDN加速 - - link: https://github.com/ - shields: https://npm.elemecdn.com/anzhiyu-blog@2.1.5/img/badge/Source-Github.svg - message: 本站项目由Github托管 - - link: http://creativecommons.org/licenses/by-nc-sa/4.0/ - shields: https://npm.elemecdn.com/anzhiyu-blog@2.2.0/img/badge/Copyright-BY-NC-SA.svg - message: 本站采用知识共享署名-非商业性使用-相同方式共享4.0国际许可协议进行许可 - socialBar: - enable: true - centerImg: - left: - - title: email - link: mailto:892768447@qq.com - icon: anzhiyu-icon-envelope - - title: RSS - link: atom.xml - icon: anzhiyu-icon-rss - right: - - title: Github - link: https://github.com/PyQt5 - icon: anzhiyu-icon-github - - title: CC - link: /copyright - icon: anzhiyu-icon-copyright-line - list: - enable: false - randomFriends: 3 - project: - # - title: 导航 - # links: - # - title: 即刻短文 - # link: /essay/ - # - title: 友链文章 - # link: /fcircle/ - # - title: 留言板 - # link: /comments/ - # - title: 协议 - # links: - # - title: 隐私协议 - # link: /privacy/ - # - title: Cookies - # link: /cookies/ - # - title: 版权协议 - # link: /copyright/ - footerBar: - enable: true - authorLink: / - cc: - enable: false - link: /copyright - linkList: - - link: https://github.com/anzhiyu-c/hexo-theme-anzhiyu - text: 主题 - # - link: https://beian.miit.gov.cn/ - # text: 湘ICP备-xxxxxxx号 - subTitle: - enable: false - # Typewriter Effect (打字效果) - effect: true - # Effect Speed Options (打字效果速度参数) - startDelay: 300 # time before typing starts in milliseconds - typeSpeed: 150 # type speed in milliseconds - backSpeed: 50 # backspacing speed in milliseconds - # loop (循环打字) - loop: true - # source 调用第三方服务 - # source: false 关闭调用 - # source: 1 调用一言网的一句话(简体) https://hitokoto.cn/ - # source: 2 调用一句网(简体) http://yijuzhan.com/ - # source: 3 调用今日诗词(简体) https://www.jinrishici.com/ - # subtitle 会先显示 source , 再显示 sub 的内容 - source: 1 - # 如果关闭打字效果,subtitle 只会显示 sub 的第一行文字 - sub: - # - 生活明朗, 万物可爱, 人间值得, 未来可期. - -# Analysis -# -------------------------------------- - -# Baidu Analytics -# https://tongji.baidu.com/web/welcome/login -baidu_analytics: f7dfd656bdac4e76da8b54bba2978f0b - -# Google Analytics -# https://analytics.google.com/analytics/web/ -google_analytics: - -# CNZZ Analytics -# https://www.umeng.com/ -cnzz_analytics: - -# Cloudflare Analytics -# https://www.cloudflare.com/zh-tw/web-analytics/ -cloudflare_analytics: - -# Microsoft Clarity -# https://clarity.microsoft.com/ -microsoft_clarity: j6xye2x6np - -# Advertisement -# -------------------------------------- - -# Google Adsense (谷歌广告) -google_adsense: - enable: false - auto_ads: true - js: https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js - client: - enable_page_level_ads: true - -# Insert ads manually (手动插入广告) -# ad: -# index: -# aside: -# post: - -# Verification (站长验证) -# -------------------------------------- - -site_verification: - - name: google-site-verification - content: xxx - - name: baidu-site-verification - content: code-xxx - - name: msvalidate.01 - content: xxx - -# Beautify/Effect (美化/效果) -# -------------------------------------- - -# Theme color for customize -# Notice: color value must in double quotes like "#000" or may cause error! - -theme_color: - enable: true - main: "#425AEF" - dark_main: "#f2b94b" - paginator: "#425AEF" - # button_hover: "#FF7242" - text_selection: "#2128bd" - link_color: "var(--anzhiyu-fontcolor)" - meta_color: "var(--anzhiyu-fontcolor)" - hr_color: "#4259ef23" - code_foreground: "#fff" - code_background: "var(--anzhiyu-code-stress)" - toc_color: "#425AEF" - # blockquote_padding_color: "#425AEF" - # blockquote_background_color: "#425AEF" - scrollbar_color: "var(--anzhiyu-scrollbar)" - meta_theme_color_light: "#f7f9fe" - meta_theme_color_dark: "#18171d" - -# 移动端侧栏 -sidebar: - site_data: - archive: true - tag: true - category: true - menus_items: true - tags_cloud: true - display_mode: true - nav_menu_project: true - -# 文章h2添加分隔线 -h2Divider: false - -# 表格隔行变色 -table_interlaced_discoloration: false - -# 首页双栏显示 -article_double_row: true - -# The top_img settings of home page -# default: top img - full screen, site info - middle (默认top_img全屏,site_info在中间) -# The position of site info, eg: 300px/300em/300rem/10% (主页标题距离顶部距离) -index_site_info_top: -# The height of top_img, eg: 300px/300em/300rem (主页top_img高度) -index_top_img_height: - -# The user interface setting of category and tag page (category和tag页的UI设置) -# index - same as Homepage UI (index 值代表 UI将与首页的UI一样) -# default - same as archives UI 默认跟archives页面UI一样 -category_ui: # 留空或 index -tag_ui: # 留空或 index - -# Footer Background -footer_bg: false - -# the position of bottom right button/default unit: px (右下角按钮距离底部的距离/默认单位为px) -rightside-bottom: 100px - -# Background effects (背景特效) -# -------------------------------------- - -# canvas_ribbon (静止彩带背景) -# See: https://github.com/hustcc/ribbon.js -canvas_ribbon: - enable: false - size: 150 - alpha: 0.6 - zIndex: -1 - click_to_change: false - mobile: false - -# Fluttering Ribbon (动态彩带) -canvas_fluttering_ribbon: - enable: false - mobile: false - -# canvas_nest -# https://github.com/hustcc/canvas-nest.js -canvas_nest: - enable: false - color: "0,0,255" #color of lines, default: '0,0,0'; RGB values: (R,G,B).(note: use ',' to separate.) - opacity: 0.7 # the opacity of line (0~1), default: 0.5. - zIndex: -1 # z-index property of the background, default: -1. - count: 99 # the number of lines, default: 99. - mobile: false - -# Typewriter Effect (打字效果) -# https://github.com/disjukr/activate-power-mode -activate_power_mode: - enable: false - colorful: true # open particle animation (冒光特效) - shake: false # open shake (抖动特效) - mobile: false - -# Mouse click effects: fireworks (鼠标点击效果: 烟火特效) -fireworks: - enable: false - zIndex: 9999 # -1 or 9999 - mobile: false - -# Mouse click effects: Heart symbol (鼠标点击效果: 爱心) -click_heart: - enable: false - mobile: false - -# Mouse click effects: words (鼠标点击效果: 文字) -ClickShowText: - enable: false - text: - # - I - # - LOVE - # - YOU - fontSize: 15px - random: false - mobile: false - -# Default display mode (网站默认的显示模式) -# light (default) / dark -display_mode: light - -# Beautify (美化页面显示) -beautify: - enable: true - field: post # site/post - title-prefix-icon: '\f0c1' - title-prefix-icon-color: "#F47466" - -# Global font settings -# Don't modify the following settings unless you know how they work (非必要不要修改) -font: - global-font-size: 16px - code-font-size: - font-family: - code-font-family: consolas, Menlo, "PingFang SC", "Microsoft JhengHei", "Microsoft YaHei", sans-serif - -# Font settings for the site title and site subtitle -# 左上角网站名字 主页居中网站名字 -blog_title_font: - font_link: - font-family: PingFang SC, 'Hiragino Sans GB', 'Microsoft JhengHei', 'Microsoft YaHei', sans-serif - -# The setting of divider icon (水平分隔线图标设置) -hr_icon: - enable: true - icon: \f0c4 # the unicode value of Font Awesome icon, such as '\f0c4' - icon-top: - -# the subtitle on homepage (主页subtitle) -subtitle: - enable: false - # Typewriter Effect (打字效果) - effect: true - # Effect Speed Options (打字效果速度参数) - startDelay: 300 # time before typing starts in milliseconds - typeSpeed: 150 # type speed in milliseconds - backSpeed: 50 # backspacing speed in milliseconds - # loop (循环打字) - loop: true - # source 调用第三方服务 - # source: false 关闭调用 - # source: 1 调用一言网的一句话(简体) https://hitokoto.cn/ - # source: 2 调用一句网(简体) http://yijuzhan.com/ - # source: 3 调用今日诗词(简体) https://www.jinrishici.com/ - # subtitle 会先显示 source , 再显示 sub 的内容 - source: 1 - # 如果关闭打字效果,subtitle 只会显示 sub 的第一行文字 - sub: - # - 生活明朗,万物可爱,人间值得,未来可期. - -# Loading Animation (加载动画) -preloader: - enable: true - # source - # 1. fullpage-loading - # 2. pace (progress bar) - # else all - source: 3 - # pace theme (see https://codebyzach.github.io/pace/) - pace_css_url: - avatar: https://npm.elemecdn.com/anzhiyu-blog-static@1.0.4/img/avatar.jpg # 自定加载动画义头像 - -# aside (侧边栏) -# -------------------------------------- - -aside: - enable: true - hide: false - button: true - mobile: true # display on mobile - position: right # left or right - display: # 控制对应详情页面是否显示侧边栏 - archive: true - tag: true - category: true - card_author: - enable: true - description: #
这有关于产品、设计、开发相关的问题和看法,还有文章翻译分享
相信你可以在这里找到对你有用的知识教程
# 默认为站点描述 - name_link: / - - card_announcement: - enable: false - content: 欢迎来看我的博客鸭~ - card_weixin: - enable: true - face: https://bu.dusays.com/2023/01/13/63c02edf44033.png - backFace: https://bu.dusays.com/2023/05/13/645fa415e8694.png - card_recent_post: - enable: true - limit: 5 # if set 0 will show all - sort: date # date or updated - sort_order: # Don't modify the setting unless you know how it works - card_categories: - enable: false - limit: 8 # if set 0 will show all - expand: none # none/true/false - sort_order: # Don't modify the setting unless you know how it works - card_tags: - enable: true - limit: 40 # if set 0 will show all - color: false - sort_order: # Don't modify the setting unless you know how it works - highlightTags: - # - Hexo - # - 前端 - card_archives: - enable: true - type: monthly # yearly or monthly - format: MMMM YYYY # eg: YYYY年MM月 - order: -1 # Sort of order. 1, asc for ascending; -1, desc for descending - limit: 8 # if set 0 will show all - sort_order: # Don't modify the setting unless you know how it works - card_webinfo: - enable: true - post_count: true - last_push_date: false - sort_order: # Don't modify the setting unless you know how it works - -# busuanzi count for PV / UV in site -# 访问人数 -busuanzi: - site_uv: true - site_pv: true - page_pv: true - -# Time difference between publish date and now (网页运行时间) -# Formal: Month/Day/Year Time or Year/Month/Day Time -runtimeshow: - enable: true - publish_date: 1/1/2018 00:00:00 - -# Console - Newest Comments -newest_comments: - enable: false - sort_order: # Don't modify the setting unless you know how it works - limit: 6 - storage: 10 # unit: mins, save data to localStorage - avatar: true - -# Bottom right button (右下角按钮) -# -------------------------------------- - -# Conversion between Traditional and Simplified Chinese (简繁转换) -translate: - enable: true - # The text of a button - default: 繁 - # Right-click menu default text - rightMenuMsgDefault: "轉為繁體" - # the language of website (1 - Traditional Chinese/ 2 - Simplified Chinese) - defaultEncoding: 2 - # Time delay - translateDelay: 0 - # The text of the button when the language is Simplified Chinese - msgToTraditionalChinese: "繁" - # The text of the button when the language is Traditional Chinese - msgToSimplifiedChinese: "简" - # Right-click the menu to traditional Chinese - rightMenuMsgToTraditionalChinese: "转为繁体" - # Right-click menu to simplified Chinese - rightMenuMsgToSimplifiedChinese: "转为简体" - -# Read Mode (閲读模式) -readmode: true - -# 中控台 -centerConsole: - enable: true - card_tags: - enable: true - limit: 40 # if set 0 will show all - color: false - sort_order: # Don't modify the setting unless you know how it works - highlightTags: - # - Hexo - # - 前端 - card_archives: - enable: true - type: monthly # yearly or monthly - format: MMMM YYYY # eg: YYYY年MM月 - order: -1 # Sort of order. 1, asc for ascending; -1, desc for descending - limit: 8 # if set 0 will show all - sort_order: # Don't modify the setting unless you know how it works - -# dark mode -darkmode: - enable: true - # Toggle Button to switch dark/light mode - button: true - # Switch dark/light mode automatically (自动切换 dark mode和 light mode) - # autoChangeMode: 1 Following System Settings, if the system doesn't support dark mode, it will switch dark mode between 6 pm to 6 am - # autoChangeMode: 2 Switch dark mode between 6 pm to 6 am - # autoChangeMode: false - autoChangeMode: 1 - start: # 8 - end: # 22 - -# Don't modify the following settings unless you know how they work (非必要请不要修改 ) -# Choose: readmode,translate,darkmode,hideAside,toc,chat,comment -# Don't repeat 不要重複 -rightside_item_order: - enable: false - hide: # readmode,translate,darkmode,hideAside - show: # toc,chat,comment - -# Lightbox (图片大图查看模式) -# -------------------------------------- -# You can only choose one, or neither (只能选择一个 或者 两个都不选) - -# medium-zoom -# https://github.com/francoischalifour/medium-zoom -medium_zoom: false - -# fancybox -# http://fancyapps.com/fancybox/3/ -fancybox: true - -# Tag Plugins settings (标籤外挂) -# -------------------------------------- - -# mermaid -# see https://github.com/mermaid-js/mermaid -mermaid: - enable: false - # built-in themes: default/forest/dark/neutral - theme: - light: default - dark: dark - -# Note (Bootstrap Callout) -note: - # Note tag style values: - # - simple bs-callout old alert style. Default. - # - modern bs-callout new (v2-v3) alert style. - # - flat flat callout style with background, like on Mozilla or StackOverflow. - # - disabled disable all CSS styles import of note tag. - style: flat - icons: true - border_radius: 3 - # Offset lighter of background in % for modern and flat styles (modern: -12 | 12; flat: -18 | 6). - # Offset also applied to label tag variables. This option can work with disabled note tag. - light_bg_offset: 0 - -icons: - ali_iconfont_js: # 阿里图标symbol 引用链接,主题会进行加载 symbol 引用 - fontawesome: false #是否启用fontawesome6图标 - fontawesome_animation_css: https://npm.elemecdn.com/hexo-butterfly-tag-plugins-plus@1.0.17/lib/assets/font-awesome-animation.min.css - -# other -# -------------------------------------- - -# Pjax -# It may contain bugs and unstable, give feedback when you find the bugs. -# https://github.com/MoOx/pjax -pjax: - enable: true - exclude: - - /music/ - - /no-pjax/ - -# Inject the css and script (aplayer/meting) -aplayerInject: - enable: true - per_page: true - -# Snackbar (Toast Notification 弹窗) -# https://github.com/polonel/SnackBar -# position 弹窗位置 -# 可选 top-left / top-center / top-right / bottom-left / bottom-center / bottom-right -snackbar: - enable: true - position: top-center - bg_light: "#425AEF" # The background color of Toast Notification in light mode - bg_dark: "#1f1f1f" # The background color of Toast Notification in dark mode - -# https://instant.page/ -# prefetch (预加载) -instantpage: true - -# https://github.com/vinta/pangu.js -# Insert a space between Chinese character and English character (中英文之间添加空格) -pangu: - enable: false - field: site # site/post - -# Lazyload (图片懒加载) -# https://github.com/verlok/vanilla-lazyload -lazyload: - enable: true - field: site # site/post - placeholder: - blur: true - progressive: true - -# PWA -# See https://github.com/JLHwung/hexo-offline -# --------------- -pwa: - enable: false - startup_image_enable: true - manifest: /manifest.json - theme_color: var(--anzhiyu-main) - mask_icon: /img/siteicon/apple-icon-180.png - apple_touch_icon: /img/siteicon/apple-icon-180.png - bookmark_icon: /img/siteicon/apple-icon-180.png - favicon_32_32: /img/siteicon/32.png - favicon_16_16: /img/siteicon/16.png - -# Open graph meta tags -# https://developers.facebook.com/docs/sharing/webmasters/ -Open_Graph_meta: true - -# Add the vendor prefixes to ensure compatibility -css_prefix: true - -# 首页顶部相关配置 -home_top: - enable: true # 开关 - timemode: date #date/updated - title: 生活明朗 - subTitle: 万物可爱。 - siteText: anheyu.com - category: - - name: 前端 - path: /categories/前端开发/ - shadow: var(--anzhiyu-shadow-blue) - class: blue - icon: anzhiyu-icon-dove - - name: 大学 - path: /categories/大学生涯/ - shadow: var(--anzhiyu-shadow-red) - class: red - icon: anzhiyu-icon-fire - - name: 生活 - path: /categories/生活日常/ - shadow: var(--anzhiyu-shadow-green) - class: green - icon: anzhiyu-icon-book - default_descr: 再怎么看我也不知道怎么描述它的啦! - swiper: - enable: false - swiper_css: https://npm.elemecdn.com/anzhiyu-theme-static@1.0.0/swiper/swiper.min.css #swiper css依赖 - swiper_js: https://npm.elemecdn.com/anzhiyu-theme-static@1.0.0/swiper/swiper.min.js #swiper js依赖 - banner: - tips: 新品主题 - title: Theme-AnZhiYu - image: https://bu.dusays.com/2023/05/13/645fa3cf90d70.webp - link: https://docs.anheyu.com/ - -# 朋友圈配置 -friends_vue: - enable: false - vue_js: https://npm.elemecdn.com/anzhiyu-theme-static@1.1.1/friends/index.4f887d95.js - apiurl: # 朋友圈后端地址 - top_tips: 使用 友链朋友圈 订阅友链最新文章 - top_background: - -# 深色模式粒子效果canvas -universe: - enable: true - -# 页面卡片顶部气泡升起效果 -bubble: - enable: false - -# 控制台打印信息 -console: - enable: true - -# 51a统计配置 -LA: - enable: false - ck: - LingQueMonitorID: - -# 标签卖萌 -diytitle: - enable: true - leaveTitle: w(゚Д゚)w 不要走!再看看嘛! - backTitle: ♪(^∇^*)欢迎肥来! - -# 留言弹幕配置 -comment_barrage_config: - enable: false - # 同时最多显示弹幕数 - maxBarrage: 1 - # 弹幕显示间隔时间ms - barrageTime: 4000 - # token,在控制台中获取 - accessToken: "" - # 博主邮箱md5值 - mailMd5: "" - -# 左下角音乐配置项 -# https://github.com/metowolf/MetingJS -nav_music: - enable: true - console_widescreen_music: false # 宽屏状态控制台显示音乐而不是标签 enable为true 控制台依然会显示 - id: 8152976493 - server: netease - volume: 0.7 # 默认音量 - all_playlist: https://y.qq.com/n/ryqq/playlist/8802438608 - -# 路径为 /music 的音乐页面默认加载的歌单 1. nav_music 2. custom -music_page_default: nav_music - -# 评论匿名邮箱 -visitorMail: - enable: true - mail: "" - -# ptool 文章底部工具 -ptool: - enable: true - share_mobile: true - share_weibo: true - share_copyurl: true - categories: false # 是否显示分类 - mode: # 运营模式与责任,不配置不显示 - -# 欢迎语配置 -greetingBox: - enable: false #开启后必须配置下面的list对应的时间段,不然会出现小白条 - default: 晚上好👋 - list: - # - greeting: 晚安😴 - # startTime: 0 - # endTime: 5 - # - greeting: 早上好鸭👋, 祝你一天好心情! - # startTime: 6 - # endTime: 9 - # - greeting: 上午好👋, 状态很好,鼓励一下~ - # startTime: 10 - # endTime: 10 - # - greeting: 11点多啦, 在坚持一下就吃饭啦~ - # startTime: 11 - # endTime: 11 - # - greeting: 午安👋, 宝贝 - # startTime: 12 - # endTime: 14 - # - greeting: 🌈充实的一天辛苦啦! - # startTime: 14 - # endTime: 18 - # - greeting: 19点喽, 奖励一顿丰盛的大餐吧🍔。 - # startTime: 19 - # endTime: 19 - # - greeting: 晚上好👋, 在属于自己的时间好好放松😌~ - # startTime: 20 - # endTime: 24 - -# 文章顶部ai摘要 -post_head_ai_description: - enable: true - gptName: AnZhiYu - mode: local # 默认模式 可选值: tianli/local - switchBtn: false # 可以配置是否显示切换按钮 以切换tianli/local - btnLink: https://afdian.net/item/886a79d4db6711eda42a52540025c377 - randomNum: 3 # 按钮最大的随机次数,也就是一篇文章最大随机出来几种 - basicWordCount: 1000 # 最低获取字符数, 最小1000, 最大1999 - key: xxxx - Referer: https://xx.xx/ - -# 快捷键配置 -shortcutKey: - enable: false - delay: 100 # 所有键位延时触发而不是立即触发(包括shift,以解决和浏览器键位冲突问题) - shiftDelay: 200 # shift按下延时多久开启 - -# 无障碍优化(在首页按下「shift + ?」以查看效果) -accesskey: - enable: true - -# 友情链接顶部相关配置 -linkPageTop: - enable: false - title: 与数百名博主无限进步 - # 添加博主友链的评论自定义格式 - addFriendPlaceholder: "昵称(请勿包含博客等字样):\n网站地址(要求博客地址,请勿提交个人主页):\n头像图片url(请提供尽可能清晰的图片,我会上传到我自己的图床):\n描述:\n站点截图(可选):\n" - -# 缩略图后缀 archive/tag/category 页面单独开启后缀 -pageThumbnailSuffix: "" - -# 隐私协议弹窗 -agreementPopup: - enable: false - url: /privacy - -# 右键菜单 -rightClickMenu: - enable: false - -# 首页随便逛逛people模式 而非技能点模式,关闭后为技能点模式需要配置creativity.yml -peoplecanvas: - enable: true - img: https://upload-bbs.miyoushe.com/upload/2023/09/03/125766904/ee23df8517f3c3e3efc4145658269c06_5714860933110284659.png - -# 动效 -dynamicEffect: - postTopWave: true # 文章顶部波浪效果 - postTopRollZoomInfo: false # 文章顶部滚动时缩放 - pageCommentsRollZoom: false # 非文章页面评论滚动时缩放显示(仅仅Twikoo生效) - -# Inject -# Insert the code to head (before '' tag) and the bottom (before '' tag) -# 插入代码到头部 之前 和 底部 之前 -inject: - head: - # 自定义css - # - - - bottom: - # 自定义js - # - - -# CDN -# Don't modify the following settings unless you know how they work -# 非必要请不要修改 -CDN: - # The CDN provider of internal scripts (主题内部 js 的 cdn 配置) - # option: local/elemecdn/jsdelivr/unpkg/cdnjs/onmicrosoft/cbd/anheyu/custom - # Dev version can only choose. ( dev版的主题只能设置为 local ) - internal_provider: local - - # The CDN provider of third party scripts (第三方 js 的 cdn 配置) - # option: elemecdn/jsdelivr/unpkg/cdnjs/onmicrosoft/cbd/anheyu/custom - third_party_provider: cbd - - # Add version number to CDN, true or false - version: true - - # Custom format - # For example: https://cdn.staticfile.org/${cdnjs_name}/${version}/${min_cdnjs_file} - custom_format: # https://npm.elemecdn.com/${name}@latest/${file} - - option: - # main_css: - # main: - # utils: - # translate: - # random_friends_post_js: - # right_click_menu_js: - # comment_barrage_js: - # ai_abstract_js: - # people_js: - # local_search: - # algolia_js: - # algolia_search: - # instantsearch: - # docsearch_js: - # docsearch_css: - # pjax: - # blueimp_md5: - # valine: - # twikoo: - # waline_js: - # waline_css: - # sharejs: - # sharejs_css: - # mathjax: - # katex: - # katex_copytex: - # mermaid: - # canvas_ribbon: - # canvas_fluttering_ribbon: - # canvas_nest: - # lazyload: - # instantpage: - # typed: - # pangu: - # fancybox_css: - # fancybox: - # medium_zoom: - # snackbar_css: - # snackbar: - # activate_power_mode: - # fireworks: - # click_heart: - # ClickShowText: - # fontawesome: - # flickr_justified_gallery_js: - # flickr_justified_gallery_css: - # aplayer_css: - # aplayer_js: - # meting_js: - # meting_api: - # prismjs_js: - # prismjs_lineNumber_js: - # prismjs_autoloader: - # artalk_js: - # artalk_css: - # pace_js: - # pace_default_css: - # countup_js: - # gsap_js: - busuanzi: https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js - # rightmenu: - # waterfall: - # ali_iconfont_css: - # accesskey_js: diff --git a/_config.butterfly.yml b/_config.butterfly.yml deleted file mode 100644 index 3af50869..00000000 --- a/_config.butterfly.yml +++ /dev/null @@ -1,1028 +0,0 @@ -# Navigation bar settings (導航欄設置) -# see https://butterfly.js.org/posts/4aa8abbe/##導航欄設置-Navigation-bar-settings -# -------------------------------------- - -prismjs: - enable: true - preprocess: true - line_number: false - tab_replace: "" - -nav: - logo: # image - display_title: true - fixed: false # fixed navigation bar - -# Menu 目錄 -menu: - 首页: / || fas fa-home - 归档: /archives/ || fas fa-archive - 标签: /tags/ || fas fa-tags - 分类: /categories/ || fas fa-folder-open - # List||fas fa-list: - # Music: /music/ || fas fa-music - # Movie: /movies/ || fas fa-video - 友链: /link/ || fas fa-link - 关于: /about/ || fas fa-heart - -# Code Blocks (代碼相關) -# -------------------------------------- - -highlight_theme: "mac light" # darker / pale night / light / ocean / mac / mac light / false -highlight_copy: true # copy button -highlight_lang: true # show the code language -highlight_shrink: false # true: shrink the code blocks / false: expand the code blocks | none: expand code blocks and hide the button -highlight_height_limit: 220 # unit: px -code_word_wrap: true - -# Social Settings (社交圖標設置) -# formal: -# icon: link || the description || color -social: - fab fa-qq: https://jq.qq.com/?_wv=1027&k=5QVVEdF || QQ || '#68B2F6' - far fa-comment: https://pd.qq.com/s/157c1hiay || Comment || '#4a7dbe' - fab fa-github: https://github.com/PyQt5 || Github || '#24292e' - fas fa-envelope: mailto:892768447@qq.com || Email || '#4a7dbe' - fas fa-rss: /atom.xml || RSS - -# Image (圖片設置) -# -------------------------------------- - -# Favicon(網站圖標) -favicon: favicon.ico - -# Avatar (頭像) -avatar: - img: /images/avatar.png - effect: false - -# Disable all banner image -disable_top_img: false - -# The banner image of home page -index_img: /images/bg-2.jpg - -# If the banner of page not setting, it will show the top_img -default_top_img: /images/bg-2.jpg - -# The banner image of archive page -archive_img: /images/bg-2.jpg - -# If the banner of tag page not setting, it will show the top_img -# note: tag page, not tags page (子標籤頁面的 top_img) -tag_img: /images/bg-2.jpg - -# The banner image of tag page -# format: -# - tag name: xxxxx -tag_per_img: - -# If the banner of category page not setting, it will show the top_img -# note: category page, not categories page (子分類頁面的 top_img) -category_img: /images/bg-2.jpg - -# The banner image of category page -# format: -# - category name: xxxxx -category_per_img: - -cover: - # display the cover or not (是否顯示文章封面) - index_enable: true - aside_enable: true - archives_enable: true - # the position of cover in home page (封面顯示的位置) - # left/right/both - position: both - # When cover is not set, the default cover is displayed (當沒有設置cover時,默認的封面顯示) - default_cover: # https://jsd.012700.xyz/gh/jerryc127/butterfly_cdn@2.1.0/top_img/default.png - - https://jsd.012700.xyz/gh/jerryc127/CDN/img/material-2.png - - https://jsd.012700.xyz/gh/jerryc127/CDN/img/material-1.png - - https://jsd.012700.xyz/gh/jerryc127/CDN/img/material-3.png - - https://jsd.012700.xyz/gh/jerryc127/CDN/img/material-6.png - - https://jsd.012700.xyz/gh/jerryc127/CDN/img/material-5.png - - https://jsd.012700.xyz/gh/jerryc127/CDN/img/material-4.png - - https://jsd.012700.xyz/gh/jerryc127/CDN/img/material-7.png - - https://jsd.012700.xyz/gh/jerryc127/CDN/img/material-9.png - - https://jsd.012700.xyz/gh/jerryc127/CDN/img/material-8.png - - https://jsd.012700.xyz/gh/jerryc127/CDN/img/material-10.png - -# Replace Broken Images (替換無法顯示的圖片) -error_img: - flink: /img/friend_404.gif - post_page: /img/404.jpg - -# A simple 404 page -error_404: - enable: true - subtitle: '页面没有找到' - background: https://i.loli.net/2020/05/19/aKOcLiyPl2JQdFD.png - -post_meta: - page: # Home Page - date_type: created # created or updated or both 主頁文章日期是創建日或者更新日或都顯示 - date_format: date # date/relative 顯示日期還是相對日期 - categories: true # true or false 主頁是否顯示分類 - tags: true # true or false 主頁是否顯示標籤 - label: true # true or false 顯示描述性文字 - post: - date_type: created # created or updated or both 文章頁日期是創建日或者更新日或都顯示 - date_format: date # date/relative 顯示日期還是相對日期 - categories: true # true or false 文章頁是否顯示分類 - tags: true # true or false 文章頁是否顯示標籤 - label: true # true or false 顯示描述性文字 - -# Display the article introduction on homepage -# 1: description -# 2: both (if the description exists, it will show description, or show the auto_excerpt) -# 3: auto_excerpt (default) -# false: do not show the article introduction -index_post_content: - method: 3 - length: 500 # if you set method to 2 or 3, the length need to config - -# anchor -anchor: - # when you scroll, the URL will update according to header id. - auto_update: true - # Click the headline to scroll and update the anchor - click_to_scroll: true - -# figcaption (圖片描述文字) -photofigcaption: true - -# copy settings -# copyright: Add the copyright information after copied content (複製的內容後面加上版權信息) -copy: - enable: true - copyright: - enable: true - limit_count: 150 - -# Post -# -------------------------------------- - -# toc (目錄) -toc: - post: true - page: false - number: true - expand: true - style_simple: false # for post - scroll_percent: true - -post_copyright: - enable: true - decode: true - author_href: - license: CC BY-NC-SA 4.0 - license_url: https://creativecommons.org/licenses/by-nc-sa/4.0/ - -# Sponsor/reward -reward: - enable: true - text: - QR_code: - - img: /images/weixin.png - link: - text: 微信付 - - img: /images/zhifubao.png - link: - text: 支付宝 - -# Post edit -# Easily browse and edit blog source code online. -post_edit: - enable: true - # url: https://github.com/user-name/repo-name/edit/branch-name/subdirectory-name/ - # For example: https://github.com/jerryc127/butterfly.js.org/edit/main/source/ - url: https://github.com/PyQt5/blog/edit/dev/source/ - -# Related Articles -related_post: - enable: true - limit: 6 # Number of posts displayed - date_type: created # or created or updated 文章日期顯示創建日或者更新日 - -# post_pagination (分頁) -# value: 1 || 2 || false -# 1: The 'next post' will link to old post -# 2: The 'next post' will link to new post -# false: disable pagination -post_pagination: 1 - -# Displays outdated notice for a post (文章過期提醒) -noticeOutdate: - enable: true - style: flat # style: simple/flat - limit_day: 730 # When will it be shown - position: top # position: top/bottom - message_prev: 距离上次更新已经过了 - message_next: 天,文章所描述的内容可能已经发生变化,请留意。 - -# Footer Settings -# -------------------------------------- -footer: - owner: - enable: true - since: 2018 - custom_text: '
蜀ICP备18031575号-1蜀ICP备18031575号-2
' - copyright: true # Copyright of theme and framework - -# aside (側邊欄) -# -------------------------------------- - -aside: - enable: true - hide: false - button: true - mobile: true # display on mobile - position: left # left or right - display: - archive: true - tag: true - category: true - card_author: - enable: true - description: - button: - enable: true - icon: fab fa-github - text: PyQt Github - link: https://github.com/PyQt5 - card_announcement: - enable: true - content: - '
- - - -

or

- - - -
' - card_recent_post: - enable: true - limit: 5 # if set 0 will show all - sort: date # date or updated - sort_order: # Don't modify the setting unless you know how it works - card_categories: - enable: true - limit: 0 # if set 0 will show all - expand: false # none/true/false - sort_order: # Don't modify the setting unless you know how it works - card_tags: - enable: true - limit: 40 # if set 0 will show all - color: true - orderby: random # Order of tags, random/name/length - order: 1 # Sort of order. 1, asc for ascending; -1, desc for descending - sort_order: # Don't modify the setting unless you know how it works - card_archives: - enable: true - type: monthly # yearly or monthly - format: YYYY年MM月 # eg: YYYY年MM月 - order: -1 # Sort of order. 1, asc for ascending; -1, desc for descending - limit: 8 # if set 0 will show all - sort_order: # Don't modify the setting unless you know how it works - card_webinfo: - enable: true - post_count: true - last_push_date: true - sort_order: # Don't modify the setting unless you know how it works - card_post_series: - enable: true - orderBy: 'date' # Order by title or date - order: -1 # Sort of order. 1, asc for ascending; -1, desc for descendin - -# busuanzi count for PV / UV in site -# 訪問人數 -busuanzi: - site_uv: true - site_pv: true - page_pv: true - -# Time difference between publish date and now (網頁運行時間) -# Formal: Month/Day/Year Time or Year/Month/Day Time -runtimeshow: - enable: true - publish_date: 2018/1/1 00:00:00 - -# Aside widget - Newest Comments -newest_comments: - enable: true - sort_order: # Don't modify the setting unless you know how it works - limit: 6 - storage: 10 # unit: mins, save data to localStorage - avatar: true - -# Bottom right button (右下角按鈕) -# -------------------------------------- - -# Conversion between Traditional and Simplified Chinese (簡繁轉換) -translate: - enable: false - # The text of a button - default: 简 - # the language of website (1 - Traditional Chinese/ 2 - Simplified Chinese) - defaultEncoding: 2 - # Time delay - translateDelay: 0 - # The text of the button when the language is Simplified Chinese - msgToTraditionalChinese: '繁' - # The text of the button when the language is Traditional Chinese - msgToSimplifiedChinese: '简' - -# Read Mode (閲讀模式) -readmode: true - -# dark mode -darkmode: - enable: true - # Toggle Button to switch dark/light mode - button: true - # Switch dark/light mode automatically (自動切換 dark mode和 light mode) - # autoChangeMode: 1 Following System Settings, if the system doesn't support dark mode, it will switch dark mode between 6 pm to 6 am - # autoChangeMode: 2 Switch dark mode between 6 pm to 6 am - # autoChangeMode: false - autoChangeMode: true - # Set the light mode time. The value is between 0 and 24. If not set, the default value is 6 and 18 - start: 8 - end: 22 - -# show scroll percent in scroll-to-top button -rightside_scroll_percent: true - -# Don't modify the following settings unless you know how they work (非必要請不要修改 ) -# Choose: readmode,translate,darkmode,hideAside,toc,chat,comment -# Don't repeat 不要重複 -rightside_item_order: - enable: false - hide: # readmode,translate,darkmode,hideAside - show: # toc,chat,comment - -# Math (數學) -# -------------------------------------- -# About the per_page -# if you set it to true, it will load mathjax/katex script in each page (true 表示每一頁都加載js) -# if you set it to false, it will load mathjax/katex script according to your setting (add the 'mathjax: true' in page's front-matter) -# (false 需要時加載,須在使用的 Markdown Front-matter 加上 mathjax: true) - -# MathJax -mathjax: - enable: false - per_page: false - -# KaTeX -katex: - enable: false - per_page: false - hide_scrollbar: true - -# search (搜索) -# see https://butterfly.js.org/posts/ceeb73f/#搜索系統 -# -------------------------------------- - -# Algolia search -algolia_search: - enable: false - hits: - per_page: 6 - -# Local search -local_search: - enable: true - # Preload the search data when the page loads. - preload: false - # Show top n results per article, show all results by setting to -1 - top_n_per_article: 1 - # Unescape html strings to the readable one. - unescape: false - CDN: - -# Docsearch -docsearch: - enable: false - appId: - apiKey: - indexName: - option: - -# Share System (分享) -# -------------------------------------- - -# Share.js -# https://github.com/overtrue/share.js -sharejs: - enable: true - sites: facebook,twitter,google,douban,wechat,weibo,qq,qzone - -# AddToAny -# https://www.addtoany.com/ -addtoany: - enable: false - item: facebook,twitter,wechat,sina_weibo,facebook_messenger,email,copy_link - -# Comments System -# -------------------------------------- - -comments: - # Up to two comments system, the first will be shown as default - # Choose: Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo/Giscus/Remark42/Artalk - # use: giscus # Valine,Disqus - text: true # Display the comment name next to the button - # lazyload: The comment system will be load when comment element enters the browser's viewport. - # If you set it to true, the comment count will be invalid - lazyload: true - count: false # Display comment count in post's top_img - card_post_count: false # Display comment count in Home Page - -# disqus -# https://disqus.com/ -disqus: - shortname: - apikey: # For newest comments widget - -# Alternative Disqus - Render comments with Disqus API -# DisqusJS 評論系統,可以實現在網路審查地區載入 Disqus 評論列表,兼容原版 -# https://github.com/SukkaW/DisqusJS -disqusjs: - shortname: - apikey: - option: - -# livere (來必力) -# https://www.livere.com/ -livere: - uid: - -# gitalk -# https://github.com/gitalk/gitalk -gitalk: - client_id: - client_secret: - repo: - owner: - admin: - option: - -# valine -# https://valine.js.org -valine: - appId: # leancloud application app id - appKey: # leancloud application app key - avatar: monsterid # gravatar style https://valine.js.org/#/avatar - serverURLs: # This configuration is suitable for domestic custom domain name users, overseas version will be automatically detected (no need to manually fill in) - bg: # valine background - visitor: false - option: - -# waline - A simple comment system with backend support fork from Valine -# https://waline.js.org/ -waline: - serverURL: # Waline server address url - bg: # waline background - pageview: false - option: - -# utterances -# https://utteranc.es/ -utterances: - repo: - # Issue Mapping: pathname/url/title/og:title - issue_term: pathname - # Theme: github-light/github-dark/github-dark-orange/icy-dark/dark-blue/photon-dark - light_theme: github-light - dark_theme: photon-dark - -# Facebook Comments Plugin -# https://developers.facebook.com/docs/plugins/comments/ -facebook_comments: - app_id: - user_id: # optional - pageSize: 10 # The number of comments to show - order_by: social # social/time/reverse_time - lang: zh_TW # Language en_US/zh_CN/zh_TW and so on - -# Twikoo -# https://github.com/imaegoo/twikoo -twikoo: - envId: - region: - visitor: false - option: - -# Giscus -# https://giscus.app/ -giscus: - repo: PyQt5/pyqt5.github.io - repo_id: MDEwOlJlcG9zaXRvcnkxODM3MTg4NDA= - category_id: DIC_kwDOCvNTuM4CZ8zK - theme: - light: light - dark: dark - option: - data-strict: 0 - data-emit-metadata: 1 - data-lang: zh-CN - data-loading: lazy - data-category: Announcements - -# Remark42 -# https://remark42.com/docs/configuration/frontend/ -remark42: - host: # Your Host URL - siteId: # Your Site ID - option: - -# Artalk -# https://artalk.js.org/guide/frontend/config.html -artalk: - server: - site: - visitor: false - option: - -# Chat Services -# -------------------------------------- - -# Chat Button [recommend] -# It will create a button in the bottom right corner of website, and hide the origin button -chat_btn: false - -# The origin chat button is displayed when scrolling up, and the button is hidden when scrolling down -chat_hide_show: false - -# chatra -# https://chatra.io/ -chatra: - enable: false - id: - -# tidio -# https://www.tidio.com/ -tidio: - enable: false - public_key: - -# daovoice -# http://dashboard.daovoice.io/app -daovoice: - enable: false - app_id: - -# crisp -# https://crisp.chat/en/ -crisp: - enable: false - website_id: - -# messenger -# https://developers.facebook.com/docs/messenger-platform/discovery/facebook-chat-plugin/ -messenger: - enable: false - pageID: - lang: zh_TW # Language en_US/zh_CN/zh_TW and so on - -# Analysis -# -------------------------------------- - -# Baidu Analytics -# https://tongji.baidu.com/web/welcome/login -baidu_analytics: f7dfd656bdac4e76da8b54bba2978f0b - -# Google Analytics -# https://analytics.google.com/analytics/web/ -google_analytics: - -# Cloudflare Analytics -# https://www.cloudflare.com/zh-tw/web-analytics/ -cloudflare_analytics: - -# Microsoft Clarity -# https://clarity.microsoft.com/ -microsoft_clarity: j6xye2x6np - -# Advertisement -# -------------------------------------- - -# Google Adsense (谷歌廣告) -google_adsense: - enable: false - auto_ads: true - js: https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js - client: - enable_page_level_ads: true - -# Insert ads manually (手動插入廣告) -# ad: -# index: -# aside: -# post: - -# Verification (站長驗證) -# -------------------------------------- - -site_verification: - - name: google-site-verification - content: "L09MDi9gA7mFqsqWfcVVtK_yhV7tPcfBIthuPs-zK4g" - # - name: baidu-site-verification - # content: xxxxxxx - -# Beautify/Effect (美化/效果) -# -------------------------------------- - -# Theme color for customize -# Notice: color value must in double quotes like "#000" or may cause error! - -# theme_color: -# enable: true -# main: "#49B1F5" -# paginator: "#00c4b6" -# button_hover: "#FF7242" -# text_selection: "#00c4b6" -# link_color: "#99a9bf" -# meta_color: "#858585" -# hr_color: "#A4D8FA" -# code_foreground: "#F47466" -# code_background: "rgba(27, 31, 35, .05)" -# toc_color: "#00c4b6" -# blockquote_padding_color: "#49b1f5" -# blockquote_background_color: "#49b1f5" -# scrollbar_color: "#49b1f5" -# meta_theme_color_light: "ffffff" -# meta_theme_color_dark: "#0d0d0d" - -# The top_img settings of home page -# default: top img - full screen, site info - middle (默認top_img全屏,site_info在中間) -# The position of site info, eg: 300px/300em/300rem/10% (主頁標題距離頂部距離) -index_site_info_top: -# The height of top_img, eg: 300px/300em/300rem (主頁top_img高度) -index_top_img_height: - -# The user interface setting of category and tag page (category和tag頁的UI設置) -# index - same as Homepage UI (index 值代表 UI將與首頁的UI一樣) -# default - same as archives UI 默認跟archives頁面UI一樣 -category_ui: index # 留空或 index -tag_ui: index # 留空或 index - -# Stretches the lines so that each line has equal width(文字向兩側對齊,對最後一行無效) -text_align_justify: false - -# Website Background (設置網站背景) -# can set it to color or image (可設置圖片 或者 顔色) -# The formal of image: url(http://xxxxxx.com/xxx.jpg) -background: /images/bg-2.jpg - -# Footer Background -footer_bg: true - -# Add mask to header or footer (为 header 或 footer 添加黑色半透遮罩) -mask: - header: true - footer: true - -# the position of bottom right button/default unit: px (右下角按鈕距離底部的距離/默認單位為px) -rightside-bottom: - -# Enter transitions (開啓網頁進入效果) -enter_transitions: true - -# Typewriter Effect (打字效果) -# https://github.com/disjukr/activate-power-mode -activate_power_mode: - enable: false - colorful: true # open particle animation (冒光特效) - shake: true # open shake (抖動特效) - mobile: false - -# Background effects (背景特效) -# -------------------------------------- - -# canvas_ribbon (靜止彩帶背景) -# See: https://github.com/hustcc/ribbon.js -canvas_ribbon: - enable: true - size: 150 - alpha: 0.6 - zIndex: -1 - click_to_change: true - mobile: true - -# Fluttering Ribbon (動態彩帶) -canvas_fluttering_ribbon: - enable: false - mobile: false - -# canvas_nest -# https://github.com/hustcc/canvas-nest.js -canvas_nest: - enable: false - color: '0,0,255' #color of lines, default: '0,0,0'; RGB values: (R,G,B).(note: use ',' to separate.) - opacity: 0.7 # the opacity of line (0~1), default: 0.5. - zIndex: -1 # z-index property of the background, default: -1. - count: 99 # the number of lines, default: 99. - mobile: false - -# Mouse click effects: fireworks (鼠標點擊效果: 煙火特效) -fireworks: - enable: false - zIndex: 9999 # -1 or 9999 - mobile: false - -# Mouse click effects: Heart symbol (鼠標點擊效果: 愛心) -click_heart: - enable: false - mobile: false - -# Mouse click effects: words (鼠標點擊效果: 文字) -clickShowText: - enable: false - text: - # - I - # - LOVE - # - YOU - fontSize: 15px - random: false - mobile: false - -# Default display mode (網站默認的顯示模式) -# light (default) / dark -display_mode: light - -# Beautify (美化頁面顯示) -beautify: - enable: true - field: post # site/post - title-prefix-icon: '\f0c1' - title-prefix-icon-color: '#F47466' - -# Global font settings -# Don't modify the following settings unless you know how they work (非必要不要修改) -font: - global-font-size: - code-font-size: - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Lato, Roboto, "PingFang SC", "Microsoft JhengHei", "Microsoft YaHei", sans-serif - code-font-family: consolas, Menlo, "PingFang SC", "Microsoft JhengHei", "Microsoft YaHei", sans-serif - -# Font settings for the site title and site subtitle -# 左上角網站名字 主頁居中網站名字 -blog_title_font: - font_link: https://fonts.googleapis.com/css?family=Titillium+Web&display=swap - font-family: Titillium Web, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft JhengHei', 'Microsoft YaHei', sans-serif - -# The setting of divider icon (水平分隔線圖標設置) -hr_icon: - enable: true - icon: # the unicode value of Font Awesome icon, such as '\3423' - icon-top: - -# the subtitle on homepage (主頁subtitle) -subtitle: - enable: true - # Typewriter Effect (打字效果) - effect: true - # Customize typed.js (配置typed.js) - # https://github.com/mattboldt/typed.js/#customization - typed_option: - loop: true - # source 調用第三方服務 - # source: false 關閉調用 - # source: 1 調用一言網的一句話(簡體) https://hitokoto.cn/ - # source: 2 調用一句網(簡體) https://yijuzhan.com/ - # source: 3 調用今日詩詞(簡體) https://www.jinrishici.com/ - # subtitle 會先顯示 source , 再顯示 sub 的內容 - source: 1 - # 如果關閉打字效果,subtitle 只會顯示 sub 的第一行文字 - sub: - - 今日事,今日毕 - - Never put off till tomorrow what you can do today - -# Loading Animation (加載動畫) -preloader: - enable: false - # source - # 1. fullpage-loading - # 2. pace (progress bar) - source: 1 - # pace theme (see https://codebyzach.github.io/pace/) - pace_css_url: - -# wordcount (字數統計) -# see https://butterfly.js.org/posts/ceeb73f/#字數統計 -wordcount: - enable: true - post_wordcount: true - min2read: true - total_wordcount: true - -# Lightbox (圖片大圖查看模式) -# -------------------------------------- -# You can only choose one, or neither (只能選擇一個 或者 兩個都不選) - -# medium-zoom -# https://github.com/francoischalifour/medium-zoom -medium_zoom: false - -# fancybox -# https://fancyapps.com/fancybox/ -fancybox: true - -# Tag Plugins settings (標籤外掛) -# -------------------------------------- - -# series (系列文章) -series: - enable: true - orderBy: 'title' # Order by title or date - order: 1 # Sort of order. 1, asc for ascending; -1, desc for descending - number: true - -# abcjs (樂譜渲染) -# See https://github.com/paulrosen/abcjs -abcjs: - enable: true - per_page: false - -# mermaid -# see https://github.com/mermaid-js/mermaid -mermaid: - enable: true - # built-in themes: default/forest/dark/neutral - theme: - light: default - dark: dark - -# Note (Bootstrap Callout) -note: - # Note tag style values: - # - simple bs-callout old alert style. Default. - # - modern bs-callout new (v2-v3) alert style. - # - flat flat callout style with background, like on Mozilla or StackOverflow. - # - disabled disable all CSS styles import of note tag. - style: flat - icons: true - border_radius: 3 - # Offset lighter of background in % for modern and flat styles (modern: -12 | 12; flat: -18 | 6). - # Offset also applied to label tag variables. This option can work with disabled note tag. - light_bg_offset: 0 - -# other -# -------------------------------------- - -# Pjax -# It may contain bugs and unstable, give feedback when you find the bugs. -# https://github.com/MoOx/pjax -pjax: - enable: true - exclude: - - /talking/ - -# Inject the css and script (aplayer/meting) -aplayerInject: - enable: false - per_page: true - -# Snackbar (Toast Notification 彈窗) -# https://github.com/polonel/SnackBar -# position 彈窗位置 -# 可選 top-left / top-center / top-right / bottom-left / bottom-center / bottom-right -snackbar: - enable: false - position: bottom-center - bg_light: '#49b1f5' # The background color of Toast Notification in light mode - bg_dark: '#1f1f1f' # The background color of Toast Notification in dark mode - -# https://instant.page/ -# prefetch (預加載) -instantpage: true - -# https://github.com/vinta/pangu.js -# Insert a space between Chinese character and English character (中英文之間添加空格) -pangu: - enable: false - field: site # site/post - -# Lazyload (圖片懶加載) -# https://github.com/verlok/vanilla-lazyload -lazyload: - enable: true - field: site # site/post - placeholder: /images/2.gif - blur: false - -# PWA -# See https://github.com/JLHwung/hexo-offline -# --------------- -pwa: - enable: false -# manifest: /pwa/manifest.json -# apple_touch_icon: /pwa/apple-touch-icon.png -# favicon_32_32: /pwa/32.png -# favicon_16_16: /pwa/16.png -# mask_icon: /pwa/safari-pinned-tab.svg - -# Open graph meta tags -# https://developers.facebook.com/docs/sharing/webmasters/ -Open_Graph_meta: - enable: true - option: - # twitter_card: - # twitter_image: - # twitter_id: - # twitter_site: - # google_plus: - # fb_admins: - # fb_app_id: - -# Add the vendor prefixes to ensure compatibility -css_prefix: true - -# Inject -# Insert the code to head (before '' tag) and the bottom (before '' tag) -# 插入代码到头部 之前 和 底部 之前 -inject: - head: - - - - - bottom: - - - -# CDN -# Don't modify the following settings unless you know how they work -# 非必要請不要修改 -CDN: - # The CDN provider of internal scripts (主題內部 js 的 cdn 配置) - # option: local/jsdelivr/unpkg/cdnjs/custom - # Dev version can only choose. ( dev版的主題只能設置為 local ) - internal_provider: custom - - # The CDN provider of third party scripts (第三方 js 的 cdn 配置) - # option: local/jsdelivr/unpkg/cdnjs/custom - # when set it to local, you need to install hexo-butterfly-extjs - third_party_provider: custom - - # Add version number to url, true or false - version: false - - # Custom format - # For example: https://cdn.staticfile.org/${cdnjs_name}/${version}/${min_cdnjs_file} - custom_format: https://jsd.012700.xyz/npm/${name}@latest/${min_file} - - option: - # abcjs_basic_js: - # activate_power_mode: - # algolia_js: - # algolia_search: - # aplayer_css: - # aplayer_js: - # artalk_css: - # artalk_js: - # blueimp_md5: - # busuanzi: - # canvas_fluttering_ribbon: - # canvas_nest: - # canvas_ribbon: - # click_heart: - # clickShowText: - # disqusjs: - # disqusjs_css: - # docsearch_css: - # docsearch_js: - # egjs_infinitegrid: - # fancybox: - # fancybox_css: - # fireworks: - # fontawesome: - # gitalk: - # gitalk_css: - # giscus: - # instantpage: - # instantsearch: - # katex: - # katex_copytex: - # lazyload: - # local_search: - # main: - # main_css: - # mathjax: - # medium_zoom: - # mermaid: - # meting_js: - # pangu: - # prismjs_autoloader: - # prismjs_js: - # prismjs_lineNumber_js: - # pjax: - # sharejs: - # sharejs_css: - # snackbar: - # snackbar_css: - # translate: - # twikoo: - # typed: - # utils: - # valine: - # waline_css: - # waline_js: diff --git a/_config.fluid.yml b/_config.fluid.yml deleted file mode 100644 index 38794875..00000000 --- a/_config.fluid.yml +++ /dev/null @@ -1,3 +0,0 @@ -# Hexo Configuration -## Docs: https://hexo.io/docs/configuration.html -## Source: https://github.com/hexojs/hexo/ diff --git a/_config.matery.yml b/_config.matery.yml deleted file mode 100644 index 38794875..00000000 --- a/_config.matery.yml +++ /dev/null @@ -1,3 +0,0 @@ -# Hexo Configuration -## Docs: https://hexo.io/docs/configuration.html -## Source: https://github.com/hexojs/hexo/ diff --git a/_config.nexmoe.yml b/_config.nexmoe.yml deleted file mode 100644 index 38794875..00000000 --- a/_config.nexmoe.yml +++ /dev/null @@ -1,3 +0,0 @@ -# Hexo Configuration -## Docs: https://hexo.io/docs/configuration.html -## Source: https://github.com/hexojs/hexo/ diff --git a/_config.shoka.yml b/_config.shoka.yml deleted file mode 100644 index f6fb6601..00000000 --- a/_config.shoka.yml +++ /dev/null @@ -1,105 +0,0 @@ -# Hexo Configuration -## Docs: https://hexo.io/docs/configuration.html -## Source: https://github.com/hexojs/hexo/ - -# Site -alternate: PyQt - -# Writing -highlight: - enable: false -prismjs: - enable: false - -autoprefixer: - exclude: - - "*.min.css" - -markdown: - render: # 渲染器设置 - html: false # 过滤 HTML 标签 - xhtmlOut: true # 使用 '/' 来闭合单标签 (比如
)。 - breaks: true # 转换段落里的 '\n' 到
。 - linkify: true # 将类似 URL 的文本自动转换为链接。 - typographer: - quotes: "“”‘’" - plugins: # markdown-it插件设置 - - plugin: - name: markdown-it-toc-and-anchor - enable: true - options: # 文章目录以及锚点应用的class名称,shoka主题必须设置成这样 - tocClassName: "toc" - anchorClassName: "anchor" - - plugin: - name: markdown-it-multimd-table - enable: true - options: - multiline: true - rowspan: true - headerless: true - - plugin: - name: ./markdown-it-furigana - enable: true - options: - fallbackParens: "()" - - plugin: - name: ./markdown-it-spoiler - enable: true - options: - title: "你知道得太多了" - -minify: - html: - enable: true - stamp: false - exclude: - - "**/json.ejs" - - "**/atom.ejs" - - "**/rss.ejs" - css: - enable: true - stamp: false - exclude: - - "**/*.min.css" - js: - enable: true - stamp: false - mangle: - toplevel: true - output: - compress: - exclude: - - "**/*.min.js" - -# algolia: -# appId: -# apiKey: -# adminApiKey: -# chunkSize: 5000 -# indexName: -# fields: -# - title #必须配置 -# - path #必须配置 -# - categories #推荐配置 -# - content:strip:truncate,0,4000 -# - gallery -# - photos -# - tags - -feed: - limit: 20 - order_by: "-date" - tag_dir: false - category_dir: false - rss: - enable: true - template: "themes/shoka/layout/_alternate/rss.ejs" - output: "rss.xml" - atom: - enable: true - template: "themes/shoka/layout/_alternate/atom.ejs" - output: "atom.xml" - jsonFeed: - enable: true - template: "themes/shoka/layout/_alternate/json.ejs" - output: "feed.json" diff --git a/_config.volantis.yml b/_config.volantis.yml deleted file mode 100644 index 38794875..00000000 --- a/_config.volantis.yml +++ /dev/null @@ -1,3 +0,0 @@ -# Hexo Configuration -## Docs: https://hexo.io/docs/configuration.html -## Source: https://github.com/hexojs/hexo/ diff --git a/_config.yelee.yml b/_config.yelee.yml deleted file mode 100644 index 993fcfe5..00000000 --- a/_config.yelee.yml +++ /dev/null @@ -1,54 +0,0 @@ -# Hexo Configuration -## Docs: https://hexo.io/docs/configuration.html -## Source: https://github.com/hexojs/hexo/ - -# Site -language: zh-Hans - -# hexo-tag-cloud -tag_cloud: - textFont: Trebuchet MS, Helvetica - textColour: \#333 - textHeight: 25 - outlineColour: \#ffffff - -# Writing -highlight: - enable: false - -#prettify 插件位置 -# enable 启用和不启用 -# theme 使用prettify高亮主题名称 -prettify: - enable: true - theme: tomorrow-night-eighties ##这里你可以定义上面下载的themes主题包里面样式文件名,不带.css后缀 - -lazyload: - enable: false - onlypost: false - loadingImg: /img/loading0_2.gif - -# Markdown-it config 表情支持 -## Docs: https://github.com/celsomiranda/hexo-renderer-markdown-it/wiki -## http://www.cnblogs.com/fsong/p/5929773.html -markdown: - render: - html: true - xhtmlOut: false - breaks: true - linkify: true - typographer: true - quotes: "“”‘’" - plugins: - - markdown-it-abbr - - markdown-it-footnote - - markdown-it-ins - - markdown-it-sub - - markdown-it-sup - - markdown-it-emoji # add emoji - anchors: - level: 2 - collisionSuffix: "v" - permalink: true - permalinkClass: header-anchor - permalinkSymbol: "" diff --git a/_config.yml b/_config.yml deleted file mode 100644 index 98d3a134..00000000 --- a/_config.yml +++ /dev/null @@ -1,277 +0,0 @@ -# Hexo Configuration -## Docs: https://hexo.io/docs/configuration.html -## Source: https://github.com/hexojs/hexo/ - -# Site -title: PyQt -subtitle: 个人学习经验分享 -description: Python PyQt PyQt6 PyQt5 PyQt4 PySide PySide2 PySide6 -keywords: Python,PyQt,PyQt6,PyQt5,PyQt4,PySide,PySide2,PySide6 -author: Irony -language: zh-CN -timezone: "Asia/Shanghai" -email: "892768447@qq.com" - -# URL -## Set your site url here. For example, if you use GitHub Page, set url as 'https://username.github.io/project' -url: https://pyqt5.com -root: / -# permalink: :year/:month/:day/:title/ -permalink: :title.html -permalink_defaults: -pretty_urls: - trailing_index: true # Set to false to remove trailing 'index.html' from permalinks - trailing_html: true # Set to false to remove trailing '.html' from permalinks - -# Directory -source_dir: source -public_dir: public -tag_dir: tags -archive_dir: archives -category_dir: categories -code_dir: downloads/code -i18n_dir: :lang -##要告诉hexo对plugins目录下的所有文件跳过解析渲染,因为测试时发现如果不配置,加载prettify的相关js会报脚本错误 -skip_render: - - "plugins/**" - - "search.html" - -# Writing -new_post_name: :title.md # File name of new posts -default_layout: post -titlecase: false # Transform title into titlecase -external_link: - enable: true # Open external links in new tab - field: site # Apply to the whole site - exclude: "" -filename_case: 0 -render_drafts: false -post_asset_folder: false -relative_link: false -future: true -highlight: - enable: false - line_number: false - auto_detect: true - tab_replace: "" - wrap: true - hljs: false -prismjs: - enable: true - preprocess: true - line_number: false - tab_replace: "" - -# Home page setting -# path: Root path for your blogs index page. (default = '') -# per_page: Posts displayed per page. (0 = disable pagination) -# order_by: Posts order. (Order by date descending by default) -index_generator: - path: "" - per_page: 10 - order_by: -date - -# Category & Tag -default_category: uncategorized -category_map: -tag_map: - -# Metadata elements -## https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta -meta_generator: true - -# Date / Time format -## Hexo uses Moment.js to parse and display date -## You can customize the date format as defined in -## http://momentjs.com/docs/#/displaying/format/ -date_format: YYYY-MM-DD -time_format: HH:mm:ss -## updated_option supports 'mtime', 'date', 'empty' -updated_option: "mtime" - -# Pagination -## Set per_page to 0 to disable pagination -per_page: 10 -pagination_dir: page - -# Include / Exclude file(s) -## include:/exclude: options only apply to the 'source/' folder -include: -exclude: -ignore: - -# Extensions -## Plugins: https://hexo.io/plugins/ -## Themes: https://hexo.io/themes/ -theme: butterfly - -# Deployment -## Docs: https://hexo.io/docs/deployment.html -deploy: - - type: git - repo: https://github.com/PyQt5/blog - branch: [master] - message: [message] - token: $GITHUB_TOKEN - -search: - path: search.xml - field: post - content: true - format: html - -# 备案 -record: "蜀ICP备18031575号-1" - -archive_generator: - per_page: 10 ##归档页面默认10篇文章标题 - yearly: true ##生成年视图 - monthly: true ##生成月视图 - -tag_generator: - per_page: 10 ##标签分类页面默认10篇文章 - -category_generator: - per_page: 10 ###分类页面默认10篇文章 - -feed: - type: atom ##feed类型 atom或者rss2 - path: atom.xml ##feed路径 - limit: 20 ##feed文章最小数量 - -nofollow: - enable: true - field: site - exclude: - -#sitemap -sitemap: - path: sitemap.xml - rel: false - tags: true - categories: true - -marked: - smartypants: false - descriptionLists: false - -baidusitemap: - path: baidusitemap.xml - -# # json api -# jsonContent: -# meta: true -# dafts: false -# pages: false -# dateFormat: YYYY-MM-DD HH:mm:ss -# file: content.json -# posts: -# title: true -# slug: true -# date: true -# updated: false -# comments: false -# path: true -# link: true -# permalink: true -# excerpt: true -# keywords: false -# text: false -# raw: true -# content: false -# author: true -# categories: true -# tags: true - -# # restful api -# restful: -# # site 可配置为数组选择性生成某些属性 -# site: -# [ -# "title", -# "subtitle", -# "description", -# "author", -# "since", -# "email", -# "favicon", -# "avatar", -# ] -# # site: true # hexo.config mix theme.config -# posts_size: 10 # 文章列表分页,0 表示不分页 -# posts_props: # 文章列表项的需要生成的属性 -# title: true -# slug: true -# date: true -# updated: true -# comments: false -# path: true -# excerpt: true -# cover: true # 封面图,取文章第一张图片 -# content: true -# raw: true -# keywords: false -# categories: true -# tags: true -# categories: true # 分类数据 -# use_category_slug: false # Use slug for filename of category data -# tags: true # 标签数据 -# use_tag_slug: false # Use slug for filename of tag data -# post: true # 文章数据 -# pages: true # 额外的 Hexo 页面数据, 如 About - -# envelope_comment -# see https://akilar.top/posts/e2d3c450/ -envelope_comment: - enable: true #控制开关 - custom_pic: - cover: https://npm.elemecdn.com/hexo-butterfly-envelope/lib/violet.jpg #信笺头部图片 - line: https://npm.elemecdn.com/hexo-butterfly-envelope/lib/line.png #信笺底部图片 - beforeimg: https://npm.elemecdn.com/hexo-butterfly-envelope/lib/before.png # 信封前半部分 - afterimg: https://npm.elemecdn.com/hexo-butterfly-envelope/lib/after.png # 信封后半部分 - message: #信笺正文,多行文本,写法如下 - - 有什么想问的? - - 有什么想说的? - - 有什么想吐槽的? - - 哪怕是有什么想吃的,都可以告诉我哦~ - bottom: 自动书记人偶竭诚为您服务! #仅支持单行文本 - height: #1024px,信封划出的高度 - path: #【可选】comments 的路径名称。默认为 comments,生成的页面为 comments/index.html - front_matter: #【可选】comments页面的 front_matter 配置 - title: 留言板 - comments: true - top_img: false - type: envelope - -# 追番插件 -# https://github.com/HCLonely/hexo-bilibili-bangumi -bangumi: # 追番设置 - enable: false - source: bili - path: - vmid: 372204786 - title: "追番列表" - quote: "生命不息,追番不止!" - show: 1 - lazyload: false - loading: - showMyComment: false - pagination: false - metaColor: - color: - webp: - progress: - extraOrder: - proxy: - host: "代理host" - port: "代理端口" - extra_options: - top_img: false - lazyload: - enable: false - -# APlayer -# https://github.com/MoePlayer/hexo-tag-aplayer/blob/master/docs/README-zh_cn.md -aplayer: - meting: true - asset_inject: false \ No newline at end of file diff --git a/createThumb.py b/createThumb.py deleted file mode 100644 index c2247cd5..00000000 --- a/createThumb.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -""" -Created on 2019年6月17日 -@author: Irony -@site: -@email: 892768447@qq.com -@file: -@description: 生成缩略图 -""" -import os -import sys -import traceback - -import requests -from PIL import Image - -try: - os.mkdir('tmp') -except Exception: - pass - - -def download(url, src, dst): - try: - resp = requests.get(url) - open(src, 'wb').write(resp.content) - thumbnail(src, dst) - except Exception: - traceback.print_exc() - - -def thumbnail(src, dst): - try: - img = Image.open(src) - img = img.convert('RGB') - img.thumbnail((80, 80), Image.ANTIALIAS) - img.save(dst) - except Exception: - traceback.print_exc() - - -if __name__ == '__main__': - length = len(sys.argv) - if length == 3: - # 本地文件生成缩略图 - _, src, dst = sys.argv - thumbnail(src, dst) - elif length == 4: - # 远程文件生成缩略图 - _, url, src, dst = sys.argv - if url.find('jsdelivr') > -1 or url.find('jsd.') > -1: - print('ignore cdn file') - else: - download(url, src, dst) diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index 3e6a1ab5..00000000 --- a/gulpfile.js +++ /dev/null @@ -1,123 +0,0 @@ -var gulp = require('gulp'); -var minifycss = require('gulp-minify-css'); -var uglify = require('gulp-uglify'); -var htmlmin = require('gulp-htmlmin'); -var htmlclean = require('gulp-htmlclean'); -var minifyInline = require('gulp-minify-inline'); -var inline = require('gulp-inline'); -var inlineimage = require('gulp-inline-image'); -var rename = require('gulp-rename'); -var jshint=require('gulp-jshint'); -var concat = require('gulp-concat'); - -// 获取 gulp-imagemin 模块 -var imagemin = require('gulp-imagemin') - -//语法检查 -gulp.task('jshint', function () { - return gulp.src('js/*.js') - .pipe(jshint()) - .pipe(jshint.reporter('default')); -}); - -// public 目录 css -gulp.task('minify-css', function () { - return gulp.src('./public/css/*.css') - .pipe(inlineimage()) - .pipe(minifycss()) - .pipe(gulp.dest('./public/css')); -}); -gulp.task('plugins-css', function () { - return gulp.src('./public/plugins/**/*.css') - .pipe(inlineimage()) - .pipe(minifycss()) - .pipe(gulp.dest('./public/plugins')); -}); -gulp.task('special-css', function () { - return gulp.src('./public/plugins/css/special.css') - .pipe(inlineimage()) - .pipe(minifycss()) - .pipe(gulp.dest('./public/plugins/css/')); -}); -gulp.task('search-css', function () { - return gulp.src('./public/search/**/*.css') - .pipe(inlineimage()) - .pipe(minifycss()) - .pipe(gulp.dest('./public/search')); -}); -gulp.task('mylove-css', function () { - return gulp.src('./public/mylove/css/*.css') - .pipe(inlineimage()) - .pipe(minifycss()) - .pipe(gulp.dest('./public/mylove/css')); -}); - -// 压缩 public 目录内 html -gulp.task('minify-html', function () { - var opts = { - removeComments: true,//清除 HTML 注释 - minifyJS: true,////压缩页面 JS - minifyCSS: true,//压缩页面 CSS - minifyURLs: true, - collapseWhitespace: true,//压缩 HTML - collapseBooleanAttributes: true,//省略布尔属性的值 ==> - removeEmptyAttributes: true,//删除所有空格作属性值 ==> - removeScriptTypeAttributes: true,//删除 \ No newline at end of file diff --git a/source/CNAME b/source/CNAME deleted file mode 100644 index 99592d2f..00000000 --- a/source/CNAME +++ /dev/null @@ -1 +0,0 @@ -blog.pyqt5.com diff --git a/source/_data/link.yml b/source/_data/link.yml deleted file mode 100644 index 483010ee..00000000 --- a/source/_data/link.yml +++ /dev/null @@ -1,15 +0,0 @@ -- class_name: 网站 - class_desc: 一些常用的网站 - link_list: - - name: Qt - link: https://doc.qt.io/qt-5/qwidget.html - avatar: https://d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/images/favicon-32x32.png - descr: Qt官方文档 - - name: Python - link: https://www.python.org/ - avatar: https://www.python.org/static/favicon.ico - descr: 强有力的编程语言 - - name: GitHub - link: https://github.com/ - avatar: https://github.githubassets.com/favicons/favicon.png - descr: 全球最大的交友网站 diff --git a/source/_posts/QPropertyAnimation.md b/source/_posts/QPropertyAnimation.md deleted file mode 100644 index 36f57a76..00000000 --- a/source/_posts/QPropertyAnimation.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -author: Irony -title: PyQt属性动画(QPropertyAnimation) -date: 2019-05-08 15:43:06 -tags: - - PyQt - - 动画 -categories: 笔记 ---- - -`QPropertyAnimation`继承自`QVariantAnimation`,其作为Qt的属性动画用于针对控件的属性或者继承自`QObject`的对象中定义的属性做修改, -简单来说就是基类是`QObject`且定义了属性变量,就可以用`QPropertyAnimation`来做属性动画。同时也可以通过`pyqtProperty`来增加自定义属性。 - - -首先,通过构造函数`QPropertyAnimation(QObject, Union[QByteArray, bytes, bytearray], parent: QObject = None)`创建一个对象,其中 - -1. 第一个参数是动画作用的对象,也可以通过`setTargetObject`设置 -2. 第二个参数是属性名,在py3中类型是bytes,也可以通过`setPropertyName`设置 - -## 函数 - -一些常见的设置函数 - -| | | -| :-------------- | :---------- | -| setPropertyName | 设置属性名 | -| setTargetObject | 设置动画作用对象 | -| setDuration | 设置动画持续时间(毫秒) | -| setStartValue | 设置开始值 | -| setEndValue | 设置结束值 | -| setEasingCurve | 设置动画曲线 | -| setKeyValueAt | 插入线性值 | -| setLoopCount | 设置循环次数(-1为永久) | - -## 示例 - -比如这个例子: - -1. 修改控件的`geometry`大小 -2. 修改自定义属性 -3. 修改进度条的value值 - -![QPropertyAnimation](/images/QPropertyAnimation.gif) - -```python -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -""" -Created on 2019年5月8日 -@author: Irony -@site: https://pyqt5.com https://github.com/892768447 -@email: 892768447@qq.com -@file: -@description: -""" -from PyQt5.QtCore import QPropertyAnimation, QRect, pyqtProperty, QEasingCurve -from PyQt5.QtWidgets import QWidget, QPushButton, QVBoxLayout,\ - QLabel, QProgressBar, QSpacerItem, QSizePolicy - - -__Author__ = 'Irony' -__Copyright__ = 'Copyright (c) 2019 Irony' -__Version__ = 1.0 - - -class Window(QWidget): - - def __init__(self, *args, **kwargs): - super(Window, self).__init__(*args, **kwargs) - self.resize(400, 400) - self._value = 0 - self.button = QPushButton('属性动画测试', self) - self.button.clicked.connect(self.doStart) - self.button.setGeometry(0, 0, 80, 40) - - self.buttonc = QPushButton('自定义属性 测试', self) - self.buttonc.clicked.connect(self.doStartCustom) - - self.label = QLabel('', self) - - self.progressbar = QProgressBar(self) - self.progressbar.setRange(0, 99) - - layout = QVBoxLayout(self) - layout.addItem(QSpacerItem( - 20, 60, QSizePolicy.Fixed, QSizePolicy.Fixed)) - layout.addWidget(self.buttonc) - layout.addWidget(self.label) - layout.addWidget(self.progressbar) - - # 进度条动画 - self.progressStart() - - # 此处是自定义属性,并通过动画修改后,设置QLabel的值 - @pyqtProperty(int) - def value(self): - return self._value - - @value.setter - def value(self, v): - self._value = v - self.label.setText('当前值:{}'.format(v)) - - def doStart(self): - # 第一个参数是要执行的对象 - animation = QPropertyAnimation(self.button, b'geometry', self) - animation.setDuration(2000) # 持续时间 - # 缓和曲线风格,加了曲线动画会很大程度影响 - animation.setEasingCurve(QEasingCurve.OutBounce) - animation.setStartValue(QRect(0, 0, 40, 40)) - animation.setEndValue(QRect(250, 250, 80, 80)) - animation.start(animation.DeleteWhenStopped) - - def doStartCustom(self): - # 自定义属性动画 - # 由于定义的属性是在继承的QWidget, 所以第一个参数是self - # 第二个参数就是 value - animation = QPropertyAnimation(self, b'value', self) - animation.setDuration(2000) # 持续时间 - animation.setStartValue(0) - animation.setEndValue(100) - animation.start(animation.DeleteWhenStopped) - - def progressStart(self): - # 进度条动画 - # 这里 value是QProgressBar自带的属性,具体可以看文档 - # https://doc.qt.io/qt-5/qprogressbar.html#properties - animation = QPropertyAnimation(self.progressbar, b'value', self) - animation.setDuration(2000) # 持续时间 - animation.setLoopCount(-1) - # 这里采用插入线性值,第一个参数的范围是(0-1) - # 第二个参数的范围是进度(最小值-最大值) - animation.setKeyValueAt(0, self.progressbar.minimum()) - animation.setKeyValueAt(0.1, 10) - animation.setKeyValueAt(0.2, 30) - animation.setKeyValueAt(0.5, 60) - animation.setKeyValueAt(0.7, 80) - animation.setKeyValueAt(1, self.progressbar.maximum()) - animation.start(animation.DeleteWhenStopped) - - -if __name__ == '__main__': - import sys - from PyQt5.QtWidgets import QApplication - app = QApplication(sys.argv) - w = Window() - w.show() - sys.exit(app.exec_()) - -``` \ No newline at end of file diff --git a/source/_posts/animateshadow.md b/source/_posts/animateshadow.md deleted file mode 100644 index 78fb8b78..00000000 --- a/source/_posts/animateshadow.md +++ /dev/null @@ -1,158 +0,0 @@ ---- -author: Irony -title: PyQt5动画边框阴影 -date: 2018-09-25 23:38:12 -tags: - - PyQt - - 动画 - - 阴影 -categories: 例子 ---- - -为子控件增加动画阴影效果,结合`QGraphicsDropShadowEffect`和`QPropertyAnimation`动态改变阴影半径达到效果,在旧版本的Qt中`QGraphicsDropShadowEffect`可能会有点问题(父控件会影响子控件) - - -## 原理 - -原理是利用QGraphicsDropShadowEffect添加边框阴影,然后使用动画不停改变阴影的模糊半径来达到效果,如图: - -![ShadowEffect](/PyQt/QGraphicsDropShadowEffect/ScreenShot/ShadowEffect.gif) - -## 简单说明 - -1. 继承`QGraphicsDropShadowEffect`增加动态属性`radius` -2. 通过`setGraphicsEffect`方法设置控件的边框阴影 -3. 通过`QPropertyAnimation`属性动画不断改变`radius`的值并调用`setBlurRadius`更新半径值 - -https://github.com/PyQt5/PyQt/blob/master/QGraphicsDropShadowEffect/ShadowEffect.py - -## 自定义类 - -```python -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -""" -Created on 2018年9月25日 -@author: Irony -@site: https://pyqt5.com, https://github.com/892768447 -@email: 892768447@qq.com -@file: AnimationShadowEffect -@description: 边框动画阴影动画 -""" -from PyQt5.QtCore import QPropertyAnimation, pyqtProperty -from PyQt5.QtWidgets import QGraphicsDropShadowEffect - - -__Author__ = """By: Irony -QQ: 892768447 -Email: 892768447@qq.com""" -__Copyright__ = 'Copyright (c) 2018 Irony' -__Version__ = 1.0 - - -class AnimationShadowEffect(QGraphicsDropShadowEffect): - - def __init__(self, color, *args, **kwargs): - super(AnimationShadowEffect, self).__init__(*args, **kwargs) - self.setColor(color) - self.setOffset(0, 0) - self.setBlurRadius(0) - self._radius = 0 - self.animation = QPropertyAnimation(self) - self.animation.setTargetObject(self) - self.animation.setDuration(2000) # 一次循环时间 - self.animation.setLoopCount(-1) # 永久循环 - self.animation.setPropertyName(b'radius') - # 插入线行值 - self.animation.setKeyValueAt(0, 1) - self.animation.setKeyValueAt(0.5, 30) - self.animation.setKeyValueAt(1, 1) - - def start(self): - self.animation.start() - - @pyqtProperty(int) - def radius(self): - return self._radius - - @radius.setter - def radius(self, r): - self._radius = r - self.setBlurRadius(r) -``` - -## 测试代码 - -```python -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -""" -Created on 2018年9月25日 -@author: Irony -@site: https://pyqt5.com, https://github.com/892768447 -@email: 892768447@qq.com -@file: Test -@description: -""" -from PyQt5.QtCore import Qt -from PyQt5.QtGui import QPixmap -from PyQt5.QtWidgets import QWidget, QHBoxLayout, QLabel, QPushButton, QLineEdit - -from AnimationShadowEffect import AnimationShadowEffect # @UnresolvedImport - - -__Author__ = """By: Irony -QQ: 892768447 -Email: 892768447@qq.com""" -__Copyright__ = 'Copyright (c) 2018 Irony' -__Version__ = 1.0 - - -class Window(QWidget): - - def __init__(self, *args, **kwargs): - super(Window, self).__init__(*args, **kwargs) - layout = QHBoxLayout(self) - - # 绿色边框 - labelGreen = QLabel(self, pixmap=QPixmap('1.jpg').scaled(100, 100)) - layout.addWidget(labelGreen) - aniGreen = AnimationShadowEffect(Qt.darkGreen, labelGreen) - labelGreen.setGraphicsEffect(aniGreen) - aniGreen.start() - - # 红色边框,圆形图片 - labelRed = QLabel(self) - labelRed.setMinimumSize(100, 100) - labelRed.setMaximumSize(100, 100) - labelRed.setStyleSheet('border-image: url(1.jpg);border-radius: 50px;') - layout.addWidget(labelRed) - aniRed = AnimationShadowEffect(Qt.red, labelGreen) - labelRed.setGraphicsEffect(aniRed) - aniRed.start() - - # 蓝色边框按钮 - button = QPushButton('按钮', self) - aniButton = AnimationShadowEffect(Qt.blue, button) - layout.addWidget(button) - button.setGraphicsEffect(aniButton) - aniButton.start() - - # 青色边框输入框 - lineedit = QLineEdit(self) - aniEdit = AnimationShadowEffect(Qt.cyan, lineedit) - layout.addWidget(lineedit) - lineedit.setGraphicsEffect(aniEdit) - aniEdit.start() - - -if __name__ == '__main__': - import sys - from PyQt5.QtWidgets import QApplication - app = QApplication(sys.argv) - w = Window() - w.show() - sys.exit(app.exec_()) -``` \ No newline at end of file diff --git a/source/_posts/bindsignals.md b/source/_posts/bindsignals.md deleted file mode 100644 index 2a68c1e6..00000000 --- a/source/_posts/bindsignals.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -author: Irony -title: 三种方式绑定信号槽 -date: 2019-05-04 16:07:06 -tags: - - PyQt - - 信号 -categories: 教程 ---- -网上关于PyQt5的信号绑定使用的教程比较上,很多还是以前的绑定方式,导致在PyQt5中无法使用,这里归纳总结下已有的几种绑定信号槽的方式, -这几种方式各有各的优点和缺点。 - - -## 方式一 - -这个方式是最开始接触设计师的时候知道的,主要是通过控件的`objectName`和`QtCore.QMetaObject.connectSlotsByName(Form)`提供的连接函数来自动完成注册, -比如带有按钮的界面ui文件转成py文件后会发现如下代码: -```python -self.pushButton = QtWidgets.QPushButton(Form) -self.pushButton.setGeometry(QtCore.QRect(60, 40, 93, 28)) -self.pushButton.setObjectName("pushButton") - -# 通过这里自动完成连接信号槽 -QtCore.QMetaObject.connectSlotsByName(Form) -``` - -此时只需要继承该UI文件类然后增加如下方法: -```python - -@pyqtSlot() -def on_pushButton_clicked(self): - print('button clicked') -``` - -这里解释一下,`@pyqtSlot()`装饰器把函数`on_pushButton_clicked`包装为一个槽函数, -而`QtCore.QMetaObject.connectSlotsByName(Form)`这句代码的意思就是自动去寻找满足的槽函数 - -注意:这里有个规范(on_xxxx_clicked),这里必须要满足`on_控件的objectName_控件的信号`这样下划线连接起来的函数名才能被识别, -比如按钮的点击:`on_pushButton_clicked`、勾选框的选中:`on_checkbox_toggled(self, checked)` - -## 方式二 - -这种方式则直接通过代码里调用控件的信号的`connect`方法来进行绑定,比如: -```python -# 按钮点击函数 -def doClicked(self): - print(self.sender(), 'clicked') - -# 绑定点击信号 -self.pushButton.clicked.connect(self.doClicked) -``` - -注意:`connect`的是函数名字,`self.sender()`这句代码是获取信号发送者(比如这里就是得到这个按钮对象), -用处在于有时候要循环创建一堆按钮 - -## 方式三 - -通过参数这种方式其实比较特殊,在PyQt中大部分存在,但是在PySide中则很少,原因是两者的封装方式不同。 - -同时该方式用于在纯代码中比较常见,而且需要对该控件有那些信号可以用要很熟习,比如: -```python - -# 按钮点击函数 -def doClicked(self): - print(self.sender(), 'clicked') - -pushButton = QPushButton('按钮', self, clicked=self.doClicked, minimumHeight=40) -``` - -这里可以通过参数(信号名字) = 函数来绑定信号 - -同时也可以设置其它参数,比如 -`button.setMinimumHeight(40)`也可以像参数里那样设置`minimumHeight=40` diff --git a/source/_posts/calljava.md b/source/_posts/calljava.md deleted file mode 100644 index 5c9b3981..00000000 --- a/source/_posts/calljava.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -author: Irony -title: Python调用Java对Excel截图 -date: 2019-03-12 21:15:06 -tags: - - Python - - 截图 -categories: 教程 ---- - -有的时候会遇到一些奇葩的需求,就是用Excel做报表,但是需要对里面的数据进行填充并生成报表图片,发送出去。这里记录用python调用jar包对excel文件进行公式计算和截图,数据填充可以用xlrd或者openpyxl - - -利用`jpype`模块初始化java虚拟机加载jar包然后执行其中的功能。 - -## 代码 - -```python -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -""" -Created on 2019年3月12日 -@author: Irony -@site: https://pyqt5.com https://github.com/892768447 -@email: 892768447@qq.com -@file: CallJava -@description: -""" -import os - -import jpype - - -__Author__ = 'Irony' -__Copyright__ = 'Copyright (c) 2019' - - -def convertToImage(): - Workbook = jpype.JClass('com.aspose.cells.Workbook') - ImageFormat = jpype.JClass('com.aspose.cells.ImageFormat') - ImageOrPrintOptions = jpype.JClass( - 'com.aspose.cells.ImageOrPrintOptions') - SheetRender = jpype.JClass('com.aspose.cells.SheetRender') - - book = Workbook(os.path.abspath('data/test.xlsx').replace('\\', '/')) - # 保存为html - book.save('data/index.html', 12) - # 保存为pdf - book.save('data/test.pdf') - - # 截图 - imgOptions = ImageOrPrintOptions() - # imgOptions.setQuality(100) - imgOptions.setOnePagePerSheet(True) - - # 输出图片格式 -# imgOptions.setImageFormat(ImageFormat.getJpeg()) - imgOptions.setImageFormat(ImageFormat.getPng()) - - # 计算 - CalculationOptions = jpype.JClass( - 'com.aspose.cells.CalculationOptions') - opt = CalculationOptions() - # 对Sheet1中的公式进行计算 - sheet = book.getWorksheets().get('Sheet1') - sheet.calculateFormula(opt, True) - - # 设置区域 - pageSetup = sheet.getPageSetup() - # 去掉边距 - pageSetup.setBottomMargin(0.) - pageSetup.setLeftMargin(0.) - pageSetup.setRightMargin(0.) - pageSetup.setTopMargin(0.) - # 设置要截图的区域(对角线) - pageSetup.setPrintArea('A0:C2') - # Create a SheetRender object for the target sheet - sr = SheetRender(sheet, imgOptions) - for page in range(sr.getPageCount()): - # Generate an image for the worksheet - sr.toImage( - page, os.path.join('data', '%d.png' % (page + 1))) - - -def test(): - # emm这里不知道什么用绝对路径就报错 - libs = '{};{}'.format( - 'libs/bcprov-jdk16-146.jar', - 'libs/aspose-cells-19.2.jar' - ) - command = (jpype.getDefaultJVMPath(), - '-ea', '-Xmn128m', '-Xms512M', '-Xmx512M', - '-Djava.class.path={0}'.format(libs)) - print(command) - jpype.startJVM(jpype.getDefaultJVMPath(), - '-ea', '-Xmn128m', '-Xms512M', '-Xmx512M', - '-Djava.class.path={0}'.format(libs) - ) - # 解决多线程问题 - jpype.attachThreadToJVM() - # 对excel截图 - convertToImage() - # 关闭虚拟机 - jpype.shutdownJVM() - print('截图完成') - - -if __name__ == '__main__': - test() -``` - -## 附件 - -[调用java生成报表.7z](/files/调用java生成报表.7z) - -解压后进入whls文件夹安装对应版本的jpype包 - -## 效果图 - -![calljava](/images/calljava.png) \ No newline at end of file diff --git a/source/_posts/cgitb.md b/source/_posts/cgitb.md deleted file mode 100644 index 21da9df4..00000000 --- a/source/_posts/cgitb.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -author: Irony -title: 异常捕获之cgitb模块 -date: 2018-09-17 23:17:06 -tags: - - Python - - 异常 -categories: 笔记 ---- - -`cgitb`模块为`Python`脚本提供了一个特殊的异常管理器。名字有点误导人,它最初设计是为了以HTML格式展示cgi脚本的大量异常信息。后来,他扩展为也可以展示纯文本信息。该模块激活后,如果发生了未捕获的异常,将会展示格式化的输出报告。该报告包括源代码每一层的回溯,以及当前执行程序的参数和局部变量。以及,你可以选择将这些信息存到一个文件里,而不是发送到浏览器。 - - -## 用途 - -当编辑器中无法显示错误信息时,尤其是`PyQt`,可以尝试在cmd中运行代码,或者使用此模块来得到错误信息。 - -## 介绍 - -### cgitb.enable - -```python -cgitb.enable(display=1, logdir=None, context=5, format="html") -``` - -参数说明 - -1. display 1,发送至浏览器;0, 不发送 -2. logdir 如果有的话,写到该目录下 -3. context 显示错误代码周围的代码行数 -4. format 是否显示为HTML,除了'html'之外的所有值,都会显示为纯文本 - -### cgitb.handle - -```python -cgitb.handle(info=None) -``` - -参数说明 - -1. 如果你想用cgitb处理异常,你可以调用这个函数。 -2. info 应当是含有异常类型、异常值和traceback对象的三元组 -3. 如同sys.exc_info()返回的那样。如果不提供info,则从sys.exc_info中获取。 - -## 如何使用 - -以下代码放在最开始执行 - -```python -import cgitb -import sys -sys.excepthook = cgitb.Hook(1, None, 5, sys.stderr, 'text') -``` diff --git a/source/_posts/circleimage.md b/source/_posts/circleimage.md deleted file mode 100644 index 31e436e5..00000000 --- a/source/_posts/circleimage.md +++ /dev/null @@ -1,194 +0,0 @@ ---- -author: Irony -title: PyQt5圆形图片 -date: 2018-09-25 22:13:26 -tags: - - PyQt - - 圆形 - - 图片 -categories: 例子 ---- - -实现圆形图片的方法有很多,比如用遮罩(mask),裁切等等。这里比较几种实现方式,选出个人认为最优的方案。 - - -https://github.com/PyQt5/PyQt/blob/master/QLabel/CircleImage.py - -## 采用mask方式 - -具体参考 [【Qt】QLabel实现的圆形图像 - 米罗西 - 博客园](https://www.cnblogs.com/zhehan54/p/9515124.html) - -## 画圆形遮盖(适合纯色背景) - -原理是在原图片上画一个4角有颜色,中间圆形镂空的图片。 - -![circleimage1](/images/circleimage1.png) - -```python -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -''' -Created on 2017年8月25日 -@author: Irony."[讽刺] -@site: https://pyqt5.com, https://github.com/892768447 -@email: 892768447@qq.com -@description: -''' -from PyQt5.QtCore import Qt -from PyQt5.QtGui import QPixmap, QPainter, QPainterPath -from PyQt5.QtWidgets import QLabel, QWidget, QHBoxLayout - - -__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com" -__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]" -__Version__ = "Version 1.0" - - -class Label(QLabel): - - def __init__(self, *args, antialiasing=True, **kwargs): - super(Label, self).__init__(*args, **kwargs) - self.Antialiasing = antialiasing - self.setMaximumSize(200, 200) - self.setMinimumSize(200, 200) - self.radius = 100 - - #加载图片并缩放 - self.image = QPixmap("head.jpg").scaled( - 200, 200, Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation) - - painter = QPainter(self.image) - if self.Antialiasing: - painter.setRenderHint(QPainter.Antialiasing, True) - painter.setRenderHint(QPainter.HighQualityAntialiasing, True) - painter.setRenderHint(QPainter.SmoothPixmapTransform, True) - - path = QPainterPath() - path.addRoundedRect( - 0, 0, self.width(), self.height(), self.radius, self.radius) - path.addRect(0,0,self.width(),self.height()) - painter.setPen(Qt.NoPen) - painter.setBrush(Qt.green) - painter.drawPath(path) - self.setPixmap(self.image) - - -class Window(QWidget): - - def __init__(self, *args, **kwargs): - super(Window, self).__init__(*args, **kwargs) - layout = QHBoxLayout(self) - layout.addWidget(Label(self)) - layout.addWidget(Label(self, antialiasing=False)) - self.setStyleSheet("background: black;") - -if __name__ == "__main__": - import sys - from PyQt5.QtWidgets import QApplication - app = QApplication(sys.argv) - w = Window() - w.show() - sys.exit(app.exec_()) -``` - -## 使用QPainter的setCompositionMode - -具体参考 [Qt 圆形头像制作工具 抗锯齿 可缩放编辑](https://qtdream.com/topic/911/qt-%E5%9C%86%E5%BD%A2%E5%A4%B4%E5%83%8F%E5%88%B6%E4%BD%9C%E5%B7%A5%E5%85%B7-%E6%8A%97%E9%94%AF%E9%BD%BF-%E5%8F%AF%E7%BC%A9%E6%94%BE%E7%BC%96%E8%BE%91) - -```c++ -//result_avatar_size 是我们最后生成的图片的长宽,可以是QSize(200, 200)的正圆 -destination_image = QImage(result_avatar_size, QImage::Format_ARGB32_Premultiplied); -//在黑色的正方形中间画一个透明的圆,作为头像遮罩 -QPainter painter(&destination_image); -painter.setRenderHint(QPainter::Antialiasing); -//全涂黑 -painter.fillRect(destination_image.rect(), QBrush(Qt::black, Qt::SolidPattern)); -painter.setCompositionMode(QPainter::CompositionMode_SourceOut); -painter.setPen(Qt::NoPen); -painter.setBrush(QBrush(Qt::transparent, Qt::SolidPattern)); -//画透明区域 -painter.drawEllipse(destination_image.rect()); -``` - -## 使用QPainter的切割方法(推荐) - -利用`QPainter.setClipPath`方法切割一个圆形的`QPainterPath` - -![circleimage2](/images/circleimage2.png) - -```python -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -''' -Created on 2017年8月25日 -@author: Irony."[讽刺] -@site: https://pyqt5.com, https://github.com/892768447 -@email: 892768447@qq.com -@file: -@description: -''' -from PyQt5.QtCore import Qt -from PyQt5.QtGui import QPixmap, QPainter, QPainterPath, QPen -from PyQt5.QtWidgets import QLabel, QWidget, QHBoxLayout - - -__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com" -__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]" -__Version__ = "Version 1.0" - - -class Label(QLabel): - - def __init__(self, *args, antialiasing=True, **kwargs): - super(Label, self).__init__(*args, **kwargs) - self.Antialiasing = antialiasing - self.setMaximumSize(200, 200) - self.setMinimumSize(200, 200) - self.radius = 100 - - #####################核心实现######################### - self.target = QPixmap(self.size()) # 大小和控件一样 - self.target.fill(Qt.transparent) # 填充背景为透明 - - p = QPixmap("head.jpg").scaled( # 加载图片并缩放和控件一样大 - 200, 200, Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation) - - painter = QPainter(self.target) - if self.Antialiasing: - # 抗锯齿 - painter.setRenderHint(QPainter.Antialiasing, True) - painter.setRenderHint(QPainter.HighQualityAntialiasing, True) - painter.setRenderHint(QPainter.SmoothPixmapTransform, True) - -# painter.setPen(# 测试黑色圆圈 -# QPen(Qt.black, 5, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) - path = QPainterPath() - path.addRoundedRect( - 0, 0, self.width(), self.height(), self.radius, self.radius) - #**** 切割为圆形 ****# - painter.setClipPath(path) -# painter.drawPath(path) # 测试黑色圆圈 - - painter.drawPixmap(0, 0, p) - self.setPixmap(self.target) - #####################核心实现######################### - -class Window(QWidget): - - def __init__(self, *args, **kwargs): - super(Window, self).__init__(*args, **kwargs) - layout = QHBoxLayout(self) - layout.addWidget(Label(self)) - layout.addWidget(Label(self, antialiasing=False)) - self.setStyleSheet("background: black;") - -if __name__ == "__main__": - import sys - from PyQt5.QtWidgets import QApplication - app = QApplication(sys.argv) - w = Window() - w.show() - sys.exit(app.exec_()) -``` \ No newline at end of file diff --git a/source/_posts/daemonthread.md b/source/_posts/daemonthread.md deleted file mode 100644 index e5d689d7..00000000 --- a/source/_posts/daemonthread.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -author: 丑读书穷加班 -title: 多线程之守护线程和阻塞线程 -date: 2018-10-24 15:51:15 -tags: - - Python - - 线程 -categories: 笔记 ---- - -如果你设置一个线程为守护线程,就表示你在说这个线程是不重要的,在进程退出的时候,不用等待这个线程退出。如果你的主线程在退出的时候,不用等待那些子线程完成,那就设置这些线程的daemon属性。 - - -即在线程开始(thread.start())之前,调用setDeamon()函数,设定线程的daemon标志。 - -(thread.setDaemon(True))就表示这个线程“不重要”。 - -如果你想等待子线程完成再退出,那就什么都不用做,或者显示地调用thread.setDaemon(False),设置daemon的值为false。新的子线程会继承父线程的daemon标志。 - -整个Python会在所有的非守护线程退出后才会结束,即进程中没有非守护线程存在的时候才结束。 - -setDaemon()函数要放在start之前设置才行。 - -```python -import threading -import time - -def func(): - print("子线程开启:", time.localtime()) - time.sleep(2) - print("子线程结束:", time.localtime()) - - -print("主线程开启:", time.localtime()) -t = threading.Thread(target=func, args=()) -# t.setDaemon(True) -t.start() -print("主线程关闭:", time.localtime()) -``` - -在 Python 的多线程编程中,在实例代码中经常有 thread1.join()这样的代码。那么今天咱们用实际代码来解释一下 join 函数的作用。 - -join的原理就是依次检验线程池中的线程是否结束,没有结束就阻塞直到线程结束,如果结束则跳转执行下一个线程的join函数。 - -先看看这个: - -1. 阻塞主进程,专注于执行多线程中的程序。 -2. 多线程多join的情况下,依次执行各线程的join方法,前头一个结束了才能执行后面一个。 -3. 无参数,则等待到该线程结束,才开始执行下一个线程的join。 -4. 参数timeout为线程的阻塞时间,如 timeout=2 就是罩着这个线程2s 以后,就不管他了,继续执行下面的代码。 -5. 下面的例子是一次阻塞子线程,每个子线程都会等上个子线程join结束才会执行,如果注释掉t.join则会同时执行5个子线程,多线程在做网络访问的时候可以减少等待时间,那么在一个工作流程中可以将访问网络接口的情况做成多线程。 - -```python -import threading, time - -def func(): - print("hello world!") - time.sleep(1) - -print("hello main start") -for i in range(5): - t = threading.Thread(target=func, args=()) - print(t.getName()) - t.start() - t.join() -``` \ No newline at end of file diff --git a/source/_posts/datawidgetmapper_625781186.md b/source/_posts/datawidgetmapper_625781186.md deleted file mode 100644 index 1d976502..00000000 --- a/source/_posts/datawidgetmapper_625781186.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -author: 不许人间见白头 -title: QDataWidgetMapper 数据库绑定 QLineEdit控件 -date: 2018-10-29 16:17:59 -tags: - - PyQt - - Model -categories: 例子 ---- - -qt为操作数据库提供了一个model+view的模式 , 这样简单的出入库逻辑就不需要自己编写。 - -`QDataWidgetMapper` 可以 将数据库的数据 映射到其他控件 。 - -注意: 表格里的数据修改 还没有提交到数据库 , 需要点击提交按钮才生效。 - - -https://github.com/PyQt5/PyQt/tree/master/Test/partner_625781186/16_sqlModel/01_mapper - -## 代码 - -```python -#-*- coding: utf-8 -*- - -from PyQt5 import QtWidgets, QtGui, QtCore -from PyQt5.QtCore import * -from PyQt5.QtGui import * -from PyQt5.QtWidgets import * -from PyQt5.QtSql import * - -import sys - -sys.path.append('./ui') -from Ui_MainWindow import Ui_MainWindow - - -class MainWindow(QMainWindow, Ui_MainWindow): - def __init__(self, parent=None, *args): - - super(MainWindow, self).__init__(parent, *args) - self.setupUi(self) - self.resize(800,600) - - #=============================== db ======================================# - # self.db = QSqlDatabase.addDatabase('QMYSQL') - # self.db.setHostName("127.0.0.1") # set address - # self.db.setUserName("root") # set user name - # self.db.setPassword('123456') # set user pwd - # self.db.setDatabaseName("database") - - self.db = QSqlDatabase.addDatabase('QSQLITE') - self.db.setDatabaseName('./db/database.db') - - #================================= codemodel =====================================# - # 实例化model - self.codeModel = QSqlRelationalTableModel() - # model设置表 - self.initializeModel(self.codeModel, 'Mongo') - # 设置编辑策略 - # self.codeModel.setEditStrategy(QSqlTableModel.OnFieldChange) - # !!! 这里要注意 , 只能用这个策略 , 才可以实现自动提交 - self.codeModel.setEditStrategy(QSqlTableModel.OnManualSubmit) - - self.codeView = self.createView("code_View", self.codeModel) - self.verticalLayout.addWidget(self.codeView) - - #================================ initData ==================================# - # 数据映射 - self.mapper = QDataWidgetMapper() - # 提交策略 - self.mapper.setSubmitPolicy(QDataWidgetMapper.AutoSubmit) - # 映射的模型源 - self.mapper.setModel(self.codeModel) - self.mapper.addMapping(self.l1,0) - self.mapper.addMapping(self.l2,1) - self.mapper.addMapping(self.l3,2) - self.mapper.addMapping(self.l4,3) - self.mapper.addMapping(self.l5,4) - - self.mapper.toFirst() - - #================================ pushButton ==================================# - self.sub_btn.clicked.connect(self.mapper.submit) - self.sub_btn.clicked.connect(self.codeModel.submitAll) - self.pre_btn.clicked.connect(self.mapper.toPrevious) - self.next_btn.clicked.connect(self.mapper.toNext) - - def initializeModel(self, model, tablename): - '''重关联。''' - model.setTable(tablename) -# model.setEditStrategy(QSqlTableModel.OnRowChange) - model.select() - - def createView(self, title, model): - '''创建TableView视图''' - view = QTableView() - view.setModel(model) - view.setWindowTitle(title) - #列宽设置 - view.horizontalHeader().setSectionResizeMode(3) - #行高设置 - view.verticalHeader().setSectionResizeMode(1) - #充满列宽 - view.horizontalHeader().setStretchLastSection(True) -# view.verticalHeader().setVisible(False)#隐藏行标题 - #标题左对齐 - view.horizontalHeader().setDefaultAlignment(Qt.AlignLeft) - #标题左对齐 - view.verticalHeader().setDefaultAlignment(Qt.AlignLeft) - - return view - - -if __name__ == "__main__": - import sys - - app = QApplication(sys.argv) - app.setStyle(QStyleFactory.create("Fusion")) - ui = MainWindow() - ui.show() - sys.exit(app.exec_()) -``` - -## 效果图 - -![datawidgetmapper](/images/datawidgetmapper.gif) - diff --git a/source/_posts/equal_str_width_625781186.md b/source/_posts/equal_str_width_625781186.md deleted file mode 100644 index e8893fbe..00000000 --- a/source/_posts/equal_str_width_625781186.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -author: 人间白头  -title: python 判断屏幕等宽字符串的长度   -date: 2019-12-26 19:49:41 -tags: - - Python - -categories: 随笔 ---- - -判断屏幕等宽字符串的长度 ? - - -判断屏幕等宽字符串的长度 ? - -![image.png](https://upload-images.jianshu.io/upload_images/10769157-58b19652011e153a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) - - -【新手】重庆-搬砖-NoWait 22:41:50 @北京-BUG开发-黑择明 求指点 -【专家】北京-BUG开发-黑择明 22:43:04 fontMetrics -【专家】 [https://pyqt.site](https://pyqt.site) (892768447) 22:43:54 QFontMetrics -【专家】 [https://pyqt.site](https://pyqt.site) (892768447) 22:44:09 通过QLabel.font().fontMetrics()得到 - -【新手】重庆-搬砖-NoWait 22:52:00 -[https://stackoverflow.com/questions/35771863/how-to-calculate-length-of-string-in-pixels-for-specific-font-and-size](https://stackoverflow.com/questions/35771863/how-to-calculate-length-of-string-in-pixels-for-specific-font-and-size) -![image.png](https://upload-images.jianshu.io/upload_images/10769157-9dc2f83609106252.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) - - -【新手】重庆-搬砖-NoWait 22:53:15 感觉和fontMetrics应该是差不多的 - -![image.png](https://upload-images.jianshu.io/upload_images/10769157-411570eeadf51793.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) - ---- - -【专家】北京-BUG开发-黑择明 (996742224) 11:29:04 -fm = QFontMetrics(QFont()) -fm.width("qweqwe") diff --git a/source/_posts/ffmpeghls.md b/source/_posts/ffmpeghls.md deleted file mode 100644 index bd9737d0..00000000 --- a/source/_posts/ffmpeghls.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -author: Irony -title: FFmpeg合成加密HLS记录 -date: 2019-01-12 19:28:06 -tags: - - Python - - FFmpeg - - HLS -categories: 笔记 ---- - -记录在某个需求中要求截图并合成加密视频文件,这里采用FFmpeg的管道流来实现生成HLS加密文件。 - - -```python -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -""" -Created on 2019年3月4日 -@author: Irony -@site: https://pyqt5.com https://github.com/892768447 -@email: 892768447@qq.com -@file: -@description: -""" - -from pathlib import Path -from subprocess import Popen, PIPE - - -__Author__ = """By: Irony -QQ: 892768447 -Email: 892768447@qq.com""" -__Copyright__ = 'Copyright (c) 2019 Irony' -__Version__ = 1.0 - - -# p = Popen([r'D:\soft\ffmpeg\bin\ffmpeg.exe', '-y', -# '-threads', '2', -# '-f', 'image2pipe', -# '-vcodec', 'mjpeg', '-r', '24', '-i', '-', -# '-vcodec', 'h264', '-r', '24', -# # '-encryption_scheme', 'cenc-aes-ctr', -# # '-encryption_key', '617D8A125A284DF48E3C6B1866348A3F', -# # '-encryption_kid', 'B326F895B6A24CC5A4DC70995728059C', -# r'F:\Workspace\Test\videos\video.mp4'], stdin=PIPE) - -p = Popen([r'D:\soft\ffmpeg\bin\ffmpeg.exe', - '-re', # 按照实际帧率读取输入文件 - '-y', # 覆盖已存在文件 - '-threads', '2', # 线程数量 - '-f', 'image2pipe', # PIPE图片流 - '-vcodec', 'mjpeg', # 图片编码 - '-r', '24', # 帧率 - '-i', '-', # 指定输入流为PIPE - '-vcodec', 'h264', # 输出编码 - '-r', '24', # 帧率 - '-map', '0', -# '-crf','20', # 降低质量 - '-b', '720k', # 码率 - '-f', 'hls', - '-codec:v', 'libx264', - '-vbsf', 'h264_mp4toannexb', - # 指定加密密匙文件 - '-hls_key_info_file', r'F:\Workspace\Test\videokey.info', - '-hls_time', '20', - '-hls_list_size', '0', - '-hls_wrap', '0', -# '-hls_flags', 'single_file', # 生成单个文件(有bug) - r'F:\Workspace\Test\videos\playlist.m3u8'], stdin=PIPE) -print(p) - -t = 1 / 24 -for i, path in enumerate(Path('frames').rglob('*.jpg')): - # print(i, path) - p.stdin.write(open(str(path), 'rb').read()) - -p.stdin.close() -p.wait() -print('ok') -``` \ No newline at end of file diff --git a/source/_posts/flipwidgetanimation.md b/source/_posts/flipwidgetanimation.md deleted file mode 100644 index 5825bcaf..00000000 --- a/source/_posts/flipwidgetanimation.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -author: Irony -title: PyQt5窗口翻转动画 -date: 2019-05-15 22:48:00 -tags: - - PyQt - - 动画 - - 翻转 -categories: 例子 ---- - -QQ的界面一直是用来模仿练习做界面的好东西,这里就有一个类似QQ登录界面的实现翻转效果,当然这里并没有用两个窗口去做,而是用了`QStackedWidget`包含两个控件做切换,同时单独使用一个窗口做动画绘制。 - - -## 原理说明 - -1. 用了两个`QLabel`来显示模拟的图片界面,并实现鼠标点击模拟真实的窗口对应位置点击 -2. 用了`QStackedWidget`来存放上面的两个界面`QLabel` -3. 点击切换时主要是对上面的两个界面进行截图并传递给翻转动画窗口 -4. 通过`setWindowOpacity`控制主窗口的显示隐藏(保留任务栏),当然也可以用`hide` -5. 动画窗口`FlipWidget.py`主要实现两张图片的翻转显示,考虑到0-90和90-180之前的情况,以及图片的缩放动画 - -## 核心实现 - -1. 主要是在`paintEvent`方法中使用`QTransform`对`QPainter`进行圆心变换以及`rotate`设置翻转角度 -2. 同时根据翻转的角度范围对图片进行切换和缩放 - -```python -def paintEvent(self, event): - super(FlipWidget, self).paintEvent(event) - - if hasattr(self, 'image1') and hasattr(self, 'image2') and self.isVisible(): - - painter = QPainter(self) - painter.setRenderHint(QPainter.Antialiasing, True) - painter.setRenderHint(QPainter.SmoothPixmapTransform, True) - - # 变换 - transform = QTransform() - # 把圆心设置为矩形中心 - transform.translate(self.width() / 2, self.height() / 2) - - if self._angle >= -90 and self._angle <= 90: - # 当翻转角度在90范围内显示第一张图,且从大图缩放到小图的过程 - painter.save() - # 设置翻转角度 - transform.rotate(self._angle, Qt.YAxis) - painter.setTransform(transform) - # 缩放图片高度 - width = self.image1.width() / 2 - height = int(self.image1.height() * - (1 - abs(self._angle / self.Scale) / 100)) - image = self.image1.scaled( - self.image1.width(), height, - Qt.IgnoreAspectRatio, Qt.SmoothTransformation) - painter.drawPixmap( - QPointF(-width, -height / 2), image) - painter.restore() - else: - # 当翻转角度在90范围内显示第二张图,且从小图缩放到原图的过程 - painter.save() - if self._angle > 0: - angle = 180 + self._angle - else: - angle = self._angle - 180 - # 设置翻转角度, 注意这里角度有差异 - transform.rotate(angle, Qt.YAxis) - painter.setTransform(transform) - # 缩放图片高度 - width = self.image2.width() / 2 - height = int(self.image2.height() * - (1 - ((360 - abs(angle)) / self.Scale / 100))) - image = self.image2.scaled( - self.image2.width(), height, - Qt.IgnoreAspectRatio, Qt.SmoothTransformation) - painter.drawPixmap( - QPointF(-width, -height / 2), image) - painter.restore() -``` - -## 代码 - -https://github.com/PyQt5/PyQt/blob/master/QPropertyAnimation/FlipWidgetAnimation.py - - -## 效果图 - -![FlipWidgetAnimation](/PyQt/QPropertyAnimation/ScreenShot/FlipWidgetAnimation.gif) \ No newline at end of file diff --git a/source/_posts/followwindow.md b/source/_posts/followwindow.md deleted file mode 100644 index fb5dea98..00000000 --- a/source/_posts/followwindow.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -author: Irony -title: PyQt5窗口跟随其它窗口 -date: 2018-10-23 15:08:56 -tags: - - PyQt - - 窗口 -categories: 例子 ---- - -要实现`PyQt`窗口跟随其它外部的窗口,能想到两点办法,一个是hook系统事件得到目标窗口的位置和大小以及是否关闭等,二是通过循环检测窗口的位置来实现。 - - -## 基于Windows定时检测目标窗口 - -1. 利用`win32gui`模块获取目标窗口的句柄 -2. 通过句柄获取目标窗口的大小位置,并设置自己的位置 -3. 主要是检测时间,在10毫秒以下很流畅 -4. 窗口关闭是根据目标句柄无效来判断 - -https://github.com/PyQt5/PyQt/blob/master/Demo/FollowWindow.py - -## 代码 - -```python -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -""" -Created on 2018年10月22日 -@author: Irony -@site: https://github.com/892768447 -@email: 892768447@qq.com -@file: FollowWindow -@description: -""" -import os - -from PyQt5.QtCore import QTimer -from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton -import win32gui - - -__Author__ = """By: Irony -QQ: 892768447 -Email: 892768447@qq.com""" -__Copyright__ = "Copyright (c) 2018 Irony" -__Version__ = "Version 1.0" - - -class Window(QWidget): - - def __init__(self, *args, **kwargs): - super(Window, self).__init__(*args, **kwargs) - layout = QVBoxLayout(self) - layout.addWidget(QPushButton('test', self)) - self.tmpHwnd = None - # 启动定时器检测记事本的位置大小和是否关闭 - self.checkTimer = QTimer(self, timeout=self.checkWindow) - self.checkTimer.start(10) # 10毫秒比较流畅 - - def checkWindow(self): - # 查找 - hwnd = win32gui.FindWindow('Notepad', None) - if self.tmpHwnd and not hwnd: - # 表示记事本关闭了 - self.checkTimer.stop() - self.close() # 关闭自己 - return - if not hwnd: - return - self.tmpHwnd = hwnd - # 获取位置 - rect = win32gui.GetWindowRect(hwnd) - print(rect) - self.move(rect[2], rect[1]) - - -if __name__ == '__main__': - import sys - from PyQt5.QtWidgets import QApplication - # 先检测是否已有记事本打开 - hwnd = win32gui.FindWindow('Notepad', None) - print('hwnd', hwnd) - if not hwnd: - # 启动记事本 - os.startfile('notepad') - app = QApplication(sys.argv) - w = Window() - w.show() - sys.exit(app.exec_()) -``` - -## 效果图 - -![FollowWindow](/PyQt/Demo/ScreenShot/FollowWindow.gif) \ No newline at end of file diff --git a/source/_posts/issignalconnected.md b/source/_posts/issignalconnected.md deleted file mode 100644 index c99fd484..00000000 --- a/source/_posts/issignalconnected.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -author: Irony -title: PyQt5判断信号是否连接 -date: 2019-04-26 22:06:26 -tags: - - PyQt - - 信号 -categories: 教程 ---- - -在`PyQt`中某些情况下需要取消原来的信号连接,此时需要使用`disconnect`方法,但是在逻辑不严谨的情况下可能会导致多次调用`disconnect`方法而导致报错,当然可以通过try except来包裹代码。这里通过 `isSignalConnected` 来判断信号是否连接。 - - -在QOjbect文档中这样写到: - -```c++ -static const QMetaMethod valueChangedSignal = QMetaMethod::fromSignal(&MyObject::valueChanged); -if (isSignalConnected(valueChangedSignal)) { - QByteArray data; - data = get_the_value(); // expensive operation - emit valueChanged(data); -} -``` - -通过直接传入信号就行了,但是这在PyQt中不可行。需要这么做 - -```python -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -""" -Created on 2019年2月24日 -@author: Irony -@site: https://pyqt5.com https://github.com/892768447 -@email: 892768447@qq.com -@file: IsSignalConnected -@description: 判断信号是否连接 -""" - -from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton, QTextBrowser - - -__Author__ = """By: Irony -QQ: 892768447 -Email: 892768447@qq.com""" -__Copyright__ = 'Copyright (c) 2019 Irony' -__Version__ = 1.0 - - -class Window(QWidget): - -    def __init__(self, *args, **kwargs): -        super(Window, self).__init__(*args, **kwargs) -        layout = QVBoxLayout(self) -        self.button1 = QPushButton('已连接', self, clicked=self.doTest) -        self.button2 = QPushButton('未连接', self) -        self.retView = QTextBrowser(self) -        layout.addWidget(self.button1) -        layout.addWidget(self.button2) -        layout.addWidget(self.retView) - -    def doTest(self): -        self.retView.append(""" -        # button1 clicked 是否连接: %s -        # button2 clicked 是否连接: %s -        """ % ( -            self.isSignalConnected(self.button1, 'clicked()'), -            self.isSignalConnected(self.button2, 'clicked()') -        )) - -    def isSignalConnected(self, obj, name): -        """判断信号是否连接 -        :param obj:        对象 -        :param name:       信号名,如 clicked() -        """ -        index = obj.metaObject().indexOfMethod(name) -        if index > -1: -            method = obj.metaObject().method(index) -            if method: -                return obj.isSignalConnected(method) -        return False - - -if __name__ == '__main__': -    import sys -    from PyQt5.QtWidgets import QApplication -    app = QApplication(sys.argv) -    w = Window() -    w.show() -    sys.exit(app.exec_()) -``` - -## 效果图 - -![IsSignalConnected](/PyQt/Demo/ScreenShot/IsSignalConnected.png) \ No newline at end of file diff --git a/source/_posts/jumpslider.md b/source/_posts/jumpslider.md deleted file mode 100644 index ff9b10ca..00000000 --- a/source/_posts/jumpslider.md +++ /dev/null @@ -1,119 +0,0 @@ ---- -author: Irony -title: PyQt5之QSlider滑动条点击定位 -date: 2018-11-05 23:12:26 -tags: - - PyQt - - 滑动条 -categories: 例子 ---- - -`QSlider` 在通常情况下支持鼠标点击可以任意拖动,或者鼠标点击则往鼠标点击的方向移动一小格,这种移动一小格通常情况下用起来很不方便,比如我要做一个播放器的播放进度条,肯定是点击某个位置就直接跳到该位置,为此需要对 `QSlider` 的鼠标事件`mousePressEvent`进行重写。 - - -## 实现方法 - -一般的想法就是重写`mousePressEvent`后,得到鼠标点击的x和y点然后进行比例换算,再通过`setValue`来设置值,其实`QSlider`的`style`里面是有一个`sliderValueFromPosition`方法来计算值的。直接调用这个方法即可。 - -1. 首先通过`QSlider.style().subControlRect`方法计算得到滑块的区域,当鼠标点击区域在此次时则交给系统自己处理(比如按住不放拖动) -2. 通过`orientation`判断滑动条的方向(横竖) -3. 通过`invertedAppearance`判断滑动条是否反向(左右、上下) -4. 通过`QSlider.style().sliderValueFromPosition(最小值, 最大值, x或者y坐标, 宽度或者高度)`来计算得到值 -5. 最后通过`setValue`来设置值 - -## 代码 - -https://github.com/PyQt5/PyQt/blob/master/QSlider/ClickJumpSlider.py - -```python -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -""" -Created on 2018年11月5日 -@author: Irony -@site: https://pyqt5.com https://github.com/892768447 -@email: 892768447@qq.com -@file: JumpSlider -@description: -""" -from PyQt5.QtCore import Qt -from PyQt5.QtWidgets import QSlider, QStyleOptionSlider, QStyle, QWidget,\ - QFormLayout, QLabel - - -__Author__ = """By: Irony -QQ: 892768447 -Email: 892768447@qq.com""" -__Copyright__ = "Copyright (c) 2018 Irony" -__Version__ = "Version 1.0" - - -class JumpSlider(QSlider): - - def mousePressEvent(self, event): - # 获取上面的拉动块位置 - option = QStyleOptionSlider() - self.initStyleOption(option) - rect = self.style().subControlRect( - QStyle.CC_Slider, option, QStyle.SC_SliderHandle, self) - if rect.contains(event.pos()): - # 如果鼠标点击的位置在滑块上则交给Qt自行处理 - super(JumpSlider, self).mousePressEvent(event) - return - if self.orientation() == Qt.Horizontal: - # 横向,要考虑invertedAppearance是否反向显示的问题 - self.setValue(self.style().sliderValueFromPosition( - self.minimum(), self.maximum(), - event.x() if not self.invertedAppearance() else (self.width( - ) - event.x()), self.width())) - else: - # 纵向 - self.setValue(self.style().sliderValueFromPosition( - self.minimum(), self.maximum(), - (self.height() - event.y()) if not self.invertedAppearance( - ) else event.y(), self.height())) - - -class TestWindow(QWidget): - - def __init__(self, *args, **kwargs): - super(TestWindow, self).__init__(*args, **kwargs) - layout = QFormLayout(self) - - self.label1 = QLabel('0', self) - layout.addRow(self.label1, JumpSlider( - Qt.Horizontal, valueChanged=lambda v: self.label1.setText(str(v)))) - - # 横向-反向显示 - self.label2 = QLabel('0', self) - layout.addRow(self.label2, JumpSlider( - Qt.Horizontal, invertedAppearance=True, - valueChanged=lambda v: self.label2.setText(str(v)))) - - self.label3 = QLabel('0', self) - layout.addRow(self.label3, JumpSlider( - Qt.Vertical, minimumHeight=200, valueChanged=lambda v: self.label3.setText(str(v)))) - - # 纵向反向显示 - self.label4 = QLabel('0', self) - layout.addRow(self.label4, JumpSlider( - Qt.Vertical, invertedAppearance=True, - minimumHeight=200, valueChanged=lambda v: self.label4.setText(str(v)))) - - -if __name__ == '__main__': - import sys - import cgitb - sys.excepthook = cgitb.enable(1, None, 5, '') - from PyQt5.QtWidgets import QApplication - app = QApplication(sys.argv) - w = TestWindow() - w.show() - sys.exit(app.exec_()) -``` - -## 效果图 - -![ClickJumpSlider](/PyQt/QSlider/ScreenShot/ClickJumpSlider.gif) - diff --git a/source/_posts/likehtmleffect.md b/source/_posts/likehtmleffect.md deleted file mode 100644 index 02800ced..00000000 --- a/source/_posts/likehtmleffect.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -author: Irony -title: PyQt5仿网页图片鼠标移动特效 -date: 2018-10-23 17:57:03 -tags: - - PyQt - - 特效 -categories: 例子 ---- - -em,就是类似于那种游戏官网首页的图片,鼠标放上去后来回移动,图片的前景和背景错位移动。 - - -## 原理分析 - -1. 2张一样大小的透明图片,1张作为背景,一张作为前景(比如说人物)。 -2. 当鼠标往左移动时,前景人物跟着往左移动,背景往右移动 -3. 计算好偏移量(见代码中) - -https://github.com/PyQt5/PyQt/blob/master/QLabel/ImageSlipped.py - -## 关键代码 - -```python -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -""" -Created on 2018年10月18日 -@author: Irony -@site: https://pyqt5.com https://github.com/892768447 -@email: 892768447@qq.com -@file: ImageSlipped -@description: -""" -from PyQt5.QtGui import QPixmap, QPainter -from PyQt5.QtWidgets import QWidget - - -__Author__ = """By: Irony -QQ: 892768447 -Email: 892768447@qq.com""" -__Copyright__ = "Copyright (c) 2018 Irony" -__Version__ = "Version 1.0" - - -class SlippedImgWidget(QWidget): - - def __init__(self, bg, fg, *args, **kwargs): - super(SlippedImgWidget, self).__init__(*args, **kwargs) - # 开启鼠标跟踪 - self.setMouseTracking(True) - # 背景 - self.bgPixmap = QPixmap(bg) - # 前景 - self.pePixmap = QPixmap(fg) - # 最小尺寸(背景右边和下方隐藏10个像素) - size = self.bgPixmap.size() - self.setMinimumSize(size.width() - 10, size.height() - 10) - self.setMaximumSize(size.width() - 10, size.height() - 10) - # 分成10份用于鼠标移动判断 - self.stepX = size.width() / 10 - self.stepY = size.height() / 10 - # 偏移量 - self._offsets = [-4, -4, -4, -4] # 背景(-4,-4),前景(-4,-4) - - def mouseMoveEvent(self, event): - super(SlippedImgWidget, self).mouseMoveEvent(event) - pos = event.pos() - - # 偏移量 - offsetX = 5 - int(pos.x() / self.stepX) - offsetY = 5 - int(pos.y() / self.stepY) - self._offsets[0] = offsetX - self._offsets[1] = offsetY - self._offsets[2] = offsetX - self._offsets[3] = offsetY - # 刷新 - self.update() - - def paintEvent(self, event): - super(SlippedImgWidget, self).paintEvent(event) - # 绘制图形 - painter = QPainter(self) - painter.setRenderHint(QPainter.Antialiasing) - # 左上角偏移5个像素画背景图片 - painter.drawPixmap( - -5 + self._offsets[0], - -5 + self._offsets[1], self.bgPixmap) - # 右下角偏移5个像素画前景图片 - painter.drawPixmap( - self.width() - self.pePixmap.width() + 5 - self._offsets[2], - self.height() - self.pePixmap.height() + 5 - self._offsets[3], - self.pePixmap - ) - - -if __name__ == '__main__': - import sys - from PyQt5.QtWidgets import QApplication - app = QApplication(sys.argv) - w = SlippedImgWidget('images/bg.png', 'images/fg.png') - w.show() - sys.exit(app.exec_()) -``` - -## 效果图 - -![ImageSlipped](/PyQt/QLabel/ScreenShot/ImageSlipped.gif) \ No newline at end of file diff --git a/source/_posts/macm1pyqt.md b/source/_posts/macm1pyqt.md deleted file mode 100644 index f8e6a13e..00000000 --- a/source/_posts/macm1pyqt.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -author: Irony -title: 如何在Mac M1上快速安装PyQt5 -date: 2023-10-07 14:08:06 -tags: - - PyQt - - Mac - - M1 -categories: 笔记 ---- - -由于官方并没有在M1上编译PyQt导致安装存在一些问题。 -M1上的Python不能直接使用x64的 PyQt5。但是M1上可以运行x64的Python。所以通过安装x64的Python然后再安装PyQt5即可。 - - -**1. 安装Python** -[python-3.9.13-macosx10.9.pkg](https://www.python.org/ftp/python/3.9.13/python-3.9.13-macosx10.9.pkg) - -**2. 勾选自定义同时只勾选安装pip** - -![step1.png](/images/macpyqtstep1.png) - -![step1.png](/images/macpyqtstep2.png) - -**3. 设置pip源** -```shell -/Library/Frameworks/Python.framework/Versions/3.9/bin/pip3 install pqi -/Library/Frameworks/Python.framework/Versions/3.9/bin/pqi use tuna -``` - -**4. 安装PyQt5** -```shell -/Library/Frameworks/Python.framework/Versions/3.9/bin/pip3 install PyQt5 -``` - -**5. 测试** -```shell -/Library/Frameworks/Python.framework/Versions/3.9/bin/python3 -``` - -![step3.png](/images/macpyqtstep3.png) - - - -📢📢📢 - -也可以直接安装 [Miniconda](https://docs.anaconda.com/free/miniconda/miniconda-install/) - -然后:conda install -c conda-forge pyqt diff --git a/source/_posts/mselectmenu.md b/source/_posts/mselectmenu.md deleted file mode 100644 index c4a0036d..00000000 --- a/source/_posts/mselectmenu.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -author: Irony -title: PyQt5菜单之多选功能 -date: 2018-10-25 09:53:34 -tags: - - PyQt - - 菜单 -categories: 例子 ---- - -有时候会遇到这种需求:在界面某个位置弹出一个菜单,其中里面的菜单项可以多选(类似配置选项),此时用`QMenu`会遇到点击一个菜单项就会自动关闭,当然可以通过其他方式实现该功能,不过这里就采用`QMenu`通过特殊的方式来实现该需求。 - - -## 需求 - -要实现的效果: - -1. 菜单1 -2. 菜单2 -3. 菜单3 -4. 菜单4 - -点击菜单1、2、3可以多选不关闭菜单 - -点击菜单4可以勾选,并且关闭菜单 - -## 原理 - -1. 设置菜单项可勾选:通过`QAction.setCheckable(True)`方法实现 -2. 设置菜单不可关闭:通过覆盖QMenu的鼠标释放`mouseReleaseEvent`方法(可直接替换或者通过`installEventFilter`安装事件过滤器实现) -3. 在菜单的鼠标释放事件中,当点击菜单项后是通过点击点坐标来查找是否有`QAction`,然后触发对应的`QAction`。 -4. 故在没有`QAction`的地方则直接交还给`QMenu`自行处理逻辑,在有`QAction`的地方可以根据自己的需求进行处理(如上所提) - -## 代码 - -```python -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -""" -Created on 2018年10月24日 -@author: Irony -@site: https://github.com/892768447 -@email: 892768447@qq.com -@file: 菜单多选不关闭 -@description: -""" -from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QPushButton, QMenu,\ - QAction - - -__Author__ = """By: Irony -QQ: 892768447 -Email: 892768447@qq.com""" -__Copyright__ = "Copyright (c) 2018 Irony" -__Version__ = "Version 1.0" - - -class Window(QWidget): - - def __init__(self, *args, **kwargs): - super(Window, self).__init__(*args, **kwargs) - layout = QVBoxLayout(self) - self.labelInfo = QLabel(self) - self.button = QPushButton('带按钮的菜单', self) - layout.addWidget(self.labelInfo) - layout.addWidget(self.button) - - # 添加菜单 - self._initMenu() - - def _initMenu(self): - # 创建菜单 - self._menu = QMenu(self.button) - # 替换menu的鼠标释放事件达到选择性不关闭菜单 - self._menu.mouseReleaseEvent = self._menu_mouseReleaseEvent - self._menu.addAction('菜单1', self._checkAction) - self._menu.addAction('菜单2', self._checkAction) - self._menu.addAction( - QAction('菜单3', self._menu, triggered=self._checkAction)) - action = QAction('菜单4', self._menu, triggered=self._checkAction) - # 添加自定义的属性,判断该属性可以关闭菜单 - action.setProperty('canHide', True) - self._menu.addAction(action) - for action in self._menu.actions(): - # 循环设置可勾选 - action.setCheckable(True) - self.button.setMenu(self._menu) - - def _menu_mouseReleaseEvent(self, event): - action = self._menu.actionAt(event.pos()) - if not action: - # 没有找到action就交给QMenu自己处理 - return QMenu.mouseReleaseEvent(self._menu, event) - if action.property('canHide'): # 如果有该属性则给菜单自己处理 - return QMenu.mouseReleaseEvent(self._menu, event) - # 找到了QAction则只触发Action - action.activate(action.Trigger) - - def _checkAction(self): - # 三个action都响应该函数 - self.labelInfo.setText('\n'.join(['{}\t选中:{}'.format( - action.text(), action.isChecked()) for action in self._menu.actions()])) - - -if __name__ == '__main__': - import sys - import cgitb - sys.excepthook = cgitb.enable(1, None, 5, 'text') - from PyQt5.QtWidgets import QApplication - app = QApplication(sys.argv) - w = Window() - w.resize(400, 400) - w.show() - sys.exit(app.exec_()) -``` - -## 效果图 - -![MultiSelect](/PyQt/QMenu/ScreenShot/MultiSelect.gif) \ No newline at end of file diff --git a/source/_posts/pageswitching.md b/source/_posts/pageswitching.md deleted file mode 100644 index 99fa4136..00000000 --- a/source/_posts/pageswitching.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -author: Irony -title: PyQt5之图片轮播 -date: 2018-11-24 21:45:06 -tags: - - PyQt - - 轮播 - - 动画 -categories: 例子 ---- - -之前看到了`QStackedWidget`做切换动画,让界面不那么生硬,于是参考了 http://qt.shoutwiki.com/wiki/Extending_QStackedWidget_for_sliding_page_animations_in_Qt 做了一个`QStackedWidget`的切换动画,然后利用`QStackedWidget`结合多个`QLabel`显示图片来做一个轮播效果。 - -其实在写之前也在网上找了很多例子,参看过后发现大多例子都是利用到了`paintEvent`去绘制,这样其实还是比较麻烦,个人觉得更好的方式是使用`QPropertyAnimation`属性动画修改控件中`QLabel`图片控件的pos位置属性就可以达到移动效果了。 - - -1. 比较核心的算法就是要计算当前页面和下一个页面的位置偏移量,比如: - -```python -# 计算偏移量 -offsetX = self.frameRect().width() -offsetY = self.frameRect().height() -w_next.setGeometry(0, 0, offsetX, offsetY) - -if direction == self.BOTTOM2TOP: - offsetX = 0 - offsetY = -offsetY -elif direction == self.TOP2BOTTOM: - offsetX = 0 -elif direction == self.RIGHT2LEFT: - offsetX = -offsetX - offsetY = 0 -elif direction == self.LEFT2RIGHT: - offsetY = 0 - -# 重新定位显示区域外部/旁边的下一个窗口小部件 -pnext = w_next.pos() -pnow = w_now.pos() -self._pnow = pnow - -# 移动到指定位置并显示 -w_next.move(pnext.x() - offsetX, pnext.y() - offsetY) -w_next.show() -w_next.raise_() -``` - -2. 其次是对这两个页面增加关联`pos`属性的`QPropertyAnimation`动画,然后加入到并行动画组`QParallelAnimationGroup`中再启动即可。 - -3. 对`QStackedWidget`的`setCurrentIndex`和`setCurrentWidget`这两个函数进行了覆盖重写达到及时手动调用这两个函数也会产生动画效果的目的。 - -## 代码 - -https://github.com/PyQt5/PyQt/blob/master/QPropertyAnimation/PageSwitching.py - -## 效果图 - -![PageSwitching](/PyQt/QPropertyAnimation/ScreenShot/PageSwitching.gif) \ No newline at end of file diff --git a/source/_posts/processinclass_625781186.md b/source/_posts/processinclass_625781186.md deleted file mode 100644 index 51ea2dbd..00000000 --- a/source/_posts/processinclass_625781186.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -author: 不许人间见白头 -title: python 在类里使用进程池 -date: 2018-11-16 21:37:31 -tags: - - 进程 -categories: 笔记 ---- - -1. 首先, 进程池的作用就是减少进程的创建和释放 开销的, 所以在类中作为局部变量是不合适的; -2. 其次, 进程池必须在`if __name__ == "__main__" `里 ,否则会报 frozen_ 什么什么的错误;(这一点可能解释有误); - - -3. 然后, 线程池的`apply_async`中如果传入`self.xxx`方法,会报`multiprocessing.Pool pickling error`什么的错误, 具体解释见https://blog.csdn.net/dutsoft/article/details/70336462, 里面有解决方法,但是我没有成功(最开始测试没有现在理解的透彻, 不过应该是可以的); 由于第1点 不合理, 所以有什么办法在类 函数中获取 进程池对象po的地址: - -![processinclass1](/images/processinclass1.png) - -我的解决思路和方法是: -1. 通过globals() 取得全局变量 , 测试证明 :不同文件的`globals()`是不同的: 如`Tab2.py `的 `globals()` 和` main_extra_func_file.py`中的 `globals() `是不同的 , 所以 这样在`Tab2.py`中取不到po对象; -2. 通过`__main__.po` 来获取 (为什么会想到这个呢, 因为有时候导包 import .xxx 和import xxx 会报 `__main__` 没有什么属性什么的): - -```python -def getPoolObject(): -# po 的名字在main函数中定义 -# __main__ 模块在sys.modules 的键是"__mp_main__" - return sys.modules["__mp_main__"].po -``` - -ps : (图没截好 , `rglob_worker` 是外部函数 , 非类内函数 ,po = getPoolBojcet() 这一行是类内函数 ,红色箭头 2. 在的那条白色分割线 是2个函数。 ) - -![processinclass2](/images/processinclass2.png) - -`len(po._cache) == 1` : po._cache 是当前有任务的进程数, ==1表示所有任务结束; 利用回调 , 可以更轻松地进行进程通信。 diff --git a/source/_posts/pyqt5_hook_key_625781186.md b/source/_posts/pyqt5_hook_key_625781186.md deleted file mode 100644 index 48747315..00000000 --- a/source/_posts/pyqt5_hook_key_625781186.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -author: 人间白头  -title: 在pyqt中使用python全局钩子模块 -date: 2019-07-07 01:37:22 -tags: - - Python - - pyqt hook key -categories: 随笔 ---- - -在某些时候需要为自己的软件增加全局键盘监听,比如软件最小化隐藏后可以通过热键唤醒,又或者比如像QQ一样可以全局热键截图。这里介绍几个方法实现在PyQt中使用Python全局钩子模块实现全局热键功能。 - - - - -1. `pyHook3` - -安装命令 : `pip install pyhook3` - -[https://blog.csdn.net/q871063970/article/details/86648386](https://blog.csdn.net/q871063970/article/details/86648386) - -似乎将pyhook支持py3版本的了? 没有太多研究. - -缺点: 只支持win平台. - -2.`keyboard` & `mouse` - -安装命令: `pip install keyboard mouse` -``` - -from PyQt5 import QtGui, QtWidgets, QtCore -from PyQt5.QtCore import * -from PyQt5.QtGui import * -from PyQt5.QtWidgets import * -import keyboard -class Window(QWidget): - - def __init__(self, *args, **kwargs): - super(Window, self).__init__(*args, **kwargs) - layout = QVBoxLayout(self) - self.testBtn = QPushButton(self) - layout.addWidget(self.testBtn) - - keyboard.add_hotkey('ctrl+shift+x', lambda:print('triggered', 'hotkey')) - keyboard.add_hotkey('ctrl+shift+c', self.abc,args=('aa',"bb","cc")) - - def abc(self,a,b,c): - print(a,b,c) - -if __name__ == '__main__': - import sys - from PyQt5.QtWidgets import QApplication - app = QApplication(sys.argv) - w = Window() - w.show() - sys.exit(app.exec_()) -``` - -更详细例子 : [pyqt中使用keyboard全局热键](https://github.com/PyQt5/PyQt/blob/63c6376358acb1863313fb5593097e6e0210cad6/Test/%E5%85%A8%E5%B1%80%E7%83%AD%E9%94%AE/HotKey.py) - -优点: 跨平台 ; - -缺点: 模块名字取得太差, 不容易被发现. diff --git a/source/_posts/pyqt5asyncio.md b/source/_posts/pyqt5asyncio.md deleted file mode 100644 index fab3b80b..00000000 --- a/source/_posts/pyqt5asyncio.md +++ /dev/null @@ -1,195 +0,0 @@ ---- -author: Irony -title: PyQt5结合Asyncio异步 -date: 2018-10-24 14:32:26 -tags: - - PyQt - - Asyncio - - 异步 -categories: 例子 ---- - -今天尝试了下[quamash](https://github.com/harvimt/quamash)框架,该框架是一个`PyQt`的异步事件循环封装库,使用Python3+ 的`asyncio`这个异步库。在看了该项目的内容后发现只有一个简单的进度条例子,故尝试用其来下载网络图片并显示。 - - -## 安装依赖 - -1. pip install quamash -2. pip install aiohttp -3. Python3.5+ 和 PyQt5 - -这里使用`aiohttp`是因为它基于`asyncio`封装的网络操作库,常见的`get`、`post`等方法,不过它只支持Python3.5及以上的版本,主要是它使用了async def 这样的语法。 - -## 说明 - -1. 在创建`QApplication`后随即设置替换事件循环`loop` -```python -app = QApplication(sys.argv) -loop = QEventLoop(app) -asyncio.set_event_loop(loop) -w = Window() -``` -2. 通过`asyncio.ensure_future(func(), loop=loop)`来执行某个异步函数 - -## 流程 - -| | | | -|:----------|:--:|----------------------------:| -| Window | → | initSession(初始化session) | -| ↓ | | | -| 下载按钮 | → | doDownload(执行_doDownload方法) | -| ↓ | | | -| session.get(下载json数据进行解析) | | | -| ↓ | | | -| 添加到界面 | ← | _doDownloadImage(对单张图片进行下载) | - -## 源码 - -```python -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -""" -Created on 2018年10月24日 -@author: Irony -@site: https://github.com/892768447 -@email: 892768447@qq.com -@file: AsyncioUiClient -@description: -""" -import asyncio - -from PyQt5.QtCore import Qt -from PyQt5.QtGui import QPixmap, QMovie -from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton,\ - QApplication, QListWidget, QListWidgetItem, QLabel, QMessageBox -import aiohttp -from quamash import QEventLoop - - -__Author__ = """By: Irony -QQ: 892768447 -Email: 892768447@qq.com""" -__Copyright__ = "Copyright (c) 2018 Irony" -__Version__ = "Version 1.0" - -Url = 'https://www.doutula.com/api/search?keyword=%E6%9C%80%E6%96%B0%E8%A1%A8%E6%83%85&mime=0&page={}' -Headers = { - ':authority': 'www.doutula.com', - ':method': 'GET', - ':scheme': 'https', - 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', - 'accept-language': 'zh-CN,zh;q=0.9', - 'cache-control': 'max-age=0', - 'dnt': '1', - 'upgrade-insecure-requests': '1', - 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.6756.400 QQBrowser/10.2.2498.400' -} - - -class Window(QWidget): - - def __init__(self, *args, **kwargs): - super(Window, self).__init__(*args, **kwargs) - layout = QVBoxLayout(self) - self.listWidget = QListWidget(self) - self.listWidget.setSpacing(2) # item直接的间隔 - # 隐藏横向滚动条 - self.listWidget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) - # 让list 从左到右排列 - self.listWidget.setFlow(self.listWidget.LeftToRight) - # 自动换行 - self.listWidget.setWrapping(True) - self.listWidget.setResizeMode(self.listWidget.Adjust) - - self.buttonMsg = QPushButton('弹出提示框', self, clicked=self.showMessage) - self.buttonDown = QPushButton('下载图片', self, clicked=self.doDownload) - layout.addWidget(self.listWidget) - layout.addWidget(self.buttonMsg) - layout.addWidget(self.buttonDown) - self.currentPage = 0 - self.initSession() # 其实没必要,session主要用在需要登录的网站。缓存cookie用 - - def initSession(self): - async def _initSession(): - # 初始化session - self.session = aiohttp.ClientSession(loop=loop) - print(self.session) - asyncio.ensure_future(_initSession(), loop=loop) - - async def _doDownloadImage(self, url): - # 下载图片并添加到界面 - async with self.session.get(url) as resp: - data = await resp.read() - if not data: - print('下载失败: ', url) - return - path = os.path.join('tmp', os.path.basename(url)) - with open(path, 'wb') as fp: - fp.write(data) - item = QListWidgetItem(url, self.listWidget) - image = QPixmap(path) - item.setSizeHint(image.size()) - label = QLabel(self.listWidget) - label.setPixmap(image) - if path.endswith('.gif'): # 可能是动态图 - label.setMovie(QMovie(path)) - self.listWidget.setItemWidget(item, label) - self.listWidget.scrollToBottom() - - async def _doDownload(self): - # 下载工作 - if self.currentPage == -1: - QMessageBox.information(self, '提示', '已经没有更多了') - return - self.currentPage += 1 - url = Url.format(self.currentPage) - print('get url: ', url) - async with self.session.get(url, headers=Headers) as resp: - data = await resp.json() - if not data: - return - data = data.get('data', None) - if not data: - self.currentPage = -1 - print('已经是最后一页了') - return - # 解析json并生成item添加到界面中 - for entity in data.get('list', []): - url = entity.get('image_url', None) - if not url: - continue - await self._doDownloadImage(url) # 下载图片 - - def doDownload(self): - # 响应按钮点击调用 - asyncio.ensure_future(self._doDownload(), loop=loop) - - def showMessage(self): - # 显示对话框 - app.aboutQt() - - def closeEvent(self, event): - if not self.session.closed: - asyncio.ensure_future(self.session.close(), loop=loop) - super(Window, self).closeEvent(event) - - -if __name__ == '__main__': - import sys - import cgitb - import os - os.makedirs('tmp', exist_ok=True) - sys.excepthook = cgitb.enable(1, None, 5, 'text') - app = QApplication(sys.argv) - loop = QEventLoop(app) - asyncio.set_event_loop(loop) - w = Window() - w.show() - with loop: - loop.run_forever() -``` - -## 效果图 - -![pyqt5asyncio](/images/pyqt5asyncio.gif) \ No newline at end of file diff --git a/source/_posts/pyqt_get_subprocess_pipeline_625781186.md b/source/_posts/pyqt_get_subprocess_pipeline_625781186.md deleted file mode 100644 index 1c10fc05..00000000 --- a/source/_posts/pyqt_get_subprocess_pipeline_625781186.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -author: 人间白头  -title: python 获取子进程print信息   -date: 2019-05-24 14:39:44 -tags: - - Python - - subprocess.Popen - - 拦截print -categories: 随笔 ---- - -在PyQt中使用子线程读取子进程Python脚本的print输出流内容。 - - - -问题所在: - -![image.png](https://i.loli.net/2019/05/24/5ce793171984f27031.png) - -如果模块都由自己开发, 正常操作 - -![image.png](https://i.loli.net/2019/05/24/5ce7933994a0090037.png) - -但是因为不能改, 所以只能拦截: -代码: -```python -pythonPath = self.pythonPath_cb.currentText() - -if suffix == "py": - # 首次 - self.pyCommand = [pythonPath, path] - self.modifiedReloadPython(path) -def modifiedReloadPython(self, path_): - os.chdir(os.path.dirname(path_)) - # 子进程调用 - self.p = subprocess.Popen(self.pyCommand, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - # self.stdoutWorker.p = self.p - self.stdoutWorker = Worker(self.p) - self.stdoutWorker.stdout_signal.connect(lambda x: self.error_te.append("PYDEBUG:\n" + x)) - self.stdoutWorker.start() -class Worker(QThread): - stdout_signal = pyqtSignal(str) - - def __init__(self, p, parent=None): - super().__init__(parent) - self.p = p - - def run(self): - while True: - QApplication.processEvents() - if self.p is not None: - line = self.p.stdout.readline() - # line = line.strip() - if line != b'': - try: - info = line.decode() - self.stdout_signal.emit(info) - except: - self.stdout_signal.emit(repr(line)) - -``` diff --git a/source/_posts/pyqtclient.md b/source/_posts/pyqtclient.md deleted file mode 100644 index 00a056f2..00000000 --- a/source/_posts/pyqtclient.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -author: Irony -title: PyQtClient例子客户端 -date: 2019-02-02 15:15:06 -sticky: 999 -tags: - - PyQt -categories: 随笔 ---- - -![1.gif](/images/1.gif)对本博客所写的项目PyQt例子进行一个客户端的编写,客户端主要实现一些动画效果,更换皮肤,运行例子等功能。![2.gif](/images/2.gif) - - -## 项目地址 - -
- -## Windows客户端下载 - -1. [包含部分例子](https://github.com/PyQt5/PyQtClient/releases/download/1.0.1/PyQtClient-x86-win32-exe.7z) -2. [不包含例子](https://github.com/PyQt5/PyQtClient/releases/download/1.0.1/PyQtClient-x86-win32-exe.7z) -3. [百度网盘](https://pan.baidu.com/s/14j9tMqGlAy_8y3067xh-vw) 提取码: nadv - -## 效果图 - -![PyQtClient](https://github.com/PyQt5/PyQtClient/raw/master/ScreenShot/PyQtClient.gif) - diff --git a/source/_posts/pyqtclientmac.md b/source/_posts/pyqtclientmac.md deleted file mode 100644 index 9a69b69a..00000000 --- a/source/_posts/pyqtclientmac.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -author: myphper -title: 在Mac上以正确的姿势使用PyQtClient看Demo -date: 2019-04-02 17:18:43 -tags: - - PyQt -categories: 教程 ---- - -由于PyQtClient只提供了Windows的版本,这里记录下编译后在Mac上运行。 - - -## 下载项目 - -安装git略。没有的东西可以都先去试试brew install xxx。没安装homebrew的建议使用搜索引擎 - -```git clone https://github.com/PyQt5/PyQtClient.git``` - -## 配置环境 - -1. 打开IDE配置python环境,使用anaconda比较方便 -2. 推荐用pycharm,我是习惯了用idea。anaconda安装可以去官网下载。 -3. 环境原因,选择新建一个 python 3.6 p.s. 我取的环境名字就是 3.6 所以后面的3.6其实是这个原因 - -## conda源 - -最好是加环境变量,不加也可以,就是以后用到的都需要指定路径,不太常用,我就没加 - -``` -~/anaconda3/bin/conda config --add channels conda-forge -~/anaconda3/bin/conda config --add channels defaults -~/anaconda3/bin/conda config --add channels r -~/anaconda3/bin/conda config --add channels bioconda -~/anaconda3/bin/conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ -``` - -## pip源 - -``` -mkdir ~/.pip && vim ~/.pip/pip.conf -``` - -``` -[global] -index-url = http://mirrors.aliyun.com/pypi/simple/ -[install] -trusted-host = mirrors.aliyun.com -``` - -## 安装编译依赖 - -``` -~/.conda/envs/3.6/bin/pip install -r PyQtClient/requirements.txt -``` - -运行提示没有webkit,开始手动编译 - -1. `wget http://download.qt.io/archive/qt/5.9/5.9.0/qt-opensource-mac-x64-5.9.0.dmg` -2. `wget https://github.com/annulen/webkit/releases/download/qtwebkit-5.212.0-alpha2/qtwebkit-5.212.0_alpha2-qt59-darwin-x64.tar.xz` -3. `wget https://www.riverbankcomputing.com/static/Downloads/PyQt5/5.10.1/PyQt5_gpl-5.10.1.zip` -4. `wget https://www.riverbankcomputing.com/static/Downloads/sip/4.19.8/sip-4.19.8.tar.gz` -5. 编译sip:`~/.conda/envs/3.6/bin/python configure.py --platform macx-g++ && make && sudo make install` -6. 编译Webkit.so 没有qmake 和 sip的环境变量, 所以后面都是手动指定的 -``` -~/.conda/envs/3.6/bin/python configure.py --confirm-license --no-designer-plugin --no-qml-plugin --disable=dbus --disable=QAxContainer --disable=QtAndroidExtras --disable=QtBluetooth --disable=QtDBus --disable=QtDesigner --disable=Enginio --disable=QtLocation --disable=QtMacExtras --disable=QtMultimedia --disable=QtMultimediaWidgets --disable=QtNfc --disable=QtSerialPort --disable=QtSql --disable=QtSvg --disable=QtTest --disable=QtWinExtras --disable=QtX11Extras --disable=QtXml --disable=QtXmlPatterns --disable=pylupdate --disable=pyrcc --qmake=~/Qt5.9.0/5.9/clang_64/bin/qmake --sip=~/.conda/3.6/bin/sip && make && sudo make install -``` - -## 插曲 - -1. libcurl版本要求10.0,而我的是9.0,原因是前面我自己摸索,乱装依赖,所以遇到了 -``` -~/anaconda3/bin/conda install -n 3.6 -c conda-forge libcurl -``` -2. 结果这个libcurl 10.0.0 是装上了,可是pygit2版本不对了,conda给升级了,PyQtClient里requirements.txt要求这个包的版本(pygit2==0.27.2)几乎决定了其他的环境版本。后来还是老实的用conda去装了。这个连python版本什么的都会跟着变的。最后降级的结果是python 3.6.7 -``` -~/anaconda3/bin/conda install -n 3.6 -c conda-forge libgit2==0.27.2 -``` - -至此总算是启动正常了。 \ No newline at end of file diff --git a/source/_posts/pytest_qt_modal_625781186.md b/source/_posts/pytest_qt_modal_625781186.md deleted file mode 100644 index 6bb21a0d..00000000 --- a/source/_posts/pytest_qt_modal_625781186.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -author: 人间白头 -title: pytest-qt 测试模态窗体. -date: 2020年4月27日22:19:27 -tags: - - pytest-qt -categories: 教程 ---- - -步骤分别是 : - -1. 点击 开始扫描 弹出 选择路径窗口 ; - -2. 勾选路基 ; - -3.点击确定 ; - - -大概想测一下这个界面 : - -![image.png](https://upload-images.jianshu.io/upload_images/10769157-c1ed0bd52808c5b8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) - - -步骤分别是 : - -1. 点击 开始扫描 弹出 选择路径窗口 ; - -2. 勾选路基 ; - -3.点击确定 ; - -需要测试的函数 : - -![image.png](https://upload-images.jianshu.io/upload_images/10769157-b5265859d74b269d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) - - -测试函数 : - -![image.png](https://upload-images.jianshu.io/upload_images/10769157-58f4310a54a815ee.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) - - -可以发现断言失败 . - -![image.png](https://upload-images.jianshu.io/upload_images/10769157-939c73b5be19c21e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) - - -官方文档 : 测试模态窗体. - -[https://pytest-qt.readthedocs.io/en/latest/note_dialogs.html](https://pytest-qt.readthedocs.io/en/latest/note_dialogs.html) - -用的是官方的 `monkeypatch` 方式 . - -大致意思就是替换 `FileSelectPathDialog` 类的exec函数. diff --git a/source/_posts/python_statemachine_625781186.md b/source/_posts/python_statemachine_625781186.md deleted file mode 100644 index 42d4f0a4..00000000 --- a/source/_posts/python_statemachine_625781186.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -author: 人间白头  -title: python 状态机模块   -date: 2019-7-17 17:03:33 -tags: - - Python - - python 状态机 - -categories: 随笔 ---- - -用状态来取代if...else判断。 - - - -GUI涉及到挺多的状态改变 , 以前一直用 if...else 来判断 , 最近读了设计模式 ,发现有个状态模式 , 随后发现了状态机这个东西 . - -python的状态机模块挺多的 , 不过好像很多都不更新了. -推荐2个状态机模块 , 但是也没有太深入的使用经验 , 就跑跑例子 , 以后有更详细的pyqt例子再补上 . - -1: `pip install python-statemachine` - -官方例子 : [https://github.com/fgmacedo/python-statemachine](https://github.com/fgmacedo/python-statemachine) - -2.`pip install state_machine` - -官方例子 : [https://github.com/jtushman/state_machine](https://github.com/jtushman/state_machine) - -1的 最近一次更新在6个月以前 , 使用`类继承`和`mixin`方式 , 不过有些地方不如2个人性化; - -2的设计更人性化一些 , 包括状态改变`before`和 `after` , 不过由于是装饰器实现的动态增加属性 , 有些地方编辑器智能提示可能就靠不上了. - -两者实现实现方式不一样 , 有兴趣可以读读源码 . - -3. qt内置状态机框架 - -https://blog.csdn.net/amnes1a/article/details/62418196 - -https://blog.csdn.net/dongfenghuojian/article/details/78187131 - -http://blog.sina.com.cn/s/articlelist_3284623693_0_1.html (系列教程) diff --git a/source/_posts/qtninepatch.md b/source/_posts/qtninepatch.md deleted file mode 100644 index 61fa68c6..00000000 --- a/source/_posts/qtninepatch.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -author: Irony -title: PyQt5显示.9格式的PNG图片 -date: 2018-10-26 10:00:08 -tags: - - PyQt - - 图片 - - 气泡 - - .9png -categories: 例子 ---- - -做过安卓开发的和使用过QQ的都知道`.9.png`这种图片格式,效果就如QQ的聊天气泡一样可以拉伸,这种格式的图片允许开发人员定义可扩展区域,当需要延伸图片以填充比图片本身更大区域时,可扩展区的内容被延展;允许开发人员定义内容显示区,用于显示文字或其他内容。目前在`Github`上有两个C++版本的,在这里我把它们都用Python实现了一遍。另外一个我也为`PyQt`提供了编译好的pyd文件。 - - -## C++版本 - -在Github开源库中搜索到两个C++版本的 - -1. 一个是 [NinePatchQt](https://github.com/Roninsc2/NinePatchQt) -2. 一个是 [QtNinePatch](https://github.com/soramimi/QtNinePatch) - -## PyQt5版本 - -这里也分为两个版本,都是基于上面的C++源码翻译改写过来的,具体的例子见项目里面的测试代码吧。 - -1. [QtNinePatch](https://github.com/PyQt5/PyQt/blob/master/QLabel/QtNinePatch.py)是参考第一个源码编写,用法是在`paintEvent`中调用 -2. [QtNinePatch2](https://github.com/PyQt5/PyQt/blob/master/QLabel/QtNinePatch2.py)是参考第二个源码编写,用法是`pixmap = QtNinePatch.createPixmapFromNinePatchImage(self.image, self.width(), self.height())`直接得到一个处理好的`QPixmap`对象来使用 - -## 说明 - -1. 建议优先使用pyd版本的(后续提供Python3.4 3.5 3.6 3.7 编译好的32为库文件),也可以自行编译,编译步骤见下文。 -2. 其次可以使用纯python版本2的(个人觉得方便调用) -3. 最后再考虑纯python版本1的吧 -4. 以上为个人意见,两个C++版本的写法不一样,但是核心算法应该是类似的。 - -## 自行编译 - -1. 首先要安装好Qt、PyQt5、编译安装对应的sip、对应的VC++编译工具 -2. 用Qt Creator 打开pro文件进行编译 -3. 进入源码中的sip文件夹修改configure.py文件 -``` -# 这里是你的VC版本和对应的Qt目录中的文件夹 -config.platform = "win32-msvc2010" -qt_path = 'D:/soft/Qt/Qt5.5.1/5.5/msvc2010' -``` -4. 最后执行python configure.py来编译 - -## 下载 - -https://github.com/PyQt5/PyQt/tree/master/QLabel - -## 效果图 - -![NinePatchImage](/PyQt/QLabel/ScreenShot/NinePatchImage.gif) - diff --git a/source/_posts/qtwebjs.md b/source/_posts/qtwebjs.md deleted file mode 100644 index 511332ac..00000000 --- a/source/_posts/qtwebjs.md +++ /dev/null @@ -1,124 +0,0 @@ ---- -author: Irony -title: QtWebkit和QWebEngineView与Javascript交互 -date: 2019-05-22 11:30:36 -tags: - - PyQt - - QWebView - - QWebEngineView - - 浏览器 -categories: 例子 ---- - -以前还是`QWebView`的时候和`Javascript`交互起来很方便,但是到了Qt5.6以后改用了`QWebEngineView`,并通过其提供的`qwebchannel.js`来进行交互。可能是由于刚出来的原因,这玩意儿有个bug就是必须在每次加载页面的时候手动注入,跳转页面后就失效了,需要手动注入,目前有没有修复具体未测试。这里对`QWebView`和`QWebEngineView`与Js交互都做了一个示例。 - - -## 说明 - -1. 针对`QWebView`通过`QWebFrame`的`addToJavaScriptWindowObject`把对象传递到`Javascript`中 -2. 针对`QWebEngineView`通过`QWebChannel.registerObject('Bridge', QObject)`把对象传递到`Javascript`中 -3. 可以通过`@pyqtSlot`装饰器来申明该方法可以暴露给`Javascript`调用 - -```python -@pyqtSlot(str) -def callFromJs(self, text): - QMessageBox.information(self, "提示", "来自js调用:{}".format(text)) -``` - -4. 针对`QWebView`在`Javascript`中获取该对象,可以通过该对象对窗口属性以及信号和暴露出的方法进行调用 - -```javascript -// 这里绑定窗口的标题变化信号(这个信号是由QWidget内部的) -Bridge.windowTitleChanged.connect({fun: function(title) { - showLog("标题被修改为:" + title); -}}, "fun"); - -// 绑定自定义的信号customSignal -Bridge.customSignal.connect({fun: function(text) { - showLog("收到自定义信号内容:" + text); -}}, "fun"); -``` - -5. 针对`QWebEngineView`在`Javascript`中获取该对象,可以通过该对象对窗口属性以及信号和暴露出的方法进行调用 - -```javascript -new QWebChannel(qt.webChannelTransport, - function(channel) { - window.Bridge = channel.objects.Bridge; - - // 这里绑定窗口的标题变化信号(这个信号是由QWidget内部的) - Bridge.windowTitleChanged.connect(function(title) { - showLog("标题被修改为:" + title); - }); - - // 绑定自定义的信号customSignal - Bridge.customSignal.connect(function(text) { - showLog("收到自定义信号内容:" + text); - }); - } -); -``` - -## 代码 - -`QWebView`: https://github.com/PyQt5/PyQt/blob/master/QWebView/JsSignals.py - -`QWebEngineView`: https://github.com/PyQt5/PyQt/blob/master/QWebEngineView/JsSignals.py - -1. 针对`QWebView`的核心实现 - -```python -class WebView(QWebView): - - customSignal = pyqtSignal(str) - - def __init__(self, *args, **kwargs): - super(WebView, self).__init__(*args, **kwargs) - self.initSettings() - # 暴露接口对象 - self.page().mainFrame().javaScriptWindowObjectCleared.connect(self._exposeInterface) - - def _exposeInterface(self): - """向Js暴露调用本地方法接口 - """ - self.page().mainFrame().addToJavaScriptWindowObject('Bridge', self) - - # 注意pyqtSlot用于把该函数暴露给js可以调用 - @pyqtSlot(str) - def callFromJs(self, text): - QMessageBox.information(self, "提示", "来自js调用:{}".format(text)) - - def sendCustomSignal(self): - # 发送自定义信号 - self.customSignal.emit('当前时间: ' + str(time())) -``` - -2. 针对`QWebEngineView`的核心实现 - -```python -class WebEngineView(QWebEngineView): - - customSignal = pyqtSignal(str) - - def __init__(self, *args, **kwargs): - super(WebEngineView, self).__init__(*args, **kwargs) - self.channel = QWebChannel(self) - # 把自身对象传递进去 - self.channel.registerObject('Bridge', self) - # 设置交互接口 - self.page().setWebChannel(self.channel) - - # 注意pyqtSlot用于把该函数暴露给js可以调用 - @pyqtSlot(str) - def callFromJs(self, text): - QMessageBox.information(self, "提示", "来自js调用:{}".format(text)) - - def sendCustomSignal(self): - # 发送自定义信号 - self.customSignal.emit('当前时间: ' + str(time())) -``` - - -## 效果图 - -![JsSignals](/PyQt/QWebEngineView/ScreenShot/JsSignals.gif) \ No newline at end of file diff --git a/source/_posts/read_open_source.md b/source/_posts/read_open_source.md deleted file mode 100644 index f419b9ec..00000000 --- a/source/_posts/read_open_source.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -author: 人间白头  -title: 像读文章一样读源码 -date: 2019-07-07 01:37:22 -tags: - - Python - - debug - - snoop -categories: 随笔 ---- - -使用snoop, 像读文章一样读源码。 - - - -不得不说 开源项目没有一个提纲 , 看起来太操蛋了。问了作者, 作者说 , 你运行下主函数, 然后慢慢跟 。。。 -![image.png](https://upload-images.jianshu.io/upload_images/10769157-b274b7acaecf49bc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) - -没有目的地概览 , 不知不觉就追究到细节里面去了。 - -![image.png](https://upload-images.jianshu.io/upload_images/10769157-1304cc87fcd42cae.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) - -所以这一篇文章的目地就是 , 如何在没有提纲的情况下 , 能更好的只关注流程 , 而不是细节 。 - -开始 : -1. python DEBUG 模块介绍 : - 前段时间看过挺多文章提到pysoonper这个调试模块 , 有兴趣的可以百度一下. -个人尝试了一下 , 篇幅过大的DEBUG不适合用 pysoonper , 因为没有缩进 ! - 这几天偶然遇到一个二次封装的模块[snoop]([https://github.com/alexmojaki/snoop](https://github.com/alexmojaki/snoop) -), 完美地解决了这个问题. -2. 操作步骤 : - -- 1 . 在`eric6.py`的`main()`函数上加snoop装饰器; -![image.png](https://upload-images.jianshu.io/upload_images/10769157-74129f6a6c303b25.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -- 2 . 用vscode 打开 `eric6start_.log` 文件 (8层深度log文件34W行, pycharm对大文件支持很差); -![log文件](https://upload-images.jianshu.io/upload_images/10769157-ae946c117a082c24.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) - -发现可以折叠 , 但是最大可折叠等级只到5级 , 而且无法对对应等级折叠 , 有点遗憾 。也许是.log格式选得不太好, 不知道是否有更好的后缀格式。 -- 3 . vscode配置log文件关键字高亮; -安装高亮插件 -![image.png](https://upload-images.jianshu.io/upload_images/10769157-8f6fee2356d7071d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -配置高亮关键字 -![image.png](https://upload-images.jianshu.io/upload_images/10769157-a135fd015409b3da.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) - -将`call` 和`return` 给加进去. - -- 4 .增加阶段关键字; - -![eric6启动阶段](https://upload-images.jianshu.io/upload_images/10769157-c39d01a02149e808.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) - -![image.png](https://upload-images.jianshu.io/upload_images/10769157-aef5704c36824dcc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) - -加`#000` 是为了方便搜索 。 -需要自己手动折叠 。 -可以发现 每个`splash.showMessage()` 都是一个阶段 , 展开折叠之后就是每个阶段具体执行细节 。 - ---- - -### ps: vscode 阅读log文件还是有一些不方便的地方 , 除了在2.中提到的, 还有包括关闭文件再打开, 折叠状态不会保留 , 有其他更好的方式 请留言告诉我 , 谢谢. diff --git a/source/_posts/rlatticeeffect.md b/source/_posts/rlatticeeffect.md deleted file mode 100644 index 88deac19..00000000 --- a/source/_posts/rlatticeeffect.md +++ /dev/null @@ -1,268 +0,0 @@ ---- -author: Irony -title: PyQt5仿网页鼠标移动点阵特效 -date: 2018-10-29 16:49:10 -tags: - - PyQt - - 动画 - - 特效 -categories: 例子 ---- - -Orz,前段时间有个zz需求,就是要做一个类似网页上很多个多点连线、鼠标移动跟随的那种炫酷特效,然后花了点时间在网上找了js做的,刚开始打算是嵌入`QWebView`来显示网页,后来研究了下js的算法代码,遂改用`QWidget`的`paintEvent`直接绘制。 - - -## 大概思路 - -1. 先根据窗口大小随机创建一些点 -2. 遍历这些点并找到与之相关联的点 -3. 在动画过程中绘制圆点和画两点之间的连线 -4. 属性动画`QPropertyAnimation`改变颜色的透明度 - -## 题外 - -1. 这里没有仔细去研究js里的算法优化,在浏览器里嗖嗖的就生成了,在py里好慢.... -2. 尽量在py里优化了循环操作,也简单的做了个cython加速也才提高了1s ? 1倍?... -3. 不要只是为了好看用这玩意儿,和网页的效果一样,占CPU !!!!!!没有任何意义 -4. 如果有更好的优化算法请告知, 3Q -5. pyd是python3.4生成的,删掉pyd也能运行 - -## 代码 - -https://github.com/PyQt5/PyQt/blob/master/QPropertyAnimation/RlatticeEffect.py - -```python -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -""" -Created on 2018年11月22日 -@author: Irony -@site: https://pyqt5.com, https://github.com/892768447 -@email: 892768447@qq.com -@file: -@description: -""" -from random import random -from time import time - -from PyQt5.QtCore import QPropertyAnimation, QObject, pyqtProperty, QEasingCurve,\ - Qt, QRectF, pyqtSignal -from PyQt5.QtGui import QColor, QPainterPath, QPainter -from PyQt5.QtWidgets import QWidget - - -__Author__ = """By: Irony -QQ: 892768447 -Email: 892768447@qq.com""" -__Copyright__ = 'Copyright (c) 2018 Irony' -__Version__ = 1.0 - - -try: - import pointtool # @UnusedImport @UnresolvedImport - getDistance = pointtool.getDistance - findClose = pointtool.findClose -except: - import math - - def getDistance(p1, p2): - return math.pow(p1.x - p2.x, 2) + math.pow(p1.y - p2.y, 2) - - def findClose(points): - plen = len(points) - for i in range(plen): - closest = [None, None, None, None, None] - p1 = points[i] - for j in range(plen): - p2 = points[j] - dte1 = getDistance(p1, p2) - if p1 != p2: - placed = False - for k in range(5): - if not placed: - if not closest[k]: - closest[k] = p2 - placed = True - for k in range(5): - if not placed: - if dte1 < getDistance(p1, closest[k]): - closest[k] = p2 - placed = True - p1.closest = closest - - -class Target: - - def __init__(self, x, y): - self.x = x - self.y = y - - -class Point(QObject): - - valueChanged = pyqtSignal() - - def __init__(self, x, ox, y, oy, *args, **kwargs): - super(Point, self).__init__(*args, **kwargs) - self.__x = x - self._x = x - self.originX = ox - self._y = y - self.__y = y - self.originY = oy - # 5个闭合点 - self.closest = [0, 0, 0, 0, 0] - # 圆半径 - self.radius = 2 + random() * 2 - # 连线颜色 - self.lineColor = QColor(156, 217, 249) - # 圆颜色 - self.circleColor = QColor(156, 217, 249) - - def initAnimation(self): - # 属性动画 - if not hasattr(self, 'xanimation'): - self.xanimation = QPropertyAnimation( - self, b'x', self, valueChanged=self.valueChanged.emit, - easingCurve=QEasingCurve.InOutSine) - self.yanimation = QPropertyAnimation( - self, b'y', self, valueChanged=self.valueChanged.emit, - easingCurve=QEasingCurve.InOutSine, - finished=self.updateAnimation) - self.updateAnimation() - - def updateAnimation(self): - self.xanimation.stop() - self.yanimation.stop() - duration = (1 + random()) * 1000 - self.xanimation.setDuration(duration) - self.yanimation.setDuration(duration) - self.xanimation.setStartValue(self.__x) - self.xanimation.setEndValue(self.originX - 50 + random() * 100) - self.yanimation.setStartValue(self.__y) - self.yanimation.setEndValue(self.originY - 50 + random() * 100) - self.xanimation.start() - self.yanimation.start() - - @pyqtProperty(float) - def x(self): - return self._x - - @x.setter - def x(self, x): - self._x = x - - @pyqtProperty(float) - def y(self): - return self._y - - @y.setter - def y(self, y): - self._y = y - - -class Window(QWidget): - - def __init__(self, *args, **kwargs): - super(Window, self).__init__(*args, **kwargs) - self.setMouseTracking(True) - self.resize(800, 600) - self.points = [] - self.target = Target(self.width() / 2, self.height() / 2) - self.initPoints() - - def paintEvent(self, event): - super(Window, self).paintEvent(event) - painter = QPainter() - painter.begin(self) - painter.setRenderHint(QPainter.Antialiasing) - painter.fillRect(self.rect(), Qt.black) - self.animate(painter) - painter.end() - - def mouseMoveEvent(self, event): - super(Window, self).mouseMoveEvent(event) - # 鼠标移动时更新xy坐标 - self.target.x = event.x() - self.target.y = event.y() - self.update() - - def initPoints(self): - t = time() - self.points.clear() - # 创建点 - stepX = self.width() / 20 - stepY = self.height() / 20 - for x in range(0, self.width(), int(stepX)): - for y in range(0, self.height(), int(stepY)): - ox = x + random() * stepX - oy = y + random() * stepY - point = Point(ox, ox, oy, oy) - point.valueChanged.connect(self.update) - self.points.append(point) - print(time() - t) - - t = time() - # 每个点寻找5个闭合点 - findClose(self.points) - print(time() - t) - - def animate(self, painter): - for p in self.points: - # 检测点的范围 - value = abs(getDistance(self.target, p)) - if value < 4000: - # 其实就是修改颜色透明度 - p.lineColor.setAlphaF(0.3) - p.circleColor.setAlphaF(0.6) - elif value < 20000: - p.lineColor.setAlphaF(0.1) - p.circleColor.setAlphaF(0.3) - elif value < 40000: - p.lineColor.setAlphaF(0.02) - p.circleColor.setAlphaF(0.1) - else: - p.lineColor.setAlphaF(0) - p.circleColor.setAlphaF(0) - - # 画线条 - if p.lineColor.alpha(): - for pc in p.closest: - if not pc: - continue - path = QPainterPath() - path.moveTo(p.x, p.y) - path.lineTo(pc.x, pc.y) - painter.save() - painter.setPen(p.lineColor) - painter.drawPath(path) - painter.restore() - - # 画圆 - painter.save() - painter.setPen(Qt.NoPen) - painter.setBrush(p.circleColor) - painter.drawRoundedRect(QRectF( - p.x - p.radius, p.y - p.radius, 2 * p.radius, 2 * p.radius), p.radius, p.radius) - painter.restore() - - # 开启动画 - p.initAnimation() - - -if __name__ == '__main__': - import sys - import cgitb - sys.excepthook = cgitb.enable(1, None, 5, '') - from PyQt5.QtWidgets import QApplication - app = QApplication(sys.argv) - w = Window() - w.show() - sys.exit(app.exec_()) -``` - -## 效果图 - -![RlatticeEffect](/PyQt/QPropertyAnimation/ScreenShot/RlatticeEffect.gif) - diff --git a/source/_posts/runnablesignal_625781186.md b/source/_posts/runnablesignal_625781186.md deleted file mode 100644 index 5f27c9cc..00000000 --- a/source/_posts/runnablesignal_625781186.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -author: 不许人间见白头 -title: QRunnable线程池发信号 -date: 2019-04-30 15:58:09 -tags: - - PyQt - - 信号 - - 线程 -categories: 教程 ---- - -因为只有继承`QObject`的类才能有信号和自定义信号,而`QRunnable`并不是继承自`QObject`,也不能用多继承的方式,这里考虑定义个全局的QObject变量用来存放一些定义好的可复用的信号。 - - -pools 是 `QThreadPool` 实例 - -## 看图说话 - -1. ![runnablesignal1](/images/runnablesignal1.png) -2. 定义一个全局信号类 -![runnablesignal2](/images/runnablesignal2.png) -3. 在QRunnable 中发送 -![runnablesignal3](/images/runnablesignal3.png) diff --git a/source/_posts/shadowradius.md b/source/_posts/shadowradius.md deleted file mode 100644 index 7e5da355..00000000 --- a/source/_posts/shadowradius.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -author: Irony -title: PyQt5无边框圆角阴影 -date: 2019-04-26 00:06:26 -tags: - - PyQt - - 无边框 - - 阴影 - - 圆角 -categories: 例子 ---- - -在做PyQt窗口开发中经常会遇到要做一些无边框不规则的窗口,可能还会带有阴影效果,这里演示做一个简单的无边框圆角的窗口,原理就在于背景窗口的透明和一层有色背景控件的叠加。 - - -## 原理说明 - -1. 黑色(方便说明)的`QDialog`或者`QWidget`作为全透明无边框窗口。 -2. 其中白色的`QWidget`才是主要显示圆角和阴影的窗口,用于承载其它控件的显示。 -3. 注意红色和紫色的方框内的层次。 -4. 另:如果要熟悉纯代码编写请看 [FramelessDialog.py](https://github.com/PyQt5/PyQt/blob/master/Demo/FramelessDialog.py) - -如图: - -![FramelessDialog1](/PyQt/Demo/ScreenShot/FramelessDialog1.png) - -## 代码 - -https://github.com/PyQt5/PyQt/blob/master/Demo/FramelessDialog.py - -```python -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -""" -Created on 2019年4月25日 -@author: Irony -@site: https://pyqt5.com https://github.com/892768447 -@email: 892768447@qq.com -@file: FramelessWidget -@description: 无边框圆角带阴影窗口 -""" -from PyQt5.QtCore import Qt -from PyQt5.QtWidgets import QDialog, QGraphicsDropShadowEffect -from frameless import Ui_Dialog - - -__Author__ = 'Irony' -__Copyright__ = 'Copyright (c) 2019' - - -class Window(QDialog, Ui_Dialog): - - def __init__(self, *args, **kwargs): - super(Window, self).__init__(*args, **kwargs) - self.mPos = None - self.setupUi(self) - self.closeButton.clicked.connect(self.close) - # 重点 - # 无边框 - self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint) - # 背景透明(就是ui中黑色背景的那个控件) - self.setAttribute(Qt.WA_TranslucentBackground, True) - - # 添加阴影 - effect = QGraphicsDropShadowEffect(self) - effect.setBlurRadius(12) - effect.setOffset(0, 0) - effect.setColor(Qt.gray) - self.setGraphicsEffect(effect) - - # 加上简单的移动功能 - - def mousePressEvent(self, event): - """鼠标点击事件""" - if event.button() == Qt.LeftButton: - self.mPos = event.pos() - event.accept() - - def mouseReleaseEvent(self, event): - '''鼠标弹起事件''' - self.mPos = None - event.accept() - - def mouseMoveEvent(self, event): - if event.buttons() == Qt.LeftButton and self.mPos: - self.move(self.mapToGlobal(event.pos() - self.mPos)) - event.accept() - - -if __name__ == '__main__': - import sys - from PyQt5.QtWidgets import QApplication - app = QApplication(sys.argv) - w = Window() - w.show() - sys.exit(app.exec_()) -``` - - -## 效果图 - -![FramelessDialog](/PyQt/Demo/ScreenShot/FramelessDialog.png) - -## 下载 - -[无边框圆角阴影.zip](/files/无边框圆角阴影.zip) \ No newline at end of file diff --git a/source/_posts/showframe.md b/source/_posts/showframe.md deleted file mode 100644 index 8da70064..00000000 --- a/source/_posts/showframe.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -author: Irony -title: PyQt5调整窗口显示边框 -date: 2019-04-26 22:19:26 -tags: - - PyQt - - 边框 -categories: 教程 ---- - -在`windows`某些场景下调整窗口大小或者移动后就会导致里面的内容重绘(速度慢,卡顿,闪烁),其实在以前`windows`在低配置设备为了减少这种频繁绘制的情况,默认会开启这种效果,不过目前设备越来越好了就关闭了该功能。具体是在控制面板中->调整`Windows`的外观和性能->去掉勾选 拖动时显示窗口内容。 - - -由于这个开关是全局状态的,而我们只需要在自己的窗口中实现该效果有两种方式。 - -1. 一种是自己绘制一个边框效果,放开鼠标时才操作真正的窗口。 -2. 二是替换窗口的处理过程函数`wndproc`处理`WM_NCLBUTTONDOWN`消息事件。 - -今天讲第二种方法: - -1. 需要了解 `SystemParametersInfo` API函数 -2. `SPI_GETDRAGFULLWINDOWS`:确定是否允许拖拉到最大窗口 -3. `SPI_SETDRAGFULLWINDOWS`:设置是否允许拖至最大窗口 - -效果就是这样的: - -![ShowFrameWhenDrag](/PyQt/Demo/ScreenShot/ShowFrameWhenDrag.gif) - -正如图片所看的那样,窗体在移动的时候,窗体并没有绘制出来,而是绘制出窗体的边框,等到窗体不在移动的时候就直接把窗体图像数据全部绘制出来,这样就避免了窗体在移动的时候出现闪烁的现象。 - -## 代码 - -https://github.com/PyQt5/PyQt/blob/master/Demo/ShowFrameWhenDrag.py - -```python -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -""" -Created on 2019年4月23日 -@author: Irony -@site: https://pyqt5.com https://github.com/892768447 -@email: 892768447@qq.com -@file: ShowFrameWhenDrag -@description: 调整窗口显示边框 -""" -from ctypes import sizeof, windll, c_int, byref, c_long, c_void_p, c_ulong, c_longlong,\ - c_ulonglong, WINFUNCTYPE, c_uint - -from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel - - -__Author__ = 'Irony' -__Copyright__ = 'Copyright (c) 2019 Irony' -__Version__ = 1.0 - -if sizeof(c_long) == sizeof(c_void_p): - WPARAM = c_ulong - LPARAM = c_long -elif sizeof(c_longlong) == sizeof(c_void_p): - WPARAM = c_ulonglong - LPARAM = c_longlong - -WM_NCLBUTTONDOWN = 0x00a1 -GWL_WNDPROC = -4 -SPI_GETDRAGFULLWINDOWS = 38 -SPI_SETDRAGFULLWINDOWS = 37 -WNDPROC = WINFUNCTYPE(c_long, c_void_p, c_uint, WPARAM, LPARAM) - -try: - CallWindowProc = windll.user32.CallWindowProcW - SetWindowLong = windll.user32.SetWindowLongW - SystemParametersInfo = windll.user32.SystemParametersInfoW -except: - CallWindowProc = windll.user32.CallWindowProcA - SetWindowLong = windll.user32.SetWindowLongA - SystemParametersInfo = windll.user32.SystemParametersInfoA - - -def GetDragFullwindows(): - rv = c_int() - SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, byref(rv), 0) - return rv.value - - -def SetDragFullwindows(value): - SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, value, 0, 0) - - -class Window(QWidget): - - def __init__(self, *args, **kwargs): - super(Window, self).__init__(*args, **kwargs) - layout = QVBoxLayout(self) - layout.addWidget(QLabel('拖动或者调整窗口试试看')) - - # 重点替换窗口处理过程 - self._newwndproc = WNDPROC(self._wndproc) - self._oldwndproc = SetWindowLong( - int(self.winId()), GWL_WNDPROC, self._newwndproc) - - def _wndproc(self, hwnd, msg, wparam, lparam): - if msg == WM_NCLBUTTONDOWN: - # 获取系统本身是否已经开启 - isDragFullWindow = GetDragFullwindows() - if isDragFullWindow != 0: - # 开启虚线框 - SetDragFullwindows(0) - # 系统本身处理 - ret = CallWindowProc( - self._oldwndproc, hwnd, msg, wparam, lparam) - # 关闭虚线框 - SetDragFullwindows(1) - return ret - return CallWindowProc(self._oldwndproc, hwnd, msg, wparam, lparam) - - -if __name__ == '__main__': - import sys - from PyQt5.QtWidgets import QApplication - app = QApplication(sys.argv) - w = Window() - w.show() - sys.exit(app.exec_()) -``` - -## 片尾 - -替换窗口过程可以处理很多系统窗口的处理过程,更多需要读者自行去发现。 \ No newline at end of file diff --git a/source/_posts/speedgithub.md b/source/_posts/speedgithub.md deleted file mode 100644 index ce7b64a0..00000000 --- a/source/_posts/speedgithub.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -author: Irony -title: 解决GitHub下载速度缓慢的问题 -date: 2019-04-18 08:59:06 -tags: - - Github -categories: 笔记 ---- - -由于Github的下载走的是AWS - 亚马逊的路线,,so slow,跟乌龟一样慢。。照着一些方法改了hosts文件,偶尔能提提速度。 - - -## Windows -Hosts文件的路径是: - -C:\Windows\System32\drivers\etc - -## Mac -终端内输入: - -sudo vim /etc/hosts - - -## 追加域名的IP地址 - -利用https://www.ipaddress.com/ 来获得以下两个GitHub域名的IP地址: - -(1) github.com - -(2) github.global.ssl.fastly.net - -打开网页后,利用输入框内分别查询两个域名 - -将以上两段IP写入Hosts文件中: - - - -``` -192.30.253.112               github.com -151.101.185.194              github.global.ssl.fastly.net -``` - -保存。 - -刷新 DNS 缓存 - -在终端或CMD中,执行以下命令: - -ipconfig /flushdns \ No newline at end of file diff --git a/source/_posts/studynotes.md b/source/_posts/studynotes.md deleted file mode 100644 index 242b15e5..00000000 --- a/source/_posts/studynotes.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -author: Irony -title: PyQt学习心得 -date: 2019-08-26 09:00:00 -sticky: 888 -tags: - - PyQt -categories: 笔记 ---- - -在学习PyQt的过程中由于资料的缺乏或者没有中文导致大多数人感叹资料太少,学习困难,又或者急于求进,赶鸭子上架的情况,此时有系统的学习方法很重要。每个人都需要有自己的学习方法,别人的学习方法并不一定适合自己但可以采纳一些。笔者在这里列举了一些当初自己自学的一些心得和方法,希望帮助大家建立一套自己的学习PyQt的方法,提高自身的学习能力。 - - -## Python基础 - -在学习和使用PyQt之前需要熟练使用Python,经过对QQ群里经常提问的问题的分析,发现大部分人对Python中的基础知识掌握不牢固导致很多基础问题,如果要想更好的使用Python以及它的扩展必需要进行系统的学习。这里列举一下常用的知识点。 - -1. 类         [参考资料](https://www.runoob.com/python3/python3-class.html) -2. 类的继承 -3. 类的多继承 -4. 类方法重写     [参考资料](https://www.runoob.com/w3cnote/python-extends-init.html) -5. 类中的super函数  [参考资料](https://www.runoob.com/python/python-func-super.html) -6. 函数调用/参数类型 -7. 对象调用(参考第1点) - -必须熟练掌握上面的知识点后入门PyQt才比较容易,如果初学者对上面的知识点还不是很了解,本文不适合继续往下阅读。 - -## 设计师 - -Qt 设计师除了方便快速设计一些简单的界面外,其实笔者觉得更大的作用在于帮助用户熟悉各类控件、属性、信号等 - -1. 这里建议初学者不要急于求成,打开设计师新建一个`Widget`的窗口,比如 - -![desiger_create](/images/studynotes/desiger_create.png) - -2. 然后把左侧的所有控件挨个拖动到中间的窗口中,比如这里拖动一个**Push Button**按钮 - -![desiger_drag](/images/studynotes/desiger_drag.png) - -3. 在设计师右下角的属性编辑器中列举了该控件的所有父类,意味着可以调用和重写父类的所有方法,建议初学者把这个属性编辑器的所有属性挨个调整看看效果,部分控件可能需要**Ctrl+R**预览界面才能看到,同时像**QListWidget,QTreeWidget,QTableWidget**等某些控件需要在控件上右键增加数据才可以 - -![desiger_property](/images/studynotes/desiger_property.png) -![desiger_property2](/images/studynotes/desiger_property2.png) - -4. 两个控件之间简单的信号槽关联可以通过设计师快速的设置 - -![desiger_signal](/images/studynotes/desiger_signal.png) -![desiger_signal2](/images/studynotes/desiger_signal2.png) - -5. 提高进阶的方法,当你需要手动写代码实现界面的时候,不妨把UI文件转出PY文件,看看是如何构造的(这里涉及到布局等知识见后文) - -## 布局 - -Qt界面提供了方便的4种基本布局,**QVboxLayout,QHboxLayout,QFormLayout,QGridLayout**,初学者需要数量掌握这4种布局外加2种拉伸器(占位挤压) - -首先需要知道Qt界面的中控件的层级顺序以及parent,parent的作用既作为子控件的父元素也可以自动管理Qt的对象(具体可以搜索下关于 Qt parent的资料) - -1. 在没有布局的情况下,在设计师中拖动摆放的控件是一层一层的叠加覆盖,此时每个添加的子控件的parent都是最外层的控件 - -![desiger_stack](/images/studynotes/desiger_stack.png) - -2. 如果需要界面中的控件自动适应高度宽度,此时则需要使用4种布局来包裹里面的子控件,注意的是:布局不是控件不能设置高度宽度和样式等,是一个抽象的东西,就好比是一根橡皮筋包裹几个矩形的物品;布局也可以设置一些属性(在设计师属性编辑器中),比如设置两者直接的间距,设置距离上下左右的间距,设置比例等 - -![desiger_layout](/images/studynotes/desiger_layout.png) - -3. 在没有布局或者有布局的时候。可以添加容器控件(**QWidget,QFrame,QGroupBox,QScrollArea,QToolBox,QTabWidget,QStackedWidget,QMidArea,QDockWidget**)这些容器可以放置子控件,从而循环嵌套。 - -## 例子 - -在PyQt5.5的时候自带了一个例子文件夹(后面的版本没有的话可以下载PyQt5源码,里面有个examples文件夹),想要熟练的掌握PyQt还需要从自带的例子中学习,必须要每个例子都运行一次然后看看这个例子实现了什么,这样才能记忆深刻。 -同时很多开发者在[https://github.com/PyQt5/PyQt](https://github.com/PyQt5/PyQt)分享了各类进阶例子,同时也欢迎大家共同完善该项目,提供更多更好的例子。另外也可以下载该项目的客户端[PyQtClient](https://github.com/PyQt5/PyQtClient/releases)软件,支持运行其中的例子 - -建议在更深入的学习PyQt之前多看看一些例子。 - -## 文档 - -接下来要说的就是Qt的api文档,[官网文档](https://doc.qt.io/qt-5/classes.html),这里其实不要害怕是英文就不想看,觉得看不懂了,其实官网的文档还是比较简洁的,而且函数名也比较直观就能知道意思。也可以用谷歌浏览器打开右键翻译,基本上都能看懂。笔者前期写过一篇[如何查阅Qt文档](/viewapi.html)的文档可以阅读学习一番。 - -这里就拿[QWebEngineView](https://doc.qt.io/qt-5/qwebengineview.html)举一个例子,首先初学者在使用这个浏览器控件时候,会有诸多的问题比如:Cookie,拦截器等就不知道如何去调用函数来设置 - -1. 首先打开官网文档 [https://doc.qt.io/qt-5/qwebengineview.html](https://doc.qt.io/qt-5/qwebengineview.html),可以看到只有少量的函数可以调用,寻找一番并没有发现和Cookie相关的东西,这个时候就需要把重点放在有特俗返回值的函数上,比如: -```c++ -QWebEngineHistory * history() const -QWebEnginePage * page() const -QWebEngineSettings * settings() const -``` - -这三个函数返回了一个类实例,就意味着可以调用其中的方法。 - -2. 点击**page()**打开 [https://doc.qt.io/qt-5/qwebenginepage.html](https://doc.qt.io/qt-5/qwebenginepage.html),发现没有cookie相关的东西,只有**QWebEngineProfile * profile() const**这个函数比较可疑。 - -3. 点击**profile()**打开 [https://doc.qt.io/qt-5/qwebengineprofile.html](https://doc.qt.io/qt-5/qwebengineprofile.html),在浏览器中搜索`cookie`发现这个类中包含大量和cookie相关的东西,比如:**QWebEngineCookieStore * cookieStore()`**从名字上可以猜测大概意思为cookie储存 - -4. 点击**cookieStore()**打开 [https://doc.qt.io/qt-5/qwebenginecookiestore.html](https://doc.qt.io/qt-5/qwebenginecookiestore.html),此时就会发现这个类里面包含了删除和设置cookie的方法。 - -5. 但是找到了这些方法后,面对初学者又一个问题来了,该如何去用?根据上面4点整理一下,把他们当做简单的Python对象,方法和操作方法和class一样的。 - -```python -self.webview = QWebEngineView() -# 得到page -page = self.webview.page() -# 得到profile -profile = page.profile() -# 得到cookieStore -cookieStore = profile.cookieStore() -# 清空cookie -cookieStore.deleteAllCookies() - -# 用简短代码来表达就是 -cookieStore = self.webview.page().profile().cookieStore() -cookieStore.deleteAllCookies() -``` - -## 异常调试 - -可能有时候由于粗心,或者调用了一些非法函数,参数错误等会导致程序出现一些异常,首先第一步复制最后一行的错误去百度或者谷歌搜索,大多时候能找到问题所在。其次如果搜索不到或者自己的异常可能是由于某个变量的值不对引起的,就需要在编辑器中打断点使用DEBUG模式调试变量值(如果不会可以采用麻烦一点的办法:用`print`打印出变量值) - -遇到问题后首先需要自己多调试排查问题,不要一遇到问题就去问,自己多尝试一个一个排查直到找到问题所在并解决,这也是一种提高自身能力的地方。 - -## 检索资料 - -作为一个开发人员确实需要具备查阅文档、查询资料等基础技能,会为自己的开发带来很大的帮助,要善于搜索,通过不同的方式去搜索才能找到自己需要的东西。信息检索是每个程序猿必备的能力之一,其好处在于可以更快更准确的在茫茫网络海洋中找到自己所需要的东西,这个过程需要长期不断积累和练习。 - -1. 中文搜索引擎:采用多个关键词 以空格分开搜索,如:PyQt 拖拽 -2. 英文搜索引擎:采用多个关键词 以空格分开搜索,如:PyQt Drag Drop - -## 片尾 - -好了,笔者基本上的学习过程就整理如上,这并不是说每个人都适合这样的方法,但至少笔者是这样一步一步走过来的。当你养成了一个学习、发现和解决问题的好习惯时就会慢慢得心应手。 \ No newline at end of file diff --git a/source/_posts/suggesteditor.md b/source/_posts/suggesteditor.md deleted file mode 100644 index bf774005..00000000 --- a/source/_posts/suggesteditor.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -author: Irony -title: 推荐编辑器LiClipse -date: 2019-05-04 18:04:08 -tags: - - 编辑器 -categories: 随笔 ---- - -关于Python的开发编辑器有很多,每个人有每个人的喜好,经常看到很多在问什么编辑器好用,有人推荐Sublime,有人推荐Pycharm等等,这里就不去比较其它编辑器的优缺点了,只谈谈关于LiClipse这个编辑器在初级使用阶段的智能提示功能等。开箱即用,支持多种语言,RST,Markdown和HTML编辑器的HTML预览。 - - -其实LiClipse这个编辑器就是以前的PyDev插件的独立版本,基于Eclipse编辑器开发,去掉了Java的相关开发功能,关于软件的详细说明可以去官网查看: http://www.liclipse.com/ - -编辑器只需要少量的配置,打开即可使用,快速自动import,也可以根据需要安装自己所需的插件,比如json、svn、主题插件等。个人推荐:适合刚入门的新手使用 - -由于新版的PyQt和PyDev去掉了详细的函数提示,所以PyQt的智能提示只有函数和返回值,并没有英文注释,但是以前的比如PyQt4的智能提示应该是有详细的英文注释提示。 - -## 界面预览 - -1. 主界面 -![editor1](/images/editor1.png) -2. 鼠标悬停提示 -![editor2](/images/editor2.png) -3. 输入提示 -![editor3](/images/editor3.png) -4. Git面板 -![editor4](/images/editor4.png) -5. 全局搜索(Ctrl + H) -![editor5](/images/editor5.png) -![editor6](/images/editor6.png) - -## 自动导包 - -其实这个功能我是非常喜欢的,通过按下快捷键即可自动寻找包名导入,快捷键 Ctrl + Shift + O - -![editor_import](/images/editor_import.png) - -也可以在标红的代码上按下 Ctrl + F1进行导入 - -![editor_import2](/images/editor_import2.png) - -## 配置 - -打开编辑器后首先要配置【Window -> Preferences】的就是Python的环境变量,可以同时添加多个Python版本 - -![editor_env](/images/editor_env.png) - -## Tab等设置 - -1. Insert spaces for tabs tab转空格 -2. Show line numbers 显示行号 - -![editor_tab](/images/editor_tab.png) - -## 模版 - -这个功能可以快速插入自己定义好的模版代码,比如 `if __name__ == '__main__':`等等,比如我这里配置的创建文件的模版 - -![editor_tpl](/images/editor_tpl.png) - -## 常用快捷键 - -| | | -|:----------:|:----------------:| -| 格式化对齐 | Ctrl + Shift + F | -| 自动导包 | Ctrl + Shift + O | -| 快捷提示 | Alt + / | \ No newline at end of file diff --git a/source/_posts/use_pyuic_insteadof_pyside2uic.md b/source/_posts/use_pyuic_insteadof_pyside2uic.md deleted file mode 100644 index dd248c74..00000000 --- a/source/_posts/use_pyuic_insteadof_pyside2uic.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -author: 人间白头  -title: 修改pyuic代替pyside2-uic. -date: 2019-12-26 19:49:41 -tags: - - PyQt5 PySide2 - -categories: 随笔 ---- - -修改pyuic代替pyside2-uic - - -修改pyuic代替pyside2-uic. - -最近看到挺多人用pyside2的uic编译ui文件有问题 . -写个解决办法. - -首先 , -`pip install qtpy` , -这个是兼容pyqt5和pyside2的 , 无缝转换 . - -然后 , -修改 pyqt5 的 uic , - -![image.png](https://upload-images.jianshu.io/upload_images/10769157-2ed1053f322c26a6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) - -最后用pyuic5 , 生成Ui_XXX.py文件 . diff --git a/source/_posts/viewapi.md b/source/_posts/viewapi.md deleted file mode 100644 index 37d7ce11..00000000 --- a/source/_posts/viewapi.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -author: Irony -title: 如何查阅Qt文档 -date: 2019-05-04 20:50:20 -tags: - - PyQt -categories: 笔记 ---- - -很多网友在问有没有PyQt5的文档之类的问题,在PyQt4的时候PyQt官网有了英文版的文档,随后有网友翻译成了中文。不过现在PyQt5官方的文档都指向了C++的Qt文档,其实C++的Qt API文档结构很清晰,翻阅很容易的,需要注意几点。 - - -作为一个开发人员确实需要具备查阅文档、查询资料等基础技能,会为自己的开发带来很大的帮助,要善于搜索,通过不同的方式去搜索才能找到自己需要的东西。 - -拿Qt C++文档来说,官网地址是:https://doc.qt.io/qt-5/qtwidgets-module.html 这里面记录了所有控件的详细函数文档。 - -比如拿 输入框 `QLineEdit` 来说,怎么去查询它的用法和信号槽等资料? - -https://doc.qt.io/qt-5/qlineedit.html - -## 左侧目录 - -在文档左侧目录中有如下几个: - -Properties - 控件里的属性(比如宽高等,通常需要当作函数调用) - -Public Slots - 这个是控件自己的槽函数(当作普通函数就行) - -Signals - 这个是输入框的包含的信号 - -Public Functions、Reimplemented Public Functions、Static Public Members、Protected Functions、Reimplemented Protected Functions - 这几个都是函数列表 - -![howtoviewapi1](/images/howtoviewapi1.png) - -## 类说明 - -![howtoviewapi2](/images/howtoviewapi2.png) - -这里有两个注意点 - -1. 红色方框内的表示该控件(输入框)继承于`QWidget`,所以该控件(输入框)拥有父类的所有方法和信号,当当前文档找不到相关资料和函数时,可以去父类找找看。 -2. 紫色方框内表示列举所有的方法(包括父类) - -## 函数列表 - -![howtoviewapi3](/images/howtoviewapi3.png) - -这里列举的就是该控件(输入框)的函数,同理点击上面的紫色方框是查看所有方法,一般这里主要用来查询你需要的功能函数,Qt的函数名比较容易理解,比如:只读ReadOnly,选择文字:setSelection。 - -所以再查下这部分资料的时候建议在浏览器中Ctrl + F打开浏览器的搜索框,并输入英文关键词来检索你所需要的函数在哪里。 - -![howtoviewapi8](/images/howtoviewapi8.png) - -## 槽函数 - -![howtoviewapi4](/images/howtoviewapi4.png) - -这部分列举的是槽函数,其实在PyQt中槽函数可以当作普通的函数。普通的函数也可以作为槽函数,直接通过信号连接即可,注意方框所示,还有很多函数是在父类里面。 - -## 信号 - -![howtoviewapi5](/images/howtoviewapi5.png) - -这部分列举了该控件(输入框)所定义的信号,主要还是看名字,大多都能知道是做什么的,比如: - -1. editingFinished - 编辑完成信号 -2. returnPressed - 回车键信号 -3. textChanged(const QString &text) - 内容改变信号 - -这里还有个问题就是参数问题,一般&后面的text作为参数传递到槽函数中 - -## 函数详细说明 - -当不明确这个函数是做什么的,可以点击该函数跳转到下面的说明,比如回车键信号`returnPressed` - -![howtoviewapi6](/images/howtoviewapi6.png) - -如图上所示,用翻译插件翻译,大部分就明白了,如下: - -![howtoviewapi7](/images/howtoviewapi7.png) - -## 关于如何搜索资料 - -比如当你要搜索输入框内容改变事件,一般建议两种搜索,且搜索的时候用空格把关键词分开搜索,而且直接用控件名 - -1. 中文搜索引擎:QLineEdit 内容 改变 -2. 英文搜索引擎:QLineEdit text change diff --git a/source/_posts/viewpyindesigner_625781186.md b/source/_posts/viewpyindesigner_625781186.md deleted file mode 100644 index 4333210a..00000000 --- a/source/_posts/viewpyindesigner_625781186.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -author: 不许人间见白头 -title: 如何和设计师中查看ui转换的py代码 -date: 2019-04-30 13:11:09 -tags: - - PyQt - - Designer - - 设计师 -categories: 教程 ---- - -通过 设计师  查看ui转换的py代码 - -当初我刚学pyqt的时候 , 也有很多疑惑 , 用什么属性把控件加到布局 , 改了这个属性会发生什么 , 为什么这个会这样, 那个会那样 。。。 。。。 - -后来就看ui 转成的py代码 , 注释一下 , 什么效果消失了 , 就是那个api引起的 。 - - -再来后发现了官方文档 , 查一查函数就行了 . - -但是有些api文档找起来麻烦 , 用设计师点几下就行了 , 然后把转换出来的代码拷贝一下就完事了. - -可是需要单独把ui转为py文件 , 之后再删除这个文件也是很烦的一件事 . - -好 , 话不多说 , 接下来手把手教你如何快速在ui中查看py代码 . - -官方也考虑过这种情况 , 所以 设计师中 是有这个功能的 , 但是qt的是没问题的 , pyqt的毕竟是绑定过来的 , 所以正常来说 你点击之后会弹出一个找不到应用程序的提示 . - -看到这个东西是不是很眼熟 , 我们用的命令pyuic5 和这个东西应该是一样的 . - -![viewpyindesigner1](/images/viewpyindesigner1.jpg) - -所以接下来 , 我们找找电脑上有没有这个东西 - -![viewpyindesigner2](/images/viewpyindesigner2.jpg) - -果然在pyqt5-toos文件夹下有这个东西 , - -我们根据第一张图的提示 , 把这个东西拷贝到相应的目录 (如果没有那个bin文件夹, 手动创建), - -![viewpyindesigner3](/images/viewpyindesigner3.jpg) - -好了 , 大功告成 ! diff --git a/source/_posts/virtualenvpy_625781186.md b/source/_posts/virtualenvpy_625781186.md deleted file mode 100644 index a5d4bb8d..00000000 --- a/source/_posts/virtualenvpy_625781186.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -author: 人间白头  -title: python 拷贝虚拟环境(一)   -date: 2019-05-02 15:21:01 -tags: - - Python - - virtualenvwrapper - - virtualenv -categories: 随笔 ---- - -通常来说 , 刚开始使用python的时候都是把包装到全局路径 , 随着各个项目安装的包越来越多 , 之后每开始一个项目 , pycharm创建索引的时间都越来越漫长 , 所以不可避免得开始使用虚拟环境。 -经过一番了解 ,虚拟环境的优点有这些: -- 改善 pycharm 索引时间; -- 各个项目的库不会冲突; -- 理论上虚拟环境可以给同版本的操作系统使用(未试验过); -- pip freeze > requestment.txt 导出的依赖清晰; -- 各个版本的python共存; -- ... - - -python虚拟环境库除了自带的venv , 还有三方库`virtualenv` , 此外 在`virtualenv`基础上又开发了`virtualenvwrapper(virtualenvwrapper_win)` 来管理 - -本文基于`virtualenvwrapper` 创建的虚拟环境来讲解. - - 以下是收集的一些virtualenvwrapper配置教程: - # linux平台 - https://www.cnblogs.com/netfoxman/p/5994697.html - # window平台 - https://blog.csdn.net/shaququ/article/details/54292043   - https://blog.csdn.net/iaau0908/article/details/54021518 -虚拟环境创建多了我们就会发现 , -有时候使用相同版本的环境,一些常用的库是需要重新安装的, -那么能不能创建一个基础环境, 默认拥有这些库, 然后在这个基础环境上继续安装三方库呢 ? - -本文经过试验发现是可行的: - -1. 创建基础虚拟环境 `mkvirtualenv <环境名称> [-p空格python其他版本的解释器路径]`. 例如 `mkvirtualenv py34 -p c:\Python34\python.exe` - -2. 切换到虚拟环境`workon py34` , 然后安装一下三方库, 然后复制`py34`这个文件夹备份一下 ; -3. 接着复制这个`py34`文件夹, 把复制后的文件夹改名为我们需要需要的文件夹例如`new34` -4. 进入`new34文件夹`, 用任意编辑器全路径搜索`py34`(替换虚拟环境的路径) -5. 删除`new34/Scripts`下的`pip.exe, pip3.exe, pip3.x.exe, easy_install.exe`(因为安装路径硬编码到这里面了, 改不了, 需要重新安装) -6. https://blog.csdn.net/douniwan007009/article/details/81463958 按方式二 , 源码安装 `setuptools` 后再用`easy_install pip` 安装pip后 , 完成 ; - 如果有问题, 就继续按照方式一的源码安装pip; -7. 在`new34`环境下 用`pip show 三方库` 来看一些库的位置, 确保正确. - - diff --git a/source/_posts/webviewnew.md b/source/_posts/webviewnew.md deleted file mode 100644 index 56badce2..00000000 --- a/source/_posts/webviewnew.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -author: Irony -title: PyQt5编译QWebView与QWebEngineView共存 -date: 2019-01-12 19:28:06 -tags: - - PyQt - - QWebView - - 浏览器 -categories: 教程 ---- - -在PyQt5.5过后移除了`QWebView`控件,改用`QWebEngineView`,但是这个刚开始用起来不是很方便,最近在整理一些例子的时候需要同时使用`QWebView`和`QWebEngineView`,故希望把`QWebView`重新加入到后面的PyQt5版本中,查看PyQt5.10.1的源码发现里面其实是有`QWebView`的,只是因为Qt5.10.1中没有编译好的dll等导致无法编译。 - - -## 准备工作 - -1. 安装VS2015 -2. 安装Qt5.10.1 -3. 前往 https://github.com/annulen/webkit/releases 下载对应的文件,比如:qtwebkit-5.212.0_alpha2-qt59-msvc2015-x86.zip -4. 下载PyQt5.10.1源码 -5. 下载对应版本的sip源码 - -## 编译 - -1. 设置环境变量`set PATH=D:\soft\Qt\Qt5.10.1\5.10.1\msvc2015\bin;%PATH%` -2. 首先进入vs2015命令行编译sip并安装,`python configure.py && nmake && nmake install` -3. 进入PyQt5.10.1源码编译安装即可 -4. 如果要减少PyQt5.10.1的编译可以试试以下代码 - -``` -D:\soft\Python35\python configure.py --confirm-license --no-designer-plugin --no-qml-plugin --disable=dbus --disable=QAxContainer --disable=QtAndroidExtras --disable=QtBluetooth --disable=QtDBus --disable=QtDesigner --disable=Enginio --disable=QtLocation --disable=QtMacExtras --disable=QtMultimedia --disable=QtMultimediaWidgets --disable=QtNfc --disable=QtSerialPort --disable=QtSql --disable=QtSvg --disable=QtTest --disable=QtWinExtras --disable=QtX11Extras --disable=QtXml --disable=QtXmlPatterns --disable=pylupdate --disable=pyrcc -``` \ No newline at end of file diff --git a/source/about/index.md b/source/about/index.md deleted file mode 100644 index 98a40b75..00000000 --- a/source/about/index.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: 关于社区 -layout: about -comments: false -date: 2019-04-30 11:38:36 -share: false -type: "about" ---- - -## 为什么要搭建这个社区 - -也许是因为喜爱PyQt,喜欢用它做很多东西吧,也想为大家提供更多关于PyQt的帮助。 - -内容主要是 记录 一些开发日志,分享些 我认为有趣的东西,还有 各种教程、例子 等等。 - -还有就是收集和整理记录下网友们平时遇到的问题,提出的需求等等,方便其他人搜索。 - -如需帮助可以前往 [issues](https://github.com/PyQt5/PyQt/issues/new) 留下您的问题 - -如需发表文章可以前往 [这里](https://github.com/PyQt5/blog/tree/dev/source/_posts) 发表新文章, 同时需要查看 [发文要求](https://github.com/PyQt5/blog/blob/dev/README.md) - -## 投稿 - -欢迎投稿: [https://github.com/PyQt5/blog/blob/dev/README.md](https://github.com/PyQt5/blog/blob/dev/README.md) - -## 关于我? - -信息很少... - -## 联系我们? - -[点击链接加入群聊【PyQt5 学习】:https://jq.qq.com/?_wv=1027&k=5Y29SHz](https://jq.qq.com/?_wv=1027&k=5Y29SHz) - -## 捐助支持 - -![微信](/images/weixin.png) or ![支付宝](/images/zhifubao.png) \ No newline at end of file diff --git a/source/ads.txt b/source/ads.txt deleted file mode 100644 index 238a07ab..00000000 --- a/source/ads.txt +++ /dev/null @@ -1 +0,0 @@ -google.com, pub-7185628244213160, DIRECT, f08c47fec0942fa0 \ No newline at end of file diff --git a/source/categories/index.md b/source/categories/index.md deleted file mode 100644 index 9aa154d8..00000000 --- a/source/categories/index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: 分类 -comments: false -share: false -aside: false -top_img: false -type: "categories" -date: 2023-10-08 00:00:13 ---- diff --git a/source/faq/index.md b/source/faq/index.md deleted file mode 100644 index 3623022b..00000000 --- a/source/faq/index.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: 常见问题 -date: 2019-06-20 10:58:20 -share: false -type: "faq" ---- - -# 常见问题整理 - -这里会收集和整理各种常见问题,包括但不限于编辑器问题、编译打包问题、常见犯错。希望大家可以共同来完善此文档,编辑地址:[https://github.com/PyQt5/blog/blob/dev/source/faq/index.md](https://github.com/PyQt5/blog/blob/dev/source/faq/index.md) - -## 案例库和提问 - -有专门的项目收集例子、提交例子、和回答问题,同时也建议大家都在上面多多提问和提交例子,这样可以留下记录方便遇到同样问题的人快速找到答案。 - -项目地址:[https://github.com/PyQt5/PyQt/issues](https://github.com/PyQt5/PyQt/issues) - -如果你想写一写文章来帮助其他人少走弯路,也可以到 [https://github.com/PyQt5/blog/tree/dev](https://github.com/PyQt5/blog/tree/dev) 去提交博客文章,访问地址是:[https://pyqt5.com](https://pyqt5.com) - -## 文档查阅 - - - Qt 官方文档 [http://doc.qt.io/qt-5/classes.html](http://doc.qt.io/qt-5/classes.html) - - PySide2 文档 [https://doc.qt.io/qtforpython/index.html](https://doc.qt.io/qtforpython/index.html) - - 如何查阅Qt文档 [https://pyqt5.com/viewapi.html](https://pyqt5.com/viewapi.html) - -## 界面美化 - - - Qt 官网样式参考 [https://doc.qt.io/qt-5/stylesheet-examples.html](https://doc.qt.io/qt-5/stylesheet-examples.html) - - QSS语法参考 [https://www.cnblogs.com/wangqiguo/p/4960776.html](https://www.cnblogs.com/wangqiguo/p/4960776.html) - - CSS语法参考 [http://www.w3school.com.cn/css/index.asp](http://www.w3school.com.cn/css/index.asp) - - 使用字体图标 [https://github.com/PyQt5/PyQt/tree/master/QFont](https://github.com/PyQt5/PyQt/tree/master/QFont) - - 阿里云字体图标 [http://iconfont.cn/](http://iconfont.cn/) - - ## Pyinstaller - -1. 如果安装anaconda, 请别用这个环境的python -2. 设置pyqt5的环境变量 -3. 如果在pycharm中把文件夹设置为了根路径 , 请在终端(cmd)中 使用命令 python xxx.py 运行脚本来确认 模块导入无错误后在打包 -4. 这点很重要!! 如果需要打包成单文件, 先别用-w 命令, 最后打包无错误后再加上-w -5. 如果打包后的窗体一闪而过, 请在cmd中运行你的exe文件 - -错误处理: - -6. module PyQt5.sip not found: 确保在cmd模式下可以import这个模块后, 再在程序中手动import PyQt5.sip , 然后再打包尝试运行 -7. Failed to load platform plugin “windows”...: 百度有解决方法 , 拷贝 python目录下的\\PyQt5\\Qt\\plugins\\platforms到exe目录 -8. QPixmap处理/样式 问题 都是同5.一样都是dll丢失 , 到目录下找对应的文件件拷贝到exe目录 -9. --add-data 打包非python模块文件 , 可能出现的问题及办法: [https://github.com/pyinstaller/pyinstaller/issues/3749](https://github.com/pyinstaller/pyinstaller/issues/3749) - - 还是失败的话检查 电脑用户名是否是中文, 如果是中文 - - 对那个路径名进行编码 - - 则改变spec中 exe= EXE(.....)里的runtime_tmpdir指定为英文路径 -10. 如果需要打包成单文件 , 先别用-w 命令, 最后打包无错误后再加上-w - -## Pycharm - -1. PyQt5环境配置 [https://blog.csdn.net/px41834/article/details/79383985](https://blog.csdn.net/px41834/article/details/79383985) -2. 调试PyQt没有错误信息提示,原因以及解决办法: [https://www.jianshu.com/p/47b6e7ce4639](https://www.jianshu.com/p/47b6e7ce4639) -3. 不识别PyQt5模块: - - 新建的项目使用了新建的虚拟环境的python.exe解释器,更换已经安装过pyqt5的解释器再更新索引即可,设置python解释器路径在pycharm的菜单File->Settings->Project:->Project Interpreter - - 在尝试网上搜索的办法都没解决的情况下 ,一般就是pycharm的配置出问题了,找到C:\\Users\\XXX\\.PyCharm2018.1 路径, 删除之后重启pycharm ,重新配置 - -## Eric6 - -1. 环境配置 请参考 第一讲 [https://space.bilibili.com/1863103/#/](https://space.bilibili.com/1863103/#/) -2. 汉化:eric6汉化包只到17.12版本,但是可以兼容高版本,自行百度或群文件下载 -3. 双击无法打开设计师//pyuic5|pyrcc5无法编译ui|qrc文件 - - 检查是否安装pyqt-tools或者PyQt5Designer - - 检查是否加入环境变量 - - eric6 菜单栏 设置(settings) - 首选项(preference) - Qt - - Qt -> Tools -> Tools Directory: 配置designer.exe路径 - - PyQt -> Tools -> Tools Directory: 配置pyuic5.exe/pyrcc5.exe路径 - - !! 检查qrc路径中是否含有中文 !! 如果有则重命名 - -## 设计师 - -1. 通过pip install pyqt5-tools 或者 pip install PyQt5Designer 安装 -2. PyQt5Designer自带汉化包,执行在site-packages\PyQt5\Qt\bin\designer.exe - -## Matplotlib - -1. PyQt5 结合 matplotlib 时,如何显示其 NavigationToolbar:[http://www.cnblogs.com/hhh5460/p/5189843.html](http://www.cnblogs.com/hhh5460/p/5189843.html) -2. matplotlib绑定到PyQt5:[http://www.cnblogs.com/hhh5460/p/4322652.html](http://www.cnblogs.com/hhh5460/p/4322652.html) \ No newline at end of file diff --git a/source/favicon.ico b/source/favicon.ico deleted file mode 100644 index d8fe8007..00000000 Binary files a/source/favicon.ico and /dev/null differ diff --git "a/source/files/\346\227\240\350\276\271\346\241\206\345\234\206\350\247\222\351\230\264\345\275\261.zip" "b/source/files/\346\227\240\350\276\271\346\241\206\345\234\206\350\247\222\351\230\264\345\275\261.zip" deleted file mode 100644 index 3479e1cc..00000000 Binary files "a/source/files/\346\227\240\350\276\271\346\241\206\345\234\206\350\247\222\351\230\264\345\275\261.zip" and /dev/null differ diff --git "a/source/files/\350\260\203\347\224\250java\347\224\237\346\210\220\346\212\245\350\241\250.7z" "b/source/files/\350\260\203\347\224\250java\347\224\237\346\210\220\346\212\245\350\241\250.7z" deleted file mode 100644 index a69a05e2..00000000 Binary files "a/source/files/\350\260\203\347\224\250java\347\224\237\346\210\220\346\212\245\350\241\250.7z" and /dev/null differ diff --git a/source/guestbook/index.md b/source/guestbook/index.md deleted file mode 100644 index 1793a01a..00000000 --- a/source/guestbook/index.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: 留言板 -date: 2019-04-30 17:38:29 -share: false -type: "guestbook" ---- - -
\ No newline at end of file diff --git a/source/images/1.gif b/source/images/1.gif deleted file mode 100644 index 533a270a..00000000 Binary files a/source/images/1.gif and /dev/null differ diff --git a/source/images/1240_thumb.jpg b/source/images/1240_thumb.jpg deleted file mode 100644 index eed791ab..00000000 Binary files a/source/images/1240_thumb.jpg and /dev/null differ diff --git a/source/images/1_thumb.jpg b/source/images/1_thumb.jpg deleted file mode 100644 index 4b306ef3..00000000 Binary files a/source/images/1_thumb.jpg and /dev/null differ diff --git a/source/images/2.gif b/source/images/2.gif deleted file mode 100644 index c87482c0..00000000 Binary files a/source/images/2.gif and /dev/null differ diff --git a/source/images/5ce793171984f27031_thumb.jpg b/source/images/5ce793171984f27031_thumb.jpg deleted file mode 100644 index a99e3b20..00000000 Binary files a/source/images/5ce793171984f27031_thumb.jpg and /dev/null differ diff --git a/source/images/ClickJumpSlider_thumb.jpg b/source/images/ClickJumpSlider_thumb.jpg deleted file mode 100644 index f39e6631..00000000 Binary files a/source/images/ClickJumpSlider_thumb.jpg and /dev/null differ diff --git a/source/images/FlipWidgetAnimation_thumb.jpg b/source/images/FlipWidgetAnimation_thumb.jpg deleted file mode 100644 index e41b1eec..00000000 Binary files a/source/images/FlipWidgetAnimation_thumb.jpg and /dev/null differ diff --git a/source/images/FollowWindow_thumb.jpg b/source/images/FollowWindow_thumb.jpg deleted file mode 100644 index cf1c1146..00000000 Binary files a/source/images/FollowWindow_thumb.jpg and /dev/null differ diff --git a/source/images/FramelessDialog1_thumb.jpg b/source/images/FramelessDialog1_thumb.jpg deleted file mode 100644 index b73ac7bb..00000000 Binary files a/source/images/FramelessDialog1_thumb.jpg and /dev/null differ diff --git a/source/images/ImageSlipped_thumb.jpg b/source/images/ImageSlipped_thumb.jpg deleted file mode 100644 index ae1c9545..00000000 Binary files a/source/images/ImageSlipped_thumb.jpg and /dev/null differ diff --git a/source/images/IsSignalConnected_thumb.jpg b/source/images/IsSignalConnected_thumb.jpg deleted file mode 100644 index 906b8886..00000000 Binary files a/source/images/IsSignalConnected_thumb.jpg and /dev/null differ diff --git a/source/images/JsSignals_thumb.jpg b/source/images/JsSignals_thumb.jpg deleted file mode 100644 index 216f798c..00000000 Binary files a/source/images/JsSignals_thumb.jpg and /dev/null differ diff --git a/source/images/MultiSelect_thumb.jpg b/source/images/MultiSelect_thumb.jpg deleted file mode 100644 index 73d9724a..00000000 Binary files a/source/images/MultiSelect_thumb.jpg and /dev/null differ diff --git a/source/images/NinePatchImage_thumb.jpg b/source/images/NinePatchImage_thumb.jpg deleted file mode 100644 index ce457222..00000000 Binary files a/source/images/NinePatchImage_thumb.jpg and /dev/null differ diff --git a/source/images/PageSwitching_thumb.jpg b/source/images/PageSwitching_thumb.jpg deleted file mode 100644 index d8c8f3bc..00000000 Binary files a/source/images/PageSwitching_thumb.jpg and /dev/null differ diff --git a/source/images/PyQt_Group.png b/source/images/PyQt_Group.png deleted file mode 100644 index 4be38ded..00000000 Binary files a/source/images/PyQt_Group.png and /dev/null differ diff --git a/source/images/PyQt_Guild.png b/source/images/PyQt_Guild.png deleted file mode 100644 index 68ffa8e6..00000000 Binary files a/source/images/PyQt_Guild.png and /dev/null differ diff --git a/source/images/QPropertyAnimation.gif b/source/images/QPropertyAnimation.gif deleted file mode 100644 index 93bfc8c0..00000000 Binary files a/source/images/QPropertyAnimation.gif and /dev/null differ diff --git a/source/images/QPropertyAnimation_thumb.jpg b/source/images/QPropertyAnimation_thumb.jpg deleted file mode 100644 index 1287a39e..00000000 Binary files a/source/images/QPropertyAnimation_thumb.jpg and /dev/null differ diff --git a/source/images/RlatticeEffect_thumb.jpg b/source/images/RlatticeEffect_thumb.jpg deleted file mode 100644 index 086e78d9..00000000 Binary files a/source/images/RlatticeEffect_thumb.jpg and /dev/null differ diff --git a/source/images/ShadowEffect_thumb.jpg b/source/images/ShadowEffect_thumb.jpg deleted file mode 100644 index ce0fd1b3..00000000 Binary files a/source/images/ShadowEffect_thumb.jpg and /dev/null differ diff --git a/source/images/ShowFrameWhenDrag_thumb.jpg b/source/images/ShowFrameWhenDrag_thumb.jpg deleted file mode 100644 index c6cd4e48..00000000 Binary files a/source/images/ShowFrameWhenDrag_thumb.jpg and /dev/null differ diff --git a/source/images/avatar.png b/source/images/avatar.png deleted file mode 100644 index b4a38f9f..00000000 Binary files a/source/images/avatar.png and /dev/null differ diff --git a/source/images/bg-2.jpg b/source/images/bg-2.jpg deleted file mode 100644 index 0fe5cf55..00000000 Binary files a/source/images/bg-2.jpg and /dev/null differ diff --git a/source/images/calljava.png b/source/images/calljava.png deleted file mode 100644 index 3fa4964f..00000000 Binary files a/source/images/calljava.png and /dev/null differ diff --git a/source/images/calljava_thumb.jpg b/source/images/calljava_thumb.jpg deleted file mode 100644 index f8f5e68a..00000000 Binary files a/source/images/calljava_thumb.jpg and /dev/null differ diff --git a/source/images/circleimage1.png b/source/images/circleimage1.png deleted file mode 100644 index 47e5da4f..00000000 Binary files a/source/images/circleimage1.png and /dev/null differ diff --git a/source/images/circleimage1_thumb.jpg b/source/images/circleimage1_thumb.jpg deleted file mode 100644 index 9039c7ee..00000000 Binary files a/source/images/circleimage1_thumb.jpg and /dev/null differ diff --git a/source/images/circleimage2.png b/source/images/circleimage2.png deleted file mode 100644 index 818d1823..00000000 Binary files a/source/images/circleimage2.png and /dev/null differ diff --git a/source/images/datawidgetmapper.gif b/source/images/datawidgetmapper.gif deleted file mode 100644 index efc857b7..00000000 Binary files a/source/images/datawidgetmapper.gif and /dev/null differ diff --git a/source/images/datawidgetmapper_thumb.jpg b/source/images/datawidgetmapper_thumb.jpg deleted file mode 100644 index 3741f3a9..00000000 Binary files a/source/images/datawidgetmapper_thumb.jpg and /dev/null differ diff --git a/source/images/default_thumb.jpg b/source/images/default_thumb.jpg deleted file mode 100644 index 42e8c024..00000000 Binary files a/source/images/default_thumb.jpg and /dev/null differ diff --git a/source/images/desiger_create_thumb.jpg b/source/images/desiger_create_thumb.jpg deleted file mode 100644 index 0965b29f..00000000 Binary files a/source/images/desiger_create_thumb.jpg and /dev/null differ diff --git a/source/images/editor1.png b/source/images/editor1.png deleted file mode 100644 index 19fc1dfb..00000000 Binary files a/source/images/editor1.png and /dev/null differ diff --git a/source/images/editor1_thumb.jpg b/source/images/editor1_thumb.jpg deleted file mode 100644 index 54fc4c1c..00000000 Binary files a/source/images/editor1_thumb.jpg and /dev/null differ diff --git a/source/images/editor2.png b/source/images/editor2.png deleted file mode 100644 index 1692d04f..00000000 Binary files a/source/images/editor2.png and /dev/null differ diff --git a/source/images/editor3.png b/source/images/editor3.png deleted file mode 100644 index 507ee209..00000000 Binary files a/source/images/editor3.png and /dev/null differ diff --git a/source/images/editor4.png b/source/images/editor4.png deleted file mode 100644 index 7cdb6d5b..00000000 Binary files a/source/images/editor4.png and /dev/null differ diff --git a/source/images/editor5.png b/source/images/editor5.png deleted file mode 100644 index 8f881915..00000000 Binary files a/source/images/editor5.png and /dev/null differ diff --git a/source/images/editor6.png b/source/images/editor6.png deleted file mode 100644 index d9c441f1..00000000 Binary files a/source/images/editor6.png and /dev/null differ diff --git a/source/images/editor_env.png b/source/images/editor_env.png deleted file mode 100644 index d90626cb..00000000 Binary files a/source/images/editor_env.png and /dev/null differ diff --git a/source/images/editor_import.png b/source/images/editor_import.png deleted file mode 100644 index bb092004..00000000 Binary files a/source/images/editor_import.png and /dev/null differ diff --git a/source/images/editor_import2.png b/source/images/editor_import2.png deleted file mode 100644 index 742a9f10..00000000 Binary files a/source/images/editor_import2.png and /dev/null differ diff --git a/source/images/editor_tab.png b/source/images/editor_tab.png deleted file mode 100644 index 2aab28fb..00000000 Binary files a/source/images/editor_tab.png and /dev/null differ diff --git a/source/images/editor_tpl.png b/source/images/editor_tpl.png deleted file mode 100644 index e4734d6b..00000000 Binary files a/source/images/editor_tpl.png and /dev/null differ diff --git a/source/images/howtoviewapi1.png b/source/images/howtoviewapi1.png deleted file mode 100644 index fc75d30c..00000000 Binary files a/source/images/howtoviewapi1.png and /dev/null differ diff --git a/source/images/howtoviewapi1_thumb.jpg b/source/images/howtoviewapi1_thumb.jpg deleted file mode 100644 index fea981f1..00000000 Binary files a/source/images/howtoviewapi1_thumb.jpg and /dev/null differ diff --git a/source/images/howtoviewapi2.png b/source/images/howtoviewapi2.png deleted file mode 100644 index cd48ab2e..00000000 Binary files a/source/images/howtoviewapi2.png and /dev/null differ diff --git a/source/images/howtoviewapi3.png b/source/images/howtoviewapi3.png deleted file mode 100644 index de87d70a..00000000 Binary files a/source/images/howtoviewapi3.png and /dev/null differ diff --git a/source/images/howtoviewapi4.png b/source/images/howtoviewapi4.png deleted file mode 100644 index 05884fe0..00000000 Binary files a/source/images/howtoviewapi4.png and /dev/null differ diff --git a/source/images/howtoviewapi5.png b/source/images/howtoviewapi5.png deleted file mode 100644 index 158ee707..00000000 Binary files a/source/images/howtoviewapi5.png and /dev/null differ diff --git a/source/images/howtoviewapi6.png b/source/images/howtoviewapi6.png deleted file mode 100644 index 29ea1b9d..00000000 Binary files a/source/images/howtoviewapi6.png and /dev/null differ diff --git a/source/images/howtoviewapi7.png b/source/images/howtoviewapi7.png deleted file mode 100644 index db4ac5cb..00000000 Binary files a/source/images/howtoviewapi7.png and /dev/null differ diff --git a/source/images/howtoviewapi8.png b/source/images/howtoviewapi8.png deleted file mode 100644 index a0067544..00000000 Binary files a/source/images/howtoviewapi8.png and /dev/null differ diff --git a/source/images/macpyqtstep1.png b/source/images/macpyqtstep1.png deleted file mode 100644 index f84aea83..00000000 Binary files a/source/images/macpyqtstep1.png and /dev/null differ diff --git a/source/images/macpyqtstep2.png b/source/images/macpyqtstep2.png deleted file mode 100644 index 17817a63..00000000 Binary files a/source/images/macpyqtstep2.png and /dev/null differ diff --git a/source/images/macpyqtstep3.png b/source/images/macpyqtstep3.png deleted file mode 100644 index 6971e9d4..00000000 Binary files a/source/images/macpyqtstep3.png and /dev/null differ diff --git a/source/images/material-10_thumb.jpg b/source/images/material-10_thumb.jpg deleted file mode 100644 index 468f86f0..00000000 Binary files a/source/images/material-10_thumb.jpg and /dev/null differ diff --git a/source/images/material-1_thumb.jpg b/source/images/material-1_thumb.jpg deleted file mode 100644 index 1252366e..00000000 Binary files a/source/images/material-1_thumb.jpg and /dev/null differ diff --git a/source/images/material-2_thumb.jpg b/source/images/material-2_thumb.jpg deleted file mode 100644 index f121ba13..00000000 Binary files a/source/images/material-2_thumb.jpg and /dev/null differ diff --git a/source/images/material-3_thumb.jpg b/source/images/material-3_thumb.jpg deleted file mode 100644 index 4ee5c708..00000000 Binary files a/source/images/material-3_thumb.jpg and /dev/null differ diff --git a/source/images/material-4_thumb.jpg b/source/images/material-4_thumb.jpg deleted file mode 100644 index 07cfe56b..00000000 Binary files a/source/images/material-4_thumb.jpg and /dev/null differ diff --git a/source/images/material-5_thumb.jpg b/source/images/material-5_thumb.jpg deleted file mode 100644 index a1fccf78..00000000 Binary files a/source/images/material-5_thumb.jpg and /dev/null differ diff --git a/source/images/material-6_thumb.jpg b/source/images/material-6_thumb.jpg deleted file mode 100644 index 2047a710..00000000 Binary files a/source/images/material-6_thumb.jpg and /dev/null differ diff --git a/source/images/material-7_thumb.jpg b/source/images/material-7_thumb.jpg deleted file mode 100644 index 75ebbb4d..00000000 Binary files a/source/images/material-7_thumb.jpg and /dev/null differ diff --git a/source/images/material-8_thumb.jpg b/source/images/material-8_thumb.jpg deleted file mode 100644 index 694ec2c8..00000000 Binary files a/source/images/material-8_thumb.jpg and /dev/null differ diff --git a/source/images/material-9_thumb.jpg b/source/images/material-9_thumb.jpg deleted file mode 100644 index 38b6f507..00000000 Binary files a/source/images/material-9_thumb.jpg and /dev/null differ diff --git a/source/images/processinclass1.png b/source/images/processinclass1.png deleted file mode 100644 index 35eb24a2..00000000 Binary files a/source/images/processinclass1.png and /dev/null differ diff --git a/source/images/processinclass1_thumb.jpg b/source/images/processinclass1_thumb.jpg deleted file mode 100644 index afca9fdc..00000000 Binary files a/source/images/processinclass1_thumb.jpg and /dev/null differ diff --git a/source/images/processinclass2.png b/source/images/processinclass2.png deleted file mode 100644 index 04a64dd6..00000000 Binary files a/source/images/processinclass2.png and /dev/null differ diff --git a/source/images/pyqt5asyncio.gif b/source/images/pyqt5asyncio.gif deleted file mode 100644 index 48b9c073..00000000 Binary files a/source/images/pyqt5asyncio.gif and /dev/null differ diff --git a/source/images/pyqt5asyncio_thumb.jpg b/source/images/pyqt5asyncio_thumb.jpg deleted file mode 100644 index 57b0e23b..00000000 Binary files a/source/images/pyqt5asyncio_thumb.jpg and /dev/null differ diff --git a/source/images/runnablesignal1.png b/source/images/runnablesignal1.png deleted file mode 100644 index 960725df..00000000 Binary files a/source/images/runnablesignal1.png and /dev/null differ diff --git a/source/images/runnablesignal1_thumb.jpg b/source/images/runnablesignal1_thumb.jpg deleted file mode 100644 index ce09413d..00000000 Binary files a/source/images/runnablesignal1_thumb.jpg and /dev/null differ diff --git a/source/images/runnablesignal2.png b/source/images/runnablesignal2.png deleted file mode 100644 index 1d1562b1..00000000 Binary files a/source/images/runnablesignal2.png and /dev/null differ diff --git a/source/images/runnablesignal3.png b/source/images/runnablesignal3.png deleted file mode 100644 index 62353765..00000000 Binary files a/source/images/runnablesignal3.png and /dev/null differ diff --git a/source/images/studynotes/desiger_create.png b/source/images/studynotes/desiger_create.png deleted file mode 100644 index 365c9463..00000000 Binary files a/source/images/studynotes/desiger_create.png and /dev/null differ diff --git a/source/images/studynotes/desiger_drag.png b/source/images/studynotes/desiger_drag.png deleted file mode 100644 index 1f974f51..00000000 Binary files a/source/images/studynotes/desiger_drag.png and /dev/null differ diff --git a/source/images/studynotes/desiger_layout.png b/source/images/studynotes/desiger_layout.png deleted file mode 100644 index 1f515493..00000000 Binary files a/source/images/studynotes/desiger_layout.png and /dev/null differ diff --git a/source/images/studynotes/desiger_property.png b/source/images/studynotes/desiger_property.png deleted file mode 100644 index ddf785f4..00000000 Binary files a/source/images/studynotes/desiger_property.png and /dev/null differ diff --git a/source/images/studynotes/desiger_property2.png b/source/images/studynotes/desiger_property2.png deleted file mode 100644 index 2e0419eb..00000000 Binary files a/source/images/studynotes/desiger_property2.png and /dev/null differ diff --git a/source/images/studynotes/desiger_signal.png b/source/images/studynotes/desiger_signal.png deleted file mode 100644 index ecc2de04..00000000 Binary files a/source/images/studynotes/desiger_signal.png and /dev/null differ diff --git a/source/images/studynotes/desiger_signal2.png b/source/images/studynotes/desiger_signal2.png deleted file mode 100644 index b1f070ba..00000000 Binary files a/source/images/studynotes/desiger_signal2.png and /dev/null differ diff --git a/source/images/studynotes/desiger_stack.png b/source/images/studynotes/desiger_stack.png deleted file mode 100644 index f72ed907..00000000 Binary files a/source/images/studynotes/desiger_stack.png and /dev/null differ diff --git a/source/images/viewpyindesigner1.jpg b/source/images/viewpyindesigner1.jpg deleted file mode 100644 index e01d53f3..00000000 Binary files a/source/images/viewpyindesigner1.jpg and /dev/null differ diff --git a/source/images/viewpyindesigner1_thumb.jpg b/source/images/viewpyindesigner1_thumb.jpg deleted file mode 100644 index e89dd720..00000000 Binary files a/source/images/viewpyindesigner1_thumb.jpg and /dev/null differ diff --git a/source/images/viewpyindesigner2.jpg b/source/images/viewpyindesigner2.jpg deleted file mode 100644 index 2081303c..00000000 Binary files a/source/images/viewpyindesigner2.jpg and /dev/null differ diff --git a/source/images/viewpyindesigner3.jpg b/source/images/viewpyindesigner3.jpg deleted file mode 100644 index 55d929f2..00000000 Binary files a/source/images/viewpyindesigner3.jpg and /dev/null differ diff --git a/source/images/weixin.png b/source/images/weixin.png deleted file mode 100644 index d8728cb8..00000000 Binary files a/source/images/weixin.png and /dev/null differ diff --git a/source/images/wxblog.jpg b/source/images/wxblog.jpg deleted file mode 100644 index 95fd81a6..00000000 Binary files a/source/images/wxblog.jpg and /dev/null differ diff --git a/source/images/zhifubao.png b/source/images/zhifubao.png deleted file mode 100644 index 1407ae92..00000000 Binary files a/source/images/zhifubao.png and /dev/null differ diff --git a/source/issues/index.md b/source/issues/index.md deleted file mode 100644 index 4b9bf4f3..00000000 --- a/source/issues/index.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: PyQt5讨论 -comments: false -date: 2019-10-20 23:24:25 -share: false -description: PyQt5 Issues 论坛 讨论 -home: true ---- - - - - - - - - -
\ No newline at end of file diff --git a/source/json/music.json b/source/json/music.json deleted file mode 100644 index bc7f9258..00000000 --- a/source/json/music.json +++ /dev/null @@ -1,128 +0,0 @@ -[ - { - "name": "青花瓷", - "artist": "周杰伦", - "url": "https://npm.elemecdn.com/anzhiyu-music@1.0.4/青花瓷/青花瓷.mp3", - "cover": "https://y.qq.com/music/photo_new/T002R300x300M000002eFUFm2XYZ7z_2.jpg?max_age=2592000", - "lrc": "https://npm.elemecdn.com/anzhiyu-music@1.0.4/青花瓷/青花瓷.lrc" - }, - { - "name": "稻香", - "artist": "周杰伦", - "url": "https://npm.elemecdn.com/anzhiyu-music@1.0.1/周杰伦/稻香/稻香.mp3", - "cover": "https://y.qq.com/music/photo_new/T002R300x300M000002Neh8l0uciQZ_1.jpg?max_age=2592000", - "lrc": "https://npm.elemecdn.com/anzhiyu-music@1.0.1/周杰伦/稻香/稻香.lrc" - }, - { - "name": "晴天", - "artist": "周杰伦", - "url": "https://npm.elemecdn.com/anzhiyu-music@1.0.2/晴天/晴天.mp3", - "cover": "https://y.qq.com/music/photo_new/T002R300x300M000000MkMni19ClKG_3.jpg?max_age=2592000", - "lrc": "https://npm.elemecdn.com/anzhiyu-music@1.0.2/晴天/晴天.lrc" - }, - { - "name": "七里香", - "artist": "周杰伦", - "url": "https://npm.elemecdn.com/anzhiyu-music@1.0.2/七里香/七里香.mp3", - "cover": "https://y.qq.com/music/photo_new/T002R300x300M000003DFRzD192KKD_1.jpg?max_age=2592000", - "lrc": "https://npm.elemecdn.com/anzhiyu-music@1.0.2/七里香/七里香.lrc" - }, - { - "name": "花海", - "artist": "周杰伦", - "url": "https://npm.elemecdn.com/anzhiyu-music-jay@1.0.1/花海/花海.flac", - "cover": "https://y.qq.com/music/photo_new/T002R300x300M000002Neh8l0uciQZ_1.jpg?max_age=2592000", - "lrc": "https://npm.elemecdn.com/anzhiyu-music-jay@1.0.1/花海/花海.lrc" - }, - { - "name": "反方向的钟", - "artist": "周杰伦", - "url": "https://npm.elemecdn.com/anzhiyu-music-jay@1.0.1/反方向的钟/反方向的钟.flac", - "cover": "https://y.qq.com/music/photo_new/T002R300x300M000000f01724fd7TH_1.jpg?max_age=2592000", - "lrc": "https://npm.elemecdn.com/anzhiyu-music-jay@1.0.1/反方向的钟/反方向的钟.lrc" - }, - { - "name": "兰亭序", - "artist": "周杰伦", - "url": "https://npm.elemecdn.com/anzhiyu-music@1.0.1/周杰伦/兰亭序/兰亭序.mp3", - "cover": "https://y.qq.com/music/photo_new/T002R300x300M000002Neh8l0uciQZ_1.jpg?max_age=2592000", - "lrc": "https://npm.elemecdn.com/anzhiyu-music@1.0.1/周杰伦/兰亭序/兰亭序.lrc" - }, - { - "name": "说好的辛福呢", - "artist": "周杰伦", - "url": "https://npm.elemecdn.com/anzhiyu-music@1.0.2/说好的辛福呢/说好的辛福呢.mp3", - "cover": "https://y.qq.com/music/photo_new/T002R300x300M000002Neh8l0uciQZ_1.jpg?max_age=2592000", - "lrc": "https://npm.elemecdn.com/anzhiyu-music@1.0.2/说好的辛福呢/说好的幸福呢.lrc" - }, - { - "name": "等你下课 (with 杨瑞代)", - "artist": "周杰伦", - "url": "https://npm.elemecdn.com/anzhiyu-music@1.0.1/周杰伦/等你下课/等你下课.mp3", - "cover": "https://y.qq.com/music/photo_new/T002R300x300M000003bSL0v4bpKAx_1.jpg?max_age=2592000", - "lrc": "https://npm.elemecdn.com/anzhiyu-music@1.0.1/周杰伦/等你下课/等你下课.lrc" - }, - { - "name": "我落泪情绪零碎", - "artist": "周杰伦", - "url": "https://npm.elemecdn.com/anzhiyu-music@1.0.2/我落泪情绪零碎/我落泪情绪零碎.mp3", - "cover": "https://y.qq.com/music/photo_new/T002R300x300M000000bviBl4FjTpO_1.jpg?max_age=2592000", - "lrc": "https://npm.elemecdn.com/anzhiyu-music@1.0.2/我落泪情绪零碎/我落泪情绪零碎.lrc" - }, - { - "name": "听妈妈的话", - "artist": "周杰伦", - "url": "https://npm.elemecdn.com/anzhiyu-music@1.0.2/听妈妈的话/听妈妈的话.mp3", - "cover": "https://y.qq.com/music/photo_new/T002R300x300M000002jLGWe16Tf1H_1.jpg?max_age=2592000", - "lrc": "https://npm.elemecdn.com/anzhiyu-music@1.0.2/听妈妈的话/听妈妈的话.lrc" - }, - { - "name": "明明就", - "artist": "周杰伦", - "url": "https://npm.elemecdn.com/anzhiyu-music-jay@1.0.1/明明就/明明就.flac", - "cover": "https://y.qq.com/music/photo_new/T002R300x300M000003Ow85E3pnoqi_1.jpg?max_age=2592000", - "lrc": "https://npm.elemecdn.com/anzhiyu-music-jay@1.0.1/明明就/明明就.lrc" - }, - { - "name": "我是如此相信", - "artist": "周杰伦", - "url": "https://npm.elemecdn.com/anzhiyu-music-jay@1.0.1/我是如此相信/我是如此相信.flac", - "cover": "https://y.qq.com/music/photo_new/T002R300x300M000001hGx1Z0so1YX_1.jpg?max_age=2592000", - "lrc": "https://npm.elemecdn.com/anzhiyu-music-jay@1.0.1/我是如此相信/我是如此相信.lrc" - }, - { - "name": "发如雪", - "artist": "周杰伦", - "url": "https://npm.elemecdn.com/anzhiyu-music@1.0.3/发如雪/发如雪.mp3", - "cover": "https://y.qq.com/music/photo_new/T002R300x300M0000024bjiL2aocxT_3.jpg?max_age=2592000", - "lrc": "https://npm.elemecdn.com/anzhiyu-music@1.0.3/发如雪/发如雪.lrc" - }, - { - "name": "以父之名", - "artist": "周杰伦", - "url": "https://npm.elemecdn.com/anzhiyu-music@1.0.3/以父之名/以父之名.mp3", - "cover": "https://y.qq.com/music/photo_new/T002R300x300M000000MkMni19ClKG_3.jpg?max_age=2592000", - "lrc": "https://npm.elemecdn.com/anzhiyu-music@1.0.3/以父之名/以父之名.lrc" - }, - { - "name": "园游会", - "artist": "周杰伦", - "url": "https://npm.elemecdn.com/anzhiyu-music@1.0.3/园游会/园游会.flac", - "cover": "https://y.qq.com/music/photo_new/T002R300x300M000003DFRzD192KKD_1.jpg?max_age=2592000", - "lrc": "https://npm.elemecdn.com/anzhiyu-music@1.0.3/园游会/园游会.lrc" - }, - { - "name": "本草纲目", - "artist": "周杰伦", - "url": "https://npm.elemecdn.com/anzhiyu-music@1.0.4/本草纲目/本草纲目.mp3", - "cover": "https://y.qq.com/music/photo_new/T002R300x300M000002jLGWe16Tf1H_1.jpg?max_age=2592000", - "lrc": "https://npm.elemecdn.com/anzhiyu-music@1.0.4/本草纲目/本草纲目.lrc" - }, - { - "name": "龙卷风", - "artist": "周杰伦", - "url": "https://npm.elemecdn.com/anzhiyu-music@1.0.4/龙卷风/龙卷风.mp3", - "cover": "https://y.qq.com/music/photo_new/T002R300x300M000000f01724fd7TH_1.jpg?max_age=2592000", - "lrc": "https://npm.elemecdn.com/anzhiyu-music@1.0.4/龙卷风/龙卷风.lrc" - } - ] \ No newline at end of file diff --git a/source/link/index.md b/source/link/index.md deleted file mode 100644 index 316ee074..00000000 --- a/source/link/index.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: 友情链接 -comments: false -share: false -type: "link" -date: 2023-10-08 00:01:32 ---- diff --git a/source/music/index.md b/source/music/index.md deleted file mode 100644 index d99628c5..00000000 --- a/source/music/index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: 音乐馆 -date: 2024-04-30 00:00:00 -type: music -aplayer: true -top_img: false -comments: false -aside: false ---- \ No newline at end of file diff --git a/source/plugins/css/history.css b/source/plugins/css/history.css deleted file mode 100644 index 0b0c76ee..00000000 --- a/source/plugins/css/history.css +++ /dev/null @@ -1,99 +0,0 @@ -@charset "utf-8"; -*{margin:0;padding:0;list-style-type:none;} -a,img{border:0;} -body{_background-image:url(about:blank);/*用浏览器空白页面作为背景*/_background-attachment:fixed; /* prevent screen flash in IE6 确保滚动条滚动时,元素不闪动*/ } -body{color:#535353;font-size:12px;font-family: "arial","微软雅黑";background:#f0f1f1;} -.clear{clear:both;display:block;height:0;overflow:hidden;} - -/* history */ -#history{width:1180px;height:450px;position:relative;margin:50px auto 0 auto;} -.title{height:95px;line-height:95px;text-indent:280px;} -.title h2{color:#7c7c7c;font-size:18px;font-weight:500;} -#circle{ - width:83px;height:83px;position:absolute;top:0;left:390px;border:6px solid rgba(0,0,0,0.15);border-radius:95px;text-indent:0;text-align:center; - -webkit-transition:all 0.3s linear; - -moz-transition:all 0.3s linear; - -o-transition:all 0.3s linear; - transition:all 0.3s linear; -} -#circle .cmsk{height:83px;position:absolute;width:83px;top:0;left:0;} -#circle:hover{ - transform:rotate(360deg); - -ms-transform:rotate(360deg); - -moz-transform:rotate(360deg); - -webkit-transform:rotate(360deg); - -o-transform:rotate(360deg); - border-color:rgba(0,0,0,0); -} -.clock{display:block;} -#circle:hover {border-color:rgba(255,255,255,0.6);background-color:#6bc30d;} -#circle:hover .clock{display:block;} -#circle:hover .circlecontent{display:none;} -#circle span{font-size:18px;color:#b0b0b0;} -#circle .clock{ - background:url(../images/clock.png) no-repeat 0 0;width:83px;height:83px;position:absolute;top:0;left:0;display:none; - -webkit-transition:all 0.5s linear; - -moz-transition:all 0.5s linear; - -o-transition:all 0.5s linear; - transition:all 0.5s linear; - border-radius:0; -} -#circle:hover .clock{border-radius:83px;} -.timeyear{color:#b0b0b0;font-size:18px;line-height:20px;} -.timeblock{height:28px;margin-top:22px;margin-left:5px;} -.timeblock span{display:block;height:24px;width:18px;background:url(../images/date.png) no-repeat 0 0;float:left;} -.timeblock .numf{background-position:0px -48px;} -.timeblock .nums{background-position:0px 0px;} -.timeblock .numt{background-position:0px -24px;} -.timeblock .numfo{background-position:0px -168px;} -#content{height:355px;width:1180px;overflow:hidden;background:url(../images/vertical.png) no-repeat 434px 2px;padding-top:10px;} -.list{overflow:hidden;position:relative;} -.list li{height:110px;vertical-align:bottom;overflow:hidden;position:relative;} -.liwrap{height:55px;margin-top:28px;} -.lileft{position:absolute;top:0;left:0px;height:55px;width:400px;line-height:55px;text-align:right;} -.liright{position:absolute;top:0;right:0px;height:55px;width:700px;} -.histt{height:35px;line-height:35px;} -.hisct{font-size:14px;color:#6e6e6e;} -.md{font-size:18px;color:#AEAEAE;} -.year{font-size:12px;color:#AEAEAE;margin-right:10px;} -.point{width:55px;height:55px;position:absolute;top:0;left:409px;background:url(../images/point.png) no-repeat 0px 18px;overflow:hidden;} -.point b{ - height:16px;width:16px;background:#fff;display:block;margin:17px 0 0 19px;border-radius:18px;border:2px solid #6bc30d; - -webkit-transition:all 0.1s linear; - -moz-transition:all 0.1s linear; - -o-transition:all 0.1s linear; - transition:all 0.1s linear; - position:absolute; - top:0;left:0; -} -.thiscur .point b{border:7px solid rgba(107,195,13,0.6);margin:12px 0px 0px 14px;border-radius:52px;} -.thiscur .histt a{color:#6bc30d;} -.histt a{ - font-size:24px;color:#747474; - -webkit-transition:all 0.3s linear; - -moz-transition:all 0.3s linear; - -o-transition:all 0.3s linear; - transition:all 0.3s linear; - text-decoration:none; - border-bottom:2px dotted #8F8F8F; -} -#arrow{position:fixed;top:50%;right:30px;} -*html #arrow{position:absolute;top:expression(eval(document.documentElement.scrollTop));margin-top:350px;} - -#arrow ul li{ - display:block;height:34px;width:20px;background:url(../images/icons3.png) no-repeat 0 0;cursor:pointer; - -webkit-transition:all 0.2s ease-out; - -moz-transition:all 0.2s ease-out; - -o-transition:all 0.2s ease-out; - transition:all 0.2s ease-out; -} -#arrow ul li:active{background-color:#f1f1f1;} -#arrow ul .arrow_active{ - background-color:#f1f1f1; - -webkit-transition:all 0.1s ease-in; - -moz-transition:all 0.1s ease-in; - -o-transition:all 0.1s ease-in; - transition:all 0.1s ease-in; -} -#arrow ul .arrowup{background-position:0px -26px;margin-bottom:10px;} -#arrow ul .arrowdown{background-position:0px 0px;} diff --git a/source/plugins/css/netease.css b/source/plugins/css/netease.css deleted file mode 100644 index e314de13..00000000 --- a/source/plugins/css/netease.css +++ /dev/null @@ -1,339 +0,0 @@ -.post-comments-count a::before { - content: "评论"; -} -#yun-tie-sdk-wrap .input-box .tie-submit-row .tie-submit-btn { - background-color: #649ab6; -} - -#yun-tie-sdk-wrap .input-box .tie-submit-row .tie-submit-btn:hover { - background-color: #4c618f; -} -.tie-empty-tip { - display: none; -} -/*即将发布消息人样式*/ -#yun-tie-sdk-wrap .input-box .tie-submit-row .user-info img:hover { - -box-shadow: 0 0 10px #fff; -rgba(255, 255, 255, .6) inset 0 0 20px rgba(255, 255, 255, 1); --webkit-box-shadow: 0 0 10px #fff; -rgba(255, 255, 255, .6) inset 0 0 20px rgba(255, 255, 255, 1); -transform: rotateZ(360deg); --webkit-transform: rotateZ(360deg); --moz-transform: rotateZ(360deg); -} -#yun-tie-sdk-wrap .input-box .tie-submit-row .user-info img { -width: 32px; -height: 32px; -border-radius: 50%; -margin: 4px 10px 4px 8px; -padding: 0; -cursor: pointer; -box-shadow: inset 0 -1px 0 #3333sf; /*设置图像阴影效果*/ --webkit-box-shadow: inset 0 -1px 0 #3333sf; --webkit-transition: 0.4s; --webkit-transition: -webkit-transform 0.4s ease-out; -transition: transform 0.4s ease-out; /*变化时间设置为0.4秒(变化动作即为下面的图像旋转360读)*/ --moz-transition: -moz-transform 0.4s ease-out; -} - -/*评论框内其他人样式*/ -#yun-tie-sdk-wrap .single-tie .photo img:hover { - -box-shadow: 0 0 10px #fff; -rgba(255, 255, 255, .6) inset 0 0 20px rgba(255, 255, 255, 1); --webkit-box-shadow: 0 0 10px #fff; -rgba(255, 255, 255, .6) inset 0 0 20px rgba(255, 255, 255, 1); -transform: rotateZ(360deg); --webkit-transform: rotateZ(360deg); --moz-transform: rotateZ(360deg); -} -#yun-tie-sdk-wrap .single-tie .photo img { -width: 42px; -height: 42px; -border-radius: 50%; -padding: 0; -cursor: pointer; -box-shadow: inset 0 -1px 0 #3333sf; /*设置图像阴影效果*/ --webkit-box-shadow: inset 0 -1px 0 #3333sf; --webkit-transition: 0.4s; --webkit-transition: -webkit-transform 0.4s ease-out; -transition: transform 0.4s ease-out; /*变化时间设置为0.4秒(变化动作即为下面的图像旋转360读)*/ --moz-transition: -moz-transform 0.4s ease-out; -} - -.name-nick{ - margin-right: 8px; -} - -.name-desp{ - animation-duration:1s; - -webkit-animation-duration:1s; -} - -.name-desp:hover{ - -webkit-transform:scale(1.3); - -moz-transform:scale(1.3); - -o-transform:scale(1.3); -} - -#yun-tie-sdk-wrap .single-tie .tie-author .name-nick{ - cursor: pointer; - transition: border-width 0.3s linear 0.1s, color 0.2s linear 0.3s; -} -#yun-tie-sdk-wrap .single-tie .tie-author .name-desp { - cursor: pointer; - transition: border-width 0.3s linear 0.1s, color 0.2s linear 0.3s; -} -.name-desp{ - animation-duration:1s; - -webkit-animation-duration:1s; -} -.tie-time:hover { - -webkit-transform:scale(1.3); - -moz-transform:scale(1.3); - -o-transform:scale(1.3); -} -#yun-tie-sdk-wrap .single-tie .tie-time { - transition: border-width 0.3s linear 0.1s, color 0.2s linear 0.3s; - cursor: pointer; -} - -span.ua { - display: inline-block !important; - margin: auto 1px .3em !important; - color: #fff !important; -} -.os_other { - background-color: #bdb2a7!important; - color: #fff; - border: 1px solid #BBB!important; - border-radius: 4px; - padding: 0 5px!important; - opacity: .4; -} -.ua_other { - background-color: #bdb2a7!important; - color: #fff; - border: 1px solid #BBB!important; - border-radius: 4px; - padding: 0 5px!important; - opacity: .4; -} -.ua_other { - opacity: 1; -} -.os_other:hover { - opacity: 1; -} -.ua_ie { - background-color: #428bca!important; - border-color: #357ebd!important; - border-radius: 4px; - padding: 0 5px!important; - opacity: .4; -} -.ua_ie:hover { - opacity: 1; -} -.ua_firefox { - background-color: #f0ad4e!important; - border-color: #eea236!important; - border-radius: 4px; - padding: 0 5px!important; - opacity: .4; -} -.ua_firefox:hover { - opacity: 1; -} -.ua_maxthon { - background-color: #7373B9!important; - border-color: #7373B9!important; - border-radius: 4px; - padding: 0 5px!important; - opacity: .4; -} -.ua_maxthon:hover { - opacity: 1; -} -.ua_ucweb { - background-color: #FF740F!important; - border-color: #d43f3a!important; - border-radius: 4px; - padding: 0 5px!important; - opacity: .4; -} -.ua_ucweb:hover { - opacity: 1; -} -.ua_sogou { - background-color: #78ACE9!important; - border-color: #4cae4c!important; - border-radius: 4px; - padding: 0 5px!important; - opacity: .4; -} -.ua_sogou:hover { - opacity: 1; -} -.ua_2345explorer { - background-color: #2478B8!important; - border-color: #4cae4c!important; - border-radius: 4px; - padding: 0 5px!important; - opacity: .4; -} -.ua_2345explorer:hover { - opacity: 1; -} -.ua_2345chrome { - background-color: #F9D024!important; - border-color: #4cae4c!important; - border-radius: 4px; - padding: 0 5px!important; - opacity: .4; -} -.ua_2345chrome:hover { - opacity: 1; -} -.ua_mi { - background-color: #FF4A00!important; - border-color: #4cae4c!important; - border-radius: 4px; - padding: 0 5px!important; - opacity: .4; -} -.ua_mi:hover { - opacity: 1; -} -.ua_lbbrowser { - background-color: #FC9D2E!important; - border-color: #4cae4c!important; - border-radius: 4px; - padding: 0 5px!important; - opacity: .4; -} -.ua_lbbrowser:hover { - opacity: 1; -} -.ua_chrome { - background-color: #EE6252!important; - border-color: #4cae4c!important; - border-radius: 4px; - padding: 0 5px!important; - opacity: .4; -} -.ua_chrome:hover { - opacity: 1; -} -.ua_qq { - background-color: #3D88A8!important; - border-color: #4cae4c!important; - border-radius: 4px; - padding: 0 5px!important; - opacity: .4; -} -.ua_qq:hover { - opacity: 1; -} -.ua_apple { - background-color: #E95620!important; - border-color: #4cae4c!important; - border-radius: 4px; - padding: 0 5px!important; - opacity: .4; -} -.ua_apple:hover { - opacity: 1; -} -.ua_opera { - background-color: #d9534f!important; - border-color: #d43f3a!important; - border-radius: 4px; - padding: 0 5px!important; - opacity: .4; -} -.ua_opera:hover { - opacity: 1; -} -.os_vista,.os_2000,.os_windows,.os_xp,.os_7,.os_8,.os_8_1 { - background-color: #39b3d7!important; - border-color: #46b8da!important; - border-radius: 4px; - padding: 0 5px!important; - opacity: .4; -} -.os_vista:hover,.os_2000:hover,.os_windows:hover,.os_xp:hover,.os_7:hover,.os_8:hover,.os_8_1:hover { - opacity: 1; -} -.os_android { - background-color: #98C13D!important; - border-color: #01B171!important; - border-radius: 4px; - padding: 0 5px!important; - opacity: .4; -} -.os_android:hover { - opacity: 1; -} -.os_ubuntu { - background-color: #DD4814!important; - border-color: #01B171!important; - border-radius: 4px; - padding: 0 5px!important; - opacity: .4; -} -.os_ubuntu:hover { - opacity: 1; -} -.os_linux { - background-color: #3A3A3A!important; - border-color: #1F1F1F!important; - border-radius: 4px; - padding: 0 5px!important; - opacity: .4; -} -.os_linux:hover { - opacity: 1; -} -.os_mac { - background-color: #666666!important; - border-color: #1F1F1F!important; - border-radius: 4px; - padding: 0 5px!important; - opacity: .4; -} -.os_mac:hover { - opacity: 1; -} -.os_unix { - background-color: #006600!important; - border-color: #1F1F1F!important; - border-radius: 4px; - padding: 0 5px!important; - opacity: .4; -} -.os_unix:hover { - opacity: 1; -} -.os_nokia { - background-color: #014485!important; - border-color: #1F1F1F!important; - border-radius: 4px; - padding: 0 5px!important; - opacity: .4; -} -.os_nokia:hover { - opacity: 1; -} -/*UA End*/ -/*博主标记 CSS*/ -.sskadmin { - background-color: #00a67c!important; - border-color: #01B171!important; - border-radius: 4px; - padding: 0 5px!important; -} -.sskadmin:hover { - opacity: 1; -} diff --git a/source/plugins/css/special.css b/source/plugins/css/special.css deleted file mode 100644 index 81ecc804..00000000 --- a/source/plugins/css/special.css +++ /dev/null @@ -1,1294 +0,0 @@ -/* 字往下掉 */ -.rw-words{ - display: inline; - line-height: 1.75; -} - -.rw-words-1 span{ - position: absolute; - opacity: 0; - overflow: hidden; - color: #999; - font-weight:normal; - -webkit-transform-origin: 10% 75%; - transform-origin: 10% 75%; - -webkit-animation: rotateWord 18s linear infinite 0s; - -ms-animation: rotateWord 18s linear infinite 0s; - animation: rotateWord 18s linear infinite 0s; -} -.rw-words-1 span:nth-child(2) { - -webkit-animation-delay: 3s; - -ms-animation-delay: 3s; - animation-delay: 3s; - color: #6b889d; -} -.rw-words-1 span:nth-child(3) { - -webkit-animation-delay: 6s; - -ms-animation-delay: 6s; - animation-delay: 6s; - color: #6b739d; -} -.rw-words-1 span:nth-child(4) { - -webkit-animation-delay: 9s; - -ms-animation-delay: 9s; - animation-delay: 9s; - color: #7a6b9d; -} -.rw-words-1 span:nth-child(5) { - -webkit-animation-delay: 12s; - -ms-animation-delay: 12s; - animation-delay: 12s; - color: #8d6b9d; -} -.rw-words-1 span:nth-child(6) { - -webkit-animation-delay: 15s; - -ms-animation-delay: 15s; - animation-delay: 15s; - color: #9b6b9d; -} -@-webkit-keyframes rotateWord { - 0% { opacity: 0; } - 5% { opacity: 1; } - 17% { opacity: 1; -webkit-transform: rotate(0deg); } - 19% { opacity: 1; -webkit-transform: rotate(98deg); } - 21% { opacity: 1; -webkit-transform: rotate(86deg); } - 23% { opacity: 1; -webkit-transform: translateY(85px) rotate(83deg); } - 25% { opacity: 0; -webkit-transform: translateY(170px) rotate(80deg); } - 80% { opacity: 0; } - 100% { opacity: 0; } -} -@-ms-keyframes rotateWord { - 0% { opacity: 0; } - 5% { opacity: 1; } - 17% { opacity: 1; -ms-transform: rotate(0deg); } - 19% { opacity: 1; -ms-transform: rotate(98deg); } - 21% { opacity: 1; -ms-transform: rotate(86deg); } - 23% { opacity: 1; -ms-transform: translateY(85px) rotate(83deg); } - 25% { opacity: 0; -ms-transform: translateY(170px) rotate(80deg); } - 80% { opacity: 0; } - 100% { opacity: 0; } -} -@keyframes rotateWord { - 0% { opacity: 0; } - 5% { opacity: 1; } - 17% { opacity: 1; -webkit-transform: rotate(0deg); transform: rotate(0deg); } - 19% { opacity: 1; -webkit-transform: rotate(98deg); transform: rotate(98deg); } - 21% { opacity: 1; -webkit-transform: rotate(86deg); transform: rotate(86deg); } - 23% { opacity: 1; -webkit-transform: translateY(85px) rotate(83deg); transform: translateY(85px) rotate(83deg); } - 25% { opacity: 0; -webkit-transform: translateY(170px) rotate(80deg); transform: translateY(170px) rotate(80deg); } - 80% { opacity: 0; } - 100% { opacity: 0; } -} -@media screen and (max-width: 768px){ - .rw-sentence { font-size: 18px; } -} -@media screen and (max-width: 320px){ - .rw-sentence { font-size: 9px; } -} - -.button { - position: absolute; - display: inline-block; - padding: 0.5em 1em; - border: 0.5px solid #d4d4d4; - margin: 0; - text-decoration: none; - text-align: center; - text-shadow: 1px 1px 0 #fff; - font:11px/normal sans-serif; - color: #333; - white-space: nowrap; - cursor: pointer; - outline: none; - background-color: #ececec; - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f4f4f4), to(#ececec)); - background-image: -moz-linear-gradient(#f4f4f4, #ececec); - background-image: -ms-linear-gradient(#f4f4f4, #ececec); - background-image: -o-linear-gradient(#f4f4f4, #ececec); - background-image: linear-gradient(#f4f4f4, #ececec); - -moz-background-clip: padding; /* for Firefox 3.6 */ - background-clip: padding-box; - border-radius: 0.2em; - /* IE hacks */ - zoom: 1; - *display: inline; -} - -.button:hover, -.button:focus, -.button:active, -.button.active { - border-color: #3072b3; - border-bottom-color: #2a65a0; - text-decoration: none; - text-shadow: -1px -1px 0 rgba(0,0,0,0.3); - color: #fff; - background-color: #3c8dde; - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#599bdc), to(#3072b3)); - background-image: -moz-linear-gradient(#599bdc, #3072b3); - background-image: -o-linear-gradient(#599bdc, #3072b3); - background-image: linear-gradient(#599bdc, #3072b3); -} - -.button:active, -.button.active { - border-color: #2a65a0; - border-bottom-color: #3884cd; - background-color: #3072b3; - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#3072b3), to(#599bdc)); - background-image: -moz-linear-gradient(#3072b3, #599bdc); - background-image: -ms-linear-gradient(#3072b3, #599bdc); - background-image: -o-linear-gradient(#3072b3, #599bdc); - background-image: linear-gradient(#3072b3, #599bdc); -} - -/* overrides extra padding on button elements in Firefox */ -.button::-moz-focus-inner { - padding: 0; - border: 0; -} - -/* Pill button 搜索删除按钮 - ========================================================================== */ - -.button.pill { - border-radius: 50em; -} - -#local-search-input:focus -{ - color:#198ded; -} - -/* 右下角搜索,通用 */ -.cb-search-content::-webkit-input-placeholder { color:#B0B0B0; } -.cb-search-content::-moz-placeholder { color:#B0B0B0; } /* firefox 19+ */ -.cb-search-content:-ms-input-placeholder { color:#B0B0B0; } /* ie */ -.cb-search-content:-moz-placeholder { color:#B0B0B0; } - -.cb-search-content:focus { - border-color: #66afe9; - outline: 0; - background-color: #fff; -} - -.dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - display: none; - float: left; - min-width: 100px; - padding: 5px 0; - margin: 2px 0 0; - font-size: 14px; - text-align: left; - list-style: none; - background-color: #fff; - width:50%; - -webkit-background-clip: padding-box; - background-clip: padding-box; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, .15); - border-radius: 4px; - -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175); - box-shadow: 0 6px 12px rgba(0, 0, 0, .175); -} - -.dropdown-menu.pull-right { - right: 0; - left: auto; -} - -.dropdown-menu .divider { - height: 1px; - margin: 9px 0; - overflow: hidden; - background-color: #e5e5e5; -} - -.dropdown-menu > li > a { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: 1.42857143; - color: #333; - white-space: nowrap; -} - -.dropdown-menu > li > a:hover, -.dropdown-menu > li > a:focus { - color: #262626; - text-decoration: none; - background-color: #f5f5f5; -} - -.dropdown-menu > .active > a, -.dropdown-menu > .active > a:hover, -.dropdown-menu > .active > a:focus { - color: #fff; - text-decoration: none; - background-color: #337ab7; - outline: 0; -} - -.dropdown-menu > .disabled > a, -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - color: #777; -} - -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - text-decoration: none; - cursor: not-allowed; - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -} - -@media screen and (min-width: 768px) { - .dropdown-menu { - position: relative; - float: none; - font-size: 18px; - color:black; - width: 50%; - margin: 0 15%; - } - - .cb-search-tool ul { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - - .cb-search-content { - display: block; - width: 40%; - margin: 0 15%; - position: absolute; - top: 13%; - float: none; - left: auto; - right: auto; - font-size: 20px; - padding: 6px 12px; - height: 40px; - background-color: #fff; - box-sizing: border-box; - color: black; - opacity: 1.0; - border: none; - outline: none; - line-height: 1.42857143; - -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; - -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; - transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; - } -} - -@media screen and (max-width: 767px) { - .dropdown-menu { - position: relative; - float: none; - font-size: 18px; - width: 50%; - margin: 0 2%; - } - - .cb-search-tool ul { - width: 50%; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - - .cb-search-content { - width: 40%; - margin: 0 2%; - position: absolute; - top: 10%; - left: auto; - right: auto; - font-size: 20px; - height: 40px; - background-color: #fff; - color: black; - opacity: 1.0; - border: none; - outline: none; - box-sizing: border-box; - padding: 6px 12px; - line-height: 1.42857143; - -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; - -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; - transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; - } -} - -/*! Hint.css - v0.1.0 - 2013-02-03 -* https://github.com/chinchang/hint.css -* Copyright (c) 2013 Kushagra Gour; Licensed MIT 提示*/ - -.hint{position:relative;display:inline-block}.hint:before,.hint:after{position:absolute;opacity:0;z-index:1000000;pointer-events:none;-webkit-transition:.3s ease;-moz-transition:.3s ease}.hint:hover:before,.hint:hover:after{opacity:1}.hint:before{content:'';position:absolute;background:transparent;border:6px solid transparent;z-index:1000001}.hint:after{content:attr(data-hint);background:#383838;color:#fff;text-shadow:0 -1px 0 black;padding:8px 10px;font-size:12px;line-height:12px;white-space:nowrap;box-shadow:4px 4px 8px rgba(0,0,0,.3)}.hint--top:before{border-top-color:#383838}.hint--bottom:before{border-bottom-color:#383838}.hint--left:before{border-left-color:#383838}.hint--right:before{border-right-color:#383838}.hint--top:before{margin-bottom:-12px}.hint--top:after{margin-left:-18px}.hint--top:before,.hint--top:after{bottom:100%;left:50%}.hint--top:hover:before,.hint--top:hover:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--bottom:before{margin-top:-12px}.hint--bottom:after{margin-left:-18px}.hint--bottom:before,.hint--bottom:after{top:100%;left:50%}.hint--bottom:hover:before,.hint--bottom:hover:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--right:before{margin-left:-12px;margin-bottom:-6px}.hint--right:after{margin-bottom:-14px}.hint--right:before,.hint--right:after{left:100%;bottom:50%}.hint--right:hover:before,.hint--right:hover:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translateX(8px)}.hint--left:before{margin-right:-12px;margin-bottom:-6px}.hint--left:after{margin-bottom:-14px}.hint--left:before,.hint--left:after{right:100%;bottom:50%}.hint--left:hover:before,.hint--left:hover:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translateX(-8px)}.hint--error:after{background-color:#b34e4d;text-shadow:0 -1px 0 #5a2626}.hint--error.hint--top:before{border-top-color:#b34e4d}.hint--error.hint--bottom:before{border-bottom-color:#b34e4d}.hint--error.hint--left:before{border-left-color:#b34e4d}.hint--error.hint--right:before{border-right-color:#b34e4d}.hint--warning:after{background-color:#c09854;text-shadow:0 -1px 0 #6d5228}.hint--warning.hint--top:before{border-top-color:#c09854}.hint--warning.hint--bottom:before{border-bottom-color:#c09854}.hint--warning.hint--left:before{border-left-color:#c09854}.hint--warning.hint--right:before{border-right-color:#c09854}.hint--info:after{background-color:#3986ac;text-shadow:0 -1px 0 #193c4c}.hint--info.hint--top:before{border-top-color:#3986ac}.hint--info.hint--bottom:before{border-bottom-color:#3986ac}.hint--info.hint--left:before{border-left-color:#3986ac}.hint--info.hint--right:before{border-right-color:#3986ac}.hint--success:after{background-color:#458746;text-shadow:0 -1px 0 #1a331a}.hint--success.hint--top:before{border-top-color:#458746}.hint--success.hint--bottom:before{border-bottom-color:#458746}.hint--success.hint--left:before{border-left-color:#458746}.hint--success.hint--right:before{border-right-color:#458746}.hint--always:after,.hint--always:before{opacity:1}.hint--always.hint--top:after,.hint--always.hint--top:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--always.hint--bottom:after,.hint--always.hint--bottom:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--always.hint--left:after,.hint--always.hint--left:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translateX(-8px)}.hint--always.hint--right:after,.hint--always.hint--right:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translateX(8px)} - -/*! Color themes for Google Code Prettify | MIT License | github.com/jmblog/color-themes-for-google-code-prettify 代码高亮*/ -.prettyprint { - background: #50504f; - font-family: Menlo, "Bitstream Vera Sans Mono", "DejaVu Sans Mono", Monaco, Consolas, monospace; - border: 0 !important; -} - -.pln { - color: #cccccc; -} - -/* Specify class=linenums on a pre to get line numbering */ -ol.linenums { - margin-top: 0; - margin-bottom: 0; - color: #999999; -} - -li.L0, -li.L1, -li.L2, -li.L3, -li.L4, -li.L5, -li.L6, -li.L7, -li.L8, -li.L9 { - padding-left: 1em; - background-color: #50504f; - list-style-type: decimal; -} - -@media screen { - - /* string content */ - - .str { - color: #99cc99; - } - - /* keyword */ - - .kwd { - color: #cc99cc; - } - - /* comment */ - - .com { - color: #999999; - } - - /* type name */ - - .typ { - color: #6699cc; - } - - /* literal value */ - - .lit { - color: #f99157; - } - - /* punctuation */ - - .pun { - color: #cccccc; - } - - /* lisp open bracket */ - - .opn { - color: #cccccc; - } - - /* lisp close bracket */ - - .clo { - color: #cccccc; - } - - /* markup tag name */ - - .tag { - color: #f2777a; - } - - /* markup attribute name */ - - .atn { - color: #f99157; - } - - /* markup attribute value */ - - .atv { - color: #66cccc; - } - - /* declaration */ - - .dec { - color: #f99157; - } - - /* variable name */ - - .var { - color: #f2777a; - } - - /* function name */ - - .fun { - color: #6699cc; - } -} - -/*左边栏提示 coding change the world样式 */ -.cd-headline { - font-size: 1rem; - line-height: 1.75; -} -@media only screen and (min-width: 768px) { - .cd-headline { - font-size: 1rem; - line-height: 1.75; - } -} -@media only screen and (min-width: 1170px) { - .cd-headline { - font-size: 1rem; - line-height: 1.75; - } -} - -.cd-words-wrapper { - display: inline-block; - position: relative; - font-size: 1rem; - line-height: 1.75; - text-align: left; -} -.cd-words-wrapper b { - display: inline-block; - font-size: 1rem; - line-height: 1.75; - position: absolute; - white-space: nowrap; - left: 0; - top: 0; -} -.cd-words-wrapper b.is-visible { - position: relative; -} -.no-js .cd-words-wrapper b { - opacity: 0; -} -.no-js .cd-words-wrapper b.is-visible { - opacity: 1; -} - -/* -------------------------------- - -xrotate-1 - --------------------------------- */ -.cd-headline.rotate-1 .cd-words-wrapper { - -webkit-perspective: 300px; - -moz-perspective: 300px; - perspective: 300px; -} -.cd-headline.rotate-1 b { - opacity: 0; - -webkit-transform-origin: 50% 100%; - -moz-transform-origin: 50% 100%; - -ms-transform-origin: 50% 100%; - -o-transform-origin: 50% 100%; - transform-origin: 50% 100%; - -webkit-transform: rotateX(180deg); - -moz-transform: rotateX(180deg); - -ms-transform: rotateX(180deg); - -o-transform: rotateX(180deg); - transform: rotateX(180deg); -} -.cd-headline.rotate-1 b.is-visible { - opacity: 1; - -webkit-transform: rotateX(0deg); - -moz-transform: rotateX(0deg); - -ms-transform: rotateX(0deg); - -o-transform: rotateX(0deg); - transform: rotateX(0deg); - -webkit-animation: cd-rotate-1-in 1.2s; - -moz-animation: cd-rotate-1-in 1.2s; - animation: cd-rotate-1-in 1.2s; -} -.cd-headline.rotate-1 b.is-hidden { - -webkit-transform: rotateX(180deg); - -moz-transform: rotateX(180deg); - -ms-transform: rotateX(180deg); - -o-transform: rotateX(180deg); - transform: rotateX(180deg); - -webkit-animation: cd-rotate-1-out 1.2s; - -moz-animation: cd-rotate-1-out 1.2s; - animation: cd-rotate-1-out 1.2s; -} - -@-webkit-keyframes cd-rotate-1-in { - 0% { - -webkit-transform: rotateX(180deg); - opacity: 0; - } - 35% { - -webkit-transform: rotateX(120deg); - opacity: 0; - } - 65% { - opacity: 0; - } - 100% { - -webkit-transform: rotateX(360deg); - opacity: 1; - } -} -@-moz-keyframes cd-rotate-1-in { - 0% { - -moz-transform: rotateX(180deg); - opacity: 0; - } - 35% { - -moz-transform: rotateX(120deg); - opacity: 0; - } - 65% { - opacity: 0; - } - 100% { - -moz-transform: rotateX(360deg); - opacity: 1; - } -} -@keyframes cd-rotate-1-in { - 0% { - -webkit-transform: rotateX(180deg); - -moz-transform: rotateX(180deg); - -ms-transform: rotateX(180deg); - -o-transform: rotateX(180deg); - transform: rotateX(180deg); - opacity: 0; - } - 35% { - -webkit-transform: rotateX(120deg); - -moz-transform: rotateX(120deg); - -ms-transform: rotateX(120deg); - -o-transform: rotateX(120deg); - transform: rotateX(120deg); - opacity: 0; - } - 65% { - opacity: 0; - } - 100% { - -webkit-transform: rotateX(360deg); - -moz-transform: rotateX(360deg); - -ms-transform: rotateX(360deg); - -o-transform: rotateX(360deg); - transform: rotateX(360deg); - opacity: 1; - } -} -@-webkit-keyframes cd-rotate-1-out { - 0% { - -webkit-transform: rotateX(0deg); - opacity: 1; - } - 35% { - -webkit-transform: rotateX(-40deg); - opacity: 1; - } - 65% { - opacity: 0; - } - 100% { - -webkit-transform: rotateX(180deg); - opacity: 0; - } -} -@-moz-keyframes cd-rotate-1-out { - 0% { - -moz-transform: rotateX(0deg); - opacity: 1; - } - 35% { - -moz-transform: rotateX(-40deg); - opacity: 1; - } - 65% { - opacity: 0; - } - 100% { - -moz-transform: rotateX(180deg); - opacity: 0; - } -} -@keyframes cd-rotate-1-out { - 0% { - -webkit-transform: rotateX(0deg); - -moz-transform: rotateX(0deg); - -ms-transform: rotateX(0deg); - -o-transform: rotateX(0deg); - transform: rotateX(0deg); - opacity: 1; - } - 35% { - -webkit-transform: rotateX(-40deg); - -moz-transform: rotateX(-40deg); - -ms-transform: rotateX(-40deg); - -o-transform: rotateX(-40deg); - transform: rotateX(-40deg); - opacity: 1; - } - 65% { - opacity: 0; - } - 100% { - -webkit-transform: rotateX(180deg); - -moz-transform: rotateX(180deg); - -ms-transform: rotateX(180deg); - -o-transform: rotateX(180deg); - transform: rotateX(180deg); - opacity: 0; - } -} - -/* -------------------------------- - -xzoom - --------------------------------- */ -.cd-headline.zoom .cd-words-wrapper { - -webkit-perspective: 300px; - -moz-perspective: 300px; - perspective: 300px; -} -.cd-headline.zoom b { - opacity: 0; -} -.cd-headline.zoom b.is-visible { - opacity: 1; - -webkit-animation: zoom-in 0.8s; - -moz-animation: zoom-in 0.8s; - animation: zoom-in 0.8s; -} -.cd-headline.zoom b.is-hidden { - -webkit-animation: zoom-out 0.8s; - -moz-animation: zoom-out 0.8s; - animation: zoom-out 0.8s; -} - -@-webkit-keyframes zoom-in { - 0% { - opacity: 0; - -webkit-transform: translateZ(100px); - } - 100% { - opacity: 1; - -webkit-transform: translateZ(0); - } -} -@-moz-keyframes zoom-in { - 0% { - opacity: 0; - -moz-transform: translateZ(100px); - } - 100% { - opacity: 1; - -moz-transform: translateZ(0); - } -} -@keyframes zoom-in { - 0% { - opacity: 0; - -webkit-transform: translateZ(100px); - -moz-transform: translateZ(100px); - -ms-transform: translateZ(100px); - -o-transform: translateZ(100px); - transform: translateZ(100px); - } - 100% { - opacity: 1; - -webkit-transform: translateZ(0); - -moz-transform: translateZ(0); - -ms-transform: translateZ(0); - -o-transform: translateZ(0); - transform: translateZ(0); - } -} -@-webkit-keyframes zoom-out { - 0% { - opacity: 1; - -webkit-transform: translateZ(0); - } - 100% { - opacity: 0; - -webkit-transform: translateZ(-100px); - } -} -@-moz-keyframes zoom-out { - 0% { - opacity: 1; - -moz-transform: translateZ(0); - } - 100% { - opacity: 0; - -moz-transform: translateZ(-100px); - } -} -@keyframes zoom-out { - 0% { - opacity: 1; - -webkit-transform: translateZ(0); - -moz-transform: translateZ(0); - -ms-transform: translateZ(0); - -o-transform: translateZ(0); - transform: translateZ(0); - } - 100% { - opacity: 0; - -webkit-transform: translateZ(-100px); - -moz-transform: translateZ(-100px); - -ms-transform: translateZ(-100px); - -o-transform: translateZ(-100px); - transform: translateZ(-100px); - } -} -/* -------------------------------- - -xslide - --------------------------------- */ -.cd-headline.slide span { - display: inline-block; - padding: .2em 0; -} -.cd-headline.slide .cd-words-wrapper { - overflow: hidden; - vertical-align: top; -} -.cd-headline.slide b { - opacity: 0; - top: .2em; -} -.cd-headline.slide b.is-visible { - top: 0; - opacity: 1; - -webkit-animation: slide-in 0.6s; - -moz-animation: slide-in 0.6s; - animation: slide-in 0.6s; -} -.cd-headline.slide b.is-hidden { - -webkit-animation: slide-out 0.6s; - -moz-animation: slide-out 0.6s; - animation: slide-out 0.6s; -} - -@-webkit-keyframes slide-in { - 0% { - opacity: 0; - -webkit-transform: translateY(-100%); - } - 60% { - opacity: 1; - -webkit-transform: translateY(20%); - } - 100% { - opacity: 1; - -webkit-transform: translateY(0); - } -} -@-moz-keyframes slide-in { - 0% { - opacity: 0; - -moz-transform: translateY(-100%); - } - 60% { - opacity: 1; - -moz-transform: translateY(20%); - } - 100% { - opacity: 1; - -moz-transform: translateY(0); - } -} -@keyframes slide-in { - 0% { - opacity: 0; - -webkit-transform: translateY(-100%); - -moz-transform: translateY(-100%); - -ms-transform: translateY(-100%); - -o-transform: translateY(-100%); - transform: translateY(-100%); - } - 60% { - opacity: 1; - -webkit-transform: translateY(20%); - -moz-transform: translateY(20%); - -ms-transform: translateY(20%); - -o-transform: translateY(20%); - transform: translateY(20%); - } - 100% { - opacity: 1; - -webkit-transform: translateY(0); - -moz-transform: translateY(0); - -ms-transform: translateY(0); - -o-transform: translateY(0); - transform: translateY(0); - } -} -@-webkit-keyframes slide-out { - 0% { - opacity: 1; - -webkit-transform: translateY(0); - } - 60% { - opacity: 0; - -webkit-transform: translateY(120%); - } - 100% { - opacity: 0; - -webkit-transform: translateY(100%); - } -} -@-moz-keyframes slide-out { - 0% { - opacity: 1; - -moz-transform: translateY(0); - } - 60% { - opacity: 0; - -moz-transform: translateY(120%); - } - 100% { - opacity: 0; - -moz-transform: translateY(100%); - } -} -@keyframes slide-out { - 0% { - opacity: 1; - -webkit-transform: translateY(0); - -moz-transform: translateY(0); - -ms-transform: translateY(0); - -o-transform: translateY(0); - transform: translateY(0); - } - 60% { - opacity: 0; - -webkit-transform: translateY(120%); - -moz-transform: translateY(120%); - -ms-transform: translateY(120%); - -o-transform: translateY(120%); - transform: translateY(120%); - } - 100% { - opacity: 0; - -webkit-transform: translateY(100%); - -moz-transform: translateY(100%); - -ms-transform: translateY(100%); - -o-transform: translateY(100%); - transform: translateY(100%); - } -} -/* -------------------------------- - -xclip - --------------------------------- */ -.cd-headline.clip span { - display: inline-block; -} -.cd-headline.clip .cd-words-wrapper { - overflow: hidden; - vertical-align: top; -} -.cd-headline.clip .cd-words-wrapper::after { - /* line */ - content: ''; - position: absolute; - top: 0; - right: 0; - width: 2px; - height: 100%; - background-color: #aebcb9; -} -.cd-headline.clip b { - opacity: 0; -} -.cd-headline.clip b.is-visible { - opacity: 1; -} - -/* -------------------------------- - -xscale - --------------------------------- */ -.cd-headline.scale i { - display: inline-block; - opacity: 0; - -webkit-transform: scale(0); - -moz-transform: scale(0); - -ms-transform: scale(0); - -o-transform: scale(0); - transform: scale(0); -} -.is-visible .cd-headline.scale i { - opacity: 1; -} -.cd-headline.scale i.in { - -webkit-animation: scale-up 0.6s forwards; - -moz-animation: scale-up 0.6s forwards; - animation: scale-up 0.6s forwards; -} -.cd-headline.scale i.out { - -webkit-animation: scale-down 0.6s forwards; - -moz-animation: scale-down 0.6s forwards; - animation: scale-down 0.6s forwards; -} - -.no-csstransitions .cd-headline.scale i { - -webkit-transform: scale(1); - -moz-transform: scale(1); - -ms-transform: scale(1); - -o-transform: scale(1); - transform: scale(1); - opacity: 0; -} - -.no-csstransitions .cd-headline.scale .is-visible i { - opacity: 1; -} - -@-webkit-keyframes scale-up { - 0% { - -webkit-transform: scale(0); - opacity: 0; - } - 60% { - -webkit-transform: scale(1.2); - opacity: 1; - } - 100% { - -webkit-transform: scale(1); - opacity: 1; - } -} -@-moz-keyframes scale-up { - 0% { - -moz-transform: scale(0); - opacity: 0; - } - 60% { - -moz-transform: scale(1.2); - opacity: 1; - } - 100% { - -moz-transform: scale(1); - opacity: 1; - } -} -@keyframes scale-up { - 0% { - -webkit-transform: scale(0); - -moz-transform: scale(0); - -ms-transform: scale(0); - -o-transform: scale(0); - transform: scale(0); - opacity: 0; - } - 60% { - -webkit-transform: scale(1.2); - -moz-transform: scale(1.2); - -ms-transform: scale(1.2); - -o-transform: scale(1.2); - transform: scale(1.2); - opacity: 1; - } - 100% { - -webkit-transform: scale(1); - -moz-transform: scale(1); - -ms-transform: scale(1); - -o-transform: scale(1); - transform: scale(1); - opacity: 1; - } -} -@-webkit-keyframes scale-down { - 0% { - -webkit-transform: scale(1); - opacity: 1; - } - 60% { - -webkit-transform: scale(0); - opacity: 0; - } -} -@-moz-keyframes scale-down { - 0% { - -moz-transform: scale(1); - opacity: 1; - } - 60% { - -moz-transform: scale(0); - opacity: 0; - } -} -@keyframes scale-down { - 0% { - -webkit-transform: scale(1); - -moz-transform: scale(1); - -ms-transform: scale(1); - -o-transform: scale(1); - transform: scale(1); - opacity: 1; - } - 60% { - -webkit-transform: scale(0); - -moz-transform: scale(0); - -ms-transform: scale(0); - -o-transform: scale(0); - transform: scale(0); - opacity: 0; - } -} -/* -------------------------------- - -xpush - --------------------------------- */ -.cd-headline.push b { - opacity: 0; -} -.cd-headline.push b.is-visible { - opacity: 1; - -webkit-animation: push-in 0.6s; - -moz-animation: push-in 0.6s; - animation: push-in 0.6s; -} -.cd-headline.push b.is-hidden { - -webkit-animation: push-out 0.6s; - -moz-animation: push-out 0.6s; - animation: push-out 0.6s; -} - -@-webkit-keyframes push-in { - 0% { - opacity: 0; - -webkit-transform: translateX(-100%); - } - 60% { - opacity: 1; - -webkit-transform: translateX(10%); - } - 100% { - opacity: 1; - -webkit-transform: translateX(0); - } -} -@-moz-keyframes push-in { - 0% { - opacity: 0; - -moz-transform: translateX(-100%); - } - 60% { - opacity: 1; - -moz-transform: translateX(10%); - } - 100% { - opacity: 1; - -moz-transform: translateX(0); - } -} -@keyframes push-in { - 0% { - opacity: 0; - -webkit-transform: translateX(-100%); - -moz-transform: translateX(-100%); - -ms-transform: translateX(-100%); - -o-transform: translateX(-100%); - transform: translateX(-100%); - } - 60% { - opacity: 1; - -webkit-transform: translateX(10%); - -moz-transform: translateX(10%); - -ms-transform: translateX(10%); - -o-transform: translateX(10%); - transform: translateX(10%); - } - 100% { - opacity: 1; - -webkit-transform: translateX(0); - -moz-transform: translateX(0); - -ms-transform: translateX(0); - -o-transform: translateX(0); - transform: translateX(0); - } -} -@-webkit-keyframes push-out { - 0% { - opacity: 1; - -webkit-transform: translateX(0); - } - 60% { - opacity: 0; - -webkit-transform: translateX(110%); - } - 100% { - opacity: 0; - -webkit-transform: translateX(100%); - } -} -@-moz-keyframes push-out { - 0% { - opacity: 1; - -moz-transform: translateX(0); - } - 60% { - opacity: 0; - -moz-transform: translateX(110%); - } - 100% { - opacity: 0; - -moz-transform: translateX(100%); - } -} -@keyframes push-out { - 0% { - opacity: 1; - -webkit-transform: translateX(0); - -moz-transform: translateX(0); - -ms-transform: translateX(0); - -o-transform: translateX(0); - transform: translateX(0); - } - 60% { - opacity: 0; - -webkit-transform: translateX(110%); - -moz-transform: translateX(110%); - -ms-transform: translateX(110%); - -o-transform: translateX(110%); - transform: translateX(110%); - } - 100% { - opacity: 0; - -webkit-transform: translateX(100%); - -moz-transform: translateX(100%); - -ms-transform: translateX(100%); - -o-transform: translateX(100%); - transform: translateX(100%); - } -} - -/* -------------------------------- - -xloading-bar - --------------------------------- */ -.cd-headline.loading-bar span { - display: inline-block; -} -.cd-headline.loading-bar .cd-words-wrapper { - overflow: hidden; - vertical-align: top; -} -.cd-headline.loading-bar .cd-words-wrapper::after { - /* loading bar */ - content: ''; - position: absolute; - left: 0; - bottom: 0; - height: 2px; - width: 0; - background: #0096a7; - z-index: 2; - -webkit-transition: width 0.3s -0.1s; - -moz-transition: width 0.3s -0.1s; - transition: width 0.3s -0.1s; -} -.cd-headline.loading-bar .cd-words-wrapper.is-loading::after { - width: 100%; - -webkit-transition: width 3s; - -moz-transition: width 3s; - transition: width 3s; -} -.cd-headline.loading-bar b { - top: .1em; - opacity: 0; - -webkit-transition: opacity 0.3s; - -moz-transition: opacity 0.3s; - transition: opacity 0.3s; -} -.cd-headline.loading-bar b.is-visible { - opacity: 1; - top: 0; -} - -/* 控制社交图标动画 */ -#header .header-nav .social a{ - transition:All 0.4s ease-in-out; - -webkit-transition:All 0.4s ease-in-out; - -moz-transition:All 0.4s ease-in-out; - -o-transition:All 0.4s ease-in-out; -} - -#header .header-nav .social a:hover{ - transform:scale(1.2); - -webkit-transform:scale(1.2); - -moz-transform:scale(1.2); - -o-transform:scale(1.2); - -ms-transform:scale(1.2); -} - -#backtoTop { - background-color:#eee; - border-radius:100%; - bottom:10%; - height:48px; - position:fixed; - right:-100px;width:48px; - transition:0.5s; - -webkit-transition:0.5s -} -#backtoTop.button--show { - right:10px -} -.per { - font-size:16px; - height:48px; - line-height:48px; - position:absolute; - text-align:center; - top:0; - width:48px; - color:#666; - cursor:pointer -} -.per:before{ - content: attr(data-percent) -} -.per:hover:before{ - content: "顶↑"; - font-size: 20px -} diff --git a/source/plugins/font/style3.css b/source/plugins/font/style3.css deleted file mode 100644 index 9867eb40..00000000 --- a/source/plugins/font/style3.css +++ /dev/null @@ -1,156 +0,0 @@ -/* 字往下掉 */ -.rw-words{ - display: inline; - line-height: 1.75; -} - -.rw-words-1 span{ - position: absolute; - opacity: 0; - overflow: hidden; - color: #999; - font-weight:normal; - -webkit-transform-origin: 10% 75%; - transform-origin: 10% 75%; - -webkit-animation: rotateWord 18s linear infinite 0s; - -ms-animation: rotateWord 18s linear infinite 0s; - animation: rotateWord 18s linear infinite 0s; -} -.rw-words-1 span:nth-child(2) { - -webkit-animation-delay: 3s; - -ms-animation-delay: 3s; - animation-delay: 3s; - color: #6b889d; -} -.rw-words-1 span:nth-child(3) { - -webkit-animation-delay: 6s; - -ms-animation-delay: 6s; - animation-delay: 6s; - color: #6b739d; -} -.rw-words-1 span:nth-child(4) { - -webkit-animation-delay: 9s; - -ms-animation-delay: 9s; - animation-delay: 9s; - color: #7a6b9d; -} -.rw-words-1 span:nth-child(5) { - -webkit-animation-delay: 12s; - -ms-animation-delay: 12s; - animation-delay: 12s; - color: #8d6b9d; -} -.rw-words-1 span:nth-child(6) { - -webkit-animation-delay: 15s; - -ms-animation-delay: 15s; - animation-delay: 15s; - color: #9b6b9d; -} -@-webkit-keyframes rotateWord { - 0% { opacity: 0; } - 5% { opacity: 1; } - 17% { opacity: 1; -webkit-transform: rotate(0deg); } - 19% { opacity: 1; -webkit-transform: rotate(98deg); } - 21% { opacity: 1; -webkit-transform: rotate(86deg); } - 23% { opacity: 1; -webkit-transform: translateY(85px) rotate(83deg); } - 25% { opacity: 0; -webkit-transform: translateY(170px) rotate(80deg); } - 80% { opacity: 0; } - 100% { opacity: 0; } -} -@-ms-keyframes rotateWord { - 0% { opacity: 0; } - 5% { opacity: 1; } - 17% { opacity: 1; -ms-transform: rotate(0deg); } - 19% { opacity: 1; -ms-transform: rotate(98deg); } - 21% { opacity: 1; -ms-transform: rotate(86deg); } - 23% { opacity: 1; -ms-transform: translateY(85px) rotate(83deg); } - 25% { opacity: 0; -ms-transform: translateY(170px) rotate(80deg); } - 80% { opacity: 0; } - 100% { opacity: 0; } -} -@keyframes rotateWord { - 0% { opacity: 0; } - 5% { opacity: 1; } - 17% { opacity: 1; -webkit-transform: rotate(0deg); transform: rotate(0deg); } - 19% { opacity: 1; -webkit-transform: rotate(98deg); transform: rotate(98deg); } - 21% { opacity: 1; -webkit-transform: rotate(86deg); transform: rotate(86deg); } - 23% { opacity: 1; -webkit-transform: translateY(85px) rotate(83deg); transform: translateY(85px) rotate(83deg); } - 25% { opacity: 0; -webkit-transform: translateY(170px) rotate(80deg); transform: translateY(170px) rotate(80deg); } - 80% { opacity: 0; } - 100% { opacity: 0; } -} -@media screen and (max-width: 768px){ - .rw-sentence { font-size: 18px; } -} -@media screen and (max-width: 320px){ - .rw-sentence { font-size: 9px; } -} - -.button { - position: absolute; - display: inline-block; - padding: 0.5em 1em; - border: 0.5px solid #d4d4d4; - margin: 0; - text-decoration: none; - text-align: center; - text-shadow: 1px 1px 0 #fff; - font:11px/normal sans-serif; - color: #333; - white-space: nowrap; - cursor: pointer; - outline: none; - background-color: #ececec; - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f4f4f4), to(#ececec)); - background-image: -moz-linear-gradient(#f4f4f4, #ececec); - background-image: -ms-linear-gradient(#f4f4f4, #ececec); - background-image: -o-linear-gradient(#f4f4f4, #ececec); - background-image: linear-gradient(#f4f4f4, #ececec); - -moz-background-clip: padding; /* for Firefox 3.6 */ - background-clip: padding-box; - border-radius: 0.2em; - /* IE hacks */ - zoom: 1; - *display: inline; -} - -.button:hover, -.button:focus, -.button:active, -.button.active { - border-color: #3072b3; - border-bottom-color: #2a65a0; - text-decoration: none; - text-shadow: -1px -1px 0 rgba(0,0,0,0.3); - color: #fff; - background-color: #3c8dde; - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#599bdc), to(#3072b3)); - background-image: -moz-linear-gradient(#599bdc, #3072b3); - background-image: -o-linear-gradient(#599bdc, #3072b3); - background-image: linear-gradient(#599bdc, #3072b3); -} - -.button:active, -.button.active { - border-color: #2a65a0; - border-bottom-color: #3884cd; - background-color: #3072b3; - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#3072b3), to(#599bdc)); - background-image: -moz-linear-gradient(#3072b3, #599bdc); - background-image: -ms-linear-gradient(#3072b3, #599bdc); - background-image: -o-linear-gradient(#3072b3, #599bdc); - background-image: linear-gradient(#3072b3, #599bdc); -} - -/* overrides extra padding on button elements in Firefox */ -.button::-moz-focus-inner { - padding: 0; - border: 0; -} - -/* Pill button 搜索删除按钮 - ========================================================================== */ - -.button.pill { - border-radius: 50em; -} \ No newline at end of file diff --git a/source/plugins/heart/images/web_heart_animation.png b/source/plugins/heart/images/web_heart_animation.png deleted file mode 100644 index bd904374..00000000 Binary files a/source/plugins/heart/images/web_heart_animation.png and /dev/null differ diff --git a/source/plugins/heart/style.css b/source/plugins/heart/style.css deleted file mode 100644 index 1c644359..00000000 --- a/source/plugins/heart/style.css +++ /dev/null @@ -1,112 +0,0 @@ - .heart { - background: url(./images/web_heart_animation.png); - height: 58px; - width: 70px; - margin-top:-20px; - cursor: pointer; - position: absolute; - } - .heart:hover, .heart:focus{ - background-position: right; - } - - @-webkit-keyframes heartBlast { - 0% { - background-position: left; - } - 100% { - background-position: right; - } - } - - @keyframes heartBlast { - 0% { - background-position: left; - } - 100% { - background-position: right; - } - } - - .heartAnimation { - display: inline-block; - -webkit-animation-name: heartBlast; - animation-name: heartBlast; - -webkit-animation-duration: .8s; - animation-duration: .8s; - -webkit-animation-iteration-count: 1; - animation-iteration-count: 1; - -webkit-animation-timing-function: steps(28); - animation-timing-function: steps(28); - background-position: right; - } - .likeCount{font-family: 'Georgia', Times, Times New Roman, serif; margin-top: 32px;margin-left: 68px;font-size: 25px;color: #999999} - -.button { - position: absolute; - display: inline-block; - padding: 0.5em 1em; - border: 0.5px solid #d4d4d4; - margin: 0; - text-decoration: none; - text-align: center; - text-shadow: 1px 1px 0 #fff; - font:11px/normal sans-serif; - color: #333; - white-space: nowrap; - cursor: pointer; - outline: none; - background-color: #ececec; - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f4f4f4), to(#ececec)); - background-image: -moz-linear-gradient(#f4f4f4, #ececec); - background-image: -ms-linear-gradient(#f4f4f4, #ececec); - background-image: -o-linear-gradient(#f4f4f4, #ececec); - background-image: linear-gradient(#f4f4f4, #ececec); - -moz-background-clip: padding; /* for Firefox 3.6 */ - background-clip: padding-box; - border-radius: 0.2em; - /* IE hacks */ - zoom: 1; - *display: inline; -} - -.button:hover, -.button:focus, -.button:active, -.button.active { - border-color: #3072b3; - border-bottom-color: #2a65a0; - text-decoration: none; - text-shadow: -1px -1px 0 rgba(0,0,0,0.3); - color: #fff; - background-color: #3c8dde; - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#599bdc), to(#3072b3)); - background-image: -moz-linear-gradient(#599bdc, #3072b3); - background-image: -o-linear-gradient(#599bdc, #3072b3); - background-image: linear-gradient(#599bdc, #3072b3); -} - -.button:active, -.button.active { - border-color: #2a65a0; - border-bottom-color: #3884cd; - background-color: #3072b3; - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#3072b3), to(#599bdc)); - background-image: -moz-linear-gradient(#3072b3, #599bdc); - background-image: -ms-linear-gradient(#3072b3, #599bdc); - background-image: -o-linear-gradient(#3072b3, #599bdc); - background-image: linear-gradient(#3072b3, #599bdc); -} - -/* overrides extra padding on button elements in Firefox */ -.button::-moz-focus-inner { - padding: 0; - border: 0; -} - -/* Pill button 搜索删除按钮 - ========================================================================== */ - -.button.pill { - border-radius: 50em; -} diff --git a/source/plugins/hint/hint.min.css b/source/plugins/hint/hint.min.css deleted file mode 100644 index 286697b6..00000000 --- a/source/plugins/hint/hint.min.css +++ /dev/null @@ -1,5 +0,0 @@ -/*! Hint.css - v0.1.0 - 2013-02-03 -* https://github.com/chinchang/hint.css -* Copyright (c) 2013 Kushagra Gour; Licensed MIT */ - -.hint{position:relative;display:inline-block}.hint:before,.hint:after{position:absolute;opacity:0;z-index:1000000;pointer-events:none;-webkit-transition:.3s ease;-moz-transition:.3s ease}.hint:hover:before,.hint:hover:after{opacity:1}.hint:before{content:'';position:absolute;background:transparent;border:6px solid transparent;z-index:1000001}.hint:after{content:attr(data-hint);background:#383838;color:#fff;text-shadow:0 -1px 0 black;padding:8px 10px;font-size:12px;line-height:12px;white-space:nowrap;box-shadow:4px 4px 8px rgba(0,0,0,.3)}.hint--top:before{border-top-color:#383838}.hint--bottom:before{border-bottom-color:#383838}.hint--left:before{border-left-color:#383838}.hint--right:before{border-right-color:#383838}.hint--top:before{margin-bottom:-12px}.hint--top:after{margin-left:-18px}.hint--top:before,.hint--top:after{bottom:100%;left:50%}.hint--top:hover:before,.hint--top:hover:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--bottom:before{margin-top:-12px}.hint--bottom:after{margin-left:-18px}.hint--bottom:before,.hint--bottom:after{top:100%;left:50%}.hint--bottom:hover:before,.hint--bottom:hover:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--right:before{margin-left:-12px;margin-bottom:-6px}.hint--right:after{margin-bottom:-14px}.hint--right:before,.hint--right:after{left:100%;bottom:50%}.hint--right:hover:before,.hint--right:hover:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translateX(8px)}.hint--left:before{margin-right:-12px;margin-bottom:-6px}.hint--left:after{margin-bottom:-14px}.hint--left:before,.hint--left:after{right:100%;bottom:50%}.hint--left:hover:before,.hint--left:hover:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translateX(-8px)}.hint--error:after{background-color:#b34e4d;text-shadow:0 -1px 0 #5a2626}.hint--error.hint--top:before{border-top-color:#b34e4d}.hint--error.hint--bottom:before{border-bottom-color:#b34e4d}.hint--error.hint--left:before{border-left-color:#b34e4d}.hint--error.hint--right:before{border-right-color:#b34e4d}.hint--warning:after{background-color:#c09854;text-shadow:0 -1px 0 #6d5228}.hint--warning.hint--top:before{border-top-color:#c09854}.hint--warning.hint--bottom:before{border-bottom-color:#c09854}.hint--warning.hint--left:before{border-left-color:#c09854}.hint--warning.hint--right:before{border-right-color:#c09854}.hint--info:after{background-color:#3986ac;text-shadow:0 -1px 0 #193c4c}.hint--info.hint--top:before{border-top-color:#3986ac}.hint--info.hint--bottom:before{border-bottom-color:#3986ac}.hint--info.hint--left:before{border-left-color:#3986ac}.hint--info.hint--right:before{border-right-color:#3986ac}.hint--success:after{background-color:#458746;text-shadow:0 -1px 0 #1a331a}.hint--success.hint--top:before{border-top-color:#458746}.hint--success.hint--bottom:before{border-bottom-color:#458746}.hint--success.hint--left:before{border-left-color:#458746}.hint--success.hint--right:before{border-right-color:#458746}.hint--always:after,.hint--always:before{opacity:1}.hint--always.hint--top:after,.hint--always.hint--top:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--always.hint--bottom:after,.hint--always.hint--bottom:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--always.hint--left:after,.hint--always.hint--left:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translateX(-8px)}.hint--always.hint--right:after,.hint--always.hint--right:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translateX(8px)} \ No newline at end of file diff --git a/source/plugins/images/bottom.png b/source/plugins/images/bottom.png deleted file mode 100644 index ec9a0067..00000000 Binary files a/source/plugins/images/bottom.png and /dev/null differ diff --git a/source/plugins/images/clock.png b/source/plugins/images/clock.png deleted file mode 100644 index 0ee90f78..00000000 Binary files a/source/plugins/images/clock.png and /dev/null differ diff --git a/source/plugins/images/date.png b/source/plugins/images/date.png deleted file mode 100644 index 7c25cec9..00000000 Binary files a/source/plugins/images/date.png and /dev/null differ diff --git a/source/plugins/images/footprint.png b/source/plugins/images/footprint.png deleted file mode 100644 index b762efb3..00000000 Binary files a/source/plugins/images/footprint.png and /dev/null differ diff --git a/source/plugins/images/icons.png b/source/plugins/images/icons.png deleted file mode 100644 index f84f128d..00000000 Binary files a/source/plugins/images/icons.png and /dev/null differ diff --git a/source/plugins/images/icons2.png b/source/plugins/images/icons2.png deleted file mode 100644 index c785edb8..00000000 Binary files a/source/plugins/images/icons2.png and /dev/null differ diff --git a/source/plugins/images/icons3.png b/source/plugins/images/icons3.png deleted file mode 100644 index 6b907e10..00000000 Binary files a/source/plugins/images/icons3.png and /dev/null differ diff --git a/source/plugins/images/point.png b/source/plugins/images/point.png deleted file mode 100644 index 1fd7b5fc..00000000 Binary files a/source/plugins/images/point.png and /dev/null differ diff --git a/source/plugins/images/top.png b/source/plugins/images/top.png deleted file mode 100644 index b64eabc3..00000000 Binary files a/source/plugins/images/top.png and /dev/null differ diff --git a/source/plugins/images/vertical.png b/source/plugins/images/vertical.png deleted file mode 100644 index db90c1e5..00000000 Binary files a/source/plugins/images/vertical.png and /dev/null differ diff --git a/source/plugins/js/easying.js b/source/plugins/js/easying.js deleted file mode 100644 index ef743210..00000000 --- a/source/plugins/js/easying.js +++ /dev/null @@ -1,205 +0,0 @@ -/* - * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ - * - * Uses the built in easing capabilities added In jQuery 1.1 - * to offer multiple easing options - * - * TERMS OF USE - jQuery Easing - * - * Open source under the BSD License. - * - * Copyright © 2008 George McGinley Smith - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * Neither the name of the author nor the names of contributors may be used to endorse - * or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - -// t: current time, b: begInnIng value, c: change In value, d: duration -jQuery.easing['jswing'] = jQuery.easing['swing']; - -jQuery.extend( jQuery.easing, -{ - def: 'easeOutQuad', - swing: function (x, t, b, c, d) { - //alert(jQuery.easing.default); - return jQuery.easing[jQuery.easing.def](x, t, b, c, d); - }, - easeInQuad: function (x, t, b, c, d) { - return c*(t/=d)*t + b; - }, - easeOutQuad: function (x, t, b, c, d) { - return -c *(t/=d)*(t-2) + b; - }, - easeInOutQuad: function (x, t, b, c, d) { - if ((t/=d/2) < 1) return c/2*t*t + b; - return -c/2 * ((--t)*(t-2) - 1) + b; - }, - easeInCubic: function (x, t, b, c, d) { - return c*(t/=d)*t*t + b; - }, - easeOutCubic: function (x, t, b, c, d) { - return c*((t=t/d-1)*t*t + 1) + b; - }, - easeInOutCubic: function (x, t, b, c, d) { - if ((t/=d/2) < 1) return c/2*t*t*t + b; - return c/2*((t-=2)*t*t + 2) + b; - }, - easeInQuart: function (x, t, b, c, d) { - return c*(t/=d)*t*t*t + b; - }, - easeOutQuart: function (x, t, b, c, d) { - return -c * ((t=t/d-1)*t*t*t - 1) + b; - }, - easeInOutQuart: function (x, t, b, c, d) { - if ((t/=d/2) < 1) return c/2*t*t*t*t + b; - return -c/2 * ((t-=2)*t*t*t - 2) + b; - }, - easeInQuint: function (x, t, b, c, d) { - return c*(t/=d)*t*t*t*t + b; - }, - easeOutQuint: function (x, t, b, c, d) { - return c*((t=t/d-1)*t*t*t*t + 1) + b; - }, - easeInOutQuint: function (x, t, b, c, d) { - if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; - return c/2*((t-=2)*t*t*t*t + 2) + b; - }, - easeInSine: function (x, t, b, c, d) { - return -c * Math.cos(t/d * (Math.PI/2)) + c + b; - }, - easeOutSine: function (x, t, b, c, d) { - return c * Math.sin(t/d * (Math.PI/2)) + b; - }, - easeInOutSine: function (x, t, b, c, d) { - return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; - }, - easeInExpo: function (x, t, b, c, d) { - return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b; - }, - easeOutExpo: function (x, t, b, c, d) { - return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; - }, - easeInOutExpo: function (x, t, b, c, d) { - if (t==0) return b; - if (t==d) return b+c; - if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; - return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; - }, - easeInCirc: function (x, t, b, c, d) { - return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; - }, - easeOutCirc: function (x, t, b, c, d) { - return c * Math.sqrt(1 - (t=t/d-1)*t) + b; - }, - easeInOutCirc: function (x, t, b, c, d) { - if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; - return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; - }, - easeInElastic: function (x, t, b, c, d) { - var s=1.70158;var p=0;var a=c; - if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; - if (a < Math.abs(c)) { a=c; var s=p/4; } - else var s = p/(2*Math.PI) * Math.asin (c/a); - return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; - }, - easeOutElastic: function (x, t, b, c, d) { - var s=1.70158;var p=0;var a=c; - if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; - if (a < Math.abs(c)) { a=c; var s=p/4; } - else var s = p/(2*Math.PI) * Math.asin (c/a); - return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b; - }, - easeInOutElastic: function (x, t, b, c, d) { - var s=1.70158;var p=0;var a=c; - if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); - if (a < Math.abs(c)) { a=c; var s=p/4; } - else var s = p/(2*Math.PI) * Math.asin (c/a); - if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; - return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b; - }, - easeInBack: function (x, t, b, c, d, s) { - if (s == undefined) s = 1.70158; - return c*(t/=d)*t*((s+1)*t - s) + b; - }, - easeOutBack: function (x, t, b, c, d, s) { - if (s == undefined) s = 1.70158; - return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; - }, - easeInOutBack: function (x, t, b, c, d, s) { - if (s == undefined) s = 1.70158; - if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; - return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; - }, - easeInBounce: function (x, t, b, c, d) { - return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b; - }, - easeOutBounce: function (x, t, b, c, d) { - if ((t/=d) < (1/2.75)) { - return c*(7.5625*t*t) + b; - } else if (t < (2/2.75)) { - return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; - } else if (t < (2.5/2.75)) { - return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; - } else { - return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; - } - }, - easeInOutBounce: function (x, t, b, c, d) { - if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b; - return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b; - } -}); - -/* - * - * TERMS OF USE - EASING EQUATIONS - * - * Open source under the BSD License. - * - * Copyright © 2001 Robert Penner - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * Neither the name of the author nor the names of contributors may be used to endorse - * or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ \ No newline at end of file diff --git a/source/plugins/js/gotop.js b/source/plugins/js/gotop.js deleted file mode 100644 index ba7d9f93..00000000 --- a/source/plugins/js/gotop.js +++ /dev/null @@ -1,66 +0,0 @@ - -var bigfa_scroll = { - drawCircle: function(id, percentage, color) { - var button = $(id) - var width = button.width(); - var height = button.height(); - var radius = parseInt(width / 2.20); - var position = width; - var positionBy2 = position / 2; - var bg = button[0]; - id = id.split("#"); - var ctx = bg.getContext("2d"); - var imd = null; - var circ = Math.PI * 2; - var quart = Math.PI / 2; - ctx.clearRect(0, 0, width, height); - ctx.beginPath(); - ctx.strokeStyle = color; - ctx.lineCap = "square"; - ctx.closePath(); - ctx.fill(); - ctx.lineWidth = 3; - imd = ctx.getImageData(0, 0, position, position); - var draw = function(current, ctxPass) { - ctxPass.putImageData(imd, 0, 0); - ctxPass.beginPath(); - ctxPass.arc(positionBy2, positionBy2, radius, -(quart), ((circ) * current) - quart, false); - ctxPass.stroke(); - } - draw(percentage / 100, ctx); - }, - backToTop: function($this) { - $this.click(function() { - jQuery("body,html").animate({ - scrollTop: '0px' - }, - 800); - return false; - }); - }, - scrollHook: function($this, color) { - color = color ? color: "#000000"; - $this.scroll(function() { - var docHeight = (jQuery(document).height() - jQuery(window).height()), - $windowObj = $this, - $per = jQuery(".per"), - percentage = 0; - defaultScroll = $windowObj.scrollTop(); - percentage = parseInt((defaultScroll / docHeight) * 100); - var backToTop = jQuery("#backtoTop"); - if (backToTop.length > 0) { - if ($windowObj.scrollTop() > 0) { - backToTop.addClass("button--show"); - } else { - backToTop.removeClass("button--show"); - } - if (document.body.clientWidth < 1111) { - backToTop.removeClass("button--show"); - } - $per.attr("data-percent", percentage); - bigfa_scroll.drawCircle("#backtoTopCanvas", percentage, color); - } - - }); - } - } diff --git a/source/plugins/js/history.js b/source/plugins/js/history.js deleted file mode 100644 index 138d1cad..00000000 --- a/source/plugins/js/history.js +++ /dev/null @@ -1,112 +0,0 @@ -(function(e){ - function b(a){ - a=a.replace(/left|top/g,"0px"); - a=a.replace(/right|bottom/g,"100%"); - a=a.replace(/([0-9\.]+)(\s|\)|$)/g,"$1px$2"); - a=a.match(/(-?[0-9\.]+)(px|\%|em|pt)\s(-?[0-9\.]+)(px|\%|em|pt)/); - return[parseFloat(a[1],10),a[2],parseFloat(a[3],10),a[4]]} - if(!document.defaultView||!document.defaultView.getComputedStyle){ - var f=e.curCSS; - e.curCSS=function(a,c,b){ - "background-position"===c&&(c="backgroundPosition"); - if("backgroundPosition"!==c||!a.currentStyle||a.currentStyle[c]) - return f.apply(this, arguments); - var g=a.style; - return!b&&g&&g[c]?g[c]:f(a,"backgroundPositionX",b)+" "+f(a,"backgroundPositionY",b) - } - } - var d=e.fn.animate; - e.fn.animate=function(a){ - "background-position"in a&&(a.backgroundPosition=a["background-position"],delete a["background-position"]); - "backgroundPosition"in a&&(a.backgroundPosition="("+a.backgroundPosition); - return d.apply(this,arguments) - }; - e.fx.step.backgroundPosition=function(a){ - if(!a.bgPosReady){ - var c=e.curCSS(a.elem,"backgroundPosition"); - c||(c="0px 0px");c=b(c);a.start= [c[0],c[2]]; - c=b(a.end); - a.end=[c[0],c[2]]; - a.unit=[c[1],c[3]]; - a.bgPosReady=!0}c=[]; - c[0]=(a.end[0]-a.start[0])*a.pos+a.start[0]+a.unit[0]; - c[1]=(a.end[1]-a.start[1])*a.pos+a.start[1]+a.unit[1]; - a.elem.style.backgroundPosition=c[0]+" "+c[1] - } - } -)(jQuery); - -(function(e){e.extend(e.fx.step,{ - backgroundPosition:function(b){ - function f(a){ - a=a.replace(/left|top/g,"0px"); - a=a.replace(/right|bottom/g,"100%"); - a=a.replace(/([0-9\.]+)(\s|\)|$)/g,"$1px$2"); - a=a.match(/(-?[0-9\.]+)(px|\%|em|pt)\s(-?[0-9\.]+)(px|\%|em|pt)/); - return[parseFloat(a[1],10),a[2],parseFloat(a[3],10),a[4]] - } - if(0===b.state&&"string"==typeof b.end){ - var d=e.curCSS(b.elem,"backgroundPosition"),d=f(d); - b.start=[d[0],d[2]];d=f(b.end);b.end=[d[0],d[2]]; - b.unit=[d[1],d[3]]}d=[]; - d[0]=(b.end[0]-b.start[0])* b.pos+b.start[0]+b.unit[0]; - d[1]=(b.end[1]-b.start[1])*b.pos+b.start[1]+b.unit[1]; - b.elem.style.backgroundPosition=d[0]+" "+d[1] - } - } -)})(jQuery); - -$(function(){ - function e(){ - c=$(".list li").eq(d).find(".year").html(); - $(".timeblock").attr("thisyear",c); - var a=c.split(""),b=["numf","nums","numt","numfo"]; - for(i=0;4>i;i++) - $("."+b[i]+"").stop(!0,!1).animate({backgroundPosition:"0px "+-24*a[i]},{duration:200})} - $(".list .liwrap").mouseover(function(){ - $(".list li").removeClass("thiscur"); - $(this).parent().addClass("thiscur") - }); - var b=0,f=$(".list li").length,d=0,a=!0,c; - (function(){//row控制竖线上小圆点个数 - var a=$(window).height(); - 890<=a&&(row=7); - 800<=a&&890>a&&(row=6); - 726<=a&& 800>a&&(row=5); - 726>a&&(row=4)} - )(); - var h=f-row; - $(".list").height(110*row); - $("#content").height(110*row+25); - $.fn.liOut=function(){ - $(this).find(".lileft").animate({left:"-400px"},500,"easeOutQuart"); - $(this).find(".liright").animate({right:"-700px"},500,"easeOutQuart") - }; - $.fn.liIn=function(){ - $(this).find(".lileft").animate({left:"0px"},500,"easeOutQuart"); - $(this).find(".liright").animate({right:"0px"},500,"easeOutQuart") - }; - $(".arrowdown").click(function(){ - a&&parseInt($(".list li:first").css("marginTop"))> -110*h&&(d++,b--,a=!1,$(".list li").eq(d-1).liOut(),$(".list li").eq(d+row-1).liIn(),$(".list li:first").animate({marginTop:110*b},600,"easeInOutQuad",function(){ - a=!0;$(".arrowdown").css("opacity",1); - $(".arrowdown").removeClass("arrow_active") - }),e() - )}); - $(".arrowup").click(function(){ - a&&0!=parseInt($(".list li:first").css("marginTop"))&&(b++,d--,a=!1,$(".list li").eq(d).liIn(),$(".list li").eq(d+row).liOut(),$(".list li:first").animate({marginTop:110*b},600,"easeInOutQuad",function(){ - a=!0;$(".arrowup").css("opacity", 1); - $(".arrowup").removeClass("arrow_active") - }),e() - )}); - $(".list").mousewheel(function(b,c){ - Math.abs(c); - if(a){ - var d=parseInt($(".list li:first").css("marginTop")); - 0-110*h&&($(".arrowdown").addClass("arrow_active"),$(".arrowdown").trigger("click")) - } - }); - $(".timeblock").attr("thisyear",c); - $(".list li:gt("+(row-1)+")").find(".lileft").css({left:"-400px"}); - $(".list li:gt("+(row-1)+")").find(".liright").css({right:"-700px"}); - -}); \ No newline at end of file diff --git a/source/plugins/js/jquery.bumpytext.packed.js b/source/plugins/js/jquery.bumpytext.packed.js deleted file mode 100644 index 90e58e1c..00000000 --- a/source/plugins/js/jquery.bumpytext.packed.js +++ /dev/null @@ -1,14 +0,0 @@ -/* - * bumpyText 1.1 - jQuery plugin for making characters in a text element bumpy. - * http://www.alexanderdickson.com/projects/jquery-plugins/bumpytext/ - * - * Dependicies: jQuery Easing Plugin (http://gsgd.co.uk/sandbox/jquery/easing/) - * - * Copyright (c) 2009 Alex Dickson - * Licensed under the MIT licenses. - * See website for more info. - * - * Date: 2009-08-30 09:03:00 +1000 (Sunday, 23 Aug 2009) - */ - -eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('(4($){$.t.w=4(5){2 e={h:\'1.x\',n:v,l:u,};2 5=$.y(e,5);d 6.c(4(){2 3=$(6);z(3.7()!==3.g()){d};2 7=3.7();2 a=\'\';r(2 i=0;i<=7.s;i++){2 8=7.F(i,i+1);a+=($.I(8))?\'<9 H="f-b">\'+8+\'\':8}3.g(a);3.A(\'9.f-b\').c(4(){$(6).B(4(){$(6).p({q:5.h},{o:j,k:5.n,m:\'C\',D:4(){$(6).p({q:0},{o:j,k:5.l,m:\'E\'})}})})})})}})(G);',45,45,'||var|obj|function|options|this|text|character|span|newMarkup|char|each|return|defaults|bumpy|html|bounceHeight||false|duration|bounceDownDuration|easing|bounceUpDuration|queue|animate|bottom|for|length|fn|700|500|bumpyText|3em|extend|if|find|mouseover|easeOutCubic|complete|easeOutBounce|slice|jQuery|class|trim'.split('|'),0,{})) diff --git a/source/plugins/js/jquery.easing.js b/source/plugins/js/jquery.easing.js deleted file mode 100644 index 83a43249..00000000 --- a/source/plugins/js/jquery.easing.js +++ /dev/null @@ -1,44 +0,0 @@ -/* - * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ - * - * Uses the built in easing capabilities added In jQuery 1.1 - * to offer multiple easing options - * - * TERMS OF USE - EASING EQUATIONS - * - * Open source under the BSD License. - * - * Copyright © 2001 Robert Penner - * All rights reserved. - * - * TERMS OF USE - jQuery Easing - * - * Open source under the BSD License. - * - * Copyright © 2008 George McGinley Smith - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * Neither the name of the author nor the names of contributors may be used to endorse - * or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ -jQuery.easing.jswing=jQuery.easing.swing;jQuery.extend(jQuery.easing,{def:"easeOutQuad",swing:function(e,f,a,h,g){return jQuery.easing[jQuery.easing.def](e,f,a,h,g)},easeInQuad:function(e,f,a,h,g){return h*(f/=g)*f+a},easeOutQuad:function(e,f,a,h,g){return -h*(f/=g)*(f-2)+a},easeInOutQuad:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f+a}return -h/2*((--f)*(f-2)-1)+a},easeInCubic:function(e,f,a,h,g){return h*(f/=g)*f*f+a},easeOutCubic:function(e,f,a,h,g){return h*((f=f/g-1)*f*f+1)+a},easeInOutCubic:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f*f+a}return h/2*((f-=2)*f*f+2)+a},easeInQuart:function(e,f,a,h,g){return h*(f/=g)*f*f*f+a},easeOutQuart:function(e,f,a,h,g){return -h*((f=f/g-1)*f*f*f-1)+a},easeInOutQuart:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f*f*f+a}return -h/2*((f-=2)*f*f*f-2)+a},easeInQuint:function(e,f,a,h,g){return h*(f/=g)*f*f*f*f+a},easeOutQuint:function(e,f,a,h,g){return h*((f=f/g-1)*f*f*f*f+1)+a},easeInOutQuint:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f*f*f*f+a}return h/2*((f-=2)*f*f*f*f+2)+a},easeInSine:function(e,f,a,h,g){return -h*Math.cos(f/g*(Math.PI/2))+h+a},easeOutSine:function(e,f,a,h,g){return h*Math.sin(f/g*(Math.PI/2))+a},easeInOutSine:function(e,f,a,h,g){return -h/2*(Math.cos(Math.PI*f/g)-1)+a},easeInExpo:function(e,f,a,h,g){return(f==0)?a:h*Math.pow(2,10*(f/g-1))+a},easeOutExpo:function(e,f,a,h,g){return(f==g)?a+h:h*(-Math.pow(2,-10*f/g)+1)+a},easeInOutExpo:function(e,f,a,h,g){if(f==0){return a}if(f==g){return a+h}if((f/=g/2)<1){return h/2*Math.pow(2,10*(f-1))+a}return h/2*(-Math.pow(2,-10*--f)+2)+a},easeInCirc:function(e,f,a,h,g){return -h*(Math.sqrt(1-(f/=g)*f)-1)+a},easeOutCirc:function(e,f,a,h,g){return h*Math.sqrt(1-(f=f/g-1)*f)+a},easeInOutCirc:function(e,f,a,h,g){if((f/=g/2)<1){return -h/2*(Math.sqrt(1-f*f)-1)+a}return h/2*(Math.sqrt(1-(f-=2)*f)+1)+a},easeInElastic:function(f,h,e,l,k){var i=1.70158;var j=0;var g=l;if(h==0){return e}if((h/=k)==1){return e+l}if(!j){j=k*0.3}if(g)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/, -Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&& -(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this, -a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b=== -"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this, -function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b
a"; -var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected, -parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent= -false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n= -s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true, -applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando]; -else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this, -a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b=== -w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i, -cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected= -c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed"); -a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g, -function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split("."); -k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a), -C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B=0){a.type= -e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&& -f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive; -if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data", -e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a, -"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a, -d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, -e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift(); -t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D|| -g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()}, -CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m, -g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)}, -text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}}, -setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return hl[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h= -h[3];l=0;for(m=h.length;l=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m=== -"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g, -h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&& -q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML=""; -if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="

";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}(); -(function(){var g=s.createElement("div");g.innerHTML="
";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}: -function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f0)for(var j=d;j0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j= -{},i;if(f&&a.length){e=0;for(var o=a.length;e-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a=== -"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode", -d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")? -a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType=== -1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/"},F={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div
","
"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d= -c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, -wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})}, -prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b, -this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild); -return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja, -""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]); -return this}else{e=0;for(var j=d.length;e0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["", -""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]===""&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e= -c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]? -c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja= -function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter= -Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a, -"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f= -a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b= -a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=//gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!== -"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("
").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this}, -serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), -function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href, -global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&& -e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)? -"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache=== -false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B= -false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since", -c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E|| -d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x); -g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status=== -1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b=== -"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional; -if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration=== -"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]|| -c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start; -this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now= -this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem, -e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b
"; -a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b); -c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a, -d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top- -f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset": -"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in -e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window); diff --git a/source/plugins/js/jquery.lazyload.min.js b/source/plugins/js/jquery.lazyload.min.js deleted file mode 100644 index 04038071..00000000 --- a/source/plugins/js/jquery.lazyload.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! Lazy Load 1.9.7 - MIT license - Copyright 2010-2015 Mika Tuupola */ -!function(a,b,c,d){var e=a(b);a.fn.lazyload=function(f){function g(){var b=0;i.each(function(){var c=a(this);if(!j.skip_invisible||c.is(":visible"))if(a.abovethetop(this,j)||a.leftofbegin(this,j));else if(a.belowthefold(this,j)||a.rightoffold(this,j)){if(++b>j.failure_limit)return!1}else c.trigger("appear"),b=0})}var h,i=this,j={threshold:0,failure_limit:0,event:"scroll",effect:"show",container:b,data_attribute:"original",skip_invisible:!1,appear:null,load:null,placeholder:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"};return f&&(d!==f.failurelimit&&(f.failure_limit=f.failurelimit,delete f.failurelimit),d!==f.effectspeed&&(f.effect_speed=f.effectspeed,delete f.effectspeed),a.extend(j,f)),h=j.container===d||j.container===b?e:a(j.container),0===j.event.indexOf("scroll")&&h.bind(j.event,function(){return g()}),this.each(function(){var b=this,c=a(b);b.loaded=!1,(c.attr("src")===d||c.attr("src")===!1)&&c.is("img")&&c.attr("src",j.placeholder),c.one("appear",function(){if(!this.loaded){if(j.appear){var d=i.length;j.appear.call(b,d,j)}a("").bind("load",function(){var d=c.attr("data-"+j.data_attribute);c.hide(),c.is("img")?c.attr("src",d):c.css("background-image","url('"+d+"')"),c[j.effect](j.effect_speed),b.loaded=!0;var e=a.grep(i,function(a){return!a.loaded});if(i=a(e),j.load){var f=i.length;j.load.call(b,f,j)}}).attr("src",c.attr("data-"+j.data_attribute))}}),0!==j.event.indexOf("scroll")&&c.bind(j.event,function(){b.loaded||c.trigger("appear")})}),e.bind("resize",function(){g()}),/(?:iphone|ipod|ipad).*os 5/gi.test(navigator.appVersion)&&e.bind("pageshow",function(b){b.originalEvent&&b.originalEvent.persisted&&i.each(function(){a(this).trigger("appear")})}),a(c).ready(function(){g()}),this},a.belowthefold=function(c,f){var g;return g=f.container===d||f.container===b?(b.innerHeight?b.innerHeight:e.height())+e.scrollTop():a(f.container).offset().top+a(f.container).height(),g<=a(c).offset().top-f.threshold},a.rightoffold=function(c,f){var g;return g=f.container===d||f.container===b?e.width()+e.scrollLeft():a(f.container).offset().left+a(f.container).width(),g<=a(c).offset().left-f.threshold},a.abovethetop=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollTop():a(f.container).offset().top,g>=a(c).offset().top+f.threshold+a(c).height()},a.leftofbegin=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollLeft():a(f.container).offset().left,g>=a(c).offset().left+f.threshold+a(c).width()},a.inviewport=function(b,c){return!(a.rightoffold(b,c)||a.leftofbegin(b,c)||a.belowthefold(b,c)||a.abovethetop(b,c))},a.extend(a.expr[":"],{"below-the-fold":function(b){return a.belowthefold(b,{threshold:0})},"above-the-top":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-screen":function(b){return a.rightoffold(b,{threshold:0})},"left-of-screen":function(b){return!a.rightoffold(b,{threshold:0})},"in-viewport":function(b){return a.inviewport(b,{threshold:0})},"above-the-fold":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-fold":function(b){return a.rightoffold(b,{threshold:0})},"left-of-fold":function(b){return!a.rightoffold(b,{threshold:0})}})}(jQuery,window,document); \ No newline at end of file diff --git a/source/plugins/js/jquery.mousewheel.js b/source/plugins/js/jquery.mousewheel.js deleted file mode 100644 index 3390202a..00000000 --- a/source/plugins/js/jquery.mousewheel.js +++ /dev/null @@ -1,12 +0,0 @@ -/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net) - * Licensed under the MIT License (LICENSE.txt). - * - * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. - * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. - * Thanks to: Seamus Leahy for adding deltaX and deltaY - * - * Version: 3.0.6 - * - * Requires: 1.2.2+ - */ -(function(a){function d(b){var c=b||window.event,d=[].slice.call(arguments,1),e=0,f=!0,g=0,h=0;return b=a.event.fix(c),b.type="mousewheel",c.wheelDelta&&(e=c.wheelDelta/120),c.detail&&(e=-c.detail/3),h=e,c.axis!==undefined&&c.axis===c.HORIZONTAL_AXIS&&(h=0,g=-1*e),c.wheelDeltaY!==undefined&&(h=c.wheelDeltaY/120),c.wheelDeltaX!==undefined&&(g=-1*c.wheelDeltaX/120),d.unshift(b,e,g,h),(a.event.dispatch||a.event.handle).apply(this,d)}var b=["DOMMouseScroll","mousewheel"];if(a.event.fixHooks)for(var c=b.length;c;)a.event.fixHooks[b[--c]]=a.event.mouseHooks;a.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=b.length;a;)this.addEventListener(b[--a],d,!1);else this.onmousewheel=d},teardown:function(){if(this.removeEventListener)for(var a=b.length;a;)this.removeEventListener(b[--a],d,!1);else this.onmousewheel=null}},a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery) diff --git a/source/plugins/js/scrollHighlight.js b/source/plugins/js/scrollHighlight.js deleted file mode 100644 index 3aecb127..00000000 --- a/source/plugins/js/scrollHighlight.js +++ /dev/null @@ -1,163 +0,0 @@ -//插件名字:scrollHighlight(滚动高亮节点插件) -//说明:ngudream基于蔡宝坚原插件做的修改 - -; -(function($) { - $.fn.scrollHighlight = function(options) { - return this.each(function() { - var defualts = { - childItem: "a", //高亮的节点 - attribute: "href", //高亮节点属性 - highlight: 'highlight', //给高亮节点添加的类 - buffer: 0, //距离节点的距离 - cancelFlag: true, //当超过节点时是否取消高亮,默认是取消高亮 - container: window, - mode: 'vertical' //滚动的模式,默认为竖直方向,可以为其他如horizontal(水平方向) - }; - var opts = $.extend({}, defualts, options), - obj = $(this), - mode = opts.mode, - buffer = opts.buffer, - highlight = opts.highlight, - childItem = opts.childItem, - attribute = opts.attribute, - $con = $(opts.container), - $w = $(window); - if (obj.length <= 0) return; - var resizeTimer; // Set resizeTimer to empty so it resets on page load - - var item = obj.find(childItem), - i = 0, - len = item.length, - wrap = [], - index = [], - anchor = []; - for (; i < len; i++) { - anchor.push(item.eq(i).attr(attribute)); //获取需要高亮的所有节点 - } - - var aLen = anchor.length; - for (var j = 0; j < aLen; j++) { - var that = $(anchor[j]);//container中的内容 - if (that.length && that.is(":visible")) { //筛选出容器内存在的节点并且是显示的 - wrap.push(anchor[j]); //将节点放置在数组wrap中 - index.push(j); //筛选出他们的位置 - } - } - - function myOffset(attr){ - //获取元素上边(左边)偏移值 - return (mode == 'vertical') ? $(attr).offset().top : $(attr).offset().left; - } - - var wLen = wrap.length; - // var pos = []; - // for (var i = 0; i < wLen; i++) { - // pos.push(myOffset(wrap[i])); //存储每个节点的偏移值 - // } - - //滚动时的函数 - function onScroll(e) { - var xy = (mode == 'vertical') ? $w.scrollTop() + buffer : $w.scrollLeft() + buffer; - function myOuter(attr){ - //获取元素外部高度(宽度) - return (mode == 'vertical') ? $(attr).offset().top : $(attr).offset().left; - //return (mode == 'vertical') ? $(attr).outerHeight() : $(attr).outerWidth(); - } - function myPos(i) { - //当是垂直(水平)滚动时,滚动高度(宽度)大于它的上边(左边)的偏移值,高亮。 - if (xy >= pos[i]) { - item.eq(index[i]).css("color", "blue"); - } - } - - var $win = $(window); - var visiable = false; - for (var i = 0; i < wLen; i++) { - //方法1 - //myPos(i); //当是垂直(水平)滚动时,获取节点上边(左边)的偏移值,并和滚动高度(宽度)对比,当滚动高度(宽度)大于它的时候,高亮。 - // var sub = 1; - // if(i == (wLen - 1)){ - // sub = 0; - // } - // if (opts.cancelFlag && (xy >= pos[i+sub] || xy < pos[i])) { //当滚动高度(宽度)超过它的位置加上它的高度(宽度)时,取消节点的高亮 - // if(i == wLen - 1){//最后一个 - // if(xy < pos[i]){ - // item.eq(index[i]).css("color", "gray"); - // } - // } else { - // item.eq(index[i]).css("color", "gray"); - // } - // } - - //方法2 - try { - var sub = 1; - if(i == (wLen - 1)){ - sub = 0; - } - var winHeight = $win.height();//是获取当前也就是浏览器所能看到的页面的那部分的高度,这个大小在你缩放浏览器窗口大小时 - var winScrollTop = $win.scrollTop();//获取垂直滚动的距离即当前滚动的地方的窗口顶端到整个页面顶端的距离 - var itemOffsetTop = $(wrap[i]).offset().top;//该元素距离页面顶部的距离 - var itemNextOffsetTop = $(wrap[i+sub]).offset().top;//该元素距离页面顶部的距离 - var itemOuterHeight = $(wrap[i]).outerHeight(true);//元素的高度 - if(opts.cancelFlag){ - if(!(winScrollTop > itemOffsetTop+itemOuterHeight) && !(winScrollTop < itemOffsetTop-winHeight)) { - if(!visiable){//可见区的每一个标题高亮 - item.eq(index[i]).css("color", "blue"); - visiable = true; - } else { - item.eq(index[i]).css("color", "gray"); - } - } else if(i != wLen - 1 && winScrollTop > itemOffsetTop && winScrollTop < (itemNextOffsetTop-itemOuterHeight)){ - if(!visiable){ - item.eq(index[i]).css("color", "blue"); - visiable = true; - } else { - item.eq(index[i]).css("color", "gray"); - } - } else if(i == wLen - 1 && winScrollTop > itemOffsetTop){ - item.eq(index[i]).css("color", "blue"); - } else { - item.eq(index[i]).css("color", "gray"); - } - } - } catch (e) { - - } - } - } - - function is_post(){//根据自己实际需要来判断 - var url = window.location.pathname; - var urlArray = url.split("/"); - if(urlArray.length > 2){ - var id = $(".article").eq(0).attr("id"); - var resultUrl = "post-" + urlArray[urlArray.length - 2]; - if(resultUrl == id){ - return true; - } - } - return false; - } - - // 当有滚动时执行下面代码 - $(window).on("scroll", function() { - if(is_post()){ - clearTimeout(resizeTimer); - resizeTimer = setTimeout(onScroll, 100); - } - }); - // 当发现调整屏幕大小时,重新执行代码 - $(window).on("resize", function() { - if(is_post()){ - clearTimeout(resizeTimer); - resizeTimer = setTimeout(onScroll, 100); - } - }); - if(is_post()){ - resizeTimer = setTimeout(onScroll, 100); - } - }); - }; -})(jQuery); diff --git a/source/plugins/prettify/lang-apollo.js b/source/plugins/prettify/lang-apollo.js deleted file mode 100644 index 10df8cde..00000000 --- a/source/plugins/prettify/lang-apollo.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @license - * Copyright (C) 2009 Onno Hommes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview - * Registers a language handler for the AGC/AEA Assembly Language as described - * at http://virtualagc.googlecode.com - *

- * This file could be used by goodle code to allow syntax highlight for - * Virtual AGC SVN repository or if you don't want to commonize - * the header for the agc/aea html assembly listing. - * - * @author ohommes@alumni.cmu.edu - */ - -PR['registerLangHandler']( - PR['createSimpleLexer']( - [ - // A line comment that starts with ; - [PR['PR_COMMENT'], /^#[^\r\n]*/, null, '#'], - // Whitespace - [PR['PR_PLAIN'], /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'], - // A double quoted, possibly multi-line, string. - [PR['PR_STRING'], /^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/, null, '"'] - ], - [ - [PR['PR_KEYWORD'], /^(?:ADS|AD|AUG|BZF|BZMF|CAE|CAF|CA|CCS|COM|CS|DAS|DCA|DCOM|DCS|DDOUBL|DIM|DOUBLE|DTCB|DTCF|DV|DXCH|EDRUPT|EXTEND|INCR|INDEX|NDX|INHINT|LXCH|MASK|MSK|MP|MSU|NOOP|OVSK|QXCH|RAND|READ|RELINT|RESUME|RETURN|ROR|RXOR|SQUARE|SU|TCR|TCAA|OVSK|TCF|TC|TS|WAND|WOR|WRITE|XCH|XLQ|XXALQ|ZL|ZQ|ADD|ADZ|SUB|SUZ|MPY|MPR|MPZ|DVP|COM|ABS|CLA|CLZ|LDQ|STO|STQ|ALS|LLS|LRS|TRA|TSQ|TMI|TOV|AXT|TIX|DLY|INP|OUT)\s/,null], - [PR['PR_TYPE'], /^(?:-?GENADR|=MINUS|2BCADR|VN|BOF|MM|-?2CADR|-?[1-6]DNADR|ADRES|BBCON|[SE]?BANK\=?|BLOCK|BNKSUM|E?CADR|COUNT\*?|2?DEC\*?|-?DNCHAN|-?DNPTR|EQUALS|ERASE|MEMORY|2?OCT|REMADR|SETLOC|SUBRO|ORG|BSS|BES|SYN|EQU|DEFINE|END)\s/,null], - // A single quote possibly followed by a word that optionally ends with - // = ! or ?. - [PR['PR_LITERAL'], - /^\'(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/], - // Any word including labels that optionally ends with = ! or ?. - [PR['PR_PLAIN'], - /^-*(?:[!-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i], - // A printable non-space non-special character - [PR['PR_PUNCTUATION'], /^[^\w\t\n\r \xA0()\"\\\';]+/] - ]), - ['apollo', 'agc', 'aea']); diff --git a/source/plugins/prettify/lang-basic.js b/source/plugins/prettify/lang-basic.js deleted file mode 100644 index d60cce31..00000000 --- a/source/plugins/prettify/lang-basic.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * @license - * Copyright (C) 2013 Peter Kofler - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// Contributed by peter dot kofler at code minus cop dot org - -/** - * @fileoverview - * Registers a language handler for Basic. - * - * To use, include prettify.js and this file in your HTML page. - * Then put your code in an HTML tag like - *

(my BASIC code)
- * - * @author peter dot kofler at code minus cop dot org - */ - -PR.registerLangHandler( - PR.createSimpleLexer( - [ // shortcutStylePatterns - // "single-line-string" - [PR.PR_STRING, /^(?:"(?:[^\\"\r\n]|\\.)*(?:"|$))/, null, '"'], - // Whitespace - [PR.PR_PLAIN, /^\s+/, null, ' \r\n\t\xA0'] - ], - [ // fallthroughStylePatterns - // A line comment that starts with REM - [PR.PR_COMMENT, /^REM[^\r\n]*/, null], - [PR.PR_KEYWORD, /^\b(?:AND|CLOSE|CLR|CMD|CONT|DATA|DEF ?FN|DIM|END|FOR|GET|GOSUB|GOTO|IF|INPUT|LET|LIST|LOAD|NEW|NEXT|NOT|ON|OPEN|OR|POKE|PRINT|READ|RESTORE|RETURN|RUN|SAVE|STEP|STOP|SYS|THEN|TO|VERIFY|WAIT)\b/, null], - [PR.PR_PLAIN, /^[A-Z][A-Z0-9]?(?:\$|%)?/i, null], - // Literals .0, 0, 0.0 0E13 - [PR.PR_LITERAL, /^(?:\d+(?:\.\d*)?|\.\d+)(?:e[+\-]?\d+)?/i, null, '0123456789'], - [PR.PR_PUNCTUATION, /^.[^\s\w\.$%"]*/, null] - // [PR.PR_PUNCTUATION, /^[-,:;!<>=\+^\/\*]+/] - ]), - ['basic','cbm']); diff --git a/source/plugins/prettify/lang-clj.js b/source/plugins/prettify/lang-clj.js deleted file mode 100644 index 0758335f..00000000 --- a/source/plugins/prettify/lang-clj.js +++ /dev/null @@ -1,64 +0,0 @@ -/** - * @license Copyright (C) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview - * Registers a language handler for Clojure. - * - * - * To use, include prettify.js and this file in your HTML page. - * Then put your code in an HTML tag like - *
(my lisp code)
- * The lang-cl class identifies the language as common lisp. - * This file supports the following language extensions: - * lang-clj - Clojure - * - * - * I used lang-lisp.js as the basis for this adding the clojure specific - * keywords and syntax. - * - * "Name" = 'Clojure' - * "Author" = 'Rich Hickey' - * "Version" = '1.2' - * "About" = 'Clojure is a lisp for the jvm with concurrency primitives and a richer set of types.' - * - * - * I used Clojure.org Reference as - * the basis for the reserved word list. - * - * - * @author jwall@google.com - */ - -PR['registerLangHandler']( - PR['createSimpleLexer']( - [ - // clojure has more paren types than minimal lisp. - ['opn', /^[\(\{\[]+/, null, '([{'], - ['clo', /^[\)\}\]]+/, null, ')]}'], - // A line comment that starts with ; - [PR['PR_COMMENT'], /^;[^\r\n]*/, null, ';'], - // Whitespace - [PR['PR_PLAIN'], /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'], - // A double quoted, possibly multi-line, string. - [PR['PR_STRING'], /^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/, null, '"'] - ], - [ - // clojure has a much larger set of keywords - [PR['PR_KEYWORD'], /^(?:def|if|do|let|quote|var|fn|loop|recur|throw|try|monitor-enter|monitor-exit|defmacro|defn|defn-|macroexpand|macroexpand-1|for|doseq|dosync|dotimes|and|or|when|not|assert|doto|proxy|defstruct|first|rest|cons|defprotocol|deftype|defrecord|reify|defmulti|defmethod|meta|with-meta|ns|in-ns|create-ns|import|intern|refer|alias|namespace|resolve|ref|deref|refset|new|set!|memfn|to-array|into-array|aset|gen-class|reduce|map|filter|find|nil?|empty?|hash-map|hash-set|vec|vector|seq|flatten|reverse|assoc|dissoc|list|list?|disj|get|union|difference|intersection|extend|extend-type|extend-protocol|prn)\b/, null], - [PR['PR_TYPE'], /^:[0-9a-zA-Z\-]+/] - ]), - ['clj']); diff --git a/source/plugins/prettify/lang-css.js b/source/plugins/prettify/lang-css.js deleted file mode 100644 index c6f7c36b..00000000 --- a/source/plugins/prettify/lang-css.js +++ /dev/null @@ -1,160 +0,0 @@ -/** - * @license - * Copyright (C) 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview - * Registers a language handler for CSS. - * - * - * To use, include prettify.js and this file in your HTML page. - * Then put your code in an HTML tag like - *

- *
- *
- * http://www.w3.org/TR/CSS21/grammar.html Section G2 defines the lexical
- * grammar.  This scheme does not recognize keywords containing escapes.
- *
- * @author mikesamuel@gmail.com
- */
-
-// This file is a call to a function defined in prettify.js which defines a
-// lexical scanner for CSS and maps tokens to styles.
-
-// The call to PR['registerLangHandler'] is quoted so that Closure Compiler
-// will not rename the call so that this language extensions can be
-// compiled/minified separately from one another.  Other symbols defined in
-// prettify.js are similarly quoted.
-
-// The call is structured thus:
-// PR['registerLangHandler'](
-//    PR['createSimpleLexer'](
-//        shortcutPatterns,
-//        fallThroughPatterns),
-//    [languageId0, ..., languageIdN])
-
-// Langugage IDs
-// =============
-// The language IDs are typically the file extensions of source files for
-// that language so that users can syntax highlight arbitrary files based
-// on just the extension.  This is heuristic, but works pretty well in
-// practice.
-
-// Patterns
-// ========
-// Lexers are typically implemented as a set of regular expressions.
-// The SimpleLexer function takes regular expressions, styles, and some
-// pragma-info and produces a lexer.  A token description looks like
-//   [STYLE_NAME, /regular-expression/, pragmas]
-
-// Initially, simple lexer's inner loop looked like:
-
-//    while sourceCode is not empty:
-//      try each regular expression in order until one matches
-//      remove the matched portion from sourceCode
-
-// This was really slow for large files because some JS interpreters
-// do a buffer copy on the matched portion which is O(n*n)
-
-// The current loop now looks like
-
-//    1. use js-modules/combinePrefixPatterns.js to 
-//       combine all regular expressions into one 
-//    2. use a single global regular expresion match to extract all tokens
-//    3. for each token try regular expressions in order until one matches it
-//       and classify it using the associated style
-
-// This is a lot more efficient but it does mean that lookahead and lookbehind
-// can't be used across boundaries to classify tokens.
-
-// Sometimes we need lookahead and lookbehind and sometimes we want to handle
-// embedded language -- JavaScript or CSS embedded in HTML, or inline assembly
-// in C.
-
-// If a particular pattern has a numbered group, and its style pattern starts
-// with "lang-" as in
-//    ['lang-js', /}
- * 
  • define style rules. See the example page for examples. - *
  • mark the {@code
    } and {@code } tags in your source with
    - *    {@code class=prettyprint.}
    - *    You can also use the (html deprecated) {@code } tag, but the pretty
    - *    printer needs to do more substantial DOM manipulations to support that, so
    - *    some css styles may not be preserved.
    - * </ol>
    - * That's it.  I wanted to keep the API as simple as possible, so there's no
    - * need to specify which language the code is in, but if you wish, you can add
    - * another class to the {@code <pre>} or {@code <code>} element to specify the
    - * language, as in {@code <pre class="prettyprint lang-java">}.  Any class that
    - * starts with "lang-" followed by a file extension, specifies the file type.
    - * See the "lang-*.js" files in this directory for code that implements
    - * per-language file handlers.
    - * <p>
    - * Change log:<br>
    - * cbeust, 2006/08/22
    - * <blockquote>
    - *   Java annotations (start with "@") are now captured as literals ("lit")
    - * </blockquote>
    - * @requires console
    - */
    -
    -// JSLint declarations
    -/*global console, document, navigator, setTimeout, window, define */
    -
    -
    -/**
    - * {@type !{
    - *   'createSimpleLexer': function (Array, Array): (function (JobT)),
    - *   'registerLangHandler': function (function (JobT), Array.<string>),
    - *   'PR_ATTRIB_NAME': string,
    - *   'PR_ATTRIB_NAME': string,
    - *   'PR_ATTRIB_VALUE': string,
    - *   'PR_COMMENT': string,
    - *   'PR_DECLARATION': string,
    - *   'PR_KEYWORD': string,
    - *   'PR_LITERAL': string,
    - *   'PR_NOCODE': string,
    - *   'PR_PLAIN': string,
    - *   'PR_PUNCTUATION': string,
    - *   'PR_SOURCE': string,
    - *   'PR_STRING': string,
    - *   'PR_TAG': string,
    - *   'PR_TYPE': string,
    - *   'prettyPrintOne': function (string, string, number|boolean),
    - *   'prettyPrint': function (?function, ?(HTMLElement|HTMLDocument))
    - * }}
    - * @const
    - */
    -/**
    -* @typedef {!Array.<number|string>}
    -* Alternating indices and the decorations that should be inserted there.
    -* The indices are monotonically increasing.
    -*/
    -var DecorationsT;
    -
    -/**
    -* @typedef {!{
    -*   sourceNode: !Element,
    -*   pre: !(number|boolean),
    -*   langExtension: ?string,
    -*   numberLines: ?(number|boolean),
    -*   sourceCode: ?string,
    -*   spans: ?(Array.<number|Node>),
    -*   basePos: ?number,
    -*   decorations: ?DecorationsT
    -* }}
    -* <dl>
    -*  <dt>sourceNode<dd>the element containing the source
    -*  <dt>sourceCode<dd>source as plain text
    -*  <dt>pre<dd>truthy if white-space in text nodes
    -*     should be considered significant.
    -*  <dt>spans<dd> alternating span start indices into source
    -*     and the text node or element (e.g. {@code <BR>}) corresponding to that
    -*     span.
    -*  <dt>decorations<dd>an array of style classes preceded
    -*     by the position at which they start in job.sourceCode in order
    -*  <dt>basePos<dd>integer position of this.sourceCode in the larger chunk of
    -*     source.
    -* </dl>
    -*/
    -var JobT;
    -
    -/**
    -* @typedef {!{
    -*   sourceCode: string,
    -*   spans: !(Array.<number|Node>)
    -* }}
    -* <dl>
    -*  <dt>sourceCode<dd>source as plain text
    -*  <dt>spans<dd> alternating span start indices into source
    -*     and the text node or element (e.g. {@code <BR>}) corresponding to that
    -*     span.
    -* </dl>
    -*/
    -var SourceSpansT;
    -
    -/** @define {boolean} */
    -var IN_GLOBAL_SCOPE = false;
    -
    -var PR;
    -
    -/**
    - * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
    - * UI events.
    - * If set to {@code false}, {@code prettyPrint()} is synchronous.
    - */
    -window['PR_SHOULD_USE_CONTINUATION'] = true;
    -
    -/**
    - * Pretty print a chunk of code.
    - * @param {string} sourceCodeHtml The HTML to pretty print.
    - * @param {string} opt_langExtension The language name to use.
    - *     Typically, a filename extension like 'cpp' or 'java'.
    - * @param {number|boolean} opt_numberLines True to number lines,
    - *     or the 1-indexed number of the first line in sourceCodeHtml.
    - * @return {string} code as html, but prettier
    - */
    -var prettyPrintOne;
    -/**
    - * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
    - * {@code class=prettyprint} and prettify them.
    - *
    - * @param {Function} opt_whenDone called when prettifying is done.
    - * @param {HTMLElement|HTMLDocument} opt_root an element or document
    - *   containing all the elements to pretty print.
    - *   Defaults to {@code document.body}.
    - */
    -var prettyPrint;
    -
    -
    -(function () {
    -  var win = window;
    -  // Keyword lists for various languages.
    -  // We use things that coerce to strings to make them compact when minified
    -  // and to defeat aggressive optimizers that fold large string constants.
    -  var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"];
    -  var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," +
    -      "double,enum,extern,float,goto,inline,int,long,register,short,signed," +
    -      "sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];
    -  var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," +
    -      "new,operator,private,protected,public,this,throw,true,try,typeof"];
    -  var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignof,align_union,asm,axiom,bool," +
    -      "concept,concept_map,const_cast,constexpr,decltype,delegate," +
    -      "dynamic_cast,explicit,export,friend,generic,late_check," +
    -      "mutable,namespace,nullptr,property,reinterpret_cast,static_assert," +
    -      "static_cast,template,typeid,typename,using,virtual,where"];
    -  var JAVA_KEYWORDS = [COMMON_KEYWORDS,
    -      "abstract,assert,boolean,byte,extends,finally,final,implements,import," +
    -      "instanceof,interface,null,native,package,strictfp,super,synchronized," +
    -      "throws,transient"];
    -  var CSHARP_KEYWORDS = [COMMON_KEYWORDS,
    -      "abstract,as,base,bool,by,byte,checked,decimal,delegate,descending," +
    -      "dynamic,event,finally,fixed,foreach,from,group,implicit,in,interface," +
    -      "internal,into,is,let,lock,null,object,out,override,orderby,params," +
    -      "partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong," +
    -      "unchecked,unsafe,ushort,var,virtual,where"];
    -  var COFFEE_KEYWORDS = "all,and,by,catch,class,else,extends,false,finally," +
    -      "for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then," +
    -      "throw,true,try,unless,until,when,while,yes";
    -  var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS,
    -      "abstract,async,await,constructor,debugger,enum,eval,export,function," +
    -      "get,implements,instanceof,interface,let,null,set,undefined,var,with," +
    -      "yield,Infinity,NaN"];
    -  var PERL_KEYWORDS = "caller,delete,die,do,dump,elsif,eval,exit,foreach,for," +
    -      "goto,if,import,last,local,my,next,no,our,print,package,redo,require," +
    -      "sub,undef,unless,until,use,wantarray,while,BEGIN,END";
    -  var PYTHON_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "and,as,assert,class,def,del," +
    -      "elif,except,exec,finally,from,global,import,in,is,lambda," +
    -      "nonlocal,not,or,pass,print,raise,try,with,yield," +
    -      "False,True,None"];
    -  var RUBY_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "alias,and,begin,case,class," +
    -      "def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo," +
    -      "rescue,retry,self,super,then,true,undef,unless,until,when,yield," +
    -      "BEGIN,END"];
    -  var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "case,done,elif,esac,eval,fi," +
    -      "function,in,local,set,then,until"];
    -  var ALL_KEYWORDS = [
    -      CPP_KEYWORDS, CSHARP_KEYWORDS, JAVA_KEYWORDS, JSCRIPT_KEYWORDS,
    -      PERL_KEYWORDS, PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS];
    -  var C_TYPES = /^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)\b/;
    -
    -  // token style names.  correspond to css classes
    -  /**
    -   * token style for a string literal
    -   * @const
    -   */
    -  var PR_STRING = 'str';
    -  /**
    -   * token style for a keyword
    -   * @const
    -   */
    -  var PR_KEYWORD = 'kwd';
    -  /**
    -   * token style for a comment
    -   * @const
    -   */
    -  var PR_COMMENT = 'com';
    -  /**
    -   * token style for a type
    -   * @const
    -   */
    -  var PR_TYPE = 'typ';
    -  /**
    -   * token style for a literal value.  e.g. 1, null, true.
    -   * @const
    -   */
    -  var PR_LITERAL = 'lit';
    -  /**
    -   * token style for a punctuation string.
    -   * @const
    -   */
    -  var PR_PUNCTUATION = 'pun';
    -  /**
    -   * token style for plain text.
    -   * @const
    -   */
    -  var PR_PLAIN = 'pln';
    -
    -  /**
    -   * token style for an sgml tag.
    -   * @const
    -   */
    -  var PR_TAG = 'tag';
    -  /**
    -   * token style for a markup declaration such as a DOCTYPE.
    -   * @const
    -   */
    -  var PR_DECLARATION = 'dec';
    -  /**
    -   * token style for embedded source.
    -   * @const
    -   */
    -  var PR_SOURCE = 'src';
    -  /**
    -   * token style for an sgml attribute name.
    -   * @const
    -   */
    -  var PR_ATTRIB_NAME = 'atn';
    -  /**
    -   * token style for an sgml attribute value.
    -   * @const
    -   */
    -  var PR_ATTRIB_VALUE = 'atv';
    -
    -  /**
    -   * A class that indicates a section of markup that is not code, e.g. to allow
    -   * embedding of line numbers within code listings.
    -   * @const
    -   */
    -  var PR_NOCODE = 'nocode';
    -
    -  
    -  
    -  /**
    -   * A set of tokens that can precede a regular expression literal in
    -   * javascript
    -   * http://web.archive.org/web/20070717142515/http://www.mozilla.org/js/language/js20/rationale/syntax.html
    -   * has the full list, but I've removed ones that might be problematic when
    -   * seen in languages that don't support regular expression literals.
    -   *
    -   * <p>Specifically, I've removed any keywords that can't precede a regexp
    -   * literal in a syntactically legal javascript program, and I've removed the
    -   * "in" keyword since it's not a keyword in many languages, and might be used
    -   * as a count of inches.
    -   *
    -   * <p>The link above does not accurately describe EcmaScript rules since
    -   * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
    -   * very well in practice.
    -   *
    -   * @private
    -   * @const
    -   */
    -  var REGEXP_PRECEDER_PATTERN = '(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*';
    -  
    -  // CAVEAT: this does not properly handle the case where a regular
    -  // expression immediately follows another since a regular expression may
    -  // have flags for case-sensitivity and the like.  Having regexp tokens
    -  // adjacent is not valid in any language I'm aware of, so I'm punting.
    -  // TODO: maybe style special characters inside a regexp as punctuation.
    -
    -  /**
    -   * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
    -   * matches the union of the sets of strings matched by the input RegExp.
    -   * Since it matches globally, if the input strings have a start-of-input
    -   * anchor (/^.../), it is ignored for the purposes of unioning.
    -   * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
    -   * @return {RegExp} a global regex.
    -   */
    -  function combinePrefixPatterns(regexs) {
    -    var capturedGroupIndex = 0;
    -  
    -    var needToFoldCase = false;
    -    var ignoreCase = false;
    -    for (var i = 0, n = regexs.length; i < n; ++i) {
    -      var regex = regexs[i];
    -      if (regex.ignoreCase) {
    -        ignoreCase = true;
    -      } else if (/[a-z]/i.test(regex.source.replace(
    -                     /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
    -        needToFoldCase = true;
    -        ignoreCase = false;
    -        break;
    -      }
    -    }
    -  
    -    var escapeCharToCodeUnit = {
    -      'b': 8,
    -      't': 9,
    -      'n': 0xa,
    -      'v': 0xb,
    -      'f': 0xc,
    -      'r': 0xd
    -    };
    -  
    -    function decodeEscape(charsetPart) {
    -      var cc0 = charsetPart.charCodeAt(0);
    -      if (cc0 !== 92 /* \\ */) {
    -        return cc0;
    -      }
    -      var c1 = charsetPart.charAt(1);
    -      cc0 = escapeCharToCodeUnit[c1];
    -      if (cc0) {
    -        return cc0;
    -      } else if ('0' <= c1 && c1 <= '7') {
    -        return parseInt(charsetPart.substring(1), 8);
    -      } else if (c1 === 'u' || c1 === 'x') {
    -        return parseInt(charsetPart.substring(2), 16);
    -      } else {
    -        return charsetPart.charCodeAt(1);
    -      }
    -    }
    -  
    -    function encodeEscape(charCode) {
    -      if (charCode < 0x20) {
    -        return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
    -      }
    -      var ch = String.fromCharCode(charCode);
    -      return (ch === '\\' || ch === '-' || ch === ']' || ch === '^')
    -          ? "\\" + ch : ch;
    -    }
    -  
    -    function caseFoldCharset(charSet) {
    -      var charsetParts = charSet.substring(1, charSet.length - 1).match(
    -          new RegExp(
    -              '\\\\u[0-9A-Fa-f]{4}'
    -              + '|\\\\x[0-9A-Fa-f]{2}'
    -              + '|\\\\[0-3][0-7]{0,2}'
    -              + '|\\\\[0-7]{1,2}'
    -              + '|\\\\[\\s\\S]'
    -              + '|-'
    -              + '|[^-\\\\]',
    -              'g'));
    -      var ranges = [];
    -      var inverse = charsetParts[0] === '^';
    -  
    -      var out = ['['];
    -      if (inverse) { out.push('^'); }
    -  
    -      for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
    -        var p = charsetParts[i];
    -        if (/\\[bdsw]/i.test(p)) {  // Don't muck with named groups.
    -          out.push(p);
    -        } else {
    -          var start = decodeEscape(p);
    -          var end;
    -          if (i + 2 < n && '-' === charsetParts[i + 1]) {
    -            end = decodeEscape(charsetParts[i + 2]);
    -            i += 2;
    -          } else {
    -            end = start;
    -          }
    -          ranges.push([start, end]);
    -          // If the range might intersect letters, then expand it.
    -          // This case handling is too simplistic.
    -          // It does not deal with non-latin case folding.
    -          // It works for latin source code identifiers though.
    -          if (!(end < 65 || start > 122)) {
    -            if (!(end < 65 || start > 90)) {
    -              ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
    -            }
    -            if (!(end < 97 || start > 122)) {
    -              ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
    -            }
    -          }
    -        }
    -      }
    -  
    -      // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
    -      // -> [[1, 12], [14, 14], [16, 17]]
    -      ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1]  - a[1]); });
    -      var consolidatedRanges = [];
    -      var lastRange = [];
    -      for (var i = 0; i < ranges.length; ++i) {
    -        var range = ranges[i];
    -        if (range[0] <= lastRange[1] + 1) {
    -          lastRange[1] = Math.max(lastRange[1], range[1]);
    -        } else {
    -          consolidatedRanges.push(lastRange = range);
    -        }
    -      }
    -  
    -      for (var i = 0; i < consolidatedRanges.length; ++i) {
    -        var range = consolidatedRanges[i];
    -        out.push(encodeEscape(range[0]));
    -        if (range[1] > range[0]) {
    -          if (range[1] + 1 > range[0]) { out.push('-'); }
    -          out.push(encodeEscape(range[1]));
    -        }
    -      }
    -      out.push(']');
    -      return out.join('');
    -    }
    -  
    -    function allowAnywhereFoldCaseAndRenumberGroups(regex) {
    -      // Split into character sets, escape sequences, punctuation strings
    -      // like ('(', '(?:', ')', '^'), and runs of characters that do not
    -      // include any of the above.
    -      var parts = regex.source.match(
    -          new RegExp(
    -              '(?:'
    -              + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]'  // a character set
    -              + '|\\\\u[A-Fa-f0-9]{4}'  // a unicode escape
    -              + '|\\\\x[A-Fa-f0-9]{2}'  // a hex escape
    -              + '|\\\\[0-9]+'  // a back-reference or octal escape
    -              + '|\\\\[^ux0-9]'  // other escape sequence
    -              + '|\\(\\?[:!=]'  // start of a non-capturing group
    -              + '|[\\(\\)\\^]'  // start/end of a group, or line start
    -              + '|[^\\x5B\\x5C\\(\\)\\^]+'  // run of other characters
    -              + ')',
    -              'g'));
    -      var n = parts.length;
    -  
    -      // Maps captured group numbers to the number they will occupy in
    -      // the output or to -1 if that has not been determined, or to
    -      // undefined if they need not be capturing in the output.
    -      var capturedGroups = [];
    -  
    -      // Walk over and identify back references to build the capturedGroups
    -      // mapping.
    -      for (var i = 0, groupIndex = 0; i < n; ++i) {
    -        var p = parts[i];
    -        if (p === '(') {
    -          // groups are 1-indexed, so max group index is count of '('
    -          ++groupIndex;
    -        } else if ('\\' === p.charAt(0)) {
    -          var decimalValue = +p.substring(1);
    -          if (decimalValue) {
    -            if (decimalValue <= groupIndex) {
    -              capturedGroups[decimalValue] = -1;
    -            } else {
    -              // Replace with an unambiguous escape sequence so that
    -              // an octal escape sequence does not turn into a backreference
    -              // to a capturing group from an earlier regex.
    -              parts[i] = encodeEscape(decimalValue);
    -            }
    -          }
    -        }
    -      }
    -  
    -      // Renumber groups and reduce capturing groups to non-capturing groups
    -      // where possible.
    -      for (var i = 1; i < capturedGroups.length; ++i) {
    -        if (-1 === capturedGroups[i]) {
    -          capturedGroups[i] = ++capturedGroupIndex;
    -        }
    -      }
    -      for (var i = 0, groupIndex = 0; i < n; ++i) {
    -        var p = parts[i];
    -        if (p === '(') {
    -          ++groupIndex;
    -          if (!capturedGroups[groupIndex]) {
    -            parts[i] = '(?:';
    -          }
    -        } else if ('\\' === p.charAt(0)) {
    -          var decimalValue = +p.substring(1);
    -          if (decimalValue && decimalValue <= groupIndex) {
    -            parts[i] = '\\' + capturedGroups[decimalValue];
    -          }
    -        }
    -      }
    -  
    -      // Remove any prefix anchors so that the output will match anywhere.
    -      // ^^ really does mean an anchored match though.
    -      for (var i = 0; i < n; ++i) {
    -        if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
    -      }
    -  
    -      // Expand letters to groups to handle mixing of case-sensitive and
    -      // case-insensitive patterns if necessary.
    -      if (regex.ignoreCase && needToFoldCase) {
    -        for (var i = 0; i < n; ++i) {
    -          var p = parts[i];
    -          var ch0 = p.charAt(0);
    -          if (p.length >= 2 && ch0 === '[') {
    -            parts[i] = caseFoldCharset(p);
    -          } else if (ch0 !== '\\') {
    -            // TODO: handle letters in numeric escapes.
    -            parts[i] = p.replace(
    -                /[a-zA-Z]/g,
    -                function (ch) {
    -                  var cc = ch.charCodeAt(0);
    -                  return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
    -                });
    -          }
    -        }
    -      }
    -  
    -      return parts.join('');
    -    }
    -  
    -    var rewritten = [];
    -    for (var i = 0, n = regexs.length; i < n; ++i) {
    -      var regex = regexs[i];
    -      if (regex.global || regex.multiline) { throw new Error('' + regex); }
    -      rewritten.push(
    -          '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
    -    }
    -  
    -    return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
    -  }
    -
    -  /**
    -   * Split markup into a string of source code and an array mapping ranges in
    -   * that string to the text nodes in which they appear.
    -   *
    -   * <p>
    -   * The HTML DOM structure:</p>
    -   * <pre>
    -   * (Element   "p"
    -   *   (Element "b"
    -   *     (Text  "print "))       ; #1
    -   *   (Text    "'Hello '")      ; #2
    -   *   (Element "br")            ; #3
    -   *   (Text    "  + 'World';")) ; #4
    -   * </pre>
    -   * <p>
    -   * corresponds to the HTML
    -   * {@code <p><b>print </b>'Hello '<br>  + 'World';</p>}.</p>
    -   *
    -   * <p>
    -   * It will produce the output:</p>
    -   * <pre>
    -   * {
    -   *   sourceCode: "print 'Hello '\n  + 'World';",
    -   *   //                     1          2
    -   *   //           012345678901234 5678901234567
    -   *   spans: [0, #1, 6, #2, 14, #3, 15, #4]
    -   * }
    -   * </pre>
    -   * <p>
    -   * where #1 is a reference to the {@code "print "} text node above, and so
    -   * on for the other text nodes.
    -   * </p>
    -   *
    -   * <p>
    -   * The {@code} spans array is an array of pairs.  Even elements are the start
    -   * indices of substrings, and odd elements are the text nodes (or BR elements)
    -   * that contain the text for those substrings.
    -   * Substrings continue until the next index or the end of the source.
    -   * </p>
    -   *
    -   * @param {Node} node an HTML DOM subtree containing source-code.
    -   * @param {boolean|number} isPreformatted truthy if white-space in
    -   *    text nodes should be considered significant.
    -   * @return {SourceSpansT} source code and the nodes in which they occur.
    -   */
    -  function extractSourceSpans(node, isPreformatted) {
    -    var nocode = /(?:^|\s)nocode(?:\s|$)/;
    -  
    -    var chunks = [];
    -    var length = 0;
    -    var spans = [];
    -    var k = 0;
    -  
    -    function walk(node) {
    -      var type = node.nodeType;
    -      if (type == 1) {  // Element
    -        if (nocode.test(node.className)) { return; }
    -        for (var child = node.firstChild; child; child = child.nextSibling) {
    -          walk(child);
    -        }
    -        var nodeName = node.nodeName.toLowerCase();
    -        if ('br' === nodeName || 'li' === nodeName) {
    -          chunks[k] = '\n';
    -          spans[k << 1] = length++;
    -          spans[(k++ << 1) | 1] = node;
    -        }
    -      } else if (type == 3 || type == 4) {  // Text
    -        var text = node.nodeValue;
    -        if (text.length) {
    -          if (!isPreformatted) {
    -            text = text.replace(/[ \t\r\n]+/g, ' ');
    -          } else {
    -            text = text.replace(/\r\n?/g, '\n');  // Normalize newlines.
    -          }
    -          // TODO: handle tabs here?
    -          chunks[k] = text;
    -          spans[k << 1] = length;
    -          length += text.length;
    -          spans[(k++ << 1) | 1] = node;
    -        }
    -      }
    -    }
    -  
    -    walk(node);
    -  
    -    return {
    -      sourceCode: chunks.join('').replace(/\n$/, ''),
    -      spans: spans
    -    };
    -  }
    -
    -  /**
    -   * Apply the given language handler to sourceCode and add the resulting
    -   * decorations to out.
    -   * @param {!Element} sourceNode
    -   * @param {number} basePos the index of sourceCode within the chunk of source
    -   *    whose decorations are already present on out.
    -   * @param {string} sourceCode
    -   * @param {function(JobT)} langHandler
    -   * @param {DecorationsT} out
    -   */
    -  function appendDecorations(
    -      sourceNode, basePos, sourceCode, langHandler, out) {
    -    if (!sourceCode) { return; }
    -    /** @type {JobT} */
    -    var job = {
    -      sourceNode: sourceNode,
    -      pre: 1,
    -      langExtension: null,
    -      numberLines: null,
    -      sourceCode: sourceCode,
    -      spans: null,
    -      basePos: basePos,
    -      decorations: null
    -    };
    -    langHandler(job);
    -    out.push.apply(out, job.decorations);
    -  }
    -
    -  var notWs = /\S/;
    -
    -  /**
    -   * Given an element, if it contains only one child element and any text nodes
    -   * it contains contain only space characters, return the sole child element.
    -   * Otherwise returns undefined.
    -   * <p>
    -   * This is meant to return the CODE element in {@code <pre><code ...>} when
    -   * there is a single child element that contains all the non-space textual
    -   * content, but not to return anything where there are multiple child elements
    -   * as in {@code <pre><code>...</code><code>...</code></pre>} or when there
    -   * is textual content.
    -   */
    -  function childContentWrapper(element) {
    -    var wrapper = undefined;
    -    for (var c = element.firstChild; c; c = c.nextSibling) {
    -      var type = c.nodeType;
    -      wrapper = (type === 1)  // Element Node
    -          ? (wrapper ? element : c)
    -          : (type === 3)  // Text Node
    -          ? (notWs.test(c.nodeValue) ? element : wrapper)
    -          : wrapper;
    -    }
    -    return wrapper === element ? undefined : wrapper;
    -  }
    -
    -  /** Given triples of [style, pattern, context] returns a lexing function,
    -    * The lexing function interprets the patterns to find token boundaries and
    -    * returns a decoration list of the form
    -    * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
    -    * where index_n is an index into the sourceCode, and style_n is a style
    -    * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to
    -    * all characters in sourceCode[index_n-1:index_n].
    -    *
    -    * The stylePatterns is a list whose elements have the form
    -    * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
    -    *
    -    * Style is a style constant like PR_PLAIN, or can be a string of the
    -    * form 'lang-FOO', where FOO is a language extension describing the
    -    * language of the portion of the token in $1 after pattern executes.
    -    * E.g., if style is 'lang-lisp', and group 1 contains the text
    -    * '(hello (world))', then that portion of the token will be passed to the
    -    * registered lisp handler for formatting.
    -    * The text before and after group 1 will be restyled using this decorator
    -    * so decorators should take care that this doesn't result in infinite
    -    * recursion.  For example, the HTML lexer rule for SCRIPT elements looks
    -    * something like ['lang-js', /<[s]cript>(.+?)<\/script>/].  This may match
    -    * '<script>foo()<\/script>', which would cause the current decorator to
    -    * be called with '<script>' which would not match the same rule since
    -    * group 1 must not be empty, so it would be instead styled as PR_TAG by
    -    * the generic tag rule.  The handler registered for the 'js' extension would
    -    * then be called with 'foo()', and finally, the current decorator would
    -    * be called with '<\/script>' which would not match the original rule and
    -    * so the generic tag rule would identify it as a tag.
    -    *
    -    * Pattern must only match prefixes, and if it matches a prefix, then that
    -    * match is considered a token with the same style.
    -    *
    -    * Context is applied to the last non-whitespace, non-comment token
    -    * recognized.
    -    *
    -    * Shortcut is an optional string of characters, any of which, if the first
    -    * character, gurantee that this pattern and only this pattern matches.
    -    *
    -    * @param {Array} shortcutStylePatterns patterns that always start with
    -    *   a known character.  Must have a shortcut string.
    -    * @param {Array} fallthroughStylePatterns patterns that will be tried in
    -    *   order if the shortcut ones fail.  May have shortcuts.
    -    *
    -    * @return {function (JobT)} a function that takes an undecorated job and
    -    *   attaches a list of decorations.
    -    */
    -  function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
    -    var shortcuts = {};
    -    var tokenizer;
    -    (function () {
    -      var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
    -      var allRegexs = [];
    -      var regexKeys = {};
    -      for (var i = 0, n = allPatterns.length; i < n; ++i) {
    -        var patternParts = allPatterns[i];
    -        var shortcutChars = patternParts[3];
    -        if (shortcutChars) {
    -          for (var c = shortcutChars.length; --c >= 0;) {
    -            shortcuts[shortcutChars.charAt(c)] = patternParts;
    -          }
    -        }
    -        var regex = patternParts[1];
    -        var k = '' + regex;
    -        if (!regexKeys.hasOwnProperty(k)) {
    -          allRegexs.push(regex);
    -          regexKeys[k] = null;
    -        }
    -      }
    -      allRegexs.push(/[\0-\uffff]/);
    -      tokenizer = combinePrefixPatterns(allRegexs);
    -    })();
    -
    -    var nPatterns = fallthroughStylePatterns.length;
    -
    -    /**
    -     * Lexes job.sourceCode and attaches an output array job.decorations of
    -     * style classes preceded by the position at which they start in
    -     * job.sourceCode in order.
    -     *
    -     * @type{function (JobT)}
    -     */
    -    var decorate = function (job) {
    -      var sourceCode = job.sourceCode, basePos = job.basePos;
    -      var sourceNode = job.sourceNode;
    -      /** Even entries are positions in source in ascending order.  Odd enties
    -        * are style markers (e.g., PR_COMMENT) that run from that position until
    -        * the end.
    -        * @type {DecorationsT}
    -        */
    -      var decorations = [basePos, PR_PLAIN];
    -      var pos = 0;  // index into sourceCode
    -      var tokens = sourceCode.match(tokenizer) || [];
    -      var styleCache = {};
    -
    -      for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
    -        var token = tokens[ti];
    -        var style = styleCache[token];
    -        var match = void 0;
    -
    -        var isEmbedded;
    -        if (typeof style === 'string') {
    -          isEmbedded = false;
    -        } else {
    -          var patternParts = shortcuts[token.charAt(0)];
    -          if (patternParts) {
    -            match = token.match(patternParts[1]);
    -            style = patternParts[0];
    -          } else {
    -            for (var i = 0; i < nPatterns; ++i) {
    -              patternParts = fallthroughStylePatterns[i];
    -              match = token.match(patternParts[1]);
    -              if (match) {
    -                style = patternParts[0];
    -                break;
    -              }
    -            }
    -
    -            if (!match) {  // make sure that we make progress
    -              style = PR_PLAIN;
    -            }
    -          }
    -
    -          isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
    -          if (isEmbedded && !(match && typeof match[1] === 'string')) {
    -            isEmbedded = false;
    -            style = PR_SOURCE;
    -          }
    -
    -          if (!isEmbedded) { styleCache[token] = style; }
    -        }
    -
    -        var tokenStart = pos;
    -        pos += token.length;
    -
    -        if (!isEmbedded) {
    -          decorations.push(basePos + tokenStart, style);
    -        } else {  // Treat group 1 as an embedded block of source code.
    -          var embeddedSource = match[1];
    -          var embeddedSourceStart = token.indexOf(embeddedSource);
    -          var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
    -          if (match[2]) {
    -            // If embeddedSource can be blank, then it would match at the
    -            // beginning which would cause us to infinitely recurse on the
    -            // entire token, so we catch the right context in match[2].
    -            embeddedSourceEnd = token.length - match[2].length;
    -            embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
    -          }
    -          var lang = style.substring(5);
    -          // Decorate the left of the embedded source
    -          appendDecorations(
    -              sourceNode,
    -              basePos + tokenStart,
    -              token.substring(0, embeddedSourceStart),
    -              decorate, decorations);
    -          // Decorate the embedded source
    -          appendDecorations(
    -              sourceNode,
    -              basePos + tokenStart + embeddedSourceStart,
    -              embeddedSource,
    -              langHandlerForExtension(lang, embeddedSource),
    -              decorations);
    -          // Decorate the right of the embedded section
    -          appendDecorations(
    -              sourceNode,
    -              basePos + tokenStart + embeddedSourceEnd,
    -              token.substring(embeddedSourceEnd),
    -              decorate, decorations);
    -        }
    -      }
    -      job.decorations = decorations;
    -    };
    -    return decorate;
    -  }
    -
    -  /** returns a function that produces a list of decorations from source text.
    -    *
    -    * This code treats ", ', and ` as string delimiters, and \ as a string
    -    * escape.  It does not recognize perl's qq() style strings.
    -    * It has no special handling for double delimiter escapes as in basic, or
    -    * the tripled delimiters used in python, but should work on those regardless
    -    * although in those cases a single string literal may be broken up into
    -    * multiple adjacent string literals.
    -    *
    -    * It recognizes C, C++, and shell style comments.
    -    *
    -    * @param {Object} options a set of optional parameters.
    -    * @return {function (JobT)} a function that examines the source code
    -    *     in the input job and builds a decoration list which it attaches to
    -    *     the job.
    -    */
    -  function sourceDecorator(options) {
    -    var shortcutStylePatterns = [], fallthroughStylePatterns = [];
    -    if (options['tripleQuotedStrings']) {
    -      // '''multi-line-string''', 'single-line-string', and double-quoted
    -      shortcutStylePatterns.push(
    -          [PR_STRING,  /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
    -           null, '\'"']);
    -    } else if (options['multiLineStrings']) {
    -      // 'multi-line-string', "multi-line-string"
    -      shortcutStylePatterns.push(
    -          [PR_STRING,  /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
    -           null, '\'"`']);
    -    } else {
    -      // 'single-line-string', "single-line-string"
    -      shortcutStylePatterns.push(
    -          [PR_STRING,
    -           /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
    -           null, '"\'']);
    -    }
    -    if (options['verbatimStrings']) {
    -      // verbatim-string-literal production from the C# grammar.  See issue 93.
    -      fallthroughStylePatterns.push(
    -          [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
    -    }
    -    var hc = options['hashComments'];
    -    if (hc) {
    -      if (options['cStyleComments']) {
    -        if (hc > 1) {  // multiline hash comments
    -          shortcutStylePatterns.push(
    -              [PR_COMMENT, /^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/, null, '#']);
    -        } else {
    -          // Stop C preprocessor declarations at an unclosed open comment
    -          shortcutStylePatterns.push(
    -              [PR_COMMENT, /^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\r\n]*)/,
    -               null, '#']);
    -        }
    -        // #include <stdio.h>
    -        fallthroughStylePatterns.push(
    -            [PR_STRING,
    -             /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,
    -             null]);
    -      } else {
    -        shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
    -      }
    -    }
    -    if (options['cStyleComments']) {
    -      fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
    -      fallthroughStylePatterns.push(
    -          [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
    -    }
    -    var regexLiterals = options['regexLiterals'];
    -    if (regexLiterals) {
    -      /**
    -       * @const
    -       */
    -      var regexExcls = regexLiterals > 1
    -        ? ''  // Multiline regex literals
    -        : '\n\r';
    -      /**
    -       * @const
    -       */
    -      var regexAny = regexExcls ? '.' : '[\\S\\s]';
    -      /**
    -       * @const
    -       */
    -      var REGEX_LITERAL = (
    -          // A regular expression literal starts with a slash that is
    -          // not followed by * or / so that it is not confused with
    -          // comments.
    -          '/(?=[^/*' + regexExcls + '])'
    -          // and then contains any number of raw characters,
    -          + '(?:[^/\\x5B\\x5C' + regexExcls + ']'
    -          // escape sequences (\x5C),
    -          +    '|\\x5C' + regexAny
    -          // or non-nesting character sets (\x5B\x5D);
    -          +    '|\\x5B(?:[^\\x5C\\x5D' + regexExcls + ']'
    -          +             '|\\x5C' + regexAny + ')*(?:\\x5D|$))+'
    -          // finally closed by a /.
    -          + '/');
    -      fallthroughStylePatterns.push(
    -          ['lang-regex',
    -           RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
    -           ]);
    -    }
    -
    -    var types = options['types'];
    -    if (types) {
    -      fallthroughStylePatterns.push([PR_TYPE, types]);
    -    }
    -
    -    var keywords = ("" + options['keywords']).replace(/^ | $/g, '');
    -    if (keywords.length) {
    -      fallthroughStylePatterns.push(
    -          [PR_KEYWORD,
    -           new RegExp('^(?:' + keywords.replace(/[\s,]+/g, '|') + ')\\b'),
    -           null]);
    -    }
    -
    -    shortcutStylePatterns.push([PR_PLAIN,       /^\s+/, null, ' \r\n\t\xA0']);
    -
    -    var punctuation =
    -      // The Bash man page says
    -
    -      // A word is a sequence of characters considered as a single
    -      // unit by GRUB. Words are separated by metacharacters,
    -      // which are the following plus space, tab, and newline: { }
    -      // | & $ ; < >
    -      // ...
    -
    -      // A word beginning with # causes that word and all remaining
    -      // characters on that line to be ignored.
    -
    -      // which means that only a '#' after /(?:^|[{}|&$;<>\s])/ starts a
    -      // comment but empirically
    -      // $ echo {#}
    -      // {#}
    -      // $ echo \$#
    -      // $#
    -      // $ echo }#
    -      // }#
    -
    -      // so /(?:^|[|&;<>\s])/ is more appropriate.
    -
    -      // http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC3
    -      // suggests that this definition is compatible with a
    -      // default mode that tries to use a single token definition
    -      // to recognize both bash/python style comments and C
    -      // preprocessor directives.
    -
    -      // This definition of punctuation does not include # in the list of
    -      // follow-on exclusions, so # will not be broken before if preceeded
    -      // by a punctuation character.  We could try to exclude # after
    -      // [|&;<>] but that doesn't seem to cause many major problems.
    -      // If that does turn out to be a problem, we should change the below
    -      // when hc is truthy to include # in the run of punctuation characters
    -      // only when not followint [|&;<>].
    -      '^.[^\\s\\w.$@\'"`/\\\\]*';
    -    if (options['regexLiterals']) {
    -      punctuation += '(?!\s*\/)';
    -    }
    -
    -    fallthroughStylePatterns.push(
    -        // TODO(mikesamuel): recognize non-latin letters and numerals in idents
    -        [PR_LITERAL,     /^@[a-z_$][a-z_$@0-9]*/i, null],
    -        [PR_TYPE,        /^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/, null],
    -        [PR_PLAIN,       /^[a-z_$][a-z_$@0-9]*/i, null],
    -        [PR_LITERAL,
    -         new RegExp(
    -             '^(?:'
    -             // A hex number
    -             + '0x[a-f0-9]+'
    -             // or an octal or decimal number,
    -             + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
    -             // possibly in scientific notation
    -             + '(?:e[+\\-]?\\d+)?'
    -             + ')'
    -             // with an optional modifier like UL for unsigned long
    -             + '[a-z]*', 'i'),
    -         null, '0123456789'],
    -        // Don't treat escaped quotes in bash as starting strings.
    -        // See issue 144.
    -        [PR_PLAIN,       /^\\[\s\S]?/, null],
    -        [PR_PUNCTUATION, new RegExp(punctuation), null]);
    -
    -    return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
    -  }
    -
    -  var decorateSource = sourceDecorator({
    -        'keywords': ALL_KEYWORDS,
    -        'hashComments': true,
    -        'cStyleComments': true,
    -        'multiLineStrings': true,
    -        'regexLiterals': true
    -      });
    -
    -  /**
    -   * Given a DOM subtree, wraps it in a list, and puts each line into its own
    -   * list item.
    -   *
    -   * @param {Node} node modified in place.  Its content is pulled into an
    -   *     HTMLOListElement, and each line is moved into a separate list item.
    -   *     This requires cloning elements, so the input might not have unique
    -   *     IDs after numbering.
    -   * @param {number|null|boolean} startLineNum
    -   *     If truthy, coerced to an integer which is the 1-indexed line number
    -   *     of the first line of code.  The number of the first line will be
    -   *     attached to the list.
    -   * @param {boolean} isPreformatted true iff white-space in text nodes should
    -   *     be treated as significant.
    -   */
    -  function numberLines(node, startLineNum, isPreformatted) {
    -    var nocode = /(?:^|\s)nocode(?:\s|$)/;
    -    var lineBreak = /\r\n?|\n/;
    -  
    -    var document = node.ownerDocument;
    -  
    -    var li = document.createElement('li');
    -    while (node.firstChild) {
    -      li.appendChild(node.firstChild);
    -    }
    -    // An array of lines.  We split below, so this is initialized to one
    -    // un-split line.
    -    var listItems = [li];
    -  
    -    function walk(node) {
    -      var type = node.nodeType;
    -      if (type == 1 && !nocode.test(node.className)) {  // Element
    -        if ('br' === node.nodeName) {
    -          breakAfter(node);
    -          // Discard the <BR> since it is now flush against a </LI>.
    -          if (node.parentNode) {
    -            node.parentNode.removeChild(node);
    -          }
    -        } else {
    -          for (var child = node.firstChild; child; child = child.nextSibling) {
    -            walk(child);
    -          }
    -        }
    -      } else if ((type == 3 || type == 4) && isPreformatted) {  // Text
    -        var text = node.nodeValue;
    -        var match = text.match(lineBreak);
    -        if (match) {
    -          var firstLine = text.substring(0, match.index);
    -          node.nodeValue = firstLine;
    -          var tail = text.substring(match.index + match[0].length);
    -          if (tail) {
    -            var parent = node.parentNode;
    -            parent.insertBefore(
    -              document.createTextNode(tail), node.nextSibling);
    -          }
    -          breakAfter(node);
    -          if (!firstLine) {
    -            // Don't leave blank text nodes in the DOM.
    -            node.parentNode.removeChild(node);
    -          }
    -        }
    -      }
    -    }
    -  
    -    // Split a line after the given node.
    -    function breakAfter(lineEndNode) {
    -      // If there's nothing to the right, then we can skip ending the line
    -      // here, and move root-wards since splitting just before an end-tag
    -      // would require us to create a bunch of empty copies.
    -      while (!lineEndNode.nextSibling) {
    -        lineEndNode = lineEndNode.parentNode;
    -        if (!lineEndNode) { return; }
    -      }
    -  
    -      function breakLeftOf(limit, copy) {
    -        // Clone shallowly if this node needs to be on both sides of the break.
    -        var rightSide = copy ? limit.cloneNode(false) : limit;
    -        var parent = limit.parentNode;
    -        if (parent) {
    -          // We clone the parent chain.
    -          // This helps us resurrect important styling elements that cross lines.
    -          // E.g. in <i>Foo<br>Bar</i>
    -          // should be rewritten to <li><i>Foo</i></li><li><i>Bar</i></li>.
    -          var parentClone = breakLeftOf(parent, 1);
    -          // Move the clone and everything to the right of the original
    -          // onto the cloned parent.
    -          var next = limit.nextSibling;
    -          parentClone.appendChild(rightSide);
    -          for (var sibling = next; sibling; sibling = next) {
    -            next = sibling.nextSibling;
    -            parentClone.appendChild(sibling);
    -          }
    -        }
    -        return rightSide;
    -      }
    -  
    -      var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0);
    -  
    -      // Walk the parent chain until we reach an unattached LI.
    -      for (var parent;
    -           // Check nodeType since IE invents document fragments.
    -           (parent = copiedListItem.parentNode) && parent.nodeType === 1;) {
    -        copiedListItem = parent;
    -      }
    -      // Put it on the list of lines for later processing.
    -      listItems.push(copiedListItem);
    -    }
    -  
    -    // Split lines while there are lines left to split.
    -    for (var i = 0;  // Number of lines that have been split so far.
    -         i < listItems.length;  // length updated by breakAfter calls.
    -         ++i) {
    -      walk(listItems[i]);
    -    }
    -  
    -    // Make sure numeric indices show correctly.
    -    if (startLineNum === (startLineNum|0)) {
    -      listItems[0].setAttribute('value', startLineNum);
    -    }
    -  
    -    var ol = document.createElement('ol');
    -    ol.className = 'linenums';
    -    var offset = Math.max(0, ((startLineNum - 1 /* zero index */)) | 0) || 0;
    -    for (var i = 0, n = listItems.length; i < n; ++i) {
    -      li = listItems[i];
    -      // Stick a class on the LIs so that stylesheets can
    -      // color odd/even rows, or any other row pattern that
    -      // is co-prime with 10.
    -      li.className = 'L' + ((i + offset) % 10);
    -      if (!li.firstChild) {
    -        li.appendChild(document.createTextNode('\xA0'));
    -      }
    -      ol.appendChild(li);
    -    }
    -  
    -    node.appendChild(ol);
    -  }
    -
    -  /**
    -   * Breaks {@code job.sourceCode} around style boundaries in
    -   * {@code job.decorations} and modifies {@code job.sourceNode} in place.
    -   * @param {JobT} job
    -   * @private
    -   */
    -  function recombineTagsAndDecorations(job) {
    -    var isIE8OrEarlier = /\bMSIE\s(\d+)/.exec(navigator.userAgent);
    -    isIE8OrEarlier = isIE8OrEarlier && +isIE8OrEarlier[1] <= 8;
    -    var newlineRe = /\n/g;
    -  
    -    var source = job.sourceCode;
    -    var sourceLength = source.length;
    -    // Index into source after the last code-unit recombined.
    -    var sourceIndex = 0;
    -  
    -    var spans = job.spans;
    -    var nSpans = spans.length;
    -    // Index into spans after the last span which ends at or before sourceIndex.
    -    var spanIndex = 0;
    -  
    -    var decorations = job.decorations;
    -    var nDecorations = decorations.length;
    -    // Index into decorations after the last decoration which ends at or before
    -    // sourceIndex.
    -    var decorationIndex = 0;
    -  
    -    // Remove all zero-length decorations.
    -    decorations[nDecorations] = sourceLength;
    -    var decPos, i;
    -    for (i = decPos = 0; i < nDecorations;) {
    -      if (decorations[i] !== decorations[i + 2]) {
    -        decorations[decPos++] = decorations[i++];
    -        decorations[decPos++] = decorations[i++];
    -      } else {
    -        i += 2;
    -      }
    -    }
    -    nDecorations = decPos;
    -  
    -    // Simplify decorations.
    -    for (i = decPos = 0; i < nDecorations;) {
    -      var startPos = decorations[i];
    -      // Conflate all adjacent decorations that use the same style.
    -      var startDec = decorations[i + 1];
    -      var end = i + 2;
    -      while (end + 2 <= nDecorations && decorations[end + 1] === startDec) {
    -        end += 2;
    -      }
    -      decorations[decPos++] = startPos;
    -      decorations[decPos++] = startDec;
    -      i = end;
    -    }
    -  
    -    nDecorations = decorations.length = decPos;
    -  
    -    var sourceNode = job.sourceNode;
    -    var oldDisplay = "";
    -    if (sourceNode) {
    -      oldDisplay = sourceNode.style.display;
    -      sourceNode.style.display = 'none';
    -    }
    -    try {
    -      var decoration = null;
    -      while (spanIndex < nSpans) {
    -        var spanStart = spans[spanIndex];
    -        var spanEnd = /** @type{number} */ (spans[spanIndex + 2])
    -            || sourceLength;
    -  
    -        var decEnd = decorations[decorationIndex + 2] || sourceLength;
    -  
    -        var end = Math.min(spanEnd, decEnd);
    -  
    -        var textNode = /** @type{Node} */ (spans[spanIndex + 1]);
    -        var styledText;
    -        if (textNode.nodeType !== 1  // Don't muck with <BR>s or <LI>s
    -            // Don't introduce spans around empty text nodes.
    -            && (styledText = source.substring(sourceIndex, end))) {
    -          // This may seem bizarre, and it is.  Emitting LF on IE causes the
    -          // code to display with spaces instead of line breaks.
    -          // Emitting Windows standard issue linebreaks (CRLF) causes a blank
    -          // space to appear at the beginning of every line but the first.
    -          // Emitting an old Mac OS 9 line separator makes everything spiffy.
    -          if (isIE8OrEarlier) {
    -            styledText = styledText.replace(newlineRe, '\r');
    -          }
    -          textNode.nodeValue = styledText;
    -          var document = textNode.ownerDocument;
    -          var span = document.createElement('span');
    -          span.className = decorations[decorationIndex + 1];
    -          var parentNode = textNode.parentNode;
    -          parentNode.replaceChild(span, textNode);
    -          span.appendChild(textNode);
    -          if (sourceIndex < spanEnd) {  // Split off a text node.
    -            spans[spanIndex + 1] = textNode
    -                // TODO: Possibly optimize by using '' if there's no flicker.
    -                = document.createTextNode(source.substring(end, spanEnd));
    -            parentNode.insertBefore(textNode, span.nextSibling);
    -          }
    -        }
    -  
    -        sourceIndex = end;
    -  
    -        if (sourceIndex >= spanEnd) {
    -          spanIndex += 2;
    -        }
    -        if (sourceIndex >= decEnd) {
    -          decorationIndex += 2;
    -        }
    -      }
    -    } finally {
    -      if (sourceNode) {
    -        sourceNode.style.display = oldDisplay;
    -      }
    -    }
    -  }
    -
    -  /** Maps language-specific file extensions to handlers. */
    -  var langHandlerRegistry = {};
    -  /** Register a language handler for the given file extensions.
    -    * @param {function (JobT)} handler a function from source code to a list
    -    *      of decorations.  Takes a single argument job which describes the
    -    *      state of the computation and attaches the decorations to it.
    -    * @param {Array.<string>} fileExtensions
    -    */
    -  function registerLangHandler(handler, fileExtensions) {
    -    for (var i = fileExtensions.length; --i >= 0;) {
    -      var ext = fileExtensions[i];
    -      if (!langHandlerRegistry.hasOwnProperty(ext)) {
    -        langHandlerRegistry[ext] = handler;
    -      } else if (win['console']) {
    -        console['warn']('cannot override language handler %s', ext);
    -      }
    -    }
    -  }
    -  function langHandlerForExtension(extension, source) {
    -    if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
    -      // Treat it as markup if the first non whitespace character is a < and
    -      // the last non-whitespace character is a >.
    -      extension = /^\s*</.test(source)
    -          ? 'default-markup'
    -          : 'default-code';
    -    }
    -    return langHandlerRegistry[extension];
    -  }
    -  registerLangHandler(decorateSource, ['default-code']);
    -  registerLangHandler(
    -      createSimpleLexer(
    -          [],
    -          [
    -           [PR_PLAIN,       /^[^<?]+/],
    -           [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
    -           [PR_COMMENT,     /^<\!--[\s\S]*?(?:-\->|$)/],
    -           // Unescaped content in an unknown language
    -           ['lang-',        /^<\?([\s\S]+?)(?:\?>|$)/],
    -           ['lang-',        /^<%([\s\S]+?)(?:%>|$)/],
    -           [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
    -           ['lang-',        /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
    -           // Unescaped content in javascript.  (Or possibly vbscript).
    -           ['lang-js',      /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
    -           // Contains unescaped stylesheet content
    -           ['lang-css',     /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
    -           ['lang-in.tag',  /^(<\/?[a-z][^<>]*>)/i]
    -          ]),
    -      ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
    -  registerLangHandler(
    -      createSimpleLexer(
    -          [
    -           [PR_PLAIN,        /^[\s]+/, null, ' \t\r\n'],
    -           [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
    -           ],
    -          [
    -           [PR_TAG,          /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
    -           [PR_ATTRIB_NAME,  /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
    -           ['lang-uq.val',   /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
    -           [PR_PUNCTUATION,  /^[=<>\/]+/],
    -           ['lang-js',       /^on\w+\s*=\s*\"([^\"]+)\"/i],
    -           ['lang-js',       /^on\w+\s*=\s*\'([^\']+)\'/i],
    -           ['lang-js',       /^on\w+\s*=\s*([^\"\'>\s]+)/i],
    -           ['lang-css',      /^style\s*=\s*\"([^\"]+)\"/i],
    -           ['lang-css',      /^style\s*=\s*\'([^\']+)\'/i],
    -           ['lang-css',      /^style\s*=\s*([^\"\'>\s]+)/i]
    -           ]),
    -      ['in.tag']);
    -  registerLangHandler(
    -      createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': CPP_KEYWORDS,
    -          'hashComments': true,
    -          'cStyleComments': true,
    -          'types': C_TYPES
    -        }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': 'null,true,false'
    -        }), ['json']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': CSHARP_KEYWORDS,
    -          'hashComments': true,
    -          'cStyleComments': true,
    -          'verbatimStrings': true,
    -          'types': C_TYPES
    -        }), ['cs']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': JAVA_KEYWORDS,
    -          'cStyleComments': true
    -        }), ['java']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': SH_KEYWORDS,
    -          'hashComments': true,
    -          'multiLineStrings': true
    -        }), ['bash', 'bsh', 'csh', 'sh']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': PYTHON_KEYWORDS,
    -          'hashComments': true,
    -          'multiLineStrings': true,
    -          'tripleQuotedStrings': true
    -        }), ['cv', 'py', 'python']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': PERL_KEYWORDS,
    -          'hashComments': true,
    -          'multiLineStrings': true,
    -          'regexLiterals': 2  // multiline regex literals
    -        }), ['perl', 'pl', 'pm']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': RUBY_KEYWORDS,
    -          'hashComments': true,
    -          'multiLineStrings': true,
    -          'regexLiterals': true
    -        }), ['rb', 'ruby']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': JSCRIPT_KEYWORDS,
    -          'cStyleComments': true,
    -          'regexLiterals': true
    -        }), ['javascript', 'js', 'ts', 'typescript']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': COFFEE_KEYWORDS,
    -          'hashComments': 3,  // ### style block comments
    -          'cStyleComments': true,
    -          'multilineStrings': true,
    -          'tripleQuotedStrings': true,
    -          'regexLiterals': true
    -        }), ['coffee']);
    -  registerLangHandler(
    -      createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
    -
    -  /** @param {JobT} job */
    -  function applyDecorator(job) {
    -    var opt_langExtension = job.langExtension;
    -
    -    try {
    -      // Extract tags, and convert the source code to plain text.
    -      var sourceAndSpans = extractSourceSpans(job.sourceNode, job.pre);
    -      /** Plain text. @type {string} */
    -      var source = sourceAndSpans.sourceCode;
    -      job.sourceCode = source;
    -      job.spans = sourceAndSpans.spans;
    -      job.basePos = 0;
    -
    -      // Apply the appropriate language handler
    -      langHandlerForExtension(opt_langExtension, source)(job);
    -
    -      // Integrate the decorations and tags back into the source code,
    -      // modifying the sourceNode in place.
    -      recombineTagsAndDecorations(job);
    -    } catch (e) {
    -      if (win['console']) {
    -        console['log'](e && e['stack'] || e);
    -      }
    -    }
    -  }
    -
    -  /**
    -   * Pretty print a chunk of code.
    -   * @param sourceCodeHtml {string} The HTML to pretty print.
    -   * @param opt_langExtension {string} The language name to use.
    -   *     Typically, a filename extension like 'cpp' or 'java'.
    -   * @param opt_numberLines {number|boolean} True to number lines,
    -   *     or the 1-indexed number of the first line in sourceCodeHtml.
    -   */
    -  function $prettyPrintOne(sourceCodeHtml, opt_langExtension, opt_numberLines) {
    -    /** @type{number|boolean} */
    -    var nl = opt_numberLines || false;
    -    /** @type{string|null} */
    -    var langExtension = opt_langExtension || null;
    -    /** @type{!Element} */
    -    var container = document.createElement('div');
    -    // This could cause images to load and onload listeners to fire.
    -    // E.g. <img onerror="alert(1337)" src="nosuchimage.png">.
    -    // We assume that the inner HTML is from a trusted source.
    -    // The pre-tag is required for IE8 which strips newlines from innerHTML
    -    // when it is injected into a <pre> tag.
    -    // http://stackoverflow.com/questions/451486/pre-tag-loses-line-breaks-when-setting-innerhtml-in-ie
    -    // http://stackoverflow.com/questions/195363/inserting-a-newline-into-a-pre-tag-ie-javascript
    -    container.innerHTML = '<pre>' + sourceCodeHtml + '</pre>';
    -    container = /** @type{!Element} */(container.firstChild);
    -    if (nl) {
    -      numberLines(container, nl, true);
    -    }
    -
    -    /** @type{JobT} */
    -    var job = {
    -      langExtension: langExtension,
    -      numberLines: nl,
    -      sourceNode: container,
    -      pre: 1,
    -      sourceCode: null,
    -      basePos: null,
    -      spans: null,
    -      decorations: null
    -    };
    -    applyDecorator(job);
    -    return container.innerHTML;
    -  }
    -
    -   /**
    -    * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
    -    * {@code class=prettyprint} and prettify them.
    -    *
    -    * @param {Function} opt_whenDone called when prettifying is done.
    -    * @param {HTMLElement|HTMLDocument} opt_root an element or document
    -    *   containing all the elements to pretty print.
    -    *   Defaults to {@code document.body}.
    -    */
    -  function $prettyPrint(opt_whenDone, opt_root) {
    -    var root = opt_root || document.body;
    -    var doc = root.ownerDocument || document;
    -    function byTagName(tn) { return root.getElementsByTagName(tn); }
    -    // fetch a list of nodes to rewrite
    -    var codeSegments = [byTagName('pre'), byTagName('code'), byTagName('xmp')];
    -    var elements = [];
    -    for (var i = 0; i < codeSegments.length; ++i) {
    -      for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
    -        elements.push(codeSegments[i][j]);
    -      }
    -    }
    -    codeSegments = null;
    -
    -    var clock = Date;
    -    if (!clock['now']) {
    -      clock = { 'now': function () { return +(new Date); } };
    -    }
    -
    -    // The loop is broken into a series of continuations to make sure that we
    -    // don't make the browser unresponsive when rewriting a large page.
    -    var k = 0;
    -
    -    var langExtensionRe = /\blang(?:uage)?-([\w.]+)(?!\S)/;
    -    var prettyPrintRe = /\bprettyprint\b/;
    -    var prettyPrintedRe = /\bprettyprinted\b/;
    -    var preformattedTagNameRe = /pre|xmp/i;
    -    var codeRe = /^code$/i;
    -    var preCodeXmpRe = /^(?:pre|code|xmp)$/i;
    -    var EMPTY = {};
    -
    -    function doWork() {
    -      var endTime = (win['PR_SHOULD_USE_CONTINUATION'] ?
    -                     clock['now']() + 250 /* ms */ :
    -                     Infinity);
    -      for (; k < elements.length && clock['now']() < endTime; k++) {
    -        var cs = elements[k];
    -
    -        // Look for a preceding comment like
    -        // <?prettify lang="..." linenums="..."?>
    -        var attrs = EMPTY;
    -        {
    -          for (var preceder = cs; (preceder = preceder.previousSibling);) {
    -            var nt = preceder.nodeType;
    -            // <?foo?> is parsed by HTML 5 to a comment node (8)
    -            // like <!--?foo?-->, but in XML is a processing instruction
    -            var value = (nt === 7 || nt === 8) && preceder.nodeValue;
    -            if (value
    -                ? !/^\??prettify\b/.test(value)
    -                : (nt !== 3 || /\S/.test(preceder.nodeValue))) {
    -              // Skip over white-space text nodes but not others.
    -              break;
    -            }
    -            if (value) {
    -              attrs = {};
    -              value.replace(
    -                  /\b(\w+)=([\w:.%+-]+)/g,
    -                function (_, name, value) { attrs[name] = value; });
    -              break;
    -            }
    -          }
    -        }
    -
    -        var className = cs.className;
    -        if ((attrs !== EMPTY || prettyPrintRe.test(className))
    -            // Don't redo this if we've already done it.
    -            // This allows recalling pretty print to just prettyprint elements
    -            // that have been added to the page since last call.
    -            && !prettyPrintedRe.test(className)) {
    -
    -          // make sure this is not nested in an already prettified element
    -          var nested = false;
    -          for (var p = cs.parentNode; p; p = p.parentNode) {
    -            var tn = p.tagName;
    -            if (preCodeXmpRe.test(tn)
    -                && p.className && prettyPrintRe.test(p.className)) {
    -              nested = true;
    -              break;
    -            }
    -          }
    -          if (!nested) {
    -            // Mark done.  If we fail to prettyprint for whatever reason,
    -            // we shouldn't try again.
    -            cs.className += ' prettyprinted';
    -
    -            // If the classes includes a language extensions, use it.
    -            // Language extensions can be specified like
    -            //     <pre class="prettyprint lang-cpp">
    -            // the language extension "cpp" is used to find a language handler
    -            // as passed to PR.registerLangHandler.
    -            // HTML5 recommends that a language be specified using "language-"
    -            // as the prefix instead.  Google Code Prettify supports both.
    -            // http://dev.w3.org/html5/spec-author-view/the-code-element.html
    -            var langExtension = attrs['lang'];
    -            if (!langExtension) {
    -              langExtension = className.match(langExtensionRe);
    -              // Support <pre class="prettyprint"><code class="language-c">
    -              var wrapper;
    -              if (!langExtension && (wrapper = childContentWrapper(cs))
    -                  && codeRe.test(wrapper.tagName)) {
    -                langExtension = wrapper.className.match(langExtensionRe);
    -              }
    -
    -              if (langExtension) { langExtension = langExtension[1]; }
    -            }
    -
    -            var preformatted;
    -            if (preformattedTagNameRe.test(cs.tagName)) {
    -              preformatted = 1;
    -            } else {
    -              var currentStyle = cs['currentStyle'];
    -              var defaultView = doc.defaultView;
    -              var whitespace = (
    -                  currentStyle
    -                  ? currentStyle['whiteSpace']
    -                  : (defaultView
    -                     && defaultView.getComputedStyle)
    -                  ? defaultView.getComputedStyle(cs, null)
    -                  .getPropertyValue('white-space')
    -                  : 0);
    -              preformatted = whitespace
    -                  && 'pre' === whitespace.substring(0, 3);
    -            }
    -
    -            // Look for a class like linenums or linenums:<n> where <n> is the
    -            // 1-indexed number of the first line.
    -            var lineNums = attrs['linenums'];
    -            if (!(lineNums = lineNums === 'true' || +lineNums)) {
    -              lineNums = className.match(/\blinenums\b(?::(\d+))?/);
    -              lineNums =
    -                lineNums
    -                ? lineNums[1] && lineNums[1].length
    -                  ? +lineNums[1] : true
    -                : false;
    -            }
    -            if (lineNums) { numberLines(cs, lineNums, preformatted); }
    -
    -            // do the pretty printing
    -            var prettyPrintingJob = {
    -              langExtension: langExtension,
    -              sourceNode: cs,
    -              numberLines: lineNums,
    -              pre: preformatted,
    -              sourceCode: null,
    -              basePos: null,
    -              spans: null,
    -              decorations: null
    -            };
    -            applyDecorator(prettyPrintingJob);
    -          }
    -        }
    -      }
    -      if (k < elements.length) {
    -        // finish up in a continuation
    -        win.setTimeout(doWork, 250);
    -      } else if ('function' === typeof opt_whenDone) {
    -        opt_whenDone();
    -      }
    -    }
    -
    -    doWork();
    -  }
    -
    -  /**
    -   * Contains functions for creating and registering new language handlers.
    -   * @type {Object}
    -   */
    -  var PR = win['PR'] = {
    -        'createSimpleLexer': createSimpleLexer,
    -        'registerLangHandler': registerLangHandler,
    -        'sourceDecorator': sourceDecorator,
    -        'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
    -        'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
    -        'PR_COMMENT': PR_COMMENT,
    -        'PR_DECLARATION': PR_DECLARATION,
    -        'PR_KEYWORD': PR_KEYWORD,
    -        'PR_LITERAL': PR_LITERAL,
    -        'PR_NOCODE': PR_NOCODE,
    -        'PR_PLAIN': PR_PLAIN,
    -        'PR_PUNCTUATION': PR_PUNCTUATION,
    -        'PR_SOURCE': PR_SOURCE,
    -        'PR_STRING': PR_STRING,
    -        'PR_TAG': PR_TAG,
    -        'PR_TYPE': PR_TYPE,
    -        'prettyPrintOne':
    -           IN_GLOBAL_SCOPE
    -             ? (win['prettyPrintOne'] = $prettyPrintOne)
    -             : (prettyPrintOne = $prettyPrintOne),
    -        'prettyPrint': prettyPrint =
    -           IN_GLOBAL_SCOPE
    -             ? (win['prettyPrint'] = $prettyPrint)
    -             : (prettyPrint = $prettyPrint)
    -      };
    -
    -  // Make PR available via the Asynchronous Module Definition (AMD) API.
    -  // Per https://github.com/amdjs/amdjs-api/wiki/AMD:
    -  // The Asynchronous Module Definition (AMD) API specifies a
    -  // mechanism for defining modules such that the module and its
    -  // dependencies can be asynchronously loaded.
    -  // ...
    -  // To allow a clear indicator that a global define function (as
    -  // needed for script src browser loading) conforms to the AMD API,
    -  // any global define function SHOULD have a property called "amd"
    -  // whose value is an object. This helps avoid conflict with any
    -  // other existing JavaScript code that could have defined a define()
    -  // function that does not conform to the AMD API.
    -  var define = win['define'];
    -  if (typeof define === "function" && define['amd']) {
    -    define("google-code-prettify", [], function () {
    -      return PR;
    -    });
    -  }
    -})();
    diff --git a/source/plugins/prettify/prettify.min.js b/source/plugins/prettify/prettify.min.js
    deleted file mode 100644
    index 745aef6b..00000000
    --- a/source/plugins/prettify/prettify.min.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -!function(){var e=null;window.PR_SHOULD_USE_CONTINUATION=!0,function(){function t(e){function t(e){var t=e.charCodeAt(0);if(92!==t)return t;var i=e.charAt(1);return(t=u[i])?t:i>="0"&&"7">=i?parseInt(e.substring(1),8):"u"===i||"x"===i?parseInt(e.substring(2),16):e.charCodeAt(1)}function i(e){return 32>e?(16>e?"\\x0":"\\x")+e.toString(16):(e=String.fromCharCode(e),"\\"===e||"-"===e||"]"===e||"^"===e?"\\"+e:e)}function n(e){var n=e.substring(1,e.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),e=[],r="^"===n[0],s=["["];r&&s.push("^");for(var r=r?1:0,o=n.length;o>r;++r){var a=n[r];if(/\\[bdsw]/i.test(a))s.push(a);else{var l,a=t(a);o>r+2&&"-"===n[r+1]?(l=t(n[r+2]),r+=2):l=a,e.push([a,l]),65>l||a>122||(65>l||a>90||e.push([32|Math.max(65,a),32|Math.min(l,90)]),97>l||a>122||e.push([-33&Math.max(97,a),-33&Math.min(l,122)]))}}for(e.sort(function(e,t){return e[0]-t[0]||t[1]-e[1]}),n=[],o=[],r=0;e.length>r;++r)a=e[r],a[0]<=o[1]+1?o[1]=Math.max(o[1],a[1]):n.push(o=a);for(r=0;n.length>r;++r)a=n[r],s.push(i(a[0])),a[1]>a[0]&&(a[1]+1>a[0]&&s.push("-"),s.push(i(a[1])));return s.push("]"),s.join("")}function r(e){for(var t=e.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),r=t.length,a=[],l=0,h=0;r>l;++l){var c=t[l];"("===c?++h:"\\"===c.charAt(0)&&(c=+c.substring(1))&&(h>=c?a[c]=-1:t[l]=i(c))}for(l=1;a.length>l;++l)-1===a[l]&&(a[l]=++s);for(h=l=0;r>l;++l)c=t[l],"("===c?(++h,a[h]||(t[l]="(?:")):"\\"===c.charAt(0)&&(c=+c.substring(1))&&h>=c&&(t[l]="\\"+a[c]);for(l=0;r>l;++l)"^"===t[l]&&"^"!==t[l+1]&&(t[l]="");if(e.ignoreCase&&o)for(l=0;r>l;++l)c=t[l],e=c.charAt(0),c.length>=2&&"["===e?t[l]=n(c):"\\"!==e&&(t[l]=c.replace(/[A-Za-z]/g,function(e){return e=e.charCodeAt(0),"["+String.fromCharCode(-33&e,32|e)+"]"}));return t.join("")}for(var s=0,o=!1,a=!1,l=0,h=e.length;h>l;++l){var c=e[l];if(c.ignoreCase)a=!0;else if(/[a-z]/i.test(c.source.replace(/\\u[\da-f]{4}|\\x[\da-f]{2}|\\[^UXux]/gi,""))){o=!0,a=!1;break}}for(var u={b:8,t:9,n:10,v:11,f:12,r:13},d=[],l=0,h=e.length;h>l;++l){if(c=e[l],c.global||c.multiline)throw Error(""+c);d.push("(?:"+r(c)+")")}return RegExp(d.join("|"),a?"gi":"g")}function i(e,t){function i(e){var l=e.nodeType;if(1==l){if(!n.test(e.className)){for(l=e.firstChild;l;l=l.nextSibling)i(l);l=e.nodeName.toLowerCase(),("br"===l||"li"===l)&&(r[a]="\n",o[a<<1]=s++,o[1|a++<<1]=e)}}else(3==l||4==l)&&(l=e.nodeValue,l.length&&(l=t?l.replace(/\r\n?/g,"\n"):l.replace(/[\t\n\r ]+/g," "),r[a]=l,o[a<<1]=s,s+=l.length,o[1|a++<<1]=e))}var n=/(?:^|\s)nocode(?:\s|$)/,r=[],s=0,o=[],a=0;return i(e),{a:r.join("").replace(/\n$/,""),d:o}}function n(e,t,i,n){t&&(e={a:t,e:e},i(e),n.push.apply(n,e.g))}function r(e){for(var t=void 0,i=e.firstChild;i;i=i.nextSibling)var n=i.nodeType,t=1===n?t?e:i:3===n?x.test(i.nodeValue)?e:t:t;return t===e?void 0:t}function s(i,r){function s(e){for(var t=e.e,i=[t,"pln"],c=0,u=e.a.match(o)||[],d={},p=0,f=u.length;f>p;++p){var m,g=u[p],y=d[g],v=void 0;if("string"==typeof y)m=!1;else{var b=a[g.charAt(0)];if(b)v=g.match(b[1]),y=b[0];else{for(m=0;l>m;++m)if(b=r[m],v=g.match(b[1])){y=b[0];break}v||(y="pln")}!(m=y.length>=5&&"lang-"===y.substring(0,5))||v&&"string"==typeof v[1]||(m=!1,y="src"),m||(d[g]=y)}if(b=c,c+=g.length,m){m=v[1];var L=g.indexOf(m),x=L+m.length;v[2]&&(x=g.length-v[2].length,L=x-m.length),y=y.substring(5),n(t+b,g.substring(0,L),s,i),n(t+b+L,m,h(y,m),i),n(t+b+x,g.substring(x),s,i)}else i.push(t+b,y)}e.g=i}var o,a={};(function(){for(var n=i.concat(r),s=[],l={},h=0,c=n.length;c>h;++h){var u=n[h],d=u[3];if(d)for(var p=d.length;--p>=0;)a[d.charAt(p)]=u;u=u[1],d=""+u,l.hasOwnProperty(d)||(s.push(u),l[d]=e)}s.push(/[\S\s]/),o=t(s)})();var l=r.length;return s}function o(t){var i=[],n=[];t.tripleQuotedStrings?i.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,e,"'\""]):t.multiLineStrings?i.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/,e,"'\"`"]):i.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,e,"\"'"]),t.verbatimStrings&&n.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,e]);var r=t.hashComments;if(r&&(t.cStyleComments?(r>1?i.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,e,"#"]):i.push(["com",/^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\n\r]*)/,e,"#"]),n.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,e])):i.push(["com",/^#[^\n\r]*/,e,"#"])),t.cStyleComments&&(n.push(["com",/^\/\/[^\n\r]*/,e]),n.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,e])),r=t.regexLiterals){var o=(r=r>1?"":"\n\r")?".":"[\\S\\s]";n.push(["lang-regex",RegExp("^(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*("+("/(?=[^/*"+r+"])(?:[^/\\x5B\\x5C"+r+"]|\\x5C"+o+"|\\x5B(?:[^\\x5C\\x5D"+r+"]|\\x5C"+o+")*(?:\\x5D|$))+/")+")")])}return(r=t.types)&&n.push(["typ",r]),r=(""+t.keywords).replace(/^ | $/g,""),r.length&&n.push(["kwd",RegExp("^(?:"+r.replace(/[\s,]+/g,"|")+")\\b"),e]),i.push(["pln",/^\s+/,e," \r\n	 "]),r="^.[^\\s\\w.$@'\"`/\\\\]*",t.regexLiterals&&(r+="(?!s*/)"),n.push(["lit",/^@[$_a-z][\w$@]*/i,e],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,e],["pln",/^[$_a-z][\w$@]*/i,e],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,e,"0123456789"],["pln",/^\\[\S\s]?/,e],["pun",RegExp(r),e]),s(i,n)}function a(e,t,i){function n(e){var t=e.nodeType;if(1!=t||s.test(e.className)){if((3==t||4==t)&&i){var l=e.nodeValue,h=l.match(o);h&&(t=l.substring(0,h.index),e.nodeValue=t,(l=l.substring(h.index+h[0].length))&&e.parentNode.insertBefore(a.createTextNode(l),e.nextSibling),r(e),t||e.parentNode.removeChild(e))}}else if("br"===e.nodeName)r(e),e.parentNode&&e.parentNode.removeChild(e);else for(e=e.firstChild;e;e=e.nextSibling)n(e)}function r(e){function t(e,i){var n=i?e.cloneNode(!1):e,r=e.parentNode;if(r){var r=t(r,1),s=e.nextSibling;r.appendChild(n);for(var o=s;o;o=s)s=o.nextSibling,r.appendChild(o)}return n}for(;!e.nextSibling;)if(e=e.parentNode,!e)return;for(var i,e=t(e.nextSibling,0);(i=e.parentNode)&&1===i.nodeType;)e=i;h.push(e)}for(var s=/(?:^|\s)nocode(?:\s|$)/,o=/\r\n?|\n/,a=e.ownerDocument,l=a.createElement("li");e.firstChild;)l.appendChild(e.firstChild);for(var h=[l],c=0;h.length>c;++c)n(h[c]);t===(0|t)&&h[0].setAttribute("value",t);var u=a.createElement("ol");u.className="linenums";for(var t=Math.max(0,0|t-1)||0,c=0,d=h.length;d>c;++c)l=h[c],l.className="L"+(c+t)%10,l.firstChild||l.appendChild(a.createTextNode(" ")),u.appendChild(l);e.appendChild(u)}function l(e,t){for(var i=t.length;--i>=0;){var n=t[i];w.hasOwnProperty(n)?u.console&&console.warn("cannot override language handler %s",n):w[n]=e}}function h(e,t){return e&&w.hasOwnProperty(e)||(e=/^\s*</.test(t)?"default-markup":"default-code"),w[e]}function c(e){var t=e.h;try{var n=i(e.c,e.i),r=n.a;e.a=r,e.d=n.d,e.e=0,h(t,r)(e);var s=/\bMSIE\s(\d+)/.exec(navigator.userAgent),s=s&&8>=+s[1],t=/\n/g,o=e.a,a=o.length,n=0,l=e.d,c=l.length,r=0,d=e.g,p=d.length,f=0;d[p]=a;var m,g;for(g=m=0;p>g;)d[g]!==d[g+2]?(d[m++]=d[g++],d[m++]=d[g++]):g+=2;for(p=m,g=m=0;p>g;){for(var y=d[g],v=d[g+1],b=g+2;p>=b+2&&d[b+1]===v;)b+=2;d[m++]=y,d[m++]=v,g=b}d.length=m;var L,x=e.c;x&&(L=x.style.display,x.style.display="none");try{for(;c>r;){var C,w=l[r+2]||a,S=d[f+2]||a,b=Math.min(w,S),O=l[r+1];if(1!==O.nodeType&&(C=o.substring(n,b))){s&&(C=C.replace(t,"\r")),O.nodeValue=C;var _=O.ownerDocument,E=_.createElement("span");E.className=d[f+1];var k=O.parentNode;k.replaceChild(E,O),E.appendChild(O),w>n&&(l[r+1]=O=_.createTextNode(o.substring(b,w)),k.insertBefore(O,E.nextSibling))}n=b,n>=w&&(r+=2),n>=S&&(f+=2)}}finally{x&&(x.style.display=L)}}catch(T){u.console&&console.log(T&&T.stack||T)}}var u=window,d=["break,continue,do,else,for,if,return,while"],p=[[d,"auto,case,char,const,default,double,enum,extern,float,goto,inline,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],f=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,delegate,dynamic_cast,explicit,export,friend,generic,late_check,mutable,namespace,nullptr,property,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],m=[p,"abstract,assert,boolean,byte,extends,final,finally,implements,import,instanceof,interface,null,native,package,strictfp,super,synchronized,throws,transient"],g=[m,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,internal,into,is,let,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var,virtual,where"],p=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],y=[d,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],v=[d,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],b=[d,"as,assert,const,copy,drop,enum,extern,fail,false,fn,impl,let,log,loop,match,mod,move,mut,priv,pub,pure,ref,self,static,struct,true,trait,type,unsafe,use"],d=[d,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],L=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)\b/,x=/\S/,C=o({keywords:[f,g,p,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",y,v,d],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),w={};l(C,["default-code"]),l(s([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]),l(s([["pln",/^\s+/,e," 	\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,e,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css",/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]),l(s([],[["atv",/^[\S\s]+/]]),["uq.val"]),l(o({keywords:f,hashComments:!0,cStyleComments:!0,types:L}),["c","cc","cpp","cxx","cyc","m"]),l(o({keywords:"null,true,false"}),["json"]),l(o({keywords:g,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:L}),["cs"]),l(o({keywords:m,cStyleComments:!0}),["java"]),l(o({keywords:d,hashComments:!0,multiLineStrings:!0}),["bash","bsh","csh","sh"]),l(o({keywords:y,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),["cv","py","python"]),l(o({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:2}),["perl","pl","pm"]),l(o({keywords:v,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb","ruby"]),l(o({keywords:p,cStyleComments:!0,regexLiterals:!0}),["javascript","js"]),l(o({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,throw,true,try,unless,until,when,while,yes",hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]),l(o({keywords:b,cStyleComments:!0,multilineStrings:!0}),["rc","rs","rust"]),l(s([],[["str",/^[\S\s]+/]]),["regex"]);var S=u.PR={createSimpleLexer:s,registerLangHandler:l,sourceDecorator:o,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ",prettyPrintOne:u.prettyPrintOne=function(e,t,i){var n=document.createElement("div");return n.innerHTML="<pre>"+e+"</pre>",n=n.firstChild,i&&a(n,i,!0),c({h:t,j:i,c:n,i:1}),n.innerHTML},prettyPrint:u.prettyPrint=function(t,i){function n(){for(var i=u.PR_SHOULD_USE_CONTINUATION?f.now()+250:1/0;l.length>g&&i>f.now();g++){for(var s=l[g],h=w,d=s;d=d.previousSibling;){var p=d.nodeType,S=(7===p||8===p)&&d.nodeValue;if(S?!/^\??prettify\b/.test(S):3!==p||/\S/.test(d.nodeValue))break;if(S){h={},S.replace(/\b(\w+)=([\w%+\-.:]+)/g,function(e,t,i){h[t]=i});break}}if(d=s.className,(h!==w||v.test(d))&&!b.test(d)){for(p=!1,S=s.parentNode;S;S=S.parentNode)if(C.test(S.tagName)&&S.className&&v.test(S.className)){p=!0;break}if(!p){if(s.className+=" prettyprinted",p=h.lang,!p){var O,p=d.match(y);!p&&(O=r(s))&&x.test(O.tagName)&&(p=O.className.match(y)),p&&(p=p[1])}if(L.test(s.tagName))S=1;else var S=s.currentStyle,_=o.defaultView,S=(S=S?S.whiteSpace:_&&_.getComputedStyle?_.getComputedStyle(s,e).getPropertyValue("white-space"):0)&&"pre"===S.substring(0,3);_=h.linenums,(_="true"===_||+_)||(_=(_=d.match(/\blinenums\b(?::(\d+))?/))?_[1]&&_[1].length?+_[1]:!0:!1),_&&a(s,_,S),m={h:p,c:s,j:_,i:S},c(m)}}}l.length>g?setTimeout(n,250):"function"==typeof t&&t()}for(var s=i||document.body,o=s.ownerDocument||document,s=[s.getElementsByTagName("pre"),s.getElementsByTagName("code"),s.getElementsByTagName("xmp")],l=[],h=0;s.length>h;++h)for(var d=0,p=s[h].length;p>d;++d)l.push(s[h][d]);var s=e,f=Date;f.now||(f={now:function(){return+new Date}});var m,g=0,y=/\blang(?:uage)?-([\w.]+)(?!\S)/,v=/\bprettyprint\b/,b=/\bprettyprinted\b/,L=/pre|xmp/i,x=/^code$/i,C=/^(?:pre|code|xmp)$/i,w={};n()}};"function"==typeof define&&define.amd&&define("google-code-prettify",[],function(){return S})}()}();
    \ No newline at end of file
    diff --git a/source/plugins/prettify/run_prettify.js b/source/plugins/prettify/run_prettify.js
    deleted file mode 100644
    index 8833b34f..00000000
    --- a/source/plugins/prettify/run_prettify.js
    +++ /dev/null
    @@ -1,1995 +0,0 @@
    -/**
    - * @license
    - * Copyright (C) 2013 Google Inc.
    - *
    - * Licensed under the Apache License, Version 2.0 (the "License");
    - * you may not use this file except in compliance with the License.
    - * You may obtain a copy of the License at
    - *
    - *      http://www.apache.org/licenses/LICENSE-2.0
    - *
    - * Unless required by applicable law or agreed to in writing, software
    - * distributed under the License is distributed on an "AS IS" BASIS,
    - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    - * See the License for the specific language governing permissions and
    - * limitations under the License.
    - */
    -
    -/**
    - * @fileoverview
    - * <div style="white-space: pre">
    - * Looks at query parameters to decide which language handlers and style-sheets
    - * to load.
    - *
    - * Query Parameter     Format           Effect                        Default
    - * +------------------+---------------+------------------------------+--------+
    - * | autorun=         | true | false  | If true then prettyPrint()   | "true" |
    - * |                  |               | is called on page load.      |        |
    - * +------------------+---------------+------------------------------+--------+
    - * | lang=            | language name | Loads the language handler   | Can    |
    - * |                  |               | named "lang-<NAME>.js".      | appear |
    - * |                  |               | See available handlers at    | many   |
    - * |                  |               | https://github.com/google/   | times. |
    - * |                  |               | code-prettify/tree/master/   |        |
    - * |                  |               | src                          |        |
    - * +------------------+---------------+------------------------------+--------+
    - * | skin=            | skin name     | Loads the skin stylesheet    | none.  |
    - * |                  |               | named "<NAME>.css".          |        |
    - * |                  |               | https://cdn.rawgit.com/      |        |
    - * |                  |               | google/code-prettify/master/ |        |
    - * |                  |               | styles/index.html            |        |
    - * +------------------+---------------+------------------------------+--------+
    - * | callback=        | JS identifier | When "prettyPrint" finishes  | none   |
    - * |                  |               | window.exports[js_ident] is  |        |
    - * |                  |               | called.                      |        |
    - * |                  |               | The callback must be under   |        |
    - * |                  |               | exports to reduce the risk   |        |
    - * |                  |               | of XSS via query parameter   |        |
    - * |                  |               | injection.                   |        |
    - * +------------------+---------------+------------------------------+--------+
    - *
    - * Exmaples
    - * .../prettify.js?lang=css&skin=sunburst
    - *   1. Loads the CSS language handler which can be used to prettify CSS
    - *      stylesheets, HTML <style> element bodies and style="..." attributes
    - *      values.
    - *   2. Loads the sunburst.css stylesheet instead of the default prettify.css
    - *      stylesheet.
    - *      A gallery of stylesheets is available at
    - *      https://cdn.rawgit.com/google/code-prettify/master/styles/index.html
    - *   3. Since autorun=false is not specified, calls prettyPrint() on page load.
    - * </div>
    - */
    -
    -/**
    -* @typedef {!Array.<number|string>}
    -* Alternating indices and the decorations that should be inserted there.
    -* The indices are monotonically increasing.
    -*/
    -var DecorationsT;
    -
    -/**
    -* @typedef {!{
    -*   sourceNode: !Element,
    -*   pre: !(number|boolean),
    -*   langExtension: ?string,
    -*   numberLines: ?(number|boolean),
    -*   sourceCode: ?string,
    -*   spans: ?(Array.<number|Node>),
    -*   basePos: ?number,
    -*   decorations: ?DecorationsT
    -* }}
    -* <dl>
    -*  <dt>sourceNode<dd>the element containing the source
    -*  <dt>sourceCode<dd>source as plain text
    -*  <dt>pre<dd>truthy if white-space in text nodes
    -*     should be considered significant.
    -*  <dt>spans<dd> alternating span start indices into source
    -*     and the text node or element (e.g. {@code <BR>}) corresponding to that
    -*     span.
    -*  <dt>decorations<dd>an array of style classes preceded
    -*     by the position at which they start in job.sourceCode in order
    -*  <dt>basePos<dd>integer position of this.sourceCode in the larger chunk of
    -*     source.
    -* </dl>
    -*/
    -var JobT;
    -
    -/**
    -* @typedef {!{
    -*   sourceCode: string,
    -*   spans: !(Array.<number|Node>)
    -* }}
    -* <dl>
    -*  <dt>sourceCode<dd>source as plain text
    -*  <dt>spans<dd> alternating span start indices into source
    -*     and the text node or element (e.g. {@code <BR>}) corresponding to that
    -*     span.
    -* </dl>
    -*/
    -var SourceSpansT;
    -
    -/** @define {boolean} */
    -var IN_GLOBAL_SCOPE = false;
    -
    -(function () {
    -  "use strict";
    -
    -  var win = window;
    -  var doc = document;
    -  var root = doc.documentElement;
    -  var head = doc['head'] || doc.getElementsByTagName("head")[0] || root;
    -
    -  // From http://javascript.nwbox.com/ContentLoaded/contentloaded.js
    -  // Author: Diego Perini (diego.perini at gmail.com)
    -  // Summary: cross-browser wrapper for DOMContentLoaded
    -  // Updated: 20101020
    -  // License: MIT
    -  // Version: 1.2
    -  function contentLoaded(callback) {
    -    var addEventListener = doc['addEventListener'];
    -    var done = false, top = true,
    -        add = addEventListener ? 'addEventListener' : 'attachEvent',
    -        rem = addEventListener ? 'removeEventListener' : 'detachEvent',
    -        pre = addEventListener ? '' : 'on',
    -
    -        init = function(e) {
    -          if (e.type == 'readystatechange' && doc.readyState != 'complete') {
    -            return;
    -          }
    -          (e.type == 'load' ? win : doc)[rem](pre + e.type, init, false);
    -          if (!done && (done = true)) { callback.call(win, e.type || e); }
    -        },
    -
    -        poll = function() {
    -          try {
    -            root.doScroll('left');
    -          } catch(e) {
    -            win.setTimeout(poll, 50);
    -            return;
    -          }
    -          init('poll');
    -        };
    -
    -    if (doc.readyState == 'complete') {
    -      callback.call(win, 'lazy');
    -    } else {
    -      if (doc.createEventObject && root.doScroll) {
    -        try { top = !win.frameElement; } catch(e) { }
    -        if (top) { poll(); }
    -      }
    -      doc[add](pre + 'DOMContentLoaded', init, false);
    -      doc[add](pre + 'readystatechange', init, false);
    -      win[add](pre + 'load', init, false);
    -    }
    -  }
    -
    -  // Given a list of URLs to stylesheets, loads the first that loads without
    -  // triggering an error event.
    -  function loadStylesheetsFallingBack(stylesheets) {
    -    var n = stylesheets.length;
    -    function load(i) {
    -      if (i === n) { return; }
    -      var link = doc.createElement('link');
    -      link.rel = 'stylesheet';
    -      link.type = 'text/css';
    -      if (i + 1 < n) {
    -        // http://pieisgood.org/test/script-link-events/ indicates that many
    -        // versions of IE do not support onerror on <link>s, though
    -        // http://msdn.microsoft.com/en-us/library/ie/ms535848(v=vs.85).aspx
    -        // indicates that recent IEs do support error.
    -        link.error = link.onerror = function () { load(i + 1); };
    -      }
    -      link.href = stylesheets[i];
    -      head.appendChild(link);
    -    }
    -    load(0);
    -  }
    -
    -  var scriptQuery = '';
    -  // Look for the <script> node that loads this script to get its parameters.
    -  // This starts looking at the end instead of just considering the last
    -  // because deferred and async scripts run out of order.
    -  // If the script is loaded twice, then this will run in reverse order.
    -  var scripts = doc.getElementsByTagName('script');
    -  for (var i = scripts.length; --i >= 0;) {
    -    var script = scripts[i];
    -    var match = script.src.match(
    -        /^[^?#]*\/run_prettify\.js(\?[^#]*)?(?:#.*)?$/);
    -    if (match) {
    -      scriptQuery = match[1] || '';
    -      // Remove the script from the DOM so that multiple runs at least run
    -      // multiple times even if parameter sets are interpreted in reverse
    -      // order.
    -      script.parentNode.removeChild(script);
    -      break;
    -    }
    -  }
    -
    -  // Pull parameters into local variables.
    -  var autorun = true;
    -  var langs = [];
    -  var skins = [];
    -  var callbacks = [];
    -  scriptQuery.replace(
    -      /[?&]([^&=]+)=([^&]+)/g,
    -      function (_, name, value) {
    -        value = decodeURIComponent(value);
    -        name = decodeURIComponent(name);
    -        if (name == 'autorun')   { autorun = !/^[0fn]/i.test(value); } else
    -        if (name == 'lang')      { langs.push(value);                } else
    -        if (name == 'skin')      { skins.push(value);                } else
    -        if (name == 'callback')  { callbacks.push(value);            }
    -      });
    -
    -  // Use https to avoid mixed content warnings in client pages and to
    -  // prevent a MITM from rewrite prettify mid-flight.
    -  // This only works if this script is loaded via https : something
    -  // over which we exercise no control.
    -  var LOADER_BASE_URL =
    -     'https://cdn.rawgit.com/google/code-prettify/master/loader';
    -
    -  for (var i = 0, n = langs.length; i < n; ++i) (function (lang) {
    -    var script = doc.createElement("script");
    -
    -    // Excerpted from jQuery.ajaxTransport("script") to fire events when
    -    // a script is finished loading.
    -    // Attach handlers for each script
    -    script.onload = script.onerror = script.onreadystatechange = function () {
    -      if (script && (
    -            !script.readyState || /loaded|complete/.test(script.readyState))) {
    -        // Handle memory leak in IE
    -        script.onerror = script.onload = script.onreadystatechange = null;
    -
    -        --pendingLanguages;
    -        checkPendingLanguages();
    -
    -        // Remove the script
    -        if (script.parentNode) {
    -          script.parentNode.removeChild(script);
    -        }
    -
    -        script = null;
    -      }
    -    };
    -
    -    script.type = 'text/javascript';
    -    script.src = LOADER_BASE_URL
    -      + '/lang-' + encodeURIComponent(langs[i]) + '.js';
    -
    -    // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
    -    head.insertBefore(script, head.firstChild);
    -  })(langs[i]);
    -
    -  var pendingLanguages = langs.length;
    -  function checkPendingLanguages() {
    -    if (!pendingLanguages) {
    -      win.setTimeout(onLangsLoaded, 0);
    -    }
    -  }
    -
    -  var skinUrls = [];
    -  for (var i = 0, n = skins.length; i < n; ++i) {
    -    skinUrls.push(LOADER_BASE_URL
    -        + '/skins/' + encodeURIComponent(skins[i]) + '.css');
    -  }
    -  skinUrls.push(LOADER_BASE_URL + '/prettify.css');
    -  loadStylesheetsFallingBack(skinUrls);
    -
    -  var prettyPrint = (function () {
    -    /**
    -     * @license
    -     * Copyright (C) 2006 Google Inc.
    -     *
    -     * Licensed under the Apache License, Version 2.0 (the "License");
    -     * you may not use this file except in compliance with the License.
    -     * You may obtain a copy of the License at
    -     *
    -     *      http://www.apache.org/licenses/LICENSE-2.0
    -     *
    -     * Unless required by applicable law or agreed to in writing, software
    -     * distributed under the License is distributed on an "AS IS" BASIS,
    -     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    -     * See the License for the specific language governing permissions and
    -     * limitations under the License.
    -     */
    -    
    -    /**
    -     * @fileoverview
    -     * some functions for browser-side pretty printing of code contained in html.
    -     *
    -     * <p>
    -     * For a fairly comprehensive set of languages see the
    -     * <a href="https://github.com/google/code-prettify#for-which-languages-does-it-work">README</a>
    -     * file that came with this source.  At a minimum, the lexer should work on a
    -     * number of languages including C and friends, Java, Python, Bash, SQL, HTML,
    -     * XML, CSS, Javascript, and Makefiles.  It works passably on Ruby, PHP and Awk
    -     * and a subset of Perl, but, because of commenting conventions, doesn't work on
    -     * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class.
    -     * <p>
    -     * Usage: <ol>
    -     * <li> include this source file in an html page via
    -     *   {@code <script type="text/javascript" src="/path/to/prettify.js"></script>}
    -     * <li> define style rules.  See the example page for examples.
    -     * <li> mark the {@code <pre>} and {@code <code>} tags in your source with
    -     *    {@code class=prettyprint.}
    -     *    You can also use the (html deprecated) {@code <xmp>} tag, but the pretty
    -     *    printer needs to do more substantial DOM manipulations to support that, so
    -     *    some css styles may not be preserved.
    -     * </ol>
    -     * That's it.  I wanted to keep the API as simple as possible, so there's no
    -     * need to specify which language the code is in, but if you wish, you can add
    -     * another class to the {@code <pre>} or {@code <code>} element to specify the
    -     * language, as in {@code <pre class="prettyprint lang-java">}.  Any class that
    -     * starts with "lang-" followed by a file extension, specifies the file type.
    -     * See the "lang-*.js" files in this directory for code that implements
    -     * per-language file handlers.
    -     * <p>
    -     * Change log:<br>
    -     * cbeust, 2006/08/22
    -     * <blockquote>
    -     *   Java annotations (start with "@") are now captured as literals ("lit")
    -     * </blockquote>
    -     * @requires console
    -     */
    -    
    -    // JSLint declarations
    -    /*global console, document, navigator, setTimeout, window, define */
    -    
    -    
    -    /**
    -     * {@type !{
    -     *   'createSimpleLexer': function (Array, Array): (function (JobT)),
    -     *   'registerLangHandler': function (function (JobT), Array.<string>),
    -     *   'PR_ATTRIB_NAME': string,
    -     *   'PR_ATTRIB_NAME': string,
    -     *   'PR_ATTRIB_VALUE': string,
    -     *   'PR_COMMENT': string,
    -     *   'PR_DECLARATION': string,
    -     *   'PR_KEYWORD': string,
    -     *   'PR_LITERAL': string,
    -     *   'PR_NOCODE': string,
    -     *   'PR_PLAIN': string,
    -     *   'PR_PUNCTUATION': string,
    -     *   'PR_SOURCE': string,
    -     *   'PR_STRING': string,
    -     *   'PR_TAG': string,
    -     *   'PR_TYPE': string,
    -     *   'prettyPrintOne': function (string, string, number|boolean),
    -     *   'prettyPrint': function (?function, ?(HTMLElement|HTMLDocument))
    -     * }}
    -     * @const
    -     */
    -    var PR;
    -    
    -    /**
    -     * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
    -     * UI events.
    -     * If set to {@code false}, {@code prettyPrint()} is synchronous.
    -     */
    -    window['PR_SHOULD_USE_CONTINUATION'] = true;
    -    
    -    /**
    -     * Pretty print a chunk of code.
    -     * @param {string} sourceCodeHtml The HTML to pretty print.
    -     * @param {string} opt_langExtension The language name to use.
    -     *     Typically, a filename extension like 'cpp' or 'java'.
    -     * @param {number|boolean} opt_numberLines True to number lines,
    -     *     or the 1-indexed number of the first line in sourceCodeHtml.
    -     * @return {string} code as html, but prettier
    -     */
    -    var prettyPrintOne;
    -    /**
    -     * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
    -     * {@code class=prettyprint} and prettify them.
    -     *
    -     * @param {Function} opt_whenDone called when prettifying is done.
    -     * @param {HTMLElement|HTMLDocument} opt_root an element or document
    -     *   containing all the elements to pretty print.
    -     *   Defaults to {@code document.body}.
    -     */
    -    var prettyPrint;
    -    
    -    
    -    (function () {
    -      var win = window;
    -      // Keyword lists for various languages.
    -      // We use things that coerce to strings to make them compact when minified
    -      // and to defeat aggressive optimizers that fold large string constants.
    -      var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"];
    -      var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," +
    -          "double,enum,extern,float,goto,inline,int,long,register,short,signed," +
    -          "sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];
    -      var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," +
    -          "new,operator,private,protected,public,this,throw,true,try,typeof"];
    -      var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignof,align_union,asm,axiom,bool," +
    -          "concept,concept_map,const_cast,constexpr,decltype,delegate," +
    -          "dynamic_cast,explicit,export,friend,generic,late_check," +
    -          "mutable,namespace,nullptr,property,reinterpret_cast,static_assert," +
    -          "static_cast,template,typeid,typename,using,virtual,where"];
    -      var JAVA_KEYWORDS = [COMMON_KEYWORDS,
    -          "abstract,assert,boolean,byte,extends,finally,final,implements,import," +
    -          "instanceof,interface,null,native,package,strictfp,super,synchronized," +
    -          "throws,transient"];
    -      var CSHARP_KEYWORDS = [COMMON_KEYWORDS,
    -          "abstract,as,async,await,base,bool,by,byte,checked,decimal,delegate,descending," +
    -          "dynamic,event,finally,fixed,foreach,from,group,implicit,in,interface," +
    -          "internal,into,is,let,lock,null,object,out,override,orderby,params," +
    -          "partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong," +
    -          "unchecked,unsafe,ushort,var,virtual,where"];
    -      var COFFEE_KEYWORDS = "all,and,by,catch,class,else,extends,false,finally," +
    -          "for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then," +
    -          "throw,true,try,unless,until,when,while,yes";
    -      var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS,
    -          "debugger,eval,export,function,get,instanceof,null,set,undefined," +
    -          "var,with,Infinity,NaN"];
    -      var PERL_KEYWORDS = "caller,delete,die,do,dump,elsif,eval,exit,foreach,for," +
    -          "goto,if,import,last,local,my,next,no,our,print,package,redo,require," +
    -          "sub,undef,unless,until,use,wantarray,while,BEGIN,END";
    -      var PYTHON_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "and,as,assert,class,def,del," +
    -          "elif,except,exec,finally,from,global,import,in,is,lambda," +
    -          "nonlocal,not,or,pass,print,raise,try,with,yield," +
    -          "False,True,None"];
    -      var RUBY_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "alias,and,begin,case,class," +
    -          "def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo," +
    -          "rescue,retry,self,super,then,true,undef,unless,until,when,yield," +
    -          "BEGIN,END"];
    -      var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "case,done,elif,esac,eval,fi," +
    -          "function,in,local,set,then,until"];
    -      var ALL_KEYWORDS = [
    -          CPP_KEYWORDS, CSHARP_KEYWORDS, JAVA_KEYWORDS, JSCRIPT_KEYWORDS,
    -          PERL_KEYWORDS, PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS];
    -      var C_TYPES = /^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)\b/;
    -    
    -      // token style names.  correspond to css classes
    -      /**
    -       * token style for a string literal
    -       * @const
    -       */
    -      var PR_STRING = 'str';
    -      /**
    -       * token style for a keyword
    -       * @const
    -       */
    -      var PR_KEYWORD = 'kwd';
    -      /**
    -       * token style for a comment
    -       * @const
    -       */
    -      var PR_COMMENT = 'com';
    -      /**
    -       * token style for a type
    -       * @const
    -       */
    -      var PR_TYPE = 'typ';
    -      /**
    -       * token style for a literal value.  e.g. 1, null, true.
    -       * @const
    -       */
    -      var PR_LITERAL = 'lit';
    -      /**
    -       * token style for a punctuation string.
    -       * @const
    -       */
    -      var PR_PUNCTUATION = 'pun';
    -      /**
    -       * token style for plain text.
    -       * @const
    -       */
    -      var PR_PLAIN = 'pln';
    -    
    -      /**
    -       * token style for an sgml tag.
    -       * @const
    -       */
    -      var PR_TAG = 'tag';
    -      /**
    -       * token style for a markup declaration such as a DOCTYPE.
    -       * @const
    -       */
    -      var PR_DECLARATION = 'dec';
    -      /**
    -       * token style for embedded source.
    -       * @const
    -       */
    -      var PR_SOURCE = 'src';
    -      /**
    -       * token style for an sgml attribute name.
    -       * @const
    -       */
    -      var PR_ATTRIB_NAME = 'atn';
    -      /**
    -       * token style for an sgml attribute value.
    -       * @const
    -       */
    -      var PR_ATTRIB_VALUE = 'atv';
    -    
    -      /**
    -       * A class that indicates a section of markup that is not code, e.g. to allow
    -       * embedding of line numbers within code listings.
    -       * @const
    -       */
    -      var PR_NOCODE = 'nocode';
    -    
    -      
    -      
    -      /**
    -       * A set of tokens that can precede a regular expression literal in
    -       * javascript
    -       * http://web.archive.org/web/20070717142515/http://www.mozilla.org/js/language/js20/rationale/syntax.html
    -       * has the full list, but I've removed ones that might be problematic when
    -       * seen in languages that don't support regular expression literals.
    -       *
    -       * <p>Specifically, I've removed any keywords that can't precede a regexp
    -       * literal in a syntactically legal javascript program, and I've removed the
    -       * "in" keyword since it's not a keyword in many languages, and might be used
    -       * as a count of inches.
    -       *
    -       * <p>The link above does not accurately describe EcmaScript rules since
    -       * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
    -       * very well in practice.
    -       *
    -       * @private
    -       * @const
    -       */
    -      var REGEXP_PRECEDER_PATTERN = '(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*';
    -      
    -      // CAVEAT: this does not properly handle the case where a regular
    -      // expression immediately follows another since a regular expression may
    -      // have flags for case-sensitivity and the like.  Having regexp tokens
    -      // adjacent is not valid in any language I'm aware of, so I'm punting.
    -      // TODO: maybe style special characters inside a regexp as punctuation.
    -    
    -      /**
    -       * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
    -       * matches the union of the sets of strings matched by the input RegExp.
    -       * Since it matches globally, if the input strings have a start-of-input
    -       * anchor (/^.../), it is ignored for the purposes of unioning.
    -       * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
    -       * @return {RegExp} a global regex.
    -       */
    -      function combinePrefixPatterns(regexs) {
    -        var capturedGroupIndex = 0;
    -      
    -        var needToFoldCase = false;
    -        var ignoreCase = false;
    -        for (var i = 0, n = regexs.length; i < n; ++i) {
    -          var regex = regexs[i];
    -          if (regex.ignoreCase) {
    -            ignoreCase = true;
    -          } else if (/[a-z]/i.test(regex.source.replace(
    -                         /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
    -            needToFoldCase = true;
    -            ignoreCase = false;
    -            break;
    -          }
    -        }
    -      
    -        var escapeCharToCodeUnit = {
    -          'b': 8,
    -          't': 9,
    -          'n': 0xa,
    -          'v': 0xb,
    -          'f': 0xc,
    -          'r': 0xd
    -        };
    -      
    -        function decodeEscape(charsetPart) {
    -          var cc0 = charsetPart.charCodeAt(0);
    -          if (cc0 !== 92 /* \\ */) {
    -            return cc0;
    -          }
    -          var c1 = charsetPart.charAt(1);
    -          cc0 = escapeCharToCodeUnit[c1];
    -          if (cc0) {
    -            return cc0;
    -          } else if ('0' <= c1 && c1 <= '7') {
    -            return parseInt(charsetPart.substring(1), 8);
    -          } else if (c1 === 'u' || c1 === 'x') {
    -            return parseInt(charsetPart.substring(2), 16);
    -          } else {
    -            return charsetPart.charCodeAt(1);
    -          }
    -        }
    -      
    -        function encodeEscape(charCode) {
    -          if (charCode < 0x20) {
    -            return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
    -          }
    -          var ch = String.fromCharCode(charCode);
    -          return (ch === '\\' || ch === '-' || ch === ']' || ch === '^')
    -              ? "\\" + ch : ch;
    -        }
    -      
    -        function caseFoldCharset(charSet) {
    -          var charsetParts = charSet.substring(1, charSet.length - 1).match(
    -              new RegExp(
    -                  '\\\\u[0-9A-Fa-f]{4}'
    -                  + '|\\\\x[0-9A-Fa-f]{2}'
    -                  + '|\\\\[0-3][0-7]{0,2}'
    -                  + '|\\\\[0-7]{1,2}'
    -                  + '|\\\\[\\s\\S]'
    -                  + '|-'
    -                  + '|[^-\\\\]',
    -                  'g'));
    -          var ranges = [];
    -          var inverse = charsetParts[0] === '^';
    -      
    -          var out = ['['];
    -          if (inverse) { out.push('^'); }
    -      
    -          for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
    -            var p = charsetParts[i];
    -            if (/\\[bdsw]/i.test(p)) {  // Don't muck with named groups.
    -              out.push(p);
    -            } else {
    -              var start = decodeEscape(p);
    -              var end;
    -              if (i + 2 < n && '-' === charsetParts[i + 1]) {
    -                end = decodeEscape(charsetParts[i + 2]);
    -                i += 2;
    -              } else {
    -                end = start;
    -              }
    -              ranges.push([start, end]);
    -              // If the range might intersect letters, then expand it.
    -              // This case handling is too simplistic.
    -              // It does not deal with non-latin case folding.
    -              // It works for latin source code identifiers though.
    -              if (!(end < 65 || start > 122)) {
    -                if (!(end < 65 || start > 90)) {
    -                  ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
    -                }
    -                if (!(end < 97 || start > 122)) {
    -                  ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
    -                }
    -              }
    -            }
    -          }
    -      
    -          // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
    -          // -> [[1, 12], [14, 14], [16, 17]]
    -          ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1]  - a[1]); });
    -          var consolidatedRanges = [];
    -          var lastRange = [];
    -          for (var i = 0; i < ranges.length; ++i) {
    -            var range = ranges[i];
    -            if (range[0] <= lastRange[1] + 1) {
    -              lastRange[1] = Math.max(lastRange[1], range[1]);
    -            } else {
    -              consolidatedRanges.push(lastRange = range);
    -            }
    -          }
    -      
    -          for (var i = 0; i < consolidatedRanges.length; ++i) {
    -            var range = consolidatedRanges[i];
    -            out.push(encodeEscape(range[0]));
    -            if (range[1] > range[0]) {
    -              if (range[1] + 1 > range[0]) { out.push('-'); }
    -              out.push(encodeEscape(range[1]));
    -            }
    -          }
    -          out.push(']');
    -          return out.join('');
    -        }
    -      
    -        function allowAnywhereFoldCaseAndRenumberGroups(regex) {
    -          // Split into character sets, escape sequences, punctuation strings
    -          // like ('(', '(?:', ')', '^'), and runs of characters that do not
    -          // include any of the above.
    -          var parts = regex.source.match(
    -              new RegExp(
    -                  '(?:'
    -                  + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]'  // a character set
    -                  + '|\\\\u[A-Fa-f0-9]{4}'  // a unicode escape
    -                  + '|\\\\x[A-Fa-f0-9]{2}'  // a hex escape
    -                  + '|\\\\[0-9]+'  // a back-reference or octal escape
    -                  + '|\\\\[^ux0-9]'  // other escape sequence
    -                  + '|\\(\\?[:!=]'  // start of a non-capturing group
    -                  + '|[\\(\\)\\^]'  // start/end of a group, or line start
    -                  + '|[^\\x5B\\x5C\\(\\)\\^]+'  // run of other characters
    -                  + ')',
    -                  'g'));
    -          var n = parts.length;
    -      
    -          // Maps captured group numbers to the number they will occupy in
    -          // the output or to -1 if that has not been determined, or to
    -          // undefined if they need not be capturing in the output.
    -          var capturedGroups = [];
    -      
    -          // Walk over and identify back references to build the capturedGroups
    -          // mapping.
    -          for (var i = 0, groupIndex = 0; i < n; ++i) {
    -            var p = parts[i];
    -            if (p === '(') {
    -              // groups are 1-indexed, so max group index is count of '('
    -              ++groupIndex;
    -            } else if ('\\' === p.charAt(0)) {
    -              var decimalValue = +p.substring(1);
    -              if (decimalValue) {
    -                if (decimalValue <= groupIndex) {
    -                  capturedGroups[decimalValue] = -1;
    -                } else {
    -                  // Replace with an unambiguous escape sequence so that
    -                  // an octal escape sequence does not turn into a backreference
    -                  // to a capturing group from an earlier regex.
    -                  parts[i] = encodeEscape(decimalValue);
    -                }
    -              }
    -            }
    -          }
    -      
    -          // Renumber groups and reduce capturing groups to non-capturing groups
    -          // where possible.
    -          for (var i = 1; i < capturedGroups.length; ++i) {
    -            if (-1 === capturedGroups[i]) {
    -              capturedGroups[i] = ++capturedGroupIndex;
    -            }
    -          }
    -          for (var i = 0, groupIndex = 0; i < n; ++i) {
    -            var p = parts[i];
    -            if (p === '(') {
    -              ++groupIndex;
    -              if (!capturedGroups[groupIndex]) {
    -                parts[i] = '(?:';
    -              }
    -            } else if ('\\' === p.charAt(0)) {
    -              var decimalValue = +p.substring(1);
    -              if (decimalValue && decimalValue <= groupIndex) {
    -                parts[i] = '\\' + capturedGroups[decimalValue];
    -              }
    -            }
    -          }
    -      
    -          // Remove any prefix anchors so that the output will match anywhere.
    -          // ^^ really does mean an anchored match though.
    -          for (var i = 0; i < n; ++i) {
    -            if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
    -          }
    -      
    -          // Expand letters to groups to handle mixing of case-sensitive and
    -          // case-insensitive patterns if necessary.
    -          if (regex.ignoreCase && needToFoldCase) {
    -            for (var i = 0; i < n; ++i) {
    -              var p = parts[i];
    -              var ch0 = p.charAt(0);
    -              if (p.length >= 2 && ch0 === '[') {
    -                parts[i] = caseFoldCharset(p);
    -              } else if (ch0 !== '\\') {
    -                // TODO: handle letters in numeric escapes.
    -                parts[i] = p.replace(
    -                    /[a-zA-Z]/g,
    -                    function (ch) {
    -                      var cc = ch.charCodeAt(0);
    -                      return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
    -                    });
    -              }
    -            }
    -          }
    -      
    -          return parts.join('');
    -        }
    -      
    -        var rewritten = [];
    -        for (var i = 0, n = regexs.length; i < n; ++i) {
    -          var regex = regexs[i];
    -          if (regex.global || regex.multiline) { throw new Error('' + regex); }
    -          rewritten.push(
    -              '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
    -        }
    -      
    -        return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
    -      }
    -    
    -      /**
    -       * Split markup into a string of source code and an array mapping ranges in
    -       * that string to the text nodes in which they appear.
    -       *
    -       * <p>
    -       * The HTML DOM structure:</p>
    -       * <pre>
    -       * (Element   "p"
    -       *   (Element "b"
    -       *     (Text  "print "))       ; #1
    -       *   (Text    "'Hello '")      ; #2
    -       *   (Element "br")            ; #3
    -       *   (Text    "  + 'World';")) ; #4
    -       * </pre>
    -       * <p>
    -       * corresponds to the HTML
    -       * {@code <p><b>print </b>'Hello '<br>  + 'World';</p>}.</p>
    -       *
    -       * <p>
    -       * It will produce the output:</p>
    -       * <pre>
    -       * {
    -       *   sourceCode: "print 'Hello '\n  + 'World';",
    -       *   //                     1          2
    -       *   //           012345678901234 5678901234567
    -       *   spans: [0, #1, 6, #2, 14, #3, 15, #4]
    -       * }
    -       * </pre>
    -       * <p>
    -       * where #1 is a reference to the {@code "print "} text node above, and so
    -       * on for the other text nodes.
    -       * </p>
    -       *
    -       * <p>
    -       * The {@code} spans array is an array of pairs.  Even elements are the start
    -       * indices of substrings, and odd elements are the text nodes (or BR elements)
    -       * that contain the text for those substrings.
    -       * Substrings continue until the next index or the end of the source.
    -       * </p>
    -       *
    -       * @param {Node} node an HTML DOM subtree containing source-code.
    -       * @param {boolean|number} isPreformatted truthy if white-space in
    -       *    text nodes should be considered significant.
    -       * @return {SourceSpansT} source code and the nodes in which they occur.
    -       */
    -      function extractSourceSpans(node, isPreformatted) {
    -        var nocode = /(?:^|\s)nocode(?:\s|$)/;
    -      
    -        var chunks = [];
    -        var length = 0;
    -        var spans = [];
    -        var k = 0;
    -      
    -        function walk(node) {
    -          var type = node.nodeType;
    -          if (type == 1) {  // Element
    -            if (nocode.test(node.className)) { return; }
    -            for (var child = node.firstChild; child; child = child.nextSibling) {
    -              walk(child);
    -            }
    -            var nodeName = node.nodeName.toLowerCase();
    -            if ('br' === nodeName || 'li' === nodeName) {
    -              chunks[k] = '\n';
    -              spans[k << 1] = length++;
    -              spans[(k++ << 1) | 1] = node;
    -            }
    -          } else if (type == 3 || type == 4) {  // Text
    -            var text = node.nodeValue;
    -            if (text.length) {
    -              if (!isPreformatted) {
    -                text = text.replace(/[ \t\r\n]+/g, ' ');
    -              } else {
    -                text = text.replace(/\r\n?/g, '\n');  // Normalize newlines.
    -              }
    -              // TODO: handle tabs here?
    -              chunks[k] = text;
    -              spans[k << 1] = length;
    -              length += text.length;
    -              spans[(k++ << 1) | 1] = node;
    -            }
    -          }
    -        }
    -      
    -        walk(node);
    -      
    -        return {
    -          sourceCode: chunks.join('').replace(/\n$/, ''),
    -          spans: spans
    -        };
    -      }
    -    
    -      /**
    -       * Apply the given language handler to sourceCode and add the resulting
    -       * decorations to out.
    -       * @param {!Element} sourceNode
    -       * @param {number} basePos the index of sourceCode within the chunk of source
    -       *    whose decorations are already present on out.
    -       * @param {string} sourceCode
    -       * @param {function(JobT)} langHandler
    -       * @param {DecorationsT} out
    -       */
    -      function appendDecorations(
    -          sourceNode, basePos, sourceCode, langHandler, out) {
    -        if (!sourceCode) { return; }
    -        /** @type {JobT} */
    -        var job = {
    -          sourceNode: sourceNode,
    -          pre: 1,
    -          langExtension: null,
    -          numberLines: null,
    -          sourceCode: sourceCode,
    -          spans: null,
    -          basePos: basePos,
    -          decorations: null
    -        };
    -        langHandler(job);
    -        out.push.apply(out, job.decorations);
    -      }
    -    
    -      var notWs = /\S/;
    -    
    -      /**
    -       * Given an element, if it contains only one child element and any text nodes
    -       * it contains contain only space characters, return the sole child element.
    -       * Otherwise returns undefined.
    -       * <p>
    -       * This is meant to return the CODE element in {@code <pre><code ...>} when
    -       * there is a single child element that contains all the non-space textual
    -       * content, but not to return anything where there are multiple child elements
    -       * as in {@code <pre><code>...</code><code>...</code></pre>} or when there
    -       * is textual content.
    -       */
    -      function childContentWrapper(element) {
    -        var wrapper = undefined;
    -        for (var c = element.firstChild; c; c = c.nextSibling) {
    -          var type = c.nodeType;
    -          wrapper = (type === 1)  // Element Node
    -              ? (wrapper ? element : c)
    -              : (type === 3)  // Text Node
    -              ? (notWs.test(c.nodeValue) ? element : wrapper)
    -              : wrapper;
    -        }
    -        return wrapper === element ? undefined : wrapper;
    -      }
    -    
    -      /** Given triples of [style, pattern, context] returns a lexing function,
    -        * The lexing function interprets the patterns to find token boundaries and
    -        * returns a decoration list of the form
    -        * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
    -        * where index_n is an index into the sourceCode, and style_n is a style
    -        * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to
    -        * all characters in sourceCode[index_n-1:index_n].
    -        *
    -        * The stylePatterns is a list whose elements have the form
    -        * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
    -        *
    -        * Style is a style constant like PR_PLAIN, or can be a string of the
    -        * form 'lang-FOO', where FOO is a language extension describing the
    -        * language of the portion of the token in $1 after pattern executes.
    -        * E.g., if style is 'lang-lisp', and group 1 contains the text
    -        * '(hello (world))', then that portion of the token will be passed to the
    -        * registered lisp handler for formatting.
    -        * The text before and after group 1 will be restyled using this decorator
    -        * so decorators should take care that this doesn't result in infinite
    -        * recursion.  For example, the HTML lexer rule for SCRIPT elements looks
    -        * something like ['lang-js', /<[s]cript>(.+?)<\/script>/].  This may match
    -        * '<script>foo()<\/script>', which would cause the current decorator to
    -        * be called with '<script>' which would not match the same rule since
    -        * group 1 must not be empty, so it would be instead styled as PR_TAG by
    -        * the generic tag rule.  The handler registered for the 'js' extension would
    -        * then be called with 'foo()', and finally, the current decorator would
    -        * be called with '<\/script>' which would not match the original rule and
    -        * so the generic tag rule would identify it as a tag.
    -        *
    -        * Pattern must only match prefixes, and if it matches a prefix, then that
    -        * match is considered a token with the same style.
    -        *
    -        * Context is applied to the last non-whitespace, non-comment token
    -        * recognized.
    -        *
    -        * Shortcut is an optional string of characters, any of which, if the first
    -        * character, gurantee that this pattern and only this pattern matches.
    -        *
    -        * @param {Array} shortcutStylePatterns patterns that always start with
    -        *   a known character.  Must have a shortcut string.
    -        * @param {Array} fallthroughStylePatterns patterns that will be tried in
    -        *   order if the shortcut ones fail.  May have shortcuts.
    -        *
    -        * @return {function (JobT)} a function that takes an undecorated job and
    -        *   attaches a list of decorations.
    -        */
    -      function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
    -        var shortcuts = {};
    -        var tokenizer;
    -        (function () {
    -          var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
    -          var allRegexs = [];
    -          var regexKeys = {};
    -          for (var i = 0, n = allPatterns.length; i < n; ++i) {
    -            var patternParts = allPatterns[i];
    -            var shortcutChars = patternParts[3];
    -            if (shortcutChars) {
    -              for (var c = shortcutChars.length; --c >= 0;) {
    -                shortcuts[shortcutChars.charAt(c)] = patternParts;
    -              }
    -            }
    -            var regex = patternParts[1];
    -            var k = '' + regex;
    -            if (!regexKeys.hasOwnProperty(k)) {
    -              allRegexs.push(regex);
    -              regexKeys[k] = null;
    -            }
    -          }
    -          allRegexs.push(/[\0-\uffff]/);
    -          tokenizer = combinePrefixPatterns(allRegexs);
    -        })();
    -    
    -        var nPatterns = fallthroughStylePatterns.length;
    -    
    -        /**
    -         * Lexes job.sourceCode and attaches an output array job.decorations of
    -         * style classes preceded by the position at which they start in
    -         * job.sourceCode in order.
    -         *
    -         * @type{function (JobT)}
    -         */
    -        var decorate = function (job) {
    -          var sourceCode = job.sourceCode, basePos = job.basePos;
    -          var sourceNode = job.sourceNode;
    -          /** Even entries are positions in source in ascending order.  Odd enties
    -            * are style markers (e.g., PR_COMMENT) that run from that position until
    -            * the end.
    -            * @type {DecorationsT}
    -            */
    -          var decorations = [basePos, PR_PLAIN];
    -          var pos = 0;  // index into sourceCode
    -          var tokens = sourceCode.match(tokenizer) || [];
    -          var styleCache = {};
    -    
    -          for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
    -            var token = tokens[ti];
    -            var style = styleCache[token];
    -            var match = void 0;
    -    
    -            var isEmbedded;
    -            if (typeof style === 'string') {
    -              isEmbedded = false;
    -            } else {
    -              var patternParts = shortcuts[token.charAt(0)];
    -              if (patternParts) {
    -                match = token.match(patternParts[1]);
    -                style = patternParts[0];
    -              } else {
    -                for (var i = 0; i < nPatterns; ++i) {
    -                  patternParts = fallthroughStylePatterns[i];
    -                  match = token.match(patternParts[1]);
    -                  if (match) {
    -                    style = patternParts[0];
    -                    break;
    -                  }
    -                }
    -    
    -                if (!match) {  // make sure that we make progress
    -                  style = PR_PLAIN;
    -                }
    -              }
    -    
    -              isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
    -              if (isEmbedded && !(match && typeof match[1] === 'string')) {
    -                isEmbedded = false;
    -                style = PR_SOURCE;
    -              }
    -    
    -              if (!isEmbedded) { styleCache[token] = style; }
    -            }
    -    
    -            var tokenStart = pos;
    -            pos += token.length;
    -    
    -            if (!isEmbedded) {
    -              decorations.push(basePos + tokenStart, style);
    -            } else {  // Treat group 1 as an embedded block of source code.
    -              var embeddedSource = match[1];
    -              var embeddedSourceStart = token.indexOf(embeddedSource);
    -              var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
    -              if (match[2]) {
    -                // If embeddedSource can be blank, then it would match at the
    -                // beginning which would cause us to infinitely recurse on the
    -                // entire token, so we catch the right context in match[2].
    -                embeddedSourceEnd = token.length - match[2].length;
    -                embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
    -              }
    -              var lang = style.substring(5);
    -              // Decorate the left of the embedded source
    -              appendDecorations(
    -                  sourceNode,
    -                  basePos + tokenStart,
    -                  token.substring(0, embeddedSourceStart),
    -                  decorate, decorations);
    -              // Decorate the embedded source
    -              appendDecorations(
    -                  sourceNode,
    -                  basePos + tokenStart + embeddedSourceStart,
    -                  embeddedSource,
    -                  langHandlerForExtension(lang, embeddedSource),
    -                  decorations);
    -              // Decorate the right of the embedded section
    -              appendDecorations(
    -                  sourceNode,
    -                  basePos + tokenStart + embeddedSourceEnd,
    -                  token.substring(embeddedSourceEnd),
    -                  decorate, decorations);
    -            }
    -          }
    -          job.decorations = decorations;
    -        };
    -        return decorate;
    -      }
    -    
    -      /** returns a function that produces a list of decorations from source text.
    -        *
    -        * This code treats ", ', and ` as string delimiters, and \ as a string
    -        * escape.  It does not recognize perl's qq() style strings.
    -        * It has no special handling for double delimiter escapes as in basic, or
    -        * the tripled delimiters used in python, but should work on those regardless
    -        * although in those cases a single string literal may be broken up into
    -        * multiple adjacent string literals.
    -        *
    -        * It recognizes C, C++, and shell style comments.
    -        *
    -        * @param {Object} options a set of optional parameters.
    -        * @return {function (JobT)} a function that examines the source code
    -        *     in the input job and builds a decoration list which it attaches to
    -        *     the job.
    -        */
    -      function sourceDecorator(options) {
    -        var shortcutStylePatterns = [], fallthroughStylePatterns = [];
    -        if (options['tripleQuotedStrings']) {
    -          // '''multi-line-string''', 'single-line-string', and double-quoted
    -          shortcutStylePatterns.push(
    -              [PR_STRING,  /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
    -               null, '\'"']);
    -        } else if (options['multiLineStrings']) {
    -          // 'multi-line-string', "multi-line-string"
    -          shortcutStylePatterns.push(
    -              [PR_STRING,  /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
    -               null, '\'"`']);
    -        } else {
    -          // 'single-line-string', "single-line-string"
    -          shortcutStylePatterns.push(
    -              [PR_STRING,
    -               /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
    -               null, '"\'']);
    -        }
    -        if (options['verbatimStrings']) {
    -          // verbatim-string-literal production from the C# grammar.  See issue 93.
    -          fallthroughStylePatterns.push(
    -              [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
    -        }
    -        var hc = options['hashComments'];
    -        if (hc) {
    -          if (options['cStyleComments']) {
    -            if (hc > 1) {  // multiline hash comments
    -              shortcutStylePatterns.push(
    -                  [PR_COMMENT, /^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/, null, '#']);
    -            } else {
    -              // Stop C preprocessor declarations at an unclosed open comment
    -              shortcutStylePatterns.push(
    -                  [PR_COMMENT, /^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\r\n]*)/,
    -                   null, '#']);
    -            }
    -            // #include <stdio.h>
    -            fallthroughStylePatterns.push(
    -                [PR_STRING,
    -                 /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,
    -                 null]);
    -          } else {
    -            shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
    -          }
    -        }
    -        if (options['cStyleComments']) {
    -          fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
    -          fallthroughStylePatterns.push(
    -              [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
    -        }
    -        var regexLiterals = options['regexLiterals'];
    -        if (regexLiterals) {
    -          /**
    -           * @const
    -           */
    -          var regexExcls = regexLiterals > 1
    -            ? ''  // Multiline regex literals
    -            : '\n\r';
    -          /**
    -           * @const
    -           */
    -          var regexAny = regexExcls ? '.' : '[\\S\\s]';
    -          /**
    -           * @const
    -           */
    -          var REGEX_LITERAL = (
    -              // A regular expression literal starts with a slash that is
    -              // not followed by * or / so that it is not confused with
    -              // comments.
    -              '/(?=[^/*' + regexExcls + '])'
    -              // and then contains any number of raw characters,
    -              + '(?:[^/\\x5B\\x5C' + regexExcls + ']'
    -              // escape sequences (\x5C),
    -              +    '|\\x5C' + regexAny
    -              // or non-nesting character sets (\x5B\x5D);
    -              +    '|\\x5B(?:[^\\x5C\\x5D' + regexExcls + ']'
    -              +             '|\\x5C' + regexAny + ')*(?:\\x5D|$))+'
    -              // finally closed by a /.
    -              + '/');
    -          fallthroughStylePatterns.push(
    -              ['lang-regex',
    -               RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
    -               ]);
    -        }
    -    
    -        var types = options['types'];
    -        if (types) {
    -          fallthroughStylePatterns.push([PR_TYPE, types]);
    -        }
    -    
    -        var keywords = ("" + options['keywords']).replace(/^ | $/g, '');
    -        if (keywords.length) {
    -          fallthroughStylePatterns.push(
    -              [PR_KEYWORD,
    -               new RegExp('^(?:' + keywords.replace(/[\s,]+/g, '|') + ')\\b'),
    -               null]);
    -        }
    -    
    -        shortcutStylePatterns.push([PR_PLAIN,       /^\s+/, null, ' \r\n\t\xA0']);
    -    
    -        var punctuation =
    -          // The Bash man page says
    -    
    -          // A word is a sequence of characters considered as a single
    -          // unit by GRUB. Words are separated by metacharacters,
    -          // which are the following plus space, tab, and newline: { }
    -          // | & $ ; < >
    -          // ...
    -    
    -          // A word beginning with # causes that word and all remaining
    -          // characters on that line to be ignored.
    -    
    -          // which means that only a '#' after /(?:^|[{}|&$;<>\s])/ starts a
    -          // comment but empirically
    -          // $ echo {#}
    -          // {#}
    -          // $ echo \$#
    -          // $#
    -          // $ echo }#
    -          // }#
    -    
    -          // so /(?:^|[|&;<>\s])/ is more appropriate.
    -    
    -          // http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC3
    -          // suggests that this definition is compatible with a
    -          // default mode that tries to use a single token definition
    -          // to recognize both bash/python style comments and C
    -          // preprocessor directives.
    -    
    -          // This definition of punctuation does not include # in the list of
    -          // follow-on exclusions, so # will not be broken before if preceeded
    -          // by a punctuation character.  We could try to exclude # after
    -          // [|&;<>] but that doesn't seem to cause many major problems.
    -          // If that does turn out to be a problem, we should change the below
    -          // when hc is truthy to include # in the run of punctuation characters
    -          // only when not followint [|&;<>].
    -          '^.[^\\s\\w.$@\'"`/\\\\]*';
    -        if (options['regexLiterals']) {
    -          punctuation += '(?!\s*\/)';
    -        }
    -    
    -        fallthroughStylePatterns.push(
    -            // TODO(mikesamuel): recognize non-latin letters and numerals in idents
    -            [PR_LITERAL,     /^@[a-z_$][a-z_$@0-9]*/i, null],
    -            [PR_TYPE,        /^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/, null],
    -            [PR_PLAIN,       /^[a-z_$][a-z_$@0-9]*/i, null],
    -            [PR_LITERAL,
    -             new RegExp(
    -                 '^(?:'
    -                 // A hex number
    -                 + '0x[a-f0-9]+'
    -                 // or an octal or decimal number,
    -                 + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
    -                 // possibly in scientific notation
    -                 + '(?:e[+\\-]?\\d+)?'
    -                 + ')'
    -                 // with an optional modifier like UL for unsigned long
    -                 + '[a-z]*', 'i'),
    -             null, '0123456789'],
    -            // Don't treat escaped quotes in bash as starting strings.
    -            // See issue 144.
    -            [PR_PLAIN,       /^\\[\s\S]?/, null],
    -            [PR_PUNCTUATION, new RegExp(punctuation), null]);
    -    
    -        return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
    -      }
    -    
    -      var decorateSource = sourceDecorator({
    -            'keywords': ALL_KEYWORDS,
    -            'hashComments': true,
    -            'cStyleComments': true,
    -            'multiLineStrings': true,
    -            'regexLiterals': true
    -          });
    -    
    -      /**
    -       * Given a DOM subtree, wraps it in a list, and puts each line into its own
    -       * list item.
    -       *
    -       * @param {Node} node modified in place.  Its content is pulled into an
    -       *     HTMLOListElement, and each line is moved into a separate list item.
    -       *     This requires cloning elements, so the input might not have unique
    -       *     IDs after numbering.
    -       * @param {number|null|boolean} startLineNum
    -       *     If truthy, coerced to an integer which is the 1-indexed line number
    -       *     of the first line of code.  The number of the first line will be
    -       *     attached to the list.
    -       * @param {boolean} isPreformatted true iff white-space in text nodes should
    -       *     be treated as significant.
    -       */
    -      function numberLines(node, startLineNum, isPreformatted) {
    -        var nocode = /(?:^|\s)nocode(?:\s|$)/;
    -        var lineBreak = /\r\n?|\n/;
    -      
    -        var document = node.ownerDocument;
    -      
    -        var li = document.createElement('li');
    -        while (node.firstChild) {
    -          li.appendChild(node.firstChild);
    -        }
    -        // An array of lines.  We split below, so this is initialized to one
    -        // un-split line.
    -        var listItems = [li];
    -      
    -        function walk(node) {
    -          var type = node.nodeType;
    -          if (type == 1 && !nocode.test(node.className)) {  // Element
    -            if ('br' === node.nodeName) {
    -              breakAfter(node);
    -              // Discard the <BR> since it is now flush against a </LI>.
    -              if (node.parentNode) {
    -                node.parentNode.removeChild(node);
    -              }
    -            } else {
    -              for (var child = node.firstChild; child; child = child.nextSibling) {
    -                walk(child);
    -              }
    -            }
    -          } else if ((type == 3 || type == 4) && isPreformatted) {  // Text
    -            var text = node.nodeValue;
    -            var match = text.match(lineBreak);
    -            if (match) {
    -              var firstLine = text.substring(0, match.index);
    -              node.nodeValue = firstLine;
    -              var tail = text.substring(match.index + match[0].length);
    -              if (tail) {
    -                var parent = node.parentNode;
    -                parent.insertBefore(
    -                  document.createTextNode(tail), node.nextSibling);
    -              }
    -              breakAfter(node);
    -              if (!firstLine) {
    -                // Don't leave blank text nodes in the DOM.
    -                node.parentNode.removeChild(node);
    -              }
    -            }
    -          }
    -        }
    -      
    -        // Split a line after the given node.
    -        function breakAfter(lineEndNode) {
    -          // If there's nothing to the right, then we can skip ending the line
    -          // here, and move root-wards since splitting just before an end-tag
    -          // would require us to create a bunch of empty copies.
    -          while (!lineEndNode.nextSibling) {
    -            lineEndNode = lineEndNode.parentNode;
    -            if (!lineEndNode) { return; }
    -          }
    -      
    -          function breakLeftOf(limit, copy) {
    -            // Clone shallowly if this node needs to be on both sides of the break.
    -            var rightSide = copy ? limit.cloneNode(false) : limit;
    -            var parent = limit.parentNode;
    -            if (parent) {
    -              // We clone the parent chain.
    -              // This helps us resurrect important styling elements that cross lines.
    -              // E.g. in <i>Foo<br>Bar</i>
    -              // should be rewritten to <li><i>Foo</i></li><li><i>Bar</i></li>.
    -              var parentClone = breakLeftOf(parent, 1);
    -              // Move the clone and everything to the right of the original
    -              // onto the cloned parent.
    -              var next = limit.nextSibling;
    -              parentClone.appendChild(rightSide);
    -              for (var sibling = next; sibling; sibling = next) {
    -                next = sibling.nextSibling;
    -                parentClone.appendChild(sibling);
    -              }
    -            }
    -            return rightSide;
    -          }
    -      
    -          var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0);
    -      
    -          // Walk the parent chain until we reach an unattached LI.
    -          for (var parent;
    -               // Check nodeType since IE invents document fragments.
    -               (parent = copiedListItem.parentNode) && parent.nodeType === 1;) {
    -            copiedListItem = parent;
    -          }
    -          // Put it on the list of lines for later processing.
    -          listItems.push(copiedListItem);
    -        }
    -      
    -        // Split lines while there are lines left to split.
    -        for (var i = 0;  // Number of lines that have been split so far.
    -             i < listItems.length;  // length updated by breakAfter calls.
    -             ++i) {
    -          walk(listItems[i]);
    -        }
    -      
    -        // Make sure numeric indices show correctly.
    -        if (startLineNum === (startLineNum|0)) {
    -          listItems[0].setAttribute('value', startLineNum);
    -        }
    -      
    -        var ol = document.createElement('ol');
    -        ol.className = 'linenums';
    -        var offset = Math.max(0, ((startLineNum - 1 /* zero index */)) | 0) || 0;
    -        for (var i = 0, n = listItems.length; i < n; ++i) {
    -          li = listItems[i];
    -          // Stick a class on the LIs so that stylesheets can
    -          // color odd/even rows, or any other row pattern that
    -          // is co-prime with 10.
    -          li.className = 'L' + ((i + offset) % 10);
    -          if (!li.firstChild) {
    -            li.appendChild(document.createTextNode('\xA0'));
    -          }
    -          ol.appendChild(li);
    -        }
    -      
    -        node.appendChild(ol);
    -      }
    -    
    -      /**
    -       * Breaks {@code job.sourceCode} around style boundaries in
    -       * {@code job.decorations} and modifies {@code job.sourceNode} in place.
    -       * @param {JobT} job
    -       * @private
    -       */
    -      function recombineTagsAndDecorations(job) {
    -        var isIE8OrEarlier = /\bMSIE\s(\d+)/.exec(navigator.userAgent);
    -        isIE8OrEarlier = isIE8OrEarlier && +isIE8OrEarlier[1] <= 8;
    -        var newlineRe = /\n/g;
    -      
    -        var source = job.sourceCode;
    -        var sourceLength = source.length;
    -        // Index into source after the last code-unit recombined.
    -        var sourceIndex = 0;
    -      
    -        var spans = job.spans;
    -        var nSpans = spans.length;
    -        // Index into spans after the last span which ends at or before sourceIndex.
    -        var spanIndex = 0;
    -      
    -        var decorations = job.decorations;
    -        var nDecorations = decorations.length;
    -        // Index into decorations after the last decoration which ends at or before
    -        // sourceIndex.
    -        var decorationIndex = 0;
    -      
    -        // Remove all zero-length decorations.
    -        decorations[nDecorations] = sourceLength;
    -        var decPos, i;
    -        for (i = decPos = 0; i < nDecorations;) {
    -          if (decorations[i] !== decorations[i + 2]) {
    -            decorations[decPos++] = decorations[i++];
    -            decorations[decPos++] = decorations[i++];
    -          } else {
    -            i += 2;
    -          }
    -        }
    -        nDecorations = decPos;
    -      
    -        // Simplify decorations.
    -        for (i = decPos = 0; i < nDecorations;) {
    -          var startPos = decorations[i];
    -          // Conflate all adjacent decorations that use the same style.
    -          var startDec = decorations[i + 1];
    -          var end = i + 2;
    -          while (end + 2 <= nDecorations && decorations[end + 1] === startDec) {
    -            end += 2;
    -          }
    -          decorations[decPos++] = startPos;
    -          decorations[decPos++] = startDec;
    -          i = end;
    -        }
    -      
    -        nDecorations = decorations.length = decPos;
    -      
    -        var sourceNode = job.sourceNode;
    -        var oldDisplay = "";
    -        if (sourceNode) {
    -          oldDisplay = sourceNode.style.display;
    -          sourceNode.style.display = 'none';
    -        }
    -        try {
    -          var decoration = null;
    -          while (spanIndex < nSpans) {
    -            var spanStart = spans[spanIndex];
    -            var spanEnd = /** @type{number} */ (spans[spanIndex + 2])
    -                || sourceLength;
    -      
    -            var decEnd = decorations[decorationIndex + 2] || sourceLength;
    -      
    -            var end = Math.min(spanEnd, decEnd);
    -      
    -            var textNode = /** @type{Node} */ (spans[spanIndex + 1]);
    -            var styledText;
    -            if (textNode.nodeType !== 1  // Don't muck with <BR>s or <LI>s
    -                // Don't introduce spans around empty text nodes.
    -                && (styledText = source.substring(sourceIndex, end))) {
    -              // This may seem bizarre, and it is.  Emitting LF on IE causes the
    -              // code to display with spaces instead of line breaks.
    -              // Emitting Windows standard issue linebreaks (CRLF) causes a blank
    -              // space to appear at the beginning of every line but the first.
    -              // Emitting an old Mac OS 9 line separator makes everything spiffy.
    -              if (isIE8OrEarlier) {
    -                styledText = styledText.replace(newlineRe, '\r');
    -              }
    -              textNode.nodeValue = styledText;
    -              var document = textNode.ownerDocument;
    -              var span = document.createElement('span');
    -              span.className = decorations[decorationIndex + 1];
    -              var parentNode = textNode.parentNode;
    -              parentNode.replaceChild(span, textNode);
    -              span.appendChild(textNode);
    -              if (sourceIndex < spanEnd) {  // Split off a text node.
    -                spans[spanIndex + 1] = textNode
    -                    // TODO: Possibly optimize by using '' if there's no flicker.
    -                    = document.createTextNode(source.substring(end, spanEnd));
    -                parentNode.insertBefore(textNode, span.nextSibling);
    -              }
    -            }
    -      
    -            sourceIndex = end;
    -      
    -            if (sourceIndex >= spanEnd) {
    -              spanIndex += 2;
    -            }
    -            if (sourceIndex >= decEnd) {
    -              decorationIndex += 2;
    -            }
    -          }
    -        } finally {
    -          if (sourceNode) {
    -            sourceNode.style.display = oldDisplay;
    -          }
    -        }
    -      }
    -    
    -      /** Maps language-specific file extensions to handlers. */
    -      var langHandlerRegistry = {};
    -      /** Register a language handler for the given file extensions.
    -        * @param {function (JobT)} handler a function from source code to a list
    -        *      of decorations.  Takes a single argument job which describes the
    -        *      state of the computation and attaches the decorations to it.
    -        * @param {Array.<string>} fileExtensions
    -        */
    -      function registerLangHandler(handler, fileExtensions) {
    -        for (var i = fileExtensions.length; --i >= 0;) {
    -          var ext = fileExtensions[i];
    -          if (!langHandlerRegistry.hasOwnProperty(ext)) {
    -            langHandlerRegistry[ext] = handler;
    -          } else if (win['console']) {
    -            console['warn']('cannot override language handler %s', ext);
    -          }
    -        }
    -      }
    -      function langHandlerForExtension(extension, source) {
    -        if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
    -          // Treat it as markup if the first non whitespace character is a < and
    -          // the last non-whitespace character is a >.
    -          extension = /^\s*</.test(source)
    -              ? 'default-markup'
    -              : 'default-code';
    -        }
    -        return langHandlerRegistry[extension];
    -      }
    -      registerLangHandler(decorateSource, ['default-code']);
    -      registerLangHandler(
    -          createSimpleLexer(
    -              [],
    -              [
    -               [PR_PLAIN,       /^[^<?]+/],
    -               [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
    -               [PR_COMMENT,     /^<\!--[\s\S]*?(?:-\->|$)/],
    -               // Unescaped content in an unknown language
    -               ['lang-',        /^<\?([\s\S]+?)(?:\?>|$)/],
    -               ['lang-',        /^<%([\s\S]+?)(?:%>|$)/],
    -               [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
    -               ['lang-',        /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
    -               // Unescaped content in javascript.  (Or possibly vbscript).
    -               ['lang-js',      /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
    -               // Contains unescaped stylesheet content
    -               ['lang-css',     /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
    -               ['lang-in.tag',  /^(<\/?[a-z][^<>]*>)/i]
    -              ]),
    -          ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
    -      registerLangHandler(
    -          createSimpleLexer(
    -              [
    -               [PR_PLAIN,        /^[\s]+/, null, ' \t\r\n'],
    -               [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
    -               ],
    -              [
    -               [PR_TAG,          /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
    -               [PR_ATTRIB_NAME,  /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
    -               ['lang-uq.val',   /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
    -               [PR_PUNCTUATION,  /^[=<>\/]+/],
    -               ['lang-js',       /^on\w+\s*=\s*\"([^\"]+)\"/i],
    -               ['lang-js',       /^on\w+\s*=\s*\'([^\']+)\'/i],
    -               ['lang-js',       /^on\w+\s*=\s*([^\"\'>\s]+)/i],
    -               ['lang-css',      /^style\s*=\s*\"([^\"]+)\"/i],
    -               ['lang-css',      /^style\s*=\s*\'([^\']+)\'/i],
    -               ['lang-css',      /^style\s*=\s*([^\"\'>\s]+)/i]
    -               ]),
    -          ['in.tag']);
    -      registerLangHandler(
    -          createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
    -      registerLangHandler(sourceDecorator({
    -              'keywords': CPP_KEYWORDS,
    -              'hashComments': true,
    -              'cStyleComments': true,
    -              'types': C_TYPES
    -            }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
    -      registerLangHandler(sourceDecorator({
    -              'keywords': 'null,true,false'
    -            }), ['json']);
    -      registerLangHandler(sourceDecorator({
    -              'keywords': CSHARP_KEYWORDS,
    -              'hashComments': true,
    -              'cStyleComments': true,
    -              'verbatimStrings': true,
    -              'types': C_TYPES
    -            }), ['cs']);
    -      registerLangHandler(sourceDecorator({
    -              'keywords': JAVA_KEYWORDS,
    -              'cStyleComments': true
    -            }), ['java']);
    -      registerLangHandler(sourceDecorator({
    -              'keywords': SH_KEYWORDS,
    -              'hashComments': true,
    -              'multiLineStrings': true
    -            }), ['bash', 'bsh', 'csh', 'sh']);
    -      registerLangHandler(sourceDecorator({
    -              'keywords': PYTHON_KEYWORDS,
    -              'hashComments': true,
    -              'multiLineStrings': true,
    -              'tripleQuotedStrings': true
    -            }), ['cv', 'py', 'python']);
    -      registerLangHandler(sourceDecorator({
    -              'keywords': PERL_KEYWORDS,
    -              'hashComments': true,
    -              'multiLineStrings': true,
    -              'regexLiterals': 2  // multiline regex literals
    -            }), ['perl', 'pl', 'pm']);
    -      registerLangHandler(sourceDecorator({
    -              'keywords': RUBY_KEYWORDS,
    -              'hashComments': true,
    -              'multiLineStrings': true,
    -              'regexLiterals': true
    -            }), ['rb', 'ruby']);
    -      registerLangHandler(sourceDecorator({
    -              'keywords': JSCRIPT_KEYWORDS,
    -              'cStyleComments': true,
    -              'regexLiterals': true
    -            }), ['javascript', 'js']);
    -      registerLangHandler(sourceDecorator({
    -              'keywords': COFFEE_KEYWORDS,
    -              'hashComments': 3,  // ### style block comments
    -              'cStyleComments': true,
    -              'multilineStrings': true,
    -              'tripleQuotedStrings': true,
    -              'regexLiterals': true
    -            }), ['coffee']);
    -      registerLangHandler(
    -          createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
    -    
    -      /** @param {JobT} job */
    -      function applyDecorator(job) {
    -        var opt_langExtension = job.langExtension;
    -    
    -        try {
    -          // Extract tags, and convert the source code to plain text.
    -          var sourceAndSpans = extractSourceSpans(job.sourceNode, job.pre);
    -          /** Plain text. @type {string} */
    -          var source = sourceAndSpans.sourceCode;
    -          job.sourceCode = source;
    -          job.spans = sourceAndSpans.spans;
    -          job.basePos = 0;
    -    
    -          // Apply the appropriate language handler
    -          langHandlerForExtension(opt_langExtension, source)(job);
    -    
    -          // Integrate the decorations and tags back into the source code,
    -          // modifying the sourceNode in place.
    -          recombineTagsAndDecorations(job);
    -        } catch (e) {
    -          if (win['console']) {
    -            console['log'](e && e['stack'] || e);
    -          }
    -        }
    -      }
    -    
    -      /**
    -       * Pretty print a chunk of code.
    -       * @param sourceCodeHtml {string} The HTML to pretty print.
    -       * @param opt_langExtension {string} The language name to use.
    -       *     Typically, a filename extension like 'cpp' or 'java'.
    -       * @param opt_numberLines {number|boolean} True to number lines,
    -       *     or the 1-indexed number of the first line in sourceCodeHtml.
    -       */
    -      function $prettyPrintOne(sourceCodeHtml, opt_langExtension, opt_numberLines) {
    -        /** @type{number|boolean} */
    -        var nl = opt_numberLines || false;
    -        /** @type{string|null} */
    -        var langExtension = opt_langExtension || null;
    -        /** @type{!Element} */
    -        var container = document.createElement('div');
    -        // This could cause images to load and onload listeners to fire.
    -        // E.g. <img onerror="alert(1337)" src="nosuchimage.png">.
    -        // We assume that the inner HTML is from a trusted source.
    -        // The pre-tag is required for IE8 which strips newlines from innerHTML
    -        // when it is injected into a <pre> tag.
    -        // http://stackoverflow.com/questions/451486/pre-tag-loses-line-breaks-when-setting-innerhtml-in-ie
    -        // http://stackoverflow.com/questions/195363/inserting-a-newline-into-a-pre-tag-ie-javascript
    -        container.innerHTML = '<pre>' + sourceCodeHtml + '</pre>';
    -        container = /** @type{!Element} */(container.firstChild);
    -        if (nl) {
    -          numberLines(container, nl, true);
    -        }
    -    
    -        /** @type{JobT} */
    -        var job = {
    -          langExtension: langExtension,
    -          numberLines: nl,
    -          sourceNode: container,
    -          pre: 1,
    -          sourceCode: null,
    -          basePos: null,
    -          spans: null,
    -          decorations: null
    -        };
    -        applyDecorator(job);
    -        return container.innerHTML;
    -      }
    -    
    -       /**
    -        * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
    -        * {@code class=prettyprint} and prettify them.
    -        *
    -        * @param {Function} opt_whenDone called when prettifying is done.
    -        * @param {HTMLElement|HTMLDocument} opt_root an element or document
    -        *   containing all the elements to pretty print.
    -        *   Defaults to {@code document.body}.
    -        */
    -      function $prettyPrint(opt_whenDone, opt_root) {
    -        var root = opt_root || document.body;
    -        var doc = root.ownerDocument || document;
    -        function byTagName(tn) { return root.getElementsByTagName(tn); }
    -        // fetch a list of nodes to rewrite
    -        var codeSegments = [byTagName('pre'), byTagName('code'), byTagName('xmp')];
    -        var elements = [];
    -        for (var i = 0; i < codeSegments.length; ++i) {
    -          for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
    -            elements.push(codeSegments[i][j]);
    -          }
    -        }
    -        codeSegments = null;
    -    
    -        var clock = Date;
    -        if (!clock['now']) {
    -          clock = { 'now': function () { return +(new Date); } };
    -        }
    -    
    -        // The loop is broken into a series of continuations to make sure that we
    -        // don't make the browser unresponsive when rewriting a large page.
    -        var k = 0;
    -    
    -        var langExtensionRe = /\blang(?:uage)?-([\w.]+)(?!\S)/;
    -        var prettyPrintRe = /\bprettyprint\b/;
    -        var prettyPrintedRe = /\bprettyprinted\b/;
    -        var preformattedTagNameRe = /pre|xmp/i;
    -        var codeRe = /^code$/i;
    -        var preCodeXmpRe = /^(?:pre|code|xmp)$/i;
    -        var EMPTY = {};
    -    
    -        function doWork() {
    -          var endTime = (win['PR_SHOULD_USE_CONTINUATION'] ?
    -                         clock['now']() + 250 /* ms */ :
    -                         Infinity);
    -          for (; k < elements.length && clock['now']() < endTime; k++) {
    -            var cs = elements[k];
    -    
    -            // Look for a preceding comment like
    -            // <?prettify lang="..." linenums="..."?>
    -            var attrs = EMPTY;
    -            {
    -              for (var preceder = cs; (preceder = preceder.previousSibling);) {
    -                var nt = preceder.nodeType;
    -                // <?foo?> is parsed by HTML 5 to a comment node (8)
    -                // like <!--?foo?-->, but in XML is a processing instruction
    -                var value = (nt === 7 || nt === 8) && preceder.nodeValue;
    -                if (value
    -                    ? !/^\??prettify\b/.test(value)
    -                    : (nt !== 3 || /\S/.test(preceder.nodeValue))) {
    -                  // Skip over white-space text nodes but not others.
    -                  break;
    -                }
    -                if (value) {
    -                  attrs = {};
    -                  value.replace(
    -                      /\b(\w+)=([\w:.%+-]+)/g,
    -                    function (_, name, value) { attrs[name] = value; });
    -                  break;
    -                }
    -              }
    -            }
    -    
    -            var className = cs.className;
    -            if ((attrs !== EMPTY || prettyPrintRe.test(className))
    -                // Don't redo this if we've already done it.
    -                // This allows recalling pretty print to just prettyprint elements
    -                // that have been added to the page since last call.
    -                && !prettyPrintedRe.test(className)) {
    -    
    -              // make sure this is not nested in an already prettified element
    -              var nested = false;
    -              for (var p = cs.parentNode; p; p = p.parentNode) {
    -                var tn = p.tagName;
    -                if (preCodeXmpRe.test(tn)
    -                    && p.className && prettyPrintRe.test(p.className)) {
    -                  nested = true;
    -                  break;
    -                }
    -              }
    -              if (!nested) {
    -                // Mark done.  If we fail to prettyprint for whatever reason,
    -                // we shouldn't try again.
    -                cs.className += ' prettyprinted';
    -    
    -                // If the classes includes a language extensions, use it.
    -                // Language extensions can be specified like
    -                //     <pre class="prettyprint lang-cpp">
    -                // the language extension "cpp" is used to find a language handler
    -                // as passed to PR.registerLangHandler.
    -                // HTML5 recommends that a language be specified using "language-"
    -                // as the prefix instead.  Google Code Prettify supports both.
    -                // http://dev.w3.org/html5/spec-author-view/the-code-element.html
    -                var langExtension = attrs['lang'];
    -                if (!langExtension) {
    -                  langExtension = className.match(langExtensionRe);
    -                  // Support <pre class="prettyprint"><code class="language-c">
    -                  var wrapper;
    -                  if (!langExtension && (wrapper = childContentWrapper(cs))
    -                      && codeRe.test(wrapper.tagName)) {
    -                    langExtension = wrapper.className.match(langExtensionRe);
    -                  }
    -    
    -                  if (langExtension) { langExtension = langExtension[1]; }
    -                }
    -    
    -                var preformatted;
    -                if (preformattedTagNameRe.test(cs.tagName)) {
    -                  preformatted = 1;
    -                } else {
    -                  var currentStyle = cs['currentStyle'];
    -                  var defaultView = doc.defaultView;
    -                  var whitespace = (
    -                      currentStyle
    -                      ? currentStyle['whiteSpace']
    -                      : (defaultView
    -                         && defaultView.getComputedStyle)
    -                      ? defaultView.getComputedStyle(cs, null)
    -                      .getPropertyValue('white-space')
    -                      : 0);
    -                  preformatted = whitespace
    -                      && 'pre' === whitespace.substring(0, 3);
    -                }
    -    
    -                // Look for a class like linenums or linenums:<n> where <n> is the
    -                // 1-indexed number of the first line.
    -                var lineNums = attrs['linenums'];
    -                if (!(lineNums = lineNums === 'true' || +lineNums)) {
    -                  lineNums = className.match(/\blinenums\b(?::(\d+))?/);
    -                  lineNums =
    -                    lineNums
    -                    ? lineNums[1] && lineNums[1].length
    -                      ? +lineNums[1] : true
    -                    : false;
    -                }
    -                if (lineNums) { numberLines(cs, lineNums, preformatted); }
    -    
    -                // do the pretty printing
    -                var prettyPrintingJob = {
    -                  langExtension: langExtension,
    -                  sourceNode: cs,
    -                  numberLines: lineNums,
    -                  pre: preformatted,
    -                  sourceCode: null,
    -                  basePos: null,
    -                  spans: null,
    -                  decorations: null
    -                };
    -                applyDecorator(prettyPrintingJob);
    -              }
    -            }
    -          }
    -          if (k < elements.length) {
    -            // finish up in a continuation
    -            win.setTimeout(doWork, 250);
    -          } else if ('function' === typeof opt_whenDone) {
    -            opt_whenDone();
    -          }
    -        }
    -    
    -        doWork();
    -      }
    -    
    -      /**
    -       * Contains functions for creating and registering new language handlers.
    -       * @type {Object}
    -       */
    -      var PR = win['PR'] = {
    -            'createSimpleLexer': createSimpleLexer,
    -            'registerLangHandler': registerLangHandler,
    -            'sourceDecorator': sourceDecorator,
    -            'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
    -            'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
    -            'PR_COMMENT': PR_COMMENT,
    -            'PR_DECLARATION': PR_DECLARATION,
    -            'PR_KEYWORD': PR_KEYWORD,
    -            'PR_LITERAL': PR_LITERAL,
    -            'PR_NOCODE': PR_NOCODE,
    -            'PR_PLAIN': PR_PLAIN,
    -            'PR_PUNCTUATION': PR_PUNCTUATION,
    -            'PR_SOURCE': PR_SOURCE,
    -            'PR_STRING': PR_STRING,
    -            'PR_TAG': PR_TAG,
    -            'PR_TYPE': PR_TYPE,
    -            'prettyPrintOne':
    -               IN_GLOBAL_SCOPE
    -                 ? (win['prettyPrintOne'] = $prettyPrintOne)
    -                 : (prettyPrintOne = $prettyPrintOne),
    -            'prettyPrint': prettyPrint =
    -               IN_GLOBAL_SCOPE
    -                 ? (win['prettyPrint'] = $prettyPrint)
    -                 : (prettyPrint = $prettyPrint)
    -          };
    -    
    -      // Make PR available via the Asynchronous Module Definition (AMD) API.
    -      // Per https://github.com/amdjs/amdjs-api/wiki/AMD:
    -      // The Asynchronous Module Definition (AMD) API specifies a
    -      // mechanism for defining modules such that the module and its
    -      // dependencies can be asynchronously loaded.
    -      // ...
    -      // To allow a clear indicator that a global define function (as
    -      // needed for script src browser loading) conforms to the AMD API,
    -      // any global define function SHOULD have a property called "amd"
    -      // whose value is an object. This helps avoid conflict with any
    -      // other existing JavaScript code that could have defined a define()
    -      // function that does not conform to the AMD API.
    -      var define = win['define'];
    -      if (typeof define === "function" && define['amd']) {
    -        define("google-code-prettify", [], function () {
    -          return PR;
    -        });
    -      }
    -    })();
    -    return prettyPrint;
    -  })();
    -
    -  // If this script is deferred or async and the document is already
    -  // loaded we need to wait for language handlers to load before performing
    -  // any autorun.
    -  function onLangsLoaded() {
    -    if (autorun) {
    -      contentLoaded(
    -        function () {
    -          var n = callbacks.length;
    -          var callback = n ? function () {
    -            for (var i = 0; i < n; ++i) {
    -              (function (i) {
    -                win.setTimeout(
    -                   function () {
    -                     win['exports'][callbacks[i]].apply(win, arguments);
    -                   }, 0);
    -               })(i);
    -            }
    -          } : void 0;
    -          prettyPrint(callback);
    -        });
    -    }
    -  }
    -  checkPendingLanguages();
    -
    -}());
    diff --git a/source/plugins/prettify/themes/atelier-dune-dark.css b/source/plugins/prettify/themes/atelier-dune-dark.css
    deleted file mode 100644
    index 252e5dcb..00000000
    --- a/source/plugins/prettify/themes/atelier-dune-dark.css
    +++ /dev/null
    @@ -1,119 +0,0 @@
    -/*! Color themes for Google Code Prettify | MIT License | github.com/jmblog/color-themes-for-google-code-prettify */
    -.prettyprint {
    -  background: #20201d;
    -  font-family: Menlo, "Bitstream Vera Sans Mono", "DejaVu Sans Mono", Monaco, Consolas, monospace;
    -  border: 0 !important;
    -}
    -
    -.pln {
    -  color: #fefbec;
    -}
    -
    -/* Specify class=linenums on a pre to get line numbering */
    -ol.linenums {
    -  margin-top: 0;
    -  margin-bottom: 0;
    -  color: #7d7a68;
    -}
    -
    -li.L0,
    -li.L1,
    -li.L2,
    -li.L3,
    -li.L4,
    -li.L5,
    -li.L6,
    -li.L7,
    -li.L8,
    -li.L9 {
    -  padding-left: 1em;
    -  background-color: #20201d;
    -  list-style-type: decimal;
    -}
    -
    -@media screen {
    -
    -  /* string content */
    -
    -  .str {
    -    color: #60ac39;
    -  }
    -
    -  /* keyword */
    -
    -  .kwd {
    -    color: #b854d4;
    -  }
    -
    -  /* comment */
    -
    -  .com {
    -    color: #7d7a68;
    -  }
    -
    -  /* type name */
    -
    -  .typ {
    -    color: #6684e1;
    -  }
    -
    -  /* literal value */
    -
    -  .lit {
    -    color: #b65611;
    -  }
    -
    -  /* punctuation */
    -
    -  .pun {
    -    color: #fefbec;
    -  }
    -
    -  /* lisp open bracket */
    -
    -  .opn {
    -    color: #fefbec;
    -  }
    -
    -  /* lisp close bracket */
    -
    -  .clo {
    -    color: #fefbec;
    -  }
    -
    -  /* markup tag name */
    -
    -  .tag {
    -    color: #d73737;
    -  }
    -
    -  /* markup attribute name */
    -
    -  .atn {
    -    color: #b65611;
    -  }
    -
    -  /* markup attribute value */
    -
    -  .atv {
    -    color: #1fad83;
    -  }
    -
    -  /* declaration */
    -
    -  .dec {
    -    color: #b65611;
    -  }
    -
    -  /* variable name */
    -
    -  .var {
    -    color: #d73737;
    -  }
    -
    -  /* function name */
    -
    -  .fun {
    -    color: #6684e1;
    -  }
    -}
    \ No newline at end of file
    diff --git a/source/plugins/prettify/themes/atelier-forest-dark.css b/source/plugins/prettify/themes/atelier-forest-dark.css
    deleted file mode 100644
    index a8f735e2..00000000
    --- a/source/plugins/prettify/themes/atelier-forest-dark.css
    +++ /dev/null
    @@ -1,119 +0,0 @@
    -/*! Color themes for Google Code Prettify | MIT License | github.com/jmblog/color-themes-for-google-code-prettify */
    -.prettyprint {
    -  background: #1b1918;
    -  font-family: Menlo, "Bitstream Vera Sans Mono", "DejaVu Sans Mono", Monaco, Consolas, monospace;
    -  border: 0 !important;
    -}
    -
    -.pln {
    -  color: #f1efee;
    -}
    -
    -/* Specify class=linenums on a pre to get line numbering */
    -ol.linenums {
    -  margin-top: 0;
    -  margin-bottom: 0;
    -  color: #766e6b;
    -}
    -
    -li.L0,
    -li.L1,
    -li.L2,
    -li.L3,
    -li.L4,
    -li.L5,
    -li.L6,
    -li.L7,
    -li.L8,
    -li.L9 {
    -  padding-left: 1em;
    -  background-color: #1b1918;
    -  list-style-type: decimal;
    -}
    -
    -@media screen {
    -
    -  /* string content */
    -
    -  .str {
    -    color: #7b9726;
    -  }
    -
    -  /* keyword */
    -
    -  .kwd {
    -    color: #6666ea;
    -  }
    -
    -  /* comment */
    -
    -  .com {
    -    color: #766e6b;
    -  }
    -
    -  /* type name */
    -
    -  .typ {
    -    color: #407ee7;
    -  }
    -
    -  /* literal value */
    -
    -  .lit {
    -    color: #df5320;
    -  }
    -
    -  /* punctuation */
    -
    -  .pun {
    -    color: #f1efee;
    -  }
    -
    -  /* lisp open bracket */
    -
    -  .opn {
    -    color: #f1efee;
    -  }
    -
    -  /* lisp close bracket */
    -
    -  .clo {
    -    color: #f1efee;
    -  }
    -
    -  /* markup tag name */
    -
    -  .tag {
    -    color: #f22c40;
    -  }
    -
    -  /* markup attribute name */
    -
    -  .atn {
    -    color: #df5320;
    -  }
    -
    -  /* markup attribute value */
    -
    -  .atv {
    -    color: #3d97b8;
    -  }
    -
    -  /* declaration */
    -
    -  .dec {
    -    color: #df5320;
    -  }
    -
    -  /* variable name */
    -
    -  .var {
    -    color: #f22c40;
    -  }
    -
    -  /* function name */
    -
    -  .fun {
    -    color: #407ee7;
    -  }
    -}
    \ No newline at end of file
    diff --git a/source/plugins/prettify/themes/atelier-savanna-dark.css b/source/plugins/prettify/themes/atelier-savanna-dark.css
    deleted file mode 100644
    index 2e92b3d0..00000000
    --- a/source/plugins/prettify/themes/atelier-savanna-dark.css
    +++ /dev/null
    @@ -1,119 +0,0 @@
    -/*! Color themes for Google Code Prettify | MIT License | github.com/jmblog/color-themes-for-google-code-prettify */
    -.prettyprint {
    -  background: #171c19;
    -  font-family: Menlo, "Bitstream Vera Sans Mono", "DejaVu Sans Mono", Monaco, Consolas, monospace;
    -  border: 0 !important;
    -}
    -
    -.pln {
    -  color: #ecf4ee;
    -}
    -
    -/* Specify class=linenums on a pre to get line numbering */
    -ol.linenums {
    -  margin-top: 0;
    -  margin-bottom: 0;
    -  color: #5f6d64;
    -}
    -
    -li.L0,
    -li.L1,
    -li.L2,
    -li.L3,
    -li.L4,
    -li.L5,
    -li.L6,
    -li.L7,
    -li.L8,
    -li.L9 {
    -  padding-left: 1em;
    -  background-color: #171c19;
    -  list-style-type: decimal;
    -}
    -
    -@media screen {
    -
    -  /* string content */
    -
    -  .str {
    -    color: #489963;
    -  }
    -
    -  /* keyword */
    -
    -  .kwd {
    -    color: #55859b;
    -  }
    -
    -  /* comment */
    -
    -  .com {
    -    color: #5f6d64;
    -  }
    -
    -  /* type name */
    -
    -  .typ {
    -    color: #478c90;
    -  }
    -
    -  /* literal value */
    -
    -  .lit {
    -    color: #9f713c;
    -  }
    -
    -  /* punctuation */
    -
    -  .pun {
    -    color: #ecf4ee;
    -  }
    -
    -  /* lisp open bracket */
    -
    -  .opn {
    -    color: #ecf4ee;
    -  }
    -
    -  /* lisp close bracket */
    -
    -  .clo {
    -    color: #ecf4ee;
    -  }
    -
    -  /* markup tag name */
    -
    -  .tag {
    -    color: #b16139;
    -  }
    -
    -  /* markup attribute name */
    -
    -  .atn {
    -    color: #9f713c;
    -  }
    -
    -  /* markup attribute value */
    -
    -  .atv {
    -    color: #1c9aa0;
    -  }
    -
    -  /* declaration */
    -
    -  .dec {
    -    color: #9f713c;
    -  }
    -
    -  /* variable name */
    -
    -  .var {
    -    color: #b16139;
    -  }
    -
    -  /* function name */
    -
    -  .fun {
    -    color: #478c90;
    -  }
    -}
    \ No newline at end of file
    diff --git a/source/plugins/prettify/themes/tomorrow-light.css b/source/plugins/prettify/themes/tomorrow-light.css
    deleted file mode 100644
    index 3638ea97..00000000
    --- a/source/plugins/prettify/themes/tomorrow-light.css
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -/*! Color themes for Google Code Prettify | MIT License | github.com/jmblog/color-themes-for-google-code-prettify */
    -.prettyprint{background:#fff;font-family:Menlo,Bitstream Vera Sans Mono,DejaVu Sans Mono,Monaco,Consolas,monospace;border:0!important}.pln{color:#4d4d4c}ol.linenums{margin-top:0;margin-bottom:0;color:#8e908c}li.L0,li.L1,li.L2,li.L3,li.L4,li.L5,li.L6,li.L7,li.L8,li.L9{padding-left:1em;background-color:#fff;list-style-type:decimal}@media screen{.str{color:#718c00}.kwd{color:#8959a8}.com{color:#8e908c}.typ{color:#4271ae}.lit{color:#f5871f}.pun{color:#4d4d4c}.opn{color:#4d4d4c}.clo{color:#4d4d4c}.tag{color:#c82829}.atn{color:#f5871f}.atv{color:#3e999f}.dec{color:#f5871f}.var{color:#c82829}.fun{color:#4271ae}}
    \ No newline at end of file
    diff --git a/source/plugins/prettify/themes/tomorrow-night-eighties.css b/source/plugins/prettify/themes/tomorrow-night-eighties.css
    deleted file mode 100644
    index 1b7574ad..00000000
    --- a/source/plugins/prettify/themes/tomorrow-night-eighties.css
    +++ /dev/null
    @@ -1,119 +0,0 @@
    -/*! Color themes for Google Code Prettify | MIT License | github.com/jmblog/color-themes-for-google-code-prettify */
    -.prettyprint {
    -  background: #50504f;
    -  font-family: Menlo, "Bitstream Vera Sans Mono", "DejaVu Sans Mono", Monaco, Consolas, monospace;
    -  border: 0 !important;
    -}
    -
    -.pln {
    -  color: #cccccc;
    -}
    -
    -/* Specify class=linenums on a pre to get line numbering */
    -ol.linenums {
    -  margin-top: 0;
    -  margin-bottom: 0;
    -  color: #999999;
    -}
    -
    -li.L0,
    -li.L1,
    -li.L2,
    -li.L3,
    -li.L4,
    -li.L5,
    -li.L6,
    -li.L7,
    -li.L8,
    -li.L9 {
    -  padding-left: 1em;
    -  background-color: #50504f;
    -  list-style-type: decimal;
    -}
    -
    -@media screen {
    -
    -  /* string content */
    -
    -  .str {
    -    color: #99cc99;
    -  }
    -
    -  /* keyword */
    -
    -  .kwd {
    -    color: #cc99cc;
    -  }
    -
    -  /* comment */
    -
    -  .com {
    -    color: #999999;
    -  }
    -
    -  /* type name */
    -
    -  .typ {
    -    color: #6699cc;
    -  }
    -
    -  /* literal value */
    -
    -  .lit {
    -    color: #f99157;
    -  }
    -
    -  /* punctuation */
    -
    -  .pun {
    -    color: #cccccc;
    -  }
    -
    -  /* lisp open bracket */
    -
    -  .opn {
    -    color: #cccccc;
    -  }
    -
    -  /* lisp close bracket */
    -
    -  .clo {
    -    color: #cccccc;
    -  }
    -
    -  /* markup tag name */
    -
    -  .tag {
    -    color: #f2777a;
    -  }
    -
    -  /* markup attribute name */
    -
    -  .atn {
    -    color: #f99157;
    -  }
    -
    -  /* markup attribute value */
    -
    -  .atv {
    -    color: #66cccc;
    -  }
    -
    -  /* declaration */
    -
    -  .dec {
    -    color: #f99157;
    -  }
    -
    -  /* variable name */
    -
    -  .var {
    -    color: #f2777a;
    -  }
    -
    -  /* function name */
    -
    -  .fun {
    -    color: #6699cc;
    -  }
    -}
    \ No newline at end of file
    diff --git a/source/search.html b/source/search.html
    deleted file mode 100644
    index 93e5b625..00000000
    --- a/source/search.html
    +++ /dev/null
    @@ -1,19 +0,0 @@
    -<!DOCTYPE html>
    -<html>
    -    <head>
    -        <meta charset="utf-8">
    -        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    -        <title>请稍候</title>
    -        <script>
    -            var search = window.location.search;
    -            if (search.indexOf("?m=google") >= 0) {
    -                window.location.href = "https://vip.kuaimen.bid/search?safe=strict&hl=zh-CN&q=" + search.replace("?m=google&w=", "");
    -            } else if (search.indexOf("?m=baidu") >= 0) {
    -                window.location.href = "https://www.baidu.com/s?ie=utf8&oe=utf8&wd=" + search.replace("?m=baidu&w=", "");
    -            } else {
    -                window.location.href = "https://pyqt5.com";
    -            }
    -        </script>
    -    </head>
    -    <body></body>
    -</html>
    \ No newline at end of file
    diff --git a/source/self/btf.css b/source/self/btf.css
    deleted file mode 100644
    index c7c31b17..00000000
    --- a/source/self/btf.css
    +++ /dev/null
    @@ -1 +0,0 @@
    -.aside-qrcode{text-align:center;padding-top:4px}.aside-qrcode img{max-width:100%;width:200px;height:200px;margin:4px 4px -10px 4px}
    \ No newline at end of file
    diff --git a/source/self/btf.js b/source/self/btf.js
    deleted file mode 100644
    index 3ff5bc6f..00000000
    --- a/source/self/btf.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -(()=>{const e=e=>e.includes("/en/");window.loadFullPage=e=>{window.location.href=e};const o=e(window.location.href),l=o?document.querySelectorAll('a[href^="https://butterfly.js.org"]'):document.querySelectorAll('a[href^="/en/"]');var r;r=o,l.forEach((o=>{r&&e(o.href)||(o.href=`javascript:loadFullPage('${o.href}');`)}))})();
    \ No newline at end of file
    diff --git a/source/static/api/css/imgshare.css b/source/static/api/css/imgshare.css
    deleted file mode 100644
    index 1280cd3f..00000000
    --- a/source/static/api/css/imgshare.css
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -.sr-bdimgshare{position:absolute;overflow:hidden;z-index:9990;color:white}.sr-bdimgshare-white{color:#666}.sr-bdimgshare .bdimgshare-bg{position:absolute;width:100%;height:100%;overflow:hidden;filter:alpha(opacity=40);opacity:.4}.sr-bdimgshare-white .bdimgshare-bg{filter:alpha(opacity=80);opacity:.8}.sr-bdimgshare .bdimgshare-content{position:relative;float:right;padding:5px 8px 5px 0}.sr-bdimgshare-black .bdimgshare-bg{background:black}.sr-bdimgshare-white .bdimgshare-bg{background:white}.sr-bdimgshare .bdimgshare-content .bdimgshare-lbl{padding-right:5px;cursor:default;float:left}.sr-bdimgshare-16 .bdimgshare-icon{display:inline-block;width:16px;height:16px;overflow:hidden;margin:8px 0 0 2px;cursor:pointer;background:url(../img/share/icons_0_16.png?v=91362611.png) no-repeat}.sr-bdimgshare-32 .bdimgshare-icon{display:inline-block;width:32px;height:32px;overflow:hidden;margin:8px 0 0 5px;cursor:pointer;background:url(../img/share/icons_0_32.png?v=7f3ed0f4.png) no-repeat}.sr-bdimgshare-black .bdimgshare-icon{filter:alpha(opacity=90);opacity:.9}.sr-bdimgshare-black .bdimgshare-icon:hover{filter:none;opacity:1}.sr-bdimgshare-white .bdimgshare-icon{filter:alpha(opacity=80);opacity:.8}.sr-bdimgshare-white .bdimgshare-icon:hover{filter:none;opacity:1}.sr-bdimgshare-collection{zoom:1;z-index:9990;_padding:2px}.sr-bdimgshare-collection:after{content:'\20';display:block;height:0;clear:both}.bdimgshare-coll-coll-saved{display:none}.bdimgshare-coll-coll,.bdimgshare-coll-share,.bdimgshare-coll-coll-saved,.bdimgshare-coll-coll:hover,.bdimgshare-coll-share:hover,.bdimgshare-coll-coll-saved:hover{text-decoration:none;text-align:center;_overflow:hidden}.sr-bdimgshare-coll-white .bdimgshare-coll-coll,.sr-bdimgshare-coll-white .bdimgshare-coll-coll-saved,.sr-bdimgshare-coll-white .bdimgshare-coll-share{color:#666;background-color:#fff;background-image:url(../images/imgshare/imgshare_collection_icons_w.png);background-repeat:no-repeat;border-width:1px;border-style:solid;border-color:#e6e6e6 #e6e6e6 #ccc}.sr-bdimgshare-coll-black .bdimgshare-coll-coll,.sr-bdimgshare-coll-black .bdimgshare-coll-coll-saved,.sr-bdimgshare-coll-black .bdimgshare-coll-share{color:#ddd;background-color:#4c4c4c;background-image:url(../images/imgshare/imgshare_collection_icons_b.png);background-repeat:no-repeat;border-width:1px;border-style:solid;border-color:#393939}.sr-bdimgshare-coll-white .bdimgshare-coll-coll:hover{color:#f24949}.sr-bdimgshare-coll-white .bdimgshare-coll-share:hover{color:#2c73c3}.sr-bdimgshare-coll-1-small .bdimgshare-coll-share,.sr-bdimgshare-coll-1-middle .bdimgshare-coll-share,.sr-bdimgshare-coll-1-big .bdimgshare-coll-share,.sr-bdimgshare-coll-1-small .bdimgshare-coll-coll,.sr-bdimgshare-coll-1-middle .bdimgshare-coll-coll,.sr-bdimgshare-coll-1-big .bdimgshare-coll-coll{display:block}.sr-bdimgshare-coll-1-small .bdimgshare-coll-coll,.sr-bdimgshare-coll-1-small .bdimgshare-coll-coll-saved,.sr-bdimgshare-coll-1-small .bdimgshare-coll-share{width:51px;height:23px;padding-left:21px;line-height:23px;font-size:12px;float:left;letter-spacing:7px}.sr-bdimgshare-coll-1-small .bdimgshare-coll-coll{background-position:5px 4px}.sr-bdimgshare-coll-1-small .bdimgshare-coll-coll:hover,.sr-bdimgshare-coll-1-small .bdimgshare-coll-coll-saved{background-position:5px -16px}.sr-bdimgshare-coll-1-small .bdimgshare-coll-share{background-position:5px -36px;margin-left:-1px}.sr-bdimgshare-coll-1-small .bdimgshare-coll-share:hover{background-position:5px -56px}.sr-bdimgshare-coll-1-middle .bdimgshare-coll-coll,.sr-bdimgshare-coll-1-middle .bdimgshare-coll-share,.sr-bdimgshare-coll-1-middle .bdimgshare-coll-coll-saved{width:51px;height:30px;padding-left:26px;line-height:30px;font-size:12px;float:left;letter-spacing:7px}.sr-bdimgshare-coll-1-middle .bdimgshare-coll-coll{background-position:10px -77px}.sr-bdimgshare-coll-1-middle .bdimgshare-coll-coll:hover,.sr-bdimgshare-coll-1-middle .bdimgshare-coll-coll-saved{background-position:10px -102px}.sr-bdimgshare-coll-1-middle .bdimgshare-coll-share{background-position:10px -127px;margin-left:-1px}.sr-bdimgshare-coll-1-middle .bdimgshare-coll-share:hover{background-position:10px -153px}.sr-bdimgshare-coll-1-big .bdimgshare-coll-coll,.sr-bdimgshare-coll-1-big .bdimgshare-coll-share,.sr-bdimgshare-coll-1-big .bdimgshare-coll-coll-saved{width:64px;height:38px;padding-left:32px;line-height:38px;font-size:14px;float:left;letter-spacing:8px}.sr-bdimgshare-coll-1-big .bdimgshare-coll-coll{background-position:10px -178px}.sr-bdimgshare-coll-1-big .bdimgshare-coll-coll:hover,.sr-bdimgshare-coll-1-big .bdimgshare-coll-coll-saved{background-position:10px -209px}.sr-bdimgshare-coll-1-big .bdimgshare-coll-share{background-position:10px -239px;margin-left:-1px}.sr-bdimgshare-coll-1-big .bdimgshare-coll-share:hover{background-position:10px -269px}.sr-bdimgshare-coll-2-small .bdimgshare-coll-share,.sr-bdimgshare-coll-2-middle .bdimgshare-coll-share,.sr-bdimgshare-coll-2-big .bdimgshare-coll-share,.sr-bdimgshare-coll-2-small .bdimgshare-coll-coll,.sr-bdimgshare-coll-2-middle .bdimgshare-coll-coll,.sr-bdimgshare-coll-2-big .bdimgshare-coll-coll{display:block}.sr-bdimgshare-coll-2-small .bdimgshare-coll-coll,.sr-bdimgshare-coll-2-small .bdimgshare-coll-share,.sr-bdimgshare-coll-2-small .bdimgshare-coll-coll-saved{width:24px;height:24px;overflow:hidden;float:left;text-indent:-9999px}.sr-bdimgshare-coll-2-small .bdimgshare-coll-coll{background-position:4px 4px}.sr-bdimgshare-coll-2-small .bdimgshare-coll-coll:hover,.sr-bdimgshare-coll-2-small .bdimgshare-coll-coll-saved{background-position:4px -16px}.sr-bdimgshare-coll-2-small .bdimgshare-coll-share{background-position:4px -36px;margin-left:-1px}.sr-bdimgshare-coll-2-small .bdimgshare-coll-share:hover{background-position:4px -56px}.sr-bdimgshare-coll-2-middle .bdimgshare-coll-coll,.sr-bdimgshare-coll-2-middle .bdimgshare-coll-share,.sr-bdimgshare-coll-2-middle .bdimgshare-coll-coll-saved{width:32px;height:32px;overflow:hidden;float:left;text-indent:-9999px}.sr-bdimgshare-coll-2-middle .bdimgshare-coll-coll{background-position:7px -76px}.sr-bdimgshare-coll-2-middle .bdimgshare-coll-coll:hover,.sr-bdimgshare-coll-2-middle .bdimgshare-coll-coll-saved{background-position:7px -101px}.sr-bdimgshare-coll-2-middle .bdimgshare-coll-share{background-position:7px -127px;margin-left:-1px}.sr-bdimgshare-coll-2-middle .bdimgshare-coll-share:hover{background-position:7px -153px}.sr-bdimgshare-coll-2-big .bdimgshare-coll-coll,.sr-bdimgshare-coll-2-big .bdimgshare-coll-share,.sr-bdimgshare-coll-2-big .bdimgshare-coll-coll-saved{width:36px;height:36px;overflow:hidden;float:left;text-indent:-9999px}.sr-bdimgshare-coll-2-big .bdimgshare-coll-coll{background-position:7px -178px}.sr-bdimgshare-coll-2-big .bdimgshare-coll-coll:hover,.sr-bdimgshare-coll-2-big .bdimgshare-coll-coll-saved{background-position:7px -209px}.sr-bdimgshare-coll-2-big .bdimgshare-coll-share{background-position:7px -240px;margin-left:-1px}.sr-bdimgshare-coll-2-big .bdimgshare-coll-share:hover{background-position:7px -270px}.sr-bdimgshare-coll-3-small .bdimgshare-coll-share,.sr-bdimgshare-coll-3-middle .bdimgshare-coll-share,.sr-bdimgshare-coll-3-big .bdimgshare-coll-share,.sr-bdimgshare-coll-3-small .bdimgshare-coll-coll,.sr-bdimgshare-coll-3-middle .bdimgshare-coll-coll,.sr-bdimgshare-coll-3-big .bdimgshare-coll-coll{display:block}.sr-bdimgshare-coll-3-small .bdimgshare-coll-coll,.sr-bdimgshare-coll-3-small .bdimgshare-coll-coll-saved,.sr-bdimgshare-coll-3-small .bdimgshare-coll-share{width:35px;height:23px;padding-left:18px;line-height:23px;font-size:12px}.sr-bdimgshare-coll-3-small .bdimgshare-coll-coll{background-position:5px 4px}.sr-bdimgshare-coll-3-small .bdimgshare-coll-coll:hover,.sr-bdimgshare-coll-3-small .bdimgshare-coll-coll-saved{background-position:5px -16px}.sr-bdimgshare-coll-3-small .bdimgshare-coll-share{background-position:5px -36px;margin-top:-1px}.sr-bdimgshare-coll-3-small .bdimgshare-coll-share:hover{background-position:5px -56px}
    -.sr-bdimgshare-coll-3-middle .bdimgshare-coll-coll,.sr-bdimgshare-coll-3-middle .bdimgshare-coll-share,.sr-bdimgshare-coll-3-middle .bdimgshare-coll-coll-saved{width:40px;height:30px;padding-left:23px;line-height:30px;font-size:12px}.sr-bdimgshare-coll-3-middle .bdimgshare-coll-coll{background-position:10px -77px}.sr-bdimgshare-coll-3-middle .bdimgshare-coll-coll:hover,.sr-bdimgshare-coll-3-middle .bdimgshare-coll-coll-saved{background-position:10px -102px}.sr-bdimgshare-coll-3-middle .bdimgshare-coll-share{background-position:10px -127px;margin-top:-1px}.sr-bdimgshare-coll-3-middle .bdimgshare-coll-share:hover{background-position:10px -153px}.sr-bdimgshare-coll-3-big .bdimgshare-coll-coll,.sr-bdimgshare-coll-3-big .bdimgshare-coll-share,.sr-bdimgshare-coll-3-big .bdimgshare-coll-coll-saved{width:47px;height:38px;padding-left:26px;line-height:38px;font-size:14px}.sr-bdimgshare-coll-3-big .bdimgshare-coll-coll{background-position:10px -178px}.sr-bdimgshare-coll-3-big .bdimgshare-coll-coll:hover,.sr-bdimgshare-coll-3-big .bdimgshare-coll-coll-saved{background-position:10px -209px}.sr-bdimgshare-coll-3-big .bdimgshare-coll-share{background-position:10px -239px;margin-top:-1px}.sr-bdimgshare-coll-3-big .bdimgshare-coll-share:hover{background-position:10px -269px}.sr-bdimgshare-coll-3-small .bdimgshare-coll-coll-saved{width:53px;padding:0;background-image:none}.sr-bdimgshare-coll-3-middle .bdimgshare-coll-coll-saved{width:63px;padding:0;background-image:none}.sr-bdimgshare-coll-3-big .bdimgshare-coll-coll-saved{width:73px;padding:0;background-image:none}.bdimgshare-collected .bdimgshare-coll-coll{display:none}.bdimgshare-collected .bdimgshare-coll-coll-saved{display:block;letter-spacing:0}.sr-bdimgshare-coll-white .bdimgshare-coll-coll-saved{color:#f24949}
    \ No newline at end of file
    diff --git a/source/static/api/css/like.css b/source/static/api/css/like.css
    deleted file mode 100644
    index 11d3f694..00000000
    --- a/source/static/api/css/like.css
    +++ /dev/null
    @@ -1 +0,0 @@
    -.bdlikebutton{background:url("../img/like/like.png?v=aa778a3c.png") no-repeat;position:relative;cursor:pointer;text-align:center;font-size:12px}.bdlikebutton-inner{overflow:hidden;*zoom:1}.bdlikebutton-small{width:85px;height:25px;text-align:center;font-weight:300}.bdlikebutton-small .bdlikebutton-count{padding-left:23px;line-height:25px}.bdlikebutton-medium{width:105px;height:50px}.bdlikebutton-medium .bdlikebutton-count,.bdlikebutton-large .bdlikebutton-count{background:url("../img/like/like.png?v=aa778a3c.png") no-repeat;display:inline-block;*display:inline;*zoom:1}.bdlikebutton-medium .bdlikebutton-count{margin-top:8px;padding:2px 0 0 20px;line-height:15px}.bdlikebutton-medium-orange .bdlikebutton-count{background-position:-280px 0}.bdlikebutton-medium-blue .bdlikebutton-count{background-position:-280px -30px}.bdlikebutton-medium-green .bdlikebutton-count{background-position:-280px -60px}.bdlikebutton-medium-red .bdlikebutton-count{background-position:-280px -90px}.bdlikebutton-medium-orange-hover .bdlikebutton-count{background-position:-280px -600px}.bdlikebutton-medium-blue-hover .bdlikebutton-count{background-position:-280px -630px}.bdlikebutton-medium-green-hover .bdlikebutton-count{background-position:-280px -660px}.bdlikebutton-medium-red-hover .bdlikebutton-count{background-position:-280px -690px}.bdlikebutton-large .bdlikebutton-count{margin-top:8px;padding:2px 0 0 27px;line-height:24px;font-size:18px}.bdlikebutton-large-orange .bdlikebutton-count{background-position:-272px -120px}.bdlikebutton-large-blue .bdlikebutton-count{background-position:-272px -170px}.bdlikebutton-large-green .bdlikebutton-count{background-position:-272px -220px}.bdlikebutton-large-red .bdlikebutton-count{background-position:-272px -270px}.bdlikebutton-large-orange-hover .bdlikebutton-count{background-position:-272px -720px}.bdlikebutton-large-blue-hover .bdlikebutton-count{background-position:-272px -770px}.bdlikebutton-large-green-hover .bdlikebutton-count{background-position:-272px -820px}.bdlikebutton-large-red-hover .bdlikebutton-count{background-position:-272px -870px}.bdlikebutton-medium .bdlikebutton-text{line-height:22px}.bdlikebutton-large{width:145px;height:60px}.bdlikebutton-large .bdlikebutton-text{line-height:22px;color:#a9a9a9}.bdlikebutton-large-orange-hover .bdlikebutton-text,.bdlikebutton-large-blue-hover .bdlikebutton-text,.bdlikebutton-large-green-hover .bdlikebutton-text,.bdlikebutton-large-red-hover .bdlikebutton-text{color:#FFF}.bdlikebutton-orange{color:#d25806}.bdlikebutton-blue{color:#2979d3}.bdlikebutton-green{color:#127b03}.bdlikebutton-red{color:#b50005}.bdlikebutton-small-orange{background-position:0 0}.bdlikebutton-small-blue{background-position:0 -30px}.bdlikebutton-small-green{background-position:0 -60px}.bdlikebutton-small-red{background-position:0 -90px}.bdlikebutton-medium-orange{background-position:0 -120px}.bdlikebutton-medium-blue{background-position:0 -175px}.bdlikebutton-medium-green{background-position:0 -230px}.bdlikebutton-medium-red{background-position:0 -285px}.bdlikebutton-large-orange{background-position:0 -340px}.bdlikebutton-large-blue{background-position:0 -405px}.bdlikebutton-large-green{background-position:0 -470px}.bdlikebutton-large-red{background-position:0 -535px}.bdlikebutton-small-orange-hover{background-position:-90px 0}.bdlikebutton-small-blue-hover{background-position:-90px -30px}.bdlikebutton-small-green-hover{background-position:-90px -60px}.bdlikebutton-small-red-hover{background-position:-90px -90px}.bdlikebutton-medium-orange-hover{background-position:-110px -120px;color:#FFF}.bdlikebutton-medium-blue-hover{background-position:-110px -175px;color:#FFF}.bdlikebutton-medium-green-hover{background-position:-110px -230px;color:#FFF}.bdlikebutton-medium-red-hover{background-position:-110px -285px;color:#FFF}.bdlikebutton-large-orange-hover{background-position:-150px -340px;color:#FFF}.bdlikebutton-large-blue-hover{background-position:-150px -405px;color:#FFF}.bdlikebutton-large-green-hover{background-position:-150px -470px;color:#FFF}.bdlikebutton-large-red-hover{background-position:-150px -535px;color:#FFF}.bdlikebutton .bdlikebutton-add{display:none;position:absolute;top:0;left:50%;z-index:10002;font-size:20px;font-weight:700}
    \ No newline at end of file
    diff --git a/source/static/api/css/select_share.css b/source/static/api/css/select_share.css
    deleted file mode 100644
    index de061abc..00000000
    --- a/source/static/api/css/select_share.css
    +++ /dev/null
    @@ -1 +0,0 @@
    -.bdselect_share_bg{position:absolute;display:none;z-index:9997}.bdselect_share_box .bdshare_arrow{position:absolute;margin:-4px 0 0;width:22px}.bdselect_share_box  .bdshare_arrow *{font-family:"SimSun";overflow:hidden;font-size:12px;line-height:1.231;display:block;height:12px}.bdshare_popup_box .S_line1_c{color:#e8daee}.bdshare_popup_box .S_bg4_c{color:#fafafa}.bdselect_share_box{position:absolute;display:none;z-index:9998;max-width:300px;border:solid 1px #f6f6f6;box-shadow:1px 4px 6px -2px #f6f6f6;-moz-box-shadow:1px 4px 6px -2px #f6f6f6;-webkit-box-shadow:1px 4px 6px -2px #f6f6f6}.bdselect_share_box .selectshare-mod-triangle{display:block;position:absolute;left:14px;top:-10px}.bdselect_share_box .selectshare-mod-triangle .triangle-border{border-color:transparent transparent #d9d9d9 transparent;left:0}.bdselect_share_box .selectshare-mod-triangle .triangle-border,.bdselect_share_box .selectshare-mod-triangle .triangle-inset{left:0;top:0;width:0;height:0;font-size:0;overflow:hidden;position:absolute;border-width:5px;border-style:dashed dashed solid dashed}.bdselect_share_box .selectshare-mod-triangle .triangle-inset{border-color:transparent transparent #f6f6f6 transparent}.bdselect_share_top{height:28px;color:#626262;overflow:hidden;font-weight:bold;font-size:14px;line-height:28px;padding:0 5px}.bdselect_share_list{margin:0;padding:10px;background:#fff;overflow:hidden;_zoom:1}.bdselect_share_top .bdselect_share_dialog_close{}.bdselect_share_triangle{display:block;position:relative;left:19px;top:-24px;z-index:20}.bdselect_share_triangle .bdselect_share_border,.bdselect_share_triangle .bdselect_share_inset{left:0;top:0;width:0;height:0;font-size:0;overflow:hidden;position:absolute;border-width:12px;border-style:dashed dashed solid dashed}.bdselect_share_triangle .bdselect_share_border{border-color:transparent transparent #fff transparent;bottom:-1px}.bdselect_share_triangle .bdselect_share_inset{border-color:transparent transparent #f6f6f6 transparent}.bdselect_share_head{width:100%;background:#f4f4f4;height:28px}.bdselect_share_head span{color:#626262;line-height:28px;margin-left:5px;font-weight:bold;font-size:12px}.bdselect_share_content{background:#fff}.bdselect_share_dialog_close{background:url("../img/share/selectshare_close.png?v=1b34ee88.png") no-repeat 0 0;width:12px;height:12px;position:absolute;top:8px;right:10px;display:block;text-decoration:none;cursor:pointer}.bdselect_share_dialog_search{position:absolute;top:0;right:30px;display:block;text-decoration:none;cursor:pointer;line-height:28px}.bdselect_share_dialog_search:hover{text-decoration:none}.bdselect_share_dialog_search_i{background:url(../img/share/share-search-icon.png) no-repeat 0 center;width:12px;height:28px;display:inline-block;vertical-align:top}.bdselect_share_dialog_search_span{display:inline-block;vertical-align:top}.bdselect_share_partners{float:left}
    \ No newline at end of file
    diff --git a/source/static/api/css/share_popup.css b/source/static/api/css/share_popup.css
    deleted file mode 100644
    index 74410946..00000000
    --- a/source/static/api/css/share_popup.css
    +++ /dev/null
    @@ -1 +0,0 @@
    -.bdshare_dialog_bg{position:fixed;_position:absolute;width:312px;height:341px;z-index:9999;overflow:hidden;display:none}.bdshare_dialog_box{position:fixed;_position:absolute;width:300px;border:6px solid #8F8F8F;height:329px;z-index:10000;text-align:left;box-shadow:0 0 7px #aaa;-webkit-box-shadow:0 0 7px #aaa;-moz-box-shadow:0 0 7px #aaa;border-radius:5px;-webkit-border-radius:5px;-moz-border-radius:5px;overflow:hidden;background:#f6f6f6;display:none}.bdshare_dialog_top,.bdshare_popup_top{height:28px;color:#626262;overflow:hidden;font-weight:bold;font-size:14px;line-height:28px;padding:0 5px}.bdshare_dialog_close{width:22px;height:23px;background:url(../img/share/pop_c.gif?v=2d7108c8.gif) no-repeat 0 0;float:right;display:block;margin-top:2px}.bdshare_dialog_list{margin:0;padding:10px 0;height:256px;background:#fff;overflow:auto;overflow-x:hidden}.bdshare_dialog_bottom{height:25px;line-height:25px;font-size:12px;text-align:right;padding:0 10px}.bdshare_dialog_bottom a{color:#999;text-decoration:none}.bdshare_dialog_bottom a:hover{color:#00a9e0}.bdshare_dialog_list li{float:left;width:130px;padding:2px;margin-left:6px;_margin-left:3px;height:28px;overflow:hidden;list-style:none}.bdshare_dialog_list a,.bdshare_popup_list a,.bdshare_popup_bottom a{color:#565656;font:12px '宋体';display:block;background-image:url(../img/share/icons_0_16.png?v=ba7acbd3.png);background-repeat:no-repeat;padding:5px 0 5px 28px;text-decoration:none;border:1px solid #fff;line-height:18px}.bdshare_dialog_list a:hover,.bdshare_popup_list a:hover{background-color:#f3f3f3;border:1px solid #eee;border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px}.popup_qzone{background-position:4px -47px}.popup_tsina{background-position:4px -99px}.popup_renren{background-position:4px -203px}.popup_tqq{background-position:4px -255px}.popup_kaixin001{background-position:4px -307px}.popup_tqf{background-position:4px -359px}.popup_hi{background-position:4px -411px}.popup_douban{background-position:4px -463px}.popup_tieba{background-position:4px -723px}.popup_hx{background-position:4px -983px}.popup_fx{background-position:4px -1035px}.popup_ty{background-position:4px -1191px}.popup_fbook{background-position:4px -1347px}.popup_twi{background-position:4px -1399px}.popup_linkedin{background-position:4px -1659px}.popup_meilishuo{background-position:4px -1711px}.popup_mogujie{background-position:4px -1763px}.popup_diandian{background-position:4px -1815px}.popup_huaban{background-position:4px -1867px}.popup_duitang{background-position:4px -2023px}.popup_youdao{background-position:4px -2075px}.popup_wealink{background-position:4px -2179px}.popup_copy{background-position:4px -2283px}.popup_mail{background-position:4px -2335px}.popup_print{background-position:4px -2387px}.popup_mshare{background-position:4px -2439px}.popup_sqq{background-position:4px -2647px}.popup_sdo{background-position:4px -2699px}.popup_qingbiji{background-position:4px -2751px}.popup_people{background-position:4px -2803px}.popup_xinhua{background-position:4px -2907px}.popup_yaolan{background-position:4px -2959px}.popup_thx{background-position:4px -2491px}.popup_bdhome{background-position:4px -151px}.popup_bdxc{background-position:4px -2543px}.popup_more{background-position:4px 5px}.popup_bdysc{background-position:4px -3063px}.popup_isohu{background-position:4px -3011px}.popup_ibaidu{background-position:4px -3115px}.popup_weixin{background-position:4px -1607px}.popup_iguba{background-position:4px -1295px}.popup_h163{background-position:4px -3156px}.bdshare_popup_bg{position:absolute;display:none;z-index:9997}.bdshare_popup_box{position:absolute;display:none;z-index:9998;text-align:left;background:#f6f6f6;border:solid 1px #e9e9e9}.bdshare_popup_list{margin:0;padding:5px 0;background:#fff;overflow:auto;overflow-x:hidden;_zoom:1}.bdshare_popup_bottom{clear:both;height:30px;font-size:12px;text-align:right;padding:0 10px}.bdshare_popup_bottom a{color:#999;text-decoration:none;border:0;float:right}.bdshare_popup_bottom a:hover{color:#00a9e0}.bdshare_popup_list li{float:left;width:100px;padding:2px;margin-left:6px;_margin-left:3px;height:28px;overflow:hidden;list-style:none}.popup_tsohu,.popup_tfh,.popup_baidu,.popup_qq,.popup_msn,.popup_sohu,.popup_qy,.popup_leho,.popup_ifeng,.popup_ff,.popup_tuita,.popup_ms,.popup_deli,.popup_s51,.popup_t163,.popup_share189,.popup_xg,.popup_s139{display:none}.bdshare_dialog_box,.bdshare_dialog_list a:hover,.bdshare_popup_list a:hover{-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;}.popup_evernotecn{background-position:4px -3180px;}
    \ No newline at end of file
    diff --git a/source/static/api/css/share_style0_16.css b/source/static/api/css/share_style0_16.css
    deleted file mode 100644
    index 3a4cd703..00000000
    --- a/source/static/api/css/share_style0_16.css
    +++ /dev/null
    @@ -1 +0,0 @@
    -.bdshare-button-style0-16 .bds_qzone{background-position:0 -52px}.bdshare-button-style0-16 .bds_tsina{background-position:0 -104px}.bdshare-button-style0-16 .bds_renren{background-position:0 -208px}.bdshare-button-style0-16 .bds_tqq{background-position:0 -260px}.bdshare-button-style0-16 .bds_kaixin001{background-position:0 -312px}.bdshare-button-style0-16 .bds_tqf{background-position:0 -364px}.bdshare-button-style0-16 .bds_hi{background-position:0 -416px}.bdshare-button-style0-16 .bds_douban{background-position:0 -468px}.bdshare-button-style0-16 .bds_tieba{background-position:0 -728px}.bdshare-button-style0-16 .bds_hx{background-position:0 -988px}.bdshare-button-style0-16 .bds_fx{background-position:0 -1040px}.bdshare-button-style0-16 .bds_ty{background-position:0 -1196px}.bdshare-button-style0-16 .bds_fbook{background-position:0 -1352px}.bdshare-button-style0-16 .bds_twi{background-position:0 -1404px}.bdshare-button-style0-16 .bds_linkedin{background-position:0 -1664px}.bdshare-button-style0-16 .bds_meilishuo{background-position:0 -1716px}.bdshare-button-style0-16 .bds_mogujie{background-position:0 -1768px}.bdshare-button-style0-16 .bds_diandian{background-position:0 -1820px}.bdshare-button-style0-16 .bds_huaban{background-position:0 -1872px}.bdshare-button-style0-16 .bds_duitang{background-position:0 -2028px}.bdshare-button-style0-16 .bds_youdao{background-position:0 -2080px}.bdshare-button-style0-16 .bds_wealink{background-position:0 -2184px}.bdshare-button-style0-16 .bds_copy{background-position:0 -2288px}.bdshare-button-style0-16 .bds_mail{background-position:0 -2340px}.bdshare-button-style0-16 .bds_print{background-position:0 -2392px}.bdshare-button-style0-16 .bds_mshare{background-position:0 -2444px}.bdshare-button-style0-16 .bds_sqq{background-position:0 -2652px}.bdshare-button-style0-16 .bds_sdo{background-position:0 -2704px}.bdshare-button-style0-16 .bds_qingbiji{background-position:0 -2756px}.bdshare-button-style0-16 .bds_people{background-position:0 -2808px}.bdshare-button-style0-16 .bds_xinhua{background-position:0 -2912px}.bdshare-button-style0-16 .bds_yaolan{background-position:0 -2964px}.bdshare-button-style0-16 .bds_thx{background-position:0 -2496px}.bdshare-button-style0-16 .bds_bdhome{background-position:0 -156px}.bdshare-button-style0-16 .bds_bdxc{background-position:0 -2548px}.bdshare-button-style0-16 .bds_bdysc{background-position:0 -3068px}.bdshare-button-style0-16 .bds_isohu{background-position:0 -3016px}.bdshare-button-style0-16 .bds_more{background-position:0 0}.bdshare-button-style0-16 .bds_ibaidu{background-position:0 -3120px}.bdshare-button-style0-16 .bds_weixin{background-position:0 -1612px}.bdshare-button-style0-16 .bds_iguba{background-position:0 -1300px}.bdshare-button-style0-16 .bds_h163{background-position:0 -3160px}.bdshare-button-style0-16{zoom:1}.bdshare-button-style0-16:after{content:".";visibility:hidden;display:block;height:0;clear:both}.bdshare-button-style0-16 a,.bdshare-button-style0-16 .bds_more{float:left;font-size:12px;padding-left:17px;line-height:16px;height:16px;background-image:url(../img/share/icons_0_16.png?v=ba7acbd3.png);background-repeat:no-repeat;cursor:pointer;margin:6px 6px 6px 0}.bdshare-button-style0-16 a:hover{color:#333;opacity:.8;filter:alpha(opacity=80)}.bdshare-button-style0-16 .bds_more{color:#333;float:left}.bdshare-button-style0-16 .bds_count{color:#333;background:url(../img/share/sc.png?v=a970ff04.png) no-repeat 0 -30px;width:42px;height:16px;padding:0;margin:6px 0 0;text-align:center}.bdshare-button-style0-16 .bds_count:hover{background-position:-42px -30px}.bdshare-button-style0-16 .bds_button_image{float:left;cursor:pointer;margin:6px 6px 0 0;height:auto;padding:0}.bdshare-button-style0-16 .bdshare_button_count{background:url(../img/share/sc.png?v=a970ff04.png) no-repeat 0 0;width:44px;height:24px;line-height:24px}.bdshare-button-style0-16 .bdshare_button_count:hover{background-position:-44px 0}.bds_tsohu,.bds_tfh,.bds_baidu,.bds_qq,.bds_msn,.bds_sohu,.bds_qy,.bds_leho,.bds_ifeng,.bds_ff,.bds_tuita,.bds_ms,.bds_deli,.bds_s51,.bds_t163,.bds_share189,.bds_xg,.bds_s139{display:none}.bds_evernotecn{background-position:0 -3184px}
    \ No newline at end of file
    diff --git a/source/static/api/css/share_style0_24.css b/source/static/api/css/share_style0_24.css
    deleted file mode 100644
    index 47afabfd..00000000
    --- a/source/static/api/css/share_style0_24.css
    +++ /dev/null
    @@ -1 +0,0 @@
    -.bdshare-button-style0-24 .bds_qzone{background-position:0 -52px}.bdshare-button-style0-24 .bds_tsina{background-position:0 -104px}.bdshare-button-style0-24 .bds_renren{background-position:0 -208px}.bdshare-button-style0-24 .bds_tqq{background-position:0 -260px}.bdshare-button-style0-24 .bds_kaixin001{background-position:0 -312px}.bdshare-button-style0-24 .bds_tqf{background-position:0 -364px}.bdshare-button-style0-24 .bds_hi{background-position:0 -416px}.bdshare-button-style0-24 .bds_douban{background-position:0 -468px}.bdshare-button-style0-24 .bds_tieba{background-position:0 -728px}.bdshare-button-style0-24 .bds_hx{background-position:0 -988px}.bdshare-button-style0-24 .bds_fx{background-position:0 -1040px}.bdshare-button-style0-24 .bds_ty{background-position:0 -1196px}.bdshare-button-style0-24 .bds_fbook{background-position:0 -1352px}.bdshare-button-style0-24 .bds_twi{background-position:0 -1404px}.bdshare-button-style0-24 .bds_linkedin{background-position:0 -1664px}.bdshare-button-style0-24 .bds_meilishuo{background-position:0 -1716px}.bdshare-button-style0-24 .bds_mogujie{background-position:0 -1768px}.bdshare-button-style0-24 .bds_diandian{background-position:0 -1820px}.bdshare-button-style0-24 .bds_huaban{background-position:0 -1872px}.bdshare-button-style0-24 .bds_duitang{background-position:0 -2028px}.bdshare-button-style0-24 .bds_youdao{background-position:0 -2080px}.bdshare-button-style0-24 .bds_wealink{background-position:0 -2184px}.bdshare-button-style0-24 .bds_copy{background-position:0 -2288px}.bdshare-button-style0-24 .bds_mail{background-position:0 -2340px}.bdshare-button-style0-24 .bds_print{background-position:0 -2392px}.bdshare-button-style0-24 .bds_mshare{background-position:0 -2444px}.bdshare-button-style0-24 .bds_sqq{background-position:0 -2652px}.bdshare-button-style0-24 .bds_sdo{background-position:0 -2704px}.bdshare-button-style0-24 .bds_qingbiji{background-position:0 -2756px}.bdshare-button-style0-24 .bds_people{background-position:0 -2808px}.bdshare-button-style0-24 .bds_xinhua{background-position:0 -2912px}.bdshare-button-style0-24 .bds_yaolan{background-position:0 -2964px}.bdshare-button-style0-24 .bds_thx{background-position:0 -2496px}.bdshare-button-style0-24 .bds_bdhome{background-position:0 -156px}.bdshare-button-style0-24 .bds_bdxc{background-position:0 -2548px}.bdshare-button-style0-24 .bds_bdysc{background-position:0 -3068px}.bdshare-button-style0-24 .bds_isohu{background-position:0 -3016px}.bdshare-button-style0-24 .bds_more{background-position:0 0}.bdshare-button-style0-24 .bds_ibaidu{background-position:0 -3120px}.bdshare-button-style0-24 .bds_weixin{background-position:0 -1612px}.bdshare-button-style0-24 .bds_iguba{background-position:0 -1300px}.bdshare-button-style0-24 .bds_h163{background-position:0 -3168px}.bdshare-button-style0-24 .bds_evernotecn{background-position:0 -3228px}.bdshare-button-style0-24{zoom:1}.bdshare-button-style0-24:after{content:".";visibility:hidden;display:block;height:0;clear:both}.bdshare-button-style0-24 a,.bdshare-button-style0-24 .bds_more{float:left;font-size:18px;padding-left:25px;line-height:24px;height:24px;background-image:url(../img/share/icons_0_24.png?v=dcaa92d6.png);background-repeat:no-repeat;cursor:pointer;margin:6px 6px 6px 0}.bdshare-button-style0-24 a:hover{color:#333;opacity:.8;filter:alpha(opacity=80)}.bdshare-button-style0-24 .bds_more{color:#333;float:left}.bdshare-button-style0-24 .bds_count{color:#333;background:url(../img/share/sc.png?v=a970ff04.png) no-repeat 0 0;width:45px;height:24px;padding:0;text-align:center;margin:6px 6px 0 0}.bdshare-button-style0-24 .bds_count:hover{background-position:-44px 0}.bds_tsohu,.bds_tfh,.bds_baidu,.bds_qq,.bds_msn,.bds_sohu,.bds_qy,.bds_leho,.bds_ifeng,.bds_ff,.bds_tuita,.bds_ms,.bds_deli,.bds_s51,.bds_t163,.bds_share189,.bds_xg,.bds_s139{display:none}
    \ No newline at end of file
    diff --git a/source/static/api/css/share_style0_32.css b/source/static/api/css/share_style0_32.css
    deleted file mode 100644
    index 59a851f0..00000000
    --- a/source/static/api/css/share_style0_32.css
    +++ /dev/null
    @@ -1 +0,0 @@
    -.bdshare-button-style0-32 .bds_qzone{background-position:0 -52px}.bdshare-button-style0-32 .bds_tsina{background-position:0 -104px}.bdshare-button-style0-32 .bds_renren{background-position:0 -208px}.bdshare-button-style0-32 .bds_tqq{background-position:0 -260px}.bdshare-button-style0-32 .bds_kaixin001{background-position:0 -312px}.bdshare-button-style0-32 .bds_tqf{background-position:0 -364px}.bdshare-button-style0-32 .bds_hi{background-position:0 -416px}.bdshare-button-style0-32 .bds_douban{background-position:0 -468px}.bdshare-button-style0-32 .bds_tieba{background-position:0 -728px}.bdshare-button-style0-32 .bds_hx{background-position:0 -988px}.bdshare-button-style0-32 .bds_fx{background-position:0 -1040px}.bdshare-button-style0-32 .bds_ty{background-position:0 -1196px}.bdshare-button-style0-32 .bds_fbook{background-position:0 -1352px}.bdshare-button-style0-32 .bds_twi{background-position:0 -1404px}.bdshare-button-style0-32 .bds_linkedin{background-position:0 -1664px}.bdshare-button-style0-32 .bds_meilishuo{background-position:0 -1716px}.bdshare-button-style0-32 .bds_mogujie{background-position:0 -1768px}.bdshare-button-style0-32 .bds_diandian{background-position:0 -1820px}.bdshare-button-style0-32 .bds_huaban{background-position:0 -1872px}.bdshare-button-style0-32 .bds_duitang{background-position:0 -2028px}.bdshare-button-style0-32 .bds_youdao{background-position:0 -2080px}.bdshare-button-style0-32 .bds_wealink{background-position:0 -2184px}.bdshare-button-style0-32 .bds_copy{background-position:0 -2288px}.bdshare-button-style0-32 .bds_mail{background-position:0 -2340px}.bdshare-button-style0-32 .bds_print{background-position:0 -2392px}.bdshare-button-style0-32 .bds_mshare{background-position:0 -2444px}.bdshare-button-style0-32 .bds_sqq{background-position:0 -2652px}.bdshare-button-style0-32 .bds_sdo{background-position:0 -2704px}.bdshare-button-style0-32 .bds_qingbiji{background-position:0 -2756px}.bdshare-button-style0-32 .bds_people{background-position:0 -2808px}.bdshare-button-style0-32 .bds_xinhua{background-position:0 -2912px}.bdshare-button-style0-32 .bds_yaolan{background-position:0 -2964px}.bdshare-button-style0-32 .bds_thx{background-position:0 -2496px}.bdshare-button-style0-32 .bds_bdhome{background-position:0 -156px}.bdshare-button-style0-32 .bds_bdxc{background-position:0 -2548px}.bdshare-button-style0-32 .bds_bdysc{background-position:0 -3068px}.bdshare-button-style0-32 .bds_isohu{background-position:0 -3016px}.bdshare-button-style0-32 .bds_ibaidu{background-position:0 -3120px}.bdshare-button-style0-32 .bds_weixin{background-position:0 -1612px}.bdshare-button-style0-32 .bds_iguba{background-position:0 -1300px}.bdshare-button-style0-32 .bds_h163{background-position:0 -3176px}.bdshare-button-style0-32{zoom:1}.bdshare-button-style0-32:after{content:".";visibility:hidden;display:block;height:0;clear:both}.bdshare-button-style0-32 a{float:left;width:32px;line-height:32px;height:32px;background-image:url(../img/share/icons_0_32.png?v=dc944784.png);background-repeat:no-repeat;cursor:pointer;margin:6px 6px 6px 0;text-indent:-100em;overflow:hidden;color:#3a8ceb}.bdshare-button-style0-32 a:hover{color:#333;opacity:.8;filter:alpha(opacity=80)}.bdshare-button-style0-32 .bds_more{color:#333}.bdshare-button-style0-32 .bds_count{color:#333;background:url(../img/share/sc.png?v=a970ff04.png) no-repeat 0 -60px;width:48px;height:32px;line-height:32px;padding:0;text-align:center;text-indent:0}.bdshare-button-style0-32 .bds_count:hover{background-position:-48px -60px}.bds_tsohu,.bds_tfh,.bds_baidu,.bds_qq,.bds_msn,.bds_sohu,.bds_qy,.bds_leho,.bds_ifeng,.bds_ff,.bds_tuita,.bds_ms,.bds_deli,.bds_s51,.bds_t163,.bds_share189,.bds_xg,.bds_s139{display:none}
    \ No newline at end of file
    diff --git a/source/static/api/css/share_style1_16.css b/source/static/api/css/share_style1_16.css
    deleted file mode 100644
    index 1fd30be1..00000000
    --- a/source/static/api/css/share_style1_16.css
    +++ /dev/null
    @@ -1 +0,0 @@
    -.bdshare-button-style1-16 .bds_qzone{background-position:0 -52px}.bdshare-button-style1-16 .bds_tsina{background-position:0 -104px}.bdshare-button-style1-16 .bds_renren{background-position:0 -208px}.bdshare-button-style1-16 .bds_tqq{background-position:0 -260px}.bdshare-button-style1-16 .bds_kaixin001{background-position:0 -312px}.bdshare-button-style1-16 .bds_tqf{background-position:0 -364px}.bdshare-button-style1-16 .bds_hi{background-position:0 -416px}.bdshare-button-style1-16 .bds_douban{background-position:0 -468px}.bdshare-button-style1-16 .bds_tieba{background-position:0 -728px}.bdshare-button-style1-16 .bds_hx{background-position:0 -988px}.bdshare-button-style1-16 .bds_fx{background-position:0 -1040px}.bdshare-button-style1-16 .bds_ty{background-position:0 -1196px}.bdshare-button-style1-16 .bds_fbook{background-position:0 -1352px}.bdshare-button-style1-16 .bds_twi{background-position:0 -1404px}.bdshare-button-style1-16 .bds_linkedin{background-position:0 -1664px}.bdshare-button-style1-16 .bds_meilishuo{background-position:0 -1716px}.bdshare-button-style1-16 .bds_mogujie{background-position:0 -1768px}.bdshare-button-style1-16 .bds_diandian{background-position:0 -1820px}.bdshare-button-style1-16 .bds_huaban{background-position:0 -1872px}.bdshare-button-style1-16 .bds_duitang{background-position:0 -2028px}.bdshare-button-style1-16 .bds_youdao{background-position:0 -2080px}.bdshare-button-style1-16 .bds_wealink{background-position:0 -2184px}.bdshare-button-style1-16 .bds_copy{background-position:0 -2288px}.bdshare-button-style1-16 .bds_mail{background-position:0 -2340px}.bdshare-button-style1-16 .bds_print{background-position:0 -2392px}.bdshare-button-style1-16 .bds_mshare{background-position:0 -2444px}.bdshare-button-style1-16 .bds_sqq{background-position:0 -2652px}.bdshare-button-style1-16 .bds_sdo{background-position:0 -2704px}.bdshare-button-style1-16 .bds_qingbiji{background-position:0 -2756px}.bdshare-button-style1-16 .bds_people{background-position:0 -2808px}.bdshare-button-style1-16 .bds_xinhua{background-position:0 -2912px}.bdshare-button-style1-16 .bds_yaolan{background-position:0 -2964px}.bdshare-button-style1-16 .bds_thx{background-position:0 -2496px}.bdshare-button-style1-16 .bds_bdhome{background-position:0 -156px}.bdshare-button-style1-16 .bds_bdxc{background-position:0 -2548px}.bdshare-button-style1-16 .bds_bdysc{background-position:0 -3068px}.bdshare-button-style1-16 .bds_isohu{background-position:0 -3016px}.bdshare-button-style1-16 .bds_more{background-position:0 0}.bdshare-button-style1-16 .bds_ibaidu{background-position:0 -3120px}.bdshare-button-style1-16 .bds_weixin{background-position:0 -1612px}.bdshare-button-style1-16 .bds_iguba{background-position:0 -1300px}.bdshare-button-style1-16 .bds_h163{background-position:0 -3160px}.bdshare-button-style1-16 .bds_evernotecn{background-position:0 -3195px}.bdshare-button-style1-16{zoom:1}.bdshare-button-style1-16:after{content:".";visibility:hidden;display:block;height:0;clear:both}.bdshare-button-style1-16 a,.bdshare-button-style1-16 .bds_more{float:left;font-size:12px;padding-left:17px;line-height:16px;height:16px;background-image:url(../img/share/icons_1_16.png?v=774cfc30.png);_background-image:url(../img/share/icons_1_16_debase.png?v=a2277903.png);background-repeat:no-repeat;cursor:pointer;margin:6px 6px 6px 0}.bdshare-button-style1-16 a:hover{color:#333;opacity:.8;filter:alpha(opacity=80)}.bdshare-button-style1-16 .bds_more{color:#333;float:left}.bdshare-button-style1-16 .bds_count{color:#333;background:url(../img/share/sc.png?v=a970ff04.png) no-repeat 0 -30px;width:42px;height:16px;padding:0;margin:6px 0 0;text-align:center}.bdshare-button-style1-16 .bds_count:hover{background-position:-42px -30px}.bdshare-button-style1-16 .bds_button_image{float:left;cursor:pointer;margin:6px 6px 0 0;height:auto;padding:0}.bdshare-button-style1-16 .bdshare_button_count{background:url(../img/share/sc.png?v=a970ff04.png) no-repeat 0 0;width:44px;height:24px;line-height:24px}.bdshare-button-style1-16 .bdshare_button_count:hover{background-position:-44px 0}.bds_tsohu,.bds_tfh,.bds_baidu,.bds_qq,.bds_msn,.bds_sohu,.bds_qy,.bds_leho,.bds_ifeng,.bds_ff,.bds_tuita,.bds_ms,.bds_deli,.bds_s51,.bds_t163,.bds_share189,.bds_xg,.bds_s139{display:none}
    \ No newline at end of file
    diff --git a/source/static/api/css/share_style1_24.css b/source/static/api/css/share_style1_24.css
    deleted file mode 100644
    index 1c4f8028..00000000
    --- a/source/static/api/css/share_style1_24.css
    +++ /dev/null
    @@ -1 +0,0 @@
    -.bdshare-button-style1-24 .bds_qzone{background-position:0 -52px}.bdshare-button-style1-24 .bds_tsina{background-position:0 -104px}.bdshare-button-style1-24 .bds_renren{background-position:0 -208px}.bdshare-button-style1-24 .bds_tqq{background-position:0 -260px}.bdshare-button-style1-24 .bds_kaixin001{background-position:0 -312px}.bdshare-button-style1-24 .bds_tqf{background-position:0 -364px}.bdshare-button-style1-24 .bds_hi{background-position:0 -416px}.bdshare-button-style1-24 .bds_douban{background-position:0 -468px}.bdshare-button-style1-24 .bds_tieba{background-position:0 -728px}.bdshare-button-style1-24 .bds_hx{background-position:0 -988px}.bdshare-button-style1-24 .bds_fx{background-position:0 -1040px}.bdshare-button-style1-24 .bds_ty{background-position:0 -1196px}.bdshare-button-style1-24 .bds_fbook{background-position:0 -1352px}.bdshare-button-style1-24 .bds_twi{background-position:0 -1404px}.bdshare-button-style1-24 .bds_linkedin{background-position:0 -1664px}.bdshare-button-style1-24 .bds_meilishuo{background-position:0 -1716px}.bdshare-button-style1-24 .bds_mogujie{background-position:0 -1768px}.bdshare-button-style1-24 .bds_diandian{background-position:0 -1820px}.bdshare-button-style1-24 .bds_huaban{background-position:0 -1872px}.bdshare-button-style1-24 .bds_duitang{background-position:0 -2028px}.bdshare-button-style1-24 .bds_youdao{background-position:0 -2080px}.bdshare-button-style1-24 .bds_wealink{background-position:0 -2184px}.bdshare-button-style1-24 .bds_copy{background-position:0 -2288px}.bdshare-button-style1-24 .bds_mail{background-position:0 -2340px}.bdshare-button-style1-24 .bds_print{background-position:0 -2392px}.bdshare-button-style1-24 .bds_mshare{background-position:0 -2444px}.bdshare-button-style1-24 .bds_sqq{background-position:0 -2652px}.bdshare-button-style1-24 .bds_sdo{background-position:0 -2704px}.bdshare-button-style1-24 .bds_qingbiji{background-position:0 -2756px}.bdshare-button-style1-24 .bds_people{background-position:0 -2808px}.bdshare-button-style1-24 .bds_xinhua{background-position:0 -2912px}.bdshare-button-style1-24 .bds_yaolan{background-position:0 -2964px}.bdshare-button-style1-24 .bds_thx{background-position:0 -2496px}.bdshare-button-style1-24 .bds_bdhome{background-position:0 -156px}.bdshare-button-style1-24 .bds_bdxc{background-position:0 -2548px}.bdshare-button-style1-24 .bds_bdysc{background-position:0 -3068px}.bdshare-button-style1-24 .bds_isohu{background-position:0 -3016px}.bdshare-button-style1-24 .bds_more{background-position:0 0}.bdshare-button-style1-24 .bds_ibaidu{background-position:0 -3120px}.bdshare-button-style1-24 .bds_weixin{background-position:0 -1612px}.bdshare-button-style1-24 .bds_iguba{background-position:0 -1300px}.bdshare-button-style1-24 .bds_h163{background-position:0 -3168px}.bdshare-button-style1-24 .bds_evernotecn{background-position:0 -3211px}.bdshare-button-style1-24{zoom:1}.bdshare-button-style1-24:after{content:".";visibility:hidden;display:block;height:0;clear:both}.bdshare-button-style1-24 a,.bdshare-button-style1-24 .bds_more{float:left;font-size:18px;padding-left:25px;line-height:24px;height:24px;background-image:url(../img/share/icons_1_24.png?v=37be22f4.png);_background-image:url(../img/share/icons_1_24_debase.png?v=37be22f4.png);background-repeat:no-repeat;cursor:pointer;margin:6px 6px 6px 0}.bdshare-button-style1-24 a:hover{color:#333;opacity:.8;filter:alpha(opacity=80)}.bdshare-button-style1-24 .bds_more{color:#333;float:left}.bdshare-button-style1-24 .bds_count{color:#333;background:url(../img/share/sc.png?v=a970ff04.png) no-repeat 0 0;width:45px;height:24px;padding:0;margin:6px 0 0;text-align:center}.bdshare-button-style1-24 .bds_count:hover{background-position:-44px 0}.bdshare-button-style1-24 .bds_button_image{float:left;cursor:pointer;margin:6px 6px 0 0;height:auto;padding:0}.bdshare-button-style1-24 .bdshare_button_count{background:url(../img/share/sc.png?v=a970ff04.png) no-repeat 0 0;width:44px;height:24px;line-height:24px}.bdshare-button-style1-24 .bdshare_button_count:hover{background-position:-44px 0}.bds_tsohu,.bds_tfh,.bds_baidu,.bds_qq,.bds_msn,.bds_sohu,.bds_qy,.bds_leho,.bds_ifeng,.bds_ff,.bds_tuita,.bds_ms,.bds_deli,.bds_s51,.bds_t163,.bds_share189,.bds_xg,.bds_s139{display:none}
    \ No newline at end of file
    diff --git a/source/static/api/css/share_style1_32.css b/source/static/api/css/share_style1_32.css
    deleted file mode 100644
    index 3b1380be..00000000
    --- a/source/static/api/css/share_style1_32.css
    +++ /dev/null
    @@ -1 +0,0 @@
    -.bdshare-button-style1-32 .bds_qzone{background-position:0 -52px}.bdshare-button-style1-32 .bds_tsina{background-position:0 -104px}.bdshare-button-style1-32 .bds_renren{background-position:0 -208px}.bdshare-button-style1-32 .bds_tqq{background-position:0 -260px}.bdshare-button-style1-32 .bds_kaixin001{background-position:0 -312px}.bdshare-button-style1-32 .bds_tqf{background-position:0 -364px}.bdshare-button-style1-32 .bds_hi{background-position:0 -416px}.bdshare-button-style1-32 .bds_douban{background-position:0 -468px}.bdshare-button-style1-32 .bds_tieba{background-position:0 -728px}.bdshare-button-style1-32 .bds_hx{background-position:0 -988px}.bdshare-button-style1-32 .bds_fx{background-position:0 -1040px}.bdshare-button-style1-32 .bds_ty{background-position:0 -1196px}.bdshare-button-style1-32 .bds_fbook{background-position:0 -1352px}.bdshare-button-style1-32 .bds_twi{background-position:0 -1404px}.bdshare-button-style1-32 .bds_linkedin{background-position:0 -1664px}.bdshare-button-style1-32 .bds_meilishuo{background-position:0 -1716px}.bdshare-button-style1-32 .bds_mogujie{background-position:0 -1768px}.bdshare-button-style1-32 .bds_diandian{background-position:0 -1820px}.bdshare-button-style1-32 .bds_huaban{background-position:0 -1872px}.bdshare-button-style1-32 .bds_duitang{background-position:0 -2028px}.bdshare-button-style1-32 .bds_youdao{background-position:0 -2080px}.bdshare-button-style1-32 .bds_wealink{background-position:0 -2184px}.bdshare-button-style1-32 .bds_copy{background-position:0 -2288px}.bdshare-button-style1-32 .bds_mail{background-position:0 -2340px}.bdshare-button-style1-32 .bds_print{background-position:0 -2392px}.bdshare-button-style1-32 .bds_mshare{background-position:0 -2444px}.bdshare-button-style1-32 .bds_sqq{background-position:0 -2652px}.bdshare-button-style1-32 .bds_sdo{background-position:0 -2704px}.bdshare-button-style1-32 .bds_qingbiji{background-position:0 -2756px}.bdshare-button-style1-32 .bds_people{background-position:0 -2808px}.bdshare-button-style1-32 .bds_xinhua{background-position:0 -2912px}.bdshare-button-style1-32 .bds_yaolan{background-position:0 -2964px}.bdshare-button-style1-32 .bds_thx{background-position:0 -2496px}.bdshare-button-style1-32 .bds_bdhome{background-position:0 -156px}.bdshare-button-style1-32 .bds_bdxc{background-position:0 -2548px}.bdshare-button-style1-32 .bds_bdysc{background-position:0 -3068px}.bdshare-button-style1-32 .bds_isohu{background-position:0 -3016px}.bdshare-button-style1-32 .bds_ibaidu{background-position:0 -3120px}.bdshare-button-style1-32 .bds_weixin{background-position:0 -1612px}.bdshare-button-style1-32 .bds_iguba{background-position:0 -1300px}.bdshare-button-style1-32 .bds_h163{background-position:0 -3176px}.bdshare-button-style1-32 .bds_evernotecn{background-position:0 -3222px}.bdshare-button-style1-32{zoom:1}.bdshare-button-style1-32:after{content:".";visibility:hidden;display:block;height:0;clear:both}.bdshare-button-style1-32 a{float:left;width:32px;line-height:32px;height:32px;background-image:url(../img/share/icons_1_32.png?v=83ba0265.png);_background-image:url(../img/share/icons_1_32_debase.png?v=0de29fb2.png);background-repeat:no-repeat;cursor:pointer;margin:6px 6px 6px 0;text-indent:-100em;overflow:hidden;color:#3a8ceb}.bdshare-button-style1-32 a:hover{color:#333;opacity:.8;filter:alpha(opacity=80)}.bdshare-button-style1-32 .bds_more{color:#333}.bdshare-button-style1-32 .bds_count{color:#333;background:url(../img/share/sc.png?v=a970ff04.png) no-repeat 0 -60px;width:48px;height:32px;line-height:32px;padding:0;text-align:center;text-indent:0}.bdshare-button-style1-32 .bds_count:hover{background-position:-48px -60px}.bds_tsohu,.bds_tfh,.bds_baidu,.bds_qq,.bds_msn,.bds_sohu,.bds_qy,.bds_leho,.bds_ifeng,.bds_ff,.bds_tuita,.bds_ms,.bds_deli,.bds_s51,.bds_t163,.bds_share189,.bds_xg,.bds_s139{display:none}
    \ No newline at end of file
    diff --git a/source/static/api/css/share_style2.css b/source/static/api/css/share_style2.css
    deleted file mode 100644
    index 06397c4c..00000000
    --- a/source/static/api/css/share_style2.css
    +++ /dev/null
    @@ -1 +0,0 @@
    -.bds_qzone{background-position:0 -52px}.bds_tsina{background-position:0 -104px}.bds_renren{background-position:0 -208px}.bds_tqq{background-position:0 -260px}.bds_kaixin001{background-position:0 -312px}.bds_tqf{background-position:0 -364px}.bds_hi{background-position:0 -416px}.bds_douban{background-position:0 -468px}.bds_tieba{background-position:0 -728px}.bds_hx{background-position:0 -988px}.bds_fx{background-position:0 -1040px}.bds_ty{background-position:0 -1196px}.bds_fbook{background-position:0 -1352px}.bds_twi{background-position:0 -1404px}.bds_linkedin{background-position:0 -1664px}.bds_meilishuo{background-position:0 -1716px}.bds_mogujie{background-position:0 -1768px}.bds_diandian{background-position:0 -1820px}.bds_huaban{background-position:0 -1872px}.bds_duitang{background-position:0 -2028px}.bds_youdao{background-position:0 -2080px}.bds_wealink{background-position:0 -2184px}.bds_copy{background-position:0 -2287px}.bds_mail{background-position:0 -2339px}.bds_print{background-position:0 -2391px}.bds_mshare{background-position:0 -2443px}.bds_sqq{background-position:0 -2651px}.bds_sdo{background-position:0 -2703px}.bds_qingbiji{background-position:0 -2755px}.bds_people{background-position:0 -2807px}.bds_xinhua{background-position:0 -2911px}.bds_yaolan{background-position:0 -2963px}.bds_thx{background-position:0 -2495px}.bds_bdhome{background-position:0 -156px}.bds_bdxc{background-position:0 -2547px}.bds_h163{background-position:0 -2990px}.bdshare-button-style2{zoom:1;padding:5px 0}.bdshare-button-style2:after{content:".";visibility:hidden;display:block;height:0;clear:both}.bdshare-button-style2 a{float:left;font-size:12px;padding-left:17px;line-height:16px;height:16px;background-image:url(../img/share/icons_2.png?v=cd8d5d1e.png);background-repeat:no-repeat;cursor:pointer;margin-right:3px;color:#3a8ceb}.bdshare-button-style2 a:hover{color:#333}.bdshare-button-style2 .bds_more{color:#333}.bdshare-button-style2 .bds_count{color:#333;background:url(../img/share/sc.png?v=a970ff04.png) no-repeat 0 -30px;width:42px;height:16px;padding:0;text-align:center}.bdshare-button-style2 .bds_count:hover{background-position:-42px -30px}.bds_tsohu..bds_tfh,.bds_baidu,.bds_qq,.bds_msn,.bds_sohu,.bds_qy,.bds_leho,.bds_ifeng,.bds_ff,.bds_tuita,.bds_ms,.bds_deli,.bds_s51,.bds_t163,.bds_share189,.bds_xg,.bds_s139{display:none}
    \ No newline at end of file
    diff --git a/source/static/api/css/share_style2_16.css b/source/static/api/css/share_style2_16.css
    deleted file mode 100644
    index 42e843e8..00000000
    --- a/source/static/api/css/share_style2_16.css
    +++ /dev/null
    @@ -1 +0,0 @@
    -.bdshare-button-style2-16 .bds_qzone{background-position:0 -52px}.bdshare-button-style2-16 .bds_tsina{background-position:0 -104px}.bdshare-button-style2-16 .bds_renren{background-position:0 -208px}.bdshare-button-style2-16 .bds_tqq{background-position:0 -260px}.bdshare-button-style2-16 .bds_kaixin001{background-position:0 -312px}.bdshare-button-style2-16 .bds_tqf{background-position:0 -364px}.bdshare-button-style2-16 .bds_hi{background-position:0 -416px}.bdshare-button-style2-16 .bds_douban{background-position:0 -468px}.bdshare-button-style2-16 .bds_tieba{background-position:0 -728px}.bdshare-button-style2-16 .bds_hx{background-position:0 -988px}.bdshare-button-style2-16 .bds_fx{background-position:0 -1040px}.bdshare-button-style2-16 .bds_ty{background-position:0 -1196px}.bdshare-button-style2-16 .bds_fbook{background-position:0 -1352px}.bdshare-button-style2-16 .bds_twi{background-position:0 -1404px}.bdshare-button-style2-16 .bds_linkedin{background-position:0 -1664px}.bdshare-button-style2-16 .bds_meilishuo{background-position:0 -1716px}.bdshare-button-style2-16 .bds_mogujie{background-position:0 -1768px}.bdshare-button-style2-16 .bds_diandian{background-position:0 -1820px}.bdshare-button-style2-16 .bds_huaban{background-position:0 -1872px}.bdshare-button-style2-16 .bds_duitang{background-position:0 -2028px}.bdshare-button-style2-16 .bds_youdao{background-position:0 -2080px}.bdshare-button-style2-16 .bds_wealink{background-position:0 -2184px}.bdshare-button-style2-16 .bds_copy{background-position:0 -2288px}.bdshare-button-style2-16 .bds_mail{background-position:0 -2340px}.bdshare-button-style2-16 .bds_print{background-position:0 -2392px}.bdshare-button-style2-16 .bds_mshare{background-position:0 -2444px}.bdshare-button-style2-16 .bds_sqq{background-position:0 -2652px}.bdshare-button-style2-16 .bds_sdo{background-position:0 -2704px}.bdshare-button-style2-16 .bds_qingbiji{background-position:0 -2756px}.bdshare-button-style2-16 .bds_people{background-position:0 -2808px}.bdshare-button-style2-16 .bds_xinhua{background-position:0 -2912px}.bdshare-button-style2-16 .bds_yaolan{background-position:0 -2964px}.bdshare-button-style2-16 .bds_thx{background-position:0 -2496px}.bdshare-button-style2-16 .bds_bdhome{background-position:0 -156px}.bdshare-button-style2-16 .bds_bdxc{background-position:0 -2548px}.bdshare-button-style2-16 .bds_bdysc{background-position:0 -3068px}.bdshare-button-style2-16 .bds_isohu{background-position:0 -3016px}.bdshare-button-style2-16 .bds_more{background-position:0 0}.bdshare-button-style2-16 .bds_ibaidu{background-position:0 -3120px}.bdshare-button-style2-16 .bds_weixin{background-position:0 -1612px}.bdshare-button-style2-16 .bds_iguba{background-position:0 -1300px}.bdshare-button-style2-16 .bds_h163{background-position:0 -3156px}.bdshare-button-style2-16 .bds_evernotecn{background-position:0 -3192px}.bdshare-button-style2-16{zoom:1}.bdshare-button-style2-16:after{content:".";visibility:hidden;display:block;height:0;clear:both}.bdshare-button-style2-16 a,.bdshare-button-style2-16 .bds_more{float:left;font-size:12px;padding-left:17px;line-height:16px;height:16px;background-image:url(../img/share/icons_2_16.png?v=81508962.png);_background-image:url(../img/share/icons_2_16_debase.png?v=43bedd85.png);background-repeat:no-repeat;cursor:pointer;margin:6px 6px 6px 0;color:#999}.bdshare-button-style2-16 a:hover{color:#333;opacity:.8;filter:alpha(opacity=80)}.bdshare-button-style2-16 .bds_more{color:#333;float:left}.bdshare-button-style2-16 .bds_count{color:#333;background:url(../img/share/sc.png?v=a970ff04.png) no-repeat 0 -30px;width:42px;height:16px;padding:0;margin:6px 0 0;text-align:center}.bdshare-button-style2-16 .bds_count:hover{background-position:-42px -30px}.bdshare-button-style2-16 .bds_button_image{float:left;cursor:pointer;margin:6px 6px 0 0;height:auto;padding:0}.bdshare-button-style2-16 .bdshare_button_count{background:url(../img/share/sc.png?v=a970ff04.png) no-repeat 0 0;width:44px;height:24px;line-height:24px}.bdshare-button-style2-16 .bdshare_button_count:hover{background-position:-44px 0}.bds_tsohu,.bds_tfh,.bds_baidu,.bds_qq,.bds_msn,.bds_sohu,.bds_qy,.bds_leho,.bds_ifeng,.bds_ff,.bds_tuita,.bds_ms,.bds_deli,.bds_s51,.bds_t163,.bds_share189,.bds_xg,.bds_s139{display:none}
    \ No newline at end of file
    diff --git a/source/static/api/css/share_style2_24.css b/source/static/api/css/share_style2_24.css
    deleted file mode 100644
    index 60da95b2..00000000
    --- a/source/static/api/css/share_style2_24.css
    +++ /dev/null
    @@ -1 +0,0 @@
    -.bdshare-button-style2-24 .bds_qzone{background-position:0 -52px}.bdshare-button-style2-24 .bds_tsina{background-position:0 -104px}.bdshare-button-style2-24 .bds_renren{background-position:0 -208px}.bdshare-button-style2-24 .bds_tqq{background-position:0 -260px}.bdshare-button-style2-24 .bds_kaixin001{background-position:0 -312px}.bdshare-button-style2-24 .bds_tqf{background-position:0 -364px}.bdshare-button-style2-24 .bds_hi{background-position:0 -416px}.bdshare-button-style2-24 .bds_douban{background-position:0 -468px}.bdshare-button-style2-24 .bds_tieba{background-position:0 -728px}.bdshare-button-style2-24 .bds_hx{background-position:0 -988px}.bdshare-button-style2-24 .bds_fx{background-position:0 -1040px}.bdshare-button-style2-24 .bds_ty{background-position:0 -1196px}.bdshare-button-style2-24 .bds_fbook{background-position:0 -1352px}.bdshare-button-style2-24 .bds_twi{background-position:0 -1404px}.bdshare-button-style2-24 .bds_linkedin{background-position:0 -1664px}.bdshare-button-style2-24 .bds_meilishuo{background-position:0 -1716px}.bdshare-button-style2-24 .bds_mogujie{background-position:0 -1768px}.bdshare-button-style2-24 .bds_diandian{background-position:0 -1820px}.bdshare-button-style2-24 .bds_huaban{background-position:0 -1872px}.bdshare-button-style2-24 .bds_duitang{background-position:0 -2028px}.bdshare-button-style2-24 .bds_youdao{background-position:0 -2080px}.bdshare-button-style2-24 .bds_wealink{background-position:0 -2184px}.bdshare-button-style2-24 .bds_copy{background-position:0 -2288px}.bdshare-button-style2-24 .bds_mail{background-position:0 -2340px}.bdshare-button-style2-24 .bds_print{background-position:0 -2392px}.bdshare-button-style2-24 .bds_mshare{background-position:0 -2444px}.bdshare-button-style2-24 .bds_sqq{background-position:0 -2652px}.bdshare-button-style2-24 .bds_sdo{background-position:0 -2704px}.bdshare-button-style2-24 .bds_qingbiji{background-position:0 -2756px}.bdshare-button-style2-24 .bds_people{background-position:0 -2808px}.bdshare-button-style2-24 .bds_xinhua{background-position:0 -2912px}.bdshare-button-style2-24 .bds_yaolan{background-position:0 -2964px}.bdshare-button-style2-24 .bds_thx{background-position:0 -2496px}.bdshare-button-style2-24 .bds_bdhome{background-position:0 -156px}.bdshare-button-style2-24 .bds_bdxc{background-position:0 -2548px}.bdshare-button-style2-24 .bds_bdysc{background-position:0 -3068px}.bdshare-button-style2-24 .bds_isohu{background-position:0 -3016px}.bdshare-button-style2-24 .bds_more{background-position:0 0}.bdshare-button-style2-24 .bds_ibaidu{background-position:0 -3120px}.bdshare-button-style2-24 .bds_weixin{background-position:0 -1612px}.bdshare-button-style2-24 .bds_iguba{background-position:0 -1300px}.bdshare-button-style2-24 .bds_h163{background-position:0 -3168px}.bdshare-button-style2-24 .bds_evernotecn{background-position:0 -3214px}.bdshare-button-style2-24{zoom:1}.bdshare-button-style2-24:after{content:".";visibility:hidden;display:block;height:0;clear:both}.bdshare-button-style2-24 a,.bdshare-button-style2-24 .bds_more{float:left;font-size:18px;padding-left:25px;line-height:24px;height:24px;background-image:url(../img/share/icons_2_24.png?v=a64ca404.png);_background-image:url(../img/share/icons_2_24_debase.png?v=7dd3ca7f.png);background-repeat:no-repeat;cursor:pointer;margin:6px 6px 6px 0;color:#999}.bdshare-button-style2-24 a:hover{color:#333;opacity:.8;filter:alpha(opacity=80)}.bdshare-button-style2-24 .bds_more{color:#333;float:left}.bdshare-button-style2-24 .bds_count{color:#333;background:url(../img/share/sc.png?v=a970ff04.png) no-repeat 0 0;width:45px;height:24px;padding:0;margin:6px 0 0;text-align:center}.bdshare-button-style2-24 .bds_count:hover{background-position:-44px 0}.bdshare-button-style2-24 .bds_button_image{float:left;cursor:pointer;margin:6px 6px 0 0;height:auto;padding:0}.bdshare-button-style2-24 .bdshare_button_count{background:url(../img/share/sc.png?v=a970ff04.png) no-repeat 0 0;width:44px;height:24px;line-height:24px}.bdshare-button-style2-24 .bdshare_button_count:hover{background-position:-44px 0}.bds_tsohu,.bds_tfh,.bds_baidu,.bds_qq,.bds_msn,.bds_sohu,.bds_qy,.bds_leho,.bds_ifeng,.bds_ff,.bds_tuita,.bds_ms,.bds_deli,.bds_s51,.bds_t163,.bds_share189,.bds_xg,.bds_s139{display:none}
    \ No newline at end of file
    diff --git a/source/static/api/css/share_style2_32.css b/source/static/api/css/share_style2_32.css
    deleted file mode 100644
    index 4ed9fd29..00000000
    --- a/source/static/api/css/share_style2_32.css
    +++ /dev/null
    @@ -1 +0,0 @@
    -.bdshare-button-style2-32 .bds_qzone{background-position:0 -52px}.bdshare-button-style2-32 .bds_tsina{background-position:0 -104px}.bdshare-button-style2-32 .bds_renren{background-position:0 -208px}.bdshare-button-style2-32 .bds_tqq{background-position:0 -260px}.bdshare-button-style2-32 .bds_kaixin001{background-position:0 -312px}.bdshare-button-style2-32 .bds_tqf{background-position:0 -364px}.bdshare-button-style2-32 .bds_hi{background-position:0 -416px}.bdshare-button-style2-32 .bds_douban{background-position:0 -468px}.bdshare-button-style2-32 .bds_tieba{background-position:0 -728px}.bdshare-button-style2-32 .bds_hx{background-position:0 -988px}.bdshare-button-style2-32 .bds_fx{background-position:0 -1040px}.bdshare-button-style2-32 .bds_ty{background-position:0 -1196px}.bdshare-button-style2-32 .bds_fbook{background-position:0 -1352px}.bdshare-button-style2-32 .bds_twi{background-position:0 -1404px}.bdshare-button-style2-32 .bds_linkedin{background-position:0 -1664px}.bdshare-button-style2-32 .bds_meilishuo{background-position:0 -1716px}.bdshare-button-style2-32 .bds_mogujie{background-position:0 -1768px}.bdshare-button-style2-32 .bds_diandian{background-position:0 -1820px}.bdshare-button-style2-32 .bds_huaban{background-position:0 -1872px}.bdshare-button-style2-32 .bds_duitang{background-position:0 -2028px}.bdshare-button-style2-32 .bds_youdao{background-position:0 -2080px}.bdshare-button-style2-32 .bds_wealink{background-position:0 -2184px}.bdshare-button-style2-32 .bds_copy{background-position:0 -2288px}.bdshare-button-style2-32 .bds_mail{background-position:0 -2340px}.bdshare-button-style2-32 .bds_print{background-position:0 -2392px}.bdshare-button-style2-32 .bds_mshare{background-position:0 -2444px}.bdshare-button-style2-32 .bds_sqq{background-position:0 -2652px}.bdshare-button-style2-32 .bds_sdo{background-position:0 -2704px}.bdshare-button-style2-32 .bds_qingbiji{background-position:0 -2756px}.bdshare-button-style2-32 .bds_people{background-position:0 -2808px}.bdshare-button-style2-32 .bds_xinhua{background-position:0 -2912px}.bdshare-button-style2-32 .bds_yaolan{background-position:0 -2964px}.bdshare-button-style2-32 .bds_thx{background-position:0 -2496px}.bdshare-button-style2-32 .bds_bdhome{background-position:0 -156px}.bdshare-button-style2-32 .bds_bdxc{background-position:0 -2548px}.bdshare-button-style2-32 .bds_bdysc{background-position:0 -3068px}.bdshare-button-style2-32 .bds_isohu{background-position:0 -3016px}.bdshare-button-style2-32 .bds_ibaidu{background-position:0 -3120px}.bdshare-button-style2-32 .bds_weixin{background-position:0 -1612px}.bdshare-button-style2-32 .bds_iguba{background-position:0 -1300px}.bdshare-button-style2-32 .h163{background-position:0 -3176px}.bdshare-button-style2-32 .bds_evernotecn{background-position:0 -3229px}.bdshare-button-style2-32{zoom:1}.bdshare-button-style2-32:after{content:".";visibility:hidden;display:block;height:0;clear:both}.bdshare-button-style2-32 a{float:left;width:32px;line-height:32px;height:32px;background-image:url(../img/share/icons_2_32.png?v=1bc5c881.png);_background-image:url(../img/share/icons_2_32_debase.png?v=11466d62.png);background-repeat:no-repeat;cursor:pointer;margin:6px 6px 6px 0;text-indent:-100em;overflow:hidden;color:#999}.bdshare-button-style2-32 a:hover{color:#333;opacity:.8;filter:alpha(opacity=80)}.bdshare-button-style2-32 .bds_more{color:#333}.bdshare-button-style2-32 .bds_count{color:#333;background:url(../img/share/sc.png?v=a970ff04.png) no-repeat 0 -60px;width:48px;height:32px;line-height:32px;padding:0;text-align:center;text-indent:0}.bdshare-button-style2-32 .bds_count:hover{background-position:-48px -60px}.bds_tsohu,.bds_tfh,.bds_baidu,.bds_qq,.bds_msn,.bds_sohu,.bds_qy,.bds_leho,.bds_ifeng,.bds_ff,.bds_tuita,.bds_ms,.bds_deli,.bds_s51,.bds_t163,.bds_share189,.bds_xg,.bds_s139{display:none}
    \ No newline at end of file
    diff --git a/source/static/api/css/share_style4.css b/source/static/api/css/share_style4.css
    deleted file mode 100644
    index 0bbdd2fb..00000000
    --- a/source/static/api/css/share_style4.css
    +++ /dev/null
    @@ -1 +0,0 @@
    -.bds_qzone{background-position:0 -52px}.bds_tsina{background-position:0 -104px}.bds_renren{background-position:0 -208px}.bds_tqq{background-position:0 -260px}.bds_kaixin001{background-position:0 -312px}.bds_tqf{background-position:0 -364px}.bds_hi{background-position:0 -416px}.bds_douban{background-position:0 -468px}.bds_tieba{background-position:0 -728px}.bds_hx{background-position:0 -988px}.bds_fx{background-position:0 -1040px}.bds_ty{background-position:0 -1196px}.bds_fbook{background-position:0 -1352px}.bds_twi{background-position:0 -1404px}.bds_zx{background-position:0 -1612px}.bds_linkedin{background-position:0 -1664px}.bds_meilishuo{background-position:0 -1716px}.bds_mogujie{background-position:0 -1768px}.bds_diandian{background-position:0 -1820px}.bds_huaban{background-position:0 -1872px}.bds_duitang{background-position:0 -2028px}.bds_youdao{background-position:0 -2080px}.bds_wealink{background-position:0 -2184px}.bds_copy{background-position:0 -2287px}.bds_mail{background-position:0 -2339px}.bds_print{background-position:0 -2391px}.bds_mshare{background-position:0 -2443px}.bds_sqq{background-position:0 -2651px}.bds_sdo{background-position:0 -2703px}.bds_qingbiji{background-position:0 -2755px}.bds_people{background-position:0 -2807px}.bds_xinhua{background-position:0 -2911px}.bds_yaolan{background-position:0 -2963px}.bds_thx{background-position:0 -2495px}.bds_bdhome{background-position:0 -156px}.bds_bdxc{background-position:0 -2547px}.bds_h163{background-position:0 -2469px}.bdshare-button-style4{zoom:1;padding:5px 0}.bdshare-button-style4:after{content:".";visibility:hidden;display:block;height:0;clear:both}.bdshare-button-style4 a{float:left;font-size:12px;padding-left:17px;line-height:16px;height:16px;background-image:url(../img/share/icons_4.png?v=eec1b34e.png);background-repeat:no-repeat;cursor:pointer;margin:6px 6px 0 0;color:#3a8ceb}.bdshare-button-style4 a:hover{color:#333}.bdshare-button-style4 .bds_more{color:#333}.bdshare-button-style4 .bds_count{color:#333;background:url(../img/share/sc.png?v=a970ff04.png) no-repeat 0 -30px;width:42px;height:16px;padding:0;text-align:center}.bdshare-button-style4 .bds_count:hover{background-position:-42px -30px}.bds_tsohu,.bds_tfh,.bds_baidu,.bds_qq,.bds_msn,.bds_sohu,.bds_qy,.bds_leho,.bds_ifeng,.bds_ff,.bds_tuita,.bds_ms,.bds_deli,.bds_s51,.bds_t163,.bds_share189,.bds_xg,.bds_s139{display:none}
    \ No newline at end of file
    diff --git a/source/static/api/css/slide_share.css b/source/static/api/css/slide_share.css
    deleted file mode 100644
    index 34394f2b..00000000
    --- a/source/static/api/css/slide_share.css
    +++ /dev/null
    @@ -1 +0,0 @@
    -.bdshare-slide-button-box{height:326px;position:fixed;overflow:visible}.bdshare-slide-button-box .bdshare-slide-button{width:24px;height:88px;display:block;position:absolute;top:58px}.bdshare-slide-style-r0 .bdshare-slide-button{background:url(../img/share/r0.gif?v=d9371706.gif) no-repeat 0 0}.bdshare-slide-style-r1 .bdshare-slide-button{background:url(../img/share/r1.gif?v=5668db67.gif) no-repeat 0 0}.bdshare-slide-style-r2 .bdshare-slide-button{background:url(../img/share/r2.gif?v=08b06973.gif) no-repeat 0 0}.bdshare-slide-style-r3 .bdshare-slide-button{background:url(../img/share/r3.gif?v=76e62e61.gif) no-repeat 0 0}.bdshare-slide-style-r4 .bdshare-slide-button{background:url(../img/share/r4.gif?v=1a3eaae1.gif) no-repeat 0 0}.bdshare-slide-style-r5 .bdshare-slide-button{background:url(../img/share/r5.gif?v=c90e5a12.gif) no-repeat 0 0}.bdshare-slide-style-r6 .bdshare-slide-button{background:url(../img/share/r6.gif?v=8af9306f.gif) no-repeat 0 0}.bdshare-slide-style-r7 .bdshare-slide-button{background:url(../img/share/r7.gif?v=053cdaac.gif) no-repeat 0 0}.bdshare-slide-style-r8 .bdshare-slide-button{background:url(../img/share/r8.gif?v=640a093b.gif) no-repeat 0 0}.bdshare-slide-style-l0 .bdshare-slide-button{background:url(../img/share/l0.gif?v=4e666e56.gif) no-repeat 0 0}.bdshare-slide-style-l1 .bdshare-slide-button{background:url(../img/share/l1.gif?v=3ffb4640.gif) no-repeat 0 0}.bdshare-slide-style-l2 .bdshare-slide-button{background:url(../img/share/l2.gif?v=47242a70.gif) no-repeat 0 0}.bdshare-slide-style-l3 .bdshare-slide-button{background:url(../img/share/l3.gif?v=78e2d043.gif) no-repeat 0 0}.bdshare-slide-style-l4 .bdshare-slide-button{background:url(../img/share/l4.gif?v=4afa38d2.gif) no-repeat 0 0}.bdshare-slide-style-l5 .bdshare-slide-button{background:url(../img/share/l5.gif?v=5e170970.gif) no-repeat 0 0}.bdshare-slide-style-l6 .bdshare-slide-button{background:url(../img/share/l6.gif?v=8759da8b.gif) no-repeat 0 0}.bdshare-slide-style-l7 .bdshare-slide-button{background:url(../img/share/l7.gif?v=df4c2738.gif) no-repeat 0 0}.bdshare-slide-style-l8 .bdshare-slide-button{background:url(../img/share/l8.gif?v=31ac73d4.gif) no-repeat 0 0}.bdshare-slide-list-box{border:solid 1px #e9e9e9;text-align:left;overflow:hidden;background:#f6f6f6}.bdshare-slide-top{height:28px;color:#626262;overflow:hidden;font-weight:bold;font-size:14px;line-height:28px;padding:0 5px}.bdshare-slide-list{background:#fff;overflow:auto;overflow-x:hidden;padding:5px 0;margin:0;background:#fff;overflow:auto;overflow-x:hidden;_zoom:1}.bdshare-slide-list-ul{padding:0;margin:0;border:0;list-style:none}.bdshare-slide-bottom{line-height:25px;font-size:12px;text-align:right;clear:both;height:30px}.bdshare-slide-bottom a{color:#999;text-decoration:none;border:0;float:right}.bdshare-slide-bottom a:hover{color:#00a9e0}.bdshare-slide-list li{float:left;padding:2px;margin-left:6px;_margin-left:3px;height:28px;overflow:hidden;list-style:none;width:100px}.bdshare-slide-list a,.bdshare-slide-bottom a{color:#565656;font:12px '宋体';display:block;background-image:url(../img/share/icons_0_16.png?v=91362611.png);background-repeat:no-repeat;padding:5px 0 5px 28px;text-decoration:none;border:1px solid #fff;line-height:18px}.bdshare-slide-list a:hover{background-color:#f3f3f3;border:1px solid #eee;border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px}.slide-qzone{background-position:4px -47px}.slide-tsina{background-position:4px -99px}.slide-renren{background-position:4px -203px}.slide-tqq{background-position:4px -255px}.slide-kaixin001{background-position:4px -307px}.slide-tqf{background-position:4px -359px}.slide-hi{background-position:4px -411px}.slide-douban{background-position:4px -463px}.slide-tieba{background-position:4px -723px}.slide-hx{background-position:4px -983px}.slide-fx{background-position:4px -1035px}.slide-ty{background-position:4px -1191px}.slide-fbook{background-position:4px -1347px}.slide-twi{background-position:4px -1399px}.slide-zx{background-position:4px -1607px}.slide-linkedin{background-position:4px -1659px}.slide-meilishuo{background-position:4px -1711px}.slide-mogujie{background-position:4px -1763px}.slide-diandian{background-position:4px -1815px}.slide-huaban{background-position:4px -1867px}.slide-duitang{background-position:4px -2023px}.slide-youdao{background-position:4px -2075px}.slide-wealink{background-position:4px -2179px}.slide-copy{background-position:4px -2283px}.slide-mail{background-position:4px -2335px}.slide-print{background-position:4px -2387px}.slide-mshare{background-position:4px -2439px}.slide-sqq{background-position:4px -2647px}.slide-sdo{background-position:4px -2699px}.slide-qingbiji{background-position:4px -2751px}.slide-people{background-position:4px -2803px}.slide-xinhua{background-position:4px -2907px}.slide-yaolan{background-position:4px -2959px}.slide-thx{background-position:4px -2491px}.slide-bdhome{background-position:4px -151px}.slide-bdxc{background-position:4px -2543px}.slide-bdysc{background-position:4px -3063px}.slide-isohu{background-position:4px -3011px}.slide-more{background-position:4px 5px}.slide-ibaidu{background-position:4px -3115px}.slide-weixin{background-position:4px -1607px}.slide-iguba{background-position:4px -1295px}.slide-evernotecn{background-position:4px -3179px}.bdshare-slide-bottom .slide-more{border:none;margin-right:10px}.slide-tsohu,.slide-tfh,.slide-baidu,.slide-qq,.slide-msn,.slide-sohu,.slide-qy,.slide-leho,.slide-ifeng,.slide-ff,.slide-tuita,.slide-ms,.slide-deli,.slide-s51,.slide-t163,.slide-share189,.slide-xg,.slide-s139{display:none}.bdshare-slide-list a:hover{-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box}
    \ No newline at end of file
    diff --git a/source/static/api/css/weixin_popup.css b/source/static/api/css/weixin_popup.css
    deleted file mode 100644
    index 334e9e5d..00000000
    --- a/source/static/api/css/weixin_popup.css
    +++ /dev/null
    @@ -1 +0,0 @@
    -.bd_weixin_popup_bg{position:absolute;left:-400px;top:-400px;width:260px;height:320px;border:0;padding:0;margin:0;opacity:0;filter:alpha(opacity=0);z-index:11000}.bd_weixin_popup{position:absolute;left:-400px;top:-400px;padding:10px;width:280px !important;height:340px !important;background:#fff;border:solid 1px #d8d8d8;z-index:11001;font-size:12px}.bd_weixin_popup .bd_weixin_popup_head{font-size:12px;font-weight:bold;text-align:left;line-height:16px;height:16px;position:relative;color:#000}.bd_weixin_popup .bd_weixin_popup_head .bd_weixin_popup_close{width:16px;height:16px;position:absolute;right:0;top:0;color:#999;text-decoration:none;font-size:16px}.bd_weixin_popup .bd_weixin_popup_head .bd_weixin_popup_close:hover{text-decoration:none}.bd_weixin_popup .bd_weixin_popup_main{padding:15px 10px;min-height:150px;_height:150px}.bd_weixin_popup .bd_weixin_popup_foot{font-size:12px;text-align:left;line-height:22px;color:#666}
    \ No newline at end of file
    diff --git a/source/static/api/img/share/icons_0_16.png b/source/static/api/img/share/icons_0_16.png
    deleted file mode 100644
    index 960adc73..00000000
    Binary files a/source/static/api/img/share/icons_0_16.png and /dev/null differ
    diff --git a/source/static/api/img/share/icons_0_24.png b/source/static/api/img/share/icons_0_24.png
    deleted file mode 100644
    index 7a495f54..00000000
    Binary files a/source/static/api/img/share/icons_0_24.png and /dev/null differ
    diff --git a/source/static/api/img/share/icons_0_32.png b/source/static/api/img/share/icons_0_32.png
    deleted file mode 100644
    index 5560ccb3..00000000
    Binary files a/source/static/api/img/share/icons_0_32.png and /dev/null differ
    diff --git a/source/static/api/img/share/icons_1_16.png b/source/static/api/img/share/icons_1_16.png
    deleted file mode 100644
    index 69775f80..00000000
    Binary files a/source/static/api/img/share/icons_1_16.png and /dev/null differ
    diff --git a/source/static/api/img/share/icons_1_24.png b/source/static/api/img/share/icons_1_24.png
    deleted file mode 100644
    index 61aed71c..00000000
    Binary files a/source/static/api/img/share/icons_1_24.png and /dev/null differ
    diff --git a/source/static/api/img/share/icons_1_32.png b/source/static/api/img/share/icons_1_32.png
    deleted file mode 100644
    index b8f86a9f..00000000
    Binary files a/source/static/api/img/share/icons_1_32.png and /dev/null differ
    diff --git a/source/static/api/img/share/icons_2_16.png b/source/static/api/img/share/icons_2_16.png
    deleted file mode 100644
    index 6f656da6..00000000
    Binary files a/source/static/api/img/share/icons_2_16.png and /dev/null differ
    diff --git a/source/static/api/img/share/icons_2_24.png b/source/static/api/img/share/icons_2_24.png
    deleted file mode 100644
    index 4045e17f..00000000
    Binary files a/source/static/api/img/share/icons_2_24.png and /dev/null differ
    diff --git a/source/static/api/img/share/icons_2_32.png b/source/static/api/img/share/icons_2_32.png
    deleted file mode 100644
    index d5f47c18..00000000
    Binary files a/source/static/api/img/share/icons_2_32.png and /dev/null differ
    diff --git a/source/static/api/img/share/l0.gif b/source/static/api/img/share/l0.gif
    deleted file mode 100644
    index a40515dd..00000000
    Binary files a/source/static/api/img/share/l0.gif and /dev/null differ
    diff --git a/source/static/api/img/share/l1.gif b/source/static/api/img/share/l1.gif
    deleted file mode 100644
    index bd3b258f..00000000
    Binary files a/source/static/api/img/share/l1.gif and /dev/null differ
    diff --git a/source/static/api/img/share/l2.gif b/source/static/api/img/share/l2.gif
    deleted file mode 100644
    index 4e4e98f0..00000000
    Binary files a/source/static/api/img/share/l2.gif and /dev/null differ
    diff --git a/source/static/api/img/share/l3.gif b/source/static/api/img/share/l3.gif
    deleted file mode 100644
    index 2f1827bd..00000000
    Binary files a/source/static/api/img/share/l3.gif and /dev/null differ
    diff --git a/source/static/api/img/share/l4.gif b/source/static/api/img/share/l4.gif
    deleted file mode 100644
    index 37208aeb..00000000
    Binary files a/source/static/api/img/share/l4.gif and /dev/null differ
    diff --git a/source/static/api/img/share/l5.gif b/source/static/api/img/share/l5.gif
    deleted file mode 100644
    index 0e8b4474..00000000
    Binary files a/source/static/api/img/share/l5.gif and /dev/null differ
    diff --git a/source/static/api/img/share/l6.gif b/source/static/api/img/share/l6.gif
    deleted file mode 100644
    index c904f285..00000000
    Binary files a/source/static/api/img/share/l6.gif and /dev/null differ
    diff --git a/source/static/api/img/share/l7.gif b/source/static/api/img/share/l7.gif
    deleted file mode 100644
    index 7f27eb00..00000000
    Binary files a/source/static/api/img/share/l7.gif and /dev/null differ
    diff --git a/source/static/api/img/share/l8.gif b/source/static/api/img/share/l8.gif
    deleted file mode 100644
    index d51f0679..00000000
    Binary files a/source/static/api/img/share/l8.gif and /dev/null differ
    diff --git a/source/static/api/img/share/pop_c.gif b/source/static/api/img/share/pop_c.gif
    deleted file mode 100644
    index 692e30e4..00000000
    Binary files a/source/static/api/img/share/pop_c.gif and /dev/null differ
    diff --git a/source/static/api/img/share/r0.gif b/source/static/api/img/share/r0.gif
    deleted file mode 100644
    index 3839907c..00000000
    Binary files a/source/static/api/img/share/r0.gif and /dev/null differ
    diff --git a/source/static/api/img/share/r1.gif b/source/static/api/img/share/r1.gif
    deleted file mode 100644
    index d91c7b8c..00000000
    Binary files a/source/static/api/img/share/r1.gif and /dev/null differ
    diff --git a/source/static/api/img/share/r2.gif b/source/static/api/img/share/r2.gif
    deleted file mode 100644
    index c58331e1..00000000
    Binary files a/source/static/api/img/share/r2.gif and /dev/null differ
    diff --git a/source/static/api/img/share/r3.gif b/source/static/api/img/share/r3.gif
    deleted file mode 100644
    index ea02bc66..00000000
    Binary files a/source/static/api/img/share/r3.gif and /dev/null differ
    diff --git a/source/static/api/img/share/r4.gif b/source/static/api/img/share/r4.gif
    deleted file mode 100644
    index cafadf19..00000000
    Binary files a/source/static/api/img/share/r4.gif and /dev/null differ
    diff --git a/source/static/api/img/share/r5.gif b/source/static/api/img/share/r5.gif
    deleted file mode 100644
    index bbd62d3f..00000000
    Binary files a/source/static/api/img/share/r5.gif and /dev/null differ
    diff --git a/source/static/api/img/share/r6.gif b/source/static/api/img/share/r6.gif
    deleted file mode 100644
    index 8947d8a2..00000000
    Binary files a/source/static/api/img/share/r6.gif and /dev/null differ
    diff --git a/source/static/api/img/share/r7.gif b/source/static/api/img/share/r7.gif
    deleted file mode 100644
    index 299f0c08..00000000
    Binary files a/source/static/api/img/share/r7.gif and /dev/null differ
    diff --git a/source/static/api/img/share/r8.gif b/source/static/api/img/share/r8.gif
    deleted file mode 100644
    index a65841f2..00000000
    Binary files a/source/static/api/img/share/r8.gif and /dev/null differ
    diff --git a/source/static/api/img/share/sc.png b/source/static/api/img/share/sc.png
    deleted file mode 100644
    index 581a0454..00000000
    Binary files a/source/static/api/img/share/sc.png and /dev/null differ
    diff --git a/source/static/api/img/share/selectshare_close.png b/source/static/api/img/share/selectshare_close.png
    deleted file mode 100644
    index e15121d6..00000000
    Binary files a/source/static/api/img/share/selectshare_close.png and /dev/null differ
    diff --git a/source/static/api/img/share/share-search-icon.png b/source/static/api/img/share/share-search-icon.png
    deleted file mode 100644
    index 8d42ac55..00000000
    Binary files a/source/static/api/img/share/share-search-icon.png and /dev/null differ
    diff --git a/source/static/api/js/base/class.js b/source/static/api/js/base/class.js
    deleted file mode 100644
    index d2f1e3a3..00000000
    --- a/source/static/api/js/base/class.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -!window._bd_share_is_recently_loaded&&window._bd_share_main.F.module("base/class",function(e,t,n){var r=e("base/min_tangram").T;t.BaseClass=function(){var e=this,t={};e.on=function(e,n){var r=t[e];r||(r=t[e]=[]),r.push(n)},e.un=function(e,n){if(!e){t={};return}var i=t[e];i&&(n?r.each(i,function(e,t){if(t==n)return i.splice(e,1),!1}):t[e]=[])},e.fire=function(n,i){var s=t[n];s&&(i=i||{},r.each(s,function(t,n){i._result=n.call(e,r.extend({_ctx:{src:e}},i))}))}};var i={};i.create=function(e,n){return n=n||t.BaseClass,function(){n.apply(this,arguments);var i=r.extend({},this);e.apply(this,arguments),this._super=i}},t.Class=i});
    \ No newline at end of file
    diff --git a/source/static/api/js/base/tangram.js b/source/static/api/js/base/tangram.js
    deleted file mode 100644
    index c918a18a..00000000
    --- a/source/static/api/js/base/tangram.js
    +++ /dev/null
    @@ -1,4 +0,0 @@
    -window._bd_share_main.F.module("base/tangram",function(e,t){var n,r=n=function(){var e,t=e=t||function(e,n){return t.dom?t.dom(e,n):null};t.version="2.0.2.5",t.guid="$BAIDU$",t.key="tangram_guid";var n=window[t.guid]=window[t.guid]||{};return(n.versions||(n.versions=[])).push(t.version),t.check=t.check||function(){},t.lang=t.lang||{},t.forEach=function(e,t,n){var r,i,s;if(typeof t=="function"&&e){i=typeof e.length=="number"?e.length:e.byteLength;if(typeof i=="number"){if(Object.prototype.toString.call(e)==="[object Function]")return e;for(r=0;r<i;r++)s=e[r],s===undefined&&(s=e.charAt&&e.charAt(r)),t.call(n||null,s,r,e)}else if(typeof e=="number")for(r=0;r<e;r++)t.call(n||null,r,r,r);else if(typeof e=="object")for(r in e)e.hasOwnProperty(r)&&t.call(n||null,e[r],r,e)}return e},t.type=function(){var e={},n=[,"HTMLElement","Attribute","Text",,,,,"Comment","Document",,"DocumentFragment"],r="Array Boolean Date Error Function Number RegExp String",i={object:1,"function":"1"},s=e.toString;return t.forEach(r.split(" "),function(n){e["[object "+n+"]"]=n.toLowerCase(),t["is"+n]=function(e){return t.type(e)==n.toLowerCase()}}),function(t){var r=typeof t;return i[r]?t==null?"null":t._type_||e[s.call(t)]||n[t.nodeType]||(t==t.window?"Window":"")||"object":r}}(),t.isDate=function(e){return t.type(e)=="date"&&e.toString()!="Invalid Date"&&!isNaN(e)},t.isElement=function(e){return t.type(e)=="HTMLElement"},t.isEnumerable=function(e){return e!=null&&(typeof e=="object"||~Object.prototype.toString.call(e).indexOf("NodeList"))&&(typeof e.length=="number"||typeof e.byteLength=="number"||typeof e[0]!="undefined")},t.isNumber=function(e){return t.type(e)=="number"&&isFinite(e)},t.isPlainObject=function(e){var n,r=Object.prototype.hasOwnProperty;if(t.type(e)!="object")return!1;if(e.constructor&&!r.call(e,"constructor")&&!r.call(e.constructor.prototype,"isPrototypeOf"))return!1;for(n in e);return n===undefined||r.call(e,n)},t.isObject=function(e){return typeof e=="function"||typeof e=="object"&&e!=null},t.extend=function(e,n){var r,i,s,o,u,a=1,f=arguments.length,l=e||{},c,h;t.isBoolean(e)&&(a=2)&&(l=n||{}),!t.isObject(l)&&(l={});for(;a<f;a++){i=arguments[a];if(t.isObject(i))for(s in i){o=l[s],u=i[s];if(o===u)continue;t.isBoolean(e)&&e&&u&&(t.isPlainObject(u)||(c=t.isArray(u)))?(c?(c=!1,h=o&&t.isArray(o)?o:[]):h=o&&t.isPlainObject(o)?o:{},l[s]=t.extend(e,h,u)):u!==undefined&&(l[s]=u)}}return l},t.createChain=function(e,n,r){var i=e=="dom"?"$DOM":"$"+e.charAt(0).toUpperCase()+e.substr(1),s=Array.prototype.slice,o=t[e];return o?o:(o=t[e]=n||function(n){return t.extend(n,t[e].fn)},o.extend=function(n){var r;for(r in n)(function(n){n!="splice"&&(o[n]=function(){var r=arguments[0];e=="dom"&&t.type(r)=="string"&&(r="#"+r);var i=o(r),u=i[n].apply(i,s.call(arguments,1));return t.type(u)=="$DOM"?u.get(0):u})})(r);return t.extend(t[e].fn,n)},t[e][i]=t[e][i]||r||function(){},o.fn=t[e][i].prototype,o)},t.overwrite=function(e,t,n){for(var r=t.length-1;r>-1;r--)e.prototype[t[r]]=n(t[r]);return e},t.object=t.object||{},t.object.isPlain=t.isPlainObject,t.createChain("string",function(e){var n=t.type(e),r=new String(~"string|number".indexOf(n)?e:n),i=String.prototype;return t.forEach(t.string.$String.prototype,function(e,t){i[t]||(r[t]=e)}),r}),t.string.extend({trim:function(){var e=new RegExp("(^[\\s\\t\\xa0\\u3000]+)|([\\u3000\\xa0\\s\\t]+$)","g");return function(){return this.replace(e,"")}}()}),t.createChain("array",function(e){var n=t.array.$Array.prototype,r=Array.prototype,i;t.type(e)!="array"&&(e=[]);for(i in n)e[i]=n[i];return e}),t.overwrite(t.array.$Array,"concat slice".split(" "),function(e){return function(){return t.array(Array.prototype[e].apply(this,arguments))}}),t.array.extend({indexOf:function(e,n){t.check(".+(,number)?","baidu.array.indexOf");var r=this.length;(n|=0)<0&&(n=Math.max(0,r+n));for(;n<r;n++)if(n in this&&this[n]===e)return n;return-1}}),t.createChain("Callbacks",function(e){var n=e;return t.type(e)==="string"&&(n={},t.forEach(e.split(/\s/),function(e){n[e]=!0})),new t.Callbacks.$Callbacks(n)},function(e){var n=t.extend({},e||{}),r=[],i=[],s=0,o,u,a,f,l=function(e,t){var u,l;if(!i||!r)return;o=n.memory&&e,a=!0,i.push(e);if(f)return;f=!0;while(u=i.shift())for(s=t||0;l=r[s];s++)if(l.apply(u[0],u[1])===!1&&n.stopOnFalse){o=!1;break}f=!1,n.once&&(r=[])},c={add:function(){if(!r)return this;var e=r&&r.length;return function i(e){var s=e.length,o,u;for(var a=0,u;a<s;a++){if(!(u=e[a]))continue;o=t.type(u),o==="function"?(!n.unique||!c.has(u))&&r.push(u):u&&u.length&&o!=="string"&&i(u)}}(arguments),!f&&o&&l(o,e),this},remove:function(){if(!r)return this;var e;return t.forEach(arguments,function(n){while((e=t.array(r).indexOf(n))>-1)r.splice(e,1),f&&e<s&&s--}),this},has:function(e){return t.array(r).indexOf(e)>-1},empty:function(){return r=[],this},disable:function(){return r=i=o=undefined,this},disabled:function(){return!r},lock:function(){return u=!0,!o&&c.disable(),this},fired:function(){return a},fireWith:function(e,t){return a&&n.once||u?this:(t=t||[],t=[e,t.slice?t.slice():t],l(t),this)},fire:function(){return c.fireWith(this,arguments),this}};return c}),t.createChain("Deferred",function(e){return new t.Deferred.$Deferred(e)},function(e){var n=this,r="pending",i=[["resolve","done",t.Callbacks("once memory"),"resolved"],["reject","fail",t.Callbacks("once memory"),"rejected"],["notify","progress",t.Callbacks("memory")]],s={state:function(){return r},always:function(){return n.done(arguments).fail(arguments),this},then:function(){var e=arguments;return t.Deferred(function(r){t.forEach(i,function(i,s){var o=i[0],u=e[s];n[i[1]](t.type(u)==="function"?function(){var e=u.apply(this,arguments);e&&t.type(e.promise)==="function"?e.promise().done(r.resolve).fail(r.reject).progress(r.notify):r[o+"With"](this===n?r:this,[e])}:r[o])})}).promise()},promise:function(e){return e!=null?t.extend(e,s):s}};s.pipe=s.then,t.forEach(i,function(e,t){var o=e[2],u=e[3];s[e[1]]=o.add,u&&o.add(function(){r=u},i[t^1][2].disable,i[2][2].lock),n[e[0]]=o.fire,n[e[0]+"With"]=o.fireWith}),s.promise(n),e&&e.call(n,n)}),t.when=t.when||function(e){function f(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?arguments:r,n===o?s.notifyWith(t,n):--i||s.resolveWith(t,n)}}var n=arguments,r=arguments.length,i=r!==1||e&&t.type(e.promise)==="function"?r:0,s=i===1?e:t.Deferred(),o,u,a;if(r>1){o=new Array(r),u=new Array(r),a=new Array(r);for(var l=0;l<r;l++)n[l]&&t.type(n[l].promise)==="function"?n[l].promise().done(f(l,a,n)).fail(s.reject).progress(f(l,u,o)):--i}return!i&&s.resolveWith(a,n),s.promise()},t.global=t.global||function(){var e=t._global_=window[t.guid],n=e._=e._||{};return function(e,t,r){return typeof t!="undefined"?(r||(t=typeof n[e]=="undefined"?t:n[e]),n[e]=t):e&&typeof n[e]=="undefined"&&(n[e]={}),n[e]}}(),t.browser=t.browser||function(){var e=navigator.userAgent,n={isStrict:document.compatMode=="CSS1Compat",isGecko:/gecko/i.test(e)&&!/like gecko/i.test(e),isWebkit:/webkit/i.test(e)};try{/(\d+\.\d+)/.test(external.max_version)&&(n.maxthon=+RegExp.$1)}catch(r){}switch(!0){case/msie (\d+\.\d+)/i.test(e):n.ie=document.documentMode||+RegExp.$1;break;case/chrome\/(\d+\.\d+)/i.test(e):n.chrome=+RegExp.$1;break;case/(\d+\.\d)?(?:\.\d)?\s+safari\/?(\d+\.\d+)?/i.test(e)&&!/chrome/i.test(e):n.safari=+(RegExp.$1||RegExp.$2);break;case/firefox\/(\d+\.\d+)/i.test(e):n.firefox=+RegExp.$1;break;case/opera(?:\/| )(\d+(?:\.\d+)?)(.+?(version\/(\d+(?:\.\d+)?)))?/i.test(e):n.opera=+(RegExp.$4||RegExp.$1)}return t.extend(t,n),n}(),t.id=function(){var e=t.global("_maps_id"),n=t.key;return window[t.guid]._counter=window[t.guid]._counter||1,function(r,i){var s,o=t.isString(r),u=t.isObject(r),a=u?r[n]:o?r:"";if(t.isString(i))switch(i){case"get":return u?a:e[a];case"remove":case"delete":if(s=e[a])t.isElement(s)&&t.browser.ie<8?s.removeAttribute(n):delete s[n],delete e[a];return a;default:return o?((s=e[a])&&delete e[a],s&&(e[s[n]=i]=s)):u&&(a&&delete e[a],e[r[n]=i]=r),i}return u?(!a&&(e[r[n]=a=t.id()]=r),a):o?e[r]:"TANGRAM_"+t._global_._counter++}}(),t._util_=t._util_||{},t._util_.support=t._util_.support||function(){var e=document.createElement("div"),t,n,r,i,s;return e.setAttribute("className","t"),e.innerHTML=' <link/><table></table><a href="/a">a</a><input type="checkbox"/>',n=e.getElementsByTagName("A")[0],n.style.cssText="top:1px;float:left;opacity:.5",i=document.createElement("select"),s=i.appendChild(document.createElement("option")),r=e.getElementsByTagName("input")[0],r.checked=!0,t={dom:{div:e,a:n,select:i,opt:s,input:r}},t}(),t.createChain("event",function(){var e={};return function(n,r){switch(t.type(n)){case"object":return e.originalEvent===n?e:e=new t.event.$Event(n);case"$Event":return n}}}(),function(e){var n,r,i,s=this;this._type_="$Event";if(typeof e=="object"&&e.type){s.originalEvent=n=e;for(var o in n)typeof n[o]!="function"&&(s[o]=n[o]);n.extraData&&t.extend(s,n.extraData),s.target=s.srcElement=n.srcElement||(r=n.target)&&(r.nodeType==3?r.parentNode:r),s.relatedTarget=n.relatedTarget||(r=n.fromElement)&&(r===s.target?n.toElement:r),s.keyCode=s.which=n.keyCode||n.which,!s.which&&n.button!==undefined&&(s.which=n.button&1?1:n.button&2?3:n.button&4?2:0);var u=document.documentElement,a=document.body;s.pageX=n.pageX||n.clientX+(u&&u.scrollLeft||a&&a.scrollLeft||0)-(u&&u.clientLeft||a&&a.clientLeft||0),s.pageY=n.pageY||n.clientY+(u&&u.scrollTop||a&&a.scrollTop||0)-(u&&u.clientTop||a&&a.clientTop||0),s.data}this.timeStamp=(new Date).getTime()}).extend({stopPropagation:function(){var e=this.originalEvent;e&&(e.stopPropagation?e.stopPropagation():e.cancelBubble=!0)},preventDefault:function(){var e=this.originalEvent;e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)}}),t.merge=function(e,t){var n=e.length,r=0;if(typeof t.length=="number")for(var i=t.length;r<i;r++)e[n++]=t[r];else while(t[r]!==undefined)e[n++]=t[r++];return e.length=n,e},t.array.extend({unique:function(e){var t=this.length,n=this.slice(0),r,i;"function"!=typeof e&&(e=function(e,t){return e===t});while(--t>0){i=n[t],r=t;while(r--)if(e(i,n[r])){n.splice(t,1);break}}t=this.length=n.length;for(r=0;r<t;r++)this[r]=n[r];return this}}),t.query=t.query||function(){function f(n,o){var u,a,f,l,c,h,p,d,v=[];return e.test(n)?(f=RegExp.$2,c=RegExp.$1||"*",t.forEach(o.getElementsByTagName(c),function(e){e.id==f&&v.push(e)})):r.test(n)||n=="*"?t.merge(v,o.getElementsByTagName(n)):i.test(n)?(p=[],c=RegExp.$1,h=RegExp.$2,u=" "+h+" ",o.getElementsByClassName?p=o.getElementsByClassName(h):t.forEach(o.getElementsByTagName("*"),function(e){e.className&&~(" "+e.className+" ").indexOf(u)&&p.push(e)}),c&&(c=c.toUpperCase())?t.forEach(p,function(e){e.tagName.toUpperCase()===c&&v.push(e)}):t.merge(v,p)):s.test(n)&&(d=n.substr(1).split("."),t.forEach(o.getElementsByTagName("*"),function(e){e.className&&(u=" "+e.className+" ",a=!0,t.forEach(d,function(e){~u.indexOf(" "+e+" ")||(a=!1)}),a&&v.push(e))})),v}function l(e,r){var i,s=e,o="__tangram__",u=[];return!r&&n.test(s)&&(i=document.getElementById(s.substr(1)))?[i]:(r=r||document,r.querySelectorAll?(r.nodeType==1&&!r.id?(r.id=o,i=r.querySelectorAll("#"+o+" "+s),r.id=""):i=r.querySelectorAll(s),i):~s.indexOf(" ")?(t.forEach(f(s.substr(0,s.indexOf(" ")),r),function(e){t.merge(u,l(s.substr(s.indexOf(" ")+1),e))}),u):f(s,r))}var e=/^(\w*)#([\w\-\$]+)$/,n=/^#([\w\-\$]+)$/,r=/^\w+$/,i=/^(\w*)\.([\w\-\$]+)$/,s=/^(\.[\w\-\$]+)+$/,o=/\s*,\s*/,u=/\s+/g,a=Array.prototype.slice;return function(e,n,r){if(!e||typeof e!="string")return r||[];var i=[];return e=e.replace(u," "),r&&t.merge(i,r)&&(r.length=0),t.forEach(e.indexOf(",")>0?e.split(o):[e],function(e){t.merge(i,l(e,n))}),t.merge(r||[],t.array(i).unique())}}(),t.createChain("dom",function(e,n){var r,i=new t.dom.$DOM(n);if(!e)return i;if(e._type_=="$DOM")return e;if(e.nodeType||e==e.window)return i[0]=e,i.length=1,i;if(e.length&&i.toString.call(e)!="[object String]")return t.merge(i,e);if(typeof e=="string")if(e.charAt(0)=="<"&&e.charAt(e.length-1)==">"&&e.length>2){var s=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,o=n&&n._type_==="$DOM"?n[0]:n,u=s.exec(e);o=o&&o.nodeType?o.ownerDocument||o:document,u=u?[o.createElement(u[1])]:t.dom.createElements?t.dom.createElements(e):[],t.merge(i,u)}else t.query(e,n,i);else if(typeof e=="function")return i.ready?i.ready(e):i;return i},function(e){this.length=0,this._type_="$DOM",this.context=e||document}).extend({size:function(){return this.length},splice:function(){},get:function(e){return typeof e=="number"?e<0?this[this.length+e]:this[e]:Array.prototype.slice.call(this,0)},toArray:function(){return this.get()}}),t.dom.extend({each:function(e){t.check("function","baidu.dom.each");var n,r,i=this.length;for(n=0;n<i;n++){r=e.call(this[n],n,this[n],this);if(r===!1||r=="break")break}return this}}),t._util_.eventBase=t._util_.eventBase||{},void function(e,t){if(e.listener)return;t=e.listener={},window.addEventListener?t.add=function(e,t,n){e.addEventListener(t,n,!1)}:window.attachEvent&&(t.add=function(e,t,n){e.attachEvent("on"+t,n)})}(t._util_.eventBase),void function(e,n){if(e.queue)return;var r=t.id,i=e.queue={},s=i.attaCache=t.global("eventQueueCache"),o=e.listener;i.get=function(e,t,n,i){var o=r(e),u;return s[o]||(s[o]={}),u=s[o],t?(!u[t]&&n&&this.setupCall(e,t,n,u[t]=[],i),u[t]||[]):u},i.add=function(e,t,n,r,i){this.get(e,t,n,i).push(r)},i.remove=function(e,t,n){var r,i;if(t){var r=this.get(e,t);if(n)for(var s=r.length-1;s>=0;s--)r[s].orig==n&&r.splice(s,1);else r.length=0}else{var i=this.get(e);for(var s in i)i[s].length=0}},i.handlerList=function(e,n){var r=[];for(var i=0,s;s=n[i];i++){if(s.delegate&&t.dom(s.delegate,e).size()<1)continue;r.push(s)}return r},i.call=function(e,n,r,s){if(r){if(!r.length)return;var o=[].slice.call(arguments,1),u=[];o.unshift(s=t.event(s||n)),s.type=n,s.currentTarget||(s.currentTarget=e),s.target||(s.target=e),r=i.handlerList(e,r);for(var a=0,f,l=r.length;a<l;a++)if(f=r[a])f.pkg.apply(e,o),f.one&&u.unshift(a);if(u.length)for(var a=0,l=u.length;a<l;a++)this.remove(e,n,r[a].fn)}else r=this.get(e,n),this.call(e,n,r,s)},i.setupCall=function(){var e=function(e,t,n,r){o.add(e,n,function(n){i.call(e,t,r,n)})};return function(n,r,i,s,o){if(!o)e(n,r,i,s);else{n=t.dom(o,n);for(var u=0,a=n.length;u<a;u++)e(n[u],r,i,s)}}}()}(t._util_.eventBase,t.event),void function(e,n){if(e.core)return;var r=e.queue,i=e.core={},s=n.special={},o=[].push,u=function(e,t){for(var n=0,r=t.length;n<r;n++)if(t.get(n).contains(e))return t[n]};i.build=function(e,n,r,i,a){var f;return i&&(f=t.dom(i,e)),n in s&&s[n].pack&&(r=s[n].pack(r)),function(n){var s=t.dom(n.target),l=[n],c;a&&!n.data&&(n.data=a),n.triggerData&&o.apply(l,n.triggerData);if(!f)return n.result=r.apply(e,l);for(var h=0;h<2;h++){if(c=u(n.target,f))return n.result=r.apply(c,l);f=t.dom(i,e)}}},i.add=function(e,t,n,i,o,u){var a=this.build(e,t,n,i,o),f,l;l=t,t in s&&(f=s[t].attachElements,l=s[t].bindType||t),r.add(e,t,l,{type:t,pkg:a,orig:n,one:u,delegate:i},f)},i.remove=function(e,t,n,i){r.remove(e,t,n,i)}}(t._util_.eventBase,t.event),t.dom.extend({on:function(e,n,r,i,s){var o=t._util_.eventBase.core;return typeof n=="object"&&n?(i=r,r=n,n=null):typeof r=="function"?(i=r,r=null):typeof n=="function"&&(i=n,n=r=null),typeof e=="string"?(e=e.split(/[ ,]+/),this.each(function(){t.forEach(e,function(e){o.add(this,e,i,n,r,s)},this)})):typeof e=="object"&&(i&&(i=null),t.forEach(e,function(e,t){this.on(t,n,r,e,s)},this)),this}}),t.dom.g=function(e){return e?"string"==typeof e||e instanceof String?document.getElementById(e):!e.nodeName||e.nodeType!=1&&e.nodeType!=9?null:e:null},t.event.on=t.on=function(e,n,r){return typeof e=="string"&&(e=t.dom.g(e)),t.dom(e).on(n.replace(/^\s*on/,""),r),e},void function(){function w(e){var n,r;if(!e||t.type(e)!=="string")return null;try{window.DOMParser?(r=new DOMParser,n=r.parseFromString(e,"text/xml")):(n=new ActiveXObject("Microsoft.XMLDOM"),n.async="false",n.loadXML(e))}catch(i){n=undefined}if(!n||!n.documentElement||n.getElementsByTagName("parsererror").length)throw new Error("Invalid XML: "+e);return n}function E(e){if(!e||t.type(e)!=="string")return null;e=t.string(e).trim();if(window.JSON&&window.JSON.parse)return window.JSON.parse(e);if(l.test(e.replace(h,"@").replace(p,"]").replace(c,"")))return(new Function("return "+e))();throw new Error("Invalid JSON: "+e)}function S(e){e&&/\S/.test(e)&&(window.execScript||function(e){window.eval.call(window,e)})(e)}function x(e){return function(n,r){t.type(n)!=="string"&&(r=n,n="*");var i=n.toLowerCase().split(/\s+/),s,o;if(t.type(r)==="function")for(var u=0,a;a=i[u];u++)s=/^\+/.test(a),s&&(a=a.substr(1)||"*"),o=e[a]=e[a]||[],o[s?"unshift":"push"](r)}}function T(e,t,n){var r,i,s,o,u=e.contents,a=e.dataTypes,f=e.responseFields;for(i in f)i in n&&(t[f[i]]=n[i]);while(a[0]==="*")a.shift(),r===undefined&&(r=e.mimeType||t.getResponseHeader("content-type"));if(r)for(i in u)if(u[i]&&u[i].test(r)){a.unshift(i);break}if(a[0]in n)s=a[0];else{for(i in n){if(!a[0]||e.converters[i+" "+a[0]]){s=i;break}o||(o=i)}s=s||o}if(s)return s!==a[0]&&a.unshift(s),n[s]}function N(e,t){var n=e.dataTypes.slice(),r=n[0],i={},s,o;e.dataFilter&&(t=e.dataFilter(t,e.dataType));if(n[1])for(var u in e.converters)i[u.toLowerCase()]=e.converters[u];for(var u=0,a;a=n[++u];)if(a!=="*"){if(r!=="*"&&r!==a){s=i[r+" "+a]||i["* "+a];if(!s)for(var f in i){o=f.split(" ");if(o[1]===a){s=i[r+" "+o[0]]||i["* "+o[0]];if(s){s===!0?s=i[f]:i[f]!==!0&&(a=o[0],n.splice(u--,0,a));break}}}if(s!==!0)if(s&&e["throws"])t=s(t);else try{t=s(t)}catch(l){return{state:"parsererror",error:s?l:"No conversion from "+r+" to "+a}}}r=a}return{state:"success",data:t}}function C(e,t,n,r,i,s){i=i||t.dataTypes[0],s=s||{},s[i]=!0;var o,u=e[i],a=u?u.length:0,f=e===v;for(var l=0;l<a&&(f||!o);l++)o=u[l](t,n,r),typeof o=="string"&&(!f||s[o]?o=undefined:(t.dataTypes.unshift(o),o=C(e,t,n,r,o,s)));return(f||!o)&&!s["*"]&&(o=C(e,t,n,r,"*",s)),o}function k(e,n){var r=t.ajax.settings.flatOptions||{},i;for(var s in n)n[s]!==undefined&&((r[s]?e:i||(i={}))[s]=n[s]);i&&t.extend(!0,e,i)}function L(e,n,r){r=t.type(r)==="function"?r():typeof r=="undefined"||r==null?"":r,e.push(encodeURIComponent(n)+"="+encodeURIComponent(r))}function A(e,n,r,i){if(t.type(r)==="array")t.forEach(r,function(t,r){i||o.test(n)?L(e,n,t):A(e,n+"["+(typeof t=="object"?r:"")+"]",t,i)});else if(!i&&t.type(r)==="object")for(var s in r)A(e,n+"["+s+"]",r[s],i);else L(e,n,r)}function B(){try{return new window.XMLHttpRequest}catch(e){}}function j(){try{return new window.ActiveXObject("Microsoft.XMLHTTP")}catch(e){}}var e=document.URL,n=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,r=/^\/\//,i=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,s=/#.*$/,o=/\[\]$/,u=/^(?:GET|HEAD)$/,a=/([?&])_=[^&]*/,f=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,l=/^[\],:{}\s]*$/,c=/(?:^|:|,)(?:\s*\[)+/g,h=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,p=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,d=["*/"]+["*"],v={},m={},g={},y={},b=i.exec(e.toLowerCase())||[];t.createChain("ajax",function(e,n){function H(e,t,n,r){var i=t,s,u,a,f,c;if(x===2)return;x=2,P&&clearTimeout(P),_=undefined,O=r||"",D.readyState=e>0?4:0,n&&(f=T(o,D,n));if(e>=200&&e<300||e===304)o.ifModified&&(c=D.getResponseHeader("Last-Modified"),c&&(g[h]=c),c=D.getResponseHeader("Etag"),c&&(y[h]=c)),e===304?(i="notmodified",s=!0):(s=N(o,f),i=s.state,u=s.data,a=s.error,s=!a);else{a=i;if(!i||e)i="error",e<0&&(e=0)}D.status=e,D.statusText=""+(t||i),s?w.resolveWith(l,[u,i,D]):w.rejectWith(l,[D,i,a]),D.statusCode(S),S=undefined,E.fireWith(l,[D,i])}t.object.isPlain(e)&&(n=e,e=undefined),n=n||{};var o=t.ajax.setup({},n),l=o.context||o,c,h,p,w=t.Deferred(),E=t.Callbacks("once memory"),S=o.statusCode||{},x=0,k={},L={},A="canceled",O,M,_,D=t.extend(new t.ajax.$Ajax(e,o),{readyState:0,setRequestHeader:function(e,t){if(!x){var n=e.toLowerCase();e=k[n]=k[n]||e,L[e]=t}},getAllResponseHeaders:function(){return x===2?O:null},getResponseHeader:function(e){var t;if(x===2){if(!M){M={};while(t=f.exec(O))M[t[1].toLowerCase()]=t[2]}t=M[e.toLowerCase()]}return t===undefined?null:t},overrideMimeType:function(e){return!x&&(o.mimeType=e),this},abort:function(e){return e=e||A,_&&_.abort(e),H(0,e),this}}),P;w.promise(D),D.success=D.done,D.error=D.fail,D.complete=E.add,D.statusCode=function(e){if(e)if(x<2)for(var t in e)S[t]=[S[t],e[t]];else D.always(e[D.status]);return this},o.url=((e||o.url)+"").replace(s,"").replace(r,b[1]+"//"),o.dataTypes=t.string(o.dataType||"*").trim().toLowerCase().split(/\s+/),o.crossDomain==null&&(p=i.exec(o.url.toLowerCase()),o.crossDomain=!(!p||p[1]==b[1]&&p[2]==b[2]&&(p[3]||(p[1]==="http:"?80:443))==(b[3]||(b[1]==="http:"?80:443)))),o.data&&o.processData&&t.type(o.data)!=="string"&&(o.data=t.ajax.param(o.data,o.traditional)),C(v,o,n,D);if(x===2)return"";c=o.global,o.type=o.type.toUpperCase(),o.hasContent=!u.test(o.type);if(!o.hasContent){o.data&&(o.url+=(~o.url.indexOf("?")?"&":"?")+o.data,delete o.data),h=o.url;if(o.cache===!1){var B=(new Date).getTime(),j=o.url.replace(a,"$1_="+B);o.url=j+(j===o.url?(~o.url.indexOf("?")?"&":"?")+"_="+B:"")}}(o.data&&o.hasContent&&o.contentType!==!1||n.contentType)&&D.setRequestHeader("Content-Type",o.contentType),o.ifModified&&(h=h||o.url,g[h]&&D.setRequestHeader("If-Modified-Since",g[h]),y[h]&&D.setRequestHeader("If-None-Match",y[h])),D.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+(o.dataTypes[0]!=="*"?", "+d+"; q=0.01":""):o.accepts["*"]);for(var F in o.headers)D.setRequestHeader(F,o.headers[F]);if(!o.beforeSend||o.beforeSend.call(l,D,o)!==!1&&x!==2){A="abort";for(var F in{success:1,error:1,complete:1})D[F](o[F]);_=C(m,o,n,D);if(!_)H(-1,"No Transport");else{D.readyState=1,o.async&&o.timeout>0&&(P=setTimeout(function(){D.abort("timeout")},o.timeout));try{x=1,_.send(L,H)}catch(I){if(!(x<2))throw I;H(-1,I)}}return D}return D.abort()},function(e,t){this.url=e,this.options=t}),t.ajax.settings={url:e,isLocal:n.test(b[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":d},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":window.String,"text html":!0,"text json":E,"text xml":w},flatOptions:{context:!0,url:!0}},t.ajax.setup=function(e,n){return n?k(e,t.ajax.settings):(n=e,e=t.ajax.settings),k(e,n),e},t.ajax.param=function(e,n){var r=[];if(t.type(e)==="array")t.forEach(e,function(e){L(r,e.name,e.value)});else for(var i in e)A(r,i,e[i],n);return r.join("&").replace(/%20/g,"+")},t.ajax.prefilter=x(v),t.ajax.transport=x(m);var O=[],M=/(=)\?(?=&|$)|\?\?/,_=(new Date).getTime();t.ajax.setup({jsonp:"callback",jsonpCallback:function(){var e=O.pop()||t.key+"_"+_++;return this[e]=!0,e}}),t.ajax.prefilter("json jsonp",function(e,n,r){var i,s,o,u=e.data,a=e.url,f=e.jsonp!==!1,l=f&&M.test(a),c=f&&!l&&t.type(u)==="string"&&!(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&M.test(u);if(e.dataTypes[0]==="jsonp"||l||c)return i=e.jsonpCallback=t.type(e.jsonpCallback)==="function"?e.jsonpCallback():e.jsonpCallback,s=window[i],l?e.url=a.replace(M,"$1"+i):c?e.data=u.replace(M,"$1"+i):f&&(e.url+=(/\?/.test(a)?"&":"?")+e.jsonp+"="+i),e.converters["script json"]=function(){return o[0]},e.dataTypes[0]="json",window[i]=function(){o=arguments},r.always(function(){window[i]=s,e[i]&&(e.jsonpCallback=n.jsonpCallback,O.push(i)),o&&t.type(s)==="function"&&s(o[0]),o=s=undefined}),"script"}),t.ajax.setup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return S(e),e}}}),t.ajax.prefilter("script",function(e){e.cache===undefined&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),t.ajax.transport("script",function(e){if(e.crossDomain){var t,n=document.head||document.getElementsByTagName("head")[0]||document.documentElement;return{send:function(r,i){t=document.createElement("script"),t.async="async",e.scriptCharset&&(t.charset=e.scriptCharset),t.src=e.url,t.onload=t.onreadystatechange=function(e,r){if(r||!t.readyState||/loaded|complete/.test(t.readyState))t.onload=t.onreadystatechange=null,n&&t.parentNode&&n.removeChild(t),t=undefined,!r&&i(200,"success")},n.insertBefore(t,n.firstChild)},abort:function(){t&&t.onload(0,1)}}}});var D,P=0,H=window.ActiveXObject?function(){for(var e in D)D[e](0,1)}:!1;t.ajax.settings.xhr=window.ActiveXObject?function(){return!this.isLocal&&B()||j()}:B,void function(e){t.extend(t._util_.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(t.ajax.settings.xhr()),t._util_.support.ajax&&t.ajax.transport(function(e){if(!e.crossDomain||t._util_.support.cors){var n;return{send:function(r,i){var s,o=e.xhr();e.username?o.open(e.type,e.url,e.async,e.username,e.password):o.open(e.type,e.url,e.async);if(e.xhrFields)for(var u in e.xhrFields)o[u]=e.xhrFields[u];e.mimeType&&o.overrideMimeType&&o.overrideMimeType(e.mimeType),!e.crossDomain&&!r["X-Requested-With"]&&(r["X-Requested-With"]="XMLHttpRequest");try{for(var u in r)o.setRequestHeader(u,r[u])}catch(a){}o.send(e.hasContent&&e.data||null),n=function(t,r){var u,a,f,l,c;try{if(n&&(r||o.readyState===4)){n=undefined,s&&(o.onreadystatechange=function(){},H&&delete D[s]);if(r)o.readyState!==4&&o.abort();else{u=o.status,f=o.getAllResponseHeaders(),l={},c=o.responseXML,c&&c.documentElement&&(l.xml=c);try{l.text=o.responseText}catch(h){}try{a=o.statusText}catch(h){a=""}!u&&e.isLocal&&!e.crossDomain?u=l.text?200:404:u===1223&&(u=204)}}}catch(p){!r&&i(-1,p)}l&&i(u,a,l,f)},e.async?o.readyState===4?setTimeout(n,0):(s=++P,H&&(D||(D={},t.dom(window).on("unload",H)),D[s]=n),o.onreadystatechange=n):n()},abort:function(){n&&n(0,1)}}}})}(),t.array.extend({contains:function(e){return!!~this.indexOf(e)}}),t.each=function(e,t,n){var r,i,s,o;if(typeof t=="function"&&e){i=typeof e.length=="number"?e.length:e.byteLength;if(typeof i=="number"){if(Object.prototype.toString.call(e)==="[object Function]")return e;for(r=0;r<i;r++){s=e[r],s===undefined&&(s=e.charAt&&e.charAt(r)),o=t.call(n||s,r,s,e);if(o===!1||o=="break")break}}else if(typeof e=="number")for(r=0;r<e;r++){o=t.call(n||r,r,r,r);if(o===!1||o=="break")break}else if(typeof e=="object")for(r in e)if(e.hasOwnProperty(r)){o=t.call(n||e[r],r,e[r],e);if(o===!1||o=="break")break}}return e},t.array.extend({each:function(e,n){return t.each(this,e,n)},forEach:function(e,n){return t.forEach(this,e,n)}}),t.array.extend({empty:function(){return this.length=0,this}}),t.array.extend({filter:function(e,n){var r=t.array([]),i,s,o,u=0;if(t.type(e)==="function")for(i=0,s=this.length;i<s;i++)o=this[i],e.call(n||this,o,i,this)===!0&&(r[u++]=o);return r}}),t.array.extend({find:function(e){var n,r,i=this.length;if(t.type(e)=="function")for(n=0;n<i;n++){r=this[n];if(e.call(this,r,n,this)===!0)return r}return null}}),t.array.extend({hash:function(e){var t={},n=e&&e.length,r,i;for(r=0,i=this.length;r<i;r++)t[this[r]]=n&&n>r?e[r]:!0;return t}}),t.array.extend({lastIndexOf:function(e,n){t.check(".+(,number)?","baidu.array.lastIndexOf");var r=this.length;(!(n|=0)||n>=r)&&(n=r-1),n<0&&(n+=r);for(;n>=0;n--)if(n in this&&this[n]===e)return n;return-1}}),t.array.extend({map:function(e,n){t.check("function(,.+)?","baidu.array.map");var r=this.length,i=t.array([]);for(var s=0;s<r;s++)i[s]=e.call(n||this,this[s],s,this);return i}}),t.array.extend({remove:function(e){var t=this.length;while(t--)this[t]===e&&this.splice(t,1);return this}}),t.array.extend({removeAt:function(e){return t.check("number","baidu.array.removeAt"),this.splice(e,1)[0]}}),t.base=t.base||{blank:function(){}},t.base.Class=function(){var e=(t._global_=window[t.guid])._instances;return e||(e=t._global_._instances={}),function(){this.guid=t.id(),this._decontrol_||(e[this.guid]=this)}}(),t.extend(t.base.Class.prototype,{toString:t.base.Class.prototype.toString=function(){return"[object "+(this._type_||"Object")+"]"},dispose:function(){delete t._global_._instances[this.guid];if(this._listeners_)for(var e in this._listeners_)this._listeners_[e].length=0,delete this._listeners_[e];for(var n in this)t.isFunction(this[n])?this[n]=t.base.blank:delete this[n];this.disposed=!0},fire:function(e,n){t.isString(e)&&(e=new t.base.Event(e));var r,i,s,o,u=this._listeners_,a=e.type,f=[e].concat(Array.prototype.slice.call(arguments,1));!u&&(u=this._listeners_={}),t.extend(e,n||{}),e.target=e.target||this,e.currentTarget=this,a.indexOf("on")&&(a="on"+a),t.isFunction(this[a])&&this[a].apply(this,f),(r=this._options)&&t.isFunction(r[a])&&r[a].apply(this,f);if(t.isArray(s=u[a]))for(r=s.length-1;r>-1;r--)o=s[r],o&&o.handler.apply(this,f),o&&o.once&&s.splice(r,1);return e.returnValue},on:function(e,n,r){if(!t.isFunction(n))return this;var i,s=this._listeners_;return!s&&(s=this._listeners_={}),e.indexOf("on")&&(e="on"+e),!t.isArray(i=s[e])&&(i=s[e]=[]),s[e].unshift({handler:n,once:!!r}),this},once:function(e,t){return this.on(e,t,!0)},one:function(e,t){return this.on(e,t,!0)},off:function(e,t){var n,r,i=this._listeners_;if(!i)return this;if(typeof e=="undefined"){for(n in i)delete i[n];return this}e.indexOf("on")&&(e="on"+e);if(typeof t=="undefined")delete i[e];else if(r=i[e])for(n=r.length-1;n>=0;n--)r[n].handler===t&&r.splice(n,1);return this}}),t.base.Class.prototype.addEventListener=t.base.Class.prototype.on,t.base.Class.prototype.removeEventListener=t.base.Class.prototype.un=t.base.Class.prototype.off,t.base.Class.prototype.dispatchEvent=t.base.Class.prototype.fire,window.baiduInstance=function(e){return window[t.guid]._instances[e]},t.base.Event=function(e,t){this.type=e,this.returnValue=!0,this.target=t||null,this.currentTarget=null,this.preventDefault=function(){this.returnValue=!1}},t.base.inherits=function(e,t,n){var r,i,s=e.prototype,o=new Function;o.prototype=t.prototype,i=e.prototype=new o;for(r in s)i[r]=s[r];return e.prototype.constructor=e,e.superClass=t.prototype,typeof n=="string"&&(i._type_=n),e.extend=function(t){for(var n in t)i[n]=t[n];return e},e},t.base.register=function(e,t,n){(e._reg_||(e._reg_=[])).push(t);for(var r in n)e.prototype[r]=n[r]},t.cookie=t.cookie||{},t.cookie._isValidKey=function(e){return(new RegExp('^[^\\x00-\\x20\\x7f\\(\\)<>@,;:\\\\\\"\\[\\]\\?=\\{\\}\\/\\u0080-\\uffff]+$')).test(e)},t.cookie.getRaw=function(e){if(t.cookie._isValidKey(e)){var n=new RegExp("(^| )"+e+"=([^;]*)(;|$)"),r=n.exec(document.cookie);if(r)return r[2]||null}return null},t.cookie.get=function(e){var n=t.cookie.getRaw(e);return"string"==typeof n?(n=decodeURIComponent(n),n):null},t.cookie.setRaw=function(e,n,r){if(!t.cookie._isValidKey(e))return;r=r||{};var i=r.expires;"number"==typeof r.expires&&(i=new Date,i.setTime(i.getTime()+r.expires)),document.cookie=e+"="+n+(r.path?"; path="+r.path:"")+(i?"; expires="+i.toGMTString():"")+(r.domain?"; domain="+r.domain:"")+(r.secure?"; secure":"")},t.cookie.remove=function(e,n){n=n||{},n.expires=new Date(0),t.cookie.setRaw(e,"",n)},t.cookie.set=function(e,n,r){t.cookie.setRaw(e,encodeURIComponent(n),r)},t.createClass=function(e,n,r){e=t.isFunction(e)?e:function(){},r=typeof n=="object"?n:r||{};var i=function(){var t=this;r.decontrolled&&(t._decontrol_=!0),i.superClass.apply(t,arguments);for(var n in i.options)t[n]=i.options[n];e.apply(t,arguments);for(var n=0,s=i._reg_;s&&n<s.length;n++)s[n].apply(t,arguments)};return t.extend(i,{superClass:r.superClass||t.base.Class,inherits:function(n){if(typeof n!="function")return i;var r=function(){};r.prototype=(i.superClass=n).prototype;var s=i.prototype=new r;return t.extend(i.prototype,e.prototype),s.constructor=e,i},register:function(e,n){return(i._reg_||(i._reg_=[])).push(e),n&&t.extend(i.prototype,n),i},extend:function(e){return t.extend(i.prototype,e),i}}),n=t.isString(n)?n:r.className||r.type,t.isString(n)&&(e.prototype._type_=n),t.isFunction(i.superClass)&&i.inherits(i.superClass),i},t.createSingle=function(e,n){var r=new t.base.Class;return t.isString(n)&&(r._type_=n),t.extend(r,e)},t.date=t.date||{},t.createChain("number",function(e){var n=parseFloat(e),r=isNaN(n)?n:e,i=typeof r=="number"?Number:String,s=i.prototype;return r=new i(r),t.forEach(t.number.$Number.prototype,function(e,t){s[t]||(r[t]=e)}),r}),t.number.extend({pad:function(e){var t=this,n="",r=t<0,i=String(Math.abs(t));return i.length<e&&(n=(new Array(e-i.length+1)).join("0")),(r?"-":"")+n+i}}),t.date.format=function(e,n){function r(e,t){n=n.replace(e,t)}if("string"!=typeof n)return e.toString();var i=t.number.pad,s=e.getFullYear(),o=e.getMonth()+1,u=e.getDate(),a=e.getHours(),f=e.getMinutes(),l=e.getSeconds();return r(/yyyy/g,i(s,4)),r(/yy/g,i(parseInt(s.toString().slice(2),10),2)),r(/MM/g,i(o,2)),r(/M/g,o),r(/dd/g,i(u,2)),r(/d/g,u)
    -,r(/HH/g,i(a,2)),r(/H/g,a),r(/hh/g,i(a%12,2)),r(/h/g,a%12),r(/mm/g,i(f,2)),r(/m/g,f),r(/ss/g,i(l,2)),r(/s/g,l),n},t.date.parse=function(e){var t=new RegExp("^\\d+(\\-|\\/)\\d+(\\-|\\/)\\d+$");if("string"==typeof e){if(t.test(e)||isNaN(Date.parse(e))){var n=e.split(/ |T/),r=n.length>1?n[1].split(/[^\d]/):[0,0,0],i=n[0].split(/[^\d]/);return new Date(i[0]-0,i[1]-1,i[2]-0,r[0]-0,r[1]-0,r[2]-0)}return new Date(e)}return new Date},t.dom.extend({pushStack:function(e){var n=t.dom();return t.merge(n,e),n.prevObject=this,n.context=this.context,n}}),t.dom.createElements=function(){function i(e,t){var n=e.getElementsByTagName("SCRIPT"),r,i,s;for(r=n.length-1;r>=0;r--)s=n[r],i=t.createElement("SCRIPT"),s.id&&(i.id=s.id),s.src&&(i.src=s.src),s.type&&(i.type=s.type),i[s.text?"text":"textContent"]=s.text||s.textContent,s.parentNode.replaceChild(i,s)}var e=/<(\w+)/i,n=/<|&#?\w+;/,r={area:[1,"<map>","</map>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],legend:[1,"<fieldset>","</fieldset>"],option:[1,"<select multiple='multiple'>","</select>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],_default:[0,"",""]};return r.optgroup=r.option,r.tbody=r.tfoot=r.colgroup=r.caption=r.thead,r.th=r.td,function(s,o){t.isNumber(s)&&(s=s.toString()),o=o||document;var u,a,f,l=s,c=l.length,h=o.createElement("div"),p=o.createDocumentFragment(),d=[];if(t.isString(l))if(!n.test(l))d.push(o.createTextNode(l));else{u=r[l.match(e)[1].toLowerCase()]||r._default,h.innerHTML="<i>mz</i>"+u[1]+l+u[2],h.removeChild(h.firstChild),i(h,o),a=u[0],f=h;while(a--)f=f.firstChild;t.merge(d,f.childNodes),t.forEach(d,function(e){p.appendChild(e)}),h=f=null}return h=null,d}}(),t.dom.extend({add:function(e,n){var r=t.array(this.get());switch(t.type(e)){case"HTMLElement":r.push(e);break;case"$DOM":case"array":t.merge(r,e);break;case"string":t.merge(r,t.dom(e,n));break;default:typeof e=="object"&&e.length&&t.merge(r,e)}return this.pushStack(r.unique())}}),t.dom.extend({addClass:function(e){if(!arguments.length)return this;var n=typeof e,r=" ";if(n=="string"){e=t.string.trim(e);var i=e.split(" ");t.forEach(this,function(e,t){var n=e.className;for(var s=0;s<i.length;s++)~(r+n+r).indexOf(r+i[s]+r)||(n+=" "+i[s]);e.className=n.replace(/^\s+/g,"")})}else n=="function"&&t.forEach(this,function(n,r){t.dom(n).addClass(e.call(n,r,n.className))});return this}}),t.dom.extend({getDocument:function(){if(this.size()<=0)return undefined;var e=this[0];return e.nodeType==9?e:e.ownerDocument||e.document}}),t._util_.cleanData=function(e){var n;for(var r=0,i;i=e[r];r++){n=t.id(i,"get");if(!n)continue;t._util_.eventBase.queue.remove(i),t.id(i,"remove")}},t.dom.extend({empty:function(){for(var e=0,n;n=this[e];e++){n.nodeType===1&&t._util_.cleanData(n.getElementsByTagName("*"));while(n.firstChild)n.removeChild(n.firstChild)}return this}}),t.dom.extend({append:function(){return t.check("^(?:string|function|HTMLElement|\\$DOM)(?:,(?:string|array|HTMLElement|\\$DOM))*$","baidu.dom.append"),t._util_.smartInsert(this,arguments,function(e){this.nodeType===1&&this.appendChild(e)}),this}}),t.dom.extend({html:function(e){var n=t.dom,r=t._util_,i=this,s=!1,o=!!r.support.dom.div.getElementsByTagName("link").length,u=r.support.dom.div.firstChild.nodeType===3,a;if(!this.size())switch(typeof e){case"undefined":return undefined;default:return i}var f="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",l=/<(?:script|style|link)/i,c=new RegExp("<(?:"+f+")[\\s/>]","i"),h=/^\s+/,p=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,d=/<([\w:]+)/,v={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};return v.optgroup=v.option,v.tbody=v.tfoot=v.colgroup=v.caption=v.thead,v.th=v.td,o||(v._default=[1,"X<div>","</div>"]),t.forEach(i,function(t,r){if(a)return;var f=n(t);switch(typeof e){case"undefined":a=t.nodeType===1?t.innerHTML:undefined;return;case"number":e=String(e);case"string":s=!0;if(!l.test(e)&&(o||!c.test(e))&&(u||!h.test(e))&&!v[(d.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(p,"<$1></$2>");try{t.nodeType===1&&(f.empty(),t.innerHTML=e),t=0}catch(m){}}t&&i.empty().append(e);break;case"function":s=!0,f.html(e.call(t,r,f.html()))}}),s?i:a}}),t._util_.smartInsert=function(e,n,r){if(n.length<=0||e.size()<=0)return;if(t.type(n[0])==="function"){var i=n[0],s;return t.forEach(e,function(e,o){s=t.dom(e),n[0]=i.call(e,o,s.html()),t._util_.smartInsert(s,n,r)})}var o=e.getDocument()||document,u=o.createDocumentFragment(),a=e.length-1,f;for(var l=0,c;c=n[l];l++)c.nodeType?u.appendChild(c):t.forEach(~"string|number".indexOf(t.type(c))?t.dom.createElements(c,o):c,function(e){u.appendChild(e)});if(!(f=u.firstChild))return;t.forEach(e,function(e,t){r.call(e.nodeName.toLowerCase()==="table"&&f.nodeName.toLowerCase()==="tr"?e.tBodies[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e,t<a?u.cloneNode(!0):u)})},t.dom.extend({after:function(){return t.check("^(?:string|function|HTMLElement|\\$DOM)(?:,(?:string|array|HTMLElement|\\$DOM))*$","baidu.dom.after"),t._util_.smartInsert(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)}),this}}),t.makeArray=function(e,n){var r=n||[];return e?(e.length==null||~"string|function|regexp".indexOf(t.type(e))?[].push.call(r,e):t.merge(r,e),r):r},t.dom.extend({map:function(e){t.check("function","baidu.dom.map");var n=[],r=0;return t.forEach(this,function(t,s){n[r++]=e.call(t,s,t,t)}),this.pushStack(n)}}),t._util_.isXML=function(e){var t=(e?e.ownerDocument||e:0).documentElement;return t?t.nodeName!=="HTML":!1},t.dom.extend({clone:function(){function u(e){return e.getElementsByTagName?e.getElementsByTagName("*"):e.querySelectorAll?e.querySelectorAll("*"):[]}function a(e,n){n.clearAttributes&&n.clearAttributes(),n.mergeAttributes&&n.mergeAttributes(e);switch(n.nodeName.toLowerCase()){case"object":n.outerHTML=e.outerHTML;break;case"textarea":case"input":~"checked|radio".indexOf(e.type)&&(e.checked&&(n.defaultChecked=n.checked=e.checked),n.value!==e.value&&(n.value=e.value)),n.defaultValue=e.defaultValue;break;case"option":n.selected=e.defaultSelected;break;case"script":n.text!==e.text&&(n.text=e.text)}n[t.key]&&n.removeAttribute(t.key)}function f(e,i){if(i.nodeType!==1||!t.id(e,"get"))return;var s=r.get(e);for(var o in s)for(var u=0,a;a=s[o][u];u++)n.add(i,o,a.orig,null,null,a.one)}function l(e,n,r){var i=e.cloneNode(!0),l,c,h;if((!o||!s)&&(e.nodeType===1||e.nodeType===11)&&!t._util_.isXML(e)){a(e,i),l=u(e),c=u(i),h=l.length;for(var p=0;p<h;p++)c[p]&&a(l[p],c[p])}if(n){f(e,i);if(r){l=u(e),c=u(i),h=l.length;for(var p=0;p<h;p++)f(l[p],c[p])}}return i}var e=t._util_,n=e.eventBase.core,r=e.eventBase.queue,i=e.support.dom.div,s=e.support.dom.input.cloneNode(!0).checked,o=!0;return!i.addEventListener&&i.attachEvent&&i.fireEvent&&(i.attachEvent("onclick",function(){o=!1}),i.cloneNode(!0).fireEvent("onclick")),function(e,t){return e=!!e,t=!!t,this.map(function(){return l(this,e,t)})}}()}),t._util_.contains=document.compareDocumentPosition?function(e,t){return!!(e.compareDocumentPosition(t)&16)}:function(e,t){if(e===t)return!1;if(e.contains&&t.contains)return e.contains(t);while(t=t.parentNode)if(t===e)return!0;return!1},t.dom.extend({contains:function(e){var n=this[0];return e=t.dom(e)[0],!n||!e?!1:t._util_.contains(n,e)}}),t._util_.smartInsertTo=function(e,n,r,i){var s=t.dom(n),o=s[0],u;if(i&&o&&(!o.parentNode||o.parentNode.nodeType===11))i=i==="before",u=t.merge(i?e:s,i?s:e),e!==u&&(e.length=0,t.merge(e,u));else for(var a=0,f;f=s[a];a++)t._util_.smartInsert(t.dom(f),a>0?e.clone(!0,!0):e,r)},t.dom.extend({appendTo:function(e){var n=[],r=n.push;return t.check("^(?:string|HTMLElement|\\$DOM)$","baidu.dom.appendTo"),t._util_.smartInsertTo(this,e,function(e){r.apply(n,t.makeArray(e.childNodes)),this.appendChild(e)}),this.pushStack(n)}}),t._util_.access=function(e,n,r,i,s){if(e.size()<=0)return e;switch(t.type(n)){case"string":if(r===undefined)return i.call(e,e[0],n);e.each(function(o,u){i.call(e,u,n,t.type(r)==="function"?r.call(u,o,i.call(e,u,n)):r,s)});break;case"object":for(var o in n)t._util_.access(e,o,n[o],i,r)}return e},t._util_.nodeName=function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},t._util_.propFixer={tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",classname:"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable",rboolean:/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i},!document.createElement("form").enctype&&(t._util_.propFixer.enctype="encoding"),t._util_.prop=function(){var e=/^(?:button|input|object|select|textarea)$/i,n=/^a(?:rea|)$/i,r=document.createElement("select"),i=r.appendChild(document.createElement("option")),s={tabIndex:{get:function(t){var r=t.getAttributeNode("tabindex");return r&&r.specified?parseInt(r.value,10):e.test(t.nodeName)||n.test(t.nodeName)&&t.href?0:undefined}}};return!i.selected&&(s.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}}),r=i=null,function(e,n,r){var i=e.nodeType,o,u;if(!e||~"238".indexOf(i))return;if(i!==1||!t._util_.isXML(e))n=t._util_.propFixer[n]||n,o=s[n]||{};return r!==undefined?o.set&&(u=o.set(e,n,r))!==undefined?u:e[n]=r:o.get&&(u=o.get(e,n))!==null?u:e[n]}}(),t._util_.support.getSetAttribute=t._util_.support.dom.div.className!=="t",t._util_.nodeHook=function(){if(t._util_.support.getSetAttribute)return;var e={};return e.name=e.id=e.coords=!0,{get:function(t,n){var r=t.getAttributeNode(n);return r&&(e[n]?r.value!=="":r.specified)?r.value:undefined},set:function(e,t,n){var r=e.getAttributeNode(t);return r||(r=document.createAttribute(t),e.setAttributeNode(r)),r.value=n+""}}}(),t._util_.removeAttr=function(){var e=t._util_.propFixer,n=/\s+/,r=t._util_.support.getSetAttribute;return function(i,s){if(!s||i.nodeType!==1)return;var o=s.split(n),u,a;for(var f=0,l;l=o[f];f++)u=e[l]||l,a=e.rboolean.test(l),!a&&t._util_.attr(i,l,""),i.removeAttribute(r?l:u),a&&u in i&&(i[u]=!1)}}(),t._util_.attr=function(){var e=t._util_,n=/^(?:button|input)$/i,r=e.support.dom,i=r.input.value==="t",s=r.a.getAttribute("href")==="/a",o=/top/.test(r.a.getAttribute("style")),u=e.nodeHook,a={className:"class"},f={get:function(t,n){var r=e.prop(t,n),i;return r===!0||typeof r!="boolean"&&(i=t.getAttributeNode(n))&&i.nodeValue!==!1?n.toLowerCase():undefined},set:function(t,n,r){if(r===!1)e.removeAttr(t,n);else{var i=e.propFixer[n]||n;i in t&&(t[i]=!0),t.setAttribute(n,n.toLowerCase())}return n}},l={type:{set:function(t,r,s){if(n.test(t.nodeName)&&t.parentNode)return s;if(!i&&s==="radio"&&e.nodeName(t,"input")){var o=t.value;return t.setAttribute("type",s),o&&(t.value=o),s}}},value:{get:function(t,n){return u&&e.nodeName(t,"button")?u.get(t,n):n in t?t.value:null},set:function(t,n,r){if(u&&e.nodeName(t,"button"))return u.set(t,n,r);t.value=r}}};return e.support.getSetAttribute||(t.forEach(["width","height"],function(e){l[e]={set:function(e,t,n){if(n==="")return e.setAttribute(t,"auto"),n}}}),l.contenteditable={get:u.get,set:function(e,t,n){n===""&&(n=!1),u.set(e,t,n)}}),s||t.forEach(["href","src","width","height"],function(e){l[e]={get:function(e,t){var n=e.getAttribute(t,2);return n===null?undefined:n}}}),o||(l.style={get:function(e){return e.style.cssText.toLowerCase()||undefined},set:function(e,t,n){return e.style.cssText=n+""}}),function(n,r,i,s){var o=n.nodeType,c=o!==1||!e.isXML(n),h,p;if(!n||~"238".indexOf(o))return;if(s&&t.dom.fn[r])return t.dom(n)[r](i);c&&(r=a[r]||r.toLowerCase(),h=l[r]||(e.propFixer.rboolean.test(r)?f:u));if(i!==undefined){if(i===null){e.removeAttr(n,r);return}return c&&h&&h.set&&(p=h.set(n,r,i))!==undefined?p:(n.setAttribute(r,i+""),i)}return c&&h&&h.get&&(p=h.get(n,r))!==null?p:(p=n.getAttribute(r),p===null?undefined:p)}}(),t.dom.extend({attr:function(e,n){return t._util_.access(this,e,n,function(e,n,r,i){return t._util_.attr(e,n,r,i)})}}),t.dom.extend({before:function(){return t.check("^(?:string|function|HTMLElement|\\$DOM)(?:,(?:string|array|HTMLElement|\\$DOM))*$","baidu.dom.before"),t._util_.smartInsert(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)}),this}}),t.dom.extend({bind:function(e,t,n){return this.on(e,undefined,t,n)}}),t.dom.match=function(){function r(e){var t=[],n;while(e=e.parentNode)e.nodeType&&t.push(e);for(var n=t.length-1;n>-1;n--)if(t[n].nodeType==1||t[n].nodeType==9)return t[n];return null}var e=/^[\w\#\-\$\.\*]+$/,n=document.createElement("DIV");return n.id="__tangram__",function(e,n,i){var s,o=t.array();switch(t.type(n)){case"$DOM":for(var u=e.length-1;u>-1;u--)for(var a=n.length-1;a>-1;a--)e[u]===n[a]&&o.push(e[u]);break;case"function":t.forEach(e,function(e,t){n.call(e,t)&&o.push(e)});break;case"HTMLElement":t.forEach(e,function(e){e==n&&o.push(e)});break;case"string":var f=t.query(n,i||document);t.forEach(e,function(e){if(s=r(e)){var i=s.nodeType==1?t.query(n,s):f;for(var u=0,a=i.length;u<a;u++)if(i[u]===e){o.push(e);break}}}),o=o.unique();break;default:o=t.array(e).unique()}return o}}(),t.dom.extend({children:function(e){var n=[];return this.each(function(){t.forEach(this.children||this.childNodes,function(e){e.nodeType==1&&n.push(e)})}),this.pushStack(t.dom.match(n,e))}}),t.dom.extend({closest:function(e,n){var r=t.array();return t.forEach(this,function(i){var s=[i];while(i=i.parentNode)i.nodeType&&s.push(i);s=t.dom.match(s,e,n),s.length&&r.push(s[0])}),this.pushStack(r.unique())}}),t.dom.extend({contents:function(){var e=[],n;for(var r=0,i;i=this[r];r++)n=i.nodeName,e.push.apply(e,t.makeArray(n&&n.toLowerCase()==="iframe"?i.contentDocument||i.contentWindow.document:i.childNodes));return this.pushStack(e)}}),t.dom.extend({getComputedStyle:function(e){if(!this[0].ownerDocument)return;var t=this[0].ownerDocument.defaultView,n=t&&t.getComputedStyle&&t.getComputedStyle(this[0],null),r=n?n.getPropertyValue(e)||n[e]:"";return r||this[0].style[e]}}),t.dom.extend({getCurrentStyle:function(){var e=document.documentElement.currentStyle?function(e){return this[0].currentStyle?this[0].currentStyle[e]:this[0].style[e]}:function(e){return this.getComputedStyle(e)};return function(t){return e.call(this,t)}}()}),t._util_.getWidthOrHeight=function(){function i(e,t){var n={};for(var r in t)n[r]=e.style[r],e.style[r]=t[r];return n}var e={},n={position:"absolute",visibility:"hidden",display:"block"},r=/^(none|table(?!-c[ea]).+)/;return t.forEach(["Width","Height"],function(s){var o={Width:["Right","Left"],Height:["Top","Bottom"]}[s];e["get"+s]=function(e,u){var a=t.dom(e),f=e.offsetWidth===0&&r.test(a.getCurrentStyle("display"))&&i(e,n),l=e["offset"+s]||parseInt(a.getCurrentStyle(s.toLowerCase()))||0,c="padding|border";return u&&t.forEach(u.split("|"),function(e){~c.indexOf(e)?c=c.replace(new RegExp("\\|?"+e+"\\|?"),""):(l+=parseFloat(a.getCurrentStyle(e+o[0]))||0,l+=parseFloat(a.getCurrentStyle(e+o[1]))||0)}),c&&t.forEach(c.split("|"),function(e){l-=parseFloat(a.getCurrentStyle(e+o[0]+(e==="border"?"Width":"")))||0,l-=parseFloat(a.getCurrentStyle(e+o[1]+(e==="border"?"Width":"")))||0}),f&&i(e,f),l}}),function(t,n,r){return e[n==="width"?"getWidth":"getHeight"](t,r)}}(),t._util_.setPositiveNumber=function(){var e=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,t=new RegExp("^("+e+")(.*)$","i");return function(e,n,r){var i=t.exec(n);return i?Math.max(0,i[1]-(r||0))+(i[2]||"px"):n}}(),t._util_.style=t.extend({set:function(e,t,n){e.style[t]=n}},document.documentElement.currentStyle?{get:function(e,n){var r=t.dom(e).getCurrentStyle(n),i;return/^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i.test(r)&&(i=e.style.left,e.style.left=n==="fontSize"?"1em":r,r=e.style.pixelLeft+"px",e.style.left=i),r}}:{get:function(e,n){return t.dom(e).getCurrentStyle(n)}}),t._util_.cssHooks=function(){function o(e,r,i){t.type(i)==="string"&&(i=t._util_.setPositiveNumber(e,i)),n.set(e,r,i)}var e=/alpha\s*\(\s*opacity\s*=\s*([^)]*)/i,n=t._util_.style,r=t._util_.support.dom.a,i={fontWeight:{normal:400,bold:700,bolder:700,lighter:100}},s={opacity:{},width:{},height:{},fontWeight:{get:function(e,t){var r=n.get(e,t);return i.fontWeight[r]||r}}};return t.extend(s.opacity,/^0.5/.test(r.style.opacity)?{get:function(e,n){var r=t.dom(e).getCurrentStyle(n);return r===""?"1":r}}:{get:function(t){return e.test((t.currentStyle||t.style).filter||"")?parseFloat(RegExp.$1)/100+"":"1"},set:function(t,n,r){var i=(t.currentStyle||t.style).filter||"",s=r*100;t.style.zoom=1,t.style.filter=e.test(i)?i.replace(e,"Alpha(opacity="+s):i+" progid:dximagetransform.microsoft.Alpha(opacity="+s+")"}}),t.forEach(["width","height"],function(e){s[e]={get:function(n){return t._util_.getWidthOrHeight(n,e)+"px"},set:o}}),t.each({padding:"",border:"Width"},function(e,t){s[e+t]={set:o};var n=["Top","Right","Bottom","Left"],r=0;for(;r<4;r++)s[e+n[r]+t]={set:o}}),s}(),t._util_.cssNumber={columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},t.string.extend({toCamelCase:function(){var e=this.valueOf();return e.indexOf("-")<0&&e.indexOf("_")<0?e:e.replace(/[-_][^-_]/g,function(e){return e.charAt(1).toUpperCase()})}}),t.dom.styleFixer=function(){var e=t._util_.style,n=t._util_.cssHooks,r=t._util_.cssNumber,i={"float":t._util_.support.dom.a.style.cssFloat?"cssFloat":"styleFloat"};return function(s,o,u){var a=t.string.toCamelCase(o),f=u===undefined?"get":"set",l,c;return a=i[a]||a,l=t.type(u)==="number"&&!r[a]?u+"px":u,c=n.hasOwnProperty(a)&&n[a][f]||e[f],c(s,a,l)}}(),t.dom.extend({css:function(e,n){return t.check("^(?:(?:string(?:,(?:number|string|function))?)|object)$","baidu.dom.css"),t._util_.access(this,e,n,function(e,n,r){var i=t.dom.styleFixer;return i?i(e,n,r):r===undefined?this.getCurrentStyle(n):e.style[n]=r})}}),t.dom.extend({data:function(){var e=t.key,n=t.global("_maps_HTMLElementData");return function(r,i){t.forEach(this,function(n){!n[e]&&(n[e]=t.id())});if(t.isString(r)){if(typeof i=="undefined"){var s,o;o=this[0]&&(s=n[this[0][e]])&&s[r];if(typeof o!="undefined")return o;var u=this[0].getAttribute("data-"+r);return~String(u).indexOf("{")?Function("return "+u)():u}t.forEach(this,function(t){var s=n[t[e]]=n[t[e]]||{};s[r]=i})}else t.type(r)=="object"&&t.forEach(this,function(i){var s=n[i[e]]=n[i[e]]||{};t.forEach(r,function(e,t){s[t]=r[t]})});return this}}()}),t.lang.Class=t.base.Class,t.lang.Event=t.base.Event,t.dom.extend({delegate:function(e,t,n,r){return typeof n=="function"&&(r=n,n=null),this.on(t,e,n,r)}}),t.dom.extend({filter:function(e){return this.pushStack(t.dom.match(this,e))}}),t.dom.extend({remove:function(e,n){arguments.length>0&&t.check("^string(?:,boolean)?$","baidu.dom.remove");var r=e?this.filter(e):this;for(var i=0,s;s=r[i];i++)!n&&s.nodeType===1&&(t._util_.cleanData(s.getElementsByTagName("*")),t._util_.cleanData([s])),s.parentNode&&s.parentNode.removeChild(s);return this}}),t.dom.extend({detach:function(e){return e&&t.check("^string$","baidu.dom.detach"),this.remove(e,!0)}}),t.object.extend=t.extend,t.dom.getStyle=function(e,n){return t.dom(t.dom.g(e)).css(n)},t.page=t.page||{},t.page.getScrollTop=function(){var e=document;return window.pageYOffset||e.documentElement.scrollTop||e.body.scrollTop},t.page.getScrollLeft=function(){var e=document;return window.pageXOffset||e.documentElement.scrollLeft||e.body.scrollLeft},function(){t.page.getMousePosition=function(){return{x:t.page.getScrollLeft()+e.x,y:t.page.getScrollTop()+e.y}};var e={x:0,y:0};t.event.on(document,"onmousemove",function(t){t=window.event||t,e.x=t.clientX,e.y=t.clientY})}(),t.dom.extend({off:function(e,n,r){var i=t._util_.eventBase.core,s=this;return e?typeof e=="string"?(typeof n=="function"&&(r=n,n=null),e=e.split(/[ ,]/),t.forEach(this,function(s){t.forEach(e,function(e){i.remove(s,e,r,n)})})):typeof e=="object"&&t.forEach(e,function(e,t){s.off(t,n,e)}):t.forEach(this,function(e){i.remove(e)}),this}}),t.event.un=t.un=function(e,n,r){return typeof e=="string"&&(e=t.dom.g(e)),t.dom(e).off(n.replace(/^\s*on/,""),r),e},t.event.preventDefault=function(e){return(new t.event(e)).preventDefault()},function(){function h(){e=!1,clearInterval(o),r.capture&&n.releaseCapture?n.releaseCapture():r.capture&&window.releaseEvents&&window.releaseEvents(Event.MOUSEMOVE|Event.MOUSEUP),document.body.style.MozUserSelect=c;var i=t.dom(document);i.off("selectstart",d),r.autoStop&&i.off("mouseup",h),t.isFunction(r.ondragend)&&r.ondragend(n,r,{left:f,top:l})}function p(c){if(!e){clearInterval(o);return}var h=r.range||[],p=t.page.getMousePosition(),d=u+p.x-i,v=a+p.y-s;t.isObject(h)&&h.length==4&&(d=Math.max(h[3],d),d=Math.min(h[1]-n.offsetWidth,d),v=Math.max(h[0],v),v=Math.min(h[2]-n.offsetHeight,v)),n.style.left=d+"px",n.style.top=v+"px",f=d,l=v,t.isFunction(r.ondrag)&&r.ondrag(n,r,{left:f,top:l})}function d(e){return t.event.preventDefault(e,!1)}var e=!1,n,r,i,s,o,u,a,f,l,c;t.dom.drag=function(v,m){if(!(n=t.dom.g(v)))return!1;r=t.object.extend({autoStop:!0,capture:!0,interval:16},m),f=u=parseInt(t.dom.getStyle(n,"left"))||0,l=a=parseInt(t.dom.getStyle(n,"top"))||0,e=!0,setTimeout(function(){var e=t.page.getMousePosition();i=r.mouseEvent?t.page.getScrollLeft()+r.mouseEvent.clientX:e.x,s=r.mouseEvent?t.page.getScrollTop()+r.mouseEvent.clientY:e.y,clearInterval(o),o=setInterval(p,r.interval)},1);var g=t.dom(document);return r.autoStop&&g.on("mouseup",h),g.on("selectstart",d),r.capture&&n.setCapture?n.setCapture():r.capture&&window.captureEvents&&window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP),c=document.body.style.MozUserSelect,document.body.style.MozUserSelect="none",t.isFunction(r.ondragstart)&&r.ondragstart(n,r),{stop:h,dispose:h,update:function(e){t.object.extend(r,e)}}}}(),t.lang.isFunction=t.isFunction,t.dom.extend({end:function(){return this.prevObject||t.dom()}}),t.dom.extend({eq:function(e){t.check("number","baidu.dom.eq");var n=this.get(e);return this.pushStack(typeof n=="undefined"?[]:[n])}}),t.dom.extend({find:function(e){var n=[],r,i="__tangram__find__",s=[];switch(t.type(e)){case"string":this.each(function(){t.merge(s,t.query(e,this))});break;case"HTMLElement":r=e.tagName+"#"+(e.id?e.id:e.id=i),this.each(function(){t.query(r,this).length>0&&n.push(e)}),e.id==i&&(e.id=""),n.length>0&&t.merge(s,n);break;case"$DOM":n=e.get(),this.each(function(){t.forEach(t.query("*",this),function(e){for(var t=0,r=n.length;t<r;t++)e===n[t]&&(s[s.length++]=n[t])})})}return this.pushStack(s)}}),t.dom.extend({first:function(){return this.eq(0)}}),t.dom.getAttr=function(e,n){return t.dom(t.dom.g(e)).attr(n)},t.dom.extend({getWindow:function(){var e=this.getDocument();return this.size()<=0?undefined:e.parentWindow||e.defaultView}}),t.dom.extend({offsetParent:function(){return this.map(function(){var e=this.offsetParent||document.body,n=/^(?:body|html)$/i;while(e&&t.dom(e).getCurrentStyle("position")==="static"&&!n.test(e.nodeName))e=e.offsetParent;return e})}}),t.dom.extend({position:function(){if(this.size()<=0)return 0;var e=/^(?:body|html)$/i,t=this.offset(),n=this.offsetParent(),r=e.test(n[0].nodeName)?{left:0,top:0}:n.offset();return t.left-=parseFloat(this.getCurrentStyle("marginLeft"))||0,t.top-=parseFloat(this.getCurrentStyle("marginTop"))||0,r.left+=parseFloat(n.getCurrentStyle("borderLeftWidth"))||0,r.top+=parseFloat(n.getCurrentStyle("borderTopWidth"))||0,{left:t.left-r.left,top:t.top-r.top}}}),t.dom.extend({offset:function(){function e(e,n,r){var i=i=t.dom(e),s=i.getCurrentStyle("position");s==="static"&&(e.style.position="relative");var o=i.offset(),u=i.getCurrentStyle("left"),a=i.getCurrentStyle("top"),f=~"absolute|fixed".indexOf(s)&&~(""+u+a).indexOf("auto"),l=f&&i.position();u=l&&l.left||parseFloat(u)||0,a=l&&l.top||parseFloat(a)||0,t.type("options")==="function"&&(n=n.call(e,r,o)),n.left!=undefined&&(e.style.left=n.left-o.left+u+"px"),n.top!=undefined&&(e.style.top=n.top-o.top+a+"px")}return function(n){if(n){t.check("^(?:object|function)$","baidu.dom.offset");for(var r=0,i;i=this[r];r++)e(i,n,r);return this}var s=this[0],o=this.getDocument(),u={left:0,top:0},a,f;if(!o)return;return f=o.documentElement,t._util_.contains(f,s)?(typeof s.getBoundingClientRect!="undefined"&&(u=s.getBoundingClientRect()),a=this.getWindow(),{left:u.left+(a.pageXOffset||f.scrollLeft)-(f.clientLeft||0),top:u.top+(a.pageYOffset||f.scrollTop)-(f.clientTop||0)}):u}}()}),t.dom.extend({has:function(e){var n=[],r=t.dom(document.body);return t.forEach(this,function(t){r[0]=t,r.find(e).length&&n.push(t)}),t.dom(n)}}),t.dom.extend({hasClass:function(e){if(arguments.length<=0||typeof e=="function")return this;if(this.size()<=0)return!1;e=e.replace(/^\s+/g,"").replace(/\s+$/g,"").replace(/\s+/g," ");var n=e.split(" "),r;return t.forEach(this,function(e){var t=e.className;for(var i=0;i<n.length;i++)if(!~(" "+t+" ").indexOf(" "+n[i]+" ")){r=!1;return}if(r!==!1){r=!0;return}}),r}}),t._util_.getWindowOrDocumentWidthOrHeight=t._util_.getWindowOrDocumentWidthOrHeight||function(){var e={window:{},document:{}};return t.forEach(["Width","Height"],function(n){var r="client"+n,i="offset"+n,s="scroll"+n;e.window["get"+n]=function(e){var n=e.document,i=n.documentElement[r];return t.browser.isStrict&&i||n.body&&n.body[r]||i},e.document["get"+n]=function(e){var t=e.documentElement;return t[r]>=t[s]?t[r]:Math.max(e.body[s],t[s],e.body[i],t[i])}}),function(t,n,r){return e[n][r==="width"?"getWidth":"getHeight"](t)}}(),t.dom.extend({height:function(e){return t._util_.access(this,"height",e,function(e,n,r){var i=r!==undefined,s=i&&parseFloat(r),o=e!=null&&e==e.window?"window":e.nodeType===9?"document":!1;if(i&&s<0||isNaN(s))return;return i&&/^(?:\d*\.)?\d+$/.test(r+="")&&(r+="px"),o?t._util_.getWindowOrDocumentWidthOrHeight(e,o,n):i?e.style.height=r:t._util_.getWidthOrHeight(e,n)})}}),t._util_.isHidden=function(e){return t.dom(e).getCurrentStyle("display")==="none"||!t._util_.contains(e.ownerDocument,e)},t.dom.extend({hide:function(){var e=[],n,r,i;return this.each(function(s,o){if(!o.style)return;n=t(o),e[s]=n.data("olddisplay"),i=o.style.display,e[s]||(r=t._util_.isHidden(o),(i&&i!=="none"||!r)&&n.data("olddisplay",r?i:n.getCurrentStyle("display"))),o.style.display="none"})}}),t.dom.extend({innerHeight:function(){if(this.size()<=0)return 0;var e=this[0],n=e!=null&&e===e.window?"window":e.nodeType===9?"document":!1;return n?t._util_.getWindowOrDocumentWidthOrHeight(e,n,"height"):t._util_.getWidthOrHeight(e,"height","padding")}}),t.dom.extend({innerWidth:function(){if(this.size()<=0)return 0;var e=this[0],n=e!=null&&e===e.window?"window":e.nodeType===9?"document":!1;return n?t._util_.getWindowOrDocumentWidthOrHeight(e,n,"width"):t._util_.getWidthOrHeight(e,"width","padding")}}),t.dom.extend({insertAfter:function(e){var n=[],r=n.push;return t.check("^(?:string|HTMLElement|\\$DOM)$","baidu.dom.insertAfter"),t._util_.smartInsertTo(this,e,function(e){r.apply(n,t.makeArray(e.childNodes)),this.parentNode.insertBefore(e,this.nextSibling)},"after"),this.pushStack(n)}}),t.dom.extend({insertBefore:function(e){var n=[],r=n.push;return t.check("^(?:string|HTMLElement|\\$DOM)$","baidu.dom.insertBefore"),t._util_.smartInsertTo(this,e,function(e){r.apply(n,t.makeArray(e.childNodes)),this.parentNode.insertBefore(e,this)},"before"),this.pushStack(n)}}),t.dom.extend({insertHTML:function(e,n){var r,i,s=this[0];return s.insertAdjacentHTML&&!t.browser.opera?s.insertAdjacentHTML(e,n):(r=s.ownerDocument.createRange(),e=e.toUpperCase(),e=="AFTERBEGIN"||e=="BEFOREEND"?(r.selectNodeContents(s),r.collapse(e=="AFTERBEGIN")):(i=e=="BEFOREBEGIN",r[i?"setStartBefore":"setEndAfter"](s),r.collapse(i)),r.insertNode(r.createContextualFragment(n))),s}}),t.dom.extend({is:function(e){return t.dom.match(this,e).length>0}}),t.dom.extend({last:function(){return this.eq(-1)}}),t.dom.extend({next:function(e){var n=[];return t.forEach(this,function(e){while((e=e.nextSibling)&&e&&e.nodeType!=1);e&&(n[n.length++]=e)}),this.pushStack(e?t.dom.match(n,e):n)}}),t.dom.extend({nextAll:function(e){var n=[];return t.forEach(this,function(e){while(e=e.nextSibling)e&&e.nodeType==1&&n.push(e)}),this.pushStack(t.dom.match(n,e))}}),t.dom.extend({nextUntil:function(e,n){var r=t.array();return t.forEach(this,function(n){var i=t.array();while(n=n.nextSibling)n&&n.nodeType==1&&i.push(n);if(e&&i.length){var s=t.dom.match(i,e);s.length&&(i=i.slice(0,i.indexOf(s[0])))}t.merge(r,i)}),this.pushStack(t.dom.match(r,n))}}),t.dom.extend({not:function(e){var n,r,i,s=this.get(),o=t.isArray(e)?e:t.dom.match(this,e);for(n=s.length-1;n>-1;n--)for(r=0,i=o.length;r<i;r++)o[r]===s[n]&&s.splice(n,1);return this.pushStack(s)}}),t.dom.extend({one:function(e,t,n,r){return this.on(e,t,n,r,1)}}),t.dom.extend({outerHeight:function(e){if(this.size()<=0)return 0;var n=this[0],r=n!=null&&n===n.window?"window":n.nodeType===9?"document":!1;return r?t._util_.getWindowOrDocumentWidthOrHeight(n,r,"height"):t._util_.getWidthOrHeight(n,"height","padding|border"+(e?"|margin":""))}}),t.dom.extend({outerWidth:function(e){if(this.size()<=0)return 0;var n=this[0],r=n!=null&&n===n.window?"window":n.nodeType===9?"document":!1;return r?t._util_.getWindowOrDocumentWidthOrHeight(n,r,"width"):t._util_.getWidthOrHeight(n,"width","padding|border"+(e?"|margin":""))}}),t.dom.extend({parent:function(e){var n=[];return t.forEach(this,function(e){(e=e.parentNode)&&e.nodeType==1&&n.push(e)}),this.pushStack(t.dom.match(n,e))}}),t.dom.extend({parents:function(e){var n=[];return t.forEach(this,function(e){var r=[];while((e=e.parentNode)&&e.nodeType==1)r.push(e);t.merge(n,r)}),this.pushStack(t.dom.match(n,e))}}),t.dom.extend({parentsUntil:function(e,n){t.check("(string|HTMLElement)(,.+)?","baidu.dom.parentsUntil");var r=[];return t.forEach(this,function(n){var i=t.array();while((n=n.parentNode)&&n.nodeType==1)i.push(n);if(e&&i.length){var s=t.dom.match(i,e);s.length&&(i=i.slice(0,i.indexOf(s[0])))}t.merge(r,i)}),this.pushStack(t.dom.match(r,n))}}),t.dom.extend({prepend:function(){return t.check("^(?:string|function|HTMLElement|\\$DOM)(?:,(?:string|array|HTMLElement|\\$DOM))*$","baidu.dom.prepend"),t._util_.smartInsert(this,arguments,function(e){this.nodeType===1&&this.insertBefore(e,this.firstChild)}),this}}),t.dom.extend({prependTo:function(e){var n=[],r=n.push;return t.check("^(?:string|HTMLElement|\\$DOM)$","baidu.dom.prependTo"),t._util_.smartInsertTo(this,e,function(e){r.apply(n,t.makeArray(e.childNodes)),this.insertBefore(e,this.firstChild)}),this.pushStack(n)}}),t.dom.extend({prev:function(e){var n=[];return t.forEach(this,function(e){while(e=e.previousSibling)if(e.nodeType==1){n.push(e);break}}),this.pushStack(t.dom.match(n,e))}}),t.dom.extend({prevAll:function(e){var n=t.array();return t.forEach(this,function(e){var r=[];while(e=e.previousSibling)e.nodeType==1&&r.push(e);t.merge(n,r.reverse())}),this.pushStack(typeof e=="string"?t.dom.match(n,e):n.unique())}}),t.dom.extend({prevUntil:function(e,n){t.check("(string|HTMLElement)(,.+)?","baidu.dom.prevUntil");var r=[];return t.forEach(this,function(n){var i=t.array();while(n=n.previousSibling)n&&n.nodeType==1&&i.push(n);if(e&&i.length){var s=t.dom.match(i,e);s.length&&(i=i.slice(0,i.indexOf(s[0])))}t.merge(r,i)}),this.pushStack(t.dom.match(r,n))}}),t.dom.extend({prop:function(e,n){return t._util_.access(this,e,n,function(e,n,r){return t._util_.prop(e,n,r)})}}),t.string.extend({escapeReg:function(){return this.replace(new RegExp("([.*+?^=!:${}()|[\\]/\\\\])","g"),"\\$1")}}),void function(e,n){function W(e,t,n,r){var i,u,a,f,l=o++,c=0,h=t.length;typeof n=="string"&&!d.test(n)&&(n=n.toLowerCase(),f=n);for(;c<h;c++){i=t[c];if(i){u=!1,i=i[e];while(i){if(i[s]===l){u=t[i.sizset];break}a=i.nodeType===1,a&&!r&&(i[s]=l,i.sizset=c);if(f){if(i.nodeName.toLowerCase()===n){u=i;break}}else if(a)if(typeof n!="string"){if(i===n){u=!0;break}}else if(F(n,[i]).length>0){u=i;break}i=i[e]}t[c]=u}}}t.query=function(e,n,r){return t.merge(r||[],t.sizzle(e,n))};var r=e.document,i=r.documentElement,s="sizcache"+(Math.random()+"").replace(".",""),o=0,u=Object.prototype.toString,a="undefined",f=!1,l=!0,c=/^#([\w\-]+$)|^(\w+$)|^\.([\w\-]+$)/,h=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,p=/\\/g,d=/\W/,v=/^\w/,m=/\D/,g=/(-?)(\d*)(?:n([+\-]?\d*))?/,y=/^\+|\s*/g
    -,b=/h\d/i,w=/input|select|textarea|button/i,E=/[\t\n\f\r]/g,S="(?:[-\\w]|[^\\x00-\\xa0]|\\\\.)",x={ID:new RegExp("#("+S+"+)"),CLASS:new RegExp("\\.("+S+"+)"),NAME:new RegExp("\\[name=['\"]*("+S+"+)['\"]*\\]"),TAG:new RegExp("^("+S.replace("[-","[-\\*")+"+)"),ATTR:new RegExp("\\[\\s*("+S+"+)\\s*(?:(\\S?=)\\s*(?:(['\"])(.*?)\\3|(#?"+S+"*)|)|)\\s*\\]"),PSEUDO:new RegExp(":("+S+"+)(?:\\((['\"]?)((?:\\([^\\)]+\\)|[^\\(\\)]*)+)\\2\\))?"),CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/},T=x.POS,N=function(){var e,t=function(e,t){return"\\"+(t-0+1)},n={};for(e in x)x[e]=new RegExp(x[e].source+/(?![^\[]*\])(?![^\(]*\))/.source),n[e]=new RegExp(/(^(?:.|\r|\n)*?)/.source+x[e].source.replace(/\\(\d+)/g,t));return x.globalPOS=T,n}(),C=function(e){var t=!1,n=r.createElement("div");try{t=e(n)}catch(i){}return n=null,t},k=C(function(e){var t=!0,n="script"+(new Date).getTime();return e.innerHTML="<a name ='"+n+"'/>",i.insertBefore(e,i.firstChild),r.getElementById(n)&&(t=!1),i.removeChild(e),t}),L=C(function(e){return e.appendChild(r.createComment("")),e.getElementsByTagName("*").length===0}),A=C(function(e){return e.innerHTML="<a href='#'></a>",e.firstChild&&typeof e.firstChild.getAttribute!==a&&e.firstChild.getAttribute("href")==="#"}),O=C(function(e){return e.innerHTML="<div class='test e'></div><div class='test'></div>",!e.getElementsByClassName||e.getElementsByClassName("e").length===0?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length!==1)});[0,0].sort(function(){return l=!1,0});var M=function(e,i,s){s=s||[],i=i||r;var o,u,a,f=i.nodeType;if(f!==1&&f!==9)return[];if(!e||typeof e!="string")return s;e=t.string(e).trim();if(!e)return s;a=D(i);if(!a)if(o=c.exec(e))if(o[1]){if(f===9){u=i.getElementById(o[1]);if(!u||!u.parentNode)return P([],s);if(u.id===o[1])return P([u],s)}else if(i.ownerDocument&&(u=i.ownerDocument.getElementById(o[1]))&&B(i,u)&&u.id===o[1])return P([u],s)}else{if(o[2])return e==="body"&&i.body?P([i.body],s):P(i.getElementsByTagName(e),s);if(O&&o[3]&&i.getElementsByClassName)return P(i.getElementsByClassName(o[3]),s)}return _(e,i,s,n,a)},_=function(e,t,n,r,i){var s,o,a,f,l,c,p,d,v=t,m=!0,g=[],y=e;do{h.exec(""),s=h.exec(y);if(s){y=s[3],g.push(s[1]);if(s[2]){f=s[3];break}}}while(s);if(g.length>1&&T.exec(e))if(g.length===2&&R.relative[g[0]])o=X(g[0]+g[1],t,r,i);else{o=R.relative[g[0]]?[t]:M(g.shift(),t);while(g.length)e=g.shift(),R.relative[e]&&(e+=g.shift()),o=X(e,o,r,i)}else{!r&&g.length>1&&t.nodeType===9&&!i&&x.ID.test(g[0])&&!x.ID.test(g[g.length-1])&&(l=j(g.shift(),t,i),t=l.expr?F(l.expr,l.set)[0]:l.set[0]);if(t){l=r?{expr:g.pop(),set:P(r)}:j(g.pop(),g.length>=1&&(g[0]==="~"||g[0]==="+")&&t.parentNode||t,i),o=l.expr?F(l.expr,l.set):l.set,g.length>0?a=P(o):m=!1;while(g.length)c=g.pop(),p=c,R.relative[c]?p=g.pop():c="",p==null&&(p=t),R.relative[c](a,p,i)}else a=g=[]}a||(a=o),a||I(c||e);if(u.call(a)==="[object Array]")if(!m)n.push.apply(n,a);else if(t&&t.nodeType===1)for(d=0;a[d]!=null;d++)a[d]&&(a[d]===!0||a[d].nodeType===1&&B(t,a[d]))&&n.push(o[d]);else for(d=0;a[d]!=null;d++)a[d]&&a[d].nodeType===1&&n.push(o[d]);else P(a,n);return f&&(_(f,v,n,r,i),H(n)),n},D=t._util_.isXML,P=t.makeArray,H=function(e){if(U){f=l,e.sort(U);if(f)for(var t=1;t<e.length;t++)e[t]===e[t-1]&&e.splice(t--,1)}return e},B=t._util_.contains,j=function(e,t,n){var r,i,s,o,u,f;if(!e)return[];for(i=0,s=R.order.length;i<s;i++){u=R.order[i];if(o=N[u].exec(e)){f=o[1],o.splice(1,1);if(f.substr(f.length-1)!=="\\"){o[1]=(o[1]||"").replace(p,""),r=R.find[u](o,t,n);if(r!=null){e=e.replace(x[u],"");break}}}}return r||(r=typeof t.getElementsByTagName!==a?t.getElementsByTagName("*"):[]),{set:r,expr:e}},F=function(e,t,r,i){var s,o,u,a,f,l,c,h,p,d=e,v=[],m=t,g=t&&t[0]&&D(t[0]);while(e&&t.length){for(u in R.filter)if((s=N[u].exec(e))!=null&&s[2]){l=R.filter[u],c=s[1],o=!1,s.splice(1,1);if(c.substr(c.length-1)==="\\")continue;m===v&&(v=[]);if(R.preFilter[u]){s=R.preFilter[u](s,m,r,v,i,g);if(!s)o=a=!0;else if(s===!0)continue}if(s)for(h=0;(f=m[h])!=null;h++)f&&(a=l(f,s,h,m),p=i^a,r&&a!=null?p?o=!0:m[h]=!1:p&&(v.push(f),o=!0));if(a!==n){r||(m=v),e=e.replace(x[u],"");if(!o)return[];break}}if(e===d){if(o!=null)break;I(e)}d=e}return m},I=function(e){throw new Error(e)},q=function(e){var t,n,r=e.nodeType,i="";if(r){if(r===1||r===9||r===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)i+=q(e)}else if(r===3||r===4)return e.nodeValue}else for(t=0;n=e[t];t++)n.nodeType!==8&&(i+=q(n));return i},R={match:x,leftMatch:N,order:["ID","NAME","TAG"],attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:A?function(e){return e.getAttribute("href")}:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},relative:{"+":function(e,t){var n=typeof t=="string",r=n&&!d.test(t),i=n&&!r;r&&(t=t.toLowerCase());for(var s=0,o=e.length,u;s<o;s++)if(u=e[s]){while((u=u.previousSibling)&&u.nodeType!==1);e[s]=i||u&&u.nodeName.toLowerCase()===t?u||!1:u===t}i&&F(t,e,!0)},">":function(e,t){var n,r=typeof t=="string",i=0,s=e.length;if(r&&!d.test(t)){t=t.toLowerCase();for(;i<s;i++){n=e[i];if(n){var o=n.parentNode;e[i]=o.nodeName.toLowerCase()===t?o:!1}}}else{for(;i<s;i++)n=e[i],n&&(e[i]=r?n.parentNode:n.parentNode===t);r&&F(t,e,!0)}},"":function(e,t,n){W("parentNode",e,t,n)},"~":function(e,t,n){W("previousSibling",e,t,n)}},find:{ID:k?function(e,t,n){if(typeof t.getElementById!==a&&!n){var r=t.getElementById(e[1]);return r&&r.parentNode?[r]:[]}}:function(e,t,r){if(typeof t.getElementById!==a&&!r){var i=t.getElementById(e[1]);return i?i.id===e[1]||typeof i.getAttributeNode!==a&&i.getAttributeNode("id").nodeValue===e[1]?[i]:n:[]}},NAME:function(e,t){if(typeof t.getElementsByName!==a){var n=[],r=t.getElementsByName(e[1]),i=0,s=r.length;for(;i<s;i++)r[i].getAttribute("name")===e[1]&&n.push(r[i]);return n.length===0?null:n}},TAG:L?function(e,t){if(typeof t.getElementsByTagName!==a)return t.getElementsByTagName(e[1])}:function(e,t){var n=t.getElementsByTagName(e[1]);if(e[1]==="*"){var r=[],i=0;for(;n[i];i++)n[i].nodeType===1&&r.push(n[i]);n=r}return n}},preFilter:{CLASS:function(e,t,n,r,i,s){e=" "+e[1].replace(p,"")+" ";if(s)return e;for(var o=0,u;(u=t[o])!=null;o++)u&&(i^(u.className&&~(" "+u.className+" ").replace(E," ").indexOf(e))?n||r.push(u):n&&(t[o]=!1));return!1},ID:function(e){return e[1].replace(p,"")},TAG:function(e,t){return e[1].replace(p,"").toLowerCase()},CHILD:function(e){if(e[1]==="nth"){e[2]||I(e[0]),e[2]=e[2].replace(y,"");var t=g.exec(e[2]==="even"&&"2n"||e[2]==="odd"&&"2n+1"||!m.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=t[1]+(t[2]||1)-0,e[3]=t[3]-0}else e[2]&&I(e[0]);return e[0]=o++,e},ATTR:function(e,t,n,r,i,s){var o=e[1]=e[1].replace(p,"");return!s&&R.attrMap[o]&&(e[1]=R.attrMap[o]),e[4]=(e[4]||e[5]||"").replace(p,""),e[2]==="~="&&(e[4]=" "+e[4]+" "),e},PSEUDO:function(e,t,n,i,s,o){if(e[1]==="not"){if(!((h.exec(e[3])||"").length>1||v.test(e[3]))){var u=F(e[3],t,n,!s);return n||i.push.apply(i,u),!1}e[3]=_(e[3],r,[],t,o)}else if(x.POS.test(e[0])||x.CHILD.test(e[0]))return!0;return e},POS:function(e){return e.unshift(!0),e}},filters:{enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!!e.firstChild},empty:function(e){return!e.firstChild},has:function(e,t,n){return!!M(n[3],e).length},header:function(e){return b.test(e.nodeName)},text:function(e){var t=e.getAttribute("type"),n=e.type;return e.nodeName.toLowerCase()==="input"&&"text"===n&&(t===null||t.toLowerCase()===n)},radio:function(e){return e.nodeName.toLowerCase()==="input"&&"radio"===e.type},checkbox:function(e){return e.nodeName.toLowerCase()==="input"&&"checkbox"===e.type},file:function(e){return e.nodeName.toLowerCase()==="input"&&"file"===e.type},password:function(e){return e.nodeName.toLowerCase()==="input"&&"password"===e.type},submit:function(e){var t=e.nodeName.toLowerCase();return(t==="input"||t==="button")&&"submit"===e.type},image:function(e){return e.nodeName.toLowerCase()==="input"&&"image"===e.type},reset:function(e){var t=e.nodeName.toLowerCase();return(t==="input"||t==="button")&&"reset"===e.type},button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&"button"===e.type||t==="button"},input:function(e){return w.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&(!!e.type||!!e.href)},active:function(e){return e===e.ownerDocument.activeElement},contains:function(e,t,n){return(e.textContent||e.innerText||q(e)).indexOf(n[3])>=0}},setFilters:{first:function(e,t){return t===0},last:function(e,t,n,r){return t===r.length-1},even:function(e,t){return t%2===0},odd:function(e,t){return t%2===1},lt:function(e,t,n){return t<n[3]-0},gt:function(e,t,n){return t>n[3]-0},nth:function(e,t,n){return n[3]-0===t},eq:function(e,t,n){return n[3]-0===t}},filter:{PSEUDO:function(e,t,n,r){var i=t[1],s=R.filters[i];if(s)return s(e,n,t,r);if(i==="not"){var o=t[3],u=0,a=o.length;for(;u<a;u++)if(o[u]===e)return!1;return!0}I(i)},CHILD:function(e,t){var n,r,i,o,u,a,f,l=t[1],c=e;switch(l){case"only":case"first":while(c=c.previousSibling)if(c.nodeType===1)return!1;if(l==="first")return!0;c=e;case"last":while(c=c.nextSibling)if(c.nodeType===1)return!1;return!0;case"nth":n=t[2],r=t[3];if(n===1&&r===0)return!0;i=t[0],o=e.parentNode;if(o&&(o[s]!==i||!e.nodeIndex)){a=0;for(c=o.firstChild;c;c=c.nextSibling)c.nodeType===1&&(c.nodeIndex=++a);o[s]=i}return f=e.nodeIndex-r,n===0?f===0:f%n===0&&f/n>=0}},ID:k?function(e,t){return e.nodeType===1&&e.getAttribute("id")===t}:function(e,t){var n=typeof e.getAttributeNode!==a&&e.getAttributeNode("id");return e.nodeType===1&&n&&n.nodeValue===t},TAG:function(e,t){return t==="*"&&e.nodeType===1||!!e.nodeName&&e.nodeName.toLowerCase()===t},CLASS:function(e,t){return(" "+(e.className||e.getAttribute("class"))+" ").indexOf(t)>-1},ATTR:function(e,t){var n=t[1],r=R.attrHandle[n]?R.attrHandle[n](e):e[n]!=null?e[n]:e.getAttribute(n),i=r+"",s=t[2],o=t[4];return r==null?s==="!=":s==="="?i===o:s==="*="?i.indexOf(o)>=0:s==="~="?(" "+i+" ").indexOf(o)>=0:o?s==="!="?i!==o:s==="^="?i.indexOf(o)===0:s==="$="?i.substr(i.length-o.length)===o:s==="|="?i===o||i.substr(0,o.length+1)===o+"-":!1:i&&r!==!1},POS:function(e,t,n,r){var i=t[2],s=R.setFilters[i];if(s)return s(e,n,t,r)}}};O&&(R.order.splice(1,0,"CLASS"),R.find.CLASS=function(e,t,n){if(typeof t.getElementsByClassName!==a&&!n)return t.getElementsByClassName(e[1])});var U,z;i.compareDocumentPosition?U=function(e,t){return e===t?(f=!0,0):!e.compareDocumentPosition||!t.compareDocumentPosition?e.compareDocumentPosition?-1:1:e.compareDocumentPosition(t)&4?-1:1}:(U=function(e,t){if(e===t)return f=!0,0;if(e.sourceIndex&&t.sourceIndex)return e.sourceIndex-t.sourceIndex;var n,r,i=[],s=[],o=e.parentNode,u=t.parentNode,a=o;if(o===u)return z(e,t);if(!o)return-1;if(!u)return 1;while(a)i.unshift(a),a=a.parentNode;a=u;while(a)s.unshift(a),a=a.parentNode;n=i.length,r=s.length;for(var l=0;l<n&&l<r;l++)if(i[l]!==s[l])return z(i[l],s[l]);return l===n?z(e,s[l],-1):z(i[l],t,1)},z=function(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}),r.querySelectorAll&&function(){var e=_,t="__sizzle__",n=/^\s*[+~]/,r=/'/g,i=[];C(function(e){e.innerHTML="<select><option selected></option></select>",e.querySelectorAll("[selected]").length||i.push("\\[[\\x20\\t\\n\\r\\f]*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),C(function(e){e.innerHTML="<p class=''></p>",e.querySelectorAll("[class^='']").length&&i.push("[*^$]=[\\x20\\t\\n\\r\\f]*(?:\"\"|'')"),e.innerHTML="<input type='hidden'>",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=i.length&&new RegExp(i.join("|")),_=function(s,o,u,a,f){if(!a&&!f&&(!i||!i.test(s)))if(o.nodeType===9)try{return P(o.querySelectorAll(s),u)}catch(l){}else if(o.nodeType===1&&o.nodeName.toLowerCase()!=="object"){var c=o,h=o.getAttribute("id"),p=h||t,d=o.parentNode,v=n.test(s);h?p=p.replace(r,"\\$&"):o.setAttribute("id",p),v&&d&&(o=d);try{if(!v||d)return P(o.querySelectorAll("[id='"+p+"'] "+s),u)}catch(l){}finally{h||c.removeAttribute("id")}}return e(s,o,u,a,f)}}();var X=function(e,t,n,r){var i,s=[],o="",u=t.nodeType?[t]:t,a=0,f=u.length;while(i=x.PSEUDO.exec(e))o+=i[0],e=e.replace(x.PSEUDO,"");R.relative[e]&&(e+="*");for(;a<f;a++)_(e,u[a],s,n,r);return F(o,s)};e.Sizzle=t.sizzle=M,t.query.matches=function(e,t){return _(e,r,[],t,D(r))}}(window),t.dom.extend({ready:function(){var e=this,n,r=window.document;t._util_.isDomReady=!1,t._util_._readyWait=1,t.dom.holdReady=function(e){e?t._util_.readyWait++:i(!0)};var i=function(e){if(e===!0?--t._util_.readyWait:t._util_.isDomReady)return;if(!r.body)return setTimeout(i,1);t._util_.isReady=!0;if(e!==!0&&--t._util_.readyWait>0)return;n.resolveWith(r),t.dom.trigger&&t.dom(r).trigger("ready").off("ready")},s=function(){r.addEventListener?(r.removeEventListener("DOMContentLoaded",s,!1),i()):r.readyState==="complete"&&(r.detachEvent("onreadystatechange",s),i())},o=function(e){if(!n){n=t.Deferred();if(r.readyState==="complete")setTimeout(i,1);else if(r.addEventListener)r.addEventListener("DOMContentLoaded",s,!1),window.addEventListener("load",i,!1);else{r.attachEvent("onreadystatechange",s),window.attachEvent("onload",i);var o=!1;try{o=window.frameElement==null&&r.documentElement}catch(u){}o&&o.doScroll&&function a(){if(!t._util_.isDomReady){try{o.doScroll("left")}catch(e){return setTimeout(a,50)}i()}}()}}return n.promise(e)};return function(t){return o().done(t),e}}()}),t.dom.extend({removeAttr:function(e){return this.each(function(n,r){t._util_.removeAttr(r,e)}),this}}),t.dom.extend({removeClass:function(e){var n=typeof e,r=" ";arguments.length||t.forEach(this,function(e){e.className=""});if(n=="string"){e=t.string.trim(e);var i=e.split(" ");t.forEach(this,function(e){var n=e.className;for(var s=0;s<i.length;s++)while(~(r+n+r).indexOf(r+i[s]+r))n=(r+n+r).replace(r+i[s]+r,r);e.className=t.string.trim(n)})}else n=="function"&&t.forEach(this,function(n,r,i){t.dom(n).removeClass(e.call(n,r,n.className))});return this}}),t.dom.extend({removeData:function(){var e=t.key,n=t.global("_maps_HTMLElementData");return function(r){return t.forEach(this,function(n){!n[e]&&(n[e]=t.id())}),t.forEach(this,function(i){var s=n[i[e]];typeof r=="string"?s&&delete s[r]:t.type(r)=="array"&&t.forEach(r,function(e){s&&delete s[e]})}),this}}()}),t.dom.extend({removeProp:function(e){return e=t._util_.propFixer[e]||e,this.each(function(t,n){try{n[e]=undefined,delete n[e]}catch(r){}}),this}}),t._util_.smartScroll=function(e){function s(e){return e&&e.nodeType===9}function o(e){return t.type(e)=="Window"?e:s(e)?e.defaultView||e.parentWindow:!1}var n={scrollLeft:"pageXOffset",scrollTop:"pageYOffset"}[e],r=e==="scrollLeft",i={};return{get:function(r){var i=o(r);return i?n in i?i[n]:t.browser.isStrict&&i.document.documentElement[e]||i.document.body[e]:r[e]},set:function(t,n){if(!t)return;var i=o(t);i?i.scrollTo(r?n:this.get(t),r?this.get(t):n):t[e]=n}}},t.dom.extend({scrollLeft:function(){var e=t._util_.smartScroll("scrollLeft");return function(n){return n&&t.check("^(?:number|string)$","baidu.dom.scrollLeft"),this.size()<=0?n===undefined?0:this:n===undefined?e.get(this[0]):e.set(this[0],n)||this}}()}),t.dom.extend({scrollTop:function(){var e=t._util_.smartScroll("scrollTop");return function(n){return n&&t.check("^(?:number|string)$","baidu.dom.scrollTop"),this.size()<=0?n===undefined?0:this:n===undefined?e.get(this[0]):e.set(this[0],n)||this}}()}),t.dom.setPixel=function(e,n,r){typeof r!="undefined"&&(t.dom.g(e).style[n]=r+(isNaN(r)?"":"px"))},t._util_.getDefaultDisplayValue=function(){var e={};return function(n){if(e[n])return e[n];var r=document.createElement(n),i,s,o;document.body.appendChild(r),i=t.dom(r).getCurrentStyle("display"),document.body.removeChild(r);if(i===""||i==="none")s=document.body.appendChild(document.createElement("iframe")),s.frameBorder=s.width=s.height=0,o=(s.contentWindow||s.contentDocument).document,o.writeln("<!DOCTYPE html><html><body>"),o.close(),r=o.appendChild(o.createElement(n)),i=t.dom(r).getCurrentStyle("display"),document.body.removeChild(s),s=null;return r=null,e[n]=i}}(),t.dom.extend({show:function(){var e=[],n,r;return this.each(function(i,s){if(!s.style)return;r=t.dom(s),n=s.style.display,e[i]=r.data("olddisplay"),!e[i]&&n==="none"&&(s.style.display=""),s.style.display===""&&t._util_.isHidden(s)&&r.data("olddisplay",e[i]=t._util_.getDefaultDisplayValue(s.nodeName))}),this.each(function(t,n){if(!n.style)return;if(n.style.display==="none"||n.style.display==="")n.style.display=e[t]||""})}}),t.dom.extend({siblings:function(e){var n=[];return t.forEach(this,function(e){var r=[],i=[],s=e;while(s=s.previousSibling)s.nodeType==1&&r.push(s);while(e=e.nextSibling)e.nodeType==1&&i.push(e);t.merge(n,r.reverse().concat(i))}),this.pushStack(t.dom.match(n,e))}}),t.dom.extend({slice:function(){var e=Array.prototype.slice;return function(n,r){return t.check("number(,number)?","baidu.dom.slice"),this.pushStack(e.apply(this,arguments))}}()}),t.dom.extend({text:function(e){var n=t.dom,r=this,i=!1,s;if(this.size()<=0)switch(typeof e){case"undefined":return undefined;default:return r}var o=function(e){var t,n="",r=0,i=e.nodeType;if(i)if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(i===3||i===4)return e.nodeValue;return n};return t.forEach(r,function(t,r){var u=n(t);if(s)return;switch(typeof e){case"undefined":return s=o(t),s;case"number":e=String(e);case"string":i=!0,u.empty().append((t&&t.ownerDocument||document).createTextNode(e));break;case"function":i=!0,u.text(e.call(t,r,u.text()))}}),i?r:s}}),t.dom.extend({toggle:function(){for(var e=0,t=this.size();e<t;e++){var n=this.eq(e);n.css("display")!="none"?n.hide():n.show()}}}),t.dom.extend({toggleClass:function(e,n){var r=typeof e,n=typeof n=="undefined"?n:Boolean(n);arguments.length<=0&&t.forEach(this,function(e){e.className=""});switch(typeof e){case"string":e=e.replace(/^\s+/g,"").replace(/\s+$/g,"").replace(/\s+/g," ");var i=e.split(" ");t.forEach(this,function(e){var t=e.className;for(var r=0;r<i.length;r++)~(" "+t+" ").indexOf(" "+i[r]+" ")&&typeof n=="undefined"?t=(" "+t+" ").replace(" "+i[r]+" "," "):!~(" "+t+" ").indexOf(" "+i[r]+" ")&&typeof n=="undefined"?t+=" "+i[r]:!~(" "+t+" ").indexOf(" "+i[r]+" ")&&n===!0?t+=" "+i[r]:~(" "+t+" ").indexOf(" "+i[r]+" ")&&n===!1&&(t=t.replace(i[r],""));e.className=t.replace(/^\s+/g,"").replace(/\s+$/g,"")});break;case"function":t.forEach(this,function(r,i){t.dom(r).toggleClass(e.call(r,i,r.className),n)})}return this}}),void function(e){if(e.mousewheel)return;var n=/firefox/i.test(navigator.userAgent),r=/msie/i.test(navigator.userAgent);t.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(n,r){e[n]={bindType:r,pack:function(e){var r=t.dom.contains;return function(t){var i=t.relatedTarget;t.type=n;if(!i||i!==this&&!r(this,i))return e.apply(this,arguments)}}}}),r||t.each({focusin:"focus",focusout:"blur"},function(t,n){e[t]={bindType:n,attachElements:"textarea,select,input,button,a"}}),e.mousewheel={bindType:n?"DOMMouseScroll":"mousewheel",pack:function(e){return function(t){var r=t.originalEvent;return t.type="mousewheel",t.wheelDelta=t.wheelDelta||(n?r.detail*-40:r.wheelDelta)||0,e.apply(this,arguments)}}}}(t.event.special),void function(e){var n=e.queue;t.dom.extend({triggerHandler:function(e,r,i){return i&&!i.triggerData&&(i.triggerData=r),t.forEach(this,function(t){n.call(t,e,undefined,i)}),this}})}(t._util_.eventBase),void function(e,n){var r=n.special,i=e.queue,s=t.dom,o=!window.addEventListener,u=/firefox/i.test(navigator.userAgent),a={submit:3,focus:o?3:2,blur:o?3:u?1:2},f=function(e,t){var n;document.createEvent?(n=document.createEvent("HTMLEvents"),n.initEvent(e,!0,!0)):document.createEventObject&&(n=document.createEventObject(),n.type=e);var r={};if(t)for(var i in t)try{n[i]=t[i]}catch(s){n.extraData||(n.extraData=r),r[i]=t[i]}return n},l=function(e,t,n){if(e.dispatchEvent)return e.dispatchEvent(n);if(e.fireEvent)return e.fireEvent("on"+t,n)},c=function(e,t,n,r,o){var u,c;if(u=f(t,r)){n&&(u.triggerData=n);if(o)i.call(e,t,null,u);else{var h=e.window===window?3:a[t];try{if(h&1||!(t in a))c=l(e,t,u)}catch(p){s(e).triggerHandler(t,n,u)}if(c!==!1&&h&2)try{e[t]&&e[t]()}catch(p){}}}};t.dom.extend({trigger:function(e,t,n){var i;return e in r&&(i=r[e]),this.each(function(){c(this,e,t,n,i)}),this}})}(t._util_.eventBase,t.event),t.dom.extend({unbind:function(e,t){return this.off(e,t)}}),t.dom.extend({undelegate:function(e,t,n){return this.off(t,e,n)}}),t.dom.extend({unique:function(e){return t.dom(t.array(this.toArray()).unique(e))}}),t._util_.inArray=function(e,t,n){if(!t)return-1;var r=Array.prototype.indexOf,i;if(r)return r.call(t,e,n);i=t.length,n=n?n<0?Math.max(0,i+n):n:0;for(;n<i;n++)if(n in t&&t[n]===e)return n;return-1},t.dom.extend({val:function(){t._util_.support.dom.select.disabled=!0;var e=t._util_,n=e.support.dom.input.value==="on",r=!e.support.dom.opt.disabled,i=["radio","checkbox"],s={option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(n){var i=n.options,s=n.selectedIndex,o=n.type==="select-one"||s<0,u=o?null:[],a=o?s+1:i.length,f=s<0?a:o?s:0,l,c;for(;f<a;f++){l=i[f];if((l.selected||f===s)&&(r?!l.disabled:l.getAttribute("disabled")===null)&&(!l.parentNode.disabled||!e.nodeName(l.parentNode,"optgroup"))){c=t.dom(l).val();if(o)return c;u.push(c)}}return u},set:function(n,r,i){var s=t.makeArray(i);return t.dom(n).find("option").each(function(n,r){r.selected=e.inArray(t.dom(this).val(),s)>=0}),!s.length&&(n.selectedIndex=-1),s}}};return!e.support.getSetAttribute&&(s.button=e.nodeHook),n||t.forEach(i,function(e){s[e]={get:function(e){return e.getAttribute("value")===null?"on":e.value}}}),t.forEach(i,function(n){s[n]=s[n]||{},s[n].set=function(n,r,i){if(t.type(i)==="array")return n.checked=e.inArray(t.dom(n).val(),i)>=0}}),function(e){var n,r;if(e===undefined){if(!(n=this[0]))return;return r=s[n.type]||s[n.nodeName.toLowerCase()]||{},r.get&&r.get(n,"value")||n.value}return this.each(function(n,i){if(i.nodeType!==1)return;var o=t.dom(i),u=t.type(e)==="function"?e.call(i,n,o.val()):e;u==null?u="":t.type(u)==="number"?u+="":t.type(u)==="array"&&(u=t.array(u).map(function(e){return e==null?"":e+""})),r=s[i.type]||s[i.nodeName.toLowerCase()]||{};if(!r.set||r.set(i,"value",u)===undefined)i.value=u}),this}}()}),t.dom.extend({width:function(e){return t._util_.access(this,"width",e,function(e,n,r){var i=r!==undefined,s=i&&parseFloat(r),o=e!=null&&e==e.window?"window":e.nodeType===9?"document":!1;if(i&&s<0||isNaN(s))return;return i&&/^(?:\d*\.)?\d+$/.test(r+="")&&(r+="px"),o?t._util_.getWindowOrDocumentWidthOrHeight(e,o,n):i?e.style.width=r:t._util_.getWidthOrHeight(e,n)})}}),t.dom.extend({end:function(){return this.prevObject||t.dom(null)}}),void function(){var e="blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave mousewheel change select submit keydown keypress keyup error contextmenu".split(" "),n={},r=function(e){n[e]=function(t,n){return n==null&&(n=t,t=null),arguments.length>0?this.on(e,null,t,n):this.trigger(e)}};for(var i=0,s=e.length;i<s;i++)r(e[i]);t.dom.extend(n)}(),t.createChain("fn",function(e){return new t.fn.$Fn(~"function|string".indexOf(t.type(e))?e:function(){})},function(e){this.fn=e}),t.fn.extend({bind:function(e){var n=this.fn,r=arguments.length>1?Array.prototype.slice.call(arguments,1):null;return function(){var i=t.type(n)==="string"?e[n]:n,s=r?r.concat(Array.prototype.slice.call(arguments,0)):arguments;return i.apply(e||i,s)}}}),t.fn.blank=function(){},t.fx=t.fx||{},t.lang.inherits=t.base.inherits,t.fx.Timeline=function(e){t.lang.Class.call(this),this.interval=16,this.duration=500,this.dynamic=!0,t.object.extend(this,e)},t.lang.inherits(t.fx.Timeline,t.lang.Class,"baidu.fx.Timeline").extend({launch:function(){var e=this;return e.dispatchEvent("onbeforestart"),typeof e.initialize=="function"&&e.initialize(),e["btime"]=(new Date).getTime(),e["etime"]=e["btime"]+(e.dynamic?e.duration:0),e["pulsed"](),e},"pulsed":function(){var e=this,t=(new Date).getTime();e.percent=(t-e["btime"])/e.duration,e.dispatchEvent("onbeforeupdate");if(t>=e["etime"]){typeof e.render=="function"&&e.render(e.transition(e.percent=1)),typeof e.finish=="function"&&e.finish(),e.dispatchEvent("onafterfinish"),e.dispose();return}typeof e.render=="function"&&e.render(e.transition(e.percent)),e.dispatchEvent("onafterupdate"),e["timer"]=setTimeout(function(){e["pulsed"]()},e.interval)},transition:function(e){return e},cancel:function(){this["timer"]&&clearTimeout(this["timer"]),this["etime"]=this["btime"],typeof this.restore=="function"&&this.restore(),this.dispatchEvent("oncancel"),this.dispose()},end:function(){this["timer"]&&clearTimeout(this["timer"]),this["etime"]=this["btime"],this["pulsed"]()}}),t.fx.create=function(e,n,r){var i=new t.fx.Timeline(n);i.element=e,i.__type=r||i.__type,i["original"]={};var s="baidu_current_effect";return i.addEventListener("onbeforestart",function(){var e=this,t;e.attribName="att_"+e.__type.replace(/\W/g,"_"),t=e.element.getAttribute(s),e.element.setAttribute(s,(t||"")+"|"+e.guid+"|",0),e.overlapping||((t=e.element.getAttribute(e.attribName))&&baiduInstance(t).cancel(),e.element.setAttribute(e.attribName,e.guid,0))}),i["clean"]=function(e){var t=this,n;if(e=t.element)e.removeAttribute(t.attribName),n=e.getAttribute(s),n=n.replace("|"+t.guid+"|",""),n?e.setAttribute(s,n,0):e.removeAttribute(s)},i.addEventListener("oncancel",function(){this["clean"](),this["restore"]()}),i.addEventListener("onafterfinish",function(){this["clean"](),this.restoreAfterFinish&&this["restore"]()}),i.protect=function(e){this["original"][e]=this.element.style[e]},i["restore"]=function(){var e=this["original"],t=this.element.style,n;for(var r in e){n=e[r];if(typeof n=="undefined")continue;t[r]=n,!n&&t.removeAttribute?t.removeAttribute(r):!n&&t.removeProperty&&t.removeProperty(r)}},i},t.fx.current=function(e){if(!(e=t.dom.g(e)))return null;var n,r,i=/\|([^\|]+)\|/g;do if(r=e.getAttribute("baidu_current_effect"))break;while((e=e.parentNode)&&e.nodeType==1);if(!r)return null;if(n=r.match(i)){i=/\|([^\|]+)\|/;for(var s=0;s<n.length;s++)i.test(n[s]),n[s]=t._global_._instances[RegExp.$1]}return n},t.string.extend({formatColor:function(){var e=/^\#[\da-f]{6}$/i,t=/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/i,n={black:"#000000",silver:"#c0c0c0",gray:"#808080",white:"#ffffff",maroon:"#800000",red:"#ff0000",purple:"#800080",fuchsia:"#ff00ff",green:"#008000",lime:"#00ff00",olive:"#808000",yellow:"#ffff0",navy:"#000080",blue:"#0000ff",teal:"#008080",aqua:"#00ffff"};return function(){var r=this.valueOf();if(e.test(r))return r;if(t.test(r)){for(var i,s=1,r="#";s<4;s++)i=parseInt(RegExp["$"+s]).toString(16),r+=("00"+i).substr(i.length);return r}if(/^\#[\da-f]{3}$/.test(r)){var o=r.charAt(1),u=r.charAt(2),a=r.charAt(3);return"#"+o+o+u+u+a+a}return n[r]?n[r]:""}}()}),t.fx.move=function(e,n){if(!(e=t.dom.g(e))||t.dom.getStyle(e,"position")=="static")return null;n=t.object.extend({x:0,y:0},n||{});if(n.x==0&&n.y==0)return null;var r=t.fx.create(e,t.object.extend({initialize:function(){this.protect("top"),this.protect("left"),this.originX=parseInt(t.dom.getStyle(e,"left"))||0,this.originY=parseInt(t.dom.getStyle(e,"top"))||0},transition:function(e){return 1-Math.pow(1-e,2)},render:function(t){e.style.top=this.y*t+this.originY+"px",e.style.left=this.x*t+this.originX+"px"}},n),"baidu.fx.move");return r.launch()},t.fx.moveTo=function(e,n,r){if(!(e=t.dom.g(e))||t.dom.getStyle(e,"position")=="static"||typeof n!="object")return null;var i=[n[0]||n.x||0,n[1]||n.y||0],s=parseInt(t.dom.getStyle(e,"left"))||0,o=parseInt(t.dom.getStyle(e,"top"))||0,u=t.fx.move(e,t.object.extend({x:i[0]-s,y:i[1]-o},r||{}));return u},t.fx.scrollBy=function(e,n,r){if(!(e=t.dom.g(e))||typeof n!="object")return null;var i={},s={};i.x=n[0]||n.x||0,i.y=n[1]||n.y||0;var o=t.fx.create(e,t.object.extend({initialize:function(){var t=s.sTop=e.scrollTop,n=s.sLeft=e.scrollLeft;s.sx=Math.min(e.scrollWidth-e.clientWidth-n,i.x),s.sy=Math.min(e.scrollHeight-e.clientHeight-t,i.y)},transition:function(e){return 1-Math.pow(1-e,2)},render:function(t){e.scrollTop=s.sy*t+s.sTop,e.scrollLeft=s.sx*t+s.sLeft},restore:function(){e.scrollTop=s.sTop,e.scrollLeft=s.sLeft}},r),"baidu.fx.scroll");return o.launch()},t.fx.scrollTo=function(e,n,r){if(!(e=t.dom.g(e))||typeof n!="object")return null;var i={};return i.x=(n[0]||n.x||0)-e.scrollLeft,i.y=(n[1]||n.y||0)-e.scrollTop,t.fx.scrollBy(e,i,r)},t._util_.smartAjax=t._util_.smartAjax||function(e){return function(n,r,i,s){t.type(r)==="function"&&(s=s||i,i=r,r=undefined),t.ajax({type:e,url:n,data:r,success:i,dataType:s})}},t.get=t.get||t._util_.smartAjax("get"),t.global.get=function(e){return t.global(e)},t.global.set=function(e,n,r){return t.global(e,n,!r)},t.global.getZIndex=function(e,n){var r=t.global.get("zIndex");return e&&(r[e]=r[e]+(n||1)),r[e]},t.global.set("zIndex",{popup:5e4,dialog:1e3},!0),t.i18n=t.i18n||{},t.i18n.cultures=t.i18n.cultures||{},t.i18n.cultures["zh-CN"]=t.object.extend(t.i18n.cultures["zh-CN"]||{},function(){var e="%u4E00,%u4E8C,%u4E09,%u56DB,%u4E94,%u516D,%u4E03,%u516B,%u4E5D,%u5341".split(",");return{calendar:{dateFormat:"yyyy-MM-dd",titleNames:"#{yyyy}"+unescape("%u5E74")+"&nbsp;#{MM}"+unescape("%u6708"),monthNamesShort:[1,2,3,4,5,6,7,8,9,10,11,12],monthNames:function(){var t=e.length,n=[];for(var r=0;r<12;r++)n.push(unescape(e[r]||e[t-1]+e[r-t]));return n}(),dayNames:function(){var t={mon:0,tue:1,wed:2,thu:3,fri:4,sat:5,sun:"%u65E5"};for(var n in t)t[n]=unescape(e[t[n]]||t[n]);return t}()},timeZone:8,whitespace:new RegExp("(^[\\s\\t\\xa0\\u3000]+)|([\\u3000\\xa0\\s\\t]+$)","g"),number:{group:",",groupLength:3,decimal:".",positive:"",negative:"-",_format:function(e,n){return t.i18n.number._format(e,{group:this.group,groupLength:this.groupLength,decimal:this.decimal,symbol:n?this.negative:this.positive})}},currency:{symbol:unescape("%uFFE5")},language:function(){var e={ok:"%u786E%u5B9A",cancel:"%u53D6%u6D88",signin:"%u6CE8%u518C",signup:"%u767B%u5F55"};for(var t in e)e[t]=unescape(e[t]);return e}()}}()),t.i18n.currentLocale="zh-CN",t.i18n.date=t.i18n.date||{getDaysInMonth:function(e,n){var r=[31,28,31,30,31,30,31,31,30,31,30,31];return n==1&&t.i18n.date.isLeapYear(e)?29:r[n]},isLeapYear:function(e){return!(e%400)||!(e%4)&&!!(e%100)},toLocaleDate:function(e,n,r){return this._basicDate(e,n,r||t.i18n.currentLocale)},_basicDate:function(e,n,r){var i=t.i18n.cultures[r||t.i18n.currentLocale].timeZone,s=i*60,o,u,a=e.getTime();return n?(o=t.i18n.cultures[n].timeZone,u=o*60):(u=-1*e.getTimezoneOffset(),o=u/60),new Date(o!=i?a+(s-u)*6e4:a)},format:function(e,n){var r=t.i18n.cultures[n||t.i18n.currentLocale];return t.date.format(t.i18n.date.toLocaleDate(e,"",n),r.calendar.dateFormat)}},t.isDate=function(e){return t.type(e)=="date"&&e.toString()!="Invalid Date"&&!isNaN(e)},t.isDocument=function(e){return t.type(e)=="Document"},t.isElement=function(e){return t.type(e)=="HTMLElement"},t.isNumber=function(e){return t.type(e)=="number"&&isFinite(e)},t.isObject=function(e){return typeof e=="function"||typeof e=="object"&&e!=null},t.isPlainObject=function(e){var n,r=Object.prototype.hasOwnProperty;if(t.type(e)!="object")return!1;if(e.constructor&&!r.call(e,"constructor")&&!r.call(e.constructor.prototype,"isPrototypeOf"))return!1;for(n in e)break;return e.item&&typeof e.length=="number"?!1:n===undefined||r.call(e,n)},t.isWindow=function(e){return t.type(e)=="Window"},t.json=t.json||{},t.json.parse=function(e){return(new Function("return ("+e+")"))()},t.json.stringify=function(){function n(t){return/["\\\x00-\x1f]/.test(t)&&(t=t.replace(/["\\\x00-\x1f]/g,function(t){var n=e[t];return n?n:(n=t.charCodeAt(),"\\u00"+Math.floor(n/16).toString(16)+(n%16).toString(16))})),'"'+t+'"'}function r(e){var n=["["],r=e.length,i,s,o;for(s=0;s<r;s++){o=e[s];switch(typeof o){case"undefined":case"function":case"unknown":break;default:i&&n.push(","),n.push(t.json.stringify(o)),i=1}}return n.push("]"),n.join("")}function i(e){return e<10?"0"+e:e}function s(e){return'"'+e.getFullYear()+"-"+i(e.getMonth()+1)+"-"+i(e.getDate())+"T"+i(e.getHours())+":"+i(e.getMinutes())+":"+i(e.getSeconds())+'"'
    -}var e={"\b":"\\b","	":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"};return function(e){switch(typeof e){case"undefined":return"undefined";case"number":return isFinite(e)?String(e):"null";case"string":return n(e);case"boolean":return String(e);default:if(e===null)return"null";if(t.type(e)==="array")return r(e);if(t.type(e)==="date")return s(e);var i=["{"],o=t.json.stringify,u,a;for(var f in e)if(Object.prototype.hasOwnProperty.call(e,f)){a=e[f];switch(typeof a){case"undefined":case"unknown":case"function":break;default:u&&i.push(","),u=1,i.push(o(f)+":"+o(a))}}return i.push("}"),i.join("")}}}(),t.lang.createClass=t.createClass,t.lang.guid=function(){return t.id()},t.lang.isArray=t.isArray,t.lang.isDate=t.isDate,t.lang.isElement=t.isElement,t.lang.isObject=t.isObject,t.lang.isString=t.isString,t.lang.register=t.base.register,t.lang.toArray=function(e){if(e===null||e===undefined)return[];if(t.lang.isArray(e))return e;if(typeof e.length!="number"||typeof e=="string"||t.lang.isFunction(e))return[e];if(e.item){var n=e.length,r=new Array(n);while(n--)r[n]=e[n];return r}return[].slice.call(e)},t.number.extend({comma:function(e){var t=this;if(!e||e<1)e=3;return t=String(t).split("."),t[0]=t[0].replace(new RegExp("(\\d)(?=(\\d{"+e+"})+$)","ig"),"$1,"),t.join(".")}}),t.number.randomInt=function(e,t){return Math.floor(Math.random()*(t-e+1)+e)},t.object.clone=function(e){var n=e,r,i;if(!e||e instanceof Number||e instanceof String||e instanceof Boolean)return n;if(t.lang.isArray(e)){n=[];var s=0;for(r=0,i=e.length;r<i;r++)n[s++]=t.object.clone(e[r])}else if(t.object.isPlain(e)){n={};for(r in e)e.hasOwnProperty(r)&&(n[r]=t.object.clone(e[r]))}return n},t.object.each=function(e,t){var n,r,i;if("function"==typeof t)for(r in e)if(e.hasOwnProperty(r)){i=e[r],n=t.call(e,i,r);if(n===!1)break}return e},t.object.isEmpty=function(e){var t=!0;if("[object Array]"===Object.prototype.toString.call(e))t=!e.length;else{e=new Object(e);for(var n in e)return!1}return t},t.object.keys=function(e){var t=[],n=0,r;for(r in e)e.hasOwnProperty(r)&&(t[n++]=r);return t},t.object.map=function(e,t){var n={};for(var r in e)e.hasOwnProperty(r)&&(n[r]=t(e[r],r));return n},t.object.merge=function(){function e(e){return t.lang.isObject(e)&&!t.lang.isFunction(e)}function n(n,r,i,s,o){if(r.hasOwnProperty(i))if(o&&e(n[i]))t.object.merge(n[i],r[i],{overwrite:s,recursive:o});else if(s||!(i in n))n[i]=r[i]}return function(e,t,r){var i=0,s=r||{},o=s.overwrite,u=s.whiteList,a=s.recursive,f;if(u&&u.length){f=u.length;for(;i<f;++i)n(e,t,u[i],o,a)}else for(i in t)n(e,t,i,o,a);return e}}(),t.object.values=function(e){var t=[],n=0,r;for(r in e)e.hasOwnProperty(r)&&(t[n++]=e[r]);return t},t.page.getHeight=function(){var e=document,t=e.body,n=e.documentElement,r=e.compatMode=="BackCompat"?t:e.documentElement;return Math.max(n.scrollHeight,t.scrollHeight,r.clientHeight)},t.page.getViewHeight=function(){var e=document,n=t.browser.ie||1,r=e.compatMode==="BackCompat"&&n<9?e.body:e.documentElement;return r.clientHeight},t.page.getViewWidth=function(){var e=document,t=e.compatMode=="BackCompat"?e.body:e.documentElement;return t.clientWidth},t.page.getWidth=function(){var e=document,t=e.body,n=e.documentElement,r=e.compatMode=="BackCompat"?t:e.documentElement;return Math.max(n.scrollWidth,t.scrollWidth,r.clientWidth)},t.platform=t.platform||function(){var e=navigator.userAgent,n=function(){};return t.forEach("Android iPad iPhone Linux Macintosh Windows X11".split(" "),function(r){var i=r.charAt(0).toUpperCase()+r.toLowerCase().substr(1);t["is"+i]=n["is"+i]=!!~e.indexOf(r)}),n}(),t.plugin=function(e,n,r,i){var s=t.isPlainObject(n),o;return s||(i=r,r=n),t.type(r)!="function"&&(r=undefined),t.type(i)!="function"&&(i=undefined),o=t.createChain(e,r,i),s&&o.extend(n),o},t.post=t.post||t._util_.smartAjax("post"),t.setBack=function(e,t){return e._back_=t,e.getBack=function(){return this._back_},e},t.createChain("sio",function(e){switch(typeof e){case"string":return new t.sio.$Sio(e)}},function(e){this.url=e}),t.sio._createScriptTag=function(e,t,n){e.setAttribute("type","text/javascript"),n&&e.setAttribute("charset",n),e.setAttribute("src",t),document.getElementsByTagName("head")[0].appendChild(e)},t.sio._removeScriptTag=function(e){if(e.clearAttributes)e.clearAttributes();else for(var t in e)e.hasOwnProperty(t)&&delete e[t];e&&e.parentNode&&e.parentNode.removeChild(e),e=null},t.sio.extend({callByBrowser:function(e,n){var r=this.url,i=document.createElement("SCRIPT"),s=0,o=n||{},u=o.charset,a=e||function(){},f=o.timeOut||0,l;i.onload=i.onreadystatechange=function(){if(s)return;var e=i.readyState;if("undefined"==typeof e||e=="loaded"||e=="complete"){s=1;try{a(),clearTimeout(l)}finally{i.onload=i.onreadystatechange=null,t.sio._removeScriptTag(i)}}},f&&(l=setTimeout(function(){i.onload=i.onreadystatechange=null,t.sio._removeScriptTag(i),o.onfailure&&o.onfailure()},f)),t.sio._createScriptTag(i,r,u)}}),t.sio.extend({callByServer:function(e,n){function v(n){return function(){try{n?a.onfailure&&a.onfailure():(e.apply(window,arguments),clearTimeout(h)),window[o]=null,delete window[o]}catch(r){}finally{t.sio._removeScriptTag(i)}}}var r=this.url,i=document.createElement("SCRIPT"),s="bd__cbs__",o,u,a=n||{},f=a.charset,l=a.queryField||"callback",c=a.timeOut||0,h,p=new RegExp("(\\?|&)"+l+"=([^&]*)"),d;if(t.lang.isFunction(e))o=s+Math.floor(Math.random()*2147483648).toString(36),window[o]=v(0);else if(t.lang.isString(e))o=e;else if(d=p.exec(r))o=d[2];c&&(h=setTimeout(v(1),c)),r=r.replace(p,"$1"+l+"="+o),r.search(p)<0&&(r+=(r.indexOf("?")<0?"?":"&")+l+"="+o),t.sio._createScriptTag(i,r,f)}}),t.sio.extend({log:function(){var e=this.url,t=new Image,n="tangram_sio_log_"+Math.floor(Math.random()*2147483648).toString(36);window[n]=t,t.onload=t.onerror=t.onabort=function(){t.onload=t.onerror=t.onabort=null,window[n]=null,t=null},t.src=e}}),t.string.extend({decodeHTML:function(){var e=this.replace(/&quot;/g,'"').replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&amp;/g,"&");return e.replace(/&#([\d]+);/g,function(e,t){return String.fromCharCode(parseInt(t,10))})}}),t.string.extend({encodeHTML:function(){return this.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}}),t.string.extend({format:function(e){var t=this.valueOf(),n=Array.prototype.slice.call(arguments,0),r=Object.prototype.toString;return n.length?(n=n.length==1?e!==null&&/\[object Array\]|\[object Object\]/.test(r.call(e))?e:n:n,t.replace(/#\{(.+?)\}/g,function(e,t){var i=n[t];return"[object Function]"==r.call(i)&&(i=i(t)),"undefined"==typeof i?"":i})):t}}),t.string.extend({getByteLength:function(){return this.replace(/[^\x00-\xff]/g,"ci").length}}),t.string.extend({stripTags:function(){return(this||"").replace(/<[^>]+>/g,"")}}),t.string.extend({subByte:function(e,n){t.check("number(,string)?$","baidu.string.subByte");if(e<0||this.getByteLength()<=e)return this.valueOf();var r=this.substr(0,e).replace(/([^\x00-\xff])/g,"$1 ").substr(0,e).replace(/[^\x00-\xff]$/,"").replace(/([^\x00-\xff]) /g,"$1");return r+(n||"")}}),t.string.extend({toHalfWidth:function(){return this.replace(/[\uFF01-\uFF5E]/g,function(e){return String.fromCharCode(e.charCodeAt(0)-65248)}).replace(/\u3000/g," ")}}),t.string.extend({wbr:function(){return this.replace(/(?:<[^>]+>)|(?:&#?[0-9a-z]{2,6};)|(.{1})/gi,"$&<wbr>").replace(/><wbr>/g,">")}}),t.swf=t.swf||{},t.swf.version=function(){var e=navigator;if(e.plugins&&e.mimeTypes.length){var t=e.plugins["Shockwave Flash"];if(t&&t.description)return t.description.replace(/([a-zA-Z]|\s)+/,"").replace(/(\s)+r/,".")+".0"}else if(window.ActiveXObject&&!window.opera)for(var n=12;n>=2;n--)try{var r=new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+n);if(r){var i=r.GetVariable("$version");return i.replace(/WIN/g,"").replace(/,/g,".")}}catch(s){}}(),t.swf.createHTML=function(e){e=e||{};var n=t.swf.version,r=e.ver||"6.0.0",i,s,o,u,a,f,l={},c=t.string.encodeHTML;for(u in e)l[u]=e[u];e=l;if(!n)return"";n=n.split("."),r=r.split(".");for(o=0;o<3;o++){i=parseInt(n[o],10),s=parseInt(r[o],10);if(s<i)break;if(s>i)return""}var h=e.vars,p=["classid","codebase","id","width","height","align"];e.align=e.align||"middle",e.classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000",e.codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0",e.movie=e.url||"",delete e.vars,delete e.url;if("string"==typeof h)e.flashvars=h;else{var d=[];for(u in h)f=h[u],d.push(u+"="+encodeURIComponent(f));e.flashvars=d.join("&")}var v=["<object "];for(o=0,a=p.length;o<a;o++)f=p[o],v.push(" ",f,'="',c(e[f]),'"');v.push(">");var m={wmode:1,scale:1,quality:1,play:1,loop:1,menu:1,salign:1,bgcolor:1,base:1,allowscriptaccess:1,allownetworking:1,allowfullscreen:1,seamlesstabbing:1,devicefont:1,swliveconnect:1,flashvars:1,movie:1};for(u in e)f=e[u],u=u.toLowerCase(),m[u]&&(f||f===!1||f===0)&&v.push('<param name="'+u+'" value="'+c(f)+'" />');e.src=e.movie,e.name=e.id,delete e.id,delete e.movie,delete e.classid,delete e.codebase,e.type="application/x-shockwave-flash",e.pluginspage="http://www.macromedia.com/go/getflashplayer",v.push("<embed");var g;for(u in e){f=e[u];if(f||f===!1||f===0){if((new RegExp("^salign$","i")).test(u)){g=f;continue}v.push(" ",u,'="',c(f),'"')}}return g&&v.push(' salign="',c(g),'"'),v.push("></embed></object>"),v.join("")},t.swf.create=function(e,n){e=e||{};var r=t.swf.createHTML(e)||e.errorMessage||"";n&&"string"==typeof n&&(n=document.getElementById(n)),t.dom.insertHTML(n||document.body,"beforeEnd",r)},t.swf.getMovie=function(e){var n=document[e],r;return t.browser.ie==9?n&&n.length?(r=t.array.remove(t.lang.toArray(n),function(e){return e.tagName.toLowerCase()!="embed"})).length==1?r[0]:r:n:n||window[e]},t.swf.Proxy=function(e,n,r){var i=this,s=this._flash=t.swf.getMovie(e),o;if(!n)return this;o=setInterval(function(){try{s[n]&&(i._initialized=!0,clearInterval(o),r&&r())}catch(e){}},100)},t.swf.Proxy.prototype.getFlash=function(){return this._flash},t.swf.Proxy.prototype.isReady=function(){return!!this._initialized},t.swf.Proxy.prototype.call=function(e,t){try{var n=this.getFlash(),r=Array.prototype.slice.call(arguments);r.shift(),n[e]&&n[e].apply(n,r)}catch(i){}},function(e){var n=document.createElement("div");e.inlineBlockNeedsLayout=!1,e.shrinkWrapBlocks=!1,t(document).ready(function(){var t=document.body,r=document.createElement("div");r.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",t.appendChild(r).appendChild(n),typeof n.style.zoom!="undefined"&&(n.style.cssText="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;width:1px;padding:1px;display:inline;zoom:1",e.inlineBlockNeedsLayout=n.offsetWidth===3,n.style.display="block",n.innerHTML="<div></div>",n.firstChild.style.width="5px",e.shrinkWrapBlocks=n.offsetWidth!==3),t.removeChild(r),r=n=t=null})}(t._util_.support),t}();t.T=r});
    \ No newline at end of file
    diff --git a/source/static/api/js/component/animate.js b/source/static/api/js/component/animate.js
    deleted file mode 100644
    index 89bd31b1..00000000
    --- a/source/static/api/js/component/animate.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("component/animate",function(e,t,n){var r,i=r=i||{version:"1.5.2.2"};i.guid="$BAIDU$",i.$$=window[i.guid]=window[i.guid]||{global:{}},i.fx=i.fx||{},i.lang=i.lang||{},i.lang.guid=function(){return"TANGRAM$"+i.$$._counter++},i.$$._counter=i.$$._counter||1,i.lang.Class=function(){this.guid=i.lang.guid(),!this.__decontrolled&&(i.$$._instances[this.guid]=this)},i.$$._instances=i.$$._instances||{},i.lang.Class.prototype.dispose=function(){delete i.$$._instances[this.guid];for(var e in this)typeof this[e]!="function"&&delete this[e];this.disposed=!0},i.lang.Class.prototype.toString=function(){return"[object "+(this.__type||this._className||"Object")+"]"},window.baiduInstance=function(e){return i.$$._instances[e]},i.lang.isString=function(e){return"[object String]"==Object.prototype.toString.call(e)},i.isString=i.lang.isString,i.lang.Event=function(e,t){this.type=e,this.returnValue=!0,this.target=t||null,this.currentTarget=null},i.lang.Class.prototype.fire=i.lang.Class.prototype.dispatchEvent=function(e,t){i.lang.isString(e)&&(e=new i.lang.Event(e)),!this.__listeners&&(this.__listeners={}),t=t||{};for(var n in t)e[n]=t[n];var n,r,s=this,o=s.__listeners,u=e.type;e.target=e.target||(e.currentTarget=s),u.indexOf("on")&&(u="on"+u),typeof s[u]=="function"&&s[u].apply(s,arguments);if(typeof o[u]=="object")for(n=0,r=o[u].length;n<r;n++)o[u][n]&&o[u][n].apply(s,arguments);return e.returnValue},i.lang.Class.prototype.on=i.lang.Class.prototype.addEventListener=function(e,t,n){if(typeof t!="function")return;!this.__listeners&&(this.__listeners={});var r,i=this.__listeners;e.indexOf("on")&&(e="on"+e),typeof i[e]!="object"&&(i[e]=[]);for(r=i[e].length-1;r>=0;r--)if(i[e][r]===t)return t;return i[e].push(t),n&&typeof n=="string"&&(i[e][n]=t),t},i.lang.inherits=function(e,t,n){var r,i,s=e.prototype,o=new Function;o.prototype=t.prototype,i=e.prototype=new o;for(r in s)i[r]=s[r];return e.prototype.constructor=e,e.superClass=t.prototype,typeof n=="string"&&(i.__type=n),e.extend=function(t){for(var n in t)i[n]=t[n];return e},e},i.inherits=i.lang.inherits,i.object=i.object||{},i.extend=i.object.extend=function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e},i.fx.Timeline=function(e){i.lang.Class.call(this),this.interval=16,this.duration=500,this.dynamic=!0,i.object.extend(this,e)},i.lang.inherits(i.fx.Timeline,i.lang.Class,"baidu.fx.Timeline").extend({launch:function(){var e=this;return e.dispatchEvent("onbeforestart"),typeof e.initialize=="function"&&e.initialize(),e["btime"]=(new Date).getTime(),e["etime"]=e["btime"]+(e.dynamic?e.duration:0),e["pulsed"](),e},"pulsed":function(){var e=this,t=(new Date).getTime();e.percent=(t-e["btime"])/e.duration,e.dispatchEvent("onbeforeupdate");if(t>=e["etime"]){typeof e.render=="function"&&e.render(e.transition(e.percent=1)),typeof e.finish=="function"&&e.finish(),e.dispatchEvent("onafterfinish"),e.dispose();return}typeof e.render=="function"&&e.render(e.transition(e.percent)),e.dispatchEvent("onafterupdate"),e["timer"]=setTimeout(function(){e["pulsed"]()},e.interval)},transition:function(e){return e},cancel:function(){this["timer"]&&clearTimeout(this["timer"]),this["etime"]=this["btime"],typeof this.restore=="function"&&this.restore(),this.dispatchEvent("oncancel"),this.dispose()},end:function(){this["timer"]&&clearTimeout(this["timer"]),this["etime"]=this["btime"],this["pulsed"]()}}),i.object.each=function(e,t){var n,r,i;if("function"==typeof t)for(r in e)if(e.hasOwnProperty(r)){i=e[r],n=t.call(e,i,r);if(n===!1)break}return e},i.dom=i.dom||{},i.dom.g=function(e){return e?"string"==typeof e||e instanceof String?document.getElementById(e):!e.nodeName||e.nodeType!=1&&e.nodeType!=9?null:e:null},i.g=i.G=i.dom.g,i.dom._g=function(e){return i.lang.isString(e)?document.getElementById(e):e},i._g=i.dom._g,i.dom.getDocument=function(e){return e=i.dom.g(e),e.nodeType==9?e:e.ownerDocument||e.document},i.dom.getComputedStyle=function(e,t){e=i.dom._g(e);var n=i.dom.getDocument(e),r;if(n.defaultView&&n.defaultView.getComputedStyle){r=n.defaultView.getComputedStyle(e,null);if(r)return r[t]||r.getPropertyValue(t)}return""},i.dom._styleFixer=i.dom._styleFixer||{},i.dom._styleFilter=i.dom._styleFilter||[],i.dom._styleFilter.filter=function(e,t,n){for(var r=0,s=i.dom._styleFilter,o;o=s[r];r++)if(o=o[n])t=o(e,t);return t},i.string=i.string||{},i.string.toCamelCase=function(e){return e.indexOf("-")<0&&e.indexOf("_")<0?e:e.replace(/[-_][^-_]/g,function(e){return e.charAt(1).toUpperCase()})},i.dom.getStyle=function(e,t){var n=i.dom;e=n.g(e),t=i.string.toCamelCase(t);var r=e.style[t]||(e.currentStyle?e.currentStyle[t]:"")||n.getComputedStyle(e,t);if(!r||r=="auto"){var s=n._styleFixer[t];s&&(r=s.get?s.get(e,t,r):i.dom.getStyle(e,s))}if(s=n._styleFilter)r=s.filter(t,r,"get");return r},i.getStyle=i.dom.getStyle,i.dom.setStyle=function(e,t,n){var r=i.dom,s;e=r.g(e),t=i.string.toCamelCase(t);if(s=r._styleFilter)n=s.filter(t,n,"set");return s=r._styleFixer[t],s&&s.set?s.set(e,n,t):e.style[s||t]=n,e},i.setStyle=i.dom.setStyle,r.undope=!0;var s=function(e,t,n,s,o){var e=r.g(e);if(!e)return;var u=new i.fx.Timeline({duration:n||400}),a={};r.object.each(t,function(t,n){var i=parseInt(r.dom.getStyle(e,n)),s=parseInt(t),o=s-i;a[n]={gap:o,start:i,end:s}}),u.transition=function(e){return e*(2-e)},u.render=function(n){r.object.each(t,function(t,i){var s=a[i];r.dom.setStyle(e,i,n*s.gap+s.start+"px")}),o&&o(n)},u.finish=function(){r.object.each(t,function(t,n){var i=a[n];r.dom.setStyle(e,n,i.end+"px")}),s&&s()},u.launch()};t.animate=s});
    \ No newline at end of file
    diff --git a/source/static/api/js/component/anticheat.js b/source/static/api/js/component/anticheat.js
    deleted file mode 100644
    index a3d0805c..00000000
    --- a/source/static/api/js/component/anticheat.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("component/anticheat",function(e,t,n){var r=e("base/tangram").T,i,s,o=function(e,t){var n=r(t).offset(),i={left:e.pageX,top:e.pageY};return{left:Math.floor(i.left-n.left),top:Math.floor(i.top-n.top)}},u=function(e,t){typeof i=="undefined"&&(i=Math.floor(e.pageX),s=Math.floor(e.pageY));if(t){var n=o(e,t);r(t).data("over_x",n.left).data("over_y",n.top).data("over_time",+(new Date))}},a=function(e,t){var n=o(e,t);r(t).data("click_x",n.left).data("click_y",n.top)},f=function(e,t,n){e=="mouseenter"?u(t,n):e=="mouseclick"&&a(t,n)},l=function(e){var t=r(e.__element),n=e.__buttonType,o=t.data("over_x")||0,u=t.data("over_y")||0,a=t.data("click_x"),f=t.data("click_y"),l=t.innerWidth(),c=t.innerHeight(),h=new Date-t.data("over_time"),p=document.body.offsetWidth,d=document.body.offsetHeight,v=window.screen.availWidth,m=window.screen.availHeight;return[i,s,n>0?1:0,o,u,a,f,l,c,n,h,p,d,v,m].join(".")};t.process=f,t.getSloc=l});
    \ No newline at end of file
    diff --git a/source/static/api/js/component/comm_tools.js b/source/static/api/js/component/comm_tools.js
    deleted file mode 100644
    index 530bb097..00000000
    --- a/source/static/api/js/component/comm_tools.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -!window._bd_share_is_recently_loaded&&window._bd_share_main.F.module("component/comm_tools",function(e,t){var n=function(){var e=window.location||document.location||{};return e.href||""},r=function(e,t){var n=e.length,r="";for(var i=1;i<=t;i++){var s=Math.floor(n*Math.random());r+=e.charAt(s)}return r},i=function(){var e=(+(new Date)).toString(36),t=r("0123456789abcdefghijklmnopqrstuvwxyz",3);return e+t};t.getLinkId=i,t.getPageUrl=n});
    \ No newline at end of file
    diff --git a/source/static/api/js/component/partners.js b/source/static/api/js/component/partners.js
    deleted file mode 100644
    index 3de5927e..00000000
    --- a/source/static/api/js/component/partners.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("component/partners",function(e,t){t.partners={evernotecn:{name:"\u5370\u8c61\u7b14\u8bb0"},h163:{name:"\u7f51\u6613\u70ed"},mshare:{name:"\u4e00\u952e\u5206\u4eab"},qzone:{name:"QQ\u7a7a\u95f4"},tsina:{name:"\u65b0\u6d6a\u5fae\u535a"},renren:{name:"\u4eba\u4eba\u7f51"},tqq:{name:"\u817e\u8baf\u5fae\u535a"},bdxc:{name:"\u767e\u5ea6\u76f8\u518c"},kaixin001:{name:"\u5f00\u5fc3\u7f51"},tqf:{name:"\u817e\u8baf\u670b\u53cb"},tieba:{name:"\u767e\u5ea6\u8d34\u5427"},douban:{name:"\u8c46\u74e3\u7f51"},bdhome:{name:"\u767e\u5ea6\u65b0\u9996\u9875"},sqq:{name:"QQ\u597d\u53cb"},thx:{name:"\u548c\u8baf\u5fae\u535a"},bdysc:{name:"\u767e\u5ea6\u4e91\u6536\u85cf"},meilishuo:{name:"\u7f8e\u4e3d\u8bf4"},mogujie:{name:"\u8611\u83c7\u8857"},diandian:{name:"\u70b9\u70b9\u7f51"},huaban:{name:"\u82b1\u74e3"},duitang:{name:"\u5806\u7cd6"},hx:{name:"\u548c\u8baf"},fx:{name:"\u98de\u4fe1"},youdao:{name:"\u6709\u9053\u4e91\u7b14\u8bb0"},sdo:{name:"\u9ea6\u5e93\u8bb0\u4e8b"},qingbiji:{name:"\u8f7b\u7b14\u8bb0"},people:{name:"\u4eba\u6c11\u5fae\u535a"},xinhua:{name:"\u65b0\u534e\u5fae\u535a"},mail:{name:"\u90ae\u4ef6\u5206\u4eab"},isohu:{name:"\u6211\u7684\u641c\u72d0"},yaolan:{name:"\u6447\u7bee\u7a7a\u95f4"},wealink:{name:"\u82e5\u90bb\u7f51"},ty:{name:"\u5929\u6daf\u793e\u533a"},fbook:{name:"Facebook"},twi:{name:"Twitter"},linkedin:{name:"linkedin"},copy:{name:"\u590d\u5236\u7f51\u5740"},print:{name:"\u6253\u5370"},ibaidu:{name:"\u767e\u5ea6\u4e2d\u5fc3"},weixin:{name:"\u5fae\u4fe1"},iguba:{name:"\u80a1\u5427"}},t.partnerSort=["mshare","qzone","tsina","bdysc","weixin","renren","tqq","bdxc","kaixin001","tqf","tieba","douban","bdhome","sqq","thx","ibaidu","meilishuo","mogujie","diandian","huaban","duitang","hx","fx","youdao","sdo","qingbiji","people","xinhua","mail","isohu","yaolan","wealink","ty","iguba","fbook","twi","linkedin","h163","evernotecn","copy","print"]});
    \ No newline at end of file
    diff --git a/source/static/api/js/component/pop_base.js b/source/static/api/js/component/pop_base.js
    deleted file mode 100644
    index 0923f443..00000000
    --- a/source/static/api/js/component/pop_base.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("component/pop_base",function(e,t,n){var r=e("base/tangram").T,i=e("conf/const"),s=e("base/class").Class;t.PopBase=s.create(function(t){function s(e){r(e).click(function(e){e=r.event(e||window.event);var t=o(e.target);t&&(e.preventDefault(),n.fire("clickact",{cmd:r(t).attr(n._actBtnSet.cmdAttr),element:t,event:e,buttonType:n._poptype}))}).mouseover(function(e){var t=o(e.target);n.fire("mouseenter",{element:t,event:e}),r(t).attr("data-cmd")=="more"&&n.fire("moreover",{element:t,event:e})})}function o(e){if(u(e))return e;if(n._actBtnSet.maxDomDepth>0){var t=n._actBtnSet.maxDomDepth,i=0,s=r(e).parent().get(0),o=n.entities;while(i<t){if(u(s))return s;s=r(s).parent().get(0);if(r.array(o).contains(s)||s==document.body)break;i++}}return null}function u(e){var t=n._actBtnSet;return e&&e.tagName&&(t.className||t.tagName)?(!t.className||r(e).hasClass(t.className))&&(!t.tagName||e.tagName.toLowerCase()==t.tagName.toLowerCase())&&r(e).attr(t.cmdAttr):!1}var n=this;n._container=null,n._actBtnSet={className:"",tagName:"a",maxDomDepth:0,cmdAttr:i.CMD_ATTR},n._partners=e("component/partners").partners,n._partnerSort=e("component/partners").partnerSort,n._poptype=-1,n.show=function(e,t){window._bd_share_main.F.use("share_popup.css",function(){n._show(e,t)})},n.hide=function(){n._hide(),n.un()},n.init=function(){n._init(),s(n._container)},n._init=function(){},n._show=function(){},n._hide=function(){}})});
    \ No newline at end of file
    diff --git a/source/static/api/js/component/pop_dialog.js b/source/static/api/js/component/pop_dialog.js
    deleted file mode 100644
    index 4ebfaafa..00000000
    --- a/source/static/api/js/component/pop_dialog.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("component/pop_dialog",function(e,t){var n=e("base/tangram").T,r=e("base/class").Class,i=e("conf/const"),s=e("component/pop_base"),o={btn:""},u,a,f,l=r.create(function(){function t(t){t.keyCode==27&&e.hide()}function r(){var e=n.browser.ie==6?n(window).scrollTop():0,t=a.outerWidth(),r=a.outerHeight(),i=n(window).width(),s=n(window).height(),o=(s-r)/2+e,u=(i-t)/2;return{top:o>0?o:0,left:u>0?u:0}}function i(t,r){var i=n.extend({},e._partnerSort,r.bdDialogPartners),s=[];n.each(i,function(t,n){s[t]='<li><a href="#" onclick="return false;" class="popup_'+n+'" data-cmd="'+n+'">'+e._partners[n].name+"</a></li>"}),e._container.html(s.join(""))}var e=this;e._poptype=2,e._hide=function(){f&&f.hide(),a&&a.hide(),n("body").unbind("keydown",t)},e._show=function(s,o){i(e._container,o);var u=r();n.each([a,f],function(e,t){t.css({top:u.top,left:u.left}).show()}),n("body").bind("keydown",t),window._bd_share_main.F.use("trans/logger",function(e){e.dialog()})},e._init=function(){var t=['<iframe frameborder="0" class="bdshare_dialog_bg" style="display:none;"></iframe>'].join(""),r=['<div class="bdshare_dialog_box" style="display:none;">','<div class="bdshare_dialog_top">','<a class="bdshare_dialog_close" href="#" onclick="return false;" title="\u5173\u95ed"></a>\u5206\u4eab\u5230',"</div>",'<ul class="bdshare_dialog_list"></ul>','<div class="bdshare_dialog_bottom">','<a href="http://share.baidu.com/" target="_blank;">\u767e\u5ea6\u5206\u4eab</a>',"</div>","</div>"].join("");n("body").insertHTML("beforeEnd",t+r),e._container=n(".bdshare_dialog_list"),a=n(".bdshare_dialog_box"),f=n(".bdshare_dialog_bg"),n(".bdshare_dialog_close").click(e.hide)}},s.PopBase);t.Dialog=function(){return u||(u=new l,u.init()),u}()});
    \ No newline at end of file
    diff --git a/source/static/api/js/component/pop_popup.js b/source/static/api/js/component/pop_popup.js
    deleted file mode 100644
    index db24c386..00000000
    --- a/source/static/api/js/component/pop_popup.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("component/pop_popup",function(e,t){var n=e("base/tangram").T,r=e("base/class").Class,i=e("conf/const"),s=e("component/pop_base"),o={btn:""},u,a,f,l,c=r.create(function(){function t(t,r){var i=r.bdMini||2,s=r.bdMiniList||e._partnerSort.slice(0,8*i),o=[];n.each(s,function(t,n){o[t]='<li><a href="#" onclick="return false;" class="popup_'+n+'" data-cmd="'+n+'">'+e._partners[n].name+"</a></li>"}),l.html(o.join("")),a.width(i*110+6),f.height(a.outerHeight()),f.width(a.outerWidth())}var e=this;e._poptype=1,e._hide=function(){f&&f.hide(),a&&a.hide()},e._show=function(r,i){t(e._container,i);var s=e._getPosition(r.element,i);n.each([a,f],function(e,t){t.css({top:s.top,left:s.left}).show()}),n(r.element).one("mouseout",function(){var t=!1;a.one("mouseover",function(){t=!0}),setTimeout(function(){!t&&e.hide()},300)})},e._getPosition=function(e,t){var r=n(e).offset(),i=r.top+n(e).height()+5,s=r.left,o=a.outerHeight(),u=n(window).scrollTop();if(i+o>n("body").height()&&i+o>n(window).height()||i+o>u+n(window).height())i=r.top-o-5,i=i<u?u:i;var f=t.bdPopupOffsetLeft,l=t.bdPopupOffsetTop;if(f||l)i+=l|0,s+=f|0;return{top:i,left:s}},e._init=function(){var t="bdSharePopup_"+ +(new Date),r=['<iframe frameborder="0" id="'+t+'bg" class="bdshare_popup_bg" style="display:none;"></iframe>'].join(""),i=['<div class="bdshare_popup_box" id="'+t+'box" style="display:none;">','<div class="bdshare_popup_top">',"\u5206\u4eab\u5230","</div>",'<ul class="bdshare_popup_list"></ul>','<div class="bdshare_popup_bottom">','<a href="#" onclick="return false;" class="popup_more"  data-cmd="more" target="_blank;">\u66f4\u591a...</a>',"</div>","</div>"].join("");n("body").insertHTML("beforeEnd",r+i),e._container=a=n("#"+t+"box"),l=a.find(".bdshare_popup_list"),f=n("#"+t+"bg"),a.mouseleave(e.hide)}},s.PopBase);t.Popup=function(){return u||(u=new c,u.init()),u}()});
    \ No newline at end of file
    diff --git a/source/static/api/js/component/pop_popup_slide.js b/source/static/api/js/component/pop_popup_slide.js
    deleted file mode 100644
    index 658726c8..00000000
    --- a/source/static/api/js/component/pop_popup_slide.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("component/pop_popup_slide",function(e,t){var n=e("base/tangram").T,r=e("base/class").Class,i=e("conf/const"),s=e("component/pop_base"),o={btn:""},u,a,f,l,c=r.create(function(){function t(e){var t=n(e).offset(),r=t.top+n(e).height()+5,i=t.left,s=a.outerHeight();return r+s>n("body").height()&&r+s>n(window).height()&&(r=t.top-s-5,r=r<0?0:r),{top:r,left:i}}function r(t,r){var i=r.mini||2,s=r.miniList||e._partnerSort.slice(0,8*i),o=[];n.each(s,function(t,n){if(!/(iPhone | iPad | Android)/i.test(navigator.userAgent)||n!=="weixin")o[t]='<li><a href="#" onclick="return false;" class="popup_'+n+'" data-cmd="'+n+'">'+e._partners[n].name+"</a></li>"}),l.html(o.join("")),a.width(i*110+6),f.width(i*110+6)}var e=this;e._hide=function(){f&&f.hide(),a&&a.hide()},e._show=function(i,s){r(e._container,s);var o=t(i.element);n.each([a,f],function(e,t){t.css({top:o.top,left:o.left}).show()}),n(i.element).one("mouseout",function(){var t=!1;a.one("mouseover",function(){t=!0}),setTimeout(function(){!t&&e.hide()},300)})},e._init=function(){var t=['<iframe frameborder="0" class="bdshare_popup_bg" style="display:none;"></iframe>'].join(""),r=['<div class="bdshare_popup_box" style="display:none;">','<div class="bdshare_popup_top">',"\u5206\u4eab\u5230","</div>",'<ul class="bdshare_popup_list"></ul>','<div class="bdshare_popup_bottom">','<a href="http://share.baidu.com/" class="popup_more"  data-cmd="more" target="_blank;">\u66f4\u591a...</a>',"</div>","</div>"].join("");n("body").insertHTML("beforeEnd",t+r),e._container=n(".bdshare_popup_box"),a=n(".bdshare_popup_box"),l=n(".bdshare_popup_list"),f=n(".bdshare_popup_bg"),a.mouseleave(e.hide)}},s.PopBase);t.Popup=function(){return u||(u=new c,u.init()),u}()});
    \ No newline at end of file
    diff --git a/source/static/api/js/component/qrcode.js b/source/static/api/js/component/qrcode.js
    deleted file mode 100644
    index 123621fd..00000000
    --- a/source/static/api/js/component/qrcode.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("component/qrcode",function(e,t){function n(e){this.mode=i.MODE_8BIT_BYTE,this.data=e}function r(e,t){this.typeNumber=e,this.errorCorrectLevel=t,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=new Array}function l(e,t){if(e.length==undefined)throw new Error(e.length+"/"+t);var n=0;while(n<e.length&&e[n]==0)n++;this.num=new Array(e.length-n+t);for(var r=0;r<e.length-n;r++)this.num[r]=e[r+n]}function c(e,t){this.totalCount=e,this.dataCount=t}function h(){this.buffer=new Array,this.length=0}n.prototype={getLength:function(e){return this.data.length},write:function(e){for(var t=0;t<this.data.length;t++)e.put(this.data.charCodeAt(t),8)}},r.prototype={addData:function(e){var t=new n(e);this.dataList.push(t),this.dataCache=null},isDark:function(e,t){if(e<0||this.moduleCount<=e||t<0||this.moduleCount<=t)throw new Error(e+","+t);return this.modules[e][t]},getModuleCount:function(){return this.moduleCount},make:function(){if(this.typeNumber<1){var e=1;for(e=1;e<40;e++){var t=c.getRSBlocks(e,this.errorCorrectLevel),n=new h,r=0;for(var i=0;i<t.length;i++)r+=t[i].dataCount;for(var i=0;i<this.dataList.length;i++){var s=this.dataList[i];n.put(s.mode,4),n.put(s.getLength(),u.getLengthInBits(s.mode,e)),s.write(n)}if(n.getLengthInBits()<=r*8)break}this.typeNumber=e}this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(e,t){this.moduleCount=this.typeNumber*4+17,this.modules=new Array(this.moduleCount);for(var n=0;n<this.moduleCount;n++){this.modules[n]=new Array(this.moduleCount);for(var i=0;i<this.moduleCount;i++)this.modules[n][i]=null}this.setupPositionProbePattern(0,0),this.setupPositionProbePattern(this.moduleCount-7,0),this.setupPositionProbePattern(0,this.moduleCount-7),this.setupPositionAdjustPattern(),this.setupTimingPattern(),this.setupTypeInfo(e,t),this.typeNumber>=7&&this.setupTypeNumber(e),this.dataCache==null&&(this.dataCache=r.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,t)},setupPositionProbePattern:function(e,t){for(var n=-1;n<=7;n++){if(e+n<=-1||this.moduleCount<=e+n)continue;for(var r=-1;r<=7;r++){if(t+r<=-1||this.moduleCount<=t+r)continue;0<=n&&n<=6&&(r==0||r==6)||0<=r&&r<=6&&(n==0||n==6)||2<=n&&n<=4&&2<=r&&r<=4?this.modules[e+n][t+r]=!0:this.modules[e+n][t+r]=!1}}},getBestMaskPattern:function(){var e=0,t=0;for(var n=0;n<8;n++){this.makeImpl(!0,n);var r=u.getLostPoint(this);if(n==0||e>r)e=r,t=n}return t},createMovieClip:function(e,t,n){var r=e.createEmptyMovieClip(t,n),i=1;this.make();for(var s=0;s<this.modules.length;s++){var o=s*i;for(var u=0;u<this.modules[s].length;u++){var a=u*i,f=this.modules[s][u];f&&(r.beginFill(0,100),r.moveTo(a,o),r.lineTo(a+i,o),r.lineTo(a+i,o+i),r.lineTo(a,o+i),r.endFill())}}return r},setupTimingPattern:function(){for(var e=8;e<this.moduleCount-8;e++){if(this.modules[e][6]!=null)continue;this.modules[e][6]=e%2==0}for(var t=8;t<this.moduleCount-8;t++){if(this.modules[6][t]!=null)continue;this.modules[6][t]=t%2==0}},setupPositionAdjustPattern:function(){var e=u.getPatternPosition(this.typeNumber);for(var t=0;t<e.length;t++)for(var n=0;n<e.length;n++){var r=e[t],i=e[n];if(this.modules[r][i]!=null)continue;for(var s=-2;s<=2;s++)for(var o=-2;o<=2;o++)s==-2||s==2||o==-2||o==2||s==0&&o==0?this.modules[r+s][i+o]=!0:this.modules[r+s][i+o]=!1}},setupTypeNumber:function(e){var t=u.getBCHTypeNumber(this.typeNumber);for(var n=0;n<18;n++){var r=!e&&(t>>n&1)==1;this.modules[Math.floor(n/3)][n%3+this.moduleCount-8-3]=r}for(var n=0;n<18;n++){var r=!e&&(t>>n&1)==1;this.modules[n%3+this.moduleCount-8-3][Math.floor(n/3)]=r}},setupTypeInfo:function(e,t){var n=this.errorCorrectLevel<<3|t,r=u.getBCHTypeInfo(n);for(var i=0;i<15;i++){var s=!e&&(r>>i&1)==1;i<6?this.modules[i][8]=s:i<8?this.modules[i+1][8]=s:this.modules[this.moduleCount-15+i][8]=s}for(var i=0;i<15;i++){var s=!e&&(r>>i&1)==1;i<8?this.modules[8][this.moduleCount-i-1]=s:i<9?this.modules[8][15-i-1+1]=s:this.modules[8][15-i-1]=s}this.modules[this.moduleCount-8][8]=!e},mapData:function(e,t){var n=-1,r=this.moduleCount-1,i=7,s=0;for(var o=this.moduleCount-1;o>0;o-=2){o==6&&o--;for(;;){for(var a=0;a<2;a++)if(this.modules[r][o-a]==null){var f=!1;s<e.length&&(f=(e[s]>>>i&1)==1);var l=u.getMask(t,r,o-a);l&&(f=!f),this.modules[r][o-a]=f,i--,i==-1&&(s++,i=7)}r+=n;if(r<0||this.moduleCount<=r){r-=n,n=-n;break}}}}},r.PAD0=236,r.PAD1=17,r.createData=function(e,t,n){var i=c.getRSBlocks(e,t),s=new h;for(var o=0;o<n.length;o++){var a=n[o];s.put(a.mode,4),s.put(a.getLength(),u.getLengthInBits(a.mode,e)),a.write(s)}var f=0;for(var o=0;o<i.length;o++)f+=i[o].dataCount;if(s.getLengthInBits()>f*8)throw new Error("code length overflow. ("+s.getLengthInBits()+">"+f*8+")");s.getLengthInBits()+4<=f*8&&s.put(0,4);while(s.getLengthInBits()%8!=0)s.putBit(!1);for(;;){if(s.getLengthInBits()>=f*8)break;s.put(r.PAD0,8);if(s.getLengthInBits()>=f*8)break;s.put(r.PAD1,8)}return r.createBytes(s,i)},r.createBytes=function(e,t){var n=0,r=0,i=0,s=new Array(t.length),o=new Array(t.length);for(var a=0;a<t.length;a++){var f=t[a].dataCount,c=t[a].totalCount-f;r=Math.max(r,f),i=Math.max(i,c),s[a]=new Array(f);for(var h=0;h<s[a].length;h++)s[a][h]=255&e.buffer[h+n];n+=f;var p=u.getErrorCorrectPolynomial(c),d=new l(s[a],p.getLength()-1),v=d.mod(p);o[a]=new Array(p.getLength()-1);for(var h=0;h<o[a].length;h++){var m=h+v.getLength()-o[a].length;o[a][h]=m>=0?v.get(m):0}}var g=0;for(var h=0;h<t.length;h++)g+=t[h].totalCount;var y=new Array(g),b=0;for(var h=0;h<r;h++)for(var a=0;a<t.length;a++)h<s[a].length&&(y[b++]=s[a][h]);for(var h=0;h<i;h++)for(var a=0;a<t.length;a++)h<o[a].length&&(y[b++]=o[a][h]);return y};var i={MODE_NUMBER:1,MODE_ALPHA_NUM:2,MODE_8BIT_BYTE:4,MODE_KANJI:8},s={L:1,M:0,Q:3,H:2},o={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7},u={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:1335,G18:7973,G15_MASK:21522,getBCHTypeInfo:function(e){var t=e<<10;while(u.getBCHDigit(t)-u.getBCHDigit(u.G15)>=0)t^=u.G15<<u.getBCHDigit(t)-u.getBCHDigit(u.G15);return(e<<10|t)^u.G15_MASK},getBCHTypeNumber:function(e){var t=e<<12;while(u.getBCHDigit(t)-u.getBCHDigit(u.G18)>=0)t^=u.G18<<u.getBCHDigit(t)-u.getBCHDigit(u.G18);return e<<12|t},getBCHDigit:function(e){var t=0;while(e!=0)t++,e>>>=1;return t},getPatternPosition:function(e){return u.PATTERN_POSITION_TABLE[e-1]},getMask:function(e,t,n){switch(e){case o.PATTERN000:return(t+n)%2==0;case o.PATTERN001:return t%2==0;case o.PATTERN010:return n%3==0;case o.PATTERN011:return(t+n)%3==0;case o.PATTERN100:return(Math.floor(t/2)+Math.floor(n/3))%2==0;case o.PATTERN101:return t*n%2+t*n%3==0;case o.PATTERN110:return(t*n%2+t*n%3)%2==0;case o.PATTERN111:return(t*n%3+(t+n)%2)%2==0;default:throw new Error("bad maskPattern:"+e)}},getErrorCorrectPolynomial:function(e){var t=new l([1],0);for(var n=0;n<e;n++)t=t.multiply(new l([1,a.gexp(n)],0));return t},getLengthInBits:function(e,t){if(1<=t&&t<10)switch(e){case i.MODE_NUMBER:return 10;case i.MODE_ALPHA_NUM:return 9;case i.MODE_8BIT_BYTE:return 8;case i.MODE_KANJI:return 8;default:throw new Error("mode:"+e)}else if(t<27)switch(e){case i.MODE_NUMBER:return 12;case i.MODE_ALPHA_NUM:return 11;case i.MODE_8BIT_BYTE:return 16;case i.MODE_KANJI:return 10;default:throw new Error("mode:"+e)}else{if(!(t<41))throw new Error("type:"+t);switch(e){case i.MODE_NUMBER:return 14;case i.MODE_ALPHA_NUM:return 13;case i.MODE_8BIT_BYTE:return 16;case i.MODE_KANJI:return 12;default:throw new Error("mode:"+e)}}},getLostPoint:function(e){var t=e.getModuleCount(),n=0;for(var r=0;r<t;r++)for(var i=0;i<t;i++){var s=0,o=e.isDark(r,i);for(var u=-1;u<=1;u++){if(r+u<0||t<=r+u)continue;for(var a=-1;a<=1;a++){if(i+a<0||t<=i+a)continue;if(u==0&&a==0)continue;o==e.isDark(r+u,i+a)&&s++}}s>5&&(n+=3+s-5)}for(var r=0;r<t-1;r++)for(var i=0;i<t-1;i++){var f=0;e.isDark(r,i)&&f++,e.isDark(r+1,i)&&f++,e.isDark(r,i+1)&&f++,e.isDark(r+1,i+1)&&f++;if(f==0||f==4)n+=3}for(var r=0;r<t;r++)for(var i=0;i<t-6;i++)e.isDark(r,i)&&!e.isDark(r,i+1)&&e.isDark(r,i+2)&&e.isDark(r,i+3)&&e.isDark(r,i+4)&&!e.isDark(r,i+5)&&e.isDark(r,i+6)&&(n+=40);for(var i=0;i<t;i++)for(var r=0;r<t-6;r++)e.isDark(r,i)&&!e.isDark(r+1,i)&&e.isDark(r+2,i)&&e.isDark(r+3,i)&&e.isDark(r+4,i)&&!e.isDark(r+5,i)&&e.isDark(r+6,i)&&(n+=40);var l=0;for(var i=0;i<t;i++)for(var r=0;r<t;r++)e.isDark(r,i)&&l++;var c=Math.abs(100*l/t/t-50)/5;return n+=c*10,n}},a={glog:function(e){if(e<1)throw new Error("glog("+e+")");return a.LOG_TABLE[e]},gexp:function(e){while(e<0)e+=255;while(e>=256)e-=255;return a.EXP_TABLE[e]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)};for(var f=0;f<8;f++)a.EXP_TABLE[f]=1<<f;for(var f=8;f<256;f++)a.EXP_TABLE[f]=a.EXP_TABLE[f-4]^a.EXP_TABLE[f-5]^a.EXP_TABLE[f-6]^a.EXP_TABLE[f-8];for(var f=0;f<255;f++)a.LOG_TABLE[a.EXP_TABLE[f]]=f;l.prototype={get:function(e){return this.num[e]},getLength:function(){return this.num.length},multiply:function(e){var t=new Array(this.getLength()+e.getLength()-1);for(var n=0;n<this.getLength();n++)for(var r=0;r<e.getLength();r++)t[n+r]^=a.gexp(a.glog(this.get(n))+a.glog(e.get(r)));return new l(t,0)},mod:function(e){if(this.getLength()-e.getLength()<0)return this;var t=a.glog(this.get(0))-a.glog(e.get(0)),n=new Array(this.getLength());for(var r=0;r<this.getLength();r++)n[r]=this.get(r);for(var r=0;r<e.getLength();r++)n[r]^=a.gexp(a.glog(e.get(r))+t);return(new l(n,0)).mod(e)}},c.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]],c.getRSBlocks=function(e,t){var n=c.getRsBlockTable(e,t);if(n==undefined)throw new Error("bad rs block @ typeNumber:"+e+"/errorCorrectLevel:"+t);var r=n.length/3,i=new Array;for(var s=0;s<r;s++){var o=n[s*3+0],u=n[s*3+1],a=n[s*3+2];for(var f=0;f<o;f++)i.push(new c(u,a))}return i},c.getRsBlockTable=function(e,t){switch(t){case s.L:return c.RS_BLOCK_TABLE[(e-1)*4+0];case s.M:return c.RS_BLOCK_TABLE[(e-1)*4+1];case s.Q:return c.RS_BLOCK_TABLE[(e-1)*4+2];case s.H:return c.RS_BLOCK_TABLE[(e-1)*4+3];default:return undefined}},h.prototype={get:function(e){var t=Math.floor(e/8);return(this.buffer[t]>>>7-e%8&1)==1},put:function(e,t){for(var n=0;n<t;n++)this.putBit((e>>>t-n-1&1)==1)},getLengthInBits:function(){return this.length},putBit:function(e){var t=Math.floor(this.length/8);this.buffer.length<=t&&this.buffer.push(0),e&&(this.buffer[t]|=128>>>this.length%8),this.length++}},t.QRCode=r,t.QRErrorCorrectLevel=s});
    \ No newline at end of file
    diff --git a/source/static/api/js/conf/const.js b/source/static/api/js/conf/const.js
    deleted file mode 100644
    index ae109027..00000000
    --- a/source/static/api/js/conf/const.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -!window._bd_share_is_recently_loaded&&window._bd_share_main.F.module("conf/const",function(e,t,n){t.CMD_ATTR="data-cmd",t.CONFIG_TAG_ATTR="data-tag",t.URLS={likeSetUrl:"http://like.baidu.com/set",commitUrl:"http://s.share.baidu.com/commit",jumpUrl:"http://s.share.baidu.com",mshareUrl:"http://s.share.baidu.com/mshare",emailUrl:"http://s.share.baidu.com/sendmail",nsClick:"http://nsclick.baidu.com/v.gif",backUrl:"http://s.share.baidu.com/back",shortUrl:"http://dwz.cn/v2cut.php"}});
    \ No newline at end of file
    diff --git a/source/static/api/js/conf/define.js b/source/static/api/js/conf/define.js
    deleted file mode 100644
    index 1ffdf8d6..00000000
    --- a/source/static/api/js/conf/define.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main?window._bd_share_is_recently_loaded=!0:(window._bd_share_is_recently_loaded=!1,window._bd_share_main={version:"2.0",jscfg:{domain:{staticUrl:"/"}}});
    \ No newline at end of file
    diff --git a/source/static/api/js/share.js b/source/static/api/js/share.js
    deleted file mode 100644
    index f81ca2a6..00000000
    --- a/source/static/api/js/share.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main?window._bd_share_is_recently_loaded=!0:(window._bd_share_is_recently_loaded=!1,window._bd_share_main={version:"2.0",jscfg:{domain:{staticUrl:"/"}}}),!window._bd_share_is_recently_loaded&&(window._bd_share_main.F=window._bd_share_main.F||function(e,t){function n(e,t){if(e instanceof Array){for(var n=0,s=e.length;s>n;n++)if(t.call(e[n],e[n],n)===!1)return}else for(var n in e)if(e.hasOwnProperty(n)&&t.call(e[n],e[n],n)===!1)return}function s(e,t){if(this.svnMod="",this.name=null,this.path=e,this.fn=null,this.exports={},this._loaded=!1,this._requiredStack=[],this._readyStack=[],s.cache[this.path]=this,t&&"."!==t.charAt(0)){var n=t.split(":");n.length>1?(this.svnMod=n[0],this.name=n[1]):this.name=t}this.svnMod||(this.svnMod=this.path.split("/js/")[0].substr(1)),this.type="js",this.getKey=function(){return this.svnMod+":"+this.name},this._info={}}function i(e,t){var n="css"==t,s=document.createElement(n?"link":"script");return s}function a(t,n,s,a){function c(){c.isCalled||(c.isCalled=!0,clearTimeout(_),s&&s())}var d=i(t,n);"SCRIPT"===d.nodeName?r(d,c):o(d,c);var _=setTimeout(function(){throw new Error("load "+n+" timeout : "+t)},e._loadScriptTimeout||1e4),l=document.getElementsByTagName("head")[0];"css"==n?(d.rel="stylesheet",d.href=t,l.appendChild(d)):(d.type="text/javascript",d.src=t,l.insertBefore(d,l.firstChild))}function r(e,t){e.onload=e.onerror=e.onreadystatechange=function(){if(/loaded|complete|undefined/.test(e.readyState)){if(e.onload=e.onerror=e.onreadystatechange=null,e.parentNode){e.parentNode.removeChild(e);try{if(e.clearAttributes)e.clearAttributes();else for(var n in e)delete e[n]}catch(s){}}e=void 0,t&&t()}}}function o(e,t){e.attachEvent?e.attachEvent("onload",t):setTimeout(function(){c(e,t)},0)}function c(e,t){if(!t||!t.isCalled){var n,s=navigator.userAgent,i=~s.indexOf("AppleWebKit"),a=~s.indexOf("Opera");if(i||a)e.sheet&&(n=!0);else if(e.sheet)try{e.sheet.cssRules&&(n=!0)}catch(r){("SecurityError"===r.name||"NS_ERROR_DOM_SECURITY_ERR"===r.name)&&(n=!0)}setTimeout(function(){n?t&&t():c(e,t)},1)}}var d="api";e.each=n,s.currentPath="",s.loadedPaths={},s.loadingPaths={},s.cache={},s.paths={},s.handlers=[],s.moduleFileMap={},s.requiredPaths={},s.lazyLoadPaths={},s.services={},s.isPathsLoaded=function(e){var t=!0;return n(e,function(e){return e in s.loadedPaths?void 0:t=!1}),t},s.require=function(e,t){e.search(":")<0&&(t||(t=d,s.currentPath&&(t=s.currentPath.split("/js/")[0].substr(1))),e=t+":"+e);var n=s.get(e,s.currentPath);if("css"!=n.type){if(n){if(!n._inited){n._inited=!0;var i,a=n.svnMod;(i=n.fn.call(null,function(e){return s.require(e,a)},n.exports,new h(n.name,a)))&&(n.exports=i)}return n.exports}throw new Error('Module "'+e+'" not found!')}},s.baseUrl=t?"/"==t[t.length-1]?t:t+"/":"/",s.getBasePath=function(e){var t,n;return-1!==(n=e.indexOf("/"))&&(t=e.slice(0,n)),t&&t in s.paths?s.paths[t]:s.baseUrl},s.getJsPath=function(t,n){if("."===t.charAt(0)){n=n.replace(/\/[^\/]+\/[^\/]+$/,""),0===t.search("./")&&(t=t.substr(2));var i=0;for(t=t.replace(/^(\.\.\/)+/g,function(e){return i=e.length/3,""});i>0;)n=n.substr(0,n.lastIndexOf("/")),i--;return n+"/"+t+"/"+t.substr(t.lastIndexOf("/")+1)+".js"}var a,r,o,c,_,l;if(t.search(":")>=0){var h=t.split(":");a=h[0],t=h[1]}else n&&(a=n.split("/")[1]);a=a||d;var u=/\.css(?:\?|$)/i.test(t);u&&e._useConfig&&s.moduleFileMap[a][t]&&(t=s.moduleFileMap[a][t]);var t=_=t,f=s.getBasePath(t);return-1!==(o=t.indexOf("/"))&&(r=t.slice(0,o),c=t.lastIndexOf("/"),_=t.slice(c+1)),r&&r in s.paths&&(t=t.slice(o+1)),l=f+a+"/js/"+t+".js"},s.get=function(e,t){var n=s.getJsPath(e,t);return s.cache[n]?s.cache[n]:new s(n,e)},s.prototype={load:function(){s.loadingPaths[this.path]=!0;var t=this.svnMod||d,n=window._bd_share_main.jscfg.domain.staticUrl+"static/"+t+"/",i=this,a=/\.css(?:\?|$)/i.test(this.name);this.type=a?"css":"js";var r="/"+this.type+"/"+s.moduleFileMap[t][this.name];if(n+=e._useConfig&&s.moduleFileMap[t][this.name]?this.type+"/"+s.moduleFileMap[t][this.name]:this.type+"/"+this.name+(a?"":".js"),e._firstScreenCSS.indexOf(this.name)>0||e._useConfig&&r==e._firstScreenJS)i._loaded=!0,i.ready();else{var o=(new Date).getTime();_.create({src:n,type:this.type,loaded:function(){i._info.loadedTime=(new Date).getTime()-o,"css"==i.type&&(i._loaded=!0,i.ready())}})}},lazyLoad:function(){if(this.name,s.lazyLoadPaths[this.getKey()])this.define(),delete s.lazyLoadPaths[this.getKey()];else{if(this.exist())return;s.requiredPaths[this.getKey()]=!0,this.load()}},ready:function(e,t){var i=t?this._requiredStack:this._readyStack;if(e)this._loaded?e():i.push(e);else{if(s.loadedPaths[this.path]=!0,delete s.loadingPaths[this.path],this._loaded=!0,s.currentPath=this.path,this._readyStack&&this._readyStack.length>0){this._inited=!0;var a,r=this.svnMod;this.fn&&(a=this.fn.call(null,function(e){return s.require(e,r)},this.exports,new h(this.name,r)))&&(this.exports=a),n(this._readyStack,function(e){e()}),delete this._readyStack}this._requiredStack&&this._requiredStack.length>0&&(n(this._requiredStack,function(e){e()}),delete this._requiredStack)}},define:function(){var e=this,t=this.deps,i=(this.path,[]);t||(t=this.getDependents()),t.length?(n(t,function(t){i.push(s.getJsPath(t,e.path))}),n(t,function(t){var n=s.get(t,e.path);n.ready(function(){s.isPathsLoaded(i)&&e.ready()},!0),n.lazyLoad()})):this.ready()},exist:function(){var e=this.path;return e in s.loadedPaths||e in s.loadingPaths},getDependents:function(){var e=this.fn.toString(),t=e.match(/function\s*\(([^,]*),/i),s=new RegExp("[^.]\\b"+t[1]+"\\(\\s*('|\")([^()\"']*)('|\")\\s*\\)","g"),i=e.match(s),a=[];return i&&n(i,function(e,n){a[n]=e.substr(t[1].length+3).slice(0,-2)}),a}};var _={create:function(e){var t=e.src;t in this._paths||(this._paths[t]=!0,n(this._rules,function(e){t=e.call(null,t)}),a(t,e.type,e.loaded))},_paths:{},_rules:[],addPathRule:function(e){this._rules.push(e)}};e.version="1.0",e.use=function(e,t){"string"==typeof e&&(e=[e]);var i=[],a=[];n(e,function(e,t){a[t]=!1}),n(e,function(e,r){var o=s.get(e),c=o._loaded;o.ready(function(){var e=o.exports||{};e._INFO=o._info,e._INFO&&(e._INFO.isNew=!c),i[r]=e,a[r]=!0;var s=!0;n(a,function(e){return e===!1?s=!1:void 0}),t&&s&&t.apply(null,i)}),o.lazyLoad()})},e.module=function(e,t,n){var i=s.get(e);i.fn=t,i.deps=n,s.requiredPaths[i.getKey()]?i.define():s.lazyLoadPaths[i.getKey()]=!0},e.pathRule=function(e){_.addPathRule(e)},e._addPath=function(e,t){if("/"!==t.slice(-1)&&(t+="/"),e in s.paths)throw new Error(e+" has already in Module.paths");s.paths[e]=t};var l=d;e._setMod=function(e){l=e||d},e._fileMap=function(t,i){if("object"==typeof t)n(t,function(t,n){e._fileMap(n,t)});else{var a=l;"string"==typeof i&&(i=[i]),t=1==t.indexOf("js/")?t.substr(4):t,t=1==t.indexOf("css/")?t.substr(5):t;var r=s.moduleFileMap[a];r||(r={}),n(i,function(e){r[e]||(r[e]=t)}),s.moduleFileMap[a]=r}},e._eventMap={},e.call=function(t,n,s){for(var i=[],a=2,r=arguments.length;r>a;a++)i.push(arguments[a]);e.use(t,function(e){for(var t=n.split("."),s=0,a=t.length;a>s;s++)e=e[t[s]];e&&e.apply(this,i)})},e._setContext=function(e){"object"==typeof e&&n(e,function(e,t){h.prototype[t]=s.require(e)})},e._setContextMethod=function(e,t){h.prototype[e]=t};var h=function(e,t){this.modName=e,this.svnMod=t};return h.prototype={domain:window._bd_share_main.jscfg.domain,use:function(t,n){"string"==typeof t&&(t=[t]);for(var s=t.length-1;s>=0;s--)t[s]=this.svnMod+":"+t[s];e.use(t,n)}},e._Context=h,e.addLog=function(t,n){e.use("lib/log",function(e){e.defaultLog(t,n)})},e.fire=function(t,n,s){e.use("lib/mod_evt",function(e){e.fire(t,n,s)})},e._defService=function(e,t){if(e){var i=s.services[e];i=i||{},n(t,function(e,t){i[t]=e}),s.services[e]=i}},e.getService=function(t,n,i){var a=s.services[t];if(!a)throw new Error(t+" mod didn't define any services");var r=a[n];if(!r)throw new Error(t+" mod didn't provide service "+n);e.use(t+":"+r,i)},e}({})),!window._bd_share_is_recently_loaded&&window._bd_share_main.F.module("base/min_tangram",function(e,t){var n={};n.each=function(e,t,n){var s,i,a,r=e.length;if("function"==typeof t)for(a=0;r>a&&(i=e[a],s=t.call(n||e,a,i),s!==!1);a++);return e};var s=function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e};n.extend=function(){for(var e=arguments[0],t=1,n=arguments.length;n>t;t++)s(e,arguments[t]);return e},n.domready=function(e,t){if(t=t||document,/complete/.test(t.readyState))e();else if(t.addEventListener)"interactive"==t.readyState?e():t.addEventListener("DOMContentLoaded",e,!1);else{var n=function(){n=new Function,e()};void function(){try{t.body.doScroll("left")}catch(e){return setTimeout(arguments.callee,10)}n()}(),t.attachEvent("onreadystatechange",function(){"complete"==t.readyState&&n()})}},n.isArray=function(e){return"[object Array]"==Object.prototype.toString.call(e)},t.T=n}),!window._bd_share_is_recently_loaded&&window._bd_share_main.F.module("base/class",function(e,t,n){var s=e("base/min_tangram").T;t.BaseClass=function(){var e=this,t={};e.on=function(e,n){var s=t[e];s||(s=t[e]=[]),s.push(n)},e.un=function(e,n){if(!e)return void(t={});var i=t[e];i&&(n?s.each(i,function(e,t){return t==n?(i.splice(e,1),!1):void 0}):t[e]=[])},e.fire=function(n,i){var a=t[n];a&&(i=i||{},s.each(a,function(t,n){i._result=n.call(e,s.extend({_ctx:{src:e}},i))}))}};var i={};i.create=function(e,n){return n=n||t.BaseClass,function(){n.apply(this,arguments);var t=s.extend({},this);e.apply(this,arguments),this._super=t}},t.Class=i}),!window._bd_share_is_recently_loaded&&window._bd_share_main.F.module("conf/const",function(e,t,n){t.CMD_ATTR="data-cmd",t.CONFIG_TAG_ATTR="data-tag",t.URLS={likeSetUrl:"http://like.baidu.com/set",commitUrl:"http://s.share.baidu.com/commit",jumpUrl:"http://s.share.baidu.com",mshareUrl:"http://s.share.baidu.com/mshare",emailUrl:"http://s.share.baidu.com/sendmail",nsClick:"/",backUrl:"http://s.share.baidu.com/back",shortUrl:"http://dwz.cn/v2cut.php"}}),!window._bd_share_is_recently_loaded&&function(){window._bd_share_main.F._setMod("api"),window._bd_share_main.F._fileMap({"/js/share.js?v=da893e3e.js":["conf/define","base/fis","base/tangrammin","base/class.js","conf/define.js","conf/const.js","config","share/api_base.js","view/view_base.js","start/router.js","component/comm_tools.js","trans/trans.js"],"/js/base/tangram.js?v=37768233.js":["base/tangram"],"/js/view/share_view.js?v=3ae6026d.js":["view/share_view"],"/js/view/slide_view.js?v=08373964.js":["view/slide_view"],"/js/view/like_view.js?v=df3e0eca.js":["view/like_view"],"/js/view/select_view.js?v=85fc7cec.js":["view/select_view"],"/js/trans/data.js?v=17af2bd2.js":["trans/data"],"/js/trans/logger.js?v=d16ec0e3.js":["trans/logger"],"/js/trans/trans_bdxc.js?v=7ac21555.js":["trans/trans_bdxc"],"/js/trans/trans_bdysc.js?v=fc21acaa.js":["trans/trans_bdysc"],"/js/trans/trans_weixin.js?v=080be124.js":["trans/trans_weixin"],"/js/share/combine_api.js?v=8d37a7b3.js":["share/combine_api"],"/js/share/like_api.js?v=d3693f0a.js":["share/like_api"],"/js/share/likeshare.js?v=e1f4fbf1.js":["share/likeshare"],"/js/share/share_api.js?v=226108fe.js":["share/share_api"],"/js/share/slide_api.js?v=ec14f516.js":["share/slide_api"],"/js/component/animate.js?v=5b737477.js":["component/animate"],"/js/component/anticheat.js?v=44b9b245.js":["component/anticheat"],"/js/component/partners.js?v=911c4302.js":["component/partners"],"/js/component/pop_base.js?v=36f92e70.js":["component/pop_base"],"/js/component/pop_dialog.js?v=d479767d.js":["component/pop_dialog"],"/js/component/pop_popup.js?v=4387b4e1.js":["component/pop_popup"],"/js/component/pop_popup_slide.js?v=b16a1f10.js":["component/pop_popup_slide"],"/js/component/qrcode.js?v=d69754a9.js":["component/qrcode"],"/css/share_style0_16.css?v=6aba13f0.css":["share_style0_16.css"],"/css/share_style0_32.css?v=4413acf0.css":["share_style0_32.css"],"/css/share_style2.css?v=611d4f74.css":["share_style2.css"],"/css/share_style4.css?v=cef2b8f3.css":["share_style4.css"],"/css/slide_share.css?v=9c50d088.css":["slide_share.css"],"/css/share_popup.css?v=240f357d.css":["share_popup.css"],"/css/like.css?v=d52a0ea5.css":["like.css"],"/css/imgshare.css?v=a7830602.css":["imgshare.css"],"/css/select_share.css?v=15f56735.css":["select_share.css"],"/css/weixin_popup.css?v=1a56666e.css":["weixin_popup.css"]}),window._bd_share_main.F._loadScriptTimeout=15e3,window._bd_share_main.F._useConfig=!0,window._bd_share_main.F._firstScreenCSS="",window._bd_share_main.F._firstScreenJS=""}(),!window._bd_share_is_recently_loaded&&window._bd_share_main.F.use("base/min_tangram",function(e){function t(e,t,n){var s=new e(n);s.setView(new t(n)),s.init(),n&&n._handleId&&(_bd_share_main.api=_bd_share_main.api||{},_bd_share_main.api[n._handleId]=s)}function n(e,n){window._bd_share_main.F.use(e,function(e,s){i.isArray(n)?i.each(n,function(n,i){t(e.Api,s.View,i)}):t(e.Api,s.View,n)})}function s(e){var t=e.common||window._bd_share_config&&_bd_share_config.common||{},n={like:{type:"like"},share:{type:"share",bdStyle:0,bdMini:2,bdSign:"on"},slide:{type:"slide",bdStyle:"1",bdMini:2,bdImg:0,bdPos:"right",bdTop:100,bdSign:"on"},image:{viewType:"list",viewStyle:"0",viewPos:"top",viewColor:"black",viewSize:"16",viewList:["qzone","tsina","huaban","tqq","renren"]},selectShare:{type:"select",bdStyle:0,bdMini:2,bdSign:"on"}},s={share:{__cmd:"",__buttonType:"",__type:"",__element:null},slide:{__cmd:"",__buttonType:"",__type:"",__element:null},image:{__cmd:"",__buttonType:"",__type:"",__element:null}};return i.each(["like","share","slide","image","selectShare"],function(a,r){e[r]&&(i.isArray(e[r])&&e[r].length>0?i.each(e[r],function(a,o){e[r][a]=i.extend({},n[r],t,o,s[r])}):e[r]=i.extend({},n[r],t,e[r],s[r]))}),e}var i=e.T;_bd_share_main.init=function(e){if(e=e||window._bd_share_config||{share:{}}){var t=s(e);t.like&&n(["share/like_api","view/like_view"],t.like),t.share&&n(["share/share_api","view/share_view"],t.share),t.slide&&n(["share/slide_api","view/slide_view"],t.slide),t.selectShare&&n(["share/select_api","view/select_view"],t.selectShare),t.image&&n(["share/image_api","view/image_view"],t.image)}},window._bd_share_main._LogPoolV2=[],window._bd_share_main.n1=(new Date).getTime(),i.domready(function(){window._bd_share_main.n2=(new Date).getTime()+1e3,_bd_share_main.init(),setTimeout(function(){window._bd_share_main.F.use("trans/logger",function(e){e.nsClick(),e.back(),e.duration()})},3e3)})}),!window._bd_share_is_recently_loaded&&window._bd_share_main.F.module("component/comm_tools",function(e,t){var n=function(){var e=window.location||document.location||{};return e.href||""},s=function(e,t){for(var n=e.length,s="",i=1;t>=i;i++){var a=Math.floor(n*Math.random());s+=e.charAt(a)}return s},i=function(){var e=(+new Date).toString(36),t=s("0123456789abcdefghijklmnopqrstuvwxyz",3);return e+t};t.getLinkId=i,t.getPageUrl=n}),!window._bd_share_is_recently_loaded&&window._bd_share_main.F.module("trans/trans",function(e,t){var n=e("component/comm_tools"),s=e("conf/const").URLS,i=function(){window._bd_share_main.F.use("base/tangram",function(e){var t=e.T;null==t.cookie.get("bdshare_firstime")&&t.cookie.set("bdshare_firstime",1*new Date,{path:"/",expires:(new Date).setFullYear(2022)-new Date})})},a=function(e){var t=e.bdUrl||n.getPageUrl();return t=t.replace(/\'/g,"%27").replace(/\"/g,"%22")},r=function(e){var t=(new Date).getTime()+3e3,s={click:1,url:a(e),uid:e.bdUid||"0",to:e.__cmd,type:"text",pic:e.bdPic||"",title:(e.bdText||document.title).substr(0,300),key:(e.bdSnsKey||{})[e.__cmd]||"",desc:e.bdDesc||"",comment:e.bdComment||"",relateUid:e.bdWbuid||"",searchPic:e.bdSearchPic||0,sign:e.bdSign||"on",l:window._bd_share_main.n1.toString(32)+window._bd_share_main.n2.toString(32)+t.toString(32),linkid:n.getLinkId(),firstime:c("bdshare_firstime")||""};switch(e.__cmd){case"copy":_(s);break;case"print":l();break;case"bdxc":h();break;case"bdysc":u(s);break;case"weixin":f(s);break;default:o(e,s)}window._bd_share_main.F.use("trans/logger",function(t){t.commit(e,s)})},o=function(e,t){var n=s.jumpUrl;"mshare"==e.__cmd?n=s.mshareUrl:"mail"==e.__cmd&&(n=s.emailUrl);var i=n+"?"+d(t);window.open(i)},c=function(e){if(e){var t=new RegExp("(^| )"+e+"=([^;]*)(;|$)"),n=t.exec(document.cookie);if(n)return decodeURIComponent(n[2]||null)}},d=function(e){var t=[];for(var n in e)t.push(encodeURIComponent(n)+"="+encodeURIComponent(e[n]));return t.join("&").replace(/%20/g,"+")},_=function(e){window._bd_share_main.F.use("base/tangram",function(t){var s=t.T;s.browser.ie?(window.clipboardData.setData("text",document.title+" "+(e.bdUrl||n.getPageUrl())),alert("标题和链接复制成功,您可以推荐给QQ/MSN上的好友了!")):window.prompt("您使用的是非IE核心浏览器,请按下 Ctrl+C 复制代码到剪贴板",document.title+" "+(e.bdUrl||n.getPageUrl()))})},l=function(){window.print()},h=function(){window._bd_share_main.F.use("trans/trans_bdxc",function(e){e&&e.run()})},u=function(e){window._bd_share_main.F.use("trans/trans_bdysc",function(t){t&&t.run(e)})},f=function(e){window._bd_share_main.F.use("trans/trans_weixin",function(t){t&&t.run(e)})},p=function(e){r(e)};t.run=p,i()});
    \ No newline at end of file
    diff --git a/source/static/api/js/share/api_base.js b/source/static/api/js/share/api_base.js
    deleted file mode 100644
    index 667171c8..00000000
    --- a/source/static/api/js/share/api_base.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("share/api_base",function(e,t,n){var r=e("base/tangram").T,i=e("base/class").Class;t.ApiBase=i.create(function(e){function s(e){window._bd_share_main.F.use("component/anticheat",function(t){t.process("mouseenter",e.event,e.element)}),t._processEvent(e)}function o(n){window._bd_share_main.F.use("component/anticheat",function(e){e.process("mouseclick",n.event,n.element)});var i=t._processAction(n);if(i&&i.data)if(n.cmd=="more"||n.cmd=="count")window._bd_share_main.F.use("component/pop_dialog",function(t){var r=t.Dialog;r.un(),r.on("clickact",o),r.on("mouseenter",s),r.show(n,e)});else if(n.cmd=="popup")u(n);else{var a;r.type(e.onBeforeClick)=="function"&&(a=r.extend({},e),a=e.onBeforeClick(n.cmd,a));var f=r.extend({},e,a,{__type:i.data.type,__buttonType:n.buttonType,__cmd:n.cmd,__element:n.element});window._bd_share_main.F.use("trans/trans",function(e){e.run(f)}),r.type(e.onAfterClick)=="function"&&e.onAfterClick(n.cmd)}}function u(t){window._bd_share_main.F.use("component/pop_popup",function(n){var r=n.Popup;r.un(),r.on("clickact",o),r.on("mouseenter",s),r.show(t,e)})}var t=this,n=null,i=null;t.getView=function(){return n},t.setView=function(e){n=e},t.init=function(){t._init(),n&&(n.on("clickact",o),n.on("mouseenter",s),n.on("moreover",u))},t.distory=function(){t._distory(),n&&(n.un(),n.distory()),delete t},t._init=function(){},t._distory=function(){},t._processEvent=function(e){},t._processAction=function(e){}})});
    \ No newline at end of file
    diff --git a/source/static/api/js/share/combine_api.js b/source/static/api/js/share/combine_api.js
    deleted file mode 100644
    index dcf4322b..00000000
    --- a/source/static/api/js/share/combine_api.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("share/combine_api",function(e,t,n){var r=e("base/tangram").T,i=e("base/class").Class,s=e("share/api_base");t.CombineApi=i.create(function(e){var t=this,n=null,r=null;t.setApi=function(e,t){n=e,r=t},t._init=function(){n&&r&&n.on("sharecompleted",function(e){})}},s.ApiBase)});
    \ No newline at end of file
    diff --git a/source/static/api/js/share/image_api.js b/source/static/api/js/share/image_api.js
    deleted file mode 100644
    index bb50abd1..00000000
    --- a/source/static/api/js/share/image_api.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("share/image_api",function(e,t,n){var r=e("base/tangram").T,i=e("base/class").Class,s=e("component/comm_tools"),o=e("share/api_base");t.Api=i.create(function(e){var t=this;t._init=function(){var e=t.getView();e.render(),e.init(),e.on("moreover",function(){e._keepBarVisible()})},t._processAction=function(n){var r=t.getView();return e.bdPic=r._getImageSrc(),{data:{type:"imgshare"}}},t._distory=function(){}},o.ApiBase)});
    \ No newline at end of file
    diff --git a/source/static/api/js/share/like_api.js b/source/static/api/js/share/like_api.js
    deleted file mode 100644
    index cd53b222..00000000
    --- a/source/static/api/js/share/like_api.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("share/like_api",function(e,t,n){var r=e("base/tangram").T,i=e("base/class").Class,s=e("share/api_base");t.Api=i.create(function(e){function r(e){window._bd_share_main.F.use("trans/data",function(t){t.get({type:"like_count",url:document.location.href,callback:function(t){var n={count:t};e&&e(n)}})})}function i(t){var n=e;window._bd_share_main.F.use("trans/trans",function(e){e.run({type:"like",url:document.location.href,callback:function(e){var n={err:e};t&&t(n)}})})}var t=this,n={count:0,clicked:!1};t._init=function(){var e=t.getView();e.render(),e.init(),r(function(t){n.count=t.count,e.setNumber(t.count)})},t._processAction=function(e){e.cmd=="like"&&(n.clicked?t.getView().showDoneState(e.element):i(function(r){n.clicked=!0,r.err==0?(n.count++,t.getView().addOne(e.element,n.count)):t.getView().showDoneState(e.element)}))}},s.ApiBase)});
    \ No newline at end of file
    diff --git a/source/static/api/js/share/likeshare.js b/source/static/api/js/share/likeshare.js
    deleted file mode 100644
    index 1c8a0e79..00000000
    --- a/source/static/api/js/share/likeshare.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -;
    \ No newline at end of file
    diff --git a/source/static/api/js/share/select_api.js b/source/static/api/js/share/select_api.js
    deleted file mode 100644
    index 52c651ad..00000000
    --- a/source/static/api/js/share/select_api.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("share/select_api",function(e,t,n){var r=e("base/tangram").T,i=e("base/class").Class,s=e("component/comm_tools"),o=e("share/api_base");t.Api=i.create(function(e){var t=this;t._init=function(){var e=t.getView();e.render(),e.init()},t._processAction=function(e){return{data:{type:"select"}}},t._distory=function(){}},o.ApiBase)});
    \ No newline at end of file
    diff --git a/source/static/api/js/share/share_api.js b/source/static/api/js/share/share_api.js
    deleted file mode 100644
    index 44f48fb2..00000000
    --- a/source/static/api/js/share/share_api.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("share/share_api",function(e,t,n){var r=e("base/tangram").T,i=e("base/class").Class,s=e("component/comm_tools"),o=e("share/api_base");t.Api=i.create(function(e){function r(t){window._bd_share_main.F.use("trans/data",function(n){n.get({type:"share_count",url:e.bdUrl||s.getPageUrl(),callback:function(e,n){var r={count:e,display:n};t&&t(r)}})})}var t=this,n={count:0,clicked:!1};t._init=function(){var e=t.getView();e.render(),e.on("getsharecount",function(){r(function(t){n.count=t.count,e.setNumber(t.count,t.display)})}),e.init()},t._processAction=function(e){return{data:{type:"share"}}}},o.ApiBase)});
    \ No newline at end of file
    diff --git a/source/static/api/js/share/slide_api.js b/source/static/api/js/share/slide_api.js
    deleted file mode 100644
    index 53a895e3..00000000
    --- a/source/static/api/js/share/slide_api.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("share/slide_api",function(e,t,n){var r=e("base/tangram").T,i=e("base/class").Class,s=e("share/api_base");t.Api=i.create(function(e){var t=this;t._init=function(){var e=t.getView();e.render(),e.init()},t._slidePop=function(t,n){t._popupBox=n.boxEle,t._getPosition=function(){return{top:0,left:e.bdPos=="left"?0:n.element.width()}},t.show(n,e)},t._processAction=function(e){return{data:{type:"share"}}},t._distory=function(){}},s.ApiBase)});
    \ No newline at end of file
    diff --git a/source/static/api/js/start/router.js b/source/static/api/js/start/router.js
    deleted file mode 100644
    index e8b817f3..00000000
    --- a/source/static/api/js/start/router.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -!window._bd_share_is_recently_loaded&&window._bd_share_main.F.use("base/min_tangram",function(e){function n(e,t,n){var r=new e(n);r.setView(new t(n)),r.init(),n&&n._handleId&&(_bd_share_main.api=_bd_share_main.api||{},_bd_share_main.api[n._handleId]=r)}function r(e,r){window._bd_share_main.F.use(e,function(e,i){t.isArray(r)?t.each(r,function(t,r){n(e.Api,i.View,r)}):n(e.Api,i.View,r)})}function i(e){var n=e.common||window._bd_share_config&&_bd_share_config.common||{},r={like:{type:"like"},share:{type:"share",bdStyle:0,bdMini:2,bdSign:"on"},slide:{type:"slide",bdStyle:"1",bdMini:2,bdImg:0,bdPos:"right",bdTop:100,bdSign:"on"},image:{viewType:"list",viewStyle:"0",viewPos:"top",viewColor:"black",viewSize:"16",viewList:["qzone","tsina","huaban","tqq","renren"]},selectShare:{type:"select",bdStyle:0,bdMini:2,bdSign:"on"}},i={share:{__cmd:"",__buttonType:"",__type:"",__element:null},slide:{__cmd:"",__buttonType:"",__type:"",__element:null},image:{__cmd:"",__buttonType:"",__type:"",__element:null}};return t.each(["like","share","slide","image","selectShare"],function(s,o){e[o]&&(t.isArray(e[o])&&e[o].length>0?t.each(e[o],function(s,u){e[o][s]=t.extend({},r[o],n,u,i[o])}):e[o]=t.extend({},r[o],n,e[o],i[o]))}),e}var t=e.T;_bd_share_main.init=function(e){e=e||window._bd_share_config||{share:{}};if(e){var t=i(e);t.like&&r(["share/like_api","view/like_view"],t.like),t.share&&r(["share/share_api","view/share_view"],t.share),t.slide&&r(["share/slide_api","view/slide_view"],t.slide),t.selectShare&&r(["share/select_api","view/select_view"],t.selectShare),t.image&&r(["share/image_api","view/image_view"],t.image)}},window._bd_share_main._LogPoolV2=[],window._bd_share_main.n1=(new Date).getTime(),t.domready(function(){window._bd_share_main.n2=(new Date).getTime()+1e3,_bd_share_main.init(),setTimeout(function(){window._bd_share_main.F.use("trans/logger",function(e){e.nsClick(),e.back(),e.duration()})},3e3)})});
    \ No newline at end of file
    diff --git a/source/static/api/js/trans/data.js b/source/static/api/js/trans/data.js
    deleted file mode 100644
    index e69de29b..00000000
    diff --git a/source/static/api/js/trans/logger.js b/source/static/api/js/trans/logger.js
    deleted file mode 100644
    index e69de29b..00000000
    diff --git a/source/static/api/js/trans/trans.js b/source/static/api/js/trans/trans.js
    deleted file mode 100644
    index 1e6e2d24..00000000
    --- a/source/static/api/js/trans/trans.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -!window._bd_share_is_recently_loaded&&window._bd_share_main.F.module("trans/trans",function(e,t){var n=e("component/comm_tools"),r=e("conf/const").URLS,i=function(){window._bd_share_main.F.use("base/tangram",function(e){var t=e.T;t.cookie.get("bdshare_firstime")==null&&t.cookie.set("bdshare_firstime",new Date*1,{path:"/",expires:(new Date).setFullYear(2022)-new Date})})},s=function(e){var t=e.bdUrl||n.getPageUrl();return t=t.replace(/\'/g,"%27").replace(/\"/g,"%22"),t},o=function(e){var t=(new Date).getTime()+3e3,r={click:1,url:s(e),uid:e.bdUid||"0",to:e.__cmd,type:"text",pic:e.bdPic||"",title:(e.bdText||document.title).substr(0,300),key:(e.bdSnsKey||{})[e.__cmd]||"",desc:e.bdDesc||"",comment:e.bdComment||"",relateUid:e.bdWbuid||"",searchPic:e.bdSearchPic||0,sign:e.bdSign||"on",l:window._bd_share_main.n1.toString(32)+window._bd_share_main.n2.toString(32)+t.toString(32),linkid:n.getLinkId(),firstime:a("bdshare_firstime")||""};switch(e.__cmd){case"copy":l(r);break;case"print":c();break;case"bdxc":h();break;case"bdysc":p(r);break;case"weixin":d(r);break;default:u(e,r)}window._bd_share_main.F.use("trans/logger",function(t){t.commit(e,r)})},u=function(e,t){var n=r.jumpUrl;e.__cmd=="mshare"?n=r.mshareUrl:e.__cmd=="mail"&&(n=r.emailUrl);var i=n+"?"+f(t);window.open(i)},a=function(e){if(e){var t=new RegExp("(^| )"+e+"=([^;]*)(;|$)"),n=t.exec(document.cookie);if(n)return decodeURIComponent(n[2]||null)}},f=function(e){var t=[];for(var n in e)t.push(encodeURIComponent(n)+"="+encodeURIComponent(e[n]));return t.join("&").replace(/%20/g,"+")},l=function(e){window._bd_share_main.F.use("base/tangram",function(t){var r=t.T;r.browser.ie?(window.clipboardData.setData("text",document.title+" "+(e.bdUrl||n.getPageUrl())),alert("\u6807\u9898\u548c\u94fe\u63a5\u590d\u5236\u6210\u529f\uff0c\u60a8\u53ef\u4ee5\u63a8\u8350\u7ed9QQ/MSN\u4e0a\u7684\u597d\u53cb\u4e86\uff01")):window.prompt("\u60a8\u4f7f\u7528\u7684\u662f\u975eIE\u6838\u5fc3\u6d4f\u89c8\u5668\uff0c\u8bf7\u6309\u4e0b Ctrl+C \u590d\u5236\u4ee3\u7801\u5230\u526a\u8d34\u677f",document.title+" "+(e.bdUrl||n.getPageUrl()))})},c=function(){window.print()},h=function(){window._bd_share_main.F.use("trans/trans_bdxc",function(e){e&&e.run()})},p=function(e){window._bd_share_main.F.use("trans/trans_bdysc",function(t){t&&t.run(e)})},d=function(e){window._bd_share_main.F.use("trans/trans_weixin",function(t){t&&t.run(e)})},v=function(e){o(e)};t.run=v,i()});
    \ No newline at end of file
    diff --git a/source/static/api/js/trans/trans_bdxc.js b/source/static/api/js/trans/trans_bdxc.js
    deleted file mode 100644
    index 86ad53d6..00000000
    --- a/source/static/api/js/trans/trans_bdxc.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("trans/trans_bdxc",function(e,t){var n=function(){var e=window,t=document,n="_bdXC",r;e[n]?window._bdXC_loaded&&e[n].reInit():(r=t.createElement("script"),r.setAttribute("charset","utf-8"),r.src="http://xiangce.baidu.com/zt/collect/mark.js?"+(new Date).getTime(),t.getElementsByTagName("head")[0].appendChild(r))};t.run=n});
    \ No newline at end of file
    diff --git a/source/static/api/js/trans/trans_bdysc.js b/source/static/api/js/trans/trans_bdysc.js
    deleted file mode 100644
    index affc6c74..00000000
    --- a/source/static/api/js/trans/trans_bdysc.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("trans/trans_bdysc",function(e,t){var n=function(e){var t={url:e.url,title:e.title};if(window.baiduSC_yaq4d3elabjnvmijccc1zuo3o4yeizck)window.baiduSC_yaq4d3elabjnvmijccc1zuo3o4yeizck.go(t);else{window.baiduSC_yaq4d3elabjnvmijccc1zuo3o4yeizck={callback:function(){this.go(t)}};var n=document.createElement("script"),r="http://s.wenzhang.baidu.com/js/pjt/content_ex/page/";r+="bookmark.js?s=baidu_fenxiang&_t="+Math.random(),n.src=r,document.getElementsByTagName("body")[0].appendChild(n)}};t.run=n});
    \ No newline at end of file
    diff --git a/source/static/api/js/trans/trans_weixin.js b/source/static/api/js/trans/trans_weixin.js
    deleted file mode 100644
    index 75029393..00000000
    --- a/source/static/api/js/trans/trans_weixin.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("trans/trans_weixin",function(n,i){var e,o,t,d="bdshare_weixin_qrcode_dialog",a="",r=0,c={},p=n("base/tangram").T,u=(n("conf/const").URLS,function(n){var i=Math.round(200/n.length);i=2>i?2:i,r=i*n.length;var e='<table style="direction:ltr;border: 0; width:'+r+'px; border-collapse: collapse;background-color:#fff;margin:0 auto;" align="center">',o=[e],t="";return p.each(n,function(n,e){o.push("<tr>"),p.each(e,function(n,e){t='<td style="width:'+i+"px;height:"+i+"px;padding:0;margin:0;border:none;background:#"+(e?"000":"FFF")+'"></td>',o.push(t)})}),o.push("</table>"),o.join("")}),s=function(n,i){window._bd_share_main.F.use("component/qrcode",function(i){var o=i.QRCode,d=i.QRErrorCorrectLevel,a=new o(-1,d.L);a.addData(n),a.make();var c=u(a.modules);p(c).appendTo(t.empty());_(r),w(),e.attr("data-url",n)})},f=function(){e.attr("data-url")!=a&&(t.html("正在加载"),s(a.length>200?a:a))},_=function(n){var i=(n>220?n:220)+20,o=p(".bd_weixin_popup_foot").height()+p(".bd_weixin_popup_head").height()+n+30;e.css({width:i,height:o})},h=function(){if(e=p("#"+d),o=p("#"+d+"_bg"),e.length<1){var n='<iframe id="'+d+'_bg" class="bd_weixin_popup_bg"></iframe>',i=['<div id="'+d+'" class="bd_weixin_popup">','<div class="bd_weixin_popup_head">',"<span>分享到微信朋友圈</span>",'<a href="#" onclick="return false;" class="bd_weixin_popup_close">&times;</a>',"</div>",'<div id="'+d+'_qr" class="bd_weixin_popup_main"></div>','<div class="bd_weixin_popup_foot">打开微信,点击底部的“发现”,<br>使用“扫一扫”即可将网页分享至朋友圈。</div>',"</div>"].join("");o=p(n).appendTo("body"),e=p(i).appendTo("body"),l()}t=e.find("#"+d+"_qr"),b()},l=function(){e.find(".bd_weixin_popup_close").click(g),p("body").on("keydown",function(n){27==n.keyCode&&g()}),p(window).resize(function(){w()})},w=function(){var n=p(window).scrollTop(),i=e.outerWidth(),t=e.outerHeight(),d=p(window).width(),a=p(window).height(),r=(a-t)/2+n,c=(d-i)/2;r=0>r?0:r,c=0>c?0:c,o.width(i).height(t).css({left:c,top:r}),e.css({left:c,top:r})},b=function(){e.show(),o.show(),w()},g=function(){e.hide(),o.hide()},v=function(n){var i="10006-weixin-1-52626-6b3bffd01fdde4900130bc5a2751b6d1";if("off"===c.sign)return n;if("normal"===c.sign){var e=n.indexOf("#"),o=n.indexOf("?");return-1==e?n+(-1==o?"?":"&")+i:n.replace("#",(-1==o?"?":"&")+i+"#")}return n.replace(/#.*$/g,"")+"#"+i},x=function(n){n=v(n);var i=[];return p.each(n,function(n,e){/[^\x00-\xff]/.test(e)?i[n]=encodeURI(e):i[n]=e}),n=i.join("")},m=function(){window._bd_share_main.F.use("component/pop_dialog",function(n){n.Dialog.hide()})},y=function(n){c=n,a=x(n.url),window._bd_share_main.F.use("weixin_popup.css",function(){m(),h(),f()})};i.run=y});
    \ No newline at end of file
    diff --git a/source/static/api/js/view/image_view.js b/source/static/api/js/view/image_view.js
    deleted file mode 100644
    index b4e6da9c..00000000
    --- a/source/static/api/js/view/image_view.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("view/image_view",function(e,t,n){var r=e("base/tangram").T,i=e("base/class").Class,s=e("conf/const"),o=e("view/view_base");t.View=i.create(function(e){function l(){var t=e.tag||"";r("img").each(function(e,n){if(!t||r(n).attr(s.CONFIG_TAG_ATTR)==t){if(r(n).attr("data-bd-imgshare-binded")==1)return;r(n).on("mouseenter",c).on("mouseleave",h),r(n).attr("data-bd-imgshare-binded",1)}})}function c(e){var t=e.target;p(t)&&(f.element=t,f.start())}function h(){f.abort()}function p(t){var n=!0;if(e.bdMinHeight&&e.bdMinHeight>t.offsetHeight)n=!1;else if(e.bdMinWidth&&e.bdMinWidth>t.offsetWidth)n=!1;else if(t.offsetWidth<100||t.offsetHeight<100)n=!1;return n}function d(e){e&&w(function(){g(e),i.show(),o=!1,u=e})}function v(){o||i.hide()}function m(){return i.find(".bdimgshare-icon")}function g(t){if(e.viewType=="list"){var n={16:{lbl:53,pright:8,item:18},24:{lbl:57,pright:8,item:28},32:{lbl:61,pright:8,item:38}},s=n[e.viewSize],o=Math.floor((t.offsetWidth-s.lbl-s.pright-10)/s.item),u=m();for(var a=0,f=u.length-1;a<f;a++)a<o-1?r(u[a]).show():r(u[a]).hide()}var l={width:i.offsetWidth,height:i.offsetHeight},c={width:t.offsetWidth,height:t.offsetHeight},h=y(r(t).offset(),c,l),p={position:"absolute",top:h.top+"px",left:h.left+"px"};e.viewType=="list"&&(p.width=c.width+"px"),i.css(p)}function y(t,n,r){return e.viewType=="list"?{top:t.top+(e.viewPos=="bottom"?n.height-r.height:0),left:t.left}:e.viewType=="collection"?{top:t.top+(e.viewPos.toLowerCase().indexOf("bottom")>-1?n.height-r.height-5:5),left:t.left+(e.viewPos.toLowerCase().indexOf("left")>-1?5:n.width-r.width-5)}:{top:t.top+(e.viewPos=="bottom"?n.height-r.height:0),left:t.left+(n.width-r.width)}}function b(){var s=["<div id='#{id}' class='sr-bdimgshare sr-bdimgshare-#{type} sr-bdimgshare-#{size} sr-bdimgshare-#{color}' style='height:#{height}px;line-height:#{lineHeight}px;font-size:#{fontSize}px;width:#{width}px;display:none;'>","<div class='bdimgshare-bg'></div>","<div class='bdimgshare-content bdsharebuttonbox bdshare-button-style#{style}-#{size}'>","<label class='bdimgshare-lbl'>#{text}</label>","#{list}","</div>","</div>"].join(""),o="<a href='#' onclick='return false;' class='bds_#{icon}' data-cmd='#{icon}' hidefocus></a>",u=e.viewType=="list",a=[];u&&r.each(e.viewList,function(e,t){a.push(r.string(o).format({icon:t}))}),a.push(r.string(o).format({icon:"more"}));var l={16:"36",24:"42",32:"48"},c={16:"33",24:"39",32:"45"},h={16:"60",24:"71",32:"82"},p={16:"12",24:"14",32:"14"},d=r.string(s).format({id:n,text:e.viewText||(u?"\u56fe\u7247\u5206\u4eab":"\u5206\u4eab"),type:e.viewType,style:e.viewStyle,size:e.viewSize,color:e.viewColor,width:u?"auto":h[e.viewSize],height:(u?l:c)[e.viewSize],lineHeight:(u?l:c)[e.viewSize]-10,fontSize:p[e.viewSize],list:a.join("")});r("body").insertHTML("beforeEnd",d),t._entities=i=r("#"+n),i.on("mouseleave",function(){f.abort()}).on("mouseenter",function(){f.clearAbort()})}function w(t){if(e.bdCustomStyle){var n=document.createElement("link");n.href=e.bdCustomStyle,n.rel="styleSheet",n.type="text/css",n.onLoad=function(){t&&t()},document.getElementsByTagName("head")[0].appendChild(n)}else window._bd_share_main.F.use(["imgshare.css","share_style0_"+e.viewSize+".css"],function(){t&&t()})}var t=this,n="bdimgshare_"+(new Date).getTime(),i=null,o=!1,u=null,a=function(e){function i(){r&&(r=clearTimeout(r)),n||(n=setTimeout(function(){e.startFn&&e.startFn(),n=!1},e.time))}function s(){n&&(n=clearTimeout(n)),r||(r=setTimeout(function(){e.abortFn&&e.abortFn(),r=!1},e.time))}var t=this,n=!1,r=!1;t.clearAbort=function(){r&&(r=clearTimeout(r))},t.start=i,t.abort=s},f=new a({time:200,startFn:function(){d(f.element)},abortFn:function(){v()}});t.render=function(e){l(),b()},t._init=function(){},t._keepBarVisible=function(){f.clearAbort(),o=!0},t._getImageSrc=function(){return u.src},t._distory=function(){i.remove();var t=e.tag||"";r("img").each(function(e,n){if(!t||r(n).attr(s.CONFIG_TAG_ATTR)==t)r(n).off("mouseenter",c).off("mouseleave",h),r(n).removeAttr("data-bd-imgshare-binded")})}},o.ViewBase)});
    \ No newline at end of file
    diff --git a/source/static/api/js/view/like_view.js b/source/static/api/js/view/like_view.js
    deleted file mode 100644
    index 32770aff..00000000
    --- a/source/static/api/js/view/like_view.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("view/like_view",function(e,t,n){e("like.css");var r=e("base/tangram").T,i=e("base/class").Class,s=e("conf/const"),o=e("view/view_base"),u=e("component/animate"),a={btn:"bdlikebutton",innerBtn:"bdlikebutton-inner",add:"bdlikebutton-add",text:"bdlikebutton-text",count:"bdlikebutton-count"};t.View=i.create(function(e){function i(){var n=e.tag||"";return r("."+a.btn).each(function(e,i){(!n||r(i).attr(s.CONFIG_TAG_ATTR)==n)&&t._entities.push(i)}),t._entities}function o(){var t=e,r=n[t.type];return t.likeText=t.likeText?t.likeText.substr(0,r[0]):r[1],t.likedText=t.likedText?t.likedText.substr(0,r[0]):r[2],t}function f(e){return r(e).parent().get(0)}var t=this,n={small:[4,"\u9876","\u5df2\u9876\u8fc7"],medium:[6,"\u9876","\u60a8\u5df2\u9876\u8fc7"],large:[10,"\u8be5\u5185\u5bb9\u5bf9\u6211\u6709\u5e2e\u52a9","\u60a8\u5df2\u9876\u8fc7\uff0c\u8c22\u8c22\uff01"]};t.render=function(e){var n=i(),s=a.btn,u=o();t._actBtnSet.className=a.innerBtn,t._actBtnSet.tagName="div",t._actBtnSet.maxDomDepth=1,r(n).each(function(e,n){var i=u.type,o=[];o.push('<div class="',a.innerBtn,'" ',t._actBtnSet.cmdAttr,'="like">'),o.push('<span class="',a.add,'">+1</span>'),o.push('<div class="',a.count,'">\u52a0\u8f7d\u4e2d</div>'),"small"!=i&&o.push('<div class="',a.text,'">',u.likeText,"</div>"),o.push("</div>"),r(n).html(o.join("")).addClass(s+"-"+u.color).addClass(s+"-"+u.type).addClass(s+"-"+u.type+"-"+u.color)})},t._init=function(){var n=e,i=n.type;r(t._entities).each(function(e,t){var s=r("."+a.innerBtn,t);s.mouseover(function(e){e=r.event(e||window.event);var o=e.relatedTarget;s.contains(o)||("small"==i&&r("."+a.count,t).html(n.likeText),r(t).addClass(a.btn+"-"+n.type+"-"+n.color+"-hover"))}).mouseout(function(e){e=r.event(e||window.event);var o=e.relatedTarget;s.contains(o)||("small"==i?r("."+a.count,t).html(n.count):r("."+a.text,t).html(n.likeText),r(t).removeClass(a.btn+"-"+n.type+"-"+n.color+"-hover"))})})},t.showDoneState=function(t){var n=e,i=f(t),s=a.text;"small"==n.type&&(s=a.count),r("."+s,i).html(n.likedText),r(i).removeClass(i,a.btn+"-"+n.type+"-"+n.color+"-hover")},t.addOne=function(n,i){var s=e,o=f(n),l=r("."+a.add,o);l.show(),u.animate(l.get(0),{top:"-25px",opacity:"0"},300,function(){l.hide(),l.css({top:"0px",opacity:99})}),t.setNumber(i),r(o).removeClass(a.btn+"-"+s.type+"-"+s.color+"-hover")},t.setNumber=function(e){r.type(e)=="number"&&r(t._entities).each(function(t,n){r("."+a.count,n).html(e)})}},o.ViewBase)});
    \ No newline at end of file
    diff --git a/source/static/api/js/view/select_view.js b/source/static/api/js/view/select_view.js
    deleted file mode 100644
    index bc394ed0..00000000
    --- a/source/static/api/js/view/select_view.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("view/select_view",function(e,t,n){var r=e("base/tangram").T,i=e("base/class").Class,s=e("conf/const"),o=e("view/view_base"),u,a,f,l,c=function(e){var t="";return document.selection?t=document.selection.createRange().text:t=document.getSelection(),r.string(t.toString()).trim()},h="getSelection"in document?function(){document.getSelection().removeAllRanges(),l=""}:function(){document.selection.empty(),l=""};t.View=i.create(function(e){function o(){if(e.bdCustomStyle){var t=document.createElement("link");t.href=e.bdCustomStyle,t.rel="styleSheet",t.type="text/css",document.getElementsByTagName("head")[0].appendChild(t)}else window._bd_share_main.F.use("share_style"+n+"_"+i+".css")}function p(e,n){var i=n.bdMini||2,s=n.bdSelectMiniList||t._partnerSort.slice(0,4),o=[];r.each(s,function(e,t){o[e]='<a href="#" class="bds_'+t+'" data-cmd="'+t+'"></a>'}),f.find(".bdselect_share_partners").html(o.join(""))}function d(e,t){var n=e.pageY,i=e.pageX;n+=5,i-=18;var s=u.outerHeight(),o=r(window).scrollTop();if(n+s>r("body").height()&&n+s>r(window).height()||n+s>o+r(window).height())n=e.pageY-s-5,n=n<o?o:n;var a=t.bdPopupOffsetLeft,f=t.bdPopupOffsetTop;if(a||f)n+=f|0,i+=a|0;return{top:n,left:i}}function g(e,n){var i=d(e,n);if(l.length<5){t.hide("less");return}r.each([u,a],function(e,t){t.css({top:i.top,left:i.left}).show(),n.bdText=c()});var s=f.find("a").length,o=r(f.find("a")).outerWidth(!0),h=o*s+20,p=parseInt(u.css("max-width"));p&&h>p&&(h=p),u.width(h),u.find(".bdselect_share_head").width(h),a.width(h),a.height(u.height());var g=u.find(".bdselect_share_dialog_search");g.attr("href","http://www.baidu.com/s?wd="+n.bdText+"&tn=SE_hldp08010_vurs2xrp");var y=m(function(){v("http://s.share.baidu.com/select?"+r.ajax.param({log_type:"click",content:encodeURIComponent(n.bdText)}))},100);g.click(y),h<220?u.find(".bdselect_share_dialog_search_span").hide():u.find(".bdselect_share_dialog_search_span").show(),v("http://s.share.baidu.com/select?"+r.ajax.param({log_type:"show",content:encodeURIComponent(n.bdText)}))}var t=this;t._container=null;var n=e.bdStyle||0,i="|16|24|32|".indexOf("|"+e.bdSize+"|")>-1?e.bdSize:16,s=!1;t._buttonType=0,t.render=function(){var s="bdSharePopup_selectshare"+ +(new Date),o=['<iframe frameborder="0" id="'+s+'bg" class="bdselect_share_bg" style="display:none;"></iframe>'].join(""),l=['<div id="'+s+'box" style="display:none;" share-type="selectshare" class="bdselect_share_box">','<div class="selectshare-mod-triangle"><div class="triangle-border"></div><div class="triangle-inset"></div></div>','<div  class="bdselect_share_head" ><span>\u5206\u4eab\u5230</span>','<a href="http://www.baidu.com/s?wd='+e.bdText+'&tn=SE_hldp08010_vurs2xrp"',' class="bdselect_share_dialog_search" target="_blank">','<i class="bdselect_share_dialog_search_i"></i>','<span class="bdselect_share_dialog_search_span">\u767e\u5ea6\u4e00\u4e0b</span></a>','<a class="bdselect_share_dialog_close"></a></div>','<div class="bdselect_share_content" >','<ul class="bdselect_share_list">','<div class="bdselect_share_partners"></div>','<a href="#" class="bds_more"  data-cmd="more"></a>',"</ul>","</div>","</div>"].join("");r("body").insertHTML("beforeEnd",o+l),t._container=u=r("#"+s+"box"),f=u.find(".bdselect_share_list").addClass("bdshare-button-style"+n+"-"+i),a=r("#"+s+"bg"),t._entities.push(u),r(".bdselect_share_dialog_close").click(t.hide)},t.hide=function(e){e||h(),a&&a.hide(),u&&u.hide()},t._init=function(){var n;e.bdContainerClass?n=r("."+e.bdContainerClass):n=r("body").children(),r("body").on("mouseup",function(i){n.each(function(n,s){s==i.target||r(s).contains(i.target)||!e.bdContainerClass&&i.target==document.body?setTimeout(function(){l=c(),o(),t.show(i,e)},10):u.css("display")=="block"&&t.hide()})})},t.show=function(e,n){window._bd_share_main.F.use(["component/partners","share_popup.css","select_share.css"],function(r){t._partnerSort=r.partnerSort,s||(p(t._container,n),s=!0),g(e,n)})};var v=function(){var e={};return function(t){var n="bdsharelog__"+(new Date).getTime(),r=e[n]=new Image;r.onload=r.onerror=function(){e[n]=null},r.src=t+"&t="+(new Date).getTime(),r=null}}(),m=function(e,t,n){var r,i,s,o=null,u=0;n||(n={});var a=function(){u=n.leading===!1?0:new Date,o=null,s=e.apply(r,i),o||(r=i=null)};return function(){var f=new Date;!u&&n.leading===!1&&(u=f);var l=t-(f-u);return r=this,i=arguments,l<=0||l>t?(clearTimeout(o),o=null,u=f,s=e.apply(r,i),o||(r=i=null)):!o&&n.trailing!==!1&&(o=setTimeout(a,l)),s}};t._distory=function(){u.remove(),a.remove()}},o.ViewBase)});
    \ No newline at end of file
    diff --git a/source/static/api/js/view/share_view.js b/source/static/api/js/view/share_view.js
    deleted file mode 100644
    index cd14c371..00000000
    --- a/source/static/api/js/view/share_view.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("view/share_view",function(e,t,n){var r=e("base/tangram").T,i=e("base/class").Class,s=e("conf/const"),o=e("view/view_base"),u={btn:"bdsharebuttonbox",count:"bds_count"};t.View=i.create(function(e){function o(){var o=e.tag||"";return r("."+u.btn).each(function(e,u){if(!o||r(u).attr(s.CONFIG_TAG_ATTR)==o)t._entities.push(u),r(u).removeClass(function(e,t){var n=t.match(/bdshare-button-style\d*-\d*/g);if(n)return n.join(" ")}),r(u).addClass("bdshare-button-style"+n+"-"+i)}),t._entities}function a(){if(e.bdCustomStyle){var t=document.createElement("link");t.href=e.bdCustomStyle,t.rel="styleSheet",t.type="text/css",document.getElementsByTagName("head")[0].appendChild(t)}else window._bd_share_main.F.use("share_style"+n+"_"+i+".css")}function f(){r("."+u.btn).each(function(e,t){r(t).children("a,span").each(function(e,t){var n=r(t).attr(s.CMD_ATTR);n&&window._bd_share_main.F.use("component/partners",function(e){var i=e.partners,s=i[n]?"\u5206\u4eab\u5230"+i[n].name:"";!r(t).attr("title")&&s&&r(t).attr("title",s)})})})}var t=this,n=e.bdStyle||0,i="|16|24|32|".indexOf("|"+e.bdSize+"|")>-1?e.bdSize:16;t._buttonType=0,t.render=function(e){o(),f()},t._init=function(){a(),r(t._entities).find("."+u.count).length>0&&t.fire("getsharecount")},t.setNumber=function(e,n){r(t._entities).find("."+u.count).html(n).attr("title","\u7d2f\u8ba1\u5206\u4eab"+e+"\u6b21")}},o.ViewBase)});
    \ No newline at end of file
    diff --git a/source/static/api/js/view/slide_view.js b/source/static/api/js/view/slide_view.js
    deleted file mode 100644
    index 0626fa34..00000000
    --- a/source/static/api/js/view/slide_view.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("view/slide_view",function(e,t,n){var r=e("base/tangram").T,i=e("base/class").Class,s=e("conf/const"),o=e("view/view_base"),u={box:"bdshare-slide-button-box",btn:"bdshare-slide-button"};t.View=i.create(function(e){function p(){window._bd_share_main.F.use("slide_share.css",function(){var t=i.width()||24;i.css(e.bdPos=="right"?"left":"right",-t),n&&n.css({top:e.bdTop|0,width:0,"z-index":99999}).css(e.bdPos,0).show(),o.width(0).hide(),a.width(h),f.width(h)})}function d(){if(l)return;a.html()||window._bd_share_main.F.use("component/partners",function(e){partnerSort=e.partnerSort,partners=e.partners,m(partnerSort,partners)});var e={};window._bd_share_main.F.use("component/animate",function(e){o.show(),e.animate(n[0],{width:h},300,function(){l=!0},function(e){o.width(e*h)})})}function v(){if(!l)return;var e={};window._bd_share_main.F.use("component/animate",function(e){e.animate(n[0],{width:0},300,function(){l=!1,o.hide()},function(e){o.width((1-e)*h)})})}function m(t,n){var i=e.bdMiniList||t.slice(0,8*c),s=[];r.each(i,function(e,t){if(!/(iPhone | iPad | Android)/i.test(navigator.userAgent)||t!=="weixin")s[e]='<li><a href="#" onclick="return false;" class="slide-'+t+'" data-cmd="'+t+'">'+n[t].name+"</a></li>"}),a.html(s.join(""))}var t=this,n,i,s,o,a,f,l=!1;t._buttonType=1;var c=e.bdMini||2,h=c*110+6,e=r.extend({},e);t.render=function(){var l=u.btn,c=u.box+" bdshare-slide-style-"+(e.bdPos=="right"?"r":"l")+e.bdImg,h=['<div class="'+c+'" style="display:none;">','<a href="#" onclick="return false;" class="'+l+'"></a>','<div class="bdshare-slide-list-box">','<div class="bdshare-slide-top">\u5206\u4eab\u5230</div>','<div class="bdshare-slide-list">','<ul class="bdshare-slide-list-ul"></ul>',"</div>",'<div class="bdshare-slide-bottom">','<a href="#" onclick="return false;" class="slide-more"  data-cmd="more">\u66f4\u591a...</a>',"</div>","</div>","</div>"].join("");n=r(h).appendTo("body"),i=n.find("."+u.btn),o=n.find(".bdshare-slide-list-box"),a=n.find(".bdshare-slide-list-ul"),s=n.find(".bdshare-slide-list"),f=n.find(".bdshare-slide-bottom"),p(),t._entities.push(n);if(r.browser.ie==6){n.css("position","absolute");var d=parseInt(n.css("top"));setInterval(function(){var t=(e.bdTop|0)+r(window).scrollTop();d!=t&&window._bd_share_main.F.use("component/animate",function(e){e.animate(n[0],{top:t},300)})},1e3)}},t._init=function(){var e=!1;i.on("mouseenter click",d),n.on("mouseleave click",v),r("body").click(function(e){n.contains(e.target)||v()})},t._distory=function(){n.remove()}},o.ViewBase)});
    \ No newline at end of file
    diff --git a/source/static/api/js/view/view_base.js b/source/static/api/js/view/view_base.js
    deleted file mode 100644
    index 078e2181..00000000
    --- a/source/static/api/js/view/view_base.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -window._bd_share_main.F.module("view/view_base",function(e,t,n){var r=e("base/tangram").T,i=e("conf/const"),s=e("base/class").Class;t.ViewBase=s.create(function(e){function s(e){r(e).click(function(i){if(r(e).attr("data-bd-bind")==n){var s=o(i.target);s&&(i.preventDefault(),t.fire("clickact",{cmd:r(s).attr(t._actBtnSet.cmdAttr),element:s,event:i,buttonType:t._poptype}))}}).mouseenter(function(i){if(r(e).attr("data-bd-bind")==n){var s=o(i.target);t.fire("mouseenter",{element:s,event:i})}}).mousemove(function(i){if(r(e).attr("data-bd-bind")==n){var s=o(i.target);r(s).hasClass("bds_more")&&t.fire("moreover",{element:s})}}),r(e).attr("data-bd-bind",n)}function o(e){if(u(e))return e;if(t._actBtnSet.maxDomDepth>0){var n=t._actBtnSet.maxDomDepth,i=0,s=r(e).parent().get(0),o=t.entities;while(i<n){if(u(s))return s;s=r(s).parent().get(0);if(r.array(o).contains(s)||s==document.body)break;i++}}return null}function u(e){var n=t._actBtnSet;return e&&e.tagName&&(n.className||n.tagName)?(!n.className||r(e).hasClass(n.className))&&(!n.tagName||n.tagName.toLowerCase().indexOf("|"+e.tagName.toLowerCase()+"|")>-1)&&r(e).attr(n.cmdAttr):!1}var t=this,n=+(new Date);t._entities=[],t._buttonType=-1,t._actBtnSet={className:"",tagName:"|a|img|span",maxDomDepth:0,cmdAttr:i.CMD_ATTR},t.render=function(e){},t.init=function(){r(t._entities).each(function(e,t){s(t)}),t._init(),t._entities.length>0&&(_bd_share_main._LogPoolV2==_bd_share_main._LogPoolV2||[],_bd_share_main._LogPoolV2.push(e.type))},t._init=function(){},t.distory=function(){r(t._entities).removeAttr("data-bd-bind"),t._distory()},t._distory=function(){}})});
    \ No newline at end of file
    diff --git a/source/tags/index.md b/source/tags/index.md
    deleted file mode 100644
    index 5447e196..00000000
    --- a/source/tags/index.md
    +++ /dev/null
    @@ -1,8 +0,0 @@
    ----
    -title: 标签
    -comments: false
    -share: false
    -top_img: false
    -type: "tags"
    -date: 2019-04-30 11:36:17
    ----
    diff --git a/source/tencent18139824940595684397.txt b/source/tencent18139824940595684397.txt
    deleted file mode 100644
    index f18c6d2c..00000000
    --- a/source/tencent18139824940595684397.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -9341423762777602494
    diff --git a/themes/anzhiyu b/themes/anzhiyu
    deleted file mode 160000
    index 661b90b2..00000000
    --- a/themes/anzhiyu
    +++ /dev/null
    @@ -1 +0,0 @@
    -Subproject commit 661b90b288d4c5389883244a0053777f17dee446
    diff --git a/themes/butterfly/.github/ISSUE_TEMPLATE/bug_report.yml b/themes/butterfly/.github/ISSUE_TEMPLATE/bug_report.yml
    deleted file mode 100644
    index 4f260daa..00000000
    --- a/themes/butterfly/.github/ISSUE_TEMPLATE/bug_report.yml
    +++ /dev/null
    @@ -1,73 +0,0 @@
    -name: Bug report
    -description: Create a report to help us improve
    -title: '[Bug]: '
    -
    -body:
    -  - type: markdown
    -    attributes:
    -      value: |
    -        重要:請依照該模板來提交 
    -        Please follow the template to create a new issue
    -  - type: input
    -    id: butterfly-ver
    -    attributes:
    -      label: 使用的 Butterfly 版本? | What version of Butterfly are you use?
    -      description: 檢視主題的 package.json | Check the theme's package.json
    -    validations:
    -      required: true
    -
    -  - type: dropdown
    -    id: modify
    -    attributes:
    -      label: 是否修改过主题文件? || Has the theme files been modified?
    -      options:
    -        - 是 (Yes)
    -        - 不是 (No)
    -    validations:
    -      required: true
    -
    -  - type: dropdown
    -    id: browser
    -    attributes:
    -      label: 使用的瀏覽器? || What browse are you using?
    -      options:
    -        - Chrome
    -        - Edge
    -        - Safari
    -        - Opera
    -        - Other
    -    validations:
    -      required: true
    -
    -  - type: dropdown
    -    id: platform
    -    attributes:
    -      label: 使用的系統? || What operating system are you using?
    -      options:
    -        - Windows
    -        - macOS 
    -        - Linux
    -        - Android
    -        - iOS
    -        - Other
    -    validations:
    -      required: true
    -
    -  - type: textarea
    -    id: description
    -    attributes:
    -      label: 問題描述 | Describe the bug
    -      description: 請描述你的問題現象 | A clear and concise description of what the bug is.
    -      placeholder: 請儘量提供截圖來定位問題 | If applicable, add screenshots to help explain your problem
    -      value:
    -    validations:
    -      required: true
    -
    -  - type: input
    -    id: website
    -    attributes:
    -      label: 出現問題網站 | Website
    -      description: 請提供下可復現網站地址 | Please supply a website url which can reproduce problem.
    -      placeholder:
    -    validations:
    -      required: true
    diff --git a/themes/butterfly/.github/ISSUE_TEMPLATE/config.yml b/themes/butterfly/.github/ISSUE_TEMPLATE/config.yml
    deleted file mode 100644
    index 9b338d0d..00000000
    --- a/themes/butterfly/.github/ISSUE_TEMPLATE/config.yml
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -blank_issues_enabled: false
    -contact_links:
    -  - name: Questions about Butterfly
    -    url: https://github.com/jerryc127/hexo-theme-butterfly/discussions
    -    about: 一些使用問題請到 Discussion 詢問。 Please ask questions in Discussion.
    -
    -  - name: Butterfly Q&A
    -    url: https://butterfly.js.org/posts/98d20436/
    -    about: Butterfly Q&A
    -
    -  - name: Telegram
    -    url: https://t.me/bu2fly
    -    about: 'Official Telegram Group'
    -
    -  - name: QQ 1群
    -    url: https://jq.qq.com/?_wv=1027&k=KU9105XR
    -    about: '群號 1070540070,不要兩個Q群都添加'
    -
    -  - name: QQ 2群
    -    url: https://jq.qq.com/?_wv=1027&k=r1nK0DQz
    -    about: '群號 978221020,不要兩個Q群都添加'
    -
    diff --git a/themes/butterfly/.github/ISSUE_TEMPLATE/feature_request.yml b/themes/butterfly/.github/ISSUE_TEMPLATE/feature_request.yml
    deleted file mode 100644
    index 3bf7c30b..00000000
    --- a/themes/butterfly/.github/ISSUE_TEMPLATE/feature_request.yml
    +++ /dev/null
    @@ -1,14 +0,0 @@
    -name: Feature request
    -description: Suggest an idea for this project
    -title: '[Feature]: '
    -
    -body:
    -  - type: textarea
    -    id: feature-request
    -    attributes:
    -      label: 想要的功能 | What feature do you want?
    -      description: 請描述你需要的新功能 | A clear and concise description of what the feature is.
    -      placeholder:
    -      value:
    -    validations:
    -      require: true
    \ No newline at end of file
    diff --git a/themes/butterfly/.github/workflows/publish.yml b/themes/butterfly/.github/workflows/publish.yml
    deleted file mode 100644
    index d68365dd..00000000
    --- a/themes/butterfly/.github/workflows/publish.yml
    +++ /dev/null
    @@ -1,19 +0,0 @@
    -name: npm publish
    -
    -on:
    -  release:
    -    types: [created]
    -jobs:
    -  build:
    -    runs-on: ubuntu-latest
    -    steps:
    -    - uses: actions/checkout@v2
    -    # Setup .npmrc file to publish to npm
    -    - uses: actions/setup-node@v1
    -      with:
    -        node-version: '12.x'
    -        registry-url: 'https://registry.npmjs.org'
    -    - run: npm install
    -    - run: npm publish
    -      env:
    -        NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
    \ No newline at end of file
    diff --git a/themes/butterfly/.github/workflows/stale.yml b/themes/butterfly/.github/workflows/stale.yml
    deleted file mode 100644
    index a50d9de1..00000000
    --- a/themes/butterfly/.github/workflows/stale.yml
    +++ /dev/null
    @@ -1,19 +0,0 @@
    -name: 'Close stale issues and PRs'
    -on:
    -  schedule:
    -    - cron: '30 1 * * *'
    -
    -jobs:
    -  stale:
    -    runs-on: ubuntu-latest
    -    steps:
    -      - uses: actions/stale@v5
    -        with:
    -          days-before-issue-stale: 30
    -          days-before-pr-stale: -1
    -          days-before-close: 7
    -          stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
    -          close-pr-message: 'This issue has not seen any activity since it was marked stale. Closing.'
    -          stale-issue-label: 'Stale'
    -          exempt-issue-labels: 'pinned,bug,enhancement,documentation,Plan'
    -          operations-per-run: 1000
    \ No newline at end of file
    diff --git a/themes/butterfly/LICENSE b/themes/butterfly/LICENSE
    deleted file mode 100644
    index 7a4a3ea2..00000000
    --- a/themes/butterfly/LICENSE
    +++ /dev/null
    @@ -1,202 +0,0 @@
    -
    -                                 Apache License
    -                           Version 2.0, January 2004
    -                        http://www.apache.org/licenses/
    -
    -   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
    -
    -   1. Definitions.
    -
    -      "License" shall mean the terms and conditions for use, reproduction,
    -      and distribution as defined by Sections 1 through 9 of this document.
    -
    -      "Licensor" shall mean the copyright owner or entity authorized by
    -      the copyright owner that is granting the License.
    -
    -      "Legal Entity" shall mean the union of the acting entity and all
    -      other entities that control, are controlled by, or are under common
    -      control with that entity. For the purposes of this definition,
    -      "control" means (i) the power, direct or indirect, to cause the
    -      direction or management of such entity, whether by contract or
    -      otherwise, or (ii) ownership of fifty percent (50%) or more of the
    -      outstanding shares, or (iii) beneficial ownership of such entity.
    -
    -      "You" (or "Your") shall mean an individual or Legal Entity
    -      exercising permissions granted by this License.
    -
    -      "Source" form shall mean the preferred form for making modifications,
    -      including but not limited to software source code, documentation
    -      source, and configuration files.
    -
    -      "Object" form shall mean any form resulting from mechanical
    -      transformation or translation of a Source form, including but
    -      not limited to compiled object code, generated documentation,
    -      and conversions to other media types.
    -
    -      "Work" shall mean the work of authorship, whether in Source or
    -      Object form, made available under the License, as indicated by a
    -      copyright notice that is included in or attached to the work
    -      (an example is provided in the Appendix below).
    -
    -      "Derivative Works" shall mean any work, whether in Source or Object
    -      form, that is based on (or derived from) the Work and for which the
    -      editorial revisions, annotations, elaborations, or other modifications
    -      represent, as a whole, an original work of authorship. For the purposes
    -      of this License, Derivative Works shall not include works that remain
    -      separable from, or merely link (or bind by name) to the interfaces of,
    -      the Work and Derivative Works thereof.
    -
    -      "Contribution" shall mean any work of authorship, including
    -      the original version of the Work and any modifications or additions
    -      to that Work or Derivative Works thereof, that is intentionally
    -      submitted to Licensor for inclusion in the Work by the copyright owner
    -      or by an individual or Legal Entity authorized to submit on behalf of
    -      the copyright owner. For the purposes of this definition, "submitted"
    -      means any form of electronic, verbal, or written communication sent
    -      to the Licensor or its representatives, including but not limited to
    -      communication on electronic mailing lists, source code control systems,
    -      and issue tracking systems that are managed by, or on behalf of, the
    -      Licensor for the purpose of discussing and improving the Work, but
    -      excluding communication that is conspicuously marked or otherwise
    -      designated in writing by the copyright owner as "Not a Contribution."
    -
    -      "Contributor" shall mean Licensor and any individual or Legal Entity
    -      on behalf of whom a Contribution has been received by Licensor and
    -      subsequently incorporated within the Work.
    -
    -   2. Grant of Copyright License. Subject to the terms and conditions of
    -      this License, each Contributor hereby grants to You a perpetual,
    -      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
    -      copyright license to reproduce, prepare Derivative Works of,
    -      publicly display, publicly perform, sublicense, and distribute the
    -      Work and such Derivative Works in Source or Object form.
    -
    -   3. Grant of Patent License. Subject to the terms and conditions of
    -      this License, each Contributor hereby grants to You a perpetual,
    -      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
    -      (except as stated in this section) patent license to make, have made,
    -      use, offer to sell, sell, import, and otherwise transfer the Work,
    -      where such license applies only to those patent claims licensable
    -      by such Contributor that are necessarily infringed by their
    -      Contribution(s) alone or by combination of their Contribution(s)
    -      with the Work to which such Contribution(s) was submitted. If You
    -      institute patent litigation against any entity (including a
    -      cross-claim or counterclaim in a lawsuit) alleging that the Work
    -      or a Contribution incorporated within the Work constitutes direct
    -      or contributory patent infringement, then any patent licenses
    -      granted to You under this License for that Work shall terminate
    -      as of the date such litigation is filed.
    -
    -   4. Redistribution. You may reproduce and distribute copies of the
    -      Work or Derivative Works thereof in any medium, with or without
    -      modifications, and in Source or Object form, provided that You
    -      meet the following conditions:
    -
    -      (a) You must give any other recipients of the Work or
    -          Derivative Works a copy of this License; and
    -
    -      (b) You must cause any modified files to carry prominent notices
    -          stating that You changed the files; and
    -
    -      (c) You must retain, in the Source form of any Derivative Works
    -          that You distribute, all copyright, patent, trademark, and
    -          attribution notices from the Source form of the Work,
    -          excluding those notices that do not pertain to any part of
    -          the Derivative Works; and
    -
    -      (d) If the Work includes a "NOTICE" text file as part of its
    -          distribution, then any Derivative Works that You distribute must
    -          include a readable copy of the attribution notices contained
    -          within such NOTICE file, excluding those notices that do not
    -          pertain to any part of the Derivative Works, in at least one
    -          of the following places: within a NOTICE text file distributed
    -          as part of the Derivative Works; within the Source form or
    -          documentation, if provided along with the Derivative Works; or,
    -          within a display generated by the Derivative Works, if and
    -          wherever such third-party notices normally appear. The contents
    -          of the NOTICE file are for informational purposes only and
    -          do not modify the License. You may add Your own attribution
    -          notices within Derivative Works that You distribute, alongside
    -          or as an addendum to the NOTICE text from the Work, provided
    -          that such additional attribution notices cannot be construed
    -          as modifying the License.
    -
    -      You may add Your own copyright statement to Your modifications and
    -      may provide additional or different license terms and conditions
    -      for use, reproduction, or distribution of Your modifications, or
    -      for any such Derivative Works as a whole, provided Your use,
    -      reproduction, and distribution of the Work otherwise complies with
    -      the conditions stated in this License.
    -
    -   5. Submission of Contributions. Unless You explicitly state otherwise,
    -      any Contribution intentionally submitted for inclusion in the Work
    -      by You to the Licensor shall be under the terms and conditions of
    -      this License, without any additional terms or conditions.
    -      Notwithstanding the above, nothing herein shall supersede or modify
    -      the terms of any separate license agreement you may have executed
    -      with Licensor regarding such Contributions.
    -
    -   6. Trademarks. This License does not grant permission to use the trade
    -      names, trademarks, service marks, or product names of the Licensor,
    -      except as required for reasonable and customary use in describing the
    -      origin of the Work and reproducing the content of the NOTICE file.
    -
    -   7. Disclaimer of Warranty. Unless required by applicable law or
    -      agreed to in writing, Licensor provides the Work (and each
    -      Contributor provides its Contributions) on an "AS IS" BASIS,
    -      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
    -      implied, including, without limitation, any warranties or conditions
    -      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
    -      PARTICULAR PURPOSE. You are solely responsible for determining the
    -      appropriateness of using or redistributing the Work and assume any
    -      risks associated with Your exercise of permissions under this License.
    -
    -   8. Limitation of Liability. In no event and under no legal theory,
    -      whether in tort (including negligence), contract, or otherwise,
    -      unless required by applicable law (such as deliberate and grossly
    -      negligent acts) or agreed to in writing, shall any Contributor be
    -      liable to You for damages, including any direct, indirect, special,
    -      incidental, or consequential damages of any character arising as a
    -      result of this License or out of the use or inability to use the
    -      Work (including but not limited to damages for loss of goodwill,
    -      work stoppage, computer failure or malfunction, or any and all
    -      other commercial damages or losses), even if such Contributor
    -      has been advised of the possibility of such damages.
    -
    -   9. Accepting Warranty or Additional Liability. While redistributing
    -      the Work or Derivative Works thereof, You may choose to offer,
    -      and charge a fee for, acceptance of support, warranty, indemnity,
    -      or other liability obligations and/or rights consistent with this
    -      License. However, in accepting such obligations, You may act only
    -      on Your own behalf and on Your sole responsibility, not on behalf
    -      of any other Contributor, and only if You agree to indemnify,
    -      defend, and hold each Contributor harmless for any liability
    -      incurred by, or claims asserted against, such Contributor by reason
    -      of your accepting any such warranty or additional liability.
    -
    -   END OF TERMS AND CONDITIONS
    -
    -   APPENDIX: How to apply the Apache License to your work.
    -
    -      To apply the Apache License to your work, attach the following
    -      boilerplate notice, with the fields enclosed by brackets "[]"
    -      replaced with your own identifying information. (Don't include
    -      the brackets!)  The text should be enclosed in the appropriate
    -      comment syntax for the file format. We also recommend that a
    -      file or class name and description of purpose be included on the
    -      same "printed page" as the copyright notice for easier
    -      identification within third-party archives.
    -
    -   Copyright [yyyy] [name of copyright owner]
    -
    -   Licensed under the Apache License, Version 2.0 (the "License");
    -   you may not use this file except in compliance with the License.
    -   You may obtain a copy of the License at
    -
    -       http://www.apache.org/licenses/LICENSE-2.0
    -
    -   Unless required by applicable law or agreed to in writing, software
    -   distributed under the License is distributed on an "AS IS" BASIS,
    -   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    -   See the License for the specific language governing permissions and
    -   limitations under the License.
    \ No newline at end of file
    diff --git a/themes/butterfly/README.md b/themes/butterfly/README.md
    deleted file mode 100644
    index 6f74c798..00000000
    --- a/themes/butterfly/README.md
    +++ /dev/null
    @@ -1,111 +0,0 @@
    -<div align="right">
    -<a title="Chinese" href="/README_CN.md">中文</a>
    -</div>
    -
    -# hexo-theme-butterfly
    -
    -![master version](https://img.shields.io/github/package-json/v/jerryc127/hexo-theme-butterfly/master?color=%231ab1ad&label=master)
    -![master version](https://img.shields.io/github/package-json/v/jerryc127/hexo-theme-butterfly/dev?label=dev)
    -![https://img.shields.io/npm/v/hexo-theme-butterfly?color=%09%23bf00ff](https://img.shields.io/npm/v/hexo-theme-butterfly?color=%09%23bf00ff)
    -![hexo version](https://img.shields.io/badge/hexo-5.3.0+-0e83c)
    -![license](https://img.shields.io/github/license/jerryc127/hexo-theme-butterfly?color=FF5531)
    -
    -![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/theme-butterfly-readme.png)
    -
    -📢 Demo: [Butterfly](https://butterfly.js.org/) || [CrazyWong](https://blog.crazywong.com/)
    -
    -📖 Docs: [English](https://butterfly.js.org/en/posts/butterfly-docs-en-get-started/) || [Chinese](https://butterfly.js.org/posts/21cfbf15/)
    -
    -Based on [hexo-theme-melody](https://github.com/Molunerfinn/hexo-theme-melody) theme.
    -
    -## 💻 Installation
    -
    -### GIT
    -
    -> If you are in Mainland China, you can download in [Gitee](https://gitee.com/immyw/hexo-theme-butterfly.git)
    -
    -Stable branch [recommend]:
    -
    -```
    -git clone -b master https://github.com/jerryc127/hexo-theme-butterfly.git themes/butterfly
    -```
    -
    -Dev branch:
    -
    -```
    -git clone -b dev https://github.com/jerryc127/hexo-theme-butterfly.git themes/butterfly
    -```
    -
    -### NPM
    -
    -> It supports Hexo 5.0.0 or later
    -
    -In Hexo site root directory 
    -
    -```powershell
    -npm i hexo-theme-butterfly
    -```
    -
    -## ⚙ Configuration
    -
    - Set theme in the hexo work folder's root config file `_config.yml`: 
    -
    -> theme: butterfly
    -
    - If you don't have pug & stylus renderer, try this: 
    -
    -> npm install hexo-renderer-pug hexo-renderer-stylus
    -
    -## 🎉 Features
    -
    -- [x] Card UI Design
    -- [X] Support sub-menu
    -- [x] Two-column layout
    -- [x] Responsive Web Design
    -- [x] Dark Mode
    -- [x] Pjax
    -- [x] Read Mode
    -- [x] Conversion between Traditional and Simplified Chinese
    -- [X] TOC catalog is available for both computers and mobile phones
    -- [X] Built-in Syntax Highlighting Themes (darker/pale night/light/ocean/mac/mac light), also support customization
    -- [X] Code Blocks (Display code language/close or expand Code Blocks/Copy Button/word wrap)
    -- [X] Disable copy/Add a Copyright Notice to the Copied Text
    -- [X] Search (Algolia Search/Local Search)
    -- [x] Mathjax and Katex
    -- [x] Built-in 404 page
    -- [x] WordCount
    -- [x] Related articles
    -- [x] Displays outdated notice for a post
    -- [x] Share (Sharejs/Addtoany)
    -- [X] Comment (Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo/Giscus/Remark42/artalk)
    -- [x] Multiple Comment System Support
    -- [x] Online Chats (Chatra/Tidio/Daovoice/Crisp/messenger)
    -- [x] Web analytics
    -- [x] Google AdSense
    -- [x] Webmaster Verification
    -- [x] Change website colour scheme
    -- [x] Typewriter Effect: activate_power_mode
    -- [x] Background effects (Canvas ribbon/canvas_ribbon_piao/canvas_nest)
    -- [x] Mouse click effects (Fireworks/Heart/Text)
    -- [x] Preloader/Loading Animation/pace.js
    -- [x] Busuanzi visitor counter
    -- [x] Medium Zoom/Fancybox
    -- [x] Mermaid
    -- [x] Justified Gallery
    -- [x] Lazyload images
    -- [x] Instantpage/Pangu/Snackbar notification toast/PWA......
    -
    -## ✨ Contributors
    -
    -<a href="https://github.com/jerryc127/hexo-theme-butterfly/graphs/contributors">
    -  <img src="https://contrib.rocks/image?repo=jerryc127/hexo-theme-butterfly" />
    -</a>
    -
    -## 📷 Screenshots
    -
    -![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/butterfly-readme-screenshots-1.jpg)
    -![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/butterfly-readme-screenshots-2.jpg)
    -![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/butterfly-readme-screenshots-3.jpg)
    -![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/butterfly-readme-screenshots-4.jpg)
    -![](https://cdn.jsdelivr.net/gh/jerryc127/CDN/img/theme-butterfly-readme-homepage-1.png)
    -![](https://cdn.jsdelivr.net/gh/jerryc127/CDN/img/theme-butterfly-readme-homepage-2.png)
    \ No newline at end of file
    diff --git a/themes/butterfly/README_CN.md b/themes/butterfly/README_CN.md
    deleted file mode 100644
    index 8b2279ba..00000000
    --- a/themes/butterfly/README_CN.md
    +++ /dev/null
    @@ -1,111 +0,0 @@
    -<div align="right">
    -  <a title="English" href="/README.md">English</a>
    -</div>
    -
    -# hexo-theme-butterfly
    -
    -![master version](https://img.shields.io/github/package-json/v/jerryc127/hexo-theme-butterfly/master?color=%231ab1ad&label=master)
    -![master version](https://img.shields.io/github/package-json/v/jerryc127/hexo-theme-butterfly/dev?label=dev)
    -![https://img.shields.io/npm/v/hexo-theme-butterfly?color=%09%23bf00ff](https://img.shields.io/npm/v/hexo-theme-butterfly?color=%09%23bf00ff)
    -![hexo version](https://img.shields.io/badge/hexo-5.3.0+-0e83c)
    -![license](https://img.shields.io/github/license/jerryc127/hexo-theme-butterfly?color=FF5531)
    -
    -![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/theme-butterfly-readme.png)
    -
    -📢 預覽: [Butterfly](https://butterfly.js.org/) || [CrazyWong](https://blog.crazywong.com/)
    -
    -📖 文檔: [中文](https://butterfly.js.org/posts/21cfbf15/) || [English](https://butterfly.js.org/en/posts/butterfly-docs-en-get-started/)
    -
    -一款基於[hexo-theme-melody](https://github.com/Molunerfinn/hexo-theme-melody)修改的主題
    -
    -## 💻 安裝
    -
    -### Git 安裝
    -
    -> 本倉庫同時上傳到 [Gitee](https://gitee.com/immyw/hexo-theme-butterfly.git),如果你訪問 Github 緩慢,可從 Gitee 中下載。
    -
    -在博客根目錄裡安裝穩定版【推薦】
    -
    -```powershell
    -git clone -b master https://github.com/jerryc127/hexo-theme-butterfly.git themes/butterfly
    -```
    -
    -如果想要安裝比較新的dev分支,可以
    -
    -```powershell
    -git clone -b dev https://github.com/jerryc127/hexo-theme-butterfly.git themes/butterfly
    -```
    -
    -### npm 安裝
    -
    -> 此方法只支持Hexo 5.0.0以上版本
    -
    -在博客根目錄裡
    -
    -```powershell
    -npm i hexo-theme-butterfly
    -```
    -
    -## ⚙ 應用主題
    -
    -修改hexo配置文件`_config.yml`,把主題改為`Butterfly`
    -
    -```
    -theme: butterfly
    -```
    -
    ->如果你沒有pug以及stylus的渲染器,請下載安裝: npm install hexo-renderer-pug hexo-renderer-stylus --save
    -
    -## 🎉 特色
    -
    -- [x] 卡片化設計
    -- [X] 支持二級目錄
    -- [x] 雙欄設計
    -- [x] 響應式主題
    -- [x] 夜間模式
    -- [x] Pjax
    -- [x] 文章閲讀模式
    -- [x] 簡體和繁體轉換
    -- [X] 電腦和手機都可查看TOC目錄
    -- [X] 內置多種代碼配色(darker/pale night/light/ocean/mac/mac light),可自定義代碼配色
    -- [X] 代碼塊顯示代碼語言/關閉或展開代碼塊/代碼複製/代碼自動換行
    -- [X] 可關閉文字複製/可開啟內容複製增加版權信息)
    -- [X] 兩種搜索( Algolia 搜索和本地搜索)
    -- [x] Mathjax 和 Katex
    -- [x] 內置404頁面
    -- [x] 顯示字數統計
    -- [x] 顯示相關文章
    -- [x] 過期文章提醒
    -- [x] 多種分享系統(Sharejs/Addtoany)
    -- [X] 多種評論系統(Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo/Giscus/Remark42/artalk)
    -- [x] 支持雙評論部署
    -- [x] 多種在線聊天(Chatra/Tidio/Daovoice/Crisp/messenger)
    -- [x] 多種分析系統
    -- [x] 谷歌廣告/手動廣告位置
    -- [x] 各種站長驗證(Google/Bing/Baidu/360/Yandex)
    -- [x] 修改網站配色
    -- [x] 打字特效 activate_power_mode
    -- [x] 多種背景特效(靜止彩帶/動態彩帶/Canvas Nest)
    -- [x] 多種鼠標點擊特效(煙花/文字/愛心)
    -- [x] 內置一種 Preloader 加載動畫和 pace.js 加載動畫條
    -- [x] 不蒜子訪問統計
    -- [x] 兩種大圖模式(Medium Zoom/Fancybox)
    -- [x] Mermaid 圖表顯示
    -- [x] 照片牆
    -- [x] 圖片懶加載
    -- [x] Instantpage/Pangu/Snackbar彈窗/PWA......
    -
    -## ✨ 貢獻者
    -
    -<a href="https://github.com/jerryc127/hexo-theme-butterfly/graphs/contributors">
    -  <img src="https://contrib.rocks/image?repo=jerryc127/hexo-theme-butterfly" />
    -</a>
    -
    -## 📷 截圖
    -
    -![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/butterfly-readme-screenshots-1.jpg)
    -![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/butterfly-readme-screenshots-2.jpg)
    -![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/butterfly-readme-screenshots-3.jpg)
    -![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/butterfly-readme-screenshots-4.jpg)
    -![](https://cdn.jsdelivr.net/gh/jerryc127/CDN/img/theme-butterfly-readme-homepage-1.png)
    -![](https://cdn.jsdelivr.net/gh/jerryc127/CDN/img/theme-butterfly-readme-homepage-2.png)
    diff --git a/themes/butterfly/_config.yml b/themes/butterfly/_config.yml
    deleted file mode 100644
    index 96cfa5a6..00000000
    --- a/themes/butterfly/_config.yml
    +++ /dev/null
    @@ -1,993 +0,0 @@
    -# Navigation bar settings (導航欄設置)
    -# see https://butterfly.js.org/posts/4aa8abbe/##導航欄設置-Navigation-bar-settings
    -# --------------------------------------
    -
    -nav:
    -  logo: # image
    -  display_title: true
    -  fixed: false # fixed navigation bar
    -
    -# Menu 目錄
    -menu:
    -  # Home: / || fas fa-home
    -  # Archives: /archives/ || fas fa-archive
    -  # Tags: /tags/ || fas fa-tags
    -  # Categories: /categories/ || fas fa-folder-open
    -  # List||fas fa-list:
    -  #   Music: /music/ || fas fa-music
    -  #   Movie: /movies/ || fas fa-video
    -  # Link: /link/ || fas fa-link
    -  # About: /about/ || fas fa-heart
    -
    -# Code Blocks (代碼相關)
    -# --------------------------------------
    -
    -highlight_theme: light #  darker / pale night / light / ocean / mac / mac light / false
    -highlight_copy: true # copy button
    -highlight_lang: true # show the code language
    -highlight_shrink: false # true: shrink the code blocks / false: expand the code blocks | none: expand code blocks and hide the button
    -highlight_height_limit: false # unit: px
    -code_word_wrap: false
    -
    -# Social Settings (社交圖標設置)
    -# formal:
    -#   icon: link || the description || color
    -social:
    -  # fab fa-github: https://github.com/xxxxx || Github || '#24292e'
    -  # fas fa-envelope: mailto:xxxxxx@gmail.com || Email || '#4a7dbe'
    -
    -# Image (圖片設置)
    -# --------------------------------------
    -
    -# Favicon(網站圖標)
    -favicon: /img/favicon.png
    -
    -# Avatar (頭像)
    -avatar:
    -  img: https://i.loli.net/2021/02/24/5O1day2nriDzjSu.png
    -  effect: false
    -
    -# Disable all banner image
    -disable_top_img: false
    -
    -# The banner image of home page
    -index_img:
    -
    -# If the banner of page not setting, it will show the top_img
    -default_top_img:
    -
    -# The banner image of archive page
    -archive_img:
    -
    -# If the banner of tag page not setting, it will show the top_img
    -# note: tag page, not tags page (子標籤頁面的 top_img)
    -tag_img:
    -
    -# The banner image of tag page
    -# format:
    -#  - tag name: xxxxx
    -tag_per_img:
    -
    -# If the banner of category page not setting, it will show the top_img
    -# note: category page, not categories page (子分類頁面的 top_img)
    -category_img:
    -
    -# The banner image of category page
    -# format:
    -#  - category name: xxxxx
    -category_per_img:
    -
    -cover:
    -  # display the cover or not (是否顯示文章封面)
    -  index_enable: true
    -  aside_enable: true
    -  archives_enable: true
    -  # the position of cover in home page (封面顯示的位置)
    -  # left/right/both
    -  position: both
    -  # When cover is not set, the default cover is displayed (當沒有設置cover時,默認的封面顯示)
    -  default_cover:
    -    # - https://i.loli.net/2020/05/01/gkihqEjXxJ5UZ1C.jpg
    -
    -# Replace Broken Images (替換無法顯示的圖片)
    -error_img:
    -  flink: /img/friend_404.gif
    -  post_page: /img/404.jpg
    -
    -# A simple 404 page
    -error_404:
    -  enable: false
    -  subtitle: 'Page Not Found'
    -  background: https://i.loli.net/2020/05/19/aKOcLiyPl2JQdFD.png
    -
    -post_meta:
    -  page: # Home Page
    -    date_type: created # created or updated or both 主頁文章日期是創建日或者更新日或都顯示
    -    date_format: date # date/relative 顯示日期還是相對日期
    -    categories: true # true or false 主頁是否顯示分類
    -    tags: false # true or false 主頁是否顯示標籤
    -    label: true # true or false 顯示描述性文字
    -  post:
    -    date_type: both # created or updated or both 文章頁日期是創建日或者更新日或都顯示
    -    date_format: date # date/relative 顯示日期還是相對日期
    -    categories: true # true or false 文章頁是否顯示分類
    -    tags: true # true or false 文章頁是否顯示標籤
    -    label: true # true or false 顯示描述性文字
    -
    -# Display the article introduction on homepage
    -# 1: description
    -# 2: both (if the description exists, it will show description, or show the auto_excerpt)
    -# 3: auto_excerpt (default)
    -# false: do not show the article introduction
    -index_post_content:
    -  method: 3
    -  length: 500 # if you set method to 2 or 3, the length need to config
    -
    -# anchor
    -anchor:
    -  # when you scroll, the URL will update according to header id.
    -  auto_update: false
    -  # Click the headline to scroll and update the anchor
    -  click_to_scroll: false
    -
    -# figcaption (圖片描述文字)
    -photofigcaption: false
    -
    -# copy settings
    -# copyright: Add the copyright information after copied content (複製的內容後面加上版權信息)
    -copy:
    -  enable: true
    -  copyright:
    -    enable: false
    -    limit_count: 50
    -
    -# Post
    -# --------------------------------------
    -
    -# toc (目錄)
    -toc:
    -  post: true
    -  page: false
    -  number: true
    -  expand: false
    -  style_simple: false # for post
    -  scroll_percent: true
    -
    -post_copyright:
    -  enable: true
    -  decode: false
    -  author_href:
    -  license: CC BY-NC-SA 4.0
    -  license_url: https://creativecommons.org/licenses/by-nc-sa/4.0/
    -
    -# Sponsor/reward
    -reward:
    -  enable: false
    -  text:
    -  QR_code:
    -    # - img: /img/wechat.jpg
    -    #   link:
    -    #   text: wechat
    -    # - img: /img/alipay.jpg
    -    #   link:
    -    #   text: alipay
    -
    -# Post edit
    -# Easily browse and edit blog source code online.
    -post_edit:
    -  enable: false
    -  # url: https://github.com/user-name/repo-name/edit/branch-name/subdirectory-name/
    -  # For example: https://github.com/jerryc127/butterfly.js.org/edit/main/source/
    -  url:
    -
    -# Related Articles
    -related_post:
    -  enable: true
    -  limit: 6 # Number of posts displayed
    -  date_type: created # or created or updated 文章日期顯示創建日或者更新日
    -
    -# post_pagination (分頁)
    -# value: 1 || 2 || false
    -# 1: The 'next post' will link to old post
    -# 2: The 'next post' will link to new post
    -# false: disable pagination
    -post_pagination: 1
    -
    -# Displays outdated notice for a post (文章過期提醒)
    -noticeOutdate:
    -  enable: false
    -  style: flat # style: simple/flat
    -  limit_day: 500 # When will it be shown
    -  position: top # position: top/bottom
    -  message_prev: It has been
    -  message_next: days since the last update, the content of the article may be outdated.
    -
    -# Footer Settings
    -# --------------------------------------
    -footer:
    -  owner:
    -    enable: true
    -    since: 2020
    -  custom_text:
    -  copyright: true # Copyright of theme and framework
    -
    -# aside (側邊欄)
    -# --------------------------------------
    -
    -aside:
    -  enable: true
    -  hide: false
    -  button: true
    -  mobile: true # display on mobile
    -  position: right # left or right
    -  display:
    -    archive: true
    -    tag: true
    -    category: true
    -  card_author:
    -    enable: true
    -    description:
    -    button:
    -      enable: true
    -      icon: fab fa-github
    -      text: Follow Me
    -      link: https://github.com/xxxxxx
    -  card_announcement:
    -    enable: true
    -    content: This is my Blog
    -  card_recent_post:
    -    enable: true
    -    limit: 5 # if set 0 will show all
    -    sort: date # date or updated
    -    sort_order: # Don't modify the setting unless you know how it works
    -  card_categories:
    -    enable: true
    -    limit: 8 # if set 0 will show all
    -    expand: none # none/true/false
    -    sort_order: # Don't modify the setting unless you know how it works
    -  card_tags:
    -    enable: true
    -    limit: 40 # if set 0 will show all
    -    color: false
    -    orderby: random # Order of tags, random/name/length
    -    order: 1 # Sort of order. 1, asc for ascending; -1, desc for descending
    -    sort_order: # Don't modify the setting unless you know how it works
    -  card_archives:
    -    enable: true
    -    type: monthly # yearly or monthly
    -    format: MMMM YYYY # eg: YYYY年MM月
    -    order: -1 # Sort of order. 1, asc for ascending; -1, desc for descending
    -    limit: 8 # if set 0 will show all
    -    sort_order: # Don't modify the setting unless you know how it works
    -  card_webinfo:
    -    enable: true
    -    post_count: true
    -    last_push_date: true
    -    sort_order: # Don't modify the setting unless you know how it works
    -  card_post_series:
    -    enable: true
    -    orderBy: 'date' # Order by title or date
    -    order: -1 # Sort of order. 1, asc for ascending; -1, desc for descending
    -
    -# busuanzi count for PV / UV in site
    -# 訪問人數
    -busuanzi:
    -  site_uv: true
    -  site_pv: true
    -  page_pv: true
    -
    -# Time difference between publish date and now (網頁運行時間)
    -# Formal: Month/Day/Year Time or Year/Month/Day Time
    -runtimeshow:
    -  enable: false
    -  publish_date:
    -
    -# Aside widget - Newest Comments
    -newest_comments:
    -  enable: false
    -  sort_order: # Don't modify the setting unless you know how it works
    -  limit: 6
    -  storage: 10 # unit: mins, save data to localStorage
    -  avatar: true
    -
    -# Bottom right button (右下角按鈕)
    -# --------------------------------------
    -
    -# Conversion between Traditional and Simplified Chinese (簡繁轉換)
    -translate:
    -  enable: false
    -  # The text of a button
    -  default: 繁
    -  # the language of website (1 - Traditional Chinese/ 2 - Simplified Chinese)
    -  defaultEncoding: 2
    -  # Time delay
    -  translateDelay: 0
    -  # The text of the button when the language is Simplified Chinese
    -  msgToTraditionalChinese: '繁'
    -  # The text of the button when the language is Traditional Chinese
    -  msgToSimplifiedChinese: '簡'
    -
    -# Read Mode (閲讀模式)
    -readmode: true
    -
    -# dark mode
    -darkmode:
    -  enable: true
    -  # Toggle Button to switch dark/light mode
    -  button: true
    -  # Switch dark/light mode automatically (自動切換 dark mode和 light mode)
    -  # autoChangeMode: 1  Following System Settings, if the system doesn't support dark mode, it will switch dark mode between 6 pm to 6 am
    -  # autoChangeMode: 2  Switch dark mode between 6 pm to 6 am
    -  # autoChangeMode: false
    -  autoChangeMode: false
    -  # Set the light mode time. The value is between 0 and 24. If not set, the default value is 6 and 18
    -  start: # 8
    -  end: # 22
    -
    -# show scroll percent in scroll-to-top button
    -rightside_scroll_percent: false
    -
    -# Don't modify the following settings unless you know how they work (非必要請不要修改 )
    -# Choose: readmode,translate,darkmode,hideAside,toc,chat,comment
    -# Don't repeat 不要重複
    -rightside_item_order:
    -  enable: false
    -  hide: # readmode,translate,darkmode,hideAside
    -  show: # toc,chat,comment
    -
    -# Math (數學)
    -# --------------------------------------
    -# About the per_page
    -# if you set it to true, it will load mathjax/katex script in each page (true 表示每一頁都加載js)
    -# if you set it to false, it will load mathjax/katex script according to your setting (add the 'mathjax: true' in page's front-matter)
    -# (false 需要時加載,須在使用的 Markdown Front-matter 加上 mathjax: true)
    -
    -# MathJax
    -mathjax:
    -  enable: false
    -  per_page: false
    -
    -# KaTeX
    -katex:
    -  enable: false
    -  per_page: false
    -  hide_scrollbar: true
    -
    -# search (搜索)
    -# see https://butterfly.js.org/posts/ceeb73f/#搜索系統
    -# --------------------------------------
    -
    -# Algolia search
    -algolia_search:
    -  enable: false
    -  hits:
    -    per_page: 6
    -
    -# Local search
    -local_search:
    -  enable: false
    -  # Preload the search data when the page loads.
    -  preload: false
    -  # Show top n results per article, show all results by setting to -1
    -  top_n_per_article: 1
    -  # Unescape html strings to the readable one.
    -  unescape: false
    -  CDN:
    -
    -# Docsearch
    -docsearch:
    -  enable: false
    -  appId:
    -  apiKey:
    -  indexName:
    -  option:
    -
    -# Share System (分享)
    -# --------------------------------------
    -
    -# Share.js
    -# https://github.com/overtrue/share.js
    -sharejs:
    -  enable: true
    -  sites: facebook,twitter,wechat,weibo,qq
    -
    -# AddToAny
    -# https://www.addtoany.com/
    -addtoany:
    -  enable: false
    -  item: facebook,twitter,wechat,sina_weibo,facebook_messenger,email,copy_link
    -
    -# Comments System
    -# --------------------------------------
    -
    -comments:
    -  # Up to two comments system, the first will be shown as default
    -  # Choose: Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo/Giscus/Remark42/Artalk
    -  use: # Valine,Disqus
    -  text: true # Display the comment name next to the button
    -  # lazyload: The comment system will be load when comment element enters the browser's viewport.
    -  # If you set it to true, the comment count will be invalid
    -  lazyload: false
    -  count: false # Display comment count in post's top_img
    -  card_post_count: false # Display comment count in Home Page
    -
    -# disqus
    -# https://disqus.com/
    -disqus:
    -  shortname:
    -  apikey: # For newest comments widget
    -
    -# Alternative Disqus - Render comments with Disqus API
    -# DisqusJS 評論系統,可以實現在網路審查地區載入 Disqus 評論列表,兼容原版
    -# https://github.com/SukkaW/DisqusJS
    -disqusjs:
    -  shortname:
    -  apikey:
    -  option:
    -
    -# livere (來必力)
    -# https://www.livere.com/
    -livere:
    -  uid:
    -
    -# gitalk
    -# https://github.com/gitalk/gitalk
    -gitalk:
    -  client_id:
    -  client_secret:
    -  repo:
    -  owner:
    -  admin:
    -  option:
    -
    -# valine
    -# https://valine.js.org
    -valine:
    -  appId: # leancloud application app id
    -  appKey: # leancloud application app key
    -  avatar: monsterid # gravatar style https://valine.js.org/#/avatar
    -  serverURLs: # This configuration is suitable for domestic custom domain name users, overseas version will be automatically detected (no need to manually fill in)
    -  bg: # valine background
    -  visitor: false
    -  option:
    -
    -# waline - A simple comment system with backend support fork from Valine
    -# https://waline.js.org/
    -waline:
    -  serverURL: # Waline server address url
    -  bg: # waline background
    -  pageview: false
    -  option:
    -
    -# utterances
    -# https://utteranc.es/
    -utterances:
    -  repo:
    -  # Issue Mapping: pathname/url/title/og:title
    -  issue_term: pathname
    -  # Theme: github-light/github-dark/github-dark-orange/icy-dark/dark-blue/photon-dark
    -  light_theme: github-light
    -  dark_theme: photon-dark
    -
    -# Facebook Comments Plugin
    -# https://developers.facebook.com/docs/plugins/comments/
    -facebook_comments:
    -  app_id:
    -  user_id: # optional
    -  pageSize: 10 # The number of comments to show
    -  order_by: social # social/time/reverse_time
    -  lang: zh_TW # Language en_US/zh_CN/zh_TW and so on
    -
    -# Twikoo
    -# https://github.com/imaegoo/twikoo
    -twikoo:
    -  envId:
    -  region:
    -  visitor: false
    -  option:
    -
    -# Giscus
    -# https://giscus.app/
    -giscus:
    -  repo:
    -  repo_id:
    -  category_id:
    -  theme:
    -    light: light
    -    dark: dark
    -  option:
    -
    -# Remark42
    -# https://remark42.com/docs/configuration/frontend/
    -remark42:
    -  host: # Your Host URL
    -  siteId: # Your Site ID
    -  option:
    -
    -# Artalk
    -# https://artalk.js.org/guide/frontend/config.html
    -artalk:
    -  server:
    -  site:
    -  visitor: false
    -  option:
    -
    -# Chat Services
    -# --------------------------------------
    -
    -# Chat Button [recommend]
    -# It will create a button in the bottom right corner of website, and hide the origin button
    -chat_btn: false
    -
    -# The origin chat button is displayed when scrolling up, and the button is hidden when scrolling down
    -chat_hide_show: false
    -
    -# chatra
    -# https://chatra.io/
    -chatra:
    -  enable: false
    -  id:
    -
    -# tidio
    -# https://www.tidio.com/
    -tidio:
    -  enable: false
    -  public_key:
    -
    -# daovoice
    -# http://dashboard.daovoice.io/app
    -daovoice:
    -  enable: false
    -  app_id:
    -
    -# crisp
    -# https://crisp.chat/en/
    -crisp:
    -  enable: false
    -  website_id:
    -
    -# messenger
    -# https://developers.facebook.com/docs/messenger-platform/discovery/facebook-chat-plugin/
    -messenger:
    -  enable: false
    -  pageID:
    -  lang: zh_TW # Language en_US/zh_CN/zh_TW and so on
    -
    -# Analysis
    -# --------------------------------------
    -
    -# Baidu Analytics
    -# https://tongji.baidu.com/web/welcome/login
    -baidu_analytics:
    -
    -# Google Analytics
    -# https://analytics.google.com/analytics/web/
    -google_analytics:
    -
    -# Cloudflare Analytics
    -# https://www.cloudflare.com/zh-tw/web-analytics/
    -cloudflare_analytics:
    -
    -# Microsoft Clarity
    -# https://clarity.microsoft.com/
    -microsoft_clarity:
    -
    -# Advertisement
    -# --------------------------------------
    -
    -# Google Adsense (谷歌廣告)
    -google_adsense:
    -  enable: false
    -  auto_ads: true
    -  js: https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js
    -  client:
    -  enable_page_level_ads: true
    -
    -# Insert ads manually (手動插入廣告)
    -# ad:
    -#   index:
    -#   aside:
    -#   post:
    -
    -# Verification (站長驗證)
    -# --------------------------------------
    -
    -site_verification:
    -  # - name: google-site-verification
    -  #   content: xxxxxx
    -  # - name: baidu-site-verification
    -  #   content: xxxxxxx
    -
    -# Beautify/Effect (美化/效果)
    -# --------------------------------------
    -
    -# Theme color for customize
    -# Notice: color value must in double quotes like "#000" or may cause error!
    -
    -# theme_color:
    -#   enable: true
    -#   main: "#49B1F5"
    -#   paginator: "#00c4b6"
    -#   button_hover: "#FF7242"
    -#   text_selection: "#00c4b6"
    -#   link_color: "#99a9bf"
    -#   meta_color: "#858585"
    -#   hr_color: "#A4D8FA"
    -#   code_foreground: "#F47466"
    -#   code_background: "rgba(27, 31, 35, .05)"
    -#   toc_color: "#00c4b6"
    -#   blockquote_padding_color: "#49b1f5"
    -#   blockquote_background_color: "#49b1f5"
    -#   scrollbar_color: "#49b1f5"
    -#   meta_theme_color_light: "ffffff"
    -#   meta_theme_color_dark: "#0d0d0d"
    -
    -# The top_img settings of home page
    -# default: top img - full screen, site info - middle (默認top_img全屏,site_info在中間)
    -# The position of site info, eg: 300px/300em/300rem/10% (主頁標題距離頂部距離)
    -index_site_info_top:
    -# The height of top_img, eg: 300px/300em/300rem (主頁top_img高度)
    -index_top_img_height:
    -
    -# The user interface setting of category and tag page (category和tag頁的UI設置)
    -# index - same as Homepage UI (index 值代表 UI將與首頁的UI一樣)
    -# default - same as archives UI 默認跟archives頁面UI一樣
    -category_ui: # 留空或 index
    -tag_ui: # 留空或 index
    -
    -# Stretches the lines so that each line has equal width(文字向兩側對齊,對最後一行無效)
    -text_align_justify: false
    -
    -# Website Background (設置網站背景)
    -# can set it to color or image (可設置圖片 或者 顔色)
    -# The formal of image: url(http://xxxxxx.com/xxx.jpg)
    -background:
    -
    -# Footer Background
    -footer_bg: false
    -
    -# Add mask to header or footer (为 header 或 footer 添加黑色半透遮罩)
    -mask:
    -  header: true
    -  footer: true
    -
    -# the position of bottom right button/default unit: px (右下角按鈕距離底部的距離/默認單位為px)
    -rightside_bottom:
    -
    -# Enter transitions (開啓網頁進入效果)
    -enter_transitions: true
    -
    -# Typewriter Effect (打字效果)
    -# https://github.com/disjukr/activate-power-mode
    -activate_power_mode:
    -  enable: false
    -  colorful: true # open particle animation (冒光特效)
    -  shake: true #  open shake (抖動特效)
    -  mobile: false
    -
    -# Background effects (背景特效)
    -# --------------------------------------
    -
    -# canvas_ribbon (靜止彩帶背景)
    -# See: https://github.com/hustcc/ribbon.js
    -canvas_ribbon:
    -  enable: false
    -  size: 150
    -  alpha: 0.6
    -  zIndex: -1
    -  click_to_change: false
    -  mobile: false
    -
    -# Fluttering Ribbon (動態彩帶)
    -canvas_fluttering_ribbon:
    -  enable: false
    -  mobile: false
    -
    -# canvas_nest
    -# https://github.com/hustcc/canvas-nest.js
    -canvas_nest:
    -  enable: false
    -  color: '0,0,255' #color of lines, default: '0,0,0'; RGB values: (R,G,B).(note: use ',' to separate.)
    -  opacity: 0.7 # the opacity of line (0~1), default: 0.5.
    -  zIndex: -1 # z-index property of the background, default: -1.
    -  count: 99 # the number of lines, default: 99.
    -  mobile: false
    -
    -# Mouse click effects: fireworks (鼠標點擊效果: 煙火特效)
    -fireworks:
    -  enable: false
    -  zIndex: 9999 # -1 or 9999
    -  mobile: false
    -
    -# Mouse click effects: Heart symbol (鼠標點擊效果: 愛心)
    -click_heart:
    -  enable: false
    -  mobile: false
    -
    -# Mouse click effects: words (鼠標點擊效果: 文字)
    -clickShowText:
    -  enable: false
    -  text:
    -    # - I
    -    # - LOVE
    -    # - YOU
    -  fontSize: 15px
    -  random: false
    -  mobile: false
    -
    -# Default display mode (網站默認的顯示模式)
    -# light (default) / dark
    -display_mode: light
    -
    -# Beautify (美化頁面顯示)
    -beautify:
    -  enable: false
    -  field: post # site/post
    -  title-prefix-icon: # '\f0c1'
    -  title-prefix-icon-color: # '#F47466'
    -
    -# Global font settings
    -# Don't modify the following settings unless you know how they work (非必要不要修改)
    -font:
    -  global-font-size:
    -  code-font-size:
    -  font-family:
    -  code-font-family:
    -
    -# Font settings for the site title and site subtitle
    -# 左上角網站名字 主頁居中網站名字
    -blog_title_font:
    -  font_link:
    -  font-family:
    -
    -# The setting of divider icon (水平分隔線圖標設置)
    -hr_icon:
    -  enable: true
    -  icon: # the unicode value of Font Awesome icon, such as '\3423'
    -  icon-top:
    -
    -# the subtitle on homepage (主頁subtitle)
    -subtitle:
    -  enable: false
    -  # Typewriter Effect (打字效果)
    -  effect: true
    -  # Customize typed.js (配置typed.js)
    -  # https://github.com/mattboldt/typed.js/#customization
    -  typed_option:
    -  # source 調用第三方服務
    -  # source: false 關閉調用
    -  # source: 1  調用一言網的一句話(簡體) https://hitokoto.cn/
    -  # source: 2  調用一句網(簡體) https://yijuzhan.com/
    -  # source: 3  調用今日詩詞(簡體) https://www.jinrishici.com/
    -  # subtitle 會先顯示 source , 再顯示 sub 的內容
    -  source: false
    -  # 如果關閉打字效果,subtitle 只會顯示 sub 的第一行文字
    -  sub:
    -
    -# Loading Animation (加載動畫)
    -preloader:
    -  enable: false
    -  # source
    -  # 1. fullpage-loading
    -  # 2. pace (progress bar)
    -  source: 1
    -  # pace theme (see https://codebyzach.github.io/pace/)
    -  pace_css_url:
    -
    -# wordcount (字數統計)
    -# see https://butterfly.js.org/posts/ceeb73f/#字數統計
    -wordcount:
    -  enable: false
    -  post_wordcount: true
    -  min2read: true
    -  total_wordcount: true
    -
    -# Lightbox (圖片大圖查看模式)
    -# --------------------------------------
    -# You can only choose one, or neither (只能選擇一個 或者 兩個都不選)
    -
    -# medium-zoom
    -# https://github.com/francoischalifour/medium-zoom
    -medium_zoom: false
    -
    -# fancybox
    -# https://fancyapps.com/fancybox/
    -fancybox: true
    -
    -# Tag Plugins settings (標籤外掛)
    -# --------------------------------------
    -
    -# series (系列文章)
    -series:
    -  enable: true
    -  orderBy: 'title' # Order by title or date
    -  order: 1 # Sort of order. 1, asc for ascending; -1, desc for descending
    -  number: true
    -
    -# abcjs (樂譜渲染)
    -# See https://github.com/paulrosen/abcjs
    -abcjs:
    -  enable: false
    -  per_page: true
    -
    -# mermaid
    -# see https://github.com/mermaid-js/mermaid
    -mermaid:
    -  enable: false
    -  # built-in themes: default/forest/dark/neutral
    -  theme:
    -    light: default
    -    dark: dark
    -
    -# Note (Bootstrap Callout)
    -note:
    -  # Note tag style values:
    -  #  - simple    bs-callout old alert style. Default.
    -  #  - modern    bs-callout new (v2-v3) alert style.
    -  #  - flat      flat callout style with background, like on Mozilla or StackOverflow.
    -  #  - disabled  disable all CSS styles import of note tag.
    -  style: flat
    -  icons: true
    -  border_radius: 3
    -  # Offset lighter of background in % for modern and flat styles (modern: -12 | 12; flat: -18 | 6).
    -  # Offset also applied to label tag variables. This option can work with disabled note tag.
    -  light_bg_offset: 0
    -
    -# other
    -# --------------------------------------
    -
    -# Pjax
    -# It may contain bugs and unstable, give feedback when you find the bugs.
    -# https://github.com/MoOx/pjax
    -pjax:
    -  enable: false
    -  exclude:
    -    # - xxxx
    -    # - xxxx
    -
    -# Inject the css and script (aplayer/meting)
    -aplayerInject:
    -  enable: false
    -  per_page: true
    -
    -# Snackbar (Toast Notification 彈窗)
    -# https://github.com/polonel/SnackBar
    -# position 彈窗位置
    -# 可選 top-left / top-center / top-right / bottom-left / bottom-center / bottom-right
    -snackbar:
    -  enable: false
    -  position: bottom-left
    -  bg_light: '#49b1f5' # The background color of Toast Notification in light mode
    -  bg_dark: '#1f1f1f' # The background color of Toast Notification in dark mode
    -
    -# https://instant.page/
    -# prefetch (預加載)
    -instantpage: false
    -
    -# https://github.com/vinta/pangu.js
    -# Insert a space between Chinese character and English character (中英文之間添加空格)
    -pangu:
    -  enable: false
    -  field: site # site/post
    -
    -# Lazyload (圖片懶加載)
    -# https://github.com/verlok/vanilla-lazyload
    -lazyload:
    -  enable: false
    -  field: site # site/post
    -  placeholder:
    -  blur: false
    -
    -# PWA
    -# See https://github.com/JLHwung/hexo-offline
    -# ---------------
    -# pwa:
    -#   enable: false
    -#   manifest: /pwa/manifest.json
    -#   apple_touch_icon: /pwa/apple-touch-icon.png
    -#   favicon_32_32: /pwa/32.png
    -#   favicon_16_16: /pwa/16.png
    -#   mask_icon: /pwa/safari-pinned-tab.svg
    -
    -# Open graph meta tags
    -# https://developers.facebook.com/docs/sharing/webmasters/
    -Open_Graph_meta:
    -  enable: true
    -  option:
    -    # twitter_card:
    -    # twitter_image:
    -    # twitter_id:
    -    # twitter_site:
    -    # google_plus:
    -    # fb_admins:
    -    # fb_app_id:
    -
    -# Add the vendor prefixes to ensure compatibility
    -css_prefix: true
    -
    -# Inject
    -# Insert the code to head (before '</head>' tag) and the bottom (before '</body>' tag)
    -# 插入代码到头部 </head> 之前 和 底部 </body> 之前
    -inject:
    -  head:
    -    # - <link rel="stylesheet" href="/xxx.css">
    -  bottom:
    -    # - <script src="xxxx"></script>
    -
    -# CDN
    -# Don't modify the following settings unless you know how they work
    -# 非必要請不要修改
    -CDN:
    -  # The CDN provider of internal scripts (主題內部 js 的 cdn 配置)
    -  # option: local/jsdelivr/unpkg/cdnjs/custom
    -  # Dev version can only choose. ( dev版的主題只能設置為 local )
    -  internal_provider: local
    -
    -  # The CDN provider of third party scripts (第三方 js 的 cdn 配置)
    -  # option: local/jsdelivr/unpkg/cdnjs/custom
    -  # when set it to local, you need to install hexo-butterfly-extjs
    -  third_party_provider: jsdelivr
    -
    -  # Add version number to url, true or false
    -  version: false
    -
    -  # Custom format
    -  # For example: https://cdn.staticfile.org/${cdnjs_name}/${version}/${min_cdnjs_file}
    -  custom_format:
    -
    -  option:
    -    # abcjs_basic_js:
    -    # activate_power_mode:
    -    # algolia_js:
    -    # algolia_search:
    -    # aplayer_css:
    -    # aplayer_js:
    -    # artalk_css:
    -    # artalk_js:
    -    # blueimp_md5:
    -    # busuanzi:
    -    # canvas_fluttering_ribbon:
    -    # canvas_nest:
    -    # canvas_ribbon:
    -    # click_heart:
    -    # clickShowText:
    -    # disqusjs:
    -    # disqusjs_css:
    -    # docsearch_css:
    -    # docsearch_js:
    -    # egjs_infinitegrid:
    -    # fancybox:
    -    # fancybox_css:
    -    # fireworks:
    -    # fontawesome:
    -    # gitalk:
    -    # gitalk_css:
    -    # giscus:
    -    # instantpage:
    -    # instantsearch:
    -    # katex:
    -    # katex_copytex:
    -    # lazyload:
    -    # local_search:
    -    # main:
    -    # main_css:
    -    # mathjax:
    -    # medium_zoom:
    -    # mermaid:
    -    # meting_js:
    -    # pangu:
    -    # prismjs_autoloader:
    -    # prismjs_js:
    -    # prismjs_lineNumber_js:
    -    # pjax:
    -    # sharejs:
    -    # sharejs_css:
    -    # snackbar:
    -    # snackbar_css:
    -    # translate:
    -    # twikoo:
    -    # typed:
    -    # utils:
    -    # valine:
    -    # waline_css:
    -    # waline_js:
    \ No newline at end of file
    diff --git a/themes/butterfly/languages/default.yml b/themes/butterfly/languages/default.yml
    deleted file mode 100644
    index 59ddd22e..00000000
    --- a/themes/butterfly/languages/default.yml
    +++ /dev/null
    @@ -1,123 +0,0 @@
    -footer:
    -  framework: Framework
    -  theme: Theme
    -
    -copy:
    -  success: Copy Successful
    -  error: Copy Error
    -  noSupport: Browser Not Supported
    -
    -page:
    -  articles: Articles
    -  tag: Tag
    -  category: Category
    -  archives: Archives
    -
    -card_post_count: comments
    -
    -no_title: Untitled
    -
    -post:
    -  created: Created
    -  updated: Updated
    -  wordcount: Word Count
    -  min2read: Reading Time
    -  min2read_unit: mins
    -  page_pv: Post Views
    -  comments: Comments
    -  copyright:
    -    author: Author
    -    link: Link
    -    copyright_notice: Copyright Notice
    -    copyright_content: 'All articles in this blog are licensed under <a href="%s">%s</a> unless stating additionally.'
    -  recommend: Related Articles
    -  edit: Edited on
    -
    -search:
    -  title: Search
    -  load_data: Loading the Database
    -  algolia_search:
    -    input_placeholder: Search for Posts
    -    hits_empty: "We didn't find any results for the search: ${query}."
    -    hits_stats: '${hits} results found in ${time} ms'
    -
    -  local_search:
    -    input_placeholder: Search for Posts
    -    hits_empty: "We didn't find any results for the search: ${query}"
    -    hits_stats: '${hits} results found'
    -
    -pagination:
    -  prev: Previous
    -  next: Next
    -
    -comment: Comment
    -
    -aside:
    -  articles: Articles
    -  tags: Tags
    -  categories: Categories
    -  card_announcement: Announcement
    -  card_categories: Categories
    -  card_tags: Tags
    -  card_archives: Archives
    -  card_recent_post: Recent Post
    -  card_webinfo:
    -    headline: Info
    -    article_name: Article
    -    runtime:
    -      name: Runtime
    -      unit: days
    -    last_push_date:
    -      name: Last Update
    -    site_wordcount: Total Count
    -    site_uv_name: UV
    -    site_pv_name: PV
    -  more_button: View More
    -  card_newest_comments:
    -    headline: Latest Comments
    -    loading_text: loading...
    -    error: Unable to retrieve comments, please check the configuration
    -    zero: No comments
    -    image: image
    -    link: link
    -    code: code
    -  card_toc: Contents
    -  card_post_series: Series
    -
    -date_suffix:
    -  just: Just now
    -  min: minutes ago
    -  hour: hours ago
    -  day: days ago
    -  month: months ago
    -
    -donate: Sponsor
    -share: Share
    -
    -rightside:
    -  readmode_title: Read Mode
    -  translate_title: Toggle Between Traditional Chinese And Simplified Chinese
    -  night_mode_title: Toggle Between Light And Dark Mode
    -  back_to_top: Back To Top
    -  toc: Table Of Contents
    -  scroll_to_comment: Scroll To Comments
    -  setting: Setting
    -  aside: Toggle between Single-column and Double-column
    -  chat: Chat
    -
    -copy_copyright:
    -  author: Author
    -  link: Link
    -  source: Source
    -  info: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
    -
    -Snackbar:
    -  chs_to_cht: You have switched to Traditional Chinese
    -  cht_to_chs: You have switched to Simplified Chinese
    -  day_to_night: You have switched to Dark Mode
    -  night_to_day: You have switched to Light Mode
    -
    -loading: Loading...
    -load_more: Load More
    -
    -error404: Page Not Found
    diff --git a/themes/butterfly/languages/en.yml b/themes/butterfly/languages/en.yml
    deleted file mode 100644
    index 489b57b6..00000000
    --- a/themes/butterfly/languages/en.yml
    +++ /dev/null
    @@ -1,123 +0,0 @@
    -footer:
    -  framework: Framework
    -  theme: Theme
    -
    -copy:
    -  success: Copy Successful
    -  error: Copy Error
    -  noSupport: Browser Not Supported
    -
    -page:
    -  articles: Articles
    -  tag: Tag
    -  category: Category
    -  archives: Archives
    -
    -card_post_count: comments
    -
    -no_title: Untitled
    -
    -post:
    -  created: Created
    -  updated: Updated
    -  wordcount: Word Count
    -  min2read: Reading Time
    -  min2read_unit: mins
    -  page_pv: Post Views
    -  comments: Comments
    -  copyright:
    -    author: Author
    -    link: Link
    -    copyright_notice: Copyright Notice
    -    copyright_content: 'All articles in this blog are licensed under <a href="%s">%s</a> unless stating additionally.'
    -  recommend: Related Articles
    -  edit: Edited on
    -
    -search:
    -  title: Search
    -  load_data: Loading the Database
    -  algolia_search:
    -    input_placeholder: Search for Posts
    -    hits_empty: "We didn't find any results for the search: ${query}."
    -    hits_stats: '${hits} results found in ${time} ms'
    -
    -  local_search:
    -    input_placeholder: Search for Posts
    -    hits_empty: "We didn't find any results for the search: ${query}"
    -    hits_stats: '${hits} results found'
    -
    -pagination:
    -  prev: Previous
    -  next: Next
    -
    -comment: Comment
    -
    -aside:
    -  articles: Articles
    -  tags: Tags
    -  categories: Categories
    -  card_announcement: Announcement
    -  card_categories: Categories
    -  card_tags: Tags
    -  card_archives: Archives
    -  card_recent_post: Recent Post
    -  card_webinfo:
    -    headline: Info
    -    article_name: Article
    -    runtime:
    -      name: Runtime
    -      unit: days
    -    last_push_date:
    -      name: Last Update
    -    site_wordcount: Total Count
    -    site_uv_name: UV
    -    site_pv_name: PV
    -  more_button: View More
    -  card_newest_comments:
    -    headline: Latest Comments
    -    loading_text: loading...
    -    error: Unable to retrieve comments, please check the configuration
    -    zero: No comments
    -    image: image
    -    link: link
    -    code: code
    -  card_toc: Contents
    -  card_post_series: Series
    -
    -date_suffix:
    -  just: Just now
    -  min: minutes ago
    -  hour: hours ago
    -  day: days ago
    -  month: months ago
    -
    -donate: Sponsor
    -share: Share
    -
    -rightside:
    -  readmode_title: Read Mode
    -  translate_title: Toggle Between Traditional Chinese And Simplified Chinese
    -  night_mode_title: Toggle Between Light And Dark Mode
    -  back_to_top: Back To Top
    -  toc: Table Of Contents
    -  scroll_to_comment: Scroll To Comments
    -  setting: Setting
    -  aside: Toggle between Single-column and Double-column
    -  chat: Chat
    -
    -copy_copyright:
    -  author: Author
    -  link: Link
    -  source: Source
    -  info: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
    -
    -Snackbar:
    -  chs_to_cht: You have switched to Traditional Chinese
    -  cht_to_chs: You have switched to Simplified Chinese
    -  day_to_night: You have switched to Dark Mode
    -  night_to_day: You have switched to Light Mode
    -
    -loading: Loading...
    -load_more: Load More
    -
    -error404: Page Not Found
    \ No newline at end of file
    diff --git a/themes/butterfly/languages/zh-CN.yml b/themes/butterfly/languages/zh-CN.yml
    deleted file mode 100644
    index b030079b..00000000
    --- a/themes/butterfly/languages/zh-CN.yml
    +++ /dev/null
    @@ -1,124 +0,0 @@
    -footer:
    -  framework: 框架
    -  theme: 主题
    -
    -copy:
    -  success: 复制成功
    -  error: 复制错误
    -  noSupport: 浏览器不支持
    -
    -page:
    -  articles: 文章总览
    -  tag: 标签
    -  category: 分类
    -  archives: 归档
    -
    -card_post_count: 条评论
    -
    -no_title: 无题
    -
    -post:
    -  created: 发表于
    -  updated: 更新于
    -  wordcount: 字数总计
    -  min2read: 阅读时长
    -  min2read_unit: 分钟
    -  page_pv: 阅读量
    -  comments: 评论数
    -  copyright:
    -    author: 文章作者
    -    link: 文章链接
    -    copyright_notice: 版权声明
    -    copyright_content: '本博客所有文章除特别声明外,均采用
    -      <a href="%s" target="_blank">%s</a> 许可协议。转载请注明来自 <a href="%s" target="_blank">%s</a>!'
    -  recommend: 相关推荐
    -  edit: 编辑
    -
    -search:
    -  title: 搜索
    -  load_data: 数据库加载中
    -  algolia_search:
    -    input_placeholder: 搜索文章
    -    hits_empty: '找不到您查询的内容:${query}'
    -    hits_stats: '找到 ${hits} 条结果,用时 ${time} 毫秒'
    -
    -  local_search:
    -    input_placeholder: 搜索文章
    -    hits_empty: '找不到您查询的内容:${query}'
    -    hits_stats: '共找到 ${hits} 篇文章'
    -
    -pagination:
    -  prev: 上一篇
    -  next: 下一篇
    -
    -comment: 评论
    -
    -aside:
    -  articles: 文章
    -  tags: 标签
    -  categories: 分类
    -  card_announcement: 公告
    -  card_categories: 分类
    -  card_tags: 标签
    -  card_archives: 归档
    -  card_recent_post: 最新文章
    -  card_webinfo:
    -    headline: 网站资讯
    -    article_name: 文章数目
    -    runtime:
    -      name: 已运行时间
    -      unit: 天
    -    last_push_date:
    -      name: 最后更新时间
    -    site_wordcount: 本站总字数
    -    site_uv_name: 本站访客数
    -    site_pv_name: 本站总访问量
    -  more_button: 查看更多
    -  card_newest_comments:
    -    headline: 最新评论
    -    loading_text: 正在加载中...
    -    error: 无法获取评论,请确认相关配置是否正确
    -    zero: 没有评论
    -    image: 图片
    -    link: 链接
    -    code: 代码
    -  card_toc: 目录
    -  card_post_series: 系列文章
    -
    -date_suffix:
    -  just: 刚刚
    -  min: 分钟前
    -  hour: 小时前
    -  day: 天前
    -  month: 个月前
    -
    -donate: 赞助
    -share: 分享
    -
    -rightside:
    -  readmode_title: 阅读模式
    -  translate_title: 简繁转换
    -  night_mode_title: 浅色和深色模式转换
    -  back_to_top: 回到顶部
    -  toc: 目录
    -  scroll_to_comment: 直达评论
    -  setting: 设置
    -  aside: 单栏和双栏切换
    -  chat: 聊天
    -
    -copy_copyright:
    -  author: 作者
    -  link: 链接
    -  source: 来源
    -  info: 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    -
    -Snackbar:
    -  chs_to_cht: 你已切换为繁体中文
    -  cht_to_chs: 你已切换为简体中文
    -  day_to_night: 你已切换为深色模式
    -  night_to_day: 你已切换为浅色模式
    -
    -loading: 加载中...
    -load_more: 加载更多
    -
    -error404: 页面没有找到
    diff --git a/themes/butterfly/languages/zh-TW.yml b/themes/butterfly/languages/zh-TW.yml
    deleted file mode 100644
    index 4ac63b84..00000000
    --- a/themes/butterfly/languages/zh-TW.yml
    +++ /dev/null
    @@ -1,124 +0,0 @@
    -footer:
    -  framework: 框架
    -  theme: 主題
    -
    -copy:
    -  success: 複製成功
    -  error: 複製錯誤
    -  noSupport: 瀏覽器不支援
    -
    -page:
    -  articles: 文章總覽
    -  tag: 標籤
    -  category: 分類
    -  archives: 歸檔
    -
    -card_post_count: 條評論
    -
    -no_title: 無標題
    -
    -post:
    -  created: 發表於
    -  updated: 更新於
    -  wordcount: 字數總計
    -  min2read: 閱讀時長
    -  min2read_unit: 分鐘
    -  page_pv: 閱讀量
    -  comments: 評論數
    -  copyright:
    -    author: 文章作者
    -    link: 文章連結
    -    copyright_notice: 版權聲明
    -    copyright_content: '本部落格所有文章除特別聲明外,均採用
    -      <a href="%s" target="_blank">%s</a> 許可協議。轉載請註明來自 <a href="%s" target="_blank">%s</a>!'
    -  recommend: 相關推薦
    -  edit: 編輯
    -
    -search:
    -  title: 搜尋
    -  load_data: 資料庫載入中
    -  algolia_search:
    -    input_placeholder: 搜尋文章
    -    hits_empty: '找不到您查詢的內容:${query}'
    -    hits_stats: '找到 ${hits} 條結果,用時 ${time} 毫秒'
    -
    -  local_search:
    -    input_placeholder: 搜尋文章
    -    hits_empty: '找不到您查詢的內容:${query}'
    -    hits_stats: '共找到 ${hits} 篇文章'
    -    
    -pagination:
    -  prev: 上一篇
    -  next: 下一篇
    -
    -comment: 評論
    -
    -aside:
    -  articles: 文章
    -  tags: 標籤
    -  categories: 分類
    -  card_announcement: 公告
    -  card_categories: 分類
    -  card_tags: 標籤
    -  card_archives: 歸檔
    -  card_recent_post: 最新文章
    -  card_webinfo:
    -    headline: 網站資訊
    -    article_name: 文章數目
    -    runtime:
    -      name: 已執行時間
    -      unit: 天
    -    last_push_date:
    -      name: 最後更新時間
    -    site_wordcount: 本站總字數
    -    site_uv_name: 本站訪客數
    -    site_pv_name: 本站總訪問量
    -  more_button: 檢視更多
    -  card_newest_comments:
    -    headline: 最新評論
    -    loading_text: 正在載入中...
    -    error: 無法獲取評論,請確認相關配置是否正確
    -    zero: 沒有評論
    -    image: 圖片
    -    link: 連結
    -    code: 程式碼
    -  card_toc: 目錄
    -  card_post_series: 文章系列
    -
    -date_suffix:
    -  just: 剛剛
    -  min: 分鐘前
    -  hour: 小時前
    -  day: 天前
    -  month: 個月前
    -
    -donate: 贊助
    -share: 分享
    -
    -rightside:
    -  readmode_title: 閱讀模式
    -  translate_title: 簡繁轉換
    -  night_mode_title: 淺色和深色模式轉換
    -  back_to_top: 返回頂部
    -  toc: 目錄
    -  scroll_to_comment: 直達評論
    -  setting: 設定
    -  aside: 單欄和雙欄切換
    -  chat: 聊天
    -
    -copy_copyright:
    -  author: 作者
    -  link: 連結
    -  source: 來源
    -  info: 著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
    -
    -Snackbar:
    -  chs_to_cht: 你已切換為繁體中文
    -  cht_to_chs: 你已切換為簡體中文
    -  day_to_night: 你已切換為深色模式
    -  night_to_day: 你已切換為淺色模式
    -
    -loading: 載入中...
    -load_more: 載入更多
    -
    -error404: 頁面沒有找到
    diff --git a/themes/butterfly/layout/archive.pug b/themes/butterfly/layout/archive.pug
    deleted file mode 100644
    index 913dedcd..00000000
    --- a/themes/butterfly/layout/archive.pug
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -extends includes/layout.pug
    -
    -block content
    -  include ./includes/mixins/article-sort.pug
    -  #archive
    -    .article-sort-title= `${_p('page.articles')} - ${getArchiveLength()}`
    -    +articleSort(page.posts)
    -    include includes/pagination.pug
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/category.pug b/themes/butterfly/layout/category.pug
    deleted file mode 100644
    index 234a0af6..00000000
    --- a/themes/butterfly/layout/category.pug
    +++ /dev/null
    @@ -1,14 +0,0 @@
    -extends includes/layout.pug
    -
    -block content
    -  if theme.category_ui == 'index'
    -    include ./includes/mixins/post-ui.pug
    -    #recent-posts.recent-posts.category_ui
    -      +postUI
    -      include includes/pagination.pug
    -  else
    -    include ./includes/mixins/article-sort.pug
    -    #category
    -      .article-sort-title= _p('page.category') + ' - ' + page.category
    -      +articleSort(page.posts)
    -      include includes/pagination.pug
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/404.pug b/themes/butterfly/layout/includes/404.pug
    deleted file mode 100644
    index 4a022c85..00000000
    --- a/themes/butterfly/layout/includes/404.pug
    +++ /dev/null
    @@ -1,12 +0,0 @@
    -- var top_img_404 = theme.error_404.background || theme.default_top_img
    -
    -#body-wrap.error404
    -  include ./header/index.pug
    -
    -  #error-wrap
    -    .error-content
    -      .error-img
    -        img(src=url_for(top_img_404) alt='Page not found')
    -      .error-info
    -        h1.error_title= '404'
    -        .error_subtitle= theme.error_404.subtitle || _p('error404')
    diff --git a/themes/butterfly/layout/includes/additional-js.pug b/themes/butterfly/layout/includes/additional-js.pug
    deleted file mode 100644
    index f37d8609..00000000
    --- a/themes/butterfly/layout/includes/additional-js.pug
    +++ /dev/null
    @@ -1,65 +0,0 @@
    -div
    -  script(src=url_for(theme.asset.utils))
    -  script(src=url_for(theme.asset.main))
    -
    -  if theme.translate.enable
    -    script(src=url_for(theme.asset.translate))
    -
    -  if theme.medium_zoom
    -    script(src=url_for(theme.asset.medium_zoom))
    -  else if theme.fancybox
    -    script(src=url_for(theme.asset.fancybox))
    -
    -  if theme.instantpage
    -    script(src=url_for(theme.asset.instantpage), type='module')
    -
    -  if theme.lazyload.enable
    -    script(src=url_for(theme.asset.lazyload))
    -
    -  if theme.snackbar.enable
    -    script(src=url_for(theme.asset.snackbar))
    -
    -  if theme.pangu.enable
    -    != partial("includes/third-party/pangu.pug", {}, { cache: true })
    -
    -  .js-pjax
    -    if needLoadCountJs
    -      != partial("includes/third-party/card-post-count/index", {}, { cache: true })
    -
    -    if loadSubJs
    -      include ./third-party/subtitle.pug
    -
    -    include ./third-party/math/index.pug
    -
    -    include ./third-party/abcjs/index.pug
    -
    -    if commentsJsLoad
    -      include ./third-party/comments/js.pug
    -
    -  != partial("includes/third-party/prismjs", {}, { cache: true })
    -
    -  if theme.aside.enable && theme.newest_comments.enable
    -    if theme.pjax.enable
    -      != partial("includes/third-party/newest-comments/index", {}, { cache: true })
    -    else if (!is_post() && page.aside !== false)
    -      != partial("includes/third-party/newest-comments/index", {}, { cache: true })
    -
    -  != fragment_cache('injectBottom', function(){return injectHtml(theme.inject.bottom)})
    -
    -  != partial("includes/third-party/effect", {}, { cache: true })
    -
    -  != partial("includes/third-party/chat/index", {}, { cache: true })
    -
    -  if theme.aplayerInject && theme.aplayerInject.enable
    -    if theme.pjax.enable || theme.aplayerInject.per_page
    -      include ./third-party/aplayer.pug
    -    else if page.aplayer
    -      include ./third-party/aplayer.pug
    -
    -  if theme.pjax.enable
    -    != partial("includes/third-party/pjax", {}, { cache: true })
    -
    -  if theme.busuanzi.site_uv || theme.busuanzi.site_pv || theme.busuanzi.page_pv
    -    script(async data-pjax src= theme.asset.busuanzi || '//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js')
    -
    -  !=partial('includes/third-party/search/index', {}, {cache: true})
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/footer.pug b/themes/butterfly/layout/includes/footer.pug
    deleted file mode 100644
    index 4d2ae791..00000000
    --- a/themes/butterfly/layout/includes/footer.pug
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -#footer-wrap
    -  if theme.footer.owner.enable
    -    - var now = new Date()
    -    - var nowYear = now.getFullYear()
    -    if theme.footer.owner.since && theme.footer.owner.since != nowYear
    -      .copyright!= `&copy;${theme.footer.owner.since} - ${nowYear} By ${config.author}`
    -    else
    -      .copyright!= `&copy;${nowYear} By ${config.author}`
    -  if theme.footer.copyright
    -    .framework-info
    -      span= _p('footer.framework') + ' '
    -      a(href='https://hexo.io')= 'Hexo'
    -      span.footer-separator |
    -      span= _p('footer.theme') + ' '
    -      a(href='https://github.com/jerryc127/hexo-theme-butterfly')= 'Butterfly'
    -  if theme.footer.custom_text
    -    .footer_custom_text!=`${theme.footer.custom_text}`
    diff --git a/themes/butterfly/layout/includes/head.pug b/themes/butterfly/layout/includes/head.pug
    deleted file mode 100644
    index cd625660..00000000
    --- a/themes/butterfly/layout/includes/head.pug
    +++ /dev/null
    @@ -1,68 +0,0 @@
    -- var pageTitle
    -- is_archive() ? page.title = findArchivesTitle(page, theme.menu, date) : ''
    -- if (is_tag()) pageTitle = _p('page.tag') + ': ' + page.tag
    -- else if (is_category()) pageTitle = _p('page.category') + ': ' + page.category
    -- else if (is_current('/404.html', [strict])) pageTitle = _p('error404')
    -- else pageTitle = page.title || config.title || ''
    -
    -- var isSubtitle = config.subtitle ? ' - ' + config.subtitle : ''
    -- var tabTitle = is_home() || !pageTitle ? config.title + isSubtitle : pageTitle + ' | ' + config.title
    -- var pageAuthor = config.email ? config.author + ',' + config.email : config.author
    -- var pageCopyright = config.copyright || config.author
    -- var themeColorLight = theme.theme_color && theme.theme_color.enable && theme.theme_color.meta_theme_color_light || '#ffffff'
    -- var themeColorDark = theme.theme_color && theme.theme_color.enable && theme.theme_color.meta_theme_color_dark || '#0d0d0d'
    -- var themeColor = theme.display_mode === 'dark' ? themeColorDark : themeColorLight
    -
    -meta(charset='UTF-8')
    -meta(http-equiv="X-UA-Compatible" content="IE=edge")
    -meta(name="viewport" content="width=device-width, initial-scale=1.0,viewport-fit=cover")
    -title= tabTitle
    -meta(name="author" content=pageAuthor)
    -meta(name="copyright" content=pageCopyright)
    -meta(name ="format-detection" content="telephone=no")
    -meta(name="theme-color" content=themeColor)
    -
    -//- Open_Graph
    -include ./head/Open_Graph.pug
    -
    -!=favicon_tag(theme.favicon || config.favicon)
    -link(rel="canonical" href=urlNoIndex(null,config.pretty_urls.trailing_index,config.pretty_urls.trailing_html))
    -
    -//- 預解析
    -!=partial('includes/head/preconnect', {}, {cache: true})
    -
    -//- 網站驗證
    -!=partial('includes/head/site_verification', {}, {cache: true})
    -
    -//- PWA
    -if (theme.pwa && theme.pwa.enable)
    -  !=partial('includes/head/pwa', {}, {cache: true})
    -
    -//- main css
    -link(rel='stylesheet', href=url_for(theme.asset.main_css))
    -link(rel='stylesheet', href=url_for(theme.asset.fontawesome) media="print" onload="this.media='all'")
    -
    -if (theme.snackbar && theme.snackbar.enable)
    -  link(rel='stylesheet', href=url_for(theme.asset.snackbar_css) media="print" onload="this.media='all'")
    -
    -if theme.fancybox
    -  link(rel='stylesheet' href=url_for(theme.asset.fancybox_css) media="print" onload="this.media='all'")
    -
    -//- google_adsense
    -!=partial('includes/head/google_adsense', {}, {cache: true})
    -
    -//- analytics
    -!=partial('includes/head/analytics', {}, {cache: true})
    -
    -//- font
    -if theme.blog_title_font && theme.blog_title_font.font_link
    -  link(rel='stylesheet' href=url_for(theme.blog_title_font.font_link) media="print" onload="this.media='all'")
    -
    -//- global config
    -!=partial('includes/head/config', {}, {cache: true})
    -
    -include ./head/config_site.pug
    -
    -!=fragment_cache('injectHeadJs', function(){return inject_head_js()})
    -
    -!=fragment_cache('injectHead', function(){return injectHtml(theme.inject.head)})
    diff --git a/themes/butterfly/layout/includes/head/Open_Graph.pug b/themes/butterfly/layout/includes/head/Open_Graph.pug
    deleted file mode 100644
    index 8fe04e0c..00000000
    --- a/themes/butterfly/layout/includes/head/Open_Graph.pug
    +++ /dev/null
    @@ -1,14 +0,0 @@
    -if theme.Open_Graph_meta.enable
    -  -
    -    const coverVal = page.cover_type === 'img' ? page.cover : theme.avatar.img
    -    let ogOption = Object.assign({
    -      type: is_post() ? 'article' : 'website',
    -      image: coverVal ? full_url_for(coverVal) : '',
    -      fb_admins: theme.facebook_comments.user_id || '',
    -      fb_app_id: theme.facebook_comments.app_id || '',
    -    }, theme.Open_Graph_meta.option)
    -  -
    -  != open_graph(ogOption)
    -else
    -  meta(name="description" content=page_description())
    -
    diff --git a/themes/butterfly/layout/includes/head/analytics.pug b/themes/butterfly/layout/includes/head/analytics.pug
    deleted file mode 100644
    index ad4a395e..00000000
    --- a/themes/butterfly/layout/includes/head/analytics.pug
    +++ /dev/null
    @@ -1,28 +0,0 @@
    -if theme.baidu_analytics
    -  script.
    -    var _hmt = _hmt || [];
    -    (function() {
    -      var hm = document.createElement("script");
    -      hm.src = "https://hm.baidu.com/hm.js?!{theme.baidu_analytics}";
    -      var s = document.getElementsByTagName("script")[0]; 
    -      s.parentNode.insertBefore(hm, s);
    -    })();
    -
    -if theme.google_analytics
    -  script(async src=`https://www.googletagmanager.com/gtag/js?id=${theme.google_analytics}`)
    -  script.
    -    window.dataLayer = window.dataLayer || [];
    -    function gtag(){dataLayer.push(arguments);}
    -    gtag('js', new Date());
    -    gtag('config', '!{theme.google_analytics}');
    -
    -if theme.cloudflare_analytics
    -  script(defer data-pjax src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon=`{"token": "${theme.cloudflare_analytics}"}`)
    -
    -if theme.microsoft_clarity
    -  script.
    -    (function(c,l,a,r,i,t,y){
    -        c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
    -        t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
    -        y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
    -    })(window, document, "clarity", "script", "!{theme.microsoft_clarity}");
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/head/config.pug b/themes/butterfly/layout/includes/head/config.pug
    deleted file mode 100644
    index 05b046c8..00000000
    --- a/themes/butterfly/layout/includes/head/config.pug
    +++ /dev/null
    @@ -1,130 +0,0 @@
    --
    -  let algolia = 'undefined';
    -  let env = process.env;
    -  if (theme.algolia_search.enable) {
    -    algolia = JSON.stringify({
    -      appId: env.ALGOLIA_APP_ID || config.algolia.appId || config.algolia.applicationID,
    -      apiKey: env.ALGOLIA_API_KEY || config.algolia.apiKey,
    -      indexName: env.ALGOLIA_INDEX_NAME || config.algolia.indexName,
    -      hits: theme.algolia_search.hits,
    -      // search languages
    -      languages: {
    -        input_placeholder: _p("search.algolia_search.input_placeholder"),
    -        hits_empty: _p("search.algolia_search.hits_empty"),
    -        hits_stats: _p("search.algolia_search.hits_stats"),
    -      }
    -    })
    -  }
    -
    -  let localSearch = 'undefined';
    -  if (theme.local_search && theme.local_search.enable) {
    -    localSearch = JSON.stringify({
    -      path: theme.local_search.CDN ? theme.local_search.CDN : config.root + config.search.path,
    -      preload: theme.local_search.preload,
    -      top_n_per_article: theme.local_search.top_n_per_article,
    -      unescape: theme.local_search.unescape,
    -      languages: {
    -        // search languages
    -        hits_empty: _p("search.local_search.hits_empty"),
    -        hits_stats: _p("search.local_search.hits_stats"),
    -      }
    -    })
    -  }
    -
    -  let translate = 'undefined';
    -  if (theme.translate && theme.translate.enable){
    -    translate = JSON.stringify({
    -      defaultEncoding: theme.translate.defaultEncoding,
    -      translateDelay: theme.translate.translateDelay,
    -      msgToTraditionalChinese: theme.translate.msgToTraditionalChinese,
    -      msgToSimplifiedChinese: theme.translate.msgToSimplifiedChinese
    -    })
    -  }
    -
    -  let copyright = 'undefined';
    -  if (theme.copy.enable && theme.copy.copyright.enable){
    -    copyright = JSON.stringify({
    -      limitCount: theme.copy.copyright.limit_count,
    -      languages: {
    -        author: _p("copy_copyright.author") + ': ' + config.author,
    -        link: _p("copy_copyright.link") + ': ',
    -        source: _p("copy_copyright.source") + ': ' + config.title,
    -        info: _p("copy_copyright.info")
    -      }
    -    })
    -  }
    -
    -  let Snackbar = 'undefined';
    -  if (theme.snackbar && theme.snackbar.enable) {
    -    Snackbar = JSON.stringify({
    -      chs_to_cht: _p("Snackbar.chs_to_cht"),
    -      cht_to_chs: _p("Snackbar.cht_to_chs"),
    -      day_to_night: _p("Snackbar.day_to_night"),
    -      night_to_day: _p("Snackbar.night_to_day"),
    -      bgLight: theme.snackbar.bg_light,
    -      bgDark: theme.snackbar.bg_dark,
    -      position: theme.snackbar.position,
    -    })
    -  }
    -
    -  let noticeOutdate = 'undefined';
    -  if (theme.noticeOutdate && theme.noticeOutdate.enable) {
    -    noticeOutdate = JSON.stringify({
    -      limitDay: theme.noticeOutdate.limit_day,
    -      position: theme.noticeOutdate.position,
    -      messagePrev: theme.noticeOutdate.message_prev,
    -      messageNext: theme.noticeOutdate.message_next,
    -    })
    -  }
    -
    -  let highlight = 'undefined';
    -  if ((config.highlight && config.highlight.enable) || (config.prismjs && config.prismjs.enable)) {
    -    highlight = JSON.stringify({
    -      plugin: config.highlight.enable ? 'highlighjs' : 'prismjs',
    -      highlightCopy: theme.highlight_copy,
    -      highlightLang: theme.highlight_lang,
    -      highlightHeightLimit: theme.highlight_height_limit
    -    })
    -  }
    -
    -script.
    -  const GLOBAL_CONFIG = {
    -    root: '!{config.root}',
    -    algolia: !{algolia},
    -    localSearch: !{localSearch},
    -    translate: !{translate},
    -    noticeOutdate: !{noticeOutdate},
    -    highlight: !{highlight},
    -    copy: {
    -      success: '!{_p("copy.success")}',
    -      error: '!{_p("copy.error")}',
    -      noSupport: '!{_p("copy.noSupport")}'
    -    },
    -    relativeDate: {
    -      homepage: !{theme.post_meta.page.date_format === 'relative'},
    -      post: !{theme.post_meta.post.date_format === 'relative'}
    -    },
    -    runtime: '!{theme.runtimeshow.enable ? _p("aside.card_webinfo.runtime.unit") : ""}',
    -    dateSuffix: {
    -      just: '!{_p("date_suffix.just")}',
    -      min: '!{_p("date_suffix.min")}',
    -      hour: '!{_p("date_suffix.hour")}',
    -      day: '!{_p("date_suffix.day")}',
    -      month: '!{_p("date_suffix.month")}'
    -    },
    -    copyright: !{copyright},
    -    lightbox: '!{ theme.medium_zoom ? "mediumZoom" : (theme.fancybox ? "fancybox" : "null" )}',
    -    Snackbar: !{Snackbar},
    -    infinitegrid: {
    -      js: '!{url_for(theme.asset.egjs_infinitegrid)}',
    -      buttonText: '!{_p("load_more")}'
    -    },
    -    isPhotoFigcaption: !{theme.photofigcaption},
    -    islazyload: !{theme.lazyload.enable},
    -    isAnchor: !{theme.anchor.auto_update || false},
    -    percent: {
    -      toc: !{theme.toc.scroll_percent},
    -      rightside: !{theme.rightside_scroll_percent},
    -    },
    -    autoDarkmode: !{theme.darkmode.enable && theme.darkmode.autoChangeMode === 1}
    -  }
    diff --git a/themes/butterfly/layout/includes/head/config_site.pug b/themes/butterfly/layout/includes/head/config_site.pug
    deleted file mode 100644
    index 94cbb51c..00000000
    --- a/themes/butterfly/layout/includes/head/config_site.pug
    +++ /dev/null
    @@ -1,30 +0,0 @@
    --
    -  const titleVal = pageTitle.replace(/'/ig,"\\'")
    -
    -  let isHighlightShrink
    -  if (theme.highlight_shrink == 'none') isHighlightShrink = 'undefined'
    -  else if (page.highlight_shrink === true || page.highlight_shrink === false) isHighlightShrink = page.highlight_shrink
    -  else isHighlightShrink = theme.highlight_shrink
    -
    -  var showToc = false
    -  if (theme.aside.enable && page.aside !== false) {
    -    let tocEnable = false
    -    if (is_post()) {
    -      if (theme.toc.post) tocEnable = true
    -    } else if (is_page()) {
    -      if (theme.toc.page) tocEnable = true
    -    }
    -    const pageToc = page.toc === true || page.toc === false ? page.toc : tocEnable
    -    showToc = pageToc && (toc(page.content) !== '' || page.encrypt == true )
    -  }
    --
    -
    -script#config-diff.
    -  var GLOBAL_CONFIG_SITE = {
    -    title: '!{titleVal}',
    -    isPost: !{is_post()},
    -    isHome: !{is_home()},
    -    isHighlightShrink: !{isHighlightShrink},
    -    isToc: !{showToc},
    -    postUpdate: '!{full_date(page.updated)}'
    -  }
    diff --git a/themes/butterfly/layout/includes/head/google_adsense.pug b/themes/butterfly/layout/includes/head/google_adsense.pug
    deleted file mode 100644
    index 3ef1af99..00000000
    --- a/themes/butterfly/layout/includes/head/google_adsense.pug
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -if (theme.google_adsense && theme.google_adsense.enable)
    -  script(async src=theme.google_adsense.js)
    -
    -  if theme.google_adsense.auto_ads
    -    script.
    -      (adsbygoogle = window.adsbygoogle || []).push({
    -        google_ad_client: '!{theme.google_adsense.client}',
    -        enable_page_level_ads: '!{theme.google_adsense.enable_page_level_ads}'
    -      });
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/head/noscript.pug b/themes/butterfly/layout/includes/head/noscript.pug
    deleted file mode 100644
    index cc3befa6..00000000
    --- a/themes/butterfly/layout/includes/head/noscript.pug
    +++ /dev/null
    @@ -1,14 +0,0 @@
    -noscript. 
    -  <style type="text/css">
    -    #nav {
    -      opacity: 1
    -    }
    -    .justified-gallery img {
    -      opacity: 1
    -    }
    -
    -    #recent-posts time,
    -    #post-meta time {
    -      display: inline !important
    -    }
    -  </style>
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/head/preconnect.pug b/themes/butterfly/layout/includes/head/preconnect.pug
    deleted file mode 100644
    index f8af3809..00000000
    --- a/themes/butterfly/layout/includes/head/preconnect.pug
    +++ /dev/null
    @@ -1,35 +0,0 @@
    --
    -  const { internal_provider, third_party_provider, custom_format } = theme.CDN
    -  const providers = {
    -    'jsdelivr': '//cdn.jsdelivr.net',
    -    'cdnjs': '//cdnjs.cloudflare.com',
    -    'unpkg': '//unpkg.com',
    -    'custom': custom_format && custom_format.match(/^((https?:)?(\/\/[^/]+)|([^/]+))(\/|$)/)[1]
    -  }
    --
    -
    -if internal_provider === third_party_provider && internal_provider !== 'local'
    -  link(rel="preconnect" href=providers[internal_provider])
    -else 
    -  if internal_provider !== 'local'
    -    link(rel="preconnect" href=providers[internal_provider])
    -  if third_party_provider !== 'local'
    -  link(rel="preconnect" href=providers[third_party_provider])
    -
    -if theme.google_analytics
    -  link(rel="preconnect" href="//www.google-analytics.com" crossorigin='')
    -
    -if theme.baidu_analytics
    -  link(rel="preconnect" href="//hm.baidu.com")
    -
    -if theme.cloudflare_analytics
    -  link(rel="preconnect" href="//static.cloudflareinsights.com")
    -
    -if theme.microsoft_clarity
    -  link(rel="preconnect" href="//www.clarity.ms")
    -
    -if theme.blog_title_font && theme.blog_title_font.font_link && theme.blog_title_font.font_link.indexOf('//fonts.googleapis.com') != -1
    -  link(rel="preconnect" href="//fonts.googleapis.com" crossorigin='')
    -
    -if !theme.asset.busuanzi && (theme.busuanzi.site_uv || theme.busuanzi.site_pv || theme.busuanzi.page_pv)
    -  link(rel="preconnect" href="//busuanzi.ibruce.info")
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/head/pwa.pug b/themes/butterfly/layout/includes/head/pwa.pug
    deleted file mode 100644
    index e9152f2e..00000000
    --- a/themes/butterfly/layout/includes/head/pwa.pug
    +++ /dev/null
    @@ -1,11 +0,0 @@
    -link(rel="manifest" href=url_for(theme.pwa.manifest))
    -if(theme.pwa.theme_color) 
    -  meta(name="msapplication-TileColor" content=theme.pwa.theme_color)
    -if(theme.pwa.apple_touch_icon) 
    -  link(rel="apple-touch-icon" sizes="180x180" href=url_for(theme.pwa.apple_touch_icon))
    -if(theme.pwa.favicon_32_32) 
    -  link(rel="icon" type="image/png" sizes="32x32" href=url_for(theme.pwa.favicon_32_32))
    -if(theme.pwa.favicon_16_16)
    -  link(rel="icon" type="image/png" sizes="16x16" href=url_for(theme.pwa.favicon_16_16))
    -if(theme.pwa.mask_icon)
    -  link(rel="mask-icon" href=url_for(theme.pwa.mask_icon) color="#5bbad5")
    diff --git a/themes/butterfly/layout/includes/head/site_verification.pug b/themes/butterfly/layout/includes/head/site_verification.pug
    deleted file mode 100644
    index 89476449..00000000
    --- a/themes/butterfly/layout/includes/head/site_verification.pug
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -if theme.site_verification
    -  each item in theme.site_verification
    -    meta(name=item.name content=item.content)
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/header/index.pug b/themes/butterfly/layout/includes/header/index.pug
    deleted file mode 100644
    index 33e01dbc..00000000
    --- a/themes/butterfly/layout/includes/header/index.pug
    +++ /dev/null
    @@ -1,52 +0,0 @@
    -if !theme.disable_top_img && page.top_img !== false
    -  if is_post()
    -    - var top_img = page.top_img || page.cover || theme.default_top_img
    -  else if is_page()
    -    - var top_img = page.top_img || theme.default_top_img
    -  else if is_tag()
    -    - var top_img = theme.tag_per_img && theme.tag_per_img[page.tag] 
    -    - top_img = top_img ? top_img : (theme.tag_img !== false ? theme.tag_img || theme.default_top_img : false)
    -  else if is_category()
    -    - var top_img = theme.category_per_img && theme.category_per_img[page.category]
    -    - top_img = top_img ? top_img : (theme.category_img !== false ? theme.category_img || theme.default_top_img : false)
    -  else if is_home()
    -    - var top_img = theme.index_img !== false ? theme.index_img || theme.default_top_img : false
    -  else if is_archive()
    -    - var top_img = theme.archive_img !== false ? theme.archive_img || theme.default_top_img : false
    -  else
    -    - var top_img = page.top_img || theme.default_top_img
    -
    -  if top_img !== false
    -    - var imgSource = top_img && isImgOrUrl(top_img) ? `background-image: url('${url_for(top_img)}')` : `background: ${top_img}`
    -    - var bg_img = top_img ? imgSource : ''
    -    - var site_title = page.title || page.tag || page.category || config.title
    -    - var isHomeClass = is_home() ? 'full_page' : 'not-home-page'
    -    - is_post() ? isHomeClass = 'post-bg' : isHomeClass
    -  else
    -    - var isHomeClass = 'not-top-img'
    -else
    -  - var top_img = false
    -  - var isHomeClass = 'not-top-img'
    -
    -- const isFixedClass = theme.nav.fixed ? ' fixed' : ''
    -
    -header#page-header(class=`${isHomeClass+isFixedClass}` style=bg_img)
    -  !=partial('includes/header/nav', {}, {cache: true})
    -  if top_img !== false
    -    if is_post()
    -      include ./post-info.pug
    -    else if is_home() 
    -      #site-info
    -        h1#site-title=site_title
    -        if theme.subtitle.enable
    -          - var loadSubJs = true
    -          #site-subtitle
    -            span#subtitle
    -        if(theme.social)
    -          #site_social_icons
    -            !=partial('includes/header/social', {}, {cache: true})
    -      #scroll-down
    -        i.fas.fa-angle-down.scroll-down-effects
    -    else
    -      #page-site-info
    -        h1#site-title=site_title
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/header/menu_item.pug b/themes/butterfly/layout/includes/header/menu_item.pug
    deleted file mode 100644
    index d172db74..00000000
    --- a/themes/butterfly/layout/includes/header/menu_item.pug
    +++ /dev/null
    @@ -1,27 +0,0 @@
    -if theme.menu
    -  .menus_items
    -    each value, label in theme.menu
    -      if typeof value !== 'object'
    -        .menus_item
    -          - const valueArray = value.split('||')
    -          a.site-page(href=url_for(trim(valueArray[0])))
    -            if valueArray[1]
    -              i.fa-fw(class=trim(valueArray[1]))
    -            span=' '+label
    -      else
    -        .menus_item
    -          - const labelArray = label.split('||')
    -          - const hideClass = labelArray[2] && trim(labelArray[2]) === 'hide' ? 'hide' : ''
    -          a.site-page.group(class=`${hideClass}` href='javascript:void(0);')
    -            if labelArray[1]
    -              i.fa-fw(class=trim(labelArray[1]))
    -            span=' '+ trim(labelArray[0])
    -            i.fas.fa-chevron-down
    -          ul.menus_item_child
    -            each val,lab in value 
    -              - const valArray = val.split('||')
    -              li
    -                a.site-page.child(href=url_for(trim(valArray[0])))
    -                  if valArray[1]
    -                    i.fa-fw(class=trim(valArray[1]))
    -                  span=' '+ lab
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/header/nav.pug b/themes/butterfly/layout/includes/header/nav.pug
    deleted file mode 100644
    index f6376ca9..00000000
    --- a/themes/butterfly/layout/includes/header/nav.pug
    +++ /dev/null
    @@ -1,21 +0,0 @@
    -nav#nav
    -  span#blog-info
    -    a(href=url_for('/') title=config.title)
    -      if theme.nav.logo
    -        img.site-icon(src=url_for(theme.nav.logo))
    -      if theme.nav.display_title
    -        span.site-name=config.title
    -    
    -  #menus
    -    if (theme.algolia_search.enable || theme.local_search.enable || theme.docsearch.enable)
    -      #search-button
    -        a.site-page.social-icon.search(href="javascript:void(0);")
    -          i.fas.fa-search.fa-fw
    -          span=' '+_p('search.title')
    -    !=partial('includes/header/menu_item', {}, {cache: true})
    -
    -    #toggle-menu
    -      a.site-page(href="javascript:void(0);")
    -        i.fas.fa-bars.fa-fw
    -
    -
    diff --git a/themes/butterfly/layout/includes/header/post-info.pug b/themes/butterfly/layout/includes/header/post-info.pug
    deleted file mode 100644
    index def23123..00000000
    --- a/themes/butterfly/layout/includes/header/post-info.pug
    +++ /dev/null
    @@ -1,144 +0,0 @@
    -- let comments = theme.comments
    -#post-info
    -  h1.post-title= page.title || _p('no_title')
    -    if theme.post_edit.enable
    -      a.post-edit-link(href=theme.post_edit.url + page.source title=_p('post.edit') target="_blank")
    -        i.fas.fa-pencil-alt
    -        
    -  #post-meta
    -    .meta-firstline
    -      if (theme.post_meta.post.date_type)
    -        span.post-meta-date
    -          if (theme.post_meta.post.date_type === 'both')
    -            i.far.fa-calendar-alt.fa-fw.post-meta-icon
    -            span.post-meta-label= _p('post.created')
    -            time.post-meta-date-created(datetime=date_xml(page.date) title=_p('post.created') + ' ' + full_date(page.date))=date(page.date, config.date_format)
    -            span.post-meta-separator |
    -            i.fas.fa-history.fa-fw.post-meta-icon
    -            span.post-meta-label= _p('post.updated')
    -            time.post-meta-date-updated(datetime=date_xml(page.updated) title=_p('post.updated') + ' ' + full_date(page.updated))=date(page.updated, config.date_format)
    -          else
    -            - let data_type_update = theme.post_meta.post.date_type === 'updated'
    -            - let date_type = data_type_update ? 'updated' : 'date'
    -            - let date_icon = data_type_update ? 'fas fa-history' :'far fa-calendar-alt'
    -            - let date_title = data_type_update ? _p('post.updated') : _p('post.created')
    -            i.fa-fw.post-meta-icon(class=date_icon)
    -            span.post-meta-label= date_title
    -            time(datetime=date_xml(page[date_type]) title=date_title + ' ' + full_date(page[date_type]))=date(page[date_type], config.date_format)
    -      if (theme.post_meta.post.categories && page.categories.data.length > 0)
    -        span.post-meta-categories
    -          if (theme.post_meta.post.date_type)
    -            span.post-meta-separator |
    -
    -          each item, index in page.categories.data
    -            i.fas.fa-inbox.fa-fw.post-meta-icon
    -            a(href=url_for(item.path)).post-meta-categories #[=item.name]
    -            if (index < page.categories.data.length - 1)
    -              i.fas.fa-angle-right.post-meta-separator
    -
    -    .meta-secondline
    -      - let postWordcount = theme.wordcount.enable && (theme.wordcount.post_wordcount || theme.wordcount.min2read)
    -      if (postWordcount)
    -        span.post-meta-separator |
    -        span.post-meta-wordcount
    -          if theme.wordcount.post_wordcount
    -            i.far.fa-file-word.fa-fw.post-meta-icon
    -            span.post-meta-label= _p('post.wordcount') + ':'
    -            span.word-count= wordcount(page.content)
    -            if theme.wordcount.min2read
    -              span.post-meta-separator |
    -          if theme.wordcount.min2read
    -            i.far.fa-clock.fa-fw.post-meta-icon
    -            span.post-meta-label= _p('post.min2read') + ':'
    -            span= min2read(page.content, {cn: 350, en: 160}) + _p('post.min2read_unit')
    -    
    -      //- for pv and count
    -      mixin pvBlock(parent_id,parent_class,parent_title)
    -        span.post-meta-separator |
    -        span(class=parent_class id=parent_id data-flag-title=page.title)
    -          i.far.fa-eye.fa-fw.post-meta-icon
    -          span.post-meta-label=_p('post.page_pv') + ':'
    -          if block
    -            block
    -
    -      - const commentUse = comments.use
    -      if page.comments !== false && commentUse && !comments.lazyload
    -        if commentUse[0] === 'Valine' && theme.valine.visitor
    -          +pvBlock(url_for(page.path),'leancloud_visitors',page.title)
    -            span.leancloud-visitors-count
    -              i.fa-solid.fa-spinner.fa-spin
    -        else if commentUse[0] === 'Waline' && theme.waline.pageview
    -          +pvBlock('','','')
    -            span.waline-pageview-count(data-path=url_for(page.path))
    -              i.fa-solid.fa-spinner.fa-spin
    -        else if commentUse[0] === 'Twikoo' && theme.twikoo.visitor
    -          +pvBlock('','','')
    -            span#twikoo_visitors
    -              i.fa-solid.fa-spinner.fa-spin
    -        else if commentUse[0] === 'Artalk' && theme.artalk.visitor
    -          +pvBlock('','','')
    -            span#ArtalkPV
    -              i.fa-solid.fa-spinner.fa-spin
    -        else if theme.busuanzi.page_pv
    -          +pvBlock('','post-meta-pv-cv','')
    -            span#busuanzi_value_page_pv
    -              i.fa-solid.fa-spinner.fa-spin
    -      else if theme.busuanzi.page_pv
    -        +pvBlock('','post-meta-pv-cv','')
    -          span#busuanzi_value_page_pv
    -            i.fa-solid.fa-spinner.fa-spin
    -
    -      if comments.count && !comments.lazyload && page.comments !== false && comments.use
    -        - var whichCount = comments.use[0]
    -
    -        mixin countBlock
    -          span.post-meta-separator |
    -          span.post-meta-commentcount
    -            i.far.fa-comments.fa-fw.post-meta-icon
    -            span.post-meta-label= _p('post.comments') + ':'
    -            if block
    -              block
    -        
    -        case whichCount
    -          when 'Disqus'
    -            +countBlock
    -              a.disqus-comment-count(href=full_url_for(page.path) + '#post-comment')
    -                i.fa-solid.fa-spinner.fa-spin
    -          when 'Disqusjs'
    -            +countBlock
    -              a.disqusjs-comment-count(href=full_url_for(page.path) + '#post-comment')
    -                i.fa-solid.fa-spinner.fa-spin
    -          when 'Valine'
    -            +countBlock
    -              a(href=url_for(page.path) + '#post-comment' itemprop="discussionUrl")
    -                span.valine-comment-count(data-xid=url_for(page.path) itemprop="commentCount")
    -                  i.fa-solid.fa-spinner.fa-spin
    -          when 'Waline'
    -            +countBlock
    -              a(href=url_for(page.path) + '#post-comment')
    -                span.waline-comment-count(data-path=url_for(page.path))
    -                  i.fa-solid.fa-spinner.fa-spin
    -          when 'Gitalk'
    -            +countBlock
    -              a(href=url_for(page.path) + '#post-comment')
    -                span.gitalk-comment-count
    -                  i.fa-solid.fa-spinner.fa-spin
    -          when 'Twikoo'
    -            +countBlock
    -              a(href=url_for(page.path) + '#post-comment')
    -                span#twikoo-count
    -                  i.fa-solid.fa-spinner.fa-spin
    -          when 'Facebook Comments'
    -            +countBlock
    -              a(href=url_for(page.path) + '#post-comment')
    -                span.fb-comments-count(data-href=urlNoIndex())
    -          when 'Remark42'
    -            +countBlock
    -              a(href=url_for(page.path) + '#post-comment')
    -                span.remark42__counter(data-url=urlNoIndex())
    -                  i.fa-solid.fa-spinner.fa-spin
    -          when 'Artalk'
    -            +countBlock
    -              a(href=url_for(page.path) + '#post-comment')
    -                span.artalk-count
    -                  i.fa-solid.fa-spinner.fa-spin
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/header/social.pug b/themes/butterfly/layout/includes/header/social.pug
    deleted file mode 100644
    index b7b586e7..00000000
    --- a/themes/butterfly/layout/includes/header/social.pug
    +++ /dev/null
    @@ -1,4 +0,0 @@
    -each url, icon in theme.social
    -  a.social-icon(href=url_for(trim(url.split('||')[0])) target="_blank" 
    -  title=url.split('||')[1] === undefined ? '' : trim(url.split('||')[1]))
    -    i(class=icon style=url.split('||')[2] === undefined ? '' : `color: ${trim(url.split('||')[2]).replace(/[\'\"]/g, '')};`)
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/layout.pug b/themes/butterfly/layout/includes/layout.pug
    deleted file mode 100644
    index dde47c52..00000000
    --- a/themes/butterfly/layout/includes/layout.pug
    +++ /dev/null
    @@ -1,47 +0,0 @@
    -- var htmlClassHideAside = theme.aside.enable && theme.aside.hide ? 'hide-aside' : ''
    -- page.aside = is_archive() ? theme.aside.display.archive: is_category() ? theme.aside.display.category : is_tag() ? theme.aside.display.tag : page.aside
    -- var hideAside = !theme.aside.enable || page.aside === false ? 'hide-aside' : ''
    -- var pageType = is_post() ? 'post' : 'page'
    -
    -doctype html
    -html(lang=config.language data-theme=theme.display_mode class=htmlClassHideAside)
    -  head
    -    include ./head.pug
    -  body
    -    if theme.preloader.enable
    -      !=partial('includes/loading/index', {}, {cache: true})
    -
    -    if theme.background
    -      #web_bg
    -      
    -    !=partial('includes/sidebar', {}, {cache: true})
    -
    -    if page.type !== '404'
    -      #body-wrap(class=pageType)
    -        include ./header/index.pug
    -
    -        main#content-inner.layout(class=hideAside)
    -          if body
    -            div!= body
    -          else
    -            block content
    -            if theme.aside.enable && page.aside !== false
    -              include widget/index.pug
    -
    -        - var footerBg = theme.footer_bg
    -        if (footerBg)
    -          if (footerBg === true)
    -            - var footer_bg = bg_img
    -          else
    -            - var footer_bg = isImgOrUrl(theme.footer_bg) ? `background-image: url('${url_for(footerBg)}')` : `background: ${footerBg}`
    -        else
    -          - var footer_bg = ''
    -
    -        footer#footer(style=footer_bg)
    -          !=partial('includes/footer', {}, {cache: true})
    -
    -    else
    -      include ./404.pug
    -
    -    include ./rightside.pug
    -    include ./additional-js.pug
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/loading/fullpage-loading.pug b/themes/butterfly/layout/includes/loading/fullpage-loading.pug
    deleted file mode 100644
    index 4a2c8bf5..00000000
    --- a/themes/butterfly/layout/includes/loading/fullpage-loading.pug
    +++ /dev/null
    @@ -1,33 +0,0 @@
    -#loading-box
    -  .loading-left-bg
    -  .loading-right-bg
    -  .spinner-box
    -    .configure-border-1
    -      .configure-core
    -    .configure-border-2
    -      .configure-core
    -    .loading-word= _p('loading')
    -
    -script.
    -  (()=>{
    -    const $loadingBox = document.getElementById('loading-box')
    -    const $body = document.body
    -    const preloader = {
    -      endLoading: () => {
    -        $body.style.overflow = ''
    -        $loadingBox.classList.add('loaded')
    -      },
    -      initLoading: () => {
    -        $body.style.overflow = 'hidden'
    -        $loadingBox.classList.remove('loaded')
    -      }
    -    }
    -
    -    preloader.initLoading()
    -    window.addEventListener('load',() => { preloader.endLoading() })
    -
    -    if (!{theme.pjax && theme.pjax.enable}) {
    -      document.addEventListener('pjax:send', () => { preloader.initLoading() })
    -      document.addEventListener('pjax:complete', () => { preloader.endLoading() })
    -    }
    -  })()
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/loading/index.pug b/themes/butterfly/layout/includes/loading/index.pug
    deleted file mode 100644
    index 663fe501..00000000
    --- a/themes/butterfly/layout/includes/loading/index.pug
    +++ /dev/null
    @@ -1,4 +0,0 @@
    -if theme.preloader.source === 1
    -  include ./fullpage-loading.pug
    -else
    -  include ./pace.pug
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/loading/pace.pug b/themes/butterfly/layout/includes/loading/pace.pug
    deleted file mode 100644
    index 7abd6178..00000000
    --- a/themes/butterfly/layout/includes/loading/pace.pug
    +++ /dev/null
    @@ -1,11 +0,0 @@
    -script.
    -  window.paceOptions = {
    -    restartOnPushState: false
    -  }
    -
    -  document.addEventListener('pjax:send', () => {
    -    Pace.restart()
    -  })
    -
    -link(rel="stylesheet", href=url_for(theme.preloader.pace_css_url || theme.asset.pace_default_css))
    -script(src=url_for(theme.asset.pace_js))
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/mixins/article-sort.pug b/themes/butterfly/layout/includes/mixins/article-sort.pug
    deleted file mode 100644
    index 3eaf0383..00000000
    --- a/themes/butterfly/layout/includes/mixins/article-sort.pug
    +++ /dev/null
    @@ -1,23 +0,0 @@
    -mixin articleSort(posts)
    -  .article-sort
    -    - var year
    -    - posts.each(function (article) {
    -      - let tempYear = date(article.date, 'YYYY')
    -      - let no_cover = article.cover === false || !theme.cover.archives_enable ? 'no-article-cover' : ''
    -      - let title = article.title || _p('no_title')
    -      if tempYear !== year
    -        - year = tempYear
    -        .article-sort-item.year= year
    -      .article-sort-item(class=no_cover)
    -        if article.cover && theme.cover.archives_enable
    -          a.article-sort-item-img(href=url_for(article.path) title=title)
    -            if article.cover_type === 'img'
    -              img(src=url_for(article.cover) alt=title onerror=`this.onerror=null;this.src='${url_for(theme.error_img.post_page)}'`)
    -            else
    -              div(style=`background: ${article.cover}`)
    -        .article-sort-item-info
    -          .article-sort-item-time
    -            i.far.fa-calendar-alt
    -            time.post-meta-date-created(datetime=date_xml(article.date) title=_p('post.created') + ' ' + full_date(article.date))= date(article.date, config.date_format)
    -          a.article-sort-item-title(href=url_for(article.path) title=title)= title
    -    - })
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/mixins/post-ui.pug b/themes/butterfly/layout/includes/mixins/post-ui.pug
    deleted file mode 100644
    index 5621b6db..00000000
    --- a/themes/butterfly/layout/includes/mixins/post-ui.pug
    +++ /dev/null
    @@ -1,129 +0,0 @@
    -mixin postUI(posts)
    -  each article , index in page.posts.data
    -    .recent-post-item
    -      -
    -        let link = article.link || article.path
    -        let title = article.title || _p('no_title')
    -        const position = theme.cover.position
    -        let leftOrRight = position === 'both'
    -          ? index%2 == 0 ? 'left' : 'right'
    -          : position === 'left' ? 'left' : 'right'
    -        let post_cover = article.cover
    -        let no_cover = article.cover === false || !theme.cover.index_enable ? 'no-cover' : ''
    -      -
    -      if post_cover && theme.cover.index_enable
    -        .post_cover(class=leftOrRight)
    -          a(href=url_for(link) title=title)
    -            if article.cover_type === 'img'
    -              img.post-bg(src=url_for(post_cover) onerror=`this.onerror=null;this.src='${url_for(theme.error_img.post_page)}'` alt=title)
    -            else
    -              div.post-bg(style=`background: ${post_cover}`)
    -      .recent-post-info(class=no_cover)
    -        a.article-title(href=url_for(link) title=title)
    -          if (is_home() && (article.top || article.sticky > 0))
    -            i.fas.fa-thumbtack.sticky
    -          = title
    -        .article-meta-wrap
    -          if (theme.post_meta.page.date_type)
    -            span.post-meta-date
    -              if (theme.post_meta.page.date_type === 'both')
    -                i.far.fa-calendar-alt
    -                span.article-meta-label=_p('post.created')
    -                time.post-meta-date-created(datetime=date_xml(article.date) title=_p('post.created') + ' ' + full_date(article.date))=date(article.date, config.date_format)
    -                span.article-meta-separator |
    -                i.fas.fa-history
    -                span.article-meta-label=_p('post.updated')
    -                time.post-meta-date-updated(datetime=date_xml(article.updated) title=_p('post.updated') + ' ' + full_date(article.updated))=date(article.updated, config.date_format)
    -              else
    -                - let data_type_updated = theme.post_meta.page.date_type === 'updated'
    -                - let date_type = data_type_updated ? 'updated' : 'date'
    -                - let date_icon = data_type_updated ? 'fas fa-history' :'far fa-calendar-alt'
    -                - let date_title = data_type_updated ? _p('post.updated') : _p('post.created')
    -                i(class=date_icon)
    -                span.article-meta-label=date_title
    -                time(datetime=date_xml(article[date_type]) title=date_title + ' ' + full_date(article[date_type]))=date(article[date_type], config.date_format)
    -          if (theme.post_meta.page.categories && article.categories.data.length > 0)
    -            span.article-meta
    -              span.article-meta-separator |
    -              i.fas.fa-inbox
    -              each item, index in article.categories.data
    -                a(href=url_for(item.path)).article-meta__categories #[=item.name]
    -                if (index < article.categories.data.length - 1)
    -                  i.fas.fa-angle-right.article-meta-link
    -          if (theme.post_meta.page.tags && article.tags.data.length > 0)
    -            span.article-meta.tags
    -              span.article-meta-separator |
    -              i.fas.fa-tag
    -              each item, index in article.tags.data
    -                a(href=url_for(item.path)).article-meta__tags #[=item.name]
    -                if (index < article.tags.data.length - 1)
    -                  span.article-meta-link #[='•']
    -          
    -          mixin countBlockInIndex
    -            - needLoadCountJs = true
    -            span.article-meta
    -              span.article-meta-separator |
    -              i.fas.fa-comments
    -              if block
    -                block
    -              span.article-meta-label= ' ' + _p('card_post_count')
    -          
    -          if theme.comments.card_post_count && theme.comments.use
    -            case theme.comments.use[0]
    -              when 'Disqus'
    -              when 'Disqusjs'
    -                +countBlockInIndex
    -                  a.disqus-count(href=full_url_for(link) + '#post-comment')
    -                    i.fa-solid.fa-spinner.fa-spin
    -              when 'Valine'
    -                +countBlockInIndex
    -                  a(href=url_for(link) + '#post-comment')
    -                    span.valine-comment-count(data-xid=url_for(link))
    -                      i.fa-solid.fa-spinner.fa-spin
    -              when 'Waline'
    -                +countBlockInIndex
    -                  a(href=url_for(link) + '#post-comment')
    -                    span.waline-comment-count(data-path=url_for(link))
    -                      i.fa-solid.fa-spinner.fa-spin
    -              when 'Twikoo'
    -                +countBlockInIndex
    -                  a.twikoo-count(href=url_for(link) + '#post-comment')
    -                    i.fa-solid.fa-spinner.fa-spin
    -              when 'Facebook Comments'
    -                +countBlockInIndex
    -                  a(href=url_for(link) + '#post-comment')
    -                    span.fb-comments-count(data-href=urlNoIndex(article.permalink))
    -              when 'Remark42'
    -                +countBlockInIndex
    -                  a(href=url_for(link) + '#post-comment')
    -                    span.remark42__counter(data-url=urlNoIndex(article.permalink))
    -                      i.fa-solid.fa-spinner.fa-spin
    -              when 'Artalk'
    -                +countBlockInIndex
    -                  a(href=url_for(link) + '#post-comment')
    -                    span.artalk-count(data-page-key=url_for(link))
    -                      i.fa-solid.fa-spinner.fa-spin
    -
    -        //- Display the article introduction on homepage
    -        case theme.index_post_content.method
    -          when false
    -            - break
    -          when 1
    -            .content!= article.description
    -          when 2
    -            if article.description
    -              .content!= article.description
    -            else
    -              - const content = strip_html(article.content)
    -              - let expert = content.substring(0, theme.index_post_content.length) 
    -              - content.length > theme.index_post_content.length ? expert += ' ...' : ''
    -              .content!= expert
    -          default
    -            - const content = strip_html(article.content)
    -            - let expert = content.substring(0, theme.index_post_content.length) 
    -            - content.length > theme.index_post_content.length ? expert += ' ...' : ''
    -            .content!= expert
    -
    -    if theme.ad && theme.ad.index
    -      if (index + 1) % 3 == 0
    -        .recent-post-item.ads-wrap!=theme.ad.index
    diff --git a/themes/butterfly/layout/includes/page/categories.pug b/themes/butterfly/layout/includes/page/categories.pug
    deleted file mode 100644
    index 79153c8d..00000000
    --- a/themes/butterfly/layout/includes/page/categories.pug
    +++ /dev/null
    @@ -1 +0,0 @@
    -.category-lists!= list_categories()
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/page/default-page.pug b/themes/butterfly/layout/includes/page/default-page.pug
    deleted file mode 100644
    index e7057f73..00000000
    --- a/themes/butterfly/layout/includes/page/default-page.pug
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -#article-container
    -  != page.content
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/page/flink.pug b/themes/butterfly/layout/includes/page/flink.pug
    deleted file mode 100644
    index 10d3893a..00000000
    --- a/themes/butterfly/layout/includes/page/flink.pug
    +++ /dev/null
    @@ -1,82 +0,0 @@
    -#article-container
    -  .flink
    -    - let { content, random, flink_url } = page
    -    - let pageContent = content
    -
    -    if flink_url || random
    -      - const linkData = flink_url ? false : site.data.link || false
    -      script.
    -        (()=>{
    -          const replaceSymbol = (str) => {
    -            return str.replace(/[\p{P}\p{S}]/gu, "-")
    -          }
    -
    -          let result = ""
    -          const add = (str) => {
    -            for(let i = 0; i < str.length; i++){
    -              const replaceClassName = replaceSymbol(str[i].class_name)
    -              const className = str[i].class_name ? `<h2 id="${replaceClassName}"><a href="#${replaceClassName}" class="headerlink" title="${str[i].class_name}"></a>${str[i].class_name}</h2>` : ""
    -              const classDesc = str[i].class_desc ? `<div class="flink-desc">${str[i].class_desc}</div>` : ""
    -
    -              let listResult = ""
    -              const lists = str[i].link_list
    -              if (!{random === true}) {
    -                lists.sort(() => Math.random() - 0.5)
    -              }
    -              for(let j = 0; j < lists.length; j++){
    -                listResult += `
    -                  <div class="flink-list-item">
    -                    <a href="${lists[j].link}" title="${lists[j].name}" target="_blank">
    -                      <div class="flink-item-icon">
    -                        <img class="no-lightbox" src="${lists[j].avatar}" onerror='this.onerror=null;this.src="!{url_for(theme.error_img.flink)}"' alt="${lists[j].name}" />
    -                      </div>
    -                      <div class="flink-item-name">${lists[j].name}</div> 
    -                      <div class="flink-item-desc" title="${lists[j].descr}">${lists[j].descr}</div>
    -                    </a>
    -                  </div>`
    -              }
    -
    -              result += `${className}${classDesc} <div class="flink-list">${listResult}</div>`
    -            }
    -
    -            document.querySelector(".flink").insertAdjacentHTML("afterbegin", result)
    -            window.lazyLoadInstance && window.lazyLoadInstance.update()
    -          }
    -
    -          const linkData = !{JSON.stringify(linkData)}
    -          if (!{Boolean(flink_url)}) {
    -            fetch("!{url_for(flink_url)}")
    -              .then(response => response.json())
    -              .then(add)
    -          } else if (linkData) {
    -            add(linkData)
    -          }
    -        })()
    -
    -    else
    -      if site.data.link
    -        - let result = ""
    -        each i in site.data.link
    -          - let className = i.class_name ? markdown(`## ${i.class_name}`) : ""
    -          - let classDesc = i.class_desc ? `<div class="flink-desc">${i.class_desc}</div>` : ""
    -
    -          - let listResult = ""
    -
    -          each j in i.link_list
    -            - 
    -              listResult += `
    -                <div class="flink-list-item">
    -                  <a href="${j.link}" title="${j.name}" target="_blank">
    -                    <div class="flink-item-icon">
    -                      <img class="no-lightbox" src="${j.avatar}" onerror='this.onerror=null;this.src="${url_for(theme.error_img.flink)}"' alt="${j.name}" />
    -                    </div>
    -                    <div class="flink-item-name">${j.name}</div> 
    -                    <div class="flink-item-desc" title="${j.descr}">${j.descr}</div>
    -                  </a>
    -                </div>`
    -            -
    -
    -          - result += `${className}${classDesc} <div class="flink-list">${listResult}</div>`
    -
    -        - pageContent = result + pageContent
    -    != pageContent
    diff --git a/themes/butterfly/layout/includes/page/tags.pug b/themes/butterfly/layout/includes/page/tags.pug
    deleted file mode 100644
    index ed7d22c1..00000000
    --- a/themes/butterfly/layout/includes/page/tags.pug
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -.tag-cloud-list.is-center
    -  !=cloudTags({source: site.tags, orderby: page.orderby || 'random', order: page.order || 1, minfontsize: 1.2, maxfontsize: 2.1, limit: 0, unit: 'em'})
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/pagination.pug b/themes/butterfly/layout/includes/pagination.pug
    deleted file mode 100644
    index 2af0e00b..00000000
    --- a/themes/butterfly/layout/includes/pagination.pug
    +++ /dev/null
    @@ -1,41 +0,0 @@
    --
    -  var options = {
    -    prev_text: '<i class="fas fa-chevron-left fa-fw"></i>',
    -    next_text: '<i class="fas fa-chevron-right fa-fw"></i>',
    -    mid_size: 1,
    -    escape: false
    -  }
    -
    -if is_post()
    -  - let prev = theme.post_pagination === 1 ? page.prev : page.next
    -  - let next = theme.post_pagination === 1 ? page.next : page.prev
    -  nav#pagination.pagination-post
    -    if(prev)
    -      - var hasPageNext = next ? 'pull-left' : 'pull-full'
    -      .prev-post(class=hasPageNext)
    -        a(href=url_for(prev.path) title=prev.title)
    -          if prev.cover_type === 'img'
    -            img.cover(src=url_for(prev.cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` alt='cover of previous post')
    -          else
    -            .cover(style=`background: ${prev.cover || 'var(--default-bg-color)'}`)
    -          .pagination-info
    -            .label=_p('pagination.prev')
    -            .prev_info=prev.title
    -          
    -    if(next)
    -      - var hasPagePrev = prev ? 'pull-right' : 'pull-full'
    -      .next-post(class=hasPagePrev)
    -        a(href=url_for(next.path) title=next.title)
    -          if next.cover_type === 'img'
    -            img.cover(src=url_for(next.cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` alt='cover of next post')
    -          else
    -            .cover(style=`background: ${next.cover || 'var(--default-bg-color)'}`)
    -          .pagination-info
    -            .label=_p('pagination.next')
    -            .next_info=next.title
    -else
    -  nav#pagination
    -    .pagination
    -      if is_home()
    -        - options.format = 'page/%d/#content-inner'
    -      !=paginator(options)
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/post/post-copyright.pug b/themes/butterfly/layout/includes/post/post-copyright.pug
    deleted file mode 100644
    index e0b09df5..00000000
    --- a/themes/butterfly/layout/includes/post/post-copyright.pug
    +++ /dev/null
    @@ -1,23 +0,0 @@
    -if theme.post_copyright.enable && page.copyright !== false
    -  - let author = page.copyright_author || config.author
    -  - let authorHref = page.copyright_author_href || theme.post_copyright.author_href || config.url
    -  - let url = page.copyright_url || page.permalink
    -  - let info = page.copyright_info || _p('post.copyright.copyright_content', theme.post_copyright.license_url, theme.post_copyright.license, config.url, config.title)
    -  .post-copyright
    -    .post-copyright__author
    -      span.post-copyright-meta
    -        i.fas.fa-circle-user.fa-fw
    -        = _p('post.copyright.author') + ": "
    -      span.post-copyright-info
    -        a(href=authorHref)=author
    -    .post-copyright__type
    -      span.post-copyright-meta
    -        i.fas.fa-square-arrow-up-right.fa-fw
    -        = _p('post.copyright.link') + ": "
    -      span.post-copyright-info
    -        a(href=url_for(url))= theme.post_copyright.decode ? decodeURI(url) : url
    -    .post-copyright__notice
    -      span.post-copyright-meta
    -        i.fas.fa-circle-exclamation.fa-fw
    -        = _p('post.copyright.copyright_notice') + ": "
    -      span.post-copyright-info!= info
    diff --git a/themes/butterfly/layout/includes/post/reward.pug b/themes/butterfly/layout/includes/post/reward.pug
    deleted file mode 100644
    index fb559465..00000000
    --- a/themes/butterfly/layout/includes/post/reward.pug
    +++ /dev/null
    @@ -1,13 +0,0 @@
    -.post-reward
    -  .reward-button
    -    i.fas.fa-qrcode
    -    = theme.reward.text || _p('donate')
    -  .reward-main
    -    ul.reward-all
    -      each item in theme.reward.QR_code
    -        - var clickTo = item.link ? item.link : item.img
    -        li.reward-item
    -          a(href=url_for(clickTo) target='_blank')
    -            img.post-qr-code-img(src=url_for(item.img) alt=item.text)
    -          .post-qr-code-desc=item.text
    -
    diff --git a/themes/butterfly/layout/includes/rightside.pug b/themes/butterfly/layout/includes/rightside.pug
    deleted file mode 100644
    index 377813db..00000000
    --- a/themes/butterfly/layout/includes/rightside.pug
    +++ /dev/null
    @@ -1,61 +0,0 @@
    -- const { readmode, translate, darkmode, aside, chat_btn } = theme
    -mixin rightsideItem(array)
    -  each item in array
    -    case item
    -      when 'readmode'
    -        if is_post() && readmode
    -          button#readmode(type="button" title=_p('rightside.readmode_title'))
    -            i.fas.fa-book-open
    -      when 'translate'
    -        if translate.enable
    -          button#translateLink(type="button" title=_p('rightside.translate_title'))= translate.default
    -      when 'darkmode'
    -        if darkmode.enable && darkmode.button
    -          button#darkmode(type="button" title=_p('rightside.night_mode_title'))
    -            i.fas.fa-adjust
    -      when 'hideAside'
    -        if aside.enable && aside.button && page.aside !== false
    -          button#hide-aside-btn(type="button" title=_p('rightside.aside'))
    -            i.fas.fa-arrows-alt-h
    -      when 'toc'
    -        if showToc
    -          button#mobile-toc-button.close(type="button" title=_p("rightside.toc"))
    -            i.fas.fa-list-ul
    -      when 'chat'
    -        if chat_btn
    -          button#chat-btn(type="button" title=_p("rightside.chat"))
    -            i.fas.fa-sms
    -      when 'comment'
    -        if commentsJsLoad
    -          a#to_comment(href="#post-comment" title=_p("rightside.scroll_to_comment"))
    -            i.fas.fa-comments
    -
    -#rightside
    -  - const { enable, hide, show } = theme.rightside_item_order
    -  - const hideArray = enable ? hide && hide.split(',') : ['readmode','translate','darkmode','hideAside']
    -  - const showArray = enable ? show && show.split(',') : ['toc','chat','comment']
    -
    -  
    -  #rightside-config-hide
    -    if hideArray
    -      +rightsideItem(hideArray)
    -  #rightside-config-show
    -    if enable
    -      if hide
    -        button#rightside-config(type="button" title=_p("rightside.setting"))
    -          i.fas.fa-cog.fa-spin
    -    else
    -      if is_post()
    -        if (readmode || translate.enable || (darkmode.enable && darkmode.button))
    -          button#rightside-config(type="button" title=_p("rightside.setting"))
    -            i.fas.fa-cog.fa-spin
    -      else if translate.enable || (darkmode.enable && darkmode.button)
    -        button#rightside-config(type="button" title=_p("rightside.setting"))
    -          i.fas.fa-cog.fa-spin
    -
    -    if showArray
    -      +rightsideItem(showArray)
    -
    -    button#go-up(type="button" title=_p("rightside.back_to_top"))
    -      span.scroll-percent
    -      i.fas.fa-arrow-up
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/sidebar.pug b/themes/butterfly/layout/includes/sidebar.pug
    deleted file mode 100644
    index 66c67a9d..00000000
    --- a/themes/butterfly/layout/includes/sidebar.pug
    +++ /dev/null
    @@ -1,18 +0,0 @@
    -#sidebar
    -  #menu-mask
    -  #sidebar-menus
    -    .avatar-img.is-center
    -      img(src=url_for(theme.avatar.img) onerror=`onerror=null;src='${theme.error_img.flink}'` alt="avatar")
    -    .sidebar-site-data.site-data.is-center
    -      a(href=url_for(config.archive_dir) + '/')
    -        .headline= _p('aside.articles') 
    -        .length-num= site.posts.length
    -      a(href=url_for(config.tag_dir) + '/' )
    -        .headline= _p('aside.tags')
    -        .length-num= site.tags.length
    -      a(href=url_for(config.category_dir) + '/')
    -        .headline= _p('aside.categories') 
    -        .length-num= site.categories.length
    -
    -    hr.custom-hr
    -    !=partial('includes/header/menu_item', {}, {cache: true})
    diff --git a/themes/butterfly/layout/includes/third-party/abcjs/abcjs.pug b/themes/butterfly/layout/includes/third-party/abcjs/abcjs.pug
    deleted file mode 100644
    index 79f86c4f..00000000
    --- a/themes/butterfly/layout/includes/third-party/abcjs/abcjs.pug
    +++ /dev/null
    @@ -1,15 +0,0 @@
    -script.
    -  (() => {
    -    const abcjsInit = () => {
    -      const abcjsFn = () => {
    -        document.querySelectorAll(".abc-music-sheet").forEach(ele => {
    -          ABCJS.renderAbc(ele, ele.innerHTML, {responsive: 'resize'})
    -        })
    -      }
    -      
    -      typeof ABCJS === 'object' ? abcjsFn()
    -        : getScript('!{url_for(theme.asset.abcjs_basic_js)}').then(abcjsFn)
    -    }
    -
    -    window.pjax ? abcjsInit() : window.addEventListener('load', abcjsInit)
    -  })()
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/abcjs/index.pug b/themes/butterfly/layout/includes/third-party/abcjs/index.pug
    deleted file mode 100644
    index 1112626e..00000000
    --- a/themes/butterfly/layout/includes/third-party/abcjs/index.pug
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -if theme.abcjs && theme.abcjs.enable
    -  if theme.abcjs.per_page
    -    if is_post() || is_page()
    -      include ./abcjs.pug
    -  else if page.abcjs
    -    include ./abcjs.pug
    diff --git a/themes/butterfly/layout/includes/third-party/aplayer.pug b/themes/butterfly/layout/includes/third-party/aplayer.pug
    deleted file mode 100644
    index c439c4cd..00000000
    --- a/themes/butterfly/layout/includes/third-party/aplayer.pug
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -link(rel='stylesheet' href=url_for(theme.asset.aplayer_css) media="print" onload="this.media='all'")
    -script(src=url_for(theme.asset.aplayer_js))
    -script(src=url_for(theme.asset.meting_js))
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/card-post-count/artalk.pug b/themes/butterfly/layout/includes/third-party/card-post-count/artalk.pug
    deleted file mode 100644
    index 9e9aaed4..00000000
    --- a/themes/butterfly/layout/includes/third-party/card-post-count/artalk.pug
    +++ /dev/null
    @@ -1,35 +0,0 @@
    -- const { server, site } = theme.artalk
    -
    -script.
    -  (() => {
    -    const getArtalkCount = async() => {
    -      try {
    -        const eleGroup = document.querySelectorAll('#recent-posts .artalk-count')
    -        const keyArray = Array.from(eleGroup).map(i => i.getAttribute('data-page-key'))
    -
    -        const headerList = {
    -          method: 'POST',
    -          headers: {
    -            'Content-Type': 'application/x-www-form-urlencoded',
    -            'Origin': window.location.origin
    -          },
    -          body: new URLSearchParams({
    -            'site_name': '!{site}',
    -            'type':'page_comment',
    -            'page_keys': keyArray
    -          })
    -        }
    -
    -        const res = await fetch('!{server}/api/stat', headerList)
    -        const result = await res.json()
    -
    -        keyArray.forEach((key, index) => {
    -          eleGroup[index].textContent = result.data[key] || 0
    -        })
    -      } catch (err) {
    -        console.error(err)
    -      }
    -    }
    -
    -    window.pjax ? getArtalkCount() : window.addEventListener('load', getArtalkCount)
    -  })()
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/card-post-count/disqus.pug b/themes/butterfly/layout/includes/third-party/card-post-count/disqus.pug
    deleted file mode 100644
    index 92a2d5bc..00000000
    --- a/themes/butterfly/layout/includes/third-party/card-post-count/disqus.pug
    +++ /dev/null
    @@ -1,25 +0,0 @@
    -- const { shortname, apikey } = theme.disqus
    -script.
    -  (() => {
    -    const getCount = async () => {
    -      try {
    -        const eleGroup = document.querySelectorAll('#recent-posts .disqus-count')
    -        const cleanedLinks = Array.from(eleGroup).map(i => `thread:link=${i.href.replace(/#post-comment$/, '')}`);
    -
    -        const res = await fetch(`https://disqus.com/api/3.0/threads/set.json?forum=!{shortname}&api_key=!{apikey}&${cleanedLinks.join('&')}`,{
    -          method: 'GET'
    -        })
    -        const result = await res.json()
    -
    -        eleGroup.forEach(i => {
    -          const cleanedLink = i.href.replace(/#post-comment$/, '')
    -          const urlData = result.response.find(data => data.link === cleanedLink) || { posts: 0 }
    -          i.textContent = urlData.posts
    -        })
    -      } catch (err) {
    -        console.error(err)
    -      }
    -    }
    -
    -    window.pjax ? getCount() : window.addEventListener('load', getCount)
    -  })()
    diff --git a/themes/butterfly/layout/includes/third-party/card-post-count/fb.pug b/themes/butterfly/layout/includes/third-party/card-post-count/fb.pug
    deleted file mode 100644
    index 75d6b4a5..00000000
    --- a/themes/butterfly/layout/includes/third-party/card-post-count/fb.pug
    +++ /dev/null
    @@ -1,18 +0,0 @@
    -- const fbSDKVer = 'v16.0'
    -- const fbSDK = theme.messenger.enable ? `https://connect.facebook.net/${theme.facebook_comments.lang}/sdk/xfbml.customerchat.js#xfbml=1&version=${fbSDKVer}` : `https://connect.facebook.net/${theme.facebook_comments.lang}/sdk.js#xfbml=1&version=${fbSDKVer}`
    -
    -script.
    -  (()=>{
    -    function loadFBComment () {
    -      if (typeof FB === 'object') FB.XFBML.parse(document.getElementById('recent-posts'))
    -      else {
    -        let ele = document.createElement('script')
    -        ele.setAttribute('src','!{fbSDK}')
    -        ele.setAttribute('async', 'true')
    -        ele.setAttribute('defer', 'true')
    -        ele.setAttribute('crossorigin', 'anonymous')
    -        document.body.appendChild(ele)
    -      }
    -    }
    -    window.pjax ? loadFBComment() : window.addEventListener('load', loadFBComment)
    -  })()
    diff --git a/themes/butterfly/layout/includes/third-party/card-post-count/index.pug b/themes/butterfly/layout/includes/third-party/card-post-count/index.pug
    deleted file mode 100644
    index 5b2685c0..00000000
    --- a/themes/butterfly/layout/includes/third-party/card-post-count/index.pug
    +++ /dev/null
    @@ -1,16 +0,0 @@
    -case theme.comments.use[0]
    -  when 'Twikoo'
    -    include ./twikoo.pug
    -  when 'Disqus'
    -  when 'Disqusjs'
    -    include ./disqus.pug
    -  when 'Valine'
    -    include ./valine.pug
    -  when 'Waline'
    -    include ./waline.pug
    -  when 'Facebook Comments'
    -    include ./fb.pug
    -  when 'Remark42'
    -    include ./remark42.pug
    -  when 'Artalk'
    -    include ./artalk.pug
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/card-post-count/remark42.pug b/themes/butterfly/layout/includes/third-party/card-post-count/remark42.pug
    deleted file mode 100644
    index b67164f7..00000000
    --- a/themes/butterfly/layout/includes/third-party/card-post-count/remark42.pug
    +++ /dev/null
    @@ -1,18 +0,0 @@
    -- const { host, siteId, option } = theme.remark42
    -
    -script.
    -  (()=>{
    -    window.remark_config = Object.assign({
    -      host: '!{host}',
    -      site_id: '!{siteId}',
    -    },!{JSON.stringify(option)})
    -
    -    function getCount () {
    -      const s = document.createElement('script')
    -      s.src = remark_config.host + '/web/counter.js'
    -      s.defer = true
    -      document.head.appendChild(s)
    -    }
    -
    -    window.pjax ? getCount() : window.addEventListener('load', getCount)
    -  })()
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/card-post-count/twikoo.pug b/themes/butterfly/layout/includes/third-party/card-post-count/twikoo.pug
    deleted file mode 100644
    index 72a42231..00000000
    --- a/themes/butterfly/layout/includes/third-party/card-post-count/twikoo.pug
    +++ /dev/null
    @@ -1,37 +0,0 @@
    -script.
    -  (() => { 
    -    const getCommentUrl = () => {
    -      const eleGroup = document.querySelectorAll('#recent-posts .article-title')
    -      let urlArray = []
    -      eleGroup.forEach(i=>{
    -        urlArray.push(i.getAttribute('href'))
    -      })
    -      return urlArray
    -    }
    -
    -    const getCount = () => {
    -      const runTwikoo = () => {
    -        twikoo.getCommentsCount({
    -          envId: '!{theme.twikoo.envId}',
    -          region: '!{theme.twikoo.region}',
    -          urls: getCommentUrl(),
    -          includeReply: false
    -        }).then(function (res) {
    -          document.querySelectorAll('#recent-posts .twikoo-count').forEach((item,index) => {
    -            item.textContent = res[index].count
    -          })
    -        }).catch(function (err) {
    -          console.log(err)
    -        })
    -      }
    -
    -        if (typeof twikoo === 'object') {
    -          runTwikoo()
    -        } else {
    -          getScript('!{url_for(theme.asset.twikoo)}').then(runTwikoo)
    -        }
    -    }
    -
    -    window.pjax ? getCount() : window.addEventListener('load', getCount)
    -
    -  })()
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/card-post-count/valine.pug b/themes/butterfly/layout/includes/third-party/card-post-count/valine.pug
    deleted file mode 100644
    index dfe9b6d5..00000000
    --- a/themes/butterfly/layout/includes/third-party/card-post-count/valine.pug
    +++ /dev/null
    @@ -1,20 +0,0 @@
    -script.
    -  (() => {
    -    function loadValine () {
    -      function initValine () {
    -        let initData = {
    -          el: '#vcomment',
    -          appId: '#{theme.valine.appId}',
    -          appKey: '#{theme.valine.appKey}',
    -          serverURLs: '#{theme.valine.serverURLs}'
    -        }
    -        
    -        const valine = new Valine(initData)
    -      }
    -
    -      if (typeof Valine === 'function') initValine() 
    -      else getScript('!{url_for(theme.asset.valine)}').then(initValine)
    -    }
    -
    -    window.pjax ? loadValine() : window.addEventListener('load', loadValine)
    -  })()
    diff --git a/themes/butterfly/layout/includes/third-party/card-post-count/waline.pug b/themes/butterfly/layout/includes/third-party/card-post-count/waline.pug
    deleted file mode 100644
    index a8faf963..00000000
    --- a/themes/butterfly/layout/includes/third-party/card-post-count/waline.pug
    +++ /dev/null
    @@ -1,21 +0,0 @@
    -- const serverURL = theme.waline.serverURL.replace(/\/$/, '')
    -script.
    -  (() => {
    -    async function loadWaline () {
    -      try {
    -        const eleGroup = document.querySelectorAll('#recent-posts .waline-comment-count')
    -        const keyArray = Array.from(eleGroup).map(i => i.getAttribute('data-path'))
    -
    -        const res = await fetch(`!{serverURL}/api/comment?type=count&url=${keyArray}`, { method: 'GET' })
    -        const result = await res.json()
    -        
    -        result.data.forEach((count, index) => {
    -          eleGroup[index].textContent = count
    -        })
    -      } catch (err) {
    -        console.error(err)
    -      }
    -    }
    -
    -    window.pjax ? loadWaline() : window.addEventListener('load', loadWaline)
    -  })()
    diff --git a/themes/butterfly/layout/includes/third-party/chat/chatra.pug b/themes/butterfly/layout/includes/third-party/chat/chatra.pug
    deleted file mode 100644
    index 5cc7b5a9..00000000
    --- a/themes/butterfly/layout/includes/third-party/chat/chatra.pug
    +++ /dev/null
    @@ -1,50 +0,0 @@
    -//- https://chatra.io/help/api/
    -script.
    -  (() => {
    -    const isChatBtn = !{theme.chat_btn}
    -    const isChatHideShow = !{theme.chat_hide_show}
    -
    -    if (isChatBtn) {
    -      const close = () => {
    -        Chatra('minimizeWidget')
    -        Chatra('hide')
    -      }
    -
    -      const open = () => {
    -        Chatra('openChat', true)
    -        Chatra('show')
    -      }
    -
    -      window.ChatraSetup = {
    -        startHidden: true
    -      }
    -    
    -      window.chatBtnFn = () => {
    -        const isShow = document.getElementById('chatra').classList.contains('chatra--expanded')
    -        isShow ? close() : open()
    -      }
    -    } else if (isChatHideShow) {
    -      window.chatBtn = {
    -        hide: () => {
    -          Chatra('hide')
    -        },
    -        show: () => {
    -          Chatra('show')
    -        }
    -      }
    -    }
    -
    -    (function(d, w, c) {
    -      w.ChatraID = '#{theme.chatra.id}'
    -      var s = d.createElement('script')
    -      w[c] = w[c] || function() {
    -          (w[c].q = w[c].q || []).push(arguments)
    -      }
    -      s.async = true
    -      s.src = 'https://call.chatra.io/chatra.js'
    -      if (d.head) d.head.appendChild(s)
    -    })(document, window, 'Chatra')
    -
    -  })()
    -
    -
    diff --git a/themes/butterfly/layout/includes/third-party/chat/crisp.pug b/themes/butterfly/layout/includes/third-party/chat/crisp.pug
    deleted file mode 100644
    index 6c8b6bf4..00000000
    --- a/themes/butterfly/layout/includes/third-party/chat/crisp.pug
    +++ /dev/null
    @@ -1,45 +0,0 @@
    -script.
    -  (() => {
    -    window.$crisp = [];
    -    window.CRISP_WEBSITE_ID = "!{theme.crisp.website_id}";
    -    (function () {
    -      d = document;
    -      s = d.createElement("script");
    -      s.src = "https://client.crisp.chat/l.js";
    -      s.async = 1;
    -      d.getElementsByTagName("head")[0].appendChild(s);
    -    })();
    -    $crisp.push(["safe", true])
    -
    -    const isChatBtn = !{theme.chat_btn}
    -    const isChatHideShow = !{theme.chat_hide_show}
    -
    -    if (isChatBtn) {
    -      const open = () => {
    -        $crisp.push(["do", "chat:show"])
    -        $crisp.push(["do", "chat:open"])
    -      }
    -
    -      const close = () => {
    -        $crisp.push(["do", "chat:hide"])
    -      }
    -
    -      close()
    -      $crisp.push(["on", "chat:closed", function() {
    -        close()
    -      }])
    -
    -      window.chatBtnFn = () => {
    -        $crisp.is("chat:visible") ? close() : open()
    -      }
    -    } else if (isChatHideShow) {
    -      window.chatBtn = {
    -        hide: () => {
    -          $crisp.push(["do", "chat:hide"])
    -        },
    -        show: () => {
    -          $crisp.push(["do", "chat:show"])
    -        }
    -      }
    -    }
    -  })()
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/chat/daovoice.pug b/themes/butterfly/layout/includes/third-party/chat/daovoice.pug
    deleted file mode 100644
    index 5a7c33dc..00000000
    --- a/themes/butterfly/layout/includes/third-party/chat/daovoice.pug
    +++ /dev/null
    @@ -1,40 +0,0 @@
    -//- https://guide.daocloud.io/daovoice/javascript-api-5869833.html
    -script.
    -  (() => {
    -    (function(i,s,o,g,r,a,m){i["DaoVoiceObject"]=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;a.charset="utf-8";m.parentNode.insertBefore(a,m)})(window,document,"script",('https:' == document.location.protocol ? 'https:' : 'http:') + "//widget.daovoice.io/widget/!{theme.daovoice.app_id}.js","daovoice")
    -
    -    const isChatBtn = !{theme.chat_btn}
    -    const isChatHideShow = !{theme.chat_hide_show}
    -
    -    daovoice('init', {
    -      app_id: '!{theme.daovoice.app_id}',},{
    -      launcher: { 
    -        disableLauncherIcon: isChatBtn
    -      },
    -    });
    -    daovoice('update');
    -
    -    if (isChatBtn) {
    -      window.chatBtnFn = () => {
    -        const isShow = document.getElementById('daodream-messenger').classList.contains('daodream-messenger-active')
    -        isShow ? daovoice('hide') : daovoice('show')
    -      }
    -    } else if (isChatHideShow) {
    -      window.chatBtn = {
    -        hide: () => {
    -          daovoice('update', {},{
    -            launcher: {
    -              disableLauncherIcon: true
    -            }
    -          })
    -        },
    -        show: () => {
    -          daovoice('update', {}, {
    -            launcher: {
    -              disableLauncherIcon: false
    -            }
    -          })
    -        }
    -      }
    -    }
    -  })()
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/chat/index.pug b/themes/butterfly/layout/includes/third-party/chat/index.pug
    deleted file mode 100644
    index 4b6bda68..00000000
    --- a/themes/butterfly/layout/includes/third-party/chat/index.pug
    +++ /dev/null
    @@ -1,10 +0,0 @@
    -if theme.chatra && theme.chatra.enable
    -  include ./chatra.pug
    -else if theme.tidio && theme.tidio.enable
    -  include ./tidio.pug
    -else if theme.daovoice && theme.daovoice.enable
    -  include ./daovoice.pug
    -else if theme.crisp && theme.crisp.enable
    -  include ./crisp.pug
    -else if theme.messenger && theme.messenger.enable
    -  include ./messenger.pug
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/chat/messenger.pug b/themes/butterfly/layout/includes/third-party/chat/messenger.pug
    deleted file mode 100644
    index 3d244fc0..00000000
    --- a/themes/butterfly/layout/includes/third-party/chat/messenger.pug
    +++ /dev/null
    @@ -1,44 +0,0 @@
    -- let { pageID, lang } = theme.messenger
    -- lang = theme.comments.use && theme.comments.use.includes('Facebook Comments') ? theme.facebook_comments.lang : lang
    -
    -#fb-customer-chat.fb-customerchat(page_id=pageID attribution='biz_inbox')
    -
    -script.
    -  (() => {
    -    document.getElementById('fb-root') ? '' : document.body.insertAdjacentHTML('afterend', '<div id="fb-root"></div>')
    -
    -    window.fbAsyncInit = function() {
    -      FB.init({
    -        xfbml: true,
    -        version: 'v16.0'
    -      });
    -    };
    -
    -    (function(d, s, id) {
    -      var js, fjs = d.getElementsByTagName(s)[0];
    -      if (d.getElementById(id)) return;
    -      js = d.createElement(s); js.id = id;
    -      js.src = 'https://connect.facebook.net/!{lang}/sdk/xfbml.customerchat.js';
    -      fjs.parentNode.insertBefore(js, fjs);
    -    }(document, 'script', 'facebook-jssdk'));
    -
    -    const isChatBtn = !{theme.chat_btn}
    -    const isChatHideShow = !{theme.chat_hide_show}
    -
    -    if (isChatBtn) {
    -      window.chatBtnFn = () => {
    -        const isShow = document.querySelector('.fb_customer_chat_bounce_in_v2')
    -        isShow ? FB.CustomerChat.hide() : FB.CustomerChat.show()
    -      }
    -    } else if (isChatHideShow) {
    -      window.chatBtn = {
    -        hide: () => {
    -          FB.CustomerChat.hide()
    -        },
    -        show: () => {
    -          FB.CustomerChat.show(false)
    -        }
    -      }
    -    }
    -  })()
    -
    diff --git a/themes/butterfly/layout/includes/third-party/chat/tidio.pug b/themes/butterfly/layout/includes/third-party/chat/tidio.pug
    deleted file mode 100644
    index 20104f53..00000000
    --- a/themes/butterfly/layout/includes/third-party/chat/tidio.pug
    +++ /dev/null
    @@ -1,45 +0,0 @@
    -script(src=`//code.tidio.co/${theme.tidio.public_key}.js` async)
    -script.
    -  (() => {
    -    const isChatBtn = !{theme.chat_btn}
    -    const isChatHideShow = !{theme.chat_hide_show}
    -
    -    if (isChatBtn) {
    -      let isShow = false
    -      const close = () => {
    -        window.tidioChatApi.hide()
    -        isShow = false
    -      }
    -      
    -      const open = () => {
    -        window.tidioChatApi.open()
    -        window.tidioChatApi.show()
    -        isShow = true
    -      }
    -
    -      const onTidioChatApiReady = () => {
    -        window.tidioChatApi.hide()
    -        window.tidioChatApi.on("close", close)
    -      }
    -      if (window.tidioChatApi) {
    -        window.tidioChatApi.on("ready", onTidioChatApiReady)
    -      } else {
    -        document.addEventListener("tidioChat-ready", onTidioChatApiReady)
    -      }
    -
    -      window.chatBtnFn = () => {
    -        if (!window.tidioChatApi) return
    -        isShow ? close() : open()
    -      }
    -    } else if (isChatHideShow) {
    -      window.chatBtn = {
    -        hide: () => {
    -          window.tidioChatApi && window.tidioChatApi.hide()
    -        },
    -        show: () => {
    -          window.tidioChatApi && window.tidioChatApi.show()
    -        }
    -      }
    -    }
    -  })()
    -
    diff --git a/themes/butterfly/layout/includes/third-party/comments/artalk.pug b/themes/butterfly/layout/includes/third-party/comments/artalk.pug
    deleted file mode 100644
    index 700b91ae..00000000
    --- a/themes/butterfly/layout/includes/third-party/comments/artalk.pug
    +++ /dev/null
    @@ -1,52 +0,0 @@
    -- const { server, site, option } = theme.artalk
    -- const { use, lazyload } = theme.comments
    -
    -script.
    -  (() => {
    -    const initArtalk = () => {
    -      window.artalkItem = new Artalk(Object.assign({
    -        el: '#artalk-wrap',
    -        server: '!{server}',
    -        site: '!{site}',
    -        pageKey: location.pathname,
    -        darkMode: document.documentElement.getAttribute('data-theme') === 'dark',
    -        countEl: '.artalk-count'
    -      },!{JSON.stringify(option)}))
    -
    -      if (GLOBAL_CONFIG.lightbox === 'null') return
    -      window.artalkItem.use(ctx => {
    -        ctx.on('list-loaded', () => {
    -          ctx.getCommentList().forEach(comment => {
    -            const $content = comment.getRender().$content
    -            btf.loadLightbox($content.querySelectorAll('img:not([atk-emoticon])'))
    -          })
    -        })
    -      })
    -    }
    -
    -    const loadArtalk = async () => {
    -      if (typeof window.artalkItem === 'object') initArtalk()
    -      else {
    -        await getCSS('!{theme.asset.artalk_css}')
    -        await getScript('!{theme.asset.artalk_js}')
    -        initArtalk()
    -      }
    -    }
    -
    -    const artalkChangeMode = theme => {
    -      const artalkWrap = document.getElementById('artalk-wrap')
    -      if (!(artalkWrap && artalkWrap.children.length)) return
    -      const isDark = theme === 'dark'
    -      window.artalkItem.setDarkMode(isDark)
    -    }
    -  
    -
    -    btf.addGlobalFn('themeChange', artalkChangeMode, 'artalk')
    -    
    -    if ('!{use[0]}' === 'Artalk' || !!{lazyload}) {
    -      if (!{lazyload}) btf.loadComment(document.getElementById('artalk-wrap'), loadArtalk)
    -      else loadArtalk()
    -    } else {
    -      window.loadOtherComment = loadArtalk
    -    }
    -  })()
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/comments/disqus.pug b/themes/butterfly/layout/includes/third-party/comments/disqus.pug
    deleted file mode 100644
    index 8d8864cf..00000000
    --- a/themes/butterfly/layout/includes/third-party/comments/disqus.pug
    +++ /dev/null
    @@ -1,59 +0,0 @@
    -- const disqusPageTitle = page.title.replace(/'/ig,"\\'")
    -- const { shortname, apikey } = theme.disqus
    -- const { use, lazyload, count } = theme.comments
    -
    -script.
    -  (() => {
    -    const disqus_config = function () {
    -      this.page.url = '!{ page.permalink }'
    -      this.page.identifier = '!{ url_for(page.path) }'
    -      this.page.title = '!{ disqusPageTitle }'
    -    }
    -
    -    const disqusReset = () => {
    -      window.DISQUS && window.DISQUS.reset({
    -        reload: true,
    -        config: disqus_config
    -      })
    -    }
    -
    -    btf.addGlobalFn('themeChange', disqusReset, 'disqus')
    -
    -    const loadDisqus = () =>{
    -      if (window.DISQUS) disqusReset()
    -      else {
    -        const script = document.createElement('script')
    -        script.src = 'https://!{shortname}.disqus.com/embed.js'
    -        script.setAttribute('data-timestamp', +new Date())
    -        document.head.appendChild(script)
    -      }
    -    }
    -
    -    const getCount = async() => {
    -      try {
    -        const eleGroup = document.querySelector('#post-meta .disqus-comment-count')
    -        if (!eleGroup) return
    -        const cleanedLinks = eleGroup.href.replace(/#post-comment$/, '')
    -
    -        const res = await fetch(`https://disqus.com/api/3.0/threads/set.json?forum=!{shortname}&api_key=!{apikey}&thread:link=${cleanedLinks}`,{
    -          method: 'GET'
    -        })
    -        const result = await res.json()
    -
    -        const count = result.response.length ? result.response[0].posts : 0
    -        eleGroup.textContent = count
    -      } catch (err) {
    -        console.error(err)
    -      }
    -    }
    -
    -    if ('!{use[0]}' === 'Disqus' || !!{lazyload}) {
    -      if (!{lazyload}) btf.loadComment(document.getElementById('disqus_thread'), loadDisqus)
    -      else {
    -        loadDisqus()
    -        !{ count ? 'GLOBAL_CONFIG_SITE.isPost && getCount()' : '' }
    -      }
    -    } else {
    -      window.loadOtherComment = loadDisqus
    -    }
    -  })()
    diff --git a/themes/butterfly/layout/includes/third-party/comments/disqusjs.pug b/themes/butterfly/layout/includes/third-party/comments/disqusjs.pug
    deleted file mode 100644
    index af416969..00000000
    --- a/themes/butterfly/layout/includes/third-party/comments/disqusjs.pug
    +++ /dev/null
    @@ -1,64 +0,0 @@
    -- let disqusjsPageTitle = page.title.replace(/'/ig,"\\'")
    -- const { shortname:dqShortname, apikey:dqApikey, option:dqOption } = theme.disqusjs
    -
    -script.
    -  (() => {
    -    const initDisqusjs = () => {
    -      window.disqusjs = null
    -      disqusjs = new DisqusJS(Object.assign({
    -        shortname: '!{dqShortname}',
    -        identifier: '!{ url_for(page.path) }',
    -        url: '!{ page.permalink }',
    -        title: '!{ disqusjsPageTitle }',
    -        apikey: '!{dqApikey}',
    -      },!{JSON.stringify(dqOption)}))
    -
    -      disqusjs.render(document.getElementById('disqusjs-wrap'))
    -    }
    -
    -    const themeChange = () => {
    -      const ele = document.getElementById('disqus_thread')
    -      if(!ele) return
    -      disqusjs.destroy()
    -      initDisqusjs()
    -    }
    -
    -    btf.addGlobalFn('themeChange', themeChange, 'disqusjs')
    -
    -    const loadDisqusjs = async() => {
    -      if (window.disqusJsLoad) initDisqusjs()
    -      else {
    -        await getCSS('!{url_for(theme.asset.disqusjs_css)}')
    -        await getScript('!{url_for(theme.asset.disqusjs)}')
    -        initDisqusjs()
    -        window.disqusJsLoad = true
    -      }
    -    }
    -
    -    const getCount = async() => {
    -      try {
    -        const eleGroup = document.querySelector('#post-meta .disqusjs-comment-count')
    -        if (!eleGroup) return
    -        const cleanedLinks = eleGroup.href.replace(/#post-comment$/, '')
    -
    -        const res = await fetch(`https://disqus.com/api/3.0/threads/set.json?forum=!{dqShortname}&api_key=!{dqApikey}&thread:link=${cleanedLinks}`,{
    -          method: 'GET'
    -        })
    -        const result = await res.json()
    -        const count = result.response.length ? result.response[0].posts : 0
    -        eleGroup.textContent = count
    -      } catch (err) {
    -        console.error(err)
    -      }
    -    }
    -
    -    if ('!{theme.comments.use[0]}' === 'Disqusjs' || !!{theme.comments.lazyload}) {
    -      if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('disqusjs-wrap'), loadDisqusjs)
    -      else {
    -        loadDisqusjs()
    -        !{ theme.comments.count ? 'GLOBAL_CONFIG_SITE.isPost && getCount()' : '' }
    -      }
    -    } else {
    -      window.loadOtherComment = loadDisqusjs
    -    }
    -  })()
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/comments/facebook_comments.pug b/themes/butterfly/layout/includes/third-party/comments/facebook_comments.pug
    deleted file mode 100644
    index f0cc9165..00000000
    --- a/themes/butterfly/layout/includes/third-party/comments/facebook_comments.pug
    +++ /dev/null
    @@ -1,46 +0,0 @@
    -- const fbSDKVer = 'v16.0'
    -- const fbSDK = theme.messenger.enable ? `https://connect.facebook.net/${theme.facebook_comments.lang}/sdk/xfbml.customerchat.js#xfbml=1&version=${fbSDKVer}` : `https://connect.facebook.net/${theme.facebook_comments.lang}/sdk.js#xfbml=1&version=${fbSDKVer}`
    -
    -script.
    -  (()=>{
    -    const loadFBComment = () => {
    -      document.getElementById('fb-root') ? '' : document.body.insertAdjacentHTML('afterend', '<div id="fb-root"></div>')
    -
    -      const themeNow = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
    -      const $fbComment = document.getElementsByClassName('fb-comments')[0]
    -      $fbComment.setAttribute('data-colorscheme',themeNow)
    -      $fbComment.setAttribute('data-href', '!{urlNoIndex(page.permalink)}')
    -
    -      if (typeof FB === 'object') {
    -        FB.XFBML.parse(document.getElementsByClassName('post-meta-commentcount')[0])
    -        FB.XFBML.parse(document.getElementById('post-comment'))
    -      }
    -      else {
    -        let ele = document.createElement('script')
    -        ele.setAttribute('src','!{fbSDK}')
    -        ele.setAttribute('async', 'true')
    -        ele.setAttribute('defer', 'true')
    -        ele.setAttribute('crossorigin', 'anonymous')
    -        ele.setAttribute('id', 'facebook-jssdk')
    -        document.getElementById('fb-root').insertAdjacentElement('afterbegin',ele)
    -      }
    -    }
    -
    -    const fbModeChange = theme => {
    -      const $fbComment = document.getElementsByClassName('fb-comments')[0]
    -      if ($fbComment && typeof FB === 'object') {
    -        $fbComment.setAttribute('data-colorscheme',theme)
    -        FB.XFBML.parse(document.getElementById('post-comment'))
    -      }
    -    }
    -
    -    btf.addGlobalFn('themeChange', fbModeChange, 'facebook_comments')
    -
    -    if ('!{theme.comments.use[0]}' === 'Facebook Comments' || !!{theme.comments.lazyload}) {
    -      if (!{theme.comments.lazyload}) btf.loadComment(document.querySelector('#post-comment .fb-comments'), loadFBComment)
    -      else loadFBComment()
    -    } else {
    -      window.loadOtherComment = loadFBComment
    -    }
    -  })()
    -
    diff --git a/themes/butterfly/layout/includes/third-party/comments/giscus.pug b/themes/butterfly/layout/includes/third-party/comments/giscus.pug
    deleted file mode 100644
    index 3e1b5188..00000000
    --- a/themes/butterfly/layout/includes/third-party/comments/giscus.pug
    +++ /dev/null
    @@ -1,54 +0,0 @@
    -- const { repo, repo_id, category_id, theme:themes, option } = theme.giscus
    -- const giscusUrl = theme.asset.giscus || 'https://giscus.app/client.js'
    -- const giscusOriginUrl = new URL(giscusUrl).origin
    -- const { use, lazyload } = theme.comments
    -
    -script.
    -  (()=>{
    -    const getGiscusTheme = theme => {
    -      return theme === 'dark' ? '!{themes.dark}' : '!{themes.light}'
    -    }
    -
    -    const loadGiscus = () => {
    -      const config = Object.assign({
    -        src: '!{giscusUrl}',
    -        'data-repo': '!{repo}',
    -        'data-repo-id': '!{repo_id}',
    -        'data-category-id': '!{category_id}',
    -        'data-mapping': 'pathname',
    -        'data-theme': getGiscusTheme(document.documentElement.getAttribute('data-theme')),
    -        'data-reactions-enabled': '1',
    -        crossorigin: 'anonymous',
    -        async: true
    -      },!{JSON.stringify(option)})
    -
    -      const ele = document.createElement('script')
    -      for (let key in config) {
    -        ele.setAttribute(key, config[key])
    -      }
    -      document.getElementById('giscus-wrap').appendChild(ele)
    -    }
    -
    -    const changeGiscusTheme = theme => {
    -      const sendMessage = message => {
    -        const iframe = document.querySelector('iframe.giscus-frame')
    -        if (!iframe) return
    -        iframe.contentWindow.postMessage({ giscus: message }, '!{giscusOriginUrl}')
    -      }
    -
    -      sendMessage({
    -        setConfig: {
    -          theme: getGiscusTheme(theme)
    -        }
    -      });
    -    }
    -
    -    btf.addGlobalFn('themeChange', changeGiscusTheme, 'giscus')
    -
    -    if ('!{use[0]}' === 'Giscus' || !!{lazyload}) {
    -      if (!{lazyload}) btf.loadComment(document.getElementById('giscus-wrap'), loadGiscus)
    -      else loadGiscus()
    -    } else {
    -      window.loadOtherComment= loadGiscus
    -    }
    -  })()
    diff --git a/themes/butterfly/layout/includes/third-party/comments/gitalk.pug b/themes/butterfly/layout/includes/third-party/comments/gitalk.pug
    deleted file mode 100644
    index e0a13897..00000000
    --- a/themes/butterfly/layout/includes/third-party/comments/gitalk.pug
    +++ /dev/null
    @@ -1,44 +0,0 @@
    -- const { client_id, client_secret, repo, owner, admin, option } = theme.gitalk
    -
    -script.
    -  (() => {
    -    const initGitalk = () => {
    -      const gitalk = new Gitalk(Object.assign({
    -        clientID: '!{client_id}',
    -        clientSecret: '!{client_secret}',
    -        repo: '!{repo}',
    -        owner: '!{owner}',
    -        admin: ['!{admin}'],
    -        id: '!{md5(page.path)}',
    -        updateCountCallback: commentCount
    -      },!{JSON.stringify(option)}))
    -
    -      gitalk.render('gitalk-container')
    -    }
    -
    -    const loadGitalk = async() => {
    -      if (typeof Gitalk === 'function') initGitalk()
    -      else {
    -        await getCSS('!{url_for(theme.asset.gitalk_css)}')
    -        await getScript('!{url_for(theme.asset.gitalk)}')
    -        initGitalk()
    -      }
    -    }
    -    
    -    const commentCount = n => {
    -      const isCommentCount = document.querySelector('#post-meta .gitalk-comment-count')
    -      if (isCommentCount) {
    -        isCommentCount.textContent= n
    -      }
    -    }
    -
    -    if ('!{theme.comments.use[0]}' === 'Gitalk' || !!{theme.comments.lazyload}) {
    -      if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('gitalk-container'), loadGitalk)
    -      else loadGitalk()
    -    } else {
    -      window.loadOtherComment = loadGitalk
    -    }
    -  })()
    -
    -
    -
    diff --git a/themes/butterfly/layout/includes/third-party/comments/index.pug b/themes/butterfly/layout/includes/third-party/comments/index.pug
    deleted file mode 100644
    index 3b8ceff5..00000000
    --- a/themes/butterfly/layout/includes/third-party/comments/index.pug
    +++ /dev/null
    @@ -1,46 +0,0 @@
    -- let defaultComment = theme.comments.use[0]
    -hr.custom-hr
    -#post-comment
    -  .comment-head
    -    .comment-headline
    -      i.fas.fa-comments.fa-fw
    -      span= ' ' + _p('comment')
    -    
    -    if theme.comments.use.length > 1
    -      .comment-switch
    -        span.first-comment=defaultComment
    -        span#switch-btn
    -        span.second-comment=theme.comments.use[1]
    -
    -
    -  .comment-wrap
    -    each name in theme.comments.use
    -      div
    -        case name
    -          when 'Disqus'
    -            #disqus_thread
    -          when 'Valine'
    -            #vcomment.vcomment
    -          when 'Disqusjs'
    -            #disqusjs-wrap
    -          when 'Livere'
    -            #lv-container(data-id="city" data-uid=theme.livere.uid)
    -          when 'Gitalk'
    -            #gitalk-container
    -          when 'Utterances'
    -            #utterances-wrap
    -          when 'Twikoo'
    -            #twikoo-wrap
    -          when 'Waline'
    -            #waline-wrap
    -          when 'Giscus'
    -            #giscus-wrap
    -          when 'Facebook Comments'
    -            .fb-comments(data-colorscheme = theme.display_mode === 'dark' ? 'dark' : 'light'
    -                        data-numposts= theme.facebook_comments.pageSize || 10
    -                        data-order-by= theme.facebook_comments.order_by || 'social'
    -                        data-width="100%")
    -          when 'Remark42'
    -            #remark42
    -          when 'Artalk'
    -            #artalk-wrap
    diff --git a/themes/butterfly/layout/includes/third-party/comments/js.pug b/themes/butterfly/layout/includes/third-party/comments/js.pug
    deleted file mode 100644
    index bf1d8728..00000000
    --- a/themes/butterfly/layout/includes/third-party/comments/js.pug
    +++ /dev/null
    @@ -1,26 +0,0 @@
    -each name in theme.comments.use
    -  case name
    -    when 'Valine'
    -      !=partial('includes/third-party/comments/valine', {}, {cache: true})
    -    when 'Disqus'
    -      include ./disqus.pug
    -    when 'Disqusjs'
    -      include ./disqusjs.pug
    -    when 'Livere'
    -      !=partial('includes/third-party/comments/livere', {}, {cache: true})
    -    when 'Gitalk'
    -      include ./gitalk.pug
    -    when 'Utterances'
    -      !=partial('includes/third-party/comments/utterances', {}, {cache: true})
    -    when 'Twikoo'
    -      !=partial('includes/third-party/comments/twikoo', {}, {cache: true})
    -    when 'Waline'
    -      !=partial('includes/third-party/comments/waline', {}, {cache: true})
    -    when 'Giscus'
    -      !=partial('includes/third-party/comments/giscus', {}, {cache: true})
    -    when 'Facebook Comments'
    -      include ./facebook_comments.pug
    -    when 'Remark42'
    -      !=partial('includes/third-party/comments/remark42', {}, {cache: true})
    -    when 'Artalk'
    -      !=partial('includes/third-party/comments/artalk', {}, {cache: true})
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/comments/livere.pug b/themes/butterfly/layout/includes/third-party/comments/livere.pug
    deleted file mode 100644
    index ecacb596..00000000
    --- a/themes/butterfly/layout/includes/third-party/comments/livere.pug
    +++ /dev/null
    @@ -1,25 +0,0 @@
    -- const { use, lazyload } = theme.comments
    -
    -script.
    -  (()=>{
    -    const loadLivere = () => {
    -      if (typeof LivereTower === 'object') window.LivereTower.init()
    -      else {
    -        (function(d, s) {
    -            var j, e = d.getElementsByTagName(s)[0];
    -            if (typeof LivereTower === 'function') { return; }
    -            j = d.createElement(s);
    -            j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
    -            j.async = true;
    -            e.parentNode.insertBefore(j, e);
    -        })(document, 'script');
    -      }
    -    }
    -
    -    if ('!{use[0]}' === 'Livere' || !!{lazyload}) {
    -      if (!{lazyload}) btf.loadComment(document.getElementById('lv-container'), loadLivere)
    -      else loadLivere()
    -    } else {
    -      window.loadOtherComment = loadLivere
    -    }
    -  })()
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/comments/remark42.pug b/themes/butterfly/layout/includes/third-party/comments/remark42.pug
    deleted file mode 100644
    index 388fb97c..00000000
    --- a/themes/butterfly/layout/includes/third-party/comments/remark42.pug
    +++ /dev/null
    @@ -1,68 +0,0 @@
    -- const { host, siteId, option } = theme.remark42
    -script.
    -  var remark_config = Object.assign({
    -    host: '!{host}',
    -    site_id: '!{siteId}',
    -    components: ['embed'],
    -    theme: document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
    -  },!{JSON.stringify(option)})
    -
    -  function addRemark42(){
    -    for (let i = 0; i < remark_config.components.length; i++) {
    -      const s = document.createElement('script')
    -      s.src = remark_config.host + '/web/' + remark_config.components[i] + '.js'
    -      s.defer = true
    -      document.head.appendChild(s)
    -    }
    -  }
    -
    -  function initRemark42() {
    -    if (window.REMARK42) {
    -      if (this.remark42Instance) {
    -        this.remark42Instance.destroy()
    -      }
    -
    -      this.remark42Instance = window.REMARK42.createInstance({
    -        ...remark_config
    -      })
    -    }
    -  }
    -
    -  function getCount () {
    -    const ele = document.querySelector('.remark42__counter')
    -    if (ele) {
    -      const s = document.createElement('script')
    -      s.src = remark_config.host + '/web/counter.js'
    -      s.defer = true
    -      document.head.appendChild(s)
    -    }
    -  }
    -
    -  function loadRemark42 () {
    -    if (window.REMARK42) {
    -      this.initRemark42()
    -      getCount()
    -    } else {
    -      addRemark42()
    -      window.addEventListener('REMARK42::ready', () => {
    -        this.initRemark42()
    -        getCount()
    -      })
    -    }
    -  }
    -
    -  function remarkChangeMode (theme) {
    -    if (!window.REMARK42) return
    -    window.REMARK42.changeTheme(theme)
    -  }
    -
    -  btf.addGlobalFn('themeChange', remarkChangeMode, 'remark42')
    -
    -  if ('!{theme.comments.use[0]}' === 'Remark42' || !!{theme.comments.lazyload}) {
    -    if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('remark42'), loadRemark42)
    -    else loadRemark42()
    -  } else {
    -    function loadOtherComment () {
    -      loadRemark42()
    -    }
    -  }
    diff --git a/themes/butterfly/layout/includes/third-party/comments/twikoo.pug b/themes/butterfly/layout/includes/third-party/comments/twikoo.pug
    deleted file mode 100644
    index 858fad3b..00000000
    --- a/themes/butterfly/layout/includes/third-party/comments/twikoo.pug
    +++ /dev/null
    @@ -1,46 +0,0 @@
    -- const { envId, region, option } = theme.twikoo
    -- const { use, lazyload, count } = theme.comments
    -
    -script.
    -  (() => {
    -    const init = () => {
    -      twikoo.init(Object.assign({
    -        el: '#twikoo-wrap',
    -        envId: '!{envId}',
    -        region: '!{region}',
    -        onCommentLoaded: () => {
    -          btf.loadLightbox(document.querySelectorAll('#twikoo .tk-content img:not(.tk-owo-emotion)'))
    -        }
    -      }, !{JSON.stringify(option)}))
    -    }
    -
    -    const loadTwikoo = () => {
    -      if (typeof twikoo === 'object') setTimeout(init,0)
    -      else getScript('!{url_for(theme.asset.twikoo)}').then(init)
    -    }
    -
    -    const getCount = () => {
    -      const countELement = document.getElementById('twikoo-count')
    -      if(!countELement) return
    -      twikoo.getCommentsCount({
    -        envId: '!{envId}',
    -        region: '!{region}',
    -        urls: [window.location.pathname],
    -        includeReply: false
    -      }).then(res => {
    -        countELement.textContent = res[0].count
    -      }).catch(err => {
    -        console.error(err)
    -      })
    -    }
    -
    -    if ('!{use[0]}' === 'Twikoo' || !!{lazyload}) {
    -      if (!{lazyload}) btf.loadComment(document.getElementById('twikoo-wrap'), loadTwikoo)
    -      else {
    -        loadTwikoo()
    -        !{count ? 'GLOBAL_CONFIG_SITE.isPost && getCount()' : ''}
    -      }
    -    } else {
    -      window.loadOtherComment = loadTwikoo
    -    }
    -  })()
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/comments/utterances.pug b/themes/butterfly/layout/includes/third-party/comments/utterances.pug
    deleted file mode 100644
    index 0ca01e7e..00000000
    --- a/themes/butterfly/layout/includes/third-party/comments/utterances.pug
    +++ /dev/null
    @@ -1,39 +0,0 @@
    -- const { use, lazyload } = theme.comments
    -- const { repo, issue_term, light_theme, dark_theme } = theme.utterances
    -
    -script.
    -  (() => {
    -    const loadUtterances = () => {
    -      let ele = document.createElement('script')
    -      ele.id = 'utterances_comment'
    -      ele.src = 'https://utteranc.es/client.js'
    -      ele.setAttribute('repo', '!{repo}')
    -      ele.setAttribute('issue-term', '!{issue_term}')
    -      const nowTheme = document.documentElement.getAttribute('data-theme') === 'dark' ? '#{dark_theme}' : '#{light_theme}'
    -      ele.setAttribute('theme', nowTheme)
    -      ele.crossOrigin = 'anonymous'
    -      ele.async = true
    -      document.getElementById('utterances-wrap').appendChild(ele)
    -    }
    -
    -    const utterancesTheme = theme => {
    -      const iframe = document.querySelector('.utterances-frame')
    -      if (iframe) {
    -        const theme = theme === 'dark' ? '#{dark_theme}' : '#{light_theme}'
    -        const message = {
    -          type: 'set-theme',
    -          theme: theme
    -        };
    -        iframe.contentWindow.postMessage(message, 'https://utteranc.es');
    -      }
    -    }
    -
    -    btf.addGlobalFn('themeChange', utterancesTheme, 'utterances')
    -
    -    if ('!{use[0]}' === 'Utterances' || !!{lazyload}) {
    -      if (!{lazyload}) btf.loadComment(document.getElementById('utterances-wrap'), loadUtterances)
    -      else loadUtterances()
    -    } else {
    -      window.loadOtherComment = loadUtterances
    -    }
    -  })()
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/comments/valine.pug b/themes/butterfly/layout/includes/third-party/comments/valine.pug
    deleted file mode 100644
    index 85781d5f..00000000
    --- a/themes/butterfly/layout/includes/third-party/comments/valine.pug
    +++ /dev/null
    @@ -1,38 +0,0 @@
    -- const { use, lazyload } = theme.comments
    -- const { appId, appKey, avatar, serverURLs, visitor, option } = theme.valine
    -
    -- let emojiMaps = '""'
    -if site.data.valine
    -  - emojiMaps = JSON.stringify(site.data.valine)
    -
    -script.
    -  (() => {
    -    const initValine = () => {
    -      const valine = new Valine(Object.assign({
    -        el: '#vcomment',
    -        appId: '#{appId}',
    -        appKey: '#{appKey}',
    -        avatar: '#{avatar}',
    -        serverURLs: '#{serverURLs}',
    -        emojiMaps: !{emojiMaps},
    -        path: window.location.pathname,
    -        visitor: #{visitor}
    -      }, !{JSON.stringify(option)}))
    -    }
    -
    -    const loadValine = async () => {
    -      if (typeof Valine === 'function') initValine()
    -      else {
    -        await getScript('!{url_for(theme.asset.valine)}')
    -        initValine()
    -      }
    -    }
    -
    -    if ('!{use[0]}' === 'Valine' || !!{lazyload}) {
    -      if (!{lazyload}) btf.loadComment(document.getElementById('vcomment'),loadValine)
    -      else setTimeout(loadValine, 0)
    -    } else {
    -      window.loadOtherComment = loadValine
    -    }
    -  })()
    -
    diff --git a/themes/butterfly/layout/includes/third-party/comments/waline.pug b/themes/butterfly/layout/includes/third-party/comments/waline.pug
    deleted file mode 100644
    index a3baccae..00000000
    --- a/themes/butterfly/layout/includes/third-party/comments/waline.pug
    +++ /dev/null
    @@ -1,33 +0,0 @@
    -- const { serverURL, option, pageview } = theme.waline
    -- const { lazyload, count, use } = theme.comments
    -
    -script.
    -  (() => {
    -    const initWaline = () => {
    -      const waline = Waline.init(Object.assign({
    -        el: '#waline-wrap',
    -        serverURL: '!{serverURL}',
    -        pageview: !{lazyload ? false : pageview},
    -        dark: 'html[data-theme="dark"]',
    -        path: window.location.pathname,
    -        comment: !{lazyload ? false : count},
    -      }, !{JSON.stringify(option)}))
    -    }
    -
    -    const loadWaline = async () => {
    -      if (typeof Waline === 'object') initWaline()
    -      else {
    -        await getCSS('!{url_for(theme.asset.waline_css)}')
    -        await getScript('!{url_for(theme.asset.waline_js)}')
    -        initWaline()
    -      }
    -    }
    -
    -    if ('!{use[0]}' === 'Waline' || !!{lazyload}) {
    -      if (!{lazyload}) btf.loadComment(document.getElementById('waline-wrap'),loadWaline)
    -      else setTimeout(loadWaline, 0)
    -    } else {
    -      window.loadOtherComment = loadWaline
    -    }
    -  })()
    -
    diff --git a/themes/butterfly/layout/includes/third-party/effect.pug b/themes/butterfly/layout/includes/third-party/effect.pug
    deleted file mode 100644
    index a3b29958..00000000
    --- a/themes/butterfly/layout/includes/third-party/effect.pug
    +++ /dev/null
    @@ -1,35 +0,0 @@
    -if theme.fireworks && theme.fireworks.enable
    -  canvas.fireworks(mobile=`${theme.fireworks.mobile}`)
    -  script(src=url_for(theme.asset.fireworks))
    -
    -if (theme.canvas_ribbon && theme.canvas_ribbon.enable)
    -  script(defer id="ribbon" src=url_for(theme.asset.canvas_ribbon) size=theme.canvas_ribbon.size
    -  alpha=theme.canvas_ribbon.alpha zIndex=theme.canvas_ribbon.zIndex mobile=`${theme.canvas_ribbon.mobile}` data-click=`${theme.canvas_ribbon.click_to_change}`)
    -
    -if (theme.canvas_fluttering_ribbon && theme.canvas_fluttering_ribbon.enable)
    -  script(defer id="fluttering_ribbon" mobile=`${theme.canvas_fluttering_ribbon.mobile}` src=url_for(theme.asset.canvas_fluttering_ribbon))
    -
    -if (theme.canvas_nest && theme.canvas_nest.enable)
    -  script#canvas_nest(defer color=theme.canvas_nest.color opacity=theme.canvas_nest.opacity zIndex=theme.canvas_nest.zIndex count=theme.canvas_nest.count mobile=`${theme.canvas_nest.mobile}` src=url_for(theme.asset.canvas_nest))
    -
    -if theme.activate_power_mode.enable
    -  script(src=url_for(theme.asset.activate_power_mode))
    -  script.
    -    POWERMODE.colorful = !{theme.activate_power_mode.colorful};
    -    POWERMODE.shake = !{theme.activate_power_mode.shake};
    -    POWERMODE.mobile = !{theme.activate_power_mode.mobile};
    -    document.body.addEventListener('input', POWERMODE);
    -
    -//- 鼠標特效
    -if theme.click_heart && theme.click_heart.enable
    -  script#click-heart(src=url_for(theme.asset.click_heart) async mobile=`${theme.click_heart.mobile}`)
    -
    -if theme.clickShowText && theme.clickShowText.enable
    -  script#click-show-text(
    -    src= url_for(theme.asset.clickShowText)
    -    data-mobile= `${theme.clickShowText.mobile}`
    -    data-text= theme.clickShowText.text.join(",")
    -    data-fontsize= theme.clickShowText.fontSize
    -    data-random= `${theme.clickShowText.random}`
    -    async
    -  )
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/math/index.pug b/themes/butterfly/layout/includes/third-party/math/index.pug
    deleted file mode 100644
    index 2b16302e..00000000
    --- a/themes/butterfly/layout/includes/third-party/math/index.pug
    +++ /dev/null
    @@ -1,18 +0,0 @@
    -if theme.mathjax && theme.mathjax.enable
    -  if theme.mathjax.per_page
    -    if is_post() || is_page()
    -      include ./mathjax.pug
    -  else
    -    if page.mathjax
    -      include ./mathjax.pug
    -
    -if theme.katex && theme.katex.enable
    -  if theme.katex.per_page
    -    if is_post() || is_page()
    -      include ./katex.pug
    -  else
    -    if page.katex
    -      include ./katex.pug
    -
    -if theme.mermaid.enable
    -  include ./mermaid.pug
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/math/katex.pug b/themes/butterfly/layout/includes/third-party/math/katex.pug
    deleted file mode 100644
    index c1f0bd69..00000000
    --- a/themes/butterfly/layout/includes/third-party/math/katex.pug
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -link(rel="stylesheet" type="text/css" href=url_for(theme.asset.katex))
    -script(src=url_for(theme.asset.katex_copytex))
    -script.
    -  (() => {
    -    document.querySelectorAll('#article-container span.katex-display').forEach(item => {
    -      btf.wrap(item, 'div', { class: 'katex-wrap'})
    -    })
    -  })()
    -  
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/math/mathjax.pug b/themes/butterfly/layout/includes/third-party/math/mathjax.pug
    deleted file mode 100644
    index 470aa451..00000000
    --- a/themes/butterfly/layout/includes/third-party/math/mathjax.pug
    +++ /dev/null
    @@ -1,38 +0,0 @@
    -//- Mathjax 3
    -script.
    -  if (!window.MathJax) {
    -    window.MathJax = {
    -      tex: {
    -        inlineMath: [['$', '$'], ['\\(', '\\)']],
    -        tags: 'ams'
    -      },
    -      chtml: {
    -        scale: 1.1
    -      },
    -      options: {
    -        renderActions: {
    -          findScript: [10, doc => {
    -            for (const node of document.querySelectorAll('script[type^="math/tex"]')) {
    -              const display = !!node.type.match(/; *mode=display/)
    -              const math = new doc.options.MathItem(node.textContent, doc.inputJax[0], display)
    -              const text = document.createTextNode('')
    -              node.parentNode.replaceChild(text, node)
    -              math.start = {node: text, delim: '', n: 0}
    -              math.end = {node: text, delim: '', n: 0}
    -              doc.math.push(math)
    -            }
    -          }, '']
    -        }
    -      }
    -    }
    -    
    -    const script = document.createElement('script')
    -    script.src = '!{url_for(theme.asset.mathjax)}'
    -    script.id = 'MathJax-script'
    -    script.async = true
    -    document.head.appendChild(script)
    -  } else {
    -    MathJax.startup.document.state(0)
    -    MathJax.texReset()
    -    MathJax.typesetPromise()
    -  }
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/math/mermaid.pug b/themes/butterfly/layout/includes/third-party/math/mermaid.pug
    deleted file mode 100644
    index 2cfc1c7c..00000000
    --- a/themes/butterfly/layout/includes/third-party/math/mermaid.pug
    +++ /dev/null
    @@ -1,38 +0,0 @@
    -script.
    -  (() => {
    -    const $mermaid = document.querySelectorAll('#article-container .mermaid-wrap')
    -    if ($mermaid.length === 0) return
    -    const runMermaid = () => {
    -      window.loadMermaid = true
    -      const theme = document.documentElement.getAttribute('data-theme') === 'dark' ? '!{theme.mermaid.theme.dark}' : '!{theme.mermaid.theme.light}'
    -
    -      Array.from($mermaid).forEach((item, index) => {
    -        const mermaidSrc = item.firstElementChild
    -        const mermaidThemeConfig = '%%{init:{ \'theme\':\'' + theme + '\'}}%%\n'
    -        const mermaidID = 'mermaid-' + index
    -        const mermaidDefinition = mermaidThemeConfig + mermaidSrc.textContent
    -
    -        const renderFn = mermaid.render(mermaidID, mermaidDefinition)
    -
    -        const renderV10 = () => {
    -          renderFn.then(({svg}) => {
    -            mermaidSrc.insertAdjacentHTML('afterend', svg)
    -          })
    -        }
    -
    -        const renderV9 = svg => {
    -          mermaidSrc.insertAdjacentHTML('afterend', svg)
    -        }
    -
    -        typeof renderFn === 'string' ? renderV9(renderFn) : renderV10()
    -      })
    -    }
    -
    -    const loadMermaid = () => {
    -      window.loadMermaid ? runMermaid() : getScript('!{url_for(theme.asset.mermaid)}').then(runMermaid)
    -    }
    -
    -    btf.addGlobalFn('themeChange', runMermaid, 'mermaid')
    -
    -    window.pjax ? loadMermaid() : document.addEventListener('DOMContentLoaded', loadMermaid)
    -  })()
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/newest-comments/artalk.pug b/themes/butterfly/layout/includes/third-party/newest-comments/artalk.pug
    deleted file mode 100644
    index e2e83bac..00000000
    --- a/themes/butterfly/layout/includes/third-party/newest-comments/artalk.pug
    +++ /dev/null
    @@ -1,110 +0,0 @@
    -- const { server, site, option } = theme.artalk
    -- const avatarCdn = option !== null && option.gravatar && option.gravatar.mirror
    -- const avatarDefault = option !== null && option.gravatar && (option.gravatar.params || option.gravatar.default)
    -
    -script.
    -  window.addEventListener('load', () => {
    -    const changeContent = (content) => {
    -      if (content === '') return content
    -
    -      content = content.replace(/<img.*?src="(.*?)"?[^\>]+>/ig, '[!{_p("aside.card_newest_comments.image")}]') // replace image link
    -      content = content.replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi, '[!{_p("aside.card_newest_comments.link")}]') // replace url
    -      content = content.replace(/<pre><code>.*?<\/pre>/gi, '[!{_p("aside.card_newest_comments.code")}]') // replace code
    -      content = content.replace(/<[^>]+>/g,"") // remove html tag
    -
    -      if (content.length > 150) {
    -        content = content.substring(0,150) + '...'
    -      }
    -      return content
    -    }
    -
    -    const generateHtml = array => {
    -      let result = ''
    -
    -      if (array.length) {
    -        for (let i = 0; i < array.length; i++) {
    -          result += '<div class=\'aside-list-item\'>'
    -
    -          if (!{theme.newest_comments.avatar}) {
    -            const name = '!{theme.lazyload.enable ? "data-lazy-src" : "src"}'
    -            result += `<a href='${array[i].url}' class='thumbnail'><img ${name}='${array[i].avatar}' alt='${array[i].nick}'></a>`
    -          }
    -
    -          result += `<div class='content'>
    -          <a class='comment' href='${array[i].url}' title='${array[i].content}'>${array[i].content}</a>
    -          <div class='name'><span>${array[i].nick} / </span><time datetime="${array[i].date}">${btf.diffDate(array[i].date, true)}</time></div>
    -          </div></div>`
    -        }
    -      } else {
    -        result += '!{_p("aside.card_newest_comments.zero")}'
    -      }
    -
    -      let $dom = document.querySelector('#card-newest-comments .aside-list')
    -      $dom.innerHTML= result
    -      window.lazyLoadInstance && window.lazyLoadInstance.update()
    -      window.pjax && window.pjax.refresh($dom)
    -    }
    -
    -    const getSetting = async () => {
    -      try {
    -        const res = await fetch('!{server}/api/conf', { method: 'GET' })
    -        return await res.json()
    -      } catch (e) {
    -        console.log(e)
    -      }
    -    }
    -
    -    const headerList = {
    -      method: 'POST',
    -      headers: {
    -        'Content-Type': 'application/x-www-form-urlencoded',
    -        'Origin': window.location.origin
    -      },
    -      body: new URLSearchParams({
    -        'site_name': '!{site}',
    -        'limit': '!{theme.newest_comments.limit}',
    -        'type':'latest_comments'
    -      })
    -    }
    -
    -    const getComment = async () => {
    -      try {
    -        const res = await fetch('!{server}/api/stat', headerList)
    -        const result = await res.json()
    -        const avatarStr = await getSetting()
    -        const { mirror, params, default:defaults } = avatarStr.data.frontend_conf.gravatar
    -        const avatarCdn = !{avatarCdn} || mirror
    -        let avatarDefault = !{avatarDefault} || params || defaults
    -        avatarDefault = avatarDefault.startsWith('d=') ? avatarDefault : `d=${avatarDefault}`
    -        const artalk = result.data.map(function (e) {
    -          return {
    -            'avatar': `${avatarCdn}${e.email_encrypted}?${avatarDefault}`,
    -            'content': changeContent(e.content_marked),
    -            'nick': e.nick,
    -            'url': e.page_url,
    -            'date': e.date,
    -          }
    -        })
    -        saveToLocal.set('artalk-newest-comments', JSON.stringify(artalk), !{theme.newest_comments.storage}/(60*24))
    -        generateHtml(artalk)
    -      } catch (e) {
    -        console.log(e)
    -        const $dom = document.querySelector('#card-newest-comments .aside-list')
    -        $dom.innerHTML= "!{_p('aside.card_newest_comments.error')}"
    -      }
    -    }
    -
    -    const newestCommentInit = () => {
    -      if (document.querySelector('#card-newest-comments .aside-list')) {
    -        const data = saveToLocal.get('artalk-newest-comments')
    -        if (data) {
    -          generateHtml(JSON.parse(data))
    -        } else {
    -          getComment()
    -        }
    -      }
    -    }
    -
    -    newestCommentInit()
    -    document.addEventListener('pjax:complete', newestCommentInit)
    -  })
    diff --git a/themes/butterfly/layout/includes/third-party/newest-comments/disqus-comment.pug b/themes/butterfly/layout/includes/third-party/newest-comments/disqus-comment.pug
    deleted file mode 100644
    index 2acba1c0..00000000
    --- a/themes/butterfly/layout/includes/third-party/newest-comments/disqus-comment.pug
    +++ /dev/null
    @@ -1,82 +0,0 @@
    -script.
    -  window.addEventListener('load', () => {
    -    const changeContent = (content) => {
    -      if (content === '') return content
    -
    -      content = content.replace(/<img.*?src="(.*?)"?[^\>]+>/ig, '[!{_p("aside.card_newest_comments.image")}]') // replace image link
    -      content = content.replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi, '[!{_p("aside.card_newest_comments.link")}]') // replace url
    -      content = content.replace(/<code>.*?<\/code>/gi, '[!{_p("aside.card_newest_comments.code")}]') // replace code
    -      content = content.replace(/<[^>]+>/g,"") // remove html tag
    -
    -      if (content.length > 150) {
    -        content = content.substring(0,150) + '...'
    -      }
    -      return content
    -    }
    -
    -    const getComment = () => {
    -      fetch('https://disqus.com/api/3.0/forums/listPosts.json?forum=!{forum}&related=thread&limit=!{theme.newest_comments.limit}&api_key=!{apiKey}')
    -        .then(response => response.json())
    -        .then(data => {
    -          const disqusArray = data.response.map(item => {
    -            return {
    -              'avatar': item.author.avatar.cache,
    -              'content': changeContent(item.message),
    -              'nick': item.author.name,
    -              'url': item.url,
    -              'date': item.createdAt
    -            }
    -          })
    -
    -          saveToLocal.set('disqus-newest-comments', JSON.stringify(disqusArray), !{theme.newest_comments.storage}/(60*24))
    -          generateHtml(disqusArray)
    -        }).catch(e => {
    -          const $dom = document.querySelector('#card-newest-comments .aside-list')
    -          $dom.textContent= "!{_p('aside.card_newest_comments.error')}"
    -        })
    -    }
    -
    -    const generateHtml = array => {
    -      let result = ''
    -
    -      if (array.length) {
    -        for (let i = 0; i < array.length; i++) {
    -          result += '<div class=\'aside-list-item\'>'
    -
    -          if (!{theme.newest_comments.avatar}) {
    -            const name = '!{theme.lazyload.enable ? "data-lazy-src" : "src"}'
    -            result += `<a href='${array[i].url}' class='thumbnail'><img ${name}='${array[i].avatar}' alt='${array[i].nick}'></a>`
    -          }
    -          
    -          result += `<div class='content'>
    -          <a class='comment' href='${array[i].url}' title='${array[i].content}'>${array[i].content}</a>
    -          <div class='name'><span>${array[i].nick}</span><time> / ${btf.diffDate(array[i].date, true)}</time></div>
    -          </div></div>`
    -        }
    -      } else {
    -        result += '!{_p("aside.card_newest_comments.zero")}'
    -      }
    -
    -      let $dom = document.querySelector('#card-newest-comments .aside-list')
    -      $dom.innerHTML= result
    -      window.lazyLoadInstance && window.lazyLoadInstance.update()
    -      window.pjax && window.pjax.refresh($dom)
    -    }
    -
    -    const newestCommentInit = () => {
    -      if (document.querySelector('#card-newest-comments .aside-list')) {
    -        const data = saveToLocal.get('disqus-newest-comments')
    -        if (data) {
    -          generateHtml(JSON.parse(data))
    -        } else {
    -          getComment()
    -        }
    -      }
    -    }
    -
    -    newestCommentInit()
    -    document.addEventListener('pjax:complete', newestCommentInit)
    -  })
    -
    -
    -
    diff --git a/themes/butterfly/layout/includes/third-party/newest-comments/github-issues.pug b/themes/butterfly/layout/includes/third-party/newest-comments/github-issues.pug
    deleted file mode 100644
    index 79430db6..00000000
    --- a/themes/butterfly/layout/includes/third-party/newest-comments/github-issues.pug
    +++ /dev/null
    @@ -1,109 +0,0 @@
    -script.
    -  window.addEventListener('load', () => {
    -    const changeContent = (content) => {
    -      if (content === '') return content
    -
    -      content = content.replace(/<img.*?src="(.*?)"?[^\>]+>/ig, '[!{_p("aside.card_newest_comments.image")}]') // replace image link
    -      content = content.replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi, '[!{_p("aside.card_newest_comments.link")}]') // replace url
    -      content = content.replace(/<pre><code>.*?<\/pre>/gi, '[!{_p("aside.card_newest_comments.code")}]') // replace code
    -      content = content.replace(/<[^>]+>/g,"") // remove html tag
    -
    -      if (content.length > 150) {
    -        content = content.substring(0,150) + '...'
    -      }
    -      return content
    -    }
    -
    -    const findTrueUrl = (array) => {
    -      Promise.all(array.map(item =>
    -        fetch(item.url).then(resp => resp.json()).then(data => {
    -          const urlArray = data.body.match(/(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?/ig)
    -          if (data.user.login === 'utterances-bot') {
    -            return urlArray.pop()
    -          } else {
    -            return urlArray.shift()
    -          }
    -        })
    -      )).then(res => {
    -          array = array.map((i,index)=> {
    -            return {
    -              ...i,
    -              url: res[index]
    -            }
    -          })
    -
    -          saveToLocal.set('github-newest-comments', JSON.stringify(array), !{theme.newest_comments.storage}/(60*24))
    -          generateHtml(array)
    -      });
    -    }
    -
    -    const getComment = () => {
    -      fetch('https://api.github.com/repos/!{userRepo}/issues/comments?sort=updated&direction=desc&per_page=!{theme.newest_comments.limit}&page=1',{
    -        "headers": {
    -          Accept: 'application/vnd.github.v3.html+json'
    -        }
    -      })
    -        .then(response => response.json())
    -        .then(data => {
    -          const githubArray = data.map(item => {
    -            return {
    -              'avatar': item.user.avatar_url,
    -              'content': changeContent(item.body_html),
    -              'nick': item.user.login,
    -              'url': item.issue_url,
    -              'date': item.updated_at,
    -              'githubUrl': item.html_url
    -            }
    -          })
    -          findTrueUrl(githubArray)
    -        }).catch(e => {
    -          const $dom = document.querySelector('#card-newest-comments .aside-list')
    -          $dom.textContent= "!{_p('aside.card_newest_comments.error')}"
    -        })
    -    }
    -
    -    const generateHtml = array => {
    -      let result = ''
    -
    -      if (array.length) {
    -        for (let i = 0; i < array.length; i++) {
    -          result += '<div class=\'aside-list-item\'>'
    -
    -          if (!{theme.newest_comments.avatar}) {
    -            const name = '!{theme.lazyload.enable ? "data-lazy-src" : "src"}'
    -            result += `<a href='${array[i].url}' class='thumbnail'><img ${name}='${array[i].avatar}' alt='${array[i].nick}'></a>`
    -          }
    -
    -          result += `<div class='content'>
    -          <a class='comment' href='${array[i].url}' title='${array[i].content}'>${array[i].content}</a>
    -          <div class='name'><span>${array[i].nick} / </span><time datetime="${array[i].date}">${btf.diffDate(array[i].date, true)}</time></div>
    -          </div></div>`
    -        }
    -      } else {
    -        result += '!{_p("aside.card_newest_comments.zero")}'
    -      }
    -
    -      let $dom = document.querySelector('#card-newest-comments .aside-list')
    -      $dom.innerHTML= result
    -      window.lazyLoadInstance && window.lazyLoadInstance.update()
    -      window.pjax && window.pjax.refresh($dom)
    -    }
    -
    -    const newestCommentInit = () => {
    -      if (document.querySelector('#card-newest-comments .aside-list')) {
    -        const data = saveToLocal.get('github-newest-comments')
    -        if (data) {
    -          generateHtml(JSON.parse(data))
    -        } else {
    -          getComment()
    -        }
    -      }
    -    }
    -
    -    newestCommentInit()
    -    document.addEventListener('pjax:complete', newestCommentInit)
    -  })
    -
    -
    -
    -
    diff --git a/themes/butterfly/layout/includes/third-party/newest-comments/index.pug b/themes/butterfly/layout/includes/third-party/newest-comments/index.pug
    deleted file mode 100644
    index 8ceaccf8..00000000
    --- a/themes/butterfly/layout/includes/third-party/newest-comments/index.pug
    +++ /dev/null
    @@ -1,30 +0,0 @@
    -- let { use } = theme.comments
    -
    -if use
    -  - let forum,apiKey,userRepo
    -  case use[0]
    -    when 'Valine'
    -      include ./valine.pug
    -    when 'Waline'
    -      include ./waline.pug
    -    when 'Twikoo'
    -      include ./twikoo-comment.pug
    -    when 'Disqus'
    -      - forum = theme.disqus.shortname
    -      - apiKey = theme.disqus.apikey
    -      include ./disqus-comment.pug
    -    when 'Disqusjs'
    -      - forum = theme.disqusjs.shortname
    -      - apiKey = theme.disqusjs.apikey
    -      include ./disqus-comment.pug
    -    when 'Gitalk'
    -      - let { repo,owner } = theme.gitalk
    -      - userRepo = owner + '/' + repo
    -      include ./github-issues.pug
    -    when 'Utterances'
    -      - userRepo = theme.utterances.repo
    -      include ./github-issues.pug
    -    when 'Remark42'
    -      include ./remark42.pug
    -    when 'Artalk'
    -      include ./artalk.pug
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/newest-comments/remark42.pug b/themes/butterfly/layout/includes/third-party/newest-comments/remark42.pug
    deleted file mode 100644
    index 71c26037..00000000
    --- a/themes/butterfly/layout/includes/third-party/newest-comments/remark42.pug
    +++ /dev/null
    @@ -1,80 +0,0 @@
    -- const { host, siteId } = theme.remark42
    -
    -script.
    -  window.addEventListener('load', () => {
    -    const changeContent = (content) => {
    -      if (content === '') return content
    -
    -      content = content.replace(/<img.*?src="(.*?)"?[^\>]+>/ig, '[!{_p("aside.card_newest_comments.image")}]') // replace image link
    -      content = content.replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi, '[!{_p("aside.card_newest_comments.link")}]') // replace url
    -      content = content.replace(/<pre><code>.*?<\/pre>/gi, '[!{_p("aside.card_newest_comments.code")}]') // replace code
    -      content = content.replace(/<[^>]+>/g,"") // remove html tag
    -
    -      if (content.length > 150) {
    -        content = content.substring(0,150) + '...'
    -      }
    -      return content
    -    }
    -
    -    const generateHtml = array => {
    -      let result = ''
    -
    -      if (array.length) {
    -        for (let i = 0; i < array.length; i++) {
    -          result += '<div class=\'aside-list-item\'>'
    -
    -          if (!{theme.newest_comments.avatar}) {
    -            const name = '!{theme.lazyload.enable ? "data-lazy-src" : "src"}'
    -            result += `<a href='${array[i].url}' class='thumbnail'><img ${name}='${array[i].avatar}' alt='${array[i].nick}'></a>`
    -          }
    -
    -          result += `<div class='content'>
    -          <a class='comment' href='${array[i].url}' title='${array[i].content}'>${array[i].content}</a>
    -          <div class='name'><span>${array[i].nick} / </span><time datetime="${array[i].date}">${btf.diffDate(array[i].date, true)}</time></div>
    -          </div></div>`
    -        }
    -      } else {
    -        result += '!{_p("aside.card_newest_comments.zero")}'
    -      }
    -
    -      let $dom = document.querySelector('#card-newest-comments .aside-list')
    -      $dom.innerHTML= result
    -      window.lazyLoadInstance && window.lazyLoadInstance.update()
    -      window.pjax && window.pjax.refresh($dom)
    -    }
    -
    -    const getComment = () => {
    -      fetch('!{host}/api/v1/last/!{theme.newest_comments.limit}?site=!{siteId}')
    -        .then(response => response.json())
    -        .then(data => {
    -          const remark42 = data.map(function (e) {
    -            return {
    -              'avatar': e.user.picture,
    -              'content': changeContent(e.text),
    -              'nick': e.user.name,
    -              'url': e.locator.url,
    -              'date': e.time,
    -            }
    -          })
    -          saveToLocal.set('remark42-newest-comments', JSON.stringify(remark42), !{theme.newest_comments.storage}/(60*24))
    -          generateHtml(remark42)
    -        }).catch(e => {
    -          const $dom = document.querySelector('#card-newest-comments .aside-list')
    -          $dom.textContent= "!{_p('aside.card_newest_comments.error')}"
    -        })
    -    }
    -
    -    const newestCommentInit = () => {
    -      if (document.querySelector('#card-newest-comments .aside-list')) {
    -        const data = saveToLocal.get('remark42-newest-comments')
    -        if (data) {
    -          generateHtml(JSON.parse(data))
    -        } else {
    -          getComment()
    -        }
    -      }
    -    }
    -
    -    newestCommentInit()
    -    document.addEventListener('pjax:complete', newestCommentInit)
    -  })
    diff --git a/themes/butterfly/layout/includes/third-party/newest-comments/twikoo-comment.pug b/themes/butterfly/layout/includes/third-party/newest-comments/twikoo-comment.pug
    deleted file mode 100644
    index 8615f160..00000000
    --- a/themes/butterfly/layout/includes/third-party/newest-comments/twikoo-comment.pug
    +++ /dev/null
    @@ -1,93 +0,0 @@
    -script.
    -  window.addEventListener('load', () => {
    -    const changeContent = (content) => {
    -      if (content === '') return content
    -
    -      content = content.replace(/<img.*?src="(.*?)"?[^\>]+>/ig, '[!{_p("aside.card_newest_comments.image")}]') // replace image link
    -      content = content.replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi, '[!{_p("aside.card_newest_comments.link")}]') // replace url
    -      content = content.replace(/<pre><code>.*?<\/pre>/gi, '[!{_p("aside.card_newest_comments.code")}]') // replace code
    -      content = content.replace(/<[^>]+>/g,"") // remove html tag
    -
    -      if (content.length > 150) {
    -        content = content.substring(0,150) + '...'
    -      }
    -      return content
    -    }
    -
    -    const getComment = () => {
    -      const runTwikoo = () => {
    -        twikoo.getRecentComments({
    -          envId: '!{theme.twikoo.envId}',
    -          region: '!{theme.twikoo.region}',
    -          pageSize: !{theme.newest_comments.limit},
    -          includeReply: true
    -        }).then(function (res) {
    -          const twikooArray = res.map(e => {
    -            return {
    -              'content': changeContent(e.comment),
    -              'avatar': e.avatar,
    -              'nick': e.nick,
    -              'url': e.url + '#' + e.id,
    -              'date': new Date(e.created).toISOString()
    -            }
    -          })
    -
    -          saveToLocal.set('twikoo-newest-comments', JSON.stringify(twikooArray), !{theme.newest_comments.storage}/(60*24))
    -          generateHtml(twikooArray)
    -        }).catch(function (err) {
    -          const $dom = document.querySelector('#card-newest-comments .aside-list')
    -          $dom.textContent= "!{_p('aside.card_newest_comments.error')}"
    -        })
    -      }
    -
    -      if (typeof twikoo === 'object') {
    -        runTwikoo()
    -      } else {
    -        getScript('!{url_for(theme.asset.twikoo)}').then(runTwikoo)
    -      }
    -    }
    -
    -    const generateHtml = array => {
    -      let result = ''
    -
    -      if (array.length) {
    -        for (let i = 0; i < array.length; i++) {
    -          result += '<div class=\'aside-list-item\'>'
    -
    -          if (!{theme.newest_comments.avatar}) {
    -            const name = '!{theme.lazyload.enable ? "data-lazy-src" : "src"}'
    -            result += `<a href='${array[i].url}' class='thumbnail'><img ${name}='${array[i].avatar}' alt='${array[i].nick}'></a>`
    -          }
    -          
    -          result += `<div class='content'>
    -          <a class='comment' href='${array[i].url}' title='${array[i].content}'>${array[i].content}</a>
    -          <div class='name'><span>${array[i].nick} / </span><time datetime="${array[i].date}">${btf.diffDate(array[i].date, true)}</time></div>
    -          </div></div>`
    -        }
    -      } else {
    -        result += '!{_p("aside.card_newest_comments.zero")}'
    -      }
    -
    -      let $dom = document.querySelector('#card-newest-comments .aside-list')
    -      $dom.innerHTML= result
    -      window.lazyLoadInstance && window.lazyLoadInstance.update()
    -      window.pjax && window.pjax.refresh($dom)
    -    }
    -
    -    const newestCommentInit = () => {
    -      if (document.querySelector('#card-newest-comments .aside-list')) {
    -        const data = saveToLocal.get('twikoo-newest-comments')
    -        if (data) {
    -          generateHtml(JSON.parse(data))
    -        } else {
    -          getComment()
    -        }
    -      }
    -    }
    -
    -    newestCommentInit()
    -    document.addEventListener('pjax:complete', newestCommentInit)
    -  })
    -
    -
    -
    diff --git a/themes/butterfly/layout/includes/third-party/newest-comments/valine.pug b/themes/butterfly/layout/includes/third-party/newest-comments/valine.pug
    deleted file mode 100644
    index 6f78774d..00000000
    --- a/themes/butterfly/layout/includes/third-party/newest-comments/valine.pug
    +++ /dev/null
    @@ -1,99 +0,0 @@
    -- let default_avatar = theme.valine.avatar
    -
    -script(src=url_for(theme.asset.blueimp_md5))
    -script.
    -  window.addEventListener('load', () => {
    -    const changeContent = (content) => {
    -      if (content === '') return content
    -
    -      content = content.replace(/<img.*?src="(.*?)"?[^\>]+>/ig, '[!{_p("aside.card_newest_comments.image")}]') // replace image link
    -      content = content.replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi, '[!{_p("aside.card_newest_comments.link")}]') // replace url
    -      content = content.replace(/<pre><code>.*?<\/pre>/gi, '[!{_p("aside.card_newest_comments.code")}]') // replace code
    -      content = content.replace(/<[^>]+>/g,"") // remove html tag
    -
    -      if (content.length > 150) {
    -        content = content.substring(0,150) + '...'
    -      }
    -      return content
    -    }
    -
    -    const getIcon = (icon, mail) => {
    -      if (icon) return icon
    -      let defaultIcon = '!{ default_avatar ? `?d=${default_avatar}` : ''}'
    -      let iconUrl = `https://gravatar.loli.net/avatar/${md5(mail.toLowerCase()) + defaultIcon}`
    -      return iconUrl
    -    }
    -
    -    const generateHtml = array => {
    -      let result = ''
    -
    -      if (array.length) {
    -        for (let i = 0; i < array.length; i++) {
    -          result += '<div class=\'aside-list-item\'>'
    -
    -          if (!{theme.newest_comments.avatar}) {
    -            const name = '!{theme.lazyload.enable ? "data-lazy-src" : "src"}'
    -            result += `<a href='${array[i].url}' class='thumbnail'><img ${name}='${array[i].avatar}' alt='${array[i].nick}'></a>`
    -          }
    -
    -          result += `<div class='content'>
    -          <a class='comment' href='${array[i].url}' title='${array[i].content}'>${array[i].content}</a>
    -          <div class='name'><span>${array[i].nick} / </span><time datetime="${array[i].date}">${btf.diffDate(array[i].date, true)}</time></div>
    -          </div></div>`
    -        }
    -      } else {
    -        result += '!{_p("aside.card_newest_comments.zero")}'
    -      }
    -
    -      let $dom = document.querySelector('#card-newest-comments .aside-list')
    -      $dom.innerHTML= result
    -      window.lazyLoadInstance && window.lazyLoadInstance.update()
    -      window.pjax && window.pjax.refresh($dom)
    -    }
    -
    -    const getComment = () => {
    -      const serverURL = '!{theme.valine.serverURLs || `https://${theme.valine.appId.substring(0,8)}.api.lncldglobal.com` }'
    -
    -      var settings = {
    -        "method": "GET",
    -        "headers": {
    -          "X-LC-Id": '!{theme.valine.appId}',
    -          "X-LC-Key": '!{theme.valine.appKey}',
    -          "Content-Type": "application/json"
    -        },
    -      }
    -
    -      fetch(`${serverURL}/1.1/classes/Comment?limit=!{theme.newest_comments.limit}&order=-createdAt`,settings)
    -        .then(response => response.json())
    -        .then(data => {
    -          const valineArray = data.results.map(function (e) {
    -            return {
    -              'avatar': getIcon(e.QQAvatar, e.mail),
    -              'content': changeContent(e.comment),
    -              'nick': e.nick,
    -              'url': e.url + '#' + e.objectId,
    -              'date': e.updatedAt,
    -            }
    -          })
    -          saveToLocal.set('valine-newest-comments', JSON.stringify(valineArray), !{theme.newest_comments.storage}/(60*24))
    -          generateHtml(valineArray)
    -        }).catch(e => {
    -          const $dom = document.querySelector('#card-newest-comments .aside-list')
    -          $dom.textContent= "!{_p('aside.card_newest_comments.error')}"
    -        }) 
    -    }
    -
    -    const newestCommentInit = () => {
    -      if (document.querySelector('#card-newest-comments .aside-list')) {
    -        const data = saveToLocal.get('valine-newest-comments')
    -        if (data) {
    -          generateHtml(JSON.parse(data))
    -        } else {
    -          getComment()
    -        }
    -      }
    -    }
    -
    -    newestCommentInit()
    -    document.addEventListener('pjax:complete', newestCommentInit)
    -  })
    diff --git a/themes/butterfly/layout/includes/third-party/newest-comments/waline.pug b/themes/butterfly/layout/includes/third-party/newest-comments/waline.pug
    deleted file mode 100644
    index be25326b..00000000
    --- a/themes/butterfly/layout/includes/third-party/newest-comments/waline.pug
    +++ /dev/null
    @@ -1,81 +0,0 @@
    -- const serverURL = theme.waline.serverURL.replace(/\/$/, '')
    -
    -script.
    -  window.addEventListener('load', () => {
    -    const changeContent = content => {
    -      if (content === '') return content
    -
    -      content = content.replace(/<img.*?src="(.*?)"?[^\>]+>/ig, '[!{_p("aside.card_newest_comments.image")}]') // replace image link
    -      content = content.replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi, '[!{_p("aside.card_newest_comments.link")}]') // replace url
    -      content = content.replace(/<pre><code>.*?<\/pre>/gi, '[!{_p("aside.card_newest_comments.code")}]') // replace code
    -      content = content.replace(/<[^>]+>/g,"") // remove html tag
    -
    -      if (content.length > 150) {
    -        content = content.substring(0,150) + '...'
    -      }
    -      return content
    -    }
    -
    -    const generateHtml = array => {
    -      let result = ''
    -
    -      if (array.length) {
    -        for (let i = 0; i < array.length; i++) {
    -          result += '<div class=\'aside-list-item\'>'
    -
    -          if (!{theme.newest_comments.avatar}) {
    -            const name = '!{theme.lazyload.enable ? "data-lazy-src" : "src"}'
    -            result += `<a href='${array[i].url}' class='thumbnail'><img ${name}='${array[i].avatar}' alt='${array[i].nick}'></a>`
    -          }
    -
    -          result += `<div class='content'>
    -          <a class='comment' href='${array[i].url}' title='${array[i].content}'>${array[i].content}</a>
    -          <div class='name'><span>${array[i].nick} / </span><time datetime="${array[i].date}">${btf.diffDate(array[i].date, true)}</time></div>
    -          </div></div>`
    -        }
    -      } else {
    -        result += '!{_p("aside.card_newest_comments.zero")}'
    -      }
    -
    -      let $dom = document.querySelector('#card-newest-comments .aside-list')
    -      $dom.innerHTML= result
    -      window.lazyLoadInstance && window.lazyLoadInstance.update()
    -      window.pjax && window.pjax.refresh($dom)
    -    }
    -
    -    const getComment = async () => {
    -      try {
    -        const res = await fetch('!{serverURL}/api/comment?type=recent&count=!{theme.newest_comments.limit}', { method: 'GET' })
    -        const result = await res.json()
    -        const walineArray = result.data.map(e => {
    -          return {
    -            'content': changeContent(e.comment),
    -            'avatar': e.avatar,
    -            'nick': e.nick,
    -            'url': e.url + '#' + e.objectId,
    -            'date': e.time || e.insertedAt
    -          }
    -        })
    -        saveToLocal.set('waline-newest-comments', JSON.stringify(walineArray), !{theme.newest_comments.storage}/(60*24))
    -        generateHtml(walineArray)
    -      } catch (err) {
    -        console.error(err)
    -        const $dom = document.querySelector('#card-newest-comments .aside-list')
    -        $dom.textContent= "!{_p('aside.card_newest_comments.error')}"
    -      }
    -    }
    -
    -    const newestCommentInit = () => {
    -      if (document.querySelector('#card-newest-comments .aside-list')) {
    -        const data = saveToLocal.get('waline-newest-comments')
    -        if (data) {
    -          generateHtml(JSON.parse(data))
    -        } else {
    -          getComment()
    -        }
    -      }
    -    }
    -
    -    newestCommentInit()
    -    document.addEventListener('pjax:complete', newestCommentInit)
    -  })
    diff --git a/themes/butterfly/layout/includes/third-party/pangu.pug b/themes/butterfly/layout/includes/third-party/pangu.pug
    deleted file mode 100644
    index 2027ca7b..00000000
    --- a/themes/butterfly/layout/includes/third-party/pangu.pug
    +++ /dev/null
    @@ -1,20 +0,0 @@
    -script.
    -  function panguFn () {
    -    if (typeof pangu === 'object') pangu.autoSpacingPage()
    -    else {
    -      getScript('!{url_for(theme.asset.pangu)}')
    -        .then(() => {
    -          pangu.autoSpacingPage()
    -        })
    -    }
    -  }
    -
    -  function panguInit () {
    -    if (!{theme.pangu.field === 'post'}){
    -      GLOBAL_CONFIG_SITE.isPost && panguFn()
    -    } else {
    -      panguFn()
    -    }
    -  }
    -
    -  document.addEventListener('DOMContentLoaded', panguInit)
    diff --git a/themes/butterfly/layout/includes/third-party/pjax.pug b/themes/butterfly/layout/includes/third-party/pjax.pug
    deleted file mode 100644
    index 2b783c63..00000000
    --- a/themes/butterfly/layout/includes/third-party/pjax.pug
    +++ /dev/null
    @@ -1,83 +0,0 @@
    -- var pjaxExclude = 'a:not([target="_blank"])'
    -if theme.pjax.exclude
    -  each val in theme.pjax.exclude
    -    - pjaxExclude = pjaxExclude + `:not([href="${val}"])`
    -
    -- let pjaxSelectors = ['head > title','#config-diff','#body-wrap','#rightside-config-hide','#rightside-config-show','.js-pjax']
    -
    -- let choose = theme.comments.use
    -if choose
    -  if theme.Open_Graph_meta.enable && (choose.includes('Livere') || choose.includes('Utterances') || choose.includes('Giscus'))
    -    - pjaxSelectors.unshift('meta[property="og:image"]', 'meta[property="og:title"]', 'meta[property="og:url"]')
    -  if choose.includes('Utterances') || choose.includes('Giscus')
    -    - pjaxSelectors.unshift('link[rel="canonical"]')
    -
    -script(src=url_for(theme.asset.pjax))
    -script.
    -  let pjaxSelectors = !{JSON.stringify(pjaxSelectors)}
    -
    -  var pjax = new Pjax({
    -    elements: '!{pjaxExclude}',
    -    selectors: pjaxSelectors,
    -    cacheBust: false,
    -    analytics: !{theme.google_analytics ? true : false},
    -    scrollRestoration: false
    -  })
    -
    -  document.addEventListener('pjax:send', function () {
    -
    -    // removeEventListener
    -    btf.removeGlobalFnEvent('pjax')
    -    btf.removeGlobalFnEvent('themeChange')
    -
    -    document.getElementById('rightside').classList.remove('rightside-show')
    -    
    -    if (window.aplayers) {
    -      for (let i = 0; i < window.aplayers.length; i++) {
    -        if (!window.aplayers[i].options.fixed) {
    -          window.aplayers[i].destroy()
    -        }
    -      }
    -    }
    -
    -    typeof typed === 'object' && typed.destroy()
    -
    -    //reset readmode
    -    const $bodyClassList = document.body.classList
    -    $bodyClassList.contains('read-mode') && $bodyClassList.remove('read-mode')
    -
    -    typeof disqusjs === 'object' && disqusjs.destroy()
    -  })
    -
    -  document.addEventListener('pjax:complete', function () {
    -    window.refreshFn()
    -
    -    document.querySelectorAll('script[data-pjax]').forEach(item => {
    -      const newScript = document.createElement('script')
    -      const content = item.text || item.textContent || item.innerHTML || ""
    -      Array.from(item.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value))
    -      newScript.appendChild(document.createTextNode(content))
    -      item.parentNode.replaceChild(newScript, item)
    -    })
    -
    -    GLOBAL_CONFIG.islazyload && window.lazyLoadInstance.update()
    -
    -    typeof panguInit === 'function' && panguInit()
    -
    -    // google analytics
    -    typeof gtag === 'function' && gtag('config', '!{theme.google_analytics}', {'page_path': window.location.pathname});
    -
    -    // baidu analytics
    -    typeof _hmt === 'object' && _hmt.push(['_trackPageview',window.location.pathname]);
    -
    -    typeof loadMeting === 'function' && document.getElementsByClassName('aplayer').length && loadMeting()
    -
    -    // prismjs
    -    typeof Prism === 'object' && Prism.highlightAll()
    -  })
    -
    -  document.addEventListener('pjax:error', e => {
    -    if (e.request.status === 404) {
    -      pjax.loadUrl('!{url_for("/404.html")}')
    -    }
    -  })
    diff --git a/themes/butterfly/layout/includes/third-party/prismjs.pug b/themes/butterfly/layout/includes/third-party/prismjs.pug
    deleted file mode 100644
    index 6af44ddd..00000000
    --- a/themes/butterfly/layout/includes/third-party/prismjs.pug
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -if config.prismjs && config.prismjs.enable && !config.prismjs.preprocess
    -  script(src=url_for(theme.asset.prismjs_js))
    -  script(src=url_for(theme.asset.prismjs_autoloader))
    -  if config.prismjs.line_number
    -    script(src=url_for(theme.asset.prismjs_lineNumber_js))
    diff --git a/themes/butterfly/layout/includes/third-party/search/algolia.pug b/themes/butterfly/layout/includes/third-party/search/algolia.pug
    deleted file mode 100644
    index b1f3c3d4..00000000
    --- a/themes/butterfly/layout/includes/third-party/search/algolia.pug
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -#algolia-search
    -  .search-dialog
    -    nav.search-nav
    -      span.search-dialog-title= _p('search.title')
    -      button.search-close-button
    -        i.fas.fa-times
    -
    -    .search-wrap
    -      #algolia-search-input
    -      hr
    -      #algolia-search-results
    -        #algolia-hits
    -        #algolia-pagination
    -        #algolia-info
    -          .algolia-stats
    -          .algolia-poweredBy
    -  
    -  #search-mask
    -
    -  script(src=url_for(theme.asset.algolia_search))
    -  script(src=url_for(theme.asset.instantsearch))
    -  script(src=url_for(theme.asset.algolia_js))
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/search/docsearch.pug b/themes/butterfly/layout/includes/third-party/search/docsearch.pug
    deleted file mode 100644
    index 9adad8b3..00000000
    --- a/themes/butterfly/layout/includes/third-party/search/docsearch.pug
    +++ /dev/null
    @@ -1,28 +0,0 @@
    -- const { appId, apiKey, indexName, option } = theme.docsearch
    -
    -.docsearch-wrap
    -  #docsearch(style="display:none")
    -  link(rel="stylesheet" href=url_for(theme.asset.docsearch_css))
    -  script(src=url_for(theme.asset.docsearch_js))
    -  script.
    -    (() => {
    -      docsearch(Object.assign({
    -        appId: '!{appId}',
    -        apiKey: '!{apiKey}',
    -        indexName: '!{indexName}',
    -        container: '#docsearch',
    -      }, !{JSON.stringify(option)}))
    -
    -      const handleClick = () => {
    -        document.querySelector('.DocSearch-Button').click()
    -      }
    -
    -      const searchClickFn = () => {
    -        btf.addEventListenerPjax(document.querySelector('#search-button > .search'), 'click', handleClick)
    -      }
    -
    -      searchClickFn()
    -      window.addEventListener('pjax:complete', searchClickFn)
    -    })()
    -
    -
    diff --git a/themes/butterfly/layout/includes/third-party/search/index.pug b/themes/butterfly/layout/includes/third-party/search/index.pug
    deleted file mode 100644
    index 160df79c..00000000
    --- a/themes/butterfly/layout/includes/third-party/search/index.pug
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -if theme.algolia_search.enable
    -  include ./algolia.pug
    -else if theme.local_search.enable
    -  include ./local-search.pug
    -else if theme.docsearch.enable
    -  include ./docsearch.pug
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/search/local-search.pug b/themes/butterfly/layout/includes/third-party/search/local-search.pug
    deleted file mode 100644
    index f22f05bb..00000000
    --- a/themes/butterfly/layout/includes/third-party/search/local-search.pug
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -#local-search
    -  .search-dialog
    -    nav.search-nav
    -      span.search-dialog-title= _p('search.title')
    -      span#loading-status
    -      button.search-close-button
    -        i.fas.fa-times
    -
    -    #loading-database.is-center
    -      i.fas.fa-spinner.fa-pulse
    -      span= '  ' + _p("search.load_data")
    -
    -    .search-wrap
    -      #local-search-input
    -        .local-search-box
    -          input(placeholder=_p("search.local_search.input_placeholder") type="text").local-search-box--input
    -      hr
    -      #local-search-results
    -      #local-search-stats-wrap
    -  #search-mask
    -
    -  script(src=url_for(theme.asset.local_search))
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/share/add-this.pug b/themes/butterfly/layout/includes/third-party/share/add-this.pug
    deleted file mode 100644
    index ab44267d..00000000
    --- a/themes/butterfly/layout/includes/third-party/share/add-this.pug
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -.addthis_inline_share_toolbox
    -script(src=`//s7.addthis.com/js/300/addthis_widget.js#pubid=${theme.addThis.pubid}` async)
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/share/addtoany.pug b/themes/butterfly/layout/includes/third-party/share/addtoany.pug
    deleted file mode 100644
    index d42f3be4..00000000
    --- a/themes/butterfly/layout/includes/third-party/share/addtoany.pug
    +++ /dev/null
    @@ -1,10 +0,0 @@
    -.addtoany
    -  .a2a_kit.a2a_kit_size_32.a2a_default_style
    -    - let addtoanyItem = theme.addtoany.item.split(',')
    -    each name in addtoanyItem
    -      a(class="a2a_button_" + name)
    -
    -    a.a2a_dd(href="https://www.addtoany.com/share")
    -script(async src='https://static.addtoany.com/menu/page.js')
    -
    -
    diff --git a/themes/butterfly/layout/includes/third-party/share/index.pug b/themes/butterfly/layout/includes/third-party/share/index.pug
    deleted file mode 100644
    index f8122c0e..00000000
    --- a/themes/butterfly/layout/includes/third-party/share/index.pug
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -.post_share
    -  if theme.sharejs.enable
    -    include ./share-js.pug
    -  else if theme.addtoany.enable
    -    !=partial('includes/third-party/share/addtoany', {}, {cache: true})
    diff --git a/themes/butterfly/layout/includes/third-party/share/share-js.pug b/themes/butterfly/layout/includes/third-party/share/share-js.pug
    deleted file mode 100644
    index 612332c4..00000000
    --- a/themes/butterfly/layout/includes/third-party/share/share-js.pug
    +++ /dev/null
    @@ -1,4 +0,0 @@
    -- const coverVal = page.cover_type === 'img' ? page.cover : theme.avatar.img
    -.social-share(data-image=url_for(coverVal) data-sites= theme.sharejs.sites)
    -link(rel='stylesheet' href=url_for(theme.asset.sharejs_css) media="print" onload="this.media='all'")
    -script(src=url_for(theme.asset.sharejs) defer)
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/third-party/subtitle.pug b/themes/butterfly/layout/includes/third-party/subtitle.pug
    deleted file mode 100644
    index 0b4f6cc9..00000000
    --- a/themes/butterfly/layout/includes/third-party/subtitle.pug
    +++ /dev/null
    @@ -1,92 +0,0 @@
    -- const { effect,source,sub,typed_option } = theme.subtitle
    -- let subContent = sub || new Array()
    -
    -script.
    -  window.typedJSFn = {
    -    init: (str) => {
    -      window.typed = new Typed('#subtitle', Object.assign({
    -        strings: str,
    -        startDelay: 300,
    -        typeSpeed: 150,
    -        loop: true,
    -        backSpeed: 50,
    -      }, !{JSON.stringify(typed_option)}))
    -    },
    -    run: (subtitleType) => {
    -      if (!{effect}) {
    -        if (typeof Typed === 'function') {
    -          subtitleType()
    -        } else {
    -          getScript('!{url_for(theme.asset.typed)}').then(subtitleType)
    -        }
    -      } else {
    -        subtitleType()
    -      }
    -    }
    -  }
    -
    -case source
    -  when 1
    -    script.
    -      function subtitleType () {
    -        fetch('https://v1.hitokoto.cn')
    -          .then(response => response.json())
    -          .then(data => {
    -            if (!{effect}) {
    -              const from = '出自 ' + data.from
    -              const sub = !{JSON.stringify(subContent)}
    -              sub.unshift(data.hitokoto, from)
    -              typedJSFn.init(sub)
    -            } else {
    -              document.getElementById('subtitle').textContent = data.hitokoto
    -            }
    -          })
    -      }
    -      typedJSFn.run(subtitleType)
    -
    -  when 2
    -    script.
    -      function subtitleType () {
    -        getScript('https://yijuzhan.com/api/word.php?m=js').then(() => {
    -          const con = str[0]
    -          if (!{effect}) {
    -            const from = '出自 ' + str[1]
    -            const sub = !{JSON.stringify(subContent)}
    -            sub.unshift(con, from)
    -            typedJSFn.init(sub)
    -          } else {
    -            document.getElementById('subtitle').textContent = con
    -          }
    -        })
    -      }
    -      typedJSFn.run(subtitleType)
    -
    -  when 3
    -    script.
    -      function subtitleType () {
    -        getScript('https://sdk.jinrishici.com/v2/browser/jinrishici.js').then(() => {
    -          jinrishici.load(result =>{
    -            if (!{effect}) {
    -              const sub = !{JSON.stringify(subContent)}
    -              const content = result.data.content
    -              sub.unshift(content)
    -              typedJSFn.init(sub)
    -            } else {
    -              document.getElementById('subtitle').textContent = result.data.content
    -            }
    -          })
    -        })
    -      }
    -      typedJSFn.run(subtitleType)
    -
    -  default
    -    - subContent = subContent.length ? subContent : new Array(config.subtitle)
    -    script.
    -      function subtitleType () {
    -        if (!{effect}) {
    -          typedJSFn.init(!{JSON.stringify(subContent)})
    -        } else {
    -          document.getElementById("subtitle").textContent = !{JSON.stringify(subContent[0])}
    -        }
    -      }
    -      typedJSFn.run(subtitleType)
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/widget/card_ad.pug b/themes/butterfly/layout/includes/widget/card_ad.pug
    deleted file mode 100644
    index b8e00fd4..00000000
    --- a/themes/butterfly/layout/includes/widget/card_ad.pug
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -if theme.ad && theme.ad.aside
    -  .card-widget.ads-wrap
    -    != theme.ad.aside
    diff --git a/themes/butterfly/layout/includes/widget/card_announcement.pug b/themes/butterfly/layout/includes/widget/card_announcement.pug
    deleted file mode 100644
    index 9e636276..00000000
    --- a/themes/butterfly/layout/includes/widget/card_announcement.pug
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -if theme.aside.card_announcement.enable
    -  .card-widget.card-announcement
    -    .item-headline
    -      i.fas.fa-bullhorn.fa-shake
    -      span= _p('aside.card_announcement')
    -    .announcement_content!= theme.aside.card_announcement.content
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/widget/card_archives.pug b/themes/butterfly/layout/includes/widget/card_archives.pug
    deleted file mode 100644
    index bb0e78eb..00000000
    --- a/themes/butterfly/layout/includes/widget/card_archives.pug
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -if theme.aside.card_archives.enable
    -  .card-widget.card-archives
    -    - let type = theme.aside.card_archives.type || 'monthly'
    -    - let format = theme.aside.card_archives.format || 'MMMM YYYY'
    -    - let order = theme.aside.card_archives.order || -1
    -    - let limit = theme.aside.card_archives.limit === 0 ? 0 : theme.aside.card_archives.limit || 8
    -    != aside_archives({ type:type, format: format, order: order, limit: limit })
    diff --git a/themes/butterfly/layout/includes/widget/card_author.pug b/themes/butterfly/layout/includes/widget/card_author.pug
    deleted file mode 100644
    index 0a1e71ae..00000000
    --- a/themes/butterfly/layout/includes/widget/card_author.pug
    +++ /dev/null
    @@ -1,27 +0,0 @@
    -if theme.aside.card_author.enable
    -  .card-widget.card-info
    -    .is-center
    -      .avatar-img
    -        img(src=url_for(theme.avatar.img) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt="avatar")
    -      .author-info__name= config.author
    -      .author-info__description!= theme.aside.card_author.description || config.description
    -
    -    .card-info-data.site-data.is-center
    -      a(href=url_for(config.archive_dir) + '/')
    -        .headline= _p('aside.articles')
    -        .length-num= site.posts.length
    -      a(href=url_for(config.tag_dir) + '/')
    -        .headline= _p('aside.tags')
    -        .length-num= site.tags.length
    -      a(href=url_for(config.category_dir) + '/')
    -        .headline= _p('aside.categories') 
    -        .length-num= site.categories.length
    -
    -    if theme.aside.card_author.button.enable
    -      a#card-info-btn(href=theme.aside.card_author.button.link)
    -        i(class=theme.aside.card_author.button.icon)
    -        span=theme.aside.card_author.button.text
    -  
    -    if(theme.social)
    -        .card-info-social-icons.is-center
    -          !=partial('includes/header/social', {}, {cache: true})
    diff --git a/themes/butterfly/layout/includes/widget/card_bottom_self.pug b/themes/butterfly/layout/includes/widget/card_bottom_self.pug
    deleted file mode 100644
    index e32907dc..00000000
    --- a/themes/butterfly/layout/includes/widget/card_bottom_self.pug
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -if site.data.widget && site.data.widget.bottom
    -  each item in site.data.widget.bottom
    -    .card-widget(class=item.class_name id=item.id_name style=item.order ? `order: ${item.order}` : '')
    -      .item-headline
    -        i(class=item.icon)
    -        span=item.name
    -      .item-content
    -        !=item.html
    -
    diff --git a/themes/butterfly/layout/includes/widget/card_categories.pug b/themes/butterfly/layout/includes/widget/card_categories.pug
    deleted file mode 100644
    index 529ea55d..00000000
    --- a/themes/butterfly/layout/includes/widget/card_categories.pug
    +++ /dev/null
    @@ -1,4 +0,0 @@
    -if theme.aside.card_categories.enable
    -  if site.categories.length
    -    .card-widget.card-categories
    -      !=aside_categories({ limit: theme.aside.card_categories.limit === 0 ? 0 : theme.aside.card_categories.limit || 8 , expand: theme.aside.card_categories.expand })
    diff --git a/themes/butterfly/layout/includes/widget/card_newest_comment.pug b/themes/butterfly/layout/includes/widget/card_newest_comment.pug
    deleted file mode 100644
    index a7a213c6..00000000
    --- a/themes/butterfly/layout/includes/widget/card_newest_comment.pug
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -if theme.newest_comments.enable && theme.comments.use && !['Livere','Facebook Comments','Giscus'].includes(theme.comments.use[0])
    -  .card-widget#card-newest-comments
    -    .item-headline
    -      i.fas.fa-comment-dots
    -      span= _p('aside.card_newest_comments.headline')
    -    .aside-list
    -      span= _p('aside.card_newest_comments.loading_text')
    diff --git a/themes/butterfly/layout/includes/widget/card_post_series.pug b/themes/butterfly/layout/includes/widget/card_post_series.pug
    deleted file mode 100644
    index c216929e..00000000
    --- a/themes/butterfly/layout/includes/widget/card_post_series.pug
    +++ /dev/null
    @@ -1,21 +0,0 @@
    -if theme.aside.card_post_series.enable
    -  - const array = fragment_cache('seriesArr', groupPosts)
    -  .card-widget.card-post-series
    -    .item-headline
    -      i.fa-solid.fa-layer-group
    -      span= _p('aside.card_post_series')
    -    .aside-list
    -      each item in array[page.series]
    -        - const { path, title = _p('no_title'), cover, cover_type, date:dateA } = item
    -        - let link = url_for(path)
    -        - let no_cover = cover === false || !theme.cover.aside_enable ? 'no-cover' : ''
    -        .aside-list-item(class=no_cover)
    -          if cover && theme.cover.aside_enable
    -            a.thumbnail(href=link title=title)
    -              if cover_type === 'img'
    -                img(src=url_for(cover) onerror=`this.onerror=null;this.src='${url_for(theme.error_img.post_page)}'` alt=title)
    -              else
    -                div(style=`background: ${cover}`)
    -          .content
    -            a.title(href=link title=title)= title
    -            time(datetime=date_xml(dateA) title=_p('post.created') + ' ' + full_date(dateA)) #[=date(dateA, config.date_format)]
    diff --git a/themes/butterfly/layout/includes/widget/card_post_toc.pug b/themes/butterfly/layout/includes/widget/card_post_toc.pug
    deleted file mode 100644
    index 41542219..00000000
    --- a/themes/butterfly/layout/includes/widget/card_post_toc.pug
    +++ /dev/null
    @@ -1,15 +0,0 @@
    -- let tocNumber = page.toc_number !== undefined ? page.toc_number : theme.toc.number
    -- let tocExpand = page.toc_expand !== undefined ? page.toc_expand : theme.toc.expand
    -- let tocExpandClass = tocExpand ? 'is-expand' : ''
    -
    -#card-toc.card-widget
    -  .item-headline
    -    i.fas.fa-stream
    -    span= _p('aside.card_toc')
    -    span.toc-percentage
    -
    -  if (page.encrypt == true)
    -    .toc-content.toc-div-class(class=tocExpandClass style="display:none")!=toc(page.origin, {list_number: tocNumber})
    -  else 
    -    .toc-content(class=tocExpandClass)!=toc(page.content, {list_number: tocNumber})
    -      
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/widget/card_recent_post.pug b/themes/butterfly/layout/includes/widget/card_recent_post.pug
    deleted file mode 100644
    index dddf0fcb..00000000
    --- a/themes/butterfly/layout/includes/widget/card_recent_post.pug
    +++ /dev/null
    @@ -1,27 +0,0 @@
    -if theme.aside.card_recent_post.enable
    -  .card-widget.card-recent-post
    -    .item-headline
    -      i.fas.fa-history
    -      span= _p('aside.card_recent_post')
    -    .aside-list
    -      - let postLimit = theme.aside.card_recent_post.limit === 0 ? site.posts.length : theme.aside.card_recent_post.limit || 5
    -      - let sort = theme.aside.card_recent_post.sort === 'updated' ? 'updated' : 'date'
    -      - site.posts.sort(sort, -1).limit(postLimit).each(function(article){
    -        - let link = article.link || article.path
    -        - let title = article.title || _p('no_title')
    -        - let no_cover = article.cover === false || !theme.cover.aside_enable ? 'no-cover' : ''
    -        - let post_cover = article.cover
    -        .aside-list-item(class=no_cover)
    -          if post_cover && theme.cover.aside_enable
    -            a.thumbnail(href=url_for(link) title=title)
    -              if article.cover_type === 'img'
    -                img(src=url_for(post_cover) onerror=`this.onerror=null;this.src='${url_for(theme.error_img.post_page)}'` alt=title)
    -              else
    -                div(style=`background: ${post_cover}`)
    -          .content
    -            a.title(href=url_for(link) title=title)= title
    -            if theme.aside.card_recent_post.sort === 'updated'
    -              time(datetime=date_xml(article.updated) title=_p('post.updated') + ' ' + full_date(article.updated)) #[=date(article.updated, config.date_format)]
    -            else
    -              time(datetime=date_xml(article.date) title=_p('post.created') + ' ' + full_date(article.date)) #[=date(article.date, config.date_format)]
    -      - })
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/widget/card_tags.pug b/themes/butterfly/layout/includes/widget/card_tags.pug
    deleted file mode 100644
    index 49296b7b..00000000
    --- a/themes/butterfly/layout/includes/widget/card_tags.pug
    +++ /dev/null
    @@ -1,14 +0,0 @@
    -if theme.aside.card_tags.enable
    -  if site.tags.length
    -    .card-widget.card-tags
    -      .item-headline
    -        i.fas.fa-tags
    -        span= _p('aside.card_tags')
    -
    -      - let { limit, orderby, order } = theme.aside.card_tags
    -      - limit = limit === 0 ? 0 : limit || 40
    -
    -      if theme.aside.card_tags.color
    -        .card-tag-cloud!= cloudTags({source: site.tags, orderby: orderby, order: order, minfontsize: 1.15, maxfontsize: 1.45, limit: limit, unit: 'em'})
    -      else
    -        .card-tag-cloud!= tagcloud({orderby: orderby, order: order, min_font: 1.1, max_font: 1.5, amount: limit , color: true, start_color: '#999', end_color: '#99a9bf', unit: 'em'})
    diff --git a/themes/butterfly/layout/includes/widget/card_top_self.pug b/themes/butterfly/layout/includes/widget/card_top_self.pug
    deleted file mode 100644
    index 6e81059d..00000000
    --- a/themes/butterfly/layout/includes/widget/card_top_self.pug
    +++ /dev/null
    @@ -1,8 +0,0 @@
    -if site.data.widget && site.data.widget.top
    -  each item in site.data.widget.top
    -    .card-widget(class=item.class_name id=item.id_name)
    -      .item-headline
    -        i(class=item.icon)
    -        span=item.name
    -      .item-content
    -        !=item.html
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/includes/widget/card_webinfo.pug b/themes/butterfly/layout/includes/widget/card_webinfo.pug
    deleted file mode 100644
    index 9ff3de09..00000000
    --- a/themes/butterfly/layout/includes/widget/card_webinfo.pug
    +++ /dev/null
    @@ -1,35 +0,0 @@
    -if theme.aside.card_webinfo.enable
    -  .card-widget.card-webinfo
    -    .item-headline
    -      i.fas.fa-chart-line
    -      span= _p('aside.card_webinfo.headline')
    -    .webinfo
    -      if theme.aside.card_webinfo.post_count
    -        .webinfo-item
    -          .item-name= _p('aside.card_webinfo.article_name') + " :"
    -          .item-count= site.posts.length
    -      if theme.runtimeshow.enable
    -        .webinfo-item
    -          .item-name= _p('aside.card_webinfo.runtime.name') + " :"
    -          .item-count#runtimeshow(data-publishDate=date_xml(theme.runtimeshow.publish_date))
    -            i.fa-solid.fa-spinner.fa-spin
    -      if theme.wordcount.enable && theme.wordcount.total_wordcount
    -        .webinfo-item
    -          .item-name=_p('aside.card_webinfo.site_wordcount') + " :"
    -          .item-count=totalcount(site)
    -      if theme.busuanzi.site_uv
    -        .webinfo-item
    -          .item-name= _p('aside.card_webinfo.site_uv_name') + " :"
    -          .item-count#busuanzi_value_site_uv
    -            i.fa-solid.fa-spinner.fa-spin
    -      if theme.busuanzi.site_pv
    -        .webinfo-item
    -          .item-name= _p('aside.card_webinfo.site_pv_name') + " :"
    -          .item-count#busuanzi_value_site_pv
    -            i.fa-solid.fa-spinner.fa-spin
    -      if theme.aside.card_webinfo.last_push_date
    -        .webinfo-item
    -          .item-name= _p('aside.card_webinfo.last_push_date.name') + " :"
    -          .item-count#last-push-date(data-lastPushDate=date_xml(Date.now()))
    -            i.fa-solid.fa-spinner.fa-spin
    -
    diff --git a/themes/butterfly/layout/includes/widget/index.pug b/themes/butterfly/layout/includes/widget/index.pug
    deleted file mode 100644
    index 388ea1cc..00000000
    --- a/themes/butterfly/layout/includes/widget/index.pug
    +++ /dev/null
    @@ -1,36 +0,0 @@
    -#aside-content.aside-content
    -  //- post
    -  if is_post()
    -    - const tocStyle = page.toc_style_simple
    -    - const tocStyleVal = tocStyle === true || tocStyle === false ? tocStyle : theme.toc.style_simple
    -    if showToc && tocStyleVal
    -      .sticky_layout
    -        include ./card_post_toc.pug
    -    else
    -      !=partial('includes/widget/card_author', {}, {cache: true})
    -      !=partial('includes/widget/card_announcement', {}, {cache: true})
    -      !=partial('includes/widget/card_top_self', {}, {cache: true})
    -      .sticky_layout
    -        if showToc
    -          include ./card_post_toc.pug
    -        if page.series
    -          include ./card_post_series.pug
    -        !=partial('includes/widget/card_recent_post', {}, {cache: true})
    -        !=partial('includes/widget/card_ad', {}, {cache: true})
    -  else
    -    //- page
    -    !=partial('includes/widget/card_author', {}, {cache: true})
    -    !=partial('includes/widget/card_announcement', {}, {cache: true})
    -    !=partial('includes/widget/card_top_self', {}, {cache: true})
    -
    -    .sticky_layout
    -      if showToc
    -        include ./card_post_toc.pug
    -      !=partial('includes/widget/card_recent_post', {}, {cache: true})
    -      !=partial('includes/widget/card_ad', {}, {cache: true})
    -      !=partial('includes/widget/card_newest_comment', {}, {cache: true})
    -      !=partial('includes/widget/card_categories', {}, {cache: true})
    -      !=partial('includes/widget/card_tags', {}, {cache: true})
    -      !=partial('includes/widget/card_archives', {}, {cache: true})
    -      !=partial('includes/widget/card_webinfo', {}, {cache: true})
    -      !=partial('includes/widget/card_bottom_self', {}, {cache: true})
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/index.pug b/themes/butterfly/layout/index.pug
    deleted file mode 100644
    index 2655cb4b..00000000
    --- a/themes/butterfly/layout/index.pug
    +++ /dev/null
    @@ -1,7 +0,0 @@
    -extends includes/layout.pug
    -
    -block content
    -  include ./includes/mixins/post-ui.pug
    -  #recent-posts.recent-posts
    -    +postUI
    -    include includes/pagination.pug
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/page.pug b/themes/butterfly/layout/page.pug
    deleted file mode 100644
    index 6c810ef7..00000000
    --- a/themes/butterfly/layout/page.pug
    +++ /dev/null
    @@ -1,20 +0,0 @@
    -extends includes/layout.pug
    -
    -block content
    -  #page
    -    if top_img === false
    -      h1.page-title= page.title
    -
    -    case page.type
    -      when 'tags'
    -        include includes/page/tags.pug
    -      when 'link'
    -        include includes/page/flink.pug
    -      when 'categories'
    -        include includes/page/categories.pug
    -      default
    -        include includes/page/default-page.pug
    -
    -    if page.comments !== false && theme.comments && theme.comments.use
    -      - var commentsJsLoad = true
    -      !=partial('includes/third-party/comments/index', {}, {cache: true})
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/post.pug b/themes/butterfly/layout/post.pug
    deleted file mode 100644
    index f54ab7a0..00000000
    --- a/themes/butterfly/layout/post.pug
    +++ /dev/null
    @@ -1,32 +0,0 @@
    -extends includes/layout.pug
    -
    -block content
    -  #post
    -    if top_img === false
    -      include includes/header/post-info.pug
    -
    -    article#article-container.post-content!=page.content
    -    include includes/post/post-copyright.pug
    -    .tag_share
    -      if (theme.post_meta.post.tags)
    -        .post-meta__tag-list
    -          each item, index in page.tags.data
    -            a(href=url_for(item.path)).post-meta__tags #[=item.name]
    -      include includes/third-party/share/index.pug
    -        
    -    if theme.reward.enable && theme.reward.QR_code
    -      !=partial('includes/post/reward', {}, {cache: true})
    -
    -    //- ad
    -    if theme.ad && theme.ad.post
    -      .ads-wrap!=theme.ad.post
    -
    -    if theme.post_pagination
    -      include includes/pagination.pug
    -    if theme.related_post && theme.related_post.enable
    -      != related_posts(page,site.posts)
    -
    -    if page.comments !== false && theme.comments && theme.comments.use
    -      - var commentsJsLoad = true
    -      !=partial('includes/third-party/comments/index', {}, {cache: true})
    -      
    \ No newline at end of file
    diff --git a/themes/butterfly/layout/tag.pug b/themes/butterfly/layout/tag.pug
    deleted file mode 100644
    index 9f99658d..00000000
    --- a/themes/butterfly/layout/tag.pug
    +++ /dev/null
    @@ -1,14 +0,0 @@
    -extends includes/layout.pug
    -
    -block content
    -  if theme.tag_ui == 'index'
    -    include ./includes/mixins/post-ui.pug
    -    #recent-posts.recent-posts
    -      +postUI
    -      include includes/pagination.pug
    -  else
    -    include ./includes/mixins/article-sort.pug
    -    #tag
    -      .article-sort-title= _p('page.tag') + ' - ' + page.tag
    -      +articleSort(page.posts)
    -      include includes/pagination.pug
    \ No newline at end of file
    diff --git a/themes/butterfly/package.json b/themes/butterfly/package.json
    deleted file mode 100644
    index 0ed17d43..00000000
    --- a/themes/butterfly/package.json
    +++ /dev/null
    @@ -1,32 +0,0 @@
    -{
    -  "name": "hexo-theme-butterfly",
    -  "version": "4.10.0",
    -  "description": "A Simple and Card UI Design theme for Hexo",
    -  "main": "package.json",
    -  "scripts": {
    -    "test": "echo \"Error: no test specified\" && exit 1"
    -  },
    -  "keywords": [
    -    "hexo",
    -    "theme",
    -    "butterfly",
    -    "Card UI Design",
    -    "Jerry",
    -    "hexo-theme-butterfly"
    -  ],
    -  "repository": {
    -    "type" : "git",
    -    "url" : "https://github.com/jerryc127/hexo-theme-butterfly.git"
    -  },
    -  "bugs": {
    -    "url": "https://github.com/jerryc127/hexo-theme-butterfly/issues",
    -    "email": "my@crazywong.com"
    -  },
    -  "dependencies": {
    -    "hexo-renderer-stylus": "^3.0.0",
    -    "hexo-renderer-pug": "^3.0.0"
    -  },
    -  "homepage": "https://butterfly.js.org/",
    -  "author": "Jerry <my@crazywong.com>",
    -  "license": "Apache-2.0"
    -}
    diff --git a/themes/butterfly/plugins.yml b/themes/butterfly/plugins.yml
    deleted file mode 100644
    index b25c304a..00000000
    --- a/themes/butterfly/plugins.yml
    +++ /dev/null
    @@ -1,211 +0,0 @@
    -algolia_search:
    -  name: algoliasearch
    -  file: dist/algoliasearch-lite.umd.js
    -  version: 4.20.0
    -instantsearch:
    -  name: instantsearch.js
    -  file: dist/instantsearch.production.min.js
    -  version: 4.57.0
    -pjax:
    -  name: pjax
    -  file: pjax.min.js
    -  version: 0.2.8
    -gitalk:
    -  name: gitalk
    -  file: dist/gitalk.min.js
    -  version: 1.8.0
    -gitalk_css:
    -  name: gitalk
    -  file: dist/gitalk.css
    -  version: 1.8.0
    -blueimp_md5:
    -  name: blueimp-md5
    -  file: js/md5.min.js
    -  version: 2.19.0
    -valine:
    -  name: valine
    -  file: dist/Valine.min.js
    -  version: 1.5.1
    -disqusjs:
    -  name: disqusjs
    -  file: dist/browser/disqusjs.es2015.umd.min.js
    -  version: 3.0.2
    -disqusjs_css:
    -  name: disqusjs
    -  file: dist/browser/styles/disqusjs.css
    -  version: 3.0.2
    -twikoo:
    -  name: twikoo
    -  file: dist/twikoo.all.min.js
    -  version: 1.6.22
    -waline_js:
    -  name: '@waline/client'
    -  file: dist/waline.js
    -  other_name: waline
    -  version: 2.15.8
    -waline_css:
    -  name: '@waline/client'
    -  file: dist/waline.css
    -  other_name: waline
    -  version: 2.15.8
    -sharejs:
    -  name: butterfly-extsrc
    -  file: sharejs/dist/js/social-share.min.js
    -  version: 1.1.3
    -sharejs_css:
    -  name: butterfly-extsrc
    -  file: sharejs/dist/css/share.min.css
    -  version: 1.1.3
    -mathjax:
    -  name: mathjax
    -  file: es5/tex-mml-chtml.js
    -  version: 3.2.2
    -katex:
    -  name: katex
    -  file: dist/katex.min.css
    -  other_name: KaTeX
    -  version: 0.16.9
    -katex_copytex:
    -  name: katex
    -  file: dist/contrib/copy-tex.min.js
    -  other_name: KaTeX
    -  version: 0.16.9
    -mermaid:
    -  name: mermaid
    -  file: dist/mermaid.min.js
    -  version: 10.5.0
    -canvas_ribbon:
    -  name: butterfly-extsrc
    -  file: dist/canvas-ribbon.min.js
    -  version: 1.1.3
    -canvas_fluttering_ribbon:
    -  name: butterfly-extsrc
    -  file: dist/canvas-fluttering-ribbon.min.js
    -  version: 1.1.3
    -canvas_nest:
    -  name: butterfly-extsrc
    -  file: dist/canvas-nest.min.js
    -  version: 1.1.3
    -activate_power_mode:
    -  name: butterfly-extsrc
    -  file: dist/activate-power-mode.min.js
    -  version: 1.1.3
    -fireworks:
    -  name: butterfly-extsrc
    -  file: dist/fireworks.min.js
    -  version: 1.1.3
    -click_heart:
    -  name: butterfly-extsrc
    -  file: dist/click-heart.min.js
    -  version: 1.1.3
    -clickShowText:
    -  name: butterfly-extsrc
    -  file: dist/click-show-text.min.js
    -  version: 1.1.3
    -lazyload:
    -  name: vanilla-lazyload
    -  file: dist/lazyload.iife.min.js
    -  version: 17.8.4
    -instantpage:
    -  name: instant.page
    -  file: instantpage.js
    -  version: 5.2.0
    -typed:
    -  name: typed.js
    -  file: dist/typed.umd.js
    -  version: 2.0.16
    -pangu:
    -  name: pangu
    -  file: dist/browser/pangu.min.js
    -  version: 4.0.7
    -fancybox_css:
    -  name: '@fancyapps/ui'
    -  file: dist/fancybox/fancybox.css
    -  version: 5.0.24
    -  other_name: fancyapps-ui
    -fancybox:
    -  name: '@fancyapps/ui'
    -  file: dist/fancybox/fancybox.umd.js
    -  version: 5.0.24
    -  other_name: fancyapps-ui
    -medium_zoom:
    -  name: medium-zoom
    -  file: dist/medium-zoom.min.js
    -  version: 1.0.8
    -snackbar_css:
    -  name: node-snackbar
    -  file: dist/snackbar.min.css
    -  version: 0.1.16
    -snackbar:
    -  name: node-snackbar
    -  file: dist/snackbar.min.js
    -  version: 0.1.16
    -fontawesome:
    -  name: '@fortawesome/fontawesome-free'
    -  file: css/all.min.css
    -  other_name: font-awesome
    -  version: 6.4.2
    -egjs_infinitegrid:
    -  name: '@egjs/infinitegrid'
    -  other_name: egjs-infinitegrid
    -  file: dist/infinitegrid.min.js
    -  version: 4.10.1
    -aplayer_css:
    -  name: aplayer
    -  file: dist/APlayer.min.css
    -  version: 1.10.1
    -aplayer_js:
    -  name: aplayer
    -  file: dist/APlayer.min.js
    -  version: 1.10.1
    -meting_js:
    -  name: butterfly-extsrc
    -  file: metingjs/dist/Meting.min.js
    -  version: 1.1.3
    -prismjs_js:
    -  name: prismjs
    -  file: prism.js
    -  other_name: prism
    -  version: 1.29.0
    -prismjs_lineNumber_js:
    -  name: prismjs
    -  file: plugins/line-numbers/prism-line-numbers.min.js
    -  other_name: prism
    -  version: 1.29.0
    -prismjs_autoloader:
    -  name: prismjs
    -  file: plugins/autoloader/prism-autoloader.min.js
    -  other_name: prism
    -  version: 1.29.0
    -artalk_js:
    -  name: artalk
    -  file: dist/Artalk.js
    -  version: 2.6.3
    -artalk_css:
    -  name: artalk
    -  file: dist/Artalk.css
    -  version: 2.6.3
    -pace_js:
    -  name: pace-js
    -  other_name: pace
    -  file: pace.min.js
    -  version: 1.2.4
    -pace_default_css:
    -  name: pace-js
    -  other_name: pace
    -  file: themes/blue/pace-theme-minimal.css
    -  version: 1.2.4
    -docsearch_js:
    -  name: '@docsearch/js'
    -  other_name: docsearch-js
    -  file: dist/umd/index.js
    -  version: 3.5.2
    -docsearch_css:
    -  name: '@docsearch/css'
    -  other_name: docsearch-css
    -  file: dist/style.css
    -  version: 3.5.2
    -abcjs_basic_js:
    -  name: abcjs
    -  file: dist/abcjs-basic-min.js
    -  version: 6.2.2
    diff --git a/themes/butterfly/scripts/events/404.js b/themes/butterfly/scripts/events/404.js
    deleted file mode 100644
    index 02491ce7..00000000
    --- a/themes/butterfly/scripts/events/404.js
    +++ /dev/null
    @@ -1,18 +0,0 @@
    -/**
    - * Butterfly
    - * 404 error page
    - */
    -
    -'use strict'
    -
    -hexo.extend.generator.register('404', function (locals) {
    -  if (!hexo.theme.config.error_404.enable) return
    -  return {
    -    path: '404.html',
    -    layout: ['page'],
    -    data: {
    -      type: '404',
    -      top_img: false
    -    }
    -  }
    -})
    diff --git a/themes/butterfly/scripts/events/cdn.js b/themes/butterfly/scripts/events/cdn.js
    deleted file mode 100644
    index b83404fe..00000000
    --- a/themes/butterfly/scripts/events/cdn.js
    +++ /dev/null
    @@ -1,97 +0,0 @@
    -/**
    - * Butterfly
    - * Merge CDN
    - */
    -
    -'use strict'
    -
    -const { version } = require('../../package.json')
    -const path = require('path')
    -
    -hexo.extend.filter.register('before_generate', () => {
    -  const themeConfig = hexo.theme.config
    -  const { CDN } = themeConfig
    -
    -  const thirdPartySrc = hexo.render.renderSync({ path: path.join(hexo.theme_dir, '/plugins.yml'), engine: 'yaml' })
    -  const internalSrc = {
    -    main: {
    -      name: 'hexo-theme-butterfly',
    -      file: 'js/main.js',
    -      version
    -    },
    -    utils: {
    -      name: 'hexo-theme-butterfly',
    -      file: 'js/utils.js',
    -      version
    -    },
    -    translate: {
    -      name: 'hexo-theme-butterfly',
    -      file: 'js/tw_cn.js',
    -      version
    -    },
    -    local_search: {
    -      name: 'hexo-theme-butterfly',
    -      file: 'js/search/local-search.js',
    -      version
    -    },
    -    algolia_js: {
    -      name: 'hexo-theme-butterfly',
    -      file: 'js/search/algolia.js',
    -      version
    -    }
    -  }
    -
    -  const minFile = file => {
    -    return file.replace(/(?<!\.min)\.(js|css)$/g, ext => '.min' + ext)
    -  }
    -
    -  const createCDNLink = (data, type, cond = '') => {
    -    Object.keys(data).forEach(key => {
    -      let { name, version, file, other_name } = data[key]
    -      const cdnjs_name = other_name || name
    -      const cdnjs_file = file.replace(/^[lib|dist]*\/|browser\//g, '')
    -      const min_cdnjs_file = minFile(cdnjs_file)
    -      if (cond === 'internal') file = `source/${file}`
    -      const min_file = minFile(file)
    -      const verType = CDN.version ? (type === 'local' ? `?v=${version}` : `@${version}`) : ''
    -
    -      const value = {
    -        version,
    -        name,
    -        file,
    -        cdnjs_file,
    -        min_file,
    -        min_cdnjs_file,
    -        cdnjs_name
    -      }
    -
    -      const cdnSource = {
    -        local: cond === 'internal' ? `${cdnjs_file + verType}` : `/pluginsSrc/${name}/${file + verType}`,
    -        jsdelivr: `https://cdn.jsdelivr.net/npm/${name}${verType}/${min_file}`,
    -        unpkg: `https://unpkg.com/${name}${verType}/${file}`,
    -        cdnjs: `https://cdnjs.cloudflare.com/ajax/libs/${cdnjs_name}/${version}/${min_cdnjs_file}`,
    -        custom: (CDN.custom_format || '').replace(/\$\{(.+?)\}/g, (match, $1) => value[$1])
    -      }
    -
    -      data[key] = cdnSource[type]
    -    })
    -
    -    if (cond === 'internal') data.main_css = 'css/index.css' + (CDN.version ? `?v=${version}` : '')
    -    return data
    -  }
    -
    -  // delete null value
    -  const deleteNullValue = obj => {
    -    if (!obj) return
    -    for (const i in obj) {
    -      obj[i] === null && delete obj[i]
    -    }
    -    return obj
    -  }
    -
    -  themeConfig.asset = Object.assign(
    -    createCDNLink(internalSrc, CDN.internal_provider, 'internal'),
    -    createCDNLink(thirdPartySrc, CDN.third_party_provider),
    -    deleteNullValue(CDN.option)
    -  )
    -})
    diff --git a/themes/butterfly/scripts/events/comment.js b/themes/butterfly/scripts/events/comment.js
    deleted file mode 100644
    index ebbe439a..00000000
    --- a/themes/butterfly/scripts/events/comment.js
    +++ /dev/null
    @@ -1,14 +0,0 @@
    -/**
    - * Capitalize the first letter of comment name
    - */
    -
    -hexo.extend.filter.register('before_generate', () => {
    -  const themeConfig = hexo.theme.config
    -  let { use } = themeConfig.comments
    -  if (!use) return
    -  if (typeof use === 'string') {
    -    use = use.split(',')
    -  }
    -  const newArray = use.map(item => item.toLowerCase().replace(/\b[a-z]/g, s => s.toUpperCase()))
    -  themeConfig.comments.use = newArray
    -})
    diff --git a/themes/butterfly/scripts/events/init.js b/themes/butterfly/scripts/events/init.js
    deleted file mode 100644
    index 36304d89..00000000
    --- a/themes/butterfly/scripts/events/init.js
    +++ /dev/null
    @@ -1,20 +0,0 @@
    -hexo.extend.filter.register('before_generate', () => {
    -  // Get first two digits of the Hexo version number
    -  const { version, log, locals } = hexo
    -  const hexoVer = version.replace(/(^.*\..*)\..*/, '$1')
    -
    -  if (hexoVer < 5.3) {
    -    log.error('Please update Hexo to V5.3.0 or higher!')
    -    log.error('請把 Hexo 升級到 V5.3.0 或更高的版本!')
    -    process.exit(-1)
    -  }
    -
    -  if (locals.get) {
    -    const data = locals.get('data')
    -    if (data && data.butterfly) {
    -      log.error("'butterfly.yml' is deprecated. Please use '_config.butterfly.yml'")
    -      log.error("'butterfly.yml' 已經棄用,請使用 '_config.butterfly.yml'")
    -      process.exit(-1)
    -    }
    -  }
    -})
    diff --git a/themes/butterfly/scripts/events/stylus.js b/themes/butterfly/scripts/events/stylus.js
    deleted file mode 100644
    index 2e6b802d..00000000
    --- a/themes/butterfly/scripts/events/stylus.js
    +++ /dev/null
    @@ -1,16 +0,0 @@
    -/**
    - * Stylus renderer
    - */
    -
    -'use strict'
    -
    -hexo.extend.filter.register('stylus:renderer', style => {
    -  const { enable: highlightEnable, line_number: highlightLineNumber } = hexo.config.highlight
    -  const { enable: prismjsEnable, line_number: prismjsLineNumber } = hexo.config.prismjs
    -
    -  style.define('$highlight_enable', highlightEnable)
    -    .define('$highlight_line_number', highlightLineNumber)
    -    .define('$prismjs_enable', prismjsEnable)
    -    .define('$prismjs_line_number', prismjsLineNumber)
    -  // .import(`${this.source_dir.replace(/\\/g, '/')}_data/css/*`)
    -})
    diff --git a/themes/butterfly/scripts/events/welcome.js b/themes/butterfly/scripts/events/welcome.js
    deleted file mode 100644
    index f4c018ab..00000000
    --- a/themes/butterfly/scripts/events/welcome.js
    +++ /dev/null
    @@ -1,13 +0,0 @@
    -hexo.on('ready', () => {
    -  const { version } = require('../../package.json')
    -  hexo.log.info(`
    -  ===================================================================
    -      #####  #    # ##### ##### ###### #####  ###### #      #   #
    -      #    # #    #   #     #   #      #    # #      #       # #
    -      #####  #    #   #     #   #####  #    # #####  #        #
    -      #    # #    #   #     #   #      #####  #      #        #
    -      #    # #    #   #     #   #      #   #  #      #        #
    -      #####   ####    #     #   ###### #    # #      ######   #
    -                            ${version}
    -  ===================================================================`)
    -})
    diff --git a/themes/butterfly/scripts/filters/post_lazyload.js b/themes/butterfly/scripts/filters/post_lazyload.js
    deleted file mode 100644
    index cecc6ce2..00000000
    --- a/themes/butterfly/scripts/filters/post_lazyload.js
    +++ /dev/null
    @@ -1,27 +0,0 @@
    -/**
    - * Butterfly
    - * lazyload
    - * replace src to data-lazy-src
    - */
    -
    -'use strict'
    -
    -const urlFor = require('hexo-util').url_for.bind(hexo)
    -
    -const lazyload = htmlContent => {
    -  const bg = hexo.theme.config.lazyload.placeholder ? urlFor(hexo.theme.config.lazyload.placeholder) : 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
    -  return htmlContent.replace(/(<img.*? src=)/ig, `$1 "${bg}" data-lazy-src=`)
    -}
    -
    -hexo.extend.filter.register('after_render:html', data => {
    -  const { enable, field } = hexo.theme.config.lazyload
    -  if (!enable || field !== 'site') return
    -  return lazyload(data)
    -})
    -
    -hexo.extend.filter.register('after_post_render', data => {
    -  const { enable, field } = hexo.theme.config.lazyload
    -  if (!enable || field !== 'post') return
    -  data.content = lazyload(data.content)
    -  return data
    -})
    diff --git a/themes/butterfly/scripts/filters/random_cover.js b/themes/butterfly/scripts/filters/random_cover.js
    deleted file mode 100644
    index 7dac3cf8..00000000
    --- a/themes/butterfly/scripts/filters/random_cover.js
    +++ /dev/null
    @@ -1,40 +0,0 @@
    -/**
    - * Butterfly
    - * ramdom cover
    - */
    -
    -'use strict'
    -
    -hexo.extend.filter.register('before_post_render', data => {
    -  const imgTestReg = /\.(png|jpe?g|gif|svg|webp)(\?.*)?$/i
    -  let { cover: coverVal, top_img: topImg } = data
    -
    -  // Add path to top_img and cover if post_asset_folder is enabled
    -  if (hexo.config.post_asset_folder) {
    -    if (topImg && topImg.indexOf('/') === -1 && imgTestReg.test(topImg)) data.top_img = `${data.path}${topImg}`
    -    if (coverVal && coverVal.indexOf('/') === -1 && imgTestReg.test(coverVal)) data.cover = `${data.path}${coverVal}`
    -  }
    -
    -  const randomCoverFn = () => {
    -    const { cover: { default_cover: defaultCover } } = hexo.theme.config
    -    if (!defaultCover) return false
    -    if (!Array.isArray(defaultCover)) return defaultCover
    -    const num = Math.floor(Math.random() * defaultCover.length)
    -    return defaultCover[num]
    -  }
    -
    -  if (coverVal === false) return data
    -
    -  // If cover is not set, use random cover
    -  if (!coverVal) {
    -    const randomCover = randomCoverFn()
    -    data.cover = randomCover
    -    coverVal = randomCover // update coverVal
    -  }
    -
    -  if (coverVal && (coverVal.indexOf('//') !== -1 || imgTestReg.test(coverVal))) {
    -    data.cover_type = 'img'
    -  }
    -
    -  return data
    -})
    diff --git a/themes/butterfly/scripts/helpers/aside_archives.js b/themes/butterfly/scripts/helpers/aside_archives.js
    deleted file mode 100644
    index 779c1d45..00000000
    --- a/themes/butterfly/scripts/helpers/aside_archives.js
    +++ /dev/null
    @@ -1,113 +0,0 @@
    -/**
    - * Butterfly
    - * for aside archives
    - */
    -
    -'use strict'
    -
    -hexo.extend.helper.register('aside_archives', function (options = {}) {
    -  const { config } = this
    -  const archiveDir = config.archive_dir
    -  const { timezone } = config
    -  const lang = toMomentLocale(this.page.lang || this.page.language || config.language)
    -  let { format } = options
    -  const type = options.type || 'monthly'
    -  const { transform } = options
    -  const showCount = Object.prototype.hasOwnProperty.call(options, 'show_count') ? options.show_count : true
    -  const order = options.order || -1
    -  const compareFunc = type === 'monthly'
    -    ? (yearA, monthA, yearB, monthB) => yearA === yearB && monthA === monthB
    -    : (yearA, monthA, yearB, monthB) => yearA === yearB
    -  const limit = options.limit
    -  let result = ''
    -
    -  if (!format) {
    -    format = type === 'monthly' ? 'MMMM YYYY' : 'YYYY'
    -  }
    -
    -  const posts = this.site.posts.sort('date', order)
    -  if (!posts.length) return result
    -
    -  const data = []
    -  let length = 0
    -
    -  posts.forEach(post => {
    -    // Clone the date object to avoid pollution
    -    let date = post.date.clone()
    -
    -    if (timezone) date = date.tz(timezone)
    -
    -    const year = date.year()
    -    const month = date.month() + 1
    -    const lastData = data[length - 1]
    -
    -    if (!lastData || !compareFunc(lastData.year, lastData.month, year, month)) {
    -      if (lang) date = date.locale(lang)
    -      const name = date.format(format)
    -      length = data.push({
    -        name,
    -        year,
    -        month,
    -        count: 1
    -      })
    -    } else {
    -      lastData.count++
    -    }
    -  })
    -
    -  const link = item => {
    -    let url = `${archiveDir}/${item.year}/`
    -
    -    if (type === 'monthly') {
    -      if (item.month < 10) url += '0'
    -      url += `${item.month}/`
    -    }
    -
    -    return this.url_for(url)
    -  }
    -
    -  const len = data.length
    -  const Judge = limit === 0 ? len : Math.min(len, limit)
    -
    -  result += `<div class="item-headline"><i class="fas fa-archive"></i><span>${this._p('aside.card_archives')}</span>`
    -
    -  if (len > Judge) {
    -    result += `<a class="card-more-btn" href="${this.url_for(archiveDir)}/" title="${this._p('aside.more_button')}">
    -    <i class="fas fa-angle-right"></i></a>`
    -  }
    -
    -  result += '</div><ul class="card-archive-list">'
    -
    -  for (let i = 0; i < Judge; i++) {
    -    const item = data[i]
    -
    -    result += '<li class="card-archive-list-item">'
    -
    -    result += `<a class="card-archive-list-link" href="${link(item)}">`
    -    result += '<span class="card-archive-list-date">'
    -    result += transform ? transform(item.name) : item.name
    -    result += '</span>'
    -
    -    if (showCount) {
    -      result += `<span class="card-archive-list-count">${item.count}</span>`
    -    }
    -    result += '</a>'
    -    result += '</li>'
    -  }
    -
    -  result += '</ul>'
    -  return result
    -})
    -
    -const toMomentLocale = function (lang) {
    -  if (lang === undefined) {
    -    return undefined
    -  }
    -
    -  // moment.locale('') equals moment.locale('en')
    -  // moment.locale(null) equals moment.locale('en')
    -  if (!lang || lang === 'en' || lang === 'default') {
    -    return 'en'
    -  }
    -  return lang.toLowerCase().replace('_', '-')
    -}
    diff --git a/themes/butterfly/scripts/helpers/aside_categories.js b/themes/butterfly/scripts/helpers/aside_categories.js
    deleted file mode 100644
    index 244b163e..00000000
    --- a/themes/butterfly/scripts/helpers/aside_categories.js
    +++ /dev/null
    @@ -1,99 +0,0 @@
    -/**
    - * Butterfly
    - * for aside categories
    - */
    -
    -'use strict'
    -
    -hexo.extend.helper.register('aside_categories', function (categories, options) {
    -  if (!options && (!categories || !Object.prototype.hasOwnProperty.call(categories, 'length'))
    -  ) {
    -    options = categories
    -    categories = this.site.categories
    -  }
    -
    -  if (!categories || !categories.length) return ''
    -  options = options || {}
    -  const { config } = this
    -  const showCount = Object.prototype.hasOwnProperty.call(options, 'show_count')
    -    ? options.show_count
    -    : true
    -  const depth = options.depth ? parseInt(options.depth, 10) : 0
    -  const orderby = options.orderby || 'name'
    -  const order = options.order || 1
    -  const categoryDir = this.url_for(config.category_dir)
    -  const limit = options.limit === 0 ? categories.length : options.limit
    -  const isExpand = options.expand !== 'none'
    -  const expandClass = isExpand && options.expand === true ? 'expand' : ''
    -  const buttonLabel = this._p('aside.more_button')
    -  const prepareQuery = (parent) => {
    -    const query = {}
    -    if (parent) { query.parent = parent } else { query.parent = { $exists: false } }
    -    return categories.find(query).sort(orderby, order).filter((cat) => cat.length)
    -  }
    -  let expandBtn = ''
    -
    -  const hierarchicalList = (t, level, parent, topparent = true) => {
    -    let result = ''
    -    const isTopParent = topparent
    -    if (t > 0) {
    -      prepareQuery(parent).forEach((cat, i) => {
    -        if (t > 0) {
    -          t = t - 1
    -          let child
    -          if (!depth || level + 1 < depth) {
    -            const childList = hierarchicalList(t, level + 1, cat._id, false)
    -            child = childList[0]
    -            t = childList[1]
    -          }
    -
    -          const parentClass = isExpand && isTopParent && child ? 'parent' : ''
    -
    -          result += `<li class="card-category-list-item ${parentClass}">`
    -
    -          result += `<a class="card-category-list-link" href="${this.url_for(cat.path)}">`
    -
    -          result += `<span class="card-category-list-name">${cat.name}</span>`
    -
    -          if (showCount) {
    -            result += `<span class="card-category-list-count">${cat.length}</span>`
    -          }
    -
    -          if (isExpand && isTopParent && child) {
    -            expandBtn = ' expandBtn'
    -            result += `<i class="fas fa-caret-left ${expandClass}"></i>`
    -          }
    -
    -          result += '</a>'
    -
    -          if (child) {
    -            result += `<ul class="card-category-list child">${child}</ul>`
    -          }
    -
    -          result += '</li>'
    -        }
    -      })
    -    }
    -
    -    return [result, t]
    -  }
    -
    -  const list = hierarchicalList(limit, 0)
    -
    -  const moreButton = function () {
    -    if (categories.length <= limit) return ''
    -    const moreHtml = `<a class="card-more-btn" href="${categoryDir}/" title="${buttonLabel}">
    -    <i class="fas fa-angle-right"></i></a>`
    -
    -    return moreHtml
    -  }
    -
    -  return `<div class="item-headline">
    -            <i class="fas fa-folder-open"></i>
    -            <span>${this._p('aside.card_categories')}</span>
    -            ${moreButton()}
    -            </div>
    -            <ul class="card-category-list${expandBtn}" id="aside-cat-list">
    -            ${list[0]}
    -            </ul>`
    -})
    diff --git a/themes/butterfly/scripts/helpers/findArchiveLength.js b/themes/butterfly/scripts/helpers/findArchiveLength.js
    deleted file mode 100644
    index 152b15ec..00000000
    --- a/themes/butterfly/scripts/helpers/findArchiveLength.js
    +++ /dev/null
    @@ -1,58 +0,0 @@
    -hexo.extend.helper.register('getArchiveLength', function () {
    -  const { archive_generator: archiveGenerator } = hexo.config
    -  if (archiveGenerator && archiveGenerator.enable === false) return this.site.posts.length
    -  const { yearly, monthly, daily } = archiveGenerator
    -  const { year, month, day } = this.page
    -  if (yearly === false || !year) return this.site.posts.length
    -
    -  const posts = this.site.posts.sort('date')
    -
    -  const compareFunc = (type, y1, m1, d1, y2, m2, d2) => {
    -    switch (type) {
    -      case 'year':
    -        return y1 === y2
    -      case 'month':
    -        return y1 === y2 && m1 === m2
    -      case 'day':
    -        return y1 === y2 && m1 === m2 && d1 === d2
    -      default:
    -        return false
    -    }
    -  }
    -
    -  const generateDateObj = (type) => {
    -    return posts.reduce((dateObj, post) => {
    -      const date = post.date.clone()
    -      const year = date.year()
    -      const month = date.month() + 1
    -      const day = date.date()
    -      const lastData = dateObj[dateObj.length - 1]
    -
    -      if (!lastData || !compareFunc(type, lastData.year, lastData.month, lastData.day, year, month, day)) {
    -        const name = type === 'year' ? year : type === 'month' ? `${year}-${month}` : `${year}-${month}-${day}`
    -        dateObj.push({
    -          name,
    -          year,
    -          month,
    -          day,
    -          count: 1
    -        })
    -      } else {
    -        lastData.count++
    -      }
    -
    -      return dateObj
    -    }, [])
    -  }
    -
    -  const data = this.fragment_cache('createArchiveObj', () => {
    -    const dateObjs = []
    -    if (yearly) dateObjs.push(...generateDateObj('year'))
    -    if (monthly) dateObjs.push(...generateDateObj('month'))
    -    if (daily) dateObjs.push(...generateDateObj('day'))
    -    return dateObjs
    -  })
    -
    -  const name = month ? (day ? `${year}-${month}-${day}` : `${year}-${month}`) : year
    -  return data.find(item => item.name === name).count
    -})
    diff --git a/themes/butterfly/scripts/helpers/inject_head_js.js b/themes/butterfly/scripts/helpers/inject_head_js.js
    deleted file mode 100644
    index 5871fd74..00000000
    --- a/themes/butterfly/scripts/helpers/inject_head_js.js
    +++ /dev/null
    @@ -1,183 +0,0 @@
    -/**
    - * Butterfly
    - * inject js to head
    - */
    -
    -'use strict'
    -
    -hexo.extend.helper.register('inject_head_js', function () {
    -  const { darkmode, aside } = this.theme
    -  const start = darkmode.start || 6
    -  const end = darkmode.end || 18
    -  const { theme_color } = hexo.theme.config
    -  const themeColorLight = (theme_color && theme_color.enable && theme_color.meta_theme_color_light) || '#ffffff'
    -  const themeColorDark = (theme_color && theme_color.enable && theme_color.meta_theme_color_dark) || '#0d0d0d'
    -
    -  const createLocalStore = () => {
    -    return `
    -      win.saveToLocal = {
    -        set: (key, value, ttl) => {
    -          if (ttl === 0) return
    -          const now = Date.now()
    -          const expiry = now + ttl * 86400000
    -          const item = {
    -            value,
    -            expiry
    -          }
    -          localStorage.setItem(key, JSON.stringify(item))
    -        },
    -      
    -        get: key => {
    -          const itemStr = localStorage.getItem(key)
    -      
    -          if (!itemStr) {
    -            return undefined
    -          }
    -          const item = JSON.parse(itemStr)
    -          const now = Date.now()
    -      
    -          if (now > item.expiry) {
    -            localStorage.removeItem(key)
    -            return undefined
    -          }
    -          return item.value
    -        }
    -      }
    -    `
    -  }
    -
    -  // https://stackoverflow.com/questions/16839698/jquery-getscript-alternative-in-native-javascript
    -  const createGetScript = () => {
    -    return `
    -      win.getScript = (url, attr = {}) => new Promise((resolve, reject) => {
    -        const script = document.createElement('script')
    -        script.src = url
    -        script.async = true
    -        script.onerror = reject
    -        script.onload = script.onreadystatechange = function() {
    -          const loadState = this.readyState
    -          if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
    -          script.onload = script.onreadystatechange = null
    -          resolve()
    -        }
    -
    -        Object.keys(attr).forEach(key => {
    -          script.setAttribute(key, attr[key])
    -        })
    -
    -        document.head.appendChild(script)
    -      })
    -    `
    -  }
    -
    -  const createGetCSS = () => {
    -    return `
    -      win.getCSS = (url, id = false) => new Promise((resolve, reject) => {
    -        const link = document.createElement('link')
    -        link.rel = 'stylesheet'
    -        link.href = url
    -        if (id) link.id = id
    -        link.onerror = reject
    -        link.onload = link.onreadystatechange = function() {
    -          const loadState = this.readyState
    -          if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
    -          link.onload = link.onreadystatechange = null
    -          resolve()
    -        }
    -        document.head.appendChild(link)
    -      })
    -    `
    -  }
    -
    -  const createDarkmodeJs = () => {
    -    if (!darkmode.enable) return ''
    -
    -    let darkmodeJs = `
    -      win.activateDarkMode = () => {
    -        document.documentElement.setAttribute('data-theme', 'dark')
    -        if (document.querySelector('meta[name="theme-color"]') !== null) {
    -          document.querySelector('meta[name="theme-color"]').setAttribute('content', '${themeColorDark}')
    -        }
    -      }
    -      win.activateLightMode = () => {
    -        document.documentElement.setAttribute('data-theme', 'light')
    -        if (document.querySelector('meta[name="theme-color"]') !== null) {
    -          document.querySelector('meta[name="theme-color"]').setAttribute('content', '${themeColorLight}')
    -        }
    -      }
    -      const t = saveToLocal.get('theme')
    -    `
    -
    -    const autoChangeMode = darkmode.autoChangeMode
    -
    -    if (autoChangeMode === 1) {
    -      darkmodeJs += `
    -          const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches
    -          const isLightMode = window.matchMedia('(prefers-color-scheme: light)').matches
    -          const isNotSpecified = window.matchMedia('(prefers-color-scheme: no-preference)').matches
    -          const hasNoSupport = !isDarkMode && !isLightMode && !isNotSpecified
    -
    -          if (t === undefined) {
    -            if (isLightMode) activateLightMode()
    -            else if (isDarkMode) activateDarkMode()
    -            else if (isNotSpecified || hasNoSupport) {
    -              const now = new Date()
    -              const hour = now.getHours()
    -              const isNight = hour <= ${start} || hour >= ${end}
    -              isNight ? activateDarkMode() : activateLightMode()
    -            }
    -            window.matchMedia('(prefers-color-scheme: dark)').addListener(e => {
    -              if (saveToLocal.get('theme') === undefined) {
    -                e.matches ? activateDarkMode() : activateLightMode()
    -              }
    -            })
    -          } else if (t === 'light') activateLightMode()
    -          else activateDarkMode()
    -        `
    -    } else if (autoChangeMode === 2) {
    -      darkmodeJs += `
    -          const now = new Date()
    -          const hour = now.getHours()
    -          const isNight = hour <= ${start} || hour >= ${end}
    -          if (t === undefined) isNight ? activateDarkMode() : activateLightMode()
    -          else if (t === 'light') activateLightMode()
    -          else activateDarkMode()
    -        `
    -    } else {
    -      darkmodeJs += `
    -        if (t === 'dark') activateDarkMode()
    -        else if (t === 'light') activateLightMode()
    -      `
    -    }
    -
    -    return darkmodeJs
    -  }
    -
    -  const createAsideStatus = () => {
    -    if (!aside.enable || !aside.button) return ''
    -
    -    return `
    -      const asideStatus = saveToLocal.get('aside-status')
    -      if (asideStatus !== undefined) {
    -        if (asideStatus === 'hide') {
    -          document.documentElement.classList.add('hide-aside')
    -        } else {
    -          document.documentElement.classList.remove('hide-aside')
    -        }
    -      }
    -    `
    -  }
    -
    -  const createDetectApple = () => {
    -    return `
    -      const detectApple = () => {
    -        if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
    -          document.documentElement.classList.add('apple')
    -        }
    -      }
    -      detectApple()
    -    `
    -  }
    -
    -  return `<script>(win=>{${createLocalStore() + createGetScript() + createGetCSS() + createDarkmodeJs() + createAsideStatus() + createDetectApple()}})(window)</script>`
    -})
    diff --git a/themes/butterfly/scripts/helpers/page.js b/themes/butterfly/scripts/helpers/page.js
    deleted file mode 100644
    index 6c773e34..00000000
    --- a/themes/butterfly/scripts/helpers/page.js
    +++ /dev/null
    @@ -1,88 +0,0 @@
    -'use strict'
    -
    -const { stripHTML, escapeHTML, prettyUrls } = require('hexo-util')
    -const crypto = require('crypto')
    -
    -hexo.extend.helper.register('page_description', function () {
    -  const { config, page } = this
    -  let description = page.description || page.content || page.title || config.description
    -
    -  if (description) {
    -    description = escapeHTML(stripHTML(description).substring(0, 150)
    -      .trim()
    -    ).replace(/\n/g, ' ')
    -    return description
    -  }
    -})
    -
    -hexo.extend.helper.register('cloudTags', function (options = {}) {
    -  const env = this
    -  let { source, minfontsize, maxfontsize, limit, unit, orderby, order } = options
    -  unit = unit || 'px'
    -
    -  let result = ''
    -  if (limit > 0) {
    -    source = source.limit(limit)
    -  }
    -
    -  const sizes = []
    -  source.sort('length').forEach(tag => {
    -    const { length } = tag
    -    if (sizes.includes(length)) return
    -    sizes.push(length)
    -  })
    -
    -  const length = sizes.length - 1
    -  source.sort(orderby, order).forEach(tag => {
    -    const ratio = length ? sizes.indexOf(tag.length) / length : 0
    -    const size = minfontsize + ((maxfontsize - minfontsize) * ratio)
    -    let style = `font-size: ${parseFloat(size.toFixed(2))}${unit};`
    -    const color = 'rgb(' + Math.floor(Math.random() * 201) + ', ' + Math.floor(Math.random() * 201) + ', ' + Math.floor(Math.random() * 201) + ')' // 0,0,0 -> 200,200,200
    -    style += ` color: ${color}`
    -    result += `<a href="${env.url_for(tag.path)}" style="${style}">${tag.name}</a>`
    -  })
    -  return result
    -})
    -
    -hexo.extend.helper.register('urlNoIndex', function (url = null, trailingIndex = false, trailingHtml = false) {
    -  return prettyUrls(url || this.url, { trailing_index: trailingIndex, trailing_html: trailingHtml })
    -})
    -
    -hexo.extend.helper.register('md5', function (path) {
    -  return crypto.createHash('md5').update(decodeURI(this.url_for(path))).digest('hex')
    -})
    -
    -hexo.extend.helper.register('injectHtml', function (data) {
    -  if (!data) return ''
    -  return data.join('')
    -})
    -
    -hexo.extend.helper.register('findArchivesTitle', function (page, menu, date) {
    -  if (page.year) {
    -    const dateStr = page.month ? `${page.year}-${page.month}` : `${page.year}`
    -    const dateFormat = page.month ? hexo.theme.config.aside.card_archives.format : 'YYYY'
    -    return date(dateStr, dateFormat)
    -  }
    -
    -  const defaultTitle = this._p('page.archives')
    -  if (!menu) return defaultTitle
    -
    -  const loop = (m) => {
    -    for (const key in m) {
    -      if (typeof m[key] === 'object') {
    -        loop(m[key])
    -      }
    -
    -      if (/\/archives\//.test(m[key])) {
    -        return key
    -      }
    -    }
    -  }
    -
    -  return loop(menu) || defaultTitle
    -})
    -
    -hexo.extend.helper.register('isImgOrUrl', function (path) {
    -  const imgTestReg = /\.(png|jpe?g|gif|svg|webp)(\?.*)?$/i
    -  return path.indexOf('//') !== -1 || imgTestReg.test(path)
    -})
    diff --git a/themes/butterfly/scripts/helpers/related_post.js b/themes/butterfly/scripts/helpers/related_post.js
    deleted file mode 100644
    index 9a46f684..00000000
    --- a/themes/butterfly/scripts/helpers/related_post.js
    +++ /dev/null
    @@ -1,100 +0,0 @@
    -/**
    - * Butterfly
    - * Related Posts
    - * According the tag
    - */
    -
    -'use strict'
    -
    -hexo.extend.helper.register('related_posts', function (currentPost, allPosts) {
    -  let relatedPosts = []
    -  currentPost.tags.forEach(function (tag) {
    -    allPosts.forEach(function (post) {
    -      if (isTagRelated(tag.name, post.tags)) {
    -        const relatedPost = {
    -          title: post.title,
    -          path: post.path,
    -          cover: post.cover,
    -          cover_type: post.cover_type,
    -          weight: 1,
    -          updated: post.updated,
    -          created: post.date
    -        }
    -        const index = findItem(relatedPosts, 'path', post.path)
    -        if (index !== -1) {
    -          relatedPosts[index].weight += 1
    -        } else {
    -          if (currentPost.path !== post.path) {
    -            relatedPosts.push(relatedPost)
    -          }
    -        }
    -      }
    -    })
    -  })
    -  if (relatedPosts.length === 0) {
    -    return ''
    -  }
    -  let result = ''
    -  const hexoConfig = hexo.config
    -  const config = hexo.theme.config
    -
    -  const limitNum = config.related_post.limit || 6
    -  const dateType = config.related_post.date_type || 'created'
    -  const headlineLang = this._p('post.recommend')
    -
    -  relatedPosts = relatedPosts.sort(compare('weight'))
    -
    -  if (relatedPosts.length > 0) {
    -    result += '<div class="relatedPosts">'
    -    result += `<div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>${headlineLang}</span></div>`
    -    result += '<div class="relatedPosts-list">'
    -
    -    for (let i = 0; i < Math.min(relatedPosts.length, limitNum); i++) {
    -      const cover = relatedPosts[i].cover || 'var(--default-bg-color)'
    -      const title = this.escape_html(relatedPosts[i].title)
    -      result += `<div><a href="${this.url_for(relatedPosts[i].path)}" title="${title}">`
    -      if (relatedPosts[i].cover_type === 'img') {
    -        result += `<img class="cover" src="${this.url_for(cover)}" alt="cover">`
    -      } else {
    -        result += `<div class="cover" style="background: ${cover}"></div>`
    -      }
    -      if (dateType === 'created') {
    -        result += `<div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> ${this.date(relatedPosts[i].created, hexoConfig.date_format)}</div>`
    -      } else {
    -        result += `<div class="content is-center"><div class="date"><i class="fas fa-history fa-fw"></i> ${this.date(relatedPosts[i].updated, hexoConfig.date_format)}</div>`
    -      }
    -      result += `<div class="title">${title}</div>`
    -      result += '</div></a></div>'
    -    }
    -
    -    result += '</div></div>'
    -    return result
    -  }
    -})
    -
    -function isTagRelated (tagName, TBDtags) {
    -  let result = false
    -  TBDtags.forEach(function (tag) {
    -    if (tagName === tag.name) {
    -      result = true
    -    }
    -  })
    -  return result
    -}
    -
    -function findItem (arrayToSearch, attr, val) {
    -  for (let i = 0; i < arrayToSearch.length; i++) {
    -    if (arrayToSearch[i][attr] === val) {
    -      return i
    -    }
    -  }
    -  return -1
    -}
    -
    -function compare (attr) {
    -  return function (a, b) {
    -    const val1 = a[attr]
    -    const val2 = b[attr]
    -    return val2 - val1
    -  }
    -}
    diff --git a/themes/butterfly/scripts/helpers/series.js b/themes/butterfly/scripts/helpers/series.js
    deleted file mode 100644
    index e1c93383..00000000
    --- a/themes/butterfly/scripts/helpers/series.js
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -'use strict'
    -
    -hexo.extend.helper.register('groupPosts', function () {
    -  const getGroupArray = array => {
    -    const groups = {}
    -    array.forEach(item => {
    -      const Key = item.series
    -      if (!Key) return
    -      groups[Key] = groups[Key] || []
    -      groups[Key].push(item)
    -    })
    -    return groups
    -  }
    -
    -  const sortPosts = posts => {
    -    const { orderBy = 'date', order = 1 } = this.theme.aside.card_post_series
    -    if (orderBy === 'title') return posts.sort('title', order)
    -    return posts.sort('date', order)
    -  }
    -
    -  return getGroupArray(sortPosts(this.site.posts))
    -})
    diff --git a/themes/butterfly/scripts/tag/button.js b/themes/butterfly/scripts/tag/button.js
    deleted file mode 100644
    index 624cdd34..00000000
    --- a/themes/butterfly/scripts/tag/button.js
    +++ /dev/null
    @@ -1,20 +0,0 @@
    -/**
    - * Button
    - * {% btn url text icon option %}
    - * option: color outline center block larger
    - * color : default/blue/pink/red/purple/orange/green
    - */
    -
    -'use strict'
    -
    -const urlFor = require('hexo-util').url_for.bind(hexo)
    -
    -const btn = args => {
    -  args = args.join(' ').split(',')
    -  const [url = '', text = '', icon = '', option = ''] = args.map(arg => arg.trim())
    -
    -  return `<a class="btn-beautify ${option}" href="${urlFor(url)}" 
    -  title="${text}">${icon.length ? `<i class="${icon}"></i>` : ''}${text.length ? `<span>${text}</span>` : ''}</a>`
    -}
    -
    -hexo.extend.tag.register('btn', btn, { ends: false })
    diff --git a/themes/butterfly/scripts/tag/flink.js b/themes/butterfly/scripts/tag/flink.js
    deleted file mode 100644
    index e41a52ff..00000000
    --- a/themes/butterfly/scripts/tag/flink.js
    +++ /dev/null
    @@ -1,39 +0,0 @@
    -/**
    - * flink
    - */
    -
    -'use strict'
    -
    -const urlFor = require('hexo-util').url_for.bind(hexo)
    -
    -const flinkFn = (args, content) => {
    -  content = hexo.render.renderSync({ text: content, engine: 'yaml' })
    -
    -  let result = ''
    -
    -  content.forEach(i => {
    -    const className = i.class_name ? `<div class="flink-name">${i.class_name}</div>` : ''
    -    const classDesc = i.class_desc ? `<div class="flink-desc">${i.class_desc}</div>` : ''
    -
    -    let listResult = ''
    -
    -    i.link_list.forEach(j => {
    -      listResult += `
    -          <div class="flink-list-item">
    -            <a href="${j.link}" title="${j.name}" target="_blank">
    -              <div class="flink-item-icon">
    -                <img class="no-lightbox" src="${j.avatar}" onerror='this.onerror=null;this.src="${urlFor(hexo.theme.config.error_img.flink)}"' alt="${j.name}" />
    -              </div>
    -              <div class="flink-item-name">${j.name}</div> 
    -              <div class="flink-item-desc" title="${j.descr}">${j.descr}</div>
    -            </a>
    -          </div>`
    -    })
    -
    -    result += `${className}${classDesc} <div class="flink-list">${listResult}</div>`
    -  })
    -
    -  return `<div class="flink">${result}</div>`
    -}
    -
    -hexo.extend.tag.register('flink', flinkFn, { ends: true })
    diff --git a/themes/butterfly/scripts/tag/gallery.js b/themes/butterfly/scripts/tag/gallery.js
    deleted file mode 100644
    index f8bceb68..00000000
    --- a/themes/butterfly/scripts/tag/gallery.js
    +++ /dev/null
    @@ -1,65 +0,0 @@
    -/**
    - * Butterfly
    - * galleryGroup and gallery
    - * {% galleryGroup [name] [descr] [url] [img] %}
    - *
    - * {% gallery [button],%}
    - * {% gallery url,[url],[button]%}
    - */
    -
    -'use strict'
    -
    -const urlFor = require('hexo-util').url_for.bind(hexo)
    -
    -const gallery = (args, content) => {
    -  args = args.join(' ').split(',')
    -  let button = false
    -  let type = 'data'
    -  let dataStr = ''
    -
    -  if (args[0] === 'url') {
    -    [type, dataStr, button] = args // url,[link],[lazyload]
    -  } else {
    -    [button] = args // [lazyload]
    -    const regex = /!\[(.*?)\]\(([^\s]*)\s*(?:["'](.*?)["']?)?\s*\)/g
    -    let m
    -    const arr = []
    -    while ((m = regex.exec(content)) !== null) {
    -      if (m.index === regex.lastIndex) {
    -        regex.lastIndex++
    -      }
    -      arr.push({
    -        url: m[2],
    -        alt: m[1],
    -        title: m[3]
    -      })
    -    }
    -
    -    dataStr = JSON.stringify(arr)
    -  }
    -
    -  return `<div class="gallery-container" data-type="${type}" data-button="${button}">
    -      <div class="gallery-data">${dataStr}</div>
    -      <div class="gallery-items">
    -      </div>
    -    </div>`
    -}
    -
    -const galleryGroup = args => {
    -  const [name, descr, url, img] = args
    -  const imgUrl = urlFor(img)
    -  const urlLink = urlFor(url)
    -
    -  return `<figure class="gallery-group">
    -  <img class="gallery-group-img no-lightbox" src='${imgUrl}' alt="Group Image Gallery">
    -  <figcaption>
    -  <div class="gallery-group-name">${name}</div>
    -  <p>${descr}</p>
    -  <a href='${urlLink}'></a>
    -  </figcaption>
    -  </figure>
    -  `
    -}
    -
    -hexo.extend.tag.register('gallery', gallery, { ends: true })
    -hexo.extend.tag.register('galleryGroup', galleryGroup)
    diff --git a/themes/butterfly/scripts/tag/hide.js b/themes/butterfly/scripts/tag/hide.js
    deleted file mode 100644
    index a788172f..00000000
    --- a/themes/butterfly/scripts/tag/hide.js
    +++ /dev/null
    @@ -1,65 +0,0 @@
    -/**
    - * Butterfly
    - * @example
    - * hideInline
    - * {% hideInline content,display,bg,color %}
    - * content不能包含當引號,可用 &apos;
    - * hideBlock
    - * {% hideBlock display,bg,color %}
    - * content
    - * {% endhideBlock %}
    - * hideToggle
    - * {% hideToggle display,bg,color %}
    - * content
    - * {% endhideToggle %}
    - */
    -
    -'use strict'
    -
    -const parseArgs = args => {
    -  return args.join(' ').split(',')
    -}
    -
    -const generateStyle = (bg, color) => {
    -  let style = 'style="'
    -  if (bg) {
    -    style += `background-color: ${bg};`
    -  }
    -  if (color) {
    -    style += `color: ${color}`
    -  }
    -  style += '"'
    -  return style
    -}
    -
    -const hideInline = args => {
    -  const [content, display = 'Click', bg = false, color = false] = parseArgs(args)
    -  const group = generateStyle(bg, color)
    -
    -  return `<span class="hide-inline"><button type="button" class="hide-button" ${group}>${display}
    -  </button><span class="hide-content">${content}</span></span>`
    -}
    -
    -const hideBlock = (args, content) => {
    -  const [display = 'Click', bg = false, color = false] = parseArgs(args)
    -  const group = generateStyle(bg, color)
    -
    -  return `<div class="hide-block"><button type="button" class="hide-button" ${group}>${display}
    -    </button><div class="hide-content">${hexo.render.renderSync({ text: content, engine: 'markdown' })}</div></div>`
    -}
    -
    -const hideToggle = (args, content) => {
    -  const [display, bg = false, color = false] = parseArgs(args)
    -  const group = generateStyle(bg, color)
    -  let border = ''
    -
    -  if (bg) {
    -    border = `style="border: 1px solid ${bg}"`
    -  }
    -
    -  return `<details class="toggle" ${border}><summary class="toggle-button" ${group}>${display}</summary><div class="toggle-content">${hexo.render.renderSync({ text: content, engine: 'markdown' })}</div></details>`
    -}
    -
    -hexo.extend.tag.register('hideInline', hideInline)
    -hexo.extend.tag.register('hideBlock', hideBlock, { ends: true })
    -hexo.extend.tag.register('hideToggle', hideToggle, { ends: true })
    diff --git a/themes/butterfly/scripts/tag/inlineImg.js b/themes/butterfly/scripts/tag/inlineImg.js
    deleted file mode 100644
    index 753add0f..00000000
    --- a/themes/butterfly/scripts/tag/inlineImg.js
    +++ /dev/null
    @@ -1,19 +0,0 @@
    -/**
    - * inlineImg 圖片
    - * @param {Array} args 圖片名稱和高度
    - * @param {string} args[0] 圖片名稱
    - * @param {number} args[1] 圖片高度
    - * @returns {string} 圖片標籤
    - */
    -
    -'use strict'
    -
    -const urlFor = require('hexo-util').url_for.bind(hexo)
    -
    -const inlineImg = ([img, height = '']) => {
    -  const heightStyle = height ? `style="height:${height}"` : ''
    -  const src = urlFor(img)
    -  return `<img class="inline-img" src="${src}" ${heightStyle} />`
    -}
    -
    -hexo.extend.tag.register('inlineImg', inlineImg, { ends: false })
    diff --git a/themes/butterfly/scripts/tag/label.js b/themes/butterfly/scripts/tag/label.js
    deleted file mode 100644
    index 4c9e692f..00000000
    --- a/themes/butterfly/scripts/tag/label.js
    +++ /dev/null
    @@ -1,14 +0,0 @@
    -/**
    - * Butterfly
    - * label
    - * {% label text color %}
    - */
    -
    -'use strict'
    -
    -const addLabel = args => {
    -  const [text, className = 'default'] = args
    -  return `<mark class="hl-label ${className}">${text}</mark> `
    -}
    -
    -hexo.extend.tag.register('label', addLabel, { ends: false })
    diff --git a/themes/butterfly/scripts/tag/mermaid.js b/themes/butterfly/scripts/tag/mermaid.js
    deleted file mode 100644
    index ba25c0fb..00000000
    --- a/themes/butterfly/scripts/tag/mermaid.js
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -/**
    - * Butterfly
    - * mermaid
    - * https://github.com/mermaid-js/mermaid
    - */
    -
    -'use strict'
    -
    -const { escapeHTML } = require('hexo-util')
    -
    -const mermaid = (args, content) => {
    -  return `<div class="mermaid-wrap"><pre class="mermaid-src" hidden>
    -  ${escapeHTML(content)}
    -  </pre></div>`
    -}
    -
    -hexo.extend.tag.register('mermaid', mermaid, { ends: true })
    diff --git a/themes/butterfly/scripts/tag/note.js b/themes/butterfly/scripts/tag/note.js
    deleted file mode 100644
    index 125bc61d..00000000
    --- a/themes/butterfly/scripts/tag/note.js
    +++ /dev/null
    @@ -1,27 +0,0 @@
    -/**
    - * note.js
    - * transplant from hexo-theme-next
    - * Modify by Jerry
    - */
    -
    -'use strict'
    -
    -const postNote = (args, content) => {
    -  const styleConfig = hexo.theme.config.note.style
    -  const noteTag = ['flat', 'modern', 'simple', 'disabled']
    -  if (!noteTag.includes(args[args.length - 1])) {
    -    args.push(styleConfig)
    -  }
    -
    -  let icon = ''
    -  const iconArray = args[args.length - 2]
    -  if (iconArray && iconArray.startsWith('fa')) {
    -    icon = `<i class="note-icon ${iconArray}"></i>`
    -    args[args.length - 2] = 'icon-padding'
    -  }
    -
    -  return `<div class="note ${args.join(' ')}">${icon + hexo.render.renderSync({ text: content, engine: 'markdown' })}</div>`
    -}
    -
    -hexo.extend.tag.register('note', postNote, { ends: true })
    -hexo.extend.tag.register('subnote', postNote, { ends: true })
    diff --git a/themes/butterfly/scripts/tag/score.js b/themes/butterfly/scripts/tag/score.js
    deleted file mode 100644
    index 441247b7..00000000
    --- a/themes/butterfly/scripts/tag/score.js
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -/**
    - * Music Score
    - * {% score %}
    - */
    -
    -'use strict'
    -
    -const score = (args, content) => {
    -  const escapeHtmlTags = s => {
    -    const lookup = {
    -      '&': '&amp;',
    -      '"': '&quot;',
    -      '\'': '&apos;',
    -      '<': '&lt;',
    -      '>': '&gt;'
    -    }
    -    return s.replace(/[&"'<>]/g, c => lookup[c])
    -  }
    -  return `<div class="abc-music-sheet">${escapeHtmlTags(content)}</div>`
    -}
    -
    -hexo.extend.tag.register('score', score, { ends: true })
    diff --git a/themes/butterfly/scripts/tag/series.js b/themes/butterfly/scripts/tag/series.js
    deleted file mode 100644
    index 4a901df2..00000000
    --- a/themes/butterfly/scripts/tag/series.js
    +++ /dev/null
    @@ -1,69 +0,0 @@
    -/**
    - * series plugin
    - * Syntax:
    - *  {% series [series name] %}
    - * Usage:
    - * {% series %}
    - * {% series series1 %}
    - */
    -
    -'use strict'
    -
    -const urlFor = require('hexo-util').url_for.bind(hexo)
    -const groups = {}
    -
    -hexo.extend.filter.register('before_post_render', data => {
    -  if (!hexo.theme.config.series.enable) return data
    -  const { layout, series } = data
    -  if (layout === 'post' && series) {
    -    groups[series] = groups[series] || []
    -    groups[series].push({
    -      title: data.title,
    -      path: data.path,
    -      date: data.date.unix()
    -    })
    -  }
    -  return data
    -})
    -
    -function series (args) {
    -  const { series } = hexo.theme.config
    -  if (!series.enable) {
    -    hexo.log.warn('Series plugin is disabled in the theme config')
    -    return ''
    -  }
    -
    -  const seriesArr = args.length ? groups[args[0]] : groups[this.series]
    -
    -  if (!seriesArr) {
    -    hexo.log.warn(`There is no series named "${args[0]}"`)
    -    return ''
    -  }
    -
    -  const isAsc = (series.order || 1) === 1 // 1: asc, -1: desc
    -  const isSortByTitle = series.orderBy === 'title'
    -
    -  const compareFn = (a, b) => {
    -    const itemA = isSortByTitle ? a.title.toUpperCase() : a.date
    -    const itemB = isSortByTitle ? b.title.toUpperCase() : b.date
    -
    -    if (itemA < itemB) {
    -      return isAsc ? -1 : 1
    -    }
    -    if (itemA > itemB) {
    -      return isAsc ? 1 : -1
    -    }
    -    return 0
    -  }
    -
    -  seriesArr.sort(compareFn)
    -
    -  let result = ''
    -  seriesArr.forEach(ele => {
    -    result += `<li><a href="${urlFor(ele.path)}" title="${ele.title}">${ele.title}</a></li>`
    -  })
    -
    -  return series.number ? `<ol>${result}</ol>` : `<ul>${result}</ul>`
    -}
    -
    -hexo.extend.tag.register('series', series, { ends: false })
    diff --git a/themes/butterfly/scripts/tag/tabs.js b/themes/butterfly/scripts/tag/tabs.js
    deleted file mode 100644
    index 6ec87de8..00000000
    --- a/themes/butterfly/scripts/tag/tabs.js
    +++ /dev/null
    @@ -1,64 +0,0 @@
    -/**
    - * Tabs
    - * transplant from hexo-theme-next
    - * modify by Jerry
    - */
    -
    -'use strict'
    -
    -const postTabs = (args, content) => {
    -  const tabBlock = /<!--\s*tab (.*?)\s*-->\n([\w\W\s\S]*?)<!--\s*endtab\s*-->/g
    -  args = args.join(' ').split(',')
    -  const tabName = args[0]
    -  const tabActive = Number(args[1]) || 0
    -  const matches = []
    -  let match
    -  let tabId = 0
    -  let tabNav = ''
    -  let tabContent = ''
    -  let noDefault = true
    -
    -  !tabName && hexo.log.warn('Tabs block must have unique name!')
    -
    -  while ((match = tabBlock.exec(content)) !== null) {
    -    matches.push(match[1], match[2])
    -  }
    -
    -  for (let i = 0; i < matches.length; i += 2) {
    -    const tabParameters = matches[i].split('@')
    -    let postContent = matches[i + 1]
    -    let tabCaption = tabParameters[0] || ''
    -    let tabIcon = tabParameters[1] || ''
    -    let tabHref = ''
    -
    -    postContent = hexo.render.renderSync({ text: postContent, engine: 'markdown' }).trim()
    -
    -    tabId += 1
    -    tabHref = (tabName + ' ' + tabId).toLowerCase().split(' ').join('-');
    -
    -    ((tabCaption.length === 0) && (tabIcon.length === 0)) && (tabCaption = tabName + ' ' + tabId)
    -
    -    const isOnlyicon = tabIcon.length > 0 && tabCaption.length === 0 ? ' style="text-align: center;"' : ''
    -    const icon = tabIcon.trim()
    -    tabIcon.length > 0 && (tabIcon = `<i class="${icon}"${isOnlyicon}></i>`)
    -
    -    let isActive = ''
    -    if ((tabActive > 0 && tabActive === tabId) || (tabActive === 0 && tabId === 1)) {
    -      isActive = ' active'
    -      noDefault = false
    -    }
    -    tabNav += `<button type="button" class="tab ${isActive}" data-href="${tabHref}">${tabIcon + tabCaption.trim()}</button>`
    -    tabContent += `<div class="tab-item-content${isActive}" id="${tabHref}">${postContent}</div>`
    -  }
    -
    -  const toTop = '<div class="tab-to-top"><button type="button" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div>'
    -
    -  tabNav = `<ul class="nav-tabs${noDefault ? ' no-default' : ''}">${tabNav}</ul>`
    -  tabContent = `<div class="tab-contents">${tabContent}</div>`
    -
    -  return `<div class="tabs" id="${tabName.toLowerCase().split(' ').join('-')}">${tabNav + tabContent + toTop}</div>`
    -}
    -
    -hexo.extend.tag.register('tabs', postTabs, { ends: true })
    -hexo.extend.tag.register('subtabs', postTabs, { ends: true })
    -hexo.extend.tag.register('subsubtabs', postTabs, { ends: true })
    diff --git a/themes/butterfly/scripts/tag/timeline.js b/themes/butterfly/scripts/tag/timeline.js
    deleted file mode 100644
    index 6dde854e..00000000
    --- a/themes/butterfly/scripts/tag/timeline.js
    +++ /dev/null
    @@ -1,41 +0,0 @@
    -/**
    - * timeline
    - * by Jerry
    - */
    -
    -'use strict'
    -
    -const timeLineFn = (args, content) => {
    -  const tlBlock = /<!--\s*timeline (.*?)\s*-->\n([\w\W\s\S]*?)<!--\s*endtimeline\s*-->/g
    -
    -  let result = ''
    -  let color = ''
    -  let text = ''
    -  if (args.length) {
    -    [text, color] = args.join(' ').split(',')
    -    const mdContent = hexo.render.renderSync({ text, engine: 'markdown' })
    -    result += `<div class='timeline-item headline'><div class='timeline-item-title'><div class='item-circle'>${mdContent}</div></div></div>`
    -  }
    -
    -  const matches = []
    -  let match
    -
    -  while ((match = tlBlock.exec(content)) !== null) {
    -    matches.push(match[1])
    -    matches.push(match[2])
    -  }
    -
    -  for (let i = 0; i < matches.length; i += 2) {
    -    const tlChildTitle = hexo.render.renderSync({ text: matches[i], engine: 'markdown' })
    -    const tlChildContent = hexo.render.renderSync({ text: matches[i + 1], engine: 'markdown' })
    -
    -    const tlTitleHtml = `<div class='timeline-item-title'><div class='item-circle'>${tlChildTitle}</div></div>`
    -    const tlContentHtml = `<div class='timeline-item-content'>${tlChildContent}</div>`
    -
    -    result += `<div class='timeline-item'>${tlTitleHtml + tlContentHtml}</div>`
    -  }
    -
    -  return `<div class="timeline ${color}">${result}</div>`
    -}
    -
    -hexo.extend.tag.register('timeline', timeLineFn, { ends: true })
    diff --git a/themes/butterfly/source/css/_global/function.styl b/themes/butterfly/source/css/_global/function.styl
    deleted file mode 100644
    index 9a4fa3c9..00000000
    --- a/themes/butterfly/source/css/_global/function.styl
    +++ /dev/null
    @@ -1,277 +0,0 @@
    -.limit-one-line
    -  overflow: hidden
    -  text-overflow: ellipsis
    -  white-space: nowrap
    -
    -.limit-more-line
    -  display: -webkit-box
    -  overflow: hidden
    -  -webkit-box-orient: vertical
    -
    -.fontawesomeIcon
    -  display: inline-block
    -  font-weight: 600
    -  font-family: 'Font Awesome 6 Free'
    -  text-rendering: auto
    -  -webkit-font-smoothing: antialiased
    -
    -// card hover
    -.cardHover
    -  border-radius: 8px
    -  background: var(--card-bg)
    -  box-shadow: var(--card-box-shadow)
    -  transition: all .3s
    -
    -  &:hover
    -    box-shadow: var(--card-hover-box-shadow)
    -
    -.imgHover
    -  width: 100%
    -  height: 100%
    -  transition: filter 375ms ease-in .2s, transform .6s
    -  object-fit: cover
    -
    -  &:hover
    -    transform: scale(1.1)
    -
    -.postImgHover
    -  &:hover
    -    .cover
    -      opacity: .8
    -      transform: scale(1.1)
    -
    -  .cover
    -    position: absolute
    -    width: 100%
    -    height: 100%
    -    opacity: .4
    -    transition: all .6s, filter 375ms ease-in .2s
    -    object-fit: cover
    -
    -.list-beauty
    -  list-style: none
    -
    -  li
    -    position: relative
    -    padding: .12em .4em .12em 1.4em
    -
    -    &:hover
    -      &:before
    -        border-color: var(--pseudo-hover)
    -
    -    &:before
    -      position: absolute
    -      top: .67em
    -      left: 0
    -      width: w = .43em
    -      height: h = w
    -      border: .5 * w solid $light-blue
    -      border-radius: w
    -      background: transparent
    -      content: ''
    -      cursor: pointer
    -      transition: all .3s ease-out
    -
    -.custom-hr
    -  position: relative
    -  margin: 40px auto
    -  border: 2px dashed var(--hr-border)
    -
    -  if hexo-config('hr_icon.enable')
    -    width: calc(100% - 4px)
    -
    -    &:hover
    -      &:before
    -        left: calc(95% - 20px)
    -
    -    &:before
    -      position: absolute
    -      top: $hr-icon-top
    -      left: 5%
    -      z-index: 1
    -      color: var(--hr-before-color)
    -      content: $hr-icon
    -      font-size: 20px
    -      line-height: 1
    -      transition: all 1s ease-in-out
    -      @extend .fontawesomeIcon
    -
    -maxWidth600()
    -  @media screen and (max-width: 600px)
    -    {block}
    -
    -maxWidth768()
    -  @media screen and (max-width: 768px)
    -    {block}
    -
    -minWidth768()
    -  @media screen and (min-width: 768px)
    -    {block}
    -
    -maxWidth1024()
    -  @media screen and (max-width: 1024px)
    -    {block}
    -
    -maxWidth900()
    -  @media screen and (max-width: 900px)
    -    {block}
    -
    -minWidth901()
    -  @media screen and (min-width: 901px)
    -    {block}
    -
    -minWidth900()
    -  @media screen and (min-width: 900px)
    -    {block}
    -
    -minWidth2000()
    -  @media screen and (min-width: 2000px)
    -    {block}
    -
    -// animation
    -if hexo-config('enter_transitions')
    -  #content-inner,
    -  #footer
    -    animation: bottom-top 1s
    -
    -  #page-header:not(.full_page)
    -    animation: header-effect 1s
    -
    -  #site-title,
    -  #site-subtitle
    -    animation: titleScale 1s
    -
    -  #nav.show
    -    animation: headerNoOpacity 1s
    -
    -  canvas:not(#ribbon-canvas),
    -  #web_bg
    -    animation: to_show 4s
    -
    -  #ribbon-canvas
    -    animation: ribbon_to_show 4s
    -
    -  #sidebar-menus
    -    &.open
    -      for i in 1 2 3 4
    -        > :nth-child({i})
    -          animation: sidebarItem (i / 5s)
    -
    -.scroll-down-effects
    -  animation: scroll-down-effect 1.5s infinite
    -
    -if hexo-config('avatar.effect') == true
    -  .avatar-img
    -    animation: avatar_turn_around 2s linear infinite
    -
    -.reward-main
    -  animation: donate_effcet .3s .1s ease both
    -
    -@keyframes scroll-down-effect
    -  0%
    -    opacity: .4
    -    transform: translate(0, 0)
    -
    -  50%
    -    opacity: 1
    -    transform: translate(0, -16px)
    -
    -  100%
    -    opacity: .4
    -    transform: translate(0, 0)
    -
    -@keyframes header-effect
    -  0%
    -    opacity: 0
    -    transform: translateY(-50px)
    -
    -  100%
    -    opacity: 1
    -    transform: translateY(0)
    -
    -@keyframes headerNoOpacity
    -  0%
    -    transform: translateY(-50px)
    -
    -  100%
    -    transform: translateY(0)
    -
    -@keyframes bottom-top
    -  0%
    -    opacity: 0
    -    transform: translateY(50px)
    -
    -  100%
    -    opacity: 1
    -    transform: translateY(0)
    -
    -@keyframes titleScale
    -  0%
    -    opacity: 0
    -    transform: scale(.7)
    -
    -  100%
    -    opacity: 1
    -    transform: scale(1)
    -
    -@keyframes search_close
    -  0%
    -    opacity: 1
    -    transform: scale(1)
    -
    -  100%
    -    opacity: 0
    -    transform: scale(.7)
    -
    -@keyframes to_show
    -  0%
    -    opacity: 0
    -
    -  100%
    -    opacity: 1
    -
    -@keyframes to_hide
    -  0%
    -    opacity: 1
    -
    -  100%
    -    opacity: 0
    -
    -@keyframes ribbon_to_show
    -  0%
    -    opacity: 0
    -
    -  100%
    -    opacity: hexo-config('canvas_ribbon.alpha')
    -
    -@keyframes avatar_turn_around
    -  from
    -    transform: rotate(0)
    -
    -  to
    -    transform: rotate(360deg)
    -
    -@keyframes sub_menus
    -  0%
    -    opacity: 0
    -    transform: translateY(10px)
    -
    -  100%
    -    opacity: 1
    -    transform: translateY(0)
    -
    -@keyframes donate_effcet
    -  0%
    -    opacity: 0
    -    transform: translateY(-20px)
    -
    -  100%
    -    opacity: 1
    -    transform: translateY(0)
    -
    -@keyframes sidebarItem
    -  0%
    -    transform: translateX(200px)
    -
    -  100%
    -    transform: translateX(0)
    \ No newline at end of file
    diff --git a/themes/butterfly/source/css/_global/index.styl b/themes/butterfly/source/css/_global/index.styl
    deleted file mode 100644
    index 22c87c2d..00000000
    --- a/themes/butterfly/source/css/_global/index.styl
    +++ /dev/null
    @@ -1,197 +0,0 @@
    -:root
    -  --global-font-size: $font-size
    -  --global-bg: $body-bg
    -  --font-color: $font-black
    -  --hr-border: lighten($theme-hr-color, 50%)
    -  --hr-before-color: lighten($theme-hr-color, 30%)
    -  --search-bg: $search-bg
    -  --search-input-color: $search-input-color
    -  --search-a-color: $search-a-color
    -  --preloader-bg: $preloader-bg
    -  --preloader-color: $preloader-word-color
    -  --tab-border-color: $tab-border-color
    -  --tab-botton-bg: $tab-botton-bg
    -  --tab-botton-color: $tab-botton-color
    -  --tab-button-hover-bg: $tab-button-hover-bg
    -  --tab-button-active-bg: $tab-button-active-bg
    -  --card-bg: $card-bg
    -  --sidebar-bg: $sidebar-background
    -  --btn-hover-color: $button-hover-color
    -  --btn-color: $button-color
    -  --btn-bg: $button-bg
    -  --text-bg-hover: rgba($text-bg-hover, .7)
    -  --light-grey: $light-grey
    -  --dark-grey: $dark-grey
    -  --white: $white
    -  --text-highlight-color: $text-highlight-color
    -  --blockquote-color: $blockquote-color
    -  --blockquote-bg: $blockquote-background-color
    -  --reward-pop: $reward-pop-up-bg
    -  --toc-link-color: $toc-link-color
    -  --card-box-shadow: 0 3px 8px 6px rgba(7, 17, 27, .05)
    -  --card-hover-box-shadow: 0 3px 8px 6px rgba(7, 17, 27, .09)
    -  --pseudo-hover: $pseudo-hover
    -  --headline-presudo: #a0a0a0
    -  --scrollbar-color: $scrollbar-color
    -  --default-bg-color: $theme-color
    -  --zoom-bg: #fff
    -  --mark-bg: alpha($dark-black, .3)
    -
    -body
    -  position: relative
    -  min-height: 100%
    -  background: var(--global-bg)
    -  color: var(--font-color)
    -  font-size: var(--global-font-size)
    -  font-family: $font-family
    -  line-height: $text-line-height
    -  -webkit-tap-highlight-color: rgba(0, 0, 0, 0)
    -
    -  if !hexo-config('copy.enable')
    -    user-select: none
    -    -webkit-user-select: none
    -
    -// scrollbar - chrome/safari
    -*::-webkit-scrollbar
    -  width: 5px
    -  height: 5px
    -
    -*::-webkit-scrollbar-thumb
    -  background: var(--scrollbar-color)
    -
    -*::-webkit-scrollbar-track
    -  background-color: transparent
    -
    -// scrollbar - firefox
    -*
    -  scrollbar-width: thin
    -  scrollbar-color: var(--scrollbar-color) transparent
    -
    -input::placeholder
    -  color: var(--font-color)
    -
    -if $web-bg
    -  #web_bg
    -    position: fixed
    -    z-index: -999
    -    width: 100%
    -    height: 100%
    -    background: $web-bg
    -    background-attachment: local
    -    background-position: center
    -    background-size: cover
    -    background-repeat: no-repeat
    -
    -h1,
    -h2,
    -h3,
    -h4,
    -h5,
    -h6
    -  position: relative
    -  margin: 20px 0 14px
    -  color: var(--text-highlight-color)
    -  font-weight: bold
    -
    -  code
    -    font-size: inherit !important
    -
    -*
    -  box-sizing: border-box
    -
    -.table-wrap
    -  overflow-x: scroll
    -  margin: 0 0 20px
    -
    -table
    -  display: table
    -  width: 100%
    -  border-spacing: 0
    -  border-collapse: collapse
    -  empty-cells: show
    -
    -  thead
    -    background: alpha($table-thead-bg, 10%)
    -
    -  th,
    -  td
    -    padding: 6px 12px
    -    border: 1px solid var(--light-grey)
    -    vertical-align: middle
    -
    -*::selection
    -  background: $theme-text-selection-color
    -  color: #F7F7F7
    -
    -button
    -  padding: 0
    -  outline: 0
    -  border: none
    -  background: none
    -  cursor: pointer
    -  touch-action: manipulation
    -
    -a
    -  color: $a-link-color
    -  text-decoration: none
    -  word-wrap: break-word
    -  transition: all .2s
    -  overflow-wrap: break-word
    -
    -  &:hover
    -    color: $light-blue
    -
    -// font
    -if $site-name-font
    -  #site-title,
    -  #site-subtitle,
    -  .site-name,
    -  #aside-content .author-info__name,
    -  #aside-content .author-info__description
    -    font-family: $site-name-font
    -
    -.is-center
    -  text-align: center
    -
    -.pull-left
    -  float: left
    -
    -.pull-right
    -  float: right
    -
    -img
    -  &[src=''],
    -  &:not([src])
    -    opacity: 0
    -
    -// lazyload blur
    -if hexo-config('lazyload.enable') && hexo-config('lazyload.blur') && !hexo-config('lazyload.placeholder')
    -  img
    -    &[data-lazy-src]:not(.loaded)
    -      filter: blur(8px) brightness(1)
    -
    -    &[data-lazy-src].error
    -      filter: none
    -
    -.img-alt
    -  margin: -10px 0 10px
    -  color: #858585
    -
    -  &:hover
    -    text-decoration: none !important
    -
    -blockquote
    -  margin: 0 0 20px
    -  padding: 12px 15px
    -  border-left: 3px solid $blockquote-padding-color
    -  background-color: var(--blockquote-bg)
    -  color: var(--blockquote-color)
    -
    -  footer
    -    cite
    -      &:before
    -        padding: 0 5px
    -        content: '—'
    -
    -  & > :last-child
    -    margin-bottom: 0 !important
    diff --git a/themes/butterfly/source/css/_highlight/highlight.styl b/themes/butterfly/source/css/_highlight/highlight.styl
    deleted file mode 100644
    index 78c08121..00000000
    --- a/themes/butterfly/source/css/_highlight/highlight.styl
    +++ /dev/null
    @@ -1,231 +0,0 @@
    -$highlight_theme = hexo-config('highlight_theme')
    -wordWrap = $highlight_enable && !$highlight_line_number && hexo-config('code_word_wrap')
    -
    -@require 'theme'
    -
    -:root
    -  --hl-color: $highlight-foreground
    -  --hl-bg: $highlight-background
    -  --hltools-bg: $highlight-tools.bg-color
    -  --hltools-color: $highlight-tools.color
    -  --hlnumber-bg: $highlight-gutter.bg-color
    -  --hlnumber-color: $highlight-gutter.color
    -  --hlscrollbar-bg: $highlight-scrollbar
    -  --hlexpand-bg: linear-gradient(180deg, rgba($highlight-background, .6), rgba($highlight-background, .9))
    -
    -[data-theme='dark']
    -  --hl-color: alpha(#FFFFFF, .7)
    -  --hl-bg: lighten(#121212, 2)
    -  --hltools-bg: lighten(#121212, 3)
    -  --hltools-color: #90a4ae
    -  --hlnumber-bg: lighten(#121212, 2)
    -  --hlnumber-color: alpha(#FFFFFF, .4)
    -  --hlscrollbar-bg: lighten(#121212, 5)
    -  --hlexpand-bg: linear-gradient(180deg, rgba(lighten(#121212, 2), .6), rgba(lighten(#121212, 2), .9))
    -
    -if $highlight_enable
    -  @require 'highlight/index'
    -
    -if $prismjs_enable
    -  @require 'prismjs/index'
    -
    -$code-block
    -  overflow: auto
    -  margin: 0 0 20px
    -  padding: 0
    -  background: var(--hl-bg)
    -  color: var(--hl-color)
    -  line-height: $line-height-code-block
    -
    -  if wordWrap
    -    counter-reset: line
    -    white-space: pre-wrap
    -
    -#article-container
    -  pre,
    -  code
    -    font-size: $code-font-size
    -    font-family: $code-font-family !important
    -
    -  code
    -    padding: 2px 4px
    -    background: $code-background
    -    color: $code-foreground
    -
    -  pre
    -    @extend $code-block
    -    padding: 10px 20px
    -
    -    code
    -      padding: 0
    -      background: none
    -      color: var(--hl-color)
    -      text-shadow: none
    -
    -  figure.highlight
    -    @extend $code-block
    -    position: relative
    -
    -    pre
    -      margin: 0
    -      padding: 8px 0
    -      border: none
    -
    -    figcaption,
    -    .caption
    -      padding: 6px 0 2px 14px
    -      font-size: $code-font-size
    -      line-height: 1em
    -
    -      a
    -        float: right
    -        padding-right: 10px
    -        color: var(--hl-color)
    -
    -        &:hover
    -          border-bottom-color: var(--hl-color)
    -
    -    &.copy-true
    -      user-select: all
    -      -webkit-user-select: all
    -
    -      & > table,
    -      & > pre
    -        display: block !important
    -        opacity: 0
    -
    -  .highlight-tools
    -    position: relative
    -    display: flex
    -    align-items: center
    -    overflow: hidden
    -    min-height: 24px
    -    height: 2.15em
    -    background: var(--hltools-bg)
    -    color: var(--hltools-color)
    -    font-size: $code-font-size
    -
    -    &.closed
    -      & ~ *
    -        display: none
    -
    -      .expand
    -        transition: all .3s
    -        transform: rotate(-90deg) !important
    -
    -    .expand
    -      position: absolute
    -      padding: .57em .7em
    -      cursor: pointer
    -      transition: transform .3s
    -
    -      & + .code-lang
    -        left: 1.7em
    -
    -    .code-lang
    -      position: absolute
    -      left: 14px
    -      text-transform: uppercase
    -      font-weight: bold
    -      font-size: 1.15em
    -      user-select: none
    -      -webkit-user-select: none
    -
    -    .copy-notice
    -      position: absolute
    -      right: 2.4em
    -      opacity: 0
    -      transition: opacity .4s
    -
    -    .copy-button
    -      position: absolute
    -      right: 14px
    -      cursor: pointer
    -      transition: color .2s
    -
    -      &:hover
    -        color: $theme-color
    -
    -  .gutter
    -    user-select: none
    -    -webkit-user-select: none
    -
    -  .gist table
    -    width: auto
    -
    -    td
    -      border: none
    -
    -  if $highlight_theme == 'mac' || ($highlight_theme == 'mac light')
    -    figure.highlight
    -      margin: 0 0 24px
    -      border-radius: 7px
    -      box-shadow: 0 5px 10px 0 $highlight-mac-border
    -      -webkit-transform: translateZ(0)
    -
    -      .highlight-tools
    -        &:after
    -          position: absolute
    -          left: 14px
    -          width: 12px
    -          height: 12px
    -          border-radius: 50%
    -          background: #fc625d
    -          box-shadow: 20px 0 #fdbc40, 40px 0 #35cd4b
    -          content: ' '
    -
    -        .expand
    -          right: 0
    -
    -          &.closed
    -            transition: all .3s
    -            transform: rotate(90deg) !important
    -
    -          & ~ .copy-notice
    -            right: 3.45em
    -
    -          & ~ .copy-button
    -            right: 2.1em
    -
    -        .code-lang
    -          left: 75px
    -
    -  if hexo-config('highlight_height_limit')
    -    .code-expand-btn
    -      position: absolute
    -      bottom: 0
    -      z-index: 10
    -      width: 100%
    -      background: var(--hlexpand-bg)
    -      text-align: center
    -      font-size: $code-font-size
    -      cursor: pointer
    -
    -      i
    -        padding: 6px 0
    -        color: var(--hlnumber-color)
    -        animation: code-expand-key 1.2s infinite
    -
    -      &.expand-done
    -        & > i
    -          transform: rotate(180deg)
    -
    -        & + table,
    -        & + pre
    -          margin-bottom: 1.8em
    -
    -      &:not(.expand-done)
    -        & ~ table,
    -        & ~ pre
    -          overflow: hidden
    -          height: unit(hexo-config('highlight_height_limit'), px)
    -
    -@keyframes code-expand-key
    -  0%
    -    opacity: .6
    -
    -  50%
    -    opacity: .1
    -
    -  100%
    -    opacity: .6
    \ No newline at end of file
    diff --git a/themes/butterfly/source/css/_highlight/highlight/diff.styl b/themes/butterfly/source/css/_highlight/highlight/diff.styl
    deleted file mode 100644
    index 83f3e179..00000000
    --- a/themes/butterfly/source/css/_highlight/highlight/diff.styl
    +++ /dev/null
    @@ -1,79 +0,0 @@
    -figure.highlight
    -  table
    -    scrollbar-color: var(--hlscrollbar-bg) transparent
    -
    -    &::-webkit-scrollbar-thumb
    -      background: var(--hlscrollbar-bg)
    -
    -  pre .deletion
    -    color: $highlight-deletion
    -
    -  pre .addition
    -    color: $highlight-addition
    -
    -  pre .meta
    -    color: $highlight-purple
    -
    -  pre
    -    .comment
    -      color: $highlight-comment
    -
    -    .variable,
    -    .attribute,
    -    .regexp,
    -    .ruby .constant,
    -    .xml .tag .title,
    -    .xml .pi,
    -    .xml .doctype,
    -    .html .doctype,
    -    .css .id,
    -    .tag .name,
    -    .css .class,
    -    .css .pseudo
    -      color: $highlight-red
    -
    -    .tag
    -      color: $highlight-aqua
    -
    -    .number,
    -    .preprocessor,
    -    .literal,
    -    .params,
    -    .constant,
    -    .command
    -      color: $highlight-orange
    -
    -    .built_in
    -      color: $highlight-yellow
    -
    -    .ruby .class .title,
    -    .css .rules .attribute,
    -    .string,
    -    .value,
    -    .inheritance,
    -    .header,
    -    .ruby .symbol,
    -    .xml .cdata,
    -    .special,
    -    .number,
    -    .formula
    -      color: $highlight-green
    -
    -    .keyword,
    -    .title,
    -    .css .hexcolor
    -      color: $highlight-aqua
    -
    -    .function,
    -    .python .decorator,
    -    .python .title,
    -    .ruby .function .title,
    -    .ruby .title .keyword,
    -    .perl .sub,
    -    .javascript .title,
    -    .coffeescript .title
    -      color: $highlight-blue
    -
    -    .tag .attr,
    -    .javascript .function
    -      color: $highlight-purple
    diff --git a/themes/butterfly/source/css/_highlight/highlight/index.styl b/themes/butterfly/source/css/_highlight/highlight/index.styl
    deleted file mode 100644
    index bdb9d96a..00000000
    --- a/themes/butterfly/source/css/_highlight/highlight/index.styl
    +++ /dev/null
    @@ -1,39 +0,0 @@
    -if $highlight_theme != false
    -  @require 'diff'
    -
    -#article-container
    -  figure.highlight
    -    .line
    -      if wordWrap
    -        &:before
    -          display: inline-block
    -          padding: 0 6px 0 0
    -          min-width: 30px
    -          color: var(--hlnumber-color)
    -          content: counter(line)
    -          counter-increment: line
    -          text-align: left
    -
    -      &.marked
    -        background-color: $highlight-selection
    -
    -    table
    -      display: block
    -      overflow: auto
    -      border: none
    -
    -      td
    -        padding: 0
    -        border: none
    -
    -    .gutter pre
    -      padding-right: 10px
    -      padding-left: 10px
    -      background-color: var(--hlnumber-bg)
    -      color: var(--hlnumber-color)
    -      text-align: right
    -
    -    .code pre
    -      padding-right: 10px
    -      padding-left: 10px
    -      width: 100%
    diff --git a/themes/butterfly/source/css/_highlight/prismjs/diff.styl b/themes/butterfly/source/css/_highlight/prismjs/diff.styl
    deleted file mode 100644
    index 1e63c795..00000000
    --- a/themes/butterfly/source/css/_highlight/prismjs/diff.styl
    +++ /dev/null
    @@ -1,302 +0,0 @@
    -if $highlight_theme == 'light' || ($highlight_theme == 'mac light')
    -  // prism-base16-ateliersulphurpool.light
    -  pre[class*='language-']
    -    .token.function
    -      color: #ffb62c
    -
    -    .token.comment,
    -    .token.prolog,
    -    .token.doctype,
    -    .token.cdata
    -      color: rgba(149, 165, 166, .8)
    -
    -    .token.punctuation
    -      color: #5e6687
    -
    -    .token.namespace
    -      opacity: .7
    -
    -    .token.operator,
    -    .token.boolean,
    -    .token.number
    -      color: #c76b29
    -
    -    .token.property
    -      color: #c08b30
    -
    -    .token.tag
    -      color: #3d8fd1
    -
    -    .token.string
    -      color: #22a2c9
    -
    -    .token.selector
    -      color: #6679cc
    -
    -    .token.attr-name
    -      color: #c76b29
    -
    -    .token.entity,
    -    .token.url,
    -    .language-css .token.string,
    -    .style .token.string
    -      color: #22a2c9
    -
    -    .token.attr-value,
    -    .token.keyword,
    -    .token.control,
    -    .token.directive,
    -    .token.unit
    -      color: #ac9739
    -
    -    .token.statement,
    -    .token.regex,
    -    .token.atrule
    -      color: #22a2c9
    -
    -    .token.placeholder,
    -    .token.variable
    -      color: #3d8fd1
    -
    -    .token.deleted
    -      text-decoration: line-through
    -
    -    .token.inserted
    -      border-bottom: 1px dotted #202746
    -      text-decoration: none
    -
    -    .token.italic
    -      font-style: italic
    -
    -    .token.important,
    -    .token.bold
    -      font-weight: bold
    -
    -    .token.important
    -      color: #c94922
    -
    -    .token.entity
    -      cursor: help
    -
    -    pre > code.highlight
    -      outline: .4em solid #c94922
    -      outline-offset: .4em
    -
    -if $highlight_theme == 'darker' || ($highlight_theme == 'mac')
    -  // prism-atom-dark
    -  pre[class*='language-']
    -    .token.comment,
    -    .token.prolog,
    -    .token.doctype,
    -    .token.cdata
    -      color: #7C7C7C
    -
    -    .token.punctuation
    -      color: #c5c8c6
    -
    -    .namespace
    -      opacity: .7
    -
    -    .token.property,
    -    .token.keyword,
    -    .token.tag
    -      color: #96CBFE
    -
    -    .token.class-name
    -      color: #FFFFB6
    -
    -    .token.boolean,
    -    .token.constant
    -      color: #99CC99
    -
    -    .token.symbol,
    -    .token.deleted
    -      color: #f92672
    -
    -    .token.number
    -      color: #FF73FD
    -
    -    .token.selector,
    -    .token.attr-name,
    -    .token.string,
    -    .token.char,
    -    .token.builtin,
    -    .token.inserted
    -      color: #A8FF60
    -
    -    .token.variable
    -      color: #C6C5FE
    -
    -    .token.operator
    -      color: #EDEDED
    -
    -    .token.entity
    -      color: #FFFFB6
    -      cursor: help
    -
    -    .token.url
    -      color: #96CBFE
    -
    -    .language-css .token.string,
    -    .style .token.string
    -      color: #87C38A
    -
    -    .token.atrule,
    -    .token.attr-value
    -      color: #F9EE98
    -
    -    .token.function
    -      color: #DAD085
    -
    -    .token.regex
    -      color: #E9C062
    -
    -    .token.important
    -      color: #fd971f
    -
    -    .token.important,
    -    .token.bold
    -      font-weight: bold
    -
    -    .token.italic
    -      font-style: italic
    -
    -if $highlight_theme == 'pale night'
    -  // prism-dracula
    -  pre[class*='language-']
    -    .token.comment,
    -    .token.prolog,
    -    .token.doctype,
    -    .token.cdata
    -      color: #6272a4
    -
    -    .token.punctuation
    -      color: #f8f8f2
    -
    -    .namespace
    -      opacity: .7
    -
    -    .token.property,
    -    .token.tag,
    -    .token.constant,
    -    .token.symbol,
    -    .token.deleted
    -      color: #ff79c6
    -
    -    .token.boolean,
    -    .token.number
    -      color: #bd93f9
    -
    -    .token.selector,
    -    .token.attr-name,
    -    .token.string,
    -    .token.char,
    -    .token.builtin,
    -    .token.inserted
    -      color: #50fa7b
    -
    -    .token.operator,
    -    .token.entity,
    -    .token.url,
    -    .language-css .token.string,
    -    .style .token.string,
    -    .token.variable
    -      color: #f8f8f2
    -
    -    .token.atrule,
    -    .token.attr-value,
    -    .token.function,
    -    .token.class-name
    -      color: #f1fa8c
    -
    -    .token.keyword
    -      color: #8be9fd
    -
    -    .token.regex,
    -    .token.important
    -      color: #ffb86c
    -
    -    .token.important,
    -    .token.bold
    -      font-weight: bold
    -
    -    .token.italic
    -      font-style: italic
    -
    -    .token.entity
    -      cursor: help
    -
    -if $highlight_theme == 'ocean'
    -  // prism-material-oceanic
    -  pre[class*='language-']
    -    &.language-css > code,
    -    &.language-sass > code,
    -    &.language-scss > code
    -      color: #fd9170 !important
    -
    -    .namespace
    -      opacity: .7
    -
    -    .token.atrule,
    -    .token.symbol,
    -    .token.constant,
    -    .token.boolean,
    -    .token.function
    -      color: #c792ea
    -
    -    .token.attr-name,
    -    .token.builtin,
    -    .token.class
    -      color: #ffcb6b
    -
    -    .token.attr-value,
    -    .token.attribute,
    -    .token.pseudo-class,
    -    .token.pseudo-element,
    -    .token.string
    -      color: #c3e88d
    -
    -    .token.cdata,
    -    .token.property,
    -    .token.char,
    -    .token.inserted
    -      color: #80cbc4
    -
    -    .token.class-name,
    -    .token.color,
    -    .token.hexcode,
    -    .token.regex
    -      color: #f2ff00
    -
    -    .token.comment,
    -    .token.prolog,
    -    .token.doctype
    -      color: #546e7a
    -
    -    .token.deleted,
    -    .token.variable,
    -    .token.entity,
    -    .token.selector,
    -    .token.tag,
    -    .token.unit
    -      color: #f07178
    -
    -    .token.id
    -      color: #c792ea
    -      font-weight: bold
    -
    -    .token.important
    -      color: #c792ea
    -      font-weight: bold
    -
    -    .token.keyword
    -      color: #c792ea
    -      font-style: italic
    -
    -    .token.number,
    -    .token.url
    -      color: #fd9170
    -
    -    .token.operator,
    -    .token.punctuation
    -      color: #89ddff
    \ No newline at end of file
    diff --git a/themes/butterfly/source/css/_highlight/prismjs/index.styl b/themes/butterfly/source/css/_highlight/prismjs/index.styl
    deleted file mode 100644
    index 1b738373..00000000
    --- a/themes/butterfly/source/css/_highlight/prismjs/index.styl
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -if $prismjs_line_number
    -  @require 'line-number'
    -
    -if $highlight_theme != false
    -  @require 'diff'
    -
    -#article-container
    -  pre[class*='language-']
    -    scrollbar-color: var(--hlscrollbar-bg) transparent
    -
    -    &::-webkit-scrollbar-thumb
    -      background: var(--hlscrollbar-bg)
    -
    -    &:not(.line-numbers)
    -      padding: 10px 20px
    -
    -    .caption
    -      margin-left: -3.8em
    -      padding: 4px 16px !important
    -
    -      a
    -        padding: 0 !important
    diff --git a/themes/butterfly/source/css/_highlight/prismjs/line-number.styl b/themes/butterfly/source/css/_highlight/prismjs/line-number.styl
    deleted file mode 100644
    index e37215be..00000000
    --- a/themes/butterfly/source/css/_highlight/prismjs/line-number.styl
    +++ /dev/null
    @@ -1,42 +0,0 @@
    -#article-container
    -  pre[class*='language-']
    -    &.line-numbers
    -      position: relative
    -      padding-left: 3.8em
    -      counter-reset: linenumber
    -      line-height: $line-height-code-block
    -
    -      > code
    -        position: relative
    -        line-height: $line-height-code-block
    -
    -        if hexo-config('code_word_wrap')
    -          white-space: pre-wrap
    -        else
    -          white-space: inherit
    -          word-wrap: normal
    -          word-break: normal
    -          overflow-wrap: normal
    -
    -      .line-numbers-rows
    -        position: absolute
    -        top: 0
    -        left: -3.8em
    -        width: 3em
    -        letter-spacing: -1px
    -        font-size: 100%
    -        pointer-events: none
    -        user-select: none
    -        -webkit-user-select: none
    -
    -        & > span
    -          display: block
    -          counter-increment: linenumber
    -          pointer-events: none
    -
    -          &:before
    -            display: block
    -            padding-right: .8em
    -            color: var(--hlnumber-color)
    -            content: counter(linenumber)
    -            text-align: right
    diff --git a/themes/butterfly/source/css/_highlight/theme.styl b/themes/butterfly/source/css/_highlight/theme.styl
    deleted file mode 100644
    index 63393dbe..00000000
    --- a/themes/butterfly/source/css/_highlight/theme.styl
    +++ /dev/null
    @@ -1,119 +0,0 @@
    -if $highlight_theme == 'darker' || ($highlight_theme == 'mac')
    -  $highlight-background = #212121
    -  $highlight-selection = #61616150
    -  $highlight-foreground = #EEFFFF
    -  $highlight-mac-border = rgba(0, 0, 0, .4)
    -  $highlight-gutter = {
    -    color: alpha($highlight-foreground, .5),
    -    bg-color: $highlight-background
    -  }
    -  $highlight-tools = {
    -    color: alpha($highlight-foreground, .8),
    -    bg-color: darken($highlight-background, 2)
    -  }
    -  $highlight-scrollbar = lighten($highlight-background, 8)
    -
    -  if $highlight_enable
    -    $highlight-comment = #969896
    -    $highlight-red = #FF5370
    -    $highlight-orange = #F78C6C
    -    $highlight-yellow = #FFCB6B
    -    $highlight-green = #C3E88D
    -    $highlight-aqua = #89DDFF
    -    $highlight-blue = #82AAFF
    -    $highlight-purple = #C792EA
    -    $highlight-deletion = #BF42BF
    -    $highlight-addition = #105EDE
    -
    -if $highlight_theme == 'pale night'
    -  $highlight-background = #292D3E
    -  $highlight-selection = #717CB450
    -  $highlight-foreground = #A6ACCD
    -  $highlight-gutter = {
    -    color: alpha($highlight-foreground, .5),
    -    bg-color: $highlight-background
    -  }
    -  $highlight-tools = {
    -    color: $highlight-foreground,
    -    bg-color: darken($highlight-background, 2)
    -  }
    -  $highlight-scrollbar = lighten($highlight-background, 8)
    -
    -  if $highlight_enable
    -    $highlight-comment = #676E95
    -    $highlight-red = #FF5370
    -    $highlight-orange = #F78C6C
    -    $highlight-yellow = #FFCB6B
    -    $highlight-green = #C3E88D
    -    $highlight-aqua = #89DDFF
    -    $highlight-blue = #82AAFF
    -    $highlight-purple = #C792EA
    -    $highlight-deletion = #BF42BF
    -    $highlight-addition = #105EDE
    -
    -if $highlight_theme == 'ocean'
    -  $highlight-background = #0F111A
    -  $highlight-selection = #717CB450
    -  $highlight-foreground = #8F93A2
    -  $highlight-gutter = {
    -    color: alpha($highlight-foreground, .5),
    -    bg-color: $highlight-background
    -  }
    -  $highlight-tools = {
    -    color: $highlight-foreground,
    -    bg-color: darken($highlight-background, 2)
    -  }
    -  $highlight-scrollbar = lighten($highlight-background, 8)
    -
    -  if $highlight_enable
    -    $highlight-comment = rgba(101, 115, 126, .8)
    -    $highlight-red = #FF5370
    -    $highlight-orange = #F78C6C
    -    $highlight-yellow = #FFCB6B
    -    $highlight-green = #C3E88D
    -    $highlight-aqua = #89DDFF
    -    $highlight-blue = #82AAFF
    -    $highlight-purple = #C792EA
    -    $highlight-deletion = #BF42BF
    -    $highlight-addition = #105EDE
    -
    -if $highlight_theme == 'light' || ($highlight_theme == 'mac light')
    -  $highlight-background = #F6F8FA
    -  $highlight-selection = #80CBC440
    -  $highlight-foreground = #90A4AE
    -  $highlight-mac-border = rgba(144, 164, 174, .4)
    -  $highlight-tools = {
    -    color: $highlight-foreground,
    -    bg-color: darken($highlight-background, 5)
    -  }
    -  $highlight-gutter = {
    -    color: alpha($highlight-foreground, .5),
    -    bg-color: $highlight-background
    -  }
    -  $highlight-scrollbar = darken($highlight-background, 8)
    -
    -  if $highlight_enable
    -    $highlight-comment = rgba(149, 165, 166, .8)
    -    $highlight-red = #E53935
    -    $highlight-orange = #F76D47
    -    $highlight-yellow = #FFB62C
    -    $highlight-green = #91B859
    -    $highlight-aqua = #39ADB5
    -    $highlight-blue = #6182B8
    -    $highlight-purple = #7C4DFF
    -    $highlight-deletion = #BF42BF
    -    $highlight-addition = #105EDE
    -
    -if $highlight_theme == false
    -  $highlight-background = #F6F8FA
    -  $highlight-foreground = #90A4AE
    -  $highlight-selection = #80CBC440
    -  $highlight-gutter = {
    -    color: alpha($highlight-foreground, .5),
    -    bg-color: $highlight-background
    -  }
    -  $highlight-tools = {
    -    color: $highlight-foreground,
    -    bg-color: darken($highlight-background, 5)
    -  }
    -  $highlight-scrollbar = darken($highlight-background, 8)
    diff --git a/themes/butterfly/source/css/_layout/aside.styl b/themes/butterfly/source/css/_layout/aside.styl
    deleted file mode 100644
    index f9c1bae9..00000000
    --- a/themes/butterfly/source/css/_layout/aside.styl
    +++ /dev/null
    @@ -1,418 +0,0 @@
    -#aside-content
    -  width: 26%
    -
    -  +minWidth900()
    -    if hexo-config('aside.position') == 'right'
    -      padding-left: 15px
    -    else
    -      padding-right: 15px
    -
    -  +maxWidth900()
    -    width: 100%
    -
    -  > .card-widget:first-child
    -    margin-top: 0
    -
    -    +maxWidth900()
    -      margin-top: 20px
    -
    -  .card-widget
    -    @extend .cardHover
    -    position: relative
    -    overflow: hidden
    -    margin-top: 20px
    -    padding: 20px 24px
    -
    -    if hexo-config('aside.mobile') == false
    -      +maxWidth768()
    -        &:not(#card-toc)
    -          display: none
    -
    -  .card-info
    -    .author-info
    -      &__name
    -        font-weight: 500
    -        font-size: 1.57em
    -
    -      &__description
    -        margin-top: -.42em
    -
    -    .card-info-data
    -      margin: 14px 0 4px
    -
    -    .card-info-social-icons
    -      margin: 6px 0 -6px
    -
    -      .social-icon
    -        margin: 0 10px
    -        color: var(--font-color)
    -        font-size: 1.4em
    -
    -      i
    -        transition: all .3s
    -
    -        &:hover
    -          transform: rotate(360deg)
    -
    -    #card-info-btn
    -      display: block
    -      margin-top: 14px
    -      background-color: var(--btn-bg)
    -      color: var(--btn-color)
    -      text-align: center
    -      line-height: 2.4
    -
    -      &:hover
    -        background-color: var(--btn-hover-color)
    -
    -      span
    -        padding-left: 10px
    -
    -  .item-headline
    -    padding-bottom: 6px
    -    font-size: 1.2em
    -
    -    span
    -      margin-left: 6px
    -
    -  .sticky_layout
    -    +minWidth900()
    -      position: sticky
    -      position: -webkit-sticky
    -      top: 20px
    -      transition: top .3s
    -
    -  .card-tag-cloud
    -    a
    -      display: inline-block
    -      padding: 0 4px
    -
    -      &:hover
    -        color: $text-hover !important
    -
    -  .aside-list
    -    & > span
    -      display: block
    -      margin-bottom: 10px
    -      text-align: center
    -
    -    & > .aside-list-item
    -      display: flex
    -      align-items: center
    -      padding: 6px 0
    -
    -      &:first-child
    -        padding-top: 0
    -
    -      &:not(:last-child)
    -        border-bottom: 1px dashed #f5f5f5
    -
    -      &:last-child
    -        padding-bottom: 0
    -
    -      .thumbnail
    -        overflow: hidden
    -        width: w = 4.2em
    -        height: w
    -
    -        :first-child
    -          @extend .imgHover
    -
    -      .content
    -        flex: 1
    -        padding-left: 10px
    -        word-break: break-all
    -
    -        & > .name
    -          @extend .limit-more-line
    -          -webkit-line-clamp: 1
    -
    -        & > time,
    -        & > .name
    -          display: block
    -          color: $theme-meta-color
    -          font-size: 85%
    -
    -        & > .title,
    -        & > .comment
    -          @extend .limit-more-line
    -          color: var(--font-color)
    -          font-size: 95%
    -          line-height: 1.5
    -          -webkit-line-clamp: 2
    -
    -          &:hover
    -            color: $text-hover
    -
    -      &.no-cover
    -        min-height: 4.4em
    -
    -  .card-archives ul.card-archive-list,
    -  .card-categories ul.card-category-list
    -    margin: 0
    -    padding: 0
    -    list-style: none
    -
    -  .card-archives ul.card-archive-list > .card-archive-list-item,
    -  .card-categories ul.card-category-list > .card-category-list-item
    -    a
    -      display: flex
    -      flex-direction: row
    -      padding: 3px 10px
    -      color: var(--font-color)
    -      transition: all .4s
    -
    -      &:hover
    -        padding: 3px 17px
    -        background-color: var(--text-bg-hover)
    -
    -      span
    -        @extend .limit-one-line
    -
    -        &:first-child
    -          flex: 1
    -
    -  .card-categories
    -    .card-category-list
    -      &.child
    -        padding: 0 0 0 16px
    -
    -      > .parent
    -        > a
    -          &.expand
    -            i
    -              transform: rotate(-90deg)
    -
    -            & + .child
    -              display: block
    -
    -          .card-category-list
    -            &-name
    -              width: 70% !important
    -
    -            &-count
    -              width: calc(100% - 70% - 20px)
    -              text-align: right
    -
    -          i
    -            float: right
    -            margin-right: -.5em
    -            padding: .5em
    -            transition: transform .3s
    -            transform: rotate(0)
    -
    -        if hexo-config('aside.card_categories.expand') == false
    -          > .child
    -            display: none
    -
    -  .card-webinfo
    -    .webinfo
    -      .webinfo-item
    -        display: flex
    -        align-items: center
    -        padding: 2px 10px 0
    -
    -        div
    -          &:first-child
    -            flex: 1
    -            padding-right: 20px
    -
    -  // toc
    -  #card-toc
    -    +minWidth901()
    -      right: 0 !important
    -
    -    +maxWidth900()
    -      position: fixed
    -      right: 55px
    -      bottom: 30px
    -      z-index: 100
    -      max-width: $toc-mobile-maxWidth
    -      max-height: calc(100% - 60px)
    -      width: $toc-mobile-width
    -      transition: none
    -      transform: scale(0)
    -      transform-origin: right bottom
    -
    -      &.open
    -        transform: scale(1)
    -
    -    .toc-percentage
    -      float: right
    -      margin-top: -9px
    -      color: #a9a9a9
    -      font-style: italic
    -      font-size: 140%
    -
    -    .toc-content
    -      overflow-y: scroll
    -      overflow-y: overlay
    -      margin: 0 -24px
    -      max-height: calc(100vh - 120px)
    -      width: calc(100% + 48px)
    -
    -      +maxWidth900()
    -        max-height: calc(100vh - 140px)
    -
    -      & > *
    -        margin: 0 20px !important
    -
    -        & > .toc-item > .toc-child
    -          margin-left: 10px
    -          padding-left: 10px
    -          border-left: 1px solid var(--dark-grey)
    -
    -      &:not(.is-expand)
    -        .toc-child
    -          display: none
    -
    -          +maxWidth900()
    -            display: block !important
    -
    -        .toc-item
    -          &.active
    -            .toc-child
    -              display: block
    -
    -      ol,
    -      li
    -        list-style: none
    -
    -      > ol
    -        padding: 0 !important
    -
    -      ol
    -        margin: 0
    -        padding-left: 18px
    -
    -      .toc-link
    -        display: block
    -        margin: 4px 0
    -        padding: 1px 6px
    -        color: var(--toc-link-color)
    -        transition: all .2s ease-in-out
    -
    -        &:hover
    -          color: $theme-color
    -
    -        &.active
    -          background: $theme-toc-color
    -          color: $toc-active-color
    -
    -  .sticky_layout:only-child
    -    > :first-child
    -      margin-top: 0
    -
    -  .card-more-btn
    -    float: right
    -    color: inherit
    -
    -    &:hover
    -      animation: more-btn-move 1s infinite
    -
    -  .card-announcement
    -    .item-headline
    -      i
    -        color: #FF0000
    -
    -.avatar-img
    -  overflow: hidden
    -  margin: 0 auto
    -  width: 110px
    -  height: 110px
    -  border-radius: 70px
    -
    -  img
    -    width: 100%
    -    height: 100%
    -    transition: filter 375ms ease-in .2s, transform .3s
    -    object-fit: cover
    -
    -    &:hover
    -      transform: rotate(360deg)
    -
    -.site-data
    -  display: table
    -  width: 100%
    -  table-layout: fixed
    -
    -  & > a
    -    display: table-cell
    -
    -    div
    -      transition: all .3s
    -
    -    &:hover
    -      div
    -        color: $theme-color !important
    -
    -    .headline
    -      @extend .limit-one-line
    -      color: var(--font-color)
    -
    -    .length-num
    -      margin-top: -.32em
    -      color: var(--text-highlight-color)
    -      font-size: 1.4em
    -
    -@keyframes more-btn-move
    -  0%,
    -  100%
    -    transform: translateX(0)
    -
    -  50%
    -    transform: translateX(3px)
    -
    -@keyframes toc-open
    -  0%
    -    transform: scale(.7)
    -
    -  100%
    -    transform: scale(1)
    -
    -@keyframes toc-close
    -  0%
    -    transform: scale(1)
    -
    -  100%
    -    transform: scale(.7)
    -
    -+minWidth900()
    -  html.hide-aside
    -    .layout
    -      justify-content: center
    -
    -      > .aside-content
    -        display: none
    -
    -      > div:first-child
    -        width: 80%
    -
    -.page
    -  .sticky_layout
    -    display: flex
    -    flex-direction: column
    -
    -  if hexo-config('aside.card_recent_post.sort_order')
    -    .card-recent-post
    -      order: hexo-config('aside.card_recent_post.sort_order')
    -
    -  if hexo-config('newest_comments.sort_order')
    -    #card-newest-comments
    -      order: hexo-config('newest_comments.sort_order')
    -
    -  if hexo-config('aside.card_categories.sort_order')
    -    .card-categories
    -      order: hexo-config('aside.card_categories.sort_order')
    -
    -  if hexo-config('aside.card_tags.sort_order')
    -    .card-tags
    -      order: hexo-config('aside.card_tags.sort_order')
    -
    -  if hexo-config('aside.card_archives.sort_order')
    -    .card-archives
    -      order: hexo-config('aside.card_archives.sort_order')
    -
    -  if hexo-config('aside.card_webinfo.sort_order')
    -    .card-webinfo
    -      order: hexo-config('aside.card_webinfo.sort_order')
    diff --git a/themes/butterfly/source/css/_layout/chat.styl b/themes/butterfly/source/css/_layout/chat.styl
    deleted file mode 100644
    index ea12227e..00000000
    --- a/themes/butterfly/source/css/_layout/chat.styl
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -// chat
    -if hexo-config('chat_btn') == true && hexo-config('chatra.enable')
    -  #chatra:not(.chatra--expanded)
    -    visibility: hidden !important
    -    width: 1px !important
    -    height: 1px !important
    -    opacity: 0 !important
    -    pointer-events: none
    -
    -if hexo-config('chat_btn') == true && hexo-config('messenger.enable')
    -  .fb_dialog,
    -  .fb-customerchat
    -    visibility: hidden !important
    -    width: 1px !important
    -    height: 1px !important
    -    opacity: 0 !important
    -    pointer-events: none
    \ No newline at end of file
    diff --git a/themes/butterfly/source/css/_layout/comments.styl b/themes/butterfly/source/css/_layout/comments.styl
    deleted file mode 100644
    index f2feebdf..00000000
    --- a/themes/butterfly/source/css/_layout/comments.styl
    +++ /dev/null
    @@ -1,81 +0,0 @@
    -#post-comment
    -  .comment-head
    -    margin-bottom: 20px
    -
    -    &:after
    -      display: block
    -      clear: both
    -      content: ''
    -
    -    .comment-headline
    -      display: inline-block
    -      vertical-align: middle
    -      font-weight: 700
    -      font-size: 1.43em
    -
    -    .comment-switch
    -      display: inline-block
    -
    -      if hexo-config('comments.text')
    -        float: right
    -        margin: 2px auto 0
    -        padding: 4px 16px
    -        width: max-content
    -        border-radius: 8px
    -        background: $comments-switch-bg
    -      else
    -        vertical-align: middle
    -
    -        > span
    -          display: none
    -
    -      .first-comment
    -        color: $comments-switch-first-text
    -
    -      .second-comment
    -        color: $comments-switch-second-text
    -
    -      #switch-btn
    -        position: relative
    -        display: inline-block
    -        margin: -4px 8px 0
    -        width: 42px
    -        height: 22px
    -        border-radius: 34px
    -        background-color: $comments-switch-first-text
    -        vertical-align: middle
    -        cursor: pointer
    -        transition: .4s
    -
    -        &:before
    -          position: absolute
    -          bottom: 4px
    -          left: 4px
    -          width: 14px
    -          height: 14px
    -          border-radius: 50%
    -          background-color: $comments-switch-round
    -          content: ''
    -          transition: .4s
    -
    -  .comment-wrap
    -    > div
    -      animation: tabshow .5s
    -
    -      &:nth-child(2)
    -        display: none
    -
    -  &.move
    -    #switch-btn
    -      background-color: $comments-switch-second-text
    -
    -      &:before
    -        transform: translateX(20px)
    -
    -    .comment-wrap
    -      > div
    -        &:first-child
    -          display: none
    -
    -        &:last-child
    -          display: block
    \ No newline at end of file
    diff --git a/themes/butterfly/source/css/_layout/footer.styl b/themes/butterfly/source/css/_layout/footer.styl
    deleted file mode 100644
    index e398510b..00000000
    --- a/themes/butterfly/source/css/_layout/footer.styl
    +++ /dev/null
    @@ -1,35 +0,0 @@
    -#footer
    -  position: relative
    -  background-color: $light-blue
    -  background-attachment: scroll
    -  background-position: bottom
    -  background-size: cover
    -
    -  if hexo-config('footer_bg') != false && hexo-config('mask.footer')
    -    &:before
    -      position: absolute
    -      width: 100%
    -      height: 100%
    -      background-color: var(--mark-bg)
    -      content: ''
    -
    -#footer-wrap
    -  position: relative
    -  padding: 40px 20px
    -  color: var(--light-grey)
    -  text-align: center
    -
    -  a
    -    color: var(--light-grey)
    -
    -    &:hover
    -      text-decoration: underline
    -
    -  .footer-separator
    -    margin: 0 4px
    -
    -  .icp-icon
    -    padding: 0 4px
    -    max-height: 1.4em
    -    width: auto
    -    vertical-align: text-bottom
    diff --git a/themes/butterfly/source/css/_layout/head.styl b/themes/butterfly/source/css/_layout/head.styl
    deleted file mode 100644
    index 3c5f4ce8..00000000
    --- a/themes/butterfly/source/css/_layout/head.styl
    +++ /dev/null
    @@ -1,406 +0,0 @@
    -#page-header
    -  position: relative
    -  width: 100%
    -  background-color: $light-blue
    -  background-position: center center
    -  background-size: cover
    -  background-repeat: no-repeat
    -  transition: all .5s
    -
    -  if hexo-config('mask.header')
    -    &:not(.not-top-img):before
    -      position: absolute
    -      width: 100%
    -      height: 100%
    -      background-color: var(--mark-bg)
    -      content: ''
    -
    -  // index
    -  &.full_page
    -    height: $index_top_img_height
    -    background-attachment: fixed
    -
    -    #site-info
    -      position: absolute
    -      top: $index_site_info_top
    -      padding: 0 10px
    -      width: 100%
    -
    -  #site-title,
    -  #site-subtitle,
    -  #scroll-down .scroll-down-effects
    -    text-align: center
    -    text-shadow: 2px 2px 4px rgba(0, 0, 0, .15)
    -    line-height: 1.5
    -
    -  #site-title
    -    margin: 0
    -    color: var(--white)
    -    font-size: 1.85em
    -
    -    +minWidth768()
    -      font-size: 2.85em
    -
    -  #site-subtitle
    -    color: var(--light-grey)
    -    font-size: 1.15em
    -
    -    +minWidth768()
    -      font-size: 1.72em
    -
    -  #site_social_icons
    -    display: none
    -    margin: 0 auto
    -    text-align: center
    -
    -    +maxWidth768()
    -      display: block
    -
    -    .social-icon
    -      margin: 0 10px
    -      color: var(--light-grey)
    -      text-shadow: 2px 2px 4px rgba(0, 0, 0, .15)
    -      font-size: 1.43em
    -
    -  #scroll-down
    -    position: absolute
    -    bottom: 10px
    -    width: 100%
    -    cursor: pointer
    -
    -    .scroll-down-effects
    -      position: relative
    -      width: 100%
    -      color: var(--light-grey)
    -      font-size: 20px
    -
    -  // page
    -  &.not-home-page
    -    height: 400px
    -
    -    +maxWidth768()
    -      height: 280px
    -
    -  #page-site-info
    -    position: absolute
    -    top: 200px
    -    padding: 0 10px
    -    width: 100%
    -
    -    +maxWidth768()
    -      top: 140px
    -
    -  // post
    -  &.post-bg
    -    height: 400px
    -
    -    +maxWidth768()
    -      height: 360px
    -
    -  #post-info
    -    position: absolute
    -    bottom: 100px
    -    padding: 0 8%
    -    width: 100%
    -    text-align: center
    -
    -    +maxWidth900()
    -      bottom: 30px
    -      text-align: left
    -
    -    +maxWidth768()
    -      bottom: 22px
    -      padding: 0 22px
    -
    -  &.not-top-img
    -    margin-bottom: 10px
    -    height: 60px
    -    background: 0
    -
    -    #nav
    -      background: rgba(255, 255, 255, .8)
    -      box-shadow: 0 5px 6px -5px rgba(133, 133, 133, .6)
    -
    -      a,
    -      .site-name
    -        color: var(--font-color)
    -        text-shadow: none
    -
    -  &.nav-fixed
    -    #nav
    -      position: fixed
    -      top: -60px
    -      z-index: 91
    -      background: rgba(255, 255, 255, .8)
    -      box-shadow: 0 5px 6px -5px alpha($grey, .6)
    -      transition: transform .2s ease-in-out, opacity .2s ease-in-out
    -
    -      #blog-info
    -        color: var(--font-color)
    -
    -        &:hover
    -          color: $light-blue
    -
    -        .site-name
    -          text-shadow: none
    -
    -      a,
    -      #toggle-menu
    -        color: var(--font-color)
    -        text-shadow: none
    -
    -        &:hover
    -          color: $light-blue
    -
    -    &.fixed
    -      #nav
    -        top: 0
    -        transition: all .5s
    -
    -  &.nav-visible:not(.fixed)
    -    #nav
    -      transition: all .5s
    -      transform: translate3d(0, 100%, 0)
    -
    -    & + .layout
    -      & > .aside-content > .sticky_layout
    -        top: 70px
    -        transition: top .5s
    -
    -  &.fixed
    -    #nav
    -      position: fixed
    -
    -    & + .layout
    -      & > .aside-content > .sticky_layout
    -        top: 70px
    -        transition: top .5s
    -
    -      #card-toc
    -        .toc-content
    -          max-height: calc(100vh - 170px)
    -
    -#page
    -  h1.page-title
    -    margin: 8px 0 20px
    -
    -// for not top_img
    -#post
    -  & > #post-info
    -    margin-bottom: 30px
    -
    -    .post-title
    -      padding-bottom: 4px
    -      border-bottom: 1px solid var(--light-grey)
    -      color: var(--text-highlight-color)
    -
    -      .post-edit-link
    -        float: right
    -
    -    #post-meta,
    -    #post-meta a
    -      color: #78818a
    -
    -#post-info
    -  .post-title
    -    @extend .limit-more-line
    -    margin-bottom: 8px
    -    color: var(--white)
    -    font-weight: normal
    -    font-size: 2.5em
    -    line-height: 1.5
    -    -webkit-line-clamp: 3
    -
    -    +maxWidth768()
    -      font-size: 2.1em
    -
    -    .post-edit-link
    -      padding-left: 10px
    -
    -  #post-meta
    -    color: var(--light-grey)
    -    font-size: 95%
    -
    -    +minWidth768()
    -      > .meta-secondline
    -        > span:first-child
    -          display: none
    -
    -    +maxWidth768()
    -      font-size: 90%
    -
    -      > .meta-firstline,
    -      > .meta-secondline
    -        display: inline
    -
    -    .post-meta
    -      &-separator
    -        margin: 0 5px
    -
    -      &-icon
    -        margin-right: 4px
    -
    -      &-label
    -        if hexo-config('post_meta.post.label')
    -          margin-right: 4px
    -        else
    -          display: none
    -
    -    a
    -      color: var(--light-grey)
    -      transition: all .3s ease-out
    -
    -      &:hover
    -        color: $text-hover
    -        text-decoration: underline
    -
    -    if hexo-config('post_meta.post.date_format') == 'relative'
    -      time
    -        display: none
    -
    -#nav
    -  position: absolute
    -  top: 0
    -  z-index: 90
    -  display: flex
    -  align-items: center
    -  padding: 0 36px
    -  width: 100%
    -  height: 60px
    -  font-size: 1.3em
    -  opacity: 0
    -  transition: all .5s
    -
    -  +maxWidth768()
    -    padding: 0 16px
    -
    -  &.show
    -    opacity: 1
    -
    -  #blog-info
    -    flex: 1
    -    color: var(--light-grey)
    -    @extend .limit-one-line
    -
    -    .site-icon
    -      margin-right: 6px
    -      height: 36px
    -      vertical-align: middle
    -
    -  #toggle-menu
    -    display: none
    -    padding: 2px 0 0 6px
    -    vertical-align: top
    -
    -    &:hover
    -      color: var(--white)
    -
    -  a
    -    color: var(--light-grey)
    -
    -    &:hover
    -      color: var(--white)
    -
    -  .site-name
    -    text-shadow: 2px 2px 4px rgba($dark-black, .15)
    -    font-weight: bold
    -
    -  .menus_items
    -    display: inline
    -
    -    .menus_item
    -      position: relative
    -      display: inline-block
    -      padding: 0 0 0 14px
    -
    -      &:hover
    -        .menus_item_child
    -          display: block
    -
    -        & > a > i:last-child
    -          transform: rotate(180deg)
    -
    -      & > a > i:last-child
    -        padding: 4px
    -        transition: transform .3s
    -
    -      .menus_item_child
    -        position: absolute
    -        right: 0
    -        display: none
    -        margin-top: 8px
    -        padding: 0
    -        width: max-content
    -        border-radius: 5px
    -        background-color: var(--sidebar-bg)
    -        box-shadow: 0 5px 20px -4px rgba($dark-black, .5)
    -        animation: sub_menus .3s .1s ease both
    -
    -        &:before
    -          position: absolute
    -          top: -8px
    -          left: 0
    -          width: 100%
    -          height: 20px
    -          content: ''
    -
    -        li
    -          list-style: none
    -
    -          &:hover
    -            background: var(--text-bg-hover)
    -
    -          &:first-child
    -            border-top-left-radius: 5px
    -            border-top-right-radius: 5px
    -
    -          &:last-child
    -            border-bottom-right-radius: 5px
    -            border-bottom-left-radius: 5px
    -
    -          a
    -            display: inline-block
    -            padding: 8px 16px
    -            width: 100%
    -            color: var(--font-color) !important
    -            text-shadow: none !important
    -
    -  &.hide-menu
    -    #toggle-menu
    -      display: inline-block !important
    -
    -      .site-page
    -        font-size: inherit
    -
    -    .menus_items
    -      display: none
    -
    -    #search-button span
    -      display: none
    -
    -  #search-button
    -    display: inline
    -    padding: 0 0 0 14px
    -
    -  .site-page
    -    position: relative
    -    padding-bottom: 6px
    -    text-shadow: 1px 1px 2px rgba($dark-black, .3)
    -    font-size: .78em
    -    cursor: pointer
    -
    -    &:not(.child)
    -      &:after
    -        position: absolute
    -        bottom: 0
    -        left: 0
    -        z-index: -1
    -        width: 0
    -        height: 3px
    -        background-color: lighten($theme-color, 30%)
    -        content: ''
    -        transition: all .3s ease-in-out
    -
    -      &:hover
    -        &:after
    -          width: 100%
    \ No newline at end of file
    diff --git a/themes/butterfly/source/css/_layout/loading.styl b/themes/butterfly/source/css/_layout/loading.styl
    deleted file mode 100644
    index 9f63e15a..00000000
    --- a/themes/butterfly/source/css/_layout/loading.styl
    +++ /dev/null
    @@ -1,95 +0,0 @@
    -if hexo-config('preloader.enable') && hexo-config('preloader.source') == 1
    -  .loading-bg
    -    position: fixed
    -    z-index: 1000
    -    width: 50%
    -    height: 100%
    -    background-color: var(--preloader-bg)
    -
    -  #loading-box
    -    .loading-left-bg
    -      @extend .loading-bg
    -
    -    .loading-right-bg
    -      @extend .loading-bg
    -      right: 0
    -
    -    .spinner-box
    -      position: fixed
    -      z-index: 1001
    -      display: flex
    -      justify-content: center
    -      align-items: center
    -      width: 100%
    -      height: 100vh
    -
    -      .configure-border-1
    -        position: absolute
    -        padding: 3px
    -        width: 115px
    -        height: 115px
    -        background: #ffab91
    -        animation: configure-clockwise 3s ease-in-out 0s infinite alternate
    -
    -      .configure-border-2
    -        left: -115px
    -        padding: 3px
    -        width: 115px
    -        height: 115px
    -        background: rgb(63, 249, 220)
    -        transform: rotate(45deg)
    -        animation: configure-xclockwise 3s ease-in-out 0s infinite alternate
    -
    -      .loading-word
    -        position: absolute
    -        color: var(--preloader-color)
    -        font-size: 16px
    -
    -      .configure-core
    -        width: 100%
    -        height: 100%
    -        background-color: var(--preloader-bg)
    -
    -    &.loaded
    -      .loading-left-bg
    -        transition: all .5s
    -        transform: translate(-100%, 0)
    -
    -      .loading-right-bg
    -        transition: all .5s
    -        transform: translate(100%, 0)
    -
    -      .spinner-box
    -        display: none
    -
    -  @keyframes configure-clockwise
    -    0%
    -      transform: rotate(0)
    -
    -    25%
    -      transform: rotate(90deg)
    -
    -    50%
    -      transform: rotate(180deg)
    -
    -    75%
    -      transform: rotate(270deg)
    -
    -    100%
    -      transform: rotate(360deg)
    -
    -  @keyframes configure-xclockwise
    -    0%
    -      transform: rotate(45deg)
    -
    -    25%
    -      transform: rotate(-45deg)
    -
    -    50%
    -      transform: rotate(-135deg)
    -
    -    75%
    -      transform: rotate(-225deg)
    -
    -    100%
    -      transform: rotate(-315deg)
    diff --git a/themes/butterfly/source/css/_layout/pagination.styl b/themes/butterfly/source/css/_layout/pagination.styl
    deleted file mode 100644
    index 6d729e38..00000000
    --- a/themes/butterfly/source/css/_layout/pagination.styl
    +++ /dev/null
    @@ -1,83 +0,0 @@
    -#pagination
    -  .pagination
    -    margin-top: 20px
    -    text-align: center
    -
    -  .page-number
    -    &.current
    -      background: $theme-paginator-color
    -      color: var(--white)
    -
    -  .pagination-info
    -    position: absolute
    -    top: 50%
    -    padding: 20px 40px
    -    width: 100%
    -    transform: translate(0, -50%)
    -
    -  .prev_info,
    -  .next_info
    -    @extend .limit-one-line
    -    color: var(--white)
    -    font-weight: 500
    -
    -  .next-post
    -    .pagination-info
    -      text-align: right
    -
    -  .pull-full
    -    width: 100% !important
    -
    -  .prev-post .label,
    -  .next-post .label
    -    color: var(--light-grey)
    -    text-transform: uppercase
    -    font-size: 90%
    -
    -  .prev-post,
    -  .next-post
    -    @extend .postImgHover
    -    width: 50%
    -
    -    +maxWidth768()
    -      width: 100%
    -
    -    a
    -      position: relative
    -      display: block
    -      overflow: hidden
    -      height: 150px
    -
    -  &.pagination-post
    -    overflow: hidden
    -    margin-top: 40px
    -    width: 100%
    -    background: $dark-black
    -
    -.layout
    -  & > .recent-posts
    -    .pagination
    -      & > *
    -        display: inline-block
    -        margin: 0 6px
    -        width: w = 2.5em
    -        height: w
    -        line-height: w
    -
    -      & > *:not(.space)
    -        @extend .cardHover
    -
    -        &:hover
    -          background: var(--btn-hover-color)
    -          color: var(--btn-color)
    -
    -  & > div:not(.recent-posts)
    -    .pagination
    -      .page-number
    -        display: inline-block
    -        margin: 0 4px
    -        min-width: w = 24px
    -        height: w
    -        text-align: center
    -        line-height: w
    -        cursor: pointer
    diff --git a/themes/butterfly/source/css/_layout/post.styl b/themes/butterfly/source/css/_layout/post.styl
    deleted file mode 100644
    index 6ad1efc6..00000000
    --- a/themes/butterfly/source/css/_layout/post.styl
    +++ /dev/null
    @@ -1,247 +0,0 @@
    -beautify()
    -  headStyle(fontsize)
    -    padding-left: unit(fontsize + 8, 'px')
    -
    -    &:before
    -      font-size: unit(fontsize - 2, 'px')
    -
    -    &:hover
    -      padding-left: unit(fontsize + 12, 'px')
    -
    -  h1,
    -  h2,
    -  h3,
    -  h4,
    -  h5,
    -  h6
    -    transition: all .2s ease-out
    -
    -    &:before
    -      position: absolute
    -      top: calc(50% - 7px)
    -      color: $title-prefix-icon-color
    -      content: $title-prefix-icon
    -      left: 0
    -      line-height: 1
    -      transition: all .2s ease-out
    -      @extend .fontawesomeIcon
    -
    -    &:hover
    -      &:before
    -        color: $light-blue
    -
    -  h1
    -    headStyle(20)
    -
    -  h2
    -    headStyle(18)
    -
    -  h3
    -    headStyle(16)
    -
    -  h4
    -    headStyle(14)
    -
    -  h5
    -    headStyle(12)
    -
    -  h6
    -    headStyle(12)
    -
    -  ol,
    -  ul
    -    p
    -      margin: 0 0 8px
    -
    -  li
    -    &::marker
    -      color: $light-blue
    -      font-weight: 600
    -      font-size: 1.05em
    -
    -    &:hover
    -      &::marker
    -        color: var(--pseudo-hover)
    -
    -  ul > li
    -    list-style-type: circle
    -  
    -  hr
    -    @extend .custom-hr
    -
    -#article-container
    -  word-wrap: break-word
    -  overflow-wrap: break-word
    -
    -  if hexo-config('text_align_justify')
    -    text-align: justify
    -
    -  a
    -    color: $theme-link-color
    -
    -    &:hover
    -      text-decoration: underline
    -
    -  img
    -    display: block
    -    margin: 0 auto 20px
    -    max-width: 100%
    -    transition: filter 375ms ease-in .2s
    -
    -  p
    -    margin: 0 0 16px
    -
    -  iframe
    -    margin: 0 0 20px
    -
    -  kbd
    -    margin: 0 3px
    -    padding: 3px 5px
    -    border: 1px solid #b4b4b4
    -    border-radius: 3px
    -    background-color: #f8f8f8
    -    box-shadow: 0 1px 3px rgba(0, 0, 0, .25), 0 2px 1px 0 rgba(255, 255, 255, .6) inset
    -    color: #34495e
    -    white-space: nowrap
    -    font-weight: 600
    -    font-size: .9em
    -    font-family: Monaco, 'Ubuntu Mono', monospace
    -    line-height: 1em
    -
    -  if hexo-config('anchor.click_to_scroll')
    -    a.headerlink
    -      position: absolute
    -      top: 0
    -      right: 0
    -      left 0
    -      bottom: 0
    -      width 100%
    -      height: 100%
    -
    -  ol,
    -  ul
    -    ol,
    -    ul
    -      padding-left: 20px
    -
    -    li
    -      margin: 4px 0
    -
    -    p
    -      margin: 0 0 8px
    -
    -  > :last-child
    -    margin-bottom: 0 !important
    -
    -  hr
    -    margin: 20px 0
    -
    -  if hexo-config('beautify.enable')
    -    if hexo-config('beautify.field') == 'site'
    -      beautify()
    -    else if hexo-config('beautify.field') == 'post'
    -      &.post-content
    -        beautify()
    -
    -#post
    -  .tag_share
    -    &:after
    -      display: block
    -      clear: both
    -      content: ''
    -
    -    .post-meta
    -      &__tag-list
    -        display: inline-block
    -
    -      &__tags
    -        display: inline-block
    -        margin: 8px 8px 8px 0
    -        padding: 0 12px
    -        width: fit-content
    -        border: 1px solid $light-blue
    -        border-radius: 12px
    -        color: $light-blue
    -        font-size: .85em
    -        transition: all .2s ease-in-out
    -
    -        &:hover
    -          background: $light-blue
    -          color: var(--white)
    -
    -    .post_share
    -      display: inline-block
    -      float: right
    -      margin: 8px 0 0
    -      width: fit-content
    -
    -      .social-share
    -        font-size: .85em
    -
    -        .social-share-icon
    -          margin: 0 4px
    -          width: w = 1.85em
    -          height: w
    -          font-size: 1.2em
    -          line-height: w
    -
    -  .post-copyright
    -    position: relative
    -    margin: 40px 0 10px
    -    padding: 10px 16px
    -    border: 1px solid var(--light-grey)
    -    transition: box-shadow .3s ease-in-out
    -
    -    &:before
    -      @extend .fontawesomeIcon
    -      position: absolute
    -      top: 2px
    -      right: 12px
    -      color: $theme-color
    -      content: '\f1f9'
    -      font-size: 1.3em
    -
    -    &:hover
    -      box-shadow: 0 0 8px 0 rgba(232, 237, 250, .6), 0 2px 4px 0 rgba(232, 237, 250, .5)
    -
    -    .post-copyright
    -      &-meta
    -        color: $light-blue
    -        font-weight: bold
    -
    -        i
    -          margin-right: 3px
    -
    -      &-info
    -        padding-left: 6px
    -
    -        a
    -          text-decoration: underline
    -          word-break: break-word
    -
    -          &:hover
    -            text-decoration: none
    -
    -  .post-outdate-notice
    -    position: relative
    -    margin: 0 0 20px
    -    padding: .5em 1.2em
    -    border-radius: 3px
    -    background-color: $noticeOutdate-bg
    -    color: $noticeOutdate-color
    -
    -    if hexo-config('noticeOutdate.style') == 'flat'
    -      padding: .5em 1em .5em 2.6em
    -      border-left: 5px solid $noticeOutdate-border
    -
    -      &:before
    -        @extend .fontawesomeIcon
    -        position: absolute
    -        top: 50%
    -        left: .9em
    -        color: $noticeOutdate-border
    -        content: '\f071'
    -        transform: translateY(-50%)
    -
    -  .ads-wrap
    -    margin: 40px 0
    diff --git a/themes/butterfly/source/css/_layout/relatedposts.styl b/themes/butterfly/source/css/_layout/relatedposts.styl
    deleted file mode 100644
    index e0642023..00000000
    --- a/themes/butterfly/source/css/_layout/relatedposts.styl
    +++ /dev/null
    @@ -1,43 +0,0 @@
    -.relatedPosts
    -  margin-top: 40px
    -
    -  & > .headline
    -    margin-bottom: 5px
    -    font-weight: 700
    -    font-size: 1.43em
    -
    -  & > .relatedPosts-list
    -    & > div
    -      position: relative
    -      display: inline-block
    -      overflow: hidden
    -      margin: 3px
    -      width: calc(33.333% - 6px)
    -      height: 200px
    -      background: $dark-black
    -      vertical-align: bottom
    -      @extend .postImgHover
    -
    -      +maxWidth768()
    -        margin: 2px
    -        width: calc(50% - 4px)
    -        height: 150px
    -
    -      +maxWidth600()
    -        width: calc(100% - 4px)
    -
    -    .content
    -      position: absolute
    -      top: 50%
    -      padding: 0 20px
    -      width: 100%
    -      transform: translate(0, -50%)
    -
    -      .date
    -        color: var(--light-grey)
    -        font-size: 90%
    -
    -      .title
    -        @extend .limit-more-line
    -        color: var(--white)
    -        -webkit-line-clamp: 2
    diff --git a/themes/butterfly/source/css/_layout/reward.styl b/themes/butterfly/source/css/_layout/reward.styl
    deleted file mode 100644
    index 4043aa24..00000000
    --- a/themes/butterfly/source/css/_layout/reward.styl
    +++ /dev/null
    @@ -1,77 +0,0 @@
    -.post-reward
    -  position: relative
    -  margin-top: 80px
    -  width: 100%
    -  text-align: center
    -  pointer-events: none
    -
    -  & > *
    -    pointer-events: auto
    -
    -  .reward-button
    -    display: inline-block
    -    padding: 4px 24px
    -    background: var(--btn-bg)
    -    color: var(--btn-color)
    -    cursor: pointer
    -
    -    i
    -      margin-right: 5px
    -
    -  &:hover
    -    .reward-button
    -      background: var(--btn-hover-color)
    -
    -    & > .reward-main
    -      display: block
    -
    -  .reward-main
    -    position: absolute
    -    bottom: 40px
    -    left: 0
    -    z-index: 100
    -    display: none
    -    padding: 0 0 15px
    -    width: 100%
    -
    -    .reward-all
    -      display: inline-block
    -      margin: 0
    -      padding: 20px 10px
    -      border-radius: 4px
    -      background: var(--reward-pop)
    -
    -      &:before
    -        position: absolute
    -        bottom: -10px
    -        left: 0
    -        width: 100%
    -        height: 20px
    -        content: ''
    -
    -      &:after
    -        position: absolute
    -        right: 0
    -        bottom: 2px
    -        left: 0
    -        margin: 0 auto
    -        width: 0
    -        height: 0
    -        border-top: 13px solid var(--reward-pop)
    -        border-right: 13px solid transparent
    -        border-left: 13px solid transparent
    -        content: ''
    -
    -      .reward-item
    -        display: inline-block
    -        padding: 0 8px
    -        list-style-type: none
    -        vertical-align: top
    -
    -        img
    -          width: 130px
    -          height: 130px
    -
    -        .post-qr-code-desc
    -          width: 130px
    -          color: $reward-pop-up-color
    diff --git a/themes/butterfly/source/css/_layout/rightside.styl b/themes/butterfly/source/css/_layout/rightside.styl
    deleted file mode 100644
    index 7d2832c7..00000000
    --- a/themes/butterfly/source/css/_layout/rightside.styl
    +++ /dev/null
    @@ -1,72 +0,0 @@
    -#rightside
    -  position: fixed
    -  right: -48px
    -  bottom: $rightside-bottom
    -  z-index: 100
    -  opacity: 0
    -  transition: all .5s
    -
    -  &.rightside-show
    -    opacity: .8
    -    transform: translate(-58px, 0)
    -
    -  #rightside-config-hide
    -    height: 0
    -    opacity: 0
    -    transition: transform .4s
    -    transform: translate(45px, 0)
    -
    -    &.show
    -      height: auto
    -      opacity: 1
    -      transform: translate(0, 0)
    -
    -    &.status
    -      height: auto
    -      opacity: 1
    -
    -  & > div
    -    & > button,
    -    & > a
    -      display: block
    -      margin-bottom: 5px
    -      width: w = 35px
    -      height: w
    -      border-radius: 5px
    -      background-color: var(--btn-bg)
    -      color: var(--btn-color)
    -      text-align: center
    -      font-size: 16px
    -      line-height: w
    -
    -      &:hover
    -        background-color: var(--btn-hover-color)
    -
    -  #mobile-toc-button
    -    display: none
    -
    -    +maxWidth900()
    -      display: block
    -
    -  +maxWidth900()
    -    #hide-aside-btn
    -      display: none
    -
    -  if hexo-config('rightside_scroll_percent')
    -    #go-up
    -      .scroll-percent
    -        display: none
    -
    -      &.show-percent
    -        .scroll-percent
    -          display: block
    -
    -          & + i
    -            display: none
    -
    -      &:hover
    -        .scroll-percent
    -          display: none
    -
    -          & + i
    -            display: block
    diff --git a/themes/butterfly/source/css/_layout/sidebar.styl b/themes/butterfly/source/css/_layout/sidebar.styl
    deleted file mode 100644
    index 1a126065..00000000
    --- a/themes/butterfly/source/css/_layout/sidebar.styl
    +++ /dev/null
    @@ -1,70 +0,0 @@
    -#sidebar
    -  #menu-mask
    -    position: fixed
    -    z-index: 102
    -    display: none
    -    width: 100%
    -    height: 100%
    -    background: alpha($dark-black, .8)
    -
    -  #sidebar-menus
    -    position: fixed
    -    top: 0
    -    right: -($sidebar-width)
    -    z-index: 103
    -    overflow-x: hidden
    -    overflow-y: scroll
    -    padding-left: 5px
    -    width: $sidebar-width
    -    height: 100%
    -    background: var(--sidebar-bg)
    -    transition: all .5s
    -
    -    &.open
    -      transform: translate3d(-100%, 0, 0)
    -
    -    & > .avatar-img
    -      margin: 20px auto
    -
    -    .sidebar-site-data
    -      padding: 0 10px
    -
    -    hr
    -      margin: 20px auto
    -
    -    .menus_items
    -      padding: 0 5px
    -
    -      .site-page
    -        @extend .limit-one-line
    -        position: relative
    -        display: block
    -        padding: 6px 30px 6px 22px
    -        color: var(--font-color)
    -        font-size: 1.15em
    -
    -        &:hover
    -          background: var(--text-bg-hover)
    -
    -        i:first-child
    -          width: 15%
    -          text-align: left
    -
    -        &.group
    -          & > i:last-child
    -            position: absolute
    -            top: .78em
    -            right: 13px
    -            transition: transform .3s
    -
    -          &.hide
    -            & > i:last-child
    -              transform: rotate(90deg)
    -
    -            & + .menus_item_child
    -              display: none
    -
    -      .menus_item_child
    -        margin: 0
    -        padding-left: 25px
    -        list-style: none
    \ No newline at end of file
    diff --git a/themes/butterfly/source/css/_layout/third-party.styl b/themes/butterfly/source/css/_layout/third-party.styl
    deleted file mode 100644
    index 20705f98..00000000
    --- a/themes/butterfly/source/css/_layout/third-party.styl
    +++ /dev/null
    @@ -1,135 +0,0 @@
    -#vcomment
    -  font-size: 1.1em
    -
    -  .vbtn
    -    border: none
    -    background: var(--btn-bg)
    -    color: var(--btn-color)
    -
    -    &:hover
    -      background: var(--btn-hover-color)
    -
    -  .vimg
    -    transition: all .3s
    -
    -    &:hover
    -      transform: rotate(360deg)
    -
    -  .vcards .vcard .vcontent.expand
    -    &:before,
    -    &:after
    -      z-index: 22
    -
    -#waline-wrap
    -  --waline-font-size: 1.1em
    -  --waline-theme-color: $button-bg
    -  --waline-active-color: $button-hover-color
    -
    -  .wl-comment-actions > button:not(last-child)
    -    padding-right: 4px
    -
    -if hexo-config('valine.bg')
    -  #vcomment
    -    textarea
    -      background: url(hexo-config('valine.bg')) 100% 100% no-repeat
    -
    -      &:focus
    -        background-image: none
    -
    -if hexo-config('waline.bg')
    -  #waline-wrap
    -    textarea
    -      background: url(hexo-config('waline.bg')) 100% 100% no-repeat
    -
    -      &:focus
    -        background-image: none
    -
    -.fireworks
    -  position: fixed
    -  top: 0
    -  left: 0
    -  z-index: $fireworks-zIndex
    -  pointer-events: none
    -
    -.medium-zoom-image--opened
    -  z-index: 99999 !important
    -  margin: 0 !important
    -
    -.medium-zoom-overlay
    -  z-index: 99999 !important
    -
    -.mermaid-wrap
    -  margin: 0 0 20px
    -  text-align: center
    -
    -  & > svg
    -    height: 100%
    -
    -.utterances,
    -.fb-comments iframe
    -  width: 100% !important
    -
    -#gitalk-container
    -  .gt-meta
    -    margin: 0 0 .8em
    -    padding: 6px 0 16px
    -
    -.katex-wrap
    -  overflow: auto
    -
    -  if hexo-config('katex') && hexo-config('katex.hide_scrollbar')
    -    &::-webkit-scrollbar
    -      display: none
    -
    -// Mathjax
    -mjx-container
    -  overflow-x: auto
    -  overflow-y: hidden
    -  padding-bottom: 4px
    -  max-width: 100%
    -
    -  &[display]
    -    display: block !important
    -    min-width: auto !important
    -
    -  &:not([display])
    -    display: inline-grid !important
    -
    -mjx-assistive-mml
    -  right: 0
    -  bottom: 0
    -
    -.aplayer
    -  color: $font-black
    -
    -#article-container
    -  .aplayer
    -    margin: 0 0 20px
    -
    -    if hexo-config('beautify.enable')
    -      ol,
    -      ul
    -        margin: 0
    -        padding: 0
    -
    -        li
    -          margin: 0
    -          padding: 0 15px
    -
    -          &:before
    -            content: none
    -
    -.snackbar-css
    -  border-radius: 5px !important
    -
    -.abc-music-sheet
    -  margin: 0 0 20px
    -  opacity: 0
    -  transition: opacity .3s
    -
    -  &.abcjs-container
    -    opacity: 1
    -
    -+maxWidth768()
    -  .fancybox__toolbar__column.is-middle
    -    display: none
    diff --git a/themes/butterfly/source/css/_mode/darkmode.styl b/themes/butterfly/source/css/_mode/darkmode.styl
    deleted file mode 100644
    index 2251ee82..00000000
    --- a/themes/butterfly/source/css/_mode/darkmode.styl
    +++ /dev/null
    @@ -1,142 +0,0 @@
    -if hexo-config('darkmode.enable') || hexo-config('display_mode') == 'dark'
    -  [data-theme='dark']
    -    --global-bg: darken(#121212, 2)
    -    --font-color: alpha(#FFFFFF, .7)
    -    --hr-border: alpha(#FFFFFF, .4)
    -    --hr-before-color: alpha(#FFFFFF, .7)
    -    --search-bg: #121212
    -    --search-input-color: alpha(#FFFFFF, .7)
    -    --search-a-color: alpha(#FFFFFF, .7)
    -    --preloader-bg: darken(#121212, 2)
    -    --preloader-color: alpha(#FFFFFF, .7)
    -    --tab-border-color: #2c2c2c
    -    --tab-botton-bg: #2c2c2c
    -    --tab-botton-color: alpha(#FFFFFF, .7)
    -    --tab-button-hover-bg: lighten(#121212, 15)
    -    --tab-button-active-bg: #121212
    -    --card-bg: #121212
    -    --sidebar-bg: #121212
    -    --btn-hover-color: lighten(#121212, 40)
    -    --btn-color: alpha(#FFFFFF, .7)
    -    --btn-bg: lighten(#121212, 5)
    -    --text-bg-hover: lighten(#121212, 15)
    -    --light-grey: alpha(#FFFFFF, .7)
    -    --dark-grey: alpha(#FFFFFF, .2)
    -    --white: alpha(#FFFFFF, .9)
    -    --text-highlight-color: alpha(#FFFFFF, .9)
    -    --blockquote-color: alpha(#FFFFFF, .7)
    -    --blockquote-bg: lighten(#121212, 10)
    -    --reward-pop: lighten(#121212, 10)
    -    --toc-link-color: alpha(#FFFFFF, .6)
    -    --scrollbar-color: lighten(#121212, 25)
    -    --timeline-bg: lighten(#121212, 5)
    -    --zoom-bg: #121212
    -    --mark-bg: alpha($dark-black, .6)
    -
    -    #web_bg:before
    -      position: absolute
    -      width: 100%
    -      height: 100%
    -      background-color: alpha($dark-black, .7)
    -      content: ''
    -
    -    #article-container
    -      code
    -        background: #2c2c2c
    -
    -      pre > code
    -        background: lighten(#121212, 2)
    -
    -      figure.highlight
    -        box-shadow: none
    -
    -      .note
    -        code
    -          background: $code-background
    -
    -      .aplayer
    -        filter: brightness(.8)
    -
    -      kbd
    -        border-color: #696969
    -        background-color: #525252
    -        color: #e2f1ff
    -
    -    // 頭部
    -    #page-header
    -      &.nav-fixed > #nav,
    -      &.not-top-img > #nav
    -        background: alpha(#121212, .8)
    -        box-shadow: 0 5px 6px -5px rgba(133, 133, 133, 0)
    -
    -    #post-comment
    -      .comment-switch
    -        if hexo-config('comments.text')
    -          background: #2c2c2c !important
    -
    -        #switch-btn
    -          filter: brightness(.8)
    -
    -    // note
    -    if hexo-config('note.style') == 'modern' || hexo-config('note.style') == 'flat'
    -      .note
    -        filter: brightness(.8)
    -
    -    // hide-tags
    -    .hide-button,
    -    .btn-beautify,
    -    .hl-label,
    -    .post-outdate-notice,
    -    .error-img,
    -    #article-container iframe,
    -    .gist,
    -    .ads-wrap
    -      filter: brightness(.8)
    -
    -    img
    -      if hexo-config('lazyload.enable') && hexo-config('lazyload.blur') && !hexo-config('lazyload.placeholder')
    -        filter: blur(0) brightness(.8)
    -      else
    -        filter: brightness(.8)
    -
    -    #aside-content .aside-list > .aside-list-item:not(:last-child)
    -      border-bottom: 1px dashed alpha(#FFFFFF, .1)
    -
    -    // Gitalk
    -    #gitalk-container
    -      filter: brightness(.8)
    -
    -      svg
    -        fill: alpha(#FFFFFF, .9) !important
    -
    -    // Disqusjs 反代模式下的適配
    -    #disqusjs
    -      #dsqjs
    -        &:hover,
    -        &:focus,
    -        .dsqjs-tab-active,
    -        .dsqjs-no-comment
    -          color: alpha(#FFFFFF, .7)
    -
    -        .dsqjs-order-label
    -          background-color: lighten(#121212, 5)
    -
    -        .dsqjs-post-body
    -          color: alpha(#FFFFFF, .7)
    -
    -          code,
    -          pre
    -            background: #2c2c2c
    -
    -          blockquote
    -            color: alpha(#FFFFFF, .7)
    -
    -    #artitalk_main #lazy
    -      background: #121212
    -
    -    #operare_artitalk .c2
    -      background: #121212
    -
    -    #card-toc
    -      +maxWidth900()
    -        background: lighten(#121212, 5)
    \ No newline at end of file
    diff --git a/themes/butterfly/source/css/_mode/readmode.styl b/themes/butterfly/source/css/_mode/readmode.styl
    deleted file mode 100644
    index 906b50f7..00000000
    --- a/themes/butterfly/source/css/_mode/readmode.styl
    +++ /dev/null
    @@ -1,185 +0,0 @@
    -if hexo-config('readmode')
    -  .read-mode
    -    --font-color: #4c4948
    -    --readmode-light-color: #fff
    -    --white: #4c4948
    -    --light-grey: #4c4948
    -    --gray: #d6dbdf
    -    --hr-border: #d6dbdf
    -    --hr-before-color: darken(#d6dbdf, 10)
    -    --highlight-bg: #f7f7f7
    -    --exit-btn-bg: #C0C0C0
    -    --exit-btn-color: #fff
    -    --exit-btn-hover: darken(#C0C0C0, 20)
    -    --pseudo-hover: none
    -
    -  [data-theme='dark']
    -    .read-mode
    -      --font-color: rgba(255, 255, 255, .7)
    -      --readmode-light-color: #0d0d0d
    -      --white: rgba(255, 255, 255, .9)
    -      --light-grey: rgba(255, 255, 255, .7)
    -      --gray: rgba(255, 255, 255, .7)
    -      --hr-border: rgba(255, 255, 255, .5)
    -      --hr-before-color: rgba(255, 255, 255, .7)
    -      --highlight-bg: #171717
    -      --exit-btn-bg: #1f1f1f
    -      --exit-btn-color: rgba(255, 255, 255, .9)
    -      --exit-btn-hover: lighten(#1f1f1f, 20)
    -
    -  .read-mode
    -    background: var(--readmode-light-color)
    -
    -    .exit-readmode
    -      position: fixed
    -      top: 30px
    -      right: 30px
    -      z-index: 100
    -      width: 40px
    -      height: 40px
    -      border-radius: 8px
    -      background: var(--exit-btn-bg)
    -      color: var(--exit-btn-color)
    -      font-size: 16px
    -      transition: background .3s
    -
    -      +maxWidth768()
    -        top: initial
    -        bottom: 30px
    -
    -      &:hover
    -        background: var(--exit-btn-hover)
    -
    -    #aside-content
    -      display: none
    -
    -    #page-header.post-bg
    -      background: none !important
    -
    -      &:before
    -        opacity: 0
    -
    -      & > #post-info
    -        text-align: center
    -
    -    #post
    -      margin: 0 auto
    -      background: transparent
    -      box-shadow: none
    -
    -      &:hover
    -        box-shadow: none
    -
    -    & > canvas
    -      display: none !important
    -
    -    .highlight-tools,
    -    #footer,
    -    #post > *:not(#post-info):not(.post-content),
    -    #nav,
    -    .post-outdate-notice,
    -    #web_bg,
    -    #rightside,
    -    .not-top-img
    -      display: none !important
    -
    -    #article-container
    -      a
    -        color: #99a9bf
    -
    -      pre,
    -      .highlight:not(.js-file-line-container)
    -        background: var(--highlight-bg) !important
    -
    -        *
    -          color: var(--font-color) !important
    -
    -      figure.highlight
    -        border-radius: 0 !important
    -        box-shadow: none !important
    -
    -        & > :not(.highlight-tools)
    -          display: block !important
    -
    -        .line:before
    -          color: var(--font-color) !important
    -
    -        .hljs
    -          background: var(--highlight-bg) !important
    -
    -      h1,
    -      h2,
    -      h3,
    -      h4,
    -      h5,
    -      h6
    -        padding: 0
    -
    -        &:before
    -          content: ''
    -
    -        &:hover
    -          padding: 0
    -
    -      ul,
    -      li,
    -      ol
    -        &:hover:before
    -          transform: none !important
    -
    -      ol,
    -      li
    -        &:before
    -          background: transparent !important
    -          color: var(--font-color) !important
    -
    -      ul
    -        >li
    -          &:before
    -            border-color: var(--gray) !important
    -
    -      .tabs
    -        border: 2px solid var(--tab-border-color)
    -
    -        > .nav-tabs
    -          background: transparent
    -
    -          > .tab
    -            border-top: none !important
    -
    -        > .tab-contents .tab-item-content.active
    -          animation: none
    -
    -      code
    -        color: var(--font-color)
    -
    -      blockquote
    -        border-color: var(--gray)
    -        background-color: var(--readmode-light-color)
    -
    -      kbd
    -        border: 1px solid var(--gray)
    -        background-color: transparent
    -        box-shadow: none
    -        color: var(--font-color)
    -
    -      .hide-toggle
    -        border: 1px solid var(--gray) !important
    -
    -      .hide-button,
    -      .btn-beautify,
    -      .hl-label
    -        border: 1px solid var(--gray) !important
    -        background: var(--readmode-light-color) !important
    -        color: var(--font-color) !important
    -
    -      .note
    -        border: 2px solid var(--gray)
    -        border-left-color: var(--gray) !important
    -        filter: none
    -        background-color: var(--readmode-light-color) !important
    -        color: var(--font-color)
    -
    -        &:before,
    -        .note-icon
    -          color: var(--font-color)
    diff --git a/themes/butterfly/source/css/_page/404.styl b/themes/butterfly/source/css/_page/404.styl
    deleted file mode 100644
    index ea8e0564..00000000
    --- a/themes/butterfly/source/css/_page/404.styl
    +++ /dev/null
    @@ -1,69 +0,0 @@
    -if hexo-config('error_404.enable')
    -  .error404
    -    #error-wrap
    -      position: absolute
    -      top: 50%
    -      right: 0
    -      left: 0
    -      margin: 0 auto
    -      padding: 60px 20px 0
    -      max-width: 1000px
    -      transform: translate(0, -50%)
    -
    -      .error-content
    -        @extend .cardHover
    -        overflow: hidden
    -        margin: 0 20px
    -        height: 360px
    -
    -        +maxWidth768()
    -          margin: 0
    -          height: 500px
    -
    -        .error-img
    -          display: inline-block
    -          overflow: hidden
    -          width: 50%
    -          height: 100%
    -
    -          +maxWidth768()
    -            width: 100%
    -            height: 45%
    -
    -          img
    -            @extend .imgHover
    -            background-color: $theme-color
    -
    -        .error-info
    -          display: inline-flex
    -          flex-direction: column
    -          justify-content: center
    -          align-content: center
    -          width: 50%
    -          height: 100%
    -          vertical-align: top
    -          text-align: center
    -
    -          if $site-name-font
    -            font-family: $site-name-font
    -
    -          +maxWidth768()
    -            width: 100%
    -            height: 55%
    -
    -          .error_title
    -            margin-top: -.6em
    -            font-size: 9em
    -
    -            +maxWidth768()
    -              font-size: 8em
    -
    -          .error_subtitle
    -            @extend .limit-more-line
    -            margin-top: -3em
    -            word-break: break-word
    -            font-size: 1.6em
    -            -webkit-line-clamp: 2
    -
    -    & + #rightside
    -      display: none
    \ No newline at end of file
    diff --git a/themes/butterfly/source/css/_page/archives.styl b/themes/butterfly/source/css/_page/archives.styl
    deleted file mode 100644
    index 309e00c8..00000000
    --- a/themes/butterfly/source/css/_page/archives.styl
    +++ /dev/null
    @@ -1,109 +0,0 @@
    -.article-sort
    -  margin-left: 10px
    -  padding-left: 20px
    -  border-left: 2px solid lighten($light-blue, 20)
    -
    -  &-title
    -    position: relative
    -    margin-left: 10px
    -    padding-bottom: 20px
    -    padding-left: 20px
    -    font-size: 1.72em
    -
    -    &:hover
    -      &:before
    -        border-color: var(--pseudo-hover)
    -
    -    &:before
    -      position: absolute
    -      top: calc(((100% - 36px) / 2))
    -      left: -9px
    -      z-index: 1
    -      width: w = 10px
    -      height: h = w
    -      border: .5 * w solid $light-blue
    -      border-radius: w
    -      background: var(--card-bg)
    -      content: ''
    -      line-height: h
    -      transition: all .2s ease-in-out
    -
    -    &:after
    -      position: absolute
    -      bottom: 0
    -      left: 0
    -      z-index: 0
    -      width: 2px
    -      height: 1.5em
    -      background: lighten($light-blue, 20)
    -      content: ''
    -
    -  &-item
    -    position: relative
    -    display: flex
    -    align-items: center
    -    margin: 0 0 20px 10px
    -    transition: all .2s ease-in-out
    -
    -    &:hover
    -      &:before
    -        border-color: var(--pseudo-hover)
    -
    -    &:before
    -      $w = 6px
    -      position: absolute
    -      left: calc(-20px - 17px)
    -      width: w = $w
    -      height: h = w
    -      border: .5 * w solid $light-blue
    -      border-radius: w
    -      background: var(--card-bg)
    -      content: ''
    -      transition: all .2s ease-in-out
    -
    -    &.no-article-cover
    -      height: 80px
    -
    -      .article-sort-item-info
    -        padding: 0
    -
    -    &.year
    -      font-size: 1.43em
    -
    -      &:hover
    -        &:before
    -          border-color: $light-blue
    -
    -      &:before
    -        border-color: var(--pseudo-hover)
    -
    -    &-time
    -      color: $theme-meta-color
    -      font-size: 95%
    -
    -      time
    -        padding-left: 6px
    -        cursor: default
    -
    -    &-title
    -      @extend .limit-more-line
    -      color: var(--font-color)
    -      font-size: 1.1em
    -      transition: all .3s
    -      -webkit-line-clamp: 2
    -
    -      &:hover
    -        color: $text-hover
    -        transform: translateX(10px)
    -
    -    &-img
    -      overflow: hidden
    -      width: 80px
    -      height: 80px
    -
    -      :first-child
    -        @extend .imgHover
    -
    -    &-info
    -      flex: 1
    -      padding: 0 16px
    diff --git a/themes/butterfly/source/css/_page/categories.styl b/themes/butterfly/source/css/_page/categories.styl
    deleted file mode 100644
    index 8b80107d..00000000
    --- a/themes/butterfly/source/css/_page/categories.styl
    +++ /dev/null
    @@ -1,37 +0,0 @@
    -.category-lists
    -  .category-title
    -    font-size: 2.57em
    -
    -    +maxWidth768()
    -      font-size: 2em
    -
    -  .category-list
    -    margin-bottom: 0
    -
    -    a
    -      color: var(--font-color)
    -
    -      &:hover
    -        color: $text-hover
    -
    -    .category-list-count
    -      margin-left: 8px
    -      color: $theme-meta-color
    -
    -      &:before
    -        content: '('
    -
    -      &:after
    -        content: ')'
    -
    -  ul
    -    padding: 0 0 0 20px
    -    @extend .list-beauty
    -
    -    ul
    -      padding-left: 4px
    -
    -    li
    -      position: relative
    -      margin: 6px 0
    -      padding: .12em .4em .12em 1.4em
    diff --git a/themes/butterfly/source/css/_page/common.styl b/themes/butterfly/source/css/_page/common.styl
    deleted file mode 100644
    index 32096a5d..00000000
    --- a/themes/butterfly/source/css/_page/common.styl
    +++ /dev/null
    @@ -1,60 +0,0 @@
    -#body-wrap
    -  display: flex
    -  flex-direction: column
    -  min-height: 100vh
    -
    -.layout
    -  display: flex
    -  flex: 1 auto
    -  margin: 0 auto
    -  padding: 40px 15px
    -  max-width: 1200px
    -  width: 100%
    -
    -  +maxWidth900()
    -    flex-direction: column
    -
    -  +maxWidth768()
    -    padding: 20px 5px
    -
    -  +minWidth2000()
    -    max-width: 70%
    -
    -  & > div:first-child:not(.recent-posts)
    -    @extend .cardHover
    -    align-self: flex-start
    -    padding: 50px 40px
    -
    -    +maxWidth768()
    -      padding: 36px 14px
    -
    -  & > div:first-child
    -    width: 74%
    -    transition: all .3s
    -
    -    +maxWidth900()
    -      width: 100% !important
    -
    -    if hexo-config('aside.position') == 'left'
    -      +minWidth900()
    -        order: 2
    -
    -  // 隱藏aside
    -  &.hide-aside
    -    max-width: 1000px
    -
    -    +minWidth2000()
    -      max-width: 1300px
    -
    -    & > div
    -      width: 100% !important
    -
    -// for apple device
    -.apple
    -  #page-header.full_page
    -    background-attachment: scroll !important
    -
    -  .recent-post-item,
    -  .avatar-img,
    -  .flink-item-icon
    -    transform: translateZ(0)
    diff --git a/themes/butterfly/source/css/_page/flink.styl b/themes/butterfly/source/css/_page/flink.styl
    deleted file mode 100644
    index 57dd50a9..00000000
    --- a/themes/butterfly/source/css/_page/flink.styl
    +++ /dev/null
    @@ -1,87 +0,0 @@
    -#article-container
    -  .flink
    -    margin-bottom: 20px
    -
    -    .flink-list
    -      overflow: auto
    -      padding: 10px 10px 0
    -      text-align: center
    -
    -      & > .flink-list-item
    -        position: relative
    -        float: left
    -        overflow: hidden
    -        margin: 15px 7px
    -        width: calc(100% / 3 - 15px)
    -        height: 90px
    -        border-radius: 8px
    -        line-height: 17px
    -        -webkit-transform: translateZ(0)
    -
    -        +maxWidth1024()
    -          width: calc(50% - 15px) !important
    -
    -        +maxWidth600()
    -          width: calc(100% - 15px) !important
    -
    -        &:hover
    -          .flink-item-icon
    -            margin-left: -10px
    -            width: 0
    -
    -        &:before
    -          position: absolute
    -          top: 0
    -          right: 0
    -          bottom: 0
    -          left: 0
    -          z-index: -1
    -          background: var(--text-bg-hover)
    -          content: ''
    -          transition: transform .3s ease-out
    -          transform: scale(0)
    -
    -        &:hover:before,
    -        &:focus:before,
    -        &:active:before
    -          transform: scale(1)
    -
    -        a
    -          color: var(--font-color)
    -          text-decoration: none
    -
    -          .flink-item-icon
    -            float: left
    -            overflow: hidden
    -            margin: 15px 10px
    -            width: 60px
    -            height: 60px
    -            border-radius: 35px
    -            transition: width .3s ease-out
    -
    -            img
    -              width: 100%
    -              height: 100%
    -              transition: filter 375ms ease-in .2s, transform .3s
    -              object-fit: cover
    -
    -          .img-alt
    -            display: none
    -
    -    .flink-item-name
    -      @extend .limit-one-line
    -      padding: 16px 10px 0 0
    -      height: 40px
    -      font-weight: bold
    -      font-size: 1.43em
    -
    -    .flink-item-desc
    -      @extend .limit-one-line
    -      padding: 16px 10px 16px 0
    -      height: 50px
    -      font-size: .93em
    -
    -    .flink-name
    -      margin-bottom: 5px
    -      font-weight: bold
    -      font-size: 1.5em
    \ No newline at end of file
    diff --git a/themes/butterfly/source/css/_page/homepage.styl b/themes/butterfly/source/css/_page/homepage.styl
    deleted file mode 100644
    index e81311a0..00000000
    --- a/themes/butterfly/source/css/_page/homepage.styl
    +++ /dev/null
    @@ -1,115 +0,0 @@
    -#recent-posts
    -  & > .recent-post-item:not(:first-child)
    -    margin-top: 20px
    -
    -  & > .recent-post-item
    -    @extend .cardHover
    -    display: flex
    -    flex-direction: row
    -    align-items: center
    -    overflow: hidden
    -    height: 16.8em
    -
    -    +maxWidth768()
    -      flex-direction: column
    -      height: auto
    -
    -    &:hover
    -      img.post-bg
    -        transform: scale(1.1)
    -
    -    &.ads-wrap
    -      display: block !important
    -      height: auto !important
    -
    -    .post_cover
    -      overflow: hidden
    -      width: 42%
    -      height: 100%
    -
    -      +maxWidth768()
    -        width: 100%
    -        height: 230px
    -
    -      .post-bg
    -        @extend .imgHover
    -
    -      &.right
    -        order: 1
    -
    -        +maxWidth768()
    -          order: 0
    -
    -    & >.recent-post-info
    -      padding: 0 40px
    -      width: 58%
    -
    -      +maxWidth768()
    -        padding: 20px 20px 30px
    -        width: 100%
    -
    -      &.no-cover
    -        width: 100%
    -
    -        +maxWidth768()
    -          padding: 30px 20px
    -
    -      & > .article-title
    -        @extend .limit-more-line
    -        color: var(--text-highlight-color)
    -        font-size: 1.55em
    -        line-height: 1.4
    -        transition: all .2s ease-in-out
    -        -webkit-line-clamp: 2
    -
    -        .sticky
    -          margin-right: 10px
    -          color: $sticky-color
    -          transform: rotate(45deg)
    -
    -        +maxWidth768()
    -          font-size: 1.43em
    -
    -        &:hover
    -          color: $text-hover
    -
    -      & > .article-meta-wrap
    -        margin: 6px 0
    -        color: $theme-meta-color
    -        font-size: .9em
    -
    -        & > .post-meta-date
    -          cursor: default
    -
    -        i
    -          margin: 0 4px 0 0
    -
    -        .fa-spinner
    -          margin: 0
    -
    -        .article-meta-label
    -          if hexo-config('post_meta.page.label')
    -            padding-right: 4px
    -          else
    -            display: none
    -
    -        .article-meta-separator
    -          margin: 0 6px
    -
    -        .article-meta-link
    -          margin: 0 4px
    -
    -        if hexo-config('post_meta.page.date_format') == 'relative'
    -          time
    -            display: none
    -
    -        a
    -          color: $theme-meta-color
    -
    -          &:hover
    -            color: $text-hover
    -            text-decoration: underline
    -
    -      & > .content
    -        @extend .limit-more-line
    -        -webkit-line-clamp: 2
    \ No newline at end of file
    diff --git a/themes/butterfly/source/css/_page/tags.styl b/themes/butterfly/source/css/_page/tags.styl
    deleted file mode 100644
    index bce33ae7..00000000
    --- a/themes/butterfly/source/css/_page/tags.styl
    +++ /dev/null
    @@ -1,23 +0,0 @@
    -.tag-cloud
    -  &-list
    -    a
    -      display: inline-block
    -      padding: 0 8px
    -      transition: all .3s
    -
    -      &:hover
    -        color: $text-hover !important
    -        transform: scale(1.1)
    -
    -      +maxWidth768()
    -        zoom: .85
    -
    -  &-title
    -    font-size: 2.57em
    -
    -    +maxWidth768()
    -      font-size: 2em
    -
    -h1.page-title
    -  & + .tag-cloud-list
    -    text-align: left
    diff --git a/themes/butterfly/source/css/_search/algolia.styl b/themes/butterfly/source/css/_search/algolia.styl
    deleted file mode 100644
    index b2f4067b..00000000
    --- a/themes/butterfly/source/css/_search/algolia.styl
    +++ /dev/null
    @@ -1,87 +0,0 @@
    -#algolia-search
    -  .search-dialog
    -    .ais-SearchBox
    -      input
    -        padding: 5px 14px
    -        width: 100%
    -        outline: none
    -        border: 2px solid $search-color
    -        border-radius: 40px
    -        background: var(--search-bg)
    -        color: var(--search-input-color)
    -
    -    .ais-Hits-list
    -      margin: 0
    -      padding: 0
    -      @extend .list-beauty
    -
    -      a
    -        color: var(--search-a-color)
    -
    -        &:hover
    -          color: $search-color
    -
    -      mark
    -        background: transparent
    -        color: $search-keyword-highlight
    -        font-weight: bold
    -
    -    .algolia-hits-item-title
    -      font-weight: 600
    -
    -    .algolia-hit-item-content
    -      margin: 0 0 8px
    -      word-break: break-word
    -
    -    .ais-Pagination
    -      margin: 15px 0 0
    -      padding: 0
    -      text-align: center
    -
    -      .ais-Pagination-list
    -        margin: 0
    -        padding: 0
    -        list-style: none
    -
    -      .ais-Pagination-item
    -        display: inline
    -        margin: 0 4px
    -        padding: 0
    -
    -        .ais-Pagination-link
    -          display: inline-block
    -          min-width: 24px
    -          height: 24px
    -          text-align: center
    -          line-height: 24px
    -
    -      .ais-Pagination-item--selected
    -        a
    -          background: $theme-paginator-color
    -          color: #eee
    -          cursor: default
    -
    -      .ais-Pagination-item--disabled
    -        visibility: hidden
    -
    -    #algolia-hits
    -      > div
    -        overflow-y: scroll
    -        margin: 0 -20px
    -        padding: 0 22px
    -        max-height: calc(80vh - 240px)
    -
    -        +maxWidth768()
    -          max-height: none
    -          height: calc(var(--search-height) - 265px)
    -
    -    #algolia-info
    -      div
    -        display: inline
    -
    -      .algolia-poweredBy
    -        float: right
    -        vertical-align: text-top
    -
    -        svg
    -          height: 1.1em
    \ No newline at end of file
    diff --git a/themes/butterfly/source/css/_search/index.styl b/themes/butterfly/source/css/_search/index.styl
    deleted file mode 100644
    index 669428b6..00000000
    --- a/themes/butterfly/source/css/_search/index.styl
    +++ /dev/null
    @@ -1,60 +0,0 @@
    -.search-dialog
    -  position: fixed
    -  top: 10%
    -  left: 50%
    -  z-index: 1001
    -  display: none
    -  margin-left: -300px
    -  padding: 20px
    -  width: 600px
    -  border-radius: 8px
    -  background: var(--search-bg)
    -  --search-height: 100vh
    -
    -  +maxWidth768()
    -    top: 0
    -    left: 0
    -    margin: 0
    -    width: 100%
    -    height: 100%
    -    border-radius: 0
    -
    -  hr
    -    margin: 20px auto
    -
    -  .search-nav
    -    margin: 0 0 14px
    -    color: $search-color
    -    font-size: 1.4em
    -    line-height: 1
    -
    -    .search-dialog-title
    -      margin-right: 10px
    -
    -    .search-close-button
    -      float: right
    -      color: $grey
    -      transition: color .2s ease-in-out
    -
    -      &:hover
    -        color: $search-color
    -  
    -  hr
    -    margin: 20px auto
    -    @extend .custom-hr
    -
    -#search-mask
    -  position: fixed
    -  top: 0
    -  right: 0
    -  bottom: 0
    -  left: 0
    -  z-index: 1000
    -  display: none
    -  background: rgba($dark-black, .6)
    -
    -if hexo-config('algolia_search.enable')
    -  @require 'algolia'
    -
    -if hexo-config('local_search.enable')
    -  @require 'local-search'
    \ No newline at end of file
    diff --git a/themes/butterfly/source/css/_search/local-search.styl b/themes/butterfly/source/css/_search/local-search.styl
    deleted file mode 100644
    index c8dfdfe2..00000000
    --- a/themes/butterfly/source/css/_search/local-search.styl
    +++ /dev/null
    @@ -1,70 +0,0 @@
    -#local-search
    -  .search-dialog
    -    .local-search-box
    -      margin: 0 auto
    -      max-width: 100%
    -      width: 100%
    -
    -      input
    -        padding: 5px 14px
    -        width: 100%
    -        outline: none
    -        border: 2px solid $search-color
    -        border-radius: 40px
    -        background: var(--search-bg)
    -        color: var(--search-input-color)
    -        -webkit-appearance: none
    -
    -    .search-wrap
    -      display: none
    -
    -    .local-search-hit-item
    -      position: relative
    -      padding-left: 24px
    -      line-height: 1.7
    -
    -      &:hover
    -        &:before
    -          border-color: var(--pseudo-hover)
    -
    -      &:before
    -        $w = .5em
    -        position: absolute
    -        top: .45em
    -        left: 0
    -        width: w = $w
    -        height: h = w
    -        border: 3px solid $search-color
    -        border-radius: w
    -        background: transparent
    -        content: ''
    -        line-height: h
    -        transition: all .2s ease-in-out
    -
    -      a
    -        display: block
    -        color: var(--search-a-color)
    -
    -        &:hover
    -          color: $search-color
    -
    -      .search-result-title
    -        font-weight: 600
    -
    -      .search-result
    -        margin: 0 0 8px
    -        word-break: break-word
    -
    -    .search-result-list
    -      overflow-y: overlay
    -      margin: 0 -20px
    -      padding: 0 22px
    -      max-height: calc(80vh - 200px)
    -
    -      +maxWidth768()
    -        max-height: calc(var(--search-height) - 220px) !important
    -
    -.search-keyword
    -  background: transparent
    -  color: $search-keyword-highlight
    -  font-weight: bold
    \ No newline at end of file
    diff --git a/themes/butterfly/source/css/_tags/button.styl b/themes/butterfly/source/css/_tags/button.styl
    deleted file mode 100644
    index c4b2c3ac..00000000
    --- a/themes/butterfly/source/css/_tags/button.styl
    +++ /dev/null
    @@ -1,55 +0,0 @@
    -#article-container
    -  .btn-center
    -    margin: 0 0 20px
    -    text-align: center
    -
    -  .btn-beautify
    -    display: inline-block
    -    margin: 0 4px 6px
    -    padding: 0 15px
    -    background-color: var(--btn-beautify-color, $btn-default-color)
    -    color: $btn-color
    -    line-height: 2
    -
    -    for $type in $color-types
    -      &.{$type}
    -        --btn-beautify-color: lookup('$tagsP-' + $type + '-color')
    -
    -    &:hover
    -      background-color: var(--btn-hover-color)
    -
    -    i + span
    -      margin-left: 6px
    -
    -    &:not(.block) + .btn-beautify:not(.block)
    -      margin: 0 4px 20px
    -
    -    &.block
    -      display: block
    -      margin: 0 0 20px
    -      width: fit-content
    -      width: -moz-fit-content
    -
    -      &.center
    -        margin: 0 auto 20px
    -
    -      &.right
    -        margin: 0 0 20px auto
    -
    -    &.larger
    -      padding: 6px 15px
    -
    -    &:hover
    -      text-decoration: none
    -
    -    &.outline
    -      border: 1px solid transparent
    -      border-color: var(--btn-beautify-color, $btn-default-color)
    -      background-color: transparent
    -      color: var(--btn-beautify-color, $btn-default-color)
    -
    -      &:hover
    -        background-color: var(--btn-beautify-color, $btn-default-color)
    -
    -      &:hover
    -        color: white !important
    diff --git a/themes/butterfly/source/css/_tags/gallery.styl b/themes/butterfly/source/css/_tags/gallery.styl
    deleted file mode 100644
    index 2c0aa957..00000000
    --- a/themes/butterfly/source/css/_tags/gallery.styl
    +++ /dev/null
    @@ -1,205 +0,0 @@
    -#article-container
    -  figure.gallery-group
    -    position: relative
    -    float: left
    -    overflow: hidden
    -    margin: 6px 4px
    -    width: calc(50% - 8px)
    -    height: 250px
    -    border-radius: 8px
    -    background: $dark-black
    -    -webkit-transform: translate3d(0, 0, 0)
    -
    -    +maxWidth600()
    -      width: calc(100% - 8px)
    -
    -    &:hover
    -      img
    -        opacity: .4
    -        transform: translate3d(0, 0, 0)
    -
    -      .gallery-group-name::after
    -        transform: translate3d(0, 0, 0)
    -
    -      p
    -        opacity: 1
    -        transform: translate3d(0, 0, 0)
    -
    -    img
    -      position: relative
    -      margin: 0
    -      max-width: none
    -      width: calc(100% + 20px)
    -      height: 250px
    -      backface-visibility: hidden
    -      opacity: .8
    -      transition: all .3s, filter 375ms ease-in .2s
    -      transform: translate3d(-10px, 0, 0)
    -      object-fit: cover
    -
    -    figcaption
    -      position: absolute
    -      top: 0
    -      left: 0
    -      padding: 30px
    -      width: 100%
    -      height: 100%
    -      color: $gallery-color
    -      text-transform: uppercase
    -      backface-visibility: hidden
    -
    -      & > a
    -        position: absolute
    -        top: 0
    -        right: 0
    -        bottom: 0
    -        left: 0
    -        z-index: 1000
    -        opacity: 0
    -
    -    p
    -      @extend .limit-more-line
    -      margin: 0
    -      padding: 8px 0 0
    -      letter-spacing: 1px
    -      font-size: 1.1em
    -      line-height: 1.5
    -      opacity: 0
    -      transition: opacity .35s, transform .35s
    -      transform: translate3d(100%, 0, 0)
    -      -webkit-line-clamp: 4
    -
    -    .gallery-group-name
    -      @extend .limit-more-line
    -      position: relative
    -      margin: 0
    -      padding: 8px 0
    -      font-weight: bold
    -      font-size: 1.65em
    -      line-height: 1.5
    -      -webkit-line-clamp: 2
    -
    -      &:after
    -        position: absolute
    -        bottom: 0
    -        left: 0
    -        width: 100%
    -        height: 2px
    -        background: $gallery-color
    -        content: ''
    -        transition: transform .35s
    -        transform: translate3d(-100%, 0, 0)
    -
    -  .gallery-group-main
    -    overflow: auto
    -    padding: 0 0 16px
    -
    -  .gallery-container
    -    margin: 0 0 16px
    -    text-align: center
    -
    -    img
    -      display: initial
    -      margin: 0
    -      width: 100%
    -      height: 100%
    -
    -    .gallery-data
    -      display: none
    -
    -    button
    -      margin-top: 25px
    -      padding: 10px
    -      width: 9em
    -      border-radius: 5px
    -      background: var(--btn-bg)
    -      color: var(--btn-color)
    -      font-weight: bold
    -      font-size: 1.1em
    -      transition: all .3s
    -
    -      &:hover
    -        background: var(--btn-hover-color)
    -
    -  .loading-container
    -    display: inline-block
    -    overflow: hidden
    -    width: 154px
    -    height: 154px
    -
    -    .loading-item
    -      position: relative
    -      width: 100%
    -      height: 100%
    -      backface-visibility: hidden
    -      transform: translateZ(0) scale(1)
    -      transform-origin: 0 0
    -
    -      div
    -        position: absolute
    -        width: 30.8px
    -        height: 30.8px
    -        border-radius: 50%
    -        background: #e15b64
    -        transform: translate(61.6px, 61.6px) scale(1)
    -        animation: loading-ball 1.92s infinite cubic-bezier(0, .5, .5, 1)
    -
    -        &:nth-child(1)
    -          background: #f47e60
    -          transform: translate(113.96px, 61.6px) scale(1)
    -          animation: loading-ball-r .48s infinite cubic-bezier(0, .5, .5, 1), loading-ball-c 1.92s infinite step-start
    -
    -        &:nth-child(2)
    -          background: #e15b64
    -          animation-delay: -.48s
    -
    -        &:nth-child(3)
    -          background: #f47e60
    -          animation-delay: -.96s
    -
    -        &:nth-child(4)
    -          background: #f8b26a
    -          animation-delay: -1.44s
    -
    -        &:nth-child(5)
    -          background: #abbd81
    -          animation-delay: -1.92s
    -
    -@keyframes loading-ball
    -  0%
    -    transform: translate(9.24px, 61.6px) scale(0)
    -
    -  25%
    -    transform: translate(9.24px, 61.6px) scale(0)
    -
    -  50%
    -    transform: translate(9.24px, 61.6px) scale(1)
    -
    -  75%
    -    transform: translate(61.6px, 61.6px) scale(1)
    -
    -  100%
    -    transform: translate(113.96px, 61.6px) scale(1)
    -
    -@keyframes loading-ball-r
    -  0%
    -    transform: translate(113.96px, 61.6px) scale(1)
    -
    -  100%
    -    transform: translate(113.96px, 61.6px) scale(0)
    -
    -@keyframes loading-ball-c
    -  0%
    -    background: #e15b64
    -
    -  25%
    -    background: #abbd81
    -
    -  50%
    -    background: #f8b26a
    -
    -  75%
    -    background: #f47e60
    -
    -  100%
    -    background: #e15b64
    diff --git a/themes/butterfly/source/css/_tags/hexo.styl b/themes/butterfly/source/css/_tags/hexo.styl
    deleted file mode 100644
    index 08cdee78..00000000
    --- a/themes/butterfly/source/css/_tags/hexo.styl
    +++ /dev/null
    @@ -1,30 +0,0 @@
    -// pullquote
    -blockquote
    -  &.pullquote
    -    position: relative
    -    max-width: 45%
    -    font-size: 110%
    -
    -    &.left
    -      float: left
    -      margin: 1em .5em 0 0
    -
    -    &.right
    -      float: right
    -      margin: 1em 0 0 .5em
    -
    -// hexo tag video
    -.video-container
    -  position: relative
    -  overflow: hidden
    -  margin-bottom: 16px
    -  padding-top: 56.25%
    -  height: 0
    -
    -  iframe
    -    position: absolute
    -    top: 0
    -    left: 0
    -    margin-top: 0
    -    width: 100%
    -    height: 100%
    diff --git a/themes/butterfly/source/css/_tags/hide.styl b/themes/butterfly/source/css/_tags/hide.styl
    deleted file mode 100644
    index 2442e937..00000000
    --- a/themes/butterfly/source/css/_tags/hide.styl
    +++ /dev/null
    @@ -1,46 +0,0 @@
    -// tag-hide
    -.hide-inline,
    -.hide-block
    -  & > .hide-button
    -    display: inline-block
    -    padding: 5px 18px
    -    background: $tag-hide-bg
    -    color: var(--white)
    -
    -    &:hover
    -      background-color: var(--btn-hover-color)
    -
    -    &.open
    -      display: none
    -
    -      & + div
    -        display: block
    -
    -      & + span
    -        display: inline
    -
    -  & > .hide-content
    -    display: none
    -
    -.hide-inline
    -  & > .hide-button
    -    margin: 0 6px
    -
    -  & > .hide-content
    -    margin: 0 6px
    -
    -.hide-block
    -  margin: 0 0 16px
    -
    -.toggle
    -  margin-bottom: 20px
    -  border: 1px solid $tag-hide-toggle-bg
    -
    -  & > .toggle-button
    -    padding: 6px 15px
    -    background: $tag-hide-toggle-bg
    -    color: #1F2D3D
    -    cursor: pointer
    -
    -  & > .toggle-content
    -    margin: 30px 24px
    diff --git a/themes/butterfly/source/css/_tags/inlineImg.styl b/themes/butterfly/source/css/_tags/inlineImg.styl
    deleted file mode 100644
    index c8bb0c10..00000000
    --- a/themes/butterfly/source/css/_tags/inlineImg.styl
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -#article-container
    -  .inline-img
    -    display: inline
    -    margin: 0 3px
    -    height: 1.1em
    -    vertical-align: text-bottom
    \ No newline at end of file
    diff --git a/themes/butterfly/source/css/_tags/label.styl b/themes/butterfly/source/css/_tags/label.styl
    deleted file mode 100644
    index d7b814ed..00000000
    --- a/themes/butterfly/source/css/_tags/label.styl
    +++ /dev/null
    @@ -1,11 +0,0 @@
    -.hl-label
    -  padding: 2px 4px
    -  border-radius: 3px
    -  color: $btn-color
    -
    -  &.default
    -    background-color: $btn-default-color
    -
    -  for $type in $color-types
    -    &.{$type}
    -      background-color: lookup('$tagsP-' + $type + '-color')
    diff --git a/themes/butterfly/source/css/_tags/note.styl b/themes/butterfly/source/css/_tags/note.styl
    deleted file mode 100644
    index 041603ff..00000000
    --- a/themes/butterfly/source/css/_tags/note.styl
    +++ /dev/null
    @@ -1,124 +0,0 @@
    -.note
    -  $note-icons = hexo-config('note.icons')
    -  position: relative
    -  margin: 0 0 20px
    -  padding: 15px
    -
    -  if hexo-config('note.border_radius') is a 'unit'
    -    border-radius: unit(hexo-config('note.border_radius'), px)
    -
    -  &.icon-padding
    -    padding-left: 3em
    -
    -  & > .note-icon
    -    position: absolute
    -    top: calc(50% - .5em)
    -    left: .8em
    -    font-size: larger
    -
    -  for $type in $color-types
    -    &.{$type}
    -      &:not(.disabled)
    -        border-left-color: lookup('$tagsP-' + $type + '-color') !important
    -
    -        &.modern
    -          border-left-color: transparent !important
    -          color: lookup('$tagsP-' + $type + '-color')
    -
    -        &:not(.simple)
    -          background: lighten(lookup('$tagsP-' + $type + '-color'), 85%) !important
    -
    -      & > .note-icon
    -        color: lookup('$tagsP-' + $type + '-color')
    -
    -  &.simple
    -    border: 1px solid #EEEEEE
    -    border-left-width: 5px
    -
    -  &.modern
    -    border: 1px solid transparent !important
    -    background-color: #f5f5f5
    -    color: $font-black
    -
    -  &.flat
    -    border: initial
    -    border-left: 5px solid #EEEEEE
    -    background-color: lighten(#EEEEEE, 65%)
    -    color: $font-black
    -
    -  h2,
    -  h3,
    -  h4,
    -  h5,
    -  h6
    -    if $note-icons
    -      margin-top: 3px
    -    else
    -      margin-top: 0
    -
    -    margin-bottom: 0
    -    padding-top: 0 !important
    -    border-bottom: initial
    -
    -  p,
    -  ul,
    -  ol,
    -  table,
    -  pre,
    -  blockquote,
    -  img
    -    &:first-child
    -      margin-top: 0 !important
    -
    -    &:last-child
    -      margin-bottom: 0 !important
    -
    -  .img-alt
    -    margin: 5px 0 10px
    -
    -  if $note-icons
    -    &:not(.no-icon)
    -      padding-left: 3em
    -
    -      &::before
    -        position: absolute
    -        top: calc(50% - .95em)
    -        left: .8em
    -        font-size: larger
    -        @extend .fontawesomeIcon
    -
    -  for $type in $note-types
    -    &.{$type}
    -      &.flat
    -        background: lookup('$note-' + $type + '-bg')
    -
    -      &.modern
    -        border-color: lookup('$note-modern-' + $type + '-border')
    -        background: lookup('$note-modern-' + $type + '-bg')
    -        color: lookup('$note-modern-' + $type + '-text')
    -
    -        a
    -          &:not(.btn)
    -            color: lookup('$note-modern-' + $type + '-text')
    -
    -            &:hover
    -              color: lookup('$note-modern-' + $type + '-hover')
    -
    -      &:not(.modern)
    -        border-left-color: lookup('$note-' + $type + '-border')
    -
    -        h2,
    -        h3,
    -        h4,
    -        h5,
    -        h6
    -          color: lookup('$note-' + $type + '-text')
    -
    -      if $note-icons
    -        &:not(.no-icon)
    -          &::before
    -            content: lookup('$note-' + $type + '-icon')
    -
    -          &:not(.modern)
    -            &::before
    -              color: lookup('$note-' + $type + '-text')
    diff --git a/themes/butterfly/source/css/_tags/tabs.styl b/themes/butterfly/source/css/_tags/tabs.styl
    deleted file mode 100644
    index 2447a1b2..00000000
    --- a/themes/butterfly/source/css/_tags/tabs.styl
    +++ /dev/null
    @@ -1,75 +0,0 @@
    -
    -#article-container
    -  .tabs
    -    position: relative
    -    margin: 0 0 20px
    -    border-right: 1px solid var(--tab-border-color)
    -    border-bottom: 1px solid var(--tab-border-color)
    -    border-left: 1px solid var(--tab-border-color)
    -
    -    > .nav-tabs
    -      display: flex
    -      flex-wrap: wrap
    -      margin: 0
    -      padding: 0
    -      background: var(--tab-botton-bg)
    -
    -      > .tab
    -        flex-grow: 1
    -        padding: 8px 18px
    -        border-top: 2px solid var(--tab-border-color)
    -        background: var(--tab-botton-bg)
    -        color: var(--tab-botton-color)
    -        line-height: 2
    -        transition: all .4s
    -
    -        i
    -          width: 1.5em
    -
    -        &.active
    -          border-top: 2px solid $tab-active-border-color
    -          background: var(--tab-button-active-bg)
    -          cursor: default
    -
    -        &:not(.active)
    -          &:hover
    -            border-top: 2px solid var(--tab-button-hover-bg)
    -            background: var(--tab-button-hover-bg)
    -
    -      &.no-default
    -        & ~ .tab-to-top
    -          display: none
    -
    -    > .tab-contents
    -      .tab-item-content
    -        position: relative
    -        display: none
    -        padding: 36px 24px 10px
    -
    -        +maxWidth768()
    -          padding: 24px 14px
    -
    -        &.active
    -          display: block
    -          animation: tabshow .5s
    -
    -        > :last-child
    -          margin-bottom: 0
    -
    -    > .tab-to-top
    -      padding: 0 16px 10px 0
    -      width: 100%
    -      text-align: right
    -
    -      button
    -        color: $tab-to-top-color
    -
    -        &:hover
    -          color: $tab-to-top-hover-color
    -
    -@keyframes tabshow
    -  0%
    -    transform: translateY(15px)
    -
    -  100%
    -    transform: translateY(0)
    diff --git a/themes/butterfly/source/css/_tags/timeline.styl b/themes/butterfly/source/css/_tags/timeline.styl
    deleted file mode 100644
    index aba927ba..00000000
    --- a/themes/butterfly/source/css/_tags/timeline.styl
    +++ /dev/null
    @@ -1,68 +0,0 @@
    -#article-container
    -  .timeline
    -    margin: 0 0 20px 10px
    -    padding: 14px 20px 5px
    -    border-left: 2px solid var(--timeline-color, $theme-color)
    -
    -    for $type in $color-types
    -      &.{$type}
    -        --timeline-color: lookup('$tagsP-' + $type + '-color')
    -        --timeline-bg: s('rgba(%s,%s,%s, 0.2)', red(lookup('$tagsP-' + $type + '-color')), green(lookup('$tagsP-' + $type + '-color')), blue(lookup('$tagsP-' + $type + '-color')))
    -
    -    .timeline-item
    -      margin: 0 0 15px
    -
    -      &:hover
    -        .item-circle
    -          &:before
    -            border-color: var(--timeline-color, $theme-color)
    -
    -      &.headline
    -        .timeline-item-title
    -          .item-circle
    -            > p
    -              font-weight: 600
    -              font-size: 1.2em
    -
    -            &:before
    -              left: -28px
    -              border: 4px solid var(--timeline-color, $theme-color)
    -
    -        &:hover
    -          .item-circle
    -            &:before
    -              border-color: var(--pseudo-hover)
    -
    -      .timeline-item-title
    -        position: relative
    -
    -      .item-circle
    -        &:before
    -          position: absolute
    -          top: 50%
    -          left: -27px
    -          width: 6px
    -          height: 6px
    -          border: 3px solid var(--pseudo-hover)
    -          border-radius: 50%
    -          background: var(--card-bg)
    -          content: ''
    -          transition: all .3s
    -          transform: translate(0, -50%)
    -
    -        > p
    -          margin: 0 0 8px
    -          font-weight: 500
    -
    -      .timeline-item-content
    -        position: relative
    -        padding: 12px 15px
    -        border-radius: 8px
    -        background: var(--timeline-bg, lighten($theme-color, 85%))
    -        font-size: .93em
    -
    -        & > :last-child
    -          margin-bottom: 0
    -
    -    & + .timeline
    -      margin-top: -20px
    \ No newline at end of file
    diff --git a/themes/butterfly/source/css/_third-party/normalize.min.css b/themes/butterfly/source/css/_third-party/normalize.min.css
    deleted file mode 100644
    index ecc522f5..00000000
    --- a/themes/butterfly/source/css/_third-party/normalize.min.css
    +++ /dev/null
    @@ -1,180 +0,0 @@
    -/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
    -html {
    -  line-height: 1.15;
    -  -webkit-text-size-adjust: 100%
    -}
    -
    -body {
    -  margin: 0
    -}
    -
    -main {
    -  display: block
    -}
    -
    -h1 {
    -  font-size: 2em;
    -  margin: .67em 0
    -}
    -
    -hr {
    -  box-sizing: content-box;
    -  height: 0;
    -  overflow: visible
    -}
    -
    -pre {
    -  font-family: monospace, monospace;
    -  font-size: 1em
    -}
    -
    -a {
    -  background-color: transparent
    -}
    -
    -abbr[title] {
    -  border-bottom: none;
    -  text-decoration: underline;
    -  text-decoration: underline dotted
    -}
    -
    -b,
    -strong {
    -  font-weight: bolder
    -}
    -
    -code,
    -kbd,
    -samp {
    -  font-family: monospace, monospace;
    -  font-size: 1em
    -}
    -
    -small {
    -  font-size: 80%
    -}
    -
    -sub,
    -sup {
    -  font-size: 75%;
    -  line-height: 0;
    -  position: relative;
    -  vertical-align: baseline
    -}
    -
    -sub {
    -  bottom: -.25em
    -}
    -
    -sup {
    -  top: -.5em
    -}
    -
    -img {
    -  border-style: none
    -}
    -
    -button,
    -input,
    -optgroup,
    -select,
    -textarea {
    -  font-family: inherit;
    -  font-size: 100%;
    -  line-height: 1.15;
    -  margin: 0
    -}
    -
    -button,
    -input {
    -  overflow: visible
    -}
    -
    -button,
    -select {
    -  text-transform: none
    -}
    -
    -[type=button],
    -[type=reset],
    -[type=submit],
    -button {
    -  -webkit-appearance: button
    -}
    -
    -[type=button]::-moz-focus-inner,
    -[type=reset]::-moz-focus-inner,
    -[type=submit]::-moz-focus-inner,
    -button::-moz-focus-inner {
    -  border-style: none;
    -  padding: 0
    -}
    -
    -[type=button]:-moz-focusring,
    -[type=reset]:-moz-focusring,
    -[type=submit]:-moz-focusring,
    -button:-moz-focusring {
    -  outline: 1px dotted ButtonText
    -}
    -
    -fieldset {
    -  padding: .35em .75em .625em
    -}
    -
    -legend {
    -  box-sizing: border-box;
    -  color: inherit;
    -  display: table;
    -  max-width: 100%;
    -  padding: 0;
    -  white-space: normal
    -}
    -
    -progress {
    -  vertical-align: baseline
    -}
    -
    -textarea {
    -  overflow: auto
    -}
    -
    -[type=checkbox],
    -[type=radio] {
    -  box-sizing: border-box;
    -  padding: 0
    -}
    -
    -[type=number]::-webkit-inner-spin-button,
    -[type=number]::-webkit-outer-spin-button {
    -  height: auto
    -}
    -
    -[type=search] {
    -  -webkit-appearance: textfield;
    -  outline-offset: -2px
    -}
    -
    -[type=search]::-webkit-search-decoration {
    -  -webkit-appearance: none
    -}
    -
    -::-webkit-file-upload-button {
    -  -webkit-appearance: button;
    -  font: inherit
    -}
    -
    -details {
    -  display: block
    -}
    -
    -summary {
    -  display: list-item
    -}
    -
    -template {
    -  display: none
    -}
    -
    -[hidden] {
    -  display: none
    -}
    \ No newline at end of file
    diff --git a/themes/butterfly/source/css/index.styl b/themes/butterfly/source/css/index.styl
    deleted file mode 100644
    index 0cfec1f3..00000000
    --- a/themes/butterfly/source/css/index.styl
    +++ /dev/null
    @@ -1,15 +0,0 @@
    -if hexo-config('css_prefix')
    -  @import 'nib'
    -
    -@import '_third-party/normalize.min.css'
    -// project
    -@import 'var'
    -@import '_global/*'
    -@import '_highlight/highlight'
    -@import '_page/*'
    -@import '_layout/*'
    -@import '_tags/*'
    -@import '_mode/*'
    -
    -// search
    -@import '_search/index'
    \ No newline at end of file
    diff --git a/themes/butterfly/source/css/var.styl b/themes/butterfly/source/css/var.styl
    deleted file mode 100644
    index 09e41293..00000000
    --- a/themes/butterfly/source/css/var.styl
    +++ /dev/null
    @@ -1,184 +0,0 @@
    -// color
    -$bright-blue = #49B1F5
    -$strong-cyan = #00c4b6
    -$light-orange = #FF7242
    -$light-red = #F47466
    -$themeColorEnable = hexo-config('theme_color') && hexo-config('theme_color.enable')
    -$theme-color = $themeColorEnable && hexo-config('theme_color.main') ? convert(hexo-config('theme_color.main')) : $bright-blue
    -$theme-paginator-color = $themeColorEnable && hexo-config('theme_color.paginator') ? convert(hexo-config('theme_color.paginator')) : $strong-cyan
    -$theme-text-selection-color = $themeColorEnable && hexo-config('theme_color.text_selection') ? convert(hexo-config('theme_color.text_selection')) : $strong-cyan
    -$theme-link-color = $themeColorEnable && hexo-config('theme_color.link_color') ? convert(hexo-config('theme_color.link_color')) : $bright-blue
    -$theme-hr-color = $themeColorEnable && hexo-config('theme_color.hr_color') ? convert(hexo-config('theme_color.hr_color')) : $bright-blue
    -$code-foreground = $themeColorEnable && hexo-config('theme_color.code_foreground') ? convert(hexo-config('theme_color.code_foreground')) : $light-red
    -$code-background = $themeColorEnable && hexo-config('theme_color.code_background') ? convert(hexo-config('theme_color.code_background')) : rgba(27, 31, 35, .05)
    -$theme-toc-color = $themeColorEnable && hexo-config('theme_color.toc_color') ? convert(hexo-config('theme_color.toc_color')) : $strong-cyan
    -// font
    -$dafault-font-family = -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Lato, Roboto, 'PingFang SC', 'Microsoft YaHei', sans-serif
    -$dafault-code-font = consolas, Menlo, 'PingFang SC', 'Microsoft YaHei', sans-serif
    -$font-family = hexo-config('font.font-family') ? unquote(hexo-config('font.font-family')) : $dafault-font-family
    -$code-font-family = hexo-config('font.code-font-family') ? unquote(hexo-config('font.code-font-family')) : $dafault-code-font
    -$site-name-font = hexo-config('blog_title_font.font-family') && unquote(hexo-config('blog_title_font.font-family'))
    -// hr
    -$hrEnable = hexo-config('hr_icon') && hexo-config('hr_icon.enable')
    -$hr-icon = $hrEnable && hexo-config('hr_icon.icon') ? hexo-config('hr_icon.icon') : '\f0c4'
    -$hr-icon-top = $hrEnable && hexo-config('hr_icon.icon-top') ? convert(hexo-config('hr_icon.icon-top')) : -10px
    -// page beatutify
    -$beautifyEnable = hexo-config('beautify.enable')
    -$title-prefix-icon = $beautifyEnable && hexo-config('beautify.title-prefix-icon') ? hexo-config('beautify.title-prefix-icon') : '\f0c1'
    -$title-prefix-icon-color = $beautifyEnable && hexo-config('beautify.title-prefix-icon-color') ? convert(hexo-config('beautify.title-prefix-icon-color')) : $light-red
    -// Global Variables
    -$font-size = hexo-config('font.global-font-size') ? convert(hexo-config('font.global-font-size')) : 14px
    -$code-font-size = hexo-config('font.code-font-size') ? convert(hexo-config('font.code-font-size')) : var(--global-font-size)
    -$font-color = #1F2D3D
    -$text-line-height = 2
    -$web-bg = hexo-config('background') && unquote(hexo-config('background'))
    -$index_top_img_height = hexo-config('index_top_img_height') ? convert(hexo-config('index_top_img_height')) : 100vh
    -$index_site_info_top = hexo-config('index_site_info_top') ? convert(hexo-config('index_site_info_top')) : 43%
    -// Global color & SVG
    -$light-blue = $theme-color
    -$dark-black = #000000
    -$light-grey = #EEEEEE
    -$grey = #858585
    -$dark-grey = #cacaca
    -$white = #FFFFFF
    -$whitesmoke = #f5f5f5
    -$font-black = #4C4948
    -$card-bg = $white
    -$text-highlight-color = $font-color
    -$text-hover = $theme-color
    -$text-bg-hover = $theme-color
    -// code
    -$line-height-code-block = 1.6
    -$blockquote-color = #6a737d
    -$blockquote-padding-color = $themeColorEnable && hexo-config('theme_color.blockquote_padding_color') ? convert(hexo-config('theme_color.blockquote_padding_color')) : #49B1F5
    -$blockquote-background-color = $themeColorEnable && hexo-config('theme_color.blockquote_background_color') ? alpha(convert(hexo-config('theme_color.blockquote_background_color')), .1) : alpha($blockquote-padding-color, .1)
    -// page
    -$body-bg = #fff
    -$a-link-color = #99a9bf
    -$sticky-color = $light-orange
    -$theme-meta-color = $themeColorEnable && hexo-config('theme_color.meta_color') ? convert(hexo-config('theme_color.meta_color')) : #858585
    -// sidebar
    -$sidebar-background = #f6f8fa
    -$sidebar-width = 300px
    -// aside
    -$toc-link-color = #666261
    -$toc-mobile-width = calc(100% - 80px)
    -$toc-mobile-maxWidth = 380px
    -$toc-active-color = #fff
    -// Button
    -$button-color = #fff
    -$button-hover-color = $themeColorEnable && hexo-config('theme_color.button_hover') ? convert(hexo-config('theme_color.button_hover')) : $light-orange
    -$button-bg = $theme-color
    -$pseudo-hover = $button-hover-color
    -// scrollbar
    -$scrollbar-color = $themeColorEnable && hexo-config('theme_color.scrollbar_color') ? convert(hexo-config('theme_color.scrollbar_color')) : $theme-color
    -// table
    -$table-thead-bg = #99a9bf
    -// reward
    -$reward-pop-up-bg = #f5f5f5
    -$reward-pop-up-color = #858585
    -// search
    -$search-bg = #f6f8fa
    -$search-input-color = $font-black
    -$search-color = $theme-color
    -$search-keyword-highlight = #F47466
    -$search-a-color = $font-black
    -// comments
    -$comments-switch-first-text = $bright-blue
    -$comments-switch-second-text = $light-orange
    -$comments-switch-round = #fff
    -$comments-switch-bg = #f6f8fa
    -// noticeOutdate
    -$noticeOutdate-bg = #ffe6e6
    -$noticeOutdate-color = #ff6666
    -$noticeOutdate-border = #ff8080
    -// gallery
    -$gallery-color = #fff
    -// tag-hide
    -$tag-hide-bg = $theme-color
    -$tag-hide-toggle-bg = #f0f0f0
    -// preloader
    -$preloader-bg = #37474f
    -$preloader-word-color = #fff
    -// rightside
    -$rightside-bottom = hexo-config('rightside_bottom') ? convert(hexo-config('rightside_bottom')) : 40px
    -// fireworks
    -$fireworks-zIndex = hexo-config('fireworks.zIndex') ? hexo-config('fireworks.zIndex') : 99999
    -// Tag Plugins - Note
    -hexo-config('note.light_bg_offset') is a 'unit' ? ($lbg = unit(hexo-config('note.light_bg_offset'), '%')) : ($lbg = 0)
    -$note-types = 'default' 'primary' 'info' 'success' 'warning' 'danger'
    -// Default
    -$note-default-border = #777
    -$note-default-bg = lighten(spin($note-default-border, 0), 94% + $lbg)
    -$note-default-text = $note-default-border
    -$note-default-icon = '\f0a9'
    -$note-modern-default-border = #e1e1e1
    -$note-modern-default-bg = lighten(spin($note-modern-default-border, 10), 60% + ($lbg * 4))
    -$note-modern-default-text = #666
    -$note-modern-default-hover = darken(spin($note-modern-default-text, -10), 32%)
    -// Primary
    -$note-primary-border = #6f42c1
    -$note-primary-bg = lighten(spin($note-primary-border, 10), 92% + $lbg)
    -$note-primary-text = $note-primary-border
    -$note-primary-icon = '\f055'
    -$note-modern-primary-border = #e1c2ff
    -$note-modern-primary-bg = lighten(spin($note-modern-primary-border, 10), 40% + ($lbg * 4))
    -$note-modern-primary-text = #6f42c1
    -$note-modern-primary-hover = darken(spin($note-modern-primary-text, -10), 22%)
    -// Info
    -$note-info-border = #428bca
    -$note-info-bg = lighten(spin($note-info-border, -10), 91% + $lbg)
    -$note-info-text = $note-info-border
    -$note-info-icon = '\f05a'
    -$note-modern-info-border = #b3e5ef
    -$note-modern-info-bg = lighten(spin($note-modern-info-border, 10), 50% + ($lbg * 4))
    -$note-modern-info-text = #31708f
    -$note-modern-info-hover = darken(spin($note-modern-info-text, -10), 32%)
    -// Success
    -$note-success-border = #5cb85c
    -$note-success-bg = lighten(spin($note-success-border, 10), 90% + $lbg)
    -$note-success-text = $note-success-border
    -$note-success-icon = '\f058'
    -$note-modern-success-border = #d0e6be
    -$note-modern-success-bg = lighten(spin($note-modern-success-border, 10), 40% + ($lbg * 4))
    -$note-modern-success-text = #3c763d
    -$note-modern-success-hover = darken(spin($note-modern-success-text, -10), 27%)
    -// Warning
    -$note-warning-border = #f0ad4e
    -$note-warning-bg = lighten(spin($note-warning-border, 10), 88% + $lbg)
    -$note-warning-text = $note-warning-border
    -$note-warning-icon = '\f06a'
    -$note-modern-warning-border = #fae4cd
    -$note-modern-warning-bg = lighten(spin($note-modern-warning-border, 10), 43% + ($lbg * 4))
    -$note-modern-warning-text = #8a6d3b
    -$note-modern-warning-hover = darken(spin($note-modern-warning-text, -10), 18%)
    -// Danger
    -$note-danger-border = #d9534f
    -$note-danger-bg = lighten(spin($note-danger-border, -10), 92% + $lbg)
    -$note-danger-text = $note-danger-border
    -$note-danger-icon = '\f056'
    -$note-modern-danger-border = #ebcdd2
    -$note-modern-danger-bg = lighten(spin($note-modern-danger-border, 10), 35% + ($lbg * 4))
    -$note-modern-danger-text = #a94442
    -$note-modern-danger-hover = darken(spin($note-modern-danger-text, -10), 22%)
    -// Tag Plugins - Button/note
    -$color-types = 'blue' 'pink' 'red' 'purple' 'orange' 'green'
    -$btn-color = #fff
    -$btn-default-color = #777
    -$tagsP-blue-color = #428bca
    -$tagsP-pink-color = #FF69B4
    -$tagsP-red-color = #FF0000
    -$tagsP-orange-color = #FF8C00
    -$tagsP-purple-color = #6f42c1
    -$tagsP-green-color = #5cb85c
    -// Tag Plugins - Tab
    -$tab-border-color = #f0f0f0
    -$tab-botton-bg = #f0f0f0
    -$tab-botton-color = $font-color
    -$tab-button-hover-bg = darken($tab-border-color, 8)
    -$tab-active-border-color = $theme-color
    -$tab-button-active-bg = $card-bg
    -$tab-to-top-color = #99a9bf
    -$tab-to-top-hover-color = $theme-color
    -// Tag Plugins - timeline
    -$timeline-default-color = $theme-color
    diff --git a/themes/butterfly/source/img/404.jpg b/themes/butterfly/source/img/404.jpg
    deleted file mode 100644
    index 4bab3c3f..00000000
    Binary files a/themes/butterfly/source/img/404.jpg and /dev/null differ
    diff --git a/themes/butterfly/source/img/favicon.png b/themes/butterfly/source/img/favicon.png
    deleted file mode 100644
    index 862ebe85..00000000
    Binary files a/themes/butterfly/source/img/favicon.png and /dev/null differ
    diff --git a/themes/butterfly/source/img/friend_404.gif b/themes/butterfly/source/img/friend_404.gif
    deleted file mode 100644
    index 91dd56a2..00000000
    Binary files a/themes/butterfly/source/img/friend_404.gif and /dev/null differ
    diff --git a/themes/butterfly/source/js/main.js b/themes/butterfly/source/js/main.js
    deleted file mode 100644
    index a22b57f5..00000000
    --- a/themes/butterfly/source/js/main.js
    +++ /dev/null
    @@ -1,879 +0,0 @@
    -document.addEventListener('DOMContentLoaded', function () {
    -  let headerContentWidth, $nav
    -  let mobileSidebarOpen = false
    -
    -  const adjustMenu = init => {
    -    const getAllWidth = ele => {
    -      return Array.from(ele).reduce((width, i) => width + i.offsetWidth, 0)
    -    }
    -
    -    if (init) {
    -      const blogInfoWidth = getAllWidth(document.querySelector('#blog-info > a').children)
    -      const menusWidth = getAllWidth(document.getElementById('menus').children)
    -      headerContentWidth = blogInfoWidth + menusWidth
    -      $nav = document.getElementById('nav')
    -    }
    -
    -    const hideMenuIndex = window.innerWidth <= 768 || headerContentWidth > $nav.offsetWidth - 120
    -    $nav.classList.toggle('hide-menu', hideMenuIndex)
    -  }
    -
    -  // 初始化header
    -  const initAdjust = () => {
    -    adjustMenu(true)
    -    $nav.classList.add('show')
    -  }
    -
    -  // sidebar menus
    -  const sidebarFn = {
    -    open: () => {
    -      btf.sidebarPaddingR()
    -      document.body.style.overflow = 'hidden'
    -      btf.animateIn(document.getElementById('menu-mask'), 'to_show 0.5s')
    -      document.getElementById('sidebar-menus').classList.add('open')
    -      mobileSidebarOpen = true
    -    },
    -    close: () => {
    -      const $body = document.body
    -      $body.style.overflow = ''
    -      $body.style.paddingRight = ''
    -      btf.animateOut(document.getElementById('menu-mask'), 'to_hide 0.5s')
    -      document.getElementById('sidebar-menus').classList.remove('open')
    -      mobileSidebarOpen = false
    -    }
    -  }
    -
    -  /**
    -   * 首頁top_img底下的箭頭
    -   */
    -  const scrollDownInIndex = () => {
    -    const handleScrollToDest = () => {
    -      btf.scrollToDest(document.getElementById('content-inner').offsetTop, 300)
    -    }
    -
    -    const $scrollDownEle = document.getElementById('scroll-down')
    -    $scrollDownEle && btf.addEventListenerPjax($scrollDownEle, 'click', handleScrollToDest)
    -  }
    -
    -  /**
    -   * 代碼
    -   * 只適用於Hexo默認的代碼渲染
    -   */
    -  const addHighlightTool = () => {
    -    const highLight = GLOBAL_CONFIG.highlight
    -    if (!highLight) return
    -
    -    const { highlightCopy, highlightLang, highlightHeightLimit, plugin } = highLight
    -    const isHighlightShrink = GLOBAL_CONFIG_SITE.isHighlightShrink
    -    const isShowTool = highlightCopy || highlightLang || isHighlightShrink !== undefined
    -    const $figureHighlight = plugin === 'highlighjs' ? document.querySelectorAll('figure.highlight') : document.querySelectorAll('pre[class*="language-"]')
    -
    -    if (!((isShowTool || highlightHeightLimit) && $figureHighlight.length)) return
    -
    -    const isPrismjs = plugin === 'prismjs'
    -    const highlightShrinkClass = isHighlightShrink === true ? 'closed' : ''
    -    const highlightShrinkEle = isHighlightShrink !== undefined ? '<i class="fas fa-angle-down expand"></i>' : ''
    -    const highlightCopyEle = highlightCopy ? '<div class="copy-notice"></div><i class="fas fa-paste copy-button"></i>' : ''
    -
    -    const copy = (text, ctx) => {
    -      if (document.queryCommandSupported && document.queryCommandSupported('copy')) {
    -        document.execCommand('copy')
    -        if (GLOBAL_CONFIG.Snackbar !== undefined) {
    -          btf.snackbarShow(GLOBAL_CONFIG.copy.success)
    -        } else {
    -          const prevEle = ctx.previousElementSibling
    -          prevEle.textContent = GLOBAL_CONFIG.copy.success
    -          prevEle.style.opacity = 1
    -          setTimeout(() => { prevEle.style.opacity = 0 }, 700)
    -        }
    -      } else {
    -        if (GLOBAL_CONFIG.Snackbar !== undefined) {
    -          btf.snackbarShow(GLOBAL_CONFIG.copy.noSupport)
    -        } else {
    -          ctx.previousElementSibling.textContent = GLOBAL_CONFIG.copy.noSupport
    -        }
    -      }
    -    }
    -
    -    // click events
    -    const highlightCopyFn = ele => {
    -      const $buttonParent = ele.parentNode
    -      $buttonParent.classList.add('copy-true')
    -      const selection = window.getSelection()
    -      const range = document.createRange()
    -      const preCodeSelector = isPrismjs ? 'pre code' : 'table .code pre'
    -      range.selectNodeContents($buttonParent.querySelectorAll(`${preCodeSelector}`)[0])
    -      selection.removeAllRanges()
    -      selection.addRange(range)
    -      const text = selection.toString()
    -      copy(text, ele.lastChild)
    -      selection.removeAllRanges()
    -      $buttonParent.classList.remove('copy-true')
    -    }
    -
    -    const highlightShrinkFn = ele => {
    -      ele.classList.toggle('closed')
    -    }
    -
    -    const highlightToolsFn = function (e) {
    -      const $target = e.target.classList
    -      if ($target.contains('expand')) highlightShrinkFn(this)
    -      else if ($target.contains('copy-button')) highlightCopyFn(this)
    -    }
    -
    -    const expandCode = function () {
    -      this.classList.toggle('expand-done')
    -    }
    -
    -    const createEle = (lang, item, service) => {
    -      const fragment = document.createDocumentFragment()
    -
    -      if (isShowTool) {
    -        const hlTools = document.createElement('div')
    -        hlTools.className = `highlight-tools ${highlightShrinkClass}`
    -        hlTools.innerHTML = highlightShrinkEle + lang + highlightCopyEle
    -        btf.addEventListenerPjax(hlTools, 'click', highlightToolsFn)
    -        fragment.appendChild(hlTools)
    -      }
    -
    -      if (highlightHeightLimit && item.offsetHeight > highlightHeightLimit + 30) {
    -        const ele = document.createElement('div')
    -        ele.className = 'code-expand-btn'
    -        ele.innerHTML = '<i class="fas fa-angle-double-down"></i>'
    -        btf.addEventListenerPjax(ele, 'click', expandCode)
    -        fragment.appendChild(ele)
    -      }
    -
    -      if (service === 'hl') {
    -        item.insertBefore(fragment, item.firstChild)
    -      } else {
    -        item.parentNode.insertBefore(fragment, item)
    -      }
    -    }
    -
    -    if (isPrismjs) {
    -      $figureHighlight.forEach(item => {
    -        if (highlightLang) {
    -          const langName = item.getAttribute('data-language') || 'Code'
    -          const highlightLangEle = `<div class="code-lang">${langName}</div>`
    -          btf.wrap(item, 'figure', { class: 'highlight' })
    -          createEle(highlightLangEle, item)
    -        } else {
    -          btf.wrap(item, 'figure', { class: 'highlight' })
    -          createEle('', item)
    -        }
    -      })
    -    } else {
    -      $figureHighlight.forEach(item => {
    -        if (highlightLang) {
    -          let langName = item.getAttribute('class').split(' ')[1]
    -          if (langName === 'plain' || langName === undefined) langName = 'Code'
    -          const highlightLangEle = `<div class="code-lang">${langName}</div>`
    -          createEle(highlightLangEle, item, 'hl')
    -        } else {
    -          createEle('', item, 'hl')
    -        }
    -      })
    -    }
    -  }
    -
    -  /**
    -   * PhotoFigcaption
    -   */
    -  const addPhotoFigcaption = () => {
    -    document.querySelectorAll('#article-container img').forEach(item => {
    -      const altValue = item.title || item.alt
    -      if (!altValue) return
    -      const ele = document.createElement('div')
    -      ele.className = 'img-alt is-center'
    -      ele.textContent = altValue
    -      item.insertAdjacentElement('afterend', ele)
    -    })
    -  }
    -
    -  /**
    -   * Lightbox
    -   */
    -  const runLightbox = () => {
    -    btf.loadLightbox(document.querySelectorAll('#article-container img:not(.no-lightbox)'))
    -  }
    -
    -  /**
    -   * justified-gallery 圖庫排版
    -   */
    -
    -  const fetchUrl = async (url) => {
    -    const response = await fetch(url)
    -    return await response.json()
    -  }
    -
    -  const runJustifiedGallery = (item, data, isButton = false, tabs) => {
    -    const dataLength = data.length
    -
    -    const ig = new InfiniteGrid.JustifiedInfiniteGrid(item, {
    -      gap: 5,
    -      isConstantSize: true,
    -      sizeRange: [150, 600],
    -      useResizeObserver: true,
    -      observeChildren: true,
    -      useTransform: true
    -      // useRecycle: false
    -    })
    -
    -    if (tabs) {
    -      btf.addGlobalFn('igOfTabs', () => { ig.destroy() }, false, tabs)
    -    }
    -
    -    const replaceDq = str => str.replace(/"/g, '&quot;') // replace double quotes to &quot;
    -
    -    const getItems = (nextGroupKey, count) => {
    -      const nextItems = []
    -      const startCount = (nextGroupKey - 1) * count
    -
    -      for (let i = 0; i < count; ++i) {
    -        const num = startCount + i
    -        if (num >= dataLength) {
    -          break
    -        }
    -
    -        const item = data[num]
    -        const alt = item.alt ? `alt="${replaceDq(item.alt)}"` : ''
    -        const title = item.title ? `title="${replaceDq(item.title)}"` : ''
    -
    -        nextItems.push(`<div class="item ">
    -            <img src="${item.url}" data-grid-maintained-target="true" ${alt + title} />
    -          </div>`)
    -      }
    -      return nextItems
    -    }
    -
    -    const buttonText = GLOBAL_CONFIG.infinitegrid.buttonText
    -    const addButton = item => {
    -      const button = document.createElement('button')
    -      button.textContent = buttonText
    -
    -      const buttonFn = e => {
    -        e.target.removeEventListener('click', buttonFn)
    -        e.target.remove()
    -        btf.setLoading.add(item)
    -        appendItem(ig.getGroups().length + 1, 10)
    -      }
    -
    -      button.addEventListener('click', buttonFn)
    -      item.insertAdjacentElement('afterend', button)
    -    }
    -
    -    const appendItem = (nextGroupKey, count) => {
    -      ig.append(getItems(nextGroupKey, count), nextGroupKey)
    -    }
    -
    -    const maxGroupKey = Math.ceil(dataLength / 10)
    -
    -    const completeFn = e => {
    -      const { updated, isResize, mounted } = e
    -      if (!updated.length || !mounted.length || isResize) {
    -        return
    -      }
    -
    -      btf.loadLightbox(item.querySelectorAll('img:not(.medium-zoom-image)'))
    -
    -      if (ig.getGroups().length === maxGroupKey) {
    -        btf.setLoading.remove(item)
    -        ig.off('renderComplete', completeFn)
    -        return
    -      }
    -
    -      if (isButton) {
    -        btf.setLoading.remove(item)
    -        addButton(item)
    -      }
    -    }
    -
    -    const requestAppendFn = btf.debounce(e => {
    -      const nextGroupKey = (+e.groupKey || 0) + 1
    -      appendItem(nextGroupKey, 10)
    -
    -      if (nextGroupKey === maxGroupKey) {
    -        ig.off('requestAppend', requestAppendFn)
    -      }
    -    }, 300)
    -
    -    btf.setLoading.add(item)
    -    ig.on('renderComplete', completeFn)
    -
    -    if (isButton) {
    -      appendItem(1, 10)
    -    } else {
    -      ig.on('requestAppend', requestAppendFn)
    -      ig.renderItems()
    -    }
    -
    -    btf.addGlobalFn('justifiedGallery', () => { ig.destroy() })
    -  }
    -
    -  const addJustifiedGallery = async (ele, tabs = false) => {
    -    const init = async () => {
    -      for (const item of ele) {
    -        if (btf.isHidden(item)) continue
    -        if (tabs && item.classList.contains('loaded')) {
    -          item.querySelector('.gallery-items').innerHTML = ''
    -          const button = item.querySelector(':scope > button')
    -          const loadingContainer = item.querySelector(':scope > .loading-container')
    -          button && button.remove()
    -          loadingContainer && loadingContainer.remove()
    -        }
    -
    -        const isButton = item.getAttribute('data-button') === 'true'
    -        const text = item.firstElementChild.textContent
    -        item.classList.add('loaded')
    -        const content = item.getAttribute('data-type') === 'url' ? await fetchUrl(text) : JSON.parse(text)
    -        runJustifiedGallery(item.lastElementChild, content, isButton, tabs)
    -      }
    -    }
    -
    -    if (typeof InfiniteGrid === 'function') {
    -      init()
    -    } else {
    -      await getScript(`${GLOBAL_CONFIG.infinitegrid.js}`)
    -      init()
    -    }
    -  }
    -
    -  /**
    -   * rightside scroll percent
    -   */
    -  const rightsideScrollPercent = currentTop => {
    -    const scrollPercent = btf.getScrollPercent(currentTop, document.body)
    -    const goUpElement = document.getElementById('go-up')
    -
    -    if (scrollPercent < 95) {
    -      goUpElement.classList.add('show-percent')
    -      goUpElement.querySelector('.scroll-percent').textContent = scrollPercent
    -    } else {
    -      goUpElement.classList.remove('show-percent')
    -    }
    -  }
    -
    -  /**
    -   * 滾動處理
    -   */
    -  const scrollFn = () => {
    -    const $rightside = document.getElementById('rightside')
    -    const innerHeight = window.innerHeight + 56
    -    let initTop = 0
    -    const $header = document.getElementById('page-header')
    -    const isChatBtn = typeof chatBtn !== 'undefined'
    -    const isShowPercent = GLOBAL_CONFIG.percent.rightside
    -
    -    // 當滾動條小于 56 的時候
    -    if (document.body.scrollHeight <= innerHeight) {
    -      $rightside.classList.add('rightside-show')
    -      return
    -    }
    -
    -    // find the scroll direction
    -    const scrollDirection = currentTop => {
    -      const result = currentTop > initTop // true is down & false is up
    -      initTop = currentTop
    -      return result
    -    }
    -
    -    let flag = ''
    -    const scrollTask = btf.throttle(() => {
    -      const currentTop = window.scrollY || document.documentElement.scrollTop
    -      const isDown = scrollDirection(currentTop)
    -      if (currentTop > 56) {
    -        if (flag === '') {
    -          $header.classList.add('nav-fixed')
    -          $rightside.classList.add('rightside-show')
    -        }
    -
    -        if (isDown) {
    -          if (flag !== 'down') {
    -            $header.classList.remove('nav-visible')
    -            isChatBtn && window.chatBtn.hide()
    -            flag = 'down'
    -          }
    -        } else {
    -          if (flag !== 'up') {
    -            $header.classList.add('nav-visible')
    -            isChatBtn && window.chatBtn.show()
    -            flag = 'up'
    -          }
    -        }
    -      } else {
    -        flag = ''
    -        if (currentTop === 0) {
    -          $header.classList.remove('nav-fixed', 'nav-visible')
    -        }
    -        $rightside.classList.remove('rightside-show')
    -      }
    -
    -      isShowPercent && rightsideScrollPercent(currentTop)
    -
    -      if (document.body.scrollHeight <= innerHeight) {
    -        $rightside.classList.add('rightside-show')
    -      }
    -    }, 300)
    -
    -    btf.addEventListenerPjax(window, 'scroll', scrollTask, { passive: true })
    -  }
    -
    -  /**
    -  * toc,anchor
    -  */
    -  const scrollFnToDo = () => {
    -    const isToc = GLOBAL_CONFIG_SITE.isToc
    -    const isAnchor = GLOBAL_CONFIG.isAnchor
    -    const $article = document.getElementById('article-container')
    -
    -    if (!($article && (isToc || isAnchor))) return
    -
    -    let $tocLink, $cardToc, autoScrollToc, $tocPercentage, isExpand
    -
    -    if (isToc) {
    -      const $cardTocLayout = document.getElementById('card-toc')
    -      $cardToc = $cardTocLayout.querySelector('.toc-content')
    -      $tocLink = $cardToc.querySelectorAll('.toc-link')
    -      $tocPercentage = $cardTocLayout.querySelector('.toc-percentage')
    -      isExpand = $cardToc.classList.contains('is-expand')
    -
    -      // toc元素點擊
    -      const tocItemClickFn = e => {
    -        const target = e.target.closest('.toc-link')
    -        if (!target) return
    -
    -        e.preventDefault()
    -        btf.scrollToDest(btf.getEleTop(document.getElementById(decodeURI(target.getAttribute('href')).replace('#', ''))), 300)
    -        if (window.innerWidth < 900) {
    -          $cardTocLayout.classList.remove('open')
    -        }
    -      }
    -
    -      btf.addEventListenerPjax($cardToc, 'click', tocItemClickFn)
    -
    -      autoScrollToc = item => {
    -        const activePosition = item.getBoundingClientRect().top
    -        const sidebarScrollTop = $cardToc.scrollTop
    -        if (activePosition > (document.documentElement.clientHeight - 100)) {
    -          $cardToc.scrollTop = sidebarScrollTop + 150
    -        }
    -        if (activePosition < 100) {
    -          $cardToc.scrollTop = sidebarScrollTop - 150
    -        }
    -      }
    -    }
    -
    -    // find head position & add active class
    -    const $articleList = $article.querySelectorAll('h1,h2,h3,h4,h5,h6')
    -    let detectItem = ''
    -    const findHeadPosition = top => {
    -      if (top === 0) {
    -        return false
    -      }
    -
    -      let currentId = ''
    -      let currentIndex = ''
    -
    -      $articleList.forEach((ele, index) => {
    -        if (top > btf.getEleTop(ele) - 80) {
    -          const id = ele.id
    -          currentId = id ? '#' + encodeURI(id) : ''
    -          currentIndex = index
    -        }
    -      })
    -
    -      if (detectItem === currentIndex) return
    -
    -      if (isAnchor) btf.updateAnchor(currentId)
    -
    -      detectItem = currentIndex
    -
    -      if (isToc) {
    -        $cardToc.querySelectorAll('.active').forEach(i => { i.classList.remove('active') })
    -
    -        if (currentId === '') {
    -          return
    -        }
    -
    -        const currentActive = $tocLink[currentIndex]
    -        currentActive.classList.add('active')
    -
    -        setTimeout(() => {
    -          autoScrollToc(currentActive)
    -        }, 0)
    -
    -        if (isExpand) return
    -        let parent = currentActive.parentNode
    -
    -        for (; !parent.matches('.toc'); parent = parent.parentNode) {
    -          if (parent.matches('li')) parent.classList.add('active')
    -        }
    -      }
    -    }
    -
    -    // main of scroll
    -    const tocScrollFn = btf.throttle(() => {
    -      const currentTop = window.scrollY || document.documentElement.scrollTop
    -      if (isToc && GLOBAL_CONFIG.percent.toc) {
    -        $tocPercentage.textContent = btf.getScrollPercent(currentTop, $article)
    -      }
    -      findHeadPosition(currentTop)
    -    }, 100)
    -
    -    btf.addEventListenerPjax(window, 'scroll', tocScrollFn, { passive: true })
    -  }
    -
    -  const handleThemeChange = mode => {
    -    const globalFn = window.globalFn || {}
    -    const themeChange = globalFn.themeChange || {}
    -    if (!themeChange) {
    -      return
    -    }
    -
    -    Object.keys(themeChange).forEach(key => {
    -      const themeChangeFn = themeChange[key]
    -      if (['disqus', 'disqusjs'].includes(key)) {
    -        setTimeout(() => themeChangeFn(mode), 300)
    -      } else {
    -        themeChangeFn(mode)
    -      }
    -    })
    -  }
    -
    -  /**
    -   * Rightside
    -   */
    -  const rightSideFn = {
    -    readmode: () => { // read mode
    -      const $body = document.body
    -      $body.classList.add('read-mode')
    -      const newEle = document.createElement('button')
    -      newEle.type = 'button'
    -      newEle.className = 'fas fa-sign-out-alt exit-readmode'
    -      $body.appendChild(newEle)
    -
    -      const clickFn = () => {
    -        $body.classList.remove('read-mode')
    -        newEle.remove()
    -        newEle.removeEventListener('click', clickFn)
    -      }
    -
    -      newEle.addEventListener('click', clickFn)
    -    },
    -    darkmode: () => { // switch between light and dark mode
    -      const willChangeMode = document.documentElement.getAttribute('data-theme') === 'dark' ? 'light' : 'dark'
    -      if (willChangeMode === 'dark') {
    -        activateDarkMode()
    -        GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.day_to_night)
    -      } else {
    -        activateLightMode()
    -        GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.night_to_day)
    -      }
    -      saveToLocal.set('theme', willChangeMode, 2)
    -      handleThemeChange(willChangeMode)
    -    },
    -    'rightside-config': item => { // Show or hide rightside-hide-btn
    -      const hideLayout = item.firstElementChild
    -      if (hideLayout.classList.contains('show')) {
    -        hideLayout.classList.add('status')
    -        setTimeout(() => {
    -          hideLayout.classList.remove('status')
    -        }, 300)
    -      }
    -
    -      hideLayout.classList.toggle('show')
    -    },
    -    'go-up': () => { // Back to top
    -      btf.scrollToDest(0, 500)
    -    },
    -    'hide-aside-btn': () => { // Hide aside
    -      const $htmlDom = document.documentElement.classList
    -      const saveStatus = $htmlDom.contains('hide-aside') ? 'show' : 'hide'
    -      saveToLocal.set('aside-status', saveStatus, 2)
    -      $htmlDom.toggle('hide-aside')
    -    },
    -    'mobile-toc-button': item => { // Show mobile toc
    -      const tocEle = document.getElementById('card-toc')
    -      tocEle.style.transition = 'transform 0.3s ease-in-out'
    -      tocEle.classList.toggle('open')
    -      tocEle.addEventListener('transitionend', () => {
    -        tocEle.style.transition = ''
    -      }, { once: true })
    -    },
    -    'chat-btn': () => { // Show chat
    -      window.chatBtnFn()
    -    },
    -    translateLink: () => { // switch between traditional and simplified chinese
    -      window.translateFn.translatePage()
    -    }
    -  }
    -
    -  document.getElementById('rightside').addEventListener('click', function (e) {
    -    const $target = e.target.closest('[id]')
    -    if ($target && rightSideFn[$target.id]) {
    -      rightSideFn[$target.id](this)
    -    }
    -  })
    -
    -  /**
    -   * menu
    -   * 側邊欄sub-menu 展開/收縮
    -   */
    -  const clickFnOfSubMenu = () => {
    -    const handleClickOfSubMenu = e => {
    -      const target = e.target.closest('.site-page.group')
    -      if (!target) return
    -      target.classList.toggle('hide')
    -    }
    -
    -    document.querySelector('#sidebar-menus .menus_items').addEventListener('click', handleClickOfSubMenu)
    -  }
    -
    -  /**
    -   * 手机端目录点击
    -   */
    -  const openMobileMenu = () => {
    -    const handleClick = () => { sidebarFn.open() }
    -    btf.addEventListenerPjax(document.getElementById('toggle-menu'), 'click', handleClick)
    -  }
    -
    -  /**
    - * 複製時加上版權信息
    - */
    -  const addCopyright = () => {
    -    const { limitCount, languages } = GLOBAL_CONFIG.copyright
    -
    -    const handleCopy = (e) => {
    -      e.preventDefault()
    -      const copyFont = window.getSelection(0).toString()
    -      let textFont = copyFont
    -      if (copyFont.length > limitCount) {
    -        textFont = `${copyFont}\n\n\n${languages.author}\n${languages.link}${window.location.href}\n${languages.source}\n${languages.info}`
    -      }
    -      if (e.clipboardData) {
    -        return e.clipboardData.setData('text', textFont)
    -      } else {
    -        return window.clipboardData.setData('text', textFont)
    -      }
    -    }
    -
    -    document.body.addEventListener('copy', handleCopy)
    -  }
    -
    -  /**
    -   * 網頁運行時間
    -   */
    -  const addRuntime = () => {
    -    const $runtimeCount = document.getElementById('runtimeshow')
    -    if ($runtimeCount) {
    -      const publishDate = $runtimeCount.getAttribute('data-publishDate')
    -      $runtimeCount.textContent = `${btf.diffDate(publishDate)} ${GLOBAL_CONFIG.runtime}`
    -    }
    -  }
    -
    -  /**
    -   * 最後一次更新時間
    -   */
    -  const addLastPushDate = () => {
    -    const $lastPushDateItem = document.getElementById('last-push-date')
    -    if ($lastPushDateItem) {
    -      const lastPushDate = $lastPushDateItem.getAttribute('data-lastPushDate')
    -      $lastPushDateItem.textContent = btf.diffDate(lastPushDate, true)
    -    }
    -  }
    -
    -  /**
    -   * table overflow
    -   */
    -  const addTableWrap = () => {
    -    const $table = document.querySelectorAll('#article-container table')
    -    if (!$table.length) return
    -
    -    $table.forEach(item => {
    -      if (!item.closest('.highlight')) {
    -        btf.wrap(item, 'div', { class: 'table-wrap' })
    -      }
    -    })
    -  }
    -
    -  /**
    -   * tag-hide
    -   */
    -  const clickFnOfTagHide = () => {
    -    const hideButtons = document.querySelectorAll('#article-container .hide-button')
    -    if (!hideButtons.length) return
    -    const handleClick = function (e) {
    -      const $this = this
    -      $this.classList.add('open')
    -      const $fjGallery = $this.nextElementSibling.querySelectorAll('.gallery-container')
    -      $fjGallery.length && addJustifiedGallery($fjGallery)
    -    }
    -
    -    hideButtons.forEach(item => {
    -      item.addEventListener('click', handleClick, { once: true })
    -    })
    -  }
    -
    -  const tabsFn = () => {
    -    const navTabsElement = document.querySelectorAll('#article-container .tabs')
    -    if (!navTabsElement.length) return
    -
    -    const removeAndAddActiveClass = (elements, detect) => {
    -      Array.from(elements).forEach(element => {
    -        element.classList.remove('active')
    -        if (element === detect || element.id === detect) {
    -          element.classList.add('active')
    -        }
    -      })
    -    }
    -
    -    const addTabNavEventListener = (item, isJustifiedGallery) => {
    -      const navClickHandler = function (e) {
    -        const target = e.target.closest('button')
    -        if (target.classList.contains('active')) return
    -        removeAndAddActiveClass(this.children, target)
    -        this.classList.remove('no-default')
    -        const tabId = target.getAttribute('data-href')
    -        const tabContent = this.nextElementSibling
    -        removeAndAddActiveClass(tabContent.children, tabId)
    -        if (isJustifiedGallery) {
    -          btf.removeGlobalFnEvent('igOfTabs', this)
    -          const justifiedGalleryItems = tabContent.querySelectorAll(`:scope > #${tabId} .gallery-container`)
    -          justifiedGalleryItems.length && addJustifiedGallery(justifiedGalleryItems, this)
    -        }
    -      }
    -      btf.addEventListenerPjax(item.firstElementChild, 'click', navClickHandler)
    -    }
    -
    -    const addTabToTopEventListener = item => {
    -      const btnClickHandler = (e) => {
    -        const target = e.target.closest('button')
    -        if (!target) return
    -        btf.scrollToDest(btf.getEleTop(item), 300)
    -      }
    -      btf.addEventListenerPjax(item.lastElementChild, 'click', btnClickHandler)
    -    }
    -
    -    navTabsElement.forEach(item => {
    -      const isJustifiedGallery = !!item.querySelectorAll('.gallery-container')
    -      addTabNavEventListener(item, isJustifiedGallery)
    -      addTabToTopEventListener(item)
    -    })
    -  }
    -
    -  const toggleCardCategory = () => {
    -    const cardCategory = document.querySelector('#aside-cat-list.expandBtn')
    -    if (!cardCategory) return
    -
    -    const handleToggleBtn = (e) => {
    -      const target = e.target
    -      if (target.nodeName === 'I') {
    -        e.preventDefault()
    -        target.parentNode.classList.toggle('expand')
    -      }
    -    }
    -    btf.addEventListenerPjax(cardCategory, 'click', handleToggleBtn, true)
    -  }
    -
    -  const switchComments = () => {
    -    const switchBtn = document.getElementById('switch-btn')
    -    if (!switchBtn) return
    -    let switchDone = false
    -    const commentContainer = document.getElementById('post-comment')
    -    const handleSwitchBtn = () => {
    -      commentContainer.classList.toggle('move')
    -      if (!switchDone) {
    -        switchDone = true
    -        loadOtherComment()
    -      }
    -    }
    -    btf.addEventListenerPjax(switchBtn, 'click', handleSwitchBtn)
    -  }
    -
    -  const addPostOutdateNotice = () => {
    -    const { limitDay, messagePrev, messageNext, position } = GLOBAL_CONFIG.noticeOutdate
    -    const diffDay = btf.diffDate(GLOBAL_CONFIG_SITE.postUpdate)
    -    if (diffDay >= limitDay) {
    -      const ele = document.createElement('div')
    -      ele.className = 'post-outdate-notice'
    -      ele.textContent = `${messagePrev} ${diffDay} ${messageNext}`
    -      const $targetEle = document.getElementById('article-container')
    -      if (position === 'top') {
    -        $targetEle.insertBefore(ele, $targetEle.firstChild)
    -      } else {
    -        $targetEle.appendChild(ele)
    -      }
    -    }
    -  }
    -
    -  const lazyloadImg = () => {
    -    window.lazyLoadInstance = new LazyLoad({
    -      elements_selector: 'img',
    -      threshold: 0,
    -      data_src: 'lazy-src'
    -    })
    -  }
    -
    -  const relativeDate = function (selector) {
    -    selector.forEach(item => {
    -      const timeVal = item.getAttribute('datetime')
    -      item.textContent = btf.diffDate(timeVal, true)
    -      item.style.display = 'inline'
    -    })
    -  }
    -
    -  const unRefreshFn = function () {
    -    window.addEventListener('resize', () => {
    -      adjustMenu(false)
    -      mobileSidebarOpen && btf.isHidden(document.getElementById('toggle-menu')) && sidebarFn.close()
    -    })
    -
    -    document.getElementById('menu-mask').addEventListener('click', e => { sidebarFn.close() })
    -
    -    clickFnOfSubMenu()
    -    GLOBAL_CONFIG.islazyload && lazyloadImg()
    -    GLOBAL_CONFIG.copyright !== undefined && addCopyright()
    -
    -    if (GLOBAL_CONFIG.autoDarkmode) {
    -      window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
    -        if (saveToLocal.get('theme') !== undefined) return
    -        e.matches ? handleThemeChange('dark') : handleThemeChange('light')
    -      })
    -    }
    -  }
    -
    -  window.refreshFn = function () {
    -    initAdjust()
    -
    -    if (GLOBAL_CONFIG_SITE.isPost) {
    -      GLOBAL_CONFIG.noticeOutdate !== undefined && addPostOutdateNotice()
    -      GLOBAL_CONFIG.relativeDate.post && relativeDate(document.querySelectorAll('#post-meta time'))
    -    } else {
    -      GLOBAL_CONFIG.relativeDate.homepage && relativeDate(document.querySelectorAll('#recent-posts time'))
    -      GLOBAL_CONFIG.runtime && addRuntime()
    -      addLastPushDate()
    -      toggleCardCategory()
    -    }
    -
    -    scrollFnToDo()
    -    GLOBAL_CONFIG_SITE.isHome && scrollDownInIndex()
    -    addHighlightTool()
    -    GLOBAL_CONFIG.isPhotoFigcaption && addPhotoFigcaption()
    -    scrollFn()
    -
    -    btf.removeGlobalFnEvent('justifiedGallery')
    -    const galleryContainer = document.querySelectorAll('#article-container .gallery-container')
    -    galleryContainer.length && addJustifiedGallery(galleryContainer)
    -
    -    runLightbox()
    -    addTableWrap()
    -    clickFnOfTagHide()
    -    tabsFn()
    -    switchComments()
    -    openMobileMenu()
    -  }
    -
    -  refreshFn()
    -  unRefreshFn()
    -})
    diff --git a/themes/butterfly/source/js/search/algolia.js b/themes/butterfly/source/js/search/algolia.js
    deleted file mode 100644
    index 9ce7b0ef..00000000
    --- a/themes/butterfly/source/js/search/algolia.js
    +++ /dev/null
    @@ -1,177 +0,0 @@
    -window.addEventListener('load', () => {
    -  const $searchMask = document.getElementById('search-mask')
    -  const $searchDialog = document.querySelector('#algolia-search .search-dialog')
    -
    -  const openSearch = () => {
    -    const bodyStyle = document.body.style
    -    bodyStyle.width = '100%'
    -    bodyStyle.overflow = 'hidden'
    -    btf.animateIn($searchMask, 'to_show 0.5s')
    -    btf.animateIn($searchDialog, 'titleScale 0.5s')
    -    setTimeout(() => { document.querySelector('#algolia-search .ais-SearchBox-input').focus() }, 100)
    -
    -    // shortcut: ESC
    -    document.addEventListener('keydown', function f (event) {
    -      if (event.code === 'Escape') {
    -        closeSearch()
    -        document.removeEventListener('keydown', f)
    -      }
    -    })
    -
    -    fixSafariHeight()
    -    window.addEventListener('resize', fixSafariHeight)
    -  }
    -
    -  const closeSearch = () => {
    -    const bodyStyle = document.body.style
    -    bodyStyle.width = ''
    -    bodyStyle.overflow = ''
    -    btf.animateOut($searchDialog, 'search_close .5s')
    -    btf.animateOut($searchMask, 'to_hide 0.5s')
    -    window.removeEventListener('resize', fixSafariHeight)
    -  }
    -
    -  // fix safari
    -  const fixSafariHeight = () => {
    -    if (window.innerWidth < 768) {
    -      $searchDialog.style.setProperty('--search-height', window.innerHeight + 'px')
    -    }
    -  }
    -
    -  const searchClickFn = () => {
    -    btf.addEventListenerPjax(document.querySelector('#search-button > .search'), 'click', openSearch)
    -  }
    -
    -  const searchFnOnce = () => {
    -    $searchMask.addEventListener('click', closeSearch)
    -    document.querySelector('#algolia-search .search-close-button').addEventListener('click', closeSearch)
    -  }
    -
    -  const cutContent = content => {
    -    if (content === '') return ''
    -
    -    const firstOccur = content.indexOf('<mark>')
    -
    -    let start = firstOccur - 30
    -    let end = firstOccur + 120
    -    let pre = ''
    -    let post = ''
    -
    -    if (start <= 0) {
    -      start = 0
    -      end = 140
    -    } else {
    -      pre = '...'
    -    }
    -
    -    if (end > content.length) {
    -      end = content.length
    -    } else {
    -      post = '...'
    -    }
    -
    -    const matchContent = pre + content.substring(start, end) + post
    -    return matchContent
    -  }
    -
    -  const algolia = GLOBAL_CONFIG.algolia
    -  const isAlgoliaValid = algolia.appId && algolia.apiKey && algolia.indexName
    -  if (!isAlgoliaValid) {
    -    return console.error('Algolia setting is invalid!')
    -  }
    -
    -  const search = instantsearch({
    -    indexName: algolia.indexName,
    -    /* global algoliasearch */
    -    searchClient: algoliasearch(algolia.appId, algolia.apiKey),
    -    searchFunction (helper) {
    -      helper.state.query && helper.search()
    -    }
    -  })
    -
    -  const configure = instantsearch.widgets.configure({
    -    hitsPerPage: 5
    -  })
    -
    -  const searchBox = instantsearch.widgets.searchBox({
    -    container: '#algolia-search-input',
    -    showReset: false,
    -    showSubmit: false,
    -    placeholder: GLOBAL_CONFIG.algolia.languages.input_placeholder,
    -    showLoadingIndicator: true
    -  })
    -
    -  const hits = instantsearch.widgets.hits({
    -    container: '#algolia-hits',
    -    templates: {
    -      item (data) {
    -        const link = data.permalink ? data.permalink : (GLOBAL_CONFIG.root + data.path)
    -        const result = data._highlightResult
    -        const content = result.contentStripTruncate
    -          ? cutContent(result.contentStripTruncate.value)
    -          : result.contentStrip
    -            ? cutContent(result.contentStrip.value)
    -            : result.content
    -              ? cutContent(result.content.value)
    -              : ''
    -        return `
    -          <a href="${link}" class="algolia-hit-item-link">
    -          <span class="algolia-hits-item-title">${result.title.value || 'no-title'}</span>
    -          <p class="algolia-hit-item-content">${content}</p>
    -          </a>`
    -      },
    -      empty: function (data) {
    -        return (
    -          '<div id="algolia-hits-empty">' +
    -          GLOBAL_CONFIG.algolia.languages.hits_empty.replace(/\$\{query}/, data.query) +
    -          '</div>'
    -        )
    -      }
    -    }
    -  })
    -
    -  const stats = instantsearch.widgets.stats({
    -    container: '#algolia-info > .algolia-stats',
    -    templates: {
    -      text: function (data) {
    -        const stats = GLOBAL_CONFIG.algolia.languages.hits_stats
    -          .replace(/\$\{hits}/, data.nbHits)
    -          .replace(/\$\{time}/, data.processingTimeMS)
    -        return (
    -          `<hr>${stats}`
    -        )
    -      }
    -    }
    -  })
    -
    -  const powerBy = instantsearch.widgets.poweredBy({
    -    container: '#algolia-info > .algolia-poweredBy'
    -  })
    -
    -  const pagination = instantsearch.widgets.pagination({
    -    container: '#algolia-pagination',
    -    totalPages: 5,
    -    templates: {
    -      first: '<i class="fas fa-angle-double-left"></i>',
    -      last: '<i class="fas fa-angle-double-right"></i>',
    -      previous: '<i class="fas fa-angle-left"></i>',
    -      next: '<i class="fas fa-angle-right"></i>'
    -    }
    -  })
    -
    -  search.addWidgets([configure, searchBox, hits, stats, powerBy, pagination]) // add the widgets to the instantsearch instance
    -
    -  search.start()
    -
    -  searchClickFn()
    -  searchFnOnce()
    -
    -  window.addEventListener('pjax:complete', () => {
    -    !btf.isHidden($searchMask) && closeSearch()
    -    searchClickFn()
    -  })
    -
    -  window.pjax && search.on('render', () => {
    -    window.pjax.refresh(document.getElementById('algolia-hits'))
    -  })
    -})
    diff --git a/themes/butterfly/source/js/search/local-search.js b/themes/butterfly/source/js/search/local-search.js
    deleted file mode 100644
    index 0eecff6b..00000000
    --- a/themes/butterfly/source/js/search/local-search.js
    +++ /dev/null
    @@ -1,364 +0,0 @@
    -/**
    - * Refer to hexo-generator-searchdb
    - * https://github.com/next-theme/hexo-generator-searchdb/blob/main/dist/search.js
    - * Modified by hexo-theme-butterfly
    - */
    -
    -class LocalSearch {
    -  constructor ({
    -    path = '',
    -    unescape = false,
    -    top_n_per_article = 1
    -  }) {
    -    this.path = path
    -    this.unescape = unescape
    -    this.top_n_per_article = top_n_per_article
    -    this.isfetched = false
    -    this.datas = null
    -  }
    -
    -  getIndexByWord (words, text, caseSensitive = false) {
    -    const index = []
    -    const included = new Set()
    -
    -    if (!caseSensitive) {
    -      text = text.toLowerCase()
    -    }
    -    words.forEach(word => {
    -      if (this.unescape) {
    -        const div = document.createElement('div')
    -        div.innerText = word
    -        word = div.innerHTML
    -      }
    -      const wordLen = word.length
    -      if (wordLen === 0) return
    -      let startPosition = 0
    -      let position = -1
    -      if (!caseSensitive) {
    -        word = word.toLowerCase()
    -      }
    -      while ((position = text.indexOf(word, startPosition)) > -1) {
    -        index.push({ position, word })
    -        included.add(word)
    -        startPosition = position + wordLen
    -      }
    -    })
    -    // Sort index by position of keyword
    -    index.sort((left, right) => {
    -      if (left.position !== right.position) {
    -        return left.position - right.position
    -      }
    -      return right.word.length - left.word.length
    -    })
    -    return [index, included]
    -  }
    -
    -  // Merge hits into slices
    -  mergeIntoSlice (start, end, index) {
    -    let item = index[0]
    -    let { position, word } = item
    -    const hits = []
    -    const count = new Set()
    -    while (position + word.length <= end && index.length !== 0) {
    -      count.add(word)
    -      hits.push({
    -        position,
    -        length: word.length
    -      })
    -      const wordEnd = position + word.length
    -
    -      // Move to next position of hit
    -      index.shift()
    -      while (index.length !== 0) {
    -        item = index[0]
    -        position = item.position
    -        word = item.word
    -        if (wordEnd > position) {
    -          index.shift()
    -        } else {
    -          break
    -        }
    -      }
    -    }
    -    return {
    -      hits,
    -      start,
    -      end,
    -      count: count.size
    -    }
    -  }
    -
    -  // Highlight title and content
    -  highlightKeyword (val, slice) {
    -    let result = ''
    -    let index = slice.start
    -    for (const { position, length } of slice.hits) {
    -      result += val.substring(index, position)
    -      index = position + length
    -      result += `<mark class="search-keyword">${val.substr(position, length)}</mark>`
    -    }
    -    result += val.substring(index, slice.end)
    -    return result
    -  }
    -
    -  getResultItems (keywords) {
    -    const resultItems = []
    -    this.datas.forEach(({ title, content, url }) => {
    -      // The number of different keywords included in the article.
    -      const [indexOfTitle, keysOfTitle] = this.getIndexByWord(keywords, title)
    -      const [indexOfContent, keysOfContent] = this.getIndexByWord(keywords, content)
    -      const includedCount = new Set([...keysOfTitle, ...keysOfContent]).size
    -
    -      // Show search results
    -      const hitCount = indexOfTitle.length + indexOfContent.length
    -      if (hitCount === 0) return
    -
    -      const slicesOfTitle = []
    -      if (indexOfTitle.length !== 0) {
    -        slicesOfTitle.push(this.mergeIntoSlice(0, title.length, indexOfTitle))
    -      }
    -
    -      let slicesOfContent = []
    -      while (indexOfContent.length !== 0) {
    -        const item = indexOfContent[0]
    -        const { position } = item
    -        // Cut out 120 characters. The maxlength of .search-input is 80.
    -        const start = Math.max(0, position - 20)
    -        const end = Math.min(content.length, position + 100)
    -        slicesOfContent.push(this.mergeIntoSlice(start, end, indexOfContent))
    -      }
    -
    -      // Sort slices in content by included keywords' count and hits' count
    -      slicesOfContent.sort((left, right) => {
    -        if (left.count !== right.count) {
    -          return right.count - left.count
    -        } else if (left.hits.length !== right.hits.length) {
    -          return right.hits.length - left.hits.length
    -        }
    -        return left.start - right.start
    -      })
    -
    -      // Select top N slices in content
    -      const upperBound = parseInt(this.top_n_per_article, 10)
    -      if (upperBound >= 0) {
    -        slicesOfContent = slicesOfContent.slice(0, upperBound)
    -      }
    -
    -      let resultItem = ''
    -
    -      url = new URL(url, location.origin)
    -      url.searchParams.append('highlight', keywords.join(' '))
    -
    -      if (slicesOfTitle.length !== 0) {
    -        resultItem += `<div class="local-search-hit-item"><a href="${url.href}"><span class="search-result-title">${this.highlightKeyword(title, slicesOfTitle[0])}</span>`
    -      } else {
    -        resultItem += `<div class="local-search-hit-item"><a href="${url.href}"><span class="search-result-title">${title}</span>`
    -      }
    -
    -      slicesOfContent.forEach(slice => {
    -        resultItem += `<p class="search-result">${this.highlightKeyword(content, slice)}...</p></a>`
    -      })
    -
    -      resultItem += '</div>'
    -      resultItems.push({
    -        item: resultItem,
    -        id: resultItems.length,
    -        hitCount,
    -        includedCount
    -      })
    -    })
    -    return resultItems
    -  }
    -
    -  fetchData () {
    -    const isXml = !this.path.endsWith('json')
    -    fetch(this.path)
    -      .then(response => response.text())
    -      .then(res => {
    -        // Get the contents from search data
    -        this.isfetched = true
    -        this.datas = isXml
    -          ? [...new DOMParser().parseFromString(res, 'text/xml').querySelectorAll('entry')].map(element => ({
    -              title: element.querySelector('title').textContent,
    -              content: element.querySelector('content').textContent,
    -              url: element.querySelector('url').textContent
    -            }))
    -          : JSON.parse(res)
    -        // Only match articles with non-empty titles
    -        this.datas = this.datas.filter(data => data.title).map(data => {
    -          data.title = data.title.trim()
    -          data.content = data.content ? data.content.trim().replace(/<[^>]+>/g, '') : ''
    -          data.url = decodeURIComponent(data.url).replace(/\/{2,}/g, '/')
    -          return data
    -        })
    -        // Remove loading animation
    -        window.dispatchEvent(new Event('search:loaded'))
    -      })
    -  }
    -
    -  // Highlight by wrapping node in mark elements with the given class name
    -  highlightText (node, slice, className) {
    -    const val = node.nodeValue
    -    let index = slice.start
    -    const children = []
    -    for (const { position, length } of slice.hits) {
    -      const text = document.createTextNode(val.substring(index, position))
    -      index = position + length
    -      const mark = document.createElement('mark')
    -      mark.className = className
    -      mark.appendChild(document.createTextNode(val.substr(position, length)))
    -      children.push(text, mark)
    -    }
    -    node.nodeValue = val.substring(index, slice.end)
    -    children.forEach(element => {
    -      node.parentNode.insertBefore(element, node)
    -    })
    -  }
    -
    -  // Highlight the search words provided in the url in the text
    -  highlightSearchWords (body) {
    -    const params = new URL(location.href).searchParams.get('highlight')
    -    const keywords = params ? params.split(' ') : []
    -    if (!keywords.length || !body) return
    -    const walk = document.createTreeWalker(body, NodeFilter.SHOW_TEXT, null)
    -    const allNodes = []
    -    while (walk.nextNode()) {
    -      if (!walk.currentNode.parentNode.matches('button, select, textarea, .mermaid')) allNodes.push(walk.currentNode)
    -    }
    -    allNodes.forEach(node => {
    -      const [indexOfNode] = this.getIndexByWord(keywords, node.nodeValue)
    -      if (!indexOfNode.length) return
    -      const slice = this.mergeIntoSlice(0, node.nodeValue.length, indexOfNode)
    -      this.highlightText(node, slice, 'search-keyword')
    -    })
    -  }
    -}
    -
    -window.addEventListener('load', () => {
    -// Search
    -  const { path, top_n_per_article, unescape, languages } = GLOBAL_CONFIG.localSearch
    -  const localSearch = new LocalSearch({
    -    path,
    -    top_n_per_article,
    -    unescape
    -  })
    -
    -  const input = document.querySelector('#local-search-input input')
    -  const statsItem = document.getElementById('local-search-stats-wrap')
    -  const $loadingStatus = document.getElementById('loading-status')
    -  const isXml = !path.endsWith('json')
    -
    -  const inputEventFunction = () => {
    -    if (!localSearch.isfetched) return
    -    let searchText = input.value.trim().toLowerCase()
    -    isXml && (searchText = searchText.replace(/</g, '&lt;').replace(/>/g, '&gt;'))
    -    if (searchText !== '') $loadingStatus.innerHTML = '<i class="fas fa-spinner fa-pulse"></i>'
    -    const keywords = searchText.split(/[-\s]+/)
    -    const container = document.getElementById('local-search-results')
    -    let resultItems = []
    -    if (searchText.length > 0) {
    -    // Perform local searching
    -      resultItems = localSearch.getResultItems(keywords)
    -    }
    -    if (keywords.length === 1 && keywords[0] === '') {
    -      container.textContent = ''
    -      statsItem.textContent = ''
    -    } else if (resultItems.length === 0) {
    -      container.textContent = ''
    -      const statsDiv = document.createElement('div')
    -      statsDiv.className = 'search-result-stats'
    -      statsDiv.textContent = languages.hits_empty.replace(/\$\{query}/, searchText)
    -      statsItem.innerHTML = statsDiv.outerHTML
    -    } else {
    -      resultItems.sort((left, right) => {
    -        if (left.includedCount !== right.includedCount) {
    -          return right.includedCount - left.includedCount
    -        } else if (left.hitCount !== right.hitCount) {
    -          return right.hitCount - left.hitCount
    -        }
    -        return right.id - left.id
    -      })
    -
    -      const stats = languages.hits_stats.replace(/\$\{hits}/, resultItems.length)
    -
    -      container.innerHTML = `<div class="search-result-list">${resultItems.map(result => result.item).join('')}</div>`
    -      statsItem.innerHTML = `<hr><div class="search-result-stats">${stats}</div>`
    -      window.pjax && window.pjax.refresh(container)
    -    }
    -
    -    $loadingStatus.textContent = ''
    -  }
    -
    -  let loadFlag = false
    -  const $searchMask = document.getElementById('search-mask')
    -  const $searchDialog = document.querySelector('#local-search .search-dialog')
    -
    -  // fix safari
    -  const fixSafariHeight = () => {
    -    if (window.innerWidth < 768) {
    -      $searchDialog.style.setProperty('--search-height', window.innerHeight + 'px')
    -    }
    -  }
    -
    -  const openSearch = () => {
    -    const bodyStyle = document.body.style
    -    bodyStyle.width = '100%'
    -    bodyStyle.overflow = 'hidden'
    -    btf.animateIn($searchMask, 'to_show 0.5s')
    -    btf.animateIn($searchDialog, 'titleScale 0.5s')
    -    setTimeout(() => { input.focus() }, 300)
    -    if (!loadFlag) {
    -      !localSearch.isfetched && localSearch.fetchData()
    -      input.addEventListener('input', inputEventFunction)
    -      loadFlag = true
    -    }
    -    // shortcut: ESC
    -    document.addEventListener('keydown', function f (event) {
    -      if (event.code === 'Escape') {
    -        closeSearch()
    -        document.removeEventListener('keydown', f)
    -      }
    -    })
    -
    -    fixSafariHeight()
    -    window.addEventListener('resize', fixSafariHeight)
    -  }
    -
    -  const closeSearch = () => {
    -    const bodyStyle = document.body.style
    -    bodyStyle.width = ''
    -    bodyStyle.overflow = ''
    -    btf.animateOut($searchDialog, 'search_close .5s')
    -    btf.animateOut($searchMask, 'to_hide 0.5s')
    -    window.removeEventListener('resize', fixSafariHeight)
    -  }
    -
    -  const searchClickFn = () => {
    -    btf.addEventListenerPjax(document.querySelector('#search-button > .search'), 'click', openSearch)
    -  }
    -
    -  const searchFnOnce = () => {
    -    document.querySelector('#local-search .search-close-button').addEventListener('click', closeSearch)
    -    $searchMask.addEventListener('click', closeSearch)
    -    if (GLOBAL_CONFIG.localSearch.preload) {
    -      localSearch.fetchData()
    -    }
    -    localSearch.highlightSearchWords(document.getElementById('article-container'))
    -  }
    -
    -  window.addEventListener('search:loaded', () => {
    -    const $loadDataItem = document.getElementById('loading-database')
    -    $loadDataItem.nextElementSibling.style.display = 'block'
    -    $loadDataItem.remove()
    -  })
    -
    -  searchClickFn()
    -  searchFnOnce()
    -
    -  // pjax
    -  window.addEventListener('pjax:complete', () => {
    -    !btf.isHidden($searchMask) && closeSearch()
    -    localSearch.highlightSearchWords(document.getElementById('article-container'))
    -    searchClickFn()
    -  })
    -})
    diff --git a/themes/butterfly/source/js/tw_cn.js b/themes/butterfly/source/js/tw_cn.js
    deleted file mode 100644
    index 15d8d153..00000000
    --- a/themes/butterfly/source/js/tw_cn.js
    +++ /dev/null
    @@ -1,122 +0,0 @@
    -document.addEventListener('DOMContentLoaded', function () {
    -  const { defaultEncoding, translateDelay, msgToTraditionalChinese, msgToSimplifiedChinese } = GLOBAL_CONFIG.translate
    -  const snackbarData = GLOBAL_CONFIG.Snackbar
    -  let currentEncoding = defaultEncoding
    -  const targetEncodingCookie = 'translate-chn-cht'
    -  let targetEncoding =
    -    saveToLocal.get(targetEncodingCookie) === undefined
    -      ? defaultEncoding
    -      : Number(saveToLocal.get('translate-chn-cht'))
    -  let translateButtonObject
    -  const isSnackbar = snackbarData !== undefined
    -
    -  function setLang () {
    -    document.documentElement.lang = targetEncoding === 1 ? 'zh-TW' : 'zh-CN'
    -  }
    -
    -  function translateText (txt) {
    -    if (txt === '' || txt == null) return ''
    -    if (currentEncoding === 1 && targetEncoding === 2) return Simplized(txt)
    -    else if (currentEncoding === 2 && targetEncoding === 1) {
    -      return Traditionalized(txt)
    -    } else return txt
    -  }
    -
    -  function translateBody (fobj) {
    -    let objs
    -    if (typeof fobj === 'object') objs = fobj.childNodes
    -    else objs = document.body.childNodes
    -    for (let i = 0; i < objs.length; i++) {
    -      const obj = objs.item(i)
    -      if (
    -        '||BR|HR|'.indexOf('|' + obj.tagName + '|') > 0 ||
    -        obj === translateButtonObject
    -      ) {
    -        continue
    -      }
    -      if (obj.title !== '' && obj.title != null) {
    -        obj.title = translateText(obj.title)
    -      }
    -      if (obj.alt !== '' && obj.alt != null) obj.alt = translateText(obj.alt)
    -      if (obj.placeholder !== '' && obj.placeholder != null) { obj.placeholder = translateText(obj.placeholder) }
    -      if (
    -        obj.tagName === 'INPUT' &&
    -        obj.value !== '' &&
    -        obj.type !== 'text' &&
    -        obj.type !== 'hidden'
    -      ) {
    -        obj.value = translateText(obj.value)
    -      }
    -      if (obj.nodeType === 3) obj.data = translateText(obj.data)
    -      else translateBody(obj)
    -    }
    -  }
    -  function translatePage () {
    -    if (targetEncoding === 1) {
    -      currentEncoding = 1
    -      targetEncoding = 2
    -      translateButtonObject.textContent = msgToTraditionalChinese
    -      isSnackbar && btf.snackbarShow(snackbarData.cht_to_chs)
    -    } else if (targetEncoding === 2) {
    -      currentEncoding = 2
    -      targetEncoding = 1
    -      translateButtonObject.textContent = msgToSimplifiedChinese
    -      isSnackbar && btf.snackbarShow(snackbarData.chs_to_cht)
    -    }
    -    saveToLocal.set(targetEncodingCookie, targetEncoding, 2)
    -    setLang()
    -    translateBody()
    -  }
    -
    -  function JTPYStr () {
    -    return '万与丑专业丛东丝丢两严丧个丬丰临为丽举么义乌乐乔习乡书买乱争于亏云亘亚产亩亲亵亸亿仅从仑仓仪们价众优伙会伛伞伟传伤伥伦伧伪伫体余佣佥侠侣侥侦侧侨侩侪侬俣俦俨俩俪俭债倾偬偻偾偿傥傧储傩儿兑兖党兰关兴兹养兽冁内冈册写军农冢冯冲决况冻净凄凉凌减凑凛几凤凫凭凯击凼凿刍划刘则刚创删别刬刭刽刿剀剂剐剑剥剧劝办务劢动励劲劳势勋勐勚匀匦匮区医华协单卖卢卤卧卫却卺厂厅历厉压厌厍厕厢厣厦厨厩厮县参叆叇双发变叙叠叶号叹叽吁后吓吕吗吣吨听启吴呒呓呕呖呗员呙呛呜咏咔咙咛咝咤咴咸哌响哑哒哓哔哕哗哙哜哝哟唛唝唠唡唢唣唤唿啧啬啭啮啰啴啸喷喽喾嗫呵嗳嘘嘤嘱噜噼嚣嚯团园囱围囵国图圆圣圹场坂坏块坚坛坜坝坞坟坠垄垅垆垒垦垧垩垫垭垯垱垲垴埘埙埚埝埯堑堕塆墙壮声壳壶壸处备复够头夸夹夺奁奂奋奖奥妆妇妈妩妪妫姗姜娄娅娆娇娈娱娲娴婳婴婵婶媪嫒嫔嫱嬷孙学孪宁宝实宠审宪宫宽宾寝对寻导寿将尔尘尧尴尸尽层屃屉届属屡屦屿岁岂岖岗岘岙岚岛岭岳岽岿峃峄峡峣峤峥峦崂崃崄崭嵘嵚嵛嵝嵴巅巩巯币帅师帏帐帘帜带帧帮帱帻帼幂幞干并广庄庆庐庑库应庙庞废庼廪开异弃张弥弪弯弹强归当录彟彦彻径徕御忆忏忧忾怀态怂怃怄怅怆怜总怼怿恋恳恶恸恹恺恻恼恽悦悫悬悭悯惊惧惨惩惫惬惭惮惯愍愠愤愦愿慑慭憷懑懒懔戆戋戏戗战戬户扎扑扦执扩扪扫扬扰抚抛抟抠抡抢护报担拟拢拣拥拦拧拨择挂挚挛挜挝挞挟挠挡挢挣挤挥挦捞损捡换捣据捻掳掴掷掸掺掼揸揽揿搀搁搂搅携摄摅摆摇摈摊撄撑撵撷撸撺擞攒敌敛数斋斓斗斩断无旧时旷旸昙昼昽显晋晒晓晔晕晖暂暧札术朴机杀杂权条来杨杩杰极构枞枢枣枥枧枨枪枫枭柜柠柽栀栅标栈栉栊栋栌栎栏树栖样栾桊桠桡桢档桤桥桦桧桨桩梦梼梾检棂椁椟椠椤椭楼榄榇榈榉槚槛槟槠横樯樱橥橱橹橼檐檩欢欤欧歼殁殇残殒殓殚殡殴毁毂毕毙毡毵氇气氢氩氲汇汉污汤汹沓沟没沣沤沥沦沧沨沩沪沵泞泪泶泷泸泺泻泼泽泾洁洒洼浃浅浆浇浈浉浊测浍济浏浐浑浒浓浔浕涂涌涛涝涞涟涠涡涢涣涤润涧涨涩淀渊渌渍渎渐渑渔渖渗温游湾湿溃溅溆溇滗滚滞滟滠满滢滤滥滦滨滩滪漤潆潇潋潍潜潴澜濑濒灏灭灯灵灾灿炀炉炖炜炝点炼炽烁烂烃烛烟烦烧烨烩烫烬热焕焖焘煅煳熘爱爷牍牦牵牺犊犟状犷犸犹狈狍狝狞独狭狮狯狰狱狲猃猎猕猡猪猫猬献獭玑玙玚玛玮环现玱玺珉珏珐珑珰珲琎琏琐琼瑶瑷璇璎瓒瓮瓯电画畅畲畴疖疗疟疠疡疬疮疯疱疴痈痉痒痖痨痪痫痴瘅瘆瘗瘘瘪瘫瘾瘿癞癣癫癯皑皱皲盏盐监盖盗盘眍眦眬着睁睐睑瞒瞩矫矶矾矿砀码砖砗砚砜砺砻砾础硁硅硕硖硗硙硚确硷碍碛碜碱碹磙礼祎祢祯祷祸禀禄禅离秃秆种积称秽秾稆税稣稳穑穷窃窍窑窜窝窥窦窭竖竞笃笋笔笕笺笼笾筑筚筛筜筝筹签简箓箦箧箨箩箪箫篑篓篮篱簖籁籴类籼粜粝粤粪粮糁糇紧絷纟纠纡红纣纤纥约级纨纩纪纫纬纭纮纯纰纱纲纳纴纵纶纷纸纹纺纻纼纽纾线绀绁绂练组绅细织终绉绊绋绌绍绎经绐绑绒结绔绕绖绗绘给绚绛络绝绞统绠绡绢绣绤绥绦继绨绩绪绫绬续绮绯绰绱绲绳维绵绶绷绸绹绺绻综绽绾绿缀缁缂缃缄缅缆缇缈缉缊缋缌缍缎缏缐缑缒缓缔缕编缗缘缙缚缛缜缝缞缟缠缡缢缣缤缥缦缧缨缩缪缫缬缭缮缯缰缱缲缳缴缵罂网罗罚罢罴羁羟羡翘翙翚耢耧耸耻聂聋职聍联聩聪肃肠肤肷肾肿胀胁胆胜胧胨胪胫胶脉脍脏脐脑脓脔脚脱脶脸腊腌腘腭腻腼腽腾膑臜舆舣舰舱舻艰艳艹艺节芈芗芜芦苁苇苈苋苌苍苎苏苘苹茎茏茑茔茕茧荆荐荙荚荛荜荞荟荠荡荣荤荥荦荧荨荩荪荫荬荭荮药莅莜莱莲莳莴莶获莸莹莺莼萚萝萤营萦萧萨葱蒇蒉蒋蒌蓝蓟蓠蓣蓥蓦蔷蔹蔺蔼蕲蕴薮藁藓虏虑虚虫虬虮虽虾虿蚀蚁蚂蚕蚝蚬蛊蛎蛏蛮蛰蛱蛲蛳蛴蜕蜗蜡蝇蝈蝉蝎蝼蝾螀螨蟏衅衔补衬衮袄袅袆袜袭袯装裆裈裢裣裤裥褛褴襁襕见观觃规觅视觇览觉觊觋觌觍觎觏觐觑觞触觯詟誉誊讠计订讣认讥讦讧讨让讪讫训议讯记讱讲讳讴讵讶讷许讹论讻讼讽设访诀证诂诃评诅识诇诈诉诊诋诌词诎诏诐译诒诓诔试诖诗诘诙诚诛诜话诞诟诠诡询诣诤该详诧诨诩诪诫诬语诮误诰诱诲诳说诵诶请诸诹诺读诼诽课诿谀谁谂调谄谅谆谇谈谊谋谌谍谎谏谐谑谒谓谔谕谖谗谘谙谚谛谜谝谞谟谠谡谢谣谤谥谦谧谨谩谪谫谬谭谮谯谰谱谲谳谴谵谶谷豮贝贞负贠贡财责贤败账货质贩贪贫贬购贮贯贰贱贲贳贴贵贶贷贸费贺贻贼贽贾贿赀赁赂赃资赅赆赇赈赉赊赋赌赍赎赏赐赑赒赓赔赕赖赗赘赙赚赛赜赝赞赟赠赡赢赣赪赵赶趋趱趸跃跄跖跞践跶跷跸跹跻踊踌踪踬踯蹑蹒蹰蹿躏躜躯车轧轨轩轪轫转轭轮软轰轱轲轳轴轵轶轷轸轹轺轻轼载轾轿辀辁辂较辄辅辆辇辈辉辊辋辌辍辎辏辐辑辒输辔辕辖辗辘辙辚辞辩辫边辽达迁过迈运还这进远违连迟迩迳迹适选逊递逦逻遗遥邓邝邬邮邹邺邻郁郄郏郐郑郓郦郧郸酝酦酱酽酾酿释里鉅鉴銮錾钆钇针钉钊钋钌钍钎钏钐钑钒钓钔钕钖钗钘钙钚钛钝钞钟钠钡钢钣钤钥钦钧钨钩钪钫钬钭钮钯钰钱钲钳钴钵钶钷钸钹钺钻钼钽钾钿铀铁铂铃铄铅铆铈铉铊铋铍铎铏铐铑铒铕铗铘铙铚铛铜铝铞铟铠铡铢铣铤铥铦铧铨铪铫铬铭铮铯铰铱铲铳铴铵银铷铸铹铺铻铼铽链铿销锁锂锃锄锅锆锇锈锉锊锋锌锍锎锏锐锑锒锓锔锕锖锗错锚锜锞锟锠锡锢锣锤锥锦锨锩锫锬锭键锯锰锱锲锳锴锵锶锷锸锹锺锻锼锽锾锿镀镁镂镃镆镇镈镉镊镌镍镎镏镐镑镒镕镖镗镙镚镛镜镝镞镟镠镡镢镣镤镥镦镧镨镩镪镫镬镭镮镯镰镱镲镳镴镶长门闩闪闫闬闭问闯闰闱闲闳间闵闶闷闸闹闺闻闼闽闾闿阀阁阂阃阄阅阆阇阈阉阊阋阌阍阎阏阐阑阒阓阔阕阖阗阘阙阚阛队阳阴阵阶际陆陇陈陉陕陧陨险随隐隶隽难雏雠雳雾霁霉霭靓静靥鞑鞒鞯鞴韦韧韨韩韪韫韬韵页顶顷顸项顺须顼顽顾顿颀颁颂颃预颅领颇颈颉颊颋颌颍颎颏颐频颒颓颔颕颖颗题颙颚颛颜额颞颟颠颡颢颣颤颥颦颧风飏飐飑飒飓飔飕飖飗飘飙飚飞飨餍饤饥饦饧饨饩饪饫饬饭饮饯饰饱饲饳饴饵饶饷饸饹饺饻饼饽饾饿馀馁馂馃馄馅馆馇馈馉馊馋馌馍馎馏馐馑馒馓馔馕马驭驮驯驰驱驲驳驴驵驶驷驸驹驺驻驼驽驾驿骀骁骂骃骄骅骆骇骈骉骊骋验骍骎骏骐骑骒骓骔骕骖骗骘骙骚骛骜骝骞骟骠骡骢骣骤骥骦骧髅髋髌鬓魇魉鱼鱽鱾鱿鲀鲁鲂鲄鲅鲆鲇鲈鲉鲊鲋鲌鲍鲎鲏鲐鲑鲒鲓鲔鲕鲖鲗鲘鲙鲚鲛鲜鲝鲞鲟鲠鲡鲢鲣鲤鲥鲦鲧鲨鲩鲪鲫鲬鲭鲮鲯鲰鲱鲲鲳鲴鲵鲶鲷鲸鲹鲺鲻鲼鲽鲾鲿鳀鳁鳂鳃鳄鳅鳆鳇鳈鳉鳊鳋鳌鳍鳎鳏鳐鳑鳒鳓鳔鳕鳖鳗鳘鳙鳛鳜鳝鳞鳟鳠鳡鳢鳣鸟鸠鸡鸢鸣鸤鸥鸦鸧鸨鸩鸪鸫鸬鸭鸮鸯鸰鸱鸲鸳鸴鸵鸶鸷鸸鸹鸺鸻鸼鸽鸾鸿鹀鹁鹂鹃鹄鹅鹆鹇鹈鹉鹊鹋鹌鹍鹎鹏鹐鹑鹒鹓鹔鹕鹖鹗鹘鹚鹛鹜鹝鹞鹟鹠鹡鹢鹣鹤鹥鹦鹧鹨鹩鹪鹫鹬鹭鹯鹰鹱鹲鹳鹴鹾麦麸黄黉黡黩黪黾龙历志制一台皋准复猛钟注范签'
    -  }
    -  function FTPYStr () {
    -    return '萬與醜專業叢東絲丟兩嚴喪個爿豐臨為麗舉麼義烏樂喬習鄉書買亂爭於虧雲亙亞產畝親褻嚲億僅從侖倉儀們價眾優夥會傴傘偉傳傷倀倫傖偽佇體餘傭僉俠侶僥偵側僑儈儕儂俁儔儼倆儷儉債傾傯僂僨償儻儐儲儺兒兌兗黨蘭關興茲養獸囅內岡冊寫軍農塚馮衝決況凍淨淒涼淩減湊凜幾鳳鳧憑凱擊氹鑿芻劃劉則剛創刪別剗剄劊劌剴劑剮劍剝劇勸辦務勱動勵勁勞勢勳猛勩勻匭匱區醫華協單賣盧鹵臥衛卻巹廠廳曆厲壓厭厙廁廂厴廈廚廄廝縣參靉靆雙發變敘疊葉號歎嘰籲後嚇呂嗎唚噸聽啟吳嘸囈嘔嚦唄員咼嗆嗚詠哢嚨嚀噝吒噅鹹呱響啞噠嘵嗶噦嘩噲嚌噥喲嘜嗊嘮啢嗩唕喚呼嘖嗇囀齧囉嘽嘯噴嘍嚳囁嗬噯噓嚶囑嚕劈囂謔團園囪圍圇國圖圓聖壙場阪壞塊堅壇壢壩塢墳墜壟壟壚壘墾坰堊墊埡墶壋塏堖塒塤堝墊垵塹墮壪牆壯聲殼壺壼處備複夠頭誇夾奪奩奐奮獎奧妝婦媽嫵嫗媯姍薑婁婭嬈嬌孌娛媧嫻嫿嬰嬋嬸媼嬡嬪嬙嬤孫學孿寧寶實寵審憲宮寬賓寢對尋導壽將爾塵堯尷屍盡層屭屜屆屬屢屨嶼歲豈嶇崗峴嶴嵐島嶺嶽崠巋嶨嶧峽嶢嶠崢巒嶗崍嶮嶄嶸嶔崳嶁脊巔鞏巰幣帥師幃帳簾幟帶幀幫幬幘幗冪襆幹並廣莊慶廬廡庫應廟龐廢廎廩開異棄張彌弳彎彈強歸當錄彠彥徹徑徠禦憶懺憂愾懷態慫憮慪悵愴憐總懟懌戀懇惡慟懨愷惻惱惲悅愨懸慳憫驚懼慘懲憊愜慚憚慣湣慍憤憒願懾憖怵懣懶懍戇戔戲戧戰戩戶紮撲扡執擴捫掃揚擾撫拋摶摳掄搶護報擔擬攏揀擁攔擰撥擇掛摯攣掗撾撻挾撓擋撟掙擠揮撏撈損撿換搗據撚擄摑擲撣摻摜摣攬撳攙擱摟攪攜攝攄擺搖擯攤攖撐攆擷擼攛擻攢敵斂數齋斕鬥斬斷無舊時曠暘曇晝曨顯晉曬曉曄暈暉暫曖劄術樸機殺雜權條來楊榪傑極構樅樞棗櫪梘棖槍楓梟櫃檸檉梔柵標棧櫛櫳棟櫨櫟欄樹棲樣欒棬椏橈楨檔榿橋樺檜槳樁夢檮棶檢欞槨櫝槧欏橢樓欖櫬櫚櫸檟檻檳櫧橫檣櫻櫫櫥櫓櫞簷檁歡歟歐殲歿殤殘殞殮殫殯毆毀轂畢斃氈毿氌氣氫氬氳彙漢汙湯洶遝溝沒灃漚瀝淪滄渢溈滬濔濘淚澩瀧瀘濼瀉潑澤涇潔灑窪浹淺漿澆湞溮濁測澮濟瀏滻渾滸濃潯濜塗湧濤澇淶漣潿渦溳渙滌潤澗漲澀澱淵淥漬瀆漸澠漁瀋滲溫遊灣濕潰濺漵漊潷滾滯灩灄滿瀅濾濫灤濱灘澦濫瀠瀟瀲濰潛瀦瀾瀨瀕灝滅燈靈災燦煬爐燉煒熗點煉熾爍爛烴燭煙煩燒燁燴燙燼熱煥燜燾煆糊溜愛爺牘犛牽犧犢強狀獷獁猶狽麅獮獰獨狹獅獪猙獄猻獫獵獼玀豬貓蝟獻獺璣璵瑒瑪瑋環現瑲璽瑉玨琺瓏璫琿璡璉瑣瓊瑤璦璿瓔瓚甕甌電畫暢佘疇癤療瘧癘瘍鬁瘡瘋皰屙癰痙癢瘂癆瘓癇癡癉瘮瘞瘺癟癱癮癭癩癬癲臒皚皺皸盞鹽監蓋盜盤瞘眥矓著睜睞瞼瞞矚矯磯礬礦碭碼磚硨硯碸礪礱礫礎硜矽碩硤磽磑礄確鹼礙磧磣堿镟滾禮禕禰禎禱禍稟祿禪離禿稈種積稱穢穠穭稅穌穩穡窮竊竅窯竄窩窺竇窶豎競篤筍筆筧箋籠籩築篳篩簹箏籌簽簡籙簀篋籜籮簞簫簣簍籃籬籪籟糴類秈糶糲粵糞糧糝餱緊縶糸糾紆紅紂纖紇約級紈纊紀紉緯紜紘純紕紗綱納紝縱綸紛紙紋紡紵紖紐紓線紺絏紱練組紳細織終縐絆紼絀紹繹經紿綁絨結絝繞絰絎繪給絢絳絡絕絞統綆綃絹繡綌綏絛繼綈績緒綾緓續綺緋綽緔緄繩維綿綬繃綢綯綹綣綜綻綰綠綴緇緙緗緘緬纜緹緲緝縕繢緦綞緞緶線緱縋緩締縷編緡緣縉縛縟縝縫縗縞纏縭縊縑繽縹縵縲纓縮繆繅纈繚繕繒韁繾繰繯繳纘罌網羅罰罷羆羈羥羨翹翽翬耮耬聳恥聶聾職聹聯聵聰肅腸膚膁腎腫脹脅膽勝朧腖臚脛膠脈膾髒臍腦膿臠腳脫腡臉臘醃膕齶膩靦膃騰臏臢輿艤艦艙艫艱豔艸藝節羋薌蕪蘆蓯葦藶莧萇蒼苧蘇檾蘋莖蘢蔦塋煢繭荊薦薘莢蕘蓽蕎薈薺蕩榮葷滎犖熒蕁藎蓀蔭蕒葒葤藥蒞蓧萊蓮蒔萵薟獲蕕瑩鶯蓴蘀蘿螢營縈蕭薩蔥蕆蕢蔣蔞藍薊蘺蕷鎣驀薔蘞藺藹蘄蘊藪槁蘚虜慮虛蟲虯蟣雖蝦蠆蝕蟻螞蠶蠔蜆蠱蠣蟶蠻蟄蛺蟯螄蠐蛻蝸蠟蠅蟈蟬蠍螻蠑螿蟎蠨釁銜補襯袞襖嫋褘襪襲襏裝襠褌褳襝褲襇褸襤繈襴見觀覎規覓視覘覽覺覬覡覿覥覦覯覲覷觴觸觶讋譽謄訁計訂訃認譏訐訌討讓訕訖訓議訊記訒講諱謳詎訝訥許訛論訩訟諷設訪訣證詁訶評詛識詗詐訴診詆謅詞詘詔詖譯詒誆誄試詿詩詰詼誠誅詵話誕詬詮詭詢詣諍該詳詫諢詡譸誡誣語誚誤誥誘誨誑說誦誒請諸諏諾讀諑誹課諉諛誰諗調諂諒諄誶談誼謀諶諜謊諫諧謔謁謂諤諭諼讒諮諳諺諦謎諞諝謨讜謖謝謠謗諡謙謐謹謾謫譾謬譚譖譙讕譜譎讞譴譫讖穀豶貝貞負貟貢財責賢敗賬貨質販貪貧貶購貯貫貳賤賁貰貼貴貺貸貿費賀貽賊贄賈賄貲賃賂贓資賅贐賕賑賚賒賦賭齎贖賞賜贔賙賡賠賧賴賵贅賻賺賽賾贗讚贇贈贍贏贛赬趙趕趨趲躉躍蹌蹠躒踐躂蹺蹕躚躋踴躊蹤躓躑躡蹣躕躥躪躦軀車軋軌軒軑軔轉軛輪軟轟軲軻轤軸軹軼軤軫轢軺輕軾載輊轎輈輇輅較輒輔輛輦輩輝輥輞輬輟輜輳輻輯轀輸轡轅轄輾轆轍轔辭辯辮邊遼達遷過邁運還這進遠違連遲邇逕跡適選遜遞邐邏遺遙鄧鄺鄔郵鄒鄴鄰鬱郤郟鄶鄭鄆酈鄖鄲醞醱醬釅釃釀釋裏钜鑒鑾鏨釓釔針釘釗釙釕釷釺釧釤鈒釩釣鍆釹鍚釵鈃鈣鈈鈦鈍鈔鍾鈉鋇鋼鈑鈐鑰欽鈞鎢鉤鈧鈁鈥鈄鈕鈀鈺錢鉦鉗鈷缽鈳鉕鈽鈸鉞鑽鉬鉭鉀鈿鈾鐵鉑鈴鑠鉛鉚鈰鉉鉈鉍鈹鐸鉶銬銠鉺銪鋏鋣鐃銍鐺銅鋁銱銦鎧鍘銖銑鋌銩銛鏵銓鉿銚鉻銘錚銫鉸銥鏟銃鐋銨銀銣鑄鐒鋪鋙錸鋱鏈鏗銷鎖鋰鋥鋤鍋鋯鋨鏽銼鋝鋒鋅鋶鐦鐧銳銻鋃鋟鋦錒錆鍺錯錨錡錁錕錩錫錮鑼錘錐錦鍁錈錇錟錠鍵鋸錳錙鍥鍈鍇鏘鍶鍔鍤鍬鍾鍛鎪鍠鍰鎄鍍鎂鏤鎡鏌鎮鎛鎘鑷鐫鎳鎿鎦鎬鎊鎰鎔鏢鏜鏍鏰鏞鏡鏑鏃鏇鏐鐔钁鐐鏷鑥鐓鑭鐠鑹鏹鐙鑊鐳鐶鐲鐮鐿鑔鑣鑞鑲長門閂閃閆閈閉問闖閏闈閑閎間閔閌悶閘鬧閨聞闥閩閭闓閥閣閡閫鬮閱閬闍閾閹閶鬩閿閽閻閼闡闌闃闠闊闋闔闐闒闕闞闤隊陽陰陣階際陸隴陳陘陝隉隕險隨隱隸雋難雛讎靂霧霽黴靄靚靜靨韃鞽韉韝韋韌韍韓韙韞韜韻頁頂頃頇項順須頊頑顧頓頎頒頌頏預顱領頗頸頡頰頲頜潁熲頦頤頻頮頹頷頴穎顆題顒顎顓顏額顳顢顛顙顥纇顫顬顰顴風颺颭颮颯颶颸颼颻飀飄飆飆飛饗饜飣饑飥餳飩餼飪飫飭飯飲餞飾飽飼飿飴餌饒餉餄餎餃餏餅餑餖餓餘餒餕餜餛餡館餷饋餶餿饞饁饃餺餾饈饉饅饊饌饢馬馭馱馴馳驅馹駁驢駔駛駟駙駒騶駐駝駑駕驛駘驍罵駰驕驊駱駭駢驫驪騁驗騂駸駿騏騎騍騅騌驌驂騙騭騤騷騖驁騮騫騸驃騾驄驏驟驥驦驤髏髖髕鬢魘魎魚魛魢魷魨魯魴魺鮁鮃鯰鱸鮋鮓鮒鮊鮑鱟鮍鮐鮭鮚鮳鮪鮞鮦鰂鮜鱠鱭鮫鮮鮺鯗鱘鯁鱺鰱鰹鯉鰣鰷鯀鯊鯇鮶鯽鯒鯖鯪鯕鯫鯡鯤鯧鯝鯢鯰鯛鯨鯵鯴鯔鱝鰈鰏鱨鯷鰮鰃鰓鱷鰍鰒鰉鰁鱂鯿鰠鼇鰭鰨鰥鰩鰟鰜鰳鰾鱈鱉鰻鰵鱅鰼鱖鱔鱗鱒鱯鱤鱧鱣鳥鳩雞鳶鳴鳲鷗鴉鶬鴇鴆鴣鶇鸕鴨鴞鴦鴒鴟鴝鴛鴬鴕鷥鷙鴯鴰鵂鴴鵃鴿鸞鴻鵐鵓鸝鵑鵠鵝鵒鷳鵜鵡鵲鶓鵪鶤鵯鵬鵮鶉鶊鵷鷫鶘鶡鶚鶻鶿鶥鶩鷊鷂鶲鶹鶺鷁鶼鶴鷖鸚鷓鷚鷯鷦鷲鷸鷺鸇鷹鸌鸏鸛鸘鹺麥麩黃黌黶黷黲黽龍歷誌製壹臺臯準復勐鐘註範籤'
    -  }
    -  function Traditionalized (cc) {
    -    let str = ''
    -    const ss = JTPYStr()
    -    const tt = FTPYStr()
    -    for (let i = 0; i < cc.length; i++) {
    -      if (cc.charCodeAt(i) > 10000 && ss.indexOf(cc.charAt(i)) !== -1) {
    -        str += tt.charAt(ss.indexOf(cc.charAt(i)))
    -      } else str += cc.charAt(i)
    -    }
    -    return str
    -  }
    -  function Simplized (cc) {
    -    let str = ''
    -    const ss = JTPYStr()
    -    const tt = FTPYStr()
    -    for (let i = 0; i < cc.length; i++) {
    -      if (cc.charCodeAt(i) > 10000 && tt.indexOf(cc.charAt(i)) !== -1) {
    -        str += ss.charAt(tt.indexOf(cc.charAt(i)))
    -      } else str += cc.charAt(i)
    -    }
    -    return str
    -  }
    -
    -  function translateInitialization () {
    -    translateButtonObject = document.getElementById('translateLink')
    -    if (translateButtonObject) {
    -      if (currentEncoding !== targetEncoding) {
    -        translateButtonObject.textContent =
    -          targetEncoding === 1
    -            ? msgToSimplifiedChinese
    -            : msgToTraditionalChinese
    -        setLang()
    -        setTimeout(translateBody, translateDelay)
    -      }
    -    }
    -  }
    -
    -  window.translateFn = {
    -    translatePage,
    -    Traditionalized,
    -    Simplized
    -  }
    -
    -  translateInitialization()
    -  document.addEventListener('pjax:complete', translateInitialization)
    -})
    diff --git a/themes/butterfly/source/js/utils.js b/themes/butterfly/source/js/utils.js
    deleted file mode 100644
    index 2c8242ca..00000000
    --- a/themes/butterfly/source/js/utils.js
    +++ /dev/null
    @@ -1,296 +0,0 @@
    -const btf = {
    -  debounce: (func, wait = 0, immediate = false) => {
    -    let timeout
    -    return (...args) => {
    -      const later = () => {
    -        timeout = null
    -        if (!immediate) func(...args)
    -      }
    -      const callNow = immediate && !timeout
    -      clearTimeout(timeout)
    -      timeout = setTimeout(later, wait)
    -      if (callNow) func(...args)
    -    }
    -  },
    -
    -  throttle: function (func, wait, options = {}) {
    -    let timeout, context, args
    -    let previous = 0
    -
    -    const later = () => {
    -      previous = options.leading === false ? 0 : new Date().getTime()
    -      timeout = null
    -      func.apply(context, args)
    -      if (!timeout) context = args = null
    -    }
    -
    -    const throttled = (...params) => {
    -      const now = new Date().getTime()
    -      if (!previous && options.leading === false) previous = now
    -      const remaining = wait - (now - previous)
    -      context = this
    -      args = params
    -      if (remaining <= 0 || remaining > wait) {
    -        if (timeout) {
    -          clearTimeout(timeout)
    -          timeout = null
    -        }
    -        previous = now
    -        func.apply(context, args)
    -        if (!timeout) context = args = null
    -      } else if (!timeout && options.trailing !== false) {
    -        timeout = setTimeout(later, remaining)
    -      }
    -    }
    -
    -    return throttled
    -  },
    -
    -  sidebarPaddingR: () => {
    -    const innerWidth = window.innerWidth
    -    const clientWidth = document.body.clientWidth
    -    const paddingRight = innerWidth - clientWidth
    -    if (innerWidth !== clientWidth) {
    -      document.body.style.paddingRight = paddingRight + 'px'
    -    }
    -  },
    -
    -  snackbarShow: (text, showAction = false, duration = 2000) => {
    -    const { position, bgLight, bgDark } = GLOBAL_CONFIG.Snackbar
    -    const bg = document.documentElement.getAttribute('data-theme') === 'light' ? bgLight : bgDark
    -    Snackbar.show({
    -      text,
    -      backgroundColor: bg,
    -      showAction,
    -      duration,
    -      pos: position,
    -      customClass: 'snackbar-css'
    -    })
    -  },
    -
    -  diffDate: (d, more = false) => {
    -    const dateNow = new Date()
    -    const datePost = new Date(d)
    -    const dateDiff = dateNow.getTime() - datePost.getTime()
    -    const minute = 1000 * 60
    -    const hour = minute * 60
    -    const day = hour * 24
    -    const month = day * 30
    -    const { dateSuffix } = GLOBAL_CONFIG
    -
    -    if (!more) return parseInt(dateDiff / day)
    -
    -    const monthCount = dateDiff / month
    -    const dayCount = dateDiff / day
    -    const hourCount = dateDiff / hour
    -    const minuteCount = dateDiff / minute
    -
    -    if (monthCount > 12) return datePost.toISOString().slice(0, 10)
    -    if (monthCount >= 1) return `${parseInt(monthCount)} ${dateSuffix.month}`
    -    if (dayCount >= 1) return `${parseInt(dayCount)} ${dateSuffix.day}`
    -    if (hourCount >= 1) return `${parseInt(hourCount)} ${dateSuffix.hour}`
    -    if (minuteCount >= 1) return `${parseInt(minuteCount)} ${dateSuffix.min}`
    -    return dateSuffix.just
    -  },
    -
    -  loadComment: (dom, callback) => {
    -    if ('IntersectionObserver' in window) {
    -      const observerItem = new IntersectionObserver((entries) => {
    -        if (entries[0].isIntersecting) {
    -          callback()
    -          observerItem.disconnect()
    -        }
    -      }, { threshold: [0] })
    -      observerItem.observe(dom)
    -    } else {
    -      callback()
    -    }
    -  },
    -
    -  scrollToDest: (pos, time = 500) => {
    -    const currentPos = window.pageYOffset
    -    const isNavFixed = document.getElementById('page-header').classList.contains('fixed')
    -    if (currentPos > pos || isNavFixed) pos = pos - 70
    -
    -    if ('scrollBehavior' in document.documentElement.style) {
    -      window.scrollTo({
    -        top: pos,
    -        behavior: 'smooth'
    -      })
    -      return
    -    }
    -
    -    let start = null
    -    pos = +pos
    -    window.requestAnimationFrame(function step (currentTime) {
    -      start = !start ? currentTime : start
    -      const progress = currentTime - start
    -      if (currentPos < pos) {
    -        window.scrollTo(0, ((pos - currentPos) * progress / time) + currentPos)
    -      } else {
    -        window.scrollTo(0, currentPos - ((currentPos - pos) * progress / time))
    -      }
    -      if (progress < time) {
    -        window.requestAnimationFrame(step)
    -      } else {
    -        window.scrollTo(0, pos)
    -      }
    -    })
    -  },
    -
    -  animateIn: (ele, text) => {
    -    ele.style.display = 'block'
    -    ele.style.animation = text
    -  },
    -
    -  animateOut: (ele, text) => {
    -    ele.addEventListener('animationend', function f () {
    -      ele.style.display = ''
    -      ele.style.animation = ''
    -      ele.removeEventListener('animationend', f)
    -    })
    -    ele.style.animation = text
    -  },
    -
    -  wrap: (selector, eleType, options) => {
    -    const createEle = document.createElement(eleType)
    -    for (const [key, value] of Object.entries(options)) {
    -      createEle.setAttribute(key, value)
    -    }
    -    selector.parentNode.insertBefore(createEle, selector)
    -    createEle.appendChild(selector)
    -  },
    -
    -  isHidden: ele => ele.offsetHeight === 0 && ele.offsetWidth === 0,
    -
    -  getEleTop: ele => {
    -    let actualTop = ele.offsetTop
    -    let current = ele.offsetParent
    -
    -    while (current !== null) {
    -      actualTop += current.offsetTop
    -      current = current.offsetParent
    -    }
    -
    -    return actualTop
    -  },
    -
    -  loadLightbox: ele => {
    -    const service = GLOBAL_CONFIG.lightbox
    -
    -    if (service === 'mediumZoom') {
    -      mediumZoom(ele, { background: 'var(--zoom-bg)' })
    -    }
    -
    -    if (service === 'fancybox') {
    -      Array.from(ele).forEach(i => {
    -        if (i.parentNode.tagName !== 'A') {
    -          const dataSrc = i.dataset.lazySrc || i.src
    -          const dataCaption = i.title || i.alt || ''
    -          btf.wrap(i, 'a', { href: dataSrc, 'data-fancybox': 'gallery', 'data-caption': dataCaption, 'data-thumb': dataSrc })
    -        }
    -      })
    -
    -      if (!window.fancyboxRun) {
    -        Fancybox.bind('[data-fancybox]', {
    -          Hash: false,
    -          Thumbs: {
    -            showOnStart: false
    -          },
    -          Images: {
    -            Panzoom: {
    -              maxScale: 4
    -            }
    -          },
    -          Carousel: {
    -            transition: 'slide'
    -          },
    -          Toolbar: {
    -            display: {
    -              left: ['infobar'],
    -              middle: [
    -                'zoomIn',
    -                'zoomOut',
    -                'toggle1to1',
    -                'rotateCCW',
    -                'rotateCW',
    -                'flipX',
    -                'flipY'
    -              ],
    -              right: ['slideshow', 'thumbs', 'close']
    -            }
    -          }
    -        })
    -        window.fancyboxRun = true
    -      }
    -    }
    -  },
    -
    -  setLoading: {
    -    add: ele => {
    -      const html = `
    -        <div class="loading-container">
    -          <div class="loading-item">
    -            <div></div><div></div><div></div><div></div><div></div>
    -          </div>
    -        </div>
    -      `
    -      ele.insertAdjacentHTML('afterend', html)
    -    },
    -    remove: ele => {
    -      ele.nextElementSibling.remove()
    -    }
    -  },
    -
    -  updateAnchor: (anchor) => {
    -    if (anchor !== window.location.hash) {
    -      if (!anchor) anchor = location.pathname
    -      const title = GLOBAL_CONFIG_SITE.title
    -      window.history.replaceState({
    -        url: location.href,
    -        title
    -      }, title, anchor)
    -    }
    -  },
    -
    -  getScrollPercent: (currentTop, ele) => {
    -    const docHeight = ele.clientHeight
    -    const winHeight = document.documentElement.clientHeight
    -    const headerHeight = ele.offsetTop
    -    const contentMath = (docHeight > winHeight) ? (docHeight - winHeight) : (document.documentElement.scrollHeight - winHeight)
    -    const scrollPercent = (currentTop - headerHeight) / (contentMath)
    -    const scrollPercentRounded = Math.round(scrollPercent * 100)
    -    const percentage = (scrollPercentRounded > 100) ? 100 : (scrollPercentRounded <= 0) ? 0 : scrollPercentRounded
    -    return percentage
    -  },
    -
    -  addGlobalFn: (key, fn, name = false, parent = window) => {
    -    const globalFn = parent.globalFn || {}
    -    const keyObj = globalFn[key] || {}
    -
    -    if (name && keyObj[name]) return
    -
    -    name = name || Object.keys(keyObj).length
    -    keyObj[name] = fn
    -    globalFn[key] = keyObj
    -    parent.globalFn = globalFn
    -  },
    -
    -  addEventListenerPjax: (ele, event, fn, option = false) => {
    -    ele.addEventListener(event, fn, option)
    -    btf.addGlobalFn('pjax', () => {
    -      ele.removeEventListener(event, fn, option)
    -    })
    -  },
    -
    -  removeGlobalFnEvent: (key, parent = window) => {
    -    const { globalFn = {} } = parent
    -    const keyObj = globalFn[key] || {}
    -    const keyArr = Object.keys(keyObj)
    -    if (!keyArr.length) return
    -    keyArr.forEach(i => {
    -      keyObj[i]()
    -    })
    -    delete parent.globalFn[key]
    -  }
    -}