diff --git a/2015/09/29/2015-09-29-replacement-of-SSD/index.html b/2015/09/29/2015-09-29-replacement-of-SSD/index.html new file mode 100644 index 000000000..87ba1deda --- /dev/null +++ b/2015/09/29/2015-09-29-replacement-of-SSD/index.html @@ -0,0 +1,210 @@ +为笔记本(华硕A46C)更换SSD全过程 | Maple's Blog + + + + + + + + + + + + +

为笔记本(华硕A46C)更换SSD全过程

前两天给自己的笔记本换了个SSD。我的笔记本是华硕A46C,2013年买的,属于超薄本。当时买的时候选的是无光驱版,因此光驱位就是一个空盒子。下图中左边的就是光驱位的空盒子。在换SSD的时候,需要买一个和这个盒子差不多形状的硬盘盒装上。我是把原来的机械硬盘放到了光驱位,然后把SSD放到了原来的机械硬盘(主硬盘)的位置,据说是主硬盘的位置能够提供更高的读取速度,我没有去查华硕这个系列的光驱位提供的接口,但是主硬盘的读取速度肯定不会低于光驱位,所以就这么换了,虽然麻烦了一些。

+ +

+

因为一般的光驱位硬盘盒和华硕的这个系列笔记本的边缘不太一致,导致装进去之后会凹进去一块,很难看。但是在淘宝上搜华硕A46硬盘架根本找不到,后来在网上看到有别人的更换教程,发现华硕的X450、X550系列的硬盘架能够完美适配华硕A46系列。

+

拆机过程如下:首先按照下图的方向把后盖拆掉

+

露出主硬盘

+

+

我买的这款三星250G SSD 感觉还是不错的,手机上买的589元。在天猫上买的,第一次发货之后,两三天没有更新快递信息,感觉是中通快递给弄丢了,卖家联系快递也没有消息,不过老板还是比较有业界良心的,直接重新发了一款并更换了快递。

+

+

看一下机械硬盘和固态硬盘的对比照,此时固态硬盘已经装在了主硬盘的外壳里了。

+
+ + +

+
+ +

下图是装上硬盘托架之后的光驱位外边缘,这个硬盘托架还是比较合适的,就是有点贵。
SSD装好之后,在里边装了win10,但是在win10里总是找不到原来的机械硬盘。进到UEFI里边是能看到的,说明硬盘托架的接口没问题,后来我尝试从机械硬盘启动,发现可以正常使用,而且在原来的系统里也能看到SSD的盘符。然后我又切回到SSD启动,机械硬盘居然神奇的出现了,并且一切使用都是正常的,我也不知道为什么,总之,这次的SSD更换也算是成功了!

+
文章作者: maple.yf
文章链接: https://maple-yf.github.io/2015/09/29/2015-09-29-replacement-of-SSD/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Maple's Blog
赞助
  • 微信
    微信
  • 支付宝
    支付宝

评论
公告
This is my Blog
\ No newline at end of file diff --git a/2015/11/07/2015-11-07-win10-menucontext/index.html b/2015/11/07/2015-11-07-win10-menucontext/index.html new file mode 100644 index 000000000..d8bcbeee4 --- /dev/null +++ b/2015/11/07/2015-11-07-win10-menucontext/index.html @@ -0,0 +1,198 @@ +win10右键反应缓慢 | Maple's Blog + + + + + + + + + + + + +

win10右键反应缓慢

最近装了win10,但是有一个小问题,右击电脑空白处想刷新的时候,反应特别慢,因为系统是安装在固态硬盘上的,所以不应该出现这种问题,于是网上搜罗了一些解决方法。

+

解决方案

开始,运行:regedit,打开注册表

+
HKEY_CLASSES_ROOT/Directory/Background/shellex/ContextMenuHandlers
+ +

删除下面两个选项就可以了:一个是 igfxcui ,另外一个是NvCplDesktopContext如果只有一项就单独删除,如果两项都有就全部删除。

+
文章作者: maple.yf
文章链接: https://maple-yf.github.io/2015/11/07/2015-11-07-win10-menucontext/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Maple's Blog
赞助
  • 微信
    微信
  • 支付宝
    支付宝

评论
公告
This is my Blog
\ No newline at end of file diff --git a/2015/11/12/2015-11-12-shadowsocks/index.html b/2015/11/12/2015-11-12-shadowsocks/index.html new file mode 100644 index 000000000..5b46b5c56 --- /dev/null +++ b/2015/11/12/2015-11-12-shadowsocks/index.html @@ -0,0 +1,234 @@ +安装 ShadowScoks | Maple's Blog + + + + + + + + + + + + +

安装 ShadowScoks

ShadowScoks是一个非常易用的翻墙工具,把它安装在自己的VPS上,就可以随心所欲的上网啦!

+

安装

输入su进入root。
分别复制以下命令到命令行:

+
wget --no-check-certificate https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks.sh
+chmod +x shadowsocks.sh
+./shadowsocks.sh 2>&1 | tee shadowsocks.log
+ +

执行最后一条命令之后,出现一下界面:

+

+

输入密码即可。并回车,再次回车,确认安装。

+

+

安装失败,出现错误提示:

+
./shadowsocks.sh: line 111:  6396 Segmentation fault      (core dumped) apt-get -y update
+Reading package lists..../shadowsocks.sh: line 111:  6461 Segmentation fault      (core dumped) apt-get -y install python python-dev python-pip curl wget unzip gcc swig automake make perl cpio
+ +

分别执行 (core dumped)后面的语句

+
apt-get -y update
+apt-get -y install python python-dev python-pip curl wget unzip gcc swig automake make perl cpio
+ +

然后,重新执行:

+
./shadowsocks.sh 2>&1 | tee shadowsocks.log
+ +

等待5分钟左右,即可安装成功,安装成功之后就会通过屏幕输出,您的IP地址,端口,密码,及加密方式。

+

+

如果您想多用户使用,请配置 /etc/shadowsocks.json 这个文件。配置模版:

+
{
+    "server":"your_server_ip",
+    "local_address": "127.0.0.1",
+    "local_port":1080,
+    "port_password":{
+        "8989":"password0",
+        "9001":"password1",
+        "9002":"password2",
+        "9003":"password3",
+        "9004":"password4"
+    },
+    "timeout":300,
+    "method":"aes-256-cfb",
+    "fast_open": false
+}
+ +

Windows客户端下载地址:https://shadowsocks.org/en/download/clients.html
使用教程:http://wiki.ssnode.co/index.php?option=com_content&view=article&id=4:about-your-home-page&catid=9&Itemid=101
使用shadowsocks时,必须要通过SSH连接上自己的VPS后才能代理成功。

+
文章作者: maple.yf
文章链接: https://maple-yf.github.io/2015/11/12/2015-11-12-shadowsocks/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Maple's Blog
赞助
  • 微信
    微信
  • 支付宝
    支付宝

评论
公告
This is my Blog
\ No newline at end of file diff --git a/2015/12/01/2015-12-01-Setting-Ubuntu-User/index.html b/2015/12/01/2015-12-01-Setting-Ubuntu-User/index.html new file mode 100644 index 000000000..9069534a4 --- /dev/null +++ b/2015/12/01/2015-12-01-Setting-Ubuntu-User/index.html @@ -0,0 +1,211 @@ +Ubuntu用户设置 | Maple's Blog + + + + + + + + + + + + +

Ubuntu用户设置

最近在安装实验室一台服务器,系统装的是Ubuntu 14.04,今天在添加用户的时候出了点小问题,在这里总结一下。

+

为Ubuntu添加新用户

在网上查到为Ubuntu填加新用户的方式是 sudo useradd me和passwd me来设置,但是,这样设置有一个很大的坑,因为这样设置的用户信息是不全的,直接导致使用这种方式设置的用户在进行远程登陆的时候,会出现

+
Could not chdir to home directory /home/me: No such file or directory
+ +

的错误,可以用过输入 bash 来进入正常的状态

+
$ bash
+me@server:/$
+ +

为了解决这个问题,其实就是修改用户的默认shell为bash。去Google了一番,终于找到解决方案:
http://askubuntu.com/questions/28969/how-do-you-change-the-default-shell-for-all-users-to-bash
方法就是,如果是root用户:

+
usermod -s /bin/bash USERNAME
+ +

如果不是root用户:

+
sudo -u USERNAME chsh -s /bin/bash
+

走过这个坑之后,建议以后添加用户,换成另外一种方式, sudo adduser me,这样虽然麻烦一些,但是权限和信息都是更加完整的。

+

为用户添加root权限

为了能使用root权限,又去搜索了一遍如何为用户添加root权限,这里有一篇文章讲解的很详细http://blog.csdn.net/dreamback1987/article/details/8766302。这里的关键点就是在修改 /etc/sudoers文件前,需要修改它的权限,改完保存之后,再把文件权限修改回来,因为如果 /etc/sudoers 文件的权限为 777 的话,sudo命令就不能使用了。

+

root用户和普通用户来回切换

因为本人菜鸟一枚,这里记录一下刚刚学到的一个小命令,就是root用户和普通用户的来回切换:

+
$su root		#切换到root用户
+$su me			#切换到me用户
+
文章作者: maple.yf
文章链接: https://maple-yf.github.io/2015/12/01/2015-12-01-Setting-Ubuntu-User/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Maple's Blog
赞助
  • 微信
    微信
  • 支付宝
    支付宝

评论
\ No newline at end of file diff --git a/2016/04/29/2016-04-29-jekyll-install/index.html b/2016/04/29/2016-04-29-jekyll-install/index.html new file mode 100644 index 000000000..97a7ae4a5 --- /dev/null +++ b/2016/04/29/2016-04-29-jekyll-install/index.html @@ -0,0 +1,213 @@ +安装静态博客Jekyll | Maple's Blog + + + + + + + + + + + + +

安装静态博客Jekyll

Jekyll是一种纯文本的静态博客,安装成功之后,直接通过markdown文本就可以更新博客内容。Jekyll的安装过程比较简单,但是安装的过程中仍然会跳进很多坑。Jekyll和Github Pages是一种很好的结合。Github Pages是github提供的一个可以免费部署个人网站且没有存储上限的一个功能。在Jekyll的官网里也有把Jekyll部署到Github Pages上的教程。

+

安装Jekyll

如果需要部署到Github Pages,Jekyll需要在本地完成安装,然后再进行部署。Jekyll的安装智能在Linux和Mac OS X上进行,另外,其依赖Ruby和RubyGems,建议安装rvm来控制Ruby的版本。Linux和Mac OS X一般都会有系统自带的Ruby,但是版本比较旧,通过

+

+ruby -v
+
+ +

可以查看当前Ruby的版本。当前Github Pages支持的是Jekyll 3.0,其依赖的Ruby 2.0及其以上版本,所以建议安装Ruby 2.0或其以上版本。
本次安装,我是直接从github上找了一个别人做好的带主题的Jekyll,然后安装在自己的VPS上了,这个Jekyll Theme的名字叫做Personal,把它git到我vps上之后,通过一个命令就可以安装完成:

+

+./scripts/install
+
+ +

它对Ruby的需求是2.0及其以上版本,否则会安装失败。

+

配置

安装成功之后,需要对_config.yml文件进行一些个性配置。具体配置可以参考项目中的教程。主要的配置有以下几个:

+
    +
  • url:这个是用来指向自己的域名(如果你有的话),配置到Github Pages上并指向自己的域名或者二级域名可以参考github官方教程
  • +
  • baseurl:用来设置自己网站的相对根目录,我设置的是空,因为在我的Github Pages中的这个项目是直接放在根目录下的
  • +
  • force-https:这个配置是原版Jekyll没有的,这里建议设置为false,因为Github Pages目前既支持http也支持https,如果自己没有https的证书的话,还是把其关闭的好
  • +
+

其余的配置都可以参考personal项目中的教程。

+

部署

配置完成之后,就可以部署到Github Pages中了,我直接把安装好的整个文件夹push到了github中。在push之前,需要先创建自己的Github Pages,每一个github用户只能创建一个Github Pages,这里是官方创建教程。创建完成之后,把自己的文件push到根目录下,就可以通过 http://gitusername.github.io 访问了,如果设置了个人的域名,则需要到自己的域名管理网站更新域名指向,把设置的域名指向 http://gitusername.github.io 即可。需要注意的是,把自己的项目文件push到github之后,也许并不能立刻就访问到网页,也许是因为github内部需要一段时间的部署。我当时部署到github之后,立刻访问得到的是404页面,刚开始以为是自己配置出错了,过滤几个小时之后,再次访问,页面才第一次呈现。

+
文章作者: maple.yf
文章链接: https://maple-yf.github.io/2016/04/29/2016-04-29-jekyll-install/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Maple's Blog
赞助
  • 微信
    微信
  • 支付宝
    支付宝

评论
\ No newline at end of file diff --git a/2016/06/25/2016-06-25-say-goodbye/index.html b/2016/06/25/2016-06-25-say-goodbye/index.html new file mode 100644 index 000000000..84acccc4f --- /dev/null +++ b/2016/06/25/2016-06-25-say-goodbye/index.html @@ -0,0 +1,215 @@ +不得不说再见 | Maple's Blog + + + + + + + + + + +

不得不说再见


+ +

+ +
终于这宴席还是要散场
+
请不要为我鼓掌
+
也不要欢送
+
+
潺潺的流水在为我歌唱
+
盛放的蔷薇散发着芬芳
+
河边的杨柳也在轻轻地飘荡
+
+
夏天总因离别变得黯然惆怅
+
还想再听一听丰富多彩的课堂
+
还想再逛一逛青春洋溢的操场
+
还想再聊一聊槽点满满的旧日时光
+
还想,还想……
+
+
别了校园,别了矿大
+
别了那逝去的青春模样
+
+
南湖上升起的月光
+
请替我守护这片温馨的土壤
+
我在下一个路口等待
+
青春不散场
文章作者: maple.yf
文章链接: https://maple-yf.github.io/2016/06/25/2016-06-25-say-goodbye/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Maple's Blog
赞助
  • 微信
    微信
  • 支付宝
    支付宝

评论
公告
This is my Blog
\ No newline at end of file diff --git a/2017/02/07/2017-02-07-snow/index.html b/2017/02/07/2017-02-07-snow/index.html new file mode 100644 index 000000000..fff7501e0 --- /dev/null +++ b/2017/02/07/2017-02-07-snow/index.html @@ -0,0 +1,201 @@ +吹雪 | Maple's Blog + + + + + + + + + + +

吹雪


+ +

+ +
我经历了一次美丽的邂逅
+
是这突如其来的吹雪
+
轻轻吻向泥土的等候
+
+
洁白在灯光交汇下漫天轻柔
+
伴着人们心满意足的步调
+
目睹了一对对静静地走到白头
文章作者: maple.yf
文章链接: https://maple-yf.github.io/2017/02/07/2017-02-07-snow/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Maple's Blog
赞助
  • 微信
    微信
  • 支付宝
    支付宝

评论
公告
This is my Blog
\ No newline at end of file diff --git a/2017/05/08/2017-05-08-dusk/index.html b/2017/05/08/2017-05-08-dusk/index.html new file mode 100644 index 000000000..75c62af92 --- /dev/null +++ b/2017/05/08/2017-05-08-dusk/index.html @@ -0,0 +1,201 @@ +趁黄昏 | Maple's Blog + + + + + + + + + + +

趁黄昏


+ +

+ +
十里春风独爱这柳树的枝头
+
趁黄昏,走一走
+
晚风亲吻着温柔
+
+
一次日落偏好那静静的巷口
+
趁黄昏,等一等
+
夕阳西下的守候
文章作者: maple.yf
文章链接: https://maple-yf.github.io/2017/05/08/2017-05-08-dusk/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Maple's Blog
赞助
  • 微信
    微信
  • 支付宝
    支付宝

评论
公告
This is my Blog
\ No newline at end of file diff --git a/2017/07/09/2017-07-09-south-lake-at-dusk/index.html b/2017/07/09/2017-07-09-south-lake-at-dusk/index.html new file mode 100644 index 000000000..f0bf6f7de --- /dev/null +++ b/2017/07/09/2017-07-09-south-lake-at-dusk/index.html @@ -0,0 +1,211 @@ +南湖向晚 | Maple's Blog + + + + + + + + + + +

南湖向晚


+ +

+ +
没有偶遇记忆中雨后的彩虹
+
这里清清静静悄悄依旧
+
于是
+
晚霞偷偷染红了半边天空
+
+
故地重游的喜悦
+
总伴着物是人非的惆怅
+
回忆也显得那么美那么伤
+
那么无可奈何的凄凉
+
+
每一次心心念念的感慨
+
都装入成长路上破旧的行囊
+
变与不变的留恋
+
都化作或甜或苦的记忆珍藏
+
再次回归的少年依旧
+
因为我从未离开不曾遗忘
+
文章作者: maple.yf
文章链接: https://maple-yf.github.io/2017/07/09/2017-07-09-south-lake-at-dusk/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Maple's Blog
赞助
  • 微信
    微信
  • 支付宝
    支付宝

评论
公告
This is my Blog
\ No newline at end of file diff --git a/2017/07/20/2017-07-20-vscode-introduction/index.html b/2017/07/20/2017-07-20-vscode-introduction/index.html new file mode 100644 index 000000000..4d480b10a --- /dev/null +++ b/2017/07/20/2017-07-20-vscode-introduction/index.html @@ -0,0 +1,261 @@ +前端编程利器VS Code | Maple's Blog + + + + + + + + + + +

前端编程利器VS Code

+ + +

前言

前端同学使用的编辑器可选范围非常广泛。

+

最开始接触到前端的时候,听说了Dreamweaver这么一个强大的软件,但严格意义上讲,这不能算作一个编辑器。后来认识了NotePad++,在当时,这确实是一款非常好用的编辑器,语法高亮的友好度仅次于IDE,而且占用内存小,运行非常流畅。

+

再然后,有人推荐Sublime。我用的时候,还是Sublime 2,最吸引我的是它的mini map,拖动mini map快速浏览大段大段的代码,比拖动小小的滑块酸爽很多呀。再加上后来安装的各种插件,感觉我进入了一个全新的世界,Sublime才是我最想用的编辑器呀!

+

工作之后,听说大家都在用webstorm,于是我也安装了一个试试,功能确实强大,特别它自带的git管理以及编辑器内部打开terminal的功能,非常适合前端开发。但是,功能强大的webstorm太过于笨重,每次打开的时候都要等一会儿,占用内存太高,同时开启两个项目的时候,电脑就会特别卡,非常影响写代码的心情,而且,webstorm是收费软件,用了一段时间之后果断放弃。

+

这时,我尝试了一款觊觎已久的酷炫编辑器 Atom。用了Atom之后,我才知道了什么叫酷炫!Sublime算什么,我再也不要用那个丑丑的Sublime了。基于Electron(最初以Atom Shell知名)和许可使用Chromium和Node.js的跨平台应用框架,并使用CoffeeScriptLess编写。Atom不但酷炫而且强大,因为有着活跃的社区,所以插件非常多,除了满足开发的刚需之外,还有很多想都想不到的插件。但是但是,美中不足的是Atom太卡了,而且用的时候偶尔还会崩溃。坚持用了一个月,最后实在受不了,我又换回Sublime了,但是心中很不甘啊!

+

当时我就想着,如果有一款编辑器可以像Sublime一样流程同时又像Atom一样酷炫该有多好。于是,我遇到了VS Code。VS Code刚刚发布Beta版时我尝试着用过一次,当时还不稳定,社区也不完善,插件更是贫乏,所以没留下好印象。这次重新尝试,是因为听说它和Atom一样,也是通过Electron编写的,我想,至少可以像Atom一样酷炫吧。试用之后才发现,原来这才是我一直苦苦寻找的理想编辑器呀!

+

特性

我强烈推荐VS Code的原因是它有以下几大特点:

+
    +
  • 酷炫 和Atom一样采用Electron框架编写,整个软件其实就是一个WebAPP,样式深度定制,酷炫到超乎你想象。如果觉得还不过瘾,可以自己编写theme插件,满足你的各种癖好。
  • +
  • 轻量 虽然同样是采用Electron框架编写,但是VS Code和Atom走了不同的路线。Atom从一开始就把插件化架构摆在第一位,所以,Atom中最重要的是灵活而又完备的API,性能则不那么重要。VS Code则是把用户体验放在第一位,高性能、更能丰富才是它的首要目的,所以,一开始VS Code的插件系统很糟糕。但是VS Code的性能绝对高出Atom一个档位。
  • +
  • 开源 继承了Electron的良好基因。
  • +
  • 跨平台 依然是继承了Electron的良好基因。
  • +
  • 丰富的插件 虽然不如Sublime和Atom数量多,但现在已经有越来越多的插件涌入。
  • +
  • 活跃的社区 得益于Electron和Atom,VS Code的社区也是非常的活跃,更加快了插件生态的繁荣。
  • +
+

自带功能

Emmet

VS Code不需要安装插件,自身就实现了Emmet,默认就是打开的。

+

智能感知

VS Code本身自带JS代码提示和自动补全功能,当然,如果你觉得不够用,还可以安装各种intelligence或者snippets插件来满足需求。

+

JS智能提示

+

Format Document

对于压缩的代码,或者格式不够规范的代码文件,可以通过这个命令一键格式化代码。当然,这个功能是每个编辑器应该都有的,并不是亮点。

+

Fromat Document

+

Auto Save

自动保存功能也是大部分优秀的编辑器应该必备的。我认为VS Code里做的比较人性化的一个点是,它的设置选项里提供了四种自动保存的时机供我们选择:offafterDelayonFocusChange(编辑器失去焦点)、onWindowChange(窗口失去焦点)。如果设置为afterDelay,则可在 files.autoSaveDelay 中配置延迟。我比较喜欢onWindowChange

+

Auto Save

+

Terminal

VS Code自带打开Terminal的功能,这是Atom和Sublime所不具备的。这也算是VS Code的一大亮点。

+

Terminal

+

插件推荐

接下来,推荐一些我用到过的非常实用的插件,帮助你编程时候事半功倍!

+

Git History

Git History

+

可以查看一个文件的所有提交记录,同时还可以调出一个可视化的界面展示文件的提交记录,是git log的强化版。还可以查看某一行的所有提交记录。

+

Git Peoject Manager

这是一个git项目管理的插件,一共就4个命令:

+
    +
  • **GPM: Open Git Project (Ctrl+Alt+P)**:打开git项目
  • +
  • GPM: Refresh Projects:刷新git项目
  • +
  • GPM: Refresh specific project folder:刷新特定路径下的git项目
  • +
  • **GPM: Open Recent Git Project (Ctrl+Shift+Q)**:最近打开的git项目列表
  • +
+

Git Project Manager

+

插件的使用也很简单,找到配置文件中gitProjectManager.baseProjectsFolders把git项目的根目录放进去,就像下边这样:
{ "gitProjectManager.baseProjectsFolders": [ "/home/user/nodeProjects", "/home/user/personal/pocs" ] }

+

然后cmd + shift + P调出命令栏,并输入GPM,上述的4个命令就被列出来了,选择Refresh Projects,稍等一会儿后,被我们添加到配置文件里的路径下的所有git项目都会被列出来。选择你的工作目录开始Coding吧!

+

Git Lens

这是一款非常强大的git插件,它提供的每一个功能,都戳中了我们日常开发中的需求痛点。所以,我强烈推荐大家安装并使用这款插件。先目睹一下它的功能概览gif图:

+

gitlens-preview.gif

+
Code Lens

在文件的顶部展示代码变更的总的记录,包括左边的最新修改记录以及右边的所有的修改作者数量。

+

Code Lens

+
Blame Annotations

点击右边的作者数量可以进入整个文件的Blame Annotations。这里展示了每一行的最后一条修改记录,具体的展示方式可以在设置里自己配置,包括作者、时间和commit信息。

+

Blame Annotations

+
Status Bar Blame

这个是指在状态栏里展示当前光标所在行的Git Blame信息。当然这里要展示的信息和格式也是可以配置的。这样,光标所在的行的最新git记录和作者信息完全展示在了状态栏里。

+

Status Bar Blame

+
Interactive Blame

这个功能和Status Bar Status类似,只不过,git信息是直接展示在文件中的代码后边。鼠标悬停在git记录上时,会有更详细的git变更气泡弹出。就像下边这样:

+

Interactive Blame

+
Quick Menu

快捷键shift + alt + H调出branch history quick pick menu, 这个菜单功能非常强大,我们可以查看之前的commits信息、所有commits信息、根据message/author/filename搜索commits信息、查看一些文件的历史记录等。

+

Quick Menu

+

Search by messages

+

Search by autor 01

+

Search by autor 02

+

Search by filename 01

+

Search by filename 02

+

通过message查找时,直接在输入框里输入message的关键信息即可。通过author查找时,则是输入@author,类似于图中的@Zeke。而通过filename查找,则需要注意一下,这里应该是: filepath,也就是相对于当前项目根目录的相对路径。类似于图中的:lib/browser/chrome-extension.js。除了这些之外,还可以根据commit id查找,这个用的不多,这里就不再举例了。

+

Project Manager

项目管理插件,这个功能和Git Project Manager有点类似,只不过,这个不但能管理git项目,还可以管理其他项目。

+

Project Manager

+

这个插件一共5个命令:

+
    +
  • Project Manager: Edit Project Edit 跳转到配置文件 projects.json 进行项目列表目录的配置修改。
  • +
  • Project Manager: List Projects 列出已经保存的项目列表。
  • +
  • Project Manager: List Projects to Open in New Window 列出已保存的项目列表并在新窗口打开选中的项目。
  • +
  • Project Manager: Refresh Projects 刷新项目列表。
  • +
  • Project Manager: Save Project 保存当前项目到项目列表。
  • +
+

其他插件

其他的一些插件就不做详细介绍了,这里列出我用过的感觉比较好的,大家自己到github上查阅吧。vscode-iconsvscode-fileheaderDocument ThisCSS PeekFile PeekMarkdown PDFMarkdown Preview EnhancedRegex Railroad Diagrams

+

如果还有其他比较好用或者有意思的插件,欢迎大家前来留言。一起讨论交流。

+
文章作者: maple.yf
文章链接: https://maple-yf.github.io/2017/07/20/2017-07-20-vscode-introduction/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Maple's Blog
赞助
  • 微信
    微信
  • 支付宝
    支付宝

评论
\ No newline at end of file diff --git a/2017/07/21/2017-07-21-raining-night/index.html b/2017/07/21/2017-07-21-raining-night/index.html new file mode 100644 index 000000000..8e4d61605 --- /dev/null +++ b/2017/07/21/2017-07-21-raining-night/index.html @@ -0,0 +1,197 @@ +夜雨 | Maple's Blog + + + + + + + + + + +

夜雨


+ +

+ +
雷隐隐,风悄悄
+
这整夜的雨
+
淅淅沥沥潇潇
文章作者: maple.yf
文章链接: https://maple-yf.github.io/2017/07/21/2017-07-21-raining-night/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Maple's Blog
赞助
  • 微信
    微信
  • 支付宝
    支付宝

评论
公告
This is my Blog
\ No newline at end of file diff --git a/2017/08/06/2017-08-06-hello-world/index.html b/2017/08/06/2017-08-06-hello-world/index.html new file mode 100644 index 000000000..12c4d0890 --- /dev/null +++ b/2017/08/06/2017-08-06-hello-world/index.html @@ -0,0 +1,207 @@ +Hello World | Maple's Blog + + + + + + + + + + + + +

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

+ +

Quick Start

Create a new post

$ hexo new "My New Post"
+ +

More info: Writing

+

Run server

$ hexo server
+ +

More info: Server

+

Generate static files

$ hexo generate
+ +

More info: Generating

+

Deploy to remote sites

$ hexo deploy
+ +

More info: Deployment

+
文章作者: maple.yf
文章链接: https://maple-yf.github.io/2017/08/06/2017-08-06-hello-world/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Maple's Blog
赞助
  • 微信
    微信
  • 支付宝
    支付宝

评论
\ No newline at end of file diff --git a/2017/08/27/2017-08-27-plantuml/index.html b/2017/08/27/2017-08-27-plantuml/index.html new file mode 100644 index 000000000..7f026655c --- /dev/null +++ b/2017/08/27/2017-08-27-plantuml/index.html @@ -0,0 +1,290 @@ +plantuml简介 | Maple's Blog + + + + + + + + + + + + +

plantuml简介

简介

最近在学习设计模式,但是在画类图的时候,有一堆的画图工具可以选择,但总感觉用的不顺手。于是在网上找到了这个神奇的语言。PlantUML是一个开源项目,支持时序图、用例图、类图、活动图、组件图、状态图、对象图等的绘制。简而言之,就是用写代码的方式画图。几行代码,输出标准结构图,不用再去考虑结构、对齐等琐事啦!

+

效果预览

如下简单的语法表达类图之间的关系

+
@startuml
+Class01 <|-- Class02
+Class03 <|.. Class04
+Class05 *-- Class06
+Class07 o-- Class08
+Class09 <.. Class10
+Class11 <-- Class12
+@enduml
+ +

效果如下:

+

+

再看一下复杂一点的装饰者模式类图,代码如下

+
@startuml
+namespace Decorator{
+    interface Component
+    interface Decorator
+    Component : +operation():void
+    ConcreateComponent : +opreation():void
+    Decorator : -component:Component
+    Decorator : +opreantion():void
+    ConcreateDecorator1 : +opreation():void
+    ConcreateDecorator1 : +addBehavior():void
+    ConcreateDecorator2 : +opreation():void
+    ConcreateDecorator2 : +addBehavior():void
+
+    Decorator <|-- ConcreateDecorator1
+    Decorator <|-- ConcreateDecorator2
+    Component <|.. Decorator
+    Component <|.. ConcreateComponent
+    Decorator o-- Component
+
+    note bottom of Decorator
+        component.opreation();
+    end note
+
+    note bottom of ConcreateDecorator1
+        super.operation();
+        addBehavior();
+    end note
+
+    note bottom of ConcreateDecorator2
+        super.operation();
+        addBehavior();
+    end note
+}
+@enduml
+ +

效果图:

+

+

时序图长这样:

+
@startuml
+title 时序图
+
+== 鉴权阶段 ==
+
+Alice -> Bob: 请求
+Bob -> Alice: 应答
+
+== 数据上传 ==
+
+Alice -> Bob: 上传数据
+note left: 这是显示在左边的备注
+
+Bob --> Canny: 转交数据
+... 不超过 5 秒钟 ...
+Canny --> Bob: 状态返回
+note right: 这是显示在右边的备注
+
+Bob -> Alice: 状态返回
+
+== 状态显示 ==
+
+Alice -> Alice: 给自己发消息
+@enduml
+ +

+

环境配置

这里主要介绍 Mac + VS Code + Markdown Preview Enhanced 实现PlantUML预览的配置过程

+

Mac环境支持plantUML的markdown编译步骤

+
brew install libtool
+brew link libtool
+brew install graphviz
+brew link --overwrite graphviz
+ +

如果没有gem,先安装gem。然后执行下面语句安装 asciidoctor。

+
gem install asciidoctor
+

安装完支持环境之后,VS Code里装上 Markdown Preview Enhanced 就可以在markdown里编辑和预览效果啦!

+

plantuml语法:http://plantuml.com/

+

目前,sublime、Atom、VS Code、Webstorm都有相对应的插件来实现在编辑器里编辑和预览plantUML。

+

plantuml编辑器整理

这里还有一些其他的编辑器推荐。大部分都是在线预览版本,也有编辑器插件。

+

1、https://www.planttext.com/
2、http://www.plantuml.com/plantuml
3、https://sujoyu.github.io/plantuml-previewer/
4、Chrome插件 UML Diagram Editor (渲染效果模糊,速度慢)
5、Intellij Idea 插件(Android Studio 当然也支持):PlantUML integration

+

参考

+
文章作者: maple.yf
文章链接: https://maple-yf.github.io/2017/08/27/2017-08-27-plantuml/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Maple's Blog
赞助
  • 微信
    微信
  • 支付宝
    支付宝

评论
\ No newline at end of file diff --git a/2018/01/07/2018-01-07-webpack-introduce/index.html b/2018/01/07/2018-01-07-webpack-introduce/index.html new file mode 100644 index 000000000..3b748414e --- /dev/null +++ b/2018/01/07/2018-01-07-webpack-introduce/index.html @@ -0,0 +1,259 @@ +模块化和Webpack入门 | Maple's Blog + + + + + + + + + + +

模块化和Webpack入门

+ +

简介

本质上,webpack 是一个现代 JavaScript 应用程序的模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。(摘自webpack中文文档)

+

模块化

我们现在已经对前端的模块化习以为常了,但是,想想就在前几年,前端的模块化解决方案层出不穷。出现了各种规范和工具。所以,介绍webpack之前,先简述一下前端模块演进历史。

+

CommonJS

CommonJS 是以在浏览器环境之外构建 JavaScript 生态系统为目标而产生的项目,比如在服务器和桌面环境中。

+

这个项目最开始是由 Mozilla 的工程师 Kevin Dangoor 在2009年1月创建的,当时的名字是 ServerJS。并于2009年8月改名为 CommonJS,以显示其 API 的更广泛实用性。

+

CommonJS 规范是为了解决 JavaScript 的作用域问题而定义的模块形式,可以使每个模块它自身的命名空间中执行。该规范的主要内容是,模块必须通过 module.exports 导出对外的变量或接口,通过 require() 来导入其他模块的输出到当前模块作用域中。

+

CommonJS就是为JS的表现来制定规范,因为js没有模块的功能所以CommonJS应运而生,它希望js可以在任何地方运行,不只是浏览器中。Node就是采用了CommonJS规范。

+

AMD

AMD(Asynchronous Module Definition 异步模块定义)是为浏览器环境设计的,因为 CommonJS 模块系统是同步加载的,当前浏览器环境还没有准备好同步加载模块的条件。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。

+

AMD 定义了一套 JavaScript 模块依赖异步加载标准,来解决同步加载的问题。中文文档

+

CMD

AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。CMD(Common Module Definition)SeaJS 在推广过程中对模块定义的规范化产出。是玉伯大大推出的专注于浏览器的js模块加载规范。

+

UMD

Universal Module Definition,AMD和CommonJS的一种兼容性写法。同时支持两种风格,使AMD和CommonJS和谐相处。

+

ES6模块

ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。ES6 模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。

+

安装

webpack的安装非常简单,和普通的node应用一样$ npm install webpack -g即可安装。

+

配置

跑起来

简单的使用webpack还是很容易的。假如我们的文件结构是

+

|–index.html
|–js
|–data.js
|–index.js
|–dist/dist.js

+

index.js里只是简单的写一句对data.js的引用例如:

+
var data = require("./data");
+

直接使用webpack命令行工具:

+
webpack js/index.js dist/dist.js
+ +

则我们可以在dist.js里看到打包后的代码,data.js也会根据引用关系打包进去。webpack的初次实践就完美的完成啦。

+

webpack.config.js

webpack之所以强大,只是一个简单的命令行工具是完全不够的。所以我们要借助webpack.config.js的配置来完成更加复杂的打包任务。

+

首先,在根目录创建package.json文件,用来配置webpack相关依赖:

+
{
+    "name": "webpack-example",
+    "version": "1.0.0",
+    "description": "A simple webpack example.",
+    "main": "bundle.js",
+    "keywords": [
+        "webpack"
+    ],
+    "author": "maple.yf",
+    "license": "MIT",
+    "dependencies": {
+        "webpack": "^1.12.2"
+    }
+}
+
+ +

其次,创建webpack.config.js文件用来配置打包信息,比如文件入口、打包输出:

+
var webpack = require('webpack')
+
+module.exports = {
+    entry: './js/index.js',
+    output: {
+        path: __dirname + '/dist',
+        filename: 'dist.js'
+    },
+    module: {
+        rules: []
+    },
+    plugins: [
+        
+    ]
+}
+ +

完成配置之后,在命令行中输入webpack,就和上一节中输入的webpack js/index.js dist/dist.js是一样的效果。

+

loader

loader 用于对模块的源代码进行转换。loader 可以使你在 import 或”加载”模块时预处理文件。因此,loader 类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL。loader 甚至允许你直接在 JavaScript 模块中 import CSS文件!

+

其实,loader就是帮助webpack处理非JavaScript文件。在webpack 1.x中,是通过module.loaders来配置的,升级到webpack 2.0后,loader配置项被功能更为强大的rules取代。官方文档loader

+

plugins

插件被webpack官方描述为支柱性功能。它是用来解决loader无法完成的其他事情的。webpack自身提供一些插件,也有很多第三方插件可以使用。能够好好使用插件,将为我们的项目打包提供非常大的便利。将专门抽出一篇来讲解webpack插件的使用技巧。

+

参考资料

+
文章作者: maple.yf
文章链接: https://maple-yf.github.io/2018/01/07/2018-01-07-webpack-introduce/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Maple's Blog
赞助
  • 微信
    微信
  • 支付宝
    支付宝

评论
\ No newline at end of file diff --git a/2018/01/08/2018-01-08-jest-introduction/index.html b/2018/01/08/2018-01-08-jest-introduction/index.html new file mode 100644 index 000000000..d3a7397ee --- /dev/null +++ b/2018/01/08/2018-01-08-jest-introduction/index.html @@ -0,0 +1,336 @@ +Jest自动化测试简介 | Maple's Blog + + + + + + + + + + + + +

Jest自动化测试简介

![](/image
s/jest/jest.png)

+ +

简介

Jest 被 Facebook 用来测试包括 React 应用在内的所有 JavaScript 代码。Jest 的一个理念是提供一套完整集成的 “零配置” 测试体验。

+

基础测试

通过test和expect函数来完成一次最简单的测试:

+
const sum = require('./sum');
+
+test('adds 1 + 2 to equal 3', () => {
+    expect(sum(1, 2)).toBe(3);
+});
+

如果sum函数返回的值就行我们测试描述的那样是3的话,测试通过。

+

结合enzyme

enzyme是aribnb开源的一套测试React的库。它提供的mount方法可以模拟React里的render生成对应的DOM字符串,另外还提供了类似simulate的方法用来模拟事件操作。比如下边的测试例子:

+
it("should provide the actions and subscribe to changes", () => {
+    store.setState({ count: 0 })
+    const Comp = ({ count, increment }) => (
+        <h1 onClick={increment}>{count}</h1>
+    )
+    const mapToProps = ({ count }) => ({ count })
+    const actions = store => ({
+        increment: state => ({ count: state.count + 1 })
+    })
+    const ConnectedComp = connect(mapToProps, actions)(Comp)
+    const App = () => (
+        <Provider store={store}>
+            <ConnectedComp />
+        </Provider>
+    )
+    const wrapper = mount(<App />)
+    expect(wrapper.html()).toBe("<h1>0</h1>")
+    wrapper.children().simulate("click")
+    wrapper.children().simulate("click")
+    expect(wrapper.html()).toBe("<h1>2</h1>")
+})
+

使用mount方法模拟render,通过html方法把DOM结构转换成字符串,通过simulate来模拟单击事件。从而完成整个测试用例。

+

快照测试

enzyme里提供的方法都是基于React的,但是对于类React库而言,这些并不能使用比如Rax。不过,Jest提供了一种快照测试,可以通过快照的方式这是render后的DOM结构。

+

快照测试是通过记录React结构树快照或其他可序列化的值,来简化 Ui 测试,并分析state如何随时间变化而改变。

+

一个典型的快照测试案例是,为移动端应用的UI组件截个图,和需要测试参考图进行比较。如果两张图片不一致,说明测试不通过:可能是非法修改造成的,也可能是UI组件未及时render造成的。

+

Jest Snapshot

在测试react组件时,也可以采用相同的思路进行快照测试。只不过,我们不是通过截图对比,而是保存render时所生成的序列化React tree。例如:

+
import React from 'react';
+import Link from '../Link.react';
+import renderer from 'react-test-renderer';
+
+it('renders correctly', () => {
+    const tree = renderer
+        .create(<Link page="http://www.facebook.com">Facebook</Link>)
+        .toJSON();
+    expect(tree).toMatchSnapshot();
+});
+ +

生成 snapshot file

第一次运行该测试脚本时,Jest会自动生成一个 snapshot file,路径默认是 ./__snapshot__。文件内容如下所示:

+
exports[`renders correctly 1`] = `
+<a
+    className="normal"
+    href="http://www.facebook.com"
+    onMouseEnter={[Function]}
+    onMouseLeave={[Function]}
+>
+    Facebook
+</a>
+`;
+
+

之后再次运行测试脚本的时候,Jest会自动比对render输出的结果和之前的snapshot file的差异,如果相同,则测试通过。

+

更新 snapshot file

由于每次运行结果都会和第一次的 snapshot file 进行比对,如果我想更换比对的 snapshot file文件内容,应该怎么办呢?

+

首先,假如我们有如下场景,更换前面的Link组件的链接,代码如下:

+
import React from 'react';
+import Link from '../Link.react';
+import renderer from 'react-test-renderer';
+
+it('renders correctly', () => {
+    const tree = renderer
+        .create(<Link page="http://www.instagram.com">Facebook</Link>)
+        .toJSON();
+    expect(tree).toMatchSnapshot();
+});
+ +

这时,运行测试脚本时,测试失败。因为render出的快照结果和本次存储的初次 snapshot file内容不一致。此时,如果我想把本次的render结果作为 snapshot file的内容供以后测试比对,可以运行一下命令进行更新:

+
jest --updateSnapshot
+ +

rax-test-renderer

针对Rax测试,官方提供了一个对应的npm包,rax-test-renderer

+

利用它提供的renderer替换react的renderer就可以对rax进行快照测试了。

+

异步测试

使用Jest进行异步测试,有以下三种方式。

+

assertions

通过断言的方式进行测试,所调用的异步方法必须返回一个promise对象。

+
it('works with promises', () => {
+    expect.assertions(1);
+    return user.getUserName(4).then(data => expect(data).toEqual('Mark'));
+});
+ +

async/await

使用这种方式,更显得简单一些,可以和之前的同步测试一样的思路写测试用例。只不过,在异步方法前边加上await关键字用来表示异步执行。

+
it('works with async/await', async () => {
+    expect.assertions(1);
+    const data = await user.getUserName(4);
+    expect(data).toEqual('Mark');
+});
+ +

done

done是异步测试的一种弥补方式,如果需要测试的异步方法没办法返回promise或者不方便转换成async/await的写法,可以通过done方法来实现这种场景的异步测试。

+
test('the data is peanut butter', done => {
+    function callback(data) {
+        expect(data).toBe('peanut butter');
+        done();
+    }
+    fetchData(callback);
+});
+

例如上边的例子,callback是一个异步调用,正常的测试流程下,是不会等着回调再进行测试的。所以Jest加入done方法,done方法被调用的时候,整条测试才会完成。如果done一直没有调用,则测试失败。

+

API

Jest提供了非常丰富的测试API,一共分为以下几类。

+

Globals

全局API:在测试工程中,这些方法或对象直接放到了全局环境中,不需要额外的引入。其中比较常用的有afterAll(fn, timeout)、afterEach(fn, timeout)、beforeAll(fn, timeout)、beforeEach(fn, timeout),分别表示所有测试结束时调用,每个测试结束时调用,所有测试开始前调用,每个测试开始前调用。

+

Expect

这是Jest的关键API,通过expect对象提供的方法,我们用来描述期望得到的结果。expect.toBe() expect.toEqual() expect.toMatch() expect.toMatchObject()等。

+

Mock Functions

用来测试函数的间接调用过程,并把调用过程中的返回信息存储下来。比如测试forEach的调用过程,为传入的数组中的每个元素调用一个回调函数。

+
//通过jest.fn()创建供forEach调用的回调函数
+const mockCallback = jest.fn();
+forEach([0, 1], mockCallback);
+
+// 此模拟函数被调用了两次
+//mockCallback.mock.calls中记录了每次调用的结果
+expect(mockCallback.mock.calls.length).toBe(2);
+
+// 第一次调用函数时的第一个参数是 0
+expect(mockCallback.mock.calls[0][0]).toBe(0);
+
+// 第二次调用函数时的第一个参数是 1
+expect(mockCallback.mock.calls[1][0]).toBe(1);
+

The Jest Object

jest是一个全局对象,在测试文件中可以直接调用。比如上边的例子中的jest.fn()。jest对象里提供了一些系统方法,可以工号的控制整个测试行为和流程。

+

Configuring Jest

Jest的配置可以直接在package.json中进行设置。

+
"jest": {
+    "verbose": true,/*展示详细的测试结果*/
+    "moduleFileExtensions": [ "jsx", "js" ], 
+    "setupFiles": [
+        "<rootDir>/config/testSetup.js" /*配置入口文件*/
+    ],
+    "transformIgnorePatterns": [
+        "node_modules/(?!(FOXRax)/)" /*不忽略node_modules中指定模块的ES6转换(默认情况下,transform转换不作用于node_modules中的模块)*/
+    ],
+    "transform": {
+        "^.+\\.(js|jsx)$": "babel-jest" /*js、jsx指定babel转换*/
+    },
+    "testMatch": [
+        "<rootDir>/src/**/*.spec.(js|jsx)" /*测试文件匹配*/
+    ]
+},
+
+

Jest CLI Options

Jest命令行工具也提供了一些实用的选项。当然,命令行选项也可以在配置文件里设置。比如比较实用的 --json --outputFile=<filename> 的配合使用就可以以json的格式把测试结果输出到本地文件中。

+

参考文献

+
文章作者: maple.yf
文章链接: https://maple-yf.github.io/2018/01/08/2018-01-08-jest-introduction/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Maple's Blog
赞助
  • 微信
    微信
  • 支付宝
    支付宝

评论
\ No newline at end of file diff --git a/2018/01/08/2018-01-08-residual-poem/index.html b/2018/01/08/2018-01-08-residual-poem/index.html new file mode 100644 index 000000000..abc9a1f65 --- /dev/null +++ b/2018/01/08/2018-01-08-residual-poem/index.html @@ -0,0 +1,199 @@ +残诗 | Maple's Blog + + + + + + + + + + +

残诗


+ +

+ +
你不经意间扣开了我的心窗
+
点亮了一点小小的希望
+
像深秋夜空中细细的星子
+
美得清澈
+
又无可奈何的渺茫
文章作者: maple.yf
文章链接: https://maple-yf.github.io/2018/01/08/2018-01-08-residual-poem/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Maple's Blog
赞助
  • 微信
    微信
  • 支付宝
    支付宝

评论
公告
This is my Blog
\ No newline at end of file diff --git a/2018/01/20/2018-01-20-introduction-of-softweare-release-lifecycle/index.html b/2018/01/20/2018-01-20-introduction-of-softweare-release-lifecycle/index.html new file mode 100644 index 000000000..d4393fbf3 --- /dev/null +++ b/2018/01/20/2018-01-20-introduction-of-softweare-release-lifecycle/index.html @@ -0,0 +1,218 @@ +软件开发生命周期 | Maple's Blog + + + + + + + + + + +

软件开发生命周期

+ +

前言

最近研究React的时候,看到这样一个版本号 React 16 RC,非常疑惑,不知道这里的RC到底是什么意思。

+

软件版本周期

查了相关资料才知道,这个和软件版本周期有关,然后在Wikipedia里找到了这张图,这是经过优化过的,原图比较丑^_^

+

+

从图中可以看到,软件的整个版本周期包括两个大的部分:开发测试阶段和发布阶段。

+

开发测试阶段有我们比较熟悉的alpha、beta,以及在此之前的pre-alpha和在此之后的release candidate,也就是前言里提到的RC版本。

+

在发布阶段,又有RTM、GA以及Production等版本阶段。

+

开发测试阶段

Pre-alpha

有时候软件会在Alpha或Beta版本前先发布Pre-alpha版本。一般而言相对于Alpha或Beta版本,Pre-alpha版本是一个功能不完整的版本。

+

Alpha (内部测试版)

Alpha版本仍然需要测试,其功能亦未完善,因为它是整个软件发布周期中的第一个阶段,所以它的名称是“Alpha”,希腊字母中的第一个字母“α”。这个版本一般不会对外发布。

+

Alpha版本通常会送到开发软件的组织或某群体中的软件测试者作内部测试。在市场上,越来越多公司会邀请外部客户或合作伙伴参与其测试。这令软件在此阶段有更大的可用性测试。

+

在测试的第一个阶段中,开发者通常会进行白盒测试。其他测试会在稍后时间由其他测试团体以黑盒或灰盒技术进行,不过有时会同时进行。

+

Beta (外部测试版)

Beta取自希腊字母中的第二个字母“β”,表示软件测试阶段的第二个大的版本。

+

Beta版本是软件最早对外公开的软件版本,由公众参与测试。一般来说,Beta包含所有功能,但可能有一些已知问题和较轻微的BUG。Beta版本的测试者通常是软件开发组织的用户或者客户,他们会以免费或优惠价钱得到软件。Beta版本也被用作查看市场的反馈和用户的建议的一个版本。

+

其他情况,例如微软曾以Community Technology Preview(简称CTP,中文称为“社区技术预览”)为发布软件的测试版本之一,微软将这个阶段的软件散布给有需要先行试用的用户或厂商,并收集这些人的使用经验,以便作为进一步修正软件的参考。

+

Release Candidate, RC

Release Candidate(简称RC)指可能成为最终产品的候选版本,如果未出现问题则可发布成为正式版本。在此阶段的产品通常包含所有功能、或接近完整,亦不会出现严重问题。

+

多数开源软件会推出两个RC版本,最后的RC2则成为正式版本。闭源软件较少公开使用,微软公司在Windows 7上应用此名称。苹果公司把在这阶段的产品称为“Golden Master Candidate”(简称GM Candidate),而最后的GM即成为正式版本。再比如,React 16就有两个RC版本,分别是Release 16.0.0-rc.1以及Release 16.0.0-rc.2。

+

当然,也有些软件厂商继续采用希腊字母来表示这一阶段的版本号,例如γ(gamma),δ(delta)。

+

发布阶段

Release to Manufacting, RTM

生产商发放(Release to Manufacturing,缩写RTM)是软件产品准备交付时使用的术语。某些计算机程序以“RTM”作为软件版本代号,例如微软Windows 7发行零售版前的RTM版本主要是发放给组装机生产商用,使制造商能够提早进行集成工作或解决软件与硬件设备可能遇到的错误。RTM版本并不一定意味着创作者解决了软件所有问题;仍有可能向公众发布前更新版本。以Windows 7为例:RTM版与零售版的版本号是一样的。

+

General availability, GA

一般可用(General availability, 缩写GA)是所有必要的商业活动已经完成,该软件产品已经可以发售的阶段。然而,这取决于语言、地域和电子设备与媒体的可用性。商业活动可能也包括安全性和合法测试,以及本地化和全球销售的可能性评估。RTM与GA的间隔可能会是1周或几个月,因为在此过程中需要进行许多商业活动·。在这个阶段,可以说软件已经“上线”了。

+

Release to Web, RTW

网络分发(Release to Web,缩写RTW),或称Web发布是一种利用互联网进行分发的软件交付方式。制造商在这种类型的发布中并不生产实体软件。随着互联网使用人数的增长,RTW变得越来越普遍。

+

参考文档

本篇文章大部分来自维基百科的内容。

+ +
文章作者: maple.yf
文章链接: https://maple-yf.github.io/2018/01/20/2018-01-20-introduction-of-softweare-release-lifecycle/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Maple's Blog
赞助
  • 微信
    微信
  • 支付宝
    支付宝

评论
\ No newline at end of file diff --git a/about/index.html b/about/index.html new file mode 100644 index 000000000..293b00212 --- /dev/null +++ b/about/index.html @@ -0,0 +1,165 @@ +Hello World | Maple's Blog + + + + + + + + + + + +
生活不止眼前的苟且,还有诗和远方的田野。
+ +
努力做一个生活有烟火气,灵魂有香气的孩子。
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/archives/2015/09/index.html b/archives/2015/09/index.html new file mode 100644 index 000000000..2a584310f --- /dev/null +++ b/archives/2015/09/index.html @@ -0,0 +1,159 @@ +2015-09-01 | Maple's Blog + + + + + + + +
文章总览 - 1
2015
为笔记本(华硕A46C)更换SSD全过程
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/archives/2015/11/index.html b/archives/2015/11/index.html new file mode 100644 index 000000000..110bb09c6 --- /dev/null +++ b/archives/2015/11/index.html @@ -0,0 +1,159 @@ +2015-11-01 | Maple's Blog + + + + + + + +
文章总览 - 2
2015
安装 ShadowScoks
win10右键反应缓慢
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/archives/2015/12/index.html b/archives/2015/12/index.html new file mode 100644 index 000000000..ffc2c2136 --- /dev/null +++ b/archives/2015/12/index.html @@ -0,0 +1,159 @@ +2015-12-01 | Maple's Blog + + + + + + + +
文章总览 - 1
2015
Ubuntu用户设置
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/archives/2015/index.html b/archives/2015/index.html new file mode 100644 index 000000000..533268969 --- /dev/null +++ b/archives/2015/index.html @@ -0,0 +1,159 @@ +2015 | Maple's Blog + + + + + + + +
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/archives/2016/04/index.html b/archives/2016/04/index.html new file mode 100644 index 000000000..3e3d33a35 --- /dev/null +++ b/archives/2016/04/index.html @@ -0,0 +1,159 @@ +2016-04-01 | Maple's Blog + + + + + + + +
文章总览 - 1
2016
安装静态博客Jekyll
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/archives/2016/06/index.html b/archives/2016/06/index.html new file mode 100644 index 000000000..d1f9db366 --- /dev/null +++ b/archives/2016/06/index.html @@ -0,0 +1,159 @@ +2016-06-01 | Maple's Blog + + + + + + + +
文章总览 - 1
2016
不得不说再见
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/archives/2016/index.html b/archives/2016/index.html new file mode 100644 index 000000000..ff638c42d --- /dev/null +++ b/archives/2016/index.html @@ -0,0 +1,159 @@ +2016 | Maple's Blog + + + + + + + +
文章总览 - 2
2016
不得不说再见
安装静态博客Jekyll
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/archives/2017/02/index.html b/archives/2017/02/index.html new file mode 100644 index 000000000..a66ea5493 --- /dev/null +++ b/archives/2017/02/index.html @@ -0,0 +1,159 @@ +2017-02-01 | Maple's Blog + + + + + + + +
文章总览 - 1
2017
吹雪
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/archives/2017/05/index.html b/archives/2017/05/index.html new file mode 100644 index 000000000..827b1447a --- /dev/null +++ b/archives/2017/05/index.html @@ -0,0 +1,159 @@ +2017-05-01 | Maple's Blog + + + + + + + +
文章总览 - 1
2017
趁黄昏
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/archives/2017/07/index.html b/archives/2017/07/index.html new file mode 100644 index 000000000..e02812e26 --- /dev/null +++ b/archives/2017/07/index.html @@ -0,0 +1,159 @@ +2017-07-01 | Maple's Blog + + + + + + + +
文章总览 - 3
2017
夜雨
前端编程利器VS Code
南湖向晚
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/archives/2017/08/index.html b/archives/2017/08/index.html new file mode 100644 index 000000000..f2aa9c68e --- /dev/null +++ b/archives/2017/08/index.html @@ -0,0 +1,159 @@ +2017-08-01 | Maple's Blog + + + + + + + +
文章总览 - 2
2017
plantuml简介
Hello World
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/archives/2017/index.html b/archives/2017/index.html new file mode 100644 index 000000000..318280d18 --- /dev/null +++ b/archives/2017/index.html @@ -0,0 +1,159 @@ +2017 | Maple's Blog + + + + + + + +
文章总览 - 7
2017
plantuml简介
Hello World
夜雨
前端编程利器VS Code
南湖向晚
趁黄昏
吹雪
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/archives/2018/01/index.html b/archives/2018/01/index.html new file mode 100644 index 000000000..a779d08b7 --- /dev/null +++ b/archives/2018/01/index.html @@ -0,0 +1,159 @@ +2018-01-01 | Maple's Blog + + + + + + + +
文章总览 - 4
2018
软件开发生命周期
软件开发生命周期
Jest自动化测试简介
残诗
模块化和Webpack入门
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/archives/2018/index.html b/archives/2018/index.html new file mode 100644 index 000000000..dc0c5949a --- /dev/null +++ b/archives/2018/index.html @@ -0,0 +1,159 @@ +2018 | Maple's Blog + + + + + + + +
文章总览 - 4
2018
软件开发生命周期
软件开发生命周期
Jest自动化测试简介
残诗
模块化和Webpack入门
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/archives/index.html b/archives/index.html new file mode 100644 index 000000000..c6260e7e0 --- /dev/null +++ b/archives/index.html @@ -0,0 +1,159 @@ +Archives | Maple's Blog + + + + + + + +
文章总览 - 17
2018
软件开发生命周期
软件开发生命周期
Jest自动化测试简介
残诗
模块化和Webpack入门
2017
plantuml简介
Hello World
夜雨
前端编程利器VS Code
南湖向晚
趁黄昏
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/archives/page/2/index.html b/archives/page/2/index.html new file mode 100644 index 000000000..dad96e5f8 --- /dev/null +++ b/archives/page/2/index.html @@ -0,0 +1,159 @@ +Archives | Maple's Blog + + + + + + + +
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/categories/Poetry/index.html b/categories/Poetry/index.html new file mode 100644 index 000000000..a678ef14a --- /dev/null +++ b/categories/Poetry/index.html @@ -0,0 +1,159 @@ +分类: Poetry | Maple's Blog + + + + + + + +
分类 - Poetry
2018
残诗
2017
夜雨
南湖向晚
趁黄昏
吹雪
2016
不得不说再见
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/categories/Tech/index.html b/categories/Tech/index.html new file mode 100644 index 000000000..f4253398b --- /dev/null +++ b/categories/Tech/index.html @@ -0,0 +1,159 @@ +分类: Tech | Maple's Blog + + + + + + + +
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/categories/Tech/page/2/index.html b/categories/Tech/page/2/index.html new file mode 100644 index 000000000..7a897aa37 --- /dev/null +++ b/categories/Tech/page/2/index.html @@ -0,0 +1,159 @@ +分类: Tech | Maple's Blog + + + + + + + +
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/categories/index.html b/categories/index.html new file mode 100644 index 000000000..92a9fe0aa --- /dev/null +++ b/categories/index.html @@ -0,0 +1,164 @@ +Categories | Maple's Blog + + + + + + + + + + + +
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/content.json b/content.json new file mode 100644 index 000000000..e894957c2 --- /dev/null +++ b/content.json @@ -0,0 +1 @@ +{"meta":{"title":"Maple's Blog","subtitle":null,"description":null,"author":"maple.yf","url":"https://maple-yf.github.io","root":"/"},"pages":[{"title":"Categories","date":"2017-08-20T16:09:17.000Z","updated":"2020-12-21T15:44:10.053Z","comments":false,"path":"categories/index.html","permalink":"https://maple-yf.github.io/categories/index.html","excerpt":"","text":"PoetryTech"},{"title":"Hello World","date":"2017-08-27T05:21:57.000Z","updated":"2020-12-21T15:44:10.053Z","comments":false,"path":"about/index.html","permalink":"https://maple-yf.github.io/about/index.html","excerpt":"","text":"生活不止眼前的苟且,还有诗和远方的田野。 努力做一个生活有烟火气,灵魂有香气的孩子。"},{"title":"Tags","date":"2017-08-20T15:51:50.000Z","updated":"2020-12-21T15:44:10.054Z","comments":false,"path":"tags/index.html","permalink":"https://maple-yf.github.io/tags/index.html","excerpt":"","text":"PoetryWebpackJekyllSSDShadowSocksUbuntu[VS Code](VS Code)WindowsUML[Auto Test](Auto Test)ITCSSNodeJavaScriptReact"}],"posts":[{"title":"软件开发生命周期","slug":"2018-01-20-introduction-of-softweare-release-lifecycle","date":"2018-01-19T16:00:00.000Z","updated":"2023-11-15T00:56:05.721Z","comments":true,"path":"2018/01/20/2018-01-20-introduction-of-softweare-release-lifecycle/","link":"","permalink":"https://maple-yf.github.io/2018/01/20/2018-01-20-introduction-of-softweare-release-lifecycle/","excerpt":"","text":"前言最近研究React的时候,看到这样一个版本号 React 16 RC,非常疑惑,不知道这里的RC到底是什么意思。 软件版本周期查了相关资料才知道,这个和软件版本周期有关,然后在Wikipedia里找到了这张图,这是经过优化过的,原图比较丑^_^。 从图中可以看到,软件的整个版本周期包括两个大的部分:开发测试阶段和发布阶段。 开发测试阶段有我们比较熟悉的alpha、beta,以及在此之前的pre-alpha和在此之后的release candidate,也就是前言里提到的RC版本。 在发布阶段,又有RTM、GA以及Production等版本阶段。 开发测试阶段Pre-alpha有时候软件会在Alpha或Beta版本前先发布Pre-alpha版本。一般而言相对于Alpha或Beta版本,Pre-alpha版本是一个功能不完整的版本。 Alpha (内部测试版)Alpha版本仍然需要测试,其功能亦未完善,因为它是整个软件发布周期中的第一个阶段,所以它的名称是“Alpha”,希腊字母中的第一个字母“α”。这个版本一般不会对外发布。 Alpha版本通常会送到开发软件的组织或某群体中的软件测试者作内部测试。在市场上,越来越多公司会邀请外部客户或合作伙伴参与其测试。这令软件在此阶段有更大的可用性测试。 在测试的第一个阶段中,开发者通常会进行白盒测试。其他测试会在稍后时间由其他测试团体以黑盒或灰盒技术进行,不过有时会同时进行。 Beta (外部测试版)Beta取自希腊字母中的第二个字母“β”,表示软件测试阶段的第二个大的版本。 Beta版本是软件最早对外公开的软件版本,由公众参与测试。一般来说,Beta包含所有功能,但可能有一些已知问题和较轻微的BUG。Beta版本的测试者通常是软件开发组织的用户或者客户,他们会以免费或优惠价钱得到软件。Beta版本也被用作查看市场的反馈和用户的建议的一个版本。 其他情况,例如微软曾以Community Technology Preview(简称CTP,中文称为“社区技术预览”)为发布软件的测试版本之一,微软将这个阶段的软件散布给有需要先行试用的用户或厂商,并收集这些人的使用经验,以便作为进一步修正软件的参考。 Release Candidate, RCRelease Candidate(简称RC)指可能成为最终产品的候选版本,如果未出现问题则可发布成为正式版本。在此阶段的产品通常包含所有功能、或接近完整,亦不会出现严重问题。 多数开源软件会推出两个RC版本,最后的RC2则成为正式版本。闭源软件较少公开使用,微软公司在Windows 7上应用此名称。苹果公司把在这阶段的产品称为“Golden Master Candidate”(简称GM Candidate),而最后的GM即成为正式版本。再比如,React 16就有两个RC版本,分别是Release 16.0.0-rc.1以及Release 16.0.0-rc.2。 当然,也有些软件厂商继续采用希腊字母来表示这一阶段的版本号,例如γ(gamma),δ(delta)。 发布阶段Release to Manufacting, RTM生产商发放(Release to Manufacturing,缩写RTM)是软件产品准备交付时使用的术语。某些计算机程序以“RTM”作为软件版本代号,例如微软Windows 7发行零售版前的RTM版本主要是发放给组装机生产商用,使制造商能够提早进行集成工作或解决软件与硬件设备可能遇到的错误。RTM版本并不一定意味着创作者解决了软件所有问题;仍有可能向公众发布前更新版本。以Windows 7为例:RTM版与零售版的版本号是一样的。 General availability, GA一般可用(General availability, 缩写GA)是所有必要的商业活动已经完成,该软件产品已经可以发售的阶段。然而,这取决于语言、地域和电子设备与媒体的可用性。商业活动可能也包括安全性和合法测试,以及本地化和全球销售的可能性评估。RTM与GA的间隔可能会是1周或几个月,因为在此过程中需要进行许多商业活动·。在这个阶段,可以说软件已经“上线”了。 Release to Web, RTW网络分发(Release to Web,缩写RTW),或称Web发布是一种利用互联网进行分发的软件交付方式。制造商在这种类型的发布中并不生产实体软件。随着互联网使用人数的增长,RTW变得越来越普遍。 参考文档本篇文章大部分来自维基百科的内容。 http://blog.csdn.net/linxinzheng/article/details/2201043 https://en.wikipedia.org/wiki/Software_release_life_cycle https://baike.baidu.com/item/%E8%BD%AF%E4%BB%B6%E7%89%88%E6%9C%AC","categories":[{"name":"Tech","slug":"Tech","permalink":"https://maple-yf.github.io/categories/Tech/"}],"tags":[{"name":"IT","slug":"IT","permalink":"https://maple-yf.github.io/tags/IT/"}]},{"title":"Jest自动化测试简介","slug":"2018-01-08-jest-introduction","date":"2018-01-07T16:00:00.000Z","updated":"2022-05-01T06:30:26.641Z","comments":true,"path":"2018/01/08/2018-01-08-jest-introduction/","link":"","permalink":"https://maple-yf.github.io/2018/01/08/2018-01-08-jest-introduction/","excerpt":"![](/images/jest/jest.png)","text":"![](/images/jest/jest.png) 简介Jest 被 Facebook 用来测试包括 React 应用在内的所有 JavaScript 代码。Jest 的一个理念是提供一套完整集成的 “零配置” 测试体验。 基础测试通过test和expect函数来完成一次最简单的测试: const sum = require('./sum'); test('adds 1 + 2 to equal 3', () => { expect(sum(1, 2)).toBe(3); }); 如果sum函数返回的值就行我们测试描述的那样是3的话,测试通过。 结合enzymeenzyme是aribnb开源的一套测试React的库。它提供的mount方法可以模拟React里的render生成对应的DOM字符串,另外还提供了类似simulate的方法用来模拟事件操作。比如下边的测试例子: it("should provide the actions and subscribe to changes", () => { store.setState({ count: 0 }) const Comp = ({ count, increment }) => ( <h1 onClick={increment}>{count}</h1> ) const mapToProps = ({ count }) => ({ count }) const actions = store => ({ increment: state => ({ count: state.count + 1 }) }) const ConnectedComp = connect(mapToProps, actions)(Comp) const App = () => ( <Provider store={store}> <ConnectedComp /> </Provider> ) const wrapper = mount(<App />) expect(wrapper.html()).toBe("<h1>0</h1>") wrapper.children().simulate("click") wrapper.children().simulate("click") expect(wrapper.html()).toBe("<h1>2</h1>") }) 使用mount方法模拟render,通过html方法把DOM结构转换成字符串,通过simulate来模拟单击事件。从而完成整个测试用例。 快照测试enzyme里提供的方法都是基于React的,但是对于类React库而言,这些并不能使用比如Rax。不过,Jest提供了一种快照测试,可以通过快照的方式这是render后的DOM结构。 快照测试是通过记录React结构树快照或其他可序列化的值,来简化 Ui 测试,并分析state如何随时间变化而改变。 一个典型的快照测试案例是,为移动端应用的UI组件截个图,和需要测试参考图进行比较。如果两张图片不一致,说明测试不通过:可能是非法修改造成的,也可能是UI组件未及时render造成的。 Jest Snapshot在测试react组件时,也可以采用相同的思路进行快照测试。只不过,我们不是通过截图对比,而是保存render时所生成的序列化React tree。例如: import React from 'react'; import Link from '../Link.react'; import renderer from 'react-test-renderer'; it('renders correctly', () => { const tree = renderer .create(<Link page="http://www.facebook.com">Facebook</Link>) .toJSON(); expect(tree).toMatchSnapshot(); }); 生成 snapshot file第一次运行该测试脚本时,Jest会自动生成一个 snapshot file,路径默认是 ./__snapshot__。文件内容如下所示: exports[`renders correctly 1`] = ` <a className="normal" href="http://www.facebook.com" onMouseEnter={[Function]} onMouseLeave={[Function]} > Facebook </a> `; 之后再次运行测试脚本的时候,Jest会自动比对render输出的结果和之前的snapshot file的差异,如果相同,则测试通过。 更新 snapshot file由于每次运行结果都会和第一次的 snapshot file 进行比对,如果我想更换比对的 snapshot file文件内容,应该怎么办呢? 首先,假如我们有如下场景,更换前面的Link组件的链接,代码如下: import React from 'react'; import Link from '../Link.react'; import renderer from 'react-test-renderer'; it('renders correctly', () => { const tree = renderer .create(<Link page="http://www.instagram.com">Facebook</Link>) .toJSON(); expect(tree).toMatchSnapshot(); }); 这时,运行测试脚本时,测试失败。因为render出的快照结果和本次存储的初次 snapshot file内容不一致。此时,如果我想把本次的render结果作为 snapshot file的内容供以后测试比对,可以运行一下命令进行更新: jest --updateSnapshot rax-test-renderer针对Rax测试,官方提供了一个对应的npm包,rax-test-renderer。 利用它提供的renderer替换react的renderer就可以对rax进行快照测试了。 异步测试使用Jest进行异步测试,有以下三种方式。 assertions通过断言的方式进行测试,所调用的异步方法必须返回一个promise对象。 it('works with promises', () => { expect.assertions(1); return user.getUserName(4).then(data => expect(data).toEqual('Mark')); }); async/await使用这种方式,更显得简单一些,可以和之前的同步测试一样的思路写测试用例。只不过,在异步方法前边加上await关键字用来表示异步执行。 it('works with async/await', async () => { expect.assertions(1); const data = await user.getUserName(4); expect(data).toEqual('Mark'); }); donedone是异步测试的一种弥补方式,如果需要测试的异步方法没办法返回promise或者不方便转换成async/await的写法,可以通过done方法来实现这种场景的异步测试。 test('the data is peanut butter', done => { function callback(data) { expect(data).toBe('peanut butter'); done(); } fetchData(callback); }); 例如上边的例子,callback是一个异步调用,正常的测试流程下,是不会等着回调再进行测试的。所以Jest加入done方法,done方法被调用的时候,整条测试才会完成。如果done一直没有调用,则测试失败。 APIJest提供了非常丰富的测试API,一共分为以下几类。 Globals全局API:在测试工程中,这些方法或对象直接放到了全局环境中,不需要额外的引入。其中比较常用的有afterAll(fn, timeout)、afterEach(fn, timeout)、beforeAll(fn, timeout)、beforeEach(fn, timeout),分别表示所有测试结束时调用,每个测试结束时调用,所有测试开始前调用,每个测试开始前调用。 Expect这是Jest的关键API,通过expect对象提供的方法,我们用来描述期望得到的结果。expect.toBe() expect.toEqual() expect.toMatch() expect.toMatchObject()等。 Mock Functions用来测试函数的间接调用过程,并把调用过程中的返回信息存储下来。比如测试forEach的调用过程,为传入的数组中的每个元素调用一个回调函数。 //通过jest.fn()创建供forEach调用的回调函数 const mockCallback = jest.fn(); forEach([0, 1], mockCallback); // 此模拟函数被调用了两次 //mockCallback.mock.calls中记录了每次调用的结果 expect(mockCallback.mock.calls.length).toBe(2); // 第一次调用函数时的第一个参数是 0 expect(mockCallback.mock.calls[0][0]).toBe(0); // 第二次调用函数时的第一个参数是 1 expect(mockCallback.mock.calls[1][0]).toBe(1); The Jest Objectjest是一个全局对象,在测试文件中可以直接调用。比如上边的例子中的jest.fn()。jest对象里提供了一些系统方法,可以工号的控制整个测试行为和流程。 Configuring JestJest的配置可以直接在package.json中进行设置。 "jest": { "verbose": true,/*展示详细的测试结果*/ "moduleFileExtensions": [ "jsx", "js" ], "setupFiles": [ "<rootDir>/config/testSetup.js" /*配置入口文件*/ ], "transformIgnorePatterns": [ "node_modules/(?!(FOXRax)/)" /*不忽略node_modules中指定模块的ES6转换(默认情况下,transform转换不作用于node_modules中的模块)*/ ], "transform": { "^.+\\\\.(js|jsx)$": "babel-jest" /*js、jsx指定babel转换*/ }, "testMatch": [ "<rootDir>/src/**/*.spec.(js|jsx)" /*测试文件匹配*/ ] }, Jest CLI OptionsJest命令行工具也提供了一些实用的选项。当然,命令行选项也可以在配置文件里设置。比如比较实用的 --json --outputFile=<filename> 的配合使用就可以以json的格式把测试结果输出到本地文件中。 参考文献 http://facebook.github.io/jest/docs/en/snapshot-testing.html#snapshot-testing-with-jest https://facebook.github.io/jest/docs/en/api.html","categories":[{"name":"Tech","slug":"Tech","permalink":"https://maple-yf.github.io/categories/Tech/"}],"tags":[{"name":"Auto Test","slug":"Auto-Test","permalink":"https://maple-yf.github.io/tags/Auto-Test/"}]},{"title":"残诗","slug":"2018-01-08-residual-poem","date":"2018-01-07T16:00:00.000Z","updated":"2022-05-01T06:30:33.058Z","comments":true,"path":"2018/01/08/2018-01-08-residual-poem/","link":"","permalink":"https://maple-yf.github.io/2018/01/08/2018-01-08-residual-poem/","excerpt":"","text":"你不经意间扣开了我的心窗 点亮了一点小小的希望 像深秋夜空中细细的星子 美得清澈 又无可奈何的渺茫","categories":[{"name":"Poetry","slug":"Poetry","permalink":"https://maple-yf.github.io/categories/Poetry/"}],"tags":[{"name":"Poetry","slug":"Poetry","permalink":"https://maple-yf.github.io/tags/Poetry/"}]},{"title":"模块化和Webpack入门","slug":"2018-01-07-webpack-introduce","date":"2018-01-06T16:00:00.000Z","updated":"2022-04-09T05:42:06.579Z","comments":true,"path":"2018/01/07/2018-01-07-webpack-introduce/","link":"","permalink":"https://maple-yf.github.io/2018/01/07/2018-01-07-webpack-introduce/","excerpt":"","text":"简介本质上,webpack 是一个现代 JavaScript 应用程序的模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。(摘自webpack中文文档) 模块化我们现在已经对前端的模块化习以为常了,但是,想想就在前几年,前端的模块化解决方案层出不穷。出现了各种规范和工具。所以,介绍webpack之前,先简述一下前端模块演进历史。 CommonJSCommonJS 是以在浏览器环境之外构建 JavaScript 生态系统为目标而产生的项目,比如在服务器和桌面环境中。 这个项目最开始是由 Mozilla 的工程师 Kevin Dangoor 在2009年1月创建的,当时的名字是 ServerJS。并于2009年8月改名为 CommonJS,以显示其 API 的更广泛实用性。 CommonJS 规范是为了解决 JavaScript 的作用域问题而定义的模块形式,可以使每个模块它自身的命名空间中执行。该规范的主要内容是,模块必须通过 module.exports 导出对外的变量或接口,通过 require() 来导入其他模块的输出到当前模块作用域中。 CommonJS就是为JS的表现来制定规范,因为js没有模块的功能所以CommonJS应运而生,它希望js可以在任何地方运行,不只是浏览器中。Node就是采用了CommonJS规范。 AMDAMD(Asynchronous Module Definition 异步模块定义)是为浏览器环境设计的,因为 CommonJS 模块系统是同步加载的,当前浏览器环境还没有准备好同步加载模块的条件。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。 AMD 定义了一套 JavaScript 模块依赖异步加载标准,来解决同步加载的问题。中文文档 CMDAMD 是 RequireJS 在推广过程中对模块定义的规范化产出。CMD(Common Module Definition) 是 SeaJS 在推广过程中对模块定义的规范化产出。是玉伯大大推出的专注于浏览器的js模块加载规范。 UMDUniversal Module Definition,AMD和CommonJS的一种兼容性写法。同时支持两种风格,使AMD和CommonJS和谐相处。 ES6模块ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。ES6 模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。 安装webpack的安装非常简单,和普通的node应用一样$ npm install webpack -g即可安装。 配置跑起来简单的使用webpack还是很容易的。假如我们的文件结构是 |–index.html|–js |–data.js |–index.js|–dist/dist.js index.js里只是简单的写一句对data.js的引用例如: var data = require("./data"); 直接使用webpack命令行工具: webpack js/index.js dist/dist.js 则我们可以在dist.js里看到打包后的代码,data.js也会根据引用关系打包进去。webpack的初次实践就完美的完成啦。 webpack.config.jswebpack之所以强大,只是一个简单的命令行工具是完全不够的。所以我们要借助webpack.config.js的配置来完成更加复杂的打包任务。 首先,在根目录创建package.json文件,用来配置webpack相关依赖: { "name": "webpack-example", "version": "1.0.0", "description": "A simple webpack example.", "main": "bundle.js", "keywords": [ "webpack" ], "author": "maple.yf", "license": "MIT", "dependencies": { "webpack": "^1.12.2" } } 其次,创建webpack.config.js文件用来配置打包信息,比如文件入口、打包输出: var webpack = require('webpack') module.exports = { entry: './js/index.js', output: { path: __dirname + '/dist', filename: 'dist.js' }, module: { rules: [] }, plugins: [ ] } 完成配置之后,在命令行中输入webpack,就和上一节中输入的webpack js/index.js dist/dist.js是一样的效果。 loaderloader 用于对模块的源代码进行转换。loader 可以使你在 import 或”加载”模块时预处理文件。因此,loader 类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL。loader 甚至允许你直接在 JavaScript 模块中 import CSS文件! 其实,loader就是帮助webpack处理非JavaScript文件。在webpack 1.x中,是通过module.loaders来配置的,升级到webpack 2.0后,loader配置项被功能更为强大的rules取代。官方文档loader。 plugins插件被webpack官方描述为支柱性功能。它是用来解决loader无法完成的其他事情的。webpack自身提供一些插件,也有很多第三方插件可以使用。能够好好使用插件,将为我们的项目打包提供非常大的便利。将专门抽出一篇来讲解webpack插件的使用技巧。 参考资料 https://doc.webpack-china.org/concepts/ http://zhaoda.net/webpack-handbook/what-is-webpack.html https://div.io/topic/1752 http://www.ruanyifeng.com/blog/2014/09/package-management.html https://webpack.js.org/comparison/","categories":[{"name":"Tech","slug":"Tech","permalink":"https://maple-yf.github.io/categories/Tech/"}],"tags":[{"name":"Webpack","slug":"Webpack","permalink":"https://maple-yf.github.io/tags/Webpack/"}]},{"title":"plantuml简介","slug":"2017-08-27-plantuml","date":"2017-08-26T16:00:00.000Z","updated":"2022-04-09T08:17:57.314Z","comments":true,"path":"2017/08/27/2017-08-27-plantuml/","link":"","permalink":"https://maple-yf.github.io/2017/08/27/2017-08-27-plantuml/","excerpt":"简介最近在学习设计模式,但是在画类图的时候,有一堆的画图工具可以选择,但总感觉用的不顺手。于是在网上找到了这个神奇的语言。PlantUML是一个开源项目,支持时序图、用例图、类图、活动图、组件图、状态图、对象图等的绘制。简而言之,就是用写代码的方式画图。几行代码,输出标准结构图,不用再去考虑结构、对齐等琐事啦! 效果预览如下简单的语法表达类图之间的关系 @startuml Class01 <|-- Class02 Class03 <|.. Class04 Class05 *-- Class06 Class07 o-- Class08 Class09 <.. Class10 Class11 <-- Class12 @enduml","text":"简介最近在学习设计模式,但是在画类图的时候,有一堆的画图工具可以选择,但总感觉用的不顺手。于是在网上找到了这个神奇的语言。PlantUML是一个开源项目,支持时序图、用例图、类图、活动图、组件图、状态图、对象图等的绘制。简而言之,就是用写代码的方式画图。几行代码,输出标准结构图,不用再去考虑结构、对齐等琐事啦! 效果预览如下简单的语法表达类图之间的关系 @startuml Class01 <|-- Class02 Class03 <|.. Class04 Class05 *-- Class06 Class07 o-- Class08 Class09 <.. Class10 Class11 <-- Class12 @enduml 效果如下: 再看一下复杂一点的装饰者模式类图,代码如下 @startuml namespace Decorator{ interface Component interface Decorator Component : +operation():void ConcreateComponent : +opreation():void Decorator : -component:Component Decorator : +opreantion():void ConcreateDecorator1 : +opreation():void ConcreateDecorator1 : +addBehavior():void ConcreateDecorator2 : +opreation():void ConcreateDecorator2 : +addBehavior():void Decorator <|-- ConcreateDecorator1 Decorator <|-- ConcreateDecorator2 Component <|.. Decorator Component <|.. ConcreateComponent Decorator o-- Component note bottom of Decorator component.opreation(); end note note bottom of ConcreateDecorator1 super.operation(); addBehavior(); end note note bottom of ConcreateDecorator2 super.operation(); addBehavior(); end note } @enduml 效果图: 时序图长这样: @startuml title 时序图 == 鉴权阶段 == Alice -> Bob: 请求 Bob -> Alice: 应答 == 数据上传 == Alice -> Bob: 上传数据 note left: 这是显示在左边的备注 Bob --> Canny: 转交数据 ... 不超过 5 秒钟 ... Canny --> Bob: 状态返回 note right: 这是显示在右边的备注 Bob -> Alice: 状态返回 == 状态显示 == Alice -> Alice: 给自己发消息 @enduml 环境配置这里主要介绍 Mac + VS Code + Markdown Preview Enhanced 实现PlantUML预览的配置过程 Mac环境支持plantUML的markdown编译\b步骤 brew install libtool brew link libtool brew install graphviz brew link --overwrite graphviz \b如果没有gem,先安装gem。然后执行下面语句安装 asciidoctor。 gem install asciidoctor 安装完支持环境之后,VS Code里装上 Markdown Preview Enhanced 就可以在markdown里编辑和预览效果啦! plantuml语法:http://plantuml.com/ 目前,sublime、Atom、VS Code、Webstorm都有相对应的插件来实现在编辑器里编辑和预览plantUML。 plantuml编辑器整理这里还有一些其他的编辑器推荐。大部分都是在线预览版本,也有编辑器插件。 1、https://www.planttext.com/2、http://www.plantuml.com/plantuml3、https://sujoyu.github.io/plantuml-previewer/4、Chrome插件 UML Diagram Editor (渲染效果模糊,速度慢)5、Intellij Idea 插件(Android Studio 当然也支持):PlantUML integration 参考 http://plantuml.com/ http://www.voidcn.com/blog/lonewolf521125/article/p-6630256.html http://www.voidcn.com/blog/linuxcjh/article/p-5799343.html","categories":[{"name":"Tech","slug":"Tech","permalink":"https://maple-yf.github.io/categories/Tech/"}],"tags":[{"name":"UML","slug":"UML","permalink":"https://maple-yf.github.io/tags/UML/"}]},{"title":"Hello World","slug":"2017-08-06-hello-world","date":"2017-08-05T16:00:00.000Z","updated":"2020-12-21T15:44:10.051Z","comments":true,"path":"2017/08/06/2017-08-06-hello-world/","link":"","permalink":"https://maple-yf.github.io/2017/08/06/2017-08-06-hello-world/","excerpt":"Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.","text":"Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub. Quick StartCreate a new post$ hexo new "My New Post" More info: Writing Run server$ hexo server More info: Server Generate static files$ hexo generate More info: Generating Deploy to remote sites$ hexo deploy More info: Deployment","categories":[{"name":"Tech","slug":"Tech","permalink":"https://maple-yf.github.io/categories/Tech/"}],"tags":[{"name":"IT","slug":"IT","permalink":"https://maple-yf.github.io/tags/IT/"}]},{"title":"夜雨","slug":"2017-07-21-raining-night","date":"2017-07-20T16:00:00.000Z","updated":"2022-05-01T06:31:18.510Z","comments":true,"path":"2017/07/21/2017-07-21-raining-night/","link":"","permalink":"https://maple-yf.github.io/2017/07/21/2017-07-21-raining-night/","excerpt":"","text":"雷隐隐,风悄悄 这整夜的雨 淅淅沥沥潇潇","categories":[{"name":"Poetry","slug":"Poetry","permalink":"https://maple-yf.github.io/categories/Poetry/"}],"tags":[{"name":"Poetry","slug":"Poetry","permalink":"https://maple-yf.github.io/tags/Poetry/"}]},{"title":"前端编程利器VS Code","slug":"2017-07-20-vscode-introduction","date":"2017-07-19T16:00:00.000Z","updated":"2022-04-09T08:18:11.358Z","comments":true,"path":"2017/07/20/2017-07-20-vscode-introduction/","link":"","permalink":"https://maple-yf.github.io/2017/07/20/2017-07-20-vscode-introduction/","excerpt":"","text":"前言前端同学使用的编辑器可选范围非常广泛。 最开始接触到前端的时候,听说了Dreamweaver这么一个强大的软件,但严格意义上讲,这不能算作一个编辑器。后来认识了NotePad++,在当时,这确实是一款非常好用的编辑器,语法高亮的友好度仅次于IDE,而且占用内存小,运行非常流畅。 再然后,有人推荐Sublime。我用的时候,还是Sublime 2,最吸引我的是它的mini map,拖动mini map快速浏览大段大段的代码,比拖动小小的滑块酸爽很多呀。再加上后来安装的各种插件,感觉我进入了一个全新的世界,Sublime才是我最想用的编辑器呀! 工作之后,听说大家都在用webstorm,于是我也安装了一个试试,功能确实强大,特别它自带的git管理以及编辑器内部打开terminal的功能,非常适合前端开发。但是,功能强大的webstorm太过于笨重,每次打开的时候都要等一会儿,占用内存太高,同时开启两个项目的时候,电脑就会特别卡,非常影响写代码的心情,而且,webstorm是收费软件,用了一段时间之后果断放弃。 这时,我尝试了一款觊觎已久的酷炫编辑器 Atom。用了Atom之后,我才知道了什么叫酷炫!Sublime算什么,我再也不要用那个丑丑的Sublime了。基于Electron(最初以Atom Shell知名)和许可使用Chromium和Node.js的跨平台应用框架,并使用CoffeeScript和Less编写。Atom不但酷炫而且强大,因为有着活跃的社区,所以插件非常多,除了满足开发的刚需之外,还有很多想都想不到的插件。但是但是,美中不足的是Atom太卡了,而且用的时候偶尔还会崩溃。坚持用了一个月,最后实在受不了,我又换回Sublime了,但是心中很不甘啊! 当时我就想着,如果有一款编辑器可以像Sublime一样流程同时又像Atom一样酷炫该有多好。于是,我遇到了VS Code。VS Code刚刚发布Beta版时我尝试着用过一次,当时还不稳定,社区也不完善,插件更是贫乏,所以没留下好印象。这次重新尝试,是因为听说它和Atom一样,也是通过Electron编写的,我想,至少可以像Atom一样酷炫吧。试用之后才发现,原来这才是我一直苦苦寻找的理想编辑器呀! 特性我强烈推荐VS Code的原因是它有以下几大特点: 酷炫 和Atom一样采用Electron框架编写,整个软件其实就是一个WebAPP,样式深度定制,酷炫到超乎你想象。如果觉得还不过瘾,可以自己编写theme插件,满足你的各种癖好。 轻量 虽然同样是采用Electron框架编写,但是VS Code和Atom走了不同的路线。Atom从一开始就把插件化架构摆在第一位,所以,Atom中最重要的是灵活而又完备的API,性能则不那么重要。VS Code则是把用户体验放在第一位,高性能、更能丰富才是它的首要目的,所以,一开始VS Code的插件系统很糟糕。但是VS Code的性能绝对高出Atom一个档位。 开源 继承了Electron的良好基因。 跨平台 依然是继承了Electron的良好基因。 丰富的插件 虽然不如Sublime和Atom数量多,但现在已经有越来越多的插件涌入。 活跃的社区 得益于Electron和Atom,VS Code的社区也是非常的活跃,更加快了插件生态的繁荣。 自带功能EmmetVS Code不需要安装插件,自身就实现了Emmet,默认就是打开的。 智能感知VS Code本身自带JS代码提示和自动补全功能,当然,如果你觉得不够用,还可以安装各种intelligence或者snippets插件来满足需求。 Format Document对于压缩的代码,或者格式不够规范的代码文件,可以通过这个命令一键格式化代码。当然,这个功能是每个编辑器应该都有的,并不是亮点。 Auto Save自动保存功能也是大部分优秀的编辑器应该必备的。我认为VS Code里做的比较人性化的一个点是,它的设置选项里提供了四种自动保存的时机供我们选择:off、afterDelay、onFocusChange(编辑器失去焦点)、onWindowChange(窗口失去焦点)。如果设置为afterDelay,则可在 files.autoSaveDelay 中配置延迟。我比较喜欢onWindowChange。 TerminalVS Code自带打开Terminal的功能,这是Atom和Sublime所不具备的。这也算是VS Code的一大亮点。 插件推荐接下来,推荐一些我用到过的非常实用的插件,帮助你编程时候事半功倍! Git History 可以查看一个文件的所有提交记录,同时还可以调出一个可视化的界面展示文件的提交记录,是git log的强化版。还可以查看某一行的所有提交记录。 Git Peoject Manager这是一个git项目管理的插件,一共就4个命令: **GPM: Open Git Project (Ctrl+Alt+P)**:打开git项目 GPM: Refresh Projects:刷新git项目 GPM: Refresh specific project folder:刷新特定路径下的git项目 **GPM: Open Recent Git Project (Ctrl+Shift+Q)**:最近打开的git项目列表 插件的使用也很简单,找到配置文件中gitProjectManager.baseProjectsFolders把git项目的根目录放进去,就像下边这样:{ "gitProjectManager.baseProjectsFolders": [ "/home/user/nodeProjects", "/home/user/personal/pocs" ] } 然后cmd + shift + P调出命令栏,并输入GPM,上述的4个命令就被列出来了,选择Refresh Projects,稍等一会儿后,被我们添加到配置文件里的路径下的所有git项目都会被列出来。选择你的工作目录开始Coding吧! Git Lens这是一款非常强大的git插件,它提供的每一个功能,都戳中了我们日常开发中的需求痛点。所以,我强烈推荐大家安装并使用这款插件。先目睹一下它的功能概览gif图: Code Lens在文件的顶部展示代码变更的总的记录,包括左边的最新修改记录以及右边的所有的修改作者数量。 Blame Annotations点击右边的作者数量可以进入整个文件的Blame Annotations。这里展示了每一行的最后一条修改记录,具体的展示方式可以在设置里自己配置,包括作者、时间和commit信息。 Status Bar Blame这个是指在状态栏里展示当前光标所在行的Git Blame信息。当然这里要展示的信息和格式也是可以配置的。这样,光标所在的行的最新git记录和作者信息完全展示在了状态栏里。 Interactive Blame这个功能和Status Bar Status类似,只不过,git信息是直接展示在文件中的代码后边。鼠标悬停在git记录上时,会有更详细的git变更气泡弹出。就像下边这样: Quick Menu快捷键shift + alt + H调出branch history quick pick menu, 这个菜单功能非常强大,我们可以查看之前的commits信息、所有commits信息、根据message/author/filename搜索commits信息、查看一些文件的历史记录等。 通过message查找时,直接在输入框里输入message的关键信息即可。通过author查找时,则是输入@author,类似于图中的@Zeke。而通过filename查找,则需要注意一下,这里应该是: filepath,也就是相对于当前项目根目录的相对路径。类似于图中的:lib/browser/chrome-extension.js。除了这些之外,还可以根据commit id查找,这个用的不多,这里就不再举例了。 Project Manager项目管理插件,这个功能和Git Project Manager有点类似,只不过,这个不但能管理git项目,还可以管理其他项目。 这个插件一共5个命令: Project Manager: Edit Project Edit 跳转到配置文件 projects.json 进行项目列表目录的配置修改。 Project Manager: List Projects 列出已经保存的项目列表。 Project Manager: List Projects to Open in New Window 列出已保存的项目列表并在新窗口打开选中的项目。 Project Manager: Refresh Projects 刷新项目列表。 Project Manager: Save Project 保存当前项目到项目列表。 其他插件其他的一些插件就不做详细介绍了,这里列出我用过的感觉比较好的,大家自己到github上查阅吧。vscode-icons、vscode-fileheader、Document This、CSS Peek、File Peek、Markdown PDF、Markdown Preview Enhanced、Regex Railroad Diagrams。 如果还有其他比较好用或者有意思的插件,欢迎大家前来留言。一起讨论交流。","categories":[{"name":"Tech","slug":"Tech","permalink":"https://maple-yf.github.io/categories/Tech/"}],"tags":[{"name":"VS Code","slug":"VS-Code","permalink":"https://maple-yf.github.io/tags/VS-Code/"}]},{"title":"南湖向晚","slug":"2017-07-09-south-lake-at-dusk","date":"2017-07-08T16:00:00.000Z","updated":"2022-05-01T06:29:33.324Z","comments":true,"path":"2017/07/09/2017-07-09-south-lake-at-dusk/","link":"","permalink":"https://maple-yf.github.io/2017/07/09/2017-07-09-south-lake-at-dusk/","excerpt":"","text":"没有偶遇记忆中雨后的彩虹 这里清清静静悄悄依旧 于是 晚霞偷偷染红了半边天空 故地重游的喜悦 总伴着物是人非的惆怅 回忆也显得那么美那么伤 那么无可奈何的凄凉 每一次心心念念的感慨 都装入成长路上破旧的行囊 变与不变的留恋 都化作或甜或苦的记忆珍藏 再次回归的少年依旧 因为我从未离开不曾遗忘","categories":[{"name":"Poetry","slug":"Poetry","permalink":"https://maple-yf.github.io/categories/Poetry/"}],"tags":[{"name":"Poetry","slug":"Poetry","permalink":"https://maple-yf.github.io/tags/Poetry/"}]},{"title":"趁黄昏","slug":"2017-05-08-dusk","date":"2017-05-07T16:00:00.000Z","updated":"2022-05-01T06:29:58.838Z","comments":true,"path":"2017/05/08/2017-05-08-dusk/","link":"","permalink":"https://maple-yf.github.io/2017/05/08/2017-05-08-dusk/","excerpt":"","text":"十里春风独爱这柳树的枝头 趁黄昏,走一走 晚风亲吻着温柔 一次日落偏好那静静的巷口 趁黄昏,等一等 夕阳西下的守候","categories":[{"name":"Poetry","slug":"Poetry","permalink":"https://maple-yf.github.io/categories/Poetry/"}],"tags":[{"name":"Poetry","slug":"Poetry","permalink":"https://maple-yf.github.io/tags/Poetry/"}]},{"title":"吹雪","slug":"2017-02-07-snow","date":"2017-02-06T16:00:00.000Z","updated":"2022-05-01T06:30:02.330Z","comments":true,"path":"2017/02/07/2017-02-07-snow/","link":"","permalink":"https://maple-yf.github.io/2017/02/07/2017-02-07-snow/","excerpt":"","text":"我经历了一次美丽的邂逅 是这突如其来的吹雪 轻轻吻向泥土的等候 洁白在灯光交汇下漫天轻柔 伴着人们心满意足的步调 目睹了一对对静静地走到白头","categories":[{"name":"Poetry","slug":"Poetry","permalink":"https://maple-yf.github.io/categories/Poetry/"}],"tags":[{"name":"Poetry","slug":"Poetry","permalink":"https://maple-yf.github.io/tags/Poetry/"}]},{"title":"不得不说再见","slug":"2016-06-25-say-goodbye","date":"2016-06-24T16:00:00.000Z","updated":"2022-05-01T06:30:06.547Z","comments":true,"path":"2016/06/25/2016-06-25-say-goodbye/","link":"","permalink":"https://maple-yf.github.io/2016/06/25/2016-06-25-say-goodbye/","excerpt":"","text":"终于这宴席还是要散场 请不要为我鼓掌 也不要欢送 潺潺的流水在为我歌唱 盛放的蔷薇散发着芬芳 河边的杨柳也在轻轻地飘荡 夏天总因离别变得黯然惆怅 还想再听一听丰富多彩的课堂 还想再逛一逛青春洋溢的操场 还想再聊一聊槽点满满的旧日时光 还想,还想…… 别了校园,别了矿大 别了那逝去的青春模样 南湖上升起的月光 请替我守护这片温馨的土壤 我在下一个路口等待 青春不散场","categories":[{"name":"Poetry","slug":"Poetry","permalink":"https://maple-yf.github.io/categories/Poetry/"}],"tags":[{"name":"Poetry","slug":"Poetry","permalink":"https://maple-yf.github.io/tags/Poetry/"}]},{"title":"安装静态博客Jekyll","slug":"2016-04-29-jekyll-install","date":"2016-04-28T16:00:00.000Z","updated":"2020-12-21T15:44:10.049Z","comments":true,"path":"2016/04/29/2016-04-29-jekyll-install/","link":"","permalink":"https://maple-yf.github.io/2016/04/29/2016-04-29-jekyll-install/","excerpt":"Jekyll是一种纯文本的静态博客,安装成功之后,直接通过markdown文本就可以更新博客内容。Jekyll的安装过程比较简单,但是安装的过程中仍然会跳进很多坑。Jekyll和Github Pages是一种很好的结合。Github Pages是github提供的一个可以免费部署个人网站且没有存储上限的一个功能。在Jekyll的官网里也有把Jekyll部署到Github Pages上的教程。 安装Jekyll如果需要部署到Github Pages,Jekyll需要在本地完成安装,然后再进行部署。Jekyll的安装智能在Linux和Mac OS X上进行,另外,其依赖Ruby和RubyGems,建议安装rvm来控制Ruby的版本。Linux和Mac OS X一般都会有系统自带的Ruby,但是版本比较旧,通过 ruby -v","text":"Jekyll是一种纯文本的静态博客,安装成功之后,直接通过markdown文本就可以更新博客内容。Jekyll的安装过程比较简单,但是安装的过程中仍然会跳进很多坑。Jekyll和Github Pages是一种很好的结合。Github Pages是github提供的一个可以免费部署个人网站且没有存储上限的一个功能。在Jekyll的官网里也有把Jekyll部署到Github Pages上的教程。 安装Jekyll如果需要部署到Github Pages,Jekyll需要在本地完成安装,然后再进行部署。Jekyll的安装智能在Linux和Mac OS X上进行,另外,其依赖Ruby和RubyGems,建议安装rvm来控制Ruby的版本。Linux和Mac OS X一般都会有系统自带的Ruby,但是版本比较旧,通过 ruby -v 可以查看当前Ruby的版本。当前Github Pages支持的是Jekyll 3.0,其依赖的Ruby 2.0及其以上版本,所以建议安装Ruby 2.0或其以上版本。本次安装,我是直接从github上找了一个别人做好的带主题的Jekyll,然后安装在自己的VPS上了,这个Jekyll Theme的名字叫做Personal,把它git到我vps上之后,通过一个命令就可以安装完成: ./scripts/install 它对Ruby的需求是2.0及其以上版本,否则会安装失败。 配置安装成功之后,需要对_config.yml文件进行一些个性配置。具体配置可以参考项目中的教程。主要的配置有以下几个: url:这个是用来指向自己的域名(如果你有的话),配置到Github Pages上并指向自己的域名或者二级域名可以参考github官方教程 baseurl:用来设置自己网站的相对根目录,我设置的是空,因为在我的Github Pages中的这个项目是直接放在根目录下的 force-https:这个配置是原版Jekyll没有的,这里建议设置为false,因为Github Pages目前既支持http也支持https,如果自己没有https的证书的话,还是把其关闭的好 其余的配置都可以参考personal项目中的教程。 部署配置完成之后,就可以部署到Github Pages中了,我直接把安装好的整个文件夹push到了github中。在push之前,需要先创建自己的Github Pages,每一个github用户只能创建一个Github Pages,这里是官方创建教程。创建完成之后,把自己的文件push到根目录下,就可以通过 http://gitusername.github.io 访问了,如果设置了个人的域名,则需要到自己的域名管理网站更新域名指向,把设置的域名指向 http://gitusername.github.io 即可。需要注意的是,把自己的项目文件push到github之后,也许并不能立刻就访问到网页,也许是因为github内部需要一段时间的部署。我当时部署到github之后,立刻访问得到的是404页面,刚开始以为是自己配置出错了,过滤几个小时之后,再次访问,页面才第一次呈现。","categories":[{"name":"Tech","slug":"Tech","permalink":"https://maple-yf.github.io/categories/Tech/"}],"tags":[{"name":"Jekyll","slug":"Jekyll","permalink":"https://maple-yf.github.io/tags/Jekyll/"}]},{"title":"Ubuntu用户设置","slug":"2015-12-01-Setting-Ubuntu-User","date":"2015-12-01T04:00:00.000Z","updated":"2020-12-21T15:44:10.049Z","comments":true,"path":"2015/12/01/2015-12-01-Setting-Ubuntu-User/","link":"","permalink":"https://maple-yf.github.io/2015/12/01/2015-12-01-Setting-Ubuntu-User/","excerpt":"最近在安装实验室一台服务器,系统装的是Ubuntu 14.04,今天在添加用户的时候出了点小问题,在这里总结一下。 为Ubuntu添加新用户在网上查到为Ubuntu填加新用户的方式是 sudo useradd me和passwd me来设置,但是,这样设置有一个很大的坑,因为这样设置的用户信息是不全的,直接导致使用这种方式设置的用户在进行远程登陆的时候,会出现 Could not chdir to home directory /home/me: No such file or directory 的错误,可以用过输入 bash 来进入正常的状态 $ bash me@server:/$","text":"最近在安装实验室一台服务器,系统装的是Ubuntu 14.04,今天在添加用户的时候出了点小问题,在这里总结一下。 为Ubuntu添加新用户在网上查到为Ubuntu填加新用户的方式是 sudo useradd me和passwd me来设置,但是,这样设置有一个很大的坑,因为这样设置的用户信息是不全的,直接导致使用这种方式设置的用户在进行远程登陆的时候,会出现 Could not chdir to home directory /home/me: No such file or directory 的错误,可以用过输入 bash 来进入正常的状态 $ bash me@server:/$ 为了解决这个问题,其实就是修改用户的默认shell为bash。去Google了一番,终于找到解决方案:http://askubuntu.com/questions/28969/how-do-you-change-the-default-shell-for-all-users-to-bash。方法就是,如果是root用户: usermod -s /bin/bash USERNAME 如果不是root用户: sudo -u USERNAME chsh -s /bin/bash 走过这个坑之后,建议以后添加用户,换成另外一种方式, sudo adduser me,这样虽然麻烦一些,但是权限和信息都是更加完整的。 为用户添加root权限为了能使用root权限,又去搜索了一遍如何为用户添加root权限,这里有一篇文章讲解的很详细http://blog.csdn.net/dreamback1987/article/details/8766302。这里的关键点就是在修改 /etc/sudoers文件前,需要修改它的权限,改完保存之后,再把文件权限修改回来,因为如果 /etc/sudoers 文件的权限为 777 的话,sudo命令就不能使用了。 root用户和普通用户来回切换因为本人菜鸟一枚,这里记录一下刚刚学到的一个小命令,就是root用户和普通用户的来回切换: $su root #切换到root用户 $su me #切换到me用户","categories":[{"name":"Tech","slug":"Tech","permalink":"https://maple-yf.github.io/categories/Tech/"}],"tags":[{"name":"Ubuntu","slug":"Ubuntu","permalink":"https://maple-yf.github.io/tags/Ubuntu/"}]},{"title":"安装 ShadowScoks","slug":"2015-11-12-shadowsocks","date":"2015-11-12T07:30:00.000Z","updated":"2022-04-09T08:18:41.323Z","comments":true,"path":"2015/11/12/2015-11-12-shadowsocks/","link":"","permalink":"https://maple-yf.github.io/2015/11/12/2015-11-12-shadowsocks/","excerpt":"ShadowScoks是一个非常易用的翻墙工具,把它安装在自己的VPS上,就可以随心所欲的上网啦! 安装输入su进入root。分别复制以下命令到命令行: wget --no-check-certificate https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks.sh chmod +x shadowsocks.sh ./shadowsocks.sh 2>&1 | tee shadowsocks.log","text":"ShadowScoks是一个非常易用的翻墙工具,把它安装在自己的VPS上,就可以随心所欲的上网啦! 安装输入su进入root。分别复制以下命令到命令行: wget --no-check-certificate https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks.sh chmod +x shadowsocks.sh ./shadowsocks.sh 2>&1 | tee shadowsocks.log 执行最后一条命令之后,出现一下界面: 输入密码即可。并回车,再次回车,确认安装。 安装失败,出现错误提示: ./shadowsocks.sh: line 111: 6396 Segmentation fault (core dumped) apt-get -y update Reading package lists..../shadowsocks.sh: line 111: 6461 Segmentation fault (core dumped) apt-get -y install python python-dev python-pip curl wget unzip gcc swig automake make perl cpio 分别执行 (core dumped)后面的语句 apt-get -y update apt-get -y install python python-dev python-pip curl wget unzip gcc swig automake make perl cpio 然后,重新执行: ./shadowsocks.sh 2>&1 | tee shadowsocks.log 等待5分钟左右,即可安装成功,安装成功之后就会通过屏幕输出,您的IP地址,端口,密码,及加密方式。 如果您想多用户使用,请配置 /etc/shadowsocks.json 这个文件。配置模版: { "server":"your_server_ip", "local_address": "127.0.0.1", "local_port":1080, "port_password":{ "8989":"password0", "9001":"password1", "9002":"password2", "9003":"password3", "9004":"password4" }, "timeout":300, "method":"aes-256-cfb", "fast_open": false } Windows客户端下载地址:https://shadowsocks.org/en/download/clients.html使用教程:http://wiki.ssnode.co/index.php?option=com_content&view=article&id=4:about-your-home-page&catid=9&Itemid=101使用shadowsocks时,必须要通过SSH连接上自己的VPS后才能代理成功。","categories":[{"name":"Tech","slug":"Tech","permalink":"https://maple-yf.github.io/categories/Tech/"}],"tags":[{"name":"ShadowSocks","slug":"ShadowSocks","permalink":"https://maple-yf.github.io/tags/ShadowSocks/"}]},{"title":"win10右键反应缓慢","slug":"2015-11-07-win10-menucontext","date":"2015-11-07T03:00:00.000Z","updated":"2020-12-21T15:44:10.049Z","comments":true,"path":"2015/11/07/2015-11-07-win10-menucontext/","link":"","permalink":"https://maple-yf.github.io/2015/11/07/2015-11-07-win10-menucontext/","excerpt":"","text":"最近装了win10,但是有一个小问题,右击电脑空白处想刷新的时候,反应特别慢,因为系统是安装在固态硬盘上的,所以不应该出现这种问题,于是网上搜罗了一些解决方法。 解决方案开始,运行:regedit,打开注册表 HKEY_CLASSES_ROOT/Directory/Background/shellex/ContextMenuHandlers 删除下面两个选项就可以了:一个是 igfxcui ,另外一个是NvCplDesktopContext如果只有一项就单独删除,如果两项都有就全部删除。","categories":[{"name":"Tech","slug":"Tech","permalink":"https://maple-yf.github.io/categories/Tech/"}],"tags":[{"name":"Windows","slug":"Windows","permalink":"https://maple-yf.github.io/tags/Windows/"}]},{"title":"为笔记本(华硕A46C)更换SSD全过程","slug":"2015-09-29-replacement-of-SSD","date":"2015-09-29T03:23:32.000Z","updated":"2022-04-09T05:36:12.906Z","comments":true,"path":"2015/09/29/2015-09-29-replacement-of-SSD/","link":"","permalink":"https://maple-yf.github.io/2015/09/29/2015-09-29-replacement-of-SSD/","excerpt":"前两天给自己的笔记本换了个SSD。我的笔记本是华硕A46C,2013年买的,属于超薄本。当时买的时候选的是无光驱版,因此光驱位就是一个空盒子。下图中左边的就是光驱位的空盒子。在换SSD的时候,需要买一个和这个盒子差不多形状的硬盘盒装上。我是把原来的机械硬盘放到了光驱位,然后把SSD放到了原来的机械硬盘(主硬盘)的位置,据说是主硬盘的位置能够提供更高的读取速度,我没有去查华硕这个系列的光驱位提供的接口,但是主硬盘的读取速度肯定不会低于光驱位,所以就这么换了,虽然麻烦了一些。","text":"前两天给自己的笔记本换了个SSD。我的笔记本是华硕A46C,2013年买的,属于超薄本。当时买的时候选的是无光驱版,因此光驱位就是一个空盒子。下图中左边的就是光驱位的空盒子。在换SSD的时候,需要买一个和这个盒子差不多形状的硬盘盒装上。我是把原来的机械硬盘放到了光驱位,然后把SSD放到了原来的机械硬盘(主硬盘)的位置,据说是主硬盘的位置能够提供更高的读取速度,我没有去查华硕这个系列的光驱位提供的接口,但是主硬盘的读取速度肯定不会低于光驱位,所以就这么换了,虽然麻烦了一些。 因为一般的光驱位硬盘盒和华硕的这个系列笔记本的边缘不太一致,导致装进去之后会凹进去一块,很难看。但是在淘宝上搜华硕A46硬盘架根本找不到,后来在网上看到有别人的更换教程,发现华硕的X450、X550系列的硬盘架能够完美适配华硕A46系列。 拆机过程如下:首先按照下图的方向把后盖拆掉 露出主硬盘 我买的这款三星250G SSD 感觉还是不错的,手机上买的589元。在天猫上买的,第一次发货之后,两三天没有更新快递信息,感觉是中通快递给弄丢了,卖家联系快递也没有消息,不过老板还是比较有业界良心的,直接重新发了一款并更换了快递。 看一下机械硬盘和固态硬盘的对比照,此时固态硬盘已经装在了主硬盘的外壳里了。 下图是装上硬盘托架之后的光驱位外边缘,这个硬盘托架还是比较合适的,就是有点贵。SSD装好之后,在里边装了win10,但是在win10里总是找不到原来的机械硬盘。进到UEFI里边是能看到的,说明硬盘托架的接口没问题,后来我尝试从机械硬盘启动,发现可以正常使用,而且在原来的系统里也能看到SSD的盘符。然后我又切回到SSD启动,机械硬盘居然神奇的出现了,并且一切使用都是正常的,我也不知道为什么,总之,这次的SSD更换也算是成功了!","categories":[{"name":"Tech","slug":"Tech","permalink":"https://maple-yf.github.io/categories/Tech/"}],"tags":[{"name":"SSD","slug":"SSD","permalink":"https://maple-yf.github.io/tags/SSD/"}]}],"categories":[{"name":"Tech","slug":"Tech","permalink":"https://maple-yf.github.io/categories/Tech/"},{"name":"Poetry","slug":"Poetry","permalink":"https://maple-yf.github.io/categories/Poetry/"}],"tags":[{"name":"IT","slug":"IT","permalink":"https://maple-yf.github.io/tags/IT/"},{"name":"Auto Test","slug":"Auto-Test","permalink":"https://maple-yf.github.io/tags/Auto-Test/"},{"name":"Poetry","slug":"Poetry","permalink":"https://maple-yf.github.io/tags/Poetry/"},{"name":"Webpack","slug":"Webpack","permalink":"https://maple-yf.github.io/tags/Webpack/"},{"name":"UML","slug":"UML","permalink":"https://maple-yf.github.io/tags/UML/"},{"name":"VS Code","slug":"VS-Code","permalink":"https://maple-yf.github.io/tags/VS-Code/"},{"name":"Jekyll","slug":"Jekyll","permalink":"https://maple-yf.github.io/tags/Jekyll/"},{"name":"Ubuntu","slug":"Ubuntu","permalink":"https://maple-yf.github.io/tags/Ubuntu/"},{"name":"ShadowSocks","slug":"ShadowSocks","permalink":"https://maple-yf.github.io/tags/ShadowSocks/"},{"name":"Windows","slug":"Windows","permalink":"https://maple-yf.github.io/tags/Windows/"},{"name":"SSD","slug":"SSD","permalink":"https://maple-yf.github.io/tags/SSD/"}]} \ No newline at end of file diff --git a/css/index.css b/css/index.css new file mode 100644 index 000000000..62b8d5521 --- /dev/null +++ b/css/index.css @@ -0,0 +1,6134 @@ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ +html { + line-height: 1.15; + -webkit-text-size-adjust: 100% +} + +body { + margin: 0 +} + +main { + display: block +} + +h1 { + font-size: 2em; + margin: .67em 0 +} + +hr { + box-sizing: content-box; + height: 0; + overflow: visible +} + +pre { + font-family: monospace, monospace; + font-size: 1em +} + +a { + background-color: transparent +} + +abbr[title] { + border-bottom: none; + text-decoration: underline; + text-decoration: underline dotted +} + +b, +strong { + font-weight: bolder +} + +code, +kbd, +samp { + font-family: monospace, monospace; + font-size: 1em +} + +small { + font-size: 80% +} + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline +} + +sub { + bottom: -.25em +} + +sup { + top: -.5em +} + +img { + border-style: none +} + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; + font-size: 100%; + line-height: 1.15; + margin: 0 +} + +button, +input { + overflow: visible +} + +button, +select { + text-transform: none +} + +[type=button], +[type=reset], +[type=submit], +button { + -webkit-appearance: button +} + +[type=button]::-moz-focus-inner, +[type=reset]::-moz-focus-inner, +[type=submit]::-moz-focus-inner, +button::-moz-focus-inner { + border-style: none; + padding: 0 +} + +[type=button]:-moz-focusring, +[type=reset]:-moz-focusring, +[type=submit]:-moz-focusring, +button:-moz-focusring { + outline: 1px dotted ButtonText +} + +fieldset { + padding: .35em .75em .625em +} + +legend { + box-sizing: border-box; + color: inherit; + display: table; + max-width: 100%; + padding: 0; + white-space: normal +} + +progress { + vertical-align: baseline +} + +textarea { + overflow: auto +} + +[type=checkbox], +[type=radio] { + box-sizing: border-box; + padding: 0 +} + +[type=number]::-webkit-inner-spin-button, +[type=number]::-webkit-outer-spin-button { + height: auto +} + +[type=search] { + -webkit-appearance: textfield; + outline-offset: -2px +} + +[type=search]::-webkit-search-decoration { + -webkit-appearance: none +} + +::-webkit-file-upload-button { + -webkit-appearance: button; + font: inherit +} + +details { + display: block +} + +summary { + display: list-item +} + +template { + display: none +} + +[hidden] { + display: none +} +.limit-one-line, +#article-container .flink .flink-item-name, +#article-container .flink .flink-item-desc, +#aside-content .card-archives ul.card-archive-list > .card-archive-list-item a span, +#aside-content .card-categories ul.card-category-list > .card-category-list-item a span, +.site-data > a .headline, +#nav #blog-info, +#pagination .prev_info, +#pagination .next_info, +#sidebar #sidebar-menus .menus_items .site-page { + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + white-space: nowrap; +} +.limit-more-line, +.article-sort-item-title, +#recent-posts > .recent-post-item >.recent-post-info > .article-title, +#recent-posts > .recent-post-item >.recent-post-info > .content, +#aside-content .aside-list > .aside-list-item .content > .name, +#aside-content .aside-list > .aside-list-item .content > .title, +#aside-content .aside-list > .aside-list-item .content > .comment, +#post-info .post-title, +.relatedPosts > .relatedPosts-list .content .title, +#article-container figure.gallery-group p, +#article-container figure.gallery-group .gallery-group-name { + display: -webkit-box; + overflow: hidden; + -webkit-box-orient: vertical; +} +.fontawesomeIcon, +.custom-hr:before, +#post .post-copyright:before, +#post .post-outdate-notice:before, +.note:not(.no-icon)::before, +.search-dialog hr:before { + display: inline-block; + font-weight: 600; + font-family: 'Font Awesome 6 Free'; + text-rendering: auto; + -webkit-font-smoothing: antialiased; +} +.cardHover, +.layout > div:first-child:not(.recent-posts), +#recent-posts > .recent-post-item, +#aside-content .card-widget, +.layout > .recent-posts .pagination > *:not(.space) { + border-radius: 8px; + background: var(--card-bg); + -webkit-box-shadow: var(--card-box-shadow); + box-shadow: var(--card-box-shadow); + -webkit-transition: all 0.3s; + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -ms-transition: all 0.3s; + transition: all 0.3s; +} +.cardHover:hover, +.layout > div:first-child:not(.recent-posts):hover, +#recent-posts > .recent-post-item:hover, +#aside-content .card-widget:hover, +.layout > .recent-posts .pagination > *:not(.space):hover { + -webkit-box-shadow: var(--card-hover-box-shadow); + box-shadow: var(--card-hover-box-shadow); +} +.imgHover, +.article-sort-item-img :first-child, +#recent-posts > .recent-post-item .post_cover .post-bg, +#aside-content .aside-list > .aside-list-item .thumbnail :first-child { + width: 100%; + height: 100%; + -webkit-transition: filter 375ms ease-in 0.2s, -webkit-transform 0.6s; + -moz-transition: filter 375ms ease-in 0.2s, -moz-transform 0.6s; + -o-transition: filter 375ms ease-in 0.2s, -o-transform 0.6s; + -ms-transition: filter 375ms ease-in 0.2s, -ms-transform 0.6s; + transition: filter 375ms ease-in 0.2s, transform 0.6s; + object-fit: cover; +} +.imgHover:hover, +.article-sort-item-img :first-child:hover, +#recent-posts > .recent-post-item .post_cover .post-bg:hover, +#aside-content .aside-list > .aside-list-item .thumbnail :first-child:hover { + -webkit-transform: scale(1.1); + -moz-transform: scale(1.1); + -o-transform: scale(1.1); + -ms-transform: scale(1.1); + transform: scale(1.1); +} +.postImgHover:hover .cover, +#pagination .prev-post:hover .cover, +#pagination .next-post:hover .cover, +.relatedPosts > .relatedPosts-list > div:hover .cover { + opacity: 0.8; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)"; + filter: alpha(opacity=80); + -webkit-transform: scale(1.1); + -moz-transform: scale(1.1); + -o-transform: scale(1.1); + -ms-transform: scale(1.1); + transform: scale(1.1); +} +.postImgHover .cover, +#pagination .prev-post .cover, +#pagination .next-post .cover, +.relatedPosts > .relatedPosts-list > div .cover { + position: absolute; + width: 100%; + height: 100%; + opacity: 0.4; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)"; + filter: alpha(opacity=40); + -webkit-transition: all 0.6s, filter 375ms ease-in 0.2s; + -moz-transition: all 0.6s, filter 375ms ease-in 0.2s; + -o-transition: all 0.6s, filter 375ms ease-in 0.2s; + -ms-transition: all 0.6s, filter 375ms ease-in 0.2s; + transition: all 0.6s, filter 375ms ease-in 0.2s; + object-fit: cover; +} +.list-beauty, +.category-lists ul { + list-style: none; +} +.list-beauty li, +.category-lists ul li { + position: relative; + padding: 0.12em 0.4em 0.12em 1.4em; +} +.list-beauty li:hover:before, +.category-lists ul li:hover:before { + border-color: var(--pseudo-hover); +} +.list-beauty li:before, +.category-lists ul li:before { + position: absolute; + top: 0.67em; + left: 0; + width: 0.43em; + height: 0.43em; + border: 0.215em solid #49b1f5; + border-radius: 0.43em; + background: transparent; + content: ''; + cursor: pointer; + -webkit-transition: all 0.3s ease-out; + -moz-transition: all 0.3s ease-out; + -o-transition: all 0.3s ease-out; + -ms-transition: all 0.3s ease-out; + transition: all 0.3s ease-out; +} +.custom-hr, +.search-dialog hr { + position: relative; + margin: 40px auto; + border: 2px dashed var(--hr-border); + width: calc(100% - 4px); +} +.custom-hr:hover:before, +.search-dialog hr:hover:before { + left: calc(95% - 20px); +} +.custom-hr:before, +.search-dialog hr:before { + position: absolute; + top: -10px; + left: 5%; + z-index: 1; + color: var(--hr-before-color); + content: '\f0c4'; + font-size: 20px; + line-height: 1; + -webkit-transition: all 1s ease-in-out; + -moz-transition: all 1s ease-in-out; + -o-transition: all 1s ease-in-out; + -ms-transition: all 1s ease-in-out; + transition: all 1s ease-in-out; +} +#content-inner, +#footer { + -webkit-animation: bottom-top 1s; + -moz-animation: bottom-top 1s; + -o-animation: bottom-top 1s; + -ms-animation: bottom-top 1s; + animation: bottom-top 1s; +} +#page-header:not(.full_page) { + -webkit-animation: header-effect 1s; + -moz-animation: header-effect 1s; + -o-animation: header-effect 1s; + -ms-animation: header-effect 1s; + animation: header-effect 1s; +} +#site-title, +#site-subtitle { + -webkit-animation: titleScale 1s; + -moz-animation: titleScale 1s; + -o-animation: titleScale 1s; + -ms-animation: titleScale 1s; + animation: titleScale 1s; +} +#nav.show { + -webkit-animation: headerNoOpacity 1s; + -moz-animation: headerNoOpacity 1s; + -o-animation: headerNoOpacity 1s; + -ms-animation: headerNoOpacity 1s; + animation: headerNoOpacity 1s; +} +canvas:not(#ribbon-canvas), +#web_bg { + -webkit-animation: to_show 4s; + -moz-animation: to_show 4s; + -o-animation: to_show 4s; + -ms-animation: to_show 4s; + animation: to_show 4s; +} +#ribbon-canvas { + -webkit-animation: ribbon_to_show 4s; + -moz-animation: ribbon_to_show 4s; + -o-animation: ribbon_to_show 4s; + -ms-animation: ribbon_to_show 4s; + animation: ribbon_to_show 4s; +} +#sidebar-menus.open > :nth-child(1) { + -webkit-animation: sidebarItem 0.2s; + -moz-animation: sidebarItem 0.2s; + -o-animation: sidebarItem 0.2s; + -ms-animation: sidebarItem 0.2s; + animation: sidebarItem 0.2s; +} +#sidebar-menus.open > :nth-child(2) { + -webkit-animation: sidebarItem 0.4s; + -moz-animation: sidebarItem 0.4s; + -o-animation: sidebarItem 0.4s; + -ms-animation: sidebarItem 0.4s; + animation: sidebarItem 0.4s; +} +#sidebar-menus.open > :nth-child(3) { + -webkit-animation: sidebarItem 0.6s; + -moz-animation: sidebarItem 0.6s; + -o-animation: sidebarItem 0.6s; + -ms-animation: sidebarItem 0.6s; + animation: sidebarItem 0.6s; +} +#sidebar-menus.open > :nth-child(4) { + -webkit-animation: sidebarItem 0.8s; + -moz-animation: sidebarItem 0.8s; + -o-animation: sidebarItem 0.8s; + -ms-animation: sidebarItem 0.8s; + animation: sidebarItem 0.8s; +} +.scroll-down-effects { + -webkit-animation: scroll-down-effect 1.5s infinite; + -moz-animation: scroll-down-effect 1.5s infinite; + -o-animation: scroll-down-effect 1.5s infinite; + -ms-animation: scroll-down-effect 1.5s infinite; + animation: scroll-down-effect 1.5s infinite; +} +.reward-main { + -webkit-animation: donate_effcet 0.3s 0.1s ease both; + -moz-animation: donate_effcet 0.3s 0.1s ease both; + -o-animation: donate_effcet 0.3s 0.1s ease both; + -ms-animation: donate_effcet 0.3s 0.1s ease both; + animation: donate_effcet 0.3s 0.1s ease both; +} +@-moz-keyframes scroll-down-effect { + 0% { + opacity: 0.4; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)"; + filter: alpha(opacity=40); + -webkit-transform: translate(0, 0); + -moz-transform: translate(0, 0); + -o-transform: translate(0, 0); + -ms-transform: translate(0, 0); + transform: translate(0, 0); + } + 50% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: translate(0, -16px); + -moz-transform: translate(0, -16px); + -o-transform: translate(0, -16px); + -ms-transform: translate(0, -16px); + transform: translate(0, -16px); + } + 100% { + opacity: 0.4; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)"; + filter: alpha(opacity=40); + -webkit-transform: translate(0, 0); + -moz-transform: translate(0, 0); + -o-transform: translate(0, 0); + -ms-transform: translate(0, 0); + transform: translate(0, 0); + } +} +@-webkit-keyframes scroll-down-effect { + 0% { + opacity: 0.4; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)"; + filter: alpha(opacity=40); + -webkit-transform: translate(0, 0); + -moz-transform: translate(0, 0); + -o-transform: translate(0, 0); + -ms-transform: translate(0, 0); + transform: translate(0, 0); + } + 50% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: translate(0, -16px); + -moz-transform: translate(0, -16px); + -o-transform: translate(0, -16px); + -ms-transform: translate(0, -16px); + transform: translate(0, -16px); + } + 100% { + opacity: 0.4; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)"; + filter: alpha(opacity=40); + -webkit-transform: translate(0, 0); + -moz-transform: translate(0, 0); + -o-transform: translate(0, 0); + -ms-transform: translate(0, 0); + transform: translate(0, 0); + } +} +@-o-keyframes scroll-down-effect { + 0% { + opacity: 0.4; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)"; + filter: alpha(opacity=40); + -webkit-transform: translate(0, 0); + -moz-transform: translate(0, 0); + -o-transform: translate(0, 0); + -ms-transform: translate(0, 0); + transform: translate(0, 0); + } + 50% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: translate(0, -16px); + -moz-transform: translate(0, -16px); + -o-transform: translate(0, -16px); + -ms-transform: translate(0, -16px); + transform: translate(0, -16px); + } + 100% { + opacity: 0.4; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)"; + filter: alpha(opacity=40); + -webkit-transform: translate(0, 0); + -moz-transform: translate(0, 0); + -o-transform: translate(0, 0); + -ms-transform: translate(0, 0); + transform: translate(0, 0); + } +} +@keyframes scroll-down-effect { + 0% { + opacity: 0.4; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)"; + filter: alpha(opacity=40); + -webkit-transform: translate(0, 0); + -moz-transform: translate(0, 0); + -o-transform: translate(0, 0); + -ms-transform: translate(0, 0); + transform: translate(0, 0); + } + 50% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: translate(0, -16px); + -moz-transform: translate(0, -16px); + -o-transform: translate(0, -16px); + -ms-transform: translate(0, -16px); + transform: translate(0, -16px); + } + 100% { + opacity: 0.4; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)"; + filter: alpha(opacity=40); + -webkit-transform: translate(0, 0); + -moz-transform: translate(0, 0); + -o-transform: translate(0, 0); + -ms-transform: translate(0, 0); + transform: translate(0, 0); + } +} +@-moz-keyframes header-effect { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: translateY(-50px); + -moz-transform: translateY(-50px); + -o-transform: translateY(-50px); + -ms-transform: translateY(-50px); + transform: translateY(-50px); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@-webkit-keyframes header-effect { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: translateY(-50px); + -moz-transform: translateY(-50px); + -o-transform: translateY(-50px); + -ms-transform: translateY(-50px); + transform: translateY(-50px); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@-o-keyframes header-effect { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: translateY(-50px); + -moz-transform: translateY(-50px); + -o-transform: translateY(-50px); + -ms-transform: translateY(-50px); + transform: translateY(-50px); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@keyframes header-effect { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: translateY(-50px); + -moz-transform: translateY(-50px); + -o-transform: translateY(-50px); + -ms-transform: translateY(-50px); + transform: translateY(-50px); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@-moz-keyframes headerNoOpacity { + 0% { + -webkit-transform: translateY(-50px); + -moz-transform: translateY(-50px); + -o-transform: translateY(-50px); + -ms-transform: translateY(-50px); + transform: translateY(-50px); + } + 100% { + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@-webkit-keyframes headerNoOpacity { + 0% { + -webkit-transform: translateY(-50px); + -moz-transform: translateY(-50px); + -o-transform: translateY(-50px); + -ms-transform: translateY(-50px); + transform: translateY(-50px); + } + 100% { + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@-o-keyframes headerNoOpacity { + 0% { + -webkit-transform: translateY(-50px); + -moz-transform: translateY(-50px); + -o-transform: translateY(-50px); + -ms-transform: translateY(-50px); + transform: translateY(-50px); + } + 100% { + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@keyframes headerNoOpacity { + 0% { + -webkit-transform: translateY(-50px); + -moz-transform: translateY(-50px); + -o-transform: translateY(-50px); + -ms-transform: translateY(-50px); + transform: translateY(-50px); + } + 100% { + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@-moz-keyframes bottom-top { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: translateY(50px); + -moz-transform: translateY(50px); + -o-transform: translateY(50px); + -ms-transform: translateY(50px); + transform: translateY(50px); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@-webkit-keyframes bottom-top { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: translateY(50px); + -moz-transform: translateY(50px); + -o-transform: translateY(50px); + -ms-transform: translateY(50px); + transform: translateY(50px); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@-o-keyframes bottom-top { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: translateY(50px); + -moz-transform: translateY(50px); + -o-transform: translateY(50px); + -ms-transform: translateY(50px); + transform: translateY(50px); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@keyframes bottom-top { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: translateY(50px); + -moz-transform: translateY(50px); + -o-transform: translateY(50px); + -ms-transform: translateY(50px); + transform: translateY(50px); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@-moz-keyframes titleScale { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: scale(0.7); + -moz-transform: scale(0.7); + -o-transform: scale(0.7); + -ms-transform: scale(0.7); + transform: scale(0.7); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } +} +@-webkit-keyframes titleScale { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: scale(0.7); + -moz-transform: scale(0.7); + -o-transform: scale(0.7); + -ms-transform: scale(0.7); + transform: scale(0.7); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } +} +@-o-keyframes titleScale { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: scale(0.7); + -moz-transform: scale(0.7); + -o-transform: scale(0.7); + -ms-transform: scale(0.7); + transform: scale(0.7); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } +} +@keyframes titleScale { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: scale(0.7); + -moz-transform: scale(0.7); + -o-transform: scale(0.7); + -ms-transform: scale(0.7); + transform: scale(0.7); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } +} +@-moz-keyframes search_close { + 0% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } + 100% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: scale(0.7); + -moz-transform: scale(0.7); + -o-transform: scale(0.7); + -ms-transform: scale(0.7); + transform: scale(0.7); + } +} +@-webkit-keyframes search_close { + 0% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } + 100% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: scale(0.7); + -moz-transform: scale(0.7); + -o-transform: scale(0.7); + -ms-transform: scale(0.7); + transform: scale(0.7); + } +} +@-o-keyframes search_close { + 0% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } + 100% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: scale(0.7); + -moz-transform: scale(0.7); + -o-transform: scale(0.7); + -ms-transform: scale(0.7); + transform: scale(0.7); + } +} +@keyframes search_close { + 0% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } + 100% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: scale(0.7); + -moz-transform: scale(0.7); + -o-transform: scale(0.7); + -ms-transform: scale(0.7); + transform: scale(0.7); + } +} +@-moz-keyframes to_show { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + } +} +@-webkit-keyframes to_show { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + } +} +@-o-keyframes to_show { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + } +} +@keyframes to_show { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + } +} +@-moz-keyframes to_hide { + 0% { + opacity: 1; + -ms-filter: none; + filter: none; + } + 100% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + } +} +@-webkit-keyframes to_hide { + 0% { + opacity: 1; + -ms-filter: none; + filter: none; + } + 100% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + } +} +@-o-keyframes to_hide { + 0% { + opacity: 1; + -ms-filter: none; + filter: none; + } + 100% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + } +} +@keyframes to_hide { + 0% { + opacity: 1; + -ms-filter: none; + filter: none; + } + 100% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + } +} +@-moz-keyframes ribbon_to_show { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + } + 100% { + opacity: 0.6; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; + filter: alpha(opacity=60); + } +} +@-webkit-keyframes ribbon_to_show { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + } + 100% { + opacity: 0.6; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; + filter: alpha(opacity=60); + } +} +@-o-keyframes ribbon_to_show { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + } + 100% { + opacity: 0.6; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; + filter: alpha(opacity=60); + } +} +@keyframes ribbon_to_show { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + } + 100% { + opacity: 0.6; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; + filter: alpha(opacity=60); + } +} +@-moz-keyframes avatar_turn_around { + from { + -webkit-transform: rotate(0); + -moz-transform: rotate(0); + -o-transform: rotate(0); + -ms-transform: rotate(0); + transform: rotate(0); + } + to { + -webkit-transform: rotate(360deg); + -moz-transform: rotate(360deg); + -o-transform: rotate(360deg); + -ms-transform: rotate(360deg); + transform: rotate(360deg); + } +} +@-webkit-keyframes avatar_turn_around { + from { + -webkit-transform: rotate(0); + -moz-transform: rotate(0); + -o-transform: rotate(0); + -ms-transform: rotate(0); + transform: rotate(0); + } + to { + -webkit-transform: rotate(360deg); + -moz-transform: rotate(360deg); + -o-transform: rotate(360deg); + -ms-transform: rotate(360deg); + transform: rotate(360deg); + } +} +@-o-keyframes avatar_turn_around { + from { + -webkit-transform: rotate(0); + -moz-transform: rotate(0); + -o-transform: rotate(0); + -ms-transform: rotate(0); + transform: rotate(0); + } + to { + -webkit-transform: rotate(360deg); + -moz-transform: rotate(360deg); + -o-transform: rotate(360deg); + -ms-transform: rotate(360deg); + transform: rotate(360deg); + } +} +@keyframes avatar_turn_around { + from { + -webkit-transform: rotate(0); + -moz-transform: rotate(0); + -o-transform: rotate(0); + -ms-transform: rotate(0); + transform: rotate(0); + } + to { + -webkit-transform: rotate(360deg); + -moz-transform: rotate(360deg); + -o-transform: rotate(360deg); + -ms-transform: rotate(360deg); + transform: rotate(360deg); + } +} +@-moz-keyframes sub_menus { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: translateY(10px); + -moz-transform: translateY(10px); + -o-transform: translateY(10px); + -ms-transform: translateY(10px); + transform: translateY(10px); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@-webkit-keyframes sub_menus { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: translateY(10px); + -moz-transform: translateY(10px); + -o-transform: translateY(10px); + -ms-transform: translateY(10px); + transform: translateY(10px); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@-o-keyframes sub_menus { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: translateY(10px); + -moz-transform: translateY(10px); + -o-transform: translateY(10px); + -ms-transform: translateY(10px); + transform: translateY(10px); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@keyframes sub_menus { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: translateY(10px); + -moz-transform: translateY(10px); + -o-transform: translateY(10px); + -ms-transform: translateY(10px); + transform: translateY(10px); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@-moz-keyframes donate_effcet { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: translateY(-20px); + -moz-transform: translateY(-20px); + -o-transform: translateY(-20px); + -ms-transform: translateY(-20px); + transform: translateY(-20px); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@-webkit-keyframes donate_effcet { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: translateY(-20px); + -moz-transform: translateY(-20px); + -o-transform: translateY(-20px); + -ms-transform: translateY(-20px); + transform: translateY(-20px); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@-o-keyframes donate_effcet { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: translateY(-20px); + -moz-transform: translateY(-20px); + -o-transform: translateY(-20px); + -ms-transform: translateY(-20px); + transform: translateY(-20px); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@keyframes donate_effcet { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transform: translateY(-20px); + -moz-transform: translateY(-20px); + -o-transform: translateY(-20px); + -ms-transform: translateY(-20px); + transform: translateY(-20px); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@-moz-keyframes sidebarItem { + 0% { + -webkit-transform: translateX(200px); + -moz-transform: translateX(200px); + -o-transform: translateX(200px); + -ms-transform: translateX(200px); + transform: translateX(200px); + } + 100% { + -webkit-transform: translateX(0); + -moz-transform: translateX(0); + -o-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } +} +@-webkit-keyframes sidebarItem { + 0% { + -webkit-transform: translateX(200px); + -moz-transform: translateX(200px); + -o-transform: translateX(200px); + -ms-transform: translateX(200px); + transform: translateX(200px); + } + 100% { + -webkit-transform: translateX(0); + -moz-transform: translateX(0); + -o-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } +} +@-o-keyframes sidebarItem { + 0% { + -webkit-transform: translateX(200px); + -moz-transform: translateX(200px); + -o-transform: translateX(200px); + -ms-transform: translateX(200px); + transform: translateX(200px); + } + 100% { + -webkit-transform: translateX(0); + -moz-transform: translateX(0); + -o-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } +} +@keyframes sidebarItem { + 0% { + -webkit-transform: translateX(200px); + -moz-transform: translateX(200px); + -o-transform: translateX(200px); + -ms-transform: translateX(200px); + transform: translateX(200px); + } + 100% { + -webkit-transform: translateX(0); + -moz-transform: translateX(0); + -o-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } +} +:root { + --global-font-size: 14px; + --global-bg: #fff; + --font-color: #4c4948; + --hr-border: #a4d8fa; + --hr-before-color: #80c8f8; + --search-bg: #f6f8fa; + --search-input-color: #4c4948; + --search-a-color: #4c4948; + --preloader-bg: #37474f; + --preloader-color: #fff; + --tab-border-color: #f0f0f0; + --tab-botton-bg: #f0f0f0; + --tab-botton-color: #1f2d3d; + --tab-button-hover-bg: #dcdcdc; + --tab-button-active-bg: #fff; + --card-bg: #fff; + --sidebar-bg: #f6f8fa; + --btn-hover-color: #ff7242; + --btn-color: #fff; + --btn-bg: #49b1f5; + --text-bg-hover: rgba(73,177,245,0.7); + --light-grey: #eee; + --dark-grey: #cacaca; + --white: #fff; + --text-highlight-color: #1f2d3d; + --blockquote-color: #6a737d; + --blockquote-bg: rgba(73,177,245,0.1); + --reward-pop: #f5f5f5; + --toc-link-color: #666261; + --card-box-shadow: 0 3px 8px 6px rgba(7,17,27,0.05); + --card-hover-box-shadow: 0 3px 8px 6px rgba(7,17,27,0.09); + --pseudo-hover: #ff7242; + --headline-presudo: #a0a0a0; + --scrollbar-color: #49b1f5; + --default-bg-color: #49b1f5; + --zoom-bg: #fff; + --mark-bg: rgba(0,0,0,0.3); +} +body { + position: relative; + min-height: 100%; + background: var(--global-bg); + color: var(--font-color); + font-size: var(--global-font-size); + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Lato, Roboto, 'PingFang SC', 'Microsoft YaHei', sans-serif; + line-height: 2; + -webkit-tap-highlight-color: rgba(0,0,0,0); +} +*::-webkit-scrollbar { + width: 5px; + height: 5px; +} +*::-webkit-scrollbar-thumb { + background: var(--scrollbar-color); +} +*::-webkit-scrollbar-track { + background-color: transparent; +} +* { + scrollbar-width: thin; + scrollbar-color: var(--scrollbar-color) transparent; +} +input::placeholder { + color: var(--font-color); +} +h1, +h2, +h3, +h4, +h5, +h6 { + position: relative; + margin: 20px 0 14px; + color: var(--text-highlight-color); + font-weight: bold; +} +h1 code, +h2 code, +h3 code, +h4 code, +h5 code, +h6 code { + font-size: inherit !important; +} +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.table-wrap { + overflow-x: scroll; + margin: 0 0 20px; +} +table { + display: table; + width: 100%; + border-spacing: 0; + border-collapse: collapse; + empty-cells: show; +} +table thead { + background: rgba(153,169,191,0.1); +} +table th, +table td { + padding: 6px 12px; + border: 1px solid var(--light-grey); + vertical-align: middle; +} +*::selection { + background: #00c4b6; + color: #f7f7f7; +} +button { + padding: 0; + outline: 0; + border: none; + background: none; + cursor: pointer; + touch-action: manipulation; +} +a { + color: #99a9bf; + text-decoration: none; + word-wrap: break-word; + -webkit-transition: all 0.2s; + -moz-transition: all 0.2s; + -o-transition: all 0.2s; + -ms-transition: all 0.2s; + transition: all 0.2s; + overflow-wrap: break-word; +} +a:hover { + color: #49b1f5; +} +.is-center { + text-align: center; +} +.pull-left { + float: left; +} +.pull-right { + float: right; +} +img[src=''], +img:not([src]) { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); +} +.img-alt { + margin: -10px 0 10px; + color: #858585; +} +.img-alt:hover { + text-decoration: none !important; +} +blockquote { + margin: 0 0 20px; + padding: 12px 15px; + border-left: 3px solid #49b1f5; + background-color: var(--blockquote-bg); + color: var(--blockquote-color); +} +blockquote footer cite:before { + padding: 0 5px; + content: '—'; +} +blockquote > :last-child { + margin-bottom: 0 !important; +} +:root { + --hl-color: #eff; + --hl-bg: #212121; + --hltools-bg: #1c1c1c; + --hltools-color: rgba(238,255,255,0.8); + --hlnumber-bg: #212121; + --hlnumber-color: rgba(238,255,255,0.5); + --hlscrollbar-bg: #353535; + --hlexpand-bg: linear-gradient(180deg, rgba(33,33,33,0.6), rgba(33,33,33,0.9)); +} +[data-theme='dark'] { + --hl-color: rgba(255,255,255,0.7); + --hl-bg: #171717; + --hltools-bg: #1a1a1a; + --hltools-color: #90a4ae; + --hlnumber-bg: #171717; + --hlnumber-color: rgba(255,255,255,0.4); + --hlscrollbar-bg: #1f1f1f; + --hlexpand-bg: linear-gradient(180deg, rgba(23,23,23,0.6), rgba(23,23,23,0.9)); +} +pre[class*='language-'] .token.comment, +pre[class*='language-'] .token.prolog, +pre[class*='language-'] .token.doctype, +pre[class*='language-'] .token.cdata { + color: #7c7c7c; +} +pre[class*='language-'] .token.punctuation { + color: #c5c8c6; +} +pre[class*='language-'] .namespace { + opacity: 0.7; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"; + filter: alpha(opacity=70); +} +pre[class*='language-'] .token.property, +pre[class*='language-'] .token.keyword, +pre[class*='language-'] .token.tag { + color: #96cbfe; +} +pre[class*='language-'] .token.class-name { + color: #ffffb6; +} +pre[class*='language-'] .token.boolean, +pre[class*='language-'] .token.constant { + color: #9c9; +} +pre[class*='language-'] .token.symbol, +pre[class*='language-'] .token.deleted { + color: #f92672; +} +pre[class*='language-'] .token.number { + color: #ff73fd; +} +pre[class*='language-'] .token.selector, +pre[class*='language-'] .token.attr-name, +pre[class*='language-'] .token.string, +pre[class*='language-'] .token.char, +pre[class*='language-'] .token.builtin, +pre[class*='language-'] .token.inserted { + color: #a8ff60; +} +pre[class*='language-'] .token.variable { + color: #c6c5fe; +} +pre[class*='language-'] .token.operator { + color: #ededed; +} +pre[class*='language-'] .token.entity { + color: #ffffb6; + cursor: help; +} +pre[class*='language-'] .token.url { + color: #96cbfe; +} +pre[class*='language-'] .language-css .token.string, +pre[class*='language-'] .style .token.string { + color: #87c38a; +} +pre[class*='language-'] .token.atrule, +pre[class*='language-'] .token.attr-value { + color: #f9ee98; +} +pre[class*='language-'] .token.function { + color: #dad085; +} +pre[class*='language-'] .token.regex { + color: #e9c062; +} +pre[class*='language-'] .token.important { + color: #fd971f; +} +pre[class*='language-'] .token.important, +pre[class*='language-'] .token.bold { + font-weight: bold; +} +pre[class*='language-'] .token.italic { + font-style: italic; +} +#article-container pre[class*='language-'] { + scrollbar-color: var(--hlscrollbar-bg) transparent; +} +#article-container pre[class*='language-']::-webkit-scrollbar-thumb { + background: var(--hlscrollbar-bg); +} +#article-container pre[class*='language-']:not(.line-numbers) { + padding: 10px 20px; +} +#article-container pre[class*='language-'] .caption { + margin-left: -3.8em; + padding: 4px 16px !important; +} +#article-container pre[class*='language-'] .caption a { + padding: 0 !important; +} +#article-container pre, +#article-container figure.highlight { + overflow: auto; + margin: 0 0 20px; + padding: 0; + background: var(--hl-bg); + color: var(--hl-color); + line-height: 1.6; +} +#article-container pre, +#article-container code { + font-size: var(--global-font-size); + font-family: consolas, Menlo, 'PingFang SC', 'Microsoft YaHei', sans-serif !important; +} +#article-container code { + padding: 2px 4px; + background: rgba(27,31,35,0.05); + color: #f47466; +} +#article-container pre { + padding: 10px 20px; +} +#article-container pre code { + padding: 0; + background: none; + color: var(--hl-color); + text-shadow: none; +} +#article-container figure.highlight { + position: relative; +} +#article-container figure.highlight pre { + margin: 0; + padding: 8px 0; + border: none; +} +#article-container figure.highlight figcaption, +#article-container figure.highlight .caption { + padding: 6px 0 2px 14px; + font-size: var(--global-font-size); + line-height: 1em; +} +#article-container figure.highlight figcaption a, +#article-container figure.highlight .caption a { + float: right; + padding-right: 10px; + color: var(--hl-color); +} +#article-container figure.highlight figcaption a:hover, +#article-container figure.highlight .caption a:hover { + border-bottom-color: var(--hl-color); +} +#article-container figure.highlight.copy-true { + -webkit-user-select: all; + -moz-user-select: all; + -ms-user-select: all; + user-select: all; + -webkit-user-select: all; +} +#article-container figure.highlight.copy-true > table, +#article-container figure.highlight.copy-true > pre { + display: block !important; + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); +} +#article-container .highlight-tools { + position: relative; + display: -webkit-box; + display: -moz-box; + display: -webkit-flex; + display: -ms-flexbox; + display: box; + display: flex; + -webkit-box-align: center; + -moz-box-align: center; + -o-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + overflow: hidden; + min-height: 24px; + height: 2.15em; + background: var(--hltools-bg); + color: var(--hltools-color); + font-size: var(--global-font-size); +} +#article-container .highlight-tools.closed ~ * { + display: none; +} +#article-container .highlight-tools.closed .expand { + -webkit-transition: all 0.3s; + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -ms-transition: all 0.3s; + transition: all 0.3s; + -webkit-transform: rotate(-90deg) !important; + -moz-transform: rotate(-90deg) !important; + -o-transform: rotate(-90deg) !important; + -ms-transform: rotate(-90deg) !important; + transform: rotate(-90deg) !important; +} +#article-container .highlight-tools .expand { + position: absolute; + padding: 0.57em 0.7em; + cursor: pointer; + -webkit-transition: -webkit-transform 0.3s; + -moz-transition: -moz-transform 0.3s; + -o-transition: -o-transform 0.3s; + -ms-transition: -ms-transform 0.3s; + transition: transform 0.3s; +} +#article-container .highlight-tools .expand + .code-lang { + left: 1.7em; +} +#article-container .highlight-tools .code-lang { + position: absolute; + left: 14px; + text-transform: uppercase; + font-weight: bold; + font-size: 1.15em; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-user-select: none; +} +#article-container .highlight-tools .copy-notice { + position: absolute; + right: 2.4em; + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transition: opacity 0.4s; + -moz-transition: opacity 0.4s; + -o-transition: opacity 0.4s; + -ms-transition: opacity 0.4s; + transition: opacity 0.4s; +} +#article-container .highlight-tools .copy-button { + position: absolute; + right: 14px; + cursor: pointer; + -webkit-transition: color 0.2s; + -moz-transition: color 0.2s; + -o-transition: color 0.2s; + -ms-transition: color 0.2s; + transition: color 0.2s; +} +#article-container .highlight-tools .copy-button:hover { + color: #49b1f5; +} +#article-container .gutter { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-user-select: none; +} +#article-container .gist table { + width: auto; +} +#article-container .gist table td { + border: none; +} +@-moz-keyframes code-expand-key { + 0% { + opacity: 0.6; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; + filter: alpha(opacity=60); + } + 50% { + opacity: 0.1; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=10)"; + filter: alpha(opacity=10); + } + 100% { + opacity: 0.6; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; + filter: alpha(opacity=60); + } +} +@-webkit-keyframes code-expand-key { + 0% { + opacity: 0.6; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; + filter: alpha(opacity=60); + } + 50% { + opacity: 0.1; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=10)"; + filter: alpha(opacity=10); + } + 100% { + opacity: 0.6; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; + filter: alpha(opacity=60); + } +} +@-o-keyframes code-expand-key { + 0% { + opacity: 0.6; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; + filter: alpha(opacity=60); + } + 50% { + opacity: 0.1; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=10)"; + filter: alpha(opacity=10); + } + 100% { + opacity: 0.6; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; + filter: alpha(opacity=60); + } +} +@keyframes code-expand-key { + 0% { + opacity: 0.6; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; + filter: alpha(opacity=60); + } + 50% { + opacity: 0.1; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=10)"; + filter: alpha(opacity=10); + } + 100% { + opacity: 0.6; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; + filter: alpha(opacity=60); + } +} +.article-sort { + margin-left: 10px; + padding-left: 20px; + border-left: 2px solid #aadafa; +} +.article-sort-title { + position: relative; + margin-left: 10px; + padding-bottom: 20px; + padding-left: 20px; + font-size: 1.72em; +} +.article-sort-title:hover:before { + border-color: var(--pseudo-hover); +} +.article-sort-title:before { + position: absolute; + top: calc(((100% - 36px) / 2)); + left: -9px; + z-index: 1; + width: 10px; + height: 10px; + border: 5px solid #49b1f5; + border-radius: 10px; + background: var(--card-bg); + content: ''; + line-height: 10px; + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + -ms-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} +.article-sort-title:after { + position: absolute; + bottom: 0; + left: 0; + z-index: 0; + width: 2px; + height: 1.5em; + background: #aadafa; + content: ''; +} +.article-sort-item { + position: relative; + display: -webkit-box; + display: -moz-box; + display: -webkit-flex; + display: -ms-flexbox; + display: box; + display: flex; + -webkit-box-align: center; + -moz-box-align: center; + -o-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + margin: 0 0 20px 10px; + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + -ms-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} +.article-sort-item:hover:before { + border-color: var(--pseudo-hover); +} +.article-sort-item:before { + position: absolute; + left: calc(-20px - 17px); + width: 6px; + height: 6px; + border: 3px solid #49b1f5; + border-radius: 6px; + background: var(--card-bg); + content: ''; + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + -ms-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} +.article-sort-item.no-article-cover { + height: 80px; +} +.article-sort-item.no-article-cover .article-sort-item-info { + padding: 0; +} +.article-sort-item.year { + font-size: 1.43em; +} +.article-sort-item.year:hover:before { + border-color: #49b1f5; +} +.article-sort-item.year:before { + border-color: var(--pseudo-hover); +} +.article-sort-item-time { + color: #858585; + font-size: 95%; +} +.article-sort-item-time time { + padding-left: 6px; + cursor: default; +} +.article-sort-item-title { + color: var(--font-color); + font-size: 1.1em; + -webkit-transition: all 0.3s; + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -ms-transition: all 0.3s; + transition: all 0.3s; + -webkit-line-clamp: 2; +} +.article-sort-item-title:hover { + color: #49b1f5; + -webkit-transform: translateX(10px); + -moz-transform: translateX(10px); + -o-transform: translateX(10px); + -ms-transform: translateX(10px); + transform: translateX(10px); +} +.article-sort-item-img { + overflow: hidden; + width: 80px; + height: 80px; +} +.article-sort-item-info { + -webkit-box-flex: 1; + -moz-box-flex: 1; + -o-box-flex: 1; + box-flex: 1; + -webkit-flex: 1; + -ms-flex: 1; + flex: 1; + padding: 0 16px; +} +.category-lists .category-title { + font-size: 2.57em; +} +@media screen and (max-width: 768px) { + .category-lists .category-title { + font-size: 2em; + } +} +.category-lists .category-list { + margin-bottom: 0; +} +.category-lists .category-list a { + color: var(--font-color); +} +.category-lists .category-list a:hover { + color: #49b1f5; +} +.category-lists .category-list .category-list-count { + margin-left: 8px; + color: #858585; +} +.category-lists .category-list .category-list-count:before { + content: '('; +} +.category-lists .category-list .category-list-count:after { + content: ')'; +} +.category-lists ul { + padding: 0 0 0 20px; +} +.category-lists ul ul { + padding-left: 4px; +} +.category-lists ul li { + position: relative; + margin: 6px 0; + padding: 0.12em 0.4em 0.12em 1.4em; +} +#body-wrap { + display: -webkit-box; + display: -moz-box; + display: -webkit-flex; + display: -ms-flexbox; + display: box; + display: flex; + -webkit-box-orient: vertical; + -moz-box-orient: vertical; + -o-box-orient: vertical; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + min-height: 100vh; +} +.layout { + display: -webkit-box; + display: -moz-box; + display: -webkit-flex; + display: -ms-flexbox; + display: box; + display: flex; + -webkit-box-flex: 1; + -moz-box-flex: 1; + -o-box-flex: 1; + box-flex: 1; + -webkit-flex: 1 auto; + -ms-flex: 1 auto; + flex: 1 auto; + margin: 0 auto; + padding: 40px 15px; + max-width: 1200px; + width: 100%; +} +@media screen and (max-width: 900px) { + .layout { + -webkit-box-orient: vertical; + -moz-box-orient: vertical; + -o-box-orient: vertical; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + } +} +@media screen and (max-width: 768px) { + .layout { + padding: 20px 5px; + } +} +@media screen and (min-width: 2000px) { + .layout { + max-width: 70%; + } +} +.layout > div:first-child:not(.recent-posts) { + -webkit-align-self: flex-start; + align-self: flex-start; + -ms-flex-item-align: start; + padding: 50px 40px; +} +@media screen and (max-width: 768px) { + .layout > div:first-child:not(.recent-posts) { + padding: 36px 14px; + } +} +.layout > div:first-child { + width: 74%; + -webkit-transition: all 0.3s; + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -ms-transition: all 0.3s; + transition: all 0.3s; +} +@media screen and (max-width: 900px) { + .layout > div:first-child { + width: 100% !important; + } +} +.layout.hide-aside { + max-width: 1000px; +} +@media screen and (min-width: 2000px) { + .layout.hide-aside { + max-width: 1300px; + } +} +.layout.hide-aside > div { + width: 100% !important; +} +.apple #page-header.full_page { + background-attachment: scroll !important; +} +.apple .recent-post-item, +.apple .avatar-img, +.apple .flink-item-icon { + -webkit-transform: translateZ(0); + -moz-transform: translateZ(0); + -o-transform: translateZ(0); + -ms-transform: translateZ(0); + transform: translateZ(0); +} +#article-container .flink { + margin-bottom: 20px; +} +#article-container .flink .flink-list { + overflow: auto; + padding: 10px 10px 0; + text-align: center; +} +#article-container .flink .flink-list > .flink-list-item { + position: relative; + float: left; + overflow: hidden; + margin: 15px 7px; + width: calc(100% / 3 - 15px); + height: 90px; + border-radius: 8px; + line-height: 17px; + -webkit-transform: translateZ(0); +} +@media screen and (max-width: 1024px) { + #article-container .flink .flink-list > .flink-list-item { + width: calc(50% - 15px) !important; + } +} +@media screen and (max-width: 600px) { + #article-container .flink .flink-list > .flink-list-item { + width: calc(100% - 15px) !important; + } +} +#article-container .flink .flink-list > .flink-list-item:hover .flink-item-icon { + margin-left: -10px; + width: 0; +} +#article-container .flink .flink-list > .flink-list-item:before { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: -1; + background: var(--text-bg-hover); + content: ''; + -webkit-transition: -webkit-transform 0.3s ease-out; + -moz-transition: -moz-transform 0.3s ease-out; + -o-transition: -o-transform 0.3s ease-out; + -ms-transition: -ms-transform 0.3s ease-out; + transition: transform 0.3s ease-out; + -webkit-transform: scale(0); + -moz-transform: scale(0); + -o-transform: scale(0); + -ms-transform: scale(0); + transform: scale(0); +} +#article-container .flink .flink-list > .flink-list-item:hover:before, +#article-container .flink .flink-list > .flink-list-item:focus:before, +#article-container .flink .flink-list > .flink-list-item:active:before { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); +} +#article-container .flink .flink-list > .flink-list-item a { + color: var(--font-color); + text-decoration: none; +} +#article-container .flink .flink-list > .flink-list-item a .flink-item-icon { + float: left; + overflow: hidden; + margin: 15px 10px; + width: 60px; + height: 60px; + border-radius: 35px; + -webkit-transition: width 0.3s ease-out; + -moz-transition: width 0.3s ease-out; + -o-transition: width 0.3s ease-out; + -ms-transition: width 0.3s ease-out; + transition: width 0.3s ease-out; +} +#article-container .flink .flink-list > .flink-list-item a .flink-item-icon img { + width: 100%; + height: 100%; + -webkit-transition: filter 375ms ease-in 0.2s, -webkit-transform 0.3s; + -moz-transition: filter 375ms ease-in 0.2s, -moz-transform 0.3s; + -o-transition: filter 375ms ease-in 0.2s, -o-transform 0.3s; + -ms-transition: filter 375ms ease-in 0.2s, -ms-transform 0.3s; + transition: filter 375ms ease-in 0.2s, transform 0.3s; + object-fit: cover; +} +#article-container .flink .flink-list > .flink-list-item a .img-alt { + display: none; +} +#article-container .flink .flink-item-name { + padding: 16px 10px 0 0; + height: 40px; + font-weight: bold; + font-size: 1.43em; +} +#article-container .flink .flink-item-desc { + padding: 16px 10px 16px 0; + height: 50px; + font-size: 0.93em; +} +#article-container .flink .flink-name { + margin-bottom: 5px; + font-weight: bold; + font-size: 1.5em; +} +#recent-posts > .recent-post-item:not(:first-child) { + margin-top: 20px; +} +#recent-posts > .recent-post-item { + display: -webkit-box; + display: -moz-box; + display: -webkit-flex; + display: -ms-flexbox; + display: box; + display: flex; + -webkit-box-orient: horizontal; + -moz-box-orient: horizontal; + -o-box-orient: horizontal; + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; + -webkit-box-align: center; + -moz-box-align: center; + -o-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + overflow: hidden; + height: 16.8em; +} +@media screen and (max-width: 768px) { + #recent-posts > .recent-post-item { + -webkit-box-orient: vertical; + -moz-box-orient: vertical; + -o-box-orient: vertical; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + height: auto; + } +} +#recent-posts > .recent-post-item:hover img.post-bg { + -webkit-transform: scale(1.1); + -moz-transform: scale(1.1); + -o-transform: scale(1.1); + -ms-transform: scale(1.1); + transform: scale(1.1); +} +#recent-posts > .recent-post-item.ads-wrap { + display: block !important; + height: auto !important; +} +#recent-posts > .recent-post-item .post_cover { + overflow: hidden; + width: 42%; + height: 100%; +} +@media screen and (max-width: 768px) { + #recent-posts > .recent-post-item .post_cover { + width: 100%; + height: 230px; + } +} +#recent-posts > .recent-post-item .post_cover.right { + -webkit-box-ordinal-group: 1; + -moz-box-ordinal-group: 1; + -o-box-ordinal-group: 1; + -ms-flex-order: 1; + -webkit-order: 1; + order: 1; +} +@media screen and (max-width: 768px) { + #recent-posts > .recent-post-item .post_cover.right { + -webkit-box-ordinal-group: 0; + -moz-box-ordinal-group: 0; + -o-box-ordinal-group: 0; + -ms-flex-order: 0; + -webkit-order: 0; + order: 0; + } +} +#recent-posts > .recent-post-item >.recent-post-info { + padding: 0 40px; + width: 58%; +} +@media screen and (max-width: 768px) { + #recent-posts > .recent-post-item >.recent-post-info { + padding: 20px 20px 30px; + width: 100%; + } +} +#recent-posts > .recent-post-item >.recent-post-info.no-cover { + width: 100%; +} +@media screen and (max-width: 768px) { + #recent-posts > .recent-post-item >.recent-post-info.no-cover { + padding: 30px 20px; + } +} +#recent-posts > .recent-post-item >.recent-post-info > .article-title { + color: var(--text-highlight-color); + font-size: 1.55em; + line-height: 1.4; + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + -ms-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; + -webkit-line-clamp: 2; +} +#recent-posts > .recent-post-item >.recent-post-info > .article-title .sticky { + margin-right: 10px; + color: #ff7242; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -o-transform: rotate(45deg); + -ms-transform: rotate(45deg); + transform: rotate(45deg); +} +@media screen and (max-width: 768px) { + #recent-posts > .recent-post-item >.recent-post-info > .article-title { + font-size: 1.43em; + } +} +#recent-posts > .recent-post-item >.recent-post-info > .article-title:hover { + color: #49b1f5; +} +#recent-posts > .recent-post-item >.recent-post-info > .article-meta-wrap { + margin: 6px 0; + color: #858585; + font-size: 0.9em; +} +#recent-posts > .recent-post-item >.recent-post-info > .article-meta-wrap > .post-meta-date { + cursor: default; +} +#recent-posts > .recent-post-item >.recent-post-info > .article-meta-wrap i { + margin: 0 4px 0 0; +} +#recent-posts > .recent-post-item >.recent-post-info > .article-meta-wrap .fa-spinner { + margin: 0; +} +#recent-posts > .recent-post-item >.recent-post-info > .article-meta-wrap .article-meta-label { + padding-right: 4px; +} +#recent-posts > .recent-post-item >.recent-post-info > .article-meta-wrap .article-meta-separator { + margin: 0 6px; +} +#recent-posts > .recent-post-item >.recent-post-info > .article-meta-wrap .article-meta-link { + margin: 0 4px; +} +#recent-posts > .recent-post-item >.recent-post-info > .article-meta-wrap a { + color: #858585; +} +#recent-posts > .recent-post-item >.recent-post-info > .article-meta-wrap a:hover { + color: #49b1f5; + text-decoration: underline; +} +#recent-posts > .recent-post-item >.recent-post-info > .content { + -webkit-line-clamp: 2; +} +.tag-cloud-list a { + display: inline-block; + padding: 0 8px; + -webkit-transition: all 0.3s; + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -ms-transition: all 0.3s; + transition: all 0.3s; +} +.tag-cloud-list a:hover { + color: #49b1f5 !important; + -webkit-transform: scale(1.1); + -moz-transform: scale(1.1); + -o-transform: scale(1.1); + -ms-transform: scale(1.1); + transform: scale(1.1); +} +@media screen and (max-width: 768px) { + .tag-cloud-list a { + zoom: 0.85; + } +} +.tag-cloud-title { + font-size: 2.57em; +} +@media screen and (max-width: 768px) { + .tag-cloud-title { + font-size: 2em; + } +} +h1.page-title + .tag-cloud-list { + text-align: left; +} +#aside-content { + width: 26%; +} +@media screen and (min-width: 900px) { + #aside-content { + padding-left: 15px; + } +} +@media screen and (max-width: 900px) { + #aside-content { + width: 100%; + } +} +#aside-content > .card-widget:first-child { + margin-top: 0; +} +@media screen and (max-width: 900px) { + #aside-content > .card-widget:first-child { + margin-top: 20px; + } +} +#aside-content .card-widget { + position: relative; + overflow: hidden; + margin-top: 20px; + padding: 20px 24px; +} +#aside-content .card-info .author-info__name { + font-weight: 500; + font-size: 1.57em; +} +#aside-content .card-info .author-info__description { + margin-top: -0.42em; +} +#aside-content .card-info .card-info-data { + margin: 14px 0 4px; +} +#aside-content .card-info .card-info-social-icons { + margin: 6px 0 -6px; +} +#aside-content .card-info .card-info-social-icons .social-icon { + margin: 0 10px; + color: var(--font-color); + font-size: 1.4em; +} +#aside-content .card-info .card-info-social-icons i { + -webkit-transition: all 0.3s; + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -ms-transition: all 0.3s; + transition: all 0.3s; +} +#aside-content .card-info .card-info-social-icons i:hover { + -webkit-transform: rotate(360deg); + -moz-transform: rotate(360deg); + -o-transform: rotate(360deg); + -ms-transform: rotate(360deg); + transform: rotate(360deg); +} +#aside-content .card-info #card-info-btn { + display: block; + margin-top: 14px; + background-color: var(--btn-bg); + color: var(--btn-color); + text-align: center; + line-height: 2.4; +} +#aside-content .card-info #card-info-btn:hover { + background-color: var(--btn-hover-color); +} +#aside-content .card-info #card-info-btn span { + padding-left: 10px; +} +#aside-content .item-headline { + padding-bottom: 6px; + font-size: 1.2em; +} +#aside-content .item-headline span { + margin-left: 6px; +} +@media screen and (min-width: 900px) { + #aside-content .sticky_layout { + position: sticky; + position: -webkit-sticky; + top: 20px; + -webkit-transition: top 0.3s; + -moz-transition: top 0.3s; + -o-transition: top 0.3s; + -ms-transition: top 0.3s; + transition: top 0.3s; + } +} +#aside-content .card-tag-cloud a { + display: inline-block; + padding: 0 4px; +} +#aside-content .card-tag-cloud a:hover { + color: #49b1f5 !important; +} +#aside-content .aside-list > span { + display: block; + margin-bottom: 10px; + text-align: center; +} +#aside-content .aside-list > .aside-list-item { + display: -webkit-box; + display: -moz-box; + display: -webkit-flex; + display: -ms-flexbox; + display: box; + display: flex; + -webkit-box-align: center; + -moz-box-align: center; + -o-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + padding: 6px 0; +} +#aside-content .aside-list > .aside-list-item:first-child { + padding-top: 0; +} +#aside-content .aside-list > .aside-list-item:not(:last-child) { + border-bottom: 1px dashed #f5f5f5; +} +#aside-content .aside-list > .aside-list-item:last-child { + padding-bottom: 0; +} +#aside-content .aside-list > .aside-list-item .thumbnail { + overflow: hidden; + width: 4.2em; + height: 4.2em; +} +#aside-content .aside-list > .aside-list-item .content { + -webkit-box-flex: 1; + -moz-box-flex: 1; + -o-box-flex: 1; + box-flex: 1; + -webkit-flex: 1; + -ms-flex: 1; + flex: 1; + padding-left: 10px; + word-break: break-all; +} +#aside-content .aside-list > .aside-list-item .content > .name { + -webkit-line-clamp: 1; +} +#aside-content .aside-list > .aside-list-item .content > time, +#aside-content .aside-list > .aside-list-item .content > .name { + display: block; + color: #858585; + font-size: 85%; +} +#aside-content .aside-list > .aside-list-item .content > .title, +#aside-content .aside-list > .aside-list-item .content > .comment { + color: var(--font-color); + font-size: 95%; + line-height: 1.5; + -webkit-line-clamp: 2; +} +#aside-content .aside-list > .aside-list-item .content > .title:hover, +#aside-content .aside-list > .aside-list-item .content > .comment:hover { + color: #49b1f5; +} +#aside-content .aside-list > .aside-list-item.no-cover { + min-height: 4.4em; +} +#aside-content .card-archives ul.card-archive-list, +#aside-content .card-categories ul.card-category-list { + margin: 0; + padding: 0; + list-style: none; +} +#aside-content .card-archives ul.card-archive-list > .card-archive-list-item a, +#aside-content .card-categories ul.card-category-list > .card-category-list-item a { + display: -webkit-box; + display: -moz-box; + display: -webkit-flex; + display: -ms-flexbox; + display: box; + display: flex; + -webkit-box-orient: horizontal; + -moz-box-orient: horizontal; + -o-box-orient: horizontal; + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; + padding: 3px 10px; + color: var(--font-color); + -webkit-transition: all 0.4s; + -moz-transition: all 0.4s; + -o-transition: all 0.4s; + -ms-transition: all 0.4s; + transition: all 0.4s; +} +#aside-content .card-archives ul.card-archive-list > .card-archive-list-item a:hover, +#aside-content .card-categories ul.card-category-list > .card-category-list-item a:hover { + padding: 3px 17px; + background-color: var(--text-bg-hover); +} +#aside-content .card-archives ul.card-archive-list > .card-archive-list-item a span:first-child, +#aside-content .card-categories ul.card-category-list > .card-category-list-item a span:first-child { + -webkit-box-flex: 1; + -moz-box-flex: 1; + -o-box-flex: 1; + box-flex: 1; + -webkit-flex: 1; + -ms-flex: 1; + flex: 1; +} +#aside-content .card-categories .card-category-list.child { + padding: 0 0 0 16px; +} +#aside-content .card-categories .card-category-list > .parent > a.expand i { + -webkit-transform: rotate(-90deg); + -moz-transform: rotate(-90deg); + -o-transform: rotate(-90deg); + -ms-transform: rotate(-90deg); + transform: rotate(-90deg); +} +#aside-content .card-categories .card-category-list > .parent > a.expand + .child { + display: block; +} +#aside-content .card-categories .card-category-list > .parent > a .card-category-list-name { + width: 70% !important; +} +#aside-content .card-categories .card-category-list > .parent > a .card-category-list-count { + width: calc(100% - 70% - 20px); + text-align: right; +} +#aside-content .card-categories .card-category-list > .parent > a i { + float: right; + margin-right: -0.5em; + padding: 0.5em; + -webkit-transition: -webkit-transform 0.3s; + -moz-transition: -moz-transform 0.3s; + -o-transition: -o-transform 0.3s; + -ms-transition: -ms-transform 0.3s; + transition: transform 0.3s; + -webkit-transform: rotate(0); + -moz-transform: rotate(0); + -o-transform: rotate(0); + -ms-transform: rotate(0); + transform: rotate(0); +} +#aside-content .card-webinfo .webinfo .webinfo-item { + display: -webkit-box; + display: -moz-box; + display: -webkit-flex; + display: -ms-flexbox; + display: box; + display: flex; + -webkit-box-align: center; + -moz-box-align: center; + -o-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + padding: 2px 10px 0; +} +#aside-content .card-webinfo .webinfo .webinfo-item div:first-child { + -webkit-box-flex: 1; + -moz-box-flex: 1; + -o-box-flex: 1; + box-flex: 1; + -webkit-flex: 1; + -ms-flex: 1; + flex: 1; + padding-right: 20px; +} +@media screen and (min-width: 901px) { + #aside-content #card-toc { + right: 0 !important; + } +} +@media screen and (max-width: 900px) { + #aside-content #card-toc { + position: fixed; + right: 55px; + bottom: 30px; + z-index: 100; + max-width: 380px; + max-height: calc(100% - 60px); + width: calc(100% - 80px); + -webkit-transition: none; + -moz-transition: none; + -o-transition: none; + -ms-transition: none; + transition: none; + -webkit-transform: scale(0); + -moz-transform: scale(0); + -o-transform: scale(0); + -ms-transform: scale(0); + transform: scale(0); + -webkit-transform-origin: right bottom; + -moz-transform-origin: right bottom; + -o-transform-origin: right bottom; + -ms-transform-origin: right bottom; + transform-origin: right bottom; + } + #aside-content #card-toc.open { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } +} +#aside-content #card-toc .toc-percentage { + float: right; + margin-top: -9px; + color: #a9a9a9; + font-style: italic; + font-size: 140%; +} +#aside-content #card-toc .toc-content { + overflow-y: scroll; + overflow-y: overlay; + margin: 0 -24px; + max-height: calc(100vh - 120px); + width: calc(100% + 48px); +} +@media screen and (max-width: 900px) { + #aside-content #card-toc .toc-content { + max-height: calc(100vh - 140px); + } +} +#aside-content #card-toc .toc-content > * { + margin: 0 20px !important; +} +#aside-content #card-toc .toc-content > * > .toc-item > .toc-child { + margin-left: 10px; + padding-left: 10px; + border-left: 1px solid var(--dark-grey); +} +#aside-content #card-toc .toc-content:not(.is-expand) .toc-child { + display: none; +} +@media screen and (max-width: 900px) { + #aside-content #card-toc .toc-content:not(.is-expand) .toc-child { + display: block !important; + } +} +#aside-content #card-toc .toc-content:not(.is-expand) .toc-item.active .toc-child { + display: block; +} +#aside-content #card-toc .toc-content ol, +#aside-content #card-toc .toc-content li { + list-style: none; +} +#aside-content #card-toc .toc-content > ol { + padding: 0 !important; +} +#aside-content #card-toc .toc-content ol { + margin: 0; + padding-left: 18px; +} +#aside-content #card-toc .toc-content .toc-link { + display: block; + margin: 4px 0; + padding: 1px 6px; + color: var(--toc-link-color); + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + -ms-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} +#aside-content #card-toc .toc-content .toc-link:hover { + color: #49b1f5; +} +#aside-content #card-toc .toc-content .toc-link.active { + background: #00c4b6; + color: #fff; +} +#aside-content .sticky_layout:only-child > :first-child { + margin-top: 0; +} +#aside-content .card-more-btn { + float: right; + color: inherit; +} +#aside-content .card-more-btn:hover { + -webkit-animation: more-btn-move 1s infinite; + -moz-animation: more-btn-move 1s infinite; + -o-animation: more-btn-move 1s infinite; + -ms-animation: more-btn-move 1s infinite; + animation: more-btn-move 1s infinite; +} +#aside-content .card-announcement .item-headline i { + color: #f00; +} +.avatar-img { + overflow: hidden; + margin: 0 auto; + width: 110px; + height: 110px; + border-radius: 70px; +} +.avatar-img img { + width: 100%; + height: 100%; + -webkit-transition: filter 375ms ease-in 0.2s, -webkit-transform 0.3s; + -moz-transition: filter 375ms ease-in 0.2s, -moz-transform 0.3s; + -o-transition: filter 375ms ease-in 0.2s, -o-transform 0.3s; + -ms-transition: filter 375ms ease-in 0.2s, -ms-transform 0.3s; + transition: filter 375ms ease-in 0.2s, transform 0.3s; + object-fit: cover; +} +.avatar-img img:hover { + -webkit-transform: rotate(360deg); + -moz-transform: rotate(360deg); + -o-transform: rotate(360deg); + -ms-transform: rotate(360deg); + transform: rotate(360deg); +} +.site-data { + display: table; + width: 100%; + table-layout: fixed; +} +.site-data > a { + display: table-cell; +} +.site-data > a div { + -webkit-transition: all 0.3s; + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -ms-transition: all 0.3s; + transition: all 0.3s; +} +.site-data > a:hover div { + color: #49b1f5 !important; +} +.site-data > a .headline { + color: var(--font-color); +} +.site-data > a .length-num { + margin-top: -0.32em; + color: var(--text-highlight-color); + font-size: 1.4em; +} +@media screen and (min-width: 900px) { + html.hide-aside .layout { + -webkit-box-pack: center; + -moz-box-pack: center; + -o-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + } + html.hide-aside .layout > .aside-content { + display: none; + } + html.hide-aside .layout > div:first-child { + width: 80%; + } +} +.page .sticky_layout { + display: -webkit-box; + display: -moz-box; + display: -webkit-flex; + display: -ms-flexbox; + display: box; + display: flex; + -webkit-box-orient: vertical; + -moz-box-orient: vertical; + -o-box-orient: vertical; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; +} +@-moz-keyframes more-btn-move { + 0%, 100% { + -webkit-transform: translateX(0); + -moz-transform: translateX(0); + -o-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } + 50% { + -webkit-transform: translateX(3px); + -moz-transform: translateX(3px); + -o-transform: translateX(3px); + -ms-transform: translateX(3px); + transform: translateX(3px); + } +} +@-webkit-keyframes more-btn-move { + 0%, 100% { + -webkit-transform: translateX(0); + -moz-transform: translateX(0); + -o-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } + 50% { + -webkit-transform: translateX(3px); + -moz-transform: translateX(3px); + -o-transform: translateX(3px); + -ms-transform: translateX(3px); + transform: translateX(3px); + } +} +@-o-keyframes more-btn-move { + 0%, 100% { + -webkit-transform: translateX(0); + -moz-transform: translateX(0); + -o-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } + 50% { + -webkit-transform: translateX(3px); + -moz-transform: translateX(3px); + -o-transform: translateX(3px); + -ms-transform: translateX(3px); + transform: translateX(3px); + } +} +@keyframes more-btn-move { + 0%, 100% { + -webkit-transform: translateX(0); + -moz-transform: translateX(0); + -o-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } + 50% { + -webkit-transform: translateX(3px); + -moz-transform: translateX(3px); + -o-transform: translateX(3px); + -ms-transform: translateX(3px); + transform: translateX(3px); + } +} +@-moz-keyframes toc-open { + 0% { + -webkit-transform: scale(0.7); + -moz-transform: scale(0.7); + -o-transform: scale(0.7); + -ms-transform: scale(0.7); + transform: scale(0.7); + } + 100% { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } +} +@-webkit-keyframes toc-open { + 0% { + -webkit-transform: scale(0.7); + -moz-transform: scale(0.7); + -o-transform: scale(0.7); + -ms-transform: scale(0.7); + transform: scale(0.7); + } + 100% { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } +} +@-o-keyframes toc-open { + 0% { + -webkit-transform: scale(0.7); + -moz-transform: scale(0.7); + -o-transform: scale(0.7); + -ms-transform: scale(0.7); + transform: scale(0.7); + } + 100% { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } +} +@keyframes toc-open { + 0% { + -webkit-transform: scale(0.7); + -moz-transform: scale(0.7); + -o-transform: scale(0.7); + -ms-transform: scale(0.7); + transform: scale(0.7); + } + 100% { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } +} +@-moz-keyframes toc-close { + 0% { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } + 100% { + -webkit-transform: scale(0.7); + -moz-transform: scale(0.7); + -o-transform: scale(0.7); + -ms-transform: scale(0.7); + transform: scale(0.7); + } +} +@-webkit-keyframes toc-close { + 0% { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } + 100% { + -webkit-transform: scale(0.7); + -moz-transform: scale(0.7); + -o-transform: scale(0.7); + -ms-transform: scale(0.7); + transform: scale(0.7); + } +} +@-o-keyframes toc-close { + 0% { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } + 100% { + -webkit-transform: scale(0.7); + -moz-transform: scale(0.7); + -o-transform: scale(0.7); + -ms-transform: scale(0.7); + transform: scale(0.7); + } +} +@keyframes toc-close { + 0% { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + } + 100% { + -webkit-transform: scale(0.7); + -moz-transform: scale(0.7); + -o-transform: scale(0.7); + -ms-transform: scale(0.7); + transform: scale(0.7); + } +} +#post-comment .comment-head { + margin-bottom: 20px; +} +#post-comment .comment-head:after { + display: block; + clear: both; + content: ''; +} +#post-comment .comment-head .comment-headline { + display: inline-block; + vertical-align: middle; + font-weight: 700; + font-size: 1.43em; +} +#post-comment .comment-head .comment-switch { + display: inline-block; + float: right; + margin: 2px auto 0; + padding: 4px 16px; + width: max-content; + border-radius: 8px; + background: #f6f8fa; +} +#post-comment .comment-head .comment-switch .first-comment { + color: #49b1f5; +} +#post-comment .comment-head .comment-switch .second-comment { + color: #ff7242; +} +#post-comment .comment-head .comment-switch #switch-btn { + position: relative; + display: inline-block; + margin: -4px 8px 0; + width: 42px; + height: 22px; + border-radius: 34px; + background-color: #49b1f5; + vertical-align: middle; + cursor: pointer; + -webkit-transition: 0.4s; + -moz-transition: 0.4s; + -o-transition: 0.4s; + -ms-transition: 0.4s; + transition: 0.4s; +} +#post-comment .comment-head .comment-switch #switch-btn:before { + position: absolute; + bottom: 4px; + left: 4px; + width: 14px; + height: 14px; + border-radius: 50%; + background-color: #fff; + content: ''; + -webkit-transition: 0.4s; + -moz-transition: 0.4s; + -o-transition: 0.4s; + -ms-transition: 0.4s; + transition: 0.4s; +} +#post-comment .comment-wrap > div { + -webkit-animation: tabshow 0.5s; + -moz-animation: tabshow 0.5s; + -o-animation: tabshow 0.5s; + -ms-animation: tabshow 0.5s; + animation: tabshow 0.5s; +} +#post-comment .comment-wrap > div:nth-child(2) { + display: none; +} +#post-comment.move #switch-btn { + background-color: #ff7242; +} +#post-comment.move #switch-btn:before { + -webkit-transform: translateX(20px); + -moz-transform: translateX(20px); + -o-transform: translateX(20px); + -ms-transform: translateX(20px); + transform: translateX(20px); +} +#post-comment.move .comment-wrap > div:first-child { + display: none; +} +#post-comment.move .comment-wrap > div:last-child { + display: block; +} +#footer { + position: relative; + background-color: #49b1f5; + background-attachment: scroll; + background-position: bottom; + background-size: cover; +} +#footer-wrap { + position: relative; + padding: 40px 20px; + color: var(--light-grey); + text-align: center; +} +#footer-wrap a { + color: var(--light-grey); +} +#footer-wrap a:hover { + text-decoration: underline; +} +#footer-wrap .footer-separator { + margin: 0 4px; +} +#footer-wrap .icp-icon { + padding: 0 4px; + max-height: 1.4em; + width: auto; + vertical-align: text-bottom; +} +#page-header { + position: relative; + width: 100%; + background-color: #49b1f5; + background-position: center center; + background-size: cover; + background-repeat: no-repeat; + -webkit-transition: all 0.5s; + -moz-transition: all 0.5s; + -o-transition: all 0.5s; + -ms-transition: all 0.5s; + transition: all 0.5s; +} +#page-header:not(.not-top-img):before { + position: absolute; + width: 100%; + height: 100%; + background-color: var(--mark-bg); + content: ''; +} +#page-header.full_page { + height: 100vh; + background-attachment: fixed; +} +#page-header.full_page #site-info { + position: absolute; + top: 43%; + padding: 0 10px; + width: 100%; +} +#page-header #site-title, +#page-header #site-subtitle, +#page-header #scroll-down .scroll-down-effects { + text-align: center; + text-shadow: 2px 2px 4px rgba(0,0,0,0.15); + line-height: 1.5; +} +#page-header #site-title { + margin: 0; + color: var(--white); + font-size: 1.85em; +} +@media screen and (min-width: 768px) { + #page-header #site-title { + font-size: 2.85em; + } +} +#page-header #site-subtitle { + color: var(--light-grey); + font-size: 1.15em; +} +@media screen and (min-width: 768px) { + #page-header #site-subtitle { + font-size: 1.72em; + } +} +#page-header #site_social_icons { + display: none; + margin: 0 auto; + text-align: center; +} +@media screen and (max-width: 768px) { + #page-header #site_social_icons { + display: block; + } +} +#page-header #site_social_icons .social-icon { + margin: 0 10px; + color: var(--light-grey); + text-shadow: 2px 2px 4px rgba(0,0,0,0.15); + font-size: 1.43em; +} +#page-header #scroll-down { + position: absolute; + bottom: 10px; + width: 100%; + cursor: pointer; +} +#page-header #scroll-down .scroll-down-effects { + position: relative; + width: 100%; + color: var(--light-grey); + font-size: 20px; +} +#page-header.not-home-page { + height: 400px; +} +@media screen and (max-width: 768px) { + #page-header.not-home-page { + height: 280px; + } +} +#page-header #page-site-info { + position: absolute; + top: 200px; + padding: 0 10px; + width: 100%; +} +@media screen and (max-width: 768px) { + #page-header #page-site-info { + top: 140px; + } +} +#page-header.post-bg { + height: 400px; +} +@media screen and (max-width: 768px) { + #page-header.post-bg { + height: 360px; + } +} +#page-header #post-info { + position: absolute; + bottom: 100px; + padding: 0 8%; + width: 100%; + text-align: center; +} +@media screen and (max-width: 900px) { + #page-header #post-info { + bottom: 30px; + text-align: left; + } +} +@media screen and (max-width: 768px) { + #page-header #post-info { + bottom: 22px; + padding: 0 22px; + } +} +#page-header.not-top-img { + margin-bottom: 10px; + height: 60px; + background: 0; +} +#page-header.not-top-img #nav { + background: rgba(255,255,255,0.8); + -webkit-box-shadow: 0 5px 6px -5px rgba(133,133,133,0.6); + box-shadow: 0 5px 6px -5px rgba(133,133,133,0.6); +} +#page-header.not-top-img #nav a, +#page-header.not-top-img #nav .site-name { + color: var(--font-color); + text-shadow: none; +} +#page-header.nav-fixed #nav { + position: fixed; + top: -60px; + z-index: 91; + background: rgba(255,255,255,0.8); + -webkit-box-shadow: 0 5px 6px -5px rgba(133,133,133,0.6); + box-shadow: 0 5px 6px -5px rgba(133,133,133,0.6); + -webkit-transition: -webkit-transform 0.2s ease-in-out, opacity 0.2s ease-in-out; + -moz-transition: -moz-transform 0.2s ease-in-out, opacity 0.2s ease-in-out; + -o-transition: -o-transform 0.2s ease-in-out, opacity 0.2s ease-in-out; + -ms-transition: -ms-transform 0.2s ease-in-out, opacity 0.2s ease-in-out; + transition: transform 0.2s ease-in-out, opacity 0.2s ease-in-out; +} +#page-header.nav-fixed #nav #blog-info { + color: var(--font-color); +} +#page-header.nav-fixed #nav #blog-info:hover { + color: #49b1f5; +} +#page-header.nav-fixed #nav #blog-info .site-name { + text-shadow: none; +} +#page-header.nav-fixed #nav a, +#page-header.nav-fixed #nav #toggle-menu { + color: var(--font-color); + text-shadow: none; +} +#page-header.nav-fixed #nav a:hover, +#page-header.nav-fixed #nav #toggle-menu:hover { + color: #49b1f5; +} +#page-header.nav-fixed.fixed #nav { + top: 0; + -webkit-transition: all 0.5s; + -moz-transition: all 0.5s; + -o-transition: all 0.5s; + -ms-transition: all 0.5s; + transition: all 0.5s; +} +#page-header.nav-visible:not(.fixed) #nav { + -webkit-transition: all 0.5s; + -moz-transition: all 0.5s; + -o-transition: all 0.5s; + -ms-transition: all 0.5s; + transition: all 0.5s; + -webkit-transform: translate3d(0, 100%, 0); + -moz-transform: translate3d(0, 100%, 0); + -o-transform: translate3d(0, 100%, 0); + -ms-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); +} +#page-header.nav-visible:not(.fixed) + .layout > .aside-content > .sticky_layout { + top: 70px; + -webkit-transition: top 0.5s; + -moz-transition: top 0.5s; + -o-transition: top 0.5s; + -ms-transition: top 0.5s; + transition: top 0.5s; +} +#page-header.fixed #nav { + position: fixed; +} +#page-header.fixed + .layout > .aside-content > .sticky_layout { + top: 70px; + -webkit-transition: top 0.5s; + -moz-transition: top 0.5s; + -o-transition: top 0.5s; + -ms-transition: top 0.5s; + transition: top 0.5s; +} +#page-header.fixed + .layout #card-toc .toc-content { + max-height: calc(100vh - 170px); +} +#page h1.page-title { + margin: 8px 0 20px; +} +#post > #post-info { + margin-bottom: 30px; +} +#post > #post-info .post-title { + padding-bottom: 4px; + border-bottom: 1px solid var(--light-grey); + color: var(--text-highlight-color); +} +#post > #post-info .post-title .post-edit-link { + float: right; +} +#post > #post-info #post-meta, +#post > #post-info #post-meta a { + color: #78818a; +} +#post-info .post-title { + margin-bottom: 8px; + color: var(--white); + font-weight: normal; + font-size: 2.5em; + line-height: 1.5; + -webkit-line-clamp: 3; +} +@media screen and (max-width: 768px) { + #post-info .post-title { + font-size: 2.1em; + } +} +#post-info .post-title .post-edit-link { + padding-left: 10px; +} +#post-info #post-meta { + color: var(--light-grey); + font-size: 95%; +} +@media screen and (min-width: 768px) { + #post-info #post-meta > .meta-secondline > span:first-child { + display: none; + } +} +@media screen and (max-width: 768px) { + #post-info #post-meta { + font-size: 90%; + } + #post-info #post-meta > .meta-firstline, + #post-info #post-meta > .meta-secondline { + display: inline; + } +} +#post-info #post-meta .post-meta-separator { + margin: 0 5px; +} +#post-info #post-meta .post-meta-icon { + margin-right: 4px; +} +#post-info #post-meta .post-meta-label { + margin-right: 4px; +} +#post-info #post-meta a { + color: var(--light-grey); + -webkit-transition: all 0.3s ease-out; + -moz-transition: all 0.3s ease-out; + -o-transition: all 0.3s ease-out; + -ms-transition: all 0.3s ease-out; + transition: all 0.3s ease-out; +} +#post-info #post-meta a:hover { + color: #49b1f5; + text-decoration: underline; +} +#nav { + position: absolute; + top: 0; + z-index: 90; + display: -webkit-box; + display: -moz-box; + display: -webkit-flex; + display: -ms-flexbox; + display: box; + display: flex; + -webkit-box-align: center; + -moz-box-align: center; + -o-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + padding: 0 36px; + width: 100%; + height: 60px; + font-size: 1.3em; + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transition: all 0.5s; + -moz-transition: all 0.5s; + -o-transition: all 0.5s; + -ms-transition: all 0.5s; + transition: all 0.5s; +} +@media screen and (max-width: 768px) { + #nav { + padding: 0 16px; + } +} +#nav.show { + opacity: 1; + -ms-filter: none; + filter: none; +} +#nav #blog-info { + -webkit-box-flex: 1; + -moz-box-flex: 1; + -o-box-flex: 1; + box-flex: 1; + -webkit-flex: 1; + -ms-flex: 1; + flex: 1; + color: var(--light-grey); +} +#nav #blog-info .site-icon { + margin-right: 6px; + height: 36px; + vertical-align: middle; +} +#nav #toggle-menu { + display: none; + padding: 2px 0 0 6px; + vertical-align: top; +} +#nav #toggle-menu:hover { + color: var(--white); +} +#nav a { + color: var(--light-grey); +} +#nav a:hover { + color: var(--white); +} +#nav .site-name { + text-shadow: 2px 2px 4px rgba(0,0,0,0.15); + font-weight: bold; +} +#nav .menus_items { + display: inline; +} +#nav .menus_items .menus_item { + position: relative; + display: inline-block; + padding: 0 0 0 14px; +} +#nav .menus_items .menus_item:hover .menus_item_child { + display: block; +} +#nav .menus_items .menus_item:hover > a > i:last-child { + -webkit-transform: rotate(180deg); + -moz-transform: rotate(180deg); + -o-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg); +} +#nav .menus_items .menus_item > a > i:last-child { + padding: 4px; + -webkit-transition: -webkit-transform 0.3s; + -moz-transition: -moz-transform 0.3s; + -o-transition: -o-transform 0.3s; + -ms-transition: -ms-transform 0.3s; + transition: transform 0.3s; +} +#nav .menus_items .menus_item .menus_item_child { + position: absolute; + right: 0; + display: none; + margin-top: 8px; + padding: 0; + width: max-content; + border-radius: 5px; + background-color: var(--sidebar-bg); + -webkit-box-shadow: 0 5px 20px -4px rgba(0,0,0,0.5); + box-shadow: 0 5px 20px -4px rgba(0,0,0,0.5); + -webkit-animation: sub_menus 0.3s 0.1s ease both; + -moz-animation: sub_menus 0.3s 0.1s ease both; + -o-animation: sub_menus 0.3s 0.1s ease both; + -ms-animation: sub_menus 0.3s 0.1s ease both; + animation: sub_menus 0.3s 0.1s ease both; +} +#nav .menus_items .menus_item .menus_item_child:before { + position: absolute; + top: -8px; + left: 0; + width: 100%; + height: 20px; + content: ''; +} +#nav .menus_items .menus_item .menus_item_child li { + list-style: none; +} +#nav .menus_items .menus_item .menus_item_child li:hover { + background: var(--text-bg-hover); +} +#nav .menus_items .menus_item .menus_item_child li:first-child { + border-top-left-radius: 5px; + border-top-right-radius: 5px; +} +#nav .menus_items .menus_item .menus_item_child li:last-child { + border-bottom-right-radius: 5px; + border-bottom-left-radius: 5px; +} +#nav .menus_items .menus_item .menus_item_child li a { + display: inline-block; + padding: 8px 16px; + width: 100%; + color: var(--font-color) !important; + text-shadow: none !important; +} +#nav.hide-menu #toggle-menu { + display: inline-block !important; +} +#nav.hide-menu #toggle-menu .site-page { + font-size: inherit; +} +#nav.hide-menu .menus_items { + display: none; +} +#nav.hide-menu #search-button span { + display: none; +} +#nav #search-button { + display: inline; + padding: 0 0 0 14px; +} +#nav .site-page { + position: relative; + padding-bottom: 6px; + text-shadow: 1px 1px 2px rgba(0,0,0,0.3); + font-size: 0.78em; + cursor: pointer; +} +#nav .site-page:not(.child):after { + position: absolute; + bottom: 0; + left: 0; + z-index: -1; + width: 0; + height: 3px; + background-color: #80c8f8; + content: ''; + -webkit-transition: all 0.3s ease-in-out; + -moz-transition: all 0.3s ease-in-out; + -o-transition: all 0.3s ease-in-out; + -ms-transition: all 0.3s ease-in-out; + transition: all 0.3s ease-in-out; +} +#nav .site-page:not(.child):hover:after { + width: 100%; +} +#pagination .pagination { + margin-top: 20px; + text-align: center; +} +#pagination .page-number.current { + background: #00c4b6; + color: var(--white); +} +#pagination .pagination-info { + position: absolute; + top: 50%; + padding: 20px 40px; + width: 100%; + -webkit-transform: translate(0, -50%); + -moz-transform: translate(0, -50%); + -o-transform: translate(0, -50%); + -ms-transform: translate(0, -50%); + transform: translate(0, -50%); +} +#pagination .prev_info, +#pagination .next_info { + color: var(--white); + font-weight: 500; +} +#pagination .next-post .pagination-info { + text-align: right; +} +#pagination .pull-full { + width: 100% !important; +} +#pagination .prev-post .label, +#pagination .next-post .label { + color: var(--light-grey); + text-transform: uppercase; + font-size: 90%; +} +#pagination .prev-post, +#pagination .next-post { + width: 50%; +} +@media screen and (max-width: 768px) { + #pagination .prev-post, + #pagination .next-post { + width: 100%; + } +} +#pagination .prev-post a, +#pagination .next-post a { + position: relative; + display: block; + overflow: hidden; + height: 150px; +} +#pagination.pagination-post { + overflow: hidden; + margin-top: 40px; + width: 100%; + background: #000; +} +.layout > .recent-posts .pagination > * { + display: inline-block; + margin: 0 6px; + width: 2.5em; + height: 2.5em; + line-height: 2.5em; +} +.layout > .recent-posts .pagination > *:not(.space):hover { + background: var(--btn-hover-color); + color: var(--btn-color); +} +.layout > div:not(.recent-posts) .pagination .page-number { + display: inline-block; + margin: 0 4px; + min-width: 24px; + height: 24px; + text-align: center; + line-height: 24px; + cursor: pointer; +} +#article-container { + word-wrap: break-word; + overflow-wrap: break-word; +} +#article-container a { + color: #49b1f5; +} +#article-container a:hover { + text-decoration: underline; +} +#article-container img { + display: block; + margin: 0 auto 20px; + max-width: 100%; + -webkit-transition: filter 375ms ease-in 0.2s; + -moz-transition: filter 375ms ease-in 0.2s; + -o-transition: filter 375ms ease-in 0.2s; + -ms-transition: filter 375ms ease-in 0.2s; + transition: filter 375ms ease-in 0.2s; +} +#article-container p { + margin: 0 0 16px; +} +#article-container iframe { + margin: 0 0 20px; +} +#article-container kbd { + margin: 0 3px; + padding: 3px 5px; + border: 1px solid #b4b4b4; + border-radius: 3px; + background-color: #f8f8f8; + -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.25), 0 2px 1px 0 rgba(255,255,255,0.6) inset; + box-shadow: 0 1px 3px rgba(0,0,0,0.25), 0 2px 1px 0 rgba(255,255,255,0.6) inset; + color: #34495e; + white-space: nowrap; + font-weight: 600; + font-size: 0.9em; + font-family: Monaco, 'Ubuntu Mono', monospace; + line-height: 1em; +} +#article-container ol ol, +#article-container ul ol, +#article-container ol ul, +#article-container ul ul { + padding-left: 20px; +} +#article-container ol li, +#article-container ul li { + margin: 4px 0; +} +#article-container ol p, +#article-container ul p { + margin: 0 0 8px; +} +#article-container > :last-child { + margin-bottom: 0 !important; +} +#article-container hr { + margin: 20px 0; +} +#post .tag_share:after { + display: block; + clear: both; + content: ''; +} +#post .tag_share .post-meta__tag-list { + display: inline-block; +} +#post .tag_share .post-meta__tags { + display: inline-block; + margin: 8px 8px 8px 0; + padding: 0 12px; + width: fit-content; + border: 1px solid #49b1f5; + border-radius: 12px; + color: #49b1f5; + font-size: 0.85em; + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + -ms-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} +#post .tag_share .post-meta__tags:hover { + background: #49b1f5; + color: var(--white); +} +#post .tag_share .post_share { + display: inline-block; + float: right; + margin: 8px 0 0; + width: fit-content; +} +#post .tag_share .post_share .social-share { + font-size: 0.85em; +} +#post .tag_share .post_share .social-share .social-share-icon { + margin: 0 4px; + width: 1.85em; + height: 1.85em; + font-size: 1.2em; + line-height: 1.85em; +} +#post .post-copyright { + position: relative; + margin: 40px 0 10px; + padding: 10px 16px; + border: 1px solid var(--light-grey); + -webkit-transition: box-shadow 0.3s ease-in-out; + -moz-transition: box-shadow 0.3s ease-in-out; + -o-transition: box-shadow 0.3s ease-in-out; + -ms-transition: box-shadow 0.3s ease-in-out; + transition: box-shadow 0.3s ease-in-out; +} +#post .post-copyright:before { + position: absolute; + top: 2px; + right: 12px; + color: #49b1f5; + content: '\f1f9'; + font-size: 1.3em; +} +#post .post-copyright:hover { + -webkit-box-shadow: 0 0 8px 0 rgba(232,237,250,0.6), 0 2px 4px 0 rgba(232,237,250,0.5); + box-shadow: 0 0 8px 0 rgba(232,237,250,0.6), 0 2px 4px 0 rgba(232,237,250,0.5); +} +#post .post-copyright .post-copyright-meta { + color: #49b1f5; + font-weight: bold; +} +#post .post-copyright .post-copyright-meta i { + margin-right: 3px; +} +#post .post-copyright .post-copyright-info { + padding-left: 6px; +} +#post .post-copyright .post-copyright-info a { + text-decoration: underline; + word-break: break-word; +} +#post .post-copyright .post-copyright-info a:hover { + text-decoration: none; +} +#post .post-outdate-notice { + position: relative; + margin: 0 0 20px; + padding: 0.5em 1.2em; + border-radius: 3px; + background-color: #ffe6e6; + color: #f66; + padding: 0.5em 1em 0.5em 2.6em; + border-left: 5px solid #ff8080; +} +#post .post-outdate-notice:before { + position: absolute; + top: 50%; + left: 0.9em; + color: #ff8080; + content: '\f071'; + -webkit-transform: translateY(-50%); + -moz-transform: translateY(-50%); + -o-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); +} +#post .ads-wrap { + margin: 40px 0; +} +.relatedPosts { + margin-top: 40px; +} +.relatedPosts > .headline { + margin-bottom: 5px; + font-weight: 700; + font-size: 1.43em; +} +.relatedPosts > .relatedPosts-list > div { + position: relative; + display: inline-block; + overflow: hidden; + margin: 3px; + width: calc(33.333% - 6px); + height: 200px; + background: #000; + vertical-align: bottom; +} +@media screen and (max-width: 768px) { + .relatedPosts > .relatedPosts-list > div { + margin: 2px; + width: calc(50% - 4px); + height: 150px; + } +} +@media screen and (max-width: 600px) { + .relatedPosts > .relatedPosts-list > div { + width: calc(100% - 4px); + } +} +.relatedPosts > .relatedPosts-list .content { + position: absolute; + top: 50%; + padding: 0 20px; + width: 100%; + -webkit-transform: translate(0, -50%); + -moz-transform: translate(0, -50%); + -o-transform: translate(0, -50%); + -ms-transform: translate(0, -50%); + transform: translate(0, -50%); +} +.relatedPosts > .relatedPosts-list .content .date { + color: var(--light-grey); + font-size: 90%; +} +.relatedPosts > .relatedPosts-list .content .title { + color: var(--white); + -webkit-line-clamp: 2; +} +.post-reward { + position: relative; + margin-top: 80px; + width: 100%; + text-align: center; + pointer-events: none; +} +.post-reward > * { + pointer-events: auto; +} +.post-reward .reward-button { + display: inline-block; + padding: 4px 24px; + background: var(--btn-bg); + color: var(--btn-color); + cursor: pointer; +} +.post-reward .reward-button i { + margin-right: 5px; +} +.post-reward:hover .reward-button { + background: var(--btn-hover-color); +} +.post-reward:hover > .reward-main { + display: block; +} +.post-reward .reward-main { + position: absolute; + bottom: 40px; + left: 0; + z-index: 100; + display: none; + padding: 0 0 15px; + width: 100%; +} +.post-reward .reward-main .reward-all { + display: inline-block; + margin: 0; + padding: 20px 10px; + border-radius: 4px; + background: var(--reward-pop); +} +.post-reward .reward-main .reward-all:before { + position: absolute; + bottom: -10px; + left: 0; + width: 100%; + height: 20px; + content: ''; +} +.post-reward .reward-main .reward-all:after { + position: absolute; + right: 0; + bottom: 2px; + left: 0; + margin: 0 auto; + width: 0; + height: 0; + border-top: 13px solid var(--reward-pop); + border-right: 13px solid transparent; + border-left: 13px solid transparent; + content: ''; +} +.post-reward .reward-main .reward-all .reward-item { + display: inline-block; + padding: 0 8px; + list-style-type: none; + vertical-align: top; +} +.post-reward .reward-main .reward-all .reward-item img { + width: 130px; + height: 130px; +} +.post-reward .reward-main .reward-all .reward-item .post-qr-code-desc { + width: 130px; + color: #858585; +} +#rightside { + position: fixed; + right: -48px; + bottom: 40px; + z-index: 100; + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transition: all 0.5s; + -moz-transition: all 0.5s; + -o-transition: all 0.5s; + -ms-transition: all 0.5s; + transition: all 0.5s; +} +#rightside.rightside-show { + opacity: 0.8; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)"; + filter: alpha(opacity=80); + -webkit-transform: translate(-58px, 0); + -moz-transform: translate(-58px, 0); + -o-transform: translate(-58px, 0); + -ms-transform: translate(-58px, 0); + transform: translate(-58px, 0); +} +#rightside #rightside-config-hide { + height: 0; + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transition: -webkit-transform 0.4s; + -moz-transition: -moz-transform 0.4s; + -o-transition: -o-transform 0.4s; + -ms-transition: -ms-transform 0.4s; + transition: transform 0.4s; + -webkit-transform: translate(45px, 0); + -moz-transform: translate(45px, 0); + -o-transform: translate(45px, 0); + -ms-transform: translate(45px, 0); + transform: translate(45px, 0); +} +#rightside #rightside-config-hide.show { + height: auto; + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: translate(0, 0); + -moz-transform: translate(0, 0); + -o-transform: translate(0, 0); + -ms-transform: translate(0, 0); + transform: translate(0, 0); +} +#rightside #rightside-config-hide.status { + height: auto; + opacity: 1; + -ms-filter: none; + filter: none; +} +#rightside > div > button, +#rightside > div > a { + display: block; + margin-bottom: 5px; + width: 35px; + height: 35px; + border-radius: 5px; + background-color: var(--btn-bg); + color: var(--btn-color); + text-align: center; + font-size: 16px; + line-height: 35px; +} +#rightside > div > button:hover, +#rightside > div > a:hover { + background-color: var(--btn-hover-color); +} +#rightside #mobile-toc-button { + display: none; +} +@media screen and (max-width: 900px) { + #rightside #mobile-toc-button { + display: block; + } +} +@media screen and (max-width: 900px) { + #rightside #hide-aside-btn { + display: none; + } +} +#sidebar #menu-mask { + position: fixed; + z-index: 102; + display: none; + width: 100%; + height: 100%; + background: rgba(0,0,0,0.8); +} +#sidebar #sidebar-menus { + position: fixed; + top: 0; + right: -300px; + z-index: 103; + overflow-x: hidden; + overflow-y: scroll; + padding-left: 5px; + width: 300px; + height: 100%; + background: var(--sidebar-bg); + -webkit-transition: all 0.5s; + -moz-transition: all 0.5s; + -o-transition: all 0.5s; + -ms-transition: all 0.5s; + transition: all 0.5s; +} +#sidebar #sidebar-menus.open { + -webkit-transform: translate3d(-100%, 0, 0); + -moz-transform: translate3d(-100%, 0, 0); + -o-transform: translate3d(-100%, 0, 0); + -ms-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); +} +#sidebar #sidebar-menus > .avatar-img { + margin: 20px auto; +} +#sidebar #sidebar-menus .sidebar-site-data { + padding: 0 10px; +} +#sidebar #sidebar-menus hr { + margin: 20px auto; +} +#sidebar #sidebar-menus .menus_items { + padding: 0 5px; +} +#sidebar #sidebar-menus .menus_items .site-page { + position: relative; + display: block; + padding: 6px 30px 6px 22px; + color: var(--font-color); + font-size: 1.15em; +} +#sidebar #sidebar-menus .menus_items .site-page:hover { + background: var(--text-bg-hover); +} +#sidebar #sidebar-menus .menus_items .site-page i:first-child { + width: 15%; + text-align: left; +} +#sidebar #sidebar-menus .menus_items .site-page.group > i:last-child { + position: absolute; + top: 0.78em; + right: 13px; + -webkit-transition: -webkit-transform 0.3s; + -moz-transition: -moz-transform 0.3s; + -o-transition: -o-transform 0.3s; + -ms-transition: -ms-transform 0.3s; + transition: transform 0.3s; +} +#sidebar #sidebar-menus .menus_items .site-page.group.hide > i:last-child { + -webkit-transform: rotate(90deg); + -moz-transform: rotate(90deg); + -o-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg); +} +#sidebar #sidebar-menus .menus_items .site-page.group.hide + .menus_item_child { + display: none; +} +#sidebar #sidebar-menus .menus_items .menus_item_child { + margin: 0; + padding-left: 25px; + list-style: none; +} +#vcomment { + font-size: 1.1em; +} +#vcomment .vbtn { + border: none; + background: var(--btn-bg); + color: var(--btn-color); +} +#vcomment .vbtn:hover { + background: var(--btn-hover-color); +} +#vcomment .vimg { + -webkit-transition: all 0.3s; + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -ms-transition: all 0.3s; + transition: all 0.3s; +} +#vcomment .vimg:hover { + -webkit-transform: rotate(360deg); + -moz-transform: rotate(360deg); + -o-transform: rotate(360deg); + -ms-transform: rotate(360deg); + transform: rotate(360deg); +} +#vcomment .vcards .vcard .vcontent.expand:before, +#vcomment .vcards .vcard .vcontent.expand:after { + z-index: 22; +} +#waline-wrap { + --waline-font-size: 1.1em; + --waline-theme-color: #49b1f5; + --waline-active-color: #ff7242; +} +#waline-wrap .wl-comment-actions > button:not(last-child) { + padding-right: 4px; +} +.fireworks { + position: fixed; + top: 0; + left: 0; + z-index: 9999; + pointer-events: none; +} +.medium-zoom-image--opened { + z-index: 99999 !important; + margin: 0 !important; +} +.medium-zoom-overlay { + z-index: 99999 !important; +} +.mermaid-wrap { + margin: 0 0 20px; + text-align: center; +} +.mermaid-wrap > svg { + height: 100%; +} +.utterances, +.fb-comments iframe { + width: 100% !important; +} +#gitalk-container .gt-meta { + margin: 0 0 0.8em; + padding: 6px 0 16px; +} +.katex-wrap { + overflow: auto; +} +.katex-wrap::-webkit-scrollbar { + display: none; +} +mjx-container { + overflow-x: auto; + overflow-y: hidden; + padding-bottom: 4px; + max-width: 100%; +} +mjx-container[display] { + display: block !important; + min-width: auto !important; +} +mjx-container:not([display]) { + display: inline-grid !important; +} +mjx-assistive-mml { + right: 0; + bottom: 0; +} +.aplayer { + color: #4c4948; +} +#article-container .aplayer { + margin: 0 0 20px; +} +.snackbar-css { + border-radius: 5px !important; +} +.abc-music-sheet { + margin: 0 0 20px; + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transition: opacity 0.3s; + -moz-transition: opacity 0.3s; + -o-transition: opacity 0.3s; + -ms-transition: opacity 0.3s; + transition: opacity 0.3s; +} +.abc-music-sheet.abcjs-container { + opacity: 1; + -ms-filter: none; + filter: none; +} +@media screen and (max-width: 768px) { + .fancybox__toolbar__column.is-middle { + display: none; + } +} +#article-container .btn-center { + margin: 0 0 20px; + text-align: center; +} +#article-container .btn-beautify { + display: inline-block; + margin: 0 4px 6px; + padding: 0 15px; + background-color: var(--btn-beautify-color, #777); + color: #fff; + line-height: 2; +} +#article-container .btn-beautify.blue { + --btn-beautify-color: #428bca; +} +#article-container .btn-beautify.pink { + --btn-beautify-color: #ff69b4; +} +#article-container .btn-beautify.red { + --btn-beautify-color: #f00; +} +#article-container .btn-beautify.purple { + --btn-beautify-color: #6f42c1; +} +#article-container .btn-beautify.orange { + --btn-beautify-color: #ff8c00; +} +#article-container .btn-beautify.green { + --btn-beautify-color: #5cb85c; +} +#article-container .btn-beautify:hover { + background-color: var(--btn-hover-color); +} +#article-container .btn-beautify i + span { + margin-left: 6px; +} +#article-container .btn-beautify:not(.block) + .btn-beautify:not(.block) { + margin: 0 4px 20px; +} +#article-container .btn-beautify.block { + display: block; + margin: 0 0 20px; + width: fit-content; + width: -moz-fit-content; +} +#article-container .btn-beautify.block.center { + margin: 0 auto 20px; +} +#article-container .btn-beautify.block.right { + margin: 0 0 20px auto; +} +#article-container .btn-beautify.larger { + padding: 6px 15px; +} +#article-container .btn-beautify:hover { + text-decoration: none; +} +#article-container .btn-beautify.outline { + border: 1px solid transparent; + border-color: var(--btn-beautify-color, #777); + background-color: transparent; + color: var(--btn-beautify-color, #777); +} +#article-container .btn-beautify.outline:hover { + background-color: var(--btn-beautify-color, #777); +} +#article-container .btn-beautify.outline:hover { + color: #fff !important; +} +#article-container figure.gallery-group { + position: relative; + float: left; + overflow: hidden; + margin: 6px 4px; + width: calc(50% - 8px); + height: 250px; + border-radius: 8px; + background: #000; + -webkit-transform: translate3d(0, 0, 0); +} +@media screen and (max-width: 600px) { + #article-container figure.gallery-group { + width: calc(100% - 8px); + } +} +#article-container figure.gallery-group:hover img { + opacity: 0.4; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)"; + filter: alpha(opacity=40); + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + -o-transform: translate3d(0, 0, 0); + -ms-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +#article-container figure.gallery-group:hover .gallery-group-name::after { + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + -o-transform: translate3d(0, 0, 0); + -ms-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +#article-container figure.gallery-group:hover p { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + -o-transform: translate3d(0, 0, 0); + -ms-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +#article-container figure.gallery-group img { + position: relative; + margin: 0; + max-width: none; + width: calc(100% + 20px); + height: 250px; + -webkit-backface-visibility: hidden; + -moz-backface-visibility: hidden; + -ms-backface-visibility: hidden; + backface-visibility: hidden; + opacity: 0.8; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)"; + filter: alpha(opacity=80); + -webkit-transition: all 0.3s, filter 375ms ease-in 0.2s; + -moz-transition: all 0.3s, filter 375ms ease-in 0.2s; + -o-transition: all 0.3s, filter 375ms ease-in 0.2s; + -ms-transition: all 0.3s, filter 375ms ease-in 0.2s; + transition: all 0.3s, filter 375ms ease-in 0.2s; + -webkit-transform: translate3d(-10px, 0, 0); + -moz-transform: translate3d(-10px, 0, 0); + -o-transform: translate3d(-10px, 0, 0); + -ms-transform: translate3d(-10px, 0, 0); + transform: translate3d(-10px, 0, 0); + object-fit: cover; +} +#article-container figure.gallery-group figcaption { + position: absolute; + top: 0; + left: 0; + padding: 30px; + width: 100%; + height: 100%; + color: #fff; + text-transform: uppercase; + -webkit-backface-visibility: hidden; + -moz-backface-visibility: hidden; + -ms-backface-visibility: hidden; + backface-visibility: hidden; +} +#article-container figure.gallery-group figcaption > a { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1000; + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); +} +#article-container figure.gallery-group p { + margin: 0; + padding: 8px 0 0; + letter-spacing: 1px; + font-size: 1.1em; + line-height: 1.5; + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transition: opacity 0.35s, -webkit-transform 0.35s; + -moz-transition: opacity 0.35s, -moz-transform 0.35s; + -o-transition: opacity 0.35s, -o-transform 0.35s; + -ms-transition: opacity 0.35s, -ms-transform 0.35s; + transition: opacity 0.35s, transform 0.35s; + -webkit-transform: translate3d(100%, 0, 0); + -moz-transform: translate3d(100%, 0, 0); + -o-transform: translate3d(100%, 0, 0); + -ms-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + -webkit-line-clamp: 4; +} +#article-container figure.gallery-group .gallery-group-name { + position: relative; + margin: 0; + padding: 8px 0; + font-weight: bold; + font-size: 1.65em; + line-height: 1.5; + -webkit-line-clamp: 2; +} +#article-container figure.gallery-group .gallery-group-name:after { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 2px; + background: #fff; + content: ''; + -webkit-transition: -webkit-transform 0.35s; + -moz-transition: -moz-transform 0.35s; + -o-transition: -o-transform 0.35s; + -ms-transition: -ms-transform 0.35s; + transition: transform 0.35s; + -webkit-transform: translate3d(-100%, 0, 0); + -moz-transform: translate3d(-100%, 0, 0); + -o-transform: translate3d(-100%, 0, 0); + -ms-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); +} +#article-container .gallery-group-main { + overflow: auto; + padding: 0 0 16px; +} +#article-container .gallery-container { + margin: 0 0 16px; + text-align: center; +} +#article-container .gallery-container img { + display: initial; + margin: 0; + width: 100%; + height: 100%; +} +#article-container .gallery-container .gallery-data { + display: none; +} +#article-container .gallery-container button { + margin-top: 25px; + padding: 10px; + width: 9em; + border-radius: 5px; + background: var(--btn-bg); + color: var(--btn-color); + font-weight: bold; + font-size: 1.1em; + -webkit-transition: all 0.3s; + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -ms-transition: all 0.3s; + transition: all 0.3s; +} +#article-container .gallery-container button:hover { + background: var(--btn-hover-color); +} +#article-container .loading-container { + display: inline-block; + overflow: hidden; + width: 154px; + height: 154px; +} +#article-container .loading-container .loading-item { + position: relative; + width: 100%; + height: 100%; + -webkit-backface-visibility: hidden; + -moz-backface-visibility: hidden; + -ms-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-transform: translateZ(0) scale(1); + -moz-transform: translateZ(0) scale(1); + -o-transform: translateZ(0) scale(1); + -ms-transform: translateZ(0) scale(1); + transform: translateZ(0) scale(1); + -webkit-transform-origin: 0 0; + -moz-transform-origin: 0 0; + -o-transform-origin: 0 0; + -ms-transform-origin: 0 0; + transform-origin: 0 0; +} +#article-container .loading-container .loading-item div { + position: absolute; + width: 30.8px; + height: 30.8px; + border-radius: 50%; + background: #e15b64; + -webkit-transform: translate(61.6px, 61.6px) scale(1); + -moz-transform: translate(61.6px, 61.6px) scale(1); + -o-transform: translate(61.6px, 61.6px) scale(1); + -ms-transform: translate(61.6px, 61.6px) scale(1); + transform: translate(61.6px, 61.6px) scale(1); + -webkit-animation: loading-ball 1.92s infinite cubic-bezier(0, 0.5, 0.5, 1); + -moz-animation: loading-ball 1.92s infinite cubic-bezier(0, 0.5, 0.5, 1); + -o-animation: loading-ball 1.92s infinite cubic-bezier(0, 0.5, 0.5, 1); + -ms-animation: loading-ball 1.92s infinite cubic-bezier(0, 0.5, 0.5, 1); + animation: loading-ball 1.92s infinite cubic-bezier(0, 0.5, 0.5, 1); +} +#article-container .loading-container .loading-item div:nth-child(1) { + background: #f47e60; + -webkit-transform: translate(113.96px, 61.6px) scale(1); + -moz-transform: translate(113.96px, 61.6px) scale(1); + -o-transform: translate(113.96px, 61.6px) scale(1); + -ms-transform: translate(113.96px, 61.6px) scale(1); + transform: translate(113.96px, 61.6px) scale(1); + -webkit-animation: loading-ball-r 0.48s infinite cubic-bezier(0, 0.5, 0.5, 1), loading-ball-c 1.92s infinite step-start; + -moz-animation: loading-ball-r 0.48s infinite cubic-bezier(0, 0.5, 0.5, 1), loading-ball-c 1.92s infinite step-start; + -o-animation: loading-ball-r 0.48s infinite cubic-bezier(0, 0.5, 0.5, 1), loading-ball-c 1.92s infinite step-start; + -ms-animation: loading-ball-r 0.48s infinite cubic-bezier(0, 0.5, 0.5, 1), loading-ball-c 1.92s infinite step-start; + animation: loading-ball-r 0.48s infinite cubic-bezier(0, 0.5, 0.5, 1), loading-ball-c 1.92s infinite step-start; +} +#article-container .loading-container .loading-item div:nth-child(2) { + background: #e15b64; + -webkit-animation-delay: -0.48s; + -moz-animation-delay: -0.48s; + -o-animation-delay: -0.48s; + -ms-animation-delay: -0.48s; + animation-delay: -0.48s; +} +#article-container .loading-container .loading-item div:nth-child(3) { + background: #f47e60; + -webkit-animation-delay: -0.96s; + -moz-animation-delay: -0.96s; + -o-animation-delay: -0.96s; + -ms-animation-delay: -0.96s; + animation-delay: -0.96s; +} +#article-container .loading-container .loading-item div:nth-child(4) { + background: #f8b26a; + -webkit-animation-delay: -1.44s; + -moz-animation-delay: -1.44s; + -o-animation-delay: -1.44s; + -ms-animation-delay: -1.44s; + animation-delay: -1.44s; +} +#article-container .loading-container .loading-item div:nth-child(5) { + background: #abbd81; + -webkit-animation-delay: -1.92s; + -moz-animation-delay: -1.92s; + -o-animation-delay: -1.92s; + -ms-animation-delay: -1.92s; + animation-delay: -1.92s; +} +@-moz-keyframes loading-ball { + 0% { + -webkit-transform: translate(9.24px, 61.6px) scale(0); + -moz-transform: translate(9.24px, 61.6px) scale(0); + -o-transform: translate(9.24px, 61.6px) scale(0); + -ms-transform: translate(9.24px, 61.6px) scale(0); + transform: translate(9.24px, 61.6px) scale(0); + } + 25% { + -webkit-transform: translate(9.24px, 61.6px) scale(0); + -moz-transform: translate(9.24px, 61.6px) scale(0); + -o-transform: translate(9.24px, 61.6px) scale(0); + -ms-transform: translate(9.24px, 61.6px) scale(0); + transform: translate(9.24px, 61.6px) scale(0); + } + 50% { + -webkit-transform: translate(9.24px, 61.6px) scale(1); + -moz-transform: translate(9.24px, 61.6px) scale(1); + -o-transform: translate(9.24px, 61.6px) scale(1); + -ms-transform: translate(9.24px, 61.6px) scale(1); + transform: translate(9.24px, 61.6px) scale(1); + } + 75% { + -webkit-transform: translate(61.6px, 61.6px) scale(1); + -moz-transform: translate(61.6px, 61.6px) scale(1); + -o-transform: translate(61.6px, 61.6px) scale(1); + -ms-transform: translate(61.6px, 61.6px) scale(1); + transform: translate(61.6px, 61.6px) scale(1); + } + 100% { + -webkit-transform: translate(113.96px, 61.6px) scale(1); + -moz-transform: translate(113.96px, 61.6px) scale(1); + -o-transform: translate(113.96px, 61.6px) scale(1); + -ms-transform: translate(113.96px, 61.6px) scale(1); + transform: translate(113.96px, 61.6px) scale(1); + } +} +@-webkit-keyframes loading-ball { + 0% { + -webkit-transform: translate(9.24px, 61.6px) scale(0); + -moz-transform: translate(9.24px, 61.6px) scale(0); + -o-transform: translate(9.24px, 61.6px) scale(0); + -ms-transform: translate(9.24px, 61.6px) scale(0); + transform: translate(9.24px, 61.6px) scale(0); + } + 25% { + -webkit-transform: translate(9.24px, 61.6px) scale(0); + -moz-transform: translate(9.24px, 61.6px) scale(0); + -o-transform: translate(9.24px, 61.6px) scale(0); + -ms-transform: translate(9.24px, 61.6px) scale(0); + transform: translate(9.24px, 61.6px) scale(0); + } + 50% { + -webkit-transform: translate(9.24px, 61.6px) scale(1); + -moz-transform: translate(9.24px, 61.6px) scale(1); + -o-transform: translate(9.24px, 61.6px) scale(1); + -ms-transform: translate(9.24px, 61.6px) scale(1); + transform: translate(9.24px, 61.6px) scale(1); + } + 75% { + -webkit-transform: translate(61.6px, 61.6px) scale(1); + -moz-transform: translate(61.6px, 61.6px) scale(1); + -o-transform: translate(61.6px, 61.6px) scale(1); + -ms-transform: translate(61.6px, 61.6px) scale(1); + transform: translate(61.6px, 61.6px) scale(1); + } + 100% { + -webkit-transform: translate(113.96px, 61.6px) scale(1); + -moz-transform: translate(113.96px, 61.6px) scale(1); + -o-transform: translate(113.96px, 61.6px) scale(1); + -ms-transform: translate(113.96px, 61.6px) scale(1); + transform: translate(113.96px, 61.6px) scale(1); + } +} +@-o-keyframes loading-ball { + 0% { + -webkit-transform: translate(9.24px, 61.6px) scale(0); + -moz-transform: translate(9.24px, 61.6px) scale(0); + -o-transform: translate(9.24px, 61.6px) scale(0); + -ms-transform: translate(9.24px, 61.6px) scale(0); + transform: translate(9.24px, 61.6px) scale(0); + } + 25% { + -webkit-transform: translate(9.24px, 61.6px) scale(0); + -moz-transform: translate(9.24px, 61.6px) scale(0); + -o-transform: translate(9.24px, 61.6px) scale(0); + -ms-transform: translate(9.24px, 61.6px) scale(0); + transform: translate(9.24px, 61.6px) scale(0); + } + 50% { + -webkit-transform: translate(9.24px, 61.6px) scale(1); + -moz-transform: translate(9.24px, 61.6px) scale(1); + -o-transform: translate(9.24px, 61.6px) scale(1); + -ms-transform: translate(9.24px, 61.6px) scale(1); + transform: translate(9.24px, 61.6px) scale(1); + } + 75% { + -webkit-transform: translate(61.6px, 61.6px) scale(1); + -moz-transform: translate(61.6px, 61.6px) scale(1); + -o-transform: translate(61.6px, 61.6px) scale(1); + -ms-transform: translate(61.6px, 61.6px) scale(1); + transform: translate(61.6px, 61.6px) scale(1); + } + 100% { + -webkit-transform: translate(113.96px, 61.6px) scale(1); + -moz-transform: translate(113.96px, 61.6px) scale(1); + -o-transform: translate(113.96px, 61.6px) scale(1); + -ms-transform: translate(113.96px, 61.6px) scale(1); + transform: translate(113.96px, 61.6px) scale(1); + } +} +@keyframes loading-ball { + 0% { + -webkit-transform: translate(9.24px, 61.6px) scale(0); + -moz-transform: translate(9.24px, 61.6px) scale(0); + -o-transform: translate(9.24px, 61.6px) scale(0); + -ms-transform: translate(9.24px, 61.6px) scale(0); + transform: translate(9.24px, 61.6px) scale(0); + } + 25% { + -webkit-transform: translate(9.24px, 61.6px) scale(0); + -moz-transform: translate(9.24px, 61.6px) scale(0); + -o-transform: translate(9.24px, 61.6px) scale(0); + -ms-transform: translate(9.24px, 61.6px) scale(0); + transform: translate(9.24px, 61.6px) scale(0); + } + 50% { + -webkit-transform: translate(9.24px, 61.6px) scale(1); + -moz-transform: translate(9.24px, 61.6px) scale(1); + -o-transform: translate(9.24px, 61.6px) scale(1); + -ms-transform: translate(9.24px, 61.6px) scale(1); + transform: translate(9.24px, 61.6px) scale(1); + } + 75% { + -webkit-transform: translate(61.6px, 61.6px) scale(1); + -moz-transform: translate(61.6px, 61.6px) scale(1); + -o-transform: translate(61.6px, 61.6px) scale(1); + -ms-transform: translate(61.6px, 61.6px) scale(1); + transform: translate(61.6px, 61.6px) scale(1); + } + 100% { + -webkit-transform: translate(113.96px, 61.6px) scale(1); + -moz-transform: translate(113.96px, 61.6px) scale(1); + -o-transform: translate(113.96px, 61.6px) scale(1); + -ms-transform: translate(113.96px, 61.6px) scale(1); + transform: translate(113.96px, 61.6px) scale(1); + } +} +@-moz-keyframes loading-ball-r { + 0% { + -webkit-transform: translate(113.96px, 61.6px) scale(1); + -moz-transform: translate(113.96px, 61.6px) scale(1); + -o-transform: translate(113.96px, 61.6px) scale(1); + -ms-transform: translate(113.96px, 61.6px) scale(1); + transform: translate(113.96px, 61.6px) scale(1); + } + 100% { + -webkit-transform: translate(113.96px, 61.6px) scale(0); + -moz-transform: translate(113.96px, 61.6px) scale(0); + -o-transform: translate(113.96px, 61.6px) scale(0); + -ms-transform: translate(113.96px, 61.6px) scale(0); + transform: translate(113.96px, 61.6px) scale(0); + } +} +@-webkit-keyframes loading-ball-r { + 0% { + -webkit-transform: translate(113.96px, 61.6px) scale(1); + -moz-transform: translate(113.96px, 61.6px) scale(1); + -o-transform: translate(113.96px, 61.6px) scale(1); + -ms-transform: translate(113.96px, 61.6px) scale(1); + transform: translate(113.96px, 61.6px) scale(1); + } + 100% { + -webkit-transform: translate(113.96px, 61.6px) scale(0); + -moz-transform: translate(113.96px, 61.6px) scale(0); + -o-transform: translate(113.96px, 61.6px) scale(0); + -ms-transform: translate(113.96px, 61.6px) scale(0); + transform: translate(113.96px, 61.6px) scale(0); + } +} +@-o-keyframes loading-ball-r { + 0% { + -webkit-transform: translate(113.96px, 61.6px) scale(1); + -moz-transform: translate(113.96px, 61.6px) scale(1); + -o-transform: translate(113.96px, 61.6px) scale(1); + -ms-transform: translate(113.96px, 61.6px) scale(1); + transform: translate(113.96px, 61.6px) scale(1); + } + 100% { + -webkit-transform: translate(113.96px, 61.6px) scale(0); + -moz-transform: translate(113.96px, 61.6px) scale(0); + -o-transform: translate(113.96px, 61.6px) scale(0); + -ms-transform: translate(113.96px, 61.6px) scale(0); + transform: translate(113.96px, 61.6px) scale(0); + } +} +@keyframes loading-ball-r { + 0% { + -webkit-transform: translate(113.96px, 61.6px) scale(1); + -moz-transform: translate(113.96px, 61.6px) scale(1); + -o-transform: translate(113.96px, 61.6px) scale(1); + -ms-transform: translate(113.96px, 61.6px) scale(1); + transform: translate(113.96px, 61.6px) scale(1); + } + 100% { + -webkit-transform: translate(113.96px, 61.6px) scale(0); + -moz-transform: translate(113.96px, 61.6px) scale(0); + -o-transform: translate(113.96px, 61.6px) scale(0); + -ms-transform: translate(113.96px, 61.6px) scale(0); + transform: translate(113.96px, 61.6px) scale(0); + } +} +@-moz-keyframes loading-ball-c { + 0% { + background: #e15b64; + } + 25% { + background: #abbd81; + } + 50% { + background: #f8b26a; + } + 75% { + background: #f47e60; + } + 100% { + background: #e15b64; + } +} +@-webkit-keyframes loading-ball-c { + 0% { + background: #e15b64; + } + 25% { + background: #abbd81; + } + 50% { + background: #f8b26a; + } + 75% { + background: #f47e60; + } + 100% { + background: #e15b64; + } +} +@-o-keyframes loading-ball-c { + 0% { + background: #e15b64; + } + 25% { + background: #abbd81; + } + 50% { + background: #f8b26a; + } + 75% { + background: #f47e60; + } + 100% { + background: #e15b64; + } +} +@keyframes loading-ball-c { + 0% { + background: #e15b64; + } + 25% { + background: #abbd81; + } + 50% { + background: #f8b26a; + } + 75% { + background: #f47e60; + } + 100% { + background: #e15b64; + } +} +blockquote.pullquote { + position: relative; + max-width: 45%; + font-size: 110%; +} +blockquote.pullquote.left { + float: left; + margin: 1em 0.5em 0 0; +} +blockquote.pullquote.right { + float: right; + margin: 1em 0 0 0.5em; +} +.video-container { + position: relative; + overflow: hidden; + margin-bottom: 16px; + padding-top: 56.25%; + height: 0; +} +.video-container iframe { + position: absolute; + top: 0; + left: 0; + margin-top: 0; + width: 100%; + height: 100%; +} +.hide-inline > .hide-button, +.hide-block > .hide-button { + display: inline-block; + padding: 5px 18px; + background: #49b1f5; + color: var(--white); +} +.hide-inline > .hide-button:hover, +.hide-block > .hide-button:hover { + background-color: var(--btn-hover-color); +} +.hide-inline > .hide-button.open, +.hide-block > .hide-button.open { + display: none; +} +.hide-inline > .hide-button.open + div, +.hide-block > .hide-button.open + div { + display: block; +} +.hide-inline > .hide-button.open + span, +.hide-block > .hide-button.open + span { + display: inline; +} +.hide-inline > .hide-content, +.hide-block > .hide-content { + display: none; +} +.hide-inline > .hide-button { + margin: 0 6px; +} +.hide-inline > .hide-content { + margin: 0 6px; +} +.hide-block { + margin: 0 0 16px; +} +.toggle { + margin-bottom: 20px; + border: 1px solid #f0f0f0; +} +.toggle > .toggle-button { + padding: 6px 15px; + background: #f0f0f0; + color: #1f2d3d; + cursor: pointer; +} +.toggle > .toggle-content { + margin: 30px 24px; +} +#article-container .inline-img { + display: inline; + margin: 0 3px; + height: 1.1em; + vertical-align: text-bottom; +} +.hl-label { + padding: 2px 4px; + border-radius: 3px; + color: #fff; +} +.hl-label.default { + background-color: #777; +} +.hl-label.blue { + background-color: #428bca; +} +.hl-label.pink { + background-color: #ff69b4; +} +.hl-label.red { + background-color: #f00; +} +.hl-label.purple { + background-color: #6f42c1; +} +.hl-label.orange { + background-color: #ff8c00; +} +.hl-label.green { + background-color: #5cb85c; +} +.note { + position: relative; + margin: 0 0 20px; + padding: 15px; + border-radius: 3px; +} +.note.icon-padding { + padding-left: 3em; +} +.note > .note-icon { + position: absolute; + top: calc(50% - 0.5em); + left: 0.8em; + font-size: larger; +} +.note.blue:not(.disabled) { + border-left-color: #428bca !important; +} +.note.blue:not(.disabled).modern { + border-left-color: transparent !important; + color: #428bca; +} +.note.blue:not(.disabled):not(.simple) { + background: #e3eef7 !important; +} +.note.blue > .note-icon { + color: #428bca; +} +.note.pink:not(.disabled) { + border-left-color: #ff69b4 !important; +} +.note.pink:not(.disabled).modern { + border-left-color: transparent !important; + color: #ff69b4; +} +.note.pink:not(.disabled):not(.simple) { + background: #ffe9f4 !important; +} +.note.pink > .note-icon { + color: #ff69b4; +} +.note.red:not(.disabled) { + border-left-color: #f00 !important; +} +.note.red:not(.disabled).modern { + border-left-color: transparent !important; + color: #f00; +} +.note.red:not(.disabled):not(.simple) { + background: #ffd9d9 !important; +} +.note.red > .note-icon { + color: #f00; +} +.note.purple:not(.disabled) { + border-left-color: #6f42c1 !important; +} +.note.purple:not(.disabled).modern { + border-left-color: transparent !important; + color: #6f42c1; +} +.note.purple:not(.disabled):not(.simple) { + background: #e9e3f6 !important; +} +.note.purple > .note-icon { + color: #6f42c1; +} +.note.orange:not(.disabled) { + border-left-color: #ff8c00 !important; +} +.note.orange:not(.disabled).modern { + border-left-color: transparent !important; + color: #ff8c00; +} +.note.orange:not(.disabled):not(.simple) { + background: #ffeed9 !important; +} +.note.orange > .note-icon { + color: #ff8c00; +} +.note.green:not(.disabled) { + border-left-color: #5cb85c !important; +} +.note.green:not(.disabled).modern { + border-left-color: transparent !important; + color: #5cb85c; +} +.note.green:not(.disabled):not(.simple) { + background: #e7f4e7 !important; +} +.note.green > .note-icon { + color: #5cb85c; +} +.note.simple { + border: 1px solid #eee; + border-left-width: 5px; +} +.note.modern { + border: 1px solid transparent !important; + background-color: #f5f5f5; + color: #4c4948; +} +.note.flat { + border: initial; + border-left: 5px solid #eee; + background-color: #f9f9f9; + color: #4c4948; +} +.note h2, +.note h3, +.note h4, +.note h5, +.note h6 { + margin-top: 3px; + margin-bottom: 0; + padding-top: 0 !important; + border-bottom: initial; +} +.note p:first-child, +.note ul:first-child, +.note ol:first-child, +.note table:first-child, +.note pre:first-child, +.note blockquote:first-child, +.note img:first-child { + margin-top: 0 !important; +} +.note p:last-child, +.note ul:last-child, +.note ol:last-child, +.note table:last-child, +.note pre:last-child, +.note blockquote:last-child, +.note img:last-child { + margin-bottom: 0 !important; +} +.note .img-alt { + margin: 5px 0 10px; +} +.note:not(.no-icon) { + padding-left: 3em; +} +.note:not(.no-icon)::before { + position: absolute; + top: calc(50% - 0.95em); + left: 0.8em; + font-size: larger; +} +.note.default.flat { + background: #f7f7f7; +} +.note.default.modern { + border-color: #e1e1e1; + background: #f3f3f3; + color: #666; +} +.note.default.modern a:not(.btn) { + color: #666; +} +.note.default.modern a:not(.btn):hover { + color: #454545; +} +.note.default:not(.modern) { + border-left-color: #777; +} +.note.default:not(.modern) h2, +.note.default:not(.modern) h3, +.note.default:not(.modern) h4, +.note.default:not(.modern) h5, +.note.default:not(.modern) h6 { + color: #777; +} +.note.default:not(.no-icon)::before { + content: '\f0a9'; +} +.note.default:not(.no-icon):not(.modern)::before { + color: #777; +} +.note.primary.flat { + background: #f5f0fa; +} +.note.primary.modern { + border-color: #e1c2ff; + background: #f3daff; + color: #6f42c1; +} +.note.primary.modern a:not(.btn) { + color: #6f42c1; +} +.note.primary.modern a:not(.btn):hover { + color: #453298; +} +.note.primary:not(.modern) { + border-left-color: #6f42c1; +} +.note.primary:not(.modern) h2, +.note.primary:not(.modern) h3, +.note.primary:not(.modern) h4, +.note.primary:not(.modern) h5, +.note.primary:not(.modern) h6 { + color: #6f42c1; +} +.note.primary:not(.no-icon)::before { + content: '\f055'; +} +.note.primary:not(.no-icon):not(.modern)::before { + color: #6f42c1; +} +.note.info.flat { + background: #eef7fa; +} +.note.info.modern { + border-color: #b3e5ef; + background: #d9edf7; + color: #31708f; +} +.note.info.modern a:not(.btn) { + color: #31708f; +} +.note.info.modern a:not(.btn):hover { + color: #215761; +} +.note.info:not(.modern) { + border-left-color: #428bca; +} +.note.info:not(.modern) h2, +.note.info:not(.modern) h3, +.note.info:not(.modern) h4, +.note.info:not(.modern) h5, +.note.info:not(.modern) h6 { + color: #428bca; +} +.note.info:not(.no-icon)::before { + content: '\f05a'; +} +.note.info:not(.no-icon):not(.modern)::before { + color: #428bca; +} +.note.success.flat { + background: #eff8f0; +} +.note.success.modern { + border-color: #d0e6be; + background: #dff0d8; + color: #3c763d; +} +.note.success.modern a:not(.btn) { + color: #3c763d; +} +.note.success.modern a:not(.btn):hover { + color: #32562c; +} +.note.success:not(.modern) { + border-left-color: #5cb85c; +} +.note.success:not(.modern) h2, +.note.success:not(.modern) h3, +.note.success:not(.modern) h4, +.note.success:not(.modern) h5, +.note.success:not(.modern) h6 { + color: #5cb85c; +} +.note.success:not(.no-icon)::before { + content: '\f058'; +} +.note.success:not(.no-icon):not(.modern)::before { + color: #5cb85c; +} +.note.warning.flat { + background: #fdf8ea; +} +.note.warning.modern { + border-color: #fae4cd; + background: #fcf4e3; + color: #8a6d3b; +} +.note.warning.modern a:not(.btn) { + color: #8a6d3b; +} +.note.warning.modern a:not(.btn):hover { + color: #714f30; +} +.note.warning:not(.modern) { + border-left-color: #f0ad4e; +} +.note.warning:not(.modern) h2, +.note.warning:not(.modern) h3, +.note.warning:not(.modern) h4, +.note.warning:not(.modern) h5, +.note.warning:not(.modern) h6 { + color: #f0ad4e; +} +.note.warning:not(.no-icon)::before { + content: '\f06a'; +} +.note.warning:not(.no-icon):not(.modern)::before { + color: #f0ad4e; +} +.note.danger.flat { + background: #fcf1f2; +} +.note.danger.modern { + border-color: #ebcdd2; + background: #f2dfdf; + color: #a94442; +} +.note.danger.modern a:not(.btn) { + color: #a94442; +} +.note.danger.modern a:not(.btn):hover { + color: #84333f; +} +.note.danger:not(.modern) { + border-left-color: #d9534f; +} +.note.danger:not(.modern) h2, +.note.danger:not(.modern) h3, +.note.danger:not(.modern) h4, +.note.danger:not(.modern) h5, +.note.danger:not(.modern) h6 { + color: #d9534f; +} +.note.danger:not(.no-icon)::before { + content: '\f056'; +} +.note.danger:not(.no-icon):not(.modern)::before { + color: #d9534f; +} +#article-container .tabs { + position: relative; + margin: 0 0 20px; + border-right: 1px solid var(--tab-border-color); + border-bottom: 1px solid var(--tab-border-color); + border-left: 1px solid var(--tab-border-color); +} +#article-container .tabs > .nav-tabs { + display: -webkit-box; + display: -moz-box; + display: -webkit-flex; + display: -ms-flexbox; + display: box; + display: flex; + -webkit-box-lines: multiple; + -moz-box-lines: multiple; + -o-box-lines: multiple; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + margin: 0; + padding: 0; + background: var(--tab-botton-bg); +} +#article-container .tabs > .nav-tabs > .tab { + -webkit-box-flex: 1; + -moz-box-flex: 1; + -o-box-flex: 1; + -ms-box-flex: 1; + box-flex: 1; + -webkit-flex-grow: 1; + flex-grow: 1; + padding: 8px 18px; + border-top: 2px solid var(--tab-border-color); + background: var(--tab-botton-bg); + color: var(--tab-botton-color); + line-height: 2; + -webkit-transition: all 0.4s; + -moz-transition: all 0.4s; + -o-transition: all 0.4s; + -ms-transition: all 0.4s; + transition: all 0.4s; +} +#article-container .tabs > .nav-tabs > .tab i { + width: 1.5em; +} +#article-container .tabs > .nav-tabs > .tab.active { + border-top: 2px solid #49b1f5; + background: var(--tab-button-active-bg); + cursor: default; +} +#article-container .tabs > .nav-tabs > .tab:not(.active):hover { + border-top: 2px solid var(--tab-button-hover-bg); + background: var(--tab-button-hover-bg); +} +#article-container .tabs > .nav-tabs.no-default ~ .tab-to-top { + display: none; +} +#article-container .tabs > .tab-contents .tab-item-content { + position: relative; + display: none; + padding: 36px 24px 10px; +} +@media screen and (max-width: 768px) { + #article-container .tabs > .tab-contents .tab-item-content { + padding: 24px 14px; + } +} +#article-container .tabs > .tab-contents .tab-item-content.active { + display: block; + -webkit-animation: tabshow 0.5s; + -moz-animation: tabshow 0.5s; + -o-animation: tabshow 0.5s; + -ms-animation: tabshow 0.5s; + animation: tabshow 0.5s; +} +#article-container .tabs > .tab-contents .tab-item-content > :last-child { + margin-bottom: 0; +} +#article-container .tabs > .tab-to-top { + padding: 0 16px 10px 0; + width: 100%; + text-align: right; +} +#article-container .tabs > .tab-to-top button { + color: #99a9bf; +} +#article-container .tabs > .tab-to-top button:hover { + color: #49b1f5; +} +@-moz-keyframes tabshow { + 0% { + -webkit-transform: translateY(15px); + -moz-transform: translateY(15px); + -o-transform: translateY(15px); + -ms-transform: translateY(15px); + transform: translateY(15px); + } + 100% { + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@-webkit-keyframes tabshow { + 0% { + -webkit-transform: translateY(15px); + -moz-transform: translateY(15px); + -o-transform: translateY(15px); + -ms-transform: translateY(15px); + transform: translateY(15px); + } + 100% { + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@-o-keyframes tabshow { + 0% { + -webkit-transform: translateY(15px); + -moz-transform: translateY(15px); + -o-transform: translateY(15px); + -ms-transform: translateY(15px); + transform: translateY(15px); + } + 100% { + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +@keyframes tabshow { + 0% { + -webkit-transform: translateY(15px); + -moz-transform: translateY(15px); + -o-transform: translateY(15px); + -ms-transform: translateY(15px); + transform: translateY(15px); + } + 100% { + -webkit-transform: translateY(0); + -moz-transform: translateY(0); + -o-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); + } +} +#article-container .timeline { + margin: 0 0 20px 10px; + padding: 14px 20px 5px; + border-left: 2px solid var(--timeline-color, #49b1f5); +} +#article-container .timeline.blue { + --timeline-color: #428bca; + --timeline-bg: rgba(66,139,202, 0.2); +} +#article-container .timeline.pink { + --timeline-color: #ff69b4; + --timeline-bg: rgba(255,105,180, 0.2); +} +#article-container .timeline.red { + --timeline-color: #f00; + --timeline-bg: rgba(255,0,0, 0.2); +} +#article-container .timeline.purple { + --timeline-color: #6f42c1; + --timeline-bg: rgba(111,66,193, 0.2); +} +#article-container .timeline.orange { + --timeline-color: #ff8c00; + --timeline-bg: rgba(255,140,0, 0.2); +} +#article-container .timeline.green { + --timeline-color: #5cb85c; + --timeline-bg: rgba(92,184,92, 0.2); +} +#article-container .timeline .timeline-item { + margin: 0 0 15px; +} +#article-container .timeline .timeline-item:hover .item-circle:before { + border-color: var(--timeline-color, #49b1f5); +} +#article-container .timeline .timeline-item.headline .timeline-item-title .item-circle > p { + font-weight: 600; + font-size: 1.2em; +} +#article-container .timeline .timeline-item.headline .timeline-item-title .item-circle:before { + left: -28px; + border: 4px solid var(--timeline-color, #49b1f5); +} +#article-container .timeline .timeline-item.headline:hover .item-circle:before { + border-color: var(--pseudo-hover); +} +#article-container .timeline .timeline-item .timeline-item-title { + position: relative; +} +#article-container .timeline .timeline-item .item-circle:before { + position: absolute; + top: 50%; + left: -27px; + width: 6px; + height: 6px; + border: 3px solid var(--pseudo-hover); + border-radius: 50%; + background: var(--card-bg); + content: ''; + -webkit-transition: all 0.3s; + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -ms-transition: all 0.3s; + transition: all 0.3s; + -webkit-transform: translate(0, -50%); + -moz-transform: translate(0, -50%); + -o-transform: translate(0, -50%); + -ms-transform: translate(0, -50%); + transform: translate(0, -50%); +} +#article-container .timeline .timeline-item .item-circle > p { + margin: 0 0 8px; + font-weight: 500; +} +#article-container .timeline .timeline-item .timeline-item-content { + position: relative; + padding: 12px 15px; + border-radius: 8px; + background: var(--timeline-bg, #e4f3fd); + font-size: 0.93em; +} +#article-container .timeline .timeline-item .timeline-item-content > :last-child { + margin-bottom: 0; +} +#article-container .timeline + .timeline { + margin-top: -20px; +} +[data-theme='dark'] { + --global-bg: #0d0d0d; + --font-color: rgba(255,255,255,0.7); + --hr-border: rgba(255,255,255,0.4); + --hr-before-color: rgba(255,255,255,0.7); + --search-bg: #121212; + --search-input-color: rgba(255,255,255,0.7); + --search-a-color: rgba(255,255,255,0.7); + --preloader-bg: #0d0d0d; + --preloader-color: rgba(255,255,255,0.7); + --tab-border-color: #2c2c2c; + --tab-botton-bg: #2c2c2c; + --tab-botton-color: rgba(255,255,255,0.7); + --tab-button-hover-bg: #383838; + --tab-button-active-bg: #121212; + --card-bg: #121212; + --sidebar-bg: #121212; + --btn-hover-color: #787878; + --btn-color: rgba(255,255,255,0.7); + --btn-bg: #1f1f1f; + --text-bg-hover: #383838; + --light-grey: rgba(255,255,255,0.7); + --dark-grey: rgba(255,255,255,0.2); + --white: rgba(255,255,255,0.9); + --text-highlight-color: rgba(255,255,255,0.9); + --blockquote-color: rgba(255,255,255,0.7); + --blockquote-bg: #2c2c2c; + --reward-pop: #2c2c2c; + --toc-link-color: rgba(255,255,255,0.6); + --scrollbar-color: #525252; + --timeline-bg: #1f1f1f; + --zoom-bg: #121212; + --mark-bg: rgba(0,0,0,0.6); +} +[data-theme='dark'] #web_bg:before { + position: absolute; + width: 100%; + height: 100%; + background-color: rgba(0,0,0,0.7); + content: ''; +} +[data-theme='dark'] #article-container code { + background: #2c2c2c; +} +[data-theme='dark'] #article-container pre > code { + background: #171717; +} +[data-theme='dark'] #article-container figure.highlight { + -webkit-box-shadow: none; + box-shadow: none; +} +[data-theme='dark'] #article-container .note code { + background: rgba(27,31,35,0.05); +} +[data-theme='dark'] #article-container .aplayer { + filter: brightness(0.8); +} +[data-theme='dark'] #article-container kbd { + border-color: #696969; + background-color: #525252; + color: #e2f1ff; +} +[data-theme='dark'] #page-header.nav-fixed > #nav, +[data-theme='dark'] #page-header.not-top-img > #nav { + background: rgba(18,18,18,0.8); + -webkit-box-shadow: 0 5px 6px -5px rgba(133,133,133,0); + box-shadow: 0 5px 6px -5px rgba(133,133,133,0); +} +[data-theme='dark'] #post-comment .comment-switch { + background: #2c2c2c !important; +} +[data-theme='dark'] #post-comment .comment-switch #switch-btn { + filter: brightness(0.8); +} +[data-theme='dark'] .note { + filter: brightness(0.8); +} +[data-theme='dark'] .hide-button, +[data-theme='dark'] .btn-beautify, +[data-theme='dark'] .hl-label, +[data-theme='dark'] .post-outdate-notice, +[data-theme='dark'] .error-img, +[data-theme='dark'] #article-container iframe, +[data-theme='dark'] .gist, +[data-theme='dark'] .ads-wrap { + filter: brightness(0.8); +} +[data-theme='dark'] img { + filter: brightness(0.8); +} +[data-theme='dark'] #aside-content .aside-list > .aside-list-item:not(:last-child) { + border-bottom: 1px dashed rgba(255,255,255,0.1); +} +[data-theme='dark'] #gitalk-container { + filter: brightness(0.8); +} +[data-theme='dark'] #gitalk-container svg { + fill: rgba(255,255,255,0.9) !important; +} +[data-theme='dark'] #disqusjs #dsqjs:hover, +[data-theme='dark'] #disqusjs #dsqjs:focus, +[data-theme='dark'] #disqusjs #dsqjs .dsqjs-tab-active, +[data-theme='dark'] #disqusjs #dsqjs .dsqjs-no-comment { + color: rgba(255,255,255,0.7); +} +[data-theme='dark'] #disqusjs #dsqjs .dsqjs-order-label { + background-color: #1f1f1f; +} +[data-theme='dark'] #disqusjs #dsqjs .dsqjs-post-body { + color: rgba(255,255,255,0.7); +} +[data-theme='dark'] #disqusjs #dsqjs .dsqjs-post-body code, +[data-theme='dark'] #disqusjs #dsqjs .dsqjs-post-body pre { + background: #2c2c2c; +} +[data-theme='dark'] #disqusjs #dsqjs .dsqjs-post-body blockquote { + color: rgba(255,255,255,0.7); +} +[data-theme='dark'] #artitalk_main #lazy { + background: #121212; +} +[data-theme='dark'] #operare_artitalk .c2 { + background: #121212; +} +@media screen and (max-width: 900px) { + [data-theme='dark'] #card-toc { + background: #1f1f1f; + } +} +.read-mode { + --font-color: #4c4948; + --readmode-light-color: #fff; + --white: #4c4948; + --light-grey: #4c4948; + --gray: #d6dbdf; + --hr-border: #d6dbdf; + --hr-before-color: #b9c2c9; + --highlight-bg: #f7f7f7; + --exit-btn-bg: #c0c0c0; + --exit-btn-color: #fff; + --exit-btn-hover: #8d8d8d; + --pseudo-hover: none; +} +[data-theme='dark'] .read-mode { + --font-color: rgba(255,255,255,0.7); + --readmode-light-color: #0d0d0d; + --white: rgba(255,255,255,0.9); + --light-grey: rgba(255,255,255,0.7); + --gray: rgba(255,255,255,0.7); + --hr-border: rgba(255,255,255,0.5); + --hr-before-color: rgba(255,255,255,0.7); + --highlight-bg: #171717; + --exit-btn-bg: #1f1f1f; + --exit-btn-color: rgba(255,255,255,0.9); + --exit-btn-hover: #525252; +} +.read-mode { + background: var(--readmode-light-color); +} +.read-mode .exit-readmode { + position: fixed; + top: 30px; + right: 30px; + z-index: 100; + width: 40px; + height: 40px; + border-radius: 8px; + background: var(--exit-btn-bg); + color: var(--exit-btn-color); + font-size: 16px; + -webkit-transition: background 0.3s; + -moz-transition: background 0.3s; + -o-transition: background 0.3s; + -ms-transition: background 0.3s; + transition: background 0.3s; +} +@media screen and (max-width: 768px) { + .read-mode .exit-readmode { + top: initial; + bottom: 30px; + } +} +.read-mode .exit-readmode:hover { + background: var(--exit-btn-hover); +} +.read-mode #aside-content { + display: none; +} +.read-mode #page-header.post-bg { + background: none !important; +} +.read-mode #page-header.post-bg:before { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); +} +.read-mode #page-header.post-bg > #post-info { + text-align: center; +} +.read-mode #post { + margin: 0 auto; + background: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.read-mode #post:hover { + -webkit-box-shadow: none; + box-shadow: none; +} +.read-mode > canvas { + display: none !important; +} +.read-mode .highlight-tools, +.read-mode #footer, +.read-mode #post > *:not(#post-info):not(.post-content), +.read-mode #nav, +.read-mode .post-outdate-notice, +.read-mode #web_bg, +.read-mode #rightside, +.read-mode .not-top-img { + display: none !important; +} +.read-mode #article-container a { + color: #99a9bf; +} +.read-mode #article-container pre, +.read-mode #article-container .highlight:not(.js-file-line-container) { + background: var(--highlight-bg) !important; +} +.read-mode #article-container pre *, +.read-mode #article-container .highlight:not(.js-file-line-container) * { + color: var(--font-color) !important; +} +.read-mode #article-container figure.highlight { + border-radius: 0 !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; +} +.read-mode #article-container figure.highlight > :not(.highlight-tools) { + display: block !important; +} +.read-mode #article-container figure.highlight .line:before { + color: var(--font-color) !important; +} +.read-mode #article-container figure.highlight .hljs { + background: var(--highlight-bg) !important; +} +.read-mode #article-container h1, +.read-mode #article-container h2, +.read-mode #article-container h3, +.read-mode #article-container h4, +.read-mode #article-container h5, +.read-mode #article-container h6 { + padding: 0; +} +.read-mode #article-container h1:before, +.read-mode #article-container h2:before, +.read-mode #article-container h3:before, +.read-mode #article-container h4:before, +.read-mode #article-container h5:before, +.read-mode #article-container h6:before { + content: ''; +} +.read-mode #article-container h1:hover, +.read-mode #article-container h2:hover, +.read-mode #article-container h3:hover, +.read-mode #article-container h4:hover, +.read-mode #article-container h5:hover, +.read-mode #article-container h6:hover { + padding: 0; +} +.read-mode #article-container ul:hover:before, +.read-mode #article-container li:hover:before, +.read-mode #article-container ol:hover:before { + -webkit-transform: none !important; + -moz-transform: none !important; + -o-transform: none !important; + -ms-transform: none !important; + transform: none !important; +} +.read-mode #article-container ol:before, +.read-mode #article-container li:before { + background: transparent !important; + color: var(--font-color) !important; +} +.read-mode #article-container ul >li:before { + border-color: var(--gray) !important; +} +.read-mode #article-container .tabs { + border: 2px solid var(--tab-border-color); +} +.read-mode #article-container .tabs > .nav-tabs { + background: transparent; +} +.read-mode #article-container .tabs > .nav-tabs > .tab { + border-top: none !important; +} +.read-mode #article-container .tabs > .tab-contents .tab-item-content.active { + -webkit-animation: none; + -moz-animation: none; + -o-animation: none; + -ms-animation: none; + animation: none; +} +.read-mode #article-container code { + color: var(--font-color); +} +.read-mode #article-container blockquote { + border-color: var(--gray); + background-color: var(--readmode-light-color); +} +.read-mode #article-container kbd { + border: 1px solid var(--gray); + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; + color: var(--font-color); +} +.read-mode #article-container .hide-toggle { + border: 1px solid var(--gray) !important; +} +.read-mode #article-container .hide-button, +.read-mode #article-container .btn-beautify, +.read-mode #article-container .hl-label { + border: 1px solid var(--gray) !important; + background: var(--readmode-light-color) !important; + color: var(--font-color) !important; +} +.read-mode #article-container .note { + border: 2px solid var(--gray); + border-left-color: var(--gray) !important; + filter: none; + background-color: var(--readmode-light-color) !important; + color: var(--font-color); +} +.read-mode #article-container .note:before, +.read-mode #article-container .note .note-icon { + color: var(--font-color); +} +.search-dialog { + position: fixed; + top: 10%; + left: 50%; + z-index: 1001; + display: none; + margin-left: -300px; + padding: 20px; + width: 600px; + border-radius: 8px; + background: var(--search-bg); + --search-height: 100vh; +} +@media screen and (max-width: 768px) { + .search-dialog { + top: 0; + left: 0; + margin: 0; + width: 100%; + height: 100%; + border-radius: 0; + } +} +.search-dialog hr { + margin: 20px auto; +} +.search-dialog .search-nav { + margin: 0 0 14px; + color: #49b1f5; + font-size: 1.4em; + line-height: 1; +} +.search-dialog .search-nav .search-dialog-title { + margin-right: 10px; +} +.search-dialog .search-nav .search-close-button { + float: right; + color: #858585; + -webkit-transition: color 0.2s ease-in-out; + -moz-transition: color 0.2s ease-in-out; + -o-transition: color 0.2s ease-in-out; + -ms-transition: color 0.2s ease-in-out; + transition: color 0.2s ease-in-out; +} +.search-dialog .search-nav .search-close-button:hover { + color: #49b1f5; +} +.search-dialog hr { + margin: 20px auto; +} +#search-mask { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1000; + display: none; + background: rgba(0,0,0,0.6); +} diff --git a/placeholder b/css/var.css similarity index 100% rename from placeholder rename to css/var.css diff --git a/images/2015-09-29-replacement-of-SSD/1.png b/images/2015-09-29-replacement-of-SSD/1.png new file mode 100644 index 000000000..1841a036d Binary files /dev/null and b/images/2015-09-29-replacement-of-SSD/1.png differ diff --git a/images/2015-09-29-replacement-of-SSD/2.png b/images/2015-09-29-replacement-of-SSD/2.png new file mode 100644 index 000000000..3b4ce44a4 Binary files /dev/null and b/images/2015-09-29-replacement-of-SSD/2.png differ diff --git a/images/2015-09-29-replacement-of-SSD/3.png b/images/2015-09-29-replacement-of-SSD/3.png new file mode 100644 index 000000000..967575e3c Binary files /dev/null and b/images/2015-09-29-replacement-of-SSD/3.png differ diff --git a/images/2015-09-29-replacement-of-SSD/4.png b/images/2015-09-29-replacement-of-SSD/4.png new file mode 100644 index 000000000..4a43e6698 Binary files /dev/null and b/images/2015-09-29-replacement-of-SSD/4.png differ diff --git a/images/2015-09-29-replacement-of-SSD/5.png b/images/2015-09-29-replacement-of-SSD/5.png new file mode 100644 index 000000000..be4d1724d Binary files /dev/null and b/images/2015-09-29-replacement-of-SSD/5.png differ diff --git a/images/2015-09-29-replacement-of-SSD/6.png b/images/2015-09-29-replacement-of-SSD/6.png new file mode 100644 index 000000000..cf7748c12 Binary files /dev/null and b/images/2015-09-29-replacement-of-SSD/6.png differ diff --git a/images/2015-09-29-replacement-of-SSD/7.png b/images/2015-09-29-replacement-of-SSD/7.png new file mode 100644 index 000000000..0ec7c2d58 Binary files /dev/null and b/images/2015-09-29-replacement-of-SSD/7.png differ diff --git a/images/2015-09-29-replacement-of-SSD/8.png b/images/2015-09-29-replacement-of-SSD/8.png new file mode 100644 index 000000000..1d7278338 Binary files /dev/null and b/images/2015-09-29-replacement-of-SSD/8.png differ diff --git a/images/2015-11-12-shadowsocks/ss1.png b/images/2015-11-12-shadowsocks/ss1.png new file mode 100644 index 000000000..98bc0f0b3 Binary files /dev/null and b/images/2015-11-12-shadowsocks/ss1.png differ diff --git a/images/2015-11-12-shadowsocks/ss2.png b/images/2015-11-12-shadowsocks/ss2.png new file mode 100644 index 000000000..8834c0738 Binary files /dev/null and b/images/2015-11-12-shadowsocks/ss2.png differ diff --git a/images/2015-11-12-shadowsocks/ss3.png b/images/2015-11-12-shadowsocks/ss3.png new file mode 100644 index 000000000..5334b26bf Binary files /dev/null and b/images/2015-11-12-shadowsocks/ss3.png differ diff --git a/images/2015-11-12-shadowsocks/ss4.png b/images/2015-11-12-shadowsocks/ss4.png new file mode 100644 index 000000000..092e64cc0 Binary files /dev/null and b/images/2015-11-12-shadowsocks/ss4.png differ diff --git a/images/2016-08-15-line-height b/images/2016-08-15-line-height new file mode 100644 index 000000000..9daeafb98 --- /dev/null +++ b/images/2016-08-15-line-height @@ -0,0 +1 @@ +test diff --git a/images/2016-08-15-line-height-css/Android-border.png b/images/2016-08-15-line-height-css/Android-border.png new file mode 100644 index 000000000..d690d57fb Binary files /dev/null and b/images/2016-08-15-line-height-css/Android-border.png differ diff --git a/images/2016-08-15-line-height-css/Android-none.png b/images/2016-08-15-line-height-css/Android-none.png new file mode 100644 index 000000000..f42e7e606 Binary files /dev/null and b/images/2016-08-15-line-height-css/Android-none.png differ diff --git a/images/2016-08-15-line-height-css/iOS-border.png b/images/2016-08-15-line-height-css/iOS-border.png new file mode 100644 index 000000000..bcd06200e Binary files /dev/null and b/images/2016-08-15-line-height-css/iOS-border.png differ diff --git a/images/2016-08-15-line-height-css/iOS-none.png b/images/2016-08-15-line-height-css/iOS-none.png new file mode 100644 index 000000000..a85818dd4 Binary files /dev/null and b/images/2016-08-15-line-height-css/iOS-none.png differ diff --git a/images/2016-08-15-line-height-css/test b/images/2016-08-15-line-height-css/test new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/images/2016-08-15-line-height-css/test @@ -0,0 +1 @@ + diff --git a/images/2017-07-12-vscode-introduction/auto-save.png b/images/2017-07-12-vscode-introduction/auto-save.png new file mode 100644 index 000000000..059d2c40a Binary files /dev/null and b/images/2017-07-12-vscode-introduction/auto-save.png differ diff --git a/images/2017-07-12-vscode-introduction/blame-annotations.png b/images/2017-07-12-vscode-introduction/blame-annotations.png new file mode 100644 index 000000000..35b0fd2a6 Binary files /dev/null and b/images/2017-07-12-vscode-introduction/blame-annotations.png differ diff --git a/images/2017-07-12-vscode-introduction/code-lens.png b/images/2017-07-12-vscode-introduction/code-lens.png new file mode 100644 index 000000000..4b0689374 Binary files /dev/null and b/images/2017-07-12-vscode-introduction/code-lens.png differ diff --git a/images/2017-07-12-vscode-introduction/format-document.png b/images/2017-07-12-vscode-introduction/format-document.png new file mode 100644 index 000000000..0c23518ba Binary files /dev/null and b/images/2017-07-12-vscode-introduction/format-document.png differ diff --git a/images/2017-07-12-vscode-introduction/git-history.gif b/images/2017-07-12-vscode-introduction/git-history.gif new file mode 100644 index 000000000..cc5bef4cf Binary files /dev/null and b/images/2017-07-12-vscode-introduction/git-history.gif differ diff --git a/images/2017-07-12-vscode-introduction/git-lens.gif b/images/2017-07-12-vscode-introduction/git-lens.gif new file mode 100644 index 000000000..697ce2261 Binary files /dev/null and b/images/2017-07-12-vscode-introduction/git-lens.gif differ diff --git a/images/2017-07-12-vscode-introduction/git-project-manager.gif b/images/2017-07-12-vscode-introduction/git-project-manager.gif new file mode 100644 index 000000000..569c915b9 Binary files /dev/null and b/images/2017-07-12-vscode-introduction/git-project-manager.gif differ diff --git a/images/2017-07-12-vscode-introduction/icon.png b/images/2017-07-12-vscode-introduction/icon.png new file mode 100644 index 000000000..98734a731 Binary files /dev/null and b/images/2017-07-12-vscode-introduction/icon.png differ diff --git a/images/2017-07-12-vscode-introduction/interactive-blame.png b/images/2017-07-12-vscode-introduction/interactive-blame.png new file mode 100644 index 000000000..d4f6d1c05 Binary files /dev/null and b/images/2017-07-12-vscode-introduction/interactive-blame.png differ diff --git a/images/2017-07-12-vscode-introduction/js-intelligence.png b/images/2017-07-12-vscode-introduction/js-intelligence.png new file mode 100644 index 000000000..4a051b59c Binary files /dev/null and b/images/2017-07-12-vscode-introduction/js-intelligence.png differ diff --git a/images/2017-07-12-vscode-introduction/project-manager-commands.png b/images/2017-07-12-vscode-introduction/project-manager-commands.png new file mode 100644 index 000000000..b479c6334 Binary files /dev/null and b/images/2017-07-12-vscode-introduction/project-manager-commands.png differ diff --git a/images/2017-07-12-vscode-introduction/quick-menu.png b/images/2017-07-12-vscode-introduction/quick-menu.png new file mode 100644 index 000000000..d52018f08 Binary files /dev/null and b/images/2017-07-12-vscode-introduction/quick-menu.png differ diff --git a/images/2017-07-12-vscode-introduction/search-by-author01.png b/images/2017-07-12-vscode-introduction/search-by-author01.png new file mode 100644 index 000000000..69ae95f78 Binary files /dev/null and b/images/2017-07-12-vscode-introduction/search-by-author01.png differ diff --git a/images/2017-07-12-vscode-introduction/search-by-author02.png b/images/2017-07-12-vscode-introduction/search-by-author02.png new file mode 100644 index 000000000..a9658afc9 Binary files /dev/null and b/images/2017-07-12-vscode-introduction/search-by-author02.png differ diff --git a/images/2017-07-12-vscode-introduction/search-by-filename01.png b/images/2017-07-12-vscode-introduction/search-by-filename01.png new file mode 100644 index 000000000..9f6976295 Binary files /dev/null and b/images/2017-07-12-vscode-introduction/search-by-filename01.png differ diff --git a/images/2017-07-12-vscode-introduction/search-by-filename02.png b/images/2017-07-12-vscode-introduction/search-by-filename02.png new file mode 100644 index 000000000..06e5b6683 Binary files /dev/null and b/images/2017-07-12-vscode-introduction/search-by-filename02.png differ diff --git a/images/2017-07-12-vscode-introduction/search-by-messages.png b/images/2017-07-12-vscode-introduction/search-by-messages.png new file mode 100644 index 000000000..3b1b0e02a Binary files /dev/null and b/images/2017-07-12-vscode-introduction/search-by-messages.png differ diff --git a/images/2017-07-12-vscode-introduction/status-bar-blame.png b/images/2017-07-12-vscode-introduction/status-bar-blame.png new file mode 100644 index 000000000..6b27c66b8 Binary files /dev/null and b/images/2017-07-12-vscode-introduction/status-bar-blame.png differ diff --git a/images/2017-07-12-vscode-introduction/terminal.png b/images/2017-07-12-vscode-introduction/terminal.png new file mode 100644 index 000000000..7604842e8 Binary files /dev/null and b/images/2017-07-12-vscode-introduction/terminal.png differ diff --git a/images/2017-08-13-plantuml/class.png b/images/2017-08-13-plantuml/class.png new file mode 100644 index 000000000..a86e9c521 Binary files /dev/null and b/images/2017-08-13-plantuml/class.png differ diff --git a/images/2017-08-13-plantuml/decorator.png b/images/2017-08-13-plantuml/decorator.png new file mode 100644 index 000000000..d436f12b8 Binary files /dev/null and b/images/2017-08-13-plantuml/decorator.png differ diff --git a/images/2017-08-13-plantuml/sequence.png b/images/2017-08-13-plantuml/sequence.png new file mode 100644 index 000000000..91f2b3030 Binary files /dev/null and b/images/2017-08-13-plantuml/sequence.png differ diff --git a/images/Jekyll-Pithy.png b/images/Jekyll-Pithy.png new file mode 100644 index 000000000..659725fb1 Binary files /dev/null and b/images/Jekyll-Pithy.png differ diff --git a/images/QrCode/Alipay.jpg b/images/QrCode/Alipay.jpg new file mode 100644 index 000000000..44e5cfaf5 Binary files /dev/null and b/images/QrCode/Alipay.jpg differ diff --git a/images/QrCode/WeChat.jpg b/images/QrCode/WeChat.jpg new file mode 100644 index 000000000..a46a208b1 Binary files /dev/null and b/images/QrCode/WeChat.jpg differ diff --git a/images/QrCode/weixin.png b/images/QrCode/weixin.png new file mode 100644 index 000000000..c9751be4f Binary files /dev/null and b/images/QrCode/weixin.png differ diff --git a/images/QrCode/zhifubao.png b/images/QrCode/zhifubao.png new file mode 100644 index 000000000..ade5ee453 Binary files /dev/null and b/images/QrCode/zhifubao.png differ diff --git a/images/cat.jpg b/images/cat.jpg new file mode 100644 index 000000000..ca4260ea1 Binary files /dev/null and b/images/cat.jpg differ diff --git a/images/checker.png b/images/checker.png new file mode 100644 index 000000000..7a65b2333 Binary files /dev/null and b/images/checker.png differ diff --git a/images/cnblogs.png b/images/cnblogs.png new file mode 100644 index 000000000..dc6d810f4 Binary files /dev/null and b/images/cnblogs.png differ diff --git a/images/css-center-things/css-center-top.jpg b/images/css-center-things/css-center-top.jpg new file mode 100644 index 000000000..d18bc50c9 Binary files /dev/null and b/images/css-center-things/css-center-top.jpg differ diff --git a/images/favicon.ico b/images/favicon.ico new file mode 100644 index 000000000..415c5578f Binary files /dev/null and b/images/favicon.ico differ diff --git a/images/github.png b/images/github.png new file mode 100644 index 000000000..9f4381950 Binary files /dev/null and b/images/github.png differ diff --git a/images/icons/M-S.png b/images/icons/M-S.png new file mode 100644 index 000000000..4bb522f2c Binary files /dev/null and b/images/icons/M-S.png differ diff --git a/images/icons/M.png b/images/icons/M.png new file mode 100644 index 000000000..ad52ae892 Binary files /dev/null and b/images/icons/M.png differ diff --git a/images/icons/favicon.ico b/images/icons/favicon.ico new file mode 100644 index 000000000..1384c22aa Binary files /dev/null and b/images/icons/favicon.ico differ diff --git a/images/introduction-of-software-release-life-cycle/software-release-life-cycle.jpg b/images/introduction-of-software-release-life-cycle/software-release-life-cycle.jpg new file mode 100644 index 000000000..bdc6d723b Binary files /dev/null and b/images/introduction-of-software-release-life-cycle/software-release-life-cycle.jpg differ diff --git a/images/introduction-of-software-release-life-cycle/software-release-life-cycle.png b/images/introduction-of-software-release-life-cycle/software-release-life-cycle.png new file mode 100644 index 000000000..15a9b9ae4 Binary files /dev/null and b/images/introduction-of-software-release-life-cycle/software-release-life-cycle.png differ diff --git a/images/introduction-of-software-release-life-cycle/software-release-life-cycle.psd b/images/introduction-of-software-release-life-cycle/software-release-life-cycle.psd new file mode 100644 index 000000000..c4a51f607 Binary files /dev/null and b/images/introduction-of-software-release-life-cycle/software-release-life-cycle.psd differ diff --git a/images/jest/jest.png b/images/jest/jest.png new file mode 100644 index 000000000..444186fd7 Binary files /dev/null and b/images/jest/jest.png differ diff --git a/images/others/codehighlight.jpg b/images/others/codehighlight.jpg new file mode 100644 index 000000000..13804b3c3 Binary files /dev/null and b/images/others/codehighlight.jpg differ diff --git a/images/plief.jpeg b/images/plief.jpeg new file mode 100644 index 000000000..6eea31747 Binary files /dev/null and b/images/plief.jpeg differ diff --git a/images/poetry/dusk.jpg b/images/poetry/dusk.jpg new file mode 100644 index 000000000..f54c8f215 Binary files /dev/null and b/images/poetry/dusk.jpg differ diff --git a/images/poetry/poetry.jpg b/images/poetry/poetry.jpg new file mode 100644 index 000000000..cc84c81d1 Binary files /dev/null and b/images/poetry/poetry.jpg differ diff --git a/images/poetry/raining-night.jpg b/images/poetry/raining-night.jpg new file mode 100644 index 000000000..862d36b14 Binary files /dev/null and b/images/poetry/raining-night.jpg differ diff --git a/images/poetry/residual-poetry.jpg b/images/poetry/residual-poetry.jpg new file mode 100644 index 000000000..cc84c81d1 Binary files /dev/null and b/images/poetry/residual-poetry.jpg differ diff --git a/images/poetry/say-goodbye.jpg b/images/poetry/say-goodbye.jpg new file mode 100644 index 000000000..7c1417aa1 Binary files /dev/null and b/images/poetry/say-goodbye.jpg differ diff --git a/images/poetry/snow.jpg b/images/poetry/snow.jpg new file mode 100644 index 000000000..c1e35f9e5 Binary files /dev/null and b/images/poetry/snow.jpg differ diff --git a/images/poetry/south-lake-at-dusk.jpg b/images/poetry/south-lake-at-dusk.jpg new file mode 100644 index 000000000..b16ff2c49 Binary files /dev/null and b/images/poetry/south-lake-at-dusk.jpg differ diff --git a/images/rss.png b/images/rss.png new file mode 100644 index 000000000..0f045549a Binary files /dev/null and b/images/rss.png differ diff --git a/images/twitter.png b/images/twitter.png new file mode 100644 index 000000000..31c2de2e1 Binary files /dev/null and b/images/twitter.png differ diff --git a/images/webpack-introduce/webpack.png b/images/webpack-introduce/webpack.png new file mode 100644 index 000000000..d28984e9d Binary files /dev/null and b/images/webpack-introduce/webpack.png differ diff --git a/images/weibo.png b/images/weibo.png new file mode 100644 index 000000000..e8bae8359 Binary files /dev/null and b/images/weibo.png differ diff --git a/img/404.jpg b/img/404.jpg new file mode 100644 index 000000000..4bab3c3f2 Binary files /dev/null and b/img/404.jpg differ diff --git a/img/favicon.png b/img/favicon.png new file mode 100644 index 000000000..862ebe858 Binary files /dev/null and b/img/favicon.png differ diff --git a/img/friend_404.gif b/img/friend_404.gif new file mode 100644 index 000000000..91dd56a28 Binary files /dev/null and b/img/friend_404.gif differ diff --git a/index.html b/index.html new file mode 100644 index 000000000..44657f66f --- /dev/null +++ b/index.html @@ -0,0 +1,307 @@ +Maple's Blog + + + + + + + +
软件开发生命周期
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/js/main.js b/js/main.js new file mode 100644 index 000000000..a22b57f54 --- /dev/null +++ b/js/main.js @@ -0,0 +1,879 @@ +document.addEventListener('DOMContentLoaded', function () { + let headerContentWidth, $nav + let mobileSidebarOpen = false + + const adjustMenu = init => { + const getAllWidth = ele => { + return Array.from(ele).reduce((width, i) => width + i.offsetWidth, 0) + } + + if (init) { + const blogInfoWidth = getAllWidth(document.querySelector('#blog-info > a').children) + const menusWidth = getAllWidth(document.getElementById('menus').children) + headerContentWidth = blogInfoWidth + menusWidth + $nav = document.getElementById('nav') + } + + const hideMenuIndex = window.innerWidth <= 768 || headerContentWidth > $nav.offsetWidth - 120 + $nav.classList.toggle('hide-menu', hideMenuIndex) + } + + // 初始化header + const initAdjust = () => { + adjustMenu(true) + $nav.classList.add('show') + } + + // sidebar menus + const sidebarFn = { + open: () => { + btf.sidebarPaddingR() + document.body.style.overflow = 'hidden' + btf.animateIn(document.getElementById('menu-mask'), 'to_show 0.5s') + document.getElementById('sidebar-menus').classList.add('open') + mobileSidebarOpen = true + }, + close: () => { + const $body = document.body + $body.style.overflow = '' + $body.style.paddingRight = '' + btf.animateOut(document.getElementById('menu-mask'), 'to_hide 0.5s') + document.getElementById('sidebar-menus').classList.remove('open') + mobileSidebarOpen = false + } + } + + /** + * 首頁top_img底下的箭頭 + */ + const scrollDownInIndex = () => { + const handleScrollToDest = () => { + btf.scrollToDest(document.getElementById('content-inner').offsetTop, 300) + } + + const $scrollDownEle = document.getElementById('scroll-down') + $scrollDownEle && btf.addEventListenerPjax($scrollDownEle, 'click', handleScrollToDest) + } + + /** + * 代碼 + * 只適用於Hexo默認的代碼渲染 + */ + const addHighlightTool = () => { + const highLight = GLOBAL_CONFIG.highlight + if (!highLight) return + + const { highlightCopy, highlightLang, highlightHeightLimit, plugin } = highLight + const isHighlightShrink = GLOBAL_CONFIG_SITE.isHighlightShrink + const isShowTool = highlightCopy || highlightLang || isHighlightShrink !== undefined + const $figureHighlight = plugin === 'highlighjs' ? document.querySelectorAll('figure.highlight') : document.querySelectorAll('pre[class*="language-"]') + + if (!((isShowTool || highlightHeightLimit) && $figureHighlight.length)) return + + const isPrismjs = plugin === 'prismjs' + const highlightShrinkClass = isHighlightShrink === true ? 'closed' : '' + const highlightShrinkEle = isHighlightShrink !== undefined ? '' : '' + const highlightCopyEle = highlightCopy ? '
' : '' + + const copy = (text, ctx) => { + if (document.queryCommandSupported && document.queryCommandSupported('copy')) { + document.execCommand('copy') + if (GLOBAL_CONFIG.Snackbar !== undefined) { + btf.snackbarShow(GLOBAL_CONFIG.copy.success) + } else { + const prevEle = ctx.previousElementSibling + prevEle.textContent = GLOBAL_CONFIG.copy.success + prevEle.style.opacity = 1 + setTimeout(() => { prevEle.style.opacity = 0 }, 700) + } + } else { + if (GLOBAL_CONFIG.Snackbar !== undefined) { + btf.snackbarShow(GLOBAL_CONFIG.copy.noSupport) + } else { + ctx.previousElementSibling.textContent = GLOBAL_CONFIG.copy.noSupport + } + } + } + + // click events + const highlightCopyFn = ele => { + const $buttonParent = ele.parentNode + $buttonParent.classList.add('copy-true') + const selection = window.getSelection() + const range = document.createRange() + const preCodeSelector = isPrismjs ? 'pre code' : 'table .code pre' + range.selectNodeContents($buttonParent.querySelectorAll(`${preCodeSelector}`)[0]) + selection.removeAllRanges() + selection.addRange(range) + const text = selection.toString() + copy(text, ele.lastChild) + selection.removeAllRanges() + $buttonParent.classList.remove('copy-true') + } + + const highlightShrinkFn = ele => { + ele.classList.toggle('closed') + } + + const highlightToolsFn = function (e) { + const $target = e.target.classList + if ($target.contains('expand')) highlightShrinkFn(this) + else if ($target.contains('copy-button')) highlightCopyFn(this) + } + + const expandCode = function () { + this.classList.toggle('expand-done') + } + + const createEle = (lang, item, service) => { + const fragment = document.createDocumentFragment() + + if (isShowTool) { + const hlTools = document.createElement('div') + hlTools.className = `highlight-tools ${highlightShrinkClass}` + hlTools.innerHTML = highlightShrinkEle + lang + highlightCopyEle + btf.addEventListenerPjax(hlTools, 'click', highlightToolsFn) + fragment.appendChild(hlTools) + } + + if (highlightHeightLimit && item.offsetHeight > highlightHeightLimit + 30) { + const ele = document.createElement('div') + ele.className = 'code-expand-btn' + ele.innerHTML = '' + btf.addEventListenerPjax(ele, 'click', expandCode) + fragment.appendChild(ele) + } + + if (service === 'hl') { + item.insertBefore(fragment, item.firstChild) + } else { + item.parentNode.insertBefore(fragment, item) + } + } + + if (isPrismjs) { + $figureHighlight.forEach(item => { + if (highlightLang) { + const langName = item.getAttribute('data-language') || 'Code' + const highlightLangEle = `
${langName}
` + btf.wrap(item, 'figure', { class: 'highlight' }) + createEle(highlightLangEle, item) + } else { + btf.wrap(item, 'figure', { class: 'highlight' }) + createEle('', item) + } + }) + } else { + $figureHighlight.forEach(item => { + if (highlightLang) { + let langName = item.getAttribute('class').split(' ')[1] + if (langName === 'plain' || langName === undefined) langName = 'Code' + const highlightLangEle = `
${langName}
` + createEle(highlightLangEle, item, 'hl') + } else { + createEle('', item, 'hl') + } + }) + } + } + + /** + * PhotoFigcaption + */ + const addPhotoFigcaption = () => { + document.querySelectorAll('#article-container img').forEach(item => { + const altValue = item.title || item.alt + if (!altValue) return + const ele = document.createElement('div') + ele.className = 'img-alt is-center' + ele.textContent = altValue + item.insertAdjacentElement('afterend', ele) + }) + } + + /** + * Lightbox + */ + const runLightbox = () => { + btf.loadLightbox(document.querySelectorAll('#article-container img:not(.no-lightbox)')) + } + + /** + * justified-gallery 圖庫排版 + */ + + const fetchUrl = async (url) => { + const response = await fetch(url) + return await response.json() + } + + const runJustifiedGallery = (item, data, isButton = false, tabs) => { + const dataLength = data.length + + const ig = new InfiniteGrid.JustifiedInfiniteGrid(item, { + gap: 5, + isConstantSize: true, + sizeRange: [150, 600], + useResizeObserver: true, + observeChildren: true, + useTransform: true + // useRecycle: false + }) + + if (tabs) { + btf.addGlobalFn('igOfTabs', () => { ig.destroy() }, false, tabs) + } + + const replaceDq = str => str.replace(/"/g, '"') // replace double quotes to " + + const getItems = (nextGroupKey, count) => { + const nextItems = [] + const startCount = (nextGroupKey - 1) * count + + for (let i = 0; i < count; ++i) { + const num = startCount + i + if (num >= dataLength) { + break + } + + const item = data[num] + const alt = item.alt ? `alt="${replaceDq(item.alt)}"` : '' + const title = item.title ? `title="${replaceDq(item.title)}"` : '' + + nextItems.push(`
+ +
`) + } + return nextItems + } + + const buttonText = GLOBAL_CONFIG.infinitegrid.buttonText + const addButton = item => { + const button = document.createElement('button') + button.textContent = buttonText + + const buttonFn = e => { + e.target.removeEventListener('click', buttonFn) + e.target.remove() + btf.setLoading.add(item) + appendItem(ig.getGroups().length + 1, 10) + } + + button.addEventListener('click', buttonFn) + item.insertAdjacentElement('afterend', button) + } + + const appendItem = (nextGroupKey, count) => { + ig.append(getItems(nextGroupKey, count), nextGroupKey) + } + + const maxGroupKey = Math.ceil(dataLength / 10) + + const completeFn = e => { + const { updated, isResize, mounted } = e + if (!updated.length || !mounted.length || isResize) { + return + } + + btf.loadLightbox(item.querySelectorAll('img:not(.medium-zoom-image)')) + + if (ig.getGroups().length === maxGroupKey) { + btf.setLoading.remove(item) + ig.off('renderComplete', completeFn) + return + } + + if (isButton) { + btf.setLoading.remove(item) + addButton(item) + } + } + + const requestAppendFn = btf.debounce(e => { + const nextGroupKey = (+e.groupKey || 0) + 1 + appendItem(nextGroupKey, 10) + + if (nextGroupKey === maxGroupKey) { + ig.off('requestAppend', requestAppendFn) + } + }, 300) + + btf.setLoading.add(item) + ig.on('renderComplete', completeFn) + + if (isButton) { + appendItem(1, 10) + } else { + ig.on('requestAppend', requestAppendFn) + ig.renderItems() + } + + btf.addGlobalFn('justifiedGallery', () => { ig.destroy() }) + } + + const addJustifiedGallery = async (ele, tabs = false) => { + const init = async () => { + for (const item of ele) { + if (btf.isHidden(item)) continue + if (tabs && item.classList.contains('loaded')) { + item.querySelector('.gallery-items').innerHTML = '' + const button = item.querySelector(':scope > button') + const loadingContainer = item.querySelector(':scope > .loading-container') + button && button.remove() + loadingContainer && loadingContainer.remove() + } + + const isButton = item.getAttribute('data-button') === 'true' + const text = item.firstElementChild.textContent + item.classList.add('loaded') + const content = item.getAttribute('data-type') === 'url' ? await fetchUrl(text) : JSON.parse(text) + runJustifiedGallery(item.lastElementChild, content, isButton, tabs) + } + } + + if (typeof InfiniteGrid === 'function') { + init() + } else { + await getScript(`${GLOBAL_CONFIG.infinitegrid.js}`) + init() + } + } + + /** + * rightside scroll percent + */ + const rightsideScrollPercent = currentTop => { + const scrollPercent = btf.getScrollPercent(currentTop, document.body) + const goUpElement = document.getElementById('go-up') + + if (scrollPercent < 95) { + goUpElement.classList.add('show-percent') + goUpElement.querySelector('.scroll-percent').textContent = scrollPercent + } else { + goUpElement.classList.remove('show-percent') + } + } + + /** + * 滾動處理 + */ + const scrollFn = () => { + const $rightside = document.getElementById('rightside') + const innerHeight = window.innerHeight + 56 + let initTop = 0 + const $header = document.getElementById('page-header') + const isChatBtn = typeof chatBtn !== 'undefined' + const isShowPercent = GLOBAL_CONFIG.percent.rightside + + // 當滾動條小于 56 的時候 + if (document.body.scrollHeight <= innerHeight) { + $rightside.classList.add('rightside-show') + return + } + + // find the scroll direction + const scrollDirection = currentTop => { + const result = currentTop > initTop // true is down & false is up + initTop = currentTop + return result + } + + let flag = '' + const scrollTask = btf.throttle(() => { + const currentTop = window.scrollY || document.documentElement.scrollTop + const isDown = scrollDirection(currentTop) + if (currentTop > 56) { + if (flag === '') { + $header.classList.add('nav-fixed') + $rightside.classList.add('rightside-show') + } + + if (isDown) { + if (flag !== 'down') { + $header.classList.remove('nav-visible') + isChatBtn && window.chatBtn.hide() + flag = 'down' + } + } else { + if (flag !== 'up') { + $header.classList.add('nav-visible') + isChatBtn && window.chatBtn.show() + flag = 'up' + } + } + } else { + flag = '' + if (currentTop === 0) { + $header.classList.remove('nav-fixed', 'nav-visible') + } + $rightside.classList.remove('rightside-show') + } + + isShowPercent && rightsideScrollPercent(currentTop) + + if (document.body.scrollHeight <= innerHeight) { + $rightside.classList.add('rightside-show') + } + }, 300) + + btf.addEventListenerPjax(window, 'scroll', scrollTask, { passive: true }) + } + + /** + * toc,anchor + */ + const scrollFnToDo = () => { + const isToc = GLOBAL_CONFIG_SITE.isToc + const isAnchor = GLOBAL_CONFIG.isAnchor + const $article = document.getElementById('article-container') + + if (!($article && (isToc || isAnchor))) return + + let $tocLink, $cardToc, autoScrollToc, $tocPercentage, isExpand + + if (isToc) { + const $cardTocLayout = document.getElementById('card-toc') + $cardToc = $cardTocLayout.querySelector('.toc-content') + $tocLink = $cardToc.querySelectorAll('.toc-link') + $tocPercentage = $cardTocLayout.querySelector('.toc-percentage') + isExpand = $cardToc.classList.contains('is-expand') + + // toc元素點擊 + const tocItemClickFn = e => { + const target = e.target.closest('.toc-link') + if (!target) return + + e.preventDefault() + btf.scrollToDest(btf.getEleTop(document.getElementById(decodeURI(target.getAttribute('href')).replace('#', ''))), 300) + if (window.innerWidth < 900) { + $cardTocLayout.classList.remove('open') + } + } + + btf.addEventListenerPjax($cardToc, 'click', tocItemClickFn) + + autoScrollToc = item => { + const activePosition = item.getBoundingClientRect().top + const sidebarScrollTop = $cardToc.scrollTop + if (activePosition > (document.documentElement.clientHeight - 100)) { + $cardToc.scrollTop = sidebarScrollTop + 150 + } + if (activePosition < 100) { + $cardToc.scrollTop = sidebarScrollTop - 150 + } + } + } + + // find head position & add active class + const $articleList = $article.querySelectorAll('h1,h2,h3,h4,h5,h6') + let detectItem = '' + const findHeadPosition = top => { + if (top === 0) { + return false + } + + let currentId = '' + let currentIndex = '' + + $articleList.forEach((ele, index) => { + if (top > btf.getEleTop(ele) - 80) { + const id = ele.id + currentId = id ? '#' + encodeURI(id) : '' + currentIndex = index + } + }) + + if (detectItem === currentIndex) return + + if (isAnchor) btf.updateAnchor(currentId) + + detectItem = currentIndex + + if (isToc) { + $cardToc.querySelectorAll('.active').forEach(i => { i.classList.remove('active') }) + + if (currentId === '') { + return + } + + const currentActive = $tocLink[currentIndex] + currentActive.classList.add('active') + + setTimeout(() => { + autoScrollToc(currentActive) + }, 0) + + if (isExpand) return + let parent = currentActive.parentNode + + for (; !parent.matches('.toc'); parent = parent.parentNode) { + if (parent.matches('li')) parent.classList.add('active') + } + } + } + + // main of scroll + const tocScrollFn = btf.throttle(() => { + const currentTop = window.scrollY || document.documentElement.scrollTop + if (isToc && GLOBAL_CONFIG.percent.toc) { + $tocPercentage.textContent = btf.getScrollPercent(currentTop, $article) + } + findHeadPosition(currentTop) + }, 100) + + btf.addEventListenerPjax(window, 'scroll', tocScrollFn, { passive: true }) + } + + const handleThemeChange = mode => { + const globalFn = window.globalFn || {} + const themeChange = globalFn.themeChange || {} + if (!themeChange) { + return + } + + Object.keys(themeChange).forEach(key => { + const themeChangeFn = themeChange[key] + if (['disqus', 'disqusjs'].includes(key)) { + setTimeout(() => themeChangeFn(mode), 300) + } else { + themeChangeFn(mode) + } + }) + } + + /** + * Rightside + */ + const rightSideFn = { + readmode: () => { // read mode + const $body = document.body + $body.classList.add('read-mode') + const newEle = document.createElement('button') + newEle.type = 'button' + newEle.className = 'fas fa-sign-out-alt exit-readmode' + $body.appendChild(newEle) + + const clickFn = () => { + $body.classList.remove('read-mode') + newEle.remove() + newEle.removeEventListener('click', clickFn) + } + + newEle.addEventListener('click', clickFn) + }, + darkmode: () => { // switch between light and dark mode + const willChangeMode = document.documentElement.getAttribute('data-theme') === 'dark' ? 'light' : 'dark' + if (willChangeMode === 'dark') { + activateDarkMode() + GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.day_to_night) + } else { + activateLightMode() + GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.night_to_day) + } + saveToLocal.set('theme', willChangeMode, 2) + handleThemeChange(willChangeMode) + }, + 'rightside-config': item => { // Show or hide rightside-hide-btn + const hideLayout = item.firstElementChild + if (hideLayout.classList.contains('show')) { + hideLayout.classList.add('status') + setTimeout(() => { + hideLayout.classList.remove('status') + }, 300) + } + + hideLayout.classList.toggle('show') + }, + 'go-up': () => { // Back to top + btf.scrollToDest(0, 500) + }, + 'hide-aside-btn': () => { // Hide aside + const $htmlDom = document.documentElement.classList + const saveStatus = $htmlDom.contains('hide-aside') ? 'show' : 'hide' + saveToLocal.set('aside-status', saveStatus, 2) + $htmlDom.toggle('hide-aside') + }, + 'mobile-toc-button': item => { // Show mobile toc + const tocEle = document.getElementById('card-toc') + tocEle.style.transition = 'transform 0.3s ease-in-out' + tocEle.classList.toggle('open') + tocEle.addEventListener('transitionend', () => { + tocEle.style.transition = '' + }, { once: true }) + }, + 'chat-btn': () => { // Show chat + window.chatBtnFn() + }, + translateLink: () => { // switch between traditional and simplified chinese + window.translateFn.translatePage() + } + } + + document.getElementById('rightside').addEventListener('click', function (e) { + const $target = e.target.closest('[id]') + if ($target && rightSideFn[$target.id]) { + rightSideFn[$target.id](this) + } + }) + + /** + * menu + * 側邊欄sub-menu 展開/收縮 + */ + const clickFnOfSubMenu = () => { + const handleClickOfSubMenu = e => { + const target = e.target.closest('.site-page.group') + if (!target) return + target.classList.toggle('hide') + } + + document.querySelector('#sidebar-menus .menus_items').addEventListener('click', handleClickOfSubMenu) + } + + /** + * 手机端目录点击 + */ + const openMobileMenu = () => { + const handleClick = () => { sidebarFn.open() } + btf.addEventListenerPjax(document.getElementById('toggle-menu'), 'click', handleClick) + } + + /** + * 複製時加上版權信息 + */ + const addCopyright = () => { + const { limitCount, languages } = GLOBAL_CONFIG.copyright + + const handleCopy = (e) => { + e.preventDefault() + const copyFont = window.getSelection(0).toString() + let textFont = copyFont + if (copyFont.length > limitCount) { + textFont = `${copyFont}\n\n\n${languages.author}\n${languages.link}${window.location.href}\n${languages.source}\n${languages.info}` + } + if (e.clipboardData) { + return e.clipboardData.setData('text', textFont) + } else { + return window.clipboardData.setData('text', textFont) + } + } + + document.body.addEventListener('copy', handleCopy) + } + + /** + * 網頁運行時間 + */ + const addRuntime = () => { + const $runtimeCount = document.getElementById('runtimeshow') + if ($runtimeCount) { + const publishDate = $runtimeCount.getAttribute('data-publishDate') + $runtimeCount.textContent = `${btf.diffDate(publishDate)} ${GLOBAL_CONFIG.runtime}` + } + } + + /** + * 最後一次更新時間 + */ + const addLastPushDate = () => { + const $lastPushDateItem = document.getElementById('last-push-date') + if ($lastPushDateItem) { + const lastPushDate = $lastPushDateItem.getAttribute('data-lastPushDate') + $lastPushDateItem.textContent = btf.diffDate(lastPushDate, true) + } + } + + /** + * table overflow + */ + const addTableWrap = () => { + const $table = document.querySelectorAll('#article-container table') + if (!$table.length) return + + $table.forEach(item => { + if (!item.closest('.highlight')) { + btf.wrap(item, 'div', { class: 'table-wrap' }) + } + }) + } + + /** + * tag-hide + */ + const clickFnOfTagHide = () => { + const hideButtons = document.querySelectorAll('#article-container .hide-button') + if (!hideButtons.length) return + const handleClick = function (e) { + const $this = this + $this.classList.add('open') + const $fjGallery = $this.nextElementSibling.querySelectorAll('.gallery-container') + $fjGallery.length && addJustifiedGallery($fjGallery) + } + + hideButtons.forEach(item => { + item.addEventListener('click', handleClick, { once: true }) + }) + } + + const tabsFn = () => { + const navTabsElement = document.querySelectorAll('#article-container .tabs') + if (!navTabsElement.length) return + + const removeAndAddActiveClass = (elements, detect) => { + Array.from(elements).forEach(element => { + element.classList.remove('active') + if (element === detect || element.id === detect) { + element.classList.add('active') + } + }) + } + + const addTabNavEventListener = (item, isJustifiedGallery) => { + const navClickHandler = function (e) { + const target = e.target.closest('button') + if (target.classList.contains('active')) return + removeAndAddActiveClass(this.children, target) + this.classList.remove('no-default') + const tabId = target.getAttribute('data-href') + const tabContent = this.nextElementSibling + removeAndAddActiveClass(tabContent.children, tabId) + if (isJustifiedGallery) { + btf.removeGlobalFnEvent('igOfTabs', this) + const justifiedGalleryItems = tabContent.querySelectorAll(`:scope > #${tabId} .gallery-container`) + justifiedGalleryItems.length && addJustifiedGallery(justifiedGalleryItems, this) + } + } + btf.addEventListenerPjax(item.firstElementChild, 'click', navClickHandler) + } + + const addTabToTopEventListener = item => { + const btnClickHandler = (e) => { + const target = e.target.closest('button') + if (!target) return + btf.scrollToDest(btf.getEleTop(item), 300) + } + btf.addEventListenerPjax(item.lastElementChild, 'click', btnClickHandler) + } + + navTabsElement.forEach(item => { + const isJustifiedGallery = !!item.querySelectorAll('.gallery-container') + addTabNavEventListener(item, isJustifiedGallery) + addTabToTopEventListener(item) + }) + } + + const toggleCardCategory = () => { + const cardCategory = document.querySelector('#aside-cat-list.expandBtn') + if (!cardCategory) return + + const handleToggleBtn = (e) => { + const target = e.target + if (target.nodeName === 'I') { + e.preventDefault() + target.parentNode.classList.toggle('expand') + } + } + btf.addEventListenerPjax(cardCategory, 'click', handleToggleBtn, true) + } + + const switchComments = () => { + const switchBtn = document.getElementById('switch-btn') + if (!switchBtn) return + let switchDone = false + const commentContainer = document.getElementById('post-comment') + const handleSwitchBtn = () => { + commentContainer.classList.toggle('move') + if (!switchDone) { + switchDone = true + loadOtherComment() + } + } + btf.addEventListenerPjax(switchBtn, 'click', handleSwitchBtn) + } + + const addPostOutdateNotice = () => { + const { limitDay, messagePrev, messageNext, position } = GLOBAL_CONFIG.noticeOutdate + const diffDay = btf.diffDate(GLOBAL_CONFIG_SITE.postUpdate) + if (diffDay >= limitDay) { + const ele = document.createElement('div') + ele.className = 'post-outdate-notice' + ele.textContent = `${messagePrev} ${diffDay} ${messageNext}` + const $targetEle = document.getElementById('article-container') + if (position === 'top') { + $targetEle.insertBefore(ele, $targetEle.firstChild) + } else { + $targetEle.appendChild(ele) + } + } + } + + const lazyloadImg = () => { + window.lazyLoadInstance = new LazyLoad({ + elements_selector: 'img', + threshold: 0, + data_src: 'lazy-src' + }) + } + + const relativeDate = function (selector) { + selector.forEach(item => { + const timeVal = item.getAttribute('datetime') + item.textContent = btf.diffDate(timeVal, true) + item.style.display = 'inline' + }) + } + + const unRefreshFn = function () { + window.addEventListener('resize', () => { + adjustMenu(false) + mobileSidebarOpen && btf.isHidden(document.getElementById('toggle-menu')) && sidebarFn.close() + }) + + document.getElementById('menu-mask').addEventListener('click', e => { sidebarFn.close() }) + + clickFnOfSubMenu() + GLOBAL_CONFIG.islazyload && lazyloadImg() + GLOBAL_CONFIG.copyright !== undefined && addCopyright() + + if (GLOBAL_CONFIG.autoDarkmode) { + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { + if (saveToLocal.get('theme') !== undefined) return + e.matches ? handleThemeChange('dark') : handleThemeChange('light') + }) + } + } + + window.refreshFn = function () { + initAdjust() + + if (GLOBAL_CONFIG_SITE.isPost) { + GLOBAL_CONFIG.noticeOutdate !== undefined && addPostOutdateNotice() + GLOBAL_CONFIG.relativeDate.post && relativeDate(document.querySelectorAll('#post-meta time')) + } else { + GLOBAL_CONFIG.relativeDate.homepage && relativeDate(document.querySelectorAll('#recent-posts time')) + GLOBAL_CONFIG.runtime && addRuntime() + addLastPushDate() + toggleCardCategory() + } + + scrollFnToDo() + GLOBAL_CONFIG_SITE.isHome && scrollDownInIndex() + addHighlightTool() + GLOBAL_CONFIG.isPhotoFigcaption && addPhotoFigcaption() + scrollFn() + + btf.removeGlobalFnEvent('justifiedGallery') + const galleryContainer = document.querySelectorAll('#article-container .gallery-container') + galleryContainer.length && addJustifiedGallery(galleryContainer) + + runLightbox() + addTableWrap() + clickFnOfTagHide() + tabsFn() + switchComments() + openMobileMenu() + } + + refreshFn() + unRefreshFn() +}) diff --git a/js/search/algolia.js b/js/search/algolia.js new file mode 100644 index 000000000..9ce7b0ef5 --- /dev/null +++ b/js/search/algolia.js @@ -0,0 +1,177 @@ +window.addEventListener('load', () => { + const $searchMask = document.getElementById('search-mask') + const $searchDialog = document.querySelector('#algolia-search .search-dialog') + + const openSearch = () => { + const bodyStyle = document.body.style + bodyStyle.width = '100%' + bodyStyle.overflow = 'hidden' + btf.animateIn($searchMask, 'to_show 0.5s') + btf.animateIn($searchDialog, 'titleScale 0.5s') + setTimeout(() => { document.querySelector('#algolia-search .ais-SearchBox-input').focus() }, 100) + + // shortcut: ESC + document.addEventListener('keydown', function f (event) { + if (event.code === 'Escape') { + closeSearch() + document.removeEventListener('keydown', f) + } + }) + + fixSafariHeight() + window.addEventListener('resize', fixSafariHeight) + } + + const closeSearch = () => { + const bodyStyle = document.body.style + bodyStyle.width = '' + bodyStyle.overflow = '' + btf.animateOut($searchDialog, 'search_close .5s') + btf.animateOut($searchMask, 'to_hide 0.5s') + window.removeEventListener('resize', fixSafariHeight) + } + + // fix safari + const fixSafariHeight = () => { + if (window.innerWidth < 768) { + $searchDialog.style.setProperty('--search-height', window.innerHeight + 'px') + } + } + + const searchClickFn = () => { + btf.addEventListenerPjax(document.querySelector('#search-button > .search'), 'click', openSearch) + } + + const searchFnOnce = () => { + $searchMask.addEventListener('click', closeSearch) + document.querySelector('#algolia-search .search-close-button').addEventListener('click', closeSearch) + } + + const cutContent = content => { + if (content === '') return '' + + const firstOccur = content.indexOf('') + + let start = firstOccur - 30 + let end = firstOccur + 120 + let pre = '' + let post = '' + + if (start <= 0) { + start = 0 + end = 140 + } else { + pre = '...' + } + + if (end > content.length) { + end = content.length + } else { + post = '...' + } + + const matchContent = pre + content.substring(start, end) + post + return matchContent + } + + const algolia = GLOBAL_CONFIG.algolia + const isAlgoliaValid = algolia.appId && algolia.apiKey && algolia.indexName + if (!isAlgoliaValid) { + return console.error('Algolia setting is invalid!') + } + + const search = instantsearch({ + indexName: algolia.indexName, + /* global algoliasearch */ + searchClient: algoliasearch(algolia.appId, algolia.apiKey), + searchFunction (helper) { + helper.state.query && helper.search() + } + }) + + const configure = instantsearch.widgets.configure({ + hitsPerPage: 5 + }) + + const searchBox = instantsearch.widgets.searchBox({ + container: '#algolia-search-input', + showReset: false, + showSubmit: false, + placeholder: GLOBAL_CONFIG.algolia.languages.input_placeholder, + showLoadingIndicator: true + }) + + const hits = instantsearch.widgets.hits({ + container: '#algolia-hits', + templates: { + item (data) { + const link = data.permalink ? data.permalink : (GLOBAL_CONFIG.root + data.path) + const result = data._highlightResult + const content = result.contentStripTruncate + ? cutContent(result.contentStripTruncate.value) + : result.contentStrip + ? cutContent(result.contentStrip.value) + : result.content + ? cutContent(result.content.value) + : '' + return ` + + ${result.title.value || 'no-title'} +

${content}

+
` + }, + empty: function (data) { + return ( + '
' + + GLOBAL_CONFIG.algolia.languages.hits_empty.replace(/\$\{query}/, data.query) + + '
' + ) + } + } + }) + + const stats = instantsearch.widgets.stats({ + container: '#algolia-info > .algolia-stats', + templates: { + text: function (data) { + const stats = GLOBAL_CONFIG.algolia.languages.hits_stats + .replace(/\$\{hits}/, data.nbHits) + .replace(/\$\{time}/, data.processingTimeMS) + return ( + `
${stats}` + ) + } + } + }) + + const powerBy = instantsearch.widgets.poweredBy({ + container: '#algolia-info > .algolia-poweredBy' + }) + + const pagination = instantsearch.widgets.pagination({ + container: '#algolia-pagination', + totalPages: 5, + templates: { + first: '', + last: '', + previous: '', + next: '' + } + }) + + search.addWidgets([configure, searchBox, hits, stats, powerBy, pagination]) // add the widgets to the instantsearch instance + + search.start() + + searchClickFn() + searchFnOnce() + + window.addEventListener('pjax:complete', () => { + !btf.isHidden($searchMask) && closeSearch() + searchClickFn() + }) + + window.pjax && search.on('render', () => { + window.pjax.refresh(document.getElementById('algolia-hits')) + }) +}) diff --git a/js/search/local-search.js b/js/search/local-search.js new file mode 100644 index 000000000..0eecff6b0 --- /dev/null +++ b/js/search/local-search.js @@ -0,0 +1,364 @@ +/** + * Refer to hexo-generator-searchdb + * https://github.com/next-theme/hexo-generator-searchdb/blob/main/dist/search.js + * Modified by hexo-theme-butterfly + */ + +class LocalSearch { + constructor ({ + path = '', + unescape = false, + top_n_per_article = 1 + }) { + this.path = path + this.unescape = unescape + this.top_n_per_article = top_n_per_article + this.isfetched = false + this.datas = null + } + + getIndexByWord (words, text, caseSensitive = false) { + const index = [] + const included = new Set() + + if (!caseSensitive) { + text = text.toLowerCase() + } + words.forEach(word => { + if (this.unescape) { + const div = document.createElement('div') + div.innerText = word + word = div.innerHTML + } + const wordLen = word.length + if (wordLen === 0) return + let startPosition = 0 + let position = -1 + if (!caseSensitive) { + word = word.toLowerCase() + } + while ((position = text.indexOf(word, startPosition)) > -1) { + index.push({ position, word }) + included.add(word) + startPosition = position + wordLen + } + }) + // Sort index by position of keyword + index.sort((left, right) => { + if (left.position !== right.position) { + return left.position - right.position + } + return right.word.length - left.word.length + }) + return [index, included] + } + + // Merge hits into slices + mergeIntoSlice (start, end, index) { + let item = index[0] + let { position, word } = item + const hits = [] + const count = new Set() + while (position + word.length <= end && index.length !== 0) { + count.add(word) + hits.push({ + position, + length: word.length + }) + const wordEnd = position + word.length + + // Move to next position of hit + index.shift() + while (index.length !== 0) { + item = index[0] + position = item.position + word = item.word + if (wordEnd > position) { + index.shift() + } else { + break + } + } + } + return { + hits, + start, + end, + count: count.size + } + } + + // Highlight title and content + highlightKeyword (val, slice) { + let result = '' + let index = slice.start + for (const { position, length } of slice.hits) { + result += val.substring(index, position) + index = position + length + result += `${val.substr(position, length)}` + } + result += val.substring(index, slice.end) + return result + } + + getResultItems (keywords) { + const resultItems = [] + this.datas.forEach(({ title, content, url }) => { + // The number of different keywords included in the article. + const [indexOfTitle, keysOfTitle] = this.getIndexByWord(keywords, title) + const [indexOfContent, keysOfContent] = this.getIndexByWord(keywords, content) + const includedCount = new Set([...keysOfTitle, ...keysOfContent]).size + + // Show search results + const hitCount = indexOfTitle.length + indexOfContent.length + if (hitCount === 0) return + + const slicesOfTitle = [] + if (indexOfTitle.length !== 0) { + slicesOfTitle.push(this.mergeIntoSlice(0, title.length, indexOfTitle)) + } + + let slicesOfContent = [] + while (indexOfContent.length !== 0) { + const item = indexOfContent[0] + const { position } = item + // Cut out 120 characters. The maxlength of .search-input is 80. + const start = Math.max(0, position - 20) + const end = Math.min(content.length, position + 100) + slicesOfContent.push(this.mergeIntoSlice(start, end, indexOfContent)) + } + + // Sort slices in content by included keywords' count and hits' count + slicesOfContent.sort((left, right) => { + if (left.count !== right.count) { + return right.count - left.count + } else if (left.hits.length !== right.hits.length) { + return right.hits.length - left.hits.length + } + return left.start - right.start + }) + + // Select top N slices in content + const upperBound = parseInt(this.top_n_per_article, 10) + if (upperBound >= 0) { + slicesOfContent = slicesOfContent.slice(0, upperBound) + } + + let resultItem = '' + + url = new URL(url, location.origin) + url.searchParams.append('highlight', keywords.join(' ')) + + if (slicesOfTitle.length !== 0) { + resultItem += `
${this.highlightKeyword(title, slicesOfTitle[0])}` + } else { + resultItem += `' + resultItems.push({ + item: resultItem, + id: resultItems.length, + hitCount, + includedCount + }) + }) + return resultItems + } + + fetchData () { + const isXml = !this.path.endsWith('json') + fetch(this.path) + .then(response => response.text()) + .then(res => { + // Get the contents from search data + this.isfetched = true + this.datas = isXml + ? [...new DOMParser().parseFromString(res, 'text/xml').querySelectorAll('entry')].map(element => ({ + title: element.querySelector('title').textContent, + content: element.querySelector('content').textContent, + url: element.querySelector('url').textContent + })) + : JSON.parse(res) + // Only match articles with non-empty titles + this.datas = this.datas.filter(data => data.title).map(data => { + data.title = data.title.trim() + data.content = data.content ? data.content.trim().replace(/<[^>]+>/g, '') : '' + data.url = decodeURIComponent(data.url).replace(/\/{2,}/g, '/') + return data + }) + // Remove loading animation + window.dispatchEvent(new Event('search:loaded')) + }) + } + + // Highlight by wrapping node in mark elements with the given class name + highlightText (node, slice, className) { + const val = node.nodeValue + let index = slice.start + const children = [] + for (const { position, length } of slice.hits) { + const text = document.createTextNode(val.substring(index, position)) + index = position + length + const mark = document.createElement('mark') + mark.className = className + mark.appendChild(document.createTextNode(val.substr(position, length))) + children.push(text, mark) + } + node.nodeValue = val.substring(index, slice.end) + children.forEach(element => { + node.parentNode.insertBefore(element, node) + }) + } + + // Highlight the search words provided in the url in the text + highlightSearchWords (body) { + const params = new URL(location.href).searchParams.get('highlight') + const keywords = params ? params.split(' ') : [] + if (!keywords.length || !body) return + const walk = document.createTreeWalker(body, NodeFilter.SHOW_TEXT, null) + const allNodes = [] + while (walk.nextNode()) { + if (!walk.currentNode.parentNode.matches('button, select, textarea, .mermaid')) allNodes.push(walk.currentNode) + } + allNodes.forEach(node => { + const [indexOfNode] = this.getIndexByWord(keywords, node.nodeValue) + if (!indexOfNode.length) return + const slice = this.mergeIntoSlice(0, node.nodeValue.length, indexOfNode) + this.highlightText(node, slice, 'search-keyword') + }) + } +} + +window.addEventListener('load', () => { +// Search + const { path, top_n_per_article, unescape, languages } = GLOBAL_CONFIG.localSearch + const localSearch = new LocalSearch({ + path, + top_n_per_article, + unescape + }) + + const input = document.querySelector('#local-search-input input') + const statsItem = document.getElementById('local-search-stats-wrap') + const $loadingStatus = document.getElementById('loading-status') + const isXml = !path.endsWith('json') + + const inputEventFunction = () => { + if (!localSearch.isfetched) return + let searchText = input.value.trim().toLowerCase() + isXml && (searchText = searchText.replace(//g, '>')) + if (searchText !== '') $loadingStatus.innerHTML = '' + const keywords = searchText.split(/[-\s]+/) + const container = document.getElementById('local-search-results') + let resultItems = [] + if (searchText.length > 0) { + // Perform local searching + resultItems = localSearch.getResultItems(keywords) + } + if (keywords.length === 1 && keywords[0] === '') { + container.textContent = '' + statsItem.textContent = '' + } else if (resultItems.length === 0) { + container.textContent = '' + const statsDiv = document.createElement('div') + statsDiv.className = 'search-result-stats' + statsDiv.textContent = languages.hits_empty.replace(/\$\{query}/, searchText) + statsItem.innerHTML = statsDiv.outerHTML + } else { + resultItems.sort((left, right) => { + if (left.includedCount !== right.includedCount) { + return right.includedCount - left.includedCount + } else if (left.hitCount !== right.hitCount) { + return right.hitCount - left.hitCount + } + return right.id - left.id + }) + + const stats = languages.hits_stats.replace(/\$\{hits}/, resultItems.length) + + container.innerHTML = `
${resultItems.map(result => result.item).join('')}
` + statsItem.innerHTML = `
${stats}
` + window.pjax && window.pjax.refresh(container) + } + + $loadingStatus.textContent = '' + } + + let loadFlag = false + const $searchMask = document.getElementById('search-mask') + const $searchDialog = document.querySelector('#local-search .search-dialog') + + // fix safari + const fixSafariHeight = () => { + if (window.innerWidth < 768) { + $searchDialog.style.setProperty('--search-height', window.innerHeight + 'px') + } + } + + const openSearch = () => { + const bodyStyle = document.body.style + bodyStyle.width = '100%' + bodyStyle.overflow = 'hidden' + btf.animateIn($searchMask, 'to_show 0.5s') + btf.animateIn($searchDialog, 'titleScale 0.5s') + setTimeout(() => { input.focus() }, 300) + if (!loadFlag) { + !localSearch.isfetched && localSearch.fetchData() + input.addEventListener('input', inputEventFunction) + loadFlag = true + } + // shortcut: ESC + document.addEventListener('keydown', function f (event) { + if (event.code === 'Escape') { + closeSearch() + document.removeEventListener('keydown', f) + } + }) + + fixSafariHeight() + window.addEventListener('resize', fixSafariHeight) + } + + const closeSearch = () => { + const bodyStyle = document.body.style + bodyStyle.width = '' + bodyStyle.overflow = '' + btf.animateOut($searchDialog, 'search_close .5s') + btf.animateOut($searchMask, 'to_hide 0.5s') + window.removeEventListener('resize', fixSafariHeight) + } + + const searchClickFn = () => { + btf.addEventListenerPjax(document.querySelector('#search-button > .search'), 'click', openSearch) + } + + const searchFnOnce = () => { + document.querySelector('#local-search .search-close-button').addEventListener('click', closeSearch) + $searchMask.addEventListener('click', closeSearch) + if (GLOBAL_CONFIG.localSearch.preload) { + localSearch.fetchData() + } + localSearch.highlightSearchWords(document.getElementById('article-container')) + } + + window.addEventListener('search:loaded', () => { + const $loadDataItem = document.getElementById('loading-database') + $loadDataItem.nextElementSibling.style.display = 'block' + $loadDataItem.remove() + }) + + searchClickFn() + searchFnOnce() + + // pjax + window.addEventListener('pjax:complete', () => { + !btf.isHidden($searchMask) && closeSearch() + localSearch.highlightSearchWords(document.getElementById('article-container')) + searchClickFn() + }) +}) diff --git a/js/tw_cn.js b/js/tw_cn.js new file mode 100644 index 000000000..15d8d1531 --- /dev/null +++ b/js/tw_cn.js @@ -0,0 +1,122 @@ +document.addEventListener('DOMContentLoaded', function () { + const { defaultEncoding, translateDelay, msgToTraditionalChinese, msgToSimplifiedChinese } = GLOBAL_CONFIG.translate + const snackbarData = GLOBAL_CONFIG.Snackbar + let currentEncoding = defaultEncoding + const targetEncodingCookie = 'translate-chn-cht' + let targetEncoding = + saveToLocal.get(targetEncodingCookie) === undefined + ? defaultEncoding + : Number(saveToLocal.get('translate-chn-cht')) + let translateButtonObject + const isSnackbar = snackbarData !== undefined + + function setLang () { + document.documentElement.lang = targetEncoding === 1 ? 'zh-TW' : 'zh-CN' + } + + function translateText (txt) { + if (txt === '' || txt == null) return '' + if (currentEncoding === 1 && targetEncoding === 2) return Simplized(txt) + else if (currentEncoding === 2 && targetEncoding === 1) { + return Traditionalized(txt) + } else return txt + } + + function translateBody (fobj) { + let objs + if (typeof fobj === 'object') objs = fobj.childNodes + else objs = document.body.childNodes + for (let i = 0; i < objs.length; i++) { + const obj = objs.item(i) + if ( + '||BR|HR|'.indexOf('|' + obj.tagName + '|') > 0 || + obj === translateButtonObject + ) { + continue + } + if (obj.title !== '' && obj.title != null) { + obj.title = translateText(obj.title) + } + if (obj.alt !== '' && obj.alt != null) obj.alt = translateText(obj.alt) + if (obj.placeholder !== '' && obj.placeholder != null) { obj.placeholder = translateText(obj.placeholder) } + if ( + obj.tagName === 'INPUT' && + obj.value !== '' && + obj.type !== 'text' && + obj.type !== 'hidden' + ) { + obj.value = translateText(obj.value) + } + if (obj.nodeType === 3) obj.data = translateText(obj.data) + else translateBody(obj) + } + } + function translatePage () { + if (targetEncoding === 1) { + currentEncoding = 1 + targetEncoding = 2 + translateButtonObject.textContent = msgToTraditionalChinese + isSnackbar && btf.snackbarShow(snackbarData.cht_to_chs) + } else if (targetEncoding === 2) { + currentEncoding = 2 + targetEncoding = 1 + translateButtonObject.textContent = msgToSimplifiedChinese + isSnackbar && btf.snackbarShow(snackbarData.chs_to_cht) + } + saveToLocal.set(targetEncodingCookie, targetEncoding, 2) + setLang() + translateBody() + } + + function JTPYStr () { + return '万与丑专业丛东丝丢两严丧个丬丰临为丽举么义乌乐乔习乡书买乱争于亏云亘亚产亩亲亵亸亿仅从仑仓仪们价众优伙会伛伞伟传伤伥伦伧伪伫体余佣佥侠侣侥侦侧侨侩侪侬俣俦俨俩俪俭债倾偬偻偾偿傥傧储傩儿兑兖党兰关兴兹养兽冁内冈册写军农冢冯冲决况冻净凄凉凌减凑凛几凤凫凭凯击凼凿刍划刘则刚创删别刬刭刽刿剀剂剐剑剥剧劝办务劢动励劲劳势勋勐勚匀匦匮区医华协单卖卢卤卧卫却卺厂厅历厉压厌厍厕厢厣厦厨厩厮县参叆叇双发变叙叠叶号叹叽吁后吓吕吗吣吨听启吴呒呓呕呖呗员呙呛呜咏咔咙咛咝咤咴咸哌响哑哒哓哔哕哗哙哜哝哟唛唝唠唡唢唣唤唿啧啬啭啮啰啴啸喷喽喾嗫呵嗳嘘嘤嘱噜噼嚣嚯团园囱围囵国图圆圣圹场坂坏块坚坛坜坝坞坟坠垄垅垆垒垦垧垩垫垭垯垱垲垴埘埙埚埝埯堑堕塆墙壮声壳壶壸处备复够头夸夹夺奁奂奋奖奥妆妇妈妩妪妫姗姜娄娅娆娇娈娱娲娴婳婴婵婶媪嫒嫔嫱嬷孙学孪宁宝实宠审宪宫宽宾寝对寻导寿将尔尘尧尴尸尽层屃屉届属屡屦屿岁岂岖岗岘岙岚岛岭岳岽岿峃峄峡峣峤峥峦崂崃崄崭嵘嵚嵛嵝嵴巅巩巯币帅师帏帐帘帜带帧帮帱帻帼幂幞干并广庄庆庐庑库应庙庞废庼廪开异弃张弥弪弯弹强归当录彟彦彻径徕御忆忏忧忾怀态怂怃怄怅怆怜总怼怿恋恳恶恸恹恺恻恼恽悦悫悬悭悯惊惧惨惩惫惬惭惮惯愍愠愤愦愿慑慭憷懑懒懔戆戋戏戗战戬户扎扑扦执扩扪扫扬扰抚抛抟抠抡抢护报担拟拢拣拥拦拧拨择挂挚挛挜挝挞挟挠挡挢挣挤挥挦捞损捡换捣据捻掳掴掷掸掺掼揸揽揿搀搁搂搅携摄摅摆摇摈摊撄撑撵撷撸撺擞攒敌敛数斋斓斗斩断无旧时旷旸昙昼昽显晋晒晓晔晕晖暂暧札术朴机杀杂权条来杨杩杰极构枞枢枣枥枧枨枪枫枭柜柠柽栀栅标栈栉栊栋栌栎栏树栖样栾桊桠桡桢档桤桥桦桧桨桩梦梼梾检棂椁椟椠椤椭楼榄榇榈榉槚槛槟槠横樯樱橥橱橹橼檐檩欢欤欧歼殁殇残殒殓殚殡殴毁毂毕毙毡毵氇气氢氩氲汇汉污汤汹沓沟没沣沤沥沦沧沨沩沪沵泞泪泶泷泸泺泻泼泽泾洁洒洼浃浅浆浇浈浉浊测浍济浏浐浑浒浓浔浕涂涌涛涝涞涟涠涡涢涣涤润涧涨涩淀渊渌渍渎渐渑渔渖渗温游湾湿溃溅溆溇滗滚滞滟滠满滢滤滥滦滨滩滪漤潆潇潋潍潜潴澜濑濒灏灭灯灵灾灿炀炉炖炜炝点炼炽烁烂烃烛烟烦烧烨烩烫烬热焕焖焘煅煳熘爱爷牍牦牵牺犊犟状犷犸犹狈狍狝狞独狭狮狯狰狱狲猃猎猕猡猪猫猬献獭玑玙玚玛玮环现玱玺珉珏珐珑珰珲琎琏琐琼瑶瑷璇璎瓒瓮瓯电画畅畲畴疖疗疟疠疡疬疮疯疱疴痈痉痒痖痨痪痫痴瘅瘆瘗瘘瘪瘫瘾瘿癞癣癫癯皑皱皲盏盐监盖盗盘眍眦眬着睁睐睑瞒瞩矫矶矾矿砀码砖砗砚砜砺砻砾础硁硅硕硖硗硙硚确硷碍碛碜碱碹磙礼祎祢祯祷祸禀禄禅离秃秆种积称秽秾稆税稣稳穑穷窃窍窑窜窝窥窦窭竖竞笃笋笔笕笺笼笾筑筚筛筜筝筹签简箓箦箧箨箩箪箫篑篓篮篱簖籁籴类籼粜粝粤粪粮糁糇紧絷纟纠纡红纣纤纥约级纨纩纪纫纬纭纮纯纰纱纲纳纴纵纶纷纸纹纺纻纼纽纾线绀绁绂练组绅细织终绉绊绋绌绍绎经绐绑绒结绔绕绖绗绘给绚绛络绝绞统绠绡绢绣绤绥绦继绨绩绪绫绬续绮绯绰绱绲绳维绵绶绷绸绹绺绻综绽绾绿缀缁缂缃缄缅缆缇缈缉缊缋缌缍缎缏缐缑缒缓缔缕编缗缘缙缚缛缜缝缞缟缠缡缢缣缤缥缦缧缨缩缪缫缬缭缮缯缰缱缲缳缴缵罂网罗罚罢罴羁羟羡翘翙翚耢耧耸耻聂聋职聍联聩聪肃肠肤肷肾肿胀胁胆胜胧胨胪胫胶脉脍脏脐脑脓脔脚脱脶脸腊腌腘腭腻腼腽腾膑臜舆舣舰舱舻艰艳艹艺节芈芗芜芦苁苇苈苋苌苍苎苏苘苹茎茏茑茔茕茧荆荐荙荚荛荜荞荟荠荡荣荤荥荦荧荨荩荪荫荬荭荮药莅莜莱莲莳莴莶获莸莹莺莼萚萝萤营萦萧萨葱蒇蒉蒋蒌蓝蓟蓠蓣蓥蓦蔷蔹蔺蔼蕲蕴薮藁藓虏虑虚虫虬虮虽虾虿蚀蚁蚂蚕蚝蚬蛊蛎蛏蛮蛰蛱蛲蛳蛴蜕蜗蜡蝇蝈蝉蝎蝼蝾螀螨蟏衅衔补衬衮袄袅袆袜袭袯装裆裈裢裣裤裥褛褴襁襕见观觃规觅视觇览觉觊觋觌觍觎觏觐觑觞触觯詟誉誊讠计订讣认讥讦讧讨让讪讫训议讯记讱讲讳讴讵讶讷许讹论讻讼讽设访诀证诂诃评诅识诇诈诉诊诋诌词诎诏诐译诒诓诔试诖诗诘诙诚诛诜话诞诟诠诡询诣诤该详诧诨诩诪诫诬语诮误诰诱诲诳说诵诶请诸诹诺读诼诽课诿谀谁谂调谄谅谆谇谈谊谋谌谍谎谏谐谑谒谓谔谕谖谗谘谙谚谛谜谝谞谟谠谡谢谣谤谥谦谧谨谩谪谫谬谭谮谯谰谱谲谳谴谵谶谷豮贝贞负贠贡财责贤败账货质贩贪贫贬购贮贯贰贱贲贳贴贵贶贷贸费贺贻贼贽贾贿赀赁赂赃资赅赆赇赈赉赊赋赌赍赎赏赐赑赒赓赔赕赖赗赘赙赚赛赜赝赞赟赠赡赢赣赪赵赶趋趱趸跃跄跖跞践跶跷跸跹跻踊踌踪踬踯蹑蹒蹰蹿躏躜躯车轧轨轩轪轫转轭轮软轰轱轲轳轴轵轶轷轸轹轺轻轼载轾轿辀辁辂较辄辅辆辇辈辉辊辋辌辍辎辏辐辑辒输辔辕辖辗辘辙辚辞辩辫边辽达迁过迈运还这进远违连迟迩迳迹适选逊递逦逻遗遥邓邝邬邮邹邺邻郁郄郏郐郑郓郦郧郸酝酦酱酽酾酿释里鉅鉴銮錾钆钇针钉钊钋钌钍钎钏钐钑钒钓钔钕钖钗钘钙钚钛钝钞钟钠钡钢钣钤钥钦钧钨钩钪钫钬钭钮钯钰钱钲钳钴钵钶钷钸钹钺钻钼钽钾钿铀铁铂铃铄铅铆铈铉铊铋铍铎铏铐铑铒铕铗铘铙铚铛铜铝铞铟铠铡铢铣铤铥铦铧铨铪铫铬铭铮铯铰铱铲铳铴铵银铷铸铹铺铻铼铽链铿销锁锂锃锄锅锆锇锈锉锊锋锌锍锎锏锐锑锒锓锔锕锖锗错锚锜锞锟锠锡锢锣锤锥锦锨锩锫锬锭键锯锰锱锲锳锴锵锶锷锸锹锺锻锼锽锾锿镀镁镂镃镆镇镈镉镊镌镍镎镏镐镑镒镕镖镗镙镚镛镜镝镞镟镠镡镢镣镤镥镦镧镨镩镪镫镬镭镮镯镰镱镲镳镴镶长门闩闪闫闬闭问闯闰闱闲闳间闵闶闷闸闹闺闻闼闽闾闿阀阁阂阃阄阅阆阇阈阉阊阋阌阍阎阏阐阑阒阓阔阕阖阗阘阙阚阛队阳阴阵阶际陆陇陈陉陕陧陨险随隐隶隽难雏雠雳雾霁霉霭靓静靥鞑鞒鞯鞴韦韧韨韩韪韫韬韵页顶顷顸项顺须顼顽顾顿颀颁颂颃预颅领颇颈颉颊颋颌颍颎颏颐频颒颓颔颕颖颗题颙颚颛颜额颞颟颠颡颢颣颤颥颦颧风飏飐飑飒飓飔飕飖飗飘飙飚飞飨餍饤饥饦饧饨饩饪饫饬饭饮饯饰饱饲饳饴饵饶饷饸饹饺饻饼饽饾饿馀馁馂馃馄馅馆馇馈馉馊馋馌馍馎馏馐馑馒馓馔馕马驭驮驯驰驱驲驳驴驵驶驷驸驹驺驻驼驽驾驿骀骁骂骃骄骅骆骇骈骉骊骋验骍骎骏骐骑骒骓骔骕骖骗骘骙骚骛骜骝骞骟骠骡骢骣骤骥骦骧髅髋髌鬓魇魉鱼鱽鱾鱿鲀鲁鲂鲄鲅鲆鲇鲈鲉鲊鲋鲌鲍鲎鲏鲐鲑鲒鲓鲔鲕鲖鲗鲘鲙鲚鲛鲜鲝鲞鲟鲠鲡鲢鲣鲤鲥鲦鲧鲨鲩鲪鲫鲬鲭鲮鲯鲰鲱鲲鲳鲴鲵鲶鲷鲸鲹鲺鲻鲼鲽鲾鲿鳀鳁鳂鳃鳄鳅鳆鳇鳈鳉鳊鳋鳌鳍鳎鳏鳐鳑鳒鳓鳔鳕鳖鳗鳘鳙鳛鳜鳝鳞鳟鳠鳡鳢鳣鸟鸠鸡鸢鸣鸤鸥鸦鸧鸨鸩鸪鸫鸬鸭鸮鸯鸰鸱鸲鸳鸴鸵鸶鸷鸸鸹鸺鸻鸼鸽鸾鸿鹀鹁鹂鹃鹄鹅鹆鹇鹈鹉鹊鹋鹌鹍鹎鹏鹐鹑鹒鹓鹔鹕鹖鹗鹘鹚鹛鹜鹝鹞鹟鹠鹡鹢鹣鹤鹥鹦鹧鹨鹩鹪鹫鹬鹭鹯鹰鹱鹲鹳鹴鹾麦麸黄黉黡黩黪黾龙历志制一台皋准复猛钟注范签' + } + function FTPYStr () { + return '萬與醜專業叢東絲丟兩嚴喪個爿豐臨為麗舉麼義烏樂喬習鄉書買亂爭於虧雲亙亞產畝親褻嚲億僅從侖倉儀們價眾優夥會傴傘偉傳傷倀倫傖偽佇體餘傭僉俠侶僥偵側僑儈儕儂俁儔儼倆儷儉債傾傯僂僨償儻儐儲儺兒兌兗黨蘭關興茲養獸囅內岡冊寫軍農塚馮衝決況凍淨淒涼淩減湊凜幾鳳鳧憑凱擊氹鑿芻劃劉則剛創刪別剗剄劊劌剴劑剮劍剝劇勸辦務勱動勵勁勞勢勳猛勩勻匭匱區醫華協單賣盧鹵臥衛卻巹廠廳曆厲壓厭厙廁廂厴廈廚廄廝縣參靉靆雙發變敘疊葉號歎嘰籲後嚇呂嗎唚噸聽啟吳嘸囈嘔嚦唄員咼嗆嗚詠哢嚨嚀噝吒噅鹹呱響啞噠嘵嗶噦嘩噲嚌噥喲嘜嗊嘮啢嗩唕喚呼嘖嗇囀齧囉嘽嘯噴嘍嚳囁嗬噯噓嚶囑嚕劈囂謔團園囪圍圇國圖圓聖壙場阪壞塊堅壇壢壩塢墳墜壟壟壚壘墾坰堊墊埡墶壋塏堖塒塤堝墊垵塹墮壪牆壯聲殼壺壼處備複夠頭誇夾奪奩奐奮獎奧妝婦媽嫵嫗媯姍薑婁婭嬈嬌孌娛媧嫻嫿嬰嬋嬸媼嬡嬪嬙嬤孫學孿寧寶實寵審憲宮寬賓寢對尋導壽將爾塵堯尷屍盡層屭屜屆屬屢屨嶼歲豈嶇崗峴嶴嵐島嶺嶽崠巋嶨嶧峽嶢嶠崢巒嶗崍嶮嶄嶸嶔崳嶁脊巔鞏巰幣帥師幃帳簾幟帶幀幫幬幘幗冪襆幹並廣莊慶廬廡庫應廟龐廢廎廩開異棄張彌弳彎彈強歸當錄彠彥徹徑徠禦憶懺憂愾懷態慫憮慪悵愴憐總懟懌戀懇惡慟懨愷惻惱惲悅愨懸慳憫驚懼慘懲憊愜慚憚慣湣慍憤憒願懾憖怵懣懶懍戇戔戲戧戰戩戶紮撲扡執擴捫掃揚擾撫拋摶摳掄搶護報擔擬攏揀擁攔擰撥擇掛摯攣掗撾撻挾撓擋撟掙擠揮撏撈損撿換搗據撚擄摑擲撣摻摜摣攬撳攙擱摟攪攜攝攄擺搖擯攤攖撐攆擷擼攛擻攢敵斂數齋斕鬥斬斷無舊時曠暘曇晝曨顯晉曬曉曄暈暉暫曖劄術樸機殺雜權條來楊榪傑極構樅樞棗櫪梘棖槍楓梟櫃檸檉梔柵標棧櫛櫳棟櫨櫟欄樹棲樣欒棬椏橈楨檔榿橋樺檜槳樁夢檮棶檢欞槨櫝槧欏橢樓欖櫬櫚櫸檟檻檳櫧橫檣櫻櫫櫥櫓櫞簷檁歡歟歐殲歿殤殘殞殮殫殯毆毀轂畢斃氈毿氌氣氫氬氳彙漢汙湯洶遝溝沒灃漚瀝淪滄渢溈滬濔濘淚澩瀧瀘濼瀉潑澤涇潔灑窪浹淺漿澆湞溮濁測澮濟瀏滻渾滸濃潯濜塗湧濤澇淶漣潿渦溳渙滌潤澗漲澀澱淵淥漬瀆漸澠漁瀋滲溫遊灣濕潰濺漵漊潷滾滯灩灄滿瀅濾濫灤濱灘澦濫瀠瀟瀲濰潛瀦瀾瀨瀕灝滅燈靈災燦煬爐燉煒熗點煉熾爍爛烴燭煙煩燒燁燴燙燼熱煥燜燾煆糊溜愛爺牘犛牽犧犢強狀獷獁猶狽麅獮獰獨狹獅獪猙獄猻獫獵獼玀豬貓蝟獻獺璣璵瑒瑪瑋環現瑲璽瑉玨琺瓏璫琿璡璉瑣瓊瑤璦璿瓔瓚甕甌電畫暢佘疇癤療瘧癘瘍鬁瘡瘋皰屙癰痙癢瘂癆瘓癇癡癉瘮瘞瘺癟癱癮癭癩癬癲臒皚皺皸盞鹽監蓋盜盤瞘眥矓著睜睞瞼瞞矚矯磯礬礦碭碼磚硨硯碸礪礱礫礎硜矽碩硤磽磑礄確鹼礙磧磣堿镟滾禮禕禰禎禱禍稟祿禪離禿稈種積稱穢穠穭稅穌穩穡窮竊竅窯竄窩窺竇窶豎競篤筍筆筧箋籠籩築篳篩簹箏籌簽簡籙簀篋籜籮簞簫簣簍籃籬籪籟糴類秈糶糲粵糞糧糝餱緊縶糸糾紆紅紂纖紇約級紈纊紀紉緯紜紘純紕紗綱納紝縱綸紛紙紋紡紵紖紐紓線紺絏紱練組紳細織終縐絆紼絀紹繹經紿綁絨結絝繞絰絎繪給絢絳絡絕絞統綆綃絹繡綌綏絛繼綈績緒綾緓續綺緋綽緔緄繩維綿綬繃綢綯綹綣綜綻綰綠綴緇緙緗緘緬纜緹緲緝縕繢緦綞緞緶線緱縋緩締縷編緡緣縉縛縟縝縫縗縞纏縭縊縑繽縹縵縲纓縮繆繅纈繚繕繒韁繾繰繯繳纘罌網羅罰罷羆羈羥羨翹翽翬耮耬聳恥聶聾職聹聯聵聰肅腸膚膁腎腫脹脅膽勝朧腖臚脛膠脈膾髒臍腦膿臠腳脫腡臉臘醃膕齶膩靦膃騰臏臢輿艤艦艙艫艱豔艸藝節羋薌蕪蘆蓯葦藶莧萇蒼苧蘇檾蘋莖蘢蔦塋煢繭荊薦薘莢蕘蓽蕎薈薺蕩榮葷滎犖熒蕁藎蓀蔭蕒葒葤藥蒞蓧萊蓮蒔萵薟獲蕕瑩鶯蓴蘀蘿螢營縈蕭薩蔥蕆蕢蔣蔞藍薊蘺蕷鎣驀薔蘞藺藹蘄蘊藪槁蘚虜慮虛蟲虯蟣雖蝦蠆蝕蟻螞蠶蠔蜆蠱蠣蟶蠻蟄蛺蟯螄蠐蛻蝸蠟蠅蟈蟬蠍螻蠑螿蟎蠨釁銜補襯袞襖嫋褘襪襲襏裝襠褌褳襝褲襇褸襤繈襴見觀覎規覓視覘覽覺覬覡覿覥覦覯覲覷觴觸觶讋譽謄訁計訂訃認譏訐訌討讓訕訖訓議訊記訒講諱謳詎訝訥許訛論訩訟諷設訪訣證詁訶評詛識詗詐訴診詆謅詞詘詔詖譯詒誆誄試詿詩詰詼誠誅詵話誕詬詮詭詢詣諍該詳詫諢詡譸誡誣語誚誤誥誘誨誑說誦誒請諸諏諾讀諑誹課諉諛誰諗調諂諒諄誶談誼謀諶諜謊諫諧謔謁謂諤諭諼讒諮諳諺諦謎諞諝謨讜謖謝謠謗諡謙謐謹謾謫譾謬譚譖譙讕譜譎讞譴譫讖穀豶貝貞負貟貢財責賢敗賬貨質販貪貧貶購貯貫貳賤賁貰貼貴貺貸貿費賀貽賊贄賈賄貲賃賂贓資賅贐賕賑賚賒賦賭齎贖賞賜贔賙賡賠賧賴賵贅賻賺賽賾贗讚贇贈贍贏贛赬趙趕趨趲躉躍蹌蹠躒踐躂蹺蹕躚躋踴躊蹤躓躑躡蹣躕躥躪躦軀車軋軌軒軑軔轉軛輪軟轟軲軻轤軸軹軼軤軫轢軺輕軾載輊轎輈輇輅較輒輔輛輦輩輝輥輞輬輟輜輳輻輯轀輸轡轅轄輾轆轍轔辭辯辮邊遼達遷過邁運還這進遠違連遲邇逕跡適選遜遞邐邏遺遙鄧鄺鄔郵鄒鄴鄰鬱郤郟鄶鄭鄆酈鄖鄲醞醱醬釅釃釀釋裏钜鑒鑾鏨釓釔針釘釗釙釕釷釺釧釤鈒釩釣鍆釹鍚釵鈃鈣鈈鈦鈍鈔鍾鈉鋇鋼鈑鈐鑰欽鈞鎢鉤鈧鈁鈥鈄鈕鈀鈺錢鉦鉗鈷缽鈳鉕鈽鈸鉞鑽鉬鉭鉀鈿鈾鐵鉑鈴鑠鉛鉚鈰鉉鉈鉍鈹鐸鉶銬銠鉺銪鋏鋣鐃銍鐺銅鋁銱銦鎧鍘銖銑鋌銩銛鏵銓鉿銚鉻銘錚銫鉸銥鏟銃鐋銨銀銣鑄鐒鋪鋙錸鋱鏈鏗銷鎖鋰鋥鋤鍋鋯鋨鏽銼鋝鋒鋅鋶鐦鐧銳銻鋃鋟鋦錒錆鍺錯錨錡錁錕錩錫錮鑼錘錐錦鍁錈錇錟錠鍵鋸錳錙鍥鍈鍇鏘鍶鍔鍤鍬鍾鍛鎪鍠鍰鎄鍍鎂鏤鎡鏌鎮鎛鎘鑷鐫鎳鎿鎦鎬鎊鎰鎔鏢鏜鏍鏰鏞鏡鏑鏃鏇鏐鐔钁鐐鏷鑥鐓鑭鐠鑹鏹鐙鑊鐳鐶鐲鐮鐿鑔鑣鑞鑲長門閂閃閆閈閉問闖閏闈閑閎間閔閌悶閘鬧閨聞闥閩閭闓閥閣閡閫鬮閱閬闍閾閹閶鬩閿閽閻閼闡闌闃闠闊闋闔闐闒闕闞闤隊陽陰陣階際陸隴陳陘陝隉隕險隨隱隸雋難雛讎靂霧霽黴靄靚靜靨韃鞽韉韝韋韌韍韓韙韞韜韻頁頂頃頇項順須頊頑顧頓頎頒頌頏預顱領頗頸頡頰頲頜潁熲頦頤頻頮頹頷頴穎顆題顒顎顓顏額顳顢顛顙顥纇顫顬顰顴風颺颭颮颯颶颸颼颻飀飄飆飆飛饗饜飣饑飥餳飩餼飪飫飭飯飲餞飾飽飼飿飴餌饒餉餄餎餃餏餅餑餖餓餘餒餕餜餛餡館餷饋餶餿饞饁饃餺餾饈饉饅饊饌饢馬馭馱馴馳驅馹駁驢駔駛駟駙駒騶駐駝駑駕驛駘驍罵駰驕驊駱駭駢驫驪騁驗騂駸駿騏騎騍騅騌驌驂騙騭騤騷騖驁騮騫騸驃騾驄驏驟驥驦驤髏髖髕鬢魘魎魚魛魢魷魨魯魴魺鮁鮃鯰鱸鮋鮓鮒鮊鮑鱟鮍鮐鮭鮚鮳鮪鮞鮦鰂鮜鱠鱭鮫鮮鮺鯗鱘鯁鱺鰱鰹鯉鰣鰷鯀鯊鯇鮶鯽鯒鯖鯪鯕鯫鯡鯤鯧鯝鯢鯰鯛鯨鯵鯴鯔鱝鰈鰏鱨鯷鰮鰃鰓鱷鰍鰒鰉鰁鱂鯿鰠鼇鰭鰨鰥鰩鰟鰜鰳鰾鱈鱉鰻鰵鱅鰼鱖鱔鱗鱒鱯鱤鱧鱣鳥鳩雞鳶鳴鳲鷗鴉鶬鴇鴆鴣鶇鸕鴨鴞鴦鴒鴟鴝鴛鴬鴕鷥鷙鴯鴰鵂鴴鵃鴿鸞鴻鵐鵓鸝鵑鵠鵝鵒鷳鵜鵡鵲鶓鵪鶤鵯鵬鵮鶉鶊鵷鷫鶘鶡鶚鶻鶿鶥鶩鷊鷂鶲鶹鶺鷁鶼鶴鷖鸚鷓鷚鷯鷦鷲鷸鷺鸇鷹鸌鸏鸛鸘鹺麥麩黃黌黶黷黲黽龍歷誌製壹臺臯準復勐鐘註範籤' + } + function Traditionalized (cc) { + let str = '' + const ss = JTPYStr() + const tt = FTPYStr() + for (let i = 0; i < cc.length; i++) { + if (cc.charCodeAt(i) > 10000 && ss.indexOf(cc.charAt(i)) !== -1) { + str += tt.charAt(ss.indexOf(cc.charAt(i))) + } else str += cc.charAt(i) + } + return str + } + function Simplized (cc) { + let str = '' + const ss = JTPYStr() + const tt = FTPYStr() + for (let i = 0; i < cc.length; i++) { + if (cc.charCodeAt(i) > 10000 && tt.indexOf(cc.charAt(i)) !== -1) { + str += ss.charAt(tt.indexOf(cc.charAt(i))) + } else str += cc.charAt(i) + } + return str + } + + function translateInitialization () { + translateButtonObject = document.getElementById('translateLink') + if (translateButtonObject) { + if (currentEncoding !== targetEncoding) { + translateButtonObject.textContent = + targetEncoding === 1 + ? msgToSimplifiedChinese + : msgToTraditionalChinese + setLang() + setTimeout(translateBody, translateDelay) + } + } + } + + window.translateFn = { + translatePage, + Traditionalized, + Simplized + } + + translateInitialization() + document.addEventListener('pjax:complete', translateInitialization) +}) diff --git a/js/utils.js b/js/utils.js new file mode 100644 index 000000000..2c8242ca0 --- /dev/null +++ b/js/utils.js @@ -0,0 +1,296 @@ +const btf = { + debounce: (func, wait = 0, immediate = false) => { + let timeout + return (...args) => { + const later = () => { + timeout = null + if (!immediate) func(...args) + } + const callNow = immediate && !timeout + clearTimeout(timeout) + timeout = setTimeout(later, wait) + if (callNow) func(...args) + } + }, + + throttle: function (func, wait, options = {}) { + let timeout, context, args + let previous = 0 + + const later = () => { + previous = options.leading === false ? 0 : new Date().getTime() + timeout = null + func.apply(context, args) + if (!timeout) context = args = null + } + + const throttled = (...params) => { + const now = new Date().getTime() + if (!previous && options.leading === false) previous = now + const remaining = wait - (now - previous) + context = this + args = params + if (remaining <= 0 || remaining > wait) { + if (timeout) { + clearTimeout(timeout) + timeout = null + } + previous = now + func.apply(context, args) + if (!timeout) context = args = null + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining) + } + } + + return throttled + }, + + sidebarPaddingR: () => { + const innerWidth = window.innerWidth + const clientWidth = document.body.clientWidth + const paddingRight = innerWidth - clientWidth + if (innerWidth !== clientWidth) { + document.body.style.paddingRight = paddingRight + 'px' + } + }, + + snackbarShow: (text, showAction = false, duration = 2000) => { + const { position, bgLight, bgDark } = GLOBAL_CONFIG.Snackbar + const bg = document.documentElement.getAttribute('data-theme') === 'light' ? bgLight : bgDark + Snackbar.show({ + text, + backgroundColor: bg, + showAction, + duration, + pos: position, + customClass: 'snackbar-css' + }) + }, + + diffDate: (d, more = false) => { + const dateNow = new Date() + const datePost = new Date(d) + const dateDiff = dateNow.getTime() - datePost.getTime() + const minute = 1000 * 60 + const hour = minute * 60 + const day = hour * 24 + const month = day * 30 + const { dateSuffix } = GLOBAL_CONFIG + + if (!more) return parseInt(dateDiff / day) + + const monthCount = dateDiff / month + const dayCount = dateDiff / day + const hourCount = dateDiff / hour + const minuteCount = dateDiff / minute + + if (monthCount > 12) return datePost.toISOString().slice(0, 10) + if (monthCount >= 1) return `${parseInt(monthCount)} ${dateSuffix.month}` + if (dayCount >= 1) return `${parseInt(dayCount)} ${dateSuffix.day}` + if (hourCount >= 1) return `${parseInt(hourCount)} ${dateSuffix.hour}` + if (minuteCount >= 1) return `${parseInt(minuteCount)} ${dateSuffix.min}` + return dateSuffix.just + }, + + loadComment: (dom, callback) => { + if ('IntersectionObserver' in window) { + const observerItem = new IntersectionObserver((entries) => { + if (entries[0].isIntersecting) { + callback() + observerItem.disconnect() + } + }, { threshold: [0] }) + observerItem.observe(dom) + } else { + callback() + } + }, + + scrollToDest: (pos, time = 500) => { + const currentPos = window.pageYOffset + const isNavFixed = document.getElementById('page-header').classList.contains('fixed') + if (currentPos > pos || isNavFixed) pos = pos - 70 + + if ('scrollBehavior' in document.documentElement.style) { + window.scrollTo({ + top: pos, + behavior: 'smooth' + }) + return + } + + let start = null + pos = +pos + window.requestAnimationFrame(function step (currentTime) { + start = !start ? currentTime : start + const progress = currentTime - start + if (currentPos < pos) { + window.scrollTo(0, ((pos - currentPos) * progress / time) + currentPos) + } else { + window.scrollTo(0, currentPos - ((currentPos - pos) * progress / time)) + } + if (progress < time) { + window.requestAnimationFrame(step) + } else { + window.scrollTo(0, pos) + } + }) + }, + + animateIn: (ele, text) => { + ele.style.display = 'block' + ele.style.animation = text + }, + + animateOut: (ele, text) => { + ele.addEventListener('animationend', function f () { + ele.style.display = '' + ele.style.animation = '' + ele.removeEventListener('animationend', f) + }) + ele.style.animation = text + }, + + wrap: (selector, eleType, options) => { + const createEle = document.createElement(eleType) + for (const [key, value] of Object.entries(options)) { + createEle.setAttribute(key, value) + } + selector.parentNode.insertBefore(createEle, selector) + createEle.appendChild(selector) + }, + + isHidden: ele => ele.offsetHeight === 0 && ele.offsetWidth === 0, + + getEleTop: ele => { + let actualTop = ele.offsetTop + let current = ele.offsetParent + + while (current !== null) { + actualTop += current.offsetTop + current = current.offsetParent + } + + return actualTop + }, + + loadLightbox: ele => { + const service = GLOBAL_CONFIG.lightbox + + if (service === 'mediumZoom') { + mediumZoom(ele, { background: 'var(--zoom-bg)' }) + } + + if (service === 'fancybox') { + Array.from(ele).forEach(i => { + if (i.parentNode.tagName !== 'A') { + const dataSrc = i.dataset.lazySrc || i.src + const dataCaption = i.title || i.alt || '' + btf.wrap(i, 'a', { href: dataSrc, 'data-fancybox': 'gallery', 'data-caption': dataCaption, 'data-thumb': dataSrc }) + } + }) + + if (!window.fancyboxRun) { + Fancybox.bind('[data-fancybox]', { + Hash: false, + Thumbs: { + showOnStart: false + }, + Images: { + Panzoom: { + maxScale: 4 + } + }, + Carousel: { + transition: 'slide' + }, + Toolbar: { + display: { + left: ['infobar'], + middle: [ + 'zoomIn', + 'zoomOut', + 'toggle1to1', + 'rotateCCW', + 'rotateCW', + 'flipX', + 'flipY' + ], + right: ['slideshow', 'thumbs', 'close'] + } + } + }) + window.fancyboxRun = true + } + } + }, + + setLoading: { + add: ele => { + const html = ` +
+
+
+
+
+ ` + ele.insertAdjacentHTML('afterend', html) + }, + remove: ele => { + ele.nextElementSibling.remove() + } + }, + + updateAnchor: (anchor) => { + if (anchor !== window.location.hash) { + if (!anchor) anchor = location.pathname + const title = GLOBAL_CONFIG_SITE.title + window.history.replaceState({ + url: location.href, + title + }, title, anchor) + } + }, + + getScrollPercent: (currentTop, ele) => { + const docHeight = ele.clientHeight + const winHeight = document.documentElement.clientHeight + const headerHeight = ele.offsetTop + const contentMath = (docHeight > winHeight) ? (docHeight - winHeight) : (document.documentElement.scrollHeight - winHeight) + const scrollPercent = (currentTop - headerHeight) / (contentMath) + const scrollPercentRounded = Math.round(scrollPercent * 100) + const percentage = (scrollPercentRounded > 100) ? 100 : (scrollPercentRounded <= 0) ? 0 : scrollPercentRounded + return percentage + }, + + addGlobalFn: (key, fn, name = false, parent = window) => { + const globalFn = parent.globalFn || {} + const keyObj = globalFn[key] || {} + + if (name && keyObj[name]) return + + name = name || Object.keys(keyObj).length + keyObj[name] = fn + globalFn[key] = keyObj + parent.globalFn = globalFn + }, + + addEventListenerPjax: (ele, event, fn, option = false) => { + ele.addEventListener(event, fn, option) + btf.addGlobalFn('pjax', () => { + ele.removeEventListener(event, fn, option) + }) + }, + + removeGlobalFnEvent: (key, parent = window) => { + const { globalFn = {} } = parent + const keyObj = globalFn[key] || {} + const keyArr = Object.keys(keyObj) + if (!keyArr.length) return + keyArr.forEach(i => { + keyObj[i]() + }) + delete parent.globalFn[key] + } +} diff --git a/page/2/index.html b/page/2/index.html new file mode 100644 index 000000000..7d4bbe62e --- /dev/null +++ b/page/2/index.html @@ -0,0 +1,269 @@ +Maple's Blog + + + + + + + +
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/tags/Auto-Test/index.html b/tags/Auto-Test/index.html new file mode 100644 index 000000000..5a09651a5 --- /dev/null +++ b/tags/Auto-Test/index.html @@ -0,0 +1,159 @@ +标签: Auto Test | Maple's Blog + + + + + + + +
标签 - Auto Test
2018
Jest自动化测试简介
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/tags/IT/index.html b/tags/IT/index.html new file mode 100644 index 000000000..cd45d2762 --- /dev/null +++ b/tags/IT/index.html @@ -0,0 +1,159 @@ +标签: IT | Maple's Blog + + + + + + + +
标签 - IT
2018
软件开发生命周期
软件开发生命周期
2017
Hello World
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/tags/Jekyll/index.html b/tags/Jekyll/index.html new file mode 100644 index 000000000..93acf3236 --- /dev/null +++ b/tags/Jekyll/index.html @@ -0,0 +1,159 @@ +标签: Jekyll | Maple's Blog + + + + + + + +
标签 - Jekyll
2016
安装静态博客Jekyll
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/tags/Poetry/index.html b/tags/Poetry/index.html new file mode 100644 index 000000000..2f242669d --- /dev/null +++ b/tags/Poetry/index.html @@ -0,0 +1,159 @@ +标签: Poetry | Maple's Blog + + + + + + + +
标签 - Poetry
2018
残诗
2017
夜雨
南湖向晚
趁黄昏
吹雪
2016
不得不说再见
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/tags/SSD/index.html b/tags/SSD/index.html new file mode 100644 index 000000000..741e7fbd1 --- /dev/null +++ b/tags/SSD/index.html @@ -0,0 +1,159 @@ +标签: SSD | Maple's Blog + + + + + + + +
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/tags/ShadowSocks/index.html b/tags/ShadowSocks/index.html new file mode 100644 index 000000000..82810068c --- /dev/null +++ b/tags/ShadowSocks/index.html @@ -0,0 +1,159 @@ +标签: ShadowSocks | Maple's Blog + + + + + + + +
标签 - ShadowSocks
2015
安装 ShadowScoks
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/tags/UML/index.html b/tags/UML/index.html new file mode 100644 index 000000000..eaf8ce161 --- /dev/null +++ b/tags/UML/index.html @@ -0,0 +1,159 @@ +标签: UML | Maple's Blog + + + + + + + +
标签 - UML
2017
plantuml简介
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/tags/Ubuntu/index.html b/tags/Ubuntu/index.html new file mode 100644 index 000000000..4df72a23e --- /dev/null +++ b/tags/Ubuntu/index.html @@ -0,0 +1,159 @@ +标签: Ubuntu | Maple's Blog + + + + + + + +
标签 - Ubuntu
2015
Ubuntu用户设置
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/tags/VS-Code/index.html b/tags/VS-Code/index.html new file mode 100644 index 000000000..cae049e9a --- /dev/null +++ b/tags/VS-Code/index.html @@ -0,0 +1,159 @@ +标签: VS Code | Maple's Blog + + + + + + + +
标签 - VS Code
2017
前端编程利器VS Code
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/tags/Webpack/index.html b/tags/Webpack/index.html new file mode 100644 index 000000000..982d7f664 --- /dev/null +++ b/tags/Webpack/index.html @@ -0,0 +1,159 @@ +标签: Webpack | Maple's Blog + + + + + + + +
标签 - Webpack
2018
模块化和Webpack入门
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/tags/Windows/index.html b/tags/Windows/index.html new file mode 100644 index 000000000..32005084c --- /dev/null +++ b/tags/Windows/index.html @@ -0,0 +1,159 @@ +标签: Windows | Maple's Blog + + + + + + + +
标签 - Windows
2015
win10右键反应缓慢
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file diff --git a/tags/index.html b/tags/index.html new file mode 100644 index 000000000..888db47ac --- /dev/null +++ b/tags/index.html @@ -0,0 +1,164 @@ +Tags | Maple's Blog + + + + + + + + + + + +
公告
This is my Blog
最新文章
+ + 分类 + +
+
网站资讯
文章数目 :
17
本站总字数 :
10.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
\ No newline at end of file