├── .github └── workflows │ └── hexo.yml ├── .gitignore ├── Layerfile ├── README.md ├── _config.yml ├── package-lock.json ├── package.json ├── scaffolds ├── draft.md ├── page.md └── post.md ├── source ├── 404.gif ├── 404.html ├── LICENSE ├── _discarded │ └── 浅谈BT-1.md ├── _drafts │ ├── 2020QM.md │ ├── HelloWorld.md │ ├── HelloWorld1.md │ └── の测试 │ │ └── T.md ├── _posts │ ├── AVorBV.md │ ├── Adobe2019年Windows全家桶.md │ ├── Bing美图故事PHP正式上线.md │ ├── GetUserInfo-ByCFAPI.md │ ├── Gitalk详细踩坑记录.md │ ├── GithubのUnlimited-Private-Repo有感.md │ ├── Github无法注册:Unable-to-verify-your-captcha-response.md │ ├── GooseDesktop桌面鸭-网课好宠物.md │ ├── Hexo-Admin-体验如Wordpress般GUI编辑.md │ ├── IPFS-CloudFlare-ServerLessWebPage.md │ ├── JS特效:一个打字绚烂烟花的特效.md │ ├── JS特效:鼠标单击出现爱心.md │ ├── LazyLoad-GoogleAdsense.md │ ├── LazyLoad.md │ ├── Live2D:为你的hexo博客添加萌萌哒看板娘.md │ ├── Make-BlogSpot-Avaliable-in-MainLand.md │ ├── MarkDown语法详解(中级版).md │ ├── MarkDown语法详解(初级版).md │ ├── MarkDown语法详解(高级版).md │ ├── Momentum:一款美化你Chrome新标签页的插件.md │ ├── NoServer-Deploy-Artalk.md │ ├── OneDrive-Index-On-CloudFlareWorkers-By-GithubAction.md │ ├── PHPnow.md │ ├── Pandownload-愿你归来仍是英雄.md │ ├── Up-Blog-By-Travis-ci.md │ ├── User-Agent野史.md │ ├── Valine:一款极简评论系统的安装到升级.md │ ├── What-I-Do-2020-04-05.md │ ├── a-simple-think-of-censorship-resistant-chatroom.md │ ├── about_attack_maplesugar.md │ ├── c++-kmp.md │ ├── dns-prefetch-with-more.md │ ├── free-10GB-oss-poweredby-backblaze.md │ ├── goodbye-yuan.md │ ├── hexoplusplus.md │ ├── hey-picbed.md │ ├── hi2022.md │ ├── how-to-use-euserv.md │ ├── instant-defection.md │ ├── panlist.md │ ├── speed-up-by-sw.md │ ├── sw-help-blog.md │ ├── update-live2d-to-v3-or-v4.md │ ├── use-ipv6-in-unsv6-en.md │ ├── why-app-but-not-browser.md │ ├── 【致歉】全能音乐搜索Bug修复.md │ ├── 一次“修”冰箱的经历.md │ ├── 一次愉快的更换域名经历.md │ ├── 一次成功的白嫖经历-萌娘百科.md │ ├── 一次糟糕的换主题过程.md │ ├── 免·爬·城·国内管理分享GoogleDrive.md │ ├── 听说你喜欢盗头像_私人独一无二彩色头像养成详解.md │ ├── 回归啦!这是见面礼.md │ ├── 国内加快NPM下载速度.md │ ├── 天体运动.md │ ├── 如何-CloudFlare-Warp.md │ ├── 如何在中国以免【爬城】的体位下使用Google的reCAPTCHA.md │ ├── 工具箱和私有云恢复!.md │ ├── 巧妙去除百度首页广告.md │ ├── 我们一起解题目吧.md │ ├── 来,破解版的Google访问助手.md │ ├── 每日bing美图获取.md │ ├── 浅谈什么是好软件(1).md │ ├── 白菜价域名的问题.md │ ├── 移除000webhost右下角Powered by 000webhost字样.md │ └── 讲讲2020-3-26Github遭劫持事件.md ├── about │ ├── ads.md │ └── index.md ├── blog-cgi.md ├── categories │ └── index.md ├── com │ └── index.md ├── img │ └── apple-touch-icon.png ├── jump.html ├── links │ └── index.md ├── offline.md ├── package.json ├── pic │ ├── BLOGER.jpg │ ├── c.jpg │ └── posted │ │ └── pasted-0.png ├── search │ └── index.md ├── tags │ └── index.md ├── vercel.json ├── 捐款吧 │ └── index.md └── 随口胡说 │ └── index.md └── themes └── fluid ├── .eslintrc ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── bug_report_zh.md │ ├── feature_request.md │ ├── feature_request_zh.md │ ├── question.md │ └── question_zh.md └── workflows │ ├── limit.yaml │ └── lint.yaml ├── .gitignore ├── _config.yml ├── _static_prefix.yml ├── gulpfile.js ├── languages ├── en.yml ├── ja.yml └── zh-CN.yml ├── layout ├── 404.ejs ├── _partial │ ├── beian.ejs │ ├── comments │ │ ├── changyan.ejs │ │ ├── disqus.ejs │ │ ├── gitalk.ejs │ │ ├── livere.ejs │ │ ├── utterances.ejs │ │ └── valine.ejs │ ├── css.ejs │ ├── footer.ejs │ ├── head.ejs │ ├── nav.ejs │ ├── paginator.ejs │ ├── plugins │ │ ├── analytics.ejs │ │ ├── anchor.ejs │ │ ├── aplayer.ejs │ │ ├── daovoice.ejs │ │ ├── fancybox.ejs │ │ ├── leancloud.ejs │ │ ├── local-search.ejs │ │ ├── math.ejs │ │ ├── mermaid.ejs │ │ ├── mouse-click.ejs │ │ ├── tocjs.ejs │ │ └── typed.ejs │ ├── post-meta.ejs │ ├── scripts.ejs │ ├── search.ejs │ ├── statistics.ejs │ └── toc.ejs ├── about.ejs ├── archive.ejs ├── categories.ejs ├── category.ejs ├── index.ejs ├── layout.ejs ├── links.ejs ├── page.ejs ├── post.ejs ├── tag.ejs └── tags.ejs ├── local-search.xml ├── package.json ├── scripts ├── events │ ├── index.js │ └── lib │ │ ├── footnote.js │ │ ├── hello.js │ │ ├── highlight.js │ │ ├── lazyload.js │ │ ├── merge-configs.js │ │ └── version.js ├── filters │ └── post-filter.js ├── generators │ ├── local-search.js │ └── pages.js ├── helpers │ ├── page.js │ ├── url.js │ ├── utils.js │ └── wordcount.js ├── tags │ ├── button.js │ ├── checkbox.js │ ├── group-image.js │ ├── label.js │ └── note.js └── utils │ ├── join-path.js │ └── object.js └── source ├── css ├── _functions │ └── base.styl ├── _mixins │ └── base.styl ├── _pages │ ├── _about │ │ └── about.styl │ ├── _archive │ │ └── archive.styl │ ├── _base │ │ ├── _widget │ │ │ ├── banner.styl │ │ │ ├── board.styl │ │ │ ├── copy-btn.styl │ │ │ ├── footer.styl │ │ │ ├── footnote.styl │ │ │ ├── header.styl │ │ │ ├── qrcode.styl │ │ │ ├── scroll-btn.styl │ │ │ └── search.styl │ │ ├── base.styl │ │ ├── color-schema.styl │ │ ├── inline.styl │ │ ├── keyframes.styl │ │ └── rewrite.styl │ ├── _category │ │ ├── categories.styl │ │ └── category.styl │ ├── _index │ │ └── index.styl │ ├── _links │ │ └── links.styl │ ├── _post │ │ ├── post.styl │ │ └── tag_plugin.styl │ ├── _tag │ │ ├── tag.styl │ │ └── tags.styl │ └── pages.styl ├── _variables │ └── base.styl └── main.styl ├── img ├── apple-touch-icon.png ├── avatar.png ├── favicon.png └── loading.gif ├── js ├── clipboard-use.js ├── color-schema.js ├── debouncer.js ├── lazyload.js ├── local-search.js ├── main.js └── utils.js ├── lib └── hint │ └── hint.min.css ├── notice.html └── sw.js /.github/workflows/hexo.yml: -------------------------------------------------------------------------------- 1 | name: ChenYFanのHexoBlogBuild 2 | 'on': 3 | - workflow_dispatch 4 | - push 5 | jobs: 6 | buildstatic: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout 10 | uses: actions/checkout@v2 11 | - name: Setup node 12 | uses: actions/setup-node@v1 13 | with: 14 | node-version: 12.x 15 | - name: Cache node modules 16 | uses: actions/cache@v1 17 | with: 18 | path: ~/.npm 19 | key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} 20 | - name: Install & Build 21 | run: > 22 | npm install -g hexo-cli 23 | 24 | npm i 25 | 26 | # Restore last modified time 27 | 28 | git ls-files -z | while read -d '' path; do touch -d "$(git log -1 29 | --format="@%ct" "$path")" "$path"; done 30 | 31 | hexo g 32 | 33 | curl -H 'Content-Type:text/plain' --data-binary 34 | @./public/baidu_urls.txt 35 | "http://data.zz.baidu.com/urls?site=https://blog.cyfan.top&token=${{ 36 | secrets.BD_TOKEN }}" 37 | 38 | rm -rf ./public/CNAME 39 | 40 | echo "blog.cyfan.top" >> ./public/CNAME 41 | 42 | - name: Deploy 43 | uses: peaceiris/actions-gh-pages@v3 44 | with: 45 | github_token: ${{ secrets.TOKEN }} 46 | publish_dir: ./public 47 | - name: Build And Deploy 48 | id: builddeploy 49 | uses: Azure/static-web-apps-deploy@v1 50 | with: 51 | azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_GRAY_GRASS_05AA38100 }} 52 | repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments) 53 | action: "upload" 54 | ###### Repository/Build Configurations - These values can be configured to match your app requirements. ###### 55 | # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig 56 | app_location: "public" # App source code path 57 | skip_app_build: true 58 | skip_api_build: true 59 | api_location: "" # Api source code path - optional 60 | output_location: "" # Built app content directory - optional 61 | ###### End of Repository/Build Configurations ###### 62 | 63 | - uses: JS-DevTools/npm-publish@v1 64 | with: 65 | token: ${{ secrets.NPM }} 66 | 67 | - name: Refresh NPM Cache 68 | run: > 69 | curl -X PUT "https://registry.npmmirror.com/chenyfan-blog/sync?publish=false&nodeps=false" 70 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | Thumbs.db 3 | db.json 4 | *.log 5 | .deploy*/ 6 | tools/ 7 | node_modules/ -------------------------------------------------------------------------------- /Layerfile: -------------------------------------------------------------------------------- 1 | #This is an example webapp.io configuration for NodeJS 2 | FROM vm/ubuntu:18.04 3 | # To note: Layerfiles create VMs, *not* containers! 4 | 5 | # Install node 6 | RUN curl -sL https://deb.nodesource.com/setup_12.x | bash && \ 7 | apt install nodejs && \ 8 | rm -f /etc/apt/sources.list.d/nodesource.list 9 | RUN npm install -g http-server 10 | 11 | COPY . . 12 | 13 | RUN BACKGROUND http-server -p 8000 -d ./dist/ 14 | EXPOSE WEBSITE http://localhost:8000 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 已迁址至 此页面仅作提示 2 | 3 | 原博客已归档 4 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | # Hexo Configuration 2 | ## Docs: https://hexo.io/docs/configuration.html 3 | ## Source: https://github.com/hexojs/hexo/ 4 | 5 | # Site 6 | title: 陈YFの博客( ̄▽ ̄)" 7 | subtitle: (。・∀・)ノ゙嗨 8 | description: "挣扎在互联网角落的小小博客,喜欢介绍一些普通的知识" 9 | keywords: BLOG,薅羊毛,技术,高中生,DNS,CDN,滑稽,图床 10 | author: CYF 11 | language: zh-CN 12 | timezone: Asia/Shanghai 13 | 14 | # URL 15 | ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' 16 | url: https://blog.cyfan.top 17 | root: / 18 | #permalink: :year/:month/:day/:title/ 19 | permalink: p/:abbrlink.html 20 | abbrlink: 21 | alg: crc32 22 | rep: hex 23 | permalink_defaults: 24 | 25 | # Directory 26 | source_dir: source 27 | public_dir: public 28 | tag_dir: tags 29 | archive_dir: archives 30 | category_dir: categories 31 | code_dir: downloads/code 32 | i18n_dir: :lang 33 | skip_render: 34 | 35 | # Writing 36 | new_post_name: :title.md # File name of new posts 37 | default_layout: post 38 | titlecase: false # Transform title into titlecase 39 | external_link: true # Open external links in new tab 40 | filename_case: 0 41 | render_drafts: false 42 | post_asset_folder: false 43 | relative_link: true 44 | future: true 45 | highlight: 46 | enable: true 47 | line_number: true 48 | auto_detect: true 49 | tab_replace: true 50 | 51 | 52 | # Home page setting 53 | # path: Root path for your blogs index page. (default = '') 54 | # per_page: Posts displayed per page. (0 = disable pagination) 55 | # order_by: Posts order. (Order by date descending by default) 56 | index_generator: 57 | path: '' 58 | per_page: 10 59 | order_by: -date 60 | 61 | # Category & Tag 62 | default_category: uncategorized 63 | category_map: 64 | tag_map: 65 | 66 | # Date / Time format 67 | ## Hexo uses Moment.js to parse and display date 68 | ## You can customize the date format as defined in 69 | ## http://momentjs.com/docs/#/displaying/format/ 70 | date_format: YYYY-MM-DD 71 | time_format: HH:mm:ss 72 | 73 | # Pagination 74 | ## Set per_page to 0 to disable pagination 75 | per_page: 10 76 | pagination_dir: page 77 | 78 | # Extensions 79 | ## Plugins: https://hexo.io/plugins/ 80 | ## Themes: https://hexo.io/themes/ 81 | theme: fluid 82 | 83 | # Deployment 84 | ## Docs: https://hexo.io/docs/deployment.html 85 | deploy: 86 | type: git 87 | repo: git@gitssh.cyfan.top:ChenYFan/blog.git 88 | branch: master 89 | 90 | search: 91 | path: search.xml 92 | field: post 93 | format: html 94 | limit: 10000 95 | 96 | Plugins: 97 | - hexo-generator-baidu-sitemap 98 | - hexo-generator-sitemap 99 | - hexo-generator-cname 100 | 101 | 102 | baidusitemap: 103 | path: baidusitemap.xml 104 | sitemap: 105 | path: sitemap.xml 106 | baidu_url_submit: 107 | count: 200 108 | host: blog.cyfan.top 109 | token: QWQ 110 | path: baidu_urls.txt 111 | neat_enable: true 112 | neat_html: 113 | enable: true 114 | exclude: 115 | 116 | neat_css: 117 | enable: true 118 | exclude: 119 | - '**/*.min.css' 120 | 121 | neat_js: 122 | enable: true 123 | mangle: true 124 | output: 125 | compress: 126 | exclude: 127 | - '**/*.min.js' 128 | - '**/jquery.fancybox.pack.js' 129 | - '**/index.js' 130 | feed: 131 | type: atom 132 | path: atom.xml 133 | limit: 50 134 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chenyfan-blog", 3 | "version": "1.2.1", 4 | "private": false, 5 | "hexo": { 6 | "version": "3.9.0" 7 | }, 8 | "scripts":{ 9 | "build":"npx hexo g" 10 | }, 11 | "dependencies": { 12 | "cheerio": "^1.0.0-rc.3", 13 | "chenyfan-blog-helper-dash": "^0.0.7", 14 | "domhandler": "^3.0.0", 15 | "dplayer": "^1.25.0", 16 | "hexo": "^3.9.0", 17 | "hexo-abbrlink": "2.2.1", 18 | "hexo-baidu-url-submit": "0.0.6", 19 | "hexo-deployer-git": "^2.1.0", 20 | "hexo-filter-flowchart": "^1.0.4", 21 | "hexo-generator-archive": "^0.1.5", 22 | "hexo-generator-baidu-sitemap": "^0.1.9", 23 | "hexo-generator-category": "^0.1.3", 24 | "hexo-generator-cname": "^0.3.0", 25 | "hexo-generator-feed": "3.0.0", 26 | "hexo-generator-index": "^0.2.1", 27 | "hexo-generator-search": "^2.4.0", 28 | "hexo-generator-searchdb": "^1.0.8", 29 | "hexo-generator-sitemap": "^2.1.0", 30 | "hexo-generator-tag": "^0.2.0", 31 | "hexo-neat": "1.0.9", 32 | "hexo-related-popular-posts": "^4.0.0", 33 | "hexo-renderer-ejs": "^0.3.1", 34 | "hexo-renderer-marked": "^1.0.1", 35 | "hexo-renderer-stylus": "^0.3.3", 36 | "hexo-server": "^0.3.3", 37 | "hexo-wordcount": "^6.0.1", 38 | "request": "^2.88.2", 39 | "sitemapper": "^3.0.5", 40 | "xml-parser": "^1.2.1" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /scaffolds/draft.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: {{ title }} 3 | tags: 4 | --- 5 | -------------------------------------------------------------------------------- /scaffolds/page.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: {{ title }} 3 | date: {{ date }} 4 | --- 5 | -------------------------------------------------------------------------------- /scaffolds/post.md: -------------------------------------------------------------------------------- 1 | title: 2 | author: 3 | tags: 4 | - 5 | categories: 6 | - 7 | des: 8 | key: 9 | date: 10 | index_img: 11 | banner_img: 12 | lushkey: 13 | --- 14 | -------------------------------------------------------------------------------- /source/404.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChenYFan/blog/3e15fc2372710483f58c22b94988424a67d8f13f/source/404.gif -------------------------------------------------------------------------------- /source/404.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 29 | 404|没有东西呢┭┮﹏┭┮ 30 | 31 | 32 | 33 |

 

34 |

404对不起对不起对不起!/(ㄒoㄒ)/~~

35 |

这里没有你想要的东西。要不,10秒后回主页

36 | 37 | 38 | -------------------------------------------------------------------------------- /source/_discarded/浅谈BT-1.md: -------------------------------------------------------------------------------- 1 | title: 从BT下载开讲-1 2 | tags: 3 | - DHT 4 | - 哈希 5 | - 文件 6 | - 贡献 7 | - BT 8 | - P2P 9 | categories: 10 | - 爱学习 11 | copyright: true 12 | author: CYF 13 | date: 2020-04-07 14:17:45 14 | --- 15 | # Bittorrent:分布式哈希表技术 16 | 17 | ## 先来一个故事 18 | 19 | 很久很久以前,有一位老头,叫做刘XX。 20 | 21 | 他是一位很有资格的老师,为了顽固学生们的学习效果,他发送给所有学生一部视频: 22 | 23 | ![图片](https://img.cyfan.top/pic/BT/视频.bmp "大视频") 24 | 25 | (注:老刘的带宽是8Mbps,即最大带宽1MB/s,每一个学生的带宽也是8Mbps) 26 | 27 | 我们假设有5位学生需要这部视频,则可以画这样一幅图: 28 | 29 | ![图片](https://img.cyfan.top/pic/BT/down1.png "组团下载ing...") 30 | 31 | 这只视频是`88.8MB`大小,按照这样的速度,同学需要花费`1024*88.8MB/(204.8kb/s)=444s`即`7分钟24秒` 32 | 33 | 这还往往只是最理想状况.现在,我们来假设一下现象的出现: 34 | 35 | 1. 由于视频过于好看,引起广泛关注.现在有200个同学要求下载.则单个人下载完需要17760s即296min也就是约5h! 36 | 2. 刘老师觉得单个视频教学质量不够好,决定上传一个8880GB的超大视频.(下载时间大于一天) 37 | 3. 几个同学与刘老师搞好了关系,刘老师给他们较高的下载速度,导致带宽分配不均匀,没有关系的学生下载速度更慢了.(百度网盘既视感) 38 | 39 | ![图片](https://img.cyfan.top/pic/BT/down-VIP.png "A1拥有VIP专线") 40 | 41 | 4. 由于刘老师给的视频过于激烈,在下载了一段时间后,FBI```open the door!```敲上门来带走了刘老师,视频被查封了!!!(下载速度0) 42 | 43 | ![图片](https://img.cyfan.top/pic/BT/FBI.jpeg "FBI!Open the door!") 44 | 45 | 可是,学习是必须的,这可怎么办呢??? 46 | 47 | 这时.... 48 | 49 | 刘老师突然想起来,为什么不让每一个学生互相连接,贡献自己已经下好的部分,以来获得最大的下载速度呢?? 50 | 51 | 请注意,在上述下载中,每一个人都没有充分利用自己的最大带宽,对不对? 52 | 53 | 那,解决办法就来了: 54 | 55 | ## P2P: 56 | 57 | 以256KB为包,我们就可获得356块文件 58 | 59 | ![图片](https://img.cyfan.top/pic/BT/file.png "分包") 60 | 61 | 回到下载界面,我们看到,所有人都与其他人获得连接,那么,连接完成后: 62 | 63 | ![图片](https://img.cyfan.top/pic/BT/down-each.png "连接") 64 | 65 | (为了方便观察,我们将不必要的连接全部去掉) 66 | 67 | 现在,我们重新开始下载: 68 | 69 | 我们假设,A1下载了第一块,A2下载了第二块... 70 | 71 | 两秒后,所有人手上都拥有了一块文件: 72 | 73 | ![图片](https://img.cyfan.top/pic/BT/down-part1.png "下载") 74 | 75 | 接下来,在不影响下载的情况下,A1与A2交换下载好的部分,同时与A3、A4、A5交换 76 | 77 | ![图片](https://img.cyfan.top/pic/BT/down-part2.png "贡献&下载") 78 | 79 | 看到了吗,所有人都得到了更高的速度,所有人的带宽都得到了最充分的利用。 80 | 81 | 接着4秒后,所有的贡献分块都下载好了,而每一个人都从文件发布者身上又得到新的文件碎片。 82 | 83 | ![图片](https://img.cyfan.top/pic/BT/down-part3.png "下载!") 84 | 85 | 所以,这种情况回一直持续下去,直到每一个人都下载完成,每一个人都只需下载149秒即2分29秒!相对于单点时间大大减少! 86 | 87 | ![图片](https://img.cyfan.top/pic/BT/down-finish.png "完整!") 88 | 89 | ## 人数多&文件大 问题 90 | 91 | 现在,我们来假设第一个问题,200人下载怎么办? 92 | 93 | 我们可以明白,人数越多,文件交换越密集,对不对? 94 | 95 | 显然会见的,这个问题显得异常白痴,可以体会的是,在最佳条件下,每个人的带宽都达到了最大,如果每个人都下载了不同的分块,同时每个人都在贡献。 96 | 97 | 那么,每个人的下载速度,根本不会受到很大影响。 98 | 99 | 这对于传统下载(http/https/ftp)不同,传统下载仅仅由一台服务器贡献,人数多对于这台服务器压力极大。 100 | 101 | 但是,在这个环境里,服务器不仅仅是一台,而且,每当加入一个人,每一个人都可以当作服务器,这样,下载速度反而会大大提升。 102 | 103 | 反而文件很大是个硬梗,不过相对于传统下载,这种下载方式还是有一定能力解决这个问题的。 104 | 105 | **但是**,这里还有几个问题没有解决: 106 | 107 | <未完待续> -------------------------------------------------------------------------------- /source/_drafts/2020QM.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 愿逝者安息,愿生者坚强 3 | author: CYF 4 | tags: 5 | - 悼念 6 | - 疫情 7 | categories: 8 | - 随心记 9 | date: 2020-04-04 09:00:00 10 | --- 11 |

博客首页、项目首页将在2020年4月4日10:00至2020年4月5日10:00保持灰化界面,此篇博文永久保持灰化。

