[
  {
    "path": ".eslintignore",
    "content": "node_modules/"
  },
  {
    "path": ".eslintrc.json",
    "content": "{\n  \"extends\": [\n    \"hexo\",\n    \"plugin:react/recommended\",\n    \"plugin:json/recommended\"\n  ],\n  \"settings\": {\n    \"node\": {\n      \"tryExtensions\": [\n        \".js\",\n        \".jsx\",\n        \".json\"\n      ]\n    },\n    \"react\": {\n      \"version\": \"16.0\"\n    }\n  },\n  \"parserOptions\": {\n    \"ecmaFeatures\": {\n      \"jsx\": true\n    },\n    \"sourceType\": \"module\",\n    \"ecmaVersion\": \"latest\"\n  },\n  \"plugins\": [\n    \"react\"\n  ],\n  \"rules\": {\n    \"react/jsx-uses-vars\": \"error\",\n    \"indent\": [\n      \"error\",\n      4,\n      {\n        \"SwitchCase\": 1\n      }\n    ],\n    \"react/no-unknown-property\": [\n      \"error\",\n      {\n        \"ignore\": [\n          \"class\",\n          \"onclick\",\n          \"onload\",\n          \"onsubmit\",\n          \"crossorigin\"\n        ]\n      }\n    ],\n    \"react/react-in-jsx-scope\": [\n      \"off\"\n    ],\n    \"react/prop-types\": [\n      \"off\"\n    ],\n    \"react/display-name\": [\n      \"off\"\n    ],\n    \"react/jsx-key\": [\n      \"off\"\n    ],\n    \"react/jsx-no-target-blank\": [\n      \"error\",\n      {\n        \"allowReferrer\": true\n      }\n    ]\n  }\n}"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/Bug反馈.md",
    "content": "---\nname: Bug反馈\nabout: 请按照模板填写Bug反馈，否则你的Issue可能会被直接关闭。\ntitle: [Bug] 问题概述\nlabels: ''\nassignees: ''\n\n---\n\n> 确保你在提交Bug反馈之前仔细阅读了[Hexo文档](https://hexo.io/zh-cn/)，[Icarus用户指南](https://ppoffice.github.io/hexo-theme-icarus/tags/Icarus%E7%94%A8%E6%88%B7%E6%8C%87%E5%8D%97/)，和[GitHub issues](https://github.com/ppoffice/hexo-theme-icarus/issues)来了解你的问题是否已经被他人提出过。\n\n**Bug描述**\n简洁清晰地描述你遇到的Bug是什么。\n\n**系统与环境**\n列出你的Hexo和Icarus的版本和配置。\n\n- Hexo，操作系统，和Node.js的版本（使用`hexo version`命令来查看）\n- 站点配置文件`_config.yml`\n- 主题配置文件`_config.icarus.yml`或`themes/icarus/_config.yml`\n- 其他额外的配置文件（文章front-matter，`_config.post.yml`，或`_config.page.yml`）\n- 浏览器版本（如Firefox 70.0，Chrome Android 80.0）\n\n**复现方式**\n列出复现这个Bug的步骤，如：\n\n1. 访问‘...’\n2. 点击’...‘\n3. 下拉到‘...’\n4. 出现‘...’的错误\n\n**期望行为**\n简洁清晰地描述没有这个情况下你期望得到的结果。\n\n**截图**\n如果可以的话，请附上几张截图来帮助说明你遇到的问题。\n\n**额外上下文**\n附上与问题有关的其他上下文信息。\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug Report\nabout: Please follow this template if you are reporting a bug, or your issue may be closed without further notice.\ntitle: [Bug] Bug summary\nlabels: ''\nassignees: ''\n\n---\n\n> Make sure you go through the [Hexo docs](https://hexo.io), [Icarus user manual](https://ppoffice.github.io/hexo-theme-icarus/tags/Icarus-User-Guide/), and [GitHub issues](https://github.com/ppoffice/hexo-theme-icarus/issues) to see if the bug you are reporting has been already addressed by others.\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**System and Environment**\nThe version and configuration of Hexo and Icarus.\n\n- Hexo, OS, and node version (use `hexo version` command to view these information)\n- Site configuration file `_config.yml`\n- Theme configuration file `_config.icarus.yml` or `themes/icarus/_config.yml`\n- Any additional theme configuration files (post front-matter, `_config.post.yml`, or `_config.page.yml`)\n- Browser and version (e.g., Firefox 70.0, Chrome Android 80.0)\n\n**To Reproduce**\nSteps to reproduce the behavior, such as:\n\n1. Go to '...'\n2. Click on '...'\n3. Scroll down to '...'\n4. '...' error appears\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\ncontact_links:\n  - name: GitHub Discussions\n    url: https://github.com/ppoffice/hexo-theme-icarus/discussions\n    about: Redirect your Icarus usage questions to here.\n  - name: GitHub讨论组\n    url: https://github.com/ppoffice/hexo-theme-icarus/discussions\n    about: 与Icarus使用相关的问题请转至这里。\n  - name: Bug Report\n    url: https://github.com/ppoffice/hexo-theme-icarus/issues/new?template=bug_report.md\n    about: Please follow this template if you are reporting a bug, or your issue may be closed without further notice.\n  - name: Bug反馈\n    url: https://github.com/ppoffice/hexo-theme-icarus/issues/new?template=Bug反馈.md\n    about: 请按照模板填写Bug反馈，否则你的Issue可能会被直接关闭。\n  - name: Feature Request\n    url: https://github.com/ppoffice/hexo-theme-icarus/issues/new?template=feature_request.md\n    about: Please follow this template if you are requesting a new feature, or your issue may be closed without further notice.\n  - name: 功能建议\n    url: https://github.com/ppoffice/hexo-theme-icarus/issues/new?template=功能建议.md\n    about: 请按照模板填写功能建议，否则你的Issue可能会被直接关闭。\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature Request\nabout: Please follow this template if you are requesting a new feature, or your issue may be closed without further notice.\ntitle: [FEAT] Feature request summary\nlabels: ''\nassignees: ''\n\n---\n\n> Make sure you go through the [Hexo docs](https://hexo.io), [Icarus user manual](https://ppoffice.github.io/hexo-theme-icarus/tags/Icarus-User-Guide/), and [GitHub issues](https://github.com/ppoffice/hexo-theme-icarus/issues) to see if the feature you are requesting has been already addressed by others.\n\n**Is your feature request related to a problem? Please describe.**\n\nA clear and concise description of what the problem is (e.g., I'm always frustrated when [...]).\n\n**Describe the solution you'd like**\n\nA clear and concise description of what you want to happen.\n\n**Describe alternatives you've considered**\n\nA clear and concise description of any alternative solutions or features you've considered.\n\n**Additional context**\n\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/功能建议.md",
    "content": "---\nname: 功能建议\nabout: 请按照模板填写功能建议，否则你的Issue可能会被直接关闭。\ntitle: [FEAT] 功能建议概述\nlabels: ''\nassignees: ''\n\n---\n\n> 确保你在提交功能建议之前仔细阅读了[Hexo文档](https://hexo.io/zh-cn/)，[Icarus用户指南](https://ppoffice.github.io/hexo-theme-icarus/tags/Icarus%E7%94%A8%E6%88%B7%E6%8C%87%E5%8D%97/)，和[GitHub issues](https://github.com/ppoffice/hexo-theme-icarus/issues)来了解你的建议是否已经被他人提出过。\n\n**你的功能建议与某个使用问题相关么？请详述。**\n\n简洁清晰地描述你遇到的问题是什么（如：我在使用...的时候遇到了...）。\n\n**描述你想要的解决方案**\n\n简洁清晰地描述你想要的解决方案可以达到的效果。\n\n**描述你考虑过的替代办法**\n\n简洁清晰地描述你考虑过的替代解决方案或是新功能。\n\n**额外上下文**\n\n附上与功能请求有关的其他上下文信息或者截图。\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE/pull_request_template.md",
    "content": "---\nname: Pull Request\nabout: Suggest a code change to this project.\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Note 0**\nPlease review [the contributing guide](https://github.com/ppoffice/hexo-theme-icarus/blob/master/CONTRIBUTING.md) before making this pull request.\n\n**Note 1**\n\nPlease break up your pull request into multiple smaller requests if it contains multiple bug fixes \nor new features.\nEach pull request should have one bug fix or new feature only for better code maintainability.\n\n**Note 2**\n\nMany components of this theme, including core functions, some Hexo extensions, widgets and plugins, \nhave been moved to [ppoffice/hexo-component-inferno](https://github.com/ppoffice/hexo-component-inferno).\nPlease make a pull request to that repository instead of this one if your changes are related to\nthe above components.\n\n**Detailed description**\n\n> Please use the [Icarus issue template](https://github.com/ppoffice/hexo-theme-icarus/blob/master/.github/ISSUE_TEMPLATE/bug_report.md) if it is a bug fix.\n\n> Please use the [Icarus feature request template](https://github.com/ppoffice/hexo-theme-icarus/blob/master/.github/ISSUE_TEMPLATE/feature_request.md) if it is a bug fix.\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n  - package-ecosystem: 'npm'\n    directory: '/'\n    schedule:\n      interval: 'daily'\n"
  },
  {
    "path": ".github/stale.yml",
    "content": "# Number of days of inactivity before an issue becomes stale\ndaysUntilStale: 14\n# Number of days of inactivity before a stale issue is closed\ndaysUntilClose: 7\n# Issues with these labels will never be considered stale\nexemptLabels:\n  - bug:core\n  - bug:extension\n  - bug:general\n  - feature:core\n  - feature:extension\n  - feature:general\n  - tutorial:v1\n  - tutorial:v2\n  - tutorial:v3\n  - tutorial:v4\n  - tutorial:v5\n  - tutorial:v6\n  - tutorial:v7\n  - tutorial:v8\n  - tutorial:v9\n  - Gitalk\n  - utterances\n# Label to use when marking an issue as stale\nstaleLabel: wontfix\n# Comment to post when marking an issue as stale. Set to `false` to disable\nmarkComment: >\n  This issue has been automatically marked as stale because it has not had\n  recent activity. It will be closed if no further activity occurs. Thank you\n  for your contributions.\n# Comment to post when closing a stale issue. Set to `false` to disable\ncloseComment: false"
  },
  {
    "path": ".github/workflows/github-release.yml",
    "content": "name: GitHub Release\n\non:\n  push:\n    tags:\n      - '*'\n\njobs:\n  publish:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n    steps:\n      - uses: actions/checkout@v3\n      - uses: ncipollo/release-action@v1\n        with:\n          tag: ${{ github.ref }}\n          name: ${{ github.ref }}\n          draft: true\n          prerelease: false\n"
  },
  {
    "path": ".github/workflows/lint.yml",
    "content": "name: Code Linting\n\non: [push, pull_request]\n\njobs:\n  lint:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n      - uses: actions/setup-node@v3\n        with:\n          node-version: latest\n      - run: npm install\n      - run: npm run lint\n"
  },
  {
    "path": ".github/workflows/npm-publish.yml",
    "content": "name: Node.js Package\n\non:\n  release:\n    types: [published]\n\njobs:\n  publish:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n      - uses: actions/setup-node@v3\n        with:\n          node-version: 14\n          registry-url: https://registry.npmjs.org/\n      - run: npm publish\n        env:\n          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/test.yml",
    "content": "name: Test\n\non: [push, pull_request]\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        node-version: [14, latest]\n      fail-fast: false\n    steps:\n      - uses: actions/checkout@v3\n        with:\n          repository: hexojs/hexo-starter\n          ref: dcd18588de8f5c1bcc689c101e2f21726c11c4d6  # pin blog dependencies to support node.js 14\n      - uses: actions/checkout@v3\n        with:\n          path: themes/icarus\n      - uses: actions/checkout@v3\n        with:\n          repository: SukkaLab/hexo-many-posts\n          path: source/_posts/hexo-many-posts\n      - uses: actions/setup-node@v3\n        with:\n          node-version: ${{ matrix.node-version }}\n      - uses: actions/cache@v3\n        with:\n          path: node_modules\n          key: npm-cache\n          restore-keys: npm-cache\n      - run: npm install\n      - run: >\n          npm install $(node -e \"const deps=require('./themes/icarus/package.json').dependencies;\n          console.log(Object.keys(deps).map(key=>key+'@'+deps[key]).join(' '));\")\n      - run: npm install hexo-tag-embed\n      - run: npx hexo config theme icarus\n      - run: time NODE_ENV=production npx hexo g -b\n"
  },
  {
    "path": ".gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n# Diagnostic reports (https://nodejs.org/api/report.html)\nreport.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n*.lcov\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# TypeScript v1 declaration files\ntypings/\n\n# TypeScript cache\n*.tsbuildinfo\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Microbundle cache\n.rpt2_cache/\n.rts2_cache_cjs/\n.rts2_cache_es/\n.rts2_cache_umd/\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env\n.env.test\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n\n# Next.js build output\n.next\n\n# Nuxt.js build / generate output\n.nuxt\ndist\n\n# Gatsby files\n.cache/\n# Comment in the public line in if your project uses Gatsby and not Next.js\n# https://nextjs.org/blog/next-9-1#public-directory-support\n# public\n\n# vuepress build output\n.vuepress/dist\n\n# Serverless directories\n.serverless/\n\n# FuseBox cache\n.fusebox/\n\n# DynamoDB Local files\n.dynamodb/\n\n# TernJS port file\n.tern-port\n\n# Stores VSCode versions used for testing VSCode extensions\n.vscode-test\n\n_config*.yml*\nyarn.lock\n\n# Intellij Idea config file\n.idea\n*.ipr\n*.iws\n*.iml"
  },
  {
    "path": ".npmignore",
    "content": ".github/\n.eslintignore\n.eslintrc.json\n.travis.yml\nyarn.lock\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing Guidelines\n\n## Code styles\n\nPlease refer to the [.eslintrc.json](https://github.com/ppoffice/hexo-theme-icarus/blob/master/.eslintrc.json).\nYou can also use `npm run lint` or `yarn lint` to fix code style issues.\n\n## Project versioning\n\nWe use [SemVer](http://semver.org/) for versioning.\nAny changes to the code base should not be released using an existing version.\n\n## Commit message format\n\nThe commit message should follow the [Bluejava commit message format](https://github.com/bluejava/git-commit-guide).\nThe supported scopes are:\n\n- **core** for changes related to Hexo extensions and theme-specific functions\n- **comment** for comment plugin layout, schema, style, or script changes\n- **share** for share plugin layout, schema, style, or script changes\n- **donate** for donation plugin layout, schema, style, or script changes\n- **search** for search plugin layout, schema, style, or script changes\n- **widget** for widget layout, schema, style, or script changes\n- **plugin** for other plugin layout, schema, style, or script changes\n- **i18n** for adding or updating translations\n- **test** for testing or linting-related commits\n- **build** for build scripts, CI, other development or deployment related commits\n- use __\\*__ or leave empty to refer to commits that do not have a clear scope\n\n## Submit changes\n\n1. Fork this repository, make changes to it, and run it against some actual Hexo sites to see if \nanything is broken.\nYou should also run `npm run lint` or `yarn lint` to find and fix any code formatting issue.\n2. Submit a pull request to our repository. Please make sure you followed the instructions\nabove.\n3. We will review the pull request regularly and inform you of our questions and any changes \nthat need to be made before we can merge your pull request.\n4. We expect your response within two weeks, after which your pull request may be closed if\nno activity is shown.\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2020 PPOffice\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<p align=\"center\" class=\"mb-2\">\n<img class=\"not-gallery-item\" height=\"48\" src=\"https://ppoffice.github.io/hexo-theme-icarus/img/logo.svg\">\n<br> A simple, delicate, and modern theme for the static site generator Hexo.\n<br>\n<a href=\"https://ppoffice.github.io/hexo-theme-icarus/\">Preview</a> |\n<a href=\"https://ppoffice.github.io/hexo-theme-icarus/categories/\">Documentation</a> |\n<a href=\"https://github.com/ppoffice/hexo-theme-icarus/discussions\">Discuss on GitHub</a>\n<br>\n</p>\n\n![](https://ppoffice.github.io/hexo-theme-icarus/gallery/preview.png?1 \"Icarus Preview\")\n\n## :cd: Installation\n\n```shell\n$ npm install hexo-theme-icarus\n$ hexo config theme icarus\n```\n\nPlease refer to [Getting Started with Icarus](https://ppoffice.github.io/hexo-theme-icarus/uncategorized/getting-started-with-icarus/) \nfor more details.\n\n## :gift: Features\n\n### Cyberpunk Theme Variant\n\nTap into the future cyber world with the newly added Cyberpunk theme variant.\nInspired by [Cyberpunk 2077](https://www.cyberpunk.net).\n\n![Icarus Cyberpunk](https://ppoffice.github.io/hexo-theme-icarus/gallery/screenshots/cyberpunk.png \"Icarus Cyberpunk\")\n\n### Extensive Plugin Support\n\nIcarus includes plentiful search, comment, sharing and other plugins out of the box that makes your\nblog feature-rich and powerful.\n\n**[Comment](https://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/Comment/)**\n\nChangyan &middot; Disqus &middot; DisqusJS &middot; Facebook &middot; Gitalk &middot; Gitment &middot;\nIsso &middot; LiveRe &middot; Utterance &middot; Valine\n\n**[Donate Button](https://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/Donation/)**\n\nAfdian.net &middot; Alipay &middot; Buy me a coffee &middot; Patreon &middot; Paypal &middot; Wecat\n\n**[Search](https://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/Search/)**\n\nAlgolia &middot; Baidu &middot; Google CSE &middot; Insight\n\n**[Share](https://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/Share/)**\n\nAddThis &middot; AddToAny &middot; Baidu Share &middot; Share.js &middot; ShareThis\n\n**[Widgets](https://ppoffice.github.io/hexo-theme-icarus/categories/Widgets/)**\n\nGoogle Adsense &middot; Archives &middot; Categories &middot; External Site Links &middot; \nRecent Posts &middot; Google Feedburner &middot; Tags &middot; Table of Contents\n\n**[Analytics](https://ppoffice.github.io/hexo-theme-icarus/Plugins/Analytics/icarus-user-guide-web-analytics-plugins/)**\n\nBaidu Statistics &middot; Bing Webmaster &middot; BuSuanZi Web Counter &middot; CNZZ Statistics &middot;\nGoogle Analytics &middot; Hotjar &middot; StatCounter &middot; Twitter Conversion Tracking\n\n**[Other Plugins](https://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/)**\n\nCookie Consent &middot; LightGallery &middot; Justified Gallery &middot; KaTeX &middot; MathJax &middot;\nOudated Browser &middot; Page Loading Animations\n\n### Colorful Code Highlight\n\nIcarus directly import stylesheets from the [highlight.js](https://highlightjs.org/) package and makes more than\n90 code highlight themes available to you.\n\n<table>\n    <tr>\n        <th>Atom One Light</th>\n        <th>Monokai</th>\n        <th>Kimbie Dark</th>\n    </tr>\n    <tr>\n        <td><img width=\"266\" src=\"https://ppoffice.github.io/hexo-theme-icarus/gallery/code-highlight/atom-one-light.png?2\"></td>\n        <td><img width=\"266\" src=\"https://ppoffice.github.io/hexo-theme-icarus/gallery/code-highlight/monokai.png?2\"></td>\n        <td><img width=\"266\" src=\"https://ppoffice.github.io/hexo-theme-icarus/gallery/code-highlight/kimbie-dark.png?2\"></td>\n    </tr>\n</table>\n\n### Flexible Theme Configuration\n\nIcarus allows you to configure your site on a per-page or per-layout basis.\n\n<div>\n<table>\n    <tr>\n        <th>_config.yml</th>\n        <th>post.md</th>\n        <th>_config.page.yml</th>\n    </tr>\n    <tr>\n        <td>\n<pre>widgets:\n  - type: profile\n    position: left\n  - type: recent_posts\n    position: right</pre>\n        </td>\n        <td>\n<pre>widgets:\n  - type: profile\n    position: left\n  - type: recent_posts\n    position: left</pre>\n        </td>\n        <td>\n<pre>widgets: null\n \n \n \n</pre>\n        </td>\n    </tr>\n    <tr>\n        <td><img width=\"266\" src=\"https://ppoffice.github.io/hexo-theme-icarus/gallery/screenshots/default-config.png\"></td>\n        <td><img width=\"266\" src=\"https://ppoffice.github.io/hexo-theme-icarus/gallery/screenshots/post-config.png\"></td>\n        <td><img width=\"266\" src=\"https://ppoffice.github.io/hexo-theme-icarus/gallery/screenshots/layout-config.png\"></td>\n    </tr>\n</table>\n</div>\n\n### Responsive Layout\n\nGive your audiences best viewing experience with Icarus's mobile-friendly responsive layout.\n\n![Responsive Layout](https://ppoffice.github.io/hexo-theme-icarus/gallery/responsive.png)\n\n## :hammer: Development\n\nThis project is built with\n\n- [Hexo](https://hexo.io/)\n- [Inferno.js](https://infernojs.org/)\n- [Stylus](https://stylus-lang.com/)\n- [Bulma](https://bulma.io/)\n\nPlease refer to the [documentation](https://ppoffice.github.io/hexo-theme-icarus/categories/) and \n[contributing guide](https://github.com/ppoffice/hexo-theme-icarus/blob/master/CONTRIBUTING.md) for implementation details.\n\n## :tada: Contribute\n\nIf you feel like to help us build a better Icarus, you can\n\n:black_nib: [Submit a tutorial](https://github.com/ppoffice/hexo-theme-icarus/new/site/source/_posts) |\n:earth_asia: [Add a translation](https://github.com/ppoffice/hexo-theme-icarus/tree/master/languages) |\n:triangular_flag_on_post: [Report a bug](https://github.com/ppoffice/hexo-theme-icarus/issues) |\n:electric_plug: [Suggest a new feature](https://github.com/ppoffice/hexo-theme-icarus/pulls)\n\n## :memo: License\n\nThis project is licensed under the MIT License - see the [LICENSE](https://github.com/ppoffice/hexo-theme-icarus/blob/master/LICENSE) file for details.\n"
  },
  {
    "path": "include/config.js",
    "content": "/* eslint no-process-exit: \"off\" */\nconst fs = require('fs');\nconst path = require('path');\nconst util = require('util');\nconst crypto = require('crypto');\nconst createLogger = require('hexo-log');\nconst yaml = require('hexo-component-inferno/lib/util/yaml');\nconst { Migrator } = require('hexo-component-inferno/lib/core/migrate');\nconst { SchemaLoader } = require('hexo-component-inferno/lib/core/schema');\nconst { yellow } = require('./util/console');\n\nconst logger = createLogger.default();\n\nfunction loadThemeConfig(hexo, cfgPaths) {\n    const configs = cfgPaths.map(cfgPath => fs.readFileSync(cfgPath))\n        .map(cfgPath => yaml.parse(cfgPath));\n    return Object.assign({}, ...configs, hexo.config.theme_config);\n}\n\nfunction generateThemeConfigFile(schema, cfgPath) {\n    const defaultValue = schema.getDefaultValue();\n    fs.writeFileSync(cfgPath, defaultValue.toYaml());\n}\n\nfunction hashConfigFile(cfgPath) {\n    const content = fs.readFileSync(cfgPath);\n    return crypto.createHash('md5').update(content).digest('hex');\n}\n\nfunction checkConfig(hexo) {\n    if (!process.argv.includes('--icarus-dont-check-config')) {\n        logger.info('=== Checking theme configurations ===');\n\n        const siteCfgFile = path.join(hexo.base_dir, '_config.yml');\n        const themeSiteCfg = path.join(hexo.base_dir, '_config.icarus.yml');\n        const themeDirCfg = path.join(hexo.theme_dir, '_config.yml');\n        const themeCfgPaths = [themeDirCfg, themeSiteCfg].filter(cfgPath => fs.existsSync(cfgPath));\n        const themeSiteCfgExample = themeSiteCfg + '.example';\n\n        const schemaDir = path.join(hexo.theme_dir, 'include/schema/');\n        const loader = SchemaLoader.load(require(path.join(schemaDir, 'config.json')), schemaDir);\n        const schema = loader.getSchema('/config.json');\n\n        if (!process.argv.includes('--icarus-dont-generate-config')) {\n            if (!themeCfgPaths.length) {\n                logger.warn('None of the following configuration files is found:');\n                logger.warn(`- ${yellow(themeSiteCfg)}`);\n                logger.warn(`- ${yellow(themeDirCfg)}`);\n                logger.info('Generating theme configuration file...');\n                generateThemeConfigFile(schema, themeSiteCfg);\n                themeCfgPaths.push(themeSiteCfg);\n                logger.info(`${yellow(themeSiteCfg)} created successfully.`);\n                logger.info('To skip configuration generation, use \"--icarus-dont-generate-config\".');\n            }\n        }\n\n        let cfg = loadThemeConfig(hexo, themeCfgPaths);\n\n        if (!process.argv.includes('--icarus-dont-upgrade-config')) {\n            const migrator = new Migrator(require(path.join(hexo.theme_dir, 'include/migration/head')));\n            if (cfg.version && migrator.isOudated(cfg.version)) {\n                logger.warn(`Your theme configuration is outdated (${cfg.version} < ${migrator.getLatestVersion()}).`);\n                logger.info('To skip the configuration upgrade, use \"--icarus-dont-upgrade-config\".');\n\n                logger.info('Backing up theme configuration files...');\n                for (const cfgPath of themeCfgPaths) {\n                    const backupPath = cfgPath + '.' + hashConfigFile(cfgPath);\n                    const relCfgPath = path.relative(hexo.base_dir, cfgPath);\n                    const relBackupPath = path.relative(hexo.base_dir, backupPath);\n                    fs.renameSync(cfgPath, backupPath);\n                    logger.info(`${yellow(relCfgPath)} => ${yellow(relBackupPath)}`);\n                }\n\n                logger.info('Upgrading theme configurations...');\n                cfg = migrator.migrate(cfg);\n                fs.writeFileSync(themeSiteCfg, yaml.stringify(cfg));\n                logger.info(`Theme configurations are written to ${yellow(themeSiteCfg)}.`);\n\n                generateThemeConfigFile(schema, themeSiteCfgExample);\n                logger.info(`Example configurations is at ${yellow(themeSiteCfgExample)}.`);\n            }\n        }\n\n        const validation = schema.validate(cfg);\n        if (validation !== true) {\n            logger.warn('Theme configurations failed one or more checks.');\n            logger.warn('Icarus may still run, but you will encounter unexcepted results.');\n            logger.warn('Here is some information for you to correct the configuration file.');\n            logger.warn(util.inspect(validation));\n        }\n\n        const rootCfg = yaml.parse(fs.readFileSync(siteCfgFile));\n        if (rootCfg.theme_config) {\n            logger.warn(`\"theme_config\" found in ${yellow(siteCfgFile)}.`);\n            logger.warn(`Please remove theme configurations from ${yellow(siteCfgFile)}.`);\n        }\n    }\n}\n\nmodule.exports = hexo => {\n    try {\n        checkConfig(hexo);\n    } catch (e) {\n        logger.error(e);\n        logger.error('Theme configuration checking failed.');\n        logger.info('You may use \\'--icarus-dont-check-config\\' to skip configuration checking.');\n        process.exit(-1);\n    }\n};\n"
  },
  {
    "path": "include/dependency.js",
    "content": "/* eslint no-process-exit: \"off\" */\nconst semver = require('semver');\nconst createLogger = require('hexo-log');\nconst packageInfo = require('../package.json');\nconst { yellow, red, green } = require('./util/console');\n\nconst logger = createLogger.default();\n\nmodule.exports = hexo => {\n    function checkDependency(name, reqVer) {\n        try {\n            require.resolve(name);\n            const version = require(name + '/package.json').version;\n            if (!semver.satisfies(version, reqVer)) {\n                logger.error(`Package ${yellow(name)}'s version (${yellow(version)}) does not satisfy the required version (${red(reqVer)}).`);\n                return false;\n            }\n            return true;\n        } catch (e) {\n            logger.error(`Package ${yellow(name)} is not installed.`);\n        }\n        return false;\n    }\n\n    logger.info('=== Checking package dependencies ===');\n    const dependencies = Object.assign({}, packageInfo.dependencies);\n    const missingDeps = Object.keys(dependencies)\n        .filter(name => !checkDependency(name, dependencies[name]));\n    if (missingDeps && missingDeps.length) {\n        logger.error('Please install the missing dependencies your Hexo site root directory:');\n        logger.error(green('npm install --save ' + missingDeps.map(name => `${name}@${dependencies[name]}`).join(' ')));\n        logger.error('or:');\n        logger.error(green('yarn add ' + missingDeps.map(name => `${name}@${dependencies[name]}`).join(' ')));\n        process.exit(-1);\n    }\n};\n"
  },
  {
    "path": "include/migration/head.js",
    "content": "module.exports = require('./v5_v5.1');\n"
  },
  {
    "path": "include/migration/v2_v3.js",
    "content": "const createLogger = require('hexo-log');\nconst deepmerge = require('deepmerge');\nconst Migration = require('hexo-component-inferno/lib/core/migrate').Migration;\n\nconst logger = createLogger.default();\n\nmodule.exports = class extends Migration {\n    constructor() {\n        super('3.0.0', null);\n    }\n\n    upgrade(config) {\n        const result = deepmerge({}, config);\n        result.head = {\n            favicon: config.favicon || null,\n            canonical_url: config.canonical_url || null,\n            open_graph: config.open_graph || null,\n            meta: config.meta || null,\n            rss: config.rss || null\n        };\n        delete result.favicon;\n        delete result.canonical_url;\n        delete result.open_graph;\n        delete result.meta;\n        delete result.rss;\n\n        if (result.logo === '/images/logo.svg') {\n            result.logo = result.logo.replace(/^\\/images/, '/img');\n        }\n\n        if (result.head.favicon === '/img/favicon.svg') {\n            result.head.favicon = result.head.favicon.replace(/^\\/images/, '/img');\n        }\n\n        if (result.search && Object.prototype.hasOwnProperty.call(result.search, 'type')) {\n            switch (result.search.type) {\n                case 'google-cse':\n                    result.search.type = 'google_cse';\n                    break;\n            }\n        }\n\n        if (result.comment && Object.prototype.hasOwnProperty.call(result.comment, 'type')) {\n            switch (result.comment.type) {\n                case 'changyan':\n                    result.comment.app_id = config.comment.appid;\n                    delete result.comment.appid;\n                    break;\n            }\n        }\n\n        if (Array.isArray(result.donate) && result.donate.length) {\n            result.donates = result.donate;\n            delete result.donate;\n        }\n\n        if (Array.isArray(result.widgets) && result.widgets.length) {\n            for (const widget of result.widgets) {\n                if (Object.prototype.hasOwnProperty.call(widget, 'type')) {\n                    switch (widget.type) {\n                        case 'archive':\n                            widget.type = 'archives';\n                            break;\n                        case 'category':\n                            widget.type = 'categories';\n                            break;\n                        case 'tag':\n                            widget.type = 'tags';\n                            break;\n                        case 'tagcloud':\n                            logger.warn('The tagcloud widget has been removed from Icarus in version 3.0.0.');\n                            logger.warn('Please remove it from your configuration file.');\n                            break;\n                    }\n                }\n            }\n        }\n\n        if (result.plugins && typeof result.plugins === 'object') {\n            for (const name in result.plugins) {\n                switch (name) {\n                    case 'outdated-browser':\n                        result.plugins.outdated_browser = result.plugins[name];\n                        delete result.plugins[name];\n                        break;\n                    case 'back-to-top':\n                        result.plugins.back_to_top = result.plugins[name];\n                        delete result.plugins[name];\n                        break;\n                    case 'baidu-analytics':\n                        result.plugins.baidu_analytics = result.plugins[name];\n                        delete result.plugins[name];\n                        break;\n                    case 'google-analytics':\n                        result.plugins.google_analytics = result.plugins[name];\n                        delete result.plugins[name];\n                        break;\n                }\n            }\n        }\n\n        return result;\n    }\n};\n"
  },
  {
    "path": "include/migration/v3_v4.js",
    "content": "const Migration = require('hexo-component-inferno/lib/core/migrate').Migration;\n\nmodule.exports = class extends Migration {\n    constructor() {\n        super('4.0.0', null);\n    }\n\n    upgrade(config) {\n        if (typeof config.article === 'object') {\n            delete config.article.thumbnail;\n        }\n        return config;\n    }\n};\n"
  },
  {
    "path": "include/migration/v4_v5.js",
    "content": "const Migration = require('hexo-component-inferno/lib/core/migrate').Migration;\n\nmodule.exports = class extends Migration {\n    constructor() {\n        super('5.0.0', null);\n    }\n\n    upgrade(config) {\n        return config;\n    }\n};\n"
  },
  {
    "path": "include/migration/v5_v5.1.js",
    "content": "const Migration = require('hexo-component-inferno/lib/core/migrate').Migration;\n\nmodule.exports = class extends Migration {\n    constructor() {\n        super('5.1.0', null);\n    }\n\n    upgrade(config) {\n        // Upgrade Waline configurations from v1 to v2.\n        const comment = config.comment || {};\n        const renamedOptions = {\n            'visitor': 'pageview',\n            'uploadImage': 'image_uploader',\n            'highlight': 'highlighter',\n            'math': 'tex_renderer'\n        };\n        if (comment.type === 'waline') {\n            for (const option in renamedOptions) {\n                if (typeof comment[option] !== 'undefined') {\n                    if (typeof comment[renamedOptions[option]] === 'undefined') {\n                        comment[renamedOptions[option]] = comment[option];\n                    }\n                    delete comment[option];\n                }\n            }\n        }\n        return config;\n    }\n};\n"
  },
  {
    "path": "include/register.js",
    "content": "const createLogger = require('hexo-log');\n\nconst logger = createLogger.default();\n\nmodule.exports = hexo => {\n    logger.info('=== Registering Hexo extensions ===');\n    require('hexo-component-inferno/lib/hexo/filter/locals')(hexo);\n    require('hexo-component-inferno/lib/hexo/generator/assets')(hexo);\n    require('hexo-component-inferno/lib/hexo/generator/insight')(hexo);\n    require('hexo-component-inferno/lib/hexo/generator/categories')(hexo);\n    require('hexo-component-inferno/lib/hexo/generator/category')(hexo);\n    require('hexo-component-inferno/lib/hexo/generator/manifest')(hexo);\n    require('hexo-component-inferno/lib/hexo/generator/tags')(hexo);\n    require('hexo-component-inferno/lib/hexo/helper/cdn')(hexo);\n    require('hexo-component-inferno/lib/hexo/helper/page')(hexo);\n    require('hexo-component-inferno/lib/hexo/tag/message')(hexo);\n    require('hexo-component-inferno/lib/hexo/tag/tabs')(hexo);\n    require('hexo-component-inferno/lib/core/view').init(hexo);\n};\n"
  },
  {
    "path": "include/schema/comment/.gitkeep",
    "content": ""
  },
  {
    "path": "include/schema/common/article.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n    \"$id\": \"/common/article.json\",\n    \"description\": \"Article related configurations\",\n    \"type\": \"object\",\n    \"properties\": {\n        \"highlight\": {\n            \"type\": \"object\",\n            \"description\": \"Code highlight settings\",\n            \"properties\": {\n                \"theme\": {\n                    \"type\": \"string\",\n                    \"description\": \"Code highlight themes\\nhttps://github.com/highlightjs/highlight.js/tree/master/src/styles\",\n                    \"default\": \"atom-one-light\",\n                    \"nullable\": true\n                },\n                \"clipboard\": {\n                    \"type\": \"boolean\",\n                    \"description\": \"Show copy code button\",\n                    \"default\": true,\n                    \"nullable\": true\n                },\n                \"fold\": {\n                    \"type\": \"string\",\n                    \"description\": \"Default folding status of the code blocks. Can be \\\"\\\", \\\"folded\\\", \\\"unfolded\\\"\",\n                    \"enum\": [\n                        \"\",\n                        \"folded\",\n                        \"unfolded\"\n                    ],\n                    \"default\": \"unfolded\",\n                    \"nullable\": true\n                }\n            },\n            \"nullable\": true\n        },\n        \"readtime\": {\n            \"type\": \"boolean\",\n            \"description\": \"Whether to show estimated article reading time\",\n            \"default\": true,\n            \"nullable\": true\n        },\n        \"update_time\": {\n            \"type\": [\"boolean\", \"string\"],\n            \"description\": \"Whether to show updated time. For \\\"auto\\\", shows article update time only when page.updated is set and it is different from page.date\",\n            \"default\": true,\n            \"enum\": [true, false, \"auto\"],\n            \"nullable\": true\n        },\n        \"licenses\": {\n            \"$ref\": \"/misc/poly_links.json\",\n            \"description\": \"Article licensing block\",\n            \"examples\": [\n                {\n                    \"Creative Commons\": {\n                      \"icon\": \"fab fa-creative-commons\",\n                      \"url\": \"https://creativecommons.org/\"\n                    },\n                    \"Attribution\": {\n                      \"icon\": \"fab fa-creative-commons-by\",\n                      \"url\": \"https://creativecommons.org/licenses/by/4.0/\"\n                    },\n                    \"Noncommercial\": {\n                      \"icon\": \"fab fa-creative-commons-nc\",\n                      \"url\": \"https://creativecommons.org/licenses/by-nc/4.0/\"\n                    }\n                }\n            ]\n        }\n    }\n}"
  },
  {
    "path": "include/schema/common/comment.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n    \"$id\": \"/common/comment.json\",\n    \"description\": \"Comment plugin configurations\\nhttps://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/Comment/\",\n    \"type\": \"object\",\n    \"oneOf\": [\n        {\n            \"$ref\": \"/comment/disqus.json\"\n        },\n        {\n            \"$ref\": \"/comment/changyan.json\"\n        },\n        {\n            \"$ref\": \"/comment/disqusjs.json\"\n        },\n        {\n            \"$ref\": \"/comment/facebook.json\"\n        },\n        {\n            \"$ref\": \"/comment/giscus.json\"\n        },\n        {\n            \"$ref\": \"/comment/gitalk.json\"\n        },\n        {\n            \"$ref\": \"/comment/gitment.json\"\n        },\n        {\n            \"$ref\": \"/comment/isso.json\"\n        },\n        {\n            \"$ref\": \"/comment/livere.json\"\n        },\n        {\n            \"$ref\": \"/comment/utterances.json\"\n        },\n        {\n            \"$ref\": \"/comment/valine.json\"\n        },\n        {\n            \"$ref\": \"/comment/waline.json\"\n        },\n        {\n            \"$ref\": \"/comment/twikoo.json\"\n        }\n    ]\n}\n"
  },
  {
    "path": "include/schema/common/donates.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n    \"$id\": \"/common/donates.json\",\n    \"description\": \"Donate plugin configurations\\nhttps://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/Donation/\",\n    \"type\": \"array\",\n    \"items\": {\n        \"type\": \"object\",\n        \"oneOf\": [\n            {\n                \"$ref\": \"/donate/afdian.json\"\n            },\n            {\n                \"$ref\": \"/donate/alipay.json\"\n            },\n            {\n                \"$ref\": \"/donate/buymeacoffee.json\"\n            },\n            {\n                \"$ref\": \"/donate/patreon.json\"\n            },\n            {\n                \"$ref\": \"/donate/paypal.json\"\n            },\n            {\n                \"$ref\": \"/donate/wechat.json\"\n            }\n        ]\n    }\n}"
  },
  {
    "path": "include/schema/common/footer.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n    \"$id\": \"/common/footer.json\",\n    \"description\": \"Page footer configurations\",\n    \"type\": \"object\",\n    \"properties\": {\n        \"copyright\": {\n            \"description\": \"Copyright text\",\n            \"type\": \"string\",\n            \"examples\": [\n                \"© 2019\",\n                \"© 2019 - 2020\",\n                \"© 2019 - 2020, Company Name\",\n                \"© 2019 - 2020, Company Name. All rights reserved.\",\n                \"粤ICP备12345678号\"\n            ]\n        },\n        \"links\": {\n            \"$ref\": \"/misc/poly_links.json\",\n            \"description\": \"Links to be shown on the right of the footer section\",\n            \"examples\": [\n                {\n                    \"Creative Commons\": {\n                        \"icon\": \"fab fa-creative-commons\",\n                        \"url\": \"https://creativecommons.org/\"\n                    },\n                    \"Attribution 4.0 International\": {\n                        \"icon\": \"fab fa-creative-commons-by\",\n                        \"url\": \"https://creativecommons.org/licenses/by/4.0/\"\n                    },\n                    \"Download on GitHub\": {\n                        \"icon\": \"fab fa-github\",\n                        \"url\": \"https://github.com/ppoffice/hexo-theme-icarus\"\n                    }\n                }\n            ]\n        }\n    }\n}"
  },
  {
    "path": "include/schema/common/head.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n    \"$id\": \"/common/head.json\",\n    \"description\": \"Page metadata configurations\",\n    \"type\": \"object\",\n    \"properties\": {\n        \"favicon\": {\n            \"type\": \"string\",\n            \"description\": \"URL or path to the website's icon\",\n            \"default\": \"/img/favicon.svg\",\n            \"nullable\": true\n        },\n        \"manifest\": {\n            \"$ref\": \"/misc/manifest.json\"\n        },\n        \"open_graph\": {\n            \"$ref\": \"/misc/open_graph.json\"\n        },\n        \"structured_data\": {\n            \"$ref\": \"/misc/structured_data.json\"\n        },\n        \"meta\": {\n            \"$ref\": \"/misc/meta.json\"\n        },\n        \"rss\": {\n            \"type\": \"string\",\n            \"description\": \"URL or path to the website's RSS atom.xml\",\n            \"nullable\": true\n        }\n    }\n}"
  },
  {
    "path": "include/schema/common/navbar.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n    \"$id\": \"/common/navbar.json\",\n    \"description\": \"Page top navigation bar configurations\",\n    \"type\": \"object\",\n    \"properties\": {\n        \"menu\": {\n            \"type\": \"object\",\n            \"description\": \"Navigation menu items\",\n            \"patternProperties\": {\n                \".+\": {\n                    \"type\": \"string\",\n                    \"description\": \"URL or path of the menu link\"\n                }\n            },\n            \"examples\": [\n                {\n                    \"Home\": \"/\",\n                    \"Archives\": \"/archives\",\n                    \"Categories\": \"/categories\",\n                    \"Tags\": \"/tags\",\n                    \"About\": \"/about\"\n                }\n            ],\n            \"nullable\": true\n        },\n        \"links\": {\n            \"$ref\": \"/misc/poly_links.json\",\n            \"description\": \"Links to be shown on the right of the navigation bar\",\n            \"examples\": [\n                {\n                    \"Download on GitHub\": {\n                        \"icon\": \"fab fa-github\",\n                        \"url\": \"https://github.com/ppoffice/hexo-theme-icarus\"\n                    }\n                }\n            ]\n        }\n    }\n}"
  },
  {
    "path": "include/schema/common/plugins.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n    \"$id\": \"/common/plugins.json\",\n    \"description\": \"Plugin configurations\\nhttps://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/\",\n    \"type\": \"object\",\n    \"properties\": {\n        \"animejs\": {\n            \"$ref\": \"/plugin/animejs.json\"\n        },\n        \"back_to_top\": {\n            \"$ref\": \"/plugin/back_to_top.json\"\n        },\n        \"baidu_analytics\": {\n            \"$ref\": \"/plugin/baidu_analytics.json\"\n        },\n        \"bing_webmaster\": {\n            \"$ref\": \"/plugin/bing_webmaster.json\"\n        },\n        \"busuanzi\": {\n            \"$ref\": \"/plugin/busuanzi.json\"\n        },\n        \"cnzz\": {\n            \"$ref\": \"/plugin/cnzz.json\"\n        },\n        \"cookie_consent\": {\n            \"$ref\": \"/plugin/cookie_consent.json\"\n        },\n        \"gallery\": {\n            \"$ref\": \"/plugin/gallery.json\"\n        },\n        \"google_analytics\": {\n            \"$ref\": \"/plugin/google_analytics.json\"\n        },\n        \"hotjar\": {\n            \"$ref\": \"/plugin/hotjar.json\"\n        },\n        \"katex\": {\n            \"$ref\": \"/plugin/katex.json\"\n        },\n        \"mathjax\": {\n            \"$ref\": \"/plugin/mathjax.json\"\n        },\n        \"outdated_browser\": {\n            \"$ref\": \"/plugin/outdated_browser.json\"\n        },\n        \"pjax\": {\n            \"$ref\": \"/plugin/pjax.json\"\n        },\n        \"progressbar\": {\n            \"$ref\": \"/plugin/progressbar.json\"\n        },\n        \"statcounter\": {\n            \"$ref\": \"/plugin/statcounter.json\"\n        },\n        \"twitter_conversion_tracking\": {\n            \"$ref\": \"/plugin/twitter_conversion_tracking.json\"\n        }\n    }\n}"
  },
  {
    "path": "include/schema/common/providers.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n    \"$id\": \"/common/providers.json\",\n    \"description\": \"CDN provider settings\\nhttps://ppoffice.github.io/hexo-theme-icarus/Configuration/Theme/speed-up-your-site-with-custom-cdn/\",\n    \"type\": \"object\",\n    \"properties\": {\n        \"cdn\": {\n            \"type\": \"string\",\n            \"description\": \"Name or URL template of the JavaScript and/or stylesheet CDN provider\",\n            \"default\": \"jsdelivr\",\n            \"nullable\": true\n        },\n        \"fontcdn\": {\n            \"type\": \"string\",\n            \"description\": \"Name or URL template of the webfont CDN provider\",\n            \"default\": \"google\",\n            \"nullable\": true\n        },\n        \"iconcdn\": {\n            \"type\": \"string\",\n            \"description\": \"Name or URL of the fontawesome icon font CDN provider\",\n            \"default\": \"fontawesome\",\n            \"nullable\": true\n        }\n    }\n}"
  },
  {
    "path": "include/schema/common/search.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n    \"$id\": \"/common/search.json\",\n    \"description\": \"Search plugin configurations\\nhttps://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/Search/\",\n    \"type\": \"object\",\n    \"oneOf\": [\n        {\n            \"$ref\": \"/search/insight.json\"\n        },\n        {\n            \"$ref\": \"/search/baidu.json\"\n        },\n        {\n            \"$ref\": \"/search/google_cse.json\"\n        },\n        {\n            \"$ref\": \"/search/algolia.json\"\n        }\n    ]\n}"
  },
  {
    "path": "include/schema/common/share.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n    \"$id\": \"/common/share.json\",\n    \"description\": \"Share plugin configurations\\nhttps://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/Share/\",\n    \"type\": \"object\",\n    \"oneOf\": [\n        {\n            \"$ref\": \"/share/sharethis.json\"\n        },\n        {\n            \"$ref\": \"/share/addthis.json\"\n        },\n        {\n            \"$ref\": \"/share/addtoany.json\"\n        },\n        {\n            \"$ref\": \"/share/bdshare.json\"\n        },\n        {\n            \"$ref\": \"/share/sharejs.json\"\n        }\n    ]\n}"
  },
  {
    "path": "include/schema/common/sidebar.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n    \"$id\": \"/common/sidebar.json\",\n    \"description\": \"Sidebar configurations.\\nPlease be noted that a sidebar is only visible when it has at least one widget\",\n    \"type\": \"object\",\n    \"properties\": {\n        \"left\": {\n            \"type\": \"object\",\n            \"description\": \"Left sidebar configurations\",\n            \"properties\": {\n                \"sticky\": {\n                    \"type\": \"boolean\",\n                    \"description\": \"Whether the sidebar sticks to the top when page scrolls\",\n                    \"default\": false\n                }\n            }\n        },\n        \"right\": {\n            \"type\": \"object\",\n            \"description\": \"Right sidebar configurations\",\n            \"properties\": {\n                \"sticky\": {\n                    \"type\": \"boolean\",\n                    \"description\": \"Whether the sidebar sticks to the top when page scrolls\",\n                    \"default\": false\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "include/schema/common/widgets.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n    \"$id\": \"/common/widgets.json\",\n    \"description\": \"Sidebar widget configurations\\nhttp://ppoffice.github.io/hexo-theme-icarus/categories/Widgets/\",\n    \"type\": \"array\",\n    \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n            \"position\": {\n                \"type\": \"string\",\n                \"description\": \"Where should the widget be placed, left sidebar or right sidebar\",\n                \"default\": \"left\"\n            }\n        },\n        \"oneOf\": [\n            {\n                \"$ref\": \"/widget/profile.json\"\n            },\n            {\n                \"$ref\": \"/widget/toc.json\"\n            },\n            {\n                \"$ref\": \"/widget/links.json\"\n            },\n            {\n                \"$ref\": \"/widget/categories.json\"\n            },\n            {\n                \"$ref\": \"/widget/recent_posts.json\"\n            },\n            {\n                \"$ref\": \"/widget/archives.json\"\n            },\n            {\n                \"$ref\": \"/widget/tags.json\"\n            },\n            {\n                \"$ref\": \"/widget/subscribe_email.json\"\n            },\n            {\n                \"$ref\": \"/widget/adsense.json\"\n            },\n            {\n                \"$ref\": \"/widget/followit.json\"\n            }\n        ],\n        \"required\": [\n            \"position\"\n        ]\n    }\n}"
  },
  {
    "path": "include/schema/config.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n    \"$id\": \"/config.json\",\n    \"description\": \"The configuration file definition\",\n    \"type\": \"object\",\n    \"properties\": {\n        \"version\": {\n            \"type\": \"string\",\n            \"description\": \"Version of the configuration file\",\n            \"default\": \"5.1.0\"\n        },\n        \"variant\": {\n            \"type\": \"string\",\n            \"description\": \"Icarus theme variant, can be \\\"default\\\" or \\\"cyberpunk\\\"\",\n            \"enum\": [\n                \"default\",\n                \"cyberpunk\"\n            ],\n            \"default\": \"default\"\n        },\n        \"logo\": {\n            \"type\": [\n                \"string\",\n                \"object\"\n            ],\n            \"description\": \"Path or URL to the website's logo\",\n            \"default\": \"/img/logo.svg\",\n            \"properties\": {\n                \"text\": {\n                    \"type\": \"string\",\n                    \"description\": \"Text to be shown in place of the logo image\"\n                }\n            },\n            \"required\": [\n                \"text\"\n            ]\n        },\n        \"head\": {\n            \"$ref\": \"/common/head.json\"\n        },\n        \"navbar\": {\n            \"$ref\": \"/common/navbar.json\"\n        },\n        \"footer\": {\n            \"$ref\": \"/common/footer.json\"\n        },\n        \"article\": {\n            \"$ref\": \"/common/article.json\"\n        },\n        \"search\": {\n            \"$ref\": \"/common/search.json\"\n        },\n        \"comment\": {\n            \"$ref\": \"/common/comment.json\"\n        },\n        \"donates\": {\n            \"$ref\": \"/common/donates.json\"\n        },\n        \"share\": {\n            \"$ref\": \"/common/share.json\"\n        },\n        \"sidebar\": {\n            \"$ref\": \"/common/sidebar.json\"\n        },\n        \"widgets\": {\n            \"$ref\": \"/common/widgets.json\"\n        },\n        \"plugins\": {\n            \"$ref\": \"/common/plugins.json\"\n        },\n        \"providers\": {\n            \"$ref\": \"/common/providers.json\"\n        }\n    },\n    \"required\": [\n        \"version\"\n    ]\n}"
  },
  {
    "path": "include/schema/donate/.gitkeep",
    "content": ""
  },
  {
    "path": "include/schema/misc/.gitkeep",
    "content": ""
  },
  {
    "path": "include/schema/plugin/animejs.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n    \"$id\": \"/plugin/animejs.json\",\n    \"description\": \"Enable page startup animations\",\n    \"type\": \"boolean\",\n    \"default\": true\n}"
  },
  {
    "path": "include/schema/plugin/back_to_top.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n    \"$id\": \"/plugin/back_to_top.json\",\n    \"description\": \"Show the \\\"back to top\\\" button\",\n    \"type\": \"boolean\",\n    \"default\": true\n}"
  },
  {
    "path": "include/schema/plugin/pjax.json",
    "content": "{\r\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n    \"$id\": \"/plugin/pjax.json\",\r\n    \"description\": \"Enable PJAX\",\r\n    \"type\": \"boolean\",\r\n    \"default\": true\r\n}"
  },
  {
    "path": "include/schema/search/.gitkeep",
    "content": ""
  },
  {
    "path": "include/schema/share/.gitkeep",
    "content": ""
  },
  {
    "path": "include/schema/widget/profile.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n    \"$id\": \"/widget/profile.json\",\n    \"description\": \"Profile widget configurations\",\n    \"type\": \"object\",\n    \"properties\": {\n        \"type\": {\n            \"type\": \"string\",\n            \"const\": \"profile\",\n            \"nullable\": true\n        },\n        \"author\": {\n            \"type\": \"string\",\n            \"description\": \"Author name\",\n            \"examples\": [\n                \"Your name\"\n            ],\n            \"nullable\": true\n        },\n        \"author_title\": {\n            \"type\": \"string\",\n            \"description\": \"Author title\",\n            \"examples\": [\n                \"Your title\"\n            ],\n            \"nullable\": true\n        },\n        \"location\": {\n            \"type\": \"string\",\n            \"description\": \"Author's current location\",\n            \"examples\": [\n                \"Your location\"\n            ],\n            \"nullable\": true\n        },\n        \"avatar\": {\n            \"type\": \"string\",\n            \"description\": \"URL or path to the avatar image\",\n            \"nullable\": true\n        },\n        \"avatar_rounded\": {\n            \"type\": \"boolean\",\n            \"description\": \"Whether show the rounded avatar image\",\n            \"default\": false,\n            \"nullable\": true\n        },\n        \"gravatar\": {\n            \"type\": \"string\",\n            \"description\": \"Email address for the Gravatar\",\n            \"nullable\": true\n        },\n        \"follow_link\": {\n            \"type\": \"string\",\n            \"description\": \"URL or path for the follow button\",\n            \"examples\": [\n                \"https://github.com/ppoffice\"\n            ],\n            \"nullable\": true\n        },\n        \"social_links\": {\n            \"$ref\": \"/misc/poly_links.json\",\n            \"description\": \"Links to be shown on the bottom of the profile widget\",\n            \"examples\": [\n                {\n                    \"Github\": {\n                        \"icon\": \"fab fa-github\",\n                        \"url\": \"https://github.com/ppoffice\"\n                    },\n                    \"Facebook\": {\n                        \"icon\": \"fab fa-facebook\",\n                        \"url\": \"https://facebook.com\"\n                    },\n                    \"Twitter\": {\n                        \"icon\": \"fab fa-twitter\",\n                        \"url\": \"https://twitter.com\"\n                    },\n                    \"Dribbble\": {\n                        \"icon\": \"fab fa-dribbble\",\n                        \"url\": \"https://dribbble.com\"\n                    },\n                    \"RSS\": {\n                        \"icon\": \"fas fa-rss\",\n                        \"url\": \"/\"\n                    }\n                }\n            ]\n        }\n    },\n    \"required\": [\n        \"type\"\n    ]\n}"
  },
  {
    "path": "include/style/article.styl",
    "content": "/* ---------------------------------\n *    Article Summary and Content\n * --------------------------------- */\n$article-font-size ?= 1.1rem\n\narticle\n    &.media\n        color: $text-light\n\n        a\n            color: inherit\n\n            &:hover\n                color: $primary\n\n        .image\n            width: 64px\n            height: 64px\n\n            img\n                object-fit: cover\n                width: 100%\n                height: 100%\n\n        .title\n            @extend .is-size-6\n            margin-bottom: .25em\n\n        .date, .categories\n            @extend .is-size-7\n\n        .categories\n            @extend .is-uppercase\n\n        .media-content\n            color: $text-light\n\n            .title\n                margin: 0\n                line-height: inherit\n\n    &.article\n        .article-meta, .article-tags\n            color: $text-light\n\n        .article-meta\n            overflow-x: auto\n            margin-bottom: .5rem\n\n        .article-more\n            @extend .button.is-light\n\n        .content\n            word-wrap: break-word\n            font-size: $article-font-size\n\n            h1\n                font-size: 1.75em\n\n            h2\n                font-size: 1.5em\n\n            h3\n                font-size: 1.25em\n\n            h4\n                font-size: 1.125em\n\n            h5\n                font-size: 1em\n\n            pre\n                font-size: .85em\n\n            code\n                padding: 0\n                background: transparent\n                overflow-wrap: break-word\n\n            blockquote\n                &.pullquote\n                    float: right\n                    max-width: 50%\n                    font-size: 1.15rem\n                    position: relative\n\n                footer\n                    strong + cite\n                        margin-left: .5em\n\n            .message.message-immersive\n                border-radius: 0\n                margin: 0 0 - $card-content-padding $card-content-padding 0 - $card-content-padding\n\n                .message-body\n                    border: none\n        \n        .article-tags\n            display: flex\n            flex-wrap: wrap\n\n.rtl\n    direction: rtl\n\n    .level\n        &, &.is-mobile\n            .level-item:not(:last-child)\n                margin-left: .75rem\n                margin-right: 0\n\n// Overflow table\n.table-overflow\n    overflow-x: auto\n\n    table\n        width: auto !important\n\n        th\n            word-break: keep-all\n\n// Video container\n.video-container\n    position: relative\n    padding-bottom: 56.25%\n    padding-top: 25px\n    height: 0\n\n    iframe\n        position: absolute\n        top: 0\n        left: 0\n        width: 100%\n        height: 100%\n\n.article-licensing\n    position: relative\n    z-index: 1\n    box-shadow: none\n    background: $white-ter\n    border-radius: $radius\n    overflow: hidden\n\n    &:after\n        position: absolute\n        z-index: -1\n        right: -50px\n        top: -87.87px\n        content: '\\f25e'\n        font-size: 200px\n        font-family: 'Font Awesome 5 Brands'\n        opacity: .1\n\n    .level-left\n        flex-wrap: wrap\n        max-width: 100%\n\n    .licensing-title\n        @extend .mb-3\n        line-height: 1.2\n\n        p:not(:last-child)\n            @extend .mb-1\n\n        a\n            @extend .is-size-7, .has-text-grey\n\n    .licensing-meta\n        .level-item\n            @extend .mr-4\n\n        .icons\n            .icon\n                @extend .ml-1\n                width: 1.2em\n                height: 1.2em\n                font-size: 1.2em\n                vertical-align: bottom\n\n        h6\n            @extend .is-size-7\n\n        a\n            color: inherit\n\na\n    &.article-nav-prev\n        span\n            text-align: left\n            flex-shrink: 1\n            word-wrap: break-word\n            white-space: normal\n\n    &.article-nav-next\n        span\n            text-align: right\n            flex-shrink: 1\n            word-wrap: break-word\n            white-space: normal"
  },
  {
    "path": "include/style/base.styl",
    "content": "bulma-stylus-root = '../../../../node_modules/bulma-stylus/stylus'\n\n/* ---------------------------------\n *   Override Bulma CSS Framework\n * --------------------------------- */\n$body-size ?= 14px\n$body-background-color ?= #f7f7f7\n\n$family-sans-serif ?= Ubuntu, Roboto, 'Open Sans', 'Microsoft YaHei', sans-serif\n$family-code ?= 'Source Code Pro', monospace, 'Microsoft YaHei'\n\n$size-7 ?= .85rem\n$size-small ?= .75rem\n\n$primary ?= $blue\n$custom-colors ?= {\n    grey-lightest: {\n        '1': $grey-lightest\n        '2': $grey-darker\n    }\n}\n\n$navbar-item-active-color ?= $primary\n$footer-background-color ?= $scheme-main\n\n$gap ?= 64px\n$tablet ?= 769px\n$desktop ?= 1088px\n$widescreen ?= 1280px\n$fullhd ?= 1472px\n\n$shadow ?= 0 4px 10px rgba(0, 0, 0, 0.05)\n\n$title-weight ?= $weight-normal\n\n$control-height ?= 2.25em\n$button-padding-vertical ?= calc(0.375em - 1px)\n\n$card-radius ?= $radius\n$card-media-margin ?= 0.75rem\n$card-shadow ?= $shadow, 0 0 1px rgba(0, 0, 0, 0.1)\n\n$menu-item-active-color ?= $link\n$menu-item-active-background-color ?= hsl(219, 70%, 96%)\n\n$content-heading-weight ?= $weight-normal\n\n\n$logo-height ?= 1.75rem\n\n// FIXME: https://github.com/groenroos/bulma-stylus/issues/11\n@import bulma-stylus-root + '/utilities/initial-variables'\n@import bulma-stylus-root + '/utilities/functions'\n@import bulma-stylus-root + '/utilities/derived-variables'\n\n$colors = merge($colors, $custom-colors)\n\n@import bulma-stylus-root + '/utilities/animations'\n@import bulma-stylus-root + '/utilities/mixins'\n@import bulma-stylus-root + '/utilities/controls'\n@import bulma-stylus-root + '/base/_all'\n@import bulma-stylus-root + '/components/_all'\n@import bulma-stylus-root + '/elements/_all'\n@import bulma-stylus-root + '/form/_all'\n@import bulma-stylus-root + '/grid/_all'\n@import bulma-stylus-root + '/layout/_all'\n\nhtml\n    height: 100%\n    -webkit-text-size-adjust: 100%\n    -moz-text-size-adjust: 100%\n    -ms-text-size-adjust: 100%\n    text-size-adjust: 100%\n\nbody\n    min-height: 100%\n    display: flex\n    flex-direction: column\n\nbody > .section\n    flex-grow: 1\n\n+desktop()\n    ::-webkit-scrollbar\n        width: 8px\n        height: 8px\n\n    ::-webkit-scrollbar-track\n        border-radius: 3px\n        background: rgba(0,0,0,0.06)\n        box-shadow: inset 0 0 5px rgba(0,0,0,0.1)\n\n    ::-webkit-scrollbar-thumb\n        border-radius: 3px\n        background: rgba(0,0,0,0.12)\n        box-shadow: inset 0 0 10px rgba(0,0,0,0.2)\n\n    ::-webkit-scrollbar-thumb:hover\n        background: rgba(0,0,0,0.24)\n"
  },
  {
    "path": "include/style/button.styl",
    "content": "/* ---------------------------------\n *            Buttons\n * --------------------------------- */\n.button\n    &.is-transparent\n        color: inherit\n        background: transparent\n        border-color: transparent\n"
  },
  {
    "path": "include/style/card.styl",
    "content": "/* ---------------------------------\n *              Card\n * --------------------------------- */\n.card\n    overflow: visible\n    border-radius: $card-radius\n\n    & + .card, & + .column-right-shadow\n        margin-top: 1.5rem\n\n    .card-image\n        overflow: hidden\n        border-top-left-radius: $card-radius\n        border-top-right-radius: $card-radius\n\n    .media + .media\n        border: none\n        margin-top: 0\n"
  },
  {
    "path": "include/style/codeblock.styl",
    "content": "/* ---------------------------------\n *          Code Highlight\n * --------------------------------- */\n$codeblock-caption-bg ?= rgba(200, 200, 200, .15)\n\nfigure.highlight\n    padding: 0\n    width: 100%\n    position: relative\n    margin: 1em 0 1em !important\n    border-radius: $radius\n\n    &.folded\n        .highlight-body\n            height: 0\n\n    .copy\n        opacity: .7\n\n    pre, table tr:hover\n        color: inherit\n        background: transparent\n\n    table\n        width: auto\n\n        tr td\n            border: none\n\n        tr:not(:first-child) td\n            padding-top: 0\n\n        tr:not(:last-child) td\n            padding-bottom: 0\n\n    pre\n        padding: 0\n        overflow: visible\n\n        .line, code .hljs\n            line-height: 1.5rem\n\n    figcaption, .gutter\n        background: $codeblock-caption-bg\n\n    figcaption\n        margin: 0 !important\n        padding: .3em 0em .3em .75em\n        font-style: normal\n        font-size: .8em\n\n        *\n            color: inherit\n\n        span\n            font-weight: 500\n            font-family: $family-code\n\n        .level-left *:not(:last-child)\n            margin-right: .5em\n\n        .level-right *:not(:first-child)\n            margin-left: .5em\n\n        .fold\n            cursor: pointer\n\n        &.level\n            overflow: auto\n\n            .level-right\n                a\n                    padding: 0em .75em\n\n    .highlight-body\n        overflow: auto\n\n    .gutter\n        text-align: right\n\n    .tag, .title, .number, .section\n        display: inherit\n        font: inherit\n        margin: inherit\n        padding: inherit\n        background: inherit\n        height: inherit\n        text-align: inherit\n        vertical-align: inherit\n        min-width: inherit\n        border-radius: inherit\n\nfigure.highlight.foldable\n  div.level-left\n    cursor: pointer  // clicking the codeblock filename can toggle folding \n\n/* ---------------------------------\n *        Fix Gist Snippet\n * --------------------------------- */\n.gist\n    table\n        tr:hover\n            background: transparent\n\n        td\n            border: none\n\n    .file\n        all: initial\n"
  },
  {
    "path": "include/style/donate.styl",
    "content": "/* ---------------------------------\n *          Donate Buttons\n * --------------------------------- */\n$donate-qrcode-max-width ?= 280px\n$donate-qrcode-shadow ?= $card-shadow\n$donate-qrcode-box-radius ?= $card-radius\n\n$donate-button-colors ?= {\n    'afdian': rgb(136, 95, 217),\n    'alipay': rgb(0, 160, 232),\n    'buymeacoffee': rgb(255, 221, 0),\n    'paypal': rgb(254, 183, 0),\n    'patreon': rgb(255, 66, 77),\n    'wechat': rgb(26, 173, 25),\n}\n\n.donate\n    position: relative\n\n    .qrcode\n        display: none\n        position: absolute\n        z-index: 99\n        bottom: 2.5em\n        line-height: 0\n        overflow: hidden\n        box-shadow: $donate-qrcode-shadow\n        border-radius: $donate-qrcode-box-radius\n\n        img\n            max-width: $donate-qrcode-max-width\n\n    &:hover\n        .qrcode\n            display: block\n\n    &:first-child:not(:last-child)\n        .qrcode\n            left: -.75rem\n\n    &:last-child:not(:first-child)\n        .qrcode\n            right: -.75rem\n\n    for $name, $color in $donate-button-colors\n        &[data-type={'\"' + $name + '\"'}]\n            color: findColorInvert($color)\n            background-color: $color\n            border-color: transparent\n\n            &:active\n                background-color: darken($color, 5%)\n\n            &:hover\n                background-color: darken($color, 2.5%)\n\n            &:focus:not(:active)\n                box-shadow: 0 0 0 .125em rgba($color, .25)\n"
  },
  {
    "path": "include/style/footer.styl",
    "content": "/* ---------------------------------\n *            Page Footer\n * --------------------------------- */\nfooter.footer\n    .level-start\n        +mobile()\n            text-align: center\n\n    .level-end\n        .field\n            flex-wrap: wrap\n            align-items: center\n\n            +mobile()\n                justify-content: center\n                margin-top: 1rem\n\n.footer-logo\n    img\n        max-height: $logo-height\n"
  },
  {
    "path": "include/style/helper.styl",
    "content": "/* ---------------------------------\n *          Spacing helpers\n * --------------------------------- */\n$spacer ?= 1rem\n$spacers ?= 0, $spacer * .25, $spacer * .5, $spacer, $spacer * 1.5, $spacer * 3\n\nfor n in (0 .. 5)\n    .ml-{n}\n        margin-left: $spacers[n] !important\n\n    .mr-{n}\n        margin-right: $spacers[n] !important\n\n    .mx-{n}\n        @extend .ml-{n}, .mr-{n}\n\n    .ml-n{n}\n        margin-left: - $spacers[n] !important\n\n    .mr-n{n}\n        margin-right: - $spacers[n] !important\n\n    .mx-n{n}\n        @extend .ml-n{n}, .mr-n{n}\n\n    .mt-{n}\n        margin-top: $spacers[n] !important\n\n    .mb-{n}\n        margin-bottom: $spacers[n] !important\n\n    .my-{n}\n        @extend .mt-{n}, .mb-{n}\n\n    .mt-n{n}\n        margin-top: - $spacers[n] !important\n\n    .mb-n{n}\n        margin-bottom: - $spacers[n] !important\n\n    .my-n{n}\n        @extend .mt-n{n}, .mb-n{n}\n\n    .pl-{n}\n        padding-left: $spacers[n] !important\n\n    .pr-{n}\n        padding-right: $spacers[n] !important\n\n    .px-{n}\n        @extend .pl-{n}, .pr-{n}\n\n    .pl-n{n}\n        padding-left: - $spacers[n] !important\n\n    .pr-n{n}\n        padding-right: - $spacers[n] !important\n\n    .px-n{n}\n        @extend .pl-n{n}, .pr-n{n}\n\n    .pt-{n}\n        padding-top: $spacers[n] !important\n\n    .pb-{n}\n        padding-bottom: $spacers[n] !important\n\n    .py-{n}\n        @extend .pt-{n}, .pb-{n}\n\n    .pt-n{n}\n        padding-top: - $spacers[n] !important\n\n    .pb-n{n}\n        padding-bottom: - $spacers[n] !important\n\n    .py-n{n}\n        @extend .pt-n{n}, .pb-n{n}\n\n.ml-auto\n    margin-left: auto !important\n\n.mr-auto\n    margin-right: auto !important\n\n.mx-auto\n    @extend .ml-auto, .mr-auto\n\n.mt-auto\n    margin-top: auto !important\n\n.mb-auto\n    margin-bottom: auto !important\n\n.my-auto\n    @extend .mt-auto, .mb-auto\n\n.pl-auto\n    margin-left: auto !important\n\n.pr-auto\n    margin-right: auto !important\n\n.px-auto\n    @extend .pl-auto, .pr-auto\n\n.pt-auto\n    margin-top: auto !important\n\n.pb-auto\n    margin-bottom: auto !important\n\n.py-auto\n    @extend .pt-auto, .pb-auto\n\n/* ---------------------------------\n *           Flex helpers\n * --------------------------------- */\nfor n in (0 .. 5)\n    .order-{n}\n        order: n !important\n\n.justify-content-start\n    justify-content: start !important\n\n.justify-content-center\n    justify-content: center !important\n\n.flex-shrink-1\n    flex-shrink: 1 !important\n\n/* ---------------------------------\n *           Color helpers\n * --------------------------------- */\n.link-muted\n    color: inherit\n\n    &:hover\n        color: $primary !important\n\n/* ---------------------------------\n *          Image helpers\n * --------------------------------- */\n.image\n    &.is-7by3\n        padding-top: 42.8%\n\n        img\n            bottom: 0\n            left: 0\n            position: absolute\n            right: 0\n            top: 0\n\n    .avatar\n        height: 100%\n        object-fit: cover\n\n    .fill\n        object-fit: cover\n        width: 100% !important\n        height: 100% !important"
  },
  {
    "path": "include/style/navbar.styl",
    "content": "/* ---------------------------------\n *           Top Navigation\n * --------------------------------- */\n$navbar-item-padding-v ?= 1.25rem\n$navbar-item-padding-h ?= .75rem\n$navbar-item-margin-v ?= 0\n$navbar-item-margin-h ?= 0\n\n.navbar-main\n    box-shadow: $shadow\n\n    .navbar-container\n        overflow-x: auto\n\n    .navbar-menu, .navbar-start, .navbar-end\n        align-items: stretch\n        display: flex\n        padding: 0\n        flex-shrink: 0\n\n    .navbar-menu\n        flex-grow: 1\n        flex-shrink: 0\n        overflow-x: auto\n\n    .navbar-start\n        justify-content: flex-start\n        margin-right: auto\n\n    .navbar-end\n        justify-content: flex-end\n        margin-left: auto\n\n    .navbar-item\n        display: flex\n        align-items: center\n        padding: $navbar-item-padding-v $navbar-item-padding-h\n        margin: $navbar-item-margin-v $navbar-item-margin-h\n\n        &.is-active\n            background-color: transparent\n\n    +until($navbar-breakpoint)\n        .navbar-menu\n            justify-content: center\n            box-shadow: none\n\n        .navbar-start\n            margin-right: 0\n\n        .navbar-end\n            margin-left: 0\n\n.navbar-logo\n    img\n        max-height: $logo-height\n\n@media screen and (min-width: $desktop)\n    .navbar > .container .navbar-menu, .container > .navbar .navbar-menu\n        margin-right: 0rem\n"
  },
  {
    "path": "include/style/pagination.styl",
    "content": "/* ---------------------------------\n *  Pagination and Post Navigation\n * --------------------------------- */\n$pagination-box-shadow ?= $card-shadow\n$pagination-background-color ?= $button-background-color\n$post-navigation-fg ?= $grey\n\n.pagination\n    @extend .pagination.is-centered\n    margin-top: 1.5rem\n\n    .pagination-link,\n    .pagination-ellipsis,\n    .pagination-previous,\n    .pagination-next\n        a\n            color: $pagination-color\n    .pagination-link,\n    .pagination-previous,\n    .pagination-next\n        border: none\n        background: $pagination-background-color\n        box-shadow: $pagination-box-shadow\n    .pagination-link.is-current\n        background: $pagination-current-background-color\n\n.post-navigation\n    color: $post-navigation-fg\n    flex-wrap: wrap\n    justify-content: space-around\n    .level-item\n        margin-bottom: 0\n"
  },
  {
    "path": "include/style/plugin.styl",
    "content": "/* ---------------------------------\n *        Back to Top Button\n * --------------------------------- */\n#back-to-top\n    position: fixed\n    opacity: 0\n    outline: none\n    padding: 8px 0\n    line-height: 24px\n    border-radius: $card-radius\n    transform: translateY(120px)\n    transition: .4s ease opacity, .4s ease width, .4s ease transform, .4s ease border-radius\n\n    &.is-rounded\n        border-radius: 50%\n\n    &.fade-in\n        opacity: 1\n\n    &.rise-up\n        transform: translateY(0)\n\n/* ---------------------------------\n *          Gallery Plugin\n * --------------------------------- */\n.gallery-item\n    .caption\n        color: $grey\n\n/* ---------------------------------\n *      Page Loading Progressbar\n * --------------------------------- */\n.pace\n    user-select: none\n    pointer-events: none\n\n    .pace-progress\n        top: 0\n        right: 100%\n        width: 100%\n        height: 2px\n        z-index: 2000\n        position: fixed\n        background: $primary\n\n.pace-inactive\n    display: none\n\n/* ---------------------------------\n *       Fix FontAwesome Icons\n * --------------------------------- */\n.fa, .fab, .fal, .far, .fas\n    line-height: inherit\n\n/* ---------------------------------\n *       MathJax and KaTeX\n * --------------------------------- */\n.MathJax, .MathJax_Display, .MJXc-display, .MathJax_SVG_Display, .katex-display\n    overflow-x: auto\n    overflow-y: hidden\n\n.katex\n    white-space: nowrap\n\n.katex-display\n    margin-top: -1em !important\n\n.katex-html\n    padding-top: 1em\n\n    .tag\n        align-items: unset\n        background-color: unset\n        border-radius: unset\n        color: unset\n        display: unset\n        font-size: unset\n        height: unset\n        justify-content: unset\n        line-height: unset\n        padding-left: unset\n        padding-right: unset\n        white-space: unset\n\n/* ---------------------------------\n *         Cookie Consent\n * --------------------------------- */\n.cc-window, .cc-revoke\n    font-size: 1.1rem !important\n    font-family: $family-sans-serif !important\n\n.cc-window\n    color: $text !important\n    background-color: $scheme-main !important\n\n    &.cc-floating\n        border-radius: $card-radius\n        box-shadow: $card-shadow\n\n    &.cc-banner\n        background-color: darken($scheme-main, 2.5%) !important\n\n    &.cc-theme-block, &.cc-theme-classic\n        .cc-compliance > .cc-btn\n            border-radius: $radius-rounded\n\n    .cc-compliance > .cc-btn\n        font-weight: 400\n        border: none\n        color: $primary-invert\n        background-color: $primary\n\n        &:hover, &:focus\n            background-color: darken($primary, 2.5%)\n\n        &.cc-deny\n            &:hover\n                color: $primary\n                text-decoration: none\n\n.cc-revoke\n    padding: .5rem 1rem !important\n    color: $primary-invert !important\n    background-color: $primary !important\n\n    &:hover\n        text-decoration: none !important\n        background-color: darken($primary, 2.5%)\n"
  },
  {
    "path": "include/style/responsive.styl",
    "content": "/* ---------------------------------\n *         Responsive Layout\n * --------------------------------- */\n+widescreen()\n    .is-1-column .container, .is-2-column .container\n        max-width: $desktop - 2 * $gap\n        width: $desktop - 2 * $gap\n\n+fullhd()\n    .is-2-column .container\n        max-width: $widescreen - 2 * $gap\n        width: $widescreen - 2 * $gap\n\n    .is-1-column .container\n        max-width: $desktop - 2 * $gap\n        width: $desktop - 2 * $gap\n\n+tablet()\n    .is-sticky\n        position: -webkit-sticky\n        position: sticky\n        top: 1.5rem\n        z-index: 99\n\n    .column-main, .column-left, .column-right, .column-right-shadow\n        &.is-sticky\n            top: .75rem\n            align-self: flex-start\n\n+mobile()\n    .section\n        padding: 1.5rem 1rem\n"
  },
  {
    "path": "include/style/search.styl",
    "content": "/* ---------------------------------\n *           Search Box\n * --------------------------------- */\n// container sizes\n$searchbox-container-width ?= 540px\n$searchbox-container-margin ?= 100px\n$searchbox-breakpoint-width ?= 559px\n$searchbox-breakpoint-height ?= 479px\n// overlay and container styles\n$searchbox-box-shadow ?= $card-shadow\n$searchbox-border-radius ?= $radius\n$searchbox-bg-overlay ?= $modal-background-background-color\n$searchbox-bg-container ?= $white-ter\n$searchbox-border ?= $border\n// header styles\n$searchbox-bg-input ?= $white\n$searchbox-bg-close-hover ?= $searchbox-bg-container\n$searchbox-bg-close-active ?= $grey-lighter\n// body styles\n$searchbox-fg-result-header ?= $grey-light\n$searchbox-fg-result-item-secondary ?= $grey-light\n$searchbox-bg-result-item-hover ?= $searchbox-bg-input\n$searchbox-fg-result-item-active ?= findColorInvert($primary)\n$searchbox-bg-result-item-active ?= $primary\n$searchbox-bg-result-item-highlight ?= $yellow\n// footer styles\n$searchbox-bg-pagination-item ?= $searchbox-bg-input\n$searchbox-bg-pagination-item-hover ?= $searchbox-bg-container\n$searchbox-fg-pagination-item-active ?= findColorInvert($primary)\n$searchbox-bg-pagination-item-active ?= $primary\n$searchbox-bg-pagination-item-disabled ?= $searchbox-bg-container\n\n.searchbox\n    display: none\n    top: 0\n    left: 0\n    width: 100%\n    height: 100%\n    z-index: 100\n    font-size: 1rem\n    line-height: 0\n    background: $searchbox-bg-overlay\n\n    &.show\n        display: flex\n\n    a, a:hover\n        color: inherit\n        text-decoration: none\n\n    input\n        font-size: 1rem\n        border: none\n        outline: none\n        box-shadow: none\n        border-radius: 0\n\n    &, .searchbox-container\n        position: fixed\n        align-items: center\n        flex-direction: column\n        line-height: 1.25em\n\n    .searchbox-container\n        z-index: 101\n        display: flex\n        overflow: hidden\n        box-shadow: $searchbox-box-shadow\n        border-radius: $searchbox-border-radius\n        background-color: $searchbox-bg-container\n        width: $searchbox-container-width\n        top: $searchbox-container-margin\n        bottom: $searchbox-container-margin\n\n    .searchbox-header, .searchbox-body, .searchbox-footer\n        width: 100%\n\n    .searchbox-header\n        display: flex\n        flex-direction: row\n        line-height: 1.5em\n        font-weight: normal\n        background-color: $searchbox-bg-input\n        // fix Chrome 71 height issue\n        // https://github.com/ppoffice/hexo-theme-icarus/issues/719\n        min-height: 3rem\n\n    .searchbox-input-container\n        display: flex\n        flex-grow: 1\n\n    .searchbox-input\n        flex-grow: 1\n        color: inherit\n        box-sizing: border-box\n        padding: .75em 0 .75em 1.25em\n        background: $searchbox-bg-input\n\n    .searchbox-close\n        display: inline-block\n        font-size: 1.5em\n        padding: .5em .75em\n        cursor: pointer\n\n        &:hover\n            background: $searchbox-bg-close-hover\n\n        &:active\n            background: $searchbox-bg-close-active\n\n    .searchbox-body\n        flex-grow: 1\n        overflow-y: auto\n        border-top: 1px solid $searchbox-border\n\n    .searchbox-result-section header, .searchbox-result-item\n        padding: .75em 1em\n\n    .searchbox-result-section\n        border-bottom: 1px solid $searchbox-border\n\n        header\n            color: $searchbox-fg-result-header\n\n    .searchbox-result-item\n        display: flex\n        flex-direction: row\n\n        &:not(.disabled):not(.active):not(:active):hover\n            background-color: $searchbox-bg-result-item-hover\n\n        &:active, &.active\n            color: $searchbox-fg-result-item-active\n            background-color: $searchbox-bg-result-item-active\n\n        em\n            font-style: normal\n            background: $searchbox-bg-result-item-highlight\n\n    .searchbox-result-icon\n        margin-right: 1em\n\n    .searchbox-result-content\n        overflow: hidden\n\n    .searchbox-result-title, .searchbox-result-preview\n        display: block\n        overflow: hidden\n        white-space: nowrap\n        text-overflow: ellipsis\n\n    .searchbox-result-title-secondary\n        color: $searchbox-fg-result-item-secondary\n\n    .searchbox-result-preview\n        margin-top: .25em\n\n    .searchbox-result-item:not(:active):not(.active)\n        .searchbox-result-preview\n            color: $searchbox-fg-result-item-secondary\n\n    .searchbox-footer\n        padding: .5em 1em\n\n    .searchbox-pagination\n        margin: 0\n        padding: 0\n        list-style: none\n        text-align: center\n\n        .searchbox-pagination-item\n            margin: 0 .25rem\n\n        .searchbox-pagination-item, .searchbox-pagination-link\n            display: inline-block\n\n        .searchbox-pagination-link\n            overflow: hidden\n            padding: .5em .8em\n            box-shadow: $searchbox-box-shadow\n            border-radius: $searchbox-border-radius\n            background-color: $searchbox-bg-pagination-item\n\n        .searchbox-pagination-item.active\n            .searchbox-pagination-link\n                color: $searchbox-fg-pagination-item-active\n                background-color: $searchbox-bg-pagination-item-active\n\n        .searchbox-pagination-item.disabled\n            .searchbox-pagination-link\n                cursor: not-allowed\n                background-color: $searchbox-bg-pagination-item-disabled\n\n        .searchbox-pagination-item:not(.active):not(.disabled)\n            .searchbox-pagination-link:hover\n                background-color: $searchbox-bg-pagination-item-hover\n\n@media screen and (max-width: $searchbox-breakpoint-width), screen and (max-height: $searchbox-breakpoint-height)\n    .searchbox .searchbox-container\n        top: 0\n        left: 0\n        width: 100%\n        height: 100%\n        border-radius: 0\n"
  },
  {
    "path": "include/style/timeline.styl",
    "content": "/* ---------------------------------\n *          Archive Timeline\n * --------------------------------- */\n$timeline-fg-line ?= $grey-lighter\n$timeline-bg-line ?= $card-background-color\n\n.timeline\n    margin-left: 1rem\n    padding: 1rem 0 0 1.5rem\n    border-left: 1px solid $timeline-fg-line\n\n    .media\n        position: relative\n\n        &:before, &:last-child:after\n            content: ''\n            display: block\n            position: absolute\n            left: calc(-.375rem - 1.5rem - .25px)\n\n        &:before\n            width: .75rem\n            height: .75rem\n            top: calc(1rem + 1.5 * .85rem / 2 - .75rem / 2)\n            background: $timeline-fg-line\n            border-radius: 50%\n\n        &:first-child:before\n            top: calc(1.5 * .85rem / 2 - .75rem / 2)\n\n        &:last-child:after\n            width: .75rem\n            top: calc(1rem + 1.5 * .85rem / 2 + .75rem / 2)\n            bottom: 0\n            background: $timeline-bg-line\n\n        &:first-child:last-child:after\n            top: calc(1.5 * .85rem / 2 + .75rem / 2)\n"
  },
  {
    "path": "include/style/widget.styl",
    "content": ".widget\n    .menu-list\n        li\n            ul\n                margin-right: 0\n\n        .level\n            margin-bottom: 0\n\n            .level-left, .level-right, .level-item\n                flex-shrink: 1\n\n            .level-left, .level-right\n                align-items: flex-start\n\n        .tag\n            background: $light-grey\n            color: $white-invert\n\n    .tags\n        .tag:first-child\n            background: $primary\n            color: $primary-invert\n\n        .tag:last-child\n            background: $light-grey\n            color: $white-invert\n\n.level.is-multiline\n    flex-wrap: wrap\n\n/* ---------------------------------\n *      Table of Content Widget\n * --------------------------------- */\n+mobile()\n    .widget.card#toc\n        display: none\n        position: fixed\n        margin: 1rem\n        left: 0\n        right: 0\n        bottom: 0\n        z-index: 100\n\n        .card-content\n            padding: 0\n\n        .menu\n            padding: 1.5rem\n            max-height: calc(100vh - 2rem)\n            overflow-y: auto\n\n    #toc-mask\n        display: none\n        position: fixed\n        top: 0\n        left: 0\n        right: 0\n        bottom: 0\n        z-index: 99\n        background: rgba(0, 0, 0, .7)\n\n    .widget.card#toc, #toc-mask\n        &.is-active\n            display: block"
  },
  {
    "path": "include/util/console.js",
    "content": "let chalk;\ntry {\n    chalk = require('chalk'); // eslint-disable-line node/no-extraneous-require\n} catch (e) { }\n\nmodule.exports = new Proxy({}, {\n    get(obj, prop) {\n        if (chalk) {\n            return chalk[prop];\n        }\n        return function() {\n            return arguments.length === 1 ? arguments[0] : arguments;\n        };\n    }\n});\n"
  },
  {
    "path": "languages/de.yml",
    "content": "common:\n    archive:\n        one: 'Archiv'\n        other: 'Archive'\n    category:\n        one: 'Kategorie'\n        other: 'Kategorien'\n    tag:\n        one: 'Tag'\n        other: 'Tags'\n    post:\n        one: 'Seite'\n        other: 'Seiten'\n    page:\n        one: 'Page'\n        other: 'Pages'\n    prev: 'Zurück'\n    next: 'Weiter'\nwidget:\n    follow: 'Folgen'\n    recents: 'Letzte Einträge'\n    links: 'Links'\n    catalogue: 'Katalog'\n    subscribe_email: 'Abonnieren Sie Updates'\n    subscribe: 'Abonnieren'\n    adsense: 'Werbung'\n    followit: 'follow.it'\narticle:\n    created_at: 'Gepostet vor&nbsp;%s'\n    updated_at: 'Aktualisiert vor&nbsp;%s'\n    more: 'Mehr lesen'\n    comments: 'Kommentare'\n    read_time: '%s lesen'\n    word_count:\n        one: 'Über %d Wort'\n        other: 'Über %d Wörter'\n    licensing:\n        author: 'Author'\n        created_at: 'Posted on'\n        updated_at: 'Updated on'\n        licensed_under: 'Licensed under'\ndonate:\n    title: 'Gefällt Ihnen der Artikel? Unterstützen Sie den Autor mit'\n    afdian: 'Afdian.net'\n    alipay: 'Alipay'\n    wechat: 'Wechat'\n    paypal: 'Paypal'\n    patreon: 'Patreon'\n    buymeacoffee: 'Kauf mir einen Kaffee'\nplugin:\n    backtotop: 'Zurück nach oben'\n    visit_count: '%s&nbsp;Besuche'\n    visitor_count: 'Von %s Nutzern besucht'\n    cookie_consent:\n      message: Diese Website verwendet Cookies, um Ihre Erfahrung zu verbessern.\n      dismiss: Verstanden!\n      allow: Cookies zulassen\n      deny: Ablehnen\n      link: Mehr erfahren\n      policy: Cookie-Richtlinie\nsearch:\n    search: 'Suche'\n    hint: 'Tippen Sie etwas...'\n    no_result: 'Keine Ergebnisse für'\n    untitled: '(Ohne Titel)'\n    empty_preview: '(Keine Vorschau)'\n"
  },
  {
    "path": "languages/en.yml",
    "content": "common:\n    archive:\n        one: 'Archive'\n        other: 'Archives'\n    category:\n        one: 'Category'\n        other: 'Categories'\n    tag:\n        one: 'Tag'\n        other: 'Tags'\n    post:\n        one: 'Post'\n        other: 'Posts'\n    page:\n        one: 'Page'\n        other: 'Pages'\n    prev: 'Previous'\n    next: 'Next'\nwidget:\n    follow: 'Follow'\n    recents: 'Recents'\n    links: 'Links'\n    catalogue: 'Catalogue'\n    subscribe_email: 'Subscribe for updates'\n    subscribe: 'Subscribe'\n    adsense: 'Advertisement'\n    followit: 'follow.it'\narticle:\n    created_at: 'Posted&nbsp;%s'\n    updated_at: 'Updated&nbsp;%s'\n    more: 'Read more'\n    comments: 'Comments'\n    read_time: '%s read'\n    word_count:\n        one: 'About %d word'\n        other: 'About %d words'\n    licensing:\n        author: 'Author'\n        created_at: 'Posted on'\n        updated_at: 'Updated on'\n        licensed_under: 'Licensed under'\ndonate:\n    title: 'Like this article? Support the author with'\n    afdian: 'Afdian.net'\n    alipay: 'Alipay'\n    wechat: 'Wechat'\n    paypal: 'Paypal'\n    patreon: 'Patreon'\n    buymeacoffee: 'Buy me a coffee'\nplugin:\n    backtotop: 'Back to top'\n    visit_count: '%s&nbsp;visits'\n    visitor_count: 'Visited by %s users'\n    cookie_consent:\n      message: This website uses cookies to improve your experience.\n      dismiss: Got it!\n      allow: Allow cookies\n      deny: Decline\n      link: Learn more\n      policy: Cookie Policy\nsearch:\n    search: 'Search'\n    hint: 'Type something...'\n    no_result: 'No results for'\n    untitled: '(Untitled)'\n    empty_preview: '(No preview)'\n"
  },
  {
    "path": "languages/es.yml",
    "content": "#By SrWoOoW\ncommon:\n    archive:\n        one: 'Archivo'\n        other: 'Archivos'\n    category:\n        one: 'Categoría'\n        other: 'Categorías'\n    tag:\n        one: 'Etiqueta'\n        other: 'Etiquetas'\n    post:\n        one: 'Entrada'\n        other: 'Entradas'\n    page:\n        one: 'Página'\n        other: 'Páginas'\n    prev: 'Anterior'\n    next: 'Siguiente'\nwidget:\n    follow: 'SEGUIR'\n    recents: 'Recientes'\n    links: 'Enlaces'\n    catalogue: 'Catálogo'\n    subscribe_email: 'Suscríbete para recibir actualizaciones'\n    subscribe: 'Suscribir'\n    adsense: 'Anuncio'\n    followit: 'follow.it'\narticle:\n    created_at: 'Publicado hace&nbsp;%s'\n    updated_at: 'Actualizado hace&nbsp;%s'\n    more: 'Leer más'\n    comments: 'Comentarios'\n    read_time: '%s de lectura'\n    word_count:\n        one: 'Aproximadamente %d palabra'\n        other: 'Aproximadamente %d palabras'\n    licensing:\n        author: 'Author'\n        created_at: 'Posted on'\n        updated_at: 'Updated on'\n        licensed_under: 'Licensed under'\ndonate:\n    title: '¿Te gusta este artículo? Apoya al autor con'\n    afdian: 'Afdian.net'\n    alipay: 'Alipay'\n    wechat: 'Wechat'\n    paypal: 'Paypal'\n    patreon: 'Patreon'\n    buymeacoffee: 'Cómprame un café'\nplugin:\n    backtotop: 'Volver arriba'\n    visit_count: '%s&nbsp;visitas'\n    visitor_count: 'Visitado por %s usuarios'\n    cookie_consent:\n      message: Este sitio web utiliza cookies para mejorar su experiencia.\n      dismiss: ¡Entendido!\n      allow: Permitir cookies\n      deny: Descenso\n      link: Aprende más\n      policy: Política de cookies\nsearch:\n    search: 'Buscar'\n    hint: 'Teclea algo...'\n    no_result: 'No hay resultados para'\n    untitled: '(Sin título)'\n    empty_preview: '(Sin vista previa)'\n"
  },
  {
    "path": "languages/fr.yml",
    "content": "common:\n    archive:\n        one: 'Archive'\n        other: 'Archives'\n    category:\n        one: 'Catégorie'\n        other: 'Catégories'\n    tag:\n        one: 'Tag'\n        other: 'Tags'\n    post:\n        one: 'Article'\n        other: 'Articles'\n    page:\n        one: 'Page'\n        other: 'Pages'\n    prev: 'Préc'\n    next: 'Suiv'\nwidget:\n    follow: 'Suivre'\n    recents: 'Récents'\n    links: 'Liens'\n    catalogue: 'Catalogue'\n    subscribe_email: 'Abonnez-vous aux mises à jour'\n    subscribe: 'Abonnez-vous'\n    adsense: 'Publicités'\n    followit: 'follow.it'\narticle:\n    created_at: 'Publié il y a&nbsp;%s'\n    updated_at: 'Mis à jour il y a&nbsp;%s'\n    more: 'Lire la suite'\n    comments: 'Commentaires'\n    read_time: '%s de lecture'\n    word_count:\n        one: 'Environ %d mot'\n        other: 'Environ %d mots'\n    licensing:\n        author: 'Auteur'\n        created_at: 'Posté le'\n        updated_at: 'Mis à jour le'\n        licensed_under: 'Licencié sous'\ndonate:\n    title: \"Vous aimez cet article? Soutenez l'auteur avec\"\n    afdian: 'Afdian.net'\n    alipay: 'Alipay'\n    wechat: 'Wechat'\n    paypal: 'Paypal'\n    patreon: 'Patreon'\n    buymeacoffee: 'Achetez-moi un café'\nplugin:\n    backtotop: 'Retour en haut'\n    visit_count: '%s&nbsp;visites'\n    visitor_count: 'Visité par %s utilisateurs'\n    cookie_consent:\n      message: 'Ce site Web utilise des cookies pour améliorer votre expérience.'\n      dismiss: \"C'est bon\"\n      allow: 'Autoriser les cookies'\n      deny: 'Refuser'\n      link: 'En savoir plus'\n      policy: 'Politique relative aux cookies'\nsearch:\n    search: 'Rechercher'\n    hint: 'Ecrivez quelque chose...'\n    no_result: 'Aucun résultat pour'\n    untitled: '(Sans titre)'\n    empty_preview: '(Pas de prévisualisation)'\n"
  },
  {
    "path": "languages/id.yml",
    "content": "common:\n    archive:\n        one: 'Arsip'\n        other: 'Arsip'\n    category:\n        one: 'Kategori'\n        other: 'Kategori'\n    tag:\n        one: 'Tag'\n        other: 'Tag'\n    post:\n        one: 'Artikel'\n        other: 'Artikel'\n    page:\n        one: 'Halaman'\n        other: 'Halaman'\n    prev: 'Sebelumnya'\n    next: 'Berikutnya'\nwidget:\n    follow: 'IKUTI'\n    recents: 'Terbaru'\n    links: 'Tautan'\n    catalogue: 'Katalog'\n    subscribe_email: 'Berlangganan untuk pembaruan'\n    subscribe: 'Berlangganan'\n    adsense: 'Iklan'\n    followit: 'follow.it'\narticle:\n    created_at: 'Diposting&nbsp;%s'\n    updated_at: 'Diperbarui&nbsp;%s'\n    more: 'Selengkapnya'\n    comments: 'Komentar'\n    read_time: '%s membaca'\n    word_count:\n        one: 'Sekitar %d kata'\n        other: 'Sekitar %d kata'\n    licensing:\n        author: 'Author'\n        created_at: 'Posted on'\n        updated_at: 'Updated on'\n        licensed_under: 'Licensed under'\ndonate:\n    title: 'Suka dengan artikel ini? Bantu penulis dengan donasi melalui'\n    afdian: 'Afdian.net'\n    alipay: 'Alipay'\n    wechat: 'Wechat'\n    paypal: 'Paypal'\n    patreon: 'Patreon'\n    buymeacoffee: 'Belikan aku kopi'\nplugin:\n    backtotop: 'Kembali ke atas'\n    visit_count: '%s&nbsp;kunjungan'\n    visitor_count: 'Dikunjungi oleh %s pengguna'\n    cookie_consent:\n      message: Situs web ini menggunakan cookie untuk meningkatkan pengalaman Anda.\n      dismiss: Mengerti!\n      allow: Izinkan cookie\n      deny: Menolak\n      link: Belajarlah lagi\n      policy: Kebijakan Cookie\nsearch:\n    search: 'Pencarian'\n    hint: 'Tulis Sesuatu..'\n    no_result: 'Tidak ada hasil untuk'\n    untitled: '(Tanpa judul)'\n    empty_preview: '(Tidak ada preview)'\n"
  },
  {
    "path": "languages/it.yml",
    "content": "common:\n    archive:\n        one: 'Archivio'\n        other: 'Archivi'\n    category:\n        one: 'Categoria'\n        other: 'Categorie'\n    tag:\n        one: 'Tag'\n        other: 'Tag'\n    post:\n        one: 'Articolo'\n        other: 'Articoli'\n    page:\n        one: 'Pagina'\n        other: 'Pagine'\n    prev: 'Precedente'\n    next: 'Successivo'\nwidget:\n    follow: 'Segui'\n    recents: 'Recenti'\n    links: 'Collegamenti'\n    catalogue: 'Catalogo'\n    subscribe_email: 'Iscriviti per aggiornamenti'\n    subscribe: 'Iscriviti'\n    adsense: 'Pubblicità'\n    followit: 'follow.it'\narticle:\n    created_at: 'Pubblicato il&nbsp;%s'\n    updated_at: 'Aggiornato il&nbsp;%s'\n    more: 'Di più'\n    comments: 'Commenti'\n    read_time: '%s di lettura'\n    word_count:\n        one: 'Circa %d parola'\n        other: 'Circa %d parole'\n    licensing:\n        author: 'Autore'\n        created_at: 'Pubblicato il'\n        updated_at: 'Aggiornato il'\n        licensed_under: 'Licenza'\ndonate:\n    title: \"Ti è piaciuto questo articolo? Supporta l'autore con\"\n    afdian: 'Afdian.net'\n    alipay: 'Alipay'\n    wechat: 'Wechat'\n    paypal: 'Paypal'\n    patreon: 'Patreon'\n    buymeacoffee: 'Buy me a coffee'\nplugin:\n    backtotop: 'Torna su'\n    visit_count: '%s&nbsp;visite'\n    visitor_count: 'Visto da %s usenti'\n    cookie_consent:\n      message: Questo sito usa i cookie per migliorare la tua esperienza.\n      dismiss: \"D'accordo!\"\n      allow: Accetta i cookie\n      deny: Rifiuta\n      link: Più informazioni\n      policy: Politica dei cookie\nsearch:\n    search: 'Cerca'\n    hint: 'Digita qualcosa...'\n    no_result: 'Nessun risultato per'\n    untitled: '(Senza titolo)'\n    empty_preview: '(Senza anteprima)'\n"
  },
  {
    "path": "languages/ja.yml",
    "content": "common:\n    archive:\n        one: 'アーカイブ'\n        other: 'アーカイブ'\n    category:\n        one: 'カテゴリ'\n        other: 'カテゴリ'\n    tag:\n        one: 'タグ'\n        other: 'タグ'\n    post:\n        one: '投稿'\n        other: '投稿'\n    page:\n        one: 'ページ'\n        other: 'ページ'\n    prev: '前'\n    next: '次'\nwidget:\n    follow: 'フォローする'\n    recents: '最近の記事'\n    links: 'リンク'\n    catalogue: 'カタログ'\n    subscribe_email: '更新を購読する'\n    subscribe: '購読する'\n    adsense: '広告'\n    followit: 'follow.it'\narticle:\n    created_at: '%sに投稿'\n    updated_at: '%sに更新'\n    more: '続きを読む'\n    comments: 'コメント'\n    read_time: '%sで読む'\n    word_count:\n        one: '約%d語'\n        other: '約%d語'\n    licensing:\n        author: 'Author'\n        created_at: 'Posted on'\n        updated_at: 'Updated on'\n        licensed_under: 'Licensed under'\ndonate:\n    title: 'この記事は気に入りましたか？ 著者をサポートする'\n    afdian: 'Afdian.net'\n    alipay: 'Alipay'\n    wechat: 'Wechat'\n    paypal: 'Paypal'\n    patreon: 'Patreon'\n    buymeacoffee: 'コーヒーを買って'\nplugin:\n    backtotop: 'トップに戻る'\n    visit_count: '%s回の訪問'\n    visitor_count: '%s人のユーザーがアクセス'\n    cookie_consent:\n      message: このウェブサイトはあなたの経験を改善するためにCookieを使用しています。\n      dismiss: 了解しました\n      allow: Cookiesを許可する\n      deny: 拒否する\n      link: もっと詳しく知る\n      policy: Cookieポリシー\nsearch:\n    search: '検索'\n    hint: '何かを入力してください...'\n    no_result: 'の結果はありません'\n    untitled: '(無題)'\n    empty_preview: '(プレビューなし)'\n"
  },
  {
    "path": "languages/ko.yml",
    "content": "common:\n    archive:\n        one: '아카이브'\n        other: '아카이브'\n    category:\n        one: '카테고리'\n        other: '카테고리'\n    tag:\n        one: '태그'\n        other: '태그'\n    post:\n        one: '포스트'\n        other: '포스트'\n    page:\n        one: '페이지'\n        other: '페이지'\n    prev: '이전'\n    next: '다음'\nwidget:\n    follow: '팔로우'\n    recents: '최근 글'\n    links: '링크'\n    catalogue: '카탈로그'\n    subscribe_email: '업데이트 소식 받기'\n    subscribe: '구독'\n    adsense: '광고'\n    followit: 'follow.it'\narticle:\n    created_at: '%s&nbsp;게시 됨'\n    updated_at: '%s&nbsp;업데이트 됨'\n    more: '자세히 보기'\n    comments: '댓글'\n    read_time: '%s안에 읽기'\n    word_count:\n        one: '약 %d 단어'\n        other: '약 %d 단어'\n    licensing:\n        author: 'Author'\n        created_at: 'Posted on'\n        updated_at: 'Updated on'\n        licensed_under: 'Licensed under'\ndonate:\n    title: '이 글이 마음에 드시나요? 다음을 통해 후원하실 수 있습니다: '\n    afdian: 'Afdian.net'\n    alipay: 'Alipay'\n    wechat: 'Wechat'\n    paypal: 'Paypal'\n    patreon: 'Patreon'\n    buymeacoffee: '커피 한 잔 사주기'\nplugin:\n    backtotop: '맨 위로'\n    visit_count: '%s회 방문'\n    visitor_count: '%s명의 사용자가 방문 함'\n    cookie_consent:\n        message: 이 웹 사이트는 귀하의 경험을 향상시키기 위해 Cookie를 사용합니다.\n        dismiss: 무시\n        allow: 허용\n        deny: 거부\n        link: 더 알아보기\n        policy: Cookie 정책\nsearch:\n    search: '검색'\n    hint: '입력 하세요...'\n    no_result: '에 대한 결과 없음'\n    untitled: '(제목 없음)'\n    empty_preview: '(미리보기 없음)'\n"
  },
  {
    "path": "languages/pl.yml",
    "content": "common:\n    archive:\n        one: 'Archiwum'\n        other: 'Archiwum'\n    category:\n        one: 'Kategoria'\n        other: 'Kategorie'\n    tag:\n        one: 'Tag'\n        other: 'Tagi'\n    post:\n        one: 'Artykuł'\n        other: 'Artykuły'\n    page:\n        one: 'Strona'\n        other: 'Strony'\n    prev: 'Poprzedni'\n    next: 'Następny'\nwidget:\n    follow: 'SUBSKRYBUJ'\n    recents: 'Najnowsze wpisy'\n    links: 'Linki'\n    catalogue: 'Spis treści'\n    subscribe_email: 'Zapisz się, aby otrzymywać aktualizacje'\n    subscribe: 'Subskrybuj'\n    adsense: 'Reklama'\n    followit: 'follow.it'\narticle:\n    created_at: 'Opublikowano&nbsp;%s'\n    updated_at: 'Zaktualizowano&nbsp;%s'\n    more: 'Czytaj dalej'\n    comments: 'Komentarze'\n    read_time: '%s czytania'\n    word_count:\n        one: 'Około %d słowa'\n        other: 'Około %d słów'\n    licensing:\n        author: 'Author'\n        created_at: 'Posted on'\n        updated_at: 'Updated on'\n        licensed_under: 'Licensed under'\ndonate:\n    title: 'Podoba Ci się ten artykuł? Wesprzyj autora za pomocą'\n    afdian: 'Afdian.net'\n    alipay: 'Alipay'\n    wechat: 'Wechat'\n    paypal: 'Paypal'\n    patreon: 'Patreon'\n    buymeacoffee: 'Kup mi kawę'\nplugin:\n    backtotop: 'Powrót do góry'\n    visit_count: '%s&nbsp;wizyty'\n    visitor_count: 'Odwiedzone przez %s użytkowników'\n    cookie_consent:\n      message: Ta strona korzysta z plików cookie, aby poprawić Twoje doświadczenia.\n      dismiss: Rozumiem!\n      allow: Zezwól na pliki cookie\n      deny: Odrzucać\n      link: Ucz się więcej\n      policy: Polityka Cookie\nsearch:\n    search: 'szukaj'\n    hint: 'Wpisz coś...'\n    no_result: 'Brak wyników dla'\n    untitled: '(Bez tytułu)'\n    empty_preview: '(Brak podglądu)'\n"
  },
  {
    "path": "languages/pt-BR.yml",
    "content": "common:\n    archive:\n        one: 'Arquivo'\n        other: 'Arquivos'\n    category:\n        one: 'Categoria'\n        other: 'Categorias'\n    tag:\n        one: 'Tag'\n        other: 'Tags'\n    post:\n        one: 'Artigo'\n        other: 'Artigos'\n    page:\n        one: 'Página'\n        other: 'Páginas'\n    prev: 'Anterior'\n    next: 'Próximo'\nwidget:\n    follow: 'Seguir'\n    recents: 'Recentes'\n    links: 'Links'\n    catalogue: 'Catálogo'\n    subscribe_email: 'Subscrição de atualizações'\n    subscribe: 'Se inscrever'\n    adsense: 'Anúncio'\n    followit: 'follow.it'\narticle:\n    created_at: 'Postado&nbsp;%s'\n    updated_at: 'Atualizado&nbsp;%s'\n    more: 'Ler Mais'\n    comments: 'Comentarios'\n    read_time: '%s lidos'\n    word_count:\n        one: 'Cerca de %d palavra'\n        other: 'Cerca de %d palavras'\n    licensing:\n        author: 'Author'\n        created_at: 'Posted on'\n        updated_at: 'Updated on'\n        licensed_under: 'Licensed under'\ndonate:\n    title: 'Gostou deste artigo? Apoie o autor com'\n    afdian: 'Afdian.net'\n    alipay: 'Alipay'\n    wechat: 'Wechat'\n    paypal: 'Paypal'\n    patreon: 'Patreon'\n    buymeacoffee: 'Me compra um café'\nplugin:\n    backtotop: 'De volta ao topo'\n    visit_count: '%s&nbsp;visitas'\n    visitor_count: 'Visitado por %s usuários'\n    cookie_consent:\n      message: Este site usa cookies para melhorar sua experiência.\n      dismiss: Entendi!\n      allow: Permitir cookies\n      deny: Declínio\n      link: Saber mais\n      policy: Política de Cookies\nsearch:\n    search: 'Procurar'\n    hint: 'Digite alguma coisa...'\n    no_result: 'Sem resultados para'\n    untitled: '(Sem título)'\n    empty_preview: '(Não há visualização)'\n"
  },
  {
    "path": "languages/ru.yml",
    "content": "common:\n    archive:\n        one: 'архив'\n        other: 'архивы'\n    category:\n        one: 'категории'\n        other: 'категории'\n    tag:\n        one: 'тег'\n        other: 'теги'\n    post:\n        one: 'пост'\n        other: 'посты'\n    page:\n        one: 'страница'\n        other: 'страницы'\n    prev: 'Назад'\n    next: 'Далее'\nwidget:\n    follow: 'Подписаться'\n    recents: 'недавние'\n    links: 'ссылки'\n    catalogue: 'Каталог'\n    subscribe_email: 'Подпишитесь на обновления'\n    subscribe: 'Подписывайся'\n    adsense: 'Рекламное объявление'\n    followit: 'follow.it'\narticle:\n    created_at: 'Опубликовано&nbsp;%s'\n    updated_at: 'Обновлено&nbsp;%s'\n    more: 'Читать дальше'\n    comments: 'Комментарии'\n    read_time: '%s на чтение'\n    word_count:\n        one: 'Около %d слова'\n        other: 'Примерно %d слова'\n    licensing:\n        author: 'Author'\n        created_at: 'Posted on'\n        updated_at: 'Updated on'\n        licensed_under: 'Licensed under'\ndonate:\n    title: 'Понравилась эта статья? Поддержите автора'\n    afdian: 'Afdian.net'\n    alipay: 'Alipay'\n    wechat: 'Wechat'\n    paypal: 'Paypal'\n    patreon: 'Patreon'\n    buymeacoffee: 'Купи мне кофе'\nplugin:\n    backtotop: 'Вернуться наверх'\n    visit_count: '%s&nbsp;посещения'\n    visitor_count: 'Посетили %s пользователя'\n    cookie_consent:\n      message: Этот веб-сайт использует файлы cookie для улучшения вашего опыта.\n      dismiss: Понял!\n      allow: Разрешить cookies\n      deny: Отказаться\n      link: Учить больше\n      policy: Политика Cookie\nsearch:\n    search: 'Поиск'\n    hint: 'Введите что-нибудь...'\n    no_result: 'Нет результатов по запросу'\n    untitled: '(Без названия)'\n    empty_preview: '(Нет предварительного просмотра)'\n"
  },
  {
    "path": "languages/sv.yml",
    "content": "common:\n    archive:\n        one: 'Arkiv'\n        other: 'Arkiv'\n    category:\n        one: 'Kategori'\n        other: 'Kategorier'\n    tag:\n        one: 'Etikett'\n        other: 'Etiketter'\n    post:\n        one: 'Inlägg'\n        other: 'Inlägg'\n    page:\n        one: 'Sida'\n        other: 'Sidor'\n    prev: 'Föregående'\n    next: 'Nästa'\nwidget:\n    follow: 'Följ'\n    recents: 'Senaste'\n    links: 'Länkar'\n    catalogue: 'Katalog'\n    subscribe_email: 'Prenumerera för uppdateringar'\n    subscribe: 'Prenumerera'\n    adsense: 'Marknadsföring'\n    followit: 'follow.it'\narticle:\n    created_at: 'Publicerad&nbsp;%s'\n    updated_at: 'Uppdaterad&nbsp;%s'\n    more: 'Läs mer'\n    comments: 'Kommentarer'\n    read_time: '%s lästid'\n    word_count:\n        one: 'Cirka %d ord'\n        other: 'Cirka %d ord'\n    licensing:\n        author: 'Författare'\n        created_at: 'Publicerad'\n        updated_at: 'Uppdaterad'\n        licensed_under: 'Licensierad under'\ndonate:\n    title: 'Tycker du om den här artikeln? Stöd författaren genom'\n    afdian: 'Afdian.net'\n    alipay: 'Alipay'\n    wechat: 'Wechat'\n    paypal: 'Paypal'\n    patreon: 'Patreon'\n    buymeacoffee: 'Köp mig en kaffe'\nplugin:\n    backtotop: 'Tillbaka till början'\n    visit_count: '%s&nbsp;besök'\n    visitor_count: 'Besökt av %s användare'\n    cookie_consent:\n      message: Den här hemsidan använder kakor för att förbättra funktionen.\n      dismiss: Jag förstår!\n      allow: Tillåt kakor\n      deny: Avböj kakor\n      link: Lär mer\n      policy: Kakpolicy\nsearch:\n    search: 'Sök'\n    hint: 'Skriv någonting...'\n    no_result: 'Inga sökresultat för'\n    untitled: '(Utan titel)'\n    empty_preview: '(Ingen förhandsvisning)'\n"
  },
  {
    "path": "languages/tk.yml",
    "content": "common:\n    archive:\n        one: 'Arhiw'\n        other: 'Arhiwler'\n    category:\n        one: 'Bölüm'\n        other: 'Bölümler'\n    tag:\n        one: 'Teg'\n        other: 'Tegler'\n    post:\n        one: 'Post'\n        other: 'Postlar'\n    page:\n        one: 'Sahypa'\n        other: 'Sahypalar'\n    prev: 'Öňki'\n    next: 'Indiki'\nwidget:\n    follow: 'Abuna bol'\n    recents: 'Täze habarlar'\n    links: 'Linkler'\n    catalogue: 'Katalog'\n    subscribe_email: 'Täzelikler üçin ýazyl'\n    subscribe: 'Ýazyl'\n    adsense: 'Mahabat'\n    followit: 'follow.it'\narticle:\n    created_at: 'Paýlaşyldy&nbsp;%s'\n    updated_at: 'Üýtgedildi&nbsp;%s'\n    more: 'Dowamy...'\n    comments: 'Kommentariýa'\n    read_time: '%s okaldy'\n    word_count:\n        one: 'Ortaça %d söz'\n        other: 'Ortaça %d söz'\n    licensing:\n        author: 'Awtor'\n        created_at: 'Paýlaşdy'\n        updated_at: 'Üýtgetdi'\n        licensed_under: 'Resmileşdirilen'\ndonate:\n    title: 'Haladynmy? Awtory gollaň'\n    afdian: 'Afdian.net'\n    alipay: 'Alipay'\n    wechat: 'Wechat'\n    paypal: 'Paypal'\n    patreon: 'Patreon'\n    buymeacoffee: 'Buy me a coffee'\nplugin:\n    backtotop: 'Ýokaryk'\n    visit_count: '%s&nbsp;görüldi'\n    visitor_count: '%s adam gördi'\n    cookie_consent:\n      message: Bu web saýt siziň üçin kuki ulanýar.\n      dismiss: Düşündim!\n      allow: Kukini kabul et!\n      deny: Närazylyk bildir\n      link: Dowamy...\n      policy: Kuki syýasaty\nsearch:\n    search: 'Gözle'\n    hint: 'Birzatlar ýazyň...'\n    no_result: 'Tapylmady'\n    untitled: 'Atlandyrylmadyk'\n    empty_preview: 'Boş'\n"
  },
  {
    "path": "languages/tr.yml",
    "content": "common:\n    archive:\n        one: 'Arşiv'\n        other: 'Arşivler'\n    category:\n        one: 'Kategori'\n        other: 'Kategoriler'\n    tag:\n        one: 'Etiket'\n        other: 'Etiketler'\n    post:\n        one: 'Gönderi'\n        other: 'Gönderiler'\n    page:\n        one: 'Sayfa'\n        other: 'Sayfalar'\n    prev: 'Önceki'\n    next: 'Sonraki'\nwidget:\n    follow: 'TAKİP ET'\n    recents: 'Son'\n    links: 'Linkler'\n    catalogue: 'Katalog'\n    subscribe_email: 'Güncellemeler için abone olun'\n    subscribe: 'Abone ol'\n    adsense: 'İlan'\n    followit: 'follow.it'\narticle:\n    created_at: '%s&nbsp;yayınlandı'\n    updated_at: '%s&nbsp;güncellendi'\n    more: 'Daha fazla oku'\n    comments: 'Yorumlar'\n    read_time: '%s okuma süresi'\n    word_count:\n        one: 'Yaklaşık %d kelime'\n        other: 'Yaklaşık %d kelime'\n    licensing:\n        author: 'Author'\n        created_at: 'Posted on'\n        updated_at: 'Updated on'\n        licensed_under: 'Licensed under'\ndonate:\n    title: 'Bu makaleyi beğendiniz mi? Yazarı şununla destekleyin'\n    afdian: 'Afdian.net'\n    alipay: 'Alipay'\n    wechat: 'Wechat'\n    paypal: 'Paypal'\n    patreon: 'Patreon'\n    buymeacoffee: 'Bana bir kahve al'\nplugin:\n    backtotop: 'Başa dönüş'\n    visit_count: '%s&nbsp;ziyaret'\n    visitor_count: '%s kullanıcı tarafından ziyaret edildi'\n    cookie_consent:\n      message: Bu web sitesi, deneyiminizi geliştirmek için çerezler kullanır.\n      dismiss: Anladım!\n      allow: Çerezlere izin ver\n      deny: Reddet\n      link: Daha fazla bilgi edin\n      policy: Çerez politikası\nsearch:\n    search: 'Ara'\n    hint: 'Bir şeyler yaz...'\n    no_result: 'İçin sonuç yok'\n    untitled: '(Başlıksız)'\n    empty_preview: '(Önizleme yok)'\n"
  },
  {
    "path": "languages/vn.yml",
    "content": "common:\n    archive:\n        one: 'Lưu trữ'\n        other: 'Lưu trữ'\n    category:\n        one: 'Thể loại'\n        other: 'Thể loại'\n    tag:\n        one: 'Nhãn'\n        other: 'Nhãn'\n    post:\n        one: 'Bài viết'\n        other: 'Bài viết'\n    page:\n        one: 'Trang'\n        other: 'Trang'\n    prev: 'Trước'\n    next: 'Sau'\nwidget:\n    follow: 'Theo dõi'\n    recents: 'Gần đây'\n    links: 'Link'\n    catalogue: 'Mục lục'\n    subscribe_email: 'Theo dõi các bản cập nhật'\n    subscribe: 'Theo dõi'\n    adsense: 'Quảng cáo'\n    followit: 'follow.it'\narticle:\n    created_at: 'Đã đăng&nbsp;%s'\n    updated_at: 'Đã cập nhật&nbsp;%s'\n    more: 'Đọc thêm'\n    comments: 'Bình luận'\n    read_time: '%s đọc'\n    word_count:\n        one: 'Khoảng %d từ'\n        other: 'Khoảng %d từ'\n    licensing:\n        author: 'Author'\n        created_at: 'Posted on'\n        updated_at: 'Updated on'\n        licensed_under: 'Licensed under'\ndonate:\n    title: 'Bạn đọc có thể ủng hộ blog qua'\n    afdian: 'Afdian.net'\n    alipay: 'Alipay'\n    wechat: 'Wechat'\n    paypal: 'Paypal'\n    patreon: 'Patreon'\n    buymeacoffee: 'Mua cho tôi một ly cà phê'\nplugin:\n    backtotop: 'Trở lai đầu trang'\n    visit_count: '%s&nbsp;Bạn đọc'\n    visitor_count: 'Thăm bởi %s bạn đọc'\n    cookie_consent:\n      message: Trang web này sử dụng cookie để cải thiện trải nghiệm của bạn.\n      dismiss: Hiểu rồi!\n      allow: Cho phép cookie\n      deny: Từ chối\n      link: Tìm hiểu thêm\n      policy: Chính sách Cookie\nsearch:\n    search: 'Tìm kiếm'\n    hint: 'Gõ gì đó...'\n    no_result: 'Không có kết quả cho'\n    untitled: '(Không có tiêu đề)'\n    empty_preview: '(Không có xem trước)'\n"
  },
  {
    "path": "languages/zh-CN.yml",
    "content": "common:\n    archive:\n        one: '归档'\n        other: '归档'\n    category:\n        one: '分类'\n        other: '分类'\n    tag:\n        one: '标签'\n        other: '标签'\n    post:\n        one: '文章'\n        other: '文章'\n    page:\n        one: '页面'\n        other: '页面'\n    prev: '上一页'\n    next: '下一页'\nwidget:\n    follow: '关注我'\n    recents: '最新文章'\n    links: '链接'\n    catalogue: '目录'\n    subscribe_email: '订阅更新'\n    subscribe: '订阅'\n    adsense: '广告'\n    followit: 'follow.it'\narticle:\n    created_at: '%s发表'\n    updated_at: '%s更新'\n    more: '阅读更多'\n    comments: '评论'\n    read_time: '%s读完'\n    word_count:\n        one: '大约%d个字'\n        other: '大约%d个字'\n    licensing:\n        author: '作者'\n        created_at: '发布于'\n        updated_at: '更新于'\n        licensed_under: '许可协议'\ndonate:\n    title: '喜欢这篇文章？打赏一下作者吧'\n    afdian: '爱发电'\n    alipay: '支付宝'\n    wechat: '微信'\n    paypal: 'Paypal'\n    patreon: 'Patreon'\n    buymeacoffee: '送我杯咖啡'\nplugin:\n    backtotop: '回到顶端'\n    visit_count: '%s次访问'\n    visitor_count: '共%s个访客'\n    cookie_consent:\n      message: 此网站使用Cookie来改善您的体验。\n      dismiss: 知道了！\n      allow: 允许使用Cookie\n      deny: 拒绝\n      link: 了解更多\n      policy: Cookie政策\nsearch:\n    search: '搜索'\n    hint: '想要查找什么...'\n    no_result: '未找到搜索结果'\n    untitled: '(无标题)'\n    empty_preview: '(无内容预览)'\n"
  },
  {
    "path": "languages/zh-TW.yml",
    "content": "common:\n    archive:\n        one: '彙整'\n        other: '彙整'\n    category:\n        one: '分類'\n        other: '分類'\n    tag:\n        one: '標籤'\n        other: '標籤'\n    post:\n        one: '文章'\n        other: '文章'\n    page:\n        one: '頁面'\n        other: '頁面'\n    prev: '上一頁'\n    next: '下一頁'\nwidget:\n    follow: '追蹤'\n    recents: '最新文章'\n    links: '連結'\n    catalogue: '文章目錄'\n    subscribe_email: '訂閱 Email'\n    subscribe: '訂閱'\n    adsense: '廣告'\n    followit: 'follow.it'\narticle:\n    created_at: '%s發表'\n    updated_at: '%s更新'\n    more: '繼續閱讀'\n    comments: '評論'\n    read_time: '%s讀完'\n    word_count:\n        one: '大約%d個字'\n        other: '大約%d個字'\n    licensing:\n        author: '作者'\n        created_at: '發表於'\n        updated_at: '更新於'\n        licensed_under: '許可協議'\ndonate:\n    title: '喜歡這篇文章嗎? 贊助一下作者吧!'\n    afdian: '愛發電'\n    alipay: '支付寶'\n    wechat: 'WeChat'\n    paypal: 'PayPal'\n    patreon: 'Patreon'\n    buymeacoffee: '送我杯咖啡'\nplugin:\n    backtotop: '回到頁首'\n    visit_count: '%s次訪問'\n    visitor_count: '共%s個訪客'\n    cookie_consent:\n      message: 此網站使用Cookie來改善您的體驗。\n      dismiss: 知道了！\n      allow: 允許使用Cookie\n      deny: 拒絕\n      link: 了解更多\n      policy: Cookie政策\nsearch:\n    search: '搜尋'\n    hint: '請輸入關鍵字...'\n    no_result: '未找到搜索結果'\n    untitled: '(無標題)'\n    empty_preview: '(無內容預覽)'\n"
  },
  {
    "path": "layout/archive.jsx",
    "content": "const moment = require('moment');\nconst { Component, Fragment } = require('inferno');\nconst { toMomentLocale } = require('hexo/dist/plugins/helper/date');\nconst Paginator = require('hexo-component-inferno/lib/view/misc/paginator');\nconst ArticleMedia = require('hexo-component-inferno/lib/view/common/article_media');\n\nmodule.exports = class extends Component {\n    render() {\n        const { config, page, helper } = this.props;\n        const { url_for, __, date_xml, date } = helper;\n\n        const language = toMomentLocale(page.lang || page.language || config.language);\n\n        function renderArticleList(posts, year, month = null) {\n            const time = moment([page.year, page.month ? page.month - 1 : null].filter(i => i !== null));\n\n            return <div class=\"card\">\n                <div class=\"card-content\">\n                    <h3 class=\"tag is-primary\">{month === null ? year : time.locale(language).format('MMMM YYYY')}</h3>\n                    <div class=\"timeline\">\n                        {posts.map(post => {\n                            const categories = post.categories.map(category => ({\n                                url: url_for(category.path),\n                                name: category.name\n                            }));\n                            return <ArticleMedia\n                                url={url_for(post.link || post.path)}\n                                title={post.title}\n                                date={date(post.date)}\n                                dateXml={date_xml(post.date)}\n                                categories={categories}\n                                thumbnail={post.thumbnail ? url_for(post.thumbnail) : null} />;\n                        })}\n                    </div>\n                </div>\n            </div>;\n        }\n\n        let articleList;\n        if (!page.year) {\n            const years = {};\n            page.posts.each(p => { years[p.date.year()] = null; });\n            articleList = Object.keys(years).sort((a, b) => b - a).map(year => {\n                const posts = page.posts.filter(p => p.date.year() === parseInt(year, 10));\n                return renderArticleList(posts, year, null);\n            });\n        } else {\n            articleList = renderArticleList(page.posts, page.year, page.month);\n        }\n\n        return <Fragment>\n            {articleList}\n            {page.total > 1 ? <Paginator\n                current={page.current}\n                total={page.total}\n                baseUrl={page.base}\n                path={config.pagination_dir}\n                urlFor={url_for}\n                prevTitle={__('common.prev')}\n                nextTitle={__('common.next')} /> : null}\n        </Fragment>;\n    }\n};\n"
  },
  {
    "path": "layout/categories.jsx",
    "content": "const { Component } = require('inferno');\nconst Categories = require('hexo-component-inferno/lib/view/widget/categories');\n\nmodule.exports = class extends Component {\n    render() {\n        const { site, page, helper } = this.props;\n\n        return <Categories.Cacheable site={site} page={page} helper={helper} />;\n    }\n};\n"
  },
  {
    "path": "layout/category.jsx",
    "content": "const { Component, Fragment } = require('inferno');\nconst Index = require('./index');\n\nmodule.exports = class extends Component {\n    render() {\n        const { config, page, helper } = this.props;\n        const { url_for, _p } = helper;\n\n        return <Fragment>\n            <div class=\"card\">\n                <div class=\"card-content\">\n                    <nav class=\"breadcrumb\" aria-label=\"breadcrumbs\">\n                        <ul>\n                            <li><a href={url_for('/categories/')}>{_p('common.category', Infinity)}</a></li>\n                            {page.parents.map(category => {\n                                return <li><a href={url_for(category.path)}>{category.name}</a></li>;\n                            })}\n                            <li class=\"is-active\"><a href=\"#\" aria-current=\"page\">{page.category}</a></li>\n                        </ul>\n                    </nav>\n                </div>\n            </div>\n            <Index config={config} page={page} helper={helper} />\n        </Fragment>;\n    }\n};\n"
  },
  {
    "path": "layout/comment/.gitkeep",
    "content": ""
  },
  {
    "path": "layout/common/article.jsx",
    "content": "const moment = require('moment');\nconst { Component, Fragment } = require('inferno');\nconst { toMomentLocale } = require('hexo/dist/plugins/helper/date');\nconst Share = require('./share');\nconst Donates = require('./donates');\nconst Comment = require('./comment');\nconst ArticleLicensing = require('hexo-component-inferno/lib/view/misc/article_licensing');\n\n/**\n * Get the word count of text.\n */\nfunction getWordCount(content) {\n    if (typeof content === 'undefined') {\n        return 0;\n    }\n    content = content.replace(/<\\/?[a-z][^>]*>/gi, '');\n    content = content.trim();\n    return content ? (content.match(/[\\u00ff-\\uffff]|[a-zA-Z]+/g) || []).length : 0;\n}\n\nmodule.exports = class extends Component {\n    render() {\n        const { config, helper, page, index } = this.props;\n        const { article, plugins } = config;\n        const { url_for, date, date_xml, __, _p } = helper;\n\n        const defaultLanguage = Array.isArray(config.language) && config.language.length ? config.language[0] : config.language;\n\n        const indexLanguage = toMomentLocale(defaultLanguage || 'en');\n        const language = toMomentLocale(page.lang || page.language || defaultLanguage || 'en');\n        const cover = page.cover ? url_for(page.cover) : null;\n        const updateTime = article && article.update_time !== undefined ? article.update_time : true;\n        const isUpdated = page.updated && !moment(page.date).isSame(moment(page.updated));\n        const shouldShowUpdated = page.updated && ((updateTime === 'auto' && isUpdated) || updateTime === true);\n\n        return <Fragment>\n            {/* Main content */}\n            <div class=\"card\">\n                {/* Thumbnail */}\n                {cover ? <div class=\"card-image\">\n                    {index ? <a href={url_for(page.link || page.path)} class=\"image is-7by3\">\n                        <img class=\"fill\" src={cover} alt={page.title || cover} />\n                    </a> : <span class=\"image is-7by3\">\n                        <img class=\"fill\" src={cover} alt={page.title || cover} />\n                    </span>}\n                </div> : null}\n                <article class={`card-content article${'direction' in page ? ' ' + page.direction : ''}`} role=\"article\">\n                    {/* Metadata */}\n                    {page.layout !== 'page' ? <div class=\"article-meta is-size-7 is-uppercase level is-mobile\">\n                        <div class=\"level-left\">\n                            {/* PIN Icon */}\n                            {page.top ? <i class=\"fas fa-thumbtack level-item\" title=\"Pinned\"></i> : null}\n                            {/* Creation Date */}\n                            {page.date && <span class=\"level-item\" dangerouslySetInnerHTML={{\n                                __html: _p('article.created_at', `<time dateTime=\"${date_xml(page.date)}\" title=\"${new Date(page.date).toLocaleString()}\">${date(page.date)}</time>`)\n                            }}></span>}\n                            {/* Last Update Date */}\n                            {shouldShowUpdated && <span class=\"level-item\" dangerouslySetInnerHTML={{\n                                __html: _p('article.updated_at', `<time dateTime=\"${date_xml(page.updated)}\" title=\"${new Date(page.updated).toLocaleString()}\">${date(page.updated)}</time>`)\n                            }}></span>}\n                            {/* author */}\n                            {page.author ? <span class=\"level-item\"> {page.author} </span> : null}\n                            {/* Categories */}\n                            {page.categories && page.categories.length ? <span class=\"level-item\">\n                                {(() => {\n                                    const categories = [];\n                                    page.categories.forEach((category, i) => {\n                                        categories.push(<a class=\"link-muted\" href={url_for(category.path)}>{category.name}</a>);\n                                        if (i < page.categories.length - 1) {\n                                            categories.push(<span>&nbsp;/&nbsp;</span>);\n                                        }\n                                    });\n                                    return categories;\n                                })()}\n                            </span> : null}\n                            {/* Read time */}\n                            {article && article.readtime && article.readtime === true ? <span class=\"level-item\">\n                                {(() => {\n                                    const words = getWordCount(page._content);\n                                    const time = moment.duration((words / 150.0) * 60, 'seconds');\n                                    return `${_p('article.read_time', time.locale(index ? indexLanguage : language).humanize())} (${_p('article.word_count', words)})`;\n                                })()}\n                            </span> : null}\n                            {/* Visitor counter */}\n                            {!index && plugins && plugins.busuanzi === true ? <span class=\"level-item\" id=\"busuanzi_container_page_pv\" dangerouslySetInnerHTML={{\n                                __html: _p('plugin.visit_count', '<span id=\"busuanzi_value_page_pv\">0</span>')\n                            }}></span> : null}\n                        </div>\n                    </div> : null}\n                    {/* Title */}\n                    {page.title !== '' && index ? <p class=\"title is-3 is-size-4-mobile\"><a class=\"link-muted\" href={url_for(page.link || page.path)}>{page.title}</a></p> : null}\n                    {page.title !== '' && !index ? <h1 class=\"title is-3 is-size-4-mobile\">{page.title}</h1> : null}\n                    {/* Content/Excerpt */}\n                    <div class=\"content\" dangerouslySetInnerHTML={{ __html: index && page.excerpt ? page.excerpt : page.content }}></div>\n                    {/* Licensing block */}\n                    {!index && article && article.licenses && Object.keys(article.licenses)\n                        ? <ArticleLicensing.Cacheable page={page} config={config} helper={helper} /> : null}\n                    {/* Tags */}\n                    {!index && page.tags && page.tags.length ? <div class=\"article-tags is-size-7 mb-4\">\n                        <span class=\"mr-2\">#</span>\n                        {page.tags.map(tag => {\n                            return <a class=\"link-muted mr-2\" rel=\"tag\" href={url_for(tag.path)}>{tag.name}</a>;\n                        })}\n                    </div> : null}\n                    {/* \"Read more\" button */}\n                    {index && page.excerpt ? <a class=\"article-more button is-small is-size-7\" href={`${url_for(page.link || page.path)}#more`}>{__('article.more')}</a> : null}\n                    {/* Share button */}\n                    {!index ? <Share config={config} page={page} helper={helper} /> : null}\n                </article>\n            </div>\n            {/* Donate button */}\n            {!index ? <Donates config={config} helper={helper} /> : null}\n            {/* Post navigation */}\n            {!index && (page.prev || page.next) ? <nav class=\"post-navigation mt-4 level is-mobile\">\n                {page.prev ? <div class=\"level-start\">\n                    <a class={`article-nav-prev level level-item${!page.prev ? ' is-hidden-mobile' : ''} link-muted`} href={url_for(page.prev.path)}>\n                        <i class=\"level-item fas fa-chevron-left\"></i>\n                        <span class=\"level-item\">{page.prev.title}</span>\n                    </a>\n                </div> : null}\n                {page.next ? <div class=\"level-end\">\n                    <a class={`article-nav-next level level-item${!page.next ? ' is-hidden-mobile' : ''} link-muted`} href={url_for(page.next.path)}>\n                        <span class=\"level-item\">{page.next.title}</span>\n                        <i class=\"level-item fas fa-chevron-right\"></i>\n                    </a>\n                </div> : null}\n            </nav> : null}\n            {/* Comment */}\n            {!index ? <Comment config={config} page={page} helper={helper} /> : null}\n        </Fragment>;\n    }\n};\n"
  },
  {
    "path": "layout/common/comment.jsx",
    "content": "const createLogger = require('hexo-log');\nconst { Component } = require('inferno');\nconst view = require('hexo-component-inferno/lib/core/view');\n\nconst logger = createLogger.default();\n\nmodule.exports = class extends Component {\n    render() {\n        const { config, page, helper } = this.props;\n        const { __ } = helper;\n        const { comment } = config;\n        if (!comment || typeof comment.type !== 'string') {\n            return null;\n        }\n\n        return <div class=\"card\" id=\"comments\">\n            <div class=\"card-content\">\n                <h3 class=\"title is-5\">{__('article.comments')}</h3>\n                {(() => {\n                    try {\n                        let Comment = view.require('comment/' + comment.type);\n                        Comment = Comment.Cacheable ? Comment.Cacheable : Comment;\n                        return <Comment config={config} page={page} helper={helper} comment={comment} />;\n                    } catch (e) {\n                        logger.w(`Icarus cannot load comment \"${comment.type}\"`);\n                        return null;\n                    }\n                })()}\n            </div>\n        </div>;\n    }\n};\n"
  },
  {
    "path": "layout/common/donates.jsx",
    "content": "const createLogger = require('hexo-log');\nconst { Component } = require('inferno');\nconst view = require('hexo-component-inferno/lib/core/view');\n\nconst logger = createLogger.default();\n\nmodule.exports = class extends Component {\n    render() {\n        const { config, helper } = this.props;\n        const { __ } = helper;\n        const { donates = [] } = config;\n        if (!Array.isArray(donates) || !donates.length) {\n            return null;\n        }\n        return <div class=\"card\">\n            <div class=\"card-content\">\n                <h3 class=\"menu-label has-text-centered\">{__('donate.title')}</h3>\n                <div class=\"buttons is-centered\">\n                    {donates.map(service => {\n                        const type = service.type;\n                        if (typeof type === 'string') {\n                            try {\n                                let Donate = view.require('donate/' + type);\n                                Donate = Donate.Cacheable ? Donate.Cacheable : Donate;\n                                return <Donate helper={helper} donate={service} />;\n                            } catch (e) {\n                                logger.w(`Icarus cannot load donate button \"${type}\"`);\n                            }\n                        }\n                        return null;\n                    })}\n                </div>\n            </div>\n        </div>;\n    }\n};\n"
  },
  {
    "path": "layout/common/footer.jsx",
    "content": "const { Component } = require('inferno');\nconst { cacheComponent } = require('hexo-component-inferno/lib/util/cache');\n\nclass Footer extends Component {\n    render() {\n        const {\n            logo,\n            logoUrl,\n            siteUrl,\n            siteTitle,\n            siteYear,\n            author,\n            links,\n            copyright,\n            showVisitorCounter,\n            visitorCounterTitle\n        } = this.props;\n\n        let footerLogo = '';\n        if (logo) {\n            if (logo.text) {\n                footerLogo = logo.text;\n            } else {\n                footerLogo = <img src={logoUrl} alt={siteTitle} height=\"28\" />;\n            }\n        } else {\n            footerLogo = siteTitle;\n        }\n\n        return <footer class=\"footer\">\n            <div class=\"container\">\n                <div class=\"level\">\n                    <div class=\"level-start\">\n                        <a class=\"footer-logo is-block mb-2\" href={siteUrl}>\n                            {footerLogo}\n                        </a>\n                        <p class=\"is-size-7\">\n                            <span dangerouslySetInnerHTML={{ __html: `&copy; ${siteYear} ${author || siteTitle}` }}></span>\n                            &nbsp;&nbsp;Powered by <a href=\"https://hexo.io/\" target=\"_blank\" rel=\"noopener\">Hexo</a>&nbsp;&&nbsp;\n                            <a href=\"https://github.com/ppoffice/hexo-theme-icarus\" target=\"_blank\" rel=\"noopener\">Icarus</a>\n                            {showVisitorCounter ? <br /> : null}\n                            {showVisitorCounter ? <span id=\"busuanzi_container_site_uv\"\n                                dangerouslySetInnerHTML={{ __html: visitorCounterTitle }}></span> : null}\n                        </p>\n                        {copyright ? <p class=\"is-size-7\" dangerouslySetInnerHTML={{ __html: copyright }}></p> : null}\n                    </div>\n                    <div class=\"level-end\">\n                        {Object.keys(links).length ? <div class=\"field has-addons\">\n                            {Object.keys(links).map(name => {\n                                const link = links[name];\n                                return <p class=\"control\">\n                                    <a class={`button is-transparent ${link.icon ? 'is-large' : ''}`} target=\"_blank\" rel=\"noopener\" title={name} href={link.url}>\n                                        {link.icon ? <i class={link.icon}></i> : name}\n                                    </a>\n                                </p>;\n                            })}\n                        </div> : null}\n                    </div>\n                </div>\n            </div>\n        </footer>;\n    }\n}\n\nmodule.exports = cacheComponent(Footer, 'common.footer', props => {\n    const { config, helper } = props;\n    const { url_for, _p, date } = helper;\n    const { logo, title, author, footer, plugins } = config;\n\n    const links = {};\n    if (footer && footer.links) {\n        Object.keys(footer.links).forEach(name => {\n            const link = footer.links[name];\n            links[name] = {\n                url: url_for(typeof link === 'string' ? link : link.url),\n                icon: link.icon\n            };\n        });\n    }\n\n    return {\n        logo,\n        logoUrl: url_for(logo),\n        siteUrl: url_for('/'),\n        siteTitle: title,\n        siteYear: date(new Date(), 'YYYY'),\n        author,\n        links,\n        copyright: footer?.copyright ?? '',\n        showVisitorCounter: plugins && plugins.busuanzi === true,\n        visitorCounterTitle: _p('plugin.visitor_count', '<span id=\"busuanzi_value_site_uv\">0</span>')\n    };\n});\n"
  },
  {
    "path": "layout/common/head.jsx",
    "content": "const { Component } = require('inferno');\nconst MetaTags = require('hexo-component-inferno/lib/view/misc/meta');\nconst WebApp = require('hexo-component-inferno/lib/view/misc/web_app');\nconst OpenGraph = require('hexo-component-inferno/lib/view/misc/open_graph');\nconst StructuredData = require('hexo-component-inferno/lib/view/misc/structured_data');\nconst Plugins = require('./plugins');\n\nfunction getPageTitle(page, siteTitle, helper) {\n    let title = page.title;\n\n    if (helper.is_archive()) {\n        title = helper._p('common.archive', Infinity);\n        if (helper.is_month()) {\n            title += ': ' + page.year + '/' + page.month;\n        } else if (helper.is_year()) {\n            title += ': ' + page.year;\n        }\n    } else if (helper.is_category()) {\n        title = helper._p('common.category', 1) + ': ' + page.category;\n    } else if (helper.is_tag()) {\n        title = helper._p('common.tag', 1) + ': ' + page.tag;\n    } else if (helper.is_categories()) {\n        title = helper._p('common.category', Infinity);\n    } else if (helper.is_tags()) {\n        title = helper._p('common.tag', Infinity);\n    }\n\n    return [title, siteTitle].filter(str => typeof str !== 'undefined' && str.trim() !== '').join(' - ');\n}\n\nmodule.exports = class extends Component {\n    render() {\n        const { site, config, helper, page } = this.props;\n        const { url_for, cdn, fontcdn, iconcdn, is_post } = helper;\n        const {\n            url,\n            head = {},\n            article,\n            highlight,\n            variant = 'default'\n        } = config;\n        const {\n            meta = [],\n            manifest = {},\n            open_graph = {},\n            structured_data = {},\n            canonical_url = page.permalink,\n            rss,\n            favicon\n        } = head;\n\n        const noIndex = helper.is_archive() || helper.is_category() || helper.is_tag();\n\n        const language = page.lang || page.language || config.language;\n        const fontCssUrl = {\n            default: fontcdn('Ubuntu:wght@400;600&family=Source+Code+Pro', 'css2'),\n            cyberpunk: fontcdn('Oxanium:wght@300;400;600&family=Roboto+Mono', 'css2')\n        };\n\n        let hlTheme, images;\n        if (highlight && highlight.enable === false) {\n            hlTheme = null;\n        } else if (article && article.highlight && article.highlight.theme) {\n            hlTheme = article.highlight.theme;\n        } else {\n            hlTheme = 'atom-one-light';\n        }\n\n        if (typeof page.og_image === 'string') {\n            images = [page.og_image];\n        } else if (typeof page.cover === 'string') {\n            images = [url_for(page.cover)];\n        } else if (typeof page.thumbnail === 'string') {\n            images = [url_for(page.thumbnail)];\n        } else if (article && typeof article.og_image === 'string') {\n            images = [article.og_image];\n        } else if (page.content && page.content.includes('<img')) {\n            let img;\n            images = [];\n            const imgPattern = /<img [^>]*src=['\"]([^'\"]+)([^>]*>)/gi;\n            while ((img = imgPattern.exec(page.content)) !== null) {\n                images.push(img[1]);\n            }\n        } else {\n            images = [url_for('/img/og_image.png')];\n        }\n\n        let adsenseClientId = null;\n        if (Array.isArray(config.widgets)) {\n            const widget = config.widgets.find(widget => widget.type === 'adsense');\n            if (widget) {\n                adsenseClientId = widget.client_id;\n            }\n        }\n\n        let openGraphImages = images;\n        if ((typeof open_graph === 'object' && open_graph !== null)\n            && ((Array.isArray(open_graph.image) && open_graph.image.length > 0) || typeof open_graph.image === 'string')) {\n            openGraphImages = open_graph.image;\n        } else if ((Array.isArray(page.photos) && page.photos.length > 0) || typeof page.photos === 'string') {\n            openGraphImages = page.photos;\n        }\n\n        let structuredImages = images;\n        if ((typeof structured_data === 'object' && structured_data !== null)\n            && ((Array.isArray(structured_data.image) && structured_data.image.length > 0) || typeof structured_data.image === 'string')) {\n            structuredImages = structured_data.image;\n        } else if ((Array.isArray(page.photos) && page.photos.length > 0) || typeof page.photos === 'string') {\n            structuredImages = page.photos;\n        }\n\n        let followItVerificationCode = null;\n        if (Array.isArray(config.widgets)) {\n            const widget = config.widgets.find(widget => widget.type === 'followit');\n            if (widget) {\n                followItVerificationCode = widget.verification_code;\n            }\n        }\n\n        return <head>\n            <meta charset=\"utf-8\" />\n            <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1\" />\n            {noIndex ? <meta name=\"robots\" content=\"noindex\" /> : null}\n            {meta && meta.length ? <MetaTags meta={meta} /> : null}\n\n            <title>{getPageTitle(page, config.title, helper)}</title>\n\n            <WebApp.Cacheable\n                helper={helper}\n                favicon={favicon}\n                icons={manifest.icons}\n                themeColor={manifest.theme_color}\n                name={manifest.name || config.title} />\n\n            {typeof open_graph === 'object' && open_graph !== null ? <OpenGraph\n                type={open_graph.type || (is_post(page) ? 'article' : 'website')}\n                title={open_graph.title || page.title || config.title}\n                date={page.date}\n                updated={page.updated}\n                author={open_graph.author || config.author}\n                description={open_graph.description || page.description || page.excerpt || page.content || config.description}\n                keywords={(page.tags && page.tags.length ? page.tags : undefined) || config.keywords}\n                url={open_graph.url || page.permalink || url}\n                images={openGraphImages}\n                siteName={open_graph.site_name || config.title}\n                language={language}\n                twitterId={open_graph.twitter_id}\n                twitterCard={open_graph.twitter_card}\n                twitterSite={open_graph.twitter_site}\n                googlePlus={open_graph.google_plus}\n                facebookAdmins={open_graph.fb_admins}\n                facebookAppId={open_graph.fb_app_id} /> : null}\n\n            {typeof structured_data === 'object' && structured_data !== null ? <StructuredData\n                title={structured_data.title || page.title || config.title}\n                description={structured_data.description || page.description || page.excerpt || page.content || config.description}\n                url={structured_data.url || page.permalink || url}\n                author={structured_data.author || config.author}\n                publisher={structured_data.publisher || config.title}\n                publisherLogo={structured_data.publisher_logo || config.logo}\n                date={page.date}\n                updated={page.updated}\n                images={structuredImages} /> : null}\n\n            {canonical_url ? <link rel=\"canonical\" href={canonical_url} /> : null}\n            {rss ? <link rel=\"alternate\" href={url_for(rss)} title={config.title} type=\"application/atom+xml\" /> : null}\n            {favicon ? <link rel=\"icon\" href={url_for(favicon)} /> : null}\n            <link rel=\"stylesheet\" href={iconcdn()} />\n            {hlTheme ? <link data-pjax rel=\"stylesheet\" href={cdn('highlight.js', '11.7.0', 'styles/' + hlTheme + '.css')} /> : null}\n            <link rel=\"stylesheet\" href={fontCssUrl[variant]} />\n            <link data-pjax rel=\"stylesheet\" href={url_for('/css/' + variant + '.css')} />\n            <Plugins site={site} config={config} helper={helper} page={page} head={true} />\n\n            {adsenseClientId ? <script data-ad-client={adsenseClientId}\n                src=\"https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js\" async></script> : null}\n\n            {followItVerificationCode ? <meta name=\"follow.it-verification-code\" content={followItVerificationCode} /> : null}\n        </head>;\n    }\n};\n"
  },
  {
    "path": "layout/common/navbar.jsx",
    "content": "const { Component, Fragment } = require('inferno');\nconst { cacheComponent } = require('hexo-component-inferno/lib/util/cache');\nconst classname = require('hexo-component-inferno/lib/util/classname');\n\nfunction isSameLink(a, b) {\n    function santize(url) {\n        let paths = url.replace(/(^\\w+:|^)\\/\\//, '').split('#')[0].split('/').filter(p => p.trim() !== '');\n        if (paths.length > 0 && paths[paths.length - 1].trim() === 'index.html') {\n            paths = paths.slice(0, paths.length - 1);\n        }\n        return paths.join('/');\n    }\n    return santize(a) === santize(b);\n}\n\nclass Navbar extends Component {\n    render() {\n        const {\n            logo,\n            logoUrl,\n            siteUrl,\n            siteTitle,\n            menu,\n            links,\n            showToc,\n            tocTitle,\n            showSearch,\n            searchTitle\n        } = this.props;\n\n        let navbarLogo = '';\n        if (logo) {\n            if (logo.text) {\n                navbarLogo = logo.text;\n            } else {\n                navbarLogo = <img src={logoUrl} alt={siteTitle} height=\"28\" />;\n            }\n        } else {\n            navbarLogo = siteTitle;\n        }\n\n        return <nav class=\"navbar navbar-main\">\n            <div class=\"container navbar-container\">\n                <div class=\"navbar-brand justify-content-center\">\n                    <a class=\"navbar-item navbar-logo\" href={siteUrl}>\n                        {navbarLogo}\n                    </a>\n                </div>\n                <div class=\"navbar-menu\">\n                    {Object.keys(menu).length ? <div class=\"navbar-start\">\n                        {Object.keys(menu).map(name => {\n                            const item = menu[name];\n                            return <a class={classname({ 'navbar-item': true, 'is-active': item.active })} href={item.url}>{name}</a>;\n                        })}\n                    </div> : null}\n                    <div class=\"navbar-end\">\n                        {Object.keys(links).length ? <Fragment>\n                            {Object.keys(links).map(name => {\n                                const link = links[name];\n                                return <a class=\"navbar-item\" target=\"_blank\" rel=\"noopener\" title={name} href={link.url}>\n                                    {link.icon ? <i class={link.icon}></i> : name}\n                                </a>;\n                            })}\n                        </Fragment> : null}\n                        {showToc ? <a class=\"navbar-item is-hidden-tablet catalogue\" title={tocTitle} href=\"javascript:;\">\n                            <i class=\"fas fa-list-ul\"></i>\n                        </a> : null}\n                        {showSearch ? <a class=\"navbar-item search\" title={searchTitle} href=\"javascript:;\">\n                            <i class=\"fas fa-search\"></i>\n                        </a> : null}\n                    </div>\n                </div>\n            </div>\n        </nav>;\n    }\n}\n\nmodule.exports = cacheComponent(Navbar, 'common.navbar', props => {\n    const { config, helper, page } = props;\n    const { url_for, _p, __ } = helper;\n    const { logo, title, navbar, widgets, search } = config;\n\n    const hasTocWidget = Array.isArray(widgets) && widgets.find(widget => widget.type === 'toc');\n    const showToc = (config.toc === true || page.toc) && hasTocWidget && ['page', 'post'].includes(page.layout);\n\n    const menu = {};\n    if (navbar && navbar.menu) {\n        const pageUrl = typeof page.path !== 'undefined' ? url_for(page.path) : '';\n        Object.keys(navbar.menu).forEach(name => {\n            const url = url_for(navbar.menu[name]);\n            const active = isSameLink(url, pageUrl);\n            menu[name] = { url, active };\n        });\n    }\n\n    const links = {};\n    if (navbar && navbar.links) {\n        Object.keys(navbar.links).forEach(name => {\n            const link = navbar.links[name];\n            links[name] = {\n                url: url_for(typeof link === 'string' ? link : link.url),\n                icon: link.icon\n            };\n        });\n    }\n\n    return {\n        logo,\n        logoUrl: url_for(logo),\n        siteUrl: url_for('/'),\n        siteTitle: title,\n        menu,\n        links,\n        showToc,\n        tocTitle: _p('widget.catalogue', Infinity),\n        showSearch: search && search.type,\n        searchTitle: __('search.search')\n    };\n});\n"
  },
  {
    "path": "layout/common/plugins.jsx",
    "content": "const createLogger = require('hexo-log');\nconst { Component, Fragment } = require('inferno');\nconst view = require('hexo-component-inferno/lib/core/view');\n\nconst logger = createLogger.default();\n\nmodule.exports = class extends Component {\n    render() {\n        const { site, config, page, helper, head } = this.props;\n        const { plugins = [] } = config;\n\n        return <Fragment>\n            {Object.keys(plugins).map(name => {\n                // plugin is not enabled\n                if (!plugins[name]) {\n                    return null;\n                }\n                try {\n                    let Plugin = view.require('plugin/' + name);\n                    Plugin = Plugin.Cacheable ? Plugin.Cacheable : Plugin;\n                    return <Plugin site={site} config={config} page={page} helper={helper} plugin={plugins[name]} head={head} />;\n                } catch (e) {\n                    logger.w(`Icarus cannot load plugin \"${name}\"`);\n                    return null;\n                }\n            })}\n        </Fragment>;\n    }\n};\n"
  },
  {
    "path": "layout/common/scripts.jsx",
    "content": "const { Component, Fragment } = require('inferno');\nconst { toMomentLocale } = require('hexo/dist/plugins/helper/date');\nconst Plugins = require('./plugins');\n\nmodule.exports = class extends Component {\n    render() {\n        const { site, config, helper, page } = this.props;\n        const { url_for, cdn } = helper;\n        const { article } = config;\n        const language = toMomentLocale(page.lang || page.language || config.language || 'en');\n\n        let fold = 'unfolded';\n        let clipboard = true;\n        if (article && article.highlight) {\n            if (typeof article.highlight.clipboard !== 'undefined') {\n                clipboard = !!article.highlight.clipboard;\n            }\n            if (typeof article.highlight.fold === 'string') {\n                fold = article.highlight.fold;\n            }\n        }\n\n        const embeddedConfig = `var IcarusThemeSettings = {\n            article: {\n                highlight: {\n                    clipboard: ${clipboard},\n                    fold: '${fold}'\n                }\n            }\n        };`;\n\n        return <Fragment>\n            <script src={cdn('jquery', '3.3.1', 'dist/jquery.min.js')}></script>\n            <script src={cdn('moment', '2.22.2', 'min/moment-with-locales.min.js')}></script>\n            {clipboard && <script src={cdn('clipboard', '2.0.4', 'dist/clipboard.min.js')} defer></script>}\n            <script dangerouslySetInnerHTML={{ __html: `moment.locale(\"${language}\");` }}></script>\n            <script dangerouslySetInnerHTML={{ __html: embeddedConfig }}></script>\n            <script data-pjax src={url_for('/js/column.js')}></script>\n            <Plugins site={site} config={config} page={page} helper={helper} head={false} />\n            <script data-pjax src={url_for('/js/main.js')} defer></script>\n        </Fragment>;\n    }\n};\n"
  },
  {
    "path": "layout/common/search.jsx",
    "content": "const createLogger = require('hexo-log');\nconst { Component } = require('inferno');\nconst view = require('hexo-component-inferno/lib/core/view');\n\nconst logger = createLogger.default();\n\nmodule.exports = class extends Component {\n    render() {\n        const { config, helper } = this.props;\n        const { search } = config;\n        if (!search || typeof search.type !== 'string') {\n            return null;\n        }\n\n        try {\n            let Search = view.require('search/' + search.type);\n            Search = Search.Cacheable ? Search.Cacheable : Search;\n            return <Search config={config} helper={helper} search={search} />;\n        } catch (e) {\n            logger.w(`Icarus cannot load search \"${search.type}\"`);\n            return null;\n        }\n    }\n};\n"
  },
  {
    "path": "layout/common/share.jsx",
    "content": "const createLogger = require('hexo-log');\nconst { Component } = require('inferno');\nconst view = require('hexo-component-inferno/lib/core/view');\n\nconst logger = createLogger.default();\n\nmodule.exports = class extends Component {\n    render() {\n        const { config, page, helper } = this.props;\n        const { share } = config;\n        if (!share || typeof share.type !== 'string') {\n            return null;\n        }\n\n        try {\n            let Share = view.require('share/' + share.type);\n            Share = Share.Cacheable ? Share.Cacheable : Share;\n            return <Share config={config} page={page} helper={helper} share={share} />;\n        } catch (e) {\n            logger.w(`Icarus cannot load share button \"${share.type}\"`);\n            return null;\n        }\n    }\n};\n"
  },
  {
    "path": "layout/common/widgets.jsx",
    "content": "const createLogger = require('hexo-log');\nconst { Component } = require('inferno');\nconst view = require('hexo-component-inferno/lib/core/view');\nconst classname = require('hexo-component-inferno/lib/util/classname');\n\nconst logger = createLogger.default();\n\nfunction formatWidgets(widgets) {\n    const result = {};\n    if (Array.isArray(widgets)) {\n        widgets.filter(widget => typeof widget === 'object').forEach(widget => {\n            if ('position' in widget && (widget.position === 'left' || widget.position === 'right')) {\n                if (!(widget.position in result)) {\n                    result[widget.position] = [widget];\n                } else {\n                    result[widget.position].push(widget);\n                }\n            }\n        });\n    }\n    return result;\n}\n\nfunction hasColumn(widgets, position, config, page) {\n    const showToc = (config.toc === true) && ['page', 'post'].includes(page.layout);\n    if (Array.isArray(widgets)) {\n        return typeof widgets.find(widget => {\n            if (widget.type === 'toc' && !showToc) {\n                return false;\n            }\n            return widget.position === position;\n        }) !== 'undefined';\n    }\n    return false;\n}\n\nfunction getColumnCount(widgets, config, page) {\n    return [hasColumn(widgets, 'left', config, page), hasColumn(widgets, 'right', config, page)].filter(v => !!v).length + 1;\n}\n\nfunction getColumnSizeClass(columnCount) {\n    switch (columnCount) {\n        case 2:\n            return 'is-4-tablet is-4-desktop is-4-widescreen';\n        case 3:\n            return 'is-4-tablet is-4-desktop is-3-widescreen';\n    }\n    return '';\n}\n\nfunction getColumnVisibilityClass(columnCount, position) {\n    if (columnCount === 3 && position === 'right') {\n        return 'is-hidden-touch is-hidden-desktop-only';\n    }\n    return '';\n}\n\nfunction getColumnOrderClass(position) {\n    return position === 'left' ? 'order-1' : 'order-3';\n}\n\nfunction isColumnSticky(config, position) {\n    return typeof config.sidebar === 'object'\n        && position in config.sidebar\n        && config.sidebar[position].sticky === true;\n}\n\nclass Widgets extends Component {\n    render() {\n        const { site, config, helper, page, position } = this.props;\n        const widgets = formatWidgets(config.widgets)[position] || [];\n        const columnCount = getColumnCount(config.widgets, config, page);\n\n        if (!widgets.length) {\n            return null;\n        }\n\n        return <div class={classname({\n            'column': true,\n            ['column-' + position]: true,\n            [getColumnSizeClass(columnCount)]: true,\n            [getColumnVisibilityClass(columnCount, position)]: true,\n            [getColumnOrderClass(position)]: true,\n            'is-sticky': isColumnSticky(config, position)\n        })}>\n            {widgets.map(widget => {\n                // widget type is not defined\n                if (!widget.type) {\n                    return null;\n                }\n                try {\n                    let Widget = view.require('widget/' + widget.type);\n                    Widget = Widget.Cacheable ? Widget.Cacheable : Widget;\n                    return <Widget site={site} helper={helper} config={config} page={page} widget={widget} />;\n                } catch (e) {\n                    logger.w(`Icarus cannot load widget \"${widget.type}\"`);\n                }\n                return null;\n            })}\n            {position === 'left' && hasColumn(config.widgets, 'right', config, page) ? <div class={classname({\n                'column-right-shadow': true,\n                'is-hidden-widescreen': true,\n                'is-sticky': isColumnSticky(config, 'right')\n            })}></div> : null}\n        </div>;\n    }\n}\n\nWidgets.getColumnCount = getColumnCount;\n\nmodule.exports = Widgets;\n"
  },
  {
    "path": "layout/donate/.gitkeep",
    "content": ""
  },
  {
    "path": "layout/index.jsx",
    "content": "const { Component, Fragment } = require('inferno');\nconst Paginator = require('hexo-component-inferno/lib/view/misc/paginator');\nconst Article = require('./common/article');\n\nmodule.exports = class extends Component {\n    render() {\n        const { config, page, helper } = this.props;\n        const { __, url_for } = helper;\n\n        return <Fragment>\n            {page.posts.map(post => <Article config={config} page={post} helper={helper} index={true} />)}\n            {page.total > 1 ? <Paginator\n                current={page.current}\n                total={page.total}\n                baseUrl={page.base}\n                path={config.pagination_dir}\n                urlFor={url_for}\n                prevTitle={__('common.prev')}\n                nextTitle={__('common.next')} /> : null}\n        </Fragment>;\n    }\n};\n"
  },
  {
    "path": "layout/layout.jsx",
    "content": "const { Component } = require('inferno');\nconst classname = require('hexo-component-inferno/lib/util/classname');\nconst Head = require('./common/head');\nconst Navbar = require('./common/navbar');\nconst Widgets = require('./common/widgets');\nconst Footer = require('./common/footer');\nconst Scripts = require('./common/scripts');\nconst Search = require('./common/search');\n\nmodule.exports = class extends Component {\n    render() {\n        const { site, config, page, helper, body } = this.props;\n\n        const language = page.lang || page.language || config.language;\n        const columnCount = Widgets.getColumnCount(config.widgets, config, page);\n\n        return <html lang={language ? language.substr(0, 2) : ''}>\n            <Head site={site} config={config} helper={helper} page={page} />\n            <body class={`is-${columnCount}-column`}>\n                <Navbar config={config} helper={helper} page={page} />\n                <section class=\"section\">\n                    <div class=\"container\">\n                        <div class=\"columns\">\n                            <div class={classname({\n                                column: true,\n                                'order-2': true,\n                                'column-main': true,\n                                'is-12': columnCount === 1,\n                                'is-8-tablet is-8-desktop is-8-widescreen': columnCount === 2,\n                                'is-8-tablet is-8-desktop is-6-widescreen': columnCount === 3\n                            })} dangerouslySetInnerHTML={{ __html: body }}></div>\n                            <Widgets site={site} config={config} helper={helper} page={page} position={'left'} />\n                            <Widgets site={site} config={config} helper={helper} page={page} position={'right'} />\n                        </div>\n                    </div>\n                </section>\n                <Footer config={config} helper={helper} />\n                <Scripts site={site} config={config} helper={helper} page={page} />\n                <Search config={config} helper={helper} />\n            </body>\n        </html>;\n    }\n};\n"
  },
  {
    "path": "layout/misc/.gitkeep",
    "content": ""
  },
  {
    "path": "layout/page.jsx",
    "content": "const { Component } = require('inferno');\nconst Article = require('./common/article');\n\nmodule.exports = class extends Component {\n    render() {\n        const { config, page, helper } = this.props;\n\n        return <Article config={config} page={page} helper={helper} index={false} />;\n    }\n};\n"
  },
  {
    "path": "layout/plugin/animejs.jsx",
    "content": "const { Component } = require('inferno');\nconst { cacheComponent } = require('hexo-component-inferno/lib/util/cache');\n\nclass AnimeJs extends Component {\n    render() {\n        if (this.props.head) {\n            return <style dangerouslySetInnerHTML={{ __html: 'body>.footer,body>.navbar,body>.section{opacity:0}' }}></style>;\n        }\n        return <script src={this.props.jsUrl}></script>;\n\n    }\n}\n\nAnimeJs.Cacheable = cacheComponent(AnimeJs, 'plugin.animejs', props => {\n    const { helper, head } = props;\n    return {\n        head,\n        jsUrl: helper.url_for('/js/animation.js')\n    };\n});\n\nmodule.exports = AnimeJs;\n"
  },
  {
    "path": "layout/plugin/back_to_top.jsx",
    "content": "const { Component, Fragment } = require('inferno');\nconst { cacheComponent } = require('hexo-component-inferno/lib/util/cache');\n\nclass BackToTop extends Component {\n    render() {\n        const { title, jsUrl } = this.props;\n\n        return <Fragment>\n            <a id=\"back-to-top\" title={title} href=\"javascript:;\">\n                <i class=\"fas fa-chevron-up\"></i>\n            </a>\n            <script data-pjax src={jsUrl} defer></script>\n        </Fragment>;\n\n    }\n}\n\nBackToTop.Cacheable = cacheComponent(BackToTop, 'plugin.backtotop', props => {\n    const { helper, head } = props;\n    if (head) {\n        return null;\n    }\n    return {\n        title: helper.__('plugin.backtotop'),\n        jsUrl: helper.url_for('/js/back_to_top.js')\n    };\n});\n\nmodule.exports = BackToTop;\n"
  },
  {
    "path": "layout/plugin/pjax.jsx",
    "content": "const { Component, Fragment } = require('inferno');\n\nclass Pjax extends Component {\n    render() {\n        if (this.props.head) {\n            return null;\n        }\n        const { helper } = this.props;\n        const { url_for, cdn } = helper;\n\n        return <Fragment>\n            <script src={cdn('pjax', '0.2.8', 'pjax.min.js')}></script>\n            <script src={url_for('/js/pjax.js')}></script>\n        </Fragment>;\n    }\n}\n\nmodule.exports = Pjax;\n"
  },
  {
    "path": "layout/post.jsx",
    "content": "const { Component } = require('inferno');\nconst Article = require('./common/article');\n\nmodule.exports = class extends Component {\n    render() {\n        const { config, page, helper } = this.props;\n\n        return <Article config={config} page={page} helper={helper} index={false} />;\n    }\n};\n"
  },
  {
    "path": "layout/search/.gitkeep",
    "content": ""
  },
  {
    "path": "layout/share/.gitkeep",
    "content": ""
  },
  {
    "path": "layout/tag.jsx",
    "content": "const { Component, Fragment } = require('inferno');\nconst Index = require('./index');\n\nmodule.exports = class extends Component {\n    render() {\n        const { config, page, helper } = this.props;\n        const { url_for, _p } = helper;\n\n        return <Fragment>\n            <div class=\"card\">\n                <div class=\"card-content\">\n                    <nav class=\"breadcrumb\" aria-label=\"breadcrumbs\">\n                        <ul>\n                            <li><a href={url_for('/tags/')}>{_p('common.tag', Infinity)}</a></li>\n                            <li class=\"is-active\"><a href=\"#\" aria-current=\"page\">{page.tag}</a></li>\n                        </ul>\n                    </nav>\n                </div>\n            </div>\n            <Index config={config} page={page} helper={helper} />\n        </Fragment>;\n    }\n};\n"
  },
  {
    "path": "layout/tags.jsx",
    "content": "const { Component } = require('inferno');\nconst Tags = require('hexo-component-inferno/lib/view/widget/tags');\n\nmodule.exports = class extends Component {\n    render() {\n        const { site, helper } = this.props;\n\n        return <Tags.Cacheable site={site} helper={helper} />;\n    }\n};\n"
  },
  {
    "path": "layout/widget/profile.jsx",
    "content": "const { Component } = require('inferno');\nconst gravatrHelper = require('hexo-util').gravatar;\nconst { cacheComponent } = require('hexo-component-inferno/lib/util/cache');\n\nclass Profile extends Component {\n    renderSocialLinks(links) {\n        if (!links.length) {\n            return null;\n        }\n        return <div class=\"level is-mobile is-multiline\">\n            {links.filter(link => typeof link === 'object').map(link => {\n                return <a class=\"level-item button is-transparent is-marginless\"\n                    target=\"_blank\" rel=\"me noopener\" title={link.name} href={link.url}>\n                    {'icon' in link ? <i class={link.icon}></i> : link.name}\n                </a>;\n            })}\n        </div>;\n    }\n\n    render() {\n        const {\n            avatar,\n            avatarRounded,\n            author,\n            authorTitle,\n            location,\n            counter,\n            followLink,\n            followTitle,\n            socialLinks\n        } = this.props;\n        return <div class=\"card widget\" data-type=\"profile\">\n            <div class=\"card-content\">\n                <nav class=\"level\">\n                    <div class=\"level-item has-text-centered flex-shrink-1\">\n                        <div>\n                            <figure class=\"image is-128x128 mx-auto mb-2\">\n                                <img class={'avatar' + (avatarRounded ? ' is-rounded' : '')} src={avatar} alt={author} />\n                            </figure>\n                            {author ? <p class=\"title is-size-4 is-block\" style={{'line-height': 'inherit'}}>{author}</p> : null}\n                            {authorTitle ? <p class=\"is-size-6 is-block\">{authorTitle}</p> : null}\n                            {location ? <p class=\"is-size-6 is-flex justify-content-center\">\n                                <i class=\"fas fa-map-marker-alt mr-1\"></i>\n                                <span>{location}</span>\n                            </p> : null}\n                        </div>\n                    </div>\n                </nav>\n                <nav class=\"level is-mobile\">\n                    <div class=\"level-item has-text-centered is-marginless\">\n                        <div>\n                            <p class=\"heading\">{counter.post.title}</p>\n                            <a href={counter.post.url}>\n                                <p class=\"title\">{counter.post.count}</p>\n                            </a>\n                        </div>\n                    </div>\n                    <div class=\"level-item has-text-centered is-marginless\">\n                        <div>\n                            <p class=\"heading\">{counter.category.title}</p>\n                            <a href={counter.category.url}>\n                                <p class=\"title\">{counter.category.count}</p>\n                            </a>\n                        </div>\n                    </div>\n                    <div class=\"level-item has-text-centered is-marginless\">\n                        <div>\n                            <p class=\"heading\">{counter.tag.title}</p>\n                            <a href={counter.tag.url}>\n                                <p class=\"title\">{counter.tag.count}</p>\n                            </a>\n                        </div>\n                    </div>\n                </nav>\n                {followLink ? <div class=\"level\">\n                    <a class=\"level-item button is-primary is-rounded\" href={followLink} target=\"_blank\" rel=\"me noopener\">{followTitle}</a>\n                </div> : null}\n                {socialLinks ? this.renderSocialLinks(socialLinks) : null}\n            </div>\n        </div>;\n    }\n}\n\nProfile.Cacheable = cacheComponent(Profile, 'widget.profile', props => {\n    const { site, helper, widget } = props;\n    const {\n        avatar,\n        gravatar,\n        avatar_rounded = false,\n        author = props.config.author,\n        author_title,\n        location,\n        follow_link,\n        social_links\n    } = widget;\n    const { url_for, _p, __ } = helper;\n\n    function getAvatar() {\n        if (gravatar) {\n            return gravatrHelper(gravatar, 128);\n        }\n        if (avatar) {\n            return url_for(avatar);\n        }\n        return url_for('/img/avatar.png');\n    }\n\n    const postCount = site.posts.length;\n    const categoryCount = site.categories.filter(category => category.length).length;\n    const tagCount = site.tags.filter(tag => tag.length).length;\n\n    const socialLinks = social_links ? Object.keys(social_links).map(name => {\n        const link = social_links[name];\n        if (typeof link === 'string') {\n            return {\n                name,\n                url: url_for(link)\n            };\n        }\n        return {\n            name,\n            url: url_for(link.url),\n            icon: link.icon\n        };\n    }) : null;\n\n    return {\n        avatar: getAvatar(),\n        avatarRounded: avatar_rounded,\n        author,\n        authorTitle: author_title,\n        location,\n        counter: {\n            post: {\n                count: postCount,\n                title: _p('common.post', postCount),\n                url: url_for('/archives/')\n            },\n            category: {\n                count: categoryCount,\n                title: _p('common.category', categoryCount),\n                url: url_for('/categories/')\n            },\n            tag: {\n                count: tagCount,\n                title: _p('common.tag', tagCount),\n                url: url_for('/tags/')\n            }\n        },\n        followLink: follow_link ? url_for(follow_link) : undefined,\n        followTitle: __('widget.follow'),\n        socialLinks\n    };\n});\n\nmodule.exports = Profile;\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"hexo-theme-icarus\",\n  \"version\": \"6.1.1\",\n  \"author\": \"ppoffice <ppoffice@users.noreply.github.com>\",\n  \"license\": \"MIT\",\n  \"description\": \"A simple, delicate, and modern theme for Hexo\",\n  \"keywords\": [\n    \"hexo\",\n    \"theme\",\n    \"icarus\"\n  ],\n  \"homepage\": \"https://github.com/ppoffice/hexo-theme-icarus\",\n  \"repository\": \"https://github.com/ppoffice/hexo-theme-icarus.git\",\n  \"bugs\": {\n    \"url\": \"https://github.com/ppoffice/hexo-theme-icarus/issues\"\n  },\n  \"engines\": {\n    \"node\": \">=14\"\n  },\n  \"scripts\": {\n    \"lint\": \"eslint --ext .js --ext .jsx --ext .json .\"\n  },\n  \"devDependencies\": {\n    \"eslint\": \"^8.56.0\",\n    \"eslint-config-hexo\": \"^5.0.0\",\n    \"eslint-plugin-json\": \"^3.1.0\",\n    \"eslint-plugin-react\": \"^7.33.2\"\n  },\n  \"dependencies\": {\n    \"bulma-stylus\": \"0.8.0\",\n    \"deepmerge\": \"^4.3.1\",\n    \"hexo\": \"^7.1.1\",\n    \"hexo-component-inferno\": \"^3.1.2\",\n    \"hexo-log\": \"^4.1.0\",\n    \"hexo-pagination\": \"^3.0.0\",\n    \"hexo-renderer-inferno\": \"^1.0.2\",\n    \"hexo-renderer-stylus\": \"^3.0.1\",\n    \"hexo-util\": \"^3.2.0\",\n    \"inferno\": \"^8.2.3\",\n    \"inferno-create-element\": \"^8.2.3\",\n    \"moment\": \"^2.30.1\",\n    \"semver\": \"^7.5.4\"\n  }\n}\n"
  },
  {
    "path": "scripts/index.js",
    "content": "/* global hexo */\nconst createLogger = require('hexo-log');\n\nconst logger = createLogger.default();\n\n/**\n * Print welcome message\n */\nlogger.info(`=======================================\n ██╗ ██████╗ █████╗ ██████╗ ██╗   ██╗███████╗\n ██║██╔════╝██╔══██╗██╔══██╗██║   ██║██╔════╝\n ██║██║     ███████║██████╔╝██║   ██║███████╗\n ██║██║     ██╔══██║██╔══██╗██║   ██║╚════██║\n ██║╚██████╗██║  ██║██║  ██║╚██████╔╝███████║\n ╚═╝ ╚═════╝╚═╝  ╚═╝╚═╝  ╚═╝ ╚═════╝ ╚══════╝\n=============================================`);\n\n/**\n * Check if all dependencies are installed\n */\nrequire('../include/dependency')(hexo);\n\n/**\n * Configuration file checking and migration\n */\nrequire('../include/config')(hexo);\n\n/**\n * Register Hexo extensions and remove Hexo filters that could cause OOM\n */\nrequire('../include/register')(hexo);\n"
  },
  {
    "path": "source/css/cyberpunk.styl",
    "content": "$family-sans-serif ?= 'Oxanium', Ubuntu, Roboto, 'Open Sans', 'Microsoft YaHei', sans-serif\n$family-code ?= 'Roboto Mono', monospace, 'Microsoft YaHei'\n// shadow and radius\n$shadow ?= none\n$radius ?= 0\n$radius-small ?= 0\n// base colors\n$white ?= #fff\n$white-bis ?= #cdcdcd\n$grey ?= #848484\n$black ?= #000\n$black-bis ?= #050a0e\n$orange ?= #ff8e3c\n$yellow ?= #fcee09\n$green ?= #00ff41\n$blue ?= #02d7f2\n$purple ?= #9561d2\n$red ?= #ff003c\n$primary ?= $yellow\n$info ?= $blue\n$success ?= $green\n$warning ?= $orange\n$danger ?= $red\n// invert colors\n$orange-invert ?= #121617\n$yellow-invert ?= #121617\n$green-invert ?= #121617\n$blue-invert ?= #121617\n$purple-invert ?= #121617\n$red-invert ?= #121617\n$primary-invert ?= #121617\n$info-invert ?= #121617\n$success-invert ?= #121617\n$warning-invert ?= #121617\n$danger-invert ?= #121617\n// derived colors\n$scheme-main ?= $black\n$link ?= $blue\n$link-hover ?= $primary\n$text ?= $white-bis\n$text-strong ?= $yellow\n$body-background-color ?= $scheme-main\n$input-color ?= $text\n$input-placeholder-color ?= rgba($input-color, .8)\n$footer-color ?= $black\n$footer-background-color ?= $yellow\n$navbar-background-color ?= $yellow\n$navbar-item-color ?= $black\n$navbar-item-active-color ?= $black\n$navbar-item-hover-color ?= $black\n$navbar-item-hover-background-color ?= transparent\n$navbar-item-margin-v ?= 1.25rem\n$navbar-item-margin-h ?= .25rem\n$navbar-item-padding-v ?= 0\n$navbar-item-padding-h ?= .5rem\n$card-background-color ?= transparent\n$menu-label-color ?= $blue\n$menu-item-hover-color ?= $black\n$menu-item-hover-background-color ?= $yellow\n$menu-item-active-color ?= $black\n$menu-item-active-background-color ?= $yellow\n$menu-list-border-left ?= 1px solid $text\n$tag-color ?= $black\n$tag-background-color ?= $blue\n$timeline-fg-line ?= $blue\n$timeline-bg-line ?= $body-background-color\n$post-navigation-fg ?= $white-bis\n$searchbox-bg-container ?= $black-bis\n$searchbox-border ?= $blue\n$searchbox-bg-input ?= $black-bis\n$searchbox-bg-close-hover ?= $black\n$searchbox-bg-close-active ?= $searchbox-bg-close-hover\n$searchbox-bg-result-item-hover ?= $black\n\n@import 'style'\n\nclip-path(clip)\n    clip-path: clip\n    -webkit-clip-path: clip\n\ncut-corner(size)\n    clip-path(unquote('polygon(' + size + ' 0, 100% 0, 100% calc(100% - ' + size + '), calc(100% - ' + size + ') 100%, 0 100%, 0 ' + size + ')'))\n\ncut-corner-reverse(size)\n    clip-path(unquote('polygon(0 0, calc(100% - ' + size + ') 0, 100% ' + size + ', 100% 100%, ' + size + ' 100%, 0 calc(100% - ' + size + '), 0 0)'))\n\ncut-corner-top-right(size)\n    clip-path(unquote('polygon(0 0, calc(100% - ' + size + ') 0, 100% ' + size + ', 100% 100%, 0 100%)'))\n\ncut-corner-bottom-left(size)\n    clip-path(unquote('polygon(0 0, 100% 0, 100% 100%, ' + size + ' 100%, 0 calc(100% - ' + size + '))'))\n\ncut-corner-bottom-right(size)\n    clip-path(unquote('polygon(0 0, 100% 0, 100% calc(100% - ' + size + '), calc(100% - ' + size + ') 100%, 0 100%)'))\n\nundercover-before()\n    position: relative\n\n    &:before\n        content: ''\n        position: absolute\n        z-index: -1\n        top: 0\n        left: 0\n        right: 0\n        bottom: 0\n\nbody\n    counter-reset: card\n\n::selection\n    color: $black\n    background: $blue\n\n.card:not(#back-to-top)\n    position: relative\n    counter-increment: card\n\n    &, .card-content\n        undercover-before()\n\n    &:before\n        top: -1.2px\n        left: -1.2px\n        right: -1.2px\n        bottom: -1.2px\n        background-color: $blue\n        cut-corner-reverse(16px)\n\n    &:after\n        content: 'R' counter(card)\n        position: absolute\n        color: $blue\n        right: 2rem\n        bottom: -.6em\n        font-size: .75rem\n        padding: 0 .25em\n        background: $body-background-color\n\n    .card-image\n        cut-corner-top-right(16px)\n\n    .card-content:before\n        background-color: $body-background-color\n        cut-corner-reverse(16px)\n\n    .card-image + .card-content:before\n        cut-corner-bottom-left(16px)\n\nclip-button($color, $color-invert)\n    &:before\n        background-color: $color\n        color: $color-invert\n\n    &:hover:before, &.is-hovered:before\n        background-color: darken($color, 2.5%)\n        color: $color-invert\n\n    &:focus:before, &.is-focused:before\n        color: $color-invert\n\n    &:active:before, &.is-active:before\n        background-color: darken($color, 5%)\n        color: $color-invert\n\n    &[disabled]:before, fieldset[disabled] &:before\n        background-color: $color\n\n    &.is-inverted\n        &:before\n            background-color: $color-invert\n            color: $color\n\n            &:hover:before, &.is-hovered:before\n                background-color: darken($color-invert, 5%)\n\n            &[disabled]:before, fieldset[disabled] &:before\n                background-color: $color-invert\n                border-color: transparent\n                box-shadow: none\n                color: $color\n\n.button:not(input)\n    border: none\n    outline: none\n    background: transparent !important\n    undercover-before()\n\n    &:before\n        cut-corner(8px)\n\n    // clip-path will cut off overflown content inside a button\n    // thus we need to use :before pseudo-element to style the buttons\n    for $name, $pair in $colors\n        $color = $pair['1']\n        $color-invert = $pair['2']\n\n        &.is-{$name}\n            clip-button($color, $color-invert)\n\n.field.has-addons\n    .control:not(:first-child)\n        .button\n            cut-corner-bottom-right(8px)\n\n.menu-list a\n    cut-corner(8px)\n\n.tags.has-addons\n    .tag:first-child\n        background: $yellow !important\n\n    .tag:last-child\n        background: $blue !important\n\n.pagination-previous, .pagination-next, .pagination-link\n    cut-corner(8px)\n\n    &:hover\n        background-color: $blue\n\n        &, a\n            color: $black\n\n.navbar-main\n    padding-top: 10px\n    padding-bottom: 30px\n\n    &:after\n        content: ''\n        position: absolute\n        left: 0\n        right: 0\n        bottom: -2px\n        background: url('../img/razor-top-black.svg') repeat-x top\n        height: 40px\n\n    .navbar-menu\n        .navbar-item\n            &:hover, &.is-active\n                color: $navbar-background-color\n                background-color: $body-background-color !important\n\narticle.article, article.media\n    .title a\n        background-image: linear-gradient(transparent calc(100% - 2px), $text-strong 2px)\n        background-repeat: no-repeat\n        background-size: 0 100%\n        transition: background-size .25s ease-in-out\n\n    .title:hover a\n        background-size: 100% 100%\n\narticle.article\n    .article-more\n        clip-button($info, $info-invert)\n\n.article-licensing\n    background: $black-ter\n\n.content\n    blockquote\n        background: transparent\n        border: .5px solid $blue\n        border-left: 5px solid $blue\n\n.footer\n    position: relative\n\n    &:before\n        content: ''\n        position: absolute\n        left: 0\n        right: 0\n        top: -1px\n        height: 39px\n        background: url('../img/razor-bottom-black.svg') repeat-x top\n\n    & > .container\n        padding-top: 40px\n\n.timeline .media\n    &:before\n        clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%)\n\n.searchbox .searchbox-container\n    border: 1px solid $blue\n\n    .searchbox-body\n        border-bottom: 1px solid $searchbox-border\n\n        li:last-child .searchbox-result-section\n            border-bottom: none\n\n    .searchbox-result-item\n        em\n            color: $black\n\n#back-to-top\n    color: $black\n    background: $blue\n    margin-top: 45px\n    cut-corner(8px)\n\n.cc-window, .cc-revoke\n    border-radius: 0 !important\n\n.cc-window\n    &:not(.cc-banner)\n        border: 1px solid $blue\n\n    &.cc-theme-classic, &.cc-theme-block\n        .cc-compliance > .cc-btn\n            border-radius: 0\n\n    &.cc-banner\n        .cc-compliance > .cc-btn\n            background-color: $blue\n\n            &:hover, &:focus\n                background-color: darken($blue, 2.5%)\n"
  },
  {
    "path": "source/css/default.styl",
    "content": "@import 'style'\n"
  },
  {
    "path": "source/css/style.styl",
    "content": "// Base CSS framework\n@import '../../include/style/base'\n// Helper classes & mixins\n@import '../../include/style/helper'\n// Icarus components\n@import '../../include/style/button'\n@import '../../include/style/card'\n@import '../../include/style/article'\n@import '../../include/style/navbar'\n@import '../../include/style/footer'\n@import '../../include/style/pagination'\n@import '../../include/style/timeline'\n@import '../../include/style/search'\n@import '../../include/style/codeblock'\n@import '../../include/style/widget'\n@import '../../include/style/donate'\n@import '../../include/style/plugin'\n@import '../../include/style/responsive'\n"
  },
  {
    "path": "source/js/.eslintrc.json",
    "content": "{\n    \"extends\": \"../../.eslintrc.json\",\n    \"env\": {\n        \"browser\": true,\n        \"jquery\": true,\n        \"node\": false\n    }\n}"
  },
  {
    "path": "source/js/animation.js",
    "content": "(function() {\n    function $() {\n        return Array.prototype.slice.call(document.querySelectorAll.apply(document, arguments));\n    }\n\n    $('body > .navbar, body > .section, body > .footer').forEach(element => {\n        element.style.transition = '0s';\n        element.style.opacity = '0';\n    });\n    document.querySelector('body > .navbar').style.transform = 'translateY(-100px)';\n    [\n        '.column-main > .card, .column-main > .pagination, .column-main > .post-navigation',\n        '.column-left > .card, .column-right-shadow > .card',\n        '.column-right > .card'\n    ].forEach(selector => {\n        $(selector).forEach(element => {\n            element.style.transition = '0s';\n            element.style.opacity = '0';\n            element.style.transform = 'scale(0.8)';\n            element.style.transformOrigin = 'center top';\n        });\n    });\n    // disable jump to location.hash\n    if (window.location.hash) {\n        window.scrollTo(0, 0);\n        setTimeout(() => window.scrollTo(0, 0));\n    }\n\n    setTimeout(() => {\n        $('body > .navbar, body > .section, body > .footer').forEach(element => {\n            element.style.opacity = '1';\n            element.style.transition = 'opacity 0.3s ease-out, transform 0.3s ease-out';\n        });\n        document.querySelector('body > .navbar').style.transform = 'translateY(0)';\n\n        let i = 1;\n        [\n            '.column-main > .card, .column-main > .pagination, .column-main > .post-navigation',\n            '.column-left > .card, .column-right-shadow > .card',\n            '.column-right > .card'\n        ].forEach(selector => {\n            $(selector).forEach(element => {\n                setTimeout(() => {\n                    element.style.opacity = '1';\n                    element.style.transform = '';\n                    element.style.transition = 'opacity 0.3s ease-out, transform 0.3s ease-out';\n                }, i * 100);\n                i++;\n            });\n        });\n\n        // jump to location.hash\n        if (window.location.hash) {\n            setTimeout(() => {\n                const id = '#' + CSS.escape(window.location.hash.substring(1));\n                const target = document.querySelector(id);\n                if (target) {\n                    target.scrollIntoView({ behavior: 'smooth' });\n                }\n            }, i * 100);\n        }\n    });\n}());\n"
  },
  {
    "path": "source/js/back_to_top.js",
    "content": "$(document).ready(() => {\n    const $button = $('#back-to-top');\n    const $footer = $('footer.footer');\n    const $mainColumn = $('.column-main');\n    const $leftSidebar = $('.column-left');\n    const $rightSidebar = $('.column-right');\n    let lastScrollTop = 0;\n    const rightMargin = 20;\n    const bottomMargin = 20;\n    let lastState = null;\n    const state = {\n        base: {\n            classname: 'card has-text-centered',\n            left: '',\n            width: 64,\n            bottom: bottomMargin\n        }\n    };\n    state['desktop-hidden'] = Object.assign({}, state.base, {\n        classname: state.base.classname + ' rise-up'\n    });\n    state['desktop-visible'] = Object.assign({}, state['desktop-hidden'], {\n        classname: state['desktop-hidden'].classname + ' fade-in'\n    });\n    state['desktop-dock'] = Object.assign({}, state['desktop-visible'], {\n        classname: state['desktop-visible'].classname + ' fade-in is-rounded',\n        width: 40\n    });\n    state['mobile-hidden'] = Object.assign({}, state.base, {\n        classname: state.base.classname + ' fade-in',\n        right: rightMargin\n    });\n    state['mobile-visible'] = Object.assign({}, state['mobile-hidden'], {\n        classname: state['mobile-hidden'].classname + ' rise-up'\n    });\n\n    function isStateEquals(prev, next) {\n        return ![].concat(Object.keys(prev), Object.keys(next)).some(key => {\n            return !Object.prototype.hasOwnProperty.call(prev, key)\n                || !Object.prototype.hasOwnProperty.call(next, key)\n                || next[key] !== prev[key];\n        });\n    }\n\n    function applyState(state) {\n        if (lastState !== null && isStateEquals(lastState, state)) {\n            return;\n        }\n        $button.attr('class', state.classname);\n        for (const prop in state) {\n            if (prop === 'classname') {\n                continue;\n            }\n            $button.css(prop, state[prop]);\n        }\n        lastState = state;\n    }\n\n    function isDesktop() {\n        return window.innerWidth >= 1078;\n    }\n\n    function isTablet() {\n        return window.innerWidth >= 768 && !isDesktop();\n    }\n\n    function isScrollUp() {\n        return $(window).scrollTop() < lastScrollTop && $(window).scrollTop() > 0;\n    }\n\n    function hasLeftSidebar() {\n        return $leftSidebar.length > 0;\n    }\n\n    function hasRightSidebar() {\n        return $rightSidebar.length > 0;\n    }\n\n    function getRightSidebarBottom() {\n        if (!hasRightSidebar()) {\n            return 0;\n        }\n        return Math.max.apply(null, $rightSidebar.find('.widget').map(function() {\n            return $(this).offset().top + $(this).outerHeight(true);\n        }));\n    }\n\n    function getScrollTop() {\n        return $(window).scrollTop();\n    }\n\n    function getScrollBottom() {\n        return $(window).scrollTop() + $(window).height();\n    }\n\n    function getButtonWidth() {\n        return $button.outerWidth(true);\n    }\n\n    function getButtonHeight() {\n        return $button.outerHeight(true);\n    }\n\n    function updateScrollTop() {\n        lastScrollTop = $(window).scrollTop();\n    }\n\n    function update() {\n        // desktop mode or tablet mode with only right sidebar enabled\n        if (isDesktop() || (isTablet() && !hasLeftSidebar() && hasRightSidebar())) {\n            let nextState;\n            const padding = ($mainColumn.outerWidth() - $mainColumn.width()) / 2;\n            const maxLeft = $(window).width() - getButtonWidth() - rightMargin;\n            const maxBottom = $footer.offset().top + (getButtonHeight() / 2) + bottomMargin;\n            if (getScrollTop() === 0 || getScrollBottom() < getRightSidebarBottom() + padding + getButtonHeight()) {\n                nextState = state['desktop-hidden'];\n            } else if (getScrollBottom() < maxBottom) {\n                nextState = state['desktop-visible'];\n            } else {\n                nextState = Object.assign({}, state['desktop-dock'], {\n                    bottom: getScrollBottom() - maxBottom + bottomMargin\n                });\n            }\n\n            const left = $mainColumn.offset().left + $mainColumn.outerWidth() + padding;\n            nextState = Object.assign({}, nextState, {\n                left: Math.min(left, maxLeft)\n            });\n            applyState(nextState);\n        } else {\n            // mobile and tablet mode\n            if (!isScrollUp()) {\n                applyState(state['mobile-hidden']);\n            } else {\n                applyState(state['mobile-visible']);\n            }\n            updateScrollTop();\n        }\n    }\n\n    update();\n    $(window).resize(update);\n    $(window).scroll(update);\n\n    $('#back-to-top').on('click', () => {\n        if (CSS && CSS.supports && CSS.supports('(scroll-behavior: smooth)')) {\n            window.scroll({ top: 0, behavior: 'smooth' });\n        } else {\n            $('body, html').animate({ scrollTop: 0 }, 400);\n        }\n    });\n});\n"
  },
  {
    "path": "source/js/column.js",
    "content": "(function() {\n    function $() {\n        return Array.prototype.slice.call(document.querySelectorAll.apply(document, arguments));\n    }\n\n    // copy widgets in the right column, when exist, to the bottom of the left column\n    if ($('.columns .column-right').length && $('.columns .column-right-shadow').length && !$('.columns .column-right-shadow')[0].children.length) {\n        for (const child of $('.columns .column-right')[0].children) {\n            $('.columns .column-right-shadow')[0].append(child.cloneNode(true));\n        }\n    }\n}());\n"
  },
  {
    "path": "source/js/main.js",
    "content": "/* eslint-disable node/no-unsupported-features/node-builtins */\n(function($, moment, ClipboardJS, config) {\n    $('.article img:not(\".not-gallery-item\")').each(function() {\n        // wrap images with link and add caption if possible\n        if ($(this).parent('a').length === 0) {\n            $(this).wrap('<a class=\"gallery-item\" href=\"' + $(this).attr('src') + '\"></a>');\n            if (this.alt) {\n                $(this).after('<p class=\"has-text-centered is-size-6 caption\">' + this.alt + '</p>');\n            }\n        }\n    });\n\n    if (typeof $.fn.lightGallery === 'function') {\n        $('.article').lightGallery({ selector: '.gallery-item' });\n    }\n    if (typeof $.fn.justifiedGallery === 'function') {\n        if ($('.justified-gallery > p > .gallery-item').length) {\n            $('.justified-gallery > p > .gallery-item').unwrap();\n        }\n        $('.justified-gallery').justifiedGallery();\n    }\n\n    if (typeof moment === 'function') {\n        $('.article-meta time').each(function() {\n            $(this).text(moment($(this).attr('datetime')).fromNow());\n        });\n    }\n\n    $('.article > .content > table').each(function() {\n        if ($(this).width() > $(this).parent().width()) {\n            $(this).wrap('<div class=\"table-overflow\"></div>');\n        }\n    });\n\n    function adjustNavbar() {\n        const navbarWidth = $('.navbar-main .navbar-start').outerWidth() + $('.navbar-main .navbar-end').outerWidth();\n        if ($(document).outerWidth() < navbarWidth) {\n            $('.navbar-main .navbar-menu').addClass('justify-content-start');\n        } else {\n            $('.navbar-main .navbar-menu').removeClass('justify-content-start');\n        }\n    }\n    adjustNavbar();\n    $(window).resize(adjustNavbar);\n\n    function toggleFold(codeBlock, isFolded) {\n        const $toggle = $(codeBlock).find('.fold i');\n        !isFolded ? $(codeBlock).removeClass('folded') : $(codeBlock).addClass('folded');\n        !isFolded ? $toggle.removeClass('fa-angle-right') : $toggle.removeClass('fa-angle-down');\n        !isFolded ? $toggle.addClass('fa-angle-down') : $toggle.addClass('fa-angle-right');\n    }\n\n    function createFoldButton(fold) {\n        return '<span class=\"fold\">' + (fold === 'unfolded' ? '<i class=\"fas fa-angle-down\"></i>' : '<i class=\"fas fa-angle-right\"></i>') + '</span>';\n    }\n\n    $('figure.highlight table').wrap('<div class=\"highlight-body\">');\n    if (typeof config !== 'undefined'\n        && typeof config.article !== 'undefined'\n        && typeof config.article.highlight !== 'undefined') {\n\n        $('figure.highlight').addClass('hljs');\n        $('figure.highlight .code .line span').each(function() {\n            const classes = $(this).attr('class').split(/\\s+/);\n            for (const cls of classes) {\n                $(this).addClass('hljs-' + cls);\n                $(this).removeClass(cls);\n            }\n        });\n\n\n        const clipboard = config.article.highlight.clipboard;\n        const fold = config.article.highlight.fold.trim();\n\n        $('figure.highlight').each(function() {\n            if ($(this).find('figcaption').length) {\n                $(this).find('figcaption').addClass('level is-mobile');\n                $(this).find('figcaption').append('<div class=\"level-left\">');\n                $(this).find('figcaption').append('<div class=\"level-right\">');\n                $(this).find('figcaption div.level-left').append($(this).find('figcaption').find('span'));\n                $(this).find('figcaption div.level-right').append($(this).find('figcaption').find('a'));\n            } else {\n                if (clipboard || fold) {\n                    $(this).prepend('<figcaption class=\"level is-mobile\"><div class=\"level-left\"></div><div class=\"level-right\"></div></figcaption>');\n                }\n            }\n        });\n\n        if (typeof ClipboardJS !== 'undefined' && clipboard) {\n            $('figure.highlight').each(function() {\n                const id = 'code-' + Date.now() + (Math.random() * 1000 | 0);\n                const button = '<a href=\"javascript:;\" class=\"copy\" title=\"Copy\" data-clipboard-target=\"#' + id + ' .code\"><i class=\"fas fa-copy\"></i></a>';\n                $(this).attr('id', id);\n                $(this).find('figcaption div.level-right').append(button);\n            });\n            new ClipboardJS('.highlight .copy'); // eslint-disable-line no-new\n        }\n\n        if (fold) {\n            $('figure.highlight').each(function() {\n                $(this).addClass('foldable'); // add 'foldable' class as long as fold is enabled\n\n                if ($(this).find('figcaption').find('span').length > 0) {\n                    const span = $(this).find('figcaption').find('span');\n                    if (span[0].innerText.indexOf('>folded') > -1) {\n                        span[0].innerText = span[0].innerText.replace('>folded', '');\n                        $(this).find('figcaption div.level-left').prepend(createFoldButton('folded'));\n                        toggleFold(this, true);\n                        return;\n                    }\n                }\n                $(this).find('figcaption div.level-left').prepend(createFoldButton(fold));\n                toggleFold(this, fold === 'folded');\n            });\n\n            $('figure.highlight figcaption .level-left').click(function() {\n                const $code = $(this).closest('figure.highlight');\n                toggleFold($code.eq(0), !$code.hasClass('folded'));\n            });\n        }\n    }\n\n    const $toc = $('#toc');\n    if ($toc.length > 0) {\n        const $mask = $('<div>');\n        $mask.attr('id', 'toc-mask');\n\n        $('body').append($mask);\n\n        function toggleToc() { // eslint-disable-line no-inner-declarations\n            $toc.toggleClass('is-active');\n            $mask.toggleClass('is-active');\n        }\n\n        $toc.on('click', toggleToc);\n        $mask.on('click', toggleToc);\n        $('.navbar-main .catalogue').on('click', toggleToc);\n    }\n}(jQuery, window.moment, window.ClipboardJS, window.IcarusThemeSettings));\n"
  },
  {
    "path": "source/js/pjax.js",
    "content": "(function() {\n    // eslint-disable-next-line no-unused-vars\n    let pjax;\n\n    function initPjax() {\n        try {\n            const Pjax = window.Pjax || function() {};\n            pjax = new Pjax({\n                selectors: [\n                    '[data-pjax]',\n                    '.pjax-reload',\n                    'head title',\n                    '.columns',\n                    '.navbar-start',\n                    '.navbar-end',\n                    '.searchbox link',\n                    '.searchbox script',\n                    '#back-to-top',\n                    '#comments link',\n                    '#comments script'\n                ],\n                cacheBust: false\n            });\n        } catch (e) {\n            console.warn('PJAX error: ' + e);\n        }\n    }\n\n    // // Listen for start of Pjax\n    // document.addEventListener('pjax:send', function() {\n    //     return;\n    //     // TODO pace start loading animation\n    // })\n\n    // Listen for completion of Pjax\n    document.addEventListener('pjax:complete', () => {\n        // Plugin [MathJax] reload logic\n        if (window.MathJax) {\n            try {\n                window.MathJax.typesetPromise && window.MathJax.typesetPromise();\n            } catch (e) {\n                console.error('MathJax reload error:', e);\n            }\n        }\n        // Plugin [Busuanzi] reload logic\n        if (window.bszCaller && window.bszTag) {\n            window.bszCaller.fetch('//busuanzi.ibruce.info/busuanzi?jsonpCallback=BusuanziCallback', a => {\n                window.bszTag.texts(a);\n                window.bszTag.shows();\n            });\n        }\n\n        // TODO pace stop loading animation\n    });\n\n    document.addEventListener('DOMContentLoaded', () => initPjax());\n}());\n"
  }
]