diff --git a/package.json b/package.json
index 54330ab8..200d1669 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,6 @@
"devDependencies": {
"algoliasearch": "^4.2.0",
"vuepress": "^1.4.1",
- "vuepress-theme-reco": "^1.4.5",
"vuepress-plugin-autobar": "github:boboidream/vuepress-bar"
},
"description": "易懂的算法教程",
diff --git a/website/.vuepress/config.js b/website/.vuepress/config.js
index 131a9a4a..fbf43a88 100644
--- a/website/.vuepress/config.js
+++ b/website/.vuepress/config.js
@@ -1,38 +1,56 @@
module.exports = {
- title: "小浩算法",
- plugins: [require('../../lib/autobar.js'), require('../../lib/Notification.js')],
- description: '和小浩一起学算法',
- // root : "./hell-algorithm",
- theme: "reco",
- themeConfig: {
- logo: '/logo.png',
- sidebar: "auto",
- searchPlaceholder: "搜索:KMP",
- nav: [
- {text: 'GitHub', link: 'https://github.com/geekxh/hello-algorithm', icon: 'reco-github'}
- ],
- head: [
- ['link', {rel: 'shortcut icon', href: '/favicon.ico'}]
- ],
- type: 'blog',
- search: true,
- searchMaxSuggestions: 10,
- lastUpdated: '文章修订于',
- author: '程序员小浩',
- authorAvatar: '/code.png',
- startYear: '2019',
- valineConfig: {
- visitor: false,
- enable: true,
- placeholder: "留下你的问题,或者你想要的资源...",
- avatar: "wavatar",
- requiredFields: ['nick'],
- appId: 'sINkW5sfpPxoqDyBqbpvTN79-gzGzoHsz',
- appKey: '5tkDVulRNyjuAbCUekxU6zHW',
+ title: "和小浩学编程",
+ plugins: [
+ require('../../lib/autobar.js'),
+ require('../../lib/Notification.js')],
+ description: '编程是一件有趣的事情',
+ // root : "./hell-algorithm",
+ theme: "reco",
+ themeConfig: {
+ logo: '/logo.png',
+ sidebar: "auto",
+ searchPlaceholder: "搜索:KMP",
+ nav: [
+ {
+ text: 'GitHub',
+ link: 'https://githubd.com/geekxh/hello-algorithm',
+ icon: 'reco-github'
+ },
+ {
+ text: 'TimeLine',
+ link: '/timeline/',
+ icon: 'reco-date'
+ }
+ ],
+ // 博客配置
+ blogConfig: {
+ tag: {
+ location: 3, // 在导航栏菜单中所占的位置,默认3
+ text: 'Tag' // 默认文案 “标签”
+ }
+ },
+ head: [
+ ['link', {rel: 'shortcut icon', href: '/favicon.ico'}]
+ ],
+ type: 'blog',
+ search: true,
+ searchMaxSuggestions: 10,
+ lastUpdated: '文章修订于',
+ author: '程序员小浩',
+ authorAvatar: '/code.png',
+ startYear: '2019',
+ valineConfig: {
+ visitor: false,
+ enable: true,
+ placeholder: "留下你的问题,或者你想要的资源...",
+ avatar: "wavatar",
+ requiredFields: ['nick'],
+ appId: 'sINkW5sfpPxoqDyBqbpvTN79-gzGzoHsz',
+ appKey: '5tkDVulRNyjuAbCUekxU6zHW',
+ },
+ noFoundPageByTencent: false
},
- noFoundPageByTencent: false
- },
- markdown: {
- lineNumbers: true,
- }
+ markdown: {
+ lineNumbers: true,
+ }
}
\ No newline at end of file
diff --git a/website/.vuepress/theme/LICENSE b/website/.vuepress/theme/LICENSE
new file mode 100644
index 00000000..84b7cce6
--- /dev/null
+++ b/website/.vuepress/theme/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 reco_luan
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/website/.vuepress/theme/README.md b/website/.vuepress/theme/README.md
new file mode 100644
index 00000000..2b6d41e4
--- /dev/null
+++ b/website/.vuepress/theme/README.md
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+## Introduce
+
+1. 这是一个vuepress主题,旨在添加博客所需的分类、标签墙、分页、评论等功能;
+2. 主题追求极简,根据 vuepress 的默认主题修改而成,官方的主题配置仍然适用;
+3. 效果:[午后南杂](https://www.recoluan.com)
+4. 文档:[vuepress-theme-reco-doc](https://vuepress-theme-reco.recoluan.com)
+
+## Quick start
+
+**npx**
+
+```
+npx @vuepress-reco/theme-cli init my-blog
+```
+
+**npm**
+
+```bash
+# init
+npm install @vuepress-reco/theme-cli -g
+theme-cli init my-blog
+
+# install
+cd my-blog
+npm install
+
+# run
+npm run dev
+
+# build
+npm run build
+```
+
+**yarn**
+
+```bash
+# init
+yarn global add @vuepress-reco/theme-cli
+theme-cli init my-blog
+
+# install
+cd my-blog
+yarn install
+
+# run
+yarn dev
+
+# build
+yarn build
+```
+
+## Preview
+
+
+
+
+
+
+
+
+
+## Contributors
+
+**衷心感谢为此项目贡献过宝贵代码的朋友们**
+
+|昵称|贡献记录|
+|:-:|-|
+|[kangxu](https://github.com/kangxukangxu)|[vuepress-theme-reco@0.x](https://github.com/recoluan/vuepress-theme-reco/commit/ec7426a88d50cf8d9f90a7ad9b731a10da7f438b)|
+|[Ekko](https://github.com/danranVm)|[vuepress-theme-reco-demo@1.x](https://github.com/recoluan/vuepress-theme-reco-demo/commit/6d2bbe919e7f6564b8c8173558d197e38e024dc5)|
+
+**衷心感谢美女设计师**
+
+|昵称|贡献内容|
+|:-:|-|
+|[Zoey]()|主题图标调整定稿|
+|冰冰|主题图标初稿|
+
+## License
+[MIT](https://github.com/recoluan/vuepress-theme-reco/blob/master/LICENSE)
diff --git a/website/.vuepress/theme/components/AlgoliaSearchBox.vue b/website/.vuepress/theme/components/AlgoliaSearchBox.vue
new file mode 100644
index 00000000..5add0002
--- /dev/null
+++ b/website/.vuepress/theme/components/AlgoliaSearchBox.vue
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/Common.vue b/website/.vuepress/theme/components/Common.vue
new file mode 100644
index 00000000..bfcd929d
--- /dev/null
+++ b/website/.vuepress/theme/components/Common.vue
@@ -0,0 +1,268 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/DropdownLink.vue b/website/.vuepress/theme/components/DropdownLink.vue
new file mode 100644
index 00000000..058b3bf5
--- /dev/null
+++ b/website/.vuepress/theme/components/DropdownLink.vue
@@ -0,0 +1,183 @@
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/DropdownTransition.vue b/website/.vuepress/theme/components/DropdownTransition.vue
new file mode 100644
index 00000000..8c711a15
--- /dev/null
+++ b/website/.vuepress/theme/components/DropdownTransition.vue
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/Footer.vue b/website/.vuepress/theme/components/Footer.vue
new file mode 100644
index 00000000..74a98809
--- /dev/null
+++ b/website/.vuepress/theme/components/Footer.vue
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/FriendLink.vue b/website/.vuepress/theme/components/FriendLink.vue
new file mode 100644
index 00000000..9d730e5e
--- /dev/null
+++ b/website/.vuepress/theme/components/FriendLink.vue
@@ -0,0 +1,196 @@
+
+
+
+
+
+ {{item.title}}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/Home.vue b/website/.vuepress/theme/components/Home.vue
new file mode 100644
index 00000000..4e31d2ce
--- /dev/null
+++ b/website/.vuepress/theme/components/Home.vue
@@ -0,0 +1,241 @@
+
+
+
+
+
+
+
+ {{ $frontmatter.heroText || $title || 'vuePress-theme-reco' }}
+
+
+
+ {{ $frontmatter.tagline || $description || 'Welcome to your vuePress-theme-reco site' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ feature.title }}
+
{{ feature.details }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/HomeBlog.vue b/website/.vuepress/theme/components/HomeBlog.vue
new file mode 100644
index 00000000..a4ec2dfa
--- /dev/null
+++ b/website/.vuepress/theme/components/HomeBlog.vue
@@ -0,0 +1,350 @@
+
+
+
+
+
+
+
+
+
+ {{ $frontmatter.heroText || $title || 'vuePress-theme-reco' }}
+
+
+
+
+
+ {{ $frontmatter.tagline || $description || 'Welcome to your vuePress-theme-reco site' }}
+
+
+
+
+
+
+
+
+
+
{{homeBlogCfg.category}}
+
+
+
+ {{ item.name }}
+ {{ item.pages.length }}
+
+
+
+
+
{{homeBlogCfg.tag}}
+
+
{{homeBlogCfg.friendLink}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/MobShare.vue b/website/.vuepress/theme/components/MobShare.vue
new file mode 100644
index 00000000..afb81e4a
--- /dev/null
+++ b/website/.vuepress/theme/components/MobShare.vue
@@ -0,0 +1,30 @@
+
+
+
分享
+
+
+ 新浪微博
+ QQ空间
+ QQ好友
+ 豆瓣
+ Facebook
+
+
+
取消
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/Mode/ModePicker.vue b/website/.vuepress/theme/components/Mode/ModePicker.vue
new file mode 100644
index 00000000..60880d2a
--- /dev/null
+++ b/website/.vuepress/theme/components/Mode/ModePicker.vue
@@ -0,0 +1,102 @@
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/Mode/applyMode.js b/website/.vuepress/theme/components/Mode/applyMode.js
new file mode 100644
index 00000000..a4a0037e
--- /dev/null
+++ b/website/.vuepress/theme/components/Mode/applyMode.js
@@ -0,0 +1,35 @@
+import modeOptions from './modeOptions'
+
+function render (mode) {
+ const rootElement = document.querySelector(':root')
+ const options = modeOptions[mode]
+
+ for (const k in options) {
+ rootElement.style.setProperty(k, options[k])
+ }
+}
+
+/**
+ * Sets a color scheme for the website.
+ * If browser supports "prefers-color-scheme", 'auto' mode will respect the setting for light or dark mode
+ * otherwise it will set a dark theme during night time
+ */
+export default function applyMode (mode) {
+ if (mode !== 'auto') {
+ render(mode)
+ return
+ }
+
+ const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches
+ const isLightMode = window.matchMedia('(prefers-color-scheme: light)').matches
+
+ if (isDarkMode) render('dark')
+ if (isLightMode) render('light')
+
+ if (!isDarkMode && !isLightMode) {
+ console.log('You specified no preference for a color scheme or your browser does not support it. I schedule dark mode during night time.')
+ const hour = new Date().getHours()
+ if (hour < 6 || hour >= 18) render('dark')
+ else render('light')
+ }
+}
diff --git a/website/.vuepress/theme/components/Mode/index.vue b/website/.vuepress/theme/components/Mode/index.vue
new file mode 100755
index 00000000..5f11859e
--- /dev/null
+++ b/website/.vuepress/theme/components/Mode/index.vue
@@ -0,0 +1,114 @@
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/Mode/modeOptions.js b/website/.vuepress/theme/components/Mode/modeOptions.js
new file mode 100644
index 00000000..fe48e9ee
--- /dev/null
+++ b/website/.vuepress/theme/components/Mode/modeOptions.js
@@ -0,0 +1,44 @@
+const modeOptions = {
+ light: {
+ '--default-color-10': 'rgba(255, 255, 255, 1)',
+ '--default-color-9': 'rgba(255, 255, 255, .9)',
+ '--default-color-8': 'rgba(255, 255, 255, .8)',
+ '--default-color-7': 'rgba(255, 255, 255, .7)',
+ '--default-color-6': 'rgba(255, 255, 255, .6)',
+ '--default-color-5': 'rgba(255, 255, 255, .5)',
+ '--default-color-4': 'rgba(255, 255, 255, .4)',
+ '--default-color-3': 'rgba(255, 255, 255, .3)',
+ '--default-color-2': 'rgba(255, 255, 255, .2)',
+ '--default-color-1': 'rgba(255, 255, 255, .1)',
+ '--background-color': '#fff',
+ '--box-shadow': '0 1px 6px 0 rgba(0, 0, 0, 0.2)',
+ '--box-shadow-hover': '0 2px 16px 0 rgba(0, 0, 0, 0.2)',
+ '--text-color': '#242424',
+ '--text-color-sub': '#7F7F7F',
+ '--border-color': '#eaecef',
+ '--code-color': 'rgba(27, 31, 35, 0.05)',
+ '--mask-color': '#888'
+ },
+ dark: {
+ '--default-color-10': 'rgba(0, 0, 0, 1)',
+ '--default-color-9': 'rgba(0, 0, 0, .9)',
+ '--default-color-8': 'rgba(0, 0, 0, .8)',
+ '--default-color-7': 'rgba(0, 0, 0, .7)',
+ '--default-color-6': 'rgba(0, 0, 0, .6)',
+ '--default-color-5': 'rgba(0, 0, 0, .5)',
+ '--default-color-4': 'rgba(0, 0, 0, .4)',
+ '--default-color-3': 'rgba(0, 0, 0, .3)',
+ '--default-color-2': 'rgba(0, 0, 0, .2)',
+ '--default-color-1': 'rgba(0, 0, 0, .1)',
+ '--background-color': '#181818',
+ '--box-shadow': '0 1px 6px 0 rgba(0, 0, 0, .9)',
+ '--box-shadow-hover': '0 2px 26px 0 rgba(0, 0, 0, .9)',
+ '--text-color': 'rgba(255, 255, 255, .8)',
+ '--text-color-sub': '#8B8B8B',
+ '--border-color': 'rgba(0, 0, 0, .3)',
+ '--code-color': 'rgba(0, 0, 0, .3)',
+ '--mask-color': '#000'
+ }
+}
+
+export default modeOptions
diff --git a/website/.vuepress/theme/components/ModuleTransition.vue b/website/.vuepress/theme/components/ModuleTransition.vue
new file mode 100644
index 00000000..5b114f54
--- /dev/null
+++ b/website/.vuepress/theme/components/ModuleTransition.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/NavLink.vue b/website/.vuepress/theme/components/NavLink.vue
new file mode 100644
index 00000000..40621a23
--- /dev/null
+++ b/website/.vuepress/theme/components/NavLink.vue
@@ -0,0 +1,52 @@
+
+
+
+ {{ item.text }}
+
+
+
+ {{ item.text }}
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/NavLinks.vue b/website/.vuepress/theme/components/NavLinks.vue
new file mode 100644
index 00000000..00b52d53
--- /dev/null
+++ b/website/.vuepress/theme/components/NavLinks.vue
@@ -0,0 +1,188 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ repoLabel }}
+
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/Navbar.vue b/website/.vuepress/theme/components/Navbar.vue
new file mode 100644
index 00000000..ccc87b3c
--- /dev/null
+++ b/website/.vuepress/theme/components/Navbar.vue
@@ -0,0 +1,131 @@
+
+
+
+
+
+
+ {{ $siteTitle }}
+
+
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/NoteAbstract.vue b/website/.vuepress/theme/components/NoteAbstract.vue
new file mode 100644
index 00000000..a6d31b61
--- /dev/null
+++ b/website/.vuepress/theme/components/NoteAbstract.vue
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/NoteAbstractItem.vue b/website/.vuepress/theme/components/NoteAbstractItem.vue
new file mode 100644
index 00000000..9e066cfa
--- /dev/null
+++ b/website/.vuepress/theme/components/NoteAbstractItem.vue
@@ -0,0 +1,86 @@
+
+
+
+
+
+ {{item.title}}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/Page.vue b/website/.vuepress/theme/components/Page.vue
new file mode 100644
index 00000000..6bf13041
--- /dev/null
+++ b/website/.vuepress/theme/components/Page.vue
@@ -0,0 +1,282 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ lastUpdatedText }}:
+ {{ lastUpdated }}
+
+
+
+
+
+
+
+
+ ←
+
+ {{ prev.title || prev.path }}
+
+
+
+
+
+ {{ next.title || next.path }}
+
+ →
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/PageInfo.vue b/website/.vuepress/theme/components/PageInfo.vue
new file mode 100644
index 00000000..9caa2b76
--- /dev/null
+++ b/website/.vuepress/theme/components/PageInfo.vue
@@ -0,0 +1,114 @@
+
+
+
+ {{ pageInfo.frontmatter.author || $themeConfig.author || $site.title }}
+
+
+ {{ pageInfo.frontmatter.date | formatDateValue }}
+
+
+
+
+
+
+ {{subItem}}
+
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/Password.vue b/website/.vuepress/theme/components/Password.vue
new file mode 100644
index 00000000..523f75a3
--- /dev/null
+++ b/website/.vuepress/theme/components/Password.vue
@@ -0,0 +1,327 @@
+
+
+
+ {{isPage ? $frontmatter.title : $site.title || $localeConfig.title}}
+
+
+
+ {{$site.description || $localeConfig.description}}
+
+
+
+
+
+ {{warningText}}
+ OK
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/PersonalInfo.vue b/website/.vuepress/theme/components/PersonalInfo.vue
new file mode 100644
index 00000000..036ea1ab
--- /dev/null
+++ b/website/.vuepress/theme/components/PersonalInfo.vue
@@ -0,0 +1,75 @@
+
+
+
+
+ {{ $themeConfig.author || $site.title }}
+
+
+
+
{{$recoPosts.length}}
+ {{homeBlogCfg.article}}
+
+
+
{{$tags.list.length}}
+ {{homeBlogCfg.tag}}
+
+
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/SearchBox.vue b/website/.vuepress/theme/components/SearchBox.vue
new file mode 100644
index 00000000..365c308c
--- /dev/null
+++ b/website/.vuepress/theme/components/SearchBox.vue
@@ -0,0 +1,238 @@
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/Sidebar.vue b/website/.vuepress/theme/components/Sidebar.vue
new file mode 100644
index 00000000..57f34d7e
--- /dev/null
+++ b/website/.vuepress/theme/components/Sidebar.vue
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/SidebarButton.vue b/website/.vuepress/theme/components/SidebarButton.vue
new file mode 100644
index 00000000..b8fb4150
--- /dev/null
+++ b/website/.vuepress/theme/components/SidebarButton.vue
@@ -0,0 +1,27 @@
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/SidebarGroup.vue b/website/.vuepress/theme/components/SidebarGroup.vue
new file mode 100644
index 00000000..5f726a97
--- /dev/null
+++ b/website/.vuepress/theme/components/SidebarGroup.vue
@@ -0,0 +1,129 @@
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/SidebarLink.vue b/website/.vuepress/theme/components/SidebarLink.vue
new file mode 100644
index 00000000..7ad741a5
--- /dev/null
+++ b/website/.vuepress/theme/components/SidebarLink.vue
@@ -0,0 +1,115 @@
+
+
+
diff --git a/website/.vuepress/theme/components/SidebarLinks.vue b/website/.vuepress/theme/components/SidebarLinks.vue
new file mode 100644
index 00000000..9d45bfe3
--- /dev/null
+++ b/website/.vuepress/theme/components/SidebarLinks.vue
@@ -0,0 +1,141 @@
+
+
+
+
+
diff --git a/website/.vuepress/theme/components/TagList.vue b/website/.vuepress/theme/components/TagList.vue
new file mode 100644
index 00000000..55e3e956
--- /dev/null
+++ b/website/.vuepress/theme/components/TagList.vue
@@ -0,0 +1,58 @@
+
+
+ {{item.name}}
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/enhanceApp.js b/website/.vuepress/theme/enhanceApp.js
new file mode 100644
index 00000000..e325e2bb
--- /dev/null
+++ b/website/.vuepress/theme/enhanceApp.js
@@ -0,0 +1,9 @@
+import postMixin from '@theme/mixins/posts'
+import localMixin from '@theme/mixins/locals'
+
+export default ({
+ Vue
+}) => {
+ Vue.mixin(postMixin)
+ Vue.mixin(localMixin)
+}
diff --git a/website/.vuepress/theme/global-components/Badge.vue b/website/.vuepress/theme/global-components/Badge.vue
new file mode 100644
index 00000000..019ba4d6
--- /dev/null
+++ b/website/.vuepress/theme/global-components/Badge.vue
@@ -0,0 +1,45 @@
+
+
+
diff --git a/website/.vuepress/theme/helpers/other.js b/website/.vuepress/theme/helpers/other.js
new file mode 100644
index 00000000..be543189
--- /dev/null
+++ b/website/.vuepress/theme/helpers/other.js
@@ -0,0 +1,18 @@
+export function getOneColor () {
+ const tagColorArr = [
+ '#e15b64',
+ '#f47e60',
+ '#f8b26a',
+ '#abbd81',
+ '#849b87',
+ '#e15b64',
+ '#f47e60',
+ '#f8b26a',
+ '#f26d6d',
+ '#67cc86',
+ '#fb9b5f',
+ '#3498db'
+ ]
+ const index = Math.floor(Math.random() * tagColorArr.length)
+ return tagColorArr[index]
+}
diff --git a/website/.vuepress/theme/helpers/postData.js b/website/.vuepress/theme/helpers/postData.js
new file mode 100644
index 00000000..95748e29
--- /dev/null
+++ b/website/.vuepress/theme/helpers/postData.js
@@ -0,0 +1,41 @@
+import { compareDate } from '@theme/helpers/utils'
+
+// 过滤博客数据
+export function filterPosts (posts, isTimeline) {
+ posts = posts.filter((item, index) => {
+ const { title, frontmatter: { home, date, publish }} = item
+ // 过滤多个分类时产生的重复数据
+ if (posts.indexOf(item) !== index) {
+ return false
+ } else {
+ const someConditions = home == true || title == undefined || publish === false
+ const boo = isTimeline === true
+ ? !(someConditions || date === undefined)
+ : !someConditions
+ return boo
+ }
+ })
+ return posts
+}
+
+// 排序博客数据
+export function sortPostsByStickyAndDate (posts) {
+ posts.sort((prev, next) => {
+ const prevSticky = prev.frontmatter.sticky
+ const nextSticky = next.frontmatter.sticky
+ if (prevSticky && nextSticky) {
+ return prevSticky == nextSticky ? compareDate(prev, next) : (prevSticky - nextSticky)
+ } else if (prevSticky && !nextSticky) {
+ return -1
+ } else if (!prevSticky && nextSticky) {
+ return 1
+ }
+ return compareDate(prev, next)
+ })
+}
+
+export function sortPostsByDate (posts) {
+ posts.sort((prev, next) => {
+ return compareDate(prev, next)
+ })
+}
diff --git a/website/.vuepress/theme/helpers/utils.js b/website/.vuepress/theme/helpers/utils.js
new file mode 100644
index 00000000..80c3efcb
--- /dev/null
+++ b/website/.vuepress/theme/helpers/utils.js
@@ -0,0 +1,273 @@
+export const hashRE = /#.*$/
+export const extRE = /\.(md|html)$/
+export const endingSlashRE = /\/$/
+export const outboundRE = /^(https?:|mailto:|tel:)/
+
+export function normalize (path) {
+ return decodeURI(path)
+ .replace(hashRE, '')
+ .replace(extRE, '')
+}
+
+export function getHash (path) {
+ const match = path.match(hashRE)
+ if (match) {
+ return match[0]
+ }
+}
+
+export function isExternal (path) {
+ return outboundRE.test(path)
+}
+
+export function isMailto (path) {
+ return /^mailto:/.test(path)
+}
+
+export function isTel (path) {
+ return /^tel:/.test(path)
+}
+
+export function ensureExt (path) {
+ if (isExternal(path)) {
+ return path
+ }
+ const hashMatch = path.match(hashRE)
+ const hash = hashMatch ? hashMatch[0] : ''
+ const normalized = normalize(path)
+
+ if (endingSlashRE.test(normalized)) {
+ return path
+ }
+ return normalized + '.html' + hash
+}
+
+export function isActive (route, path) {
+ const routeHash = route.hash
+ const linkHash = getHash(path)
+ if (linkHash && routeHash !== linkHash) {
+ return false
+ }
+ const routePath = normalize(route.path)
+ const pagePath = normalize(path)
+ return routePath === pagePath
+}
+
+export function resolvePage (pages, rawPath, base) {
+ if (base) {
+ rawPath = resolvePath(rawPath, base)
+ }
+ const path = normalize(rawPath)
+ for (let i = 0; i < pages.length; i++) {
+ if (normalize(pages[i].regularPath) === path) {
+ return Object.assign({}, pages[i], {
+ type: 'page',
+ path: ensureExt(pages[i].path)
+ })
+ }
+ }
+ console.error(`[vuepress] No matching page found for sidebar item "${rawPath}"`)
+ return {}
+}
+
+function resolvePath (relative, base, append) {
+ const firstChar = relative.charAt(0)
+ if (firstChar === '/') {
+ return relative
+ }
+
+ if (firstChar === '?' || firstChar === '#') {
+ return base + relative
+ }
+
+ const stack = base.split('/')
+
+ // remove trailing segment if:
+ // - not appending
+ // - appending to trailing slash (last segment is empty)
+ if (!append || !stack[stack.length - 1]) {
+ stack.pop()
+ }
+
+ // resolve relative path
+ const segments = relative.replace(/^\//, '').split('/')
+ for (let i = 0; i < segments.length; i++) {
+ const segment = segments[i]
+ if (segment === '..') {
+ stack.pop()
+ } else if (segment !== '.') {
+ stack.push(segment)
+ }
+ }
+
+ // ensure leading slash
+ if (stack[0] !== '') {
+ stack.unshift('')
+ }
+
+ return stack.join('/')
+}
+
+/**
+ * @param { Page } page
+ * @param { string } regularPath
+ * @param { SiteData } site
+ * @param { string } localePath
+ * @returns { SidebarGroup }
+ */
+export function resolveSidebarItems (page, regularPath, site, localePath) {
+ const { pages, themeConfig } = site
+
+ const localeConfig = localePath && themeConfig.locales
+ ? themeConfig.locales[localePath] || themeConfig
+ : themeConfig
+
+ const pageSidebarConfig = page.frontmatter.sidebar || localeConfig.sidebar || themeConfig.sidebar
+ if (pageSidebarConfig === 'auto') {
+ return resolveHeaders(page)
+ }
+
+ const sidebarConfig = localeConfig.sidebar || themeConfig.sidebar
+ if (!sidebarConfig) {
+ return []
+ } else {
+ const { base, config } = resolveMatchingConfig(regularPath, sidebarConfig)
+ return config
+ ? config.map(item => resolveItem(item, pages, base))
+ : []
+ }
+}
+
+/**
+ * @param { Page } page
+ * @returns { SidebarGroup }
+ */
+function resolveHeaders (page) {
+ const headers = groupHeaders(page.headers || [])
+ return [{
+ type: 'group',
+ collapsable: false,
+ title: page.title,
+ path: null,
+ children: headers.map(h => ({
+ type: 'auto',
+ title: h.title,
+ basePath: page.path,
+ path: page.path + '#' + h.slug,
+ children: h.children || []
+ }))
+ }]
+}
+
+export function groupHeaders (headers) {
+ // group h3s under h2
+ headers = headers.map(h => Object.assign({}, h))
+ let lastH2
+ headers.forEach(h => {
+ if (h.level === 2) {
+ lastH2 = h
+ } else if (lastH2) {
+ (lastH2.children || (lastH2.children = [])).push(h)
+ }
+ })
+ return headers.filter(h => h.level === 2)
+}
+
+export function resolveNavLinkItem (linkItem) {
+ return Object.assign(linkItem, {
+ type: linkItem.items && linkItem.items.length ? 'links' : 'link'
+ })
+}
+
+/**
+ * @param { Route } route
+ * @param { Array | Array | [link: string]: SidebarConfig } config
+ * @returns { base: string, config: SidebarConfig }
+ */
+export function resolveMatchingConfig (regularPath, config) {
+ if (Array.isArray(config)) {
+ return {
+ base: '/',
+ config: config
+ }
+ }
+ for (const base in config) {
+ if (ensureEndingSlash(regularPath).indexOf(encodeURI(base)) === 0) {
+ return {
+ base,
+ config: config[base]
+ }
+ }
+ }
+ return {}
+}
+
+export function formatDate (time, fmt = 'yyyy-MM-dd hh:mm:ss') {
+ time = time.replace(/-/g, '/')
+ const date = new Date(time)
+ if (/(y+)/.test(fmt)) {
+ fmt = fmt.replace(RegExp.$1, date.getFullYear() + '').substr(4 - RegExp.$1.length)
+ }
+
+ const o = {
+ 'M+': date.getMonth() + 1,
+ 'd+': date.getDate(),
+ 'h+': date.getHours(),
+ 'm+': date.getMinutes(),
+ 's+': date.getSeconds()
+ }
+
+ for (const key in o) {
+ if (RegExp(`(${key})`).test(fmt)) {
+ const str = o[key] + ''
+ fmt = fmt.replace(RegExp.$1, str.length === 2 ? str : '0' + str)
+ }
+ }
+ return fmt
+}
+
+// 获取时间的数字类型
+export function getTimeNum (date) {
+ return new Date(date.frontmatter.date).getTime()
+}
+
+// 比对时间
+export function compareDate (a, b) {
+ return getTimeNum(b) - getTimeNum(a)
+}
+
+function ensureEndingSlash (path) {
+ return /(\.html|\/)$/.test(path)
+ ? path
+ : path + '/'
+}
+
+function resolveItem (item, pages, base, groupDepth = 1) {
+ if (typeof item === 'string') {
+ return resolvePage(pages, item, base)
+ } else if (Array.isArray(item)) {
+ return Object.assign(resolvePage(pages, item[0], base), {
+ title: item[1]
+ })
+ } else {
+ if (groupDepth > 3) {
+ console.error(
+ '[vuepress] detected a too deep nested sidebar group.'
+ )
+ }
+ const children = item.children || []
+ if (children.length === 0 && item.path) {
+ return Object.assign(resolvePage(pages, item.path, base), {
+ title: item.title
+ })
+ }
+ return {
+ type: 'group',
+ path: item.path,
+ title: item.title,
+ sidebarDepth: item.sidebarDepth,
+ children: children.map(child => resolveItem(child, pages, base, groupDepth + 1)),
+ collapsable: item.collapsable !== false
+ }
+ }
+}
diff --git a/website/.vuepress/theme/images/home-bg.jpg b/website/.vuepress/theme/images/home-bg.jpg
new file mode 100644
index 00000000..02d4a81b
Binary files /dev/null and b/website/.vuepress/theme/images/home-bg.jpg differ
diff --git a/website/.vuepress/theme/images/home-head.png b/website/.vuepress/theme/images/home-head.png
new file mode 100644
index 00000000..72247268
Binary files /dev/null and b/website/.vuepress/theme/images/home-head.png differ
diff --git a/website/.vuepress/theme/images/icon_vuepress_reco.png b/website/.vuepress/theme/images/icon_vuepress_reco.png
new file mode 100644
index 00000000..ac012529
Binary files /dev/null and b/website/.vuepress/theme/images/icon_vuepress_reco.png differ
diff --git a/website/.vuepress/theme/index.js b/website/.vuepress/theme/index.js
new file mode 100644
index 00000000..6835f6d7
--- /dev/null
+++ b/website/.vuepress/theme/index.js
@@ -0,0 +1,97 @@
+const path = require('path')
+
+// Theme API.
+module.exports = (options, ctx) => ({
+ alias () {
+ const { themeConfig, siteConfig } = ctx
+ // resolve algolia
+ const isAlgoliaSearch = (
+ themeConfig.algolia ||
+ Object.keys(siteConfig.locales && themeConfig.locales || {})
+ .some(base => themeConfig.locales[base].algolia)
+ )
+ return {
+ '@AlgoliaSearchBox': isAlgoliaSearch
+ ? path.resolve(__dirname, 'components/AlgoliaSearchBox.vue')
+ : path.resolve(__dirname, 'noopModule.js'),
+ '@SearchBox': path.resolve(__dirname, 'components/SearchBox.vue')
+ }
+ },
+
+ plugins: [
+ '@vuepress-reco/back-to-top',
+ '@vuepress-reco/loading-page',
+ '@vuepress-reco/pagation',
+ '@vuepress-reco/comments',
+ '@vuepress/active-header-links',
+ ['@vuepress/medium-zoom', {
+ selector: '.theme-reco-content :not(a) > img'
+ }],
+ '@vuepress/plugin-nprogress',
+ ['@vuepress/plugin-blog', {
+ permalink: '/:regular',
+ frontmatters: [
+ {
+ id: 'tags',
+ keys: ['tags'],
+ path: '/tag/',
+ layout: 'Tags',
+ scopeLayout: 'Tag'
+ },
+ {
+ id: 'categories',
+ keys: ['categories'],
+ path: '/categories/',
+ layout: 'Categories',
+ scopeLayout: 'Category'
+ },
+ {
+ id: 'timeline',
+ keys: ['timeline'],
+ path: '/timeline/',
+ layout: 'TimeLines',
+ scopeLayout: 'TimeLine'
+ }
+ ]
+ }],
+ ['container', {
+ type: 'tip',
+ defaultTitle: {
+ '/': '',
+ '/zh/': '提示'
+ }
+ }],
+ ['container', {
+ type: 'warning',
+ defaultTitle: {
+ '/': '',
+ '/zh/': '注意'
+ }
+ }],
+ ['container', {
+ type: 'danger',
+ defaultTitle: {
+ '/': '',
+ '/zh/': '警告'
+ }
+ }],
+ ['container', {
+ type: 'right',
+ defaultTitle: ''
+ }],
+ ['container', {
+ type: 'theorem',
+ before: info => `'
+ }],
+ ['container', {
+ type: 'details',
+ before: info => `${info ? `${info} ` : ''}\n`,
+ after: () => ' \n',
+ defaultTitle: {
+ '/': 'See More',
+ '/zh/': '更多'
+ }
+ }]
+ ]
+})
diff --git a/website/.vuepress/theme/layouts/404.vue b/website/.vuepress/theme/layouts/404.vue
new file mode 100644
index 00000000..3b3a22fc
--- /dev/null
+++ b/website/.vuepress/theme/layouts/404.vue
@@ -0,0 +1,69 @@
+
+
+
+ 404
+ {{ getMsg() }}
+ Take me home.
+
+
+
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/layouts/Category.vue b/website/.vuepress/theme/layouts/Category.vue
new file mode 100644
index 00000000..71fb8153
--- /dev/null
+++ b/website/.vuepress/theme/layouts/Category.vue
@@ -0,0 +1,169 @@
+
+
+
+
+
+
+
+ {{ item.name }}
+ {{ item.pages.length }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/layouts/Layout.vue b/website/.vuepress/theme/layouts/Layout.vue
new file mode 100644
index 00000000..8123cbf8
--- /dev/null
+++ b/website/.vuepress/theme/layouts/Layout.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/layouts/Tag.vue b/website/.vuepress/theme/layouts/Tag.vue
new file mode 100644
index 00000000..7f761c1d
--- /dev/null
+++ b/website/.vuepress/theme/layouts/Tag.vue
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/layouts/Tags.vue b/website/.vuepress/theme/layouts/Tags.vue
new file mode 100644
index 00000000..aecf550c
--- /dev/null
+++ b/website/.vuepress/theme/layouts/Tags.vue
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/layouts/TimeLines.vue b/website/.vuepress/theme/layouts/TimeLines.vue
new file mode 100644
index 00000000..30dd5f2a
--- /dev/null
+++ b/website/.vuepress/theme/layouts/TimeLines.vue
@@ -0,0 +1,153 @@
+
+
+
+
+ Yesterday Once More!
+
+
+
+ {{item.year}}
+
+
+ {{subItem.frontmatter.date | dateFormat}}
+ {{subItem.title}}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/website/.vuepress/theme/lib/vuepress-theme-reco.js b/website/.vuepress/theme/lib/vuepress-theme-reco.js
new file mode 100644
index 00000000..ee7a9c3c
--- /dev/null
+++ b/website/.vuepress/theme/lib/vuepress-theme-reco.js
@@ -0,0 +1,7 @@
+'use strict'
+
+module.exports = vuepressThemeReco
+
+function vuepressThemeReco () {
+ // TODO
+}
diff --git a/website/.vuepress/theme/locals/en.js b/website/.vuepress/theme/locals/en.js
new file mode 100644
index 00000000..1d917f24
--- /dev/null
+++ b/website/.vuepress/theme/locals/en.js
@@ -0,0 +1,8 @@
+export default {
+ homeBlog: {
+ article: 'Article',
+ tag: 'Tag',
+ category: 'Category',
+ friendLink: 'Friend Link'
+ }
+}
diff --git a/website/.vuepress/theme/locals/index.js b/website/.vuepress/theme/locals/index.js
new file mode 100644
index 00000000..05f22191
--- /dev/null
+++ b/website/.vuepress/theme/locals/index.js
@@ -0,0 +1,7 @@
+import zhHans from './zh-hans.js'
+import zhHant from './zh-hant.js'
+import en from './en.js'
+import ja from './ja.js'
+import ko from './ko.js'
+
+export { zhHans, zhHant, en, ja, ko }
diff --git a/website/.vuepress/theme/locals/ja.js b/website/.vuepress/theme/locals/ja.js
new file mode 100644
index 00000000..c5b81f8f
--- /dev/null
+++ b/website/.vuepress/theme/locals/ja.js
@@ -0,0 +1,8 @@
+export default {
+ homeBlog: {
+ article: '文章',
+ tag: 'ラベル',
+ category: '分類',
+ friendLink: '友情リンク'
+ }
+}
diff --git a/website/.vuepress/theme/locals/ko.js b/website/.vuepress/theme/locals/ko.js
new file mode 100644
index 00000000..7b53fe35
--- /dev/null
+++ b/website/.vuepress/theme/locals/ko.js
@@ -0,0 +1,8 @@
+export default {
+ homeBlog: {
+ article: '글',
+ tag: '태그',
+ category: '분류',
+ friendLink: '링크 참조'
+ }
+}
diff --git a/website/.vuepress/theme/locals/zh-hans.js b/website/.vuepress/theme/locals/zh-hans.js
new file mode 100644
index 00000000..adf34dba
--- /dev/null
+++ b/website/.vuepress/theme/locals/zh-hans.js
@@ -0,0 +1,8 @@
+export default {
+ homeBlog: {
+ article: '文章',
+ tag: '标签',
+ category: '分类',
+ friendLink: '友情链接'
+ }
+}
diff --git a/website/.vuepress/theme/locals/zh-hant.js b/website/.vuepress/theme/locals/zh-hant.js
new file mode 100644
index 00000000..e84913f2
--- /dev/null
+++ b/website/.vuepress/theme/locals/zh-hant.js
@@ -0,0 +1,8 @@
+export default {
+ homeBlog: {
+ article: '文章',
+ tag: '標簽',
+ category: '分類',
+ friendLink: '友情鏈接'
+ }
+}
diff --git a/website/.vuepress/theme/mixins/index.js b/website/.vuepress/theme/mixins/index.js
new file mode 100644
index 00000000..5afa78a9
--- /dev/null
+++ b/website/.vuepress/theme/mixins/index.js
@@ -0,0 +1,26 @@
+export default {
+ methods: {
+ _tagColor () {
+ const tagColorArr = ['#e15b64', '#f47e60', '#f8b26a', '#abbd81', '#849b87', '#e15b64', '#f47e60', '#f8b26a', '#f26d6d', '#67cc86', '#fb9b5f', '#3498db']
+ const index = Math.floor(Math.random() * tagColorArr.length)
+ return tagColorArr[index]
+ },
+ // 获取当前页码
+ _getStoragePage () {
+ const path = window.location.pathname
+ const currentPage = JSON.parse(sessionStorage.getItem('currentPage'))
+
+ if (currentPage === null || path !== currentPage.path) {
+ sessionStorage.setItem('currentPage', { page: 1, path: '' })
+ return 1
+ }
+
+ return parseInt(currentPage.page)
+ },
+ // 设置当前页码
+ _setStoragePage (page) {
+ const path = window.location.pathname
+ sessionStorage.setItem('currentPage', JSON.stringify({ page, path }))
+ }
+ }
+}
diff --git a/website/.vuepress/theme/mixins/locals.js b/website/.vuepress/theme/mixins/locals.js
new file mode 100644
index 00000000..58abc458
--- /dev/null
+++ b/website/.vuepress/theme/mixins/locals.js
@@ -0,0 +1,25 @@
+import { zhHans, zhHant, en, ja, ko } from '../locals/index'
+
+export default {
+ computed: {
+ $recoLocals () {
+ const recoLocals = this.$themeLocaleConfig.recoLocals
+ if (recoLocals) {
+ return recoLocals
+ }
+ if (/^zh\-(CN|SG)$/.test(this.$lang)) {
+ return zhHans
+ }
+ if (/^zh\-(HK|MO|TW)$/.test(this.$lang)) {
+ return zhHant
+ }
+ if (/^ja\-JP$/.test(this.$lang)) {
+ return ja
+ }
+ if (/^ko\-KR$/.test(this.$lang)) {
+ return ko
+ }
+ return en
+ }
+ }
+}
diff --git a/website/.vuepress/theme/mixins/moduleTransiton.js b/website/.vuepress/theme/mixins/moduleTransiton.js
new file mode 100644
index 00000000..42cf101a
--- /dev/null
+++ b/website/.vuepress/theme/mixins/moduleTransiton.js
@@ -0,0 +1,13 @@
+export default {
+ data () {
+ return {
+ recoShowModule: false
+ }
+ },
+ mounted () {
+ this.recoShowModule = true
+ },
+ destroyed () {
+ this.recoShowModule = false
+ }
+}
diff --git a/website/.vuepress/theme/mixins/pagination.js b/website/.vuepress/theme/mixins/pagination.js
new file mode 100644
index 00000000..dbefecc7
--- /dev/null
+++ b/website/.vuepress/theme/mixins/pagination.js
@@ -0,0 +1,21 @@
+export default {
+ methods: {
+ // 获取当前页码
+ _getStoragePage () {
+ const path = window.location.pathname
+ const currentPage = JSON.parse(sessionStorage.getItem('currentPage'))
+
+ if (currentPage === null || path !== currentPage.path) {
+ sessionStorage.setItem('currentPage', { page: 1, path: '' })
+ return 1
+ }
+
+ return parseInt(currentPage.page)
+ },
+ // 设置当前页码
+ _setStoragePage (page) {
+ const path = window.location.pathname
+ sessionStorage.setItem('currentPage', JSON.stringify({ page, path }))
+ }
+ }
+}
diff --git a/website/.vuepress/theme/mixins/posts.js b/website/.vuepress/theme/mixins/posts.js
new file mode 100644
index 00000000..4c71405b
--- /dev/null
+++ b/website/.vuepress/theme/mixins/posts.js
@@ -0,0 +1,60 @@
+import { filterPosts, sortPostsByStickyAndDate, sortPostsByDate } from '../helpers/postData'
+
+export default {
+ computed: {
+ $recoPosts () {
+ const {
+ $categories: { list: articles }
+ } = this
+
+ let posts = articles.reduce((allData, currentData) => {
+ return [...allData, ...currentData.pages]
+ }, [])
+
+ posts = filterPosts(posts, false)
+ sortPostsByStickyAndDate(posts)
+
+ return posts
+ },
+ $recoPostsForTimeline () {
+ let pages = this.$recoPosts
+ const formatPages = {}
+ const formatPagesArr = []
+ pages = filterPosts(pages, true)
+ this.pages = pages.length == 0 ? [] : pages
+ for (let i = 0, length = pages.length; i < length; i++) {
+ const page = pages[i]
+ const pageDateYear = dateFormat(page.frontmatter.date, 'year')
+ if (formatPages[pageDateYear]) formatPages[pageDateYear].push(page)
+ else {
+ formatPages[pageDateYear] = [page]
+ }
+ }
+
+ for (const key in formatPages) {
+ const data = formatPages[key]
+ sortPostsByDate(data)
+ formatPagesArr.unshift({
+ year: key,
+ data
+ })
+ }
+
+ return formatPagesArr
+ }
+ }
+}
+
+function renderTime (date) {
+ var dateee = new Date(date).toJSON()
+ return new Date(+new Date(dateee) + 8 * 3600 * 1000).toISOString().replace(/T/g, ' ').replace(/\.[\d]{3}Z/, '').replace(/-/g, '/')
+}
+function dateFormat (date, type) {
+ date = renderTime(date)
+ const dateObj = new Date(date)
+ const year = dateObj.getFullYear()
+ const mon = dateObj.getMonth() + 1
+ const day = dateObj.getDate()
+ if (type == 'year') return year
+ else return `${mon}-${day}`
+}
diff --git a/website/.vuepress/theme/noopModule.js b/website/.vuepress/theme/noopModule.js
new file mode 100644
index 00000000..b1c6ea43
--- /dev/null
+++ b/website/.vuepress/theme/noopModule.js
@@ -0,0 +1 @@
+export default {}
diff --git a/website/.vuepress/theme/package.json b/website/.vuepress/theme/package.json
new file mode 100644
index 00000000..650d415e
--- /dev/null
+++ b/website/.vuepress/theme/package.json
@@ -0,0 +1,65 @@
+{
+ "_args": [
+ [
+ "vuepress-theme-reco@1.4.5",
+ "/Users/haolin3/Project/hello-algorithm"
+ ]
+ ],
+ "_development": true,
+ "_from": "vuepress-theme-reco@1.4.5",
+ "_id": "vuepress-theme-reco@1.4.5",
+ "_inBundle": false,
+ "_integrity": "sha512-6PUIzDIzfs8ZCdnUiPdYuCc1IHpRDuNXvD0RuBCbw8N6LsBsPSJy7aiffcDebjDyOpFFkEzTBDNH1EtVGkbExg==",
+ "_location": "/vuepress-theme-reco",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "version",
+ "registry": true,
+ "raw": "vuepress-theme-reco@1.4.5",
+ "name": "vuepress-theme-reco",
+ "escapedName": "vuepress-theme-reco",
+ "rawSpec": "1.4.5",
+ "saveSpec": null,
+ "fetchSpec": "1.4.5"
+ },
+ "_requiredBy": [
+ "#DEV:/"
+ ],
+ "_resolved": "https://registry.npmjs.org/vuepress-theme-reco/-/vuepress-theme-reco-1.4.5.tgz",
+ "_spec": "1.4.5",
+ "_where": "/Users/haolin3/Project/hello-algorithm",
+ "author": {
+ "name": "reco_luan"
+ },
+ "bugs": {
+ "url": "https://github.com/vuepress-reco/vuepress-theme-reco/issues"
+ },
+ "dependencies": {
+ "@vuepress-reco/vuepress-plugin-back-to-top": "^1.4.0",
+ "@vuepress-reco/vuepress-plugin-comments": "^1.4.3",
+ "@vuepress-reco/vuepress-plugin-loading-page": "^1.4.0",
+ "@vuepress-reco/vuepress-plugin-pagation": "^1.4.0",
+ "@vuepress/plugin-blog": "1.9.2",
+ "@vuepress/plugin-medium-zoom": "1.4.1",
+ "docsearch.js": "2.6.3",
+ "md5": "2.2.1",
+ "valine": "1.4.4",
+ "vue-click-outside": "1.1.0"
+ },
+ "description": "A simple and beautiful vuepress Blog & Doc theme.",
+ "gitHead": "44f9d0eb140fed40ba3cce815213c978a06faee0",
+ "homepage": "https://vuepress-theme-reco.recoluan.com/",
+ "keywords": [
+ "vuepress",
+ "vue",
+ "theme"
+ ],
+ "license": "MIT",
+ "main": "index.js",
+ "name": "vuepress-theme-reco",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/vuepress-reco/vuepress-theme-reco.git"
+ },
+ "version": "1.4.5"
+}
diff --git a/website/.vuepress/theme/styles/arrow.styl b/website/.vuepress/theme/styles/arrow.styl
new file mode 100644
index 00000000..d116e1cc
--- /dev/null
+++ b/website/.vuepress/theme/styles/arrow.styl
@@ -0,0 +1,22 @@
+@require './config'
+
+.arrow
+ display inline-block
+ width 0
+ height 0
+ &.up
+ border-left 4px solid transparent
+ border-right 4px solid transparent
+ border-bottom 6px solid var(--text-color-sub)
+ &.down
+ border-left 4px solid transparent
+ border-right 4px solid transparent
+ border-top 6px solid var(--text-color-sub)
+ &.right
+ border-top 4px solid transparent
+ border-bottom 4px solid transparent
+ border-left 6px solid var(--text-color-sub)
+ &.left
+ border-top 4px solid transparent
+ border-bottom 4px solid transparent
+ border-right 6px solid var(--text-color-sub)
diff --git a/website/.vuepress/theme/styles/code.styl b/website/.vuepress/theme/styles/code.styl
new file mode 100644
index 00000000..0cfa3c1d
--- /dev/null
+++ b/website/.vuepress/theme/styles/code.styl
@@ -0,0 +1,135 @@
+.content__default
+ code
+ color lighten($textColor, 20%)
+ padding 0.25rem 0.5rem
+ margin 0
+ font-size 0.85em
+ background-color var(--code-color)
+ border-radius 3px
+ .token
+ &.deleted
+ color #EC5975
+ &.inserted
+ color $accentColor
+
+.content__default
+ pre, pre[class*="language-"]
+ line-height 1.4
+ padding 1.25rem 1.5rem
+ margin 0.85rem 0
+ background-color $codeBgColor
+ border-radius 6px
+ overflow auto
+ code
+ color #fff
+ padding 0
+ background-color transparent
+ border-radius 0
+
+div[class*="language-"]
+ position relative
+ background-color $codeBgColor
+ border-radius 6px
+ .highlight-lines
+ user-select none
+ padding-top 1.3rem
+ position absolute
+ top 0
+ left 0
+ width 100%
+ line-height 1.4
+ .highlighted
+ background-color rgba(0, 0, 0, 66%)
+ pre, pre[class*="language-"]
+ background transparent
+ position relative
+ z-index 1
+ &::before
+ position absolute
+ z-index 3
+ top 0.8em
+ right 1em
+ font-size 0.75rem
+ color rgba(255, 255, 255, 0.4)
+ &:not(.line-numbers-mode)
+ .line-numbers-wrapper
+ display none
+ &.line-numbers-mode
+ .highlight-lines .highlighted
+ position relative
+ &:before
+ content ' '
+ position absolute
+ z-index 3
+ left 0
+ top 0
+ display block
+ width $lineNumbersWrapperWidth
+ height 100%
+ background-color rgba(0, 0, 0, 66%)
+ pre
+ padding-left $lineNumbersWrapperWidth + 1 rem
+ vertical-align middle
+ .line-numbers-wrapper
+ position absolute
+ top 0
+ width $lineNumbersWrapperWidth
+ text-align center
+ color rgba(255, 255, 255, 0.3)
+ padding 1.25rem 0
+ line-height 1.4
+ br
+ user-select none
+ .line-number
+ position relative
+ z-index 4
+ user-select none
+ font-size 0.85em
+ &::after
+ content ''
+ position absolute
+ z-index 2
+ top 0
+ left 0
+ width $lineNumbersWrapperWidth
+ height 100%
+ border-radius 6px 0 0 6px
+ border-right 1px solid rgba(0, 0, 0, 66%)
+ background-color $codeBgColor
+
+
+for lang in $codeLang
+ div{'[class~="language-' + lang + '"]'}
+ &:before
+ content ('' + lang)
+
+div[class~="language-javascript"]
+ &:before
+ content "js"
+
+div[class~="language-typescript"]
+ &:before
+ content "ts"
+
+div[class~="language-markup"]
+ &:before
+ content "html"
+
+div[class~="language-markdown"]
+ &:before
+ content "md"
+
+div[class~="language-json"]:before
+ content "json"
+
+div[class~="language-ruby"]:before
+ content "rb"
+
+div[class~="language-python"]:before
+ content "py"
+
+div[class~="language-bash"]:before
+ content "sh"
+
+div[class~="language-php"]:before
+ content "php"
diff --git a/website/.vuepress/theme/styles/custom-blocks.styl b/website/.vuepress/theme/styles/custom-blocks.styl
new file mode 100644
index 00000000..54c564ec
--- /dev/null
+++ b/website/.vuepress/theme/styles/custom-blocks.styl
@@ -0,0 +1,51 @@
+.custom-block
+ .custom-block-title
+ font-weight 600
+ margin-bottom -0.4rem
+ &.tip, &.warning, &.danger
+ padding .1rem 1.5rem
+ border-left-width .5rem
+ border-left-style solid
+ margin 1rem 0
+ &.tip
+ background-color var(--code-color)
+ border-color #67cc86
+ .custom-block-title
+ color #67cc86
+ &.warning
+ background-color var(--code-color)
+ border-color #fb9b5f
+ .custom-block-title
+ color #fb9b5f
+ &.danger
+ background-color var(--code-color)
+ border-color #f26d6d
+ .custom-block-title
+ color #f26d6d
+ &.right
+ color transparentify($textColor, 0.4)
+ font-size 0.9rem
+ text-align right
+ &.theorem
+ margin 1rem 0
+ padding .1rem 1.5rem
+ border-radius 0.4rem
+ background-color var(--code-color)
+ .title
+ font-weight bold
+ &.details
+ display block
+ position relative
+ border-radius 2px
+ margin 1em 0
+ padding 1rem
+ background-color var(--code-color)
+ h4
+ margin-top 0
+ figure, p
+ &:last-child
+ margin-bottom 0
+ padding-bottom 0
+ summary
+ outline none
+ cursor pointer
diff --git a/website/.vuepress/theme/styles/iconfont.css b/website/.vuepress/theme/styles/iconfont.css
new file mode 100644
index 00000000..63028ad1
--- /dev/null
+++ b/website/.vuepress/theme/styles/iconfont.css
@@ -0,0 +1,174 @@
+@font-face {
+ font-family:"iconfont";
+ src: url('http://at.alicdn.com/t/font_1030519_ookn0nnv0z8.eot?t=1574737898757');
+ /* IE9 */
+ src: url('http://at.alicdn.com/t/font_1030519_ookn0nnv0z8.eot?t=1574737898757#iefix') format('embedded-opentype'),
+ /* IE6-IE8 */
+ url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'), url('http://at.alicdn.com/t/font_1030519_ookn0nnv0z8.woff?t=1574737898757') format('woff'), url('http://at.alicdn.com/t/font_1030519_ookn0nnv0z8.ttf?t=1574737898757') format('truetype'),
+ /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
+ url('http://at.alicdn.com/t/font_1030519_ookn0nnv0z8.svg?t=1574737898757#iconfont') format('svg');
+ /* iOS 4.1- */
+}
+.iconfont {
+ font-family:"iconfont" !important;
+ font-size: 16px;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+.reco-douban:before {
+ content:"\e603";
+}
+.reco-wechat:before {
+ content:"\e720";
+}
+.reco-color:before {
+ content:"\eae9";
+}
+.reco-blog:before {
+ content:"\e61d";
+}
+.reco-sf:before {
+ content:"\e610";
+}
+.reco-message:before {
+ content:"\e634";
+}
+.reco-eye:before {
+ content:"\e669";
+}
+.reco-search:before {
+ content:"\e611";
+}
+.reco-category:before {
+ content:"\e61e";
+}
+.reco-npm:before {
+ content:"\e88d";
+}
+.reco-menu:before {
+ content:"\e67c";
+}
+.reco-suggestion:before {
+ content:"\e608";
+}
+.reco-coding:before {
+ content:"\e601";
+}
+.reco-github:before {
+ content:"\e628";
+}
+.reco-mail:before {
+ content:"\e624";
+}
+.reco-other:before {
+ content:"\e60e";
+}
+.reco-home:before {
+ content:"\e65b";
+}
+.reco-document:before {
+ content:"\e67a";
+}
+.reco-huawei:before {
+ content:"\e6b9";
+}
+.reco-up:before {
+ content:"\e68b";
+}
+.reco-weibo:before {
+ content:"\e612";
+}
+.reco-lock:before {
+ content:"\e60f";
+}
+.reco-fullscreen:before {
+ content:"\e602";
+}
+.reco-tag:before {
+ content:"\e633";
+}
+.reco-date:before {
+ content:"\e63b";
+}
+.reco-jianshu:before {
+ content:"\e60c";
+}
+.reco-friend:before {
+ content:"\e62f";
+}
+.reco-bokeyuan:before {
+ content:"\e626";
+}
+.reco-beian:before {
+ content:"\e667";
+}
+.reco-copyright:before {
+ content:"\ef87";
+}
+.reco-rss:before {
+ content:"\f09d";
+}
+.reco-bilibili:before {
+ content:"\e630";
+}
+.reco-account:before {
+ content:"\e607";
+}
+.reco-qq:before {
+ content:"\e67b";
+}
+.reco-theme:before {
+ content:"\e7e8";
+}
+.reco-three:before {
+ content:"\e644";
+}
+.reco-gitlab:before {
+ content:"\e63c";
+}
+.reco-api:before {
+ content:"\e662";
+}
+.reco-mayun:before {
+ content:"\e6d0";
+}
+.reco-zhihu:before {
+ content:"\e605";
+}
+.reco-facebook:before {
+ content:"\e606";
+}
+.reco-taobao:before {
+ content:"\e6a5";
+}
+.reco-tongzhi:before {
+ content:"\e764";
+}
+.reco-douyin:before {
+ content:"\e654";
+}
+.reco-v2ex:before {
+ content:"\e62a";
+}
+.reco-sticky:before {
+ content:"\e62b";
+}
+.reco-toutiao:before {
+ content:"\e6b7";
+}
+.reco-linkedin:before {
+ content:"\e668";
+}
+.reco-faq:before {
+ content:"\e643";
+}
+.reco-twitter:before {
+ content:"\e60b";
+}
+.reco-csdn:before {
+ content:"\e609";
+}
+.reco-juejin:before {
+ content:"\e613";
+}
diff --git a/website/.vuepress/theme/styles/mobile.styl b/website/.vuepress/theme/styles/mobile.styl
new file mode 100644
index 00000000..cb44a7d7
--- /dev/null
+++ b/website/.vuepress/theme/styles/mobile.styl
@@ -0,0 +1,39 @@
+// @require './config'
+
+$mobileSidebarWidth = $sidebarWidth * 0.82
+
+// narrow desktop / iPad
+@media (max-width: $MQNarrow)
+ .sidebar
+ font-size 15px
+ width $mobileSidebarWidth
+ .page, .password-wrapper-in
+ margin-left $mobileSidebarWidth
+
+// wide mobile
+@media (max-width: $MQMobile)
+ .sidebar
+ top 0
+ padding-top $navbarHeight
+ transform translateX(-100%)
+ transition transform .2s ease
+ .page, .password-wrapper-in
+ margin-left 0
+ .theme-container
+ &.sidebar-open
+ .sidebar
+ transform translateX(0)
+ &.no-navbar
+ .sidebar
+ padding-top: 0
+ .password-shadow
+ padding-left 0
+
+// narrow mobile
+@media (max-width: $MQMobileNarrow)
+ h1
+ font-size 1.9rem
+ .content__default
+ div[class*="language-"]
+ margin 0.85rem -1.5rem
+ border-radius 0
diff --git a/website/.vuepress/theme/styles/mode.styl b/website/.vuepress/theme/styles/mode.styl
new file mode 100644
index 00000000..c74ac858
--- /dev/null
+++ b/website/.vuepress/theme/styles/mode.styl
@@ -0,0 +1,38 @@
+:root
+ --default-color-10 $lightColor10
+ --default-color-9 $lightColor9
+ --default-color-8 $lightColor8
+ --default-color-7 $lightColor7
+ --default-color-6 $lightColor6
+ --default-color-5 $lightColor5
+ --default-color-4 $lightColor4
+ --default-color-3 $lightColor3
+ --default-color-2 $lightColor2
+ --default-color-1 $lightColor1
+ --background-color $backgroundColor
+ --box-shadow $boxShadow
+ --box-shadow-hover $boxShadowHover
+ --text-color $textColor
+ --text-color-sub $textColorSub
+ --border-color $borderColor
+ --code-color $codeColor
+ --mask-color $maskColor
+ @media (prefers-color-scheme: dark)
+ --default-color-10 $darkColor10
+ --default-color-9 $darkColor9
+ --default-color-8 $darkColor8
+ --default-color-7 $darkColor7
+ --default-color-6 $darkColor6
+ --default-color-5 $darkColor5
+ --default-color-4 $darkColor4
+ --default-color-3 $darkColor3
+ --default-color-2 $darkColor2
+ --default-color-1 $darkColor1
+ --background-color $backgroundColorDark
+ --box-shadow $boxShadowDark
+ --box-shadow-hover $boxShadowHoverDark
+ --text-color $textColorDark
+ --text-color-sub $textColorSubDark
+ --border-color $borderColorDark
+ --code-color $codeColorDark
+ --mask-color $maskColorDark
diff --git a/website/.vuepress/theme/styles/palette.styl b/website/.vuepress/theme/styles/palette.styl
new file mode 100644
index 00000000..a0dfaa83
--- /dev/null
+++ b/website/.vuepress/theme/styles/palette.styl
@@ -0,0 +1,47 @@
+$darkColor10 = rgba(0, 0, 0, 1)
+$darkColor9 = rgba(0, 0, 0, .9)
+$darkColor8 = rgba(0, 0, 0, .8)
+$darkColor7 = rgba(0, 0, 0, .7)
+$darkColor6 = rgba(0, 0, 0, .6)
+$darkColor5 = rgba(0, 0, 0, .5)
+$darkColor4 = rgba(0, 0, 0, .4)
+$darkColor3 = rgba(0, 0, 0, .3)
+$darkColor2 = rgba(0, 0, 0, .2)
+$darkColor1 = rgba(0, 0, 0, .1)
+
+$lightColor10 = rgba(255, 255, 255, 1)
+$lightColor9 = rgba(255, 255, 255, .9)
+$lightColor8 = rgba(255, 255, 255, .8)
+$lightColor7 = rgba(255, 255, 255, .7)
+$lightColor6 = rgba(255, 255, 255, .6)
+$lightColor5 = rgba(255, 255, 255, .5)
+$lightColor4 = rgba(255, 255, 255, .4)
+$lightColor3 = rgba(255, 255, 255, .3)
+$lightColor2 = rgba(255, 255, 255, .2)
+$lightColor1 = rgba(255, 255, 255, .1)
+
+$textShadow = 0 2px 4px $darkColor1;
+$borderRadius = .25rem
+$lineNumbersWrapperWidth = 2.5rem
+
+$backgroundColor ?= #fff
+$backgroundColorDark ?= #181818
+
+$boxShadow = 0 1px 6px 0 $darkColor2
+$boxShadowHover = 0 2px 16px 0 $darkColor2
+$boxShadowDark = 0 1px 6px 0 $darkColor6
+$boxShadowHoverDark = 0 2px 16px 0 $darkColor6
+
+$textColor ?= #242424
+$textColorDark ?= $lightColor8
+$textColorSub = #7F7F7F
+$textColorSubDark = #8B8B8B
+
+$borderColor ?= #eaecef
+$borderColorDark ?= $darkColor3
+
+$codeColor ?= rgba(27, 31, 35, 0.05)
+$codeColorDark ?= $darkColor3
+
+$maskColor ?= #888
+$maskColorDark ?= #000
diff --git a/website/.vuepress/theme/styles/theme.styl b/website/.vuepress/theme/styles/theme.styl
new file mode 100644
index 00000000..535eb7e3
--- /dev/null
+++ b/website/.vuepress/theme/styles/theme.styl
@@ -0,0 +1,226 @@
+@require './mode'
+@require './code'
+@require './custom-blocks'
+@require './arrow'
+@require './wrapper'
+@require './toc'
+@require './iconfont.css'
+
+html, body
+ padding 0
+ margin 0
+body
+ font-family Ubuntu, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif
+ -webkit-font-smoothing antialiased
+ -moz-osx-font-smoothing grayscale
+ font-size 15px
+ color var(--text-color)
+ background-color var(--background-color)
+
+.page, .password-wrapper-in
+ overflow-x: hidden
+ margin-left $sidebarWidth
+
+.navbar
+ position fixed
+ z-index 20
+ top 0
+ left 0
+ right 0
+ height $navbarHeight
+ box-sizing border-box
+
+.sidebar-mask
+ position fixed
+ z-index 9
+ top 0
+ left 0
+ width 100vw
+ height 100vh
+ display none
+ background-color: rgba(0,0,0,.65);
+
+.sidebar
+ font-size 16px
+ background-color var(--background-color)
+ width $sidebarWidth
+ position fixed
+ z-index 10
+ margin 0
+ top $navbarHeight
+ left 0
+ bottom 0
+ box-sizing border-box
+ border-right 1px solid var(--border-color)
+ overflow-y auto
+
+.content__default:not(.custom)
+ @extend $wrapper
+ // > *:first-child
+ // margin-top 1.6rem
+ a:hover
+ text-decoration underline
+ p.demo
+ padding 1rem 1.5rem
+ border 1px solid #ddd
+ border-radius 4px
+ img
+ max-width 100%
+
+.content__default.custom
+ padding 0
+ margin 0
+ img
+ max-width 100%
+
+a
+ font-weight 500
+ color $accentColor
+ text-decoration none
+
+p a code
+ font-weight 400
+ color $accentColor
+
+kbd
+ background #eee
+ border solid 0.15rem #ddd
+ border-bottom solid 0.25rem #ddd
+ border-radius 0.15rem
+ padding 0 0.15em
+
+blockquote
+ font-size .9rem
+ color #999
+ border-left .25rem solid #999
+ background-color var(--code-color)
+ margin 0.5rem 0
+ padding .25rem 0 .25rem 1rem
+ & > p
+ margin 0
+
+ul, ol
+ padding-left 1.2em
+
+strong
+ font-weight 600
+
+h1, h2, h3, h4, h5, h6
+ font-weight 500
+ line-height 1.25
+ .content__default:not(.custom) > &
+ margin-top (0.5rem - $navbarHeight)
+ padding-top ($navbarHeight + 1rem)
+ margin-bottom 0
+ &:first-child
+ margin-top -3.5rem
+ margin-bottom 1rem
+ + p, + pre, + .custom-block
+ margin-top 2rem
+ &:hover .header-anchor
+ opacity: 1
+
+h1
+ font-size 1.6rem
+
+h2
+ font-size 1.4rem
+ padding-bottom .3rem
+ border-bottom 1px solid var(--border-color)
+
+h3
+ font-size 1.2rem
+
+a.header-anchor
+ font-size 0.85em
+ float left
+ margin-left -0.87em
+ padding-right 0.23em
+ margin-top 0.125em
+ opacity 0
+ &:hover
+ text-decoration none
+
+code, kbd, .line-number
+ font-family source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace
+
+p, ul, ol
+ line-height 1.7
+
+hr
+ border 0
+ border-top 1px solid var(--border-color)
+
+table
+ border-collapse collapse
+ margin 1rem 0
+ display: block
+ overflow-x: auto
+
+tr
+ border-top 1px solid var(--border-color)
+ &:nth-child(2n)
+ background-color var(--code-color)
+
+th, td
+ border 1px solid var(--border-color)
+ padding .6em 1em
+
+.theme-container
+ &.sidebar-open
+ .sidebar-mask
+ display: block
+ &.no-navbar
+ .content__default:not(.custom) > h1, h2, h3, h4, h5, h6
+ margin-top 1.5rem
+ padding-top 0
+ .sidebar
+ top 0
+
+@media (min-width: ($MQMobile + 1px))
+ .theme-container.no-sidebar
+ .sidebar
+ display none
+ .page, .password-wrapper-in
+ margin-left 0
+
+@require 'mobile.styl'
+
+.iconfont
+ font-size: 0.9rem;
+ color: var(--text-color-sub);
+
+/************** 滚动条 **************/
+::-webkit-scrollbar
+ width: 5px;
+ height: 5px;
+
+::-webkit-scrollbar-track-piece
+ // background-color: rgba(0, 0, 0, 0.2);
+
+::-webkit-scrollbar-thumb:vertical
+ height: 5px;
+ background-color: $accentColor;
+
+::-webkit-scrollbar-thumb:horizontal
+ width: 5px;
+ background-color: $accentColor;
+
+/************** 流程图的滚动条 **************/
+.vuepress-flowchart
+ overflow: auto
+
+/************** SW-Update Popup **************/
+
+.sw-update-popup
+ border-radius: $borderRadius!important;
+ box-shadow: var(--box-shadow)!important;
+ color: var(--text-color)!important;
+ background: var(--background-color)!important;
+ border: none!important;
+ > button
+ background: $accentColor;
+ border-radius: $borderRadius;
+ color: #fff;
+ -webkit-tap-highlight-color:rgba(0, 0, 0, 0)
+ border: none;
diff --git a/website/.vuepress/theme/styles/toc.styl b/website/.vuepress/theme/styles/toc.styl
new file mode 100644
index 00000000..d3e71069
--- /dev/null
+++ b/website/.vuepress/theme/styles/toc.styl
@@ -0,0 +1,3 @@
+.table-of-contents
+ .badge
+ vertical-align middle
diff --git a/website/.vuepress/theme/styles/wrapper.styl b/website/.vuepress/theme/styles/wrapper.styl
new file mode 100644
index 00000000..a99262c7
--- /dev/null
+++ b/website/.vuepress/theme/styles/wrapper.styl
@@ -0,0 +1,9 @@
+$wrapper
+ max-width $contentWidth
+ margin 0 auto
+ padding 2rem 2.5rem
+ @media (max-width: $MQNarrow)
+ padding 2rem
+ @media (max-width: $MQMobileNarrow)
+ padding 1.5rem
+
diff --git a/website/README.md b/website/README.md
index a03eab9e..c5f7a3d5 100644
--- a/website/README.md
+++ b/website/README.md
@@ -1,5 +1,13 @@
----
-title: 奥利给
----
+# 这是你的主页
-这是一个彩蛋。
\ No newline at end of file
+---
+home: true
+heroImage: /hero.png
+heroImageStyle: {
+ maxHeight: '200px',
+ display: block,
+ margin: '6rem auto 1.5rem',
+ borderRadius: '50%',
+ boxShadow: '0 5px 18px rgba(0,0,0,0.2)'
+}
+---
\ No newline at end of file