12 | 13 | 2020年的清明,与众不同,在我的记忆里,清明,永远是伴随着那蒙蒙小雨和四处弥漫的寒意。今天,2020年地清明,却意外的是晴天,这很令人意外,但也似乎表达了什么。 14 | 15 | 可能,老天的眼泪,早已哭干吧. 16 | 17 | 今年的清明比往年更添一抹特殊的意义: 18 | 19 | 一个不明源头的病毒使本应蒙上喜庆色彩的华夏大地变得毫无生机 20 | 21 | 一群可敬可爱的人儿用自己的血肉之躯筑起了护我们平安的防线 22 | 23 | 是他们日夜坚守勇敢逆行 24 | 25 | 是他们治病救人坚守一线 26 | 27 | 的确,没有什么岁月静好,只是有人在替我们负重前行罢了。 28 | 29 | 花开疫散并非一瞬间 30 | 31 | 日夜奋战才换来一座座城市恢复脉搏 32 | 33 | 为表达全国各族人民对抗击新冠肺炎疫情斗争牺牲烈士和逝世同胞的深切哀悼,国务院昨天(4月3日)发布公告,决定2020年4月4日举行全国性哀悼活动。在此期间,全国和驻外使领馆下半旗志哀,全国停止公共娱乐活动。4月4日10时起,全国人民默哀3分钟,汽车、火车、舰船鸣笛,防空警报鸣响。 34 | 35 | 下半旗....恍惚间除了2019年7月29日就是2015年,这已经很早以前了,下半旗本是领导人死后的待遇;这些疫情战士,用生命给我们换来了一片净土,自己却没能躺回去享受,毫不客气地说,他们就是这个新时代最开始的领导人,带领我们拼过最艰难的时期,下半旗,毫不为过! 36 | 37 | 可能没有他们,中国早已生灵涂炭. 38 | 39 | 感谢你们,替我们守住了这个春天 40 | 41 | 愿逝者安息,愿生者坚强 42 | 43 | 静默,悼念. 44 | 45 | 53 | -------------------------------------------------------------------------------- /source/_drafts/HelloWorld.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: HelloWorld 3 | author: 4 | tags: 5 | categories: 6 | date: 2022/3/11 20:58:49 7 | --- 8 | -------------------------------------------------------------------------------- /source/_drafts/HelloWorld1.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: HelloWorld 3 | author: 4 | tags: 5 | categories: 6 | date: 2022/3/10 01:15:00 7 | --- 8 | -------------------------------------------------------------------------------- /source/_drafts/の测试/T.md: -------------------------------------------------------------------------------- 1 | ![](https://s2.loli.net/2022/03/24/uVkzMar67XHKDEZ.png) 2 | -------------------------------------------------------------------------------- /source/_posts/Adobe2019年Windows全家桶.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Adobe2019年Windows全家桶 3 | tags: 4 | - Adobe 5 | - 全家桶 6 | - 年度 7 | categories: 繡软件 8 | copyright: true 9 | abbrlink: e464ba8a 10 | date: 2019-08-01 15:18:13 11 | --- 12 | # 警告: 13 | 14 | 文件过大,故放在百度网盘上。 15 | 先贴链接: 16 | 17 | 18 | >>百度网盘 提取码: rxx1 19 | 20 | 21 | ![旗舰店上的价格](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/ADOBE.png "旗舰店上的价格") 22 | 23 | # 什么是Adobe CC? 24 | 25 | adobe是Photoshop的原始软件名称,CC即为:Creative Cloud ,也就是创意云。 26 | 所有Adobe创意相关的服务和软件工具都是通过CC服务体系交付给设计师、客户和开发者。CC不仅能够提供Adobe旗下所有的创意软件,还具有一定大小的云存储服务,所有软件工具的升级、下载和安装均能够在CC内的Adobe Application manager内完成。Creative Cloud 集成了用户创作作品所需要的所有元素,能够带给用户最棒、最新的 Adobe 创意工具和服务,Creative Cloud 将用户需要的所有元素集中整合到一个平台,简化了整个创意过程,为用户的使用带来便利。 27 | 28 | # 我有这些有什么用? 29 | 30 | ....... 31 | 此处不做回答 32 | -------------------------------------------------------------------------------- /source/_posts/Bing美图故事PHP正式上线.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Bing美图与故事PHP正式上线 3 | author: CYF 4 | tags: 5 | - PHP 6 | - Bing 7 | - 美图 8 | - 版权 9 | copyright: true 10 | categories: 11 | - 屌代码 12 | index_img: 'https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/img/10.jpg' 13 | banner_img: 'https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/img/10.jpg' 14 | abbrlink: 20ca08a 15 | date: 2020-03-16 10:44:00 16 | --- 17 | 欸...自己挖的坑必须要自己填啊... 18 | 19 | 最近听信了某个·大佬·其实是把我做实验的,在Hexo环境安装了dplayer,结果装到一半,断网了,重新安装就疯狂报错,以至于想要npm卸载都卸不了,结果手贱,手动删除了几个npm依赖,结果导致整个Hexo环境崩溃了,一旦进行 `hexo server -w` 就会冒出一大片红海。害的我不得不备份文章和主题后删除了整个Hexo环境,从头安装Hexo,结果忘记了我还安装了一大堆插件,只好一个一个安装回去,期间的痛苦我真的再也不想回忆一遍,新手可以自己安装一遍Hexo+数十个插件,体验一下。问题是还把鼠标按坏了,现在打字变成异常困难的事情了... 20 | 21 | 欸,最近逃课太频繁,理科全挂科了,甚至在这一次尖子班考试里化学挂科了,不应该这样的啊,我以前化学老棒老棒的了,看起来要拾回学习的心了。所以以后站点维护估计不会那么频繁了。 22 | 23 | # 前言 24 | 25 | 这两天因为Heroku每月时间重置了,又可以接着用了,于是考虑了很长时间决定工具箱和私有云重新上线。 26 | 27 | 28 | 不过工具箱因为绝大部分都是静态,没几个是动态的,所以打算采用动静态前后分离,动态资源以接口形式接到静态页面上,这样可以尽可能减少动态Heroku的运行时间,同样由于前端CloudFlare缓存大大减少调用时间。而私有云静态不可能,所以完全动态,又因为Heroku的时间计算是一个没验证账户一个月600小时,上个月不知道分成两个应用运行...所以干脆私有云和接口并在了一起,加上CloudFlare2hours的缓存,600小时一个月应该够用了... 29 | 30 | ## 关于bing接口 31 | 32 | 以前我在博客上写过怎么用BingPHP,但当时是用缓存的方式写入,但换到heroku上缓存写入就不可能了,于是想想办法解决, `windows.location` 会导致强制https至bing,对于不支持http就很吃亏了,最终采用 `header` 注入方式. 33 | 34 | 由于如果没有获取版权总觉得空荡荡,所以又特地写了一个获取bingcopyright的PHP,同时好好恶补了一下正则获取和解析xml。 35 | 36 | 还有当时没空写UI,这次特地去淘了两个css3和html5漂亮的界面,同时解决了手机端莫名其妙的UI问题.采用js检测UA的方式实现移动端和桌面端分别跳转. 37 | 38 | 这是实际使用: 39 | 40 | 桌面端: 41 | 42 | ![实际使用](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/8.gif "桌面端动图") 43 | 44 | 手机端: 45 | 46 | 47 | 48 | 49 | 解决手机端不兼容桌面端问题: 50 | 51 | 手机横屏bug(已修复): 52 | 53 | 54 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-40.png) 55 | 56 | 57 | 以及我的头像版权镇压,保证没有bug(不要删除ヽ(≧□≦)ノ!) 58 | 59 | 60 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-41.png) 61 | 62 | 已开源,https://github.com/ChenYFan/Bing_Pic_and_Copyright_Catcher 63 | 不过暂时不允许转载删除版权和头像,因为修改这个花费我太多精力了,感谢您的理解! 64 | 65 | 66 | 今日Bing美图: 67 | 68 | ![Bing](https://pan.cyfan.top/api/bing/bing.php "今日Bing美图") 69 | 70 | ![](https://npm.elemecdn.com/chenyfan-oss@1.1.11/213.jpg) -------------------------------------------------------------------------------- /source/_posts/GithubのUnlimited-Private-Repo有感.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: GithubのUnlimited Private Repo有感 3 | author: CYF 4 | tags: 5 | - Github 6 | - Repository 7 | - 撸羊毛 8 | - 私人 9 | - 无限制 10 | categories: 11 | - 瞎扯淡 12 | index_img: 'https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/cover/4.jpg' 13 | banner_img: 'https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/cover/4.jpg' 14 | abbrlink: 36dee3d7 15 | date: 2020-03-22 09:37:00 16 | --- 17 | Unlimited Repo这个项目上一年就开了,只不过当时我身边一堆垃圾新闻客户端根本没有提到这件事,我居然不知道。直到现在手贱开了一个PrivateRepo才发现什么时候变免费了???顿时感觉失去了关爱.... 18 | 19 | ~~欸没错这篇又是水文~~今天讲讲关于这件事以及对于github的心理感想。 20 | 21 | # 收购 22 | 23 | 微软~~爸爸~~2018年末收购Github这件事情我是知道的。 24 | 25 | 哦,知道就知道呗,我当时的心理想法是这样的。 26 | 27 | 确实是这样,我虽然知道网上很多人对这件事褒贬不一,可我确实是心中毫无波澜。 28 | 29 | 因为很多人认为,有那么一个大靠山,就可以接着~~薅~~撸羊毛。 30 | 31 | 也有一些程序员觉得,这样Github就丧失了它开源(OpenSource)的初衷。 32 | 33 | 甚至还有Gitlab公然在底下挑衅。 34 | 35 | (当然这篇博文不是过来喷GitLab的,我只是想描述当时Github有多惨。) 36 | 37 | 我为什么当时毫无波澜呢,说实话原因有下: 38 | 39 | 1.当时还是个萌新,不知道这有什么意义。(雾) 40 | 2.感觉收购后和收购前没什么不同。(大雾) 41 | 3.当时还没有理解Git是什么东西,上传方式都是拖拽上传(大大雾) 42 | 43 | 嗯。 44 | 45 | # 成长 46 | 47 | 渐渐的,用到Github多了,虽然是个学生,但还是有抽出心思写写无聊的程序,对于一些吊炸天的repo一个star,对于一些有版权风险的一个fork...逐渐对于github熟悉起来,也渐渐喜欢上了github,虽然后面使用过coding和gitee,但用户体验就没做那么好(个人感想),最终还是没有抛弃github... 48 | 49 | Github附加功能有些真的没法比,光是那pages我就觉得好上天了,用过codingpages,A记录绑定的ip过几天就要换一次,CNAME绑定的又不会宕机时自动切换,有时候速度还不如Github. 50 | 51 | # 感想 52 | 53 | ## 拿来当网盘用 54 | 55 | 很多人说github开放Unlimited Private Repo后国内会引起一波免费网盘潮,我觉得这似乎不大可能: 56 | 57 | 1.Github本身只是托管代码的,那些放私人文件的一群人难道没有感觉到这一点么? 58 | 2.光是那Github全英文注册界面估计就能拦截一堆小学生了,滥用的可能性就会大大降低了. 59 | 3.Github被国内防火\*限速了(这似乎才是最大原因好不好),用起来比百度网盘还难过. 60 | 61 | 当然,如果只是放一些文档,我觉得大部分人也就是睁一只眼闭一只眼,毕竟临时放一些文档也不为过么. 62 | 63 | 只是有时候瞎逛github总能找到一些SB宗教的信息,欸,打广告打到这上面来了,亏他们想得出,不过网页有时候也是可以借鉴的,一些比较好的善用技术上网法则有些时候也能发现. 64 | 65 | 当然有一些正义的人会到这些repo上抗议,我看过了,但这些repo的拥有者反而更加不讲理,开口就是骂人.我觉得这样的人根本没有理可以讲,而且这种人也没有交流的价值,我个人建议还是不要管这些人,毕竟上Github的人大都都是有理智的,没有多少人会相信这一群讲话毫无根据的人,让他们自生自灭,不被人看得起,才是最好的解决办法. 66 | 67 | ## 好代码不会开源 68 | 69 | 好,我就说几个结局,看看大家有没有身同感受. 70 | 71 | ### Public坑 72 | 73 | 开了一个Public坑 ==> 被dalao给了一个Star ==> 两个人互相follow ==> PY交易(雾) ==>两个人都被互相激励,写出更好的代码 74 | 75 | 开了一个Public坑 ==> 没人来 ==> 默默自己写着repo ==> 有一天有人把你的repo分享到了知乎 ==> Star过一千 ==> ~~接到局里喝茶(大大雾)~~ ==> 删除repo 76 | 77 | 开了一个Public坑 ==> 没人来 ==> 归档,不想写了 ==> 一个人看到了,测试了一下,发了一个issues ==> 一群人被吸引过来,发了一堆issues ==>被迫续更 78 | 79 | 开了一个Public坑 ==> 吸引了一群人 ==>没空写了,转给社区,自己去悠哉悠哉了 ==>社区继续维护 80 | 81 | 开了一个Public坑 ==> 然后就没有然后了... 82 | 83 | ### Private坑 84 | 85 | 开了一个Private Repo ==> 哎呀自己写的怎么这么烂,欸,幸好没有开源 ==> 清空repo重新写 86 | 87 | 开了一个Private Repo ==> 欸我写的这么好,赶紧开源 ==>跳回public坑 ==>结局与前四个一样 88 | 89 | 开了一个Private Repo ==> 欸我写的这么好,怎么没人Star呢 ==>四处宣扬自己的项目 ==> 最后发现开成私人坑了 ==> 转回public ==> 结局相同 90 | 91 | 开了一个Private Repo ==> 做网盘 ==> 这特么什么神速度 ==> 退坑 92 | 93 | # 结尾 94 | 95 | 至少现在看来Private Repo似乎没有被滥用的很厉害,当然,善用免费服务才能让服务变得更加长久,多了微软~~爸爸~~,相信Github会做的更好! 96 | -------------------------------------------------------------------------------- /source/_posts/Github无法注册:Unable-to-verify-your-captcha-response.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Github无法注册:Unable to verify your captcha response 3 | tags: 4 | - Github 5 | - 错误 6 | - 人机验证 7 | - 善用技术上网 8 | categories: 干问题 9 | copyright: true 10 | abbrlink: 6708e52c 11 | date: 2019-07-27 15:17:34 12 | --- 13 | # 前言: 14 | 前几天就想注册一个Github账号,话说回来早就该注册了。 15 | 前面注册时也是正常的,结果在人机验证(Github Captcha)卡住了。 16 | 点击Create an Account,结果... 17 | # 注册时报错: 18 | ``` 19 | Unable to verify your captcha response. 20 | Please visit https://help.github.com/articles/troubleshooting-connectivity-problems/#troubleshooting-the-captcha 21 | for troubleshooting information. 22 | ``` 23 | 一脸懵逼... 24 | 什么鬼,可是在按下之前人机验证不都是打钩了吗?U•ェ•* 25 | ??? 26 | # 试图解决: 27 | 网上查了一下,也有很多类似的事,如 28 | 其中博主提出解决方案: 29 | > 使用IE就可以了. 30 | 31 | (/≧▽≦)/,笑死我了,连Chrome都做不到,怎么可能在IE中做到? 32 | 后来在评论中看到这样的话: 33 | 34 | > **欧二lord:** 35 | > 善用技术上网吧,我换了三个浏览器都不行,后来善用技术上网用chrome就可以了. 36 | 37 | 善用技术上网么... 38 | 我挂上代理后再次进入,结果还是老样子: 39 | ![老样子](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/GITHUB_ERROR.jpg "还是老样子啊") 40 | 41 | ... 42 | 43 | # 最后解决: 44 | 然后我一直点着Create an Account,一直报错.大概点了5下后: 45 | ![新样子](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/GITHUB_CAPTCHA.jpg "=_=换了个样子") 46 | 终于报出真正的人机验证了!点进去,人机验证的方式是旋转小狗小牛到正确的位置. 47 | 人机验证完成,我就直接被跳到邮箱验证了. 48 | ^3^,终于解决了! 49 | # 总结: 50 | 1. 浏览器: 51 | - [x] Chrome 52 | - [x] Firefox 53 | - [x] Chromium 54 | - [ ] IE 55 | 2. 网络状态 56 | - [x] 善用技术上网 57 | 3. 连续点击直到出现真正的人机验证 58 | OK! 59 | - - - 60 | 61 | -------------------------------------------------------------------------------- /source/_posts/GooseDesktop桌面鸭-网课好宠物.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: GooseDesktop桌面鸭_网课好宠物 3 | author: CYF 4 | tags: 5 | - 宠物 6 | - 桌面 7 | - GooseDesktop 8 | categories: 9 | - 繡软件 10 | index_img: 'https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/cover/5.png' 11 | banner_img: 'https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/cover/5.png' 12 | abbrlink: 5b32ef71 13 | date: 2020-03-24 08:24:00 14 | --- 15 | # GooseDesktop 16 | 17 | 18 | >>点我去下载 19 | 20 | 21 | 22 | 23 | 可玩性非常高: 24 | 25 | 26 | - 会随机拖出一些~~治愈人心~~毒鸡汤(可以自定义) 27 | ![](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/10.gif) 28 | - 会随机拖出一些你珍藏多年的图片(可以自定义) 29 | ![](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/11.gif) 30 | - 关闭它拖出了来的图片会导致它追你的鼠标,追到就咬住,鼠标暂时失控. 31 | - 双击它也会追鼠标(可以关闭) 32 | - 自定义鸭子的颜色 33 | 34 | 好的,也就这么多,更多的可以自己用VSCode写一些mod. 35 | 36 | 试着想一下,这是不是特别适合网课的时候玩呢? 37 | 38 | # 配置 39 | 40 | 下载下来,打开来应该是这样: 41 | 42 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-91.png) 43 | 44 | 进入 `Assets`: 45 | 46 | 47 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-92.png) 48 | 49 | `Images\memes`,里面是鸭子随机拖出来的图片,我的版本里已经预置了10张美图+2张脖子以下不能看.jpg.注意不要在家长旁边打开!当然你也可以替换成别的,文件名随意. 50 | 51 | 在 `/Assets/Text/NotepadMessages` 里是鸭子拖出来的文本,里面已经预置了1222句毒鸡汤,句句治愈人心.当然你也可以替换成别的,文件名随意. 52 | 53 | 打开 `/config.ini` 应该是这样: 54 | 55 | ``` 56 | Version_DoNotEdit=1 57 | EnableMods=false 58 | SilenceSounds=false 59 | Task_CanAttackMouse=True 60 | AttackRandomly=False 61 | UseCustomColors=true 62 | GooseDefaultWhite=#ffffff 63 | GooseDefaultOrange=#ffa500 64 | GooseDefaultOutline=#d3d3d3 65 | MinWanderingTimeSeconds=10 66 | MaxWanderingTimeSeconds=10 67 | FirstWanderTimeSeconds=1 68 | ``` 69 | 70 | 第二行指开不开启mod,目前它还没有很多mod,保持false即可. 71 | 72 | `SilenceSounds` 指鸭子发布发出声音,false表示发出,默认false. 73 | 74 | `Task_CanAttackMous` 指点击它会不会咬,默认为true(否则桌面鸭意义何在) 75 | 76 | `AttackRandomly` 指会不会随机咬,默认保持false,这个最好不要开起来(否则后果难以想象) 77 | 78 | `UseCustomColors` 使用自定义颜色,默认false 79 | 80 | 下面三行是颜色自定义. 81 | 82 | `MinWanderingTimeSeconds` 鸭子随机拖出文件等待时间最小值,单位秒,建议:30 83 | `MaxWanderingTimeSeconds` 鸭子随机拖出文件等待时间最小值,单位秒,建议:120 84 | 85 | `FirstWanderTimeSeconds` 第一次打开鸭子后多久开始拖,随意 86 | 87 | # 基本操作 88 | 89 | ## 关闭 90 | 91 | **回到桌面** 其他应用无效,长按Esc即可. 92 | 93 | 或双击运行 `Close Goose.bat` 快速关闭 94 | 95 | 或直接运行: `taskkill/f /im goosedesktop.exe` 也行. 96 | 97 | ## 静音 98 | 99 | 配置文件 `SilenceSounds=true` 即可 100 | 101 | ## 惹怒 102 | 103 | 双击它,它就会追着你的鼠标,咬到了就是将近5秒鼠标失控时间,鼠标就会被这只鸭子叼着走. 104 | 105 | 或关闭它拖出来的文件,也是同样的效果. 106 | 107 | # 后言 108 | 109 | 这篇水的有点彻底啊....QWQ 110 | -------------------------------------------------------------------------------- /source/_posts/MarkDown语法详解(中级版).md: -------------------------------------------------------------------------------- 1 | --- 2 | title: MarkDown语法详解(中级版) 3 | tags: 4 | - MarkDown 5 | - 语法 6 | categories: 爱学习 7 | copyright: true 8 | abbrlink: 45f10239 9 | date: 2019-07-22 14:28:23 10 | updated: 2019-07-23 14:44:57 11 | --- 12 | # 前言: 13 | > **注意** 14 | > 文章内所有名字纯属虚构,如有雷同,纯属巧合! 15 | 16 | > 这是第二篇MarkDown语法详解(中级版),如果你想要学习第一篇,请前往[MarkDown语法详解(初级版)](/2019/07/21/MarkDown语法详解(初级版)) 17 | 18 | 下面开始授课: 19 | ## 超链接: 20 | 格式如下: 21 | ``` 22 | [MarkDown语法详解(初级版)](/2019/07/21/MarkDown语法详解(初级版)) 23 | ``` 24 | 25 | 你会得到: 26 | [MarkDown语法详解(初级版)](/2019/07/21/MarkDown语法详解(初级版)) 27 | 第一个方括号内填标题,后一个圆括号内写链接. 28 | 这个比较简单. 29 | 当然你也可以这样: 30 | ``` 31 | 32 | ``` 33 | 结果是: 34 | 35 | 36 | ## 图片: 37 | ### 一种方法: 38 | 格式如下: 39 | ``` 40 | ![图片标题](图片地址 "图片ALT") 41 | ``` 42 | 43 | 其中`图片alt`可不填.图片地址可以是绝对地址,也可以是相对地址. 44 | 45 | 例如: 46 | ``` 47 | ![刘老师](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/LLS.jpg "刘老师真容") 48 | ``` 49 | 是相对地址,会得到: 50 | ![刘老师](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/LLS.jpg "刘老师真容") 51 | (这么帅气的脸只舍得打半边马赛克) 52 | 而 53 | ``` 54 | ![刘老师](https://blog.cyfblog.gahttps://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/LLS.jpg "刘老师真容") 55 | ``` 56 | 是绝对地址,会得到: 57 | ![刘老师](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/LLS.jpg "刘老师真容") 58 | 59 | 其实结果是一样的. 60 | ### 另一种方法: 61 | 当然,你也可以像网址那样对图片网址使用变量: 62 | ``` 63 | 这个链接用 1 作为网址变量 [刘老师真容][1]. 64 | 然后在文档的结尾位变量赋值(网址) 65 | 66 | [1]: https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/LLS.jpg 67 | ``` 68 | 会得到: 69 | 这个链接用 1 作为网址变量 [刘老师真容][1]. 70 | 然后在文档的结尾位变量赋值(网址) 71 | 72 | [1]: https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/LLS.jpg 73 | 74 | > **提示** 75 | > 如果你对大小比较在意,可以使用html语法来写.具体写法在高级玩法写出. 76 | 77 | ## 排序 78 | ### 无序排序: 79 | 使用`+`或`-`或`*`来做首标题 80 | 实例如下: 81 | ``` 82 | + 科学作业:无 83 | + 语文作业:翻倍 84 | + 数学作业:超级加倍 85 | ``` 86 | 会得到: 87 | 88 | + 科学作业:无 89 | + 语文作业:翻倍 90 | + 数学作业:超级加倍 91 | 92 | > **注意** 93 | > 无论是`+`或`-`或`*`,使用时与要列表的文字空一格空格! 94 | 95 | ### 有序列表: 96 | 使用`数字`+`.`+`空格`+`文字`代替,如: 97 | ``` 98 | 1. 写试卷 99 | 2. 写两张试卷 100 | 3. 写三张试卷 101 | ``` 102 | 会得到: 103 | 104 | 1. 写试卷 105 | 2. 写两张试卷 106 | 3. 写三张试卷 107 | 108 | > **警告** 109 | > 一定要加空格! 110 | 111 | ## 列表镶嵌: 112 | 如实例:在第二列前加上Tab一个即可! 113 | ``` 114 | + 一级无序列表内容 115 | + 二级无序列表内容 116 | + 二级无序列表内容 117 | + 二级无序列表内容 118 | 119 | - 一级无序列表内容 120 | 1. 二级有序列表内容 121 | 2. 二级有序列表内容 122 | 3. 二级有序列表内容 123 | 124 | 1. 一级有序列表内容 125 | + 二级无序列表内容 126 | + 二级无序列表内容 127 | + 二级无序列表内容 128 | 129 | 130 | 1. 一级有序列表内容 131 | 1. 二级有序列表内容 132 | 2. 二级有序列表内容 133 | 3. 二级有序列表内容 134 | ``` 135 | 会得到: 136 | + 一级无序列表内容 137 | + 二级无序列表内容 138 | + 二级无序列表内容 139 | + 二级无序列表内容 140 | 141 | - 一级无序列表内容 142 | 1. 二级有序列表内容 143 | 2. 二级有序列表内容 144 | 3. 二级有序列表内容 145 | 146 | 1. 一级有序列表内容 147 | + 二级无序列表内容 148 | + 二级无序列表内容 149 | + 二级无序列表内容 150 | 151 | 152 | 1. 一级有序列表内容 153 | 1. 二级有序列表内容 154 | 2. 二级有序列表内容 155 | 3. 二级有序列表内容 156 | 157 | ## 分隔符: 158 | 以`- - -`为例子: 159 | 中级教程完. 160 | - - - 161 | 162 | -------------------------------------------------------------------------------- /source/_posts/MarkDown语法详解(初级版).md: -------------------------------------------------------------------------------- 1 | --- 2 | title: MarkDown语法详解(初级版) 3 | tags: 4 | - MarkDown 5 | - 语法 6 | categories: 爱学习 7 | copyright: true 8 | abbrlink: 9ecd8772 9 | date: 2019-07-21 14:12:31 10 | --- 11 | # 前言: 12 | ## 什么是MarkDown? 13 | Markdown 是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档。 14 | Markdown 语言在 2004 由约翰·格鲁伯(英语:John Gruber)创建。 15 | ![约翰·格鲁伯](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/JG.jpg "约翰·格鲁伯") 16 | Markdown 编写的文档可以导出 HTML 、Word、图像、PDF、Epub 等多种格式的文档。 17 | Markdown 编写的文档后缀为 .md, .markdown。 18 | 由于Markdown的轻量化、易读易写特性,并且对于图片,图表、数学式都有支持,当前许多网站都广泛使用 Markdown 来撰写帮助文档或是用于论坛上发表消息。例如:GitHub、reddit、Diaspora、Stack Exchange、OpenStreetMap 、SourceForge等。甚至Markdown能被使用来撰写电子书。因此,很多博客把它当作语法来写,比如WordPress,Hexo,或者是Typecho. 19 | 常见的编辑器有[Typora](https://typora.io/),还有萌萌哒编辑器[Yosoro](https://yosoro.coolecho.net/) 20 | 下面开始讲 21 | # 语法: # 22 | > **注意** 23 | > 文章内所有名字纯属虚构,如有雷同,纯属巧合! 24 | 25 | ## 文字 26 | MarkDown的文字直接书写,与正常无区别 27 | 书写 28 | ``` 29 | 我是刘老师. 30 | ``` 31 | 32 | 会得到: 33 | 34 | 我是刘老师. 35 | 36 | ## 标题: 37 | 基本上标题分两种: 38 | ### 分隔符标题: 39 | 以`-`和`=`分隔成一级和二级标题: 40 | ``` 41 | 我是一级刘老师 42 | --- 43 | 我是二级刘老师 44 | === 45 | ``` 46 | 会得到: 47 | 48 | 我是一级刘老师 49 | --- 50 | 我是二级刘老师 51 | === 52 | 53 | > **注意:** 54 | > 无论是`-`还是`=`,只要三个及以上即可! 55 | 56 | ### 字符标题: 57 | 以`#`代替标识,`#`越多`,标题级别越低: 58 | 例子: 59 | ``` 60 | # 我是一级刘老师 61 | ## 我是二级刘老师 62 | ### 我是三级刘老师 63 | #### 我是四级刘老师 64 | ##### 我是五级刘老师 65 | ###### 我是六级刘老师 66 | ``` 67 | 会得到: 68 | # 我是一级刘老师 69 | ## 我是二级刘老师 70 | ### 我是三级刘老师 71 | #### 我是四级刘老师 72 | ##### 我是五级刘老师 73 | ###### 我是六级刘老师 74 | 75 | > **注意** 76 | > 以#来做标题不得超过6个! 77 | ## 段落: 78 | MarkDown的段落直接换行,与正常无区别. 79 | 80 | ## 字体: 81 | MarkDown可用字体如下: 82 | ``` 83 | *我是斜着的刘老师* 84 | _我也是斜着的刘老师_ 85 | **我是粗粗的刘老师** 86 | __我也是粗粗的刘老师__ 87 | ***我是又粗又斜的刘老师*** 88 | ___我也是又粗又斜的刘老师___ 89 | ``` 90 | 你会得到: 91 | *我是斜着的刘老师* 92 | _我也是斜着的刘老师_ 93 | **我是粗粗的刘老师** 94 | __我也是粗粗的刘老师__ 95 | ***我是又粗又斜的刘老师*** 96 | ___我也是又粗又斜的刘老师___ 97 | 98 | ## 删除线 99 | 用`~~`把要删除的文字包起来 100 | ``` 101 | 刘老师:今天试卷加~~三张~~ 四张! 102 | ``` 103 | 会得到: 104 | 105 | 刘老师:今天试卷加~~三张~~ 四张! 106 | 107 | 108 | ## 引用(有时可做警告) 109 | 语法: 110 | ``` 111 | > 刘:YRWS,ZSWF 112 | ``` 113 | 得到: 114 | > 刘:YRWS,ZSWF 115 | 116 | 还可以多级引用: 117 | ``` 118 | > 我是被引用的刘老师. 119 | >> 我是被引用的刘老师. 120 | >>> 我是被引用的刘老师. 121 | >>>> 我是被引用的刘老师. 122 | >>>>> 我是被引用的刘老师. 123 | >>>>>> 我是被引用的刘老师. 124 | >>>>>>> 我是被引用的刘老师. 125 | >>>>>>>> 我是被引用的刘老师. 126 | >>>>>>>>> 我是被引用的刘老师. 127 | ``` 128 | 129 | > 我是被引用的刘老师. 130 | >> 我是被引用的刘老师. 131 | >>> 我是被引用的刘老师. 132 | >>>> 我是被引用的刘老师. 133 | >>>>> 我是被引用的刘老师. 134 | >>>>>> 我是被引用的刘老师. 135 | >>>>>>> 我是被引用的刘老师. 136 | >>>>>>>> 我是被引用的刘老师. 137 | >>>>>>>>> 我是被引用的刘老师. 138 | 139 | 好像可以一直下去 140 | > **注意** 141 | > 如果你想要跳出引用,请换行再写! 142 | 143 | ## 代码: 144 | ### 单行代码: 145 | 用\`包裹 146 | ### 代码块: 147 | 用\`\`\`把代码包裹 148 | 此处不好举例,不再举例了. 149 | > **提示** 150 | > 在\`\`\`后加上代码类型可以给予代码高亮欧! 151 | 152 | 初级教程完,接下来请去中级教程. 153 | - - - 154 | -------------------------------------------------------------------------------- /source/_posts/MarkDown语法详解(高级版).md: -------------------------------------------------------------------------------- 1 | --- 2 | title: MarkDown语法详解(高级版) 3 | tags: 4 | - MarkDown 5 | - 语法 6 | categories: 爱学习 7 | copyright: true 8 | abbrlink: '6290e861' 9 | date: 2019-07-24 12:46:32 10 | --- 11 | # 前言: 12 | > **注意** 13 | > 文章内所有名字纯属虚构,如有雷同,纯属巧合! 14 | 15 | > 这是第三篇MarkDown语法详解(高级版),如果你想要学习第二篇,请前往[MarkDown语法详解(中级版)](/2019/07/22/MarkDown语法详解(中级版));如果你想要学习第一篇,请前往[MarkDown语法详解(初级版)](/2019/07/21/MarkDown语法详解(初级版)) 16 | 17 | > **警告** 18 | > 本次授课相对来说比较难,请做好心理准备! 19 | 20 | ## 列表: 21 | ### 正常方法: 22 | Markdown 制作表格使用`|`来分隔不同的单元格,使用`-`来分隔表头和其他行。 23 | 语法格式如下: 24 | ```Markdown 25 | | 表头 | 表头 | 26 | | ---- | ---- | 27 | | 单元格 | 单元格 | 28 | | 单元格 | 单元格 | 29 | ``` 30 | | 表头 | 表头 | 31 | | ---- | ---- | 32 | | 单元格 | 单元格 | 33 | | 单元格 | 单元格 | 34 | 35 | 当然你也可以在表格中使用特殊符号如: 36 | ```Markdown 37 | |人物|技能一|技能二|技能三|大招| 38 | |----|----|----|----|----| 39 | |刘老师|讲一个段子|加一张试卷|/|考一场试| 40 | |梁M法|抢体育课|抢电脑课|抢美术课|连续考试| 41 | |刘老师老婆|[哭](https://baike.baidu.com/item/一哭二闹三上吊/838254)|[闹](https://baike.baidu.com/item/一哭二闹三上吊/838254)|[上吊](https://baike.baidu.com/item/一哭二闹三上吊/838254)|向刘老师发射一张离婚协议书.对其造成5000点物理伤害| 42 | ``` 43 | |人物|技能一|技能二|技能三|大招| 44 | |----|----|----|----|----| 45 | |刘老师|讲一个段子|加一张试卷|/|考一场试| 46 | |梁M法|抢体育课|抢电脑课|抢美术课|连续考试| 47 | |刘老师老婆|[哭](https://baike.baidu.com/item/一哭二闹三上吊/838254)|[闹](https://baike.baidu.com/item/一哭二闹三上吊/838254)|[上吊](https://baike.baidu.com/item/一哭二闹三上吊/838254)|向刘老师发射一张离婚协议书.对其造成5000点物理伤害| 48 | 49 | ### 对齐: 50 | 我们可以设置表格的对齐方式: 51 | 52 | - -: 设置内容和标题栏居右对齐。 53 | - :- 设置内容和标题栏居左对齐。 54 | - :-: 设置内容和标题栏居中对齐。 55 | 实例如下: 56 | ``` 57 | | 左对齐 | 右对齐 | 居中对齐 | 58 | | :-----| ----: | :----: | 59 | | 单元格 | 单元格 | 单元格 | 60 | | 单元格 | 单元格 | 单元格 | 61 | ``` 62 | | 左对齐 | 右对齐 | 居中对齐 | 63 | | :-----| ----: | :----: | 64 | | 单元格 | 单元格 | 单元格 | 65 | | 单元格 | 单元格 | 单元格 | 66 | 67 | > **提示**: 68 | > 表格打完要空一行啊! 69 | 70 | ## 流程图: 71 | Hexo用户可能要额外安装插件: `npm install --save hexo-filter-flowchart` 72 | 73 | st=>start: Start:>http://www.google.com[blank] e=>end:>http://www.google.com op1=>operation: My Operation sub1=>subroutine: My Subroutine cond=>condition: Yes or No?:>http://www.google.com io=>inputoutput: catch something... para=>parallel: parallel tasks st->op1->cond cond(yes)->io->e cond(no)->para para(path1, bottom)->sub1(right)->op1 para(path2, top)->op1 74 | 具体写法前往[官网](http://flowchart.js.org)了解更多. 75 | 76 | ## 打出正常符号来: 77 | 用`\`反斜杠来转义,转义表格如下: 78 | 79 | | 你要打出的符号 | 你应该写出的符号 | 80 | |----|----| 81 | |`!`|`\!| 82 | |\`|\\\`| 83 | |`#`|`\#`| 84 | |`-`|`\-`| 85 | |`&`|`\&`| 86 | |`*`|`\*`| 87 | |`+`|`\+`| 88 | 89 | 等等等等只要以单个`\`放在需转义的单个字符前即可. 90 | 91 | > **注意** 92 | > 多字符转义需要一个一个添加`\`! 93 | > 被\`和\`\`\`包裹起来的代码无需转义! 94 | 95 | ## 公式: 96 | ### 单行公式: 97 | 用一个`$`来包裹单行代码(Hexo不支持) 98 | ### 多行公式: 99 | 用两个`$`来包裹单行代码(Hexo不支持) 100 | 101 | ## Todo: 102 | 用`[ ]`代替未完成的事项: 103 | - [ ] 语文作业 104 | 用`[x]`代替已完成的事项: 105 | - [x] 科学作业 106 | 107 | > **注意** 108 | > 如果你显示不出来.... 109 | > 说明你踩坑里去了! 110 | > 在每一个`[ ]`和`[x]`前要加上[无序列表的符号](/2019/07/22/MarkDown语法详解(中级版)/#无序排序)!! 111 | > 反正我是踩坑里去了! 112 | 113 | 114 | ## HTML标签: 115 | Markdown本身就能与html互相转换,比如: 116 | ```markdown 117 | [baidu](https://baidu.com) 118 | ``` 119 | 转换成html: 120 | ```html 121 | baidu 122 | ``` 123 | 不在 Markdown 涵盖范围之内的标签,都可以直接在文档里面用 HTML 撰写。 124 | 目前支持的 HTML 元素有:`&lt;kbd&gt; &lt;b&gt; &lt;i&gt; &lt;em&gt; &lt;sup&gt; &lt;sub&gt; &lt;br&gt;`等 ,如: 125 | 此处讲解几个不能被markdown使用的标签: 126 | ### 按键符号: 127 | ``` 128 | 按&lt;kbd&gt; &lt;b&gt; &lt;i&gt; &lt;em&gt; &lt;sup&gt; &lt;sub&gt; &lt;br&gt;就可以调出任务管理器了! 129 | ``` 130 | 按Ctrl+Shift+Esc就可以调出任务管理器了! 131 | 132 | ### 上标 133 | ```html 134 | 我是正常的刘老师我是上标刘老师 135 | ``` 136 | 我是正常的刘老师我是上标刘老师 137 | 138 | ### 下标: 139 | ```html 140 | 我是正常的刘老师我是下标刘老师 141 | ``` 142 | 我是正常的刘老师我是下标刘老师 143 | 144 | ### 改字体颜色: 145 | ```html 146 | 刘:我的心和我一样颜色 147 | ``` 148 | 刘:我的心和我一样颜色 149 | ### 改字体背景颜色: 150 | ```html 151 |

刘:我的心和背景一样颜色!

152 | ``` 153 |

刘:我的心和背景一样颜色!

154 | 155 | ### 改字体大小: 156 | ```html 157 | 刘:我的\*和我一样大 158 | ``` 159 | 160 | 刘:我的\*和我一样大 161 | 162 | ## js/css 163 | 与正常使用无差异 164 | 165 | 完 166 | - - - 167 | 168 | 169 | 170 | 171 | 172 | 173 | -------------------------------------------------------------------------------- /source/_posts/Momentum:一款美化你Chrome新标签页的插件.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Momentum:一款美化你Chrome新标签页的插件 3 | tags: 4 | - 插件 5 | - 标签页 6 | - 美化 7 | - Chrome 8 | categories: 丆插件 9 | copyright: true 10 | abbrlink: 3d76e8ac 11 | date: 2019-08-05 14:52:50 12 | --- 13 | 最近在折腾站点收录,有点忙,今天就过来水一片吧。 14 | # Momentum chrome插件概述 15 | Momentum插件是一款自动更换壁纸,自带时钟,任务日历和工作清单的chrome浏览器插件。官方的解释就是:替换你 Chrome 浏览器默认的“标签页”。里面的图片全部来自500PX里面的高清图,无广告,无弹窗,非常适合笔记本使用,让装逼再上新台阶。让我来感受下出自细节,触及心灵的美。 16 | 17 | # Momentum chrome插件功能介绍 18 | 我们知道Chrome 的新标签页默认会显示经常访问的网页,多数情况下会比导航网站靠谱,但是我们是不是会觉得新标签页由于多年没换过,偶尔换个新鲜养眼的也不错?Momentum插件就是能帮助我们解决这个问题的,能给老掉牙的 Chrome 新标签页换个样式,首先添加一个漂亮的风景照,右上角显示当前城市天气,右下角可添加待办事项 Todo 列表,正中间显示系统时间以及今天的主要目标,想切换回原标签页,点击左上角 Apps 即可 19 | 20 | - [x] 华丽的、赏心悦目的图片充满整个Tab页,忘掉Google默认的那个吧! 21 | - [x] 轻度的任务管理:设置今天的目标,以及查看过往Todo list来巡视完成情况。 22 | - [x] 时间、所在地天气、格言(英语谚语或来自某经典电影的台词…),合理的排布位置并没有让页面显得臃肿。 23 | - [x] 当然,常用网址和Chrome应用列表页也保留了。(点击左上角“Apps”进入) 24 | 25 | ![棒棒哒](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/M.jpg "↑每天都能换壁纸呢!!") 26 | 27 | # Momentum chrome插件下载 28 | 在chrome应用商店搜索momentum插件,直接安装就可以.但无法直连,这里提供私有云链接: 29 | 30 | 31 | >>CYF的私有云 32 | 33 | 34 | - - - 35 | 36 | 37 | -------------------------------------------------------------------------------- /source/_posts/PHPnow.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: PHPnow-Windows下最轻巧的PHP运行软件,没有之一 3 | author: CYF 4 | tags: 5 | - PHP 6 | - Windows 7 | - 精简 8 | categories: 9 | - 繡软件 10 | index_img: 'https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-162.png' 11 | banner_img: 'https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-162.png' 12 | abbrlink: fb03447c 13 | date: 2020-03-29 08:20:00 14 | --- 15 | 虽然作为一个静态博客的博主,但是还是有调试PHP的需求,(搭建静态是因为静态博客省钱),之前用过PHPStudy,不得不说功能真的非常强大,~~但我很多功能都不需要~~ ,而且相当吃内存,我一个笔记本主要是追求轻巧,PHPStudy一个安装包将近50MB。最头疼的是,我的80端口已经被系统监听了,无法终结,PHPStudy即使改了端口也没用,导致MySQL服务刚启动就停止的奇葩现象,害的我一年都没有好好调试过PHP。 16 | 17 | 至于这个安装包哪里来的,讲个笑话,在植物大战僵尸贴吧个人网址flash试玩版里提到: 18 | 19 | 20 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-143.png) 21 | 22 | 然后我就把PHPnow提取出来了,一个只有20MB的PHP运行包。 23 | 24 | >>去网盘下载 25 | 26 | 27 | 28 | **请注意,PHPnow已经终止开发,最后一版的更新时间是2012-02-03** ,默认官网是,现在已经重定向至,最高PHP是5.2.14,最高MySQL是5.1.50,框架只有Apache,最高2.2.16,并且与Windows10存在一定的bug,请仔细阅读下面的文档! 29 | 30 | # 安装 31 | 32 | 33 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-152.png) 34 | 35 | 解压: 36 | 37 | 38 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-153.png) 39 | 40 | 有个7z.exe说明这是个解压Package.7z包, 41 | 42 | Win10因为有UAC,直接双击Setup.cmd有问题,右键管理员也不行,要手动启动管理员命令行,cd到相应文件夹,输入 `Setup` 安装!否则会安装失败! 43 | 44 | 45 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-154.png) 46 | 47 | 48 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-155.png) 49 | 50 | 输入22 51 | 52 | 53 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-156.png) 54 | 55 | 输入51 56 | 57 | 接着是一番解压,不要管。 58 | 59 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-157.png) 60 | 61 | 输入y 62 | 63 | 64 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-158.png) 65 | 66 | 67 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-159.png) 68 | 69 | Windows10家庭版不知道为什么80端口被禁用了,所以只能选1,我这里端口为4001 70 | 71 | 72 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-160.png) 73 | 74 | 安装,设置root密码 75 | 76 | 77 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-161.png) 78 | 79 | 任意键后,出现以下 80 | 81 | 82 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-162.png) 83 | 84 | 安装完成! 85 | 86 | # 控制面板 87 | 88 | 安装完成后输入 `pncp` ,进入管理界面 89 | 90 | 91 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-163.png) 92 | 93 | 下次启动输入20,关闭输入30,其它的具体看情况 94 | 95 | # 放入 96 | 97 | 将php放入 `htdocs` 即可! 98 | 99 | # 测试Typecho 100 | 101 | 由于版本真的很古老,安装Typecho之类的请安装0.9,安装最新版1.\*会导致错误! 102 | 103 | 104 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-164.png) 105 | 106 | 107 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-165.png) 108 | 109 | 一路确认,数据库填写test,安装完成 110 | 111 | 112 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-166.png) 113 | 114 | 115 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-167.png) 116 | 117 | 毕竟是古老的php,至少笔记本跑起来真的毫无压力,作为测试环境也完全足够了. -------------------------------------------------------------------------------- /source/_posts/Pandownload-愿你归来仍是英雄.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Pandownload:愿你归来仍是英雄' 3 | author: CYF 4 | tags: 5 | - 百度 6 | - 网盘 7 | - PanDownload 8 | - 悼文 9 | index_img: 'https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/cover/8.jpg' 10 | banner_img: 'https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/cover/8.jpg' 11 | categories: 12 | - 随心记 13 | abbrlink: 1b33467f 14 | date: 2020-04-17 17:19:00 15 | --- 16 | PanDownload 21世纪的英雄,在几天前,死了。 17 | 18 | 4月15日下午,扬州网警巡查执法官方微博发布通报称:“Pandownload软件开发嫌疑人已经被捕。” 19 | 20 | 刘某:PanDownload有窃取用户隐私行为。 21 | 22 | 嗯,来,你的证据呢? 23 | 24 | # 人性的毁灭 25 | 26 | 百度网盘迟迟不对PanDownload限制,之前很奇怪,现在明白了,原来是等到“盈利”到30万,有了个证据,才死死咬住不放。百度阴险,由此可见。 27 | 28 | 百度网盘限速,我就只能说呵呵了,如果你杠百度网盘硬盘资源有限,那么开始你可以调小硬盘大小,尽量不限速,那还行。自己拼命张开嘴说自己吃的多,到头来发现吃不了又悄悄闭嘴,什么意思? 29 | 30 | 刘某,一个人就可以把一个开发者抓到牢里,呵,我现在相当有理由怀疑这是个幌子,百度人性,可见一斑。哦不,百度没有人性。 31 | 32 | 想当年,550KB的运用程序硬是给我弄成大文件。我??? 33 | 34 | # 要推车出去的停车场 35 | 36 | 百度网盘就好比停车场吧,刚开始假惺惺说这里空间比谁都大,好吧这确实赢得了我的好感,于是我也存了很多东西上去,就好比我把很多车开进来。直到垄断了整个停车场事业。百度终于展现自己的吃相了。 37 | 38 | 开车进来?没问题!2T空间,随便你!对啊,2T空间,谁不想要呢?我也停了。附近的停车场用户太多没能力,倒闭了。 39 | 40 | 现在,当我要开车出去的时候,你突然告诉我,不能开车出去,要用手推出去,理由是出去的通道很窄?要开车要付费,几十块一个月? 41 | 42 | PanDownload,形象点,就是把你分身成几个,一起推,现在,总算能正常出去了吧。 43 | 44 | PanDownload窃取用户隐私?你可能没搞懂,PanDownload,作用就是把你分身(Aria2多线程下载),窃取用户隐私,我可以肯定地说,就是个幌子。幕后百度,我只能说呵呵了。 45 | 46 | # 漏洞百出的被捕声明 47 | 48 | 49 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-195.png) 50 | 51 | 首先,PanDownload核心就是获取个直链,你需要反编译解剖软件结构,一盯几个小时?民警办案效率挺高的嘛。 52 | 53 | 黑客攻击计算机系统,哦,获取直链就算是黑客啦?我觉得我好屌哦。 54 | 55 | 隐私照片和文件泄露:证据呢? 56 | 57 | 以非会员权限突破百度网盘设定:你还是没脸说自己限速是吧,百度? 58 | 59 | 侵入?非法控制?:PanDownload唯一的作用就是获取直接链接(百度网盘客户端的正常操作)以及多线程下载(官方客户端没有),我用多线程就算是违法咯? 60 | 61 | 欸,行了行了,我都不想说了; 62 | 63 | # 未来,何去何从 64 | 65 | 互联网上分享个文件真的很难吗?我想,对于众多小白来说,真的,互联网分享文件确实很难。 66 | 67 | 百度一家,我已经彻底失去最后一点希望了, 68 | 69 | 贴吧的风控我也是服了,认认真真敲好的字被删除,我还不如用知乎; 70 | 71 | 搜索引擎?呵呵,营销号的风格,一目了然,国内我现在用[magi](https://magi.com) 一个人工智能搜索引擎,自动从网上拉取文章研究,AI把营销号和同类文章精准度真的高,而且搜索一些学习单词也很正常;或者使用DogeDoge(感觉颇似DuckDuckGo),精准的不误导不追踪;Bing,说实话不太习惯;国外的我就不必多说了; 72 | 73 | 网盘?OneDrive15GB储存个人资料不香么?普通大文件分享像我这样的穷B Workers+GoogleDrive用户体验完爆百度,为什么要百度资本?Mega还行,实际上Mega15GB也就刚好吧(那个50GB中35GB是新用户临时体验,一个月后失效)。再不济,iCloud!苹果有国内加速节点,虽然5GB真的够呛,不过同步一些个人资料还行吧?开源项目直接扔Github,反正也没多大。 74 | 75 | 所有百度,我只有用百度统计需求,原因么,Google统计国内加载真的很拖速度,迫不得已使用百度统计,虽然功能差很多,不过勉强吧; 76 | 77 | **PanDownload能死而复生么?我不清楚,但是,我衷心祈愿!** 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /source/_posts/What-I-Do-2020-04-05.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 这一个半月,我干了什么 3 | author: CYF 4 | tags: 5 | - 日常 6 | - 总结 7 | categories: 8 | - 随心记 9 | index_img: 'https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/cover/9.jpg' 10 | banner_img: 'https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/cover/9.jpg' 11 | abbrlink: cc675020 12 | date: 2020-05-30 16:06:00 13 | --- 14 | ![](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/moji/wjlkdhxs.jpg) 15 | 16 | 啊,期中考试终于考完了,现在心里想的都是司马脸,![](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/moji/huaji.gif) 17 | 18 | 距离上一次更新已经将近1个半月了,赶在5月小尾巴发一篇博文。当然,这个月维护还是做到了,只不过太忙没更新而已。 19 | 20 | 过来扯扯这个月发生了什么。 21 | 22 | # 计算机方面 23 | 24 | ## 网站方面 25 | 26 | ### VPS 27 | 28 | 入手了一台德国VPS,还得感谢这位老兄: 29 | 30 | [簞純-EUserv 德国永久免费VPS申请](https://blog.qwqdanchun.cn/archives/1001) 31 | 32 | 试了一下,性能略差,连IPV4都没有,就当是学习吧,现在就是拿来玩玩的,毕竟我大多数情况下基本是ServerLess。 33 | 34 | 以后打算全站迁移到一台VPS上,当然习惯用Hexo了,毕竟Hexo-Admin还是很给力的。 35 | 36 | ### 图床: 37 | 38 | 我当场裂开。 39 | 40 | 之前全放在Github上,但是,但是这会导致多线程并发是Worker抛出异常,速度还很慢。而且很大,Github那么恐怖的大小:![](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/206.jpg) 41 | 42 | 三个星期前开始迁移,刚开始采用了GoogleDrive+ 43 | GDIndex,上学去的时候,加载速度还不错,结果一到学校,自己打开,爆一大堆404. 44 | 45 | Workers自然也出大问题 46 | ![](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-205.png) 47 | 48 | 后来了解到,谷歌网盘在每每输出一个文件,都会来一次销魂的杀毒,一张10kb的图片,杀毒将近10s,Worker超时30s直接返回404!!!???,我当时心里就开始表演天皇meta的showtime了。![](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/moji/喷血.png) 49 | 50 | 所以后来又采用腾讯云免费SCF额度+OneDrive那可怜的5GB制作图床,好歹也能正常加载,但是OMp的工作原理和GI不一样,GoogleDrive在国内那是不可访问的,所以最终还是采用了反向代理,但是OneDrive是可以滴,所以OMp采用的是301跳转。燃鹅,直连速度和延迟相当的感人,在多线程并发时经常超时。![](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/moji/tx.png) 51 | 52 | 当时整个人都裂开了。 53 | 54 | 所以,最终解决办法就是,氪金!!!!!! 55 | 56 | 腾讯云COS(相当于阿里云OSS)+CDN,当然因为没备案所以放在Hongkong,但是腾讯云有个暗坑,COS绑定自定义域名~~md~~居然不给直接开SSL,非得要套层CDN才行,这不是明摆着坑钱么。计算下来,每天平均支出0.03¥. 57 | 58 | 肉疼。![](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/moji/s.png) 59 | 60 | 好在腾讯COS也有客户端,上传文件至少没那么麻烦。 61 | 62 | 63 | ![](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/207.jpg) 64 | 65 | 不过话说回来,最近香港局势确实很不稳定,我现在根本无法直连Hongkong的COSBucket,CDN套就套吧,只不过神奇地绕道美国都是什么奇葩玩意,害得我只能A到日本,出口居然是Amazon。 66 | 67 | ### 评论系统 68 | 69 | 又是一个当场炸裂的东西。 70 | 71 | Gitalk本身链接api.github.com就是一个相当蛋疼的事情。 72 | 73 | ![](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/205.jpg) 74 | 75 | 我也尝试着做过类似于DiqusJS的反向代理的尝试,可是到最后一步Github回调地址又给我强制跳到api.github.com,我当时人都傻了。最后实在头疼,换成了Valine。当然找了个魔改版本,看起来还不错。~~【这一次再也不会造成30天无访问自动归档这种奇异的事情了】~~ 76 | 77 | ![](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/208.jpg) 78 | 79 | 两个魔改后的JS地址 80 | 81 | ```html 82 | https://npm.elemecdn.com/chenyfan-oss@1.0.0/js/av-min.js 83 | https://npm.elemecdn.com/chenyfan-oss@1.0.0/js/valine.min.js 84 | ``` 85 | 86 | ## 编程方面 87 | 88 | 艹,VB轮到我这一届居然不考,![](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/moji/qgbf.png),害得我只能硬啃C++。考试还行,就那附加题做不出来,一道高精乘法,居然忘记了`strlen()`这个函数,当时想撞墙的心态都有了。 89 | 90 | # 学习方面 91 | 92 | 考完了,我完了。 93 | 94 | 数学150分扣46分是什么鬼???????语文五道选择题错三道又是什么鬼???????? 95 | 96 | 还好物理只扣10分,化学一分没扣,计算机也只是附加题最后一道不会写而已 97 | 98 | 欸欸欸欸欸欸欸,感觉我要垫底。 99 | 100 | # 后言 101 | 102 | 好好学习,天天向上! 103 | 104 | 好了好了,继续潜水![](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/moji/无奈.png) 105 | 106 | 滑稽 -------------------------------------------------------------------------------- /source/_posts/a-simple-think-of-censorship-resistant-chatroom.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 一个不成熟的抗审查、激励性、分布式聊天室想法 3 | author: CYF 4 | tags: 5 | - Sensitive 6 | categories: 7 | - SensitivePosts 8 | hide: true 9 | abbrlink: cc28d5dc 10 | date: 2022-06-20 12:00:00 11 | --- 12 | 13 | 吾于信息课件作小差,恍惚间,茫然时,一个不成熟的念头天马行空般浮于心间:做一个分布式的聊天室怎么样。 14 | 15 | 16 | 17 | 由于疫情原因,全球各地经济状况都在下滑。身处通货膨胀还不严重的China的我,还是能感受到经济滑坡带来的社会动荡。社会的不安定必然会加强对公民的言论和行为审查。必然,我也希望我能做好最坏的打算,如果真的断开了与海外互联网的链接,构造一个不受审查、私人间的聊天室对于我来说就变得很有必要。 18 | 19 | 然而 -------------------------------------------------------------------------------- /source/_posts/goodbye-yuan.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 致敬袁老,精神永在 3 | author: CYF 4 | key: 袁隆平 5 | index_img: 'https://npm.elemecdn.com/chenyfan-cdn@2.0.0-img/hpp_upload/1621673305000.jpg' 6 | banner_img: 'https://npm.elemecdn.com/chenyfan-cdn@2.0.0-img/hpp_upload/1621673305000.jpg' 7 | lushkey: goodbye-yuan.md 8 | abbrlink: 4ee6384 9 | date: 2021-05-22 16:49:21 10 | --- 11 | 12 | “共和国勋章”获得者、中国工程院院士、国家杂交水稻工程技术研究中心主任、湖南省政协原副主席袁隆平,因多器官功能衰竭,于2021年5月22日13时07分在长沙逝世,享年91岁。 13 | 14 | 感谢袁老,让我们端的起饭碗,让我们00后的孩子至少吃得饱。一路走好。 15 | 16 | 我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=3uzi7w7znlsa 17 | 18 | 26 | 27 | -------------------------------------------------------------------------------- /source/_posts/hi2022.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 2022新春小记 3 | author: ChenYFan 4 | tags: 5 | - 新年贺词 6 | categories: 7 | - 随心扯 8 | abbrlink: 7c7f6808 9 | date: 2022-01-10 21:57:45 10 | --- 11 | 12 | 这是一篇随迟但到的新春贺词( 13 | 14 | 15 | 首先呢,旧年总结是不可能做的,这辈子都不可能做的。我发这篇文章的首要目的就是证明我还活着,毕竟上一篇文章到现在已经快半年了(实际上确实有半年) 16 | 17 | 2021年是牛年,这一年过得很平淡,但却伴随着不少热点事件,刨去政治的,防沉迷、反诈、jsd掉备等等。这些热点我会在以后(maybe)一一热炒冷饭。 18 | 19 | 新文仍在赶工,可以[戳我围观新文](/p/c0af86bb.html)(还没写完) 20 | 21 | 博客已经开启了自己写的ChenBlogHelper,在第一次进入博客的时候会自动安装并刷新激活。此helper能够在前端绕过备案、优选cdn以及统计。 22 | 23 | 博客现在在中国大陆有一个广州节点承载,希望这能够给你们带来更好的访问体验。 24 | 25 | 总之,新的一年,祝大家顺心顺意,愉快地享受新年的每一天! -------------------------------------------------------------------------------- /source/_posts/panlist.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: PanList:ServerLess百度网盘列表直链程序 3 | author: CYF 4 | tags: 5 | - 百度网盘 6 | - 网盘 7 | - CloudFlareWorkers 8 | - CloudFlare 9 | - 薅羊毛 10 | categories: 11 | - 好方法 12 | index_img: 'https://npm.elemecdn.com/chenyfan-oss@1.1.5/banner.jpg' 13 | banner_img: 'https://npm.elemecdn.com/chenyfan-oss@1.1.5/banner.jpg' 14 | lushkey: panlist.md 15 | abbrlink: 32883f0c 16 | date: 2021-01-06 21:44:55 17 | --- 18 | 19 | {% note success %} 20 | ### 警告 21 | 本篇文章在panlist发布后两天内写成,panlist尚处于高速迭代状态,本篇教程随时会失效! 22 | {% endnote %} 23 | 24 | > ~~百度网盘2021年最新不限速下载方式是怎么回事呢?百度网盘相信大家都很熟悉,但是百度网盘2021年最新不限速下载方式是怎么回事呢,下面就让小编带大家一起了解吧。~~ 25 | > ~~百度网盘2021年最新不限速下载方式,其实就是PandownloadCloudFlareWorkers版本,大家可能会很惊讶百度网盘怎么会2021年最新不限速下载方式呢?但事实就是这样,小编也感到非常惊讶。~~ 26 | > ~~这就是关于百度网盘2021年最新不限速下载方式的事情了,大家有什么想法呢,欢迎在评论区告诉小编一起讨论哦!~~ 27 | 28 | 29 | 之前写过[GoogleDrive](/p/74e90c90.html)、[OneDrive](/p/4fb070ca.html) 的CloudFlare列表程序,这两个有个共同点,那就是国内都无法很好的下载,所以用CloudFlareWorkers作为中间件转发流量。 30 | 31 | 比较讽刺的是,CloudFlareWorkers用的都是国外节点,但以上两个运行于此的目录列表程序支持的下载速度却远远大于国内有节点的百度网盘,不说是移动BGP走香港有多好,至少我在『电信』网络环境下的下载速度都远远大于百度网盘。很显然,百度网盘作为垄断国内网盘市场的资本,既然已经度过了烧钱的时间,那么现在自然是能剩多少省多少,这就是『吃相难看』。 32 | 33 | 两年前,当微博上的人们开始质问突然『诈尸』的百度网盘微博账号,网友们才纷纷意识到自己的百度网盘被恶意限速了,紧接着,破解百度网盘限速的方式层出不穷。只是后来,这些方式一点一点被打压下去,最终戛然而止。 34 | 35 | 最近这几天因为在写[HexoPlusPlus: A ServerLess Hexo Dashboard](https://github.com/HexoPlusPlus/HexoPlusPlus) 正在努力学习CloudFlareWorkers。由于评论模块需要数据结构有关知识,可惜这一块知识大都都被一些所谓白嫖CloudFlareWorkers的教程所淹没: 36 | 37 | !["Google上CloudFlareWorkers搜索结果"](https://npm.elemecdn.com/chenyfan-oss@1.1.5/101043.jpg) 38 | 39 | 在查询有关资料的时候,Github上一颗冉冉新星引起了我的注意,[PanList](https://github.com/teardr0p/PanList) ,根据其Commit显示,这个仓库仅仅是两天前刚刚开辟的,但是本文写是就有61Star和21Fork 【当然我也有Star】,可见其热门程度。不过简单的翻看了一下我就明白其为何如此热门,第一,它是专门对付令人头疼的百度网盘,第二,它是构建于CloudFlareWorkers。 40 | 41 | # 起步 42 | 43 | 电脑登录百度网盘: 44 | 45 | !["百度网盘"](https://npm.elemecdn.com/chenyfan-oss@1.1.5/101056.jpg) 46 | 47 | 按下F12进入开发者模式,选择`Application`模块,点击`Cookies`: 48 | 49 | !["Cookies"](https://npm.elemecdn.com/chenyfan-oss@1.1.5/101101.jpg) 50 | 51 | 在这里,我们需要获取两个Cookie:`BDUSS`和`STOKEN` 52 | 53 | # 获取 54 | 55 | |Github|JSDelivr| 56 | |---|---| 57 | |[原版Github下载地址](https://raw.githubusercontent.com/teardr0p/PanList/master/index.js)|[原版JSDelivr下载地址](https://cdn.jsdelivr.net/gh/teardr0p/PanList@master/index.js)| 58 | 59 | 修改前面四行代码,分别为 60 | 61 | ```js 62 | const BDUSS = '' 63 | const STOKEN = '' 64 | const USERNAME = '' 65 | const PASSWORD = '' 66 | ``` 67 | 68 | 将获取到的Cookie复制到第一行和第二行。第三、四行是登录后台所需的账号密码。 69 | 70 | > AnyWay,你也可以将这些写入到后台变量 71 | 72 | 新建一个Worker,将处理好的代码直接复制进去: 73 | 74 | ![复制代码](https://npm.elemecdn.com/chenyfan-oss@1.1.5/101307.jpg) 75 | 76 | 保存并部署,确定。 77 | 78 | # 绑定域名 79 | 80 | ![绑定域名](https://npm.elemecdn.com/chenyfan-oss@1.1.5/101107.jpg) 81 | 82 | 路由:`{待绑定的域名}/*` [后面\*的原理是覆盖该路径下所有文件] 83 | Worker:你新建的Worker名字 84 | 85 | # 评测 86 | 87 | 登陆界面: 88 | 89 | ![login](https://npm.elemecdn.com/chenyfan-oss@1.1.5/101115.jpg) 90 | 91 | 打开后: 92 | 93 | ![](https://npm.elemecdn.com/chenyfan-oss@1.1.5/101118.jpg) 94 | 95 | > 挺讽刺的是,去除了百度网盘原始界面乱七八糟的东西,CloudFlareWorkers的国外服务器打开速度都比百度网盘快 96 | 97 | Chrome直接下载速度 98 | 99 | ![](https://npm.elemecdn.com/chenyfan-oss@1.1.5/101447.jpg) 100 | 101 | 传递Cookie后IDM下载速度: 102 | 103 | ![](https://npm.elemecdn.com/chenyfan-oss@1.1.5/101120.jpg) 104 | 105 | 注:单线程下载速率最终取决于百度网盘的限制,也就是说无论如何你也无法逃避百度网盘对源头的遏制,就在我下完`Soul`这部将近2GB的电影后,我的账号就被百度拉入黑名单,现在即使用IDM也只有80kb/s 但是还是比原来的客户端快 106 | 107 | # 尾声 108 | 109 | 本质上panlist无非就是通过baidu没有公开的API通过Cookie鉴权来获取文件列表和下载,虽然依旧没有突破单线程下载限速,但至少实现了直链下载和多线程下载的功能,并且部署在CloudFlareWorkers上的方式确实大开眼界,无服务器应用的范围又扩展了一步,我十分看好这个项目。 110 | 111 | 另外,本人也在努力开发一款同样基于CloudFlareWorkers的评论系统,以下是截图: 112 | 113 | ![](https://npm.elemecdn.com/chenyfan-oss@1.1.5/101127.jpg) 114 | 115 | 最后,来一句姗姗来迟的新年祝福: 116 | 117 | ![](https://npm.elemecdn.com/chenyfan-oss@1.1.5/happy.jpg) 118 | -------------------------------------------------------------------------------- /source/_posts/why-app-but-not-browser.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 为什么是APP而不是网页 3 | author: ChenYFan 4 | tags: 5 | - 应用 6 | - 浏览器 7 | - 隐私 8 | - app 9 | categories: 10 | - 叨叨念 11 | des: 关于国内各大厂商倾向于应用软件而非网页软件的想法 12 | key: '隐私,安全' 13 | index_img: 'https://npm.elemecdn.com/chenyfan-oss@2.0.4' 14 | banner_img: 'https://npm.elemecdn.com/chenyfan-oss@2.0.4' 15 | lushkey: why-app-but-not-browser.md 16 | abbrlink: c0af86a9 17 | date: 2021-07-28 13:24:15 18 | --- 19 | 20 | 一个简单的功能,完全可以在浏览器内实现,凭什么国内某些软件这么希望你去下载,去使用他们的app? 21 | 22 | 23 | 24 | 就在不久前,我是真的体会到了什么叫流氓厂商。点名批评一下百度,我苹果手机Safari随便在百度上搜索点什么,还没把营销号、广告和垃圾信息从眼中剔除,突然间,AppStore界面平移到我眼前,一个叫`百度`的软件可怜巴巴的望着我。于是我点击左上角返回键,然后继续搜索... 25 | 26 | 这不是一件在国内很常见的事情吗,然后我继续浏览,点击一个百度百科网页链接,又是还没开看,appstore显示了出来,这次是百度百科app。 27 | 28 | 好,没事,我平复了一下心情,整理了一下被打乱的思绪,继续浏览着百科,滑到页面底部,加载新的内容时,一个弹窗显示出来:使用百度百科APP,获取更好的浏览体验! 29 | 30 | 关闭,继续浏览。 31 | 32 | 点击百科内部的内链,尝试跳转到另一个百科界面,突然,浏览器一片空白,我又被引导向appstore。 33 | 34 | 很抱歉,我直接关闭了百度,使用谷歌和维基百科继续查询资料。这一次,谷歌虽然也在下方提示【在IOS上尝试使用谷歌桌面版,获取更好的体验】,但至始至终没有把我强制跳到appstore。维基百科就更不用说了,连使用app都没有提示。 35 | 36 | 退出了浏览器,我不禁陷入了沉思。我还记得不久前拿到朋友的新鸿蒙手机,划开屏幕一看,第一个界面全是百度系列:百度、百度搜索、百度智能浏览器、百度贴吧、百度知道...一个个功能冗余的百度app赫然显示在我的眼前,当我一脸震惊地看向朋友,他耸耸肩:点进去就自己下载的,不安装就没办法看了。 37 | 38 | 看着自己苹果手机中的两个一个浏览器:Safari和Alook,我停止了思考,当一个大厂天天为自己的免费网盘带宽叫屈,下载一个3M的电子书被限成一副狗样时,你还能相信他有这么大的带宽给用户推自己的动辄100MB的APP?这能算是本末倒置吗? 39 | 40 | 从此,我在手机上再也没有用过百度系。必应和谷歌,DogeDoge和DuckDuckGo成为了我的搜索主力。 41 | 42 | # 为什么是APP 43 | 44 | ## 隐私 45 | 46 | 47 | app对隐私的疯狂到了什么地步?我也就不贴知乎链接了,就贴一个今天cctv的内容吧: 48 | 49 | 50 | 51 | 在安卓环境【尤其是国内某些套壳系统】下,app的权限不算小,有些时候可以在没有提醒的情况下把你的浏览器记录翻个遍。 52 | 53 | ios其实相对安卓来说,至少系统能主动提醒用户是否给予其访问权利。 54 | 55 | 这一点我也十分佩服MIUI,能在这种隐私岁随意获取风气下站住来守住用户的底线,无论其目的如何,这一点已经赢得了我的好感【虽然我不用安卓】 56 | 57 | 对于软件商来说,用户的数据是一大笔财富。比如知道所有人的喜好、购买能力等,这些信息掌握得越细致,越能挖掘到更多的商机。 58 | 59 | 暂且不说百度,就连TIM和QQ也会主动扫描用户Chrome浏览记录~~我靠那我的nhentai浏览记录怎么办~~ 60 | 61 | ## 互唤醒【For安卓】 62 | 63 | 为了实现广告营销,部分软件实际上要向用户主动推送广告信息。 64 | 65 | 尤其是安卓,由于谷歌市场退出中国大陆,国内安卓生态其实很乱,一个简单的消息推送,也能难倒一群开发者。 66 | 67 | 为什么消息推送变成了一个难题?其实我们想象中的消息推送与实际上的方式有很大差距: 68 | 69 | 想象中:用户手机<==主动推送==微信服务器 70 | 实际上:用户手机<==被动推送==>苹果|安卓消息推送服务器<==主动推送==微信服务器 71 | 72 | 苹果还好说,18年以前经常会出现微信无法推送的情况,但自从大陆线路优化以及云上贵州的迁移,其推送服务逐渐变得正常。然而谷歌早已退出中国市场,其内置的推送服务器已经不可链接,请问这些app这么办? 73 | 74 | 答:常驻系统后台。 75 | 76 | 但是常驻系统后台成为一个Zombine进程也不可避免会被杀掉,请问这又能怎么办? 77 | 78 | 答:相互唤醒。 79 | 80 | 当用户打开一个app,此app会在后台激活另一群app,然后如果当前app被杀了,被激活的app又会激活那个被杀的app。 81 | 82 | 这样就很好理解了虽然只有百度app才会推送广告,但他依旧会引导你去下载百度浏览器---避免被杀掉啊。 83 | 84 | # 为什么不是浏览器应用 85 | 86 | ## 隐私 87 | 88 | 在这个隐私即金钱的时代,对于国内厂商来说,首先一个遗憾的事情是,浏览器是很难获取到用户的隐私信息。不是说功能限制,而是浏览器其核心就是沙盒化。在没有用户同意和外接接口、插件的前提下,你不可能直接用js获取到用户手机/电脑上的文件。 89 | 90 | 而且最致命的是,如果网页应用敢在后台偷偷上传用户隐私,控制台一开就会使其暴露无遗,相对比APP的黑盒操作,那简直是天差地别。 91 | 92 | ## 功能限制 93 | 94 | js功能其实很强大,但有些底层和协议上的限制不能做就是不能做,你不可能用js空手写一个SMTP发送邮件,你也不可能直接用SSH协议链接服务器【WebSSH需要在服务器主动安装服务端】 95 | 96 | 其次,一些十分耗资源和计算力的服务不可能在浏览器上实现,比如腾讯不可能把王者荣耀搬到浏览器上,你也不可能在浏览器里跑机器学习。 97 | 98 | ## 网络限制 99 | 100 | 如果使用浏览器,其每一次打开服务网店都要重新下载上面的js、css和图片资源,这一瞬间爆发对服务器压力其实不小。 101 | 102 | 而使用app,他可以事先在后台下载好广告图片,其样式和功能无需重新下载,并且很多资源可以缓存在本地,即使短暂离线也能推送。 103 | 104 | 这一点,PWA技术完全可以胜任。PWA通过在浏览器内ServiceWorker拦截和缓存内容实现离线浏览。但目前来讲PWA技术在国内不温不火【很明显,触碰到了某些企业的利益】,所以还是以应用程序为主。 105 | 106 | 但是,你这样剩下来的流量费还是比不过强制更新来的多啊 107 | 108 | # 为什么国外没有出现类似的情况 109 | 110 | ## 监管缺失 111 | 112 | 海外,安卓应用最官方的商店只有一家:GooglePlay,虽然不像AppStore那种不上架连安装都不给的程度,但也是一种象征。没有上架谷歌商店的应用基本都会被判定为盗版或者危险。而且谷歌play对广告监管很严。如果一个应用敢像百度般,疯狂推送广告和自唤醒,可能连安全审查都过不去。 113 | 114 | 在国内,连老大都管不了,宛若袁世凯暴毙天下军阀混战,其乱象不言而喻。 115 | 116 | ## 隐私意识缺乏 117 | 118 | 李彦宏有句~~名言~~:中国人更愿意用隐私交换便捷性。 119 | 120 | 虽然此话一出被无数网友嘲讽,但也不得不承认这确实如此。甚至有些时候自己也是被迫的。没有多少人会上网的时候开无数个虚拟机中继代理AdGuard,相反,有更多人为了PDD的几分钱蔬菜而抢破头。一句话:国人都喜欢薅羊毛,但最终都会成为韭菜被割。 121 | 122 | 相反,在国外,人们对于隐私十分看重,哪怕GoogleAdsense都被罚了好几次,还不用说Tor之类的隐私保护软件。 123 | 124 | ## 使用观念的不同 125 | 126 | 我个人的习惯是,完成一件事情,用什么东西都越轻越好,不是有必要就不下客户端。比如在电脑微信接收消息,你可以选择下载微信客户端完成传输,也可以用[网页微信](https://wx.qq.com)。相较于前者,后者用完就关,不留痕迹,速度也快。 127 | 128 | 然而国人的习惯大多是:先下载下来,万一以后有用呢。 129 | 130 | 当我看到电视上的手机广告,大多8H16G运存128G内存起步,盯着手里这台国产只装了QQ到2021年还能打Minecraft的iPhone6s【实际配置2GB运存A9处理器】,不禁留下了悔恨的泪水:幸好没买安卓。 131 | 132 | 安卓手机即使内存再大,其底层核心还是虚拟化,加上国内的恶劣的生态,如果你不留神多下点软件,其流畅度甚至比不过6年前的6s。 133 | 134 | 而手机卡,大多数人的第一个想法是:换一台手机。而不是:我删掉点软件,只保留QQ和微信。 135 | 136 | 尤其是,在国内的内循环已经完成的前提下,更多人选择了买爱国手机,装爱国软件。实际上,留一条隐私底线其实也没有什么。但偏偏有人喜欢把自己隐私送给别人。 137 | 138 | # 后言 139 | 140 | 实际上,绝大多数软件从C/S架构向B/S架构的转换是不可避免的。但是国内的生态似乎在阻碍着这一发展。 141 | 142 | 或许有人会问,隐私再保护有什么用。那我只能说,如果你的隐私在黑市只能卖1毛钱一条,那隐私保护的好的人或许能卖5块钱一条。真正的危害其实不在于精准推送,而更怕有人会拿去做违法事情,暴力你,诈骗你。 -------------------------------------------------------------------------------- /source/_posts/【致歉】全能音乐搜索Bug修复.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 【致歉】全能音乐搜索Bug修复 3 | tags: 4 | - 音乐 5 | - 致歉 6 | copyright: true 7 | categories: 爱学习 8 | abbrlink: 58d8c071 9 | date: 2019-08-15 14:08:41 10 | --- 11 | # 前言: 12 | 13 | 就在昨天,一位孜孜不倦的网友 [qwqdanchun](https://github.com/qwqdanchun) 跑到我的issues中,追了我一整天,原因是音乐搜索出现程序错误。 14 | 15 | 刚开始我有点不以为然,本来有些接口就坏掉了,打不开又以为是php服务商的问题,后来ta部署到heroku上,搜索功能有问题,只能显示主页,帮助页显示也有问题,一搜索直接刷新了,这才意识到严重性。 16 | 17 | 后来我打开电脑,仔细查看,终于发现了问题。 18 | 19 | # 问题: 20 | 21 | 我打开储存在本地的文件,和压缩包内文件进行比较,终于发现少了一个文件:`.htaccess` 22 | 23 | 这个文件丢了可就了不得了,这会导致伪静态直接找不到自己在哪。 24 | 25 | 原来在解压时,Windows不允许创建一个无名字的文件,而Liunx允许,这导致我的阉割版好压直接略过错误不报提醒。 26 | 27 | 找到问题就好办了。 28 | 29 | # 解决: 30 | 31 | 直接在Github储存库添加一个`.htaccess`,里面填上: 32 | 33 | ```php 34 | 35 | RewriteEngine on 36 | RewriteCond %{REQUEST_FILENAME} !-d 37 | RewriteCond %{REQUEST_FILENAME} !-f 38 | RewriteRule ^(.*)$ index.php [L,E=PATH_INFO:$1] 39 | 40 | ``` 41 | # 结果: 42 | 43 | ![修复完成](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/MUSIC/OK.jpg "修复完成") 44 | 45 | # 心得: 46 | 47 | 凡事都要细心,不能毛糙,要及时比对啊!!! 48 | 49 | - - - 50 | -------------------------------------------------------------------------------- /source/_posts/一次“修”冰箱的经历.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 一次“修”冰箱的经历 3 | author: CYF 4 | tags: 5 | - 冰箱 6 | - 动手实践 7 | - 修理 8 | - 电器 9 | categories: 10 | - 随心记 11 | index_img: 'https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-127.jpg' 12 | banner_img: 'https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-127.jpg' 13 | abbrlink: 75fc481 14 | date: 2020-03-26 08:01:00 15 | --- 16 | 奶奶家有一台2年前买到的美的智能冰箱,当时买过来时因为在清仓,花了800块。后来出了点小问题停用了,闲置了1年。今年疫情,我只能窝在奶奶家,这个孙子又特别能吃,所以只能重新启用了这台冰箱. 17 | 18 | 但是开始用的时候就出了点问题,不知道是不是放久了,冰箱两个按键短路了. 19 | 20 | 短路也就罢了,关键是这冰箱有安全锁,10秒钟不操作就锁住了,如果在锁住的时候试图操纵,冰箱蜂鸣器就会B\~\~\~\~\~一声,锁键就会闪烁表示不允许操作; 21 | 22 | 结果现在这台冰箱变成电音演奏者了,短路短的很有节奏;而且最重要的是这安全锁没办法彻底禁用.... 23 | 24 | 最重要的是这蜂鸣器非常响亮,冰箱在一楼,我在三楼睡觉都能听的清清楚楚. 25 | 26 | 而且家里必须要用这台冰箱,不用不行。 27 | 28 | 以前上去扇两巴掌就安静了,最近变了,怎么扇都没用了。欸,好生生的智能冰箱变成智障冰箱了。这设计者是怎么想的。 . 29 | 30 | 最致命的是如果修就要回厂重修,费用200元,那还不如不修呢 31 | 32 | 33 | 至于为什么解决是因为这货不识像,在晚上吃饭的时候在我耳边响.,怎么响我也就忍了,在我耳边响,不好意思,我上去用力一扣,把整个面板扣了下来.后面有一束线连着,仔细一看是可插拔的,使劲一拔: 34 | 35 | 36 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-127.jpg) 37 | 38 | 欸,整个世界都安静了。 39 | 40 | 安心吃完饭,我拿着面板上楼了,现在必须要修理一下,否则没面板这个冰箱是不能运行的。 41 | 42 | # 思考 43 | 44 | 我思考了一下,为什么它会发出恼人的声音呢? 45 | 46 | 47 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-131.png) 48 | 49 | 简单思考一下,解决短路我觉得是不可能的,把安全锁彻底解除也没有办法, 50 | 51 | 一、我没有螺丝刀 52 | 二、短路具体在哪我也不知道 53 | 三、解锁键没有短路,安全锁不可能解除,所以不会乱调温 54 | 四、这台冰箱没有解锁的需求 55 | 56 | 所以最经济最治标不治本的方法就是把蜂鸣器破坏掉。 57 | 58 | # 观察 59 | 60 | 背面: 61 | 62 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-128.jpg) 63 | 64 | 侧面: 65 | 66 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-129.jpg) 67 | 68 | 这是六针接口,待会儿从这里重新插进去。 69 | 70 | 71 | 72 | 观察了一下,很快就确定了蜂鸣器的位置: 73 | 74 | 75 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-130.jpg) 76 | 77 | (虚化没做好,请见谅) 78 | 79 | 以前拆过计算器,发出声音的就是这个玩意。 80 | 81 | 拿了把剪刀,伸进去,夹住,弄两下就下来了: 82 | 83 | 84 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-132.jpg) 85 | 86 | 这是蜂鸣器的三张特写: 87 | 88 | 89 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-133.jpg) 90 | 91 | 92 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-134.jpg) 93 | 94 | 蜂鸣器设计者还是用心的,起码标注了正极在哪: 95 | 96 | 97 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-135.jpg) 98 | 99 | 搞定,下去重新插上去,接着不管怎么闪烁、怎么按,它都不会响啦! 100 | -------------------------------------------------------------------------------- /source/_posts/一次愉快的更换域名经历.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 一次愉快的更换域名经历 3 | author: CYF 4 | tags: 5 | - 域名 6 | - 更换 7 | - 迁址 8 | - 公告 9 | copyright: true 10 | categories: 11 | - 爱折腾 12 | index_img: 'https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-33.png' 13 | banner_img: 'https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-33.png' 14 | abbrlink: 992fe77 15 | date: 2020-03-17 11:26:00 16 | --- 17 | 五天前买了白菜价cyfan.top,由于没有实名被ServerHold了,从昨天回了趟老家,顺便拿回了我的身份证,早上八点开始了实名认证的经历。 18 | 19 | 现在,全站从 `cyfan.ga` 永久迁址到 `cyfan.top`。 20 | 21 | 所花的时间:从早上8点到现在11点,只用了3小时。 22 | 23 | 这已经很快了好吧... 24 | 25 | 26 | 27 | 28 | 29 | # 实名: 30 | 31 | 由于事先为了方便提交,我很早就下好了阿里云手机端。 32 | 33 | 拿到身份证,点击阿里云,分别实名认证账号、信息模板、域名账号。 34 | 35 | 接着,我看了一下说明,实名认证大约要3-5天。 36 | 37 | 好吧╮(╯-╰)╭,这工单处理速度真的是。 38 | 39 | 结果刚发完牢骚,手机信息就给我发进来,说信息模板实名认证成功。 40 | 41 | . 42 | .. 43 | ... 44 | .... 45 | 46 | 这就是你说的3天?是不是你的时间跟我不太一样啊,这工单的处理速度真的是...还好未成年可以实名... 47 | 48 | 不出3分钟,当我正在实名认证支付宝(对,我的支付宝还没有实名认证),连续两条信息发过来,分别是账号和域名实名成功... 49 | 50 | 说实话,这速度真的是大大超乎我的预料,这里真心赞扬阿里云工单的处理速度!给个赞! 51 | 52 | 接着等待Whois上ServerHold消失,等待了15分钟,终于!: 53 | 54 | 55 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-42.png) 56 | 57 | # 更换NS 58 | 59 | 由于习惯了CF的简洁控制台、良心的附加服务、高效的更新和较快的速度,我还是迁回了CF: 60 | 61 | 更换NameServer: 62 | 63 | 64 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-43.png) 65 | 66 | 回到CloudFlare上,删除重新添加,结果卡在了这么哭笑不得的步骤: 67 | 68 | 69 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-44.png) 70 | 71 | NS你让我怎么改??? 72 | 73 | 好吧,估计是ServerHold缓存没有搞回来,预计24小时... 74 | 75 | 于是手贱在CF论坛上发了一篇求助: 76 | 77 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-46.png) 78 | 79 | 但!问!题!是!当我发出这篇求助后3秒不到,我的邮箱里就接到一篇来自CF的邮件,显示域名托管成功: 80 | 81 | 82 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-47.png) 83 | 84 | 当时我脸都黑了,你这个托管时间有点及时啊,为什么偏偏在我发出求助后... 85 | 86 | 欸不管了,开工! 87 | 88 | # 更替域名 89 | 90 | 期间的痛苦我觉得没必要在这里重新复述一遍了,也就是一个一个删除,一个一个增加,Github飞快的解绑加绑,CloudFlare修改Workers,这也没得抱怨,欸,起码比上次更换Hexo环境轻松多了. 91 | 92 | 很快,所有替换都完毕了,接下来要处理第三方服务了. 93 | 94 | # 第三方服务 95 | 96 | ## Google Adsense 97 | 98 | 说实话广告收入本来就是附加的,到现在只赚了0.24$,折合人民币一块五毛,正好抵得上2个月的域名费用。。。 99 | 100 | 添加域名,添加代码,提示人工审核要2星期,欸,经历以前的添加广告的经历,我觉得可能不止,算了,添加都添加了,还能怎样...估计两个星期我都要上学去了.. 101 | 102 | ## Gitalk 103 | 104 | 由于换了域名,回源地址要改一下,这里也就不展开说了 105 | 106 | ## Google Search 107 | 108 | 之前仅仅只是在谷歌上提交了搜索,也不知道怎么搞得,百度必应DuckDuckGo上都有了(也不是什么坏事),不过主要来源是谷歌,而且只是在谷歌上搞. 109 | 110 | 谷歌还是比较贴心的,多了一个快速迁移,只要是更换域名就都可以使用: 111 | 112 | 113 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-48.png) 114 | 115 | 116 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-49.png) 117 | 118 | 119 | PS:使用时需要添加301永久重定向,CloudFlare上可以快速设置PageRule达到,不过Free最多设置三个...(资本主义大佬) 120 | 121 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-51.png "你这个有点小贵啊") 122 | 123 | 由于 `.ga` 这个域名还有4个月,我还有其他用途,总不可能泛域名301吧,所以也就添加了两个原先在谷歌上有较多记录的两个. 124 | 125 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-50.png) 126 | 127 | ## QQ企业邮箱 128 | 129 | eeeeeeeem,我自己是删除了原先的账号重新添加,当然这是最简单的法子,因为这个账号里真的没什么可以用的. 130 | 131 | # 个人API类 132 | 133 | 这个真的很蛋疼,因为我自己都忘记了到底添加了多少个api,只能依靠Github自带功能搜索 `cyfan.ga` 手动替换,对于一些多的api就直接下载,靠Notepad++的批量替换功能解决,比如Bing美图一替换就有40个,这个做起来还是可以的. 134 | 135 | # 源站跳转 136 | 137 | 由于本人比较活泼,在各个站点都有留下足迹,别人点击就可以进入我的博客. 138 | 139 | 但是全部301跳转是不可能的,所以干脆加了个CFWorker+GithubPages+JS跳转,重写了一下UI,访问原先站点就通通跳向 `cyfan.top` 140 | 141 | # 安定下来了 142 | 143 | 话说为什么要花大钱(9¥)买个 `.top` 域名,纯粹是想安定下来好好写博客, `.ga` 毕竟是免费1年域名,测试开发还行,想永久下去真的很难了,而且最主要的是Freenom最近一直关闭注册,一直换域名就很难让别人能关注到你写的东西.. 144 | 145 | 阿里云是真的便宜, `.top`首年只要 `9¥`,可以随时续费,接下来每年都只要续费 `26¥`,对于我这种学生党而言,过年的时候支付宝攒个26块还是有的. 146 | 147 | 148 | 说实话搭建这个站点的费用真的不高,每年花费点鼠标钱(一个鼠标30块)就可以永久维护下去 149 | 150 | 151 | + 静态托管:Github (Coding托管些大文件): **0.00¥/year** 152 | + 动态托管:Heroku(600hours/m) **0.00¥/year** 153 | + 域名: `.top` 白菜价 **26.00¥/year** 154 | + CDN:CloudFlare,国内外还行的速度(当然不指望在特殊时期还能保持较高的速度) **0.00¥/year** 155 | 156 | 另外Adsense提供了微薄的收入...(0.24$/year) 157 | 158 | 折算下来折腾这个站点真的很值得了,花那么一点小钱就可以在互联网一个角落里打理一片属于自己的天地,这真的很让人兴奋. 159 | 160 | 加个域名的好处就是可以随便加友链啦,hiahiahia○( ^皿^)っHiahiahia… 161 | 162 | 顺便测试了一下全国访问情况: 163 | 164 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-45.png) 165 | 166 | 还行,那就这么办吧! 167 | -------------------------------------------------------------------------------- /source/_posts/国内加快NPM下载速度.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 国内加快NPM下载速度 3 | tags: 4 | - NPM 5 | - 奇淫巧技 6 | - Node.js 7 | categories: 好方法 8 | copyright: true 9 | abbrlink: eb4a371e 10 | date: 2019-07-19 12:25:27 11 | --- 12 | # 前言 13 | 大家都知道,在国内下载Github上文件是什么情景。 14 | 对<(^-^)>,就是那个8kb/s的结果! 15 | 这是因为`不为人知的秘密`所造成的。 16 | 同样,在NPM下载中也是很痛苦的。 17 | 以下载cnpm为例: 18 | 在命令提示符中键入`npm install -g cnpm`,结果可能是这样: 19 | ``` 20 | C:\Users\CYF>npm install -g cnpm 21 | [...................]fetchMetadata: sill resolveWithNewModule cnpm@6.1.0 checking installable status 22 | ``` 23 | 24 | 就这样卡半天。 25 | 5分钟后: 26 | 27 | ``` 28 | C:\Users\CYF\AppData\Roaming\npm\cnpm -> C:\Users\CYF\AppData\Roaming\npm\node_modules\cnpm\bin\cnpm 29 | + cnpm@6.1.0 30 | added 691 packages from 924 contributors in 308.39s 31 | ``` 32 | 308.39秒啊啊啊啊啊,这到底卡了多久啊! 33 | # 如何解决? 34 | ## 方法一: 35 | 在每行npm后加上[npm淘宝镜像](registry.npm.taobao.org)(不是那个淘宝),加上`--registry=https://registry.npm.taobao.org`. 36 | 如`npm install -g cnpm`变成`npm install -g cnpm --registry=https://registry.npm.taobao.org` 37 | 那样能快很多。先卸载cnpm: 38 | ``` 39 | npm uninstall cnpm 40 | ``` 41 | 会得到: 42 | ``` 43 | npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.9 (node_modules\fsevents): 44 | npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.9: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"}) 45 | audited 9067 packages in 26.562s 46 | found 0 vulnerabilities 47 | ``` 48 | 呃呃呃,卸载还比安装快. 49 | 再安装: 50 | ``` 51 | C:\Users\CYF\AppData\Roaming\npm\cnpm -> C:\Users\CYF\AppData\Roaming\npm\node_modules\cnpm\bin\cnpm 52 | + cnpm@6.1.0 53 | added 691 packages from 924 contributors in 97.818s 54 | ``` 55 | ## 方法二: 56 | 直接使用`cnpm`代替`npm`. 57 | 如`npm install -g cnpm`变成`cnpm install -g cnpm` 58 | 原理与方法一相同,不再阐述。 59 | 60 | ## 方法三: 61 | 可以用全局代理软件如`Proxifier`给`npm`挂代理,使他绕过`不为人知的秘密`,加快下载速度. 62 | 但不建议,因为这种方法麻烦,用方法一二完全可以代替. 63 | 64 | # F&Q: 65 | ## Q:镜像站是什么? 66 | ## F:所谓镜像站,就是把你现有的网站放在另外一个地方的服务器上,当然,这个服务器既可是你购置而托管的,又可是虚拟的服务器。如果你把网页放在两个以上不同国家或地区的服务器上,那就说明你已为你的网站建立了多重镜像站,这样可以加快你的网站的访问速度,称之为“多重镜像站”。镜像站就跟镜子一样。一般是个人网站的站长为自己的站做一个备份,也就是说,一个站由于流量或其它原因访问不到时,人们可以去另一个一模一样的站看。这个站还可以起到分流,减少服务器压力的作用。不过,这些都是由于个人网站的服务器不能接受太多的访问量而采取的办法。商业网站一般不用这样的办法。因为用户要记两个域名,内容要上传两次,要随时保持两个地方一致,内容一多非常麻烦。而淘宝npm的服务器构建在国内,加快了访问速度。(部分摘自百度百科:镜像站) 67 | 68 | ## Q:如果镜像站上没有npm的文件,怎么办? 69 | ## F:从 registry.npm.taobao.org 安装所有模块. 当安装的时候发现安装的模块还没有同步过来, 淘宝 NPM 会自动在后台进行同步, 并且会让你从官方 NPM registry.npmjs.org 进行安装. 下次你再安装这个模块的时候, 就会直接从 淘宝 NPM 安装了. 70 | 71 | - - - 72 | 73 | -------------------------------------------------------------------------------- /source/_posts/如何在中国以免【爬城】的体位下使用Google的reCAPTCHA.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 如何在中国以免【爬城】的体位下使用Google的reCAPTCHA 3 | tags: 4 | - 善用技术上网 5 | - Google 6 | - 人机验证 7 | - 奇淫巧技 8 | - Tampermonkey 9 | - JavaScript 10 | categories: 好方法 11 | copyright: true 12 | abbrlink: 67db86ca 13 | date: 2019-07-29 15:11:19 14 | --- 15 | # 前言: 16 | 在中国,每每用到[clipconverter](https://www.clipconverter.cc)时下载youtube上的视频,reCAPTCHA一直没有加载出来. 17 | 后来意识到Google的人机验证好像在中国**不能用**. 18 | ...... 19 | 这是就进入`前有狼后又虎的尴尬状态了`,,ԾㅂԾ,,. 20 | 不代理,人机验证加载不出来,挂代理,50Mbps的代理速度估计是要把我活生生等死. 21 | ## 为什么在中国不能用?????? 22 | 自2014年5月27日后,Google 公司的各项服务遭到疑似来自`不可告人的秘密`的~~善~~意干扰,导致中国大陆地区的用户无法正常使用其服务的事件。自当天起,来自中国大陆的用户发现 Google 旗下的各个分站以及 Google 的其他服务(Google 搜索、Google Play、Gmail 等)均无法正常访问与使用,所有 google.cn 以外的 Google 服务均受影响无法使用,用户甚至无法登陆 Google 账户。然而,不同于 2009 年至 2013 年仅针对敏感时期的行为规律,XX运动纪念日结束后攻击者对 Google 的~~善意~~打扰仍未停止。——维基百科 23 | 而 reCaptcha 人机验证就是 Google 的服务之一。所以,reCaptcha 也没能逃过这次封锁,才导致国内 reCaptcha 验证码无法显示。 24 | 25 | > **现在打个岔** 26 | > 本文图片较少,故接下来要强制添加图片: 27 | > ![强制有图](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/QZYT.png "强制有图") 28 | > 哈哈哈哈哈哈哈哈(●'◡'●)开玩笑. 29 | 30 | ## reCaptcha有哪些,有什么用? 31 | reCaptcha有三个版本V1、V2、V3,通常现在使用的是v2. 32 | 这些往往在原网站上的去,又用上recaptcha的网站,比如谷歌镜像之类的。 33 | 34 | # 试图解决: 35 | ## 直接绕开: 36 | 既然你不让我用,那我就不用了.(¬︿̫̿¬☆) 37 | 打开`开发者工具`找到js脚本,指向空白. 38 | 当然这样行不通了. 39 | ## ATP 40 | ~~就是[Ass-To-Pussy](https://baike.baidu.com/item/atp/10948513?fr=aladdin)~~ 41 | w(゚Д゚)w我在说什么????千万不要点链接啊啊啊! 42 | 呸呸呸,就是指在爬出去的情况下通过人机验证,再回来下载. 43 | 而这也很快被防盗链挡住了. 44 | emmmmmmm...... 45 | 46 | # 后来解决: 47 | 其实大家都没想到,reCaptcha在国内还是有镜像的. 48 | 网址是:,很简单暴力的域名. 49 | 甚至连维基中文都认为镜像网址挂了。因为你直接打开,恭喜,你会收获这个 50 | 51 | Not Found 52 | Error 404 53 | 54 | 于是就孪生了两种方法: 55 | ## 小白解法: 56 | Tampermonkey脚本:(感谢原作者an_anthony的贡献!) 57 | ```Javascript 58 | // ==UserScript== 59 | // @namespace xyz.tree0 60 | // @name reCaptcha 验证码镜像加载 61 | // @description 替换使用官方地址的 reCaptcha 为官方镜像地址,让墙内用户的 reCaptch 能正常显示。 62 | // @description 似乎只能用于 reCaptcha v2 63 | // @author an_anthony 64 | // @version 0.1.2 65 | // @grant none 66 | // @match *://*/* 67 | // ==/UserScript== 68 | 69 | var scrArr = document.getElementsByTagName("script"); 70 | for(var k = 0;k < scrArr.length;++k) 71 | { 72 | if(scrArr[k].src !== null && scrArr[k].src.indexOf("https://www.google.com/recaptcha/api.js") != -1){ 73 | var scrAppend = document.createElement("script"); 74 | scrAppend.src = scrArr[k].src.replace("google.com","recaptcha.net"); 75 | scrAppend.type = "text/javascript"; 76 | scrAppend.async = true; 77 | scrArr[k].parentNode.appendChild(scrAppend); 78 | scrArr[k].parentNode.removeChild(scrArr[k]); 79 | alert("已替换该页面的 reCaptcha 地址,如果还未显示出 reCaptcha Logo,请稍等(约30s)"); 80 | break; 81 | } 82 | 83 | } 84 | ``` 85 | 86 | > **Attention!** 87 | > 对那些使用了 Content-Security-Policy 属性的网站无效。Content-Security-Policy 属性会验证资源的地址,导致更换的镜像地址被阻止。如果你查看了 F12,会发现很多类似下面的错误信息: 88 | >> Refused to load the script ‘xxx’ because it violates the following Content Security Policy directive 89 | > 解决方案:请使用大神解法: 90 | 91 | ## 大神来此: 92 | 打开开发者工具,搜索`www.google.com/recaptcha/api.js` 93 | `.com`之类的以情况而定. 94 | 接着把他替换成`https://recaptcha.net/recaptcha/api.js` 95 | 等一会儿就好了. 96 | 其实这与js原理相同,但此种解法在CSP检测完成后进行,相当于绕开CSP。 97 | 98 | 完毕! 99 | 100 | - - - 101 | 102 | -------------------------------------------------------------------------------- /source/_posts/工具箱和私有云恢复!.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 工具箱和私有云恢复!顺便讨论一下免费php供应商怎么选=> 3 | author: CYF 4 | tags: 5 | - PHP 6 | - 免费 7 | - 撸羊毛 8 | - 工具箱 9 | - 私有云 10 | - 恢复 11 | copyright: true 12 | categories: 13 | - 要公告 14 | abbrlink: d72d7290 15 | date: 2020-03-13 14:07:00 16 | --- 17 | # 所有 18 | 19 | 早上折腾了3个小时,终于完美恢复了两个因为heroku宕机而失效的php网站。 20 | 21 | 现在选择的是这家免费php : [ProFreeHost](https://ProFreeHost.com) 22 | 23 | 你让我买一台服务器???对不起,做不到,没钱.不过捐个八十一百还有可能会考虑 24 | 25 | 讲讲最近跳槽的free php hosts 26 | 27 | ## 000Webhost 28 | 29 | 30 | 之前一直使用000webhost,这里给大家提个醒,千万不要用三蛋空间的东西了!!!太坑了!!!!虽然1GB硬盘10GB流量免费套餐很诱人,可完全就是个骗子! 31 | 32 | 之前在很多社交网站上都看到有人极力推荐,没广告,速度快。 33 | 34 | PS:现在变成300MB磁盘和3GB带宽了: 35 | 36 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-38.png) 37 | 38 | 可我真的登进去后才发现暗坑汹涌, 39 | 随便捡几个: 40 | 41 | + 绑定自定义域名最多**2个**,三个?对不起,请付费或左转至上司Hostinger购买~~炒鸡便宜~~的vps主机 42 | + MySQL数据库最多**2个**,三个?对不起,请付费或左转至上司Hostinger购买~~炒鸡便宜~~的vps主机 43 | + 右下角的000wenhost广告需要你的支持,不能关闭哦!要关闭?对不起,请付费或左转至上司Hostinger购买~~炒鸡便宜~~的php 44 | + 超长时间在线,保证你的网站能被别人访问!(官方介绍) 实际情况:在经历了多重人机检测、多重广告关闭,我终于在一个隐藏的很深的协议里看到了免费网站在线时间不少于95%,实际上个人检测在90%上下波动。 45 | + 对于中国服务很不友好,其中不仅仅有 `「羲农去我久」1PjT8X/2TCX3i。` 的功劳,他自己也对来自中国的ip进行了限速。 46 | + 以及隐私政策里写的很隐蔽的 ·我们可以在特殊情况下掌握您账户的控制权 · 47 | + ... 48 | 49 | 50 | 以至于首页极其搞笑的计数器: 51 | 52 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/7.gif "中间短暂的空白是刷新") 53 | 54 | 当时我注册了两个账号,一个拿来搭建网站,另一个搭建 `「故人重分携,临流驻归驾」1lDFXf/1wDWhT。` 个人使用,结果没用几天搭建的 `「故人重分携,临流驻归驾」1lDFXf/1wDWhT。` 直接给我Block了,点进去说是第三方服务举报,说我违反了使用条约,就把整个账户禁用了,而且恢复还要提交个人身份证明。 55 | 56 | 57 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-37.png) 58 | 59 | ????????? 60 | 61 | 见了鬼了,我就想问一下,搭个个人镜像哪来的第三方?流量没走到20MB,使用不超过5天,根本没有理由就把我禁止了,什么玩意? 62 | 63 | 更令人难受的是没过一星期,把我的工具箱和私有云也给禁用了,也是同样的第三方举报,也是违反使用条约,也是整个账户禁用。 64 | 65 | 我就服了,直接说不干不行吗,为什么p话怎么多??? 66 | 67 | 随便一找就在百度上找到难兄难弟: 68 | 69 | 70 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-36.png "emmmmm...") 71 | 72 | 幸好我的所有网站资料一直有一份备份在本地,不然整个网站没了我就要疯了。 73 | 74 | 幸好我博客没有使用动态,要是连窝颠了那不就完蛋了。 75 | 76 | 况且对于000webhost种种限制我真的没办法忍受,于是我就出坑了. 77 | 78 | ## heroku 79 | 80 | 这个其实我很早就开用了. 81 | 82 | 这个还是比较良心的,免费没验证的用户最多五个应用,经过信用卡验证的最多20个,支持php\nodejs\ruby\python主流网页应用. 83 | 84 | 据这个nodejs可以搭建代理,php可以搭建 `「故人重分携,临流驻归驾」1lDFXf/1wDWhT。`,结果Youtube上涌现出一堆 `「遥夜亭皋闲信步,乍过清明,早觉伤春暮。数点雨声风约住,朦胧淡月云来去」qzNyk/2xYh2k。` 、 `「去郭轩楹敞,无村眺望赊。澄江平少岸,幽树晩多花。细雨鱼儿出,微风燕子斜。城中十万戸」3tdLut/3nY4xB。`等等撸羊毛技巧。不过啊,同学们,撸羊毛也要有限度啊,把羊撸死了还撸什么羊毛啊!!,现在Heroku国内下载已经严重限速到15kb/s,部分情况下直接阻断。不过这个问题可以通过CFWorkers解决。 85 | 86 | 上传方式有点少,一般用Git方式或直接绑定github. 87 | 88 | 当然也有几条有点坑的问题 89 | 90 | - 每月600hours运行,添加银行卡验证再加400hours(实际上600hours够用了,平均每天能运行20小时) 91 | - 未绑定银行卡不能使用CNAME绑定域名;这个比较坑,如果只是搭建网站还能用CFWorkers。 92 | - 以及半小时没人访问休眠,有人访问会自动唤醒,但大概要5秒。 93 | 94 | 之前就一直使用这种方案,感觉运行的还行,不过前几个月不知道为什么只要是php运行就会报错,现在好了,不过已经换了就懒得还回来了。 95 | 96 | ## ProFreeHost 97 | 98 | 99 | 这家是今年新开的,不过广告没做的很响,也没多少人推荐。 100 | 101 | 似乎可以无限注册,每注册一个就会给一个独立ip,但是不是固定的暂时不知道 102 | 103 | 支持NS绑定域名(不过获取到独立IP后可以用A记录绑定) 104 | 105 | 不过独立ip全部都被 `墙` 了,只能用CFCDN复活。 106 | 107 | 只是无法添加SSL证书很蛋疼,那个添加SSL的cPanel界面死活进不去,害的我不得不把CloudFlare改成链接到源服务器不加密,折腾了将近一小时。 108 | 109 | 上传方式和000webhost一样,支持网页上传和FTP上传,只能说还行。 110 | 111 | cpannel界面烂的一撇,不过至少还能用,就先凑合吧。 112 | 113 | 隐私政策说的很清楚,不会莫名其妙禁用账户,不过实际效果还需要检验。 114 | 115 | 欸,目前看来这个先凑合着用吧。 116 | 117 | 不过还行的是,支持php修改文件,也就是说我的EncodeExplorer也支持上传,在国内免翻也能上传文件,这个还行。 118 | 119 | 120 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-39.png) 121 | 122 | ~~游客账号:admin 123 | 密码: admin 124 | 游客账号只能浏览,不能能添加上传删除。~~ 125 | 126 | 127 | 128 | # 结尾 129 | 130 | 欸,现在也只能走一步看一步了,`.top` 域名这事搞得我浑身难受,至少今天把php服务搞定了,也行,每天都有小突破. 131 | 132 | - - - 133 | 华丽丽的分割线 134 | - - - 135 | 136 | 2020年3月16日添加: 137 | 138 | 真不好意思,折腾了这么多天,又把数据全部迁回Heroku了。 139 | 140 | 欸,ProFreeHost其实有个地方相当的坑,单文件最多只能存储4M,再大就直接403了,欸,算了,就当作临时盘白嫖吧。 141 | 142 | 到最后来还是Heroku靠谱。 -------------------------------------------------------------------------------- /source/_posts/巧妙去除百度首页广告.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 巧妙去除百度首页广告 3 | tags: 4 | - 奇淫巧技 5 | - 百度 6 | - 广告 7 | categories: 好方法 8 | copyright: true 9 | abbrlink: c226bfa5 10 | date: 2019-07-17 12:37:02 11 | --- 12 | # 前言: 13 | 百度首页有~新闻~广告,虽然声称新闻,实际上就是你会发现其中有大量广告。 14 | 好吧好吧,如果你一直坚定认为它是新闻,我也没办法。 15 | 下面说说如何去除 16 | ## 去除前: 17 | 这是你输入[https://baidu.com](https://baidu.com)时的场景: 18 | ![百度首页广告](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/BAIDUADS.jpg "去除前") 19 | ## 做法: 20 | 在baidu.com 后跟上```/?tn=simple```,变成[https://baidu.com?tn=simple](https://baidu.com/?tn=simple) 21 | ![百度首页广告](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/BAIDUNOADS.jpg "去除后") 22 | ### 搞定! 23 | - - - 24 | -------------------------------------------------------------------------------- /source/_posts/来,破解版的Google访问助手.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 来,破解版的Google访问助手 3 | tags: 4 | - 插件 5 | - Google 6 | - 破解 7 | - Chrome 8 | categories: 丆插件 9 | copyright: true 10 | abbrlink: 2b9edbbb 11 | date: 2019-09-14 13:14:46 12 | --- 13 | # 前言: 14 | 15 | 已失效! 16 | 17 | 18 | (迟到的祝福)o( ̄┰ ̄*)ゞ 19 | 20 | 好吧好吧,那就给份中秋礼物吧! 21 | 22 | 在中国,访问Google是最蛋疼的事了,原因是显然易见的。 23 | 24 | 可是作为一个雪深+三流程序猿,上Google是相当重要的。 25 | 26 | 基本上自己都是白嫖我同学康哥的ss,白嫖总是麻烦,还要用ss客户端。 27 | 28 | 网上的谷歌访问助手,现在官网都挂了,虽然能用,但是让我强制改主页确实不爽,而且图标也死丑,看着恶心。 29 | 30 | 于是看看如何破解。 31 | 32 | # Going: 33 | 34 | 既然它会检测有没有广告,那我干脆直接在所有页面上都加上被隐藏的广告链接,这样既不会视觉干扰,又可以破解。 35 | 36 | 然后我高高兴兴的在Github上搜索原版源代码,结果发现...好像...有人已经破解了 37 | 38 | ![图片](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/GOG.png "好尴尬啊") 39 | 40 | 那我一不做,二不休,直接就用这个吧! 41 | 42 | 不过这位老兄的图标似乎没改,那我就改了一下,以下是我改动的: 43 | 44 | - [X] 去除Google+(今年四月Google把它关了) 45 | - [X] 添加Google Earth(亲测速度爆表,酸爽!) 46 | - [X] 更换Google全家古老的图标,换成新的。 47 | - [X] 更换插件图标,换了个Google Studio的(加了个小星星和滤镜) 48 | - [X] 厚颜无耻的加上了自己的名字. 49 | 50 | ![图片](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/GGFWZS.png "一阵酸爽") 51 | 52 | 然而上Google是爽,加载速度极快: 53 | 54 | ![图片](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/GHS.bmp "速度不错") 55 | 56 | 1.1MB的网页在2.1秒内打开,和百度打开速度相比: 57 | 58 | ![图片](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/BHS.bmp "相差不多") 59 | 60 | 1.4秒内打开也挺小,只有0.7s的相差,也是不多,完全可以用Google当引擎啦! 61 | 62 | 然而缺点也很多,学术研究完全不能上,Youtube不支持,wikipedia也不行. 63 | 64 | 对于维基百科,完全可以用Google翻译当跳板曲线救国. 65 | 66 | 总之,能乐和几天十几天!(≧∀≦)ゞ 67 | 68 | 69 | >>CYF的私有云 70 | 71 | 72 | 特征码:`glabchgbmippkhlcjkcmdmclmapehoha` 73 | -------------------------------------------------------------------------------- /source/_posts/白菜价域名的问题.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 白菜价域名的问题 3 | author: CYF 4 | tags: 5 | - 域名 6 | - 便宜 7 | copyright: true 8 | categories: 9 | - 随心记 10 | abbrlink: 2698fd57 11 | date: 2020-03-12 09:47:00 12 | --- 13 | 14 | ................................................... 15 | # 没有开头的开头 16 | 17 | 今天2020年3月12日早上去万网,发现`.top`域名首年只要9块钱. 18 | 19 | 真的只要9块钱,而且下一年续费也炒鸡便宜,只要26元,这点小钱还是付的起的. 20 | 21 | 22 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-21.png) 23 | 24 | 因为自己的.ga域名毕竟是免费域名,拿出去没牌面.Freenom半死不活,现在又不能重新购买白嫖撸羊毛,反正9元也不贵,买就买吧,就把.top换成永久站点名字也行. 25 | 26 | 然后手贱,一步一步点下去,支付宝一扫,就在那指纹按下去的一瞬间,我突然意识到一件事情,不用实名认证吗? 27 | 28 | 结果低头一看,支付成功. 29 | 30 | emmmmmm...既然买了,那就看看吧. 31 | 32 | 点进去,默认的NS是阿里云,用这个很容易被ServerHold,而且不能用CFCDN. 33 | 34 | 国内备案你就让我别想了,你让我手持身份证拍照很抱歉我做不到,况且我服务器本来就是白嫖Github+CF高速香港CDN不在国内,也不需要备案. 35 | 36 | 于是我就换成了CoudFlare的NameServer: 37 | 38 | 39 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-22.png) 40 | 41 | 结果CloudFlare死活不肯接受: 42 | 43 | 44 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-23.png) 45 | 46 | 但是Whois已经确认绑定完成了. 47 | 48 | 49 | ... 50 | 51 | 我当时就无语了,NS解析已经删除了,人家whois也说可以了,怎么就你不行呢? 52 | 53 | 放ICANN Lookup上查: 54 | 55 | 56 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-24.png) 57 | 58 | 怎么就被serverHold了???????还有注册姓名全部是空的为什么???? 59 | 60 | 前往ICANN帮助文档: 61 | 62 | 63 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-26.png) 64 | 65 | 66 | ``` 67 | If you provided delegation information (name servers), this status may indicate an issue with your domain that needs resolution. If so, you should contact your registrar to request more information. If your domain does not have any issues, but you need it to resolve in the DNS, you must first contact your registrar in order to provide the necessary delegation information. 68 | ``` 69 | 70 | 至少以我现在的英语水平,还是能勉强读懂的,大意就是注册商没有给予完整的注册人信息; 71 | 72 | 可是我在万网填的东西比当时Freenom填的东西还要多,怎么就没完整呢??? 73 | 74 | 回到万网,我找了找帮助文档: 75 | 76 | 77 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-25.png) 78 | 79 | 80 | 81 | ![upload successful](https://npm.elemecdn.com/chenyfan-oss@1.0.0/pic/post/pasted-27.png) 82 | 83 | 行了行了,到这一步我也明白了,简单的说不给实名认证就故意不填写完整,故意Serverhold,目的就是要实名认证. 84 | 85 | 可是,问题是我身份证落在老家,现在疫情这么严重,你让我怎么回去拿???? 86 | 87 | (而且问题是我还是个学生,未成年...) 88 | 89 | # 后记 90 | 91 | 后来想一想,万网域名白菜价肯定是有它的原因的,毕竟不拿点用户隐私资料,不应付工信部压力,这饭真的没法恰了. 92 | 93 | 欸,算了, `.top` 买来也不算贵,而且 `cyfan.ga` 还有5个月余额,先吊这吧,有空再换站点. 94 | 95 | 说实话当时建立这个博客纯粹是试水,纯粹测试一下有没有写博客的毅力,大家看看我以前的博文就知道了,基本都是直接搬运的,这也是为什么用免费域名的原因,考试考完了仔细思考了一下,发现自己创作博文更加有趣,结果最近就入水了... 96 | 97 | 白菜价域名确实便宜,Godaddy上最经济的续费价格域名应该是`.de`,大概每年56RMB,其它的大都首年便宜,续费就令人望而止步了. 98 | 99 | 欸,还能说什么呢,既然买了,就更应该好好写. -------------------------------------------------------------------------------- /source/blog-cgi.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 用户端面板 3 | banner_img: 'https://npm.elemecdn.com/chenyfan-os@0.0.0-r6' 4 | --- 5 | 6 |

7 | 8 | -------------------------------------------------------------------------------- /source/categories/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 分类 3 | type: categories 4 | layout: categories 5 | comments: false 6 | --- 7 | -------------------------------------------------------------------------------- /source/com/index.md: -------------------------------------------------------------------------------- 1 | title: 留言板 2 | comments: true 3 | hide: true 4 | index_img: 'https://npm.elemecdn.com/chenyfan-cdn@2.0.0/img/back/2k.jpg' 5 | banner_img: 'https://npm.elemecdn.com/chenyfan-cdn@2.0.0/img/back/2k.jpg' 6 | date: 1949-10-01 23:59:59 7 | update: 2020-02-27 08:48:09 8 | --- 9 | 有什么要说的可以写在这里 10 | 如果你想说悄悄话,发邮件到 11 | # 留言须知: 12 | 13 | 1. ~~来比力服务器部署于韩国,可能无法加载或长时间空白。在无法加载情况下请刷新,在空白情况下请耐心等待。如果手机SNS登陆方式被遮挡,请横屏选择登陆方式!~~ ~~加载太TM慢了!!!!换作Valine吧!评论时要注明自己的邮箱,头像会来自[Gravatar](http://cn.gravatar.com),同时你也会收到邮件通知。一定要正确! 蛋疼的是LeanCloud出了点小问题,于是跳槽到Gitalk了.使用Gitalk需要Github账号,而且很有可能需要梯子!国内对于Github相当不友好,很有可能加载不出来或者是网络错误! ~~ Valine,我最终还是选择了你【吐血】 14 | 2. 拒绝包括但不限于色情、反动、低俗发言,拒绝抹黑当局的言论。 15 | 3. 拒绝无意义的言语,相信我,你打字要6秒,我删除只要1秒! 16 | 4. 拒绝机器人、小学生、广告主!务必使用**正确的邮箱**,故意不正确使用将会被直接拉黑1-3650天 17 | 5. 我们现在不想,未来也不支持QQ头像的获取,为了保证前端用户隐私的安全【包括ip、邮箱、UserAgent】,这些数据在前端均被加密或没有传递到前端,除了博主,其他任何人都无法获取到你的隐私记录。 18 | 19 | 20 | 21 | 22 | 6. 关于友链 23 | 24 | + 0.首先确保有本站的友情链接: 25 | 26 | 27 | ``` 28 | 标题: 陈YF的博客 29 | 地址: https://blog.cyfan.top 30 | 图像(如果有): https://npm.elemecdn.com/chenyfan-oss@3 31 | 简介(如果有): 一个在互联网角落挣扎的小小博客,很小很小 32 | 屏幕截图(如果有): https://api.cyfan.top/thumb?url=https://blog.cyfan.top 33 | 背景颜色(如果有): #F6B352 34 | ``` 35 | 36 | + 1.存活时间不小于**3个月**。 37 | 38 | + 2.确定不会随随便便删库跑路。 39 | 40 | + 3.时间达到30天无法正常访问的将会被踢除。 41 | 42 | + 4.免费顶级域名看情况接受,二级域名(如\*.cyfan.top)则需验证主域名所有权,验证方式(设置顶级域名的TXT记录为二级记录的SHA256值,如我的顶级域名是 `cyfan.top`,我的二级域名是 `blog.cyfan.top`,则txt记录为: `cyfan.top 0370E381DE878A0799F3B72600C2805AC4BCEA76AA0A6539812F77361E696353` ,【大小写不严格】,这说明对于 \*.github.io 和 \*.coding.me 这种公有域名给予拒绝) 43 | 44 | + 5.确保站点可以以HTTPS访问,允许不强制,可以没有HSTS(为什么要https原因很显然,这里不阐述) 。当然有例外,如果是我恳求加友链的https可以作为不是特别重要的原因。 45 | 46 | + 6.确保站点内容不违反中国大陆法律. 47 | 48 | + 7.拥有尽可能多的原创内容,越多优先级越高。 49 | 50 | + 8.如果因特殊原因而更换地址,请~~留言或~~PR。 51 | 52 | + 9.1 53 | > **我们拒绝了留言的方式添加友链,任何以留言形式添加友链都将被我们拒绝,请采用PR形式添加友链** 54 | 55 | + 9.2另一种添加方式:Pull Request: 56 | 57 | + 9.2.1 进入[存储Blog的Repo](https://github.com/ChenYFan/blog), ~~Fork~~(新版本的Github已经自动完成了,无需手动Fork),直接修改(主题配置文件) 在倒数第二行按照示例规则添加友链【务必注意缩进、空格和换行】: 58 | 59 | ``` 60 | - { 61 | title: '博客名字【不得大于9字,否则会被截断】', 62 | link: '网页链接,需进行主域名认证', 63 | intro: 'Slogan【不得大于15字,否则会被截断】', 64 | image: 'icon图片链接【推荐使用jsdelivr加速链接,使用github直接做图床未经加速将受到警告】' 65 | } 66 | ``` 67 | 68 | **点击PullRequest,向本仓库发起PR。** 69 | 70 | 近期发现有些朋友fork了我的仓库但没有向我的仓库提交PullRequest,对于这些同学我只能说声抱歉,麻烦修改后重新前往本仓库看看有无新的PR,如果您连Github基本操作PR都不会的话,那麻烦还是先学习吧,学好了欢迎随时添加友链! 71 | 72 | 由于PR的特殊性,没有遵守以上任何一条条款将无条件拒绝并ClosePR。同样,为了维护公平,我们**拒绝了**留言方式添加,~~除非你和CYF是好朋友~~ 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | - - - 82 | 以下是留言区: 83 | -------------------------------------------------------------------------------- /source/img/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChenYFan/blog/3e15fc2372710483f58c22b94988424a67d8f13f/source/img/apple-touch-icon.png -------------------------------------------------------------------------------- /source/jump.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 | 5 | 6 | 7 | 8 | 跳转中 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |
17 | 18 |
19 |
20 | 21 |
22 |

Loading...

23 |

还有3s,正在准备你需要的内容...

24 |
25 |
26 |
27 |
28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /source/offline.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Oops!您离线了哦 3 | banner_img: 'https://npm.elemecdn.com/chenyfan-os@0.0.0-r6' 4 | --- 5 | 6 | # 此页面无法打开 7 | 8 | 由于网络原因,我们无法从任何一个镜像站获取到最新的博客内容。 9 | 10 | 这有可能是我们的所有主从备服务器全部炸裂,当然,更有可能的是您网络丢失,或者至少您与我们服务器之间失去了联系。 11 | 12 | 我们建议您检查您的网络连接。当然,您也可以通过[ChenBlogHelperの用户端控制面板排查问题](/blog-cgi) -------------------------------------------------------------------------------- /source/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "node-static": "^0.7.9" 4 | }, 5 | "scripts": { 6 | "start": "static . -a 0.0.0.0 -p $LEANCLOUD_APP_PORT" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /source/pic/BLOGER.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChenYFan/blog/3e15fc2372710483f58c22b94988424a67d8f13f/source/pic/BLOGER.jpg -------------------------------------------------------------------------------- /source/pic/c.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChenYFan/blog/3e15fc2372710483f58c22b94988424a67d8f13f/source/pic/c.jpg -------------------------------------------------------------------------------- /source/pic/posted/pasted-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChenYFan/blog/3e15fc2372710483f58c22b94988424a67d8f13f/source/pic/posted/pasted-0.png -------------------------------------------------------------------------------- /source/search/index.md: -------------------------------------------------------------------------------- 1 | title: search 2 | date: 2014-12-22 12:39:04 3 | type: "search" 4 | --- -------------------------------------------------------------------------------- /source/tags/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 标签 3 | type: tags 4 | comments: false 5 | --- 6 | -------------------------------------------------------------------------------- /source/vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "routes": [ 4 | { "handle": "filesystem" }, 5 | { "src": "/(.*)", "status": 404, "dest": "/404.html" } 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /source/捐款吧/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 捐款吧 3 | comments: false 4 | --- 5 | 支付宝: ![Alipay](https://img.cyfan.top/pic/AP.jpg "支付宝") 6 | 或点此:[支付宝快捷支付](HTTPS://QR.ALIPAY.COM/FKX04238VDRCZQX8MCZX2E) 7 | 爱你呦! 8 | 9 | 如果你不想花钱,也可以前往[广告页](/about/ads.html), 每一次点击都能给我带来少量盈利!谢谢! 10 | 11 | (2020年1月27日:新增比特币捐款!!!!) 12 | 13 | 比特币收款地址: bc1qcf5xj54c7nk5cm7wtwek8ke5vww440ksyfma57 14 | 15 | 谢谢您的捐助! 16 | -------------------------------------------------------------------------------- /source/随口胡说/index.md: -------------------------------------------------------------------------------- 1 | title: 随口胡说 2 | date: 2020-03-19 13:21:09 3 | --- 4 | {% raw %} 5 |
6 | 7 | 24 | 25 | {% endraw %} 26 | -------------------------------------------------------------------------------- /themes/fluid/.gitattributes: -------------------------------------------------------------------------------- 1 | source/lib/* linguist-vendored 2 | -------------------------------------------------------------------------------- /themes/fluid/.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: ':bug: bug' 6 | assignees: '' 7 | --- 8 | 9 | #### Make sure 10 | - [ ] Upgrade the latest [release version](https://github.com/fluid-dev/hexo-theme-fluid/releases). 11 | - [ ] Browser does not belong to IE and other old browsers 12 | - [ ] It can be replicated through `hexo clean && hexo s` and cleared browser cache in the localhost. 13 | - [ ] Not affected by other Hexo plugins 14 | 15 | #### Describe the bug 16 | 17 | 18 | #### To Reproduce 19 | Steps to reproduce the behavior: 20 | 1. Go to '...', click on '....' 21 | 2. Scroll down to '....' 22 | 3. See error 23 | 24 | 25 | 26 | #### Screenshots 27 | 28 | -------------------------------------------------------------------------------- /themes/fluid/.github/ISSUE_TEMPLATE/bug_report_zh.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug 报告 3 | about: 创建一份 Bug 报告帮助我们优化产品 4 | title: '' 5 | labels: ':bug: bug' 6 | assignees: '' 7 | --- 8 | 9 | 10 | 11 | 12 | 13 | 14 | #### 请确认 15 | - [ ] 是当前最新的 [Release 版本](https://github.com/fluid-dev/hexo-theme-fluid/releases) 16 | - [ ] 浏览器不属于 IE 等非主流浏览器 17 | - [ ] 本地 `hexo clean && hexo s`,并且清除浏览器缓存,仍可复现 18 | - [ ] 已经排除是其他 Hexo 插件影响 19 | 20 | #### Bug 描述 21 | 22 | 23 | #### 复现步骤 24 | 该 Bug 复现步骤如下: 25 | 1. 在 xxx 页面点击 xxx 按钮 26 | 2. 然后向下滚动 27 | 3. 会出现 xxx 28 | 29 | 30 | 31 | #### 截图 32 | -------------------------------------------------------------------------------- /themes/fluid/.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: ':sparkles: enhancement' 6 | assignees: '' 7 | --- 8 | 9 | #### Make sure 10 | - [ ] Difficult to implement through [custom](https://hexo.fluid-dev.com/docs/en/guide/#custom-js-css-html). 11 | - [ ] Difficult to implement through third-party plugins. 12 | 13 | #### Is your feature request related to a problem? Please describe 14 | 15 | 16 | #### Describe the solution you'd like 17 | 18 | 19 | #### Describe alternatives you've considered 20 | 21 | -------------------------------------------------------------------------------- /themes/fluid/.github/ISSUE_TEMPLATE/feature_request_zh.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 功能需求或优化 3 | about: 创建一份合理可行的建议帮助我们提升产品 4 | title: '' 5 | labels: ':sparkles: enhancement' 6 | assignees: '' 7 | --- 8 | 9 | #### 如是功能需求,请确定符合以下情况 10 | - [ ] 难以通过[自定义](https://hexo.fluid-dev.com/docs/guide/#%E8%87%AA%E5%AE%9A%E4%B9%89-js-css-html)实现的功能 11 | - [ ] 难以通过第三方插件实现 12 | 13 | #### 请描述该需求尝试解决的问题 14 | 15 | 16 | #### 请描述您认为可行的解决方案 17 | 18 | 19 | #### 考虑过的替代方案 20 | 21 | -------------------------------------------------------------------------------- /themes/fluid/.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: Ask a question about use, need help 4 | --- 5 | 6 | #### Make sure 7 | - [ ] Upgrade the latest [release version](https://github.com/fluid-dev/hexo-theme-fluid/releases). 8 | - [ ] No solution found in [Documentation][https://hexo.fluid-dev.com/docs/en/] 9 | 10 | #### Describe the question 11 | 12 | -------------------------------------------------------------------------------- /themes/fluid/.github/ISSUE_TEMPLATE/question_zh.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 问题求助 3 | about: 提出一个使用过程中遇到的问题,需要得到帮助 4 | --- 5 | 6 | #### 请确认 7 | - [ ] 是当前最新的 [Release 版本](https://github.com/fluid-dev/hexo-theme-fluid/releases) 8 | - [ ] 在 [用户指南](https://hexo.fluid-dev.com/docs/) 中没有找到解决办法 9 | 10 | #### 问题描述 11 | 15 | -------------------------------------------------------------------------------- /themes/fluid/.github/workflows/limit.yaml: -------------------------------------------------------------------------------- 1 | name: Limit PRs 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | limit_master_pr: 10 | runs-on: ubuntu-latest 11 | name: Limits PR to master 12 | steps: 13 | - name: Limit action step 14 | id: limit_action 15 | uses: LukBukkit/action-pr-limits@v1 16 | with: 17 | whitelist: | 18 | develop 19 | -------------------------------------------------------------------------------- /themes/fluid/.github/workflows/lint.yaml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | push: 5 | branches: 6 | - develop 7 | pull_request: 8 | branches: 9 | - develop 10 | 11 | jobs: 12 | build: 13 | 14 | runs-on: ubuntu-latest 15 | strategy: 16 | matrix: 17 | node-version: [8.x, 14.x] 18 | 19 | steps: 20 | - name: Checkout Branch 21 | uses: actions/checkout@v2 22 | with: 23 | fetch-depth: 1 24 | 25 | - name: Setup Node 26 | uses: actions/setup-node@v1 27 | with: 28 | node-version: ${{ matrix.node-version }} 29 | 30 | - name: Install Node Modules 31 | run: | 32 | rm -f .yarnclean 33 | yarn --frozen-lockfile --ignore-engines --ignore-optional --non-interactive --silent --ignore-scripts --production=false 34 | env: 35 | PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: true 36 | HUSKY_SKIP_INSTALL: true 37 | 38 | - name: Run Lint 39 | run: yarn run lint 40 | -------------------------------------------------------------------------------- /themes/fluid/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .DS_Store 3 | *.log 4 | *.iml 5 | yarn.lock 6 | package-lock.json 7 | node_modules/ -------------------------------------------------------------------------------- /themes/fluid/_static_prefix.yml: -------------------------------------------------------------------------------- 1 | #--------------------------- 2 | # Fluid 3 | # Author: Fluid-dev organization 4 | # Github: https://github.com/fluid-dev/hexo-theme-fluid 5 | #--------------------------- 6 | 7 | #--------------------------- 8 | # 这里是配置 JS CSS 静态资源的 URL 前缀,可以自定义成 CDN 地址, 9 | # 请注意,您最好使用与内部版本相同的版本,以避免潜在的问题, 10 | # 在站点上启用 https 时,请使用 CDN 地址的 https 协议, 11 | # 同样,这里的配置也支持覆盖功能 12 | # ** 如果你不知道如何设置,请不要做任何改动 ** 13 | # 14 | # Here is the url prefix to configure JS and CSS static assets. Set CDN addresses you want to customize. 15 | # Be aware that you would better use the same version as internal ones to avoid potential problems. 16 | # Please use the https protocol of CDN files when you enable https on your site. 17 | # the configuration here supports overwrite 18 | # DO NOT EDIT THE FOLLOWING SETTINGS UNLESS YOU KNOW WHAT YOU ARE DOING 19 | #--------------------------- 20 | 21 | #--------------------------- 22 | # 内部静态 23 | # Internal static 24 | #--------------------------- 25 | 26 | internal_js: https://npm.elemecdn.com/chenyfan-blog@1.0.1/public/js 27 | internal_css: https://npm.elemecdn.com/chenyfan-blog@1.0.1/public/css 28 | internal_img: https://npm.elemecdn.com/chenyfan-blog@1.0.1/public/img 29 | 30 | 31 | #--------------------------- 32 | # 第三方库 33 | # Third-party library 34 | #--------------------------- 35 | 36 | # 图标库,包含了大量社交类图标,主题依赖的不包含在内,因此可自行修改,详见 https://hexo.fluid-dev.com/docs/icon/ 37 | # Icon library, which includes many social icons, does not include those theme dependent, so your can modify link by yourself. Detail: https://hexo.fluid-dev.com/docs/en/icon/ 38 | iconfont: https://npm.elemecdn.com/chenyfan-cdn@2.0.0/assets/blog/font_1736178_pjno9b9zyxs.css 39 | 40 | anchor: https://cdn.staticfile.org/anchor-js/4.2.2/ 41 | 42 | github_markdown: https://npm.elemecdn.com/github-markdown-css@4.0.0/ 43 | 44 | jquery: https://npm.elemecdn.com/jquery@3.4.1/dist/ 45 | 46 | bootstrap: https://npm.elemecdn.com/bootstrap@5.1.3/dist/ 47 | 48 | highlightjs: https://npm.elemecdn.com/highlight.js@10.0.0/ 49 | 50 | tocbot: https://npm.elemecdn.com/tocbot@4.11.1/dist/ 51 | 52 | typed: https://npm.elemecdn.com/typed.js@2.0.11/lib/ 53 | 54 | fancybox: https://npm.elemecdn.com/@fancyapps/fancybox@3.5.7/dist/ 55 | 56 | mathjax: https://cdn.staticfile.org/mathjax/3.0.5/es5/ 57 | 58 | katex: https://cdn.staticfile.org/KaTeX/0.11.1/ 59 | 60 | aplayer: https://cdn.staticfile.org/aplayer/1.10.1/ 61 | 62 | busuanzi: https://busuanzi.ibruce.info/busuanzi/2.3/ 63 | 64 | clipboard: https://npm.elemecdn.com/clipboard@2.0.6/dist/ 65 | 66 | mermaid: https://cdn.staticfile.org/mermaid/8.5.0/ 67 | 68 | valine: https://cdn.staticfile.org/valine/1.4.14/ 69 | 70 | gitalk: https://cdn.staticfile.org/gitalk/1.6.2/ 71 | 72 | blueimp_md5: https://cdn.staticfile.org/blueimp-md5/2.13.0/ 73 | 74 | disqusjs: https://npm.elemecdn.com/disqusjs@1.0/dist/ 75 | 76 | hint: https://npm.elemecdn.com/chenyfan-blog@1.0.1/public/lib/hint/ 77 | -------------------------------------------------------------------------------- /themes/fluid/gulpfile.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const gulp = require('gulp'); 4 | const eslint = require('gulp-eslint'); 5 | const shell = require('gulp-shell'); 6 | const yaml = require('js-yaml'); 7 | 8 | gulp.task('lint', () => gulp.src([ 9 | './source/js/**/*.js', 10 | './scripts/**/*.js' 11 | ]).pipe(eslint()) 12 | .pipe(eslint.format()) 13 | .pipe(eslint.failAfterError())); 14 | 15 | gulp.task('lint:ejs', shell.task([ 16 | 'ejslint ./layout/**/*.ejs' 17 | ])); 18 | 19 | gulp.task('validate:config', cb => { 20 | const themeConfig = fs.readFileSync(path.join(__dirname, '_config.yml')); 21 | 22 | try { 23 | yaml.safeLoad(themeConfig); 24 | return cb(); 25 | } catch (error) { 26 | return cb(new Error(error)); 27 | } 28 | }); 29 | 30 | gulp.task('validate:languages', cb => { 31 | const languagesPath = path.join(__dirname, 'languages'); 32 | const languages = fs.readdirSync(languagesPath); 33 | const errors = []; 34 | 35 | languages.forEach(lang => { 36 | const languagePath = path.join(languagesPath, lang); 37 | try { 38 | yaml.safeLoad(fs.readFileSync(languagePath), { 39 | filename: path.relative(__dirname, languagePath) 40 | }); 41 | } catch (error) { 42 | errors.push(error); 43 | } 44 | }); 45 | 46 | return errors.length === 0 ? cb() : cb(errors); 47 | }); 48 | 49 | gulp.task('default', gulp.series('lint', 'lint:ejs', 'validate:config', 'validate:languages')); 50 | -------------------------------------------------------------------------------- /themes/fluid/languages/en.yml: -------------------------------------------------------------------------------- 1 | search: 2 | title: Search 3 | keyword: keyword 4 | status: 5 | success: v 6 | error: x 7 | 8 | postTotal: "%d posts in total." 9 | 10 | paginator: 11 | pre: Previous 12 | next: Next 13 | 14 | post: 15 | toc: TOC 16 | pre: Previous 17 | next: Next 18 | 19 | home: 20 | title: Home 21 | 22 | archive: 23 | title: Archives 24 | subtitle: Archive 25 | 26 | tag: 27 | title: Tags 28 | subtitle: Tag 29 | 30 | category: 31 | title: Categories 32 | subtitle: Category 33 | 34 | about: 35 | title: About 36 | subtitle: About 37 | 38 | page404: 39 | title: Page not found 40 | subtitle: Oops, Page not found... 41 | 42 | links: 43 | title: Links 44 | subtitle: Links 45 | -------------------------------------------------------------------------------- /themes/fluid/languages/ja.yml: -------------------------------------------------------------------------------- 1 | search: 2 | title: 検索 3 | keyword: キーワード 4 | status: 5 | success: v 6 | error: x 7 | 8 | postTotal: 合計 %d 件のポスト 9 | 10 | paginator: 11 | pre: 前のページ 12 | next: 次のページ 13 | 14 | post: 15 | toc: ディレクトリ 16 | pre: 前の記事 17 | next: 次の記事 18 | 19 | home: 20 | title: ホーム 21 | 22 | archive: 23 | title: アーカイブ 24 | subtitle: アーカイブ 25 | 26 | tag: 27 | title: タグ 28 | subtitle: タグ 29 | 30 | category: 31 | title: カテゴリー 32 | subtitle: カテゴリー 33 | 34 | about: 35 | title: 本ブログ情報  36 | subtitle: 本ブログ情報 37 | 38 | page404: 39 | title: ページが見つかりませんでした 40 | subtitle: ページが見つかりませんでした 41 | 42 | links: 43 | title: リンク 44 | subtitle: リンク 45 | -------------------------------------------------------------------------------- /themes/fluid/languages/zh-CN.yml: -------------------------------------------------------------------------------- 1 | search: 2 | title: 搜索 3 | keyword: 关键词 4 | status: 5 | success: v 6 | error: x 7 | 8 | postTotal: 共计 %d 篇文章 9 | 10 | paginator: 11 | pre: 上一页 12 | next: 下一页 13 | 14 | post: 15 | toc: 目录 16 | pre: 上一篇 17 | next: 下一篇 18 | 19 | home: 20 | title: 首页 21 | 22 | archive: 23 | title: 归档 24 | subtitle: 归档 25 | 26 | tag: 27 | title: 标签 28 | subtitle: 标签 29 | 30 | category: 31 | title: 分类 32 | subtitle: 分类 33 | 34 | about: 35 | title: 关于 36 | subtitle: 关于 37 | 38 | page404: 39 | title: 页面走丢啦~ 40 | subtitle: 页面走丢啦~ 41 | 42 | links: 43 | title: 友链 44 | subtitle: 友情链接 45 | -------------------------------------------------------------------------------- /themes/fluid/layout/404.ejs: -------------------------------------------------------------------------------- 1 | <% 2 | page.layout = "404" 3 | page.title = theme.page404.title || __('page404.title') 4 | page.subtitle = theme.page404.subtitle || __('page404.subtitle') 5 | page.banner_img = theme.page404.banner_img 6 | page.banner_img_height = theme.page404.banner_img_height 7 | page.banner_mask_alpha = theme.page404.banner_mask_alpha 8 | %> 9 | 10 | 17 | 18 | 27 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/beian.ejs: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/comments/changyan.ejs: -------------------------------------------------------------------------------- 1 | <% if(theme.changyan.appid){ %> 2 |
3 | 21 | <% } %> 22 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/comments/disqus.ejs: -------------------------------------------------------------------------------- 1 | <% if (theme.disqus.disqusjs) { %> 2 |
3 |
4 | 16 | 19 |
20 | <% } else { %> 21 |
22 |
23 | 39 | 42 |
43 | <% } %> 44 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/comments/gitalk.ejs: -------------------------------------------------------------------------------- 1 | <% if(theme.gitalk.clientID && theme.gitalk.clientSecret && theme.gitalk.repo){ %> 2 |
3 | 26 | <% } %> 27 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/comments/livere.ejs: -------------------------------------------------------------------------------- 1 | <% if(theme.livere.uid){ %> 2 |
3 | 9 | 10 |
11 | <% } %> 12 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/comments/utterances.ejs: -------------------------------------------------------------------------------- 1 | <% if(theme.utterances.repo && theme.utterances.issue_term){ %> 2 | 17 | <% } %> 18 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/css.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <% if (theme.custom_css) { %> 6 | <%- css(theme.custom_css) %> 7 | <% } %> 8 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/footer.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | 6 | 7 | UPyun 8 | 9 | 10 |
11 | 由强力的Hexo驱动 | 12 | 13 | 14 | 由可爱的Fluid支持 | 炒鸡NB的CYF书写 | 已加入十年之约 | 部分图片存储于DogeDoge图床 | 托管于CloudFlare
17 | 当前博客版本:锟斤拷版本 | 博客用户端管理 18 | 21 |

