From ae766518438c155d550e6c8853306b19ee344199 Mon Sep 17 00:00:00 2001 From: zmr Date: Wed, 26 Apr 2023 14:12:09 +0800 Subject: [PATCH] Site updated: 2023-04-26 14:12:07 --- 2019/12/30/hello-world/index.html | 16 + 2020/01/03/VMware安装centos7/index.html | 16 + .../index.html | 16 + 2023/03/23/esxi8.0安装/index.html | 16 + 2023/03/24/esxi安装homeassistant/index.html | 16 + 2023/03/24/esxi安装openwrt/index.html | 16 + 2023/03/24/esxi安装群晖dsm7.1/index.html | 16 + 2023/03/26/esxi常规配置/index.html | 16 + about/index.html | 16 + archives/2019/12/index.html | 16 + archives/2019/index.html | 16 + archives/2020/01/index.html | 16 + archives/2020/index.html | 16 + archives/2023/03/index.html | 16 + archives/2023/index.html | 16 + archives/index.html | 16 + atom.xml | 188 ++ css/hbe.style.css | 749 ++++++ css/link.css | 3 + css/main.css | 9 + css/noscript.css | 3 + guestbook/index.html | 16 + images/apple-touch-icon-next.png | Bin 0 -> 1544 bytes images/avatar.gif | Bin 0 -> 1785 bytes images/favicon-16x16-next.png | Bin 0 -> 435 bytes images/favicon-32x32-next.png | Bin 0 -> 640 bytes images/logo-algolia-nebula-blue-full.svg | 1 + images/logo.svg | 1 + images/nh.jpg | Bin 0 -> 75589 bytes index.html | 16 + js/bookmark.js | 56 + js/comments-buttons.js | 25 + js/comments.js | 21 + js/config.js | 66 + js/cursor/explosion.min.js | 1 + js/cursor/fireworks.js | 154 ++ js/cursor/love.min.js | 1 + js/cursor/text.js | 24 + js/link.js | 26 + js/motion.js | 140 + js/next-boot.js | 75 + js/pjax.js | 50 + js/schedule.js | 138 + js/schemes/muse.js | 60 + js/tagcanvas.js | 2243 +++++++++++++++++ js/tagcloud.js | 1 + js/third-party/analytics/baidu-analytics.js | 7 + js/third-party/analytics/google-analytics.js | 35 + js/third-party/analytics/growingio.js | 10 + js/third-party/analytics/matomo.js | 19 + js/third-party/chat/chatra.js | 19 + js/third-party/chat/gitter.js | 5 + js/third-party/chat/tidio.js | 10 + js/third-party/comments/changyan.js | 39 + js/third-party/comments/disqus.js | 41 + js/third-party/comments/disqusjs.js | 23 + js/third-party/comments/gitalk.js | 24 + js/third-party/comments/isso.js | 15 + js/third-party/comments/livere.js | 19 + js/third-party/comments/utterances.js | 17 + js/third-party/fancybox.js | 38 + js/third-party/math/katex.js | 7 + js/third-party/math/mathjax.js | 36 + js/third-party/pace.js | 7 + js/third-party/quicklink.js | 37 + js/third-party/search/algolia-search.js | 130 + js/third-party/search/local-search.js | 99 + js/third-party/statistics/firestore.js | 60 + js/third-party/statistics/lean-analytics.js | 107 + js/third-party/tags/mermaid.js | 32 + js/third-party/tags/pdf.js | 23 + js/utils.js | 452 ++++ lib/hbe.js | 293 +++ lib/pace/LICENSE | 21 + lib/pace/README.html | 39 + lib/pace/pace-theme-barber-shop.min.css | 1 + lib/pace/pace-theme-big-counter.min.css | 1 + lib/pace/pace-theme-bounce.min.css | 1 + lib/pace/pace-theme-center-atom.min.css | 1 + lib/pace/pace-theme-center-circle.min.css | 1 + lib/pace/pace-theme-center-radar.min.css | 1 + lib/pace/pace-theme-center-simple.min.css | 1 + lib/pace/pace-theme-corner-indicator.min.css | 1 + lib/pace/pace-theme-fill-left.min.css | 1 + lib/pace/pace-theme-flash.min.css | 1 + lib/pace/pace-theme-flat-top.min.css | 1 + lib/pace/pace-theme-loading-bar.min.css | 1 + lib/pace/pace-theme-mac-osx.min.css | 1 + lib/pace/pace-theme-material.min.css | 1 + lib/pace/pace-theme-minimal.min.css | 1 + lib/pace/pace.min.js | 2 + links/index.html | 16 + links/linklist.json | 1 + placeholder | 0 search.xml | 476 ++++ tags/VMware/index.html | 16 + tags/centos/index.html | 16 + tags/dsm/index.html | 16 + tags/esxi/index.html | 16 + tags/homeassistant/index.html | 16 + tags/index.html | 16 + tags/openwrt/index.html | 16 + tags/旁路由/index.html | 16 + tags/群晖/index.html | 16 + tags/软路由/index.html | 16 + 105 files changed, 6657 insertions(+) create mode 100644 2019/12/30/hello-world/index.html create mode 100644 2020/01/03/VMware安装centos7/index.html create mode 100644 2023/03/23/esxi+openwrt+dsm+homeassistant-软路由all-in-one/index.html create mode 100644 2023/03/23/esxi8.0安装/index.html create mode 100644 2023/03/24/esxi安装homeassistant/index.html create mode 100644 2023/03/24/esxi安装openwrt/index.html create mode 100644 2023/03/24/esxi安装群晖dsm7.1/index.html create mode 100644 2023/03/26/esxi常规配置/index.html create mode 100644 about/index.html create mode 100644 archives/2019/12/index.html create mode 100644 archives/2019/index.html create mode 100644 archives/2020/01/index.html create mode 100644 archives/2020/index.html create mode 100644 archives/2023/03/index.html create mode 100644 archives/2023/index.html create mode 100644 archives/index.html create mode 100644 atom.xml create mode 100644 css/hbe.style.css create mode 100644 css/link.css create mode 100644 css/main.css create mode 100644 css/noscript.css create mode 100644 guestbook/index.html create mode 100644 images/apple-touch-icon-next.png create mode 100644 images/avatar.gif create mode 100644 images/favicon-16x16-next.png create mode 100644 images/favicon-32x32-next.png create mode 100644 images/logo-algolia-nebula-blue-full.svg create mode 100644 images/logo.svg create mode 100644 images/nh.jpg create mode 100644 index.html create mode 100644 js/bookmark.js create mode 100644 js/comments-buttons.js create mode 100644 js/comments.js create mode 100644 js/config.js create mode 100644 js/cursor/explosion.min.js create mode 100644 js/cursor/fireworks.js create mode 100644 js/cursor/love.min.js create mode 100644 js/cursor/text.js create mode 100644 js/link.js create mode 100644 js/motion.js create mode 100644 js/next-boot.js create mode 100644 js/pjax.js create mode 100644 js/schedule.js create mode 100644 js/schemes/muse.js create mode 100644 js/tagcanvas.js create mode 100644 js/tagcloud.js create mode 100644 js/third-party/analytics/baidu-analytics.js create mode 100644 js/third-party/analytics/google-analytics.js create mode 100644 js/third-party/analytics/growingio.js create mode 100644 js/third-party/analytics/matomo.js create mode 100644 js/third-party/chat/chatra.js create mode 100644 js/third-party/chat/gitter.js create mode 100644 js/third-party/chat/tidio.js create mode 100644 js/third-party/comments/changyan.js create mode 100644 js/third-party/comments/disqus.js create mode 100644 js/third-party/comments/disqusjs.js create mode 100644 js/third-party/comments/gitalk.js create mode 100644 js/third-party/comments/isso.js create mode 100644 js/third-party/comments/livere.js create mode 100644 js/third-party/comments/utterances.js create mode 100644 js/third-party/fancybox.js create mode 100644 js/third-party/math/katex.js create mode 100644 js/third-party/math/mathjax.js create mode 100644 js/third-party/pace.js create mode 100644 js/third-party/quicklink.js create mode 100644 js/third-party/search/algolia-search.js create mode 100644 js/third-party/search/local-search.js create mode 100644 js/third-party/statistics/firestore.js create mode 100644 js/third-party/statistics/lean-analytics.js create mode 100644 js/third-party/tags/mermaid.js create mode 100644 js/third-party/tags/pdf.js create mode 100644 js/utils.js create mode 100644 lib/hbe.js create mode 100644 lib/pace/LICENSE create mode 100644 lib/pace/README.html create mode 100644 lib/pace/pace-theme-barber-shop.min.css create mode 100644 lib/pace/pace-theme-big-counter.min.css create mode 100644 lib/pace/pace-theme-bounce.min.css create mode 100644 lib/pace/pace-theme-center-atom.min.css create mode 100644 lib/pace/pace-theme-center-circle.min.css create mode 100644 lib/pace/pace-theme-center-radar.min.css create mode 100644 lib/pace/pace-theme-center-simple.min.css create mode 100644 lib/pace/pace-theme-corner-indicator.min.css create mode 100644 lib/pace/pace-theme-fill-left.min.css create mode 100644 lib/pace/pace-theme-flash.min.css create mode 100644 lib/pace/pace-theme-flat-top.min.css create mode 100644 lib/pace/pace-theme-loading-bar.min.css create mode 100644 lib/pace/pace-theme-mac-osx.min.css create mode 100644 lib/pace/pace-theme-material.min.css create mode 100644 lib/pace/pace-theme-minimal.min.css create mode 100644 lib/pace/pace.min.js create mode 100644 links/index.html create mode 100644 links/linklist.json delete mode 100644 placeholder create mode 100644 search.xml create mode 100644 tags/VMware/index.html create mode 100644 tags/centos/index.html create mode 100644 tags/dsm/index.html create mode 100644 tags/esxi/index.html create mode 100644 tags/homeassistant/index.html create mode 100644 tags/index.html create mode 100644 tags/openwrt/index.html create mode 100644 tags/旁路由/index.html create mode 100644 tags/群晖/index.html create mode 100644 tags/软路由/index.html diff --git a/2019/12/30/hello-world/index.html b/2019/12/30/hello-world/index.html new file mode 100644 index 0000000..1a1765a --- /dev/null +++ b/2019/12/30/hello-world/index.html @@ -0,0 +1,16 @@ +Hello World | 随言碎语

随言碎语

咕叽咕叽

Hello World

欢迎来到我的博客,这是我的第一篇博客,由hexo+next构建。

0%
\ No newline at end of file diff --git a/2020/01/03/VMware安装centos7/index.html b/2020/01/03/VMware安装centos7/index.html new file mode 100644 index 0000000..4e19a5d --- /dev/null +++ b/2020/01/03/VMware安装centos7/index.html @@ -0,0 +1,16 @@ +VMware安装centos7 | 随言碎语

随言碎语

咕叽咕叽

VMware安装centos7

在VMware Workstation上安装centos。

1. 准备:

  • VMware Workstation

  • 镜像文件:CentOS-7-x86_64-bin-DVD1.iso

2. 新建虚拟机

  1. 新建虚拟机,选择自定义

  2. 硬盘兼容性–默认

image-20230422105921574

  1. 稍后安装操作系统(需要在虚拟机安装完成之后,删除不需要的硬件,所以稍后安装操作系统)

  2. 择客户端操作系统:客户机操作系统–Linux版本centos 64位

  3. 处理器配置(CPU)和内存,按需要配置

  4. 网络类型–桥接网络(可以使虚拟机与主机使用同一网络)

  • 注:若是NAT和仅主机模式,需要注意网卡的地址,创建的虚拟机和所使用的网卡在同一个网段。
  1. 选择I/O控制器类型、磁盘类型和创建新的虚拟磁盘(一般默认就行)

  2. 指定磁盘容量(不低于20G)

  3. 指定磁盘文件(.vmdk)文件

  4. 完成后,删除不必要的设备

    image-20230422111309578

  5. 选中CD/DVD,使用ISO镜像文件-选择镜像文件

    image-20230422111531776

12.确定后,打开这个虚拟机的电源

image-20230422114456361

3. 进入centos7安装页面

  1. 选择install centos7

image-20230422111901398

  1. 设置语言–使用中文-简体中文–点击继续

image-20230422114739708

  • 注:如果这里选择了中文简体,那么键盘布局一定要选择英文
  1. 进一步设置要安装的信息

    image-20230422115039348

    软件选择:这里我们选择最小化安装,即只有最基础的系统,没有桌面

    image-20230422115156841

  2. 系统安装位置,点进去进行自定义分区(如果没有特别的要求,默认分区也行)

    image-20230422115350829
    4.1 若需要自主分区,点击我要配置分区
    image-20230422115507917
    4.2 选择标准分组,点击**+**
    image-20230422115613958
    4.3 依次添加新挂载点:/boot;swap;/;
    image-20230422115944392
    注:

    • /boot 分区:是引导分区;作用:系统启动,在boot分区存放着grub,内核文件等,一般200M就够了。
    • swap交换分区:内存扩展分区;一般也就2G 。
    • / 根目录:10G左右,数据一般也不会直接放在根目录下。

    4.4 点击完成,接受更改即可。

    image-20230422120644423

  3. 关掉KDUMP

    image-20230422120802249

  4. 配置网络和主机名

    image-20230422120925893

    网络要根据自己的环境和需求去配置,配置后点击保存即可。

  5. 安全策略保持默认的即可,直接点击开始安装

    image-20230422121138262

  6. 设置用户名和密码(主要是设置root密码,创建用户可以不做)

    image-20230422121219185

    点击root密码,输入密码点击完成。

    image-20230422121357933

  7. 点击重启,等待系统安装完成即可使用了

    image-20230422121530317

0%
\ No newline at end of file diff --git a/2023/03/23/esxi+openwrt+dsm+homeassistant-软路由all-in-one/index.html b/2023/03/23/esxi+openwrt+dsm+homeassistant-软路由all-in-one/index.html new file mode 100644 index 0000000..593587c --- /dev/null +++ b/2023/03/23/esxi+openwrt+dsm+homeassistant-软路由all-in-one/index.html @@ -0,0 +1,16 @@ +esxi+openwrt+dsm+homeassistant 软路由 all in one | 随言碎语

随言碎语

咕叽咕叽

esxi+openwrt+dsm+homeassistant 软路由 all in one

软路由 all in one,在J425小主机上安装esxi+openwrt+dsm+homeassistant,集软路由、网盘、智能家居控制于一体。

硬件介绍

软件安装

  1. esxi8.0安装
  2. esxi+openwrt作为旁路由
  3. esxi安装群晖dsm7.1
  4. esxi安装homeassistant
0%
\ No newline at end of file diff --git a/2023/03/23/esxi8.0安装/index.html b/2023/03/23/esxi8.0安装/index.html new file mode 100644 index 0000000..a33991b --- /dev/null +++ b/2023/03/23/esxi8.0安装/index.html @@ -0,0 +1,16 @@ +esxi8.0安装 | 随言碎语

esxi8.0安装

esxi 8.0的安装。

准备工具

硬件:

  • 8G以上U盘一个
  • 待安装的主机一套

软件:

  • rufus-3.15p.exe 用来刻录镜像

  • VMware-VMvisor-Installer-8.0.0-21203435.x86_64-Dell_Customized-A03.iso

    注:这里使用的是DELL定制版本,其他版本可从官网下载。操作步骤都是一样的

刻录镜像到启动U盘

  1. 打开rufus-3.15p.exe
    image-20230422123404610
  2. 依次选择U盘,选择镜像文件,点击开始。
  3. 写入完成后拔下U盘。

安装ESXI8.0

  1. 将写好的U盘插到机器上,开机进入bios页面,选择从U盘启动。

  2. 在加载页面按 SHIFT+O (5秒倒计时结束前按)

    image-20230422124229021

  3. 输入autoParititionOSDataSize=8192设置缓存大小

    image-20230422130103695

    • 注:如果不设置的话,默认是划分120G
  4. 等待页面加载

    image-20230422130452177

  5. 按回车确定,然后F11接受协议。

    image-20230422130636232

  6. 选择安装的硬盘,建议安装到SSD盘

    image-20230422131134063

  7. 如果之前安装过,会让选择安装方式。如果之前的不想要的,就直接选择第三个覆盖安装。(按空格选中,回车确定)

    image-20230422131415703

  8. 键盘选择US Default

    image-20230422131519284

  9. 设置root密码,并确认安装

    image-20230422131707324

  10. 安装完成后,会提示拔出U盘并重启

    image-20230422131850437

  11. 重启后显示下图的页面即表示成功了

    image-20230422131945389

给ESXi 设置为静态 IP

  1. 按 F2 进入,提示需要输入账户密码,用户名为 root,密码为刚刚安装时设置的密码,然后回车。

    image-20230422132154911

  2. 选择**configure management network **

    image-20230422132512778

  3. 然后选择 IPV4 configuration 回车

    image-20230422132558114

  4. 接着移动光标到第三项,随后按空格键确定选择

  5. 接着填入你需要设置的 ESXi 静态 IP 地址。

    image-20230422132853991

第一行填入 esxi 的静态 IP,第二行填入子网掩码 255.255.255.0,第三行填写路由器的网关地址,设置好后回车即可。

  1. 打开浏览器,输入管理地址即可访问esxi系统

    image-20230422133642869

设置管理网口(多网卡)

如果有多张网卡,可以指定哪个网口可以访问esxi的管理页面,没有指定的将无法访问。

  1. F2进入后,依次选择**configure management network **->**Network Adapters **

    image-20230422133918448

  2. 选择网卡,这里可以选择多个,如果只选择了某一个,以后就只有插在这个网口上的机器能访问管理页面。

    image-20230422134113958

0%
\ No newline at end of file diff --git a/2023/03/24/esxi安装homeassistant/index.html b/2023/03/24/esxi安装homeassistant/index.html new file mode 100644 index 0000000..59120d0 --- /dev/null +++ b/2023/03/24/esxi安装homeassistant/index.html @@ -0,0 +1,16 @@ +esxi安装homeassistant | 随言碎语

随言碎语

咕叽咕叽

esxi安装homeassistant

在esxi上安装homeassistant

准备

0%
\ No newline at end of file diff --git a/2023/03/24/esxi安装openwrt/index.html b/2023/03/24/esxi安装openwrt/index.html new file mode 100644 index 0000000..8c47cfb --- /dev/null +++ b/2023/03/24/esxi安装openwrt/index.html @@ -0,0 +1,16 @@ +esxi+openwrt作为旁路由 | 随言碎语

esxi+openwrt作为旁路由

在esxi上安装openwrt,并作为旁路由来使用。

准备

  • starwindconverter.exe 用来将img转换为VMDK
  • openwrt-x86-64-generic-squashfs-combined-efi.img.gz openwrt固件包

1. 构建/获取openWRT

这里推荐使用supes.top 自己选择需要的固件,然后进行构建。5分钟左右就能获取到自定义的固件。

  1. 访问supes.top 官网

image-20230422145319548

  1. 自己根据需求去构建,或者是直接下载构建好的通用包

    image-20230422145651697

  • 注:目前免费的用户,一天之内只能构建一次,有需求的可充值解锁。

2. 转换固件为vmdk格式

  1. 解压openwrt-x86-64-generic-squashfs-combined-efi.img.gz

  2. 解压后的文件是openwrt-x86-64-generic-squashfs-combined-efi.img,这个格式是无法在esxi中直接使用的,因此需要转一下

  3. 安装starwindconverter.exe ,没啥可交代的,一路next即可。

  4. 打开安装好的starwindconverter软件,选择local file->next

    image-20230422150336027

  5. 选择解压后的openwrt-x86-64-generic-squashfs-combined-efi.img

    image-20230422150500119

  6. 还是选择local file

image-20230422150951371

  1. 选择VMDK

    image-20230422151034204

  2. 选择ESXI Server image

    image-20230422151136889

9.选择** ESXI pre-allocates image**

image-20230422151215810

10.选择输出的路径和名称,点击conver

image-20230422151331578

11.转换完成后,会出来两个大小不一样的文件

image-20230422151557911

3. 创建虚拟机

  1. 进入esxi的管理页面,依次点击虚拟机->创建虚拟机

    image-20230422151821830

  2. 选择名称和客户机操作系统

    image-20230422152710801

客户机操作系统系列: 选择Linux,客户机操作系统版本:其他Linux(64位)

  1. 选择存储,如果由多块硬盘,可选择安装的位置

    image-20230422152842237

  2. 内存设置为1G,删除掉硬盘以及其他不需要的设备

    image-20230422153126229

  3. 添加硬盘->现有硬盘

    image-20230422153403639

  4. 将转换后的两个vmdk文件全部都上传上去(只会显示1个),然后选择上传的文件

    image-20230422153716292

    • 注:如果需要网卡直通,可点击添加其他设备->PCI设备。

    • 如果由多个网卡,但是这里无法点击,说明这个设别没有进行直通。如何直通可参考之前的文章 esxi常规配置

      image-20230422154249143

  5. 点击下一步,确认一下配置,无误后点击完成即可。

  6. 选中虚拟机,点击打开电源,等待开机

    image-20230422154411639

  7. 点击进入操作台,可看到openwrt已经正常启动,在浏览器中输入IP地址即可访问openwrt的管理页面。

    image-20230422154700759

4. 配置opwrt作为旁路由

由于是作为旁路由来使用的,所有wan口是不需要的,只需要LAN即可。

  1. 进入openwrt的管理页面,依次点击网络->接口,将wan和wan6全部删除掉。

image-20230422161227530

注:删除后,不要点击 保存并应用!!! 不要点击 保存并应用!!! 不要点击 保存并应用!!!

  1. 点击设备,选择br-lan,点击配置…

image-20230422161705488

  1. 网桥端口中,将所有的网卡都勾选上

    image-20230422161814059

  2. 回到接口页面,编辑lan

    image-20230422161955936

  3. 确认里面的设备是br-lan

    image-20230422162141208

  4. 保存后,点击最外层的保存并应用

    image-20230422162251244

  5. 网络连接正常后,配置自己需要的服务,然后需要这些服务的设备,将openwrt作为网关就可以了。

5. 问题

  1. 为什么不作为主路由使用,而是选择旁路由?

    1
    2
    3
    1。主要还是看各自的需要来决定的,各有利弊。
    2.对我来说,只是想用一下它的插件功能,例如广告拦截,proxy等。
    3.即便是软路由整体挂了,也不会影响家里的其他设别的正常使用。
  2. 如何修改openwrt的地址?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    1.修改lan口的ip地址

    [root@OpenWrt:03:52 PM ~] # cat /etc/config/network

    ....

    config interface 'lan'
    option device 'br-lan'
    option proto 'static'
    option netmask '255.255.255.0'
    option ip6assign '60'
    option ipaddr '10.1.100.254'
    option gateway '10.1.100.1'
    option dns '223.5.5.5'
    option delegate '0'

    ....

    2. 改完后保存退出,并reboot重启
  3. 网卡直通后,无法访问openwrt的管理页面?

1
2
多张网卡直通后,可能会造成网卡识别混乱。
如果当前无法访问,把网线拔了,可换个网口再试试,肯定会有一个是能够访问的。
0%
\ No newline at end of file diff --git a/2023/03/24/esxi安装群晖dsm7.1/index.html b/2023/03/24/esxi安装群晖dsm7.1/index.html new file mode 100644 index 0000000..115c7e8 --- /dev/null +++ b/2023/03/24/esxi安装群晖dsm7.1/index.html @@ -0,0 +1,16 @@ +esxi安装群晖dsm7.1 | 随言碎语

随言碎语

咕叽咕叽

esxi安装群晖dsm7.1

在esxi上安装DSM

准备

0%
\ No newline at end of file diff --git a/2023/03/26/esxi常规配置/index.html b/2023/03/26/esxi常规配置/index.html new file mode 100644 index 0000000..2f59801 --- /dev/null +++ b/2023/03/26/esxi常规配置/index.html @@ -0,0 +1,16 @@ +esxi常规配置 | 随言碎语

esxi常规配置

esxi修改网卡顺序、网卡直通、修改安全策略、开机自动启动虚拟机。

修改网卡顺序

系统中网卡的显示顺序可能和实际的对应不上,可以修改相关的配置文件,让其能和实际的端口对上。

先确定当前的顺序,以及希望修改后的顺序:

实际网口名称ESXi中默认网口名称希望的网口名称
eth0vmnic1vmnic0
eth1vmnic2vmnic1
eth2vmnic0vmnic2
eth3vmnic3vmnic3
  1. 开启维护模式,和ssh连接。

  2. 查看系统中当前pci和逻辑pci对应的网卡名称

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias list
    Bus type Bus address Alias
    ------------------------------------
    pci m00008501 vmnic0
    pci m00008901 vmhba0
    pci p0000:04:00.0 vmnic3
    pci s00000003.00 vmnic1
    pci p0000:02:00.0 vmnic2
    logical pci#s00000003.00#0 vmnic1
    logical pci#m00008501#0 vmnic0
    logical pci#m00008901#0 vmhba0
    logical pci#p0000:02:00.0#0 vmnic2
    logical pci#p0000:04:00.0#0 vmnic3

  3. 修改网卡名称,这里pci和逻辑pci对应的名称要同时修改,并且要一致。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type pci --alias vmnic0 --bus-address s00000003.00
    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type logical --alias vmnic0 --bus-address "pci#s00000003.00#0"

    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type pci --alias vmnic1 --bus-address p0000:02:00.0
    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type logical --alias vmnic1 --bus-address "pci#p0000:02:00.0#0"

    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type pci --alias vmnic2 --bus-address m00008501
    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type logical --alias vmnic2 --bus-address "pci#m00008501#0"

  4. 重启机器

网卡直通

安装软路由时,需要将网卡直通,从而发挥网卡的最大性能。

  1. 进入esxi的管理页面

    image-20230422142105492

注:至少要保留一个网口,用来作为esxi的管理网口,否则将无法登录esxi

  1. 选择需要直通的网口,进行切换即可

修改安全策略

可能会出现虚拟机和esxi之间相互ping不通的情况,这是由于esxi的安全策略导致的

  1. 依次点击网络->虚拟交换机->编辑vSwith0

    image-20230422143110862

  2. 将安全选项中,混杂模式和伪传输改为接受

开机自动启动虚拟机

设置开启后自动启动虚拟机,以及启动顺序

1.依次点击主机->管理->系统->自动启动->编辑设置,将总开关打开

image-20230422143559690

2.选择虚拟机,设置是否开机自启、调整启动的顺序和延迟启动时间。

  • 注:这里最好错开启动,不要同时启动,由依赖的虚拟机先启动。
0%
\ No newline at end of file diff --git a/about/index.html b/about/index.html new file mode 100644 index 0000000..feb4ec5 --- /dev/null +++ b/about/index.html @@ -0,0 +1,16 @@ +about | 随言碎语

随言碎语

咕叽咕叽

about

0%
\ No newline at end of file diff --git a/archives/2019/12/index.html b/archives/2019/12/index.html new file mode 100644 index 0000000..d5070ad --- /dev/null +++ b/archives/2019/12/index.html @@ -0,0 +1,16 @@ +归档 | 随言碎语

随言碎语

咕叽咕叽

嗯..! 目前共计 8 篇日志。 继续努力。
2019
0%
\ No newline at end of file diff --git a/archives/2019/index.html b/archives/2019/index.html new file mode 100644 index 0000000..cc708e9 --- /dev/null +++ b/archives/2019/index.html @@ -0,0 +1,16 @@ +归档 | 随言碎语

随言碎语

咕叽咕叽

嗯..! 目前共计 8 篇日志。 继续努力。
2019
0%
\ No newline at end of file diff --git a/archives/2020/01/index.html b/archives/2020/01/index.html new file mode 100644 index 0000000..011a700 --- /dev/null +++ b/archives/2020/01/index.html @@ -0,0 +1,16 @@ +归档 | 随言碎语

随言碎语

咕叽咕叽

嗯..! 目前共计 8 篇日志。 继续努力。
2020
0%
\ No newline at end of file diff --git a/archives/2020/index.html b/archives/2020/index.html new file mode 100644 index 0000000..2342b0b --- /dev/null +++ b/archives/2020/index.html @@ -0,0 +1,16 @@ +归档 | 随言碎语

随言碎语

咕叽咕叽

嗯..! 目前共计 8 篇日志。 继续努力。
2020
0%
\ No newline at end of file diff --git a/archives/2023/03/index.html b/archives/2023/03/index.html new file mode 100644 index 0000000..f555724 --- /dev/null +++ b/archives/2023/03/index.html @@ -0,0 +1,16 @@ +归档 | 随言碎语

随言碎语

咕叽咕叽

0%
\ No newline at end of file diff --git a/archives/2023/index.html b/archives/2023/index.html new file mode 100644 index 0000000..b0305ed --- /dev/null +++ b/archives/2023/index.html @@ -0,0 +1,16 @@ +归档 | 随言碎语

随言碎语

咕叽咕叽

0%
\ No newline at end of file diff --git a/archives/index.html b/archives/index.html new file mode 100644 index 0000000..5eca31e --- /dev/null +++ b/archives/index.html @@ -0,0 +1,16 @@ +归档 | 随言碎语

随言碎语

咕叽咕叽

0%
\ No newline at end of file diff --git a/atom.xml b/atom.xml new file mode 100644 index 0000000..b8f3526 --- /dev/null +++ b/atom.xml @@ -0,0 +1,188 @@ + + + 随言碎语 + + 咕叽咕叽 + + + + 2023-04-22T06:40:08.722Z + http://kiki.kim/ + + + 小梦同学的blog + + + + Hexo + + + esxi常规配置 + + http://kiki.kim/2023/03/26/esxi%E5%B8%B8%E8%A7%84%E9%85%8D%E7%BD%AE/ + 2023-03-26T03:45:22.000Z + 2023-04-22T06:40:08.722Z + + + <p>esxi修改网卡顺序、网卡直通、修改安全策略、开机自动启动虚拟机。</p> + + + + + + + + + + + + esxi安装homeassistant + + http://kiki.kim/2023/03/24/esxi%E5%AE%89%E8%A3%85homeassistant/ + 2023-03-24T12:15:04.000Z + 2023-04-22T08:51:44.267Z + + + <p>在esxi上安装homeassistant</p> + + + + + + + + + + + + esxi+openwrt作为旁路由 + + http://kiki.kim/2023/03/24/esxi%E5%AE%89%E8%A3%85openwrt/ + 2023-03-24T12:15:04.000Z + 2023-04-22T08:39:45.162Z + + + <p>在esxi上安装openwrt,并作为旁路由来使用。</p> + + + + + + + + + + + + + + + + esxi安装群晖dsm7.1 + + http://kiki.kim/2023/03/24/esxi%E5%AE%89%E8%A3%85%E7%BE%A4%E6%99%96dsm7.1/ + 2023-03-24T12:15:04.000Z + 2023-04-22T08:51:15.950Z + + + <p>在esxi上安装DSM</p> + + + + + + + + + + + + + + esxi+openwrt+dsm+homeassistant 软路由 all in one + + http://kiki.kim/2023/03/23/esxi+openwrt+dsm+homeassistant-%E8%BD%AF%E8%B7%AF%E7%94%B1all-in-one/ + 2023-03-23T13:25:34.000Z + 2023-04-24T04:53:03.818Z + + + <p>软路由 all in one,在J425小主机上安装esxi+openwrt+dsm+homeassistant,集软路由、网盘、智能家居控制于一体。</p> + + + + + + + + + + + + + + + + + + + + esxi8.0安装 + + http://kiki.kim/2023/03/23/esxi8.0%E5%AE%89%E8%A3%85/ + 2023-03-23T13:25:34.000Z + 2023-04-24T01:37:17.777Z + + + <p>esxi 8.0的安装。</p> + + + + + + + + + + + + VMware安装centos7 + + http://kiki.kim/2020/01/03/VMware%E5%AE%89%E8%A3%85centos7/ + 2020-01-03T13:25:34.000Z + 2023-04-22T06:02:29.866Z + + + <p>在VMware Workstation上安装centos。</p> + + + + + + + + + + + + Hello World + + http://kiki.kim/2019/12/30/hello-world/ + 2019-12-30T15:25:34.000Z + 2023-04-22T05:46:03.233Z + + + + + + + <p>欢迎来到我的博客,这是我的第一篇博客,由hexo+next构建。</p> + + + + + + + + + + diff --git a/css/hbe.style.css b/css/hbe.style.css new file mode 100644 index 0000000..2935f20 --- /dev/null +++ b/css/hbe.style.css @@ -0,0 +1,749 @@ +.hbe, +.hbe:after, +.hbe:before { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.hbe-container{ + margin: 0 auto; + overflow: hidden; +} +.hbe-content { + text-align: center; + font-size: 150%; + padding: 1em 0; +} + +.hbe-input { + position: relative; + z-index: 1; + display: inline-block; + margin: 1em; + width: 80%; + min-width: 400px; + vertical-align: top; +} + +.hbe-input-field { + line-height: normal; + font-size: 100%; + margin: 0; + position: relative; + display: block; + float: right; + padding: 0.8em; + width: 60%; + border: none; + border-radius: 0; + background: #f0f0f0; + color: #aaa; + font-weight: 400; + font-family: "Avenir Next", "Helvetica Neue", Helvetica, Arial, sans-serif; + -webkit-appearance: none; /* for box shadows to show on iOS */ +} + +.hbe-input-field:focus { + outline: none; +} + +.hbe-input-label { + display: inline-block; + float: right; + padding: 0 1em; + width: 40%; + color: #696969; + font-weight: bold; + font-size: 70.25%; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.hbe-input-label-content { + position: relative; + display: block; + padding: 1.6em 0; + width: 100%; +} + +.hbe-graphic { + position: absolute; + top: 0; + left: 0; + fill: none; +} + +/* hbe button in post page */ +.hbe-button { + width: 130px; + height: 40px; + background: linear-gradient(to bottom, #4eb5e5 0%,#389ed5 100%); /* W3C */ + border: none; + border-radius: 5px; + position: relative; + border-bottom: 4px solid #2b8bc6; + color: #fbfbfb; + font-weight: 600; + font-family: 'Open Sans', sans-serif; + text-shadow: 1px 1px 1px rgba(0,0,0,.4); + font-size: 15px; + text-align: left; + text-indent: 5px; + box-shadow: 0px 3px 0px 0px rgba(0,0,0,.2); + cursor: pointer; + + display: block; + margin: 0 auto; + margin-bottom: 20px; +} + +.hbe-button:active { + box-shadow: 0px 2px 0px 0px rgba(0,0,0,.2); + top: 1px; +} + +.hbe-button:after { + content: ""; + width: 0; + height: 0; + display: block; + border-top: 20px solid #187dbc; + border-bottom: 20px solid #187dbc; + border-left: 16px solid transparent; + border-right: 20px solid #187dbc; + position: absolute; + opacity: 0.6; + right: 0; + top: 0; + border-radius: 0 5px 5px 0; +} +/* hbe button in post page */ + +/* default theme {{{ */ +.hbe-input-default { + overflow: hidden; +} + +.hbe-input-field-default { + width: 100%; + background: transparent; + padding: 0.5em; + margin-bottom: 2em; + color: #f9f7f6; + z-index: 100; + opacity: 0; +} + +.hbe-input-label-default { + width: 100%; + position: absolute; + text-align: left; + padding: 0.5em 0; + pointer-events: none; + font-size: 1em; +} + +.hbe-input-label-default::before, +.hbe-input-label-default::after { + content: ''; + position: absolute; + width: 100%; + left: 0; +} + +.hbe-input-label-default::before { + height: 100%; + background: #666666; + top: 0; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + -webkit-transition: -webkit-transform 0.2s; + transition: transform 0.2s; +} + +.hbe-input-label-default::after { + height: 2px; + background: #666666; + top: 100%; + -webkit-transition: opacity 0.2s; + transition: opacity 0.2s; +} + +.hbe-input-label-content-default { + padding: 0; + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + -webkit-transition: -webkit-transform 0.2s, color 0.2s; + transition: transform 0.2s, color 0.2s; +} + +.hbe-input-field-default:focus, +.hbe-input--filled .hbe-input-field-default { + opacity: 1; + -webkit-transition: opacity 0s 0.2s; + transition: opacity 0s 0.2s; +} + +.hbe-input-label-default::before, +.hbe-input-label-default::after, +.hbe-input-label-content-default, +.hbe-input-field-default:focus, +.hbe-input--filled .hbe-input-field-default { + -webkit-transition-timing-function: cubic-bezier(0, 0.25, 0.5, 1); + transition-timing-function: cubic-bezier(0, 0.25, 0.5, 1); +} + +.hbe-input-field-default:focus + .hbe-input-label-default::before, +.hbe-input--filled .hbe-input-label-default::before { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} + +.hbe-input-field-default:focus + .hbe-input-label-default::after, +.hbe-input--filled .hbe-input-label-default::after { + opacity: 0; +} + +.hbe-input-field-default:focus + .hbe-input-label-default .hbe-input-label-content-default, +.hbe-input--filled .hbe-input-label-default .hbe-input-label-content-default { + color: #555555; + -webkit-transform: translate3d(0, 2.1em, 0) scale3d(0.65, 0.65, 1); + transform: translate3d(0, 2.1em, 0) scale3d(0.65, 0.65, 1); +} +/* default theme }}} */ + +/* up theme {{{ */ +.hbe-input-up { + overflow: hidden; + padding-top: 2em; +} + +.hbe-input-field-up { + width: 100%; + background: transparent; + opacity: 0; + padding: 0.35em; + z-index: 100; + color: #837482; +} + +.hbe-input-label-up { + width: 100%; + bottom: 0; + position: absolute; + pointer-events: none; + text-align: left; + color: #8E9191; + padding: 0 0.5em; +} + +.hbe-input-label-up::before { + content: ''; + position: absolute; + width: 100%; + height: 4em; + top: 100%; + left: 0; + background: #fff; + border-top: 4px solid #9B9F9F; + -webkit-transform: translate3d(0, -3px, 0); + transform: translate3d(0, -3px, 0); + -webkit-transition: -webkit-transform 0.4s; + transition: transform 0.4s; + -webkit-transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); + transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); +} + +.hbe-input-label-content-up { + padding: 0.5em 0; + -webkit-transform-origin: 0% 100%; + transform-origin: 0% 100%; + -webkit-transition: -webkit-transform 0.4s, color 0.4s; + transition: transform 0.4s, color 0.4s; + -webkit-transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); + transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); +} + +.hbe-input-field-up:focus, +.input--filled .hbe-input-field-up { + cursor: text; + opacity: 1; + -webkit-transition: opacity 0s 0.4s; + transition: opacity 0s 0.4s; +} + +.hbe-input-field-up:focus + .hbe-input-label-up::before, +.input--filled .hbe-input-label-up::before { + -webkit-transition-delay: 0.05s; + transition-delay: 0.05s; + -webkit-transform: translate3d(0, -3.3em, 0); + transform: translate3d(0, -3.3em, 0); +} + +.hbe-input-field-up:focus + .hbe-input-label-up .hbe-input-label-content-up, +.input--filled .hbe-input-label-content-up { + color: #6B6E6E; + -webkit-transform: translate3d(0, -3.3em, 0) scale3d(0.81, 0.81, 1); + transform: translate3d(0, -3.3em, 0) scale3d(0.81, 0.81, 1); +} +/* up theme }}} */ + +/* wave theme {{{ */ +.hbe-input-wave { + overflow: hidden; + padding-top: 1em; +} + +.hbe-input-field-wave { + padding: 0.5em 0em 0.25em; + width: 100%; + background: transparent; + color: #9da8b2; + font-size: 1.25em; +} + +.hbe-input-label-wave { + position: absolute; + top: 0.95em; + font-size: 0.85em; + left: 0; + display: block; + width: 100%; + text-align: left; + padding: 0em; + pointer-events: none; + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + -webkit-transition: -webkit-transform 0.2s 0.15s, color 1s; + transition: transform 0.2s 0.15s, color 1s; + -webkit-transition-timing-function: ease-out; + transition-timing-function: ease-out; +} + +.hbe-graphic-wave { + stroke: #92989e; + pointer-events: none; + -webkit-transition: -webkit-transform 0.7s, stroke 0.7s; + transition: transform 0.7s, stroke 0.7s; + -webkit-transition-timing-function: cubic-bezier(0, 0.25, 0.5, 1); + transition-timing-function: cubic-bezier(0, 0.25, 0.5, 1); +} + +.hbe-input-field-wave:focus + .hbe-input-label-wave, +.input--filled .hbe-input-label-wave { + color: #333; + -webkit-transform: translate3d(0, -1.25em, 0) scale3d(0.75, 0.75, 1); + transform: translate3d(0, -1.25em, 0) scale3d(0.75, 0.75, 1); +} + +.hbe-input-field-wave:focus ~ .hbe-graphic-wave, +.input--filled .graphic-wave { + stroke: #333; + -webkit-transform: translate3d(-66.6%, 0, 0); + transform: translate3d(-66.6%, 0, 0); +} +/* wave theme }}} */ + +/* flip theme {{{ */ +.hbe-input-field-flip { + width: 100%; + background-color: #d0d1d0; + border: 2px solid transparent; + -webkit-transition: background-color 0.25s, border-color 0.25s; + transition: background-color 0.25s, border-color 0.25s; +} + +.hbe-input-label-flip { + width: 100%; + text-align: left; + position: absolute; + bottom: 100%; + pointer-events: none; + overflow: hidden; + padding: 0 1.25em; + -webkit-transform: translate3d(0, 3em, 0); + transform: translate3d(0, 3em, 0); + -webkit-transition: -webkit-transform 0.25s; + transition: transform 0.25s ; + -webkit-transition-timing-function: ease-in-out; + transition-timing-function: ease-in-out; +} + +.hbe-input-label-content-flip { + color: #8B8C8B; + padding: 0.25em 0; + -webkit-transition: -webkit-transform 0.25s; + transition: transform 0.25s; + -webkit-transition-timing-function: ease-in-out; + transition-timing-function: ease-in-out; +} + +.hbe-input-label-content-flip::after { + content: attr(data-content); + position: absolute; + font-weight: 800; + bottom: 100%; + left: 0; + height: 100%; + width: 100%; + color: #666666; + padding: 0.25em 0; + letter-spacing: 1px; + font-size: 1em; +} + +.hbe-input-field-flip:focus + .hbe-input-label-flip, +.input--filled .hbe-input-label-flip { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} + +.hbe-input-field-flip:focus + .hbe-input-label-flip .hbe-input-label-content-flip, +.input--filled .hbe-input-label-content-flip { + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); +} + +.hbe-input-field-flip:focus + .hbe-input-field-flip, +.input--filled .hbe-input-field-flip { + background-color: transparent; + border-color: #666666; +} +/* flip theme }}} */ + +/* xray theme {{{ */ +.hbe-input-xray { + overflow: hidden; + padding-bottom: 2.5em; +} + +.hbe-input-field-xray { + padding: 0; + margin-top: 1.2em; + width: 100%; + background: transparent; + color: #84AF9B ; + font-size: 1.55em; +} + +.hbe-input-label-xray { + position: absolute; + top: 2em; + left: 0; + display: block; + width: 100%; + text-align: left; + padding: 0em; + letter-spacing: 1px; + color: #84AF9B ; + pointer-events: none; + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + -webkit-transition: -webkit-transform 0.2s 0.1s, color 0.3s; + transition: transform 0.2s 0.1s, color 0.3s; + -webkit-transition-timing-function: ease-out; + transition-timing-function: ease-out; +} + +.hbe-graphic-xray { + stroke: #84AF9B ; + pointer-events: none; + stroke-width: 2px; + top: 1.25em; + bottom: 0px; + height: 3.275em; + -webkit-transition: -webkit-transform 0.7s, stroke 0.7s; + transition: transform 0.7s, stroke 0.7s; + -webkit-transition-timing-function: cubic-bezier(0, 0.25, 0.5, 1); + transition-timing-function: cubic-bezier(0, 0.25, 0.5, 1); +} + +.hbe-input-field-xray:focus + .hbe-input-label-xray, +.input--filled .hbe-input-label-xray { + color: #84AF9B ; + -webkit-transform: translate3d(0, 3.5em, 0) scale3d(0.85, 0.85, 1); + transform: translate3d(0, 3.5em, 0) scale3d(0.85, 0.85, 1); +} + +.hbe-input-field-xray:focus ~ .hbe-graphic-xray, +.input--filled .graphic-xray { + stroke: #84AF9B ; + -webkit-transform: translate3d(-66.6%, 0, 0); + transform: translate3d(-66.6%, 0, 0); +} +/* xray theme }}} */ + +/* blink theme {{{ */ +.hbe-input-blink { + padding-top: 1em; +} + +.hbe-input-field-blink { + width: 100%; + padding: 0.8em 0.5em; + background: transparent; + border: 2px solid; + color: #8781bd; + -webkit-transition: border-color 0.25s; + transition: border-color 0.25s; +} + +.hbe-input-label-blink { + width: 100%; + position: absolute; + top: 0; + text-align: left; + overflow: hidden; + padding: 0; + pointer-events: none; + -webkit-transform: translate3d(0, 3em, 0); + transform: translate3d(0, 3em, 0); +} + +.hbe-input-label-content-blink { + padding: 0 1em; + font-weight: 400; + color: #b5b5b5; +} + +.hbe-input-label-content-blink::after { + content: attr(data-content); + position: absolute; + top: -200%; + left: 0; + color: #8781bd ; + font-weight: 800; +} + +.hbe-input-field-blink:focus, +.input--filled .hbe-input-field-blink { + border-color: #8781bd ; +} + +.hbe-input-field-blink:focus + .hbe-input-label-blink, +.input--filled .hbe-input-label-blink { + -webkit-animation: anim-blink-1 0.25s forwards; + animation: anim-blink-1 0.25s forwards; +} + +.hbe-input-field-blink:focus + .hbe-input-label-blink .hbe-input-label-content-blink, +.input--filled .hbe-input-label-content-blink { + -webkit-animation: anim-blink-2 0.25s forwards ease-in; + animation: anim-blink-2 0.25s forwards ease-in; +} + +@-webkit-keyframes anim-blink-1 { + 0%, 70% { + -webkit-transform: translate3d(0, 3em, 0); + transform: translate3d(0, 3em, 0); + } + 71%, 100% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@-webkit-keyframes anim-blink-2 { + 0% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + 70%, 71% { + -webkit-transform: translate3d(0, 125%, 0); + transform: translate3d(0, 125%, 0); + opacity: 0; + -webkit-animation-timing-function: ease-out; + } + 100% { + color: transparent; + -webkit-transform: translate3d(0, 200%, 0); + transform: translate3d(0, 200%, 0); + } +} + +@keyframes anim-blink-1 { + 0%, 70% { + -webkit-transform: translate3d(0, 3em, 0); + transform: translate3d(0, 3em, 0); + } + 71%, 100% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes anim-blink-2 { + 0% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + 70%, 71% { + -webkit-transform: translate3d(0, 125%, 0); + transform: translate3d(0, 125%, 0); + opacity: 0; + -webkit-animation-timing-function: ease-out; + } + 100% { + color: transparent; + -webkit-transform: translate3d(0, 200%, 0); + transform: translate3d(0, 200%, 0); + } +} +/* blink theme }}} */ + +/* surge theme {{{ */ +.hbe-input-surge { + overflow: hidden; + padding-bottom: 1em; +} + +.hbe-input-field-surge { + padding: 0.25em 0.5em; + margin-top: 1.25em; + width: 100%; + background: transparent; + color: #D0D0D0; + font-size: 1.55em; + opacity: 0; +} + +.hbe-input-label-surge { + width: 100%; + text-align: left; + position: absolute; + top: 1em; + pointer-events: none; + overflow: hidden; + padding: 0 0.25em; + -webkit-transform: translate3d(1em, 2.75em, 0); + transform: translate3d(1em, 2.75em, 0); + -webkit-transition: -webkit-transform 0.3s; + transition: transform 0.3s; +} + +.hbe-input-label-content-surge { + color: #A4A5A6; + padding: 0.4em 0 0.25em; + -webkit-transition: -webkit-transform 0.3s; + transition: transform 0.3s; +} + +.hbe-input-label-content-surge::after { + content: attr(data-content); + position: absolute; + font-weight: 800; + top: 100%; + left: 0; + height: 100%; + width: 100%; + color: #2C3E50; + padding: 0.25em 0; + letter-spacing: 1px; + font-size: 0.85em; +} + +.hbe-graphic-surge { + fill: #2C3E50; + pointer-events: none; + top: 1em; + bottom: 0px; + height: 4.5em; + z-index: -1; + -webkit-transition: -webkit-transform 0.7s, fill 0.7s; + transition: transform 0.7s, fill 0.7s; + -webkit-transition-timing-function: cubic-bezier(0, 0.25, 0.5, 1); + transition-timing-function: cubic-bezier(0, 0.25, 0.5, 1); +} + +.hbe-input-field-surge:focus, +.input--filled .hbe-input-field-surge { + -webkit-transition: opacity 0s 0.35s; + transition: opacity 0s 0.35s; + opacity: 1; +} + +.hbe-input-field-surge:focus + .hbe-input-label-surge, +.input--filled .hbe-input-label-surge { + -webkit-transition-delay: 0.15s; + transition-delay: 0.15s; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} + +.hbe-input-field-surge:focus + .hbe-input-label-surge .hbe-input-label-content-surge, +.input--filled .hbe-input-label-content-surge { + -webkit-transition-delay: 0.15s; + transition-delay: 0.15s; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); +} + +.hbe-input-field-surge:focus ~ .hbe-graphic-surge, +.input--filled .graphic-surge { + fill: #2C3E50; + -webkit-transform: translate3d(-66.6%, 0, 0); + transform: translate3d(-66.6%, 0, 0); +} +/* surge theme }}} */ + +/* shrink theme {{{ */ +.hbe-input-field-shrink { + width: 100%; + background: transparent; + padding: 0.5em 0; + margin-bottom: 2em; + color: #2C3E50; +} + +.hbe-input-label-shrink { + width: 100%; + position: absolute; + text-align: left; + font-size: 1em; + padding: 10px 0 5px; + pointer-events: none; +} + +.hbe-input-label-shrink::after { + content: ''; + position: absolute; + width: 100%; + height: 7px; + background: #B7C3AC; + left: 0; + top: 100%; + -webkit-transform-origin: 50% 100%; + transform-origin: 50% 100%; + -webkit-transition: -webkit-transform 0.3s, background-color 0.3s; + transition: transform 0.3s, background-color 0.3s; +} + +.hbe-input-label-content-shrink { + padding: 0; + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + -webkit-transition: -webkit-transform 0.3s, color 0.3s; + transition: transform 0.3s, color 0.3s; +} + +.hbe-input-field-shrink:focus + .hbe-input-label-shrink::after, +.input--filled .hbe-input-label-shrink::after { + background: #84AF9B; + -webkit-transform: scale3d(1, 0.25, 1); + transform: scale3d(1, 0.25, 1); +} + +.hbe-input-field-shrink:focus + .hbe-input-label-shrink .hbe-input-label-content-shrink, +.input--filled .hbe-input-label-shrink .hbe-input-label-content-shrink { + color: #84AF9B; + -webkit-transform: translate3d(0, 2em, 0) scale3d(0.655, 0.655, 1); + transform: translate3d(0, 2em, 0) scale3d(0.655, 0.655, 1); +} +/* shrink theme }}} */ diff --git a/css/link.css b/css/link.css new file mode 100644 index 0000000..7a8708d --- /dev/null +++ b/css/link.css @@ -0,0 +1,3 @@ +/* build time:Tue Apr 25 2023 15:41:31 GMT+0800 (GMT+08:00)*/ +.links-content{margin-top:1rem}.link-navigation::after{content:" ";display:block;clear:both}.card{width:130px;font-size:1rem;padding:0;border-radius:4px;transition-duration:.15s;margin-bottom:1rem;display:block;float:left;box-shadow:0 2px 6px 0 rgba(0,0,0,.12);background:#f5f5f5}.card{margin-left:16px}@media(max-width:567px){.card{margin-left:16px;width:calc((100% - 16px)/ 2)}.card:nth-child(2n+1){margin-left:0}.card:not(:nth-child(2n+1)){margin-left:16px}}@media(min-width:567px){.card{margin-left:16px;width:calc((100% - 32px)/ 3)}.card:nth-child(3n+1){margin-left:0}.card:not(:nth-child(3n+1)){margin-left:16px}}@media(min-width:768px){.card{margin-left:16px;width:calc((100% - 48px)/ 4)}.card:nth-child(4n+1){margin-left:0}.card:not(:nth-child(4n+1)){margin-left:16px}}@media(min-width:1200px){.card{margin-left:16px;width:calc((100% - 64px)/ 5)}.card:nth-child(5n+1){margin-left:0}.card:not(:nth-child(5n+1)){margin-left:16px}}.card:hover{transform:scale(1.1);box-shadow:0 2px 6px 0 rgba(0,0,0,.12),0 0 6px 0 rgba(0,0,0,.04)}.card .thumb{width:100%;height:0;padding-bottom:100%;background-size:100% 100%!important}.posts-expand .post-body img{margin:0;padding:0;border:0}.card .card-header{display:block;text-align:center;padding:1rem .25rem;font-weight:500;color:#333;white-space:normal}.card .card-header a{font-style:normal;color:#2bbc8a;font-weight:700;text-decoration:none;border:0}.card .card-header a:hover{color:#d480aa;text-decoration:none;border:0} +/* rebuild by neat */ \ No newline at end of file diff --git a/css/main.css b/css/main.css new file mode 100644 index 0000000..54fb0fe --- /dev/null +++ b/css/main.css @@ -0,0 +1,9 @@ +/* build time:Tue Apr 25 2023 15:41:35 GMT+0800 (GMT+08:00)*/ +:root{--body-bg-color:#eee;--content-bg-color:#fff;--card-bg-color:#f5f5f5;--text-color:#555;--blockquote-color:#666;--link-color:#555;--link-hover-color:#222;--brand-color:#fff;--brand-hover-color:#fff;--table-row-odd-bg-color:#f9f9f9;--table-row-hover-bg-color:#f5f5f5;--menu-item-bg-color:#f5f5f5;--theme-color:#222;--btn-default-bg:#fff;--btn-default-color:#555;--btn-default-border-color:#555;--btn-default-hover-bg:#222;--btn-default-hover-color:#fff;--btn-default-hover-border-color:#222;--highlight-background:#fefbec;--highlight-foreground:#6e6b5e;--highlight-gutter-background:#efecdd;--highlight-gutter-foreground:#7c796c;color-scheme:light}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:0 0}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]{outline-offset:-2px;-webkit-appearance:textfield}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}::selection{background:#262a30;color:#eee}body,html{height:100%}body{background:var(--body-bg-color);box-sizing:border-box;color:var(--text-color);font-family:Lato,'PingFang SC','Microsoft YaHei',sans-serif;font-size:1em;line-height:2;min-height:100%;position:relative;transition:padding .2s ease-in-out}h1,h2,h3,h4,h5,h6{font-family:Lato,'PingFang SC','Microsoft YaHei',sans-serif;font-weight:700;line-height:1.5;margin:30px 0 15px}h1{font-size:1.5em}h2{font-size:1.375em}h3{font-size:1.25em}h4{font-size:1.125em}h5{font-size:1em}h6{font-size:.875em}p{margin:0 0 20px}a{border-bottom:1px solid #999;color:var(--link-color);cursor:pointer;outline:0;text-decoration:none;overflow-wrap:break-word}a:hover{border-bottom-color:var(--link-hover-color);color:var(--link-hover-color)}embed,iframe,img,video{display:block;margin-left:auto;margin-right:auto;max-width:100%}hr{background-image:repeating-linear-gradient(-45deg,#ddd,#ddd 4px,transparent 4px,transparent 8px);border:0;height:3px;margin:40px 0}blockquote{border-left:4px solid #ddd;color:var(--blockquote-color);margin:0;padding:0 15px}blockquote cite::before{content:'-';padding:0 5px}dt{font-weight:700}dd{margin:0;padding:0}.table-container{overflow:auto}table{border-collapse:collapse;border-spacing:0;font-size:.875em;margin:0 0 20px;width:100%}tbody tr:nth-of-type(odd){background:var(--table-row-odd-bg-color)}tbody tr:hover{background:var(--table-row-hover-bg-color)}caption,td,th{padding:8px}td,th{border:1px solid #ddd;border-bottom:3px solid #ddd}th{font-weight:700;padding-bottom:10px}td{border-bottom-width:1px}.btn{background:var(--btn-default-bg);border:2px solid var(--btn-default-border-color);border-radius:2px;color:var(--btn-default-color);display:inline-block;font-size:.875em;line-height:2;padding:0 20px;transition:background-color .2s ease-in-out}.btn:hover{background:var(--btn-default-hover-bg);border-color:var(--btn-default-hover-border-color);color:var(--btn-default-hover-color)}.btn+.btn{margin:0 0 8px 8px}.btn .fa-fw{text-align:left;width:1.285714285714286em}.toggle{line-height:0}.toggle .toggle-line{background:#fff;display:block;height:2px;left:0;position:relative;top:0;transition:all .4s;width:100%}.toggle .toggle-line:first-child{margin-top:1px}.toggle .toggle-line:not(:first-child){margin-top:4px}.toggle.toggle-arrow :first-child{left:50%;top:2px;transform:rotate(45deg);width:50%}.toggle.toggle-arrow :last-child{left:50%;top:-2px;transform:rotate(-45deg);width:50%}.toggle.toggle-close :nth-child(2){opacity:0}.toggle.toggle-close :first-child{top:6px;transform:rotate(45deg)}.toggle.toggle-close :last-child{top:-6px;transform:rotate(-45deg)}/*! + Theme: Atelier Dune Light + Author: Bram de Haan (http://atelierbramdehaan.nl) + License: ~ MIT (or more permissive) [via base16-schemes-source] + Maintainer: @highlightjs/core-team + Version: 2021.09.0 +*/pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#6e6b5e;background:#fefbec}.hljs ::selection,.hljs::selection{background-color:#a6a28c;color:#6e6b5e}.hljs-comment{color:#999580}.hljs-tag{color:#7d7a68}.hljs-operator,.hljs-punctuation,.hljs-subst{color:#6e6b5e}.hljs-operator{opacity:.7}.hljs-bullet,.hljs-deletion,.hljs-name,.hljs-selector-tag,.hljs-template-variable,.hljs-variable{color:#d73737}.hljs-attr,.hljs-link,.hljs-literal,.hljs-number,.hljs-symbol,.hljs-variable.constant_{color:#b65611}.hljs-class .hljs-title,.hljs-title,.hljs-title.class_{color:#ae9513}.hljs-strong{font-weight:700;color:#ae9513}.hljs-addition,.hljs-code,.hljs-string,.hljs-title.class_.inherited__{color:#60ac39}.hljs-built_in,.hljs-doctag,.hljs-keyword.hljs-atrule,.hljs-quote,.hljs-regexp{color:#1fad83}.hljs-attribute,.hljs-function .hljs-title,.hljs-section,.hljs-title.function_,.ruby .hljs-property{color:#6684e1}.diff .hljs-meta,.hljs-keyword,.hljs-template-tag,.hljs-type{color:#b854d4}.hljs-emphasis{color:#b854d4;font-style:italic}.hljs-meta,.hljs-meta .hljs-keyword,.hljs-meta .hljs-string{color:#d43552}.hljs-meta .hljs-keyword,.hljs-meta-keyword{font-weight:700}.highlight:hover .copy-btn,pre:hover .copy-btn{opacity:1}figure.highlight .table-container{position:relative}.copy-btn{color:#333;cursor:pointer;line-height:1.6;opacity:0;padding:2px 6px;position:absolute;transition:opacity .2s ease-in-out;background:#fff;border:0;font-size:.8125em;right:0;top:0}code,figure.highlight,kbd,pre{background:var(--highlight-background);color:var(--highlight-foreground)}figure.highlight,pre{line-height:1.6;margin:0 auto 20px}figure.highlight figcaption,pre .caption,pre figcaption{background:var(--highlight-gutter-background);color:var(--highlight-foreground);display:flow-root;font-size:.875em;line-height:1.2;padding:.5em}figure.highlight figcaption a,pre .caption a,pre figcaption a{color:var(--highlight-foreground);float:right}figure.highlight figcaption a:hover,pre .caption a:hover,pre figcaption a:hover{border-bottom-color:var(--highlight-foreground)}code,pre{font-family:consolas,Menlo,monospace,'PingFang SC','Microsoft YaHei'}code{border-radius:3px;font-size:.875em;padding:2px 4px;overflow-wrap:break-word}kbd{border:2px solid #ccc;border-radius:.2em;box-shadow:.1em .1em .2em rgba(0,0,0,.1);font-family:inherit;padding:.1em .3em;white-space:nowrap}figure.highlight{overflow:auto;position:relative}figure.highlight pre{border:0;margin:0;padding:10px 0}figure.highlight table{border:0;margin:0;width:auto}figure.highlight td{border:0;padding:0}figure.highlight .gutter{-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}figure.highlight .gutter pre{background:var(--highlight-gutter-background);color:var(--highlight-gutter-foreground);padding-left:10px;padding-right:10px;text-align:right}figure.highlight .code pre{padding-left:10px;width:100%}figure.highlight .marked{background:rgba(0,0,0,.3)}pre .caption,pre figcaption{margin-bottom:10px}.gist table{width:auto}.gist table td{border:0}pre{overflow:auto;padding:10px;position:relative}pre code{background:0 0;padding:0;text-shadow:none}.blockquote-center{border-left:0;margin:40px 0;padding:0;position:relative;text-align:center}.blockquote-center::after,.blockquote-center::before{left:0;line-height:1;opacity:.6;position:absolute;width:100%}.blockquote-center::before{border-top:1px solid #ccc;text-align:left;top:-20px;content:'\f10d';font-family:'Font Awesome 6 Free';font-weight:900}.blockquote-center::after{border-bottom:1px solid #ccc;bottom:-20px;text-align:right;content:'\f10e';font-family:'Font Awesome 6 Free';font-weight:900}.blockquote-center div,.blockquote-center p{text-align:center}.group-picture{margin-bottom:20px}.group-picture .group-picture-row{display:flex;gap:3px;margin-bottom:3px}.group-picture .group-picture-column{flex:1}.group-picture .group-picture-column img{height:100%;margin:0;object-fit:cover;width:100%}.post-body .label{color:#555;padding:0 2px}.post-body .label.default{background:#f0f0f0}.post-body .label.primary{background:#efe6f7}.post-body .label.info{background:#e5f2f8}.post-body .label.success{background:#e7f4e9}.post-body .label.warning{background:#fcf6e1}.post-body .label.danger{background:#fae8eb}.post-body .link-grid{display:grid;grid-gap:1.5rem;gap:1.5rem;grid-template-columns:1fr 1fr;margin-bottom:20px;padding:1rem}@media (max-width:767px){.post-body .link-grid{grid-template-columns:1fr}}.post-body .link-grid .link-grid-container{border:solid #ddd;box-shadow:1rem 1rem .5rem rgba(0,0,0,.5);min-height:5rem;min-width:0;padding:.5rem;position:relative;transition:background .3s}.post-body .link-grid .link-grid-container:hover{animation:next-shake .5s;background:var(--card-bg-color)}.post-body .link-grid .link-grid-container:active{box-shadow:.5rem .5rem .25rem rgba(0,0,0,.5);transform:translate(.2rem,.2rem)}.post-body .link-grid .link-grid-container .link-grid-image{border:1px solid #ddd;border-radius:50%;box-sizing:border-box;height:5rem;padding:3px;position:absolute;width:5rem}.post-body .link-grid .link-grid-container p{margin:0 1rem 0 6rem}.post-body .link-grid .link-grid-container p:first-of-type{font-size:1.2em}.post-body .link-grid .link-grid-container p:last-of-type{font-size:.8em;line-height:1.3rem;opacity:.7}.post-body .link-grid .link-grid-container a{border:0;height:100%;left:0;position:absolute;top:0;width:100%}@keyframes next-shake{0%{transform:translate(1pt,1pt) rotate(0)}10%{transform:translate(-1pt,-2pt) rotate(-1deg)}20%{transform:translate(-3pt,0) rotate(1deg)}30%{transform:translate(3pt,2pt) rotate(0)}40%{transform:translate(1pt,-1pt) rotate(1deg)}50%{transform:translate(-1pt,2pt) rotate(-1deg)}60%{transform:translate(-3pt,1pt) rotate(0)}70%{transform:translate(3pt,1pt) rotate(-1deg)}80%{transform:translate(-1pt,-1pt) rotate(1deg)}90%{transform:translate(1pt,2pt) rotate(0)}100%{transform:translate(1pt,-2pt) rotate(-1deg)}}.post-body .note{border-radius:3px;margin-bottom:20px;padding:1em;position:relative;background:#f9f9f9;border:initial;border-left:3px solid #eee}.post-body .note summary{cursor:pointer;outline:0}.post-body .note summary p{display:inline}.post-body .note h2,.post-body .note h3,.post-body .note h4,.post-body .note h5,.post-body .note h6{border-bottom:initial;margin:0;padding-top:0}.post-body .note :first-child{margin-top:0}.post-body .note :last-child{margin-bottom:0}.post-body .note:not(.no-icon){padding-left:2.5em}.post-body .note:not(.no-icon)::before{font-size:1.5em;left:.3em;position:absolute;top:calc(50% - 1em)}.post-body .note.default{background:#f7f7f7;border-left-color:#777}.post-body .note.default h2,.post-body .note.default h3,.post-body .note.default h4,.post-body .note.default h5,.post-body .note.default h6{color:#777}.post-body .note.default:not(.no-icon)::before{content:'\f0a9';font-family:'Font Awesome 6 Free';font-weight:900;color:#777}.post-body .note.primary{background:#f5f0fa;border-left-color:#6f42c1}.post-body .note.primary h2,.post-body .note.primary h3,.post-body .note.primary h4,.post-body .note.primary h5,.post-body .note.primary h6{color:#6f42c1}.post-body .note.primary:not(.no-icon)::before{content:'\f055';font-family:'Font Awesome 6 Free';font-weight:900;color:#6f42c1}.post-body .note.info{background:#eef7fa;border-left-color:#428bca}.post-body .note.info h2,.post-body .note.info h3,.post-body .note.info h4,.post-body .note.info h5,.post-body .note.info h6{color:#428bca}.post-body .note.info:not(.no-icon)::before{content:'\f05a';font-family:'Font Awesome 6 Free';font-weight:900;color:#428bca}.post-body .note.success{background:#eff8f0;border-left-color:#5cb85c}.post-body .note.success h2,.post-body .note.success h3,.post-body .note.success h4,.post-body .note.success h5,.post-body .note.success h6{color:#5cb85c}.post-body .note.success:not(.no-icon)::before{content:'\f058';font-family:'Font Awesome 6 Free';font-weight:900;color:#5cb85c}.post-body .note.warning{background:#fdf8ea;border-left-color:#f0ad4e}.post-body .note.warning h2,.post-body .note.warning h3,.post-body .note.warning h4,.post-body .note.warning h5,.post-body .note.warning h6{color:#f0ad4e}.post-body .note.warning:not(.no-icon)::before{content:'\f06a';font-family:'Font Awesome 6 Free';font-weight:900;color:#f0ad4e}.post-body .note.danger{background:#fcf1f2;border-left-color:#d9534f}.post-body .note.danger h2,.post-body .note.danger h3,.post-body .note.danger h4,.post-body .note.danger h5,.post-body .note.danger h6{color:#d9534f}.post-body .note.danger:not(.no-icon)::before{content:'\f056';font-family:'Font Awesome 6 Free';font-weight:900;color:#d9534f}.post-body .tabs{margin-bottom:20px}.post-body .tabs,.tabs-comment{padding-top:10px}.post-body .tabs ul.nav-tabs,.tabs-comment ul.nav-tabs{background:var(--content-bg-color);display:flex;display:flex;flex-wrap:wrap;justify-content:center;margin:0;padding:0;position:-webkit-sticky;position:sticky;top:0;z-index:5}@media (max-width:413px){.post-body .tabs ul.nav-tabs,.tabs-comment ul.nav-tabs{display:block;margin-bottom:5px}}.post-body .tabs ul.nav-tabs li.tab,.tabs-comment ul.nav-tabs li.tab{border-bottom:1px solid #ddd;border-left:1px solid transparent;border-right:1px solid transparent;border-radius:0;border-top:3px solid transparent;flex-grow:1;list-style-type:none}@media (max-width:413px){.post-body .tabs ul.nav-tabs li.tab,.tabs-comment ul.nav-tabs li.tab{border-bottom:1px solid transparent;border-left:3px solid transparent;border-right:1px solid transparent;border-top:1px solid transparent}}@media (max-width:413px){.post-body .tabs ul.nav-tabs li.tab,.tabs-comment ul.nav-tabs li.tab{border-radius:0}}.post-body .tabs ul.nav-tabs li.tab a,.tabs-comment ul.nav-tabs li.tab a{border-bottom:initial;display:block;line-height:1.8;padding:.25em .75em;text-align:center;transition:all .2s ease-out}.post-body .tabs ul.nav-tabs li.tab a i,.tabs-comment ul.nav-tabs li.tab a i{width:1.285714285714286em}.post-body .tabs ul.nav-tabs li.tab.active,.tabs-comment ul.nav-tabs li.tab.active{border-bottom-color:transparent;border-left-color:#ddd;border-right-color:#ddd;border-top-color:#fc6423}@media (max-width:413px){.post-body .tabs ul.nav-tabs li.tab.active,.tabs-comment ul.nav-tabs li.tab.active{border-bottom-color:#ddd;border-left-color:#fc6423;border-right-color:#ddd;border-top-color:#ddd}}.post-body .tabs ul.nav-tabs li.tab.active a,.tabs-comment ul.nav-tabs li.tab.active a{cursor:default}.post-body .tabs .tab-content,.tabs-comment .tab-content{border:1px solid #ddd;border-radius:0;border-top-color:transparent}@media (max-width:413px){.post-body .tabs .tab-content,.tabs-comment .tab-content{border-radius:0;border-top-color:#ddd}}.post-body .tabs .tab-content .tab-pane,.tabs-comment .tab-content .tab-pane{padding:20px 20px 0}.post-body .tabs .tab-content .tab-pane:not(.active),.tabs-comment .tab-content .tab-pane:not(.active){display:none}.pagination .next,.pagination .page-number,.pagination .prev,.pagination .space{display:inline-block;margin:-1px 10px 0;padding:0 10px}@media (max-width:767px){.pagination .next,.pagination .page-number,.pagination .prev,.pagination .space{margin:0 5px}}.pagination .page-number.current{background:#ccc;border-color:#ccc;color:var(--content-bg-color)}.pagination{border-top:1px solid #eee;margin:120px 0 0;text-align:center}.pagination .next,.pagination .page-number,.pagination .prev{border-bottom:0;border-top:1px solid #eee;transition:border-color .2s ease-in-out}.pagination .next:hover,.pagination .page-number:hover,.pagination .prev:hover{border-top-color:var(--link-hover-color)}@media (max-width:767px){.pagination{border-top:0}.pagination .next,.pagination .page-number,.pagination .prev{border-bottom:1px solid #eee;border-top:0}.pagination .next:hover,.pagination .page-number:hover,.pagination .prev:hover{border-bottom-color:var(--link-hover-color)}}.pagination .space{margin:0;padding:0}.comments{margin-top:60px;overflow:hidden}.comment-button-group{display:flex;display:flex;flex-wrap:wrap;justify-content:center;justify-content:center;margin:1em 0}.comment-button-group .comment-button{margin:.1em .2em}.comment-button-group .comment-button.active{background:var(--btn-default-hover-bg);border-color:var(--btn-default-hover-border-color);color:var(--btn-default-hover-color)}.comment-position{display:none}.comment-position.active{display:block}.tabs-comment{margin-top:4em;padding-top:0}.tabs-comment .comments{margin-top:0;padding-top:0}.headband{background:var(--theme-color);height:3px}@media (max-width:991px){.headband{display:none}}.site-brand-container{display:flex;flex-shrink:0;padding:0 10px}.use-motion .column,.use-motion .site-brand-container .toggle{opacity:0}.site-meta{flex-grow:1;text-align:center}@media (max-width:767px){.site-meta{text-align:center}}.custom-logo-image{margin-top:20px}@media (max-width:991px){.custom-logo-image{display:none}}.brand{border-bottom:0;color:var(--brand-color);display:inline-block;padding:0}.brand:hover{color:var(--brand-hover-color)}.site-title{font-family:Lato,'PingFang SC','Microsoft YaHei',sans-serif;font-size:1.375em;font-weight:400;line-height:1.5;margin:0}.site-subtitle{color:#ddd;font-size:.8125em;margin:10px 10px 0}.use-motion .custom-logo-image,.use-motion .site-subtitle,.use-motion .site-title{opacity:0;position:relative;top:-10px}.site-nav-right,.site-nav-toggle{display:none}@media (max-width:767px){.site-nav-right,.site-nav-toggle{display:flex;flex-direction:column;justify-content:center}}.site-nav-right .toggle,.site-nav-toggle .toggle{color:var(--text-color);padding:10px;width:22px}.site-nav-right .toggle .toggle-line,.site-nav-toggle .toggle .toggle-line{background:var(--text-color);border-radius:1px}@media (max-width:767px){.site-nav{--scroll-height:0;height:0;overflow:hidden;transition:.2s ease-in-out;transition-property:height,visibility;visibility:hidden}body:not(.site-nav-on) .site-nav .animated{animation:none}body.site-nav-on .site-nav{height:var(--scroll-height);visibility:unset}}.menu{margin:0;padding:1em 0;text-align:center}.menu-item{display:inline-block;list-style:none;margin:0 10px}@media (max-width:767px){.menu-item{display:block;margin-top:10px}.menu-item.menu-item-search{display:none}}.menu-item a{border-bottom:0;display:block;font-size:.8125em;transition:border-color .2s ease-in-out}.menu-item a.menu-item-active,.menu-item a:hover{background:var(--menu-item-bg-color)}.menu-item .fa,.menu-item .fab,.menu-item .far,.menu-item .fas{margin-right:8px}.menu-item .badge{display:inline-block;font-weight:700;line-height:1;margin-left:.35em;margin-top:.35em;text-align:center;white-space:nowrap}@media (max-width:767px){.menu-item .badge{float:right;margin-left:0}}.use-motion .menu-item{visibility:hidden}.github-corner :hover .octo-arm{animation:octocat-wave 560ms ease-in-out}.github-corner svg{color:#fff;fill:var(--theme-color);position:absolute;right:0;top:0;z-index:5}@media (max-width:991px){.github-corner{display:none}.github-corner svg{color:var(--theme-color);fill:#fff}.github-corner .github-corner:hover .octo-arm{animation:none}.github-corner .github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}.sidebar-inner{color:#999;padding:18px 10px;text-align:center;display:flex;flex-direction:column;justify-content:center}.cc-license .cc-opacity{border-bottom:0;opacity:.7}.cc-license .cc-opacity:hover{opacity:.9}.cc-license img{display:inline-block}.site-author-image{border:1px solid #eee;max-width:120px;padding:2px;border-radius:50%;transition:transform 1s ease-out}.site-author-image:hover{transform:rotateZ(360deg)}.site-author-name{color:var(--text-color);font-weight:600;margin:0}.site-description{color:#999;font-size:.8125em;margin-top:0}.links-of-author a{font-size:.8125em}.sidebar .sidebar-button:not(:first-child){margin-top:15px}.sidebar .sidebar-button button{background:0 0;color:#fc6423;cursor:pointer;line-height:2;padding:0 15px;border:1px solid #fc6423;border-radius:4px}.sidebar .sidebar-button button:hover{background:#fc6423;color:#fff}.sidebar .sidebar-button button .fa,.sidebar .sidebar-button button .fab,.sidebar .sidebar-button button .far,.sidebar .sidebar-button button .fas{margin-right:5px}.links-of-blogroll{font-size:.8125em}.links-of-blogroll-title{font-size:.875em;font-weight:600}.links-of-blogroll-list{list-style:none;margin:0;padding:0}.sidebar-nav{font-size:.875em;height:0;margin:0;overflow:hidden;padding-left:0;pointer-events:none;transition:.2s ease-in-out;transition-property:height,visibility;visibility:hidden}.sidebar-nav-active .sidebar-nav{height:calc(2em + 1px);pointer-events:unset;visibility:unset}.sidebar-nav li{border-bottom:1px solid transparent;color:var(--text-color);cursor:pointer;display:inline-block;transition:.2s ease-in-out;transition-property:border-bottom-color,color}.sidebar-nav li.sidebar-nav-overview{margin-left:10px}.sidebar-nav li:hover{color:#fc6423}.sidebar-overview-active .sidebar-nav-overview,.sidebar-toc-active .sidebar-nav-toc{border-bottom-color:#fc6423;color:#fc6423;transition-delay:.2s}.sidebar-overview-active .sidebar-nav-overview:hover,.sidebar-toc-active .sidebar-nav-toc:hover{color:#fc6423}.sidebar-panel-container{align-items:start;display:grid;flex:1;overflow-x:hidden;overflow-y:auto;padding-top:0;transition:padding-top .2s ease-in-out}.sidebar-nav-active .sidebar-panel-container{padding-top:20px}.sidebar-panel{animation:deactivate-sidebar-panel .2s ease-in-out;grid-area:1/1;height:0;opacity:0;overflow:hidden;pointer-events:none;transform:translateY(0);transition:.2s ease-in-out;transition-delay:0s;transition-property:opacity,transform,visibility;visibility:hidden}.sidebar-nav-active .sidebar-panel,.sidebar-overview-active .sidebar-panel.post-toc-wrap{transform:translateY(-20px)}.sidebar-overview-active:not(.sidebar-nav-active) .sidebar-panel.post-toc-wrap{transition-delay:0s,.2s,0s}.sidebar-overview-active .sidebar-panel.site-overview-wrap,.sidebar-toc-active .sidebar-panel.post-toc-wrap{animation-name:activate-sidebar-panel;height:auto;opacity:1;pointer-events:unset;transform:translateY(0);transition-delay:.2s,.2s,0s;visibility:unset}.sidebar-panel.site-overview-wrap{display:flex;flex-direction:column;justify-content:center;gap:10px;justify-content:flex-start}@keyframes deactivate-sidebar-panel{from{height:var(--inactive-panel-height,0)}to{height:var(--active-panel-height,0)}}@keyframes activate-sidebar-panel{from{height:var(--inactive-panel-height,auto)}to{height:var(--active-panel-height,auto)}}.sidebar-toggle{bottom:61px;height:16px;padding:5px;width:16px;background:#222;cursor:pointer;opacity:.6;position:fixed;z-index:30;right:30px}@media (max-width:991px){.sidebar-toggle{right:20px}}.sidebar-toggle:hover{opacity:.8}@media (max-width:991px){.sidebar-toggle{opacity:.8}}.sidebar-toggle:hover .toggle-line{background:#fc6423}@media (any-hover:hover){body:not(.sidebar-active) .sidebar-toggle:hover :first-child{left:50%;top:2px;transform:rotate(45deg);width:50%}body:not(.sidebar-active) .sidebar-toggle:hover :last-child{left:50%;top:-2px;transform:rotate(-45deg);width:50%}}.sidebar-active .sidebar-toggle :nth-child(2){opacity:0}.sidebar-active .sidebar-toggle :first-child{top:6px;transform:rotate(45deg)}.sidebar-active .sidebar-toggle :last-child{top:-6px;transform:rotate(-45deg)}.post-toc{font-size:.875em}.post-toc ol{list-style:none;margin:0;padding:0 2px 0 10px;text-align:left}.post-toc ol>:last-child{margin-bottom:5px}.post-toc ol>ol{padding-left:0}.post-toc ol a{transition:all .2s ease-in-out}.post-toc .nav-item{line-height:1.8;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.post-toc .nav .nav-child{--height:0;height:0;opacity:0;overflow:hidden;transition-property:height,opacity,visibility;transition:.2s ease-in-out;visibility:hidden}.post-toc .nav .active>.nav-child{height:var(--height,auto);opacity:1;visibility:unset}.post-toc .nav .active>a{border-bottom-color:#fc6423;color:#fc6423}.post-toc .nav .active-current>a{color:#fc6423}.post-toc .nav .active-current>a:hover{color:#fc6423}.site-state{display:flex;flex-wrap:wrap;justify-content:center;line-height:1.4}.site-state-item{padding:0 15px}.site-state-item a{border-bottom:0;display:block}.site-state-item-count{display:block;font-size:1em;font-weight:600}.site-state-item-name{color:#999;font-size:.8125em}.footer{color:#999;font-size:.875em;padding:20px 0;transition:.2s ease-in-out;transition-property:left,right}.footer.footer-fixed{bottom:0;left:0;position:absolute;right:0}.footer-inner{box-sizing:border-box;text-align:center;display:flex;flex-direction:column;justify-content:center;margin:0 auto;width:calc(100% - 20px)}@media (max-width:767px){.footer-inner{width:auto}}@media (min-width:1200px){.footer-inner{width:1160px}}@media (min-width:1600px){.footer-inner{width:73%}}.use-motion .footer{opacity:0}.languages{display:inline-block;font-size:1.125em;position:relative}.languages .lang-select-label span{margin:0 .5em}.languages .lang-select{height:100%;left:0;opacity:0;position:absolute;top:0;width:100%}.with-love{color:red;display:inline-block;margin:0 5px}.busuanzi-count #busuanzi_container_site_uv{display:none}.busuanzi-count #busuanzi_container_site_pv{display:none}@keyframes icon-animate{0%,100%{transform:scale(1)}10%,30%{transform:scale(.9)}20%,40%,60%,80%{transform:scale(1.1)}50%,70%{transform:scale(1.1)}}.back-to-top{font-size:12px;align-items:center;bottom:-100px;color:#fff;display:flex;height:26px;transition:bottom .2s ease-in-out;background:#222;cursor:pointer;opacity:.6;position:fixed;z-index:30;right:30px}.back-to-top span{margin-right:8px}.back-to-top .fa{text-align:center;width:26px}@media (max-width:991px){.back-to-top{right:20px}}.back-to-top:hover{opacity:.8}@media (max-width:991px){.back-to-top{opacity:.8}}.back-to-top:hover{color:#fc6423}.back-to-top.back-to-top-on{bottom:30px}.reading-progress-bar{--progress:0;background:#37c6c0;height:3px;position:fixed;z-index:50;width:var(--progress);left:0;bottom:0}.rtl.post-body a,.rtl.post-body h1,.rtl.post-body h2,.rtl.post-body h3,.rtl.post-body h4,.rtl.post-body h5,.rtl.post-body h6,.rtl.post-body li,.rtl.post-body ol,.rtl.post-body p,.rtl.post-body ul{direction:rtl;font-family:UKIJ Ekran}.rtl.post-title{font-family:UKIJ Ekran}.post-button{margin-top:40px;text-align:center}.use-motion .comments,.use-motion .pagination,.use-motion .post-block{visibility:hidden}.use-motion .post-header{visibility:hidden}.use-motion .post-body{visibility:hidden}.use-motion .collection-header{visibility:hidden}.posts-collapse .post-content{margin-bottom:35px;margin-left:35px;position:relative}@media (max-width:767px){.posts-collapse .post-content{margin-left:0;margin-right:0}}.posts-collapse .post-content .collection-title{font-size:1.125em;position:relative}.posts-collapse .post-content .collection-title::before{background:#999;border:1px solid #fff;margin-left:-6px;margin-top:-4px;position:absolute;top:50%;border-radius:50%;content:' ';height:10px;width:10px}.posts-collapse .post-content .collection-year{font-size:1.5em;font-weight:700;margin:60px 0;position:relative}.posts-collapse .post-content .collection-year::before{background:#bbb;margin-left:-4px;margin-top:-4px;position:absolute;top:50%;border-radius:50%;content:' ';height:8px;width:8px}.posts-collapse .post-content .collection-header{display:block;margin-left:20px}.posts-collapse .post-content .collection-header small{color:#bbb;margin-left:5px}.posts-collapse .post-content .post-header{border-bottom:1px dashed #ccc;margin:30px 2px 0;padding-left:15px;position:relative;transition:border .2s ease-in-out}.posts-collapse .post-content .post-header::before{background:#bbb;border:1px solid #fff;left:-6px;position:absolute;top:.75em;transition:background .2s ease-in-out;border-radius:50%;content:' ';height:6px;width:6px}.posts-collapse .post-content .post-header:hover{border-bottom-color:#666}.posts-collapse .post-content .post-header:hover::before{background:#222}.posts-collapse .post-content .post-meta-container{display:inline;font-size:.75em;margin-right:10px}.posts-collapse .post-content .post-title{display:inline}.posts-collapse .post-content .post-title a{border-bottom:0;color:var(--link-color)}.posts-collapse .post-content .post-title .fa-external-link-alt{font-size:.875em;margin-left:5px}.posts-collapse .post-content::before{background:#f5f5f5;content:' ';height:100%;margin-left:-2px;position:absolute;top:1.25em;width:4px}.post-body{font-family:Lato,'PingFang SC','Microsoft YaHei',sans-serif;overflow-wrap:break-word}@media (min-width:1200px){.post-body{font-size:1.125em}}@media (min-width:992px){.post-body{text-align:justify}}@media (max-width:991px){.post-body{text-align:justify}}.post-body h1 .header-anchor,.post-body h1 .headerlink,.post-body h2 .header-anchor,.post-body h2 .headerlink,.post-body h3 .header-anchor,.post-body h3 .headerlink,.post-body h4 .header-anchor,.post-body h4 .headerlink,.post-body h5 .header-anchor,.post-body h5 .headerlink,.post-body h6 .header-anchor,.post-body h6 .headerlink{border-bottom-style:none;color:inherit;float:right;font-size:.875em;margin-left:10px;opacity:0}.post-body h1 .header-anchor::before,.post-body h1 .headerlink::before,.post-body h2 .header-anchor::before,.post-body h2 .headerlink::before,.post-body h3 .header-anchor::before,.post-body h3 .headerlink::before,.post-body h4 .header-anchor::before,.post-body h4 .headerlink::before,.post-body h5 .header-anchor::before,.post-body h5 .headerlink::before,.post-body h6 .header-anchor::before,.post-body h6 .headerlink::before{content:'\f0c1';font-family:'Font Awesome 6 Free';font-weight:900}.post-body h1:hover .header-anchor,.post-body h1:hover .headerlink,.post-body h2:hover .header-anchor,.post-body h2:hover .headerlink,.post-body h3:hover .header-anchor,.post-body h3:hover .headerlink,.post-body h4:hover .header-anchor,.post-body h4:hover .headerlink,.post-body h5:hover .header-anchor,.post-body h5:hover .headerlink,.post-body h6:hover .header-anchor,.post-body h6:hover .headerlink{opacity:.5}.post-body h1:hover .header-anchor:hover,.post-body h1:hover .headerlink:hover,.post-body h2:hover .header-anchor:hover,.post-body h2:hover .headerlink:hover,.post-body h3:hover .header-anchor:hover,.post-body h3:hover .headerlink:hover,.post-body h4:hover .header-anchor:hover,.post-body h4:hover .headerlink:hover,.post-body h5:hover .header-anchor:hover,.post-body h5:hover .headerlink:hover,.post-body h6:hover .header-anchor:hover,.post-body h6:hover .headerlink:hover{opacity:1}.post-body .exturl .fa{font-size:.875em;margin-left:4px}.post-body .fancybox+figcaption,.post-body .image-caption,.post-body img+figcaption{color:#999;font-size:.875em;font-weight:700;line-height:1;margin:-15px auto 15px;text-align:center}.post-body embed,.post-body iframe,.post-body img,.post-body video{margin-bottom:20px}.post-body .video-container{height:0;margin-bottom:20px;overflow:hidden;padding-top:75%;position:relative;width:100%}.post-body .video-container embed,.post-body .video-container iframe,.post-body .video-container object{height:100%;left:0;margin:0;position:absolute;top:0;width:100%}.post-gallery{display:flex;min-height:200px}.post-gallery .post-gallery-image{flex:1}.post-gallery .post-gallery-image:not(:first-child){clip-path:polygon(40px 0,100% 0,100% 100%,0 100%);margin-left:-20px}.post-gallery .post-gallery-image:not(:last-child){margin-right:-20px}.post-gallery .post-gallery-image img{height:100%;object-fit:cover;opacity:1;width:100%}.posts-expand .post-gallery{margin-bottom:60px}.posts-collapse .post-gallery{margin:15px 0}.posts-expand .post-header{font-size:1.125em;margin-bottom:60px;text-align:center}.posts-expand .post-title{font-size:1.5em;font-weight:400;margin:initial;overflow-wrap:break-word}.posts-expand .post-title-link{border-bottom:0;color:var(--link-color);display:inline-block;position:relative}.posts-expand .post-title-link::before{background:var(--link-color);bottom:0;content:'';height:2px;left:0;position:absolute;transform:scaleX(0);transition:transform .2s ease-in-out;width:100%}.posts-expand .post-title-link:hover::before{transform:scaleX(1)}.posts-expand .post-title-link .fa-external-link-alt{font-size:.875em;margin-left:5px}.post-sticky-flag{display:inline-block;margin-right:8px;transform:rotate(30deg)}.posts-expand .post-meta-container{color:#999;font-family:Lato,'PingFang SC','Microsoft YaHei',sans-serif;font-size:.75em;margin-top:3px}.posts-expand .post-meta-container .post-description{font-size:.875em;margin-top:2px}.posts-expand .post-meta-container time{border-bottom:1px dashed #999}.post-meta{display:flex;flex-wrap:wrap;justify-content:center}:not(.post-meta-break)+.post-meta-item::before{content:'|';margin:0 .5em}.post-meta-item-icon{margin-right:3px}@media (max-width:991px){.post-meta-item-text{display:none}}.post-meta-break{flex-basis:100%;height:0}#busuanzi_container_page_pv{display:none}.post-nav{border-top:1px solid #eee;display:flex;gap:30px;justify-content:space-between;margin-top:1em;padding:10px 5px 0}.post-nav-item{flex:1}.post-nav-item a{border-bottom:0;display:block;font-size:.875em;line-height:1.6}.post-nav-item a:active{top:2px}.post-nav-item .fa{font-size:.75em}.post-nav-item:first-child .fa{margin-right:5px}.post-nav-item:last-child{text-align:right}.post-nav-item:last-child .fa{margin-left:5px}.post-footer{display:flex;flex-direction:column;justify-content:center}.post-eof{background:#ccc;height:1px;margin:80px auto 60px;width:8%}.post-block:last-of-type .post-eof{display:none}.post-copyright ul{list-style:none;overflow:hidden;padding:.5em 1em;position:relative;background:var(--card-bg-color);border-left:3px solid #ff2a2a;margin:1em 0 0}.post-copyright ul::after{content:'\f25e';font-family:'Font Awesome 6 Brands';font-size:200px;opacity:.1;position:absolute;right:-50px;top:-150px}.post-tags{margin-top:40px;text-align:center}.post-tags a{display:inline-block;font-size:.8125em}.post-tags a:not(:last-child){margin-right:10px}.social-like{border-top:1px solid #eee;font-size:.875em;margin-top:1em;padding-top:1em;text-align:center}.reward-container{margin:1em 0 0;padding:1em 0;text-align:center}.reward-container button{background:0 0;color:#fc6423;cursor:pointer;line-height:2;padding:0 15px;border:2px solid #fc6423;border-radius:2px;outline:0;transition:all .2s ease-in-out;vertical-align:text-top}.reward-container button:hover{background:#fc6423;color:#fff}.post-reward{display:none;padding-top:20px}.post-reward.active{display:block}.post-reward div{display:inline-block}.post-reward div span{display:block}.post-reward img{display:inline-block;margin:.8em 2em 0;max-width:100%;width:180px}@keyframes next-roll{from{transform:rotateZ(30deg)}to{transform:rotateZ(-30deg)}}.category-all-page .category-all-title{text-align:center}.category-all-page .category-all{margin-top:20px}.category-all-page .category-list{list-style:none;margin:0;padding:0}.category-all-page .category-list-item{margin:5px 10px}.category-all-page .category-list-count{color:#bbb}.category-all-page .category-list-count::before{content:' ('}.category-all-page .category-list-count::after{content:') '}.category-all-page .category-list-child{padding-left:10px}.event-list hr{background:#222;margin:20px 0 45px}.event-list hr::after{background:#222;color:#fff;content:'NOW';display:inline-block;font-weight:700;padding:0 5px}.event-list .event{--event-background:#222;--event-foreground:#bbb;--event-title:#fff;background:var(--event-background);padding:15px}.event-list .event .event-summary{border-bottom:0;color:var(--event-title);margin:0;padding:0 0 0 35px;position:relative}.event-list .event .event-summary::before{animation:dot-flash 1s alternate infinite ease-in-out;background:var(--event-title);left:0;margin-top:-6px;position:absolute;top:50%;border-radius:50%;content:' ';height:12px;width:12px}.event-list .event:nth-of-type(odd) .event-summary::before{animation-delay:.5s}.event-list .event:not(:last-child){margin-bottom:20px}.event-list .event .event-relative-time{color:var(--event-foreground);display:inline-block;font-size:12px;font-weight:400;padding-left:12px}.event-list .event .event-details{color:var(--event-foreground);display:block;line-height:18px;padding:6px 0 6px 35px}.event-list .event .event-details::before{color:var(--event-foreground);display:inline-block;margin-right:9px;width:14px;font-family:'Font Awesome 6 Free';font-weight:900}.event-list .event .event-details.event-location::before{content:'\f041'}.event-list .event .event-details.event-duration::before{content:'\f017'}.event-list .event .event-details.event-description::before{content:'\f024'}.event-list .event-past{--event-background:#f5f5f5;--event-foreground:#999;--event-title:#222}@keyframes dot-flash{from{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.8)}}ul.breadcrumb{font-size:.75em;list-style:none;margin:1em 0;padding:0 2em;text-align:center}ul.breadcrumb li{display:inline}ul.breadcrumb li:not(:first-child)::before{content:'/\00a0';font-weight:400;padding:.5em}ul.breadcrumb li:last-child{font-weight:700}.tag-cloud{text-align:center}.tag-cloud a{display:inline-block;margin:10px}.tag-cloud-0{border-bottom-color:#aaa;color:#aaa}.tag-cloud-1{border-bottom-color:#9a9a9a;color:#9a9a9a}.tag-cloud-2{border-bottom-color:#8b8b8b;color:#8b8b8b}.tag-cloud-3{border-bottom-color:#7c7c7c;color:#7c7c7c}.tag-cloud-4{border-bottom-color:#6c6c6c;color:#6c6c6c}.tag-cloud-5{border-bottom-color:#5d5d5d;color:#5d5d5d}.tag-cloud-6{border-bottom-color:#4e4e4e;color:#4e4e4e}.tag-cloud-7{border-bottom-color:#3e3e3e;color:#3e3e3e}.tag-cloud-8{border-bottom-color:#2f2f2f;color:#2f2f2f}.tag-cloud-9{border-bottom-color:#202020;color:#202020}.tag-cloud-10{border-bottom-color:#111;color:#111}.search-active{overflow:hidden}.search-pop-overlay{background:rgba(0,0,0,0);display:flex;height:100%;left:0;position:fixed;top:0;transition:visibility .4s,background .4s;visibility:hidden;width:100%;z-index:40}.search-active .search-pop-overlay{background:rgba(0,0,0,.3);visibility:visible}.search-popup{background:var(--card-bg-color);border-radius:5px;height:80%;margin:auto;transform:scale(0);transition:transform .4s;width:700px}.search-active .search-popup{transform:scale(1)}@media (max-width:767px){.search-popup{border-radius:0;height:100%;width:100%}}.search-popup .popup-btn-close,.search-popup .search-icon{color:#999;font-size:18px;padding:0 10px}.search-popup .popup-btn-close{cursor:pointer}.search-popup .popup-btn-close:hover .fa{color:#222}.search-popup .search-header{background:#eee;border-top-left-radius:5px;border-top-right-radius:5px;display:flex;padding:5px}.search-popup input.search-input{background:0 0;border:0;outline:0;width:100%}.search-popup input.search-input::-webkit-search-cancel-button{display:none}.search-popup .search-result-container{height:calc(100% - 55px);overflow:auto;padding:5px 25px}.search-popup .search-result-container hr{margin:5px 0 10px}.search-popup .search-result-container hr:first-child{display:none}.search-popup .search-result-list{margin:0 5px;padding:0}.search-popup a.search-result-title{font-weight:700}.search-popup p.search-result{border-bottom:1px dashed #ccc;padding:5px 0}.search-popup .search-input-container{flex-grow:1;padding:2px}.search-popup .no-result{display:flex}.search-popup .search-result-list{width:100%}.search-popup .search-result-icon{color:#ccc;margin:auto}mark.search-keyword{background:0 0;border-bottom:1px dashed #ff2a2a;color:#ff2a2a;font-weight:700}.use-motion .animated{animation-fill-mode:none;visibility:inherit}.use-motion .sidebar .animated{animation-fill-mode:both}.header{background:var(--content-bg-color);border-radius:20px 20px 20px 20px;box-shadow:0 2px 2px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.06),0 1px 5px 0 rgba(0,0,0,.12)}@media (max-width:991px){.header{border-radius:initial}}.main{align-items:stretch;display:flex;justify-content:space-between;margin:0 auto;width:calc(100% - 20px)}@media (max-width:767px){.main{width:auto}}@media (min-width:1200px){.main{width:1160px}}@media (min-width:1600px){.main{width:73%}}@media (max-width:991px){.main{display:block;width:auto}}.main-inner{border-radius:20px 20px 20px 20px;box-sizing:border-box;width:calc(100% - 252px)}@media (max-width:991px){.main-inner{border-radius:initial;width:100%}}.footer-inner{padding-left:252px}@media (max-width:991px){.footer-inner{padding-left:0;padding-right:0;width:auto}}.column{width:240px}@media (max-width:991px){.column{width:auto}}.site-brand-container{background:var(--theme-color)}@media (max-width:991px){.site-nav-on .site-brand-container{box-shadow:0 0 16px rgba(0,0,0,.5)}}.site-meta{padding:20px 0}@media (min-width:768px) and (max-width:991px){.site-nav-right,.site-nav-toggle{display:flex;flex-direction:column;justify-content:center}}.site-nav-right .toggle,.site-nav-toggle .toggle{color:#fff}.site-nav-right .toggle .toggle-line,.site-nav-toggle .toggle .toggle-line{background:#fff}@media (min-width:768px) and (max-width:991px){.site-nav{--scroll-height:0;height:0;overflow:hidden;transition:.2s ease-in-out;transition-property:height,visibility;visibility:hidden}body:not(.site-nav-on) .site-nav .animated{animation:none}body.site-nav-on .site-nav{height:var(--scroll-height);visibility:unset}}.menu .menu-item{display:block;margin:0}.menu .menu-item a{padding:5px 20px;position:relative;text-align:left;transition-property:background-color}@media (max-width:991px){.menu .menu-item.menu-item-search{display:none}}.menu .menu-item .badge{background:#ccc;border-radius:10px;color:var(--content-bg-color);float:right;padding:2px 5px;text-shadow:1px 1px 0 rgba(0,0,0,.1)}.sub-menu{margin:0;padding:6px 0}.sub-menu .menu-item{display:inline-block}.sub-menu .menu-item a{background:0 0;margin:5px 10px;padding:initial}.sub-menu .menu-item a:hover{background:0 0;color:#fc6423}.sub-menu .menu-item-active{border-bottom-color:#fc6423;color:#fc6423}.sub-menu .menu-item-active:hover{border-bottom-color:#fc6423}.sidebar{position:-webkit-sticky;position:sticky;top:12px}@media (max-width:991px){.sidebar{display:none}}.sidebar-inner{background:var(--content-bg-color);border-radius:20px;box-shadow:0 2px 2px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.06),0 1px 5px 0 rgba(0,0,0,.12),0 -1px .5px 0 rgba(0,0,0,.09);box-sizing:border-box;color:var(--text-color);margin-top:12px;max-height:calc(100vh - 24px);visibility:hidden}.site-state-item{padding:0 10px}.sidebar .sidebar-button{border-bottom:1px dotted #ccc;border-top:1px dotted #ccc}.sidebar .sidebar-button button{border:0;color:#fc6423;display:block;width:100%}.sidebar .sidebar-button button:hover{background:0 0;border:0;color:#e34603}.links-of-author{display:flex;flex-wrap:wrap;justify-content:center}.links-of-author-item{margin:5px 0 0}.links-of-author-item a{box-sizing:border-box;display:inline-block;max-width:100%;overflow:hidden;padding:0 5px;text-overflow:ellipsis;white-space:nowrap}.links-of-author-item a{border-bottom:0;border-radius:4px;display:block}.links-of-author-item a:hover{background:var(--body-bg-color)}.main-inner .comment-position .comments,.main-inner .pagination,.main-inner .post-block,.main-inner .sub-menu,.main-inner .tabs-comment,.main-inner>.comments{background:var(--content-bg-color);border-radius:20px 20px 20px 20px;box-shadow:0 2px 2px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.06),0 1px 5px 0 rgba(0,0,0,.12)}.main-inner .post-block:not(:first-child):not(:first-child){border-radius:20px;box-shadow:0 2px 2px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.06),0 1px 5px 0 rgba(0,0,0,.12),0 -1px .5px 0 rgba(0,0,0,.09);margin-top:12px}@media (min-width:768px) and (max-width:991px){.main-inner .post-block:not(:first-child):not(:first-child){margin-top:10px}}@media (max-width:767px){.main-inner .post-block:not(:first-child):not(:first-child){margin-top:8px}}.main-inner .comment-position .comments,.main-inner .pagination,.main-inner .tabs-comment,.main-inner>.comments{border-radius:20px;box-shadow:0 2px 2px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.06),0 1px 5px 0 rgba(0,0,0,.12),0 -1px .5px 0 rgba(0,0,0,.09);margin-top:12px}@media (min-width:768px) and (max-width:991px){.main-inner .comment-position .comments,.main-inner .pagination,.main-inner .tabs-comment,.main-inner>.comments{margin-top:10px}}@media (max-width:767px){.main-inner .comment-position .comments,.main-inner .pagination,.main-inner .tabs-comment,.main-inner>.comments{margin-top:8px}}.comments,.post-block{padding:40px}.post-eof{display:none}.pagination{border-top:initial;padding:10px 0}.post-body h1,.post-body h2{border-bottom:1px solid #eee}.post-body h3{border-bottom:1px dotted #eee}@media (min-width:768px) and (max-width:991px){.main-inner{padding:10px}.posts-expand .post-button{margin-top:20px}.post-block{padding:20px}.comments{padding:10px 20px}}@media (max-width:767px){.main-inner{padding:8px}.posts-expand .post-button{margin:12px 0}.post-block{padding:12px}.comments{padding:10px 12px}} +/* rebuild by neat */ \ No newline at end of file diff --git a/css/noscript.css b/css/noscript.css new file mode 100644 index 0000000..2b54dc1 --- /dev/null +++ b/css/noscript.css @@ -0,0 +1,3 @@ +/* build time:Tue Apr 25 2023 15:41:35 GMT+0800 (GMT+08:00)*/ +body{margin-top:2rem}.use-motion .collection-header,.use-motion .comments,.use-motion .menu-item,.use-motion .pagination,.use-motion .post-block,.use-motion .post-body,.use-motion .post-header,.use-motion .sidebar,.use-motion .sidebar-inner{visibility:visible}.use-motion .column,.use-motion .footer,.use-motion .site-brand-container .toggle{opacity:initial}.use-motion .custom-logo-image,.use-motion .site-subtitle,.use-motion .site-title{opacity:initial;top:initial}.use-motion .logo-line{transform:scaleX(1)}.search-pop-overlay,.sidebar-nav{display:none}.sidebar-panel{display:block}.noscript-warning{background-color:#f55;color:#fff;font-family:sans-serif;font-size:1rem;font-weight:700;left:0;position:fixed;text-align:center;top:0;width:100%;z-index:50} +/* rebuild by neat */ \ No newline at end of file diff --git a/guestbook/index.html b/guestbook/index.html new file mode 100644 index 0000000..2c4273f --- /dev/null +++ b/guestbook/index.html @@ -0,0 +1,16 @@ +留言板 | 随言碎语

随言碎语

咕叽咕叽

留言板

欢迎来到我的博客!

欢迎在这里留言!任何问题都可以在这里留言,博主会及时回复的,添加email可以收到回复提示

0%
\ No newline at end of file diff --git a/images/apple-touch-icon-next.png b/images/apple-touch-icon-next.png new file mode 100644 index 0000000000000000000000000000000000000000..86a0d1d33bc2ae8a0416ebba67d1bbb60aa29c38 GIT binary patch literal 1544 zcmV+j2KV`iP)Px#OHfQyMIs_1FE20E)zv2_C(h2!$jHdT!ovUm|GT@p zWo2de_xJq#{8d#|IyyQ>M@Qx533`J9dBE>4W{r{KFjMLpp4N$2iMRJCGfPM7@le{)BPzVgz zp?ByVdWYVj|4-=tUS5SkR}Te{-Fr#UrxsqJ9+ed6YY9KmoXq6n^B9DRMwF@T2u)qH z!=wh-sAdPH_8fFy0-I1d68Zp);!FTtdweUZc2nr)?5^hh99w*FOU z@NYFT^!v%iPrGly0Q*+sLVtesYh+the|AET4WK8lR^dv1IZ-3FhAuiK5V|-?gf2#j z&_yW`x^K3G&OKl4kP$$ih@p!?B6M+)2(4Rz(6$=G6WT(;6uP)cgkEi(xI(Yi7`D(w zo(Y6r>FyarFV`4e&^@lk@PfWf|DSeM5}?agV`>aDXt-c%3^!*Ij0g0Q8X5*mjbRC$9oB0MOK51O_53LU8p`RzcozW; zx3wC>721@58xhdzx?E$}LW9xpjUu4UhOZO>Z8Us+D+1bR_}&sQXJ}B}yadb|8fraT zV|YUw4WF(>KpPF;mjp}*eTo5XG<+u!&}PFoihwq!uhI`XPYZ1{e1FDs0nqR?Ym5YF zqv0DwK${KUMFjNpqb>9(0vg8Y^d$otmiJc}L#s|8wD~Z~fHtQu8PG6DgwAq-&}PFY z1KMo(WI!7YpAcwxN`zJiV(2pgG_<|npE+y^Z8UsBppAx42(;Po$$&N*J{izP!?y+W zi2YsL=fkK`KXsymhWcmL#_y-S*Y&V_u#us^S9pDvbMSkxv7uidoc36Qa`CQ+5AC^d z=CTJ%0ZkrQ=v?t(E_)>OCL8YaU+nX$$--iAUNb;m^jBG2!5*5enU|exmY3aQcv=O- znjO}ft-yw2|VZs2g-W`Epf@n*5gsJ2LLtC^nFlq8+?%Xc!{Z3_|hFI~!oeU$ep z%4jE9Y9n1{ah68@W{++)8|fc~HIM4)QycHpg}3P<_K$M$L~}7jBXs?6bDwjvo+I;D zsoi}398La6+~*osM@45l#ptQ6MrZFz597*no3v)ffsUEletxWeW~`A+ntYvaeQj?e z*kSqGXZsrrhZ>IsxH$({IR{z11zkG`GR^j$#{%z41lp5(Ne#glJc5nj-BUaKR!X?# zzN6F-<0?&z;|30?9q0Z}oHG*G)Q)s%Db~RbjMU)mp-u&Dmm0zkF~o9eRh}p?ByVnjn4wmEZ*c=^{+H00012dQ@0+Qek%>aB^>E zX>4U6ba`-PAZc)PV*mhnoa6Eg2ys>@D9TUE%t_@^00ScnE@KN5BNI!L6ay0=M1VBI uWCJ6!R3OXP)X2ol#2my2%YaCrN-hBE7ZG&wLN%2D0000`v literal 0 HcmV?d00001 diff --git a/images/avatar.gif b/images/avatar.gif new file mode 100644 index 0000000000000000000000000000000000000000..3b5d744b17ae541e331e9296640f0418d4e7c821 GIT binary patch literal 1785 zcmc(eiCfYK1Au>kC}AoSube4(tj%1XGs-IqwL{J4`&#nMW_^ZNl2cuo5V((w@KF|BSr-Dy?Ci?Qibx<>SXfwIUgogbVv$IpPzd>aHjAZHDkmh84Xt*5 zetu+ln8)SL&&~0%H{C|LeZF5GCnaWl}%00$Q845^9#jbGjmg0YYZq% z1HxF_nwpz|7kNflF9N9Q5iJvD0w&0S9`em0*f}BgKh?c=3?YfFSYWEn(AG8D&f9}T zF|^Ozg(s2g21~=--BqP2;U+HbKfJ-6t^Mpd+Vd(rH9aPG>VjZaYzrEFkzM1W4W*?PEbt7_?0ObX=R3 zfm*vF0T2e?IaX0s7omGCFNR2kL@?w2C0yDOh`J7v?|JOT+#U{?U0_{uqpk}`=r+VP zC12fo8O3{HxoZwDCgwbOZNi&VzKT}`9?t!=AVtC=y%<;l+psDMv*su+IEO5Q?TgN0 z=&H7$Gf?L=qqi5`@bimQ^6tFqKOeh&ck{=aiDvo7nlqFv&4wkwGeO}maQB{~k%?ck zE7Cdok^c8R9AM5IP1JJ)~Cz5Sv{>KNvX5%lB* z9%4%%UT_Wehfmg@gc%I&MaBNNZg03yUt|q!t%QXZJ9njhaoqbXT&%>qob*i$7vJ9{ z<5xiO5wWzi1105!#^PQCsto8sM4BepmIPkI5zoZ?*-1r_m8zst+M_T+_C9c`BdGyZ z()dMh4bJ_{K1iXtN>KzH?;xb$$ACsu8o5!>Fp}gw-jJ7^zUL{9PKe8II{SSj5atkhyp)&z8{9L0;5~dN8IV%e^8!Cm#@R*x{T5QR+y!yez%{*GTHhd}S&e?yi8`c_py&b`IA#{jM67?2A- z96X6KMj50BNJHBI?9Zj78OXyk^6Q>ufCnUfBpmb@X3fgX_M_S)8KAM>*1*t+*UyZc z^4w;`mO~qzDlqH`0`+#Ffh1i?m ztGf;Harv-B6uCo0TB=_qclsj^84AC_7^!(v;Oi5;Kl$z+X{K*fpE(N zWyVw!0PLHXpb*M(Bl@dIQsB%LhJP-?;tE={h{Y(QpYjdD9`hDbfEiJN) znh_Ry7j#5m>=)N|?3XDh_r1_zMIHc&wJ0=9`=ky7CuDT$ia(uo`t1DDrGgKeCI{e@ z{!P0)EBNAc7g6Tp|0X`9!<~%Y?miKrA{MDPqrRMh1+NgBt?oT@PRlxMyn2}v=_`HO z`{&U{yA!^h75UlWQ#)`T_pCemHpYGaJuhRu^ZY~){h#)L$)<4Zd(gT$0zX0)xk sj2>F=QOaOm@==$w^6D`S!9xiV>IXt*{ozi=Q1Vaehf=%aC;;&N3lE276aWAK literal 0 HcmV?d00001 diff --git a/images/favicon-16x16-next.png b/images/favicon-16x16-next.png new file mode 100644 index 0000000000000000000000000000000000000000..de8c5d3a5f8215c3f7b095c9e284e061bda65f86 GIT binary patch literal 435 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstUx|vage(c z!@6@aFM%A+0*}aIAe|4wj2{=>aRxHH1AIbUeKHFb!9Yn#DLy_vBO^maMdk0`zd#Zw z0tY~@yu3V6p{Ay$mX_Az$B+O0`?r4m`qisfPnj~MwY3$f@^9nqaG!lvI6;x#X;^) z4C~IxyaaMM3p^r=f%IJvW-JI^#13S11^9%x`eYU=fq|TyoQjGHgbgIWfB*jF%NI8{ zx2;>Zu3x`iO-&6bs0aoM3JPUqWq0n}*}Qo(P|Le_@AmKC57(%ytPE5IHwwrGiqzKD z{{8#c)YSCg!Gk}3{P_R>|Gj(no6k4eJyZq^Jd4Jw%*zpM57yY9pK zMcQgs21j>QigM54W!RCVazM0UCtHDVhG46xh5pA!(TqDDnlwLEm~eRS(JM@6p3293 zNMwDW(!P~x!s$%jghh-wOB)P19fJ88oOHECttPa5*~LF^Vp#0%pwrbyN~~|szWB|o z_J4%n&U>rEu5s2%I6jof{A;(j!|>g|;yo?%ZfFGheBJp^9_Zijs*s41pu}>8f};Gi z%$!t(lFEWqh0KDIWCn(cIgdZ_a1@4VXq@stea7=?5CgL^w_Y;0u(GiCWD#az1(ybs x!zs+ln?n>%-?(z($eANDN7zp{cr5VJV|XPlSn|oqbSlsa22WQ%mvv4FO#p=N1nU3* literal 0 HcmV?d00001 diff --git a/images/logo-algolia-nebula-blue-full.svg b/images/logo-algolia-nebula-blue-full.svg new file mode 100644 index 0000000..886c422 --- /dev/null +++ b/images/logo-algolia-nebula-blue-full.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/logo.svg b/images/logo.svg new file mode 100644 index 0000000..992c1a5 --- /dev/null +++ b/images/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/nh.jpg b/images/nh.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4dd8a3649801705d6862c87c050f8f21b193d52e GIT binary patch literal 75589 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随言碎语
0%
\ No newline at end of file diff --git a/js/bookmark.js b/js/bookmark.js new file mode 100644 index 0000000..8e3ae6a --- /dev/null +++ b/js/bookmark.js @@ -0,0 +1,56 @@ +/* global CONFIG */ + +document.addEventListener('DOMContentLoaded', () => { + 'use strict'; + + const doSaveScroll = () => { + localStorage.setItem('bookmark' + location.pathname, window.scrollY); + }; + + const scrollToMark = () => { + let top = localStorage.getItem('bookmark' + location.pathname); + top = parseInt(top, 10); + // If the page opens with a specific hash, just jump out + if (!isNaN(top) && location.hash === '') { + // Auto scroll to the position + window.anime({ + targets : document.scrollingElement, + duration : 200, + easing : 'linear', + scrollTop: top + }); + } + }; + // Register everything + const init = function(trigger) { + // Create a link element + const link = document.querySelector('.book-mark-link'); + // Scroll event + window.addEventListener('scroll', () => link.classList.toggle('book-mark-link-fixed', window.scrollY === 0), { passive: true }); + // Register beforeunload event when the trigger is auto + if (trigger === 'auto') { + // Register beforeunload event + window.addEventListener('beforeunload', doSaveScroll); + document.addEventListener('pjax:send', doSaveScroll); + } + // Save the position by clicking the icon + link.addEventListener('click', () => { + doSaveScroll(); + window.anime({ + targets : link, + duration: 200, + easing : 'linear', + top : -30, + complete: () => { + setTimeout(() => { + link.style.top = ''; + }, 400); + } + }); + }); + scrollToMark(); + document.addEventListener('pjax:success', scrollToMark); + }; + + init(CONFIG.bookmark.save); +}); diff --git a/js/comments-buttons.js b/js/comments-buttons.js new file mode 100644 index 0000000..505c21b --- /dev/null +++ b/js/comments-buttons.js @@ -0,0 +1,25 @@ +/* global CONFIG */ + +(function() { + const commentButton = document.querySelectorAll('.comment-button'); + commentButton.forEach(element => { + const commentClass = element.classList[2]; + element.addEventListener('click', () => { + commentButton.forEach(active => active.classList.toggle('active', active === element)); + document.querySelectorAll('.comment-position').forEach(active => active.classList.toggle('active', active.classList.contains(commentClass))); + if (CONFIG.comments.storage) { + localStorage.setItem('comments_active', commentClass); + } + }); + }); + let { activeClass } = CONFIG.comments; + if (CONFIG.comments.storage) { + activeClass = localStorage.getItem('comments_active') || activeClass; + } + if (activeClass) { + const activeButton = document.querySelector(`.comment-button.${activeClass}`); + if (activeButton) { + activeButton.click(); + } + } +})(); diff --git a/js/comments.js b/js/comments.js new file mode 100644 index 0000000..4045e8c --- /dev/null +++ b/js/comments.js @@ -0,0 +1,21 @@ +/* global CONFIG */ + +window.addEventListener('tabs:register', () => { + let { activeClass } = CONFIG.comments; + if (CONFIG.comments.storage) { + activeClass = localStorage.getItem('comments_active') || activeClass; + } + if (activeClass) { + const activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`); + if (activeTab) { + activeTab.click(); + } + } +}); +if (CONFIG.comments.storage) { + window.addEventListener('tabs:click', event => { + if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return; + const commentClass = event.target.classList[1]; + localStorage.setItem('comments_active', commentClass); + }); +} diff --git a/js/config.js b/js/config.js new file mode 100644 index 0000000..caa0075 --- /dev/null +++ b/js/config.js @@ -0,0 +1,66 @@ +if (!window.NexT) window.NexT = {}; + +(function() { + const className = 'next-config'; + + const staticConfig = {}; + let variableConfig = {}; + + const parse = text => JSON.parse(text || '{}'); + + const update = name => { + const targetEle = document.querySelector(`.${className}[data-name="${name}"]`); + if (!targetEle) return; + const parsedConfig = parse(targetEle.text); + if (name === 'main') { + Object.assign(staticConfig, parsedConfig); + } else { + variableConfig[name] = parsedConfig; + } + }; + + update('main'); + + window.CONFIG = new Proxy({}, { + get(overrideConfig, name) { + let existing; + if (name in staticConfig) { + existing = staticConfig[name]; + } else { + if (!(name in variableConfig)) update(name); + existing = variableConfig[name]; + } + + // For unset override and mixable existing + if (!(name in overrideConfig) && typeof existing === 'object') { + // Get ready to mix. + overrideConfig[name] = {}; + } + + if (name in overrideConfig) { + const override = overrideConfig[name]; + + // When mixable + if (typeof override === 'object' && typeof existing === 'object') { + // Mix, proxy changes to the override. + return new Proxy({ ...existing, ...override }, { + set(target, prop, value) { + target[prop] = value; + override[prop] = value; + return true; + } + }); + } + + return override; + } + + // Only when not mixable and override hasn't been set. + return existing; + } + }); + + document.addEventListener('pjax:success', () => { + variableConfig = {}; + }); +})(); diff --git a/js/cursor/explosion.min.js b/js/cursor/explosion.min.js new file mode 100644 index 0000000..cb967a5 --- /dev/null +++ b/js/cursor/explosion.min.js @@ -0,0 +1 @@ +"use strict";function updateCoords(e){pointerX=(e.clientX||e.touches[0].clientX)-canvasEl.getBoundingClientRect().left,pointerY=e.clientY||e.touches[0].clientY-canvasEl.getBoundingClientRect().top}function setParticuleDirection(e){var t=anime.random(0,360)*Math.PI/180,a=anime.random(50,180),n=[-1,1][anime.random(0,1)]*a;return{x:e.x+n*Math.cos(t),y:e.y+n*Math.sin(t)}}function createParticule(e,t){var a={};return a.x=e,a.y=t,a.color=colors[anime.random(0,colors.length-1)],a.radius=anime.random(16,32),a.endPos=setParticuleDirection(a),a.draw=function(){ctx.beginPath(),ctx.arc(a.x,a.y,a.radius,0,2*Math.PI,!0),ctx.fillStyle=a.color,ctx.fill()},a}function createCircle(e,t){var a={};return a.x=e,a.y=t,a.color="#F00",a.radius=.1,a.alpha=.5,a.lineWidth=6,a.draw=function(){ctx.globalAlpha=a.alpha,ctx.beginPath(),ctx.arc(a.x,a.y,a.radius,0,2*Math.PI,!0),ctx.lineWidth=a.lineWidth,ctx.strokeStyle=a.color,ctx.stroke(),ctx.globalAlpha=1},a}function renderParticule(e){for(var t=0;t { + if (circle.position.x > this.area.width || circle.position.y > this.area.height) { + return this.circles.splice(index, 1) + } + circle.move() + }) + if (this.circles.length == 0) { + this.stop = true + } + } + + draw() { + this.circles.forEach(circle => circle.draw()) + } +} + +class CursorSpecialEffects { + constructor() { + this.computerCanvas = document.createElement('canvas') + this.renderCanvas = document.createElement('canvas') + + this.computerContext = this.computerCanvas.getContext('2d') + this.renderContext = this.renderCanvas.getContext('2d') + + this.globalWidth = window.innerWidth + this.globalHeight = window.innerHeight + + this.booms = [] + this.running = false + } + + handleMouseDown(e) { + const boom = new Boom({ + origin: { x: e.clientX, y: e.clientY }, + context: this.computerContext, + area: { + width: this.globalWidth, + height: this.globalHeight + } + }) + boom.init() + this.booms.push(boom) + this.running || this.run() + } + + handlePageHide() { + this.booms = [] + this.running = false + } + + init() { + const style = this.renderCanvas.style + style.position = 'fixed' + style.top = style.left = 0 + style.zIndex = '999999999999999999999999999999999999999999' + style.pointerEvents = 'none' + + style.width = this.renderCanvas.width = this.computerCanvas.width = this.globalWidth + style.height = this.renderCanvas.height = this.computerCanvas.height = this.globalHeight + + document.body.append(this.renderCanvas) + + window.addEventListener('mousedown', this.handleMouseDown.bind(this)) + window.addEventListener('pagehide', this.handlePageHide.bind(this)) + } + + run() { + this.running = true + if (this.booms.length == 0) { + return this.running = false + } + + requestAnimationFrame(this.run.bind(this)) + + this.computerContext.clearRect(0, 0, this.globalWidth, this.globalHeight) + this.renderContext.clearRect(0, 0, this.globalWidth, this.globalHeight) + + this.booms.forEach((boom, index) => { + if (boom.stop) { + return this.booms.splice(index, 1) + } + boom.move() + boom.draw() + }) + this.renderContext.drawImage(this.computerCanvas, 0, 0, this.globalWidth, this.globalHeight) + } +} + +const cursorSpecialEffects = new CursorSpecialEffects() +cursorSpecialEffects.init() diff --git a/js/cursor/love.min.js b/js/cursor/love.min.js new file mode 100644 index 0000000..cdf22df --- /dev/null +++ b/js/cursor/love.min.js @@ -0,0 +1 @@ +!function(e,t,a){function n(){c(".heart{width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: fixed;}.heart:after{top: -5px;}.heart:before{left: -5px;}"),o(),r()}function r(){for(var e=0;e").text(a[a_idx]); + var x = e.pageX, + y = e.pageY; + $i.css({ + "z-index": 99999, + "top": y - 28, + "left": x - a[a_idx].length * 8, + "position": "absolute", + "color": "#ff7a45" + }); + $("body").append($i); + $i.animate({ + "top": y - 180, + "opacity": 0 + }, 1500, function() { + $i.remove(); + }); + a_idx = (a_idx + 1) % a.length; + }); +}); diff --git a/js/link.js b/js/link.js new file mode 100644 index 0000000..4641df0 --- /dev/null +++ b/js/link.js @@ -0,0 +1,26 @@ +// 随机排列 +function shuffle(arr) { + let i = arr.length; + while (i) { + let j = Math.floor(Math.random() * i--); + [arr[j], arr[i]] = [arr[i], arr[j]]; + } +} + +// 渲染数据 +function renderlink(data) { + var name, avatar, site, li = ""; + shuffle(data); + for (var i = 0; i < data.length; i++) { + name = data[i].name; + avatar = data[i].avatar; + site = data[i].site; + li += '
' + '' + '
' + '
' + '
' + '
' + '' + '
' + '
'; + } + document.querySelector(".link-navigation").innerHTML = li; +} + +// 获取 json 文件 +fetch('/links/linklist.json') + .then(response => response.json()) + .then(res => renderlink(res)); diff --git a/js/motion.js b/js/motion.js new file mode 100644 index 0000000..aad22db --- /dev/null +++ b/js/motion.js @@ -0,0 +1,140 @@ +/* global NexT, CONFIG */ + +NexT.motion = {}; + +NexT.motion.integrator = { + queue: [], + init : function() { + this.queue = []; + return this; + }, + add: function(fn) { + const sequence = fn(); + if (CONFIG.motion.async) this.queue.push(sequence); + else this.queue = this.queue.concat(sequence); + return this; + }, + bootstrap: function() { + if (!CONFIG.motion.async) this.queue = [this.queue]; + this.queue.forEach(sequence => { + const timeline = window.anime.timeline({ + duration: 200, + easing : 'linear' + }); + sequence.forEach(item => { + if (item.deltaT) timeline.add(item, item.deltaT); + else timeline.add(item); + }); + }); + } +}; + +NexT.motion.middleWares = { + header: function() { + const sequence = []; + + function getMistLineSettings(targets) { + sequence.push({ + targets, + scaleX : [0, 1], + duration: 500, + deltaT : '-=200' + }); + } + + function pushToSequence(targets, sequenceQueue = false) { + sequence.push({ + targets, + opacity: 1, + top : 0, + deltaT : sequenceQueue ? '-=200' : '-=0' + }); + } + + pushToSequence('.column'); + CONFIG.scheme === 'Mist' && getMistLineSettings('.logo-line'); + CONFIG.scheme === 'Muse' && pushToSequence('.custom-logo-image'); + pushToSequence('.site-title'); + pushToSequence('.site-brand-container .toggle', true); + pushToSequence('.site-subtitle'); + (CONFIG.scheme === 'Pisces' || CONFIG.scheme === 'Gemini') && pushToSequence('.custom-logo-image'); + + const menuItemTransition = CONFIG.motion.transition.menu_item; + if (menuItemTransition) { + document.querySelectorAll('.menu-item').forEach(targets => { + sequence.push({ + targets, + complete: () => targets.classList.add('animated', menuItemTransition), + deltaT : '-=200' + }); + }); + } + + return sequence; + }, + + subMenu: function() { + const subMenuItem = document.querySelectorAll('.sub-menu .menu-item'); + if (subMenuItem.length > 0) { + subMenuItem.forEach(element => { + element.classList.add('animated'); + }); + } + return []; + }, + + postList: function() { + const sequence = []; + const { post_block, post_header, post_body, coll_header } = CONFIG.motion.transition; + + function animate(animation, elements) { + if (!animation) return; + elements.forEach(targets => { + sequence.push({ + targets, + complete: () => targets.classList.add('animated', animation), + deltaT : '-=100' + }); + }); + } + + document.querySelectorAll('.post-block').forEach(targets => { + sequence.push({ + targets, + complete: () => targets.classList.add('animated', post_block), + deltaT : '-=100' + }); + animate(coll_header, targets.querySelectorAll('.collection-header')); + animate(post_header, targets.querySelectorAll('.post-header')); + animate(post_body, targets.querySelectorAll('.post-body')); + }); + + animate(post_block, document.querySelectorAll('.pagination, .comments')); + + return sequence; + }, + + sidebar: function() { + const sequence = []; + const sidebar = document.querySelectorAll('.sidebar-inner'); + const sidebarTransition = CONFIG.motion.transition.sidebar; + // Only for Pisces | Gemini. + if (sidebarTransition && (CONFIG.scheme === 'Pisces' || CONFIG.scheme === 'Gemini')) { + sidebar.forEach(targets => { + sequence.push({ + targets, + complete: () => targets.classList.add('animated', sidebarTransition), + deltaT : '-=100' + }); + }); + } + return sequence; + }, + + footer: function() { + return [{ + targets: document.querySelector('.footer'), + opacity: 1 + }]; + } +}; diff --git a/js/next-boot.js b/js/next-boot.js new file mode 100644 index 0000000..1225fd2 --- /dev/null +++ b/js/next-boot.js @@ -0,0 +1,75 @@ +/* global NexT, CONFIG */ + +NexT.boot = {}; + +NexT.boot.registerEvents = function() { + + NexT.utils.registerScrollPercent(); + NexT.utils.registerCanIUseTag(); + + // Mobile top menu bar. + document.querySelector('.site-nav-toggle .toggle').addEventListener('click', event => { + event.currentTarget.classList.toggle('toggle-close'); + const siteNav = document.querySelector('.site-nav'); + if (!siteNav) return; + siteNav.style.setProperty('--scroll-height', siteNav.scrollHeight + 'px'); + document.body.classList.toggle('site-nav-on'); + }); + + document.querySelectorAll('.sidebar-nav li').forEach((element, index) => { + element.addEventListener('click', () => { + NexT.utils.activateSidebarPanel(index); + }); + }); + + window.addEventListener('hashchange', () => { + const tHash = location.hash; + if (tHash !== '' && !tHash.match(/%\S{2}/)) { + const target = document.querySelector(`.tabs ul.nav-tabs li a[href="${tHash}"]`); + target && target.click(); + } + }); +}; + +NexT.boot.refresh = function() { + + /** + * Register JS handlers by condition option. + * Need to add config option in Front-End at 'scripts/helpers/next-config.js' file. + */ + CONFIG.prism && window.Prism.highlightAll(); + CONFIG.mediumzoom && window.mediumZoom('.post-body :not(a) > img, .post-body > img', { + background: 'var(--content-bg-color)' + }); + CONFIG.lazyload && window.lozad('.post-body img').observe(); + CONFIG.pangu && window.pangu.spacingPage(); + + CONFIG.exturl && NexT.utils.registerExtURL(); + NexT.utils.wrapTableWithBox(); + NexT.utils.registerCopyCode(); + NexT.utils.registerTabsTag(); + NexT.utils.registerActiveMenuItem(); + NexT.utils.registerLangSelect(); + NexT.utils.registerSidebarTOC(); + NexT.utils.registerPostReward(); + NexT.utils.registerVideoIframe(); +}; + +NexT.boot.motion = function() { + // Define Motion Sequence & Bootstrap Motion. + if (CONFIG.motion.enable) { + NexT.motion.integrator + .add(NexT.motion.middleWares.header) + .add(NexT.motion.middleWares.postList) + .add(NexT.motion.middleWares.sidebar) + .add(NexT.motion.middleWares.footer) + .bootstrap(); + } + NexT.utils.updateSidebarPosition(); +}; + +document.addEventListener('DOMContentLoaded', () => { + NexT.boot.registerEvents(); + NexT.boot.refresh(); + NexT.boot.motion(); +}); diff --git a/js/pjax.js b/js/pjax.js new file mode 100644 index 0000000..f81a6a0 --- /dev/null +++ b/js/pjax.js @@ -0,0 +1,50 @@ +/* global NexT, CONFIG, Pjax */ + +const pjax = new Pjax({ + selectors: [ + 'head title', + 'script[type="application/json"]', + // Precede .main-inner to prevent placeholder TOC changes asap + '.post-toc-wrap', + '.main-inner', + '.languages', + '.pjax' + ], + switches: { + '.post-toc-wrap': function(oldWrap, newWrap) { + if (newWrap.querySelector('.post-toc')) { + Pjax.switches.outerHTML.call(this, oldWrap, newWrap); + } else { + const curTOC = oldWrap.querySelector('.post-toc'); + if (curTOC) { + curTOC.classList.add('placeholder-toc'); + } + this.onSwitch(); + } + } + }, + analytics: false, + cacheBust: false, + scrollTo : !CONFIG.bookmark.enable +}); + +document.addEventListener('pjax:success', () => { + pjax.executeScripts(document.querySelectorAll('script[data-pjax]')); + NexT.boot.refresh(); + // Define Motion Sequence & Bootstrap Motion. + if (CONFIG.motion.enable) { + NexT.motion.integrator + .init() + .add(NexT.motion.middleWares.subMenu) + .add(NexT.motion.middleWares.postList) + // Add sidebar-post-related transition. + .add(NexT.motion.middleWares.sidebar) + .bootstrap(); + } + if (CONFIG.sidebar.display !== 'remove') { + const hasTOC = document.querySelector('.post-toc:not(.placeholder-toc)'); + document.querySelector('.sidebar-inner').classList.toggle('sidebar-nav-active', hasTOC); + NexT.utils.activateSidebarPanel(hasTOC ? 0 : 1); + NexT.utils.updateSidebarPosition(); + } +}); diff --git a/js/schedule.js b/js/schedule.js new file mode 100644 index 0000000..8f0c26c --- /dev/null +++ b/js/schedule.js @@ -0,0 +1,138 @@ +/* global CONFIG */ + +// https://developers.google.com/calendar/api/v3/reference/events/list +(function() { + // Initialization + const calendar = { + orderBy : 'startTime', + showLocation: false, + offsetMax : 72, + offsetMin : 4, + showDeleted : false, + singleEvents: true, + maxResults : 250 + }; + + // Read config form theme config file + Object.assign(calendar, CONFIG.calendar); + + const now = new Date(); + const timeMax = new Date(); + const timeMin = new Date(); + + timeMax.setHours(now.getHours() + calendar.offsetMax); + timeMin.setHours(now.getHours() - calendar.offsetMin); + + // Build URL + const params = { + key : calendar.api_key, + orderBy : calendar.orderBy, + timeMax : timeMax.toISOString(), + timeMin : timeMin.toISOString(), + showDeleted : calendar.showDeleted, + singleEvents: calendar.singleEvents, + maxResults : calendar.maxResults + }; + + const request_url = new URL(`https://www.googleapis.com/calendar/v3/calendars/${calendar.calendar_id}/events`); + Object.entries(params).forEach(param => request_url.searchParams.append(...param)); + + function getRelativeTime(current, previous) { + const msPerMinute = 60 * 1000; + const msPerHour = msPerMinute * 60; + const msPerDay = msPerHour * 24; + const msPerMonth = msPerDay * 30; + const msPerYear = msPerDay * 365; + + let elapsed = current - previous; + const tense = elapsed > 0 ? ' ago' : ' later'; + + elapsed = Math.abs(elapsed); + + if (elapsed < msPerHour) { + return Math.round(elapsed / msPerMinute) + ' minutes' + tense; + } else if (elapsed < msPerDay) { + return Math.round(elapsed / msPerHour) + ' hours' + tense; + } else if (elapsed < msPerMonth) { + return 'about ' + Math.round(elapsed / msPerDay) + ' days' + tense; + } else if (elapsed < msPerYear) { + return 'about ' + Math.round(elapsed / msPerMonth) + ' months' + tense; + } + + return 'about ' + Math.round(elapsed / msPerYear) + ' years' + tense; + } + + function buildEventDOM(tense, event, start, end) { + const durationFormat = { + weekday: 'short', + hour : '2-digit', + minute : '2-digit' + }; + const relativeTime = tense === 'now' ? 'NOW' : getRelativeTime(now, start); + const duration = start.toLocaleTimeString([], durationFormat) + ' - ' + end.toLocaleTimeString([], durationFormat); + + let location = ''; + if (calendar.showLocation && event.location) { + location = `${event.location}`; + } + let description = ''; + if (event.description) { + description = `${event.description}`; + } + + const eventContent = `
+

+ ${event.summary} + ${relativeTime} +

+ ${location} + ${duration} + ${description} +
`; + return eventContent; + } + + function fetchData() { + const eventList = document.querySelector('.event-list'); + if (!eventList) return; + + fetch(request_url.href).then(response => { + return response.json(); + }).then(data => { + if (data.items.length === 0) { + eventList.innerHTML = '
'; + return; + } + // Clean the event list + eventList.innerHTML = ''; + let prevEnd = 0; // used to decide where to insert an
+ const utc = new Date().getTimezoneOffset() * 60000; + + data.items.forEach(event => { + // Parse data + const start = new Date(event.start.dateTime || (new Date(event.start.date).getTime() + utc)); + const end = new Date(event.end.dateTime || (new Date(event.end.date).getTime() + utc)); + + let tense = 'now'; + if (end < now) { + tense = 'past'; + } else if (start > now) { + tense = 'future'; + } + + if (tense === 'future' && prevEnd < now) { + eventList.insertAdjacentHTML('beforeend', '
'); + } + + eventList.insertAdjacentHTML('beforeend', buildEventDOM(tense, event, start, end)); + prevEnd = end; + }); + }); + } + + fetchData(); + const fetchDataTimer = setInterval(fetchData, 60000); + document.addEventListener('pjax:send', () => { + clearInterval(fetchDataTimer); + }); +})(); diff --git a/js/schemes/muse.js b/js/schemes/muse.js new file mode 100644 index 0000000..ba60b51 --- /dev/null +++ b/js/schemes/muse.js @@ -0,0 +1,60 @@ +/* global CONFIG */ + +document.addEventListener('DOMContentLoaded', () => { + + const isRight = CONFIG.sidebar.position === 'right'; + + const sidebarToggleMotion = { + mouse: {}, + init : function() { + window.addEventListener('mousedown', this.mousedownHandler.bind(this)); + window.addEventListener('mouseup', this.mouseupHandler.bind(this)); + document.querySelector('.sidebar-dimmer').addEventListener('click', this.clickHandler.bind(this)); + document.querySelector('.sidebar-toggle').addEventListener('click', this.clickHandler.bind(this)); + window.addEventListener('sidebar:show', this.showSidebar); + window.addEventListener('sidebar:hide', this.hideSidebar); + }, + mousedownHandler: function(event) { + this.mouse.X = event.pageX; + this.mouse.Y = event.pageY; + }, + mouseupHandler: function(event) { + const deltaX = event.pageX - this.mouse.X; + const deltaY = event.pageY - this.mouse.Y; + const clickingBlankPart = Math.hypot(deltaX, deltaY) < 20 && event.target.matches('.main'); + // Fancybox has z-index property, but medium-zoom does not, so the sidebar will overlay the zoomed image. + if (clickingBlankPart || event.target.matches('img.medium-zoom-image')) { + this.hideSidebar(); + } + }, + clickHandler: function() { + document.body.classList.contains('sidebar-active') ? this.hideSidebar() : this.showSidebar(); + }, + showSidebar: function() { + document.body.classList.add('sidebar-active'); + const animateAction = isRight ? 'fadeInRight' : 'fadeInLeft'; + document.querySelectorAll('.sidebar .animated').forEach((element, index) => { + element.style.animationDelay = (100 * index) + 'ms'; + element.classList.remove(animateAction); + setTimeout(() => { + // Trigger a DOM reflow + element.classList.add(animateAction); + }); + }); + }, + hideSidebar: function() { + document.body.classList.remove('sidebar-active'); + } + }; + if (CONFIG.sidebar.display !== 'remove') sidebarToggleMotion.init(); + + function updateFooterPosition() { + const footer = document.querySelector('.footer'); + const containerHeight = document.querySelector('.main').offsetHeight + footer.offsetHeight; + footer.classList.toggle('footer-fixed', containerHeight <= window.innerHeight); + } + + updateFooterPosition(); + window.addEventListener('resize', updateFooterPosition); + window.addEventListener('scroll', updateFooterPosition, { passive: true }); +}); diff --git a/js/tagcanvas.js b/js/tagcanvas.js new file mode 100644 index 0000000..80866a2 --- /dev/null +++ b/js/tagcanvas.js @@ -0,0 +1,2243 @@ +/** + * Copyright (C) 2010-2015 Graham Breach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +/** + * TagCanvas 2.9 + * For more information, please contact + */ +(function(){ +"use strict"; +var i, j, abs = Math.abs, sin = Math.sin, cos = Math.cos, max = Math.max, + min = Math.min, ceil = Math.ceil, sqrt = Math.sqrt, pow = Math.pow, + hexlookup3 = {}, hexlookup2 = {}, hexlookup1 = { + 0:"0,", 1:"17,", 2:"34,", 3:"51,", 4:"68,", 5:"85,", + 6:"102,", 7:"119,", 8:"136,", 9:"153,", a:"170,", A:"170,", + b:"187,", B:"187,", c:"204,", C:"204,", d:"221,", D:"221,", + e:"238,", E:"238,", f:"255,", F:"255," + }, Oproto, Tproto, TCproto, Mproto, Vproto, TSproto, TCVproto, + doc = document, ocanvas, handlers = {}; +for(i = 0; i < 256; ++i) { + j = i.toString(16); + if(i < 16) + j = '0' + j; + hexlookup2[j] = hexlookup2[j.toUpperCase()] = i.toString() + ','; +} +function Defined(d) { + return typeof d != 'undefined'; +} +function IsObject(o) { + return typeof o == 'object' && o != null; +} +function Clamp(v, mn, mx) { + return isNaN(v) ? mx : min(mx, max(mn, v)); +} +function Nop() { + return false; +} +function TimeNow() { + return new Date().valueOf(); +} +function SortList(l, f) { + var nl = [], tl = l.length, i; + for(i = 0; i < tl; ++i) + nl.push(l[i]); + nl.sort(f); + return nl; +} +function Shuffle(a) { + var i = a.length-1, t, p; + while(i) { + p = ~~(Math.random()*i); + t = a[i]; + a[i] = a[p]; + a[p] = t; + --i; + } +} +function Vector(x, y, z) { + this.x = x; + this.y = y; + this.z = z; +} +Vproto = Vector.prototype; +Vproto.length = function() { + return sqrt(this.x * this.x + this.y * this.y + this.z * this.z); +}; +Vproto.dot = function(v) { + return this.x * v.x + this.y * v.y + this.z * v.z; +}; +Vproto.cross = function(v) { + var x = this.y * v.z - this.z * v.y, + y = this.z * v.x - this.x * v.z, + z = this.x * v.y - this.y * v.x; + return new Vector(x, y, z); +}; +Vproto.angle = function(v) { + var dot = this.dot(v), ac; + if(dot == 0) + return Math.PI / 2.0; + ac = dot / (this.length() * v.length()); + if(ac >= 1) + return 0; + if(ac <= -1) + return Math.PI; + return Math.acos(ac); +}; +Vproto.unit = function() { + var l = this.length(); + return new Vector(this.x / l, this.y / l, this.z / l); +}; +function MakeVector(lg, lt) { + lt = lt * Math.PI / 180; + lg = lg * Math.PI / 180; + var x = sin(lg) * cos(lt), y = -sin(lt), z = -cos(lg) * cos(lt); + return new Vector(x, y, z); +} +function Matrix(a) { + this[1] = {1: a[0], 2: a[1], 3: a[2]}; + this[2] = {1: a[3], 2: a[4], 3: a[5]}; + this[3] = {1: a[6], 2: a[7], 3: a[8]}; +} +Mproto = Matrix.prototype; +Matrix.Identity = function() { + return new Matrix([1,0,0, 0,1,0, 0,0,1]); +}; +Matrix.Rotation = function(angle, u) { + var sina = sin(angle), cosa = cos(angle), mcos = 1 - cosa; + return new Matrix([ + cosa + pow(u.x, 2) * mcos, u.x * u.y * mcos - u.z * sina, u.x * u.z * mcos + u.y * sina, + u.y * u.x * mcos + u.z * sina, cosa + pow(u.y, 2) * mcos, u.y * u.z * mcos - u.x * sina, + u.z * u.x * mcos - u.y * sina, u.z * u.y * mcos + u.x * sina, cosa + pow(u.z, 2) * mcos + ]); +} +Mproto.mul = function(m) { + var a = [], i, j, mmatrix = (m.xform ? 1 : 0); + for(i = 1; i <= 3; ++i) + for(j = 1; j <= 3; ++j) { + if(mmatrix) + a.push(this[i][1] * m[1][j] + + this[i][2] * m[2][j] + + this[i][3] * m[3][j]); + else + a.push(this[i][j] * m); + } + return new Matrix(a); +}; +Mproto.xform = function(p) { + var a = {}, x = p.x, y = p.y, z = p.z; + a.x = x * this[1][1] + y * this[2][1] + z * this[3][1]; + a.y = x * this[1][2] + y * this[2][2] + z * this[3][2]; + a.z = x * this[1][3] + y * this[2][3] + z * this[3][3]; + return a; +}; +function PointsOnSphere(n,xr,yr,zr,magic) { + var i, y, r, phi, pts = [], off = 2/n, inc; + inc = Math.PI * (3 - sqrt(5) + (parseFloat(magic) ? parseFloat(magic) : 0)); + for(i = 0; i < n; ++i) { + y = i * off - 1 + (off / 2); + r = sqrt(1 - y*y); + phi = i * inc; + pts.push([cos(phi) * r * xr, y * yr, sin(phi) * r * zr]); + } + return pts; +} +function Cylinder(n,o,xr,yr,zr,magic) { + var phi, pts = [], off = 2/n, inc, i, j, k, l; + inc = Math.PI * (3 - sqrt(5) + (parseFloat(magic) ? parseFloat(magic) : 0)); + for(i = 0; i < n; ++i) { + j = i * off - 1 + (off / 2); + phi = i * inc; + k = cos(phi); + l = sin(phi); + pts.push(o ? [j * xr, k * yr, l * zr] : [k * xr, j * yr, l * zr]); + } + return pts; +} +function Ring(o, n, xr, yr, zr, j) { + var phi, pts = [], inc = Math.PI * 2 / n, i, k, l; + for(i = 0; i < n; ++i) { + phi = i * inc; + k = cos(phi); + l = sin(phi); + pts.push(o ? [j * xr, k * yr, l * zr] : [k * xr, j * yr, l * zr]); + } + return pts; +} +function PointsOnCylinderV(n,xr,yr,zr,m) { return Cylinder(n, 0, xr, yr, zr, m) } +function PointsOnCylinderH(n,xr,yr,zr,m) { return Cylinder(n, 1, xr, yr, zr, m) } +function PointsOnRingV(n, xr, yr, zr, offset) { + offset = isNaN(offset) ? 0 : offset * 1; + return Ring(0, n, xr, yr, zr, offset); +} +function PointsOnRingH(n, xr, yr, zr, offset) { + offset = isNaN(offset) ? 0 : offset * 1; + return Ring(1, n, xr, yr, zr, offset); +} +function CentreImage(t) { + var i = new Image; + i.onload = function() { + var dx = i.width / 2, dy = i.height / 2; + t.centreFunc = function(c, w, h, cx, cy) { + c.setTransform(1, 0, 0, 1, 0, 0); + c.globalAlpha = 1; + c.drawImage(i, cx - dx, cy - dy); + }; + }; + i.src = t.centreImage; +} +function SetAlpha(c,a) { + var d = c, p1, p2, ae = (a*1).toPrecision(3) + ')'; + if(c[0] === '#') { + if(!hexlookup3[c]) + if(c.length === 4) + hexlookup3[c] = 'rgba(' + hexlookup1[c[1]] + hexlookup1[c[2]] + hexlookup1[c[3]]; + else + hexlookup3[c] = 'rgba(' + hexlookup2[c.substr(1,2)] + hexlookup2[c.substr(3,2)] + hexlookup2[c.substr(5,2)]; + d = hexlookup3[c] + ae; + } else if(c.substr(0,4) === 'rgb(' || c.substr(0,4) === 'hsl(') { + d = (c.replace('(','a(').replace(')', ',' + ae)); + } else if(c.substr(0,5) === 'rgba(' || c.substr(0,5) === 'hsla(') { + p1 = c.lastIndexOf(',') + 1, p2 = c.indexOf(')'); + a *= parseFloat(c.substring(p1,p2)); + d = c.substr(0,p1) + a.toPrecision(3) + ')'; + } + return d; +} +function NewCanvas(w,h) { + // if using excanvas, give up now + if(window.G_vmlCanvasManager) + return null; + var c = doc.createElement('canvas'); + c.width = w; + c.height = h; + return c; +} +// I think all browsers pass this test now... +function ShadowAlphaBroken() { + var cv = NewCanvas(3,3), c, i; + if(!cv) + return false; + c = cv.getContext('2d'); + c.strokeStyle = '#000'; + c.shadowColor = '#fff'; + c.shadowBlur = 3; + c.globalAlpha = 0; + c.strokeRect(2,2,2,2); + c.globalAlpha = 1; + i = c.getImageData(2,2,1,1); + cv = null; + return (i.data[0] > 0); +} +function SetGradient(c, l, o, g) { + var gd = c.createLinearGradient(0, 0, l, 0), i; + for(i in g) + gd.addColorStop(1 - i, g[i]); + c.fillStyle = gd; + c.fillRect(0, o, l, 1); +} +function FindGradientColour(tc, p, r) { + var l = 1024, h = 1, gl = tc.weightGradient, cv, c, i, d; + if(tc.gCanvas) { + c = tc.gCanvas.getContext('2d'); + h = tc.gCanvas.height; + } else { + if(IsObject(gl[0])) + h = gl.length; + else + gl = [gl]; + tc.gCanvas = cv = NewCanvas(l, h); + if(!cv) + return null; + c = cv.getContext('2d'); + for(i = 0; i < h; ++i) + SetGradient(c, l, i, gl[i]); + } + r = max(min(r || 0, h - 1), 0); + d = c.getImageData(~~((l - 1) * p), r, 1, 1).data; + return 'rgba(' + d[0] + ',' + d[1] + ',' + d[2] + ',' + (d[3]/255) + ')'; +} +function TextSet(ctxt, font, colour, strings, padx, pady, shadowColour, + shadowBlur, shadowOffsets, maxWidth, widths, align) { + var xo = padx + (shadowBlur || 0) + + (shadowOffsets.length && shadowOffsets[0] < 0 ? abs(shadowOffsets[0]) : 0), + yo = pady + (shadowBlur || 0) + + (shadowOffsets.length && shadowOffsets[1] < 0 ? abs(shadowOffsets[1]) : 0), i, xc; + ctxt.font = font; + ctxt.textBaseline = 'top'; + ctxt.fillStyle = colour; + shadowColour && (ctxt.shadowColor = shadowColour); + shadowBlur && (ctxt.shadowBlur = shadowBlur); + shadowOffsets.length && (ctxt.shadowOffsetX = shadowOffsets[0], + ctxt.shadowOffsetY = shadowOffsets[1]); + for(i = 0; i < strings.length; ++i) { + xc = 0; + if(widths) { + if('right' == align) { + xc = maxWidth - widths[i]; + } else if('centre' == align) { + xc = (maxWidth - widths[i]) / 2; + } + } + ctxt.fillText(strings[i], xo + xc, yo); + yo += parseInt(font); + } +} +function RRect(c, x, y, w, h, r, s) { + if(r) { + c.beginPath(); + c.moveTo(x, y + h - r); + c.arcTo(x, y, x + r, y, r); + c.arcTo(x + w, y, x + w, y + r, r); + c.arcTo(x + w, y + h, x + w - r, y + h, r); + c.arcTo(x, y + h, x, y + h - r, r); + c.closePath(); + c[s ? 'stroke' : 'fill'](); + } else { + c[s ? 'strokeRect' : 'fillRect'](x, y, w, h); + } +} +function TextCanvas(strings, font, w, h, maxWidth, stringWidths, align, valign, + scale) { + this.strings = strings; + this.font = font; + this.width = w; + this.height = h; + this.maxWidth = maxWidth; + this.stringWidths = stringWidths; + this.align = align; + this.valign = valign; + this.scale = scale; +} +TCVproto = TextCanvas.prototype; +TCVproto.SetImage = function(image, w, h, position, padding, align, valign, + scale) { + this.image = image; + this.iwidth = w * this.scale; + this.iheight = h * this.scale; + this.ipos = position; + this.ipad = padding * this.scale; + this.iscale = scale; + this.ialign = align; + this.ivalign = valign; +}; +TCVproto.Align = function(size, space, a) { + var pos = 0; + if(a == 'right' || a == 'bottom') + pos = space - size; + else if(a != 'left' && a != 'top') + pos = (space - size) / 2; + return pos; +}; +TCVproto.Create = function(colour, bgColour, bgOutline, bgOutlineThickness, + shadowColour, shadowBlur, shadowOffsets, padding, radius) { + var cv, cw, ch, c, x1, x2, y1, y2, offx, offy, ix, iy, iw, ih, rr, + sox = abs(shadowOffsets[0]), soy = abs(shadowOffsets[1]), shadowcv, shadowc; + padding = max(padding, sox + shadowBlur, soy + shadowBlur); + x1 = 2 * (padding + bgOutlineThickness); + y1 = 2 * (padding + bgOutlineThickness); + cw = this.width + x1; + ch = this.height + y1; + offx = offy = padding + bgOutlineThickness; + + if(this.image) { + ix = iy = padding + bgOutlineThickness; + iw = this.iwidth; + ih = this.iheight; + if(this.ipos == 'top' || this.ipos == 'bottom') { + if(iw < this.width) + ix += this.Align(iw, this.width, this.ialign); + else + offx += this.Align(this.width, iw, this.align); + if(this.ipos == 'top') + offy += ih + this.ipad; + else + iy += this.height + this.ipad; + cw = max(cw, iw + x1); + ch += ih + this.ipad; + } else { + if(ih < this.height) + iy += this.Align(ih, this.height, this.ivalign); + else + offy += this.Align(this.height, ih, this.valign); + if(this.ipos == 'right') + ix += this.width + this.ipad; + else + offx += iw + this.ipad; + cw += iw + this.ipad; + ch = max(ch, ih + y1); + } + } + + cv = NewCanvas(cw, ch); + if(!cv) + return null; + x1 = y1 = bgOutlineThickness / 2; + x2 = cw - bgOutlineThickness; + y2 = ch - bgOutlineThickness; + rr = min(radius, x2 / 2, y2 / 2); + c = cv.getContext('2d'); + if(bgColour) { + c.fillStyle = bgColour; + RRect(c, x1, y1, x2, y2, rr); + } + if(bgOutlineThickness) { + c.strokeStyle = bgOutline; + c.lineWidth = bgOutlineThickness; + RRect(c, x1, y1, x2, y2, rr, true); + } + if(shadowBlur || sox || soy) { + // use a transparent canvas to draw on + shadowcv = NewCanvas(cw, ch); + if(shadowcv) { + shadowc = c; + c = shadowcv.getContext('2d'); + } + } + + // don't use TextSet shadow support because it adds space for shadow + TextSet(c, this.font, colour, this.strings, offx, offy, 0, 0, [], + this.maxWidth, this.stringWidths, this.align); + + if(this.image) + c.drawImage(this.image, ix, iy, iw, ih); + + if(shadowc) { + // draw the text and image with the added shadow + c = shadowc; + shadowColour && (c.shadowColor = shadowColour); + shadowBlur && (c.shadowBlur = shadowBlur); + c.shadowOffsetX = shadowOffsets[0]; + c.shadowOffsetY = shadowOffsets[1]; + c.drawImage(shadowcv, 0, 0); + } + return cv; +}; +function ExpandImage(i, w, h) { + var cv = NewCanvas(w, h), c; + if(!cv) + return null; + c = cv.getContext('2d'); + c.drawImage(i, (w - i.width) / 2, (h - i.height) / 2); + return cv; +} +function ScaleImage(i, w, h) { + var cv = NewCanvas(w, h), c; + if(!cv) + return null; + c = cv.getContext('2d'); + c.drawImage(i, 0, 0, w, h); + return cv; +} +function AddBackgroundToImage(i, w, h, scale, colour, othickness, ocolour, + padding, radius, ofill) { + var cw = w + ((2 * padding) + othickness) * scale, + ch = h + ((2 * padding) + othickness) * scale, + cv = NewCanvas(cw, ch), c, x1, y1, x2, y2, ocanvas, cc, rr; + if(!cv) + return null; + othickness *= scale; + radius *= scale; + x1 = y1 = othickness / 2; + x2 = cw - othickness; + y2 = ch - othickness; + padding = (padding * scale) + x1; // add space for outline + c = cv.getContext('2d'); + rr = min(radius, x2 / 2, y2 / 2); + if(colour) { + c.fillStyle = colour; + RRect(c, x1, y1, x2, y2, rr); + } + if(othickness) { + c.strokeStyle = ocolour; + c.lineWidth = othickness; + RRect(c, x1, y1, x2, y2, rr, true); + } + + if(ofill) { + // use compositing to colour in the image and border + ocanvas = NewCanvas(cw, ch); + cc = ocanvas.getContext('2d'); + cc.drawImage(i, padding, padding, w, h); + cc.globalCompositeOperation = 'source-in'; + cc.fillStyle = ocolour; + cc.fillRect(0, 0, cw, ch); + cc.globalCompositeOperation = 'destination-over'; + cc.drawImage(cv, 0, 0); + cc.globalCompositeOperation = 'source-over'; + c.drawImage(ocanvas, 0, 0); + } else { + c.drawImage(i, padding, padding, i.width, i.height); + } + return {image: cv, width: cw / scale, height: ch / scale}; +} +/** + * Rounds off the corners of an image + */ +function RoundImage(i, r, iw, ih, s) { + var cv, c, r1 = parseFloat(r), l = max(iw, ih); + cv = NewCanvas(iw, ih); + if(!cv) + return null; + if(r.indexOf('%') > 0) + r1 = l * r1 / 100; + else + r1 = r1 * s; + c = cv.getContext('2d'); + c.globalCompositeOperation = 'source-over'; + c.fillStyle = '#fff'; + if(r1 >= l/2) { + r1 = min(iw,ih) / 2; + c.beginPath(); + c.moveTo(iw/2,ih/2); + c.arc(iw/2,ih/2,r1,0,2*Math.PI,false); + c.fill(); + c.closePath(); + } else { + r1 = min(iw/2,ih/2,r1); + RRect(c, 0, 0, iw, ih, r1, true); + c.fill(); + } + c.globalCompositeOperation = 'source-in'; + c.drawImage(i, 0, 0, iw, ih); + return cv; +} +/** + * Creates a new canvas containing the image and its shadow + * Returns an object containing the image and its dimensions at z=0 + */ +function AddShadowToImage(i, w, h, scale, sc, sb, so) { + var sw = abs(so[0]), sh = abs(so[1]), + cw = w + (sw > sb ? sw + sb : sb * 2) * scale, + ch = h + (sh > sb ? sh + sb : sb * 2) * scale, + xo = scale * ((sb || 0) + (so[0] < 0 ? sw : 0)), + yo = scale * ((sb || 0) + (so[1] < 0 ? sh : 0)), cv, c; + cv = NewCanvas(cw, ch); + if(!cv) + return null; + c = cv.getContext('2d'); + sc && (c.shadowColor = sc); + sb && (c.shadowBlur = sb * scale); + so && (c.shadowOffsetX = so[0] * scale, c.shadowOffsetY = so[1] * scale); + c.drawImage(i, xo, yo, w, h); + return {image: cv, width: cw / scale, height: ch / scale}; +} +function FindTextBoundingBox(s,f,ht) { + var w = parseInt(s.toString().length * ht), h = parseInt(ht * 2 * s.length), + cv = NewCanvas(w,h), c, idata, w1, h1, x, y, i, ex; + if(!cv) + return null; + c = cv.getContext('2d'); + c.fillStyle = '#000'; + c.fillRect(0,0,w,h); + TextSet(c,ht + 'px ' + f,'#fff',s,0,0,0,0,[],'centre') + + idata = c.getImageData(0,0,w,h); + w1 = idata.width; h1 = idata.height; + ex = { + min: { x: w1, y: h1 }, + max: { x: -1, y: -1 } + }; + for(y = 0; y < h1; ++y) { + for(x = 0; x < w1; ++x) { + i = (y * w1 + x) * 4; + if(idata.data[i+1] > 0) { + if(x < ex.min.x) ex.min.x = x; + if(x > ex.max.x) ex.max.x = x; + if(y < ex.min.y) ex.min.y = y; + if(y > ex.max.y) ex.max.y = y; + } + } + } + // device pixels might not be css pixels + if(w1 != w) { + ex.min.x *= (w / w1); + ex.max.x *= (w / w1); + } + if(h1 != h) { + ex.min.y *= (w / h1); + ex.max.y *= (w / h1); + } + + cv = null; + return ex; +} +function FixFont(f) { + return "'" + f.replace(/(\'|\")/g,'').replace(/\s*,\s*/g, "', '") + "'"; +} +function AddHandler(h,f,e) { + e = e || doc; + if(e.addEventListener) + e.addEventListener(h,f,false); + else + e.attachEvent('on' + h, f); +} +function RemoveHandler(h,f,e) { + e = e || doc; + if(e.removeEventListener) + e.removeEventListener(h, f); + else + e.detachEvent('on' + h, f); +} +function AddImage(i, o, t, tc) { + var s = tc.imageScale, mscale, ic, bc, oc, iw, ih; + // image not loaded, wait for image onload + if(!o.complete) + return AddHandler('load',function() { AddImage(i,o,t,tc); }, o); + if(!i.complete) + return AddHandler('load',function() { AddImage(i,o,t,tc); }, i); + + // Yes, this does look like nonsense, but it makes sure that both the + // width and height are actually set and not just calculated. This is + // required to keep proportional sizes when the images are hidden, so + // the images can be used again for another cloud. + o.width = o.width; + o.height = o.height; + + if(s) { + i.width = o.width * s; + i.height = o.height * s; + } + // the standard width of the image, with imageScale applied + t.iw = i.width; + t.ih = i.height; + if(tc.txtOpt) { + ic = i; + mscale = tc.zoomMax * tc.txtScale; + iw = t.iw * mscale; + ih = t.ih * mscale; + if(iw < o.naturalWidth || ih < o.naturalHeight) { + ic = ScaleImage(i, iw, ih); + if(ic) + t.fimage = ic; + } else { + iw = t.iw; + ih = t.ih; + mscale = 1; + } + if(parseFloat(tc.imageRadius)) + t.image = t.fimage = i = RoundImage(t.image, tc.imageRadius, iw, ih, mscale); + if(!t.HasText()) { + if(tc.shadow) { + ic = AddShadowToImage(t.image, iw, ih, mscale, tc.shadow, tc.shadowBlur, + tc.shadowOffset); + if(ic) { + t.fimage = ic.image; + t.w = ic.width; + t.h = ic.height; + } + } + if(tc.bgColour || tc.bgOutlineThickness) { + bc = tc.bgColour == 'tag' ? GetProperty(t.a, 'background-color') : + tc.bgColour; + oc = tc.bgOutline == 'tag' ? GetProperty(t.a, 'color') : + (tc.bgOutline || tc.textColour); + iw = t.fimage.width; + ih = t.fimage.height; + if(tc.outlineMethod == 'colour') { + // create the outline version first, using the current image state + ic = AddBackgroundToImage(t.fimage, iw, ih, mscale, bc, + tc.bgOutlineThickness, t.outline.colour, tc.padding, tc.bgRadius, 1); + if(ic) + t.oimage = ic.image; + } + ic = AddBackgroundToImage(t.fimage, iw, ih, mscale, bc, + tc.bgOutlineThickness, oc, tc.padding, tc.bgRadius); + if(ic) { + t.fimage = ic.image; + t.w = ic.width; + t.h = ic.height; + } + } + if(tc.outlineMethod == 'size') { + if(tc.outlineIncrease > 0) { + t.iw += 2 * tc.outlineIncrease; + t.ih += 2 * tc.outlineIncrease; + iw = mscale * t.iw; + ih = mscale * t.ih; + ic = ScaleImage(t.fimage, iw, ih); + t.oimage = ic; + t.fimage = ExpandImage(t.fimage, t.oimage.width, t.oimage.height); + } else { + iw = mscale * (t.iw + (2 * tc.outlineIncrease)); + ih = mscale * (t.ih + (2 * tc.outlineIncrease)); + ic = ScaleImage(t.fimage, iw, ih); + t.oimage = ExpandImage(ic, t.fimage.width, t.fimage.height); + } + } + } + } + t.Init(); +} +function GetProperty(e,p) { + var dv = doc.defaultView, pc = p.replace(/\-([a-z])/g,function(a){return a.charAt(1).toUpperCase()}); + return (dv && dv.getComputedStyle && dv.getComputedStyle(e,null).getPropertyValue(p)) || + (e.currentStyle && e.currentStyle[pc]); +} +function FindWeight(a, wFrom, tHeight) { + var w = 1, p; + if(wFrom) { + w = 1 * (a.getAttribute(wFrom) || tHeight); + } else if(p = GetProperty(a,'font-size')) { + w = (p.indexOf('px') > -1 && p.replace('px','') * 1) || + (p.indexOf('pt') > -1 && p.replace('pt','') * 1.25) || + p * 3.3; + } + return w; +} +function EventToCanvasId(e) { + return e.target && Defined(e.target.id) ? e.target.id : + e.srcElement.parentNode.id; +} +function EventXY(e, c) { + var xy, p, xmul = parseInt(GetProperty(c, 'width')) / c.width, + ymul = parseInt(GetProperty(c, 'height')) / c.height; + if(Defined(e.offsetX)) { + xy = {x: e.offsetX, y: e.offsetY}; + } else { + p = AbsPos(c.id); + if(Defined(e.changedTouches)) + e = e.changedTouches[0]; + if(e.pageX) + xy = {x: e.pageX - p.x, y: e.pageY - p.y}; + } + if(xy && xmul && ymul) { + xy.x /= xmul; + xy.y /= ymul; + } + return xy; +} +function MouseOut(e) { + var cv = e.target || e.fromElement.parentNode, tc = TagCanvas.tc[cv.id]; + if(tc) { + tc.mx = tc.my = -1; + tc.UnFreeze(); + tc.EndDrag(); + } +} +function MouseMove(e) { + var i, t = TagCanvas, tc, p, tg = EventToCanvasId(e); + for(i in t.tc) { + tc = t.tc[i]; + if(tc.tttimer) { + clearTimeout(tc.tttimer); + tc.tttimer = null; + } + } + if(tg && t.tc[tg]) { + tc = t.tc[tg]; + if(p = EventXY(e, tc.canvas)) { + tc.mx = p.x; + tc.my = p.y; + tc.Drag(e, p); + } + tc.drawn = 0; + } +} +function MouseDown(e) { + var t = TagCanvas, cb = doc.addEventListener ? 0 : 1, + tg = EventToCanvasId(e); + if(tg && e.button == cb && t.tc[tg]) { + t.tc[tg].BeginDrag(e); + } +} +function MouseUp(e) { + var t = TagCanvas, cb = doc.addEventListener ? 0 : 1, + tg = EventToCanvasId(e), tc; + if(tg && e.button == cb && t.tc[tg]) { + tc = t.tc[tg]; + MouseMove(e); + if(!tc.EndDrag() && !tc.touchState) + tc.Clicked(e); + } +} +function TouchDown(e) { + var tg = EventToCanvasId(e), tc = (tg && TagCanvas.tc[tg]), p; + if(tc && e.changedTouches) { + if(e.touches.length == 1 && tc.touchState == 0) { + tc.touchState = 1; + tc.BeginDrag(e); + if(p = EventXY(e, tc.canvas)) { + tc.mx = p.x; + tc.my = p.y; + tc.drawn = 0; + } + } else if(e.targetTouches.length == 2 && tc.pinchZoom) { + tc.touchState = 3; + tc.EndDrag(); + tc.BeginPinch(e); + } else { + tc.EndDrag(); + tc.EndPinch(); + tc.touchState = 0; + } + } +} +function TouchUp(e) { + var tg = EventToCanvasId(e), tc = (tg && TagCanvas.tc[tg]); + if(tc && e.changedTouches) { + switch(tc.touchState) { + case 1: + tc.Draw(); + tc.Clicked(); + break; + case 2: + tc.EndDrag(); + break; + case 3: + tc.EndPinch(); + } + tc.touchState = 0; + } +} +function TouchMove(e) { + var i, t = TagCanvas, tc, p, tg = EventToCanvasId(e); + for(i in t.tc) { + tc = t.tc[i]; + if(tc.tttimer) { + clearTimeout(tc.tttimer); + tc.tttimer = null; + } + } + tc = (tg && t.tc[tg]); + if(tc && e.changedTouches && tc.touchState) { + switch(tc.touchState) { + case 1: + case 2: + if(p = EventXY(e, tc.canvas)) { + tc.mx = p.x; + tc.my = p.y; + if(tc.Drag(e, p)) + tc.touchState = 2; + } + break; + case 3: + tc.Pinch(e); + } + tc.drawn = 0; + } +} +function MouseWheel(e) { + var t = TagCanvas, tg = EventToCanvasId(e); + if(tg && t.tc[tg]) { + e.cancelBubble = true; + e.returnValue = false; + e.preventDefault && e.preventDefault(); + t.tc[tg].Wheel((e.wheelDelta || e.detail) > 0); + } +} +function Scroll(e) { + var i, t = TagCanvas; + clearTimeout(t.scrollTimer); + for(i in t.tc) { + t.tc[i].Pause(); + } + t.scrollTimer = setTimeout(function() { + var i, t = TagCanvas; + for(i in t.tc) { + t.tc[i].Resume(); + } + }, t.scrollPause); +} +function DrawCanvas() { + DrawCanvasRAF(TimeNow()); +} +function DrawCanvasRAF(t) { + var tc = TagCanvas.tc, i; + TagCanvas.NextFrame(TagCanvas.interval); + t = t || TimeNow(); + for(i in tc) + tc[i].Draw(t); +} +function AbsPos(id) { + var e = doc.getElementById(id), r = e.getBoundingClientRect(), + dd = doc.documentElement, b = doc.body, w = window, + xs = w.pageXOffset || dd.scrollLeft, + ys = w.pageYOffset || dd.scrollTop, + xo = dd.clientLeft || b.clientLeft, + yo = dd.clientTop || b.clientTop; + return { x: r.left + xs - xo, y: r.top + ys - yo }; +} +function Project(tc,p1,sx,sy) { + var m = tc.radius * tc.z1 / (tc.z1 + tc.z2 + p1.z); + return { + x: p1.x * m * sx, + y: p1.y * m * sy, + z: p1.z, + w: (tc.z1 - p1.z) / tc.z2 + }; +} +/** + * @constructor + * for recursively splitting tag contents on
tags + */ +function TextSplitter(e) { + this.e = e; + this.br = 0; + this.line = []; + this.text = []; + this.original = e.innerText || e.textContent; +} +TSproto = TextSplitter.prototype; +TSproto.Empty = function() { + for(var i = 0; i < this.text.length; ++i) + if(this.text[i].length) + return false; + return true; +}; +TSproto.Lines = function(e) { + var r = e ? 1 : 0, cn, cl, i; + e = e || this.e; + cn = e.childNodes; + cl = cn.length; + + for(i = 0; i < cl; ++i) { + if(cn[i].nodeName == 'BR') { + this.text.push(this.line.join(' ')); + this.br = 1; + } else if(cn[i].nodeType == 3) { + if(this.br) { + this.line = [cn[i].nodeValue]; + this.br = 0; + } else { + this.line.push(cn[i].nodeValue); + } + } else { + this.Lines(cn[i]); + } + } + r || this.br || this.text.push(this.line.join(' ')); + return this.text; +}; +TSproto.SplitWidth = function(w, c, f, h) { + var i, j, words, text = []; + c.font = h + 'px ' + f; + for(i = 0; i < this.text.length; ++i) { + words = this.text[i].split(/\s+/); + this.line = [words[0]]; + for(j = 1; j < words.length; ++j) { + if(c.measureText(this.line.join(' ') + ' ' + words[j]).width > w) { + text.push(this.line.join(' ')); + this.line = [words[j]]; + } else { + this.line.push(words[j]); + } + } + text.push(this.line.join(' ')); + } + return this.text = text; +}; +/** + * @constructor + */ +function Outline(tc,t) { + this.ts = null; + this.tc = tc; + this.tag = t; + this.x = this.y = this.w = this.h = this.sc = 1; + this.z = 0; + this.pulse = 1; + this.pulsate = tc.pulsateTo < 1; + this.colour = tc.outlineColour; + this.adash = ~~tc.outlineDash; + this.agap = ~~tc.outlineDashSpace || this.adash; + this.aspeed = tc.outlineDashSpeed * 1; + if(this.colour == 'tag') + this.colour = GetProperty(t.a, 'color'); + else if(this.colour == 'tagbg') + this.colour = GetProperty(t.a, 'background-color'); + this.Draw = this.pulsate ? this.DrawPulsate : this.DrawSimple; + this.radius = tc.outlineRadius | 0; + this.SetMethod(tc.outlineMethod); +} +Oproto = Outline.prototype; +Oproto.SetMethod = function(om) { + var methods = { + block: ['PreDraw','DrawBlock'], + colour: ['PreDraw','DrawColour'], + outline: ['PostDraw','DrawOutline'], + classic: ['LastDraw','DrawOutline'], + size: ['PreDraw','DrawSize'], + none: ['LastDraw'] + }, funcs = methods[om] || methods.outline; + if(om == 'none') { + this.Draw = function() { return 1; } + } else { + this.drawFunc = this[funcs[1]]; + } + this[funcs[0]] = this.Draw; +}; +Oproto.Update = function(x,y,w,h,sc,z,xo,yo) { + var o = this.tc.outlineOffset, o2 = 2 * o; + this.x = sc * x + xo - o; + this.y = sc * y + yo - o; + this.w = sc * w + o2; + this.h = sc * h + o2; + this.sc = sc; // used to determine frontmost + this.z = z; +}; +Oproto.Ants = function(c) { + if(!this.adash) + return; + var l = this.adash, g = this.agap, s = this.aspeed, length = l + g, + l1 = 0, l2 = l, g1 = g, g2 = 0, seq = 0, ants; + if(s) { + seq = abs(s) * (TimeNow() - this.ts) / 50; + if(s < 0) + seq = 8.64e6 - seq; + s = ~~seq % length; + } + if(s) { + if(l >= s) { + l1 = l - s; + l2 = s; + } else { + g1 = length - s; + g2 = g - g1; + } + ants = [l1, g1, l2, g2]; + } else { + ants = [l,g]; + } + c.setLineDash(ants); +} +Oproto.DrawOutline = function(c,x,y,w,h,colour) { + var r = min(this.radius, h/2, w/2); + c.strokeStyle = colour; + this.Ants(c); + RRect(c, x, y, w, h, r, true); +}; +Oproto.DrawSize = function(c,x,y,w,h,colour,tag,x1,y1) { + var tw = tag.w, th = tag.h, m, i, sc; + if(this.pulsate) { + if(tag.image) + sc = (tag.image.height + this.tc.outlineIncrease) / tag.image.height; + else + sc = tag.oscale; + i = tag.fimage || tag.image; + m = 1 + ((sc - 1) * (1-this.pulse)); + tag.h *= m; + tag.w *= m; + } else { + i = tag.oimage; + } + tag.alpha = 1; + tag.Draw(c, x1, y1, i); + tag.h = th; + tag.w = tw; + return 1; +}; +Oproto.DrawColour = function(c,x,y,w,h,colour,tag,x1,y1) { + if(tag.oimage) { + if(this.pulse < 1) { + tag.alpha = 1 - pow(this.pulse, 2); + tag.Draw(c, x1, y1, tag.fimage); + tag.alpha = this.pulse; + } else { + tag.alpha = 1; + } + tag.Draw(c, x1, y1, tag.oimage); + return 1; + } + return this[tag.image ? 'DrawColourImage' : 'DrawColourText'](c,x,y,w,h,colour,tag,x1,y1); +}; +Oproto.DrawColourText = function(c,x,y,w,h,colour,tag,x1,y1) { + var normal = tag.colour; + tag.colour = colour; + tag.alpha = 1; + tag.Draw(c,x1,y1); + tag.colour = normal; + return 1; +}; +Oproto.DrawColourImage = function(c,x,y,w,h,colour,tag,x1,y1) { + var ccanvas = c.canvas, fx = ~~max(x,0), fy = ~~max(y,0), + fw = min(ccanvas.width - fx, w) + .5|0, fh = min(ccanvas.height - fy,h) + .5|0, cc; + if(ocanvas) + ocanvas.width = fw, ocanvas.height = fh; + else + ocanvas = NewCanvas(fw, fh); + if(!ocanvas) + return this.SetMethod('outline'); // if using IE and images, give up! + cc = ocanvas.getContext('2d'); + + cc.drawImage(ccanvas,fx,fy,fw,fh,0,0,fw,fh); + c.clearRect(fx,fy,fw,fh); + if(this.pulsate) { + tag.alpha = 1 - pow(this.pulse, 2); + } else { + tag.alpha = 1; + } + tag.Draw(c,x1,y1); + c.setTransform(1,0,0,1,0,0); + c.save(); + c.beginPath(); + c.rect(fx,fy,fw,fh); + c.clip(); + c.globalCompositeOperation = 'source-in'; + c.fillStyle = colour; + c.fillRect(fx,fy,fw,fh); + c.restore(); + c.globalAlpha = 1; + c.globalCompositeOperation = 'destination-over'; + c.drawImage(ocanvas,0,0,fw,fh,fx,fy,fw,fh); + c.globalCompositeOperation = 'source-over'; + return 1; +}; +Oproto.DrawBlock = function(c,x,y,w,h,colour) { + var r = min(this.radius, h/2, w/2); + c.fillStyle = colour; + RRect(c, x, y, w, h, r); +}; +Oproto.DrawSimple = function(c, tag, x1, y1, ga, useGa) { + var t = this.tc; + c.setTransform(1,0,0,1,0,0); + c.strokeStyle = this.colour; + c.lineWidth = t.outlineThickness; + c.shadowBlur = c.shadowOffsetX = c.shadowOffsetY = 0; + c.globalAlpha = useGa ? ga : 1; + return this.drawFunc(c,this.x,this.y,this.w,this.h,this.colour,tag,x1,y1); +}; +Oproto.DrawPulsate = function(c, tag, x1, y1) { + var diff = TimeNow() - this.ts, t = this.tc, + ga = t.pulsateTo + ((1 - t.pulsateTo) * + (0.5 + (cos(2 * Math.PI * diff / (1000 * t.pulsateTime)) / 2))); + this.pulse = ga = TagCanvas.Smooth(1,ga); + return this.DrawSimple(c, tag, x1, y1, ga, 1); +}; +Oproto.Active = function(c,x,y) { + var a = (x >= this.x && y >= this.y && + x <= this.x + this.w && y <= this.y + this.h); + if(a) { + this.ts = this.ts || TimeNow(); + } else { + this.ts = null; + } + return a; +}; +Oproto.PreDraw = Oproto.PostDraw = Oproto.LastDraw = Nop; +/** + * @constructor + */ +function Tag(tc, text, a, v, w, h, col, bcol, bradius, boutline, bothickness, + font, padding, original) { + this.tc = tc; + this.image = null; + this.text = text; + this.text_original = original; + this.line_widths = []; + this.title = a.title || null; + this.a = a; + this.position = new Vector(v[0], v[1], v[2]); + this.x = this.y = this.z = 0; + this.w = w; + this.h = h; + this.colour = col || tc.textColour; + this.bgColour = bcol || tc.bgColour; + this.bgRadius = bradius | 0; + this.bgOutline = boutline || this.colour; + this.bgOutlineThickness = bothickness | 0; + this.textFont = font || tc.textFont; + this.padding = padding | 0; + this.sc = this.alpha = 1; + this.weighted = !tc.weight; + this.outline = new Outline(tc,this); +} +Tproto = Tag.prototype; +Tproto.Init = function(e) { + var tc = this.tc; + this.textHeight = tc.textHeight; + if(this.HasText()) { + this.Measure(tc.ctxt,tc); + } else { + this.w = this.iw; + this.h = this.ih; + } + + this.SetShadowColour = tc.shadowAlpha ? this.SetShadowColourAlpha : this.SetShadowColourFixed; + this.SetDraw(tc); +}; +Tproto.Draw = Nop; +Tproto.HasText = function() { + return this.text && this.text[0].length > 0; +}; +Tproto.EqualTo = function(e) { + var i = e.getElementsByTagName('img'); + if(this.a.href != e.href) + return 0; + if(i.length) + return this.image.src == i[0].src; + return (e.innerText || e.textContent) == this.text_original; +}; +Tproto.SetImage = function(i) { + this.image = this.fimage = i; +}; +Tproto.SetDraw = function(t) { + this.Draw = this.fimage ? (t.ie > 7 ? this.DrawImageIE : this.DrawImage) : this.DrawText; + t.noSelect && (this.CheckActive = Nop); +}; +Tproto.MeasureText = function(c) { + var i, l = this.text.length, w = 0, wl; + for(i = 0; i < l; ++i) { + this.line_widths[i] = wl = c.measureText(this.text[i]).width; + w = max(w, wl); + } + return w; +}; +Tproto.Measure = function(c,t) { + var extents = FindTextBoundingBox(this.text, this.textFont, this.textHeight), + s, th, f, soff, cw, twidth, theight, img, tcv; + // add the gap at the top to the height to make equal gap at bottom + theight = extents ? extents.max.y + extents.min.y : this.textHeight; + c.font = this.font = this.textHeight + 'px ' + this.textFont; + twidth = this.MeasureText(c); + if(t.txtOpt) { + s = t.txtScale; + th = s * this.textHeight; + f = th + 'px ' + this.textFont; + soff = [s * t.shadowOffset[0], s * t.shadowOffset[1]]; + c.font = f; + cw = this.MeasureText(c); + tcv = new TextCanvas(this.text, f, cw + s, (s * theight) + s, cw, + this.line_widths, t.textAlign, t.textVAlign, s); + + if(this.image) + tcv.SetImage(this.image, this.iw, this.ih, t.imagePosition, t.imagePadding, + t.imageAlign, t.imageVAlign, t.imageScale); + + img = tcv.Create(this.colour, this.bgColour, this.bgOutline, + s * this.bgOutlineThickness, t.shadow, s * t.shadowBlur, soff, + s * this.padding, s * this.bgRadius); + + // add outline image using highlight colour + if(t.outlineMethod == 'colour') { + this.oimage = tcv.Create(this.outline.colour, this.bgColour, this.outline.colour, + s * this.bgOutlineThickness, t.shadow, s * t.shadowBlur, soff, + s * this.padding, s * this.bgRadius); + + } else if(t.outlineMethod == 'size') { + extents = FindTextBoundingBox(this.text, this.textFont, + this.textHeight + t.outlineIncrease); + th = extents.max.y + extents.min.y; + f = (s * (this.textHeight + t.outlineIncrease)) + 'px ' + this.textFont; + c.font = f; + cw = this.MeasureText(c); + + tcv = new TextCanvas(this.text, f, cw + s, (s * th) + s, cw, + this.line_widths, t.textAlign, t.textVAlign, s); + if(this.image) + tcv.SetImage(this.image, this.iw + t.outlineIncrease, + this.ih + t.outlineIncrease, t.imagePosition, t.imagePadding, + t.imageAlign, t.imageVAlign, t.imageScale); + + this.oimage = tcv.Create(this.colour, this.bgColour, this.bgOutline, + s * this.bgOutlineThickness, t.shadow, s * t.shadowBlur, soff, + s * this.padding, s * this.bgRadius); + + this.oscale = this.oimage.width / img.width; + if(t.outlineIncrease > 0) + img = ExpandImage(img, this.oimage.width, this.oimage.height); + else + this.oimage = ExpandImage(this.oimage, img.width, img.height); + } + if(img) { + this.fimage = img; + twidth = this.fimage.width / s; + theight = this.fimage.height / s; + } + this.SetDraw(t); + t.txtOpt = !!this.fimage; + } + this.h = theight; + this.w = twidth; +}; +Tproto.SetFont = function(f, c, bc, boc) { + this.textFont = f; + this.colour = c; + this.bgColour = bc; + this.bgOutline = boc; + this.Measure(this.tc.ctxt, this.tc); +}; +Tproto.SetWeight = function(w) { + var tc = this.tc, modes = tc.weightMode.split(/[, ]/), m, s, wl = w.length; + if(!this.HasText()) + return; + this.weighted = true; + for(s = 0; s < wl; ++s) { + m = modes[s] || 'size'; + if('both' == m) { + this.Weight(w[s], tc.ctxt, tc, 'size', tc.min_weight[s], + tc.max_weight[s], s); + this.Weight(w[s], tc.ctxt, tc, 'colour', tc.min_weight[s], + tc.max_weight[s], s); + } else { + this.Weight(w[s], tc.ctxt, tc, m, tc.min_weight[s], tc.max_weight[s], s); + } + } + this.Measure(tc.ctxt, tc); +}; +Tproto.Weight = function(w, c, t, m, wmin, wmax, wnum) { + w = isNaN(w) ? 1 : w; + var nweight = (w - wmin) / (wmax - wmin); + if('colour' == m) + this.colour = FindGradientColour(t, nweight, wnum); + else if('bgcolour' == m) + this.bgColour = FindGradientColour(t, nweight, wnum); + else if('bgoutline' == m) + this.bgOutline = FindGradientColour(t, nweight, wnum); + else if('outline' == m) + this.outline.colour = FindGradientColour(t, nweight, wnum); + else if('size' == m) { + if(t.weightSizeMin > 0 && t.weightSizeMax > t.weightSizeMin) { + this.textHeight = t.weightSize * + (t.weightSizeMin + (t.weightSizeMax - t.weightSizeMin) * nweight); + } else { + // min textHeight of 1 + this.textHeight = max(1, w * t.weightSize); + } + } +}; +Tproto.SetShadowColourFixed = function(c,s,a) { + c.shadowColor = s; +}; +Tproto.SetShadowColourAlpha = function(c,s,a) { + c.shadowColor = SetAlpha(s, a); +}; +Tproto.DrawText = function(c,xoff,yoff) { + var t = this.tc, x = this.x, y = this.y, s = this.sc, i, xl; + c.globalAlpha = this.alpha; + c.fillStyle = this.colour; + t.shadow && this.SetShadowColour(c,t.shadow,this.alpha); + c.font = this.font; + x += xoff / s; + y += (yoff / s) - (this.h / 2); + for(i = 0; i < this.text.length; ++i) { + xl = x; + if('right' == t.textAlign) { + xl += this.w / 2 - this.line_widths[i]; + } else if('centre' == t.textAlign) { + xl -= this.line_widths[i] / 2; + } else { + xl -= this.w / 2; + } + c.setTransform(s, 0, 0, s, s * xl, s * y); + c.fillText(this.text[i], 0, 0); + y += this.textHeight; + } +}; +Tproto.DrawImage = function(c,xoff,yoff,im) { + var x = this.x, y = this.y, s = this.sc, + i = im || this.fimage, w = this.w, h = this.h, a = this.alpha, + shadow = this.shadow; + c.globalAlpha = a; + shadow && this.SetShadowColour(c,shadow,a); + x += (xoff / s) - (w / 2); + y += (yoff / s) - (h / 2); + c.setTransform(s, 0, 0, s, s * x, s * y); + c.drawImage(i, 0, 0, w, h); +}; +Tproto.DrawImageIE = function(c,xoff,yoff) { + var i = this.fimage, s = this.sc, + w = i.width = this.w*s, h = i.height = this.h * s, + x = (this.x*s) + xoff - (w/2), y = (this.y*s) + yoff - (h/2); + c.setTransform(1,0,0,1,0,0); + c.globalAlpha = this.alpha; + c.drawImage(i, x, y); +}; +Tproto.Calc = function(m,a) { + var pp, t = this.tc, mnb = t.minBrightness, + mxb = t.maxBrightness, r = t.max_radius; + pp = m.xform(this.position); + this.xformed = pp; + pp = Project(t, pp, t.stretchX, t.stretchY); + this.x = pp.x; + this.y = pp.y; + this.z = pp.z; + this.sc = pp.w; + this.alpha = a * Clamp(mnb + (mxb - mnb) * (r - this.z) / (2 * r), 0, 1); + return this.xformed; +}; +Tproto.UpdateActive = function(c, xoff, yoff) { + var o = this.outline, w = this.w, h = this.h, + x = this.x - w/2, y = this.y - h/2; + o.Update(x, y, w, h, this.sc, this.z, xoff, yoff); + return o; +}; +Tproto.CheckActive = function(c,xoff,yoff) { + var t = this.tc, o = this.UpdateActive(c, xoff, yoff); + return o.Active(c, t.mx, t.my) ? o : null; +}; +Tproto.Clicked = function(e) { + var a = this.a, t = a.target, h = a.href, evt; + if(t != '' && t != '_self') { + if(self.frames[t]) { + self.frames[t].document.location = h; + } else{ + try { + if(top.frames[t]) { + top.frames[t].document.location = h; + return; + } + } catch(err) { + // different domain/port/protocol? + } + window.open(h, t); + } + return; + } + if(doc.createEvent) { + evt = doc.createEvent('MouseEvents'); + evt.initMouseEvent('click', 1, 1, window, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, null); + if(!a.dispatchEvent(evt)) + return; + } else if(a.fireEvent) { + if(!a.fireEvent('onclick')) + return; + } + doc.location = h; +}; +/** + * @constructor + */ +function TagCanvas(cid,lctr,opt) { + var i, p, c = doc.getElementById(cid), cp = ['id','class','innerHTML'], raf; + + if(!c) throw 0; + if(Defined(window.G_vmlCanvasManager)) { + c = window.G_vmlCanvasManager.initElement(c); + this.ie = parseFloat(navigator.appVersion.split('MSIE')[1]); + } + if(c && (!c.getContext || !c.getContext('2d').fillText)) { + p = doc.createElement('DIV'); + for(i = 0; i < cp.length; ++i) + p[cp[i]] = c[cp[i]]; + c.parentNode.insertBefore(p,c); + c.parentNode.removeChild(c); + throw 0; + } + for(i in TagCanvas.options) + this[i] = opt && Defined(opt[i]) ? opt[i] : + (Defined(TagCanvas[i]) ? TagCanvas[i] : TagCanvas.options[i]); + + this.canvas = c; + this.ctxt = c.getContext('2d'); + this.z1 = 250 / max(this.depth, 0.001); + this.z2 = this.z1 / this.zoom; + this.radius = min(c.height, c.width) * 0.0075; // fits radius of 100 in canvas + this.max_radius = 100; + this.max_weight = []; + this.min_weight = []; + this.textFont = this.textFont && FixFont(this.textFont); + this.textHeight *= 1; + this.imageRadius = this.imageRadius.toString(); + this.pulsateTo = Clamp(this.pulsateTo, 0, 1); + this.minBrightness = Clamp(this.minBrightness, 0, 1); + this.maxBrightness = Clamp(this.maxBrightness, this.minBrightness, 1); + this.ctxt.textBaseline = 'top'; + this.lx = (this.lock + '').indexOf('x') + 1; + this.ly = (this.lock + '').indexOf('y') + 1; + this.frozen = this.dx = this.dy = this.fixedAnim = this.touchState = 0; + this.fixedAlpha = 1; + this.source = lctr || cid; + this.repeatTags = min(64, ~~this.repeatTags); + this.minTags = min(200, ~~this.minTags); + if(~~this.scrollPause > 0) + TagCanvas.scrollPause = ~~this.scrollPause; + else + this.scrollPause = 0; + if(this.minTags > 0 && this.repeatTags < 1 && (i = this.GetTags().length)) + this.repeatTags = ceil(this.minTags / i) - 1; + this.transform = Matrix.Identity(); + this.startTime = this.time = TimeNow(); + this.mx = this.my = -1; + this.centreImage && CentreImage(this); + this.Animate = this.dragControl ? this.AnimateDrag : this.AnimatePosition; + this.animTiming = (typeof TagCanvas[this.animTiming] == 'function' ? + TagCanvas[this.animTiming] : TagCanvas.Smooth); + if(this.shadowBlur || this.shadowOffset[0] || this.shadowOffset[1]) { + // let the browser translate "red" into "#ff0000" + this.ctxt.shadowColor = this.shadow; + this.shadow = this.ctxt.shadowColor; + this.shadowAlpha = ShadowAlphaBroken(); + } else { + delete this.shadow; + } + this.Load(); + if(lctr && this.hideTags) { + (function(t) { + if(TagCanvas.loaded) + t.HideTags(); + else + AddHandler('load', function() { t.HideTags(); }, window); + })(this); + } + + this.yaw = this.initial ? this.initial[0] * this.maxSpeed : 0; + this.pitch = this.initial ? this.initial[1] * this.maxSpeed : 0; + if(this.tooltip) { + this.ctitle = c.title; + c.title = ''; + if(this.tooltip == 'native') { + this.Tooltip = this.TooltipNative; + } else { + this.Tooltip = this.TooltipDiv; + if(!this.ttdiv) { + this.ttdiv = doc.createElement('div'); + this.ttdiv.className = this.tooltipClass; + this.ttdiv.style.position = 'absolute'; + this.ttdiv.style.zIndex = c.style.zIndex + 1; + AddHandler('mouseover',function(e){e.target.style.display='none';},this.ttdiv); + doc.body.appendChild(this.ttdiv); + } + } + } else { + this.Tooltip = this.TooltipNone; + } + if(!this.noMouse && !handlers[cid]) { + handlers[cid] = [ + ['mousemove', MouseMove], + ['mouseout', MouseOut], + ['mouseup', MouseUp], + ['touchstart', TouchDown], + ['touchend', TouchUp], + ['touchcancel', TouchUp], + ['touchmove', TouchMove] + ]; + if(this.dragControl) { + handlers[cid].push(['mousedown', MouseDown]); + handlers[cid].push(['selectstart', Nop]); + } + if(this.wheelZoom) { + handlers[cid].push(['mousewheel', MouseWheel]); + handlers[cid].push(['DOMMouseScroll', MouseWheel]); + } + if(this.scrollPause) { + handlers[cid].push(['scroll', Scroll, window]); + } + for(i = 0; i < handlers[cid].length; ++i) { + p = handlers[cid][i]; + AddHandler(p[0], p[1], p[2] ? p[2] : c); + } + } + if(!TagCanvas.started) { + raf = window.requestAnimationFrame = window.requestAnimationFrame || + window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || + window.msRequestAnimationFrame; + TagCanvas.NextFrame = raf ? TagCanvas.NextFrameRAF : + TagCanvas.NextFrameTimeout; + TagCanvas.interval = this.interval; + TagCanvas.NextFrame(this.interval); + TagCanvas.started = 1; + } +} +TCproto = TagCanvas.prototype; +TCproto.SourceElements = function() { + if(doc.querySelectorAll) + return doc.querySelectorAll('#' + this.source); + return [doc.getElementById(this.source)]; +}; +TCproto.HideTags = function() { + var el = this.SourceElements(), i; + for(i = 0; i < el.length; ++i) + el[i].style.display = 'none'; +}; +TCproto.GetTags = function() { + var el = this.SourceElements(), etl, tl = [], i, j, k; + for(k = 0; k <= this.repeatTags; ++k) { + for(i = 0; i < el.length; ++i) { + etl = el[i].getElementsByTagName('a'); + for(j = 0; j < etl.length; ++j) { + tl.push(etl[j]); + } + } + } + return tl; +}; +TCproto.Message = function(text) { + var tl = [], i, p, tc = text.split(''), a, t, x, z; + for(i = 0; i < tc.length; ++i) { + if(tc[i] != ' ') { + p = i - tc.length / 2; + a = doc.createElement('A'); + a.href = '#'; + a.innerText = tc[i]; + x = 100 * sin(p / 9); + z = -100 * cos(p / 9); + t = new Tag(this, tc[i], a, [x,0,z], 2, 18, '#000', '#fff', 0, 0, 0, + 'monospace', 2, tc[i]); + t.Init(); + tl.push(t); + } + } + return tl; +}; +TCproto.CreateTag = function(e) { + var im, i, t, txt, ts, font, bc, boc, p = [0, 0, 0]; + if('text' != this.imageMode) { + im = e.getElementsByTagName('img'); + if(im.length) { + i = new Image; + i.src = im[0].src; + + if(!this.imageMode) { + t = new Tag(this, "", e, p, 0, 0); + t.SetImage(i); + //t.Init(); + AddImage(i, im[0], t, this); + return t; + } + } + } + if('image' != this.imageMode) { + ts = new TextSplitter(e); + txt = ts.Lines(); + if(!ts.Empty()) { + font = this.textFont || FixFont(GetProperty(e,'font-family')); + if(this.splitWidth) + txt = ts.SplitWidth(this.splitWidth, this.ctxt, font, this.textHeight); + + bc = this.bgColour == 'tag' ? GetProperty(e, 'background-color') : + this.bgColour; + boc = this.bgOutline == 'tag' ? GetProperty(e, 'color') : this.bgOutline; + } else { + ts = null; + } + } + if(ts || i) { + t = new Tag(this, txt, e, p, 2, this.textHeight + 2, + this.textColour || GetProperty(e,'color'), bc, this.bgRadius, + boc, this.bgOutlineThickness, font, this.padding, ts && ts.original); + if(i) { + t.SetImage(i); + AddImage(i, im[0], t, this); + } else { + t.Init(); + } + return t; + } +}; +TCproto.UpdateTag = function(t, a) { + var colour = this.textColour || GetProperty(a, 'color'), + font = this.textFont || FixFont(GetProperty(a, 'font-family')), + bc = this.bgColour == 'tag' ? GetProperty(a, 'background-color') : + this.bgColour, boc = this.bgOutline == 'tag' ? GetProperty(a, 'color') : + this.bgOutline; + t.a = a; + t.title = a.title; + if(t.colour != colour || t.textFont != font || t.bgColour != bc || + t.bgOutline != boc) + t.SetFont(font, colour, bc, boc); +}; +TCproto.Weight = function(tl) { + var ll = tl.length, w, i, s, weights = [], valid, + wfrom = this.weightFrom ? this.weightFrom.split(/[, ]/) : [null], + wl = wfrom.length; + for(i = 0; i < ll; ++i) { + weights[i] = []; + for(s = 0; s < wl; ++s) { + w = FindWeight(tl[i].a, wfrom[s], this.textHeight); + if(!this.max_weight[s] || w > this.max_weight[s]) + this.max_weight[s] = w; + if(!this.min_weight[s] || w < this.min_weight[s]) + this.min_weight[s] = w; + weights[i][s] = w; + } + } + for(s = 0; s < wl; ++s) { + if(this.max_weight[s] > this.min_weight[s]) + valid = 1; + } + if(valid) { + for(i = 0; i < ll; ++i) { + tl[i].SetWeight(weights[i]); + } + } +}; +TCproto.Load = function() { + var tl = this.GetTags(), taglist = [], shape, t, + shapeArgs, rx, ry, rz, vl, i, tagmap = [], pfuncs = { + sphere: PointsOnSphere, + vcylinder: PointsOnCylinderV, + hcylinder: PointsOnCylinderH, + vring: PointsOnRingV, + hring: PointsOnRingH + }; + + if(tl.length) { + tagmap.length = tl.length; + for(i = 0; i < tl.length; ++i) + tagmap[i] = i; + this.shuffleTags && Shuffle(tagmap); + rx = 100 * this.radiusX; + ry = 100 * this.radiusY; + rz = 100 * this.radiusZ; + this.max_radius = max(rx, max(ry, rz)); + + for(i = 0; i < tl.length; ++i) { + t = this.CreateTag(tl[tagmap[i]]); + if(t) + taglist.push(t); + } + this.weight && this.Weight(taglist, true); + + if(this.shapeArgs) { + this.shapeArgs[0] = taglist.length; + } else { + shapeArgs = this.shape.toString().split(/[(),]/); + shape = shapeArgs.shift(); + if(typeof window[shape] === 'function') + this.shape = window[shape]; + else + this.shape = pfuncs[shape] || pfuncs.sphere; + this.shapeArgs = [taglist.length, rx, ry, rz].concat(shapeArgs); + } + vl = this.shape.apply(this, this.shapeArgs); + this.listLength = taglist.length; + for(i = 0; i < taglist.length; ++i) + taglist[i].position = new Vector(vl[i][0], vl[i][1], vl[i][2]); + } + if(this.noTagsMessage && !taglist.length) { + i = (this.imageMode && this.imageMode != 'both' ? this.imageMode + ' ': ''); + taglist = this.Message('No ' + i + 'tags'); + } + this.taglist = taglist; +}; +TCproto.Update = function() { + var tl = this.GetTags(), newlist = [], + taglist = this.taglist, found, + added = [], removed = [], vl, ol, nl, i, j; + + if(!this.shapeArgs) + return this.Load(); + + if(tl.length) { + nl = this.listLength = tl.length; + ol = taglist.length; + + // copy existing list, populate "removed" + for(i = 0; i < ol; ++i) { + newlist.push(taglist[i]); + removed.push(i); + } + + // find added and removed tags + for(i = 0; i < nl; ++i) { + for(j = 0, found = 0; j < ol; ++j) { + if(taglist[j].EqualTo(tl[i])) { + this.UpdateTag(newlist[j], tl[i]); + found = removed[j] = -1; + } + } + if(!found) + added.push(i); + } + + // clean out found tags from removed list + for(i = 0, j = 0; i < ol; ++i) { + if(removed[j] == -1) + removed.splice(j,1); + else + ++j; + } + + // insert new tags in gaps where old tags removed + if(removed.length) { + Shuffle(removed); + while(removed.length && added.length) { + i = removed.shift(); + j = added.shift(); + newlist[i] = this.CreateTag(tl[j]); + } + + // remove any more (in reverse order) + removed.sort(function(a,b) {return a-b}); + while(removed.length) { + newlist.splice(removed.pop(), 1); + } + } + + // add any extra tags + j = newlist.length / (added.length + 1); + i = 0; + while(added.length) { + newlist.splice(ceil(++i * j), 0, this.CreateTag(tl[added.shift()])); + } + + // assign correct positions to tags + this.shapeArgs[0] = nl = newlist.length; + vl = this.shape.apply(this, this.shapeArgs); + for(i = 0; i < nl; ++i) + newlist[i].position = new Vector(vl[i][0], vl[i][1], vl[i][2]); + + // reweight tags + this.weight && this.Weight(newlist); + } + this.taglist = newlist; +}; +TCproto.SetShadow = function(c) { + c.shadowBlur = this.shadowBlur; + c.shadowOffsetX = this.shadowOffset[0]; + c.shadowOffsetY = this.shadowOffset[1]; +}; +TCproto.Draw = function(t) { + if(this.paused) + return; + var cv = this.canvas, cw = cv.width, ch = cv.height, max_sc = 0, + tdelta = (t - this.time) * TagCanvas.interval / 1000, + x = cw / 2 + this.offsetX, y = ch / 2 + this.offsetY, c = this.ctxt, + active, a, i, aindex = -1, tl = this.taglist, l = tl.length, + frontsel = this.frontSelect, centreDrawn = (this.centreFunc == Nop), fixed; + this.time = t; + if(this.frozen && this.drawn) + return this.Animate(cw,ch,tdelta); + fixed = this.AnimateFixed(); + c.setTransform(1,0,0,1,0,0); + for(i = 0; i < l; ++i) + tl[i].Calc(this.transform, this.fixedAlpha); + tl = SortList(tl, function(a,b) {return b.z-a.z}); + + if(fixed && this.fixedAnim.active) { + active = this.fixedAnim.tag.UpdateActive(c, x, y); + } else { + this.active = null; + for(i = 0; i < l; ++i) { + a = this.mx >= 0 && this.my >= 0 && this.taglist[i].CheckActive(c, x, y); + if(a && a.sc > max_sc && (!frontsel || a.z <= 0)) { + active = a; + aindex = i; + active.tag = this.taglist[i]; + max_sc = a.sc; + } + } + this.active = active; + } + + this.txtOpt || (this.shadow && this.SetShadow(c)); + c.clearRect(0,0,cw,ch); + for(i = 0; i < l; ++i) { + if(!centreDrawn && tl[i].z <= 0) { + // run the centreFunc if the next tag is at the front + try { this.centreFunc(c, cw, ch, x, y); } + catch(e) { + alert(e); + // don't run it again + this.centreFunc = Nop; + } + centreDrawn = true; + } + + if(!(active && active.tag == tl[i] && active.PreDraw(c, tl[i], x, y))) + tl[i].Draw(c, x, y); + active && active.tag == tl[i] && active.PostDraw(c); + } + if(this.freezeActive && active) { + this.Freeze(); + } else { + this.UnFreeze(); + this.drawn = (l == this.listLength); + } + if(this.fixedCallback) { + this.fixedCallback(this,this.fixedCallbackTag); + this.fixedCallback = null; + } + fixed || this.Animate(cw, ch, tdelta); + active && active.LastDraw(c); + cv.style.cursor = active ? this.activeCursor : ''; + this.Tooltip(active,this.taglist[aindex]); +}; +TCproto.TooltipNone = function() { }; +TCproto.TooltipNative = function(active,tag) { + if(active) + this.canvas.title = tag && tag.title ? tag.title : ''; + else + this.canvas.title = this.ctitle; +}; +TCproto.SetTTDiv = function(title, tag) { + var tc = this, s = tc.ttdiv.style; + if(title != tc.ttdiv.innerHTML) + s.display = 'none'; + tc.ttdiv.innerHTML = title; + tag && (tag.title = tc.ttdiv.innerHTML); + if(s.display == 'none' && ! tc.tttimer) { + tc.tttimer = setTimeout(function() { + var p = AbsPos(tc.canvas.id); + s.display = 'block'; + s.left = p.x + tc.mx + 'px'; + s.top = p.y + tc.my + 24 + 'px'; + tc.tttimer = null; + }, tc.tooltipDelay); + } +}; +TCproto.TooltipDiv = function(active,tag) { + if(active && tag && tag.title) { + this.SetTTDiv(tag.title, tag); + } else if(!active && this.mx != -1 && this.my != -1 && this.ctitle.length) { + this.SetTTDiv(this.ctitle); + } else { + this.ttdiv.style.display = 'none'; + } +}; +TCproto.Transform = function(tc, p, y) { + if(p || y) { + var sp = sin(p), cp = cos(p), sy = sin(y), cy = cos(y), + ym = new Matrix([cy,0,sy, 0,1,0, -sy,0,cy]), + pm = new Matrix([1,0,0, 0,cp,-sp, 0,sp,cp]); + tc.transform = tc.transform.mul(ym.mul(pm)); + } +}; +TCproto.AnimateFixed = function() { + var fa, t1, angle, m, d; + if(this.fadeIn) { + t1 = TimeNow() - this.startTime; + if(t1 >= this.fadeIn) { + this.fadeIn = 0; + this.fixedAlpha = 1; + } else { + this.fixedAlpha = t1 / this.fadeIn; + } + } + if(this.fixedAnim) { + if(!this.fixedAnim.transform) + this.fixedAnim.transform = this.transform; + fa = this.fixedAnim, t1 = TimeNow() - fa.t0, angle = fa.angle, + m, d = this.animTiming(fa.t, t1); + this.transform = fa.transform; + if(t1 >= fa.t) { + this.fixedCallbackTag = fa.tag; + this.fixedCallback = fa.cb; + this.fixedAnim = this.yaw = this.pitch = 0; + } else { + angle *= d; + } + m = Matrix.Rotation(angle, fa.axis); + this.transform = this.transform.mul(m); + return (this.fixedAnim != 0); + } + return false; +}; +TCproto.AnimatePosition = function(w, h, t) { + var tc = this, x = tc.mx, y = tc.my, s, r; + if(!tc.frozen && x >= 0 && y >= 0 && x < w && y < h) { + s = tc.maxSpeed, r = tc.reverse ? -1 : 1; + tc.lx || (tc.yaw = ((x * 2 * s / w) - s) * r * t); + tc.ly || (tc.pitch = ((y * 2 * s / h) - s) * -r * t); + tc.initial = null; + } else if(!tc.initial) { + if(tc.frozen && !tc.freezeDecel) + tc.yaw = tc.pitch = 0; + else + tc.Decel(tc); + } + this.Transform(tc, tc.pitch, tc.yaw); +}; +TCproto.AnimateDrag = function(w, h, t) { + var tc = this, rs = 100 * t * tc.maxSpeed / tc.max_radius / tc.zoom; + if(tc.dx || tc.dy) { + tc.lx || (tc.yaw = tc.dx * rs / tc.stretchX); + tc.ly || (tc.pitch = tc.dy * -rs / tc.stretchY); + tc.dx = tc.dy = 0; + tc.initial = null; + } else if(!tc.initial) { + tc.Decel(tc); + } + this.Transform(tc, tc.pitch, tc.yaw); +}; +TCproto.Freeze = function() { + if(!this.frozen) { + this.preFreeze = [this.yaw, this.pitch]; + this.frozen = 1; + this.drawn = 0; + } +}; +TCproto.UnFreeze = function() { + if(this.frozen) { + this.yaw = this.preFreeze[0]; + this.pitch = this.preFreeze[1]; + this.frozen = 0; + } +}; +TCproto.Decel = function(tc) { + var s = tc.minSpeed, ay = abs(tc.yaw), ap = abs(tc.pitch); + if(!tc.lx && ay > s) + tc.yaw = ay > tc.z0 ? tc.yaw * tc.decel : 0; + if(!tc.ly && ap > s) + tc.pitch = ap > tc.z0 ? tc.pitch * tc.decel : 0; +}; +TCproto.Zoom = function(r) { + this.z2 = this.z1 * (1/r); + this.drawn = 0; +}; +TCproto.Clicked = function(e) { + var a = this.active; + try { + if(a && a.tag) + if(this.clickToFront === false || this.clickToFront === null) + a.tag.Clicked(e); + else + this.TagToFront(a.tag, this.clickToFront, function() { + a.tag.Clicked(e); + }, true); + } catch(ex) { + } +}; +TCproto.Wheel = function(i) { + var z = this.zoom + this.zoomStep * (i ? 1 : -1); + this.zoom = min(this.zoomMax,max(this.zoomMin,z)); + this.Zoom(this.zoom); +}; +TCproto.BeginDrag = function(e) { + this.down = EventXY(e, this.canvas); + e.cancelBubble = true; + e.returnValue = false; + e.preventDefault && e.preventDefault(); +}; +TCproto.Drag = function(e, p) { + if(this.dragControl && this.down) { + var t2 = this.dragThreshold * this.dragThreshold, + dx = p.x - this.down.x, dy = p.y - this.down.y; + if(this.dragging || dx * dx + dy * dy > t2) { + this.dx = dx; + this.dy = dy; + this.dragging = 1; + this.down = p; + } + } + return this.dragging; +}; +TCproto.EndDrag = function() { + var res = this.dragging; + this.dragging = this.down = null; + return res; +}; +function PinchDistance(e) { + var t1 = e.targetTouches[0], t2 = e.targetTouches[1]; + return sqrt(pow(t2.pageX - t1.pageX, 2) + pow(t2.pageY - t1.pageY, 2)); +} +TCproto.BeginPinch = function(e) { + this.pinched = [PinchDistance(e), this.zoom]; + e.preventDefault && e.preventDefault(); +}; +TCproto.Pinch = function(e) { + var z, d, p = this.pinched; + if(!p) + return; + d = PinchDistance(e); + z = p[1] * d / p[0]; + this.zoom = min(this.zoomMax,max(this.zoomMin,z)); + this.Zoom(this.zoom); +}; +TCproto.EndPinch = function(e) { + this.pinched = null; +}; +TCproto.Pause = function() { this.paused = true; }; +TCproto.Resume = function() { this.paused = false; }; +TCproto.SetSpeed = function(i) { + this.initial = i; + this.yaw = i[0] * this.maxSpeed; + this.pitch = i[1] * this.maxSpeed; +}; +TCproto.FindTag = function(t) { + if(!Defined(t)) + return null; + Defined(t.index) && (t = t.index); + if(!IsObject(t)) + return this.taglist[t]; + var srch, tgt, i; + if(Defined(t.id)) + srch = 'id', tgt = t.id; + else if(Defined(t.text)) + srch = 'innerText', tgt = t.text; + + for(i = 0; i < this.taglist.length; ++i) + if(this.taglist[i].a[srch] == tgt) + return this.taglist[i]; +}; +TCproto.RotateTag = function(tag, lt, lg, time, callback, active) { + var t = tag.Calc(this.transform, 1), v1 = new Vector(t.x, t.y, t.z), + v2 = MakeVector(lg, lt), angle = v1.angle(v2), u = v1.cross(v2).unit(); + if(angle == 0) { + this.fixedCallbackTag = tag; + this.fixedCallback = callback; + } else { + this.fixedAnim = { + angle: -angle, + axis: u, + t: time, + t0: TimeNow(), + cb: callback, + tag: tag, + active: active + }; + } +}; +TCproto.TagToFront = function(tag, time, callback, active) { + this.RotateTag(tag, 0, 0, time, callback, active); +}; +TagCanvas.Start = function(id,l,o) { + TagCanvas.Delete(id); + TagCanvas.tc[id] = new TagCanvas(id,l,o); +}; +function tccall(f,id) { + TagCanvas.tc[id] && TagCanvas.tc[id][f](); +} +TagCanvas.Linear = function(t, t0) { return t0 / t; } +TagCanvas.Smooth = function(t, t0) { return 0.5 - cos(t0 * Math.PI / t) / 2; } +TagCanvas.Pause = function(id) { tccall('Pause',id); }; +TagCanvas.Resume = function(id) { tccall('Resume',id); }; +TagCanvas.Reload = function(id) { tccall('Load',id); }; +TagCanvas.Update = function(id) { tccall('Update',id); }; +TagCanvas.SetSpeed = function(id, speed) { + if(IsObject(speed) && TagCanvas.tc[id] && + !isNaN(speed[0]) && !isNaN(speed[1])) { + TagCanvas.tc[id].SetSpeed(speed); + return true; + } + return false; +}; +TagCanvas.TagToFront = function(id, options) { + if(!IsObject(options)) + return false; + options.lat = options.lng = 0; + return TagCanvas.RotateTag(id, options); +}; +TagCanvas.RotateTag = function(id, options) { + if(IsObject(options) && TagCanvas.tc[id]) { + if(isNaN(options.time)) + options.time = 500; + var tt = TagCanvas.tc[id].FindTag(options); + if(tt) { + TagCanvas.tc[id].RotateTag(tt, options.lat, options.lng, + options.time, options.callback, options.active); + return true; + } + } + return false; +}; +TagCanvas.Delete = function(id) { + var i, c; + if(handlers[id]) { + c = doc.getElementById(id); + if(c) { + for(i = 0; i < handlers[id].length; ++i) + RemoveHandler(handlers[id][i][0], handlers[id][i][1], c); + } + } + delete handlers[id]; + delete TagCanvas.tc[id]; +}; +TagCanvas.NextFrameRAF = function() { + requestAnimationFrame(DrawCanvasRAF); +}; +TagCanvas.NextFrameTimeout = function(iv) { + setTimeout(DrawCanvas, iv); +}; +TagCanvas.tc = {}; +TagCanvas.options = { +z1: 20000, +z2: 20000, +z0: 0.0002, +freezeActive: true, +freezeDecel: false, +activeCursor: 'pointer', +pulsateTo: 1, +pulsateTime: 3, +reverse: false, +depth: 0.5, +maxSpeed: 0.05, +minSpeed: 0, +decel: 0.95, +interval: 20, +minBrightness: 0.1, +maxBrightness: 1, +outlineColour: '', +outlineThickness: 2, +outlineOffset: 5, +outlineMethod: 'outline', +outlineRadius: 0, +textColour: ['#222', '#000'], +textHeight: 15, +textFont: 'Helvetica, Arial, sans-serif', +shadow: '#111', +shadowBlur: 1, +shadowOffset: [0.1,0.1], +initial: null, +hideTags: false, +zoom: 0, +weight: false, +weightMode: 'size', +weightFrom: null, +weightSize: 1, +weightSizeMin: null, +weightSizeMax: null, +weightGradient: {0:'#f00', 0.33:'#ff0', 0.66:'#0f0', 1:'#00f'}, +txtOpt: true, +txtScale: 2, +frontSelect: false, +wheelZoom: true, +zoomMin: 0.8, +zoomMax: 0.8, +zoomStep: 0.05, +shape: 'sphere', +lock: null, +tooltip: null, +tooltipDelay: 300, +tooltipClass: 'tctooltip', +radiusX: 1, +radiusY: 1, +radiusZ: 1, +stretchX: 1, +stretchY: 1, +offsetX: 0, +offsetY: 0, +shuffleTags: false, +noSelect: false, +noMouse: false, +imageScale: 1, +paused: false, +dragControl: false, +dragThreshold: 4, +centreFunc: Nop, +splitWidth: 0, +animTiming: 'Smooth', +clickToFront: false, +fadeIn: 0, +padding: 0, +bgColour: null, +bgRadius: 0, +bgOutline: null, +bgOutlineThickness: 0, +outlineIncrease: 4, +textAlign: 'centre', +textVAlign: 'middle', +imageMode: null, +imagePosition: null, +imagePadding: 2, +imageAlign: 'centre', +imageVAlign: 'middle', +noTagsMessage: true, +centreImage: null, +pinchZoom: false, +repeatTags: 0, +minTags: 0, +imageRadius: 0, +scrollPause: false, +outlineDash: 0, +outlineDashSpace: 0, +outlineDashSpeed: 1 +}; +for(i in TagCanvas.options) TagCanvas[i] = TagCanvas.options[i]; +window.TagCanvas = TagCanvas; +// set a flag for when the window has loaded +AddHandler('load',function(){TagCanvas.loaded=1},window); +})(); diff --git a/js/tagcloud.js b/js/tagcloud.js new file mode 100644 index 0000000..a36284d --- /dev/null +++ b/js/tagcloud.js @@ -0,0 +1 @@ +function addLoadEvent(func) {var oldonload = window.onload;if (typeof window.onload != 'function') {window.onload = func;} else {window.onload = function() {oldonload();func();}}}addLoadEvent(function() {console.log('tag cloud plugin rock and roll!'); try { TagCanvas.textFont = 'Trebuchet MS, Helvetica'; TagCanvas.textColour = '#333'; TagCanvas.textHeight = 25; TagCanvas.outlineColour = '#E2E1C1'; TagCanvas.outlineMethod = 'block'; TagCanvas.maxSpeed = 0.03; TagCanvas.minBrightness = 0.2; TagCanvas.depth = 0.92; TagCanvas.pulsateTo = 0.6; TagCanvas.initial = [0.1,-0.1]; TagCanvas.decel = 0.98; TagCanvas.reverse = true; TagCanvas.hideTags = false; TagCanvas.shadow = '#ccf'; TagCanvas.shadowBlur = 3; TagCanvas.weight = false; TagCanvas.imageScale = null; TagCanvas.fadeIn = 1000; TagCanvas.clickToFront = 600; TagCanvas.Start('resCanvas'); TagCanvas.tc['resCanvas'].Wheel(false)} catch(e) { console.log(e); document.getElementById('myCanvasContainer').style.display = 'none'; } }); \ No newline at end of file diff --git a/js/third-party/analytics/baidu-analytics.js b/js/third-party/analytics/baidu-analytics.js new file mode 100644 index 0000000..c10e7d0 --- /dev/null +++ b/js/third-party/analytics/baidu-analytics.js @@ -0,0 +1,7 @@ +/* global _hmt */ + +if (!window._hmt) window._hmt = []; + +document.addEventListener('pjax:success', () => { + _hmt.push(['_trackPageview', location.pathname]); +}); diff --git a/js/third-party/analytics/google-analytics.js b/js/third-party/analytics/google-analytics.js new file mode 100644 index 0000000..2cd128f --- /dev/null +++ b/js/third-party/analytics/google-analytics.js @@ -0,0 +1,35 @@ +/* global CONFIG, dataLayer, gtag */ + +if (!CONFIG.google_analytics.only_pageview) { + if (CONFIG.hostname === location.hostname) { + window.dataLayer = window.dataLayer || []; + window.gtag = function() { + dataLayer.push(arguments); + }; + gtag('js', new Date()); + gtag('config', CONFIG.google_analytics.tracking_id); + + document.addEventListener('pjax:success', () => { + gtag('event', 'page_view', { + page_location: location.href, + page_path : location.pathname, + page_title : document.title + }); + }); + } +} else { + const sendPageView = () => { + if (CONFIG.hostname !== location.hostname) return; + const uid = localStorage.getItem('uid') || (Math.random() + '.' + Math.random()); + localStorage.setItem('uid', uid); + navigator.sendBeacon('https://www.google-analytics.com/collect', new URLSearchParams({ + v : 1, + tid: CONFIG.google_analytics.tracking_id, + cid: uid, + t : 'pageview', + dp : encodeURIComponent(location.pathname) + })); + }; + document.addEventListener('pjax:complete', sendPageView); + sendPageView(); +} diff --git a/js/third-party/analytics/growingio.js b/js/third-party/analytics/growingio.js new file mode 100644 index 0000000..0460833 --- /dev/null +++ b/js/third-party/analytics/growingio.js @@ -0,0 +1,10 @@ +/* global CONFIG, gio */ + +if (!window.gio) { + window.gio = function() { + (window.gio.q = window.gio.q || []).push(arguments); + }; +} + +gio('init', `${CONFIG.growingio_analytics}`, {}); +gio('send'); diff --git a/js/third-party/analytics/matomo.js b/js/third-party/analytics/matomo.js new file mode 100644 index 0000000..290a3e0 --- /dev/null +++ b/js/third-party/analytics/matomo.js @@ -0,0 +1,19 @@ +/* global CONFIG */ + +if (CONFIG.matomo.enable) { + window._paq = window._paq || []; + const _paq = window._paq; + + /* tracker methods like "setCustomDimension" should be called before "trackPageView" */ + _paq.push(['trackPageView']); + _paq.push(['enableLinkTracking']); + const u = CONFIG.matomo.server_url; + _paq.push(['setTrackerUrl', u + 'matomo.php']); + _paq.push(['setSiteId', CONFIG.matomo.site_id]); + const d = document; + const g = d.createElement('script'); + const s = d.getElementsByTagName('script')[0]; + g.async = true; + g.src = u + 'matomo.js'; + s.parentNode.insertBefore(g, s); +} diff --git a/js/third-party/chat/chatra.js b/js/third-party/chat/chatra.js new file mode 100644 index 0000000..e495b8e --- /dev/null +++ b/js/third-party/chat/chatra.js @@ -0,0 +1,19 @@ +/* global CONFIG, Chatra */ + +(function() { + if (CONFIG.chatra.embed) { + window.ChatraSetup = { + mode : 'frame', + injectTo: CONFIG.chatra.embed + }; + } + + window.ChatraID = CONFIG.chatra.id; + + const chatButton = document.querySelector('.sidebar-button button'); + if (chatButton) { + chatButton.addEventListener('click', () => { + Chatra('openChat', true); + }); + } +})(); diff --git a/js/third-party/chat/gitter.js b/js/third-party/chat/gitter.js new file mode 100644 index 0000000..2b26d05 --- /dev/null +++ b/js/third-party/chat/gitter.js @@ -0,0 +1,5 @@ +/* global CONFIG */ + +((window.gitter = {}).chat = {}).options = { + room: CONFIG.gitter.room +}; diff --git a/js/third-party/chat/tidio.js b/js/third-party/chat/tidio.js new file mode 100644 index 0000000..bffb918 --- /dev/null +++ b/js/third-party/chat/tidio.js @@ -0,0 +1,10 @@ +/* global tidioChatApi */ + +(function() { + const chatButton = document.querySelector('.sidebar-button button'); + if (chatButton) { + chatButton.addEventListener('click', () => { + tidioChatApi.open(); + }); + } +})(); diff --git a/js/third-party/comments/changyan.js b/js/third-party/comments/changyan.js new file mode 100644 index 0000000..18a1be4 --- /dev/null +++ b/js/third-party/comments/changyan.js @@ -0,0 +1,39 @@ +/* global NexT, CONFIG */ + +document.addEventListener('page:loaded', () => { + const { appid, appkey } = CONFIG.changyan; + const mainJs = 'https://cy-cdn.kuaizhan.com/upload/changyan.js'; + const countJs = `https://cy-cdn.kuaizhan.com/upload/plugins/plugins.list.count.js?clientId=${appid}`; + + // Get the number of comments + setTimeout(() => { + return NexT.utils.getScript(countJs, { + attributes: { + async: true, + id : 'cy_cmt_num' + } + }); + }, 0); + + // When scroll to comment section + if (CONFIG.page.comments && !CONFIG.page.isHome) { + NexT.utils.loadComments('#SOHUCS') + .then(() => { + return NexT.utils.getScript(mainJs, { + attributes: { + async: true + } + }); + }) + .then(() => { + window.changyan.api.config({ + appid, + conf: appkey + }); + }) + .catch(error => { + // eslint-disable-next-line no-console + console.error('Failed to load Changyan', error); + }); + } +}); diff --git a/js/third-party/comments/disqus.js b/js/third-party/comments/disqus.js new file mode 100644 index 0000000..4d1ca9e --- /dev/null +++ b/js/third-party/comments/disqus.js @@ -0,0 +1,41 @@ +/* global NexT, CONFIG, DISQUS */ + +document.addEventListener('page:loaded', () => { + + if (CONFIG.disqus.count) { + if (window.DISQUSWIDGETS) { + window.DISQUSWIDGETS.getCount({ reset: true }); + } else { + // Defer loading until the whole page loading is completed + NexT.utils.getScript(`https://${CONFIG.disqus.shortname}.disqus.com/count.js`, { + attributes: { id: 'dsq-count-scr', defer: true } + }); + } + } + + if (CONFIG.page.comments) { + // `disqus_config` should be a global variable + // See https://help.disqus.com/en/articles/1717084-javascript-configuration-variables + window.disqus_config = function() { + this.page.url = CONFIG.page.permalink; + this.page.identifier = CONFIG.page.path; + this.page.title = CONFIG.page.title; + if (CONFIG.disqus.i18n.disqus !== 'disqus') { + this.language = CONFIG.disqus.i18n.disqus; + } + }; + NexT.utils.loadComments('#disqus_thread').then(() => { + if (window.DISQUS) { + DISQUS.reset({ + reload: true, + config: window.disqus_config + }); + } else { + NexT.utils.getScript(`https://${CONFIG.disqus.shortname}.disqus.com/embed.js`, { + attributes: { dataset: { timestamp: '' + +new Date() } } + }); + } + }); + } + +}); diff --git a/js/third-party/comments/disqusjs.js b/js/third-party/comments/disqusjs.js new file mode 100644 index 0000000..d8401ee --- /dev/null +++ b/js/third-party/comments/disqusjs.js @@ -0,0 +1,23 @@ +/* global NexT, CONFIG, DisqusJS */ + +document.addEventListener('page:loaded', () => { + if (!CONFIG.page.comments) return; + + NexT.utils.loadComments('#disqus_thread') + .then(() => NexT.utils.getScript(CONFIG.disqusjs.js, { condition: window.DisqusJS })) + .then(() => { + window.dsqjs = new DisqusJS({ + api : CONFIG.disqusjs.api || 'https://disqus.com/api/', + apikey : CONFIG.disqusjs.apikey, + shortname : CONFIG.disqusjs.shortname, + url : CONFIG.page.permalink, + identifier: CONFIG.page.path, + title : CONFIG.page.title + }); + window.dsqjs.render(document.querySelector('.disqusjs-container')); + }); +}); + +document.addEventListener('pjax:send', () => { + if (window.dsqjs) window.dsqjs.destroy(); +}); diff --git a/js/third-party/comments/gitalk.js b/js/third-party/comments/gitalk.js new file mode 100644 index 0000000..08d07f4 --- /dev/null +++ b/js/third-party/comments/gitalk.js @@ -0,0 +1,24 @@ +/* global NexT, CONFIG, Gitalk */ + +document.addEventListener('page:loaded', () => { + if (!CONFIG.page.comments) return; + + NexT.utils.loadComments('.gitalk-container') + .then(() => NexT.utils.getScript(CONFIG.gitalk.js, { + condition: window.Gitalk + })) + .then(() => { + const gitalk = new Gitalk({ + clientID : CONFIG.gitalk.client_id, + clientSecret : CONFIG.gitalk.client_secret, + repo : CONFIG.gitalk.repo, + owner : CONFIG.gitalk.github_id, + admin : [CONFIG.gitalk.admin_user], + id : CONFIG.gitalk.path_md5, + proxy : CONFIG.gitalk.proxy, + language : CONFIG.gitalk.language || window.navigator.language, + distractionFreeMode: CONFIG.gitalk.distraction_free_mode + }); + gitalk.render(document.querySelector('.gitalk-container')); + }); +}); diff --git a/js/third-party/comments/isso.js b/js/third-party/comments/isso.js new file mode 100644 index 0000000..2c70601 --- /dev/null +++ b/js/third-party/comments/isso.js @@ -0,0 +1,15 @@ +/* global NexT, CONFIG */ + +document.addEventListener('page:loaded', () => { + if (!CONFIG.page.comments) return; + + NexT.utils.loadComments('#isso-thread') + .then(() => NexT.utils.getScript(`${CONFIG.isso}js/embed.min.js`, { + attributes: { + dataset: { + isso: `${CONFIG.isso}` + } + }, + parentNode: document.querySelector('#isso-thread') + })); +}); diff --git a/js/third-party/comments/livere.js b/js/third-party/comments/livere.js new file mode 100644 index 0000000..c4bcd2e --- /dev/null +++ b/js/third-party/comments/livere.js @@ -0,0 +1,19 @@ +/* global NexT, CONFIG, LivereTower */ + +document.addEventListener('page:loaded', () => { + if (!CONFIG.page.comments) return; + + NexT.utils.loadComments('#lv-container').then(() => { + window.livereOptions = { + refer: CONFIG.page.path.replace(/index\.html$/, '') + }; + + if (typeof LivereTower === 'function') return; + + NexT.utils.getScript('https://cdn-city.livere.com/js/embed.dist.js', { + attributes: { + async: true + } + }); + }); +}); diff --git a/js/third-party/comments/utterances.js b/js/third-party/comments/utterances.js new file mode 100644 index 0000000..332ee05 --- /dev/null +++ b/js/third-party/comments/utterances.js @@ -0,0 +1,17 @@ +/* global NexT, CONFIG */ + +document.addEventListener('page:loaded', () => { + if (!CONFIG.page.comments) return; + + NexT.utils.loadComments('.utterances-container') + .then(() => NexT.utils.getScript('https://utteranc.es/client.js', { + attributes: { + async : true, + crossOrigin : 'anonymous', + 'repo' : CONFIG.utterances.repo, + 'issue-term': CONFIG.utterances.issue_term, + 'theme' : CONFIG.utterances.theme + }, + parentNode: document.querySelector('.utterances-container') + })); +}); diff --git a/js/third-party/fancybox.js b/js/third-party/fancybox.js new file mode 100644 index 0000000..bb436ab --- /dev/null +++ b/js/third-party/fancybox.js @@ -0,0 +1,38 @@ +document.addEventListener('page:loaded', () => { + + /** + * Wrap images with fancybox. + */ + document.querySelectorAll('.post-body :not(a) > img, .post-body > img').forEach(element => { + const $image = $(element); + const imageLink = $image.attr('data-src') || $image.attr('src'); + const $imageWrapLink = $image.wrap(``).parent('a'); + if ($image.is('.post-gallery img')) { + $imageWrapLink.attr('data-fancybox', 'gallery').attr('rel', 'gallery'); + } else if ($image.is('.group-picture img')) { + $imageWrapLink.attr('data-fancybox', 'group').attr('rel', 'group'); + } else { + $imageWrapLink.attr('data-fancybox', 'default').attr('rel', 'default'); + } + + const imageTitle = $image.attr('title') || $image.attr('alt'); + if (imageTitle) { + // Do not append image-caption if pandoc has already created a figcaption + if (!$imageWrapLink.next('figcaption').length) { + $imageWrapLink.append(`

${imageTitle}

`); + } + // Make sure img title tag will show correctly in fancybox + $imageWrapLink.attr('title', imageTitle).attr('data-caption', imageTitle); + } + }); + + $.fancybox.defaults.hash = false; + $('.fancybox').fancybox({ + loop : true, + helpers: { + overlay: { + locked: false + } + } + }); +}); diff --git a/js/third-party/math/katex.js b/js/third-party/math/katex.js new file mode 100644 index 0000000..ad745b1 --- /dev/null +++ b/js/third-party/math/katex.js @@ -0,0 +1,7 @@ +/* global NexT, CONFIG */ + +document.addEventListener('page:loaded', () => { + if (!CONFIG.enableMath) return; + + NexT.utils.getScript(CONFIG.katex.copy_tex_js).catch(() => {}); +}); diff --git a/js/third-party/math/mathjax.js b/js/third-party/math/mathjax.js new file mode 100644 index 0000000..fe4d448 --- /dev/null +++ b/js/third-party/math/mathjax.js @@ -0,0 +1,36 @@ +/* global NexT, CONFIG, MathJax */ + +document.addEventListener('page:loaded', () => { + if (!CONFIG.enableMath) return; + + if (typeof MathJax === 'undefined') { + window.MathJax = { + tex: { + inlineMath: { '[+]': [['$', '$']] }, + tags : CONFIG.mathjax.tags + }, + options: { + renderActions: { + insertedScript: [200, () => { + document.querySelectorAll('mjx-container').forEach(node => { + const target = node.parentNode; + if (target.nodeName.toLowerCase() === 'li') { + target.parentNode.classList.add('has-jax'); + } + }); + }, '', false] + } + } + }; + NexT.utils.getScript(CONFIG.mathjax.js, { + attributes: { + defer: true + } + }); + } else { + MathJax.startup.document.state(0); + MathJax.typesetClear(); + MathJax.texReset(); + MathJax.typesetPromise(); + } +}); diff --git a/js/third-party/pace.js b/js/third-party/pace.js new file mode 100644 index 0000000..c22d59f --- /dev/null +++ b/js/third-party/pace.js @@ -0,0 +1,7 @@ +/* global Pace */ + +Pace.options.restartOnPushState = false; + +document.addEventListener('pjax:send', () => { + Pace.restart(); +}); diff --git a/js/third-party/quicklink.js b/js/third-party/quicklink.js new file mode 100644 index 0000000..2543ad1 --- /dev/null +++ b/js/third-party/quicklink.js @@ -0,0 +1,37 @@ +/* global CONFIG, quicklink */ + +(function() { + if (typeof CONFIG.quicklink.ignores === 'string') { + const ignoresStr = `[${CONFIG.quicklink.ignores}]`; + CONFIG.quicklink.ignores = JSON.parse(ignoresStr); + } + + let resetFn = null; + + const onRefresh = () => { + if (resetFn) resetFn(); + if (!CONFIG.quicklink.enable) return; + + let ignoresArr = CONFIG.quicklink.ignores || []; + if (!Array.isArray(ignoresArr)) { + ignoresArr = [ignoresArr]; + } + + resetFn = quicklink.listen({ + timeout : CONFIG.quicklink.timeout, + priority: CONFIG.quicklink.priority, + ignores : [ + uri => uri.includes('#'), + uri => uri === CONFIG.quicklink.url, + ...ignoresArr + ] + }); + }; + + if (CONFIG.quicklink.delay) { + window.addEventListener('load', onRefresh); + document.addEventListener('pjax:success', onRefresh); + } else { + document.addEventListener('page:loaded', onRefresh); + } +})(); diff --git a/js/third-party/search/algolia-search.js b/js/third-party/search/algolia-search.js new file mode 100644 index 0000000..12a554c --- /dev/null +++ b/js/third-party/search/algolia-search.js @@ -0,0 +1,130 @@ +/* global instantsearch, algoliasearch, CONFIG, pjax */ + +document.addEventListener('DOMContentLoaded', () => { + const { indexName, appID, apiKey, hits } = CONFIG.algolia; + + const search = instantsearch({ + indexName, + searchClient : algoliasearch(appID, apiKey), + searchFunction: helper => { + if (document.querySelector('.search-input').value) { + helper.search(); + } + } + }); + + if (typeof pjax === 'object') { + search.on('render', () => { + pjax.refresh(document.querySelector('.algolia-hits')); + }); + } + + // Registering Widgets + search.addWidgets([ + instantsearch.widgets.configure({ + hitsPerPage: hits.per_page || 10 + }), + + instantsearch.widgets.searchBox({ + container : '.search-input-container', + placeholder : CONFIG.i18n.placeholder, + // Hide default icons of algolia search + showReset : false, + showSubmit : false, + showLoadingIndicator: false, + cssClasses : { + input: 'search-input' + } + }), + + instantsearch.widgets.stats({ + container: '.algolia-stats', + templates: { + text: data => { + const stats = CONFIG.i18n.hits_time + .replace('${hits}', data.nbHits) + .replace('${time}', data.processingTimeMS); + return `${stats} + Algolia`; + } + }, + cssClasses: { + text: 'search-stats' + } + }), + + instantsearch.widgets.hits({ + container : '.algolia-hits', + escapeHTML: false, + templates : { + item: data => { + const { title, excerpt, excerptStrip, contentStripTruncate } = data._highlightResult; + let result = `${title.value}`; + const content = excerpt || excerptStrip || contentStripTruncate; + if (content && content.value) { + const div = document.createElement('div'); + div.innerHTML = content.value; + result += `

${div.textContent.substring(0, 100)}...

`; + } + return result; + }, + empty: data => { + return `
+ ${CONFIG.i18n.empty.replace('${query}', data.query)} +
`; + } + }, + cssClasses: { + list: 'search-result-list' + } + }), + + instantsearch.widgets.pagination({ + container: '.algolia-pagination', + scrollTo : false, + showFirst: false, + showLast : false, + templates: { + first : '', + last : '', + previous: '', + next : '' + }, + cssClasses: { + list : ['pagination', 'algolia-pagination'], + item : 'pagination-item', + link : 'page-number', + selectedItem: 'current', + disabledItem: 'disabled-item' + } + }) + ]); + + search.start(); + + // Handle and trigger popup window + document.querySelectorAll('.popup-trigger').forEach(element => { + element.addEventListener('click', () => { + document.body.classList.add('search-active'); + setTimeout(() => document.querySelector('.search-input').focus(), 500); + }); + }); + + // Monitor main search box + const onPopupClose = () => { + document.body.classList.remove('search-active'); + }; + + document.querySelector('.search-pop-overlay').addEventListener('click', event => { + if (event.target === document.querySelector('.search-pop-overlay')) { + onPopupClose(); + } + }); + document.querySelector('.popup-btn-close').addEventListener('click', onPopupClose); + document.addEventListener('pjax:success', onPopupClose); + window.addEventListener('keyup', event => { + if (event.key === 'Escape') { + onPopupClose(); + } + }); +}); diff --git a/js/third-party/search/local-search.js b/js/third-party/search/local-search.js new file mode 100644 index 0000000..92a264d --- /dev/null +++ b/js/third-party/search/local-search.js @@ -0,0 +1,99 @@ +/* global CONFIG, pjax, LocalSearch */ + +document.addEventListener('DOMContentLoaded', () => { + if (!CONFIG.path) { + // Search DB path + console.warn('`hexo-generator-searchdb` plugin is not installed!'); + return; + } + const localSearch = new LocalSearch({ + path : CONFIG.path, + top_n_per_article: CONFIG.localsearch.top_n_per_article, + unescape : CONFIG.localsearch.unescape + }); + + const input = document.querySelector('.search-input'); + + const inputEventFunction = () => { + if (!localSearch.isfetched) return; + const searchText = input.value.trim().toLowerCase(); + const keywords = searchText.split(/[-\s]+/); + const container = document.querySelector('.search-result-container'); + let resultItems = []; + if (searchText.length > 0) { + // Perform local searching + resultItems = localSearch.getResultItems(keywords); + } + if (keywords.length === 1 && keywords[0] === '') { + container.classList.add('no-result'); + container.innerHTML = '
'; + } else if (resultItems.length === 0) { + container.classList.add('no-result'); + container.innerHTML = '
'; + } 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 = CONFIG.i18n.hits.replace('${hits}', resultItems.length); + + container.classList.remove('no-result'); + container.innerHTML = `
${stats}
+
+
    ${resultItems.map(result => result.item).join('')}
`; + if (typeof pjax === 'object') pjax.refresh(container); + } + }; + + localSearch.highlightSearchWords(document.querySelector('.post-body')); + if (CONFIG.localsearch.preload) { + localSearch.fetchData(); + } + + if (CONFIG.localsearch.trigger === 'auto') { + input.addEventListener('input', inputEventFunction); + } else { + document.querySelector('.search-icon').addEventListener('click', inputEventFunction); + input.addEventListener('keypress', event => { + if (event.key === 'Enter') { + inputEventFunction(); + } + }); + } + window.addEventListener('search:loaded', inputEventFunction); + + // Handle and trigger popup window + document.querySelectorAll('.popup-trigger').forEach(element => { + element.addEventListener('click', () => { + document.body.classList.add('search-active'); + // Wait for search-popup animation to complete + setTimeout(() => input.focus(), 500); + if (!localSearch.isfetched) localSearch.fetchData(); + }); + }); + + // Monitor main search box + const onPopupClose = () => { + document.body.classList.remove('search-active'); + }; + + document.querySelector('.search-pop-overlay').addEventListener('click', event => { + if (event.target === document.querySelector('.search-pop-overlay')) { + onPopupClose(); + } + }); + document.querySelector('.popup-btn-close').addEventListener('click', onPopupClose); + document.addEventListener('pjax:success', () => { + localSearch.highlightSearchWords(document.querySelector('.post-body')); + onPopupClose(); + }); + window.addEventListener('keyup', event => { + if (event.key === 'Escape') { + onPopupClose(); + } + }); +}); diff --git a/js/third-party/statistics/firestore.js b/js/third-party/statistics/firestore.js new file mode 100644 index 0000000..3ea7ba6 --- /dev/null +++ b/js/third-party/statistics/firestore.js @@ -0,0 +1,60 @@ +/* global CONFIG, firebase */ + +firebase.initializeApp({ + apiKey : CONFIG.firestore.apiKey, + projectId: CONFIG.firestore.projectId +}); + +(function() { + const getCount = (doc, increaseCount) => { + // IncreaseCount will be false when not in article page + return doc.get().then(d => { + // Has no data, initialize count + let count = d.exists ? d.data().count : 0; + // If first view this article + if (increaseCount) { + // Increase count + count++; + doc.set({ + count + }); + } + return count; + }); + }; + + const db = firebase.firestore(); + const articles = db.collection(CONFIG.firestore.collection); + + document.addEventListener('page:loaded', () => { + + if (CONFIG.page.isPost) { + // Fix issue #118 + // https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent + const title = document.querySelector('.post-title').textContent.trim(); + const doc = articles.doc(title); + let increaseCount = CONFIG.hostname === location.hostname; + if (localStorage.getItem(title)) { + increaseCount = false; + } else { + // Mark as visited + localStorage.setItem(title, true); + } + getCount(doc, increaseCount).then(count => { + document.querySelector('.firestore-visitors-count').innerText = count; + }); + } else if (CONFIG.page.isHome) { + const promises = [...document.querySelectorAll('.post-title')].map(element => { + const title = element.textContent.trim(); + const doc = articles.doc(title); + return getCount(doc); + }); + Promise.all(promises).then(counts => { + const metas = document.querySelectorAll('.firestore-visitors-count'); + counts.forEach((val, idx) => { + metas[idx].innerText = val; + }); + }); + } + }); +})(); diff --git a/js/third-party/statistics/lean-analytics.js b/js/third-party/statistics/lean-analytics.js new file mode 100644 index 0000000..8397112 --- /dev/null +++ b/js/third-party/statistics/lean-analytics.js @@ -0,0 +1,107 @@ +/* global CONFIG */ +/* eslint-disable no-console */ + +(function() { + const leancloudSelector = url => { + url = encodeURI(url); + return document.getElementById(url).querySelector('.leancloud-visitors-count'); + }; + + const addCount = Counter => { + const visitors = document.querySelector('.leancloud_visitors'); + const url = decodeURI(visitors.id); + const title = visitors.dataset.flagTitle; + + Counter('get', `/classes/Counter?where=${encodeURIComponent(JSON.stringify({ url }))}`) + .then(response => response.json()) + .then(({ results }) => { + if (results.length > 0) { + const counter = results[0]; + leancloudSelector(url).innerText = counter.time + 1; + Counter('put', '/classes/Counter/' + counter.objectId, { + time: { + '__op' : 'Increment', + 'amount': 1 + } + }) + .catch(error => { + console.error('Failed to save visitor count', error); + }); + } else if (CONFIG.leancloud_visitors.security) { + leancloudSelector(url).innerText = 'Counter not initialized! More info at console err msg.'; + console.error('ATTENTION! LeanCloud counter has security bug, see how to solve it here: https://github.com/theme-next/hexo-leancloud-counter-security. \n However, you can still use LeanCloud without security, by setting `security` option to `false`.'); + } else { + Counter('post', '/classes/Counter', { title, url, time: 1 }) + .then(response => response.json()) + .then(() => { + leancloudSelector(url).innerText = 1; + }) + .catch(error => { + console.error('Failed to create', error); + }); + } + }) + .catch(error => { + console.error('LeanCloud Counter Error', error); + }); + }; + + const showTime = Counter => { + const visitors = document.querySelectorAll('.leancloud_visitors'); + const entries = [...visitors].map(element => { + return decodeURI(element.id); + }); + + Counter('get', `/classes/Counter?where=${encodeURIComponent(JSON.stringify({ url: { '$in': entries } }))}`) + .then(response => response.json()) + .then(({ results }) => { + for (const url of entries) { + const target = results.find(item => item.url === url); + leancloudSelector(url).innerText = target ? target.time : 0; + } + }) + .catch(error => { + console.error('LeanCloud Counter Error', error); + }); + }; + + const { app_id, app_key, server_url } = CONFIG.leancloud_visitors; + const fetchData = api_server => { + const Counter = (method, url, data) => { + return fetch(`${api_server}/1.1${url}`, { + method, + headers: { + 'X-LC-Id' : app_id, + 'X-LC-Key' : app_key, + 'Content-Type': 'application/json' + }, + body: JSON.stringify(data) + }); + }; + if (CONFIG.page.isPost) { + if (CONFIG.hostname !== location.hostname) return; + addCount(Counter); + } else if (document.querySelectorAll('.post-title-link').length >= 1) { + showTime(Counter); + } + }; + + let api_server; + if (server_url) { + api_server = server_url; + } else if (app_id.slice(-9) === '-MdYXbMMI') { + api_server = `https://${app_id.slice(0, 8).toLowerCase()}.api.lncldglobal.com`; + } + + document.addEventListener('page:loaded', () => { + if (api_server) { + fetchData(api_server); + } else { + fetch(`https://app-router.leancloud.cn/2/route?appId=${app_id}`) + .then(response => response.json()) + .then(({ api_server }) => { + fetchData(`https://${api_server}`); + }); + } + }); +})(); diff --git a/js/third-party/tags/mermaid.js b/js/third-party/tags/mermaid.js new file mode 100644 index 0000000..9623dc5 --- /dev/null +++ b/js/third-party/tags/mermaid.js @@ -0,0 +1,32 @@ +/* global NexT, CONFIG, mermaid */ + +document.addEventListener('page:loaded', () => { + const mermaidElements = document.querySelectorAll('.mermaid'); + if (mermaidElements.length) { + NexT.utils.getScript(CONFIG.mermaid.js, { + condition: window.mermaid + }).then(() => { + mermaidElements.forEach(element => { + const newElement = document.createElement('div'); + newElement.innerHTML = element.innerHTML; + newElement.className = element.className; + const parent = element.parentNode; + // Fix issue #347 + // Support mermaid inside backtick code block + if (parent.matches('pre')) { + parent.parentNode.replaceChild(newElement, parent); + } else { + parent.replaceChild(newElement, element); + } + }); + mermaid.initialize({ + theme : CONFIG.darkmode && window.matchMedia('(prefers-color-scheme: dark)').matches ? CONFIG.mermaid.theme.dark : CONFIG.mermaid.theme.light, + logLevel : 4, + flowchart: { curve: 'linear' }, + gantt : { axisFormat: '%m/%d/%Y' }, + sequence : { actorMargin: 50 } + }); + mermaid.init(); + }); + } +}); diff --git a/js/third-party/tags/pdf.js b/js/third-party/tags/pdf.js new file mode 100644 index 0000000..7e82891 --- /dev/null +++ b/js/third-party/tags/pdf.js @@ -0,0 +1,23 @@ +/* global NexT, CONFIG, PDFObject */ + +document.addEventListener('page:loaded', () => { + if (document.querySelectorAll('.pdf-container').length) { + NexT.utils.getScript(CONFIG.pdf.object_url, { + condition: window.PDFObject + }).then(() => { + document.querySelectorAll('.pdf-container').forEach(element => { + PDFObject.embed(element.dataset.target, element, { + pdfOpenParams: { + navpanes : 0, + toolbar : 0, + statusbar: 0, + pagemode : 'thumbs', + view : 'FitH' + }, + PDFJS_URL: CONFIG.pdf.url, + height : element.dataset.height + }); + }); + }); + } +}); diff --git a/js/utils.js b/js/utils.js new file mode 100644 index 0000000..ee10f61 --- /dev/null +++ b/js/utils.js @@ -0,0 +1,452 @@ +/* global NexT, CONFIG */ + +HTMLElement.prototype.wrap = function(wrapper) { + this.parentNode.insertBefore(wrapper, this); + this.parentNode.removeChild(this); + wrapper.appendChild(this); +}; + +(function() { + const onPageLoaded = () => document.dispatchEvent( + new Event('page:loaded', { + bubbles: true + }) + ); + + if (document.readyState === 'loading') { + document.addEventListener('readystatechange', onPageLoaded, { once: true }); + } else { + onPageLoaded(); + } + document.addEventListener('pjax:success', onPageLoaded); +})(); + +NexT.utils = { + + registerExtURL: function() { + document.querySelectorAll('span.exturl').forEach(element => { + const link = document.createElement('a'); + // https://stackoverflow.com/questions/30106476/using-javascripts-atob-to-decode-base64-doesnt-properly-decode-utf-8-strings + link.href = decodeURIComponent(atob(element.dataset.url).split('').map(c => { + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); + }).join('')); + link.rel = 'noopener external nofollow noreferrer'; + link.target = '_blank'; + link.className = element.className; + link.title = element.title; + link.innerHTML = element.innerHTML; + element.parentNode.replaceChild(link, element); + }); + }, + + /** + * One-click copy code support. + */ + registerCopyCode: function() { + let figure = document.querySelectorAll('figure.highlight'); + if (figure.length === 0) figure = document.querySelectorAll('pre:not(.mermaid)'); + figure.forEach(element => { + element.querySelectorAll('.code .line span').forEach(span => { + span.classList.forEach(name => { + span.classList.replace(name, `hljs-${name}`); + }); + }); + if (!CONFIG.copycode.enable) return; + let target = element; + if (CONFIG.copycode.style !== 'mac') target = element.querySelector('.table-container') || element; + target.insertAdjacentHTML('beforeend', '
'); + const button = element.querySelector('.copy-btn'); + button.addEventListener('click', () => { + const lines = element.querySelector('.code') || element.querySelector('code'); + const code = lines.innerText; + if (navigator.clipboard) { + // https://caniuse.com/mdn-api_clipboard_writetext + navigator.clipboard.writeText(code).then(() => { + button.querySelector('i').className = 'fa fa-check-circle fa-fw'; + }, () => { + button.querySelector('i').className = 'fa fa-times-circle fa-fw'; + }); + } else { + const ta = document.createElement('textarea'); + ta.style.top = window.scrollY + 'px'; // Prevent page scrolling + ta.style.position = 'absolute'; + ta.style.opacity = '0'; + ta.readOnly = true; + ta.value = code; + document.body.append(ta); + ta.select(); + ta.setSelectionRange(0, code.length); + ta.readOnly = false; + const result = document.execCommand('copy'); + button.querySelector('i').className = result ? 'fa fa-check-circle fa-fw' : 'fa fa-times-circle fa-fw'; + ta.blur(); // For iOS + button.blur(); + document.body.removeChild(ta); + } + }); + element.addEventListener('mouseleave', () => { + setTimeout(() => { + button.querySelector('i').className = 'fa fa-copy fa-fw'; + }, 300); + }); + }); + }, + + wrapTableWithBox: function() { + document.querySelectorAll('table').forEach(element => { + const box = document.createElement('div'); + box.className = 'table-container'; + element.wrap(box); + }); + }, + + registerVideoIframe: function() { + document.querySelectorAll('iframe').forEach(element => { + const supported = [ + 'www.youtube.com', + 'player.vimeo.com', + 'player.youku.com', + 'player.bilibili.com', + 'www.tudou.com' + ].some(host => element.src.includes(host)); + if (supported && !element.parentNode.matches('.video-container')) { + const box = document.createElement('div'); + box.className = 'video-container'; + element.wrap(box); + const width = Number(element.width); + const height = Number(element.height); + if (width && height) { + box.style.paddingTop = (height / width * 100) + '%'; + } + } + }); + }, + + updateActiveNav: function() { + if (!Array.isArray(NexT.utils.sections)) return; + let index = NexT.utils.sections.findIndex(element => { + return element && element.getBoundingClientRect().top > 10; + }); + if (index === -1) { + index = NexT.utils.sections.length - 1; + } else if (index > 0) { + index--; + } + this.activateNavByIndex(index); + }, + + registerScrollPercent: function() { + const backToTop = document.querySelector('.back-to-top'); + const readingProgressBar = document.querySelector('.reading-progress-bar'); + // For init back to top in sidebar if page was scrolled after page refresh. + window.addEventListener('scroll', () => { + if (backToTop || readingProgressBar) { + const contentHeight = document.body.scrollHeight - window.innerHeight; + const scrollPercent = contentHeight > 0 ? Math.min(100 * window.scrollY / contentHeight, 100) : 0; + if (backToTop) { + backToTop.classList.toggle('back-to-top-on', Math.round(scrollPercent) >= 5); + backToTop.querySelector('span').innerText = Math.round(scrollPercent) + '%'; + } + if (readingProgressBar) { + readingProgressBar.style.setProperty('--progress', scrollPercent.toFixed(2) + '%'); + } + } + this.updateActiveNav(); + }, { passive: true }); + + backToTop && backToTop.addEventListener('click', () => { + window.anime({ + targets : document.scrollingElement, + duration : 500, + easing : 'linear', + scrollTop: 0 + }); + }); + }, + + /** + * Tabs tag listener (without twitter bootstrap). + */ + registerTabsTag: function() { + // Binding `nav-tabs` & `tab-content` by real time permalink changing. + document.querySelectorAll('.tabs ul.nav-tabs .tab').forEach(element => { + element.addEventListener('click', event => { + event.preventDefault(); + // Prevent selected tab to select again. + if (element.classList.contains('active')) return; + const nav = element.parentNode; + // Get the height of `tab-pane` which is activated before, and set it as the height of `tab-content` with extra margin / paddings. + const tabContent = nav.nextElementSibling; + tabContent.style.overflow = 'hidden'; + tabContent.style.transition = 'height 1s'; + // Comment system selection tab does not contain .active class. + const activeTab = tabContent.querySelector('.active') || tabContent.firstElementChild; + // Hight might be `auto`. + const prevHeight = parseInt(window.getComputedStyle(activeTab).height.replace('px', ''), 10) || 0; + const paddingTop = parseInt(window.getComputedStyle(activeTab).paddingTop.replace('px', ''), 10); + const marginBottom = parseInt(window.getComputedStyle(activeTab.firstElementChild).marginBottom.replace('px', ''), 10); + tabContent.style.height = prevHeight + paddingTop + marginBottom + 'px'; + // Add & Remove active class on `nav-tabs` & `tab-content`. + [...nav.children].forEach(target => { + target.classList.toggle('active', target === element); + }); + // https://stackoverflow.com/questions/20306204/using-queryselector-with-ids-that-are-numbers + const tActive = document.getElementById(element.querySelector('a').getAttribute('href').replace('#', '')); + [...tActive.parentNode.children].forEach(target => { + target.classList.toggle('active', target === tActive); + }); + // Trigger event + tActive.dispatchEvent(new Event('tabs:click', { + bubbles: true + })); + // Get the height of `tab-pane` which is activated now. + const hasScrollBar = document.body.scrollHeight > (window.innerHeight || document.documentElement.clientHeight); + const currHeight = parseInt(window.getComputedStyle(tabContent.querySelector('.active')).height.replace('px', ''), 10); + // Reset the height of `tab-content` and see the animation. + tabContent.style.height = currHeight + paddingTop + marginBottom + 'px'; + // Change the height of `tab-content` may cause scrollbar show / disappear, which may result in the change of the `tab-pane`'s height + setTimeout(() => { + if ((document.body.scrollHeight > (window.innerHeight || document.documentElement.clientHeight)) !== hasScrollBar) { + tabContent.style.transition = 'height 0.3s linear'; + // After the animation, we need reset the height of `tab-content` again. + const currHeightAfterScrollBarChange = parseInt(window.getComputedStyle(tabContent.querySelector('.active')).height.replace('px', ''), 10); + tabContent.style.height = currHeightAfterScrollBarChange + paddingTop + marginBottom + 'px'; + } + // Remove all the inline styles, and let the height be adaptive again. + setTimeout(() => { + tabContent.style.transition = ''; + tabContent.style.height = ''; + }, 250); + }, 1000); + if (!CONFIG.stickytabs) return; + const offset = nav.parentNode.getBoundingClientRect().top + window.scrollY + 10; + window.anime({ + targets : document.scrollingElement, + duration : 500, + easing : 'linear', + scrollTop: offset + }); + }); + }); + + window.dispatchEvent(new Event('tabs:register')); + }, + + registerCanIUseTag: function() { + // Get responsive height passed from iframe. + window.addEventListener('message', ({ data }) => { + if (typeof data === 'string' && data.includes('ciu_embed')) { + const featureID = data.split(':')[1]; + const height = data.split(':')[2]; + document.querySelector(`iframe[data-feature=${featureID}]`).style.height = parseInt(height, 10) + 5 + 'px'; + } + }, false); + }, + + registerActiveMenuItem: function() { + document.querySelectorAll('.menu-item a[href]').forEach(target => { + const isSamePath = target.pathname === location.pathname || target.pathname === location.pathname.replace('index.html', ''); + const isSubPath = !CONFIG.root.startsWith(target.pathname) && location.pathname.startsWith(target.pathname); + target.classList.toggle('menu-item-active', target.hostname === location.hostname && (isSamePath || isSubPath)); + }); + }, + + registerLangSelect: function() { + const selects = document.querySelectorAll('.lang-select'); + selects.forEach(sel => { + sel.value = CONFIG.page.lang; + sel.addEventListener('change', () => { + const target = sel.options[sel.selectedIndex]; + document.querySelectorAll('.lang-select-label span').forEach(span => { + span.innerText = target.text; + }); + // Disable Pjax to force refresh translation of menu item + window.location.href = target.dataset.href; + }); + }); + }, + + registerSidebarTOC: function() { + this.sections = [...document.querySelectorAll('.post-toc:not(.placeholder-toc) li a.nav-link')].map(element => { + const target = document.getElementById(decodeURI(element.getAttribute('href')).replace('#', '')); + // TOC item animation navigate. + element.addEventListener('click', event => { + event.preventDefault(); + const offset = target.getBoundingClientRect().top + window.scrollY; + window.anime({ + targets : document.scrollingElement, + duration : 500, + easing : 'linear', + scrollTop: offset, + complete : () => { + history.pushState(null, document.title, element.href); + } + }); + }); + return target; + }); + this.updateActiveNav(); + }, + + registerPostReward: function() { + const button = document.querySelector('.reward-container button'); + if (!button) return; + button.addEventListener('click', () => { + document.querySelector('.post-reward').classList.toggle('active'); + }); + }, + + activateNavByIndex: function(index) { + const nav = document.querySelector('.post-toc:not(.placeholder-toc) .nav'); + if (!nav) return; + + const navItemList = nav.querySelectorAll('.nav-item'); + const target = navItemList[index]; + if (!target || target.classList.contains('active-current')) return; + + const singleHeight = navItemList[navItemList.length - 1].offsetHeight; + + nav.querySelectorAll('.active').forEach(navItem => { + navItem.classList.remove('active', 'active-current'); + }); + target.classList.add('active', 'active-current'); + + let activateEle = target.querySelector('.nav-child') || target.parentElement; + let navChildHeight = 0; + + while (nav.contains(activateEle)) { + if (activateEle.classList.contains('nav-item')) { + activateEle.classList.add('active'); + } else { // .nav-child or .nav + // scrollHeight isn't reliable for transitioning child items. + // The last nav-item in a list has a margin-bottom of 5px. + navChildHeight += (singleHeight * activateEle.childElementCount) + 5; + activateEle.style.setProperty('--height', `${navChildHeight}px`); + } + activateEle = activateEle.parentElement; + } + + // Scrolling to center active TOC element if TOC content is taller then viewport. + const tocElement = document.querySelector(CONFIG.scheme === 'Pisces' || CONFIG.scheme === 'Gemini' ? '.sidebar-panel-container' : '.sidebar'); + if (!document.querySelector('.sidebar-toc-active')) return; + window.anime({ + targets : tocElement, + duration : 200, + easing : 'linear', + scrollTop: tocElement.scrollTop - (tocElement.offsetHeight / 2) + target.getBoundingClientRect().top - tocElement.getBoundingClientRect().top + }); + }, + + updateSidebarPosition: function() { + if (window.innerWidth < 1200 || CONFIG.scheme === 'Pisces' || CONFIG.scheme === 'Gemini') return; + // Expand sidebar on post detail page by default, when post has a toc. + const hasTOC = document.querySelector('.post-toc:not(.placeholder-toc)'); + let display = CONFIG.page.sidebar; + if (typeof display !== 'boolean') { + // There's no definition sidebar in the page front-matter. + display = CONFIG.sidebar.display === 'always' || (CONFIG.sidebar.display === 'post' && hasTOC); + } + if (display) { + window.dispatchEvent(new Event('sidebar:show')); + } + }, + + activateSidebarPanel: function(index) { + const sidebar = document.querySelector('.sidebar-inner'); + const activeClassNames = ['sidebar-toc-active', 'sidebar-overview-active']; + if (sidebar.classList.contains(activeClassNames[index])) return; + + const panelContainer = sidebar.querySelector('.sidebar-panel-container'); + const tocPanel = panelContainer.firstElementChild; + const overviewPanel = panelContainer.lastElementChild; + + let postTOCHeight = tocPanel.scrollHeight; + // For TOC activation, try to use the animated TOC height + if (index === 0) { + const nav = tocPanel.querySelector('.nav'); + if (nav) { + postTOCHeight = parseInt(nav.style.getPropertyValue('--height'), 10); + } + } + const panelHeights = [ + postTOCHeight, + overviewPanel.scrollHeight + ]; + panelContainer.style.setProperty('--inactive-panel-height', `${panelHeights[1 - index]}px`); + panelContainer.style.setProperty('--active-panel-height', `${panelHeights[index]}px`); + + sidebar.classList.replace(activeClassNames[1 - index], activeClassNames[index]); + }, + + getScript: function(src, options = {}, legacyCondition) { + if (typeof options === 'function') { + return this.getScript(src, { + condition: legacyCondition + }).then(options); + } + const { + condition = false, + attributes: { + id = '', + async = false, + defer = false, + crossOrigin = '', + dataset = {}, + ...otherAttributes + } = {}, + parentNode = null + } = options; + return new Promise((resolve, reject) => { + if (condition) { + resolve(); + } else { + const script = document.createElement('script'); + + if (id) script.id = id; + if (crossOrigin) script.crossOrigin = crossOrigin; + script.async = async; + script.defer = defer; + Object.assign(script.dataset, dataset); + Object.entries(otherAttributes).forEach(([name, value]) => { + script.setAttribute(name, String(value)); + }); + + script.onload = resolve; + script.onerror = reject; + + if (typeof src === 'object') { + const { url, integrity } = src; + script.src = url; + if (integrity) { + script.integrity = integrity; + script.crossOrigin = 'anonymous'; + } + } else { + script.src = src; + } + (parentNode || document.head).appendChild(script); + } + }); + }, + + loadComments: function(selector, legacyCallback) { + if (legacyCallback) { + return this.loadComments(selector).then(legacyCallback); + } + return new Promise(resolve => { + const element = document.querySelector(selector); + if (!CONFIG.comments.lazyload || !element) { + resolve(); + return; + } + const intersectionObserver = new IntersectionObserver((entries, observer) => { + const entry = entries[0]; + if (!entry.isIntersecting) return; + + resolve(); + observer.disconnect(); + }); + intersectionObserver.observe(element); + }); + } +}; diff --git a/lib/hbe.js b/lib/hbe.js new file mode 100644 index 0000000..bc024dc --- /dev/null +++ b/lib/hbe.js @@ -0,0 +1,293 @@ +(() => { + 'use strict'; + + const cryptoObj = window.crypto || window.msCrypto; + const storage = window.localStorage; + + const storageName = 'hexo-blog-encrypt:#' + window.location.pathname; + const keySalt = textToArray('hexo-blog-encrypt的作者们都是大帅比!'); + const ivSalt = textToArray('hexo-blog-encrypt是地表最强Hexo加密插件!'); + +// As we can't detect the wrong password with AES-CBC, +// so adding an empty div and check it when decrption. +const knownPrefix = ""; + + const mainElement = document.getElementById('hexo-blog-encrypt'); + const wrongPassMessage = mainElement.dataset['wpm']; + const wrongHashMessage = mainElement.dataset['whm']; + const dataElement = mainElement.getElementsByTagName('script')['hbeData']; + const encryptedData = dataElement.innerText; + const HmacDigist = dataElement.dataset['hmacdigest']; + + function hexToArray(s) { + return new Uint8Array(s.match(/[\da-f]{2}/gi).map((h => { + return parseInt(h, 16); + }))); + } + + function textToArray(s) { + var i = s.length; + var n = 0; + var ba = new Array() + + for (var j = 0; j < i;) { + var c = s.codePointAt(j); + if (c < 128) { + ba[n++] = c; + j++; + } else if ((c > 127) && (c < 2048)) { + ba[n++] = (c >> 6) | 192; + ba[n++] = (c & 63) | 128; + j++; + } else if ((c > 2047) && (c < 65536)) { + ba[n++] = (c >> 12) | 224; + ba[n++] = ((c >> 6) & 63) | 128; + ba[n++] = (c & 63) | 128; + j++; + } else { + ba[n++] = (c >> 18) | 240; + ba[n++] = ((c >> 12) & 63) | 128; + ba[n++] = ((c >> 6) & 63) | 128; + ba[n++] = (c & 63) | 128; + j += 2; + } + } + return new Uint8Array(ba); + } + + function arrayBufferToHex(arrayBuffer) { + if (typeof arrayBuffer !== 'object' || arrayBuffer === null || typeof arrayBuffer.byteLength !== 'number') { + throw new TypeError('Expected input to be an ArrayBuffer') + } + + var view = new Uint8Array(arrayBuffer) + var result = '' + var value + + for (var i = 0; i < view.length; i++) { + value = view[i].toString(16) + result += (value.length === 1 ? '0' + value : value) + } + + return result + } + + async function getExecutableScript(oldElem) { + let out = document.createElement('script'); + const attList = ['type', 'text', 'src', 'crossorigin', 'defer', 'referrerpolicy']; + attList.forEach((att) => { + if (oldElem[att]) + out[att] = oldElem[att]; + }) + + return out; + } + + async function convertHTMLToElement(content) { + let out = document.createElement('div'); + out.innerHTML = content; + out.querySelectorAll('script').forEach(async (elem) => { + elem.replaceWith(await getExecutableScript(elem)); + }); + + return out; + } + + function getKeyMaterial(password) { + let encoder = new TextEncoder(); + return cryptoObj.subtle.importKey( + 'raw', + encoder.encode(password), + { + 'name': 'PBKDF2', + }, + false, + [ + 'deriveKey', + 'deriveBits', + ] + ); + } + + function getHmacKey(keyMaterial) { + return cryptoObj.subtle.deriveKey({ + 'name': 'PBKDF2', + 'hash': 'SHA-256', + 'salt': keySalt.buffer, + 'iterations': 1024 + }, keyMaterial, { + 'name': 'HMAC', + 'hash': 'SHA-256', + 'length': 256, + }, true, [ + 'verify', + ]); + } + + function getDecryptKey(keyMaterial) { + return cryptoObj.subtle.deriveKey({ + 'name': 'PBKDF2', + 'hash': 'SHA-256', + 'salt': keySalt.buffer, + 'iterations': 1024, + }, keyMaterial, { + 'name': 'AES-CBC', + 'length': 256, + }, true, [ + 'decrypt', + ]); + } + + function getIv(keyMaterial) { + return cryptoObj.subtle.deriveBits({ + 'name': 'PBKDF2', + 'hash': 'SHA-256', + 'salt': ivSalt.buffer, + 'iterations': 512, + }, keyMaterial, 16 * 8); + } + + async function verifyContent(key, content) { + const encoder = new TextEncoder(); + const encoded = encoder.encode(content); + + let signature = hexToArray(HmacDigist); + + const result = await cryptoObj.subtle.verify({ + 'name': 'HMAC', + 'hash': 'SHA-256', + }, key, signature, encoded); + console.log(`Verification result: ${result}`); + if (!result) { + alert(wrongHashMessage); + console.log(`${wrongHashMessage}, got `, signature, ` but proved wrong.`); + } + return result; + } + + async function decrypt(decryptKey, iv, hmacKey) { + let typedArray = hexToArray(encryptedData); + + const result = await cryptoObj.subtle.decrypt({ + 'name': 'AES-CBC', + 'iv': iv, + }, decryptKey, typedArray.buffer).then(async (result) => { + const decoder = new TextDecoder(); + const decoded = decoder.decode(result); + + // check the prefix, if not then we can sure here is wrong password. + if (!decoded.startsWith(knownPrefix)) { + throw "Decode successfully but not start with KnownPrefix."; + } + + const hideButton = document.createElement('button'); + hideButton.textContent = 'Encrypt again'; + hideButton.type = 'button'; + hideButton.classList.add("hbe-button"); + hideButton.addEventListener('click', () => { + window.localStorage.removeItem(storageName); + window.location.reload(); + }); + + document.getElementById('hexo-blog-encrypt').style.display = 'inline'; + document.getElementById('hexo-blog-encrypt').innerHTML = ''; + document.getElementById('hexo-blog-encrypt').appendChild(await convertHTMLToElement(decoded)); + document.getElementById('hexo-blog-encrypt').appendChild(hideButton); + + // support html5 lazyload functionality. + document.querySelectorAll('img').forEach((elem) => { + if (elem.getAttribute("data-src") && !elem.src) { + elem.src = elem.getAttribute('data-src'); + } + }); + + // support theme-next refresh + window.NexT && NexT.boot && typeof NexT.boot.refresh === 'function' && NexT.boot.refresh(); + + // TOC part + var tocDiv = document.getElementById("toc-div"); + if (tocDiv) { + tocDiv.style.display = 'inline'; + } + + var tocDivs = document.getElementsByClassName('toc-div-class'); + if (tocDivs && tocDivs.length > 0) { + for (var idx = 0; idx < tocDivs.length; idx++) { + tocDivs[idx].style.display = 'inline'; + } + } + + return await verifyContent(hmacKey, decoded); + }).catch((e) => { + alert(wrongPassMessage); + console.log(e); + return false; + }); + + return result; + + } + + function hbeLoader() { + + const oldStorageData = JSON.parse(storage.getItem(storageName)); + + if (oldStorageData) { + console.log(`Password got from localStorage(${storageName}): `, oldStorageData); + + const sIv = hexToArray(oldStorageData.iv).buffer; + const sDk = oldStorageData.dk; + const sHmk = oldStorageData.hmk; + + cryptoObj.subtle.importKey('jwk', sDk, { + 'name': 'AES-CBC', + 'length': 256, + }, true, [ + 'decrypt', + ]).then((dkCK) => { + cryptoObj.subtle.importKey('jwk', sHmk, { + 'name': 'HMAC', + 'hash': 'SHA-256', + 'length': 256, + }, true, [ + 'verify', + ]).then((hmkCK) => { + decrypt(dkCK, sIv, hmkCK).then((result) => { + if (!result) { + storage.removeItem(storageName); + } + }); + }); + }); + } + + mainElement.addEventListener('keydown', async (event) => { + if (event.isComposing || event.keyCode === 13) { + const password = document.getElementById('hbePass').value; + const keyMaterial = await getKeyMaterial(password); + const hmacKey = await getHmacKey(keyMaterial); + const decryptKey = await getDecryptKey(keyMaterial); + const iv = await getIv(keyMaterial); + + decrypt(decryptKey, iv, hmacKey).then((result) => { + console.log(`Decrypt result: ${result}`); + if (result) { + cryptoObj.subtle.exportKey('jwk', decryptKey).then((dk) => { + cryptoObj.subtle.exportKey('jwk', hmacKey).then((hmk) => { + const newStorageData = { + 'dk': dk, + 'iv': arrayBufferToHex(iv), + 'hmk': hmk, + }; + storage.setItem(storageName, JSON.stringify(newStorageData)); + }); + }); + } + }); + } + }); + } + + hbeLoader(); + +})(); diff --git a/lib/pace/LICENSE b/lib/pace/LICENSE new file mode 100644 index 0000000..69a20d6 --- /dev/null +++ b/lib/pace/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 «NexT» + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/lib/pace/README.html b/lib/pace/README.html new file mode 100644 index 0000000..15335de --- /dev/null +++ b/lib/pace/README.html @@ -0,0 +1,39 @@ +

Progress bar for NexT

+ +

Installation

+ +

If you want to use the CDN instead of clone this repo, please jump to the Step 3.

+ +

Step 1 → Go to NexT dir

+ +

Change dir to NexT directory. There must be layout, source, languages and other directories:

+
$ cd themes/next
+$ ls
+_config.yml  crowdin.yml  docs  gulpfile.js  languages  layout  LICENSE.md  package.json  README.md  scripts  source
+
+

Step 2 → Get module

+ +

Install module to source/lib directory:

+
$ git clone https://github.com/theme-next/theme-next-pace source/lib/pace
+
+

Step 3 → Set it up

+ +

Enable module in NexT _config.yml file and select your theme:

+
pace:
+  enable: true
+  # Themes list:
+  # big-counter | bounce | barber-shop | center-atom | center-circle | center-radar | center-simple
+  # corner-indicator | fill-left | flat-top | flash | loading-bar | mac-osx | material | minimal
+  theme: minimal
+
+

And, if you wants to use the CDN, then need to set: (you also need to find your corresponding theme css link in jsdelivr)

+
vendors:
+  ...
+  pace: //cdn.jsdelivr.net/npm/pace-js@1/pace.min.js
+  pace_css: //cdn.jsdelivr.net/npm/pace-js@1/themes/blue/pace-theme-minimal.css
+
+

Update

+ +
$ cd themes/next/source/lib/pace
+$ git pull
+
diff --git a/lib/pace/pace-theme-barber-shop.min.css b/lib/pace/pace-theme-barber-shop.min.css new file mode 100644 index 0000000..971e8a1 --- /dev/null +++ b/lib/pace/pace-theme-barber-shop.min.css @@ -0,0 +1 @@ +.pace,.pace .pace-progress{width:100%;overflow:hidden}.pace,.pace .pace-activity{position:fixed;top:0;left:0}.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:2000;height:12px;background:#fff}.pace-inactive{display:none}.pace .pace-progress{background-color:#29d;position:fixed;top:0;bottom:0;right:100%}.pace .pace-activity{right:-32px;bottom:0;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0);background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(.25,rgba(255,255,255,.2)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,.2)),color-stop(.75,rgba(255,255,255,.2)),color-stop(.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.2) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.2) 50%,rgba(255,255,255,.2) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,.2) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.2) 50%,rgba(255,255,255,.2) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.2) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.2) 50%,rgba(255,255,255,.2) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.2) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.2) 50%,rgba(255,255,255,.2) 75%,transparent 75%,transparent);-webkit-background-size:32px 32px;-moz-background-size:32px 32px;-o-background-size:32px 32px;background-size:32px 32px;-webkit-animation:pace-theme-barber-shop-motion .5s linear infinite;-moz-animation:pace-theme-barber-shop-motion .5s linear infinite;-ms-animation:pace-theme-barber-shop-motion .5s linear infinite;-o-animation:pace-theme-barber-shop-motion .5s linear infinite;animation:pace-theme-barber-shop-motion .5s linear infinite}@-webkit-keyframes pace-theme-barber-shop-motion{0%{-webkit-transform:none;transform:none}100%{-webkit-transform:translate(-32px,0);transform:translate(-32px,0)}}@-moz-keyframes pace-theme-barber-shop-motion{0%{-moz-transform:none;transform:none}100%{-moz-transform:translate(-32px,0);transform:translate(-32px,0)}}@-o-keyframes pace-theme-barber-shop-motion{0%{-o-transform:none;transform:none}100%{-o-transform:translate(-32px,0);transform:translate(-32px,0)}}@-ms-keyframes pace-theme-barber-shop-motion{0%{-ms-transform:none;transform:none}100%{-ms-transform:translate(-32px,0);transform:translate(-32px,0)}}@keyframes pace-theme-barber-shop-motion{0%{transform:none}100%{transform:translate(-32px,0)}} \ No newline at end of file diff --git a/lib/pace/pace-theme-big-counter.min.css b/lib/pace/pace-theme-big-counter.min.css new file mode 100644 index 0000000..f30e0a9 --- /dev/null +++ b/lib/pace/pace-theme-big-counter.min.css @@ -0,0 +1 @@ +.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.pace.pace-inactive .pace-progress{display:none}.pace .pace-progress{position:fixed;z-index:2000;top:0;right:0;height:5rem;width:5rem;-webkit-transform:translate3d(0,0,0)!important;-ms-transform:translate3d(0,0,0)!important;transform:translate3d(0,0,0)!important}.pace .pace-progress:after{display:block;position:absolute;top:0;right:.5rem;content:attr(data-progress-text);font-family:"Helvetica Neue",sans-serif;font-weight:100;font-size:5rem;line-height:1;text-align:right;color:rgba(34,153,221,.19999999999999996)} \ No newline at end of file diff --git a/lib/pace/pace-theme-bounce.min.css b/lib/pace/pace-theme-bounce.min.css new file mode 100644 index 0000000..3edcd35 --- /dev/null +++ b/lib/pace/pace-theme-bounce.min.css @@ -0,0 +1 @@ +.pace{width:140px;height:300px;position:fixed;top:-90px;right:-20px;z-index:2000;-webkit-transform:scale(0);-moz-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);transform:scale(0);opacity:0;-webkit-transition:all 2s linear 0s;-moz-transition:all 2s linear 0s;transition:all 2s linear 0s}.pace.pace-active{-webkit-transform:scale(.25);-moz-transform:scale(.25);-ms-transform:scale(.25);-o-transform:scale(.25);transform:scale(.25);opacity:1}.pace .pace-activity{width:140px;height:140px;border-radius:70px;background:#29d;position:absolute;top:0;z-index:1911;-webkit-animation:pace-bounce 1s infinite;-moz-animation:pace-bounce 1s infinite;-o-animation:pace-bounce 1s infinite;-ms-animation:pace-bounce 1s infinite;animation:pace-bounce 1s infinite}.pace .pace-progress{position:absolute;display:block;left:50%;bottom:0;z-index:1910;margin-left:-30px;width:60px;height:75px;background:rgba(20,20,20,.1);box-shadow:0 0 20px 35px rgba(20,20,20,.1);border-radius:30px/40px;-webkit-transform:scaleY(.3)!important;-moz-transform:scaleY(.3)!important;-ms-transform:scaleY(.3)!important;-o-transform:scaleY(.3)!important;transform:scaleY(.3)!important;-webkit-animation:pace-compress .5s infinite alternate;-moz-animation:pace-compress .5s infinite alternate;-o-animation:pace-compress .5s infinite alternate;-ms-animation:pace-compress .5s infinite alternate;animation:pace-compress .5s infinite alternate}@-webkit-keyframes pace-bounce{0%,100%,95%{top:0;-webkit-animation-timing-function:ease-in}50%{top:140px;height:140px;-webkit-animation-timing-function:ease-out}55%{top:160px;height:120px;border-radius:70px/60px;-webkit-animation-timing-function:ease-in}65%{top:120px;height:140px;border-radius:70px;-webkit-animation-timing-function:ease-out}}@-moz-keyframes pace-bounce{0%,100%,95%{top:0;-moz-animation-timing-function:ease-in}50%{top:140px;height:140px;-moz-animation-timing-function:ease-out}55%{top:160px;height:120px;border-radius:70px/60px;-moz-animation-timing-function:ease-in}65%{top:120px;height:140px;border-radius:70px;-moz-animation-timing-function:ease-out}}@keyframes pace-bounce{0%,100%,95%{top:0;animation-timing-function:ease-in}50%{top:140px;height:140px;animation-timing-function:ease-out}55%{top:160px;height:120px;border-radius:70px/60px;animation-timing-function:ease-in}65%{top:120px;height:140px;border-radius:70px;animation-timing-function:ease-out}}@-webkit-keyframes pace-compress{0%{bottom:0;margin-left:-30px;width:60px;height:75px;background:rgba(20,20,20,.1);box-shadow:0 0 20px 35px rgba(20,20,20,.1);border-radius:30px/40px;-webkit-animation-timing-function:ease-in}100%{bottom:30px;margin-left:-10px;width:20px;height:5px;background:rgba(20,20,20,.3);box-shadow:0 0 20px 35px rgba(20,20,20,.3);border-radius:20px;-webkit-animation-timing-function:ease-out}}@-moz-keyframes pace-compress{0%{bottom:0;margin-left:-30px;width:60px;height:75px;background:rgba(20,20,20,.1);box-shadow:0 0 20px 35px rgba(20,20,20,.1);border-radius:30px/40px;-moz-animation-timing-function:ease-in}100%{bottom:30px;margin-left:-10px;width:20px;height:5px;background:rgba(20,20,20,.3);box-shadow:0 0 20px 35px rgba(20,20,20,.3);border-radius:20px;-moz-animation-timing-function:ease-out}}@keyframes pace-compress{0%{bottom:0;margin-left:-30px;width:60px;height:75px;background:rgba(20,20,20,.1);box-shadow:0 0 20px 35px rgba(20,20,20,.1);border-radius:30px/40px;animation-timing-function:ease-in}100%{bottom:30px;margin-left:-10px;width:20px;height:5px;background:rgba(20,20,20,.3);box-shadow:0 0 20px 35px rgba(20,20,20,.3);border-radius:20px;animation-timing-function:ease-out}} \ No newline at end of file diff --git a/lib/pace/pace-theme-center-atom.min.css b/lib/pace/pace-theme-center-atom.min.css new file mode 100644 index 0000000..828dcba --- /dev/null +++ b/lib/pace/pace-theme-center-atom.min.css @@ -0,0 +1 @@ +.pace,.pace .pace-progress{z-index:2000;height:60px;width:100px}.pace .pace-activity,.pace .pace-progress:before{border-radius:50%;display:block;position:absolute}.pace.pace-inactive{display:none}.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;position:fixed;margin:auto;top:0;left:0;right:0;bottom:0}.pace .pace-progress{position:absolute;-webkit-transform:translate3d(0,0,0)!important;-ms-transform:translate3d(0,0,0)!important;transform:translate3d(0,0,0)!important}.pace .pace-progress:before{content:attr(data-progress-text);text-align:center;color:#fff;background:#29d;font-family:"Helvetica Neue",sans-serif;font-size:14px;font-weight:100;line-height:1;padding:20% 0 7px;width:50%;height:40%;margin:10px 0 0 30px;z-index:999}.pace .pace-activity{font-size:15px;line-height:1;z-index:2000;-webkit-animation:pace-theme-center-atom-spin 2s linear infinite;-moz-animation:pace-theme-center-atom-spin 2s linear infinite;-o-animation:pace-theme-center-atom-spin 2s linear infinite;animation:pace-theme-center-atom-spin 2s linear infinite;border:5px solid #29d;content:' ';top:0;left:0;height:60px;width:100px}.pace .pace-activity:after,.pace .pace-activity:before{content:' ';display:block;position:absolute;top:-5px;left:-5px;height:60px;width:100px}.pace .pace-activity:after{border-radius:50%;border:5px solid #29d;-webkit-transform:rotate(60deg);-moz-transform:rotate(60deg);-o-transform:rotate(60deg);transform:rotate(60deg)}.pace .pace-activity:before{border-radius:50%;border:5px solid #29d;-webkit-transform:rotate(120deg);-moz-transform:rotate(120deg);-o-transform:rotate(120deg);transform:rotate(120deg)}@-webkit-keyframes pace-theme-center-atom-spin{0%{-webkit-transform:rotate(0)}100%{-webkit-transform:rotate(359deg)}}@-moz-keyframes pace-theme-center-atom-spin{0%{-moz-transform:rotate(0)}100%{-moz-transform:rotate(359deg)}}@-o-keyframes pace-theme-center-atom-spin{0%{-o-transform:rotate(0)}100%{-o-transform:rotate(359deg)}}@keyframes pace-theme-center-atom-spin{0%{transform:rotate(0)}100%{transform:rotate(359deg)}} \ No newline at end of file diff --git a/lib/pace/pace-theme-center-circle.min.css b/lib/pace/pace-theme-center-circle.min.css new file mode 100644 index 0000000..c005c71 --- /dev/null +++ b/lib/pace/pace-theme-center-circle.min.css @@ -0,0 +1 @@ +.pace,.pace .pace-progress{z-index:2000;left:0;top:0;height:6rem}.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;-webkit-perspective:12rem;-moz-perspective:12rem;-ms-perspective:12rem;-o-perspective:12rem;perspective:12rem;position:fixed;width:6rem;margin:auto;right:0;bottom:0}.pace.pace-inactive .pace-progress{display:none}.pace .pace-progress{display:block;position:absolute;width:6rem!important;line-height:6rem;font-size:2rem;border-radius:50%;background:rgba(34,153,221,.8);color:#fff;font-family:"Helvetica Neue",sans-serif;font-weight:100;text-align:center;-webkit-animation:pace-theme-center-circle-spin linear infinite 2s;-moz-animation:pace-theme-center-circle-spin linear infinite 2s;-ms-animation:pace-theme-center-circle-spin linear infinite 2s;-o-animation:pace-theme-center-circle-spin linear infinite 2s;animation:pace-theme-center-circle-spin linear infinite 2s;-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;-ms-transform-style:preserve-3d;-o-transform-style:preserve-3d;transform-style:preserve-3d}.pace .pace-progress:after{content:attr(data-progress-text);display:block}@-webkit-keyframes pace-theme-center-circle-spin{from{-webkit-transform:rotateY(0)}to{-webkit-transform:rotateY(360deg)}}@-moz-keyframes pace-theme-center-circle-spin{from{-moz-transform:rotateY(0)}to{-moz-transform:rotateY(360deg)}}@-ms-keyframes pace-theme-center-circle-spin{from{-ms-transform:rotateY(0)}to{-ms-transform:rotateY(360deg)}}@-o-keyframes pace-theme-center-circle-spin{from{-o-transform:rotateY(0)}to{-o-transform:rotateY(360deg)}}@keyframes pace-theme-center-circle-spin{from{transform:rotateY(0)}to{transform:rotateY(360deg)}} \ No newline at end of file diff --git a/lib/pace/pace-theme-center-radar.min.css b/lib/pace/pace-theme-center-radar.min.css new file mode 100644 index 0000000..8bb4535 --- /dev/null +++ b/lib/pace/pace-theme-center-radar.min.css @@ -0,0 +1 @@ +.pace,.pace .pace-activity{z-index:2000;height:90px;width:90px}.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;position:fixed;margin:auto;top:0;left:0;right:0;bottom:0}.pace.pace-inactive .pace-activity{display:none}.pace .pace-activity,.pace .pace-activity:before{position:absolute;display:block;border-color:#29d transparent transparent;border-radius:50%}.pace .pace-activity{left:-30px;top:-30px;border-width:30px;border-style:double;-webkit-animation:spin 1s linear infinite;-moz-animation:spin 1s linear infinite;-o-animation:spin 1s linear infinite;animation:spin 1s linear infinite}.pace .pace-activity:before{content:' ';top:10px;left:10px;height:50px;width:50px;border-width:10px;border-style:solid}@-webkit-keyframes spin{100%{-webkit-transform:rotate(359deg)}}@-moz-keyframes spin{100%{-moz-transform:rotate(359deg)}}@-o-keyframes spin{100%{-moz-transform:rotate(359deg)}}@keyframes spin{100%{transform:rotate(359deg)}} \ No newline at end of file diff --git a/lib/pace/pace-theme-center-simple.min.css b/lib/pace/pace-theme-center-simple.min.css new file mode 100644 index 0000000..a6dbd9c --- /dev/null +++ b/lib/pace/pace-theme-center-simple.min.css @@ -0,0 +1 @@ +.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:2000;position:fixed;margin:auto;top:0;left:0;right:0;bottom:0;height:5px;width:200px;background:#fff;border:1px solid #29d;overflow:hidden}.pace .pace-progress{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;-o-box-sizing:border-box;box-sizing:border-box;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0);max-width:200px;z-index:2000;display:block;position:absolute;top:0;right:100%;height:100%;width:100%;background:#29d}.pace.pace-inactive{display:none} \ No newline at end of file diff --git a/lib/pace/pace-theme-corner-indicator.min.css b/lib/pace/pace-theme-corner-indicator.min.css new file mode 100644 index 0000000..490db22 --- /dev/null +++ b/lib/pace/pace-theme-corner-indicator.min.css @@ -0,0 +1 @@ +.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.pace .pace-activity{display:block;position:fixed;z-index:2000;top:0;right:0;width:300px;height:300px;background:#29d;-webkit-transition:-webkit-transform .3s;transition:transform .3s;-webkit-transform:translateX(100%) translateY(-100%) rotate(45deg);transform:translateX(100%) translateY(-100%) rotate(45deg);pointer-events:none}.pace.pace-active .pace-activity{-webkit-transform:translateX(50%) translateY(-50%) rotate(45deg);transform:translateX(50%) translateY(-50%) rotate(45deg)}.pace .pace-activity::after,.pace .pace-activity::before{-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;bottom:30px;left:50%;display:block;border:5px solid #fff;border-radius:50%;content:''}.pace .pace-activity::before{margin-left:-40px;width:80px;height:80px;border-right-color:rgba(0,0,0,.2);border-left-color:rgba(0,0,0,.2);-webkit-animation:pace-theme-corner-indicator-spin 3s linear infinite;animation:pace-theme-corner-indicator-spin 3s linear infinite}.pace .pace-activity::after{bottom:50px;margin-left:-20px;width:40px;height:40px;border-top-color:rgba(0,0,0,.2);border-bottom-color:rgba(0,0,0,.2);-webkit-animation:pace-theme-corner-indicator-spin 1s linear infinite;animation:pace-theme-corner-indicator-spin 1s linear infinite}@-webkit-keyframes pace-theme-corner-indicator-spin{0%{-webkit-transform:rotate(0)}100%{-webkit-transform:rotate(359deg)}}@keyframes pace-theme-corner-indicator-spin{0%{transform:rotate(0)}100%{transform:rotate(359deg)}} \ No newline at end of file diff --git a/lib/pace/pace-theme-fill-left.min.css b/lib/pace/pace-theme-fill-left.min.css new file mode 100644 index 0000000..533d55d --- /dev/null +++ b/lib/pace/pace-theme-fill-left.min.css @@ -0,0 +1 @@ +.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.pace-inactive{display:none}.pace .pace-progress{background-color:rgba(34,153,221,.19999999999999996);position:fixed;z-index:-1;top:0;right:100%;bottom:0;width:100%} \ No newline at end of file diff --git a/lib/pace/pace-theme-flash.min.css b/lib/pace/pace-theme-flash.min.css new file mode 100644 index 0000000..35a749d --- /dev/null +++ b/lib/pace/pace-theme-flash.min.css @@ -0,0 +1 @@ +.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.pace-inactive{display:none}.pace .pace-progress{background:#29d;position:fixed;z-index:2000;top:0;right:100%;width:100%;height:2px}.pace .pace-progress-inner{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #29d,0 0 5px #29d;opacity:1;-webkit-transform:rotate(3deg) translate(0,-4px);-moz-transform:rotate(3deg) translate(0,-4px);-ms-transform:rotate(3deg) translate(0,-4px);-o-transform:rotate(3deg) translate(0,-4px);transform:rotate(3deg) translate(0,-4px)}.pace .pace-activity{display:block;position:fixed;z-index:2000;top:15px;right:15px;width:14px;height:14px;border:2px solid transparent;border-top-color:#29d;border-left-color:#29d;border-radius:10px;-webkit-animation:pace-spinner .4s linear infinite;-moz-animation:pace-spinner .4s linear infinite;-ms-animation:pace-spinner .4s linear infinite;-o-animation:pace-spinner .4s linear infinite;animation:pace-spinner .4s linear infinite}@-webkit-keyframes pace-spinner{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes pace-spinner{0%{-moz-transform:rotate(0);transform:rotate(0)}100%{-moz-transform:rotate(360deg);transform:rotate(360deg)}}@-o-keyframes pace-spinner{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(360deg);transform:rotate(360deg)}}@-ms-keyframes pace-spinner{0%{-ms-transform:rotate(0);transform:rotate(0)}100%{-ms-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes pace-spinner{0%{transform:rotate(0)}100%{transform:rotate(360deg)}} \ No newline at end of file diff --git a/lib/pace/pace-theme-flat-top.min.css b/lib/pace/pace-theme-flat-top.min.css new file mode 100644 index 0000000..6854b8c --- /dev/null +++ b/lib/pace/pace-theme-flat-top.min.css @@ -0,0 +1 @@ +.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;position:fixed;top:0;left:0;width:100%;-webkit-transform:translate3d(0,-50px,0);-ms-transform:translate3d(0,-50px,0);transform:translate3d(0,-50px,0);-webkit-transition:-webkit-transform .5s ease-out;-ms-transition:-webkit-transform .5s ease-out;transition:transform .5s ease-out}.pace.pace-active{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.pace .pace-progress{display:block;position:fixed;z-index:2000;top:0;right:100%;width:100%;height:10px;background:#29d;pointer-events:none} diff --git a/lib/pace/pace-theme-loading-bar.min.css b/lib/pace/pace-theme-loading-bar.min.css new file mode 100644 index 0000000..9b30580 --- /dev/null +++ b/lib/pace/pace-theme-loading-bar.min.css @@ -0,0 +1 @@ +.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;-o-box-sizing:border-box;box-sizing:border-box;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;z-index:2000;position:fixed;margin:auto;top:12px;left:0;right:0;bottom:0;width:200px;height:50px;overflow:hidden}.pace .pace-progress{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;-o-box-sizing:border-box;box-sizing:border-box;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;-webkit-background-clip:padding-box;-moz-background-clip:padding;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);display:block;position:absolute;right:100%;margin-right:-7px;width:93%;top:7px;height:14px;font-size:12px;background:#29d;color:#29d;line-height:60px;font-weight:700;font-family:Helvetica,Arial,"Lucida Grande",sans-serif;-webkit-box-shadow:120px 0 #fff,240px 0 #fff;-ms-box-shadow:120px 0 #fff,240px 0 #fff;box-shadow:120px 0 #fff,240px 0 #fff}.pace .pace-progress:after{content:attr(data-progress-text);display:inline-block;position:fixed;width:45px;text-align:right;right:0;padding-right:16px;top:4px}.pace .pace-progress[data-progress-text="0%"]:after{right:-200px}.pace .pace-progress[data-progress-text="1%"]:after{right:-198.14px}.pace .pace-progress[data-progress-text="2%"]:after{right:-196.28px}.pace .pace-progress[data-progress-text="3%"]:after{right:-194.42px}.pace .pace-progress[data-progress-text="4%"]:after{right:-192.56px}.pace .pace-progress[data-progress-text="5%"]:after{right:-190.7px}.pace .pace-progress[data-progress-text="6%"]:after{right:-188.84px}.pace .pace-progress[data-progress-text="7%"]:after{right:-186.98px}.pace .pace-progress[data-progress-text="8%"]:after{right:-185.12px}.pace .pace-progress[data-progress-text="9%"]:after{right:-183.26px}.pace .pace-progress[data-progress-text="10%"]:after{right:-181.4px}.pace .pace-progress[data-progress-text="11%"]:after{right:-179.54px}.pace .pace-progress[data-progress-text="12%"]:after{right:-177.68px}.pace .pace-progress[data-progress-text="13%"]:after{right:-175.82px}.pace .pace-progress[data-progress-text="14%"]:after{right:-173.96px}.pace .pace-progress[data-progress-text="15%"]:after{right:-172.1px}.pace .pace-progress[data-progress-text="16%"]:after{right:-170.24px}.pace .pace-progress[data-progress-text="17%"]:after{right:-168.38px}.pace .pace-progress[data-progress-text="18%"]:after{right:-166.52px}.pace .pace-progress[data-progress-text="19%"]:after{right:-164.66px}.pace .pace-progress[data-progress-text="20%"]:after{right:-162.8px}.pace .pace-progress[data-progress-text="21%"]:after{right:-160.94px}.pace .pace-progress[data-progress-text="22%"]:after{right:-159.08px}.pace .pace-progress[data-progress-text="23%"]:after{right:-157.22px}.pace .pace-progress[data-progress-text="24%"]:after{right:-155.36px}.pace .pace-progress[data-progress-text="25%"]:after{right:-153.5px}.pace .pace-progress[data-progress-text="26%"]:after{right:-151.64px}.pace .pace-progress[data-progress-text="27%"]:after{right:-149.78px}.pace .pace-progress[data-progress-text="28%"]:after{right:-147.92px}.pace .pace-progress[data-progress-text="29%"]:after{right:-146.06px}.pace .pace-progress[data-progress-text="30%"]:after{right:-144.2px}.pace .pace-progress[data-progress-text="31%"]:after{right:-142.34px}.pace .pace-progress[data-progress-text="32%"]:after{right:-140.48px}.pace .pace-progress[data-progress-text="33%"]:after{right:-138.62px}.pace .pace-progress[data-progress-text="34%"]:after{right:-136.76px}.pace .pace-progress[data-progress-text="35%"]:after{right:-134.9px}.pace .pace-progress[data-progress-text="36%"]:after{right:-133.04px}.pace .pace-progress[data-progress-text="37%"]:after{right:-131.18px}.pace .pace-progress[data-progress-text="38%"]:after{right:-129.32px}.pace .pace-progress[data-progress-text="39%"]:after{right:-127.46px}.pace .pace-progress[data-progress-text="40%"]:after{right:-125.6px}.pace .pace-progress[data-progress-text="41%"]:after{right:-123.74px}.pace .pace-progress[data-progress-text="42%"]:after{right:-121.88px}.pace .pace-progress[data-progress-text="43%"]:after{right:-120.02px}.pace .pace-progress[data-progress-text="44%"]:after{right:-118.16px}.pace .pace-progress[data-progress-text="45%"]:after{right:-116.3px}.pace .pace-progress[data-progress-text="46%"]:after{right:-114.44px}.pace .pace-progress[data-progress-text="47%"]:after{right:-112.58px}.pace .pace-progress[data-progress-text="48%"]:after{right:-110.72px}.pace .pace-progress[data-progress-text="49%"]:after{right:-108.86px}.pace .pace-progress[data-progress-text="50%"]:after{right:-107px}.pace .pace-progress[data-progress-text="51%"]:after{right:-105.14px}.pace .pace-progress[data-progress-text="52%"]:after{right:-103.28px}.pace .pace-progress[data-progress-text="53%"]:after{right:-101.42px}.pace .pace-progress[data-progress-text="54%"]:after{right:-99.56px}.pace .pace-progress[data-progress-text="55%"]:after{right:-97.7px}.pace .pace-progress[data-progress-text="56%"]:after{right:-95.84px}.pace .pace-progress[data-progress-text="57%"]:after{right:-93.98px}.pace .pace-progress[data-progress-text="58%"]:after{right:-92.12px}.pace .pace-progress[data-progress-text="59%"]:after{right:-90.26px}.pace .pace-progress[data-progress-text="60%"]:after{right:-88.4px}.pace .pace-progress[data-progress-text="61%"]:after{right:-86.54px}.pace .pace-progress[data-progress-text="62%"]:after{right:-84.68px}.pace .pace-progress[data-progress-text="63%"]:after{right:-82.82px}.pace .pace-progress[data-progress-text="64%"]:after{right:-80.96px}.pace .pace-progress[data-progress-text="65%"]:after{right:-79.1px}.pace .pace-progress[data-progress-text="66%"]:after{right:-77.24px}.pace .pace-progress[data-progress-text="67%"]:after{right:-75.38px}.pace .pace-progress[data-progress-text="68%"]:after{right:-73.52px}.pace .pace-progress[data-progress-text="69%"]:after{right:-71.66px}.pace .pace-progress[data-progress-text="70%"]:after{right:-69.8px}.pace .pace-progress[data-progress-text="71%"]:after{right:-67.94px}.pace .pace-progress[data-progress-text="72%"]:after{right:-66.08px}.pace .pace-progress[data-progress-text="73%"]:after{right:-64.22px}.pace .pace-progress[data-progress-text="74%"]:after{right:-62.36px}.pace .pace-progress[data-progress-text="75%"]:after{right:-60.5px}.pace .pace-progress[data-progress-text="76%"]:after{right:-58.64px}.pace .pace-progress[data-progress-text="77%"]:after{right:-56.78px}.pace .pace-progress[data-progress-text="78%"]:after{right:-54.92px}.pace .pace-progress[data-progress-text="79%"]:after{right:-53.06px}.pace .pace-progress[data-progress-text="80%"]:after{right:-51.2px}.pace .pace-progress[data-progress-text="81%"]:after{right:-49.34px}.pace .pace-progress[data-progress-text="82%"]:after{right:-47.48px}.pace .pace-progress[data-progress-text="83%"]:after{right:-45.62px}.pace .pace-progress[data-progress-text="84%"]:after{right:-43.76px}.pace .pace-progress[data-progress-text="85%"]:after{right:-41.9px}.pace .pace-progress[data-progress-text="86%"]:after{right:-40.04px}.pace .pace-progress[data-progress-text="87%"]:after{right:-38.18px}.pace .pace-progress[data-progress-text="88%"]:after{right:-36.32px}.pace .pace-progress[data-progress-text="89%"]:after{right:-34.46px}.pace .pace-progress[data-progress-text="90%"]:after{right:-32.6px}.pace .pace-progress[data-progress-text="91%"]:after{right:-30.74px}.pace .pace-progress[data-progress-text="92%"]:after{right:-28.88px}.pace .pace-progress[data-progress-text="93%"]:after{right:-27.02px}.pace .pace-progress[data-progress-text="94%"]:after{right:-25.16px}.pace .pace-progress[data-progress-text="95%"]:after{right:-23.3px}.pace .pace-progress[data-progress-text="96%"]:after{right:-21.44px}.pace .pace-progress[data-progress-text="97%"]:after{right:-19.58px}.pace .pace-progress[data-progress-text="98%"]:after{right:-17.72px}.pace .pace-progress[data-progress-text="99%"]:after{right:-15.86px}.pace .pace-progress[data-progress-text="100%"]:after{right:-14px}.pace .pace-activity{position:absolute;width:100%;height:28px;z-index:2001;box-shadow:inset 0 0 0 2px #29d,inset 0 0 0 7px #FFF;border-radius:10px}.pace.pace-inactive{display:none} \ No newline at end of file diff --git a/lib/pace/pace-theme-mac-osx.min.css b/lib/pace/pace-theme-mac-osx.min.css new file mode 100644 index 0000000..4dfbb49 --- /dev/null +++ b/lib/pace/pace-theme-mac-osx.min.css @@ -0,0 +1 @@ +.pace,.pace .pace-progress{width:100%;height:12px;overflow:hidden}.pace,.pace .pace-activity{position:fixed;top:0;left:0}.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:2000;background:#fff}.pace-inactive{display:none}.pace .pace-progress{background-color:#0087E1;position:fixed;top:0;right:100%;-webkit-border-radius:0 0 4px;-moz-border-radius:0 0 4px;-o-border-radius:0 0 4px;border-radius:0 0 4px;-webkit-box-shadow:inset -1px 0 #00558F,inset 0 -1px #00558F,inset 0 2px rgba(255,255,255,.5),inset 0 6px rgba(255,255,255,.3);-moz-box-shadow:inset -1px 0 #00558F,inset 0 -1px #00558F,inset 0 2px rgba(255,255,255,.5),inset 0 6px rgba(255,255,255,.3);-o-box-shadow:inset -1px 0 #00558F,inset 0 -1px #00558F,inset 0 2px rgba(255,255,255,.5),inset 0 6px rgba(255,255,255,.3);box-shadow:inset -1px 0 #00558F,inset 0 -1px #00558F,inset 0 2px rgba(255,255,255,.5),inset 0 6px rgba(255,255,255,.3)}.pace .pace-activity{right:-28px;bottom:0;-webkit-background-image:radial-gradient(rgba(255,255,255,.65) 0,rgba(255,255,255,.15) 100%);-moz-background-image:radial-gradient(rgba(255,255,255,.65) 0,rgba(255,255,255,.15) 100%);-o-background-image:radial-gradient(rgba(255,255,255,.65) 0,rgba(255,255,255,.15) 100%);background-image:radial-gradient(rgba(255,255,255,.65) 0,rgba(255,255,255,.15) 100%);-webkit-background-size:28px 100%;-moz-background-size:28px 100%;-o-background-size:28px 100%;background-size:28px 100%;-webkit-animation:pace-theme-mac-osx-motion .5s linear infinite;-moz-animation:pace-theme-mac-osx-motion .5s linear infinite;-ms-animation:pace-theme-mac-osx-motion .5s linear infinite;-o-animation:pace-theme-mac-osx-motion .5s linear infinite;animation:pace-theme-mac-osx-motion .5s linear infinite}@-webkit-keyframes pace-theme-mac-osx-motion{0%{-webkit-transform:none;transform:none}100%{-webkit-transform:translate(-28px,0);transform:translate(-28px,0)}}@-moz-keyframes pace-theme-mac-osx-motion{0%{-moz-transform:none;transform:none}100%{-moz-transform:translate(-28px,0);transform:translate(-28px,0)}}@-o-keyframes pace-theme-mac-osx-motion{0%{-o-transform:none;transform:none}100%{-o-transform:translate(-28px,0);transform:translate(-28px,0)}}@-ms-keyframes pace-theme-mac-osx-motion{0%{-ms-transform:none;transform:none}100%{-ms-transform:translate(-28px,0);transform:translate(-28px,0)}}@keyframes pace-theme-mac-osx-motion{0%{transform:none}100%{transform:translate(-28px,0)}} \ No newline at end of file diff --git a/lib/pace/pace-theme-material.min.css b/lib/pace/pace-theme-material.min.css new file mode 100644 index 0000000..5f2920b --- /dev/null +++ b/lib/pace/pace-theme-material.min.css @@ -0,0 +1 @@ +.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:#29d}.pace-progress{position:fixed;z-index:2000;top:50%;left:50%;margin-left:-2.5rem;margin-top:-2.5rem;height:5rem;width:5rem;opacity:1;-webkit-transition:opacity .1s;transition:opacity .1s;-webkit-transform:translate3d(0,0,0)!important;-ms-transform:translate3d(0,0,0)!important;transform:translate3d(0,0,0)!important}.pace-inactive .pace-progress,.pace-progress[data-progress="00"]{opacity:0}.pace-progress:after{height:5rem;width:5rem;text-align:center;line-height:5rem;content:attr(data-progress);display:block;font-size:1.8rem;font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-weight:300}.pace-progress .pace-progress-inner{overflow:hidden;position:absolute;width:2.5rem;height:5rem;-webkit-transform-origin:left center;-ms-transform-origin:left center;transform-origin:left center;-webkit-transition:-webkit-transform .1s;transition:transform .1s;left:2.5rem;top:0}.pace-progress .pace-progress-inner:after,.pace-progress .pace-progress-inner:before{position:absolute;width:5rem;height:5rem;content:' ';left:-2.5rem;top:0;box-sizing:border-box;border:1px solid;border-radius:5rem}.pace-progress .pace-progress-inner:before{border-right-color:transparent;border-bottom-color:transparent;-webkit-transform:rotate(135deg);-ms-transform:rotate(135deg);transform:rotate(135deg)}.pace-progress .pace-progress-inner:after{border-left-color:transparent;border-top-color:transparent;display:none;-webkit-transform:rotate(315deg);-ms-transform:rotate(315deg);transform:rotate(315deg)}.pace-progress[data-progress="00"] .pace-progress-inner:before{-webkit-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.pace-progress[data-progress="01"] .pace-progress-inner:before{-webkit-transform:rotate(-41deg);-ms-transform:rotate(-41deg);transform:rotate(-41deg)}.pace-progress[data-progress="02"] .pace-progress-inner:before{-webkit-transform:rotate(-38deg);-ms-transform:rotate(-38deg);transform:rotate(-38deg)}.pace-progress[data-progress="03"] .pace-progress-inner:before{-webkit-transform:rotate(-34deg);-ms-transform:rotate(-34deg);transform:rotate(-34deg)}.pace-progress[data-progress="04"] .pace-progress-inner:before{-webkit-transform:rotate(-31deg);-ms-transform:rotate(-31deg);transform:rotate(-31deg)}.pace-progress[data-progress="05"] .pace-progress-inner:before{-webkit-transform:rotate(-27deg);-ms-transform:rotate(-27deg);transform:rotate(-27deg)}.pace-progress[data-progress="06"] .pace-progress-inner:before{-webkit-transform:rotate(-23deg);-ms-transform:rotate(-23deg);transform:rotate(-23deg)}.pace-progress[data-progress="07"] .pace-progress-inner:before{-webkit-transform:rotate(-20deg);-ms-transform:rotate(-20deg);transform:rotate(-20deg)}.pace-progress[data-progress="08"] .pace-progress-inner:before{-webkit-transform:rotate(-16deg);-ms-transform:rotate(-16deg);transform:rotate(-16deg)}.pace-progress[data-progress="09"] .pace-progress-inner:before{-webkit-transform:rotate(-13deg);-ms-transform:rotate(-13deg);transform:rotate(-13deg)}.pace-progress[data-progress="10"] .pace-progress-inner:before{-webkit-transform:rotate(-9deg);-ms-transform:rotate(-9deg);transform:rotate(-9deg)}.pace-progress[data-progress="11"] .pace-progress-inner:before{-webkit-transform:rotate(-5deg);-ms-transform:rotate(-5deg);transform:rotate(-5deg)}.pace-progress[data-progress="12"] .pace-progress-inner:before{-webkit-transform:rotate(-2deg);-ms-transform:rotate(-2deg);transform:rotate(-2deg)}.pace-progress[data-progress="13"] .pace-progress-inner:before{-webkit-transform:rotate(2deg);-ms-transform:rotate(2deg);transform:rotate(2deg)}.pace-progress[data-progress="14"] .pace-progress-inner:before{-webkit-transform:rotate(5deg);-ms-transform:rotate(5deg);transform:rotate(5deg)}.pace-progress[data-progress="15"] .pace-progress-inner:before{-webkit-transform:rotate(9deg);-ms-transform:rotate(9deg);transform:rotate(9deg)}.pace-progress[data-progress="16"] .pace-progress-inner:before{-webkit-transform:rotate(13deg);-ms-transform:rotate(13deg);transform:rotate(13deg)}.pace-progress[data-progress="17"] .pace-progress-inner:before{-webkit-transform:rotate(16deg);-ms-transform:rotate(16deg);transform:rotate(16deg)}.pace-progress[data-progress="18"] .pace-progress-inner:before{-webkit-transform:rotate(20deg);-ms-transform:rotate(20deg);transform:rotate(20deg)}.pace-progress[data-progress="19"] .pace-progress-inner:before{-webkit-transform:rotate(23deg);-ms-transform:rotate(23deg);transform:rotate(23deg)}.pace-progress[data-progress="20"] .pace-progress-inner:before{-webkit-transform:rotate(27deg);-ms-transform:rotate(27deg);transform:rotate(27deg)}.pace-progress[data-progress="21"] .pace-progress-inner:before{-webkit-transform:rotate(31deg);-ms-transform:rotate(31deg);transform:rotate(31deg)}.pace-progress[data-progress="22"] .pace-progress-inner:before{-webkit-transform:rotate(34deg);-ms-transform:rotate(34deg);transform:rotate(34deg)}.pace-progress[data-progress="23"] .pace-progress-inner:before{-webkit-transform:rotate(38deg);-ms-transform:rotate(38deg);transform:rotate(38deg)}.pace-progress[data-progress="24"] .pace-progress-inner:before{-webkit-transform:rotate(41deg);-ms-transform:rotate(41deg);transform:rotate(41deg)}.pace-progress[data-progress="25"] .pace-progress-inner:before{-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.pace-progress[data-progress="26"] .pace-progress-inner:before{-webkit-transform:rotate(49deg);-ms-transform:rotate(49deg);transform:rotate(49deg)}.pace-progress[data-progress="27"] .pace-progress-inner:before{-webkit-transform:rotate(52deg);-ms-transform:rotate(52deg);transform:rotate(52deg)}.pace-progress[data-progress="28"] .pace-progress-inner:before{-webkit-transform:rotate(56deg);-ms-transform:rotate(56deg);transform:rotate(56deg)}.pace-progress[data-progress="29"] .pace-progress-inner:before{-webkit-transform:rotate(59deg);-ms-transform:rotate(59deg);transform:rotate(59deg)}.pace-progress[data-progress="30"] .pace-progress-inner:before{-webkit-transform:rotate(63deg);-ms-transform:rotate(63deg);transform:rotate(63deg)}.pace-progress[data-progress="31"] .pace-progress-inner:before{-webkit-transform:rotate(67deg);-ms-transform:rotate(67deg);transform:rotate(67deg)}.pace-progress[data-progress="32"] .pace-progress-inner:before{-webkit-transform:rotate(70deg);-ms-transform:rotate(70deg);transform:rotate(70deg)}.pace-progress[data-progress="33"] .pace-progress-inner:before{-webkit-transform:rotate(74deg);-ms-transform:rotate(74deg);transform:rotate(74deg)}.pace-progress[data-progress="34"] .pace-progress-inner:before{-webkit-transform:rotate(77deg);-ms-transform:rotate(77deg);transform:rotate(77deg)}.pace-progress[data-progress="35"] .pace-progress-inner:before{-webkit-transform:rotate(81deg);-ms-transform:rotate(81deg);transform:rotate(81deg)}.pace-progress[data-progress="36"] .pace-progress-inner:before{-webkit-transform:rotate(85deg);-ms-transform:rotate(85deg);transform:rotate(85deg)}.pace-progress[data-progress="37"] .pace-progress-inner:before{-webkit-transform:rotate(88deg);-ms-transform:rotate(88deg);transform:rotate(88deg)}.pace-progress[data-progress="38"] .pace-progress-inner:before{-webkit-transform:rotate(92deg);-ms-transform:rotate(92deg);transform:rotate(92deg)}.pace-progress[data-progress="39"] .pace-progress-inner:before{-webkit-transform:rotate(95deg);-ms-transform:rotate(95deg);transform:rotate(95deg)}.pace-progress[data-progress="40"] .pace-progress-inner:before{-webkit-transform:rotate(99deg);-ms-transform:rotate(99deg);transform:rotate(99deg)}.pace-progress[data-progress="41"] .pace-progress-inner:before{-webkit-transform:rotate(103deg);-ms-transform:rotate(103deg);transform:rotate(103deg)}.pace-progress[data-progress="42"] .pace-progress-inner:before{-webkit-transform:rotate(106deg);-ms-transform:rotate(106deg);transform:rotate(106deg)}.pace-progress[data-progress="43"] .pace-progress-inner:before{-webkit-transform:rotate(110deg);-ms-transform:rotate(110deg);transform:rotate(110deg)}.pace-progress[data-progress="44"] .pace-progress-inner:before{-webkit-transform:rotate(113deg);-ms-transform:rotate(113deg);transform:rotate(113deg)}.pace-progress[data-progress="45"] .pace-progress-inner:before{-webkit-transform:rotate(117deg);-ms-transform:rotate(117deg);transform:rotate(117deg)}.pace-progress[data-progress="46"] .pace-progress-inner:before{-webkit-transform:rotate(121deg);-ms-transform:rotate(121deg);transform:rotate(121deg)}.pace-progress[data-progress="47"] .pace-progress-inner:before{-webkit-transform:rotate(124deg);-ms-transform:rotate(124deg);transform:rotate(124deg)}.pace-progress[data-progress="48"] .pace-progress-inner:before{-webkit-transform:rotate(128deg);-ms-transform:rotate(128deg);transform:rotate(128deg)}.pace-progress[data-progress="49"] .pace-progress-inner:before{-webkit-transform:rotate(131deg);-ms-transform:rotate(131deg);transform:rotate(131deg)}.pace-progress[data-progress="50"] .pace-progress-inner:before{-webkit-transform:rotate(135deg);-ms-transform:rotate(135deg);transform:rotate(135deg)}.pace-progress[data-progress="50"] .pace-progress-inner:after{-webkit-transform:rotate(315deg);-ms-transform:rotate(315deg);transform:rotate(315deg);display:block}.pace-progress[data-progress="51"] .pace-progress-inner:after{-webkit-transform:rotate(319deg);-ms-transform:rotate(319deg);transform:rotate(319deg);display:block}.pace-progress[data-progress="52"] .pace-progress-inner:after{-webkit-transform:rotate(322deg);-ms-transform:rotate(322deg);transform:rotate(322deg);display:block}.pace-progress[data-progress="53"] .pace-progress-inner:after{-webkit-transform:rotate(326deg);-ms-transform:rotate(326deg);transform:rotate(326deg);display:block}.pace-progress[data-progress="54"] .pace-progress-inner:after{-webkit-transform:rotate(329deg);-ms-transform:rotate(329deg);transform:rotate(329deg);display:block}.pace-progress[data-progress="55"] .pace-progress-inner:after{-webkit-transform:rotate(333deg);-ms-transform:rotate(333deg);transform:rotate(333deg);display:block}.pace-progress[data-progress="56"] .pace-progress-inner:after{-webkit-transform:rotate(337deg);-ms-transform:rotate(337deg);transform:rotate(337deg);display:block}.pace-progress[data-progress="57"] .pace-progress-inner:after{-webkit-transform:rotate(340deg);-ms-transform:rotate(340deg);transform:rotate(340deg);display:block}.pace-progress[data-progress="58"] .pace-progress-inner:after{-webkit-transform:rotate(344deg);-ms-transform:rotate(344deg);transform:rotate(344deg);display:block}.pace-progress[data-progress="59"] .pace-progress-inner:after{-webkit-transform:rotate(347deg);-ms-transform:rotate(347deg);transform:rotate(347deg);display:block}.pace-progress[data-progress="60"] .pace-progress-inner:after{-webkit-transform:rotate(351deg);-ms-transform:rotate(351deg);transform:rotate(351deg);display:block}.pace-progress[data-progress="61"] .pace-progress-inner:after{-webkit-transform:rotate(355deg);-ms-transform:rotate(355deg);transform:rotate(355deg);display:block}.pace-progress[data-progress="62"] .pace-progress-inner:after{-webkit-transform:rotate(358deg);-ms-transform:rotate(358deg);transform:rotate(358deg);display:block}.pace-progress[data-progress="63"] .pace-progress-inner:after{-webkit-transform:rotate(362deg);-ms-transform:rotate(362deg);transform:rotate(362deg);display:block}.pace-progress[data-progress="64"] .pace-progress-inner:after{-webkit-transform:rotate(365deg);-ms-transform:rotate(365deg);transform:rotate(365deg);display:block}.pace-progress[data-progress="65"] .pace-progress-inner:after{-webkit-transform:rotate(369deg);-ms-transform:rotate(369deg);transform:rotate(369deg);display:block}.pace-progress[data-progress="66"] .pace-progress-inner:after{-webkit-transform:rotate(373deg);-ms-transform:rotate(373deg);transform:rotate(373deg);display:block}.pace-progress[data-progress="67"] .pace-progress-inner:after{-webkit-transform:rotate(376deg);-ms-transform:rotate(376deg);transform:rotate(376deg);display:block}.pace-progress[data-progress="68"] .pace-progress-inner:after{-webkit-transform:rotate(380deg);-ms-transform:rotate(380deg);transform:rotate(380deg);display:block}.pace-progress[data-progress="69"] .pace-progress-inner:after{-webkit-transform:rotate(383deg);-ms-transform:rotate(383deg);transform:rotate(383deg);display:block}.pace-progress[data-progress="70"] .pace-progress-inner:after{-webkit-transform:rotate(387deg);-ms-transform:rotate(387deg);transform:rotate(387deg);display:block}.pace-progress[data-progress="71"] .pace-progress-inner:after{-webkit-transform:rotate(391deg);-ms-transform:rotate(391deg);transform:rotate(391deg);display:block}.pace-progress[data-progress="72"] .pace-progress-inner:after{-webkit-transform:rotate(394deg);-ms-transform:rotate(394deg);transform:rotate(394deg);display:block}.pace-progress[data-progress="73"] .pace-progress-inner:after{-webkit-transform:rotate(398deg);-ms-transform:rotate(398deg);transform:rotate(398deg);display:block}.pace-progress[data-progress="74"] .pace-progress-inner:after{-webkit-transform:rotate(401deg);-ms-transform:rotate(401deg);transform:rotate(401deg);display:block}.pace-progress[data-progress="75"] .pace-progress-inner:after{-webkit-transform:rotate(405deg);-ms-transform:rotate(405deg);transform:rotate(405deg);display:block}.pace-progress[data-progress="76"] .pace-progress-inner:after{-webkit-transform:rotate(409deg);-ms-transform:rotate(409deg);transform:rotate(409deg);display:block}.pace-progress[data-progress="77"] .pace-progress-inner:after{-webkit-transform:rotate(412deg);-ms-transform:rotate(412deg);transform:rotate(412deg);display:block}.pace-progress[data-progress="78"] .pace-progress-inner:after{-webkit-transform:rotate(416deg);-ms-transform:rotate(416deg);transform:rotate(416deg);display:block}.pace-progress[data-progress="79"] .pace-progress-inner:after{-webkit-transform:rotate(419deg);-ms-transform:rotate(419deg);transform:rotate(419deg);display:block}.pace-progress[data-progress="80"] .pace-progress-inner:after{-webkit-transform:rotate(423deg);-ms-transform:rotate(423deg);transform:rotate(423deg);display:block}.pace-progress[data-progress="81"] .pace-progress-inner:after{-webkit-transform:rotate(427deg);-ms-transform:rotate(427deg);transform:rotate(427deg);display:block}.pace-progress[data-progress="82"] .pace-progress-inner:after{-webkit-transform:rotate(430deg);-ms-transform:rotate(430deg);transform:rotate(430deg);display:block}.pace-progress[data-progress="83"] .pace-progress-inner:after{-webkit-transform:rotate(434deg);-ms-transform:rotate(434deg);transform:rotate(434deg);display:block}.pace-progress[data-progress="84"] .pace-progress-inner:after{-webkit-transform:rotate(437deg);-ms-transform:rotate(437deg);transform:rotate(437deg);display:block}.pace-progress[data-progress="85"] .pace-progress-inner:after{-webkit-transform:rotate(441deg);-ms-transform:rotate(441deg);transform:rotate(441deg);display:block}.pace-progress[data-progress="86"] .pace-progress-inner:after{-webkit-transform:rotate(445deg);-ms-transform:rotate(445deg);transform:rotate(445deg);display:block}.pace-progress[data-progress="87"] .pace-progress-inner:after{-webkit-transform:rotate(448deg);-ms-transform:rotate(448deg);transform:rotate(448deg);display:block}.pace-progress[data-progress="88"] .pace-progress-inner:after{-webkit-transform:rotate(452deg);-ms-transform:rotate(452deg);transform:rotate(452deg);display:block}.pace-progress[data-progress="89"] .pace-progress-inner:after{-webkit-transform:rotate(455deg);-ms-transform:rotate(455deg);transform:rotate(455deg);display:block}.pace-progress[data-progress="90"] .pace-progress-inner:after{-webkit-transform:rotate(459deg);-ms-transform:rotate(459deg);transform:rotate(459deg);display:block}.pace-progress[data-progress="91"] .pace-progress-inner:after{-webkit-transform:rotate(463deg);-ms-transform:rotate(463deg);transform:rotate(463deg);display:block}.pace-progress[data-progress="92"] .pace-progress-inner:after{-webkit-transform:rotate(466deg);-ms-transform:rotate(466deg);transform:rotate(466deg);display:block}.pace-progress[data-progress="93"] .pace-progress-inner:after{-webkit-transform:rotate(470deg);-ms-transform:rotate(470deg);transform:rotate(470deg);display:block}.pace-progress[data-progress="94"] .pace-progress-inner:after{-webkit-transform:rotate(473deg);-ms-transform:rotate(473deg);transform:rotate(473deg);display:block}.pace-progress[data-progress="95"] .pace-progress-inner:after{-webkit-transform:rotate(477deg);-ms-transform:rotate(477deg);transform:rotate(477deg);display:block}.pace-progress[data-progress="96"] .pace-progress-inner:after{-webkit-transform:rotate(481deg);-ms-transform:rotate(481deg);transform:rotate(481deg);display:block}.pace-progress[data-progress="97"] .pace-progress-inner:after{-webkit-transform:rotate(484deg);-ms-transform:rotate(484deg);transform:rotate(484deg);display:block}.pace-progress[data-progress="98"] .pace-progress-inner:after{-webkit-transform:rotate(488deg);-ms-transform:rotate(488deg);transform:rotate(488deg);display:block}.pace-progress[data-progress="99"] .pace-progress-inner:after{-webkit-transform:rotate(491deg);-ms-transform:rotate(491deg);transform:rotate(491deg);display:block}.pace-progress[data-progress="100"] .pace-progress-inner:after{-webkit-transform:rotate(495deg);-ms-transform:rotate(495deg);transform:rotate(495deg);display:block}.pace-progress[data-progress="00"] .pace-progress-inner{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}.pace-progress[data-progress="01"] .pace-progress-inner{-webkit-transform:rotate(4deg);-ms-transform:rotate(4deg);transform:rotate(4deg)}.pace-progress[data-progress="02"] .pace-progress-inner{-webkit-transform:rotate(7deg);-ms-transform:rotate(7deg);transform:rotate(7deg)}.pace-progress[data-progress="03"] .pace-progress-inner{-webkit-transform:rotate(11deg);-ms-transform:rotate(11deg);transform:rotate(11deg)}.pace-progress[data-progress="04"] .pace-progress-inner{-webkit-transform:rotate(14deg);-ms-transform:rotate(14deg);transform:rotate(14deg)}.pace-progress[data-progress="05"] .pace-progress-inner{-webkit-transform:rotate(18deg);-ms-transform:rotate(18deg);transform:rotate(18deg)}.pace-progress[data-progress="06"] .pace-progress-inner{-webkit-transform:rotate(22deg);-ms-transform:rotate(22deg);transform:rotate(22deg)}.pace-progress[data-progress="07"] .pace-progress-inner{-webkit-transform:rotate(25deg);-ms-transform:rotate(25deg);transform:rotate(25deg)}.pace-progress[data-progress="08"] .pace-progress-inner{-webkit-transform:rotate(29deg);-ms-transform:rotate(29deg);transform:rotate(29deg)}.pace-progress[data-progress="09"] .pace-progress-inner{-webkit-transform:rotate(32deg);-ms-transform:rotate(32deg);transform:rotate(32deg)}.pace-progress[data-progress="10"] .pace-progress-inner{-webkit-transform:rotate(36deg);-ms-transform:rotate(36deg);transform:rotate(36deg)}.pace-progress[data-progress="11"] .pace-progress-inner{-webkit-transform:rotate(40deg);-ms-transform:rotate(40deg);transform:rotate(40deg)}.pace-progress[data-progress="12"] .pace-progress-inner{-webkit-transform:rotate(43deg);-ms-transform:rotate(43deg);transform:rotate(43deg)}.pace-progress[data-progress="13"] .pace-progress-inner{-webkit-transform:rotate(47deg);-ms-transform:rotate(47deg);transform:rotate(47deg)}.pace-progress[data-progress="14"] .pace-progress-inner{-webkit-transform:rotate(50deg);-ms-transform:rotate(50deg);transform:rotate(50deg)}.pace-progress[data-progress="15"] .pace-progress-inner{-webkit-transform:rotate(54deg);-ms-transform:rotate(54deg);transform:rotate(54deg)}.pace-progress[data-progress="16"] .pace-progress-inner{-webkit-transform:rotate(58deg);-ms-transform:rotate(58deg);transform:rotate(58deg)}.pace-progress[data-progress="17"] .pace-progress-inner{-webkit-transform:rotate(61deg);-ms-transform:rotate(61deg);transform:rotate(61deg)}.pace-progress[data-progress="18"] .pace-progress-inner{-webkit-transform:rotate(65deg);-ms-transform:rotate(65deg);transform:rotate(65deg)}.pace-progress[data-progress="19"] .pace-progress-inner{-webkit-transform:rotate(68deg);-ms-transform:rotate(68deg);transform:rotate(68deg)}.pace-progress[data-progress="20"] .pace-progress-inner{-webkit-transform:rotate(72deg);-ms-transform:rotate(72deg);transform:rotate(72deg)}.pace-progress[data-progress="21"] .pace-progress-inner{-webkit-transform:rotate(76deg);-ms-transform:rotate(76deg);transform:rotate(76deg)}.pace-progress[data-progress="22"] .pace-progress-inner{-webkit-transform:rotate(79deg);-ms-transform:rotate(79deg);transform:rotate(79deg)}.pace-progress[data-progress="23"] .pace-progress-inner{-webkit-transform:rotate(83deg);-ms-transform:rotate(83deg);transform:rotate(83deg)}.pace-progress[data-progress="24"] .pace-progress-inner{-webkit-transform:rotate(86deg);-ms-transform:rotate(86deg);transform:rotate(86deg)}.pace-progress[data-progress="25"] .pace-progress-inner{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.pace-progress[data-progress="26"] .pace-progress-inner{-webkit-transform:rotate(94deg);-ms-transform:rotate(94deg);transform:rotate(94deg)}.pace-progress[data-progress="27"] .pace-progress-inner{-webkit-transform:rotate(97deg);-ms-transform:rotate(97deg);transform:rotate(97deg)}.pace-progress[data-progress="28"] .pace-progress-inner{-webkit-transform:rotate(101deg);-ms-transform:rotate(101deg);transform:rotate(101deg)}.pace-progress[data-progress="29"] .pace-progress-inner{-webkit-transform:rotate(104deg);-ms-transform:rotate(104deg);transform:rotate(104deg)}.pace-progress[data-progress="30"] .pace-progress-inner{-webkit-transform:rotate(108deg);-ms-transform:rotate(108deg);transform:rotate(108deg)}.pace-progress[data-progress="31"] .pace-progress-inner{-webkit-transform:rotate(112deg);-ms-transform:rotate(112deg);transform:rotate(112deg)}.pace-progress[data-progress="32"] .pace-progress-inner{-webkit-transform:rotate(115deg);-ms-transform:rotate(115deg);transform:rotate(115deg)}.pace-progress[data-progress="33"] .pace-progress-inner{-webkit-transform:rotate(119deg);-ms-transform:rotate(119deg);transform:rotate(119deg)}.pace-progress[data-progress="34"] .pace-progress-inner{-webkit-transform:rotate(122deg);-ms-transform:rotate(122deg);transform:rotate(122deg)}.pace-progress[data-progress="35"] .pace-progress-inner{-webkit-transform:rotate(126deg);-ms-transform:rotate(126deg);transform:rotate(126deg)}.pace-progress[data-progress="36"] .pace-progress-inner{-webkit-transform:rotate(130deg);-ms-transform:rotate(130deg);transform:rotate(130deg)}.pace-progress[data-progress="37"] .pace-progress-inner{-webkit-transform:rotate(133deg);-ms-transform:rotate(133deg);transform:rotate(133deg)}.pace-progress[data-progress="38"] .pace-progress-inner{-webkit-transform:rotate(137deg);-ms-transform:rotate(137deg);transform:rotate(137deg)}.pace-progress[data-progress="39"] .pace-progress-inner{-webkit-transform:rotate(140deg);-ms-transform:rotate(140deg);transform:rotate(140deg)}.pace-progress[data-progress="40"] .pace-progress-inner{-webkit-transform:rotate(144deg);-ms-transform:rotate(144deg);transform:rotate(144deg)}.pace-progress[data-progress="41"] .pace-progress-inner{-webkit-transform:rotate(148deg);-ms-transform:rotate(148deg);transform:rotate(148deg)}.pace-progress[data-progress="42"] .pace-progress-inner{-webkit-transform:rotate(151deg);-ms-transform:rotate(151deg);transform:rotate(151deg)}.pace-progress[data-progress="43"] .pace-progress-inner{-webkit-transform:rotate(155deg);-ms-transform:rotate(155deg);transform:rotate(155deg)}.pace-progress[data-progress="44"] .pace-progress-inner{-webkit-transform:rotate(158deg);-ms-transform:rotate(158deg);transform:rotate(158deg)}.pace-progress[data-progress="45"] .pace-progress-inner{-webkit-transform:rotate(162deg);-ms-transform:rotate(162deg);transform:rotate(162deg)}.pace-progress[data-progress="46"] .pace-progress-inner{-webkit-transform:rotate(166deg);-ms-transform:rotate(166deg);transform:rotate(166deg)}.pace-progress[data-progress="47"] .pace-progress-inner{-webkit-transform:rotate(169deg);-ms-transform:rotate(169deg);transform:rotate(169deg)}.pace-progress[data-progress="48"] .pace-progress-inner{-webkit-transform:rotate(173deg);-ms-transform:rotate(173deg);transform:rotate(173deg)}.pace-progress[data-progress="49"] .pace-progress-inner{-webkit-transform:rotate(176deg);-ms-transform:rotate(176deg);transform:rotate(176deg)}.pace-progress[data-progress="50"] .pace-progress-inner{-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.pace-progress[data-progress="51"] .pace-progress-inner{-webkit-transform:rotate(184deg);-ms-transform:rotate(184deg);transform:rotate(184deg);overflow:visible}.pace-progress[data-progress="52"] .pace-progress-inner{-webkit-transform:rotate(187deg);-ms-transform:rotate(187deg);transform:rotate(187deg);overflow:visible}.pace-progress[data-progress="53"] .pace-progress-inner{-webkit-transform:rotate(191deg);-ms-transform:rotate(191deg);transform:rotate(191deg);overflow:visible}.pace-progress[data-progress="54"] .pace-progress-inner{-webkit-transform:rotate(194deg);-ms-transform:rotate(194deg);transform:rotate(194deg);overflow:visible}.pace-progress[data-progress="55"] .pace-progress-inner{-webkit-transform:rotate(198deg);-ms-transform:rotate(198deg);transform:rotate(198deg);overflow:visible}.pace-progress[data-progress="56"] .pace-progress-inner{-webkit-transform:rotate(202deg);-ms-transform:rotate(202deg);transform:rotate(202deg);overflow:visible}.pace-progress[data-progress="57"] .pace-progress-inner{-webkit-transform:rotate(205deg);-ms-transform:rotate(205deg);transform:rotate(205deg);overflow:visible}.pace-progress[data-progress="58"] .pace-progress-inner{-webkit-transform:rotate(209deg);-ms-transform:rotate(209deg);transform:rotate(209deg);overflow:visible}.pace-progress[data-progress="59"] .pace-progress-inner{-webkit-transform:rotate(212deg);-ms-transform:rotate(212deg);transform:rotate(212deg);overflow:visible}.pace-progress[data-progress="60"] .pace-progress-inner{-webkit-transform:rotate(216deg);-ms-transform:rotate(216deg);transform:rotate(216deg);overflow:visible}.pace-progress[data-progress="61"] .pace-progress-inner{-webkit-transform:rotate(220deg);-ms-transform:rotate(220deg);transform:rotate(220deg);overflow:visible}.pace-progress[data-progress="62"] .pace-progress-inner{-webkit-transform:rotate(223deg);-ms-transform:rotate(223deg);transform:rotate(223deg);overflow:visible}.pace-progress[data-progress="63"] .pace-progress-inner{-webkit-transform:rotate(227deg);-ms-transform:rotate(227deg);transform:rotate(227deg);overflow:visible}.pace-progress[data-progress="64"] .pace-progress-inner{-webkit-transform:rotate(230deg);-ms-transform:rotate(230deg);transform:rotate(230deg);overflow:visible}.pace-progress[data-progress="65"] .pace-progress-inner{-webkit-transform:rotate(234deg);-ms-transform:rotate(234deg);transform:rotate(234deg);overflow:visible}.pace-progress[data-progress="66"] .pace-progress-inner{-webkit-transform:rotate(238deg);-ms-transform:rotate(238deg);transform:rotate(238deg);overflow:visible}.pace-progress[data-progress="67"] .pace-progress-inner{-webkit-transform:rotate(241deg);-ms-transform:rotate(241deg);transform:rotate(241deg);overflow:visible}.pace-progress[data-progress="68"] .pace-progress-inner{-webkit-transform:rotate(245deg);-ms-transform:rotate(245deg);transform:rotate(245deg);overflow:visible}.pace-progress[data-progress="69"] .pace-progress-inner{-webkit-transform:rotate(248deg);-ms-transform:rotate(248deg);transform:rotate(248deg);overflow:visible}.pace-progress[data-progress="70"] .pace-progress-inner{-webkit-transform:rotate(252deg);-ms-transform:rotate(252deg);transform:rotate(252deg);overflow:visible}.pace-progress[data-progress="71"] .pace-progress-inner{-webkit-transform:rotate(256deg);-ms-transform:rotate(256deg);transform:rotate(256deg);overflow:visible}.pace-progress[data-progress="72"] .pace-progress-inner{-webkit-transform:rotate(259deg);-ms-transform:rotate(259deg);transform:rotate(259deg);overflow:visible}.pace-progress[data-progress="73"] .pace-progress-inner{-webkit-transform:rotate(263deg);-ms-transform:rotate(263deg);transform:rotate(263deg);overflow:visible}.pace-progress[data-progress="74"] .pace-progress-inner{-webkit-transform:rotate(266deg);-ms-transform:rotate(266deg);transform:rotate(266deg);overflow:visible}.pace-progress[data-progress="75"] .pace-progress-inner{-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg);overflow:visible}.pace-progress[data-progress="76"] .pace-progress-inner{-webkit-transform:rotate(274deg);-ms-transform:rotate(274deg);transform:rotate(274deg);overflow:visible}.pace-progress[data-progress="77"] .pace-progress-inner{-webkit-transform:rotate(277deg);-ms-transform:rotate(277deg);transform:rotate(277deg);overflow:visible}.pace-progress[data-progress="78"] .pace-progress-inner{-webkit-transform:rotate(281deg);-ms-transform:rotate(281deg);transform:rotate(281deg);overflow:visible}.pace-progress[data-progress="79"] .pace-progress-inner{-webkit-transform:rotate(284deg);-ms-transform:rotate(284deg);transform:rotate(284deg);overflow:visible}.pace-progress[data-progress="80"] .pace-progress-inner{-webkit-transform:rotate(288deg);-ms-transform:rotate(288deg);transform:rotate(288deg);overflow:visible}.pace-progress[data-progress="81"] .pace-progress-inner{-webkit-transform:rotate(292deg);-ms-transform:rotate(292deg);transform:rotate(292deg);overflow:visible}.pace-progress[data-progress="82"] .pace-progress-inner{-webkit-transform:rotate(295deg);-ms-transform:rotate(295deg);transform:rotate(295deg);overflow:visible}.pace-progress[data-progress="83"] .pace-progress-inner{-webkit-transform:rotate(299deg);-ms-transform:rotate(299deg);transform:rotate(299deg);overflow:visible}.pace-progress[data-progress="84"] .pace-progress-inner{-webkit-transform:rotate(302deg);-ms-transform:rotate(302deg);transform:rotate(302deg);overflow:visible}.pace-progress[data-progress="85"] .pace-progress-inner{-webkit-transform:rotate(306deg);-ms-transform:rotate(306deg);transform:rotate(306deg);overflow:visible}.pace-progress[data-progress="86"] .pace-progress-inner{-webkit-transform:rotate(310deg);-ms-transform:rotate(310deg);transform:rotate(310deg);overflow:visible}.pace-progress[data-progress="87"] .pace-progress-inner{-webkit-transform:rotate(313deg);-ms-transform:rotate(313deg);transform:rotate(313deg);overflow:visible}.pace-progress[data-progress="88"] .pace-progress-inner{-webkit-transform:rotate(317deg);-ms-transform:rotate(317deg);transform:rotate(317deg);overflow:visible}.pace-progress[data-progress="89"] .pace-progress-inner{-webkit-transform:rotate(320deg);-ms-transform:rotate(320deg);transform:rotate(320deg);overflow:visible}.pace-progress[data-progress="90"] .pace-progress-inner{-webkit-transform:rotate(324deg);-ms-transform:rotate(324deg);transform:rotate(324deg);overflow:visible}.pace-progress[data-progress="91"] .pace-progress-inner{-webkit-transform:rotate(328deg);-ms-transform:rotate(328deg);transform:rotate(328deg);overflow:visible}.pace-progress[data-progress="92"] .pace-progress-inner{-webkit-transform:rotate(331deg);-ms-transform:rotate(331deg);transform:rotate(331deg);overflow:visible}.pace-progress[data-progress="93"] .pace-progress-inner{-webkit-transform:rotate(335deg);-ms-transform:rotate(335deg);transform:rotate(335deg);overflow:visible}.pace-progress[data-progress="94"] .pace-progress-inner{-webkit-transform:rotate(338deg);-ms-transform:rotate(338deg);transform:rotate(338deg);overflow:visible}.pace-progress[data-progress="95"] .pace-progress-inner{-webkit-transform:rotate(342deg);-ms-transform:rotate(342deg);transform:rotate(342deg);overflow:visible}.pace-progress[data-progress="96"] .pace-progress-inner{-webkit-transform:rotate(346deg);-ms-transform:rotate(346deg);transform:rotate(346deg);overflow:visible}.pace-progress[data-progress="97"] .pace-progress-inner{-webkit-transform:rotate(349deg);-ms-transform:rotate(349deg);transform:rotate(349deg);overflow:visible}.pace-progress[data-progress="98"] .pace-progress-inner{-webkit-transform:rotate(353deg);-ms-transform:rotate(353deg);transform:rotate(353deg);overflow:visible}.pace-progress[data-progress="99"] .pace-progress-inner{-webkit-transform:rotate(356deg);-ms-transform:rotate(356deg);transform:rotate(356deg);overflow:visible}.pace-progress[data-progress="100"] .pace-progress-inner{-webkit-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg);overflow:visible} diff --git a/lib/pace/pace-theme-minimal.min.css b/lib/pace/pace-theme-minimal.min.css new file mode 100644 index 0000000..1c15936 --- /dev/null +++ b/lib/pace/pace-theme-minimal.min.css @@ -0,0 +1 @@ +.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.pace-inactive{display:none}.pace .pace-progress{background:#29d;position:fixed;z-index:2000;top:0;right:100%;width:100%;height:2px} \ No newline at end of file diff --git a/lib/pace/pace.min.js b/lib/pace/pace.min.js new file mode 100644 index 0000000..234f9b3 --- /dev/null +++ b/lib/pace/pace.min.js @@ -0,0 +1,2 @@ +/*! pace 1.0.2 */ +(function(){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X=[].slice,Y={}.hasOwnProperty,Z=function(a,b){function c(){this.constructor=a}for(var d in b)Y.call(b,d)&&(a[d]=b[d]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a},$=[].indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(b in this&&this[b]===a)return b;return-1};for(u={catchupTime:100,initialRate:.03,minTime:250,ghostTime:100,maxProgressPerFrame:20,easeFactor:1.25,startOnPageLoad:!0,restartOnPushState:!0,restartOnRequestAfter:500,target:"body",elements:{checkInterval:100,selectors:["body"]},eventLag:{minSamples:10,sampleCount:3,lagThreshold:3},ajax:{trackMethods:["GET"],trackWebSockets:!0,ignoreURLs:[]}},C=function(){var a;return null!=(a="undefined"!=typeof performance&&null!==performance&&"function"==typeof performance.now?performance.now():void 0)?a:+new Date},E=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame,t=window.cancelAnimationFrame||window.mozCancelAnimationFrame,null==E&&(E=function(a){return setTimeout(a,50)},t=function(a){return clearTimeout(a)}),G=function(a){var b,c;return b=C(),(c=function(){var d;return d=C()-b,d>=33?(b=C(),a(d,function(){return E(c)})):setTimeout(c,33-d)})()},F=function(){var a,b,c;return c=arguments[0],b=arguments[1],a=3<=arguments.length?X.call(arguments,2):[],"function"==typeof c[b]?c[b].apply(c,a):c[b]},v=function(){var a,b,c,d,e,f,g;for(b=arguments[0],d=2<=arguments.length?X.call(arguments,1):[],f=0,g=d.length;g>f;f++)if(c=d[f])for(a in c)Y.call(c,a)&&(e=c[a],null!=b[a]&&"object"==typeof b[a]&&null!=e&&"object"==typeof e?v(b[a],e):b[a]=e);return b},q=function(a){var b,c,d,e,f;for(c=b=0,e=0,f=a.length;f>e;e++)d=a[e],c+=Math.abs(d),b++;return c/b},x=function(a,b){var c,d,e;if(null==a&&(a="options"),null==b&&(b=!0),e=document.querySelector("[data-pace-"+a+"]")){if(c=e.getAttribute("data-pace-"+a),!b)return c;try{return JSON.parse(c)}catch(f){return d=f,"undefined"!=typeof console&&null!==console?console.error("Error parsing inline pace options",d):void 0}}},g=function(){function a(){}return a.prototype.on=function(a,b,c,d){var e;return null==d&&(d=!1),null==this.bindings&&(this.bindings={}),null==(e=this.bindings)[a]&&(e[a]=[]),this.bindings[a].push({handler:b,ctx:c,once:d})},a.prototype.once=function(a,b,c){return this.on(a,b,c,!0)},a.prototype.off=function(a,b){var c,d,e;if(null!=(null!=(d=this.bindings)?d[a]:void 0)){if(null==b)return delete this.bindings[a];for(c=0,e=[];cQ;Q++)K=U[Q],D[K]===!0&&(D[K]=u[K]);i=function(a){function b(){return V=b.__super__.constructor.apply(this,arguments)}return Z(b,a),b}(Error),b=function(){function a(){this.progress=0}return a.prototype.getElement=function(){var a;if(null==this.el){if(a=document.querySelector(D.target),!a)throw new i;this.el=document.createElement("div"),this.el.className="pace pace-active",document.body.className=document.body.className.replace(/pace-done/g,""),document.body.className+=" pace-running",this.el.innerHTML='
\n
\n
\n
',null!=a.firstChild?a.insertBefore(this.el,a.firstChild):a.appendChild(this.el)}return this.el},a.prototype.finish=function(){var a;return a=this.getElement(),a.className=a.className.replace("pace-active",""),a.className+=" pace-inactive",document.body.className=document.body.className.replace("pace-running",""),document.body.className+=" pace-done"},a.prototype.update=function(a){return this.progress=a,this.render()},a.prototype.destroy=function(){try{this.getElement().parentNode.removeChild(this.getElement())}catch(a){i=a}return this.el=void 0},a.prototype.render=function(){var a,b,c,d,e,f,g;if(null==document.querySelector(D.target))return!1;for(a=this.getElement(),d="translate3d("+this.progress+"%, 0, 0)",g=["webkitTransform","msTransform","transform"],e=0,f=g.length;f>e;e++)b=g[e],a.children[0].style[b]=d;return(!this.lastRenderedProgress||this.lastRenderedProgress|0!==this.progress|0)&&(a.children[0].setAttribute("data-progress-text",""+(0|this.progress)+"%"),this.progress>=100?c="99":(c=this.progress<10?"0":"",c+=0|this.progress),a.children[0].setAttribute("data-progress",""+c)),this.lastRenderedProgress=this.progress},a.prototype.done=function(){return this.progress>=100},a}(),h=function(){function a(){this.bindings={}}return a.prototype.trigger=function(a,b){var c,d,e,f,g;if(null!=this.bindings[a]){for(f=this.bindings[a],g=[],d=0,e=f.length;e>d;d++)c=f[d],g.push(c.call(this,b));return g}},a.prototype.on=function(a,b){var c;return null==(c=this.bindings)[a]&&(c[a]=[]),this.bindings[a].push(b)},a}(),P=window.XMLHttpRequest,O=window.XDomainRequest,N=window.WebSocket,w=function(a,b){var c,d,e;e=[];for(d in b.prototype)try{e.push(null==a[d]&&"function"!=typeof b[d]?"function"==typeof Object.defineProperty?Object.defineProperty(a,d,{get:function(){return b.prototype[d]},configurable:!0,enumerable:!0}):a[d]=b.prototype[d]:void 0)}catch(f){c=f}return e},A=[],j.ignore=function(){var a,b,c;return b=arguments[0],a=2<=arguments.length?X.call(arguments,1):[],A.unshift("ignore"),c=b.apply(null,a),A.shift(),c},j.track=function(){var a,b,c;return b=arguments[0],a=2<=arguments.length?X.call(arguments,1):[],A.unshift("track"),c=b.apply(null,a),A.shift(),c},J=function(a){var b;if(null==a&&(a="GET"),"track"===A[0])return"force";if(!A.length&&D.ajax){if("socket"===a&&D.ajax.trackWebSockets)return!0;if(b=a.toUpperCase(),$.call(D.ajax.trackMethods,b)>=0)return!0}return!1},k=function(a){function b(){var a,c=this;b.__super__.constructor.apply(this,arguments),a=function(a){var b;return b=a.open,a.open=function(d,e){return J(d)&&c.trigger("request",{type:d,url:e,request:a}),b.apply(a,arguments)}},window.XMLHttpRequest=function(b){var c;return c=new P(b),a(c),c};try{w(window.XMLHttpRequest,P)}catch(d){}if(null!=O){window.XDomainRequest=function(){var b;return b=new O,a(b),b};try{w(window.XDomainRequest,O)}catch(d){}}if(null!=N&&D.ajax.trackWebSockets){window.WebSocket=function(a,b){var d;return d=null!=b?new N(a,b):new N(a),J("socket")&&c.trigger("request",{type:"socket",url:a,protocols:b,request:d}),d};try{w(window.WebSocket,N)}catch(d){}}}return Z(b,a),b}(h),R=null,y=function(){return null==R&&(R=new k),R},I=function(a){var b,c,d,e;for(e=D.ajax.ignoreURLs,c=0,d=e.length;d>c;c++)if(b=e[c],"string"==typeof b){if(-1!==a.indexOf(b))return!0}else if(b.test(a))return!0;return!1},y().on("request",function(b){var c,d,e,f,g;return f=b.type,e=b.request,g=b.url,I(g)?void 0:j.running||D.restartOnRequestAfter===!1&&"force"!==J(f)?void 0:(d=arguments,c=D.restartOnRequestAfter||0,"boolean"==typeof c&&(c=0),setTimeout(function(){var b,c,g,h,i,k;if(b="socket"===f?e.readyState<2:0<(h=e.readyState)&&4>h){for(j.restart(),i=j.sources,k=[],c=0,g=i.length;g>c;c++){if(K=i[c],K instanceof a){K.watch.apply(K,d);break}k.push(void 0)}return k}},c))}),a=function(){function a(){var a=this;this.elements=[],y().on("request",function(){return a.watch.apply(a,arguments)})}return a.prototype.watch=function(a){var b,c,d,e;return d=a.type,b=a.request,e=a.url,I(e)?void 0:(c="socket"===d?new n(b):new o(b),this.elements.push(c))},a}(),o=function(){function a(a){var b,c,d,e,f,g,h=this;if(this.progress=0,null!=window.ProgressEvent)for(c=null,a.addEventListener("progress",function(a){return h.progress=a.lengthComputable?100*a.loaded/a.total:h.progress+(100-h.progress)/2},!1),g=["load","abort","timeout","error"],d=0,e=g.length;e>d;d++)b=g[d],a.addEventListener(b,function(){return h.progress=100},!1);else f=a.onreadystatechange,a.onreadystatechange=function(){var b;return 0===(b=a.readyState)||4===b?h.progress=100:3===a.readyState&&(h.progress=50),"function"==typeof f?f.apply(null,arguments):void 0}}return a}(),n=function(){function a(a){var b,c,d,e,f=this;for(this.progress=0,e=["error","open"],c=0,d=e.length;d>c;c++)b=e[c],a.addEventListener(b,function(){return f.progress=100},!1)}return a}(),d=function(){function a(a){var b,c,d,f;for(null==a&&(a={}),this.elements=[],null==a.selectors&&(a.selectors=[]),f=a.selectors,c=0,d=f.length;d>c;c++)b=f[c],this.elements.push(new e(b))}return a}(),e=function(){function a(a){this.selector=a,this.progress=0,this.check()}return a.prototype.check=function(){var a=this;return document.querySelector(this.selector)?this.done():setTimeout(function(){return a.check()},D.elements.checkInterval)},a.prototype.done=function(){return this.progress=100},a}(),c=function(){function a(){var a,b,c=this;this.progress=null!=(b=this.states[document.readyState])?b:100,a=document.onreadystatechange,document.onreadystatechange=function(){return null!=c.states[document.readyState]&&(c.progress=c.states[document.readyState]),"function"==typeof a?a.apply(null,arguments):void 0}}return a.prototype.states={loading:0,interactive:50,complete:100},a}(),f=function(){function a(){var a,b,c,d,e,f=this;this.progress=0,a=0,e=[],d=0,c=C(),b=setInterval(function(){var g;return g=C()-c-50,c=C(),e.push(g),e.length>D.eventLag.sampleCount&&e.shift(),a=q(e),++d>=D.eventLag.minSamples&&a=100&&(this.done=!0),b===this.last?this.sinceLastUpdate+=a:(this.sinceLastUpdate&&(this.rate=(b-this.last)/this.sinceLastUpdate),this.catchup=(b-this.progress)/D.catchupTime,this.sinceLastUpdate=0,this.last=b),b>this.progress&&(this.progress+=this.catchup*a),c=1-Math.pow(this.progress/100,D.easeFactor),this.progress+=c*this.rate*a,this.progress=Math.min(this.lastProgress+D.maxProgressPerFrame,this.progress),this.progress=Math.max(0,this.progress),this.progress=Math.min(100,this.progress),this.lastProgress=this.progress,this.progress},a}(),L=null,H=null,r=null,M=null,p=null,s=null,j.running=!1,z=function(){return D.restartOnPushState?j.restart():void 0},null!=window.history.pushState&&(T=window.history.pushState,window.history.pushState=function(){return z(),T.apply(window.history,arguments)}),null!=window.history.replaceState&&(W=window.history.replaceState,window.history.replaceState=function(){return z(),W.apply(window.history,arguments)}),l={ajax:a,elements:d,document:c,eventLag:f},(B=function(){var a,c,d,e,f,g,h,i;for(j.sources=L=[],g=["ajax","elements","document","eventLag"],c=0,e=g.length;e>c;c++)a=g[c],D[a]!==!1&&L.push(new l[a](D[a]));for(i=null!=(h=D.extraSources)?h:[],d=0,f=i.length;f>d;d++)K=i[d],L.push(new K(D));return j.bar=r=new b,H=[],M=new m})(),j.stop=function(){return j.trigger("stop"),j.running=!1,r.destroy(),s=!0,null!=p&&("function"==typeof t&&t(p),p=null),B()},j.restart=function(){return j.trigger("restart"),j.stop(),j.start()},j.go=function(){var a;return j.running=!0,r.render(),a=C(),s=!1,p=G(function(b,c){var d,e,f,g,h,i,k,l,n,o,p,q,t,u,v,w;for(l=100-r.progress,e=p=0,f=!0,i=q=0,u=L.length;u>q;i=++q)for(K=L[i],o=null!=H[i]?H[i]:H[i]=[],h=null!=(w=K.elements)?w:[K],k=t=0,v=h.length;v>t;k=++t)g=h[k],n=null!=o[k]?o[k]:o[k]=new m(g),f&=n.done,n.done||(e++,p+=n.tick(b));return d=p/e,r.update(M.tick(b,d)),r.done()||f||s?(r.update(100),j.trigger("done"),setTimeout(function(){return r.finish(),j.running=!1,j.trigger("hide")},Math.max(D.ghostTime,Math.max(D.minTime-(C()-a),0)))):c()})},j.start=function(a){v(D,a),j.running=!0;try{r.render()}catch(b){i=b}return document.querySelector(".pace")?(j.trigger("start"),j.go()):setTimeout(j.start,50)},"function"==typeof define&&define.amd?define(["pace"],function(){return j}):"object"==typeof exports?module.exports=j:D.startOnPageLoad&&j.start()}).call(this); \ No newline at end of file diff --git a/links/index.html b/links/index.html new file mode 100644 index 0000000..ac22ce9 --- /dev/null +++ b/links/index.html @@ -0,0 +1,16 @@ +友情链接 | 随言碎语

随言碎语

咕叽咕叽

友情链接

排名不分先后,每次刷新会随机排列。


留言互换友链 o ((>ω<)) o

友链格式

0%
\ No newline at end of file diff --git a/links/linklist.json b/links/linklist.json new file mode 100644 index 0000000..83fc1f0 --- /dev/null +++ b/links/linklist.json @@ -0,0 +1 @@ +[{"name":"如鱼饮水,冷暖自知","site":"https://wangjiezhe.com","avatar":"https://gravatar.loli.net/avatar/e09cf54e933e5a690716e68961ff3b1c?s=512"},{"name":"如鱼饮水,冷暖自知","site":"https://wangjiezhe.com","avatar":"https://gravatar.loli.net/avatar/e09cf54e933e5a690716e68961ff3b1c?s=512"},{"name":"如鱼饮水,冷暖自知","site":"https://wangjiezhe.com","avatar":"https://gravatar.loli.net/avatar/e09cf54e933e5a690716e68961ff3b1c?s=512"}] \ No newline at end of file diff --git a/placeholder b/placeholder deleted file mode 100644 index e69de29..0000000 diff --git a/search.xml b/search.xml new file mode 100644 index 0000000..5add895 --- /dev/null +++ b/search.xml @@ -0,0 +1,476 @@ + + + + esxi+openwrt+dsm+homeassistant 软路由 all in one + /2023/03/23/esxi+openwrt+dsm+homeassistant-%E8%BD%AF%E8%B7%AF%E7%94%B1all-in-one/ + 软路由 all in one,在J425小主机上安装esxi+openwrt+dsm+homeassistant,集软路由、网盘、智能家居控制于一体。

+ + +

硬件介绍

软件安装

    +
  1. esxi8.0安装
  2. +
  3. esxi+openwrt作为旁路由
  4. +
  5. esxi安装群晖dsm7.1
  6. +
  7. esxi安装homeassistant
  8. +
+]]>
+ + esxi + homeassistant + openwrt + dsm + 软路由 + 群晖 + +
+ + esxi常规配置 + /2023/03/26/esxi%E5%B8%B8%E8%A7%84%E9%85%8D%E7%BD%AE/ + esxi修改网卡顺序、网卡直通、修改安全策略、开机自动启动虚拟机。

+ + +

修改网卡顺序

系统中网卡的显示顺序可能和实际的对应不上,可以修改相关的配置文件,让其能和实际的端口对上。

+

先确定当前的顺序,以及希望修改后的顺序:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
实际网口名称ESXi中默认网口名称希望的网口名称
eth0vmnic1vmnic0
eth1vmnic2vmnic1
eth2vmnic0vmnic2
eth3vmnic3vmnic3
+
    +
  1. 开启维护模式,和ssh连接。

    +
  2. +
  3. 查看系统中当前pci和逻辑pci对应的网卡名称

    +
    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias list
    Bus type Bus address Alias
    ------------------------------------
    pci m00008501 vmnic0
    pci m00008901 vmhba0
    pci p0000:04:00.0 vmnic3
    pci s00000003.00 vmnic1
    pci p0000:02:00.0 vmnic2
    logical pci#s00000003.00#0 vmnic1
    logical pci#m00008501#0 vmnic0
    logical pci#m00008901#0 vmhba0
    logical pci#p0000:02:00.0#0 vmnic2
    logical pci#p0000:04:00.0#0 vmnic3

  4. +
  5. 修改网卡名称,这里pci和逻辑pci对应的名称要同时修改,并且要一致。

    +
    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type pci --alias vmnic0 --bus-address s00000003.00
    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type logical --alias vmnic0 --bus-address "pci#s00000003.00#0"

    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type pci --alias vmnic1 --bus-address p0000:02:00.0
    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type logical --alias vmnic1 --bus-address "pci#p0000:02:00.0#0"

    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type pci --alias vmnic2 --bus-address m00008501
    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type logical --alias vmnic2 --bus-address "pci#m00008501#0"

  6. +
  7. 重启机器

    +
  8. +
+

网卡直通

安装软路由时,需要将网卡直通,从而发挥网卡的最大性能。

+
    +
  1. 进入esxi的管理页面

    +

    image-20230422142105492

    +
  2. +
+

注:至少要保留一个网口,用来作为esxi的管理网口,否则将无法登录esxi

+
+ +
    +
  1. 选择需要直通的网口,进行切换即可
  2. +
+

修改安全策略

可能会出现虚拟机和esxi之间相互ping不通的情况,这是由于esxi的安全策略导致的

+
    +
  1. 依次点击网络->虚拟交换机->编辑vSwith0

    +

    image-20230422143110862

    +
  2. +
  3. 将安全选项中,混杂模式和伪传输改为接受

    +
  4. +
+

开机自动启动虚拟机

设置开启后自动启动虚拟机,以及启动顺序

+

1.依次点击主机->管理->系统->自动启动->编辑设置,将总开关打开

+

image-20230422143559690

+

2.选择虚拟机,设置是否开机自启、调整启动的顺序和延迟启动时间。

+
    +
  • 注:这里最好错开启动,不要同时启动,由依赖的虚拟机先启动。
  • +
+]]>
+ + esxi + 软路由 + +
+ + esxi安装homeassistant + /2023/03/24/esxi%E5%AE%89%E8%A3%85homeassistant/ + 在esxi上安装homeassistant

+ + +

准备

]]>
+ + esxi + homeassistant + +
+ + esxi+openwrt作为旁路由 + /2023/03/24/esxi%E5%AE%89%E8%A3%85openwrt/ + 在esxi上安装openwrt,并作为旁路由来使用。

+ + +

准备

    +
  • starwindconverter.exe 用来将img转换为VMDK
  • +
  • openwrt-x86-64-generic-squashfs-combined-efi.img.gz openwrt固件包
  • +
+

1. 构建/获取openWRT

这里推荐使用supes.top 自己选择需要的固件,然后进行构建。5分钟左右就能获取到自定义的固件。

+
    +
  1. 访问supes.top 官网
  2. +
+

image-20230422145319548

+
    +
  1. 自己根据需求去构建,或者是直接下载构建好的通用包

    +

    image-20230422145651697

    +
  2. +
+
    +
  • 注:目前免费的用户,一天之内只能构建一次,有需求的可充值解锁。
  • +
+

2. 转换固件为vmdk格式

    +
  1. 解压openwrt-x86-64-generic-squashfs-combined-efi.img.gz

    +
  2. +
  3. 解压后的文件是openwrt-x86-64-generic-squashfs-combined-efi.img,这个格式是无法在esxi中直接使用的,因此需要转一下

    +
  4. +
  5. 安装starwindconverter.exe ,没啥可交代的,一路next即可。

    +
  6. +
  7. 打开安装好的starwindconverter软件,选择local file->next

    +

    image-20230422150336027

    +
  8. +
  9. 选择解压后的openwrt-x86-64-generic-squashfs-combined-efi.img

    +

    image-20230422150500119

    +
  10. +
  11. 还是选择local file

    +
  12. +
+

image-20230422150951371

+
    +
  1. 选择VMDK

    +

    image-20230422151034204

    +
  2. +
  3. 选择ESXI Server image

    +

    image-20230422151136889

    +
  4. +
+

9.选择** ESXI pre-allocates image**

+

image-20230422151215810

+

10.选择输出的路径和名称,点击conver

+

image-20230422151331578

+

11.转换完成后,会出来两个大小不一样的文件

+

image-20230422151557911

+

3. 创建虚拟机

    +
  1. 进入esxi的管理页面,依次点击虚拟机->创建虚拟机

    +

    image-20230422151821830

    +
  2. +
  3. 选择名称和客户机操作系统

    +

    image-20230422152710801

    +
  4. +
+

客户机操作系统系列: 选择Linux,客户机操作系统版本:其他Linux(64位)

+
    +
  1. 选择存储,如果由多块硬盘,可选择安装的位置

    +

    image-20230422152842237

    +
  2. +
  3. 内存设置为1G,删除掉硬盘以及其他不需要的设备

    +

    image-20230422153126229

    +
  4. +
  5. 添加硬盘->现有硬盘

    +

    image-20230422153403639

    +
  6. +
  7. 将转换后的两个vmdk文件全部都上传上去(只会显示1个),然后选择上传的文件

    +

    image-20230422153716292

    +
      +
    • 注:如果需要网卡直通,可点击添加其他设备->PCI设备。

      +
    • +
    • 如果由多个网卡,但是这里无法点击,说明这个设别没有进行直通。如何直通可参考之前的文章 esxi常规配置

      +

      image-20230422154249143

      +
    • +
    +
  8. +
  9. 点击下一步,确认一下配置,无误后点击完成即可。

    +
  10. +
  11. 选中虚拟机,点击打开电源,等待开机

    +

    image-20230422154411639

    +
  12. +
  13. 点击进入操作台,可看到openwrt已经正常启动,在浏览器中输入IP地址即可访问openwrt的管理页面。

    +

    image-20230422154700759

    +
  14. +
+

4. 配置opwrt作为旁路由

由于是作为旁路由来使用的,所有wan口是不需要的,只需要LAN即可。

+
    +
  1. 进入openwrt的管理页面,依次点击网络->接口,将wan和wan6全部删除掉。
  2. +
+

image-20230422161227530

+

注:删除后,不要点击 保存并应用!!! 不要点击 保存并应用!!! 不要点击 保存并应用!!!

+
+ +
    +
  1. 点击设备,选择br-lan,点击配置…
  2. +
+

image-20230422161705488

+
    +
  1. 网桥端口中,将所有的网卡都勾选上

    +

    image-20230422161814059

    +
  2. +
  3. 回到接口页面,编辑lan

    +

    image-20230422161955936

    +
  4. +
  5. 确认里面的设备是br-lan

    +

    image-20230422162141208

    +
  6. +
  7. 保存后,点击最外层的保存并应用

    +

    image-20230422162251244

    +
  8. +
  9. 网络连接正常后,配置自己需要的服务,然后需要这些服务的设备,将openwrt作为网关就可以了。

    +
  10. +
+

5. 问题

    +
  1. 为什么不作为主路由使用,而是选择旁路由?

    +
    1。主要还是看各自的需要来决定的,各有利弊。
    2.对我来说,只是想用一下它的插件功能,例如广告拦截,proxy等。
    3.即便是软路由整体挂了,也不会影响家里的其他设别的正常使用。
  2. +
  3. 如何修改openwrt的地址?

    +
    1.修改lan口的ip地址

    [root@OpenWrt:03:52 PM ~] # cat /etc/config/network

    ....

    config interface 'lan'
    option device 'br-lan'
    option proto 'static'
    option netmask '255.255.255.0'
    option ip6assign '60'
    option ipaddr '10.1.100.254'
    option gateway '10.1.100.1'
    option dns '223.5.5.5'
    option delegate '0'

    ....

    2. 改完后保存退出,并reboot重启
  4. +
  5. 网卡直通后,无法访问openwrt的管理页面?

    +
  6. +
+
多张网卡直通后,可能会造成网卡识别混乱。
如果当前无法访问,把网线拔了,可换个网口再试试,肯定会有一个是能够访问的。
+ +]]>
+ + esxi + openwrt + 软路由 + 旁路由 + +
+ + esxi安装群晖dsm7.1 + /2023/03/24/esxi%E5%AE%89%E8%A3%85%E7%BE%A4%E6%99%96dsm7.1/ + 在esxi上安装DSM

+ + +

准备

]]>
+ + esxi + 群晖 + DSM + +
+ + esxi8.0安装 + /2023/03/23/esxi8.0%E5%AE%89%E8%A3%85/ + esxi 8.0的安装。

+ + + + +

准备工具

硬件:

+
    +
  • 8G以上U盘一个
  • +
  • 待安装的主机一套
  • +
+

软件:

+
    +
  • rufus-3.15p.exe 用来刻录镜像

    +
  • +
  • VMware-VMvisor-Installer-8.0.0-21203435.x86_64-Dell_Customized-A03.iso

    +

    注:这里使用的是DELL定制版本,其他版本可从官网下载。操作步骤都是一样的

    +
  • +
+

刻录镜像到启动U盘

    +
  1. 打开rufus-3.15p.exe
    image-20230422123404610
  2. +
  3. 依次选择U盘,选择镜像文件,点击开始。
  4. +
  5. 写入完成后拔下U盘。
  6. +
+

安装ESXI8.0

    +
  1. 将写好的U盘插到机器上,开机进入bios页面,选择从U盘启动。

    +
  2. +
  3. 在加载页面按 SHIFT+O (5秒倒计时结束前按)

    +

    image-20230422124229021

    +
  4. +
  5. 输入autoParititionOSDataSize=8192设置缓存大小

    +

    image-20230422130103695

    +
      +
    • 注:如果不设置的话,默认是划分120G
    • +
    +
  6. +
  7. 等待页面加载

    +

    image-20230422130452177

    +
  8. +
  9. 按回车确定,然后F11接受协议。

    +

    image-20230422130636232

    +
  10. +
  11. 选择安装的硬盘,建议安装到SSD盘

    +

    image-20230422131134063

    +
  12. +
  13. 如果之前安装过,会让选择安装方式。如果之前的不想要的,就直接选择第三个覆盖安装。(按空格选中,回车确定)

    +

    image-20230422131415703

    +
  14. +
  15. 键盘选择US Default

    +

    image-20230422131519284

    +
  16. +
  17. 设置root密码,并确认安装

    +

    image-20230422131707324

    +
  18. +
  19. 安装完成后,会提示拔出U盘并重启

    +

    image-20230422131850437

    +
  20. +
  21. 重启后显示下图的页面即表示成功了

    +

    image-20230422131945389

    +
  22. +
+

给ESXi 设置为静态 IP

    +
  1. 按 F2 进入,提示需要输入账户密码,用户名为 root,密码为刚刚安装时设置的密码,然后回车。

    +

    image-20230422132154911

    +
  2. +
  3. 选择**configure management network **

    +

    image-20230422132512778

    +
  4. +
  5. 然后选择 IPV4 configuration 回车

    +

    image-20230422132558114

    +
  6. +
  7. 接着移动光标到第三项,随后按空格键确定选择

    +
  8. +
  9. 接着填入你需要设置的 ESXi 静态 IP 地址。

    +

    image-20230422132853991

    +
  10. +
+

第一行填入 esxi 的静态 IP,第二行填入子网掩码 255.255.255.0,第三行填写路由器的网关地址,设置好后回车即可。

+
    +
  1. 打开浏览器,输入管理地址即可访问esxi系统

    +

    image-20230422133642869

    +
  2. +
+

设置管理网口(多网卡)

如果有多张网卡,可以指定哪个网口可以访问esxi的管理页面,没有指定的将无法访问。

+
    +
  1. F2进入后,依次选择**configure management network **->**Network Adapters **

    +

    image-20230422133918448

    +
  2. +
  3. 选择网卡,这里可以选择多个,如果只选择了某一个,以后就只有插在这个网口上的机器能访问管理页面。

    +

    image-20230422134113958

    +
  4. +
+]]>
+ + esxi + 软路由 + +
+ + VMware安装centos7 + /2020/01/03/VMware%E5%AE%89%E8%A3%85centos7/ + 在VMware Workstation上安装centos。

+ + + + +

1. 准备:

    +
  • VMware Workstation

    +
  • +
  • 镜像文件:CentOS-7-x86_64-bin-DVD1.iso

    +
  • +
+

2. 新建虚拟机

    +
  1. 新建虚拟机,选择自定义

    +
  2. +
  3. 硬盘兼容性–默认

    +
  4. +
+

image-20230422105921574

+
    +
  1. 稍后安装操作系统(需要在虚拟机安装完成之后,删除不需要的硬件,所以稍后安装操作系统)

    +
  2. +
  3. 择客户端操作系统:客户机操作系统–Linux版本centos 64位

    +
  4. +
  5. 处理器配置(CPU)和内存,按需要配置

    +
  6. +
  7. 网络类型–桥接网络(可以使虚拟机与主机使用同一网络)

    +
  8. +
+
    +
  • 注:若是NAT和仅主机模式,需要注意网卡的地址,创建的虚拟机和所使用的网卡在同一个网段。
  • +
+
    +
  1. 选择I/O控制器类型、磁盘类型和创建新的虚拟磁盘(一般默认就行)

    +
  2. +
  3. 指定磁盘容量(不低于20G)

    +
  4. +
  5. 指定磁盘文件(.vmdk)文件

    +
  6. +
  7. 完成后,删除不必要的设备

    +

    image-20230422111309578

    +
  8. +
  9. 选中CD/DVD,使用ISO镜像文件-选择镜像文件

    +

    image-20230422111531776

    +
  10. +
+

12.确定后,打开这个虚拟机的电源

+

image-20230422114456361

+

3. 进入centos7安装页面

    +
  1. 选择install centos7
  2. +
+

image-20230422111901398

+
    +
  1. 设置语言–使用中文-简体中文–点击继续
  2. +
+

image-20230422114739708

+
    +
  • 注:如果这里选择了中文简体,那么键盘布局一定要选择英文
  • +
+
    +
  1. 进一步设置要安装的信息

    +

    image-20230422115039348

    +

    软件选择:这里我们选择最小化安装,即只有最基础的系统,没有桌面

    +

    image-20230422115156841

    +
  2. +
  3. 系统安装位置,点进去进行自定义分区(如果没有特别的要求,默认分区也行)

    +

    image-20230422115350829
    4.1 若需要自主分区,点击我要配置分区
    image-20230422115507917
    4.2 选择标准分组,点击**+**
    image-20230422115613958
    4.3 依次添加新挂载点:/boot;swap;/;
    image-20230422115944392
    注:

    +
      +
    • /boot 分区:是引导分区;作用:系统启动,在boot分区存放着grub,内核文件等,一般200M就够了。
    • +
    • swap交换分区:内存扩展分区;一般也就2G 。
    • +
    • / 根目录:10G左右,数据一般也不会直接放在根目录下。
    • +
    +

    4.4 点击完成,接受更改即可。

    +

    image-20230422120644423

    +
  4. +
  5. 关掉KDUMP

    +

    image-20230422120802249

    +
  6. +
  7. 配置网络和主机名

    +

    image-20230422120925893

    +

    网络要根据自己的环境和需求去配置,配置后点击保存即可。

    +
  8. +
  9. 安全策略保持默认的即可,直接点击开始安装

    +

    image-20230422121138262

    +
  10. +
  11. 设置用户名和密码(主要是设置root密码,创建用户可以不做)

    +

    image-20230422121219185

    +

    点击root密码,输入密码点击完成。

    +

    image-20230422121357933

    +
  12. +
  13. 点击重启,等待系统安装完成即可使用了

    +

    image-20230422121530317

    +
  14. +
+]]>
+ + VMware + centos + +
+ + Hello World + /2019/12/30/hello-world/ + 欢迎来到我的博客,这是我的第一篇博客,由hexo+next构建。

+]]>
+
+
diff --git a/tags/VMware/index.html b/tags/VMware/index.html new file mode 100644 index 0000000..7d69b68 --- /dev/null +++ b/tags/VMware/index.html @@ -0,0 +1,16 @@ +标签: VMware | 随言碎语

随言碎语

咕叽咕叽

VMware 标签

2020
0%
\ No newline at end of file diff --git a/tags/centos/index.html b/tags/centos/index.html new file mode 100644 index 0000000..706d40c --- /dev/null +++ b/tags/centos/index.html @@ -0,0 +1,16 @@ +标签: centos | 随言碎语

随言碎语

咕叽咕叽

centos 标签

2020
0%
\ No newline at end of file diff --git a/tags/dsm/index.html b/tags/dsm/index.html new file mode 100644 index 0000000..9d31bf5 --- /dev/null +++ b/tags/dsm/index.html @@ -0,0 +1,16 @@ +标签: DSM | 随言碎语

随言碎语

咕叽咕叽

DSM 标签

2023
0%
\ No newline at end of file diff --git a/tags/esxi/index.html b/tags/esxi/index.html new file mode 100644 index 0000000..231485e --- /dev/null +++ b/tags/esxi/index.html @@ -0,0 +1,16 @@ +标签: esxi | 随言碎语

随言碎语

咕叽咕叽

0%
\ No newline at end of file diff --git a/tags/homeassistant/index.html b/tags/homeassistant/index.html new file mode 100644 index 0000000..247245c --- /dev/null +++ b/tags/homeassistant/index.html @@ -0,0 +1,16 @@ +标签: homeassistant | 随言碎语

随言碎语

咕叽咕叽

0%
\ No newline at end of file diff --git a/tags/index.html b/tags/index.html new file mode 100644 index 0000000..717c2c6 --- /dev/null +++ b/tags/index.html @@ -0,0 +1,16 @@ +tags | 随言碎语

随言碎语

咕叽咕叽

0%
\ No newline at end of file diff --git a/tags/openwrt/index.html b/tags/openwrt/index.html new file mode 100644 index 0000000..74b616a --- /dev/null +++ b/tags/openwrt/index.html @@ -0,0 +1,16 @@ +标签: openwrt | 随言碎语

随言碎语

咕叽咕叽

0%
\ No newline at end of file diff --git a/tags/旁路由/index.html b/tags/旁路由/index.html new file mode 100644 index 0000000..0abd1f2 --- /dev/null +++ b/tags/旁路由/index.html @@ -0,0 +1,16 @@ +标签: 旁路由 | 随言碎语

随言碎语

咕叽咕叽

旁路由 标签

2023
0%
\ No newline at end of file diff --git a/tags/群晖/index.html b/tags/群晖/index.html new file mode 100644 index 0000000..d7ca537 --- /dev/null +++ b/tags/群晖/index.html @@ -0,0 +1,16 @@ +标签: 群晖 | 随言碎语

随言碎语

咕叽咕叽

0%
\ No newline at end of file diff --git a/tags/软路由/index.html b/tags/软路由/index.html new file mode 100644 index 0000000..3ddf5ef --- /dev/null +++ b/tags/软路由/index.html @@ -0,0 +1,16 @@ +标签: 软路由 | 随言碎语

随言碎语

咕叽咕叽

0%
\ No newline at end of file

随言碎语

咕叽咕叽

esxi修改网卡顺序、网卡直通、修改安全策略、开机自动启动虚拟机。

阅读全文 »

欢迎来到我的博客,这是我的第一篇博客,由hexo+next构建。