22 | 23 |

24 | 25 | 当前在线用户: 【锟斤拷】 | 26 | 你的ip: 【锟斤拷】 | 27 | 你的所在国家/地区: 【锟斤拷】 | 28 | 统计服务器通讯延迟:【锟斤拷】 29 | 30 |

31 |
32 | <%- partial('_partial/statistics.ejs') %> 33 | <%- partial('_partial/beian.ejs') %> 34 | <% if(theme.web_analytics.cnzz) { %> 35 | 36 | 37 | <% } %> 38 |
39 | 50 | 51 | 54 | 55 | 56 | 57 |
58 | 59 | 60 | <%- partial('_partial/scripts.ejs') %> -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/paginator.ejs: -------------------------------------------------------------------------------- 1 | <% if (page.total > 1){ %> 2 | 12 | <% var point = theme.scroll_down_arrow.scroll_after_turning_page ? '#board' : '' %> 13 | 18 | <% } %> 19 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/plugins/analytics.ejs: -------------------------------------------------------------------------------- 1 | <% if (theme.web_analytics.enable) { %> 2 | 3 | <% if(theme.web_analytics.baidu) { %> 4 | 5 | 14 | <% } %> 15 | 16 | <% if (theme.web_analytics.google){ %> 17 | 18 | 28 | <% } %> 29 | 30 | <% if (theme.web_analytics.gtag){ %> 31 | 32 | 33 | 39 | <% } %> 40 | 41 | <% if(theme.web_analytics.tencent && theme.web_analytics.tencent.sid && theme.web_analytics.tencent.cid) { %> 42 | 43 | 57 | <% } %> 58 | 59 | <% if(theme.web_analytics.tajs) { %> 60 | 61 | 62 | <% } %> 63 | 64 | <% if(theme.web_analytics.woyaola) { %> 65 | 66 | 67 | <% } %> 68 | 69 | <% if(theme.web_analytics.cnzz) { %> 70 | 71 | 73 | <% } %> 74 | <% } %> 75 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/plugins/anchor.ejs: -------------------------------------------------------------------------------- 1 | <% if((is_post() || is_page()) && theme.fun_features.anchorjs.enable){ %> 2 | <%- js_ex(theme.static_prefix.anchor, "/anchor.min.js") %> 3 | 18 | <% } %> 19 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/plugins/aplayer.ejs: -------------------------------------------------------------------------------- 1 | <%- js_ex(theme.static_prefix.aplayer, 'APlayer.min.js', 'defer') %> 2 | <%- css_ex(theme.static_prefix.aplayer, 'APlayer.min.css') %> 3 | 20 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/plugins/daovoice.ejs: -------------------------------------------------------------------------------- 1 | <% if(theme.daovoice.enable && theme.daovoice.appid){ %> 2 | 21 | <% } %> 22 | 23 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/plugins/fancybox.ejs: -------------------------------------------------------------------------------- 1 | <% if ((is_post() || (is_page() && page.image_zoom)) && theme.post.image_zoom.enable) { %> 2 | <%- js_ex(theme.static_prefix.fancybox, 'jquery.fancybox.min.js') %> 3 | <%- css_ex(theme.static_prefix.fancybox, 'jquery.fancybox.min.css') %> 4 | 5 | 15 | <% } %> 16 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/plugins/local-search.ejs: -------------------------------------------------------------------------------- 1 | <% if(theme.search.enable){ %> 2 | <%- js_ex(theme.static_prefix.internal_js, "local-search.js") %> 3 | 11 | <% } %> 12 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/plugins/math.ejs: -------------------------------------------------------------------------------- 1 | <% 2 | var enable = theme.post.math.enable; 3 | 4 | if (enable) { 5 | if (is_post()) { 6 | enable = !theme.post.math.specific || (theme.post.math.specific && page.math); 7 | } else if (is_page()) { 8 | enable = page.math; 9 | } else { 10 | enable = false; 11 | } 12 | } 13 | %> 14 | 15 | <% if (enable) { %> 16 | <% var engine = theme.post.math.engine; %> 17 | 18 | <% if(engine === 'mathjax') { %> 19 | 20 | 50 | 51 | <%- js_ex(theme.static_prefix.mathjax, "tex-svg.js", 'async') %> 52 | 53 | <% } else if (engine === 'katex') { %> 54 | 55 | <%- css_ex(theme.static_prefix.katex, "katex.min.css") %> 56 | <% } %> 57 | <% } %> 58 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/plugins/mermaid.ejs: -------------------------------------------------------------------------------- 1 | <% 2 | var enable = theme.post.mermaid.enable; 3 | 4 | if (enable) { 5 | if (is_post()) { 6 | enable = !theme.post.mermaid.specific || (theme.post.mermaid.specific && page.mermaid); 7 | } else if (is_page()) { 8 | enable = page.mermaid; 9 | } else { 10 | enable = false; 11 | } 12 | } 13 | 14 | var options = JSON.stringify(theme.post.mermaid.options); 15 | %> 16 | 17 | <% if (enable) { %> 18 | <%- js_ex(theme.static_prefix.mermaid, 'mermaid.min.js') %> 19 | 24 | <% } %> 25 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/plugins/mouse-click.ejs: -------------------------------------------------------------------------------- 1 | <% if (theme.fun_features.mouse_click && theme.fun_features.mouse_click.enable) { %> 2 | <% var style = theme.fun_features.mouse_click.style %> 3 | <% if (style === 'values') { %> 4 | 50 | <% } else if (style === 'love') { %> 51 | 98 | <% } %> 99 | <% } %> 100 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/plugins/tocjs.ejs: -------------------------------------------------------------------------------- 1 | <% if(is_post() && theme.post.toc.enable && page.toc != false){ %> 2 | <%- js_ex(theme.static_prefix.tocbot, '/tocbot.min.js') %> 3 | 26 | <% } %> 27 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/plugins/typed.ejs: -------------------------------------------------------------------------------- 1 | <% if(theme.fun_features.typing.enable && page.subtitle !== false){ %> 2 | <%- js_ex(theme.static_prefix.typed, "/typed.min.js") %> 3 | 19 | <% } %> 20 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/post-meta.ejs: -------------------------------------------------------------------------------- 1 | <% if (theme.post.meta.date.enable && page.meta !== false) { %> 2 | 8 | <% } %> 9 | 10 |
11 | <% if (theme.post.meta.wordcount.enable && page.meta !== false) { %> 12 | <% var wordcount_texts = theme.post.meta.wordcount.format.split('{}') %> 13 | 17 | <% } %> 18 | 19 | <% if (theme.post.meta.min2read.enable && page.meta !== false) { %> 20 | <% var min2read_texts = theme.post.meta.min2read.format.split('{}') %> 21 | 28 | <% } %> 29 | 30 | 31 | loading 32 | 阅读量 33 | 34 | 35 | <% var views_texts = theme.post.meta.views.format.split('{}') %> 36 | <% if (theme.post.meta.views.enable && page.meta !== false) { %> 37 | <% if (theme.post.meta.views.source === 'leancloud') { %> 38 | 39 | 43 | <% } else if (theme.post.meta.views.source === 'busuanzi' && page.meta !== false) { %> 44 | 45 | 49 | <% } %> 50 | <% } %> 51 |
52 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/search.ejs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/statistics.ejs: -------------------------------------------------------------------------------- 1 | <% if (theme.footer.statistics.enable) { %> 2 |
3 | <% var pv_texts = theme.footer.statistics.pv_format.split('{}') %> 4 | <% var uv_texts = theme.footer.statistics.uv_format.split('{}') %> 5 | 6 | <% if (theme.footer.statistics.source === 'leancloud') { %> 7 | <% if (theme.footer.statistics.pv_format) { %> 8 | 9 | 14 | <% } %> 15 | <% if (theme.footer.statistics.uv_format) { %> 16 | 17 | 22 | <% } %> 23 | 24 | <% } else if (theme.footer.statistics.source === 'busuanzi') { %> 25 | <% if (theme.footer.statistics.pv_format) { %> 26 | 27 | 32 | <% } %> 33 | <% if (theme.footer.statistics.uv_format) { %> 34 | 35 | 40 | <% } %> 41 | <% } %> 42 |
43 | <% } %> 44 | -------------------------------------------------------------------------------- /themes/fluid/layout/_partial/toc.ejs: -------------------------------------------------------------------------------- 1 |
2 |

 <%= __('post.toc') %>

3 |
4 |
5 | -------------------------------------------------------------------------------- /themes/fluid/layout/about.ejs: -------------------------------------------------------------------------------- 1 | <% 2 | page.layout = "about" 3 | page.title = theme.about.title || __('about.title') 4 | page.subtitle = theme.about.subtitle || __('about.subtitle') 5 | page.banner_img = theme.about.banner_img 6 | page.banner_img_height = theme.about.banner_img_height 7 | page.banner_mask_alpha = theme.about.banner_mask_alpha 8 | %> 9 | 10 |
11 |
12 |
<%- theme.about.name %>
13 |
<%- theme.about.introduce %>
14 |
15 | <% for(const each of theme.about.icons || []) { %> 16 | <% if (!each.class) continue; %> 17 | <% var cls = each.class %> 18 | <% var isQr = each.qrcode %> 19 | 22 | > 23 | 24 | <% if (isQr) { %> 25 | qrcode 26 | <% } %> 27 | 28 | <% } %> 29 |
30 |
31 |
32 |
33 | <%- page.content %> 34 |
35 | -------------------------------------------------------------------------------- /themes/fluid/layout/archive.ejs: -------------------------------------------------------------------------------- 1 | <% 2 | page.layout = "archive" 3 | page.title = theme.archive.title || __('archive.title') 4 | page.subtitle = theme.archive.subtitle || __('archive.subtitle') 5 | page.banner_img = theme.archive.banner_img 6 | page.banner_img_height = theme.archive.banner_img_height 7 | page.banner_mask_alpha = theme.archive.banner_mask_alpha 8 | var date_cursor = 'xxx' 9 | %> 10 | 11 |
12 |

<%= __('postTotal', site.posts.length) %>

13 |
14 | <% page.posts.each(function (post) { %> 15 | <% if(date(post.date, "YYYY") != date_cursor) { %> 16 | <% date_cursor = date(post.date, "YYYY") %> 17 |

<%= date_cursor %>

18 | <% } %> 19 | 20 | <%= post.title %> 21 | 22 | 23 | <% }) %> 24 |
25 | <%- partial('_partial/paginator') %> 26 | -------------------------------------------------------------------------------- /themes/fluid/layout/categories.ejs: -------------------------------------------------------------------------------- 1 | <% 2 | page.layout = "categories" 3 | page.title = theme.category.title || __('category.title') 4 | page.subtitle = theme.category.subtitle || __('category.subtitle') 5 | page.banner_img = theme.category.banner_img 6 | page.banner_img_height = theme.category.banner_img_height 7 | page.banner_mask_alpha = theme.category.banner_mask_alpha 8 | 9 | var orderBy = theme.category.order_by || 'name' 10 | %> 11 | 12 | <% function render_categories(cats, depth) { %> 13 | <% depth = depth || 0 %> 14 | <% return cats.each(function(cat){ %> 15 | <% var subCats = site.categories.find({parent: cat._id}).sort(orderBy).filter(cat => cat.length) %> 16 | <% var collapsed = subCats.length === 0 %> 17 |
18 | 26 | 27 | 28 | <%= cat.posts.length %> 29 | 30 |
31 | <% if (subCats.length > 0) { %> 32 | <%- render_sub_categories(subCats, cat, depth + 1) %> 33 | <% } else { %> 34 | <%- render_posts(cat) %> 35 | <% } %> 36 |
37 |
38 | <% }) %> 39 | <% } %> 40 | 41 | <% function render_sub_categories(cats, parent, depth) { %> 42 |
44 | <%- render_categories(cats, depth) %> 45 |
46 | <% } %> 47 | 48 | <% function render_posts(cat) { %> 49 |
51 | <% var limit = theme.category.post_limit %> 52 | <% var posts = cat.posts.sort(config.index_generator.order_by || '-date') %> 53 | <% for (var idx = 0; idx < posts.length; idx++) { %> 54 | <% var post = posts.data[idx] %> 55 | <% if (idx && limit && idx >= limit) { %> 56 | 57 | More... 58 | 59 | <% break %> 60 | <% } else { %> 61 | 62 | <%= post.title %> 63 | 64 | <% } %> 65 | <% } %> 66 |
67 | <% } %> 68 | 69 |
70 | <% cats = site.categories.find({parent: {$exists: false}}).sort(orderBy).filter(cat => cat.length) %> 71 | <%- render_categories(cats) %> 72 |
73 | -------------------------------------------------------------------------------- /themes/fluid/layout/category.ejs: -------------------------------------------------------------------------------- 1 | <% 2 | page.layout = "category" 3 | page.title = [__('category.title'), page.category].join(" - ") 4 | page.subtitle = [__('category.subtitle'), page.category].join(" - ") 5 | page.banner_img = theme.category.banner_img 6 | page.banner_img_height = theme.category.banner_img_height 7 | page.banner_mask_alpha = theme.category.banner_mask_alpha 8 | 9 | var cat = site.categories.find({name: page.category}).filter(cat => cat.length).data[0] 10 | var date_cursor = 'xxx' 11 | %> 12 | 13 |
14 |

<%= __('postTotal', cat ? cat.posts.length : 0) %>

15 |
16 | <% page.posts.each(function (post) { %> 17 | <% if(date(post.date, "YYYY") != date_cursor) { %> 18 | <% date_cursor = date(post.date, "YYYY") %> 19 |

<%= date_cursor %>

20 | <% } %> 21 | 22 | <%= post.title %> 23 | 24 | 25 | <% }) %> 26 |
27 | <%- partial('_partial/paginator') %> 28 | -------------------------------------------------------------------------------- /themes/fluid/layout/index.ejs: -------------------------------------------------------------------------------- 1 | <% 2 | if (theme.index.slogan.enable) { 3 | page.subtitle = theme.index.slogan.text || config.subtitle || '' 4 | } 5 | page.banner_img = theme.index.banner_img 6 | page.banner_img_height = theme.index.banner_img_height 7 | page.banner_mask_alpha = theme.index.banner_mask_alpha 8 | %> 9 | 10 | <% page.posts.each(function (post) { %> 11 |
12 | <% var post_url = url_for(post.path), index_img = post.index_img || theme.index.post_default_img %> 13 | <% if(index_img) { %> 14 |
15 | 16 | <%= post.title %> 17 | 18 |
19 | <% } %> 20 |
21 |

22 | <%= post.title %> 23 |

24 | 25 |

26 | 27 | <% var excerpt = '' %> 28 | <% if(post.excerpt) { %> 29 | <% excerpt = strip_html(post.excerpt).substr(0, 200) %> 30 | <% } else if(theme.index.auto_excerpt.enable){ %> 31 | <% excerpt = strip_html(post.content).substr(0, 200) %> 32 | <% } %> 33 | <%- excerpt %> 34 | 35 |

36 | 37 | 68 |
69 |
70 | <% }) %> 71 | 72 | <%- partial('_partial/paginator') %> 73 | -------------------------------------------------------------------------------- /themes/fluid/layout/links.ejs: -------------------------------------------------------------------------------- 1 | <% 2 | page.layout = "links" 3 | page.title = theme.links.title || __('links.title') 4 | page.subtitle = theme.links.subtitle || __('links.subtitle') 5 | page.banner_img = theme.links.banner_img 6 | page.banner_img_height = theme.links.banner_img_height 7 | page.banner_mask_alpha = theme.links.banner_mask_alpha 8 | %> 9 | 25 | 53 | -------------------------------------------------------------------------------- /themes/fluid/layout/page.ejs: -------------------------------------------------------------------------------- 1 | <% 2 | var layout = page.layout 3 | page.title = page.title || __(`${ layout }.title`) 4 | page.subtitle = page.subtitle || page.title || __(`${ layout }.subtitle`) 5 | page.banner_img = page.banner_img || theme.page.banner_img 6 | page.banner_img_height = page.banner_img_height || theme.page.banner_img_height 7 | page.banner_mask_alpha = page.banner_mask_alpha || theme.page.banner_mask_alpha 8 | %> 9 | 10 |
11 | <%- page.content %> 12 |
13 |
14 | <% var type = '_partial/comments/' + theme.post.comments.type %> 15 | <%- partial(type) %> 16 |
17 | -------------------------------------------------------------------------------- /themes/fluid/layout/tag.ejs: -------------------------------------------------------------------------------- 1 | <% 2 | page.layout = "tag" 3 | page.title = [__('tag.title'), page.tag].join(" - ") 4 | page.subtitle = [__('tag.subtitle'), page.tag].join(" - ") 5 | page.banner_img = theme.tag.banner_img 6 | page.banner_img_height = theme.tag.banner_img_height 7 | page.banner_mask_alpha = theme.tag.banner_mask_alpha 8 | 9 | var tag = site.tags.find({name: page.tag}).filter(tag => tag.length).data[0] 10 | var date_cursor = 'xxx' 11 | %> 12 | 13 |
14 |

<%= __('postTotal', tag ? tag.posts.length : 0) %>

15 |
16 | <% page.posts.each(function (post) { %> 17 | <% if(date(post.date, "YYYY") != date_cursor) { %> 18 | <% date_cursor = date(post.date, "YYYY") %> 19 |

<%= date_cursor %>

20 | <% } %> 21 | 22 | <%= post.title %> 23 | 24 | 25 | <% }) %> 26 |
27 | <%- partial('_partial/paginator') %> 28 | -------------------------------------------------------------------------------- /themes/fluid/layout/tags.ejs: -------------------------------------------------------------------------------- 1 | <% 2 | page.layout = "tags" 3 | page.title = theme.tag.title || __('tag.title') 4 | page.subtitle = theme.tag.subtitle || __('tag.subtitle') 5 | page.banner_img = theme.tag.banner_img 6 | page.banner_img_height = theme.tag.banner_img_height 7 | page.banner_mask_alpha = theme.tag.banner_mask_alpha 8 | 9 | var min_font = theme.tag.tagcloud.min_font || 15 10 | var max_font = theme.tag.tagcloud.max_font || 30 11 | var unit = theme.tag.tagcloud.unit || 'px' 12 | var start_color = theme.tag.tagcloud.start_color || '#BBBBEE' 13 | var end_color = theme.tag.tagcloud.end_color || '#337ab7' 14 | %> 15 | 16 |
17 | <%- tagcloud({ 18 | min_font: min_font, 19 | max_font: max_font, 20 | amount: 999, 21 | unit: unit, 22 | color: true, 23 | start_color, 24 | end_color 25 | }) %> 26 |
27 | -------------------------------------------------------------------------------- /themes/fluid/local-search.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% if posts %} 4 | {% for post in posts.toArray() %} 5 | {% if post.indexing == undefined or post.indexing %} 6 | 7 | {{ post.title }} 8 | 9 | {{ [url, post.path] | urlJoin | uriencode }} 10 | {% if content %} 11 | 12 | {% endif %} 13 | {% if post.categories and post.categories.length>0 %} 14 | 15 | {% for cate in post.categories.toArray() %} 16 | {{ cate.name }} 17 | {% endfor %} 18 | 19 | {% endif %} 20 | {% if post.tags and post.tags.length>0 %} 21 | 22 | {% for tag in post.tags.toArray() %} 23 | {{ tag.name }} 24 | {% endfor %} 25 | 26 | {% endif %} 27 | 28 | {% endif %} 29 | {% endfor %} 30 | {% endif %} 31 | {% if pages %} 32 | {% for page in pages.toArray() %} 33 | {% if post.indexing == undefined or post.indexing %} 34 | 35 | {{ page.title }} 36 | 37 | {{ [url, post.path] | urlJoin | uriencode }} 38 | {% if content %} 39 | 40 | {% endif %} 41 | 42 | {% endif %} 43 | {% endfor %} 44 | {% endif %} 45 | 46 | -------------------------------------------------------------------------------- /themes/fluid/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hexo-theme-fluid", 3 | "version": "1.8.1", 4 | "description": "An elegant Material-Design theme for Hexo.", 5 | "main": "gulpfile.js", 6 | "scripts": { 7 | "lint": "gulp" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/fluid-dev/hexo-theme-fluid.git" 12 | }, 13 | "keywords": [ 14 | "hexo", 15 | "theme", 16 | "fluid", 17 | "material" 18 | ], 19 | "author": "fluid-dev (https://github.com/fluid-dev)", 20 | "license": "MIT", 21 | "bugs": { 22 | "url": "https://github.com/fluid-dev/hexo-theme-fluid/issues" 23 | }, 24 | "homepage": "https://hexo.fluid-dev.com/docs", 25 | "engines": { 26 | "node": ">=8.10.0" 27 | }, 28 | "devDependencies": { 29 | "ejs-lint": "^1.1.0", 30 | "gulp": "^4.0.2", 31 | "gulp-eslint": "^6.0.0", 32 | "gulp-shell": "^0.8.0", 33 | "husky": "^4.2.5", 34 | "js-yaml": "^3.13.1" 35 | }, 36 | "husky": { 37 | "hooks": { 38 | "pre-commit": "npm run lint" 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /themes/fluid/scripts/events/index.js: -------------------------------------------------------------------------------- 1 | /* global hexo */ 2 | 3 | 'use strict'; 4 | 5 | hexo.on('generateBefore', () => { 6 | require('./lib/hello')(hexo); 7 | require('./lib/merge-configs')(hexo); 8 | require('./lib/highlight')(hexo); 9 | require('./lib/lazyload')(hexo); 10 | require('./lib/footnote')(hexo); 11 | }); 12 | 13 | hexo.on('generateAfter', () => { 14 | require('./lib/version')(hexo); 15 | }); 16 | -------------------------------------------------------------------------------- /themes/fluid/scripts/events/lib/footnote.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Register footnotes filter 4 | module.exports = (hexo) => { 5 | const config = hexo.theme.config; 6 | if (config.post.footnote.enable) { 7 | hexo.extend.filter.register('before_post_render', function(page) { 8 | page.content = renderFootnotes(page.content, page.footnote); 9 | return page; 10 | }); 11 | } 12 | 13 | /** 14 | * Modify by https://github.com/kchen0x/hexo-reference 15 | * 16 | * Render markdown footnotes 17 | * @param {String} text 18 | * @param {String} header 19 | * @returns {String} text 20 | */ 21 | function renderFootnotes(text, header) { 22 | const reFootnoteContent = /\[\^(\d+)]: ?([\S\s]+?)(?=\[\^(?:\d+)]|\n\n|$)/g; 23 | const reInlineFootnote = /\[\^(\d+)]\((.+?)\)/g; 24 | const reFootnoteIndex = /\[\^(\d+)]/g; 25 | let footnotes = []; 26 | let html = ''; 27 | 28 | // threat all inline footnotes 29 | text = text.replace(reInlineFootnote, function(match, index, content) { 30 | footnotes.push({ 31 | index : index, 32 | content: content 33 | }); 34 | // remove content of inline footnote 35 | return '[^' + index + ']'; 36 | }); 37 | 38 | // threat all footnote contents 39 | text = text.replace(reFootnoteContent, function(match, index, content) { 40 | footnotes.push({ 41 | index : index, 42 | content: content 43 | }); 44 | // remove footnote content 45 | return ''; 46 | }); 47 | 48 | // create map for looking footnotes array 49 | function createLookMap(field) { 50 | let map = {}; 51 | for (let i = 0; i < footnotes.length; i++) { 52 | const item = footnotes[i]; 53 | const key = item[field]; 54 | map[key] = item; 55 | } 56 | return map; 57 | } 58 | const indexMap = createLookMap('index'); 59 | 60 | // render (HTML) footnotes reference 61 | text = text.replace(reFootnoteIndex, 62 | function(match, index) { 63 | if (!indexMap[index]) { 64 | return match; 65 | } 66 | let tooltip = indexMap[index].content; 67 | tooltip = hexo.render.renderSync({ text: tooltip, engine: 'markdown' }); 68 | tooltip = tooltip.replace(/(<.+?>)/g, ''); 69 | return '' 70 | + '' 71 | + '[' + index + ']'; 74 | }); 75 | 76 | // sort footnotes by their index 77 | footnotes.sort(function(a, b) { 78 | return a.index - b.index; 79 | }); 80 | 81 | // render footnotes (HTML) 82 | footnotes.forEach(function(footNote) { 83 | html += '
  • '; 84 | html += ''; 85 | const fn = hexo.render.renderSync({ text: footNote.content.trim(), engine: 'markdown' }); 86 | html += fn.replace(/(

    )|(<\/p>)/g, ''); 87 | html += '

  • '; 88 | }); 89 | 90 | // add footnotes at the end of the content 91 | if (footnotes.length) { 92 | text += '
    '; 93 | text += header || config.post.footnote.header || ''; 94 | text += '
    '; 95 | text += '
      ' + html + '
    '; 96 | text += '
    '; 97 | } 98 | return text; 99 | } 100 | }; 101 | -------------------------------------------------------------------------------- /themes/fluid/scripts/events/lib/hello.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = (hexo) => { 4 | hexo.log.info(` 5 | ------------------------------------------------ 6 | | | 7 | | ________ __ _ __ | 8 | | |_ __ |[ | (_) | ] | 9 | | | |_ \\_| | | __ _ __ .--.| | | 10 | | | _| | |[ | | | [ |/ /'\`\\' | | 11 | | _| |_ | | | \\_/ |, | || \\__/ | | 12 | | |_____| [___]'.__.'_/[___]'.__.;__] | 13 | | | 14 | | Thank you for using Fluid theme ! | 15 | | Docs: https://hexo.fluid-dev.com/docs/ | 16 | | | 17 | ------------------------------------------------ 18 | `); 19 | }; 20 | -------------------------------------------------------------------------------- /themes/fluid/scripts/events/lib/highlight.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const objUtil = require('../../utils/object'); 4 | 5 | module.exports = (hexo) => { 6 | const config = hexo.theme.config; 7 | if (!config.highlight.enable) { 8 | return; 9 | } 10 | 11 | // Force set hexo config 12 | hexo.config.highlight = objUtil.merge({}, hexo.config.highlight, { 13 | enable : true, 14 | hljs : true, 15 | line_number: false, 16 | wrap : false, 17 | auto_detect: true 18 | }); 19 | 20 | if (config.highlight.bg_color) { 21 | hexo.extend.filter.register('after_render:html', (html, data) => { 22 | return html.replace(/(?)(.*?)<\/pre>/gis, (str, p1, p2) => { 23 | if (p2.search(/mermaid/) !== -1) { 24 | return str; 25 | } 26 | return `
    ${p2}
    `; 27 | }); 28 | }); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /themes/fluid/scripts/events/lib/lazyload.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const joinPath = require('../../utils/join-path'); 4 | 5 | module.exports = (hexo) => { 6 | var config = hexo.theme.config; 7 | let loadingImage = 'https://npm.elemecdn.com/chenyfan-blog@1.0.1/themes/fluid/source/img/loading.gif'; 8 | if (!config.lazyload || !config.lazyload.enable || !loadingImage) { 9 | return; 10 | } 11 | if (config.lazyload.onlypost) { 12 | hexo.extend.filter.register('after_post_render', function(page) { 13 | if (page.source.search(/^_posts\/.+\.md$/) === -1 && !page.lazyload) { 14 | return; 15 | } 16 | page.content = lazyProcess(page.content, loadingImage); 17 | return page; 18 | }); 19 | } else { 20 | hexo.extend.filter.register('after_render:html', function(str, data) { 21 | return lazyProcess(str, loadingImage); 22 | }); 23 | } 24 | }; 25 | 26 | const lazyProcess = (htmlContent, loadingImage) => { 27 | return htmlContent.replace(/]+src="(.*?)"[^>]*>/gi, (str, p1) => { 28 | if (/srcset=/gi.test(str)) { 29 | return str; 30 | } 31 | return str.replace(p1, `${p1}" srcset="${loadingImage}`); 32 | }); 33 | }; 34 | -------------------------------------------------------------------------------- /themes/fluid/scripts/events/lib/merge-configs.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | const yaml = require('js-yaml'); 6 | const objUtil = require('../../utils/object'); 7 | 8 | module.exports = (hexo) => { 9 | let sourceConfig, staticPrefix; 10 | 11 | if (hexo.locals.get) { 12 | const data = hexo.locals.get('data'); 13 | sourceConfig = {}; 14 | if (data && data.fluid_config) { 15 | sourceConfig = data.fluid_config; 16 | } else { 17 | const isZh = hexo.config.language.search(/zh-CN/i) !== -1; 18 | if (isZh) { 19 | hexo.log.warn('推荐你使用覆盖配置功能: https://hexo.fluid-dev.com/docs/guide/#%E8%A6%86%E7%9B%96%E9%85%8D%E7%BD%AE'); 20 | } else { 21 | hexo.log.warn('It is recommended that you use override configuration: https://hexo.fluid-dev.com/docs/en/guide/#override-configuration'); 22 | } 23 | } 24 | staticPrefix = {}; 25 | if (data && data.fluid_static_prefix) { 26 | staticPrefix = data.fluid_static_prefix; 27 | } 28 | } 29 | 30 | // Merge configs in /source/_data/fluid_static_prefix.yml into hexo.theme.config. 31 | const configPath = path.join(__dirname, '../../../_static_prefix.yml'); 32 | const yamlDoc = yaml.safeLoad(fs.readFileSync(configPath, 'utf8')); 33 | hexo.theme.config.static_prefix = objUtil.merge({}, yamlDoc, staticPrefix); 34 | hexo.log.debug('Fluid: theme static_prefix config merged'); 35 | 36 | // Merge configs in hexo.config.theme_config and /source/_data/fluid_config.yml into hexo.theme.config. 37 | hexo.theme.config = objUtil.merge({}, hexo.theme.config, sourceConfig, hexo.config.theme_config); 38 | 39 | hexo.log.debug('Fluid: theme config merged'); 40 | hexo.log.debug('Configs:\n', JSON.stringify(hexo.theme.config, undefined, 2)); 41 | }; 42 | -------------------------------------------------------------------------------- /themes/fluid/scripts/events/lib/version.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = (hexo) => { 4 | if (!hexo.theme.config.version.check) { 5 | return; 6 | } 7 | 8 | const https = require('https'); 9 | const path = require('path'); 10 | const { version } = require(path.normalize('../../../package.json')); 11 | const isZh = hexo.config.language.search(/zh-CN/i) !== -1; 12 | 13 | const errorLog = (_) => { 14 | if (isZh) { 15 | hexo.log.warn('获取主题最新版本信息失败,可能与 GitHub 连接不畅,不影响正常使用'); 16 | } else { 17 | hexo.log.warn('Failed to detect version info. Don\'t worry, it won\'t hinder the use'); 18 | } 19 | }; 20 | 21 | https.get('https://api.github.com/repos/fluid-dev/hexo-theme-fluid/releases/latest', (res) => { 22 | let result = ''; 23 | res.on('data', data => { 24 | result += data; 25 | }); 26 | res.on('end', () => { 27 | try { 28 | const tag = JSON.parse(result).tag_name; 29 | if (!tag) { 30 | errorLog('Missing release tag'); 31 | return; 32 | } 33 | const latest = tag.replace('v', '').split('.'); 34 | const current = version.split('.'); 35 | 36 | let isOutdated = false; 37 | for (let i = 0; i < Math.max(latest.length, current.length); i++) { 38 | if (!current[i] || latest[i] > current[i]) { 39 | isOutdated = true; 40 | break; 41 | } 42 | if (latest[i] < current[i]) { 43 | break; 44 | } 45 | } 46 | 47 | if (isOutdated) { 48 | if (isZh) { 49 | hexo.log.warn(`你的 Fluid 主题版本已落后. 当前版本: v${current.join('.')}, 最新版本: v${latest.join('.')}`); 50 | hexo.log.warn('查看 https://github.com/fluid/hexo-theme-fluid/releases 获取更多信息.'); 51 | } else { 52 | hexo.log.warn(`Your theme Fluid is outdated. Current version: v${current.join('.')}, latest version: v${latest.join('.')}`); 53 | hexo.log.warn('Visit https://github.com/fluid/hexo-theme-fluid/releases for more information.'); 54 | } 55 | } else { 56 | if (isZh) { 57 | hexo.log.info(`感谢支持!你现在使用的是 Fluid 最新版本,版本号: v${current.join('.')}`); 58 | } else { 59 | hexo.log.info(`Congratulations! Your are using the latest version of theme Fluid. Current version: v${current.join('.')}`); 60 | } 61 | } 62 | } catch (err) { 63 | errorLog(err); 64 | } 65 | }); 66 | }).on('error', err => { 67 | errorLog(err); 68 | }); 69 | }; 70 | -------------------------------------------------------------------------------- /themes/fluid/scripts/filters/post-filter.js: -------------------------------------------------------------------------------- 1 | /* global hexo */ 2 | 3 | 'use strict'; 4 | 5 | // 生成前过滤文章 6 | hexo.extend.filter.register('before_generate', function() { 7 | this._bindLocals(); 8 | 9 | const all_posts = this.locals.get('posts'); 10 | const hide_posts = all_posts.filter(post => post.hide); 11 | const normal_posts = all_posts.filter(post => !post.hide); 12 | 13 | this.locals.set('all_posts', all_posts); 14 | this.locals.set('hide_posts', hide_posts); 15 | this.locals.set('posts', normal_posts); 16 | }); 17 | 18 | const original_post_generator = hexo.extend.generator.get('post'); 19 | 20 | hexo.extend.generator.register('post', function(locals) { 21 | // 发送时需要把过滤的页面也加入 22 | return original_post_generator.bind(this)({ 23 | posts: new locals.posts.constructor( 24 | locals.posts.data.concat(locals.hide_posts.data) 25 | ) 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /themes/fluid/scripts/generators/local-search.js: -------------------------------------------------------------------------------- 1 | /* global hexo */ 2 | 3 | 'use strict'; 4 | 5 | hexo.extend.generator.register('_hexo_generator_search', function(locals) { 6 | const config = this.theme.config; 7 | if (!config.search.enable) { 8 | return; 9 | } 10 | 11 | const nunjucks = require('nunjucks'); 12 | const env = new nunjucks.Environment(); 13 | const pathFn = require('path'); 14 | const fs = require('fs'); 15 | 16 | env.addFilter('uriencode', function(str) { 17 | return encodeURI(str); 18 | }); 19 | 20 | env.addFilter('noControlChars', function(str) { 21 | // eslint-disable-next-line no-control-regex 22 | return str && str.replace(/[\x00-\x1F\x7F]/g, ''); 23 | }); 24 | 25 | env.addFilter('urlJoin', function(str) { 26 | const base = str[0]; 27 | const relative = str[1]; 28 | return relative 29 | ? base.replace(/\/+$/, '') + '/' + relative.replace(/^\/+/, '') 30 | : base; 31 | }); 32 | 33 | const searchTmplSrc = pathFn.join(__dirname, '../../local-search.xml'); 34 | const searchTmpl = nunjucks.compile(fs.readFileSync(searchTmplSrc, 'utf8'), env); 35 | 36 | const searchConfig = config.search; 37 | let searchField = searchConfig.field; 38 | const content = searchConfig.content || true; 39 | 40 | let posts, pages; 41 | 42 | if (searchField.trim() !== '') { 43 | searchField = searchField.trim(); 44 | if (searchField === 'post') { 45 | posts = locals.posts.sort('-date'); 46 | } else if (searchField === 'page') { 47 | pages = locals.pages; 48 | } else { 49 | posts = locals.posts.sort('-date'); 50 | pages = locals.pages; 51 | } 52 | } else { 53 | posts = locals.posts.sort('-date'); 54 | } 55 | 56 | const xml = searchTmpl.render({ 57 | config : config, 58 | posts : posts, 59 | pages : pages, 60 | content: content, 61 | url : hexo.config.root 62 | }); 63 | 64 | return { 65 | path: searchConfig.generate_path || '/local-search.xml', 66 | data: xml 67 | }; 68 | }); 69 | -------------------------------------------------------------------------------- /themes/fluid/scripts/generators/pages.js: -------------------------------------------------------------------------------- 1 | /* global hexo */ 2 | 3 | 'use strict'; 4 | 5 | // generate 404 page 6 | hexo.extend.generator.register('_404', function(locals) { 7 | return { 8 | path : '404.html', 9 | data : locals.theme, 10 | layout: '404' 11 | }; 12 | }); 13 | 14 | // generate tags Page 15 | hexo.extend.generator.register('_tags', function(locals) { 16 | return { 17 | path : 'tags/index.html', 18 | data : locals.theme, 19 | layout: 'tags' 20 | }; 21 | }); 22 | 23 | // generate categories Page 24 | hexo.extend.generator.register('_categories', function(locals) { 25 | return { 26 | path : 'categories/index.html', 27 | data : locals.theme, 28 | layout: 'categories' 29 | }; 30 | }); 31 | 32 | // generate links page 33 | hexo.extend.generator.register('_links', function(locals) { 34 | return { 35 | path : 'links/index.html', 36 | data : locals.theme, 37 | layout: 'links' 38 | }; 39 | }); 40 | -------------------------------------------------------------------------------- /themes/fluid/scripts/helpers/page.js: -------------------------------------------------------------------------------- 1 | /* global hexo */ 2 | 3 | 'use strict'; 4 | 5 | hexo.extend.helper.register('prev_page', function prev_page(page) { 6 | const prev = page.prev; 7 | if (!prev) { 8 | return null; 9 | } 10 | if (prev.hide) { 11 | return prev_page(prev); 12 | } 13 | return prev; 14 | }); 15 | 16 | hexo.extend.helper.register('next_page', function next_page(page) { 17 | const next = page.next; 18 | if (!next) { 19 | return null; 20 | } 21 | if (next.hide) { 22 | return next_page(next); 23 | } 24 | return next; 25 | }); 26 | -------------------------------------------------------------------------------- /themes/fluid/scripts/helpers/url.js: -------------------------------------------------------------------------------- 1 | /* global hexo */ 2 | 3 | 'use strict'; 4 | 5 | const joinPath = require('../utils/join-path'); 6 | 7 | hexo.extend.helper.register('css_ex', function(base, relative, ex = '') { 8 | return ``; 9 | }); 10 | 11 | hexo.extend.helper.register('js_ex', function(base, relative, ex = '') { 12 | return ``; 13 | }); 14 | 15 | hexo.extend.helper.register('url_join', function(base, relative) { 16 | return this.url_for(joinPath(base, relative)); 17 | }); 18 | -------------------------------------------------------------------------------- /themes/fluid/scripts/helpers/utils.js: -------------------------------------------------------------------------------- 1 | /* global hexo */ 2 | 3 | 'use strict'; 4 | 5 | const crypto = require('crypto'); 6 | 7 | hexo.extend.helper.register('md5', function(string) { 8 | return crypto.createHash('md5').update(string).digest('hex'); 9 | }); 10 | -------------------------------------------------------------------------------- /themes/fluid/scripts/helpers/wordcount.js: -------------------------------------------------------------------------------- 1 | /* global hexo */ 2 | 3 | 'use strict'; 4 | 5 | let counter = function(content) { 6 | content = require('hexo-util').stripHTML(content); 7 | const cn = (content.match(/[\u4E00-\u9FA5]/g) || []).length; 8 | const en = (content.replace(/[\u4E00-\u9FA5]/g, '').match( 9 | /[a-zA-Z0-9_\u0392-\u03c9\u0400-\u04FF]+|[\u4E00-\u9FFF\u3400-\u4dbf\uf900-\ufaff\u3040-\u309f\uac00-\ud7af\u0400-\u04FF]+|[\u00E4\u00C4\u00E5\u00C5\u00F6\u00D6]+|\w+/g) || []).length; 10 | return [cn, en]; 11 | }; 12 | 13 | hexo.extend.helper.register('min2read', function(content, { cn = 300, en = 160 } = {}) { 14 | let len = counter(content); 15 | let readingTime = (len[0] / cn) + (len[1] / en); 16 | return readingTime < 1 ? '1' : parseInt(readingTime, 10); 17 | }); 18 | 19 | hexo.extend.helper.register('wordcount', function(content) { 20 | let len = counter(content); 21 | let count = len[0] + len[1]; 22 | if (count < 1000) { 23 | return count; 24 | } 25 | return (Math.round(count / 100) / 10) + 'k'; 26 | }); 27 | 28 | hexo.extend.helper.register('totalcount', function(site) { 29 | let count = 0; 30 | site.posts.forEach(function(post) { 31 | let len = counter(post.content); 32 | count += len[0] + len[1]; 33 | }); 34 | if (count < 1000) { 35 | return count; 36 | } 37 | return (Math.round(count / 100) / 10) + 'k'; 38 | }); 39 | -------------------------------------------------------------------------------- /themes/fluid/scripts/tags/button.js: -------------------------------------------------------------------------------- 1 | /* global hexo */ 2 | 3 | 'use strict'; 4 | 5 | const button = (args) => { 6 | args = args.join(' ').split(','); 7 | const url = (args[0] || '').trim(); 8 | const text = (args[1] || '').trim(); 9 | const title = (args[2] || '').trim(); 10 | 11 | !url && hexo.log.warn('Button url must be defined!'); 12 | 13 | return ` 0 ? ` title="${title}"` : ''} target="_blank">${text}`; 14 | }; 15 | 16 | // {% btn url, text, title %} 17 | hexo.extend.tag.register('button', button, { ends: false }); 18 | hexo.extend.tag.register('btn', button, { ends: false }); 19 | -------------------------------------------------------------------------------- /themes/fluid/scripts/tags/checkbox.js: -------------------------------------------------------------------------------- 1 | /* global hexo */ 2 | 3 | 'use strict'; 4 | 5 | const checkbox = (args) => { 6 | args = args[0] === ',' ? args.slice(1) : args; 7 | args = args.join(' ').split(','); 8 | const text = (args[0] || '').trim(); 9 | 10 | if (text === 'checked' || text === 'true' || text === 'false') { 11 | const checked = text === 'checked' || text === 'true'; 12 | return ``; 13 | } 14 | !text && hexo.log.warn('Checkbox text must be defined!'); 15 | 16 | const checked = (args[1] || '').length > 0 && args[1].trim() !== 'false'; 17 | const inline = (args[2] || '').length > 0 && args[2].trim() !== 'false'; 18 | 19 | return `${!inline ? '
    ' : ''} 20 | ${text} 21 | ${!inline ? '
    ' : ''}`; 22 | 23 | }; 24 | 25 | // {% cb text, checked?, inline? %} 26 | hexo.extend.tag.register('checkbox', checkbox, { ends: false }); 27 | hexo.extend.tag.register('cb', checkbox, { ends: false }); 28 | -------------------------------------------------------------------------------- /themes/fluid/scripts/tags/group-image.js: -------------------------------------------------------------------------------- 1 | /* global hexo */ 2 | 3 | 'use strict'; 4 | 5 | const DEFAULT_LAYOUTS = { 6 | 2 : [1, 1], 7 | 3 : [2, 1], 8 | 4 : [2, 2], 9 | 5 : [3, 2], 10 | 6 : [3, 3], 11 | 7 : [3, 2, 2], 12 | 8 : [3, 2, 3], 13 | 9 : [3, 3, 3], 14 | 10: [3, 2, 2, 3] 15 | }; 16 | 17 | const groupBy = (total, layout) => { 18 | const r = []; 19 | for (let count of total) { 20 | r.push(layout.slice(0, count)); 21 | layout = layout.slice(count); 22 | } 23 | return r; 24 | }; 25 | 26 | const templates = { 27 | 28 | dispatch: (images, total, layout) => { 29 | const valid = layout && (layout.reduce((prev, current) => prev + current) === total); 30 | const _layout = valid ? layout : DEFAULT_LAYOUTS[total]; 31 | return _layout ? templates.getHTML(groupBy(_layout, images)) : templates.defaults(images); 32 | }, 33 | 34 | defaults: (images) => { 35 | const ROW_SIZE = 3; 36 | const rows = images.length / ROW_SIZE; 37 | const imageArr = []; 38 | 39 | for (let i = 0; i < rows; i++) { 40 | imageArr.push(images.slice(i * ROW_SIZE, (i + 1) * ROW_SIZE)); 41 | } 42 | 43 | return templates.getHTML(imageArr); 44 | }, 45 | 46 | getHTML: (rows) => { 47 | return rows.map(row => { 48 | return `
    ${templates.getColumnHTML(row)}
    `; 49 | }).join(''); 50 | }, 51 | 52 | getColumnHTML: (images) => { 53 | return images.map(image => { 54 | return `
    ${image}
    `; 55 | }).join(''); 56 | } 57 | }; 58 | 59 | const groupImage = (args, content) => { 60 | const total = parseInt(args[0], 10); 61 | const layout = args[1] && args[1].split('-').map((v) => parseInt(v, 10)); 62 | 63 | content = hexo.render.renderSync({ text: content, engine: 'markdown' }); 64 | 65 | const images = content.match(//g); 66 | 67 | return `
    ${templates.dispatch(images, total, layout)}
    `; 68 | }; 69 | 70 | /* 71 | {% groupimage total n1-n2-n3-... %} 72 | ![](url) 73 | ![](url) 74 | ![](url) 75 | {% endgroupimage %} 76 | */ 77 | hexo.extend.tag.register('groupimage', groupImage, { ends: true }); 78 | hexo.extend.tag.register('gi', groupImage, { ends: true }); 79 | -------------------------------------------------------------------------------- /themes/fluid/scripts/tags/label.js: -------------------------------------------------------------------------------- 1 | /* global hexo */ 2 | 3 | 'use strict'; 4 | 5 | const label = (args) => { 6 | args = args.join(' ').split('@'); 7 | const classes = args[0] || 'default'; 8 | const text = args[1] || ''; 9 | 10 | !text && hexo.log.warn('Label text must be defined!'); 11 | 12 | return `${text}`; 13 | }; 14 | 15 | // {% label class @text %} 16 | hexo.extend.tag.register('label', label, { ends: false }); 17 | -------------------------------------------------------------------------------- /themes/fluid/scripts/tags/note.js: -------------------------------------------------------------------------------- 1 | /* global hexo */ 2 | 3 | 'use strict'; 4 | 5 | const note = (args, content) => { 6 | if (!args || !args[0]) { 7 | args = ['primary']; 8 | } 9 | return `
    10 | ${hexo.render.renderSync({ text: content, engine: 'markdown' }).split('\n').join('')} 11 |
    `; 12 | }; 13 | 14 | /* 15 | {% note class %} 16 | text 17 | {% endnote %} 18 | */ 19 | hexo.extend.tag.register('note', note, { ends: true }); 20 | -------------------------------------------------------------------------------- /themes/fluid/scripts/utils/join-path.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const joinPath = function(base, relative) { 4 | if (relative && /^https*:\/\//.test(relative)) { 5 | return relative; 6 | } 7 | return relative 8 | ? base.replace(/\/+$/, '') + '/' + relative.replace(/^\/+/, '') 9 | : base; 10 | }; 11 | 12 | module.exports = joinPath; 13 | -------------------------------------------------------------------------------- /themes/fluid/scripts/utils/object.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const isObject = (item) => { 4 | return item && typeof item === 'object' && !Array.isArray(item); 5 | }; 6 | 7 | const merge = (target, ...sources) => { 8 | for (const source of sources) { 9 | for (const key in source) { 10 | if (!Object.prototype.hasOwnProperty.call(source, key)) { 11 | continue; 12 | } 13 | if (isObject(target[key]) && isObject(source[key])) { 14 | merge(target[key], source[key]); 15 | } else { 16 | target[key] = source[key]; 17 | } 18 | } 19 | } 20 | return target; 21 | }; 22 | 23 | module.exports = { 24 | isObject: isObject, 25 | merge : merge 26 | }; 27 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_functions/base.styl: -------------------------------------------------------------------------------- 1 | theme-config(config, predef) 2 | unquote(hexo-config(config) ? hexo-config(config):predef) 3 | 4 | theme-config-unit(config, predef, unit) 5 | unit(hexo-config(config) ? hexo-config(config):predef, unit) 6 | 7 | theme-config-origin(config, predef) 8 | (hexo-config(config) ? hexo-config(config):predef) 9 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_mixins/base.styl: -------------------------------------------------------------------------------- 1 | /* 给锚点增加偏移量(适配导航栏的高度) */ 2 | anchor-offset() 3 | &::before 4 | display block 5 | content "" 6 | margin-top -5rem 7 | height 5rem 8 | width 1px 9 | visibility hidden 10 | 11 | /* 毛玻璃透明效果 */ 12 | ground-glass($px, $bg-color, $alpha) 13 | /* 若浏览器支持 backdrop-filter,则启用毛玻璃 */ 14 | @supports (-webkit-backdrop-filter: blur($px)) or (backdrop-filter: blur($px)) 15 | & 16 | background rgba(convert($bg-color), $alpha) 17 | -webkit-backdrop-filter blur($px) 18 | backdrop-filter blur($px) 19 | 20 | /* 若浏览器器不支持,则使用透明 */ 21 | @supports not ((-webkit-backdrop-filter: blur($px)) or (backdrop-filter: blur($px))) 22 | & 23 | background rgb(convert($bg-color)) 24 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/_about/about.styl: -------------------------------------------------------------------------------- 1 | .about-avatar 2 | position relative 3 | margin -8rem auto 1rem 4 | width 10rem 5 | height 10rem 6 | z-index 3 7 | 8 | img 9 | width 100% 10 | height 100% 11 | border-radius 50% 12 | -moz-border-radius 50% 13 | -webkit-border-radius 50% 14 | object-fit cover 15 | -webkit-box-shadow 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12) 16 | box-shadow 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12) 17 | 18 | .about-info 19 | & > div 20 | margin-bottom .5rem 21 | 22 | .about-name 23 | font-size 1.75rem 24 | font-weight bold 25 | 26 | .about-intro 27 | font-size 1rem 28 | 29 | .about-icons 30 | & > a:not(:last-child) 31 | margin-right .5rem 32 | 33 | & > a > i 34 | font-size 1.5rem 35 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/_archive/archive.styl: -------------------------------------------------------------------------------- 1 | .list-group 2 | a ~ p.h5 3 | margin-top 1rem 4 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/_base/_widget/banner.styl: -------------------------------------------------------------------------------- 1 | .banner 2 | height 100% 3 | position relative 4 | overflow hidden 5 | cursor default 6 | overflow-wrap break-word 7 | 8 | .mask 9 | position absolute 10 | width 100% 11 | height 100% 12 | background-color rgba(0, 0, 0, 0.3) 13 | 14 | .page-header 15 | color #fff 16 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/_base/_widget/board.styl: -------------------------------------------------------------------------------- 1 | #board 2 | position relative 3 | margin-top -2rem 4 | background-color var(--board-bg-color) 5 | transition background-color .2s ease-in-out 6 | border-radius 0.5rem 7 | z-index 3 8 | -webkit-box-shadow 0 12px 15px 0 rgba(0, 0, 0, 0.24), 0 17px 50px 0 rgba(0, 0, 0, 0.19) 9 | box-shadow 0 12px 15px 0 rgba(0, 0, 0, 0.24), 0 17px 50px 0 rgba(0, 0, 0, 0.19) 10 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/_base/_widget/copy-btn.styl: -------------------------------------------------------------------------------- 1 | .copy-btn 2 | display inline-block 3 | cursor pointer 4 | border-radius .1rem 5 | border none 6 | background-color transparent 7 | -webkit-user-select none 8 | -moz-user-select none 9 | -ms-user-select none 10 | user-select none 11 | -webkit-appearance none 12 | font-size .75rem 13 | line-height 1 14 | font-weight bold 15 | outline none 16 | -webkit-transition opacity .2s ease-in-out 17 | -o-transition opacity .2s ease-in-out 18 | transition opacity .2s ease-in-out 19 | padding .25rem 20 | position absolute 21 | right .5rem 22 | top .25rem 23 | opacity 0 24 | 25 | & > i 26 | font-size .75rem 27 | font-weight 400 28 | 29 | & > span 30 | margin-left 5px 31 | 32 | .copy-btn-dark 33 | color #6a737d 34 | 35 | .copy-btn-light 36 | color #bababa 37 | 38 | .markdown-body pre:hover > .copy-btn 39 | opacity 0.9 40 | 41 | .markdown-body pre:hover > .copy-btn, .markdown-body pre:not(:hover) > .copy-btn 42 | outline none 43 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/_base/_widget/footer.styl: -------------------------------------------------------------------------------- 1 | footer > div > div:not(:first-child) 2 | margin .25rem 0 3 | font-size .85rem 4 | 5 | .statistics > span:last-child 6 | margin 0 .35rem 7 | 8 | a.beian-police 9 | position relative 10 | overflow hidden 11 | display inline-flex 12 | align-items center 13 | justify-content center 14 | 15 | img 16 | margin 0 3px 17 | width 18px 18 | height 18px 19 | 20 | @media (max-width: 320px) 21 | a.beian-police 22 | span.beian-police-sep 23 | display none 24 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/_base/_widget/footnote.styl: -------------------------------------------------------------------------------- 1 | sup > a, .footnote-text 2 | anchor-offset() 3 | &::before 4 | display inline-block 5 | 6 | .footnote-item 7 | anchor-offset() 8 | 9 | .footnote-list 10 | ol 11 | list-style-type none 12 | counter-reset sectioncounter 13 | padding-left .5rem 14 | font-size .95rem 15 | 16 | li:before 17 | font-family "Helvetica Neue", monospace, "Monaco" 18 | content "["counter(sectioncounter)"]" 19 | counter-increment sectioncounter 20 | 21 | li+li 22 | margin-top .5rem 23 | 24 | .footnote-text 25 | padding-left .5em 26 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/_base/_widget/header.styl: -------------------------------------------------------------------------------- 1 | @media (max-width: 767px) 2 | header 3 | .h2 4 | font-size 1.5rem 5 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/_base/_widget/qrcode.styl: -------------------------------------------------------------------------------- 1 | .qr-trigger 2 | cursor pointer 3 | position relative 4 | 5 | &:hover .qr-img 6 | display block 7 | transition all .3s 8 | 9 | .qr-img 10 | max-width 200px 11 | position absolute 12 | right -100px 13 | z-index 99 14 | display none 15 | box-shadow 0 0 20px -5px hsla(0, 0%, 62%, .2) 16 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/_base/_widget/scroll-btn.styl: -------------------------------------------------------------------------------- 1 | .scroll-down-bar 2 | position absolute 3 | width 100% 4 | height 6rem 5 | text-align center 6 | cursor pointer 7 | bottom 0 8 | 9 | i 10 | font-size 2rem 11 | font-weight bold 12 | display inline-block 13 | position relative 14 | padding-top 2rem 15 | color #ff 16 | -webkit-transform translateZ(0) 17 | -moz-transform translateZ(0) 18 | -ms-transform translateZ(0) 19 | -o-transform translateZ(0) 20 | transform translateZ(0) 21 | -webkit-animation scroll-down 1.5s infinite 22 | animation scroll-down 1.5s infinite 23 | 24 | #scroll-top-button 25 | position fixed 26 | background var(--board-bg-color) 27 | transition background-color .2s ease-in-out, bottom .3s ease 28 | border-radius 4px 29 | min-width 40px 30 | min-height 40px 31 | bottom -60px 32 | outline none 33 | display flex 34 | display -webkit-flex 35 | align-items center 36 | -webkit-box-shadow 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12) 37 | box-shadow 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12) 38 | 39 | i 40 | font-size 1.75rem 41 | margin auto 42 | color var(--sec-text-color) 43 | -webkit-transform translateZ(0) 44 | -moz-transform translateZ(0) 45 | -ms-transform translateZ(0) 46 | -o-transform translateZ(0) 47 | transform translateZ(0) 48 | 49 | &:hover i, &:active i 50 | -webkit-animation-name scroll-top 51 | animation-name scroll-top 52 | -webkit-animation-duration 1s 53 | animation-duration 1s 54 | -webkit-animation-delay .1s 55 | animation-delay .1s 56 | -webkit-animation-timing-function ease-in-out 57 | animation-timing-function ease-in-out 58 | -webkit-animation-iteration-count infinite 59 | animation-iteration-count infinite 60 | -webkit-animation-fill-mode forwards 61 | animation-fill-mode forwards 62 | -webkit-animation-direction alternate 63 | animation-direction alternate 64 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/_base/_widget/search.styl: -------------------------------------------------------------------------------- 1 | #local-search-result 2 | .search-list-title 3 | border-left 3px solid #0d47a1 4 | 5 | .search-list-content 6 | padding 0 1.25rem 7 | 8 | .search-word 9 | color orangered 10 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/_base/base.styl: -------------------------------------------------------------------------------- 1 | @import "_widget/*" 2 | 3 | html, body 4 | font-size $font-size 5 | font-family $font-family 6 | 7 | html, body, header 8 | height 100% 9 | overflow-wrap break-word 10 | 11 | body 12 | transition color .2s ease-in-out, background-color .2s ease-in-out 13 | background-color var(--body-bg-color) 14 | color var(--text-color) 15 | 16 | a 17 | color var(--text-color) 18 | text-decoration none 19 | cursor pointer 20 | transition color .2s ease-in-out, background-color .2s ease-in-out 21 | 22 | &:hover 23 | color var(--link-hover-color) 24 | text-decoration none 25 | transition color .2s ease-in-out, background-color .2s ease-in-out 26 | 27 | img[srcset] 28 | object-fit cover 29 | 30 | *[align="left"] 31 | text-align left 32 | 33 | *[align="center"] 34 | text-align center 35 | 36 | *[align="right"] 37 | text-align right 38 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/_base/color-schema.styl: -------------------------------------------------------------------------------- 1 | :root 2 | --color-mode 'light' 3 | --body-bg-color $body-bg-color 4 | --board-bg-color $board-bg-color 5 | --text-color $text-color 6 | --sec-text-color $sec-text-color 7 | --post-text-color $post-text-color 8 | --post-heading-color $post-heading-color 9 | --post-link-color $post-link-color 10 | --link-hover-color $link-hover-color 11 | --link-hover-bg-color $link-hover-bg-color 12 | --navbar-bg-color $navbar-bg-color 13 | --navbar-text-color $navbar-text-color 14 | 15 | dark-colors() 16 | --body-bg-color $body-bg-color-dark 17 | --board-bg-color $board-bg-color-dark 18 | --text-color $text-color-dark 19 | --sec-text-color $sec-text-color-dark 20 | --post-text-color $post-text-color-dark 21 | --post-heading-color $post-heading-color-dark 22 | --post-link-color $post-link-color-dark 23 | --link-hover-color $link-hover-color-dark 24 | --link-hover-bg-color $link-hover-bg-color-dark 25 | --navbar-bg-color $navbar-bg-color-dark 26 | --navbar-text-color $navbar-text-color-dark 27 | 28 | img, .note, .label 29 | -webkit-filter brightness(.9) 30 | filter brightness(.9) 31 | transition filter .2s ease-in-out 32 | 33 | .page-header 34 | color #ddd 35 | transition color .2s ease-in-out 36 | 37 | .markdown-body 38 | 39 | :not(pre) > code 40 | background-color rgba(#3e4b5e, .35) 41 | transition background-color .2s ease-in-out 42 | 43 | .highlight pre, pre 44 | background-color rgba(#f6f8fa, .80) 45 | transition background-color .2s ease-in-out 46 | 47 | h1, h2 48 | border-bottom-color $line-color-dark 49 | transition border-bottom-color .2s ease-in-out 50 | 51 | h1, h2, h3, h6, h5, h6 52 | color #ddd 53 | transition color .2s ease-in-out 54 | 55 | table 56 | tr 57 | background-color var(--board-bg-color) 58 | transition background-color .2s ease-in-out 59 | tr:nth-child(2n) 60 | background-color var(--board-bg-color) 61 | transition background-color .2s ease-in-out 62 | th, td 63 | border-color $line-color-dark 64 | transition border-color .2s ease-in-out 65 | 66 | hr 67 | border-top-color $line-color-dark 68 | transition border-top-color .2s ease-in-out 69 | 70 | .navbar .dropdown-collapse, .top-nav-collapse, .navbar-col-show 71 | if $navbar-glass-enable 72 | ground-glass($navbar-glass-px, $navbar-bg-color-dark, $navbar-glass-alpha) 73 | 74 | .note :not(pre) > code 75 | background-color rgba(27, 31, 35, .05) 76 | 77 | .modal-dialog .modal-content .modal-header 78 | border-bottom-color $line-color-dark 79 | transition border-bottom-color .2s ease-in-out 80 | 81 | .gt-comment-admin .gt-comment-content 82 | background-color transparent 83 | transition background-color .2s ease-in-out 84 | 85 | @media (prefers-color-scheme: dark) 86 | :root 87 | --color-mode 'dark' 88 | 89 | :root:not([data-user-color-scheme]) 90 | dark-colors() 91 | 92 | [data-user-color-scheme='dark'] 93 | dark-colors() 94 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/_base/inline.styl: -------------------------------------------------------------------------------- 1 | .fade-in-up 2 | -webkit-animation-name fade-in-up 3 | animation-name fade-in-up 4 | 5 | .hidden-mobile 6 | display block 7 | 8 | .visible-mobile 9 | display none 10 | 11 | @media (max-width: 575px) 12 | .hidden-mobile 13 | display none 14 | 15 | .visible-mobile 16 | display block 17 | 18 | @media (max-width: 767px) 19 | .nopadding-md 20 | padding-left 0 !important 21 | padding-right 0 !important 22 | 23 | .flex-center 24 | display -webkit-box 25 | display -ms-flexbox 26 | display flex 27 | -webkit-box-align center 28 | -ms-flex-align center 29 | align-items center 30 | -webkit-box-pack center 31 | -ms-flex-pack center 32 | justify-content center 33 | height 100% 34 | 35 | .hover-with-bg 36 | display inline-block 37 | padding .45rem 38 | 39 | &:hover 40 | background-color var(--link-hover-bg-color) 41 | transition-duration .2s 42 | transition-timing-function ease-in-out 43 | border-radius .15rem 44 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/_base/keyframes.styl: -------------------------------------------------------------------------------- 1 | @keyframes fade-in-up 2 | from 3 | opacity 0 4 | -webkit-transform translate3d(0, 100%, 0) 5 | transform translate3d(0, 100%, 0) 6 | to 7 | opacity 1 8 | -webkit-transform translate3d(0, 0, 0) 9 | transform translate3d(0, 0, 0) 10 | 11 | @keyframes scroll-down 12 | 0% 13 | opacity 0.8 14 | top 0 15 | 50% 16 | opacity 0.4 17 | top -1em 18 | 100% 19 | opacity 0.8 20 | top 0 21 | 22 | @keyframes scroll-top 23 | 0% 24 | -webkit-transform translateY(0) 25 | transform translateY(0) 26 | 50% 27 | -webkit-transform translateY(-0.35rem) 28 | transform translateY(-0.35rem) 29 | 100% 30 | -webkit-transform translateY(0) 31 | transform translateY(0) 32 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/_category/categories.styl: -------------------------------------------------------------------------------- 1 | .category 2 | 3 | &:not(:last-child) 4 | margin-bottom 1rem 5 | 6 | &-sub 7 | pass 8 | 9 | &-item 10 | font-size 1.25rem 11 | font-weight bold 12 | display flex 13 | align-items center 14 | 15 | &-subitem 16 | font-size 1rem 17 | font-weight bold 18 | 19 | &-collapse 20 | margin-left: 1.25rem 21 | width 100% 22 | 23 | &-count 24 | font-size .9rem 25 | font-weight initial 26 | min-width 1.3em 27 | line-height 1.3em 28 | display flex 29 | align-items center 30 | 31 | i 32 | padding-right .25rem 33 | 34 | span 35 | width 2rem 36 | 37 | &-item-action 38 | 39 | &:not(.collapsed) > i 40 | transform rotate(90deg) 41 | transform-origin center center 42 | 43 | i 44 | transition transform .3s ease-out 45 | display inline-block 46 | margin-left .25rem 47 | 48 | &:hover 49 | z-index 1 50 | color var(--link-hover-color) 51 | text-decoration none 52 | background-color var(--link-hover-bg-color) 53 | 54 | .row 55 | margin-left 0 56 | margin-right 0 57 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/_category/category.styl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChenYFan/blog/3e15fc2372710483f58c22b94988424a67d8f13f/themes/fluid/source/css/_pages/_category/category.styl -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/_index/index.styl: -------------------------------------------------------------------------------- 1 | .index-card 2 | margin-bottom 2.5rem 3 | 4 | .index-img 5 | img 6 | display block 7 | width 100% 8 | height 10rem 9 | object-fit cover 10 | box-shadow 0 5px 11px 0 rgba(0, 0, 0, 0.18), 0 4px 15px 0 rgba(0, 0, 0, 0.15) 11 | border-radius .25rem 12 | 13 | .index-info 14 | display flex 15 | flex-direction column 16 | justify-content space-between 17 | padding-top .5rem 18 | padding-bottom .5rem 19 | 20 | .index-header 21 | color var(--text-color) 22 | font-size 1.5rem 23 | font-weight bold 24 | line-height 1.2 25 | white-space nowrap 26 | overflow hidden 27 | text-overflow ellipsis 28 | 29 | .index-btm 30 | color var(--sec-text-color) 31 | 32 | a 33 | color var(--sec-text-color) 34 | 35 | .index-excerpt 36 | color var(--sec-text-color) 37 | 38 | margin 0.5rem 0 0.5rem 0 39 | max-height calc(1.4rem * 3) 40 | line-height 1.4rem 41 | overflow hidden 42 | 43 | & > div 44 | float right 45 | margin-left -0.25rem 46 | width 100% 47 | word-break break-word 48 | display -webkit-box 49 | -webkit-box-orient vertical 50 | -webkit-line-clamp 3 51 | 52 | @media (max-width: 767px) 53 | .index-info 54 | padding-top 1.25rem 55 | 56 | .index-header 57 | font-size 1.25rem 58 | white-space normal 59 | overflow hidden 60 | word-break break-word 61 | display -webkit-box 62 | -webkit-box-orient vertical 63 | -webkit-line-clamp 2 64 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/_links/links.styl: -------------------------------------------------------------------------------- 1 | .links 2 | .card 3 | box-shadow none 4 | min-width 33% 5 | background-color transparent 6 | border 0 7 | 8 | .card-body 9 | margin 1rem 0 10 | padding 1rem 11 | border-radius .3rem 12 | display block 13 | width 100% 14 | height 100% 15 | 16 | &:hover 17 | .link-avatar 18 | transform scale(1.1) 19 | 20 | .card-content 21 | display flex 22 | flex-wrap nowrap 23 | width 100% 24 | height 3.5rem 25 | 26 | .link-avatar 27 | flex none 28 | width 3rem 29 | height 3rem 30 | margin-right .75rem 31 | object-fit cover 32 | transition-duration .2s 33 | transition-timing-function ease-in-out 34 | 35 | img 36 | width 100% 37 | height 100% 38 | border-radius 50% 39 | -moz-border-radius 50% 40 | -webkit-border-radius 50% 41 | object-fit cover 42 | 43 | .link-text 44 | flex 1 45 | display grid 46 | flex-direction column 47 | 48 | .link-title 49 | overflow hidden 50 | text-overflow ellipsis 51 | white-space nowrap 52 | color $text_color 53 | font-weight bold 54 | 55 | .link-intro 56 | max-height 2rem 57 | font-size 0.85rem 58 | line-height 1.2 59 | color var(--sec-text-color) 60 | display -webkit-box 61 | -webkit-box-orient vertical 62 | -webkit-line-clamp 2 63 | text-overflow ellipsis 64 | overflow hidden 65 | 66 | @media (max-width 767px) 67 | .links 68 | display flex 69 | flex-direction column 70 | justify-content center 71 | align-items center 72 | 73 | .card 74 | padding-left 2rem 75 | padding-right 2rem 76 | 77 | @media (min-width 768px) 78 | .link-text:only-child 79 | margin-left 1rem 80 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/_post/tag_plugin.styl: -------------------------------------------------------------------------------- 1 | // note 2 | .note 3 | padding 0.75rem 4 | border-left 0.35rem solid 5 | border-radius 0.25rem 6 | margin 1.5rem 0 7 | color $text-color 8 | 9 | a 10 | color $text-color 11 | 12 | *:last-child 13 | margin-bottom 0 14 | 15 | .note-primary 16 | background-color #dfeefd 17 | border-color #176ac4 18 | 19 | .note-secondary 20 | background-color #e2e3e5 21 | border-color #58595a 22 | 23 | .note-success 24 | background-color #e2f0e5 25 | border-color #49a75f 26 | 27 | .note-danger 28 | background-color #fae7e8 29 | border-color #e45460 30 | 31 | .note-warning 32 | background-color #faf4e0 33 | border-color #c2a442 34 | 35 | .note-info 36 | background-color #e4f2f5 37 | border-color #2492a5 38 | 39 | .note-light 40 | background-color #fefefe 41 | border-color #0f0f0f 42 | 43 | // label 44 | .label 45 | display inline 46 | border-radius 3px 47 | font-size 85% 48 | margin 0 49 | padding .2em .4em 50 | color $text-color 51 | 52 | .label-default 53 | background #e7e3e3 54 | 55 | .label-primary 56 | background #dfeefd 57 | 58 | .label-info 59 | background #e4f2f5 60 | 61 | .label-success 62 | background #e2f0e5 63 | 64 | .label-warning 65 | background #faf4e0 66 | 67 | .label-danger 68 | background #fae7e8 69 | 70 | // button 71 | .markdown-body .btn 72 | background #2F4154 73 | border-radius .25rem 74 | color #fff !important 75 | display inline-block 76 | font-size .875em 77 | line-height 2 78 | padding 0 .75rem 79 | text-decoration none 80 | transition-property background 81 | transition-delay 0s 82 | transition-duration 0.2s 83 | transition-timing-function ease-in-out 84 | -webkit-box-shadow 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12) 85 | box-shadow 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12) 86 | margin-bottom 1rem 87 | 88 | &:hover 89 | background #23ae92 90 | color #fff !important 91 | text-decoration none 92 | 93 | // group-image 94 | 95 | 96 | & img 97 | margin 0 auto 98 | border-radius 3px 99 | box-shadow 0 3px 9px 0 rgba(0, 0, 0, 0.15), 0 3px 9px 0 rgba(0, 0, 0, 0.15) 100 | box-shadow 0 3px 9px 0 rgba(0, 0, 0, 0.15), 0 3px 9px 0 rgba(0, 0, 0, 0.15) 101 | 102 | .group-image-row 103 | margin-bottom .5rem 104 | display flex 105 | justify-content center 106 | 107 | .group-image-wrap 108 | flex 1 109 | display flex 110 | justify-content center 111 | 112 | &:not(:last-child) 113 | margin-right .25rem 114 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/_tag/tag.styl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChenYFan/blog/3e15fc2372710483f58c22b94988424a67d8f13f/themes/fluid/source/css/_pages/_tag/tag.styl -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/_tag/tags.styl: -------------------------------------------------------------------------------- 1 | .tagcloud 2 | padding 1rem 5% 3 | 4 | a 5 | display inline-block 6 | padding .5rem 7 | 8 | &:hover 9 | color var(--link-hover-color) !important 10 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_pages/pages.styl: -------------------------------------------------------------------------------- 1 | @import "_base/*" 2 | @import "_index/*" 3 | @import "_post/*" 4 | @import "_archive/*" 5 | @import "_about/*" 6 | @import "_category/*" 7 | @import "_tag/*" 8 | @import "_links/*" 9 | -------------------------------------------------------------------------------- /themes/fluid/source/css/_variables/base.styl: -------------------------------------------------------------------------------- 1 | // Font 2 | $font-size = theme-config("font.font_size", "16px") 3 | $font-family = theme-config("font.font_family", '"SF Pro SC", "SF Pro Text", "SF Pro Icons", PingFang SC, Lantinghei SC, Microsoft Yahei, Hiragino Sans GB, Microsoft Sans Serif, WenQuanYi Micro Hei, sans-serif') 4 | $code-font-size = theme-config("font.code_font_size", "85%") 5 | 6 | // Colors 7 | 8 | // body 9 | $body-bg-color = theme-config("color.body_bg_color", "#eee") 10 | $body-bg-color-dark = theme-config("color.body_bg_color_dark", "#181c27") 11 | 12 | // global 13 | $text-color = theme-config("color.text_color", "#3c4858") 14 | $text-color-dark = theme-config("color.text_color_dark", "#c4c6c9") 15 | $sec-text-color = theme-config("color.sec_text_color", "#718096") 16 | $sec-text-color-dark = theme-config("color.sec_text_color_dark", "#a7a9ad") 17 | $post-text-color = theme-config("color.post_text_color", "#2c3e50") 18 | $post-text-color-dark = theme-config("color.post_text_color_dark", "#c4c6c9") 19 | $post-heading-color = theme-config("color.post_heading_color", "#1a202c") 20 | $post-heading-color-dark = theme-config("color.post_heading_color_dark", "#c4c6c9") 21 | $post-link-color = theme-config("color.post_link_color", "#2c3e50") 22 | $post-link-color-dark = theme-config("color.post_link_color_dark", "#c4c6c9") 23 | $link-hover-color = theme-config("color.link_hover_color", "#30a9de") 24 | $link-hover-color-dark = theme-config("color.link_hover_color_dark", "#30a9de") 25 | $link-hover-bg-color = theme-config("color.link_hover_bg_color", "#ebedef") 26 | $link-hover-bg-color-dark = theme-config("color.link_hover_bg_color_dark", "#364151") 27 | $line-color-dark = #435266 28 | 29 | // navbar 30 | $navbar-bg-color = theme-config("color.navbar_bg_color", "#2f4154") 31 | $navbar-bg-color-dark = theme-config("color.navbar_bg_color_dark", "#1f3144") 32 | $navbar-text-color = theme-config("color.navbar_text_color", "#fff") 33 | $navbar-text-color-dark = theme-config("color.navbar_text_color_dark", "d0d0d0") 34 | $navbar-glass-enable = theme-config-origin("navbar.ground_glass.enable", false) 35 | $navbar-glass-px = theme-config-unit("navbar.ground_glass.px", 1, "px") 36 | $navbar-glass-alpha = theme-config-origin("navbar.ground_glass.alpha", 1) 37 | 38 | // board 39 | $board-bg-color = theme-config("color.board_color", "#fff") 40 | $board-bg-color-dark = theme-config("color.board_color_dark", "#252d38") 41 | 42 | // Shadow 43 | $img-shadow = 0 5px 11px 0 rgba(0, 0, 0, .18), 0 4px 15px 0 rgba(0, 0, 0, .15) 44 | -------------------------------------------------------------------------------- /themes/fluid/source/css/main.styl: -------------------------------------------------------------------------------- 1 | // -------------------------------------- 2 | // Fluid 3 | // https://github.com/fluid-dev/hexo-theme-fluid 4 | // -------------------------------------- 5 | 6 | @import "_variables/base" 7 | 8 | @import "_functions/base" 9 | 10 | @import "_mixins/base" 11 | 12 | @import "_pages/pages" 13 | -------------------------------------------------------------------------------- /themes/fluid/source/img/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChenYFan/blog/3e15fc2372710483f58c22b94988424a67d8f13f/themes/fluid/source/img/apple-touch-icon.png -------------------------------------------------------------------------------- /themes/fluid/source/img/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChenYFan/blog/3e15fc2372710483f58c22b94988424a67d8f13f/themes/fluid/source/img/avatar.png -------------------------------------------------------------------------------- /themes/fluid/source/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChenYFan/blog/3e15fc2372710483f58c22b94988424a67d8f13f/themes/fluid/source/img/favicon.png -------------------------------------------------------------------------------- /themes/fluid/source/img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChenYFan/blog/3e15fc2372710483f58c22b94988424a67d8f13f/themes/fluid/source/img/loading.gif -------------------------------------------------------------------------------- /themes/fluid/source/js/clipboard-use.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line no-unused-expressions 2 | !(function(e, t, a) { 3 | function initCopyCode() { 4 | var copyHtml = ''; 5 | copyHtml += ''; 8 | $('.markdown-body pre').each(function() { 9 | const pre = $(this); 10 | if (pre.find('code.mermaid').length > 0) { 11 | return; 12 | } 13 | pre.append(copyHtml); 14 | }); 15 | // eslint-disable-next-line no-undef 16 | var clipboard = new ClipboardJS('.copy-btn', { 17 | target: function(trigger) { 18 | return trigger.previousElementSibling; 19 | } 20 | }); 21 | $('.copy-btn').addClass(getBgClass()); 22 | clipboard.on('success', function(e) { 23 | e.clearSelection(); 24 | var tmp = e.trigger.outerHTML; 25 | e.trigger.innerHTML = 'Success'; 26 | setTimeout(function() { 27 | e.trigger.outerHTML = tmp; 28 | }, 2000); 29 | }); 30 | } 31 | 32 | function getBgClass() { 33 | var ele = $('div.hljs, pre'); 34 | if (ele.length === 0) { 35 | return 'copy-btn-dark'; 36 | } 37 | var rgbArr = ele.css('background-color').replace( 38 | /rgba*\(/, '').replace(')', '').split(','); 39 | var color = (0.213 * rgbArr[0]) + (0.715 * rgbArr[1]) + (0.072 * rgbArr[2]) > 255 / 2; 40 | return color ? 'copy-btn-dark' : 'copy-btn-light'; 41 | } 42 | 43 | var oldLoadCb = window.onload; 44 | window.onload = function() { 45 | oldLoadCb && oldLoadCb(); 46 | 47 | initCopyCode(); 48 | }; 49 | })(window, document); 50 | -------------------------------------------------------------------------------- /themes/fluid/source/js/debouncer.js: -------------------------------------------------------------------------------- 1 | window.requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame; 2 | 3 | /** 4 | * Handles debouncing of events via requestAnimationFrame 5 | * @see http://www.html5rocks.com/en/tutorials/speed/animations/ 6 | * @param {Function} callback The callback to handle whichever event 7 | */ 8 | function Debouncer(callback) { 9 | this.callback = callback; 10 | this.ticking = false; 11 | } 12 | Debouncer.prototype = { 13 | constructor: Debouncer, 14 | 15 | /** 16 | * dispatches the event to the supplied callback 17 | * @private 18 | */ 19 | update: function() { 20 | this.callback && this.callback(); 21 | this.ticking = false; 22 | }, 23 | 24 | /** 25 | * ensures events don't get stacked 26 | * @private 27 | */ 28 | requestTick: function() { 29 | if (!this.ticking) { 30 | requestAnimationFrame(this.rafCallback || (this.rafCallback = this.update.bind(this))); 31 | this.ticking = true; 32 | } 33 | }, 34 | 35 | /** 36 | * Attach this as the event listeners 37 | */ 38 | handleEvent: function() { 39 | this.requestTick(); 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /themes/fluid/source/js/lazyload.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line no-unused-expressions 2 | !(function(window, document) { 3 | var runningOnBrowser = typeof window !== 'undefined'; 4 | var supportsIntersectionObserver = runningOnBrowser && 'IntersectionObserver' in window; 5 | 6 | var images = Array.prototype.slice.call(document.querySelectorAll('img[srcset]')); 7 | if (!images || images.length === 0) { 8 | return; 9 | } 10 | 11 | if (supportsIntersectionObserver) { 12 | var io = new IntersectionObserver(function(changes) { 13 | changes.forEach(({ target, isIntersecting }) => { 14 | if (!isIntersecting) return; 15 | target.setAttribute('srcset', target.src); 16 | target.onload = target.onerror = () => io.unobserve(target); 17 | }); 18 | }, { 19 | threshold : [0], 20 | rootMargin: (window.innerHeight || document.documentElement.clientHeight) + 'px' 21 | }); 22 | images.map((item) => io.observe(item)); 23 | } else { 24 | // eslint-disable-next-line no-inner-declarations 25 | function elementInViewport(el) { 26 | var rect = el.getBoundingClientRect(); 27 | var height = window.innerHeight || document.documentElement.clientHeight; 28 | var top = rect.top; 29 | return (top >= 0 && top <= height * 3) || (top <= 0 && top <= -(height * 2) - rect.height); 30 | } 31 | 32 | // eslint-disable-next-line no-inner-declarations 33 | function loadImage(el, fn) { 34 | var img = new Image(); 35 | var src = el.getAttribute('src'); 36 | img.onload = function() { 37 | el.srcset = src; 38 | fn && fn(); 39 | }; 40 | img.srcset = src; 41 | } 42 | 43 | // eslint-disable-next-line no-undef 44 | var lazyLoader = new Debouncer(processImages); 45 | 46 | // eslint-disable-next-line no-inner-declarations 47 | function processImages() { 48 | for (var i = 0; i < images.length; i++) { 49 | if (elementInViewport(images[i])) { 50 | // eslint-disable-next-line no-loop-func 51 | (function(index) { 52 | var loadingImage = images[index]; 53 | loadImage(loadingImage, function() { 54 | images = images.filter(function(t) { 55 | return loadingImage !== t; 56 | }); 57 | }); 58 | })(i); 59 | } 60 | } 61 | if (images.length === 0) { 62 | window.removeEventListener('scroll', lazyLoader, false); 63 | } 64 | } 65 | 66 | window.addEventListener('scroll', lazyLoader, false); 67 | lazyLoader.handleEvent(); 68 | } 69 | 70 | })(window, document); 71 | -------------------------------------------------------------------------------- /themes/fluid/source/js/main.js: -------------------------------------------------------------------------------- 1 | // 监听滚动事件 2 | function listenScroll(callback) { 3 | // eslint-disable-next-line no-undef 4 | const dbc = new Debouncer(callback); 5 | window.addEventListener('scroll', dbc, false); 6 | dbc.handleEvent(); 7 | } 8 | 9 | // 滚动到指定元素 10 | function scrollToElement(target, offset) { 11 | var scroll_offset = $(target).offset(); 12 | $('body,html').animate({ 13 | scrollTop: scroll_offset.top + (offset || 0), 14 | easing : 'swing' 15 | }); 16 | } 17 | 18 | // 顶部菜单的监听事件 19 | function navbarScrollEvent() { 20 | var navbar = $('#navbar'); 21 | var submenu = $('#navbar .dropdown-menu'); 22 | if (navbar.offset().top > 0) { 23 | navbar.removeClass('navbar-dark'); 24 | submenu.removeClass('navbar-dark'); 25 | } 26 | listenScroll(function() { 27 | navbar[navbar.offset().top > 50 ? 'addClass' : 'removeClass']('top-nav-collapse'); 28 | submenu[navbar.offset().top > 50 ? 'addClass' : 'removeClass']('dropdown-collapse'); 29 | if (navbar.offset().top > 0) { 30 | navbar.removeClass('navbar-dark'); 31 | submenu.removeClass('navbar-dark'); 32 | } else { 33 | navbar.addClass('navbar-dark'); 34 | submenu.removeClass('navbar-dark'); 35 | } 36 | }); 37 | $('#navbar-toggler-btn').on('click', function() { 38 | $('.animated-icon').toggleClass('open'); 39 | $('#navbar').toggleClass('navbar-col-show'); 40 | }); 41 | } 42 | 43 | // 头图视差的监听事件 44 | function parallaxEvent() { 45 | var target = $('#background[parallax="true"]'); 46 | var parallax = function() { 47 | var oVal = $(window).scrollTop() / 5; 48 | var offset = parseInt($('#board').css('margin-top'), 0); 49 | var max = 96 + offset; 50 | if (oVal > max) { 51 | oVal = max; 52 | } 53 | target.css({ 54 | transform : 'translate3d(0,' + oVal + 'px,0)', 55 | '-webkit-transform': 'translate3d(0,' + oVal + 'px,0)', 56 | '-ms-transform' : 'translate3d(0,' + oVal + 'px,0)', 57 | '-o-transform' : 'translate3d(0,' + oVal + 'px,0)' 58 | }); 59 | 60 | var toc = $('#toc'); 61 | if (toc) { 62 | $('#toc-ctn').css({ 63 | 'padding-top': oVal + 'px' 64 | }); 65 | } 66 | }; 67 | if (target.length > 0) { 68 | listenScroll(parallax); 69 | } 70 | } 71 | 72 | // 向下滚动箭头的监听事件 73 | function scrollDownArrowEvent() { 74 | $('.scroll-down-bar').on('click', function() { 75 | scrollToElement('#board', -$('#navbar').height()); 76 | }); 77 | } 78 | 79 | // 向顶部滚动箭头的监听事件 80 | function scrollTopArrowEvent() { 81 | var topArrow = $('#scroll-top-button'); 82 | if (!topArrow) { 83 | return; 84 | } 85 | var posDisplay = false; 86 | var scrollDisplay = false; 87 | // 位置 88 | var setTopArrowPos = function() { 89 | var boardRight = document.getElementById('board').getClientRects()[0].right; 90 | var bodyWidth = document.body.offsetWidth; 91 | var right = bodyWidth - boardRight; 92 | posDisplay = right >= 50; 93 | topArrow.css({ 94 | 'bottom': posDisplay && scrollDisplay ? '20px' : '-60px', 95 | 'right' : right - 64 + 'px' 96 | }); 97 | }; 98 | setTopArrowPos(); 99 | $(window).resize(setTopArrowPos); 100 | // 显示 101 | var headerHeight = $('#board').offset().top; 102 | listenScroll(function() { 103 | var scrollHeight = document.body.scrollTop + document.documentElement.scrollTop; 104 | scrollDisplay = scrollHeight >= headerHeight; 105 | topArrow.css({ 106 | 'bottom': posDisplay && scrollDisplay ? '20px' : '-60px' 107 | }); 108 | }); 109 | // 点击 110 | topArrow.on('click', function() { 111 | $('body,html').animate({ 112 | scrollTop: 0, 113 | easing : 'swing' 114 | }); 115 | }); 116 | } 117 | 118 | $(document).ready(function() { 119 | navbarScrollEvent(); 120 | parallaxEvent(); 121 | scrollDownArrowEvent(); 122 | scrollTopArrowEvent(); 123 | }); 124 | -------------------------------------------------------------------------------- /themes/fluid/source/js/utils.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line no-unused-vars 2 | function waitElementVisible(targetId, callback) { 3 | var runningOnBrowser = typeof window !== 'undefined'; 4 | var isBot = (runningOnBrowser && !('onscroll' in window)) || (typeof navigator !== 'undefined' 5 | && /(gle|ing|ro|msn)bot|crawl|spider|yand|duckgo/i.test(navigator.userAgent)); 6 | var supportsIntersectionObserver = runningOnBrowser && 'IntersectionObserver' in window; 7 | if (!isBot && supportsIntersectionObserver) { 8 | var io = new IntersectionObserver(function(entries, ob) { 9 | if (entries[0].isIntersecting) { 10 | callback && callback(); 11 | ob.disconnect(); 12 | } 13 | }, { 14 | threshold : [0], 15 | rootMargin: (window.innerHeight || document.documentElement.clientHeight) + 'px' 16 | }); 17 | io.observe(document.getElementById(targetId)); 18 | } else { 19 | callback && callback(); 20 | } 21 | } 22 | 23 | // eslint-disable-next-line no-unused-vars 24 | function waitElementLoaded(targetId, callback) { 25 | var runningOnBrowser = typeof window !== 'undefined'; 26 | var isBot = (runningOnBrowser && !('onscroll' in window)) || (typeof navigator !== 'undefined' 27 | && /(gle|ing|ro|msn)bot|crawl|spider|yand|duckgo/i.test(navigator.userAgent)); 28 | if (!runningOnBrowser || isBot) { 29 | return; 30 | } 31 | 32 | if ('MutationObserver' in window) { 33 | var mo = new MutationObserver(function(records, ob) { 34 | var ele = document.getElementById(targetId); 35 | if (ele) { 36 | callback && callback(); 37 | ob.disconnect(); 38 | } 39 | }); 40 | mo.observe(document, { childList: true, subtree: true }); 41 | } else { 42 | var oldLoad = window.onload; 43 | window.onload = function() { 44 | oldLoad && oldLoad(); 45 | callback && callback(); 46 | }; 47 | } 48 | } 49 | 50 | // eslint-disable-next-line no-unused-vars 51 | function addScript(url, onload) { 52 | var s = document.createElement('script'); 53 | s.setAttribute('src', url); 54 | s.setAttribute('type', 'text/javascript'); 55 | s.setAttribute('charset', 'UTF-8'); 56 | s.async = false; 57 | if (typeof onload === 'function') { 58 | if (window.attachEvent) { 59 | s.onreadystatechange = function() { 60 | var e = s.readyState; 61 | if (e === 'loaded' || e === 'complete') { 62 | s.onreadystatechange = null; 63 | onload(); 64 | } 65 | }; 66 | } else { 67 | s.onload = onload; 68 | } 69 | } 70 | var e = document.getElementsByTagName('script')[0] 71 | || document.getElementsByTagName('head')[0] 72 | || document.head || document.documentElement; 73 | e.parentNode.insertBefore(s, e); 74 | } 75 | 76 | // eslint-disable-next-line no-unused-vars 77 | function addCssLink(url) { 78 | var l = document.createElement('link'); 79 | l.setAttribute('rel', 'stylesheet'); 80 | l.setAttribute('type', 'text/css'); 81 | l.setAttribute('href', url); 82 | var e = document.getElementsByTagName('link')[0] 83 | || document.getElementsByTagName('head')[0] 84 | || document.head || document.documentElement; 85 | e.parentNode.insertBefore(l, e); 86 | } 87 | --------------------------------------------------------------------------------